refactor: remove unused files, bug fixes and name changes

This commit is contained in:
Hansen Wang
2023-04-24 02:09:39 +08:00
parent e1528823f7
commit 5d891c1f44
32 changed files with 352 additions and 417 deletions

View File

@@ -21,16 +21,16 @@
import { zhCN, dateZhCN, darkTheme } from 'naive-ui'; import { zhCN, dateZhCN, darkTheme } from 'naive-ui';
import { LockScreen } from '@/components/Lockscreen'; import { LockScreen } from '@/components/Lockscreen';
import { AppProvider } from '@/components/Application'; import { AppProvider } from '@/components/Application';
import { useLockscreenStore } from '@/store/modules/lockscreen'; import { useScreenLockStore } from '@/store/modules/screenLock.js';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { useDesignSettingStore } from '@/store/modules/designSetting'; import { useDesignSettingStore } from '@/store/modules/designSetting';
import { lighten } from '@/utils/index'; import { lighten } from '@/utils/index';
const route = useRoute(); const route = useRoute();
const useLockscreen = useLockscreenStore(); const useScreenLock = useScreenLockStore();
const designStore = useDesignSettingStore(); const designStore = useDesignSettingStore();
const isLock = computed(() => useLockscreen.isLock); const isLock = computed(() => useScreenLock.isLocked);
const lockTime = computed(() => useLockscreen.lockTime); const lockTime = computed(() => useScreenLock.lockTime);
/** /**
* @type import('naive-ui').GlobalThemeOverrides * @type import('naive-ui').GlobalThemeOverrides
@@ -53,21 +53,21 @@
const getDarkTheme = computed(() => (designStore.darkTheme ? darkTheme : undefined)); const getDarkTheme = computed(() => (designStore.darkTheme ? darkTheme : undefined));
let timer; let timer: NodeJS.Timer;
const timekeeping = () => { const timekeeping = () => {
clearInterval(timer); clearInterval(timer);
if (route.name == 'login' || isLock.value) return; if (route.name == 'login' || isLock.value) return;
// 设置不锁屏 // 设置不锁屏
useLockscreen.setLock(false); useScreenLock.setLock(false);
// 重置锁屏时间 // 重置锁屏时间
useLockscreen.setLockTime(); useScreenLock.setLockTime();
timer = setInterval(() => { timer = setInterval(() => {
// 锁屏倒计时递减 // 锁屏倒计时递减
useLockscreen.setLockTime(lockTime.value - 1); useScreenLock.setLockTime(lockTime.value - 1);
if (lockTime.value <= 0) { if (lockTime.value <= 0) {
// 设置锁屏 // 设置锁屏
useLockscreen.setLock(true); useScreenLock.setLock(true);
return clearInterval(timer); return clearInterval(timer);
} }
}, 1000); }, 1000);

View File

@@ -60,11 +60,11 @@
</template> </template>
</n-input> </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> <span class="text-red-500">{{ errorMsg }}</span>
</div> </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="showLogin = false">返回</a></div>
<div><a @click="goLogin">重新登录</a></div> <div><a @click="goLogin">重新登录</a></div>
<div><a @click="onLogin">进入系统</a></div> <div><a @click="onLogin">进入系统</a></div>
@@ -91,11 +91,11 @@
import { useOnline } from '@/hooks/useOnline'; import { useOnline } from '@/hooks/useOnline';
import { useTime } from '@/hooks/useTime'; import { useTime } from '@/hooks/useTime';
import { useBattery } from '@/hooks/useBattery'; import { useBattery } from '@/hooks/useBattery';
import { useLockscreenStore } from '@/store/modules/lockscreen'; import { useScreenLockStore } from '@/store/modules/screenLock';
import { useUserStore } from '@/store/modules/user'; import { UserInfoType, useUserStore } from '@/store/modules/user';
export default defineComponent({ export default defineComponent({
name: 'Lockscreen', name: 'ScreenLock',
components: { components: {
LockOutlined, LockOutlined,
LoadingOutlined, LoadingOutlined,
@@ -106,7 +106,7 @@
recharge, recharge,
}, },
setup() { setup() {
const useLockscreen = useLockscreenStore(); const useScreenLock = useScreenLockStore();
const userStore = useUserStore(); const userStore = useUserStore();
// 获取时间 // 获取时间
@@ -117,7 +117,7 @@
const route = useRoute(); const route = useRoute();
const { battery, batteryStatus, calcDischargingTime, calcChargingTime } = useBattery(); const { battery, batteryStatus, calcDischargingTime, calcChargingTime } = useBattery();
const userInfo: object = userStore.getUserInfo || {}; const userInfo: UserInfoType = userStore.getUserInfo || {};
const username = userInfo['username'] || ''; const username = userInfo['username'] || '';
const state = reactive({ const state = reactive({
showLogin: false, showLogin: false,
@@ -146,7 +146,7 @@
const { code, message } = await userStore.login(params); const { code, message } = await userStore.login(params);
if (code === ResultEnum.SUCCESS) { if (code === ResultEnum.SUCCESS) {
onLockLogin(false); onLockLogin(false);
useLockscreen.setLock(false); useScreenLock.setLock(false);
} else { } else {
state.errorMsg = message; state.errorMsg = message;
state.isLoginError = true; state.isLoginError = true;
@@ -157,7 +157,7 @@
//重新登录 //重新登录
const goLogin = () => { const goLogin = () => {
onLockLogin(false); onLockLogin(false);
useLockscreen.setLock(false); useScreenLock.setLock(false);
router.replace({ router.replace({
path: '/login', path: '/login',
query: { query: {

View File

@@ -1,3 +1,3 @@
import { useAsync } from './use-async'; import { useAsync } from './useAsync';
export { useAsync }; export { useAsync };

View File

@@ -4,39 +4,39 @@ import { useProjectSettingStore } from '@/store/modules/projectSetting';
export function useProjectSetting() { export function useProjectSetting() {
const projectStore = useProjectSettingStore(); 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 { return {
getNavMode, navMode,
getNavTheme, navTheme,
getIsMobile, isMobile,
getHeaderSetting, headerSetting,
getMultiTabsSetting, multiTabsSetting,
getMenuSetting, menuSetting,
getCrumbsSetting, crumbsSetting,
getPermissionMode, permissionMode,
getShowFooter, showFooter,
getIsPageAnimate, isPageAnimate,
getPageAnimateType, pageAnimateType,
}; };
} }

View File

@@ -106,7 +106,7 @@ export function useECharts(
return chartInstance; return chartInstance;
} }
function disposeInstance(){ function disposeInstance() {
if (!chartInstance) return; if (!chartInstance) return;
removeResizeFn(); removeResizeFn();
chartInstance.dispose(); chartInstance.dispose();
@@ -118,6 +118,6 @@ export function useECharts(
resize, resize,
echarts, echarts,
getInstance, getInstance,
disposeInstance disposeInstance,
}; };
} }

View File

@@ -75,7 +75,7 @@
<div <div
class="layout-header-trigger layout-header-trigger-min" class="layout-header-trigger layout-header-trigger-min"
v-for="item in iconList" v-for="item in iconList"
:key="item.icon.name" :key="item.icon"
> >
<n-tooltip placement="bottom"> <n-tooltip placement="bottom">
<template #trigger> <template #trigger>
@@ -134,7 +134,7 @@
import { NDialogProvider, useDialog, useMessage } from 'naive-ui'; import { NDialogProvider, useDialog, useMessage } from 'naive-ui';
import { TABS_ROUTES } from '@/store/mutation-types'; import { TABS_ROUTES } from '@/store/mutation-types';
import { useUserStore } from '@/store/modules/user'; import { useUserStore } from '@/store/modules/user';
import { useLockscreenStore } from '@/store/modules/lockscreen'; import { useScreenLockStore } from '@/store/modules/screenLock';
import ProjectSetting from './ProjectSetting.vue'; import ProjectSetting from './ProjectSetting.vue';
import { AsideMenu } from '@/layout/components/Menu'; import { AsideMenu } from '@/layout/components/Menu';
import { useProjectSetting } from '@/hooks/setting/useProjectSetting'; import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
@@ -153,37 +153,37 @@
}, },
setup(props) { setup(props) {
const userStore = useUserStore(); const userStore = useUserStore();
const useLockscreen = useLockscreenStore(); const useLockscreen = useScreenLockStore();
const message = useMessage(); const message = useMessage();
const dialog = useDialog(); const dialog = useDialog();
const { getNavMode, getNavTheme, getHeaderSetting, getMenuSetting, getCrumbsSetting } = const { navMode, navTheme, headerSetting, menuSetting, crumbsSetting } = useProjectSetting();
useProjectSetting();
const { username } = userStore?.info || {}; const { name } = userStore?.info || {};
const drawerSetting = ref(); const drawerSetting = ref();
const state = reactive({ const state = reactive({
username: username || '', username: name ?? '',
fullscreenIcon: 'FullscreenOutlined', fullscreenIcon: 'FullscreenOutlined',
navMode: getNavMode, navMode,
navTheme: getNavTheme, navTheme,
headerSetting: getHeaderSetting, headerSetting,
crumbsSetting: getCrumbsSetting, crumbsSetting,
}); });
const getInverted = computed(() => { const getInverted = computed(() => {
const navTheme = unref(getNavTheme); return ['light', 'header-dark'].includes(unref(navTheme))
return ['light', 'header-dark'].includes(navTheme) ? props.inverted : !props.inverted; ? props.inverted
: !props.inverted;
}); });
const mixMenu = computed(() => { const mixMenu = computed(() => {
return unref(getMenuSetting).mixMenu; return unref(menuSetting).mixMenu;
}); });
const getChangeStyle = computed(() => { const getChangeStyle = computed(() => {
const { collapsed } = props; const { collapsed } = props;
const { minMenuWidth, menuWidth }: any = unref(getMenuSetting); const { minMenuWidth, menuWidth } = unref(menuSetting);
return { return {
left: collapsed ? `${minMenuWidth}px` : `${menuWidth}px`, left: collapsed ? `${minMenuWidth}px` : `${menuWidth}px`,
width: `calc(100% - ${collapsed ? `${minMenuWidth}px` : `${menuWidth}px`})`, width: `calc(100% - ${collapsed ? `${minMenuWidth}px` : `${menuWidth}px`})`,

View File

@@ -30,13 +30,13 @@
}, },
}, },
setup() { setup() {
const { getIsPageAnimate, getPageAnimateType } = useProjectSetting(); const { isPageAnimate, pageAnimateType } = useProjectSetting();
const asyncRouteStore = useAsyncRouteStore(); const asyncRouteStore = useAsyncRouteStore();
// 需要缓存的路由组件 // 需要缓存的路由组件
const keepAliveComponents = computed(() => asyncRouteStore.keepAliveComponents); const keepAliveComponents = computed(() => asyncRouteStore.keepAliveComponents);
const getTransitionName = computed(() => { const getTransitionName = computed(() => {
return unref(getIsPageAnimate) ? unref(getPageAnimateType) : ''; return unref(isPageAnimate) ? unref(pageAnimateType) : '';
}); });
return { return {

View File

@@ -23,7 +23,7 @@
import { useProjectSetting } from '@/hooks/setting/useProjectSetting'; import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
export default defineComponent({ export default defineComponent({
name: 'Menu', name: 'AppMenu',
components: {}, components: {},
props: { props: {
mode: { mode: {
@@ -52,9 +52,7 @@
const selectedKeys = ref<string>(currentRoute.name as string); const selectedKeys = ref<string>(currentRoute.name as string);
const headerMenuSelectKey = ref<string>(''); const headerMenuSelectKey = ref<string>('');
const { getNavMode } = useProjectSetting(); const { navMode } = useProjectSetting();
const navMode = getNavMode;
// 获取当前打开的子菜单 // 获取当前打开的子菜单
const matched = currentRoute.matched; const matched = currentRoute.matched;

View File

@@ -1,6 +1,6 @@
<template> <template>
<div <div
class="tabs-view box-border" class="box-border tabs-view"
:class="{ :class="{
'tabs-view-fix': multiTabsSetting.fixed, 'tabs-view-fix': multiTabsSetting.fixed,
'tabs-view-fixed-header': isMultiHeaderFixed, 'tabs-view-fixed-header': isMultiHeaderFixed,
@@ -82,7 +82,6 @@
computed, computed,
ref, ref,
toRefs, toRefs,
unref,
provide, provide,
watch, watch,
onMounted, onMounted,
@@ -130,7 +129,7 @@
}, },
setup(props) { setup(props) {
const { getDarkTheme, getAppTheme } = useDesignSetting(); const { getDarkTheme, getAppTheme } = useDesignSetting();
const { getNavMode, getHeaderSetting, getMenuSetting, getMultiTabsSetting, getIsMobile } = const { navMode, headerSetting, menuSetting, multiTabsSetting, isMobile } =
useProjectSetting(); useProjectSetting();
const settingStore = useProjectSettingStore(); const settingStore = useProjectSettingStore();
@@ -161,7 +160,7 @@
dropdownY: 0, dropdownY: 0,
showDropdown: false, showDropdown: false,
isMultiHeaderFixed: false, isMultiHeaderFixed: false,
multiTabsSetting: getMultiTabsSetting, multiTabsSetting: multiTabsSetting,
}); });
// 获取简易的路由对象 // 获取简易的路由对象
@@ -173,25 +172,23 @@
const isMixMenuNoneSub = computed(() => { const isMixMenuNoneSub = computed(() => {
const mixMenu = settingStore.menuSetting.mixMenu; const mixMenu = settingStore.menuSetting.mixMenu;
const currentRoute = useRoute(); const currentRoute = useRoute();
const navMode = unref(getNavMode); if (navMode.value != 'horizontal-mix') return true;
if (unref(navMode) != 'horizontal-mix') return true; return !(navMode.value === 'horizontal-mix' && mixMenu && currentRoute.meta.isRoot);
return !(unref(navMode) === 'horizontal-mix' && mixMenu && currentRoute.meta.isRoot);
}); });
//动态组装样式 菜单缩进 //动态组装样式 菜单缩进
const getChangeStyle = computed(() => { const getChangeStyle = computed(() => {
const { collapsed } = props; const { collapsed } = props;
const navMode = unref(getNavMode); const { minMenuWidth, menuWidth }: any = menuSetting.value;
const { minMenuWidth, menuWidth }: any = unref(getMenuSetting); const { fixed }: any = multiTabsSetting.value;
const { fixed }: any = unref(getMultiTabsSetting);
let lenNum = let lenNum =
navMode === 'horizontal' || !isMixMenuNoneSub.value navMode.value === 'horizontal' || !isMixMenuNoneSub.value
? '0px' ? '0px'
: collapsed : collapsed
? `${minMenuWidth}px` ? `${minMenuWidth}px`
: `${menuWidth}px`; : `${menuWidth}px`;
if (getIsMobile.value) { if (isMobile.value) {
return { return {
left: '0px', left: '0px',
width: '100%', width: '100%',
@@ -205,7 +202,7 @@
//tags 右侧下拉菜单 //tags 右侧下拉菜单
const TabsMenuOptions = computed(() => { const TabsMenuOptions = computed(() => {
const isDisabled = unref(tabsList).length <= 1; const isDisabled = tabsList.value.length <= 1;
return [ return [
{ {
label: '刷新当前', label: '刷新当前',
@@ -215,7 +212,7 @@
{ {
label: `关闭当前`, label: `关闭当前`,
key: '2', key: '2',
disabled: unref(isCurrent) || isDisabled, disabled: isCurrent.value || isDisabled,
icon: renderIcon(CloseOutlined), icon: renderIcon(CloseOutlined),
}, },
{ {
@@ -263,8 +260,8 @@
window.pageYOffset || window.pageYOffset ||
document.body.scrollTop; // 滚动条偏移量 document.body.scrollTop; // 滚动条偏移量
state.isMultiHeaderFixed = !!( state.isMultiHeaderFixed = !!(
!getHeaderSetting.value.fixed && !headerSetting.value.fixed &&
getMultiTabsSetting.value.fixed && multiTabsSetting.value.fixed &&
scrollTop >= 64 scrollTop >= 64
); );
} }
@@ -297,7 +294,7 @@
(to) => { (to) => {
if (whiteList.includes(route.name as string)) return; if (whiteList.includes(route.name as string)) return;
state.activeKey = to; state.activeKey = to;
tabsViewStore.addTabs(getSimpleRoute(route)); tabsViewStore.addTab(getSimpleRoute(route));
updateNavScroll(true); updateNavScroll(true);
}, },
{ immediate: true } { immediate: true }
@@ -328,7 +325,7 @@
const reloadPage = () => { const reloadPage = () => {
delKeepAliveCompName(); delKeepAliveCompName();
router.push({ router.push({
path: '/redirect' + unref(route).fullPath, path: '/redirect' + route.fullPath,
}); });
}; };

View File

@@ -21,7 +21,7 @@
</n-layout-sider> </n-layout-sider>
<n-drawer <n-drawer
v-model:show="showSideDrawder" v-model:show="showSideDrawer"
:width="menuWidth" :width="menuWidth"
:placement="'left'" :placement="'left'"
class="layout-side-drawer" class="layout-side-drawer"
@@ -82,21 +82,19 @@
const { getDarkTheme } = useDesignSetting(); const { getDarkTheme } = useDesignSetting();
const { const {
// getShowFooter, // showFooter,
getNavMode, navMode,
getNavTheme, navTheme,
getHeaderSetting, headerSetting,
getMenuSetting, menuSetting,
getMultiTabsSetting, multiTabsSetting,
} = useProjectSetting(); } = useProjectSetting();
const settingStore = useProjectSettingStore(); const settingStore = useProjectSettingStore();
const navMode = getNavMode;
const collapsed = ref<boolean>(false); const collapsed = ref<boolean>(false);
const { mobileWidth, menuWidth } = unref(getMenuSetting); const { mobileWidth, menuWidth } = unref(menuSetting);
const isMobile = computed<boolean>({ const isMobile = computed<boolean>({
get: () => settingStore.getIsMobile, get: () => settingStore.getIsMobile,
@@ -104,12 +102,12 @@
}); });
const fixedHeader = computed(() => { const fixedHeader = computed(() => {
const { fixed } = unref(getHeaderSetting); const { fixed } = unref(headerSetting);
return fixed ? 'absolute' : 'static'; return fixed ? 'absolute' : 'static';
}); });
const isMixMenuNoneSub = computed(() => { const isMixMenuNoneSub = computed(() => {
const mixMenu = settingStore.menuSetting.mixMenu; const mixMenu = unref(menuSetting).mixMenu;
const currentRoute = useRoute(); const currentRoute = useRoute();
if (unref(navMode) != 'horizontal-mix') return true; if (unref(navMode) != 'horizontal-mix') return true;
if (unref(navMode) === 'horizontal-mix' && mixMenu && currentRoute.meta.isRoot) { if (unref(navMode) === 'horizontal-mix' && mixMenu && currentRoute.meta.isRoot) {
@@ -119,45 +117,37 @@
}); });
const fixedMenu = computed(() => { const fixedMenu = computed(() => {
const { fixed } = unref(getHeaderSetting); const { fixed } = unref(headerSetting);
return fixed ? 'absolute' : 'static'; return fixed ? 'absolute' : 'static';
}); });
const isMultiTabs = computed(() => { const isMultiTabs = computed(() => {
return unref(getMultiTabsSetting).show; return unref(multiTabsSetting).show;
}); });
const fixedMulti = computed(() => { const fixedMulti = computed(() => {
return unref(getMultiTabsSetting).fixed; return unref(multiTabsSetting).fixed;
}); });
const inverted = computed(() => { const inverted = computed(() => {
return ['dark', 'header-dark'].includes(unref(getNavTheme)); return ['dark', 'header-dark'].includes(unref(navTheme));
}); });
const getHeaderInverted = computed(() => { const getHeaderInverted = computed(() => {
const navTheme = unref(getNavTheme); return ['light', 'header-dark'].includes(unref(navTheme)) ? unref(inverted) : !unref(inverted);
return ['light', 'header-dark'].includes(navTheme) ? unref(inverted) : !unref(inverted);
}); });
const leftMenuWidth = computed(() => { const leftMenuWidth = computed(() => {
const { minMenuWidth, menuWidth } = unref(getMenuSetting); const { minMenuWidth, menuWidth } = unref(menuSetting);
return collapsed.value ? minMenuWidth : menuWidth; 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(() => { const getMenuLocation = computed(() => {
return 'left'; return 'left';
}); });
// 控制显示或隐藏移动端侧边栏 // 控制显示或隐藏移动端侧边栏
const showSideDrawder = computed({ const showSideDrawer = computed({
get: () => isMobile.value && collapsed.value, get: () => isMobile.value && collapsed.value,
set: (val) => (collapsed.value = val), set: (val) => (collapsed.value = val),
}); });

View File

@@ -1,6 +1,6 @@
import * as NaiveUI from 'naive-ui'; import * as NaiveUI from 'naive-ui';
import { computed } from 'vue'; import { computed } from 'vue';
import { useDesignSettingWithOut } from '@/store/modules/designSetting'; import { useDesignSetting } from '@/store/modules/designSetting';
import { lighten } from '@/utils/index'; import { lighten } from '@/utils/index';
/** /**
@@ -10,7 +10,7 @@ import { lighten } from '@/utils/index';
*/ */
export function setupNaiveDiscreteApi() { export function setupNaiveDiscreteApi() {
const designStore = useDesignSettingWithOut(); const designStore = useDesignSetting();
const configProviderPropsRef = computed(() => ({ const configProviderPropsRef = computed(() => ({
theme: designStore.darkTheme ? NaiveUI.darkTheme : undefined, theme: designStore.darkTheme ? NaiveUI.darkTheme : undefined,

View File

@@ -1,8 +1,8 @@
import type { AppRouteRecordRaw } from '@/router/types';
import { ErrorPage, RedirectName, Layout } from '@/router/constant'; import { ErrorPage, RedirectName, Layout } from '@/router/constant';
import { RouteRecordRaw } from 'vue-router';
// 404 on a page // 404 on a page
export const ErrorPageRoute: AppRouteRecordRaw = { export const ErrorPageRoute: RouteRecordRaw = {
path: '/:path(.*)*', path: '/:path(.*)*',
name: 'ErrorPage', name: 'ErrorPage',
component: Layout, component: Layout,
@@ -23,7 +23,7 @@ export const ErrorPageRoute: AppRouteRecordRaw = {
], ],
}; };
export const RedirectRoute: AppRouteRecordRaw = { export const RedirectRoute: RouteRecordRaw = {
path: '/redirect', path: '/redirect',
name: RedirectName, name: RedirectName,
component: Layout, component: Layout,

View File

@@ -1,5 +1,5 @@
import { adminMenus } from '@/api/system/menu'; import { adminMenus } from '@/api/system/menu';
import { constantRouterIcon } from './router-icons'; import { constantRouterIcon } from './icons';
import { RouteRecordRaw } from 'vue-router'; import { RouteRecordRaw } from 'vue-router';
import { Layout, ParentLayout } from '@/router/constant'; import { Layout, ParentLayout } from '@/router/constant';
import type { AppRouteRecordRaw } from '@/router/types'; import type { AppRouteRecordRaw } from '@/router/types';
@@ -16,13 +16,13 @@ LayoutMap.set('IFRAME', Iframe);
* @param parent * @param parent
* @returns {*} * @returns {*}
*/ */
export const routerGenerator = (routerMap, parent?): any[] => { export const generateRoutes = (routerMap, parent?): any[] => {
return routerMap.map((item) => { return routerMap.map((item) => {
const currentRouter: any = { const currentRoute: any = {
// 路由地址 动态拼接生成如 /dashboard/workplace // 路由地址 动态拼接生成如 /dashboard/workplace
path: `${(parent && parent.path) || ''}/${item.path}`, path: `${(parent && parent.path) ?? ''}/${item.path}`,
// 路由名称,建议唯一 // 路由名称,建议唯一
name: item.name || '', name: item.name ?? '',
// 该路由对应页面的 组件 // 该路由对应页面的 组件
component: item.component, component: item.component,
// meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉) // 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) { if (item.children && item.children.length > 0) {
//如果未定义 redirect 默认第一个子路由为 redirect //如果未定义 redirect 默认第一个子路由为 redirect
!item.redirect && (currentRouter.redirect = `${item.path}/${item.children[0].path}`); !item.redirect && (currentRoute.redirect = `${item.path}/${item.children[0].path}`);
// Recursion // 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>} * @returns {Promise<Router>}
*/ */
export const generatorDynamicRouter = (): Promise<RouteRecordRaw[]> => { export const generateDynamicRoutes = async (): Promise<RouteRecordRaw[]> => {
return new Promise((resolve, reject) => { const result = await adminMenus();
adminMenus() const router = generateRoutes(result);
.then((result) => { asyncImportRoute(router);
const routeList = routerGenerator(result); return router;
asyncImportRoute(routeList);
resolve(routeList);
})
.catch((err) => {
reject(err);
});
});
}; };
/** /**

View File

@@ -1,7 +1,7 @@
import type { RouteRecordRaw } from 'vue-router'; import type { RouteRecordRaw } from 'vue-router';
import { isNavigationFailure, Router } from 'vue-router'; import { isNavigationFailure, Router } from 'vue-router';
import { useUserStoreWidthOut } from '@/store/modules/user'; import { useUser } from '@/store/modules/user';
import { useAsyncRouteStoreWidthOut } from '@/store/modules/asyncRoute'; import { useAsyncRoute } from '@/store/modules/asyncRoute';
import { ACCESS_TOKEN } from '@/store/mutation-types'; import { ACCESS_TOKEN } from '@/store/mutation-types';
import { storage } from '@/utils/Storage'; import { storage } from '@/utils/Storage';
import { PageEnum } from '@/enums/pageEnum'; import { PageEnum } from '@/enums/pageEnum';
@@ -12,8 +12,8 @@ const LOGIN_PATH = PageEnum.BASE_LOGIN;
const whitePathList = [LOGIN_PATH]; // no redirect whitelist const whitePathList = [LOGIN_PATH]; // no redirect whitelist
export function createRouterGuards(router: Router) { export function createRouterGuards(router: Router) {
const userStore = useUserStoreWidthOut(); const userStore = useUser();
const asyncRouteStore = useAsyncRouteStoreWidthOut(); const asyncRouteStore = useAsyncRoute();
router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
const Loading = window['$loading'] || null; const Loading = window['$loading'] || null;
Loading && Loading.start(); Loading && Loading.start();
@@ -51,12 +51,12 @@ export function createRouterGuards(router: Router) {
return; return;
} }
if (asyncRouteStore.getIsDynamicAddedRoute) { if (asyncRouteStore.getIsDynamicRouteAdded) {
next(); next();
return; return;
} }
const userInfo = await userStore.GetInfo(); const userInfo = await userStore.getInfo();
const routes = await asyncRouteStore.generateRoutes(userInfo); 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 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 };
asyncRouteStore.setDynamicAddedRoute(true); asyncRouteStore.setDynamicRouteAdded(true);
next(nextData); next(nextData);
Loading && Loading.finish(); Loading && Loading.finish();
}); });
@@ -84,7 +84,7 @@ export function createRouterGuards(router: Router) {
if (isNavigationFailure(failure)) { if (isNavigationFailure(failure)) {
//console.log('failed navigation', failure) //console.log('failed navigation', failure)
} }
const asyncRouteStore = useAsyncRouteStoreWidthOut(); const asyncRouteStore = useAsyncRoute();
// 在这里设置需要缓存的组件名称 // 在这里设置需要缓存的组件名称
const keepAliveComponents = asyncRouteStore.keepAliveComponents; const keepAliveComponents = asyncRouteStore.keepAliveComponents;
const currentComName: any = to.matched.find((item) => item.name == to.name)?.name; const currentComName: any = to.matched.find((item) => item.name == to.name)?.name;

View File

@@ -1,22 +1,20 @@
import { App } from 'vue'; import { App } from 'vue';
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'; import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import { RedirectRoute } from '@/router/base'; import { RedirectRoute } from '@/router/base';
import { PageEnum } from '@/enums/pageEnum'; import { PageEnum } from '@/enums/pageEnum';
import { createRouterGuards } from './router-guards'; import { createRouterGuards } from './guards';
import type { IModuleType } from './types'; import type { IModuleType } from './types';
const modules = import.meta.glob<IModuleType>('./modules/**/*.ts', { eager: true }); const modules = import.meta.glob<IModuleType>('./modules/**/*.ts', { eager: true });
const routeModuleList: RouteRecordRaw[] = []; const routeModuleList: RouteRecordRaw[] = Object.keys(modules).reduce((list, key) => {
const mod = modules[key].default ?? {};
Object.keys(modules).forEach((key) => {
const mod = modules[key].default || {};
const modList = Array.isArray(mod) ? [...mod] : [mod]; const modList = Array.isArray(mod) ? [...mod] : [mod];
routeModuleList.push(...modList); return [...list, ...modList];
}); }, []);
function sortRoute(a, b) { 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); routeModuleList.sort(sortRoute);
@@ -43,10 +41,10 @@ export const LoginRoute: RouteRecordRaw = {
export const asyncRoutes = [...routeModuleList]; export const asyncRoutes = [...routeModuleList];
//普通路由 无需验证权限 //普通路由 无需验证权限
export const constantRouter: any[] = [LoginRoute, RootRoute, RedirectRoute]; export const constantRouter: RouteRecordRaw[] = [LoginRoute, RootRoute, RedirectRoute];
const router = createRouter({ const router = createRouter({
history: createWebHashHistory(''), history: createWebHistory(),
routes: constantRouter, routes: constantRouter,
strict: true, strict: true,
scrollBehavior: () => ({ left: 0, top: 0 }), scrollBehavior: () => ({ left: 0, top: 0 }),

View File

@@ -1,12 +1,12 @@
import type { RouteRecordRaw, RouteMeta } from 'vue-router'; import type { RouteRecordRaw, RouteMeta } from 'vue-router';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export type Component<T extends any = any> = export type Component<T = any> =
| ReturnType<typeof defineComponent> | ReturnType<typeof defineComponent>
| (() => Promise<typeof import('*.vue')>) | (() => Promise<typeof import('*.vue')>)
| (() => Promise<T>); | (() => Promise<T>);
export interface AppRouteRecordRaw extends Omit<RouteRecordRaw, 'meta'> { export interface AppRouteRecordRaw extends Omit<RouteRecordRaw, 'meta' | 'children'> {
name: string; name: string;
meta: RouteMeta; meta: RouteMeta;
component?: Component | string; component?: Component | string;

View File

@@ -3,7 +3,7 @@ import { defineStore } from 'pinia';
import { RouteRecordRaw } from 'vue-router'; import { RouteRecordRaw } from 'vue-router';
import { store } from '@/store'; import { store } from '@/store';
import { asyncRoutes, constantRouter } from '@/router/index'; import { asyncRoutes, constantRouter } from '@/router/index';
import { generatorDynamicRouter } from '@/router/generator-routers'; import { generateDynamicRoutes } from '@/router/generator';
import { useProjectSetting } from '@/hooks/setting/useProjectSetting'; import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
interface TreeHelperConfig { interface TreeHelperConfig {
@@ -23,9 +23,9 @@ const getConfig = (config: Partial<TreeHelperConfig>) => Object.assign({}, DEFAU
export interface IAsyncRouteState { export interface IAsyncRouteState {
menus: RouteRecordRaw[]; menus: RouteRecordRaw[];
routers: any[]; routers: any[];
addRouters: any[]; routersAdded: any[];
keepAliveComponents: string[]; keepAliveComponents: string[];
isDynamicAddedRoute: boolean; isDynamicRouteAdded: boolean;
} }
function filter<T = any>( function filter<T = any>(
@@ -53,54 +53,53 @@ export const useAsyncRouteStore = defineStore({
state: (): IAsyncRouteState => ({ state: (): IAsyncRouteState => ({
menus: [], menus: [],
routers: constantRouter, routers: constantRouter,
addRouters: [], routersAdded: [],
keepAliveComponents: [], keepAliveComponents: [],
// Whether the route has been dynamically added // Whether the route has been dynamically added
isDynamicAddedRoute: false, isDynamicRouteAdded: false,
}), }),
getters: { getters: {
getMenus(): RouteRecordRaw[] { getMenus(): RouteRecordRaw[] {
return this.menus; return this.menus;
}, },
getIsDynamicAddedRoute(): boolean { getIsDynamicRouteAdded(): boolean {
return this.isDynamicAddedRoute; return this.isDynamicRouteAdded;
}, },
}, },
actions: { actions: {
getRouters() { getRouters() {
return toRaw(this.addRouters); return toRaw(this.routersAdded);
}, },
setDynamicAddedRoute(added: boolean) { setDynamicRouteAdded(added: boolean) {
this.isDynamicAddedRoute = added; this.isDynamicRouteAdded = added;
}, },
// 设置动态路由 // 设置动态路由
setRouters(routers) { setRouters(routers: RouteRecordRaw[]) {
this.addRouters = routers; this.routersAdded = routers;
this.routers = constantRouter.concat(routers); this.routers = constantRouter.concat(routers);
}, },
setMenus(menus) { setMenus(menus: RouteRecordRaw[]) {
// 设置动态路由 // 设置动态路由
this.menus = menus; this.menus = menus;
}, },
setKeepAliveComponents(compNames) { setKeepAliveComponents(compNames: string[]) {
// 设置需要缓存的组件 // 设置需要缓存的组件
this.keepAliveComponents = compNames; this.keepAliveComponents = compNames;
}, },
async generateRoutes(data) { async generateRoutes(data) {
let accessedRouters; let accessedRouters;
const permissionsList = data.permissions || []; const permissionsList = data.permissions ?? [];
const routeFilter = (route) => { const routeFilter = (route) => {
const { meta } = route; const { meta } = route;
const { permissions } = meta || {}; const { permissions } = meta || {};
if (!permissions) return true; if (!permissions) return true;
return permissionsList.some((item) => permissions.includes(item.value)); return permissionsList.some((item) => permissions.includes(item.value));
}; };
const { getPermissionMode } = useProjectSetting(); const { permissionMode } = useProjectSetting();
const permissionMode = unref(getPermissionMode); if (unref(permissionMode) === 'BACK') {
if (permissionMode === 'BACK') {
// 动态获取菜单 // 动态获取菜单
try { try {
accessedRouters = await generatorDynamicRouter(); accessedRouters = await generateDynamicRoutes();
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
@@ -121,6 +120,6 @@ export const useAsyncRouteStore = defineStore({
}); });
// Need to be used outside the setup // Need to be used outside the setup
export function useAsyncRouteStoreWidthOut() { export function useAsyncRoute() {
return useAsyncRouteStore(store); return useAsyncRouteStore(store);
} }

View File

@@ -35,6 +35,6 @@ export const useDesignSettingStore = defineStore({
}); });
// Need to be used outside the setup // Need to be used outside the setup
export function useDesignSettingWithOut() { export function useDesignSetting() {
return useDesignSettingStore(store); return useDesignSettingStore(store);
} }

View File

@@ -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,
};

View File

@@ -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;
},
},
});

View File

@@ -1,7 +1,6 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { store } from '@/store';
import projectSetting from '@/settings/projectSetting'; import projectSetting from '@/settings/projectSetting';
import type { IheaderSetting, ImenuSetting, ImultiTabsSetting, IcrumbsSetting } from '/#/config'; import type { IHeaderSetting, IMenuSetting, IMultiTabsSetting, ICrumbsSetting } from '/#/config';
const { const {
navMode, navMode,
@@ -20,11 +19,11 @@ const {
interface ProjectSettingState { interface ProjectSettingState {
navMode: string; //导航模式 navMode: string; //导航模式
navTheme: string; //导航风格 navTheme: string; //导航风格
headerSetting: IheaderSetting; //顶部设置 headerSetting: IHeaderSetting; //顶部设置
showFooter: boolean; //页脚 showFooter: boolean; //页脚
menuSetting: ImenuSetting; //多标签 menuSetting: IMenuSetting; //多标签
multiTabsSetting: ImultiTabsSetting; //多标签 multiTabsSetting: IMultiTabsSetting; //多标签
crumbsSetting: IcrumbsSetting; //面包屑 crumbsSetting: ICrumbsSetting; //面包屑
permissionMode: string; //权限模式 permissionMode: string; //权限模式
isPageAnimate: boolean; //是否开启路由动画 isPageAnimate: boolean; //是否开启路由动画
pageAnimateType: string; //路由动画类型 pageAnimateType: string; //路由动画类型
@@ -90,8 +89,3 @@ export const useProjectSettingStore = defineStore({
}, },
}, },
}); });
// Need to be used outside the setup
export function useProjectSettingStoreWithOut() {
return useProjectSettingStore(store);
}

View 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;
},
},
});

View File

@@ -30,11 +30,11 @@ export const useTabsViewStore = defineStore({
}), }),
getters: {}, getters: {},
actions: { actions: {
initTabs(routes) { initTabs(routes: RouteItem[]) {
// 初始化标签页 // 初始化标签页
this.tabsList = routes; this.tabsList = routes;
}, },
addTabs(route): boolean { addTab(route: RouteItem): boolean {
// 添加标签页 // 添加标签页
if (whiteList.includes(route.name)) return false; if (whiteList.includes(route.name)) return false;
const isExists = this.tabsList.some((item) => item.fullPath == route.fullPath); const isExists = this.tabsList.some((item) => item.fullPath == route.fullPath);
@@ -43,28 +43,29 @@ export const useTabsViewStore = defineStore({
} }
return true; return true;
}, },
closeLeftTabs(route) { closeLeftTabs(route: RouteItem) {
// 关闭左侧 // 关闭左侧
const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath); const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
this.tabsList = this.tabsList.filter((item, i) => i >= index || (item?.meta?.affix ?? false)); 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); const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
this.tabsList = this.tabsList.filter((item, i) => i <= index || (item?.meta?.affix ?? false)); 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); const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
this.tabsList.splice(index, 1); this.tabsList.splice(index, 1);
}, },
closeAllTabs() { closeAllTabs() {
// 关闭全部 // 关闭全部
console.log(retainAffixRoute(this.tabsList));
this.tabsList = retainAffixRoute(this.tabsList); this.tabsList = retainAffixRoute(this.tabsList);
}, },
}, },

View File

@@ -1,18 +1,24 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { store } from '@/store'; 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 { 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'; import { storage } from '@/utils/Storage';
export type UserInfoType = {
// TODO: add your own data
name: string;
email: string;
};
export interface IUserState { export interface IUserState {
token: string; token: string;
username: string; username: string;
welcome: string; welcome: string;
avatar: string; avatar: string;
permissions: any[]; permissions: any[];
info: any; info: UserInfoType;
} }
export const useUserStore = defineStore({ export const useUserStore = defineStore({
@@ -38,7 +44,7 @@ export const useUserStore = defineStore({
getPermissions(): [any][] { getPermissions(): [any][] {
return this.permissions; return this.permissions;
}, },
getUserInfo(): object { getUserInfo(): UserInfoType {
return this.info; return this.info;
}, },
}, },
@@ -52,63 +58,49 @@ export const useUserStore = defineStore({
setPermissions(permissions) { setPermissions(permissions) {
this.permissions = permissions; this.permissions = permissions;
}, },
setUserInfo(info) { setUserInfo(info: UserInfoType) {
this.info = info; this.info = info;
}, },
// 登录 // 登录
async login(userInfo) { async login(params: any) {
try { const response = await login(params);
const response = await login(userInfo); const { result, code } = response;
const { result, code } = response; if (code === ResultEnum.SUCCESS) {
if (code === ResultEnum.SUCCESS) { const ex = 7 * 24 * 60 * 60;
const ex = 7 * 24 * 60 * 60; storage.set(ACCESS_TOKEN, result.token, ex);
storage.set(ACCESS_TOKEN, result.token, ex); storage.set(CURRENT_USER, result, ex);
storage.set(CURRENT_USER, result, ex); storage.set(IS_SCREENLOCKED, false);
storage.set(IS_LOCKSCREEN, false); this.setToken(result.token);
this.setToken(result.token); this.setUserInfo(result);
this.setUserInfo(result);
}
return Promise.resolve(response);
} catch (e) {
return Promise.reject(e);
} }
return response;
}, },
// 获取用户信息 // 获取用户信息
GetInfo() { async getInfo() {
const that = this; const result = await getUserInfoApi();
return new Promise((resolve, reject) => { if (result.permissions && result.permissions.length) {
getUserInfo() const permissionsList = result.permissions;
.then((res) => { this.setPermissions(permissionsList);
const result = res; this.setUserInfo(result);
if (result.permissions && result.permissions.length) { } else {
const permissionsList = result.permissions; throw new Error('getInfo: permissionsList must be a non-null array !');
that.setPermissions(permissionsList); }
that.setUserInfo(result); this.setAvatar(result.avatar);
} else { return result;
reject(new Error('getInfo: permissionsList must be a non-null array !'));
}
that.setAvatar(result.avatar);
resolve(res);
})
.catch((error) => {
reject(error);
});
});
}, },
// 登出 // 登出
async logout() { async logout() {
this.setPermissions([]); this.setPermissions([]);
this.setUserInfo(''); this.setUserInfo({ name: '', email: '' });
storage.remove(ACCESS_TOKEN); storage.remove(ACCESS_TOKEN);
storage.remove(CURRENT_USER); storage.remove(CURRENT_USER);
return Promise.resolve('');
}, },
}, },
}); });
// Need to be used outside the setup // Need to be used outside the setup
export function useUserStoreWidthOut() { export function useUser() {
return useUserStore(store); return useUserStore(store);
} }

View File

@@ -1,4 +1,4 @@
export const ACCESS_TOKEN = 'ACCESS-TOKEN'; // 用户token export const ACCESS_TOKEN = 'ACCESS-TOKEN'; // 用户token
export const CURRENT_USER = 'CURRENT-USER'; // 当前用户信息 export const CURRENT_USER = 'CURRENT-USER'; // 当前用户信息
export const IS_LOCKSCREEN = 'IS-LOCKSCREEN'; // 是否锁屏 export const IS_SCREENLOCKED = 'IS-SCREENLOCKED'; // 是否锁屏
export const TABS_ROUTES = 'TABS-ROUTES'; // 标签页 export const TABS_ROUTES = 'TABS-ROUTES'; // 标签页

View File

@@ -1,12 +1,12 @@
import { IAsyncRouteState } from '@/store/modules/asyncRoute'; import { IAsyncRouteState } from '@/store/modules/asyncRoute';
import { IUserState } from '@/store/modules/user'; import { IUserState } from '@/store/modules/user';
import { ILockscreenState } from '@/store/modules/lockscreen'; import { IScreenLockState } from '@/store/modules/screenLock';
import { ITabsViewState } from '@/store/modules/tabsView'; import { ITabsViewState } from '@/store/modules/tabsView';
export interface IStore { export interface IStore {
asyncRoute: IAsyncRouteState; asyncRoute: IAsyncRouteState;
user: IUserState; user: IUserState;
lockscreen: ILockscreenState; screenLock: IScreenLockState;
tabsView: ITabsViewState; tabsView: ITabsViewState;
count: number; count: number;
} }

View File

@@ -6,122 +6,119 @@ const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7;
* @param {string=} prefixKey - * @param {string=} prefixKey -
* @param {Object} [storage=localStorage] - sessionStorage | localStorage * @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();
}
/** /**
* 本地缓存 * @description 设置缓存
* @class Storage * @param {string} key 缓存键
* @param {*} value 缓存值
* @param expire
*/ */
const Storage = class { set(key: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) {
private storage = storage; const stringData = JSON.stringify({
private prefixKey?: string = prefixKey; 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(); * 读取缓存
} * @param {string} key 缓存键
* @param {*=} def 默认值
/** */
* @description 设置缓存 get(key: string, def: any = null) {
* @param {string} key 缓存键 const item = this.storage.getItem(this.getKey(key));
* @param {*} value 缓存值 if (item) {
* @param expire try {
*/ const data = JSON.parse(item);
set(key: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) { const { value, expire } = data;
const stringData = JSON.stringify({ // 在有效期内直接返回
value, if (expire === null || expire >= Date.now()) {
expire: expire !== null ? new Date().getTime() + expire * 1000 : null, return value;
});
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();
} }
this.remove(key);
} catch (e) {
return def;
} }
} }
}; return def;
return new Storage(); }
};
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('');

View File

@@ -15,7 +15,7 @@ import { setObjToUrlParams } from '@/utils/urlUtils';
import { RequestOptions, Result, CreateAxiosOptions } from './types'; import { RequestOptions, Result, CreateAxiosOptions } from './types';
import { useUserStoreWidthOut } from '@/store/modules/user'; import { useUser } from '@/store/modules/user';
const globSetting = useGlobSetting(); const globSetting = useGlobSetting();
const urlPrefix = globSetting.urlPrefix || ''; const urlPrefix = globSetting.urlPrefix || '';
@@ -176,7 +176,7 @@ const transform: AxiosTransform = {
*/ */
requestInterceptors: (config, options) => { requestInterceptors: (config, options) => {
// 请求之前处理config // 请求之前处理config
const userStore = useUserStoreWidthOut(); const userStore = useUser();
const token = userStore.getToken; const token = userStore.getToken;
if (token && (config as Recordable)?.requestOptions?.withToken !== false) { if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
// jwt token // jwt token

View File

@@ -1,10 +1,6 @@
module.exports = { module.exports = {
// darkMode: 'class',
plugins: [createEnterPlugin()], plugins: [createEnterPlugin()],
content: { content: ['./index.html', './src/**/*.{vue,ts,tsx}'],
enable: process.env.NODE_ENV === 'production',
content: ['./index.html', './src/**/*.{vue,ts,tsx}'],
},
corePlugins: { corePlugins: {
preflight: false, preflight: false,
}, },

10
types/config.d.ts vendored
View File

@@ -17,17 +17,17 @@ export interface ProjectSettingState {
permissionMode: string; permissionMode: string;
} }
export interface IbodySetting { export interface IBodySetting {
fixed: boolean; fixed: boolean;
} }
export interface IheaderSetting { export interface IHeaderSetting {
bgColor: string; bgColor: string;
fixed: boolean; fixed: boolean;
isReload: boolean; isReload: boolean;
} }
export interface ImenuSetting { export interface IMenuSetting {
minMenuWidth: number; minMenuWidth: number;
menuWidth: number; menuWidth: number;
fixed: boolean; fixed: boolean;
@@ -36,12 +36,12 @@ export interface ImenuSetting {
mobileWidth: number; mobileWidth: number;
} }
export interface IcrumbsSetting { export interface ICrumbsSetting {
show: boolean; show: boolean;
showIcon: boolean; showIcon: boolean;
} }
export interface ImultiTabsSetting { export interface IMultiTabsSetting {
bgColor: string; bgColor: string;
fixed: boolean; fixed: boolean;
show: boolean; show: boolean;