Show open-capacity labels, enlarge funds, move rules; WeCom on short funds.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-29 17:53:43 +08:00
parent 6081fb7e48
commit 80c561bdce
7 changed files with 399 additions and 31 deletions
+12
View File
@@ -233,6 +233,18 @@ export type PlanState = {
atm_open_offset_enabled?: boolean;
max_atm_open_offset?: number;
can_open: boolean;
open_capacity?: {
leverage?: number;
perp_can_open?: boolean | null;
option_can_open?: boolean | null;
perp_label?: string;
option_label?: string;
funds_ok?: boolean;
perp_need_usdt?: number | null;
option_need_usdc?: number | null;
perp_have_usdt?: number | null;
option_have_usdc?: number | null;
};
last_error: string | null;
show_manual_trade_buttons?: boolean;
position: {
+6 -28
View File
@@ -31,7 +31,6 @@ function pnlClass(n: number | null | undefined) {
export default function FundsBar() {
const [s, setS] = useState<FundsSummary | null>(null);
const [rulesOpen, setRulesOpen] = useState(false);
const load = useCallback(() => {
apiFetch<FundsSummary>("/api/funds/summary")
@@ -49,10 +48,6 @@ export default function FundsBar() {
if (!s?.ok) return null;
const rulesText = `行情 ${s.exchange || "OKX"} · ${
s.perp_inst_id || "ETH-USDT-SWAP"
} · 目标平仓(双腿/远虚只平永续) · 未达标则到期结算`;
return (
<div className="funds-bar-shell">
<div className="funds-bar-inner">
@@ -83,50 +78,33 @@ export default function FundsBar() {
: "—"}
</div>
</div>
<div className="funds-item">
<div className="funds-item funds-item--money">
<div className="funds-label"></div>
<div className="funds-value mono">{fmtU(s.total_funds)}</div>
</div>
<div className="funds-item">
<div className="funds-item funds-item--money">
<div className="funds-label"></div>
<div className="funds-value mono">{fmtU(s.funding_usdt)}</div>
</div>
<div className="funds-item">
<div className="funds-item funds-item--money">
<div className="funds-label"></div>
<div className="funds-value mono">{fmtU(s.trading_usdt)}</div>
</div>
<div className="funds-item">
<div className="funds-item funds-item--money">
<div className="funds-label"></div>
<div className="funds-value mono">{s.options_funding_label}</div>
</div>
<div className="funds-item">
<div className="funds-item funds-item--money">
<div className="funds-label"></div>
<div className="funds-value mono">{s.options_trading_label}</div>
</div>
<div className="funds-item funds-item--pnl">
<div className="funds-item funds-item--pnl funds-item--money">
<div className="funds-label"></div>
<div className={`funds-value mono ${pnlClass(s.realtime_pnl)}`}>
{s.realtime_pnl == null ? "—" : fmtU(s.realtime_pnl)}
</div>
</div>
</div>
<div className="funds-rules">
<button
type="button"
className="funds-rules-toggle"
aria-expanded={rulesOpen}
onClick={() => setRulesOpen((v) => !v)}
>
<span></span>
<span className="funds-rules-chevron" aria-hidden>
{rulesOpen ? "▾" : "▸"}
</span>
</button>
{rulesOpen ? (
<p className="funds-rules-body meta">{rulesText}</p>
) : null}
</div>
</div>
</div>
);
+46 -3
View File
@@ -80,6 +80,7 @@ const PHASE_ZH: Record<string, string> = {
outside_window: "窗外",
liquidity_wait: "流动性等待",
weekend_skip: "周末跳过",
wait_funds: "资金不足",
};
export default function PlanPage() {
@@ -213,6 +214,16 @@ export default function PlanPage() {
{err ? <div className="err">{err}</div> : null}
<div className="plan-rules-fold">
<details>
<summary></summary>
<p className="meta plan-rules-body">
{String(plan?.exchange || "okx").toUpperCase()} · ETH-USDT-SWAP ·
(/) ·
</p>
</details>
</div>
<div className="plan-actions">
<button
className={plan?.running ? "btn btn-running" : "btn"}
@@ -318,9 +329,41 @@ export default function PlanPage() {
</div>
<div className="kv">
<span> / </span>
<span className="mono">
{fmt(plan?.ledger?.equity)} / {fmt(plan?.ledger?.available)} ·{" "}
{fmt(plan?.leverage, 0)}x
<span className="open-cap-row">
<span
className={
plan?.open_capacity?.perp_can_open === true
? "open-cap-ok"
: plan?.open_capacity?.perp_can_open === false
? "open-cap-bad"
: "mono"
}
title={
plan?.open_capacity?.perp_need_usdt != null
? `需≈${plan.open_capacity.perp_need_usdt}U / 有${plan.open_capacity.perp_have_usdt ?? "—"}U`
: undefined
}
>
{plan?.open_capacity?.perp_label ||
`永续${fmt(plan?.leverage, 0)}x —`}
</span>
<span className="open-cap-sep">·</span>
<span
className={
plan?.open_capacity?.option_can_open === true
? "open-cap-ok"
: plan?.open_capacity?.option_can_open === false
? "open-cap-bad"
: "mono"
}
title={
plan?.open_capacity?.option_need_usdc != null
? `需≈${plan.open_capacity.option_need_usdc}U / 有${plan.open_capacity.option_have_usdc ?? "—"}U`
: undefined
}
>
{plan?.open_capacity?.option_label || "期权 —"}
</span>
</span>
</div>
<div className="kv">
+59
View File
@@ -232,6 +232,16 @@ input {
white-space: nowrap;
}
.funds-item--money .funds-value {
font-size: 16px;
font-weight: 700;
letter-spacing: 0.01em;
}
.funds-item--money .funds-label {
font-size: 12px;
}
.funds-item--pnl .funds-value {
font-variant-numeric: tabular-nums;
}
@@ -271,6 +281,55 @@ input {
color: var(--muted);
}
.plan-rules-fold {
margin: 0 0 10px;
}
.plan-rules-fold details {
border: 1px solid var(--line);
border-radius: 8px;
background: var(--bg-panel);
padding: 8px 12px;
}
.plan-rules-fold summary {
cursor: pointer;
color: var(--muted);
font-size: 13px;
user-select: none;
}
.plan-rules-fold summary:hover {
color: var(--text);
}
.plan-rules-body {
margin: 8px 0 0;
line-height: 1.45;
}
.open-cap-row {
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
font-weight: 700;
font-size: 14px;
}
.open-cap-sep {
color: var(--muted);
font-weight: 500;
}
.open-cap-ok {
color: #0ecb81;
}
.open-cap-bad {
color: #f6465d;
}
.topnav {
display: none;
}