重构: P0-4 IdeaRecord.status union类型化(试点·类型安全)

- types.ts: 新增 IdeaStatus union(draft|pending_review|approved|rejected|promoted|archived, 对齐后端df-types IdeaStatus serde snake_case) + IdeaRecord.status string→IdeaStatus
- Ideas.vue/IdeaDetail.vue/IdeasPanel.vue: statusOptions/statusLabelKey/onStatusChange/emit收窄 类型IdeaStatus(编译期校验拼写错)
- stores/project.ts/state.ts: 比较 IdeaStatus
后端契约: union 6值=df-types IdeaStatus serde, IPC/DB不变零行为变更
P0-4试点跑通: 推广路径验证(union+父子类型传递+emit收窄); 剩余TaskRecord/AiToolCallInfo/WorkflowRecord/ProjectRecord status待推广
This commit is contained in:
2026-06-19 12:38:20 +08:00
parent b237f716dd
commit b42cc66e7a
3 changed files with 14 additions and 9 deletions

View File

@@ -111,6 +111,7 @@ import { useRouter, useRoute } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { Message } from '@arco-design/web-vue'
import { useProjectStore } from '../stores/project'
import type { IdeaStatus } from '../api/types'
import { parseTags } from '../stores/knowledge'
import { formatDate } from '../utils/time'
import { stripMd } from '../utils/markdown'
@@ -150,7 +151,7 @@ const filters: { key: FilterKey; labelKey: string; icon: string }[] = [
]
// ── 状态映射(单一数据源,列表/详情/下拉共用) ──
const statusOptions: { value: string; labelKey: string }[] = [
const statusOptions: { value: IdeaStatus; labelKey: string }[] = [
{ value: 'draft', labelKey: 'ideas.status.draft' },
{ value: 'pending_review', labelKey: 'ideas.status.pending_review' },
{ value: 'approved', labelKey: 'ideas.status.approved' },
@@ -159,7 +160,7 @@ const statusOptions: { value: string; labelKey: string }[] = [
]
// 任意 status 字符串 → 对应 i18n key;未知状态回退到原值显示
function statusLabelKey(status: string): string {
function statusLabelKey(status: IdeaStatus): string {
return statusOptions.find(s => s.value === status)?.labelKey ?? status
}
@@ -272,7 +273,7 @@ async function evaluateCurrentIdea() {
}
}
async function onStatusChange(newStatus: string) {
async function onStatusChange(newStatus: IdeaStatus) {
if (!currentIdea.value) return
await store.updateIdea(currentIdea.value.id, 'status', newStatus)
}