mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +08:00 
			
		
		
		
	perf: layout (#50)
This commit is contained in:
		
							parent
							
								
									77b7abcbc3
								
							
						
					
					
						commit
						6b16a04229
					
				
							
								
								
									
										1
									
								
								src/assets/svg/globalization.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/assets/svg/globalization.svg
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="globalization" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 512 512"><path d="M478.33 433.6l-90-218a22 22 0 0 0-40.67 0l-90 218a22 22 0 1 0 40.67 16.79L316.66 406h102.67l18.33 44.39A22 22 0 0 0 458 464a22 22 0 0 0 20.32-30.4zM334.83 362L368 281.65L401.17 362z" fill="currentColor"></path><path d="M267.84 342.92a22 22 0 0 0-4.89-30.7c-.2-.15-15-11.13-36.49-34.73c39.65-53.68 62.11-114.75 71.27-143.49H330a22 22 0 0 0 0-44H214V70a22 22 0 0 0-44 0v20H54a22 22 0 0 0 0 44h197.25c-9.52 26.95-27.05 69.5-53.79 108.36c-31.41-41.68-43.08-68.65-43.17-68.87a22 22 0 0 0-40.58 17c.58 1.38 14.55 34.23 52.86 83.93c.92 1.19 1.83 2.35 2.74 3.51c-39.24 44.35-77.74 71.86-93.85 80.74a22 22 0 1 0 21.07 38.63c2.16-1.18 48.6-26.89 101.63-85.59c22.52 24.08 38 35.44 38.93 36.1a22 22 0 0 0 30.75-4.9z" fill="currentColor"></path></svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 965 B  | 
@ -1 +0,0 @@
 | 
				
			|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconinternationality" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 512 512"><path d="M478.33 433.6l-90-218a22 22 0 0 0-40.67 0l-90 218a22 22 0 1 0 40.67 16.79L316.66 406h102.67l18.33 44.39A22 22 0 0 0 458 464a22 22 0 0 0 20.32-30.4zM334.83 362L368 281.65L401.17 362z" fill="currentColor"></path><path d="M267.84 342.92a22 22 0 0 0-4.89-30.7c-.2-.15-15-11.13-36.49-34.73c39.65-53.68 62.11-114.75 71.27-143.49H330a22 22 0 0 0 0-44H214V70a22 22 0 0 0-44 0v20H54a22 22 0 0 0 0 44h197.25c-9.52 26.95-27.05 69.5-53.79 108.36c-31.41-41.68-43.08-68.65-43.17-68.87a22 22 0 0 0-40.58 17c.58 1.38 14.55 34.23 52.86 83.93c.92 1.19 1.83 2.35 2.74 3.51c-39.24 44.35-77.74 71.86-93.85 80.74a22 22 0 1 0 21.07 38.63c2.16-1.18 48.6-26.89 101.63-85.59c22.52 24.08 38 35.44 38.93 36.1a22 22 0 0 0 30.75-4.9z" fill="currentColor"></path></svg>
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 972 B  | 
@ -1,10 +0,0 @@
 | 
				
			|||||||
import { App } from "vue";
 | 
					 | 
				
			||||||
import reBreadCrumb from "./src/index.vue";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const ReBreadCrumb = Object.assign(reBreadCrumb, {
 | 
					 | 
				
			||||||
  install(app: App) {
 | 
					 | 
				
			||||||
    app.component(reBreadCrumb.name, reBreadCrumb);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default ReBreadCrumb;
 | 
					 | 
				
			||||||
@ -1,3 +1,14 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { ref } from "vue";
 | 
				
			||||||
 | 
					const lists = ref<ForDataType<undefined>>([
 | 
				
			||||||
 | 
					  { type: "", label: "善良" },
 | 
				
			||||||
 | 
					  { type: "success", label: "好学" },
 | 
				
			||||||
 | 
					  { type: "info", label: "幽默" },
 | 
				
			||||||
 | 
					  { type: "danger", label: "旅游" },
 | 
				
			||||||
 | 
					  { type: "warning", label: "追剧" }
 | 
				
			||||||
 | 
					]);
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <el-descriptions
 | 
					  <el-descriptions
 | 
				
			||||||
    class="margin-top"
 | 
					    class="margin-top"
 | 
				
			||||||
@ -75,17 +86,6 @@
 | 
				
			|||||||
  </el-descriptions>
 | 
					  </el-descriptions>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script setup lang="ts">
 | 
					 | 
				
			||||||
import { ref } from "vue";
 | 
					 | 
				
			||||||
const lists = ref<ForDataType<undefined>>([
 | 
					 | 
				
			||||||
  { type: "", label: "善良" },
 | 
					 | 
				
			||||||
  { type: "success", label: "好学" },
 | 
					 | 
				
			||||||
  { type: "info", label: "幽默" },
 | 
					 | 
				
			||||||
  { type: "danger", label: "旅游" },
 | 
					 | 
				
			||||||
  { type: "warning", label: "追剧" }
 | 
					 | 
				
			||||||
]);
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style scoped>
 | 
					<style scoped>
 | 
				
			||||||
.el-tag--mini {
 | 
					.el-tag--mini {
 | 
				
			||||||
  margin-right: 10px !important;
 | 
					  margin-right: 10px !important;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +0,0 @@
 | 
				
			|||||||
import { App } from "vue";
 | 
					 | 
				
			||||||
import reHamBurger from "./src/index.vue";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const ReHamBurger = Object.assign(reHamBurger, {
 | 
					 | 
				
			||||||
  install(app: App) {
 | 
					 | 
				
			||||||
    app.component(reHamBurger.name, reHamBurger);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default ReHamBurger;
 | 
					 | 
				
			||||||
@ -1,3 +1,59 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { useI18n } from "vue-i18n";
 | 
				
			||||||
 | 
					import { emitter } from "/@/utils/mitt";
 | 
				
			||||||
 | 
					import Hamburger from "./sidebar/hamBurger.vue";
 | 
				
			||||||
 | 
					import { useRouter, useRoute } from "vue-router";
 | 
				
			||||||
 | 
					import { storageSession } from "/@/utils/storage";
 | 
				
			||||||
 | 
					import Breadcrumb from "./sidebar/breadCrumb.vue";
 | 
				
			||||||
 | 
					import { useAppStoreHook } from "/@/store/modules/app";
 | 
				
			||||||
 | 
					import { unref, watch, getCurrentInstance } from "vue";
 | 
				
			||||||
 | 
					import { deviceDetection } from "/@/utils/deviceDetection";
 | 
				
			||||||
 | 
					import screenfull from "../components/screenfull/index.vue";
 | 
				
			||||||
 | 
					import globalization from "/@/assets/svg/globalization.svg";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const instance =
 | 
				
			||||||
 | 
					  getCurrentInstance().appContext.config.globalProperties.$storage;
 | 
				
			||||||
 | 
					const pureApp = useAppStoreHook();
 | 
				
			||||||
 | 
					const router = useRouter();
 | 
				
			||||||
 | 
					const route = useRoute();
 | 
				
			||||||
 | 
					let usename = storageSession.getItem("info")?.username;
 | 
				
			||||||
 | 
					const { locale, t } = useI18n();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					watch(
 | 
				
			||||||
 | 
					  () => locale.value,
 | 
				
			||||||
 | 
					  () => {
 | 
				
			||||||
 | 
					    //@ts-ignore
 | 
				
			||||||
 | 
					    document.title = t(unref(route.meta.title)); // 动态title
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 退出登录
 | 
				
			||||||
 | 
					const logout = (): void => {
 | 
				
			||||||
 | 
					  storageSession.removeItem("info");
 | 
				
			||||||
 | 
					  router.push("/login");
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onPanel() {
 | 
				
			||||||
 | 
					  emitter.emit("openPanel");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function toggleSideBar() {
 | 
				
			||||||
 | 
					  pureApp.toggleSideBar();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 简体中文
 | 
				
			||||||
 | 
					function translationCh() {
 | 
				
			||||||
 | 
					  instance.locale = { locale: "zh" };
 | 
				
			||||||
 | 
					  locale.value = "zh";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// English
 | 
				
			||||||
 | 
					function translationEn() {
 | 
				
			||||||
 | 
					  instance.locale = { locale: "en" };
 | 
				
			||||||
 | 
					  locale.value = "en";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="navbar">
 | 
					  <div class="navbar">
 | 
				
			||||||
    <Hamburger
 | 
					    <Hamburger
 | 
				
			||||||
@ -13,7 +69,7 @@
 | 
				
			|||||||
      <screenfull v-show="!deviceDetection()" />
 | 
					      <screenfull v-show="!deviceDetection()" />
 | 
				
			||||||
      <!-- 国际化 -->
 | 
					      <!-- 国际化 -->
 | 
				
			||||||
      <el-dropdown trigger="click">
 | 
					      <el-dropdown trigger="click">
 | 
				
			||||||
        <iconinternationality />
 | 
					        <globalization />
 | 
				
			||||||
        <template #dropdown>
 | 
					        <template #dropdown>
 | 
				
			||||||
          <el-dropdown-menu class="translation">
 | 
					          <el-dropdown-menu class="translation">
 | 
				
			||||||
            <el-dropdown-item
 | 
					            <el-dropdown-item
 | 
				
			||||||
@ -60,99 +116,6 @@
 | 
				
			|||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					 | 
				
			||||||
import { defineComponent, unref, watch, getCurrentInstance } from "vue";
 | 
					 | 
				
			||||||
import Breadcrumb from "/@/components/ReBreadCrumb";
 | 
					 | 
				
			||||||
import Hamburger from "/@/components/ReHamBurger";
 | 
					 | 
				
			||||||
import screenfull from "../components/screenfull/index.vue";
 | 
					 | 
				
			||||||
import { useRouter, useRoute } from "vue-router";
 | 
					 | 
				
			||||||
import { useAppStoreHook } from "/@/store/modules/app";
 | 
					 | 
				
			||||||
import { storageSession } from "/@/utils/storage";
 | 
					 | 
				
			||||||
import favicon from "/favicon.ico";
 | 
					 | 
				
			||||||
import { emitter } from "/@/utils/mitt";
 | 
					 | 
				
			||||||
import { deviceDetection } from "/@/utils/deviceDetection";
 | 
					 | 
				
			||||||
import { useI18n } from "vue-i18n";
 | 
					 | 
				
			||||||
import iconinternationality from "/@/assets/svg/iconinternationality.svg";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineComponent({
 | 
					 | 
				
			||||||
  name: "Navbar",
 | 
					 | 
				
			||||||
  components: {
 | 
					 | 
				
			||||||
    Breadcrumb,
 | 
					 | 
				
			||||||
    Hamburger,
 | 
					 | 
				
			||||||
    screenfull,
 | 
					 | 
				
			||||||
    iconinternationality
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // @ts-ignore
 | 
					 | 
				
			||||||
  computed: {
 | 
					 | 
				
			||||||
    // eslint-disable-next-line vue/return-in-computed-property
 | 
					 | 
				
			||||||
    currentLocale() {
 | 
					 | 
				
			||||||
      switch (this.$storage.locale?.locale) {
 | 
					 | 
				
			||||||
        case "zh":
 | 
					 | 
				
			||||||
          return true;
 | 
					 | 
				
			||||||
        case "en":
 | 
					 | 
				
			||||||
          return false;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  setup() {
 | 
					 | 
				
			||||||
    const instance =
 | 
					 | 
				
			||||||
      getCurrentInstance().appContext.config.globalProperties.$storage;
 | 
					 | 
				
			||||||
    const pureApp = useAppStoreHook();
 | 
					 | 
				
			||||||
    const router = useRouter();
 | 
					 | 
				
			||||||
    const route = useRoute();
 | 
					 | 
				
			||||||
    let usename = storageSession.getItem("info")?.username;
 | 
					 | 
				
			||||||
    const { locale, t } = useI18n();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    watch(
 | 
					 | 
				
			||||||
      () => locale.value,
 | 
					 | 
				
			||||||
      () => {
 | 
					 | 
				
			||||||
        //@ts-ignore
 | 
					 | 
				
			||||||
        document.title = t(unref(route.meta.title)); // 动态title
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 退出登录
 | 
					 | 
				
			||||||
    const logout = (): void => {
 | 
					 | 
				
			||||||
      storageSession.removeItem("info");
 | 
					 | 
				
			||||||
      router.push("/login");
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function onPanel() {
 | 
					 | 
				
			||||||
      emitter.emit("openPanel");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function toggleSideBar() {
 | 
					 | 
				
			||||||
      pureApp.toggleSideBar();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 简体中文
 | 
					 | 
				
			||||||
    function translationCh() {
 | 
					 | 
				
			||||||
      instance.locale = { locale: "zh" };
 | 
					 | 
				
			||||||
      locale.value = "zh";
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // English
 | 
					 | 
				
			||||||
    function translationEn() {
 | 
					 | 
				
			||||||
      instance.locale = { locale: "en" };
 | 
					 | 
				
			||||||
      locale.value = "en";
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
      locale,
 | 
					 | 
				
			||||||
      usename,
 | 
					 | 
				
			||||||
      pureApp,
 | 
					 | 
				
			||||||
      favicon,
 | 
					 | 
				
			||||||
      logout,
 | 
					 | 
				
			||||||
      onPanel,
 | 
					 | 
				
			||||||
      translationCh,
 | 
					 | 
				
			||||||
      translationEn,
 | 
					 | 
				
			||||||
      toggleSideBar,
 | 
					 | 
				
			||||||
      deviceDetection
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss" scoped>
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
.navbar {
 | 
					.navbar {
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
@ -190,7 +153,7 @@ export default defineComponent({
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .iconinternationality {
 | 
					    .globalization {
 | 
				
			||||||
      height: 48px;
 | 
					      height: 48px;
 | 
				
			||||||
      width: 40px;
 | 
					      width: 40px;
 | 
				
			||||||
      padding: 11px;
 | 
					      padding: 11px;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,114 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  computed,
 | 
				
			||||||
 | 
					  unref,
 | 
				
			||||||
 | 
					  watch,
 | 
				
			||||||
 | 
					  nextTick,
 | 
				
			||||||
 | 
					  onMounted,
 | 
				
			||||||
 | 
					  getCurrentInstance
 | 
				
			||||||
 | 
					} from "vue";
 | 
				
			||||||
 | 
					import { useI18n } from "vue-i18n";
 | 
				
			||||||
 | 
					import settings from "/@/settings";
 | 
				
			||||||
 | 
					import { emitter } from "/@/utils/mitt";
 | 
				
			||||||
 | 
					import { templateRef } from "@vueuse/core";
 | 
				
			||||||
 | 
					import SidebarItem from "./sidebarItem.vue";
 | 
				
			||||||
 | 
					import { algorithm } from "/@/utils/algorithm";
 | 
				
			||||||
 | 
					import screenfull from "../screenfull/index.vue";
 | 
				
			||||||
 | 
					import { useRoute, useRouter } from "vue-router";
 | 
				
			||||||
 | 
					import { storageSession } from "/@/utils/storage";
 | 
				
			||||||
 | 
					import { deviceDetection } from "/@/utils/deviceDetection";
 | 
				
			||||||
 | 
					import globalization from "/@/assets/svg/globalization.svg";
 | 
				
			||||||
 | 
					import { usePermissionStoreHook } from "/@/store/modules/permission";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const instance =
 | 
				
			||||||
 | 
					  getCurrentInstance().appContext.config.globalProperties.$storage;
 | 
				
			||||||
 | 
					const menuRef = templateRef<ElRef | null>("menu", null);
 | 
				
			||||||
 | 
					const routeStore = usePermissionStoreHook();
 | 
				
			||||||
 | 
					const route = useRoute();
 | 
				
			||||||
 | 
					const router = useRouter();
 | 
				
			||||||
 | 
					const routers = useRouter().options.routes;
 | 
				
			||||||
 | 
					let usename = storageSession.getItem("info")?.username;
 | 
				
			||||||
 | 
					const { locale, t } = useI18n();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					watch(
 | 
				
			||||||
 | 
					  () => locale.value,
 | 
				
			||||||
 | 
					  () => {
 | 
				
			||||||
 | 
					    //@ts-ignore
 | 
				
			||||||
 | 
					    // 动态title
 | 
				
			||||||
 | 
					    document.title = t(unref(route.meta.title));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 退出登录
 | 
				
			||||||
 | 
					const logout = (): void => {
 | 
				
			||||||
 | 
					  storageSession.removeItem("info");
 | 
				
			||||||
 | 
					  router.push("/login");
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onPanel() {
 | 
				
			||||||
 | 
					  emitter.emit("openPanel");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const activeMenu = computed(() => {
 | 
				
			||||||
 | 
					  const { meta, path } = route;
 | 
				
			||||||
 | 
					  if (meta.activeMenu) {
 | 
				
			||||||
 | 
					    return meta.activeMenu;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return path;
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const menuSelect = (indexPath: string): void => {
 | 
				
			||||||
 | 
					  let parentPath = "";
 | 
				
			||||||
 | 
					  let parentPathIndex = indexPath.lastIndexOf("/");
 | 
				
			||||||
 | 
					  if (parentPathIndex > 0) {
 | 
				
			||||||
 | 
					    parentPath = indexPath.slice(0, parentPathIndex);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 找到当前路由的信息
 | 
				
			||||||
 | 
					  function findCurrentRoute(routes) {
 | 
				
			||||||
 | 
					    return routes.map(item => {
 | 
				
			||||||
 | 
					      if (item.path === indexPath) {
 | 
				
			||||||
 | 
					        // 切换左侧菜单 通知标签页
 | 
				
			||||||
 | 
					        emitter.emit("changLayoutRoute", {
 | 
				
			||||||
 | 
					          indexPath,
 | 
				
			||||||
 | 
					          parentPath
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        if (item.children) findCurrentRoute(item.children);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  findCurrentRoute(algorithm.increaseIndexes(routers));
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function backHome() {
 | 
				
			||||||
 | 
					  router.push("/welcome");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function handleResize() {
 | 
				
			||||||
 | 
					  menuRef.value.handleResize();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 简体中文
 | 
				
			||||||
 | 
					function translationCh() {
 | 
				
			||||||
 | 
					  instance.locale = { locale: "zh" };
 | 
				
			||||||
 | 
					  locale.value = "zh";
 | 
				
			||||||
 | 
					  handleResize();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// English
 | 
				
			||||||
 | 
					function translationEn() {
 | 
				
			||||||
 | 
					  instance.locale = { locale: "en" };
 | 
				
			||||||
 | 
					  locale.value = "en";
 | 
				
			||||||
 | 
					  handleResize();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onMounted(() => {
 | 
				
			||||||
 | 
					  nextTick(() => {
 | 
				
			||||||
 | 
					    handleResize();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="horizontal-header">
 | 
					  <div class="horizontal-header">
 | 
				
			||||||
    <div class="horizontal-header-left" @click="backHome">
 | 
					    <div class="horizontal-header-left" @click="backHome">
 | 
				
			||||||
@ -25,7 +136,7 @@
 | 
				
			|||||||
      <screenfull v-show="!deviceDetection()" />
 | 
					      <screenfull v-show="!deviceDetection()" />
 | 
				
			||||||
      <!-- 国际化 -->
 | 
					      <!-- 国际化 -->
 | 
				
			||||||
      <el-dropdown trigger="click">
 | 
					      <el-dropdown trigger="click">
 | 
				
			||||||
        <iconinternationality />
 | 
					        <globalization />
 | 
				
			||||||
        <template #dropdown>
 | 
					        <template #dropdown>
 | 
				
			||||||
          <el-dropdown-menu class="translation">
 | 
					          <el-dropdown-menu class="translation">
 | 
				
			||||||
            <el-dropdown-item
 | 
					            <el-dropdown-item
 | 
				
			||||||
@ -72,177 +183,6 @@
 | 
				
			|||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  computed,
 | 
					 | 
				
			||||||
  defineComponent,
 | 
					 | 
				
			||||||
  unref,
 | 
					 | 
				
			||||||
  watch,
 | 
					 | 
				
			||||||
  nextTick,
 | 
					 | 
				
			||||||
  onMounted,
 | 
					 | 
				
			||||||
  getCurrentInstance
 | 
					 | 
				
			||||||
} from "vue";
 | 
					 | 
				
			||||||
import { useI18n } from "vue-i18n";
 | 
					 | 
				
			||||||
import settings from "/@/settings";
 | 
					 | 
				
			||||||
import { emitter } from "/@/utils/mitt";
 | 
					 | 
				
			||||||
import { templateRef } from "@vueuse/core";
 | 
					 | 
				
			||||||
import SidebarItem from "./sidebarItem.vue";
 | 
					 | 
				
			||||||
import { algorithm } from "/@/utils/algorithm";
 | 
					 | 
				
			||||||
import screenfull from "../screenfull/index.vue";
 | 
					 | 
				
			||||||
import { useRoute, useRouter } from "vue-router";
 | 
					 | 
				
			||||||
import { storageSession } from "/@/utils/storage";
 | 
					 | 
				
			||||||
import { deviceDetection } from "/@/utils/deviceDetection";
 | 
					 | 
				
			||||||
import { usePermissionStoreHook } from "/@/store/modules/permission";
 | 
					 | 
				
			||||||
import iconinternationality from "/@/assets/svg/iconinternationality.svg";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
let routerArrays: Array<object> = [
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    path: "/welcome",
 | 
					 | 
				
			||||||
    parentPath: "/",
 | 
					 | 
				
			||||||
    meta: {
 | 
					 | 
				
			||||||
      title: "message.hshome",
 | 
					 | 
				
			||||||
      icon: "el-icon-s-home",
 | 
					 | 
				
			||||||
      showLink: true,
 | 
					 | 
				
			||||||
      savedPosition: false
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
export default defineComponent({
 | 
					 | 
				
			||||||
  name: "sidebar",
 | 
					 | 
				
			||||||
  components: { SidebarItem, screenfull, iconinternationality },
 | 
					 | 
				
			||||||
  // @ts-ignore
 | 
					 | 
				
			||||||
  computed: {
 | 
					 | 
				
			||||||
    // eslint-disable-next-line vue/return-in-computed-property
 | 
					 | 
				
			||||||
    currentLocale() {
 | 
					 | 
				
			||||||
      if (
 | 
					 | 
				
			||||||
        !this.$storage.routesInStorage ||
 | 
					 | 
				
			||||||
        this.$storage.routesInStorage.length === 0
 | 
					 | 
				
			||||||
      ) {
 | 
					 | 
				
			||||||
        // eslint-disable-next-line vue/no-side-effects-in-computed-properties
 | 
					 | 
				
			||||||
        this.$storage.routesInStorage = routerArrays;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (!this.$storage.locale) {
 | 
					 | 
				
			||||||
        // eslint-disable-next-line
 | 
					 | 
				
			||||||
        this.$storage.locale = { locale: "zh" };
 | 
					 | 
				
			||||||
        useI18n().locale.value = "zh";
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      switch (this.$storage.locale?.locale) {
 | 
					 | 
				
			||||||
        case "zh":
 | 
					 | 
				
			||||||
          return true;
 | 
					 | 
				
			||||||
        case "en":
 | 
					 | 
				
			||||||
          return false;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  setup() {
 | 
					 | 
				
			||||||
    const instance =
 | 
					 | 
				
			||||||
      getCurrentInstance().appContext.config.globalProperties.$storage;
 | 
					 | 
				
			||||||
    const menuRef = templateRef<ElRef | null>("menu", null);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const routeStore = usePermissionStoreHook();
 | 
					 | 
				
			||||||
    const route = useRoute();
 | 
					 | 
				
			||||||
    const router = useRouter();
 | 
					 | 
				
			||||||
    const routers = useRouter().options.routes;
 | 
					 | 
				
			||||||
    let usename = storageSession.getItem("info")?.username;
 | 
					 | 
				
			||||||
    const { locale, t } = useI18n();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    watch(
 | 
					 | 
				
			||||||
      () => locale.value,
 | 
					 | 
				
			||||||
      () => {
 | 
					 | 
				
			||||||
        //@ts-ignore
 | 
					 | 
				
			||||||
        // 动态title
 | 
					 | 
				
			||||||
        document.title = t(unref(route.meta.title));
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 退出登录
 | 
					 | 
				
			||||||
    const logout = (): void => {
 | 
					 | 
				
			||||||
      storageSession.removeItem("info");
 | 
					 | 
				
			||||||
      router.push("/login");
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function onPanel() {
 | 
					 | 
				
			||||||
      emitter.emit("openPanel");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const activeMenu = computed(() => {
 | 
					 | 
				
			||||||
      const { meta, path } = route;
 | 
					 | 
				
			||||||
      if (meta.activeMenu) {
 | 
					 | 
				
			||||||
        return meta.activeMenu;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return path;
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const menuSelect = (indexPath: string): void => {
 | 
					 | 
				
			||||||
      let parentPath = "";
 | 
					 | 
				
			||||||
      let parentPathIndex = indexPath.lastIndexOf("/");
 | 
					 | 
				
			||||||
      if (parentPathIndex > 0) {
 | 
					 | 
				
			||||||
        parentPath = indexPath.slice(0, parentPathIndex);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      // 找到当前路由的信息
 | 
					 | 
				
			||||||
      function findCurrentRoute(routes) {
 | 
					 | 
				
			||||||
        return routes.map(item => {
 | 
					 | 
				
			||||||
          if (item.path === indexPath) {
 | 
					 | 
				
			||||||
            // 切换左侧菜单 通知标签页
 | 
					 | 
				
			||||||
            emitter.emit("changLayoutRoute", {
 | 
					 | 
				
			||||||
              indexPath,
 | 
					 | 
				
			||||||
              parentPath
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            if (item.children) findCurrentRoute(item.children);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      findCurrentRoute(algorithm.increaseIndexes(routers));
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function backHome() {
 | 
					 | 
				
			||||||
      router.push("/welcome");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function handleResize() {
 | 
					 | 
				
			||||||
      menuRef.value.handleResize();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 简体中文
 | 
					 | 
				
			||||||
    function translationCh() {
 | 
					 | 
				
			||||||
      instance.locale = { locale: "zh" };
 | 
					 | 
				
			||||||
      locale.value = "zh";
 | 
					 | 
				
			||||||
      handleResize();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // English
 | 
					 | 
				
			||||||
    function translationEn() {
 | 
					 | 
				
			||||||
      instance.locale = { locale: "en" };
 | 
					 | 
				
			||||||
      locale.value = "en";
 | 
					 | 
				
			||||||
      handleResize();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    onMounted(() => {
 | 
					 | 
				
			||||||
      nextTick(() => {
 | 
					 | 
				
			||||||
        handleResize();
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
      locale,
 | 
					 | 
				
			||||||
      usename,
 | 
					 | 
				
			||||||
      settings,
 | 
					 | 
				
			||||||
      routeStore,
 | 
					 | 
				
			||||||
      activeMenu,
 | 
					 | 
				
			||||||
      logout,
 | 
					 | 
				
			||||||
      onPanel,
 | 
					 | 
				
			||||||
      backHome,
 | 
					 | 
				
			||||||
      menuSelect,
 | 
					 | 
				
			||||||
      translationCh,
 | 
					 | 
				
			||||||
      translationEn,
 | 
					 | 
				
			||||||
      deviceDetection
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss" scoped>
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
.translation {
 | 
					.translation {
 | 
				
			||||||
  .el-dropdown-menu__item {
 | 
					  .el-dropdown-menu__item {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,61 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import Logo from "./logo.vue";
 | 
				
			||||||
 | 
					import { emitter } from "/@/utils/mitt";
 | 
				
			||||||
 | 
					import SidebarItem from "./sidebarItem.vue";
 | 
				
			||||||
 | 
					import { algorithm } from "/@/utils/algorithm";
 | 
				
			||||||
 | 
					import { storageLocal } from "/@/utils/storage";
 | 
				
			||||||
 | 
					import { useRoute, useRouter } from "vue-router";
 | 
				
			||||||
 | 
					import { computed, ref, onBeforeMount } from "vue";
 | 
				
			||||||
 | 
					import { useAppStoreHook } from "/@/store/modules/app";
 | 
				
			||||||
 | 
					import { usePermissionStoreHook } from "/@/store/modules/permission";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const route = useRoute();
 | 
				
			||||||
 | 
					const pureApp = useAppStoreHook();
 | 
				
			||||||
 | 
					const router = useRouter().options.routes;
 | 
				
			||||||
 | 
					const routeStore = usePermissionStoreHook();
 | 
				
			||||||
 | 
					const showLogo = ref(storageLocal.getItem("logoVal") || "1");
 | 
				
			||||||
 | 
					const isCollapse = computed(() => {
 | 
				
			||||||
 | 
					  return !pureApp.getSidebarStatus;
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					const activeMenu = computed(() => {
 | 
				
			||||||
 | 
					  const { meta, path } = route;
 | 
				
			||||||
 | 
					  if (meta.activeMenu) {
 | 
				
			||||||
 | 
					    return meta.activeMenu;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return path;
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const menuSelect = (indexPath: string): void => {
 | 
				
			||||||
 | 
					  let parentPath = "";
 | 
				
			||||||
 | 
					  let parentPathIndex = indexPath.lastIndexOf("/");
 | 
				
			||||||
 | 
					  if (parentPathIndex > 0) {
 | 
				
			||||||
 | 
					    parentPath = indexPath.slice(0, parentPathIndex);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 找到当前路由的信息
 | 
				
			||||||
 | 
					  // eslint-disable-next-line no-inner-declarations
 | 
				
			||||||
 | 
					  function findCurrentRoute(routes) {
 | 
				
			||||||
 | 
					    return routes.map(item => {
 | 
				
			||||||
 | 
					      if (item.path === indexPath) {
 | 
				
			||||||
 | 
					        // 切换左侧菜单 通知标签页
 | 
				
			||||||
 | 
					        emitter.emit("changLayoutRoute", {
 | 
				
			||||||
 | 
					          indexPath,
 | 
				
			||||||
 | 
					          parentPath
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        if (item.children) findCurrentRoute(item.children);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  findCurrentRoute(algorithm.increaseIndexes(router));
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onBeforeMount(() => {
 | 
				
			||||||
 | 
					  emitter.on("logoChange", key => {
 | 
				
			||||||
 | 
					    showLogo.value = key;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div :class="['sidebar-container', showLogo ? 'has-logo' : '']">
 | 
					  <div :class="['sidebar-container', showLogo ? 'has-logo' : '']">
 | 
				
			||||||
    <Logo v-if="showLogo === '1'" :collapse="isCollapse" />
 | 
					    <Logo v-if="showLogo === '1'" :collapse="isCollapse" />
 | 
				
			||||||
@ -21,77 +79,3 @@
 | 
				
			|||||||
    </el-scrollbar>
 | 
					    </el-scrollbar>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					 | 
				
			||||||
<script lang="ts">
 | 
					 | 
				
			||||||
import Logo from "./logo.vue";
 | 
					 | 
				
			||||||
import { emitter } from "/@/utils/mitt";
 | 
					 | 
				
			||||||
import SidebarItem from "./sidebarItem.vue";
 | 
					 | 
				
			||||||
import { algorithm } from "/@/utils/algorithm";
 | 
					 | 
				
			||||||
import { storageLocal } from "/@/utils/storage";
 | 
					 | 
				
			||||||
import { useRoute, useRouter } from "vue-router";
 | 
					 | 
				
			||||||
import { useAppStoreHook } from "/@/store/modules/app";
 | 
					 | 
				
			||||||
import { computed, defineComponent, ref, onBeforeMount } from "vue";
 | 
					 | 
				
			||||||
import { usePermissionStoreHook } from "/@/store/modules/permission";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineComponent({
 | 
					 | 
				
			||||||
  name: "sidebar",
 | 
					 | 
				
			||||||
  components: { SidebarItem, Logo },
 | 
					 | 
				
			||||||
  setup() {
 | 
					 | 
				
			||||||
    const routeStore = usePermissionStoreHook();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const router = useRouter().options.routes;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const pureApp = useAppStoreHook();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const route = useRoute();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const showLogo = ref(storageLocal.getItem("logoVal") || "1");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const activeMenu = computed(() => {
 | 
					 | 
				
			||||||
      const { meta, path } = route;
 | 
					 | 
				
			||||||
      if (meta.activeMenu) {
 | 
					 | 
				
			||||||
        return meta.activeMenu;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return path;
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const menuSelect = (indexPath: string): void => {
 | 
					 | 
				
			||||||
      let parentPath = "";
 | 
					 | 
				
			||||||
      let parentPathIndex = indexPath.lastIndexOf("/");
 | 
					 | 
				
			||||||
      if (parentPathIndex > 0) {
 | 
					 | 
				
			||||||
        parentPath = indexPath.slice(0, parentPathIndex);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      // 找到当前路由的信息
 | 
					 | 
				
			||||||
      // eslint-disable-next-line no-inner-declarations
 | 
					 | 
				
			||||||
      function findCurrentRoute(routes) {
 | 
					 | 
				
			||||||
        return routes.map(item => {
 | 
					 | 
				
			||||||
          if (item.path === indexPath) {
 | 
					 | 
				
			||||||
            // 切换左侧菜单 通知标签页
 | 
					 | 
				
			||||||
            emitter.emit("changLayoutRoute", {
 | 
					 | 
				
			||||||
              indexPath,
 | 
					 | 
				
			||||||
              parentPath
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            if (item.children) findCurrentRoute(item.children);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      findCurrentRoute(algorithm.increaseIndexes(router));
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    onBeforeMount(() => {
 | 
					 | 
				
			||||||
      emitter.on("logoChange", key => {
 | 
					 | 
				
			||||||
        showLogo.value = key;
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
      activeMenu,
 | 
					 | 
				
			||||||
      isCollapse: computed(() => !pureApp.getSidebarStatus),
 | 
					 | 
				
			||||||
      menuSelect,
 | 
					 | 
				
			||||||
      showLogo,
 | 
					 | 
				
			||||||
      routeStore
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,442 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					  computed: {
 | 
				
			||||||
 | 
					    dynamicTagList() {
 | 
				
			||||||
 | 
					      return this.$storage.routesInStorage;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  ref,
 | 
				
			||||||
 | 
					  watch,
 | 
				
			||||||
 | 
					  onBeforeMount,
 | 
				
			||||||
 | 
					  unref,
 | 
				
			||||||
 | 
					  nextTick,
 | 
				
			||||||
 | 
					  getCurrentInstance
 | 
				
			||||||
 | 
					} from "vue";
 | 
				
			||||||
 | 
					import { RouteConfigs } from "../../types";
 | 
				
			||||||
 | 
					import { emitter } from "/@/utils/mitt";
 | 
				
			||||||
 | 
					import { templateRef } from "@vueuse/core";
 | 
				
			||||||
 | 
					import { storageLocal } from "/@/utils/storage";
 | 
				
			||||||
 | 
					import { useRoute, useRouter } from "vue-router";
 | 
				
			||||||
 | 
					import { toggleClass, removeClass, hasClass } from "/@/utils/operate";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import close from "/@/assets/svg/close.svg";
 | 
				
			||||||
 | 
					import refresh from "/@/assets/svg/refresh.svg";
 | 
				
			||||||
 | 
					import closeAll from "/@/assets/svg/close_all.svg";
 | 
				
			||||||
 | 
					import closeLeft from "/@/assets/svg/close_left.svg";
 | 
				
			||||||
 | 
					import closeOther from "/@/assets/svg/close_other.svg";
 | 
				
			||||||
 | 
					import closeRight from "/@/assets/svg/close_right.svg";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let refreshButton = "refresh-button";
 | 
				
			||||||
 | 
					const instance = getCurrentInstance();
 | 
				
			||||||
 | 
					let st: any;
 | 
				
			||||||
 | 
					const route = useRoute();
 | 
				
			||||||
 | 
					const router = useRouter();
 | 
				
			||||||
 | 
					const showTags = ref(storageLocal.getItem("tagsVal") || false);
 | 
				
			||||||
 | 
					const containerDom = templateRef<HTMLElement | null>("containerDom", null);
 | 
				
			||||||
 | 
					const activeIndex = ref(-1);
 | 
				
			||||||
 | 
					let routerArrays: Array<RouteConfigs> = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    path: "/welcome",
 | 
				
			||||||
 | 
					    parentPath: "/",
 | 
				
			||||||
 | 
					    meta: {
 | 
				
			||||||
 | 
					      title: "message.hshome",
 | 
				
			||||||
 | 
					      icon: "el-icon-s-home",
 | 
				
			||||||
 | 
					      showLink: true,
 | 
				
			||||||
 | 
					      savedPosition: false
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					const tagsViews = ref<ForDataType<undefined>>([
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    icon: refresh,
 | 
				
			||||||
 | 
					    text: "重新加载",
 | 
				
			||||||
 | 
					    divided: false,
 | 
				
			||||||
 | 
					    disabled: false,
 | 
				
			||||||
 | 
					    show: true
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    icon: close,
 | 
				
			||||||
 | 
					    text: "关闭当前标签页",
 | 
				
			||||||
 | 
					    divided: false,
 | 
				
			||||||
 | 
					    disabled: routerArrays.length > 1 ? false : true,
 | 
				
			||||||
 | 
					    show: true
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    icon: closeLeft,
 | 
				
			||||||
 | 
					    text: "关闭左侧标签页",
 | 
				
			||||||
 | 
					    divided: true,
 | 
				
			||||||
 | 
					    disabled: routerArrays.length > 1 ? false : true,
 | 
				
			||||||
 | 
					    show: true
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    icon: closeRight,
 | 
				
			||||||
 | 
					    text: "关闭右侧标签页",
 | 
				
			||||||
 | 
					    divided: false,
 | 
				
			||||||
 | 
					    disabled: routerArrays.length > 1 ? false : true,
 | 
				
			||||||
 | 
					    show: true
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    icon: closeOther,
 | 
				
			||||||
 | 
					    text: "关闭其他标签页",
 | 
				
			||||||
 | 
					    divided: true,
 | 
				
			||||||
 | 
					    disabled: routerArrays.length > 2 ? false : true,
 | 
				
			||||||
 | 
					    show: true
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    icon: closeAll,
 | 
				
			||||||
 | 
					    text: "关闭全部标签页",
 | 
				
			||||||
 | 
					    divided: false,
 | 
				
			||||||
 | 
					    disabled: routerArrays.length > 1 ? false : true,
 | 
				
			||||||
 | 
					    show: true
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 显示模式,默认灵动模式显示
 | 
				
			||||||
 | 
					const showModel = ref(storageLocal.getItem("showModel") || "smart");
 | 
				
			||||||
 | 
					if (!showModel.value) {
 | 
				
			||||||
 | 
					  storageLocal.setItem("showModel", "card");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let visible = ref(false);
 | 
				
			||||||
 | 
					let buttonLeft = ref(0);
 | 
				
			||||||
 | 
					let buttonTop = ref(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 当前右键选中的路由信息
 | 
				
			||||||
 | 
					let currentSelect = ref({});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function dynamicRouteTag(value: string, parentPath: string): void {
 | 
				
			||||||
 | 
					  const hasValue = st.routesInStorage.some((item: any) => {
 | 
				
			||||||
 | 
					    return item.path === value;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function concatPath(arr: object[], value: string, parentPath: string) {
 | 
				
			||||||
 | 
					    if (!hasValue) {
 | 
				
			||||||
 | 
					      arr.forEach((arrItem: any) => {
 | 
				
			||||||
 | 
					        let pathConcat = parentPath + arrItem.path;
 | 
				
			||||||
 | 
					        if (arrItem.path === value || pathConcat === value) {
 | 
				
			||||||
 | 
					          routerArrays.push({
 | 
				
			||||||
 | 
					            path: value,
 | 
				
			||||||
 | 
					            parentPath: `/${parentPath.split("/")[1]}`,
 | 
				
			||||||
 | 
					            meta: arrItem.meta
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					          st.routesInStorage = routerArrays;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          if (arrItem.children && arrItem.children.length > 0) {
 | 
				
			||||||
 | 
					            concatPath(arrItem.children, value, parentPath);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  concatPath(router.options.routes, value, parentPath);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 重新加载
 | 
				
			||||||
 | 
					function onFresh() {
 | 
				
			||||||
 | 
					  toggleClass(true, refreshButton, document.querySelector(".rotate"));
 | 
				
			||||||
 | 
					  const { fullPath } = unref(route);
 | 
				
			||||||
 | 
					  router.replace({
 | 
				
			||||||
 | 
					    path: "/redirect" + fullPath
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  setTimeout(() => {
 | 
				
			||||||
 | 
					    removeClass(document.querySelector(".rotate"), refreshButton);
 | 
				
			||||||
 | 
					  }, 600);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function deleteDynamicTag(obj: any, current: any, tag?: string) {
 | 
				
			||||||
 | 
					  let valueIndex: number = routerArrays.findIndex((item: any) => {
 | 
				
			||||||
 | 
					    return item.path === obj.path;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const spliceRoute = (start?: number, end?: number, other?: boolean): void => {
 | 
				
			||||||
 | 
					    if (other) {
 | 
				
			||||||
 | 
					      st.routesInStorage = [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          path: "/welcome",
 | 
				
			||||||
 | 
					          parentPath: "/",
 | 
				
			||||||
 | 
					          meta: {
 | 
				
			||||||
 | 
					            title: "message.hshome",
 | 
				
			||||||
 | 
					            icon: "el-icon-s-home",
 | 
				
			||||||
 | 
					            showLink: true,
 | 
				
			||||||
 | 
					            savedPosition: false
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        obj
 | 
				
			||||||
 | 
					      ];
 | 
				
			||||||
 | 
					      routerArrays = st.routesInStorage;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      routerArrays.splice(start, end);
 | 
				
			||||||
 | 
					      st.routesInStorage = routerArrays;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    router.push(obj.path);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (tag === "other") {
 | 
				
			||||||
 | 
					    spliceRoute(1, 1, true);
 | 
				
			||||||
 | 
					  } else if (tag === "left") {
 | 
				
			||||||
 | 
					    spliceRoute(1, valueIndex - 1);
 | 
				
			||||||
 | 
					  } else if (tag === "right") {
 | 
				
			||||||
 | 
					    spliceRoute(valueIndex + 1, routerArrays.length);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    // 从当前匹配到的路径中删除
 | 
				
			||||||
 | 
					    spliceRoute(valueIndex, 1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (current === obj.path) {
 | 
				
			||||||
 | 
					    // 如果删除当前激活tag就自动切换到最后一个tag
 | 
				
			||||||
 | 
					    let newRoute: any = routerArrays.slice(-1);
 | 
				
			||||||
 | 
					    nextTick(() => {
 | 
				
			||||||
 | 
					      router.push({
 | 
				
			||||||
 | 
					        path: newRoute[0].path
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function deleteMenu(item, tag?: string) {
 | 
				
			||||||
 | 
					  deleteDynamicTag(item, item.path, tag);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onClickDrop(key, item, selectRoute?: RouteConfigs) {
 | 
				
			||||||
 | 
					  if (item && item.disabled) return;
 | 
				
			||||||
 | 
					  // 当前路由信息
 | 
				
			||||||
 | 
					  switch (key) {
 | 
				
			||||||
 | 
					    case 0:
 | 
				
			||||||
 | 
					      // 重新加载
 | 
				
			||||||
 | 
					      onFresh();
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 1:
 | 
				
			||||||
 | 
					      // 关闭当前标签页
 | 
				
			||||||
 | 
					      selectRoute
 | 
				
			||||||
 | 
					        ? deleteMenu({ path: selectRoute.path, meta: selectRoute.meta })
 | 
				
			||||||
 | 
					        : deleteMenu({ path: route.path, meta: route.meta });
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 2:
 | 
				
			||||||
 | 
					      // 关闭左侧标签页
 | 
				
			||||||
 | 
					      selectRoute
 | 
				
			||||||
 | 
					        ? deleteMenu(
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              path: selectRoute.path,
 | 
				
			||||||
 | 
					              meta: selectRoute.meta
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "left"
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					        : deleteMenu({ path: route.path, meta: route.meta }, "left");
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 3:
 | 
				
			||||||
 | 
					      // 关闭右侧标签页
 | 
				
			||||||
 | 
					      selectRoute
 | 
				
			||||||
 | 
					        ? deleteMenu(
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              path: selectRoute.path,
 | 
				
			||||||
 | 
					              meta: selectRoute.meta
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "right"
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					        : deleteMenu({ path: route.path, meta: route.meta }, "right");
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 4:
 | 
				
			||||||
 | 
					      // 关闭其他标签页
 | 
				
			||||||
 | 
					      selectRoute
 | 
				
			||||||
 | 
					        ? deleteMenu(
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              path: selectRoute.path,
 | 
				
			||||||
 | 
					              meta: selectRoute.meta
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "other"
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					        : deleteMenu({ path: route.path, meta: route.meta }, "other");
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 5:
 | 
				
			||||||
 | 
					      // 关闭全部标签页
 | 
				
			||||||
 | 
					      routerArrays.splice(1, routerArrays.length);
 | 
				
			||||||
 | 
					      st.routesInStorage = routerArrays;
 | 
				
			||||||
 | 
					      router.push("/welcome");
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  setTimeout(() => {
 | 
				
			||||||
 | 
					    showMenuModel(route.fullPath);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 触发右键中菜单的点击事件
 | 
				
			||||||
 | 
					function selectTag(key, item) {
 | 
				
			||||||
 | 
					  onClickDrop(key, item, currentSelect.value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function closeMenu() {
 | 
				
			||||||
 | 
					  visible.value = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function showMenus(value: Boolean) {
 | 
				
			||||||
 | 
					  Array.of(1, 2, 3, 4, 5).forEach(v => {
 | 
				
			||||||
 | 
					    tagsViews.value[v].show = value;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function disabledMenus(value: Boolean) {
 | 
				
			||||||
 | 
					  Array.of(1, 2, 3, 4, 5).forEach(v => {
 | 
				
			||||||
 | 
					    tagsViews.value[v].disabled = value;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 检查当前右键的菜单两边是否存在别的菜单,如果左侧的菜单是首页,则不显示关闭左侧标签页,如果右侧没有菜单,则不显示关闭右侧标签页
 | 
				
			||||||
 | 
					function showMenuModel(currentPath: string, refresh = false) {
 | 
				
			||||||
 | 
					  let allRoute = unref(st.routesInStorage);
 | 
				
			||||||
 | 
					  let routeLength = unref(st.routesInStorage).length;
 | 
				
			||||||
 | 
					  // currentIndex为1时,左侧的菜单是首页,则不显示关闭左侧标签页
 | 
				
			||||||
 | 
					  let currentIndex = allRoute.findIndex(v => v.path === currentPath);
 | 
				
			||||||
 | 
					  // 如果currentIndex等于routeLength-1,右侧没有菜单,则不显示关闭右侧标签页
 | 
				
			||||||
 | 
					  showMenus(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (refresh) {
 | 
				
			||||||
 | 
					    tagsViews.value[0].show = true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (currentIndex === 1 && routeLength !== 2) {
 | 
				
			||||||
 | 
					    // 左侧的菜单是首页,右侧存在别的菜单
 | 
				
			||||||
 | 
					    tagsViews.value[2].show = false;
 | 
				
			||||||
 | 
					    Array.of(1, 3, 4, 5).forEach(v => {
 | 
				
			||||||
 | 
					      tagsViews.value[v].disabled = false;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    tagsViews.value[2].disabled = true;
 | 
				
			||||||
 | 
					  } else if (currentIndex === 1 && routeLength === 2) {
 | 
				
			||||||
 | 
					    disabledMenus(false);
 | 
				
			||||||
 | 
					    // 左侧的菜单是首页,右侧不存在别的菜单
 | 
				
			||||||
 | 
					    Array.of(2, 3, 4).forEach(v => {
 | 
				
			||||||
 | 
					      tagsViews.value[v].show = false;
 | 
				
			||||||
 | 
					      tagsViews.value[v].disabled = true;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  } else if (routeLength - 1 === currentIndex && currentIndex !== 0) {
 | 
				
			||||||
 | 
					    // 当前路由是所有路由中的最后一个
 | 
				
			||||||
 | 
					    tagsViews.value[3].show = false;
 | 
				
			||||||
 | 
					    Array.of(1, 2, 4, 5).forEach(v => {
 | 
				
			||||||
 | 
					      tagsViews.value[v].disabled = false;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    tagsViews.value[3].disabled = true;
 | 
				
			||||||
 | 
					  } else if (currentIndex === 0) {
 | 
				
			||||||
 | 
					    // 当前路由为首页
 | 
				
			||||||
 | 
					    disabledMenus(true);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    disabledMenus(false);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function openMenu(tag, e) {
 | 
				
			||||||
 | 
					  closeMenu();
 | 
				
			||||||
 | 
					  if (tag.path === "/welcome") {
 | 
				
			||||||
 | 
					    // 右键菜单为首页,只显示刷新
 | 
				
			||||||
 | 
					    showMenus(false);
 | 
				
			||||||
 | 
					    tagsViews.value[0].show = true;
 | 
				
			||||||
 | 
					  } else if (route.path !== tag.path) {
 | 
				
			||||||
 | 
					    // 右键菜单不匹配当前路由,隐藏刷新
 | 
				
			||||||
 | 
					    tagsViews.value[0].show = false;
 | 
				
			||||||
 | 
					    showMenuModel(tag.path);
 | 
				
			||||||
 | 
					    // eslint-disable-next-line no-dupe-else-if
 | 
				
			||||||
 | 
					  } else if (st.routesInStorage.length === 2 && route.path !== tag.path) {
 | 
				
			||||||
 | 
					    showMenus(true);
 | 
				
			||||||
 | 
					    // 只有两个标签时不显示关闭其他标签页
 | 
				
			||||||
 | 
					    tagsViews.value[4].show = false;
 | 
				
			||||||
 | 
					  } else if (route.path === tag.path) {
 | 
				
			||||||
 | 
					    // 右键当前激活的菜单
 | 
				
			||||||
 | 
					    showMenuModel(tag.path, true);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  currentSelect.value = tag;
 | 
				
			||||||
 | 
					  const menuMinWidth = 105;
 | 
				
			||||||
 | 
					  const offsetLeft = unref(containerDom).getBoundingClientRect().left;
 | 
				
			||||||
 | 
					  const offsetWidth = unref(containerDom).offsetWidth;
 | 
				
			||||||
 | 
					  const maxLeft = offsetWidth - menuMinWidth;
 | 
				
			||||||
 | 
					  const left = e.clientX - offsetLeft + 5;
 | 
				
			||||||
 | 
					  if (left > maxLeft) {
 | 
				
			||||||
 | 
					    buttonLeft.value = maxLeft;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    buttonLeft.value = left;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  buttonTop.value = e.clientY + 10;
 | 
				
			||||||
 | 
					  setTimeout(() => {
 | 
				
			||||||
 | 
					    visible.value = true;
 | 
				
			||||||
 | 
					  }, 10);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 触发tags标签切换
 | 
				
			||||||
 | 
					function tagOnClick(item) {
 | 
				
			||||||
 | 
					  showMenuModel(item.path);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 鼠标移入
 | 
				
			||||||
 | 
					function onMouseenter(item, index) {
 | 
				
			||||||
 | 
					  if (index) activeIndex.value = index;
 | 
				
			||||||
 | 
					  if (unref(showModel) === "smart") {
 | 
				
			||||||
 | 
					    if (hasClass(instance.refs["schedule" + index], "schedule-active")) return;
 | 
				
			||||||
 | 
					    toggleClass(true, "schedule-in", instance.refs["schedule" + index]);
 | 
				
			||||||
 | 
					    toggleClass(false, "schedule-out", instance.refs["schedule" + index]);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    if (hasClass(instance.refs["dynamic" + index], "card-active")) return;
 | 
				
			||||||
 | 
					    toggleClass(true, "card-in", instance.refs["dynamic" + index]);
 | 
				
			||||||
 | 
					    toggleClass(false, "card-out", instance.refs["dynamic" + index]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 鼠标移出
 | 
				
			||||||
 | 
					function onMouseleave(item, index) {
 | 
				
			||||||
 | 
					  activeIndex.value = -1;
 | 
				
			||||||
 | 
					  if (unref(showModel) === "smart") {
 | 
				
			||||||
 | 
					    if (hasClass(instance.refs["schedule" + index], "schedule-active")) return;
 | 
				
			||||||
 | 
					    toggleClass(false, "schedule-in", instance.refs["schedule" + index]);
 | 
				
			||||||
 | 
					    toggleClass(true, "schedule-out", instance.refs["schedule" + index]);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    if (hasClass(instance.refs["dynamic" + index], "card-active")) return;
 | 
				
			||||||
 | 
					    toggleClass(false, "card-in", instance.refs["dynamic" + index]);
 | 
				
			||||||
 | 
					    toggleClass(true, "card-out", instance.refs["dynamic" + index]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					watch(
 | 
				
			||||||
 | 
					  () => visible.value,
 | 
				
			||||||
 | 
					  val => {
 | 
				
			||||||
 | 
					    if (val) {
 | 
				
			||||||
 | 
					      document.body.addEventListener("click", closeMenu);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      document.body.removeEventListener("click", closeMenu);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onBeforeMount(() => {
 | 
				
			||||||
 | 
					  if (!instance) return;
 | 
				
			||||||
 | 
					  st = instance.appContext.app.config.globalProperties.$storage;
 | 
				
			||||||
 | 
					  routerArrays = st.routesInStorage ?? routerArrays;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 根据当前路由初始化操作标签页的禁用状态
 | 
				
			||||||
 | 
					  showMenuModel(route.fullPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 触发隐藏标签页
 | 
				
			||||||
 | 
					  emitter.on("tagViewsChange", key => {
 | 
				
			||||||
 | 
					    if (unref(showTags) === key) return;
 | 
				
			||||||
 | 
					    showTags.value = key;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 改变标签风格
 | 
				
			||||||
 | 
					  emitter.on("tagViewsShowModel", key => {
 | 
				
			||||||
 | 
					    showModel.value = key;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //  接收侧边栏切换传递过来的参数
 | 
				
			||||||
 | 
					  emitter.on("changLayoutRoute", ({ indexPath, parentPath }) => {
 | 
				
			||||||
 | 
					    dynamicRouteTag(indexPath, parentPath);
 | 
				
			||||||
 | 
					    setTimeout(() => {
 | 
				
			||||||
 | 
					      showMenuModel(indexPath);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div ref="containerDom" class="tags-view" v-if="!showTags">
 | 
					  <div ref="containerDom" class="tags-view" v-if="!showTags">
 | 
				
			||||||
    <el-scrollbar wrap-class="scrollbar-wrapper" class="scroll-container">
 | 
					    <el-scrollbar wrap-class="scrollbar-wrapper" class="scroll-container">
 | 
				
			||||||
@ -87,479 +526,6 @@
 | 
				
			|||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  ref,
 | 
					 | 
				
			||||||
  watch,
 | 
					 | 
				
			||||||
  onBeforeMount,
 | 
					 | 
				
			||||||
  unref,
 | 
					 | 
				
			||||||
  nextTick,
 | 
					 | 
				
			||||||
  getCurrentInstance
 | 
					 | 
				
			||||||
} from "vue";
 | 
					 | 
				
			||||||
import { useRoute, useRouter } from "vue-router";
 | 
					 | 
				
			||||||
import { storageLocal } from "/@/utils/storage";
 | 
					 | 
				
			||||||
import { emitter } from "/@/utils/mitt";
 | 
					 | 
				
			||||||
import { toggleClass, removeClass, hasClass } from "/@/utils/operate";
 | 
					 | 
				
			||||||
import { templateRef } from "@vueuse/core";
 | 
					 | 
				
			||||||
import closeOther from "/@/assets/svg/close_other.svg";
 | 
					 | 
				
			||||||
import closeLeft from "/@/assets/svg/close_left.svg";
 | 
					 | 
				
			||||||
import closeRight from "/@/assets/svg/close_right.svg";
 | 
					 | 
				
			||||||
import close from "/@/assets/svg/close.svg";
 | 
					 | 
				
			||||||
import refresh from "/@/assets/svg/refresh.svg";
 | 
					 | 
				
			||||||
import closeAll from "/@/assets/svg/close_all.svg";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
let refreshButton = "refresh-button";
 | 
					 | 
				
			||||||
let routerArrays: Array<object> = [
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    path: "/welcome",
 | 
					 | 
				
			||||||
    parentPath: "/",
 | 
					 | 
				
			||||||
    meta: {
 | 
					 | 
				
			||||||
      title: "message.hshome",
 | 
					 | 
				
			||||||
      icon: "el-icon-s-home",
 | 
					 | 
				
			||||||
      showLink: true,
 | 
					 | 
				
			||||||
      savedPosition: false
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default {
 | 
					 | 
				
			||||||
  name: "tag",
 | 
					 | 
				
			||||||
  components: {
 | 
					 | 
				
			||||||
    closeOther,
 | 
					 | 
				
			||||||
    closeLeft,
 | 
					 | 
				
			||||||
    closeRight,
 | 
					 | 
				
			||||||
    close,
 | 
					 | 
				
			||||||
    refresh,
 | 
					 | 
				
			||||||
    closeAll
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // @ts-ignore
 | 
					 | 
				
			||||||
  computed: {
 | 
					 | 
				
			||||||
    dynamicTagList() {
 | 
					 | 
				
			||||||
      return this.$storage.routesInStorage;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  setup() {
 | 
					 | 
				
			||||||
    const instance = getCurrentInstance();
 | 
					 | 
				
			||||||
    let st: any;
 | 
					 | 
				
			||||||
    const route = useRoute();
 | 
					 | 
				
			||||||
    const router = useRouter();
 | 
					 | 
				
			||||||
    const showTags = ref(storageLocal.getItem("tagsVal") || false);
 | 
					 | 
				
			||||||
    const containerDom = templateRef<HTMLElement | null>("containerDom", null);
 | 
					 | 
				
			||||||
    const activeIndex = ref(-1);
 | 
					 | 
				
			||||||
    const tagsViews = ref([
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        icon: "refresh",
 | 
					 | 
				
			||||||
        text: "重新加载",
 | 
					 | 
				
			||||||
        divided: false,
 | 
					 | 
				
			||||||
        disabled: false,
 | 
					 | 
				
			||||||
        show: true
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        icon: "close",
 | 
					 | 
				
			||||||
        text: "关闭当前标签页",
 | 
					 | 
				
			||||||
        divided: false,
 | 
					 | 
				
			||||||
        disabled: routerArrays.length > 1 ? false : true,
 | 
					 | 
				
			||||||
        show: true
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        icon: "closeLeft",
 | 
					 | 
				
			||||||
        text: "关闭左侧标签页",
 | 
					 | 
				
			||||||
        divided: true,
 | 
					 | 
				
			||||||
        disabled: routerArrays.length > 1 ? false : true,
 | 
					 | 
				
			||||||
        show: true
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        icon: "closeRight",
 | 
					 | 
				
			||||||
        text: "关闭右侧标签页",
 | 
					 | 
				
			||||||
        divided: false,
 | 
					 | 
				
			||||||
        disabled: routerArrays.length > 1 ? false : true,
 | 
					 | 
				
			||||||
        show: true
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        icon: "closeOther",
 | 
					 | 
				
			||||||
        text: "关闭其他标签页",
 | 
					 | 
				
			||||||
        divided: true,
 | 
					 | 
				
			||||||
        disabled: routerArrays.length > 2 ? false : true,
 | 
					 | 
				
			||||||
        show: true
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        icon: "closeAll",
 | 
					 | 
				
			||||||
        text: "关闭全部标签页",
 | 
					 | 
				
			||||||
        divided: false,
 | 
					 | 
				
			||||||
        disabled: routerArrays.length > 1 ? false : true,
 | 
					 | 
				
			||||||
        show: true
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 显示模式,默认灵动模式显示
 | 
					 | 
				
			||||||
    const showModel = ref(storageLocal.getItem("showModel") || "smart");
 | 
					 | 
				
			||||||
    if (!showModel.value) {
 | 
					 | 
				
			||||||
      storageLocal.setItem("showModel", "card");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let visible = ref(false);
 | 
					 | 
				
			||||||
    let buttonLeft = ref(0);
 | 
					 | 
				
			||||||
    let buttonTop = ref(0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 当前右键选中的路由信息
 | 
					 | 
				
			||||||
    let currentSelect = ref({});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function dynamicRouteTag(value: string, parentPath: string): void {
 | 
					 | 
				
			||||||
      const hasValue = st.routesInStorage.some((item: any) => {
 | 
					 | 
				
			||||||
        return item.path === value;
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      function concatPath(arr: object[], value: string, parentPath: string) {
 | 
					 | 
				
			||||||
        if (!hasValue) {
 | 
					 | 
				
			||||||
          arr.forEach((arrItem: any) => {
 | 
					 | 
				
			||||||
            let pathConcat = parentPath + arrItem.path;
 | 
					 | 
				
			||||||
            if (arrItem.path === value || pathConcat === value) {
 | 
					 | 
				
			||||||
              routerArrays.push({
 | 
					 | 
				
			||||||
                path: value,
 | 
					 | 
				
			||||||
                parentPath: `/${parentPath.split("/")[1]}`,
 | 
					 | 
				
			||||||
                meta: arrItem.meta
 | 
					 | 
				
			||||||
              });
 | 
					 | 
				
			||||||
              st.routesInStorage = routerArrays;
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
              if (arrItem.children && arrItem.children.length > 0) {
 | 
					 | 
				
			||||||
                concatPath(arrItem.children, value, parentPath);
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      concatPath(router.options.routes, value, parentPath);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 重新加载
 | 
					 | 
				
			||||||
    function onFresh() {
 | 
					 | 
				
			||||||
      toggleClass(true, refreshButton, document.querySelector(".rotate"));
 | 
					 | 
				
			||||||
      const { fullPath } = unref(route);
 | 
					 | 
				
			||||||
      router.replace({
 | 
					 | 
				
			||||||
        path: "/redirect" + fullPath
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      setTimeout(() => {
 | 
					 | 
				
			||||||
        removeClass(document.querySelector(".rotate"), refreshButton);
 | 
					 | 
				
			||||||
      }, 600);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function deleteDynamicTag(obj: any, current: any, tag?: string) {
 | 
					 | 
				
			||||||
      let valueIndex: number = routerArrays.findIndex((item: any) => {
 | 
					 | 
				
			||||||
        return item.path === obj.path;
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      const spliceRoute = (
 | 
					 | 
				
			||||||
        start?: number,
 | 
					 | 
				
			||||||
        end?: number,
 | 
					 | 
				
			||||||
        other?: boolean
 | 
					 | 
				
			||||||
      ): void => {
 | 
					 | 
				
			||||||
        if (other) {
 | 
					 | 
				
			||||||
          st.routesInStorage = routerArrays = [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              path: "/welcome",
 | 
					 | 
				
			||||||
              parentPath: "/",
 | 
					 | 
				
			||||||
              meta: {
 | 
					 | 
				
			||||||
                title: "message.hshome",
 | 
					 | 
				
			||||||
                icon: "el-icon-s-home",
 | 
					 | 
				
			||||||
                showLink: true,
 | 
					 | 
				
			||||||
                savedPosition: false
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            obj
 | 
					 | 
				
			||||||
          ];
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          routerArrays.splice(start, end);
 | 
					 | 
				
			||||||
          st.routesInStorage = routerArrays;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        router.push(obj.path);
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (tag === "other") {
 | 
					 | 
				
			||||||
        spliceRoute(1, 1, true);
 | 
					 | 
				
			||||||
      } else if (tag === "left") {
 | 
					 | 
				
			||||||
        spliceRoute(1, valueIndex - 1);
 | 
					 | 
				
			||||||
      } else if (tag === "right") {
 | 
					 | 
				
			||||||
        spliceRoute(valueIndex + 1, routerArrays.length);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        // 从当前匹配到的路径中删除
 | 
					 | 
				
			||||||
        spliceRoute(valueIndex, 1);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (current === obj.path) {
 | 
					 | 
				
			||||||
        // 如果删除当前激活tag就自动切换到最后一个tag
 | 
					 | 
				
			||||||
        let newRoute: any = routerArrays.slice(-1);
 | 
					 | 
				
			||||||
        nextTick(() => {
 | 
					 | 
				
			||||||
          router.push({
 | 
					 | 
				
			||||||
            path: newRoute[0].path
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function deleteMenu(item, tag?: string) {
 | 
					 | 
				
			||||||
      deleteDynamicTag(item, item.path, tag);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function onClickDrop(key, item, selectRoute) {
 | 
					 | 
				
			||||||
      if (item && item.disabled) return;
 | 
					 | 
				
			||||||
      // 当前路由信息
 | 
					 | 
				
			||||||
      switch (key) {
 | 
					 | 
				
			||||||
        case 0:
 | 
					 | 
				
			||||||
          // 重新加载
 | 
					 | 
				
			||||||
          onFresh();
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
        case 1:
 | 
					 | 
				
			||||||
          // 关闭当前标签页
 | 
					 | 
				
			||||||
          selectRoute
 | 
					 | 
				
			||||||
            ? deleteMenu({ path: selectRoute.path, meta: selectRoute.meta })
 | 
					 | 
				
			||||||
            : deleteMenu({ path: route.path, meta: route.meta });
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
        case 2:
 | 
					 | 
				
			||||||
          // 关闭左侧标签页
 | 
					 | 
				
			||||||
          selectRoute
 | 
					 | 
				
			||||||
            ? deleteMenu(
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  path: selectRoute.path,
 | 
					 | 
				
			||||||
                  meta: selectRoute.meta
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "left"
 | 
					 | 
				
			||||||
              )
 | 
					 | 
				
			||||||
            : deleteMenu({ path: route.path, meta: route.meta }, "left");
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
        case 3:
 | 
					 | 
				
			||||||
          // 关闭右侧标签页
 | 
					 | 
				
			||||||
          selectRoute
 | 
					 | 
				
			||||||
            ? deleteMenu(
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  path: selectRoute.path,
 | 
					 | 
				
			||||||
                  meta: selectRoute.meta
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "right"
 | 
					 | 
				
			||||||
              )
 | 
					 | 
				
			||||||
            : deleteMenu({ path: route.path, meta: route.meta }, "right");
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
        case 4:
 | 
					 | 
				
			||||||
          // 关闭其他标签页
 | 
					 | 
				
			||||||
          selectRoute
 | 
					 | 
				
			||||||
            ? deleteMenu(
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  path: selectRoute.path,
 | 
					 | 
				
			||||||
                  meta: selectRoute.meta
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "other"
 | 
					 | 
				
			||||||
              )
 | 
					 | 
				
			||||||
            : deleteMenu({ path: route.path, meta: route.meta }, "other");
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
        case 5:
 | 
					 | 
				
			||||||
          // 关闭全部标签页
 | 
					 | 
				
			||||||
          routerArrays.splice(1, routerArrays.length);
 | 
					 | 
				
			||||||
          st.routesInStorage = routerArrays;
 | 
					 | 
				
			||||||
          router.push("/welcome");
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      setTimeout(() => {
 | 
					 | 
				
			||||||
        showMenuModel(route.fullPath);
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 触发右键中菜单的点击事件
 | 
					 | 
				
			||||||
    function selectTag(key, item) {
 | 
					 | 
				
			||||||
      onClickDrop(key, item, currentSelect.value);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function closeMenu() {
 | 
					 | 
				
			||||||
      visible.value = false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function showMenus(value: Boolean) {
 | 
					 | 
				
			||||||
      Array.of(1, 2, 3, 4, 5).forEach(v => {
 | 
					 | 
				
			||||||
        tagsViews.value[v].show = value;
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function disabledMenus(value: Boolean) {
 | 
					 | 
				
			||||||
      Array.of(1, 2, 3, 4, 5).forEach(v => {
 | 
					 | 
				
			||||||
        tagsViews.value[v].disabled = value;
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 检查当前右键的菜单两边是否存在别的菜单,如果左侧的菜单是首页,则不显示关闭左侧标签页,如果右侧没有菜单,则不显示关闭右侧标签页
 | 
					 | 
				
			||||||
    function showMenuModel(currentPath: string, refresh = false) {
 | 
					 | 
				
			||||||
      let allRoute = unref(st.routesInStorage);
 | 
					 | 
				
			||||||
      let routeLength = unref(st.routesInStorage).length;
 | 
					 | 
				
			||||||
      // currentIndex为1时,左侧的菜单是首页,则不显示关闭左侧标签页
 | 
					 | 
				
			||||||
      let currentIndex = allRoute.findIndex(v => v.path === currentPath);
 | 
					 | 
				
			||||||
      // 如果currentIndex等于routeLength-1,右侧没有菜单,则不显示关闭右侧标签页
 | 
					 | 
				
			||||||
      showMenus(true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (refresh) {
 | 
					 | 
				
			||||||
        tagsViews.value[0].show = true;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (currentIndex === 1 && routeLength !== 2) {
 | 
					 | 
				
			||||||
        // 左侧的菜单是首页,右侧存在别的菜单
 | 
					 | 
				
			||||||
        tagsViews.value[2].show = false;
 | 
					 | 
				
			||||||
        Array.of(1, 3, 4, 5).forEach(v => {
 | 
					 | 
				
			||||||
          tagsViews.value[v].disabled = false;
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        tagsViews.value[2].disabled = true;
 | 
					 | 
				
			||||||
      } else if (currentIndex === 1 && routeLength === 2) {
 | 
					 | 
				
			||||||
        disabledMenus(false);
 | 
					 | 
				
			||||||
        // 左侧的菜单是首页,右侧不存在别的菜单
 | 
					 | 
				
			||||||
        Array.of(2, 3, 4).forEach(v => {
 | 
					 | 
				
			||||||
          tagsViews.value[v].show = false;
 | 
					 | 
				
			||||||
          tagsViews.value[v].disabled = true;
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      } else if (routeLength - 1 === currentIndex && currentIndex !== 0) {
 | 
					 | 
				
			||||||
        // 当前路由是所有路由中的最后一个
 | 
					 | 
				
			||||||
        tagsViews.value[3].show = false;
 | 
					 | 
				
			||||||
        Array.of(1, 2, 4, 5).forEach(v => {
 | 
					 | 
				
			||||||
          tagsViews.value[v].disabled = false;
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        tagsViews.value[3].disabled = true;
 | 
					 | 
				
			||||||
      } else if (currentIndex === 0) {
 | 
					 | 
				
			||||||
        // 当前路由为首页
 | 
					 | 
				
			||||||
        disabledMenus(true);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        disabledMenus(false);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function openMenu(tag, e) {
 | 
					 | 
				
			||||||
      closeMenu();
 | 
					 | 
				
			||||||
      if (tag.path === "/welcome") {
 | 
					 | 
				
			||||||
        // 右键菜单为首页,只显示刷新
 | 
					 | 
				
			||||||
        showMenus(false);
 | 
					 | 
				
			||||||
        tagsViews.value[0].show = true;
 | 
					 | 
				
			||||||
      } else if (route.path !== tag.path) {
 | 
					 | 
				
			||||||
        // 右键菜单不匹配当前路由,隐藏刷新
 | 
					 | 
				
			||||||
        tagsViews.value[0].show = false;
 | 
					 | 
				
			||||||
        showMenuModel(tag.path);
 | 
					 | 
				
			||||||
        // eslint-disable-next-line no-dupe-else-if
 | 
					 | 
				
			||||||
      } else if (st.routesInStorage.length === 2 && route.path !== tag.path) {
 | 
					 | 
				
			||||||
        showMenus(true);
 | 
					 | 
				
			||||||
        // 只有两个标签时不显示关闭其他标签页
 | 
					 | 
				
			||||||
        tagsViews.value[4].show = false;
 | 
					 | 
				
			||||||
      } else if (route.path === tag.path) {
 | 
					 | 
				
			||||||
        // 右键当前激活的菜单
 | 
					 | 
				
			||||||
        showMenuModel(tag.path, true);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      currentSelect.value = tag;
 | 
					 | 
				
			||||||
      const menuMinWidth = 105;
 | 
					 | 
				
			||||||
      const offsetLeft = unref(containerDom).getBoundingClientRect().left;
 | 
					 | 
				
			||||||
      const offsetWidth = unref(containerDom).offsetWidth;
 | 
					 | 
				
			||||||
      const maxLeft = offsetWidth - menuMinWidth;
 | 
					 | 
				
			||||||
      const left = e.clientX - offsetLeft + 5;
 | 
					 | 
				
			||||||
      if (left > maxLeft) {
 | 
					 | 
				
			||||||
        buttonLeft.value = maxLeft;
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        buttonLeft.value = left;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      buttonTop.value = e.clientY + 10;
 | 
					 | 
				
			||||||
      setTimeout(() => {
 | 
					 | 
				
			||||||
        visible.value = true;
 | 
					 | 
				
			||||||
      }, 10);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 触发tags标签切换
 | 
					 | 
				
			||||||
    function tagOnClick(item) {
 | 
					 | 
				
			||||||
      showMenuModel(item.path);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 鼠标移入
 | 
					 | 
				
			||||||
    function onMouseenter(item, index) {
 | 
					 | 
				
			||||||
      if (index) activeIndex.value = index;
 | 
					 | 
				
			||||||
      if (unref(showModel) === "smart") {
 | 
					 | 
				
			||||||
        if (hasClass(instance.refs["schedule" + index], "schedule-active"))
 | 
					 | 
				
			||||||
          return;
 | 
					 | 
				
			||||||
        toggleClass(true, "schedule-in", instance.refs["schedule" + index]);
 | 
					 | 
				
			||||||
        toggleClass(false, "schedule-out", instance.refs["schedule" + index]);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        if (hasClass(instance.refs["dynamic" + index], "card-active")) return;
 | 
					 | 
				
			||||||
        toggleClass(true, "card-in", instance.refs["dynamic" + index]);
 | 
					 | 
				
			||||||
        toggleClass(false, "card-out", instance.refs["dynamic" + index]);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 鼠标移出
 | 
					 | 
				
			||||||
    function onMouseleave(item, index) {
 | 
					 | 
				
			||||||
      activeIndex.value = -1;
 | 
					 | 
				
			||||||
      if (unref(showModel) === "smart") {
 | 
					 | 
				
			||||||
        if (hasClass(instance.refs["schedule" + index], "schedule-active"))
 | 
					 | 
				
			||||||
          return;
 | 
					 | 
				
			||||||
        toggleClass(false, "schedule-in", instance.refs["schedule" + index]);
 | 
					 | 
				
			||||||
        toggleClass(true, "schedule-out", instance.refs["schedule" + index]);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        if (hasClass(instance.refs["dynamic" + index], "card-active")) return;
 | 
					 | 
				
			||||||
        toggleClass(false, "card-in", instance.refs["dynamic" + index]);
 | 
					 | 
				
			||||||
        toggleClass(true, "card-out", instance.refs["dynamic" + index]);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    watch(
 | 
					 | 
				
			||||||
      () => visible.value,
 | 
					 | 
				
			||||||
      val => {
 | 
					 | 
				
			||||||
        if (val) {
 | 
					 | 
				
			||||||
          document.body.addEventListener("click", closeMenu);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          document.body.removeEventListener("click", closeMenu);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    onBeforeMount(() => {
 | 
					 | 
				
			||||||
      if (!instance) return;
 | 
					 | 
				
			||||||
      st = instance.appContext.app.config.globalProperties.$storage;
 | 
					 | 
				
			||||||
      routerArrays = st.routesInStorage ?? routerArrays;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // 根据当前路由初始化操作标签页的禁用状态
 | 
					 | 
				
			||||||
      showMenuModel(route.fullPath);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // 触发隐藏标签页
 | 
					 | 
				
			||||||
      emitter.on("tagViewsChange", key => {
 | 
					 | 
				
			||||||
        if (unref(showTags) === key) return;
 | 
					 | 
				
			||||||
        showTags.value = key;
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // 改变标签风格
 | 
					 | 
				
			||||||
      emitter.on("tagViewsShowModel", key => {
 | 
					 | 
				
			||||||
        showModel.value = key;
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      //  接收侧边栏切换传递过来的参数
 | 
					 | 
				
			||||||
      emitter.on("changLayoutRoute", ({ indexPath, parentPath }) => {
 | 
					 | 
				
			||||||
        dynamicRouteTag(indexPath, parentPath);
 | 
					 | 
				
			||||||
        setTimeout(() => {
 | 
					 | 
				
			||||||
          showMenuModel(indexPath);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
      deleteMenu,
 | 
					 | 
				
			||||||
      showTags,
 | 
					 | 
				
			||||||
      onFresh,
 | 
					 | 
				
			||||||
      tagsViews,
 | 
					 | 
				
			||||||
      onClickDrop,
 | 
					 | 
				
			||||||
      visible,
 | 
					 | 
				
			||||||
      buttonLeft,
 | 
					 | 
				
			||||||
      buttonTop,
 | 
					 | 
				
			||||||
      openMenu,
 | 
					 | 
				
			||||||
      closeMenu,
 | 
					 | 
				
			||||||
      selectTag,
 | 
					 | 
				
			||||||
      currentSelect,
 | 
					 | 
				
			||||||
      onMouseenter,
 | 
					 | 
				
			||||||
      onMouseleave,
 | 
					 | 
				
			||||||
      tagOnClick,
 | 
					 | 
				
			||||||
      activeIndex,
 | 
					 | 
				
			||||||
      showModel,
 | 
					 | 
				
			||||||
      showMenuModel
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss" scoped>
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
@keyframes scheduleInWidth {
 | 
					@keyframes scheduleInWidth {
 | 
				
			||||||
  from {
 | 
					  from {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,16 +1,5 @@
 | 
				
			|||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
let routerArrays: Array<object> = [
 | 
					import { routerArrays } from "./types";
 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    path: "/welcome",
 | 
					 | 
				
			||||||
    parentPath: "/",
 | 
					 | 
				
			||||||
    meta: {
 | 
					 | 
				
			||||||
      title: "message.hshome",
 | 
					 | 
				
			||||||
      icon: "el-icon-s-home",
 | 
					 | 
				
			||||||
      showLink: true,
 | 
					 | 
				
			||||||
      savedPosition: false
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  computed: {
 | 
					  computed: {
 | 
				
			||||||
    layout() {
 | 
					    layout() {
 | 
				
			||||||
@ -204,7 +193,6 @@ onBeforeMount(() => {
 | 
				
			|||||||
</style>
 | 
					</style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style lang="scss" scoped>
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
$sideBarWidth: 210px;
 | 
					 | 
				
			||||||
@mixin clearfix {
 | 
					@mixin clearfix {
 | 
				
			||||||
  &::after {
 | 
					  &::after {
 | 
				
			||||||
    content: "";
 | 
					    content: "";
 | 
				
			||||||
@ -241,7 +229,7 @@ $sideBarWidth: 210px;
 | 
				
			|||||||
  top: 0;
 | 
					  top: 0;
 | 
				
			||||||
  right: 0;
 | 
					  right: 0;
 | 
				
			||||||
  z-index: 9;
 | 
					  z-index: 9;
 | 
				
			||||||
  width: calc(100% - #{$sideBarWidth});
 | 
					  width: calc(100% - 210px);
 | 
				
			||||||
  transition: width 0.28s;
 | 
					  transition: width 0.28s;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										23
									
								
								src/layout/types.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/layout/types.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					export type RouteConfigs = {
 | 
				
			||||||
 | 
					  path?: string;
 | 
				
			||||||
 | 
					  parentPath?: string;
 | 
				
			||||||
 | 
					  meta?: {
 | 
				
			||||||
 | 
					    title?: string;
 | 
				
			||||||
 | 
					    icon?: string;
 | 
				
			||||||
 | 
					    showLink?: boolean;
 | 
				
			||||||
 | 
					    savedPosition?: boolean;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const routerArrays: Array<RouteConfigs> = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    path: "/welcome",
 | 
				
			||||||
 | 
					    parentPath: "/",
 | 
				
			||||||
 | 
					    meta: {
 | 
				
			||||||
 | 
					      title: "message.hshome",
 | 
				
			||||||
 | 
					      icon: "el-icon-s-home",
 | 
				
			||||||
 | 
					      showLink: true,
 | 
				
			||||||
 | 
					      savedPosition: false
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
@ -179,7 +179,7 @@
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      .iconinternationality {
 | 
					      .globalization {
 | 
				
			||||||
        height: 62px;
 | 
					        height: 62px;
 | 
				
			||||||
        width: 40px;
 | 
					        width: 40px;
 | 
				
			||||||
        padding: 11px;
 | 
					        padding: 11px;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user