Files
AIGC/demo/frontend/src/stores/user.js
2025-10-21 16:50:33 +08:00

160 lines
4.2 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', () => {
// 状态 - 从 sessionStorage 尝试恢复用户信息
const user = ref(null)
const token = ref(null)
const loading = ref(false)
const initialized = ref(false)
try {
const cachedUser = sessionStorage.getItem('user')
const cachedToken = sessionStorage.getItem('token')
if (cachedUser && cachedToken) {
user.value = JSON.parse(cachedUser)
token.value = cachedToken
}
} catch (_) {
// ignore sessionStorage parse errors
}
// 计算属性
const isAuthenticated = computed(() => !!user.value)
const isAdmin = computed(() => user.value?.role === 'ROLE_ADMIN')
const username = computed(() => user.value?.username || '')
// 登录
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
// 保存到sessionStorage关闭页面时自动清除
sessionStorage.setItem('token', response.data.token)
sessionStorage.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无状态直接清除sessionStorage即可
token.value = null
user.value = null
sessionStorage.removeItem('token')
sessionStorage.removeItem('user')
} catch (error) {
console.error('Logout error:', error)
}
}
// 获取当前用户信息
const fetchCurrentUser = async () => {
try {
const response = await getCurrentUser()
if (response.success) {
user.value = response.data
sessionStorage.setItem('user', JSON.stringify(user.value))
} else {
// 会话无效,清除本地存储
clearUserData()
}
} catch (error) {
console.error('Fetch user error:', error)
// 请求失败时不强制清除,保持现有本地态
}
}
// 清除用户数据
const clearUserData = () => {
token.value = null
user.value = null
// 清除 sessionStorage 中的用户数据
sessionStorage.removeItem('token')
sessionStorage.removeItem('user')
}
// 初始化
const init = async () => {
if (initialized.value) {
return
}
// 从sessionStorage恢复用户状态
const savedToken = sessionStorage.getItem('token')
const savedUser = sessionStorage.getItem('user')
if (savedToken && savedUser) {
try {
token.value = savedToken
user.value = JSON.parse(savedUser)
// 只在开发环境输出详细日志
if (process.env.NODE_ENV === 'development') {
console.log('恢复用户状态:', user.value?.username, '角色:', user.value?.role)
}
} catch (error) {
console.error('Failed to restore user state:', error)
clearUserData()
}
}
initialized.value = true
}
return {
// 状态
user,
token,
loading,
// 计算属性
isAuthenticated,
isAdmin,
username,
// 方法
loginUser,
registerUser,
logoutUser,
fetchCurrentUser,
clearUserData,
init,
initialized
}
})