智能荐股系统 v1.0.0:股票池/行情/新闻RAG/机构持仓/多因子评分/AI深度研报
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
/* 股票池 */
|
||||
let page = 1, total = 0, industries = [];
|
||||
|
||||
async function loadIndustries() {
|
||||
try {
|
||||
const d = await api('/api/overview');
|
||||
industries = d.heat.map(h => h.industry);
|
||||
const sel = $('#industry');
|
||||
industries.forEach(i => {
|
||||
const o = document.createElement('option');
|
||||
o.textContent = i;
|
||||
sel.appendChild(o);
|
||||
});
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
async function load(p) {
|
||||
if (p) page = p;
|
||||
const q = new URLSearchParams({
|
||||
keyword: $('#kw').value.trim(),
|
||||
industry: $('#industry').value,
|
||||
board: $('#board').value,
|
||||
rating: $('#rating').value,
|
||||
sort: $('#sort').value,
|
||||
order: $('#sort').value === 'score' ? 'desc' : 'desc',
|
||||
page: page, per: 20
|
||||
});
|
||||
try {
|
||||
const d = await api('/api/stocks?' + q.toString());
|
||||
total = d.total;
|
||||
render(d.items);
|
||||
$('#pageInfo').textContent = `第 ${page} / ${Math.max(1, Math.ceil(total / 20))} 页 · 共 ${total} 只`;
|
||||
$('#stCount').textContent = `共 ${total} 只`;
|
||||
$('#prevBtn').disabled = page <= 1;
|
||||
$('#nextBtn').disabled = page * 20 >= total;
|
||||
} catch (e) {
|
||||
$('#tb').innerHTML = '<tr><td colspan="12" class="empty">加载失败</td></tr>';
|
||||
}
|
||||
}
|
||||
|
||||
function render(items) {
|
||||
if (!items.length) { $('#tb').innerHTML = '<tr><td colspan="12" class="empty">无匹配股票</td></tr>'; return; }
|
||||
$('#tb').innerHTML = items.map(it => `<tr class="row-link" onclick="location.href='/stock/${it.code}'">
|
||||
<td><b>${it.name}</b><div style="color:var(--muted);font-size:12px">${it.code}</div></td>
|
||||
<td>${escapeHtml(it.industry)}</td>
|
||||
<td style="color:var(--text2)">${it.board}</td>
|
||||
<td class="num">${it.close}</td>
|
||||
<td class="num ${pctClass(it.change_pct)}">${fmtPct(it.change_pct)}</td>
|
||||
<td class="num ${pctClass(it.chg_5d)}">${fmtPct(it.chg_5d)}</td>
|
||||
<td class="num">${it.vol_ratio}</td>
|
||||
<td class="num">${fmtAmountYi(it.amount)}</td>
|
||||
<td class="num">${Number(it.market_cap).toFixed(0)}亿</td>
|
||||
<td class="num"><b style="color:${it.score >= 68 ? '#f59e0b' : it.score >= 55 ? '#3b82f6' : '#9da7b3'}">${it.score}</b></td>
|
||||
<td><span class="tag tag-${it.rating}">${it.rating}</span></td>
|
||||
<td><button class="btn" onclick="event.stopPropagation();addWatch('${it.code}')">⭐自选</button></td>
|
||||
</tr>`).join('');
|
||||
}
|
||||
|
||||
async function addWatch(code) {
|
||||
try { await api('/api/watchlist/' + code, { method: 'POST' }); toast('已加入自选'); }
|
||||
catch (e) { toast('操作失败'); }
|
||||
}
|
||||
|
||||
$('#kw').addEventListener('keydown', e => { if (e.key === 'Enter') load(1); });
|
||||
$('#kw').addEventListener('input', debounce(() => load(1), 400));
|
||||
$('#industry').onchange = () => load(1);
|
||||
$('#board').onchange = () => load(1);
|
||||
$('#rating').onchange = () => load(1);
|
||||
$('#sort').onchange = () => load(1);
|
||||
|
||||
loadIndustries();
|
||||
load(1);
|
||||
Reference in New Issue
Block a user