diff --git a/docs/更新文档.md b/docs/更新文档.md index a371ad4..6d70a81 100644 --- a/docs/更新文档.md +++ b/docs/更新文档.md @@ -4,6 +4,32 @@ --- +## 2026-07-16 · OKX 拆成永续/期权双卡(2×2 对齐) + +### 修改原因 + +OKX 单卡内嵌永续+期权过高,右侧币安/Gate 两卡对不齐,1080p 观感不协调。按产品建议改为四卡对齐。 + +### 修改的地方 + +| 文件 | 改动摘要 | +|------|----------| +| `manual_trading_hub/static/app.js` | 期权分栏时 OKX 渲染为「·永续」「·期权」两张独立卡;标题与操作按钮按卡片分流 | +| `manual_trading_hub/static/app.css` | 左右列均 `1fr/1fr`,四卡 2×2 等高对齐;卡体内滚 | +| `manual_trading_hub/static/index.html` | 静态资源缓存 `20260716-hub-okx-2x2` | + +### 达成的目标 + +监控区呈现:左上永续 / 左下期权 / 右上币安 / 右下 Gate,四卡对齐。 + +### 交付之后的验收 + +1. 桌面监控区可见 `OKX_趋势 · 永续` 与 `OKX_趋势 · 期权` 两张独立卡。 +2. 四卡与右侧币安、Gate 同行等高,不再一大两小。 +3. 点击任一张 OKX 卡标题仍可全屏;期权卡「全平」不重复出现。 + +--- + ## 2026-07-16 · 1080p 监控区无持仓空洞收紧 ### 修改原因 diff --git a/manual_trading_hub/static/app.css b/manual_trading_hub/static/app.css index a2aaf8b..8f7138b 100644 --- a/manual_trading_hub/static/app.css +++ b/manual_trading_hub/static/app.css @@ -1275,31 +1275,25 @@ html[data-theme="light"] .host-metric-bar { .monitor-split-right { min-width: 0; min-height: 0; -} - -.monitor-split-left > .card { - height: 100%; -} - -.monitor-split-right { display: grid; - /* 无持仓时勿 1fr 均分拉高,按内容收紧;有仓时自然增高 */ - grid-template-rows: auto auto; - align-content: start; + grid-template-rows: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; - overflow: auto; + align-content: stretch; + overflow: hidden; } +.monitor-split-left > .card, .monitor-split-right > .card { - height: auto; + height: 100%; min-height: 0; + overflow: hidden; } .card-monitor-okx-split, .card-monitor-split-side { display: flex; flex-direction: column; - overflow: visible; + overflow: hidden; } .card-monitor-okx-split .card-body, @@ -1307,7 +1301,7 @@ html[data-theme="light"] .host-metric-bar { flex: 1; display: flex; flex-direction: column; - overflow: visible; + overflow: auto; min-height: 0; } @@ -1374,6 +1368,7 @@ html[data-theme="light"] .host-metric-bar { grid-template-columns: 1fr; } + .monitor-split-left, .monitor-split-right { grid-template-rows: auto auto; } @@ -9898,15 +9893,18 @@ html[data-theme="light"] .hub-logs-card-hint { height: auto; } + body.hub-page-monitor:not(.hub-phone) .monitor-split-left, body.hub-page-monitor:not(.hub-phone) .monitor-split-right { gap: 8px; - grid-template-rows: auto auto; - align-content: start; - overflow: auto; + grid-template-rows: minmax(0, 1fr) minmax(0, 1fr); + align-content: stretch; + overflow: hidden; } + body.hub-page-monitor:not(.hub-phone) .monitor-split-left > .card, body.hub-page-monitor:not(.hub-phone) .monitor-split-right > .card { - height: auto; + height: 100%; + min-height: 0; } body.hub-page-monitor:not(.hub-phone) .card-monitor-okx-split, @@ -9922,7 +9920,7 @@ html[data-theme="light"] .hub-logs-card-hint { body.hub-page-monitor:not(.hub-phone) .card-monitor-okx-split .card-body, body.hub-page-monitor:not(.hub-phone) .card-monitor-split-side .card-body { padding: 8px 10px; - overflow: hidden; + overflow: auto; } body.hub-page-monitor:not(.hub-phone) .hub-inner-cards { @@ -10208,38 +10206,34 @@ body.hub-tablet.hub-page-monitor:not(.hub-phone) .grid-monitor-options-split .mo align-items: stretch; } -body.hub-tablet.hub-page-monitor:not(.hub-phone) .monitor-split-left > .card { +body.hub-tablet.hub-page-monitor:not(.hub-phone) .monitor-split-left > .card, +body.hub-tablet.hub-page-monitor:not(.hub-phone) .monitor-split-right > .card { height: 100%; min-height: 0; } -body.hub-tablet.hub-page-monitor:not(.hub-phone) .monitor-split-right > .card { - height: auto; - min-height: 0; -} - +body.hub-tablet.hub-page-monitor:not(.hub-phone) .monitor-split-left, body.hub-tablet.hub-page-monitor:not(.hub-phone) .monitor-split-right { - grid-template-rows: auto auto; - align-content: start; + grid-template-rows: minmax(0, 1fr) minmax(0, 1fr); + align-content: stretch; gap: 6px; min-height: 0; - overflow: auto; + overflow: hidden; } -/* 竖屏(<960)叠成 OKX 上 + Gate/币安并排 */ +/* 竖屏(<960)叠成 OKX 两卡在上 + Gate/币安并排 */ @media (max-width: 960px) { body.hub-tablet.hub-page-monitor:not(.hub-phone) .monitor-split-body { grid-template-rows: minmax(0, 1.35fr) minmax(0, 1fr); } - body.hub-tablet.hub-page-monitor:not(.hub-phone) .monitor-split-right { - grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); - grid-template-rows: auto; - align-content: stretch; + body.hub-tablet.hub-page-monitor:not(.hub-phone) .monitor-split-left { + grid-template-rows: minmax(0, 1fr) minmax(0, 1fr); } - body.hub-tablet.hub-page-monitor:not(.hub-phone) .monitor-split-right > .card { - height: 100%; + body.hub-tablet.hub-page-monitor:not(.hub-phone) .monitor-split-right { + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + grid-template-rows: minmax(0, 1fr); } } diff --git a/manual_trading_hub/static/app.js b/manual_trading_hub/static/app.js index 9c03cde..8a181cd 100644 --- a/manual_trading_hub/static/app.js +++ b/manual_trading_hub/static/app.js @@ -2434,7 +2434,11 @@ if (optionsSplit) { const okxRow = displayRows.find((r) => rowHasOptionsLayout(r)); const otherRows = displayRows.filter((r) => !rowHasOptionsLayout(r)); - const leftHtml = okxRow ? renderMonitorCard(okxRow, { okxSplit: true }) : ""; + /* OKX 拆成永续+期权两张独立卡,与右侧两所组成 2×2 对齐 */ + const leftHtml = okxRow + ? renderMonitorCard(okxRow, { okxPart: "perp", splitSide: true }) + + renderMonitorCard(okxRow, { okxPart: "options", splitSide: true }) + : ""; const rightHtml = otherRows.map((r) => renderMonitorCard(r, { splitSide: true })).join(""); cardsHtml = `
` + @@ -3852,12 +3856,26 @@ return html; } - function renderGridBody(row, ag, pos, hm, flaskOk, keys, orders, trends, rolls, kmap) { + function renderGridBody(row, ag, pos, hm, flaskOk, keys, orders, trends, rolls, kmap, layoutOpts) { + const layout = layoutOpts || {}; const tickMap = buildPriceTickMap(row); const intraday = isIntradayDisciplineRow(row); let inner = ""; + if (layout.okxPart === "perp") { + inner += renderAccountStatRow(row, ag); + inner += renderPerpetualPositionsSection(row, ag, pos, orders, trends, tickMap, intraday); + inner += renderCardStrategyStats(row, hm, flaskOk); + inner += `
点击标题栏进入全屏
`; + return inner; + } + if (layout.okxPart === "options") { + inner += renderOptionsSectionBody(row); + inner += `
点击标题栏进入全屏 · 期权专页可下单
`; + return inner; + } if (rowHasOptionsLayout(row)) { if (monitorGridOptionsSplit) { + /* 兼容旧单卡内嵌;正常分栏已走 okxPart 双卡 */ inner += '
'; inner += renderPerpetualInnerCard(row, ag, pos, orders, trends, tickMap, intraday); inner += renderOptionsInnerCard(row); @@ -4266,41 +4284,49 @@ inner = `
${esc(agErr || "子代理返回失败")}
`; inner += `
请检查 PM2 子代理与 ${esc(row.agent_url || "")}/status
`; } else { - inner = renderGridBody(row, ag, pos, hm, flaskOk, keys, orders, trends, rolls, kmap); + inner = renderGridBody(row, ag, pos, hm, flaskOk, keys, orders, trends, rolls, kmap, opts); } const online = row.http_ok && agOk; const cardCls = online ? "card-online" : "card-offline"; const dotCls = online ? "ok" : "bad"; const flaskOpen = row.flask_url_browser || row.flask_url; + const okxPart = opts.okxPart || ""; + const isOkxOptionsCard = okxPart === "options"; + const isOkxPerpCard = okxPart === "perp"; + const titleSuffix = isOkxPerpCard ? " · 永续" : isOkxOptionsCard ? " · 期权" : ""; const openFlask = flaskOpen ? `打开实例` : ""; - const openTrade = flaskOpen - ? `下单` - : ""; - const openKey = flaskOpen - ? `监控位` - : ""; + const openTrade = + flaskOpen && !isOkxOptionsCard + ? `下单` + : ""; + const openKey = + flaskOpen && !isOkxOptionsCard + ? `监控位` + : ""; const openReview = flaskOpen ? `复盘` : ""; const openOptions = - flaskOpen && (row.capabilities || []).includes("options") + flaskOpen && ((row.capabilities || []).includes("options") || isOkxOptionsCard) ? `期权` : ""; const intraday = isIntradayDisciplineRow(row); - const fcHeadBadge = intraday ? forceCloseHeadBadgeHtml(row.force_close) : ""; + const fcHeadBadge = intraday && !isOkxOptionsCard ? forceCloseHeadBadgeHtml(row.force_close) : ""; + const showCloseAll = !intraday && !isOkxOptionsCard; const layoutCls = opts.okxSplit ? " card-monitor-okx-split" - : opts.splitSide + : opts.splitSide || okxPart ? " card-monitor-split-side" : ""; - return `
+ const partAttr = okxPart ? ` data-okx-part="${esc(okxPart)}"` : ""; + return `
-
${esc(row.name)}${fcHeadBadge}${formatRiskStatusBadge(hm.risk_status)}
+
${esc(row.name)}${esc(titleSuffix)}${fcHeadBadge}${formatRiskStatusBadge(hm.risk_status)}
${esc(flaskOpen || "")}
@@ -4310,7 +4336,7 @@ ${openKey} ${openOptions} ${openReview} - ${intraday ? "" : ``} + ${showCloseAll ? `` : ""}
${inner}
diff --git a/manual_trading_hub/static/index.html b/manual_trading_hub/static/index.html index 0c4fc76..65791b1 100644 --- a/manual_trading_hub/static/index.html +++ b/manual_trading_hub/static/index.html @@ -15,7 +15,7 @@ - + @@ -1327,6 +1327,6 @@ - +