109 lines
4.5 KiB
JavaScript
109 lines
4.5 KiB
JavaScript
/* 机构动向 */
|
|
let curType = '';
|
|
|
|
async function loadInsts() {
|
|
try {
|
|
const d = await api('/api/institutions?type=' + curType);
|
|
const items = d.items || [];
|
|
$('#tb').innerHTML = items.map(it => `
|
|
<tr>
|
|
<td><b>${escapeHtml(it.name)}</b></td>
|
|
<td><span class="cat-tag">${escapeHtml(it.type)}</span></td>
|
|
<td style="max-width:360px;white-space:normal;color:var(--text2)">${escapeHtml(it.description)}</td>
|
|
<td class="num" id="rc-${it.id}">…</td>
|
|
<td class="num" id="hc-${it.id}">…</td>
|
|
<td><button class="btn" onclick="showInst(${it.id})">查看详情</button></td>
|
|
</tr>`).join('');
|
|
items.forEach(it => fillCounts(it.id, it.name));
|
|
} catch (e) {
|
|
$('#tb').innerHTML = '<tr><td colspan="6" class="empty">加载失败</td></tr>';
|
|
}
|
|
}
|
|
|
|
async function fillCounts(id, name) {
|
|
try {
|
|
const d = await api('/api/ratings/upgrades');
|
|
const rc = d.items.filter(x => x.inst_name === name).length;
|
|
$('#rc-' + id).textContent = rc;
|
|
} catch (e) {}
|
|
}
|
|
|
|
async function showInst(id) {
|
|
try {
|
|
const d = await api('/api/institutions/' + id);
|
|
const inst = d.institution;
|
|
const ratings = (d.ratings || []).map(r => `
|
|
<tr class="row-link" onclick="location.href='/stock/${r.stock_code}'">
|
|
<td>${r.name}(${r.stock_code})</td>
|
|
<td><span class="tag tag-${r.rating}">${r.rating}</span></td>
|
|
<td class="num">${r.target_price}</td><td>${r.rating_date}</td>
|
|
</tr>`).join('');
|
|
const holdings = (d.holdings || []).map(h => `
|
|
<tr class="row-link" onclick="location.href='/stock/${h.stock_code}'">
|
|
<td>${h.name}(${h.stock_code})</td><td>${h.quarter}</td>
|
|
<td class="num">${fmtNum(h.hold_value)}</td>
|
|
<td class="num ${pctClass(h.change_pct)}">${fmtPct(h.change_pct)}</td>
|
|
</tr>`).join('');
|
|
openModal(`
|
|
<h3>${escapeHtml(inst.name)} <span class="cat-tag">${escapeHtml(inst.type)}</span></h3>
|
|
<div style="color:var(--text2);margin-bottom:14px">${escapeHtml(inst.description)}</div>
|
|
<h3 style="font-size:15px">近期评级</h3>
|
|
<table>${ratings || '<tr><td class="empty">暂无</td></tr>'}</table>
|
|
<h3 style="font-size:15px;margin-top:16px">基金持仓</h3>
|
|
<table>${holdings || '<tr><td class="empty">暂无</td></tr>'}</table>
|
|
`);
|
|
} catch (e) { toast('加载失败'); }
|
|
}
|
|
|
|
async function loadMoves() {
|
|
try {
|
|
const d = await api('/api/holdings/moves');
|
|
const q = d.quarter || '';
|
|
const inc = (d.increase || []).map(h => `
|
|
<tr class="row-link" onclick="location.href='/stock/${h.stock_code}'">
|
|
<td>${h.name}</td><td>${escapeHtml(h.inst_name)}</td>
|
|
<td class="num up">${fmtPct(h.change_pct)}</td>
|
|
</tr>`).join('');
|
|
const dec = (d.decrease || []).map(h => `
|
|
<tr class="row-link" onclick="location.href='/stock/${h.stock_code}'">
|
|
<td>${h.name}</td><td>${escapeHtml(h.inst_name)}</td>
|
|
<td class="num down">${fmtPct(h.change_pct)}</td>
|
|
</tr>`).join('');
|
|
$('#holdBox').innerHTML = `<div style="font-size:12px;color:var(--muted);margin-bottom:8px">最新季度:${q}</div>
|
|
<table>
|
|
<tr><th>增持榜</th><th>机构</th><th>环比</th></tr>${inc || '<tr><td colspan="3" class="empty">暂无</td></tr>'}
|
|
<tr><td colspan="3" style="height:8px;border:none"></td></tr>
|
|
<tr><th>减持榜</th><th>机构</th><th>环比</th></tr>${dec || '<tr><td colspan="3" class="empty">暂无</td></tr>'}
|
|
</table>`;
|
|
} catch (e) {}
|
|
}
|
|
|
|
async function loadUpgrades() {
|
|
try {
|
|
const d = await api('/api/ratings/upgrades');
|
|
$('#upgradeBox').innerHTML = `<table>
|
|
<tr><th>股票</th><th>机构</th><th>评级</th><th>日期</th></tr>
|
|
${(d.items || []).slice(0, 14).map(r => `
|
|
<tr class="row-link" onclick="location.href='/stock/${r.stock_code}'">
|
|
<td><b>${r.name}</b><div style="color:var(--muted);font-size:12px">${r.stock_code}</div></td>
|
|
<td style="color:var(--text2)">${escapeHtml(r.inst_name)}</td>
|
|
<td><span class="tag tag-${r.rating}">${r.rating}</span> <span style="color:var(--muted);font-size:12px">→ 目标${r.target_price}</span></td>
|
|
<td style="color:var(--muted)">${r.rating_date}</td>
|
|
</tr>`).join('')}
|
|
</table>`;
|
|
} catch (e) {}
|
|
}
|
|
|
|
$$('#typePills .pill').forEach(p => {
|
|
p.onclick = () => {
|
|
$$('#typePills .pill').forEach(x => x.classList.remove('active'));
|
|
p.classList.add('active');
|
|
curType = p.dataset.t;
|
|
loadInsts();
|
|
};
|
|
});
|
|
|
|
loadMoves();
|
|
loadUpgrades();
|
|
loadInsts();
|