mirror of
https://github.com/jekip/naive-ui-admin.git
synced 2026-02-04 13:42:27 +08:00
refactor: remove unused files, bug fixes and name changes
This commit is contained in:
18
src/App.vue
18
src/App.vue
@@ -21,16 +21,16 @@
|
||||
import { zhCN, dateZhCN, darkTheme } from 'naive-ui';
|
||||
import { LockScreen } from '@/components/Lockscreen';
|
||||
import { AppProvider } from '@/components/Application';
|
||||
import { useLockscreenStore } from '@/store/modules/lockscreen';
|
||||
import { useScreenLockStore } from '@/store/modules/screenLock.js';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useDesignSettingStore } from '@/store/modules/designSetting';
|
||||
import { lighten } from '@/utils/index';
|
||||
|
||||
const route = useRoute();
|
||||
const useLockscreen = useLockscreenStore();
|
||||
const useScreenLock = useScreenLockStore();
|
||||
const designStore = useDesignSettingStore();
|
||||
const isLock = computed(() => useLockscreen.isLock);
|
||||
const lockTime = computed(() => useLockscreen.lockTime);
|
||||
const isLock = computed(() => useScreenLock.isLocked);
|
||||
const lockTime = computed(() => useScreenLock.lockTime);
|
||||
|
||||
/**
|
||||
* @type import('naive-ui').GlobalThemeOverrides
|
||||
@@ -53,21 +53,21 @@
|
||||
|
||||
const getDarkTheme = computed(() => (designStore.darkTheme ? darkTheme : undefined));
|
||||
|
||||
let timer;
|
||||
let timer: NodeJS.Timer;
|
||||
|
||||
const timekeeping = () => {
|
||||
clearInterval(timer);
|
||||
if (route.name == 'login' || isLock.value) return;
|
||||
// 设置不锁屏
|
||||
useLockscreen.setLock(false);
|
||||
useScreenLock.setLock(false);
|
||||
// 重置锁屏时间
|
||||
useLockscreen.setLockTime();
|
||||
useScreenLock.setLockTime();
|
||||
timer = setInterval(() => {
|
||||
// 锁屏倒计时递减
|
||||
useLockscreen.setLockTime(lockTime.value - 1);
|
||||
useScreenLock.setLockTime(lockTime.value - 1);
|
||||
if (lockTime.value <= 0) {
|
||||
// 设置锁屏
|
||||
useLockscreen.setLock(true);
|
||||
useScreenLock.setLock(true);
|
||||
return clearInterval(timer);
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
@@ -60,11 +60,11 @@
|
||||
</template>
|
||||
</n-input>
|
||||
|
||||
<div class="w-full flex" v-if="isLoginError">
|
||||
<div class="flex w-full" v-if="isLoginError">
|
||||
<span class="text-red-500">{{ errorMsg }}</span>
|
||||
</div>
|
||||
|
||||
<div class="w-full mt-1 flex justify-around">
|
||||
<div class="flex justify-around w-full mt-1">
|
||||
<div><a @click="showLogin = false">返回</a></div>
|
||||
<div><a @click="goLogin">重新登录</a></div>
|
||||
<div><a @click="onLogin">进入系统</a></div>
|
||||
@@ -91,11 +91,11 @@
|
||||
import { useOnline } from '@/hooks/useOnline';
|
||||
import { useTime } from '@/hooks/useTime';
|
||||
import { useBattery } from '@/hooks/useBattery';
|
||||
import { useLockscreenStore } from '@/store/modules/lockscreen';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { useScreenLockStore } from '@/store/modules/screenLock';
|
||||
import { UserInfoType, useUserStore } from '@/store/modules/user';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Lockscreen',
|
||||
name: 'ScreenLock',
|
||||
components: {
|
||||
LockOutlined,
|
||||
LoadingOutlined,
|
||||
@@ -106,7 +106,7 @@
|
||||
recharge,
|
||||
},
|
||||
setup() {
|
||||
const useLockscreen = useLockscreenStore();
|
||||
const useScreenLock = useScreenLockStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
// 获取时间
|
||||
@@ -117,7 +117,7 @@
|
||||
const route = useRoute();
|
||||
|
||||
const { battery, batteryStatus, calcDischargingTime, calcChargingTime } = useBattery();
|
||||
const userInfo: object = userStore.getUserInfo || {};
|
||||
const userInfo: UserInfoType = userStore.getUserInfo || {};
|
||||
const username = userInfo['username'] || '';
|
||||
const state = reactive({
|
||||
showLogin: false,
|
||||
@@ -146,7 +146,7 @@
|
||||
const { code, message } = await userStore.login(params);
|
||||
if (code === ResultEnum.SUCCESS) {
|
||||
onLockLogin(false);
|
||||
useLockscreen.setLock(false);
|
||||
useScreenLock.setLock(false);
|
||||
} else {
|
||||
state.errorMsg = message;
|
||||
state.isLoginError = true;
|
||||
@@ -157,7 +157,7 @@
|
||||
//重新登录
|
||||
const goLogin = () => {
|
||||
onLockLogin(false);
|
||||
useLockscreen.setLock(false);
|
||||
useScreenLock.setLock(false);
|
||||
router.replace({
|
||||
path: '/login',
|
||||
query: {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import { useAsync } from './use-async';
|
||||
import { useAsync } from './useAsync';
|
||||
|
||||
export { useAsync };
|
||||
|
||||
@@ -4,39 +4,39 @@ import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
||||
export function useProjectSetting() {
|
||||
const projectStore = useProjectSettingStore();
|
||||
|
||||
const getNavMode = computed(() => projectStore.navMode);
|
||||
const navMode = computed(() => projectStore.navMode);
|
||||
|
||||
const getNavTheme = computed(() => projectStore.navTheme);
|
||||
const navTheme = computed(() => projectStore.navTheme);
|
||||
|
||||
const getIsMobile = computed(() => projectStore.isMobile);
|
||||
const isMobile = computed(() => projectStore.isMobile);
|
||||
|
||||
const getHeaderSetting = computed(() => projectStore.headerSetting);
|
||||
const headerSetting = computed(() => projectStore.headerSetting);
|
||||
|
||||
const getMultiTabsSetting = computed(() => projectStore.multiTabsSetting);
|
||||
const multiTabsSetting = computed(() => projectStore.multiTabsSetting);
|
||||
|
||||
const getMenuSetting = computed(() => projectStore.menuSetting);
|
||||
const menuSetting = computed(() => projectStore.menuSetting);
|
||||
|
||||
const getCrumbsSetting = computed(() => projectStore.crumbsSetting);
|
||||
const crumbsSetting = computed(() => projectStore.crumbsSetting);
|
||||
|
||||
const getPermissionMode = computed(() => projectStore.permissionMode);
|
||||
const permissionMode = computed(() => projectStore.permissionMode);
|
||||
|
||||
const getShowFooter = computed(() => projectStore.showFooter);
|
||||
const showFooter = computed(() => projectStore.showFooter);
|
||||
|
||||
const getIsPageAnimate = computed(() => projectStore.isPageAnimate);
|
||||
const isPageAnimate = computed(() => projectStore.isPageAnimate);
|
||||
|
||||
const getPageAnimateType = computed(() => projectStore.pageAnimateType);
|
||||
const pageAnimateType = computed(() => projectStore.pageAnimateType);
|
||||
|
||||
return {
|
||||
getNavMode,
|
||||
getNavTheme,
|
||||
getIsMobile,
|
||||
getHeaderSetting,
|
||||
getMultiTabsSetting,
|
||||
getMenuSetting,
|
||||
getCrumbsSetting,
|
||||
getPermissionMode,
|
||||
getShowFooter,
|
||||
getIsPageAnimate,
|
||||
getPageAnimateType,
|
||||
navMode,
|
||||
navTheme,
|
||||
isMobile,
|
||||
headerSetting,
|
||||
multiTabsSetting,
|
||||
menuSetting,
|
||||
crumbsSetting,
|
||||
permissionMode,
|
||||
showFooter,
|
||||
isPageAnimate,
|
||||
pageAnimateType,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ export function useECharts(
|
||||
return chartInstance;
|
||||
}
|
||||
|
||||
function disposeInstance(){
|
||||
function disposeInstance() {
|
||||
if (!chartInstance) return;
|
||||
removeResizeFn();
|
||||
chartInstance.dispose();
|
||||
@@ -118,6 +118,6 @@ export function useECharts(
|
||||
resize,
|
||||
echarts,
|
||||
getInstance,
|
||||
disposeInstance
|
||||
disposeInstance,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
<div
|
||||
class="layout-header-trigger layout-header-trigger-min"
|
||||
v-for="item in iconList"
|
||||
:key="item.icon.name"
|
||||
:key="item.icon"
|
||||
>
|
||||
<n-tooltip placement="bottom">
|
||||
<template #trigger>
|
||||
@@ -134,7 +134,7 @@
|
||||
import { NDialogProvider, useDialog, useMessage } from 'naive-ui';
|
||||
import { TABS_ROUTES } from '@/store/mutation-types';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { useLockscreenStore } from '@/store/modules/lockscreen';
|
||||
import { useScreenLockStore } from '@/store/modules/screenLock';
|
||||
import ProjectSetting from './ProjectSetting.vue';
|
||||
import { AsideMenu } from '@/layout/components/Menu';
|
||||
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
||||
@@ -153,37 +153,37 @@
|
||||
},
|
||||
setup(props) {
|
||||
const userStore = useUserStore();
|
||||
const useLockscreen = useLockscreenStore();
|
||||
const useLockscreen = useScreenLockStore();
|
||||
const message = useMessage();
|
||||
const dialog = useDialog();
|
||||
const { getNavMode, getNavTheme, getHeaderSetting, getMenuSetting, getCrumbsSetting } =
|
||||
useProjectSetting();
|
||||
const { navMode, navTheme, headerSetting, menuSetting, crumbsSetting } = useProjectSetting();
|
||||
|
||||
const { username } = userStore?.info || {};
|
||||
const { name } = userStore?.info || {};
|
||||
|
||||
const drawerSetting = ref();
|
||||
|
||||
const state = reactive({
|
||||
username: username || '',
|
||||
username: name ?? '',
|
||||
fullscreenIcon: 'FullscreenOutlined',
|
||||
navMode: getNavMode,
|
||||
navTheme: getNavTheme,
|
||||
headerSetting: getHeaderSetting,
|
||||
crumbsSetting: getCrumbsSetting,
|
||||
navMode,
|
||||
navTheme,
|
||||
headerSetting,
|
||||
crumbsSetting,
|
||||
});
|
||||
|
||||
const getInverted = computed(() => {
|
||||
const navTheme = unref(getNavTheme);
|
||||
return ['light', 'header-dark'].includes(navTheme) ? props.inverted : !props.inverted;
|
||||
return ['light', 'header-dark'].includes(unref(navTheme))
|
||||
? props.inverted
|
||||
: !props.inverted;
|
||||
});
|
||||
|
||||
const mixMenu = computed(() => {
|
||||
return unref(getMenuSetting).mixMenu;
|
||||
return unref(menuSetting).mixMenu;
|
||||
});
|
||||
|
||||
const getChangeStyle = computed(() => {
|
||||
const { collapsed } = props;
|
||||
const { minMenuWidth, menuWidth }: any = unref(getMenuSetting);
|
||||
const { minMenuWidth, menuWidth } = unref(menuSetting);
|
||||
return {
|
||||
left: collapsed ? `${minMenuWidth}px` : `${menuWidth}px`,
|
||||
width: `calc(100% - ${collapsed ? `${minMenuWidth}px` : `${menuWidth}px`})`,
|
||||
|
||||
@@ -30,13 +30,13 @@
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const { getIsPageAnimate, getPageAnimateType } = useProjectSetting();
|
||||
const { isPageAnimate, pageAnimateType } = useProjectSetting();
|
||||
const asyncRouteStore = useAsyncRouteStore();
|
||||
// 需要缓存的路由组件
|
||||
const keepAliveComponents = computed(() => asyncRouteStore.keepAliveComponents);
|
||||
|
||||
const getTransitionName = computed(() => {
|
||||
return unref(getIsPageAnimate) ? unref(getPageAnimateType) : '';
|
||||
return unref(isPageAnimate) ? unref(pageAnimateType) : '';
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Menu',
|
||||
name: 'AppMenu',
|
||||
components: {},
|
||||
props: {
|
||||
mode: {
|
||||
@@ -52,9 +52,7 @@
|
||||
const selectedKeys = ref<string>(currentRoute.name as string);
|
||||
const headerMenuSelectKey = ref<string>('');
|
||||
|
||||
const { getNavMode } = useProjectSetting();
|
||||
|
||||
const navMode = getNavMode;
|
||||
const { navMode } = useProjectSetting();
|
||||
|
||||
// 获取当前打开的子菜单
|
||||
const matched = currentRoute.matched;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="tabs-view box-border"
|
||||
class="box-border tabs-view"
|
||||
:class="{
|
||||
'tabs-view-fix': multiTabsSetting.fixed,
|
||||
'tabs-view-fixed-header': isMultiHeaderFixed,
|
||||
@@ -82,7 +82,6 @@
|
||||
computed,
|
||||
ref,
|
||||
toRefs,
|
||||
unref,
|
||||
provide,
|
||||
watch,
|
||||
onMounted,
|
||||
@@ -130,7 +129,7 @@
|
||||
},
|
||||
setup(props) {
|
||||
const { getDarkTheme, getAppTheme } = useDesignSetting();
|
||||
const { getNavMode, getHeaderSetting, getMenuSetting, getMultiTabsSetting, getIsMobile } =
|
||||
const { navMode, headerSetting, menuSetting, multiTabsSetting, isMobile } =
|
||||
useProjectSetting();
|
||||
const settingStore = useProjectSettingStore();
|
||||
|
||||
@@ -161,7 +160,7 @@
|
||||
dropdownY: 0,
|
||||
showDropdown: false,
|
||||
isMultiHeaderFixed: false,
|
||||
multiTabsSetting: getMultiTabsSetting,
|
||||
multiTabsSetting: multiTabsSetting,
|
||||
});
|
||||
|
||||
// 获取简易的路由对象
|
||||
@@ -173,25 +172,23 @@
|
||||
const isMixMenuNoneSub = computed(() => {
|
||||
const mixMenu = settingStore.menuSetting.mixMenu;
|
||||
const currentRoute = useRoute();
|
||||
const navMode = unref(getNavMode);
|
||||
if (unref(navMode) != 'horizontal-mix') return true;
|
||||
return !(unref(navMode) === 'horizontal-mix' && mixMenu && currentRoute.meta.isRoot);
|
||||
if (navMode.value != 'horizontal-mix') return true;
|
||||
return !(navMode.value === 'horizontal-mix' && mixMenu && currentRoute.meta.isRoot);
|
||||
});
|
||||
|
||||
//动态组装样式 菜单缩进
|
||||
const getChangeStyle = computed(() => {
|
||||
const { collapsed } = props;
|
||||
const navMode = unref(getNavMode);
|
||||
const { minMenuWidth, menuWidth }: any = unref(getMenuSetting);
|
||||
const { fixed }: any = unref(getMultiTabsSetting);
|
||||
const { minMenuWidth, menuWidth }: any = menuSetting.value;
|
||||
const { fixed }: any = multiTabsSetting.value;
|
||||
let lenNum =
|
||||
navMode === 'horizontal' || !isMixMenuNoneSub.value
|
||||
navMode.value === 'horizontal' || !isMixMenuNoneSub.value
|
||||
? '0px'
|
||||
: collapsed
|
||||
? `${minMenuWidth}px`
|
||||
: `${menuWidth}px`;
|
||||
|
||||
if (getIsMobile.value) {
|
||||
if (isMobile.value) {
|
||||
return {
|
||||
left: '0px',
|
||||
width: '100%',
|
||||
@@ -205,7 +202,7 @@
|
||||
|
||||
//tags 右侧下拉菜单
|
||||
const TabsMenuOptions = computed(() => {
|
||||
const isDisabled = unref(tabsList).length <= 1;
|
||||
const isDisabled = tabsList.value.length <= 1;
|
||||
return [
|
||||
{
|
||||
label: '刷新当前',
|
||||
@@ -215,7 +212,7 @@
|
||||
{
|
||||
label: `关闭当前`,
|
||||
key: '2',
|
||||
disabled: unref(isCurrent) || isDisabled,
|
||||
disabled: isCurrent.value || isDisabled,
|
||||
icon: renderIcon(CloseOutlined),
|
||||
},
|
||||
{
|
||||
@@ -263,8 +260,8 @@
|
||||
window.pageYOffset ||
|
||||
document.body.scrollTop; // 滚动条偏移量
|
||||
state.isMultiHeaderFixed = !!(
|
||||
!getHeaderSetting.value.fixed &&
|
||||
getMultiTabsSetting.value.fixed &&
|
||||
!headerSetting.value.fixed &&
|
||||
multiTabsSetting.value.fixed &&
|
||||
scrollTop >= 64
|
||||
);
|
||||
}
|
||||
@@ -297,7 +294,7 @@
|
||||
(to) => {
|
||||
if (whiteList.includes(route.name as string)) return;
|
||||
state.activeKey = to;
|
||||
tabsViewStore.addTabs(getSimpleRoute(route));
|
||||
tabsViewStore.addTab(getSimpleRoute(route));
|
||||
updateNavScroll(true);
|
||||
},
|
||||
{ immediate: true }
|
||||
@@ -328,7 +325,7 @@
|
||||
const reloadPage = () => {
|
||||
delKeepAliveCompName();
|
||||
router.push({
|
||||
path: '/redirect' + unref(route).fullPath,
|
||||
path: '/redirect' + route.fullPath,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</n-layout-sider>
|
||||
|
||||
<n-drawer
|
||||
v-model:show="showSideDrawder"
|
||||
v-model:show="showSideDrawer"
|
||||
:width="menuWidth"
|
||||
:placement="'left'"
|
||||
class="layout-side-drawer"
|
||||
@@ -82,21 +82,19 @@
|
||||
|
||||
const { getDarkTheme } = useDesignSetting();
|
||||
const {
|
||||
// getShowFooter,
|
||||
getNavMode,
|
||||
getNavTheme,
|
||||
getHeaderSetting,
|
||||
getMenuSetting,
|
||||
getMultiTabsSetting,
|
||||
// showFooter,
|
||||
navMode,
|
||||
navTheme,
|
||||
headerSetting,
|
||||
menuSetting,
|
||||
multiTabsSetting,
|
||||
} = useProjectSetting();
|
||||
|
||||
const settingStore = useProjectSettingStore();
|
||||
|
||||
const navMode = getNavMode;
|
||||
|
||||
const collapsed = ref<boolean>(false);
|
||||
|
||||
const { mobileWidth, menuWidth } = unref(getMenuSetting);
|
||||
const { mobileWidth, menuWidth } = unref(menuSetting);
|
||||
|
||||
const isMobile = computed<boolean>({
|
||||
get: () => settingStore.getIsMobile,
|
||||
@@ -104,12 +102,12 @@
|
||||
});
|
||||
|
||||
const fixedHeader = computed(() => {
|
||||
const { fixed } = unref(getHeaderSetting);
|
||||
const { fixed } = unref(headerSetting);
|
||||
return fixed ? 'absolute' : 'static';
|
||||
});
|
||||
|
||||
const isMixMenuNoneSub = computed(() => {
|
||||
const mixMenu = settingStore.menuSetting.mixMenu;
|
||||
const mixMenu = unref(menuSetting).mixMenu;
|
||||
const currentRoute = useRoute();
|
||||
if (unref(navMode) != 'horizontal-mix') return true;
|
||||
if (unref(navMode) === 'horizontal-mix' && mixMenu && currentRoute.meta.isRoot) {
|
||||
@@ -119,45 +117,37 @@
|
||||
});
|
||||
|
||||
const fixedMenu = computed(() => {
|
||||
const { fixed } = unref(getHeaderSetting);
|
||||
const { fixed } = unref(headerSetting);
|
||||
return fixed ? 'absolute' : 'static';
|
||||
});
|
||||
|
||||
const isMultiTabs = computed(() => {
|
||||
return unref(getMultiTabsSetting).show;
|
||||
return unref(multiTabsSetting).show;
|
||||
});
|
||||
|
||||
const fixedMulti = computed(() => {
|
||||
return unref(getMultiTabsSetting).fixed;
|
||||
return unref(multiTabsSetting).fixed;
|
||||
});
|
||||
|
||||
const inverted = computed(() => {
|
||||
return ['dark', 'header-dark'].includes(unref(getNavTheme));
|
||||
return ['dark', 'header-dark'].includes(unref(navTheme));
|
||||
});
|
||||
|
||||
const getHeaderInverted = computed(() => {
|
||||
const navTheme = unref(getNavTheme);
|
||||
return ['light', 'header-dark'].includes(navTheme) ? unref(inverted) : !unref(inverted);
|
||||
return ['light', 'header-dark'].includes(unref(navTheme)) ? unref(inverted) : !unref(inverted);
|
||||
});
|
||||
|
||||
const leftMenuWidth = computed(() => {
|
||||
const { minMenuWidth, menuWidth } = unref(getMenuSetting);
|
||||
const { minMenuWidth, menuWidth } = unref(menuSetting);
|
||||
return collapsed.value ? minMenuWidth : menuWidth;
|
||||
});
|
||||
|
||||
// const getChangeStyle = computed(() => {
|
||||
// const { minMenuWidth, menuWidth } = unref(getMenuSetting);
|
||||
// return {
|
||||
// 'padding-left': collapsed.value ? `${minMenuWidth}px` : `${menuWidth}px`,
|
||||
// };
|
||||
// });
|
||||
|
||||
const getMenuLocation = computed(() => {
|
||||
return 'left';
|
||||
});
|
||||
|
||||
// 控制显示或隐藏移动端侧边栏
|
||||
const showSideDrawder = computed({
|
||||
const showSideDrawer = computed({
|
||||
get: () => isMobile.value && collapsed.value,
|
||||
set: (val) => (collapsed.value = val),
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as NaiveUI from 'naive-ui';
|
||||
import { computed } from 'vue';
|
||||
import { useDesignSettingWithOut } from '@/store/modules/designSetting';
|
||||
import { useDesignSetting } from '@/store/modules/designSetting';
|
||||
import { lighten } from '@/utils/index';
|
||||
|
||||
/**
|
||||
@@ -10,7 +10,7 @@ import { lighten } from '@/utils/index';
|
||||
*/
|
||||
|
||||
export function setupNaiveDiscreteApi() {
|
||||
const designStore = useDesignSettingWithOut();
|
||||
const designStore = useDesignSetting();
|
||||
|
||||
const configProviderPropsRef = computed(() => ({
|
||||
theme: designStore.darkTheme ? NaiveUI.darkTheme : undefined,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { AppRouteRecordRaw } from '@/router/types';
|
||||
import { ErrorPage, RedirectName, Layout } from '@/router/constant';
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
// 404 on a page
|
||||
export const ErrorPageRoute: AppRouteRecordRaw = {
|
||||
export const ErrorPageRoute: RouteRecordRaw = {
|
||||
path: '/:path(.*)*',
|
||||
name: 'ErrorPage',
|
||||
component: Layout,
|
||||
@@ -23,7 +23,7 @@ export const ErrorPageRoute: AppRouteRecordRaw = {
|
||||
],
|
||||
};
|
||||
|
||||
export const RedirectRoute: AppRouteRecordRaw = {
|
||||
export const RedirectRoute: RouteRecordRaw = {
|
||||
path: '/redirect',
|
||||
name: RedirectName,
|
||||
component: Layout,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { adminMenus } from '@/api/system/menu';
|
||||
import { constantRouterIcon } from './router-icons';
|
||||
import { constantRouterIcon } from './icons';
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
import { Layout, ParentLayout } from '@/router/constant';
|
||||
import type { AppRouteRecordRaw } from '@/router/types';
|
||||
@@ -16,13 +16,13 @@ LayoutMap.set('IFRAME', Iframe);
|
||||
* @param parent
|
||||
* @returns {*}
|
||||
*/
|
||||
export const routerGenerator = (routerMap, parent?): any[] => {
|
||||
export const generateRoutes = (routerMap, parent?): any[] => {
|
||||
return routerMap.map((item) => {
|
||||
const currentRouter: any = {
|
||||
const currentRoute: any = {
|
||||
// 路由地址 动态拼接生成如 /dashboard/workplace
|
||||
path: `${(parent && parent.path) || ''}/${item.path}`,
|
||||
path: `${(parent && parent.path) ?? ''}/${item.path}`,
|
||||
// 路由名称,建议唯一
|
||||
name: item.name || '',
|
||||
name: item.name ?? '',
|
||||
// 该路由对应页面的 组件
|
||||
component: item.component,
|
||||
// meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉)
|
||||
@@ -35,17 +35,17 @@ export const routerGenerator = (routerMap, parent?): any[] => {
|
||||
};
|
||||
|
||||
// 为了防止出现后端返回结果不规范,处理有可能出现拼接出两个 反斜杠
|
||||
currentRouter.path = currentRouter.path.replace('//', '/');
|
||||
currentRoute.path = currentRoute.path.replace('//', '/');
|
||||
// 重定向
|
||||
item.redirect && (currentRouter.redirect = item.redirect);
|
||||
item.redirect && (currentRoute.redirect = item.redirect);
|
||||
// 是否有子菜单,并递归处理
|
||||
if (item.children && item.children.length > 0) {
|
||||
//如果未定义 redirect 默认第一个子路由为 redirect
|
||||
!item.redirect && (currentRouter.redirect = `${item.path}/${item.children[0].path}`);
|
||||
!item.redirect && (currentRoute.redirect = `${item.path}/${item.children[0].path}`);
|
||||
// Recursion
|
||||
currentRouter.children = routerGenerator(item.children, currentRouter);
|
||||
currentRoute.children = generateRoutes(item.children, currentRoute);
|
||||
}
|
||||
return currentRouter;
|
||||
return currentRoute;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -53,19 +53,11 @@ export const routerGenerator = (routerMap, parent?): any[] => {
|
||||
* 动态生成菜单
|
||||
* @returns {Promise<Router>}
|
||||
*/
|
||||
export const generatorDynamicRouter = (): Promise<RouteRecordRaw[]> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
adminMenus()
|
||||
.then((result) => {
|
||||
const routeList = routerGenerator(result);
|
||||
asyncImportRoute(routeList);
|
||||
|
||||
resolve(routeList);
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
export const generateDynamicRoutes = async (): Promise<RouteRecordRaw[]> => {
|
||||
const result = await adminMenus();
|
||||
const router = generateRoutes(result);
|
||||
asyncImportRoute(router);
|
||||
return router;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
import { isNavigationFailure, Router } from 'vue-router';
|
||||
import { useUserStoreWidthOut } from '@/store/modules/user';
|
||||
import { useAsyncRouteStoreWidthOut } from '@/store/modules/asyncRoute';
|
||||
import { useUser } from '@/store/modules/user';
|
||||
import { useAsyncRoute } from '@/store/modules/asyncRoute';
|
||||
import { ACCESS_TOKEN } from '@/store/mutation-types';
|
||||
import { storage } from '@/utils/Storage';
|
||||
import { PageEnum } from '@/enums/pageEnum';
|
||||
@@ -12,8 +12,8 @@ const LOGIN_PATH = PageEnum.BASE_LOGIN;
|
||||
const whitePathList = [LOGIN_PATH]; // no redirect whitelist
|
||||
|
||||
export function createRouterGuards(router: Router) {
|
||||
const userStore = useUserStoreWidthOut();
|
||||
const asyncRouteStore = useAsyncRouteStoreWidthOut();
|
||||
const userStore = useUser();
|
||||
const asyncRouteStore = useAsyncRoute();
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
const Loading = window['$loading'] || null;
|
||||
Loading && Loading.start();
|
||||
@@ -51,12 +51,12 @@ export function createRouterGuards(router: Router) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (asyncRouteStore.getIsDynamicAddedRoute) {
|
||||
if (asyncRouteStore.getIsDynamicRouteAdded) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
const userInfo = await userStore.GetInfo();
|
||||
const userInfo = await userStore.getInfo();
|
||||
|
||||
const routes = await asyncRouteStore.generateRoutes(userInfo);
|
||||
|
||||
@@ -74,7 +74,7 @@ export function createRouterGuards(router: Router) {
|
||||
const redirectPath = (from.query.redirect || to.path) as string;
|
||||
const redirect = decodeURIComponent(redirectPath);
|
||||
const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect };
|
||||
asyncRouteStore.setDynamicAddedRoute(true);
|
||||
asyncRouteStore.setDynamicRouteAdded(true);
|
||||
next(nextData);
|
||||
Loading && Loading.finish();
|
||||
});
|
||||
@@ -84,7 +84,7 @@ export function createRouterGuards(router: Router) {
|
||||
if (isNavigationFailure(failure)) {
|
||||
//console.log('failed navigation', failure)
|
||||
}
|
||||
const asyncRouteStore = useAsyncRouteStoreWidthOut();
|
||||
const asyncRouteStore = useAsyncRoute();
|
||||
// 在这里设置需要缓存的组件名称
|
||||
const keepAliveComponents = asyncRouteStore.keepAliveComponents;
|
||||
const currentComName: any = to.matched.find((item) => item.name == to.name)?.name;
|
||||
@@ -1,22 +1,20 @@
|
||||
import { App } from 'vue';
|
||||
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
|
||||
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
|
||||
import { RedirectRoute } from '@/router/base';
|
||||
import { PageEnum } from '@/enums/pageEnum';
|
||||
import { createRouterGuards } from './router-guards';
|
||||
import { createRouterGuards } from './guards';
|
||||
import type { IModuleType } from './types';
|
||||
|
||||
const modules = import.meta.glob<IModuleType>('./modules/**/*.ts', { eager: true });
|
||||
|
||||
const routeModuleList: RouteRecordRaw[] = [];
|
||||
|
||||
Object.keys(modules).forEach((key) => {
|
||||
const mod = modules[key].default || {};
|
||||
const routeModuleList: RouteRecordRaw[] = Object.keys(modules).reduce((list, key) => {
|
||||
const mod = modules[key].default ?? {};
|
||||
const modList = Array.isArray(mod) ? [...mod] : [mod];
|
||||
routeModuleList.push(...modList);
|
||||
});
|
||||
return [...list, ...modList];
|
||||
}, []);
|
||||
|
||||
function sortRoute(a, b) {
|
||||
return (a.meta?.sort || 0) - (b.meta?.sort || 0);
|
||||
return (a.meta?.sort ?? 0) - (b.meta?.sort ?? 0);
|
||||
}
|
||||
|
||||
routeModuleList.sort(sortRoute);
|
||||
@@ -43,10 +41,10 @@ export const LoginRoute: RouteRecordRaw = {
|
||||
export const asyncRoutes = [...routeModuleList];
|
||||
|
||||
//普通路由 无需验证权限
|
||||
export const constantRouter: any[] = [LoginRoute, RootRoute, RedirectRoute];
|
||||
export const constantRouter: RouteRecordRaw[] = [LoginRoute, RootRoute, RedirectRoute];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(''),
|
||||
history: createWebHistory(),
|
||||
routes: constantRouter,
|
||||
strict: true,
|
||||
scrollBehavior: () => ({ left: 0, top: 0 }),
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import type { RouteRecordRaw, RouteMeta } from 'vue-router';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export type Component<T extends any = any> =
|
||||
export type Component<T = any> =
|
||||
| ReturnType<typeof defineComponent>
|
||||
| (() => Promise<typeof import('*.vue')>)
|
||||
| (() => Promise<T>);
|
||||
|
||||
export interface AppRouteRecordRaw extends Omit<RouteRecordRaw, 'meta'> {
|
||||
export interface AppRouteRecordRaw extends Omit<RouteRecordRaw, 'meta' | 'children'> {
|
||||
name: string;
|
||||
meta: RouteMeta;
|
||||
component?: Component | string;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { defineStore } from 'pinia';
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
import { store } from '@/store';
|
||||
import { asyncRoutes, constantRouter } from '@/router/index';
|
||||
import { generatorDynamicRouter } from '@/router/generator-routers';
|
||||
import { generateDynamicRoutes } from '@/router/generator';
|
||||
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
||||
|
||||
interface TreeHelperConfig {
|
||||
@@ -23,9 +23,9 @@ const getConfig = (config: Partial<TreeHelperConfig>) => Object.assign({}, DEFAU
|
||||
export interface IAsyncRouteState {
|
||||
menus: RouteRecordRaw[];
|
||||
routers: any[];
|
||||
addRouters: any[];
|
||||
routersAdded: any[];
|
||||
keepAliveComponents: string[];
|
||||
isDynamicAddedRoute: boolean;
|
||||
isDynamicRouteAdded: boolean;
|
||||
}
|
||||
|
||||
function filter<T = any>(
|
||||
@@ -53,54 +53,53 @@ export const useAsyncRouteStore = defineStore({
|
||||
state: (): IAsyncRouteState => ({
|
||||
menus: [],
|
||||
routers: constantRouter,
|
||||
addRouters: [],
|
||||
routersAdded: [],
|
||||
keepAliveComponents: [],
|
||||
// Whether the route has been dynamically added
|
||||
isDynamicAddedRoute: false,
|
||||
isDynamicRouteAdded: false,
|
||||
}),
|
||||
getters: {
|
||||
getMenus(): RouteRecordRaw[] {
|
||||
return this.menus;
|
||||
},
|
||||
getIsDynamicAddedRoute(): boolean {
|
||||
return this.isDynamicAddedRoute;
|
||||
getIsDynamicRouteAdded(): boolean {
|
||||
return this.isDynamicRouteAdded;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
getRouters() {
|
||||
return toRaw(this.addRouters);
|
||||
return toRaw(this.routersAdded);
|
||||
},
|
||||
setDynamicAddedRoute(added: boolean) {
|
||||
this.isDynamicAddedRoute = added;
|
||||
setDynamicRouteAdded(added: boolean) {
|
||||
this.isDynamicRouteAdded = added;
|
||||
},
|
||||
// 设置动态路由
|
||||
setRouters(routers) {
|
||||
this.addRouters = routers;
|
||||
setRouters(routers: RouteRecordRaw[]) {
|
||||
this.routersAdded = routers;
|
||||
this.routers = constantRouter.concat(routers);
|
||||
},
|
||||
setMenus(menus) {
|
||||
setMenus(menus: RouteRecordRaw[]) {
|
||||
// 设置动态路由
|
||||
this.menus = menus;
|
||||
},
|
||||
setKeepAliveComponents(compNames) {
|
||||
setKeepAliveComponents(compNames: string[]) {
|
||||
// 设置需要缓存的组件
|
||||
this.keepAliveComponents = compNames;
|
||||
},
|
||||
async generateRoutes(data) {
|
||||
let accessedRouters;
|
||||
const permissionsList = data.permissions || [];
|
||||
const permissionsList = data.permissions ?? [];
|
||||
const routeFilter = (route) => {
|
||||
const { meta } = route;
|
||||
const { permissions } = meta || {};
|
||||
if (!permissions) return true;
|
||||
return permissionsList.some((item) => permissions.includes(item.value));
|
||||
};
|
||||
const { getPermissionMode } = useProjectSetting();
|
||||
const permissionMode = unref(getPermissionMode);
|
||||
if (permissionMode === 'BACK') {
|
||||
const { permissionMode } = useProjectSetting();
|
||||
if (unref(permissionMode) === 'BACK') {
|
||||
// 动态获取菜单
|
||||
try {
|
||||
accessedRouters = await generatorDynamicRouter();
|
||||
accessedRouters = await generateDynamicRoutes();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
@@ -121,6 +120,6 @@ export const useAsyncRouteStore = defineStore({
|
||||
});
|
||||
|
||||
// Need to be used outside the setup
|
||||
export function useAsyncRouteStoreWidthOut() {
|
||||
export function useAsyncRoute() {
|
||||
return useAsyncRouteStore(store);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,6 @@ export const useDesignSettingStore = defineStore({
|
||||
});
|
||||
|
||||
// Need to be used outside the setup
|
||||
export function useDesignSettingWithOut() {
|
||||
export function useDesignSetting() {
|
||||
return useDesignSettingStore(store);
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
const allModules = import.meta.glob('./*/index.ts', { eager: true });
|
||||
const modules = {} as any;
|
||||
Object.keys(allModules).forEach((path) => {
|
||||
const fileName = path.split('/')[1];
|
||||
modules[fileName] = allModules[path][fileName] || allModules[path].default || allModules[path];
|
||||
});
|
||||
|
||||
// export default modules
|
||||
import asyncRoute from './async-route';
|
||||
import user from './user';
|
||||
import tabsView from './tabs-view';
|
||||
import lockscreen from './lockscreen';
|
||||
|
||||
export default {
|
||||
asyncRoute,
|
||||
user,
|
||||
tabsView,
|
||||
lockscreen,
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { IS_LOCKSCREEN } from '@/store/mutation-types';
|
||||
import { storage } from '@/utils/Storage';
|
||||
|
||||
// 长时间不操作默认锁屏时间
|
||||
const initTime = 60 * 60;
|
||||
|
||||
const isLock = storage.get(IS_LOCKSCREEN, false);
|
||||
|
||||
export type ILockscreenState = {
|
||||
isLock: boolean; // 是否锁屏
|
||||
lockTime: number;
|
||||
};
|
||||
|
||||
export const useLockscreenStore = defineStore({
|
||||
id: 'app-lockscreen',
|
||||
state: (): ILockscreenState => ({
|
||||
isLock: isLock === true, // 是否锁屏
|
||||
lockTime: isLock == 'true' ? initTime : 0,
|
||||
}),
|
||||
getters: {},
|
||||
actions: {
|
||||
setLock(payload) {
|
||||
this.isLock = payload;
|
||||
storage.set(IS_LOCKSCREEN, this.isLock);
|
||||
},
|
||||
setLockTime(payload = initTime) {
|
||||
this.lockTime = payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -1,7 +1,6 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { store } from '@/store';
|
||||
import projectSetting from '@/settings/projectSetting';
|
||||
import type { IheaderSetting, ImenuSetting, ImultiTabsSetting, IcrumbsSetting } from '/#/config';
|
||||
import type { IHeaderSetting, IMenuSetting, IMultiTabsSetting, ICrumbsSetting } from '/#/config';
|
||||
|
||||
const {
|
||||
navMode,
|
||||
@@ -20,11 +19,11 @@ const {
|
||||
interface ProjectSettingState {
|
||||
navMode: string; //导航模式
|
||||
navTheme: string; //导航风格
|
||||
headerSetting: IheaderSetting; //顶部设置
|
||||
headerSetting: IHeaderSetting; //顶部设置
|
||||
showFooter: boolean; //页脚
|
||||
menuSetting: ImenuSetting; //多标签
|
||||
multiTabsSetting: ImultiTabsSetting; //多标签
|
||||
crumbsSetting: IcrumbsSetting; //面包屑
|
||||
menuSetting: IMenuSetting; //多标签
|
||||
multiTabsSetting: IMultiTabsSetting; //多标签
|
||||
crumbsSetting: ICrumbsSetting; //面包屑
|
||||
permissionMode: string; //权限模式
|
||||
isPageAnimate: boolean; //是否开启路由动画
|
||||
pageAnimateType: string; //路由动画类型
|
||||
@@ -90,8 +89,3 @@ export const useProjectSettingStore = defineStore({
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Need to be used outside the setup
|
||||
export function useProjectSettingStoreWithOut() {
|
||||
return useProjectSettingStore(store);
|
||||
}
|
||||
|
||||
31
src/store/modules/screenLock.ts
Normal file
31
src/store/modules/screenLock.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { IS_SCREENLOCKED } from '@/store/mutation-types';
|
||||
import { storage } from '@/utils/Storage';
|
||||
|
||||
// 长时间不操作默认锁屏时间
|
||||
const initTime = 60 * 60;
|
||||
|
||||
const isLocked = storage.get(IS_SCREENLOCKED, false);
|
||||
|
||||
export type IScreenLockState = {
|
||||
isLocked: boolean; // 是否锁屏
|
||||
lockTime: number;
|
||||
};
|
||||
|
||||
export const useScreenLockStore = defineStore({
|
||||
id: 'app-screen-lock',
|
||||
state: (): IScreenLockState => ({
|
||||
isLocked: isLocked === true, // 是否锁屏
|
||||
lockTime: isLocked == 'true' ? initTime : 0,
|
||||
}),
|
||||
getters: {},
|
||||
actions: {
|
||||
setLock(payload: boolean) {
|
||||
this.isLocked = payload;
|
||||
storage.set(IS_SCREENLOCKED, this.isLocked);
|
||||
},
|
||||
setLockTime(payload = initTime) {
|
||||
this.lockTime = payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -30,11 +30,11 @@ export const useTabsViewStore = defineStore({
|
||||
}),
|
||||
getters: {},
|
||||
actions: {
|
||||
initTabs(routes) {
|
||||
initTabs(routes: RouteItem[]) {
|
||||
// 初始化标签页
|
||||
this.tabsList = routes;
|
||||
},
|
||||
addTabs(route): boolean {
|
||||
addTab(route: RouteItem): boolean {
|
||||
// 添加标签页
|
||||
if (whiteList.includes(route.name)) return false;
|
||||
const isExists = this.tabsList.some((item) => item.fullPath == route.fullPath);
|
||||
@@ -43,28 +43,29 @@ export const useTabsViewStore = defineStore({
|
||||
}
|
||||
return true;
|
||||
},
|
||||
closeLeftTabs(route) {
|
||||
closeLeftTabs(route: RouteItem) {
|
||||
// 关闭左侧
|
||||
const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
|
||||
this.tabsList = this.tabsList.filter((item, i) => i >= index || (item?.meta?.affix ?? false));
|
||||
},
|
||||
closeRightTabs(route) {
|
||||
closeRightTabs(route: RouteItem) {
|
||||
// 关闭右侧
|
||||
const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
|
||||
this.tabsList = this.tabsList.filter((item, i) => i <= index || (item?.meta?.affix ?? false));
|
||||
},
|
||||
closeOtherTabs(route) {
|
||||
closeOtherTabs(route: RouteItem) {
|
||||
// 关闭其他
|
||||
this.tabsList = this.tabsList.filter((item) => item.fullPath == route.fullPath || (item?.meta?.affix ?? false));
|
||||
this.tabsList = this.tabsList.filter(
|
||||
(item) => item.fullPath == route.fullPath || (item?.meta?.affix ?? false)
|
||||
);
|
||||
},
|
||||
closeCurrentTab(route) {
|
||||
closeCurrentTab(route: RouteItem) {
|
||||
// 关闭当前页
|
||||
const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
|
||||
this.tabsList.splice(index, 1);
|
||||
},
|
||||
closeAllTabs() {
|
||||
// 关闭全部
|
||||
console.log(retainAffixRoute(this.tabsList));
|
||||
this.tabsList = retainAffixRoute(this.tabsList);
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,18 +1,24 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { store } from '@/store';
|
||||
import { ACCESS_TOKEN, CURRENT_USER, IS_LOCKSCREEN } from '@/store/mutation-types';
|
||||
import { ACCESS_TOKEN, CURRENT_USER, IS_SCREENLOCKED } from '@/store/mutation-types';
|
||||
import { ResultEnum } from '@/enums/httpEnum';
|
||||
|
||||
import { getUserInfo, login } from '@/api/system/user';
|
||||
import { getUserInfo as getUserInfoApi, login } from '@/api/system/user';
|
||||
import { storage } from '@/utils/Storage';
|
||||
|
||||
export type UserInfoType = {
|
||||
// TODO: add your own data
|
||||
name: string;
|
||||
email: string;
|
||||
};
|
||||
|
||||
export interface IUserState {
|
||||
token: string;
|
||||
username: string;
|
||||
welcome: string;
|
||||
avatar: string;
|
||||
permissions: any[];
|
||||
info: any;
|
||||
info: UserInfoType;
|
||||
}
|
||||
|
||||
export const useUserStore = defineStore({
|
||||
@@ -38,7 +44,7 @@ export const useUserStore = defineStore({
|
||||
getPermissions(): [any][] {
|
||||
return this.permissions;
|
||||
},
|
||||
getUserInfo(): object {
|
||||
getUserInfo(): UserInfoType {
|
||||
return this.info;
|
||||
},
|
||||
},
|
||||
@@ -52,63 +58,49 @@ export const useUserStore = defineStore({
|
||||
setPermissions(permissions) {
|
||||
this.permissions = permissions;
|
||||
},
|
||||
setUserInfo(info) {
|
||||
setUserInfo(info: UserInfoType) {
|
||||
this.info = info;
|
||||
},
|
||||
// 登录
|
||||
async login(userInfo) {
|
||||
try {
|
||||
const response = await login(userInfo);
|
||||
const { result, code } = response;
|
||||
if (code === ResultEnum.SUCCESS) {
|
||||
const ex = 7 * 24 * 60 * 60;
|
||||
storage.set(ACCESS_TOKEN, result.token, ex);
|
||||
storage.set(CURRENT_USER, result, ex);
|
||||
storage.set(IS_LOCKSCREEN, false);
|
||||
this.setToken(result.token);
|
||||
this.setUserInfo(result);
|
||||
}
|
||||
return Promise.resolve(response);
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
async login(params: any) {
|
||||
const response = await login(params);
|
||||
const { result, code } = response;
|
||||
if (code === ResultEnum.SUCCESS) {
|
||||
const ex = 7 * 24 * 60 * 60;
|
||||
storage.set(ACCESS_TOKEN, result.token, ex);
|
||||
storage.set(CURRENT_USER, result, ex);
|
||||
storage.set(IS_SCREENLOCKED, false);
|
||||
this.setToken(result.token);
|
||||
this.setUserInfo(result);
|
||||
}
|
||||
return response;
|
||||
},
|
||||
|
||||
// 获取用户信息
|
||||
GetInfo() {
|
||||
const that = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
getUserInfo()
|
||||
.then((res) => {
|
||||
const result = res;
|
||||
if (result.permissions && result.permissions.length) {
|
||||
const permissionsList = result.permissions;
|
||||
that.setPermissions(permissionsList);
|
||||
that.setUserInfo(result);
|
||||
} else {
|
||||
reject(new Error('getInfo: permissionsList must be a non-null array !'));
|
||||
}
|
||||
that.setAvatar(result.avatar);
|
||||
resolve(res);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
async getInfo() {
|
||||
const result = await getUserInfoApi();
|
||||
if (result.permissions && result.permissions.length) {
|
||||
const permissionsList = result.permissions;
|
||||
this.setPermissions(permissionsList);
|
||||
this.setUserInfo(result);
|
||||
} else {
|
||||
throw new Error('getInfo: permissionsList must be a non-null array !');
|
||||
}
|
||||
this.setAvatar(result.avatar);
|
||||
return result;
|
||||
},
|
||||
|
||||
// 登出
|
||||
async logout() {
|
||||
this.setPermissions([]);
|
||||
this.setUserInfo('');
|
||||
this.setUserInfo({ name: '', email: '' });
|
||||
storage.remove(ACCESS_TOKEN);
|
||||
storage.remove(CURRENT_USER);
|
||||
return Promise.resolve('');
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Need to be used outside the setup
|
||||
export function useUserStoreWidthOut() {
|
||||
export function useUser() {
|
||||
return useUserStore(store);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export const ACCESS_TOKEN = 'ACCESS-TOKEN'; // 用户token
|
||||
export const CURRENT_USER = 'CURRENT-USER'; // 当前用户信息
|
||||
export const IS_LOCKSCREEN = 'IS-LOCKSCREEN'; // 是否锁屏
|
||||
export const IS_SCREENLOCKED = 'IS-SCREENLOCKED'; // 是否锁屏
|
||||
export const TABS_ROUTES = 'TABS-ROUTES'; // 标签页
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { IAsyncRouteState } from '@/store/modules/asyncRoute';
|
||||
import { IUserState } from '@/store/modules/user';
|
||||
import { ILockscreenState } from '@/store/modules/lockscreen';
|
||||
import { IScreenLockState } from '@/store/modules/screenLock';
|
||||
import { ITabsViewState } from '@/store/modules/tabsView';
|
||||
|
||||
export interface IStore {
|
||||
asyncRoute: IAsyncRouteState;
|
||||
user: IUserState;
|
||||
lockscreen: ILockscreenState;
|
||||
screenLock: IScreenLockState;
|
||||
tabsView: ITabsViewState;
|
||||
count: number;
|
||||
}
|
||||
|
||||
@@ -6,122 +6,119 @@ const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7;
|
||||
* @param {string=} prefixKey -
|
||||
* @param {Object} [storage=localStorage] - sessionStorage | localStorage
|
||||
*/
|
||||
export const createStorage = ({ prefixKey = '', storage = localStorage } = {}) => {
|
||||
|
||||
export default class Storage {
|
||||
private storage: globalThis.Storage;
|
||||
private prefixKey?: string;
|
||||
|
||||
constructor(prefixKey = '', storage = localStorage) {
|
||||
this.storage = storage;
|
||||
this.prefixKey = prefixKey;
|
||||
}
|
||||
|
||||
private getKey(key: string) {
|
||||
return `${this.prefixKey}${key}`.toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地缓存类
|
||||
* @class Storage
|
||||
* @description 设置缓存
|
||||
* @param {string} key 缓存键
|
||||
* @param {*} value 缓存值
|
||||
* @param expire
|
||||
*/
|
||||
const Storage = class {
|
||||
private storage = storage;
|
||||
private prefixKey?: string = prefixKey;
|
||||
set(key: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) {
|
||||
const stringData = JSON.stringify({
|
||||
value,
|
||||
expire: expire !== null ? new Date().getTime() + expire * 1000 : null,
|
||||
});
|
||||
this.storage.setItem(this.getKey(key), stringData);
|
||||
}
|
||||
|
||||
private getKey(key: string) {
|
||||
return `${this.prefixKey}${key}`.toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 设置缓存
|
||||
* @param {string} key 缓存键
|
||||
* @param {*} value 缓存值
|
||||
* @param expire
|
||||
*/
|
||||
set(key: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) {
|
||||
const stringData = JSON.stringify({
|
||||
value,
|
||||
expire: expire !== null ? new Date().getTime() + expire * 1000 : null,
|
||||
});
|
||||
this.storage.setItem(this.getKey(key), stringData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取缓存
|
||||
* @param {string} key 缓存键
|
||||
* @param {*=} def 默认值
|
||||
*/
|
||||
get(key: string, def: any = null) {
|
||||
const item = this.storage.getItem(this.getKey(key));
|
||||
if (item) {
|
||||
try {
|
||||
const data = JSON.parse(item);
|
||||
const { value, expire } = data;
|
||||
// 在有效期内直接返回
|
||||
if (expire === null || expire >= Date.now()) {
|
||||
return value;
|
||||
}
|
||||
this.remove(key);
|
||||
} catch (e) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存删除某项
|
||||
* @param {string} key
|
||||
*/
|
||||
remove(key: string) {
|
||||
this.storage.removeItem(this.getKey(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空所有缓存
|
||||
* @memberOf Cache
|
||||
*/
|
||||
clear(): void {
|
||||
this.storage.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置cookie
|
||||
* @param {string} name cookie 名称
|
||||
* @param {*} value cookie 值
|
||||
* @param {number=} expire 过期时间
|
||||
* 如果过期时间未设置,默认关闭浏览器自动删除
|
||||
* @example
|
||||
*/
|
||||
setCookie(name: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) {
|
||||
document.cookie = `${this.getKey(name)}=${value}; Max-Age=${expire}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据名字获取cookie值
|
||||
* @param name
|
||||
*/
|
||||
getCookie(name: string): string {
|
||||
const cookieArr = document.cookie.split('; ');
|
||||
for (let i = 0, length = cookieArr.length; i < length; i++) {
|
||||
const kv = cookieArr[i].split('=');
|
||||
if (kv[0] === this.getKey(name)) {
|
||||
return kv[1];
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据名字删除指定的cookie
|
||||
* @param {string} key
|
||||
*/
|
||||
removeCookie(key: string) {
|
||||
this.setCookie(key, 1, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空cookie,使所有cookie失效
|
||||
*/
|
||||
clearCookie(): void {
|
||||
const keys = document.cookie.match(/[^ =;]+(?==)/g);
|
||||
if (keys) {
|
||||
for (let i = keys.length; i--; ) {
|
||||
document.cookie = keys[i] + '=0;expire=' + new Date(0).toUTCString();
|
||||
/**
|
||||
* 读取缓存
|
||||
* @param {string} key 缓存键
|
||||
* @param {*=} def 默认值
|
||||
*/
|
||||
get(key: string, def: any = null) {
|
||||
const item = this.storage.getItem(this.getKey(key));
|
||||
if (item) {
|
||||
try {
|
||||
const data = JSON.parse(item);
|
||||
const { value, expire } = data;
|
||||
// 在有效期内直接返回
|
||||
if (expire === null || expire >= Date.now()) {
|
||||
return value;
|
||||
}
|
||||
this.remove(key);
|
||||
} catch (e) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
};
|
||||
return new Storage();
|
||||
};
|
||||
return def;
|
||||
}
|
||||
|
||||
export const storage = createStorage();
|
||||
/**
|
||||
* 从缓存删除某项
|
||||
* @param {string} key
|
||||
*/
|
||||
remove(key: string) {
|
||||
this.storage.removeItem(this.getKey(key));
|
||||
}
|
||||
|
||||
export default Storage;
|
||||
/**
|
||||
* 清空所有缓存
|
||||
* @memberOf Cache
|
||||
*/
|
||||
clear(): void {
|
||||
this.storage.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置cookie
|
||||
* @param {string} name cookie 名称
|
||||
* @param {*} value cookie 值
|
||||
* @param {number=} expire 过期时间
|
||||
* 如果过期时间未设置,默认关闭浏览器自动删除
|
||||
* @example
|
||||
*/
|
||||
setCookie(name: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) {
|
||||
document.cookie = `${this.getKey(name)}=${value}; Max-Age=${expire}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据名字获取cookie值
|
||||
* @param name
|
||||
*/
|
||||
getCookie(name: string): string {
|
||||
const cookieArr = document.cookie.split('; ');
|
||||
for (let i = 0, length = cookieArr.length; i < length; i++) {
|
||||
const kv = cookieArr[i].split('=');
|
||||
if (kv[0] === this.getKey(name)) {
|
||||
return kv[1];
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据名字删除指定的cookie
|
||||
* @param {string} key
|
||||
*/
|
||||
removeCookie(key: string) {
|
||||
this.setCookie(key, 1, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空cookie,使所有cookie失效
|
||||
*/
|
||||
clearCookie(): void {
|
||||
const keys = document.cookie.match(/[^ =;]+(?==)/g);
|
||||
if (keys) {
|
||||
for (let i = keys.length; i--; ) {
|
||||
document.cookie = keys[i] + '=0;expire=' + new Date(0).toUTCString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const storage = new Storage('');
|
||||
|
||||
@@ -15,7 +15,7 @@ import { setObjToUrlParams } from '@/utils/urlUtils';
|
||||
|
||||
import { RequestOptions, Result, CreateAxiosOptions } from './types';
|
||||
|
||||
import { useUserStoreWidthOut } from '@/store/modules/user';
|
||||
import { useUser } from '@/store/modules/user';
|
||||
|
||||
const globSetting = useGlobSetting();
|
||||
const urlPrefix = globSetting.urlPrefix || '';
|
||||
@@ -176,7 +176,7 @@ const transform: AxiosTransform = {
|
||||
*/
|
||||
requestInterceptors: (config, options) => {
|
||||
// 请求之前处理config
|
||||
const userStore = useUserStoreWidthOut();
|
||||
const userStore = useUser();
|
||||
const token = userStore.getToken;
|
||||
if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
|
||||
// jwt token
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
module.exports = {
|
||||
// darkMode: 'class',
|
||||
plugins: [createEnterPlugin()],
|
||||
content: {
|
||||
enable: process.env.NODE_ENV === 'production',
|
||||
content: ['./index.html', './src/**/*.{vue,ts,tsx}'],
|
||||
},
|
||||
content: ['./index.html', './src/**/*.{vue,ts,tsx}'],
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
|
||||
10
types/config.d.ts
vendored
10
types/config.d.ts
vendored
@@ -17,17 +17,17 @@ export interface ProjectSettingState {
|
||||
permissionMode: string;
|
||||
}
|
||||
|
||||
export interface IbodySetting {
|
||||
export interface IBodySetting {
|
||||
fixed: boolean;
|
||||
}
|
||||
|
||||
export interface IheaderSetting {
|
||||
export interface IHeaderSetting {
|
||||
bgColor: string;
|
||||
fixed: boolean;
|
||||
isReload: boolean;
|
||||
}
|
||||
|
||||
export interface ImenuSetting {
|
||||
export interface IMenuSetting {
|
||||
minMenuWidth: number;
|
||||
menuWidth: number;
|
||||
fixed: boolean;
|
||||
@@ -36,12 +36,12 @@ export interface ImenuSetting {
|
||||
mobileWidth: number;
|
||||
}
|
||||
|
||||
export interface IcrumbsSetting {
|
||||
export interface ICrumbsSetting {
|
||||
show: boolean;
|
||||
showIcon: boolean;
|
||||
}
|
||||
|
||||
export interface ImultiTabsSetting {
|
||||
export interface IMultiTabsSetting {
|
||||
bgColor: string;
|
||||
fixed: boolean;
|
||||
show: boolean;
|
||||
|
||||
Reference in New Issue
Block a user