import { defineStore } from 'pinia' import { ref, computed } from 'vue' import { login as loginApi } from '@/api/modules/system' import { SESSION_TIMEOUT } from '@/constants' import type { PermissionCode, SystemUser } from '@/types' import { clearSessionActivity, sessionActivityTime, startSessionActivity, syncSessionActivity, touchSessionActivity, } from '@/utils/sessionActivity' const USER_STORAGE_KEY = 'currentUser' const allPermissions: PermissionCode[] = [ 'dashboard', 'fine-tune', 'model-eval', 'model-inference', 'model-manage', 'dataset', 'data-process', 'data-convert', 'compute', 'hardware', 'logs', 'user-settings', ] function restoreUser(): SystemUser | null { const persisted = localStorage.getItem(USER_STORAGE_KEY) if (persisted) { try { return JSON.parse(persisted) as SystemUser } catch { localStorage.removeItem(USER_STORAGE_KEY) } } // 兼容改造前已经登录的 admin 会话。 if (localStorage.getItem('username') === 'admin') { return { id: 'USR-0001', username: 'admin', display_name: '系统管理员', role: 'admin', status: 'active', permissions: allPermissions, create_time: '2026-01-01T08:00:00+08:00', protected: true, } } return null } /** * 认证 store * 沿用原项目 localStorage 的登录时间戳 + 5 分钟会话超时机制 */ export const useAuthStore = defineStore('auth', () => { const currentUser = ref(restoreUser()) const username = computed(() => currentUser.value?.username || '') const displayName = computed(() => currentUser.value?.display_name || username.value) const roleLabel = computed(() => { if (currentUser.value?.role === 'admin') return '超级管理员' if (currentUser.value?.role === 'operator') return '操作员' return '观察员' }) const loginTime = sessionActivityTime const isLoggedIn = computed(() => { if (!loginTime.value) return false return Date.now() - loginTime.value < SESSION_TIMEOUT }) /** 登录 */ async function login(user: string, password: string) { const response = await loginApi(user, password) currentUser.value = response.user startSessionActivity() localStorage.setItem('username', response.user.username) localStorage.setItem(USER_STORAGE_KEY, JSON.stringify(response.user)) } /** 检查当前账号是否拥有指定模块权限。 */ function hasPermission(permission?: PermissionCode) { if (!permission) return true return currentUser.value?.permissions.includes(permission) ?? false } /** 续期会话(活跃时刷新) */ function refresh() { if (currentUser.value) touchSessionActivity() } /** 在路由判断前吸收其他标签页写入的最后活跃时间。 */ function syncSession() { syncSessionActivity() } /** 退出 */ function logout() { currentUser.value = null clearSessionActivity() localStorage.removeItem('username') localStorage.removeItem(USER_STORAGE_KEY) } return { currentUser, username, displayName, roleLabel, loginTime, isLoggedIn, hasPermission, login, refresh, syncSession, logout, } })