## 4. 五套登录后主题设计方案 为满足不同用户群体在不同使用场景下的视觉偏好,本章为 SQL-Platform 设计五套完整的登录后主题方案。每套主题均包含完整的 CSS 变量规范、色彩心理学依据及典型应用场景说明。五套主题涵盖从专业沉稳到活力温暖的全方位视觉谱系,确保平台在各类企业环境中都能提供最佳的用户体验。 --- ### 4.1 主题一「深蓝专业」— 默认深色增强版 **设计定位**:深蓝专业主题是在现有深色主题基础上的全面增强版本,定位为平台的默认主题。设计目标是在保持深色模式优势(降低眼部疲劳、突出内容)的同时,通过更纯正深邃的蓝色调提升整体品质感,并强化视觉层次与可读性。 **色彩设计理念**:该主题摒弃了原主题中偏灰的杂色倾向,将背景色收敛到更纯正的深蓝谱系。主背景色 `#070d19` 接近纯黑但带有微弱的蓝色相,营造出深邃而稳定的基底。次背景色 `#0f172a` 参考了 Slate 色板中最深沉的蓝色调,既保证了与主背景的层次区分,又维持了蓝色谱系的纯粹性。文字色彩采用 `#f8fafc`(极亮蓝白)作为主文字色,相比纯白色更具温润感,长时间阅读不易产生刺眼感。次文字色 `#94a3b8` 提供了充分的对比度,确保辅助信息的可读性。 **强调色体系**:蓝色系强调色选用 `#3b82f6`(Tailwind Blue 500),这是一个饱和度适中、辨识度高的蓝色,在深色背景上呈现明亮但不刺眼的视觉效果。状态色(成功、错误、警告)均经过深色背景适配,确保各色彩在深蓝底上都有足够的明度对比。 **适用场景**:作为默认主题,适用于绝大多数使用场景,特别适合技术团队日常操作、数据库管理、权限配置等需要长时间专注的工作界面。 ```css /* === 主题一:深蓝专业 ocean-deep === */ [data-theme="ocean-deep"] { /* shadcn/ui 基础变量 */ --background: 222 47% 4%; --foreground: 210 40% 98%; --card: 222 47% 7%; --card-foreground: 210 40% 98%; --popover: 222 47% 7%; --popover-foreground: 210 40% 98%; --primary: 217 91% 60%; --primary-foreground: 0 0% 100%; --secondary: 217 33% 17%; --secondary-foreground: 210 40% 98%; --muted: 217 33% 17%; --muted-foreground: 215 20% 65%; --accent: 217 33% 17%; --accent-foreground: 210 40% 98%; --destructive: 0 84% 60%; --destructive-foreground: 0 0% 100%; --border: 217 33% 17%; --input: 217 33% 17%; --ring: 217 91% 60%; --radius: 0.5rem; /* DataGuard 自定义变量 */ --dg-bg-primary: #070d19; --dg-bg-secondary: #0f172a; --dg-bg-tertiary: #172033; --dg-bg-hover: #233049; --dg-border: #1e293b; --dg-border-light: #172033; --dg-text-primary: #f8fafc; --dg-text-secondary: #94a3b8; --dg-text-muted: #64748b; --dg-blue: #3b82f6; --dg-green: #22c55e; --dg-red: #ef4444; --dg-orange: #f97316; --dg-purple: #8b5cf6; --dg-cyan: #06b6d4; --dg-yellow: #eab308; --dg-gradient-start: #3b82f6; --dg-gradient-end: #2563eb; } ``` --- ### 4.2 主题二「浅色商务」— 企业办公风 **设计定位**:浅色商务主题面向白天办公环境优化,采用温暖的灰白色调替代常见的冷白背景,营造舒适、专业且不刺眼的工作界面。该主题适合不习惯深色模式的用户,或在明亮办公室环境中使用。 **色彩设计理念**:背景色摒弃了纯白的冷峻感,主背景色 `#fafaf9` 选用带有微弱暖色相的" zinc white",在显示器上呈现柔和的纸质感。次背景色 `#f5f5f4` 和三级背景色 `#e7e5e4` 构成自然的层次递进,避免了传统浅色主题中背景层次过于平淡的问题。边框色 `#d6d3d1` 同样带有暖色调,使界面分割更加自然和谐。文字色彩方面,主文字色 `#1c1917` 是带有微弱棕色相的深黑色,相比纯黑在暖白背景上对比度更舒适,避免了"黑字白纸"的刺眼感。 **强调色体系**:强调色选用稳重的 `#2563eb`(Tailwind Blue 600),这是一个偏深的标准蓝色,传达专业、可信赖的企业形象。状态色均调整为适合浅色背景的版本,成功绿 `#16a34a`、错误红 `#dc2626`、警告橙 `#ca8a04` 在浅色背景上均保持良好的可读性。 **适用场景**:适合白天办公环境、管理人员日常审批查看、客户演示投屏等场景。浅色界面在投影设备上的显示效果通常优于深色界面,因此该主题也是会议室演示的首选。 ```css /* === 主题二:浅色商务 light-professional === */ [data-theme="light-professional"] { /* shadcn/ui 基础变量 */ --background: 40 9% 98%; --foreground: 24 10% 10%; --card: 40 9% 96%; --card-foreground: 24 10% 10%; --popover: 40 9% 96%; --popover-foreground: 24 10% 10%; --primary: 221 83% 53%; --primary-foreground: 0 0% 100%; --secondary: 40 6% 90%; --secondary-foreground: 24 10% 10%; --muted: 40 6% 90%; --muted-foreground: 25 5% 45%; --accent: 40 6% 90%; --accent-foreground: 24 10% 10%; --destructive: 0 72% 51%; --destructive-foreground: 0 0% 100%; --border: 24 6% 83%; --input: 24 6% 83%; --ring: 221 83% 53%; --radius: 0.5rem; /* DataGuard 自定义变量 */ --dg-bg-primary: #fafaf9; --dg-bg-secondary: #f5f5f4; --dg-bg-tertiary: #e7e5e4; --dg-bg-hover: #d6d3d1; --dg-border: #d6d3d1; --dg-border-light: #e7e5e4; --dg-text-primary: #1c1917; --dg-text-secondary: #78716c; --dg-text-muted: #a8a29e; --dg-blue: #2563eb; --dg-green: #16a34a; --dg-red: #dc2626; --dg-orange: #ea580c; --dg-purple: #7c3aed; --dg-cyan: #0891b2; --dg-yellow: #ca8a04; --dg-gradient-start: #2563eb; --dg-gradient-end: #4f46e5; } ``` --- ### 4.3 主题三「午夜紫韵」— 高端紫色调 **设计定位**:午夜紫韵主题以深紫黑色为基底,搭配明亮的紫色渐变强调色,营造高端、神秘且富有科技感的视觉氛围。该主题适合作为给客户演示时的展示主题,能够传达产品的技术领先性和品质感。 **色彩设计理念**:主背景色 `#0a0612` 是带有明显紫色相的极深色,接近"午夜黑"的概念,为整个界面奠定了神秘而高贵的基调。次背景色 `#130c21` 和三级背景色 `#1c1330` 沿紫色谱系逐步提亮,形成清晰的层次结构。悬停背景色 `#2d1f4a` 是一个中等深度的紫色,在交互时能够产生明显的视觉反馈,同时保持整体色调的一致性。文字色彩方面,主文字色 `#faf5ff` 带有微弱的紫色调,使文字在深色背景上更加柔和雅致。 **强调色体系**:该主题的核心亮点在于紫色渐变强调体系。渐变起点 `#9333ea`(Tailwind Purple 600)到渐变终点 `#c084fc`(Tailwind Purple 400)构成了一段明亮且富有活力的紫色渐变,用于品牌标识、主要按钮和重要数据高亮。蓝色调整为偏紫的靛蓝色 `#818cf8`,绿色调整为翠绿色 `#34d399`,红色调整为玫红色 `#fb7185`,所有状态色都经过紫色调环境的协调适配。 **适用场景**:产品发布会演示、客户汇报展示、高端企业部署、技术峰会展台等需要彰显产品品质的正式场合。 ```css /* === 主题三:午夜紫韵 midnight-purple === */ [data-theme="midnight-purple"] { /* shadcn/ui 基础变量 */ --background: 264 56% 4%; --foreground: 280 100% 98%; --card: 264 48% 8%; --card-foreground: 280 100% 98%; --popover: 264 48% 8%; --popover-foreground: 280 100% 98%; --primary: 270 91% 65%; --primary-foreground: 0 0% 100%; --secondary: 264 40% 20%; --secondary-foreground: 280 100% 98%; --muted: 264 40% 20%; --muted-foreground: 280 30% 60%; --accent: 264 40% 20%; --accent-foreground: 280 100% 98%; --destructive: 348 100% 72%; --destructive-foreground: 264 56% 4%; --border: 264 40% 20%; --input: 264 40% 20%; --ring: 270 91% 65%; --radius: 0.5rem; /* DataGuard 自定义变量 */ --dg-bg-primary: #0a0612; --dg-bg-secondary: #130c21; --dg-bg-tertiary: #1c1330; --dg-bg-hover: #2d1f4a; --dg-border: #2d1f4a; --dg-border-light: #1c1330; --dg-text-primary: #faf5ff; --dg-text-secondary: #b794c7; --dg-text-muted: #7c5a8a; --dg-blue: #818cf8; --dg-green: #34d399; --dg-red: #fb7185; --dg-orange: #fb923c; --dg-purple: #c084fc; --dg-cyan: #22d3ee; --dg-yellow: #facc15; --dg-gradient-start: #9333ea; --dg-gradient-end: #c084fc; } ``` --- ### 4.4 主题四「松绿自然」— 护眼绿调 **设计定位**:松绿自然主题面向长时间使用平台的开发团队设计,以墨绿色为基调,利用绿色光谱对人眼最为友好的特性,最大程度降低长时间注视屏幕带来的视觉疲劳。 **色彩设计理念**:该主题的核心设计原则是"护眼优先"。主背景色 `#0a1210` 是带有明显绿色相的极深色,类似深夜松林深处的颜色,极低明度确保了基础视觉负荷的最小化。次背景色 `#111f1a`(深墨绿)和三级背景色 `#192c24`(墨绿灰)沿绿色谱系递进,在保持低明度的同时构建清晰的视觉层次。悬停背景色 `#253d32` 选用了中等深度的松绿色,交互时呈现自然、柔和的状态变化。边框色 `#253d32` 与悬停色共用,确保交互反馈与界面分割的视觉统一。主文字色 `#f0fdf4` 是极淡的薄荷白,在墨绿背景上明亮而不刺眼,具有极佳的阅读舒适度。 **强调色体系**:绿色系强调色选用 `#4ade80`(Tailwind Green 400),这是一个明亮、清新的绿色,在墨绿暗底上如同松针上的晨露般醒目。信息色 `#2dd4bf` 偏向青绿色,与主色调完美协调。蓝色调整为天蓝色 `#38bdf8`,在绿调环境中起到色彩平衡的作用,避免界面过于单调。 **适用场景**:开发团队日常长时间使用、DBA 持续监控数据库状态、运维人员驻屏值班等需要长时间面对屏幕的工作场景。 ```css /* === 主题四:松绿自然 pine-green === */ [data-theme="pine-green"] { /* shadcn/ui 基础变量 */ --background: 150 25% 5%; --foreground: 140 60% 97%; --card: 150 25% 9%; --card-foreground: 140 60% 97%; --popover: 150 25% 9%; --popover-foreground: 140 60% 97%; --primary: 142 71% 45%; --primary-foreground: 150 25% 5%; --secondary: 150 20% 18%; --secondary-foreground: 140 60% 97%; --muted: 150 20% 18%; --muted-foreground: 150 20% 55%; --accent: 150 20% 18%; --accent-foreground: 140 60% 97%; --destructive: 0 90% 72%; --destructive-foreground: 150 25% 5%; --border: 150 20% 18%; --input: 150 20% 18%; --ring: 142 71% 45%; --radius: 0.5rem; /* DataGuard 自定义变量 */ --dg-bg-primary: #0a1210; --dg-bg-secondary: #111f1a; --dg-bg-tertiary: #192c24; --dg-bg-hover: #253d32; --dg-border: #253d32; --dg-border-light: #192c24; --dg-text-primary: #f0fdf4; --dg-text-secondary: #86b8a0; --dg-text-muted: #5a7c6b; --dg-blue: #38bdf8; --dg-green: #4ade80; --dg-red: #f87171; --dg-orange: #fb923c; --dg-purple: #c084fc; --dg-cyan: #2dd4bf; --dg-yellow: #facc15; --dg-gradient-start: #059669; --dg-gradient-end: #10b981; } ``` --- ### 4.5 主题五「橙光活力」— 活力暖色调 **设计定位**:橙光活力主题以深棕暗橙为基底,搭配明亮的橙色渐变,传递温暖、积极、富有活力的品牌情绪。该主题面向年轻化团队和创新型企业,打破传统数据安全平台冰冷刻板的印象。 **色彩设计理念**:主背景色 `#110d08` 是带有明显棕色相的极深色,类似深烘焙咖啡豆的颜色,温暖而沉稳。次背景色 `#1d1610` 和三级背景色 `#2b1f16` 沿棕色谱系递进,营造出如同暖色调咖啡馆般的舒适感。悬停背景色 `#3d2d20` 是一个中等深度的暖棕色,交互反馈如同木材被温暖光线照亮。文字色彩方面,主文字色 `#fef7ed` 是极淡的暖白色,如同烛光下的纸张,在暗棕底上既明亮又温暖。 **强调色体系**:核心渐变从 `#ea580c`(Tailwind Orange 600)到 `#f59e0b`(Tailwind Amber 500),这是一段充满能量感的橙黄渐变,用于重要按钮、品牌标识和数据高亮时极具视觉冲击力。蓝色调整为柔和的 `#60a5fa`,在暖色调环境中起到中和平衡的作用。紫色调整为偏暖的 `#a78bfa`,与整体暖调和谐共存。 **适用场景**:互联网创业公司、年轻化的技术团队、创意型企业、产品内部分享会等追求活力与创新氛围的使用场景。 ```css /* === 主题五:橙光活力 orange-vitality === */ [data-theme="orange-vitality"] { /* shadcn/ui 基础变量 */ --background: 30 35% 5%; --foreground: 30 100% 97%; --card: 30 30% 9%; --card-foreground: 30 100% 97%; --popover: 30 30% 9%; --popover-foreground: 30 100% 97%; --primary: 25 95% 53%; --primary-foreground: 0 0% 100%; --secondary: 30 25% 18%; --secondary-foreground: 30 100% 97%; --muted: 30 25% 18%; --muted-foreground: 30 25% 55%; --accent: 30 25% 18%; --accent-foreground: 30 100% 97%; --destructive: 0 80% 70%; --destructive-foreground: 30 35% 5%; --border: 30 25% 18%; --input: 30 25% 18%; --ring: 25 95% 53%; --radius: 0.5rem; /* DataGuard 自定义变量 */ --dg-bg-primary: #110d08; --dg-bg-secondary: #1d1610; --dg-bg-tertiary: #2b1f16; --dg-bg-hover: #3d2d20; --dg-border: #3d2d20; --dg-border-light: #2b1f16; --dg-text-primary: #fef7ed; --dg-text-secondary: #d4a574; --dg-text-muted: #9c7a54; --dg-blue: #60a5fa; --dg-green: #4ade80; --dg-red: #f87171; --dg-orange: #fb923c; --dg-purple: #a78bfa; --dg-cyan: #2dd4bf; --dg-yellow: #fcd34d; --dg-gradient-start: #ea580c; --dg-gradient-end: #f59e0b; } ``` --- ### 4.6 各主题 CSS 变量规范对比表 下表汇总了五套主题的全部 DataGuard 自定义 CSS 变量值,便于开发实现时快速查阅与对比。 | CSS 变量 | 深蓝专业 | 浅色商务 | 午夜紫韵 | 松绿自然 | 橙光活力 | |:---|:---|:---|:---|:---|:---| | `--dg-bg-primary` | `#070d19` | `#fafaf9` | `#0a0612` | `#0a1210` | `#110d08` | | `--dg-bg-secondary` | `#0f172a` | `#f5f5f4` | `#130c21` | `#111f1a` | `#1d1610` | | `--dg-bg-tertiary` | `#172033` | `#e7e5e4` | `#1c1330` | `#192c24` | `#2b1f16` | | `--dg-bg-hover` | `#233049` | `#d6d3d1` | `#2d1f4a` | `#253d32` | `#3d2d20` | | `--dg-border` | `#1e293b` | `#d6d3d1` | `#2d1f4a` | `#253d32` | `#3d2d20` | | `--dg-border-light` | `#172033` | `#e7e5e4` | `#1c1330` | `#192c24` | `#2b1f16` | | `--dg-text-primary` | `#f8fafc` | `#1c1917` | `#faf5ff` | `#f0fdf4` | `#fef7ed` | | `--dg-text-secondary` | `#94a3b8` | `#78716c` | `#b794c7` | `#86b8a0` | `#d4a574` | | `--dg-text-muted` | `#64748b` | `#a8a29e` | `#7c5a8a` | `#5a7c6b` | `#9c7a54` | | `--dg-blue` | `#3b82f6` | `#2563eb` | `#818cf8` | `#38bdf8` | `#60a5fa` | | `--dg-green` | `#22c55e` | `#16a34a` | `#34d399` | `#4ade80` | `#4ade80` | | `--dg-red` | `#ef4444` | `#dc2626` | `#fb7185` | `#f87171` | `#f87171` | | `--dg-orange` | `#f97316` | `#ea580c` | `#fb923c` | `#fb923c` | `#fb923c` | | `--dg-purple` | `#8b5cf6` | `#7c3aed` | `#c084fc` | `#c084fc` | `#a78bfa` | | `--dg-cyan` | `#06b6d4` | `#0891b2` | `#22d3ee` | `#2dd4bf` | `#2dd4bf` | | `--dg-yellow` | `#eab308` | `#ca8a04` | `#facc15` | `#facc15` | `#fcd34d` | | `--dg-gradient-start` | `#3b82f6` | `#2563eb` | `#9333ea` | `#059669` | `#ea580c` | | `--dg-gradient-end` | `#2563eb` | `#4f46e5` | `#c084fc` | `#10b981` | `#f59e0b` | **shadcn/ui 基础变量对比表** | HSL 变量 | 深蓝专业 | 浅色商务 | 午夜紫韵 | 松绿自然 | 橙光活力 | |:---|:---|:---|:---|:---|:---| | `--background` | `222 47% 4%` | `40 9% 98%` | `264 56% 4%` | `150 25% 5%` | `30 35% 5%` | | `--foreground` | `210 40% 98%` | `24 10% 10%` | `280 100% 98%` | `140 60% 97%` | `30 100% 97%` | | `--card` | `222 47% 7%` | `40 9% 96%` | `264 48% 8%` | `150 25% 9%` | `30 30% 9%` | | `--primary` | `217 91% 60%` | `221 83% 53%` | `270 91% 65%` | `142 71% 45%` | `25 95% 53%` | | `--secondary` | `217 33% 17%` | `40 6% 90%` | `264 40% 20%` | `150 20% 18%` | `30 25% 18%` | | `--muted` | `217 33% 17%` | `40 6% 90%` | `264 40% 20%` | `150 20% 18%` | `30 25% 18%` | | `--muted-foreground` | `215 20% 65%` | `25 5% 45%` | `280 30% 60%` | `150 20% 55%` | `30 25% 55%` | | `--destructive` | `0 84% 60%` | `0 72% 51%` | `348 100% 72%` | `0 90% 72%` | `0 80% 70%` | | `--border` | `217 33% 17%` | `24 6% 83%` | `264 40% 20%` | `150 20% 18%` | `30 25% 18%` | | `--ring` | `217 91% 60%` | `221 83% 53%` | `270 91% 65%` | `142 71% 45%` | `25 95% 53%` | --- ### 4.7 主题切换实现方案 #### 4.7.1 CSS 变量组织方式 五套主题的 CSS 变量采用 **"分散定义、统一命名空间"** 的组织策略。每套主题的所有变量定义在一个独立的 `data-theme` 属性选择器下,避免变量冲突和覆盖混乱。 **文件结构建议**: ``` frontend/src/styles/ ├── themes/ │ ├── index.css /* 主题入口文件,导入所有主题 */ │ ├── ocean-deep.css /* 主题一:深蓝专业 */ │ ├── light-professional.css /* 主题二:浅色商务 */ │ ├── midnight-purple.css /* 主题三:午夜紫韵 */ │ ├── pine-green.css /* 主题四:松绿自然 */ │ └── orange-vitality.css /* 主题五:橙光活力 */ └── index.css /* 现有主样式文件 */ ``` **入口文件 `themes/index.css` 内容**: ```css /* ===== SQL-Platform 主题系统入口 ===== */ /* 按加载顺序:默认主题(深蓝专业)无需 data-theme 属性 */ @import "./ocean-deep.css"; @import "./light-professional.css"; @import "./midnight-purple.css"; @import "./pine-green.css"; @import "./orange-vitality.css"; ``` > **实现说明**:`ocean-deep.css` 同时提供 `:root` 级别的默认变量(确保无 `data-theme` 属性时回退到默认主题)和 `[data-theme="ocean-deep"]` 选择器下的显式定义,保证其他主题切换回来时变量能正确覆盖。 #### 4.7.2 useTheme Hook 增强实现 现有的 `useTheme` hook 需要从双值切换(dark/light)扩展为多主题选择。以下是增强后的实现方案: ```typescript // frontend/src/hooks/useTheme.ts import { useState, useEffect, useCallback } from 'react'; /** 支持的主题标识列表 */ export const THEMES = [ { id: 'ocean-deep', label: '深蓝专业', description: '默认深色增强版' }, { id: 'light-professional', label: '浅色商务', description: '企业办公风' }, { id: 'midnight-purple', label: '午夜紫韵', description: '高端紫色调' }, { id: 'pine-green', label: '松绿自然', description: '护眼绿调' }, { id: 'orange-vitality', label: '橙光活力', description: '活力暖色调' }, ] as const; export type ThemeId = typeof THEMES[number]['id']; const STORAGE_KEY = 'sqlp-theme-id'; const DEFAULT_THEME: ThemeId = 'ocean-deep'; /** * 从 localStorage 读取保存的主题 */ function getSavedTheme(): ThemeId { try { const saved = localStorage.getItem(STORAGE_KEY); if (saved && THEMES.some(t => t.id === saved)) { return saved as ThemeId; } } catch { // localStorage 不可用时忽略 } return DEFAULT_THEME; } /** * 检测系统色彩偏好 */ function getSystemPreference(): 'dark' | 'light' { return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; } /** * 根据系统偏好映射默认主题 */ function getDefaultBySystem(): ThemeId { return getSystemPreference() === 'dark' ? 'ocean-deep' : 'light-professional'; } export function useTheme() { const [theme, setThemeState] = useState(() => { const saved = getSavedTheme(); return saved || getDefaultBySystem(); }); /** * 切换主题的核心方法 */ const setTheme = useCallback((newTheme: ThemeId) => { setThemeState(newTheme); document.documentElement.setAttribute('data-theme', newTheme); try { localStorage.setItem(STORAGE_KEY, newTheme); } catch { // localStorage 不可用时静默处理 } }, []); /** * 初始化主题:首次加载时应用 */ useEffect(() => { const saved = getSavedTheme(); const initial = saved || getDefaultBySystem(); document.documentElement.setAttribute('data-theme', initial); setThemeState(initial); }, []); /** * 监听系统主题变化,仅在用户未手动选择主题时自动切换 */ useEffect(() => { const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); const handler = (e: MediaQueryListEvent) => { // 检查用户是否已手动设置过主题 const hasUserPreference = localStorage.getItem(STORAGE_KEY) !== null; if (!hasUserPreference) { const newTheme = e.matches ? 'ocean-deep' : 'light-professional'; setTheme(newTheme); } }; mediaQuery.addEventListener('change', handler); return () => mediaQuery.removeEventListener('change', handler); }, [setTheme]); return { theme, setTheme, themes: THEMES }; } ``` #### 4.7.3 主题预览组件设计 AppearanceSettings 页面需新增主题选择区域,包含五张主题预览卡片。每张卡片展示主题的核心色彩样本和简要描述。 ```typescript // frontend/src/components/settings/ThemePreviewCard.tsx import { Check } from 'lucide-react'; import { cn } from '@/lib/utils'; import type { ThemeId } from '@/hooks/useTheme'; interface ThemePreviewCardProps { themeId: ThemeId; label: string; description: string; colors: { bg: string; secondary: string; accent: string; text: string; }; isActive: boolean; onClick: () => void; } export function ThemePreviewCard({ label, description, colors, isActive, onClick, }: ThemePreviewCardProps) { return ( ); } ``` **AppearanceSettings 页面中的主题选择区域布局**: ```tsx // 在 AppearanceSettings 页面中使用 import { useTheme, THEMES } from '@/hooks/useTheme'; import { ThemePreviewCard } from '@/components/settings/ThemePreviewCard'; // 各主题预览色值配置 const THEME_PREVIEW_COLORS: Record = { 'ocean-deep': { bg: '#070d19', secondary: '#0f172a', accent: '#3b82f6', text: '#f8fafc' }, 'light-professional': { bg: '#fafaf9', secondary: '#f5f5f4', accent: '#2563eb', text: '#1c1917' }, 'midnight-purple': { bg: '#0a0612', secondary: '#130c21', accent: '#c084fc', text: '#faf5ff' }, 'pine-green': { bg: '#0a1210', secondary: '#111f1a', accent: '#4ade80', text: '#f0fdf4' }, 'orange-vitality': { bg: '#110d08', secondary: '#1d1610', accent: '#fb923c', text: '#fef7ed' }, }; function ThemeSelector() { const { theme: activeTheme, setTheme } = useTheme(); return (

界面主题

{THEMES.map((t) => ( setTheme(t.id)} /> ))}
); } ``` #### 4.7.4 localStorage 持久化方案 主题持久化遵循以下策略: | 策略项 | 说明 | |:---|:---| | **存储键名** | `sqlp-theme-id`,与现有 `theme` 键分离,避免升级冲突 | | **存储值** | 主题标识字符串,如 `ocean-deep`、`light-professional` | | **回退逻辑** | 读取不到有效值时,检测 `prefers-color-scheme` 系统偏好,暗色默认 `ocean-deep`,亮色默认 `light-professional` | | **版本兼容** | 首次升级时,若检测到旧版 `theme: "dark"` 键,自动迁移至 `ocean-deep`;`theme: "light"` 迁移至 `light-professional`,随后删除旧键 | | **异常处理** | localStorage 不可用时(隐私模式、存储已满),降级为仅内存状态,不抛出错误 | | **跨设备同步** | 通过 `storage` 事件监听同源其他标签页的主题变更,实现多标签页同步: | ```typescript /** * 跨标签页主题同步 */ useEffect(() => { const handler = (e: StorageEvent) => { if (e.key === STORAGE_KEY && e.newValue) { const newTheme = e.newValue as ThemeId; if (THEMES.some(t => t.id === newTheme)) { setThemeState(newTheme); document.documentElement.setAttribute('data-theme', newTheme); } } }; window.addEventListener('storage', handler); return () => window.removeEventListener('storage', handler); }, []); ``` #### 4.7.5 系统主题偏好检测 平台需响应操作系统的 `prefers-color-scheme` 媒体查询,提供智能化的默认主题推荐。 **检测逻辑**: ```typescript // 检测系统暗色/浅色偏好 const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; const prefersLight = window.matchMedia('(prefers-color-scheme: light)').matches; ``` **偏好映射规则**: | 系统偏好 | 默认推荐主题 | 推荐逻辑 | |:---|:---|:---| | `prefers-color-scheme: dark` | **深蓝专业** (`ocean-deep`) | 暗色系统偏好用户通常偏好深色界面 | | `prefers-color-scheme: light` | **浅色商务** (`light-professional`) | 亮色系统偏好用户通常偏好浅色界面 | | 未指定(no-preference) | **深蓝专业** (`ocean-deep`) | 默认采用平台默认主题 | **动态响应机制**: ```typescript /** * 系统主题偏好动态响应 * 仅在用户未手动设置主题时自动跟随系统 */ useEffect(() => { const darkQuery = window.matchMedia('(prefers-color-scheme: dark)'); const lightQuery = window.matchMedia('(prefers-color-scheme: light)'); const handleChange = () => { const hasUserPreference = localStorage.getItem(STORAGE_KEY) !== null; if (hasUserPreference) return; // 用户已手动选择,不自动切换 if (darkQuery.matches) { setTheme('ocean-deep'); } else if (lightQuery.matches) { setTheme('light-professional'); } }; darkQuery.addEventListener('change', handleChange); lightQuery.addEventListener('change', handleChange); return () => { darkQuery.removeEventListener('change', handleChange); lightQuery.removeEventListener('change', handleChange); }; }, [setTheme]); ``` **重要原则**:系统偏好仅影响**首次访问**或**清除 localStorage 后**的默认主题选择。一旦用户手动选择了主题,该选择将被持久化并优先于系统偏好,避免在用户主动选择后因系统时间变化(如 macOS 自动切换暗色模式)导致界面意外变更。 #### 4.7.6 切换过渡动效 主题切换时应提供平滑的视觉过渡,避免色彩突变带来的不适感。 ```css /* 全局主题过渡效果 —— 添加到 index.css */ html { /* 对所有 CSS 变量变化应用 200ms 缓动过渡 */ transition: background-color 200ms ease, color 200ms ease; } html *, html *::before, html *::after { /* 谨慎使用:仅对关键属性过渡,避免性能问题 */ transition: background-color 200ms ease, border-color 200ms ease, color 150ms ease; } /* 可选:切换瞬间的淡入效果 */ [data-theme] { animation: themeFadeIn 200ms ease; } @keyframes themeFadeIn { from { opacity: 0.92; } to { opacity: 1; } } ``` **性能优化建议**:全局 `*` 过渡规则可能影响大型列表渲染性能。生产环境中建议仅对需要过渡的元素添加过渡规则,或通过 JavaScript 在切换主题时临时添加过渡 class,切换完成后再移除: ```typescript /** * 带过渡动画的主题切换 */ const setThemeWithTransition = useCallback((newTheme: ThemeId) => { const root = document.documentElement; root.classList.add('theme-transitioning'); setTheme(newTheme); // 300ms 后移除过渡 class setTimeout(() => { root.classList.remove('theme-transitioning'); }, 300); }, [setTheme]); ``` ```css /* 仅在切换时启用过渡 */ html.theme-transitioning, html.theme-transitioning * { transition: background-color 200ms ease, border-color 200ms ease, color 150ms ease !important; } ``` 以上实现方案确保五套主题能够稳定、高效、优雅地在平台中运行,为用户提供丰富的个性化选择。