feat: options UI scroll layout, stats card, funding balance, and cross-account transfer
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2356,8 +2356,16 @@ html[data-theme="light"] .settings-export-link {
|
||||
}
|
||||
.options-strike-table-wrap {
|
||||
overflow-x: auto;
|
||||
overflow-y: auto;
|
||||
max-height: 352px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.options-strike-table thead th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
background: rgba(18, 24, 38, 0.98);
|
||||
}
|
||||
.options-strike-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
@@ -2462,7 +2470,68 @@ html[data-theme="light"] .settings-export-link {
|
||||
display: grid;
|
||||
grid-template-columns: 1.15fr 0.85fr;
|
||||
gap: 16px;
|
||||
align-items: start;
|
||||
align-items: stretch;
|
||||
}
|
||||
.options-order-card,
|
||||
.options-pos-card-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
.options-pos-stack {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
min-height: 0;
|
||||
}
|
||||
.options-pos-subcard {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
.options-pos-subcard h3 {
|
||||
margin: 0 0 8px;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
.options-pos-live-pane {
|
||||
flex: 1;
|
||||
min-height: 100px;
|
||||
max-height: 220px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.options-pos-stats-card {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.options-stats-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px 24px;
|
||||
}
|
||||
.options-stat-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.options-stat-item .k {
|
||||
font-size: 0.78rem;
|
||||
opacity: 0.7;
|
||||
}
|
||||
.options-stat-item .v {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
.options-pos-history-card {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.options-history-table-wrap {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
min-height: 120px;
|
||||
}
|
||||
@media (max-width: 1100px) {
|
||||
.options-dual-grid {
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
optType: "C",
|
||||
chain: null,
|
||||
selectedInst: null,
|
||||
posTab: "live",
|
||||
};
|
||||
|
||||
function fmt(v, d) {
|
||||
@@ -289,7 +288,7 @@
|
||||
msgEl.textContent = d.ok ? "下单已提交,可在 OKX 委托中查看" : (d.msg || "失败");
|
||||
msgEl.classList.toggle("opt-error", !d.ok);
|
||||
if (d.ok) {
|
||||
refreshPositions();
|
||||
refreshAllPositions();
|
||||
if (typeof refreshAccountSnapshot === "function") refreshAccountSnapshot();
|
||||
} else {
|
||||
alert(d.msg || "下单失败");
|
||||
@@ -349,8 +348,7 @@
|
||||
} else {
|
||||
alert(r.msg || "平仓失败");
|
||||
}
|
||||
refreshPositions();
|
||||
refreshHistory();
|
||||
refreshAllPositions();
|
||||
if (typeof refreshAccountSnapshot === "function") refreshAccountSnapshot();
|
||||
} finally {
|
||||
if (btn) btn.disabled = false;
|
||||
@@ -380,6 +378,24 @@
|
||||
});
|
||||
}
|
||||
|
||||
async function refreshStats() {
|
||||
const d = await apiJson("/api/options/stats");
|
||||
const winEl = document.getElementById("opt-stats-winrate");
|
||||
const plrEl = document.getElementById("opt-stats-plr");
|
||||
const closedEl = document.getElementById("opt-stats-closed");
|
||||
if (!d.ok) {
|
||||
if (winEl) winEl.textContent = "—";
|
||||
if (plrEl) plrEl.textContent = "—";
|
||||
if (closedEl) closedEl.textContent = "—";
|
||||
return;
|
||||
}
|
||||
if (winEl) winEl.textContent = d.total_closed ? d.win_rate + "%" : "0%";
|
||||
if (plrEl) {
|
||||
plrEl.textContent = d.profit_loss_ratio != null ? String(d.profit_loss_ratio) : "—";
|
||||
}
|
||||
if (closedEl) closedEl.textContent = String(d.total_closed || 0);
|
||||
}
|
||||
|
||||
async function refreshHistory() {
|
||||
const d = await apiJson("/api/options/history");
|
||||
const tbody = document.getElementById("opt-history-tbody");
|
||||
@@ -405,14 +421,10 @@
|
||||
});
|
||||
}
|
||||
|
||||
function switchPosTab(tab) {
|
||||
state.posTab = tab;
|
||||
document.querySelectorAll(".opt-pos-tab").forEach(function (b) {
|
||||
b.classList.toggle("active", b.getAttribute("data-tab") === tab);
|
||||
});
|
||||
document.getElementById("opt-pos-live").hidden = tab !== "live";
|
||||
document.getElementById("opt-pos-history").hidden = tab !== "history";
|
||||
if (tab === "history") refreshHistory();
|
||||
function refreshAllPositions() {
|
||||
refreshPositions();
|
||||
refreshStats();
|
||||
refreshHistory();
|
||||
}
|
||||
|
||||
document.querySelectorAll(".opt-uly-btn").forEach(function (btn) {
|
||||
@@ -433,18 +445,9 @@
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll(".opt-pos-tab").forEach(function (btn) {
|
||||
btn.addEventListener("click", function () {
|
||||
switchPosTab(btn.getAttribute("data-tab"));
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById("opt-exp-select").addEventListener("change", renderStrikes);
|
||||
document.getElementById("opt-load-chain").addEventListener("click", loadChain);
|
||||
document.getElementById("opt-refresh-positions").addEventListener("click", function () {
|
||||
refreshPositions();
|
||||
if (state.posTab === "history") refreshHistory();
|
||||
});
|
||||
document.getElementById("opt-refresh-positions").addEventListener("click", refreshAllPositions);
|
||||
document.getElementById("opt-open-btn").addEventListener("click", openPosition);
|
||||
|
||||
document.querySelectorAll('input[name="opt-size-mode"]').forEach(function (r) {
|
||||
@@ -464,5 +467,5 @@
|
||||
|
||||
updateSizeInputs();
|
||||
loadChain();
|
||||
refreshPositions();
|
||||
refreshAllPositions();
|
||||
})();
|
||||
|
||||
@@ -64,10 +64,12 @@
|
||||
body: JSON.stringify({
|
||||
ccy: document.getElementById("opt-set-cross-ccy").value,
|
||||
amount: amount,
|
||||
account: document.getElementById("opt-set-cross-acct").value,
|
||||
from_account: document.getElementById("opt-set-cross-from-acct").value,
|
||||
to_account: document.getElementById("opt-set-cross-to-acct").value,
|
||||
direction: document.getElementById("opt-set-cross-dir").value,
|
||||
}),
|
||||
});
|
||||
setMsg("opt-set-cross-msg", d.ok ? "划转成功" : (d.msg || "失败"), !d.ok);
|
||||
if (d.ok && typeof refreshAccountSnapshot === "function") refreshAccountSnapshot();
|
||||
});
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user