中控手机卡片改为大浮盈与短合约名,减少重复行。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-05 19:24:43 +08:00
parent cf347e7b6b
commit a835e3aeec
4 changed files with 137 additions and 32 deletions
+47 -15
View File
@@ -1873,45 +1873,77 @@ html.hub-phone-html #overview-status {
.hub-phone-cards {
display: flex;
flex-direction: column;
gap: 10px;
gap: 14px;
}
.hub-phone-card {
background: rgba(16, 24, 40, 0.92);
border: 1px solid rgba(56, 189, 248, 0.2);
border-radius: 12px;
padding: 12px;
border-radius: 14px;
padding: 16px 16px 14px;
}
.hub-phone-card-head {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 6px;
margin-bottom: 12px;
}
.hub-phone-card-head strong {
font-size: 1.02rem;
line-height: 1.3;
}
.hub-phone-card-tags {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px 8px;
margin-bottom: 8px;
gap: 6px;
}
.hub-phone-card-pnl {
margin-bottom: 10px;
}
.hub-phone-card-pnl .muted {
display: block;
font-size: 0.72rem;
margin-bottom: 2px;
}
.hub-phone-card-pnl span:not(.muted) {
font-size: 1.35rem;
font-weight: 700;
font-variant-numeric: tabular-nums;
letter-spacing: -0.02em;
}
.hub-phone-card-kpis {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 8px;
margin-bottom: 8px;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 8px 12px;
margin-bottom: 12px;
}
.hub-phone-card-kpis .muted {
display: block;
font-size: 0.68rem;
font-size: 0.72rem;
margin-bottom: 2px;
}
.hub-phone-card-pos .pos-brief {
font-size: 0.78rem;
.hub-phone-card-pos {
font-size: 0.92rem;
line-height: 1.45;
}
.hub-phone-card-exit,
.hub-phone-card-liq {
font-size: 0.76rem;
.hub-phone-pos-line + .hub-phone-pos-line {
margin-top: 4px;
}
.hub-phone-card-foot {
margin-top: 8px;
font-size: 0.8rem;
line-height: 1.4;
}
.hub-phone-card-err {
margin: 0 0 8px;
font-size: 0.78rem;
}
.hub-phone-card-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 10px;
margin-top: 14px;
}
html.hub-phone-html .desk {
display: none !important;
+88 -15
View File
@@ -337,6 +337,82 @@
});
}
function shortOptName(id) {
const s = String(id || "").trim();
if (!s) return "—";
const parts = s.split("-");
if (parts.length >= 5) {
const base = parts[0];
const strike = parts[3];
const ot = String(parts[4] || "").toUpperCase();
const side = ot === "P" ? "Put" : ot === "C" ? "Call" : ot;
return base + " " + side + " " + strike;
}
return s;
}
function formatExitBriefPhone(p) {
if (!p) return "";
if (p.target_monitor_text && String(p.target_monitor_text).trim() && p.target_monitor_text !== "—") {
return String(p.target_monitor_text).trim();
}
const tgt = Number(p.target_index);
if (Number.isFinite(tgt) && tgt > 0) {
const ot = String(p.opt_type || "").toUpperCase();
const side = ot === "P" ? "Put≤" : ot === "C" ? "Call≥" : "目标";
return side + tgt;
}
if (p.profit_exit_enabled) {
const m = Number(p.profit_exit_mult);
if (Number.isFinite(m) && m > 0) {
return (Math.abs(m - Math.round(m)) < 1e-9 ? Math.round(m) : m) + "倍出场";
}
return "利润出场";
}
return "";
}
function phonePosLine(p) {
const sheets = p.sheets != null ? String(p.sheets) : "—";
const lev = Number(p.contract_leverage != null ? p.contract_leverage : p.leverage);
const levTxt = Number.isFinite(lev) && lev > 0 ? " · " + lev.toFixed(1) + "×" : "";
return escapeHtml(shortOptName(p.inst_id) + " · " + sheets + "张" + levTxt);
}
function phonePositionBlock(brief, cond) {
const list = brief || [];
if (!list.length) {
if (cond) {
return (
'<div class="hub-phone-card-pos">' +
escapeHtml(condWaitLine(cond)) +
"</div>"
);
}
return '<div class="hub-phone-card-pos muted">暂无持仓</div>';
}
const shown = list.slice(0, 3).map(function (p) {
return '<div class="hub-phone-pos-line">' + phonePosLine(p) + "</div>";
});
if (list.length > 3) {
shown.push('<div class="muted">还有 ' + (list.length - 3) + " 笔</div>");
}
return '<div class="hub-phone-card-pos">' + shown.join("") + "</div>";
}
function phoneFootLine(brief) {
const list = brief || [];
if (!list.length) return "";
const bits = [];
const exitText = formatExitBriefPhone(list[0]);
if (exitText) bits.push(exitText);
const liq = bidLiquidityLine(list[0]);
if (liq && liq.text) bits.push((liq.weak ? "买一弱 " : "") + liq.text);
if (!bits.length) return "";
const cls = liq && liq.weak ? "hub-phone-card-foot liq-warn" : "hub-phone-card-foot muted";
return '<div class="' + cls + '">' + escapeHtml(bits.join(" · ")) + "</div>";
}
function renderPhoneCard(row) {
const snap = row.snapshot || {};
const inst = snap.instance || {};
@@ -351,7 +427,9 @@
const modeHtml =
m === "sim" || m === "live"
? '<span class="overview-mode-tag overview-mode-tag--' + m + '">' + escapeHtml(m) + "</span>"
: '<span class="muted">' + escapeHtml(inst.mode || "—") + "</span>";
: inst.mode
? '<span class="muted">' + escapeHtml(inst.mode) + "</span>"
: "";
const err = row.error
? '<div class="muted hub-phone-card-err">错误: ' + escapeHtml(row.error) + "</div>"
: "";
@@ -361,31 +439,26 @@
"<strong>" +
escapeHtml(row.name || "") +
"</strong>" +
'<div class="hub-phone-card-tags">' +
(online ? '<span class="status-on">在线</span>' : '<span class="status-off">离线</span>') +
modeHtml +
condTagHtml(cond) +
"</div>" +
"</div></div>" +
err +
'<div class="hub-phone-card-kpis">' +
'<div><span class="muted">浮盈</span>' +
'<div class="hub-phone-card-pnl">' +
'<span class="muted">浮盈</span>' +
fmtPnlHtml(pnl) +
"</div>" +
'<div><span class="muted">权利金</span>' +
'<div class="hub-phone-card-kpis">' +
"<div><span class=\"muted\">权利金</span>" +
premiumCell(snap) +
"</div>" +
'<div><span class="muted">占比</span>' +
"<div><span class=\"muted\">占比</span>" +
premiumRatioCell(snap) +
"</div>" +
"</div>" +
'<div class="hub-phone-card-pos">' +
positionSummary(brief, cond) +
"</div>" +
'<div class="hub-phone-card-exit muted">出场 ' +
(brief.length ? escapeHtml(formatExitBrief(brief[0])) : "—") +
"</div>" +
'<div class="hub-phone-card-liq">' +
bidLiquiditySummary(brief) +
"</div>" +
phonePositionBlock(brief, cond) +
phoneFootLine(brief) +
'<div class="hub-phone-card-actions">' +
'<button type="button" class="btn" data-open-inst="' +
escapeHtml(String(row.id || "")) +
+1 -1
View File
@@ -11,7 +11,7 @@
<link rel="icon" href="{{ url_for('static', filename='icons/favicon.ico') }}?v=2" sizes="any">
<link rel="apple-touch-icon" href="{{ url_for('static', filename='icons/apple-touch-icon.png') }}?v=2">
<link rel="manifest" href="/manifest.webmanifest">
<link rel="stylesheet" href="{{ url_for('static', filename='hub.css') }}?v=39">
<link rel="stylesheet" href="{{ url_for('static', filename='hub.css') }}?v=40">
<script>
(function () {
try {
+1 -1
View File
@@ -15,6 +15,6 @@
<div id="overview-grid"></div>
{% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='hub.js') }}?v=27"></script>
<script src="{{ url_for('static', filename='hub.js') }}?v=28"></script>
<script>HubOverview.boot();</script>
{% endblock %}