Fix perp manual order watch_entry bug; slim dialog UI; nav shows 永期/期期.

Manual market_order was validated as watch (missing watch_entry=0). Collapse order calc into details, remove page head card, show mode name in nav.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-14 16:19:15 +08:00
parent 78b909761d
commit 7d29181a04
8 changed files with 177 additions and 61 deletions
+62 -16
View File
@@ -1002,23 +1002,46 @@
}
function setGateLine(gates) {
const text = (function () {
if (!gates) return "";
const parts = [
"计仓:" + (gates.is_full_margin ? "全仓" : "非全仓"),
"测算:" + (gates.can_preview ? "可" : "否"),
"开仓:" + (gates.can_start ? "可" : "否"),
];
if (gates.reasons && gates.reasons.length) parts.push(gates.reasons.join("; "));
return parts.join(" · ");
})();
const el = $("hp-gate-line");
if (!el) return;
if (!gates) {
el.textContent = "";
return;
}
const parts = [
"计仓:" + (gates.is_full_margin ? "全仓" : "非全仓"),
"测算:" + (gates.can_preview ? "可" : "否"),
"开仓:" + (gates.can_start ? "可" : "否"),
];
if (gates.reasons && gates.reasons.length) parts.push(gates.reasons.join("; "));
el.textContent = parts.join(" · ");
state.canStart = !!gates.can_start;
if (el) el.textContent = text;
const inline = $("hp-po-gate-inline");
if (inline) inline.textContent = text;
state.canStart = !!(gates && gates.can_start);
syncPreviewStartBtn();
}
function setPoOrderErr(msg, focusId) {
const err = $("hp-po-order-err");
if (err) {
if (msg) {
err.textContent = msg;
err.removeAttribute("hidden");
} else {
err.textContent = "";
err.setAttribute("hidden", "");
}
}
if (focusId && $(focusId)) {
try {
$(focusId).focus();
$(focusId).classList.add("hp-input-invalid");
setTimeout(function () {
if ($(focusId)) $(focusId).classList.remove("hp-input-invalid");
}, 2400);
} catch (e) {}
}
}
function syncPreviewStartBtn() {
const start = $("hp-preview-start");
if (!start) return;
@@ -3150,19 +3173,41 @@
} else {
if (!state.selected) throw new Error("请选用期权腿");
if (isOptionPrimary()) {
setPoOrderErr("");
const sized = currentOpSizing();
if (!sized || !(sized.sheets > 0)) throw new Error("请选择期权并填写张数");
if (!sized || !(sized.sheets > 0)) {
setPoOrderErr("请选择期权并填写张数(≥1)", "hp-order-sheets");
throw new Error("请选择期权并填写张数(≥1)");
}
const exitMode = state.exitMode === "target" ? "target" : "profit";
let optPts = 0;
let perpPts = 0;
let profitTarget = 0;
if (exitMode === "profit") {
profitTarget = numInput("hp-profit-target", NaN);
if (!(profitTarget > 0)) throw new Error("请填写目标盈利金额(USDT,扣双边手续费后净利)");
if (!(profitTarget > 0)) {
setPoOrderErr("请填写目标盈利金额(USDT,扣双边手续费后净利)", "hp-profit-target");
throw new Error("请填写目标盈利金额(USDT,扣双边手续费后净利)");
}
} else {
optPts = numInput("hp-opt-target-pts", NaN);
perpPts = numInput("hp-perp-target-pts", NaN);
if (!(optPts > 0) || !(perpPts > 0)) throw new Error("请填写期权/永续目标位点数(须大于0)");
if (!(optPts > 0) || !(perpPts > 0)) {
setPoOrderErr("请填写期权/永续目标位点数(须大于0)", !(optPts > 0) ? "hp-opt-target-pts" : "hp-perp-target-pts");
throw new Error("请填写期权/永续目标位点数(须大于0)");
}
}
if (!(state.market && state.market.exchange_symbol)) {
setPoOrderErr("永续行情未就绪,请先点「刷新行情」");
throw new Error("永续行情未就绪,请先点「刷新行情」");
}
if (!state.canStart) {
const gateTxt =
($("hp-po-gate-inline") && $("hp-po-gate-inline").textContent) ||
($("hp-gate-line") && $("hp-gate-line").textContent) ||
"请先刷新行情/检查账户";
setPoOrderErr("门禁未满足,不可开仓: " + gateTxt);
throw new Error("门禁未满足,不可开仓: " + gateTxt);
}
const exp = currentExp("hp-exp-select");
const entry = indexPx() || Number((state.market && state.market.mark) || 0);
@@ -3174,6 +3219,7 @@
plan_type: "perp_options",
option_primary: true,
market_order: 1,
watch_entry: 0,
exit_mode: exitMode,
underlying: state.underlying,
direction: getDirection(),
+55 -1
View File
@@ -3454,12 +3454,66 @@ html[data-theme="light"] .opt-be-dist-down {
.hedge-plan-page-wrap .hp-oo-size-mode.is-selected .hp-oo-check,
.hedge-plan-page-wrap .hp-oo-close-mode.is-selected .hp-oo-check,
.hedge-plan-page-wrap .hp-po-dir.is-selected .hp-oo-check,
.hedge-plan-page-wrap .hp-po-exit-mode.is-selected .hp-oo-check,
.hedge-plan-page-wrap .hp-oo-size-mode.active .hp-oo-check,
.hedge-plan-page-wrap .hp-oo-close-mode.active .hp-oo-check,
.hedge-plan-page-wrap .hp-po-dir.active .hp-oo-check {
.hedge-plan-page-wrap .hp-po-dir.active .hp-oo-check,
.hedge-plan-page-wrap .hp-po-exit-mode.active .hp-oo-check {
display: inline;
color: var(--accent, #00d4ff);
}
.hedge-plan-page-wrap .hp-po-exit-mode .hp-oo-check {
display: none;
margin-right: 4px;
font-weight: 700;
}
.hedge-plan-page-wrap .hp-po-exit-mode.is-selected,
.hedge-plan-page-wrap .hp-po-exit-mode.active {
border-color: var(--accent, #00d4ff);
color: var(--text, #fff);
background: rgba(0, 212, 255, 0.16);
box-shadow: inset 0 0 0 1px rgba(0, 212, 255, 0.35);
font-weight: 700;
}
.hedge-plan-page-wrap .hp-page-toolbar {
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
margin: 0 0 12px;
}
.hedge-plan-page-wrap .hp-po-gate-inline {
font-size: 0.82rem;
line-height: 1.35;
}
.hedge-plan-page-wrap .hp-po-order-dialog .hp-po-quote-compact {
display: flex;
flex-wrap: wrap;
gap: 8px 14px;
align-items: baseline;
font-size: 0.84rem;
}
.hedge-plan-page-wrap .hp-po-order-dialog .hp-po-quote-one {
margin: 2px 0 0;
font-size: 0.78rem;
}
.hedge-plan-page-wrap .hp-po-order-dialog .hp-po-order-calc {
margin-top: 4px;
}
.hedge-plan-page-wrap .hp-po-order-err {
margin: 6px 0 0;
font-size: 0.82rem;
}
.hedge-plan-page-wrap .hp-input-invalid {
border-color: #e85d5d !important;
box-shadow: 0 0 0 1px rgba(232, 93, 93, 0.45);
}
.hedge-plan-page-wrap .hp-po-field--wide {
grid-column: 1 / -1;
}
.opt-order-dialog.hp-po-order-dialog {
width: min(96vw, 560px);
}
.hedge-plan-page-wrap .hp-po-top {
display: flex;
flex-wrap: wrap;