refactor(projects): 精简版+动态路由权限初步

This commit is contained in:
Soybean
2022-01-03 22:20:10 +08:00
parent 7a0648dba5
commit de2057f141
354 changed files with 2053 additions and 22117 deletions

View File

@ -1,45 +0,0 @@
import type { RouteLocationNormalizedLoaded } from 'vue-router';
import { ROUTE_HOME } from '@/router';
import { brightenColor, darkenColor } from '@/utils';
import type { MultiTabRoute } from '@/interface';
export function getHoverAndPressedColor(color: string) {
return {
hover: brightenColor(color),
pressed: darkenColor(color)
};
}
/** 获取路由首页信息 */
export function getHomeTabRoute(route: RouteLocationNormalizedLoaded) {
const { name, path, meta } = ROUTE_HOME;
const isHome = route.name === ROUTE_HOME.name;
const home: MultiTabRoute = {
name,
path,
fullPath: path,
meta
};
if (isHome) {
Object.assign(home, route);
}
return home;
}
/**
* 获取该页签在多页签数据中的索引
* @param routes - 多页签数据
* @param fullPath - 该页签的路径
*/
export function getIndexInTabRoutes(routes: MultiTabRoute[], fullPath: string) {
return routes.findIndex(route => route.fullPath === fullPath);
}
/**
* 判断该页签是否在多页签数据中
* @param routes - 多页签数据
* @param fullPath - 该页签的路径
*/
export function isInTabRoutes(routes: MultiTabRoute[], fullPath: string) {
return getIndexInTabRoutes(routes, fullPath) > -1;
}

View File

@ -1,203 +1,25 @@
import { nextTick } from 'vue';
import type { RouteLocationNormalizedLoaded } from 'vue-router';
import type { ScrollbarInst } from 'naive-ui';
import type { Ref } from 'vue';
import { defineStore } from 'pinia';
import { router, ROUTE_HOME } from '@/router';
import { store, useThemeStore } from '@/store';
import { getTabRouteStorage } from '@/utils';
import type { MultiTab, MultiTabRoute } from '@/interface';
import { getHomeTabRoute, isInTabRoutes } from './helpers';
import { useReload } from '@/hooks';
/** app状态 */
interface AppState {
layout: LayoutState;
menu: MenuState;
multiTab: MultiTab;
/** 重新加载标记 */
reloadFlag: boolean;
settingDrawer: SettingDrawer;
interface AppStore {
/** 重载页面的标志 */
reloadFlag: Ref<boolean>;
/**
* 触发重载页面
* @param duration - 延迟时间(ms, 默认0)
*/
handleReload(duration?: number): void;
}
/** 布局状态 */
interface LayoutState {
scrollbar: ScrollbarInst | null;
}
export const useAppStore = defineStore('app-store', () => {
// 重新加载页面
const { reloadFlag, handleReload } = useReload();
/** 菜单状态 */
interface MenuState {
/** 菜单折叠 */
collapsed: boolean;
/** 混合菜单vertical-mix是否固定二级菜单 */
fixedMix: boolean;
}
const appStore: AppStore = {
reloadFlag,
handleReload
};
/** 项目配置抽屉的状态 */
interface SettingDrawer {
/** 设置抽屉可见性 */
visible: boolean;
}
const appStore = defineStore({
id: 'app-store',
state: (): AppState => ({
layout: {
scrollbar: null
},
menu: {
collapsed: false,
fixedMix: false
},
multiTab: {
routes: [],
activeRoute: ''
},
reloadFlag: true,
settingDrawer: {
visible: false
}
}),
getters: {
activeMultiTabIndex(state) {
const { routes, activeRoute } = state.multiTab;
return routes.findIndex(v => v.fullPath === activeRoute);
}
},
actions: {
/** 设置scrollbar的实例 */
setScrollbarInstance(scrollbar: ScrollbarInst) {
this.layout.scrollbar = scrollbar;
},
/** 重置滚动条行为 */
resetScrollBehavior() {
const { scrollbar } = this.layout;
setTimeout(() => {
scrollbar?.scrollTo({ left: 0, top: 0 });
}, 250);
},
/** 折叠/展开菜单 */
handleMenuCollapse(collapsed: boolean) {
this.menu.collapsed = collapsed;
},
/** 设置混合菜单是否固定 */
toggleFixedMixMenu() {
this.menu.fixedMix = !this.menu.fixedMix;
},
/** 切换折叠/展开菜单 */
toggleMenu() {
this.menu.collapsed = !this.menu.collapsed;
},
/** 添加多页签的数据 */
addMultiTab(route: RouteLocationNormalizedLoaded) {
const { fullPath } = route;
const isExist = isInTabRoutes(this.multiTab.routes, fullPath);
if (!isExist) {
this.multiTab.routes.push({ ...route });
}
},
/** 删除多页签的数据 */
removeMultiTab(fullPath: string) {
const isActive = this.multiTab.activeRoute === fullPath;
const { routes } = this.multiTab;
const updateRoutes = routes.filter(v => v.fullPath !== fullPath);
this.multiTab.routes = updateRoutes;
if (isActive) {
const activePath = updateRoutes[updateRoutes.length - 1].fullPath;
router.push(activePath);
this.setActiveMultiTab(activePath);
}
},
/**
* 删除所有多页签只保留路由首页
* @param exclude - 保留的多页签
*/
clearMultiTab(exclude: string[] = []) {
const remain = [ROUTE_HOME.path, ...exclude];
const { routes } = this.multiTab;
const updateRoutes = routes.filter(v => remain.includes(v.fullPath));
this.multiTab.routes = updateRoutes;
const activePath = updateRoutes[updateRoutes.length - 1].fullPath;
router.push(activePath);
this.setActiveMultiTab(activePath);
},
/** 删除左边多页签 */
clearLeftMultiTab(fullPath: string) {
const { routes } = this.multiTab;
const currentIndex = routes.findIndex(route => route.fullPath === fullPath);
const activeIndex = this.activeMultiTabIndex;
if (currentIndex > -1) {
const remain = [ROUTE_HOME.path, ...routes.slice(currentIndex).map(v => v.fullPath)];
const updateRoutes = routes.filter(v => remain.includes(v.fullPath));
this.multiTab.routes = updateRoutes;
if (activeIndex < currentIndex) {
const activePath = updateRoutes[updateRoutes.length - 1].fullPath;
router.push(activePath);
this.setActiveMultiTab(activePath);
}
}
},
/** 删除右边多页签 */
clearRightMultiTab(fullPath: string) {
const { routes } = this.multiTab;
const currentIndex = routes.findIndex(route => route.fullPath === fullPath);
const activeIndex = this.activeMultiTabIndex;
if (currentIndex > -1) {
const remain = [ROUTE_HOME.path, ...routes.slice(0, currentIndex + 1).map(v => v.fullPath)];
const updateRoutes = routes.filter(v => remain.includes(v.fullPath));
this.multiTab.routes = updateRoutes;
if (activeIndex > currentIndex) {
router.push(fullPath);
this.setActiveMultiTab(fullPath);
}
}
},
/** 点击单个页签tab */
handleClickTab(fullPath: string) {
if (this.multiTab.activeRoute !== fullPath) {
router.push(fullPath);
this.setActiveMultiTab(fullPath);
}
},
/** 设置当前路由对应的页签为激活状态 */
setActiveMultiTab(fullPath: string) {
this.multiTab.activeRoute = fullPath;
},
/** 初始化多页签数据 */
initMultiTab() {
const theme = useThemeStore();
const { currentRoute } = router;
const isHome = currentRoute.value.name === ROUTE_HOME.name;
const home = getHomeTabRoute(currentRoute.value);
const routes: MultiTabRoute[] = theme.multiTabStyle.isCache ? getTabRouteStorage() : [];
const hasHome = isInTabRoutes(routes, home.fullPath);
const hasCurrent = isInTabRoutes(routes, currentRoute.value.fullPath);
if (!hasHome) {
routes.unshift(home);
}
if (!isHome && !hasCurrent) {
routes.push(currentRoute.value);
}
this.multiTab.routes = routes;
this.setActiveMultiTab(currentRoute.value.fullPath);
},
/** 重新加载页面 */
handleReload() {
this.reloadFlag = false;
nextTick(() => {
this.reloadFlag = true;
this.resetScrollBehavior();
});
},
/** 打开配置抽屉 */
openSettingDrawer() {
this.settingDrawer.visible = true;
},
/** 关闭配置抽屉 */
closeSettingDrawer() {
this.settingDrawer.visible = false;
}
}
return appStore;
});
export default function useAppStore() {
return appStore(store);
}