From 45ecb4e9dfe225bc982e9af9315590bcb0783df7 Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Fri, 18 Sep 2026 08:26:57 +0800 Subject: feat(frontend): 结果/实验/策略/数据页迁移 shadcn 与新 Chart API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [变更性质] 四个业务标签页与数据集卡片迁移 shadcn 组件,图表消费切换到 layerchart 长格式 API,功能与数据语义不变。 [新增功能] 结果页权益曲线(策略权益/现金/基准,基准可缺省)与回撤曲线(desc 面积)改由 Chart.svelte data/series 渲染;实验记录页多回测归一对比 曲线改为快速长格式行构造。空数据行允许 undefined 列(基准缺口), Chart data 类型放宽 [key:string]: string|number|undefined。 [实现方案] RunsPage:查看入口改 shadcn Button(href 语义保留 hash 路由), 对比图数据由 compareOption(echarts option)化为 compare。 ProjectResultsTab:图表开关、日志折叠用 Button;equityData/ drawdownData $derived 计算峰值回撤。ProjectStrategyTab:快照输入、 冲突/AI/版本操作迁移 Button/Input。ProjectDataTab 与 DatasetCard: shadcn 组件 + 保留 banner error/warn/info、retry-row 等 legacy class, "使用相同请求重新获取"重试入口与 onRecreated 逻辑不变,配套 datasetCardRetry/datasetCardWarnings/projectDataTabRecreated 回归 测试。resultsAccounting.test.ts:layerchart 在 jsdom 挂载约 3 秒, suite 全量下易撞默认 5s 超时,首测提高至 20s。 [影响范围] npm run check 0 error、58 tests 全绿、npm run build 通过;真浏览器 375/768/1440 图表页零溢出(artifacts/ui-shadcn 截图与探针 JSON)。 --- frontend/src/components/DatasetCard.svelte | 169 ++++++++++++++++++++++------- 1 file changed, 128 insertions(+), 41 deletions(-) (limited to 'frontend/src/components/DatasetCard.svelte') diff --git a/frontend/src/components/DatasetCard.svelte b/frontend/src/components/DatasetCard.svelte index 7b38874..2d49e65 100644 --- a/frontend/src/components/DatasetCard.svelte +++ b/frontend/src/components/DatasetCard.svelte @@ -1,15 +1,24 @@ -
+ {#if ds}
-
+
{ds.name ?? '未命名数据集'} {#if ds.manifest_hash}manifest {ds.manifest_hash.slice(0, 10)}…{/if} - {#if ds.cache_hit}缓存命中 · 复用现有物化对象{/if} + {#if ds.cache_hit}缓存命中 · 复用现有物化对象{/if}
- + {datasetStatusLabel[ds.status]} - + +
+
+ + + + 请求标的 + {(ds.request.instruments ?? []).map(instrumentLabel).join(';')} + + + 范围 + {ds.request.start_date} ~ {ds.request.end_date} · {ds.request.frequency} · {adjustmentLabel[ds.request.adjustment] ?? ds.request.adjustment} + + + 字段 + {(ds.request.fields ?? []).join(', ')} + + + 创建时间 + {fmtDate(ds.created_at)} + + +
- - - - - - - -
请求标的{(ds.request.instruments ?? []).map(instrumentLabel).join(';')}
范围{ds.request.start_date} ~ {ds.request.end_date} · {ds.request.frequency} · {adjustmentLabel[ds.request.adjustment] ?? ds.request.adjustment}
字段{(ds.request.fields ?? []).join(', ')}
创建时间{fmtDate(ds.created_at)}
{#if ds.status === 'failed'} - {/if} - {#if ds.status !== 'ready'} -

{ds.status === 'pending' || ds.status === 'running' ? '获取中,完成后可预览覆盖情况' : ''}

+
+ + {#if recreatedId} + + 已用原请求创建新数据集(编号 {recreatedId.slice(0, 8)}…),新数据集出现在下方列表并自动跟踪进度;本条失败记录原样保留。 + + {/if} + {#if recreateErr}{recreateErr}{/if} +
{/if} {#if ds.status === 'ready'}
- +
{#if showPreview}
@@ -111,30 +186,40 @@
    {#each cov.warnings as w, i (i)}
  • {w}
  • {/each}
- {#if (preview.coverage ?? []).some((c) => c.warnings)} -
    - {#each preview.coverage.filter((c) => c.warnings) as c (c.instrument)} -
  • {c.instrument}:{(c.warnings ?? []).join(';')}
  • - {/each} -
- {/if}
- {:else if cov.common.start} + {/if} + {#if (preview.coverage ?? []).some((c) => (c.warnings ?? []).length > 0)} + + {/if} + {#if cov.common.start && cov.warnings.length === 0} {/if} - - - {#each preview.columns as c (c)}{/each} - - - {#each preview.rows as row, i (i)} - {#each preview.columns as c (c)}{/each} - {/each} - -
{c}
{row[c]}
+
+ + + + {#each preview.columns as c (c)}{c}{/each} + + + + {#each preview.rows as row, i (i)} + + {#each preview.columns as c (c)}{row[c]}{/each} + + {/each} + + +
{#if preview.truncated}

预览仅展示部分行

{/if} @@ -145,13 +230,15 @@ {:else} {/if} -
+ -- cgit v1.2.3