1. 后端新增menu字段接口和route权限字段,重构权限接口返回菜单树 2. 前端替换硬编码侧边菜单为动态渲染,新增菜单store和图标映射逻辑 3. 调整权限路由元信息和初始化权限数据
112 lines
2.4 KiB
TypeScript
112 lines
2.4 KiB
TypeScript
import { defineStore } from "pinia";
|
|
import { computed, ref } from "vue";
|
|
import { http } from "@/modules/admin/api/http";
|
|
|
|
export type UserProfile = {
|
|
id: number;
|
|
username: string;
|
|
nickname: string;
|
|
email?: string | null;
|
|
phone?: string | null;
|
|
role_id: number;
|
|
};
|
|
|
|
export type Permission = {
|
|
id: number;
|
|
name: string;
|
|
code: string;
|
|
parentid: number;
|
|
description?: string | null;
|
|
};
|
|
|
|
export type MenuItem = {
|
|
id: number;
|
|
name: string;
|
|
code: string;
|
|
parentid: number;
|
|
route: string;
|
|
description?: string;
|
|
children: MenuItem[];
|
|
};
|
|
|
|
export type RolePermissionResponse = {
|
|
role_id: number;
|
|
role_name: string;
|
|
permissions: Permission[];
|
|
menu: MenuItem[];
|
|
};
|
|
|
|
export const useAuthStore = defineStore("auth", () => {
|
|
const token = ref<string>(localStorage.getItem("access_token") || "");
|
|
const user = ref<UserProfile | null>(null);
|
|
const permissions = ref<Permission[]>([]);
|
|
const menu = ref<MenuItem[]>([]);
|
|
|
|
const isAuthenticated = computed(() => Boolean(token.value));
|
|
|
|
const permissionCodes = computed(() => permissions.value.map(p => p.code));
|
|
|
|
function setToken(t: string) {
|
|
token.value = t;
|
|
if (t) {
|
|
localStorage.setItem("access_token", t);
|
|
} else {
|
|
localStorage.removeItem("access_token");
|
|
}
|
|
}
|
|
|
|
async function fetchProfile() {
|
|
const { data } = await http.get<UserProfile>("/users/me");
|
|
user.value = data;
|
|
return data;
|
|
}
|
|
|
|
async function fetchPermissions() {
|
|
const { data } = await http.get<RolePermissionResponse>("/permissions/user/me");
|
|
permissions.value = data.permissions || [];
|
|
menu.value = data.menu || [];
|
|
return { permissions: permissions.value, menu: menu.value };
|
|
}
|
|
|
|
async function loginAndFetchData() {
|
|
await fetchProfile();
|
|
await fetchPermissions();
|
|
}
|
|
|
|
function hasPermission(code: string): boolean {
|
|
return permissionCodes.value.includes(code);
|
|
}
|
|
|
|
function hasAnyPermission(codes: string[]): boolean {
|
|
return codes.some(code => permissionCodes.value.includes(code));
|
|
}
|
|
|
|
async function logout() {
|
|
try {
|
|
await http.post("/users/logout");
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
user.value = null;
|
|
permissions.value = [];
|
|
menu.value = [];
|
|
setToken("");
|
|
}
|
|
|
|
return {
|
|
token,
|
|
user,
|
|
permissions,
|
|
menu,
|
|
permissionCodes,
|
|
isAuthenticated,
|
|
setToken,
|
|
fetchProfile,
|
|
fetchPermissions,
|
|
loginAndFetchData,
|
|
hasPermission,
|
|
hasAnyPermission,
|
|
logout,
|
|
};
|
|
});
|