Options: eth-amount dialog, stop note autofill, pending tab in positions.
Selecting 指定币数量 opens an order dialog; pending orders move into a 当前委托 tab after 当前持仓; harden remark autofill that showed dekun. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -276,9 +276,144 @@
|
||||
function updateSizeInputs() {
|
||||
const mode = currentSizeMode();
|
||||
const sheetsEl = document.getElementById("opt-sheets-amount");
|
||||
const ethEl = document.getElementById("opt-eth-amount");
|
||||
if (sheetsEl) sheetsEl.style.display = mode === "sheets" ? "" : "none";
|
||||
if (ethEl) ethEl.style.display = mode === "eth_amount" ? "" : "none";
|
||||
}
|
||||
|
||||
function hardenOrderAutofill() {
|
||||
const note = document.getElementById("opt-signal-note");
|
||||
if (!note) return;
|
||||
function wipeNote() {
|
||||
// 浏览器常把用户名(dekun)填进备注框
|
||||
if (/^[a-z][a-z0-9._-]{1,31}$/i.test(String(note.value || "").trim())) {
|
||||
note.value = "";
|
||||
}
|
||||
}
|
||||
wipeNote();
|
||||
note.addEventListener("focus", function () {
|
||||
note.removeAttribute("readonly");
|
||||
});
|
||||
note.addEventListener("blur", function () {
|
||||
if (!note.value) note.setAttribute("readonly", "readonly");
|
||||
});
|
||||
setTimeout(wipeNote, 200);
|
||||
setTimeout(wipeNote, 800);
|
||||
}
|
||||
|
||||
function hideEthOrderDialog() {
|
||||
const bd = document.getElementById("opt-eth-order-backdrop");
|
||||
if (bd) bd.hidden = true;
|
||||
}
|
||||
|
||||
function openEthOrderDialog() {
|
||||
if (!state.selectedInst) {
|
||||
alert("请先选择合约");
|
||||
const sheetsRadio = document.querySelector('input[name="opt-size-mode"][value="sheets"]');
|
||||
if (sheetsRadio) {
|
||||
sheetsRadio.checked = true;
|
||||
updateSizeInputs();
|
||||
}
|
||||
return;
|
||||
}
|
||||
const bd = document.getElementById("opt-eth-order-backdrop");
|
||||
const instEl = document.getElementById("opt-eth-order-inst");
|
||||
const amountEl = document.getElementById("opt-eth-order-amount");
|
||||
const preview = document.getElementById("opt-eth-order-preview");
|
||||
const msg = document.getElementById("opt-eth-order-msg");
|
||||
if (instEl) instEl.textContent = state.selectedInst;
|
||||
if (amountEl) {
|
||||
amountEl.value = document.getElementById("opt-eth-amount").value || "";
|
||||
amountEl.focus();
|
||||
}
|
||||
if (preview) preview.textContent = "输入币数量后显示张数与权利金估算";
|
||||
if (msg) {
|
||||
msg.textContent = "";
|
||||
msg.classList.remove("opt-error");
|
||||
}
|
||||
if (bd) bd.hidden = false;
|
||||
refreshEthOrderPreview();
|
||||
}
|
||||
|
||||
async function refreshEthOrderPreview() {
|
||||
const preview = document.getElementById("opt-eth-order-preview");
|
||||
const amountEl = document.getElementById("opt-eth-order-amount");
|
||||
if (!preview || !amountEl || !state.selectedInst) return;
|
||||
const eth = parseFloat(amountEl.value);
|
||||
if (!Number.isFinite(eth) || eth <= 0) {
|
||||
preview.textContent = "输入币数量后显示张数与权利金估算";
|
||||
return;
|
||||
}
|
||||
preview.textContent = "估算中…";
|
||||
try {
|
||||
const url =
|
||||
"/api/options/quote?inst_id=" +
|
||||
encodeURIComponent(state.selectedInst) +
|
||||
"&mode=eth_amountð_amount=" +
|
||||
encodeURIComponent(String(eth));
|
||||
const d = await apiJson(url);
|
||||
if (!d || !d.ok) {
|
||||
preview.textContent = (d && d.msg) || "报价失败";
|
||||
return;
|
||||
}
|
||||
const sz = d.sizing || {};
|
||||
if (sz.ok === false) {
|
||||
preview.textContent = sz.msg || "张数无效";
|
||||
return;
|
||||
}
|
||||
const sheets = sz.sheets != null ? sz.sheets : "—";
|
||||
const prem = sz.total_premium != null ? sz.total_premium : null;
|
||||
const premTxt = prem != null ? fmt(prem, 2) + " USDC" : "—";
|
||||
preview.textContent = "约 " + sheets + " 张 · 预估权利金 " + premTxt;
|
||||
} catch (e) {
|
||||
preview.textContent = "报价失败";
|
||||
}
|
||||
}
|
||||
|
||||
async function submitEthOrderDialog() {
|
||||
const amountEl = document.getElementById("opt-eth-order-amount");
|
||||
const msg = document.getElementById("opt-eth-order-msg");
|
||||
const submitBtn = document.getElementById("opt-eth-order-submit");
|
||||
const eth = amountEl ? parseFloat(amountEl.value) : NaN;
|
||||
if (!Number.isFinite(eth) || eth <= 0) {
|
||||
if (msg) {
|
||||
msg.textContent = "请输入有效币数量";
|
||||
msg.classList.add("opt-error");
|
||||
}
|
||||
return;
|
||||
}
|
||||
const hidden = document.getElementById("opt-eth-amount");
|
||||
if (hidden) hidden.value = String(eth);
|
||||
const ethRadio = document.querySelector('input[name="opt-size-mode"][value="eth_amount"]');
|
||||
if (ethRadio) ethRadio.checked = true;
|
||||
updateSizeInputs();
|
||||
if (submitBtn) submitBtn.disabled = true;
|
||||
try {
|
||||
if (state.selectedInst) {
|
||||
await selectContract(state.selectedInst, null, true);
|
||||
}
|
||||
const ok = await openPosition();
|
||||
if (ok) {
|
||||
hideEthOrderDialog();
|
||||
setOptionsPosTab("pending");
|
||||
} else if (msg) {
|
||||
const orderMsg = document.getElementById("opt-order-msg");
|
||||
msg.textContent = (orderMsg && orderMsg.textContent) || "下单失败";
|
||||
msg.classList.add("opt-error");
|
||||
}
|
||||
} finally {
|
||||
if (submitBtn) submitBtn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
function cancelEthOrderDialog() {
|
||||
hideEthOrderDialog();
|
||||
const sheetsRadio = document.querySelector('input[name="opt-size-mode"][value="sheets"]');
|
||||
if (sheetsRadio) {
|
||||
sheetsRadio.checked = true;
|
||||
updateSizeInputs();
|
||||
}
|
||||
const hidden = document.getElementById("opt-eth-amount");
|
||||
if (hidden) hidden.value = "";
|
||||
if (state.selectedInst) selectContract(state.selectedInst, null, true);
|
||||
}
|
||||
|
||||
function quoteUrl(instId) {
|
||||
@@ -1106,16 +1241,16 @@
|
||||
async function openPosition() {
|
||||
if (!state.selectedInst) {
|
||||
alert("请先选择合约");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
const q = state.orderQuote;
|
||||
if (!q || !q.ok || !q.can_open) {
|
||||
alert((q && (q.msg || q.open_block_msg)) || "暂无卖一深度,无法按卖一开仓");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (q.sizing && q.sizing.ok === false) {
|
||||
alert(q.sizing.msg || "张数无效");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
const btn = document.getElementById("opt-open-btn");
|
||||
btn.disabled = true;
|
||||
@@ -1136,7 +1271,7 @@
|
||||
const tgt = parseFloat(tgtRaw);
|
||||
if (!Number.isFinite(tgt) || tgt <= 0) {
|
||||
alert("目标位无效");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
body.target_index = tgt;
|
||||
}
|
||||
@@ -1146,16 +1281,17 @@
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
const msgEl = document.getElementById("opt-order-msg");
|
||||
msgEl.textContent = d.ok ? "下单已提交,右侧可查看/撤销未成交委托" : (d.msg || "失败");
|
||||
msgEl.textContent = d.ok ? "下单已提交,可在「当前委托」查看/撤销" : (d.msg || "失败");
|
||||
msgEl.classList.toggle("opt-error", !d.ok);
|
||||
if (d.ok) {
|
||||
refreshPendingOrders();
|
||||
startPendingOrdersPoll();
|
||||
refreshAllPositions();
|
||||
if (typeof refreshAccountSnapshot === "function") refreshAccountSnapshot();
|
||||
} else {
|
||||
alert(d.msg || "下单失败");
|
||||
return true;
|
||||
}
|
||||
alert(d.msg || "下单失败");
|
||||
return false;
|
||||
} finally {
|
||||
const latest = state.orderQuote;
|
||||
btn.disabled = !(latest && latest.ok && latest.can_open && !(latest.sizing && latest.sizing.ok === false));
|
||||
@@ -1587,6 +1723,10 @@
|
||||
if (tab === "live" && window.OptionsExpiryCountdown && OptionsExpiryCountdown.ensureTimer) {
|
||||
OptionsExpiryCountdown.ensureTimer();
|
||||
}
|
||||
if (tab === "pending") {
|
||||
refreshPendingOrders();
|
||||
startPendingOrdersPoll();
|
||||
}
|
||||
}
|
||||
|
||||
function bindOptionsPosTabs() {
|
||||
@@ -2047,15 +2187,48 @@
|
||||
});
|
||||
}
|
||||
bindOptionsPosTabs();
|
||||
hardenOrderAutofill();
|
||||
|
||||
document.querySelectorAll('input[name="opt-size-mode"]').forEach(function (r) {
|
||||
r.addEventListener("change", function () {
|
||||
const mode = currentSizeMode();
|
||||
updateSizeInputs();
|
||||
if (mode === "eth_amount") {
|
||||
openEthOrderDialog();
|
||||
return;
|
||||
}
|
||||
if (state.selectedInst) selectContract(state.selectedInst, null, true);
|
||||
});
|
||||
});
|
||||
|
||||
["opt-sheets-amount", "opt-eth-amount", "opt-target-idx"].forEach(function (id) {
|
||||
const ethBackdrop = document.getElementById("opt-eth-order-backdrop");
|
||||
const ethCancel = document.getElementById("opt-eth-order-cancel");
|
||||
const ethSubmit = document.getElementById("opt-eth-order-submit");
|
||||
const ethAmount = document.getElementById("opt-eth-order-amount");
|
||||
if (ethCancel) ethCancel.addEventListener("click", cancelEthOrderDialog);
|
||||
if (ethSubmit) ethSubmit.addEventListener("click", submitEthOrderDialog);
|
||||
if (ethAmount) {
|
||||
ethAmount.addEventListener("input", refreshEthOrderPreview);
|
||||
ethAmount.addEventListener("change", refreshEthOrderPreview);
|
||||
ethAmount.addEventListener("keydown", function (ev) {
|
||||
if (ev.key === "Enter") {
|
||||
ev.preventDefault();
|
||||
submitEthOrderDialog();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (ethBackdrop) {
|
||||
ethBackdrop.addEventListener("click", function (ev) {
|
||||
if (ev.target === ethBackdrop) cancelEthOrderDialog();
|
||||
});
|
||||
}
|
||||
document.addEventListener("keydown", function (ev) {
|
||||
if (ev.key !== "Escape") return;
|
||||
const bd = document.getElementById("opt-eth-order-backdrop");
|
||||
if (bd && !bd.hidden) cancelEthOrderDialog();
|
||||
});
|
||||
|
||||
["opt-sheets-amount", "opt-target-idx"].forEach(function (id) {
|
||||
const el = document.getElementById(id);
|
||||
if (!el) return;
|
||||
el.addEventListener("change", function () {
|
||||
|
||||
Reference in New Issue
Block a user