feat(web): 前端全局重构专业量化后台(深色+红涨绿跌+设计系统)

- 设计系统 styles/tokens.css: 深色token(#0d1117底/#161b22卡片) + 红涨绿跌
  (--up#f85149/--down#3fb950) + 品牌蓝#1890ff + 间距/圆角/阴影/mono
- Element Plus深色(element-dark.css + dark/css-vars)+reset
- 删Vite脚手架残留(style.css重写/HelloWorld/hero/vite/vue资源)
- Layout重构(深色专业侧边)+Login+图表统一深色(useChart/echartsDark)
- 新建paper/Live.vue实走监控(step状态/净值/持仓/今日信号10s轮询)
- 业务页套.page头, 保留所有功能/路由/api
- 验证: vue-tsc --noEmit  + npm run build 
This commit is contained in:
2026-07-09 23:02:31 +08:00
parent 252deb5ec7
commit 18d4ba2013
29 changed files with 987 additions and 574 deletions
+10 -5
View File
@@ -29,10 +29,14 @@ function open(row: TaskListItem): void {
</script>
<template>
<el-card v-loading="loading">
<template #header>
<h3>历史任务</h3>
</template>
<div class="page">
<div class="page-head">
<div>
<h2 class="page-title">历史任务</h2>
<p class="page-subtitle">回测 / 因子分析 任务列表</p>
</div>
</div>
<el-card v-loading="loading">
<el-table :data="tasks" stripe size="small" empty-text="暂无历史任务">
<el-table-column prop="task_id" label="任务 ID" min-width="220" />
<el-table-column prop="type" label="类型" width="80" />
@@ -47,5 +51,6 @@ function open(row: TaskListItem): void {
</template>
</el-table-column>
</el-table>
</el-card>
</el-card>
</div>
</template>
+10 -5
View File
@@ -77,10 +77,14 @@ async function onSubmit(): Promise<void> {
</script>
<template>
<el-card v-loading="loading">
<template #header>
<h3>新建回测</h3>
</template>
<div class="page">
<div class="page-head">
<div>
<h2 class="page-title">新建回测</h2>
<p class="page-subtitle">选择策略与标的提交后进入进度跟踪</p>
</div>
</div>
<el-card v-loading="loading">
<el-form :model="form" label-width="120px">
<el-form-item label="策略">
<el-select v-model="form.strategy" placeholder="选择策略" style="width: 280px">
@@ -103,5 +107,6 @@ async function onSubmit(): Promise<void> {
<el-button type="primary" :loading="submitting" @click="onSubmit">提交回测</el-button>
</el-form-item>
</el-form>
</el-card>
</el-card>
</div>
</template>
+10 -5
View File
@@ -90,10 +90,14 @@ async function onSubmit(): Promise<void> {
</script>
<template>
<el-card v-loading="loading || polling" :element-loading-text="stageText || '优化中…'">
<template #header>
<h3>参数优化</h3>
</template>
<div class="page">
<div class="page-head">
<div>
<h2 class="page-title">参数优化</h2>
<p class="page-subtitle">参数网格搜索 · 自动轮询结果</p>
</div>
</div>
<el-card v-loading="loading || polling" :element-loading-text="stageText || '优化中…'">
<el-form :model="form" label-width="120px">
<el-form-item label="策略">
<el-select v-model="form.strategy" style="width: 280px">
@@ -129,5 +133,6 @@ async function onSubmit(): Promise<void> {
<template #default="{ row }">{{ fmt(row.statistics?.[k]) }}</template>
</el-table-column>
</el-table>
</el-card>
</el-card>
</div>
</template>
+26 -15
View File
@@ -26,19 +26,30 @@ function pct(): number {
</script>
<template>
<el-card>
<h3>回测进行中</h3>
<p>任务 ID{{ taskId }}</p>
<p>
状态
<el-tag :type="status === 'done' ? 'success' : status === 'failed' ? 'danger' : 'warning'">
{{ status }}
</el-tag>
</p>
<p>阶段{{ stage || '—' }}</p>
<el-progress
:percentage="pct()"
:status="status === 'failed' ? 'exception' : status === 'done' ? 'success' : undefined"
/>
</el-card>
<div class="page">
<div class="page-head">
<div>
<h2 class="page-title">任务进行中</h2>
<p class="page-subtitle">任务 ID{{ taskId }}</p>
</div>
</div>
<el-card>
<p class="progress-status">
状态
<el-tag :type="status === 'done' ? 'success' : status === 'failed' ? 'danger' : 'warning'">
{{ status }}
</el-tag>
</p>
<p class="progress-stage">阶段{{ stage || '—' }}</p>
<el-progress
:percentage="pct()"
:status="status === 'failed' ? 'exception' : status === 'done' ? 'success' : undefined"
/>
</el-card>
</div>
</template>
<style scoped>
.progress-status { margin-bottom: 8px; }
.progress-stage { margin-bottom: 16px; color: var(--text-2); }
</style>
+12 -6
View File
@@ -51,9 +51,15 @@ onMounted(async () => {
</script>
<template>
<div v-loading="loading">
<div v-loading="loading" class="page">
<div class="page-head">
<div>
<h2 class="page-title">回测结果 <span class="muted">{{ taskId }}</span></h2>
<p class="page-subtitle">统计指标 / 资金曲线 / K 线买卖点 / 成交明细</p>
</div>
</div>
<el-card>
<template #header><h3>统计指标</h3></template>
<template #header><span class="section-title">统计指标</span></template>
<el-descriptions :column="4" border>
<el-descriptions-item v-for="e in statEntries" :key="e.key" :label="e.key">
{{ e.value }}
@@ -61,17 +67,17 @@ onMounted(async () => {
</el-descriptions>
</el-card>
<el-row :gutter="16" style="margin-top: 16px">
<el-row :gutter="16">
<el-col :span="12"><el-card><EquityChart :data="equity" /></el-card></el-col>
<el-col :span="12"><el-card><DailyPnlChart :data="pnl" /></el-card></el-col>
</el-row>
<el-card style="margin-top: 16px">
<el-card>
<KlineChart :kline="kline" :trades="trades" />
</el-card>
<el-card style="margin-top: 16px">
<template #header><h3>成交记录</h3></template>
<el-card>
<template #header><span class="section-title">成交记录</span></template>
<TradesTable :trades="trades" />
</el-card>
</div>