将 menu 从 appstore 提出.

This commit is contained in:
lijiahangmax
2023-09-25 22:05:48 +08:00
parent 80e5e241fa
commit 99d6d16a04
23 changed files with 190 additions and 287 deletions

View File

@@ -1,5 +1,6 @@
import { createPinia } from 'pinia';
import useAppStore from './modules/app';
import useMenuStore from './modules/menu';
import useUserStore from './modules/user';
import useTabBarStore from './modules/tab-bar';
import useCacheStore from './modules/cache';
@@ -8,6 +9,7 @@ const pinia = createPinia();
export {
useAppStore,
useMenuStore,
useUserStore,
useTabBarStore,
useCacheStore

View File

@@ -1,15 +1,10 @@
import { defineStore } from 'pinia';
import { Notification } from '@arco-design/web-vue';
import type { RouteRecordNormalized } from 'vue-router';
import defaultSettings from '@/config/settings.json';
import { getMenuList } from '@/api/user/auth';
import { AppState } from './types';
import router from '@/router';
const useAppStore = defineStore('app', {
export default defineStore('app', {
state: (): AppState => ({
...defaultSettings,
menuFetched: false,
}),
getters: {
@@ -19,23 +14,16 @@ const useAppStore = defineStore('app', {
appDevice(state: AppState) {
return state.device;
},
appAsyncMenus(state: AppState): RouteRecordNormalized[] {
return state.serverMenu as unknown as RouteRecordNormalized[];
},
},
actions: {
/**
* 更新配置
*/
// 更新配置
updateSettings(partial: Partial<AppState>) {
// @ts-ignore-next-line
this.$patch(partial);
this.$patch(partial as object);
console.log(partial);
},
/**
* 修改颜色主题
*/
// 修改颜色主题
toggleTheme(dark: boolean) {
if (dark) {
this.theme = 'dark';
@@ -46,90 +34,14 @@ const useAppStore = defineStore('app', {
}
},
/**
* 切换设备
*/
// 切换设备
toggleDevice(device: string) {
this.device = device;
},
/**
* 切换菜单状态
*/
// 切换菜单状态
toggleMenu(value: boolean) {
this.hideMenu = value;
},
/**
* 加载菜单
*/
async fetchMenuConfig() {
try {
const { data } = await getMenuList();
// @ts-ignore
this.serverMenu = (data as Array<any>).map(s => {
// 转换
const convert = (item: any) => {
// 设置路由属性
const meta = {
locale: item.name,
icon: item.icon,
order: item.sort,
hideInMenu: item.visible === 0,
hideChildrenInMenu: item.visible === 0,
noAffix: item.visible === 0,
ignoreCache: item.cache === 0,
};
// 获取 router
const route = router.getRoutes().find(r => {
return r.name === item.component;
});
// 设置 router meta
if (route) {
// 路由配置覆盖菜单配置
route.meta = { ...meta, ...route.meta };
}
// 返回
return {
name: item.component,
path: item.path,
meta: meta,
children: undefined as unknown
};
};
// 构建父目录
const menu = convert(s);
// 构建子目录
if (s.children) {
menu.children = (s.children as Array<any>).map(convert);
}
return menu;
});
// 是否已加载过
this.menuFetched = true;
// 未配置菜单
if (this.serverMenu.length === 0) {
Notification.error({
content: '该用户未配置菜单, 请先联系管理员配置',
closable: true,
});
}
} catch (error) {
Notification.error({
content: '加载菜单失败',
closable: true,
});
}
},
/**
* 清空菜单
*/
clearMenu() {
this.serverMenu = [];
this.menuFetched = false;
},
},
});
export default useAppStore;

View File

@@ -1,5 +1,3 @@
import type { RouteRecordNormalized } from 'vue-router';
export interface AppState {
theme: string;
colorWeak: boolean;
@@ -9,13 +7,10 @@ export interface AppState {
hideMenu: boolean;
menuCollapse: boolean;
footer: boolean;
themeColor: string;
menuWidth: number;
globalSettings: boolean;
device: string;
tabBar: boolean;
serverMenu: RouteRecordNormalized[];
menuFetched: boolean;
[key: string]: unknown;
}

View File

@@ -3,7 +3,7 @@ import { CacheState } from './types';
export type CacheType = 'menus' | 'roles' | 'tags' | 'hostKeys' | 'hostIdentities'
const useCacheStore = defineStore('cache', {
export default defineStore('cache', {
state: (): CacheState => ({
menus: [],
roles: [],
@@ -15,13 +15,9 @@ const useCacheStore = defineStore('cache', {
getters: {},
actions: {
/**
* 设置
*/
// 设置
set(name: CacheType, value: any) {
this[name] = value;
}
},
});
export default useCacheStore;

View File

@@ -0,0 +1,87 @@
import { defineStore } from 'pinia';
import { Notification } from '@arco-design/web-vue';
import type { RouteRecordNormalized } from 'vue-router';
import { getMenuList } from '@/api/user/auth';
import { MenuState } from './types';
import router from '@/router';
export default defineStore('menu', {
state: (): MenuState => ({
serverMenus: [],
menuFetched: false,
}),
getters: {
appMenus(state: MenuState): RouteRecordNormalized[] {
return state.serverMenus as unknown as RouteRecordNormalized[];
},
},
actions: {
// 加载菜单
async fetchMenu() {
try {
const { data } = await getMenuList();
// @ts-ignore
this.serverMenus = (data as Array<any>).map(s => {
// 转换
const convert = (item: any) => {
// 设置路由属性
const meta = {
locale: item.name,
icon: item.icon,
order: item.sort,
hideInMenu: item.visible === 0,
hideChildrenInMenu: item.visible === 0,
noAffix: item.visible === 0,
ignoreCache: item.cache === 0,
};
// 获取 router
const route = router.getRoutes().find(r => {
return r.name === item.component;
});
// 设置 router meta
if (route) {
// 路由配置覆盖菜单配置
route.meta = { ...meta, ...route.meta };
}
// 返回
return {
name: item.component,
path: item.path,
meta: meta,
children: undefined as unknown
};
};
// 构建父目录
const menu = convert(s);
// 构建子目录
if (s.children) {
menu.children = (s.children as Array<any>).map(convert);
}
return menu;
});
// 是否已加载过
this.menuFetched = true;
// 未配置菜单
if (this.serverMenus.length === 0) {
Notification.error({
content: '该用户未配置菜单, 请先联系管理员配置',
closable: true,
});
}
} catch (error) {
Notification.error({
content: '加载菜单失败',
closable: true,
});
}
},
// 清空菜单
clearMenu() {
this.serverMenus = [];
this.menuFetched = false;
},
},
});

View File

@@ -0,0 +1,6 @@
import type { RouteRecordNormalized } from 'vue-router';
export interface MenuState {
serverMenus: RouteRecordNormalized[];
menuFetched: boolean;
}

View File

@@ -3,7 +3,7 @@ import { DEFAULT_ROUTE_NAME, DEFAULT_TAB } from '@/router/constants';
import { isString } from '@/utils/is';
import { TabBarState, TagProps } from './types';
const useTabBarStore = defineStore('tabBar', {
export default defineStore('tabBar', {
state: (): TabBarState => ({
cacheTabList: new Set([DEFAULT_ROUTE_NAME]),
tagList: [DEFAULT_TAB],
@@ -19,9 +19,7 @@ const useTabBarStore = defineStore('tabBar', {
},
actions: {
/**
* 添加 tab
*/
// 添加 tab
addTab(tag: TagProps, ignoreCache: boolean) {
this.tagList.push(tag);
if (!ignoreCache) {
@@ -29,31 +27,23 @@ const useTabBarStore = defineStore('tabBar', {
}
},
/**
* 移除 tab
*/
// 移除 tab
deleteTab(idx: number, tag: TagProps) {
this.tagList.splice(idx, 1);
this.cacheTabList.delete(tag.name);
},
/**
* 添加缓存
*/
// 添加缓存
addCache(name: string) {
if (isString(name) && name !== '') this.cacheTabList.add(name);
},
/**
* 删除缓存
*/
// 删除缓存
deleteCache(tag: TagProps) {
this.cacheTabList.delete(tag.name);
},
/**
* 重设缓存
*/
// 重设缓存
freshTabList(tags: TagProps[]) {
this.tagList = tags;
this.cacheTabList.clear();
@@ -63,9 +53,7 @@ const useTabBarStore = defineStore('tabBar', {
.forEach((x) => this.cacheTabList.add(x));
},
/**
* 重设 tab
*/
// 重设 tab
resetTabList() {
this.tagList = [DEFAULT_TAB];
this.cacheTabList.clear();
@@ -73,5 +61,3 @@ const useTabBarStore = defineStore('tabBar', {
},
},
});
export default useTabBarStore;

View File

@@ -4,9 +4,9 @@ import { clearToken, setToken } from '@/utils/auth';
import { md5 } from '@/utils';
import { removeRouteListener } from '@/utils/route-listener';
import { UserState } from './types';
import useAppStore from '../app';
import { useMenuStore, useTabBarStore } from '@/store';
const useUserStore = defineStore('user', {
export default defineStore('user', {
state: (): UserState => ({
id: undefined,
username: undefined,
@@ -23,16 +23,12 @@ const useUserStore = defineStore('user', {
},
actions: {
/**
* 设置用户信息
*/
// 设置用户信息
setInfo(partial: Partial<UserState>) {
this.$patch(partial);
},
/**
* 获取用户信息
*/
// 获取用户信息
async info() {
const { data } = await getUserPermission();
this.setInfo({
@@ -45,9 +41,7 @@ const useUserStore = defineStore('user', {
});
},
/**
* 登录
*/
// 登录
async login(loginForm: LoginRequest) {
try {
const loginRequest: LoginRequest = {
@@ -64,9 +58,7 @@ const useUserStore = defineStore('user', {
}
},
/**
* 登出
*/
// 登出
async logout() {
try {
await userLogout();
@@ -77,19 +69,18 @@ const useUserStore = defineStore('user', {
}
},
/**
* 登出回调
*/
// 登出回调
logoutCallBack() {
this.$reset();
clearToken();
// 移除路由监听器
removeRouteListener();
// 清空菜单
const appStore = useAppStore();
appStore.clearMenu();
const menuStore = useMenuStore();
menuStore.clearMenu();
// 清除 tabs
const tabBarStore = useTabBarStore();
tabBarStore.resetTabList();
},
},
});
export default useUserStore;