feat: daily volume top20 rank per exchange in market page
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -89,6 +89,9 @@
|
||||
|
||||
const elExchange = document.getElementById("market-exchange");
|
||||
const elSymbol = document.getElementById("market-symbol");
|
||||
const elVolRankMeta = document.getElementById("market-vol-rank-meta");
|
||||
const elVolRankList = document.getElementById("market-vol-rank-list");
|
||||
const elVolRankDetails = document.getElementById("market-vol-rank");
|
||||
const elTf = document.getElementById("market-timeframe");
|
||||
const elRefresh = document.getElementById("market-refresh");
|
||||
const elStatus = document.getElementById("market-status");
|
||||
@@ -2613,6 +2616,68 @@
|
||||
void postChartUnwatch();
|
||||
}
|
||||
|
||||
function renderVolumeRank(data) {
|
||||
if (!elVolRankMeta || !elVolRankList) return;
|
||||
elVolRankList.innerHTML = "";
|
||||
if (!data || !data.ok || !data.items || !data.items.length) {
|
||||
elVolRankMeta.textContent =
|
||||
(data && data.msg) || "暂无排名数据(请稍后或检查实例 /api/hub/volume-rank)";
|
||||
return;
|
||||
}
|
||||
const resetHour = data.reset_hour != null ? data.reset_hour : 8;
|
||||
const rankDate = data.rank_date || "—";
|
||||
const updated = data.updated_at || "—";
|
||||
elVolRankMeta.textContent =
|
||||
"昨日成交 Top20 · 交易日 " + rankDate + " · 每早 " + resetHour + ":00 更新 · " + updated;
|
||||
const curSym = (elSymbol && elSymbol.value.trim().toUpperCase()) || "";
|
||||
data.items.forEach(function (row) {
|
||||
const li = document.createElement("li");
|
||||
const btn = document.createElement("button");
|
||||
btn.type = "button";
|
||||
btn.className = "market-vol-rank-item";
|
||||
if (row.symbol && row.symbol.toUpperCase() === curSym) {
|
||||
btn.classList.add("is-active");
|
||||
}
|
||||
btn.dataset.symbol = row.symbol || "";
|
||||
btn.innerHTML =
|
||||
'<span class="market-vol-rank-no">' +
|
||||
(row.rank || "") +
|
||||
'</span><span class="market-vol-rank-sym">' +
|
||||
(row.symbol || "") +
|
||||
'</span><span class="market-vol-rank-vol">' +
|
||||
(row.volume_label || "") +
|
||||
"</span>";
|
||||
btn.addEventListener("click", function () {
|
||||
if (!elSymbol || !row.symbol) return;
|
||||
elSymbol.value = row.symbol;
|
||||
if (elVolRankDetails) elVolRankDetails.open = false;
|
||||
loadChart(false);
|
||||
});
|
||||
li.appendChild(btn);
|
||||
elVolRankList.appendChild(li);
|
||||
});
|
||||
}
|
||||
|
||||
async function loadVolumeRank() {
|
||||
const exKey = (elExchange && elExchange.value) || "";
|
||||
if (!exKey || !elVolRankMeta) return;
|
||||
elVolRankMeta.textContent = "加载排名…";
|
||||
if (elVolRankList) elVolRankList.innerHTML = "";
|
||||
try {
|
||||
const r = await fetch(
|
||||
"/api/chart/volume-rank?exchange_key=" + encodeURIComponent(exKey),
|
||||
{ credentials: "same-origin" }
|
||||
);
|
||||
const data = await r.json();
|
||||
if (!r.ok) {
|
||||
throw new Error((data && data.detail) || (data && data.msg) || "加载失败");
|
||||
}
|
||||
renderVolumeRank(data);
|
||||
} catch (e) {
|
||||
renderVolumeRank({ ok: false, msg: String(e.message || e) });
|
||||
}
|
||||
}
|
||||
|
||||
async function loadMeta() {
|
||||
const r = await fetch("/api/chart/meta", { credentials: "same-origin" });
|
||||
chartMeta = await r.json();
|
||||
@@ -2628,6 +2693,7 @@
|
||||
readQuery();
|
||||
applyDefaults();
|
||||
updateExchangeDisplay();
|
||||
void loadVolumeRank();
|
||||
}
|
||||
|
||||
async function loadChart(force, options) {
|
||||
@@ -2767,6 +2833,7 @@
|
||||
updateExchangeDisplay();
|
||||
syncFsToolbarFromMain();
|
||||
lastViewKey = "";
|
||||
void loadVolumeRank();
|
||||
loadChart(false);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user