feat: 双主题系统 — 编辑风 + 极简亮色

前端:
- 新增 Pinia theme store,localStorage 持久化,data-theme 切换
- App.vue: :root 新增 --font-*/--sidebar-* CSS 变量;新增 :root[data-theme=light] 完整配色(极简黑白金 + Noto Sans SC)
- DesktopLayout: 侧边栏 15 个变量化 + 顶栏主题切换按钮
- MobileLayout: 装饰色变量化
- Settings: 新增「界面主题」卡片
- 21 个组件 font-family 统一替换为 var(--font-*)
- 新增 utils/managerColor.ts — 12 色调色板 + 自适应文字色 + 后端自定义色优先
- WorkPlans/MiniBusiness/KeyVisits/CustomerManage: 客户经理标签色统一走共享工具
- UserManage: 编辑弹窗新增颜色选择器(仅 manager)
- LightBoard: 去标题星标图标
- ManagerWorkspace/WorkPlans/MiniBusiness/KeyVisits: 删除按钮改为实心红底白字

后端:
- User 模型新增 color 列 + lifespan 自动迁移
- users API 支持 color 字段读写
- UserOut schema 新增 color

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-06 16:03:13 +08:00
parent 336b60b3af
commit deeafe239f
37 changed files with 2275 additions and 218 deletions
@@ -302,7 +302,7 @@ const notesByDate = computed(() => {
<el-table-column prop="communication_content" label="沟通内容" min-width="200" show-overflow-tooltip />
<el-table-column label="操作" width="70">
<template #default="{ row }">
<el-button text size="small" type="danger" @click="handleDelete('visit', row.id)">删除</el-button>
<el-button size="small" type="danger" @click="handleDelete('visit', row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
@@ -328,7 +328,7 @@ const notesByDate = computed(() => {
<el-table-column prop="time_range" label="时间" width="100" />
<el-table-column label="操作" width="70">
<template #default="{ row }">
<el-button text size="small" type="danger" @click="handleDelete('note', row.id)">删除</el-button>
<el-button size="small" type="danger" @click="handleDelete('note', row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
@@ -361,7 +361,7 @@ const notesByDate = computed(() => {
</el-table-column>
<el-table-column label="操作" width="70">
<template #default="{ row }">
<el-button text size="small" type="danger" @click="handleDelete('plan', row.id)">删除</el-button>
<el-button size="small" type="danger" @click="handleDelete('plan', row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
@@ -395,7 +395,7 @@ const notesByDate = computed(() => {
<el-table-column prop="expected_revenue_date" label="预计列收" width="110" />
<el-table-column label="操作" width="70">
<template #default="{ row }">
<el-button text size="small" type="danger" @click="handleDelete('mini', row.id)">删除</el-button>
<el-button size="small" type="danger" @click="handleDelete('mini', row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
@@ -430,7 +430,7 @@ const notesByDate = computed(() => {
<el-table-column prop="visit_target" label="拜访对象" width="100" />
<el-table-column label="操作" width="70">
<template #default="{ row }">
<el-button text size="small" type="danger" @click="handleDelete('key', row.id)">删除</el-button>
<el-button size="small" type="danger" @click="handleDelete('key', row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
@@ -534,9 +534,9 @@ const notesByDate = computed(() => {
<style scoped>
.page-head { margin-bottom: 20px; }
.page-title { margin: 0; font-family: 'ZCOOL XiaoWei', STSong, serif; font-size: 22px; font-weight: 400; color: var(--ink); letter-spacing: 0.06em; }
.page-title { margin: 0; font-family: var(--font-heading); font-size: 22px; font-weight: 400; color: var(--ink); letter-spacing: 0.06em; }
.page-rule { width: 32px; height: 3px; background: var(--gold); margin-top: 12px; }
.date-group { margin-bottom: 20px; }
.date-title { display: flex; align-items: center; margin: 12px 0 8px; font-family: 'ZCOOL XiaoWei', STSong, serif; font-size: 14px; color: var(--ink); letter-spacing: 0.04em; }
.empty { text-align: center; color: var(--c-text-muted); padding: 40px 0; font-family: 'Noto Serif SC', STSong, serif; }
.date-title { display: flex; align-items: center; margin: 12px 0 8px; font-family: var(--font-heading); font-size: 14px; color: var(--ink); letter-spacing: 0.04em; }
.empty { text-align: center; color: var(--c-text-muted); padding: 40px 0; font-family: var(--font-body); }
</style>