持仓区增加账户内划转,买一平仓规则并入左侧开平仓说明

持仓卡片底部可折叠划转面板(资金/交易 USDT/USDC);移除持仓区重复平仓规则,统一到左侧开平仓规则说明。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-23 08:11:19 +08:00
parent fe5bb923d7
commit aa14688a7e
3 changed files with 264 additions and 18 deletions
+62
View File
@@ -5297,6 +5297,68 @@ html[data-theme="light"] .opt-source-badge--oo {
border-color: #ffb347;
color: #ffb347;
}
.options-page-wrap .opt-pos-transfer {
margin-top: 10px;
padding: 10px 12px;
border-radius: 8px;
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.06);
}
.options-page-wrap .opt-pos-transfer-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
cursor: pointer;
list-style: none;
font-weight: 600;
font-size: 0.88rem;
margin: 0 0 8px;
}
.options-page-wrap .opt-pos-transfer-head::-webkit-details-marker {
display: none;
}
.options-page-wrap .opt-pos-transfer[open] .opt-pos-transfer-closed-hint {
display: none;
}
.options-page-wrap .opt-pos-transfer:not([open]) .opt-pos-transfer-open-hint {
display: none;
}
.options-page-wrap .opt-pos-transfer:not([open]) .opt-pos-transfer-body {
display: none;
}
.options-page-wrap .opt-pos-transfer:not([open]) .opt-pos-transfer-head {
margin-bottom: 0;
}
.options-page-wrap .opt-pos-transfer-body .options-settings-subtitle {
margin-bottom: 6px;
}
.options-page-wrap .opt-pos-transfer-form {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
margin: 0;
}
.options-page-wrap .opt-pos-transfer-form select,
.options-page-wrap .opt-pos-transfer-form input[type="number"] {
font-size: 0.74rem;
}
.options-page-wrap .opt-pos-transfer-form input[type="number"] {
width: 96px;
max-width: 30vw;
}
.options-page-wrap .opt-pos-xfer-msg {
margin-top: 6px;
font-size: 0.76rem;
min-height: 1.1em;
}
.options-page-wrap .opt-pos-xfer-msg.opt-error {
color: #ff7b72;
}
.options-page-wrap .opt-pos-xfer-msg.opt-success {
color: #3dd68c;
}
.opt-pos-card {
margin-bottom: 10px;
}
+159
View File
@@ -373,6 +373,164 @@
}
}
function setXferMsg(text, isErr) {
const el = document.getElementById("opt-pos-xfer-msg");
if (!el) return;
el.textContent = text || "";
el.classList.toggle("opt-error", !!isErr);
el.classList.toggle("opt-success", !!text && !isErr);
}
function xferRoundAvail(v) {
const n = Number(v);
if (!Number.isFinite(n) || n <= 0) return null;
return Math.round(n * 100) / 100;
}
function xferPickBalance(bal, account, ccy) {
if (!bal) return null;
const acct = account === "trading" ? "trading" : "funding";
const c = String(ccy || "").toLowerCase();
const availKey = acct + "_" + c + "_avail";
const totalKey = acct + "_" + c;
return xferRoundAvail(bal[availKey] != null ? bal[availKey] : bal[totalKey]);
}
function xferAccountLabel(acct) {
return acct === "trading" ? "交易账户" : "资金账户";
}
function setPosXferBusy(busy) {
["opt-pos-xfer-btn", "opt-pos-xfer-all-btn"].forEach(function (id) {
const btn = document.getElementById(id);
if (!btn) return;
if (busy) {
if (!btn.dataset.origText) btn.dataset.origText = btn.textContent;
btn.disabled = true;
} else {
btn.disabled = false;
if (btn.dataset.origText) {
btn.textContent = btn.dataset.origText;
delete btn.dataset.origText;
}
}
});
const input = document.getElementById("opt-pos-xfer-amount");
if (input) input.disabled = !!busy;
}
async function submitPosTransfer(amount) {
const ccyEl = document.getElementById("opt-pos-xfer-ccy");
const fromEl = document.getElementById("opt-pos-xfer-from");
const toEl = document.getElementById("opt-pos-xfer-to");
if (!ccyEl || !fromEl || !toEl) return { ok: false };
setPosXferBusy(true);
setXferMsg("划转中…", false);
try {
const r = await apiJson("/api/options/transfer", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
ccy: ccyEl.value,
from: fromEl.value,
to: toEl.value,
amount: amount,
}),
});
if (r.ok) {
setXferMsg("划转成功", false);
const amtEl = document.getElementById("opt-pos-xfer-amount");
if (amtEl) amtEl.value = "";
refreshAllPositions();
if (typeof refreshAccountSnapshot === "function") refreshAccountSnapshot({ force: true });
await refreshBridgeSellUi(true);
} else {
setXferMsg("划转失败:" + (r.msg || "未知错误"), true);
}
return r;
} catch (e) {
setXferMsg("划转失败:" + (e.message || "网络错误"), true);
return { ok: false };
} finally {
setPosXferBusy(false);
}
}
function bindPosTransferControls() {
const xferBtn = document.getElementById("opt-pos-xfer-btn");
const xferAllBtn = document.getElementById("opt-pos-xfer-all-btn");
const amtEl = document.getElementById("opt-pos-xfer-amount");
if (!xferBtn && !xferAllBtn) return;
function hardenXferAmountInput() {
if (!amtEl) return;
function wipe() {
const v = String(amtEl.value || "").trim();
if (/^[a-z][a-z0-9._-]{1,31}$/i.test(v)) amtEl.value = "";
}
wipe();
amtEl.setAttribute("readonly", "readonly");
amtEl.addEventListener("focus", function () {
amtEl.removeAttribute("readonly");
});
amtEl.addEventListener("blur", function () {
if (!amtEl.value) amtEl.setAttribute("readonly", "readonly");
});
setTimeout(wipe, 200);
setTimeout(wipe, 800);
}
hardenXferAmountInput();
if (xferBtn) {
xferBtn.addEventListener("click", async function () {
const amount = parseFloat((amtEl || {}).value);
if (!amount || amount <= 0) {
setXferMsg("请输入有效数量", true);
return;
}
await submitPosTransfer(amount);
});
}
if (xferAllBtn) {
xferAllBtn.addEventListener(
"click",
function () {
if (amtEl) amtEl.removeAttribute("readonly");
},
true
);
xferAllBtn.addEventListener("click", async function () {
try {
const ccyEl = document.getElementById("opt-pos-xfer-ccy");
const fromEl = document.getElementById("opt-pos-xfer-from");
const toEl = document.getElementById("opt-pos-xfer-to");
const bal = await refreshBridgeSellUi(true);
const ccy = ccyEl ? ccyEl.value : "USDT";
const from = fromEl ? fromEl.value : "funding";
const to = toEl ? toEl.value : "trading";
const amount = xferPickBalance(bal, from, ccy);
if (!amount) {
setXferMsg("划出账户可用余额不足", true);
return;
}
const msg =
"确认全部划转?\n\n" +
"币种:" + ccy + "\n" +
"划出:" + xferAccountLabel(from) + "\n" +
"划入:" + xferAccountLabel(to) + "\n" +
"金额:" + amount.toFixed(2) + " " + ccy + "\n\n" +
"将划转该账户全部可用余额。";
if (!confirm(msg)) return;
if (amtEl) amtEl.value = String(amount);
await submitPosTransfer(amount);
} catch (e) {
setXferMsg("划转失败:" + (e.message || "余额拉取失败"), true);
}
});
}
}
async function retrySellBackCoin() {
const uly = String(state.underlying || "ETH").toUpperCase();
const d = await refreshBridgeSellUi(true);
@@ -2860,6 +3018,7 @@
});
}
bindOptionsPosTabs();
bindPosTransferControls();
hardenOrderAutofill();
(function bindProfitExitOpenControls() {