Commit e6db0d39b9ba98f6396866715ed3b6d56994697a

Authored by vben
1 parent 2e79c9f3

feat(layout): add mix sidebar mode

Showing 64 changed files with 1523 additions and 1090 deletions
CHANGELOG.zh_CN.md
... ... @@ -3,6 +3,11 @@
3 3 ### ✨ Features
4 4  
5 5 - 新增 `v-ripple`水波纹指令
  6 +- 新增左侧菜单混合模式
  7 +
  8 +### ✨ Refactor
  9 +
  10 +- 移除折叠显示菜单名配置
6 11  
7 12 ### 🐛 Bug Fixes
8 13  
... ...
package.json
... ... @@ -21,23 +21,23 @@
21 21 "reinstall": "rimraf yarn.lock && rimraf package.lock.json && rimraf node_modules && npm run bootstrap"
22 22 },
23 23 "dependencies": {
24   - "@iconify/iconify": "^2.0.0-rc.2",
25   - "@vueuse/core": "^4.0.0-rc.9",
  24 + "@iconify/iconify": "^2.0.0-rc.4",
  25 + "@vueuse/core": "^4.0.0",
26 26 "ant-design-vue": "^2.0.0-rc.5",
27   - "apexcharts": "^3.22.3",
  27 + "apexcharts": "^3.23.0",
28 28 "axios": "^0.21.0",
29 29 "crypto-es": "^1.2.6",
30 30 "echarts": "^4.9.0",
31   - "lodash-es": "^4.17.15",
  31 + "lodash-es": "^4.17.20",
32 32 "mockjs": "^1.1.0",
33 33 "moment": "^2.29.1",
34 34 "nprogress": "^0.2.0",
35 35 "path-to-regexp": "^6.2.0",
36 36 "qrcode": "^1.4.4",
37 37 "sortablejs": "^1.12.0",
38   - "vditor": "^3.7.2",
  38 + "vditor": "^3.7.3",
39 39 "vue": "^3.0.4",
40   - "vue-i18n": "^9.0.0-beta.13",
  40 + "vue-i18n": "9.0.0-beta.14",
41 41 "vue-router": "^4.0.1",
42 42 "vue-types": "^3.0.1",
43 43 "vuex": "^4.0.0-rc.2",
... ... @@ -48,7 +48,7 @@
48 48 "devDependencies": {
49 49 "@commitlint/cli": "^11.0.0",
50 50 "@commitlint/config-conventional": "^11.0.0",
51   - "@iconify/json": "^1.1.272",
  51 + "@iconify/json": "^1.1.275",
52 52 "@ls-lint/ls-lint": "^1.9.2",
53 53 "@purge-icons/generated": "^0.4.1",
54 54 "@types/echarts": "^4.9.3",
... ... @@ -61,10 +61,10 @@
61 61 "@types/qrcode": "^1.3.5",
62 62 "@types/rollup-plugin-visualizer": "^2.6.0",
63 63 "@types/sortablejs": "^1.10.6",
64   - "@types/yargs": "^15.0.11",
  64 + "@types/yargs": "^15.0.12",
65 65 "@types/zxcvbn": "^4.4.0",
66   - "@typescript-eslint/eslint-plugin": "^4.10.0",
67   - "@typescript-eslint/parser": "^4.10.0",
  66 + "@typescript-eslint/eslint-plugin": "^4.11.0",
  67 + "@typescript-eslint/parser": "^4.11.0",
68 68 "@vue/compiler-sfc": "^3.0.4",
69 69 "@vuedx/typecheck": "^0.2.4-0",
70 70 "@vuedx/typescript-plugin-vue": "^0.2.4-0",
... ... @@ -75,16 +75,16 @@
75 75 "cross-env": "^7.0.3",
76 76 "dot-prop": "^6.0.1",
77 77 "dotenv": "^8.2.0",
78   - "eslint": "^7.15.0",
79   - "eslint-config-prettier": "^7.0.0",
  78 + "eslint": "^7.16.0",
  79 + "eslint-config-prettier": "^7.1.0",
80 80 "eslint-plugin-prettier": "^3.3.0",
81   - "eslint-plugin-vue": "^7.2.0",
  81 + "eslint-plugin-vue": "^7.3.0",
82 82 "esno": "^0.3.0",
83 83 "fs-extra": "^9.0.1",
84 84 "globrex": "^0.1.2",
85 85 "husky": "^4.3.6",
86 86 "koa-static": "^5.0.0",
87   - "less": "^3.13.0",
  87 + "less": "^4.0.0",
88 88 "lint-staged": "^10.5.3",
89 89 "portfinder": "^1.0.28",
90 90 "postcss-import": "^12.0.1",
... ...
src/assets/images/layout/menu-mix.svg deleted 100644 → 0
1   -<?xml version="1.0" encoding="UTF-8"?>
2   -<svg width="52px" height="45px" viewBox="0 0 52 45" version="1.1"
3   - xmlns="http://www.w3.org/2000/svg"
4   - xmlns:xlink="http://www.w3.org/1999/xlink">
5   - <defs>
6   - <filter x="-9.4%" y="-6.2%" width="118.8%" height="122.5%" filterUnits="objectBoundingBox" id="filter-1">
7   - <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
8   - <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
9   - <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
10   - <feMerge>
11   - <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
12   - <feMergeNode in="SourceGraphic"></feMergeNode>
13   - </feMerge>
14   - </filter>
15   - <rect id="path-2" x="0" y="0" width="48" height="40" rx="4"></rect>
16   - <filter x="-4.2%" y="-2.5%" width="108.3%" height="110.0%" filterUnits="objectBoundingBox" id="filter-4">
17   - <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
18   - <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
19   - <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
20   - </filter>
21   - </defs>
22   - <g id="配置面板" width="48" height="40" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
23   - <g id="setting-copy-2" width="48" height="40" transform="translate(-1190.000000, -136.000000)">
24   - <g id="Group-8" width="48" height="40" transform="translate(1167.000000, 0.000000)">
25   - <g id="Group-5-Copy-5" filter="url(#filter-1)" transform="translate(25.000000, 137.000000)">
26   - <mask id="mask-3" fill="white">
27   - <use xlink:href="#path-2"></use>
28   - </mask>
29   - <g id="Rectangle-18">
30   - <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
31   - <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-2"></use>
32   - </g>
33   - <rect id="Rectangle-18" fill="#fff" mask="url(#mask-3)" x="0" y="0" width="16" height="40"></rect>
34   - <rect id="Rectangle-11" fill="#303648" mask="url(#mask-3)" x="0" y="0" width="48" height="10"></rect>
35   - </g>
36   - </g>
37   - </g>
38   - </g>
39   -</svg>
src/assets/images/layout/menu-sidebar.svg deleted 100644 → 0
1   -<?xml version="1.0" encoding="UTF-8"?>
2   -<svg width="52px" height="45px" viewBox="0 0 52 45" version="1.1"
3   - xmlns="http://www.w3.org/2000/svg"
4   - xmlns:xlink="http://www.w3.org/1999/xlink">
5   - <defs>
6   - <filter x="-9.4%" y="-6.2%" width="118.8%" height="122.5%" filterUnits="objectBoundingBox" id="filter-1">
7   - <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
8   - <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
9   - <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
10   - <feMerge>
11   - <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
12   - <feMergeNode in="SourceGraphic"></feMergeNode>
13   - </feMerge>
14   - </filter>
15   - <rect id="path-2" x="0" y="0" width="48" height="40" rx="4"></rect>
16   - <filter x="-4.2%" y="-2.5%" width="108.3%" height="110.0%" filterUnits="objectBoundingBox" id="filter-4">
17   - <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
18   - <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
19   - <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
20   - </filter>
21   - </defs>
22   - <g width="48" height="40" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
23   - <g id="setting-copy-2" width="48" height="40" transform="translate(-1190.000000, -136.000000)">
24   - <g id="Group-8" width="48" height="40" transform="translate(1167.000000, 0.000000)">
25   - <g id="Group-5-Copy-5" filter="url(#filter-1)" transform="translate(25.000000, 137.000000)">
26   - <mask id="mask-3" fill="white">
27   - <use xlink:href="#path-2"></use>
28   - </mask>
29   - <g id="Rectangle-18">
30   - <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
31   - <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-2"></use>
32   - </g>
33   - <rect id="Rectangle-11" fill="#FFFFFF" mask="url(#mask-3)" x="0" y="0" width="48" height="10"></rect>
34   - <rect id="Rectangle-18" fill="#303648" mask="url(#mask-3)" x="0" y="0" width="16" height="40"></rect>
35   - </g>
36   - </g>
37   - </g>
38   - </g>
39   -</svg>
src/assets/images/layout/menu-top.svg deleted 100644 → 0
1   -<?xml version="1.0" encoding="UTF-8"?>
2   -<svg width="52px" height="45px" viewBox="0 0 52 45" version="1.1"
3   - xmlns="http://www.w3.org/2000/svg"
4   - xmlns:xlink="http://www.w3.org/1999/xlink">
5   -
6   - <defs>
7   - <filter x="-9.4%" y="-6.2%" width="118.8%" height="122.5%" filterUnits="objectBoundingBox" id="filter-1">
8   - <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
9   - <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
10   - <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
11   - <feMerge>
12   - <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
13   - <feMergeNode in="SourceGraphic"></feMergeNode>
14   - </feMerge>
15   - </filter>
16   - <rect id="path-2" x="0" y="0" width="48" height="40" rx="4"></rect>
17   - <filter x="-4.2%" y="-2.5%" width="108.3%" height="110.0%" filterUnits="objectBoundingBox" id="filter-4">
18   - <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
19   - <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
20   - <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
21   - </filter>
22   - </defs>
23   - <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
24   - <g id="setting-copy-2" transform="translate(-1254.000000, -337.000000)">
25   - <g id="Group-8" transform="translate(1167.000000, 0.000000)">
26   - <g id="Group-5" filter="url(#filter-1)" transform="translate(89.000000, 338.000000)">
27   - <mask id="mask-3" fill="white">
28   - <use xlink:href="#path-2"></use>
29   - </mask>
30   - <g id="Rectangle-18">
31   - <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
32   - <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-2"></use>
33   - </g>
34   - <rect id="Rectangle-11" fill="#303648" mask="url(#mask-3)" x="0" y="0" width="48" height="10"></rect>
35   - </g>
36   - </g>
37   - </g>
38   - </g>
39   -</svg>
src/components/Application/src/AppLogo.vue
... ... @@ -3,14 +3,10 @@
3 3 * @Description: logo component
4 4 -->
5 5 <template>
6   - <div
7   - class="anticon"
8   - :class="[prefixCls, theme, { 'collapsed-show-title': getCollapsedShowTitle }]"
9   - @click="handleGoHome"
10   - >
  6 + <div class="anticon" :class="[prefixCls, theme]" @click="handleGoHome">
11 7 <img src="/@/assets/images/logo.png" />
12 8 <div class="ml-2 ellipsis" :class="[`${prefixCls}__title`]" v-show="showTitle">
13   - {{ globSetting.title }}
  9 + {{ title }}
14 10 </div>
15 11 </div>
16 12 </template>
... ... @@ -40,9 +36,7 @@
40 36 setup() {
41 37 const { prefixCls } = useDesign('app-logo');
42 38  
43   - const { getCollapsedShowTitle } = useMenuSetting();
44   -
45   - const globSetting = useGlobSetting();
  39 + const { title } = useGlobSetting();
46 40  
47 41 const go = useGo();
48 42  
... ... @@ -52,8 +46,7 @@
52 46  
53 47 return {
54 48 handleGoHome,
55   - globSetting,
56   - getCollapsedShowTitle,
  49 + title,
57 50 prefixCls,
58 51 };
59 52 },
... ... @@ -70,10 +63,6 @@
70 63 cursor: pointer;
71 64 transition: all 0.2s ease;
72 65  
73   - &.collapsed-show-title {
74   - padding-left: 20px;
75   - }
76   -
77 66 &.light {
78 67 border-bottom: 1px solid @border-color-base;
79 68 }
... ...
src/components/Application/src/search/AppSearchModal.vue
... ... @@ -65,10 +65,12 @@
65 65 import { useI18n } from '/@/hooks/web/useI18n';
66 66 import { ClickOutSide } from '/@/components/ClickOutSide';
67 67 import { useAppInject } from '/@/hooks/web/useAppInject';
  68 +
68 69 export default defineComponent({
69 70 name: 'AppSearchModal',
70 71 components: { SearchOutlined, ClickOutSide, AppSearchFooter },
71 72 emits: ['close'],
  73 +
72 74 props: {
73 75 visible: Boolean,
74 76 },
... ...
src/components/ClickOutSide/src/index.vue
... ... @@ -3,12 +3,13 @@
3 3 </template>
4 4 <script lang="ts">
5 5 import type { Ref } from 'vue';
6   - import { defineComponent, ref } from 'vue';
  6 + import { defineComponent, ref, onMounted } from 'vue';
7 7  
8 8 import { useClickOutside } from '/@/hooks/web/useClickOutside';
9 9  
10 10 export default defineComponent({
11 11 name: 'ClickOutSide',
  12 + emits: ['mounted', 'clickOutside'],
12 13 setup(_, { emit }) {
13 14 const wrap = ref<ElRef>(null);
14 15  
... ... @@ -16,6 +17,10 @@
16 17 emit('clickOutside');
17 18 });
18 19  
  20 + onMounted(() => {
  21 + emit('mounted');
  22 + });
  23 +
19 24 return { wrap };
20 25 },
21 26 });
... ...
src/components/Markdown/src/index.vue
... ... @@ -57,7 +57,7 @@
57 57 onUnmounted(() => {
58 58 const vditorInstance = unref(vditorRef);
59 59 if (!vditorInstance) return;
60   - vditorInstance.destroy();
  60 + vditorInstance?.destroy?.();
61 61 });
62 62  
63 63 return {
... ...
src/components/Menu/index.ts
... ... @@ -6,4 +6,8 @@ export const BasicMenu = createAsyncComponent(() =&gt; import(&#39;./src/BasicMenu.vue&#39;
6 6 loading: false,
7 7 });
8 8  
  9 +export const MenuTag = createAsyncComponent(() => import('./src/components/MenuItemTag.vue'), {
  10 + loading: false,
  11 +});
  12 +
9 13 withInstall(BasicMenu);
... ...
src/components/Menu/src/BasicMenu.vue
... ... @@ -17,7 +17,7 @@
17 17 :item="item"
18 18 :theme="theme"
19 19 :level="1"
20   - :showTitle="showTitle"
  20 + :showTitle="!getCollapsed"
21 21 :isHorizontal="isHorizontal"
22 22 />
23 23 </template>
... ... @@ -95,16 +95,12 @@
95 95 prefixCls,
96 96 `justify-${align}`,
97 97 {
98   - [`${prefixCls}--hide-title`]: !unref(showTitle),
99   - [`${prefixCls}--collapsed-show-title`]: props.collapsedShowTitle,
100 98 [`${prefixCls}__second`]: !props.isHorizontal && unref(getSplit),
101 99 [`${prefixCls}__sidebar-hor`]: unref(getIsTopMenu),
102 100 },
103 101 ];
104 102 });
105 103  
106   - const showTitle = computed(() => props.collapsedShowTitle && unref(getCollapsed));
107   -
108 104 const getInlineCollapseOptions = computed(() => {
109 105 const isInline = props.mode === MenuModeEnum.INLINE;
110 106  
... ... @@ -168,7 +164,7 @@
168 164 getMenuClass,
169 165 handleOpenChange,
170 166 getOpenKeys,
171   - showTitle,
  167 + getCollapsed,
172 168 ...toRefs(menuState),
173 169 };
174 170 },
... ...
src/components/Menu/src/components/MenuItemTag.vue
... ... @@ -15,6 +15,7 @@
15 15  
16 16 const getShowTag = computed(() => {
17 17 const { item, showTitle, isHorizontal } = props;
  18 +
18 19 if (!item || showTitle || isHorizontal) return false;
19 20  
20 21 const { tag } = item;
... ...
src/components/Menu/src/index.less
... ... @@ -48,47 +48,16 @@
48 48 opacity: 1 !important;
49 49 }
50 50  
51   - &--hide-title {
52   - &.ant-menu-inline-collapsed > .ant-menu-item,
53   - &.ant-menu-inline-collapsed > .ant-menu-item-group > .ant-menu-item-group-list > .ant-menu-item,
54   - &.ant-menu-inline-collapsed
55   - > .ant-menu-item-group
56   - > .ant-menu-item-group-list
57   - > .ant-menu-submenu
58   - > .ant-menu-submenu-title,
59   - &.ant-menu-inline-collapsed .ant-menu-submenu-title {
60   - padding-right: 16px !important;
61   - padding-left: 16px !important;
62   - }
63   - }
64   -
65   - &--collapsed-show-title.ant-menu-inline-collapsed {
66   - .@{basic-menu-prefix-cls}-item__level1 {
67   - padding: 2px 0;
68   - }
69   -
70   - & > li[role='menuitem']:not(.ant-menu-submenu),
71   - & > li > .ant-menu-submenu-title {
72   - display: flex;
73   - margin-top: 10px;
74   - font-size: 12px;
75   - flex-direction: column;
76   - align-items: center;
77   - line-height: 24px;
78   - }
79   -
80   - & > li > .ant-menu-submenu-title {
81   - line-height: 24px;
82   - }
83   - .@{basic-menu-content-prefix-cls}-wrapper {
84   - display: flex;
85   - justify-content: center;
86   - align-items: center;
87   - flex-direction: column;
88   - .@{basic-menu-content-prefix-cls}--show-title {
89   - line-height: 30px;
90   - }
91   - }
  51 + &.ant-menu-inline-collapsed > .ant-menu-item,
  52 + &.ant-menu-inline-collapsed > .ant-menu-item-group > .ant-menu-item-group-list > .ant-menu-item,
  53 + &.ant-menu-inline-collapsed
  54 + > .ant-menu-item-group
  55 + > .ant-menu-item-group-list
  56 + > .ant-menu-submenu
  57 + > .ant-menu-submenu-title,
  58 + &.ant-menu-inline-collapsed .ant-menu-submenu-title {
  59 + padding-right: 16px !important;
  60 + padding-left: 16px !important;
92 61 }
93 62  
94 63 .@{basic-menu-content-prefix-cls}-wrapper {
... ... @@ -252,43 +221,6 @@
252 221 }
253 222 }
254 223  
255   - .@{basic-menu-tag-prefix-cls} {
256   - position: absolute;
257   - top: calc(50% - 8px);
258   - right: 30px;
259   - display: inline-block;
260   - padding: 2px 4px;
261   - margin-right: 4px;
262   - font-size: 12px;
263   - line-height: 14px;
264   - color: #fff;
265   - border-radius: 2px;
266   -
267   - &--dot {
268   - top: calc(50% - 4px);
269   - width: 8px;
270   - height: 8px;
271   - padding: 0;
272   - border-radius: 50%;
273   - }
274   -
275   - &--primary {
276   - background: @primary-color;
277   - }
278   -
279   - &--error {
280   - background: @error-color;
281   - }
282   -
283   - &--success {
284   - background: @success-color;
285   - }
286   -
287   - &--warn {
288   - background: @warning-color;
289   - }
290   - }
291   -
292 224 .ant-menu-submenu,
293 225 .ant-menu-submenu-inline {
294 226 transition: unset;
... ... @@ -322,3 +254,40 @@
322 254 }
323 255 }
324 256 }
  257 +
  258 +.@{basic-menu-tag-prefix-cls} {
  259 + position: absolute;
  260 + top: calc(50% - 8px);
  261 + right: 30px;
  262 + display: inline-block;
  263 + padding: 2px 4px;
  264 + margin-right: 4px;
  265 + font-size: 12px;
  266 + line-height: 14px;
  267 + color: #fff;
  268 + border-radius: 2px;
  269 +
  270 + &--dot {
  271 + top: calc(50% - 4px);
  272 + width: 6px;
  273 + height: 6px;
  274 + padding: 0;
  275 + border-radius: 50%;
  276 + }
  277 +
  278 + &--primary {
  279 + background: @primary-color;
  280 + }
  281 +
  282 + &--error {
  283 + background: @error-color;
  284 + }
  285 +
  286 + &--success {
  287 + background: @success-color;
  288 + }
  289 +
  290 + &--warn {
  291 + background: @warning-color;
  292 + }
  293 +}
... ...
src/components/Menu/src/props.ts
... ... @@ -10,8 +10,6 @@ export const basicProps = {
10 10 default: () => [],
11 11 },
12 12  
13   - collapsedShowTitle: propTypes.bool,
14   -
15 13 // 最好是4 倍数
16 14 inlineIndent: propTypes.number.def(20),
17 15 // 菜单组件的mode属性
... ... @@ -19,7 +17,6 @@ export const basicProps = {
19 17 type: String as PropType<MenuModeEnum>,
20 18 default: MenuModeEnum.INLINE,
21 19 },
22   - showLogo: propTypes.bool,
23 20 type: {
24 21 type: String as PropType<MenuTypeEnum>,
25 22 default: MenuTypeEnum.MIX,
... ...
src/components/Tinymce/src/Editor.vue
... ... @@ -107,7 +107,7 @@
107 107  
108 108 function destory() {
109 109 if (getTinymce() !== null) {
110   - getTinymce().remove(unref(editorRef));
  110 + getTinymce()?.remove?.(unref(editorRef));
111 111 }
112 112 }
113 113  
... ...
src/design/var/index.less
... ... @@ -26,6 +26,8 @@
26 26  
27 27 @layout-sider-fixed-z-index: 510;
28 28  
  29 +@layout-mix-sider-fixed-z-index: 550;
  30 +
29 31 @preview-comp-z-index: 1000;
30 32  
31 33 @page-footer-z-index: 99;
... ...
src/directives/clickOutside.ts 0 → 100644
  1 +import { on } from '/@/utils/domUtils';
  2 +import { isServer } from '/@/utils/is';
  3 +import type { ComponentPublicInstance, DirectiveBinding, ObjectDirective } from 'vue';
  4 +
  5 +type DocumentHandler = <T extends MouseEvent>(mouseup: T, mousedown: T) => void;
  6 +
  7 +type FlushList = Map<
  8 + HTMLElement,
  9 + {
  10 + documentHandler: DocumentHandler;
  11 + bindingFn: (...args: unknown[]) => unknown;
  12 + }
  13 +>;
  14 +
  15 +const nodeList: FlushList = new Map();
  16 +
  17 +let startClick: MouseEvent;
  18 +
  19 +if (!isServer) {
  20 + on(document, 'mousedown', (e: MouseEvent) => (startClick = e));
  21 + on(document, 'mouseup', (e: MouseEvent) => {
  22 + for (const { documentHandler } of nodeList.values()) {
  23 + documentHandler(e, startClick);
  24 + }
  25 + });
  26 +}
  27 +
  28 +function createDocumentHandler(el: HTMLElement, binding: DirectiveBinding): DocumentHandler {
  29 + let excludes: HTMLElement[] = [];
  30 + if (Array.isArray(binding.arg)) {
  31 + excludes = binding.arg;
  32 + } else {
  33 + // due to current implementation on binding type is wrong the type casting is necessary here
  34 + excludes.push((binding.arg as unknown) as HTMLElement);
  35 + }
  36 + return function (mouseup, mousedown) {
  37 + const popperRef = (binding.instance as ComponentPublicInstance<{
  38 + popperRef: Nullable<HTMLElement>;
  39 + }>).popperRef;
  40 + const mouseUpTarget = mouseup.target as Node;
  41 + const mouseDownTarget = mousedown.target as Node;
  42 + const isBound = !binding || !binding.instance;
  43 + const isTargetExists = !mouseUpTarget || !mouseDownTarget;
  44 + const isContainedByEl = el.contains(mouseUpTarget) || el.contains(mouseDownTarget);
  45 + const isSelf = el === mouseUpTarget;
  46 +
  47 + const isTargetExcluded =
  48 + (excludes.length && excludes.some((item) => item?.contains(mouseUpTarget))) ||
  49 + (excludes.length && excludes.includes(mouseDownTarget as HTMLElement));
  50 + const isContainedByPopper =
  51 + popperRef && (popperRef.contains(mouseUpTarget) || popperRef.contains(mouseDownTarget));
  52 + if (
  53 + isBound ||
  54 + isTargetExists ||
  55 + isContainedByEl ||
  56 + isSelf ||
  57 + isTargetExcluded ||
  58 + isContainedByPopper
  59 + ) {
  60 + return;
  61 + }
  62 + binding.value();
  63 + };
  64 +}
  65 +
  66 +const ClickOutside: ObjectDirective = {
  67 + beforeMount(el, binding) {
  68 + nodeList.set(el, {
  69 + documentHandler: createDocumentHandler(el, binding),
  70 + bindingFn: binding.value,
  71 + });
  72 + },
  73 + updated(el, binding) {
  74 + nodeList.set(el, {
  75 + documentHandler: createDocumentHandler(el, binding),
  76 + bindingFn: binding.value,
  77 + });
  78 + },
  79 + unmounted(el) {
  80 + nodeList.delete(el);
  81 + },
  82 +};
  83 +
  84 +export default ClickOutside;
... ...
src/enums/menuEnum.ts
... ... @@ -4,6 +4,8 @@
4 4 export enum MenuTypeEnum {
5 5 // left menu
6 6 SIDEBAR = 'sidebar',
  7 +
  8 + MIX_SIDEBAR = 'mix-sidebar',
7 9 // mixin menu
8 10 MIX = 'mix',
9 11 // top menu
... ...
src/hooks/setting/useHeaderSetting.ts
... ... @@ -16,6 +16,7 @@ const {
16 16 getSplit,
17 17 getShowHeaderTrigger,
18 18 getIsSidebarType,
  19 + getIsMixSidebar,
19 20 getIsTopMenu,
20 21 } = useMenuSetting();
21 22 const { getShowBreadCrumb, getShowLogo } = useRootSetting();
... ... @@ -27,13 +28,18 @@ const getShowFullHeaderRef = computed(() =&gt; {
27 28 !unref(getFullContent) &&
28 29 unref(getShowMixHeaderRef) &&
29 30 unref(getShowHeader) &&
30   - !unref(getIsTopMenu)
  31 + !unref(getIsTopMenu) &&
  32 + !unref(getIsMixSidebar)
31 33 );
32 34 });
33 35  
34 36 const getShowInsetHeaderRef = computed(() => {
35 37 const need = !unref(getFullContent) && unref(getShowHeader);
36   - return (need && !unref(getShowMixHeaderRef)) || (need && unref(getIsTopMenu));
  38 + return (
  39 + (need && !unref(getShowMixHeaderRef)) ||
  40 + (need && unref(getIsTopMenu)) ||
  41 + (need && unref(getIsMixSidebar))
  42 + );
37 43 });
38 44  
39 45 // Get header configuration
... ... @@ -66,7 +72,7 @@ const getShowBread = computed(() =&gt; {
66 72 });
67 73  
68 74 const getShowHeaderLogo = computed(() => {
69   - return unref(getShowLogo) && !unref(getIsSidebarType);
  75 + return unref(getShowLogo) && !unref(getIsSidebarType) && !unref(getIsMixSidebar);
70 76 });
71 77  
72 78 const getShowContent = computed(() => {
... ...
src/hooks/setting/useMenuSetting.ts
... ... @@ -37,10 +37,10 @@ const getCanDrag = computed(() =&gt; unref(getMenuSetting).canDrag);
37 37  
38 38 const getAccordion = computed(() => unref(getMenuSetting).accordion);
39 39  
40   -const getCollapsedShowTitle = computed(() => unref(getMenuSetting).collapsedShowTitle);
41   -
42 40 const getTopMenuAlign = computed(() => unref(getMenuSetting).topMenuAlign);
43 41  
  42 +const getCloseMixSidebarOnChange = computed(() => unref(getMenuSetting).closeMixSidebarOnChange);
  43 +
44 44 const getIsSidebarType = computed(() => unref(getMenuType) === MenuTypeEnum.SIDEBAR);
45 45  
46 46 const getIsTopMenu = computed(() => unref(getMenuType) === MenuTypeEnum.TOP_MENU);
... ... @@ -61,6 +61,10 @@ const getIsHorizontal = computed(() =&gt; {
61 61 return unref(getMenuMode) === MenuModeEnum.HORIZONTAL;
62 62 });
63 63  
  64 +const getIsMixSidebar = computed(() => {
  65 + return unref(getMenuType) === MenuTypeEnum.MIX_SIDEBAR;
  66 +});
  67 +
64 68 const getIsMixMode = computed(() => {
65 69 return unref(getMenuMode) === MenuModeEnum.INLINE && unref(getMenuType) === MenuTypeEnum.MIX;
66 70 });
... ... @@ -70,14 +74,15 @@ const getRealWidth = computed(() =&gt; {
70 74 });
71 75  
72 76 const getMiniWidthNumber = computed(() => {
73   - const { collapsedShowTitle } = unref(getMenuSetting);
74   - return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH;
  77 + return SIDE_BAR_MINI_WIDTH;
75 78 });
76 79  
77 80 const getCalcContentWidth = computed(() => {
78 81 const width =
79 82 unref(getIsTopMenu) || !unref(getShowMenu) || (unref(getSplit) && unref(getMenuHidden))
80 83 ? 0
  84 + : unref(getIsMixSidebar)
  85 + ? SIDE_BAR_SHOW_TIT_MINI_WIDTH
81 86 : unref(getRealWidth);
82 87  
83 88 return `calc(100% - ${unref(width)}px)`;
... ... @@ -124,7 +129,6 @@ export function useMenuSetting() {
124 129 getMenuTheme,
125 130 getCanDrag,
126 131 getIsHorizontal,
127   - getCollapsedShowTitle,
128 132 getIsSidebarType,
129 133 getAccordion,
130 134 getShowTopMenu,
... ... @@ -135,5 +139,7 @@ export function useMenuSetting() {
135 139 getMenuBgColor,
136 140 getShowSidebar,
137 141 getIsMixMode,
  142 + getIsMixSidebar,
  143 + getCloseMixSidebarOnChange,
138 144 };
139 145 }
... ...
src/hooks/web/useApexCharts.ts
... ... @@ -51,7 +51,7 @@ export function useApexCharts(elRef: Ref&lt;HTMLDivElement&gt;) {
51 51  
52 52 tryOnUnmounted(() => {
53 53 if (!chartInstance) return;
54   - chartInstance.destroy();
  54 + chartInstance?.destroy?.();
55 55 chartInstance = null;
56 56 });
57 57  
... ...
src/hooks/web/useI18n.ts
... ... @@ -36,5 +36,5 @@ export function useI18n(namespace?: string) {
36 36 // Mainly to configure the vscode i18nn ally plugin. This function is only used for routing and menus. Please use useI18n for other places
37 37  
38 38 // 为什么要编写此函数?
39   -// 主要用于配合vscode i18nn ally插件。此功能仅用于路由和菜单。请在其他地方使用useIs18n
  39 +// 主要用于配合vscode i18nn ally插件。此功能仅用于路由和菜单。请在其他地方使用useI18n
40 40 export const t = (key: string) => key;
... ...
src/layouts/default/header/components/Breadcrumb.vue
... ... @@ -48,7 +48,7 @@
48 48 if (currentRoute.value.name === REDIRECT_NAME) {
49 49 return;
50 50 }
51   - const matched = currentRoute.value.matched;
  51 + const matched = currentRoute.value?.matched;
52 52 if (!matched || matched.length === 0) return;
53 53  
54 54 let breadcrumbList = filter(toRaw(matched), (item) => {
... ... @@ -102,7 +102,7 @@
102 102 color: @breadcrumb-item-normal-color;
103 103  
104 104 a {
105   - color: @text-color-base;
  105 + color: rgba(0, 0, 0, 0.65);
106 106  
107 107 &:hover {
108 108 color: @primary-color;
... ...
src/layouts/default/header/index.vue
... ... @@ -10,7 +10,9 @@
10 10 :style="getLogoWidth"
11 11 />
12 12 <LayoutTrigger
13   - v-if="(getShowContent && getShowHeaderTrigger && !getSplit) || getIsMobile"
  13 + v-if="
  14 + (getShowContent && getShowHeaderTrigger && !getSplit && !getIsMixSidebar) || getIsMobile
  15 + "
14 16 :theme="getHeaderTheme"
15 17 :sider="false"
16 18 />
... ... @@ -110,6 +112,7 @@
110 112 getSplit,
111 113 getIsMixMode,
112 114 getMenuWidth,
  115 + getIsMixSidebar,
113 116 } = useMenuSetting();
114 117 const { getShowLocale } = useLocaleSetting();
115 118 const { getUseErrorHandle } = useRootSetting();
... ... @@ -173,6 +176,7 @@
173 176 getUseLockPage,
174 177 getUseErrorHandle,
175 178 getLogoWidth,
  179 + getIsMixSidebar,
176 180 };
177 181 },
178 182 });
... ...
src/layouts/default/index.vue
... ... @@ -2,7 +2,7 @@
2 2 <Layout :class="prefixCls">
3 3 <LayoutFeatures />
4 4 <LayoutHeader fixed v-if="getShowFullHeaderRef" />
5   - <Layout>
  5 + <Layout class="ant-layout-has-sider">
6 6 <LayoutSideBar v-if="getShowSidebar || getIsMobile" />
7 7 <Layout :class="`${prefixCls}__main`">
8 8 <LayoutMultipleHeader />
... ... @@ -53,13 +53,14 @@
53 53  
54 54 const { getShowFullHeaderRef } = useHeaderSetting();
55 55  
56   - const { getShowSidebar } = useMenuSetting();
  56 + const { getShowSidebar, getIsMixSidebar } = useMenuSetting();
57 57  
58 58 return {
59 59 getShowFullHeaderRef,
60 60 getShowSidebar,
61 61 prefixCls,
62 62 getIsMobile,
  63 + getIsMixSidebar,
63 64 };
64 65 },
65 66 });
... ...
src/layouts/default/menu/index.tsx
... ... @@ -43,7 +43,6 @@ export default defineComponent({
43 43 const {
44 44 getMenuMode,
45 45 getMenuType,
46   - getCollapsedShowTitle,
47 46 getMenuTheme,
48 47 getCollapsed,
49 48 getAccordion,
... ... @@ -132,12 +131,10 @@ export default defineComponent({
132 131 isHorizontal={props.isHorizontal}
133 132 type={unref(getMenuType)}
134 133 mode={unref(getComputedMenuMode)}
135   - collapsedShowTitle={unref(getCollapsedShowTitle)}
136 134 theme={unref(getComputedMenuTheme)}
137 135 items={unref(menusRef)}
138 136 accordion={unref(getAccordion)}
139 137 onMenuClick={handleMenuClick}
140   - showLogo={unref(getIsShowLogo)}
141 138 />
142 139 );
143 140 }
... ...
src/layouts/default/setting/SettingDrawer.tsx
... ... @@ -61,7 +61,6 @@ export default defineComponent({
61 61 getShowMenu,
62 62 getMenuType,
63 63 getTrigger,
64   - getCollapsedShowTitle,
65 64 getMenuFixed,
66 65 getCollapsed,
67 66 getCanDrag,
... ... @@ -71,6 +70,8 @@ export default defineComponent({
71 70 getMenuBgColor,
72 71 getIsTopMenu,
73 72 getSplit,
  73 + getIsMixSidebar,
  74 + getCloseMixSidebarOnChange,
74 75 } = useMenuSetting();
75 76  
76 77 const {
... ... @@ -106,6 +107,13 @@ export default defineComponent({
106 107 def={unref(getSplit)}
107 108 disabled={!unref(getShowMenuRef) || unref(getMenuType) !== MenuTypeEnum.MIX}
108 109 />
  110 +
  111 + <SwitchItem
  112 + title={t('layout.setting.closeMixSidebarOnChange')}
  113 + event={HandlerEnum.MENU_CLOSE_MIX_SIDEBAR_ON_CHANGE}
  114 + def={unref(getCloseMixSidebarOnChange)}
  115 + disabled={!unref(getIsMixSidebar)}
  116 + />
109 117 </>
110 118 );
111 119 }
... ... @@ -166,14 +174,9 @@ export default defineComponent({
166 174 title={t('layout.setting.menuCollapse')}
167 175 event={HandlerEnum.MENU_COLLAPSED}
168 176 def={unref(getCollapsed)}
169   - disabled={!unref(getShowMenuRef)}
170   - />
171   - <SwitchItem
172   - title={t('layout.setting.collapseMenuDisplayName')}
173   - event={HandlerEnum.MENU_COLLAPSED_SHOW_TITLE}
174   - def={unref(getCollapsedShowTitle)}
175   - disabled={!unref(getShowMenuRef) || !unref(getCollapsed)}
  177 + disabled={!unref(getShowMenuRef) || unref(getIsMixSidebar)}
176 178 />
  179 +
177 180 <SwitchItem
178 181 title={t('layout.setting.fixedHeader')}
179 182 event={HandlerEnum.HEADER_FIXED}
... ... @@ -184,7 +187,7 @@ export default defineComponent({
184 187 title={t('layout.setting.fixedSideBar')}
185 188 event={HandlerEnum.MENU_FIXED}
186 189 def={unref(getMenuFixed)}
187   - disabled={!unref(getShowMenuRef)}
  190 + disabled={!unref(getShowMenuRef) || unref(getIsMixSidebar)}
188 191 />
189 192 <SelectItem
190 193 title={t('layout.setting.topMenuLayout')}
... ... @@ -192,7 +195,10 @@ export default defineComponent({
192 195 def={unref(getTopMenuAlign)}
193 196 options={topMenuAlignOptions}
194 197 disabled={
195   - !unref(getShowHeader) || unref(getSplit) || (!unref(getIsTopMenu) && !unref(getSplit))
  198 + !unref(getShowHeader) ||
  199 + unref(getSplit) ||
  200 + (!unref(getIsTopMenu) && !unref(getSplit)) ||
  201 + unref(getIsMixSidebar)
196 202 }
197 203 />
198 204 <SelectItem
... ... @@ -200,7 +206,7 @@ export default defineComponent({
200 206 event={HandlerEnum.MENU_TRIGGER}
201 207 def={triggerDef}
202 208 options={triggerOptions}
203   - disabled={!unref(getShowMenuRef)}
  209 + disabled={!unref(getShowMenuRef) || unref(getIsMixSidebar)}
204 210 />
205 211 <SelectItem
206 212 title={t('layout.setting.contentMode')}
... ... @@ -282,7 +288,12 @@ export default defineComponent({
282 288 event={HandlerEnum.HEADER_SHOW}
283 289 def={unref(getShowHeader)}
284 290 />
285   - <SwitchItem title="Logo" event={HandlerEnum.SHOW_LOGO} def={unref(getShowLogo)} />
  291 + <SwitchItem
  292 + title="Logo"
  293 + event={HandlerEnum.SHOW_LOGO}
  294 + def={unref(getShowLogo)}
  295 + disabled={unref(getIsMixSidebar)}
  296 + />
286 297 <SwitchItem
287 298 title={t('layout.setting.footer')}
288 299 event={HandlerEnum.SHOW_FOOTER}
... ...
src/layouts/default/setting/components/TypePicker.vue
... ... @@ -6,12 +6,13 @@
6 6 @click="handler(item)"
7 7 :class="[
8 8 `${prefixCls}__item`,
  9 + `${prefixCls}__item--${item.type}`,
9 10 {
10 11 [`${prefixCls}__item--active`]: def === item.type,
11 12 },
12 13 ]"
13 14 >
14   - <img :src="item.src" />
  15 + <div class="mix-sidebar" />
15 16 </div>
16 17 </Tooltip>
17 18 </template>
... ... @@ -58,33 +59,118 @@
58 59  
59 60 &__item {
60 61 position: relative;
61   - width: 70px;
62   - height: 50px;
63   - margin: 0 20px 20px 0;
  62 + width: 56px;
  63 + height: 48px;
  64 + margin-right: 16px;
  65 + overflow: hidden;
64 66 cursor: pointer;
65   - border-radius: 6px;
  67 + background-color: #f0f2f5;
  68 + border-radius: 4px;
  69 + box-shadow: 0 1px 2.5px 0 rgba(0, 0, 0, 0.18);
66 70  
  71 + &::before,
67 72 &::after {
68 73 position: absolute;
69   - top: 50%;
70   - left: 50%;
71   - width: 0;
72   - height: 0;
73 74 content: '';
74   - opacity: 0;
75   - transition: all 0.3s;
76 75 }
77 76  
  77 + &--sidebar {
  78 + &::before {
  79 + top: 0;
  80 + left: 0;
  81 + z-index: 1;
  82 + width: 33%;
  83 + height: 100%;
  84 + background-color: #273352;
  85 + border-radius: 4px 0 0 4px;
  86 + }
  87 +
  88 + &::after {
  89 + top: 0;
  90 + left: 0;
  91 + width: 100%;
  92 + height: 25%;
  93 + background-color: #fff;
  94 + }
  95 + }
  96 +
  97 + &--mix {
  98 + &::before {
  99 + top: 0;
  100 + left: 0;
  101 + width: 33%;
  102 + height: 100%;
  103 + background-color: #fff;
  104 + border-radius: 4px 0 0 4px;
  105 + }
  106 +
  107 + &::after {
  108 + top: 0;
  109 + left: 0;
  110 + z-index: 1;
  111 + width: 100%;
  112 + height: 25%;
  113 + background-color: #273352;
  114 + }
  115 + }
  116 +
  117 + &--top-menu {
  118 + &::after {
  119 + top: 0;
  120 + left: 0;
  121 + width: 100%;
  122 + height: 25%;
  123 + background-color: #273352;
  124 + }
  125 + }
  126 +
  127 + &--mix-sidebar {
  128 + &::before {
  129 + top: 0;
  130 + left: 0;
  131 + z-index: 1;
  132 + width: 25%;
  133 + height: 100%;
  134 + background-color: #273352;
  135 + border-radius: 4px 0 0 4px;
  136 + }
  137 +
  138 + &::after {
  139 + top: 0;
  140 + left: 0;
  141 + width: 100%;
  142 + height: 25%;
  143 + background-color: #fff;
  144 + }
  145 +
  146 + .mix-sidebar {
  147 + position: absolute;
  148 + left: 25%;
  149 + width: 15%;
  150 + height: 100%;
  151 + background-color: #fff;
  152 + }
  153 + }
  154 +
  155 + // &::after {
  156 + // position: absolute;
  157 + // top: 50%;
  158 + // left: 50%;
  159 + // width: 0;
  160 + // height: 0;
  161 + // content: '';
  162 + // opacity: 0;
  163 + // transition: all 0.3s;
  164 + // }
  165 +
78 166 &:hover,
79 167 &--active {
  168 + padding: 12px;
  169 + border: 2px solid @primary-color;
  170 +
  171 + &::before,
80 172 &::after {
81   - top: -8px;
82   - left: -4px;
83   - width: 80px;
84   - height: 64px;
85   - border: 2px solid @primary-color;
86   - border-radius: 6px;
87   - opacity: 1;
  173 + border-radius: 0;
88 174 }
89 175 }
90 176 }
... ...
src/layouts/default/setting/enum.ts
1 1 import { ContentEnum, RouterTransitionEnum } from '/@/enums/appEnum';
2 2 import { MenuModeEnum, MenuTypeEnum, TopMenuAlignEnum, TriggerEnum } from '/@/enums/menuEnum';
3 3  
4   -import mixImg from '/@/assets/images/layout/menu-mix.svg';
5   -import sidebarImg from '/@/assets/images/layout/menu-sidebar.svg';
6   -import menuTopImg from '/@/assets/images/layout/menu-top.svg';
7 4 import { useI18n } from '/@/hooks/web/useI18n';
8 5  
9 6 const { t } = useI18n();
... ... @@ -22,6 +19,7 @@ export enum HandlerEnum {
22 19 MENU_THEME,
23 20 MENU_SPLIT,
24 21 MENU_FIXED,
  22 + MENU_CLOSE_MIX_SIDEBAR_ON_CHANGE,
25 23  
26 24 // header
27 25 HEADER_SHOW,
... ... @@ -116,19 +114,21 @@ export const menuTypeList = [
116 114 title: t('layout.setting.menuTypeSidebar'),
117 115 mode: MenuModeEnum.INLINE,
118 116 type: MenuTypeEnum.SIDEBAR,
119   - src: sidebarImg,
120 117 },
121 118 {
122 119 title: t('layout.setting.menuTypeMix'),
123 120 mode: MenuModeEnum.INLINE,
124 121 type: MenuTypeEnum.MIX,
125   - src: mixImg,
126 122 },
127 123  
128 124 {
129 125 title: t('layout.setting.menuTypeTopMenu'),
130 126 mode: MenuModeEnum.HORIZONTAL,
131 127 type: MenuTypeEnum.TOP_MENU,
132   - src: menuTopImg,
  128 + },
  129 + {
  130 + title: t('layout.setting.menuTypeMixSidebar'),
  131 + mode: MenuModeEnum.INLINE,
  132 + type: MenuTypeEnum.MIX_SIDEBAR,
133 133 },
134 134 ];
... ...
src/layouts/default/setting/handler.ts
... ... @@ -48,9 +48,6 @@ export function handler(event: HandlerEnum, value: any): DeepPartial&lt;ProjectConf
48 48 case HandlerEnum.MENU_WIDTH:
49 49 return { menuSetting: { menuWidth: value } };
50 50  
51   - case HandlerEnum.MENU_COLLAPSED_SHOW_TITLE:
52   - return { menuSetting: { collapsedShowTitle: value } };
53   -
54 51 case HandlerEnum.MENU_SHOW_SIDEBAR:
55 52 return { menuSetting: { show: value } };
56 53  
... ... @@ -60,6 +57,8 @@ export function handler(event: HandlerEnum, value: any): DeepPartial&lt;ProjectConf
60 57  
61 58 case HandlerEnum.MENU_SPLIT:
62 59 return { menuSetting: { split: value } };
  60 + case HandlerEnum.MENU_CLOSE_MIX_SIDEBAR_ON_CHANGE:
  61 + return { menuSetting: { closeMixSidebarOnChange: value } };
63 62  
64 63 case HandlerEnum.MENU_FIXED:
65 64 return { menuSetting: { fixed: value } };
... ...
src/layouts/default/sider/LayoutSider.vue
... ... @@ -128,5 +128,55 @@
128 128 });
129 129 </script>
130 130 <style lang="less">
131   - @import './index.less';
  131 + @import (reference) '../../../design/index.less';
  132 + @prefix-cls: ~'@{namespace}-layout-sideBar';
  133 +
  134 + .@{prefix-cls} {
  135 + z-index: @layout-sider-fixed-z-index;
  136 +
  137 + &--fixed {
  138 + position: fixed;
  139 + top: 0;
  140 + left: 0;
  141 + height: 100%;
  142 + }
  143 +
  144 + &--mix {
  145 + top: @header-height;
  146 + height: calc(100% - @header-height);
  147 + }
  148 +
  149 + &.ant-layout-sider-dark {
  150 + background: @sider-dark-bg-color;
  151 +
  152 + .ant-layout-sider-trigger {
  153 + color: darken(@white, 25%);
  154 + background: @trigger-dark-bg-color;
  155 +
  156 + &:hover {
  157 + color: @white;
  158 + background: @trigger-dark-hover-bg-color;
  159 + }
  160 + }
  161 + }
  162 +
  163 + &:not(.ant-layout-sider-dark) {
  164 + // box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05);
  165 +
  166 + .ant-layout-sider-trigger {
  167 + color: @text-color-base;
  168 + border-top: 1px solid @border-color-light;
  169 + }
  170 + }
  171 +
  172 + .ant-layout-sider-zero-width-trigger {
  173 + top: 40%;
  174 + z-index: 10;
  175 + }
  176 +
  177 + & .ant-layout-sider-trigger {
  178 + height: 36px;
  179 + line-height: 36px;
  180 + }
  181 + }
132 182 </style>
... ...
src/layouts/default/sider/MixSider.vue 0 → 100644
  1 +<template>
  2 + <div :class="`${prefixCls}-dom`" />
  3 +
  4 + <div
  5 + v-click-outside="handleClickOutside"
  6 + :class="[
  7 + prefixCls,
  8 + getMenuTheme,
  9 + {
  10 + open: openMenu,
  11 + },
  12 + ]"
  13 + >
  14 + <AppLogo :showTitle="false" :class="`${prefixCls}-logo`" />
  15 + <ScrollContainer>
  16 + <ul :class="`${prefixCls}-module`">
  17 + <li
  18 + :class="[
  19 + `${prefixCls}-module__item `,
  20 + {
  21 + [`${prefixCls}-module__item--active`]: item.path === activePath,
  22 + },
  23 + ]"
  24 + v-for="item in menuModules"
  25 + :key="item.path"
  26 + @click="hanldeModuleClick(item.path)"
  27 + >
  28 + <MenuTag :item="item" :showTitle="false" :isHorizontal="false" />
  29 + <g-icon
  30 + :class="`${prefixCls}-module__icon`"
  31 + :size="22"
  32 + :icon="item.meta && item.meta.icon"
  33 + />
  34 + <p :class="`${prefixCls}-module__name`">{{ t(item.name) }}</p>
  35 + </li>
  36 + </ul>
  37 + </ScrollContainer>
  38 +
  39 + <div :class="`${prefixCls}-menu-list`" ref="sideRef" :style="getMenuStyle">
  40 + <div
  41 + :class="[
  42 + `${prefixCls}-menu-list__title`,
  43 + {
  44 + show: openMenu,
  45 + },
  46 + ]"
  47 + >
  48 + <span class="text"> {{ title }}</span>
  49 + </div>
  50 + <ScrollContainer :class="`${prefixCls}-menu-list__content`">
  51 + <BasicMenu
  52 + :isHorizontal="false"
  53 + mode="inline"
  54 + :items="chilrenMenus"
  55 + :theme="getMenuTheme"
  56 + @menuClick="handleMenuClick"
  57 + />
  58 + </ScrollContainer>
  59 + <div
  60 + v-show="getShowDragBar && openMenu"
  61 + :class="`${prefixCls}-drag-bar`"
  62 + ref="dragBarRef"
  63 + ></div>
  64 + </div>
  65 + </div>
  66 +</template>
  67 +<script lang="ts">
  68 + import { defineComponent, onMounted, ref, computed, CSSProperties, unref } from 'vue';
  69 + import type { Menu } from '/@/router/types';
  70 + import type { RouteLocationNormalized } from 'vue-router';
  71 + import { useDesign } from '/@/hooks/web/useDesign';
  72 + import { getShallowMenus, getChildrenMenus, getCurrentParentPath } from '/@/router/menus';
  73 + import { useI18n } from '/@/hooks/web/useI18n';
  74 + import { ScrollContainer } from '/@/components/Container';
  75 + import { AppLogo } from '/@/components/Application';
  76 + import { useGo } from '/@/hooks/web/usePage';
  77 + import { BasicMenu, MenuTag } from '/@/components/Menu';
  78 + import { listenerLastChangeTab } from '/@/logics/mitt/tabChange';
  79 + import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
  80 + import { useDragLine } from './useLayoutSider';
  81 +
  82 + import clickOutside from '/@/directives/clickOutside';
  83 + import { useGlobSetting } from '/@/hooks/setting';
  84 +
  85 + export default defineComponent({
  86 + name: 'LayoutMixSider',
  87 + components: {
  88 + ScrollContainer,
  89 + AppLogo,
  90 + BasicMenu,
  91 + MenuTag,
  92 + },
  93 + directives: {
  94 + clickOutside,
  95 + },
  96 + setup() {
  97 + let menuModules = ref<Menu[]>([]);
  98 + const activePath = ref('');
  99 + const chilrenMenus = ref<Menu[]>([]);
  100 + const openMenu = ref(false);
  101 + const dragBarRef = ref<ElRef>(null);
  102 + const sideRef = ref<ElRef>(null);
  103 + const currentRoute = ref<Nullable<RouteLocationNormalized>>(null);
  104 +
  105 + const { prefixCls } = useDesign('layout-mix-sider');
  106 + const go = useGo();
  107 + const { t } = useI18n();
  108 + const {
  109 + getMenuWidth,
  110 + getCanDrag,
  111 + getCloseMixSidebarOnChange,
  112 + getMenuTheme,
  113 + getMixSidebarTheme,
  114 + } = useMenuSetting();
  115 + const { title } = useGlobSetting();
  116 +
  117 + useDragLine(sideRef, dragBarRef, true);
  118 +
  119 + const getMenuStyle = computed(
  120 + (): CSSProperties => {
  121 + return {
  122 + width: unref(openMenu) ? `${unref(getMenuWidth)}px` : 0,
  123 + };
  124 + }
  125 + );
  126 +
  127 + const getShowDragBar = computed(() => unref(getCanDrag));
  128 +
  129 + onMounted(async () => {
  130 + menuModules.value = await getShallowMenus();
  131 + });
  132 +
  133 + listenerLastChangeTab((route) => {
  134 + currentRoute.value = route;
  135 + setActive();
  136 + if (unref(getCloseMixSidebarOnChange)) {
  137 + openMenu.value = false;
  138 + }
  139 + });
  140 +
  141 + async function hanldeModuleClick(path: string) {
  142 + const children = await getChildrenMenus(path);
  143 +
  144 + if (unref(activePath) === path) {
  145 + openMenu.value = !unref(openMenu);
  146 + if (!unref(openMenu)) {
  147 + setActive();
  148 + }
  149 + } else {
  150 + openMenu.value = true;
  151 + activePath.value = path;
  152 + }
  153 +
  154 + if (!children || children.length === 0) {
  155 + go(path);
  156 + chilrenMenus.value = [];
  157 + openMenu.value = false;
  158 + return;
  159 + }
  160 + chilrenMenus.value = children;
  161 + }
  162 +
  163 + async function setActive() {
  164 + const path = currentRoute.value?.path;
  165 + if (!path) return;
  166 + const parentPath = await getCurrentParentPath(path);
  167 + activePath.value = parentPath;
  168 + // hanldeModuleClick(parentPath);
  169 + }
  170 +
  171 + function handleMenuClick(path: string) {
  172 + go(path);
  173 + }
  174 +
  175 + function handleClickOutside() {
  176 + openMenu.value = false;
  177 + setActive();
  178 + }
  179 +
  180 + return {
  181 + t,
  182 + prefixCls,
  183 + menuModules,
  184 + hanldeModuleClick,
  185 + activePath,
  186 + chilrenMenus,
  187 + getShowDragBar,
  188 + handleMenuClick,
  189 + getMenuStyle,
  190 + handleClickOutside,
  191 + sideRef,
  192 + dragBarRef,
  193 + title,
  194 + openMenu,
  195 + getMenuTheme,
  196 + getMixSidebarTheme,
  197 + };
  198 + },
  199 + });
  200 +</script>
  201 +<style lang="less">
  202 + @import (reference) '../../../design/index.less';
  203 + @prefix-cls: ~'@{namespace}-layout-mix-sider';
  204 + @tag-prefix-cls: ~'@{namespace}-basic-menu-item-tag';
  205 + @width: 80px;
  206 + .@{prefix-cls} {
  207 + position: fixed;
  208 + top: 0;
  209 + left: 0;
  210 + z-index: @layout-mix-sider-fixed-z-index;
  211 + width: @width;
  212 + height: 100%;
  213 + max-width: @width;
  214 + min-width: @width;
  215 + overflow: hidden;
  216 + background: @sider-dark-bg-color;
  217 + transition: all 0.2s ease 0s;
  218 + flex: 0 0 @width;
  219 + .@{tag-prefix-cls} {
  220 + position: absolute;
  221 + top: 6px;
  222 + right: 2px;
  223 + }
  224 +
  225 + &-dom {
  226 + width: @width;
  227 + height: 100%;
  228 + max-width: @width;
  229 + min-width: @width;
  230 + overflow: hidden;
  231 + transition: all 0.2s ease 0s;
  232 + flex: 0 0 @width;
  233 + }
  234 +
  235 + &-logo {
  236 + display: flex;
  237 + height: @header-height;
  238 + padding-left: 0 !important;
  239 + justify-content: center;
  240 +
  241 + img {
  242 + width: @logo-width;
  243 + height: @logo-width;
  244 + }
  245 + }
  246 +
  247 + &.light {
  248 + .@{prefix-cls}-logo {
  249 + border-bottom: 1px solid rgb(238, 238, 238);
  250 + }
  251 +
  252 + &.open {
  253 + > .scroll-container {
  254 + border-right: 1px solid rgb(238, 238, 238);
  255 + }
  256 + }
  257 +
  258 + .@{prefix-cls}-module {
  259 + &__item {
  260 + font-weight: normal;
  261 + color: rgba(0, 0, 0, 0.65);
  262 +
  263 + &--active {
  264 + color: @primary-color;
  265 + background: unset;
  266 + }
  267 + }
  268 + }
  269 + }
  270 +
  271 + &.dark {
  272 + &.open {
  273 + .@{prefix-cls}-logo {
  274 + border-bottom: 1px solid rgb(114 114 114);
  275 + }
  276 +
  277 + > .scroll-container {
  278 + border-right: 1px solid rgb(114 114 114);
  279 + }
  280 + }
  281 + .@{prefix-cls}-menu-list {
  282 + background: @sider-dark-bg-color;
  283 +
  284 + &__title {
  285 + color: @white;
  286 + border-bottom: none;
  287 + border-bottom: 1px solid rgb(114 114 114);
  288 + }
  289 + }
  290 + }
  291 +
  292 + &-module {
  293 + position: relative;
  294 + height: calc(100% - @header-height) !important;
  295 + padding-top: 1px;
  296 +
  297 + &__item {
  298 + position: relative;
  299 + padding: 12px 0;
  300 + color: rgba(255, 255, 255, 0.65);
  301 + text-align: center;
  302 + cursor: pointer;
  303 + transition: all 0.3s ease;
  304 +
  305 + &:hover {
  306 + color: @white;
  307 + }
  308 + // &:hover,
  309 + &--active {
  310 + font-weight: 700;
  311 + color: @white;
  312 + background: @sider-dark-darken-bg-color;
  313 +
  314 + &::before {
  315 + position: absolute;
  316 + top: 0;
  317 + left: 0;
  318 + width: 3px;
  319 + height: 100%;
  320 + background: @primary-color;
  321 + content: '';
  322 + }
  323 + }
  324 + }
  325 +
  326 + &__icon {
  327 + margin-bottom: 8px;
  328 + font-size: 24px;
  329 + }
  330 +
  331 + &__name {
  332 + margin-bottom: 0;
  333 + font-size: 12px;
  334 + }
  335 + }
  336 +
  337 + &-menu-list {
  338 + position: fixed;
  339 + top: 0;
  340 + left: 80px;
  341 + width: 0;
  342 + width: 200px;
  343 + height: calc(100%);
  344 + background: #fff;
  345 + transition: width 0.2s;
  346 + .@{tag-prefix-cls} {
  347 + position: absolute;
  348 + top: 10px;
  349 + right: 30px;
  350 + }
  351 +
  352 + &__title {
  353 + display: flex;
  354 + height: @header-height;
  355 + margin-left: -6px;
  356 + font-size: 18px;
  357 + color: @primary-color;
  358 + border-bottom: 1px solid rgb(238, 238, 238);
  359 + opacity: 0;
  360 + transition: unset;
  361 + // justify-content: center;
  362 + align-items: center;
  363 + justify-content: start;
  364 +
  365 + &.show {
  366 + opacity: 1;
  367 + transition: all 0.5s ease;
  368 + }
  369 + }
  370 +
  371 + &__content {
  372 + height: calc(100% - @header-height) !important;
  373 +
  374 + .scrollbar__wrap {
  375 + height: 100%;
  376 + overflow-x: hidden;
  377 + }
  378 +
  379 + .scrollbar__bar.is-horizontal {
  380 + display: none;
  381 + }
  382 +
  383 + .ant-menu {
  384 + height: 100%;
  385 + }
  386 +
  387 + .ant-menu-inline,
  388 + .ant-menu-vertical,
  389 + .ant-menu-vertical-left {
  390 + border-right: 1px solid transparent;
  391 + }
  392 + }
  393 + }
  394 +
  395 + &-drag-bar {
  396 + position: absolute;
  397 + top: 0;
  398 + right: -3px;
  399 + width: 3px;
  400 + height: 100%;
  401 + cursor: ew-resize;
  402 + background: #f8f8f9;
  403 + border-top: none;
  404 + border-bottom: none;
  405 + box-shadow: 0 0 4px 0 rgba(28, 36, 56, 0.15);
  406 + }
  407 + }
  408 +</style>
... ...
src/layouts/default/sider/index.less deleted 100644 → 0
1   -@import (reference) '../../../design/index.less';
2   -@prefix-cls: ~'@{namespace}-layout-sideBar';
3   -
4   -.@{prefix-cls} {
5   - z-index: @layout-sider-fixed-z-index;
6   -
7   - &--fixed {
8   - position: fixed;
9   - top: 0;
10   - left: 0;
11   - height: 100%;
12   - }
13   -
14   - &--mix {
15   - top: @header-height;
16   - height: calc(100% - @header-height);
17   - }
18   -
19   - &.ant-layout-sider-dark {
20   - background: @sider-dark-bg-color;
21   -
22   - .ant-layout-sider-trigger {
23   - color: darken(@white, 25%);
24   - background: @trigger-dark-bg-color;
25   -
26   - &:hover {
27   - color: @white;
28   - background: @trigger-dark-hover-bg-color;
29   - }
30   - }
31   - }
32   -
33   - &:not(.ant-layout-sider-dark) {
34   - // box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05);
35   -
36   - .ant-layout-sider-trigger {
37   - color: @text-color-base;
38   - border-top: 1px solid @border-color-light;
39   - }
40   - }
41   -
42   - .ant-layout-sider-zero-width-trigger {
43   - top: 40%;
44   - z-index: 10;
45   - }
46   -
47   - & .ant-layout-sider-trigger {
48   - height: 36px;
49   - line-height: 36px;
50   - }
51   -}
src/layouts/default/sider/index.vue
... ... @@ -10,6 +10,7 @@
10 10 >
11 11 <Sider />
12 12 </Drawer>
  13 + <MixSider v-else-if="getIsMixSidebar" />
13 14 <Sider v-else />
14 15 </template>
15 16 <script lang="ts">
... ... @@ -17,16 +18,17 @@
17 18  
18 19 import Sider from './LayoutSider.vue';
19 20 import { Drawer } from 'ant-design-vue';
  21 + import MixSider from './MixSider.vue';
20 22 import { useAppInject } from '/@/hooks/web/useAppInject';
21 23 import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
22 24 import { useDesign } from '/@/hooks/web/useDesign';
23 25 export default defineComponent({
24 26 name: 'SiderWrapper',
25   - components: { Sider, Drawer },
  27 + components: { Sider, Drawer, MixSider },
26 28 setup() {
27 29 const { prefixCls } = useDesign('layout-sider-wrapper');
28 30 const { getIsMobile } = useAppInject();
29   - const { setMenuSetting, getCollapsed, getMenuWidth } = useMenuSetting();
  31 + const { setMenuSetting, getCollapsed, getMenuWidth, getIsMixSidebar } = useMenuSetting();
30 32  
31 33 function handleClose() {
32 34 setMenuSetting({
... ... @@ -34,7 +36,7 @@
34 36 });
35 37 }
36 38  
37   - return { prefixCls, getIsMobile, getCollapsed, handleClose, getMenuWidth };
  39 + return { prefixCls, getIsMobile, getCollapsed, handleClose, getMenuWidth, getIsMixSidebar };
38 40 },
39 41 });
40 42 </script>
... ...
src/layouts/default/sider/useLayoutSider.ts
... ... @@ -71,21 +71,30 @@ export function useTrigger(getIsMobile: Ref&lt;boolean&gt;) {
71 71 * @param siderRef
72 72 * @param dragBarRef
73 73 */
74   -export function useDragLine(siderRef: Ref<any>, dragBarRef: Ref<any>) {
  74 +export function useDragLine(siderRef: Ref<any>, dragBarRef: Ref<any>, mix = false) {
75 75 const { getMiniWidthNumber, getCollapsed, setMenuSetting } = useMenuSetting();
76 76  
77 77 onMounted(() => {
78 78 nextTick(() => {
79   - const [exec] = useDebounce(changeWrapWidth, 20);
  79 + const [exec] = useDebounce(changeWrapWidth, 80);
80 80 exec();
81 81 });
82 82 });
83 83  
  84 + function getEl(elRef: Ref<ElRef | ComponentRef>): any {
  85 + const el = unref(elRef);
  86 + if (!el) return null;
  87 + if (Reflect.has(el, '$el')) {
  88 + return (unref(elRef) as ComponentRef)?.$el;
  89 + }
  90 + return unref(elRef);
  91 + }
  92 +
84 93 function handleMouseMove(ele: HTMLElement, wrap: HTMLElement, clientX: number) {
85 94 document.onmousemove = function (innerE) {
86 95 let iT = (ele as any).left + (innerE.clientX - clientX);
87 96 innerE = innerE || window.event;
88   - const maxT = 600;
  97 + const maxT = 800;
89 98 const minT = unref(getMiniWidthNumber);
90 99 iT < 0 && (iT = 0);
91 100 iT > maxT && (iT = maxT);
... ... @@ -97,31 +106,36 @@ export function useDragLine(siderRef: Ref&lt;any&gt;, dragBarRef: Ref&lt;any&gt;) {
97 106  
98 107 // Drag and drop in the menu area-release the mouse
99 108 function removeMouseup(ele: any) {
100   - const wrap = unref(siderRef).$el;
  109 + const wrap = getEl(siderRef);
101 110 document.onmouseup = function () {
102 111 document.onmousemove = null;
103 112 document.onmouseup = null;
  113 + wrap.style.transition = 'width 0.2s';
104 114 const width = parseInt(wrap.style.width);
105   - const miniWidth = unref(getMiniWidthNumber);
106 115  
107   - if (!unref(getCollapsed)) {
108   - width > miniWidth + 20
109   - ? setMenuSetting({ menuWidth: width })
110   - : setMenuSetting({ collapsed: true });
  116 + if (!mix) {
  117 + const miniWidth = unref(getMiniWidthNumber);
  118 + if (!unref(getCollapsed)) {
  119 + width > miniWidth + 20
  120 + ? setMenuSetting({ menuWidth: width })
  121 + : setMenuSetting({ collapsed: true });
  122 + } else {
  123 + width > miniWidth && setMenuSetting({ collapsed: false, menuWidth: width });
  124 + }
111 125 } else {
112   - width > miniWidth && setMenuSetting({ collapsed: false, menuWidth: width });
  126 + setMenuSetting({ menuWidth: width });
113 127 }
  128 +
114 129 ele.releaseCapture?.();
115 130 };
116 131 }
117 132  
118 133 function changeWrapWidth() {
119   - const ele = unref(dragBarRef)?.$el;
120   - if (!ele) {
121   - return;
122   - }
123   - const side = unref(siderRef);
124   - const wrap = (side || {}).$el;
  134 + const ele = getEl(dragBarRef);
  135 + if (!ele) return;
  136 + const wrap = getEl(siderRef);
  137 + if (!wrap) return;
  138 +
125 139 ele.onmousedown = (e: any) => {
126 140 wrap.style.transition = 'unset';
127 141 const clientX = e?.clientX;
... ...
src/layouts/page/useCache.ts
... ... @@ -15,7 +15,10 @@ export function useCache(isPage: boolean) {
15 15 if (routeName && ![ParentLayoutName].includes(routeName)) {
16 16 name.value = routeName;
17 17 } else {
18   - const matched = currentRoute.value.matched;
  18 + const matched = currentRoute.value?.matched;
  19 + if (!matched) {
  20 + return;
  21 + }
19 22 const len = matched.length;
20 23 if (len < 2) return;
21 24 name.value = matched[len - 2].name as string;
... ...
src/locales/lang/en/layout/setting.ts
... ... @@ -12,7 +12,8 @@ export default {
12 12 menuTriggerTop: 'Top',
13 13 // menu type
14 14 menuTypeSidebar: 'Left menu mode',
15   - menuTypeMix: 'Mixed mode',
  15 + menuTypeMixSidebar: 'Left menu mixed mode',
  16 + menuTypeMix: 'Top Menu Mix mode',
16 17 menuTypeTopMenu: 'Top menu mode',
17 18  
18 19 on: 'On',
... ... @@ -35,6 +36,7 @@ export default {
35 36 interfaceDisplay: 'Interface display',
36 37 animation: 'Animation',
37 38 splitMenu: 'Split menu',
  39 + closeMixSidebarOnChange: 'Switch page to close menu',
38 40  
39 41 headerTheme: 'Header theme',
40 42 sidebarTheme: 'Menu theme',
... ... @@ -43,7 +45,6 @@ export default {
43 45 menuSearch: 'Menu search',
44 46 menuAccordion: 'Sidebar accordion',
45 47 menuCollapse: 'Collapse menu',
46   - collapseMenuDisplayName: 'Collapse menu display name',
47 48 topMenuLayout: 'Top menu layout',
48 49 menuCollapseButton: 'Menu collapse button',
49 50 contentMode: 'Content area width',
... ...
src/locales/lang/en/routes/demo/comp.ts
... ... @@ -9,6 +9,12 @@ export default {
9 9 scrollAction: 'Scroll Function',
10 10 virtualScroll: 'Virtual Scroll',
11 11  
  12 + tree: 'Tree',
  13 +
  14 + treeBasic: 'Basic',
  15 + editTree: 'Right-click',
  16 + actionTree: 'Function operation',
  17 +
12 18 modal: 'Modal',
13 19 drawer: 'Drawer',
14 20 desc: 'Desc',
... ...
src/locales/lang/en/routes/demo/level.ts
1 1 export default {
2   - level: 'Multi menu cache',
  2 + level: 'MultiMenu',
3 3 };
... ...
src/locales/lang/en/routes/demo/tree.ts deleted 100644 → 0
1   -export default {
2   - tree: 'Tree',
3   -
4   - basic: 'Basic',
5   - editTree: 'Right-click',
6   - actionTree: 'Function operation',
7   -};
src/locales/lang/zh_CN/layout/setting.ts
... ... @@ -12,7 +12,8 @@ export default {
12 12 menuTriggerTop: '顶部',
13 13 // menu type
14 14 menuTypeSidebar: '左侧菜单模式',
15   - menuTypeMix: '混合模式',
  15 + menuTypeMixSidebar: '左侧菜单混合模式',
  16 + menuTypeMix: '顶部菜单混合模式',
16 17 menuTypeTopMenu: '顶部菜单模式',
17 18  
18 19 on: '开',
... ... @@ -34,6 +35,7 @@ export default {
34 35 interfaceDisplay: '界面显示',
35 36 animation: '动画',
36 37 splitMenu: '分割菜单',
  38 + closeMixSidebarOnChange: '切换页面关闭菜单',
37 39  
38 40 headerTheme: '顶栏主题',
39 41 sidebarTheme: '菜单主题',
... ... @@ -42,7 +44,6 @@ export default {
42 44 menuSearch: '菜单搜索',
43 45 menuAccordion: '侧边菜单手风琴模式',
44 46 menuCollapse: '折叠菜单',
45   - collapseMenuDisplayName: '折叠菜单显示名称',
46 47 topMenuLayout: '顶部菜单布局',
47 48 menuCollapseButton: '菜单折叠按钮',
48 49 contentMode: '内容区域宽度',
... ...
src/locales/lang/zh_CN/routes/demo/charts.ts
1 1 export default {
2   - charts: '图表',
  2 + charts: '图表',
3 3 map: '地图',
4 4 line: '折线图',
5 5 pie: '饼图',
... ...
src/locales/lang/zh_CN/routes/demo/comp.ts
... ... @@ -9,6 +9,11 @@ export default {
9 9 scrollAction: '滚动函数',
10 10 virtualScroll: '虚拟滚动',
11 11  
  12 + tree: 'Tree',
  13 + treeBasic: '基础树',
  14 + editTree: '右键示例',
  15 + actionTree: '函数操作示例',
  16 +
12 17 modal: '弹窗扩展',
13 18 drawer: '抽屉扩展',
14 19 desc: '详情组件',
... ...
src/locales/lang/zh_CN/routes/demo/level.ts
1 1 export default {
2   - level: '多级菜单缓存',
  2 + level: '多级菜单',
3 3 };
... ...
src/locales/lang/zh_CN/routes/demo/tree.ts deleted 100644 → 0
1   -export default {
2   - tree: 'Tree',
3   -
4   - basic: '基础树',
5   - editTree: '右键示例',
6   - actionTree: '函数操作示例',
7   -};
src/router/menus/modules/demo/comp.ts
... ... @@ -15,6 +15,107 @@ const menu: MenuModule = {
15 15 name: t('routes.demo.comp.basic'),
16 16 },
17 17 {
  18 + path: 'form',
  19 + name: t('routes.demo.form.form'),
  20 +
  21 + children: [
  22 + {
  23 + path: 'basic',
  24 + name: t('routes.demo.form.basic'),
  25 + },
  26 + {
  27 + path: 'useForm',
  28 + name: t('routes.demo.form.useForm'),
  29 + },
  30 + {
  31 + path: 'refForm',
  32 + name: t('routes.demo.form.refForm'),
  33 + },
  34 + {
  35 + path: 'advancedForm',
  36 + name: t('routes.demo.form.advancedForm'),
  37 + },
  38 + {
  39 + path: 'ruleForm',
  40 + name: t('routes.demo.form.ruleForm'),
  41 + },
  42 + {
  43 + path: 'dynamicForm',
  44 + name: t('routes.demo.form.dynamicForm'),
  45 + },
  46 + {
  47 + path: 'customerForm',
  48 + name: t('routes.demo.form.customerForm'),
  49 + },
  50 + ],
  51 + },
  52 + {
  53 + path: 'table',
  54 + name: t('routes.demo.table.table'),
  55 + children: [
  56 + {
  57 + path: 'basic',
  58 + name: t('routes.demo.table.basic'),
  59 + },
  60 + {
  61 + path: 'treeTable',
  62 + name: t('routes.demo.table.treeTable'),
  63 + },
  64 + {
  65 + path: 'fetchTable',
  66 + name: t('routes.demo.table.fetchTable'),
  67 + },
  68 + {
  69 + path: 'fixedColumn',
  70 + name: t('routes.demo.table.fixedColumn'),
  71 + },
  72 + {
  73 + path: 'customerCell',
  74 + name: t('routes.demo.table.customerCell'),
  75 + },
  76 + {
  77 + path: 'formTable',
  78 + name: t('routes.demo.table.formTable'),
  79 + },
  80 + {
  81 + path: 'useTable',
  82 + name: t('routes.demo.table.useTable'),
  83 + },
  84 + {
  85 + path: 'refTable',
  86 + name: t('routes.demo.table.refTable'),
  87 + },
  88 + {
  89 + path: 'multipleHeader',
  90 + name: t('routes.demo.table.multipleHeader'),
  91 + },
  92 + {
  93 + path: 'mergeHeader',
  94 + name: t('routes.demo.table.mergeHeader'),
  95 + },
  96 + {
  97 + path: 'expandTable',
  98 + name: t('routes.demo.table.expandTable'),
  99 + },
  100 + {
  101 + path: 'fixedHeight',
  102 + name: t('routes.demo.table.fixedHeight'),
  103 + },
  104 + {
  105 + path: 'footerTable',
  106 + name: t('routes.demo.table.footerTable'),
  107 + },
  108 + {
  109 + path: 'editCellTable',
  110 + name: t('routes.demo.table.editCellTable'),
  111 + },
  112 + {
  113 + path: 'editRowTable',
  114 + name: t('routes.demo.table.editRowTable'),
  115 + },
  116 + ],
  117 + },
  118 + {
18 119 path: 'countTo',
19 120 name: t('routes.demo.comp.countTo'),
20 121 },
... ... @@ -55,6 +156,48 @@ const menu: MenuModule = {
55 156 },
56 157 },
57 158 {
  159 + path: 'tree',
  160 + name: t('routes.demo.comp.tree'),
  161 + children: [
  162 + {
  163 + path: 'basic',
  164 + name: t('routes.demo.comp.treeBasic'),
  165 + },
  166 + {
  167 + path: 'editTree',
  168 + name: t('routes.demo.comp.editTree'),
  169 + },
  170 + {
  171 + path: 'actionTree',
  172 + name: t('routes.demo.comp.actionTree'),
  173 + },
  174 + ],
  175 + },
  176 + {
  177 + name: t('routes.demo.editor.editor'),
  178 + path: 'editor',
  179 + children: [
  180 + {
  181 + path: 'markdown',
  182 + name: t('routes.demo.editor.markdown'),
  183 + },
  184 + {
  185 + path: 'tinymce',
  186 + name: t('routes.demo.editor.tinymce'),
  187 + children: [
  188 + {
  189 + path: 'index',
  190 + name: t('routes.demo.editor.tinymceBasic'),
  191 + },
  192 + {
  193 + path: 'editor',
  194 + name: t('routes.demo.editor.tinymceForm'),
  195 + },
  196 + ],
  197 + },
  198 + ],
  199 + },
  200 + {
58 201 path: 'scroll',
59 202 name: t('routes.demo.comp.scroll'),
60 203 children: [
... ...
src/router/menus/modules/demo/editor.ts deleted 100644 → 0
1   -import type { MenuModule } from '/@/router/types.d';
2   -import { t } from '/@/hooks/web/useI18n';
3   -
4   -const menu: MenuModule = {
5   - orderNo: 500,
6   - menu: {
7   - name: t('routes.demo.editor.editor'),
8   - path: '/editor',
9   - children: [
10   - {
11   - path: 'markdown',
12   - name: t('routes.demo.editor.markdown'),
13   - },
14   - {
15   - path: 'tinymce',
16   - name: t('routes.demo.editor.tinymce'),
17   - children: [
18   - {
19   - path: 'index',
20   - name: t('routes.demo.editor.tinymceBasic'),
21   - },
22   - {
23   - path: 'editor',
24   - name: t('routes.demo.editor.tinymceForm'),
25   - },
26   - ],
27   - },
28   - ],
29   - },
30   -};
31   -export default menu;
src/router/menus/modules/demo/feat.ts
... ... @@ -63,6 +63,28 @@ const menu: MenuModule = {
63 63 name: t('routes.demo.feat.errorLog'),
64 64 },
65 65 {
  66 + name: t('routes.demo.excel.excel'),
  67 + path: 'excel',
  68 + children: [
  69 + {
  70 + path: 'customExport',
  71 + name: t('routes.demo.excel.customExport'),
  72 + },
  73 + {
  74 + path: 'jsonExport',
  75 + name: t('routes.demo.excel.jsonExport'),
  76 + },
  77 + {
  78 + path: 'arrayExport',
  79 + name: t('routes.demo.excel.arrayExport'),
  80 + },
  81 + {
  82 + path: 'importExcel',
  83 + name: t('routes.demo.excel.importExcel'),
  84 + },
  85 + ],
  86 + },
  87 + {
66 88 path: 'testTab',
67 89 name: t('routes.demo.feat.tab'),
68 90 children: [
... ...
src/router/menus/modules/demo/form.ts deleted 100644 → 0
1   -import type { MenuModule } from '/@/router/types.d';
2   -import { t } from '/@/hooks/web/useI18n';
3   -
4   -const menu: MenuModule = {
5   - orderNo: 40,
6   - menu: {
7   - path: '/form',
8   - name: t('routes.demo.form.form'),
9   -
10   - children: [
11   - {
12   - path: 'basic',
13   - name: t('routes.demo.form.basic'),
14   - },
15   - {
16   - path: 'useForm',
17   - name: t('routes.demo.form.useForm'),
18   - },
19   - {
20   - path: 'refForm',
21   - name: t('routes.demo.form.refForm'),
22   - },
23   - {
24   - path: 'advancedForm',
25   - name: t('routes.demo.form.advancedForm'),
26   - },
27   - {
28   - path: 'ruleForm',
29   - name: t('routes.demo.form.ruleForm'),
30   - },
31   - {
32   - path: 'dynamicForm',
33   - name: t('routes.demo.form.dynamicForm'),
34   - },
35   - {
36   - path: 'customerForm',
37   - name: t('routes.demo.form.customerForm'),
38   - },
39   - ],
40   - },
41   -};
42   -export default menu;
src/router/menus/modules/demo/table.ts deleted 100644 → 0
1   -import type { MenuModule } from '/@/router/types.d';
2   -import { t } from '/@/hooks/web/useI18n';
3   -
4   -const menu: MenuModule = {
5   - orderNo: 30,
6   - menu: {
7   - path: '/table',
8   - name: t('routes.demo.table.table'),
9   - children: [
10   - {
11   - path: 'basic',
12   - name: t('routes.demo.table.basic'),
13   - },
14   - {
15   - path: 'treeTable',
16   - name: t('routes.demo.table.treeTable'),
17   - },
18   - {
19   - path: 'fetchTable',
20   - name: t('routes.demo.table.fetchTable'),
21   - },
22   - {
23   - path: 'fixedColumn',
24   - name: t('routes.demo.table.fixedColumn'),
25   - },
26   - {
27   - path: 'customerCell',
28   - name: t('routes.demo.table.customerCell'),
29   - },
30   - {
31   - path: 'formTable',
32   - name: t('routes.demo.table.formTable'),
33   - },
34   - {
35   - path: 'useTable',
36   - name: t('routes.demo.table.useTable'),
37   - },
38   - {
39   - path: 'refTable',
40   - name: t('routes.demo.table.refTable'),
41   - },
42   - {
43   - path: 'multipleHeader',
44   - name: t('routes.demo.table.multipleHeader'),
45   - },
46   - {
47   - path: 'mergeHeader',
48   - name: t('routes.demo.table.mergeHeader'),
49   - },
50   - {
51   - path: 'expandTable',
52   - name: t('routes.demo.table.expandTable'),
53   - },
54   - {
55   - path: 'fixedHeight',
56   - name: t('routes.demo.table.fixedHeight'),
57   - },
58   - {
59   - path: 'footerTable',
60   - name: t('routes.demo.table.footerTable'),
61   - },
62   - {
63   - path: 'editCellTable',
64   - name: t('routes.demo.table.editCellTable'),
65   - },
66   - {
67   - path: 'editRowTable',
68   - name: t('routes.demo.table.editRowTable'),
69   - },
70   - ],
71   - },
72   -};
73   -export default menu;
src/router/menus/modules/demo/tree.ts deleted 100644 → 0
1   -import type { MenuModule } from '/@/router/types.d';
2   -import { t } from '/@/hooks/web/useI18n';
3   -
4   -const menu: MenuModule = {
5   - orderNo: 50,
6   - menu: {
7   - path: '/tree',
8   - name: t('routes.demo.tree.tree'),
9   - children: [
10   - {
11   - path: 'basic',
12   - name: t('routes.demo.tree.basic'),
13   - },
14   - {
15   - path: 'editTree',
16   - name: t('routes.demo.tree.editTree'),
17   - },
18   - {
19   - path: 'actionTree',
20   - name: t('routes.demo.tree.actionTree'),
21   - },
22   - ],
23   - },
24   -};
25   -export default menu;
src/router/routes/modules/demo/comp.ts
... ... @@ -22,6 +22,208 @@ const comp: AppRouteModule = {
22 22 title: t('routes.demo.comp.basic'),
23 23 },
24 24 },
  25 +
  26 + {
  27 + path: 'form',
  28 + name: 'FormDemo',
  29 + redirect: '/comp/form/basic',
  30 + component: getParentLayout('FormDemo'),
  31 + meta: {
  32 + // icon: 'mdi:form-select',
  33 + title: t('routes.demo.form.form'),
  34 + },
  35 + children: [
  36 + {
  37 + path: 'basic',
  38 + name: 'FormBasicDemo',
  39 + component: () => import('/@/views/demo/form/index.vue'),
  40 + meta: {
  41 + title: t('routes.demo.form.basic'),
  42 + },
  43 + },
  44 + {
  45 + path: 'useForm',
  46 + name: 'UseFormDemo',
  47 + component: () => import('/@/views/demo/form/UseForm.vue'),
  48 + meta: {
  49 + title: t('routes.demo.form.useForm'),
  50 + },
  51 + },
  52 + {
  53 + path: 'refForm',
  54 + name: 'RefFormDemo',
  55 + component: () => import('/@/views/demo/form/RefForm.vue'),
  56 + meta: {
  57 + title: t('routes.demo.form.refForm'),
  58 + },
  59 + },
  60 + {
  61 + path: 'advancedForm',
  62 + name: 'AdvancedFormDemo',
  63 + component: () => import('/@/views/demo/form/AdvancedForm.vue'),
  64 + meta: {
  65 + title: t('routes.demo.form.advancedForm'),
  66 + },
  67 + },
  68 + {
  69 + path: 'ruleForm',
  70 + name: 'RuleFormDemo',
  71 + component: () => import('/@/views/demo/form/RuleForm.vue'),
  72 + meta: {
  73 + title: t('routes.demo.form.ruleForm'),
  74 + },
  75 + },
  76 + {
  77 + path: 'dynamicForm',
  78 + name: 'DynamicFormDemo',
  79 + component: () => import('/@/views/demo/form/DynamicForm.vue'),
  80 + meta: {
  81 + title: t('routes.demo.form.dynamicForm'),
  82 + },
  83 + },
  84 + {
  85 + path: 'customerForm',
  86 + name: 'CustomerFormDemo',
  87 + component: () => import('/@/views/demo/form/CustomerForm.vue'),
  88 + meta: {
  89 + title: t('routes.demo.form.customerForm'),
  90 + },
  91 + },
  92 + ],
  93 + },
  94 + {
  95 + path: 'table',
  96 + name: 'TableDemo',
  97 + redirect: '/comp/table/basic',
  98 + component: getParentLayout('TableDemo'),
  99 + meta: {
  100 + // icon: 'carbon:table-split',
  101 + title: t('routes.demo.table.table'),
  102 + },
  103 +
  104 + children: [
  105 + {
  106 + path: 'basic',
  107 + name: 'TableBasicDemo',
  108 + component: () => import('/@/views/demo/table/Basic.vue'),
  109 + meta: {
  110 + title: t('routes.demo.table.basic'),
  111 + },
  112 + },
  113 + {
  114 + path: 'treeTable',
  115 + name: 'TreeTableDemo',
  116 + component: () => import('/@/views/demo/table/TreeTable.vue'),
  117 + meta: {
  118 + title: t('routes.demo.table.treeTable'),
  119 + },
  120 + },
  121 + {
  122 + path: 'fetchTable',
  123 + name: 'FetchTableDemo',
  124 + component: () => import('/@/views/demo/table/FetchTable.vue'),
  125 + meta: {
  126 + title: t('routes.demo.table.fetchTable'),
  127 + },
  128 + },
  129 + {
  130 + path: 'fixedColumn',
  131 + name: 'FixedColumnDemo',
  132 + component: () => import('/@/views/demo/table/FixedColumn.vue'),
  133 + meta: {
  134 + title: t('routes.demo.table.fixedColumn'),
  135 + },
  136 + },
  137 + {
  138 + path: 'customerCell',
  139 + name: 'CustomerCellDemo',
  140 + component: () => import('/@/views/demo/table/CustomerCell.vue'),
  141 + meta: {
  142 + title: t('routes.demo.table.customerCell'),
  143 + },
  144 + },
  145 + {
  146 + path: 'formTable',
  147 + name: 'FormTableDemo',
  148 + component: () => import('/@/views/demo/table/FormTable.vue'),
  149 + meta: {
  150 + title: t('routes.demo.table.formTable'),
  151 + },
  152 + },
  153 + {
  154 + path: 'useTable',
  155 + name: 'UseTableDemo',
  156 + component: () => import('/@/views/demo/table/UseTable.vue'),
  157 + meta: {
  158 + title: t('routes.demo.table.useTable'),
  159 + },
  160 + },
  161 + {
  162 + path: 'refTable',
  163 + name: 'RefTableDemo',
  164 + component: () => import('/@/views/demo/table/RefTable.vue'),
  165 + meta: {
  166 + title: t('routes.demo.table.refTable'),
  167 + },
  168 + },
  169 + {
  170 + path: 'multipleHeader',
  171 + name: 'MultipleHeaderDemo',
  172 + component: () => import('/@/views/demo/table/MultipleHeader.vue'),
  173 + meta: {
  174 + title: t('routes.demo.table.multipleHeader'),
  175 + },
  176 + },
  177 + {
  178 + path: 'mergeHeader',
  179 + name: 'MergeHeaderDemo',
  180 + component: () => import('/@/views/demo/table/MergeHeader.vue'),
  181 + meta: {
  182 + title: t('routes.demo.table.mergeHeader'),
  183 + },
  184 + },
  185 + {
  186 + path: 'expandTable',
  187 + name: 'ExpandTableDemo',
  188 + component: () => import('/@/views/demo/table/ExpandTable.vue'),
  189 + meta: {
  190 + title: t('routes.demo.table.expandTable'),
  191 + },
  192 + },
  193 + {
  194 + path: 'fixedHeight',
  195 + name: 'FixedHeightDemo',
  196 + component: () => import('/@/views/demo/table/FixedHeight.vue'),
  197 + meta: {
  198 + title: t('routes.demo.table.fixedHeight'),
  199 + },
  200 + },
  201 + {
  202 + path: 'footerTable',
  203 + name: 'FooterTableDemo',
  204 + component: () => import('/@/views/demo/table/FooterTable.vue'),
  205 + meta: {
  206 + title: t('routes.demo.table.footerTable'),
  207 + },
  208 + },
  209 + {
  210 + path: 'editCellTable',
  211 + name: 'EditCellTableDemo',
  212 + component: () => import('/@/views/demo/table/EditCellTable.vue'),
  213 + meta: {
  214 + title: t('routes.demo.table.editCellTable'),
  215 + },
  216 + },
  217 + {
  218 + path: 'editRowTable',
  219 + name: 'EditRowTableDemo',
  220 + component: () => import('/@/views/demo/table/EditRowTable.vue'),
  221 + meta: {
  222 + title: t('routes.demo.table.editRowTable'),
  223 + },
  224 + },
  225 + ],
  226 + },
25 227 {
26 228 path: 'transition',
27 229 name: 'transitionDemo',
... ... @@ -38,7 +240,89 @@ const comp: AppRouteModule = {
38 240 title: t('routes.demo.comp.countTo'),
39 241 },
40 242 },
41   -
  243 + {
  244 + path: 'tree',
  245 + name: 'TreeDemo',
  246 + redirect: '/comp/tree/basic',
  247 + component: getParentLayout('TreeDemo'),
  248 + meta: {
  249 + // icon: 'clarity:tree-view-line',
  250 + title: t('routes.demo.comp.tree'),
  251 + },
  252 + children: [
  253 + {
  254 + path: 'basic',
  255 + name: 'BasicTreeDemo',
  256 + component: () => import('/@/views/demo/tree/index.vue'),
  257 + meta: {
  258 + title: t('routes.demo.comp.treeBasic'),
  259 + },
  260 + },
  261 + {
  262 + path: 'editTree',
  263 + name: 'EditTreeDemo',
  264 + component: () => import('/@/views/demo/tree/EditTree.vue'),
  265 + meta: {
  266 + title: t('routes.demo.comp.editTree'),
  267 + },
  268 + },
  269 + {
  270 + path: 'actionTree',
  271 + name: 'ActionTreeDemo',
  272 + component: () => import('/@/views/demo/tree/ActionTree.vue'),
  273 + meta: {
  274 + title: t('routes.demo.comp.actionTree'),
  275 + },
  276 + },
  277 + ],
  278 + },
  279 + {
  280 + path: 'editor',
  281 + name: 'EditorDemo',
  282 + redirect: '/comp/editor/markdown',
  283 + component: getParentLayout('EditorDemo'),
  284 + meta: {
  285 + // icon: 'carbon:table-split',
  286 + title: t('routes.demo.editor.editor'),
  287 + },
  288 + children: [
  289 + {
  290 + path: 'markdown',
  291 + name: 'MarkdownDemo',
  292 + component: () => import('/@/views/demo/editor/Markdown.vue'),
  293 + meta: {
  294 + title: t('routes.demo.editor.markdown'),
  295 + },
  296 + },
  297 + {
  298 + path: 'tinymce',
  299 + component: getParentLayout('TinymceDemo'),
  300 + name: 'TinymceDemo',
  301 + meta: {
  302 + title: t('routes.demo.editor.tinymce'),
  303 + },
  304 + redirect: '/comp/editor/tinymce/index',
  305 + children: [
  306 + {
  307 + path: 'index',
  308 + name: 'TinymceBasicDemo',
  309 + component: () => import('/@/views/demo/editor/tinymce/index.vue'),
  310 + meta: {
  311 + title: t('routes.demo.editor.tinymceBasic'),
  312 + },
  313 + },
  314 + {
  315 + path: 'editor',
  316 + name: 'TinymceFormDemo',
  317 + component: () => import('/@/views/demo/editor/tinymce/Editor.vue'),
  318 + meta: {
  319 + title: t('routes.demo.editor.tinymceForm'),
  320 + },
  321 + },
  322 + ],
  323 + },
  324 + ],
  325 + },
42 326 {
43 327 path: 'scroll',
44 328 name: 'ScrollDemo',
... ...
src/router/routes/modules/demo/editor.ts deleted 100644 → 0
1   -import type { AppRouteModule } from '/@/router/types';
2   -
3   -import { getParentLayout, LAYOUT } from '/@/router/constant';
4   -import { t } from '/@/hooks/web/useI18n';
5   -
6   -const editor: AppRouteModule = {
7   - path: '/editor',
8   - name: 'Editor',
9   - component: LAYOUT,
10   - redirect: '/editor/markdown',
11   - meta: {
12   - icon: 'carbon:table-split',
13   - title: t('routes.demo.editor.editor'),
14   - },
15   - children: [
16   - {
17   - path: 'markdown',
18   - name: 'MarkdownDemo',
19   - component: () => import('/@/views/demo/editor/Markdown.vue'),
20   - meta: {
21   - title: t('routes.demo.editor.markdown'),
22   - },
23   - },
24   - {
25   - path: 'tinymce',
26   - component: getParentLayout('TinymceDemo'),
27   - name: 'TinymceDemo',
28   - meta: {
29   - title: t('routes.demo.editor.tinymce'),
30   - },
31   - redirect: '/editor/tinymce/index',
32   - children: [
33   - {
34   - path: 'index',
35   - name: 'TinymceBasicDemo',
36   - component: () => import('/@/views/demo/editor/tinymce/index.vue'),
37   - meta: {
38   - title: t('routes.demo.editor.tinymceBasic'),
39   - },
40   - },
41   - {
42   - path: 'editor',
43   - name: 'TinymceFormDemo',
44   - component: () => import('/@/views/demo/editor/tinymce/Editor.vue'),
45   - meta: {
46   - title: t('routes.demo.editor.tinymceForm'),
47   - },
48   - },
49   - ],
50   - },
51   - ],
52   -};
53   -
54   -export default editor;
src/router/routes/modules/demo/excel.ts deleted 100644 → 0
1   -import type { AppRouteModule } from '/@/router/types';
2   -
3   -import { LAYOUT } from '/@/router/constant';
4   -import { t } from '/@/hooks/web/useI18n';
5   -
6   -const excel: AppRouteModule = {
7   - path: '/excel',
8   - name: 'Excel',
9   - component: LAYOUT,
10   - redirect: '/excel/customExport',
11   - meta: {
12   - icon: 'mdi:microsoft-excel',
13   - title: t('routes.demo.excel.excel'),
14   - },
15   -
16   - children: [
17   - {
18   - path: 'customExport',
19   - name: 'CustomExport',
20   - component: () => import('/@/views/demo/excel/CustomExport.vue'),
21   - meta: {
22   - title: t('routes.demo.excel.customExport'),
23   - },
24   - },
25   - {
26   - path: 'jsonExport',
27   - name: 'JsonExport',
28   - component: () => import('/@/views/demo/excel/JsonExport.vue'),
29   - meta: {
30   - title: t('routes.demo.excel.jsonExport'),
31   - },
32   - },
33   - {
34   - path: 'arrayExport',
35   - name: 'ArrayExport',
36   - component: () => import('/@/views/demo/excel/ArrayExport.vue'),
37   - meta: {
38   - title: t('routes.demo.excel.arrayExport'),
39   - },
40   - },
41   - {
42   - path: 'importExcel',
43   - name: 'ImportExcel',
44   - component: () => import('/@/views/demo/excel/ImportExcel.vue'),
45   - meta: {
46   - title: t('routes.demo.excel.importExcel'),
47   - },
48   - },
49   - ],
50   -};
51   -
52   -export default excel;
src/router/routes/modules/demo/feat.ts
1 1 import type { AppRouteModule } from '/@/router/types';
2 2  
3   -import { LAYOUT } from '/@/router/constant';
  3 +import { getParentLayout, LAYOUT } from '/@/router/constant';
4 4 import { t } from '/@/hooks/web/useI18n';
5 5  
6 6 const feat: AppRouteModule = {
... ... @@ -111,6 +111,51 @@ const feat: AppRouteModule = {
111 111 },
112 112 },
113 113 {
  114 + path: 'excel',
  115 + name: 'Excel',
  116 + redirect: '/feat/excel/customExport',
  117 + component: getParentLayout('Excel'),
  118 + meta: {
  119 + // icon: 'mdi:microsoft-excel',
  120 + title: t('routes.demo.excel.excel'),
  121 + },
  122 +
  123 + children: [
  124 + {
  125 + path: 'customExport',
  126 + name: 'CustomExport',
  127 + component: () => import('/@/views/demo/excel/CustomExport.vue'),
  128 + meta: {
  129 + title: t('routes.demo.excel.customExport'),
  130 + },
  131 + },
  132 + {
  133 + path: 'jsonExport',
  134 + name: 'JsonExport',
  135 + component: () => import('/@/views/demo/excel/JsonExport.vue'),
  136 + meta: {
  137 + title: t('routes.demo.excel.jsonExport'),
  138 + },
  139 + },
  140 + {
  141 + path: 'arrayExport',
  142 + name: 'ArrayExport',
  143 + component: () => import('/@/views/demo/excel/ArrayExport.vue'),
  144 + meta: {
  145 + title: t('routes.demo.excel.arrayExport'),
  146 + },
  147 + },
  148 + {
  149 + path: 'importExcel',
  150 + name: 'ImportExcel',
  151 + component: () => import('/@/views/demo/excel/ImportExcel.vue'),
  152 + meta: {
  153 + title: t('routes.demo.excel.importExcel'),
  154 + },
  155 + },
  156 + ],
  157 + },
  158 + {
114 159 path: 'testTab/:id',
115 160 name: 'TestTab',
116 161 component: () => import('/@/views/demo/feat/tab-params/index.vue'),
... ...
src/router/routes/modules/demo/form.ts deleted 100644 → 0
1   -import type { AppRouteModule } from '/@/router/types';
2   -
3   -import { LAYOUT } from '/@/router/constant';
4   -import { t } from '/@/hooks/web/useI18n';
5   -
6   -const form: AppRouteModule = {
7   - path: '/form',
8   - name: 'FormDemo',
9   - component: LAYOUT,
10   - redirect: '/form/basic',
11   - meta: {
12   - icon: 'mdi:form-select',
13   - title: t('routes.demo.form.form'),
14   - },
15   - children: [
16   - {
17   - path: 'basic',
18   - name: 'FormBasicDemo',
19   - component: () => import('/@/views/demo/form/index.vue'),
20   - meta: {
21   - title: t('routes.demo.form.basic'),
22   - },
23   - },
24   - {
25   - path: 'useForm',
26   - name: 'UseFormDemo',
27   - component: () => import('/@/views/demo/form/UseForm.vue'),
28   - meta: {
29   - title: t('routes.demo.form.useForm'),
30   - },
31   - },
32   - {
33   - path: 'refForm',
34   - name: 'RefFormDemo',
35   - component: () => import('/@/views/demo/form/RefForm.vue'),
36   - meta: {
37   - title: t('routes.demo.form.refForm'),
38   - },
39   - },
40   - {
41   - path: 'advancedForm',
42   - name: 'AdvancedFormDemo',
43   - component: () => import('/@/views/demo/form/AdvancedForm.vue'),
44   - meta: {
45   - title: t('routes.demo.form.advancedForm'),
46   - },
47   - },
48   - {
49   - path: 'ruleForm',
50   - name: 'RuleFormDemo',
51   - component: () => import('/@/views/demo/form/RuleForm.vue'),
52   - meta: {
53   - title: t('routes.demo.form.ruleForm'),
54   - },
55   - },
56   - {
57   - path: 'dynamicForm',
58   - name: 'DynamicFormDemo',
59   - component: () => import('/@/views/demo/form/DynamicForm.vue'),
60   - meta: {
61   - title: t('routes.demo.form.dynamicForm'),
62   - },
63   - },
64   - {
65   - path: 'customerForm',
66   - name: 'CustomerFormDemo',
67   - component: () => import('/@/views/demo/form/CustomerForm.vue'),
68   - meta: {
69   - title: t('routes.demo.form.customerForm'),
70   - },
71   - },
72   - ],
73   -};
74   -export default form;
src/router/routes/modules/demo/table.ts deleted 100644 → 0
1   -import type { AppRouteModule } from '/@/router/types';
2   -
3   -import { LAYOUT } from '/@/router/constant';
4   -import { t } from '/@/hooks/web/useI18n';
5   -
6   -const table: AppRouteModule = {
7   - path: '/table',
8   - name: 'TableDemo',
9   - component: LAYOUT,
10   - redirect: '/table/basic',
11   - meta: {
12   - icon: 'carbon:table-split',
13   - title: t('routes.demo.table.table'),
14   - },
15   -
16   - children: [
17   - {
18   - path: 'basic',
19   - name: 'TableBasicDemo',
20   - component: () => import('/@/views/demo/table/Basic.vue'),
21   - meta: {
22   - title: t('routes.demo.table.basic'),
23   - },
24   - },
25   - {
26   - path: 'treeTable',
27   - name: 'TreeTableDemo',
28   - component: () => import('/@/views/demo/table/TreeTable.vue'),
29   - meta: {
30   - title: t('routes.demo.table.treeTable'),
31   - },
32   - },
33   - {
34   - path: 'fetchTable',
35   - name: 'FetchTableDemo',
36   - component: () => import('/@/views/demo/table/FetchTable.vue'),
37   - meta: {
38   - title: t('routes.demo.table.fetchTable'),
39   - },
40   - },
41   - {
42   - path: 'fixedColumn',
43   - name: 'FixedColumnDemo',
44   - component: () => import('/@/views/demo/table/FixedColumn.vue'),
45   - meta: {
46   - title: t('routes.demo.table.fixedColumn'),
47   - },
48   - },
49   - {
50   - path: 'customerCell',
51   - name: 'CustomerCellDemo',
52   - component: () => import('/@/views/demo/table/CustomerCell.vue'),
53   - meta: {
54   - title: t('routes.demo.table.customerCell'),
55   - },
56   - },
57   - {
58   - path: 'formTable',
59   - name: 'FormTableDemo',
60   - component: () => import('/@/views/demo/table/FormTable.vue'),
61   - meta: {
62   - title: t('routes.demo.table.formTable'),
63   - },
64   - },
65   - {
66   - path: 'useTable',
67   - name: 'UseTableDemo',
68   - component: () => import('/@/views/demo/table/UseTable.vue'),
69   - meta: {
70   - title: t('routes.demo.table.useTable'),
71   - },
72   - },
73   - {
74   - path: 'refTable',
75   - name: 'RefTableDemo',
76   - component: () => import('/@/views/demo/table/RefTable.vue'),
77   - meta: {
78   - title: t('routes.demo.table.refTable'),
79   - },
80   - },
81   - {
82   - path: 'multipleHeader',
83   - name: 'MultipleHeaderDemo',
84   - component: () => import('/@/views/demo/table/MultipleHeader.vue'),
85   - meta: {
86   - title: t('routes.demo.table.multipleHeader'),
87   - },
88   - },
89   - {
90   - path: 'mergeHeader',
91   - name: 'MergeHeaderDemo',
92   - component: () => import('/@/views/demo/table/MergeHeader.vue'),
93   - meta: {
94   - title: t('routes.demo.table.mergeHeader'),
95   - },
96   - },
97   - {
98   - path: 'expandTable',
99   - name: 'ExpandTableDemo',
100   - component: () => import('/@/views/demo/table/ExpandTable.vue'),
101   - meta: {
102   - title: t('routes.demo.table.expandTable'),
103   - },
104   - },
105   - {
106   - path: 'fixedHeight',
107   - name: 'FixedHeightDemo',
108   - component: () => import('/@/views/demo/table/FixedHeight.vue'),
109   - meta: {
110   - title: t('routes.demo.table.fixedHeight'),
111   - },
112   - },
113   - {
114   - path: 'footerTable',
115   - name: 'FooterTableDemo',
116   - component: () => import('/@/views/demo/table/FooterTable.vue'),
117   - meta: {
118   - title: t('routes.demo.table.footerTable'),
119   - },
120   - },
121   - {
122   - path: 'editCellTable',
123   - name: 'EditCellTableDemo',
124   - component: () => import('/@/views/demo/table/EditCellTable.vue'),
125   - meta: {
126   - title: t('routes.demo.table.editCellTable'),
127   - },
128   - },
129   - {
130   - path: 'editRowTable',
131   - name: 'EditRowTableDemo',
132   - component: () => import('/@/views/demo/table/EditRowTable.vue'),
133   - meta: {
134   - title: t('routes.demo.table.editRowTable'),
135   - },
136   - },
137   - ],
138   -};
139   -
140   -export default table;
src/router/routes/modules/demo/tree.ts deleted 100644 → 0
1   -import type { AppRouteModule } from '/@/router/types';
2   -
3   -import { LAYOUT } from '/@/router/constant';
4   -import { t } from '/@/hooks/web/useI18n';
5   -
6   -const tree: AppRouteModule = {
7   - path: '/tree',
8   - name: 'TreeDemo',
9   - component: LAYOUT,
10   - redirect: '/tree/basic',
11   - meta: {
12   - icon: 'clarity:tree-view-line',
13   - title: t('routes.demo.tree.tree'),
14   - },
15   - children: [
16   - {
17   - path: 'basic',
18   - name: 'BasicTreeDemo',
19   - component: () => import('/@/views/demo/tree/index.vue'),
20   - meta: {
21   - title: t('routes.demo.tree.basic'),
22   - },
23   - },
24   - {
25   - path: 'editTree',
26   - name: 'EditTreeDemo',
27   - component: () => import('/@/views/demo/tree/EditTree.vue'),
28   - meta: {
29   - title: t('routes.demo.tree.editTree'),
30   - },
31   - },
32   - {
33   - path: 'actionTree',
34   - name: 'ActionTreeDemo',
35   - component: () => import('/@/views/demo/tree/ActionTree.vue'),
36   - meta: {
37   - title: t('routes.demo.tree.actionTree'),
38   - },
39   - },
40   - ],
41   -};
42   -
43   -export default tree;
src/settings/colorSetting.ts
... ... @@ -11,6 +11,7 @@ export const HEADER_PRESET_BG_COLOR_LIST: string[] = [
11 11 '#24292e',
12 12 '#394664',
13 13 '#001529',
  14 + '#383f45',
14 15 ];
15 16  
16 17 // sider preset color
... ... @@ -24,4 +25,5 @@ export const SIDE_BAR_BG_COLOR_LIST: string[] = [
24 25 '#001628',
25 26 '#28333E',
26 27 '#344058',
  28 + '#383f45',
27 29 ];
... ...
src/settings/projectSetting.ts
... ... @@ -81,11 +81,9 @@ const setting: ProjectConfig = {
81 81 fixed: true,
82 82 // Menu collapse
83 83 collapsed: false,
84   - // Whether to display the menu name when folding the menu
85   - collapsedShowTitle: false,
86 84 // Whether it can be dragged
87 85 // Only limited to the opening of the left menu, the mouse has a drag bar on the right side of the menu
88   - canDrag: false,
  86 + canDrag: true,
89 87 // Whether to show no dom
90 88 show: true,
91 89 // Whether to show dom
... ... @@ -106,6 +104,8 @@ const setting: ProjectConfig = {
106 104 trigger: TriggerEnum.HEADER,
107 105 // Turn on accordion mode, only show a menu
108 106 accordion: true,
  107 + // Switch page to close menu
  108 + closeMixSidebarOnChange: false,
109 109 },
110 110  
111 111 // Multi-label
... ...
src/store/modules/tab.ts
... ... @@ -88,8 +88,9 @@ class Tab extends VuexModule {
88 88 if (item.meta?.affix) {
89 89 const name = item.name as string;
90 90 pageCacheSet.add(name);
91   - } else if (item.matched && needCache) {
92   - const matched = item.matched;
  91 + } else if (item?.matched && needCache) {
  92 + const matched = item?.matched;
  93 + if (!matched) return;
93 94 const len = matched.length;
94 95  
95 96 if (len < 2) return;
... ...
src/types/config.d.ts
... ... @@ -7,7 +7,6 @@ export interface MenuSetting {
7 7 bgColor: string;
8 8 fixed: boolean;
9 9 collapsed: boolean;
10   - collapsedShowTitle: boolean;
11 10 canDrag: boolean;
12 11 show: boolean;
13 12 hidden: boolean;
... ... @@ -19,6 +18,7 @@ export interface MenuSetting {
19 18 topMenuAlign: 'start' | 'center' | 'end';
20 19 trigger: TriggerEnum;
21 20 accordion: boolean;
  21 + closeMixSidebarOnChange: boolean;
22 22 }
23 23  
24 24 export interface MultiTabsSetting {
... ... @@ -109,6 +109,7 @@ export interface ProjectConfig {
109 109 // pageLayout是否开启keep-alive
110 110 openKeepAlive: boolean;
111 111  
  112 + //
112 113 // 锁屏时间
113 114 lockTime: number;
114 115 // 显示面包屑
... ...
src/utils/factory/createAsyncComponent.tsx
... ... @@ -34,7 +34,9 @@ export function createAsyncComponent(loader: Fn, options: Options = {}) {
34 34 loadingComponent: loading ? <Spin spinning={true} size={size} /> : undefined,
35 35 // The error component will be displayed if a timeout is
36 36 // provided and exceeded. Default: Infinity.
  37 + // TODO
37 38 timeout,
  39 + // errorComponent
38 40 // Defining if component is suspensible. Default: true.
39 41 // suspensible: false,
40 42 delay,
... ...
yarn.lock
... ... @@ -1041,53 +1041,58 @@
1041 1041 resolved "https://registry.npmjs.org/@iconify/iconify/-/iconify-2.0.0-rc.1.tgz#a8bae29d71016d5af98c69f56a73c4a040217b3a"
1042 1042 integrity sha512-ji5H04VjYtR4seIEgVVLPxg1KRhrFquOiyfPyLVS6vYPkuqV6bcWdssi05YSmf/OAzG4E7Qsg80/bOKyd5tYTw==
1043 1043  
1044   -"@iconify/iconify@>=2.0.0-rc.1", "@iconify/iconify@^2.0.0-rc.2":
  1044 +"@iconify/iconify@>=2.0.0-rc.1":
1045 1045 version "2.0.0-rc.2"
1046 1046 resolved "https://registry.npmjs.org/@iconify/iconify/-/iconify-2.0.0-rc.2.tgz#c4a95ddc06ca9b9496df03604e66fdefb39f4c4b"
1047 1047 integrity sha512-BybEHU5/I9EQ0CcwKAqmreZ2bMnAXrqLCTptAc6vPetHMbrXdZfejP5mt57e/8PNSt/qE7BHniU5PCYA+PGIHw==
1048 1048  
1049   -"@iconify/json@^1.1.272":
1050   - version "1.1.272"
1051   - resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.272.tgz#27c7caee9764e0304161261ec08ffc2794944b66"
1052   - integrity sha512-FyiTc7UiXJ5cDfk09lv70sYOSi5uLyK+a0LnF1KgWmofkikL06p98ksNRN7stmHryOYarSy75xgi6MbgAwtltQ==
1053   -
1054   -"@intlify/core-base@9.0.0-beta.13":
1055   - version "9.0.0-beta.13"
1056   - resolved "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.0.0-beta.13.tgz#fb6bc278209cb7bef44853a42160fedb0560c3f8"
1057   - integrity sha512-ukImWV+QvRmNZtCTLrSW391z46eMuBheCMPZh801nM3v0Dosfu2PtWO5/z8Q9Bsom4Q+PNQ5eBtOQj2yCAhVEA==
1058   - dependencies:
1059   - "@intlify/message-compiler" "9.0.0-beta.13"
1060   - "@intlify/message-resolver" "9.0.0-beta.13"
1061   - "@intlify/runtime" "9.0.0-beta.13"
1062   - "@intlify/shared" "9.0.0-beta.13"
1063   -
1064   -"@intlify/message-compiler@9.0.0-beta.13":
1065   - version "9.0.0-beta.13"
1066   - resolved "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.0.0-beta.13.tgz#3b8ddcb2be3f80b28c6e4f6028c0b3ec4e709849"
1067   - integrity sha512-1z7716InFM8FdTAz64wqZvFuT4wL7WKF63v+vUEW4s9FLoL0U+xIccor9P5XHAvvG1gPMH/Zxd0deg/ULZ1Mcg==
1068   - dependencies:
1069   - "@intlify/message-resolver" "9.0.0-beta.13"
1070   - "@intlify/shared" "9.0.0-beta.13"
  1049 +"@iconify/iconify@^2.0.0-rc.4":
  1050 + version "2.0.0-rc.4"
  1051 + resolved "https://registry.npmjs.org/@iconify/iconify/-/iconify-2.0.0-rc.4.tgz#46098fb544a4eb3af724219e4955c9022801835e"
  1052 + integrity sha512-YCSECbeXKFJEIVkKgKMjUzJ439ysufmL/a31B1j7dCvnHaBWsX9J4XehhJgg/aTy3yvhHaVhI6xt1kSMZP799A==
  1053 +
  1054 +"@iconify/json@^1.1.275":
  1055 + version "1.1.275"
  1056 + resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.275.tgz#ac9a706cdc7c9e64ab8e8bb09ae770f551f7496f"
  1057 + integrity sha512-Nt6tXJpZFd/gFRV24BvmlIdxnbMxgshIKFPQwOWgeVjKiOKEwiBKjXUzBE74As7/Olps/ac1gEB40N9/DGOJ3Q==
  1058 +
  1059 +"@intlify/core-base@9.0.0-beta.14":
  1060 + version "9.0.0-beta.14"
  1061 + resolved "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.0.0-beta.14.tgz#b190d1dd95d28977b26353c77121d2d84d15b7ee"
  1062 + integrity sha512-ZX+JJvBtcdVZxrTg8oO6flXC965aURIvAeDOYT3DqlUWekHKQ2hUVc1J8SP7rzEgFUqDqCMrDMtv2gZNvxD2Aw==
  1063 + dependencies:
  1064 + "@intlify/message-compiler" "9.0.0-beta.14"
  1065 + "@intlify/message-resolver" "9.0.0-beta.14"
  1066 + "@intlify/runtime" "9.0.0-beta.14"
  1067 + "@intlify/shared" "9.0.0-beta.14"
  1068 +
  1069 +"@intlify/message-compiler@9.0.0-beta.14":
  1070 + version "9.0.0-beta.14"
  1071 + resolved "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.0.0-beta.14.tgz#4b5a4467459c402e71652075e9d95e5d85e85588"
  1072 + integrity sha512-fXgiQuLKsYINnzhnCQD3OJnT2/59HrPw8WWiG8MpuMSDcUkUXV4ie0DW+9x48QQqpel7TU11Lage3zuFxw27iQ==
  1073 + dependencies:
  1074 + "@intlify/message-resolver" "9.0.0-beta.14"
  1075 + "@intlify/shared" "9.0.0-beta.14"
1071 1076 source-map "0.6.1"
1072 1077  
1073   -"@intlify/message-resolver@9.0.0-beta.13":
1074   - version "9.0.0-beta.13"
1075   - resolved "https://registry.npmjs.org/@intlify/message-resolver/-/message-resolver-9.0.0-beta.13.tgz#ae6de0bf0e54093160442d465e719bf03fd0f146"
1076   - integrity sha512-mR1eSpRtB4jh11TpQTUyzjEwqZ6D30mJYREEfSrl5YKfUKwDQrulrOaIO8T5gVQG2m09vfxJHVrgfJ2hR8z/0Q==
  1078 +"@intlify/message-resolver@9.0.0-beta.14":
  1079 + version "9.0.0-beta.14"
  1080 + resolved "https://registry.npmjs.org/@intlify/message-resolver/-/message-resolver-9.0.0-beta.14.tgz#f964706650d71ef06669c17c29cb60500ef2617a"
  1081 + integrity sha512-/PPLMHX0w/ECkG+Fmne8L3WVVVwAp3tpdisf5G775b49Fspy4dKXqkLXM2NZKhdguJbXWHXXXiRkr+mlhq8G9Q==
1077 1082  
1078   -"@intlify/runtime@9.0.0-beta.13":
1079   - version "9.0.0-beta.13"
1080   - resolved "https://registry.npmjs.org/@intlify/runtime/-/runtime-9.0.0-beta.13.tgz#8deff103ee6982c6d531314e9f965b90768d8a27"
1081   - integrity sha512-hcb3sg75SokuzNDG8IC6PJmwjsS/xdgevd99UNG1zKb7s5qFFb90ApvPDpiH0+R9TMQe11fZqg5dyrVBKqAV4A==
  1083 +"@intlify/runtime@9.0.0-beta.14":
  1084 + version "9.0.0-beta.14"
  1085 + resolved "https://registry.npmjs.org/@intlify/runtime/-/runtime-9.0.0-beta.14.tgz#367f6b09c991c71905b73224e238aa8382976b2d"
  1086 + integrity sha512-WgFnXkniJIMrZfW1kcxejQ96te56r3us632/WME7SL1IYsGV+WErXiJMBrHf8ngwAy15WmfYoKWr32sRxWjCtw==
1082 1087 dependencies:
1083   - "@intlify/message-compiler" "9.0.0-beta.13"
1084   - "@intlify/message-resolver" "9.0.0-beta.13"
1085   - "@intlify/shared" "9.0.0-beta.13"
  1088 + "@intlify/message-compiler" "9.0.0-beta.14"
  1089 + "@intlify/message-resolver" "9.0.0-beta.14"
  1090 + "@intlify/shared" "9.0.0-beta.14"
1086 1091  
1087   -"@intlify/shared@9.0.0-beta.13":
1088   - version "9.0.0-beta.13"
1089   - resolved "https://registry.npmjs.org/@intlify/shared/-/shared-9.0.0-beta.13.tgz#2d93d695f19fd699ea8b336066f9d6dfc185f094"
1090   - integrity sha512-/rqC3YEGHs3uu3XSsF1zdBKJb+on34Yn8Z58K3YxJsFxKPHa8mH73EUtN79hTZWh6Js4zEa/WsCgZCM62b8eJA==
  1092 +"@intlify/shared@9.0.0-beta.14":
  1093 + version "9.0.0-beta.14"
  1094 + resolved "https://registry.npmjs.org/@intlify/shared/-/shared-9.0.0-beta.14.tgz#c221a45f666a40935f998d2e3c14451a516b9f56"
  1095 + integrity sha512-f+Gev5GnrNLyieJCB6sB/qqe03XaMf6yJiAXG3IamZ4mp45oj2Lw9Oj3hAepDW36VUZK2wCIDmWy53pxJNIFpQ==
1091 1096  
1092 1097 "@koa/cors@^3.1.0":
1093 1098 version "3.1.0"
... ... @@ -1558,10 +1563,10 @@
1558 1563 resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d"
1559 1564 integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==
1560 1565  
1561   -"@types/yargs@^15.0.11":
1562   - version "15.0.11"
1563   - resolved "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.11.tgz#361d7579ecdac1527687bcebf9946621c12ab78c"
1564   - integrity sha512-jfcNBxHFYJ4nPIacsi3woz1+kvUO6s1CyeEhtnDHBjHUMNj5UlW2GynmnSgiJJEdNg9yW5C8lfoNRZrHGv5EqA==
  1566 +"@types/yargs@^15.0.12":
  1567 + version "15.0.12"
  1568 + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.12.tgz#6234ce3e3e3fa32c5db301a170f96a599c960d74"
  1569 + integrity sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw==
1565 1570 dependencies:
1566 1571 "@types/yargs-parser" "*"
1567 1572  
... ... @@ -1575,61 +1580,61 @@
1575 1580 resolved "https://registry.npmjs.org/@types/zxcvbn/-/zxcvbn-4.4.0.tgz#fbc1d941cc6d9d37d18405c513ba6b294f89b609"
1576 1581 integrity sha512-GQLOT+SN20a+AI51y3fAimhyTF4Y0RG+YP3gf91OibIZ7CJmPFgoZi+ZR5a+vRbS01LbQosITWum4ATmJ1Z6Pg==
1577 1582  
1578   -"@typescript-eslint/eslint-plugin@^4.10.0":
1579   - version "4.10.0"
1580   - resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.10.0.tgz#19ed3baf4bc4232c5a7fcd32eaca75c3a5baf9f3"
1581   - integrity sha512-h6/V46o6aXpKRlarP1AiJEXuCJ7cMQdlpfMDrcllIgX3dFkLwEBTXAoNP98ZoOmqd1xvymMVRAI4e7yVvlzWEg==
  1583 +"@typescript-eslint/eslint-plugin@^4.11.0":
  1584 + version "4.11.0"
  1585 + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.11.0.tgz#bc6c1e4175c0cf42083da4314f7931ad12f731cc"
  1586 + integrity sha512-x4arJMXBxyD6aBXLm3W7mSDZRiABzy+2PCLJbL7OPqlp53VXhaA1HKK7R2rTee5OlRhnUgnp8lZyVIqjnyPT6g==
1582 1587 dependencies:
1583   - "@typescript-eslint/experimental-utils" "4.10.0"
1584   - "@typescript-eslint/scope-manager" "4.10.0"
  1588 + "@typescript-eslint/experimental-utils" "4.11.0"
  1589 + "@typescript-eslint/scope-manager" "4.11.0"
1585 1590 debug "^4.1.1"
1586 1591 functional-red-black-tree "^1.0.1"
1587 1592 regexpp "^3.0.0"
1588 1593 semver "^7.3.2"
1589 1594 tsutils "^3.17.1"
1590 1595  
1591   -"@typescript-eslint/experimental-utils@4.10.0":
1592   - version "4.10.0"
1593   - resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.10.0.tgz#dbf5d0f89802d5feaf7d11e5b32df29bbc2f3a0e"
1594   - integrity sha512-opX+7ai1sdWBOIoBgpVJrH5e89ra1KoLrJTz0UtWAa4IekkKmqDosk5r6xqRaNJfCXEfteW4HXQAwMdx+jjEmw==
  1596 +"@typescript-eslint/experimental-utils@4.11.0":
  1597 + version "4.11.0"
  1598 + resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.11.0.tgz#d1a47cc6cfe1c080ce4ead79267574b9881a1565"
  1599 + integrity sha512-1VC6mSbYwl1FguKt8OgPs8xxaJgtqFpjY/UzUYDBKq4pfQ5lBvN2WVeqYkzf7evW42axUHYl2jm9tNyFsb8oLg==
1595 1600 dependencies:
1596 1601 "@types/json-schema" "^7.0.3"
1597   - "@typescript-eslint/scope-manager" "4.10.0"
1598   - "@typescript-eslint/types" "4.10.0"
1599   - "@typescript-eslint/typescript-estree" "4.10.0"
  1602 + "@typescript-eslint/scope-manager" "4.11.0"
  1603 + "@typescript-eslint/types" "4.11.0"
  1604 + "@typescript-eslint/typescript-estree" "4.11.0"
1600 1605 eslint-scope "^5.0.0"
1601 1606 eslint-utils "^2.0.0"
1602 1607  
1603   -"@typescript-eslint/parser@^4.10.0":
1604   - version "4.10.0"
1605   - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.10.0.tgz#1a622b0847b765b2d8f0ede6f0cdd85f03d76031"
1606   - integrity sha512-amBvUUGBMadzCW6c/qaZmfr3t9PyevcSWw7hY2FuevdZVp5QPw/K76VSQ5Sw3BxlgYCHZcK6DjIhSZK0PQNsQg==
  1608 +"@typescript-eslint/parser@^4.11.0":
  1609 + version "4.11.0"
  1610 + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.11.0.tgz#1dd3d7e42708c10ce9f3aa64c63c0ab99868b4e2"
  1611 + integrity sha512-NBTtKCC7ZtuxEV5CrHUO4Pg2s784pvavc3cnz6V+oJvVbK4tH9135f/RBP6eUA2KHiFKAollSrgSctQGmHbqJQ==
1607 1612 dependencies:
1608   - "@typescript-eslint/scope-manager" "4.10.0"
1609   - "@typescript-eslint/types" "4.10.0"
1610   - "@typescript-eslint/typescript-estree" "4.10.0"
  1613 + "@typescript-eslint/scope-manager" "4.11.0"
  1614 + "@typescript-eslint/types" "4.11.0"
  1615 + "@typescript-eslint/typescript-estree" "4.11.0"
1611 1616 debug "^4.1.1"
1612 1617  
1613   -"@typescript-eslint/scope-manager@4.10.0":
1614   - version "4.10.0"
1615   - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.10.0.tgz#dbd7e1fc63d7363e3aaff742a6f2b8afdbac9d27"
1616   - integrity sha512-WAPVw35P+fcnOa8DEic0tQUhoJJsgt+g6DEcz257G7vHFMwmag58EfowdVbiNcdfcV27EFR0tUBVXkDoIvfisQ==
  1618 +"@typescript-eslint/scope-manager@4.11.0":
  1619 + version "4.11.0"
  1620 + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.11.0.tgz#2d906537db8a3a946721699e4fc0833810490254"
  1621 + integrity sha512-6VSTm/4vC2dHM3ySDW9Kl48en+yLNfVV6LECU8jodBHQOhO8adAVizaZ1fV0QGZnLQjQ/y0aBj5/KXPp2hBTjA==
1617 1622 dependencies:
1618   - "@typescript-eslint/types" "4.10.0"
1619   - "@typescript-eslint/visitor-keys" "4.10.0"
  1623 + "@typescript-eslint/types" "4.11.0"
  1624 + "@typescript-eslint/visitor-keys" "4.11.0"
1620 1625  
1621   -"@typescript-eslint/types@4.10.0":
1622   - version "4.10.0"
1623   - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.10.0.tgz#12f983750ebad867f0c806e705c1953cd6415789"
1624   - integrity sha512-+dt5w1+Lqyd7wIPMa4XhJxUuE8+YF+vxQ6zxHyhLGHJjHiunPf0wSV8LtQwkpmAsRi1lEOoOIR30FG5S2HS33g==
  1626 +"@typescript-eslint/types@4.11.0":
  1627 + version "4.11.0"
  1628 + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.11.0.tgz#86cf95e7eac4ccfd183f9fcf1480cece7caf4ca4"
  1629 + integrity sha512-XXOdt/NPX++txOQHM1kUMgJUS43KSlXGdR/aDyEwuAEETwuPt02Nc7v+s57PzuSqMbNLclblQdv3YcWOdXhQ7g==
1625 1630  
1626   -"@typescript-eslint/typescript-estree@4.10.0":
1627   - version "4.10.0"
1628   - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.10.0.tgz#1e62e45fd57866afd42daf5e9fb6bd4e8dbcfa75"
1629   - integrity sha512-mGK0YRp9TOk6ZqZ98F++bW6X5kMTzCRROJkGXH62d2azhghmq+1LNLylkGe6uGUOQzD452NOAEth5VAF6PDo5g==
  1631 +"@typescript-eslint/typescript-estree@4.11.0":
  1632 + version "4.11.0"
  1633 + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.11.0.tgz#1144d145841e5987d61c4c845442a24b24165a4b"
  1634 + integrity sha512-eA6sT5dE5RHAFhtcC+b5WDlUIGwnO9b0yrfGa1mIOIAjqwSQCpXbLiFmKTdRbQN/xH2EZkGqqLDrKUuYOZ0+Hg==
1630 1635 dependencies:
1631   - "@typescript-eslint/types" "4.10.0"
1632   - "@typescript-eslint/visitor-keys" "4.10.0"
  1636 + "@typescript-eslint/types" "4.11.0"
  1637 + "@typescript-eslint/visitor-keys" "4.11.0"
1633 1638 debug "^4.1.1"
1634 1639 globby "^11.0.1"
1635 1640 is-glob "^4.0.1"
... ... @@ -1637,12 +1642,12 @@
1637 1642 semver "^7.3.2"
1638 1643 tsutils "^3.17.1"
1639 1644  
1640   -"@typescript-eslint/visitor-keys@4.10.0":
1641   - version "4.10.0"
1642   - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.10.0.tgz#9478822329a9bc8ebcc80623d7f79a01da5ee451"
1643   - integrity sha512-hPyz5qmDMuZWFtHZkjcCpkAKHX8vdu1G3YsCLEd25ryZgnJfj6FQuJ5/O7R+dB1ueszilJmAFMtlU4CA6se3Jg==
  1645 +"@typescript-eslint/visitor-keys@4.11.0":
  1646 + version "4.11.0"
  1647 + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.11.0.tgz#906669a50f06aa744378bb84c7d5c4fdbc5b7d51"
  1648 + integrity sha512-tRYKyY0i7cMk6v4UIOCjl1LhuepC/pc6adQqJk4Is3YcC6k46HvsV9Wl7vQoLbm9qADgeujiT7KdLrylvFIQ+A==
1644 1649 dependencies:
1645   - "@typescript-eslint/types" "4.10.0"
  1650 + "@typescript-eslint/types" "4.11.0"
1646 1651 eslint-visitor-keys "^2.0.0"
1647 1652  
1648 1653 "@vue/compiler-core@*", "@vue/compiler-core@3.0.4", "@vue/compiler-core@^3.0.0-rc.5":
... ... @@ -1800,18 +1805,18 @@
1800 1805 vscode-languageserver-textdocument "^1.0.1"
1801 1806 vscode-uri "^2.1.2"
1802 1807  
1803   -"@vueuse/core@^4.0.0-rc.9":
1804   - version "4.0.0-rc.9"
1805   - resolved "https://registry.npmjs.org/@vueuse/core/-/core-4.0.0-rc.9.tgz#5e5f6029704ddc8f851286389ebf7faadf7073d5"
1806   - integrity sha512-h/6qJ523kT9qASaX7ZgJKdrnubpuTmzFg+RIi1XL/Z/Uj9OpCCru1ORc8VPmFy6TfOcE4j/8Q9ZDmXJV3IfcIQ==
  1808 +"@vueuse/core@^4.0.0":
  1809 + version "4.0.0"
  1810 + resolved "https://registry.npmjs.org/@vueuse/core/-/core-4.0.0.tgz#5bea3eaa848e3b3e00427f5053fb98e7e4834b0f"
  1811 + integrity sha512-BBkqriC2j9SH/LuHCggS2MP7VSwBfGkTB9qQh1lzadodk2TnM1JHwM76f3G0hCGqqhEF7ab8Xs+1M1PlvuEQYA==
1807 1812 dependencies:
1808   - "@vueuse/shared" "4.0.0-rc.9"
  1813 + "@vueuse/shared" "4.0.0"
1809 1814 vue-demi latest
1810 1815  
1811   -"@vueuse/shared@4.0.0-rc.9":
1812   - version "4.0.0-rc.9"
1813   - resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-4.0.0-rc.9.tgz#a54ddff35ad6f2d595e21163ddaa064ace9d7220"
1814   - integrity sha512-JeEbKhE5TxMJZzfQt7GWyjY/RALr+orQJsoS0bKgtH0OG0L+iId3AOOuMkeBXsKWg6Q7wrtAYGLeM12SViD/NQ==
  1816 +"@vueuse/shared@4.0.0":
  1817 + version "4.0.0"
  1818 + resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-4.0.0.tgz#d495b8fd2f28a453ef0fccae175ca848a4a84bb0"
  1819 + integrity sha512-8tn1BpnaMJU2LqFyFzzN6Dvmc1uDsSlb3Neli5bwwb9f+rcASpuOS3nAWAY6/rIODZP1iwXDNCL4rNFR3YxYtQ==
1815 1820 dependencies:
1816 1821 vue-demi latest
1817 1822  
... ... @@ -1869,7 +1874,7 @@ aggregate-error@^3.0.0:
1869 1874 clean-stack "^2.0.0"
1870 1875 indent-string "^4.0.0"
1871 1876  
1872   -ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4:
  1877 +ajv@^6.10.0, ajv@^6.12.4:
1873 1878 version "6.12.6"
1874 1879 resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
1875 1880 integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
... ... @@ -1972,10 +1977,10 @@ anymatch@~3.1.1:
1972 1977 normalize-path "^3.0.0"
1973 1978 picomatch "^2.0.4"
1974 1979  
1975   -apexcharts@^3.22.3:
1976   - version "3.22.3"
1977   - resolved "https://registry.npmjs.org/apexcharts/-/apexcharts-3.22.3.tgz#a829c4500db8478069b80e227741830b77d89467"
1978   - integrity sha512-ZRZWmAmSdyc+tFhHMZ10ZxbvSbomWe46izpi8yQj5cKLxuujw2XeXVQ0jxnPl9yE5Q7W2hAbDWStaouBN4mSuw==
  1980 +apexcharts@^3.23.0:
  1981 + version "3.23.0"
  1982 + resolved "https://registry.npmjs.org/apexcharts/-/apexcharts-3.23.0.tgz#12877aa789d658aef5eb930af6c3b8850fefd925"
  1983 + integrity sha512-1mV6qouuopvYR6UFSXi/Ge4jRMe//zyAN3aK05mAs4Iuet8mA0w31Q6OU6syD77bawt9p3YKNOmNF7OO2u9w0g==
1979 1984 dependencies:
1980 1985 svg.draggable.js "^2.2.2"
1981 1986 svg.easing.js "^2.0.0"
... ... @@ -2046,11 +2051,6 @@ assign-symbols@^1.0.0:
2046 2051 resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
2047 2052 integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=
2048 2053  
2049   -astral-regex@^1.0.0:
2050   - version "1.0.0"
2051   - resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
2052   - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
2053   -
2054 2054 astral-regex@^2.0.0:
2055 2055 version "2.0.0"
2056 2056 resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
... ... @@ -2918,6 +2918,13 @@ cookies@~0.8.0:
2918 2918 depd "~2.0.0"
2919 2919 keygrip "~1.1.0"
2920 2920  
  2921 +copy-anything@^2.0.1:
  2922 + version "2.0.1"
  2923 + resolved "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.1.tgz#2afbce6da684bdfcbec93752fa762819cb480d9a"
  2924 + integrity sha512-lA57e7viQHOdPQcrytv5jFeudZZOXuyk47lZym279FiDQ8jeZomXiGuVf6ffMKkJ+3TIai3J1J3yi6M+/4U35g==
  2925 + dependencies:
  2926 + is-what "^3.7.1"
  2927 +
2921 2928 copy-descriptor@^0.1.0:
2922 2929 version "0.1.1"
2923 2930 resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
... ... @@ -3432,10 +3439,10 @@ escape-string-regexp@^1.0.5:
3432 3439 resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
3433 3440 integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
3434 3441  
3435   -eslint-config-prettier@^7.0.0:
3436   - version "7.0.0"
3437   - resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.0.0.tgz#c1ae4106f74e6c0357f44adb076771d032ac0e97"
3438   - integrity sha512-8Y8lGLVPPZdaNA7JXqnvETVC7IiVRgAP6afQu9gOQRn90YY3otMNh+x7Vr2vMePQntF+5erdSUBqSzCmU/AxaQ==
  3442 +eslint-config-prettier@^7.1.0:
  3443 + version "7.1.0"
  3444 + resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.1.0.tgz#5402eb559aa94b894effd6bddfa0b1ca051c858f"
  3445 + integrity sha512-9sm5/PxaFG7qNJvJzTROMM1Bk1ozXVTKI0buKOyb0Bsr1hrwi0H/TzxF/COtf1uxikIK8SwhX7K6zg78jAzbeA==
3439 3446  
3440 3447 eslint-plugin-prettier@^3.3.0:
3441 3448 version "3.3.0"
... ... @@ -3444,15 +3451,15 @@ eslint-plugin-prettier@^3.3.0:
3444 3451 dependencies:
3445 3452 prettier-linter-helpers "^1.0.0"
3446 3453  
3447   -eslint-plugin-vue@^7.2.0:
3448   - version "7.2.0"
3449   - resolved "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.2.0.tgz#dd8323fe7ca28fe9377ce3f5f6cf17afe2686f2a"
3450   - integrity sha512-4mt0yIv6rBDNtvis/g22a0ozJ12GfcdEzX77u0ICYjKlxOVtGrKGEvo0cbOObHaKDg9a9kJcoaNodqE4TPfS2A==
  3454 +eslint-plugin-vue@^7.3.0:
  3455 + version "7.3.0"
  3456 + resolved "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.3.0.tgz#0faf0fcf0e1b1052bf800d4dee42d64f50679cb0"
  3457 + integrity sha512-4rc9xrZgwT4aLz3XE6lrHu+FZtDLWennYvtzVvvS81kW9c65U4DUzQQWAFjDCgCFvN6HYWxi7ueEtxZVSB+f0g==
3451 3458 dependencies:
3452 3459 eslint-utils "^2.1.0"
3453 3460 natural-compare "^1.4.0"
3454 3461 semver "^7.3.2"
3455   - vue-eslint-parser "^7.2.0"
  3462 + vue-eslint-parser "^7.3.0"
3456 3463  
3457 3464 eslint-scope@^5.0.0, eslint-scope@^5.1.1:
3458 3465 version "5.1.1"
... ... @@ -3479,10 +3486,10 @@ eslint-visitor-keys@^2.0.0:
3479 3486 resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
3480 3487 integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
3481 3488  
3482   -eslint@^7.15.0:
3483   - version "7.15.0"
3484   - resolved "https://registry.npmjs.org/eslint/-/eslint-7.15.0.tgz#eb155fb8ed0865fcf5d903f76be2e5b6cd7e0bc7"
3485   - integrity sha512-Vr64xFDT8w30wFll643e7cGrIkPEU50yIiI36OdSIDoSGguIeaLzBo0vpGvzo9RECUqq7htURfwEtKqwytkqzA==
  3489 +eslint@^7.16.0:
  3490 + version "7.16.0"
  3491 + resolved "https://registry.npmjs.org/eslint/-/eslint-7.16.0.tgz#a761605bf9a7b32d24bb7cde59aeb0fd76f06092"
  3492 + integrity sha512-iVWPS785RuDA4dWuhhgXTNrGxHHK3a8HLSMBgbbU59ruJDubUraXN8N5rn7kb8tG6sjg74eE0RA3YWT51eusEw==
3486 3493 dependencies:
3487 3494 "@babel/code-frame" "^7.0.0"
3488 3495 "@eslint/eslintrc" "^0.2.2"
... ... @@ -3518,7 +3525,7 @@ eslint@^7.15.0:
3518 3525 semver "^7.2.1"
3519 3526 strip-ansi "^6.0.0"
3520 3527 strip-json-comments "^3.1.0"
3521   - table "^5.2.3"
  3528 + table "^6.0.4"
3522 3529 text-table "^0.2.0"
3523 3530 v8-compile-cache "^2.0.3"
3524 3531  
... ... @@ -4788,6 +4795,11 @@ is-utf8@^0.2.0, is-utf8@^0.2.1:
4788 4795 resolved "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
4789 4796 integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=
4790 4797  
  4798 +is-what@^3.7.1:
  4799 + version "3.12.0"
  4800 + resolved "https://registry.npmjs.org/is-what/-/is-what-3.12.0.tgz#f4405ce4bd6dd420d3ced51a026fb90e03705e55"
  4801 + integrity sha512-2ilQz5/f/o9V7WRWJQmpFYNmQFZ9iM+OXRonZKcYgTkCzjb949Vi4h282PD1UfmgHk666rcWonbRJ++KI41VGw==
  4802 +
4791 4803 is-windows@^1.0.1, is-windows@^1.0.2:
4792 4804 version "1.0.2"
4793 4805 resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
... ... @@ -5091,11 +5103,13 @@ koa@^2.13.0:
5091 5103 type-is "^1.6.16"
5092 5104 vary "^1.1.2"
5093 5105  
5094   -less@^3.13.0:
5095   - version "3.13.0"
5096   - resolved "https://registry.npmjs.org/less/-/less-3.13.0.tgz#6a47bb19d97edcf7a53d444b099275dd6b17c85a"
5097   - integrity sha512-uPhr9uoSGVKKYVGz0rXcYBK1zjwcIWRGcbnSgNt66XuIZYrYPaQiS+LeUOvqedBwrwdBYYaLqSff5ytGYuT7rA==
  5106 +less@^4.0.0:
  5107 + version "4.0.0"
  5108 + resolved "https://registry.npmjs.org/less/-/less-4.0.0.tgz#d238cc25576c1f722794dbca4ac82e5e3c7e9e65"
  5109 + integrity sha512-av1eEa2D0xZfF7fjLJS/Dld7zAYSLU7EOEJvuOELeaNI3i6L/81AdjbK5/pytaRkBwi7ZEa0433IDvMLskKCOw==
5098 5110 dependencies:
  5111 + copy-anything "^2.0.1"
  5112 + parse-node-version "^1.0.1"
5099 5113 tslib "^1.10.0"
5100 5114 optionalDependencies:
5101 5115 errno "^0.1.1"
... ... @@ -5219,6 +5233,11 @@ lodash-es@^4.17.15:
5219 5233 resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78"
5220 5234 integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ==
5221 5235  
  5236 +lodash-es@^4.17.20:
  5237 + version "4.17.20"
  5238 + resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.20.tgz#29f6332eefc60e849f869c264bc71126ad61e8f7"
  5239 + integrity sha512-JD1COMZsq8maT6mnuz1UMV0jvYD0E0aUsSOdrr1/nAG3dhqQXwRRgeW0cSqH1U43INKcqxaiVIQNOUDld7gRDA==
  5240 +
5222 5241 lodash._reinterpolate@^3.0.0:
5223 5242 version "3.0.0"
5224 5243 resolved "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
... ... @@ -6036,6 +6055,11 @@ parse-json@^5.0.0:
6036 6055 json-parse-even-better-errors "^2.3.0"
6037 6056 lines-and-columns "^1.1.6"
6038 6057  
  6058 +parse-node-version@^1.0.1:
  6059 + version "1.0.1"
  6060 + resolved "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b"
  6061 + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==
  6062 +
6039 6063 parse-passwd@^1.0.0:
6040 6064 version "1.0.0"
6041 6065 resolved "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
... ... @@ -7141,15 +7165,6 @@ slash@^3.0.0:
7141 7165 resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
7142 7166 integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
7143 7167  
7144   -slice-ansi@^2.1.0:
7145   - version "2.1.0"
7146   - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636"
7147   - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==
7148   - dependencies:
7149   - ansi-styles "^3.2.0"
7150   - astral-regex "^1.0.0"
7151   - is-fullwidth-code-point "^2.0.0"
7152   -
7153 7168 slice-ansi@^3.0.0:
7154 7169 version "3.0.0"
7155 7170 resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787"
... ... @@ -7648,17 +7663,7 @@ svg.select.js@^3.0.1:
7648 7663 dependencies:
7649 7664 svg.js "^2.6.5"
7650 7665  
7651   -table@^5.2.3:
7652   - version "5.4.6"
7653   - resolved "https://registry.npmjs.org/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e"
7654   - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==
7655   - dependencies:
7656   - ajv "^6.10.2"
7657   - lodash "^4.17.14"
7658   - slice-ansi "^2.1.0"
7659   - string-width "^3.0.0"
7660   -
7661   -table@^6.0.3:
  7666 +table@^6.0.3, table@^6.0.4:
7662 7667 version "6.0.4"
7663 7668 resolved "https://registry.npmjs.org/table/-/table-6.0.4.tgz#c523dd182177e926c723eb20e1b341238188aa0d"
7664 7669 integrity sha512-sBT4xRLdALd+NFBvwOz8bw4b15htyythha+q+DVZqy2RS08PPC8O2sZFgJYEY7bJvbCFKccs+WIZ/cd+xxTWCw==
... ... @@ -8090,10 +8095,10 @@ vary@^1.1.2:
8090 8095 resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
8091 8096 integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
8092 8097  
8093   -vditor@^3.7.2:
8094   - version "3.7.2"
8095   - resolved "https://registry.npmjs.org/vditor/-/vditor-3.7.2.tgz#d1308fa34a7457a89384f5667be53f05c6a3eec6"
8096   - integrity sha512-CtDba2Jr/op+/E7aRKBoOY8rl8SMkkTdQHxuAbZzb7qv044BXadJIhiBLVv84UHhHaTgsDb/SWMklyoinxegAw==
  8098 +vditor@^3.7.3:
  8099 + version "3.7.3"
  8100 + resolved "https://registry.npmjs.org/vditor/-/vditor-3.7.3.tgz#6f7bdee7dca758985b29be1533ed952178f0aac4"
  8101 + integrity sha512-2EHwAc9l+HOo6dcScSJDPmVTsVuEqHK2ucZwAHgvctpua3pMz/CAGMHgPoyB5X1Pju7yrLfsESHZh8V6Ndh6rg==
8097 8102 dependencies:
8098 8103 diff-match-patch "^1.0.5"
8099 8104  
... ... @@ -8232,18 +8237,6 @@ vue-demi@latest:
8232 8237 resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.4.5.tgz#ea422a4468cb6321a746826a368a770607f87791"
8233 8238 integrity sha512-51xf1B6hV2PfjnzYHO/yUForFCRQ49KS8ngQb5T6l1HDEmfghTFtsxtRa5tbx4eqQsH76ll/0gIxuf1gei0ubw==
8234 8239  
8235   -vue-eslint-parser@^7.2.0:
8236   - version "7.2.0"
8237   - resolved "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.2.0.tgz#1e17ae94ca71e617025e05143c8ac5593aacb6ef"
8238   - integrity sha512-uVcQqe8sUNzdHGcRHMd2Z/hl6qEaWrAmglTKP92Fnq9TYU9un8xsyFgEdFJaXh/1rd7h8Aic1GaiQow5nVneow==
8239   - dependencies:
8240   - debug "^4.1.1"
8241   - eslint-scope "^5.0.0"
8242   - eslint-visitor-keys "^1.1.0"
8243   - espree "^6.2.1"
8244   - esquery "^1.0.1"
8245   - lodash "^4.17.15"
8246   -
8247 8240 vue-eslint-parser@^7.3.0:
8248 8241 version "7.3.0"
8249 8242 resolved "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.3.0.tgz#894085839d99d81296fa081d19643733f23d7559"
... ... @@ -8256,13 +8249,13 @@ vue-eslint-parser@^7.3.0:
8256 8249 esquery "^1.0.1"
8257 8250 lodash "^4.17.15"
8258 8251  
8259   -vue-i18n@^9.0.0-beta.13:
8260   - version "9.0.0-beta.13"
8261   - resolved "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.0.0-beta.13.tgz#89cf5dd1566025f441132231d15ed621ef70ba96"
8262   - integrity sha512-ZN6r5ITODu9NYAAbe1IGVUkNeamuleaXTLn5NMn/YZQ+5NSjDjysyVZVLkVOEOIw6bT2tLveyjsWlAZBVtfcPw==
  8252 +vue-i18n@9.0.0-beta.14:
  8253 + version "9.0.0-beta.14"
  8254 + resolved "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.0.0-beta.14.tgz#2b2b89bc5371263d499bd17e3c0696bb9582c4f9"
  8255 + integrity sha512-jPFtBXcRLuGc4YrI97JJuvj70BndqOhpQNJNthAIPC5x8eJIno44NkK/P769nqQWkbsnYO1sNwb+6oCO6QhaxA==
8263 8256 dependencies:
8264   - "@intlify/core-base" "9.0.0-beta.13"
8265   - "@intlify/shared" "9.0.0-beta.13"
  8257 + "@intlify/core-base" "9.0.0-beta.14"
  8258 + "@intlify/shared" "9.0.0-beta.14"
8266 8259 "@vue/devtools-api" "^6.0.0-beta.2"
8267 8260  
8268 8261 vue-router@^4.0.1:
... ...