fix(web): 监控页表格五修(用户验收08-26晚)——①整表挤左根治:五张表全部固定width→min-width(08-20四修治折行时全列定宽,合计~600px<卡片宽,Element固定列不拉伸→右侧大片空白;min-width保下限不折行+剩余宽度按比例分配铺满整卡)②小数位统一(非设计初衷,原始浮点透出14.6/23.577/200.0混杂):均价/价格/成本统一fmtPrice两位小数,数量/持仓/冻结/可卖num()取整千分位,时间列fmtTradeTime兼容空格式与ISO'T'两种落库路径;npm run build绿 [vps]
CI/CD / test (push) Successful in 9s
CI/CD / nas-deploy (push) Successful in 30s
CI/CD / nas-verify (push) Successful in 5s

This commit is contained in:
2026-08-26 23:06:30 +08:00
parent a7c2dd6f59
commit c0dd91e8d2
+69 -33
View File
@@ -81,6 +81,18 @@ function pct(v: number | null): string {
return (v * 100).toFixed(2) + '%'
}
/** 价格/成本统一 2 位小数(原始浮点透出会 14.6 / 23.577 混杂) */
function fmtPrice(v: number | null | undefined): string {
if (v == null || !Number.isFinite(v)) return '—'
return v.toFixed(2)
}
/** 成交时间:兼容 'YYYY-MM-DD HH:MM:SS'(组合实盘) 与 ISO 'T'(supervisor) 两种落库格式 */
function fmtTradeTime(v: string | null | undefined): string {
if (!v) return '—'
return String(v).replace('T', ' ').slice(0, 19)
}
async function load(): Promise<void> {
try {
const [acc, st, bal, pos, tr] = await Promise.all([
@@ -240,14 +252,20 @@ async function onStop(): Promise<void> {
<el-card shadow="never">
<template #header><span class="section-title">本策略持仓(实例账本)</span></template>
<el-table :data="positions" size="small" empty-text="无持仓">
<el-table-column prop="symbol" label="标的" width="90" />
<el-table-column prop="volume" label="总持仓" width="90" class-name="num" />
<el-table-column prop="frozen" label="冻结" width="80" class-name="num" />
<el-table-column label="数量(可用)" width="100" class-name="num">
<template #default="{ row }">{{ row.volume - row.frozen }}</template>
<el-table-column prop="symbol" label="标的" min-width="100" />
<el-table-column prop="volume" label="总持仓" min-width="90" class-name="num">
<template #default="{ row }">{{ num(row.volume) }}</template>
</el-table-column>
<el-table-column prop="avg_price" label="均价" width="90" class-name="num" />
<el-table-column prop="updated_at" label="更新时间" min-width="150">
<el-table-column prop="frozen" label="冻结" min-width="80" class-name="num">
<template #default="{ row }">{{ num(row.frozen) }}</template>
</el-table-column>
<el-table-column label="数量(可用)" min-width="110" class-name="num">
<template #default="{ row }">{{ num(row.volume - row.frozen) }}</template>
</el-table-column>
<el-table-column prop="avg_price" label="均价" min-width="90" class-name="num">
<template #default="{ row }">{{ fmtPrice(row.avg_price) }}</template>
</el-table-column>
<el-table-column prop="updated_at" label="更新时间" min-width="160">
<template #default="{ row }">{{ fmtTime(row.updated_at) }}</template>
</el-table-column>
</el-table>
@@ -257,19 +275,25 @@ async function onStop(): Promise<void> {
<el-card shadow="never">
<template #header><span class="section-title">本策略今日成交(归因)</span></template>
<el-table :data="todayTrades" size="small" empty-text="今日无成交">
<el-table-column prop="traded_at" label="时间" width="150" />
<el-table-column prop="strategy_name" label="策略" width="110" show-overflow-tooltip />
<el-table-column prop="symbol" label="标的" width="90" />
<el-table-column label="方向" width="70">
<el-table-column prop="traded_at" label="时间" min-width="150">
<template #default="{ row }">{{ fmtTradeTime(row.traded_at) }}</template>
</el-table-column>
<el-table-column prop="strategy_name" label="策略" min-width="110" show-overflow-tooltip />
<el-table-column prop="symbol" label="标的" min-width="100" />
<el-table-column label="方向" min-width="70">
<template #default="{ row }">
<span :class="row.direction === '多' || row.direction === 'buy' ? 'up' : 'down'">
{{ row.direction }}
</span>
</template>
</el-table-column>
<el-table-column prop="offset" label="开平" width="70" />
<el-table-column prop="price" label="价格" width="100" class-name="num" />
<el-table-column prop="volume" label="数量" width="90" class-name="num" />
<el-table-column prop="offset" label="开平" min-width="70" />
<el-table-column prop="price" label="价格" min-width="100" class-name="num">
<template #default="{ row }">{{ fmtPrice(row.price) }}</template>
</el-table-column>
<el-table-column prop="volume" label="数量" min-width="90" class-name="num">
<template #default="{ row }">{{ num(row.volume) }}</template>
</el-table-column>
</el-table>
</el-card>
@@ -277,19 +301,25 @@ async function onStop(): Promise<void> {
<el-card shadow="never">
<template #header><span class="section-title">本策略全部成交(归因,最新在上)</span></template>
<el-table :data="[...trades].reverse()" size="small" empty-text="无成交" max-height="400">
<el-table-column prop="traded_at" label="时间" width="150" />
<el-table-column prop="strategy_name" label="策略" width="110" show-overflow-tooltip />
<el-table-column prop="symbol" label="标的" width="90" />
<el-table-column label="方向" width="70">
<el-table-column prop="traded_at" label="时间" min-width="150">
<template #default="{ row }">{{ fmtTradeTime(row.traded_at) }}</template>
</el-table-column>
<el-table-column prop="strategy_name" label="策略" min-width="110" show-overflow-tooltip />
<el-table-column prop="symbol" label="标的" min-width="100" />
<el-table-column label="方向" min-width="70">
<template #default="{ row }">
<span :class="row.direction === '多' || row.direction === 'buy' ? 'up' : 'down'">
{{ row.direction }}
</span>
</template>
</el-table-column>
<el-table-column prop="offset" label="开平" width="70" />
<el-table-column prop="price" label="价格" width="100" class-name="num" />
<el-table-column prop="volume" label="数量" width="90" class-name="num" />
<el-table-column prop="offset" label="开平" min-width="70" />
<el-table-column prop="price" label="价格" min-width="100" class-name="num">
<template #default="{ row }">{{ fmtPrice(row.price) }}</template>
</el-table-column>
<el-table-column prop="volume" label="数量" min-width="90" class-name="num">
<template #default="{ row }">{{ num(row.volume) }}</template>
</el-table-column>
</el-table>
</el-card>
@@ -331,34 +361,40 @@ async function onStop(): Promise<void> {
<div class="acct-sub-title">实例分解</div>
<el-table :data="snap.instances" size="small" empty-text="无实例">
<el-table-column prop="id" label="#" width="60" />
<el-table-column prop="name" label="实例" width="140" show-overflow-tooltip />
<el-table-column label="状态" width="90">
<el-table-column prop="id" label="#" min-width="60" />
<el-table-column prop="name" label="实例" min-width="140" show-overflow-tooltip />
<el-table-column label="状态" min-width="90">
<template #default="{ row }">
<el-tag :type="row.status === 'running' ? 'success' : 'info'" size="small">{{ row.status }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="initial_capital" label="预算" width="110" class-name="num">
<el-table-column prop="initial_capital" label="预算" min-width="110" class-name="num">
<template #default="{ row }">{{ num(row.initial_capital) }}</template>
</el-table-column>
<el-table-column prop="cash" label="现金" width="110" class-name="num">
<el-table-column prop="cash" label="现金" min-width="110" class-name="num">
<template #default="{ row }">{{ num(row.cash) }}</template>
</el-table-column>
<el-table-column prop="market_value" label="市值" width="110" class-name="num">
<el-table-column prop="market_value" label="市值" min-width="110" class-name="num">
<template #default="{ row }">{{ num(row.market_value) }}</template>
</el-table-column>
<el-table-column prop="equity" label="净值" width="110" class-name="num">
<el-table-column prop="equity" label="净值" min-width="110" class-name="num">
<template #default="{ row }">{{ num(row.equity) }}</template>
</el-table-column>
</el-table>
<div class="acct-sub-title">账户持仓(QMT 全账户)</div>
<el-table :data="snap.positions" size="small" empty-text="账户无持仓" max-height="300">
<el-table-column prop="symbol" label="标的" width="90" />
<el-table-column prop="volume" label="持仓" width="100" class-name="num" />
<el-table-column prop="can_use" label="可卖(T+1)" width="100" class-name="num" />
<el-table-column prop="avg_price" label="成本" width="100" class-name="num" />
<el-table-column prop="mv" label="市值" width="120" class-name="num">
<el-table-column prop="symbol" label="标的" min-width="100" />
<el-table-column prop="volume" label="持仓" min-width="100" class-name="num">
<template #default="{ row }">{{ num(row.volume) }}</template>
</el-table-column>
<el-table-column prop="can_use" label="可卖(T+1)" min-width="110" class-name="num">
<template #default="{ row }">{{ num(row.can_use) }}</template>
</el-table-column>
<el-table-column prop="avg_price" label="成本" min-width="100" class-name="num">
<template #default="{ row }">{{ fmtPrice(row.avg_price) }}</template>
</el-table-column>
<el-table-column prop="mv" label="市值" min-width="120" class-name="num">
<template #default="{ row }">{{ num(row.mv) }}</template>
</el-table-column>
</el-table>