fix: 滚仓拒绝原因页内展示,斐波/突破隐藏预览按钮
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1305,6 +1305,12 @@ html[data-theme="light"] .detail-actions {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#roll-form[data-add-mode="fib_618"] #roll-preview-btn,
|
||||
#roll-form[data-add-mode="fib_786"] #roll-preview-btn,
|
||||
#roll-form[data-add-mode="breakout"] #roll-preview-btn {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#strategy-roll-panel .roll-risk-banner {
|
||||
margin-bottom: 8px;
|
||||
color: #8fc8ff;
|
||||
@@ -1341,12 +1347,30 @@ html[data-theme="light"] #strategy-roll-panel .roll-section-title {
|
||||
color: #dde2ff;
|
||||
}
|
||||
|
||||
#roll-preview-box.roll-preview-box.is-error {
|
||||
border-color: #8a3a4a;
|
||||
background: #1a1218;
|
||||
color: #ffb4b4;
|
||||
}
|
||||
|
||||
#roll-preview-box.roll-preview-box.is-preview {
|
||||
border-color: #3a5a8a;
|
||||
background: #141a28;
|
||||
color: #dde2ff;
|
||||
}
|
||||
|
||||
html[data-theme="light"] #roll-preview-box.roll-preview-box {
|
||||
background: #f6f9fc !important;
|
||||
border-color: #b8c8d8 !important;
|
||||
color: #1a2838 !important;
|
||||
}
|
||||
|
||||
html[data-theme="light"] #roll-preview-box.roll-preview-box.is-error {
|
||||
background: #fff5f5 !important;
|
||||
border-color: #d8a0a8 !important;
|
||||
color: #8a2030 !important;
|
||||
}
|
||||
|
||||
#roll-countdown.roll-countdown {
|
||||
margin-top: 6px;
|
||||
color: #ffb347;
|
||||
|
||||
+142
-51
@@ -42,10 +42,21 @@
|
||||
const previewBox = document.getElementById("roll-preview-box");
|
||||
const previewText = document.getElementById("roll-preview-text");
|
||||
const countdownEl = document.getElementById("roll-countdown");
|
||||
const trendLocked = submitBtn && submitBtn.getAttribute("data-trend-locked") === "1";
|
||||
|
||||
let countdownTimer = null;
|
||||
let previewOk = false;
|
||||
let lastPreviewMode = "";
|
||||
let allowMonitorSubmit = false;
|
||||
|
||||
function isMarketMode() {
|
||||
return (modeSel.value || "market") === "market";
|
||||
}
|
||||
|
||||
function isMonitorMode() {
|
||||
const m = modeSel.value || "market";
|
||||
return m === "fib_618" || m === "fib_786" || m === "breakout";
|
||||
}
|
||||
|
||||
function selectedOption() {
|
||||
return symbolSel.options[symbolSel.selectedIndex];
|
||||
@@ -64,6 +75,57 @@
|
||||
"当前风险:" + rp + "%(来自监控单 #" + (opt.getAttribute("data-monitor-id") || "?") + ")";
|
||||
}
|
||||
|
||||
function syncSubmitButton() {
|
||||
if (!submitBtn || trendLocked) return;
|
||||
if (isMonitorMode()) {
|
||||
submitBtn.disabled = false;
|
||||
return;
|
||||
}
|
||||
submitBtn.disabled = !previewOk || !!countdownTimer;
|
||||
}
|
||||
|
||||
function clearMessageBox() {
|
||||
if (!previewBox) return;
|
||||
previewBox.style.display = "none";
|
||||
previewBox.classList.remove("is-error", "is-preview");
|
||||
if (previewText) previewText.textContent = "";
|
||||
if (countdownEl) countdownEl.style.display = "none";
|
||||
}
|
||||
|
||||
function showReject(msg) {
|
||||
if (!previewBox || !previewText) return;
|
||||
previewBox.style.display = "block";
|
||||
previewBox.classList.remove("is-preview");
|
||||
previewBox.classList.add("is-error");
|
||||
previewText.textContent = msg || "无法执行";
|
||||
if (countdownEl) countdownEl.style.display = "none";
|
||||
}
|
||||
|
||||
function showPreviewResult(p) {
|
||||
if (!previewBox || !previewText) return;
|
||||
previewBox.style.display = "block";
|
||||
previewBox.classList.remove("is-error");
|
||||
previewBox.classList.add("is-preview");
|
||||
previewText.innerHTML =
|
||||
"<strong>" +
|
||||
(p.add_mode_label || "") +
|
||||
"</strong> · 约 <strong>" +
|
||||
(p.add_amount_display != null ? p.add_amount_display : p.add_amount_raw) +
|
||||
"</strong> 张<br>" +
|
||||
"加仓参考价 " +
|
||||
(p.add_price_display != null ? p.add_price_display : p.add_price) +
|
||||
" · 新止损 " +
|
||||
(p.new_sl_display != null ? p.new_sl_display : p.new_stop_loss) +
|
||||
"<br>" +
|
||||
"合并均价 " +
|
||||
p.avg_entry_after +
|
||||
" · 打到止损约 " +
|
||||
p.loss_at_sl_usdt +
|
||||
"U(风险预算 " +
|
||||
(p.risk_budget_usdt != null ? p.risk_budget_usdt : "—") +
|
||||
"U)";
|
||||
}
|
||||
|
||||
function syncFieldVisibility() {
|
||||
syncRollFormMode(form, modeSel.value || "market");
|
||||
resetPreview();
|
||||
@@ -71,13 +133,13 @@
|
||||
|
||||
function resetPreview() {
|
||||
previewOk = false;
|
||||
if (submitBtn) submitBtn.disabled = true;
|
||||
if (previewBox) previewBox.style.display = "none";
|
||||
if (countdownEl) countdownEl.style.display = "none";
|
||||
allowMonitorSubmit = false;
|
||||
clearMessageBox();
|
||||
if (countdownTimer) {
|
||||
clearInterval(countdownTimer);
|
||||
countdownTimer = null;
|
||||
}
|
||||
syncSubmitButton();
|
||||
}
|
||||
|
||||
function formPayload() {
|
||||
@@ -89,78 +151,98 @@
|
||||
return obj;
|
||||
}
|
||||
|
||||
function runPreview() {
|
||||
resetPreview();
|
||||
if (!symbolSel.value) {
|
||||
alert("请先选择持仓币种");
|
||||
return;
|
||||
}
|
||||
previewBtn.disabled = true;
|
||||
fetch("/strategy/roll/preview", {
|
||||
function requestPreview() {
|
||||
return fetch("/strategy/roll/preview", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
||||
body: JSON.stringify(formPayload()),
|
||||
credentials: "same-origin",
|
||||
})
|
||||
.then(function (r) {
|
||||
return r.json();
|
||||
})
|
||||
}).then(function (r) {
|
||||
return r.json();
|
||||
});
|
||||
}
|
||||
|
||||
function runPreview() {
|
||||
resetPreview();
|
||||
if (!symbolSel.value) {
|
||||
showReject("请先选择持仓币种");
|
||||
return;
|
||||
}
|
||||
if (previewBtn) previewBtn.disabled = true;
|
||||
requestPreview()
|
||||
.then(function (data) {
|
||||
previewBtn.disabled = false;
|
||||
if (previewBtn) previewBtn.disabled = false;
|
||||
if (!data.ok) {
|
||||
alert(data.msg || "预览失败");
|
||||
showReject(data.msg || "预览失败");
|
||||
return;
|
||||
}
|
||||
const p = data.preview || {};
|
||||
lastPreviewMode = p.add_mode || modeSel.value;
|
||||
previewText.innerHTML =
|
||||
"<strong>" +
|
||||
(p.add_mode_label || "") +
|
||||
"</strong> · 约 <strong>" +
|
||||
(p.add_amount_display != null ? p.add_amount_display : p.add_amount_raw) +
|
||||
"</strong> 张<br>" +
|
||||
"加仓参考价 " +
|
||||
(p.add_price_display != null ? p.add_price_display : p.add_price) +
|
||||
" · 新止损 " +
|
||||
(p.new_sl_display != null ? p.new_sl_display : p.new_stop_loss) +
|
||||
"<br>" +
|
||||
"合并均价 " +
|
||||
p.avg_entry_after +
|
||||
" · 打到止损约 " +
|
||||
p.loss_at_sl_usdt +
|
||||
"U(风险预算 " +
|
||||
(p.risk_budget_usdt != null ? p.risk_budget_usdt : "—") +
|
||||
"U)";
|
||||
previewBox.style.display = "block";
|
||||
showPreviewResult(p);
|
||||
previewOk = true;
|
||||
if (lastPreviewMode === "market") {
|
||||
startCountdown(10);
|
||||
} else if (submitBtn) {
|
||||
submitBtn.disabled = false;
|
||||
countdownEl.style.display = "none";
|
||||
} else {
|
||||
syncSubmitButton();
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
previewBtn.disabled = false;
|
||||
alert("预览请求失败");
|
||||
if (previewBtn) previewBtn.disabled = false;
|
||||
showReject("预览请求失败,请稍后重试");
|
||||
});
|
||||
}
|
||||
|
||||
function runMonitorSubmit() {
|
||||
if (!symbolSel.value) {
|
||||
showReject("请先选择持仓币种");
|
||||
return;
|
||||
}
|
||||
if (submitBtn) submitBtn.disabled = true;
|
||||
requestPreview()
|
||||
.then(function (data) {
|
||||
if (submitBtn && !trendLocked) submitBtn.disabled = false;
|
||||
if (!data.ok) {
|
||||
showReject(data.msg || "无法提交监控");
|
||||
return;
|
||||
}
|
||||
const p = data.preview || {};
|
||||
const modeLabel = modeSel.options[modeSel.selectedIndex].text;
|
||||
const summary =
|
||||
"约 " +
|
||||
(p.add_amount_display != null ? p.add_amount_display : p.add_amount_raw) +
|
||||
" 张 · 触发参考价 " +
|
||||
(p.add_price_display != null ? p.add_price_display : p.add_price) +
|
||||
" · 新止损 " +
|
||||
(p.new_sl_display != null ? p.new_sl_display : p.new_stop_loss);
|
||||
if (!confirm("确认提交「" + modeLabel + "」?\n" + summary)) {
|
||||
return;
|
||||
}
|
||||
allowMonitorSubmit = true;
|
||||
form.requestSubmit();
|
||||
})
|
||||
.catch(function () {
|
||||
if (submitBtn && !trendLocked) submitBtn.disabled = false;
|
||||
showReject("校验请求失败,请稍后重试");
|
||||
});
|
||||
}
|
||||
|
||||
function startCountdown(sec) {
|
||||
let left = sec;
|
||||
if (submitBtn) submitBtn.disabled = true;
|
||||
countdownEl.style.display = "block";
|
||||
countdownEl.textContent = "市价加仓:" + left + " 秒后可执行(可取消刷新预览)";
|
||||
if (countdownEl) {
|
||||
countdownEl.style.display = "block";
|
||||
countdownEl.textContent = "市价加仓:" + left + " 秒后可执行(修改表单将取消预览)";
|
||||
}
|
||||
countdownTimer = setInterval(function () {
|
||||
left -= 1;
|
||||
if (left <= 0) {
|
||||
clearInterval(countdownTimer);
|
||||
countdownTimer = null;
|
||||
countdownEl.textContent = "可以执行市价加仓";
|
||||
if (submitBtn) submitBtn.disabled = false;
|
||||
if (countdownEl) countdownEl.textContent = "可以执行市价加仓";
|
||||
syncSubmitButton();
|
||||
return;
|
||||
}
|
||||
countdownEl.textContent = "市价加仓:" + left + " 秒后可执行";
|
||||
if (countdownEl) countdownEl.textContent = "市价加仓:" + left + " 秒后可执行";
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
@@ -173,16 +255,25 @@
|
||||
form.addEventListener("change", function (e) {
|
||||
if (e.target !== previewBtn) resetPreview();
|
||||
});
|
||||
previewBtn.addEventListener("click", runPreview);
|
||||
if (previewBtn) previewBtn.addEventListener("click", runPreview);
|
||||
form.addEventListener("submit", function (e) {
|
||||
if (!previewOk) {
|
||||
if (isMonitorMode()) {
|
||||
if (allowMonitorSubmit) {
|
||||
allowMonitorSubmit = false;
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
alert("请先点击预览");
|
||||
runMonitorSubmit();
|
||||
return;
|
||||
}
|
||||
if (lastPreviewMode === "market" && submitBtn && submitBtn.disabled) {
|
||||
if (!previewOk) {
|
||||
e.preventDefault();
|
||||
alert("请等待 10 秒确认倒计时结束");
|
||||
showReject("请先点击「预览」并通过校验");
|
||||
return;
|
||||
}
|
||||
if (submitBtn && submitBtn.disabled) {
|
||||
e.preventDefault();
|
||||
showReject("请等待 10 秒确认倒计时结束后再执行市价加仓");
|
||||
return;
|
||||
}
|
||||
const modeLabel = modeSel.options[modeSel.selectedIndex].text;
|
||||
|
||||
Reference in New Issue
Block a user