From 6cd942fb2931f48be340d93661fd265cf4f32f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E5=BC=BA?= <357099073@qq.com> Date: Tue, 28 Oct 2025 10:59:23 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A0=B7=E5=BC=8F=EF=BC=8C?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=98=8E=E6=9A=97=E4=B8=BB=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- front/THEME_GUIDE.md | 414 +++++++++++++++ front/src/App.vue | 14 + front/src/assets/css/root.scss | 501 +++++++++++++++++- front/src/assets/css/style.scss | 13 +- front/src/assets/css/theme-usage.md | 235 ++++++++ front/src/components/ThemeToggle.vue | 57 ++ front/src/utils/theme.ts | 103 ++++ front/src/views/apps/knowledge/index.vue | 157 +++--- front/src/views/components/head.vue | 178 ------- front/src/views/components/layout.vue | 136 +++-- front/src/views/components/sidebar.vue | 66 ++- front/src/views/components/sub-sidebar.vue | 57 +- .../views/components/universal-sub-menu.vue | 71 +-- front/src/views/dashboard/index.vue | 167 +++--- front/src/views/system/roles/index.vue | 19 +- front/src/views/system/tenant/index.vue | 22 +- front/src/views/system/users/index.vue | 95 ++-- 17 files changed, 1782 insertions(+), 523 deletions(-) create mode 100644 front/THEME_GUIDE.md create mode 100644 front/src/assets/css/theme-usage.md create mode 100644 front/src/components/ThemeToggle.vue create mode 100644 front/src/utils/theme.ts delete mode 100644 front/src/views/components/head.vue diff --git a/front/THEME_GUIDE.md b/front/THEME_GUIDE.md new file mode 100644 index 0000000..1b8c999 --- /dev/null +++ b/front/THEME_GUIDE.md @@ -0,0 +1,414 @@ +# 主题系统使用指南 + +## 概述 + +项目已成功集成完整的亮色/暗色主题系统,支持一键切换并自动保存用户偏好。 + +## ✨ 主要特性 + +- ✅ 完整的亮色和暗色主题定义 +- ✅ 自动检测系统主题偏好 +- ✅ 用户偏好持久化(localStorage) +- ✅ 监听系统主题变化 +- ✅ 平滑的过渡动画 +- ✅ 50+ CSS 变量覆盖所有UI场景 +- ✅ TypeScript 类型支持 +- ✅ 响应式数据绑定 + +## 🚀 快速开始 + +### 1. 全局初始化(已完成) + +主题系统已在 `App.vue` 中全局初始化,整个应用自动支持主题切换功能。 + +### 2. 主题切换按钮 + +在头部工具栏可以看到主题切换按钮(🌙/☀️图标),点击即可切换主题。 + +### 3. 手动切换主题 + +```typescript +import { useTheme } from '@/utils/theme'; + +// 在组件中使用 +const { toggle, setTheme, currentTheme, isDark } = useTheme(); + +// 切换主题 +toggle(); + +// 设置为特定主题 +setTheme('dark'); // 或 'light' + +// 获取当前主题状态 +console.log(isDark()); // true 或 false +console.log(currentTheme); // 'light' 或 'dark' +``` + +### 4. 在样式文件中使用主题变量 + +```scss +.my-component { + background: var(--background-color); + color: var(--text-color); + border: 1px solid var(--border-color); + + &:hover { + background: var(--background-hover); + border-color: var(--border-color-hover); + } +} +``` + +## 📋 可用的 CSS 变量 + +### 主题标识 +- `--theme-mode`: 当前主题模式 ('light' 或 'dark') + +### 主要颜色 +- `--primary-color`, `--primary-hover`, `--primary-active` +- `--secondary-color`, `--secondary-hover`, `--secondary-active` +- `--accent-color`, `--accent-hover` + +### 背景颜色 +- `--background-color`: 主要背景 +- `--background-secondary`, `--background-tertiary` +- `--background-hover` + +### 文本颜色 +- `--text-color`: 主要文本 +- `--text-secondary`, `--text-tertiary` +- `--text-inverse`: 反转文本色 + +### 边框颜色 +- `--border-color`, `--border-color-hover`, `--border-color-active` + +### 状态颜色 +- `--success-color`, `--success-bg` +- `--warning-color`, `--warning-bg` +- `--error-color`, `--error-bg` +- `--info-color`, `--info-bg` + +### 组件颜色 +- `--card-bg`, `--card-shadow` +- `--sidebar-bg`, `--sidebar-hover` +- `--header-bg` + +### 阴影 +- `--shadow-sm`, `--shadow-md`, `--shadow-lg`, `--shadow-xl` + +### 圆角 +- `--border-radius`, `--border-radius-sm` +- `--border-radius-lg`, `--border-radius-xl` +- `--border-radius-full` + +### 过渡 +- `--transition-base`: all 0.3s +- `--transition-fast`: all 0.15s +- `--transition-slow`: all 0.5s + +### 字体 +- `--font-family-base` + +## 🎨 自定义滚动条 + +项目已经内置了自定义滚动条样式,支持主题切换: + +### 特性 +- ✅ 自动适配亮色/暗色主题 +- ✅ 支持 WebKit 和 Firefox 浏览器 +- ✅ 平滑的过渡动画 +- ✅ 悬停效果增强 +- ✅ 支持隐藏滚动条(保持滚动功能) + +### 滚动条大小 +- 宽度/高度:8px +- 适合现代 UI 风格 +- 不影响内容布局 + +### 使用方式 + +**1. 默认滚动条(自动应用)** +所有滚动容器都会自动使用主题滚动条样式。 + +**2. 隐藏滚动条** +如需隐藏滚动条但保持滚动功能: + +```vue +
+ +
+``` + +**3. 自定义滚动条颜色** +如需特定区域使用不同的滚动条颜色,可在组件样式中覆盖: + +```scss +.my-custom-scroll { + &::-webkit-scrollbar-thumb { + background: var(--primary-color); + } + + scrollbar-color: var(--primary-color) var(--background-secondary); +} +``` + +### 浏览器兼容性 +- ✅ Chrome/Edge: 完美支持 +- ✅ Firefox: 完美支持 +- ✅ Safari: 完美支持 +- ✅ Opera: 完美支持 +- ⚠️ IE: 使用原生滚动条 + +## 📁 文件结构 + +``` +front/ +├── src/ +│ ├── App.vue # 全局初始化主题系统 ⭐ +│ ├── main.ts # 入口文件,引入样式 +│ ├── assets/ +│ │ └── css/ +│ │ ├── root.scss # 主题变量定义 +│ │ └── theme-usage.md # 详细使用文档 +│ ├── utils/ +│ │ └── theme.ts # 主题切换工具 +│ ├── components/ +│ │ └── ThemeToggle.vue # 主题切换组件 +│ └── views/ +│ └── components/ +│ └── layout.vue # 已集成主题切换按钮 +├── THEME_GUIDE.md # 本文件 +``` + +## 💡 使用示例 + +### 示例 1: 基础组件 + +```vue + + + + + +``` + +### 示例 2: 按钮组件 + +```vue + + + + + +``` + +### 示例 3: 状态提示 + +```vue + + + + + +``` + +## 🔧 API 参考 + +### ThemeManager 类 + +```typescript +class ThemeManager { + // 初始化主题 + init(): void; + + // 设置主题 + setTheme(theme: 'light' | 'dark', save?: boolean): void; + + // 切换主题 + toggle(): ThemeMode; + + // 获取当前主题 + getCurrentTheme(): ThemeMode; + + // 检查是否为暗色 + isDark(): boolean; + + // 检查是否为亮色 + isLight(): boolean; +} +``` + +### useTheme Hook + +```typescript +export const useTheme = () => { + return { + currentTheme: ThemeMode; // 当前主题 + toggle(): void; // 切换主题 + setTheme(theme: ThemeMode): void; // 设置主题 + isDark(): boolean; // 是否暗色 + isLight(): boolean; // 是否亮色 + }; +}; +``` + +## 🎨 主题配色方案 + +### 亮色主题 +- 背景: 白色 → 浅灰 +- 文本: 深灰 → 黑色 +- 主色: 蓝色系 (#3498db) +- 次色: 绿色系 (#2ecc71) +- 强调: 黄色系 (#ffcc00) + +### 暗色主题 +- 背景: 深灰 → 黑色 +- 文本: 浅灰 → 白色 +- 主色: 浅蓝系 (#5dade2) +- 次色: 浅绿系 (#58d68d) +- 强调: 浅黄系 (#f7dc6f) + +## 📝 注意事项 + +1. **始终使用 CSS 变量**: 不要在样式中硬编码颜色值 +2. **响应式绑定**: 在 Vue 组件中使用 `computed` 来响应式获取主题 +3. **测试两个主题**: 确保在亮色和暗色主题下都有良好的可读性 +4. **避免高对比度**: 暗色主题使用柔和的色彩,减少眼部疲劳 +5. **合理使用阴影**: 暗色主题中使用更深的阴影增强层次感 + +## 🐛 故障排除 + +### 主题切换不生效 +- 确保在组件中正确导入并使用 `useTheme()` +- 检查是否正确添加了 `root.scss` 到主样式文件 + +### 样式未应用 +- 确保使用 CSS 变量而不是硬编码值 +- 检查元素是否正确继承了主题变量 + +### TypeScript 错误 +- 确保已正确导入类型定义 +- 重启 VS Code 的 TypeScript 服务器 + +## 📞 支持 + +如有问题或建议,请查看: +- `front/src/assets/css/theme-usage.md` - 详细使用文档 +- `front/src/utils/theme.ts` - 源代码和注释 +- `front/src/components/ThemeToggle.vue` - 组件示例 + diff --git a/front/src/App.vue b/front/src/App.vue index 42c51de..7c4c3ac 100644 --- a/front/src/App.vue +++ b/front/src/App.vue @@ -1,4 +1,18 @@ diff --git a/front/src/views/components/sub-sidebar.vue b/front/src/views/components/sub-sidebar.vue index 7c4f5f7..4670b4f 100644 --- a/front/src/views/components/sub-sidebar.vue +++ b/front/src/views/components/sub-sidebar.vue @@ -3,9 +3,9 @@ { .sub-sidebar-container { width: 150px; height: 100%; - background: #fafafa; - border-right: 1px solid #e8e8e8; + background: var(--sidebar-bg); + border-right: 1px solid var(--border-color); display: flex; flex-direction: column; overflow: hidden; + transition: var(--transition-base); } .back-section { display: flex; align-items: center; padding: 16px 20px; - border-bottom: 1px solid #e8e8e8; + border-bottom: 1px solid var(--border-color); cursor: pointer; - transition: background-color 0.2s; + transition: var(--transition-fast); &:hover { - background-color: #f0f0f0; + background-color: var(--background-hover); } .el-icon { margin-right: 8px; - color: #666; + color: var(--text-secondary); } .back-text { font-size: 14px; - color: #666; + color: var(--text-secondary); font-weight: 500; } } .module-title { padding: 20px; - border-bottom: 1px solid #e8e8e8; + border-bottom: 1px solid var(--border-color); h3 { margin: 0; font-size: 16px; font-weight: 600; - color: #333; + color: var(--text-color); } } @@ -135,28 +136,46 @@ const handleSubMenuClick = (item: SubMenuItem) => { height: 44px; line-height: 44px; margin: 4px 8px; - border-radius: 6px; + border-radius: var(--border-radius); + transition: var(--transition-fast); + display: flex !important; + align-items: center !important; + + i { + margin-right: 8px; + font-size: 16px; + transition: var(--transition-fast); + } &:hover { - background-color: #f0f0f0; + background-color: var(--background-hover) !important; + color: var(--primary-color) !important; + + i { + color: var(--primary-color) !important; + } } &.is-active { - background-color: #e6f0ff; - color: #409eff; + background-color: var(--background-hover) !important; + color: var(--primary-color) !important; + + i { + color: var(--primary-color) !important; + } } } } .module-description { padding: 16px 20px; - border-top: 1px solid #e8e8e8; - background-color: #f5f5f5; + border-top: 1px solid var(--border-color); + background-color: var(--background-secondary); p { margin: 0; font-size: 12px; - color: #999; + color: var(--text-tertiary); line-height: 1.5; } } diff --git a/front/src/views/components/universal-sub-menu.vue b/front/src/views/components/universal-sub-menu.vue index cb0e151..439216d 100644 --- a/front/src/views/components/universal-sub-menu.vue +++ b/front/src/views/components/universal-sub-menu.vue @@ -409,11 +409,12 @@ onActivated(async () => { .universal-sub-menu { display: flex; /* height: 100%; */ - background: #f5f5f5; + background: var(--background-secondary); + transition: var(--transition-base); } .sub-sidebar-wrapper { - border-right: 1px solid #e4e7ed; + border-right: 1px solid var(--border-color); overflow-y: none; } @@ -422,6 +423,7 @@ onActivated(async () => { padding: 20px; overflow-y: auto; height: calc(100vh - 162px); + background: var(--background-color); } /* 加载状态样式 */ @@ -432,17 +434,18 @@ onActivated(async () => { align-items: center; justify-content: center; height: 200px; - background: #ffffff; - border-radius: 8px; - box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); + background: var(--card-bg); + border-radius: var(--border-radius-lg); + box-shadow: var(--card-shadow); + border: 1px solid var(--border-color); } .loading-spinner { width: 32px; height: 32px; - border: 2px solid rgba(64, 158, 255, 0.2); - border-radius: 50%; - border-top-color: #409eff; + border: 2px solid var(--info-bg); + border-radius: var(--border-radius-full); + border-top-color: var(--info-color); animation: spin 1s ease-in-out infinite; } @@ -455,7 +458,7 @@ onActivated(async () => { .loading-state p, .error-state p { margin-top: 12px; - color: #606266; + color: var(--text-secondary); font-size: 14px; } @@ -465,11 +468,11 @@ onActivated(async () => { .error-icon i { font-size: 48px; - color: #f56c6c; + color: var(--error-color); } .error-state h3 { - color: #f56c6c; + color: var(--error-color); margin-bottom: 8px; } @@ -490,15 +493,15 @@ onActivated(async () => { .component-loading .loading-spinner { width: 32px; height: 32px; - border: 2px solid rgba(64, 158, 255, 0.2); - border-radius: 50%; - border-top-color: #409eff; + border: 2px solid var(--info-bg); + border-radius: var(--border-radius-full); + border-top-color: var(--info-color); animation: spin 1s ease-in-out infinite; } .component-loading p { margin-top: 12px; - color: #606266; + color: var(--text-secondary); font-size: 14px; } @@ -512,10 +515,11 @@ onActivated(async () => { .development-component { padding: 60px 40px; text-align: center; - background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); - border-radius: 12px; - box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.1); - border: 1px solid #e4e7ed; + background: var(--background-tertiary); + border-radius: var(--border-radius-xl); + box-shadow: var(--shadow-lg); + border: 1px solid var(--border-color); + transition: var(--transition-base); } .development-icon { @@ -524,46 +528,47 @@ onActivated(async () => { .development-icon i { font-size: 64px; - color: #409eff; + color: var(--info-color); opacity: 0.8; } .development-component h3 { - color: #303133; + color: var(--text-color); margin-bottom: 16px; font-size: 24px; font-weight: 600; } .development-path { - color: #606266; + color: var(--text-secondary); margin: 12px 0; font-size: 16px; font-family: 'Courier New', monospace; - background: rgba(64, 158, 255, 0.1); + background: var(--info-bg); padding: 8px 16px; - border-radius: 6px; + border-radius: var(--border-radius); display: inline-block; + border: 1px solid var(--info-color); } .development-desc { - color: #909399; + color: var(--text-tertiary); margin: 16px 0 24px 0; font-size: 16px; } .development-tips { - background: rgba(255, 255, 255, 0.8); + background: var(--info-bg); padding: 20px; - border-radius: 8px; - border-left: 4px solid #409eff; + border-radius: var(--border-radius-lg); + border-left: 4px solid var(--info-color); text-align: left; max-width: 500px; margin: 0 auto; } .development-tips p { - color: #606266; + color: var(--text-secondary); margin: 8px 0; font-size: 14px; line-height: 1.6; @@ -572,11 +577,11 @@ onActivated(async () => { .debug-info { padding: 20px; text-align: center; - color: #666; + color: var(--text-secondary); font-size: 12px; - background: #f0f0f0; - border: 1px dashed #ccc; + background: var(--warning-bg); + border: 1px dashed var(--warning-color); margin: 10px; - border-radius: 4px; + border-radius: var(--border-radius); } diff --git a/front/src/views/dashboard/index.vue b/front/src/views/dashboard/index.vue index 0f39735..5e1f65f 100644 --- a/front/src/views/dashboard/index.vue +++ b/front/src/views/dashboard/index.vue @@ -393,6 +393,7 @@ $warning-color: #f59e0b; $danger-color: #ef4444; $purple-color: #8b5cf6; + // 工具类 @mixin transition($property: all, $duration: 0.3s, $easing: ease) { transition: $property $duration $easing; @@ -404,14 +405,15 @@ $purple-color: #8b5cf6; "medium": 0 4px 6px rgba(0, 0, 0, 0.05), "large": 0 10px 15px rgba(0, 0, 0, 0.07), ); - box-shadow: map-get($shadows, $size); + // box-shadow: map-get($shadows, $size); } // 主容器 .dashboard-container { display: flex; min-height: 100vh; - background-color: #f9fafb; + background: var(--background-color); + transition: var(--transition-base); } // 侧边栏 @@ -570,8 +572,8 @@ $purple-color: #8b5cf6; .main-header { height: $header-height; - background-color: white; - @include shadow; + background: var(--header-bg); + box-shadow: var(--shadow-sm); padding: 0 2rem; display: flex; align-items: center; @@ -589,11 +591,11 @@ $purple-color: #8b5cf6; background: none; border: none; cursor: pointer; - color: $dark-gray; + color: var(--text-color); @include transition(color); &:hover { - color: $primary-color; + color: var(--primary-color); } } @@ -613,13 +615,19 @@ $purple-color: #8b5cf6; position: relative; display: flex; align-items: center; - background-color: $light-gray; - border-radius: 6px; + background: var(--background-secondary); + border: 1px solid var(--border-color); + border-radius: var(--border-radius); padding: 0.5rem 1rem; width: 240px; + transition: var(--transition-fast); + + &:hover { + border-color: var(--border-color-hover); + } .search-icon { - color: $medium-gray; + color: var(--text-secondary); margin-right: 0.5rem; } @@ -629,9 +637,10 @@ $purple-color: #8b5cf6; outline: none; flex: 1; font-size: 0.875rem; + color: var(--text-color); &::placeholder { - color: $medium-gray; + color: var(--text-tertiary); } } } @@ -644,22 +653,22 @@ $purple-color: #8b5cf6; .action-btn { background: none; border: none; - color: $dark-gray; + color: var(--text-color); cursor: pointer; position: relative; - @include transition(color); + transition: var(--transition-fast); &:hover { - color: $primary-color; + color: var(--primary-color); } .notification-badge { position: absolute; top: -5px; right: -5px; - background-color: $danger-color; - color: white; - border-radius: 50%; + background: var(--error-color); + color: var(--text-inverse); + border-radius: var(--border-radius-full); width: 16px; height: 16px; font-size: 0.7rem; @@ -693,23 +702,25 @@ $purple-color: #8b5cf6; margin-bottom: 2rem; .stat-card { - background-color: white; - @include shadow; - border-radius: 8px; + background: var(--card-bg); + box-shadow: var(--card-shadow); + border-radius: var(--border-radius-lg); padding: 1.25rem; display: flex; justify-content: space-between; align-items: center; - border-top: 4px solid $secondary-color; - @include transition(transform, 0.3s); + border-top: 4px solid var(--primary-color); + transition: var(--transition-base); + border: 1px solid var(--border-color); &:hover { transform: translateY(-5px); + box-shadow: var(--shadow-lg); } .stat-info { .stat-label { - color: $medium-gray; + color: var(--text-secondary); font-size: 0.875rem; margin: 0 0 0.5rem 0; } @@ -718,6 +729,7 @@ $purple-color: #8b5cf6; font-size: 1.5rem; font-weight: 600; margin: 0 0 0.25rem 0; + color: var(--text-color); } .stat-change { @@ -728,28 +740,28 @@ $purple-color: #8b5cf6; gap: 0.5rem; .change-period { - color: $medium-gray; + color: var(--text-tertiary); } } .positive { - color: $success-color; + color: var(--success-color); } .negative { - color: $danger-color; + color: var(--error-color); } } .stat-icon { width: 48px; height: 48px; - border-radius: 12px; - background-color: rgba($secondary-color, 0.1); + border-radius: var(--border-radius-lg); + background: var(--info-bg); display: flex; align-items: center; justify-content: center; - color: $secondary-color; + color: var(--info-color); } } } @@ -761,22 +773,30 @@ $purple-color: #8b5cf6; margin-bottom: 2rem; .chart-card { - background-color: white; - @include shadow; - border-radius: 8px; + background: var(--card-bg); + box-shadow: var(--card-shadow); + border-radius: var(--border-radius-lg); overflow: hidden; + border: 1px solid var(--border-color); + transition: var(--transition-base); + + &:hover { + box-shadow: var(--shadow-lg); + } .chart-header { padding: 1.25rem 1.5rem; - border-bottom: 1px solid $light-gray; + border-bottom: 1px solid var(--border-color); display: flex; align-items: center; justify-content: space-between; + background: var(--header-bg); h2 { margin: 0; font-size: 1.125rem; font-weight: 600; + color: var(--text-color); } .chart-filters { @@ -785,22 +805,24 @@ $purple-color: #8b5cf6; .filter-btn { background: none; - border: 1px solid $light-gray; - border-radius: 4px; + border: 1px solid var(--border-color); + border-radius: var(--border-radius); padding: 0.375rem 0.75rem; font-size: 0.75rem; cursor: pointer; - @include transition(all); + color: var(--text-color); + transition: var(--transition-fast); &:hover { - border-color: $secondary-color; - color: $secondary-color; + border-color: var(--primary-color); + color: var(--primary-color); + background: var(--background-hover); } &.active { - background-color: $secondary-color; - color: white; - border-color: $secondary-color; + background: var(--primary-color); + color: var(--text-inverse); + border-color: var(--primary-color); } } } @@ -809,6 +831,7 @@ $purple-color: #8b5cf6; .chart-container { padding: 1.5rem; width: 100%; + background: var(--card-bg); } } } @@ -820,34 +843,42 @@ $purple-color: #8b5cf6; .tasks-card, .activities-card { - background-color: white; - @include shadow; - border-radius: 8px; + background: var(--card-bg); + box-shadow: var(--card-shadow); + border-radius: var(--border-radius-lg); overflow: hidden; + border: 1px solid var(--border-color); + transition: var(--transition-base); + + &:hover { + box-shadow: var(--shadow-lg); + } .card-header { padding: 1.25rem 1.5rem; - border-bottom: 1px solid $light-gray; + border-bottom: 1px solid var(--border-color); display: flex; align-items: center; justify-content: space-between; + background: var(--header-bg); h2 { margin: 0; font-size: 1.125rem; font-weight: 600; + color: var(--text-color); } .view-all { background: none; border: none; - color: $secondary-color; + color: var(--primary-color); font-size: 0.875rem; cursor: pointer; - @include transition(color); + transition: var(--transition-fast); &:hover { - color: $primary-color; + color: var(--primary-hover); } } } @@ -861,15 +892,16 @@ $purple-color: #8b5cf6; .task-item, .activity-item { padding: 1rem 1.5rem; - border-bottom: 1px solid $light-gray; - @include transition(background-color); + border-bottom: 1px solid var(--border-color); + background: var(--card-bg); + transition: var(--transition-fast); &:last-child { border-bottom: none; } &:hover { - background-color: $light-gray; + background: var(--background-hover); } } } @@ -894,10 +926,10 @@ $purple-color: #8b5cf6; left: 0; width: 20px; height: 20px; - border-radius: 4px; - border: 2px solid $medium-gray; + border-radius: var(--border-radius); + border: 2px solid var(--border-color); cursor: pointer; - @include transition(all); + transition: var(--transition-fast); &::after { content: ""; @@ -907,15 +939,15 @@ $purple-color: #8b5cf6; top: 2px; width: 5px; height: 10px; - border: solid white; + border: solid var(--text-inverse); border-width: 0 2px 2px 0; transform: rotate(45deg); } } input:checked + label { - background-color: $success-color; - border-color: $success-color; + background: var(--success-color); + border-color: var(--success-color); &::after { display: block; @@ -929,40 +961,41 @@ $purple-color: #8b5cf6; .task-title { margin: 0 0 0.25rem 0; font-size: 0.875rem; - @include transition(text-decoration, color); + color: var(--text-color); + transition: var(--transition-base); &.completed { text-decoration: line-through; - color: $medium-gray; + color: var(--text-tertiary); } } .task-date { margin: 0; font-size: 0.75rem; - color: $medium-gray; + color: var(--text-secondary); } } .task-priority { font-size: 0.75rem; padding: 0.25rem 0.5rem; - border-radius: 4px; + border-radius: var(--border-radius); font-weight: 500; &.high { - background-color: rgba(239, 68, 68, 0.1); - color: $danger-color; + background: var(--error-bg); + color: var(--error-color); } &.medium { - background-color: rgba(245, 158, 11, 0.1); - color: $warning-color; + background: var(--warning-bg); + color: var(--warning-color); } &.low { - background-color: rgba(16, 185, 129, 0.1); - color: $success-color; + background: var(--success-bg); + color: var(--success-color); } } } @@ -998,7 +1031,7 @@ $purple-color: #8b5cf6; .activity-time { margin: 0; font-size: 0.75rem; - color: $medium-gray; + color: var(--text-secondary); } } } diff --git a/front/src/views/system/roles/index.vue b/front/src/views/system/roles/index.vue index 02d6d42..7f32a11 100644 --- a/front/src/views/system/roles/index.vue +++ b/front/src/views/system/roles/index.vue @@ -2,10 +2,12 @@

角色管理

- - - 添加角色 - +
+ + + 添加角色 + +
@@ -226,15 +228,6 @@ onMounted(() => { box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.03); } -.header-bar { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 20px; - padding-bottom: 6px; - border-bottom: 1px solid #f0f1f2; -} - .header-bar h2 { font-size: 1.18rem; font-weight: 600; diff --git a/front/src/views/system/tenant/index.vue b/front/src/views/system/tenant/index.vue index 1cbe43d..e38b998 100644 --- a/front/src/views/system/tenant/index.vue +++ b/front/src/views/system/tenant/index.vue @@ -526,15 +526,17 @@ onMounted(() => { \ No newline at end of file +