Unify key support/resistance monitor type and fix form parity.
Merge 关键阻力位/关键支撑位 into 关键支撑阻力, share key_monitor_form.js across hub and new-tab views, and add hub shortcut to /key_monitor. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* 关键位监控添加表单:类型切换显隐、成交量排名校验(四所实例共用)。
|
||||
*/
|
||||
(function (global) {
|
||||
const RS_TYPES = new Set([
|
||||
"关键支撑阻力",
|
||||
"关键阻力位",
|
||||
"关键支撑位",
|
||||
]);
|
||||
|
||||
function syncKeyMonitorFormFields() {
|
||||
const typeEl = document.querySelector('#key-form [name="type"]');
|
||||
const dirEl = document.getElementById("key-direction");
|
||||
const modeEl = document.getElementById("key-sl-tp-mode");
|
||||
const manualTp = document.getElementById("key-manual-tp");
|
||||
const beWrap = document.getElementById("key-breakeven-wrap");
|
||||
if (!typeEl) return;
|
||||
const t = (typeEl.value || "").trim();
|
||||
const autoTypes = new Set(["箱体突破", "收敛突破"]);
|
||||
const fibTypes = new Set(["斐波回调0.618", "斐波回调0.786"]);
|
||||
const fbTypes = new Set(["假突破"]);
|
||||
const teTypes = new Set(["触价开仓"]);
|
||||
const showAuto = autoTypes.has(t);
|
||||
const showFb = fbTypes.has(t);
|
||||
const showTe = teTypes.has(t);
|
||||
const showBe = showAuto || fibTypes.has(t) || showFb || showTe;
|
||||
const showDir = !RS_TYPES.has(t);
|
||||
const upperEl = document.getElementById("key-upper");
|
||||
const lowerEl = document.getElementById("key-lower");
|
||||
const fbPriceEl = document.getElementById("key-fb-price");
|
||||
const teEntryEl = document.getElementById("key-trigger-entry");
|
||||
const teSlEl = document.getElementById("key-trigger-sl");
|
||||
const teTpEl = document.getElementById("key-trigger-tp");
|
||||
if (dirEl) {
|
||||
dirEl.style.display = showDir ? "" : "none";
|
||||
dirEl.required = showDir;
|
||||
if (!showDir) dirEl.value = "";
|
||||
}
|
||||
if (modeEl) modeEl.style.display = showAuto ? "" : "none";
|
||||
if (manualTp) {
|
||||
const trend = showAuto && modeEl && modeEl.value === "trend_manual";
|
||||
manualTp.style.display = trend ? "" : "none";
|
||||
manualTp.required = !!trend;
|
||||
}
|
||||
if (beWrap) beWrap.style.display = showBe ? "inline-flex" : "none";
|
||||
if (global.TimeCloseUI) global.TimeCloseUI.syncKeyTimeCloseVisibility(showBe);
|
||||
const hideBounds = showFb || showTe;
|
||||
if (upperEl) {
|
||||
upperEl.style.display = hideBounds ? "none" : "";
|
||||
upperEl.required = !hideBounds;
|
||||
if (hideBounds) upperEl.value = "";
|
||||
}
|
||||
if (lowerEl) {
|
||||
lowerEl.style.display = hideBounds ? "none" : "";
|
||||
lowerEl.required = !hideBounds;
|
||||
if (hideBounds) lowerEl.value = "";
|
||||
}
|
||||
if (fbPriceEl) {
|
||||
fbPriceEl.style.display = showFb ? "" : "none";
|
||||
fbPriceEl.required = showFb;
|
||||
if (!showFb) fbPriceEl.value = "";
|
||||
fbPriceEl.placeholder =
|
||||
dirEl && dirEl.value === "short"
|
||||
? "高点(阻力)"
|
||||
: dirEl && dirEl.value === "long"
|
||||
? "低点(支撑)"
|
||||
: "做空填高点/做多填低点";
|
||||
}
|
||||
[teEntryEl, teSlEl, teTpEl].forEach((el) => {
|
||||
if (!el) return;
|
||||
el.style.display = showTe ? "" : "none";
|
||||
el.required = showTe;
|
||||
if (!showTe) el.value = "";
|
||||
});
|
||||
}
|
||||
|
||||
function bindKeyMonitorForm() {
|
||||
const keyForm = document.getElementById("key-form");
|
||||
const keyTypeSel = document.querySelector('#key-form [name="type"]');
|
||||
const keyModeSel = document.getElementById("key-sl-tp-mode");
|
||||
const keyDirSel = document.getElementById("key-direction");
|
||||
if (keyTypeSel) keyTypeSel.addEventListener("change", syncKeyMonitorFormFields);
|
||||
if (keyModeSel) keyModeSel.addEventListener("change", syncKeyMonitorFormFields);
|
||||
if (keyDirSel) keyDirSel.addEventListener("change", syncKeyMonitorFormFields);
|
||||
syncKeyMonitorFormFields();
|
||||
if (global.TimeCloseUI) {
|
||||
global.TimeCloseUI.bindTimeCloseForm(
|
||||
"key-time-close-cb",
|
||||
"key-time-close-hours",
|
||||
"key-time-close-wrap"
|
||||
);
|
||||
}
|
||||
if (!keyForm || keyForm.dataset.keyFormBound === "1") return;
|
||||
keyForm.dataset.keyFormBound = "1";
|
||||
keyForm.addEventListener("submit", (e) => {
|
||||
e.preventDefault();
|
||||
if (global.FormSubmitGuard && global.FormSubmitGuard.isLocked(keyForm)) return;
|
||||
const symbolEl = keyForm.querySelector('[name="symbol"]');
|
||||
const symbol = (symbolEl ? symbolEl.value : "").trim();
|
||||
if (!symbol) {
|
||||
alert("请先输入交易对");
|
||||
return;
|
||||
}
|
||||
const typeVal = (keyForm.querySelector('[name="type"]') || {}).value || "";
|
||||
if (typeVal === "假突破") {
|
||||
if (global.FormSubmitGuard) global.FormSubmitGuard.nativeSubmitOnce(keyForm, "提交中…");
|
||||
else keyForm.submit();
|
||||
return;
|
||||
}
|
||||
if (global.FormSubmitGuard) global.FormSubmitGuard.lock(keyForm, "校验排名中…");
|
||||
fetch(`/api/symbol_liquidity_rank?symbol=${encodeURIComponent(symbol)}`)
|
||||
.then((r) => r.json().then((d) => ({ status: r.status, data: d })))
|
||||
.then(({ status, data }) => {
|
||||
if (status >= 400 || !data.ok) {
|
||||
alert((data && data.msg) || "日成交量排名读取失败");
|
||||
if (global.FormSubmitGuard) global.FormSubmitGuard.unlock(keyForm);
|
||||
return;
|
||||
}
|
||||
const rankMax = data.rank_max || 30;
|
||||
const inTop = data.in_top != null ? data.in_top : data.in_top30;
|
||||
if (data.rank == null || !inTop) {
|
||||
alert(
|
||||
`${data.symbol} 当前日成交量排名 ${data.rank == null ? "—" : data.rank}/${data.total},不在前${rankMax},已拦截。`
|
||||
);
|
||||
if (global.FormSubmitGuard) global.FormSubmitGuard.unlock(keyForm);
|
||||
return;
|
||||
}
|
||||
if (global.FormSubmitGuard) global.FormSubmitGuard.nativeSubmitOnce(keyForm, "提交中…");
|
||||
else keyForm.submit();
|
||||
})
|
||||
.catch(() => {
|
||||
alert("日成交量排名检查失败,请稍后重试");
|
||||
if (global.FormSubmitGuard) global.FormSubmitGuard.unlock(keyForm);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
global.KeyMonitorForm = {
|
||||
syncFields: syncKeyMonitorFormFields,
|
||||
init: bindKeyMonitorForm,
|
||||
};
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", bindKeyMonitorForm);
|
||||
} else {
|
||||
bindKeyMonitorForm();
|
||||
}
|
||||
})(typeof window !== "undefined" ? window : globalThis);
|
||||
Reference in New Issue
Block a user