Files
zmAI/demo/frontend/src/stores/user.js

183 lines
5.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { login, register, logout, getCurrentUser } from '@/api/auth'
export const useUserStore = defineStore('user', () => {
// 状态 - 从 localStorage 尝试恢复用户信息
const user = ref(null)
const token = ref(null)
const loading = ref(false)
const initialized = ref(false)
try {
const cachedUser = localStorage.getItem('user')
const cachedToken = localStorage.getItem('token')
if (cachedUser && cachedToken) {
user.value = JSON.parse(cachedUser)
token.value = cachedToken
}
} catch (_) {
// ignore localStorage parse errors
}
// 计算属性
const isAuthenticated = computed(() => !!user.value)
const isAdmin = computed(() => user.value?.role === 'ROLE_ADMIN' || user.value?.role === 'ROLE_SUPER_ADMIN')
const isSuperAdmin = computed(() => user.value?.role === 'ROLE_SUPER_ADMIN')
const username = computed(() => user.value?.username || '')
// 可用积分(总积分 - 冻结积分)
const availablePoints = computed(() => {
if (!user.value) return 0
const total = user.value.points || 0
const frozen = user.value.frozenPoints || 0
return Math.max(0, total - frozen)
})
// 登录
const loginUser = async (credentials) => {
try {
loading.value = true
const response = await login(credentials)
if (response.success) {
// 使用JWT认证保存token和用户信息
user.value = response.data.user
token.value = response.data.token
// 保存到localStorage关闭浏览器后仍保持登录
localStorage.setItem('token', response.data.token)
localStorage.setItem('user', JSON.stringify(user.value))
return { success: true }
} else {
return { success: false, message: response.message }
}
} catch (error) {
console.error('Login error:', error)
return { success: false, message: '登录失败,请检查网络连接' }
} finally {
loading.value = false
}
}
// 注册
const registerUser = async (userData) => {
try {
loading.value = true
const response = await register(userData)
if (response.success) {
return { success: true, message: '注册成功,请登录' }
} else {
return { success: false, message: response.message }
}
} catch (error) {
console.error('Register error:', error)
return { success: false, message: '注册失败,请检查网络连接' }
} finally {
loading.value = false
}
}
// 登出
const logoutUser = async () => {
try {
// JWT无状态直接清除localStorage即可
token.value = null
user.value = null
localStorage.removeItem('token')
localStorage.removeItem('user')
} catch (error) {
console.error('Logout error:', error)
}
}
// 获取当前用户信息
const fetchCurrentUser = async () => {
try {
const response = await getCurrentUser()
// 统一使用 response.data 格式
const data = response.data || response
if (data.success) {
user.value = data.data
localStorage.setItem('user', JSON.stringify(user.value))
} else {
console.warn('获取用户信息失败:', data.message)
// 不要立即清除用户数据,保持当前登录状态
// 只在明确的401/认证失败时才由axios拦截器处理登出
}
} catch (error) {
console.error('Fetch user error:', error)
// 请求失败时不强制清除,保持现有本地态
}
}
// 清除用户数据
const clearUserData = () => {
token.value = null
user.value = null
// 清除 localStorage 中的用户数据
localStorage.removeItem('token')
localStorage.removeItem('user')
}
// 初始化
const init = async () => {
if (initialized.value) {
return
}
// 从 localStorage 恢复用户状态
const savedToken = localStorage.getItem('token')
const savedUser = localStorage.getItem('user')
console.log('Store init - savedToken:', savedToken ? savedToken.substring(0, 30) + '...' : 'null')
if (savedToken && savedUser) {
try {
token.value = savedToken
user.value = JSON.parse(savedUser)
console.log('恢复用户状态:', user.value?.username)
// 刷新用户信息(确保角色等信息是最新的)
await fetchCurrentUser()
} catch (error) {
console.error('Failed to restore user state:', error)
clearUserData()
}
}
initialized.value = true
}
// 重置初始化状态(登录成功后调用)
const resetInitialized = () => {
initialized.value = false
}
return {
// 状态
user,
token,
loading,
// 计算属性
isAuthenticated,
isAdmin,
isSuperAdmin,
username,
availablePoints,
// 方法
loginUser,
registerUser,
logoutUser,
fetchCurrentUser,
clearUserData,
init,
initialized,
resetInitialized
}
})