Paginate hub archive trade records at 5 per page.
Match the instance records pager so 内照明心 lists stay compact with prev/next controls. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -8670,6 +8670,25 @@ body.funds-fullscreen-open {
|
|||||||
background: var(--panel);
|
background: var(--panel);
|
||||||
overscroll-behavior: contain;
|
overscroll-behavior: contain;
|
||||||
}
|
}
|
||||||
|
.archive-trades-pager {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-top: 8px;
|
||||||
|
font-size: 0.74rem;
|
||||||
|
color: var(--muted);
|
||||||
|
}
|
||||||
|
.archive-trades-pager[hidden] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.archive-trades-pager .ghost {
|
||||||
|
font-size: 0.72rem;
|
||||||
|
padding: 2px 8px;
|
||||||
|
}
|
||||||
|
.archive-trades-pager .ghost:disabled {
|
||||||
|
opacity: 0.45;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
.archive-trades-table {
|
.archive-trades-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 1000px;
|
min-width: 1000px;
|
||||||
|
|||||||
@@ -45,8 +45,13 @@
|
|||||||
const elMarkAuto = document.getElementById("archive-mark-auto");
|
const elMarkAuto = document.getElementById("archive-mark-auto");
|
||||||
const elTrades = document.getElementById("archive-trades");
|
const elTrades = document.getElementById("archive-trades");
|
||||||
const elTradesSection = document.getElementById("archive-trades-section");
|
const elTradesSection = document.getElementById("archive-trades-section");
|
||||||
|
const elTradesPager = document.getElementById("archive-trades-pager");
|
||||||
|
const elTradesPrev = document.getElementById("archive-trades-prev");
|
||||||
|
const elTradesNext = document.getElementById("archive-trades-next");
|
||||||
|
const elTradesPageLabel = document.getElementById("archive-trades-page-label");
|
||||||
const ARCHIVE_MARK_AUTO_KEY = "hubArchiveMarkAuto";
|
const ARCHIVE_MARK_AUTO_KEY = "hubArchiveMarkAuto";
|
||||||
const TRADES_VISIBLE_ROWS_CHART_OPEN = 10;
|
const TRADES_PAGE_SIZE = 5;
|
||||||
|
const TRADES_VISIBLE_ROWS_CHART_OPEN = 5;
|
||||||
|
|
||||||
const TF_MS = {
|
const TF_MS = {
|
||||||
"5m": 5 * 60_000,
|
"5m": 5 * 60_000,
|
||||||
@@ -61,6 +66,7 @@
|
|||||||
let selectedQuoteId = null;
|
let selectedQuoteId = null;
|
||||||
let editingQuoteId = null;
|
let editingQuoteId = null;
|
||||||
let dailyTrades = [];
|
let dailyTrades = [];
|
||||||
|
let tradesPage = 0;
|
||||||
let dailyStats = { open_count: 0, by_exchange: {} };
|
let dailyStats = { open_count: 0, by_exchange: {} };
|
||||||
let periodMode = "today";
|
let periodMode = "today";
|
||||||
let periodLabel = "";
|
let periodLabel = "";
|
||||||
@@ -1487,6 +1493,16 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ensureTradePageVisible(tr) {
|
||||||
|
if (!tr || !dailyTrades.length) return;
|
||||||
|
const key = tradeRowKey(tr);
|
||||||
|
const idx = dailyTrades.findIndex(function (t) {
|
||||||
|
return tradeRowKey(t) === key;
|
||||||
|
});
|
||||||
|
if (idx < 0) return;
|
||||||
|
tradesPage = Math.floor(idx / TRADES_PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
async function switchToTrade(tr) {
|
async function switchToTrade(tr) {
|
||||||
if (!tr) return;
|
if (!tr) return;
|
||||||
const exKey = String(tr.exchange_key || "").toLowerCase();
|
const exKey = String(tr.exchange_key || "").toLowerCase();
|
||||||
@@ -1502,6 +1518,7 @@
|
|||||||
|
|
||||||
selected = { exchange_key: exKey, symbol: sym };
|
selected = { exchange_key: exKey, symbol: sym };
|
||||||
selectedTradeKey = key;
|
selectedTradeKey = key;
|
||||||
|
ensureTradePageVisible(tr);
|
||||||
renderTrades();
|
renderTrades();
|
||||||
|
|
||||||
const needSymbolReload = prevEx !== exKey || prevSym !== sym;
|
const needSymbolReload = prevEx !== exKey || prevSym !== sym;
|
||||||
@@ -1535,19 +1552,49 @@
|
|||||||
await switchToTrade(tr);
|
await switchToTrade(tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function tradesPageCount() {
|
||||||
|
return Math.max(1, Math.ceil((dailyTrades.length || 0) / TRADES_PAGE_SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
function clampTradesPage() {
|
||||||
|
const pages = tradesPageCount();
|
||||||
|
if (tradesPage >= pages) tradesPage = pages - 1;
|
||||||
|
if (tradesPage < 0) tradesPage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTradesPager() {
|
||||||
|
clampTradesPage();
|
||||||
|
const pages = tradesPageCount();
|
||||||
|
const show = dailyTrades.length > TRADES_PAGE_SIZE;
|
||||||
|
if (elTradesPager) elTradesPager.hidden = !show;
|
||||||
|
if (elTradesPageLabel) {
|
||||||
|
elTradesPageLabel.textContent = "第 " + (tradesPage + 1) + " / " + pages + " 页";
|
||||||
|
}
|
||||||
|
if (elTradesPrev) elTradesPrev.disabled = tradesPage <= 0;
|
||||||
|
if (elTradesNext) elTradesNext.disabled = tradesPage + 1 >= pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
function pagedDailyTrades() {
|
||||||
|
clampTradesPage();
|
||||||
|
const start = tradesPage * TRADES_PAGE_SIZE;
|
||||||
|
return dailyTrades.slice(start, start + TRADES_PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
function renderTrades() {
|
function renderTrades() {
|
||||||
if (!elTrades) return;
|
if (!elTrades) return;
|
||||||
if (!dailyTrades.length) {
|
if (!dailyTrades.length) {
|
||||||
elTrades.innerHTML =
|
elTrades.innerHTML =
|
||||||
'<p class="archive-empty">该日暂无交易记录.可调整日期或点击「同步」拉取数据.</p>';
|
'<p class="archive-empty">该日暂无交易记录.可调整日期或点击「同步」拉取数据.</p>';
|
||||||
|
updateTradesPager();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const pageRows = pagedDailyTrades();
|
||||||
elTrades.innerHTML =
|
elTrades.innerHTML =
|
||||||
'<table class="archive-trades-table"><thead><tr>' +
|
'<table class="archive-trades-table"><thead><tr>' +
|
||||||
"<th>交易所</th><th>合约</th><th>开仓类型</th><th>开仓时间</th><th>平仓时间</th><th>持仓时长</th>" +
|
"<th>交易所</th><th>合约</th><th>开仓类型</th><th>开仓时间</th><th>平仓时间</th><th>持仓时长</th>" +
|
||||||
"<th>方向</th><th>结果</th><th>盈亏</th><th>成交额</th><th>手续费</th><th>标签</th><th>备注</th><th>操作</th>" +
|
"<th>方向</th><th>结果</th><th>盈亏</th><th>成交额</th><th>手续费</th><th>标签</th><th>备注</th><th>操作</th>" +
|
||||||
"</tr></thead><tbody>" +
|
"</tr></thead><tbody>" +
|
||||||
dailyTrades
|
pageRows
|
||||||
.map(function (t) {
|
.map(function (t) {
|
||||||
const tid = t.trade_id || t.id;
|
const tid = t.trade_id || t.id;
|
||||||
const exKey = String(t.exchange_key || "").toLowerCase();
|
const exKey = String(t.exchange_key || "").toLowerCase();
|
||||||
@@ -1643,6 +1690,8 @@
|
|||||||
.join("") +
|
.join("") +
|
||||||
"</tbody></table>";
|
"</tbody></table>";
|
||||||
|
|
||||||
|
updateTradesPager();
|
||||||
|
|
||||||
elTrades.querySelectorAll(".archive-del-btn").forEach(function (btn) {
|
elTrades.querySelectorAll(".archive-del-btn").forEach(function (btn) {
|
||||||
btn.addEventListener("click", function (ev) {
|
btn.addEventListener("click", function (ev) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
@@ -1781,6 +1830,7 @@
|
|||||||
if (elQuoteDate && tradingDay && !elQuoteDate.value) elQuoteDate.value = tradingDay;
|
if (elQuoteDate && tradingDay && !elQuoteDate.value) elQuoteDate.value = tradingDay;
|
||||||
syncPeriodUI();
|
syncPeriodUI();
|
||||||
dailyTrades = j.trades || [];
|
dailyTrades = j.trades || [];
|
||||||
|
tradesPage = 0;
|
||||||
dailyStats = j.stats || { open_count: 0, by_exchange: {} };
|
dailyStats = j.stats || { open_count: 0, by_exchange: {} };
|
||||||
if (periodMode === "today" && tradingDay) {
|
if (periodMode === "today" && tradingDay) {
|
||||||
selectedCalendarDay = tradingDay;
|
selectedCalendarDay = tradingDay;
|
||||||
@@ -1852,6 +1902,20 @@
|
|||||||
function bindEvents() {
|
function bindEvents() {
|
||||||
if (elBtnRefresh) elBtnRefresh.addEventListener("click", loadDailyTrades);
|
if (elBtnRefresh) elBtnRefresh.addEventListener("click", loadDailyTrades);
|
||||||
if (elBtnSync) elBtnSync.addEventListener("click", syncAll);
|
if (elBtnSync) elBtnSync.addEventListener("click", syncAll);
|
||||||
|
if (elTradesPrev) {
|
||||||
|
elTradesPrev.addEventListener("click", function () {
|
||||||
|
if (tradesPage <= 0) return;
|
||||||
|
tradesPage -= 1;
|
||||||
|
renderTrades();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (elTradesNext) {
|
||||||
|
elTradesNext.addEventListener("click", function () {
|
||||||
|
if (tradesPage + 1 >= tradesPageCount()) return;
|
||||||
|
tradesPage += 1;
|
||||||
|
renderTrades();
|
||||||
|
});
|
||||||
|
}
|
||||||
if (elExchange) {
|
if (elExchange) {
|
||||||
elExchange.addEventListener("change", function () {
|
elExchange.addEventListener("change", function () {
|
||||||
void loadDailyTrades();
|
void loadDailyTrades();
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" media="print" onload="this.media='all'" />
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" media="print" onload="this.media='all'" />
|
||||||
<noscript><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" /></noscript>
|
<noscript><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" /></noscript>
|
||||||
<link rel="stylesheet" href="/assets/app.css?v=20260717-scrollbar-right-all" />
|
<link rel="stylesheet" href="/assets/app.css?v=20260717-archive-pager" />
|
||||||
<link rel="stylesheet" href="/assets/trade_stats_calendar.css?v=4" />
|
<link rel="stylesheet" href="/assets/trade_stats_calendar.css?v=4" />
|
||||||
<link rel="stylesheet" href="/assets/account_risk_badge.css?v=4" />
|
<link rel="stylesheet" href="/assets/account_risk_badge.css?v=4" />
|
||||||
<script src="/assets/account_risk_badge.js?v=4"></script>
|
<script src="/assets/account_risk_badge.js?v=4"></script>
|
||||||
@@ -544,6 +544,11 @@
|
|||||||
<details id="archive-trades-section" class="archive-acc-section archive-trades-section archive-panel-desktop" open>
|
<details id="archive-trades-section" class="archive-acc-section archive-trades-section archive-panel-desktop" open>
|
||||||
<summary class="archive-acc-summary">交易记录</summary>
|
<summary class="archive-acc-summary">交易记录</summary>
|
||||||
<div id="archive-trades" class="archive-trades"></div>
|
<div id="archive-trades" class="archive-trades"></div>
|
||||||
|
<div class="archive-trades-pager" id="archive-trades-pager" hidden>
|
||||||
|
<button type="button" class="ghost" id="archive-trades-prev">上一页</button>
|
||||||
|
<span class="muted" id="archive-trades-page-label">第 1 / 1 页</span>
|
||||||
|
<button type="button" class="ghost" id="archive-trades-next">下一页</button>
|
||||||
|
</div>
|
||||||
</details>
|
</details>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
@@ -1311,7 +1316,7 @@
|
|||||||
<script src="/assets/plan.js?v=20260614-plan-refresh"></script>
|
<script src="/assets/plan.js?v=20260614-plan-refresh"></script>
|
||||||
<script src="/assets/calculator.js?v=20260715-calc-tabs"></script>
|
<script src="/assets/calculator.js?v=20260715-calc-tabs"></script>
|
||||||
<script src="/assets/trade_stats_calendar.js?v=3"></script>
|
<script src="/assets/trade_stats_calendar.js?v=3"></script>
|
||||||
<script src="/assets/archive.js?v=20260710-archive-cum2"></script>
|
<script src="/assets/archive.js?v=20260717-trades-pager"></script>
|
||||||
<script src="/assets/funds.js?v=20260717-funds-scroll-fix"></script>
|
<script src="/assets/funds.js?v=20260717-funds-scroll-fix"></script>
|
||||||
<script src="/assets/dashboard.js?v=20260708-options-expiry-cd"></script>
|
<script src="/assets/dashboard.js?v=20260708-options-expiry-cd"></script>
|
||||||
<script src="/assets/strategy.js?v=3"></script>
|
<script src="/assets/strategy.js?v=3"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user