From b42cc66e7aabdefb90984b41807c847533cf324b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BB=9D=E5=B0=98?= <237809796@qq.com> Date: Fri, 19 Jun 2026 12:38:20 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84:=20P0-4=20IdeaRecord.status?= =?UTF-8?q?=20union=E7=B1=BB=E5=9E=8B=E5=8C=96(=E8=AF=95=E7=82=B9=C2=B7?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=AE=89=E5=85=A8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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待推广 --- src/api/types.ts | 6 +++++- src/components/ideas/IdeaDetail.vue | 10 +++++----- src/views/Ideas.vue | 7 ++++--- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/api/types.ts b/src/api/types.ts index a1f783c..4d56118 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -4,11 +4,15 @@ // 灵感 // ============================================================ +// IdeaRecord.status union 类型 — 值集对齐后端 IdeaStatus serde (df-types/src/types.rs:52) +// snake_case: draft | pending_review | approved | rejected | promoted | archived +export type IdeaStatus = 'draft' | 'pending_review' | 'approved' | 'rejected' | 'promoted' | 'archived' + export interface IdeaRecord { id: string title: string description: string - status: string // draft | pending_review | approved | rejected | promoted | archived + status: IdeaStatus priority: number score: number | null tags: string | null // JSON 数组字符串 diff --git a/src/components/ideas/IdeaDetail.vue b/src/components/ideas/IdeaDetail.vue index 52d55fc..3cb40aa 100644 --- a/src/components/ideas/IdeaDetail.vue +++ b/src/components/ideas/IdeaDetail.vue @@ -130,7 +130,7 @@ import { computed } from 'vue' import { useI18n } from 'vue-i18n' import { parseTags } from '../../stores/knowledge' import { useRendered } from '../../composables/useMarkdown' -import type { IdeaRecord } from '../../api/types' +import type { IdeaRecord, IdeaStatus } from '../../api/types' const props = defineProps<{ idea: IdeaRecord @@ -138,20 +138,20 @@ const props = defineProps<{ evalError: string promoting: boolean deleting: boolean - statusOptions: { value: string; labelKey: string }[] + statusOptions: { value: IdeaStatus; labelKey: string }[] }>() const emit = defineEmits<{ (e: 'evaluate'): void (e: 'promote'): void (e: 'delete'): void - (e: 'status-change', value: string): void + (e: 'status-change', value: IdeaStatus): void }>() const { t } = useI18n() // 任意 status 字符串 → 对应 i18n key;未知状态回退到原值显示 -function statusLabelKey(status: string): string { +function statusLabelKey(status: IdeaStatus): string { return props.statusOptions.find(s => s.value === status)?.labelKey ?? status } @@ -230,7 +230,7 @@ function sentimentClass(sentiment: number) { } function onStatusChange(e: Event) { - emit('status-change', (e.target as HTMLSelectElement).value) + emit('status-change', (e.target as HTMLSelectElement).value as IdeaStatus) } diff --git a/src/views/Ideas.vue b/src/views/Ideas.vue index b2b27f2..90e8d80 100644 --- a/src/views/Ideas.vue +++ b/src/views/Ideas.vue @@ -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) }