126 lines
4.8 KiB
TypeScript
126 lines
4.8 KiB
TypeScript
//! 项目 & 任务状态映射常量
|
||
//!
|
||
//! 统一各视图(Projects/ProjectDetail/Tasks/Dashboard)的 label / badge / 阶段进度,
|
||
//! 根治此前三套状态映射互相矛盾、任务文案两处不一致的问题。
|
||
|
||
// ── 项目状态 ──
|
||
|
||
// 值为 i18n key,实际文案走 $t('projects.status.<key>')(见 src/i18n/{zh-CN,en}/projects.ts)
|
||
// F-09 对齐:删 in_progress/paused/cancelled(project 维度无数据产生源、无 UI 入口、无消费方),
|
||
// 保留与后端真实生命周期一致的最小集(planning 常态 + 软删 deleted_at 由 list_deleted 单独处理)。
|
||
export const PROJECT_STATUS_LABELS: Record<string, string> = {
|
||
planning: 'projects.status.planning',
|
||
active: 'projects.status.active',
|
||
completed: 'projects.status.completed',
|
||
}
|
||
|
||
/** 项目状态 → 卡片 badge 样式 class */
|
||
export const PROJECT_STATUS_BADGE_CLASS: Record<string, string> = {
|
||
planning: 'stage-design',
|
||
active: 'stage-coding',
|
||
completed: 'stage-release',
|
||
}
|
||
|
||
/** 项目状态 → 阶段/进度信息(详情页 pipeline + Dashboard 进度条共用) */
|
||
export interface ProjectStageInfo {
|
||
/** pipeline 步骤索引 0-4: idea/requirement/coding/testing/release */
|
||
stepIndex: number
|
||
/** 进度百分比 */
|
||
progress: number
|
||
/** Dashboard dot/chip 颜色档: coding/testing/release */
|
||
stage: string
|
||
}
|
||
|
||
export const PROJECT_STAGE_INFO: Record<string, ProjectStageInfo> = {
|
||
planning: { stepIndex: 0, progress: 20, stage: 'planning' },
|
||
active: { stepIndex: 2, progress: 55, stage: 'coding' },
|
||
completed: { stepIndex: 4, progress: 100, stage: 'release' },
|
||
}
|
||
|
||
export function projectStatusLabel(status: string): string {
|
||
return PROJECT_STATUS_LABELS[status] ?? status
|
||
}
|
||
|
||
export function projectBadgeClass(status: string): string {
|
||
return PROJECT_STATUS_BADGE_CLASS[status] ?? 'stage-design'
|
||
}
|
||
|
||
export function projectStageInfo(status: string): ProjectStageInfo {
|
||
// F-09:兜底用字面量而非 PROJECT_STAGE_INFO.planning,避免已删键的隐式依赖
|
||
return PROJECT_STAGE_INFO[status] ?? { stepIndex: 0, progress: 0, stage: 'planning' }
|
||
}
|
||
|
||
// ── 任务状态 ──
|
||
|
||
// D-260616-01:前端对齐后端 7 态纯状态机(crates/df-core/src/types.rs TaskStatus)
|
||
// 删旧 5 态 Git 工作流导向(review_ready/merged/abandoned)。
|
||
// 后端 task.rs update_task 写 status 经 TaskStatus::is_valid 拦截,旧 5 态无法落库;
|
||
// migrations.rs V1 无 seed,create_task 默认 todo → 新 DB 无旧 5 态数据,安全对齐。
|
||
//
|
||
// 值为 i18n key,实际文案走 $t('tasks.status.<key>')(见 src/i18n/{zh-CN,en}/tasks.ts)
|
||
export const TASK_STATUS_LABELS: Record<string, string> = {
|
||
todo: 'tasks.status.todo',
|
||
in_progress: 'tasks.status.in_progress',
|
||
in_review: 'tasks.status.in_review',
|
||
testing: 'tasks.status.testing',
|
||
done: 'tasks.status.done',
|
||
blocked: 'tasks.status.blocked',
|
||
cancelled: 'tasks.status.cancelled',
|
||
}
|
||
|
||
// class 名对齐既有 css(Tasks/TaskDetail/ProjectDetail 均有 status-todo/progress/review/done/abandoned):
|
||
// - todo/in_progress/in_review/done 复用既有 class(保持跨视图样式一致,不破坏指派外文件)
|
||
// - cancelled 复用 status-abandoned(同为 danger 红色,语义一致)
|
||
// - testing/blocked 新增(Tasks.vue 自身样式补充;TaskDetail/ProjectDetail 遇此值兜底 status-todo 灰色,
|
||
// 非破坏——仅样式保守,文案经 $t 正常渲染)
|
||
export const TASK_STATUS_CLASS: Record<string, string> = {
|
||
todo: 'status-todo',
|
||
in_progress: 'status-progress',
|
||
in_review: 'status-review',
|
||
testing: 'status-testing',
|
||
done: 'status-done',
|
||
blocked: 'status-blocked',
|
||
cancelled: 'status-abandoned',
|
||
}
|
||
|
||
// D-260616-01 删旧 5 态前的老 DB 数据兼容映射(老 DB 可能存 completed/review_ready/merged/abandoned)
|
||
// 新 DB 经 TaskStatus::is_valid 拦截不会有,但老 DB 未迁移清理时兜底显示而非 $t() 报错
|
||
const LEGACY_STATUS_MAP: Record<string, string> = {
|
||
completed: 'done',
|
||
review_ready: 'in_review',
|
||
merged: 'done',
|
||
abandoned: 'cancelled',
|
||
}
|
||
|
||
/** 老DB 旧态映射(completed→done / review_ready→in_review 等),新 DB 无此数据 */
|
||
function mapLegacyStatus(status: string): string {
|
||
return LEGACY_STATUS_MAP[status] ?? status
|
||
}
|
||
|
||
export function taskStatusLabel(status: string): string {
|
||
return TASK_STATUS_LABELS[mapLegacyStatus(status)] ?? 'tasks.status.todo'
|
||
}
|
||
|
||
export function taskStatusClass(status: string): string {
|
||
return TASK_STATUS_CLASS[mapLegacyStatus(status)] ?? 'status-todo'
|
||
}
|
||
|
||
// ── 任务优先级 ──
|
||
|
||
export const PRIORITY_LABELS: Record<number, string> = { 0: 'P0', 1: 'P1', 2: 'P2', 3: 'P3' }
|
||
|
||
export const PRIORITY_CLASSES: Record<number, string> = {
|
||
0: 'priority-critical',
|
||
1: 'priority-high',
|
||
2: 'priority-medium',
|
||
3: 'priority-low',
|
||
}
|
||
|
||
export function priorityLabel(p: number): string {
|
||
return PRIORITY_LABELS[p] ?? `P${p}`
|
||
}
|
||
|
||
export function priorityClass(p: number): string {
|
||
return PRIORITY_CLASSES[p] ?? 'priority-low'
|
||
}
|