Files
YG_FT/frontend/src/stores/auth.ts
caoxiaozhu e09c6e81df feat: 用户与权限管理
新增 PermissionCode 权限类型与用户/权限 API,路由注册用户设置/创建/权限页与无权访问页并接入权限守卫,AppSidebar 按权限过滤菜单并新增用户设置入口,auth store 与 mock 适配器同步支持用户管理与新登录认证,回归脚本与 npm 脚本注册。
2026-07-14 16:10:50 +08:00

115 lines
3.1 KiB
TypeScript

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'
const USER_STORAGE_KEY = 'currentUser'
const allPermissions: PermissionCode[] = [
'dashboard',
'fine-tune',
'model-eval',
'model-inference',
'model-manage',
'dataset',
'data-process',
'data-convert',
'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<SystemUser | null>(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 = ref<number>(parseInt(localStorage.getItem('loginTime') || '0', 10) || 0)
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
loginTime.value = Date.now()
localStorage.setItem('username', response.user.username)
localStorage.setItem(USER_STORAGE_KEY, JSON.stringify(response.user))
localStorage.setItem('loginTime', String(loginTime.value))
}
/** 检查当前账号是否拥有指定模块权限。 */
function hasPermission(permission?: PermissionCode) {
if (!permission) return true
return currentUser.value?.permissions.includes(permission) ?? false
}
/** 续期会话(活跃时刷新) */
function refresh() {
if (isLoggedIn.value) {
loginTime.value = Date.now()
localStorage.setItem('loginTime', String(loginTime.value))
}
}
/** 退出 */
function logout() {
currentUser.value = null
loginTime.value = 0
localStorage.removeItem('username')
localStorage.removeItem(USER_STORAGE_KEY)
localStorage.removeItem('loginTime')
}
return {
currentUser,
username,
displayName,
roleLabel,
loginTime,
isLoggedIn,
hasPermission,
login,
refresh,
logout,
}
})