mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +08:00 
			
		
		
		
	perf: 更干净整洁的项目配置右侧弹出面板 (#841)
This commit is contained in:
		
							parent
							
								
									e7d55ff67e
								
							
						
					
					
						commit
						7acdf03f87
					
				@ -1,7 +1,5 @@
 | 
				
			|||||||
@import "cropperjs/dist/cropper.css";
 | 
					 | 
				
			||||||
@import "tippy.js/dist/tippy.css";
 | 
					 | 
				
			||||||
@import "tippy.js/themes/light.css";
 | 
					@import "tippy.js/themes/light.css";
 | 
				
			||||||
@import "tippy.js/animations/perspective.css";
 | 
					@import "cropperjs/dist/cropper.css";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.re-circled {
 | 
					.re-circled {
 | 
				
			||||||
  .cropper-view-box,
 | 
					  .cropper-view-box,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,10 @@
 | 
				
			|||||||
import "./circled.css";
 | 
					import "./circled.css";
 | 
				
			||||||
import Cropper from "cropperjs";
 | 
					import Cropper from "cropperjs";
 | 
				
			||||||
 | 
					import { useTippy } from "vue-tippy";
 | 
				
			||||||
import { ElUpload } from "element-plus";
 | 
					import { ElUpload } from "element-plus";
 | 
				
			||||||
import type { CSSProperties } from "vue";
 | 
					import type { CSSProperties } from "vue";
 | 
				
			||||||
import { useResizeObserver } from "@vueuse/core";
 | 
					import { useResizeObserver } from "@vueuse/core";
 | 
				
			||||||
import { longpress } from "@/directives/longpress";
 | 
					import { longpress } from "@/directives/longpress";
 | 
				
			||||||
import { useTippy, directive as tippy } from "vue-tippy";
 | 
					 | 
				
			||||||
import { delay, debounce, isArray, downloadByBase64 } from "@pureadmin/utils";
 | 
					import { delay, debounce, isArray, downloadByBase64 } from "@pureadmin/utils";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  ref,
 | 
					  ref,
 | 
				
			||||||
@ -233,7 +233,6 @@ export default defineComponent({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const menuContent = defineComponent({
 | 
					    const menuContent = defineComponent({
 | 
				
			||||||
      directives: {
 | 
					      directives: {
 | 
				
			||||||
        tippy,
 | 
					 | 
				
			||||||
        longpress
 | 
					        longpress
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      setup() {
 | 
					      setup() {
 | 
				
			||||||
 | 
				
			|||||||
@ -33,7 +33,7 @@ export function useRenderIcon(icon: any, attrs?: iconType): Component {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  } else if (typeof icon === "function" || typeof icon?.render === "function") {
 | 
					  } else if (typeof icon === "function" || typeof icon?.render === "function") {
 | 
				
			||||||
    // svg
 | 
					    // svg
 | 
				
			||||||
    return icon;
 | 
					    return h(icon, { ...attrs });
 | 
				
			||||||
  } else if (typeof icon === "object") {
 | 
					  } else if (typeof icon === "object") {
 | 
				
			||||||
    return defineComponent({
 | 
					    return defineComponent({
 | 
				
			||||||
      name: "OfflineIcon",
 | 
					      name: "OfflineIcon",
 | 
				
			||||||
 | 
				
			|||||||
@ -13,7 +13,8 @@ export interface iconType {
 | 
				
			|||||||
  align?: string;
 | 
					  align?: string;
 | 
				
			||||||
  onLoad?: Function;
 | 
					  onLoad?: Function;
 | 
				
			||||||
  includes?: Function;
 | 
					  includes?: Function;
 | 
				
			||||||
 | 
					  // svg 需要什么SVG属性自行添加
 | 
				
			||||||
  //  all icon
 | 
					  fill?: string;
 | 
				
			||||||
 | 
					  // all icon
 | 
				
			||||||
  style?: object;
 | 
					  style?: object;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,6 @@
 | 
				
			|||||||
  color: rgba(0, 0, 0, 0.65);
 | 
					  color: rgba(0, 0, 0, 0.65);
 | 
				
			||||||
  background-color: rgb(0 0 0 / 4%);
 | 
					  background-color: rgb(0 0 0 / 4%);
 | 
				
			||||||
  border-radius: 2px;
 | 
					  border-radius: 2px;
 | 
				
			||||||
  transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pure-segmented-group {
 | 
					.pure-segmented-group {
 | 
				
			||||||
@ -43,7 +42,7 @@
 | 
				
			|||||||
  text-align: center;
 | 
					  text-align: center;
 | 
				
			||||||
  cursor: pointer;
 | 
					  cursor: pointer;
 | 
				
			||||||
  border-radius: 4px;
 | 
					  border-radius: 4px;
 | 
				
			||||||
  transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
 | 
					  transition: all 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pure-segmented-item > div {
 | 
					.pure-segmented-item > div {
 | 
				
			||||||
 | 
				
			|||||||
@ -121,7 +121,11 @@ export default defineComponent({
 | 
				
			|||||||
                  class="pure-segmented-item-icon"
 | 
					                  class="pure-segmented-item-icon"
 | 
				
			||||||
                  style={{ marginRight: option.label ? "6px" : 0 }}
 | 
					                  style={{ marginRight: option.label ? "6px" : 0 }}
 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
                  {h(useRenderIcon(option.icon))}
 | 
					                  {h(
 | 
				
			||||||
 | 
					                    useRenderIcon(option.icon, {
 | 
				
			||||||
 | 
					                      ...option?.iconAttrs
 | 
				
			||||||
 | 
					                    })
 | 
				
			||||||
 | 
					                  )}
 | 
				
			||||||
                </span>
 | 
					                </span>
 | 
				
			||||||
              ) : null}
 | 
					              ) : null}
 | 
				
			||||||
              {option.label ? (
 | 
					              {option.label ? (
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
import type { VNode, Component } from "vue";
 | 
					import type { VNode, Component } from "vue";
 | 
				
			||||||
 | 
					import type { iconType } from "@/components/ReIcon/src/types.ts";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface OptionsType {
 | 
					export interface OptionsType {
 | 
				
			||||||
  /** 文字 */
 | 
					  /** 文字 */
 | 
				
			||||||
@ -8,6 +9,8 @@ export interface OptionsType {
 | 
				
			|||||||
   * @see {@link 用法参考 https://yiming_chang.gitee.io/pure-admin-doc/pages/icon/#%E9%80%9A%E7%94%A8%E5%9B%BE%E6%A0%87-userendericon-hooks }
 | 
					   * @see {@link 用法参考 https://yiming_chang.gitee.io/pure-admin-doc/pages/icon/#%E9%80%9A%E7%94%A8%E5%9B%BE%E6%A0%87-userendericon-hooks }
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  icon?: string | Component;
 | 
					  icon?: string | Component;
 | 
				
			||||||
 | 
					  /** 图标属性、样式配置 */
 | 
				
			||||||
 | 
					  iconAttrs?: iconType;
 | 
				
			||||||
  /** 值 */
 | 
					  /** 值 */
 | 
				
			||||||
  value?: string | number;
 | 
					  value?: string | number;
 | 
				
			||||||
  /** 是否禁用 */
 | 
					  /** 是否禁用 */
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@
 | 
				
			|||||||
import { emitter } from "@/utils/mitt";
 | 
					import { emitter } from "@/utils/mitt";
 | 
				
			||||||
import { onClickOutside } from "@vueuse/core";
 | 
					import { onClickOutside } from "@vueuse/core";
 | 
				
			||||||
import { ref, computed, onMounted, onBeforeUnmount } from "vue";
 | 
					import { ref, computed, onMounted, onBeforeUnmount } from "vue";
 | 
				
			||||||
 | 
					import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
 | 
				
			||||||
import Close from "@iconify-icons/ep/close";
 | 
					import Close from "@iconify-icons/ep/close";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const target = ref(null);
 | 
					const target = ref(null);
 | 
				
			||||||
@ -9,7 +10,6 @@ const show = ref<Boolean>(false);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const iconClass = computed(() => {
 | 
					const iconClass = computed(() => {
 | 
				
			||||||
  return [
 | 
					  return [
 | 
				
			||||||
    "mr-[20px]",
 | 
					 | 
				
			||||||
    "outline-none",
 | 
					    "outline-none",
 | 
				
			||||||
    "width-[20px]",
 | 
					    "width-[20px]",
 | 
				
			||||||
    "height-[20px]",
 | 
					    "height-[20px]",
 | 
				
			||||||
@ -22,6 +22,8 @@ const iconClass = computed(() => {
 | 
				
			|||||||
  ];
 | 
					  ];
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const { onReset } = useDataThemeChange();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onClickOutside(target, (event: any) => {
 | 
					onClickOutside(target, (event: any) => {
 | 
				
			||||||
  if (event.clientX > target.value.offsetLeft) return;
 | 
					  if (event.clientX > target.value.offsetLeft) return;
 | 
				
			||||||
  show.value = false;
 | 
					  show.value = false;
 | 
				
			||||||
@ -43,23 +45,47 @@ onBeforeUnmount(() => {
 | 
				
			|||||||
  <div :class="{ show: show }" class="right-panel-container">
 | 
					  <div :class="{ show: show }" class="right-panel-container">
 | 
				
			||||||
    <div class="right-panel-background" />
 | 
					    <div class="right-panel-background" />
 | 
				
			||||||
    <div ref="target" class="right-panel bg-bg_color">
 | 
					    <div ref="target" class="right-panel bg-bg_color">
 | 
				
			||||||
      <div class="right-panel-items">
 | 
					      <div
 | 
				
			||||||
        <div class="project-configuration">
 | 
					        class="project-configuration border-b-[1px] border-solid border-[var(--pure-border-color)]"
 | 
				
			||||||
          <h4 class="dark:text-white">项目配置</h4>
 | 
					      >
 | 
				
			||||||
          <span title="关闭配置" :class="iconClass">
 | 
					        <h4 class="dark:text-white">项目配置</h4>
 | 
				
			||||||
            <IconifyIconOffline
 | 
					        <span
 | 
				
			||||||
              class="dark:text-white"
 | 
					          v-tippy="{
 | 
				
			||||||
              width="20px"
 | 
					            content: '关闭配置',
 | 
				
			||||||
              height="20px"
 | 
					            placement: 'bottom-start',
 | 
				
			||||||
              :icon="Close"
 | 
					            zIndex: 41000
 | 
				
			||||||
              @click="show = !show"
 | 
					          }"
 | 
				
			||||||
            />
 | 
					          :class="iconClass"
 | 
				
			||||||
          </span>
 | 
					        >
 | 
				
			||||||
        </div>
 | 
					          <IconifyIconOffline
 | 
				
			||||||
        <div
 | 
					            class="dark:text-white"
 | 
				
			||||||
          class="border-b-[1px] border-solid border-[#dcdfe6] dark:border-[#303030]"
 | 
					            width="20px"
 | 
				
			||||||
        />
 | 
					            height="20px"
 | 
				
			||||||
 | 
					            :icon="Close"
 | 
				
			||||||
 | 
					            @click="show = !show"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </span>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <el-scrollbar>
 | 
				
			||||||
        <slot />
 | 
					        <slot />
 | 
				
			||||||
 | 
					      </el-scrollbar>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <div
 | 
				
			||||||
 | 
					        class="flex justify-end p-3 border-t-[1px] border-solid border-[var(--pure-border-color)]"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <el-button
 | 
				
			||||||
 | 
					          v-tippy="{
 | 
				
			||||||
 | 
					            content: '清空缓存并返回登录页',
 | 
				
			||||||
 | 
					            placement: 'left-start',
 | 
				
			||||||
 | 
					            zIndex: 41000
 | 
				
			||||||
 | 
					          }"
 | 
				
			||||||
 | 
					          type="danger"
 | 
				
			||||||
 | 
					          text
 | 
				
			||||||
 | 
					          bg
 | 
				
			||||||
 | 
					          @click="onReset"
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          清空缓存
 | 
				
			||||||
 | 
					        </el-button>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
@ -74,6 +100,10 @@ onBeforeUnmount(() => {
 | 
				
			|||||||
</style>
 | 
					</style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style lang="scss" scoped>
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					:deep(.el-scrollbar) {
 | 
				
			||||||
 | 
					  height: calc(100vh - 110px);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.right-panel-background {
 | 
					.right-panel-background {
 | 
				
			||||||
  position: fixed;
 | 
					  position: fixed;
 | 
				
			||||||
  top: 0;
 | 
					  top: 0;
 | 
				
			||||||
@ -90,7 +120,7 @@ onBeforeUnmount(() => {
 | 
				
			|||||||
  right: 0;
 | 
					  right: 0;
 | 
				
			||||||
  z-index: 40000;
 | 
					  z-index: 40000;
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
  max-width: 315px;
 | 
					  max-width: 300px;
 | 
				
			||||||
  height: 100vh;
 | 
					  height: 100vh;
 | 
				
			||||||
  box-shadow: 0 0 15px 0 rgb(0 0 0 / 5%);
 | 
					  box-shadow: 0 0 15px 0 rgb(0 0 0 / 5%);
 | 
				
			||||||
  transition: all 0.25s cubic-bezier(0.7, 0.3, 0.1, 1);
 | 
					  transition: all 0.25s cubic-bezier(0.7, 0.3, 0.1, 1);
 | 
				
			||||||
@ -112,47 +142,10 @@ onBeforeUnmount(() => {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.handle-button {
 | 
					 | 
				
			||||||
  position: absolute;
 | 
					 | 
				
			||||||
  top: 45%;
 | 
					 | 
				
			||||||
  left: -48px;
 | 
					 | 
				
			||||||
  z-index: 0;
 | 
					 | 
				
			||||||
  width: 48px;
 | 
					 | 
				
			||||||
  height: 48px;
 | 
					 | 
				
			||||||
  font-size: 24px;
 | 
					 | 
				
			||||||
  line-height: 48px;
 | 
					 | 
				
			||||||
  color: #fff;
 | 
					 | 
				
			||||||
  text-align: center;
 | 
					 | 
				
			||||||
  pointer-events: auto;
 | 
					 | 
				
			||||||
  cursor: pointer;
 | 
					 | 
				
			||||||
  background: rgb(24 144 255);
 | 
					 | 
				
			||||||
  border-radius: 6px 0 0 6px !important;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  i {
 | 
					 | 
				
			||||||
    font-size: 24px;
 | 
					 | 
				
			||||||
    line-height: 48px;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.right-panel-items {
 | 
					 | 
				
			||||||
  height: calc(100vh - 60px);
 | 
					 | 
				
			||||||
  margin-top: 60px;
 | 
					 | 
				
			||||||
  overflow-y: auto;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.project-configuration {
 | 
					.project-configuration {
 | 
				
			||||||
  position: fixed;
 | 
					 | 
				
			||||||
  top: 15px;
 | 
					 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  align-items: center;
 | 
					  align-items: center;
 | 
				
			||||||
  justify-content: space-between;
 | 
					  justify-content: space-between;
 | 
				
			||||||
  width: 100%;
 | 
					  padding: 14px 20px;
 | 
				
			||||||
  height: 30px;
 | 
					 | 
				
			||||||
  margin-left: 10px;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
:deep(.el-divider--horizontal) {
 | 
					 | 
				
			||||||
  width: 90%;
 | 
					 | 
				
			||||||
  margin: 20px auto 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
 | 
				
			|||||||
@ -8,28 +8,22 @@ import {
 | 
				
			|||||||
  nextTick,
 | 
					  nextTick,
 | 
				
			||||||
  onBeforeMount
 | 
					  onBeforeMount
 | 
				
			||||||
} from "vue";
 | 
					} from "vue";
 | 
				
			||||||
import { getConfig } from "@/config";
 | 
					 | 
				
			||||||
import { useRouter } from "vue-router";
 | 
					 | 
				
			||||||
import panel from "../panel/index.vue";
 | 
					import panel from "../panel/index.vue";
 | 
				
			||||||
import { emitter } from "@/utils/mitt";
 | 
					import { emitter } from "@/utils/mitt";
 | 
				
			||||||
import { resetRouter } from "@/router";
 | 
					 | 
				
			||||||
import { removeToken } from "@/utils/auth";
 | 
					 | 
				
			||||||
import { routerArrays } from "@/layout/types";
 | 
					 | 
				
			||||||
import { useNav } from "@/layout/hooks/useNav";
 | 
					import { useNav } from "@/layout/hooks/useNav";
 | 
				
			||||||
import { useAppStoreHook } from "@/store/modules/app";
 | 
					import { useAppStoreHook } from "@/store/modules/app";
 | 
				
			||||||
 | 
					import { useDark, debounce, useGlobal } from "@pureadmin/utils";
 | 
				
			||||||
import { toggleTheme } from "@pureadmin/theme/dist/browser-utils";
 | 
					import { toggleTheme } from "@pureadmin/theme/dist/browser-utils";
 | 
				
			||||||
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
 | 
					import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
 | 
				
			||||||
 | 
					import Segmented, { type OptionsType } from "@/components/ReSegmented";
 | 
				
			||||||
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
 | 
					import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
 | 
				
			||||||
import { useDark, debounce, useGlobal, storageLocal } from "@pureadmin/utils";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 Check from "@iconify-icons/ep/check";
 | 
					 | 
				
			||||||
import Logout from "@iconify-icons/ri/logout-circle-r-line";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const router = useRouter();
 | 
					const { device } = useNav();
 | 
				
			||||||
const { isDark } = useDark();
 | 
					const { isDark } = useDark();
 | 
				
			||||||
const { device, tooltipEffect } = useNav();
 | 
					 | 
				
			||||||
const { $storage } = useGlobal<GlobalPropertiesApi>();
 | 
					const { $storage } = useGlobal<GlobalPropertiesApi>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const mixRef = ref();
 | 
					const mixRef = ref();
 | 
				
			||||||
@ -40,8 +34,8 @@ const {
 | 
				
			|||||||
  dataTheme,
 | 
					  dataTheme,
 | 
				
			||||||
  layoutTheme,
 | 
					  layoutTheme,
 | 
				
			||||||
  themeColors,
 | 
					  themeColors,
 | 
				
			||||||
 | 
					  toggleClass,
 | 
				
			||||||
  dataThemeChange,
 | 
					  dataThemeChange,
 | 
				
			||||||
  setEpThemeColor,
 | 
					 | 
				
			||||||
  setLayoutThemeColor
 | 
					  setLayoutThemeColor
 | 
				
			||||||
} = useDataThemeChange();
 | 
					} = useDataThemeChange();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -89,13 +83,6 @@ function storageConfigureChange<T>(key: string, val: T): void {
 | 
				
			|||||||
  $storage.configure = storageConfigure;
 | 
					  $storage.configure = storageConfigure;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function toggleClass(flag: boolean, clsName: string, target?: HTMLElement) {
 | 
					 | 
				
			||||||
  const targetEl = target || document.body;
 | 
					 | 
				
			||||||
  let { className } = targetEl;
 | 
					 | 
				
			||||||
  className = className.replace(clsName, "").trim();
 | 
					 | 
				
			||||||
  targetEl.className = flag ? `${className} ${clsName} ` : className;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** 灰色模式设置 */
 | 
					/** 灰色模式设置 */
 | 
				
			||||||
const greyChange = (value): void => {
 | 
					const greyChange = (value): void => {
 | 
				
			||||||
  toggleClass(settings.greyVal, "html-grey", document.querySelector("html"));
 | 
					  toggleClass(settings.greyVal, "html-grey", document.querySelector("html"));
 | 
				
			||||||
@ -132,24 +119,11 @@ const multiTagsCacheChange = () => {
 | 
				
			|||||||
  useMultiTagsStoreHook().multiTagsCacheChange(multiTagsCache);
 | 
					  useMultiTagsStoreHook().multiTagsCacheChange(multiTagsCache);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** 清空缓存并返回登录页 */
 | 
					function onChange({ option }) {
 | 
				
			||||||
function onReset() {
 | 
					  const { value } = option;
 | 
				
			||||||
  removeToken();
 | 
					  markValue.value = value;
 | 
				
			||||||
  storageLocal().clear();
 | 
					  storageConfigureChange("showModel", value);
 | 
				
			||||||
  const { Grey, Weak, MultiTagsCache, EpThemeColor, Layout } = getConfig();
 | 
					  emitter.emit("tagViewsShowModel", value);
 | 
				
			||||||
  useAppStoreHook().setLayout(Layout);
 | 
					 | 
				
			||||||
  setEpThemeColor(EpThemeColor);
 | 
					 | 
				
			||||||
  useMultiTagsStoreHook().multiTagsCacheChange(MultiTagsCache);
 | 
					 | 
				
			||||||
  toggleClass(Grey, "html-grey", document.querySelector("html"));
 | 
					 | 
				
			||||||
  toggleClass(Weak, "html-weakness", document.querySelector("html"));
 | 
					 | 
				
			||||||
  router.push("/login");
 | 
					 | 
				
			||||||
  useMultiTagsStoreHook().handleTags("equal", [...routerArrays]);
 | 
					 | 
				
			||||||
  resetRouter();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function onChange(label) {
 | 
					 | 
				
			||||||
  storageConfigureChange("showModel", label);
 | 
					 | 
				
			||||||
  emitter.emit("tagViewsShowModel", label);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** 侧边栏Logo */
 | 
					/** 侧边栏Logo */
 | 
				
			||||||
@ -185,6 +159,32 @@ const getThemeColor = computed(() => {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const themeOptions = computed<Array<OptionsType>>(() => {
 | 
				
			||||||
 | 
					  return [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      label: "亮色",
 | 
				
			||||||
 | 
					      icon: dayIcon,
 | 
				
			||||||
 | 
					      iconAttrs: { fill: isDark.value ? "#fff" : "#000" }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      label: "暗色",
 | 
				
			||||||
 | 
					      icon: darkIcon,
 | 
				
			||||||
 | 
					      iconAttrs: { fill: isDark.value ? "#fff" : "#000" }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const markOptions: Array<OptionsType> = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "灵动",
 | 
				
			||||||
 | 
					    value: "smart"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    label: "卡片",
 | 
				
			||||||
 | 
					    value: "card"
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** 设置导航模式 */
 | 
					/** 设置导航模式 */
 | 
				
			||||||
function setLayoutModel(layout: string) {
 | 
					function setLayoutModel(layout: string) {
 | 
				
			||||||
  layoutTheme.value.layout = layout;
 | 
					  layoutTheme.value.layout = layout;
 | 
				
			||||||
@ -234,185 +234,153 @@ onBeforeMount(() => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <panel>
 | 
					  <panel>
 | 
				
			||||||
    <el-divider>主题</el-divider>
 | 
					    <div class="p-6">
 | 
				
			||||||
    <el-switch
 | 
					      <p class="mb-3 font-medium text-sm dark:text-white">整体风格</p>
 | 
				
			||||||
      v-model="dataTheme"
 | 
					      <Segmented
 | 
				
			||||||
      inline-prompt
 | 
					        :modelValue="dataTheme ? 1 : 0"
 | 
				
			||||||
      class="pure-datatheme"
 | 
					        :options="themeOptions"
 | 
				
			||||||
      :active-icon="dayIcon"
 | 
					        @change="
 | 
				
			||||||
      :inactive-icon="darkIcon"
 | 
					          {
 | 
				
			||||||
      @change="dataThemeChange"
 | 
					            dataTheme = !dataTheme;
 | 
				
			||||||
    />
 | 
					            dataThemeChange();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        "
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <el-divider>导航栏模式</el-divider>
 | 
					      <p class="mt-5 mb-3 font-medium text-sm dark:text-white">主题色</p>
 | 
				
			||||||
    <ul class="pure-theme">
 | 
					      <ul class="theme-color">
 | 
				
			||||||
      <el-tooltip
 | 
					        <li
 | 
				
			||||||
        :effect="tooltipEffect"
 | 
					          v-for="(item, index) in themeColors"
 | 
				
			||||||
        class="item"
 | 
					          v-show="showThemeColors(item.themeColor)"
 | 
				
			||||||
        content="左侧模式"
 | 
					          :key="index"
 | 
				
			||||||
        placement="bottom"
 | 
					          :style="getThemeColorStyle(item.color)"
 | 
				
			||||||
        popper-class="pure-tooltip"
 | 
					          @click="setLayoutThemeColor(item.themeColor)"
 | 
				
			||||||
      >
 | 
					        >
 | 
				
			||||||
 | 
					          <el-icon
 | 
				
			||||||
 | 
					            style="margin: 0.1em 0.1em 0 0"
 | 
				
			||||||
 | 
					            :size="17"
 | 
				
			||||||
 | 
					            :color="getThemeColor(item.themeColor)"
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            <IconifyIconOffline :icon="Check" />
 | 
				
			||||||
 | 
					          </el-icon>
 | 
				
			||||||
 | 
					        </li>
 | 
				
			||||||
 | 
					      </ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <p class="mt-5 mb-3 font-medium text-sm dark:text-white">导航模式</p>
 | 
				
			||||||
 | 
					      <ul class="pure-theme">
 | 
				
			||||||
        <li
 | 
					        <li
 | 
				
			||||||
          ref="verticalRef"
 | 
					          ref="verticalRef"
 | 
				
			||||||
 | 
					          v-tippy="{
 | 
				
			||||||
 | 
					            content: '左侧菜单',
 | 
				
			||||||
 | 
					            zIndex: 41000
 | 
				
			||||||
 | 
					          }"
 | 
				
			||||||
          :class="layoutTheme.layout === 'vertical' ? 'is-select' : ''"
 | 
					          :class="layoutTheme.layout === 'vertical' ? 'is-select' : ''"
 | 
				
			||||||
          @click="setLayoutModel('vertical')"
 | 
					          @click="setLayoutModel('vertical')"
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
          <div />
 | 
					          <div />
 | 
				
			||||||
          <div />
 | 
					          <div />
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
      </el-tooltip>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      <el-tooltip
 | 
					 | 
				
			||||||
        v-if="device !== 'mobile'"
 | 
					 | 
				
			||||||
        :effect="tooltipEffect"
 | 
					 | 
				
			||||||
        class="item"
 | 
					 | 
				
			||||||
        content="顶部模式"
 | 
					 | 
				
			||||||
        placement="bottom"
 | 
					 | 
				
			||||||
        popper-class="pure-tooltip"
 | 
					 | 
				
			||||||
      >
 | 
					 | 
				
			||||||
        <li
 | 
					        <li
 | 
				
			||||||
 | 
					          v-if="device !== 'mobile'"
 | 
				
			||||||
          ref="horizontalRef"
 | 
					          ref="horizontalRef"
 | 
				
			||||||
 | 
					          v-tippy="{
 | 
				
			||||||
 | 
					            content: '顶部菜单',
 | 
				
			||||||
 | 
					            zIndex: 41000
 | 
				
			||||||
 | 
					          }"
 | 
				
			||||||
          :class="layoutTheme.layout === 'horizontal' ? 'is-select' : ''"
 | 
					          :class="layoutTheme.layout === 'horizontal' ? 'is-select' : ''"
 | 
				
			||||||
          @click="setLayoutModel('horizontal')"
 | 
					          @click="setLayoutModel('horizontal')"
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
          <div />
 | 
					          <div />
 | 
				
			||||||
          <div />
 | 
					          <div />
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
      </el-tooltip>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      <el-tooltip
 | 
					 | 
				
			||||||
        v-if="device !== 'mobile'"
 | 
					 | 
				
			||||||
        :effect="tooltipEffect"
 | 
					 | 
				
			||||||
        class="item"
 | 
					 | 
				
			||||||
        content="混合模式"
 | 
					 | 
				
			||||||
        placement="bottom"
 | 
					 | 
				
			||||||
        popper-class="pure-tooltip"
 | 
					 | 
				
			||||||
      >
 | 
					 | 
				
			||||||
        <li
 | 
					        <li
 | 
				
			||||||
 | 
					          v-if="device !== 'mobile'"
 | 
				
			||||||
          ref="mixRef"
 | 
					          ref="mixRef"
 | 
				
			||||||
 | 
					          v-tippy="{
 | 
				
			||||||
 | 
					            content: '混合菜单',
 | 
				
			||||||
 | 
					            zIndex: 41000
 | 
				
			||||||
 | 
					          }"
 | 
				
			||||||
          :class="layoutTheme.layout === 'mix' ? 'is-select' : ''"
 | 
					          :class="layoutTheme.layout === 'mix' ? 'is-select' : ''"
 | 
				
			||||||
          @click="setLayoutModel('mix')"
 | 
					          @click="setLayoutModel('mix')"
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
          <div />
 | 
					          <div />
 | 
				
			||||||
          <div />
 | 
					          <div />
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
      </el-tooltip>
 | 
					      </ul>
 | 
				
			||||||
    </ul>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <el-divider>主题色</el-divider>
 | 
					      <p class="mt-5 mb-3 font-medium text-base dark:text-white">页签风格</p>
 | 
				
			||||||
    <ul class="theme-color">
 | 
					      <Segmented
 | 
				
			||||||
      <li
 | 
					        :modelValue="markValue === 'smart' ? 0 : 1"
 | 
				
			||||||
        v-for="(item, index) in themeColors"
 | 
					        :options="markOptions"
 | 
				
			||||||
        v-show="showThemeColors(item.themeColor)"
 | 
					        @change="onChange"
 | 
				
			||||||
        :key="index"
 | 
					 | 
				
			||||||
        :style="getThemeColorStyle(item.color)"
 | 
					 | 
				
			||||||
        @click="setLayoutThemeColor(item.themeColor)"
 | 
					 | 
				
			||||||
      >
 | 
					 | 
				
			||||||
        <el-icon
 | 
					 | 
				
			||||||
          style="margin: 0.1em 0.1em 0 0"
 | 
					 | 
				
			||||||
          :size="17"
 | 
					 | 
				
			||||||
          :color="getThemeColor(item.themeColor)"
 | 
					 | 
				
			||||||
        >
 | 
					 | 
				
			||||||
          <IconifyIconOffline :icon="Check" />
 | 
					 | 
				
			||||||
        </el-icon>
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
    </ul>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <el-divider>界面显示</el-divider>
 | 
					 | 
				
			||||||
    <ul class="setting">
 | 
					 | 
				
			||||||
      <li>
 | 
					 | 
				
			||||||
        <span class="dark:text-white">灰色模式</span>
 | 
					 | 
				
			||||||
        <el-switch
 | 
					 | 
				
			||||||
          v-model="settings.greyVal"
 | 
					 | 
				
			||||||
          inline-prompt
 | 
					 | 
				
			||||||
          inactive-color="#a6a6a6"
 | 
					 | 
				
			||||||
          active-text="开"
 | 
					 | 
				
			||||||
          inactive-text="关"
 | 
					 | 
				
			||||||
          @change="greyChange"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
      <li>
 | 
					 | 
				
			||||||
        <span class="dark:text-white">色弱模式</span>
 | 
					 | 
				
			||||||
        <el-switch
 | 
					 | 
				
			||||||
          v-model="settings.weakVal"
 | 
					 | 
				
			||||||
          inline-prompt
 | 
					 | 
				
			||||||
          inactive-color="#a6a6a6"
 | 
					 | 
				
			||||||
          active-text="开"
 | 
					 | 
				
			||||||
          inactive-text="关"
 | 
					 | 
				
			||||||
          @change="weekChange"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
      <li>
 | 
					 | 
				
			||||||
        <span class="dark:text-white">隐藏标签页</span>
 | 
					 | 
				
			||||||
        <el-switch
 | 
					 | 
				
			||||||
          v-model="settings.tabsVal"
 | 
					 | 
				
			||||||
          inline-prompt
 | 
					 | 
				
			||||||
          inactive-color="#a6a6a6"
 | 
					 | 
				
			||||||
          active-text="开"
 | 
					 | 
				
			||||||
          inactive-text="关"
 | 
					 | 
				
			||||||
          @change="tagsChange"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
      <li>
 | 
					 | 
				
			||||||
        <span class="dark:text-white">隐藏页脚</span>
 | 
					 | 
				
			||||||
        <el-switch
 | 
					 | 
				
			||||||
          v-model="settings.hideFooter"
 | 
					 | 
				
			||||||
          inline-prompt
 | 
					 | 
				
			||||||
          inactive-color="#a6a6a6"
 | 
					 | 
				
			||||||
          active-text="开"
 | 
					 | 
				
			||||||
          inactive-text="关"
 | 
					 | 
				
			||||||
          @change="hideFooterChange"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
      <li>
 | 
					 | 
				
			||||||
        <span class="dark:text-white">侧边栏Logo</span>
 | 
					 | 
				
			||||||
        <el-switch
 | 
					 | 
				
			||||||
          v-model="logoVal"
 | 
					 | 
				
			||||||
          inline-prompt
 | 
					 | 
				
			||||||
          :active-value="true"
 | 
					 | 
				
			||||||
          :inactive-value="false"
 | 
					 | 
				
			||||||
          inactive-color="#a6a6a6"
 | 
					 | 
				
			||||||
          active-text="开"
 | 
					 | 
				
			||||||
          inactive-text="关"
 | 
					 | 
				
			||||||
          @change="logoChange"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
      <li>
 | 
					 | 
				
			||||||
        <span class="dark:text-white">标签页持久化</span>
 | 
					 | 
				
			||||||
        <el-switch
 | 
					 | 
				
			||||||
          v-model="settings.multiTagsCache"
 | 
					 | 
				
			||||||
          inline-prompt
 | 
					 | 
				
			||||||
          inactive-color="#a6a6a6"
 | 
					 | 
				
			||||||
          active-text="开"
 | 
					 | 
				
			||||||
          inactive-text="关"
 | 
					 | 
				
			||||||
          @change="multiTagsCacheChange"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      <li>
 | 
					 | 
				
			||||||
        <span class="dark:text-white">标签风格</span>
 | 
					 | 
				
			||||||
        <el-radio-group v-model="markValue" size="small" @change="onChange">
 | 
					 | 
				
			||||||
          <el-radio label="card">卡片</el-radio>
 | 
					 | 
				
			||||||
          <el-radio label="smart">灵动</el-radio>
 | 
					 | 
				
			||||||
        </el-radio-group>
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
    </ul>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <el-divider />
 | 
					 | 
				
			||||||
    <el-button
 | 
					 | 
				
			||||||
      type="danger"
 | 
					 | 
				
			||||||
      style="width: 90%; margin: 24px 15px"
 | 
					 | 
				
			||||||
      @click="onReset"
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
      <IconifyIconOffline
 | 
					 | 
				
			||||||
        :icon="Logout"
 | 
					 | 
				
			||||||
        width="15"
 | 
					 | 
				
			||||||
        height="15"
 | 
					 | 
				
			||||||
        style="margin-right: 4px"
 | 
					 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
      清空缓存并返回登录页
 | 
					
 | 
				
			||||||
    </el-button>
 | 
					      <p class="mt-5 mb-1 font-medium text-sm dark:text-white">界面显示</p>
 | 
				
			||||||
 | 
					      <ul class="setting">
 | 
				
			||||||
 | 
					        <li>
 | 
				
			||||||
 | 
					          <span class="dark:text-white">灰色模式</span>
 | 
				
			||||||
 | 
					          <el-switch
 | 
				
			||||||
 | 
					            v-model="settings.greyVal"
 | 
				
			||||||
 | 
					            inline-prompt
 | 
				
			||||||
 | 
					            active-text="开"
 | 
				
			||||||
 | 
					            inactive-text="关"
 | 
				
			||||||
 | 
					            @change="greyChange"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </li>
 | 
				
			||||||
 | 
					        <li>
 | 
				
			||||||
 | 
					          <span class="dark:text-white">色弱模式</span>
 | 
				
			||||||
 | 
					          <el-switch
 | 
				
			||||||
 | 
					            v-model="settings.weakVal"
 | 
				
			||||||
 | 
					            inline-prompt
 | 
				
			||||||
 | 
					            active-text="开"
 | 
				
			||||||
 | 
					            inactive-text="关"
 | 
				
			||||||
 | 
					            @change="weekChange"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </li>
 | 
				
			||||||
 | 
					        <li>
 | 
				
			||||||
 | 
					          <span class="dark:text-white">隐藏标签页</span>
 | 
				
			||||||
 | 
					          <el-switch
 | 
				
			||||||
 | 
					            v-model="settings.tabsVal"
 | 
				
			||||||
 | 
					            inline-prompt
 | 
				
			||||||
 | 
					            active-text="开"
 | 
				
			||||||
 | 
					            inactive-text="关"
 | 
				
			||||||
 | 
					            @change="tagsChange"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </li>
 | 
				
			||||||
 | 
					        <li>
 | 
				
			||||||
 | 
					          <span class="dark:text-white">隐藏页脚</span>
 | 
				
			||||||
 | 
					          <el-switch
 | 
				
			||||||
 | 
					            v-model="settings.hideFooter"
 | 
				
			||||||
 | 
					            inline-prompt
 | 
				
			||||||
 | 
					            active-text="开"
 | 
				
			||||||
 | 
					            inactive-text="关"
 | 
				
			||||||
 | 
					            @change="hideFooterChange"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </li>
 | 
				
			||||||
 | 
					        <li>
 | 
				
			||||||
 | 
					          <span class="dark:text-white">Logo</span>
 | 
				
			||||||
 | 
					          <el-switch
 | 
				
			||||||
 | 
					            v-model="logoVal"
 | 
				
			||||||
 | 
					            inline-prompt
 | 
				
			||||||
 | 
					            :active-value="true"
 | 
				
			||||||
 | 
					            :inactive-value="false"
 | 
				
			||||||
 | 
					            active-text="开"
 | 
				
			||||||
 | 
					            inactive-text="关"
 | 
				
			||||||
 | 
					            @change="logoChange"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </li>
 | 
				
			||||||
 | 
					        <li>
 | 
				
			||||||
 | 
					          <span class="dark:text-white">页签持久化</span>
 | 
				
			||||||
 | 
					          <el-switch
 | 
				
			||||||
 | 
					            v-model="settings.multiTagsCache"
 | 
				
			||||||
 | 
					            inline-prompt
 | 
				
			||||||
 | 
					            active-text="开"
 | 
				
			||||||
 | 
					            inactive-text="关"
 | 
				
			||||||
 | 
					            @change="multiTagsCacheChange"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </li>
 | 
				
			||||||
 | 
					      </ul>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
  </panel>
 | 
					  </panel>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -422,41 +390,41 @@ onBeforeMount(() => {
 | 
				
			|||||||
  font-weight: 700;
 | 
					  font-weight: 700;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.is-select {
 | 
					:deep(.el-switch__core) {
 | 
				
			||||||
  border: 2px solid var(--el-color-primary);
 | 
					  --el-switch-off-color: var(--pure-switch-off-color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  min-width: 36px;
 | 
				
			||||||
 | 
					  height: 18px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.setting {
 | 
					:deep(.el-switch__core .el-switch__action) {
 | 
				
			||||||
  width: 100%;
 | 
					  height: 14px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.theme-color {
 | 
				
			||||||
 | 
					  height: 20px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  li {
 | 
					  li {
 | 
				
			||||||
    display: flex;
 | 
					    float: left;
 | 
				
			||||||
    align-items: center;
 | 
					    height: 20px;
 | 
				
			||||||
    justify-content: space-between;
 | 
					    margin-right: 8px;
 | 
				
			||||||
    margin: 25px;
 | 
					    cursor: pointer;
 | 
				
			||||||
  }
 | 
					    border-radius: 4px;
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pure-datatheme {
 | 
					    &:nth-child(2) {
 | 
				
			||||||
  display: block;
 | 
					      border: 1px solid #ddd;
 | 
				
			||||||
  width: 100%;
 | 
					    }
 | 
				
			||||||
  height: 50px;
 | 
					  }
 | 
				
			||||||
  padding-top: 25px;
 | 
					 | 
				
			||||||
  text-align: center;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pure-theme {
 | 
					.pure-theme {
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  flex-wrap: wrap;
 | 
					  gap: 12px;
 | 
				
			||||||
  justify-content: space-around;
 | 
					 | 
				
			||||||
  width: 100%;
 | 
					 | 
				
			||||||
  height: 50px;
 | 
					 | 
				
			||||||
  margin-top: 25px;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  li {
 | 
					  li {
 | 
				
			||||||
    position: relative;
 | 
					    position: relative;
 | 
				
			||||||
    width: 18%;
 | 
					    width: 46px;
 | 
				
			||||||
    height: 45px;
 | 
					    height: 36px;
 | 
				
			||||||
    overflow: hidden;
 | 
					    overflow: hidden;
 | 
				
			||||||
    cursor: pointer;
 | 
					    cursor: pointer;
 | 
				
			||||||
    background: #f0f2f5;
 | 
					    background: #f0f2f5;
 | 
				
			||||||
@ -517,27 +485,17 @@ onBeforeMount(() => {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.theme-color {
 | 
					.is-select {
 | 
				
			||||||
  display: flex;
 | 
					  border: 2px solid var(--el-color-primary);
 | 
				
			||||||
  justify-content: center;
 | 
					}
 | 
				
			||||||
  width: 100%;
 | 
					 | 
				
			||||||
  height: 40px;
 | 
					 | 
				
			||||||
  margin-top: 20px;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.setting {
 | 
				
			||||||
  li {
 | 
					  li {
 | 
				
			||||||
    float: left;
 | 
					    display: flex;
 | 
				
			||||||
    width: 20px;
 | 
					    align-items: center;
 | 
				
			||||||
    height: 20px;
 | 
					    justify-content: space-between;
 | 
				
			||||||
    margin-top: 8px;
 | 
					    padding: 4px 0;
 | 
				
			||||||
    margin-right: 8px;
 | 
					    font-size: 14px;
 | 
				
			||||||
    font-weight: 700;
 | 
					 | 
				
			||||||
    text-align: center;
 | 
					 | 
				
			||||||
    cursor: pointer;
 | 
					 | 
				
			||||||
    border-radius: 2px;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    &:nth-child(2) {
 | 
					 | 
				
			||||||
      border: 1px solid #ddd;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,14 @@
 | 
				
			|||||||
import { ref } from "vue";
 | 
					import { ref } from "vue";
 | 
				
			||||||
import { getConfig } from "@/config";
 | 
					import { getConfig } from "@/config";
 | 
				
			||||||
import { useLayout } from "./useLayout";
 | 
					import { useLayout } from "./useLayout";
 | 
				
			||||||
import { useGlobal } from "@pureadmin/utils";
 | 
					import { removeToken } from "@/utils/auth";
 | 
				
			||||||
 | 
					import { routerArrays } from "@/layout/types";
 | 
				
			||||||
 | 
					import { router, resetRouter } from "@/router";
 | 
				
			||||||
import type { themeColorsType } from "../types";
 | 
					import type { themeColorsType } from "../types";
 | 
				
			||||||
 | 
					import { useAppStoreHook } from "@/store/modules/app";
 | 
				
			||||||
 | 
					import { useGlobal, storageLocal } from "@pureadmin/utils";
 | 
				
			||||||
import { useEpThemeStoreHook } from "@/store/modules/epTheme";
 | 
					import { useEpThemeStoreHook } from "@/store/modules/epTheme";
 | 
				
			||||||
 | 
					import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  darken,
 | 
					  darken,
 | 
				
			||||||
  lighten,
 | 
					  lighten,
 | 
				
			||||||
@ -37,6 +42,13 @@ export function useDataThemeChange() {
 | 
				
			|||||||
  const dataTheme = ref<boolean>($storage?.layout?.darkMode);
 | 
					  const dataTheme = ref<boolean>($storage?.layout?.darkMode);
 | 
				
			||||||
  const body = document.documentElement as HTMLElement;
 | 
					  const body = document.documentElement as HTMLElement;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function toggleClass(flag: boolean, clsName: string, target?: HTMLElement) {
 | 
				
			||||||
 | 
					    const targetEl = target || document.body;
 | 
				
			||||||
 | 
					    let { className } = targetEl;
 | 
				
			||||||
 | 
					    className = className.replace(clsName, "").trim();
 | 
				
			||||||
 | 
					    targetEl.className = flag ? `${className} ${clsName} ` : className;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** 设置导航主题色 */
 | 
					  /** 设置导航主题色 */
 | 
				
			||||||
  function setLayoutThemeColor(theme = getConfig().Theme ?? "default") {
 | 
					  function setLayoutThemeColor(theme = getConfig().Theme ?? "default") {
 | 
				
			||||||
    layoutTheme.value.theme = theme;
 | 
					    layoutTheme.value.theme = theme;
 | 
				
			||||||
@ -78,9 +90,8 @@ export function useDataThemeChange() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** 日间、夜间主题切换 */
 | 
					  /** 亮色、暗色整体风格切换 */
 | 
				
			||||||
  function dataThemeChange() {
 | 
					  function dataThemeChange() {
 | 
				
			||||||
    /* 如果当前是light夜间主题,默认切换到default主题 */
 | 
					 | 
				
			||||||
    if (useEpThemeStoreHook().epTheme === "light" && dataTheme.value) {
 | 
					    if (useEpThemeStoreHook().epTheme === "light" && dataTheme.value) {
 | 
				
			||||||
      setLayoutThemeColor("default");
 | 
					      setLayoutThemeColor("default");
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@ -94,11 +105,28 @@ export function useDataThemeChange() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** 清空缓存并返回登录页 */
 | 
				
			||||||
 | 
					  function onReset() {
 | 
				
			||||||
 | 
					    removeToken();
 | 
				
			||||||
 | 
					    storageLocal().clear();
 | 
				
			||||||
 | 
					    const { Grey, Weak, MultiTagsCache, EpThemeColor, Layout } = getConfig();
 | 
				
			||||||
 | 
					    useAppStoreHook().setLayout(Layout);
 | 
				
			||||||
 | 
					    setEpThemeColor(EpThemeColor);
 | 
				
			||||||
 | 
					    useMultiTagsStoreHook().multiTagsCacheChange(MultiTagsCache);
 | 
				
			||||||
 | 
					    toggleClass(Grey, "html-grey", document.querySelector("html"));
 | 
				
			||||||
 | 
					    toggleClass(Weak, "html-weakness", document.querySelector("html"));
 | 
				
			||||||
 | 
					    router.push("/login");
 | 
				
			||||||
 | 
					    useMultiTagsStoreHook().handleTags("equal", [...routerArrays]);
 | 
				
			||||||
 | 
					    resetRouter();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    body,
 | 
					    body,
 | 
				
			||||||
    dataTheme,
 | 
					    dataTheme,
 | 
				
			||||||
    layoutTheme,
 | 
					    layoutTheme,
 | 
				
			||||||
    themeColors,
 | 
					    themeColors,
 | 
				
			||||||
 | 
					    onReset,
 | 
				
			||||||
 | 
					    toggleClass,
 | 
				
			||||||
    dataThemeChange,
 | 
					    dataThemeChange,
 | 
				
			||||||
    setEpThemeColor,
 | 
					    setEpThemeColor,
 | 
				
			||||||
    setLayoutThemeColor
 | 
					    setLayoutThemeColor
 | 
				
			||||||
 | 
				
			|||||||
@ -45,6 +45,14 @@ app.component("FontIcon", FontIcon);
 | 
				
			|||||||
import { Auth } from "@/components/ReAuth";
 | 
					import { Auth } from "@/components/ReAuth";
 | 
				
			||||||
app.component("Auth", Auth);
 | 
					app.component("Auth", Auth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 全局注册`vue-tippy`
 | 
				
			||||||
 | 
					import "tippy.js/dist/tippy.css";
 | 
				
			||||||
 | 
					import "tippy.js/animations/perspective.css";
 | 
				
			||||||
 | 
					import VueTippy from "vue-tippy";
 | 
				
			||||||
 | 
					app.use(VueTippy, {
 | 
				
			||||||
 | 
					  defaultProps: { animation: "perspective" }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
getPlatformConfig(app).then(async config => {
 | 
					getPlatformConfig(app).then(async config => {
 | 
				
			||||||
  setupStore(app);
 | 
					  setupStore(app);
 | 
				
			||||||
  app.use(router);
 | 
					  app.use(router);
 | 
				
			||||||
 | 
				
			|||||||
@ -2,11 +2,18 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* 暗黑模式适配 */
 | 
					/* 暗黑模式适配 */
 | 
				
			||||||
html.dark {
 | 
					html.dark {
 | 
				
			||||||
  /* 自定义深色背景颜色 */
 | 
					 | 
				
			||||||
  // --el-bg-color: #020409;
 | 
					 | 
				
			||||||
  $border-style: #303030;
 | 
					  $border-style: #303030;
 | 
				
			||||||
  $color-white: #fff;
 | 
					  $color-white: #fff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* 自定义深色背景颜色 */
 | 
				
			||||||
 | 
					  // --el-bg-color: #020409;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* 常用border-color 需要时可取用 */
 | 
				
			||||||
 | 
					  --pure-border-color: rgb(253 253 253 / 12%);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* switch关闭状态下的color 需要时可取用 */
 | 
				
			||||||
 | 
					  --pure-switch-off-color: #ffffff3f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .navbar,
 | 
					  .navbar,
 | 
				
			||||||
  .tags-view,
 | 
					  .tags-view,
 | 
				
			||||||
  .contextmenu,
 | 
					  .contextmenu,
 | 
				
			||||||
 | 
				
			|||||||
@ -50,12 +50,6 @@
 | 
				
			|||||||
  padding: 0 !important;
 | 
					  padding: 0 !important;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 自定义 tooltip 的类名 */
 | 
					 | 
				
			||||||
.pure-tooltip {
 | 
					 | 
				
			||||||
  // 右侧操作面板right-panel类名的z-index为40000,tooltip需要大于它才能显示
 | 
					 | 
				
			||||||
  z-index: 41000 !important;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* nprogress 适配 element-plus 的主题色 */
 | 
					/* nprogress 适配 element-plus 的主题色 */
 | 
				
			||||||
#nprogress {
 | 
					#nprogress {
 | 
				
			||||||
  & .bar {
 | 
					  & .bar {
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,12 @@
 | 
				
			|||||||
:root {
 | 
					:root {
 | 
				
			||||||
  /* 左侧菜单展开、收起动画时长 */
 | 
					  /* 左侧菜单展开、收起动画时长 */
 | 
				
			||||||
  --pure-transition-duration: 0.3s;
 | 
					  --pure-transition-duration: 0.3s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* 常用border-color 需要时可取用 */
 | 
				
			||||||
 | 
					  --pure-border-color: rgb(5 5 5 / 6%);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* switch关闭状态下的color 需要时可取用 */
 | 
				
			||||||
 | 
					  --pure-switch-off-color: #a6a6a6;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 灰色模式 */
 | 
					/* 灰色模式 */
 | 
				
			||||||
 | 
				
			|||||||
@ -4,15 +4,10 @@ import { getTime } from "@pureadmin/utils";
 | 
				
			|||||||
import { Play, Pause, Forward, Rewind } from "./svg";
 | 
					import { Play, Pause, Forward, Rewind } from "./svg";
 | 
				
			||||||
import { ref, onMounted, onBeforeUnmount } from "vue";
 | 
					import { ref, onMounted, onBeforeUnmount } from "vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "tippy.js/dist/tippy.css";
 | 
					 | 
				
			||||||
import "tippy.js/animations/scale.css";
 | 
					 | 
				
			||||||
import { directive as tippy } from "vue-tippy";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
defineOptions({
 | 
					defineOptions({
 | 
				
			||||||
  name: "Wavesurfer"
 | 
					  name: "Wavesurfer"
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const vTippy = tippy;
 | 
					 | 
				
			||||||
const loading = ref(true);
 | 
					const loading = ref(true);
 | 
				
			||||||
const wavesurfer = ref(null);
 | 
					const wavesurfer = ref(null);
 | 
				
			||||||
const wavesurferRef = ref();
 | 
					const wavesurferRef = ref();
 | 
				
			||||||
@ -114,8 +109,7 @@ onBeforeUnmount(() => {
 | 
				
			|||||||
        <Rewind
 | 
					        <Rewind
 | 
				
			||||||
          v-tippy="{
 | 
					          v-tippy="{
 | 
				
			||||||
            content: '快退(可长按)',
 | 
					            content: '快退(可长按)',
 | 
				
			||||||
            placement: 'bottom',
 | 
					            placement: 'bottom'
 | 
				
			||||||
            animation: 'scale'
 | 
					 | 
				
			||||||
          }"
 | 
					          }"
 | 
				
			||||||
          v-longpress:0:100="() => wavesurfer?.skip(-1)"
 | 
					          v-longpress:0:100="() => wavesurfer?.skip(-1)"
 | 
				
			||||||
          class="cursor-pointer"
 | 
					          class="cursor-pointer"
 | 
				
			||||||
@ -123,8 +117,7 @@ onBeforeUnmount(() => {
 | 
				
			|||||||
        <div
 | 
					        <div
 | 
				
			||||||
          v-tippy="{
 | 
					          v-tippy="{
 | 
				
			||||||
            content: isPlay ? '暂停' : '播放',
 | 
					            content: isPlay ? '暂停' : '播放',
 | 
				
			||||||
            placement: 'bottom',
 | 
					            placement: 'bottom'
 | 
				
			||||||
            animation: 'scale'
 | 
					 | 
				
			||||||
          }"
 | 
					          }"
 | 
				
			||||||
          class="cursor-pointer"
 | 
					          class="cursor-pointer"
 | 
				
			||||||
          @click="wavesurfer?.playPause()"
 | 
					          @click="wavesurfer?.playPause()"
 | 
				
			||||||
@ -135,8 +128,7 @@ onBeforeUnmount(() => {
 | 
				
			|||||||
        <Forward
 | 
					        <Forward
 | 
				
			||||||
          v-tippy="{
 | 
					          v-tippy="{
 | 
				
			||||||
            content: '快进(可长按)',
 | 
					            content: '快进(可长按)',
 | 
				
			||||||
            placement: 'bottom',
 | 
					            placement: 'bottom'
 | 
				
			||||||
            animation: 'scale'
 | 
					 | 
				
			||||||
          }"
 | 
					          }"
 | 
				
			||||||
          v-longpress:0:100="() => wavesurfer?.skip(1)"
 | 
					          v-longpress:0:100="() => wavesurfer?.skip(1)"
 | 
				
			||||||
          class="cursor-pointer"
 | 
					          class="cursor-pointer"
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user