mirror of
https://github.com/fawney19/Aether.git
synced 2026-01-09 11:12:28 +08:00
108 lines
2.9 KiB
TypeScript
108 lines
2.9 KiB
TypeScript
import { defineStore } from 'pinia'
|
||
import { ref, computed } from 'vue'
|
||
import { authApi, type User } from '@/api/auth'
|
||
import apiClient from '@/api/client'
|
||
import { log } from '@/utils/logger'
|
||
|
||
export const useAuthStore = defineStore('auth', () => {
|
||
// 初始化时从 localStorage 恢复 token
|
||
const storedToken = apiClient.getToken()
|
||
|
||
const user = ref<User | null>(null)
|
||
const token = ref<string | null>(storedToken)
|
||
const loading = ref(false)
|
||
const error = ref<string | null>(null)
|
||
|
||
const isAuthenticated = computed(() => {
|
||
// 使用 store 中的 token 状态判断认证状态
|
||
// 如果需要同步 localStorage,应该在 checkAuth 或专门的 syncToken 方法中处理
|
||
return !!token.value
|
||
})
|
||
|
||
/**
|
||
* 同步 localStorage 中的 token 到 store
|
||
* 用于处理多标签页或外部 token 变更的情况
|
||
*/
|
||
function syncToken() {
|
||
const currentToken = apiClient.getToken()
|
||
if (token.value !== currentToken) {
|
||
token.value = currentToken
|
||
}
|
||
}
|
||
const isAdmin = computed(() => user.value?.role === 'admin')
|
||
|
||
async function login(email: string, password: string, authType: 'local' | 'ldap' = 'local') {
|
||
loading.value = true
|
||
error.value = null
|
||
|
||
try {
|
||
const response = await authApi.login({ email, password, auth_type: authType })
|
||
token.value = response.access_token
|
||
|
||
// 获取用户信息
|
||
const userInfo = await authApi.getCurrentUser()
|
||
user.value = userInfo
|
||
|
||
return true
|
||
} catch (err: any) {
|
||
// 不要暴露后端的详细错误信息
|
||
if (err.response?.status === 401) {
|
||
error.value = '邮箱或密码错误'
|
||
} else if (err.response?.status === 422) {
|
||
error.value = '请输入有效的邮箱地址'
|
||
} else if (err.response?.status === 500) {
|
||
error.value = '服务器错误,请稍后重试'
|
||
} else {
|
||
error.value = '登录失败,请检查网络连接'
|
||
}
|
||
return false
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
async function logout() {
|
||
user.value = null
|
||
token.value = null
|
||
authApi.logout()
|
||
}
|
||
|
||
async function fetchCurrentUser() {
|
||
try {
|
||
const userInfo = await authApi.getCurrentUser()
|
||
user.value = userInfo
|
||
return userInfo
|
||
} catch (err: any) {
|
||
log.error('Failed to fetch user info', err)
|
||
// 根据用户要求,不管什么错误都不清除状态
|
||
// 保持登录状态,除非用户手动退出
|
||
log.info('Keeping session despite error, as per user requirement')
|
||
return null
|
||
}
|
||
}
|
||
|
||
async function checkAuth() {
|
||
const storedToken = apiClient.getToken()
|
||
if (storedToken) {
|
||
token.value = storedToken
|
||
// 即使获取用户信息失败,也保留 token
|
||
// 只有 401 错误才表示 token 真正失效
|
||
await fetchCurrentUser()
|
||
}
|
||
}
|
||
|
||
return {
|
||
user,
|
||
token,
|
||
loading,
|
||
error,
|
||
isAuthenticated,
|
||
isAdmin,
|
||
login,
|
||
logout,
|
||
fetchCurrentUser,
|
||
checkAuth,
|
||
syncToken
|
||
}
|
||
})
|