前端启动成功

This commit is contained in:
2025-10-07 13:31:06 +08:00
parent 8bd1edc75d
commit 741e89bc62
39 changed files with 19370 additions and 1458 deletions

View File

@@ -1,9 +1,12 @@
import { createStore } from "vuex";
import authModule from './modules/auth';
export default createStore({
state: {},
getters: {},
mutations: {},
actions: {},
modules: {},
modules: {
auth: authModule
},
});

View File

@@ -0,0 +1,270 @@
/**
* @description 认证相关状态管理
* @author yslg
* @since 2025-10-07
*/
import { Module } from 'vuex';
import { LoginDomain, SysMenu, SysPermission } from '@/types';
import { authApi } from '@/apis/auth';
import router from '@/router';
// State接口定义
export interface AuthState {
// 用户信息
loginDomain: LoginDomain | null;
// 用户Token
token: string | null;
// 用户菜单
menus: SysMenu[];
// 用户权限
permissions: SysPermission[];
// 动态路由是否已加载
routesLoaded: boolean;
}
// 认证模块
const authModule: Module<AuthState, any> = {
namespaced: true,
state: (): AuthState => ({
loginDomain: null,
token: localStorage.getItem('token') || null,
menus: [],
permissions: [],
routesLoaded: false,
}),
getters: {
// 是否已登录
isAuthenticated: (state): boolean => {
return !!(state.token && state.loginDomain);
},
// 获取用户信息
userInfo: (state) => {
return state.loginDomain?.user || null;
},
// 获取用户角色
userRoles: (state) => {
return state.loginDomain?.roles || [];
},
// 检查是否有指定权限
hasPermission: (state) => (permissionCode: string): boolean => {
if (!state.permissions || state.permissions.length === 0) {
return false;
}
return state.permissions.some(permission =>
permission.code === permissionCode
);
},
// 检查是否有任意一个权限
hasAnyPermission: (state, getters) => (permissionCodes: string[]): boolean => {
return permissionCodes.some(code => getters.hasPermission(code));
},
// 检查是否有所有权限
hasAllPermissions: (state, getters) => (permissionCodes: string[]): boolean => {
return permissionCodes.every(code => getters.hasPermission(code));
},
// 获取菜单树结构
menuTree: (state): SysMenu[] => {
return buildMenuTree(state.menus);
}
},
mutations: {
// 设置登录信息
SET_LOGIN_DOMAIN(state, loginDomain: LoginDomain) {
state.loginDomain = loginDomain;
state.token = loginDomain.token || null;
state.menus = loginDomain.menus || [];
state.permissions = loginDomain.permissions || [];
// 存储token到localStorage
if (state.token) {
localStorage.setItem('token', state.token);
}
},
// 设置Token
SET_TOKEN(state, token: string | null) {
state.token = token;
if (token) {
localStorage.setItem('token', token);
} else {
localStorage.removeItem('token');
}
},
// 设置菜单
SET_MENUS(state, menus: SysMenu[]) {
state.menus = menus;
},
// 设置权限
SET_PERMISSIONS(state, permissions: SysPermission[]) {
state.permissions = permissions;
},
// 设置路由加载状态
SET_ROUTES_LOADED(state, loaded: boolean) {
state.routesLoaded = loaded;
},
// 清除认证信息
CLEAR_AUTH(state) {
state.loginDomain = null;
state.token = null;
state.menus = [];
state.permissions = [];
state.routesLoaded = false;
localStorage.removeItem('token');
}
},
actions: {
// 登录
async login({ commit, dispatch }, loginParam) {
try {
const loginDomain = await authApi.login(loginParam);
// 保存登录信息
commit('SET_LOGIN_DOMAIN', loginDomain);
// 生成动态路由
await dispatch('generateRoutes');
return Promise.resolve(loginDomain);
} catch (error) {
return Promise.reject(error);
}
},
// 登出
async logout({ commit }) {
try {
await authApi.logout();
} catch (error) {
console.error('登出接口调用失败:', error);
} finally {
// 清除认证信息
commit('CLEAR_AUTH');
// 重置路由
resetRouter();
// 跳转到登录页
router.push('/login');
}
},
// 生成动态路由
async generateRoutes({ state, commit }) {
try {
if (!state.menus || state.menus.length === 0) {
console.warn('用户菜单为空,无法生成路由');
return;
}
// 根据菜单生成路由
const { generateRoutes } = await import('@/utils/route-generator');
const routes = generateRoutes(state.menus);
// 添加路由到router
routes.forEach((route: any) => {
router.addRoute(route);
});
// 标记路由已加载
commit('SET_ROUTES_LOADED', true);
console.log('动态路由生成完成', routes);
} catch (error) {
console.error('生成动态路由失败:', error);
throw error;
}
},
// 刷新Token
async refreshToken({ commit }) {
try {
const newToken = await authApi.refreshToken();
commit('SET_TOKEN', newToken);
return Promise.resolve(newToken);
} catch (error) {
// 刷新失败,清除认证信息
commit('CLEAR_AUTH');
router.push('/login');
return Promise.reject(error);
}
}
}
};
/**
* 构建菜单树结构
* @param menus 菜单列表
* @returns 菜单树
*/
function buildMenuTree(menus: SysMenu[]): SysMenu[] {
if (!menus || menus.length === 0) {
return [];
}
const menuMap = new Map<string, SysMenu>();
const rootMenus: SysMenu[] = [];
// 创建菜单映射
menus.forEach(menu => {
if (menu.menuID) {
menuMap.set(menu.menuID, { ...menu, children: [] });
}
});
// 构建树结构
menus.forEach(menu => {
const menuNode = menuMap.get(menu.menuID!);
if (!menuNode) return;
if (!menu.parentID || menu.parentID === '0') {
// 根菜单
rootMenus.push(menuNode);
} else {
// 子菜单
const parent = menuMap.get(menu.parentID);
if (parent) {
parent.children = parent.children || [];
parent.children.push(menuNode);
}
}
});
// 按orderNum排序
const sortMenus = (menus: SysMenu[]): SysMenu[] => {
return menus
.sort((a, b) => (a.orderNum || 0) - (b.orderNum || 0))
.map(menu => ({
...menu,
children: menu.children ? sortMenus(menu.children) : []
}));
};
return sortMenus(rootMenus);
}
/**
* 重置路由
*/
function resetRouter() {
// 这里需要根据实际路由配置来重置
// 由于Vue Router 4没有直接的重置方法我们需要重新创建router实例
// 或者记录动态添加的路由并逐个移除
location.reload(); // 临时方案,后续可以优化
}
export default authModule;