From 5396fcd1f0ad9e7c1e756874ca3e55185311d247 Mon Sep 17 00:00:00 2001 From: dekun Date: Sat, 3 Oct 2026 04:02:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=80=BB=E8=A7=88=E6=8C=81=E4=BB=93=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=E5=87=BA=E5=9C=BA=EF=BC=9B=E5=86=85=E5=B5=8C=E6=89=93?= =?UTF-8?q?=E5=BC=80=E6=94=B9=E4=B8=BA=E6=89=93=E5=BC=80=E5=B9=B6=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E6=96=B0=E6=A0=87=E7=AD=BE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- static/hub.css | 10 +++++++++ static/hub.js | 44 +++++++++++++++++++++++++++------------- templates/dashboard.html | 2 +- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/static/hub.css b/static/hub.css index 2a92a68..769ca15 100644 --- a/static/hub.css +++ b/static/hub.css @@ -403,6 +403,16 @@ button, .btn { .pos-brief li { margin: 2px 0; } +.pos-exit { + margin-top: 2px; + font-size: 0.76rem; + color: var(--text); + opacity: 0.9; +} +.pos-exit.muted { + color: var(--muted); + opacity: 1; +} .card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); diff --git a/static/hub.js b/static/hub.js index 66b48a5..f482020 100644 --- a/static/hub.js +++ b/static/hub.js @@ -24,12 +24,36 @@ .replace(/"/g, """); } + function formatExitBrief(p) { + if (p && p.target_monitor_text && String(p.target_monitor_text).trim() && p.target_monitor_text !== "—") { + return String(p.target_monitor_text).trim(); + } + const parts = []; + const tgt = Number(p && p.target_index); + if (Number.isFinite(tgt) && tgt > 0) { + const ot = String((p && p.opt_type) || "").toUpperCase(); + const side = ot === "P" ? "Put≤" : ot === "C" ? "Call≥" : "目标"; + parts.push(side + " " + tgt); + } + if (p && p.profit_exit_enabled) { + const m = Number(p.profit_exit_mult); + if (Number.isFinite(m) && m > 0) { + parts.push(Math.abs(m - Math.round(m)) < 1e-9 ? Math.round(m) + "倍" : m + "倍"); + } else { + parts.push("利润出场"); + } + } + return parts.length ? parts.join(" · ") : "未设出场"; + } + function positionSummary(brief) { const list = brief || []; if (!list.length) return '暂无持仓'; const items = list.slice(0, 8).map(function (p) { const id = p.inst_id || ""; const sheets = escapeHtml(String(p.sheets != null ? p.sheets : "—")); + const exitText = formatExitBrief(p); + const exitCls = exitText === "未设出场" ? "muted" : ""; return ( "
  • " + escapeHtml(id) + @@ -37,7 +61,11 @@ sheets + "张 · " + fmtPnlHtml(p.pnl_usdt) + - "
  • " + '
    出场: ' + + escapeHtml(exitText) + + "
    " ); }); const more = @@ -233,10 +261,7 @@ '
    ' + '内嵌打开' + - '' + + '">打开' + closeActionButtons(brief, row.id, online) + "
    " + "" @@ -442,15 +467,6 @@ "" + list.map(renderRow).join("") + ""; - grid.querySelectorAll("[data-open-tab]").forEach(function (btn) { - btn.addEventListener("click", async function () { - const id = btn.getAttribute("data-open-tab"); - const rr = await fetch("/api/instances/" + id + "/open_url"); - const dd = await rr.json(); - if (dd.ok && dd.url) window.open(dd.url, "_blank", "noopener"); - else alert(dd.msg || "无法打开"); - }); - }); grid.querySelectorAll("[data-close-opt]").forEach(function (btn) { btn.addEventListener("click", function () { requestClose(btn); diff --git a/templates/dashboard.html b/templates/dashboard.html index 0378720..922c471 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -14,6 +14,6 @@
    {% endblock %} {% block scripts %} - + {% endblock %}