diff --git a/pc/src/assets/less/style.less b/pc/src/assets/less/style.less index f1df539..7730e1c 100644 --- a/pc/src/assets/less/style.less +++ b/pc/src/assets/less/style.less @@ -1,79 +1,8 @@ -// Element Plus 主题变量覆盖 +// Element Plus Message z-index :root { - // 基础颜色 - --el-color-primary: #409eff; - --el-color-success: #67c23a; - --el-color-warning: #e6a23c; - --el-color-danger: #f56c6c; - --el-color-info: #909399; - - // 背景颜色 - --el-bg-color: #ffffff; - --el-bg-color-page: #f2f3f5; - --el-bg-color-overlay: #ffffff; - - // 文字颜色 - --el-text-color-primary: #303133; - --el-text-color-regular: #606266; - --el-text-color-secondary: #909399; - --el-text-color-placeholder: #a8abb2; - --el-text-color-disabled: #c0c4cc; - - // 边框颜色 - --el-border-color: #dcdfe6; - --el-border-color-light: #e4e7ed; - --el-border-color-lighter: #ebeef5; - --el-border-color-extra-light: #f2f6fc; - --el-border-color-dark: #d4d7de; - --el-border-color-darker: #cdd0d6; - - // 填充颜色 - --el-fill-color: #f0f2f5; - --el-fill-color-light: #f5f7fa; - --el-fill-color-lighter: #fafafa; - --el-fill-color-extra-light: #fafcff; - --el-fill-color-dark: #ebedf0; - --el-fill-color-darker: #e6e8eb; - --el-fill-color-blank: #ffffff; - - // Message z-index --el-message-z-index: 9999; } -// 暗色主题 -[data-theme="dark"] { - --el-color-primary: #409eff; - --el-color-success: #67c23a; - --el-color-warning: #e6a23c; - --el-color-danger: #f56c6c; - --el-color-info: #909399; - - --el-bg-color: #1d1e1f; - --el-bg-color-page: #141414; - --el-bg-color-overlay: #1d1e1f; - - --el-text-color-primary: #e5eaf3; - --el-text-color-regular: #cfd3dc; - --el-text-color-secondary: #a3a6ad; - --el-text-color-placeholder: #6c6e72; - --el-text-color-disabled: #6c6e72; - - --el-border-color: #4c4d4f; - --el-border-color-light: #414243; - --el-border-color-lighter: #363637; - --el-border-color-extra-light: #2b2b2c; - --el-border-color-dark: #58585b; - --el-border-color-darker: #636466; - - --el-fill-color: #2b2b2c; - --el-fill-color-light: #262727; - --el-fill-color-lighter: #1d1e1f; - --el-fill-color-extra-light: #191919; - --el-fill-color-dark: #39393a; - --el-fill-color-darker: #424243; - --el-fill-color-blank: transparent; -} - // body 样式 body { background-color: var(--el-bg-color-page); @@ -91,9 +20,6 @@ body { transition: background-color 0.3s, border-color 0.3s, box-shadow 0.3s; } -[data-theme="dark"] .container-box { - box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.09); -} .header-bar { display: flex; @@ -106,3 +32,12 @@ body { justify-content: flex-end; margin: 14px 0 0 0; } + +// 修复 ElMessage 显示问题 +// 只修复定位,保持 Element Plus 官方样式 +.el-message { + // 确保消息固定在页面顶部中央,不受父容器影响 + position: fixed !important; + z-index: var(--el-message-z-index, 9999) !important; + pointer-events: auto !important; +} \ No newline at end of file diff --git a/pc/src/components/CommonAside.vue b/pc/src/components/CommonAside.vue index 4659195..75a5155 100644 --- a/pc/src/components/CommonAside.vue +++ b/pc/src/components/CommonAside.vue @@ -9,7 +9,7 @@ :background-color="asideBgColor" :text-color="asideTextColor" :active-text-color="activeColor" - active-background-color="activeBgColor" + :active-background-color="activeBgColor" class="el-menu-vertical-demo" @select="handleMenuSelect" :default-active="route.path" @@ -73,31 +73,61 @@ const loading = ref(true); const store = useAllDataStore(); const isCollapse = computed(() => store.state.isCollapse); const width = computed(() => store.state.isCollapse ? '64px' : '180px'); -const asideBgColor = ref('#0074e9'); -const asideTextColor = ref('#ffffff'); -const activeColor = ref ('#fff'); -const activeBgColor = ref ('#0074e9'); +// 使用 Element Plus 的颜色变量,主题切换时会自动适配 +// 这些值会被 el-menu 组件使用,el-menu 会自动适配主题 +// 计算是否为暗色主题(响应式) +const isDark = ref(document.documentElement.classList.contains('dark')); -// 更新主题颜色 -const updateThemeColors = () => { - try { - const root = document.documentElement; - const bgColor = getComputedStyle(root).getPropertyValue('--aside-bg-color').trim(); - const textColor = getComputedStyle(root).getPropertyValue('--aside-text-color').trim(); - - // 只有当获取到有效值时才更新 - if (bgColor) { - asideBgColor.value = bgColor; - } - if (textColor) { - asideTextColor.value = textColor; - } - } catch (e) { - console.warn('更新主题颜色失败:', e); - // 出错时保持默认值 - } +// 监听主题变化 +const updateTheme = () => { + isDark.value = document.documentElement.classList.contains('dark'); }; +// 使用 MutationObserver 监听 html 元素的 class 变化(主题切换时更新) +let themeObserver = null; + +// 自定义颜色配置 +const BG_COLOR = '#062da3'; // 背景和 active 颜色 +const HOVER_COLOR = '#4f84ff'; // hover 颜色 + +// 将 hex 颜色转换为 rgba +function hexToRgba(hex, alpha = 1) { + const r = parseInt(hex.slice(1, 3), 16); + const g = parseInt(hex.slice(3, 5), 16); + const b = parseInt(hex.slice(5, 7), 16); + return `rgba(${r}, ${g}, ${b}, ${alpha})`; +} + +// 亮色主题使用自定义背景色,暗色主题使用默认背景 +const asideBgColor = computed(() => { + if (isDark.value) { + return 'var(--el-bg-color)'; + } + // 亮色主题使用 #062da3 背景 + return BG_COLOR; +}); + +const asideTextColor = computed(() => { + if (isDark.value) { + return 'var(--el-text-color-primary)'; + } + // 亮色主题使用白色文字 + return '#ffffff'; +}); + +const activeColor = ref('#ffffff'); // active 文字颜色为白色 + +// hover 和 active 背景色 +const activeBgColor = computed(() => { + if (isDark.value) { + return 'rgba(255, 255, 255, 0.1)'; + } + // 亮色主题 active 使用 #4f84ff + return HOVER_COLOR; +}); + +// 不再需要手动更新主题颜色,因为使用了 Element Plus 的 CSS 变量,会自动适配 + // 将后端数据转换为前端需要的格式 const transformMenuData = (menus) => { // 首先映射字段格式 @@ -213,25 +243,25 @@ const fetchMenus = async () => { } }; -// 组件挂载时获取菜单 +// 组件挂载时初始化主题监听和获取菜单 onMounted(() => { - // 先更新主题颜色,确保组件可见 - updateThemeColors(); + // 初始化主题监听 + themeObserver = new MutationObserver(() => { + updateTheme(); + }); + + themeObserver.observe(document.documentElement, { + attributes: true, + attributeFilter: ['class'] + }); + + // 初始化时检查一次主题 + updateTheme(); // 延迟一点获取菜单,确保主题已初始化 setTimeout(() => { fetchMenus(); }, 100); - - // 监听主题变化事件 - window.addEventListener('theme-change', updateThemeColors); - - // 监听 CSS 变量变化(MutationObserver) - const observer = new MutationObserver(updateThemeColors); - observer.observe(document.documentElement, { - attributes: true, - attributeFilter: ['data-theme'] - }); }); // 计算属性:统一排序所有菜单项(不再区分有无子菜单) @@ -304,12 +334,18 @@ const findMenuItemByPath = (menus, path) => { diff --git a/pc/src/components/CommonHeader.vue b/pc/src/components/CommonHeader.vue index 95f4893..248dc94 100644 --- a/pc/src/components/CommonHeader.vue +++ b/pc/src/components/CommonHeader.vue @@ -46,7 +46,7 @@