diff --git a/lib/common/static/options_review.js b/lib/common/static/options_review.js index a3a50c4..4db3b53 100644 --- a/lib/common/static/options_review.js +++ b/lib/common/static/options_review.js @@ -32,11 +32,68 @@ var tradesPages = 1; var reviewedPage = 0; var reviewedPages = 1; + var tradesListFp = ""; + var reviewedListFp = ""; + var statsFp = ""; function $(id) { return document.getElementById(id); } + function listFingerprint(kind, data, rows) { + var parts = [ + kind, + activeSource, + String((data && data.total) || 0), + String((data && data.page) || 0), + String((data && data.pages) || 0), + ]; + (rows || []).forEach(function (t) { + var e = t.entry || {}; + parts.push( + [ + t.id, + t.realized_pnl_total, + t.profit_rate, + t.initial_premium_usdt, + t.option_fee_usdt, + t.status_raw, + t.reviewed ? 1 : 0, + t.opened_at, + t.closed_at, + t.hold_seconds, + t.reviewed_at, + t.strategy_tag || e.strategy_tag, + t.result_tag || e.result_tag, + t.direction_view || e.direction_view, + t.entry_logic || e.entry_logic, + t.source_label || t.source_type, + t.inst_id, + t.underlying, + t.direction, + t.plan_close_reason, + ].join("\u001f") + ); + }); + return parts.join("\u001e"); + } + + function statsFingerprint(data) { + try { + return JSON.stringify({ + kpi: data.kpi || {}, + by_source_type: data.by_source_type || [], + by_underlying: data.by_underlying || [], + by_strategy: data.by_strategy || [], + by_close_reason: data.by_close_reason || [], + by_hold_bucket: data.by_hold_bucket || [], + by_opt_type: data.by_opt_type || [], + }); + } catch (_) { + return String(Date.now()); + } + } + function escapeHtml(s) { return String(s == null ? "" : s) .replace(/&/g, "&") @@ -203,7 +260,7 @@ setSyncStatus("读取本地记录…"); loadTrades({ sync: false }); loadReviewed({ sync: false }); - loadStats(); + loadStats({ soft: false }); backgroundSync(); } @@ -221,7 +278,7 @@ setSyncStatus("本地记录已加载"); loadTrades({ sync: false, soft: true }); loadReviewed({ sync: false, soft: true }); - loadStats(); + loadStats({ soft: true }); }) .catch(function () { setSyncStatus("同步跳过,已显示本地缓存"); @@ -379,12 +436,8 @@ function beginListLoad(wrapId, soft) { var wrap = $(wrapId); if (!wrap) return null; - if (soft) { - if (!wrap.style.minHeight) { - wrap.style.minHeight = Math.max(wrap.offsetHeight, 1) + "px"; - } - wrap.classList.add("or-list-loading"); - } else { + // soft 刷新不打半透明:无变化时也不应闪;有变化时静默换表 + if (!soft) { wrap.classList.remove("or-list-loading"); wrap.style.minHeight = ""; } @@ -405,6 +458,7 @@ if (!tbody) return; var wrap = beginListLoad("or-trades-wrap", soft); if (!soft) { + tradesListFp = ""; tbody.innerHTML = '