diff --git a/frontend/web/src/pages/Home.tsx b/frontend/web/src/pages/Home.tsx
index f5e955b..fd9a3c2 100644
--- a/frontend/web/src/pages/Home.tsx
+++ b/frontend/web/src/pages/Home.tsx
@@ -216,6 +216,11 @@ function RecentRunRow({ run, onOpen }: { run: Run; onOpen: () => void }) {
{run.scenario_name || run.scenario_id.slice(0, 8)}
· {run.target_name || run.target_id.slice(0, 8)}
+ {run.scenario_version != null && (
+
+ v{run.scenario_version}
+
+ )}
{trigger !== 'manual' && (
{triggerLabels[trigger] ?? trigger}
diff --git a/frontend/web/src/pages/Reports.tsx b/frontend/web/src/pages/Reports.tsx
index 8c563e4..25d2d94 100644
--- a/frontend/web/src/pages/Reports.tsx
+++ b/frontend/web/src/pages/Reports.tsx
@@ -159,15 +159,26 @@ export default function ReportsPage() {
clearSelection()
}
- // 场景筛选项:从 run 列表聚合(含各场景 run 数量)
+ // 场景筛选项:从 run 列表聚合(含各场景 run 数量与出现过的考纲版本)
const scenarioOptions = useMemo(() => {
- const map = new Map()
+ const map = new Map }>()
for (const r of runs) {
const entry = map.get(r.scenario_id)
- if (entry) entry.count += 1
- else map.set(r.scenario_id, { name: r.scenario_name || r.scenario_id.slice(0, 8), count: 1 })
+ if (entry) {
+ entry.count += 1
+ entry.versions.add(r.scenario_version ?? 1)
+ } else {
+ map.set(r.scenario_id, {
+ name: r.scenario_name || r.scenario_id.slice(0, 8),
+ count: 1,
+ versions: new Set([r.scenario_version ?? 1]),
+ })
+ }
}
- return [...map.entries()].map(([id, s]) => ({ value: id, label: `${s.name}(${s.count})` }))
+ return [...map.entries()].map(([id, s]) => {
+ const versions = [...s.versions].sort((a, b) => a - b).map((v) => `v${v}`).join('/')
+ return { value: id, label: `${s.name}(${s.count} · ${versions})` }
+ })
}, [runs])
const filteredRuns = useMemo(
@@ -179,15 +190,17 @@ export default function ReportsPage() {
const passRate = (r.summary as Record)?.pass_rate as number | undefined
const pct = passRate != null ? `${Math.round(passRate * 100)}%` : '-'
const scenario = r.scenario_name || r.scenario_id.slice(0, 8)
+ const version = `v${r.scenario_version ?? 1}`
const target = r.target_name || r.target_id.slice(0, 8)
const time = r.started_at ? formatDateTime(r.started_at) : ''
const trigger = r.triggered_by ?? 'manual'
return {
value: r.id,
- searchText: `${scenario} ${target} ${time} ${r.id} ${triggerLabels[trigger] ?? trigger}`.toLowerCase(),
+ searchText: `${scenario} ${version} ${target} ${time} ${r.id} ${triggerLabels[trigger] ?? trigger}`.toLowerCase(),
label: (
{scenario}
+ {version}
· {target}
{time}
(opt?.label as string ?? '').toLowerCase().includes(input.toLowerCase())}
placeholder="选择评测场景"
- options={scenarios.map((s) => ({ label: s.name, value: s.id }))}
+ options={scenarios.map((s) => ({ label: `${s.name}(v${s.version ?? 1})`, value: s.id }))}
style={{ flex: 1 }}
size="middle"
/>
diff --git a/frontend/web/src/pages/Scenarios.tsx b/frontend/web/src/pages/Scenarios.tsx
index 9d4f665..e242d85 100644
--- a/frontend/web/src/pages/Scenarios.tsx
+++ b/frontend/web/src/pages/Scenarios.tsx
@@ -248,7 +248,7 @@ export default function ScenariosPage() {
setDrawerOpen(false)}
width={720}
@@ -329,7 +329,7 @@ export default function ScenariosPage() {
setPreviewOpen(false)}
footer={null}