feat(hub): simplify desktop monitor cards to positions only
Move orders, key levels, entrust, trend plans, and roll groups to fullscreen detail view. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1537,7 +1537,9 @@
|
|||||||
.join("");
|
.join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderPositionBlock(exchangeId, exchangeKey, x, monitorOrder, trendPlan, tickMap) {
|
function renderPositionBlock(exchangeId, exchangeKey, x, monitorOrder, trendPlan, tickMap, opts) {
|
||||||
|
const options = opts || {};
|
||||||
|
const compact = !!options.compact;
|
||||||
const symAttr = esc(x.symbol || "").replace(/"/g, """);
|
const symAttr = esc(x.symbol || "").replace(/"/g, """);
|
||||||
const exKeyAttr = esc(exchangeKey || exchangeId || "").replace(/"/g, """);
|
const exKeyAttr = esc(exchangeKey || exchangeId || "").replace(/"/g, """);
|
||||||
const sideAttr = esc((x.side || "").toLowerCase()).replace(/"/g, """);
|
const sideAttr = esc((x.side || "").toLowerCase()).replace(/"/g, """);
|
||||||
@@ -1551,6 +1553,15 @@
|
|||||||
const tpAttr = esc(String(tpsl.tp)).replace(/"/g, """);
|
const tpAttr = esc(String(tpsl.tp)).replace(/"/g, """);
|
||||||
const mktAttrs = marketOpenBtnAttrs(exchangeId, exchangeKey, x.symbol, x, monitorOrder, trendPlan);
|
const mktAttrs = marketOpenBtnAttrs(exchangeId, exchangeKey, x.symbol, x, monitorOrder, trendPlan);
|
||||||
const symBeBadge = beSecured ? ` ${breakevenBadgeHtml()}` : "";
|
const symBeBadge = beSecured ? ` ${breakevenBadgeHtml()}` : "";
|
||||||
|
const actionCell = compact
|
||||||
|
? `<button type="button" class="btn-close-pos btn-sm danger" data-ex-id="${esc(exchangeId)}" data-symbol="${symAttr}" data-side="${sideAttr}">平仓</button>`
|
||||||
|
: `<div class="pos-action-group">
|
||||||
|
<button type="button" class="btn-place-tpsl btn-sm ghost" data-ex-id="${esc(exchangeId)}" data-symbol="${symAttr}" data-side="${sideAttr}" data-contracts="${contractsAttr}" data-sl="${slAttr}" data-tp="${tpAttr}">委托</button>
|
||||||
|
<button type="button" class="btn-close-pos btn-sm danger" data-ex-id="${esc(exchangeId)}" data-symbol="${symAttr}" data-side="${sideAttr}">平仓</button>
|
||||||
|
</div>`;
|
||||||
|
const ordersBlock = compact
|
||||||
|
? ""
|
||||||
|
: renderOrdersCollapse(exchangeId, x.symbol, cond, reg, tickMap);
|
||||||
return `<div class="pos-block">
|
return `<div class="pos-block">
|
||||||
<div class="table-scroll">
|
<div class="table-scroll">
|
||||||
<table class="data-table"><thead><tr><th>合约</th><th>方向</th><th>开仓价</th><th>标记价</th><th>张数</th><th>浮盈</th><th>操作</th></tr></thead><tbody>
|
<table class="data-table"><thead><tr><th>合约</th><th>方向</th><th>开仓价</th><th>标记价</th><th>张数</th><th>浮盈</th><th>操作</th></tr></thead><tbody>
|
||||||
@@ -1561,16 +1572,11 @@
|
|||||||
<td>${fmtMarkPrice(x, tickMap)}</td>
|
<td>${fmtMarkPrice(x, tickMap)}</td>
|
||||||
<td>${fmt(x.contracts, 4)}</td>
|
<td>${fmt(x.contracts, 4)}</td>
|
||||||
<td class="${pnlCls(x.unrealized_pnl)}">${fmt(x.unrealized_pnl, 2)}</td>
|
<td class="${pnlCls(x.unrealized_pnl)}">${fmt(x.unrealized_pnl, 2)}</td>
|
||||||
<td class="td-actions">
|
<td class="td-actions">${actionCell}</td>
|
||||||
<div class="pos-action-group">
|
|
||||||
<button type="button" class="btn-place-tpsl btn-sm ghost" data-ex-id="${esc(exchangeId)}" data-symbol="${symAttr}" data-side="${sideAttr}" data-contracts="${contractsAttr}" data-sl="${slAttr}" data-tp="${tpAttr}">委托</button>
|
|
||||||
<button type="button" class="btn-close-pos btn-sm danger" data-ex-id="${esc(exchangeId)}" data-symbol="${symAttr}" data-side="${sideAttr}">平仓</button>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</tbody></table>
|
</tbody></table>
|
||||||
</div>
|
</div>
|
||||||
${renderOrdersCollapse(exchangeId, x.symbol, cond, reg, tickMap)}
|
${ordersBlock}
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1590,63 +1596,15 @@
|
|||||||
p,
|
p,
|
||||||
findMonitorOrder(orders, p.symbol, p.side),
|
findMonitorOrder(orders, p.symbol, p.side),
|
||||||
findTrendPlan(trends, p.symbol, p.side),
|
findTrendPlan(trends, p.symbol, p.side),
|
||||||
tickMap
|
tickMap,
|
||||||
|
{ compact: true }
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.join("");
|
.join("");
|
||||||
} else {
|
} else {
|
||||||
inner += '<div class="empty-hint">无持仓</div>';
|
inner += '<div class="empty-hint">无持仓</div>';
|
||||||
}
|
}
|
||||||
if (orders.length) {
|
inner += `<div class="card-expand-hint">点击标题栏进入全屏 · 委托 / 关键位 / 下单监控 / 趋势回调 / 顺势加仓</div>`;
|
||||||
inner += `<div class="section-title">下单监控 · ${orders.length}</div>`;
|
|
||||||
orders.forEach((o) => {
|
|
||||||
const sym = o.exchange_symbol || o.symbol || "";
|
|
||||||
inner += `<div class="list-line">${esc(o.symbol || o.exchange_symbol)} · ${renderDirectionHtml(o.direction)} · 触发 ${fmtSymbolPrice(o.trigger_price, sym, tickMap)}</div>`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if ((row.capabilities || []).includes("key")) {
|
|
||||||
inner += `<div class="section-title">关键位 · ${keys.length}</div>`;
|
|
||||||
if (!flaskOk) {
|
|
||||||
const fe = row.flask_error || hm.msg || hm.error || "策略 Flask 未连通";
|
|
||||||
inner += `<div class="err">${esc(fe)}</div>`;
|
|
||||||
} else if (!keys.length) {
|
|
||||||
inner += '<div class="empty-hint">当前无记录</div>';
|
|
||||||
} else {
|
|
||||||
keys.forEach((k) => {
|
|
||||||
const kp = kmap[k.id] || kmap[String(k.id)] || {};
|
|
||||||
const mt = k.monitor_type || k.type || "";
|
|
||||||
const pending = keyHasPendingOrder(k, kp);
|
|
||||||
const lineCls = pending ? "list-line hub-key-pending" : "list-line";
|
|
||||||
let line = `${esc(k.symbol)} · ${esc(mt)}`;
|
|
||||||
if (k.direction) line += ` · ${renderDirectionHtml(k.direction)}`;
|
|
||||||
if (pending) line += ` · <span class="hub-key-pending-tag">挂单</span>`;
|
|
||||||
const amtTxt = fmtKeyOrderAmount(k);
|
|
||||||
if (amtTxt) line += ` · 数量 ${esc(amtTxt)}`;
|
|
||||||
line += ` · ${esc(k.upper)} / ${esc(k.lower)}`;
|
|
||||||
if (kp.price_display != null || kp.price != null) {
|
|
||||||
line += ` · ${esc(kp.price_display != null ? kp.price_display : kp.price)}`;
|
|
||||||
}
|
|
||||||
line += ` · ${esc(kp.gate_summary || "-")}`;
|
|
||||||
inner += `<div class="${lineCls}">${line}</div>`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((row.capabilities || []).includes("trend") && trends.length) {
|
|
||||||
inner += `<div class="section-title">趋势回调 · ${trends.length}</div>`;
|
|
||||||
trends.forEach((t) => {
|
|
||||||
const sym = t.exchange_symbol || t.symbol || "";
|
|
||||||
const sl = t.stop_loss_display || fmtSymbolPrice(t.stop_loss, sym, tickMap);
|
|
||||||
const tp = t.take_profit_display || fmtSymbolPrice(t.take_profit, sym, tickMap);
|
|
||||||
inner += `<div class="list-line">#${t.id} ${esc(t.symbol)} ${renderDirectionHtml(t.direction)} · 均价 ${esc(t.avg_entry_price_display || fmtSymbolPrice(t.avg_entry_price, sym, tickMap))} · SL ${esc(sl)} · TP ${esc(tp)}${trendAddSummaryHtml(t, tickMap)}</div>`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (rolls.length) {
|
|
||||||
inner += `<div class="section-title">顺势加仓 · ${rolls.length}</div>`;
|
|
||||||
rolls.forEach((g) => {
|
|
||||||
inner += `<div class="list-line">组 #${g.id} · 监控 #${g.order_monitor_id || "—"} · ${g.leg_count != null ? g.leg_count : "—"} 腿</div>`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
inner += `<div class="card-expand-hint">点击标题栏放大全屏 · 查看持仓卡片 / 关键位 / 策略详情</div>`;
|
|
||||||
return inner;
|
return inner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -246,6 +246,6 @@
|
|||||||
<div id="toast"></div>
|
<div id="toast"></div>
|
||||||
<script src="https://unpkg.com/lightweight-charts@4.2.0/dist/lightweight-charts.standalone.production.js"></script>
|
<script src="https://unpkg.com/lightweight-charts@4.2.0/dist/lightweight-charts.standalone.production.js"></script>
|
||||||
<script src="/assets/chart.js?v=20260603-hub-binance-tick"></script>
|
<script src="/assets/chart.js?v=20260603-hub-binance-tick"></script>
|
||||||
<script src="/assets/app.js?v=20260604-hub-mobile-tiles"></script>
|
<script src="/assets/app.js?v=20260604-hub-grid-compact2"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user