diff --git a/static/cond_orders.js b/static/cond_orders.js index 53f17b4..b3787d7 100644 --- a/static/cond_orders.js +++ b/static/cond_orders.js @@ -366,8 +366,7 @@ '">' + '
' + - '
" + "" ); } @@ -444,8 +442,10 @@ const list = (allCandidates || []).filter(function (it) { return candidateMatchesUnderlying(it, uly); }); + const meta = document.getElementById("cf-inst-meta"); if (!(allCandidates || []).length) { box.innerHTML = '暂无启用实例'; + if (meta) meta.textContent = "暂无实例"; return; } if (!list.length) { @@ -453,8 +453,13 @@ '当前标的 ' + escapeHtml(uly) + " 下暂无匹配客户端(请确认实例 OKX_OPTIONS_UNDERLYINGS)"; + if (meta) meta.textContent = "当前 " + uly + " · 可选 0"; return; } + const selectableN = list.filter(function (it) { + return !!it.selectable; + }).length; + if (meta) meta.textContent = "当前 " + uly + " · 可选 " + selectableN; const keep = {}; (checkedIds || []).forEach(function (id) { keep[String(id)] = true; @@ -489,6 +494,27 @@ ); }); }); + box.querySelectorAll("[data-xfer-toggle]").forEach(function (el) { + el.addEventListener("click", function (ev) { + ev.preventDefault(); + ev.stopPropagation(); + const card = el.closest(".cond-inst"); + if (!card || card.classList.contains("is-off")) return; + card.classList.toggle("is-xfer-open"); + }); + }); + box.querySelectorAll(".cond-inst-name").forEach(function (el) { + el.addEventListener("click", function (ev) { + const card = el.closest(".cond-inst"); + if (!card || card.classList.contains("is-off")) return; + const cb = card.querySelector('input[name="cf-inst"]'); + if (!cb || cb.disabled) return; + // 点名称切换勾选(避免点余额误勾) + if (ev.target === el) { + cb.checked = !cb.checked; + } + }); + }); } async function loadCandidates() { @@ -774,6 +800,55 @@ }; } + function syncSegButtons(segId, attr, value) { + const seg = document.getElementById(segId); + if (!seg) return; + seg.querySelectorAll(".cond-seg-btn").forEach(function (btn) { + const on = String(btn.getAttribute(attr) || "") === String(value); + btn.classList.toggle("on", on); + }); + } + + function bindSegGroup(segId, attr, selectId, onChange) { + const seg = document.getElementById(segId); + const sel = document.getElementById(selectId); + if (!seg || !sel) return; + syncSegButtons(segId, attr, sel.value); + seg.querySelectorAll(".cond-seg-btn").forEach(function (btn) { + btn.addEventListener("click", function () { + const v = btn.getAttribute(attr); + if (!v || sel.value === v) { + if (v) syncSegButtons(segId, attr, v); + return; + } + sel.value = v; + syncSegButtons(segId, attr, v); + if (typeof onChange === "function") onChange(v); + }); + }); + sel.addEventListener("change", function () { + syncSegButtons(segId, attr, sel.value); + if (typeof onChange === "function") onChange(sel.value); + }); + } + + function syncPeMultEnabled() { + const pe = document.getElementById("cf-pe"); + const mult = document.getElementById("cf-pe-mult"); + if (!pe || !mult) return; + mult.disabled = !pe.checked; + } + + function currentCheckedInstIds() { + const box = document.getElementById("cf-instances"); + if (!box) return []; + return Array.prototype.slice + .call(box.querySelectorAll('input[name="cf-inst"]:checked')) + .map(function (el) { + return decodeURIComponent(el.value || ""); + }); + } + function boot() { const btn = document.getElementById("btn-cond-refresh"); if (btn) btn.addEventListener("click", function () { @@ -785,20 +860,15 @@ const pxEl = document.getElementById("cf-trigger-px"); if (typeEl) typeEl.addEventListener("change", syncTriggerHint); if (pxEl) pxEl.addEventListener("input", syncTriggerHint); - const ulyEl = document.getElementById("cf-underlying"); - if (ulyEl) { - ulyEl.addEventListener("change", function () { - const box = document.getElementById("cf-instances"); - const checkedIds = box - ? Array.prototype.slice - .call(box.querySelectorAll('input[name="cf-inst"]:checked')) - .map(function (el) { - return decodeURIComponent(el.value || ""); - }) - : []; - paintCandidates(checkedIds); - }); - } + bindSegGroup("cf-uly-seg", "data-uly", "cf-underlying", function () { + paintCandidates(currentCheckedInstIds()); + }); + bindSegGroup("cf-side-seg", "data-side", "cf-opt-type", function () { + syncTriggerHint(); + }); + const pe = document.getElementById("cf-pe"); + if (pe) pe.addEventListener("change", syncPeMultEnabled); + syncPeMultEnabled(); syncTriggerHint(); // 读缓存秒开 + SSE;不再前端定时现场拉实例 refresh(); diff --git a/static/hub.css b/static/hub.css index 3236674..025575b 100644 --- a/static/hub.css +++ b/static/hub.css @@ -1474,58 +1474,122 @@ input.readonly { border-radius: 999px; padding: 3px 10px; } -.cond-section { - border-top: 1px solid rgba(56, 189, 248, 0.12); - padding: 14px 0 4px; +.cond-create-split { + display: grid; + grid-template-columns: minmax(260px, 0.92fr) minmax(300px, 1.18fr); + gap: 16px 18px; + align-items: start; + padding-top: 2px; } -.cond-section:first-of-type { border-top: 0; padding-top: 0; } -.cond-section-title { +.cond-col-title { font-size: 0.78rem; color: var(--accent-2); - letter-spacing: 0.08em; - margin-bottom: 10px; - font-weight: 600; + letter-spacing: 0.06em; + margin: 0 0 10px; + font-weight: 650; } -.cond-grid { +.cond-block { margin-bottom: 14px; } +.cond-block:last-child { margin-bottom: 0; } +.cond-mini-label { + display: block; + font-size: 0.75rem; + color: #b6c7da; + margin-bottom: 6px; +} +.cond-native-select[hidden] { display: none !important; } +.cond-seg { + display: inline-flex; + border: 1px solid var(--line); + border-radius: 9px; + overflow: hidden; + background: rgba(8, 16, 30, 0.8); +} +.cond-seg-btn { + border: 0; + background: transparent; + color: var(--muted); + padding: 8px 14px; + font-size: 0.84rem; + cursor: pointer; + min-width: 72px; + margin: 0; + border-radius: 0; + font-weight: 500; +} +.cond-seg-btn + .cond-seg-btn { border-left: 1px solid var(--line); } +.cond-seg-btn.on { + background: rgba(56, 189, 248, 0.16); + color: var(--text); + font-weight: 650; +} +.cond-param-row { display: grid; - grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); - gap: 12px 14px; + grid-template-columns: 1.25fr 0.7fr 0.7fr; + gap: 10px; align-items: end; } -.cond-grid label { +.cond-field { + display: block; margin: 0; - font-size: 0.8rem; + font-size: 0.75rem; color: #b6c7da; } -.cond-grid input, -.cond-grid select { +.cond-field input { margin-top: 6px; + width: 100%; } +.cond-field-mult { min-width: 72px; } +.cond-field-mult input { width: 72px; } .cond-trigger-hint { - grid-column: 1 / -1; - padding: 9px 12px; - border-radius: 10px; - font-size: 0.82rem; + margin-top: 8px; + padding: 8px 10px; + border-radius: 9px; + font-size: 0.78rem; line-height: 1.45; border: 1px solid var(--line); background: rgba(8, 16, 30, 0.7); color: var(--text); } -.cond-trigger-hint.is-put { border-color: rgba(251, 113, 133, 0.35); } -.cond-trigger-hint.is-call { border-color: rgba(52, 211, 153, 0.35); } +.cond-trigger-hint.is-put { border-color: rgba(251, 113, 133, 0.35); color: #fda4af; } +.cond-trigger-hint.is-call { border-color: rgba(52, 211, 153, 0.35); color: #6ee7b7; } +.cond-exit-row { + display: grid; + grid-template-columns: 1fr auto auto; + gap: 10px; + align-items: end; +} .cond-switch { display: flex !important; align-items: center; gap: 8px; - min-height: 62px; + margin: 0; + padding: 8px 0; + font-size: 0.84rem; + color: var(--text); + white-space: nowrap; + min-height: 0; } .cond-switch input { width: auto; margin: 0; } -.cond-inst-group + .cond-inst-group { margin-top: 14px; } -.cond-inst-group-label { margin-bottom: 8px; } +.cond-right-head { + display: flex; + align-items: baseline; + justify-content: space-between; + gap: 8px; + margin-bottom: 4px; +} +.cond-right-head .cond-col-title { margin: 0; } +.cond-right-meta { font-size: 0.76rem; } +.cond-right-lead { + margin: 0 0 10px; + font-size: 0.76rem; + line-height: 1.4; +} +.cond-inst-group + .cond-inst-group { margin-top: 10px; } +.cond-inst-group-label { margin-bottom: 6px; } .cond-inst-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); - gap: 10px; + display: flex; + flex-direction: column; + gap: 8px; } .cond-inst-row { display: block; @@ -1533,10 +1597,10 @@ input.readonly { } .cond-inst-row.is-off { opacity: 0.5; } .cond-inst { - display: flex; - flex-direction: column; - align-items: stretch; - gap: 8px; + display: grid; + grid-template-columns: auto 1fr auto; + gap: 8px 10px; + align-items: start; min-width: 0; padding: 10px 12px; border-radius: 10px; @@ -1552,41 +1616,51 @@ input.readonly { border-color: rgba(56, 189, 248, 0.55); background: rgba(56, 189, 248, 0.12); } -.cond-inst input { width: auto; margin: 0; flex-shrink: 0; } -.cond-inst-head { - display: flex; - align-items: center; - gap: 8px; - min-width: 0; - cursor: pointer; +.cond-inst > input[type="checkbox"] { + width: auto; + margin: 2px 0 0; + flex-shrink: 0; + grid-column: 1; + grid-row: 1; + align-self: start; +} +.cond-inst-main { + min-width: 0; + grid-column: 2; + grid-row: 1; } -.cond-inst.is-off .cond-inst-head { cursor: not-allowed; } .cond-inst-name { - flex: 1; - font-weight: 600; + display: block; + font-weight: 650; + font-size: 0.92rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; + cursor: pointer; } -.cond-inst-tag { color: var(--muted); font-size: 0.75rem; flex-shrink: 0; } -.cond-inst-body { - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 8px; - padding-left: 24px; - min-width: 0; +.cond-inst.is-off .cond-inst-name { cursor: not-allowed; } +.cond-inst-tag { + color: var(--muted); + font-size: 0.72rem; + flex-shrink: 0; + justify-self: end; + align-self: start; + grid-column: 3; + grid-row: 1; } .cond-inst-fund-line { display: flex; align-items: center; flex-wrap: wrap; - gap: 8px 12px; + gap: 6px 12px; + margin-top: 3px; + cursor: pointer; } +.cond-inst.is-off .cond-inst-fund-line { cursor: default; } .cond-inst-funds { color: var(--accent-2, #38bdf8); - font-size: 0.78rem; + font-size: 0.76rem; font-weight: 600; white-space: nowrap; flex-shrink: 0; @@ -1596,11 +1670,15 @@ input.readonly { font-weight: 500; } .cond-inst-actions { - display: flex; + display: none; align-items: center; flex-wrap: wrap; gap: 6px; + grid-column: 2 / -1; + grid-row: 2; + padding-top: 2px; } +.cond-inst.is-xfer-open .cond-inst-actions { display: flex; } .cond-inst-xfer { flex-shrink: 0; white-space: nowrap; @@ -1615,6 +1693,18 @@ input.readonly { align-items: center; gap: 12px; margin-top: 14px; + padding-top: 12px; + border-top: 1px solid rgba(56, 189, 248, 0.12); +} +@media (max-width: 900px) { + .cond-create-split { grid-template-columns: 1fr; } + .cond-param-row { grid-template-columns: 1fr 1fr 1fr; } + .cond-exit-row { grid-template-columns: 1fr auto auto; } +} +@media (max-width: 560px) { + .cond-param-row, + .cond-exit-row { grid-template-columns: 1fr; } + .cond-field-mult input { width: 100%; } } .cond-empty { padding: 28px 8px; text-align: center; } .cond-st { @@ -2179,16 +2269,16 @@ html.hub-phone-html body.page-cond-orders .cond-card { html.hub-phone-html body.page-cond-orders .cond-card-head { margin-bottom: 10px; } -html.hub-phone-html body.page-cond-orders .cond-grid { - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 10px 12px; -} -html.hub-phone-html body.page-cond-orders .cond-switch { - min-height: 0; - grid-column: 1 / -1; -} -html.hub-phone-html body.page-cond-orders .cond-inst-grid { +html.hub-phone-html body.page-cond-orders .cond-create-split { grid-template-columns: 1fr; + gap: 14px; +} +html.hub-phone-html body.page-cond-orders .cond-param-row, +html.hub-phone-html body.page-cond-orders .cond-exit-row { + grid-template-columns: 1fr; +} +html.hub-phone-html body.page-cond-orders .cond-field-mult input { + width: 100%; } html.hub-phone-html body.page-cond-orders .cond-actions { flex-direction: column; diff --git a/templates/base.html b/templates/base.html index 61c7c0e..5ad024c 100644 --- a/templates/base.html +++ b/templates/base.html @@ -11,7 +11,7 @@ - + + {% endblock %}