feat条件单新建改为左策略右选机双栏布局。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-13 19:41:04 +08:00
parent e2a28e6c94
commit 96c78b2ed1
4 changed files with 308 additions and 128 deletions
+93 -23
View File
@@ -366,8 +366,7 @@
'">' +
'<div class="cond-inst' +
(disabled ? " is-off" : "") +
'">' +
'<label class="cond-inst-head" title="' +
'" title="' +
escapeHtml(tip) +
'">' +
'<input type="checkbox" name="cf-inst" value="' +
@@ -376,15 +375,11 @@
(disabled ? " disabled" : "") +
(checked ? " checked" : "") +
">" +
'<div class="cond-inst-main">' +
'<span class="cond-inst-name">' +
escapeHtml(it.name || "") +
"</span>" +
'<span class="cond-inst-tag">' +
escapeHtml(tip) +
"</span>" +
"</label>" +
'<div class="cond-inst-body">' +
'<span class="cond-inst-fund-line">' +
'<span class="cond-inst-fund-line" data-xfer-toggle="1">' +
'<span class="cond-inst-funds cond-inst-funds--trading" title="交易账户可用">交易 ' +
escapeHtml(fmtTradingU(it.trading_usdt)) +
"</span>" +
@@ -392,6 +387,10 @@
escapeHtml(fmtTradingU(it.funding_usdt)) +
"</span>" +
"</span>" +
"</div>" +
'<span class="cond-inst-tag">' +
escapeHtml(tip) +
"</span>" +
'<span class="cond-inst-actions">' +
'<button type="button" class="btn btn-secondary btn-sm cond-inst-xfer" data-inst-id="' +
escapeHtml(id) +
@@ -409,7 +408,6 @@
">划入资金</button>" +
"</span>" +
"</div>" +
"</div>" +
"</div>"
);
}
@@ -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 = '<span class="muted">暂无启用实例</span>';
if (meta) meta.textContent = "暂无实例";
return;
}
if (!list.length) {
@@ -453,8 +453,13 @@
'<span class="muted">当前标的 ' +
escapeHtml(uly) +
" 下暂无匹配客户端(请确认实例 OKX_OPTIONS_UNDERLYINGS)</span>";
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();
+151 -61
View File
@@ -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;