Commit 215d8bab380728164d7fe2958c2d2d1151fce892
1 parent
700306bb
refactor: refactor store
Showing
80 changed files
with
1546 additions
and
1497 deletions
build/generate/generateModifyVars.ts
... | ... | @@ -28,6 +28,7 @@ export function generateModifyVars(dark = false) { |
28 | 28 | 'success-color': '#55D187', // Success color |
29 | 29 | 'error-color': '#ED6F6F', // False color |
30 | 30 | 'warning-color': '#EFBD47', // Warning color |
31 | + 'border-color-base': '#EEEEEE', | |
31 | 32 | 'font-size-base': '14px', // Main font size |
32 | 33 | 'border-radius-base': '2px', // Component/float fillet |
33 | 34 | 'link-color': primary, // Link color | ... | ... |
index.html
... | ... | @@ -16,9 +16,11 @@ |
16 | 16 | <script> |
17 | 17 | (() => { |
18 | 18 | var htmlRoot = document.getElementById('htmlRoot'); |
19 | - const theme = window.localStorage.getItem('__APP__DARK__MODE__'); | |
20 | - if (!htmlRoot || !theme) return; | |
21 | - htmlRoot.setAttribute('data-theme', theme); | |
19 | + var theme = window.localStorage.getItem('__APP__DARK__MODE__'); | |
20 | + if (htmlRoot && theme) { | |
21 | + htmlRoot.setAttribute('data-theme', theme); | |
22 | + theme = htmlRoot = null; | |
23 | + } | |
22 | 24 | })(); |
23 | 25 | </script> |
24 | 26 | <div id="app"> | ... | ... |
package.json
... | ... | @@ -32,7 +32,7 @@ |
32 | 32 | }, |
33 | 33 | "dependencies": { |
34 | 34 | "@iconify/iconify": "^2.0.0-rc.6", |
35 | - "@vueuse/core": "^4.8.0", | |
35 | + "@vueuse/core": "^4.8.1", | |
36 | 36 | "@zxcvbn-ts/core": "^0.3.0", |
37 | 37 | "ant-design-vue": "^2.1.2", |
38 | 38 | "axios": "^0.21.1", |
... | ... | @@ -43,6 +43,7 @@ |
43 | 43 | "mockjs": "^1.1.0", |
44 | 44 | "nprogress": "^0.2.0", |
45 | 45 | "path-to-regexp": "^6.2.0", |
46 | + "pinia": "^2.0.0-alpha.12", | |
46 | 47 | "print-js": "^1.6.0", |
47 | 48 | "qrcode": "^1.4.4", |
48 | 49 | "sortablejs": "^1.13.0", |
... | ... | @@ -52,8 +53,6 @@ |
52 | 53 | "vue-i18n": "9.0.0", |
53 | 54 | "vue-router": "^4.0.6", |
54 | 55 | "vue-types": "^3.0.2", |
55 | - "vuex": "^4.0.0", | |
56 | - "vuex-module-decorators": "^1.0.1", | |
57 | 56 | "xlsx": "^0.16.9" |
58 | 57 | }, |
59 | 58 | "devDependencies": { |
... | ... | @@ -81,7 +80,7 @@ |
81 | 80 | "conventional-changelog-cli": "^2.1.1", |
82 | 81 | "cross-env": "^7.0.3", |
83 | 82 | "dotenv": "^8.2.0", |
84 | - "eslint": "^7.23.0", | |
83 | + "eslint": "^7.24.0", | |
85 | 84 | "eslint-config-prettier": "^8.1.0", |
86 | 85 | "eslint-define-config": "^1.0.7", |
87 | 86 | "eslint-plugin-prettier": "^3.3.1", |
... | ... | @@ -115,13 +114,14 @@ |
115 | 114 | "vite-plugin-style-import": "^0.9.2", |
116 | 115 | "vite-plugin-svg-icons": "^0.4.1", |
117 | 116 | "vite-plugin-theme": "^0.6.3", |
118 | - "vite-plugin-windicss": "0.12.5", | |
117 | + "vite-plugin-windicss": "0.13.1", | |
119 | 118 | "vue-eslint-parser": "^7.6.0" |
120 | 119 | }, |
121 | 120 | "resolutions": { |
122 | 121 | "//": "Used to install imagemin dependencies, because imagemin may not be installed in China.If it is abroad, you can delete it", |
123 | 122 | "bin-wrapper": "npm:bin-wrapper-china", |
124 | - "rollup": "^2.44.0" | |
123 | + "rollup": "^2.45.1", | |
124 | + "esbuild": "^0.11.6" | |
125 | 125 | }, |
126 | 126 | "repository": { |
127 | 127 | "type": "git", | ... | ... |
src/components/Application/src/AppProvider.vue
... | ... | @@ -3,22 +3,24 @@ |
3 | 3 | |
4 | 4 | import { createAppProviderContext } from './useAppContext'; |
5 | 5 | |
6 | - import designSetting from '/@/settings/designSetting'; | |
6 | + import { prefixCls } from '/@/settings/designSetting'; | |
7 | 7 | import { createBreakpointListen } from '/@/hooks/event/useBreakpoint'; |
8 | 8 | import { propTypes } from '/@/utils/propTypes'; |
9 | - import { appStore } from '/@/store/modules/app'; | |
9 | + import { useAppStore } from '/@/store/modules/app'; | |
10 | 10 | import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum'; |
11 | 11 | |
12 | 12 | export default defineComponent({ |
13 | 13 | name: 'AppProvider', |
14 | 14 | inheritAttrs: false, |
15 | 15 | props: { |
16 | - prefixCls: propTypes.string.def(designSetting.prefixCls), | |
16 | + prefixCls: propTypes.string.def(prefixCls), | |
17 | 17 | }, |
18 | 18 | setup(props, { slots }) { |
19 | 19 | const isMobile = ref(false); |
20 | 20 | const isSetState = ref(false); |
21 | 21 | |
22 | + const appStore = useAppStore(); | |
23 | + | |
22 | 24 | createBreakpointListen(({ screenMap, sizeEnum, width }) => { |
23 | 25 | const lgWidth = screenMap.get(sizeEnum.LG); |
24 | 26 | if (lgWidth) { |
... | ... | @@ -42,20 +44,20 @@ |
42 | 44 | split: menuSplit, |
43 | 45 | }, |
44 | 46 | } = appStore.getProjectConfig; |
45 | - appStore.commitProjectConfigState({ | |
47 | + appStore.setProjectConfig({ | |
46 | 48 | menuSetting: { |
47 | 49 | type: MenuTypeEnum.SIDEBAR, |
48 | 50 | mode: MenuModeEnum.INLINE, |
49 | 51 | split: false, |
50 | 52 | }, |
51 | 53 | }); |
52 | - appStore.commitBeforeMiniState({ menuMode, menuCollapsed, menuType, menuSplit }); | |
54 | + appStore.setBeforeMiniInfo({ menuMode, menuCollapsed, menuType, menuSplit }); | |
53 | 55 | } |
54 | 56 | } else { |
55 | 57 | if (unref(isSetState)) { |
56 | 58 | isSetState.value = false; |
57 | - const { menuMode, menuCollapsed, menuType, menuSplit } = appStore.getBeforeMiniState; | |
58 | - appStore.commitProjectConfigState({ | |
59 | + const { menuMode, menuCollapsed, menuType, menuSplit } = appStore.getBeforeMiniInfo; | |
60 | + appStore.setProjectConfig({ | |
59 | 61 | menuSetting: { |
60 | 62 | type: menuType, |
61 | 63 | mode: menuMode, | ... | ... |
src/components/Application/src/search/AppSearchKeyItem.vue
1 | 1 | <template> |
2 | 2 | <span :class="$attrs.class"> |
3 | - <Icon :icon="icon" /> | |
3 | + <g-icon :icon="icon" /> | |
4 | 4 | </span> |
5 | 5 | </template> |
6 | 6 | <script lang="ts"> |
7 | 7 | import { defineComponent } from 'vue'; |
8 | - import { Icon } from '/@/components/Icon'; | |
9 | - import { propTypes } from '/@/utils/propTypes'; | |
10 | - | |
11 | 8 | export default defineComponent({ |
12 | - components: { Icon }, | |
13 | 9 | props: { |
14 | - icon: propTypes.string, | |
10 | + icon: String, | |
15 | 11 | }, |
16 | 12 | }); |
17 | 13 | </script> | ... | ... |
src/components/SimpleMenu/src/SimpleMenu.vue
... | ... | @@ -6,7 +6,6 @@ |
6 | 6 | :class="prefixCls" |
7 | 7 | :activeSubMenuNames="activeSubMenuNames" |
8 | 8 | @select="handleSelect" |
9 | - @open-change="handleOpenChange" | |
10 | 9 | > |
11 | 10 | <template v-for="item in items" :key="item.path"> |
12 | 11 | <SimpleSubMenu |
... | ... | @@ -140,17 +139,11 @@ |
140 | 139 | menuState.activeName = key; |
141 | 140 | } |
142 | 141 | |
143 | - function handleOpenChange(v) { | |
144 | - console.log('======================'); | |
145 | - console.log(v); | |
146 | - console.log('======================'); | |
147 | - } | |
148 | 142 | return { |
149 | 143 | prefixCls, |
150 | 144 | getBindValues, |
151 | 145 | handleSelect, |
152 | 146 | getOpenKeys, |
153 | - handleOpenChange, | |
154 | 147 | ...toRefs(menuState), |
155 | 148 | }; |
156 | 149 | }, | ... | ... |
src/hooks/setting/useHeaderSetting.ts
... | ... | @@ -2,94 +2,89 @@ import type { HeaderSetting } from '/#/config'; |
2 | 2 | |
3 | 3 | import { computed, unref } from 'vue'; |
4 | 4 | |
5 | -import { appStore } from '/@/store/modules/app'; | |
5 | +import { useAppStore } from '/@/store/modules/app'; | |
6 | 6 | |
7 | 7 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
8 | 8 | import { useRootSetting } from '/@/hooks/setting/useRootSetting'; |
9 | 9 | import { useFullContent } from '/@/hooks/web/useFullContent'; |
10 | - | |
11 | 10 | import { MenuModeEnum } from '/@/enums/menuEnum'; |
12 | 11 | |
13 | -const { getFullContent } = useFullContent(); | |
14 | -const { | |
15 | - getMenuMode, | |
16 | - getSplit, | |
17 | - getShowHeaderTrigger, | |
18 | - getIsSidebarType, | |
19 | - getIsMixSidebar, | |
20 | - getIsTopMenu, | |
21 | -} = useMenuSetting(); | |
22 | -const { getShowBreadCrumb, getShowLogo } = useRootSetting(); | |
23 | - | |
24 | -const getShowMixHeaderRef = computed(() => !unref(getIsSidebarType) && unref(getShowHeader)); | |
12 | +export function useHeaderSetting() { | |
13 | + const { getFullContent } = useFullContent(); | |
14 | + const appStore = useAppStore(); | |
25 | 15 | |
26 | -const getShowFullHeaderRef = computed(() => { | |
27 | - return ( | |
28 | - !unref(getFullContent) && | |
29 | - unref(getShowMixHeaderRef) && | |
30 | - unref(getShowHeader) && | |
31 | - !unref(getIsTopMenu) && | |
32 | - !unref(getIsMixSidebar) | |
33 | - ); | |
34 | -}); | |
16 | + const getShowFullHeaderRef = computed(() => { | |
17 | + return ( | |
18 | + !unref(getFullContent) && | |
19 | + unref(getShowMixHeaderRef) && | |
20 | + unref(getShowHeader) && | |
21 | + !unref(getIsTopMenu) && | |
22 | + !unref(getIsMixSidebar) | |
23 | + ); | |
24 | + }); | |
35 | 25 | |
36 | -const getShowInsetHeaderRef = computed(() => { | |
37 | - const need = !unref(getFullContent) && unref(getShowHeader); | |
38 | - return ( | |
39 | - (need && !unref(getShowMixHeaderRef)) || | |
40 | - (need && unref(getIsTopMenu)) || | |
41 | - (need && unref(getIsMixSidebar)) | |
42 | - ); | |
43 | -}); | |
26 | + const getUnFixedAndFull = computed(() => !unref(getFixed) && !unref(getShowFullHeaderRef)); | |
44 | 27 | |
45 | -// Get header configuration | |
46 | -const getHeaderSetting = computed(() => appStore.getProjectConfig.headerSetting); | |
28 | + const getShowInsetHeaderRef = computed(() => { | |
29 | + const need = !unref(getFullContent) && unref(getShowHeader); | |
30 | + return ( | |
31 | + (need && !unref(getShowMixHeaderRef)) || | |
32 | + (need && unref(getIsTopMenu)) || | |
33 | + (need && unref(getIsMixSidebar)) | |
34 | + ); | |
35 | + }); | |
47 | 36 | |
48 | -const getShowDoc = computed(() => unref(getHeaderSetting).showDoc); | |
37 | + const { | |
38 | + getMenuMode, | |
39 | + getSplit, | |
40 | + getShowHeaderTrigger, | |
41 | + getIsSidebarType, | |
42 | + getIsMixSidebar, | |
43 | + getIsTopMenu, | |
44 | + } = useMenuSetting(); | |
45 | + const { getShowBreadCrumb, getShowLogo } = useRootSetting(); | |
49 | 46 | |
50 | -const getHeaderTheme = computed(() => unref(getHeaderSetting).theme); | |
47 | + const getShowMixHeaderRef = computed(() => !unref(getIsSidebarType) && unref(getShowHeader)); | |
51 | 48 | |
52 | -const getShowHeader = computed(() => unref(getHeaderSetting).show); | |
49 | + const getShowDoc = computed(() => appStore.getHeaderSetting.showDoc); | |
53 | 50 | |
54 | -const getFixed = computed(() => unref(getHeaderSetting).fixed); | |
51 | + const getHeaderTheme = computed(() => appStore.getHeaderSetting.theme); | |
55 | 52 | |
56 | -const getHeaderBgColor = computed(() => unref(getHeaderSetting).bgColor); | |
53 | + const getShowHeader = computed(() => appStore.getHeaderSetting.show); | |
57 | 54 | |
58 | -const getShowSearch = computed(() => unref(getHeaderSetting).showSearch); | |
55 | + const getFixed = computed(() => appStore.getHeaderSetting.fixed); | |
59 | 56 | |
60 | -const getUseLockPage = computed(() => unref(getHeaderSetting).useLockPage); | |
57 | + const getHeaderBgColor = computed(() => appStore.getHeaderSetting.bgColor); | |
61 | 58 | |
62 | -const getShowFullScreen = computed(() => unref(getHeaderSetting).showFullScreen); | |
59 | + const getShowSearch = computed(() => appStore.getHeaderSetting.showSearch); | |
63 | 60 | |
64 | -const getShowNotice = computed(() => unref(getHeaderSetting).showNotice); | |
61 | + const getUseLockPage = computed(() => appStore.getHeaderSetting.useLockPage); | |
65 | 62 | |
66 | -const getUnFixedAndFull = computed(() => !unref(getFixed) && !unref(getShowFullHeaderRef)); | |
63 | + const getShowFullScreen = computed(() => appStore.getHeaderSetting.showFullScreen); | |
67 | 64 | |
68 | -const getShowBread = computed(() => { | |
69 | - return ( | |
70 | - unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && unref(getShowBreadCrumb) && !unref(getSplit) | |
71 | - ); | |
72 | -}); | |
65 | + const getShowNotice = computed(() => appStore.getHeaderSetting.showNotice); | |
73 | 66 | |
74 | -const getShowHeaderLogo = computed(() => { | |
75 | - return unref(getShowLogo) && !unref(getIsSidebarType) && !unref(getIsMixSidebar); | |
76 | -}); | |
67 | + const getShowBread = computed(() => { | |
68 | + return ( | |
69 | + unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && unref(getShowBreadCrumb) && !unref(getSplit) | |
70 | + ); | |
71 | + }); | |
77 | 72 | |
78 | -const getShowContent = computed(() => { | |
79 | - return unref(getShowBread) || unref(getShowHeaderTrigger); | |
80 | -}); | |
73 | + const getShowHeaderLogo = computed(() => { | |
74 | + return unref(getShowLogo) && !unref(getIsSidebarType) && !unref(getIsMixSidebar); | |
75 | + }); | |
81 | 76 | |
82 | -// Set header configuration | |
83 | -function setHeaderSetting(headerSetting: Partial<HeaderSetting>): void { | |
84 | - appStore.commitProjectConfigState({ headerSetting }); | |
85 | -} | |
77 | + const getShowContent = computed(() => { | |
78 | + return unref(getShowBread) || unref(getShowHeaderTrigger); | |
79 | + }); | |
86 | 80 | |
87 | -export function useHeaderSetting() { | |
81 | + // Set header configuration | |
82 | + function setHeaderSetting(headerSetting: Partial<HeaderSetting>) { | |
83 | + appStore.setProjectConfig({ headerSetting }); | |
84 | + } | |
88 | 85 | return { |
89 | 86 | setHeaderSetting, |
90 | 87 | |
91 | - getHeaderSetting, | |
92 | - | |
93 | 88 | getShowDoc, |
94 | 89 | getShowSearch, |
95 | 90 | getHeaderTheme, | ... | ... |
src/hooks/setting/useMenuSetting.ts
... | ... | @@ -2,7 +2,7 @@ import type { MenuSetting } from '/#/config'; |
2 | 2 | |
3 | 3 | import { computed, unref, ref } from 'vue'; |
4 | 4 | |
5 | -import { appStore } from '/@/store/modules/app'; | |
5 | +import { useAppStore } from '/@/store/modules/app'; | |
6 | 6 | |
7 | 7 | import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum'; |
8 | 8 | import { MenuModeEnum, MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum'; |
... | ... | @@ -10,127 +10,129 @@ import { useFullContent } from '/@/hooks/web/useFullContent'; |
10 | 10 | |
11 | 11 | const mixSideHasChildren = ref(false); |
12 | 12 | |
13 | -// Get menu configuration | |
14 | -const getMenuSetting = computed(() => appStore.getProjectConfig.menuSetting); | |
13 | +export function useMenuSetting() { | |
14 | + const { getFullContent: fullContent } = useFullContent(); | |
15 | + const appStore = useAppStore(); | |
16 | + | |
17 | + const getShowSidebar = computed(() => { | |
18 | + return ( | |
19 | + unref(getSplit) || | |
20 | + (unref(getShowMenu) && unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && !unref(fullContent)) | |
21 | + ); | |
22 | + }); | |
15 | 23 | |
16 | -const getCollapsed = computed(() => unref(getMenuSetting).collapsed); | |
24 | + const getCollapsed = computed(() => appStore.getMenuSetting.collapsed); | |
17 | 25 | |
18 | -const getMenuType = computed(() => unref(getMenuSetting).type); | |
26 | + const getMenuType = computed(() => appStore.getMenuSetting.type); | |
19 | 27 | |
20 | -const getMenuMode = computed(() => unref(getMenuSetting).mode); | |
28 | + const getMenuMode = computed(() => appStore.getMenuSetting.mode); | |
21 | 29 | |
22 | -const getMenuFixed = computed(() => unref(getMenuSetting).fixed); | |
30 | + const getMenuFixed = computed(() => appStore.getMenuSetting.fixed); | |
23 | 31 | |
24 | -const getShowMenu = computed(() => unref(getMenuSetting).show); | |
32 | + const getShowMenu = computed(() => appStore.getMenuSetting.show); | |
25 | 33 | |
26 | -const getMenuHidden = computed(() => unref(getMenuSetting).hidden); | |
34 | + const getMenuHidden = computed(() => appStore.getMenuSetting.hidden); | |
27 | 35 | |
28 | -const getMenuWidth = computed(() => unref(getMenuSetting).menuWidth); | |
36 | + const getMenuWidth = computed(() => appStore.getMenuSetting.menuWidth); | |
29 | 37 | |
30 | -const getTrigger = computed(() => unref(getMenuSetting).trigger); | |
38 | + const getTrigger = computed(() => appStore.getMenuSetting.trigger); | |
31 | 39 | |
32 | -const getMenuTheme = computed(() => unref(getMenuSetting).theme); | |
40 | + const getMenuTheme = computed(() => appStore.getMenuSetting.theme); | |
33 | 41 | |
34 | -const getSplit = computed(() => unref(getMenuSetting).split); | |
42 | + const getSplit = computed(() => appStore.getMenuSetting.split); | |
35 | 43 | |
36 | -const getMenuBgColor = computed(() => unref(getMenuSetting).bgColor); | |
44 | + const getMenuBgColor = computed(() => appStore.getMenuSetting.bgColor); | |
37 | 45 | |
38 | -const getMixSideTrigger = computed(() => unref(getMenuSetting).mixSideTrigger); | |
46 | + const getMixSideTrigger = computed(() => appStore.getMenuSetting.mixSideTrigger); | |
39 | 47 | |
40 | -const getCanDrag = computed(() => unref(getMenuSetting).canDrag); | |
48 | + const getCanDrag = computed(() => appStore.getMenuSetting.canDrag); | |
41 | 49 | |
42 | -const getAccordion = computed(() => unref(getMenuSetting).accordion); | |
50 | + const getAccordion = computed(() => appStore.getMenuSetting.accordion); | |
43 | 51 | |
44 | -const getMixSideFixed = computed(() => unref(getMenuSetting).mixSideFixed); | |
52 | + const getMixSideFixed = computed(() => appStore.getMenuSetting.mixSideFixed); | |
45 | 53 | |
46 | -const getTopMenuAlign = computed(() => unref(getMenuSetting).topMenuAlign); | |
54 | + const getTopMenuAlign = computed(() => appStore.getMenuSetting.topMenuAlign); | |
47 | 55 | |
48 | -const getCloseMixSidebarOnChange = computed(() => unref(getMenuSetting).closeMixSidebarOnChange); | |
56 | + const getCloseMixSidebarOnChange = computed( | |
57 | + () => appStore.getMenuSetting.closeMixSidebarOnChange | |
58 | + ); | |
49 | 59 | |
50 | -const getIsSidebarType = computed(() => unref(getMenuType) === MenuTypeEnum.SIDEBAR); | |
60 | + const getIsSidebarType = computed(() => unref(getMenuType) === MenuTypeEnum.SIDEBAR); | |
51 | 61 | |
52 | -const getIsTopMenu = computed(() => unref(getMenuType) === MenuTypeEnum.TOP_MENU); | |
62 | + const getIsTopMenu = computed(() => unref(getMenuType) === MenuTypeEnum.TOP_MENU); | |
53 | 63 | |
54 | -const getCollapsedShowTitle = computed(() => unref(getMenuSetting).collapsedShowTitle); | |
64 | + const getCollapsedShowTitle = computed(() => appStore.getMenuSetting.collapsedShowTitle); | |
55 | 65 | |
56 | -const getShowTopMenu = computed(() => { | |
57 | - return unref(getMenuMode) === MenuModeEnum.HORIZONTAL || unref(getSplit); | |
58 | -}); | |
66 | + const getShowTopMenu = computed(() => { | |
67 | + return unref(getMenuMode) === MenuModeEnum.HORIZONTAL || unref(getSplit); | |
68 | + }); | |
59 | 69 | |
60 | -const getShowHeaderTrigger = computed(() => { | |
61 | - if (unref(getMenuType) === MenuTypeEnum.TOP_MENU || !unref(getShowMenu) || unref(getMenuHidden)) { | |
62 | - return false; | |
63 | - } | |
70 | + const getShowHeaderTrigger = computed(() => { | |
71 | + if ( | |
72 | + unref(getMenuType) === MenuTypeEnum.TOP_MENU || | |
73 | + !unref(getShowMenu) || | |
74 | + unref(getMenuHidden) | |
75 | + ) { | |
76 | + return false; | |
77 | + } | |
64 | 78 | |
65 | - return unref(getTrigger) === TriggerEnum.HEADER; | |
66 | -}); | |
79 | + return unref(getTrigger) === TriggerEnum.HEADER; | |
80 | + }); | |
67 | 81 | |
68 | -const getIsHorizontal = computed(() => { | |
69 | - return unref(getMenuMode) === MenuModeEnum.HORIZONTAL; | |
70 | -}); | |
82 | + const getIsHorizontal = computed(() => { | |
83 | + return unref(getMenuMode) === MenuModeEnum.HORIZONTAL; | |
84 | + }); | |
71 | 85 | |
72 | -const getIsMixSidebar = computed(() => { | |
73 | - return unref(getMenuType) === MenuTypeEnum.MIX_SIDEBAR; | |
74 | -}); | |
86 | + const getIsMixSidebar = computed(() => { | |
87 | + return unref(getMenuType) === MenuTypeEnum.MIX_SIDEBAR; | |
88 | + }); | |
75 | 89 | |
76 | -const getIsMixMode = computed(() => { | |
77 | - return unref(getMenuMode) === MenuModeEnum.INLINE && unref(getMenuType) === MenuTypeEnum.MIX; | |
78 | -}); | |
90 | + const getIsMixMode = computed(() => { | |
91 | + return unref(getMenuMode) === MenuModeEnum.INLINE && unref(getMenuType) === MenuTypeEnum.MIX; | |
92 | + }); | |
79 | 93 | |
80 | -const getRealWidth = computed(() => { | |
81 | - if (unref(getIsMixSidebar)) { | |
82 | - return unref(getCollapsed) && !unref(getMixSideFixed) | |
83 | - ? unref(getMiniWidthNumber) | |
84 | - : unref(getMenuWidth); | |
85 | - } | |
86 | - return unref(getCollapsed) ? unref(getMiniWidthNumber) : unref(getMenuWidth); | |
87 | -}); | |
88 | - | |
89 | -const getMiniWidthNumber = computed(() => { | |
90 | - const { collapsedShowTitle } = unref(getMenuSetting); | |
91 | - return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH; | |
92 | -}); | |
93 | - | |
94 | -const getCalcContentWidth = computed(() => { | |
95 | - const width = | |
96 | - unref(getIsTopMenu) || !unref(getShowMenu) || (unref(getSplit) && unref(getMenuHidden)) | |
97 | - ? 0 | |
98 | - : unref(getIsMixSidebar) | |
99 | - ? (unref(getCollapsed) ? SIDE_BAR_MINI_WIDTH : SIDE_BAR_SHOW_TIT_MINI_WIDTH) + | |
100 | - (unref(getMixSideFixed) && unref(mixSideHasChildren) ? unref(getRealWidth) : 0) | |
101 | - : unref(getRealWidth); | |
102 | - | |
103 | - return `calc(100% - ${unref(width)}px)`; | |
104 | -}); | |
105 | - | |
106 | -const { getFullContent: fullContent } = useFullContent(); | |
107 | - | |
108 | -const getShowSidebar = computed(() => { | |
109 | - return ( | |
110 | - unref(getSplit) || | |
111 | - (unref(getShowMenu) && unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && !unref(fullContent)) | |
112 | - ); | |
113 | -}); | |
94 | + const getRealWidth = computed(() => { | |
95 | + if (unref(getIsMixSidebar)) { | |
96 | + return unref(getCollapsed) && !unref(getMixSideFixed) | |
97 | + ? unref(getMiniWidthNumber) | |
98 | + : unref(getMenuWidth); | |
99 | + } | |
100 | + return unref(getCollapsed) ? unref(getMiniWidthNumber) : unref(getMenuWidth); | |
101 | + }); | |
114 | 102 | |
115 | -// Set menu configuration | |
116 | -function setMenuSetting(menuSetting: Partial<MenuSetting>): void { | |
117 | - appStore.commitProjectConfigState({ menuSetting }); | |
118 | -} | |
103 | + const getMiniWidthNumber = computed(() => { | |
104 | + const { collapsedShowTitle } = appStore.getMenuSetting; | |
105 | + return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH; | |
106 | + }); | |
107 | + | |
108 | + const getCalcContentWidth = computed(() => { | |
109 | + const width = | |
110 | + unref(getIsTopMenu) || !unref(getShowMenu) || (unref(getSplit) && unref(getMenuHidden)) | |
111 | + ? 0 | |
112 | + : unref(getIsMixSidebar) | |
113 | + ? (unref(getCollapsed) ? SIDE_BAR_MINI_WIDTH : SIDE_BAR_SHOW_TIT_MINI_WIDTH) + | |
114 | + (unref(getMixSideFixed) && unref(mixSideHasChildren) ? unref(getRealWidth) : 0) | |
115 | + : unref(getRealWidth); | |
119 | 116 | |
120 | -function toggleCollapsed() { | |
121 | - setMenuSetting({ | |
122 | - collapsed: !unref(getCollapsed), | |
117 | + return `calc(100% - ${unref(width)}px)`; | |
123 | 118 | }); |
124 | -} | |
125 | 119 | |
126 | -export function useMenuSetting() { | |
120 | + // Set menu configuration | |
121 | + function setMenuSetting(menuSetting: Partial<MenuSetting>): void { | |
122 | + appStore.setProjectConfig({ menuSetting }); | |
123 | + } | |
124 | + | |
125 | + function toggleCollapsed() { | |
126 | + setMenuSetting({ | |
127 | + collapsed: !unref(getCollapsed), | |
128 | + }); | |
129 | + } | |
127 | 130 | return { |
128 | 131 | setMenuSetting, |
129 | 132 | |
130 | 133 | toggleCollapsed, |
131 | 134 | |
132 | 135 | getMenuFixed, |
133 | - getMenuSetting, | |
134 | 136 | getRealWidth, |
135 | 137 | getMenuType, |
136 | 138 | getMenuMode, | ... | ... |
src/hooks/setting/useMultipleTabSetting.ts
1 | 1 | import type { MultiTabsSetting } from '/#/config'; |
2 | 2 | |
3 | -import { computed, unref } from 'vue'; | |
3 | +import { computed } from 'vue'; | |
4 | 4 | |
5 | -import { appStore } from '/@/store/modules/app'; | |
5 | +import { useAppStore } from '/@/store/modules/app'; | |
6 | 6 | |
7 | -const getMultipleTabSetting = computed(() => appStore.getProjectConfig.multiTabsSetting); | |
8 | - | |
9 | -const getShowMultipleTab = computed(() => unref(getMultipleTabSetting).show); | |
7 | +export function useMultipleTabSetting() { | |
8 | + const appStore = useAppStore(); | |
10 | 9 | |
11 | -const getShowQuick = computed(() => unref(getMultipleTabSetting).showQuick); | |
10 | + const getShowMultipleTab = computed(() => appStore.getMultiTabsSetting.show); | |
12 | 11 | |
13 | -const getShowRedo = computed(() => unref(getMultipleTabSetting).showRedo); | |
12 | + const getShowQuick = computed(() => appStore.getMultiTabsSetting.showQuick); | |
14 | 13 | |
15 | -const getShowFold = computed(() => unref(getMultipleTabSetting).showFold); | |
14 | + const getShowRedo = computed(() => appStore.getMultiTabsSetting.showRedo); | |
16 | 15 | |
17 | -function setMultipleTabSetting(multiTabsSetting: Partial<MultiTabsSetting>) { | |
18 | - appStore.commitProjectConfigState({ multiTabsSetting }); | |
19 | -} | |
16 | + const getShowFold = computed(() => appStore.getMultiTabsSetting.showFold); | |
20 | 17 | |
21 | -export function useMultipleTabSetting() { | |
18 | + function setMultipleTabSetting(multiTabsSetting: Partial<MultiTabsSetting>) { | |
19 | + appStore.setProjectConfig({ multiTabsSetting }); | |
20 | + } | |
22 | 21 | return { |
23 | 22 | setMultipleTabSetting, |
24 | - | |
25 | - getMultipleTabSetting, | |
26 | 23 | getShowMultipleTab, |
27 | 24 | getShowQuick, |
28 | 25 | getShowRedo, | ... | ... |
src/hooks/setting/useRootSetting.ts
1 | 1 | import type { ProjectConfig } from '/#/config'; |
2 | 2 | |
3 | -import { computed, unref } from 'vue'; | |
3 | +import { computed } from 'vue'; | |
4 | 4 | |
5 | -import { appStore } from '/@/store/modules/app'; | |
6 | -import { ContentEnum } from '/@/enums/appEnum'; | |
7 | -import { ThemeEnum } from '../../enums/appEnum'; | |
5 | +import { useAppStore } from '/@/store/modules/app'; | |
6 | +import { ContentEnum, ThemeEnum } from '/@/enums/appEnum'; | |
8 | 7 | |
9 | 8 | type RootSetting = Omit< |
10 | 9 | ProjectConfig, |
11 | 10 | 'locale' | 'headerSetting' | 'menuSetting' | 'multiTabsSetting' |
12 | 11 | >; |
13 | 12 | |
14 | -const getRootSetting = computed((): RootSetting => appStore.getProjectConfig); | |
13 | +export function useRootSetting() { | |
14 | + const appStore = useAppStore(); | |
15 | 15 | |
16 | -const getPageLoading = computed(() => appStore.getPageLoading); | |
16 | + const getPageLoading = computed(() => appStore.getPageLoading); | |
17 | 17 | |
18 | -const getOpenKeepAlive = computed(() => unref(getRootSetting).openKeepAlive); | |
18 | + const getOpenKeepAlive = computed(() => appStore.getProjectConfig.openKeepAlive); | |
19 | 19 | |
20 | -const getSettingButtonPosition = computed(() => unref(getRootSetting).settingButtonPosition); | |
20 | + const getSettingButtonPosition = computed(() => appStore.getProjectConfig.settingButtonPosition); | |
21 | 21 | |
22 | -const getCanEmbedIFramePage = computed(() => unref(getRootSetting).canEmbedIFramePage); | |
22 | + const getCanEmbedIFramePage = computed(() => appStore.getProjectConfig.canEmbedIFramePage); | |
23 | 23 | |
24 | -const getPermissionMode = computed(() => unref(getRootSetting).permissionMode); | |
24 | + const getPermissionMode = computed(() => appStore.getProjectConfig.permissionMode); | |
25 | 25 | |
26 | -const getShowLogo = computed(() => unref(getRootSetting).showLogo); | |
26 | + const getShowLogo = computed(() => appStore.getProjectConfig.showLogo); | |
27 | 27 | |
28 | -const getContentMode = computed(() => unref(getRootSetting).contentMode); | |
28 | + const getContentMode = computed(() => appStore.getProjectConfig.contentMode); | |
29 | 29 | |
30 | -const getUseOpenBackTop = computed(() => unref(getRootSetting).useOpenBackTop); | |
30 | + const getUseOpenBackTop = computed(() => appStore.getProjectConfig.useOpenBackTop); | |
31 | 31 | |
32 | -const getShowSettingButton = computed(() => unref(getRootSetting).showSettingButton); | |
32 | + const getShowSettingButton = computed(() => appStore.getProjectConfig.showSettingButton); | |
33 | 33 | |
34 | -const getUseErrorHandle = computed(() => unref(getRootSetting).useErrorHandle); | |
34 | + const getUseErrorHandle = computed(() => appStore.getProjectConfig.useErrorHandle); | |
35 | 35 | |
36 | -const getShowFooter = computed(() => unref(getRootSetting).showFooter); | |
36 | + const getShowFooter = computed(() => appStore.getProjectConfig.showFooter); | |
37 | 37 | |
38 | -const getShowBreadCrumb = computed(() => unref(getRootSetting).showBreadCrumb); | |
38 | + const getShowBreadCrumb = computed(() => appStore.getProjectConfig.showBreadCrumb); | |
39 | 39 | |
40 | -const getThemeColor = computed(() => unref(getRootSetting).themeColor); | |
40 | + const getThemeColor = computed(() => appStore.getProjectConfig.themeColor); | |
41 | 41 | |
42 | -const getShowBreadCrumbIcon = computed(() => unref(getRootSetting).showBreadCrumbIcon); | |
42 | + const getShowBreadCrumbIcon = computed(() => appStore.getProjectConfig.showBreadCrumbIcon); | |
43 | 43 | |
44 | -const getFullContent = computed(() => unref(getRootSetting).fullContent); | |
44 | + const getFullContent = computed(() => appStore.getProjectConfig.fullContent); | |
45 | 45 | |
46 | -const getColorWeak = computed(() => unref(getRootSetting).colorWeak); | |
46 | + const getColorWeak = computed(() => appStore.getProjectConfig.colorWeak); | |
47 | 47 | |
48 | -const getGrayMode = computed(() => unref(getRootSetting).grayMode); | |
48 | + const getGrayMode = computed(() => appStore.getProjectConfig.grayMode); | |
49 | 49 | |
50 | -const getLockTime = computed(() => unref(getRootSetting).lockTime); | |
50 | + const getLockTime = computed(() => appStore.getProjectConfig.lockTime); | |
51 | 51 | |
52 | -const getShowDarkModeToggle = computed(() => unref(getRootSetting).showDarkModeToggle); | |
52 | + const getShowDarkModeToggle = computed(() => appStore.getProjectConfig.showDarkModeToggle); | |
53 | 53 | |
54 | -const getDarkMode = computed(() => appStore.getDarkMode); | |
54 | + const getDarkMode = computed(() => appStore.getDarkMode); | |
55 | 55 | |
56 | -const getLayoutContentMode = computed(() => | |
57 | - unref(getRootSetting).contentMode === ContentEnum.FULL ? ContentEnum.FULL : ContentEnum.FIXED | |
58 | -); | |
56 | + const getLayoutContentMode = computed(() => | |
57 | + appStore.getProjectConfig.contentMode === ContentEnum.FULL | |
58 | + ? ContentEnum.FULL | |
59 | + : ContentEnum.FIXED | |
60 | + ); | |
59 | 61 | |
60 | -function setRootSetting(setting: Partial<RootSetting>) { | |
61 | - appStore.commitProjectConfigState(setting); | |
62 | -} | |
62 | + function setRootSetting(setting: Partial<RootSetting>) { | |
63 | + appStore.setProjectConfig(setting); | |
64 | + } | |
63 | 65 | |
64 | -function setDarkMode(mode: ThemeEnum) { | |
65 | - appStore.commitDarkMode(mode); | |
66 | -} | |
67 | - | |
68 | -export function useRootSetting() { | |
66 | + function setDarkMode(mode: ThemeEnum) { | |
67 | + appStore.setDarkMode(mode); | |
68 | + } | |
69 | 69 | return { |
70 | 70 | setRootSetting, |
71 | 71 | |
... | ... | @@ -73,7 +73,6 @@ export function useRootSetting() { |
73 | 73 | getFullContent, |
74 | 74 | getColorWeak, |
75 | 75 | getGrayMode, |
76 | - getRootSetting, | |
77 | 76 | getLayoutContentMode, |
78 | 77 | getPageLoading, |
79 | 78 | getOpenKeepAlive, | ... | ... |
src/hooks/setting/useTransitionSetting.ts
1 | 1 | import type { TransitionSetting } from '/#/config'; |
2 | 2 | |
3 | -import { computed, unref } from 'vue'; | |
3 | +import { computed } from 'vue'; | |
4 | 4 | |
5 | -import { appStore } from '/@/store/modules/app'; | |
5 | +import { useAppStore } from '/@/store/modules/app'; | |
6 | 6 | |
7 | -const getTransitionSetting = computed(() => appStore.getProjectConfig.transitionSetting); | |
8 | - | |
9 | -const getEnableTransition = computed(() => unref(getTransitionSetting)?.enable); | |
7 | +export function useTransitionSetting() { | |
8 | + const appStore = useAppStore(); | |
10 | 9 | |
11 | -const getOpenNProgress = computed(() => unref(getTransitionSetting)?.openNProgress); | |
10 | + const getEnableTransition = computed(() => appStore.getTransitionSetting?.enable); | |
12 | 11 | |
13 | -const getOpenPageLoading = computed((): boolean => { | |
14 | - return !!unref(getTransitionSetting)?.openPageLoading; | |
15 | -}); | |
12 | + const getOpenNProgress = computed(() => appStore.getTransitionSetting?.openNProgress); | |
16 | 13 | |
17 | -const getBasicTransition = computed(() => unref(getTransitionSetting)?.basicTransition); | |
14 | + const getOpenPageLoading = computed((): boolean => { | |
15 | + return !!appStore.getTransitionSetting?.openPageLoading; | |
16 | + }); | |
18 | 17 | |
19 | -function setTransitionSetting(transitionSetting: Partial<TransitionSetting>) { | |
20 | - appStore.commitProjectConfigState({ transitionSetting }); | |
21 | -} | |
18 | + const getBasicTransition = computed(() => appStore.getTransitionSetting?.basicTransition); | |
22 | 19 | |
23 | -export function useTransitionSetting() { | |
20 | + function setTransitionSetting(transitionSetting: Partial<TransitionSetting>) { | |
21 | + appStore.setProjectConfig({ transitionSetting }); | |
22 | + } | |
24 | 23 | return { |
25 | 24 | setTransitionSetting, |
26 | 25 | |
27 | - getTransitionSetting, | |
28 | 26 | getEnableTransition, |
29 | 27 | getOpenNProgress, |
30 | 28 | getOpenPageLoading, | ... | ... |
src/plugins/echarts/index.ts renamed to src/hooks/web/useEcharts/echarts.ts
src/hooks/web/useECharts.ts renamed to src/hooks/web/useEcharts/index.ts
1 | +import type { EChartsOption } from 'echarts'; | |
2 | +import type { Ref } from 'vue'; | |
3 | + | |
1 | 4 | import { useTimeoutFn } from '/@/hooks/core/useTimeout'; |
2 | 5 | import { tryOnUnmounted } from '@vueuse/core'; |
3 | -import { unref, Ref, nextTick, watch, computed, ref } from 'vue'; | |
4 | -import type { EChartsOption } from 'echarts'; | |
6 | +import { unref, nextTick, watch, computed, ref } from 'vue'; | |
5 | 7 | import { useDebounce } from '/@/hooks/core/useDebounce'; |
6 | 8 | import { useEventListener } from '/@/hooks/event/useEventListener'; |
7 | 9 | import { useBreakpoint } from '/@/hooks/event/useBreakpoint'; |
8 | 10 | |
9 | -import echarts from '/@/plugins/echarts'; | |
10 | -import { useRootSetting } from '../setting/useRootSetting'; | |
11 | +import echarts from './echarts'; | |
12 | +import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | |
11 | 13 | |
12 | 14 | export function useECharts( |
13 | 15 | elRef: Ref<HTMLDivElement>, | ... | ... |
src/hooks/web/useFullContent.ts
1 | 1 | import { computed, unref } from 'vue'; |
2 | 2 | |
3 | -import { appStore } from '/@/store/modules/app'; | |
3 | +import { useAppStore } from '/@/store/modules/app'; | |
4 | 4 | |
5 | 5 | import router from '/@/router'; |
6 | 6 | |
... | ... | @@ -8,6 +8,7 @@ import router from '/@/router'; |
8 | 8 | * @description: Full screen display content |
9 | 9 | */ |
10 | 10 | export const useFullContent = () => { |
11 | + const appStore = useAppStore(); | |
11 | 12 | const { currentRoute } = router; |
12 | 13 | |
13 | 14 | // Whether to display the content in full screen without displaying the menu | ... | ... |
src/hooks/web/useLockPage.ts
1 | 1 | import { computed, onUnmounted, unref, watchEffect } from 'vue'; |
2 | 2 | import { useThrottle } from '/@/hooks/core/useThrottle'; |
3 | 3 | |
4 | -import { appStore } from '/@/store/modules/app'; | |
5 | -import { lockStore } from '/@/store/modules/lock'; | |
6 | -import { userStore } from '/@/store/modules/user'; | |
4 | +import { useAppStore } from '/@/store/modules/app'; | |
5 | +import { useLockStore } from '/@/store/modules/lock'; | |
6 | + | |
7 | +import { useUserStore } from '/@/store/modules/user'; | |
7 | 8 | import { useRootSetting } from '../setting/useRootSetting'; |
8 | 9 | |
9 | 10 | export function useLockPage() { |
10 | 11 | const { getLockTime } = useRootSetting(); |
12 | + const lockStore = useLockStore(); | |
13 | + const userStore = useUserStore(); | |
14 | + const appStore = useAppStore(); | |
15 | + | |
11 | 16 | let timeId: TimeoutHandle; |
12 | 17 | |
13 | 18 | function clear(): void { |
... | ... | @@ -16,7 +21,7 @@ export function useLockPage() { |
16 | 21 | |
17 | 22 | function resetCalcLockTimeout(): void { |
18 | 23 | // not login |
19 | - if (!userStore.getTokenState) { | |
24 | + if (!userStore.getToken) { | |
20 | 25 | clear(); |
21 | 26 | return; |
22 | 27 | } |
... | ... | @@ -33,14 +38,14 @@ export function useLockPage() { |
33 | 38 | } |
34 | 39 | |
35 | 40 | function lockPage(): void { |
36 | - lockStore.commitLockInfoState({ | |
41 | + lockStore.setLockInfo({ | |
37 | 42 | isLock: true, |
38 | 43 | pwd: undefined, |
39 | 44 | }); |
40 | 45 | } |
41 | 46 | |
42 | 47 | watchEffect((onClean) => { |
43 | - if (userStore.getTokenState) { | |
48 | + if (userStore.getToken) { | |
44 | 49 | resetCalcLockTimeout(); |
45 | 50 | } else { |
46 | 51 | clear(); | ... | ... |
src/hooks/web/usePage.ts
1 | -import type { RouteLocationRaw } from 'vue-router'; | |
1 | +import type { RouteLocationRaw, Router } from 'vue-router'; | |
2 | 2 | |
3 | 3 | import { PageEnum } from '/@/enums/pageEnum'; |
4 | 4 | import { isString } from '/@/utils/is'; |
5 | 5 | import { unref } from 'vue'; |
6 | 6 | |
7 | -import router from '/@/router'; | |
7 | +import { useRouter } from 'vue-router'; | |
8 | 8 | |
9 | 9 | export type RouteLocationRawEx = Omit<RouteLocationRaw, 'path'> & { path: PageEnum }; |
10 | 10 | |
... | ... | @@ -13,10 +13,16 @@ function handleError(e: Error) { |
13 | 13 | } |
14 | 14 | |
15 | 15 | // page switch |
16 | -export function useGo() { | |
17 | - const { push, replace } = router; | |
16 | +export function useGo(_router?: Router) { | |
17 | + let router; | |
18 | + if (!_router) { | |
19 | + router = useRouter(); | |
20 | + } | |
21 | + const { push, replace } = _router || router; | |
18 | 22 | function go(opt: PageEnum | RouteLocationRawEx | string = PageEnum.BASE_HOME, isReplace = false) { |
19 | - if (!opt) return; | |
23 | + if (!opt) { | |
24 | + return; | |
25 | + } | |
20 | 26 | if (isString(opt)) { |
21 | 27 | isReplace ? replace(opt).catch(handleError) : push(opt).catch(handleError); |
22 | 28 | } else { |
... | ... | @@ -30,8 +36,12 @@ export function useGo() { |
30 | 36 | /** |
31 | 37 | * @description: redo current page |
32 | 38 | */ |
33 | -export const useRedo = () => { | |
34 | - const { push, currentRoute } = router; | |
39 | +export const useRedo = (_router?: Router) => { | |
40 | + let router; | |
41 | + if (!_router) { | |
42 | + router = useRouter(); | |
43 | + } | |
44 | + const { push, currentRoute } = _router || router; | |
35 | 45 | const { query, params } = currentRoute.value; |
36 | 46 | function redo(): Promise<boolean> { |
37 | 47 | return new Promise((resolve) => { | ... | ... |
src/hooks/web/usePermission.ts
1 | 1 | import type { RouteRecordRaw } from 'vue-router'; |
2 | 2 | |
3 | -import { appStore } from '/@/store/modules/app'; | |
4 | -import { permissionStore } from '/@/store/modules/permission'; | |
5 | -import { userStore } from '/@/store/modules/user'; | |
3 | +import { useAppStore } from '/@/store/modules/app'; | |
4 | +import { usePermissionStore } from '/@/store/modules/permission'; | |
5 | +import { useUserStore } from '/@/store/modules/user'; | |
6 | 6 | |
7 | 7 | import { useTabs } from './useTabs'; |
8 | 8 | |
... | ... | @@ -15,15 +15,20 @@ import { RoleEnum } from '/@/enums/roleEnum'; |
15 | 15 | |
16 | 16 | import { intersection } from 'lodash-es'; |
17 | 17 | import { isArray } from '/@/utils/is'; |
18 | -import { tabStore } from '/@/store/modules/tab'; | |
18 | +import { useMultipleTabStore } from '/@/store/modules/multipleTab'; | |
19 | 19 | |
20 | 20 | // User permissions related operations |
21 | 21 | export function usePermission() { |
22 | + const userStore = useUserStore(); | |
23 | + const appStore = useAppStore(); | |
24 | + const permissionStore = usePermissionStore(); | |
25 | + const { closeAll } = useTabs(router); | |
26 | + | |
22 | 27 | /** |
23 | 28 | * Change permission mode |
24 | 29 | */ |
25 | 30 | async function togglePermissionMode() { |
26 | - appStore.commitProjectConfigState({ | |
31 | + appStore.setProjectConfig({ | |
27 | 32 | permissionMode: |
28 | 33 | projectSetting.permissionMode === PermissionModeEnum.BACK |
29 | 34 | ? PermissionModeEnum.ROLE |
... | ... | @@ -37,14 +42,14 @@ export function usePermission() { |
37 | 42 | * @param id |
38 | 43 | */ |
39 | 44 | async function resume(id?: string | number) { |
40 | - tabStore.commitClearCache(); | |
45 | + const tabStore = useMultipleTabStore(); | |
46 | + tabStore.clearCacheTabs(); | |
41 | 47 | resetRouter(); |
42 | 48 | const routes = await permissionStore.buildRoutesAction(id); |
43 | 49 | routes.forEach((route) => { |
44 | 50 | router.addRoute((route as unknown) as RouteRecordRaw); |
45 | 51 | }); |
46 | - permissionStore.commitLastBuildMenuTimeState(); | |
47 | - const { closeAll } = useTabs(); | |
52 | + permissionStore.setLastBuildMenuTime(); | |
48 | 53 | closeAll(); |
49 | 54 | } |
50 | 55 | |
... | ... | @@ -53,22 +58,24 @@ export function usePermission() { |
53 | 58 | */ |
54 | 59 | function hasPermission(value?: RoleEnum | RoleEnum[] | string | string[], def = true): boolean { |
55 | 60 | const permMode = projectSetting.permissionMode; |
61 | + | |
56 | 62 | if (PermissionModeEnum.ROLE === permMode) { |
57 | 63 | // Visible by default |
58 | 64 | if (!value) { |
59 | 65 | return def; |
60 | 66 | } |
61 | 67 | if (!isArray(value)) { |
62 | - return userStore.getRoleListState?.includes(value as RoleEnum); | |
68 | + return userStore.getRoleList?.includes(value as RoleEnum); | |
63 | 69 | } |
64 | - return (intersection(value, userStore.getRoleListState) as RoleEnum[]).length > 0; | |
70 | + return (intersection(value, userStore.getRoleList) as RoleEnum[]).length > 0; | |
65 | 71 | } |
72 | + | |
66 | 73 | if (PermissionModeEnum.BACK === permMode) { |
67 | 74 | // Visible by default |
68 | 75 | if (!value) { |
69 | 76 | return def; |
70 | 77 | } |
71 | - const allCodeList = permissionStore.getPermCodeListState; | |
78 | + const allCodeList = permissionStore.getPermCodeList; | |
72 | 79 | if (!isArray(value)) { |
73 | 80 | return allCodeList.includes(value as string); |
74 | 81 | } |
... | ... | @@ -90,7 +97,7 @@ export function usePermission() { |
90 | 97 | if (!isArray(roles)) { |
91 | 98 | roles = [roles]; |
92 | 99 | } |
93 | - userStore.commitRoleListState(roles); | |
100 | + userStore.setRoleList(roles); | |
94 | 101 | await resume(); |
95 | 102 | } |
96 | 103 | ... | ... |
src/hooks/web/useTabs.ts
1 | -import { tabStore } from '/@/store/modules/tab'; | |
2 | -import { appStore } from '/@/store/modules/app'; | |
3 | -import type { RouteLocationNormalized } from 'vue-router'; | |
1 | +import type { RouteLocationNormalized, Router } from 'vue-router'; | |
4 | 2 | |
5 | -export function useTabs() { | |
6 | - function canIUseFn(): boolean { | |
7 | - const { multiTabsSetting: { show } = {} } = appStore.getProjectConfig; | |
3 | +import { useRouter } from 'vue-router'; | |
4 | +import { unref } from 'vue'; | |
5 | + | |
6 | +import { useMultipleTabStore } from '/@/store/modules/multipleTab'; | |
7 | +import { useAppStore } from '/@/store/modules/app'; | |
8 | + | |
9 | +enum TableActionEnum { | |
10 | + REFRESH, | |
11 | + CLOSE_ALL, | |
12 | + CLOSE_LEFT, | |
13 | + CLOSE_RIGHT, | |
14 | + CLOSE_OTHER, | |
15 | + CLOSE_CURRENT, | |
16 | + CLOSE, | |
17 | +} | |
18 | + | |
19 | +export function useTabs(_router: Router) { | |
20 | + const appStore = useAppStore(); | |
21 | + | |
22 | + function canIUseTabs(): boolean { | |
23 | + const { show } = appStore.getMultiTabsSetting; | |
8 | 24 | if (!show) { |
9 | 25 | throw new Error('The multi-tab page is currently not open, please open it in the settings๏ผ'); |
10 | 26 | } |
11 | 27 | return !!show; |
12 | 28 | } |
13 | 29 | |
30 | + const tabStore = useMultipleTabStore(); | |
31 | + const router = _router || useRouter(); | |
32 | + | |
33 | + const { currentRoute } = router; | |
34 | + | |
35 | + function getCurrentTab() { | |
36 | + const route = unref(currentRoute); | |
37 | + return tabStore.getTabList.find((item) => item.path === route.path)!; | |
38 | + } | |
39 | + | |
40 | + async function handleTabAction(action: TableActionEnum, tab?: RouteLocationNormalized) { | |
41 | + const canIUse = canIUseTabs; | |
42 | + if (!canIUse) { | |
43 | + return; | |
44 | + } | |
45 | + const currentTab = getCurrentTab(); | |
46 | + switch (action) { | |
47 | + case TableActionEnum.REFRESH: | |
48 | + await tabStore.refreshPage(router); | |
49 | + break; | |
50 | + | |
51 | + case TableActionEnum.CLOSE_ALL: | |
52 | + await tabStore.closeAllTab(router); | |
53 | + break; | |
54 | + | |
55 | + case TableActionEnum.CLOSE_LEFT: | |
56 | + await tabStore.closeLeftTabs(currentTab, router); | |
57 | + break; | |
58 | + | |
59 | + case TableActionEnum.CLOSE_RIGHT: | |
60 | + await tabStore.closeRightTabs(currentTab, router); | |
61 | + break; | |
62 | + | |
63 | + case TableActionEnum.CLOSE_OTHER: | |
64 | + await tabStore.closeOtherTabs(currentTab, router); | |
65 | + break; | |
66 | + | |
67 | + case TableActionEnum.CLOSE_CURRENT: | |
68 | + case TableActionEnum.CLOSE: | |
69 | + await tabStore.closeTab(tab || currentTab, router); | |
70 | + break; | |
71 | + } | |
72 | + } | |
73 | + | |
14 | 74 | return { |
15 | - refreshPage: async () => { | |
16 | - if (canIUseFn()) { | |
17 | - await tabStore.commitRedoPage(); | |
18 | - } | |
75 | + refreshPage: () => handleTabAction(TableActionEnum.REFRESH), | |
76 | + closeAll: () => handleTabAction(TableActionEnum.CLOSE_ALL), | |
77 | + closeLeft: () => handleTabAction(TableActionEnum.CLOSE_LEFT), | |
78 | + closeRight: () => handleTabAction(TableActionEnum.CLOSE_RIGHT), | |
79 | + closeOther: () => handleTabAction(TableActionEnum.CLOSE_OTHER), | |
80 | + closeCurrent: () => handleTabAction(TableActionEnum.CLOSE_CURRENT), | |
81 | + close: (tab?: RouteLocationNormalized) => { | |
82 | + handleTabAction(TableActionEnum.CLOSE, tab); | |
19 | 83 | }, |
20 | - closeAll: () => canIUseFn() && tabStore.closeAllTabAction(), | |
21 | - closeLeft: () => canIUseFn() && tabStore.closeLeftTabAction(tabStore.getCurrentTab), | |
22 | - closeRight: () => canIUseFn() && tabStore.closeRightTabAction(tabStore.getCurrentTab), | |
23 | - closeOther: () => canIUseFn() && tabStore.closeOtherTabAction(tabStore.getCurrentTab), | |
24 | - closeCurrent: () => canIUseFn() && tabStore.closeTabAction(tabStore.getCurrentTab), | |
25 | - close: (tab?: RouteLocationNormalized) => | |
26 | - canIUseFn() && tabStore.closeTabAction(tab || tabStore.getCurrentTab), | |
27 | 84 | }; |
28 | 85 | } | ... | ... |
src/layouts/default/header/components/ErrorAction.vue
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | :mouseEnterDelay="0.5" |
6 | 6 | @click="handleToErrorList" |
7 | 7 | > |
8 | - <Badge :count="getCount" :offset="[0, 10]" dot :overflowCount="99"> | |
8 | + <Badge :count="getCount" :offset="[0, 10]" :overflowCount="99"> | |
9 | 9 | <Icon icon="ion:bug-outline" /> |
10 | 10 | </Badge> |
11 | 11 | </Tooltip> |
... | ... | @@ -16,7 +16,7 @@ |
16 | 16 | import Icon from '/@/components/Icon'; |
17 | 17 | |
18 | 18 | import { useI18n } from '/@/hooks/web/useI18n'; |
19 | - import { errorStore } from '/@/store/modules/error'; | |
19 | + import { useErrorLogStore } from '/@/store/modules/errorLog'; | |
20 | 20 | import { PageEnum } from '/@/enums/pageEnum'; |
21 | 21 | |
22 | 22 | import { useRouter } from 'vue-router'; |
... | ... | @@ -28,14 +28,13 @@ |
28 | 28 | setup() { |
29 | 29 | const { t } = useI18n(); |
30 | 30 | const { push } = useRouter(); |
31 | + const errorLogStore = useErrorLogStore(); | |
31 | 32 | |
32 | - const getCount = computed(() => { | |
33 | - return errorStore.getErrorListCountState; | |
34 | - }); | |
33 | + const getCount = computed(() => errorLogStore.getErrorLogListCount); | |
35 | 34 | |
36 | 35 | function handleToErrorList() { |
37 | 36 | push(PageEnum.ERROR_LOG_PAGE).then(() => { |
38 | - errorStore.commitErrorListCountState(0); | |
37 | + errorLogStore.setErrorLogListCount(0); | |
39 | 38 | }); |
40 | 39 | } |
41 | 40 | ... | ... |
src/layouts/default/header/components/lock/LockModal.vue
... | ... | @@ -31,8 +31,8 @@ |
31 | 31 | import { BasicModal, useModalInner } from '/@/components/Modal/index'; |
32 | 32 | import { BasicForm, useForm } from '/@/components/Form/index'; |
33 | 33 | |
34 | - import { userStore } from '/@/store/modules/user'; | |
35 | - import { lockStore } from '/@/store/modules/lock'; | |
34 | + import { useUserStore } from '/@/store/modules/user'; | |
35 | + import { useLockStore } from '/@/store/modules/lock'; | |
36 | 36 | import headerImg from '/@/assets/images/header.jpg'; |
37 | 37 | export default defineComponent({ |
38 | 38 | name: 'LockModal', |
... | ... | @@ -41,10 +41,10 @@ |
41 | 41 | setup() { |
42 | 42 | const { t } = useI18n(); |
43 | 43 | const { prefixCls } = useDesign('header-lock-modal'); |
44 | + const userStore = useUserStore(); | |
45 | + const lockStore = useLockStore(); | |
44 | 46 | |
45 | - const getRealName = computed(() => { | |
46 | - return userStore.getUserInfoState?.realName; | |
47 | - }); | |
47 | + const getRealName = computed(() => userStore.getUserInfo?.realName); | |
48 | 48 | const [register, { closeModal }] = useModalInner(); |
49 | 49 | |
50 | 50 | const [registerForm, { validateFields, resetFields }] = useForm({ |
... | ... | @@ -64,7 +64,7 @@ |
64 | 64 | const password: string | undefined = values.password; |
65 | 65 | closeModal(); |
66 | 66 | |
67 | - lockStore.commitLockInfoState({ | |
67 | + lockStore.setLockInfo({ | |
68 | 68 | isLock: true, |
69 | 69 | pwd: password, |
70 | 70 | }); | ... | ... |
src/layouts/default/header/components/user-dropdown/index.vue
... | ... | @@ -41,7 +41,7 @@ |
41 | 41 | |
42 | 42 | import { DOC_URL } from '/@/settings/siteSetting'; |
43 | 43 | |
44 | - import { userStore } from '/@/store/modules/user'; | |
44 | + import { useUserStore } from '/@/store/modules/user'; | |
45 | 45 | import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting'; |
46 | 46 | import { useI18n } from '/@/hooks/web/useI18n'; |
47 | 47 | import { useDesign } from '/@/hooks/web/useDesign'; |
... | ... | @@ -71,9 +71,10 @@ |
71 | 71 | const { prefixCls } = useDesign('header-user-dropdown'); |
72 | 72 | const { t } = useI18n(); |
73 | 73 | const { getShowDoc } = useHeaderSetting(); |
74 | + const userStore = useUserStore(); | |
74 | 75 | |
75 | 76 | const getUserInfo = computed(() => { |
76 | - const { realName = '', desc } = userStore.getUserInfoState || {}; | |
77 | + const { realName = '', desc } = userStore.getUserInfo || {}; | |
77 | 78 | return { realName, desc }; |
78 | 79 | }); |
79 | 80 | ... | ... |
src/layouts/default/index.vue
... | ... | @@ -42,13 +42,9 @@ |
42 | 42 | }, |
43 | 43 | setup() { |
44 | 44 | const { prefixCls } = useDesign('default-layout'); |
45 | - | |
46 | 45 | const { getIsMobile } = useAppInject(); |
47 | - | |
48 | 46 | const { getShowFullHeaderRef } = useHeaderSetting(); |
49 | - | |
50 | 47 | const { getShowSidebar, getIsMixSidebar } = useMenuSetting(); |
51 | - | |
52 | 48 | const layoutClass = computed(() => ({ 'ant-layout-has-sider': unref(getIsMixSidebar) })); |
53 | 49 | |
54 | 50 | return { | ... | ... |
src/layouts/default/menu/useLayoutMenu.ts
... | ... | @@ -9,7 +9,7 @@ import { useThrottle } from '/@/hooks/core/useThrottle'; |
9 | 9 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
10 | 10 | |
11 | 11 | import { getChildrenMenus, getCurrentParentPath, getMenus, getShallowMenus } from '/@/router/menus'; |
12 | -import { permissionStore } from '/@/store/modules/permission'; | |
12 | +import { usePermissionStore } from '/@/store/modules/permission'; | |
13 | 13 | import { useAppInject } from '/@/hooks/web/useAppInject'; |
14 | 14 | |
15 | 15 | export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { |
... | ... | @@ -17,6 +17,7 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { |
17 | 17 | const menusRef = ref<Menu[]>([]); |
18 | 18 | const { currentRoute } = useRouter(); |
19 | 19 | const { getIsMobile } = useAppInject(); |
20 | + const permissionStore = usePermissionStore(); | |
20 | 21 | const { setMenuSetting, getIsHorizontal, getSplit } = useMenuSetting(); |
21 | 22 | |
22 | 23 | const [throttleHandleSplitLeftMenu] = useThrottle(handleSplitLeftMenu, 50); |
... | ... | @@ -55,7 +56,7 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { |
55 | 56 | |
56 | 57 | // Menu changes |
57 | 58 | watch( |
58 | - [() => permissionStore.getLastBuildMenuTimeState, () => permissionStore.getBackMenuListState], | |
59 | + [() => permissionStore.getLastBuildMenuTime, () => permissionStore.getBackMenuList], | |
59 | 60 | () => { |
60 | 61 | genMenus(); |
61 | 62 | }, | ... | ... |
src/layouts/default/setting/components/SettingFooter.vue
... | ... | @@ -21,32 +21,36 @@ |
21 | 21 | |
22 | 22 | import { CopyOutlined, RedoOutlined } from '@ant-design/icons-vue'; |
23 | 23 | |
24 | - import { appStore } from '/@/store/modules/app'; | |
25 | - import { permissionStore } from '/@/store/modules/permission'; | |
26 | - import { tabStore } from '/@/store/modules/tab'; | |
27 | - import { userStore } from '/@/store/modules/user'; | |
24 | + import { useAppStore } from '/@/store/modules/app'; | |
25 | + import { usePermissionStore } from '/@/store/modules/permission'; | |
26 | + import { useMultipleTabStore } from '/@/store/modules/multipleTab'; | |
27 | + import { useUserStore } from '/@/store/modules/user'; | |
28 | 28 | |
29 | 29 | import { useDesign } from '/@/hooks/web/useDesign'; |
30 | 30 | import { useI18n } from '/@/hooks/web/useI18n'; |
31 | 31 | import { useMessage } from '/@/hooks/web/useMessage'; |
32 | 32 | import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard'; |
33 | - import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | |
34 | 33 | |
35 | 34 | import { updateColorWeak } from '/@/logics/theme/updateColorWeak'; |
36 | 35 | import { updateGrayMode } from '/@/logics/theme/updateGrayMode'; |
37 | - | |
38 | 36 | import defaultSetting from '/@/settings/projectSetting'; |
37 | + | |
39 | 38 | export default defineComponent({ |
40 | 39 | name: 'SettingFooter', |
41 | 40 | components: { CopyOutlined, RedoOutlined }, |
42 | 41 | setup() { |
43 | - const { getRootSetting } = useRootSetting(); | |
42 | + const permissionStore = usePermissionStore(); | |
44 | 43 | const { prefixCls } = useDesign('setting-footer'); |
45 | 44 | const { t } = useI18n(); |
46 | 45 | const { createSuccessModal, createMessage } = useMessage(); |
46 | + const tabStore = useMultipleTabStore(); | |
47 | + const userStore = useUserStore(); | |
48 | + const appStore = useAppStore(); | |
47 | 49 | |
48 | 50 | function handleCopy() { |
49 | - const { isSuccessRef } = useCopyToClipboard(JSON.stringify(unref(getRootSetting), null, 2)); | |
51 | + const { isSuccessRef } = useCopyToClipboard( | |
52 | + JSON.stringify(unref(appStore.getProjectConfig), null, 2) | |
53 | + ); | |
50 | 54 | unref(isSuccessRef) && |
51 | 55 | createSuccessModal({ |
52 | 56 | title: t('layout.setting.operatingTitle'), |
... | ... | @@ -55,7 +59,7 @@ |
55 | 59 | } |
56 | 60 | function handleResetSetting() { |
57 | 61 | try { |
58 | - appStore.commitProjectConfigState(defaultSetting); | |
62 | + appStore.setProjectConfig(defaultSetting); | |
59 | 63 | const { colorWeak, grayMode } = defaultSetting; |
60 | 64 | // updateTheme(themeColor); |
61 | 65 | updateColorWeak(colorWeak); |
... | ... | @@ -68,10 +72,10 @@ |
68 | 72 | |
69 | 73 | function handleClearAndRedo() { |
70 | 74 | localStorage.clear(); |
71 | - appStore.resumeAllState(); | |
72 | - permissionStore.commitResetState(); | |
73 | - tabStore.commitResetState(); | |
74 | - userStore.commitResetState(); | |
75 | + appStore.resetAllState(); | |
76 | + permissionStore.resetState(); | |
77 | + tabStore.resetState(); | |
78 | + userStore.resetState(); | |
75 | 79 | location.reload(); |
76 | 80 | } |
77 | 81 | return { | ... | ... |
src/layouts/default/setting/handler.ts
... | ... | @@ -3,15 +3,16 @@ import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updat |
3 | 3 | import { updateColorWeak } from '/@/logics/theme/updateColorWeak'; |
4 | 4 | import { updateGrayMode } from '/@/logics/theme/updateGrayMode'; |
5 | 5 | |
6 | -import { appStore } from '/@/store/modules/app'; | |
6 | +import { useAppStore } from '/@/store/modules/app'; | |
7 | 7 | import { ProjectConfig } from '/#/config'; |
8 | 8 | import { changeTheme } from '/@/logics/theme'; |
9 | 9 | import { updateDarkTheme } from '/@/logics/theme/dark'; |
10 | 10 | import { useRootSetting } from '/@/hooks/setting/useRootSetting'; |
11 | 11 | |
12 | 12 | export function baseHandler(event: HandlerEnum, value: any) { |
13 | + const appStore = useAppStore(); | |
13 | 14 | const config = handler(event, value); |
14 | - appStore.commitProjectConfigState(config); | |
15 | + appStore.setProjectConfig(config); | |
15 | 16 | if (event === HandlerEnum.CHANGE_THEME) { |
16 | 17 | updateHeaderBgColor(); |
17 | 18 | updateSidebarBgColor(); |
... | ... | @@ -19,6 +20,8 @@ export function baseHandler(event: HandlerEnum, value: any) { |
19 | 20 | } |
20 | 21 | |
21 | 22 | export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConfig> { |
23 | + const appStore = useAppStore(); | |
24 | + | |
22 | 25 | const { getThemeColor, getDarkMode } = useRootSetting(); |
23 | 26 | switch (event) { |
24 | 27 | case HandlerEnum.CHANGE_LAYOUT: |
... | ... | @@ -50,7 +53,7 @@ export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConf |
50 | 53 | } |
51 | 54 | updateDarkTheme(value); |
52 | 55 | |
53 | - return { darkMode: value }; | |
56 | + return {}; | |
54 | 57 | |
55 | 58 | case HandlerEnum.MENU_HAS_DRAG: |
56 | 59 | return { menuSetting: { canDrag: value } }; |
... | ... | @@ -97,7 +100,7 @@ export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConf |
97 | 100 | |
98 | 101 | // ============transition================== |
99 | 102 | case HandlerEnum.OPEN_PAGE_LOADING: |
100 | - appStore.commitPageLoadingState(false); | |
103 | + appStore.setPageLoading(false); | |
101 | 104 | return { transitionSetting: { openPageLoading: value } }; |
102 | 105 | |
103 | 106 | case HandlerEnum.ROUTER_TRANSITION: | ... | ... |
src/layouts/default/tabs/components/FoldButton.vue
... | ... | @@ -5,38 +5,33 @@ |
5 | 5 | </template> |
6 | 6 | <script lang="ts"> |
7 | 7 | import { defineComponent, unref, computed } from 'vue'; |
8 | + import { Icon } from '/@/components/Icon'; | |
9 | + | |
8 | 10 | import { useDesign } from '/@/hooks/web/useDesign'; |
9 | 11 | import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting'; |
10 | 12 | import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; |
11 | 13 | |
12 | - import Icon from '/@/components/Icon'; | |
13 | - | |
14 | 14 | export default defineComponent({ |
15 | 15 | name: 'FoldButton', |
16 | 16 | components: { Icon }, |
17 | - | |
18 | 17 | setup() { |
19 | 18 | const { prefixCls } = useDesign('multiple-tabs-content'); |
20 | 19 | const { getShowMenu, setMenuSetting } = useMenuSetting(); |
21 | 20 | const { getShowHeader, setHeaderSetting } = useHeaderSetting(); |
22 | 21 | |
23 | - const getIsUnFold = computed(() => { | |
24 | - return !unref(getShowMenu) && !unref(getShowHeader); | |
25 | - }); | |
22 | + const getIsUnFold = computed(() => !unref(getShowMenu) && !unref(getShowHeader)); | |
26 | 23 | |
27 | - const getIcon = computed(() => { | |
28 | - return unref(getIsUnFold) ? 'codicon:screen-normal' : 'codicon:screen-full'; | |
29 | - }); | |
24 | + const getIcon = computed(() => | |
25 | + unref(getIsUnFold) ? 'codicon:screen-normal' : 'codicon:screen-full' | |
26 | + ); | |
30 | 27 | |
31 | 28 | function handleFold() { |
32 | - const isScale = !unref(getShowMenu) && !unref(getShowHeader); | |
29 | + const isUnFold = unref(getIsUnFold); | |
33 | 30 | setMenuSetting({ |
34 | - show: isScale, | |
35 | - hidden: !isScale, | |
36 | - }); | |
37 | - setHeaderSetting({ | |
38 | - show: isScale, | |
31 | + show: isUnFold, | |
32 | + hidden: !isUnFold, | |
39 | 33 | }); |
34 | + setHeaderSetting({ show: isUnFold }); | |
40 | 35 | } |
41 | 36 | |
42 | 37 | return { prefixCls, getIcon, handleFold }; | ... | ... |
src/layouts/default/tabs/components/QuickButton.vue deleted
100644 โ 0
1 | -<template> | |
2 | - <TabContent :type="TabContentEnum.EXTRA_TYPE" :tabItem="$route" /> | |
3 | -</template> | |
4 | -<script lang="ts"> | |
5 | - import { defineComponent } from 'vue'; | |
6 | - | |
7 | - import { TabContentEnum } from '../types'; | |
8 | - | |
9 | - import TabContent from './TabContent.vue'; | |
10 | - export default defineComponent({ | |
11 | - name: 'QuickButton', | |
12 | - components: { | |
13 | - TabContent, | |
14 | - }, | |
15 | - setup() { | |
16 | - return { | |
17 | - TabContentEnum, | |
18 | - }; | |
19 | - }, | |
20 | - }); | |
21 | -</script> |
src/layouts/default/tabs/components/TabContent.vue
1 | 1 | <template> |
2 | 2 | <Dropdown :dropMenuList="getDropMenuList" :trigger="getTrigger" @menuEvent="handleMenuEvent"> |
3 | - <div :class="`${prefixCls}__info`" @contextmenu="handleContext" v-if="isTabs"> | |
3 | + <div :class="`${prefixCls}__info`" @contextmenu="handleContext" v-if="getIsTabs"> | |
4 | 4 | <span class="ml-1">{{ getTitle }}</span> |
5 | 5 | </div> |
6 | - | |
7 | 6 | <span :class="`${prefixCls}__extra-quick`" v-else @click="handleContext"> |
8 | 7 | <Icon icon="ion:chevron-down" /> |
9 | 8 | </span> |
... | ... | @@ -11,18 +10,18 @@ |
11 | 10 | </template> |
12 | 11 | <script lang="ts"> |
13 | 12 | import type { PropType } from 'vue'; |
13 | + import type { RouteLocationNormalized } from 'vue-router'; | |
14 | 14 | |
15 | - import { defineComponent, computed } from 'vue'; | |
15 | + import { defineComponent, computed, unref } from 'vue'; | |
16 | 16 | import { Dropdown } from '/@/components/Dropdown/index'; |
17 | - import Icon from '/@/components/Icon'; | |
17 | + import { Icon } from '/@/components/Icon'; | |
18 | 18 | |
19 | - import { TabContentProps, TabContentEnum } from '../types'; | |
19 | + import { TabContentProps } from '../types'; | |
20 | 20 | |
21 | 21 | import { useDesign } from '/@/hooks/web/useDesign'; |
22 | - import { useTabDropdown } from '../useTabDropdown'; | |
23 | 22 | import { useI18n } from '/@/hooks/web/useI18n'; |
23 | + import { useTabDropdown } from '../useTabDropdown'; | |
24 | 24 | |
25 | - import { RouteLocationNormalized } from 'vue-router'; | |
26 | 25 | export default defineComponent({ |
27 | 26 | name: 'TabContent', |
28 | 27 | components: { Dropdown, Icon }, |
... | ... | @@ -31,11 +30,7 @@ |
31 | 30 | type: Object as PropType<RouteLocationNormalized>, |
32 | 31 | default: null, |
33 | 32 | }, |
34 | - | |
35 | - type: { | |
36 | - type: Number as PropType<TabContentEnum>, | |
37 | - default: TabContentEnum.TAB_TYPE, | |
38 | - }, | |
33 | + isExtra: Boolean, | |
39 | 34 | }, |
40 | 35 | setup(props) { |
41 | 36 | const { prefixCls } = useDesign('multiple-tabs-content'); |
... | ... | @@ -43,27 +38,29 @@ |
43 | 38 | |
44 | 39 | const getTitle = computed(() => { |
45 | 40 | const { tabItem: { meta } = {} } = props; |
46 | - return meta && t(meta.title); | |
41 | + return meta && t(meta.title as string); | |
47 | 42 | }); |
48 | 43 | |
49 | - const { | |
50 | - getDropMenuList, | |
51 | - handleMenuEvent, | |
52 | - handleContextMenu, | |
53 | - getTrigger, | |
54 | - isTabs, | |
55 | - } = useTabDropdown(props as TabContentProps); | |
44 | + const getIsTabs = computed(() => !props.isExtra); | |
45 | + | |
46 | + const getTrigger = computed(() => (unref(getIsTabs) ? ['contextmenu'] : ['click'])); | |
56 | 47 | |
57 | - function handleContext(e: ChangeEvent) { | |
48 | + const { getDropMenuList, handleMenuEvent, handleContextMenu } = useTabDropdown( | |
49 | + props as TabContentProps, | |
50 | + getIsTabs | |
51 | + ); | |
52 | + | |
53 | + function handleContext(e) { | |
58 | 54 | props.tabItem && handleContextMenu(props.tabItem)(e); |
59 | 55 | } |
56 | + | |
60 | 57 | return { |
61 | 58 | prefixCls, |
62 | 59 | getDropMenuList, |
63 | 60 | handleMenuEvent, |
64 | 61 | handleContext, |
65 | 62 | getTrigger, |
66 | - isTabs, | |
63 | + getIsTabs, | |
67 | 64 | getTitle, |
68 | 65 | }; |
69 | 66 | }, | ... | ... |
src/layouts/default/tabs/components/TabRedo.vue
1 | 1 | <template> |
2 | - <Tooltip :title="t('common.redo')" placement="bottom" :mouseEnterDelay="0.5"> | |
3 | - <span :class="`${prefixCls}__extra-redo`" @click="handleRedo"> | |
4 | - <RedoOutlined :spin="loading" /> | |
5 | - </span> | |
6 | - </Tooltip> | |
2 | + <span :class="`${prefixCls}__extra-redo`" @click="handleRedo"> | |
3 | + <RedoOutlined :spin="loading" /> | |
4 | + </span> | |
7 | 5 | </template> |
8 | 6 | <script lang="ts"> |
9 | 7 | import { defineComponent, ref } from 'vue'; |
10 | 8 | import { RedoOutlined } from '@ant-design/icons-vue'; |
11 | 9 | import { useDesign } from '/@/hooks/web/useDesign'; |
12 | - import { Tooltip } from 'ant-design-vue'; | |
13 | - import { useI18n } from '/@/hooks/web/useI18n'; | |
14 | 10 | import { useTabs } from '/@/hooks/web/useTabs'; |
15 | 11 | |
16 | 12 | export default defineComponent({ |
17 | 13 | name: 'TabRedo', |
18 | - components: { RedoOutlined, Tooltip }, | |
14 | + components: { RedoOutlined }, | |
19 | 15 | |
20 | 16 | setup() { |
21 | 17 | const loading = ref(false); |
18 | + | |
22 | 19 | const { prefixCls } = useDesign('multiple-tabs-content'); |
23 | - const { t } = useI18n(); | |
24 | 20 | const { refreshPage } = useTabs(); |
25 | 21 | |
26 | 22 | async function handleRedo() { |
... | ... | @@ -29,9 +25,9 @@ |
29 | 25 | setTimeout(() => { |
30 | 26 | loading.value = false; |
31 | 27 | // Animation execution time |
32 | - }, 1000); | |
28 | + }, 1200); | |
33 | 29 | } |
34 | - return { prefixCls, t, handleRedo, loading }; | |
30 | + return { prefixCls, handleRedo, loading }; | |
35 | 31 | }, |
36 | 32 | }); |
37 | 33 | </script> | ... | ... |
src/layouts/default/tabs/index.less
... | ... | @@ -8,13 +8,20 @@ html[data-theme='dark'] { |
8 | 8 | } |
9 | 9 | } |
10 | 10 | |
11 | +html[data-theme='light'] { | |
12 | + .@{prefix-cls} { | |
13 | + .ant-tabs-tab:not(.ant-tabs-tab-active) { | |
14 | + border: 1px solid #d9d9d9 !important; | |
15 | + } | |
16 | + } | |
17 | +} | |
18 | + | |
11 | 19 | .@{prefix-cls} { |
12 | 20 | z-index: 10; |
13 | 21 | height: @multiple-height + 2; |
14 | 22 | line-height: @multiple-height + 2; |
15 | 23 | background: @component-background; |
16 | 24 | border-bottom: 1px solid @border-color-base; |
17 | - box-shadow: 0 1px 2px 0 rgba(29, 35, 41, 0.05); | |
18 | 25 | |
19 | 26 | .ant-tabs-small { |
20 | 27 | height: @multiple-height; | ... | ... |
src/layouts/default/tabs/index.vue
... | ... | @@ -20,26 +20,26 @@ |
20 | 20 | |
21 | 21 | <template #tabBarExtraContent v-if="getShowRedo || getShowQuick"> |
22 | 22 | <TabRedo v-if="getShowRedo" /> |
23 | - <QuickButton v-if="getShowQuick" /> | |
23 | + <TabContent isExtra :tabItem="$route" v-if="getShowQuick" /> | |
24 | 24 | <FoldButton v-if="getShowFold" /> |
25 | 25 | </template> |
26 | 26 | </Tabs> |
27 | 27 | </div> |
28 | 28 | </template> |
29 | 29 | <script lang="ts"> |
30 | + import type { RouteLocationNormalized } from 'vue-router'; | |
31 | + | |
30 | 32 | import { defineComponent, computed, unref, ref } from 'vue'; |
31 | 33 | |
32 | 34 | import { Tabs } from 'ant-design-vue'; |
33 | 35 | import TabContent from './components/TabContent.vue'; |
34 | - import QuickButton from './components/QuickButton.vue'; | |
35 | 36 | import FoldButton from './components/FoldButton.vue'; |
36 | 37 | import TabRedo from './components/TabRedo.vue'; |
37 | - import type { RouteLocationNormalized } from 'vue-router'; | |
38 | 38 | |
39 | 39 | import { useGo } from '/@/hooks/web/usePage'; |
40 | 40 | |
41 | - import { tabStore } from '/@/store/modules/tab'; | |
42 | - import { userStore } from '/@/store/modules/user'; | |
41 | + import { useMultipleTabStore } from '/@/store/modules/multipleTab'; | |
42 | + import { useUserStore } from '/@/store/modules/user'; | |
43 | 43 | |
44 | 44 | import { initAffixTabs, useTabsDrag } from './useMultipleTabs'; |
45 | 45 | import { useDesign } from '/@/hooks/web/useDesign'; |
... | ... | @@ -48,13 +48,12 @@ |
48 | 48 | import { REDIRECT_NAME } from '/@/router/constant'; |
49 | 49 | import { listenerRouteChange } from '/@/logics/mitt/routeChange'; |
50 | 50 | |
51 | - import router from '/@/router'; | |
51 | + import { useRouter } from 'vue-router'; | |
52 | 52 | |
53 | 53 | export default defineComponent({ |
54 | 54 | name: 'MultipleTabs', |
55 | 55 | components: { |
56 | - QuickButton, | |
57 | - TabRedo: TabRedo, | |
56 | + TabRedo, | |
58 | 57 | FoldButton, |
59 | 58 | Tabs, |
60 | 59 | TabPane: Tabs.TabPane, |
... | ... | @@ -65,12 +64,16 @@ |
65 | 64 | const activeKeyRef = ref(''); |
66 | 65 | |
67 | 66 | useTabsDrag(affixTextList); |
67 | + const tabStore = useMultipleTabStore(); | |
68 | + const userStore = useUserStore(); | |
69 | + const router = useRouter(); | |
70 | + | |
68 | 71 | const { prefixCls } = useDesign('multiple-tabs'); |
69 | 72 | const go = useGo(); |
70 | 73 | const { getShowQuick, getShowRedo, getShowFold } = useMultipleTabSetting(); |
71 | 74 | |
72 | 75 | const getTabsState = computed(() => { |
73 | - return tabStore.getTabsState.filter((item) => !item.meta?.hideTab); | |
76 | + return tabStore.getTabList.filter((item) => !item.meta?.hideTab); | |
74 | 77 | }); |
75 | 78 | |
76 | 79 | const unClose = computed(() => unref(getTabsState).length === 1); |
... | ... | @@ -86,10 +89,11 @@ |
86 | 89 | |
87 | 90 | listenerRouteChange((route) => { |
88 | 91 | const { name } = route; |
89 | - if (name === REDIRECT_NAME || !route || !userStore.getTokenState) return; | |
92 | + if (name === REDIRECT_NAME || !route || !userStore.getToken) { | |
93 | + return; | |
94 | + } | |
90 | 95 | |
91 | 96 | const { path, fullPath, meta = {} } = route; |
92 | - | |
93 | 97 | const { currentActiveMenu, hideTab } = meta; |
94 | 98 | const isHide = !hideTab ? null : currentActiveMenu; |
95 | 99 | const p = isHide || fullPath || path; |
... | ... | @@ -101,10 +105,11 @@ |
101 | 105 | const findParentRoute = router |
102 | 106 | .getRoutes() |
103 | 107 | .find((item) => item.path === currentActiveMenu); |
108 | + | |
104 | 109 | findParentRoute && |
105 | - tabStore.addTabAction((findParentRoute as unknown) as RouteLocationNormalized); | |
110 | + tabStore.addTab((findParentRoute as unknown) as RouteLocationNormalized); | |
106 | 111 | } else { |
107 | - tabStore.addTabAction(unref(route)); | |
112 | + tabStore.addTab(unref(route)); | |
108 | 113 | } |
109 | 114 | }); |
110 | 115 | |
... | ... | @@ -116,9 +121,11 @@ |
116 | 121 | // Close the current tab |
117 | 122 | function handleEdit(targetKey: string) { |
118 | 123 | // Added operation to hide, currently only use delete operation |
119 | - if (unref(unClose)) return; | |
124 | + if (unref(unClose)) { | |
125 | + return; | |
126 | + } | |
120 | 127 | |
121 | - tabStore.closeTabByKeyAction(targetKey); | |
128 | + tabStore.closeTabByKey(targetKey, router); | |
122 | 129 | } |
123 | 130 | return { |
124 | 131 | prefixCls, | ... | ... |
src/layouts/default/tabs/types.ts
... | ... | @@ -14,22 +14,12 @@ export interface TabContentProps { |
14 | 14 | trigger?: ('click' | 'hover' | 'contextmenu')[]; |
15 | 15 | } |
16 | 16 | |
17 | -/** | |
18 | - * @description: ๅณ้ฎ๏ผไธๆ่ๅๆๅญ | |
19 | - */ | |
20 | 17 | export enum MenuEventEnum { |
21 | - // ๅทๆฐ | |
22 | 18 | REFRESH_PAGE, |
23 | - // ๅ ณ้ญๅฝๅ | |
24 | 19 | CLOSE_CURRENT, |
25 | - // ๅ ณ้ญๅทฆไพง | |
26 | 20 | CLOSE_LEFT, |
27 | - // ๅ ณ้ญๅณไพง | |
28 | 21 | CLOSE_RIGHT, |
29 | - // ๅ ณ้ญๅ ถไป | |
30 | 22 | CLOSE_OTHER, |
31 | - // ๅ ณ้ญๆๆ | |
32 | 23 | CLOSE_ALL, |
33 | - // ๆพๅคง | |
34 | 24 | SCALE, |
35 | 25 | } | ... | ... |
src/layouts/default/tabs/useMultipleTabs.ts
1 | 1 | import { toRaw, ref, nextTick } from 'vue'; |
2 | -import { RouteLocationNormalized } from 'vue-router'; | |
2 | +import type { RouteLocationNormalized } from 'vue-router'; | |
3 | 3 | import { useDesign } from '/@/hooks/web/useDesign'; |
4 | 4 | import { useSortable } from '/@/hooks/web/useSortable'; |
5 | -import router from '/@/router'; | |
6 | -import { tabStore } from '/@/store/modules/tab'; | |
5 | +import { useMultipleTabStore } from '/@/store/modules/multipleTab'; | |
7 | 6 | import { isNullAndUnDef } from '/@/utils/is'; |
8 | 7 | import projectSetting from '/@/settings/projectSetting'; |
8 | +import { useRouter } from 'vue-router'; | |
9 | 9 | |
10 | 10 | export function initAffixTabs(): string[] { |
11 | 11 | const affixList = ref<RouteLocationNormalized[]>([]); |
12 | + | |
13 | + const tabStore = useMultipleTabStore(); | |
14 | + const router = useRouter(); | |
12 | 15 | /** |
13 | 16 | * @description: Filter all fixed routes |
14 | 17 | */ |
... | ... | @@ -30,7 +33,7 @@ export function initAffixTabs(): string[] { |
30 | 33 | const affixTabs = filterAffixTabs((router.getRoutes() as unknown) as RouteLocationNormalized[]); |
31 | 34 | affixList.value = affixTabs; |
32 | 35 | for (const tab of affixTabs) { |
33 | - tabStore.addTabAction(({ | |
36 | + tabStore.addTab(({ | |
34 | 37 | meta: tab.meta, |
35 | 38 | name: tab.name, |
36 | 39 | path: tab.path, |
... | ... | @@ -39,6 +42,7 @@ export function initAffixTabs(): string[] { |
39 | 42 | } |
40 | 43 | |
41 | 44 | let isAddAffix = false; |
45 | + | |
42 | 46 | if (!isAddAffix) { |
43 | 47 | addAffixTabs(); |
44 | 48 | isAddAffix = true; |
... | ... | @@ -47,8 +51,8 @@ export function initAffixTabs(): string[] { |
47 | 51 | } |
48 | 52 | |
49 | 53 | export function useTabsDrag(affixTextList: string[]) { |
54 | + const tabStore = useMultipleTabStore(); | |
50 | 55 | const { multiTabsSetting } = projectSetting; |
51 | - | |
52 | 56 | const { prefixCls } = useDesign('multiple-tabs'); |
53 | 57 | nextTick(() => { |
54 | 58 | if (!multiTabsSetting.canDrag) return; |
... | ... | @@ -66,7 +70,7 @@ export function useTabsDrag(affixTextList: string[]) { |
66 | 70 | return; |
67 | 71 | } |
68 | 72 | |
69 | - tabStore.commitSortTabs({ oldIndex, newIndex }); | |
73 | + tabStore.sortTabs(oldIndex, newIndex); | |
70 | 74 | }, |
71 | 75 | }); |
72 | 76 | initSortable(); | ... | ... |
src/layouts/default/tabs/useTabDropdown.ts
1 | 1 | import type { TabContentProps } from './types'; |
2 | 2 | import type { DropMenu } from '/@/components/Dropdown'; |
3 | +import type { ComputedRef } from 'vue'; | |
3 | 4 | |
4 | 5 | import { computed, unref, reactive } from 'vue'; |
5 | -import { TabContentEnum, MenuEventEnum } from './types'; | |
6 | -import { tabStore } from '/@/store/modules/tab'; | |
7 | -import router from '/@/router'; | |
8 | -import { RouteLocationNormalized } from 'vue-router'; | |
6 | +import { MenuEventEnum } from './types'; | |
7 | +import { useMultipleTabStore } from '/@/store/modules/multipleTab'; | |
8 | +import { RouteLocationNormalized, useRouter } from 'vue-router'; | |
9 | 9 | import { useTabs } from '/@/hooks/web/useTabs'; |
10 | 10 | import { useI18n } from '/@/hooks/web/useI18n'; |
11 | 11 | |
12 | -const { t } = useI18n(); | |
13 | - | |
14 | -export function useTabDropdown(tabContentProps: TabContentProps) { | |
12 | +export function useTabDropdown(tabContentProps: TabContentProps, getIsTabs: ComputedRef<boolean>) { | |
15 | 13 | const state = reactive({ |
16 | 14 | current: null as Nullable<RouteLocationNormalized>, |
17 | 15 | currentIndex: 0, |
18 | 16 | }); |
19 | 17 | |
20 | - const { currentRoute } = router; | |
21 | - | |
22 | - const isTabs = computed(() => tabContentProps.type === TabContentEnum.TAB_TYPE); | |
18 | + const { t } = useI18n(); | |
19 | + const tabStore = useMultipleTabStore(); | |
20 | + const { currentRoute } = useRouter(); | |
21 | + const { refreshPage, closeAll, close, closeLeft, closeOther, closeRight } = useTabs(); | |
23 | 22 | |
24 | - const getCurrentTab = computed( | |
23 | + const getTargetTab = computed( | |
25 | 24 | (): RouteLocationNormalized => { |
26 | - return unref(isTabs) ? tabContentProps.tabItem : unref(currentRoute); | |
25 | + return unref(getIsTabs) ? tabContentProps.tabItem : unref(currentRoute); | |
27 | 26 | } |
28 | 27 | ); |
29 | 28 | |
... | ... | @@ -31,8 +30,10 @@ export function useTabDropdown(tabContentProps: TabContentProps) { |
31 | 30 | * @description: drop-down list |
32 | 31 | */ |
33 | 32 | const getDropMenuList = computed(() => { |
34 | - if (!unref(getCurrentTab)) return; | |
35 | - const { meta } = unref(getCurrentTab); | |
33 | + if (!unref(getTargetTab)) { | |
34 | + return; | |
35 | + } | |
36 | + const { meta } = unref(getTargetTab); | |
36 | 37 | const { path } = unref(currentRoute); |
37 | 38 | |
38 | 39 | // Refresh button |
... | ... | @@ -42,11 +43,11 @@ export function useTabDropdown(tabContentProps: TabContentProps) { |
42 | 43 | // Close left |
43 | 44 | const closeLeftDisabled = index === 0; |
44 | 45 | |
45 | - const disabled = tabStore.getTabsState.length === 1; | |
46 | + const disabled = tabStore.getTabList.length === 1; | |
46 | 47 | |
47 | 48 | // Close right |
48 | 49 | const closeRightDisabled = |
49 | - index === tabStore.getTabsState.length - 1 && tabStore.getLastDragEndIndexState >= 0; | |
50 | + index === tabStore.getTabList.length - 1 && tabStore.getLastDragEndIndex >= 0; | |
50 | 51 | const dropMenuList: DropMenu[] = [ |
51 | 52 | { |
52 | 53 | icon: 'ion:reload-sharp', |
... | ... | @@ -58,7 +59,7 @@ export function useTabDropdown(tabContentProps: TabContentProps) { |
58 | 59 | icon: 'clarity:close-line', |
59 | 60 | event: MenuEventEnum.CLOSE_CURRENT, |
60 | 61 | text: t('layout.multipleTab.close'), |
61 | - disabled: meta?.affix || disabled, | |
62 | + disabled: !!meta?.affix || disabled, | |
62 | 63 | divider: true, |
63 | 64 | }, |
64 | 65 | { |
... | ... | @@ -92,15 +93,13 @@ export function useTabDropdown(tabContentProps: TabContentProps) { |
92 | 93 | return dropMenuList; |
93 | 94 | }); |
94 | 95 | |
95 | - const getTrigger = computed(() => { | |
96 | - return unref(isTabs) ? ['contextmenu'] : ['click']; | |
97 | - }); | |
98 | - | |
99 | 96 | function handleContextMenu(tabItem: RouteLocationNormalized) { |
100 | 97 | return (e: Event) => { |
101 | - if (!tabItem) return; | |
98 | + if (!tabItem) { | |
99 | + return; | |
100 | + } | |
102 | 101 | e?.preventDefault(); |
103 | - const index = tabStore.getTabsState.findIndex((tab) => tab.path === tabItem.path); | |
102 | + const index = tabStore.getTabList.findIndex((tab) => tab.path === tabItem.path); | |
104 | 103 | state.current = tabItem; |
105 | 104 | state.currentIndex = index; |
106 | 105 | }; |
... | ... | @@ -108,12 +107,8 @@ export function useTabDropdown(tabContentProps: TabContentProps) { |
108 | 107 | |
109 | 108 | // Handle right click event |
110 | 109 | function handleMenuEvent(menu: DropMenu): void { |
111 | - const { refreshPage, closeAll, close, closeLeft, closeOther, closeRight } = useTabs(); | |
112 | 110 | const { event } = menu; |
113 | 111 | switch (event) { |
114 | - case MenuEventEnum.SCALE: | |
115 | - scaleScreen(); | |
116 | - break; | |
117 | 112 | case MenuEventEnum.REFRESH_PAGE: |
118 | 113 | // refresh page |
119 | 114 | refreshPage(); |
... | ... | @@ -140,5 +135,5 @@ export function useTabDropdown(tabContentProps: TabContentProps) { |
140 | 135 | break; |
141 | 136 | } |
142 | 137 | } |
143 | - return { getDropMenuList, handleMenuEvent, handleContextMenu, getTrigger, isTabs }; | |
138 | + return { getDropMenuList, handleMenuEvent, handleContextMenu }; | |
144 | 139 | } | ... | ... |
src/layouts/iframe/useFrameKeepAlive.ts
... | ... | @@ -2,18 +2,19 @@ import type { AppRouteRecordRaw } from '/@/router/types'; |
2 | 2 | |
3 | 3 | import { computed, toRaw, unref } from 'vue'; |
4 | 4 | |
5 | -import { tabStore } from '/@/store/modules/tab'; | |
5 | +import { useMultipleTabStore } from '/@/store/modules/multipleTab'; | |
6 | 6 | |
7 | 7 | import { uniqBy } from 'lodash-es'; |
8 | 8 | |
9 | 9 | import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting'; |
10 | 10 | |
11 | -import router from '/@/router'; | |
11 | +import { useRouter } from 'vue-router'; | |
12 | 12 | |
13 | 13 | export function useFrameKeepAlive() { |
14 | + const router = useRouter(); | |
14 | 15 | const { currentRoute } = router; |
15 | 16 | const { getShowMultipleTab } = useMultipleTabSetting(); |
16 | - | |
17 | + const tabStore = useMultipleTabStore(); | |
17 | 18 | const getFramePages = computed(() => { |
18 | 19 | const ret = |
19 | 20 | getAllFramePages((toRaw(router.getRoutes()) as unknown) as AppRouteRecordRaw[]) || []; |
... | ... | @@ -21,7 +22,7 @@ export function useFrameKeepAlive() { |
21 | 22 | }); |
22 | 23 | |
23 | 24 | const getOpenTabList = computed((): string[] => { |
24 | - return tabStore.getTabsState.reduce((prev: string[], next) => { | |
25 | + return tabStore.getTabList.reduce((prev: string[], next) => { | |
25 | 26 | if (next.meta && Reflect.has(next.meta, 'frameSrc')) { |
26 | 27 | prev.push(next.name as string); |
27 | 28 | } | ... | ... |
src/layouts/page/index.vue
... | ... | @@ -35,13 +35,14 @@ |
35 | 35 | import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting'; |
36 | 36 | import { getTransitionName } from './transition'; |
37 | 37 | |
38 | - import { useStore } from 'vuex'; | |
38 | + import { useMultipleTabStore } from '/@/store/modules/multipleTab'; | |
39 | 39 | |
40 | 40 | export default defineComponent({ |
41 | 41 | name: 'PageLayout', |
42 | 42 | components: { FrameLayout }, |
43 | 43 | setup() { |
44 | 44 | const { getShowMultipleTab } = useMultipleTabSetting(); |
45 | + const tabStore = useMultipleTabStore(); | |
45 | 46 | |
46 | 47 | const { getOpenKeepAlive, getCanEmbedIFramePage } = useRootSetting(); |
47 | 48 | |
... | ... | @@ -49,15 +50,11 @@ |
49 | 50 | |
50 | 51 | const openCache = computed(() => unref(getOpenKeepAlive) && unref(getShowMultipleTab)); |
51 | 52 | |
52 | - const { getters } = useStore(); | |
53 | - | |
54 | 53 | const getCaches = computed((): string[] => { |
55 | 54 | if (!unref(getOpenKeepAlive)) { |
56 | 55 | return []; |
57 | 56 | } |
58 | - // TODO The useStore is used here mainly to solve the problem of circular dependency hot update | |
59 | - const cacheTabs = getters['app-tab/getCachedTabsState']; | |
60 | - return cacheTabs; | |
57 | + return tabStore.getCachedTabList; | |
61 | 58 | }); |
62 | 59 | |
63 | 60 | return { | ... | ... |
src/locales/setupI18n.ts
... | ... | @@ -3,14 +3,15 @@ import type { I18n, I18nOptions } from 'vue-i18n'; |
3 | 3 | |
4 | 4 | import { createI18n } from 'vue-i18n'; |
5 | 5 | |
6 | -import { localeStore } from '/@/store/modules/locale'; | |
7 | 6 | import { localeSetting } from '/@/settings/localeSetting'; |
7 | +import { useLocaleStoreWithOut } from '/@/store/modules/locale'; | |
8 | 8 | |
9 | 9 | const { fallback, availableLocales } = localeSetting; |
10 | 10 | |
11 | 11 | export let i18n: ReturnType<typeof createI18n>; |
12 | 12 | |
13 | 13 | async function createI18nOptions(): Promise<I18nOptions> { |
14 | + const localeStore = useLocaleStoreWithOut(); | |
14 | 15 | const locale = localeStore.getLocale; |
15 | 16 | const defaultLocal = await import(`./lang/${locale}.ts`); |
16 | 17 | const message = defaultLocal.default?.message ?? {}; | ... | ... |
src/locales/useLocale.ts
... | ... | @@ -6,7 +6,7 @@ import type { LocaleType } from '/#/config'; |
6 | 6 | import moment from 'moment'; |
7 | 7 | |
8 | 8 | import { i18n } from './setupI18n'; |
9 | -import { localeStore } from '/@/store/modules/locale'; | |
9 | +import { useLocaleStoreWithOut } from '/@/store/modules/locale'; | |
10 | 10 | import { unref, computed } from 'vue'; |
11 | 11 | |
12 | 12 | interface LangModule { |
... | ... | @@ -18,6 +18,8 @@ interface LangModule { |
18 | 18 | const loadLocalePool: LocaleType[] = []; |
19 | 19 | |
20 | 20 | function setI18nLanguage(locale: LocaleType) { |
21 | + const localeStore = useLocaleStoreWithOut(); | |
22 | + | |
21 | 23 | if (i18n.mode === 'legacy') { |
22 | 24 | i18n.global.locale = locale; |
23 | 25 | } else { |
... | ... | @@ -28,6 +30,7 @@ function setI18nLanguage(locale: LocaleType) { |
28 | 30 | } |
29 | 31 | |
30 | 32 | export function useLocale() { |
33 | + const localeStore = useLocaleStoreWithOut(); | |
31 | 34 | const getLocale = computed(() => localeStore.getLocale); |
32 | 35 | const getShowLocalePicker = computed(() => localeStore.getShowPicker); |
33 | 36 | |
... | ... | @@ -40,7 +43,9 @@ export function useLocale() { |
40 | 43 | async function changeLocale(locale: LocaleType) { |
41 | 44 | const globalI18n = i18n.global; |
42 | 45 | const currentLocale = unref(globalI18n.locale); |
43 | - if (currentLocale === locale) return locale; | |
46 | + if (currentLocale === locale) { | |
47 | + return locale; | |
48 | + } | |
44 | 49 | |
45 | 50 | if (loadLocalePool.includes(locale)) { |
46 | 51 | setI18nLanguage(locale); | ... | ... |
src/logics/error-handle/index.ts
... | ... | @@ -2,7 +2,10 @@ |
2 | 2 | * Used to configure the global error handling function, which can monitor vue errors, script errors, static resource errors and Promise errors |
3 | 3 | */ |
4 | 4 | |
5 | -import { errorStore, ErrorInfo } from '/@/store/modules/error'; | |
5 | +import type { ErrorLogInfo } from '/#/store'; | |
6 | + | |
7 | +import { useErrorLogStoreWithOut } from '/@/store/modules/errorLog'; | |
8 | + | |
6 | 9 | import { ErrorTypeEnum } from '/@/enums/exceptionEnum'; |
7 | 10 | import { App } from 'vue'; |
8 | 11 | import projectSetting from '/@/settings/projectSetting'; |
... | ... | @@ -61,8 +64,9 @@ function formatComponentName(vm: any) { |
61 | 64 | */ |
62 | 65 | |
63 | 66 | function vueErrorHandler(err: Error, vm: any, info: string) { |
67 | + const errorLogStore = useErrorLogStoreWithOut(); | |
64 | 68 | const { name, path } = formatComponentName(vm); |
65 | - errorStore.commitErrorInfoState({ | |
69 | + errorLogStore.addErrorLogInfo({ | |
66 | 70 | type: ErrorTypeEnum.VUE, |
67 | 71 | name, |
68 | 72 | file: path, |
... | ... | @@ -86,7 +90,7 @@ export function scriptErrorHandler( |
86 | 90 | if (event === 'Script error.' && !source) { |
87 | 91 | return false; |
88 | 92 | } |
89 | - const errorInfo: Partial<ErrorInfo> = {}; | |
93 | + const errorInfo: Partial<ErrorLogInfo> = {}; | |
90 | 94 | colno = colno || (window.event && (window.event as any).errorCharacter) || 0; |
91 | 95 | errorInfo.message = event as string; |
92 | 96 | if (error?.stack) { |
... | ... | @@ -95,13 +99,14 @@ export function scriptErrorHandler( |
95 | 99 | errorInfo.stack = ''; |
96 | 100 | } |
97 | 101 | const name = source ? source.substr(source.lastIndexOf('/') + 1) : 'script'; |
98 | - errorStore.commitErrorInfoState({ | |
102 | + const errorLogStore = useErrorLogStoreWithOut(); | |
103 | + errorLogStore.addErrorLogInfo({ | |
99 | 104 | type: ErrorTypeEnum.SCRIPT, |
100 | 105 | name: name, |
101 | 106 | file: source as string, |
102 | 107 | detail: 'lineno' + lineno, |
103 | 108 | url: window.location.href, |
104 | - ...(errorInfo as Pick<ErrorInfo, 'message' | 'stack'>), | |
109 | + ...(errorInfo as Pick<ErrorLogInfo, 'message' | 'stack'>), | |
105 | 110 | }); |
106 | 111 | return true; |
107 | 112 | } |
... | ... | @@ -112,8 +117,9 @@ export function scriptErrorHandler( |
112 | 117 | function registerPromiseErrorHandler() { |
113 | 118 | window.addEventListener( |
114 | 119 | 'unhandledrejection', |
115 | - function (event: any) { | |
116 | - errorStore.commitErrorInfoState({ | |
120 | + function (event) { | |
121 | + const errorLogStore = useErrorLogStoreWithOut(); | |
122 | + errorLogStore.addErrorLogInfo({ | |
117 | 123 | type: ErrorTypeEnum.PROMISE, |
118 | 124 | name: 'Promise Error!', |
119 | 125 | file: 'none', |
... | ... | @@ -136,10 +142,10 @@ function registerResourceErrorHandler() { |
136 | 142 | 'error', |
137 | 143 | function (e: Event) { |
138 | 144 | const target = e.target ? e.target : (e.srcElement as any); |
139 | - | |
140 | - errorStore.commitErrorInfoState({ | |
145 | + const errorLogStore = useErrorLogStoreWithOut(); | |
146 | + errorLogStore.addErrorLogInfo({ | |
141 | 147 | type: ErrorTypeEnum.RESOURCE, |
142 | - name: 'Resouce Error!', | |
148 | + name: 'Resource Error!', | |
143 | 149 | file: (e.target || ({} as any)).currentSrc, |
144 | 150 | detail: JSON.stringify({ |
145 | 151 | tagName: target.localName, |
... | ... | @@ -147,7 +153,7 @@ function registerResourceErrorHandler() { |
147 | 153 | type: e.type, |
148 | 154 | }), |
149 | 155 | url: window.location.href, |
150 | - stack: 'resouce is not found', | |
156 | + stack: 'resource is not found', | |
151 | 157 | message: (e.target || ({} as any)).localName + ' is load error', |
152 | 158 | }); |
153 | 159 | }, |
... | ... | @@ -161,7 +167,9 @@ function registerResourceErrorHandler() { |
161 | 167 | */ |
162 | 168 | export function setupErrorHandle(app: App) { |
163 | 169 | const { useErrorHandle } = projectSetting; |
164 | - if (!useErrorHandle) return; | |
170 | + if (!useErrorHandle) { | |
171 | + return; | |
172 | + } | |
165 | 173 | // Vue exception monitoring; |
166 | 174 | app.config.errorHandler = vueErrorHandler; |
167 | 175 | ... | ... |
src/logics/initAppConfig.ts
... | ... | @@ -12,18 +12,20 @@ import { updateGrayMode } from '/@/logics/theme/updateGrayMode'; |
12 | 12 | import { updateDarkTheme } from '/@/logics/theme/dark'; |
13 | 13 | import { changeTheme } from '/@/logics/theme'; |
14 | 14 | |
15 | -import { appStore } from '/@/store/modules/app'; | |
16 | -import { localeStore } from '/@/store/modules/locale'; | |
15 | +import { useAppStore } from '/@/store/modules/app'; | |
16 | +import { useLocaleStore } from '/@/store/modules/locale'; | |
17 | 17 | |
18 | 18 | import { getCommonStoragePrefix, getStorageShortName } from '/@/utils/env'; |
19 | 19 | |
20 | 20 | import { primaryColor } from '../../build/config/themeConfig'; |
21 | 21 | import { Persistent } from '/@/utils/cache/persistent'; |
22 | 22 | import { deepMerge } from '/@/utils'; |
23 | -import { ThemeEnum } from '../enums/appEnum'; | |
23 | +import { ThemeEnum } from '/@/enums/appEnum'; | |
24 | 24 | |
25 | 25 | // Initial project configuration |
26 | 26 | export function initAppConfigStore() { |
27 | + const localeStore = useLocaleStore(); | |
28 | + const appStore = useAppStore(); | |
27 | 29 | let projCfg: ProjectConfig = Persistent.getLocal(PROJ_CFG_KEY) as ProjectConfig; |
28 | 30 | projCfg = deepMerge(projectSetting, projCfg || {}); |
29 | 31 | const darkMode = appStore.getDarkMode; |
... | ... | @@ -45,7 +47,7 @@ export function initAppConfigStore() { |
45 | 47 | } catch (error) { |
46 | 48 | console.log(error); |
47 | 49 | } |
48 | - appStore.commitProjectConfigState(projCfg); | |
50 | + appStore.setProjectConfig(projCfg); | |
49 | 51 | |
50 | 52 | // init dark mode |
51 | 53 | updateDarkTheme(darkMode); | ... | ... |
src/logics/theme/updateBackground.ts
1 | 1 | import { colorIsDark, lighten, darken } from '/@/utils/color'; |
2 | -import { appStore } from '/@/store/modules/app'; | |
2 | +import { useAppStore } from '/@/store/modules/app'; | |
3 | 3 | import { ThemeEnum } from '/@/enums/appEnum'; |
4 | 4 | import { setCssVar } from './util'; |
5 | 5 | |
... | ... | @@ -16,12 +16,13 @@ const SIDER_LIGHTEN_BG_COLOR = '--sider-dark-lighten-bg-color'; |
16 | 16 | * @param color |
17 | 17 | */ |
18 | 18 | export function updateHeaderBgColor(color?: string) { |
19 | + const appStore = useAppStore(); | |
19 | 20 | const darkMode = appStore.getDarkMode === ThemeEnum.DARK; |
20 | 21 | if (!color) { |
21 | 22 | if (darkMode) { |
22 | 23 | color = '#151515'; |
23 | 24 | } else { |
24 | - color = appStore.getProjectConfig.headerSetting.bgColor; | |
25 | + color = appStore.getHeaderSetting.bgColor; | |
25 | 26 | } |
26 | 27 | } |
27 | 28 | // bg color |
... | ... | @@ -35,7 +36,7 @@ export function updateHeaderBgColor(color?: string) { |
35 | 36 | // Determine the depth of the color value and automatically switch the theme |
36 | 37 | const isDark = colorIsDark(color!); |
37 | 38 | |
38 | - appStore.commitProjectConfigState({ | |
39 | + appStore.setProjectConfig({ | |
39 | 40 | headerSetting: { |
40 | 41 | theme: isDark || darkMode ? ThemeEnum.DARK : ThemeEnum.LIGHT, |
41 | 42 | }, |
... | ... | @@ -47,13 +48,15 @@ export function updateHeaderBgColor(color?: string) { |
47 | 48 | * @param color bg color |
48 | 49 | */ |
49 | 50 | export function updateSidebarBgColor(color?: string) { |
51 | + const appStore = useAppStore(); | |
52 | + | |
50 | 53 | // if (!isHexColor(color)) return; |
51 | 54 | const darkMode = appStore.getDarkMode === ThemeEnum.DARK; |
52 | 55 | if (!color) { |
53 | 56 | if (darkMode) { |
54 | 57 | color = '#212121'; |
55 | 58 | } else { |
56 | - color = appStore.getProjectConfig.menuSetting.bgColor; | |
59 | + color = appStore.getMenuSetting.bgColor; | |
57 | 60 | } |
58 | 61 | } |
59 | 62 | setCssVar(SIDER_DARK_BG_COLOR, color); |
... | ... | @@ -64,7 +67,7 @@ export function updateSidebarBgColor(color?: string) { |
64 | 67 | // Only when the background color is #fff, the theme of the menu will be changed to light |
65 | 68 | const isLight = ['#fff', '#ffffff'].includes(color!.toLowerCase()); |
66 | 69 | |
67 | - appStore.commitProjectConfigState({ | |
70 | + appStore.setProjectConfig({ | |
68 | 71 | menuSetting: { |
69 | 72 | theme: isLight && !darkMode ? ThemeEnum.LIGHT : ThemeEnum.DARK, |
70 | 73 | }, | ... | ... |
src/main.ts
... | ... | @@ -5,15 +5,13 @@ import { createApp } from 'vue'; |
5 | 5 | import App from './App.vue'; |
6 | 6 | |
7 | 7 | import router, { setupRouter } from '/@/router'; |
8 | +import { setupRouterGuard } from '/@/router/guard'; | |
8 | 9 | import { setupStore } from '/@/store'; |
9 | 10 | import { setupErrorHandle } from '/@/logics/error-handle'; |
10 | 11 | import { setupGlobDirectives } from '/@/directives'; |
11 | 12 | import { setupI18n } from '/@/locales/setupI18n'; |
12 | 13 | import { registerGlobComp } from '/@/components/registerGlobComp'; |
13 | 14 | |
14 | -// router-guard | |
15 | -import '/@/router/guard'; | |
16 | - | |
17 | 15 | // Register icon Sprite |
18 | 16 | import 'vite-plugin-svg-icons/register'; |
19 | 17 | |
... | ... | @@ -27,6 +25,10 @@ if (import.meta.env.DEV) { |
27 | 25 | |
28 | 26 | (async () => { |
29 | 27 | const app = createApp(App); |
28 | + | |
29 | + // Configure vuex store | |
30 | + setupStore(app); | |
31 | + | |
30 | 32 | // Register global components |
31 | 33 | registerGlobComp(app); |
32 | 34 | |
... | ... | @@ -36,8 +38,8 @@ if (import.meta.env.DEV) { |
36 | 38 | // Configure routing |
37 | 39 | setupRouter(app); |
38 | 40 | |
39 | - // Configure vuex store | |
40 | - setupStore(app); | |
41 | + // router-guard | |
42 | + setupRouterGuard(); | |
41 | 43 | |
42 | 44 | // Register global directive |
43 | 45 | setupGlobDirectives(app); | ... | ... |
src/router/constant.ts
... | ... | @@ -20,13 +20,3 @@ export const getParentLayout = (_name?: string) => { |
20 | 20 | }); |
21 | 21 | }); |
22 | 22 | }; |
23 | - | |
24 | -// export const getParentLayout = (name: string) => { | |
25 | -// return () => | |
26 | -// new Promise((resolve) => { | |
27 | -// resolve({ | |
28 | -// ...ParentLayout, | |
29 | -// name, | |
30 | -// }); | |
31 | -// }); | |
32 | -// }; | ... | ... |
src/router/guard/index.ts
... | ... | @@ -9,11 +9,13 @@ import { createHttpGuard } from './httpGuard'; |
9 | 9 | import { createPageGuard } from './pageGuard'; |
10 | 10 | import { createStateGuard } from './stateGuard'; |
11 | 11 | |
12 | -createPageGuard(router); | |
13 | -createPageLoadingGuard(router); | |
14 | -createHttpGuard(router); | |
15 | -createScrollGuard(router); | |
16 | -createMessageGuard(router); | |
17 | -createProgressGuard(router); | |
18 | -createPermissionGuard(router); | |
19 | -createStateGuard(router); | |
12 | +export function setupRouterGuard() { | |
13 | + createPageGuard(router); | |
14 | + createPageLoadingGuard(router); | |
15 | + createHttpGuard(router); | |
16 | + createScrollGuard(router); | |
17 | + createMessageGuard(router); | |
18 | + createProgressGuard(router); | |
19 | + createPermissionGuard(router); | |
20 | + createStateGuard(router); | |
21 | +} | ... | ... |
src/router/guard/pageLoadingGuard.ts
1 | 1 | import type { Router } from 'vue-router'; |
2 | -import { appStore } from '/@/store/modules/app'; | |
3 | -import { userStore } from '/@/store/modules/user'; | |
2 | +import { useAppStoreWidthOut } from '/@/store/modules/app'; | |
3 | +import { useUserStoreWidthOut } from '/@/store/modules/user'; | |
4 | 4 | import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; |
5 | 5 | import { unref } from 'vue'; |
6 | 6 | |
7 | -const { getOpenPageLoading } = useTransitionSetting(); | |
8 | 7 | export function createPageLoadingGuard(router: Router) { |
8 | + const userStore = useUserStoreWidthOut(); | |
9 | + const appStore = useAppStoreWidthOut(); | |
10 | + const { getOpenPageLoading } = useTransitionSetting(); | |
9 | 11 | router.beforeEach(async (to) => { |
10 | - if (!userStore.getTokenState) { | |
12 | + if (!userStore.getToken) { | |
11 | 13 | return true; |
12 | 14 | } |
13 | 15 | if (to.meta.loaded) { |
... | ... | @@ -24,7 +26,7 @@ export function createPageLoadingGuard(router: Router) { |
24 | 26 | router.afterEach(async () => { |
25 | 27 | if (unref(getOpenPageLoading)) { |
26 | 28 | setTimeout(() => { |
27 | - appStore.commitPageLoadingState(false); | |
29 | + appStore.setPageLoading(false); | |
28 | 30 | }, 220); |
29 | 31 | } |
30 | 32 | return true; | ... | ... |
src/router/guard/permissionGuard.ts
1 | 1 | import type { Router, RouteRecordRaw } from 'vue-router'; |
2 | 2 | |
3 | -import { permissionStore } from '/@/store/modules/permission'; | |
3 | +import { usePermissionStoreWidthOut } from '/@/store/modules/permission'; | |
4 | 4 | |
5 | 5 | import { PageEnum } from '/@/enums/pageEnum'; |
6 | -import { userStore } from '/@/store/modules/user'; | |
6 | +import { useUserStoreWidthOut } from '/@/store/modules/user'; | |
7 | 7 | |
8 | 8 | import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic'; |
9 | 9 | |
... | ... | @@ -12,6 +12,8 @@ const LOGIN_PATH = PageEnum.BASE_LOGIN; |
12 | 12 | const whitePathList: PageEnum[] = [LOGIN_PATH]; |
13 | 13 | |
14 | 14 | export function createPermissionGuard(router: Router) { |
15 | + const userStore = useUserStoreWidthOut(); | |
16 | + const permissionStore = usePermissionStoreWidthOut(); | |
15 | 17 | router.beforeEach(async (to, from, next) => { |
16 | 18 | // Jump to the 404 page after processing the login |
17 | 19 | if (from.path === LOGIN_PATH && to.name === PAGE_NOT_FOUND_ROUTE.name) { |
... | ... | @@ -25,7 +27,7 @@ export function createPermissionGuard(router: Router) { |
25 | 27 | return; |
26 | 28 | } |
27 | 29 | |
28 | - const token = userStore.getTokenState; | |
30 | + const token = userStore.getToken; | |
29 | 31 | |
30 | 32 | // token does not exist |
31 | 33 | if (!token) { |
... | ... | @@ -51,7 +53,7 @@ export function createPermissionGuard(router: Router) { |
51 | 53 | next(redirectData); |
52 | 54 | return; |
53 | 55 | } |
54 | - if (permissionStore.getIsDynamicAddedRouteState) { | |
56 | + if (permissionStore.getIsDynamicAddedRoute) { | |
55 | 57 | next(); |
56 | 58 | return; |
57 | 59 | } |
... | ... | @@ -64,7 +66,7 @@ export function createPermissionGuard(router: Router) { |
64 | 66 | const redirectPath = (from.query.redirect || to.path) as string; |
65 | 67 | const redirect = decodeURIComponent(redirectPath); |
66 | 68 | const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect }; |
67 | - permissionStore.commitDynamicAddedRouteState(true); | |
69 | + permissionStore.setDynamicAddedRoute(true); | |
68 | 70 | next(nextData); |
69 | 71 | }); |
70 | 72 | } | ... | ... |
src/router/guard/progressGuard.ts
... | ... | @@ -6,9 +6,8 @@ import nProgress from 'nprogress'; |
6 | 6 | |
7 | 7 | import { unref } from 'vue'; |
8 | 8 | |
9 | -const { getOpenNProgress } = useTransitionSetting(); | |
10 | - | |
11 | 9 | export function createProgressGuard(router: Router) { |
10 | + const { getOpenNProgress } = useTransitionSetting(); | |
12 | 11 | router.beforeEach(async (to) => { |
13 | 12 | if (to.meta.loaded) return true; |
14 | 13 | unref(getOpenNProgress) && nProgress.start(); | ... | ... |
src/router/guard/stateGuard.ts
1 | 1 | import type { Router } from 'vue-router'; |
2 | -import { appStore } from '/@/store/modules/app'; | |
3 | -import { tabStore } from '/@/store/modules/tab'; | |
4 | -import { userStore } from '/@/store/modules/user'; | |
5 | -import { permissionStore } from '/@/store/modules/permission'; | |
2 | +import { useAppStore } from '/@/store/modules/app'; | |
3 | +import { useMultipleTabStore } from '/@/store/modules/multipleTab'; | |
4 | +import { useUserStore } from '/@/store/modules/user'; | |
5 | +import { usePermissionStore } from '/@/store/modules/permission'; | |
6 | 6 | import { PageEnum } from '/@/enums/pageEnum'; |
7 | 7 | import { removeTabChangeListener } from '/@/logics/mitt/routeChange'; |
8 | 8 | |
9 | 9 | export function createStateGuard(router: Router) { |
10 | 10 | router.afterEach((to) => { |
11 | + const tabStore = useMultipleTabStore(); | |
12 | + const userStore = useUserStore(); | |
13 | + const appStore = useAppStore(); | |
14 | + const permissionStore = usePermissionStore(); | |
11 | 15 | // Just enter the login page and clear the authentication information |
12 | 16 | if (to.path === PageEnum.BASE_LOGIN) { |
13 | - appStore.resumeAllState(); | |
14 | - permissionStore.commitResetState(); | |
15 | - tabStore.commitResetState(); | |
16 | - userStore.commitResetState(); | |
17 | + appStore.resetAllState(); | |
18 | + permissionStore.resetState(); | |
19 | + tabStore.resetState(); | |
20 | + userStore.resetState(); | |
17 | 21 | removeTabChangeListener(); |
18 | 22 | } |
19 | 23 | }); | ... | ... |
src/router/menus/index.ts
1 | 1 | import type { Menu, MenuModule } from '/@/router/types'; |
2 | 2 | import type { RouteRecordNormalized } from 'vue-router'; |
3 | 3 | |
4 | -import { appStore } from '/@/store/modules/app'; | |
5 | -import { permissionStore } from '/@/store/modules/permission'; | |
4 | +import { useAppStoreWidthOut } from '/@/store/modules/app'; | |
5 | +import { usePermissionStore } from '/@/store/modules/permission'; | |
6 | 6 | import { transformMenuModule, getAllParentPath } from '/@/router/helper/menuHelper'; |
7 | 7 | import { filter } from '/@/utils/helper/treeHelper'; |
8 | 8 | import { isUrl } from '/@/utils/is'; |
... | ... | @@ -24,6 +24,7 @@ Object.keys(modules).forEach((key) => { |
24 | 24 | // ==========Helper=========== |
25 | 25 | // =========================== |
26 | 26 | const isBackMode = () => { |
27 | + const appStore = useAppStoreWidthOut(); | |
27 | 28 | return appStore.getProjectConfig.permissionMode === PermissionModeEnum.BACK; |
28 | 29 | }; |
29 | 30 | |
... | ... | @@ -39,7 +40,8 @@ const staticMenus: Menu[] = []; |
39 | 40 | })(); |
40 | 41 | |
41 | 42 | async function getAsyncMenus() { |
42 | - return !isBackMode() ? staticMenus : permissionStore.getBackMenuListState; | |
43 | + const permissionStore = usePermissionStore(); | |
44 | + return !isBackMode() ? staticMenus : permissionStore.getBackMenuList; | |
43 | 45 | } |
44 | 46 | |
45 | 47 | export const getMenus = async (): Promise<Menu[]> => { | ... | ... |
src/settings/designSetting.ts
src/settings/projectSetting.ts
src/settings/siteSetting.ts
src/store/index.ts
1 | 1 | import type { App } from 'vue'; |
2 | -import { createStore } from 'vuex'; | |
3 | -import { config } from 'vuex-module-decorators'; | |
4 | -import { isDevMode } from '/@/utils/env'; | |
5 | - | |
6 | -config.rawError = true; | |
7 | - | |
8 | -const store = createStore({ | |
9 | - strict: isDevMode(), | |
10 | -}); | |
2 | +import { createPinia } from 'pinia'; | |
3 | +const store = createPinia(); | |
11 | 4 | |
12 | 5 | export function setupStore(app: App<Element>) { |
13 | 6 | app.use(store); |
14 | 7 | } |
15 | 8 | |
16 | -export default store; | |
9 | +export { store }; | ... | ... |
src/store/modules/app.ts
1 | 1 | import type { ProjectConfig } from '/#/config'; |
2 | -import type { BeforeMiniState } from '../types'; | |
2 | +import type { BeforeMiniState } from '/#/store'; | |
3 | 3 | |
4 | -import { VuexModule, getModule, Module, Mutation, Action } from 'vuex-module-decorators'; | |
5 | -import store from '/@/store'; | |
4 | +import { defineStore } from 'pinia'; | |
5 | +import { store } from '/@/store'; | |
6 | 6 | |
7 | -import { PROJ_CFG_KEY, APP_DARK_MODE_KEY_ } from '/@/enums/cacheEnum'; | |
8 | - | |
9 | -import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; | |
7 | +import { ThemeEnum } from '/@/enums/appEnum'; | |
8 | +import { APP_DARK_MODE_KEY_, PROJ_CFG_KEY } from '/@/enums/cacheEnum'; | |
10 | 9 | import { Persistent } from '/@/utils/cache/persistent'; |
11 | -import { deepMerge } from '/@/utils'; | |
12 | - | |
13 | -import { resetRouter } from '/@/router'; | |
14 | -import { ThemeEnum } from '../../enums/appEnum'; | |
15 | - | |
16 | 10 | import { darkMode } from '/@/settings/designSetting'; |
11 | +import { resetRouter } from '/@/router'; | |
12 | +import { deepMerge } from '/@/utils'; | |
17 | 13 | |
18 | -export interface LockInfo { | |
19 | - pwd: string | undefined; | |
20 | - isLock: boolean; | |
21 | -} | |
22 | - | |
23 | -let timeId: TimeoutHandle; | |
24 | -const NAME = 'app'; | |
25 | -hotModuleUnregisterModule(NAME); | |
26 | -@Module({ dynamic: true, namespaced: true, store, name: NAME }) | |
27 | -export default class App extends VuexModule { | |
28 | - private darkMode; | |
29 | - | |
14 | +interface AppState { | |
15 | + darkMode: ThemeEnum; | |
30 | 16 | // Page loading status |
31 | - private pageLoadingState = false; | |
32 | - | |
17 | + pageLoading: boolean; | |
33 | 18 | // project config |
34 | - private projectConfigState: ProjectConfig | null = Persistent.getLocal(PROJ_CFG_KEY); | |
35 | - | |
36 | - // set main overflow hidden | |
37 | - private lockMainScrollState = false; | |
38 | - | |
19 | + projectConfig: ProjectConfig | null; | |
39 | 20 | // When the window shrinks, remember some states, and restore these states when the window is restored |
40 | - private beforeMiniState: BeforeMiniState = {}; | |
41 | - | |
42 | - get getPageLoading() { | |
43 | - return this.pageLoadingState; | |
44 | - } | |
45 | - | |
46 | - get getDarkMode() { | |
47 | - return this.darkMode || localStorage.getItem(APP_DARK_MODE_KEY_) || darkMode; | |
48 | - } | |
49 | - | |
50 | - get getBeforeMiniState() { | |
51 | - return this.beforeMiniState; | |
52 | - } | |
53 | - | |
54 | - get getLockMainScrollState() { | |
55 | - return this.lockMainScrollState; | |
56 | - } | |
57 | - | |
58 | - get getProjectConfig(): ProjectConfig { | |
59 | - return this.projectConfigState || ({} as ProjectConfig); | |
60 | - } | |
61 | - | |
62 | - @Mutation | |
63 | - commitPageLoadingState(loading: boolean): void { | |
64 | - this.pageLoadingState = loading; | |
65 | - } | |
66 | - | |
67 | - @Mutation | |
68 | - commitDarkMode(mode: ThemeEnum): void { | |
69 | - this.darkMode = mode; | |
70 | - localStorage.setItem(APP_DARK_MODE_KEY_, mode); | |
71 | - } | |
72 | - | |
73 | - @Mutation | |
74 | - commitBeforeMiniState(state: BeforeMiniState): void { | |
75 | - this.beforeMiniState = state; | |
76 | - } | |
77 | - | |
78 | - @Mutation | |
79 | - commitLockMainScrollState(lock: boolean): void { | |
80 | - this.lockMainScrollState = lock; | |
81 | - } | |
82 | - | |
83 | - @Mutation | |
84 | - commitProjectConfigState(proCfg: DeepPartial<ProjectConfig>): void { | |
85 | - this.projectConfigState = deepMerge(this.projectConfigState || {}, proCfg); | |
86 | - Persistent.setLocal(PROJ_CFG_KEY, this.projectConfigState); | |
87 | - } | |
88 | - | |
89 | - @Action | |
90 | - async resumeAllState() { | |
91 | - resetRouter(); | |
92 | - Persistent.clearAll(); | |
93 | - } | |
94 | - | |
95 | - @Action | |
96 | - public async setPageLoadingAction(loading: boolean): Promise<void> { | |
97 | - if (loading) { | |
98 | - clearTimeout(timeId); | |
99 | - // Prevent flicker | |
100 | - timeId = setTimeout(() => { | |
101 | - this.commitPageLoadingState(loading); | |
102 | - }, 50); | |
103 | - } else { | |
104 | - this.commitPageLoadingState(loading); | |
105 | - clearTimeout(timeId); | |
106 | - } | |
107 | - } | |
21 | + beforeMiniInfo: BeforeMiniState; | |
22 | +} | |
23 | +let timeId: TimeoutHandle; | |
24 | +export const useAppStore = defineStore({ | |
25 | + id: 'app', | |
26 | + state: (): AppState => ({ | |
27 | + darkMode: ThemeEnum.LIGHT, | |
28 | + pageLoading: false, | |
29 | + projectConfig: Persistent.getLocal(PROJ_CFG_KEY), | |
30 | + beforeMiniInfo: {}, | |
31 | + }), | |
32 | + getters: { | |
33 | + getPageLoading() { | |
34 | + return this.pageLoading; | |
35 | + }, | |
36 | + getDarkMode() { | |
37 | + return this.darkMode || localStorage.getItem(APP_DARK_MODE_KEY_) || darkMode; | |
38 | + }, | |
39 | + | |
40 | + getBeforeMiniInfo() { | |
41 | + return this.beforeMiniInfo; | |
42 | + }, | |
43 | + | |
44 | + getProjectConfig(): ProjectConfig { | |
45 | + return this.projectConfig || ({} as ProjectConfig); | |
46 | + }, | |
47 | + | |
48 | + getHeaderSetting() { | |
49 | + return this.getProjectConfig.headerSetting; | |
50 | + }, | |
51 | + getMenuSetting() { | |
52 | + return this.getProjectConfig.menuSetting; | |
53 | + }, | |
54 | + getTransitionSetting() { | |
55 | + return this.getProjectConfig.transitionSetting; | |
56 | + }, | |
57 | + getMultiTabsSetting() { | |
58 | + return this.getProjectConfig.multiTabsSetting; | |
59 | + }, | |
60 | + }, | |
61 | + actions: { | |
62 | + setPageLoading(loading: boolean): void { | |
63 | + this.pageLoading = loading; | |
64 | + }, | |
65 | + | |
66 | + setDarkMode(mode: ThemeEnum): void { | |
67 | + this.darkMode = mode; | |
68 | + localStorage.setItem(APP_DARK_MODE_KEY_, mode); | |
69 | + }, | |
70 | + | |
71 | + setBeforeMiniInfo(state: BeforeMiniState): void { | |
72 | + this.beforeMiniInfo = state; | |
73 | + }, | |
74 | + | |
75 | + setProjectConfig(config: DeepPartial<ProjectConfig>): void { | |
76 | + this.projectConfig = deepMerge(this.projectConfig || {}, config); | |
77 | + Persistent.setLocal(PROJ_CFG_KEY, this.projectConfig); | |
78 | + }, | |
79 | + | |
80 | + async resetAllState() { | |
81 | + resetRouter(); | |
82 | + Persistent.clearAll(); | |
83 | + }, | |
84 | + async setPageLoadingAction(loading: boolean): Promise<void> { | |
85 | + if (loading) { | |
86 | + clearTimeout(timeId); | |
87 | + // Prevent flicker | |
88 | + timeId = setTimeout(() => { | |
89 | + this.setPageLoading(loading); | |
90 | + }, 50); | |
91 | + } else { | |
92 | + this.setPageLoading(loading); | |
93 | + clearTimeout(timeId); | |
94 | + } | |
95 | + }, | |
96 | + }, | |
97 | +}); | |
98 | + | |
99 | +// Need to be used outside the setup | |
100 | +export function useAppStoreWidthOut() { | |
101 | + return useAppStore(store); | |
108 | 102 | } |
109 | -export const appStore = getModule<App>(App); | ... | ... |
src/store/modules/error.ts deleted
100644 โ 0
1 | -import store from '/@/store'; | |
2 | -import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; | |
3 | -import { VuexModule, getModule, Module, Mutation, Action } from 'vuex-module-decorators'; | |
4 | - | |
5 | -import { formatToDateTime } from '/@/utils/dateUtil'; | |
6 | -import { ErrorTypeEnum } from '/@/enums/exceptionEnum'; | |
7 | -import projectSetting from '/@/settings/projectSetting'; | |
8 | - | |
9 | -export interface ErrorInfo { | |
10 | - type: ErrorTypeEnum; | |
11 | - file: string; | |
12 | - name?: string; | |
13 | - message: string; | |
14 | - stack?: string; | |
15 | - detail: string; | |
16 | - url: string; | |
17 | - time?: string; | |
18 | -} | |
19 | - | |
20 | -export interface ErrorState { | |
21 | - errorInfoState: ErrorInfo[] | null; | |
22 | - errorListCountState: number; | |
23 | -} | |
24 | - | |
25 | -const NAME = 'app-error'; | |
26 | -hotModuleUnregisterModule(NAME); | |
27 | -@Module({ dynamic: true, namespaced: true, store, name: NAME }) | |
28 | -class Error extends VuexModule implements ErrorState { | |
29 | - // error log list | |
30 | - errorInfoState: ErrorInfo[] = []; | |
31 | - | |
32 | - // error log count | |
33 | - errorListCountState = 0; | |
34 | - | |
35 | - get getErrorInfoState() { | |
36 | - return this.errorInfoState; | |
37 | - } | |
38 | - | |
39 | - get getErrorListCountState() { | |
40 | - return this.errorListCountState; | |
41 | - } | |
42 | - | |
43 | - @Mutation | |
44 | - commitErrorInfoState(info: ErrorInfo): void { | |
45 | - const item = { | |
46 | - ...info, | |
47 | - time: formatToDateTime(new Date()), | |
48 | - }; | |
49 | - this.errorInfoState = [item, ...this.errorInfoState]; | |
50 | - this.errorListCountState += 1; | |
51 | - } | |
52 | - | |
53 | - @Mutation | |
54 | - commitErrorListCountState(count: number): void { | |
55 | - this.errorListCountState = count; | |
56 | - } | |
57 | - | |
58 | - @Action | |
59 | - setupErrorHandle(error: any) { | |
60 | - const { useErrorHandle } = projectSetting; | |
61 | - if (!useErrorHandle) return; | |
62 | - | |
63 | - const errInfo: Partial<ErrorInfo> = { | |
64 | - message: error.message, | |
65 | - type: ErrorTypeEnum.AJAX, | |
66 | - }; | |
67 | - if (error.response) { | |
68 | - const { | |
69 | - config: { url = '', data: params = '', method = 'get', headers = {} } = {}, | |
70 | - data = {}, | |
71 | - } = error.response; | |
72 | - errInfo.url = url; | |
73 | - errInfo.name = 'Ajax Error!'; | |
74 | - errInfo.file = '-'; | |
75 | - errInfo.stack = JSON.stringify(data); | |
76 | - errInfo.detail = JSON.stringify({ params, method, headers }); | |
77 | - } | |
78 | - this.commitErrorInfoState(errInfo as ErrorInfo); | |
79 | - } | |
80 | -} | |
81 | -export const errorStore = getModule<Error>(Error); |
src/store/modules/errorLog.ts
0 โ 100644
1 | +import type { ErrorLogInfo } from '/#/store'; | |
2 | + | |
3 | +import { defineStore } from 'pinia'; | |
4 | +import { store } from '/@/store'; | |
5 | + | |
6 | +import { formatToDateTime } from '/@/utils/dateUtil'; | |
7 | +import projectSetting from '/@/settings/projectSetting'; | |
8 | + | |
9 | +import { ErrorTypeEnum } from '/@/enums/exceptionEnum'; | |
10 | + | |
11 | +export interface ErrorLogState { | |
12 | + errorLogInfoList: Nullable<ErrorLogInfo[]>; | |
13 | + errorLogListCount: number; | |
14 | +} | |
15 | + | |
16 | +export const useErrorLogStore = defineStore({ | |
17 | + id: 'app-error-log', | |
18 | + state: (): ErrorLogState => ({ | |
19 | + errorLogInfoList: null, | |
20 | + errorLogListCount: 0, | |
21 | + }), | |
22 | + getters: { | |
23 | + getErrorLogInfoList() { | |
24 | + return this.errorLogInfoList || []; | |
25 | + }, | |
26 | + getErrorLogListCount() { | |
27 | + return this.errorLogListCount; | |
28 | + }, | |
29 | + }, | |
30 | + actions: { | |
31 | + addErrorLogInfo(info: ErrorLogInfo) { | |
32 | + const item = { | |
33 | + ...info, | |
34 | + time: formatToDateTime(new Date()), | |
35 | + }; | |
36 | + this.errorLogInfoList = [item, ...(this.errorLogInfoList || [])]; | |
37 | + this.errorLogListCount += 1; | |
38 | + }, | |
39 | + | |
40 | + setErrorLogListCount(count: number): void { | |
41 | + this.errorLogListCount = count; | |
42 | + }, | |
43 | + | |
44 | + /** | |
45 | + * Triggered after ajax request error | |
46 | + * @param error | |
47 | + * @returns | |
48 | + */ | |
49 | + addAjaxErrorInfo(error) { | |
50 | + const { useErrorHandle } = projectSetting; | |
51 | + if (!useErrorHandle) { | |
52 | + return; | |
53 | + } | |
54 | + const errInfo: Partial<ErrorLogInfo> = { | |
55 | + message: error.message, | |
56 | + type: ErrorTypeEnum.AJAX, | |
57 | + }; | |
58 | + if (error.response) { | |
59 | + const { | |
60 | + config: { url = '', data: params = '', method = 'get', headers = {} } = {}, | |
61 | + data = {}, | |
62 | + } = error.response; | |
63 | + errInfo.url = url; | |
64 | + errInfo.name = 'Ajax Error!'; | |
65 | + errInfo.file = '-'; | |
66 | + errInfo.stack = JSON.stringify(data); | |
67 | + errInfo.detail = JSON.stringify({ params, method, headers }); | |
68 | + } | |
69 | + this.addErrorLogInfo(errInfo as ErrorLogInfo); | |
70 | + }, | |
71 | + }, | |
72 | +}); | |
73 | + | |
74 | +// Need to be used outside the setup | |
75 | +export function useErrorLogStoreWithOut() { | |
76 | + return useErrorLogStore(store); | |
77 | +} | ... | ... |
src/store/modules/locale.ts
1 | -import store from '/@/store'; | |
1 | +import type { LocaleSetting, LocaleType } from '/#/config'; | |
2 | 2 | |
3 | -import { VuexModule, getModule, Module, Mutation, Action } from 'vuex-module-decorators'; | |
3 | +import { defineStore } from 'pinia'; | |
4 | +import { store } from '/@/store'; | |
4 | 5 | |
5 | 6 | import { LOCALE_KEY } from '/@/enums/cacheEnum'; |
6 | - | |
7 | -import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; | |
8 | -import { LocaleSetting, LocaleType } from '/#/config'; | |
9 | 7 | import { createLocalStorage } from '/@/utils/cache'; |
10 | 8 | import { localeSetting } from '/@/settings/localeSetting'; |
11 | 9 | |
12 | 10 | const ls = createLocalStorage(); |
13 | 11 | |
14 | -const lsSetting = (ls.get(LOCALE_KEY) || localeSetting) as LocaleSetting; | |
15 | - | |
16 | -const NAME = 'app-locale'; | |
17 | -hotModuleUnregisterModule(NAME); | |
18 | -@Module({ dynamic: true, namespaced: true, store, name: NAME }) | |
19 | -class Locale extends VuexModule { | |
20 | - private info: LocaleSetting = lsSetting; | |
21 | - | |
22 | - get getShowPicker(): boolean { | |
23 | - return !!this.info?.showPicker; | |
24 | - } | |
12 | +const lsLocaleSetting = (ls.get(LOCALE_KEY) || localeSetting) as LocaleSetting; | |
25 | 13 | |
26 | - get getLocale(): LocaleType { | |
27 | - return this.info?.locale; | |
28 | - } | |
29 | - | |
30 | - @Mutation | |
31 | - setLocaleInfo(info: Partial<LocaleSetting>): void { | |
32 | - this.info = { ...this.info, ...info }; | |
33 | - ls.set(LOCALE_KEY, this.info); | |
34 | - } | |
14 | +interface LocaleState { | |
15 | + localInfo: LocaleSetting; | |
16 | +} | |
35 | 17 | |
36 | - @Action | |
37 | - initLocale(): void { | |
38 | - this.setLocaleInfo({ | |
39 | - ...localeSetting, | |
40 | - ...this.info, | |
41 | - }); | |
42 | - } | |
18 | +export const useLocaleStore = defineStore({ | |
19 | + id: 'app-locale', | |
20 | + state: (): LocaleState => ({ | |
21 | + localInfo: lsLocaleSetting, | |
22 | + }), | |
23 | + getters: { | |
24 | + getShowPicker() { | |
25 | + return !!this.localInfo?.showPicker; | |
26 | + }, | |
27 | + getLocale(): LocaleType { | |
28 | + return this.localInfo?.locale ?? 'zh_CN'; | |
29 | + }, | |
30 | + }, | |
31 | + actions: { | |
32 | + /** | |
33 | + * Set up multilingual information and cache | |
34 | + * @param info multilingual info | |
35 | + */ | |
36 | + setLocaleInfo(info: Partial<LocaleSetting>) { | |
37 | + this.localInfo = { ...this.localInfo, ...info }; | |
38 | + ls.set(LOCALE_KEY, this.localInfo); | |
39 | + }, | |
40 | + /** | |
41 | + * Initialize multilingual information and load the existing configuration from the local cache | |
42 | + */ | |
43 | + initLocale() { | |
44 | + this.setLocaleInfo({ | |
45 | + ...localeSetting, | |
46 | + ...this.localInfo, | |
47 | + }); | |
48 | + }, | |
49 | + }, | |
50 | +}); | |
51 | + | |
52 | +// Need to be used outside the setup | |
53 | +export function useLocaleStoreWithOut() { | |
54 | + return useLocaleStore(store); | |
43 | 55 | } |
44 | -export const localeStore = getModule<Locale>(Locale); | ... | ... |
src/store/modules/lock.ts
1 | -import type { LockInfo } from '/@/store/types'; | |
1 | +import type { LockInfo } from '/#/store'; | |
2 | 2 | |
3 | -import { VuexModule, getModule, Module, Mutation, Action } from 'vuex-module-decorators'; | |
4 | -import store from '/@/store'; | |
3 | +import { defineStore } from 'pinia'; | |
5 | 4 | |
6 | 5 | import { LOCK_INFO_KEY } from '/@/enums/cacheEnum'; |
7 | - | |
8 | -import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; | |
9 | 6 | import { Persistent } from '/@/utils/cache/persistent'; |
7 | +import { useUserStore } from './user'; | |
10 | 8 | |
11 | -import { userStore } from './user'; | |
12 | - | |
13 | -const NAME = 'app-lock'; | |
14 | -hotModuleUnregisterModule(NAME); | |
15 | -@Module({ dynamic: true, namespaced: true, store, name: NAME }) | |
16 | -class Lock extends VuexModule { | |
17 | - // lock info | |
18 | - private lockInfoState: LockInfo | null = Persistent.getLocal(LOCK_INFO_KEY); | |
19 | - | |
20 | - get getLockInfo(): LockInfo { | |
21 | - return this.lockInfoState || ({} as LockInfo); | |
22 | - } | |
23 | - | |
24 | - @Mutation | |
25 | - commitLockInfoState(info: LockInfo): void { | |
26 | - this.lockInfoState = Object.assign({}, this.lockInfoState, info); | |
27 | - Persistent.setLocal(LOCK_INFO_KEY, this.lockInfoState); | |
28 | - } | |
29 | - | |
30 | - @Mutation | |
31 | - resetLockInfo(): void { | |
32 | - Persistent.removeLocal(LOCK_INFO_KEY); | |
33 | - this.lockInfoState = null; | |
34 | - } | |
9 | +interface LockState { | |
10 | + lockInfo: Nullable<LockInfo>; | |
11 | +} | |
35 | 12 | |
36 | - /** | |
37 | - * @description: unlock page | |
38 | - */ | |
39 | - @Action | |
40 | - public async unLockAction({ password }: { password: string }) { | |
41 | - const tryLogin = async () => { | |
42 | - try { | |
43 | - const username = userStore.getUserInfoState.username; | |
44 | - const res = await userStore.login({ username, password, goHome: false, mode: 'none' }); | |
45 | - if (res) { | |
46 | - this.resetLockInfo(); | |
47 | - } | |
48 | - return res; | |
49 | - } catch (error) { | |
50 | - return false; | |
13 | +export const useLockStore = defineStore({ | |
14 | + id: 'app-lock', | |
15 | + state: (): LockState => ({ | |
16 | + lockInfo: Persistent.getLocal(LOCK_INFO_KEY), | |
17 | + }), | |
18 | + getters: { | |
19 | + getLockInfo() { | |
20 | + return this.lockInfo; | |
21 | + }, | |
22 | + }, | |
23 | + actions: { | |
24 | + setLockInfo(info: LockInfo) { | |
25 | + this.lockInfo = Object.assign({}, this.lockInfo, info); | |
26 | + Persistent.setLocal(LOCK_INFO_KEY, this.lockInfo); | |
27 | + }, | |
28 | + resetLockInfo() { | |
29 | + Persistent.removeLocal(LOCK_INFO_KEY); | |
30 | + this.lockInfo = null; | |
31 | + }, | |
32 | + // Unlock | |
33 | + async unLock(password?: string) { | |
34 | + const userStore = useUserStore(); | |
35 | + if (this.lockInfo?.pwd === password) { | |
36 | + this.resetLockInfo(); | |
37 | + return true; | |
51 | 38 | } |
52 | - }; | |
53 | - | |
54 | - if (this.getLockInfo?.pwd === password) { | |
55 | - this.resetLockInfo(); | |
56 | - return true; | |
57 | - } | |
58 | - return await tryLogin(); | |
59 | - } | |
60 | -} | |
61 | -export const lockStore = getModule<Lock>(Lock); | |
39 | + const tryLogin = async () => { | |
40 | + try { | |
41 | + const username = userStore.getUserInfo?.username; | |
42 | + const res = await userStore.login({ | |
43 | + username, | |
44 | + password: password!, | |
45 | + goHome: false, | |
46 | + mode: 'none', | |
47 | + }); | |
48 | + if (res) { | |
49 | + this.resetLockInfo(); | |
50 | + } | |
51 | + return res; | |
52 | + } catch (error) { | |
53 | + return false; | |
54 | + } | |
55 | + }; | |
56 | + return await tryLogin(); | |
57 | + }, | |
58 | + }, | |
59 | +}); | ... | ... |
src/store/modules/multipleTab.ts
0 โ 100644
1 | +import type { RouteLocationNormalized, RouteLocationRaw, Router } from 'vue-router'; | |
2 | + | |
3 | +import { toRaw, unref } from 'vue'; | |
4 | +import { defineStore } from 'pinia'; | |
5 | +import { store } from '/@/store'; | |
6 | + | |
7 | +import { useGo, useRedo } from '/@/hooks/web/usePage'; | |
8 | + | |
9 | +import { PageEnum } from '/@/enums/pageEnum'; | |
10 | +import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/routes/basic'; | |
11 | +import { getRawRoute } from '/@/utils'; | |
12 | + | |
13 | +export interface MultipleTabState { | |
14 | + cacheTabList: Set<string>; | |
15 | + tabList: RouteLocationNormalized[]; | |
16 | + lastDragEndIndex: number; | |
17 | +} | |
18 | + | |
19 | +function handleGotoPage(router: Router) { | |
20 | + const go = useGo(router); | |
21 | + go(unref(router.currentRoute).path, true); | |
22 | +} | |
23 | + | |
24 | +export const useMultipleTabStore = defineStore({ | |
25 | + id: 'app-multiple-tab', | |
26 | + state: (): MultipleTabState => ({ | |
27 | + // Tabs that need to be cached | |
28 | + cacheTabList: new Set(), | |
29 | + // multiple tab list | |
30 | + tabList: [], | |
31 | + // Index of the last moved tab | |
32 | + lastDragEndIndex: 0, | |
33 | + }), | |
34 | + getters: { | |
35 | + getTabList() { | |
36 | + return this.tabList; | |
37 | + }, | |
38 | + getCachedTabList(): string[] { | |
39 | + return Array.from(this.cacheTabList); | |
40 | + }, | |
41 | + getLastDragEndIndex(): number { | |
42 | + return this.lastDragEndIndex; | |
43 | + }, | |
44 | + }, | |
45 | + actions: { | |
46 | + /** | |
47 | + * Update the cache according to the currently opened tabs | |
48 | + */ | |
49 | + async updateCacheTab() { | |
50 | + const cacheMap: Set<string> = new Set(); | |
51 | + | |
52 | + for (const tab of this.tabList) { | |
53 | + const item = getRawRoute(tab); | |
54 | + // Ignore the cache | |
55 | + const needCache = !item.meta?.ignoreKeepAlive; | |
56 | + if (!needCache) { | |
57 | + return; | |
58 | + } | |
59 | + const name = item.name as string; | |
60 | + cacheMap.add(name); | |
61 | + } | |
62 | + this.cacheTabList = cacheMap; | |
63 | + }, | |
64 | + | |
65 | + /** | |
66 | + * Refresh tabs | |
67 | + */ | |
68 | + async refreshPage(router: Router) { | |
69 | + const { currentRoute } = router; | |
70 | + const route = unref(currentRoute); | |
71 | + const name = route.name; | |
72 | + | |
73 | + const findTab = this.getCachedTabList.find((item) => item === name); | |
74 | + if (findTab) { | |
75 | + this.cacheTabList.delete(findTab); | |
76 | + } | |
77 | + const redo = useRedo(router); | |
78 | + await redo(); | |
79 | + }, | |
80 | + clearCacheTabs(): void { | |
81 | + this.cacheTabList = new Set(); | |
82 | + }, | |
83 | + resetState(): void { | |
84 | + this.tabList = []; | |
85 | + this.clearCacheTabs(); | |
86 | + }, | |
87 | + goToPage(router: Router) { | |
88 | + const go = useGo(router); | |
89 | + const len = this.tabList.length; | |
90 | + const { path } = unref(router.currentRoute); | |
91 | + | |
92 | + let toPath: PageEnum | string = PageEnum.BASE_HOME; | |
93 | + | |
94 | + if (len > 0) { | |
95 | + const page = this.tabList[len - 1]; | |
96 | + const p = page.fullPath || page.path; | |
97 | + if (p) { | |
98 | + toPath = p; | |
99 | + } | |
100 | + } | |
101 | + // Jump to the current page and report an error | |
102 | + path !== toPath && go(toPath as PageEnum, true); | |
103 | + }, | |
104 | + | |
105 | + async addTab(route: RouteLocationNormalized) { | |
106 | + const { path, name, fullPath, params, query } = getRawRoute(route); | |
107 | + // 404 The page does not need to add a tab | |
108 | + if ( | |
109 | + path === PageEnum.ERROR_PAGE || | |
110 | + !name || | |
111 | + [REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes(name as string) | |
112 | + ) { | |
113 | + return; | |
114 | + } | |
115 | + | |
116 | + let updateIndex = -1; | |
117 | + // Existing pages, do not add tabs repeatedly | |
118 | + const tabHasExits = this.tabList.some((tab, index) => { | |
119 | + updateIndex = index; | |
120 | + return (tab.fullPath || tab.path) === (fullPath || path); | |
121 | + }); | |
122 | + | |
123 | + // If the tab already exists, perform the update operation | |
124 | + if (tabHasExits) { | |
125 | + const curTab = toRaw(this.tabList)[updateIndex]; | |
126 | + if (!curTab) { | |
127 | + return; | |
128 | + } | |
129 | + curTab.params = params || curTab.params; | |
130 | + curTab.query = query || curTab.query; | |
131 | + curTab.fullPath = fullPath || curTab.fullPath; | |
132 | + this.tabList.splice(updateIndex, 1, curTab); | |
133 | + return; | |
134 | + } | |
135 | + // Add tab | |
136 | + this.tabList.push(route); | |
137 | + this.updateCacheTab(); | |
138 | + }, | |
139 | + | |
140 | + async closeTab(tab: RouteLocationNormalized, router: Router) { | |
141 | + const getToTarget = (tabItem: RouteLocationNormalized) => { | |
142 | + const { params, path, query } = tabItem; | |
143 | + return { | |
144 | + params: params || {}, | |
145 | + path, | |
146 | + query: query || {}, | |
147 | + }; | |
148 | + }; | |
149 | + | |
150 | + const close = (route: RouteLocationNormalized) => { | |
151 | + const { fullPath, meta: { affix } = {} } = route; | |
152 | + if (affix) { | |
153 | + return; | |
154 | + } | |
155 | + const index = this.tabList.findIndex((item) => item.fullPath === fullPath); | |
156 | + index !== -1 && this.tabList.splice(index, 1); | |
157 | + }; | |
158 | + | |
159 | + const { currentRoute, replace } = router; | |
160 | + | |
161 | + const { path } = unref(currentRoute); | |
162 | + if (path !== tab.path) { | |
163 | + // Closed is not the activation tab | |
164 | + close(tab); | |
165 | + return; | |
166 | + } | |
167 | + | |
168 | + // Closed is activated atb | |
169 | + let toTarget: RouteLocationRaw = {}; | |
170 | + | |
171 | + const index = this.tabList.findIndex((item) => item.path === path); | |
172 | + | |
173 | + // If the current is the leftmost tab | |
174 | + if (index === 0) { | |
175 | + // There is only one tab, then jump to the homepage, otherwise jump to the right tab | |
176 | + if (this.tabList.length === 1) { | |
177 | + toTarget = PageEnum.BASE_HOME; | |
178 | + } else { | |
179 | + // Jump to the right tab | |
180 | + const page = this.tabList[index + 1]; | |
181 | + toTarget = getToTarget(page); | |
182 | + } | |
183 | + } else { | |
184 | + // Close the current tab | |
185 | + const page = this.tabList[index - 1]; | |
186 | + toTarget = getToTarget(page); | |
187 | + } | |
188 | + close(currentRoute.value); | |
189 | + replace(toTarget); | |
190 | + }, | |
191 | + | |
192 | + // Close according to key | |
193 | + async closeTabByKey(key: string, router: Router) { | |
194 | + const index = this.tabList.findIndex((item) => (item.fullPath || item.path) === key); | |
195 | + index !== -1 && this.closeTab(this.tabList[index], router); | |
196 | + }, | |
197 | + | |
198 | + // Sort the tabs | |
199 | + async sortTabs(oldIndex: number, newIndex: number) { | |
200 | + const currentTab = this.tabList[oldIndex]; | |
201 | + this.tabList.splice(oldIndex, 1); | |
202 | + this.tabList.splice(newIndex, 0, currentTab); | |
203 | + this.lastDragEndIndex = this.lastDragEndIndex + 1; | |
204 | + }, | |
205 | + | |
206 | + // Close the tab on the right and jump | |
207 | + async closeLeftTabs(route: RouteLocationNormalized, router: Router) { | |
208 | + const index = this.tabList.findIndex((item) => item.path === route.path); | |
209 | + | |
210 | + if (index > 0) { | |
211 | + const leftTabs = this.tabList.slice(0, index); | |
212 | + const pathList: string[] = []; | |
213 | + for (const item of leftTabs) { | |
214 | + const affix = item?.meta?.affix ?? false; | |
215 | + if (!affix) { | |
216 | + pathList.push(item.fullPath); | |
217 | + } | |
218 | + } | |
219 | + this.bulkCloseTabs(pathList); | |
220 | + } | |
221 | + this.updateCacheTab(); | |
222 | + handleGotoPage(router); | |
223 | + }, | |
224 | + | |
225 | + // Close the tab on the left and jump | |
226 | + async closeRightTabs(route: RouteLocationNormalized, router: Router) { | |
227 | + const index = this.tabList.findIndex((item) => item.fullPath === route.fullPath); | |
228 | + | |
229 | + if (index >= 0 && index < this.tabList.length - 1) { | |
230 | + const rightTabs = this.tabList.slice(index + 1, this.tabList.length); | |
231 | + | |
232 | + const pathList: string[] = []; | |
233 | + for (const item of rightTabs) { | |
234 | + const affix = item?.meta?.affix ?? false; | |
235 | + if (!affix) { | |
236 | + pathList.push(item.fullPath); | |
237 | + } | |
238 | + } | |
239 | + this.bulkCloseTabs(pathList); | |
240 | + } | |
241 | + this.updateCacheTab(); | |
242 | + handleGotoPage(router); | |
243 | + }, | |
244 | + | |
245 | + async closeAllTab(router: Router) { | |
246 | + this.tabList = this.tabList.filter((item) => item?.meta?.affix ?? false); | |
247 | + this.clearCacheTabs(); | |
248 | + this.goToPage(router); | |
249 | + }, | |
250 | + | |
251 | + /** | |
252 | + * Close other tabs | |
253 | + */ | |
254 | + async closeOtherTabs(route: RouteLocationNormalized, router: Router) { | |
255 | + const closePathList = this.tabList.map((item) => item.fullPath); | |
256 | + | |
257 | + const pathList: string[] = []; | |
258 | + | |
259 | + for (const path of closePathList) { | |
260 | + if (path !== route.fullPath) { | |
261 | + const closeItem = this.tabList.find((item) => item.path === path); | |
262 | + if (!closeItem) { | |
263 | + return; | |
264 | + } | |
265 | + const affix = closeItem?.meta?.affix ?? false; | |
266 | + if (!affix) { | |
267 | + pathList.push(closeItem.fullPath); | |
268 | + } | |
269 | + } | |
270 | + } | |
271 | + this.bulkCloseTabs(pathList); | |
272 | + this.updateCacheTab(); | |
273 | + handleGotoPage(router); | |
274 | + }, | |
275 | + | |
276 | + /** | |
277 | + * Close tabs in bulk | |
278 | + */ | |
279 | + async bulkCloseTabs(pathList: string[]) { | |
280 | + this.tabList = this.tabList.filter((item) => !pathList.includes(item.fullPath)); | |
281 | + }, | |
282 | + }, | |
283 | +}); | |
284 | + | |
285 | +// Need to be used outside the setup | |
286 | +export function useMultipleTabWithOutStore() { | |
287 | + return useMultipleTabStore(store); | |
288 | +} | ... | ... |
src/store/modules/permission.ts
1 | 1 | import type { AppRouteRecordRaw, Menu } from '/@/router/types'; |
2 | 2 | |
3 | -import store from '/@/store'; | |
3 | +import { defineStore } from 'pinia'; | |
4 | +import { store } from '/@/store'; | |
5 | +import { useI18n } from '/@/hooks/web/useI18n'; | |
6 | +import { useUserStore } from './user'; | |
7 | +import { useAppStoreWidthOut } from './app'; | |
4 | 8 | import { toRaw } from 'vue'; |
5 | -import { VuexModule, Mutation, Module, getModule, Action } from 'vuex-module-decorators'; | |
9 | +import { transformObjToRoute, flatMultiLevelRoutes } from '/@/router/helper/routeHelper'; | |
10 | +import { transformRouteToMenu } from '/@/router/helper/menuHelper'; | |
6 | 11 | |
7 | -import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; | |
12 | +import projectSetting from '/@/settings/projectSetting'; | |
8 | 13 | |
9 | 14 | import { PermissionModeEnum } from '/@/enums/appEnum'; |
10 | 15 | |
11 | -import { appStore } from '/@/store/modules/app'; | |
12 | -import { userStore } from '/@/store/modules/user'; | |
13 | -import projectSetting from '/@/settings/projectSetting'; | |
14 | - | |
15 | 16 | import { asyncRoutes } from '/@/router/routes'; |
16 | 17 | import { ERROR_LOG_ROUTE, PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic'; |
17 | -import { transformObjToRoute, flatMultiLevelRoutes } from '/@/router/helper/routeHelper'; | |
18 | -import { transformRouteToMenu } from '/@/router/helper/menuHelper'; | |
19 | 18 | |
20 | 19 | import { filter } from '/@/utils/helper/treeHelper'; |
21 | 20 | |
... | ... | @@ -23,125 +22,127 @@ import { getMenuListById } from '/@/api/sys/menu'; |
23 | 22 | import { getPermCodeByUserId } from '/@/api/sys/user'; |
24 | 23 | |
25 | 24 | import { useMessage } from '/@/hooks/web/useMessage'; |
26 | -import { useI18n } from '/@/hooks/web/useI18n'; | |
27 | 25 | |
28 | -const NAME = 'app-permission'; | |
29 | -hotModuleUnregisterModule(NAME); | |
30 | -@Module({ dynamic: true, namespaced: true, store, name: NAME }) | |
31 | -class Permission extends VuexModule { | |
26 | +interface PermissionState { | |
32 | 27 | // Permission code list |
33 | - private permCodeListState: string[] = []; | |
34 | - | |
28 | + permCodeList: string[]; | |
35 | 29 | // Whether the route has been dynamically added |
36 | - private isDynamicAddedRouteState = false; | |
37 | - | |
30 | + isDynamicAddedRoute: boolean; | |
38 | 31 | // To trigger a menu update |
39 | - private lastBuildMenuTimeState = 0; | |
40 | - | |
32 | + lastBuildMenuTime: number; | |
41 | 33 | // Backstage menu list |
42 | - private backMenuListState: Menu[] = []; | |
43 | - | |
44 | - get getPermCodeListState() { | |
45 | - return this.permCodeListState; | |
46 | - } | |
47 | - | |
48 | - get getBackMenuListState() { | |
49 | - return this.backMenuListState; | |
50 | - } | |
51 | - | |
52 | - get getLastBuildMenuTimeState() { | |
53 | - return this.lastBuildMenuTimeState; | |
54 | - } | |
55 | - | |
56 | - get getIsDynamicAddedRouteState() { | |
57 | - return this.isDynamicAddedRouteState; | |
58 | - } | |
59 | - | |
60 | - @Mutation | |
61 | - commitPermCodeListState(codeList: string[]): void { | |
62 | - this.permCodeListState = codeList; | |
63 | - } | |
64 | - | |
65 | - @Mutation | |
66 | - commitBackMenuListState(list: Menu[]): void { | |
67 | - this.backMenuListState = list; | |
68 | - } | |
69 | - | |
70 | - @Mutation | |
71 | - commitLastBuildMenuTimeState(): void { | |
72 | - this.lastBuildMenuTimeState = new Date().getTime(); | |
73 | - } | |
74 | - | |
75 | - @Mutation | |
76 | - commitDynamicAddedRouteState(added: boolean): void { | |
77 | - this.isDynamicAddedRouteState = added; | |
78 | - } | |
79 | - | |
80 | - @Mutation | |
81 | - commitResetState(): void { | |
82 | - this.isDynamicAddedRouteState = false; | |
83 | - this.permCodeListState = []; | |
84 | - this.backMenuListState = []; | |
85 | - this.lastBuildMenuTimeState = 0; | |
86 | - } | |
87 | - | |
88 | - @Action | |
89 | - async changePermissionCode(userId: string) { | |
90 | - const codeList = await getPermCodeByUserId({ userId }); | |
91 | - this.commitPermCodeListState(codeList); | |
92 | - } | |
93 | - | |
94 | - @Action | |
95 | - async buildRoutesAction(id?: number | string): Promise<AppRouteRecordRaw[]> { | |
96 | - const { t } = useI18n(); | |
97 | - let routes: AppRouteRecordRaw[] = []; | |
98 | - const roleList = toRaw(userStore.getRoleListState); | |
99 | - const { permissionMode = projectSetting.permissionMode } = appStore.getProjectConfig; | |
100 | - // role permissions | |
101 | - if (permissionMode === PermissionModeEnum.ROLE) { | |
102 | - const routeFilter = (route: AppRouteRecordRaw) => { | |
103 | - const { meta } = route; | |
104 | - const { roles } = meta || {}; | |
105 | - if (!roles) return true; | |
106 | - return roleList.some((role) => roles.includes(role)); | |
107 | - }; | |
108 | - routes = filter(asyncRoutes, routeFilter); | |
109 | - routes = routes.filter(routeFilter); | |
110 | - // Convert multi-level routing to level 2 routing | |
111 | - routes = flatMultiLevelRoutes(routes); | |
112 | - // If you are sure that you do not need to do background dynamic permissions, please comment the entire judgment below | |
113 | - } else if (permissionMode === PermissionModeEnum.BACK) { | |
114 | - const { createMessage } = useMessage(); | |
115 | - | |
116 | - createMessage.loading({ | |
117 | - content: t('sys.app.menuLoading'), | |
118 | - duration: 1, | |
119 | - }); | |
120 | - // Here to get the background routing menu logic to modify by yourself | |
121 | - const paramId = id || userStore.getUserInfoState.userId; | |
122 | - | |
123 | - // !Simulate to obtain permission codes from the background, | |
124 | - // this function may only need to be executed once, and the actual project can be put at the right time by itself | |
125 | - try { | |
126 | - this.changePermissionCode('1'); | |
127 | - } catch (error) {} | |
128 | - if (!paramId) { | |
129 | - throw new Error('paramId is undefined!'); | |
34 | + backMenuList: Menu[]; | |
35 | +} | |
36 | +export const usePermissionStore = defineStore({ | |
37 | + id: 'app-permission', | |
38 | + state: (): PermissionState => ({ | |
39 | + permCodeList: [], | |
40 | + // Whether the route has been dynamically added | |
41 | + isDynamicAddedRoute: false, | |
42 | + // To trigger a menu update | |
43 | + lastBuildMenuTime: 0, | |
44 | + // Backstage menu list | |
45 | + backMenuList: [], | |
46 | + }), | |
47 | + getters: { | |
48 | + getPermCodeList() { | |
49 | + return this.permCodeList; | |
50 | + }, | |
51 | + getBackMenuList() { | |
52 | + return this.backMenuList; | |
53 | + }, | |
54 | + getLastBuildMenuTime() { | |
55 | + return this.lastBuildMenuTime; | |
56 | + }, | |
57 | + getIsDynamicAddedRoute() { | |
58 | + return this.isDynamicAddedRoute; | |
59 | + }, | |
60 | + }, | |
61 | + actions: { | |
62 | + setPermCodeList(codeList: string[]) { | |
63 | + this.permCodeList = codeList; | |
64 | + }, | |
65 | + | |
66 | + setBackMenuList(list: Menu[]) { | |
67 | + this.backMenuList = list; | |
68 | + }, | |
69 | + | |
70 | + setLastBuildMenuTime() { | |
71 | + this.lastBuildMenuTime = new Date().getTime(); | |
72 | + }, | |
73 | + | |
74 | + setDynamicAddedRoute(added: boolean) { | |
75 | + this.isDynamicAddedRoute = added; | |
76 | + }, | |
77 | + resetState(): void { | |
78 | + this.isDynamicAddedRoute = false; | |
79 | + this.permCodeList = []; | |
80 | + this.backMenuList = []; | |
81 | + this.lastBuildMenuTime = 0; | |
82 | + }, | |
83 | + async changePermissionCode(userId: string) { | |
84 | + const codeList = await getPermCodeByUserId({ userId }); | |
85 | + this.setPermCodeList(codeList); | |
86 | + }, | |
87 | + async buildRoutesAction(id?: number | string): Promise<AppRouteRecordRaw[]> { | |
88 | + const { t } = useI18n(); | |
89 | + const userStore = useUserStore(); | |
90 | + const appStore = useAppStoreWidthOut(); | |
91 | + | |
92 | + let routes: AppRouteRecordRaw[] = []; | |
93 | + const roleList = toRaw(userStore.getRoleList); | |
94 | + const { permissionMode = projectSetting.permissionMode } = appStore.getProjectConfig; | |
95 | + // role permissions | |
96 | + if (permissionMode === PermissionModeEnum.ROLE) { | |
97 | + const routeFilter = (route: AppRouteRecordRaw) => { | |
98 | + const { meta } = route; | |
99 | + const { roles } = meta || {}; | |
100 | + if (!roles) return true; | |
101 | + return roleList.some((role) => roles.includes(role)); | |
102 | + }; | |
103 | + routes = filter(asyncRoutes, routeFilter); | |
104 | + routes = routes.filter(routeFilter); | |
105 | + // Convert multi-level routing to level 2 routing | |
106 | + routes = flatMultiLevelRoutes(routes); | |
107 | + // If you are sure that you do not need to do background dynamic permissions, please comment the entire judgment below | |
108 | + } else if (permissionMode === PermissionModeEnum.BACK) { | |
109 | + const { createMessage } = useMessage(); | |
110 | + | |
111 | + createMessage.loading({ | |
112 | + content: t('sys.app.menuLoading'), | |
113 | + duration: 1, | |
114 | + }); | |
115 | + // Here to get the background routing menu logic to modify by yourself | |
116 | + const paramId = id || userStore.getUserInfo?.userId; | |
117 | + | |
118 | + // !Simulate to obtain permission codes from the background, | |
119 | + // this function may only need to be executed once, and the actual project can be put at the right time by itself | |
120 | + try { | |
121 | + this.changePermissionCode('1'); | |
122 | + } catch (error) {} | |
123 | + | |
124 | + if (!paramId) { | |
125 | + throw new Error('paramId is undefined!'); | |
126 | + } | |
127 | + let routeList = (await getMenuListById({ id: paramId })) as AppRouteRecordRaw[]; | |
128 | + | |
129 | + // Dynamically introduce components | |
130 | + routeList = transformObjToRoute(routeList); | |
131 | + | |
132 | + // Background routing to menu structure | |
133 | + const backMenuList = transformRouteToMenu(routeList); | |
134 | + this.setBackMenuList(backMenuList); | |
135 | + | |
136 | + routeList = flatMultiLevelRoutes(routeList); | |
137 | + routes = [PAGE_NOT_FOUND_ROUTE, ...routeList]; | |
130 | 138 | } |
131 | - let routeList = (await getMenuListById({ id: paramId })) as AppRouteRecordRaw[]; | |
132 | - | |
133 | - // Dynamically introduce components | |
134 | - routeList = transformObjToRoute(routeList); | |
135 | - | |
136 | - // Background routing to menu structure | |
137 | - const backMenuList = transformRouteToMenu(routeList); | |
138 | - this.commitBackMenuListState(backMenuList); | |
139 | - | |
140 | - routeList = flatMultiLevelRoutes(routeList); | |
141 | - routes = [PAGE_NOT_FOUND_ROUTE, ...routeList]; | |
142 | - } | |
143 | - routes.push(ERROR_LOG_ROUTE); | |
144 | - return routes; | |
145 | - } | |
139 | + routes.push(ERROR_LOG_ROUTE); | |
140 | + return routes; | |
141 | + }, | |
142 | + }, | |
143 | +}); | |
144 | + | |
145 | +// Need to be used outside the setup | |
146 | +export function usePermissionStoreWidthOut() { | |
147 | + return usePermissionStore(store); | |
146 | 148 | } |
147 | -export const permissionStore = getModule<Permission>(Permission); | ... | ... |
src/store/modules/tab.ts deleted
100644 โ 0
1 | -import type { RouteLocationNormalized, RouteLocationRaw } from 'vue-router'; | |
2 | - | |
3 | -import { toRaw, unref } from 'vue'; | |
4 | -import { Action, Module, Mutation, VuexModule, getModule } from 'vuex-module-decorators'; | |
5 | -import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; | |
6 | - | |
7 | -import { PageEnum } from '/@/enums/pageEnum'; | |
8 | - | |
9 | -import store from '/@/store'; | |
10 | -import router from '/@/router'; | |
11 | -import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/routes/basic'; | |
12 | -import { getRawRoute } from '/@/utils'; | |
13 | - | |
14 | -import { useGo, useRedo } from '/@/hooks/web/usePage'; | |
15 | -import { cloneDeep } from 'lodash-es'; | |
16 | - | |
17 | -const NAME = 'app-tab'; | |
18 | - | |
19 | -hotModuleUnregisterModule(NAME); | |
20 | - | |
21 | -function isGotoPage() { | |
22 | - const go = useGo(); | |
23 | - go(unref(router.currentRoute).path, true); | |
24 | -} | |
25 | - | |
26 | -@Module({ namespaced: true, name: NAME, dynamic: true, store }) | |
27 | -class Tab extends VuexModule { | |
28 | - cachedTabsState: Set<string> = new Set(); | |
29 | - | |
30 | - // tab list | |
31 | - tabsState: RouteLocationNormalized[] = []; | |
32 | - | |
33 | - lastDragEndIndexState = 0; | |
34 | - | |
35 | - get getTabsState() { | |
36 | - return this.tabsState; | |
37 | - } | |
38 | - | |
39 | - get getCurrentTab(): RouteLocationNormalized { | |
40 | - const route = unref(router.currentRoute); | |
41 | - return this.tabsState.find((item) => item.path === route.path)!; | |
42 | - } | |
43 | - | |
44 | - get getCachedTabsState(): string[] { | |
45 | - return Array.from(this.cachedTabsState); | |
46 | - } | |
47 | - | |
48 | - get getLastDragEndIndexState(): number { | |
49 | - return this.lastDragEndIndexState; | |
50 | - } | |
51 | - | |
52 | - @Mutation | |
53 | - commitClearCache(): void { | |
54 | - this.cachedTabsState = new Set(); | |
55 | - } | |
56 | - | |
57 | - @Mutation | |
58 | - goToPage() { | |
59 | - const go = useGo(); | |
60 | - const len = this.tabsState.length; | |
61 | - const { path } = unref(router.currentRoute); | |
62 | - | |
63 | - let toPath: PageEnum | string = PageEnum.BASE_HOME; | |
64 | - | |
65 | - if (len > 0) { | |
66 | - const page = this.tabsState[len - 1]; | |
67 | - const p = page.fullPath || page.path; | |
68 | - if (p) { | |
69 | - toPath = p; | |
70 | - } | |
71 | - } | |
72 | - // Jump to the current page and report an error | |
73 | - path !== toPath && go(toPath as PageEnum, true); | |
74 | - } | |
75 | - | |
76 | - @Mutation | |
77 | - commitCachedMapState(): void { | |
78 | - const cacheMap: Set<string> = new Set(); | |
79 | - | |
80 | - this.tabsState.forEach((tab) => { | |
81 | - const item = getRawRoute(tab); | |
82 | - const needCache = !item.meta?.ignoreKeepAlive; | |
83 | - if (!needCache) return; | |
84 | - const name = item.name as string; | |
85 | - cacheMap.add(name); | |
86 | - }); | |
87 | - this.cachedTabsState = cacheMap; | |
88 | - } | |
89 | - | |
90 | - @Mutation | |
91 | - commitTabRoutesState(route: RouteLocationNormalized) { | |
92 | - const { path, fullPath, params, query } = route; | |
93 | - | |
94 | - let updateIndex = -1; | |
95 | - // Existing pages, do not add tabs repeatedly | |
96 | - const hasTab = this.tabsState.some((tab, index) => { | |
97 | - updateIndex = index; | |
98 | - return (tab.fullPath || tab.path) === (fullPath || path); | |
99 | - }); | |
100 | - if (hasTab) { | |
101 | - const curTab = toRaw(this.tabsState)[updateIndex]; | |
102 | - if (!curTab) return; | |
103 | - curTab.params = params || curTab.params; | |
104 | - curTab.query = query || curTab.query; | |
105 | - curTab.fullPath = fullPath || curTab.fullPath; | |
106 | - this.tabsState.splice(updateIndex, 1, curTab); | |
107 | - return; | |
108 | - } | |
109 | - this.tabsState = cloneDeep([...this.tabsState, route]); | |
110 | - } | |
111 | - | |
112 | - /** | |
113 | - * @description: close tab | |
114 | - */ | |
115 | - @Mutation | |
116 | - commitCloseTab(route: RouteLocationNormalized): void { | |
117 | - const { fullPath, meta: { affix } = {} } = route; | |
118 | - if (affix) return; | |
119 | - const index = this.tabsState.findIndex((item) => item.fullPath === fullPath); | |
120 | - index !== -1 && this.tabsState.splice(index, 1); | |
121 | - } | |
122 | - | |
123 | - @Mutation | |
124 | - commitCloseAllTab(): void { | |
125 | - this.tabsState = this.tabsState.filter((item) => { | |
126 | - return item.meta && item.meta.affix; | |
127 | - }); | |
128 | - } | |
129 | - | |
130 | - @Mutation | |
131 | - commitResetState(): void { | |
132 | - this.tabsState = []; | |
133 | - this.cachedTabsState = new Set(); | |
134 | - } | |
135 | - | |
136 | - @Mutation | |
137 | - commitSortTabs({ oldIndex, newIndex }: { oldIndex: number; newIndex: number }): void { | |
138 | - const currentTab = this.tabsState[oldIndex]; | |
139 | - | |
140 | - this.tabsState.splice(oldIndex, 1); | |
141 | - this.tabsState.splice(newIndex, 0, currentTab); | |
142 | - this.lastDragEndIndexState = this.lastDragEndIndexState + 1; | |
143 | - } | |
144 | - | |
145 | - @Mutation | |
146 | - closeMultipleTab({ pathList }: { pathList: string[] }): void { | |
147 | - this.tabsState = toRaw(this.tabsState).filter((item) => !pathList.includes(item.fullPath)); | |
148 | - } | |
149 | - | |
150 | - @Action | |
151 | - addTabAction(route: RouteLocationNormalized) { | |
152 | - const { path, name } = route; | |
153 | - // 404 The page does not need to add a tab | |
154 | - if ( | |
155 | - path === PageEnum.ERROR_PAGE || | |
156 | - !name || | |
157 | - [REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes(name as string) | |
158 | - ) { | |
159 | - return; | |
160 | - } | |
161 | - this.commitTabRoutesState(getRawRoute(route)); | |
162 | - | |
163 | - this.commitCachedMapState(); | |
164 | - } | |
165 | - | |
166 | - @Mutation | |
167 | - async commitRedoPage() { | |
168 | - const route = router.currentRoute.value; | |
169 | - const name = route.name; | |
170 | - | |
171 | - const findVal = Array.from(this.cachedTabsState).find((item) => item === name); | |
172 | - if (findVal) { | |
173 | - this.cachedTabsState.delete(findVal); | |
174 | - // this.cachedTabsState.splice(index, 1); | |
175 | - } | |
176 | - const redo = useRedo(); | |
177 | - await redo(); | |
178 | - } | |
179 | - | |
180 | - @Action | |
181 | - closeAllTabAction() { | |
182 | - this.commitCloseAllTab(); | |
183 | - this.commitClearCache(); | |
184 | - this.goToPage(); | |
185 | - } | |
186 | - | |
187 | - @Action | |
188 | - closeTabAction(tab: RouteLocationNormalized) { | |
189 | - function getObj(tabItem: RouteLocationNormalized) { | |
190 | - const { params, path, query } = tabItem; | |
191 | - return { | |
192 | - params: params || {}, | |
193 | - path, | |
194 | - query: query || {}, | |
195 | - }; | |
196 | - } | |
197 | - const { currentRoute, replace } = router; | |
198 | - | |
199 | - const { path } = unref(currentRoute); | |
200 | - if (path !== tab.path) { | |
201 | - // Closed is not the activation tab | |
202 | - this.commitCloseTab(tab); | |
203 | - return; | |
204 | - } | |
205 | - | |
206 | - // Closed is activated atb | |
207 | - let toObj: RouteLocationRaw = {}; | |
208 | - | |
209 | - const index = this.getTabsState.findIndex((item) => item.path === path); | |
210 | - | |
211 | - // If the current is the leftmost tab | |
212 | - if (index === 0) { | |
213 | - // There is only one tab, then jump to the homepage, otherwise jump to the right tab | |
214 | - if (this.getTabsState.length === 1) { | |
215 | - toObj = PageEnum.BASE_HOME; | |
216 | - } else { | |
217 | - // Jump to the right tab | |
218 | - const page = this.getTabsState[index + 1]; | |
219 | - toObj = getObj(page); | |
220 | - } | |
221 | - } else { | |
222 | - // Close the current tab | |
223 | - const page = this.getTabsState[index - 1]; | |
224 | - toObj = getObj(page); | |
225 | - } | |
226 | - this.commitCloseTab(currentRoute.value); | |
227 | - replace(toObj); | |
228 | - } | |
229 | - | |
230 | - @Action | |
231 | - closeTabByKeyAction(key: string) { | |
232 | - const index = this.tabsState.findIndex((item) => (item.fullPath || item.path) === key); | |
233 | - index !== -1 && this.closeTabAction(this.tabsState[index]); | |
234 | - } | |
235 | - | |
236 | - @Action | |
237 | - closeLeftTabAction(route: RouteLocationNormalized): void { | |
238 | - const index = this.tabsState.findIndex((item) => item.path === route.path); | |
239 | - | |
240 | - if (index > 0) { | |
241 | - const leftTabs = this.tabsState.slice(0, index); | |
242 | - const pathList: string[] = []; | |
243 | - for (const item of leftTabs) { | |
244 | - const affix = item.meta ? item.meta.affix : false; | |
245 | - if (!affix) { | |
246 | - pathList.push(item.fullPath); | |
247 | - } | |
248 | - } | |
249 | - this.closeMultipleTab({ pathList }); | |
250 | - } | |
251 | - this.commitCachedMapState(); | |
252 | - isGotoPage(); | |
253 | - } | |
254 | - | |
255 | - @Action | |
256 | - closeRightTabAction(route: RouteLocationNormalized): void { | |
257 | - const index = this.tabsState.findIndex((item) => item.fullPath === route.fullPath); | |
258 | - | |
259 | - if (index >= 0 && index < this.tabsState.length - 1) { | |
260 | - const rightTabs = this.tabsState.slice(index + 1, this.tabsState.length); | |
261 | - | |
262 | - const pathList: string[] = []; | |
263 | - for (const item of rightTabs) { | |
264 | - const affix = item.meta ? item.meta.affix : false; | |
265 | - if (!affix) { | |
266 | - pathList.push(item.fullPath); | |
267 | - } | |
268 | - } | |
269 | - this.closeMultipleTab({ pathList }); | |
270 | - } | |
271 | - this.commitCachedMapState(); | |
272 | - isGotoPage(); | |
273 | - } | |
274 | - | |
275 | - @Action | |
276 | - closeOtherTabAction(route: RouteLocationNormalized): void { | |
277 | - const closePathList = this.tabsState.map((item) => item.fullPath); | |
278 | - const pathList: string[] = []; | |
279 | - closePathList.forEach((path) => { | |
280 | - if (path !== route.fullPath) { | |
281 | - const closeItem = this.tabsState.find((item) => item.path === path); | |
282 | - if (!closeItem) return; | |
283 | - const affix = closeItem.meta ? closeItem.meta.affix : false; | |
284 | - if (!affix) { | |
285 | - pathList.push(closeItem.fullPath); | |
286 | - } | |
287 | - } | |
288 | - }); | |
289 | - this.closeMultipleTab({ pathList }); | |
290 | - this.commitCachedMapState(); | |
291 | - isGotoPage(); | |
292 | - } | |
293 | -} | |
294 | -export const tabStore = getModule<Tab>(Tab); |
src/store/modules/user.ts
1 | -import type { | |
2 | - LoginParams, | |
3 | - GetUserInfoByUserIdModel, | |
4 | - GetUserInfoByUserIdParams, | |
5 | -} from '/@/api/sys/model/userModel'; | |
6 | -import type { UserInfo } from '/@/store/types'; | |
1 | +import type { UserInfo } from '/#/store'; | |
2 | +import type { ErrorMessageMode } from '/@/utils/http/axios/types'; | |
7 | 3 | |
8 | -import store from '/@/store/index'; | |
9 | -import { VuexModule, Module, getModule, Mutation, Action } from 'vuex-module-decorators'; | |
10 | -import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; | |
4 | +import { defineStore } from 'pinia'; | |
5 | +import { store } from '/@/store'; | |
11 | 6 | |
12 | -import { PageEnum } from '/@/enums/pageEnum'; | |
13 | 7 | import { RoleEnum } from '/@/enums/roleEnum'; |
8 | +import { PageEnum } from '/@/enums/pageEnum'; | |
14 | 9 | import { ROLES_KEY, TOKEN_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum'; |
15 | 10 | |
16 | -import { useMessage } from '/@/hooks/web/useMessage'; | |
17 | - | |
18 | -import router from '/@/router'; | |
11 | +import { getAuthCache, setAuthCache } from '/@/utils/auth'; | |
12 | +import { | |
13 | + GetUserInfoByUserIdModel, | |
14 | + GetUserInfoByUserIdParams, | |
15 | + LoginParams, | |
16 | +} from '/@/api/sys/model/userModel'; | |
19 | 17 | |
20 | -import { loginApi, getUserInfoById } from '/@/api/sys/user'; | |
18 | +import { getUserInfoById, loginApi } from '/@/api/sys/user'; | |
21 | 19 | |
22 | 20 | import { useI18n } from '/@/hooks/web/useI18n'; |
23 | -import { ErrorMessageMode } from '/@/utils/http/axios/types'; | |
24 | -import { getAuthCache, setAuthCache } from '/@/utils/auth/index'; | |
25 | - | |
26 | -const NAME = 'app-user'; | |
27 | -hotModuleUnregisterModule(NAME); | |
28 | - | |
29 | -@Module({ namespaced: true, name: NAME, dynamic: true, store }) | |
30 | -class User extends VuexModule { | |
31 | - // user info | |
32 | - private userInfoState: UserInfo | null = null; | |
33 | - | |
34 | - // token | |
35 | - private tokenState = ''; | |
36 | - | |
37 | - // roleList | |
38 | - private roleListState: RoleEnum[] = []; | |
39 | - | |
40 | - get getUserInfoState(): UserInfo { | |
41 | - return this.userInfoState || getAuthCache<UserInfo>(USER_INFO_KEY) || {}; | |
42 | - } | |
43 | - | |
44 | - get getTokenState(): string { | |
45 | - return this.tokenState || getAuthCache<string>(TOKEN_KEY); | |
46 | - } | |
47 | - | |
48 | - get getRoleListState(): RoleEnum[] { | |
49 | - return this.roleListState.length > 0 ? this.roleListState : getAuthCache<RoleEnum[]>(ROLES_KEY); | |
50 | - } | |
51 | - | |
52 | - @Mutation | |
53 | - commitResetState(): void { | |
54 | - this.userInfoState = null; | |
55 | - this.tokenState = ''; | |
56 | - this.roleListState = []; | |
57 | - } | |
58 | - | |
59 | - @Mutation | |
60 | - commitUserInfoState(info: UserInfo): void { | |
61 | - this.userInfoState = info; | |
62 | - setAuthCache(USER_INFO_KEY, info); | |
63 | - } | |
64 | - | |
65 | - @Mutation | |
66 | - commitRoleListState(roleList: RoleEnum[]): void { | |
67 | - this.roleListState = roleList; | |
68 | - setAuthCache(ROLES_KEY, roleList); | |
69 | - } | |
70 | - | |
71 | - @Mutation | |
72 | - commitTokenState(info: string): void { | |
73 | - this.tokenState = info; | |
74 | - setAuthCache(TOKEN_KEY, info); | |
75 | - } | |
76 | - | |
77 | - /** | |
78 | - * @description: login | |
79 | - */ | |
80 | - @Action | |
81 | - async login( | |
82 | - params: LoginParams & { | |
83 | - goHome?: boolean; | |
84 | - mode?: ErrorMessageMode; | |
85 | - } | |
86 | - ): Promise<GetUserInfoByUserIdModel | null> { | |
87 | - try { | |
88 | - const { goHome = true, mode, ...loginParams } = params; | |
89 | - const data = await loginApi(loginParams, mode); | |
90 | - | |
91 | - const { token, userId } = data; | |
92 | - | |
93 | - // save token | |
94 | - this.commitTokenState(token); | |
21 | +import { useMessage } from '/@/hooks/web/useMessage'; | |
22 | +import router from '/@/router'; | |
95 | 23 | |
96 | - // get user info | |
97 | - const userInfo = await this.getUserInfoAction({ userId }); | |
24 | +interface UserState { | |
25 | + userInfo: Nullable<UserInfo>; | |
26 | + token?: string; | |
27 | + roleList: RoleEnum[]; | |
28 | +} | |
98 | 29 | |
99 | - goHome && (await router.replace(PageEnum.BASE_HOME)); | |
30 | +export const useUserStore = defineStore({ | |
31 | + id: 'app-user', | |
32 | + state: (): UserState => ({ | |
33 | + // user info | |
34 | + userInfo: null, | |
35 | + // token | |
36 | + token: undefined, | |
37 | + // roleList | |
38 | + roleList: [], | |
39 | + }), | |
40 | + getters: { | |
41 | + getUserInfo(): UserInfo { | |
42 | + return this.userInfo || getAuthCache<UserInfo>(USER_INFO_KEY) || {}; | |
43 | + }, | |
44 | + getToken(): string { | |
45 | + return this.token || getAuthCache<string>(TOKEN_KEY); | |
46 | + }, | |
47 | + getRoleList(): RoleEnum[] { | |
48 | + return this.roleList.length > 0 ? this.roleList : getAuthCache<RoleEnum[]>(ROLES_KEY); | |
49 | + }, | |
50 | + }, | |
51 | + actions: { | |
52 | + setToken(info: string) { | |
53 | + this.token = info; | |
54 | + setAuthCache(TOKEN_KEY, info); | |
55 | + }, | |
56 | + setRoleList(roleList: RoleEnum[]) { | |
57 | + this.roleList = roleList; | |
58 | + setAuthCache(ROLES_KEY, roleList); | |
59 | + }, | |
60 | + setUserInfo(info: UserInfo) { | |
61 | + this.userInfo = info; | |
62 | + setAuthCache(USER_INFO_KEY, info); | |
63 | + }, | |
64 | + resetState() { | |
65 | + this.userInfo = null; | |
66 | + this.token = ''; | |
67 | + this.roleList = []; | |
68 | + }, | |
69 | + /** | |
70 | + * @description: login | |
71 | + */ | |
72 | + async login( | |
73 | + params: LoginParams & { | |
74 | + goHome?: boolean; | |
75 | + mode?: ErrorMessageMode; | |
76 | + } | |
77 | + ): Promise<GetUserInfoByUserIdModel | null> { | |
78 | + try { | |
79 | + const { goHome = true, mode, ...loginParams } = params; | |
80 | + const data = await loginApi(loginParams, mode); | |
81 | + const { token, userId } = data; | |
82 | + | |
83 | + // save token | |
84 | + this.setToken(token); | |
85 | + // get user info | |
86 | + const userInfo = await this.getUserInfoAction({ userId }); | |
87 | + | |
88 | + goHome && (await router.replace(PageEnum.BASE_HOME)); | |
89 | + return userInfo; | |
90 | + } catch (error) { | |
91 | + return null; | |
92 | + } | |
93 | + }, | |
94 | + async getUserInfoAction({ userId }: GetUserInfoByUserIdParams) { | |
95 | + const userInfo = await getUserInfoById({ userId }); | |
96 | + const { roles } = userInfo; | |
97 | + const roleList = roles.map((item) => item.value) as RoleEnum[]; | |
98 | + this.setUserInfo(userInfo); | |
99 | + this.setRoleList(roleList); | |
100 | 100 | return userInfo; |
101 | - } catch (error) { | |
102 | - return null; | |
103 | - } | |
104 | - } | |
105 | - | |
106 | - @Action | |
107 | - async getUserInfoAction({ userId }: GetUserInfoByUserIdParams) { | |
108 | - const userInfo = await getUserInfoById({ userId }); | |
109 | - const { roles } = userInfo; | |
110 | - const roleList = roles.map((item) => item.value) as RoleEnum[]; | |
111 | - this.commitUserInfoState(userInfo); | |
112 | - this.commitRoleListState(roleList); | |
113 | - return userInfo; | |
114 | - } | |
115 | - | |
116 | - /** | |
117 | - * @description: logout | |
118 | - */ | |
119 | - @Action | |
120 | - async logout(goLogin = false) { | |
121 | - goLogin && router.push(PageEnum.BASE_LOGIN); | |
122 | - } | |
123 | - | |
124 | - /** | |
125 | - * @description: Confirm before logging out | |
126 | - */ | |
127 | - @Action | |
128 | - async confirmLoginOut() { | |
129 | - const { createConfirm } = useMessage(); | |
130 | - const { t } = useI18n(); | |
131 | - createConfirm({ | |
132 | - iconType: 'warning', | |
133 | - title: t('sys.app.logoutTip'), | |
134 | - content: t('sys.app.logoutMessage'), | |
135 | - onOk: async () => { | |
136 | - await this.logout(true); | |
137 | - }, | |
138 | - }); | |
139 | - } | |
101 | + }, | |
102 | + /** | |
103 | + * @description: logout | |
104 | + */ | |
105 | + logout(goLogin = false) { | |
106 | + goLogin && router.push(PageEnum.BASE_LOGIN); | |
107 | + }, | |
108 | + | |
109 | + /** | |
110 | + * @description: Confirm before logging out | |
111 | + */ | |
112 | + confirmLoginOut() { | |
113 | + const { createConfirm } = useMessage(); | |
114 | + const { t } = useI18n(); | |
115 | + createConfirm({ | |
116 | + iconType: 'warning', | |
117 | + title: t('sys.app.logoutTip'), | |
118 | + content: t('sys.app.logoutMessage'), | |
119 | + onOk: async () => { | |
120 | + await this.logout(true); | |
121 | + }, | |
122 | + }); | |
123 | + }, | |
124 | + }, | |
125 | +}); | |
126 | + | |
127 | +// Need to be used outside the setup | |
128 | +export function useUserStoreWidthOut() { | |
129 | + return useUserStore(store); | |
140 | 130 | } |
141 | -export const userStore = getModule<User>(User); | ... | ... |
src/store/types.ts deleted
100644 โ 0
1 | -import { MenuModeEnum, MenuTypeEnum } from '../enums/menuEnum'; | |
2 | - | |
3 | -export interface LockInfo { | |
4 | - pwd: string | undefined; | |
5 | - isLock: boolean; | |
6 | -} | |
7 | - | |
8 | -export interface UserInfo { | |
9 | - // ็จๆทid | |
10 | - userId: string | number; | |
11 | - // ็จๆทๅ | |
12 | - username: string; | |
13 | - // ็ๅฎๅๅญ | |
14 | - realName: string; | |
15 | - // ไป็ป | |
16 | - desc?: string; | |
17 | -} | |
18 | - | |
19 | -export interface BeforeMiniState { | |
20 | - menuCollapsed?: boolean; | |
21 | - menuSplit?: boolean; | |
22 | - menuMode?: MenuModeEnum; | |
23 | - menuType?: MenuTypeEnum; | |
24 | -} |
src/utils/cache/persistent.ts
1 | -import type { LockInfo, UserInfo } from '/@/store/types'; | |
2 | - | |
3 | -import { ProjectConfig } from '/#/config'; | |
1 | +import type { LockInfo, UserInfo } from '/#/store'; | |
2 | +import type { ProjectConfig } from '/#/config'; | |
4 | 3 | |
5 | 4 | import { createLocalStorage, createSessionStorage } from '/@/utils/cache'; |
6 | 5 | import { Memory } from './memory'; | ... | ... |
src/utils/env.ts
src/utils/http/axios/index.ts
... | ... | @@ -16,7 +16,8 @@ import { RequestEnum, ResultEnum, ContentTypeEnum } from '/@/enums/httpEnum'; |
16 | 16 | import { isString } from '/@/utils/is'; |
17 | 17 | import { getToken } from '/@/utils/auth'; |
18 | 18 | import { setObjToUrlParams, deepMerge } from '/@/utils'; |
19 | -import { errorStore } from '/@/store/modules/error'; | |
19 | +import { useErrorLogStoreWithOut } from '/@/store/modules/errorLog'; | |
20 | + | |
20 | 21 | import { errorResult } from './const'; |
21 | 22 | import { useI18n } from '/@/hooks/web/useI18n'; |
22 | 23 | import { createNow, formatRequestDate } from './helper'; |
... | ... | @@ -150,7 +151,8 @@ const transform: AxiosTransform = { |
150 | 151 | */ |
151 | 152 | responseInterceptorsCatch: (error: any) => { |
152 | 153 | const { t } = useI18n(); |
153 | - errorStore.setupErrorHandle(error); | |
154 | + const errorLogStore = useErrorLogStoreWithOut(); | |
155 | + errorLogStore.addAjaxErrorInfo(error); | |
154 | 156 | const { response, code, message } = error || {}; |
155 | 157 | const msg: string = response?.data?.error?.message ?? ''; |
156 | 158 | const err: string = error?.toString?.() ?? ''; | ... | ... |
src/views/demo/permission/CurrentPermissionMode.vue
... | ... | @@ -10,7 +10,7 @@ |
10 | 10 | </template> |
11 | 11 | <script lang="ts"> |
12 | 12 | import { defineComponent, computed } from 'vue'; |
13 | - import { appStore } from '/@/store/modules/app'; | |
13 | + import { useAppStore } from '/@/store/modules/app'; | |
14 | 14 | import { PermissionModeEnum } from '/@/enums/appEnum'; |
15 | 15 | import { Divider } from 'ant-design-vue'; |
16 | 16 | import { usePermission } from '/@/hooks/web/usePermission'; |
... | ... | @@ -18,9 +18,8 @@ |
18 | 18 | name: 'CurrentPermissionMode', |
19 | 19 | components: { Divider }, |
20 | 20 | setup() { |
21 | - const permissionMode = computed(() => { | |
22 | - return appStore.getProjectConfig.permissionMode; | |
23 | - }); | |
21 | + const appStore = useAppStore(); | |
22 | + const permissionMode = computed(() => appStore.getProjectConfig.permissionMode); | |
24 | 23 | const { togglePermissionMode } = usePermission(); |
25 | 24 | |
26 | 25 | return { | ... | ... |
src/views/demo/permission/back/Btn.vue
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | <CurrentPermissionMode /> |
6 | 6 | |
7 | 7 | <p> |
8 | - ๅฝๅๆฅๆ็codeๅ่กจ: <a> {{ permissionStore.getPermCodeListState }} </a> | |
8 | + ๅฝๅๆฅๆ็codeๅ่กจ: <a> {{ permissionStore.getPermCodeList }} </a> | |
9 | 9 | </p> |
10 | 10 | <Divider /> |
11 | 11 | <Alert class="mt-4" type="info" message="็นๅปๅ่ฏทๆฅ็ๆ้ฎๅๅ" show-icon /> |
... | ... | @@ -59,7 +59,7 @@ |
59 | 59 | import CurrentPermissionMode from '../CurrentPermissionMode.vue'; |
60 | 60 | import { usePermission } from '/@/hooks/web/usePermission'; |
61 | 61 | import { Authority } from '/@/components/Authority'; |
62 | - import { permissionStore } from '/@/store/modules/permission'; | |
62 | + import { usePermissionStore } from '/@/store/modules/permission'; | |
63 | 63 | import { PermissionModeEnum } from '/@/enums/appEnum'; |
64 | 64 | import { PageWrapper } from '/@/components/Page'; |
65 | 65 | |
... | ... | @@ -67,6 +67,7 @@ |
67 | 67 | components: { Alert, PageWrapper, CurrentPermissionMode, Divider, Authority }, |
68 | 68 | setup() { |
69 | 69 | const { hasPermission } = usePermission(); |
70 | + const permissionStore = usePermissionStore(); | |
70 | 71 | |
71 | 72 | function changePermissionCode(userId: string) { |
72 | 73 | permissionStore.changePermissionCode(userId); | ... | ... |
src/views/demo/permission/front/Btn.vue
... | ... | @@ -8,7 +8,7 @@ |
8 | 8 | <CurrentPermissionMode /> |
9 | 9 | |
10 | 10 | <p> |
11 | - ๅฝๅ่ง่ฒ: <a> {{ userStore.getRoleListState }} </a> | |
11 | + ๅฝๅ่ง่ฒ: <a> {{ userStore.getRoleList }} </a> | |
12 | 12 | </p> |
13 | 13 | <Alert class="mt-4" type="info" message="็นๅปๅ่ฏทๆฅ็ๆ้ฎๅๅ" show-icon /> |
14 | 14 | |
... | ... | @@ -63,7 +63,7 @@ |
63 | 63 | import { computed, defineComponent } from 'vue'; |
64 | 64 | import { Alert, Divider } from 'ant-design-vue'; |
65 | 65 | import CurrentPermissionMode from '../CurrentPermissionMode.vue'; |
66 | - import { userStore } from '/@/store/modules/user'; | |
66 | + import { useUserStore } from '/@/store/modules/user'; | |
67 | 67 | import { RoleEnum } from '/@/enums/roleEnum'; |
68 | 68 | import { usePermission } from '/@/hooks/web/usePermission'; |
69 | 69 | import { Authority } from '/@/components/Authority'; |
... | ... | @@ -73,11 +73,13 @@ |
73 | 73 | components: { Alert, PageWrapper, CurrentPermissionMode, Divider, Authority }, |
74 | 74 | setup() { |
75 | 75 | const { changeRole, hasPermission } = usePermission(); |
76 | + const userStore = useUserStore(); | |
77 | + | |
76 | 78 | return { |
77 | 79 | userStore, |
78 | 80 | RoleEnum, |
79 | - isSuper: computed(() => userStore.getRoleListState.includes(RoleEnum.SUPER)), | |
80 | - isTest: computed(() => userStore.getRoleListState.includes(RoleEnum.TEST)), | |
81 | + isSuper: computed(() => userStore.getRoleList.includes(RoleEnum.SUPER)), | |
82 | + isTest: computed(() => userStore.getRoleList.includes(RoleEnum.TEST)), | |
81 | 83 | changeRole, |
82 | 84 | hasPermission, |
83 | 85 | }; | ... | ... |
src/views/demo/permission/front/index.vue
... | ... | @@ -8,7 +8,7 @@ |
8 | 8 | <CurrentPermissionMode /> |
9 | 9 | |
10 | 10 | <p> |
11 | - ๅฝๅ่ง่ฒ: <a> {{ userStore.getRoleListState }} </a> | |
11 | + ๅฝๅ่ง่ฒ: <a> {{ userStore.getRoleList }} </a> | |
12 | 12 | </p> |
13 | 13 | <Alert class="mt-4" type="info" message="็นๅปๅ่ฏทๆฅ็ๅทฆไพง่ๅๅๅ" show-icon /> |
14 | 14 | |
... | ... | @@ -29,7 +29,7 @@ |
29 | 29 | import { computed, defineComponent } from 'vue'; |
30 | 30 | import { Alert } from 'ant-design-vue'; |
31 | 31 | import CurrentPermissionMode from '../CurrentPermissionMode.vue'; |
32 | - import { userStore } from '/@/store/modules/user'; | |
32 | + import { useUserStore } from '/@/store/modules/user'; | |
33 | 33 | import { RoleEnum } from '/@/enums/roleEnum'; |
34 | 34 | import { usePermission } from '/@/hooks/web/usePermission'; |
35 | 35 | import { PageWrapper } from '/@/components/Page'; |
... | ... | @@ -38,11 +38,13 @@ |
38 | 38 | components: { Alert, CurrentPermissionMode, PageWrapper }, |
39 | 39 | setup() { |
40 | 40 | const { changeRole } = usePermission(); |
41 | + const userStore = useUserStore(); | |
42 | + | |
41 | 43 | return { |
42 | 44 | userStore, |
43 | 45 | RoleEnum, |
44 | - isSuper: computed(() => userStore.getRoleListState.includes(RoleEnum.SUPER)), | |
45 | - isTest: computed(() => userStore.getRoleListState.includes(RoleEnum.TEST)), | |
46 | + isSuper: computed(() => userStore.getRoleList.includes(RoleEnum.SUPER)), | |
47 | + isTest: computed(() => userStore.getRoleList.includes(RoleEnum.TEST)), | |
46 | 48 | changeRole, |
47 | 49 | }; |
48 | 50 | }, | ... | ... |
src/views/sys/error-log/DetailModal.vue
... | ... | @@ -5,6 +5,7 @@ |
5 | 5 | </template> |
6 | 6 | <script lang="ts"> |
7 | 7 | import type { PropType } from 'vue'; |
8 | + import type { ErrorLogInfo } from '/#/store'; | |
8 | 9 | |
9 | 10 | import { defineComponent } from 'vue'; |
10 | 11 | import { BasicModal } from '/@/components/Modal/index'; |
... | ... | @@ -12,8 +13,6 @@ |
12 | 13 | |
13 | 14 | import { useI18n } from '/@/hooks/web/useI18n'; |
14 | 15 | |
15 | - import { ErrorInfo } from '/@/store/modules/error'; | |
16 | - | |
17 | 16 | import { getDescSchema } from './data'; |
18 | 17 | |
19 | 18 | export default defineComponent({ |
... | ... | @@ -21,7 +20,7 @@ |
21 | 20 | components: { BasicModal, Description }, |
22 | 21 | props: { |
23 | 22 | info: { |
24 | - type: Object as PropType<ErrorInfo>, | |
23 | + type: Object as PropType<ErrorLogInfo>, | |
25 | 24 | default: null, |
26 | 25 | }, |
27 | 26 | }, |
... | ... | @@ -30,7 +29,7 @@ |
30 | 29 | |
31 | 30 | const [register] = useDescription({ |
32 | 31 | column: 2, |
33 | - schema: getDescSchema(), | |
32 | + schema: getDescSchema()!, | |
34 | 33 | }); |
35 | 34 | |
36 | 35 | return { | ... | ... |
src/views/sys/error-log/data.tsx
src/views/sys/error-log/index.vue
... | ... | @@ -28,6 +28,8 @@ |
28 | 28 | </template> |
29 | 29 | |
30 | 30 | <script lang="ts"> |
31 | + import type { ErrorLogInfo } from '/#/store'; | |
32 | + | |
31 | 33 | import { defineComponent, watch, ref, nextTick } from 'vue'; |
32 | 34 | |
33 | 35 | import DetailModal from './DetailModal.vue'; |
... | ... | @@ -37,7 +39,7 @@ |
37 | 39 | import { useMessage } from '/@/hooks/web/useMessage'; |
38 | 40 | import { useI18n } from '/@/hooks/web/useI18n'; |
39 | 41 | |
40 | - import { errorStore, ErrorInfo } from '/@/store/modules/error'; | |
42 | + import { useErrorLogStore } from '/@/store/modules/errorLog'; | |
41 | 43 | |
42 | 44 | import { fireErrorApi } from '/@/api/demo/error'; |
43 | 45 | |
... | ... | @@ -49,11 +51,11 @@ |
49 | 51 | name: 'ErrorHandler', |
50 | 52 | components: { DetailModal, BasicTable, TableAction }, |
51 | 53 | setup() { |
52 | - const rowInfo = ref<ErrorInfo>(); | |
54 | + const rowInfo = ref<ErrorLogInfo>(); | |
53 | 55 | const imgList = ref<string[]>([]); |
54 | 56 | |
55 | 57 | const { t } = useI18n(); |
56 | - | |
58 | + const errorLogStore = useErrorLogStore(); | |
57 | 59 | const [register, { setTableData }] = useTable({ |
58 | 60 | title: t('sys.errorLog.tableTitle'), |
59 | 61 | columns: getColumns(), |
... | ... | @@ -67,7 +69,7 @@ |
67 | 69 | const [registerModal, { openModal }] = useModal(); |
68 | 70 | |
69 | 71 | watch( |
70 | - () => errorStore.getErrorInfoState, | |
72 | + () => errorLogStore.getErrorLogInfoList, | |
71 | 73 | (list) => { |
72 | 74 | nextTick(() => { |
73 | 75 | setTableData(cloneDeep(list)); |
... | ... | @@ -82,7 +84,7 @@ |
82 | 84 | createMessage.info(t('sys.errorLog.enableMessage')); |
83 | 85 | } |
84 | 86 | // ๆฅ็่ฏฆๆ |
85 | - function handleDetail(row: ErrorInfo) { | |
87 | + function handleDetail(row: ErrorLogInfo) { | |
86 | 88 | rowInfo.value = row; |
87 | 89 | openModal(true); |
88 | 90 | } | ... | ... |
src/views/sys/lock/LockPage.vue
... | ... | @@ -38,7 +38,7 @@ |
38 | 38 | class="enter-x" |
39 | 39 | v-model:value="password" |
40 | 40 | /> |
41 | - <span :class="`${prefixCls}-entry__err-msg enter-x`" v-if="errMsgRef"> | |
41 | + <span :class="`${prefixCls}-entry__err-msg enter-x`" v-if="errMsg"> | |
42 | 42 | {{ t('sys.lock.alert') }} |
43 | 43 | </span> |
44 | 44 | <div :class="`${prefixCls}-entry__footer enter-x`"> |
... | ... | @@ -46,7 +46,7 @@ |
46 | 46 | type="link" |
47 | 47 | size="small" |
48 | 48 | class="mt-2 mr-2 enter-x" |
49 | - :disabled="loadingRef" | |
49 | + :disabled="loading" | |
50 | 50 | @click="handleShowForm(true)" |
51 | 51 | > |
52 | 52 | {{ t('common.back') }} |
... | ... | @@ -55,12 +55,12 @@ |
55 | 55 | type="link" |
56 | 56 | size="small" |
57 | 57 | class="mt-2 mr-2 enter-x" |
58 | - :disabled="loadingRef" | |
58 | + :disabled="loading" | |
59 | 59 | @click="goLogin" |
60 | 60 | > |
61 | 61 | {{ t('sys.lock.backToLogin') }} |
62 | 62 | </a-button> |
63 | - <a-button class="mt-2" type="link" size="small" @click="unLock()" :loading="loadingRef"> | |
63 | + <a-button class="mt-2" type="link" size="small" @click="unLock()" :loading="loading"> | |
64 | 64 | {{ t('sys.lock.entry') }} |
65 | 65 | </a-button> |
66 | 66 | </div> |
... | ... | @@ -80,8 +80,8 @@ |
80 | 80 | import { defineComponent, ref, computed } from 'vue'; |
81 | 81 | import { Input } from 'ant-design-vue'; |
82 | 82 | |
83 | - import { userStore } from '/@/store/modules/user'; | |
84 | - import { lockStore } from '/@/store/modules/lock'; | |
83 | + import { useUserStore } from '/@/store/modules/user'; | |
84 | + import { useLockStore } from '/@/store/modules/lock'; | |
85 | 85 | import { useI18n } from '/@/hooks/web/useI18n'; |
86 | 86 | |
87 | 87 | import { useNow } from './useNow'; |
... | ... | @@ -95,19 +95,21 @@ |
95 | 95 | components: { LockOutlined, InputPassword: Input.Password }, |
96 | 96 | |
97 | 97 | setup() { |
98 | - const passwordRef = ref(''); | |
99 | - const loadingRef = ref(false); | |
100 | - const errMsgRef = ref(false); | |
98 | + const password = ref(''); | |
99 | + const loading = ref(false); | |
100 | + const errMsg = ref(false); | |
101 | 101 | const showDate = ref(true); |
102 | 102 | |
103 | 103 | const { prefixCls } = useDesign('lock-page'); |
104 | + const lockStore = useLockStore(); | |
105 | + const userStore = useUserStore(); | |
104 | 106 | |
105 | 107 | const { ...state } = useNow(true); |
106 | 108 | |
107 | 109 | const { t } = useI18n(); |
108 | 110 | |
109 | 111 | const realName = computed(() => { |
110 | - const { realName } = userStore.getUserInfoState || {}; | |
112 | + const { realName } = userStore.getUserInfo || {}; | |
111 | 113 | return realName; |
112 | 114 | }); |
113 | 115 | |
... | ... | @@ -115,16 +117,16 @@ |
115 | 117 | * @description: unLock |
116 | 118 | */ |
117 | 119 | async function unLock() { |
118 | - if (!passwordRef.value) { | |
120 | + if (!password.value) { | |
119 | 121 | return; |
120 | 122 | } |
121 | - let password = passwordRef.value; | |
123 | + let pwd = password.value; | |
122 | 124 | try { |
123 | - loadingRef.value = true; | |
124 | - const res = await lockStore.unLockAction({ password }); | |
125 | - errMsgRef.value = !res; | |
125 | + loading.value = true; | |
126 | + const res = await lockStore.unLock(pwd); | |
127 | + errMsg.value = !res; | |
126 | 128 | } finally { |
127 | - loadingRef.value = false; | |
129 | + loading.value = false; | |
128 | 130 | } |
129 | 131 | } |
130 | 132 | |
... | ... | @@ -141,12 +143,12 @@ |
141 | 143 | goLogin, |
142 | 144 | realName, |
143 | 145 | unLock, |
144 | - errMsgRef, | |
145 | - loadingRef, | |
146 | + errMsg, | |
147 | + loading, | |
146 | 148 | t, |
147 | 149 | prefixCls, |
148 | 150 | showDate, |
149 | - password: passwordRef, | |
151 | + password, | |
150 | 152 | handleShowForm, |
151 | 153 | headerImg, |
152 | 154 | ...state, | ... | ... |
src/views/sys/lock/index.vue
... | ... | @@ -7,17 +7,13 @@ |
7 | 7 | import { defineComponent, computed } from 'vue'; |
8 | 8 | import LockPage from './LockPage.vue'; |
9 | 9 | |
10 | - import { lockStore } from '/@/store/modules/lock'; | |
10 | + import { useLockStore } from '/@/store/modules/lock'; | |
11 | 11 | export default defineComponent({ |
12 | 12 | name: 'Lock', |
13 | 13 | components: { LockPage }, |
14 | 14 | setup() { |
15 | - const getIsLock = computed(() => { | |
16 | - const { getLockInfo } = lockStore; | |
17 | - const { isLock } = getLockInfo; | |
18 | - return isLock; | |
19 | - }); | |
20 | - | |
15 | + const lockStore = useLockStore(); | |
16 | + const getIsLock = computed(() => lockStore?.getLockInfo?.isLock ?? false); | |
21 | 17 | return { getIsLock }; |
22 | 18 | }, |
23 | 19 | }); | ... | ... |
src/views/sys/lock/useNow.ts
1 | 1 | import { dateUtil } from '/@/utils/dateUtil'; |
2 | 2 | import { reactive, toRefs } from 'vue'; |
3 | -import { localeStore } from '/@/store/modules/locale'; | |
3 | +import { useLocaleStore } from '/@/store/modules/locale'; | |
4 | 4 | import { tryOnMounted, tryOnUnmounted } from '@vueuse/core'; |
5 | 5 | |
6 | 6 | export function useNow(immediate = true) { |
7 | + const localeStore = useLocaleStore(); | |
7 | 8 | const localData = dateUtil.localeData(localeStore.getLocale); |
8 | 9 | let timer: IntervalHandle; |
9 | 10 | ... | ... |
src/views/sys/login/Login.vue
... | ... | @@ -58,7 +58,7 @@ |
58 | 58 | import { useGlobSetting } from '/@/hooks/setting'; |
59 | 59 | import { useI18n } from '/@/hooks/web/useI18n'; |
60 | 60 | import { useDesign } from '/@/hooks/web/useDesign'; |
61 | - import { localeStore } from '/@/store/modules/locale'; | |
61 | + import { useLocaleStore } from '/@/store/modules/locale'; | |
62 | 62 | |
63 | 63 | export default defineComponent({ |
64 | 64 | name: 'Login', |
... | ... | @@ -76,6 +76,7 @@ |
76 | 76 | const globSetting = useGlobSetting(); |
77 | 77 | const { prefixCls } = useDesign('login'); |
78 | 78 | const { t } = useI18n(); |
79 | + const localeStore = useLocaleStore(); | |
79 | 80 | |
80 | 81 | return { |
81 | 82 | t, | ... | ... |
src/views/sys/login/LoginForm.vue
... | ... | @@ -85,7 +85,7 @@ |
85 | 85 | import { useI18n } from '/@/hooks/web/useI18n'; |
86 | 86 | import { useMessage } from '/@/hooks/web/useMessage'; |
87 | 87 | |
88 | - import { userStore } from '/@/store/modules/user'; | |
88 | + import { useUserStore } from '/@/store/modules/user'; | |
89 | 89 | import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin'; |
90 | 90 | import { useDesign } from '/@/hooks/web/useDesign'; |
91 | 91 | import { useKeyPress } from '/@/hooks/event/useKeyPress'; |
... | ... | @@ -114,6 +114,7 @@ |
114 | 114 | const { t } = useI18n(); |
115 | 115 | const { notification } = useMessage(); |
116 | 116 | const { prefixCls } = useDesign('login'); |
117 | + const userStore = useUserStore(); | |
117 | 118 | |
118 | 119 | const { setLoginState, getLoginState } = useLoginState(); |
119 | 120 | const { getFormRules } = useFormRules(); | ... | ... |
types/store.ts
0 โ 100644
1 | +import { ErrorTypeEnum } from '/@/enums/exceptionEnum'; | |
2 | +import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum'; | |
3 | + | |
4 | +// Lock screen information | |
5 | +export interface LockInfo { | |
6 | + // Password required | |
7 | + pwd?: string | undefined; | |
8 | + // Is it locked? | |
9 | + isLock?: boolean; | |
10 | +} | |
11 | + | |
12 | +// Error-log information | |
13 | +export interface ErrorLogInfo { | |
14 | + // Type of error | |
15 | + type: ErrorTypeEnum; | |
16 | + // Error file | |
17 | + file: string; | |
18 | + // Error name | |
19 | + name?: string; | |
20 | + // Error message | |
21 | + message: string; | |
22 | + // Error stack | |
23 | + stack?: string; | |
24 | + // Error detail | |
25 | + detail: string; | |
26 | + // Error url | |
27 | + url: string; | |
28 | + // Error time | |
29 | + time?: string; | |
30 | +} | |
31 | + | |
32 | +export interface UserInfo { | |
33 | + userId: string | number; | |
34 | + username: string; | |
35 | + realName: string; | |
36 | + desc?: string; | |
37 | +} | |
38 | + | |
39 | +export interface BeforeMiniState { | |
40 | + menuCollapsed?: boolean; | |
41 | + menuSplit?: boolean; | |
42 | + menuMode?: MenuModeEnum; | |
43 | + menuType?: MenuTypeEnum; | |
44 | +} | ... | ... |
yarn.lock
... | ... | @@ -1762,25 +1762,25 @@ |
1762 | 1762 | resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.0.11.tgz#20d22dd0da7d358bb21c17f9bde8628152642c77" |
1763 | 1763 | integrity sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA== |
1764 | 1764 | |
1765 | -"@vueuse/core@^4.8.0": | |
1766 | - version "4.8.0" | |
1767 | - resolved "https://registry.npmjs.org/@vueuse/core/-/core-4.8.0.tgz#d86e36956521c0f9b6571cb58b27f0e2535259b3" | |
1768 | - integrity sha512-nUH4Hn1DN4kkuF1r5ZcfGnjoAKDD0Kw9oFnt/TUo1aueNijq4KujagtoQN8OC4Pei10TeTDdqhmZAWnaCE1NbA== | |
1765 | +"@vueuse/core@^4.8.1": | |
1766 | + version "4.8.1" | |
1767 | + resolved "https://registry.npmjs.org/@vueuse/core/-/core-4.8.1.tgz#d7a7fb2e72610d1962ecb9244bd93dacb96d921c" | |
1768 | + integrity sha512-oXFEDaKNU69Rj20/Hd7ZlmTpEtA2M19cRkZaL4A0Nl0w5Wb5In/8aK+0vtdi1VyMUXXbq6h1OGKCJcIhg5cziA== | |
1769 | 1769 | dependencies: |
1770 | - "@vueuse/shared" "4.8.0" | |
1770 | + "@vueuse/shared" "4.8.1" | |
1771 | 1771 | vue-demi latest |
1772 | 1772 | |
1773 | -"@vueuse/shared@4.8.0": | |
1774 | - version "4.8.0" | |
1775 | - resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-4.8.0.tgz#abf3da96ca81b4be82e885928193fef2c676cdbc" | |
1776 | - integrity sha512-g1lSbHD4ptiS74qBUvffJ98QjRsoCH7ILjxVzJF488EPAmp5z3taLnoggt6NXfonnYve7fEPuqsJqd2BLOxT1A== | |
1773 | +"@vueuse/shared@4.8.1": | |
1774 | + version "4.8.1" | |
1775 | + resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-4.8.1.tgz#45fd5f64bf4e8944db42a5b72fa2705cfc74608a" | |
1776 | + integrity sha512-ONKJoIvZPrGCA8loK7dX+ZcjgZLikI+vPiz1lWlXs6+jZiQiZSLkmvg1NjV6Cfb6OqbDCfEScTWLbZHB7EwrRw== | |
1777 | 1777 | dependencies: |
1778 | 1778 | vue-demi latest |
1779 | 1779 | |
1780 | -"@windicss/plugin-utils@0.12.5": | |
1781 | - version "0.12.5" | |
1782 | - resolved "https://registry.npmjs.org/@windicss/plugin-utils/-/plugin-utils-0.12.5.tgz#d03517d1ae7a48b5b459e3d670e873d38b63e4a1" | |
1783 | - integrity sha512-4ux2o4s6D/gRTD68os41oxs/0NFk/eSJxHhZL9nN2wy4RGt+pPMQJyOHV56l7zDh9B0ywU5+ZRxDjdw2cl5Yvg== | |
1780 | +"@windicss/plugin-utils@0.13.1": | |
1781 | + version "0.13.1" | |
1782 | + resolved "https://registry.npmjs.org/@windicss/plugin-utils/-/plugin-utils-0.13.1.tgz#e0e172855ebcf0b8a5f0f358befdcaf44bae5cf1" | |
1783 | + integrity sha512-Vr7f7yWxmB5AWwe+iDPV3JbhTlZHbDvM89IfJ0hyP6PqYmZNTtUfMXMbHXZJHVAbQ54dWBMG23WmeC9X327ETA== | |
1784 | 1784 | dependencies: |
1785 | 1785 | debug "^4.3.2" |
1786 | 1786 | fast-glob "^3.2.5" |
... | ... | @@ -1788,7 +1788,7 @@ |
1788 | 1788 | micromatch "^4.0.2" |
1789 | 1789 | pirates "^4.0.1" |
1790 | 1790 | sucrase "^3.17.1" |
1791 | - windicss "^2.5.11" | |
1791 | + windicss "^2.5.12" | |
1792 | 1792 | |
1793 | 1793 | "@zxcvbn-ts/core@^0.3.0": |
1794 | 1794 | version "0.3.0" |
... | ... | @@ -3670,21 +3670,11 @@ esbuild-register@^2.2.0: |
3670 | 3670 | esbuild "^0.9.2" |
3671 | 3671 | jsonc-parser "^3.0.0" |
3672 | 3672 | |
3673 | -esbuild@^0.11.4: | |
3674 | - version "0.11.5" | |
3675 | - resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.11.5.tgz#25b18a2ff2fb9580683edce26a48f64c08c2f2df" | |
3676 | - integrity sha512-aRs6jAE+bVRp1tyfzUugAw1T/Y0Fwzp4Z2ROikF3h+UifoD5QlEbEYQGc6orNnnSIRhWR5VWBH7LozlAumaLHg== | |
3677 | - | |
3678 | -esbuild@^0.11.6: | |
3673 | +esbuild@^0.11.4, esbuild@^0.11.6, esbuild@^0.9.2, esbuild@^0.9.3: | |
3679 | 3674 | version "0.11.6" |
3680 | 3675 | resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.11.6.tgz#20961309c4cfed00b71027e18806150358d0cbb0" |
3681 | 3676 | integrity sha512-L+nKW9ftVS/N2CVJMR9YmXHbkm+vHzlNYuo09rzipQhF7dYNvRLfWoEPSDRTl10and4owFBV9rJ2CTFNtLIOiw== |
3682 | 3677 | |
3683 | -esbuild@^0.9.2, esbuild@^0.9.3: | |
3684 | - version "0.9.7" | |
3685 | - resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.9.7.tgz#ea0d639cbe4b88ec25fbed4d6ff00c8d788ef70b" | |
3686 | - integrity sha512-VtUf6aQ89VTmMLKrWHYG50uByMF4JQlVysb8dmg6cOgW8JnFCipmz7p+HNBl+RR3LLCuBxFGVauAe2wfnF9bLg== | |
3687 | - | |
3688 | 3678 | escalade@^3.1.1: |
3689 | 3679 | version "3.1.1" |
3690 | 3680 | resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" |
... | ... | @@ -3752,10 +3742,10 @@ eslint-visitor-keys@^2.0.0: |
3752 | 3742 | resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" |
3753 | 3743 | integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== |
3754 | 3744 | |
3755 | -eslint@^7.23.0: | |
3756 | - version "7.23.0" | |
3757 | - resolved "https://registry.npmjs.org/eslint/-/eslint-7.23.0.tgz#8d029d252f6e8cf45894b4bee08f5493f8e94325" | |
3758 | - integrity sha512-kqvNVbdkjzpFy0XOszNwjkKzZ+6TcwCQ/h+ozlcIWwaimBBuhlQ4nN6kbiM2L+OjDcznkTJxzYfRFH92sx4a0Q== | |
3745 | +eslint@^7.24.0: | |
3746 | + version "7.24.0" | |
3747 | + resolved "https://registry.npmjs.org/eslint/-/eslint-7.24.0.tgz#2e44fa62d93892bfdb100521f17345ba54b8513a" | |
3748 | + integrity sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ== | |
3759 | 3749 | dependencies: |
3760 | 3750 | "@babel/code-frame" "7.12.11" |
3761 | 3751 | "@eslint/eslintrc" "^0.4.0" |
... | ... | @@ -6942,6 +6932,11 @@ pify@^4.0.1: |
6942 | 6932 | resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" |
6943 | 6933 | integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== |
6944 | 6934 | |
6935 | +pinia@^2.0.0-alpha.12: | |
6936 | + version "2.0.0-alpha.12" | |
6937 | + resolved "https://registry.npmjs.org/pinia/-/pinia-2.0.0-alpha.12.tgz#690e9a7b4c176bb9d95fe0dc8ec4ab8847b09493" | |
6938 | + integrity sha512-qmcDpuoAwxQKAVp7/cOkXFYDaja+vyXMWR6kvdyzeJcGGMvZf1HQ2xFhUSW5lf1eW5IiQP0cBRdF3ZDyVa+JIQ== | |
6939 | + | |
6945 | 6940 | pinkie-promise@^2.0.0: |
6946 | 6941 | version "2.0.1" |
6947 | 6942 | resolved "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" |
... | ... | @@ -7691,10 +7686,10 @@ rollup-plugin-visualizer@5.3.0: |
7691 | 7686 | source-map "^0.7.3" |
7692 | 7687 | yargs "^16.2.0" |
7693 | 7688 | |
7694 | -rollup@^2.25.0, rollup@^2.38.5, rollup@^2.44.0: | |
7695 | - version "2.44.0" | |
7696 | - resolved "https://registry.npmjs.org/rollup/-/rollup-2.44.0.tgz#8da324d1c4fd12beef9ae6e12f4068265b6d95eb" | |
7697 | - integrity sha512-rGSF4pLwvuaH/x4nAS+zP6UNn5YUDWf/TeEU5IoXSZKBbKRNTCI3qMnYXKZgrC0D2KzS2baiOZt1OlqhMu5rnQ== | |
7689 | +rollup@^2.25.0, rollup@^2.38.5, rollup@^2.44.0, rollup@^2.45.1: | |
7690 | + version "2.45.1" | |
7691 | + resolved "https://registry.npmjs.org/rollup/-/rollup-2.45.1.tgz#eae2b94dc2088b4e0a3b7197a5a1ee0bdd589d5c" | |
7692 | + integrity sha512-vPD+JoDj3CY8k6m1bLcAFttXMe78P4CMxoau0iLVS60+S9kLsv2379xaGy4NgYWu+h2WTlucpoLPAoUoixFBag== | |
7698 | 7693 | optionalDependencies: |
7699 | 7694 | fsevents "~2.3.1" |
7700 | 7695 | |
... | ... | @@ -9187,15 +9182,15 @@ vite-plugin-theme@^0.6.3: |
9187 | 9182 | esbuild-plugin-alias "^0.1.2" |
9188 | 9183 | tinycolor2 "^1.4.2" |
9189 | 9184 | |
9190 | -vite-plugin-windicss@0.12.5: | |
9191 | - version "0.12.5" | |
9192 | - resolved "https://registry.npmjs.org/vite-plugin-windicss/-/vite-plugin-windicss-0.12.5.tgz#74a5043db3615fe432855f6ecff13be36f7a6843" | |
9193 | - integrity sha512-M/eEA+x94kxZNpEEkJLdY7M6Lp3WFhN0Kb/a2zhdPxBviMwaHSA5A7fUqN1xTYMxlQe4xM7D7naxL7EpnSNlmg== | |
9185 | +vite-plugin-windicss@0.13.1: | |
9186 | + version "0.13.1" | |
9187 | + resolved "https://registry.npmjs.org/vite-plugin-windicss/-/vite-plugin-windicss-0.13.1.tgz#82a488f3395be710ae2166b83b0612a5eaec7738" | |
9188 | + integrity sha512-WmFfTLTMSY5gRC3MWX9o72Yni2HRdrtJ2im+cCyZ2W/p4WE6T702zFCScO8Tnz/E08GDx4OH6oFCZWeZYwgxzg== | |
9194 | 9189 | dependencies: |
9195 | - "@windicss/plugin-utils" "0.12.5" | |
9190 | + "@windicss/plugin-utils" "0.13.1" | |
9196 | 9191 | chalk "^4.1.0" |
9197 | 9192 | debug "^4.3.2" |
9198 | - windicss "^2.5.11" | |
9193 | + windicss "^2.5.12" | |
9199 | 9194 | |
9200 | 9195 | vite@2.1.5: |
9201 | 9196 | version "2.1.5" |
... | ... | @@ -9265,16 +9260,6 @@ vue@^3.0.0: |
9265 | 9260 | "@vue/runtime-dom" "3.0.10" |
9266 | 9261 | "@vue/shared" "3.0.10" |
9267 | 9262 | |
9268 | -vuex-module-decorators@^1.0.1: | |
9269 | - version "1.0.1" | |
9270 | - resolved "https://registry.npmjs.org/vuex-module-decorators/-/vuex-module-decorators-1.0.1.tgz#d34dafb5428a3636f1c26d3d014c15fc9659ccd0" | |
9271 | - integrity sha512-FLWZsXV5XAtl/bcKUyQFpnSBtpc3wK/7zSdy9oKbyp71mZd4ut5y2zSd219wWW9OG7WUOlVwac4rXFFDVnq7ug== | |
9272 | - | |
9273 | -vuex@^4.0.0: | |
9274 | - version "4.0.0" | |
9275 | - resolved "https://registry.npmjs.org/vuex/-/vuex-4.0.0.tgz#ac877aa76a9c45368c979471e461b520d38e6cf5" | |
9276 | - integrity sha512-56VPujlHscP5q/e7Jlpqc40sja4vOhC4uJD1llBCWolVI8ND4+VzisDVkUMl+z5y0MpIImW6HjhNc+ZvuizgOw== | |
9277 | - | |
9278 | 9263 | warning@^4.0.0: |
9279 | 9264 | version "4.0.3" |
9280 | 9265 | resolved "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" |
... | ... | @@ -9326,10 +9311,10 @@ which@^2.0.1: |
9326 | 9311 | dependencies: |
9327 | 9312 | isexe "^2.0.0" |
9328 | 9313 | |
9329 | -windicss@^2.5.11: | |
9330 | - version "2.5.11" | |
9331 | - resolved "https://registry.npmjs.org/windicss/-/windicss-2.5.11.tgz#dd4027c724c7b12a37746d1474b96a52239157d1" | |
9332 | - integrity sha512-u7b4rOPb8MwO1glkf0gdDygZ+lIzXb/PYLNjqni5Fe2684DCEt6dWTKdk3iMxXgbKoqRNncKu7xt3pFwXHdSAw== | |
9314 | +windicss@^2.5.12: | |
9315 | + version "2.5.12" | |
9316 | + resolved "https://registry.npmjs.org/windicss/-/windicss-2.5.12.tgz#7bc469b05d7a8fa3905d49d6521a1ff9107d0ea4" | |
9317 | + integrity sha512-BZ0Ps1C0RlCHBVOPcw/DAReeR9o/mKaoFgkBsVphQ23M5nsvVfVXgGlNJZssjAQsXnlDpj97pnIhtDn1ENBjXw== | |
9333 | 9318 | |
9334 | 9319 | wmf@~1.0.1: |
9335 | 9320 | version "1.0.2" | ... | ... |