Merge remote-tracking branch 'origin/main' into gitee
@ -47,7 +47,7 @@
 | 
			
		||||
  <img alt="PureAdmin" src="https://xiaoxian521.github.io/hyperlink/img/vue-pure-admin/2.jpg">
 | 
			
		||||
</p>
 | 
			
		||||
 | 
			
		||||
暗黑模式
 | 
			
		||||
暗色风格
 | 
			
		||||
 | 
			
		||||
<p align="center">
 | 
			
		||||
  <img alt="PureAdmin" src="https://xiaoxian521.github.io/hyperlink/img/vue-pure-admin/3.jpg">
 | 
			
		||||
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" class="icon" viewBox="0 0 1024 1024"><path fill="#386BF3" d="M410.558.109c0 210.974-300.876 361.752-300.876 633.548 0 174.943 134.704 316.787 300.876 316.787s300.877-141.817 300.877-316.787C711.408 361.752 410.558 210.974 410.558.109"/><path fill="#C3D2FB" d="M613.469 73.665c0 211.055-300.877 361.914-300.877 633.547C312.592 882.156 447.296 1024 613.47 1024s300.876-141.817 300.876-316.788C914.29 435.58 613.469 284.72 613.469 73.665"/><path fill="#303F5B" d="M312.592 707.212c0-183.713 137.636-312.171 226.723-441.39 81.702 106.112 172.12 218.74 172.12 367.726A309.755 309.755 0 0 1 420.36 950.064a323.11 323.11 0 0 1-107.769-242.852z"/></svg>
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" class="icon" viewBox="0 0 1024 1024"><path fill="#386BF3" d="M410.558.109c0 210.974-300.876 361.752-300.876 633.548 0 174.943 134.704 316.787 300.876 316.787s300.877-141.817 300.877-316.787C711.408 361.752 410.558 210.974 410.558.109"/><path fill="#C3D2FB" d="M613.469 73.665c0 211.055-300.877 361.914-300.877 633.547C312.592 882.156 447.296 1024 613.47 1024s300.876-141.817 300.876-316.788C914.29 435.58 613.469 284.72 613.469 73.665"/><path fill="#303F5B" d="M312.592 707.212c0-183.713 137.636-312.171 226.723-441.39 81.702 106.112 172.12 218.74 172.12 367.726A309.755 309.755 0 0 1 420.36 950.064a323.1 323.1 0 0 1-107.769-242.852z"/></svg>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 708 B After Width: | Height: | Size: 706 B  | 
@ -9,6 +9,7 @@
 | 
			
		||||
  "Layout": "vertical",
 | 
			
		||||
  "Theme": "light",
 | 
			
		||||
  "DarkMode": false,
 | 
			
		||||
  "OverallStyle": "light",
 | 
			
		||||
  "Grey": false,
 | 
			
		||||
  "Weak": false,
 | 
			
		||||
  "HideTabs": false,
 | 
			
		||||
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" class="icon" viewBox="0 0 1024 1024"><path fill="#386BF3" d="M410.558.109c0 210.974-300.876 361.752-300.876 633.548 0 174.943 134.704 316.787 300.876 316.787s300.877-141.817 300.877-316.787C711.408 361.752 410.558 210.974 410.558.109"/><path fill="#C3D2FB" d="M613.469 73.665c0 211.055-300.877 361.914-300.877 633.547C312.592 882.156 447.296 1024 613.47 1024s300.876-141.817 300.876-316.788C914.29 435.58 613.469 284.72 613.469 73.665"/><path fill="#303F5B" d="M312.592 707.212c0-183.713 137.636-312.171 226.723-441.39 81.702 106.112 172.12 218.74 172.12 367.726A309.755 309.755 0 0 1 420.36 950.064a323.11 323.11 0 0 1-107.769-242.852z"/></svg>
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" class="icon" viewBox="0 0 1024 1024"><path fill="#386BF3" d="M410.558.109c0 210.974-300.876 361.752-300.876 633.548 0 174.943 134.704 316.787 300.876 316.787s300.877-141.817 300.877-316.787C711.408 361.752 410.558 210.974 410.558.109"/><path fill="#C3D2FB" d="M613.469 73.665c0 211.055-300.877 361.914-300.877 633.547C312.592 882.156 447.296 1024 613.47 1024s300.876-141.817 300.876-316.788C914.29 435.58 613.469 284.72 613.469 73.665"/><path fill="#303F5B" d="M312.592 707.212c0-183.713 137.636-312.171 226.723-441.39 81.702 106.112 172.12 218.74 172.12 367.726A309.755 309.755 0 0 1 420.36 950.064a323.1 323.1 0 0 1-107.769-242.852z"/></svg>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 708 B After Width: | Height: | Size: 706 B  | 
							
								
								
									
										1
									
								
								src/assets/svg/system.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" class="icon" viewBox="0 0 1024 1024"><path d="M554 849.574c0 23.365-18.635 42.307-42 42.307s-42-18.941-42-42.307V662.719c0-23.365 18.635-42.307 42-42.307v-7.051c23.365 0 42 25.993 42 49.358z"/><path d="M893 888.5c0 17.397-14.103 31.5-31.5 31.5h-700c-17.397 0-31.5-14.103-31.5-31.5s14.103-31.5 31.5-31.5h700c17.397 0 31.5 14.103 31.5 31.5m33-714.074C926 135.484 894.686 105 855.744 105H168.256C129.314 105 98 135.484 98 174.426V533h828zM98 630.988C98 669.931 129.314 702 168.256 702h687.488C894.686 702 926 669.931 926 630.988V596H98z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 605 B  | 
| 
		 Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB  | 
@ -115,7 +115,13 @@ export default defineComponent({
 | 
			
		||||
            onClick={event => handleChange({ option, index }, event)}
 | 
			
		||||
          >
 | 
			
		||||
            <input type="radio" name="segmented" />
 | 
			
		||||
            <div class="pure-segmented-item-label">
 | 
			
		||||
            <div
 | 
			
		||||
              class="pure-segmented-item-label"
 | 
			
		||||
              v-tippy={{
 | 
			
		||||
                content: option?.tip,
 | 
			
		||||
                zIndex: 41000
 | 
			
		||||
              }}
 | 
			
		||||
            >
 | 
			
		||||
              {option.icon && !isFunction(option.label) ? (
 | 
			
		||||
                <span
 | 
			
		||||
                  class="pure-segmented-item-icon"
 | 
			
		||||
 | 
			
		||||
@ -15,4 +15,6 @@ export interface OptionsType {
 | 
			
		||||
  value?: string | number;
 | 
			
		||||
  /** 是否禁用 */
 | 
			
		||||
  disabled?: boolean;
 | 
			
		||||
  /** `tooltip` 提示 */
 | 
			
		||||
  tip?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@ import {
 | 
			
		||||
  reactive,
 | 
			
		||||
  computed,
 | 
			
		||||
  nextTick,
 | 
			
		||||
  onUnmounted,
 | 
			
		||||
  onBeforeMount
 | 
			
		||||
} from "vue";
 | 
			
		||||
import panel from "../panel/index.vue";
 | 
			
		||||
@ -21,6 +22,7 @@ import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
 | 
			
		||||
import Check from "@iconify-icons/ep/check";
 | 
			
		||||
import dayIcon from "@/assets/svg/day.svg?component";
 | 
			
		||||
import darkIcon from "@/assets/svg/dark.svg?component";
 | 
			
		||||
import systemIcon from "@/assets/svg/system.svg?component";
 | 
			
		||||
 | 
			
		||||
const { device } = useNav();
 | 
			
		||||
const { isDark } = useDark();
 | 
			
		||||
@ -32,6 +34,7 @@ const horizontalRef = ref();
 | 
			
		||||
 | 
			
		||||
const {
 | 
			
		||||
  dataTheme,
 | 
			
		||||
  overallStyle,
 | 
			
		||||
  layoutTheme,
 | 
			
		||||
  themeColors,
 | 
			
		||||
  toggleClass,
 | 
			
		||||
@ -70,7 +73,7 @@ const getThemeColorStyle = computed(() => {
 | 
			
		||||
  };
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/** 当网页为暗黑模式时不显示亮白色切换选项 */
 | 
			
		||||
/** 当网页整体为暗色风格时不显示亮白色主题配色切换选项 */
 | 
			
		||||
const showThemeColors = computed(() => {
 | 
			
		||||
  return themeColor => {
 | 
			
		||||
    return themeColor === "light" && isDark.value ? false : true;
 | 
			
		||||
@ -162,13 +165,24 @@ const getThemeColor = computed(() => {
 | 
			
		||||
const themeOptions = computed<Array<OptionsType>>(() => {
 | 
			
		||||
  return [
 | 
			
		||||
    {
 | 
			
		||||
      label: "亮色",
 | 
			
		||||
      label: "浅色",
 | 
			
		||||
      icon: dayIcon,
 | 
			
		||||
      theme: "light",
 | 
			
		||||
      tip: "清新启航,点亮舒适的工作界面",
 | 
			
		||||
      iconAttrs: { fill: isDark.value ? "#fff" : "#000" }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "暗色",
 | 
			
		||||
      label: "深色",
 | 
			
		||||
      icon: darkIcon,
 | 
			
		||||
      theme: "dark",
 | 
			
		||||
      tip: "月光序曲,沉醉于夜的静谧雅致",
 | 
			
		||||
      iconAttrs: { fill: isDark.value ? "#fff" : "#000" }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      label: "自动",
 | 
			
		||||
      icon: systemIcon,
 | 
			
		||||
      theme: "system",
 | 
			
		||||
      tip: "同步时光,界面随晨昏自然呼应",
 | 
			
		||||
      iconAttrs: { fill: isDark.value ? "#fff" : "#000" }
 | 
			
		||||
    }
 | 
			
		||||
  ];
 | 
			
		||||
@ -177,10 +191,12 @@ const themeOptions = computed<Array<OptionsType>>(() => {
 | 
			
		||||
const markOptions: Array<OptionsType> = [
 | 
			
		||||
  {
 | 
			
		||||
    label: "灵动",
 | 
			
		||||
    tip: "灵动标签,添趣生辉",
 | 
			
		||||
    value: "smart"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    label: "卡片",
 | 
			
		||||
    tip: "卡片标签,高效浏览",
 | 
			
		||||
    value: "card"
 | 
			
		||||
  }
 | 
			
		||||
];
 | 
			
		||||
@ -195,7 +211,8 @@ function setLayoutModel(layout: string) {
 | 
			
		||||
    darkMode: $storage.layout?.darkMode,
 | 
			
		||||
    sidebarStatus: $storage.layout?.sidebarStatus,
 | 
			
		||||
    epThemeColor: $storage.layout?.epThemeColor,
 | 
			
		||||
    themeColor: layoutTheme.value.theme
 | 
			
		||||
    themeColor: $storage.layout?.themeColor,
 | 
			
		||||
    overallStyle: $storage.layout?.overallStyle
 | 
			
		||||
  };
 | 
			
		||||
  useAppStoreHook().setLayout(layout);
 | 
			
		||||
}
 | 
			
		||||
@ -220,9 +237,34 @@ watch($storage, ({ layout }) => {
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)");
 | 
			
		||||
 | 
			
		||||
/** 根据操作系统主题设置平台整体风格 */
 | 
			
		||||
function updateTheme() {
 | 
			
		||||
  if (overallStyle.value !== "system") return;
 | 
			
		||||
  if (mediaQueryList.matches) {
 | 
			
		||||
    dataTheme.value = true;
 | 
			
		||||
  } else {
 | 
			
		||||
    dataTheme.value = false;
 | 
			
		||||
  }
 | 
			
		||||
  dataThemeChange(overallStyle.value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function removeMatchMedia() {
 | 
			
		||||
  mediaQueryList.removeEventListener("change", updateTheme);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 监听操作系统主题改变 */
 | 
			
		||||
function watchSystemThemeChange() {
 | 
			
		||||
  updateTheme();
 | 
			
		||||
  removeMatchMedia();
 | 
			
		||||
  mediaQueryList.addEventListener("change", updateTheme);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
onBeforeMount(() => {
 | 
			
		||||
  /* 初始化项目配置 */
 | 
			
		||||
  nextTick(() => {
 | 
			
		||||
    watchSystemThemeChange();
 | 
			
		||||
    settings.greyVal &&
 | 
			
		||||
      document.querySelector("html")?.setAttribute("class", "html-grey");
 | 
			
		||||
    settings.weakVal &&
 | 
			
		||||
@ -231,6 +273,8 @@ onBeforeMount(() => {
 | 
			
		||||
    settings.hideFooter && hideFooterChange();
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
onUnmounted(() => removeMatchMedia);
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
@ -238,12 +282,17 @@ onBeforeMount(() => {
 | 
			
		||||
    <div class="p-6">
 | 
			
		||||
      <p class="mb-3 font-medium text-sm dark:text-white">整体风格</p>
 | 
			
		||||
      <Segmented
 | 
			
		||||
        :modelValue="dataTheme ? 1 : 0"
 | 
			
		||||
        class="select-none"
 | 
			
		||||
        :modelValue="overallStyle === 'system' ? 2 : dataTheme ? 1 : 0"
 | 
			
		||||
        :options="themeOptions"
 | 
			
		||||
        @change="
 | 
			
		||||
          {
 | 
			
		||||
            dataTheme = !dataTheme;
 | 
			
		||||
            dataThemeChange();
 | 
			
		||||
          theme => {
 | 
			
		||||
            theme.index === 1 && theme.index !== 2
 | 
			
		||||
              ? (dataTheme = true)
 | 
			
		||||
              : (dataTheme = false);
 | 
			
		||||
            overallStyle = theme.option.theme;
 | 
			
		||||
            dataThemeChange(theme.option.theme);
 | 
			
		||||
            theme.index === 2 && watchSystemThemeChange();
 | 
			
		||||
          }
 | 
			
		||||
        "
 | 
			
		||||
      />
 | 
			
		||||
@ -272,7 +321,7 @@ onBeforeMount(() => {
 | 
			
		||||
        <li
 | 
			
		||||
          ref="verticalRef"
 | 
			
		||||
          v-tippy="{
 | 
			
		||||
            content: '左侧菜单',
 | 
			
		||||
            content: '左侧菜单,亲切熟悉',
 | 
			
		||||
            zIndex: 41000
 | 
			
		||||
          }"
 | 
			
		||||
          :class="layoutTheme.layout === 'vertical' ? 'is-select' : ''"
 | 
			
		||||
@ -285,7 +334,7 @@ onBeforeMount(() => {
 | 
			
		||||
          v-if="device !== 'mobile'"
 | 
			
		||||
          ref="horizontalRef"
 | 
			
		||||
          v-tippy="{
 | 
			
		||||
            content: '顶部菜单',
 | 
			
		||||
            content: '顶部菜单,简洁概览',
 | 
			
		||||
            zIndex: 41000
 | 
			
		||||
          }"
 | 
			
		||||
          :class="layoutTheme.layout === 'horizontal' ? 'is-select' : ''"
 | 
			
		||||
@ -298,7 +347,7 @@ onBeforeMount(() => {
 | 
			
		||||
          v-if="device !== 'mobile'"
 | 
			
		||||
          ref="mixRef"
 | 
			
		||||
          v-tippy="{
 | 
			
		||||
            content: '混合菜单',
 | 
			
		||||
            content: '混合菜单,灵活多变',
 | 
			
		||||
            zIndex: 41000
 | 
			
		||||
          }"
 | 
			
		||||
          :class="layoutTheme.layout === 'mix' ? 'is-select' : ''"
 | 
			
		||||
@ -311,6 +360,7 @@ onBeforeMount(() => {
 | 
			
		||||
 | 
			
		||||
      <p class="mt-5 mb-3 font-medium text-base dark:text-white">页签风格</p>
 | 
			
		||||
      <Segmented
 | 
			
		||||
        class="select-none"
 | 
			
		||||
        :modelValue="markValue === 'smart' ? 0 : 1"
 | 
			
		||||
        :options="markOptions"
 | 
			
		||||
        @change="onChange"
 | 
			
		||||
 | 
			
		||||
@ -38,6 +38,7 @@ export function useDataThemeChange() {
 | 
			
		||||
 | 
			
		||||
  const { $storage } = useGlobal<GlobalPropertiesApi>();
 | 
			
		||||
  const dataTheme = ref<boolean>($storage?.layout?.darkMode);
 | 
			
		||||
  const overallStyle = ref<string>($storage?.layout?.overallStyle);
 | 
			
		||||
  const body = document.documentElement as HTMLElement;
 | 
			
		||||
 | 
			
		||||
  function toggleClass(flag: boolean, clsName: string, target?: HTMLElement) {
 | 
			
		||||
@ -64,7 +65,8 @@ export function useDataThemeChange() {
 | 
			
		||||
      darkMode: dataTheme.value,
 | 
			
		||||
      sidebarStatus: $storage.layout?.sidebarStatus,
 | 
			
		||||
      epThemeColor: $storage.layout?.epThemeColor,
 | 
			
		||||
      themeColor: isClick ? theme : storageThemeColor
 | 
			
		||||
      themeColor: isClick ? theme : storageThemeColor,
 | 
			
		||||
      overallStyle: overallStyle.value
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if (theme === "default" || theme === "light") {
 | 
			
		||||
@ -94,8 +96,9 @@ export function useDataThemeChange() {
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /** 亮色、暗色整体风格切换 */
 | 
			
		||||
  function dataThemeChange() {
 | 
			
		||||
  /** 浅色、深色整体风格切换 */
 | 
			
		||||
  function dataThemeChange(overall?: string) {
 | 
			
		||||
    overallStyle.value = overall;
 | 
			
		||||
    if (useEpThemeStoreHook().epTheme === "light" && dataTheme.value) {
 | 
			
		||||
      setLayoutThemeColor("default", false);
 | 
			
		||||
    } else {
 | 
			
		||||
@ -130,6 +133,7 @@ export function useDataThemeChange() {
 | 
			
		||||
  return {
 | 
			
		||||
    body,
 | 
			
		||||
    dataTheme,
 | 
			
		||||
    overallStyle,
 | 
			
		||||
    layoutTheme,
 | 
			
		||||
    themeColors,
 | 
			
		||||
    onReset,
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,8 @@ export function useLayout() {
 | 
			
		||||
        darkMode: $config?.DarkMode ?? false,
 | 
			
		||||
        sidebarStatus: $config?.SidebarStatus ?? true,
 | 
			
		||||
        epThemeColor: $config?.EpThemeColor ?? "#409EFF",
 | 
			
		||||
        themeColor: $config?.Theme ?? "light"
 | 
			
		||||
        themeColor: $config?.Theme ?? "light",
 | 
			
		||||
        overallStyle: $config?.OverallStyle ?? "light"
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
    /** 灰色模式、色弱模式、隐藏标签页 */
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,8 @@ function setTheme(layoutModel: string) {
 | 
			
		||||
    darkMode: $storage.layout?.darkMode,
 | 
			
		||||
    sidebarStatus: $storage.layout?.sidebarStatus,
 | 
			
		||||
    epThemeColor: $storage.layout?.epThemeColor,
 | 
			
		||||
    themeColor: $storage.layout?.themeColor
 | 
			
		||||
    themeColor: $storage.layout?.themeColor,
 | 
			
		||||
    overallStyle: $storage.layout?.overallStyle
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -119,7 +120,7 @@ onMounted(() => {
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
onBeforeMount(() => {
 | 
			
		||||
  useDataThemeChange().dataThemeChange();
 | 
			
		||||
  useDataThemeChange().dataThemeChange($storage.layout?.overallStyle);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const layoutHeader = defineComponent({
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
@use "element-plus/theme-chalk/src/dark/css-vars.scss" as *;
 | 
			
		||||
 | 
			
		||||
/* 暗黑模式适配 */
 | 
			
		||||
/* 整体暗色风格适配 */
 | 
			
		||||
html.dark {
 | 
			
		||||
  $border-style: #303030;
 | 
			
		||||
  $color-white: #fff;
 | 
			
		||||
@ -126,7 +126,7 @@ html.dark {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* 克隆并自定义 ElMessage 样式,不会影响 ElMessage 原本样式,在 src/utils/message.ts 中调用自定义样式 ElMessage 方法即可,非暗黑模式在 src/style/element-plus.scss 文件进行了适配 */
 | 
			
		||||
  /* 克隆并自定义 ElMessage 样式,不会影响 ElMessage 原本样式,在 src/utils/message.ts 中调用自定义样式 ElMessage 方法即可,整体浅色风格在 src/style/element-plus.scss 文件进行了适配 */
 | 
			
		||||
  .pure-message {
 | 
			
		||||
    background-color: rgb(36 37 37) !important;
 | 
			
		||||
    background-image: initial !important;
 | 
			
		||||
 | 
			
		||||
@ -116,7 +116,7 @@
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 克隆并自定义 ElMessage 样式,不会影响 ElMessage 原本样式,在 src/utils/message.ts 中调用自定义样式 ElMessage 方法即可,暗黑模式在 src/style/dark.scss 文件进行了适配 */
 | 
			
		||||
/* 克隆并自定义 ElMessage 样式,不会影响 ElMessage 原本样式,在 src/utils/message.ts 中调用自定义样式 ElMessage 方法即可,整体暗色风格在 src/style/dark.scss 文件进行了适配 */
 | 
			
		||||
.pure-message {
 | 
			
		||||
  padding: 10px 13px !important;
 | 
			
		||||
  background: #fff !important;
 | 
			
		||||
@ -189,7 +189,7 @@
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 仿 el-scrollbar 滚动条样式,支持大多数浏览器,如Chrome、Edge、Firefox、Safari等。暗黑模式在 src/style/dark.scss 文件进行了适配 */
 | 
			
		||||
/* 仿 el-scrollbar 滚动条样式,支持大多数浏览器,如Chrome、Edge、Firefox、Safari等。整体暗色风格在 src/style/dark.scss 文件进行了适配 */
 | 
			
		||||
.pure-scrollbar {
 | 
			
		||||
  /* Firefox */
 | 
			
		||||
  scrollbar-width: thin; /* 可选值为 'auto', 'thin', 'none' */
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,8 @@ export const injectResponsiveStorage = (app: App, config: PlatformConfigs) => {
 | 
			
		||||
        darkMode: config.DarkMode ?? false,
 | 
			
		||||
        sidebarStatus: config.SidebarStatus ?? true,
 | 
			
		||||
        epThemeColor: config.EpThemeColor ?? "#409EFF",
 | 
			
		||||
        themeColor: config.Theme ?? "light" // 主题色(对应项目配置中的主题色,与theme不同的是它不会受到亮色、暗色整体风格切换的影响,只会在手动点击主题色时改变)
 | 
			
		||||
        themeColor: config.Theme ?? "light", // 主题色(对应项目配置中的主题色,与theme不同的是它不会受到浅色、深色整体风格切换的影响,只会在手动点击主题色时改变)
 | 
			
		||||
        overallStyle: config.OverallStyle ?? "light" // 整体风格(浅色:light、深色:dark、自动:system)
 | 
			
		||||
      },
 | 
			
		||||
      // 项目配置-界面显示
 | 
			
		||||
      configure: Storage.getData("configure", nameSpace) ?? {
 | 
			
		||||
 | 
			
		||||
@ -117,7 +117,7 @@ defineOptions({
 | 
			
		||||
    <h4 class="mb-4">
 | 
			
		||||
      类似 Ant Design 风格的消息提示,点击弹出提示信息(基于 ElMessage
 | 
			
		||||
      样式改版,不会影响 ElMessage
 | 
			
		||||
      原本样式,使用和打包大小成本极低并适配暗黑模式)
 | 
			
		||||
      原本样式,使用和打包大小成本极低并适配整体暗色风格)
 | 
			
		||||
    </h4>
 | 
			
		||||
 | 
			
		||||
    <el-space wrap>
 | 
			
		||||
 | 
			
		||||
@ -56,8 +56,8 @@ const currentPage = computed(() => {
 | 
			
		||||
const { t } = useI18n();
 | 
			
		||||
const { initStorage } = useLayout();
 | 
			
		||||
initStorage();
 | 
			
		||||
const { dataTheme, dataThemeChange } = useDataThemeChange();
 | 
			
		||||
dataThemeChange();
 | 
			
		||||
const { dataTheme, overallStyle, dataThemeChange } = useDataThemeChange();
 | 
			
		||||
dataThemeChange(overallStyle.value);
 | 
			
		||||
const { title, getDropdownItemStyle, getDropdownItemClass } = useNav();
 | 
			
		||||
const { locale, translationCh, translationEn } = useTranslationLang();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								types/global.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -83,6 +83,7 @@ declare global {
 | 
			
		||||
    Layout?: string;
 | 
			
		||||
    Theme?: string;
 | 
			
		||||
    DarkMode?: boolean;
 | 
			
		||||
    OverallStyle?: string;
 | 
			
		||||
    Grey?: boolean;
 | 
			
		||||
    Weak?: boolean;
 | 
			
		||||
    HideTabs?: boolean;
 | 
			
		||||
@ -127,6 +128,7 @@ declare global {
 | 
			
		||||
    sidebarStatus?: boolean;
 | 
			
		||||
    epThemeColor?: string;
 | 
			
		||||
    themeColor?: string;
 | 
			
		||||
    overallStyle?: string;
 | 
			
		||||
    showLogo?: boolean;
 | 
			
		||||
    showModel?: string;
 | 
			
		||||
    mapConfigure?: {
 | 
			
		||||
@ -154,6 +156,7 @@ declare global {
 | 
			
		||||
      sidebarStatus?: boolean;
 | 
			
		||||
      epThemeColor?: string;
 | 
			
		||||
      themeColor?: string;
 | 
			
		||||
      overallStyle?: string;
 | 
			
		||||
    };
 | 
			
		||||
    configure: {
 | 
			
		||||
      grey?: boolean;
 | 
			
		||||
 | 
			
		||||