mirror of
https://github.com/vbenjs/vben-admin-thin-next.git
synced 2025-01-23 09:40:22 +08:00
refactor: refactor store
This commit is contained in:
parent
700306bb45
commit
215d8bab38
@ -28,6 +28,7 @@ export function generateModifyVars(dark = false) {
|
|||||||
'success-color': '#55D187', // Success color
|
'success-color': '#55D187', // Success color
|
||||||
'error-color': '#ED6F6F', // False color
|
'error-color': '#ED6F6F', // False color
|
||||||
'warning-color': '#EFBD47', // Warning color
|
'warning-color': '#EFBD47', // Warning color
|
||||||
|
'border-color-base': '#EEEEEE',
|
||||||
'font-size-base': '14px', // Main font size
|
'font-size-base': '14px', // Main font size
|
||||||
'border-radius-base': '2px', // Component/float fillet
|
'border-radius-base': '2px', // Component/float fillet
|
||||||
'link-color': primary, // Link color
|
'link-color': primary, // Link color
|
||||||
|
@ -16,9 +16,11 @@
|
|||||||
<script>
|
<script>
|
||||||
(() => {
|
(() => {
|
||||||
var htmlRoot = document.getElementById('htmlRoot');
|
var htmlRoot = document.getElementById('htmlRoot');
|
||||||
const theme = window.localStorage.getItem('__APP__DARK__MODE__');
|
var theme = window.localStorage.getItem('__APP__DARK__MODE__');
|
||||||
if (!htmlRoot || !theme) return;
|
if (htmlRoot && theme) {
|
||||||
htmlRoot.setAttribute('data-theme', theme);
|
htmlRoot.setAttribute('data-theme', theme);
|
||||||
|
theme = htmlRoot = null;
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
|
12
package.json
12
package.json
@ -32,7 +32,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iconify/iconify": "^2.0.0-rc.6",
|
"@iconify/iconify": "^2.0.0-rc.6",
|
||||||
"@vueuse/core": "^4.8.0",
|
"@vueuse/core": "^4.8.1",
|
||||||
"@zxcvbn-ts/core": "^0.3.0",
|
"@zxcvbn-ts/core": "^0.3.0",
|
||||||
"ant-design-vue": "^2.1.2",
|
"ant-design-vue": "^2.1.2",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
@ -43,6 +43,7 @@
|
|||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"path-to-regexp": "^6.2.0",
|
"path-to-regexp": "^6.2.0",
|
||||||
|
"pinia": "^2.0.0-alpha.12",
|
||||||
"print-js": "^1.6.0",
|
"print-js": "^1.6.0",
|
||||||
"qrcode": "^1.4.4",
|
"qrcode": "^1.4.4",
|
||||||
"sortablejs": "^1.13.0",
|
"sortablejs": "^1.13.0",
|
||||||
@ -52,8 +53,6 @@
|
|||||||
"vue-i18n": "9.0.0",
|
"vue-i18n": "9.0.0",
|
||||||
"vue-router": "^4.0.6",
|
"vue-router": "^4.0.6",
|
||||||
"vue-types": "^3.0.2",
|
"vue-types": "^3.0.2",
|
||||||
"vuex": "^4.0.0",
|
|
||||||
"vuex-module-decorators": "^1.0.1",
|
|
||||||
"xlsx": "^0.16.9"
|
"xlsx": "^0.16.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -81,7 +80,7 @@
|
|||||||
"conventional-changelog-cli": "^2.1.1",
|
"conventional-changelog-cli": "^2.1.1",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"eslint": "^7.23.0",
|
"eslint": "^7.24.0",
|
||||||
"eslint-config-prettier": "^8.1.0",
|
"eslint-config-prettier": "^8.1.0",
|
||||||
"eslint-define-config": "^1.0.7",
|
"eslint-define-config": "^1.0.7",
|
||||||
"eslint-plugin-prettier": "^3.3.1",
|
"eslint-plugin-prettier": "^3.3.1",
|
||||||
@ -115,13 +114,14 @@
|
|||||||
"vite-plugin-style-import": "^0.9.2",
|
"vite-plugin-style-import": "^0.9.2",
|
||||||
"vite-plugin-svg-icons": "^0.4.1",
|
"vite-plugin-svg-icons": "^0.4.1",
|
||||||
"vite-plugin-theme": "^0.6.3",
|
"vite-plugin-theme": "^0.6.3",
|
||||||
"vite-plugin-windicss": "0.12.5",
|
"vite-plugin-windicss": "0.13.1",
|
||||||
"vue-eslint-parser": "^7.6.0"
|
"vue-eslint-parser": "^7.6.0"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"//": "Used to install imagemin dependencies, because imagemin may not be installed in China.If it is abroad, you can delete it",
|
"//": "Used to install imagemin dependencies, because imagemin may not be installed in China.If it is abroad, you can delete it",
|
||||||
"bin-wrapper": "npm:bin-wrapper-china",
|
"bin-wrapper": "npm:bin-wrapper-china",
|
||||||
"rollup": "^2.44.0"
|
"rollup": "^2.45.1",
|
||||||
|
"esbuild": "^0.11.6"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -3,22 +3,24 @@
|
|||||||
|
|
||||||
import { createAppProviderContext } from './useAppContext';
|
import { createAppProviderContext } from './useAppContext';
|
||||||
|
|
||||||
import designSetting from '/@/settings/designSetting';
|
import { prefixCls } from '/@/settings/designSetting';
|
||||||
import { createBreakpointListen } from '/@/hooks/event/useBreakpoint';
|
import { createBreakpointListen } from '/@/hooks/event/useBreakpoint';
|
||||||
import { propTypes } from '/@/utils/propTypes';
|
import { propTypes } from '/@/utils/propTypes';
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
|
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'AppProvider',
|
name: 'AppProvider',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
prefixCls: propTypes.string.def(designSetting.prefixCls),
|
prefixCls: propTypes.string.def(prefixCls),
|
||||||
},
|
},
|
||||||
setup(props, { slots }) {
|
setup(props, { slots }) {
|
||||||
const isMobile = ref(false);
|
const isMobile = ref(false);
|
||||||
const isSetState = ref(false);
|
const isSetState = ref(false);
|
||||||
|
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
createBreakpointListen(({ screenMap, sizeEnum, width }) => {
|
createBreakpointListen(({ screenMap, sizeEnum, width }) => {
|
||||||
const lgWidth = screenMap.get(sizeEnum.LG);
|
const lgWidth = screenMap.get(sizeEnum.LG);
|
||||||
if (lgWidth) {
|
if (lgWidth) {
|
||||||
@ -42,20 +44,20 @@
|
|||||||
split: menuSplit,
|
split: menuSplit,
|
||||||
},
|
},
|
||||||
} = appStore.getProjectConfig;
|
} = appStore.getProjectConfig;
|
||||||
appStore.commitProjectConfigState({
|
appStore.setProjectConfig({
|
||||||
menuSetting: {
|
menuSetting: {
|
||||||
type: MenuTypeEnum.SIDEBAR,
|
type: MenuTypeEnum.SIDEBAR,
|
||||||
mode: MenuModeEnum.INLINE,
|
mode: MenuModeEnum.INLINE,
|
||||||
split: false,
|
split: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
appStore.commitBeforeMiniState({ menuMode, menuCollapsed, menuType, menuSplit });
|
appStore.setBeforeMiniInfo({ menuMode, menuCollapsed, menuType, menuSplit });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (unref(isSetState)) {
|
if (unref(isSetState)) {
|
||||||
isSetState.value = false;
|
isSetState.value = false;
|
||||||
const { menuMode, menuCollapsed, menuType, menuSplit } = appStore.getBeforeMiniState;
|
const { menuMode, menuCollapsed, menuType, menuSplit } = appStore.getBeforeMiniInfo;
|
||||||
appStore.commitProjectConfigState({
|
appStore.setProjectConfig({
|
||||||
menuSetting: {
|
menuSetting: {
|
||||||
type: menuType,
|
type: menuType,
|
||||||
mode: menuMode,
|
mode: menuMode,
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<span :class="$attrs.class">
|
<span :class="$attrs.class">
|
||||||
<Icon :icon="icon" />
|
<g-icon :icon="icon" />
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { Icon } from '/@/components/Icon';
|
|
||||||
import { propTypes } from '/@/utils/propTypes';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { Icon },
|
|
||||||
props: {
|
props: {
|
||||||
icon: propTypes.string,
|
icon: String,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
:class="prefixCls"
|
:class="prefixCls"
|
||||||
:activeSubMenuNames="activeSubMenuNames"
|
:activeSubMenuNames="activeSubMenuNames"
|
||||||
@select="handleSelect"
|
@select="handleSelect"
|
||||||
@open-change="handleOpenChange"
|
|
||||||
>
|
>
|
||||||
<template v-for="item in items" :key="item.path">
|
<template v-for="item in items" :key="item.path">
|
||||||
<SimpleSubMenu
|
<SimpleSubMenu
|
||||||
@ -140,17 +139,11 @@
|
|||||||
menuState.activeName = key;
|
menuState.activeName = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleOpenChange(v) {
|
|
||||||
console.log('======================');
|
|
||||||
console.log(v);
|
|
||||||
console.log('======================');
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
prefixCls,
|
prefixCls,
|
||||||
getBindValues,
|
getBindValues,
|
||||||
handleSelect,
|
handleSelect,
|
||||||
getOpenKeys,
|
getOpenKeys,
|
||||||
handleOpenChange,
|
|
||||||
...toRefs(menuState),
|
...toRefs(menuState),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -2,94 +2,89 @@ import type { HeaderSetting } from '/#/config';
|
|||||||
|
|
||||||
import { computed, unref } from 'vue';
|
import { computed, unref } from 'vue';
|
||||||
|
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
|
|
||||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||||
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||||
import { useFullContent } from '/@/hooks/web/useFullContent';
|
import { useFullContent } from '/@/hooks/web/useFullContent';
|
||||||
|
|
||||||
import { MenuModeEnum } from '/@/enums/menuEnum';
|
import { MenuModeEnum } from '/@/enums/menuEnum';
|
||||||
|
|
||||||
const { getFullContent } = useFullContent();
|
|
||||||
const {
|
|
||||||
getMenuMode,
|
|
||||||
getSplit,
|
|
||||||
getShowHeaderTrigger,
|
|
||||||
getIsSidebarType,
|
|
||||||
getIsMixSidebar,
|
|
||||||
getIsTopMenu,
|
|
||||||
} = useMenuSetting();
|
|
||||||
const { getShowBreadCrumb, getShowLogo } = useRootSetting();
|
|
||||||
|
|
||||||
const getShowMixHeaderRef = computed(() => !unref(getIsSidebarType) && unref(getShowHeader));
|
|
||||||
|
|
||||||
const getShowFullHeaderRef = computed(() => {
|
|
||||||
return (
|
|
||||||
!unref(getFullContent) &&
|
|
||||||
unref(getShowMixHeaderRef) &&
|
|
||||||
unref(getShowHeader) &&
|
|
||||||
!unref(getIsTopMenu) &&
|
|
||||||
!unref(getIsMixSidebar)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const getShowInsetHeaderRef = computed(() => {
|
|
||||||
const need = !unref(getFullContent) && unref(getShowHeader);
|
|
||||||
return (
|
|
||||||
(need && !unref(getShowMixHeaderRef)) ||
|
|
||||||
(need && unref(getIsTopMenu)) ||
|
|
||||||
(need && unref(getIsMixSidebar))
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get header configuration
|
|
||||||
const getHeaderSetting = computed(() => appStore.getProjectConfig.headerSetting);
|
|
||||||
|
|
||||||
const getShowDoc = computed(() => unref(getHeaderSetting).showDoc);
|
|
||||||
|
|
||||||
const getHeaderTheme = computed(() => unref(getHeaderSetting).theme);
|
|
||||||
|
|
||||||
const getShowHeader = computed(() => unref(getHeaderSetting).show);
|
|
||||||
|
|
||||||
const getFixed = computed(() => unref(getHeaderSetting).fixed);
|
|
||||||
|
|
||||||
const getHeaderBgColor = computed(() => unref(getHeaderSetting).bgColor);
|
|
||||||
|
|
||||||
const getShowSearch = computed(() => unref(getHeaderSetting).showSearch);
|
|
||||||
|
|
||||||
const getUseLockPage = computed(() => unref(getHeaderSetting).useLockPage);
|
|
||||||
|
|
||||||
const getShowFullScreen = computed(() => unref(getHeaderSetting).showFullScreen);
|
|
||||||
|
|
||||||
const getShowNotice = computed(() => unref(getHeaderSetting).showNotice);
|
|
||||||
|
|
||||||
const getUnFixedAndFull = computed(() => !unref(getFixed) && !unref(getShowFullHeaderRef));
|
|
||||||
|
|
||||||
const getShowBread = computed(() => {
|
|
||||||
return (
|
|
||||||
unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && unref(getShowBreadCrumb) && !unref(getSplit)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const getShowHeaderLogo = computed(() => {
|
|
||||||
return unref(getShowLogo) && !unref(getIsSidebarType) && !unref(getIsMixSidebar);
|
|
||||||
});
|
|
||||||
|
|
||||||
const getShowContent = computed(() => {
|
|
||||||
return unref(getShowBread) || unref(getShowHeaderTrigger);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set header configuration
|
|
||||||
function setHeaderSetting(headerSetting: Partial<HeaderSetting>): void {
|
|
||||||
appStore.commitProjectConfigState({ headerSetting });
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useHeaderSetting() {
|
export function useHeaderSetting() {
|
||||||
|
const { getFullContent } = useFullContent();
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
|
const getShowFullHeaderRef = computed(() => {
|
||||||
|
return (
|
||||||
|
!unref(getFullContent) &&
|
||||||
|
unref(getShowMixHeaderRef) &&
|
||||||
|
unref(getShowHeader) &&
|
||||||
|
!unref(getIsTopMenu) &&
|
||||||
|
!unref(getIsMixSidebar)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const getUnFixedAndFull = computed(() => !unref(getFixed) && !unref(getShowFullHeaderRef));
|
||||||
|
|
||||||
|
const getShowInsetHeaderRef = computed(() => {
|
||||||
|
const need = !unref(getFullContent) && unref(getShowHeader);
|
||||||
|
return (
|
||||||
|
(need && !unref(getShowMixHeaderRef)) ||
|
||||||
|
(need && unref(getIsTopMenu)) ||
|
||||||
|
(need && unref(getIsMixSidebar))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
getMenuMode,
|
||||||
|
getSplit,
|
||||||
|
getShowHeaderTrigger,
|
||||||
|
getIsSidebarType,
|
||||||
|
getIsMixSidebar,
|
||||||
|
getIsTopMenu,
|
||||||
|
} = useMenuSetting();
|
||||||
|
const { getShowBreadCrumb, getShowLogo } = useRootSetting();
|
||||||
|
|
||||||
|
const getShowMixHeaderRef = computed(() => !unref(getIsSidebarType) && unref(getShowHeader));
|
||||||
|
|
||||||
|
const getShowDoc = computed(() => appStore.getHeaderSetting.showDoc);
|
||||||
|
|
||||||
|
const getHeaderTheme = computed(() => appStore.getHeaderSetting.theme);
|
||||||
|
|
||||||
|
const getShowHeader = computed(() => appStore.getHeaderSetting.show);
|
||||||
|
|
||||||
|
const getFixed = computed(() => appStore.getHeaderSetting.fixed);
|
||||||
|
|
||||||
|
const getHeaderBgColor = computed(() => appStore.getHeaderSetting.bgColor);
|
||||||
|
|
||||||
|
const getShowSearch = computed(() => appStore.getHeaderSetting.showSearch);
|
||||||
|
|
||||||
|
const getUseLockPage = computed(() => appStore.getHeaderSetting.useLockPage);
|
||||||
|
|
||||||
|
const getShowFullScreen = computed(() => appStore.getHeaderSetting.showFullScreen);
|
||||||
|
|
||||||
|
const getShowNotice = computed(() => appStore.getHeaderSetting.showNotice);
|
||||||
|
|
||||||
|
const getShowBread = computed(() => {
|
||||||
|
return (
|
||||||
|
unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && unref(getShowBreadCrumb) && !unref(getSplit)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const getShowHeaderLogo = computed(() => {
|
||||||
|
return unref(getShowLogo) && !unref(getIsSidebarType) && !unref(getIsMixSidebar);
|
||||||
|
});
|
||||||
|
|
||||||
|
const getShowContent = computed(() => {
|
||||||
|
return unref(getShowBread) || unref(getShowHeaderTrigger);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set header configuration
|
||||||
|
function setHeaderSetting(headerSetting: Partial<HeaderSetting>) {
|
||||||
|
appStore.setProjectConfig({ headerSetting });
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
setHeaderSetting,
|
setHeaderSetting,
|
||||||
|
|
||||||
getHeaderSetting,
|
|
||||||
|
|
||||||
getShowDoc,
|
getShowDoc,
|
||||||
getShowSearch,
|
getShowSearch,
|
||||||
getHeaderTheme,
|
getHeaderTheme,
|
||||||
|
@ -2,7 +2,7 @@ import type { MenuSetting } from '/#/config';
|
|||||||
|
|
||||||
import { computed, unref, ref } from 'vue';
|
import { computed, unref, ref } from 'vue';
|
||||||
|
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
|
|
||||||
import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
|
import { SIDE_BAR_MINI_WIDTH, SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum';
|
||||||
import { MenuModeEnum, MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum';
|
import { MenuModeEnum, MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum';
|
||||||
@ -10,127 +10,129 @@ import { useFullContent } from '/@/hooks/web/useFullContent';
|
|||||||
|
|
||||||
const mixSideHasChildren = ref(false);
|
const mixSideHasChildren = ref(false);
|
||||||
|
|
||||||
// Get menu configuration
|
|
||||||
const getMenuSetting = computed(() => appStore.getProjectConfig.menuSetting);
|
|
||||||
|
|
||||||
const getCollapsed = computed(() => unref(getMenuSetting).collapsed);
|
|
||||||
|
|
||||||
const getMenuType = computed(() => unref(getMenuSetting).type);
|
|
||||||
|
|
||||||
const getMenuMode = computed(() => unref(getMenuSetting).mode);
|
|
||||||
|
|
||||||
const getMenuFixed = computed(() => unref(getMenuSetting).fixed);
|
|
||||||
|
|
||||||
const getShowMenu = computed(() => unref(getMenuSetting).show);
|
|
||||||
|
|
||||||
const getMenuHidden = computed(() => unref(getMenuSetting).hidden);
|
|
||||||
|
|
||||||
const getMenuWidth = computed(() => unref(getMenuSetting).menuWidth);
|
|
||||||
|
|
||||||
const getTrigger = computed(() => unref(getMenuSetting).trigger);
|
|
||||||
|
|
||||||
const getMenuTheme = computed(() => unref(getMenuSetting).theme);
|
|
||||||
|
|
||||||
const getSplit = computed(() => unref(getMenuSetting).split);
|
|
||||||
|
|
||||||
const getMenuBgColor = computed(() => unref(getMenuSetting).bgColor);
|
|
||||||
|
|
||||||
const getMixSideTrigger = computed(() => unref(getMenuSetting).mixSideTrigger);
|
|
||||||
|
|
||||||
const getCanDrag = computed(() => unref(getMenuSetting).canDrag);
|
|
||||||
|
|
||||||
const getAccordion = computed(() => unref(getMenuSetting).accordion);
|
|
||||||
|
|
||||||
const getMixSideFixed = computed(() => unref(getMenuSetting).mixSideFixed);
|
|
||||||
|
|
||||||
const getTopMenuAlign = computed(() => unref(getMenuSetting).topMenuAlign);
|
|
||||||
|
|
||||||
const getCloseMixSidebarOnChange = computed(() => unref(getMenuSetting).closeMixSidebarOnChange);
|
|
||||||
|
|
||||||
const getIsSidebarType = computed(() => unref(getMenuType) === MenuTypeEnum.SIDEBAR);
|
|
||||||
|
|
||||||
const getIsTopMenu = computed(() => unref(getMenuType) === MenuTypeEnum.TOP_MENU);
|
|
||||||
|
|
||||||
const getCollapsedShowTitle = computed(() => unref(getMenuSetting).collapsedShowTitle);
|
|
||||||
|
|
||||||
const getShowTopMenu = computed(() => {
|
|
||||||
return unref(getMenuMode) === MenuModeEnum.HORIZONTAL || unref(getSplit);
|
|
||||||
});
|
|
||||||
|
|
||||||
const getShowHeaderTrigger = computed(() => {
|
|
||||||
if (unref(getMenuType) === MenuTypeEnum.TOP_MENU || !unref(getShowMenu) || unref(getMenuHidden)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return unref(getTrigger) === TriggerEnum.HEADER;
|
|
||||||
});
|
|
||||||
|
|
||||||
const getIsHorizontal = computed(() => {
|
|
||||||
return unref(getMenuMode) === MenuModeEnum.HORIZONTAL;
|
|
||||||
});
|
|
||||||
|
|
||||||
const getIsMixSidebar = computed(() => {
|
|
||||||
return unref(getMenuType) === MenuTypeEnum.MIX_SIDEBAR;
|
|
||||||
});
|
|
||||||
|
|
||||||
const getIsMixMode = computed(() => {
|
|
||||||
return unref(getMenuMode) === MenuModeEnum.INLINE && unref(getMenuType) === MenuTypeEnum.MIX;
|
|
||||||
});
|
|
||||||
|
|
||||||
const getRealWidth = computed(() => {
|
|
||||||
if (unref(getIsMixSidebar)) {
|
|
||||||
return unref(getCollapsed) && !unref(getMixSideFixed)
|
|
||||||
? unref(getMiniWidthNumber)
|
|
||||||
: unref(getMenuWidth);
|
|
||||||
}
|
|
||||||
return unref(getCollapsed) ? unref(getMiniWidthNumber) : unref(getMenuWidth);
|
|
||||||
});
|
|
||||||
|
|
||||||
const getMiniWidthNumber = computed(() => {
|
|
||||||
const { collapsedShowTitle } = unref(getMenuSetting);
|
|
||||||
return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH;
|
|
||||||
});
|
|
||||||
|
|
||||||
const getCalcContentWidth = computed(() => {
|
|
||||||
const width =
|
|
||||||
unref(getIsTopMenu) || !unref(getShowMenu) || (unref(getSplit) && unref(getMenuHidden))
|
|
||||||
? 0
|
|
||||||
: unref(getIsMixSidebar)
|
|
||||||
? (unref(getCollapsed) ? SIDE_BAR_MINI_WIDTH : SIDE_BAR_SHOW_TIT_MINI_WIDTH) +
|
|
||||||
(unref(getMixSideFixed) && unref(mixSideHasChildren) ? unref(getRealWidth) : 0)
|
|
||||||
: unref(getRealWidth);
|
|
||||||
|
|
||||||
return `calc(100% - ${unref(width)}px)`;
|
|
||||||
});
|
|
||||||
|
|
||||||
const { getFullContent: fullContent } = useFullContent();
|
|
||||||
|
|
||||||
const getShowSidebar = computed(() => {
|
|
||||||
return (
|
|
||||||
unref(getSplit) ||
|
|
||||||
(unref(getShowMenu) && unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && !unref(fullContent))
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set menu configuration
|
|
||||||
function setMenuSetting(menuSetting: Partial<MenuSetting>): void {
|
|
||||||
appStore.commitProjectConfigState({ menuSetting });
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleCollapsed() {
|
|
||||||
setMenuSetting({
|
|
||||||
collapsed: !unref(getCollapsed),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useMenuSetting() {
|
export function useMenuSetting() {
|
||||||
|
const { getFullContent: fullContent } = useFullContent();
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
|
const getShowSidebar = computed(() => {
|
||||||
|
return (
|
||||||
|
unref(getSplit) ||
|
||||||
|
(unref(getShowMenu) && unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && !unref(fullContent))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const getCollapsed = computed(() => appStore.getMenuSetting.collapsed);
|
||||||
|
|
||||||
|
const getMenuType = computed(() => appStore.getMenuSetting.type);
|
||||||
|
|
||||||
|
const getMenuMode = computed(() => appStore.getMenuSetting.mode);
|
||||||
|
|
||||||
|
const getMenuFixed = computed(() => appStore.getMenuSetting.fixed);
|
||||||
|
|
||||||
|
const getShowMenu = computed(() => appStore.getMenuSetting.show);
|
||||||
|
|
||||||
|
const getMenuHidden = computed(() => appStore.getMenuSetting.hidden);
|
||||||
|
|
||||||
|
const getMenuWidth = computed(() => appStore.getMenuSetting.menuWidth);
|
||||||
|
|
||||||
|
const getTrigger = computed(() => appStore.getMenuSetting.trigger);
|
||||||
|
|
||||||
|
const getMenuTheme = computed(() => appStore.getMenuSetting.theme);
|
||||||
|
|
||||||
|
const getSplit = computed(() => appStore.getMenuSetting.split);
|
||||||
|
|
||||||
|
const getMenuBgColor = computed(() => appStore.getMenuSetting.bgColor);
|
||||||
|
|
||||||
|
const getMixSideTrigger = computed(() => appStore.getMenuSetting.mixSideTrigger);
|
||||||
|
|
||||||
|
const getCanDrag = computed(() => appStore.getMenuSetting.canDrag);
|
||||||
|
|
||||||
|
const getAccordion = computed(() => appStore.getMenuSetting.accordion);
|
||||||
|
|
||||||
|
const getMixSideFixed = computed(() => appStore.getMenuSetting.mixSideFixed);
|
||||||
|
|
||||||
|
const getTopMenuAlign = computed(() => appStore.getMenuSetting.topMenuAlign);
|
||||||
|
|
||||||
|
const getCloseMixSidebarOnChange = computed(
|
||||||
|
() => appStore.getMenuSetting.closeMixSidebarOnChange
|
||||||
|
);
|
||||||
|
|
||||||
|
const getIsSidebarType = computed(() => unref(getMenuType) === MenuTypeEnum.SIDEBAR);
|
||||||
|
|
||||||
|
const getIsTopMenu = computed(() => unref(getMenuType) === MenuTypeEnum.TOP_MENU);
|
||||||
|
|
||||||
|
const getCollapsedShowTitle = computed(() => appStore.getMenuSetting.collapsedShowTitle);
|
||||||
|
|
||||||
|
const getShowTopMenu = computed(() => {
|
||||||
|
return unref(getMenuMode) === MenuModeEnum.HORIZONTAL || unref(getSplit);
|
||||||
|
});
|
||||||
|
|
||||||
|
const getShowHeaderTrigger = computed(() => {
|
||||||
|
if (
|
||||||
|
unref(getMenuType) === MenuTypeEnum.TOP_MENU ||
|
||||||
|
!unref(getShowMenu) ||
|
||||||
|
unref(getMenuHidden)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return unref(getTrigger) === TriggerEnum.HEADER;
|
||||||
|
});
|
||||||
|
|
||||||
|
const getIsHorizontal = computed(() => {
|
||||||
|
return unref(getMenuMode) === MenuModeEnum.HORIZONTAL;
|
||||||
|
});
|
||||||
|
|
||||||
|
const getIsMixSidebar = computed(() => {
|
||||||
|
return unref(getMenuType) === MenuTypeEnum.MIX_SIDEBAR;
|
||||||
|
});
|
||||||
|
|
||||||
|
const getIsMixMode = computed(() => {
|
||||||
|
return unref(getMenuMode) === MenuModeEnum.INLINE && unref(getMenuType) === MenuTypeEnum.MIX;
|
||||||
|
});
|
||||||
|
|
||||||
|
const getRealWidth = computed(() => {
|
||||||
|
if (unref(getIsMixSidebar)) {
|
||||||
|
return unref(getCollapsed) && !unref(getMixSideFixed)
|
||||||
|
? unref(getMiniWidthNumber)
|
||||||
|
: unref(getMenuWidth);
|
||||||
|
}
|
||||||
|
return unref(getCollapsed) ? unref(getMiniWidthNumber) : unref(getMenuWidth);
|
||||||
|
});
|
||||||
|
|
||||||
|
const getMiniWidthNumber = computed(() => {
|
||||||
|
const { collapsedShowTitle } = appStore.getMenuSetting;
|
||||||
|
return collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH;
|
||||||
|
});
|
||||||
|
|
||||||
|
const getCalcContentWidth = computed(() => {
|
||||||
|
const width =
|
||||||
|
unref(getIsTopMenu) || !unref(getShowMenu) || (unref(getSplit) && unref(getMenuHidden))
|
||||||
|
? 0
|
||||||
|
: unref(getIsMixSidebar)
|
||||||
|
? (unref(getCollapsed) ? SIDE_BAR_MINI_WIDTH : SIDE_BAR_SHOW_TIT_MINI_WIDTH) +
|
||||||
|
(unref(getMixSideFixed) && unref(mixSideHasChildren) ? unref(getRealWidth) : 0)
|
||||||
|
: unref(getRealWidth);
|
||||||
|
|
||||||
|
return `calc(100% - ${unref(width)}px)`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set menu configuration
|
||||||
|
function setMenuSetting(menuSetting: Partial<MenuSetting>): void {
|
||||||
|
appStore.setProjectConfig({ menuSetting });
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleCollapsed() {
|
||||||
|
setMenuSetting({
|
||||||
|
collapsed: !unref(getCollapsed),
|
||||||
|
});
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
setMenuSetting,
|
setMenuSetting,
|
||||||
|
|
||||||
toggleCollapsed,
|
toggleCollapsed,
|
||||||
|
|
||||||
getMenuFixed,
|
getMenuFixed,
|
||||||
getMenuSetting,
|
|
||||||
getRealWidth,
|
getRealWidth,
|
||||||
getMenuType,
|
getMenuType,
|
||||||
getMenuMode,
|
getMenuMode,
|
||||||
|
@ -1,28 +1,25 @@
|
|||||||
import type { MultiTabsSetting } from '/#/config';
|
import type { MultiTabsSetting } from '/#/config';
|
||||||
|
|
||||||
import { computed, unref } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
|
|
||||||
const getMultipleTabSetting = computed(() => appStore.getProjectConfig.multiTabsSetting);
|
|
||||||
|
|
||||||
const getShowMultipleTab = computed(() => unref(getMultipleTabSetting).show);
|
|
||||||
|
|
||||||
const getShowQuick = computed(() => unref(getMultipleTabSetting).showQuick);
|
|
||||||
|
|
||||||
const getShowRedo = computed(() => unref(getMultipleTabSetting).showRedo);
|
|
||||||
|
|
||||||
const getShowFold = computed(() => unref(getMultipleTabSetting).showFold);
|
|
||||||
|
|
||||||
function setMultipleTabSetting(multiTabsSetting: Partial<MultiTabsSetting>) {
|
|
||||||
appStore.commitProjectConfigState({ multiTabsSetting });
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useMultipleTabSetting() {
|
export function useMultipleTabSetting() {
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
|
const getShowMultipleTab = computed(() => appStore.getMultiTabsSetting.show);
|
||||||
|
|
||||||
|
const getShowQuick = computed(() => appStore.getMultiTabsSetting.showQuick);
|
||||||
|
|
||||||
|
const getShowRedo = computed(() => appStore.getMultiTabsSetting.showRedo);
|
||||||
|
|
||||||
|
const getShowFold = computed(() => appStore.getMultiTabsSetting.showFold);
|
||||||
|
|
||||||
|
function setMultipleTabSetting(multiTabsSetting: Partial<MultiTabsSetting>) {
|
||||||
|
appStore.setProjectConfig({ multiTabsSetting });
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
setMultipleTabSetting,
|
setMultipleTabSetting,
|
||||||
|
|
||||||
getMultipleTabSetting,
|
|
||||||
getShowMultipleTab,
|
getShowMultipleTab,
|
||||||
getShowQuick,
|
getShowQuick,
|
||||||
getShowRedo,
|
getShowRedo,
|
||||||
|
@ -1,71 +1,71 @@
|
|||||||
import type { ProjectConfig } from '/#/config';
|
import type { ProjectConfig } from '/#/config';
|
||||||
|
|
||||||
import { computed, unref } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
import { ContentEnum } from '/@/enums/appEnum';
|
import { ContentEnum, ThemeEnum } from '/@/enums/appEnum';
|
||||||
import { ThemeEnum } from '../../enums/appEnum';
|
|
||||||
|
|
||||||
type RootSetting = Omit<
|
type RootSetting = Omit<
|
||||||
ProjectConfig,
|
ProjectConfig,
|
||||||
'locale' | 'headerSetting' | 'menuSetting' | 'multiTabsSetting'
|
'locale' | 'headerSetting' | 'menuSetting' | 'multiTabsSetting'
|
||||||
>;
|
>;
|
||||||
|
|
||||||
const getRootSetting = computed((): RootSetting => appStore.getProjectConfig);
|
|
||||||
|
|
||||||
const getPageLoading = computed(() => appStore.getPageLoading);
|
|
||||||
|
|
||||||
const getOpenKeepAlive = computed(() => unref(getRootSetting).openKeepAlive);
|
|
||||||
|
|
||||||
const getSettingButtonPosition = computed(() => unref(getRootSetting).settingButtonPosition);
|
|
||||||
|
|
||||||
const getCanEmbedIFramePage = computed(() => unref(getRootSetting).canEmbedIFramePage);
|
|
||||||
|
|
||||||
const getPermissionMode = computed(() => unref(getRootSetting).permissionMode);
|
|
||||||
|
|
||||||
const getShowLogo = computed(() => unref(getRootSetting).showLogo);
|
|
||||||
|
|
||||||
const getContentMode = computed(() => unref(getRootSetting).contentMode);
|
|
||||||
|
|
||||||
const getUseOpenBackTop = computed(() => unref(getRootSetting).useOpenBackTop);
|
|
||||||
|
|
||||||
const getShowSettingButton = computed(() => unref(getRootSetting).showSettingButton);
|
|
||||||
|
|
||||||
const getUseErrorHandle = computed(() => unref(getRootSetting).useErrorHandle);
|
|
||||||
|
|
||||||
const getShowFooter = computed(() => unref(getRootSetting).showFooter);
|
|
||||||
|
|
||||||
const getShowBreadCrumb = computed(() => unref(getRootSetting).showBreadCrumb);
|
|
||||||
|
|
||||||
const getThemeColor = computed(() => unref(getRootSetting).themeColor);
|
|
||||||
|
|
||||||
const getShowBreadCrumbIcon = computed(() => unref(getRootSetting).showBreadCrumbIcon);
|
|
||||||
|
|
||||||
const getFullContent = computed(() => unref(getRootSetting).fullContent);
|
|
||||||
|
|
||||||
const getColorWeak = computed(() => unref(getRootSetting).colorWeak);
|
|
||||||
|
|
||||||
const getGrayMode = computed(() => unref(getRootSetting).grayMode);
|
|
||||||
|
|
||||||
const getLockTime = computed(() => unref(getRootSetting).lockTime);
|
|
||||||
|
|
||||||
const getShowDarkModeToggle = computed(() => unref(getRootSetting).showDarkModeToggle);
|
|
||||||
|
|
||||||
const getDarkMode = computed(() => appStore.getDarkMode);
|
|
||||||
|
|
||||||
const getLayoutContentMode = computed(() =>
|
|
||||||
unref(getRootSetting).contentMode === ContentEnum.FULL ? ContentEnum.FULL : ContentEnum.FIXED
|
|
||||||
);
|
|
||||||
|
|
||||||
function setRootSetting(setting: Partial<RootSetting>) {
|
|
||||||
appStore.commitProjectConfigState(setting);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setDarkMode(mode: ThemeEnum) {
|
|
||||||
appStore.commitDarkMode(mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useRootSetting() {
|
export function useRootSetting() {
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
|
const getPageLoading = computed(() => appStore.getPageLoading);
|
||||||
|
|
||||||
|
const getOpenKeepAlive = computed(() => appStore.getProjectConfig.openKeepAlive);
|
||||||
|
|
||||||
|
const getSettingButtonPosition = computed(() => appStore.getProjectConfig.settingButtonPosition);
|
||||||
|
|
||||||
|
const getCanEmbedIFramePage = computed(() => appStore.getProjectConfig.canEmbedIFramePage);
|
||||||
|
|
||||||
|
const getPermissionMode = computed(() => appStore.getProjectConfig.permissionMode);
|
||||||
|
|
||||||
|
const getShowLogo = computed(() => appStore.getProjectConfig.showLogo);
|
||||||
|
|
||||||
|
const getContentMode = computed(() => appStore.getProjectConfig.contentMode);
|
||||||
|
|
||||||
|
const getUseOpenBackTop = computed(() => appStore.getProjectConfig.useOpenBackTop);
|
||||||
|
|
||||||
|
const getShowSettingButton = computed(() => appStore.getProjectConfig.showSettingButton);
|
||||||
|
|
||||||
|
const getUseErrorHandle = computed(() => appStore.getProjectConfig.useErrorHandle);
|
||||||
|
|
||||||
|
const getShowFooter = computed(() => appStore.getProjectConfig.showFooter);
|
||||||
|
|
||||||
|
const getShowBreadCrumb = computed(() => appStore.getProjectConfig.showBreadCrumb);
|
||||||
|
|
||||||
|
const getThemeColor = computed(() => appStore.getProjectConfig.themeColor);
|
||||||
|
|
||||||
|
const getShowBreadCrumbIcon = computed(() => appStore.getProjectConfig.showBreadCrumbIcon);
|
||||||
|
|
||||||
|
const getFullContent = computed(() => appStore.getProjectConfig.fullContent);
|
||||||
|
|
||||||
|
const getColorWeak = computed(() => appStore.getProjectConfig.colorWeak);
|
||||||
|
|
||||||
|
const getGrayMode = computed(() => appStore.getProjectConfig.grayMode);
|
||||||
|
|
||||||
|
const getLockTime = computed(() => appStore.getProjectConfig.lockTime);
|
||||||
|
|
||||||
|
const getShowDarkModeToggle = computed(() => appStore.getProjectConfig.showDarkModeToggle);
|
||||||
|
|
||||||
|
const getDarkMode = computed(() => appStore.getDarkMode);
|
||||||
|
|
||||||
|
const getLayoutContentMode = computed(() =>
|
||||||
|
appStore.getProjectConfig.contentMode === ContentEnum.FULL
|
||||||
|
? ContentEnum.FULL
|
||||||
|
: ContentEnum.FIXED
|
||||||
|
);
|
||||||
|
|
||||||
|
function setRootSetting(setting: Partial<RootSetting>) {
|
||||||
|
appStore.setProjectConfig(setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDarkMode(mode: ThemeEnum) {
|
||||||
|
appStore.setDarkMode(mode);
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
setRootSetting,
|
setRootSetting,
|
||||||
|
|
||||||
@ -73,7 +73,6 @@ export function useRootSetting() {
|
|||||||
getFullContent,
|
getFullContent,
|
||||||
getColorWeak,
|
getColorWeak,
|
||||||
getGrayMode,
|
getGrayMode,
|
||||||
getRootSetting,
|
|
||||||
getLayoutContentMode,
|
getLayoutContentMode,
|
||||||
getPageLoading,
|
getPageLoading,
|
||||||
getOpenKeepAlive,
|
getOpenKeepAlive,
|
||||||
|
@ -1,30 +1,28 @@
|
|||||||
import type { TransitionSetting } from '/#/config';
|
import type { TransitionSetting } from '/#/config';
|
||||||
|
|
||||||
import { computed, unref } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
|
|
||||||
const getTransitionSetting = computed(() => appStore.getProjectConfig.transitionSetting);
|
|
||||||
|
|
||||||
const getEnableTransition = computed(() => unref(getTransitionSetting)?.enable);
|
|
||||||
|
|
||||||
const getOpenNProgress = computed(() => unref(getTransitionSetting)?.openNProgress);
|
|
||||||
|
|
||||||
const getOpenPageLoading = computed((): boolean => {
|
|
||||||
return !!unref(getTransitionSetting)?.openPageLoading;
|
|
||||||
});
|
|
||||||
|
|
||||||
const getBasicTransition = computed(() => unref(getTransitionSetting)?.basicTransition);
|
|
||||||
|
|
||||||
function setTransitionSetting(transitionSetting: Partial<TransitionSetting>) {
|
|
||||||
appStore.commitProjectConfigState({ transitionSetting });
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useTransitionSetting() {
|
export function useTransitionSetting() {
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
|
const getEnableTransition = computed(() => appStore.getTransitionSetting?.enable);
|
||||||
|
|
||||||
|
const getOpenNProgress = computed(() => appStore.getTransitionSetting?.openNProgress);
|
||||||
|
|
||||||
|
const getOpenPageLoading = computed((): boolean => {
|
||||||
|
return !!appStore.getTransitionSetting?.openPageLoading;
|
||||||
|
});
|
||||||
|
|
||||||
|
const getBasicTransition = computed(() => appStore.getTransitionSetting?.basicTransition);
|
||||||
|
|
||||||
|
function setTransitionSetting(transitionSetting: Partial<TransitionSetting>) {
|
||||||
|
appStore.setProjectConfig({ transitionSetting });
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
setTransitionSetting,
|
setTransitionSetting,
|
||||||
|
|
||||||
getTransitionSetting,
|
|
||||||
getEnableTransition,
|
getEnableTransition,
|
||||||
getOpenNProgress,
|
getOpenNProgress,
|
||||||
getOpenPageLoading,
|
getOpenPageLoading,
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
|
import type { EChartsOption } from 'echarts';
|
||||||
|
import type { Ref } from 'vue';
|
||||||
|
|
||||||
import { useTimeoutFn } from '/@/hooks/core/useTimeout';
|
import { useTimeoutFn } from '/@/hooks/core/useTimeout';
|
||||||
import { tryOnUnmounted } from '@vueuse/core';
|
import { tryOnUnmounted } from '@vueuse/core';
|
||||||
import { unref, Ref, nextTick, watch, computed, ref } from 'vue';
|
import { unref, nextTick, watch, computed, ref } from 'vue';
|
||||||
import type { EChartsOption } from 'echarts';
|
|
||||||
import { useDebounce } from '/@/hooks/core/useDebounce';
|
import { useDebounce } from '/@/hooks/core/useDebounce';
|
||||||
import { useEventListener } from '/@/hooks/event/useEventListener';
|
import { useEventListener } from '/@/hooks/event/useEventListener';
|
||||||
import { useBreakpoint } from '/@/hooks/event/useBreakpoint';
|
import { useBreakpoint } from '/@/hooks/event/useBreakpoint';
|
||||||
|
|
||||||
import echarts from '/@/plugins/echarts';
|
import echarts from './echarts';
|
||||||
import { useRootSetting } from '../setting/useRootSetting';
|
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||||
|
|
||||||
export function useECharts(
|
export function useECharts(
|
||||||
elRef: Ref<HTMLDivElement>,
|
elRef: Ref<HTMLDivElement>,
|
@ -1,6 +1,6 @@
|
|||||||
import { computed, unref } from 'vue';
|
import { computed, unref } from 'vue';
|
||||||
|
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
|
|
||||||
import router from '/@/router';
|
import router from '/@/router';
|
||||||
|
|
||||||
@ -8,6 +8,7 @@ import router from '/@/router';
|
|||||||
* @description: Full screen display content
|
* @description: Full screen display content
|
||||||
*/
|
*/
|
||||||
export const useFullContent = () => {
|
export const useFullContent = () => {
|
||||||
|
const appStore = useAppStore();
|
||||||
const { currentRoute } = router;
|
const { currentRoute } = router;
|
||||||
|
|
||||||
// Whether to display the content in full screen without displaying the menu
|
// Whether to display the content in full screen without displaying the menu
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
import { computed, onUnmounted, unref, watchEffect } from 'vue';
|
import { computed, onUnmounted, unref, watchEffect } from 'vue';
|
||||||
import { useThrottle } from '/@/hooks/core/useThrottle';
|
import { useThrottle } from '/@/hooks/core/useThrottle';
|
||||||
|
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
import { lockStore } from '/@/store/modules/lock';
|
import { useLockStore } from '/@/store/modules/lock';
|
||||||
import { userStore } from '/@/store/modules/user';
|
|
||||||
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
import { useRootSetting } from '../setting/useRootSetting';
|
import { useRootSetting } from '../setting/useRootSetting';
|
||||||
|
|
||||||
export function useLockPage() {
|
export function useLockPage() {
|
||||||
const { getLockTime } = useRootSetting();
|
const { getLockTime } = useRootSetting();
|
||||||
|
const lockStore = useLockStore();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
let timeId: TimeoutHandle;
|
let timeId: TimeoutHandle;
|
||||||
|
|
||||||
function clear(): void {
|
function clear(): void {
|
||||||
@ -16,7 +21,7 @@ export function useLockPage() {
|
|||||||
|
|
||||||
function resetCalcLockTimeout(): void {
|
function resetCalcLockTimeout(): void {
|
||||||
// not login
|
// not login
|
||||||
if (!userStore.getTokenState) {
|
if (!userStore.getToken) {
|
||||||
clear();
|
clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -33,14 +38,14 @@ export function useLockPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function lockPage(): void {
|
function lockPage(): void {
|
||||||
lockStore.commitLockInfoState({
|
lockStore.setLockInfo({
|
||||||
isLock: true,
|
isLock: true,
|
||||||
pwd: undefined,
|
pwd: undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
watchEffect((onClean) => {
|
watchEffect((onClean) => {
|
||||||
if (userStore.getTokenState) {
|
if (userStore.getToken) {
|
||||||
resetCalcLockTimeout();
|
resetCalcLockTimeout();
|
||||||
} else {
|
} else {
|
||||||
clear();
|
clear();
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import type { RouteLocationRaw } from 'vue-router';
|
import type { RouteLocationRaw, Router } from 'vue-router';
|
||||||
|
|
||||||
import { PageEnum } from '/@/enums/pageEnum';
|
import { PageEnum } from '/@/enums/pageEnum';
|
||||||
import { isString } from '/@/utils/is';
|
import { isString } from '/@/utils/is';
|
||||||
import { unref } from 'vue';
|
import { unref } from 'vue';
|
||||||
|
|
||||||
import router from '/@/router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
export type RouteLocationRawEx = Omit<RouteLocationRaw, 'path'> & { path: PageEnum };
|
export type RouteLocationRawEx = Omit<RouteLocationRaw, 'path'> & { path: PageEnum };
|
||||||
|
|
||||||
@ -13,10 +13,16 @@ function handleError(e: Error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// page switch
|
// page switch
|
||||||
export function useGo() {
|
export function useGo(_router?: Router) {
|
||||||
const { push, replace } = router;
|
let router;
|
||||||
|
if (!_router) {
|
||||||
|
router = useRouter();
|
||||||
|
}
|
||||||
|
const { push, replace } = _router || router;
|
||||||
function go(opt: PageEnum | RouteLocationRawEx | string = PageEnum.BASE_HOME, isReplace = false) {
|
function go(opt: PageEnum | RouteLocationRawEx | string = PageEnum.BASE_HOME, isReplace = false) {
|
||||||
if (!opt) return;
|
if (!opt) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (isString(opt)) {
|
if (isString(opt)) {
|
||||||
isReplace ? replace(opt).catch(handleError) : push(opt).catch(handleError);
|
isReplace ? replace(opt).catch(handleError) : push(opt).catch(handleError);
|
||||||
} else {
|
} else {
|
||||||
@ -30,8 +36,12 @@ export function useGo() {
|
|||||||
/**
|
/**
|
||||||
* @description: redo current page
|
* @description: redo current page
|
||||||
*/
|
*/
|
||||||
export const useRedo = () => {
|
export const useRedo = (_router?: Router) => {
|
||||||
const { push, currentRoute } = router;
|
let router;
|
||||||
|
if (!_router) {
|
||||||
|
router = useRouter();
|
||||||
|
}
|
||||||
|
const { push, currentRoute } = _router || router;
|
||||||
const { query, params } = currentRoute.value;
|
const { query, params } = currentRoute.value;
|
||||||
function redo(): Promise<boolean> {
|
function redo(): Promise<boolean> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router';
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
|
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
import { permissionStore } from '/@/store/modules/permission';
|
import { usePermissionStore } from '/@/store/modules/permission';
|
||||||
import { userStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
|
|
||||||
import { useTabs } from './useTabs';
|
import { useTabs } from './useTabs';
|
||||||
|
|
||||||
@ -15,15 +15,20 @@ import { RoleEnum } from '/@/enums/roleEnum';
|
|||||||
|
|
||||||
import { intersection } from 'lodash-es';
|
import { intersection } from 'lodash-es';
|
||||||
import { isArray } from '/@/utils/is';
|
import { isArray } from '/@/utils/is';
|
||||||
import { tabStore } from '/@/store/modules/tab';
|
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
|
||||||
|
|
||||||
// User permissions related operations
|
// User permissions related operations
|
||||||
export function usePermission() {
|
export function usePermission() {
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const appStore = useAppStore();
|
||||||
|
const permissionStore = usePermissionStore();
|
||||||
|
const { closeAll } = useTabs(router);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change permission mode
|
* Change permission mode
|
||||||
*/
|
*/
|
||||||
async function togglePermissionMode() {
|
async function togglePermissionMode() {
|
||||||
appStore.commitProjectConfigState({
|
appStore.setProjectConfig({
|
||||||
permissionMode:
|
permissionMode:
|
||||||
projectSetting.permissionMode === PermissionModeEnum.BACK
|
projectSetting.permissionMode === PermissionModeEnum.BACK
|
||||||
? PermissionModeEnum.ROLE
|
? PermissionModeEnum.ROLE
|
||||||
@ -37,14 +42,14 @@ export function usePermission() {
|
|||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
async function resume(id?: string | number) {
|
async function resume(id?: string | number) {
|
||||||
tabStore.commitClearCache();
|
const tabStore = useMultipleTabStore();
|
||||||
|
tabStore.clearCacheTabs();
|
||||||
resetRouter();
|
resetRouter();
|
||||||
const routes = await permissionStore.buildRoutesAction(id);
|
const routes = await permissionStore.buildRoutesAction(id);
|
||||||
routes.forEach((route) => {
|
routes.forEach((route) => {
|
||||||
router.addRoute((route as unknown) as RouteRecordRaw);
|
router.addRoute((route as unknown) as RouteRecordRaw);
|
||||||
});
|
});
|
||||||
permissionStore.commitLastBuildMenuTimeState();
|
permissionStore.setLastBuildMenuTime();
|
||||||
const { closeAll } = useTabs();
|
|
||||||
closeAll();
|
closeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,22 +58,24 @@ export function usePermission() {
|
|||||||
*/
|
*/
|
||||||
function hasPermission(value?: RoleEnum | RoleEnum[] | string | string[], def = true): boolean {
|
function hasPermission(value?: RoleEnum | RoleEnum[] | string | string[], def = true): boolean {
|
||||||
const permMode = projectSetting.permissionMode;
|
const permMode = projectSetting.permissionMode;
|
||||||
|
|
||||||
if (PermissionModeEnum.ROLE === permMode) {
|
if (PermissionModeEnum.ROLE === permMode) {
|
||||||
// Visible by default
|
// Visible by default
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
if (!isArray(value)) {
|
if (!isArray(value)) {
|
||||||
return userStore.getRoleListState?.includes(value as RoleEnum);
|
return userStore.getRoleList?.includes(value as RoleEnum);
|
||||||
}
|
}
|
||||||
return (intersection(value, userStore.getRoleListState) as RoleEnum[]).length > 0;
|
return (intersection(value, userStore.getRoleList) as RoleEnum[]).length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PermissionModeEnum.BACK === permMode) {
|
if (PermissionModeEnum.BACK === permMode) {
|
||||||
// Visible by default
|
// Visible by default
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
const allCodeList = permissionStore.getPermCodeListState;
|
const allCodeList = permissionStore.getPermCodeList;
|
||||||
if (!isArray(value)) {
|
if (!isArray(value)) {
|
||||||
return allCodeList.includes(value as string);
|
return allCodeList.includes(value as string);
|
||||||
}
|
}
|
||||||
@ -90,7 +97,7 @@ export function usePermission() {
|
|||||||
if (!isArray(roles)) {
|
if (!isArray(roles)) {
|
||||||
roles = [roles];
|
roles = [roles];
|
||||||
}
|
}
|
||||||
userStore.commitRoleListState(roles);
|
userStore.setRoleList(roles);
|
||||||
await resume();
|
await resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,28 +1,85 @@
|
|||||||
import { tabStore } from '/@/store/modules/tab';
|
import type { RouteLocationNormalized, Router } from 'vue-router';
|
||||||
import { appStore } from '/@/store/modules/app';
|
|
||||||
import type { RouteLocationNormalized } from 'vue-router';
|
|
||||||
|
|
||||||
export function useTabs() {
|
import { useRouter } from 'vue-router';
|
||||||
function canIUseFn(): boolean {
|
import { unref } from 'vue';
|
||||||
const { multiTabsSetting: { show } = {} } = appStore.getProjectConfig;
|
|
||||||
|
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
|
||||||
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
|
|
||||||
|
enum TableActionEnum {
|
||||||
|
REFRESH,
|
||||||
|
CLOSE_ALL,
|
||||||
|
CLOSE_LEFT,
|
||||||
|
CLOSE_RIGHT,
|
||||||
|
CLOSE_OTHER,
|
||||||
|
CLOSE_CURRENT,
|
||||||
|
CLOSE,
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useTabs(_router: Router) {
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
|
function canIUseTabs(): boolean {
|
||||||
|
const { show } = appStore.getMultiTabsSetting;
|
||||||
if (!show) {
|
if (!show) {
|
||||||
throw new Error('The multi-tab page is currently not open, please open it in the settings!');
|
throw new Error('The multi-tab page is currently not open, please open it in the settings!');
|
||||||
}
|
}
|
||||||
return !!show;
|
return !!show;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tabStore = useMultipleTabStore();
|
||||||
|
const router = _router || useRouter();
|
||||||
|
|
||||||
|
const { currentRoute } = router;
|
||||||
|
|
||||||
|
function getCurrentTab() {
|
||||||
|
const route = unref(currentRoute);
|
||||||
|
return tabStore.getTabList.find((item) => item.path === route.path)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleTabAction(action: TableActionEnum, tab?: RouteLocationNormalized) {
|
||||||
|
const canIUse = canIUseTabs;
|
||||||
|
if (!canIUse) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const currentTab = getCurrentTab();
|
||||||
|
switch (action) {
|
||||||
|
case TableActionEnum.REFRESH:
|
||||||
|
await tabStore.refreshPage(router);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TableActionEnum.CLOSE_ALL:
|
||||||
|
await tabStore.closeAllTab(router);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TableActionEnum.CLOSE_LEFT:
|
||||||
|
await tabStore.closeLeftTabs(currentTab, router);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TableActionEnum.CLOSE_RIGHT:
|
||||||
|
await tabStore.closeRightTabs(currentTab, router);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TableActionEnum.CLOSE_OTHER:
|
||||||
|
await tabStore.closeOtherTabs(currentTab, router);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TableActionEnum.CLOSE_CURRENT:
|
||||||
|
case TableActionEnum.CLOSE:
|
||||||
|
await tabStore.closeTab(tab || currentTab, router);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
refreshPage: async () => {
|
refreshPage: () => handleTabAction(TableActionEnum.REFRESH),
|
||||||
if (canIUseFn()) {
|
closeAll: () => handleTabAction(TableActionEnum.CLOSE_ALL),
|
||||||
await tabStore.commitRedoPage();
|
closeLeft: () => handleTabAction(TableActionEnum.CLOSE_LEFT),
|
||||||
}
|
closeRight: () => handleTabAction(TableActionEnum.CLOSE_RIGHT),
|
||||||
|
closeOther: () => handleTabAction(TableActionEnum.CLOSE_OTHER),
|
||||||
|
closeCurrent: () => handleTabAction(TableActionEnum.CLOSE_CURRENT),
|
||||||
|
close: (tab?: RouteLocationNormalized) => {
|
||||||
|
handleTabAction(TableActionEnum.CLOSE, tab);
|
||||||
},
|
},
|
||||||
closeAll: () => canIUseFn() && tabStore.closeAllTabAction(),
|
|
||||||
closeLeft: () => canIUseFn() && tabStore.closeLeftTabAction(tabStore.getCurrentTab),
|
|
||||||
closeRight: () => canIUseFn() && tabStore.closeRightTabAction(tabStore.getCurrentTab),
|
|
||||||
closeOther: () => canIUseFn() && tabStore.closeOtherTabAction(tabStore.getCurrentTab),
|
|
||||||
closeCurrent: () => canIUseFn() && tabStore.closeTabAction(tabStore.getCurrentTab),
|
|
||||||
close: (tab?: RouteLocationNormalized) =>
|
|
||||||
canIUseFn() && tabStore.closeTabAction(tab || tabStore.getCurrentTab),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
:mouseEnterDelay="0.5"
|
:mouseEnterDelay="0.5"
|
||||||
@click="handleToErrorList"
|
@click="handleToErrorList"
|
||||||
>
|
>
|
||||||
<Badge :count="getCount" :offset="[0, 10]" dot :overflowCount="99">
|
<Badge :count="getCount" :offset="[0, 10]" :overflowCount="99">
|
||||||
<Icon icon="ion:bug-outline" />
|
<Icon icon="ion:bug-outline" />
|
||||||
</Badge>
|
</Badge>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -16,7 +16,7 @@
|
|||||||
import Icon from '/@/components/Icon';
|
import Icon from '/@/components/Icon';
|
||||||
|
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
import { errorStore } from '/@/store/modules/error';
|
import { useErrorLogStore } from '/@/store/modules/errorLog';
|
||||||
import { PageEnum } from '/@/enums/pageEnum';
|
import { PageEnum } from '/@/enums/pageEnum';
|
||||||
|
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
@ -28,14 +28,13 @@
|
|||||||
setup() {
|
setup() {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { push } = useRouter();
|
const { push } = useRouter();
|
||||||
|
const errorLogStore = useErrorLogStore();
|
||||||
|
|
||||||
const getCount = computed(() => {
|
const getCount = computed(() => errorLogStore.getErrorLogListCount);
|
||||||
return errorStore.getErrorListCountState;
|
|
||||||
});
|
|
||||||
|
|
||||||
function handleToErrorList() {
|
function handleToErrorList() {
|
||||||
push(PageEnum.ERROR_LOG_PAGE).then(() => {
|
push(PageEnum.ERROR_LOG_PAGE).then(() => {
|
||||||
errorStore.commitErrorListCountState(0);
|
errorLogStore.setErrorLogListCount(0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
import { BasicModal, useModalInner } from '/@/components/Modal/index';
|
import { BasicModal, useModalInner } from '/@/components/Modal/index';
|
||||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||||
|
|
||||||
import { userStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
import { lockStore } from '/@/store/modules/lock';
|
import { useLockStore } from '/@/store/modules/lock';
|
||||||
import headerImg from '/@/assets/images/header.jpg';
|
import headerImg from '/@/assets/images/header.jpg';
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'LockModal',
|
name: 'LockModal',
|
||||||
@ -41,10 +41,10 @@
|
|||||||
setup() {
|
setup() {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { prefixCls } = useDesign('header-lock-modal');
|
const { prefixCls } = useDesign('header-lock-modal');
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const lockStore = useLockStore();
|
||||||
|
|
||||||
const getRealName = computed(() => {
|
const getRealName = computed(() => userStore.getUserInfo?.realName);
|
||||||
return userStore.getUserInfoState?.realName;
|
|
||||||
});
|
|
||||||
const [register, { closeModal }] = useModalInner();
|
const [register, { closeModal }] = useModalInner();
|
||||||
|
|
||||||
const [registerForm, { validateFields, resetFields }] = useForm({
|
const [registerForm, { validateFields, resetFields }] = useForm({
|
||||||
@ -64,7 +64,7 @@
|
|||||||
const password: string | undefined = values.password;
|
const password: string | undefined = values.password;
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
lockStore.commitLockInfoState({
|
lockStore.setLockInfo({
|
||||||
isLock: true,
|
isLock: true,
|
||||||
pwd: password,
|
pwd: password,
|
||||||
});
|
});
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
import { DOC_URL } from '/@/settings/siteSetting';
|
import { DOC_URL } from '/@/settings/siteSetting';
|
||||||
|
|
||||||
import { userStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
|
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
@ -71,9 +71,10 @@
|
|||||||
const { prefixCls } = useDesign('header-user-dropdown');
|
const { prefixCls } = useDesign('header-user-dropdown');
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { getShowDoc } = useHeaderSetting();
|
const { getShowDoc } = useHeaderSetting();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
const getUserInfo = computed(() => {
|
const getUserInfo = computed(() => {
|
||||||
const { realName = '', desc } = userStore.getUserInfoState || {};
|
const { realName = '', desc } = userStore.getUserInfo || {};
|
||||||
return { realName, desc };
|
return { realName, desc };
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -42,13 +42,9 @@
|
|||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const { prefixCls } = useDesign('default-layout');
|
const { prefixCls } = useDesign('default-layout');
|
||||||
|
|
||||||
const { getIsMobile } = useAppInject();
|
const { getIsMobile } = useAppInject();
|
||||||
|
|
||||||
const { getShowFullHeaderRef } = useHeaderSetting();
|
const { getShowFullHeaderRef } = useHeaderSetting();
|
||||||
|
|
||||||
const { getShowSidebar, getIsMixSidebar } = useMenuSetting();
|
const { getShowSidebar, getIsMixSidebar } = useMenuSetting();
|
||||||
|
|
||||||
const layoutClass = computed(() => ({ 'ant-layout-has-sider': unref(getIsMixSidebar) }));
|
const layoutClass = computed(() => ({ 'ant-layout-has-sider': unref(getIsMixSidebar) }));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -9,7 +9,7 @@ import { useThrottle } from '/@/hooks/core/useThrottle';
|
|||||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||||
|
|
||||||
import { getChildrenMenus, getCurrentParentPath, getMenus, getShallowMenus } from '/@/router/menus';
|
import { getChildrenMenus, getCurrentParentPath, getMenus, getShallowMenus } from '/@/router/menus';
|
||||||
import { permissionStore } from '/@/store/modules/permission';
|
import { usePermissionStore } from '/@/store/modules/permission';
|
||||||
import { useAppInject } from '/@/hooks/web/useAppInject';
|
import { useAppInject } from '/@/hooks/web/useAppInject';
|
||||||
|
|
||||||
export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
|
export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
|
||||||
@ -17,6 +17,7 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
|
|||||||
const menusRef = ref<Menu[]>([]);
|
const menusRef = ref<Menu[]>([]);
|
||||||
const { currentRoute } = useRouter();
|
const { currentRoute } = useRouter();
|
||||||
const { getIsMobile } = useAppInject();
|
const { getIsMobile } = useAppInject();
|
||||||
|
const permissionStore = usePermissionStore();
|
||||||
const { setMenuSetting, getIsHorizontal, getSplit } = useMenuSetting();
|
const { setMenuSetting, getIsHorizontal, getSplit } = useMenuSetting();
|
||||||
|
|
||||||
const [throttleHandleSplitLeftMenu] = useThrottle(handleSplitLeftMenu, 50);
|
const [throttleHandleSplitLeftMenu] = useThrottle(handleSplitLeftMenu, 50);
|
||||||
@ -55,7 +56,7 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) {
|
|||||||
|
|
||||||
// Menu changes
|
// Menu changes
|
||||||
watch(
|
watch(
|
||||||
[() => permissionStore.getLastBuildMenuTimeState, () => permissionStore.getBackMenuListState],
|
[() => permissionStore.getLastBuildMenuTime, () => permissionStore.getBackMenuList],
|
||||||
() => {
|
() => {
|
||||||
genMenus();
|
genMenus();
|
||||||
},
|
},
|
||||||
|
@ -21,32 +21,36 @@
|
|||||||
|
|
||||||
import { CopyOutlined, RedoOutlined } from '@ant-design/icons-vue';
|
import { CopyOutlined, RedoOutlined } from '@ant-design/icons-vue';
|
||||||
|
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
import { permissionStore } from '/@/store/modules/permission';
|
import { usePermissionStore } from '/@/store/modules/permission';
|
||||||
import { tabStore } from '/@/store/modules/tab';
|
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
|
||||||
import { userStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
|
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
|
import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
|
||||||
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
|
||||||
|
|
||||||
import { updateColorWeak } from '/@/logics/theme/updateColorWeak';
|
import { updateColorWeak } from '/@/logics/theme/updateColorWeak';
|
||||||
import { updateGrayMode } from '/@/logics/theme/updateGrayMode';
|
import { updateGrayMode } from '/@/logics/theme/updateGrayMode';
|
||||||
|
|
||||||
import defaultSetting from '/@/settings/projectSetting';
|
import defaultSetting from '/@/settings/projectSetting';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SettingFooter',
|
name: 'SettingFooter',
|
||||||
components: { CopyOutlined, RedoOutlined },
|
components: { CopyOutlined, RedoOutlined },
|
||||||
setup() {
|
setup() {
|
||||||
const { getRootSetting } = useRootSetting();
|
const permissionStore = usePermissionStore();
|
||||||
const { prefixCls } = useDesign('setting-footer');
|
const { prefixCls } = useDesign('setting-footer');
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { createSuccessModal, createMessage } = useMessage();
|
const { createSuccessModal, createMessage } = useMessage();
|
||||||
|
const tabStore = useMultipleTabStore();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
function handleCopy() {
|
function handleCopy() {
|
||||||
const { isSuccessRef } = useCopyToClipboard(JSON.stringify(unref(getRootSetting), null, 2));
|
const { isSuccessRef } = useCopyToClipboard(
|
||||||
|
JSON.stringify(unref(appStore.getProjectConfig), null, 2)
|
||||||
|
);
|
||||||
unref(isSuccessRef) &&
|
unref(isSuccessRef) &&
|
||||||
createSuccessModal({
|
createSuccessModal({
|
||||||
title: t('layout.setting.operatingTitle'),
|
title: t('layout.setting.operatingTitle'),
|
||||||
@ -55,7 +59,7 @@
|
|||||||
}
|
}
|
||||||
function handleResetSetting() {
|
function handleResetSetting() {
|
||||||
try {
|
try {
|
||||||
appStore.commitProjectConfigState(defaultSetting);
|
appStore.setProjectConfig(defaultSetting);
|
||||||
const { colorWeak, grayMode } = defaultSetting;
|
const { colorWeak, grayMode } = defaultSetting;
|
||||||
// updateTheme(themeColor);
|
// updateTheme(themeColor);
|
||||||
updateColorWeak(colorWeak);
|
updateColorWeak(colorWeak);
|
||||||
@ -68,10 +72,10 @@
|
|||||||
|
|
||||||
function handleClearAndRedo() {
|
function handleClearAndRedo() {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
appStore.resumeAllState();
|
appStore.resetAllState();
|
||||||
permissionStore.commitResetState();
|
permissionStore.resetState();
|
||||||
tabStore.commitResetState();
|
tabStore.resetState();
|
||||||
userStore.commitResetState();
|
userStore.resetState();
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
|
@ -3,15 +3,16 @@ import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updat
|
|||||||
import { updateColorWeak } from '/@/logics/theme/updateColorWeak';
|
import { updateColorWeak } from '/@/logics/theme/updateColorWeak';
|
||||||
import { updateGrayMode } from '/@/logics/theme/updateGrayMode';
|
import { updateGrayMode } from '/@/logics/theme/updateGrayMode';
|
||||||
|
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
import { ProjectConfig } from '/#/config';
|
import { ProjectConfig } from '/#/config';
|
||||||
import { changeTheme } from '/@/logics/theme';
|
import { changeTheme } from '/@/logics/theme';
|
||||||
import { updateDarkTheme } from '/@/logics/theme/dark';
|
import { updateDarkTheme } from '/@/logics/theme/dark';
|
||||||
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||||
|
|
||||||
export function baseHandler(event: HandlerEnum, value: any) {
|
export function baseHandler(event: HandlerEnum, value: any) {
|
||||||
|
const appStore = useAppStore();
|
||||||
const config = handler(event, value);
|
const config = handler(event, value);
|
||||||
appStore.commitProjectConfigState(config);
|
appStore.setProjectConfig(config);
|
||||||
if (event === HandlerEnum.CHANGE_THEME) {
|
if (event === HandlerEnum.CHANGE_THEME) {
|
||||||
updateHeaderBgColor();
|
updateHeaderBgColor();
|
||||||
updateSidebarBgColor();
|
updateSidebarBgColor();
|
||||||
@ -19,6 +20,8 @@ export function baseHandler(event: HandlerEnum, value: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConfig> {
|
export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConfig> {
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
const { getThemeColor, getDarkMode } = useRootSetting();
|
const { getThemeColor, getDarkMode } = useRootSetting();
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case HandlerEnum.CHANGE_LAYOUT:
|
case HandlerEnum.CHANGE_LAYOUT:
|
||||||
@ -50,7 +53,7 @@ export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConf
|
|||||||
}
|
}
|
||||||
updateDarkTheme(value);
|
updateDarkTheme(value);
|
||||||
|
|
||||||
return { darkMode: value };
|
return {};
|
||||||
|
|
||||||
case HandlerEnum.MENU_HAS_DRAG:
|
case HandlerEnum.MENU_HAS_DRAG:
|
||||||
return { menuSetting: { canDrag: value } };
|
return { menuSetting: { canDrag: value } };
|
||||||
@ -97,7 +100,7 @@ export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConf
|
|||||||
|
|
||||||
// ============transition==================
|
// ============transition==================
|
||||||
case HandlerEnum.OPEN_PAGE_LOADING:
|
case HandlerEnum.OPEN_PAGE_LOADING:
|
||||||
appStore.commitPageLoadingState(false);
|
appStore.setPageLoading(false);
|
||||||
return { transitionSetting: { openPageLoading: value } };
|
return { transitionSetting: { openPageLoading: value } };
|
||||||
|
|
||||||
case HandlerEnum.ROUTER_TRANSITION:
|
case HandlerEnum.ROUTER_TRANSITION:
|
||||||
|
@ -5,38 +5,33 @@
|
|||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, unref, computed } from 'vue';
|
import { defineComponent, unref, computed } from 'vue';
|
||||||
|
import { Icon } from '/@/components/Icon';
|
||||||
|
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
|
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
|
||||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||||
|
|
||||||
import Icon from '/@/components/Icon';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'FoldButton',
|
name: 'FoldButton',
|
||||||
components: { Icon },
|
components: { Icon },
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const { prefixCls } = useDesign('multiple-tabs-content');
|
const { prefixCls } = useDesign('multiple-tabs-content');
|
||||||
const { getShowMenu, setMenuSetting } = useMenuSetting();
|
const { getShowMenu, setMenuSetting } = useMenuSetting();
|
||||||
const { getShowHeader, setHeaderSetting } = useHeaderSetting();
|
const { getShowHeader, setHeaderSetting } = useHeaderSetting();
|
||||||
|
|
||||||
const getIsUnFold = computed(() => {
|
const getIsUnFold = computed(() => !unref(getShowMenu) && !unref(getShowHeader));
|
||||||
return !unref(getShowMenu) && !unref(getShowHeader);
|
|
||||||
});
|
|
||||||
|
|
||||||
const getIcon = computed(() => {
|
const getIcon = computed(() =>
|
||||||
return unref(getIsUnFold) ? 'codicon:screen-normal' : 'codicon:screen-full';
|
unref(getIsUnFold) ? 'codicon:screen-normal' : 'codicon:screen-full'
|
||||||
});
|
);
|
||||||
|
|
||||||
function handleFold() {
|
function handleFold() {
|
||||||
const isScale = !unref(getShowMenu) && !unref(getShowHeader);
|
const isUnFold = unref(getIsUnFold);
|
||||||
setMenuSetting({
|
setMenuSetting({
|
||||||
show: isScale,
|
show: isUnFold,
|
||||||
hidden: !isScale,
|
hidden: !isUnFold,
|
||||||
});
|
|
||||||
setHeaderSetting({
|
|
||||||
show: isScale,
|
|
||||||
});
|
});
|
||||||
|
setHeaderSetting({ show: isUnFold });
|
||||||
}
|
}
|
||||||
|
|
||||||
return { prefixCls, getIcon, handleFold };
|
return { prefixCls, getIcon, handleFold };
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
<template>
|
|
||||||
<TabContent :type="TabContentEnum.EXTRA_TYPE" :tabItem="$route" />
|
|
||||||
</template>
|
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent } from 'vue';
|
|
||||||
|
|
||||||
import { TabContentEnum } from '../types';
|
|
||||||
|
|
||||||
import TabContent from './TabContent.vue';
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'QuickButton',
|
|
||||||
components: {
|
|
||||||
TabContent,
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
return {
|
|
||||||
TabContentEnum,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
@ -1,9 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<Dropdown :dropMenuList="getDropMenuList" :trigger="getTrigger" @menuEvent="handleMenuEvent">
|
<Dropdown :dropMenuList="getDropMenuList" :trigger="getTrigger" @menuEvent="handleMenuEvent">
|
||||||
<div :class="`${prefixCls}__info`" @contextmenu="handleContext" v-if="isTabs">
|
<div :class="`${prefixCls}__info`" @contextmenu="handleContext" v-if="getIsTabs">
|
||||||
<span class="ml-1">{{ getTitle }}</span>
|
<span class="ml-1">{{ getTitle }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span :class="`${prefixCls}__extra-quick`" v-else @click="handleContext">
|
<span :class="`${prefixCls}__extra-quick`" v-else @click="handleContext">
|
||||||
<Icon icon="ion:chevron-down" />
|
<Icon icon="ion:chevron-down" />
|
||||||
</span>
|
</span>
|
||||||
@ -11,18 +10,18 @@
|
|||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { PropType } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
|
import type { RouteLocationNormalized } from 'vue-router';
|
||||||
|
|
||||||
import { defineComponent, computed } from 'vue';
|
import { defineComponent, computed, unref } from 'vue';
|
||||||
import { Dropdown } from '/@/components/Dropdown/index';
|
import { Dropdown } from '/@/components/Dropdown/index';
|
||||||
import Icon from '/@/components/Icon';
|
import { Icon } from '/@/components/Icon';
|
||||||
|
|
||||||
import { TabContentProps, TabContentEnum } from '../types';
|
import { TabContentProps } from '../types';
|
||||||
|
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { useTabDropdown } from '../useTabDropdown';
|
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
|
import { useTabDropdown } from '../useTabDropdown';
|
||||||
|
|
||||||
import { RouteLocationNormalized } from 'vue-router';
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'TabContent',
|
name: 'TabContent',
|
||||||
components: { Dropdown, Icon },
|
components: { Dropdown, Icon },
|
||||||
@ -31,11 +30,7 @@
|
|||||||
type: Object as PropType<RouteLocationNormalized>,
|
type: Object as PropType<RouteLocationNormalized>,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
isExtra: Boolean,
|
||||||
type: {
|
|
||||||
type: Number as PropType<TabContentEnum>,
|
|
||||||
default: TabContentEnum.TAB_TYPE,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const { prefixCls } = useDesign('multiple-tabs-content');
|
const { prefixCls } = useDesign('multiple-tabs-content');
|
||||||
@ -43,27 +38,29 @@
|
|||||||
|
|
||||||
const getTitle = computed(() => {
|
const getTitle = computed(() => {
|
||||||
const { tabItem: { meta } = {} } = props;
|
const { tabItem: { meta } = {} } = props;
|
||||||
return meta && t(meta.title);
|
return meta && t(meta.title as string);
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const getIsTabs = computed(() => !props.isExtra);
|
||||||
getDropMenuList,
|
|
||||||
handleMenuEvent,
|
|
||||||
handleContextMenu,
|
|
||||||
getTrigger,
|
|
||||||
isTabs,
|
|
||||||
} = useTabDropdown(props as TabContentProps);
|
|
||||||
|
|
||||||
function handleContext(e: ChangeEvent) {
|
const getTrigger = computed(() => (unref(getIsTabs) ? ['contextmenu'] : ['click']));
|
||||||
|
|
||||||
|
const { getDropMenuList, handleMenuEvent, handleContextMenu } = useTabDropdown(
|
||||||
|
props as TabContentProps,
|
||||||
|
getIsTabs
|
||||||
|
);
|
||||||
|
|
||||||
|
function handleContext(e) {
|
||||||
props.tabItem && handleContextMenu(props.tabItem)(e);
|
props.tabItem && handleContextMenu(props.tabItem)(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
prefixCls,
|
prefixCls,
|
||||||
getDropMenuList,
|
getDropMenuList,
|
||||||
handleMenuEvent,
|
handleMenuEvent,
|
||||||
handleContext,
|
handleContext,
|
||||||
getTrigger,
|
getTrigger,
|
||||||
isTabs,
|
getIsTabs,
|
||||||
getTitle,
|
getTitle,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -1,26 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<Tooltip :title="t('common.redo')" placement="bottom" :mouseEnterDelay="0.5">
|
<span :class="`${prefixCls}__extra-redo`" @click="handleRedo">
|
||||||
<span :class="`${prefixCls}__extra-redo`" @click="handleRedo">
|
<RedoOutlined :spin="loading" />
|
||||||
<RedoOutlined :spin="loading" />
|
</span>
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref } from 'vue';
|
import { defineComponent, ref } from 'vue';
|
||||||
import { RedoOutlined } from '@ant-design/icons-vue';
|
import { RedoOutlined } from '@ant-design/icons-vue';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { Tooltip } from 'ant-design-vue';
|
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
|
||||||
import { useTabs } from '/@/hooks/web/useTabs';
|
import { useTabs } from '/@/hooks/web/useTabs';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'TabRedo',
|
name: 'TabRedo',
|
||||||
components: { RedoOutlined, Tooltip },
|
components: { RedoOutlined },
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
const { prefixCls } = useDesign('multiple-tabs-content');
|
const { prefixCls } = useDesign('multiple-tabs-content');
|
||||||
const { t } = useI18n();
|
|
||||||
const { refreshPage } = useTabs();
|
const { refreshPage } = useTabs();
|
||||||
|
|
||||||
async function handleRedo() {
|
async function handleRedo() {
|
||||||
@ -29,9 +25,9 @@
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
// Animation execution time
|
// Animation execution time
|
||||||
}, 1000);
|
}, 1200);
|
||||||
}
|
}
|
||||||
return { prefixCls, t, handleRedo, loading };
|
return { prefixCls, handleRedo, loading };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -8,13 +8,20 @@ html[data-theme='dark'] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html[data-theme='light'] {
|
||||||
|
.@{prefix-cls} {
|
||||||
|
.ant-tabs-tab:not(.ant-tabs-tab-active) {
|
||||||
|
border: 1px solid #d9d9d9 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.@{prefix-cls} {
|
.@{prefix-cls} {
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
height: @multiple-height + 2;
|
height: @multiple-height + 2;
|
||||||
line-height: @multiple-height + 2;
|
line-height: @multiple-height + 2;
|
||||||
background: @component-background;
|
background: @component-background;
|
||||||
border-bottom: 1px solid @border-color-base;
|
border-bottom: 1px solid @border-color-base;
|
||||||
box-shadow: 0 1px 2px 0 rgba(29, 35, 41, 0.05);
|
|
||||||
|
|
||||||
.ant-tabs-small {
|
.ant-tabs-small {
|
||||||
height: @multiple-height;
|
height: @multiple-height;
|
||||||
|
@ -20,26 +20,26 @@
|
|||||||
|
|
||||||
<template #tabBarExtraContent v-if="getShowRedo || getShowQuick">
|
<template #tabBarExtraContent v-if="getShowRedo || getShowQuick">
|
||||||
<TabRedo v-if="getShowRedo" />
|
<TabRedo v-if="getShowRedo" />
|
||||||
<QuickButton v-if="getShowQuick" />
|
<TabContent isExtra :tabItem="$route" v-if="getShowQuick" />
|
||||||
<FoldButton v-if="getShowFold" />
|
<FoldButton v-if="getShowFold" />
|
||||||
</template>
|
</template>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { RouteLocationNormalized } from 'vue-router';
|
||||||
|
|
||||||
import { defineComponent, computed, unref, ref } from 'vue';
|
import { defineComponent, computed, unref, ref } from 'vue';
|
||||||
|
|
||||||
import { Tabs } from 'ant-design-vue';
|
import { Tabs } from 'ant-design-vue';
|
||||||
import TabContent from './components/TabContent.vue';
|
import TabContent from './components/TabContent.vue';
|
||||||
import QuickButton from './components/QuickButton.vue';
|
|
||||||
import FoldButton from './components/FoldButton.vue';
|
import FoldButton from './components/FoldButton.vue';
|
||||||
import TabRedo from './components/TabRedo.vue';
|
import TabRedo from './components/TabRedo.vue';
|
||||||
import type { RouteLocationNormalized } from 'vue-router';
|
|
||||||
|
|
||||||
import { useGo } from '/@/hooks/web/usePage';
|
import { useGo } from '/@/hooks/web/usePage';
|
||||||
|
|
||||||
import { tabStore } from '/@/store/modules/tab';
|
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
|
||||||
import { userStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
|
|
||||||
import { initAffixTabs, useTabsDrag } from './useMultipleTabs';
|
import { initAffixTabs, useTabsDrag } from './useMultipleTabs';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
@ -48,13 +48,12 @@
|
|||||||
import { REDIRECT_NAME } from '/@/router/constant';
|
import { REDIRECT_NAME } from '/@/router/constant';
|
||||||
import { listenerRouteChange } from '/@/logics/mitt/routeChange';
|
import { listenerRouteChange } from '/@/logics/mitt/routeChange';
|
||||||
|
|
||||||
import router from '/@/router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'MultipleTabs',
|
name: 'MultipleTabs',
|
||||||
components: {
|
components: {
|
||||||
QuickButton,
|
TabRedo,
|
||||||
TabRedo: TabRedo,
|
|
||||||
FoldButton,
|
FoldButton,
|
||||||
Tabs,
|
Tabs,
|
||||||
TabPane: Tabs.TabPane,
|
TabPane: Tabs.TabPane,
|
||||||
@ -65,12 +64,16 @@
|
|||||||
const activeKeyRef = ref('');
|
const activeKeyRef = ref('');
|
||||||
|
|
||||||
useTabsDrag(affixTextList);
|
useTabsDrag(affixTextList);
|
||||||
|
const tabStore = useMultipleTabStore();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
const { prefixCls } = useDesign('multiple-tabs');
|
const { prefixCls } = useDesign('multiple-tabs');
|
||||||
const go = useGo();
|
const go = useGo();
|
||||||
const { getShowQuick, getShowRedo, getShowFold } = useMultipleTabSetting();
|
const { getShowQuick, getShowRedo, getShowFold } = useMultipleTabSetting();
|
||||||
|
|
||||||
const getTabsState = computed(() => {
|
const getTabsState = computed(() => {
|
||||||
return tabStore.getTabsState.filter((item) => !item.meta?.hideTab);
|
return tabStore.getTabList.filter((item) => !item.meta?.hideTab);
|
||||||
});
|
});
|
||||||
|
|
||||||
const unClose = computed(() => unref(getTabsState).length === 1);
|
const unClose = computed(() => unref(getTabsState).length === 1);
|
||||||
@ -86,10 +89,11 @@
|
|||||||
|
|
||||||
listenerRouteChange((route) => {
|
listenerRouteChange((route) => {
|
||||||
const { name } = route;
|
const { name } = route;
|
||||||
if (name === REDIRECT_NAME || !route || !userStore.getTokenState) return;
|
if (name === REDIRECT_NAME || !route || !userStore.getToken) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const { path, fullPath, meta = {} } = route;
|
const { path, fullPath, meta = {} } = route;
|
||||||
|
|
||||||
const { currentActiveMenu, hideTab } = meta;
|
const { currentActiveMenu, hideTab } = meta;
|
||||||
const isHide = !hideTab ? null : currentActiveMenu;
|
const isHide = !hideTab ? null : currentActiveMenu;
|
||||||
const p = isHide || fullPath || path;
|
const p = isHide || fullPath || path;
|
||||||
@ -101,10 +105,11 @@
|
|||||||
const findParentRoute = router
|
const findParentRoute = router
|
||||||
.getRoutes()
|
.getRoutes()
|
||||||
.find((item) => item.path === currentActiveMenu);
|
.find((item) => item.path === currentActiveMenu);
|
||||||
|
|
||||||
findParentRoute &&
|
findParentRoute &&
|
||||||
tabStore.addTabAction((findParentRoute as unknown) as RouteLocationNormalized);
|
tabStore.addTab((findParentRoute as unknown) as RouteLocationNormalized);
|
||||||
} else {
|
} else {
|
||||||
tabStore.addTabAction(unref(route));
|
tabStore.addTab(unref(route));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -116,9 +121,11 @@
|
|||||||
// Close the current tab
|
// Close the current tab
|
||||||
function handleEdit(targetKey: string) {
|
function handleEdit(targetKey: string) {
|
||||||
// Added operation to hide, currently only use delete operation
|
// Added operation to hide, currently only use delete operation
|
||||||
if (unref(unClose)) return;
|
if (unref(unClose)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tabStore.closeTabByKeyAction(targetKey);
|
tabStore.closeTabByKey(targetKey, router);
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
prefixCls,
|
prefixCls,
|
||||||
|
@ -14,22 +14,12 @@ export interface TabContentProps {
|
|||||||
trigger?: ('click' | 'hover' | 'contextmenu')[];
|
trigger?: ('click' | 'hover' | 'contextmenu')[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @description: 右键:下拉菜单文字
|
|
||||||
*/
|
|
||||||
export enum MenuEventEnum {
|
export enum MenuEventEnum {
|
||||||
// 刷新
|
|
||||||
REFRESH_PAGE,
|
REFRESH_PAGE,
|
||||||
// 关闭当前
|
|
||||||
CLOSE_CURRENT,
|
CLOSE_CURRENT,
|
||||||
// 关闭左侧
|
|
||||||
CLOSE_LEFT,
|
CLOSE_LEFT,
|
||||||
// 关闭右侧
|
|
||||||
CLOSE_RIGHT,
|
CLOSE_RIGHT,
|
||||||
// 关闭其他
|
|
||||||
CLOSE_OTHER,
|
CLOSE_OTHER,
|
||||||
// 关闭所有
|
|
||||||
CLOSE_ALL,
|
CLOSE_ALL,
|
||||||
// 放大
|
|
||||||
SCALE,
|
SCALE,
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
import { toRaw, ref, nextTick } from 'vue';
|
import { toRaw, ref, nextTick } from 'vue';
|
||||||
import { RouteLocationNormalized } from 'vue-router';
|
import type { RouteLocationNormalized } from 'vue-router';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { useSortable } from '/@/hooks/web/useSortable';
|
import { useSortable } from '/@/hooks/web/useSortable';
|
||||||
import router from '/@/router';
|
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
|
||||||
import { tabStore } from '/@/store/modules/tab';
|
|
||||||
import { isNullAndUnDef } from '/@/utils/is';
|
import { isNullAndUnDef } from '/@/utils/is';
|
||||||
import projectSetting from '/@/settings/projectSetting';
|
import projectSetting from '/@/settings/projectSetting';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
export function initAffixTabs(): string[] {
|
export function initAffixTabs(): string[] {
|
||||||
const affixList = ref<RouteLocationNormalized[]>([]);
|
const affixList = ref<RouteLocationNormalized[]>([]);
|
||||||
|
|
||||||
|
const tabStore = useMultipleTabStore();
|
||||||
|
const router = useRouter();
|
||||||
/**
|
/**
|
||||||
* @description: Filter all fixed routes
|
* @description: Filter all fixed routes
|
||||||
*/
|
*/
|
||||||
@ -30,7 +33,7 @@ export function initAffixTabs(): string[] {
|
|||||||
const affixTabs = filterAffixTabs((router.getRoutes() as unknown) as RouteLocationNormalized[]);
|
const affixTabs = filterAffixTabs((router.getRoutes() as unknown) as RouteLocationNormalized[]);
|
||||||
affixList.value = affixTabs;
|
affixList.value = affixTabs;
|
||||||
for (const tab of affixTabs) {
|
for (const tab of affixTabs) {
|
||||||
tabStore.addTabAction(({
|
tabStore.addTab(({
|
||||||
meta: tab.meta,
|
meta: tab.meta,
|
||||||
name: tab.name,
|
name: tab.name,
|
||||||
path: tab.path,
|
path: tab.path,
|
||||||
@ -39,6 +42,7 @@ export function initAffixTabs(): string[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let isAddAffix = false;
|
let isAddAffix = false;
|
||||||
|
|
||||||
if (!isAddAffix) {
|
if (!isAddAffix) {
|
||||||
addAffixTabs();
|
addAffixTabs();
|
||||||
isAddAffix = true;
|
isAddAffix = true;
|
||||||
@ -47,8 +51,8 @@ export function initAffixTabs(): string[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useTabsDrag(affixTextList: string[]) {
|
export function useTabsDrag(affixTextList: string[]) {
|
||||||
|
const tabStore = useMultipleTabStore();
|
||||||
const { multiTabsSetting } = projectSetting;
|
const { multiTabsSetting } = projectSetting;
|
||||||
|
|
||||||
const { prefixCls } = useDesign('multiple-tabs');
|
const { prefixCls } = useDesign('multiple-tabs');
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (!multiTabsSetting.canDrag) return;
|
if (!multiTabsSetting.canDrag) return;
|
||||||
@ -66,7 +70,7 @@ export function useTabsDrag(affixTextList: string[]) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tabStore.commitSortTabs({ oldIndex, newIndex });
|
tabStore.sortTabs(oldIndex, newIndex);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
initSortable();
|
initSortable();
|
||||||
|
@ -1,29 +1,28 @@
|
|||||||
import type { TabContentProps } from './types';
|
import type { TabContentProps } from './types';
|
||||||
import type { DropMenu } from '/@/components/Dropdown';
|
import type { DropMenu } from '/@/components/Dropdown';
|
||||||
|
import type { ComputedRef } from 'vue';
|
||||||
|
|
||||||
import { computed, unref, reactive } from 'vue';
|
import { computed, unref, reactive } from 'vue';
|
||||||
import { TabContentEnum, MenuEventEnum } from './types';
|
import { MenuEventEnum } from './types';
|
||||||
import { tabStore } from '/@/store/modules/tab';
|
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
|
||||||
import router from '/@/router';
|
import { RouteLocationNormalized, useRouter } from 'vue-router';
|
||||||
import { RouteLocationNormalized } from 'vue-router';
|
|
||||||
import { useTabs } from '/@/hooks/web/useTabs';
|
import { useTabs } from '/@/hooks/web/useTabs';
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
|
|
||||||
const { t } = useI18n();
|
export function useTabDropdown(tabContentProps: TabContentProps, getIsTabs: ComputedRef<boolean>) {
|
||||||
|
|
||||||
export function useTabDropdown(tabContentProps: TabContentProps) {
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
current: null as Nullable<RouteLocationNormalized>,
|
current: null as Nullable<RouteLocationNormalized>,
|
||||||
currentIndex: 0,
|
currentIndex: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { currentRoute } = router;
|
const { t } = useI18n();
|
||||||
|
const tabStore = useMultipleTabStore();
|
||||||
|
const { currentRoute } = useRouter();
|
||||||
|
const { refreshPage, closeAll, close, closeLeft, closeOther, closeRight } = useTabs();
|
||||||
|
|
||||||
const isTabs = computed(() => tabContentProps.type === TabContentEnum.TAB_TYPE);
|
const getTargetTab = computed(
|
||||||
|
|
||||||
const getCurrentTab = computed(
|
|
||||||
(): RouteLocationNormalized => {
|
(): RouteLocationNormalized => {
|
||||||
return unref(isTabs) ? tabContentProps.tabItem : unref(currentRoute);
|
return unref(getIsTabs) ? tabContentProps.tabItem : unref(currentRoute);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -31,8 +30,10 @@ export function useTabDropdown(tabContentProps: TabContentProps) {
|
|||||||
* @description: drop-down list
|
* @description: drop-down list
|
||||||
*/
|
*/
|
||||||
const getDropMenuList = computed(() => {
|
const getDropMenuList = computed(() => {
|
||||||
if (!unref(getCurrentTab)) return;
|
if (!unref(getTargetTab)) {
|
||||||
const { meta } = unref(getCurrentTab);
|
return;
|
||||||
|
}
|
||||||
|
const { meta } = unref(getTargetTab);
|
||||||
const { path } = unref(currentRoute);
|
const { path } = unref(currentRoute);
|
||||||
|
|
||||||
// Refresh button
|
// Refresh button
|
||||||
@ -42,11 +43,11 @@ export function useTabDropdown(tabContentProps: TabContentProps) {
|
|||||||
// Close left
|
// Close left
|
||||||
const closeLeftDisabled = index === 0;
|
const closeLeftDisabled = index === 0;
|
||||||
|
|
||||||
const disabled = tabStore.getTabsState.length === 1;
|
const disabled = tabStore.getTabList.length === 1;
|
||||||
|
|
||||||
// Close right
|
// Close right
|
||||||
const closeRightDisabled =
|
const closeRightDisabled =
|
||||||
index === tabStore.getTabsState.length - 1 && tabStore.getLastDragEndIndexState >= 0;
|
index === tabStore.getTabList.length - 1 && tabStore.getLastDragEndIndex >= 0;
|
||||||
const dropMenuList: DropMenu[] = [
|
const dropMenuList: DropMenu[] = [
|
||||||
{
|
{
|
||||||
icon: 'ion:reload-sharp',
|
icon: 'ion:reload-sharp',
|
||||||
@ -58,7 +59,7 @@ export function useTabDropdown(tabContentProps: TabContentProps) {
|
|||||||
icon: 'clarity:close-line',
|
icon: 'clarity:close-line',
|
||||||
event: MenuEventEnum.CLOSE_CURRENT,
|
event: MenuEventEnum.CLOSE_CURRENT,
|
||||||
text: t('layout.multipleTab.close'),
|
text: t('layout.multipleTab.close'),
|
||||||
disabled: meta?.affix || disabled,
|
disabled: !!meta?.affix || disabled,
|
||||||
divider: true,
|
divider: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -92,15 +93,13 @@ export function useTabDropdown(tabContentProps: TabContentProps) {
|
|||||||
return dropMenuList;
|
return dropMenuList;
|
||||||
});
|
});
|
||||||
|
|
||||||
const getTrigger = computed(() => {
|
|
||||||
return unref(isTabs) ? ['contextmenu'] : ['click'];
|
|
||||||
});
|
|
||||||
|
|
||||||
function handleContextMenu(tabItem: RouteLocationNormalized) {
|
function handleContextMenu(tabItem: RouteLocationNormalized) {
|
||||||
return (e: Event) => {
|
return (e: Event) => {
|
||||||
if (!tabItem) return;
|
if (!tabItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
e?.preventDefault();
|
e?.preventDefault();
|
||||||
const index = tabStore.getTabsState.findIndex((tab) => tab.path === tabItem.path);
|
const index = tabStore.getTabList.findIndex((tab) => tab.path === tabItem.path);
|
||||||
state.current = tabItem;
|
state.current = tabItem;
|
||||||
state.currentIndex = index;
|
state.currentIndex = index;
|
||||||
};
|
};
|
||||||
@ -108,12 +107,8 @@ export function useTabDropdown(tabContentProps: TabContentProps) {
|
|||||||
|
|
||||||
// Handle right click event
|
// Handle right click event
|
||||||
function handleMenuEvent(menu: DropMenu): void {
|
function handleMenuEvent(menu: DropMenu): void {
|
||||||
const { refreshPage, closeAll, close, closeLeft, closeOther, closeRight } = useTabs();
|
|
||||||
const { event } = menu;
|
const { event } = menu;
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case MenuEventEnum.SCALE:
|
|
||||||
scaleScreen();
|
|
||||||
break;
|
|
||||||
case MenuEventEnum.REFRESH_PAGE:
|
case MenuEventEnum.REFRESH_PAGE:
|
||||||
// refresh page
|
// refresh page
|
||||||
refreshPage();
|
refreshPage();
|
||||||
@ -140,5 +135,5 @@ export function useTabDropdown(tabContentProps: TabContentProps) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { getDropMenuList, handleMenuEvent, handleContextMenu, getTrigger, isTabs };
|
return { getDropMenuList, handleMenuEvent, handleContextMenu };
|
||||||
}
|
}
|
||||||
|
@ -2,18 +2,19 @@ import type { AppRouteRecordRaw } from '/@/router/types';
|
|||||||
|
|
||||||
import { computed, toRaw, unref } from 'vue';
|
import { computed, toRaw, unref } from 'vue';
|
||||||
|
|
||||||
import { tabStore } from '/@/store/modules/tab';
|
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
|
||||||
|
|
||||||
import { uniqBy } from 'lodash-es';
|
import { uniqBy } from 'lodash-es';
|
||||||
|
|
||||||
import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting';
|
import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting';
|
||||||
|
|
||||||
import router from '/@/router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
export function useFrameKeepAlive() {
|
export function useFrameKeepAlive() {
|
||||||
|
const router = useRouter();
|
||||||
const { currentRoute } = router;
|
const { currentRoute } = router;
|
||||||
const { getShowMultipleTab } = useMultipleTabSetting();
|
const { getShowMultipleTab } = useMultipleTabSetting();
|
||||||
|
const tabStore = useMultipleTabStore();
|
||||||
const getFramePages = computed(() => {
|
const getFramePages = computed(() => {
|
||||||
const ret =
|
const ret =
|
||||||
getAllFramePages((toRaw(router.getRoutes()) as unknown) as AppRouteRecordRaw[]) || [];
|
getAllFramePages((toRaw(router.getRoutes()) as unknown) as AppRouteRecordRaw[]) || [];
|
||||||
@ -21,7 +22,7 @@ export function useFrameKeepAlive() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const getOpenTabList = computed((): string[] => {
|
const getOpenTabList = computed((): string[] => {
|
||||||
return tabStore.getTabsState.reduce((prev: string[], next) => {
|
return tabStore.getTabList.reduce((prev: string[], next) => {
|
||||||
if (next.meta && Reflect.has(next.meta, 'frameSrc')) {
|
if (next.meta && Reflect.has(next.meta, 'frameSrc')) {
|
||||||
prev.push(next.name as string);
|
prev.push(next.name as string);
|
||||||
}
|
}
|
||||||
|
@ -35,13 +35,14 @@
|
|||||||
import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting';
|
import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting';
|
||||||
import { getTransitionName } from './transition';
|
import { getTransitionName } from './transition';
|
||||||
|
|
||||||
import { useStore } from 'vuex';
|
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'PageLayout',
|
name: 'PageLayout',
|
||||||
components: { FrameLayout },
|
components: { FrameLayout },
|
||||||
setup() {
|
setup() {
|
||||||
const { getShowMultipleTab } = useMultipleTabSetting();
|
const { getShowMultipleTab } = useMultipleTabSetting();
|
||||||
|
const tabStore = useMultipleTabStore();
|
||||||
|
|
||||||
const { getOpenKeepAlive, getCanEmbedIFramePage } = useRootSetting();
|
const { getOpenKeepAlive, getCanEmbedIFramePage } = useRootSetting();
|
||||||
|
|
||||||
@ -49,15 +50,11 @@
|
|||||||
|
|
||||||
const openCache = computed(() => unref(getOpenKeepAlive) && unref(getShowMultipleTab));
|
const openCache = computed(() => unref(getOpenKeepAlive) && unref(getShowMultipleTab));
|
||||||
|
|
||||||
const { getters } = useStore();
|
|
||||||
|
|
||||||
const getCaches = computed((): string[] => {
|
const getCaches = computed((): string[] => {
|
||||||
if (!unref(getOpenKeepAlive)) {
|
if (!unref(getOpenKeepAlive)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
// TODO The useStore is used here mainly to solve the problem of circular dependency hot update
|
return tabStore.getCachedTabList;
|
||||||
const cacheTabs = getters['app-tab/getCachedTabsState'];
|
|
||||||
return cacheTabs;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -3,14 +3,15 @@ import type { I18n, I18nOptions } from 'vue-i18n';
|
|||||||
|
|
||||||
import { createI18n } from 'vue-i18n';
|
import { createI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import { localeStore } from '/@/store/modules/locale';
|
|
||||||
import { localeSetting } from '/@/settings/localeSetting';
|
import { localeSetting } from '/@/settings/localeSetting';
|
||||||
|
import { useLocaleStoreWithOut } from '/@/store/modules/locale';
|
||||||
|
|
||||||
const { fallback, availableLocales } = localeSetting;
|
const { fallback, availableLocales } = localeSetting;
|
||||||
|
|
||||||
export let i18n: ReturnType<typeof createI18n>;
|
export let i18n: ReturnType<typeof createI18n>;
|
||||||
|
|
||||||
async function createI18nOptions(): Promise<I18nOptions> {
|
async function createI18nOptions(): Promise<I18nOptions> {
|
||||||
|
const localeStore = useLocaleStoreWithOut();
|
||||||
const locale = localeStore.getLocale;
|
const locale = localeStore.getLocale;
|
||||||
const defaultLocal = await import(`./lang/${locale}.ts`);
|
const defaultLocal = await import(`./lang/${locale}.ts`);
|
||||||
const message = defaultLocal.default?.message ?? {};
|
const message = defaultLocal.default?.message ?? {};
|
||||||
|
@ -6,7 +6,7 @@ import type { LocaleType } from '/#/config';
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
import { i18n } from './setupI18n';
|
import { i18n } from './setupI18n';
|
||||||
import { localeStore } from '/@/store/modules/locale';
|
import { useLocaleStoreWithOut } from '/@/store/modules/locale';
|
||||||
import { unref, computed } from 'vue';
|
import { unref, computed } from 'vue';
|
||||||
|
|
||||||
interface LangModule {
|
interface LangModule {
|
||||||
@ -18,6 +18,8 @@ interface LangModule {
|
|||||||
const loadLocalePool: LocaleType[] = [];
|
const loadLocalePool: LocaleType[] = [];
|
||||||
|
|
||||||
function setI18nLanguage(locale: LocaleType) {
|
function setI18nLanguage(locale: LocaleType) {
|
||||||
|
const localeStore = useLocaleStoreWithOut();
|
||||||
|
|
||||||
if (i18n.mode === 'legacy') {
|
if (i18n.mode === 'legacy') {
|
||||||
i18n.global.locale = locale;
|
i18n.global.locale = locale;
|
||||||
} else {
|
} else {
|
||||||
@ -28,6 +30,7 @@ function setI18nLanguage(locale: LocaleType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useLocale() {
|
export function useLocale() {
|
||||||
|
const localeStore = useLocaleStoreWithOut();
|
||||||
const getLocale = computed(() => localeStore.getLocale);
|
const getLocale = computed(() => localeStore.getLocale);
|
||||||
const getShowLocalePicker = computed(() => localeStore.getShowPicker);
|
const getShowLocalePicker = computed(() => localeStore.getShowPicker);
|
||||||
|
|
||||||
@ -40,7 +43,9 @@ export function useLocale() {
|
|||||||
async function changeLocale(locale: LocaleType) {
|
async function changeLocale(locale: LocaleType) {
|
||||||
const globalI18n = i18n.global;
|
const globalI18n = i18n.global;
|
||||||
const currentLocale = unref(globalI18n.locale);
|
const currentLocale = unref(globalI18n.locale);
|
||||||
if (currentLocale === locale) return locale;
|
if (currentLocale === locale) {
|
||||||
|
return locale;
|
||||||
|
}
|
||||||
|
|
||||||
if (loadLocalePool.includes(locale)) {
|
if (loadLocalePool.includes(locale)) {
|
||||||
setI18nLanguage(locale);
|
setI18nLanguage(locale);
|
||||||
|
@ -2,7 +2,10 @@
|
|||||||
* Used to configure the global error handling function, which can monitor vue errors, script errors, static resource errors and Promise errors
|
* Used to configure the global error handling function, which can monitor vue errors, script errors, static resource errors and Promise errors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { errorStore, ErrorInfo } from '/@/store/modules/error';
|
import type { ErrorLogInfo } from '/#/store';
|
||||||
|
|
||||||
|
import { useErrorLogStoreWithOut } from '/@/store/modules/errorLog';
|
||||||
|
|
||||||
import { ErrorTypeEnum } from '/@/enums/exceptionEnum';
|
import { ErrorTypeEnum } from '/@/enums/exceptionEnum';
|
||||||
import { App } from 'vue';
|
import { App } from 'vue';
|
||||||
import projectSetting from '/@/settings/projectSetting';
|
import projectSetting from '/@/settings/projectSetting';
|
||||||
@ -61,8 +64,9 @@ function formatComponentName(vm: any) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function vueErrorHandler(err: Error, vm: any, info: string) {
|
function vueErrorHandler(err: Error, vm: any, info: string) {
|
||||||
|
const errorLogStore = useErrorLogStoreWithOut();
|
||||||
const { name, path } = formatComponentName(vm);
|
const { name, path } = formatComponentName(vm);
|
||||||
errorStore.commitErrorInfoState({
|
errorLogStore.addErrorLogInfo({
|
||||||
type: ErrorTypeEnum.VUE,
|
type: ErrorTypeEnum.VUE,
|
||||||
name,
|
name,
|
||||||
file: path,
|
file: path,
|
||||||
@ -86,7 +90,7 @@ export function scriptErrorHandler(
|
|||||||
if (event === 'Script error.' && !source) {
|
if (event === 'Script error.' && !source) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const errorInfo: Partial<ErrorInfo> = {};
|
const errorInfo: Partial<ErrorLogInfo> = {};
|
||||||
colno = colno || (window.event && (window.event as any).errorCharacter) || 0;
|
colno = colno || (window.event && (window.event as any).errorCharacter) || 0;
|
||||||
errorInfo.message = event as string;
|
errorInfo.message = event as string;
|
||||||
if (error?.stack) {
|
if (error?.stack) {
|
||||||
@ -95,13 +99,14 @@ export function scriptErrorHandler(
|
|||||||
errorInfo.stack = '';
|
errorInfo.stack = '';
|
||||||
}
|
}
|
||||||
const name = source ? source.substr(source.lastIndexOf('/') + 1) : 'script';
|
const name = source ? source.substr(source.lastIndexOf('/') + 1) : 'script';
|
||||||
errorStore.commitErrorInfoState({
|
const errorLogStore = useErrorLogStoreWithOut();
|
||||||
|
errorLogStore.addErrorLogInfo({
|
||||||
type: ErrorTypeEnum.SCRIPT,
|
type: ErrorTypeEnum.SCRIPT,
|
||||||
name: name,
|
name: name,
|
||||||
file: source as string,
|
file: source as string,
|
||||||
detail: 'lineno' + lineno,
|
detail: 'lineno' + lineno,
|
||||||
url: window.location.href,
|
url: window.location.href,
|
||||||
...(errorInfo as Pick<ErrorInfo, 'message' | 'stack'>),
|
...(errorInfo as Pick<ErrorLogInfo, 'message' | 'stack'>),
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -112,8 +117,9 @@ export function scriptErrorHandler(
|
|||||||
function registerPromiseErrorHandler() {
|
function registerPromiseErrorHandler() {
|
||||||
window.addEventListener(
|
window.addEventListener(
|
||||||
'unhandledrejection',
|
'unhandledrejection',
|
||||||
function (event: any) {
|
function (event) {
|
||||||
errorStore.commitErrorInfoState({
|
const errorLogStore = useErrorLogStoreWithOut();
|
||||||
|
errorLogStore.addErrorLogInfo({
|
||||||
type: ErrorTypeEnum.PROMISE,
|
type: ErrorTypeEnum.PROMISE,
|
||||||
name: 'Promise Error!',
|
name: 'Promise Error!',
|
||||||
file: 'none',
|
file: 'none',
|
||||||
@ -136,10 +142,10 @@ function registerResourceErrorHandler() {
|
|||||||
'error',
|
'error',
|
||||||
function (e: Event) {
|
function (e: Event) {
|
||||||
const target = e.target ? e.target : (e.srcElement as any);
|
const target = e.target ? e.target : (e.srcElement as any);
|
||||||
|
const errorLogStore = useErrorLogStoreWithOut();
|
||||||
errorStore.commitErrorInfoState({
|
errorLogStore.addErrorLogInfo({
|
||||||
type: ErrorTypeEnum.RESOURCE,
|
type: ErrorTypeEnum.RESOURCE,
|
||||||
name: 'Resouce Error!',
|
name: 'Resource Error!',
|
||||||
file: (e.target || ({} as any)).currentSrc,
|
file: (e.target || ({} as any)).currentSrc,
|
||||||
detail: JSON.stringify({
|
detail: JSON.stringify({
|
||||||
tagName: target.localName,
|
tagName: target.localName,
|
||||||
@ -147,7 +153,7 @@ function registerResourceErrorHandler() {
|
|||||||
type: e.type,
|
type: e.type,
|
||||||
}),
|
}),
|
||||||
url: window.location.href,
|
url: window.location.href,
|
||||||
stack: 'resouce is not found',
|
stack: 'resource is not found',
|
||||||
message: (e.target || ({} as any)).localName + ' is load error',
|
message: (e.target || ({} as any)).localName + ' is load error',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -161,7 +167,9 @@ function registerResourceErrorHandler() {
|
|||||||
*/
|
*/
|
||||||
export function setupErrorHandle(app: App) {
|
export function setupErrorHandle(app: App) {
|
||||||
const { useErrorHandle } = projectSetting;
|
const { useErrorHandle } = projectSetting;
|
||||||
if (!useErrorHandle) return;
|
if (!useErrorHandle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Vue exception monitoring;
|
// Vue exception monitoring;
|
||||||
app.config.errorHandler = vueErrorHandler;
|
app.config.errorHandler = vueErrorHandler;
|
||||||
|
|
||||||
|
@ -12,18 +12,20 @@ import { updateGrayMode } from '/@/logics/theme/updateGrayMode';
|
|||||||
import { updateDarkTheme } from '/@/logics/theme/dark';
|
import { updateDarkTheme } from '/@/logics/theme/dark';
|
||||||
import { changeTheme } from '/@/logics/theme';
|
import { changeTheme } from '/@/logics/theme';
|
||||||
|
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
import { localeStore } from '/@/store/modules/locale';
|
import { useLocaleStore } from '/@/store/modules/locale';
|
||||||
|
|
||||||
import { getCommonStoragePrefix, getStorageShortName } from '/@/utils/env';
|
import { getCommonStoragePrefix, getStorageShortName } from '/@/utils/env';
|
||||||
|
|
||||||
import { primaryColor } from '../../build/config/themeConfig';
|
import { primaryColor } from '../../build/config/themeConfig';
|
||||||
import { Persistent } from '/@/utils/cache/persistent';
|
import { Persistent } from '/@/utils/cache/persistent';
|
||||||
import { deepMerge } from '/@/utils';
|
import { deepMerge } from '/@/utils';
|
||||||
import { ThemeEnum } from '../enums/appEnum';
|
import { ThemeEnum } from '/@/enums/appEnum';
|
||||||
|
|
||||||
// Initial project configuration
|
// Initial project configuration
|
||||||
export function initAppConfigStore() {
|
export function initAppConfigStore() {
|
||||||
|
const localeStore = useLocaleStore();
|
||||||
|
const appStore = useAppStore();
|
||||||
let projCfg: ProjectConfig = Persistent.getLocal(PROJ_CFG_KEY) as ProjectConfig;
|
let projCfg: ProjectConfig = Persistent.getLocal(PROJ_CFG_KEY) as ProjectConfig;
|
||||||
projCfg = deepMerge(projectSetting, projCfg || {});
|
projCfg = deepMerge(projectSetting, projCfg || {});
|
||||||
const darkMode = appStore.getDarkMode;
|
const darkMode = appStore.getDarkMode;
|
||||||
@ -45,7 +47,7 @@ export function initAppConfigStore() {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
appStore.commitProjectConfigState(projCfg);
|
appStore.setProjectConfig(projCfg);
|
||||||
|
|
||||||
// init dark mode
|
// init dark mode
|
||||||
updateDarkTheme(darkMode);
|
updateDarkTheme(darkMode);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { colorIsDark, lighten, darken } from '/@/utils/color';
|
import { colorIsDark, lighten, darken } from '/@/utils/color';
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
import { ThemeEnum } from '/@/enums/appEnum';
|
import { ThemeEnum } from '/@/enums/appEnum';
|
||||||
import { setCssVar } from './util';
|
import { setCssVar } from './util';
|
||||||
|
|
||||||
@ -16,12 +16,13 @@ const SIDER_LIGHTEN_BG_COLOR = '--sider-dark-lighten-bg-color';
|
|||||||
* @param color
|
* @param color
|
||||||
*/
|
*/
|
||||||
export function updateHeaderBgColor(color?: string) {
|
export function updateHeaderBgColor(color?: string) {
|
||||||
|
const appStore = useAppStore();
|
||||||
const darkMode = appStore.getDarkMode === ThemeEnum.DARK;
|
const darkMode = appStore.getDarkMode === ThemeEnum.DARK;
|
||||||
if (!color) {
|
if (!color) {
|
||||||
if (darkMode) {
|
if (darkMode) {
|
||||||
color = '#151515';
|
color = '#151515';
|
||||||
} else {
|
} else {
|
||||||
color = appStore.getProjectConfig.headerSetting.bgColor;
|
color = appStore.getHeaderSetting.bgColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// bg color
|
// bg color
|
||||||
@ -35,7 +36,7 @@ export function updateHeaderBgColor(color?: string) {
|
|||||||
// Determine the depth of the color value and automatically switch the theme
|
// Determine the depth of the color value and automatically switch the theme
|
||||||
const isDark = colorIsDark(color!);
|
const isDark = colorIsDark(color!);
|
||||||
|
|
||||||
appStore.commitProjectConfigState({
|
appStore.setProjectConfig({
|
||||||
headerSetting: {
|
headerSetting: {
|
||||||
theme: isDark || darkMode ? ThemeEnum.DARK : ThemeEnum.LIGHT,
|
theme: isDark || darkMode ? ThemeEnum.DARK : ThemeEnum.LIGHT,
|
||||||
},
|
},
|
||||||
@ -47,13 +48,15 @@ export function updateHeaderBgColor(color?: string) {
|
|||||||
* @param color bg color
|
* @param color bg color
|
||||||
*/
|
*/
|
||||||
export function updateSidebarBgColor(color?: string) {
|
export function updateSidebarBgColor(color?: string) {
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
// if (!isHexColor(color)) return;
|
// if (!isHexColor(color)) return;
|
||||||
const darkMode = appStore.getDarkMode === ThemeEnum.DARK;
|
const darkMode = appStore.getDarkMode === ThemeEnum.DARK;
|
||||||
if (!color) {
|
if (!color) {
|
||||||
if (darkMode) {
|
if (darkMode) {
|
||||||
color = '#212121';
|
color = '#212121';
|
||||||
} else {
|
} else {
|
||||||
color = appStore.getProjectConfig.menuSetting.bgColor;
|
color = appStore.getMenuSetting.bgColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setCssVar(SIDER_DARK_BG_COLOR, color);
|
setCssVar(SIDER_DARK_BG_COLOR, color);
|
||||||
@ -64,7 +67,7 @@ export function updateSidebarBgColor(color?: string) {
|
|||||||
// Only when the background color is #fff, the theme of the menu will be changed to light
|
// Only when the background color is #fff, the theme of the menu will be changed to light
|
||||||
const isLight = ['#fff', '#ffffff'].includes(color!.toLowerCase());
|
const isLight = ['#fff', '#ffffff'].includes(color!.toLowerCase());
|
||||||
|
|
||||||
appStore.commitProjectConfigState({
|
appStore.setProjectConfig({
|
||||||
menuSetting: {
|
menuSetting: {
|
||||||
theme: isLight && !darkMode ? ThemeEnum.LIGHT : ThemeEnum.DARK,
|
theme: isLight && !darkMode ? ThemeEnum.LIGHT : ThemeEnum.DARK,
|
||||||
},
|
},
|
||||||
|
12
src/main.ts
12
src/main.ts
@ -5,15 +5,13 @@ import { createApp } from 'vue';
|
|||||||
import App from './App.vue';
|
import App from './App.vue';
|
||||||
|
|
||||||
import router, { setupRouter } from '/@/router';
|
import router, { setupRouter } from '/@/router';
|
||||||
|
import { setupRouterGuard } from '/@/router/guard';
|
||||||
import { setupStore } from '/@/store';
|
import { setupStore } from '/@/store';
|
||||||
import { setupErrorHandle } from '/@/logics/error-handle';
|
import { setupErrorHandle } from '/@/logics/error-handle';
|
||||||
import { setupGlobDirectives } from '/@/directives';
|
import { setupGlobDirectives } from '/@/directives';
|
||||||
import { setupI18n } from '/@/locales/setupI18n';
|
import { setupI18n } from '/@/locales/setupI18n';
|
||||||
import { registerGlobComp } from '/@/components/registerGlobComp';
|
import { registerGlobComp } from '/@/components/registerGlobComp';
|
||||||
|
|
||||||
// router-guard
|
|
||||||
import '/@/router/guard';
|
|
||||||
|
|
||||||
// Register icon Sprite
|
// Register icon Sprite
|
||||||
import 'vite-plugin-svg-icons/register';
|
import 'vite-plugin-svg-icons/register';
|
||||||
|
|
||||||
@ -27,6 +25,10 @@ if (import.meta.env.DEV) {
|
|||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
|
// Configure vuex store
|
||||||
|
setupStore(app);
|
||||||
|
|
||||||
// Register global components
|
// Register global components
|
||||||
registerGlobComp(app);
|
registerGlobComp(app);
|
||||||
|
|
||||||
@ -36,8 +38,8 @@ if (import.meta.env.DEV) {
|
|||||||
// Configure routing
|
// Configure routing
|
||||||
setupRouter(app);
|
setupRouter(app);
|
||||||
|
|
||||||
// Configure vuex store
|
// router-guard
|
||||||
setupStore(app);
|
setupRouterGuard();
|
||||||
|
|
||||||
// Register global directive
|
// Register global directive
|
||||||
setupGlobDirectives(app);
|
setupGlobDirectives(app);
|
||||||
|
@ -20,13 +20,3 @@ export const getParentLayout = (_name?: string) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// export const getParentLayout = (name: string) => {
|
|
||||||
// return () =>
|
|
||||||
// new Promise((resolve) => {
|
|
||||||
// resolve({
|
|
||||||
// ...ParentLayout,
|
|
||||||
// name,
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
|
@ -9,11 +9,13 @@ import { createHttpGuard } from './httpGuard';
|
|||||||
import { createPageGuard } from './pageGuard';
|
import { createPageGuard } from './pageGuard';
|
||||||
import { createStateGuard } from './stateGuard';
|
import { createStateGuard } from './stateGuard';
|
||||||
|
|
||||||
createPageGuard(router);
|
export function setupRouterGuard() {
|
||||||
createPageLoadingGuard(router);
|
createPageGuard(router);
|
||||||
createHttpGuard(router);
|
createPageLoadingGuard(router);
|
||||||
createScrollGuard(router);
|
createHttpGuard(router);
|
||||||
createMessageGuard(router);
|
createScrollGuard(router);
|
||||||
createProgressGuard(router);
|
createMessageGuard(router);
|
||||||
createPermissionGuard(router);
|
createProgressGuard(router);
|
||||||
createStateGuard(router);
|
createPermissionGuard(router);
|
||||||
|
createStateGuard(router);
|
||||||
|
}
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
import type { Router } from 'vue-router';
|
import type { Router } from 'vue-router';
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStoreWidthOut } from '/@/store/modules/app';
|
||||||
import { userStore } from '/@/store/modules/user';
|
import { useUserStoreWidthOut } from '/@/store/modules/user';
|
||||||
import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
|
import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
|
||||||
import { unref } from 'vue';
|
import { unref } from 'vue';
|
||||||
|
|
||||||
const { getOpenPageLoading } = useTransitionSetting();
|
|
||||||
export function createPageLoadingGuard(router: Router) {
|
export function createPageLoadingGuard(router: Router) {
|
||||||
|
const userStore = useUserStoreWidthOut();
|
||||||
|
const appStore = useAppStoreWidthOut();
|
||||||
|
const { getOpenPageLoading } = useTransitionSetting();
|
||||||
router.beforeEach(async (to) => {
|
router.beforeEach(async (to) => {
|
||||||
if (!userStore.getTokenState) {
|
if (!userStore.getToken) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (to.meta.loaded) {
|
if (to.meta.loaded) {
|
||||||
@ -24,7 +26,7 @@ export function createPageLoadingGuard(router: Router) {
|
|||||||
router.afterEach(async () => {
|
router.afterEach(async () => {
|
||||||
if (unref(getOpenPageLoading)) {
|
if (unref(getOpenPageLoading)) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
appStore.commitPageLoadingState(false);
|
appStore.setPageLoading(false);
|
||||||
}, 220);
|
}, 220);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import type { Router, RouteRecordRaw } from 'vue-router';
|
import type { Router, RouteRecordRaw } from 'vue-router';
|
||||||
|
|
||||||
import { permissionStore } from '/@/store/modules/permission';
|
import { usePermissionStoreWidthOut } from '/@/store/modules/permission';
|
||||||
|
|
||||||
import { PageEnum } from '/@/enums/pageEnum';
|
import { PageEnum } from '/@/enums/pageEnum';
|
||||||
import { userStore } from '/@/store/modules/user';
|
import { useUserStoreWidthOut } from '/@/store/modules/user';
|
||||||
|
|
||||||
import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic';
|
import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic';
|
||||||
|
|
||||||
@ -12,6 +12,8 @@ const LOGIN_PATH = PageEnum.BASE_LOGIN;
|
|||||||
const whitePathList: PageEnum[] = [LOGIN_PATH];
|
const whitePathList: PageEnum[] = [LOGIN_PATH];
|
||||||
|
|
||||||
export function createPermissionGuard(router: Router) {
|
export function createPermissionGuard(router: Router) {
|
||||||
|
const userStore = useUserStoreWidthOut();
|
||||||
|
const permissionStore = usePermissionStoreWidthOut();
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
// Jump to the 404 page after processing the login
|
// Jump to the 404 page after processing the login
|
||||||
if (from.path === LOGIN_PATH && to.name === PAGE_NOT_FOUND_ROUTE.name) {
|
if (from.path === LOGIN_PATH && to.name === PAGE_NOT_FOUND_ROUTE.name) {
|
||||||
@ -25,7 +27,7 @@ export function createPermissionGuard(router: Router) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const token = userStore.getTokenState;
|
const token = userStore.getToken;
|
||||||
|
|
||||||
// token does not exist
|
// token does not exist
|
||||||
if (!token) {
|
if (!token) {
|
||||||
@ -51,7 +53,7 @@ export function createPermissionGuard(router: Router) {
|
|||||||
next(redirectData);
|
next(redirectData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (permissionStore.getIsDynamicAddedRouteState) {
|
if (permissionStore.getIsDynamicAddedRoute) {
|
||||||
next();
|
next();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -64,7 +66,7 @@ export function createPermissionGuard(router: Router) {
|
|||||||
const redirectPath = (from.query.redirect || to.path) as string;
|
const redirectPath = (from.query.redirect || to.path) as string;
|
||||||
const redirect = decodeURIComponent(redirectPath);
|
const redirect = decodeURIComponent(redirectPath);
|
||||||
const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect };
|
const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect };
|
||||||
permissionStore.commitDynamicAddedRouteState(true);
|
permissionStore.setDynamicAddedRoute(true);
|
||||||
next(nextData);
|
next(nextData);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,8 @@ import nProgress from 'nprogress';
|
|||||||
|
|
||||||
import { unref } from 'vue';
|
import { unref } from 'vue';
|
||||||
|
|
||||||
const { getOpenNProgress } = useTransitionSetting();
|
|
||||||
|
|
||||||
export function createProgressGuard(router: Router) {
|
export function createProgressGuard(router: Router) {
|
||||||
|
const { getOpenNProgress } = useTransitionSetting();
|
||||||
router.beforeEach(async (to) => {
|
router.beforeEach(async (to) => {
|
||||||
if (to.meta.loaded) return true;
|
if (to.meta.loaded) return true;
|
||||||
unref(getOpenNProgress) && nProgress.start();
|
unref(getOpenNProgress) && nProgress.start();
|
||||||
|
@ -1,19 +1,23 @@
|
|||||||
import type { Router } from 'vue-router';
|
import type { Router } from 'vue-router';
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
import { tabStore } from '/@/store/modules/tab';
|
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
|
||||||
import { userStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
import { permissionStore } from '/@/store/modules/permission';
|
import { usePermissionStore } from '/@/store/modules/permission';
|
||||||
import { PageEnum } from '/@/enums/pageEnum';
|
import { PageEnum } from '/@/enums/pageEnum';
|
||||||
import { removeTabChangeListener } from '/@/logics/mitt/routeChange';
|
import { removeTabChangeListener } from '/@/logics/mitt/routeChange';
|
||||||
|
|
||||||
export function createStateGuard(router: Router) {
|
export function createStateGuard(router: Router) {
|
||||||
router.afterEach((to) => {
|
router.afterEach((to) => {
|
||||||
|
const tabStore = useMultipleTabStore();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const appStore = useAppStore();
|
||||||
|
const permissionStore = usePermissionStore();
|
||||||
// Just enter the login page and clear the authentication information
|
// Just enter the login page and clear the authentication information
|
||||||
if (to.path === PageEnum.BASE_LOGIN) {
|
if (to.path === PageEnum.BASE_LOGIN) {
|
||||||
appStore.resumeAllState();
|
appStore.resetAllState();
|
||||||
permissionStore.commitResetState();
|
permissionStore.resetState();
|
||||||
tabStore.commitResetState();
|
tabStore.resetState();
|
||||||
userStore.commitResetState();
|
userStore.resetState();
|
||||||
removeTabChangeListener();
|
removeTabChangeListener();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import type { Menu, MenuModule } from '/@/router/types';
|
import type { Menu, MenuModule } from '/@/router/types';
|
||||||
import type { RouteRecordNormalized } from 'vue-router';
|
import type { RouteRecordNormalized } from 'vue-router';
|
||||||
|
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStoreWidthOut } from '/@/store/modules/app';
|
||||||
import { permissionStore } from '/@/store/modules/permission';
|
import { usePermissionStore } from '/@/store/modules/permission';
|
||||||
import { transformMenuModule, getAllParentPath } from '/@/router/helper/menuHelper';
|
import { transformMenuModule, getAllParentPath } from '/@/router/helper/menuHelper';
|
||||||
import { filter } from '/@/utils/helper/treeHelper';
|
import { filter } from '/@/utils/helper/treeHelper';
|
||||||
import { isUrl } from '/@/utils/is';
|
import { isUrl } from '/@/utils/is';
|
||||||
@ -24,6 +24,7 @@ Object.keys(modules).forEach((key) => {
|
|||||||
// ==========Helper===========
|
// ==========Helper===========
|
||||||
// ===========================
|
// ===========================
|
||||||
const isBackMode = () => {
|
const isBackMode = () => {
|
||||||
|
const appStore = useAppStoreWidthOut();
|
||||||
return appStore.getProjectConfig.permissionMode === PermissionModeEnum.BACK;
|
return appStore.getProjectConfig.permissionMode === PermissionModeEnum.BACK;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -39,7 +40,8 @@ const staticMenus: Menu[] = [];
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
async function getAsyncMenus() {
|
async function getAsyncMenus() {
|
||||||
return !isBackMode() ? staticMenus : permissionStore.getBackMenuListState;
|
const permissionStore = usePermissionStore();
|
||||||
|
return !isBackMode() ? staticMenus : permissionStore.getBackMenuList;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getMenus = async (): Promise<Menu[]> => {
|
export const getMenus = async (): Promise<Menu[]> => {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { ThemeEnum } from '../enums/appEnum';
|
import { ThemeEnum } from '../enums/appEnum';
|
||||||
export default {
|
|
||||||
prefixCls: 'vben',
|
export const prefixCls = 'vben';
|
||||||
};
|
|
||||||
|
|
||||||
export const darkMode = ThemeEnum.LIGHT;
|
export const darkMode = ThemeEnum.LIGHT;
|
||||||
|
|
||||||
|
@ -61,7 +61,6 @@ const setting: ProjectConfig = {
|
|||||||
theme: ThemeEnum.LIGHT,
|
theme: ThemeEnum.LIGHT,
|
||||||
// Whether to enable the lock screen function
|
// Whether to enable the lock screen function
|
||||||
useLockPage: true,
|
useLockPage: true,
|
||||||
|
|
||||||
// Whether to show the full screen button
|
// Whether to show the full screen button
|
||||||
showFullScreen: true,
|
showFullScreen: true,
|
||||||
// Whether to show the document button
|
// Whether to show the document button
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// github repo url
|
// github repo url
|
||||||
export const GITHUB_URL = 'https://github.com/anncwb/vue-vben-admin';
|
export const GITHUB_URL = 'https://github.com/anncwb/vue-vben-admin';
|
||||||
|
|
||||||
// vue-vben-admin-next-doc
|
// vue-vben-admin-next-doc
|
||||||
export const DOC_URL = 'https://vvbin.cn/doc-next/';
|
export const DOC_URL = 'https://vvbin.cn/doc-next/';
|
||||||
|
|
||||||
// site url
|
// site url
|
||||||
export const SITE_URL = 'https://vvbin.cn/next/';
|
export const SITE_URL = 'https://vvbin.cn/next/';
|
||||||
|
@ -1,16 +1,9 @@
|
|||||||
import type { App } from 'vue';
|
import type { App } from 'vue';
|
||||||
import { createStore } from 'vuex';
|
import { createPinia } from 'pinia';
|
||||||
import { config } from 'vuex-module-decorators';
|
const store = createPinia();
|
||||||
import { isDevMode } from '/@/utils/env';
|
|
||||||
|
|
||||||
config.rawError = true;
|
|
||||||
|
|
||||||
const store = createStore({
|
|
||||||
strict: isDevMode(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export function setupStore(app: App<Element>) {
|
export function setupStore(app: App<Element>) {
|
||||||
app.use(store);
|
app.use(store);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default store;
|
export { store };
|
||||||
|
@ -1,109 +1,102 @@
|
|||||||
import type { ProjectConfig } from '/#/config';
|
import type { ProjectConfig } from '/#/config';
|
||||||
import type { BeforeMiniState } from '../types';
|
import type { BeforeMiniState } from '/#/store';
|
||||||
|
|
||||||
import { VuexModule, getModule, Module, Mutation, Action } from 'vuex-module-decorators';
|
import { defineStore } from 'pinia';
|
||||||
import store from '/@/store';
|
import { store } from '/@/store';
|
||||||
|
|
||||||
import { PROJ_CFG_KEY, APP_DARK_MODE_KEY_ } from '/@/enums/cacheEnum';
|
import { ThemeEnum } from '/@/enums/appEnum';
|
||||||
|
import { APP_DARK_MODE_KEY_, PROJ_CFG_KEY } from '/@/enums/cacheEnum';
|
||||||
import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper';
|
|
||||||
import { Persistent } from '/@/utils/cache/persistent';
|
import { Persistent } from '/@/utils/cache/persistent';
|
||||||
|
import { darkMode } from '/@/settings/designSetting';
|
||||||
|
import { resetRouter } from '/@/router';
|
||||||
import { deepMerge } from '/@/utils';
|
import { deepMerge } from '/@/utils';
|
||||||
|
|
||||||
import { resetRouter } from '/@/router';
|
interface AppState {
|
||||||
import { ThemeEnum } from '../../enums/appEnum';
|
darkMode: ThemeEnum;
|
||||||
|
|
||||||
import { darkMode } from '/@/settings/designSetting';
|
|
||||||
|
|
||||||
export interface LockInfo {
|
|
||||||
pwd: string | undefined;
|
|
||||||
isLock: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
let timeId: TimeoutHandle;
|
|
||||||
const NAME = 'app';
|
|
||||||
hotModuleUnregisterModule(NAME);
|
|
||||||
@Module({ dynamic: true, namespaced: true, store, name: NAME })
|
|
||||||
export default class App extends VuexModule {
|
|
||||||
private darkMode;
|
|
||||||
|
|
||||||
// Page loading status
|
// Page loading status
|
||||||
private pageLoadingState = false;
|
pageLoading: boolean;
|
||||||
|
|
||||||
// project config
|
// project config
|
||||||
private projectConfigState: ProjectConfig | null = Persistent.getLocal(PROJ_CFG_KEY);
|
projectConfig: ProjectConfig | null;
|
||||||
|
|
||||||
// set main overflow hidden
|
|
||||||
private lockMainScrollState = false;
|
|
||||||
|
|
||||||
// When the window shrinks, remember some states, and restore these states when the window is restored
|
// When the window shrinks, remember some states, and restore these states when the window is restored
|
||||||
private beforeMiniState: BeforeMiniState = {};
|
beforeMiniInfo: BeforeMiniState;
|
||||||
|
}
|
||||||
get getPageLoading() {
|
let timeId: TimeoutHandle;
|
||||||
return this.pageLoadingState;
|
export const useAppStore = defineStore({
|
||||||
}
|
id: 'app',
|
||||||
|
state: (): AppState => ({
|
||||||
get getDarkMode() {
|
darkMode: ThemeEnum.LIGHT,
|
||||||
return this.darkMode || localStorage.getItem(APP_DARK_MODE_KEY_) || darkMode;
|
pageLoading: false,
|
||||||
}
|
projectConfig: Persistent.getLocal(PROJ_CFG_KEY),
|
||||||
|
beforeMiniInfo: {},
|
||||||
get getBeforeMiniState() {
|
}),
|
||||||
return this.beforeMiniState;
|
getters: {
|
||||||
}
|
getPageLoading() {
|
||||||
|
return this.pageLoading;
|
||||||
get getLockMainScrollState() {
|
},
|
||||||
return this.lockMainScrollState;
|
getDarkMode() {
|
||||||
}
|
return this.darkMode || localStorage.getItem(APP_DARK_MODE_KEY_) || darkMode;
|
||||||
|
},
|
||||||
get getProjectConfig(): ProjectConfig {
|
|
||||||
return this.projectConfigState || ({} as ProjectConfig);
|
getBeforeMiniInfo() {
|
||||||
}
|
return this.beforeMiniInfo;
|
||||||
|
},
|
||||||
@Mutation
|
|
||||||
commitPageLoadingState(loading: boolean): void {
|
getProjectConfig(): ProjectConfig {
|
||||||
this.pageLoadingState = loading;
|
return this.projectConfig || ({} as ProjectConfig);
|
||||||
}
|
},
|
||||||
|
|
||||||
@Mutation
|
getHeaderSetting() {
|
||||||
commitDarkMode(mode: ThemeEnum): void {
|
return this.getProjectConfig.headerSetting;
|
||||||
this.darkMode = mode;
|
},
|
||||||
localStorage.setItem(APP_DARK_MODE_KEY_, mode);
|
getMenuSetting() {
|
||||||
}
|
return this.getProjectConfig.menuSetting;
|
||||||
|
},
|
||||||
@Mutation
|
getTransitionSetting() {
|
||||||
commitBeforeMiniState(state: BeforeMiniState): void {
|
return this.getProjectConfig.transitionSetting;
|
||||||
this.beforeMiniState = state;
|
},
|
||||||
}
|
getMultiTabsSetting() {
|
||||||
|
return this.getProjectConfig.multiTabsSetting;
|
||||||
@Mutation
|
},
|
||||||
commitLockMainScrollState(lock: boolean): void {
|
},
|
||||||
this.lockMainScrollState = lock;
|
actions: {
|
||||||
}
|
setPageLoading(loading: boolean): void {
|
||||||
|
this.pageLoading = loading;
|
||||||
@Mutation
|
},
|
||||||
commitProjectConfigState(proCfg: DeepPartial<ProjectConfig>): void {
|
|
||||||
this.projectConfigState = deepMerge(this.projectConfigState || {}, proCfg);
|
setDarkMode(mode: ThemeEnum): void {
|
||||||
Persistent.setLocal(PROJ_CFG_KEY, this.projectConfigState);
|
this.darkMode = mode;
|
||||||
}
|
localStorage.setItem(APP_DARK_MODE_KEY_, mode);
|
||||||
|
},
|
||||||
@Action
|
|
||||||
async resumeAllState() {
|
setBeforeMiniInfo(state: BeforeMiniState): void {
|
||||||
resetRouter();
|
this.beforeMiniInfo = state;
|
||||||
Persistent.clearAll();
|
},
|
||||||
}
|
|
||||||
|
setProjectConfig(config: DeepPartial<ProjectConfig>): void {
|
||||||
@Action
|
this.projectConfig = deepMerge(this.projectConfig || {}, config);
|
||||||
public async setPageLoadingAction(loading: boolean): Promise<void> {
|
Persistent.setLocal(PROJ_CFG_KEY, this.projectConfig);
|
||||||
if (loading) {
|
},
|
||||||
clearTimeout(timeId);
|
|
||||||
// Prevent flicker
|
async resetAllState() {
|
||||||
timeId = setTimeout(() => {
|
resetRouter();
|
||||||
this.commitPageLoadingState(loading);
|
Persistent.clearAll();
|
||||||
}, 50);
|
},
|
||||||
} else {
|
async setPageLoadingAction(loading: boolean): Promise<void> {
|
||||||
this.commitPageLoadingState(loading);
|
if (loading) {
|
||||||
clearTimeout(timeId);
|
clearTimeout(timeId);
|
||||||
}
|
// Prevent flicker
|
||||||
}
|
timeId = setTimeout(() => {
|
||||||
|
this.setPageLoading(loading);
|
||||||
|
}, 50);
|
||||||
|
} else {
|
||||||
|
this.setPageLoading(loading);
|
||||||
|
clearTimeout(timeId);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Need to be used outside the setup
|
||||||
|
export function useAppStoreWidthOut() {
|
||||||
|
return useAppStore(store);
|
||||||
}
|
}
|
||||||
export const appStore = getModule<App>(App);
|
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
import store from '/@/store';
|
|
||||||
import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper';
|
|
||||||
import { VuexModule, getModule, Module, Mutation, Action } from 'vuex-module-decorators';
|
|
||||||
|
|
||||||
import { formatToDateTime } from '/@/utils/dateUtil';
|
|
||||||
import { ErrorTypeEnum } from '/@/enums/exceptionEnum';
|
|
||||||
import projectSetting from '/@/settings/projectSetting';
|
|
||||||
|
|
||||||
export interface ErrorInfo {
|
|
||||||
type: ErrorTypeEnum;
|
|
||||||
file: string;
|
|
||||||
name?: string;
|
|
||||||
message: string;
|
|
||||||
stack?: string;
|
|
||||||
detail: string;
|
|
||||||
url: string;
|
|
||||||
time?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ErrorState {
|
|
||||||
errorInfoState: ErrorInfo[] | null;
|
|
||||||
errorListCountState: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const NAME = 'app-error';
|
|
||||||
hotModuleUnregisterModule(NAME);
|
|
||||||
@Module({ dynamic: true, namespaced: true, store, name: NAME })
|
|
||||||
class Error extends VuexModule implements ErrorState {
|
|
||||||
// error log list
|
|
||||||
errorInfoState: ErrorInfo[] = [];
|
|
||||||
|
|
||||||
// error log count
|
|
||||||
errorListCountState = 0;
|
|
||||||
|
|
||||||
get getErrorInfoState() {
|
|
||||||
return this.errorInfoState;
|
|
||||||
}
|
|
||||||
|
|
||||||
get getErrorListCountState() {
|
|
||||||
return this.errorListCountState;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mutation
|
|
||||||
commitErrorInfoState(info: ErrorInfo): void {
|
|
||||||
const item = {
|
|
||||||
...info,
|
|
||||||
time: formatToDateTime(new Date()),
|
|
||||||
};
|
|
||||||
this.errorInfoState = [item, ...this.errorInfoState];
|
|
||||||
this.errorListCountState += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mutation
|
|
||||||
commitErrorListCountState(count: number): void {
|
|
||||||
this.errorListCountState = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Action
|
|
||||||
setupErrorHandle(error: any) {
|
|
||||||
const { useErrorHandle } = projectSetting;
|
|
||||||
if (!useErrorHandle) return;
|
|
||||||
|
|
||||||
const errInfo: Partial<ErrorInfo> = {
|
|
||||||
message: error.message,
|
|
||||||
type: ErrorTypeEnum.AJAX,
|
|
||||||
};
|
|
||||||
if (error.response) {
|
|
||||||
const {
|
|
||||||
config: { url = '', data: params = '', method = 'get', headers = {} } = {},
|
|
||||||
data = {},
|
|
||||||
} = error.response;
|
|
||||||
errInfo.url = url;
|
|
||||||
errInfo.name = 'Ajax Error!';
|
|
||||||
errInfo.file = '-';
|
|
||||||
errInfo.stack = JSON.stringify(data);
|
|
||||||
errInfo.detail = JSON.stringify({ params, method, headers });
|
|
||||||
}
|
|
||||||
this.commitErrorInfoState(errInfo as ErrorInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export const errorStore = getModule<Error>(Error);
|
|
77
src/store/modules/errorLog.ts
Normal file
77
src/store/modules/errorLog.ts
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import type { ErrorLogInfo } from '/#/store';
|
||||||
|
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { store } from '/@/store';
|
||||||
|
|
||||||
|
import { formatToDateTime } from '/@/utils/dateUtil';
|
||||||
|
import projectSetting from '/@/settings/projectSetting';
|
||||||
|
|
||||||
|
import { ErrorTypeEnum } from '/@/enums/exceptionEnum';
|
||||||
|
|
||||||
|
export interface ErrorLogState {
|
||||||
|
errorLogInfoList: Nullable<ErrorLogInfo[]>;
|
||||||
|
errorLogListCount: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useErrorLogStore = defineStore({
|
||||||
|
id: 'app-error-log',
|
||||||
|
state: (): ErrorLogState => ({
|
||||||
|
errorLogInfoList: null,
|
||||||
|
errorLogListCount: 0,
|
||||||
|
}),
|
||||||
|
getters: {
|
||||||
|
getErrorLogInfoList() {
|
||||||
|
return this.errorLogInfoList || [];
|
||||||
|
},
|
||||||
|
getErrorLogListCount() {
|
||||||
|
return this.errorLogListCount;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
addErrorLogInfo(info: ErrorLogInfo) {
|
||||||
|
const item = {
|
||||||
|
...info,
|
||||||
|
time: formatToDateTime(new Date()),
|
||||||
|
};
|
||||||
|
this.errorLogInfoList = [item, ...(this.errorLogInfoList || [])];
|
||||||
|
this.errorLogListCount += 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
setErrorLogListCount(count: number): void {
|
||||||
|
this.errorLogListCount = count;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggered after ajax request error
|
||||||
|
* @param error
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
addAjaxErrorInfo(error) {
|
||||||
|
const { useErrorHandle } = projectSetting;
|
||||||
|
if (!useErrorHandle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const errInfo: Partial<ErrorLogInfo> = {
|
||||||
|
message: error.message,
|
||||||
|
type: ErrorTypeEnum.AJAX,
|
||||||
|
};
|
||||||
|
if (error.response) {
|
||||||
|
const {
|
||||||
|
config: { url = '', data: params = '', method = 'get', headers = {} } = {},
|
||||||
|
data = {},
|
||||||
|
} = error.response;
|
||||||
|
errInfo.url = url;
|
||||||
|
errInfo.name = 'Ajax Error!';
|
||||||
|
errInfo.file = '-';
|
||||||
|
errInfo.stack = JSON.stringify(data);
|
||||||
|
errInfo.detail = JSON.stringify({ params, method, headers });
|
||||||
|
}
|
||||||
|
this.addErrorLogInfo(errInfo as ErrorLogInfo);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Need to be used outside the setup
|
||||||
|
export function useErrorLogStoreWithOut() {
|
||||||
|
return useErrorLogStore(store);
|
||||||
|
}
|
@ -1,44 +1,55 @@
|
|||||||
import store from '/@/store';
|
import type { LocaleSetting, LocaleType } from '/#/config';
|
||||||
|
|
||||||
import { VuexModule, getModule, Module, Mutation, Action } from 'vuex-module-decorators';
|
import { defineStore } from 'pinia';
|
||||||
|
import { store } from '/@/store';
|
||||||
|
|
||||||
import { LOCALE_KEY } from '/@/enums/cacheEnum';
|
import { LOCALE_KEY } from '/@/enums/cacheEnum';
|
||||||
|
|
||||||
import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper';
|
|
||||||
import { LocaleSetting, LocaleType } from '/#/config';
|
|
||||||
import { createLocalStorage } from '/@/utils/cache';
|
import { createLocalStorage } from '/@/utils/cache';
|
||||||
import { localeSetting } from '/@/settings/localeSetting';
|
import { localeSetting } from '/@/settings/localeSetting';
|
||||||
|
|
||||||
const ls = createLocalStorage();
|
const ls = createLocalStorage();
|
||||||
|
|
||||||
const lsSetting = (ls.get(LOCALE_KEY) || localeSetting) as LocaleSetting;
|
const lsLocaleSetting = (ls.get(LOCALE_KEY) || localeSetting) as LocaleSetting;
|
||||||
|
|
||||||
const NAME = 'app-locale';
|
interface LocaleState {
|
||||||
hotModuleUnregisterModule(NAME);
|
localInfo: LocaleSetting;
|
||||||
@Module({ dynamic: true, namespaced: true, store, name: NAME })
|
}
|
||||||
class Locale extends VuexModule {
|
|
||||||
private info: LocaleSetting = lsSetting;
|
export const useLocaleStore = defineStore({
|
||||||
|
id: 'app-locale',
|
||||||
get getShowPicker(): boolean {
|
state: (): LocaleState => ({
|
||||||
return !!this.info?.showPicker;
|
localInfo: lsLocaleSetting,
|
||||||
}
|
}),
|
||||||
|
getters: {
|
||||||
get getLocale(): LocaleType {
|
getShowPicker() {
|
||||||
return this.info?.locale;
|
return !!this.localInfo?.showPicker;
|
||||||
}
|
},
|
||||||
|
getLocale(): LocaleType {
|
||||||
@Mutation
|
return this.localInfo?.locale ?? 'zh_CN';
|
||||||
setLocaleInfo(info: Partial<LocaleSetting>): void {
|
},
|
||||||
this.info = { ...this.info, ...info };
|
},
|
||||||
ls.set(LOCALE_KEY, this.info);
|
actions: {
|
||||||
}
|
/**
|
||||||
|
* Set up multilingual information and cache
|
||||||
@Action
|
* @param info multilingual info
|
||||||
initLocale(): void {
|
*/
|
||||||
this.setLocaleInfo({
|
setLocaleInfo(info: Partial<LocaleSetting>) {
|
||||||
...localeSetting,
|
this.localInfo = { ...this.localInfo, ...info };
|
||||||
...this.info,
|
ls.set(LOCALE_KEY, this.localInfo);
|
||||||
});
|
},
|
||||||
}
|
/**
|
||||||
|
* Initialize multilingual information and load the existing configuration from the local cache
|
||||||
|
*/
|
||||||
|
initLocale() {
|
||||||
|
this.setLocaleInfo({
|
||||||
|
...localeSetting,
|
||||||
|
...this.localInfo,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Need to be used outside the setup
|
||||||
|
export function useLocaleStoreWithOut() {
|
||||||
|
return useLocaleStore(store);
|
||||||
}
|
}
|
||||||
export const localeStore = getModule<Locale>(Locale);
|
|
||||||
|
@ -1,61 +1,59 @@
|
|||||||
import type { LockInfo } from '/@/store/types';
|
import type { LockInfo } from '/#/store';
|
||||||
|
|
||||||
import { VuexModule, getModule, Module, Mutation, Action } from 'vuex-module-decorators';
|
import { defineStore } from 'pinia';
|
||||||
import store from '/@/store';
|
|
||||||
|
|
||||||
import { LOCK_INFO_KEY } from '/@/enums/cacheEnum';
|
import { LOCK_INFO_KEY } from '/@/enums/cacheEnum';
|
||||||
|
|
||||||
import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper';
|
|
||||||
import { Persistent } from '/@/utils/cache/persistent';
|
import { Persistent } from '/@/utils/cache/persistent';
|
||||||
|
import { useUserStore } from './user';
|
||||||
|
|
||||||
import { userStore } from './user';
|
interface LockState {
|
||||||
|
lockInfo: Nullable<LockInfo>;
|
||||||
const NAME = 'app-lock';
|
|
||||||
hotModuleUnregisterModule(NAME);
|
|
||||||
@Module({ dynamic: true, namespaced: true, store, name: NAME })
|
|
||||||
class Lock extends VuexModule {
|
|
||||||
// lock info
|
|
||||||
private lockInfoState: LockInfo | null = Persistent.getLocal(LOCK_INFO_KEY);
|
|
||||||
|
|
||||||
get getLockInfo(): LockInfo {
|
|
||||||
return this.lockInfoState || ({} as LockInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mutation
|
|
||||||
commitLockInfoState(info: LockInfo): void {
|
|
||||||
this.lockInfoState = Object.assign({}, this.lockInfoState, info);
|
|
||||||
Persistent.setLocal(LOCK_INFO_KEY, this.lockInfoState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mutation
|
|
||||||
resetLockInfo(): void {
|
|
||||||
Persistent.removeLocal(LOCK_INFO_KEY);
|
|
||||||
this.lockInfoState = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description: unlock page
|
|
||||||
*/
|
|
||||||
@Action
|
|
||||||
public async unLockAction({ password }: { password: string }) {
|
|
||||||
const tryLogin = async () => {
|
|
||||||
try {
|
|
||||||
const username = userStore.getUserInfoState.username;
|
|
||||||
const res = await userStore.login({ username, password, goHome: false, mode: 'none' });
|
|
||||||
if (res) {
|
|
||||||
this.resetLockInfo();
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
} catch (error) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (this.getLockInfo?.pwd === password) {
|
|
||||||
this.resetLockInfo();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return await tryLogin();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
export const lockStore = getModule<Lock>(Lock);
|
|
||||||
|
export const useLockStore = defineStore({
|
||||||
|
id: 'app-lock',
|
||||||
|
state: (): LockState => ({
|
||||||
|
lockInfo: Persistent.getLocal(LOCK_INFO_KEY),
|
||||||
|
}),
|
||||||
|
getters: {
|
||||||
|
getLockInfo() {
|
||||||
|
return this.lockInfo;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
setLockInfo(info: LockInfo) {
|
||||||
|
this.lockInfo = Object.assign({}, this.lockInfo, info);
|
||||||
|
Persistent.setLocal(LOCK_INFO_KEY, this.lockInfo);
|
||||||
|
},
|
||||||
|
resetLockInfo() {
|
||||||
|
Persistent.removeLocal(LOCK_INFO_KEY);
|
||||||
|
this.lockInfo = null;
|
||||||
|
},
|
||||||
|
// Unlock
|
||||||
|
async unLock(password?: string) {
|
||||||
|
const userStore = useUserStore();
|
||||||
|
if (this.lockInfo?.pwd === password) {
|
||||||
|
this.resetLockInfo();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const tryLogin = async () => {
|
||||||
|
try {
|
||||||
|
const username = userStore.getUserInfo?.username;
|
||||||
|
const res = await userStore.login({
|
||||||
|
username,
|
||||||
|
password: password!,
|
||||||
|
goHome: false,
|
||||||
|
mode: 'none',
|
||||||
|
});
|
||||||
|
if (res) {
|
||||||
|
this.resetLockInfo();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return await tryLogin();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
288
src/store/modules/multipleTab.ts
Normal file
288
src/store/modules/multipleTab.ts
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
import type { RouteLocationNormalized, RouteLocationRaw, Router } from 'vue-router';
|
||||||
|
|
||||||
|
import { toRaw, unref } from 'vue';
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { store } from '/@/store';
|
||||||
|
|
||||||
|
import { useGo, useRedo } from '/@/hooks/web/usePage';
|
||||||
|
|
||||||
|
import { PageEnum } from '/@/enums/pageEnum';
|
||||||
|
import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/routes/basic';
|
||||||
|
import { getRawRoute } from '/@/utils';
|
||||||
|
|
||||||
|
export interface MultipleTabState {
|
||||||
|
cacheTabList: Set<string>;
|
||||||
|
tabList: RouteLocationNormalized[];
|
||||||
|
lastDragEndIndex: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleGotoPage(router: Router) {
|
||||||
|
const go = useGo(router);
|
||||||
|
go(unref(router.currentRoute).path, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useMultipleTabStore = defineStore({
|
||||||
|
id: 'app-multiple-tab',
|
||||||
|
state: (): MultipleTabState => ({
|
||||||
|
// Tabs that need to be cached
|
||||||
|
cacheTabList: new Set(),
|
||||||
|
// multiple tab list
|
||||||
|
tabList: [],
|
||||||
|
// Index of the last moved tab
|
||||||
|
lastDragEndIndex: 0,
|
||||||
|
}),
|
||||||
|
getters: {
|
||||||
|
getTabList() {
|
||||||
|
return this.tabList;
|
||||||
|
},
|
||||||
|
getCachedTabList(): string[] {
|
||||||
|
return Array.from(this.cacheTabList);
|
||||||
|
},
|
||||||
|
getLastDragEndIndex(): number {
|
||||||
|
return this.lastDragEndIndex;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
/**
|
||||||
|
* Update the cache according to the currently opened tabs
|
||||||
|
*/
|
||||||
|
async updateCacheTab() {
|
||||||
|
const cacheMap: Set<string> = new Set();
|
||||||
|
|
||||||
|
for (const tab of this.tabList) {
|
||||||
|
const item = getRawRoute(tab);
|
||||||
|
// Ignore the cache
|
||||||
|
const needCache = !item.meta?.ignoreKeepAlive;
|
||||||
|
if (!needCache) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const name = item.name as string;
|
||||||
|
cacheMap.add(name);
|
||||||
|
}
|
||||||
|
this.cacheTabList = cacheMap;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh tabs
|
||||||
|
*/
|
||||||
|
async refreshPage(router: Router) {
|
||||||
|
const { currentRoute } = router;
|
||||||
|
const route = unref(currentRoute);
|
||||||
|
const name = route.name;
|
||||||
|
|
||||||
|
const findTab = this.getCachedTabList.find((item) => item === name);
|
||||||
|
if (findTab) {
|
||||||
|
this.cacheTabList.delete(findTab);
|
||||||
|
}
|
||||||
|
const redo = useRedo(router);
|
||||||
|
await redo();
|
||||||
|
},
|
||||||
|
clearCacheTabs(): void {
|
||||||
|
this.cacheTabList = new Set();
|
||||||
|
},
|
||||||
|
resetState(): void {
|
||||||
|
this.tabList = [];
|
||||||
|
this.clearCacheTabs();
|
||||||
|
},
|
||||||
|
goToPage(router: Router) {
|
||||||
|
const go = useGo(router);
|
||||||
|
const len = this.tabList.length;
|
||||||
|
const { path } = unref(router.currentRoute);
|
||||||
|
|
||||||
|
let toPath: PageEnum | string = PageEnum.BASE_HOME;
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
const page = this.tabList[len - 1];
|
||||||
|
const p = page.fullPath || page.path;
|
||||||
|
if (p) {
|
||||||
|
toPath = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Jump to the current page and report an error
|
||||||
|
path !== toPath && go(toPath as PageEnum, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
async addTab(route: RouteLocationNormalized) {
|
||||||
|
const { path, name, fullPath, params, query } = getRawRoute(route);
|
||||||
|
// 404 The page does not need to add a tab
|
||||||
|
if (
|
||||||
|
path === PageEnum.ERROR_PAGE ||
|
||||||
|
!name ||
|
||||||
|
[REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes(name as string)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let updateIndex = -1;
|
||||||
|
// Existing pages, do not add tabs repeatedly
|
||||||
|
const tabHasExits = this.tabList.some((tab, index) => {
|
||||||
|
updateIndex = index;
|
||||||
|
return (tab.fullPath || tab.path) === (fullPath || path);
|
||||||
|
});
|
||||||
|
|
||||||
|
// If the tab already exists, perform the update operation
|
||||||
|
if (tabHasExits) {
|
||||||
|
const curTab = toRaw(this.tabList)[updateIndex];
|
||||||
|
if (!curTab) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
curTab.params = params || curTab.params;
|
||||||
|
curTab.query = query || curTab.query;
|
||||||
|
curTab.fullPath = fullPath || curTab.fullPath;
|
||||||
|
this.tabList.splice(updateIndex, 1, curTab);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Add tab
|
||||||
|
this.tabList.push(route);
|
||||||
|
this.updateCacheTab();
|
||||||
|
},
|
||||||
|
|
||||||
|
async closeTab(tab: RouteLocationNormalized, router: Router) {
|
||||||
|
const getToTarget = (tabItem: RouteLocationNormalized) => {
|
||||||
|
const { params, path, query } = tabItem;
|
||||||
|
return {
|
||||||
|
params: params || {},
|
||||||
|
path,
|
||||||
|
query: query || {},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const close = (route: RouteLocationNormalized) => {
|
||||||
|
const { fullPath, meta: { affix } = {} } = route;
|
||||||
|
if (affix) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const index = this.tabList.findIndex((item) => item.fullPath === fullPath);
|
||||||
|
index !== -1 && this.tabList.splice(index, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const { currentRoute, replace } = router;
|
||||||
|
|
||||||
|
const { path } = unref(currentRoute);
|
||||||
|
if (path !== tab.path) {
|
||||||
|
// Closed is not the activation tab
|
||||||
|
close(tab);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Closed is activated atb
|
||||||
|
let toTarget: RouteLocationRaw = {};
|
||||||
|
|
||||||
|
const index = this.tabList.findIndex((item) => item.path === path);
|
||||||
|
|
||||||
|
// If the current is the leftmost tab
|
||||||
|
if (index === 0) {
|
||||||
|
// There is only one tab, then jump to the homepage, otherwise jump to the right tab
|
||||||
|
if (this.tabList.length === 1) {
|
||||||
|
toTarget = PageEnum.BASE_HOME;
|
||||||
|
} else {
|
||||||
|
// Jump to the right tab
|
||||||
|
const page = this.tabList[index + 1];
|
||||||
|
toTarget = getToTarget(page);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Close the current tab
|
||||||
|
const page = this.tabList[index - 1];
|
||||||
|
toTarget = getToTarget(page);
|
||||||
|
}
|
||||||
|
close(currentRoute.value);
|
||||||
|
replace(toTarget);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Close according to key
|
||||||
|
async closeTabByKey(key: string, router: Router) {
|
||||||
|
const index = this.tabList.findIndex((item) => (item.fullPath || item.path) === key);
|
||||||
|
index !== -1 && this.closeTab(this.tabList[index], router);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Sort the tabs
|
||||||
|
async sortTabs(oldIndex: number, newIndex: number) {
|
||||||
|
const currentTab = this.tabList[oldIndex];
|
||||||
|
this.tabList.splice(oldIndex, 1);
|
||||||
|
this.tabList.splice(newIndex, 0, currentTab);
|
||||||
|
this.lastDragEndIndex = this.lastDragEndIndex + 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Close the tab on the right and jump
|
||||||
|
async closeLeftTabs(route: RouteLocationNormalized, router: Router) {
|
||||||
|
const index = this.tabList.findIndex((item) => item.path === route.path);
|
||||||
|
|
||||||
|
if (index > 0) {
|
||||||
|
const leftTabs = this.tabList.slice(0, index);
|
||||||
|
const pathList: string[] = [];
|
||||||
|
for (const item of leftTabs) {
|
||||||
|
const affix = item?.meta?.affix ?? false;
|
||||||
|
if (!affix) {
|
||||||
|
pathList.push(item.fullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.bulkCloseTabs(pathList);
|
||||||
|
}
|
||||||
|
this.updateCacheTab();
|
||||||
|
handleGotoPage(router);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Close the tab on the left and jump
|
||||||
|
async closeRightTabs(route: RouteLocationNormalized, router: Router) {
|
||||||
|
const index = this.tabList.findIndex((item) => item.fullPath === route.fullPath);
|
||||||
|
|
||||||
|
if (index >= 0 && index < this.tabList.length - 1) {
|
||||||
|
const rightTabs = this.tabList.slice(index + 1, this.tabList.length);
|
||||||
|
|
||||||
|
const pathList: string[] = [];
|
||||||
|
for (const item of rightTabs) {
|
||||||
|
const affix = item?.meta?.affix ?? false;
|
||||||
|
if (!affix) {
|
||||||
|
pathList.push(item.fullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.bulkCloseTabs(pathList);
|
||||||
|
}
|
||||||
|
this.updateCacheTab();
|
||||||
|
handleGotoPage(router);
|
||||||
|
},
|
||||||
|
|
||||||
|
async closeAllTab(router: Router) {
|
||||||
|
this.tabList = this.tabList.filter((item) => item?.meta?.affix ?? false);
|
||||||
|
this.clearCacheTabs();
|
||||||
|
this.goToPage(router);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close other tabs
|
||||||
|
*/
|
||||||
|
async closeOtherTabs(route: RouteLocationNormalized, router: Router) {
|
||||||
|
const closePathList = this.tabList.map((item) => item.fullPath);
|
||||||
|
|
||||||
|
const pathList: string[] = [];
|
||||||
|
|
||||||
|
for (const path of closePathList) {
|
||||||
|
if (path !== route.fullPath) {
|
||||||
|
const closeItem = this.tabList.find((item) => item.path === path);
|
||||||
|
if (!closeItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const affix = closeItem?.meta?.affix ?? false;
|
||||||
|
if (!affix) {
|
||||||
|
pathList.push(closeItem.fullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.bulkCloseTabs(pathList);
|
||||||
|
this.updateCacheTab();
|
||||||
|
handleGotoPage(router);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close tabs in bulk
|
||||||
|
*/
|
||||||
|
async bulkCloseTabs(pathList: string[]) {
|
||||||
|
this.tabList = this.tabList.filter((item) => !pathList.includes(item.fullPath));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Need to be used outside the setup
|
||||||
|
export function useMultipleTabWithOutStore() {
|
||||||
|
return useMultipleTabStore(store);
|
||||||
|
}
|
@ -1,21 +1,20 @@
|
|||||||
import type { AppRouteRecordRaw, Menu } from '/@/router/types';
|
import type { AppRouteRecordRaw, Menu } from '/@/router/types';
|
||||||
|
|
||||||
import store from '/@/store';
|
import { defineStore } from 'pinia';
|
||||||
|
import { store } from '/@/store';
|
||||||
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
|
import { useUserStore } from './user';
|
||||||
|
import { useAppStoreWidthOut } from './app';
|
||||||
import { toRaw } from 'vue';
|
import { toRaw } from 'vue';
|
||||||
import { VuexModule, Mutation, Module, getModule, Action } from 'vuex-module-decorators';
|
import { transformObjToRoute, flatMultiLevelRoutes } from '/@/router/helper/routeHelper';
|
||||||
|
import { transformRouteToMenu } from '/@/router/helper/menuHelper';
|
||||||
|
|
||||||
import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper';
|
import projectSetting from '/@/settings/projectSetting';
|
||||||
|
|
||||||
import { PermissionModeEnum } from '/@/enums/appEnum';
|
import { PermissionModeEnum } from '/@/enums/appEnum';
|
||||||
|
|
||||||
import { appStore } from '/@/store/modules/app';
|
|
||||||
import { userStore } from '/@/store/modules/user';
|
|
||||||
import projectSetting from '/@/settings/projectSetting';
|
|
||||||
|
|
||||||
import { asyncRoutes } from '/@/router/routes';
|
import { asyncRoutes } from '/@/router/routes';
|
||||||
import { ERROR_LOG_ROUTE, PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic';
|
import { ERROR_LOG_ROUTE, PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic';
|
||||||
import { transformObjToRoute, flatMultiLevelRoutes } from '/@/router/helper/routeHelper';
|
|
||||||
import { transformRouteToMenu } from '/@/router/helper/menuHelper';
|
|
||||||
|
|
||||||
import { filter } from '/@/utils/helper/treeHelper';
|
import { filter } from '/@/utils/helper/treeHelper';
|
||||||
|
|
||||||
@ -23,125 +22,127 @@ import { getMenuListById } from '/@/api/sys/menu';
|
|||||||
import { getPermCodeByUserId } from '/@/api/sys/user';
|
import { getPermCodeByUserId } from '/@/api/sys/user';
|
||||||
|
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
|
||||||
|
|
||||||
const NAME = 'app-permission';
|
interface PermissionState {
|
||||||
hotModuleUnregisterModule(NAME);
|
|
||||||
@Module({ dynamic: true, namespaced: true, store, name: NAME })
|
|
||||||
class Permission extends VuexModule {
|
|
||||||
// Permission code list
|
// Permission code list
|
||||||
private permCodeListState: string[] = [];
|
permCodeList: string[];
|
||||||
|
|
||||||
// Whether the route has been dynamically added
|
// Whether the route has been dynamically added
|
||||||
private isDynamicAddedRouteState = false;
|
isDynamicAddedRoute: boolean;
|
||||||
|
|
||||||
// To trigger a menu update
|
// To trigger a menu update
|
||||||
private lastBuildMenuTimeState = 0;
|
lastBuildMenuTime: number;
|
||||||
|
|
||||||
// Backstage menu list
|
// Backstage menu list
|
||||||
private backMenuListState: Menu[] = [];
|
backMenuList: Menu[];
|
||||||
|
}
|
||||||
get getPermCodeListState() {
|
export const usePermissionStore = defineStore({
|
||||||
return this.permCodeListState;
|
id: 'app-permission',
|
||||||
}
|
state: (): PermissionState => ({
|
||||||
|
permCodeList: [],
|
||||||
get getBackMenuListState() {
|
// Whether the route has been dynamically added
|
||||||
return this.backMenuListState;
|
isDynamicAddedRoute: false,
|
||||||
}
|
// To trigger a menu update
|
||||||
|
lastBuildMenuTime: 0,
|
||||||
get getLastBuildMenuTimeState() {
|
// Backstage menu list
|
||||||
return this.lastBuildMenuTimeState;
|
backMenuList: [],
|
||||||
}
|
}),
|
||||||
|
getters: {
|
||||||
get getIsDynamicAddedRouteState() {
|
getPermCodeList() {
|
||||||
return this.isDynamicAddedRouteState;
|
return this.permCodeList;
|
||||||
}
|
},
|
||||||
|
getBackMenuList() {
|
||||||
@Mutation
|
return this.backMenuList;
|
||||||
commitPermCodeListState(codeList: string[]): void {
|
},
|
||||||
this.permCodeListState = codeList;
|
getLastBuildMenuTime() {
|
||||||
}
|
return this.lastBuildMenuTime;
|
||||||
|
},
|
||||||
@Mutation
|
getIsDynamicAddedRoute() {
|
||||||
commitBackMenuListState(list: Menu[]): void {
|
return this.isDynamicAddedRoute;
|
||||||
this.backMenuListState = list;
|
},
|
||||||
}
|
},
|
||||||
|
actions: {
|
||||||
@Mutation
|
setPermCodeList(codeList: string[]) {
|
||||||
commitLastBuildMenuTimeState(): void {
|
this.permCodeList = codeList;
|
||||||
this.lastBuildMenuTimeState = new Date().getTime();
|
},
|
||||||
}
|
|
||||||
|
setBackMenuList(list: Menu[]) {
|
||||||
@Mutation
|
this.backMenuList = list;
|
||||||
commitDynamicAddedRouteState(added: boolean): void {
|
},
|
||||||
this.isDynamicAddedRouteState = added;
|
|
||||||
}
|
setLastBuildMenuTime() {
|
||||||
|
this.lastBuildMenuTime = new Date().getTime();
|
||||||
@Mutation
|
},
|
||||||
commitResetState(): void {
|
|
||||||
this.isDynamicAddedRouteState = false;
|
setDynamicAddedRoute(added: boolean) {
|
||||||
this.permCodeListState = [];
|
this.isDynamicAddedRoute = added;
|
||||||
this.backMenuListState = [];
|
},
|
||||||
this.lastBuildMenuTimeState = 0;
|
resetState(): void {
|
||||||
}
|
this.isDynamicAddedRoute = false;
|
||||||
|
this.permCodeList = [];
|
||||||
@Action
|
this.backMenuList = [];
|
||||||
async changePermissionCode(userId: string) {
|
this.lastBuildMenuTime = 0;
|
||||||
const codeList = await getPermCodeByUserId({ userId });
|
},
|
||||||
this.commitPermCodeListState(codeList);
|
async changePermissionCode(userId: string) {
|
||||||
}
|
const codeList = await getPermCodeByUserId({ userId });
|
||||||
|
this.setPermCodeList(codeList);
|
||||||
@Action
|
},
|
||||||
async buildRoutesAction(id?: number | string): Promise<AppRouteRecordRaw[]> {
|
async buildRoutesAction(id?: number | string): Promise<AppRouteRecordRaw[]> {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
let routes: AppRouteRecordRaw[] = [];
|
const userStore = useUserStore();
|
||||||
const roleList = toRaw(userStore.getRoleListState);
|
const appStore = useAppStoreWidthOut();
|
||||||
const { permissionMode = projectSetting.permissionMode } = appStore.getProjectConfig;
|
|
||||||
// role permissions
|
let routes: AppRouteRecordRaw[] = [];
|
||||||
if (permissionMode === PermissionModeEnum.ROLE) {
|
const roleList = toRaw(userStore.getRoleList);
|
||||||
const routeFilter = (route: AppRouteRecordRaw) => {
|
const { permissionMode = projectSetting.permissionMode } = appStore.getProjectConfig;
|
||||||
const { meta } = route;
|
// role permissions
|
||||||
const { roles } = meta || {};
|
if (permissionMode === PermissionModeEnum.ROLE) {
|
||||||
if (!roles) return true;
|
const routeFilter = (route: AppRouteRecordRaw) => {
|
||||||
return roleList.some((role) => roles.includes(role));
|
const { meta } = route;
|
||||||
};
|
const { roles } = meta || {};
|
||||||
routes = filter(asyncRoutes, routeFilter);
|
if (!roles) return true;
|
||||||
routes = routes.filter(routeFilter);
|
return roleList.some((role) => roles.includes(role));
|
||||||
// Convert multi-level routing to level 2 routing
|
};
|
||||||
routes = flatMultiLevelRoutes(routes);
|
routes = filter(asyncRoutes, routeFilter);
|
||||||
// If you are sure that you do not need to do background dynamic permissions, please comment the entire judgment below
|
routes = routes.filter(routeFilter);
|
||||||
} else if (permissionMode === PermissionModeEnum.BACK) {
|
// Convert multi-level routing to level 2 routing
|
||||||
const { createMessage } = useMessage();
|
routes = flatMultiLevelRoutes(routes);
|
||||||
|
// If you are sure that you do not need to do background dynamic permissions, please comment the entire judgment below
|
||||||
createMessage.loading({
|
} else if (permissionMode === PermissionModeEnum.BACK) {
|
||||||
content: t('sys.app.menuLoading'),
|
const { createMessage } = useMessage();
|
||||||
duration: 1,
|
|
||||||
});
|
createMessage.loading({
|
||||||
// Here to get the background routing menu logic to modify by yourself
|
content: t('sys.app.menuLoading'),
|
||||||
const paramId = id || userStore.getUserInfoState.userId;
|
duration: 1,
|
||||||
|
});
|
||||||
// !Simulate to obtain permission codes from the background,
|
// Here to get the background routing menu logic to modify by yourself
|
||||||
// this function may only need to be executed once, and the actual project can be put at the right time by itself
|
const paramId = id || userStore.getUserInfo?.userId;
|
||||||
try {
|
|
||||||
this.changePermissionCode('1');
|
// !Simulate to obtain permission codes from the background,
|
||||||
} catch (error) {}
|
// this function may only need to be executed once, and the actual project can be put at the right time by itself
|
||||||
if (!paramId) {
|
try {
|
||||||
throw new Error('paramId is undefined!');
|
this.changePermissionCode('1');
|
||||||
}
|
} catch (error) {}
|
||||||
let routeList = (await getMenuListById({ id: paramId })) as AppRouteRecordRaw[];
|
|
||||||
|
if (!paramId) {
|
||||||
// Dynamically introduce components
|
throw new Error('paramId is undefined!');
|
||||||
routeList = transformObjToRoute(routeList);
|
}
|
||||||
|
let routeList = (await getMenuListById({ id: paramId })) as AppRouteRecordRaw[];
|
||||||
// Background routing to menu structure
|
|
||||||
const backMenuList = transformRouteToMenu(routeList);
|
// Dynamically introduce components
|
||||||
this.commitBackMenuListState(backMenuList);
|
routeList = transformObjToRoute(routeList);
|
||||||
|
|
||||||
routeList = flatMultiLevelRoutes(routeList);
|
// Background routing to menu structure
|
||||||
routes = [PAGE_NOT_FOUND_ROUTE, ...routeList];
|
const backMenuList = transformRouteToMenu(routeList);
|
||||||
}
|
this.setBackMenuList(backMenuList);
|
||||||
routes.push(ERROR_LOG_ROUTE);
|
|
||||||
return routes;
|
routeList = flatMultiLevelRoutes(routeList);
|
||||||
}
|
routes = [PAGE_NOT_FOUND_ROUTE, ...routeList];
|
||||||
|
}
|
||||||
|
routes.push(ERROR_LOG_ROUTE);
|
||||||
|
return routes;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Need to be used outside the setup
|
||||||
|
export function usePermissionStoreWidthOut() {
|
||||||
|
return usePermissionStore(store);
|
||||||
}
|
}
|
||||||
export const permissionStore = getModule<Permission>(Permission);
|
|
||||||
|
@ -1,294 +0,0 @@
|
|||||||
import type { RouteLocationNormalized, RouteLocationRaw } from 'vue-router';
|
|
||||||
|
|
||||||
import { toRaw, unref } from 'vue';
|
|
||||||
import { Action, Module, Mutation, VuexModule, getModule } from 'vuex-module-decorators';
|
|
||||||
import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper';
|
|
||||||
|
|
||||||
import { PageEnum } from '/@/enums/pageEnum';
|
|
||||||
|
|
||||||
import store from '/@/store';
|
|
||||||
import router from '/@/router';
|
|
||||||
import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/routes/basic';
|
|
||||||
import { getRawRoute } from '/@/utils';
|
|
||||||
|
|
||||||
import { useGo, useRedo } from '/@/hooks/web/usePage';
|
|
||||||
import { cloneDeep } from 'lodash-es';
|
|
||||||
|
|
||||||
const NAME = 'app-tab';
|
|
||||||
|
|
||||||
hotModuleUnregisterModule(NAME);
|
|
||||||
|
|
||||||
function isGotoPage() {
|
|
||||||
const go = useGo();
|
|
||||||
go(unref(router.currentRoute).path, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Module({ namespaced: true, name: NAME, dynamic: true, store })
|
|
||||||
class Tab extends VuexModule {
|
|
||||||
cachedTabsState: Set<string> = new Set();
|
|
||||||
|
|
||||||
// tab list
|
|
||||||
tabsState: RouteLocationNormalized[] = [];
|
|
||||||
|
|
||||||
lastDragEndIndexState = 0;
|
|
||||||
|
|
||||||
get getTabsState() {
|
|
||||||
return this.tabsState;
|
|
||||||
}
|
|
||||||
|
|
||||||
get getCurrentTab(): RouteLocationNormalized {
|
|
||||||
const route = unref(router.currentRoute);
|
|
||||||
return this.tabsState.find((item) => item.path === route.path)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
get getCachedTabsState(): string[] {
|
|
||||||
return Array.from(this.cachedTabsState);
|
|
||||||
}
|
|
||||||
|
|
||||||
get getLastDragEndIndexState(): number {
|
|
||||||
return this.lastDragEndIndexState;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mutation
|
|
||||||
commitClearCache(): void {
|
|
||||||
this.cachedTabsState = new Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mutation
|
|
||||||
goToPage() {
|
|
||||||
const go = useGo();
|
|
||||||
const len = this.tabsState.length;
|
|
||||||
const { path } = unref(router.currentRoute);
|
|
||||||
|
|
||||||
let toPath: PageEnum | string = PageEnum.BASE_HOME;
|
|
||||||
|
|
||||||
if (len > 0) {
|
|
||||||
const page = this.tabsState[len - 1];
|
|
||||||
const p = page.fullPath || page.path;
|
|
||||||
if (p) {
|
|
||||||
toPath = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Jump to the current page and report an error
|
|
||||||
path !== toPath && go(toPath as PageEnum, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mutation
|
|
||||||
commitCachedMapState(): void {
|
|
||||||
const cacheMap: Set<string> = new Set();
|
|
||||||
|
|
||||||
this.tabsState.forEach((tab) => {
|
|
||||||
const item = getRawRoute(tab);
|
|
||||||
const needCache = !item.meta?.ignoreKeepAlive;
|
|
||||||
if (!needCache) return;
|
|
||||||
const name = item.name as string;
|
|
||||||
cacheMap.add(name);
|
|
||||||
});
|
|
||||||
this.cachedTabsState = cacheMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mutation
|
|
||||||
commitTabRoutesState(route: RouteLocationNormalized) {
|
|
||||||
const { path, fullPath, params, query } = route;
|
|
||||||
|
|
||||||
let updateIndex = -1;
|
|
||||||
// Existing pages, do not add tabs repeatedly
|
|
||||||
const hasTab = this.tabsState.some((tab, index) => {
|
|
||||||
updateIndex = index;
|
|
||||||
return (tab.fullPath || tab.path) === (fullPath || path);
|
|
||||||
});
|
|
||||||
if (hasTab) {
|
|
||||||
const curTab = toRaw(this.tabsState)[updateIndex];
|
|
||||||
if (!curTab) return;
|
|
||||||
curTab.params = params || curTab.params;
|
|
||||||
curTab.query = query || curTab.query;
|
|
||||||
curTab.fullPath = fullPath || curTab.fullPath;
|
|
||||||
this.tabsState.splice(updateIndex, 1, curTab);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.tabsState = cloneDeep([...this.tabsState, route]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description: close tab
|
|
||||||
*/
|
|
||||||
@Mutation
|
|
||||||
commitCloseTab(route: RouteLocationNormalized): void {
|
|
||||||
const { fullPath, meta: { affix } = {} } = route;
|
|
||||||
if (affix) return;
|
|
||||||
const index = this.tabsState.findIndex((item) => item.fullPath === fullPath);
|
|
||||||
index !== -1 && this.tabsState.splice(index, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mutation
|
|
||||||
commitCloseAllTab(): void {
|
|
||||||
this.tabsState = this.tabsState.filter((item) => {
|
|
||||||
return item.meta && item.meta.affix;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mutation
|
|
||||||
commitResetState(): void {
|
|
||||||
this.tabsState = [];
|
|
||||||
this.cachedTabsState = new Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mutation
|
|
||||||
commitSortTabs({ oldIndex, newIndex }: { oldIndex: number; newIndex: number }): void {
|
|
||||||
const currentTab = this.tabsState[oldIndex];
|
|
||||||
|
|
||||||
this.tabsState.splice(oldIndex, 1);
|
|
||||||
this.tabsState.splice(newIndex, 0, currentTab);
|
|
||||||
this.lastDragEndIndexState = this.lastDragEndIndexState + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mutation
|
|
||||||
closeMultipleTab({ pathList }: { pathList: string[] }): void {
|
|
||||||
this.tabsState = toRaw(this.tabsState).filter((item) => !pathList.includes(item.fullPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Action
|
|
||||||
addTabAction(route: RouteLocationNormalized) {
|
|
||||||
const { path, name } = route;
|
|
||||||
// 404 The page does not need to add a tab
|
|
||||||
if (
|
|
||||||
path === PageEnum.ERROR_PAGE ||
|
|
||||||
!name ||
|
|
||||||
[REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes(name as string)
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.commitTabRoutesState(getRawRoute(route));
|
|
||||||
|
|
||||||
this.commitCachedMapState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mutation
|
|
||||||
async commitRedoPage() {
|
|
||||||
const route = router.currentRoute.value;
|
|
||||||
const name = route.name;
|
|
||||||
|
|
||||||
const findVal = Array.from(this.cachedTabsState).find((item) => item === name);
|
|
||||||
if (findVal) {
|
|
||||||
this.cachedTabsState.delete(findVal);
|
|
||||||
// this.cachedTabsState.splice(index, 1);
|
|
||||||
}
|
|
||||||
const redo = useRedo();
|
|
||||||
await redo();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Action
|
|
||||||
closeAllTabAction() {
|
|
||||||
this.commitCloseAllTab();
|
|
||||||
this.commitClearCache();
|
|
||||||
this.goToPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Action
|
|
||||||
closeTabAction(tab: RouteLocationNormalized) {
|
|
||||||
function getObj(tabItem: RouteLocationNormalized) {
|
|
||||||
const { params, path, query } = tabItem;
|
|
||||||
return {
|
|
||||||
params: params || {},
|
|
||||||
path,
|
|
||||||
query: query || {},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { currentRoute, replace } = router;
|
|
||||||
|
|
||||||
const { path } = unref(currentRoute);
|
|
||||||
if (path !== tab.path) {
|
|
||||||
// Closed is not the activation tab
|
|
||||||
this.commitCloseTab(tab);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Closed is activated atb
|
|
||||||
let toObj: RouteLocationRaw = {};
|
|
||||||
|
|
||||||
const index = this.getTabsState.findIndex((item) => item.path === path);
|
|
||||||
|
|
||||||
// If the current is the leftmost tab
|
|
||||||
if (index === 0) {
|
|
||||||
// There is only one tab, then jump to the homepage, otherwise jump to the right tab
|
|
||||||
if (this.getTabsState.length === 1) {
|
|
||||||
toObj = PageEnum.BASE_HOME;
|
|
||||||
} else {
|
|
||||||
// Jump to the right tab
|
|
||||||
const page = this.getTabsState[index + 1];
|
|
||||||
toObj = getObj(page);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Close the current tab
|
|
||||||
const page = this.getTabsState[index - 1];
|
|
||||||
toObj = getObj(page);
|
|
||||||
}
|
|
||||||
this.commitCloseTab(currentRoute.value);
|
|
||||||
replace(toObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Action
|
|
||||||
closeTabByKeyAction(key: string) {
|
|
||||||
const index = this.tabsState.findIndex((item) => (item.fullPath || item.path) === key);
|
|
||||||
index !== -1 && this.closeTabAction(this.tabsState[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Action
|
|
||||||
closeLeftTabAction(route: RouteLocationNormalized): void {
|
|
||||||
const index = this.tabsState.findIndex((item) => item.path === route.path);
|
|
||||||
|
|
||||||
if (index > 0) {
|
|
||||||
const leftTabs = this.tabsState.slice(0, index);
|
|
||||||
const pathList: string[] = [];
|
|
||||||
for (const item of leftTabs) {
|
|
||||||
const affix = item.meta ? item.meta.affix : false;
|
|
||||||
if (!affix) {
|
|
||||||
pathList.push(item.fullPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.closeMultipleTab({ pathList });
|
|
||||||
}
|
|
||||||
this.commitCachedMapState();
|
|
||||||
isGotoPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Action
|
|
||||||
closeRightTabAction(route: RouteLocationNormalized): void {
|
|
||||||
const index = this.tabsState.findIndex((item) => item.fullPath === route.fullPath);
|
|
||||||
|
|
||||||
if (index >= 0 && index < this.tabsState.length - 1) {
|
|
||||||
const rightTabs = this.tabsState.slice(index + 1, this.tabsState.length);
|
|
||||||
|
|
||||||
const pathList: string[] = [];
|
|
||||||
for (const item of rightTabs) {
|
|
||||||
const affix = item.meta ? item.meta.affix : false;
|
|
||||||
if (!affix) {
|
|
||||||
pathList.push(item.fullPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.closeMultipleTab({ pathList });
|
|
||||||
}
|
|
||||||
this.commitCachedMapState();
|
|
||||||
isGotoPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Action
|
|
||||||
closeOtherTabAction(route: RouteLocationNormalized): void {
|
|
||||||
const closePathList = this.tabsState.map((item) => item.fullPath);
|
|
||||||
const pathList: string[] = [];
|
|
||||||
closePathList.forEach((path) => {
|
|
||||||
if (path !== route.fullPath) {
|
|
||||||
const closeItem = this.tabsState.find((item) => item.path === path);
|
|
||||||
if (!closeItem) return;
|
|
||||||
const affix = closeItem.meta ? closeItem.meta.affix : false;
|
|
||||||
if (!affix) {
|
|
||||||
pathList.push(closeItem.fullPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.closeMultipleTab({ pathList });
|
|
||||||
this.commitCachedMapState();
|
|
||||||
isGotoPage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export const tabStore = getModule<Tab>(Tab);
|
|
@ -1,141 +1,130 @@
|
|||||||
import type {
|
import type { UserInfo } from '/#/store';
|
||||||
LoginParams,
|
import type { ErrorMessageMode } from '/@/utils/http/axios/types';
|
||||||
GetUserInfoByUserIdModel,
|
|
||||||
GetUserInfoByUserIdParams,
|
|
||||||
} from '/@/api/sys/model/userModel';
|
|
||||||
import type { UserInfo } from '/@/store/types';
|
|
||||||
|
|
||||||
import store from '/@/store/index';
|
import { defineStore } from 'pinia';
|
||||||
import { VuexModule, Module, getModule, Mutation, Action } from 'vuex-module-decorators';
|
import { store } from '/@/store';
|
||||||
import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper';
|
|
||||||
|
|
||||||
import { PageEnum } from '/@/enums/pageEnum';
|
|
||||||
import { RoleEnum } from '/@/enums/roleEnum';
|
import { RoleEnum } from '/@/enums/roleEnum';
|
||||||
|
import { PageEnum } from '/@/enums/pageEnum';
|
||||||
import { ROLES_KEY, TOKEN_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum';
|
import { ROLES_KEY, TOKEN_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum';
|
||||||
|
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { getAuthCache, setAuthCache } from '/@/utils/auth';
|
||||||
|
import {
|
||||||
|
GetUserInfoByUserIdModel,
|
||||||
|
GetUserInfoByUserIdParams,
|
||||||
|
LoginParams,
|
||||||
|
} from '/@/api/sys/model/userModel';
|
||||||
|
|
||||||
import router from '/@/router';
|
import { getUserInfoById, loginApi } from '/@/api/sys/user';
|
||||||
|
|
||||||
import { loginApi, getUserInfoById } from '/@/api/sys/user';
|
|
||||||
|
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
import { ErrorMessageMode } from '/@/utils/http/axios/types';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
import { getAuthCache, setAuthCache } from '/@/utils/auth/index';
|
import router from '/@/router';
|
||||||
|
|
||||||
const NAME = 'app-user';
|
interface UserState {
|
||||||
hotModuleUnregisterModule(NAME);
|
userInfo: Nullable<UserInfo>;
|
||||||
|
token?: string;
|
||||||
@Module({ namespaced: true, name: NAME, dynamic: true, store })
|
roleList: RoleEnum[];
|
||||||
class User extends VuexModule {
|
}
|
||||||
// user info
|
|
||||||
private userInfoState: UserInfo | null = null;
|
export const useUserStore = defineStore({
|
||||||
|
id: 'app-user',
|
||||||
// token
|
state: (): UserState => ({
|
||||||
private tokenState = '';
|
// user info
|
||||||
|
userInfo: null,
|
||||||
// roleList
|
// token
|
||||||
private roleListState: RoleEnum[] = [];
|
token: undefined,
|
||||||
|
// roleList
|
||||||
get getUserInfoState(): UserInfo {
|
roleList: [],
|
||||||
return this.userInfoState || getAuthCache<UserInfo>(USER_INFO_KEY) || {};
|
}),
|
||||||
}
|
getters: {
|
||||||
|
getUserInfo(): UserInfo {
|
||||||
get getTokenState(): string {
|
return this.userInfo || getAuthCache<UserInfo>(USER_INFO_KEY) || {};
|
||||||
return this.tokenState || getAuthCache<string>(TOKEN_KEY);
|
},
|
||||||
}
|
getToken(): string {
|
||||||
|
return this.token || getAuthCache<string>(TOKEN_KEY);
|
||||||
get getRoleListState(): RoleEnum[] {
|
},
|
||||||
return this.roleListState.length > 0 ? this.roleListState : getAuthCache<RoleEnum[]>(ROLES_KEY);
|
getRoleList(): RoleEnum[] {
|
||||||
}
|
return this.roleList.length > 0 ? this.roleList : getAuthCache<RoleEnum[]>(ROLES_KEY);
|
||||||
|
},
|
||||||
@Mutation
|
},
|
||||||
commitResetState(): void {
|
actions: {
|
||||||
this.userInfoState = null;
|
setToken(info: string) {
|
||||||
this.tokenState = '';
|
this.token = info;
|
||||||
this.roleListState = [];
|
setAuthCache(TOKEN_KEY, info);
|
||||||
}
|
},
|
||||||
|
setRoleList(roleList: RoleEnum[]) {
|
||||||
@Mutation
|
this.roleList = roleList;
|
||||||
commitUserInfoState(info: UserInfo): void {
|
setAuthCache(ROLES_KEY, roleList);
|
||||||
this.userInfoState = info;
|
},
|
||||||
setAuthCache(USER_INFO_KEY, info);
|
setUserInfo(info: UserInfo) {
|
||||||
}
|
this.userInfo = info;
|
||||||
|
setAuthCache(USER_INFO_KEY, info);
|
||||||
@Mutation
|
},
|
||||||
commitRoleListState(roleList: RoleEnum[]): void {
|
resetState() {
|
||||||
this.roleListState = roleList;
|
this.userInfo = null;
|
||||||
setAuthCache(ROLES_KEY, roleList);
|
this.token = '';
|
||||||
}
|
this.roleList = [];
|
||||||
|
},
|
||||||
@Mutation
|
/**
|
||||||
commitTokenState(info: string): void {
|
* @description: login
|
||||||
this.tokenState = info;
|
*/
|
||||||
setAuthCache(TOKEN_KEY, info);
|
async login(
|
||||||
}
|
params: LoginParams & {
|
||||||
|
goHome?: boolean;
|
||||||
/**
|
mode?: ErrorMessageMode;
|
||||||
* @description: login
|
}
|
||||||
*/
|
): Promise<GetUserInfoByUserIdModel | null> {
|
||||||
@Action
|
try {
|
||||||
async login(
|
const { goHome = true, mode, ...loginParams } = params;
|
||||||
params: LoginParams & {
|
const data = await loginApi(loginParams, mode);
|
||||||
goHome?: boolean;
|
const { token, userId } = data;
|
||||||
mode?: ErrorMessageMode;
|
|
||||||
}
|
// save token
|
||||||
): Promise<GetUserInfoByUserIdModel | null> {
|
this.setToken(token);
|
||||||
try {
|
// get user info
|
||||||
const { goHome = true, mode, ...loginParams } = params;
|
const userInfo = await this.getUserInfoAction({ userId });
|
||||||
const data = await loginApi(loginParams, mode);
|
|
||||||
|
goHome && (await router.replace(PageEnum.BASE_HOME));
|
||||||
const { token, userId } = data;
|
return userInfo;
|
||||||
|
} catch (error) {
|
||||||
// save token
|
return null;
|
||||||
this.commitTokenState(token);
|
}
|
||||||
|
},
|
||||||
// get user info
|
async getUserInfoAction({ userId }: GetUserInfoByUserIdParams) {
|
||||||
const userInfo = await this.getUserInfoAction({ userId });
|
const userInfo = await getUserInfoById({ userId });
|
||||||
|
const { roles } = userInfo;
|
||||||
goHome && (await router.replace(PageEnum.BASE_HOME));
|
const roleList = roles.map((item) => item.value) as RoleEnum[];
|
||||||
return userInfo;
|
this.setUserInfo(userInfo);
|
||||||
} catch (error) {
|
this.setRoleList(roleList);
|
||||||
return null;
|
return userInfo;
|
||||||
}
|
},
|
||||||
}
|
/**
|
||||||
|
* @description: logout
|
||||||
@Action
|
*/
|
||||||
async getUserInfoAction({ userId }: GetUserInfoByUserIdParams) {
|
logout(goLogin = false) {
|
||||||
const userInfo = await getUserInfoById({ userId });
|
goLogin && router.push(PageEnum.BASE_LOGIN);
|
||||||
const { roles } = userInfo;
|
},
|
||||||
const roleList = roles.map((item) => item.value) as RoleEnum[];
|
|
||||||
this.commitUserInfoState(userInfo);
|
/**
|
||||||
this.commitRoleListState(roleList);
|
* @description: Confirm before logging out
|
||||||
return userInfo;
|
*/
|
||||||
}
|
confirmLoginOut() {
|
||||||
|
const { createConfirm } = useMessage();
|
||||||
/**
|
const { t } = useI18n();
|
||||||
* @description: logout
|
createConfirm({
|
||||||
*/
|
iconType: 'warning',
|
||||||
@Action
|
title: t('sys.app.logoutTip'),
|
||||||
async logout(goLogin = false) {
|
content: t('sys.app.logoutMessage'),
|
||||||
goLogin && router.push(PageEnum.BASE_LOGIN);
|
onOk: async () => {
|
||||||
}
|
await this.logout(true);
|
||||||
|
},
|
||||||
/**
|
});
|
||||||
* @description: Confirm before logging out
|
},
|
||||||
*/
|
},
|
||||||
@Action
|
});
|
||||||
async confirmLoginOut() {
|
|
||||||
const { createConfirm } = useMessage();
|
// Need to be used outside the setup
|
||||||
const { t } = useI18n();
|
export function useUserStoreWidthOut() {
|
||||||
createConfirm({
|
return useUserStore(store);
|
||||||
iconType: 'warning',
|
|
||||||
title: t('sys.app.logoutTip'),
|
|
||||||
content: t('sys.app.logoutMessage'),
|
|
||||||
onOk: async () => {
|
|
||||||
await this.logout(true);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
export const userStore = getModule<User>(User);
|
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
import { MenuModeEnum, MenuTypeEnum } from '../enums/menuEnum';
|
|
||||||
|
|
||||||
export interface LockInfo {
|
|
||||||
pwd: string | undefined;
|
|
||||||
isLock: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UserInfo {
|
|
||||||
// 用户id
|
|
||||||
userId: string | number;
|
|
||||||
// 用户名
|
|
||||||
username: string;
|
|
||||||
// 真实名字
|
|
||||||
realName: string;
|
|
||||||
// 介绍
|
|
||||||
desc?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BeforeMiniState {
|
|
||||||
menuCollapsed?: boolean;
|
|
||||||
menuSplit?: boolean;
|
|
||||||
menuMode?: MenuModeEnum;
|
|
||||||
menuType?: MenuTypeEnum;
|
|
||||||
}
|
|
5
src/utils/cache/persistent.ts
vendored
5
src/utils/cache/persistent.ts
vendored
@ -1,6 +1,5 @@
|
|||||||
import type { LockInfo, UserInfo } from '/@/store/types';
|
import type { LockInfo, UserInfo } from '/#/store';
|
||||||
|
import type { ProjectConfig } from '/#/config';
|
||||||
import { ProjectConfig } from '/#/config';
|
|
||||||
|
|
||||||
import { createLocalStorage, createSessionStorage } from '/@/utils/cache';
|
import { createLocalStorage, createSessionStorage } from '/@/utils/cache';
|
||||||
import { Memory } from './memory';
|
import { Memory } from './memory';
|
||||||
|
@ -35,6 +35,7 @@ export function getAppEnvConfig() {
|
|||||||
`VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.`
|
`VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
VITE_GLOB_APP_TITLE,
|
VITE_GLOB_APP_TITLE,
|
||||||
VITE_GLOB_API_URL,
|
VITE_GLOB_API_URL,
|
||||||
|
@ -16,7 +16,8 @@ import { RequestEnum, ResultEnum, ContentTypeEnum } from '/@/enums/httpEnum';
|
|||||||
import { isString } from '/@/utils/is';
|
import { isString } from '/@/utils/is';
|
||||||
import { getToken } from '/@/utils/auth';
|
import { getToken } from '/@/utils/auth';
|
||||||
import { setObjToUrlParams, deepMerge } from '/@/utils';
|
import { setObjToUrlParams, deepMerge } from '/@/utils';
|
||||||
import { errorStore } from '/@/store/modules/error';
|
import { useErrorLogStoreWithOut } from '/@/store/modules/errorLog';
|
||||||
|
|
||||||
import { errorResult } from './const';
|
import { errorResult } from './const';
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
import { createNow, formatRequestDate } from './helper';
|
import { createNow, formatRequestDate } from './helper';
|
||||||
@ -150,7 +151,8 @@ const transform: AxiosTransform = {
|
|||||||
*/
|
*/
|
||||||
responseInterceptorsCatch: (error: any) => {
|
responseInterceptorsCatch: (error: any) => {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
errorStore.setupErrorHandle(error);
|
const errorLogStore = useErrorLogStoreWithOut();
|
||||||
|
errorLogStore.addAjaxErrorInfo(error);
|
||||||
const { response, code, message } = error || {};
|
const { response, code, message } = error || {};
|
||||||
const msg: string = response?.data?.error?.message ?? '';
|
const msg: string = response?.data?.error?.message ?? '';
|
||||||
const err: string = error?.toString?.() ?? '';
|
const err: string = error?.toString?.() ?? '';
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, computed } from 'vue';
|
import { defineComponent, computed } from 'vue';
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
import { PermissionModeEnum } from '/@/enums/appEnum';
|
import { PermissionModeEnum } from '/@/enums/appEnum';
|
||||||
import { Divider } from 'ant-design-vue';
|
import { Divider } from 'ant-design-vue';
|
||||||
import { usePermission } from '/@/hooks/web/usePermission';
|
import { usePermission } from '/@/hooks/web/usePermission';
|
||||||
@ -18,9 +18,8 @@
|
|||||||
name: 'CurrentPermissionMode',
|
name: 'CurrentPermissionMode',
|
||||||
components: { Divider },
|
components: { Divider },
|
||||||
setup() {
|
setup() {
|
||||||
const permissionMode = computed(() => {
|
const appStore = useAppStore();
|
||||||
return appStore.getProjectConfig.permissionMode;
|
const permissionMode = computed(() => appStore.getProjectConfig.permissionMode);
|
||||||
});
|
|
||||||
const { togglePermissionMode } = usePermission();
|
const { togglePermissionMode } = usePermission();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<CurrentPermissionMode />
|
<CurrentPermissionMode />
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
当前拥有的code列表: <a> {{ permissionStore.getPermCodeListState }} </a>
|
当前拥有的code列表: <a> {{ permissionStore.getPermCodeList }} </a>
|
||||||
</p>
|
</p>
|
||||||
<Divider />
|
<Divider />
|
||||||
<Alert class="mt-4" type="info" message="点击后请查看按钮变化" show-icon />
|
<Alert class="mt-4" type="info" message="点击后请查看按钮变化" show-icon />
|
||||||
@ -59,7 +59,7 @@
|
|||||||
import CurrentPermissionMode from '../CurrentPermissionMode.vue';
|
import CurrentPermissionMode from '../CurrentPermissionMode.vue';
|
||||||
import { usePermission } from '/@/hooks/web/usePermission';
|
import { usePermission } from '/@/hooks/web/usePermission';
|
||||||
import { Authority } from '/@/components/Authority';
|
import { Authority } from '/@/components/Authority';
|
||||||
import { permissionStore } from '/@/store/modules/permission';
|
import { usePermissionStore } from '/@/store/modules/permission';
|
||||||
import { PermissionModeEnum } from '/@/enums/appEnum';
|
import { PermissionModeEnum } from '/@/enums/appEnum';
|
||||||
import { PageWrapper } from '/@/components/Page';
|
import { PageWrapper } from '/@/components/Page';
|
||||||
|
|
||||||
@ -67,6 +67,7 @@
|
|||||||
components: { Alert, PageWrapper, CurrentPermissionMode, Divider, Authority },
|
components: { Alert, PageWrapper, CurrentPermissionMode, Divider, Authority },
|
||||||
setup() {
|
setup() {
|
||||||
const { hasPermission } = usePermission();
|
const { hasPermission } = usePermission();
|
||||||
|
const permissionStore = usePermissionStore();
|
||||||
|
|
||||||
function changePermissionCode(userId: string) {
|
function changePermissionCode(userId: string) {
|
||||||
permissionStore.changePermissionCode(userId);
|
permissionStore.changePermissionCode(userId);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<CurrentPermissionMode />
|
<CurrentPermissionMode />
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
当前角色: <a> {{ userStore.getRoleListState }} </a>
|
当前角色: <a> {{ userStore.getRoleList }} </a>
|
||||||
</p>
|
</p>
|
||||||
<Alert class="mt-4" type="info" message="点击后请查看按钮变化" show-icon />
|
<Alert class="mt-4" type="info" message="点击后请查看按钮变化" show-icon />
|
||||||
|
|
||||||
@ -63,7 +63,7 @@
|
|||||||
import { computed, defineComponent } from 'vue';
|
import { computed, defineComponent } from 'vue';
|
||||||
import { Alert, Divider } from 'ant-design-vue';
|
import { Alert, Divider } from 'ant-design-vue';
|
||||||
import CurrentPermissionMode from '../CurrentPermissionMode.vue';
|
import CurrentPermissionMode from '../CurrentPermissionMode.vue';
|
||||||
import { userStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
import { RoleEnum } from '/@/enums/roleEnum';
|
import { RoleEnum } from '/@/enums/roleEnum';
|
||||||
import { usePermission } from '/@/hooks/web/usePermission';
|
import { usePermission } from '/@/hooks/web/usePermission';
|
||||||
import { Authority } from '/@/components/Authority';
|
import { Authority } from '/@/components/Authority';
|
||||||
@ -73,11 +73,13 @@
|
|||||||
components: { Alert, PageWrapper, CurrentPermissionMode, Divider, Authority },
|
components: { Alert, PageWrapper, CurrentPermissionMode, Divider, Authority },
|
||||||
setup() {
|
setup() {
|
||||||
const { changeRole, hasPermission } = usePermission();
|
const { changeRole, hasPermission } = usePermission();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
userStore,
|
userStore,
|
||||||
RoleEnum,
|
RoleEnum,
|
||||||
isSuper: computed(() => userStore.getRoleListState.includes(RoleEnum.SUPER)),
|
isSuper: computed(() => userStore.getRoleList.includes(RoleEnum.SUPER)),
|
||||||
isTest: computed(() => userStore.getRoleListState.includes(RoleEnum.TEST)),
|
isTest: computed(() => userStore.getRoleList.includes(RoleEnum.TEST)),
|
||||||
changeRole,
|
changeRole,
|
||||||
hasPermission,
|
hasPermission,
|
||||||
};
|
};
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<CurrentPermissionMode />
|
<CurrentPermissionMode />
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
当前角色: <a> {{ userStore.getRoleListState }} </a>
|
当前角色: <a> {{ userStore.getRoleList }} </a>
|
||||||
</p>
|
</p>
|
||||||
<Alert class="mt-4" type="info" message="点击后请查看左侧菜单变化" show-icon />
|
<Alert class="mt-4" type="info" message="点击后请查看左侧菜单变化" show-icon />
|
||||||
|
|
||||||
@ -29,7 +29,7 @@
|
|||||||
import { computed, defineComponent } from 'vue';
|
import { computed, defineComponent } from 'vue';
|
||||||
import { Alert } from 'ant-design-vue';
|
import { Alert } from 'ant-design-vue';
|
||||||
import CurrentPermissionMode from '../CurrentPermissionMode.vue';
|
import CurrentPermissionMode from '../CurrentPermissionMode.vue';
|
||||||
import { userStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
import { RoleEnum } from '/@/enums/roleEnum';
|
import { RoleEnum } from '/@/enums/roleEnum';
|
||||||
import { usePermission } from '/@/hooks/web/usePermission';
|
import { usePermission } from '/@/hooks/web/usePermission';
|
||||||
import { PageWrapper } from '/@/components/Page';
|
import { PageWrapper } from '/@/components/Page';
|
||||||
@ -38,11 +38,13 @@
|
|||||||
components: { Alert, CurrentPermissionMode, PageWrapper },
|
components: { Alert, CurrentPermissionMode, PageWrapper },
|
||||||
setup() {
|
setup() {
|
||||||
const { changeRole } = usePermission();
|
const { changeRole } = usePermission();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
userStore,
|
userStore,
|
||||||
RoleEnum,
|
RoleEnum,
|
||||||
isSuper: computed(() => userStore.getRoleListState.includes(RoleEnum.SUPER)),
|
isSuper: computed(() => userStore.getRoleList.includes(RoleEnum.SUPER)),
|
||||||
isTest: computed(() => userStore.getRoleListState.includes(RoleEnum.TEST)),
|
isTest: computed(() => userStore.getRoleList.includes(RoleEnum.TEST)),
|
||||||
changeRole,
|
changeRole,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { PropType } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
|
import type { ErrorLogInfo } from '/#/store';
|
||||||
|
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { BasicModal } from '/@/components/Modal/index';
|
import { BasicModal } from '/@/components/Modal/index';
|
||||||
@ -12,8 +13,6 @@
|
|||||||
|
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
|
|
||||||
import { ErrorInfo } from '/@/store/modules/error';
|
|
||||||
|
|
||||||
import { getDescSchema } from './data';
|
import { getDescSchema } from './data';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@ -21,7 +20,7 @@
|
|||||||
components: { BasicModal, Description },
|
components: { BasicModal, Description },
|
||||||
props: {
|
props: {
|
||||||
info: {
|
info: {
|
||||||
type: Object as PropType<ErrorInfo>,
|
type: Object as PropType<ErrorLogInfo>,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -30,7 +29,7 @@
|
|||||||
|
|
||||||
const [register] = useDescription({
|
const [register] = useDescription({
|
||||||
column: 2,
|
column: 2,
|
||||||
schema: getDescSchema(),
|
schema: getDescSchema()!,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -57,7 +57,7 @@ export function getColumns(): BasicColumn[] {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDescSchema() {
|
export function getDescSchema(): any {
|
||||||
return getColumns().map((column) => {
|
return getColumns().map((column) => {
|
||||||
return {
|
return {
|
||||||
field: column.dataIndex!,
|
field: column.dataIndex!,
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { ErrorLogInfo } from '/#/store';
|
||||||
|
|
||||||
import { defineComponent, watch, ref, nextTick } from 'vue';
|
import { defineComponent, watch, ref, nextTick } from 'vue';
|
||||||
|
|
||||||
import DetailModal from './DetailModal.vue';
|
import DetailModal from './DetailModal.vue';
|
||||||
@ -37,7 +39,7 @@
|
|||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
|
|
||||||
import { errorStore, ErrorInfo } from '/@/store/modules/error';
|
import { useErrorLogStore } from '/@/store/modules/errorLog';
|
||||||
|
|
||||||
import { fireErrorApi } from '/@/api/demo/error';
|
import { fireErrorApi } from '/@/api/demo/error';
|
||||||
|
|
||||||
@ -49,11 +51,11 @@
|
|||||||
name: 'ErrorHandler',
|
name: 'ErrorHandler',
|
||||||
components: { DetailModal, BasicTable, TableAction },
|
components: { DetailModal, BasicTable, TableAction },
|
||||||
setup() {
|
setup() {
|
||||||
const rowInfo = ref<ErrorInfo>();
|
const rowInfo = ref<ErrorLogInfo>();
|
||||||
const imgList = ref<string[]>([]);
|
const imgList = ref<string[]>([]);
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const errorLogStore = useErrorLogStore();
|
||||||
const [register, { setTableData }] = useTable({
|
const [register, { setTableData }] = useTable({
|
||||||
title: t('sys.errorLog.tableTitle'),
|
title: t('sys.errorLog.tableTitle'),
|
||||||
columns: getColumns(),
|
columns: getColumns(),
|
||||||
@ -67,7 +69,7 @@
|
|||||||
const [registerModal, { openModal }] = useModal();
|
const [registerModal, { openModal }] = useModal();
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => errorStore.getErrorInfoState,
|
() => errorLogStore.getErrorLogInfoList,
|
||||||
(list) => {
|
(list) => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
setTableData(cloneDeep(list));
|
setTableData(cloneDeep(list));
|
||||||
@ -82,7 +84,7 @@
|
|||||||
createMessage.info(t('sys.errorLog.enableMessage'));
|
createMessage.info(t('sys.errorLog.enableMessage'));
|
||||||
}
|
}
|
||||||
// 查看详情
|
// 查看详情
|
||||||
function handleDetail(row: ErrorInfo) {
|
function handleDetail(row: ErrorLogInfo) {
|
||||||
rowInfo.value = row;
|
rowInfo.value = row;
|
||||||
openModal(true);
|
openModal(true);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
class="enter-x"
|
class="enter-x"
|
||||||
v-model:value="password"
|
v-model:value="password"
|
||||||
/>
|
/>
|
||||||
<span :class="`${prefixCls}-entry__err-msg enter-x`" v-if="errMsgRef">
|
<span :class="`${prefixCls}-entry__err-msg enter-x`" v-if="errMsg">
|
||||||
{{ t('sys.lock.alert') }}
|
{{ t('sys.lock.alert') }}
|
||||||
</span>
|
</span>
|
||||||
<div :class="`${prefixCls}-entry__footer enter-x`">
|
<div :class="`${prefixCls}-entry__footer enter-x`">
|
||||||
@ -46,7 +46,7 @@
|
|||||||
type="link"
|
type="link"
|
||||||
size="small"
|
size="small"
|
||||||
class="mt-2 mr-2 enter-x"
|
class="mt-2 mr-2 enter-x"
|
||||||
:disabled="loadingRef"
|
:disabled="loading"
|
||||||
@click="handleShowForm(true)"
|
@click="handleShowForm(true)"
|
||||||
>
|
>
|
||||||
{{ t('common.back') }}
|
{{ t('common.back') }}
|
||||||
@ -55,12 +55,12 @@
|
|||||||
type="link"
|
type="link"
|
||||||
size="small"
|
size="small"
|
||||||
class="mt-2 mr-2 enter-x"
|
class="mt-2 mr-2 enter-x"
|
||||||
:disabled="loadingRef"
|
:disabled="loading"
|
||||||
@click="goLogin"
|
@click="goLogin"
|
||||||
>
|
>
|
||||||
{{ t('sys.lock.backToLogin') }}
|
{{ t('sys.lock.backToLogin') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button class="mt-2" type="link" size="small" @click="unLock()" :loading="loadingRef">
|
<a-button class="mt-2" type="link" size="small" @click="unLock()" :loading="loading">
|
||||||
{{ t('sys.lock.entry') }}
|
{{ t('sys.lock.entry') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
@ -80,8 +80,8 @@
|
|||||||
import { defineComponent, ref, computed } from 'vue';
|
import { defineComponent, ref, computed } from 'vue';
|
||||||
import { Input } from 'ant-design-vue';
|
import { Input } from 'ant-design-vue';
|
||||||
|
|
||||||
import { userStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
import { lockStore } from '/@/store/modules/lock';
|
import { useLockStore } from '/@/store/modules/lock';
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
|
|
||||||
import { useNow } from './useNow';
|
import { useNow } from './useNow';
|
||||||
@ -95,19 +95,21 @@
|
|||||||
components: { LockOutlined, InputPassword: Input.Password },
|
components: { LockOutlined, InputPassword: Input.Password },
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const passwordRef = ref('');
|
const password = ref('');
|
||||||
const loadingRef = ref(false);
|
const loading = ref(false);
|
||||||
const errMsgRef = ref(false);
|
const errMsg = ref(false);
|
||||||
const showDate = ref(true);
|
const showDate = ref(true);
|
||||||
|
|
||||||
const { prefixCls } = useDesign('lock-page');
|
const { prefixCls } = useDesign('lock-page');
|
||||||
|
const lockStore = useLockStore();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
const { ...state } = useNow(true);
|
const { ...state } = useNow(true);
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const realName = computed(() => {
|
const realName = computed(() => {
|
||||||
const { realName } = userStore.getUserInfoState || {};
|
const { realName } = userStore.getUserInfo || {};
|
||||||
return realName;
|
return realName;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -115,16 +117,16 @@
|
|||||||
* @description: unLock
|
* @description: unLock
|
||||||
*/
|
*/
|
||||||
async function unLock() {
|
async function unLock() {
|
||||||
if (!passwordRef.value) {
|
if (!password.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let password = passwordRef.value;
|
let pwd = password.value;
|
||||||
try {
|
try {
|
||||||
loadingRef.value = true;
|
loading.value = true;
|
||||||
const res = await lockStore.unLockAction({ password });
|
const res = await lockStore.unLock(pwd);
|
||||||
errMsgRef.value = !res;
|
errMsg.value = !res;
|
||||||
} finally {
|
} finally {
|
||||||
loadingRef.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,12 +143,12 @@
|
|||||||
goLogin,
|
goLogin,
|
||||||
realName,
|
realName,
|
||||||
unLock,
|
unLock,
|
||||||
errMsgRef,
|
errMsg,
|
||||||
loadingRef,
|
loading,
|
||||||
t,
|
t,
|
||||||
prefixCls,
|
prefixCls,
|
||||||
showDate,
|
showDate,
|
||||||
password: passwordRef,
|
password,
|
||||||
handleShowForm,
|
handleShowForm,
|
||||||
headerImg,
|
headerImg,
|
||||||
...state,
|
...state,
|
||||||
|
@ -7,17 +7,13 @@
|
|||||||
import { defineComponent, computed } from 'vue';
|
import { defineComponent, computed } from 'vue';
|
||||||
import LockPage from './LockPage.vue';
|
import LockPage from './LockPage.vue';
|
||||||
|
|
||||||
import { lockStore } from '/@/store/modules/lock';
|
import { useLockStore } from '/@/store/modules/lock';
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Lock',
|
name: 'Lock',
|
||||||
components: { LockPage },
|
components: { LockPage },
|
||||||
setup() {
|
setup() {
|
||||||
const getIsLock = computed(() => {
|
const lockStore = useLockStore();
|
||||||
const { getLockInfo } = lockStore;
|
const getIsLock = computed(() => lockStore?.getLockInfo?.isLock ?? false);
|
||||||
const { isLock } = getLockInfo;
|
|
||||||
return isLock;
|
|
||||||
});
|
|
||||||
|
|
||||||
return { getIsLock };
|
return { getIsLock };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { dateUtil } from '/@/utils/dateUtil';
|
import { dateUtil } from '/@/utils/dateUtil';
|
||||||
import { reactive, toRefs } from 'vue';
|
import { reactive, toRefs } from 'vue';
|
||||||
import { localeStore } from '/@/store/modules/locale';
|
import { useLocaleStore } from '/@/store/modules/locale';
|
||||||
import { tryOnMounted, tryOnUnmounted } from '@vueuse/core';
|
import { tryOnMounted, tryOnUnmounted } from '@vueuse/core';
|
||||||
|
|
||||||
export function useNow(immediate = true) {
|
export function useNow(immediate = true) {
|
||||||
|
const localeStore = useLocaleStore();
|
||||||
const localData = dateUtil.localeData(localeStore.getLocale);
|
const localData = dateUtil.localeData(localeStore.getLocale);
|
||||||
let timer: IntervalHandle;
|
let timer: IntervalHandle;
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
import { useGlobSetting } from '/@/hooks/setting';
|
import { useGlobSetting } from '/@/hooks/setting';
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { localeStore } from '/@/store/modules/locale';
|
import { useLocaleStore } from '/@/store/modules/locale';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Login',
|
name: 'Login',
|
||||||
@ -76,6 +76,7 @@
|
|||||||
const globSetting = useGlobSetting();
|
const globSetting = useGlobSetting();
|
||||||
const { prefixCls } = useDesign('login');
|
const { prefixCls } = useDesign('login');
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const localeStore = useLocaleStore();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
t,
|
t,
|
||||||
|
@ -85,7 +85,7 @@
|
|||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
|
|
||||||
import { userStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin';
|
import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { useKeyPress } from '/@/hooks/event/useKeyPress';
|
import { useKeyPress } from '/@/hooks/event/useKeyPress';
|
||||||
@ -114,6 +114,7 @@
|
|||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { notification } = useMessage();
|
const { notification } = useMessage();
|
||||||
const { prefixCls } = useDesign('login');
|
const { prefixCls } = useDesign('login');
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
const { setLoginState, getLoginState } = useLoginState();
|
const { setLoginState, getLoginState } = useLoginState();
|
||||||
const { getFormRules } = useFormRules();
|
const { getFormRules } = useFormRules();
|
||||||
|
44
types/store.ts
Normal file
44
types/store.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { ErrorTypeEnum } from '/@/enums/exceptionEnum';
|
||||||
|
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
|
||||||
|
|
||||||
|
// Lock screen information
|
||||||
|
export interface LockInfo {
|
||||||
|
// Password required
|
||||||
|
pwd?: string | undefined;
|
||||||
|
// Is it locked?
|
||||||
|
isLock?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error-log information
|
||||||
|
export interface ErrorLogInfo {
|
||||||
|
// Type of error
|
||||||
|
type: ErrorTypeEnum;
|
||||||
|
// Error file
|
||||||
|
file: string;
|
||||||
|
// Error name
|
||||||
|
name?: string;
|
||||||
|
// Error message
|
||||||
|
message: string;
|
||||||
|
// Error stack
|
||||||
|
stack?: string;
|
||||||
|
// Error detail
|
||||||
|
detail: string;
|
||||||
|
// Error url
|
||||||
|
url: string;
|
||||||
|
// Error time
|
||||||
|
time?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserInfo {
|
||||||
|
userId: string | number;
|
||||||
|
username: string;
|
||||||
|
realName: string;
|
||||||
|
desc?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BeforeMiniState {
|
||||||
|
menuCollapsed?: boolean;
|
||||||
|
menuSplit?: boolean;
|
||||||
|
menuMode?: MenuModeEnum;
|
||||||
|
menuType?: MenuTypeEnum;
|
||||||
|
}
|
91
yarn.lock
91
yarn.lock
@ -1762,25 +1762,25 @@
|
|||||||
resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.0.11.tgz#20d22dd0da7d358bb21c17f9bde8628152642c77"
|
resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.0.11.tgz#20d22dd0da7d358bb21c17f9bde8628152642c77"
|
||||||
integrity sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA==
|
integrity sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA==
|
||||||
|
|
||||||
"@vueuse/core@^4.8.0":
|
"@vueuse/core@^4.8.1":
|
||||||
version "4.8.0"
|
version "4.8.1"
|
||||||
resolved "https://registry.npmjs.org/@vueuse/core/-/core-4.8.0.tgz#d86e36956521c0f9b6571cb58b27f0e2535259b3"
|
resolved "https://registry.npmjs.org/@vueuse/core/-/core-4.8.1.tgz#d7a7fb2e72610d1962ecb9244bd93dacb96d921c"
|
||||||
integrity sha512-nUH4Hn1DN4kkuF1r5ZcfGnjoAKDD0Kw9oFnt/TUo1aueNijq4KujagtoQN8OC4Pei10TeTDdqhmZAWnaCE1NbA==
|
integrity sha512-oXFEDaKNU69Rj20/Hd7ZlmTpEtA2M19cRkZaL4A0Nl0w5Wb5In/8aK+0vtdi1VyMUXXbq6h1OGKCJcIhg5cziA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vueuse/shared" "4.8.0"
|
"@vueuse/shared" "4.8.1"
|
||||||
vue-demi latest
|
vue-demi latest
|
||||||
|
|
||||||
"@vueuse/shared@4.8.0":
|
"@vueuse/shared@4.8.1":
|
||||||
version "4.8.0"
|
version "4.8.1"
|
||||||
resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-4.8.0.tgz#abf3da96ca81b4be82e885928193fef2c676cdbc"
|
resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-4.8.1.tgz#45fd5f64bf4e8944db42a5b72fa2705cfc74608a"
|
||||||
integrity sha512-g1lSbHD4ptiS74qBUvffJ98QjRsoCH7ILjxVzJF488EPAmp5z3taLnoggt6NXfonnYve7fEPuqsJqd2BLOxT1A==
|
integrity sha512-ONKJoIvZPrGCA8loK7dX+ZcjgZLikI+vPiz1lWlXs6+jZiQiZSLkmvg1NjV6Cfb6OqbDCfEScTWLbZHB7EwrRw==
|
||||||
dependencies:
|
dependencies:
|
||||||
vue-demi latest
|
vue-demi latest
|
||||||
|
|
||||||
"@windicss/plugin-utils@0.12.5":
|
"@windicss/plugin-utils@0.13.1":
|
||||||
version "0.12.5"
|
version "0.13.1"
|
||||||
resolved "https://registry.npmjs.org/@windicss/plugin-utils/-/plugin-utils-0.12.5.tgz#d03517d1ae7a48b5b459e3d670e873d38b63e4a1"
|
resolved "https://registry.npmjs.org/@windicss/plugin-utils/-/plugin-utils-0.13.1.tgz#e0e172855ebcf0b8a5f0f358befdcaf44bae5cf1"
|
||||||
integrity sha512-4ux2o4s6D/gRTD68os41oxs/0NFk/eSJxHhZL9nN2wy4RGt+pPMQJyOHV56l7zDh9B0ywU5+ZRxDjdw2cl5Yvg==
|
integrity sha512-Vr7f7yWxmB5AWwe+iDPV3JbhTlZHbDvM89IfJ0hyP6PqYmZNTtUfMXMbHXZJHVAbQ54dWBMG23WmeC9X327ETA==
|
||||||
dependencies:
|
dependencies:
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
fast-glob "^3.2.5"
|
fast-glob "^3.2.5"
|
||||||
@ -1788,7 +1788,7 @@
|
|||||||
micromatch "^4.0.2"
|
micromatch "^4.0.2"
|
||||||
pirates "^4.0.1"
|
pirates "^4.0.1"
|
||||||
sucrase "^3.17.1"
|
sucrase "^3.17.1"
|
||||||
windicss "^2.5.11"
|
windicss "^2.5.12"
|
||||||
|
|
||||||
"@zxcvbn-ts/core@^0.3.0":
|
"@zxcvbn-ts/core@^0.3.0":
|
||||||
version "0.3.0"
|
version "0.3.0"
|
||||||
@ -3670,21 +3670,11 @@ esbuild-register@^2.2.0:
|
|||||||
esbuild "^0.9.2"
|
esbuild "^0.9.2"
|
||||||
jsonc-parser "^3.0.0"
|
jsonc-parser "^3.0.0"
|
||||||
|
|
||||||
esbuild@^0.11.4:
|
esbuild@^0.11.4, esbuild@^0.11.6, esbuild@^0.9.2, esbuild@^0.9.3:
|
||||||
version "0.11.5"
|
|
||||||
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.11.5.tgz#25b18a2ff2fb9580683edce26a48f64c08c2f2df"
|
|
||||||
integrity sha512-aRs6jAE+bVRp1tyfzUugAw1T/Y0Fwzp4Z2ROikF3h+UifoD5QlEbEYQGc6orNnnSIRhWR5VWBH7LozlAumaLHg==
|
|
||||||
|
|
||||||
esbuild@^0.11.6:
|
|
||||||
version "0.11.6"
|
version "0.11.6"
|
||||||
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.11.6.tgz#20961309c4cfed00b71027e18806150358d0cbb0"
|
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.11.6.tgz#20961309c4cfed00b71027e18806150358d0cbb0"
|
||||||
integrity sha512-L+nKW9ftVS/N2CVJMR9YmXHbkm+vHzlNYuo09rzipQhF7dYNvRLfWoEPSDRTl10and4owFBV9rJ2CTFNtLIOiw==
|
integrity sha512-L+nKW9ftVS/N2CVJMR9YmXHbkm+vHzlNYuo09rzipQhF7dYNvRLfWoEPSDRTl10and4owFBV9rJ2CTFNtLIOiw==
|
||||||
|
|
||||||
esbuild@^0.9.2, esbuild@^0.9.3:
|
|
||||||
version "0.9.7"
|
|
||||||
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.9.7.tgz#ea0d639cbe4b88ec25fbed4d6ff00c8d788ef70b"
|
|
||||||
integrity sha512-VtUf6aQ89VTmMLKrWHYG50uByMF4JQlVysb8dmg6cOgW8JnFCipmz7p+HNBl+RR3LLCuBxFGVauAe2wfnF9bLg==
|
|
||||||
|
|
||||||
escalade@^3.1.1:
|
escalade@^3.1.1:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||||
@ -3752,10 +3742,10 @@ eslint-visitor-keys@^2.0.0:
|
|||||||
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
|
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
|
||||||
integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
|
integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
|
||||||
|
|
||||||
eslint@^7.23.0:
|
eslint@^7.24.0:
|
||||||
version "7.23.0"
|
version "7.24.0"
|
||||||
resolved "https://registry.npmjs.org/eslint/-/eslint-7.23.0.tgz#8d029d252f6e8cf45894b4bee08f5493f8e94325"
|
resolved "https://registry.npmjs.org/eslint/-/eslint-7.24.0.tgz#2e44fa62d93892bfdb100521f17345ba54b8513a"
|
||||||
integrity sha512-kqvNVbdkjzpFy0XOszNwjkKzZ+6TcwCQ/h+ozlcIWwaimBBuhlQ4nN6kbiM2L+OjDcznkTJxzYfRFH92sx4a0Q==
|
integrity sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/code-frame" "7.12.11"
|
"@babel/code-frame" "7.12.11"
|
||||||
"@eslint/eslintrc" "^0.4.0"
|
"@eslint/eslintrc" "^0.4.0"
|
||||||
@ -6942,6 +6932,11 @@ pify@^4.0.1:
|
|||||||
resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
|
resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
|
||||||
integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
|
integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
|
||||||
|
|
||||||
|
pinia@^2.0.0-alpha.12:
|
||||||
|
version "2.0.0-alpha.12"
|
||||||
|
resolved "https://registry.npmjs.org/pinia/-/pinia-2.0.0-alpha.12.tgz#690e9a7b4c176bb9d95fe0dc8ec4ab8847b09493"
|
||||||
|
integrity sha512-qmcDpuoAwxQKAVp7/cOkXFYDaja+vyXMWR6kvdyzeJcGGMvZf1HQ2xFhUSW5lf1eW5IiQP0cBRdF3ZDyVa+JIQ==
|
||||||
|
|
||||||
pinkie-promise@^2.0.0:
|
pinkie-promise@^2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
|
resolved "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
|
||||||
@ -7691,10 +7686,10 @@ rollup-plugin-visualizer@5.3.0:
|
|||||||
source-map "^0.7.3"
|
source-map "^0.7.3"
|
||||||
yargs "^16.2.0"
|
yargs "^16.2.0"
|
||||||
|
|
||||||
rollup@^2.25.0, rollup@^2.38.5, rollup@^2.44.0:
|
rollup@^2.25.0, rollup@^2.38.5, rollup@^2.44.0, rollup@^2.45.1:
|
||||||
version "2.44.0"
|
version "2.45.1"
|
||||||
resolved "https://registry.npmjs.org/rollup/-/rollup-2.44.0.tgz#8da324d1c4fd12beef9ae6e12f4068265b6d95eb"
|
resolved "https://registry.npmjs.org/rollup/-/rollup-2.45.1.tgz#eae2b94dc2088b4e0a3b7197a5a1ee0bdd589d5c"
|
||||||
integrity sha512-rGSF4pLwvuaH/x4nAS+zP6UNn5YUDWf/TeEU5IoXSZKBbKRNTCI3qMnYXKZgrC0D2KzS2baiOZt1OlqhMu5rnQ==
|
integrity sha512-vPD+JoDj3CY8k6m1bLcAFttXMe78P4CMxoau0iLVS60+S9kLsv2379xaGy4NgYWu+h2WTlucpoLPAoUoixFBag==
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "~2.3.1"
|
fsevents "~2.3.1"
|
||||||
|
|
||||||
@ -9187,15 +9182,15 @@ vite-plugin-theme@^0.6.3:
|
|||||||
esbuild-plugin-alias "^0.1.2"
|
esbuild-plugin-alias "^0.1.2"
|
||||||
tinycolor2 "^1.4.2"
|
tinycolor2 "^1.4.2"
|
||||||
|
|
||||||
vite-plugin-windicss@0.12.5:
|
vite-plugin-windicss@0.13.1:
|
||||||
version "0.12.5"
|
version "0.13.1"
|
||||||
resolved "https://registry.npmjs.org/vite-plugin-windicss/-/vite-plugin-windicss-0.12.5.tgz#74a5043db3615fe432855f6ecff13be36f7a6843"
|
resolved "https://registry.npmjs.org/vite-plugin-windicss/-/vite-plugin-windicss-0.13.1.tgz#82a488f3395be710ae2166b83b0612a5eaec7738"
|
||||||
integrity sha512-M/eEA+x94kxZNpEEkJLdY7M6Lp3WFhN0Kb/a2zhdPxBviMwaHSA5A7fUqN1xTYMxlQe4xM7D7naxL7EpnSNlmg==
|
integrity sha512-WmFfTLTMSY5gRC3MWX9o72Yni2HRdrtJ2im+cCyZ2W/p4WE6T702zFCScO8Tnz/E08GDx4OH6oFCZWeZYwgxzg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@windicss/plugin-utils" "0.12.5"
|
"@windicss/plugin-utils" "0.13.1"
|
||||||
chalk "^4.1.0"
|
chalk "^4.1.0"
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
windicss "^2.5.11"
|
windicss "^2.5.12"
|
||||||
|
|
||||||
vite@2.1.5:
|
vite@2.1.5:
|
||||||
version "2.1.5"
|
version "2.1.5"
|
||||||
@ -9265,16 +9260,6 @@ vue@^3.0.0:
|
|||||||
"@vue/runtime-dom" "3.0.10"
|
"@vue/runtime-dom" "3.0.10"
|
||||||
"@vue/shared" "3.0.10"
|
"@vue/shared" "3.0.10"
|
||||||
|
|
||||||
vuex-module-decorators@^1.0.1:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.npmjs.org/vuex-module-decorators/-/vuex-module-decorators-1.0.1.tgz#d34dafb5428a3636f1c26d3d014c15fc9659ccd0"
|
|
||||||
integrity sha512-FLWZsXV5XAtl/bcKUyQFpnSBtpc3wK/7zSdy9oKbyp71mZd4ut5y2zSd219wWW9OG7WUOlVwac4rXFFDVnq7ug==
|
|
||||||
|
|
||||||
vuex@^4.0.0:
|
|
||||||
version "4.0.0"
|
|
||||||
resolved "https://registry.npmjs.org/vuex/-/vuex-4.0.0.tgz#ac877aa76a9c45368c979471e461b520d38e6cf5"
|
|
||||||
integrity sha512-56VPujlHscP5q/e7Jlpqc40sja4vOhC4uJD1llBCWolVI8ND4+VzisDVkUMl+z5y0MpIImW6HjhNc+ZvuizgOw==
|
|
||||||
|
|
||||||
warning@^4.0.0:
|
warning@^4.0.0:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
|
resolved "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
|
||||||
@ -9326,10 +9311,10 @@ which@^2.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
isexe "^2.0.0"
|
isexe "^2.0.0"
|
||||||
|
|
||||||
windicss@^2.5.11:
|
windicss@^2.5.12:
|
||||||
version "2.5.11"
|
version "2.5.12"
|
||||||
resolved "https://registry.npmjs.org/windicss/-/windicss-2.5.11.tgz#dd4027c724c7b12a37746d1474b96a52239157d1"
|
resolved "https://registry.npmjs.org/windicss/-/windicss-2.5.12.tgz#7bc469b05d7a8fa3905d49d6521a1ff9107d0ea4"
|
||||||
integrity sha512-u7b4rOPb8MwO1glkf0gdDygZ+lIzXb/PYLNjqni5Fe2684DCEt6dWTKdk3iMxXgbKoqRNncKu7xt3pFwXHdSAw==
|
integrity sha512-BZ0Ps1C0RlCHBVOPcw/DAReeR9o/mKaoFgkBsVphQ23M5nsvVfVXgGlNJZssjAQsXnlDpj97pnIhtDn1ENBjXw==
|
||||||
|
|
||||||
wmf@~1.0.1:
|
wmf@~1.0.1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
|
Loading…
Reference in New Issue
Block a user