mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +08:00 
			
		
		
		
	feat: add horizontal nav (#45)
* feat: add horizontal nav * workflow: update linter.yml * fix: update * fix: update * fix: update * Rename Link.vue to link.vue * Rename SidebarItem.vue to sidebarItem.vue * Rename Logo.vue to logo.vue * Rename AppMain.vue to appMain.vue * Rename Navbar.vue to navbar.vue * fix: update * fix: update * fix: update * workflow: update linter.yml * fix: update * chore: update * workflow: update * fix: update * fix: update * fix: update * perf: 外链功能实现方式改变 * style: update nav style * perf: 优化国际化 * fix: update * fix: update
This commit is contained in:
		
							parent
							
								
									e86757e30e
								
							
						
					
					
						commit
						fd8de45bff
					
				
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
									
									
									
									
								
							@ -29,7 +29,7 @@
 | 
			
		||||
    "dayjs": "^1.10.6",
 | 
			
		||||
    "dotenv": "^8.2.0",
 | 
			
		||||
    "echarts": "^5.1.2",
 | 
			
		||||
    "element-plus": "^1.1.0-beta.12",
 | 
			
		||||
    "element-plus": "^1.1.0-beta.16",
 | 
			
		||||
    "element-resize-detector": "^1.2.3",
 | 
			
		||||
    "font-awesome": "^4.7.0",
 | 
			
		||||
    "lodash-es": "^4.17.21",
 | 
			
		||||
@ -40,10 +40,10 @@
 | 
			
		||||
    "path-to-regexp": "^6.2.0",
 | 
			
		||||
    "pinia": "^2.0.0-rc.6",
 | 
			
		||||
    "resize-observer-polyfill": "^1.5.1",
 | 
			
		||||
    "responsive-storage": "^1.0.9",
 | 
			
		||||
    "responsive-storage": "^1.0.10",
 | 
			
		||||
    "sortablejs": "1.13.0",
 | 
			
		||||
    "v-contextmenu": "^3.0.0",
 | 
			
		||||
    "vue": "3.2.11",
 | 
			
		||||
    "vue": "^3.2.19",
 | 
			
		||||
    "vue-i18n": "^9.2.0-beta.3",
 | 
			
		||||
    "vue-json-pretty": "^2.0.2",
 | 
			
		||||
    "vue-router": "^4.0.11",
 | 
			
		||||
@ -66,7 +66,7 @@
 | 
			
		||||
    "@typescript-eslint/parser": "^4.31.0",
 | 
			
		||||
    "@vitejs/plugin-vue": "^1.6.0",
 | 
			
		||||
    "@vitejs/plugin-vue-jsx": "^1.1.7",
 | 
			
		||||
    "@vue/compiler-sfc": "3.2.11",
 | 
			
		||||
    "@vue/compiler-sfc": "^3.2.19",
 | 
			
		||||
    "@vue/eslint-config-prettier": "^6.0.0",
 | 
			
		||||
    "@vue/eslint-config-typescript": "^7.0.0",
 | 
			
		||||
    "autoprefixer": "^10.2.4",
 | 
			
		||||
@ -91,7 +91,7 @@
 | 
			
		||||
    "stylelint-order": "^4.1.0",
 | 
			
		||||
    "typescript": "^4.4.2",
 | 
			
		||||
    "unplugin-element-plus": "^0.0.1",
 | 
			
		||||
    "vite": "^2.5.7",
 | 
			
		||||
    "vite": "^2.5.10",
 | 
			
		||||
    "vite-plugin-mock": "^2.9.6",
 | 
			
		||||
    "vite-plugin-style-import": "^1.2.1",
 | 
			
		||||
    "vite-svg-loader": "^2.2.0",
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,8 @@
 | 
			
		||||
@font-face {
 | 
			
		||||
  font-family: "iconfont";
 | 
			
		||||
  src: url("iconfont.eot?t=1619360751585"); /* IE9 */
 | 
			
		||||
  src: url("iconfont.eot?t=1619360751585#iefix") format("embedded-opentype"),
 | 
			
		||||
    /* IE6-IE8 */
 | 
			
		||||
      url("data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAARMAAsAAAAACbwAAAP9AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDQAqGEIRiATYCJAMYCw4ABCAFhG0Hfhs2CMgOJS2d2ECiAwlgBN+vlf0+zE5mg6wAXeJZIjpmuSejwkZFpjyxij57rCLU/p9b+c8NWt6VZsJElIM/LOtvdta6uELEuI1RpSiTq877eC1W5aXc/38/V+f5b2lrettv68Xkvj8zA0+cJTJJQyKSxKSSKBWPlNixsM5M+mTE89a4m0BnrRop+8ZmViBbIQ4KxE1DVyC7cisjwtDamp4zi3ihatOz9BfAc//xMQNNkU1SM3Hk4cujGgyMi5MjaYPhCecti35/94OKjG1AIR72hm9Li+Vt0nSLYro9YHl8K0nj4vjWyaffTiaTMMEW0xUVO53ZUn8t//CqJBMNgbPB31+pjC/TNMH4FprC+FaayuRTmsTkiFuGvdnj1KXAOIiV4K+OJFWaiyg0Ta9XlNpZFnNMMU87Fu6JpEd7eVb2opxYflpfv3a6POca5EdfirMurHNGCE8kd+I1Aga56YZpli8QTd2pkM13zTZ3LWH/yp07FYsroO6K+8wWApapQmIJS/sos3zFfAfHn7h7YNkyBXLpDpx4e1dclrGWJZBjHTZlH7GTZu5+x+JBl122Uu7Dnneswsb7GzdAYdAeAQNsuPCgpUXf26No0Vtakrt6EdLv73FsGfVc+stJczdJknB3izcB36+MxPaRNRuxkhDbHm3uWlgXdtH0nPRZONzVMmLbhDTJuGaPNCfq0vWC2f87RVXNo+ZKmG1whgeqbK2MNlctwFnlMtis7d3MsMNhGBuNtnQt7IjdW4k7NbE3+trR+Ch7WcWwpjkOHUkI4nbFjG3xcHdz1HEIabtS38eCpsmEOO2WrO1tMUMd5tprJzKSyJyclDN2xNNTI/96bFx+DY/OZ1M/Agzf5q9pwwDDd2mR2fk3+hv//gtHjxX1/Gv7BYy+e/TXTxieKPKA/wJB1v9p9MQFZWkUnqbM59f7CDSOyHhvg3RyEX+W+EJf98UsIXcTWksyJD1rIGutYxf+Nqj6dmQarevsprPVOM7vW4RJE2UWtjjLIMz3BpK5PkA23x678L9AtdRvaMyPNOicjLIr9m0II3eYocJRk1bjkqEG/FT5eG7oXUI97FVYafRSgixk5KTGuoZmbRz9yPZxTCiiN3FOJcoCPmmM3Q+93oAUZAE3qrzOxXmwq76e9r1SnRrwQa69GKTgkEayKk5iUAX4Ubs0l9t6/yVIF+alYCPzLlQJxIQYG5c0qtNAYI+jnzTvuWwfEqFrwnF0th/FBPhIxhBEXlkOkAT7d3NDKq6Oa4tiUJd6Po5Sse74jO9VXgcdcdUmUuQoUaOJnt4Dl+JXXeEyPxSI1voUw1/7MCwcm0NW4TI0Df09vyvCmMFradjrDakM0Z+bXAAAAAA=")
 | 
			
		||||
      format("woff2"),
 | 
			
		||||
    url("iconfont.woff?t=1619360751585") format("woff"),
 | 
			
		||||
    url("iconfont.ttf?t=1619360751585") format("truetype"),
 | 
			
		||||
    /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
 | 
			
		||||
      url("iconfont.svg?t=1619360751585#iconfont") format("svg"); /* iOS 4.1- */
 | 
			
		||||
  font-family: "iconfont"; /* Project id 2208059 */
 | 
			
		||||
  src: url("iconfont.woff2?t=1632557807050") format("woff2"),
 | 
			
		||||
    url("iconfont.woff?t=1632557807050") format("woff"),
 | 
			
		||||
    url("iconfont.ttf?t=1632557807050") format("truetype");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.iconfont {
 | 
			
		||||
@ -19,6 +13,10 @@
 | 
			
		||||
  -moz-osx-font-smoothing: grayscale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.team-iconinternationality::before {
 | 
			
		||||
  content: "\e67a";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.team-iconshanchu::before {
 | 
			
		||||
  content: "\e617";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@ -4,13 +4,15 @@
 | 
			
		||||
    l,
 | 
			
		||||
    n,
 | 
			
		||||
    o,
 | 
			
		||||
    i,
 | 
			
		||||
    a =
 | 
			
		||||
      '<svg><symbol id="team-iconshanchu" viewBox="0 0 1024 1024"><path d="M200.0896 166.675692l657.250462 657.218954-33.429662 33.429662-657.250462-657.250462z"  ></path><path d="M166.675692 823.9104l657.218954-657.250462 33.429662 33.429662-657.250462 657.250462z"  ></path></symbol><symbol id="team-iconshow-main-container" viewBox="0 0 1024 1024"><path d="M0 0v1024h1024V0z m409.6 921.6H102.4v-307.2h102.4v204.8h204.8zM409.6 204.8H204.8v204.8H102.4V102.4h307.2z m512 614.4v102.4h-307.2v-102.4h204.8v-204.8h102.4z m0-614.4v204.8h-102.4V204.8h-204.8V102.4h307.2z"  ></path></symbol><symbol id="team-iconhidden-main-container" viewBox="0 0 1024 1024"><path d="M0 0v1024h1024V0z m409.6 716.8v204.8H307.2v-204.8H102.4v-102.4h307.2z m0-409.6v102.4H102.4V307.2h204.8V102.4h102.4z m512 409.6h-204.8v204.8h-102.4v-307.2h307.2z m0-307.2h-307.2V102.4h102.4v204.8h204.8z"  ></path></symbol><symbol id="team-iconexit-fullscreen" viewBox="0 0 1024 1024"><path d="M366.2 181.8c-1-8-10.8-11.4-16.5-5.7l-53.1 53.1L134.2 67c-3.8-3.8-10-3.8-13.7 0L69 118.3c-3.8 3.8-3.8 10 0 13.7l162.4 162.4-53.3 53.3c-5.7 5.7-2.3 15.5 5.7 16.5l194.6 23c6.2 0.7 11.5-4.5 10.8-10.8l-23-194.6z m12.3 453.3l-194.7 23c-8 1-11.4 10.8-5.7 16.5l53.3 53.3L69 890.1c-3.8 3.8-3.8 10 0 13.7l51.5 51.4c3.8 3.8 10 3.8 13.7 0l162.4-162.3 53.1 53.1c5.7 5.7 15.5 2.3 16.5-5.7l23-194.4c0.7-6.3-4.5-11.5-10.7-10.8z m269.4-248l194.7-23c8-1 11.4-10.8 5.7-16.5L795 294.4l162.4-162.3c3.8-3.8 3.8-10 0-13.7L905.9 67c-3.8-3.8-10-3.8-13.7 0L729.7 229.2l-53.1-53.1c-5.7-5.7-15.6-2.3-16.5 5.7l-23 194.5c-0.6 6.3 4.6 11.5 10.8 10.8zM795 727.8l53.3-53.3c5.7-5.7 2.3-15.5-5.7-16.5L648 635c-6.2-0.7-11.5 4.5-10.8 10.8l23 194.6c1 8 10.8 11.4 16.5 5.7l53.1-53.1 162.4 162.3c3.8 3.8 10 3.8 13.7 0l51.5-51.4c3.8-3.8 3.8-10 0-13.7L795 727.8z m0 0" fill="#515151" ></path></symbol><symbol id="team-iconfullscreen" viewBox="0 0 1024 1024"><path d="M229.8 163l55.7-55.7c6-6 2.4-16.2-6-17.2l-203.2-24c-6.5-0.8-12 4.7-11.3 11.3l24 203.2c1 8.4 11.3 11.9 17.2 6l55.4-55.4 169.6 169.4c3.9 3.9 10.4 3.9 14.3 0l53.8-53.6c3.9-3.9 3.9-10.4 0-14.3L229.8 163z m447.3 237.6c3.9 3.9 10.4 3.9 14.3 0L861 231.1l55.4 55.4c6 6 16.2 2.4 17.2-6l24-203c0.8-6.5-4.7-12-11.3-11.3l-203.2 24c-8.4 1-11.9 11.3-6 17.2l55.7 55.7-169.5 169.4c-3.9 3.9-3.9 10.4 0 14.3l53.8 53.8z m256.6 343.9c-1-8.4-11.3-11.9-17.2-6L861 794 691.4 624.5c-3.9-3.9-10.4-3.9-14.3 0l-53.8 53.6c-3.9 3.9-3.9 10.4 0 14.3L792.9 862l-55.7 55.7c-6 6-2.4 16.2 6 17.2l203.2 24c6.5 0.8 12-4.7 11.3-11.3l-24-203.1z m-588.1-120c-3.9-3.9-10.4-3.9-14.3 0L161.7 794l-55.4-55.4c-6-6-16.2-2.4-17.2 6l-24 203c-0.8 6.5 4.7 12.1 11.3 11.3l203.2-24c8.4-1 11.9-11.3 6-17.2l-55.7-55.5 169.6-169.4c3.9-3.9 3.9-10.4 0-14.3l-53.9-54z m0 0" fill="#515151" ></path></symbol></svg>',
 | 
			
		||||
    d = (d = document.getElementsByTagName("script"))[
 | 
			
		||||
      d.length - 1
 | 
			
		||||
    ].getAttribute("data-injectcss");
 | 
			
		||||
  if (d && !e.__iconfont__svg__cssinject__) {
 | 
			
		||||
    i =
 | 
			
		||||
      '<svg><symbol id="team-iconinternationality" viewBox="0 0 1024 1024"><path d="M219.4 363.4c11.8 35 31.4 65.4 58.7 92.2 23.2-25.2 40.7-56.2 52-92.2H219.4z m722.2-207.1H508.9L484.2 23.9H82.4C38.1 23.9 2 60 2 104.3v683.1c0 44.3 36.1 80.4 80.4 80.4h366.3l-29.4 132.4h522.4c44.3 0 80.4-36.1 80.4-80.4V236.7c-0.1-44.4-36.2-80.4-80.5-80.4zM396.1 562.2c-47.4-17.5-86.5-39.7-118-65.4-33 29.4-74.2 51-122.1 64.4l-16.5-27.3c46.9-12.4 86-30.9 116.9-57.2-31.9-32.5-54.1-70.1-66.5-112.8h-44.8V333H262c-7.2-13.4-16.5-26.3-27.3-38.6l30.9-11.3c10.8 13.9 20.6 30.4 29.4 49.5h111.8v30.9H362c-14.4 44.3-35 81.4-62.3 111.3 30.4 24.2 68.5 44.3 113.3 60.8l-16.9 26.6z m585.7 357c0 22.2-18 40.2-40.2 40.2H469.8l20.1-92.2h150.9l-86-479.6-0.5 2.6-3.6-19.1 1 0.5-31.4-175.2h421.9c22.2 0 40.2 18 40.2 40.2v682.6h-0.6zM655.2 540.1H766v-29.4H655.2V452h118v-29.4H620.7v211.2h157.1v-29.4H655.2v-64.3z m231.3-63.4c-9.3 0-17.5 1.5-25.2 5.7-7.2 3.6-14.4 9.3-20.1 16.5v-18h-33.5v153h33.5v-92.2c1-12.4 5.2-21.6 12.4-28.3 6.2-5.7 13.4-8.8 21.6-8.8 23.2 0 34.5 12.4 34.5 37.6v91.2h33.5V539c1-41.7-18.6-62.3-56.7-62.3z"  ></path></symbol><symbol id="team-iconshanchu" viewBox="0 0 1024 1024"><path d="M200.0896 166.675692l657.250462 657.218954-33.429662 33.429662-657.250462-657.250462z"  ></path><path d="M166.675692 823.9104l657.218954-657.250462 33.429662 33.429662-657.250462 657.250462z"  ></path></symbol><symbol id="team-iconshow-main-container" viewBox="0 0 1024 1024"><path d="M0 0v1024h1024V0z m409.6 921.6H102.4v-307.2h102.4v204.8h204.8zM409.6 204.8H204.8v204.8H102.4V102.4h307.2z m512 614.4v102.4h-307.2v-102.4h204.8v-204.8h102.4z m0-614.4v204.8h-102.4V204.8h-204.8V102.4h307.2z"  ></path></symbol><symbol id="team-iconhidden-main-container" viewBox="0 0 1024 1024"><path d="M0 0v1024h1024V0z m409.6 716.8v204.8H307.2v-204.8H102.4v-102.4h307.2z m0-409.6v102.4H102.4V307.2h204.8V102.4h102.4z m512 409.6h-204.8v204.8h-102.4v-307.2h307.2z m0-307.2h-307.2V102.4h102.4v204.8h204.8z"  ></path></symbol><symbol id="team-iconexit-fullscreen" viewBox="0 0 1024 1024"><path d="M366.2 181.8c-1-8-10.8-11.4-16.5-5.7l-53.1 53.1L134.2 67c-3.8-3.8-10-3.8-13.7 0L69 118.3c-3.8 3.8-3.8 10 0 13.7l162.4 162.4-53.3 53.3c-5.7 5.7-2.3 15.5 5.7 16.5l194.6 23c6.2 0.7 11.5-4.5 10.8-10.8l-23-194.6z m12.3 453.3l-194.7 23c-8 1-11.4 10.8-5.7 16.5l53.3 53.3L69 890.1c-3.8 3.8-3.8 10 0 13.7l51.5 51.4c3.8 3.8 10 3.8 13.7 0l162.4-162.3 53.1 53.1c5.7 5.7 15.5 2.3 16.5-5.7l23-194.4c0.7-6.3-4.5-11.5-10.7-10.8z m269.4-248l194.7-23c8-1 11.4-10.8 5.7-16.5L795 294.4l162.4-162.3c3.8-3.8 3.8-10 0-13.7L905.9 67c-3.8-3.8-10-3.8-13.7 0L729.7 229.2l-53.1-53.1c-5.7-5.7-15.6-2.3-16.5 5.7l-23 194.5c-0.6 6.3 4.6 11.5 10.8 10.8zM795 727.8l53.3-53.3c5.7-5.7 2.3-15.5-5.7-16.5L648 635c-6.2-0.7-11.5 4.5-10.8 10.8l23 194.6c1 8 10.8 11.4 16.5 5.7l53.1-53.1 162.4 162.3c3.8 3.8 10 3.8 13.7 0l51.5-51.4c3.8-3.8 3.8-10 0-13.7L795 727.8z m0 0" fill="#515151" ></path></symbol><symbol id="team-iconfullscreen" viewBox="0 0 1024 1024"><path d="M229.8 163l55.7-55.7c6-6 2.4-16.2-6-17.2l-203.2-24c-6.5-0.8-12 4.7-11.3 11.3l24 203.2c1 8.4 11.3 11.9 17.2 6l55.4-55.4 169.6 169.4c3.9 3.9 10.4 3.9 14.3 0l53.8-53.6c3.9-3.9 3.9-10.4 0-14.3L229.8 163z m447.3 237.6c3.9 3.9 10.4 3.9 14.3 0L861 231.1l55.4 55.4c6 6 16.2 2.4 17.2-6l24-203c0.8-6.5-4.7-12-11.3-11.3l-203.2 24c-8.4 1-11.9 11.3-6 17.2l55.7 55.7-169.5 169.4c-3.9 3.9-3.9 10.4 0 14.3l53.8 53.8z m256.6 343.9c-1-8.4-11.3-11.9-17.2-6L861 794 691.4 624.5c-3.9-3.9-10.4-3.9-14.3 0l-53.8 53.6c-3.9 3.9-3.9 10.4 0 14.3L792.9 862l-55.7 55.7c-6 6-2.4 16.2 6 17.2l203.2 24c6.5 0.8 12-4.7 11.3-11.3l-24-203.1z m-588.1-120c-3.9-3.9-10.4-3.9-14.3 0L161.7 794l-55.4-55.4c-6-6-16.2-2.4-17.2 6l-24 203c-0.8 6.5 4.7 12.1 11.3 11.3l203.2-24c8.4-1 11.9-11.3 6-17.2l-55.7-55.5 169.6-169.4c3.9-3.9 3.9-10.4 0-14.3l-53.9-54z m0 0" fill="#515151" ></path></symbol></svg>',
 | 
			
		||||
    h = (h = document.getElementsByTagName("script"))[
 | 
			
		||||
      h.length - 1
 | 
			
		||||
    ].getAttribute("data-injectcss"),
 | 
			
		||||
    a = function (e, t) {
 | 
			
		||||
      t.parentNode.insertBefore(e, t);
 | 
			
		||||
    };
 | 
			
		||||
  if (h && !e.__iconfont__svg__cssinject__) {
 | 
			
		||||
    e.__iconfont__svg__cssinject__ = !0;
 | 
			
		||||
    try {
 | 
			
		||||
      document.write(
 | 
			
		||||
@ -23,20 +25,26 @@
 | 
			
		||||
  function m() {
 | 
			
		||||
    o || ((o = !0), l());
 | 
			
		||||
  }
 | 
			
		||||
  function d() {
 | 
			
		||||
    try {
 | 
			
		||||
      n.documentElement.doScroll("left");
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      return void setTimeout(d, 50);
 | 
			
		||||
    }
 | 
			
		||||
    m();
 | 
			
		||||
  }
 | 
			
		||||
  (t = function () {
 | 
			
		||||
    var e, t, c, l;
 | 
			
		||||
    ((l = document.createElement("div")).innerHTML = a),
 | 
			
		||||
      (a = null),
 | 
			
		||||
      (c = l.getElementsByTagName("svg")[0]) &&
 | 
			
		||||
        (c.setAttribute("aria-hidden", "true"),
 | 
			
		||||
        (c.style.position = "absolute"),
 | 
			
		||||
        (c.style.width = 0),
 | 
			
		||||
        (c.style.height = 0),
 | 
			
		||||
        (c.style.overflow = "hidden"),
 | 
			
		||||
        (e = c),
 | 
			
		||||
        (t = document.body).firstChild
 | 
			
		||||
          ? ((l = e), (c = t.firstChild).parentNode.insertBefore(l, c))
 | 
			
		||||
          : t.appendChild(e));
 | 
			
		||||
    var e, t;
 | 
			
		||||
    ((t = document.createElement("div")).innerHTML = i),
 | 
			
		||||
      (i = null),
 | 
			
		||||
      (e = t.getElementsByTagName("svg")[0]) &&
 | 
			
		||||
        (e.setAttribute("aria-hidden", "true"),
 | 
			
		||||
        (e.style.position = "absolute"),
 | 
			
		||||
        (e.style.width = 0),
 | 
			
		||||
        (e.style.height = 0),
 | 
			
		||||
        (e.style.overflow = "hidden"),
 | 
			
		||||
        (t = e),
 | 
			
		||||
        (e = document.body).firstChild ? a(t, e.firstChild) : e.appendChild(t));
 | 
			
		||||
  }),
 | 
			
		||||
    document.addEventListener
 | 
			
		||||
      ? ~["complete", "loaded", "interactive"].indexOf(document.readyState)
 | 
			
		||||
@ -49,14 +57,7 @@
 | 
			
		||||
        ((l = t),
 | 
			
		||||
        (n = e.document),
 | 
			
		||||
        (o = !1),
 | 
			
		||||
        (i = function () {
 | 
			
		||||
          try {
 | 
			
		||||
            n.documentElement.doScroll("left");
 | 
			
		||||
          } catch (e) {
 | 
			
		||||
            return void setTimeout(i, 50);
 | 
			
		||||
          }
 | 
			
		||||
          m();
 | 
			
		||||
        })(),
 | 
			
		||||
        d(),
 | 
			
		||||
        (n.onreadystatechange = function () {
 | 
			
		||||
          "complete" == n.readyState && ((n.onreadystatechange = null), m());
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,17 @@
 | 
			
		||||
{
 | 
			
		||||
  "id": "2208059",
 | 
			
		||||
  "name": "CURD-TS",
 | 
			
		||||
  "name": "pure-admin",
 | 
			
		||||
  "font_family": "iconfont",
 | 
			
		||||
  "css_prefix_text": "team-icon",
 | 
			
		||||
  "description": "增删查改xi't",
 | 
			
		||||
  "description": "pure-admin",
 | 
			
		||||
  "glyphs": [
 | 
			
		||||
    {
 | 
			
		||||
      "icon_id": "18367956",
 | 
			
		||||
      "name": "中英文2 中文",
 | 
			
		||||
      "font_class": "internationality",
 | 
			
		||||
      "unicode": "e67a",
 | 
			
		||||
      "unicode_decimal": 59002
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "icon_id": "6184565",
 | 
			
		||||
      "name": "删除",
 | 
			
		||||
 | 
			
		||||
@ -1,41 +0,0 @@
 | 
			
		||||
<?xml version="1.0" standalone="no"?>
 | 
			
		||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
 | 
			
		||||
<!--
 | 
			
		||||
2013-9-30: Created.
 | 
			
		||||
-->
 | 
			
		||||
<svg>
 | 
			
		||||
<metadata>
 | 
			
		||||
Created by iconfont
 | 
			
		||||
</metadata>
 | 
			
		||||
<defs>
 | 
			
		||||
 | 
			
		||||
<font id="iconfont" horiz-adv-x="1024" >
 | 
			
		||||
  <font-face
 | 
			
		||||
    font-family="iconfont"
 | 
			
		||||
    font-weight="500"
 | 
			
		||||
    font-stretch="normal"
 | 
			
		||||
    units-per-em="1024"
 | 
			
		||||
    ascent="896"
 | 
			
		||||
    descent="-128"
 | 
			
		||||
  />
 | 
			
		||||
    <missing-glyph />
 | 
			
		||||
    
 | 
			
		||||
    <glyph glyph-name="shanchu" unicode="" d="M200.0896 729.324308l657.250462-657.218954-33.429662-33.429662-657.250462 657.250462zM166.675692 72.0896l657.218954 657.250462 33.429662-33.429662-657.250462-657.250462z"  horiz-adv-x="1024" />
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    <glyph glyph-name="show-main-container" unicode="" d="M0 896v-1024h1024V896z m409.6-921.6H102.4v307.2h102.4v-204.8h204.8zM409.6 691.2H204.8v-204.8H102.4V793.6h307.2z m512-614.4v-102.4h-307.2v102.4h204.8v204.8h102.4z m0 614.4v-204.8h-102.4V691.2h-204.8V793.6h307.2z"  horiz-adv-x="1024" />
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    <glyph glyph-name="hidden-main-container" unicode="" d="M0 896v-1024h1024V896z m409.6-716.8v-204.8H307.2v204.8H102.4v102.4h307.2z m0 409.6v-102.4H102.4V588.8h204.8V793.6h102.4z m512-409.6h-204.8v-204.8h-102.4v307.2h307.2z m0 307.2h-307.2V793.6h102.4v-204.8h204.8z"  horiz-adv-x="1024" />
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    <glyph glyph-name="exit-fullscreen" unicode="" d="M366.2 714.2c-1 8-10.8 11.4-16.5 5.7l-53.1-53.1L134.2 829c-3.8 3.8-10 3.8-13.7 0L69 777.7c-3.8-3.8-3.8-10 0-13.7l162.4-162.4-53.3-53.3c-5.7-5.7-2.3-15.5 5.7-16.5l194.6-23c6.2-0.7 11.5 4.5 10.8 10.8l-23 194.6z m12.3-453.3l-194.7-23c-8-1-11.4-10.8-5.7-16.5l53.3-53.3L69 5.899999999999977c-3.8-3.8-3.8-10 0-13.7l51.5-51.4c3.8-3.8 10-3.8 13.7 0l162.4 162.3 53.1-53.1c5.7-5.7 15.5-2.3 16.5 5.7l23 194.4c0.7 6.3-4.5 11.5-10.7 10.8z m269.4 248l194.7 23c8 1 11.4 10.8 5.7 16.5L795 601.6l162.4 162.3c3.8 3.8 3.8 10 0 13.7L905.9 829c-3.8 3.8-10 3.8-13.7 0L729.7 666.8l-53.1 53.1c-5.7 5.7-15.6 2.3-16.5-5.7l-23-194.5c-0.6-6.3 4.6-11.5 10.8-10.8zM795 168.20000000000005l53.3 53.3c5.7 5.7 2.3 15.5-5.7 16.5L648 261c-6.2 0.7-11.5-4.5-10.8-10.8l23-194.6c1-8 10.8-11.4 16.5-5.7l53.1 53.1 162.4-162.3c3.8-3.8 10-3.8 13.7 0l51.5 51.4c3.8 3.8 3.8 10 0 13.7L795 168.20000000000005z m0 0"  horiz-adv-x="1024" />
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    <glyph glyph-name="fullscreen" unicode="" d="M229.8 733l55.7 55.7c6 6 2.4 16.2-6 17.2l-203.2 24c-6.5 0.8-12-4.7-11.3-11.3l24-203.2c1-8.4 11.3-11.9 17.2-6l55.4 55.4 169.6-169.4c3.9-3.9 10.4-3.9 14.3 0l53.8 53.6c3.9 3.9 3.9 10.4 0 14.3L229.8 733z m447.3-237.6c3.9-3.9 10.4-3.9 14.3 0L861 664.9l55.4-55.4c6-6 16.2-2.4 17.2 6l24 203c0.8 6.5-4.7 12-11.3 11.3l-203.2-24c-8.4-1-11.9-11.3-6-17.2l55.7-55.7-169.5-169.4c-3.9-3.9-3.9-10.4 0-14.3l53.8-53.8z m256.6-343.9c-1 8.4-11.3 11.9-17.2 6L861 102 691.4 271.5c-3.9 3.9-10.4 3.9-14.3 0l-53.8-53.6c-3.9-3.9-3.9-10.4 0-14.3L792.9 34l-55.7-55.7c-6-6-2.4-16.2 6-17.2l203.2-24c6.5-0.8 12 4.7 11.3 11.3l-24 203.1z m-588.1 120c-3.9 3.9-10.4 3.9-14.3 0L161.7 102l-55.4 55.4c-6 6-16.2 2.4-17.2-6l-24-203c-0.8-6.5 4.7-12.1 11.3-11.3l203.2 24c8.4 1 11.9 11.3 6 17.2l-55.7 55.5 169.6 169.4c3.9 3.9 3.9 10.4 0 14.3l-53.9 54z m0 0"  horiz-adv-x="1024" />
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  </font>
 | 
			
		||||
</defs></svg>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 3.1 KiB  | 
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										1
									
								
								src/assets/svg/iconinternationality.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/assets/svg/iconinternationality.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="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>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 972 B  | 
@ -1,3 +1,5 @@
 | 
			
		||||
import { App } from "vue";
 | 
			
		||||
import axios from "axios";
 | 
			
		||||
let config: object = {};
 | 
			
		||||
 | 
			
		||||
const setConfig = (cfg?: unknown) => {
 | 
			
		||||
@ -22,4 +24,33 @@ const getConfig = (key?: string) => {
 | 
			
		||||
  return config;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 获取项目动态全局配置
 | 
			
		||||
export const getServerConfig = async (app: App): Promise<undefined> => {
 | 
			
		||||
  app.config.globalProperties.$config = getConfig();
 | 
			
		||||
  return axios({
 | 
			
		||||
    baseURL: "",
 | 
			
		||||
    method: "get",
 | 
			
		||||
    url:
 | 
			
		||||
      process.env.NODE_ENV === "production"
 | 
			
		||||
        ? "/manages/serverConfig.json"
 | 
			
		||||
        : "/serverConfig.json"
 | 
			
		||||
  })
 | 
			
		||||
    .then(({ data: config }) => {
 | 
			
		||||
      let $config = app.config.globalProperties.$config;
 | 
			
		||||
      // 自动注入项目配置
 | 
			
		||||
      if (app && $config && typeof config === "object") {
 | 
			
		||||
        $config = Object.assign($config, config);
 | 
			
		||||
        app.config.globalProperties.$config = $config;
 | 
			
		||||
        // 设置全局配置
 | 
			
		||||
        setConfig($config);
 | 
			
		||||
      }
 | 
			
		||||
      // 设置全局baseURL
 | 
			
		||||
      app.config.globalProperties.$baseUrl = $config.baseURL;
 | 
			
		||||
      return $config;
 | 
			
		||||
    })
 | 
			
		||||
    .catch(() => {
 | 
			
		||||
      throw "请在public文件夹下添加serverConfig.json配置文件";
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export { getConfig, setConfig };
 | 
			
		||||
 | 
			
		||||
@ -1,5 +0,0 @@
 | 
			
		||||
export { default as Navbar } from "./Navbar.vue";
 | 
			
		||||
export { default as Sidebar } from "./sidebar/index.vue";
 | 
			
		||||
export { default as AppMain } from "./AppMain.vue";
 | 
			
		||||
export { default as setting } from "./setting/index.vue";
 | 
			
		||||
export { default as tag } from "./tag/index.vue";
 | 
			
		||||
@ -8,98 +8,84 @@
 | 
			
		||||
 | 
			
		||||
    <Breadcrumb class="breadcrumb-container" />
 | 
			
		||||
 | 
			
		||||
    <div class="right-menu">
 | 
			
		||||
    <div class="vertical-header-right">
 | 
			
		||||
      <!-- 全屏 -->
 | 
			
		||||
      <screenfull v-show="!deviceDetection()" />
 | 
			
		||||
      <!-- 国际化 -->
 | 
			
		||||
      <div
 | 
			
		||||
        v-show="!deviceDetection()"
 | 
			
		||||
        class="inter"
 | 
			
		||||
        :title="currentLocale ? '中文' : 'English'"
 | 
			
		||||
        @click="toggleLang"
 | 
			
		||||
      >
 | 
			
		||||
        <img :src="currentLocale ? ch : en" />
 | 
			
		||||
      </div>
 | 
			
		||||
      <i
 | 
			
		||||
        class="el-icon-setting hsset"
 | 
			
		||||
        :title="$t('message.hssystemSet')"
 | 
			
		||||
        @click="onPanel"
 | 
			
		||||
      ></i>
 | 
			
		||||
      <el-dropdown trigger="click">
 | 
			
		||||
        <iconinternationality />
 | 
			
		||||
        <template #dropdown>
 | 
			
		||||
          <el-dropdown-menu class="translation">
 | 
			
		||||
            <el-dropdown-item
 | 
			
		||||
              :style="{
 | 
			
		||||
                background: locale === 'zh' ? '#1b2a47' : '',
 | 
			
		||||
                color: locale === 'zh' ? '#f4f4f5' : '#000'
 | 
			
		||||
              }"
 | 
			
		||||
              @click="translationCh"
 | 
			
		||||
              >简体中文</el-dropdown-item
 | 
			
		||||
            >
 | 
			
		||||
            <el-dropdown-item
 | 
			
		||||
              :style="{
 | 
			
		||||
                background: locale === 'en' ? '#1b2a47' : '',
 | 
			
		||||
                color: locale === 'en' ? '#f4f4f5' : '#000'
 | 
			
		||||
              }"
 | 
			
		||||
              @click="translationEn"
 | 
			
		||||
              >English</el-dropdown-item
 | 
			
		||||
            >
 | 
			
		||||
          </el-dropdown-menu>
 | 
			
		||||
        </template>
 | 
			
		||||
      </el-dropdown>
 | 
			
		||||
      <!-- 退出登陆 -->
 | 
			
		||||
      <el-dropdown trigger="click">
 | 
			
		||||
        <span class="el-dropdown-link">
 | 
			
		||||
          <img :src="favicon" />
 | 
			
		||||
          <img
 | 
			
		||||
            src="https://avatars.githubusercontent.com/u/44761321?s=400&u=30907819abd29bb3779bc247910873e7c7f7c12f&v=4"
 | 
			
		||||
          />
 | 
			
		||||
          <p>{{ usename }}</p>
 | 
			
		||||
        </span>
 | 
			
		||||
        <template #dropdown>
 | 
			
		||||
          <el-dropdown-menu>
 | 
			
		||||
          <el-dropdown-menu class="logout">
 | 
			
		||||
            <el-dropdown-item icon="el-icon-switch-button" @click="logout">{{
 | 
			
		||||
              $t("message.hsLoginOut")
 | 
			
		||||
            }}</el-dropdown-item>
 | 
			
		||||
          </el-dropdown-menu>
 | 
			
		||||
        </template>
 | 
			
		||||
      </el-dropdown>
 | 
			
		||||
      <i
 | 
			
		||||
        class="el-icon-setting"
 | 
			
		||||
        :title="$t('message.hssystemSet')"
 | 
			
		||||
        @click="onPanel"
 | 
			
		||||
      ></i>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import {
 | 
			
		||||
  defineComponent,
 | 
			
		||||
  onMounted,
 | 
			
		||||
  unref,
 | 
			
		||||
  watch,
 | 
			
		||||
  getCurrentInstance
 | 
			
		||||
} from "vue";
 | 
			
		||||
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 ch from "/@/assets/ch.png";
 | 
			
		||||
import en from "/@/assets/en.png";
 | 
			
		||||
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";
 | 
			
		||||
 | 
			
		||||
let routerArrays: Array<object> = [
 | 
			
		||||
  {
 | 
			
		||||
    path: "/welcome",
 | 
			
		||||
    parentPath: "/",
 | 
			
		||||
    meta: {
 | 
			
		||||
      title: "message.hshome",
 | 
			
		||||
      icon: "el-icon-s-home",
 | 
			
		||||
      showLink: true,
 | 
			
		||||
      savedPosition: false
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
];
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
  name: "Navbar",
 | 
			
		||||
  components: {
 | 
			
		||||
    Breadcrumb,
 | 
			
		||||
    Hamburger,
 | 
			
		||||
    screenfull
 | 
			
		||||
    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;
 | 
			
		||||
@ -114,25 +100,9 @@ export default defineComponent({
 | 
			
		||||
    const pureApp = useAppStoreHook();
 | 
			
		||||
    const router = useRouter();
 | 
			
		||||
    const route = useRoute();
 | 
			
		||||
 | 
			
		||||
    let usename = storageSession.getItem("info")?.username;
 | 
			
		||||
 | 
			
		||||
    const { locale, t } = useI18n();
 | 
			
		||||
 | 
			
		||||
    // 国际化语言切换
 | 
			
		||||
    const toggleLang = (): void => {
 | 
			
		||||
      switch (instance.locale.locale) {
 | 
			
		||||
        case "zh":
 | 
			
		||||
          instance.locale = { locale: "en" };
 | 
			
		||||
          locale.value = "en";
 | 
			
		||||
          break;
 | 
			
		||||
        case "en":
 | 
			
		||||
          instance.locale = { locale: "zh" };
 | 
			
		||||
          locale.value = "zh";
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    watch(
 | 
			
		||||
      () => locale.value,
 | 
			
		||||
      () => {
 | 
			
		||||
@ -155,28 +125,31 @@ export default defineComponent({
 | 
			
		||||
      pureApp.toggleSideBar();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onMounted(() => {
 | 
			
		||||
      document
 | 
			
		||||
        .querySelector(".el-dropdown__popper")
 | 
			
		||||
        ?.setAttribute("class", "resetTop");
 | 
			
		||||
      document
 | 
			
		||||
        .querySelector(".el-popper__arrow")
 | 
			
		||||
        ?.setAttribute("class", "hidden");
 | 
			
		||||
    });
 | 
			
		||||
    // 简体中文
 | 
			
		||||
    function translationCh() {
 | 
			
		||||
      instance.locale = { locale: "zh" };
 | 
			
		||||
      locale.value = "zh";
 | 
			
		||||
      window.location.reload();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // English
 | 
			
		||||
    function translationEn() {
 | 
			
		||||
      instance.locale = { locale: "en" };
 | 
			
		||||
      locale.value = "en";
 | 
			
		||||
      window.location.reload();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      pureApp,
 | 
			
		||||
      toggleSideBar,
 | 
			
		||||
      usename,
 | 
			
		||||
      toggleLang,
 | 
			
		||||
      logout,
 | 
			
		||||
      ch,
 | 
			
		||||
      en,
 | 
			
		||||
      favicon,
 | 
			
		||||
      onPanel,
 | 
			
		||||
      deviceDetection,
 | 
			
		||||
      locale,
 | 
			
		||||
      t
 | 
			
		||||
      usename,
 | 
			
		||||
      pureApp,
 | 
			
		||||
      favicon,
 | 
			
		||||
      logout,
 | 
			
		||||
      onPanel,
 | 
			
		||||
      translationCh,
 | 
			
		||||
      translationEn,
 | 
			
		||||
      toggleSideBar,
 | 
			
		||||
      deviceDetection
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
@ -185,13 +158,13 @@ export default defineComponent({
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.navbar {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 50px;
 | 
			
		||||
  height: 48px;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  background: #fff;
 | 
			
		||||
  box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
 | 
			
		||||
 | 
			
		||||
  .hamburger-container {
 | 
			
		||||
    line-height: 46px;
 | 
			
		||||
    line-height: 48px;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    float: left;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
@ -203,56 +176,46 @@ export default defineComponent({
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .breadcrumb-container {
 | 
			
		||||
    float: left;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .right-menu {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    right: 0;
 | 
			
		||||
  .vertical-header-right {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    min-width: 280px;
 | 
			
		||||
    height: 48px;
 | 
			
		||||
    line-height: 48px;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    color: #000000d9;
 | 
			
		||||
    justify-content: flex-end;
 | 
			
		||||
 | 
			
		||||
    .inter {
 | 
			
		||||
      width: 40px;
 | 
			
		||||
      height: 48px;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: space-around;
 | 
			
		||||
    .screen-full {
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
 | 
			
		||||
      &:hover {
 | 
			
		||||
        cursor: pointer;
 | 
			
		||||
        background: #f0f0f0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      img {
 | 
			
		||||
        width: 25px;
 | 
			
		||||
        background: #f6f6f6;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .hsset {
 | 
			
		||||
      width: 40px;
 | 
			
		||||
    .iconinternationality {
 | 
			
		||||
      height: 48px;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: space-around;
 | 
			
		||||
      margin-right: 5px;
 | 
			
		||||
      width: 40px;
 | 
			
		||||
      padding: 11px;
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
 | 
			
		||||
      &:hover {
 | 
			
		||||
        cursor: pointer;
 | 
			
		||||
        background: #f0f0f0;
 | 
			
		||||
        background: #f6f6f6;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .el-dropdown-link {
 | 
			
		||||
      width: 70px;
 | 
			
		||||
      width: 100px;
 | 
			
		||||
      height: 48px;
 | 
			
		||||
      padding: 10px;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: space-around;
 | 
			
		||||
      margin-right: 10px;
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
      color: #000000d9;
 | 
			
		||||
 | 
			
		||||
      &:hover {
 | 
			
		||||
        background: #f6f6f6;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      p {
 | 
			
		||||
        font-size: 14px;
 | 
			
		||||
@ -261,22 +224,50 @@ export default defineComponent({
 | 
			
		||||
      img {
 | 
			
		||||
        width: 22px;
 | 
			
		||||
        height: 22px;
 | 
			
		||||
        border-radius: 50%;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .el-icon-setting {
 | 
			
		||||
      height: 48px;
 | 
			
		||||
      width: 40px;
 | 
			
		||||
      padding: 11px;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
 | 
			
		||||
      &:hover {
 | 
			
		||||
        background: #f6f6f6;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
// single element-plus reset
 | 
			
		||||
.el-dropdown-menu__item {
 | 
			
		||||
  padding: 0 10px;
 | 
			
		||||
 | 
			
		||||
  .breadcrumb-container {
 | 
			
		||||
    float: left;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.el-dropdown-menu {
 | 
			
		||||
  padding: 6px 0;
 | 
			
		||||
.translation {
 | 
			
		||||
  .el-dropdown-menu__item {
 | 
			
		||||
    padding: 0 40px !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .el-dropdown-menu__item:focus,
 | 
			
		||||
  .el-dropdown-menu__item:not(.is-disabled):hover {
 | 
			
		||||
    color: #606266;
 | 
			
		||||
    background: #f0f0f0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.el-dropdown-menu__item:focus,
 | 
			
		||||
.el-dropdown-menu__item:not(.is-disabled):hover {
 | 
			
		||||
  color: #606266;
 | 
			
		||||
  background: #f0f0f0;
 | 
			
		||||
.logout {
 | 
			
		||||
  .el-dropdown-menu__item {
 | 
			
		||||
    padding: 0 18px !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .el-dropdown-menu__item:focus,
 | 
			
		||||
  .el-dropdown-menu__item:not(.is-disabled):hover {
 | 
			
		||||
    color: #606266;
 | 
			
		||||
    background: #f0f0f0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@ -3,7 +3,7 @@ import { ref } from "vue";
 | 
			
		||||
import { useEventListener, onClickOutside } from "@vueuse/core";
 | 
			
		||||
import { emitter } from "/@/utils/mitt";
 | 
			
		||||
 | 
			
		||||
let show = ref(false);
 | 
			
		||||
let show = ref<Boolean>(false);
 | 
			
		||||
const target = ref(null);
 | 
			
		||||
onClickOutside(target, () => {
 | 
			
		||||
  show.value = false;
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { useFullscreen } from "@vueuse/core";
 | 
			
		||||
 | 
			
		||||
const { isFullscreen, toggle } = useFullscreen();
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -23,15 +22,10 @@ const { isFullscreen, toggle } = useFullscreen();
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.screen-full {
 | 
			
		||||
  width: 40px;
 | 
			
		||||
  height: 48px;
 | 
			
		||||
  width: 36px;
 | 
			
		||||
  height: 62px;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  justify-content: space-around;
 | 
			
		||||
 | 
			
		||||
  &:hover {
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    background: #f0f0f0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,18 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { split } from "lodash-es";
 | 
			
		||||
import panel from "../panel/index.vue";
 | 
			
		||||
import { useRouter } from "vue-router";
 | 
			
		||||
import { emitter } from "/@/utils/mitt";
 | 
			
		||||
import { templateRef } from "@vueuse/core";
 | 
			
		||||
import { reactive, ref, unref, useCssModule } from "vue";
 | 
			
		||||
import { storageLocal, storageSession } from "/@/utils/storage";
 | 
			
		||||
import { reactive, ref, unref, useCssModule, getCurrentInstance } from "vue";
 | 
			
		||||
 | 
			
		||||
const router = useRouter();
 | 
			
		||||
const { isSelect } = useCssModule();
 | 
			
		||||
 | 
			
		||||
const instance =
 | 
			
		||||
  getCurrentInstance().appContext.app.config.globalProperties.$storage;
 | 
			
		||||
 | 
			
		||||
// 默认灵动模式
 | 
			
		||||
const markValue = ref(storageLocal.getItem("showModel") || "smart");
 | 
			
		||||
 | 
			
		||||
@ -80,37 +84,54 @@ function onChange({ label }) {
 | 
			
		||||
  emitter.emit("tagViewsShowModel", label);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const firstTheme = templateRef<HTMLElement | null>("firstTheme", null);
 | 
			
		||||
const secondTheme = templateRef<HTMLElement | null>("secondTheme", null);
 | 
			
		||||
const verticalDarkDom = templateRef<HTMLElement | null>(
 | 
			
		||||
  "verticalDarkDom",
 | 
			
		||||
  null
 | 
			
		||||
);
 | 
			
		||||
const verticalLightDom = templateRef<HTMLElement | null>(
 | 
			
		||||
  "verticalLightDom",
 | 
			
		||||
  null
 | 
			
		||||
);
 | 
			
		||||
const horizontalDarkDom = templateRef<HTMLElement | null>(
 | 
			
		||||
  "horizontalDarkDom",
 | 
			
		||||
  null
 | 
			
		||||
);
 | 
			
		||||
const horizontalLightDom = templateRef<HTMLElement | null>(
 | 
			
		||||
  "horizontalLightDom",
 | 
			
		||||
  null
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const dataTheme = ref(storageLocal.getItem("data-theme") || "dark");
 | 
			
		||||
if (dataTheme.value) {
 | 
			
		||||
  storageLocal.setItem("data-theme", unref(dataTheme));
 | 
			
		||||
  window.document.body.setAttribute("data-theme", unref(dataTheme));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// dark主题
 | 
			
		||||
function onDark() {
 | 
			
		||||
  storageLocal.setItem("data-theme", "dark");
 | 
			
		||||
  window.document.body.setAttribute("data-theme", "dark");
 | 
			
		||||
  toggleClass(true, isSelect, unref(firstTheme));
 | 
			
		||||
  toggleClass(false, isSelect, unref(secondTheme));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// light主题
 | 
			
		||||
function onLight() {
 | 
			
		||||
  storageLocal.setItem("data-theme", "light");
 | 
			
		||||
  window.document.body.setAttribute("data-theme", "light");
 | 
			
		||||
  toggleClass(false, isSelect, unref(firstTheme));
 | 
			
		||||
  toggleClass(true, isSelect, unref(secondTheme));
 | 
			
		||||
let dataTheme =
 | 
			
		||||
  ref(storageLocal.getItem("responsive-layout")) ||
 | 
			
		||||
  ref({
 | 
			
		||||
    layout: "horizontal-dark"
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
if (unref(dataTheme)) {
 | 
			
		||||
  // 设置主题
 | 
			
		||||
  let theme = split(unref(dataTheme).layout, "-")[1];
 | 
			
		||||
  window.document.body.setAttribute("data-theme", theme);
 | 
			
		||||
  // 设置导航模式
 | 
			
		||||
  let layout = split(unref(dataTheme).layout, "-")[0];
 | 
			
		||||
  window.document.body.setAttribute("data-layout", layout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 侧边栏Logo
 | 
			
		||||
function logoChange() {
 | 
			
		||||
  unref(logoVal) === "1"
 | 
			
		||||
    ? storageLocal.setItem("logoVal", "1")
 | 
			
		||||
    : storageLocal.setItem("logoVal", "-1");
 | 
			
		||||
  emitter.emit("logoChange", unref(logoVal));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function setTheme(layout: string, theme: string, dom: HTMLElement) {
 | 
			
		||||
  dataTheme.value.layout = `${layout}-${theme}`;
 | 
			
		||||
  window.document.body.setAttribute("data-layout", layout);
 | 
			
		||||
  window.document.body.setAttribute("data-theme", theme);
 | 
			
		||||
  instance.layout = { layout: `${layout}-${theme}` };
 | 
			
		||||
  toggleClass(true, isSelect, unref(dom));
 | 
			
		||||
  toggleClass(false, isSelect, unref(dom));
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
@ -124,9 +145,9 @@ function logoChange() {
 | 
			
		||||
        placement="bottom"
 | 
			
		||||
      >
 | 
			
		||||
        <li
 | 
			
		||||
          :class="dataTheme === 'dark' ? $style.isSelect : ''"
 | 
			
		||||
          ref="firstTheme"
 | 
			
		||||
          @click="onDark"
 | 
			
		||||
          :class="dataTheme.layout === 'vertical-dark' ? $style.isSelect : ''"
 | 
			
		||||
          ref="verticalDarkDom"
 | 
			
		||||
          @click="setTheme('vertical', 'dark', verticalDarkDom)"
 | 
			
		||||
        >
 | 
			
		||||
          <div></div>
 | 
			
		||||
          <div></div>
 | 
			
		||||
@ -140,9 +161,43 @@ function logoChange() {
 | 
			
		||||
        placement="bottom"
 | 
			
		||||
      >
 | 
			
		||||
        <li
 | 
			
		||||
          :class="dataTheme === 'light' ? $style.isSelect : ''"
 | 
			
		||||
          ref="secondTheme"
 | 
			
		||||
          @click="onLight"
 | 
			
		||||
          :class="dataTheme.layout === 'vertical-light' ? $style.isSelect : ''"
 | 
			
		||||
          ref="verticalLightDom"
 | 
			
		||||
          @click="setTheme('vertical', 'light', verticalLightDom)"
 | 
			
		||||
        >
 | 
			
		||||
          <div></div>
 | 
			
		||||
          <div></div>
 | 
			
		||||
        </li>
 | 
			
		||||
      </el-tooltip>
 | 
			
		||||
 | 
			
		||||
      <el-tooltip
 | 
			
		||||
        class="item"
 | 
			
		||||
        effect="dark"
 | 
			
		||||
        content="暗色主题"
 | 
			
		||||
        placement="bottom"
 | 
			
		||||
      >
 | 
			
		||||
        <li
 | 
			
		||||
          :class="dataTheme.layout === 'horizontal-dark' ? $style.isSelect : ''"
 | 
			
		||||
          ref="horizontalDarkDom"
 | 
			
		||||
          @click="setTheme('horizontal', 'dark', horizontalDarkDom)"
 | 
			
		||||
        >
 | 
			
		||||
          <div></div>
 | 
			
		||||
          <div></div>
 | 
			
		||||
        </li>
 | 
			
		||||
      </el-tooltip>
 | 
			
		||||
 | 
			
		||||
      <el-tooltip
 | 
			
		||||
        class="item"
 | 
			
		||||
        effect="dark"
 | 
			
		||||
        content="暗色主题"
 | 
			
		||||
        placement="bottom"
 | 
			
		||||
      >
 | 
			
		||||
        <li
 | 
			
		||||
          :class="
 | 
			
		||||
            dataTheme.layout === 'horizontal-light' ? $style.isSelect : ''
 | 
			
		||||
          "
 | 
			
		||||
          ref="horizontalLightDom"
 | 
			
		||||
          @click="setTheme('horizontal', 'light', horizontalLightDom)"
 | 
			
		||||
        >
 | 
			
		||||
          <div></div>
 | 
			
		||||
          <div></div>
 | 
			
		||||
@ -237,18 +292,19 @@ function logoChange() {
 | 
			
		||||
.theme-stley {
 | 
			
		||||
  margin-top: 25px;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 60px;
 | 
			
		||||
  height: 180px;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-wrap: wrap;
 | 
			
		||||
  justify-content: space-around;
 | 
			
		||||
 | 
			
		||||
  li {
 | 
			
		||||
    width: 30%;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    margin: 10px;
 | 
			
		||||
    width: 36%;
 | 
			
		||||
    height: 70px;
 | 
			
		||||
    background: #f0f2f5;
 | 
			
		||||
    position: relative;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    background-color: #f0f2f5;
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    box-shadow: 0 1px 2.5px 0 rgb(0 0 0 / 18%);
 | 
			
		||||
 | 
			
		||||
@ -265,7 +321,7 @@ function logoChange() {
 | 
			
		||||
          height: 30%;
 | 
			
		||||
          top: 0;
 | 
			
		||||
          right: 0;
 | 
			
		||||
          background-color: #fff;
 | 
			
		||||
          background: #fff;
 | 
			
		||||
          box-shadow: 0 0 1px #888;
 | 
			
		||||
          position: absolute;
 | 
			
		||||
        }
 | 
			
		||||
@ -278,7 +334,7 @@ function logoChange() {
 | 
			
		||||
          width: 30%;
 | 
			
		||||
          height: 100%;
 | 
			
		||||
          box-shadow: 0 0 1px #888;
 | 
			
		||||
          background-color: #fff;
 | 
			
		||||
          background: #fff;
 | 
			
		||||
          border-radius: 4px 0 0 4px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -287,12 +343,34 @@ function logoChange() {
 | 
			
		||||
          height: 30%;
 | 
			
		||||
          top: 0;
 | 
			
		||||
          right: 0;
 | 
			
		||||
          background-color: #fff;
 | 
			
		||||
          background: #fff;
 | 
			
		||||
          box-shadow: 0 0 1px #888;
 | 
			
		||||
          position: absolute;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &:nth-child(3) {
 | 
			
		||||
      div {
 | 
			
		||||
        &:nth-child(1) {
 | 
			
		||||
          width: 100%;
 | 
			
		||||
          height: 30%;
 | 
			
		||||
          background: #1b2a47;
 | 
			
		||||
          box-shadow: 0 0 1px #888;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &:nth-child(4) {
 | 
			
		||||
      div {
 | 
			
		||||
        &:nth-child(1) {
 | 
			
		||||
          width: 100%;
 | 
			
		||||
          height: 30%;
 | 
			
		||||
          background: #fff;
 | 
			
		||||
          box-shadow: 0 0 1px #888;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
@ -1,51 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <component :is="type" v-bind="linkProps(to)">
 | 
			
		||||
    <slot />
 | 
			
		||||
  </component>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { computed, defineComponent, unref } from "vue";
 | 
			
		||||
import { isUrl } from "/@/utils/is";
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
  name: "Link",
 | 
			
		||||
  props: {
 | 
			
		||||
    to: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      required: true
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  setup(props) {
 | 
			
		||||
    const isExternal = computed(() => {
 | 
			
		||||
      return isUrl(props.to);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const type = computed(() => {
 | 
			
		||||
      if (unref(isExternal)) {
 | 
			
		||||
        return "a";
 | 
			
		||||
      }
 | 
			
		||||
      return "router-link";
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    function linkProps(to) {
 | 
			
		||||
      if (unref(isExternal)) {
 | 
			
		||||
        return {
 | 
			
		||||
          href: to,
 | 
			
		||||
          target: "_blank",
 | 
			
		||||
          rel: "noopener"
 | 
			
		||||
        };
 | 
			
		||||
      }
 | 
			
		||||
      return {
 | 
			
		||||
        to: to
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      isExternal,
 | 
			
		||||
      type,
 | 
			
		||||
      linkProps
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
@ -1,116 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div v-if="!item.hidden">
 | 
			
		||||
    <template
 | 
			
		||||
      v-if="
 | 
			
		||||
        hasOneShowingChild(item.children, item) &&
 | 
			
		||||
        (!onlyOneChild.children || onlyOneChild.noShowingChildren) &&
 | 
			
		||||
        !item.alwaysShow
 | 
			
		||||
      "
 | 
			
		||||
    >
 | 
			
		||||
      <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
 | 
			
		||||
        <el-menu-item
 | 
			
		||||
          :index="resolvePath(onlyOneChild.path)"
 | 
			
		||||
          :class="{ 'submenu-title-noDropdown': !isNest }"
 | 
			
		||||
        >
 | 
			
		||||
          <i :class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)" />
 | 
			
		||||
          <template #title>
 | 
			
		||||
            <span>{{ $t(onlyOneChild.meta.title) }}</span>
 | 
			
		||||
          </template>
 | 
			
		||||
        </el-menu-item>
 | 
			
		||||
      </app-link>
 | 
			
		||||
    </template>
 | 
			
		||||
 | 
			
		||||
    <el-sub-menu
 | 
			
		||||
      v-else
 | 
			
		||||
      ref="subMenu"
 | 
			
		||||
      :index="resolvePath(item.path)"
 | 
			
		||||
      popper-append-to-body
 | 
			
		||||
    >
 | 
			
		||||
      <template #title>
 | 
			
		||||
        <i :class="item.meta.icon"></i>
 | 
			
		||||
        <span>{{ $t(item.meta.title) }}</span>
 | 
			
		||||
      </template>
 | 
			
		||||
      <sidebar-item
 | 
			
		||||
        v-for="child in item.children"
 | 
			
		||||
        :key="child.path"
 | 
			
		||||
        :is-nest="true"
 | 
			
		||||
        :item="child"
 | 
			
		||||
        :base-path="resolvePath(child.path)"
 | 
			
		||||
        class="nest-menu"
 | 
			
		||||
      />
 | 
			
		||||
    </el-sub-menu>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import path from "path";
 | 
			
		||||
import AppLink from "./Link.vue";
 | 
			
		||||
import { defineComponent, PropType, ref } from "vue";
 | 
			
		||||
import { RouteRecordRaw } from "vue-router";
 | 
			
		||||
import { isUrl } from "/@/utils/is.ts";
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
  name: "SidebarItem",
 | 
			
		||||
  components: { AppLink },
 | 
			
		||||
  props: {
 | 
			
		||||
    item: {
 | 
			
		||||
      type: Object as PropType<RouteRecordRaw>,
 | 
			
		||||
      required: true
 | 
			
		||||
    },
 | 
			
		||||
    isNest: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      default: false
 | 
			
		||||
    },
 | 
			
		||||
    basePath: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: ""
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  setup(props) {
 | 
			
		||||
    const onlyOneChild = ref<RouteRecordRaw>({} as any);
 | 
			
		||||
 | 
			
		||||
    function hasOneShowingChild(
 | 
			
		||||
      children: RouteRecordRaw[] = [],
 | 
			
		||||
      parent: RouteRecordRaw
 | 
			
		||||
    ) {
 | 
			
		||||
      const showingChildren = children.filter((item: any) => {
 | 
			
		||||
        if (item.hidden) {
 | 
			
		||||
          // 不显示hidden属性为true的菜单
 | 
			
		||||
          return false;
 | 
			
		||||
        } else {
 | 
			
		||||
          onlyOneChild.value = item;
 | 
			
		||||
          return true;
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      if (showingChildren.length === 1) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (showingChildren.length === 0) {
 | 
			
		||||
        // @ts-ignore
 | 
			
		||||
        onlyOneChild.value = { ...parent, path: "", noShowingChildren: true };
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // const resolvePath = (routePath: string) => {
 | 
			
		||||
    //   return path.resolve(props.basePath, routePath);
 | 
			
		||||
    // };
 | 
			
		||||
 | 
			
		||||
    function resolvePath(routePath) {
 | 
			
		||||
      if (isUrl(routePath)) {
 | 
			
		||||
        return routePath;
 | 
			
		||||
      }
 | 
			
		||||
      if (isUrl(this.basePath)) {
 | 
			
		||||
        return props.basePath;
 | 
			
		||||
      }
 | 
			
		||||
      // @ts-ignore
 | 
			
		||||
      return path.resolve(props.basePath, routePath);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return { hasOneShowingChild, resolvePath, onlyOneChild };
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										254
									
								
								src/layout/components/sidebar/horizontal.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								src/layout/components/sidebar/horizontal.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,254 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="horizontal-header">
 | 
			
		||||
    <div class="horizontal-header-left" @click="backHome">
 | 
			
		||||
      <i class="fa fa-optin-monster"></i>
 | 
			
		||||
      <h4>{{ settings.title }}</h4>
 | 
			
		||||
    </div>
 | 
			
		||||
    <el-menu
 | 
			
		||||
      :default-active="activeMenu"
 | 
			
		||||
      unique-opened
 | 
			
		||||
      router
 | 
			
		||||
      class="horizontal-header-menu"
 | 
			
		||||
      mode="horizontal"
 | 
			
		||||
      @select="menuSelect"
 | 
			
		||||
    >
 | 
			
		||||
      <sidebar-item
 | 
			
		||||
        v-for="route in routeStore.wholeRoutes"
 | 
			
		||||
        :key="route.path"
 | 
			
		||||
        :item="route"
 | 
			
		||||
        :base-path="route.path"
 | 
			
		||||
      />
 | 
			
		||||
    </el-menu>
 | 
			
		||||
    <div class="horizontal-header-right">
 | 
			
		||||
      <!-- 全屏 -->
 | 
			
		||||
      <screenfull v-show="!deviceDetection()" />
 | 
			
		||||
      <!-- 国际化 -->
 | 
			
		||||
      <el-dropdown trigger="click">
 | 
			
		||||
        <iconinternationality />
 | 
			
		||||
        <template #dropdown>
 | 
			
		||||
          <el-dropdown-menu class="translation">
 | 
			
		||||
            <el-dropdown-item
 | 
			
		||||
              :style="{
 | 
			
		||||
                background: locale === 'zh' ? '#1b2a47' : '',
 | 
			
		||||
                color: locale === 'zh' ? '#f4f4f5' : '#000'
 | 
			
		||||
              }"
 | 
			
		||||
              @click="translationCh"
 | 
			
		||||
              >简体中文</el-dropdown-item
 | 
			
		||||
            >
 | 
			
		||||
            <el-dropdown-item
 | 
			
		||||
              :style="{
 | 
			
		||||
                background: locale === 'en' ? '#1b2a47' : '',
 | 
			
		||||
                color: locale === 'en' ? '#f4f4f5' : '#000'
 | 
			
		||||
              }"
 | 
			
		||||
              @click="translationEn"
 | 
			
		||||
              >English</el-dropdown-item
 | 
			
		||||
            >
 | 
			
		||||
          </el-dropdown-menu>
 | 
			
		||||
        </template>
 | 
			
		||||
      </el-dropdown>
 | 
			
		||||
      <!-- 退出登陆 -->
 | 
			
		||||
      <el-dropdown trigger="click">
 | 
			
		||||
        <span class="el-dropdown-link">
 | 
			
		||||
          <img
 | 
			
		||||
            src="https://avatars.githubusercontent.com/u/44761321?s=400&u=30907819abd29bb3779bc247910873e7c7f7c12f&v=4"
 | 
			
		||||
          />
 | 
			
		||||
          <p>{{ usename }}</p>
 | 
			
		||||
        </span>
 | 
			
		||||
        <template #dropdown>
 | 
			
		||||
          <el-dropdown-menu class="logout">
 | 
			
		||||
            <el-dropdown-item icon="el-icon-switch-button" @click="logout">{{
 | 
			
		||||
              $t("message.hsLoginOut")
 | 
			
		||||
            }}</el-dropdown-item>
 | 
			
		||||
          </el-dropdown-menu>
 | 
			
		||||
        </template>
 | 
			
		||||
      </el-dropdown>
 | 
			
		||||
      <i
 | 
			
		||||
        class="el-icon-setting"
 | 
			
		||||
        :title="$t('message.hssystemSet')"
 | 
			
		||||
        @click="onPanel"
 | 
			
		||||
      ></i>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import {
 | 
			
		||||
  computed,
 | 
			
		||||
  defineComponent,
 | 
			
		||||
  unref,
 | 
			
		||||
  watch,
 | 
			
		||||
  getCurrentInstance
 | 
			
		||||
} from "vue";
 | 
			
		||||
import { useI18n } from "vue-i18n";
 | 
			
		||||
import settings from "/@/settings";
 | 
			
		||||
import { emitter } from "/@/utils/mitt";
 | 
			
		||||
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 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 translationCh() {
 | 
			
		||||
      instance.locale = { locale: "zh" };
 | 
			
		||||
      locale.value = "zh";
 | 
			
		||||
      window.location.reload();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // English
 | 
			
		||||
    function translationEn() {
 | 
			
		||||
      instance.locale = { locale: "en" };
 | 
			
		||||
      locale.value = "en";
 | 
			
		||||
      window.location.reload();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      locale,
 | 
			
		||||
      usename,
 | 
			
		||||
      settings,
 | 
			
		||||
      routeStore,
 | 
			
		||||
      activeMenu,
 | 
			
		||||
      logout,
 | 
			
		||||
      onPanel,
 | 
			
		||||
      backHome,
 | 
			
		||||
      menuSelect,
 | 
			
		||||
      translationCh,
 | 
			
		||||
      translationEn,
 | 
			
		||||
      deviceDetection
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.translation {
 | 
			
		||||
  .el-dropdown-menu__item {
 | 
			
		||||
    padding: 0 40px !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .el-dropdown-menu__item:focus,
 | 
			
		||||
  .el-dropdown-menu__item:not(.is-disabled):hover {
 | 
			
		||||
    color: #606266;
 | 
			
		||||
    background: #f0f0f0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.logout {
 | 
			
		||||
  .el-dropdown-menu__item {
 | 
			
		||||
    padding: 0 18px !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .el-dropdown-menu__item:focus,
 | 
			
		||||
  .el-dropdown-menu__item:not(.is-disabled):hover {
 | 
			
		||||
    color: #606266;
 | 
			
		||||
    background: #f0f0f0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@ -1,9 +1,17 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import settings from "/@/settings";
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
  collapse: Boolean
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="sidebar-logo-container" :class="{ collapse: collapse }">
 | 
			
		||||
  <div class="sidebar-logo-container" :class="{ collapse: props.collapse }">
 | 
			
		||||
    <transition name="sidebarLogoFade">
 | 
			
		||||
      <router-link
 | 
			
		||||
        v-if="collapse"
 | 
			
		||||
        key="collapse"
 | 
			
		||||
        v-if="props.collapse"
 | 
			
		||||
        key="props.collapse"
 | 
			
		||||
        :title="settings.title"
 | 
			
		||||
        class="sidebar-logo-link"
 | 
			
		||||
        to="/"
 | 
			
		||||
@ -25,25 +33,6 @@
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { defineComponent } from "vue";
 | 
			
		||||
import settings from "/@/settings";
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
  props: {
 | 
			
		||||
    collapse: {
 | 
			
		||||
      type: Boolean,
 | 
			
		||||
      required: true
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  setup() {
 | 
			
		||||
    return {
 | 
			
		||||
      settings
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
.sidebar-logo-container {
 | 
			
		||||
  position: relative;
 | 
			
		||||
							
								
								
									
										104
									
								
								src/layout/components/sidebar/sidebarItem.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								src/layout/components/sidebar/sidebarItem.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,104 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import path from "path";
 | 
			
		||||
import { PropType, ref } from "vue";
 | 
			
		||||
import { RouteRecordRaw } from "vue-router";
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
  item: {
 | 
			
		||||
    type: Object as PropType<RouteRecordRaw>
 | 
			
		||||
  },
 | 
			
		||||
  isNest: {
 | 
			
		||||
    type: Boolean,
 | 
			
		||||
    default: false
 | 
			
		||||
  },
 | 
			
		||||
  basePath: {
 | 
			
		||||
    type: String,
 | 
			
		||||
    default: ""
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
type childrenType = {
 | 
			
		||||
  path?: string;
 | 
			
		||||
  noShowingChildren?: boolean;
 | 
			
		||||
  children?: RouteRecordRaw[];
 | 
			
		||||
  meta?: {
 | 
			
		||||
    icon?: string;
 | 
			
		||||
    title?: string;
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const onlyOneChild = ref<RouteRecordRaw | childrenType>({} as any);
 | 
			
		||||
 | 
			
		||||
function hasOneShowingChild(
 | 
			
		||||
  children: RouteRecordRaw[] = [],
 | 
			
		||||
  parent: RouteRecordRaw
 | 
			
		||||
) {
 | 
			
		||||
  const showingChildren = children.filter((item: any) => {
 | 
			
		||||
    if (item.hidden) {
 | 
			
		||||
      // 不显示hidden属性为true的菜单
 | 
			
		||||
      return false;
 | 
			
		||||
    } else {
 | 
			
		||||
      onlyOneChild.value = item;
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  if (showingChildren.length === 1) {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (showingChildren.length === 0) {
 | 
			
		||||
    onlyOneChild.value = { ...parent, path: "", noShowingChildren: true };
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function resolvePath(routePath) {
 | 
			
		||||
  return path.resolve(props.basePath, routePath);
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <template
 | 
			
		||||
    v-if="
 | 
			
		||||
      hasOneShowingChild(props.item.children, props.item) &&
 | 
			
		||||
      (!onlyOneChild.children || onlyOneChild.noShowingChildren) &&
 | 
			
		||||
      !props.item.alwaysShow
 | 
			
		||||
    "
 | 
			
		||||
  >
 | 
			
		||||
    <el-menu-item
 | 
			
		||||
      :index="resolvePath(onlyOneChild.path)"
 | 
			
		||||
      :class="{ 'submenu-title-noDropdown': !isNest }"
 | 
			
		||||
    >
 | 
			
		||||
      <i
 | 
			
		||||
        :class="
 | 
			
		||||
          onlyOneChild.meta.icon || (props.item.meta && props.item.meta.icon)
 | 
			
		||||
        "
 | 
			
		||||
      />
 | 
			
		||||
      <template #title>
 | 
			
		||||
        <span>{{ $t(onlyOneChild.meta.title) }}</span>
 | 
			
		||||
      </template>
 | 
			
		||||
    </el-menu-item>
 | 
			
		||||
  </template>
 | 
			
		||||
 | 
			
		||||
  <el-sub-menu
 | 
			
		||||
    v-else
 | 
			
		||||
    ref="subMenu"
 | 
			
		||||
    :index="resolvePath(props.item.path)"
 | 
			
		||||
    popper-append-to-body
 | 
			
		||||
  >
 | 
			
		||||
    <template #title>
 | 
			
		||||
      <i :class="props.item.meta.icon"></i>
 | 
			
		||||
      <span>{{ $t(props.item.meta.title) }}</span>
 | 
			
		||||
    </template>
 | 
			
		||||
    <sidebar-item
 | 
			
		||||
      v-for="child in props.item.children"
 | 
			
		||||
      :key="child.path"
 | 
			
		||||
      :is-nest="true"
 | 
			
		||||
      :item="child"
 | 
			
		||||
      :base-path="resolvePath(child.path)"
 | 
			
		||||
      class="nest-menu"
 | 
			
		||||
    />
 | 
			
		||||
  </el-sub-menu>
 | 
			
		||||
</template>
 | 
			
		||||
@ -1,11 +1,12 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div :class="{ 'has-logo': showLogo }">
 | 
			
		||||
  <div :class="['sidebar-container', showLogo ? 'has-logo' : '']">
 | 
			
		||||
    <Logo v-if="showLogo === '1'" :collapse="isCollapse" />
 | 
			
		||||
    <el-scrollbar wrap-class="scrollbar-wrapper">
 | 
			
		||||
      <el-menu
 | 
			
		||||
        :default-active="activeMenu"
 | 
			
		||||
        :collapse="isCollapse"
 | 
			
		||||
        unique-opened
 | 
			
		||||
        router
 | 
			
		||||
        :collapse-transition="false"
 | 
			
		||||
        mode="vertical"
 | 
			
		||||
        @select="menuSelect"
 | 
			
		||||
@ -22,14 +23,14 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { computed, defineComponent, ref, onBeforeMount } from "vue";
 | 
			
		||||
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 SidebarItem from "./SidebarItem.vue";
 | 
			
		||||
import { algorithm } from "/@/utils/algorithm";
 | 
			
		||||
import { emitter } from "/@/utils/mitt";
 | 
			
		||||
import Logo from "./Logo.vue";
 | 
			
		||||
import { storageLocal } from "/@/utils/storage";
 | 
			
		||||
import { computed, defineComponent, ref, onBeforeMount } from "vue";
 | 
			
		||||
import { usePermissionStoreHook } from "/@/store/modules/permission";
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
@ -61,6 +62,7 @@ export default defineComponent({
 | 
			
		||||
        parentPath = indexPath.slice(0, parentPathIndex);
 | 
			
		||||
      }
 | 
			
		||||
      // 找到当前路由的信息
 | 
			
		||||
      // eslint-disable-next-line no-inner-declarations
 | 
			
		||||
      function findCurrentRoute(routes) {
 | 
			
		||||
        return routes.map(item => {
 | 
			
		||||
          if (item.path === indexPath) {
 | 
			
		||||
@ -1,3 +1,41 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
let routerArrays: Array<object> = [
 | 
			
		||||
  {
 | 
			
		||||
    path: "/welcome",
 | 
			
		||||
    parentPath: "/",
 | 
			
		||||
    meta: {
 | 
			
		||||
      title: "message.hshome",
 | 
			
		||||
      icon: "el-icon-s-home",
 | 
			
		||||
      showLink: true,
 | 
			
		||||
      savedPosition: false
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
];
 | 
			
		||||
export default {
 | 
			
		||||
  computed: {
 | 
			
		||||
    layout() {
 | 
			
		||||
      if (!this.$storage.layout) {
 | 
			
		||||
        // eslint-disable-next-line vue/no-side-effects-in-computed-properties
 | 
			
		||||
        this.$storage.layout = { layout: "vertical-dark" };
 | 
			
		||||
      }
 | 
			
		||||
      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";
 | 
			
		||||
      }
 | 
			
		||||
      return this.$storage?.layout.layout;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import {
 | 
			
		||||
  ref,
 | 
			
		||||
@ -10,13 +48,20 @@ import {
 | 
			
		||||
  useCssModule
 | 
			
		||||
} from "vue";
 | 
			
		||||
import options from "/@/settings";
 | 
			
		||||
import { useI18n } from "vue-i18n";
 | 
			
		||||
import { toggleClass } from "/@/utils/operate";
 | 
			
		||||
import { useEventListener } from "@vueuse/core";
 | 
			
		||||
import { useAppStoreHook } from "/@/store/modules/app";
 | 
			
		||||
import fullScreen from "/@/assets/svg/full_screen.svg";
 | 
			
		||||
import exitScreen from "/@/assets/svg/exit_screen.svg";
 | 
			
		||||
import { useSettingStoreHook } from "/@/store/modules/settings";
 | 
			
		||||
import { Navbar, Sidebar, AppMain, setting, tag } from "./components";
 | 
			
		||||
 | 
			
		||||
import navbar from "./components/navbar.vue";
 | 
			
		||||
import tag from "./components/tag/index.vue";
 | 
			
		||||
import appMain from "./components/appMain.vue";
 | 
			
		||||
import setting from "./components/setting/index.vue";
 | 
			
		||||
import Vertical from "./components/sidebar/vertical.vue";
 | 
			
		||||
import Horizontal from "./components/sidebar/horizontal.vue";
 | 
			
		||||
 | 
			
		||||
interface setInter {
 | 
			
		||||
  sidebar: any;
 | 
			
		||||
@ -118,19 +163,25 @@ onBeforeMount(() => {
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <div :class="set.classes" class="app-wrapper">
 | 
			
		||||
  <div :class="['app-wrapper', set.classes]">
 | 
			
		||||
    <div
 | 
			
		||||
      v-if="set.device === 'mobile' && set.sidebar.opened"
 | 
			
		||||
      v-show="
 | 
			
		||||
        set.device === 'mobile' &&
 | 
			
		||||
        set.sidebar.opened &&
 | 
			
		||||
        layout.includes('vertical')
 | 
			
		||||
      "
 | 
			
		||||
      class="drawer-bg"
 | 
			
		||||
      @click="handleClickOutside(false)"
 | 
			
		||||
    />
 | 
			
		||||
    <!-- 侧边栏 -->
 | 
			
		||||
    <sidebar class="sidebar-container" v-if="!containerHiddenSideBar" />
 | 
			
		||||
    <Vertical v-show="!containerHiddenSideBar && layout.includes('vertical')" />
 | 
			
		||||
    <div class="main-container">
 | 
			
		||||
      <div :class="{ 'fixed-header': set.fixedHeader }">
 | 
			
		||||
        <!-- 顶部导航栏 -->
 | 
			
		||||
        <navbar v-show="!containerHiddenSideBar" />
 | 
			
		||||
        <navbar
 | 
			
		||||
          v-show="!containerHiddenSideBar && layout.includes('vertical')"
 | 
			
		||||
        />
 | 
			
		||||
        <!-- tabs标签页 -->
 | 
			
		||||
        <Horizontal v-show="layout.includes('horizontal')" />
 | 
			
		||||
        <tag>
 | 
			
		||||
          <span @click="onFullScreen">
 | 
			
		||||
            <fullScreen v-if="!containerHiddenSideBar" />
 | 
			
		||||
@ -194,10 +245,6 @@ $sideBarWidth: 210px;
 | 
			
		||||
  transition: width 0.28s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.hideSidebar .fixed-header {
 | 
			
		||||
  width: calc(100% - 54px);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.mobile .fixed-header {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										43
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								src/main.ts
									
									
									
									
									
								
							@ -1,6 +1,7 @@
 | 
			
		||||
import App from "./App.vue";
 | 
			
		||||
import router from "./router";
 | 
			
		||||
import { setupStore } from "/@/store";
 | 
			
		||||
import { getServerConfig } from "./config";
 | 
			
		||||
import { createApp, Directive } from "vue";
 | 
			
		||||
import { usI18n } from "../src/plugins/i18n";
 | 
			
		||||
import { useTable } from "../src/plugins/vxe-table";
 | 
			
		||||
@ -14,13 +15,8 @@ import "./assets/iconfont/iconfont.js";
 | 
			
		||||
import "./assets/iconfont/iconfont.css";
 | 
			
		||||
import "v-contextmenu/dist/themes/default.css";
 | 
			
		||||
 | 
			
		||||
import { setConfig, getConfig } from "./config";
 | 
			
		||||
import axios from "axios";
 | 
			
		||||
 | 
			
		||||
const app = createApp(App);
 | 
			
		||||
 | 
			
		||||
app.config.globalProperties.$config = getConfig();
 | 
			
		||||
 | 
			
		||||
// 响应式storage
 | 
			
		||||
import Storage from "responsive-storage";
 | 
			
		||||
// @ts-ignore
 | 
			
		||||
@ -47,6 +43,13 @@ app.use(Storage, {
 | 
			
		||||
    default: Storage.getData(undefined, "locale") ?? {
 | 
			
		||||
      locale: "zh"
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  // layout模式以及主题
 | 
			
		||||
  layout: {
 | 
			
		||||
    type: Object,
 | 
			
		||||
    default: Storage.getData(undefined, "layout") ?? {
 | 
			
		||||
      layout: "vertical-dark"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@ -56,35 +59,7 @@ Object.keys(directives).forEach(key => {
 | 
			
		||||
  app.directive(key, (directives as { [key: string]: Directive })[key]);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// 获取项目动态全局配置
 | 
			
		||||
export const getServerConfig = async (): Promise<undefined> => {
 | 
			
		||||
  return axios({
 | 
			
		||||
    baseURL: "",
 | 
			
		||||
    method: "get",
 | 
			
		||||
    url:
 | 
			
		||||
      process.env.NODE_ENV === "production"
 | 
			
		||||
        ? "/manages/serverConfig.json"
 | 
			
		||||
        : "/serverConfig.json"
 | 
			
		||||
  })
 | 
			
		||||
    .then(({ data: config }) => {
 | 
			
		||||
      let $config = app.config.globalProperties.$config;
 | 
			
		||||
      // 自动注入项目配置
 | 
			
		||||
      if (app && $config && typeof config === "object") {
 | 
			
		||||
        $config = Object.assign($config, config);
 | 
			
		||||
        app.config.globalProperties.$config = $config;
 | 
			
		||||
        // 设置全局配置
 | 
			
		||||
        setConfig($config);
 | 
			
		||||
      }
 | 
			
		||||
      // 设置全局baseURL
 | 
			
		||||
      app.config.globalProperties.$baseUrl = $config.baseURL;
 | 
			
		||||
      return $config;
 | 
			
		||||
    })
 | 
			
		||||
    .catch(() => {
 | 
			
		||||
      throw "请在public文件夹下添加serverConfig.json配置文件";
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
getServerConfig().then(async () => {
 | 
			
		||||
getServerConfig(app).then(async () => {
 | 
			
		||||
  setupStore(app);
 | 
			
		||||
  app.use(router).use(useElementPlus).use(useTable).use(usI18n);
 | 
			
		||||
  await router.isReady();
 | 
			
		||||
 | 
			
		||||
@ -4,8 +4,10 @@ import {
 | 
			
		||||
  RouteComponent,
 | 
			
		||||
  createWebHashHistory
 | 
			
		||||
} from "vue-router";
 | 
			
		||||
import { split } from "lodash-es";
 | 
			
		||||
import { i18n } from "/@/plugins/i18n";
 | 
			
		||||
import NProgress from "/@/utils/progress";
 | 
			
		||||
import { openLink } from "/@/utils/link";
 | 
			
		||||
import { storageSession, storageLocal } from "/@/utils/storage";
 | 
			
		||||
import { usePermissionStoreHook } from "/@/store/modules/permission";
 | 
			
		||||
 | 
			
		||||
@ -128,13 +130,20 @@ const whiteList = ["/login", "/register"];
 | 
			
		||||
router.beforeEach((to, _from, next) => {
 | 
			
		||||
  const name = storageSession.getItem("info");
 | 
			
		||||
  NProgress.start();
 | 
			
		||||
  const externalLink = to?.redirectedFrom?.fullPath;
 | 
			
		||||
  // @ts-ignore
 | 
			
		||||
  const { t } = i18n.global;
 | 
			
		||||
  // @ts-ignore
 | 
			
		||||
  to.meta.title ? (document.title = t(to.meta.title)) : "";
 | 
			
		||||
  if (!externalLink) to.meta.title ? (document.title = t(to.meta.title)) : "";
 | 
			
		||||
  if (name) {
 | 
			
		||||
    if (_from?.name) {
 | 
			
		||||
      next();
 | 
			
		||||
      // 如果路由包含http 则是超链接 反之是普通路由
 | 
			
		||||
      if (externalLink && externalLink.includes("http")) {
 | 
			
		||||
        openLink(`http${split(externalLink, "http")[1]}`);
 | 
			
		||||
        NProgress.done();
 | 
			
		||||
      } else {
 | 
			
		||||
        next();
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      // 刷新
 | 
			
		||||
      if (usePermissionStoreHook().wholeRoutes.length === 0)
 | 
			
		||||
 | 
			
		||||
@ -36,9 +36,7 @@
 | 
			
		||||
 | 
			
		||||
// dropdown
 | 
			
		||||
.el-dropdown-menu {
 | 
			
		||||
  a {
 | 
			
		||||
    display: block;
 | 
			
		||||
  }
 | 
			
		||||
  padding: 2px 0 2px 0 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// to fix el-date-picker css style
 | 
			
		||||
@ -51,6 +49,6 @@
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// el-tooltip,的权重
 | 
			
		||||
.is-dark {
 | 
			
		||||
  z-index: 99999 !important;
 | 
			
		||||
}
 | 
			
		||||
// .is-dark {
 | 
			
		||||
//   z-index: 99999 !important;
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
@ -84,12 +84,6 @@ ul {
 | 
			
		||||
  display: none !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.resetTop {
 | 
			
		||||
  top: 48px !important;
 | 
			
		||||
  outline: 0;
 | 
			
		||||
  box-shadow: 0 2px 8px rgb(0 0 0 / 15%);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 灰色模式
 | 
			
		||||
.html-grey {
 | 
			
		||||
  filter: grayscale(100%);
 | 
			
		||||
@ -115,7 +109,3 @@ ul {
 | 
			
		||||
.mobile-spacing {
 | 
			
		||||
  margin: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.el-popper[data-popper-placement^="bottom"] > .el-popper__arrow {
 | 
			
		||||
  top: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -8,11 +8,13 @@
 | 
			
		||||
  // 子菜单背景
 | 
			
		||||
  $subMenuBg,
 | 
			
		||||
  // 鼠标覆盖子菜单时的背景
 | 
			
		||||
  $subMenuHover
 | 
			
		||||
  $subMenuHover,
 | 
			
		||||
  // vertical模式下主体内容距离网页文档左侧的距离
 | 
			
		||||
  $sideBarWidth,
 | 
			
		||||
  $navTextColor
 | 
			
		||||
) {
 | 
			
		||||
  $menuText: #7a80b4;
 | 
			
		||||
  $menuActiveText: #7a80b4;
 | 
			
		||||
  $sideBarWidth: 210px;
 | 
			
		||||
 | 
			
		||||
  .main-container {
 | 
			
		||||
    min-height: 100%;
 | 
			
		||||
@ -21,9 +23,13 @@
 | 
			
		||||
    position: relative;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .el-popper.is-light {
 | 
			
		||||
    border: none !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .sidebar-container {
 | 
			
		||||
    transition: width 0.28s;
 | 
			
		||||
    width: $sideBarWidth !important;
 | 
			
		||||
    width: $sideBarWidth;
 | 
			
		||||
    background-color: $menuBg;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    position: fixed;
 | 
			
		||||
@ -35,16 +41,15 @@
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
    box-shadow: 0 0 1px #888;
 | 
			
		||||
 | 
			
		||||
    // reset element-plus css
 | 
			
		||||
    .scrollbar-wrapper {
 | 
			
		||||
      overflow-x: hidden !important;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .horizontal-collapse-transition {
 | 
			
		||||
      transition: 0s width ease-in-out, 0s padding-left ease-in-out,
 | 
			
		||||
        0s padding-right ease-in-out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .scrollbar-wrapper {
 | 
			
		||||
      overflow-x: hidden !important;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .el-scrollbar__bar.is-vertical {
 | 
			
		||||
      right: 0;
 | 
			
		||||
    }
 | 
			
		||||
@ -72,9 +77,7 @@
 | 
			
		||||
    .el-menu {
 | 
			
		||||
      border: none;
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      background-color: transparent;
 | 
			
		||||
      // background-color: $menuBg !important;
 | 
			
		||||
      // width: 100% !important;
 | 
			
		||||
      background-color: transparent !important;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .el-menu-item,
 | 
			
		||||
@ -85,7 +88,7 @@
 | 
			
		||||
    // menu hover
 | 
			
		||||
    .submenu-title-noDropdown,
 | 
			
		||||
    .el-sub-menu__title {
 | 
			
		||||
      background: $menuBg;
 | 
			
		||||
      // background: $menuBg;
 | 
			
		||||
 | 
			
		||||
      &:hover {
 | 
			
		||||
        background-color: $menuHover !important;
 | 
			
		||||
@ -106,7 +109,7 @@
 | 
			
		||||
      color: $subMenuActiveText !important;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & .nest-menu .el-sub-menu > .el-sub-menu__title,
 | 
			
		||||
    .el-menu .el-menu--inline .el-sub-menu__title,
 | 
			
		||||
    & .el-sub-menu .el-menu-item {
 | 
			
		||||
      font-size: 12px;
 | 
			
		||||
      min-width: $sideBarWidth !important;
 | 
			
		||||
@ -118,13 +121,327 @@
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .horizontal-header {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    justify-content: space-around;
 | 
			
		||||
    background-color: $menuBg;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 62px;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
 | 
			
		||||
    .horizontal-header-left {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      width: auto;
 | 
			
		||||
      min-width: 200px;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      padding-left: 10px;
 | 
			
		||||
      cursor: pointer;
 | 
			
		||||
      transition: all 0.2s ease;
 | 
			
		||||
 | 
			
		||||
      &:hover {
 | 
			
		||||
        background: $menuHover;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      i {
 | 
			
		||||
        font-size: 30px;
 | 
			
		||||
        color: #1890ff;
 | 
			
		||||
        margin-right: 4px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      h4 {
 | 
			
		||||
        font-size: 16px;
 | 
			
		||||
        font-weight: 700;
 | 
			
		||||
        color: $navTextColor;
 | 
			
		||||
        transition: all 0.5s;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .horizontal-header-menu {
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      min-width: 0;
 | 
			
		||||
      flex: 1;
 | 
			
		||||
      // todo::
 | 
			
		||||
      overflow-x: auto;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .horizontal-header-right {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      min-width: 280px;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      color: $navTextColor;
 | 
			
		||||
      justify-content: flex-end;
 | 
			
		||||
 | 
			
		||||
      .screen-full {
 | 
			
		||||
        cursor: pointer;
 | 
			
		||||
 | 
			
		||||
        &:hover {
 | 
			
		||||
          background: $menuHover;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .iconinternationality {
 | 
			
		||||
        height: 62px;
 | 
			
		||||
        width: 40px;
 | 
			
		||||
        padding: 11px;
 | 
			
		||||
        cursor: pointer;
 | 
			
		||||
        color: $navTextColor;
 | 
			
		||||
 | 
			
		||||
        &:hover {
 | 
			
		||||
          background: $menuHover;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .el-dropdown-link {
 | 
			
		||||
        width: 100px;
 | 
			
		||||
        height: 62px;
 | 
			
		||||
        padding: 10px;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        justify-content: space-around;
 | 
			
		||||
        cursor: pointer;
 | 
			
		||||
        color: $navTextColor;
 | 
			
		||||
 | 
			
		||||
        &:hover {
 | 
			
		||||
          background: $menuHover;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        p {
 | 
			
		||||
          font-size: 14px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        img {
 | 
			
		||||
          width: 22px;
 | 
			
		||||
          height: 22px;
 | 
			
		||||
          border-radius: 50%;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .el-icon-setting {
 | 
			
		||||
        height: 62px;
 | 
			
		||||
        width: 40px;
 | 
			
		||||
        padding: 11px;
 | 
			
		||||
        display: flex;
 | 
			
		||||
        cursor: pointer;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
 | 
			
		||||
        &:hover {
 | 
			
		||||
          background: $menuHover;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .el-menu {
 | 
			
		||||
      border: none;
 | 
			
		||||
      height: 100%;
 | 
			
		||||
      background-color: transparent;
 | 
			
		||||
      width: 100% !important;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .el-menu-item,
 | 
			
		||||
    .el-sub-menu__title {
 | 
			
		||||
      color: $menuText;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .submenu-title-noDropdown,
 | 
			
		||||
    .el-sub-menu__title {
 | 
			
		||||
      height: 60px;
 | 
			
		||||
      background: $menuBg;
 | 
			
		||||
 | 
			
		||||
      &:hover {
 | 
			
		||||
        background-color: $menuHover !important;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .is-active > .el-sub-menu__title,
 | 
			
		||||
    .is-active.submenu-title-noDropdown {
 | 
			
		||||
      color: $subMenuActiveText !important;
 | 
			
		||||
      border-bottom-color: #409eff;
 | 
			
		||||
 | 
			
		||||
      i {
 | 
			
		||||
        color: $subMenuActiveText !important;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .is-active {
 | 
			
		||||
      transition: color 0.3s;
 | 
			
		||||
      color: $subMenuActiveText !important;
 | 
			
		||||
      border-bottom-color: #409eff;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // vertical菜单折叠
 | 
			
		||||
  .el-menu--vertical {
 | 
			
		||||
    .el-menu--popup {
 | 
			
		||||
      background-color: $subMenuBg !important;
 | 
			
		||||
 | 
			
		||||
      .el-menu-item {
 | 
			
		||||
        color: $menuText;
 | 
			
		||||
        background-color: $subMenuBg;
 | 
			
		||||
 | 
			
		||||
        &:hover {
 | 
			
		||||
          background-color: $subMenuHover;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .el-sub-menu__title {
 | 
			
		||||
        color: $menuText;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > .el-menu {
 | 
			
		||||
      i {
 | 
			
		||||
        margin-right: 16px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .is-active > .el-sub-menu__title,
 | 
			
		||||
    .is-active.submenu-title-noDropdown {
 | 
			
		||||
      color: $subMenuActiveText !important;
 | 
			
		||||
 | 
			
		||||
      i {
 | 
			
		||||
        color: $subMenuActiveText !important;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 子菜单中还有子菜单
 | 
			
		||||
    .el-menu .el-sub-menu__title {
 | 
			
		||||
      font-size: 12px;
 | 
			
		||||
      min-width: $sideBarWidth !important;
 | 
			
		||||
      background-color: $subMenuBg !important;
 | 
			
		||||
 | 
			
		||||
      &:hover {
 | 
			
		||||
        background-color: $menuHover !important;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .is-active {
 | 
			
		||||
      transition: color 0.3s;
 | 
			
		||||
      color: $subMenuActiveText !important;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .nest-menu .el-sub-menu > .el-sub-menu__title,
 | 
			
		||||
    .el-menu-item {
 | 
			
		||||
      &:hover {
 | 
			
		||||
        background-color: $menuHover !important;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // horizontal菜单折叠
 | 
			
		||||
  .el-menu--horizontal {
 | 
			
		||||
    .el-menu--popup {
 | 
			
		||||
      background-color: $subMenuBg !important;
 | 
			
		||||
 | 
			
		||||
      .el-menu-item {
 | 
			
		||||
        color: $menuText;
 | 
			
		||||
        background-color: $subMenuBg;
 | 
			
		||||
 | 
			
		||||
        &:hover {
 | 
			
		||||
          background-color: $subMenuHover;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .el-sub-menu__title {
 | 
			
		||||
        color: $menuText;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 无子菜单时激活border-bottom
 | 
			
		||||
    .router-link-exact-active > .submenu-title-noDropdown {
 | 
			
		||||
      height: 60px;
 | 
			
		||||
      border-bottom: 2px solid var(--el-menu-active-color);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 子菜单中还有子菜单
 | 
			
		||||
    .el-menu .el-sub-menu__title {
 | 
			
		||||
      font-size: 12px;
 | 
			
		||||
      min-width: $sideBarWidth !important;
 | 
			
		||||
      background-color: $subMenuBg !important;
 | 
			
		||||
 | 
			
		||||
      &:hover {
 | 
			
		||||
        background-color: $menuHover !important;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > .el-menu {
 | 
			
		||||
      i {
 | 
			
		||||
        margin-right: 16px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .is-active > .el-sub-menu__title,
 | 
			
		||||
    .is-active.submenu-title-noDropdown {
 | 
			
		||||
      color: $subMenuActiveText !important;
 | 
			
		||||
 | 
			
		||||
      i {
 | 
			
		||||
        color: $subMenuActiveText !important;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .is-active {
 | 
			
		||||
      transition: color 0.3s;
 | 
			
		||||
      color: $subMenuActiveText !important;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .nest-menu .el-sub-menu > .el-sub-menu__title,
 | 
			
		||||
    .el-menu-item {
 | 
			
		||||
      &:hover {
 | 
			
		||||
        background-color: $menuHover !important;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .el-scrollbar__wrap {
 | 
			
		||||
    overflow: auto;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .el-menu--collapse .el-menu .el-sub-menu {
 | 
			
		||||
    min-width: $sideBarWidth !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 手机端
 | 
			
		||||
  .mobile {
 | 
			
		||||
    .main-container {
 | 
			
		||||
      margin-left: 0 !important;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .sidebar-container {
 | 
			
		||||
      transition: transform 0.28s;
 | 
			
		||||
      width: $sideBarWidth !important;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &.hideSidebar {
 | 
			
		||||
      .sidebar-container {
 | 
			
		||||
        pointer-events: none;
 | 
			
		||||
        transition-duration: 0.3s;
 | 
			
		||||
        transform: translate3d(-$sideBarWidth, 0, 0);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .withoutAnimation {
 | 
			
		||||
    .main-container,
 | 
			
		||||
    .sidebar-container {
 | 
			
		||||
      transition: none;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
body[data-layout="vertical"] {
 | 
			
		||||
  .hideSidebar {
 | 
			
		||||
    .fixed-header {
 | 
			
		||||
      width: calc(100% - 54px);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .sidebar-container {
 | 
			
		||||
      width: 54px !important;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .main-container {
 | 
			
		||||
      margin-left: 54px;
 | 
			
		||||
      margin-left: 54px !important;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .submenu-title-noDropdown {
 | 
			
		||||
@ -161,122 +478,88 @@
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 菜单折叠
 | 
			
		||||
  .el-menu--vertical {
 | 
			
		||||
    .el-menu--popup {
 | 
			
		||||
      background-color: $subMenuBg !important;
 | 
			
		||||
 | 
			
		||||
      .el-menu-item {
 | 
			
		||||
        color: $menuText;
 | 
			
		||||
        background-color: $subMenuBg;
 | 
			
		||||
 | 
			
		||||
        &:hover {
 | 
			
		||||
          background-color: $subMenuHover;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .el-sub-menu__title {
 | 
			
		||||
        color: $menuText;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > .el-menu {
 | 
			
		||||
      i {
 | 
			
		||||
        margin-right: 16px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .is-active > .el-sub-menu__title,
 | 
			
		||||
    .is-active.submenu-title-noDropdown {
 | 
			
		||||
      color: $subMenuActiveText !important;
 | 
			
		||||
 | 
			
		||||
      i {
 | 
			
		||||
        color: $subMenuActiveText !important;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .is-active {
 | 
			
		||||
      transition: color 0.3s;
 | 
			
		||||
      color: $subMenuActiveText !important;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .nest-menu .el-sub-menu > .el-sub-menu__title,
 | 
			
		||||
    .el-menu-item {
 | 
			
		||||
      &:hover {
 | 
			
		||||
        // you can use $subMenuHover
 | 
			
		||||
        background-color: $menuHover !important;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .el-scrollbar__wrap {
 | 
			
		||||
    overflow: auto;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .el-menu--collapse .el-menu .el-sub-menu {
 | 
			
		||||
    min-width: $sideBarWidth !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 手机端
 | 
			
		||||
  .mobile {
 | 
			
		||||
    .main-container {
 | 
			
		||||
      margin-left: 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .sidebar-container {
 | 
			
		||||
      transition: transform 0.28s;
 | 
			
		||||
      width: $sideBarWidth !important;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &.hideSidebar {
 | 
			
		||||
      .sidebar-container {
 | 
			
		||||
        pointer-events: none;
 | 
			
		||||
        transition-duration: 0.3s;
 | 
			
		||||
        transform: translate3d(-$sideBarWidth, 0, 0);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .withoutAnimation {
 | 
			
		||||
    .main-container,
 | 
			
		||||
    .sidebar-container {
 | 
			
		||||
      transition: none;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 暗色主题
 | 
			
		||||
body[data-theme="dark"] {
 | 
			
		||||
// vertical模式下暗色主题
 | 
			
		||||
body[data-layout="vertical"][data-theme="dark"] {
 | 
			
		||||
  $subMenuActiveText: #f4f4f5;
 | 
			
		||||
  $menuBg: #1b2a47;
 | 
			
		||||
  $menuHover: #2a395b;
 | 
			
		||||
  $subMenuBg: #1f2d3d;
 | 
			
		||||
  $subMenuHover: #001528;
 | 
			
		||||
  $sideBarWidth: 210px;
 | 
			
		||||
  $navTextColor: #fff;
 | 
			
		||||
 | 
			
		||||
  @include merge-style(
 | 
			
		||||
    $subMenuActiveText,
 | 
			
		||||
    $menuBg,
 | 
			
		||||
    $menuHover,
 | 
			
		||||
    $subMenuBg,
 | 
			
		||||
    $subMenuHover
 | 
			
		||||
    $subMenuHover,
 | 
			
		||||
    $sideBarWidth,
 | 
			
		||||
    $navTextColor
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 亮色主题
 | 
			
		||||
body[data-theme="light"] {
 | 
			
		||||
// vertical模式下亮色主题
 | 
			
		||||
body[data-layout="vertical"][data-theme="light"] {
 | 
			
		||||
  $subMenuActiveText: #409eff;
 | 
			
		||||
  $menuBg: #fff;
 | 
			
		||||
  $menuHover: #e0ebf6;
 | 
			
		||||
  $subMenuBg: #fff;
 | 
			
		||||
  $subMenuHover: #e0ebf6;
 | 
			
		||||
  $sideBarWidth: 210px;
 | 
			
		||||
  $navTextColor: #7a80b4;
 | 
			
		||||
 | 
			
		||||
  @include merge-style(
 | 
			
		||||
    $subMenuActiveText,
 | 
			
		||||
    $menuBg,
 | 
			
		||||
    $menuHover,
 | 
			
		||||
    $subMenuBg,
 | 
			
		||||
    $subMenuHover
 | 
			
		||||
    $subMenuHover,
 | 
			
		||||
    $sideBarWidth,
 | 
			
		||||
    $navTextColor
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// horizontal模式下暗色主题
 | 
			
		||||
body[data-layout="horizontal"][data-theme="dark"] {
 | 
			
		||||
  $subMenuActiveText: #f4f4f5;
 | 
			
		||||
  $menuBg: #1b2a47;
 | 
			
		||||
  $menuHover: #2a395b;
 | 
			
		||||
  $subMenuBg: #1f2d3d;
 | 
			
		||||
  $subMenuHover: #001528;
 | 
			
		||||
  $sideBarWidth: 0;
 | 
			
		||||
  $navTextColor: #fff;
 | 
			
		||||
 | 
			
		||||
  @include merge-style(
 | 
			
		||||
    $subMenuActiveText,
 | 
			
		||||
    $menuBg,
 | 
			
		||||
    $menuHover,
 | 
			
		||||
    $subMenuBg,
 | 
			
		||||
    $subMenuHover,
 | 
			
		||||
    $sideBarWidth,
 | 
			
		||||
    $navTextColor
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// horizontal模式下亮色主题
 | 
			
		||||
body[data-layout="horizontal"][data-theme="light"] {
 | 
			
		||||
  $subMenuActiveText: #409eff;
 | 
			
		||||
  $menuBg: #fff;
 | 
			
		||||
  $menuHover: #e0ebf6;
 | 
			
		||||
  $subMenuBg: #fff;
 | 
			
		||||
  $subMenuHover: #e0ebf6;
 | 
			
		||||
  $sideBarWidth: 0;
 | 
			
		||||
  $navTextColor: #7a80b4;
 | 
			
		||||
 | 
			
		||||
  @include merge-style(
 | 
			
		||||
    $subMenuActiveText,
 | 
			
		||||
    $menuBg,
 | 
			
		||||
    $menuHover,
 | 
			
		||||
    $subMenuBg,
 | 
			
		||||
    $subMenuHover,
 | 
			
		||||
    $sideBarWidth,
 | 
			
		||||
    $navTextColor
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								src/utils/link.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/utils/link.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
export const openLink = (link: string) => {
 | 
			
		||||
  const $a: HTMLElement = document.createElement("a");
 | 
			
		||||
  $a.setAttribute("href", link);
 | 
			
		||||
  $a.setAttribute("target", "_blank");
 | 
			
		||||
  $a.setAttribute("rel", "noreferrer noopener");
 | 
			
		||||
  $a.setAttribute("id", "external");
 | 
			
		||||
  document.getElementById("external") &&
 | 
			
		||||
    document.body.removeChild(document.getElementById("external"));
 | 
			
		||||
  document.body.appendChild($a);
 | 
			
		||||
  $a.click();
 | 
			
		||||
  $a.remove();
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										191
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										191
									
								
								yarn.lock
									
									
									
									
									
								
							@ -420,11 +420,6 @@
 | 
			
		||||
  dependencies:
 | 
			
		||||
    chalk "^4.0.0"
 | 
			
		||||
 | 
			
		||||
"@element-plus/icons@^0.0.11":
 | 
			
		||||
  version "0.0.11"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@element-plus/icons/-/icons-0.0.11.tgz#9b187c002774548b911850d17fa5fc2f9a515f57"
 | 
			
		||||
  integrity sha512-iKQXSxXu131Ai+I9Ymtcof9WId7kaXvB1+WRfAfpQCW7UiAMYgdNDqb/u0hgTo2Yq3MwC4MWJnNuTBEpG8r7+A==
 | 
			
		||||
 | 
			
		||||
"@eslint/eslintrc@^0.4.3":
 | 
			
		||||
  version "0.4.3"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
 | 
			
		||||
@ -786,6 +781,16 @@
 | 
			
		||||
    estree-walker "^2.0.2"
 | 
			
		||||
    source-map "^0.6.1"
 | 
			
		||||
 | 
			
		||||
"@vue/compiler-core@3.2.19":
 | 
			
		||||
  version "3.2.19"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.19.tgz#b537dd377ce51fdb64e9b30ebfbff7cd70a64cb9"
 | 
			
		||||
  integrity sha512-8dOPX0YOtaXol0Zf2cfLQ4NU/yHYl2H7DCKsLEZ7gdvPK6ZSEwGLJ7IdghhY2YEshEpC5RB9QKdC5I07z8Dtjg==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/parser" "^7.15.0"
 | 
			
		||||
    "@vue/shared" "3.2.19"
 | 
			
		||||
    estree-walker "^2.0.2"
 | 
			
		||||
    source-map "^0.6.1"
 | 
			
		||||
 | 
			
		||||
"@vue/compiler-dom@3.2.11":
 | 
			
		||||
  version "3.2.11"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.11.tgz#d066f8e1f1812b4e881593819ade0fe6d654c776"
 | 
			
		||||
@ -794,7 +799,31 @@
 | 
			
		||||
    "@vue/compiler-core" "3.2.11"
 | 
			
		||||
    "@vue/shared" "3.2.11"
 | 
			
		||||
 | 
			
		||||
"@vue/compiler-sfc@3.2.11", "@vue/compiler-sfc@^3.0.11":
 | 
			
		||||
"@vue/compiler-dom@3.2.19":
 | 
			
		||||
  version "3.2.19"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.19.tgz#0607bc90de6af55fde73b09b3c4d0bf8cb597ed8"
 | 
			
		||||
  integrity sha512-WzQoE8rfkFjPtIioc7SSgTsnz9g2oG61DU8KHnzPrRS7fW/lji6H2uCYJfp4Z6kZE8GjnHc1Ljwl3/gxDes0cw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@vue/compiler-core" "3.2.19"
 | 
			
		||||
    "@vue/shared" "3.2.19"
 | 
			
		||||
 | 
			
		||||
"@vue/compiler-sfc@3.2.19", "@vue/compiler-sfc@^3.2.19":
 | 
			
		||||
  version "3.2.19"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.19.tgz#d412195a98ebd49b84602f171719294a1d9549be"
 | 
			
		||||
  integrity sha512-pLlbgkO1UHTO02MSpa/sFOXUwIDxSMiKZ1ozE5n71CY4DM+YmI+G3gT/ZHZ46WBId7f3VTF/D8pGwMygcQbrQA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@babel/parser" "^7.15.0"
 | 
			
		||||
    "@vue/compiler-core" "3.2.19"
 | 
			
		||||
    "@vue/compiler-dom" "3.2.19"
 | 
			
		||||
    "@vue/compiler-ssr" "3.2.19"
 | 
			
		||||
    "@vue/ref-transform" "3.2.19"
 | 
			
		||||
    "@vue/shared" "3.2.19"
 | 
			
		||||
    estree-walker "^2.0.2"
 | 
			
		||||
    magic-string "^0.25.7"
 | 
			
		||||
    postcss "^8.1.10"
 | 
			
		||||
    source-map "^0.6.1"
 | 
			
		||||
 | 
			
		||||
"@vue/compiler-sfc@^3.0.11":
 | 
			
		||||
  version "3.2.11"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.11.tgz#628fa12238760d9b9b339ac2e125a759224fadbf"
 | 
			
		||||
  integrity sha512-cUIaS8mgJrQ6yucj2AupWAwBRITK3W/a8wCOn9g5fJGtOl8h4APY8vN3lzP8HIJDyEeRF3I8SfRhL+oX97kSnw==
 | 
			
		||||
@ -826,6 +855,14 @@
 | 
			
		||||
    "@vue/compiler-dom" "3.2.11"
 | 
			
		||||
    "@vue/shared" "3.2.11"
 | 
			
		||||
 | 
			
		||||
"@vue/compiler-ssr@3.2.19":
 | 
			
		||||
  version "3.2.19"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.19.tgz#3e91ecf70f8f961c5f63eacd2139bcdab9a7a07c"
 | 
			
		||||
  integrity sha512-oLon0Cn3O7WEYzzmzZavGoqXH+199LT+smdjBT3Uf3UX4HwDNuBFCmvL0TsqV9SQnIgKvBRbQ7lhbpnd4lqM3w==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@vue/compiler-dom" "3.2.19"
 | 
			
		||||
    "@vue/shared" "3.2.19"
 | 
			
		||||
 | 
			
		||||
"@vue/devtools-api@^6.0.0-beta.13", "@vue/devtools-api@^6.0.0-beta.14", "@vue/devtools-api@^6.0.0-beta.15":
 | 
			
		||||
  version "6.0.0-beta.15"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.0.0-beta.15.tgz#ad7cb384e062f165bcf9c83732125bffbc2ad83d"
 | 
			
		||||
@ -845,12 +882,12 @@
 | 
			
		||||
  dependencies:
 | 
			
		||||
    vue-eslint-parser "^7.0.0"
 | 
			
		||||
 | 
			
		||||
"@vue/reactivity@3.2.11":
 | 
			
		||||
  version "3.2.11"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.11.tgz#ec04d33acaf2b92cca2960535bec81b26cc5772b"
 | 
			
		||||
  integrity sha512-hEQstxPQbgGZq5qApzrvbDmRdK1KP96O/j4XrwT8fVkT1ytkFs4fH2xNEh9QKwXfybbQkLs77W7OfXCv5o6qbA==
 | 
			
		||||
"@vue/reactivity@3.2.19":
 | 
			
		||||
  version "3.2.19"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.19.tgz#fc6e0f0106f295226835cfed5ff5f84d927bea65"
 | 
			
		||||
  integrity sha512-FtachoYs2SnyrWup5UikP54xDX6ZJ1s5VgHcJp4rkGoutU3Ry61jhs+nCX7J64zjX992Mh9gGUC0LqTs8q9vCA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@vue/shared" "3.2.11"
 | 
			
		||||
    "@vue/shared" "3.2.19"
 | 
			
		||||
 | 
			
		||||
"@vue/ref-transform@3.2.11":
 | 
			
		||||
  version "3.2.11"
 | 
			
		||||
@ -863,28 +900,52 @@
 | 
			
		||||
    estree-walker "^2.0.2"
 | 
			
		||||
    magic-string "^0.25.7"
 | 
			
		||||
 | 
			
		||||
"@vue/runtime-core@3.2.11":
 | 
			
		||||
  version "3.2.11"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.11.tgz#0dbe801be4bd0bfde253226797e7d304c8fdda30"
 | 
			
		||||
  integrity sha512-horlxjWwSvModC87WdsWswzzHE5IexmKkQA65S5vFgP5hLUBW+HRyScDeuB/RRcFmqnf+ozacNCfap0kqcpODw==
 | 
			
		||||
"@vue/ref-transform@3.2.19":
 | 
			
		||||
  version "3.2.19"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/ref-transform/-/ref-transform-3.2.19.tgz#cf0f986486bb26838fbd09749e927bab19745600"
 | 
			
		||||
  integrity sha512-03wwUnoIAeKti5IGGx6Vk/HEBJ+zUcm5wrUM3+PQsGf7IYnXTbeIfHHpx4HeSeWhnLAjqZjADQwW8uA4rBmVbg==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@vue/reactivity" "3.2.11"
 | 
			
		||||
    "@vue/shared" "3.2.11"
 | 
			
		||||
    "@babel/parser" "^7.15.0"
 | 
			
		||||
    "@vue/compiler-core" "3.2.19"
 | 
			
		||||
    "@vue/shared" "3.2.19"
 | 
			
		||||
    estree-walker "^2.0.2"
 | 
			
		||||
    magic-string "^0.25.7"
 | 
			
		||||
 | 
			
		||||
"@vue/runtime-dom@3.2.11":
 | 
			
		||||
  version "3.2.11"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.11.tgz#04f9054a9e64bdf156c2fc22cad67cfaa8b84616"
 | 
			
		||||
  integrity sha512-cOK1g0INdiCbds2xrrJKrrN+pDHuLz6esUs/crdEiupDuX7IeiMbdqrAQCkYHp5P1KLWcbGlkmwfVD7HQGii0Q==
 | 
			
		||||
"@vue/runtime-core@3.2.19":
 | 
			
		||||
  version "3.2.19"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.19.tgz#807715b7f4728abb84fa4a8efdbe37d8ddb4c6d3"
 | 
			
		||||
  integrity sha512-qArZSWKxWsgKfxk9BelZ32nY0MZ31CAW2kUUyVJyxh4cTfHaXGbjiQB5JgsvKc49ROMNffv9t3/qjasQqAH+RQ==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@vue/runtime-core" "3.2.11"
 | 
			
		||||
    "@vue/shared" "3.2.11"
 | 
			
		||||
    "@vue/reactivity" "3.2.19"
 | 
			
		||||
    "@vue/shared" "3.2.19"
 | 
			
		||||
 | 
			
		||||
"@vue/runtime-dom@3.2.19":
 | 
			
		||||
  version "3.2.19"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.19.tgz#7e8bf645754703e360fa132e4be9113edf2377bb"
 | 
			
		||||
  integrity sha512-hIRboxXwafeHhbZEkZYNV0MiJXPNf4fP0X6hM2TJb0vssz8BKhD9cF92BkRgZztTQevecbhk0gu4uAPJ3dxL9A==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@vue/runtime-core" "3.2.19"
 | 
			
		||||
    "@vue/shared" "3.2.19"
 | 
			
		||||
    csstype "^2.6.8"
 | 
			
		||||
 | 
			
		||||
"@vue/server-renderer@3.2.19":
 | 
			
		||||
  version "3.2.19"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.19.tgz#870bcec9f7cdaee0c2187a169b6e636ab4362fb1"
 | 
			
		||||
  integrity sha512-A9FNT7fgQJXItwdzWREntAgWKVtKYuXHBKGev/H4+ByTu8vB7gQXGcim01QxaJshdNg4dYuH2tEBZXCNCNx+/w==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@vue/compiler-ssr" "3.2.19"
 | 
			
		||||
    "@vue/shared" "3.2.19"
 | 
			
		||||
 | 
			
		||||
"@vue/shared@3.2.11":
 | 
			
		||||
  version "3.2.11"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.2.11.tgz#01899f54949caf1ac241de397bd17069632574de"
 | 
			
		||||
  integrity sha512-ovfXAsSsCvV9JVceWjkqC/7OF5HbgLOtCWjCIosmPGG8lxbPuavhIxRH1dTx4Dg9xLgRTNLvI3pVxG4ItQZekg==
 | 
			
		||||
 | 
			
		||||
"@vue/shared@3.2.19":
 | 
			
		||||
  version "3.2.19"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.2.19.tgz#111ec3da18337d86274446984c49925b1b2b2dd7"
 | 
			
		||||
  integrity sha512-Knqhx7WieLdVgwCAZgTVrDCXZ50uItuecLh9JdLC8O+a5ayaSyIQYveUK3hCRNC7ws5zalHmZwfdLMGaS8r4Ew==
 | 
			
		||||
 | 
			
		||||
"@vueuse/core@^6.4.1":
 | 
			
		||||
  version "6.4.1"
 | 
			
		||||
  resolved "https://registry.npmjs.org/@vueuse/core/-/core-6.4.1.tgz#21416997a23bfb4924a5082ed6fa959027f80d04"
 | 
			
		||||
@ -1532,7 +1593,7 @@ dargs@^7.0.0:
 | 
			
		||||
  resolved "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc"
 | 
			
		||||
  integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==
 | 
			
		||||
 | 
			
		||||
dayjs@1.x, dayjs@^1.10.6:
 | 
			
		||||
dayjs@^1.10.6, dayjs@^1.10.7:
 | 
			
		||||
  version "1.10.7"
 | 
			
		||||
  resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz#2cf5f91add28116748440866a0a1d26f3a6ce468"
 | 
			
		||||
  integrity sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==
 | 
			
		||||
@ -1707,18 +1768,17 @@ electron-to-chromium@^1.3.830:
 | 
			
		||||
  resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.840.tgz#3f2a1df97015d9b1db5d86a4c6bd4cdb920adcbb"
 | 
			
		||||
  integrity sha512-yRoUmTLDJnkIJx23xLY7GbSvnmDCq++NSuxHDQ0jiyDJ9YZBUGJcrdUqm+ZwZFzMbCciVzfem2N2AWiHJcWlbw==
 | 
			
		||||
 | 
			
		||||
element-plus@^1.1.0-beta.12:
 | 
			
		||||
  version "1.1.0-beta.12"
 | 
			
		||||
  resolved "https://registry.npmjs.org/element-plus/-/element-plus-1.1.0-beta.12.tgz#2fd646f3c2f787dfb282d091ec6aa6945d1bec6a"
 | 
			
		||||
  integrity sha512-IkFHcYWGDzHqeL2LpDM5ZQnuviqkNj8Bu9zg/Q6KImGk8xo4rqMf+e4rBHinIpeKzKdVag0c2TDABNBfKvjaPA==
 | 
			
		||||
element-plus@^1.1.0-beta.16:
 | 
			
		||||
  version "1.1.0-beta.16"
 | 
			
		||||
  resolved "https://registry.npmjs.org/element-plus/-/element-plus-1.1.0-beta.16.tgz#4409d9e33d005693f6039f5ed1fe05e301b3170d"
 | 
			
		||||
  integrity sha512-4BZEldnIfFZs5A/saRqaWE4PwTot4p3YZU7qsDr3ev2zp35pcCL9TtpWMLIvNTMxvxKew0HTDPTk9fAWIZFQrQ==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@element-plus/icons" "^0.0.11"
 | 
			
		||||
    "@popperjs/core" "^2.10.1"
 | 
			
		||||
    "@vueuse/core" "~6.1.0"
 | 
			
		||||
    async-validator "^3.4.0"
 | 
			
		||||
    dayjs "1.x"
 | 
			
		||||
    dayjs "^1.10.7"
 | 
			
		||||
    lodash "^4.17.21"
 | 
			
		||||
    mitt "^2.1.0"
 | 
			
		||||
    memoize-one "^5.2.1"
 | 
			
		||||
    normalize-wheel "^1.0.1"
 | 
			
		||||
    resize-observer-polyfill "^1.5.1"
 | 
			
		||||
 | 
			
		||||
@ -1817,9 +1877,9 @@ esbuild@0.11.3:
 | 
			
		||||
  integrity sha512-BzVRHcCtFepjS9WcqRjqoIxLqgpK21a8J4Zi4msSGxDxiXVO1IbcqT1KjhdDDnJxKfe7bvzZrvMEX+bVO0Elcw==
 | 
			
		||||
 | 
			
		||||
esbuild@^0.12.17:
 | 
			
		||||
  version "0.12.28"
 | 
			
		||||
  resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.12.28.tgz#84da0d2a0d0dee181281545271e0d65cf6fab1ef"
 | 
			
		||||
  integrity sha512-pZ0FrWZXlvQOATlp14lRSk1N9GkeJ3vLIwOcUoo3ICQn9WNR4rWoNi81pbn6sC1iYUy7QPqNzI3+AEzokwyVcA==
 | 
			
		||||
  version "0.12.29"
 | 
			
		||||
  resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.12.29.tgz#be602db7c4dc78944a9dbde0d1ea19d36c1f882d"
 | 
			
		||||
  integrity sha512-w/XuoBCSwepyiZtIRsKsetiLDUVGPVw1E/R3VTFSecIy8UR7Cq3SOtwKHJMFoVqqVG36aGkzh4e8BvpO1Fdc7g==
 | 
			
		||||
 | 
			
		||||
escalade@^3.1.1:
 | 
			
		||||
  version "3.1.1"
 | 
			
		||||
@ -2939,6 +2999,11 @@ mdn-data@2.0.14:
 | 
			
		||||
  resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
 | 
			
		||||
  integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
 | 
			
		||||
 | 
			
		||||
memoize-one@^5.2.1:
 | 
			
		||||
  version "5.2.1"
 | 
			
		||||
  resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
 | 
			
		||||
  integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
 | 
			
		||||
 | 
			
		||||
meow@^8.0.0:
 | 
			
		||||
  version "8.1.2"
 | 
			
		||||
  resolved "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897"
 | 
			
		||||
@ -3081,7 +3146,12 @@ multimatch@^4.0.0:
 | 
			
		||||
    arrify "^2.0.1"
 | 
			
		||||
    minimatch "^3.0.4"
 | 
			
		||||
 | 
			
		||||
nanoid@^3.1.23:
 | 
			
		||||
nanocolors@^0.1.5:
 | 
			
		||||
  version "0.1.12"
 | 
			
		||||
  resolved "https://registry.npmjs.org/nanocolors/-/nanocolors-0.1.12.tgz#8577482c58cbd7b5bb1681db4cf48f11a87fd5f6"
 | 
			
		||||
  integrity sha512-2nMHqg1x5PU+unxX7PGY7AuYxl2qDx7PSrTRjizr8sxdd3l/3hBuWWaki62qmtYm2U5i4Z5E7GbjlyDFhs9/EQ==
 | 
			
		||||
 | 
			
		||||
nanoid@^3.1.23, nanoid@^3.1.25:
 | 
			
		||||
  version "3.1.25"
 | 
			
		||||
  resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152"
 | 
			
		||||
  integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==
 | 
			
		||||
@ -3504,7 +3574,7 @@ postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.
 | 
			
		||||
    source-map "^0.6.1"
 | 
			
		||||
    supports-color "^6.1.0"
 | 
			
		||||
 | 
			
		||||
postcss@^8.1.10, postcss@^8.2.6, postcss@^8.3.6:
 | 
			
		||||
postcss@^8.1.10, postcss@^8.2.6:
 | 
			
		||||
  version "8.3.6"
 | 
			
		||||
  resolved "https://registry.npmjs.org/postcss/-/postcss-8.3.6.tgz#2730dd76a97969f37f53b9a6096197be311cc4ea"
 | 
			
		||||
  integrity sha512-wG1cc/JhRgdqB6WHEuyLTedf3KIRuD0hG6ldkFEZNCjRxiC+3i6kkWUUbiJQayP28iwG35cEmAbe98585BYV0A==
 | 
			
		||||
@ -3513,6 +3583,15 @@ postcss@^8.1.10, postcss@^8.2.6, postcss@^8.3.6:
 | 
			
		||||
    nanoid "^3.1.23"
 | 
			
		||||
    source-map-js "^0.6.2"
 | 
			
		||||
 | 
			
		||||
postcss@^8.3.6:
 | 
			
		||||
  version "8.3.7"
 | 
			
		||||
  resolved "https://registry.npmjs.org/postcss/-/postcss-8.3.7.tgz#ec88563588c8da8e58e7226f7633b51ae221eeda"
 | 
			
		||||
  integrity sha512-9SaY7nnyQ63/WittqZYAvkkYPyKxchMKH71UDzeTmWuLSvxTRpeEeABZAzlCi55cuGcoFyoV/amX2BdsafQidQ==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    nanocolors "^0.1.5"
 | 
			
		||||
    nanoid "^3.1.25"
 | 
			
		||||
    source-map-js "^0.6.2"
 | 
			
		||||
 | 
			
		||||
preact@^10.4.8:
 | 
			
		||||
  version "10.5.14"
 | 
			
		||||
  resolved "https://registry.npmjs.org/preact/-/preact-10.5.14.tgz#0b14a2eefba3c10a57116b90d1a65f5f00cd2701"
 | 
			
		||||
@ -3713,12 +3792,12 @@ resolve@^1.1.7, resolve@^1.10.0, resolve@^1.19.0, resolve@^1.20.0:
 | 
			
		||||
    is-core-module "^2.2.0"
 | 
			
		||||
    path-parse "^1.0.6"
 | 
			
		||||
 | 
			
		||||
responsive-storage@^1.0.9:
 | 
			
		||||
  version "1.0.9"
 | 
			
		||||
  resolved "https://registry.npmjs.org/responsive-storage/-/responsive-storage-1.0.9.tgz#389544da44fbd34adb8bd210dd6b4d6d4795642f"
 | 
			
		||||
  integrity sha512-GODZF3a50hvnBvAntqDgiEub4+xXRcdACH1wnsM8KVmSnSd0IKqCcrE0fwk5b6y3lPW2h+ZpB3bBMcQpkuTeJg==
 | 
			
		||||
responsive-storage@^1.0.10:
 | 
			
		||||
  version "1.0.10"
 | 
			
		||||
  resolved "https://registry.npmjs.org/responsive-storage/-/responsive-storage-1.0.10.tgz#a872d7a1ea4f78f3e77d60ae62910483114cd445"
 | 
			
		||||
  integrity sha512-M4j7C7/2xAxEfXuwoyt4Xh9N14o0pItsBnMK/BrNOi0mGpxcpDERNrSCPFvVM0avmpi4tliYduqU96ffOT16Ww==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    vue "^3.1.1"
 | 
			
		||||
    vue "^3.2.19"
 | 
			
		||||
 | 
			
		||||
restore-cursor@^3.1.0:
 | 
			
		||||
  version "3.1.0"
 | 
			
		||||
@ -3741,9 +3820,9 @@ rimraf@^3.0.2:
 | 
			
		||||
    glob "^7.1.3"
 | 
			
		||||
 | 
			
		||||
rollup@^2.38.5:
 | 
			
		||||
  version "2.56.3"
 | 
			
		||||
  resolved "https://registry.npmjs.org/rollup/-/rollup-2.56.3.tgz#b63edadd9851b0d618a6d0e6af8201955a77aeff"
 | 
			
		||||
  integrity sha512-Au92NuznFklgQCUcV96iXlxUbHuB1vQMaH76DHl5M11TotjOHwqk9CwcrT78+Tnv4FN9uTBxq6p4EJoYkpyekg==
 | 
			
		||||
  version "2.57.0"
 | 
			
		||||
  resolved "https://registry.npmjs.org/rollup/-/rollup-2.57.0.tgz#c1694475eb22e1022477c0f4635fd0ac80713173"
 | 
			
		||||
  integrity sha512-bKQIh1rWKofRee6mv8SrF2HdP6pea5QkwBZSMImJysFj39gQuiV8MEPBjXOCpzk3wSYp63M2v2wkWBmFC8O/rg==
 | 
			
		||||
  optionalDependencies:
 | 
			
		||||
    fsevents "~2.3.2"
 | 
			
		||||
 | 
			
		||||
@ -4446,10 +4525,10 @@ vite-svg-loader@^2.2.0:
 | 
			
		||||
    "@vue/compiler-sfc" "^3.0.11"
 | 
			
		||||
    svgo "^2.3.0"
 | 
			
		||||
 | 
			
		||||
vite@^2.5.7:
 | 
			
		||||
  version "2.5.7"
 | 
			
		||||
  resolved "https://registry.npmjs.org/vite/-/vite-2.5.7.tgz#e495be9d8bcbf9d30c7141efdccacde746ee0125"
 | 
			
		||||
  integrity sha512-hyUoWmRPhjN1aI+ZSBqDINKdIq7aokHE2ZXiztOg4YlmtpeQtMwMeyxv6X9YxHZmvGzg/js/eATM9Z1nwyakxg==
 | 
			
		||||
vite@^2.5.10:
 | 
			
		||||
  version "2.5.10"
 | 
			
		||||
  resolved "https://registry.npmjs.org/vite/-/vite-2.5.10.tgz#c598e3b5a7e1956ffc52eb3b3420d177fc2ed2a5"
 | 
			
		||||
  integrity sha512-0ObiHTi5AHyXdJcvZ67HMsDgVpjT5RehvVKv6+Q0jFZ7zDI28PF5zK9mYz2avxdA+4iJMdwCz6wnGNnn4WX5Gg==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    esbuild "^0.12.17"
 | 
			
		||||
    postcss "^8.3.6"
 | 
			
		||||
@ -4505,14 +4584,16 @@ vue-types@^4.1.0:
 | 
			
		||||
  dependencies:
 | 
			
		||||
    is-plain-object "5.0.0"
 | 
			
		||||
 | 
			
		||||
vue@3.2.11, vue@^3.1.1:
 | 
			
		||||
  version "3.2.11"
 | 
			
		||||
  resolved "https://registry.npmjs.org/vue/-/vue-3.2.11.tgz#6b92295048df705ddac558fd3e3ed553e55e57c8"
 | 
			
		||||
  integrity sha512-JkI3/eIgfk4E0f/p319TD3EZgOwBQfftgnkRsXlT7OrRyyiyoyUXn6embPGZXSBxD3LoZ9SWhJoxLhFh5AleeA==
 | 
			
		||||
vue@^3.2.19:
 | 
			
		||||
  version "3.2.19"
 | 
			
		||||
  resolved "https://registry.npmjs.org/vue/-/vue-3.2.19.tgz#da2c80a6a0271c7097fee9e31692adfd9d569c8f"
 | 
			
		||||
  integrity sha512-6KAMdIfAtlK+qohTIUE4urwAv4A3YRuo8uAbByApUmiB0CziGAAPs6qVugN6oHPia8YIafHB/37K0O6KZ7sGmA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@vue/compiler-dom" "3.2.11"
 | 
			
		||||
    "@vue/runtime-dom" "3.2.11"
 | 
			
		||||
    "@vue/shared" "3.2.11"
 | 
			
		||||
    "@vue/compiler-dom" "3.2.19"
 | 
			
		||||
    "@vue/compiler-sfc" "3.2.19"
 | 
			
		||||
    "@vue/runtime-dom" "3.2.19"
 | 
			
		||||
    "@vue/server-renderer" "3.2.19"
 | 
			
		||||
    "@vue/shared" "3.2.19"
 | 
			
		||||
 | 
			
		||||
vuedraggable@^4.1.0:
 | 
			
		||||
  version "4.1.0"
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user