修复: 前端UX一致性(Dashboard状态映射/状态徽章全局/Knowledge下一条与失败反馈/Ideas筛选与错误条/ConfirmDialog安全/快捷菜单状态机/分页越界) + 后端校验(queue/count-list一致/软删拒改/父聚合/promote CAS/MCP状态机收口/update白名单剔除id/created_at) + 销账

This commit is contained in:
lxy
2026-08-09 21:35:58 +08:00
parent 8bc5380ecb
commit fbd8fae44b
30 changed files with 829 additions and 138 deletions
@@ -58,16 +58,16 @@ function getProjectTaskCount(projectId: string): number {
return store.projectTaskCounts[projectId] ?? 0
}
// 阶段 label key:projectStageInfo 返回的 stage 值(coding/testing/release/planning)
// 阶段 label key:projectStageInfo 返回的 stage 值(coding/testing/release/planning/paused/cancelled)
// 直接拼接 i18n key dashboard.stage.<stage>,与 constants/project.ts PROJECT_STAGE_INFO 单一来源。
// 面板名为"活跃项目",只显示 active 状态(DB 实际默认值,ProjectStatus union 历史遗留未含
// 'active',此处断言绕过;DB 实际无 planning/in_progress 等值产生,详见功能决策记录)。
// 面板名为"活跃项目",按真实生命周期过滤:排除已完结/已取消(后端状态机无 'active',原
// filter status==='active' 恒空,见走查 DBP-1)。
//
// 问题3:按「最近活跃」排序(last_active_at 优先,回退 updated_at),反映业务活跃
// (任务/灵感/状态推进事件)而非元信息修改时间。取前 6 条(completed 归档项目不混入)。
const displayProjects = computed(() =>
store.projects
.filter(p => (p.status as string) === 'active')
.filter(p => p.status !== 'completed' && p.status !== 'cancelled')
.sort((a, b) =>
(b.last_active_at ?? b.updated_at).localeCompare(a.last_active_at ?? a.updated_at)
)
@@ -114,6 +114,8 @@ const displayProjects = computed(() =>
.dot-release { background: var(--df-success); }
.dot-planning { background: var(--df-info); }
.dot-cancelled { background: var(--df-text-dim); }
/* WK-1:paused 置灰(对齐 cancelled dim 档,临时暂停不误标为已取消) */
.dot-paused { background: var(--df-text-dim); }
.project-name {
font-size: 12px;
@@ -135,6 +137,7 @@ const displayProjects = computed(() =>
.chip-release { background: rgba(61,219,160,0.12); color: var(--df-success); }
.chip-planning { background: rgba(94,175,240,0.12); color: var(--df-info); }
.chip-cancelled { background: rgba(255,255,255,0.06); color: var(--df-text-dim); }
.chip-paused { background: rgba(255,255,255,0.06); color: var(--df-text-dim); }
.project-bar-wrap { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.project-bar {
@@ -154,6 +157,7 @@ const displayProjects = computed(() =>
.fill-release { background: var(--df-success); }
.fill-planning { background: var(--df-info); }
.fill-cancelled { background: var(--df-text-dim); }
.fill-paused { background: var(--df-text-dim); }
.project-pct {
font-family: var(--df-font-mono);