重构: 跨模块样式DRY收口+审批列表增强+灵感模块优化

- 全局样式收口: page-header/btn/modal/filter-bar/back-link/empty-state
  等通用类从12个视图的scoped重复定义提取到global.css/components.css
- 审批列表增强: 筛选栏(状态/风险/工具搜索)+行展开查看完整参数结果
  +审批耗时显示+刷新spinner+硬编码颜色全部改用CSS变量
- 灵感模块: scoreTier统一评分阈值+score-bar/assessment-badge提取全局
  +statusLabelKey消除重复+i18n状态文案对齐+eval-report--muted统一空态
- Dashboard: df-panel/df-link提取全局(修scoped不渗透)+统计卡可点击跳转
  +活跃项目面板只显示active状态+灵感列表按分数排序+刷新spinner
- 修复: intent.rs tool_type类型对齐(newtype)+ToolCardList补ai-btn定义
  +SkillMention/ImageInput样式不渗透修复(提取全局)
This commit is contained in:
lxy
2026-07-02 23:24:11 +08:00
parent eee0f06e1a
commit 249b3b9ea8
29 changed files with 691 additions and 925 deletions
+33 -18
View File
@@ -5,10 +5,6 @@
<router-link to="/ideas" class="df-link">{{ $t('dashboard.viewAll') }}</router-link>
</div>
<div class="ideas-stats">
<div class="stat-item">
<span class="stat-num">{{ stats.total }}</span>
<span class="stat-label">{{ $t('ideas.statsTotal') }}</span>
</div>
<div class="stat-item">
<span class="stat-num">{{ stats.pending }}</span>
<span class="stat-label">{{ $t('ideas.statsPending') }}</span>
@@ -23,7 +19,7 @@
</div>
</div>
<div class="idea-rows">
<div v-for="idea in displayIdeas" :key="idea.id" class="idea-row">
<div v-for="idea in displayIdeas" :key="idea.id" class="idea-row clickable" @click="goDetail(idea.id)" :title="t('dashboard.goIdeaDetail')">
<div class="idea-score-ring" :class="'ring-' + idea.tier">
<span class="idea-score-num">{{ idea.score }}</span>
</div>
@@ -39,26 +35,39 @@
<script setup lang="ts">
// 灵感池面板 — 从 Dashboard.vue 抽出(灵感列表 + 评分环 + tier 着色 + 空态)。
// 共享 project store(全局单例),displayIdeas computed 直读 store.ideas(取前 4 条),无需父传 props。
// 共享 project store(全局单例),displayIdeas computed 按分数倒序取前 4 条(精选),无需父传 props。
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { useProjectStore } from '@/stores/project'
import { scoreTier } from '@/utils/ideaEval'
const store = useProjectStore()
const { t } = useI18n()
const router = useRouter()
// 点击灵感行跳转详情(Ideas.vue 同组件路由,会自动选中)
function goDetail(ideaId: string) {
router.push(`/ideas/${ideaId}`)
}
// 精选灵感列表:按分数倒序取前 4 条(高分优先,符合"精选"语义;原来 slice(0,4)
// 无排序会显示最老的 4 条而非高分灵感)。
const displayIdeas = computed(() =>
store.ideas.slice(0, 4).map(i => ({
id: i.id,
title: i.title,
score: i.score ?? 0,
tier: (i.score ?? 0) >= 80 ? 'high' : (i.score ?? 0) >= 60 ? 'mid' : 'low',
statusLabel: i.status,
}))
[...store.ideas]
.sort((a, b) => (b.score ?? 0) - (a.score ?? 0))
.slice(0, 4)
.map(i => ({
id: i.id,
title: i.title,
score: i.score ?? 0,
tier: scoreTier(i.score),
statusLabel: i.status,
}))
)
// 灵感池统计概览 — 4 项关键指标(总数/待审/已晋升/平均分)。
// score 可为 null(未评估),avgScore 仅对已评估灵感求均值,无则显示 '—'。
// 灵感池细分统计(顶部 StatCardRow 已显示总数,此处仅展示待审/已晋升/平均分 3 项细分,
// 删除重复的 total 避免与顶部统计卡信息冗余)。
const stats = computed(() => {
const ideas = store.ideas
const scored = ideas.filter(i => i.score != null)
@@ -66,7 +75,6 @@ const stats = computed(() => {
? Math.round(scored.reduce((sum, i) => sum + (i.score ?? 0), 0) / scored.length)
: null
return {
total: ideas.length,
pending: ideas.filter(i => i.status === 'draft' || i.status === 'pending_review').length,
promoted: ideas.filter(i => i.status === 'promoted').length,
avgScore: avg == null ? '—' : avg,
@@ -79,10 +87,10 @@ function ideaStatusLabel(status: string): string {
</script>
<style scoped>
/* 仅迁入灵感行自身样式;df-panel/df-link 等通用面板类留 Dashboard.vue(多面板共享) */
/* df-panel/df-link 通用面板类已提取到 styles/components.css 全局 */
.ideas-stats {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-columns: repeat(3, 1fr);
gap: 8px;
margin-bottom: 12px;
}
@@ -117,6 +125,13 @@ function ideaStatusLabel(status: string): string {
padding: 7px 0;
border-bottom: 0.5px solid var(--df-border);
}
.idea-row.clickable {
cursor: pointer;
transition: background 0.15s var(--df-ease);
}
.idea-row.clickable:hover {
background: var(--df-bg);
}
.idea-row:last-child { border-bottom: none; }
.idea-score-ring {