diff --git a/lib/common/static/hedge_plan.js b/lib/common/static/hedge_plan.js index 89ec163..577597e 100644 --- a/lib/common/static/hedge_plan.js +++ b/lib/common/static/hedge_plan.js @@ -6,6 +6,7 @@ if (!root) return; const state = { + tab: "perp_options", mode: "perp_options", underlying: root.getAttribute("data-default-underly") || "ETH", chain: null, @@ -37,14 +38,28 @@ return dir === "short" ? "C" : "P"; } - function syncModeUI() { - document.querySelectorAll(".hp-mode-btn").forEach(function (b) { - b.classList.toggle("active", b.getAttribute("data-mode") === state.mode); + function syncTabUI() { + const tab = state.tab || "perp_options"; + document.querySelectorAll(".hp-tab").forEach(function (b) { + const on = b.getAttribute("data-tab") === tab; + b.classList.toggle("active", on); + b.setAttribute("aria-selected", on ? "true" : "false"); }); - const po = $("hp-po-layout"); - const oo = $("hp-oo-layout"); - if (po) po.classList.toggle("hidden", state.mode !== "perp_options"); - if (oo) oo.classList.toggle("hidden", state.mode !== "options_options"); + ["perp_options", "options_options", "history", "stats"].forEach(function (id) { + const panel = $("hp-tab-" + id); + if (!panel) return; + const on = id === tab; + panel.classList.toggle("hidden", !on); + if (on) panel.removeAttribute("hidden"); + else panel.setAttribute("hidden", ""); + }); + if (tab === "perp_options" || tab === "options_options") { + state.mode = tab; + } + } + + function syncModeUI() { + syncTabUI(); } function setGateLine(gates) { @@ -341,11 +356,12 @@ } async function runPreview() { - const tbody = $("hp-result-tbody"); - const summary = $("hp-summary"); + const isOo = state.mode === "options_options"; + const tbody = $(isOo ? "hp-result-tbody-oo" : "hp-result-tbody"); + const summary = $(isOo ? "hp-summary-oo" : "hp-summary"); try { let body; - if (state.mode === "options_options") { + if (isOo) { if (!state.legA || !state.legB) throw new Error("请选用两条期权腿"); const target = Number(($("hp-target") && $("hp-target").value) || 0); if (!target) throw new Error("请填写目标价"); @@ -408,6 +424,7 @@ (s.expiry_is_loss ? " · 到期无盈利(记总亏损)" : ""); } } + if (!tbody) return; tbody.innerHTML = ""; (d.scenarios || []).forEach(function (sc) { const tr = document.createElement("tr"); @@ -441,11 +458,21 @@ } function bind() { - document.querySelectorAll(".hp-mode-btn").forEach(function (b) { + document.querySelectorAll(".hp-tab").forEach(function (b) { b.addEventListener("click", function () { - state.mode = b.getAttribute("data-mode") || "perp_options"; - syncModeUI(); - loadGates(); + state.tab = b.getAttribute("data-tab") || "perp_options"; + syncTabUI(); + if (state.tab === "perp_options" || state.tab === "options_options") { + void loadGates(); + } else { + const el = $("hp-gate-line"); + if (el) { + el.textContent = + state.tab === "history" + ? "历史记录:独立对冲表,与普通交易记录分离" + : "统计:止盈=盈利−保费;止损=期权盈利−永续亏损"; + } + } }); }); document.querySelectorAll(".hp-uly-btn, .hp-uly-btn-oo").forEach(function (b) { @@ -468,27 +495,37 @@ }); }); } - if ($("hp-refresh")) $("hp-refresh").addEventListener("click", function () { - void refreshAll(); - }); - if ($("hp-load-chain")) $("hp-load-chain").addEventListener("click", function () { - void loadChain(); - }); - if ($("hp-oo-load-chain")) $("hp-oo-load-chain").addEventListener("click", function () { - void loadChain(); - }); - if ($("hp-exp-select")) - $("hp-exp-select").addEventListener("change", renderListStrikes); - if ($("hp-oo-exp-select")) - $("hp-oo-exp-select").addEventListener("change", renderTStrikes); + if ($("hp-refresh")) + $("hp-refresh").addEventListener("click", function () { + void refreshAll(); + }); + if ($("hp-load-chain")) + $("hp-load-chain").addEventListener("click", function () { + void loadChain(); + }); + if ($("hp-oo-load-chain")) + $("hp-oo-load-chain").addEventListener("click", function () { + void loadChain(); + }); + if ($("hp-exp-select")) $("hp-exp-select").addEventListener("change", renderListStrikes); + if ($("hp-oo-exp-select")) $("hp-oo-exp-select").addEventListener("change", renderTStrikes); if ($("hp-sheets")) $("hp-sheets").addEventListener("input", updatePremiumLine); - if ($("hp-preview-btn")) $("hp-preview-btn").addEventListener("click", function () { - void runPreview(); - }); + if ($("hp-preview-btn")) + $("hp-preview-btn").addEventListener("click", function () { + state.mode = "perp_options"; + void runPreview(); + }); + if ($("hp-preview-btn-oo")) + $("hp-preview-btn-oo").addEventListener("click", function () { + state.mode = "options_options"; + void runPreview(); + }); } async function refreshAll() { - await loadGates(); + if (state.tab === "perp_options" || state.tab === "options_options") { + await loadGates(); + } try { await loadMarket(); } catch (e) { @@ -503,7 +540,7 @@ } } - syncModeUI(); + syncTabUI(); bind(); void refreshAll(); })(); diff --git a/lib/common/static/instance_theme.css b/lib/common/static/instance_theme.css index c10a42e..b4e6b56 100644 --- a/lib/common/static/instance_theme.css +++ b/lib/common/static/instance_theme.css @@ -3167,6 +3167,95 @@ html[data-theme="light"] .opt-be-dist-down { .options-strike-table-wrap--t { max-height: 380px; } + +/* 对冲计划 Tab:高对比选中态 */ +.hedge-plan-page-wrap .hp-head-card { + margin-bottom: 12px; +} +.hedge-plan-page-wrap .hp-head-row { + display: flex; + flex-wrap: wrap; + gap: 10px; + align-items: center; + justify-content: space-between; + margin-bottom: 12px; +} +.hedge-plan-page-wrap .hp-title { + margin: 0; +} +.hedge-plan-page-wrap .hp-title-sub { + font-size: 0.85rem; + font-weight: 400; +} +.hedge-plan-page-wrap .hp-tabs { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin: 0 0 10px; + padding: 6px; + border-radius: 10px; + background: rgba(0, 0, 0, 0.28); + border: 1px solid rgba(255, 255, 255, 0.08); +} +.hedge-plan-page-wrap .hp-tab { + appearance: none; + border: 1px solid rgba(255, 255, 255, 0.14); + background: rgba(255, 255, 255, 0.04); + color: #aeb6c5; + font-size: 0.92rem; + font-weight: 600; + padding: 9px 16px; + border-radius: 8px; + cursor: pointer; + line-height: 1.2; + transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease; +} +.hedge-plan-page-wrap .hp-tab:hover { + color: #eef3ff; + border-color: rgba(120, 170, 255, 0.45); + background: rgba(74, 124, 255, 0.16); +} +.hedge-plan-page-wrap .hp-tab.active { + color: #0b1220; + background: linear-gradient(180deg, #d7e6ff 0%, #8eb6ff 100%); + border-color: #fff; + box-shadow: 0 0 0 2px rgba(142, 182, 255, 0.55), 0 6px 16px rgba(0, 0, 0, 0.35); +} +.hedge-plan-page-wrap .hp-tab-panel.hidden, +.hedge-plan-page-wrap .hp-tab-panel[hidden] { + display: none !important; +} +.hedge-plan-page-wrap .hp-placeholder { + margin: 16px 0 4px; + padding: 18px; + text-align: center; + border-radius: 8px; + border: 1px dashed rgba(255, 255, 255, 0.16); + color: #9aa4b2; + background: rgba(255, 255, 255, 0.03); +} +.hedge-plan-page-wrap #hp-gate-line { + margin: 0; +} +html[data-theme="light"] .hedge-plan-page-wrap .hp-tabs { + background: rgba(15, 23, 42, 0.06); + border-color: rgba(15, 23, 42, 0.1); +} +html[data-theme="light"] .hedge-plan-page-wrap .hp-tab { + background: #fff; + color: #5b6472; + border-color: rgba(15, 23, 42, 0.14); +} +html[data-theme="light"] .hedge-plan-page-wrap .hp-tab.active { + color: #0b1220; + background: linear-gradient(180deg, #ffffff 0%, #b9d2ff 100%); + border-color: #2f6fed; + box-shadow: 0 0 0 2px rgba(47, 111, 237, 0.25); +} +html[data-theme="light"] .hedge-plan-page-wrap .hp-placeholder { + border-color: rgba(15, 23, 42, 0.18); + background: rgba(15, 23, 42, 0.03); +} .options-strike-table--t thead th { text-align: center; } diff --git a/lib/hedge_plan/templates/hedge_plan_panel.html b/lib/hedge_plan/templates/hedge_plan_panel.html index ec80121..3fb70f9 100644 --- a/lib/hedge_plan/templates/hedge_plan_panel.html +++ b/lib/hedge_plan/templates/hedge_plan_panel.html @@ -11,134 +11,179 @@