Keep draft target input across position refresh until set.

Polling was re-rendering cards and wiping the field before 设定; drafts and focus are now restored.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-15 16:10:09 +08:00
parent 0bedb2e972
commit 944a211e4a
+32 -1
View File
@@ -19,6 +19,8 @@
orderQuote: null,
expandedPosInst: null,
posTab: "live",
/** 未点设定前的目标输入草稿,避免持仓轮询重绘清空 */
targetDraftByInst: {},
};
let lastGoodPositions = null;
@@ -897,7 +899,8 @@
' data-prem="' + (prem != null ? prem : "") + '"' +
' data-armed-target="' + (armed ? tgt : "") + '">' +
'<span class="opt-target-row-label">委托</span>' +
'<input type="number" class="opt-pos-target-input" data-inst="' + inst + '" step="0.1" min="0" placeholder="监控目标指数" value="">' +
'<input type="number" class="opt-pos-target-input" data-inst="' + inst + '" step="0.1" min="0" placeholder="监控目标指数" value="' +
(state.targetDraftByInst[inst] != null ? String(state.targetDraftByInst[inst]) : "") + '">' +
'<button type="button" class="btn-secondary opt-target-set-btn" data-inst="' + inst + '">设定</button>' +
'<button type="button" class="btn-secondary opt-target-cancel-btn" data-inst="' + inst + '"' + (armed ? "" : " disabled") + ">取消</button>" +
(armed
@@ -1021,6 +1024,12 @@
container.querySelectorAll(".opt-pos-target-input").forEach(function (inp) {
inp.addEventListener("click", function (e) { e.stopPropagation(); });
inp.addEventListener("input", function () {
const instId = inp.getAttribute("data-inst") || "";
const draft = String(inp.value || "");
if (instId) {
if (draft.trim() === "") delete state.targetDraftByInst[instId];
else state.targetDraftByInst[instId] = draft;
}
updatePosTargetEstimate(inp.closest(".opt-target-row"));
});
inp.addEventListener("keydown", function (e) {
@@ -1030,6 +1039,8 @@
setPositionTarget(inp.getAttribute("data-inst"), null);
}
});
// 重绘后恢复预估展示(草稿或已设定目标)
updatePosTargetEstimate(inp.closest(".opt-target-row"));
});
container.querySelectorAll(".opt-pos-bar").forEach(function (bar) {
bar.addEventListener("click", function () {
@@ -1068,6 +1079,7 @@
alert(d.msg || "设定失败");
return;
}
delete state.targetDraftByInst[inst];
if (inp) inp.value = "";
if (row) {
row.setAttribute("data-armed-target", String(tgt));
@@ -1092,6 +1104,7 @@
alert(d.msg || "取消失败");
return;
}
delete state.targetDraftByInst[inst];
await refreshAllPositions();
} finally {
if (btn) btn.disabled = false;
@@ -1224,6 +1237,13 @@
const empty = document.getElementById("opt-pos-empty");
const livePane = document.getElementById("opt-pos-live");
if (!wrap) return;
const active = document.activeElement;
const draftFocusInst =
active && active.classList && active.classList.contains("opt-pos-target-input")
? active.getAttribute("data-inst")
: null;
const draftSelStart = draftFocusInst != null ? active.selectionStart : null;
const draftSelEnd = draftFocusInst != null ? active.selectionEnd : null;
wrap.innerHTML = "";
if (!list.length) {
if (empty) empty.style.display = "";
@@ -1257,6 +1277,17 @@
if (window.OptionsExpiryCountdown && OptionsExpiryCountdown.ensureTimer) {
OptionsExpiryCountdown.ensureTimer();
}
if (draftFocusInst) {
const reinp = wrap.querySelector('.opt-pos-target-input[data-inst="' + draftFocusInst + '"]');
if (reinp) {
reinp.focus();
try {
if (draftSelStart != null && draftSelEnd != null) {
reinp.setSelectionRange(draftSelStart, draftSelEnd);
}
} catch (e) { /* ignore */ }
}
}
}
async function refreshPositions() {