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">
 | 
					  <img alt="PureAdmin" src="https://xiaoxian521.github.io/hyperlink/img/vue-pure-admin/2.jpg">
 | 
				
			||||||
</p>
 | 
					</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
暗黑模式
 | 
					暗色风格
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<p align="center">
 | 
					<p align="center">
 | 
				
			||||||
  <img alt="PureAdmin" src="https://xiaoxian521.github.io/hyperlink/img/vue-pure-admin/3.jpg">
 | 
					  <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",
 | 
					  "Layout": "vertical",
 | 
				
			||||||
  "Theme": "light",
 | 
					  "Theme": "light",
 | 
				
			||||||
  "DarkMode": false,
 | 
					  "DarkMode": false,
 | 
				
			||||||
 | 
					  "OverallStyle": "light",
 | 
				
			||||||
  "Grey": false,
 | 
					  "Grey": false,
 | 
				
			||||||
  "Weak": false,
 | 
					  "Weak": false,
 | 
				
			||||||
  "HideTabs": 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)}
 | 
					            onClick={event => handleChange({ option, index }, event)}
 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            <input type="radio" name="segmented" />
 | 
					            <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) ? (
 | 
					              {option.icon && !isFunction(option.label) ? (
 | 
				
			||||||
                <span
 | 
					                <span
 | 
				
			||||||
                  class="pure-segmented-item-icon"
 | 
					                  class="pure-segmented-item-icon"
 | 
				
			||||||
 | 
				
			|||||||
@ -15,4 +15,6 @@ export interface OptionsType {
 | 
				
			|||||||
  value?: string | number;
 | 
					  value?: string | number;
 | 
				
			||||||
  /** 是否禁用 */
 | 
					  /** 是否禁用 */
 | 
				
			||||||
  disabled?: boolean;
 | 
					  disabled?: boolean;
 | 
				
			||||||
 | 
					  /** `tooltip` 提示 */
 | 
				
			||||||
 | 
					  tip?: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,6 +6,7 @@ import {
 | 
				
			|||||||
  reactive,
 | 
					  reactive,
 | 
				
			||||||
  computed,
 | 
					  computed,
 | 
				
			||||||
  nextTick,
 | 
					  nextTick,
 | 
				
			||||||
 | 
					  onUnmounted,
 | 
				
			||||||
  onBeforeMount
 | 
					  onBeforeMount
 | 
				
			||||||
} from "vue";
 | 
					} from "vue";
 | 
				
			||||||
import panel from "../panel/index.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 Check from "@iconify-icons/ep/check";
 | 
				
			||||||
import dayIcon from "@/assets/svg/day.svg?component";
 | 
					import dayIcon from "@/assets/svg/day.svg?component";
 | 
				
			||||||
import darkIcon from "@/assets/svg/dark.svg?component";
 | 
					import darkIcon from "@/assets/svg/dark.svg?component";
 | 
				
			||||||
 | 
					import systemIcon from "@/assets/svg/system.svg?component";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const { device } = useNav();
 | 
					const { device } = useNav();
 | 
				
			||||||
const { isDark } = useDark();
 | 
					const { isDark } = useDark();
 | 
				
			||||||
@ -32,6 +34,7 @@ const horizontalRef = ref();
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const {
 | 
					const {
 | 
				
			||||||
  dataTheme,
 | 
					  dataTheme,
 | 
				
			||||||
 | 
					  overallStyle,
 | 
				
			||||||
  layoutTheme,
 | 
					  layoutTheme,
 | 
				
			||||||
  themeColors,
 | 
					  themeColors,
 | 
				
			||||||
  toggleClass,
 | 
					  toggleClass,
 | 
				
			||||||
@ -70,7 +73,7 @@ const getThemeColorStyle = computed(() => {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** 当网页为暗黑模式时不显示亮白色切换选项 */
 | 
					/** 当网页整体为暗色风格时不显示亮白色主题配色切换选项 */
 | 
				
			||||||
const showThemeColors = computed(() => {
 | 
					const showThemeColors = computed(() => {
 | 
				
			||||||
  return themeColor => {
 | 
					  return themeColor => {
 | 
				
			||||||
    return themeColor === "light" && isDark.value ? false : true;
 | 
					    return themeColor === "light" && isDark.value ? false : true;
 | 
				
			||||||
@ -162,13 +165,24 @@ const getThemeColor = computed(() => {
 | 
				
			|||||||
const themeOptions = computed<Array<OptionsType>>(() => {
 | 
					const themeOptions = computed<Array<OptionsType>>(() => {
 | 
				
			||||||
  return [
 | 
					  return [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      label: "亮色",
 | 
					      label: "浅色",
 | 
				
			||||||
      icon: dayIcon,
 | 
					      icon: dayIcon,
 | 
				
			||||||
 | 
					      theme: "light",
 | 
				
			||||||
 | 
					      tip: "清新启航,点亮舒适的工作界面",
 | 
				
			||||||
      iconAttrs: { fill: isDark.value ? "#fff" : "#000" }
 | 
					      iconAttrs: { fill: isDark.value ? "#fff" : "#000" }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      label: "暗色",
 | 
					      label: "深色",
 | 
				
			||||||
      icon: darkIcon,
 | 
					      icon: darkIcon,
 | 
				
			||||||
 | 
					      theme: "dark",
 | 
				
			||||||
 | 
					      tip: "月光序曲,沉醉于夜的静谧雅致",
 | 
				
			||||||
 | 
					      iconAttrs: { fill: isDark.value ? "#fff" : "#000" }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      label: "自动",
 | 
				
			||||||
 | 
					      icon: systemIcon,
 | 
				
			||||||
 | 
					      theme: "system",
 | 
				
			||||||
 | 
					      tip: "同步时光,界面随晨昏自然呼应",
 | 
				
			||||||
      iconAttrs: { fill: isDark.value ? "#fff" : "#000" }
 | 
					      iconAttrs: { fill: isDark.value ? "#fff" : "#000" }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  ];
 | 
					  ];
 | 
				
			||||||
@ -177,10 +191,12 @@ const themeOptions = computed<Array<OptionsType>>(() => {
 | 
				
			|||||||
const markOptions: Array<OptionsType> = [
 | 
					const markOptions: Array<OptionsType> = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "灵动",
 | 
					    label: "灵动",
 | 
				
			||||||
 | 
					    tip: "灵动标签,添趣生辉",
 | 
				
			||||||
    value: "smart"
 | 
					    value: "smart"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "卡片",
 | 
					    label: "卡片",
 | 
				
			||||||
 | 
					    tip: "卡片标签,高效浏览",
 | 
				
			||||||
    value: "card"
 | 
					    value: "card"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
@ -195,7 +211,8 @@ function setLayoutModel(layout: string) {
 | 
				
			|||||||
    darkMode: $storage.layout?.darkMode,
 | 
					    darkMode: $storage.layout?.darkMode,
 | 
				
			||||||
    sidebarStatus: $storage.layout?.sidebarStatus,
 | 
					    sidebarStatus: $storage.layout?.sidebarStatus,
 | 
				
			||||||
    epThemeColor: $storage.layout?.epThemeColor,
 | 
					    epThemeColor: $storage.layout?.epThemeColor,
 | 
				
			||||||
    themeColor: layoutTheme.value.theme
 | 
					    themeColor: $storage.layout?.themeColor,
 | 
				
			||||||
 | 
					    overallStyle: $storage.layout?.overallStyle
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  useAppStoreHook().setLayout(layout);
 | 
					  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(() => {
 | 
					onBeforeMount(() => {
 | 
				
			||||||
  /* 初始化项目配置 */
 | 
					  /* 初始化项目配置 */
 | 
				
			||||||
  nextTick(() => {
 | 
					  nextTick(() => {
 | 
				
			||||||
 | 
					    watchSystemThemeChange();
 | 
				
			||||||
    settings.greyVal &&
 | 
					    settings.greyVal &&
 | 
				
			||||||
      document.querySelector("html")?.setAttribute("class", "html-grey");
 | 
					      document.querySelector("html")?.setAttribute("class", "html-grey");
 | 
				
			||||||
    settings.weakVal &&
 | 
					    settings.weakVal &&
 | 
				
			||||||
@ -231,6 +273,8 @@ onBeforeMount(() => {
 | 
				
			|||||||
    settings.hideFooter && hideFooterChange();
 | 
					    settings.hideFooter && hideFooterChange();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onUnmounted(() => removeMatchMedia);
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
@ -238,12 +282,17 @@ onBeforeMount(() => {
 | 
				
			|||||||
    <div class="p-6">
 | 
					    <div class="p-6">
 | 
				
			||||||
      <p class="mb-3 font-medium text-sm dark:text-white">整体风格</p>
 | 
					      <p class="mb-3 font-medium text-sm dark:text-white">整体风格</p>
 | 
				
			||||||
      <Segmented
 | 
					      <Segmented
 | 
				
			||||||
        :modelValue="dataTheme ? 1 : 0"
 | 
					        class="select-none"
 | 
				
			||||||
 | 
					        :modelValue="overallStyle === 'system' ? 2 : dataTheme ? 1 : 0"
 | 
				
			||||||
        :options="themeOptions"
 | 
					        :options="themeOptions"
 | 
				
			||||||
        @change="
 | 
					        @change="
 | 
				
			||||||
          {
 | 
					          theme => {
 | 
				
			||||||
            dataTheme = !dataTheme;
 | 
					            theme.index === 1 && theme.index !== 2
 | 
				
			||||||
            dataThemeChange();
 | 
					              ? (dataTheme = true)
 | 
				
			||||||
 | 
					              : (dataTheme = false);
 | 
				
			||||||
 | 
					            overallStyle = theme.option.theme;
 | 
				
			||||||
 | 
					            dataThemeChange(theme.option.theme);
 | 
				
			||||||
 | 
					            theme.index === 2 && watchSystemThemeChange();
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        "
 | 
					        "
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
@ -272,7 +321,7 @@ onBeforeMount(() => {
 | 
				
			|||||||
        <li
 | 
					        <li
 | 
				
			||||||
          ref="verticalRef"
 | 
					          ref="verticalRef"
 | 
				
			||||||
          v-tippy="{
 | 
					          v-tippy="{
 | 
				
			||||||
            content: '左侧菜单',
 | 
					            content: '左侧菜单,亲切熟悉',
 | 
				
			||||||
            zIndex: 41000
 | 
					            zIndex: 41000
 | 
				
			||||||
          }"
 | 
					          }"
 | 
				
			||||||
          :class="layoutTheme.layout === 'vertical' ? 'is-select' : ''"
 | 
					          :class="layoutTheme.layout === 'vertical' ? 'is-select' : ''"
 | 
				
			||||||
@ -285,7 +334,7 @@ onBeforeMount(() => {
 | 
				
			|||||||
          v-if="device !== 'mobile'"
 | 
					          v-if="device !== 'mobile'"
 | 
				
			||||||
          ref="horizontalRef"
 | 
					          ref="horizontalRef"
 | 
				
			||||||
          v-tippy="{
 | 
					          v-tippy="{
 | 
				
			||||||
            content: '顶部菜单',
 | 
					            content: '顶部菜单,简洁概览',
 | 
				
			||||||
            zIndex: 41000
 | 
					            zIndex: 41000
 | 
				
			||||||
          }"
 | 
					          }"
 | 
				
			||||||
          :class="layoutTheme.layout === 'horizontal' ? 'is-select' : ''"
 | 
					          :class="layoutTheme.layout === 'horizontal' ? 'is-select' : ''"
 | 
				
			||||||
@ -298,7 +347,7 @@ onBeforeMount(() => {
 | 
				
			|||||||
          v-if="device !== 'mobile'"
 | 
					          v-if="device !== 'mobile'"
 | 
				
			||||||
          ref="mixRef"
 | 
					          ref="mixRef"
 | 
				
			||||||
          v-tippy="{
 | 
					          v-tippy="{
 | 
				
			||||||
            content: '混合菜单',
 | 
					            content: '混合菜单,灵活多变',
 | 
				
			||||||
            zIndex: 41000
 | 
					            zIndex: 41000
 | 
				
			||||||
          }"
 | 
					          }"
 | 
				
			||||||
          :class="layoutTheme.layout === 'mix' ? 'is-select' : ''"
 | 
					          :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>
 | 
					      <p class="mt-5 mb-3 font-medium text-base dark:text-white">页签风格</p>
 | 
				
			||||||
      <Segmented
 | 
					      <Segmented
 | 
				
			||||||
 | 
					        class="select-none"
 | 
				
			||||||
        :modelValue="markValue === 'smart' ? 0 : 1"
 | 
					        :modelValue="markValue === 'smart' ? 0 : 1"
 | 
				
			||||||
        :options="markOptions"
 | 
					        :options="markOptions"
 | 
				
			||||||
        @change="onChange"
 | 
					        @change="onChange"
 | 
				
			||||||
 | 
				
			|||||||
@ -38,6 +38,7 @@ export function useDataThemeChange() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  const { $storage } = useGlobal<GlobalPropertiesApi>();
 | 
					  const { $storage } = useGlobal<GlobalPropertiesApi>();
 | 
				
			||||||
  const dataTheme = ref<boolean>($storage?.layout?.darkMode);
 | 
					  const dataTheme = ref<boolean>($storage?.layout?.darkMode);
 | 
				
			||||||
 | 
					  const overallStyle = ref<string>($storage?.layout?.overallStyle);
 | 
				
			||||||
  const body = document.documentElement as HTMLElement;
 | 
					  const body = document.documentElement as HTMLElement;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function toggleClass(flag: boolean, clsName: string, target?: HTMLElement) {
 | 
					  function toggleClass(flag: boolean, clsName: string, target?: HTMLElement) {
 | 
				
			||||||
@ -64,7 +65,8 @@ export function useDataThemeChange() {
 | 
				
			|||||||
      darkMode: dataTheme.value,
 | 
					      darkMode: dataTheme.value,
 | 
				
			||||||
      sidebarStatus: $storage.layout?.sidebarStatus,
 | 
					      sidebarStatus: $storage.layout?.sidebarStatus,
 | 
				
			||||||
      epThemeColor: $storage.layout?.epThemeColor,
 | 
					      epThemeColor: $storage.layout?.epThemeColor,
 | 
				
			||||||
      themeColor: isClick ? theme : storageThemeColor
 | 
					      themeColor: isClick ? theme : storageThemeColor,
 | 
				
			||||||
 | 
					      overallStyle: overallStyle.value
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (theme === "default" || theme === "light") {
 | 
					    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) {
 | 
					    if (useEpThemeStoreHook().epTheme === "light" && dataTheme.value) {
 | 
				
			||||||
      setLayoutThemeColor("default", false);
 | 
					      setLayoutThemeColor("default", false);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@ -130,6 +133,7 @@ export function useDataThemeChange() {
 | 
				
			|||||||
  return {
 | 
					  return {
 | 
				
			||||||
    body,
 | 
					    body,
 | 
				
			||||||
    dataTheme,
 | 
					    dataTheme,
 | 
				
			||||||
 | 
					    overallStyle,
 | 
				
			||||||
    layoutTheme,
 | 
					    layoutTheme,
 | 
				
			||||||
    themeColors,
 | 
					    themeColors,
 | 
				
			||||||
    onReset,
 | 
					    onReset,
 | 
				
			||||||
 | 
				
			|||||||
@ -28,7 +28,8 @@ export function useLayout() {
 | 
				
			|||||||
        darkMode: $config?.DarkMode ?? false,
 | 
					        darkMode: $config?.DarkMode ?? false,
 | 
				
			||||||
        sidebarStatus: $config?.SidebarStatus ?? true,
 | 
					        sidebarStatus: $config?.SidebarStatus ?? true,
 | 
				
			||||||
        epThemeColor: $config?.EpThemeColor ?? "#409EFF",
 | 
					        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,
 | 
					    darkMode: $storage.layout?.darkMode,
 | 
				
			||||||
    sidebarStatus: $storage.layout?.sidebarStatus,
 | 
					    sidebarStatus: $storage.layout?.sidebarStatus,
 | 
				
			||||||
    epThemeColor: $storage.layout?.epThemeColor,
 | 
					    epThemeColor: $storage.layout?.epThemeColor,
 | 
				
			||||||
    themeColor: $storage.layout?.themeColor
 | 
					    themeColor: $storage.layout?.themeColor,
 | 
				
			||||||
 | 
					    overallStyle: $storage.layout?.overallStyle
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -119,7 +120,7 @@ onMounted(() => {
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onBeforeMount(() => {
 | 
					onBeforeMount(() => {
 | 
				
			||||||
  useDataThemeChange().dataThemeChange();
 | 
					  useDataThemeChange().dataThemeChange($storage.layout?.overallStyle);
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const layoutHeader = defineComponent({
 | 
					const layoutHeader = defineComponent({
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
@use "element-plus/theme-chalk/src/dark/css-vars.scss" as *;
 | 
					@use "element-plus/theme-chalk/src/dark/css-vars.scss" as *;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 暗黑模式适配 */
 | 
					/* 整体暗色风格适配 */
 | 
				
			||||||
html.dark {
 | 
					html.dark {
 | 
				
			||||||
  $border-style: #303030;
 | 
					  $border-style: #303030;
 | 
				
			||||||
  $color-white: #fff;
 | 
					  $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 {
 | 
					  .pure-message {
 | 
				
			||||||
    background-color: rgb(36 37 37) !important;
 | 
					    background-color: rgb(36 37 37) !important;
 | 
				
			||||||
    background-image: initial !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 {
 | 
					.pure-message {
 | 
				
			||||||
  padding: 10px 13px !important;
 | 
					  padding: 10px 13px !important;
 | 
				
			||||||
  background: #fff !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 {
 | 
					.pure-scrollbar {
 | 
				
			||||||
  /* Firefox */
 | 
					  /* Firefox */
 | 
				
			||||||
  scrollbar-width: thin; /* 可选值为 'auto', 'thin', 'none' */
 | 
					  scrollbar-width: thin; /* 可选值为 'auto', 'thin', 'none' */
 | 
				
			||||||
 | 
				
			|||||||
@ -19,7 +19,8 @@ export const injectResponsiveStorage = (app: App, config: PlatformConfigs) => {
 | 
				
			|||||||
        darkMode: config.DarkMode ?? false,
 | 
					        darkMode: config.DarkMode ?? false,
 | 
				
			||||||
        sidebarStatus: config.SidebarStatus ?? true,
 | 
					        sidebarStatus: config.SidebarStatus ?? true,
 | 
				
			||||||
        epThemeColor: config.EpThemeColor ?? "#409EFF",
 | 
					        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) ?? {
 | 
					      configure: Storage.getData("configure", nameSpace) ?? {
 | 
				
			||||||
 | 
				
			|||||||
@ -117,7 +117,7 @@ defineOptions({
 | 
				
			|||||||
    <h4 class="mb-4">
 | 
					    <h4 class="mb-4">
 | 
				
			||||||
      类似 Ant Design 风格的消息提示,点击弹出提示信息(基于 ElMessage
 | 
					      类似 Ant Design 风格的消息提示,点击弹出提示信息(基于 ElMessage
 | 
				
			||||||
      样式改版,不会影响 ElMessage
 | 
					      样式改版,不会影响 ElMessage
 | 
				
			||||||
      原本样式,使用和打包大小成本极低并适配暗黑模式)
 | 
					      原本样式,使用和打包大小成本极低并适配整体暗色风格)
 | 
				
			||||||
    </h4>
 | 
					    </h4>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <el-space wrap>
 | 
					    <el-space wrap>
 | 
				
			||||||
 | 
				
			|||||||
@ -56,8 +56,8 @@ const currentPage = computed(() => {
 | 
				
			|||||||
const { t } = useI18n();
 | 
					const { t } = useI18n();
 | 
				
			||||||
const { initStorage } = useLayout();
 | 
					const { initStorage } = useLayout();
 | 
				
			||||||
initStorage();
 | 
					initStorage();
 | 
				
			||||||
const { dataTheme, dataThemeChange } = useDataThemeChange();
 | 
					const { dataTheme, overallStyle, dataThemeChange } = useDataThemeChange();
 | 
				
			||||||
dataThemeChange();
 | 
					dataThemeChange(overallStyle.value);
 | 
				
			||||||
const { title, getDropdownItemStyle, getDropdownItemClass } = useNav();
 | 
					const { title, getDropdownItemStyle, getDropdownItemClass } = useNav();
 | 
				
			||||||
const { locale, translationCh, translationEn } = useTranslationLang();
 | 
					const { locale, translationCh, translationEn } = useTranslationLang();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										3
									
								
								types/global.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -83,6 +83,7 @@ declare global {
 | 
				
			|||||||
    Layout?: string;
 | 
					    Layout?: string;
 | 
				
			||||||
    Theme?: string;
 | 
					    Theme?: string;
 | 
				
			||||||
    DarkMode?: boolean;
 | 
					    DarkMode?: boolean;
 | 
				
			||||||
 | 
					    OverallStyle?: string;
 | 
				
			||||||
    Grey?: boolean;
 | 
					    Grey?: boolean;
 | 
				
			||||||
    Weak?: boolean;
 | 
					    Weak?: boolean;
 | 
				
			||||||
    HideTabs?: boolean;
 | 
					    HideTabs?: boolean;
 | 
				
			||||||
@ -127,6 +128,7 @@ declare global {
 | 
				
			|||||||
    sidebarStatus?: boolean;
 | 
					    sidebarStatus?: boolean;
 | 
				
			||||||
    epThemeColor?: string;
 | 
					    epThemeColor?: string;
 | 
				
			||||||
    themeColor?: string;
 | 
					    themeColor?: string;
 | 
				
			||||||
 | 
					    overallStyle?: string;
 | 
				
			||||||
    showLogo?: boolean;
 | 
					    showLogo?: boolean;
 | 
				
			||||||
    showModel?: string;
 | 
					    showModel?: string;
 | 
				
			||||||
    mapConfigure?: {
 | 
					    mapConfigure?: {
 | 
				
			||||||
@ -154,6 +156,7 @@ declare global {
 | 
				
			|||||||
      sidebarStatus?: boolean;
 | 
					      sidebarStatus?: boolean;
 | 
				
			||||||
      epThemeColor?: string;
 | 
					      epThemeColor?: string;
 | 
				
			||||||
      themeColor?: string;
 | 
					      themeColor?: string;
 | 
				
			||||||
 | 
					      overallStyle?: string;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    configure: {
 | 
					    configure: {
 | 
				
			||||||
      grey?: boolean;
 | 
					      grey?: boolean;
 | 
				
			||||||
 | 
				
			|||||||