修复: 前端UI审查问题(项目状态badge+confirm替换+加载态+CSS修正)

- ProjectDetail: 加载态/不存在态 + stage badge CSS 类名修正(7个实际状态)

- Tasks: confirm()替换为useConfirm + 死代码清理 + priority CSS去重

- Knowledge: 列表加载态

- Projects: CSS变量名拼写修正(--df-mono→--df-font-mono)

- EmptyState: opacity从容器移到图标(对比度修复)

- Ideas: 5处内联style替换为modal-field class

- ProjectDetail: 删除注释stages死代码
This commit is contained in:
2026-07-02 12:12:29 +08:00
parent acf0ed091d
commit c3b47b5771
8 changed files with 63 additions and 51 deletions

View File

@@ -1,11 +1,20 @@
<template>
<div class="project-detail">
<!-- 加载态 -->
<div v-if="loading" class="loading-state">{{ $t('common.loading') }}</div>
<!-- 项目不存在 -->
<div v-else-if="!currentProject" class="empty-state">
<p>{{ $t('projectDetail.notFound') }}</p>
<router-link to="/projects" class="btn btn-primary">{{ $t('projectDetail.backToList') }}</router-link>
</div>
<!-- 项目详情 -->
<template v-else>
<!-- 页面头部 -->
<header class="page-header">
<div class="header-left">
<router-link to="/projects" class="back-link">{{ $t('projectDetail.backToList') }}</router-link>
<h1>{{ currentProject?.name ?? '...' }}</h1>
<span class="stage-badge" :class="'stage-' + stageKey">{{ $t(statusLabel) }}</span>
<h1>{{ currentProject.name }}</h1>
<span v-if="statusLabel" class="stage-badge" :class="'stage-' + stageKey">{{ $t(statusLabel) }}</span>
</div>
<div class="header-actions">
<button class="btn btn-ghost" @click="handleSync">{{ $t('projectDetail.sync') }}</button>
@@ -253,6 +262,7 @@
<!-- 确认弹层删除/重定位确认替代原生 window.confirm/alert -->
<ConfirmDialog :visible="confirmState.visible" :msg="confirmState.msg" @result="answerConfirm" />
</template>
</div>
</template>
@@ -290,14 +300,7 @@ const activeTab = ref<'overview' | 'files' | 'graph'>('overview')
// 确认弹层状态机抽至 composables/useConfirm(原 4 视图重复:Projects/ProjectDetail/Ideas/Settings)
const { confirmState, confirmDialog, answerConfirm } = useConfirm()
// ── 阶段定义(暂时隐藏,阶段进度条模板已注释,后续接入真实状态机后启用) ──
// const stages = [
// { key: 'idea', labelKey: 'stageIdea' },
// { key: 'requirement', labelKey: 'stageRequirement' },
// { key: 'coding', labelKey: 'stageCoding' },
// { key: 'testing', labelKey: 'stageTesting' },
// { key: 'release', labelKey: 'stageRelease' },
// ]
// ── 当前项目 ──
// 状态文案/阶段进度统一走 ../constants/project(与 Projects/Tasks/Dashboard 一致,
@@ -306,6 +309,7 @@ const projectId = computed(() => route.params.id as string)
const currentProject = computed(() =>
store.projects.find(p => p.id === projectId.value)
)
const loading = computed(() => store.projects.length === 0 && !store.error)
// 状态文案/阶段进度统一走 ../constants/project
// B-260615-25:项目描述 Markdown 渲染(复用 AiChat/TaskDetail 同款渲染器,模块级单例),
@@ -553,6 +557,10 @@ onUnmounted(() => {
<style scoped>
/* ... 现有样式 ... */
/* 加载/空态(模板顶部使用) */
.loading-state { text-align: center; padding: 40px; color: var(--df-text-dim); }
.empty-state { text-align: center; padding: 40px; display: flex; flex-direction: column; align-items: center; gap: 12px; }
/* ===== 项目信息样式 ===== */
.project-info {
display: flex;
@@ -736,11 +744,13 @@ onUnmounted(() => {
border-radius: var(--df-radius-lg);
font-weight: 500;
}
.stage-idea { background: rgba(100,181,246,0.15); color: var(--df-info); }
.stage-requirement { background: rgba(255,217,61,0.15); color: var(--df-warning); }
.stage-coding { background: rgba(108,99,255,0.15); color: var(--df-accent); }
.stage-testing { background: rgba(100,255,218,0.15); color: var(--df-success); }
.stage-release { background: rgba(255,107,107,0.15); color: #ff9800; }
.stage-planning { background: rgba(100,181,246,0.15); color: #64b5f6; }
.stage-in_progress { background: rgba(108,99,255,0.15); color: #6c63ff; }
.stage-testing { background: rgba(255,193,7,0.15); color: #ffc107; }
.stage-releasing { background: rgba(156,39,176,0.15); color: #ce93d8; }
.stage-completed { background: rgba(100,200,100,0.15); color: #64c864; }
.stage-paused { background: rgba(158,158,158,0.15); color: #9e9e9e; }
.stage-cancelled { background: rgba(244,67,54,0.15); color: #f44336; }
.header-actions { display: flex; gap: 10px; }