feat: two-level entry model UI for trend accounts (reversal/trend/swing)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-06 19:02:18 +08:00
parent eb6788091d
commit ff1bcd69d2
14 changed files with 289 additions and 146 deletions
+3
View File
@@ -1,4 +1,7 @@
.order-trade-style-hint{font-size:.78rem;color:#8fc8ff;margin-left:4px;white-space:nowrap}
.order-entry-model-row{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.order-entry-model-row select.order-entry-category{min-width:4.8em;max-width:6.5em}
.order-entry-model-row select.order-entry-model-sub{min-width:7em;max-width:10rem}
.order-leverage-hint{font-size:.78rem;color:#cfd3ef;white-space:nowrap;align-self:center}
body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;background:#0b0d14;color:#eaeaea;padding:14px 20px}
.container{width:100%;max-width:min(1440px,94vw);margin:0 auto;padding:0 clamp(8px,1.5vw,20px)}
+107 -23
View File
@@ -1,38 +1,125 @@
(function (global) {
function tradeStyleForSelect(sel) {
if (!sel || !sel.value) return "trend";
var opt = sel.options[sel.selectedIndex];
if (opt && opt.getAttribute) {
var ds = opt.getAttribute("data-trade-style");
if (ds === "swing" || ds === "trend") return ds;
}
function categoriesData() {
return global.ORDER_ENTRY_MODEL_CATEGORIES || [];
}
function codeToCategoryMap() {
return global.ORDER_ENTRY_MODEL_CODE_TO_CATEGORY || {};
}
function tradeStyleForCode(code) {
var map = global.ORDER_ENTRY_MODEL_TRADE_STYLE || {};
return map[sel.value] || "trend";
return map[code] || "trend";
}
function findOption(catKey, code) {
var cats = categoriesData();
for (var i = 0; i < cats.length; i++) {
if (cats[i].key !== catKey) continue;
var opts = cats[i].options || [];
for (var j = 0; j < opts.length; j++) {
if (opts[j].code === code) return opts[j];
}
}
return null;
}
function rebuildEntryModelSubSelect(preserveCode) {
var catSel = document.getElementById("order-entry-category");
var modelSel = document.getElementById("order-entry-model");
if (!catSel || !modelSel) return;
var catKey = catSel.value;
var cats = categoriesData();
var cat = null;
for (var i = 0; i < cats.length; i++) {
if (cats[i].key === catKey) {
cat = cats[i];
break;
}
}
modelSel.innerHTML = "";
var placeholder = document.createElement("option");
placeholder.value = "";
placeholder.textContent = "类型";
modelSel.appendChild(placeholder);
if (!cat || !cat.options || !cat.options.length) {
modelSel.disabled = true;
modelSel.value = "";
syncOrderEntryModelTradeStyle();
return;
}
modelSel.disabled = false;
var pick = preserveCode || "";
for (var k = 0; k < cat.options.length; k++) {
var o = cat.options[k];
var opt = document.createElement("option");
opt.value = o.code;
opt.textContent = o.label;
if (o.trade_style) opt.setAttribute("data-trade-style", o.trade_style);
if (o.help) opt.title = o.help;
modelSel.appendChild(opt);
}
if (pick && findOption(catKey, pick)) {
modelSel.value = pick;
} else if (cat.options.length === 1) {
modelSel.value = cat.options[0].code;
} else {
modelSel.value = "";
}
syncOrderEntryModelTradeStyle();
}
function syncOrderEntryModelTradeStyle() {
var sel = document.getElementById("order-entry-model");
var modelSel = document.getElementById("order-entry-model");
var hidden = document.getElementById("order-trade-style-hidden");
var hint = document.getElementById("order-trade-style-hint");
if (!sel || !hidden) return;
if (!modelSel || !hidden) return;
var labels = { trend: "趋势单", swing: "波段单" };
var ts = tradeStyleForSelect(sel);
var code = modelSel.value || "";
var ts = tradeStyleForCode(code);
hidden.value = ts;
if (hint) hint.textContent = labels[ts] || ts;
}
function initOrderEntryModelSelect(root) {
var scope = root && root.querySelector ? root : document;
var sel =
var catSel =
scope === document
? document.getElementById("order-entry-category")
: scope.querySelector("#order-entry-category");
var modelSel =
scope === document
? document.getElementById("order-entry-model")
: scope.querySelector("#order-entry-model");
if (!sel) return;
if (sel.dataset.entryModelWired !== "1") {
sel.dataset.entryModelWired = "1";
sel.addEventListener("change", syncOrderEntryModelTradeStyle);
if (!catSel || !modelSel) return;
if (catSel.dataset.entryModelWired !== "1") {
catSel.dataset.entryModelWired = "1";
catSel.addEventListener("change", function () {
rebuildEntryModelSubSelect("");
});
}
syncOrderEntryModelTradeStyle();
if (modelSel.dataset.entryModelWired !== "1") {
modelSel.dataset.entryModelWired = "1";
modelSel.addEventListener("change", syncOrderEntryModelTradeStyle);
}
var presetCode = modelSel.getAttribute("data-preset-code") || modelSel.value || "";
if (presetCode) {
var catMap = codeToCategoryMap();
var catKey = catMap[presetCode];
if (catKey) {
catSel.value = catKey;
rebuildEntryModelSubSelect(presetCode);
return;
}
}
rebuildEntryModelSubSelect("");
}
global.paintOrderLeverageHint = function (leverage) {
@@ -51,12 +138,9 @@
global.initOrderEntryModelSelect = initOrderEntryModelSelect;
global.syncOrderEntryModelTradeStyle = syncOrderEntryModelTradeStyle;
global.rebuildEntryModelSubSelect = rebuildEntryModelSubSelect;
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", function () {
initOrderEntryModelSelect();
});
} else {
document.addEventListener("DOMContentLoaded", function () {
initOrderEntryModelSelect();
}
});
})(typeof window !== "undefined" ? window : globalThis);