Files
kaidi/frontend/src/store/modules/user.ts
T
2026-08-17 23:03:03 +08:00

99 lines
3.2 KiB
TypeScript

import { defineStore } from 'pinia';
import type { RoleView, SessionView, UserView } from '@/api/auth';
import * as authApi from '@/api/auth';
import { usePermissionStore } from '@/store';
import { hasPermissionAccess } from './menu-access';
import { resolveWorkbenchRoute } from './workbench-route';
const emptyUser: UserView = {
publicId: '',
username: '',
displayName: '',
departmentName: '',
mustChangePassword: false,
};
export const useUserStore = defineStore('user', {
state: () => ({
authenticated: false,
user: { ...emptyUser },
roles: [] as RoleView[],
currentRole: null as string | null,
permissions: [] as string[],
sessionExpiresAt: null as string | null,
absoluteSessionExpiresAt: null as string | null,
loading: false,
}),
getters: {
displayName: (state) => state.user.displayName || state.user.username,
roleName: (state) => state.roles.find((role) => role.code === state.currentRole)?.name || '',
workbenchRoute: (state) => resolveWorkbenchRoute(state.currentRole, state.roles),
hasRole: (state) => (roleCode: string) => state.roles.some((role) => role.code === roleCode),
hasPermission: (state) => (permission: string) =>
hasPermissionAccess(state.currentRole, state.permissions, permission),
},
actions: {
applySession(session: SessionView) {
this.authenticated = session.authenticated;
this.user = session.user || { ...emptyUser };
this.roles = session.roles || [];
this.currentRole = session.activeRole || null;
this.permissions = session.permissions || [];
this.sessionExpiresAt = session.sessionExpiresAt || null;
this.absoluteSessionExpiresAt = session.absoluteSessionExpiresAt || null;
},
async login(payload: authApi.LoginRequest) {
this.loading = true;
try {
this.applySession(await authApi.login(payload));
} finally {
this.loading = false;
}
},
async restoreSession() {
if (this.authenticated) return this.user;
const session = await authApi.getSession();
this.applySession(session);
if (!this.authenticated) throw new Error('Session is not authenticated');
return this.user;
},
async refreshProfile() {
this.user = await authApi.getProfile();
return this.user;
},
async selectRole(roleCode: string) {
const session = await authApi.selectRole(roleCode);
this.applySession(session);
const permissionStore = usePermissionStore();
permissionStore.resetForIdentity();
permissionStore.initRoutes();
},
async updatePassword(payload: authApi.PasswordChangeRequest) {
this.applySession(await authApi.changePassword(payload));
},
async logout() {
if (this.authenticated) {
try {
await authApi.logout();
} finally {
this.clearSession();
}
} else {
this.clearSession();
}
},
clearSession() {
this.authenticated = false;
this.user = { ...emptyUser };
this.roles = [];
this.currentRole = null;
this.permissions = [];
this.sessionExpiresAt = null;
this.absoluteSessionExpiresAt = null;
},
},
persist: false,
});