diff --git a/lib/common/static/instance_theme.css b/lib/common/static/instance_theme.css index 5a62a78..36b4129 100644 --- a/lib/common/static/instance_theme.css +++ b/lib/common/static/instance_theme.css @@ -2197,12 +2197,48 @@ html[data-theme="light"] .journal-detail-img-thumb { .settings-side-col { display: flex; flex-direction: column; - gap: 8px; + gap: 0; align-self: stretch; height: 100%; min-height: 0; } +.settings-card--side-panel { + height: 100%; + min-height: 0; + display: flex; + flex-direction: column; + padding: 10px 12px; + overflow: hidden; +} + +.settings-side-subcards { + display: flex; + flex-direction: column; + gap: 8px; + flex: 1 1 auto; + min-height: 0; +} + +.settings-side-subcards > .settings-subcard { + flex: 1 1 0; + min-height: 0; + overflow-y: auto; + padding: 8px 10px; + margin: 0; +} + +.settings-side-subcards > .settings-subcard--export { + flex: 0 0 auto; + overflow: visible; +} + +.settings-subcard-desc { + font-size: 0.7rem; + margin: 0 0 6px; + line-height: 1.4; +} + .settings-card--risk { min-width: 0; height: 100%; @@ -2210,28 +2246,13 @@ html[data-theme="light"] .journal-detail-img-thumb { flex-direction: column; } -.settings-side-col > .settings-card { - flex: 1 1 0; - min-height: 0; - overflow-y: auto; - display: flex; - flex-direction: column; -} - -.settings-side-col > .settings-card--export { - flex: 0 0 auto; - min-height: 0; - overflow: visible; -} - -.settings-side-col .settings-card--export .settings-link-list { +.settings-link-list--export { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; - flex: 0 0 auto; } -.settings-side-col .settings-card--export .settings-export-link { +.settings-link-list--export .settings-export-link { display: flex; align-items: center; justify-content: center; @@ -2244,7 +2265,7 @@ html[data-theme="light"] .journal-detail-img-thumb { } @media (max-width: 520px) { - .settings-side-col .settings-card--export .settings-link-list { + .settings-link-list--export { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @@ -2842,10 +2863,89 @@ html[data-theme="light"] .settings-export-link { margin: 0 0 6px; line-height: 1.45; } +.options-transfer-compact { + display: flex; + flex-direction: column; + gap: 8px; +} + +.options-transfer-block { + display: flex; + flex-direction: column; + gap: 4px; +} + +.options-transfer-head { + font-size: 0.72rem; + font-weight: 600; + color: #a8b0cc; + line-height: 1.3; +} + +.options-transfer-line { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 5px; +} + +.options-transfer-acct { + font-size: 0.68rem; + color: #8892b0; + white-space: nowrap; + padding: 0 2px; +} + +.opt-set-chip-group { + display: inline-flex; + border: 1px solid var(--border-soft, #2a3150); + border-radius: 6px; + overflow: hidden; + flex-shrink: 0; +} + +.opt-set-chip { + border: none; + background: transparent; + color: #a8b0cc; + font-size: 0.68rem; + line-height: 1.2; + padding: 4px 7px; + cursor: pointer; + white-space: nowrap; +} + +.opt-set-chip:hover { + background: rgba(143, 200, 255, 0.08); + color: #cfd3ef; +} + +.opt-set-chip.active { + background: #1f3a5a; + color: #8fc8ff; +} + +.opt-set-amount { + width: 72px; + min-width: 64px; + font-size: 0.72rem; + padding: 4px 6px; + min-height: 26px; +} + +.options-swap-compact .options-settings-hint { + margin: 0 0 5px; +} + +.options-swap-compact .options-transfer-line { + margin-bottom: 0; +} + .options-settings-msg { - font-size: 0.7rem; - margin-top: 4px; + font-size: 0.68rem; + margin-top: 2px; min-height: 1em; + line-height: 1.35; } .pos-pnl-profit { color: #7ee787; diff --git a/lib/common/static/options_settings.js b/lib/common/static/options_settings.js index 4e7f27b..06c8b36 100644 --- a/lib/common/static/options_settings.js +++ b/lib/common/static/options_settings.js @@ -16,60 +16,99 @@ el.classList.toggle("opt-error", !!isErr); } - document.getElementById("opt-set-swap-btn").addEventListener("click", async function () { - const amount = parseFloat(document.getElementById("opt-set-swap-amount").value); - if (!amount || amount <= 0) { - setMsg("opt-set-swap-msg", "请输入有效数量", true); - return; - } - const d = await apiJson("/api/options/spot/swap", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - direction: document.getElementById("opt-set-swap-dir").value, - amount: amount, - }), + function wireChipGroup(id) { + const group = document.getElementById(id); + if (!group) return function () { + return null; + }; + const chips = group.querySelectorAll(".opt-set-chip"); + chips.forEach(function (chip) { + chip.addEventListener("click", function () { + chips.forEach(function (c) { + c.classList.remove("active"); + }); + chip.classList.add("active"); + }); }); - setMsg("opt-set-swap-msg", d.ok ? "兑换单已提交" : (d.msg || "失败"), !d.ok); - }); + return function () { + return group.querySelector(".opt-set-chip.active"); + }; + } - document.getElementById("opt-set-int-btn").addEventListener("click", async function () { - const amount = parseFloat(document.getElementById("opt-set-int-amount").value); - if (!amount || amount <= 0) { - setMsg("opt-set-int-msg", "请输入有效数量", true); - return; - } - const d = await apiJson("/api/options/transfer", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - ccy: document.getElementById("opt-set-int-ccy").value, - from: document.getElementById("opt-set-int-from").value, - to: document.getElementById("opt-set-int-to").value, - amount: amount, - }), - }); - setMsg("opt-set-int-msg", d.ok ? "划转成功" : (d.msg || "失败"), !d.ok); - }); + const activeSwapDir = wireChipGroup("opt-set-swap-dir"); + const activeIntDir = wireChipGroup("opt-set-int-dir"); + const activeIntCcy = wireChipGroup("opt-set-int-ccy"); + const activeCrossDir = wireChipGroup("opt-set-cross-dir"); + const activeCrossCcy = wireChipGroup("opt-set-cross-ccy"); - document.getElementById("opt-set-cross-btn").addEventListener("click", async function () { - const amount = parseFloat(document.getElementById("opt-set-cross-amount").value); - if (!amount || amount <= 0) { - setMsg("opt-set-cross-msg", "请输入有效数量", true); - return; - } - const d = await apiJson("/api/options/cross-transfer", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - ccy: document.getElementById("opt-set-cross-ccy").value, - amount: amount, - from_account: document.getElementById("opt-set-cross-from-acct").value, - to_account: document.getElementById("opt-set-cross-to-acct").value, - direction: document.getElementById("opt-set-cross-dir").value, - }), + const swapBtn = document.getElementById("opt-set-swap-btn"); + if (swapBtn) { + swapBtn.addEventListener("click", async function () { + const amount = parseFloat(document.getElementById("opt-set-swap-amount").value); + if (!amount || amount <= 0) { + setMsg("opt-set-swap-msg", "请输入有效数量", true); + return; + } + const dirChip = activeSwapDir(); + const d = await apiJson("/api/options/spot/swap", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + direction: (dirChip && dirChip.getAttribute("data-dir")) || "usdt_to_usdc", + amount: amount, + }), + }); + setMsg("opt-set-swap-msg", d.ok ? "兑换单已提交" : (d.msg || "失败"), !d.ok); }); - setMsg("opt-set-cross-msg", d.ok ? "划转成功" : (d.msg || "失败"), !d.ok); - if (d.ok && typeof refreshAccountSnapshot === "function") refreshAccountSnapshot(); - }); + } + + const intBtn = document.getElementById("opt-set-int-btn"); + if (intBtn) { + intBtn.addEventListener("click", async function () { + const amount = parseFloat(document.getElementById("opt-set-int-amount").value); + if (!amount || amount <= 0) { + setMsg("opt-set-int-msg", "请输入有效数量", true); + return; + } + const dirChip = activeIntDir(); + const ccyChip = activeIntCcy(); + const d = await apiJson("/api/options/transfer", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + ccy: (ccyChip && ccyChip.getAttribute("data-ccy")) || "USDC", + from: (dirChip && dirChip.getAttribute("data-from")) || "funding", + to: (dirChip && dirChip.getAttribute("data-to")) || "trading", + amount: amount, + }), + }); + setMsg("opt-set-int-msg", d.ok ? "划转成功" : (d.msg || "失败"), !d.ok); + }); + } + + const crossBtn = document.getElementById("opt-set-cross-btn"); + if (crossBtn) { + crossBtn.addEventListener("click", async function () { + const amount = parseFloat(document.getElementById("opt-set-cross-amount").value); + if (!amount || amount <= 0) { + setMsg("opt-set-cross-msg", "请输入有效数量", true); + return; + } + const dirChip = activeCrossDir(); + const ccyChip = activeCrossCcy(); + const d = await apiJson("/api/options/cross-transfer", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + ccy: (ccyChip && ccyChip.getAttribute("data-ccy")) || "USDT", + amount: amount, + from_account: "funding", + to_account: "funding", + direction: (dirChip && dirChip.getAttribute("data-dir")) || "sub_to_main", + }), + }); + setMsg("opt-set-cross-msg", d.ok ? "划转成功" : (d.msg || "失败"), !d.ok); + if (d.ok && typeof refreshAccountSnapshot === "function") refreshAccountSnapshot(); + }); + } })(); diff --git a/lib/instance/templates/embed_shell.html b/lib/instance/templates/embed_shell.html index 8196fbb..7b52524 100644 --- a/lib/instance/templates/embed_shell.html +++ b/lib/instance/templates/embed_shell.html @@ -7,7 +7,7 @@ - +
主账户期权资金:账户内划转、主账户与子账户之间划转。
- {% include 'options_settings_transfer.html' %} -子账户永续:资金账户与交易账户之间划转 USDT。
- {% include 'instance_transfer_panel.html' %} -子账户永续:资金账户与交易账户之间划转 USDT。
+ {% include 'instance_transfer_panel.html' %} +