forked from jiaoly/financial_system
103 lines
2.9 KiB
TypeScript
103 lines
2.9 KiB
TypeScript
import { defineStore } from "pinia";
|
|
|
|
import {
|
|
clearStoredToken,
|
|
getStoredToken,
|
|
setStoredToken,
|
|
} from "../api/http";
|
|
import {
|
|
changePassword as changePasswordRequest,
|
|
getCurrentUser,
|
|
login as loginRequest,
|
|
updateProfile as updateProfileRequest,
|
|
uploadAvatar as uploadAvatarRequest,
|
|
} from "../api/auth";
|
|
import type { ChangePasswordRequest, MenuItem, UpdateProfileRequest, UserProfile } from "../api/types";
|
|
|
|
interface AuthState {
|
|
token: string;
|
|
user: UserProfile | null;
|
|
menus: MenuItem[];
|
|
permissions: string[];
|
|
loaded: boolean;
|
|
}
|
|
|
|
export const useAuthStore = defineStore("auth", {
|
|
state: (): AuthState => ({
|
|
token: getStoredToken(),
|
|
user: null,
|
|
menus: [],
|
|
permissions: [],
|
|
loaded: false,
|
|
}),
|
|
getters: {
|
|
isAuthenticated: (state) => Boolean(state.token),
|
|
displayName: (state) => state.user?.display_name || state.user?.username || "未登录",
|
|
roleLabel: (state) => roleLabel(state.user?.role || ""),
|
|
},
|
|
actions: {
|
|
hasPermission(permission: string): boolean {
|
|
return this.permissions.includes(permission);
|
|
},
|
|
async login(username: string, password: string): Promise<void> {
|
|
const session = await loginRequest(username, password);
|
|
this.token = session.access_token;
|
|
this.user = session.user;
|
|
this.menus = session.menus;
|
|
this.permissions = session.permissions;
|
|
this.loaded = true;
|
|
setStoredToken(session.access_token);
|
|
},
|
|
async loadSession(): Promise<void> {
|
|
if (!this.token) {
|
|
this.loaded = true;
|
|
return;
|
|
}
|
|
try {
|
|
const profile = await getCurrentUser();
|
|
this.user = profile;
|
|
this.menus = profile.menus;
|
|
this.permissions = profile.permissions;
|
|
} catch (error) {
|
|
this.logout();
|
|
throw error;
|
|
} finally {
|
|
this.loaded = true;
|
|
}
|
|
},
|
|
async updateProfile(payload: UpdateProfileRequest): Promise<void> {
|
|
const profile = await updateProfileRequest(payload);
|
|
this.user = profile;
|
|
this.menus = profile.menus;
|
|
this.permissions = profile.permissions;
|
|
},
|
|
async uploadAvatar(file: File): Promise<void> {
|
|
const profile = await uploadAvatarRequest(file);
|
|
this.user = profile;
|
|
this.menus = profile.menus;
|
|
this.permissions = profile.permissions;
|
|
},
|
|
async changePassword(payload: ChangePasswordRequest): Promise<string> {
|
|
const response = await changePasswordRequest(payload);
|
|
return response.message;
|
|
},
|
|
logout(): void {
|
|
this.token = "";
|
|
this.user = null;
|
|
this.menus = [];
|
|
this.permissions = [];
|
|
this.loaded = true;
|
|
clearStoredToken();
|
|
},
|
|
},
|
|
});
|
|
|
|
function roleLabel(role: string): string {
|
|
const labels: Record<string, string> = {
|
|
superuser: "超级用户",
|
|
manager: "管理者",
|
|
viewer: "查看权限",
|
|
};
|
|
return labels[role] || "未授权";
|
|
}
|