176 lines
5.3 KiB
TypeScript
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 { AuthApi, type User as ApiUser } from '@/api'
// 扩展API用户类型以保持兼容性
export interface User extends ApiUser {}
export const useUserStore = defineStore('user', () => {
// 状态
const user = ref<User | null>(null)
const token = ref<string | null>(localStorage.getItem('X-Access-Token'))
const isLoading = ref(false)
// 计算属性
const isLoggedIn = computed(() => !!user.value && !!token.value)
const isStudent = computed(() => user.value?.role === 'student')
const isTeacher = computed(() => user.value?.role === 'teacher')
const isAdmin = computed(() => user.value?.role === 'admin')
// 方法 - 简化版本,主要用于状态管理
const login = async (_credentials: { email: string; password: string }) => {
// 这个方法现在主要用于兼容性,实际登录逻辑在组件中处理
return { success: true, message: '请使用登录模态框进行登录' }
}
const register = async (_userData: any) => {
// 这个方法现在主要用于兼容性,实际注册逻辑在组件中处理
return { success: true, message: '请使用注册模态框进行注册' }
}
const logout = async () => {
try {
// 尝试调用登出API如果存在的话
// 但不让API失败阻止登出过程
if (token.value) {
try {
await AuthApi.logout()
console.log('服务器端登出成功')
} catch (error: any) {
// 如果是404错误说明后端没有登出接口这是正常的
if (error.response?.status === 404) {
console.log('后端无登出接口,仅执行客户端登出')
} else {
console.warn('登出API调用失败但继续执行客户端登出:', error.message)
}
}
}
} finally {
// 无论API调用是否成功都清除本地数据
user.value = null
token.value = null
localStorage.removeItem('X-Access-Token')
localStorage.removeItem('refreshToken')
localStorage.removeItem('user')
localStorage.removeItem('rememberMe')
console.log('用户已登出')
}
}
// 获取当前用户信息
const getCurrentUser = async () => {
if (!token.value) {
return { success: false, message: '未登录' }
}
// 如果已经有用户信息,直接返回成功
if (user.value) {
return { success: true, message: '用户信息已存在' }
}
// 尝试从localStorage恢复用户信息
const savedUser = localStorage.getItem('user')
if (savedUser) {
try {
user.value = JSON.parse(savedUser)
return { success: true, message: '用户信息已恢复' }
} catch (error) {
console.error('解析用户信息失败:', error)
}
}
// 暂时注释掉API调用因为后端可能没有这个接口
// isLoading.value = true
// try {
// const response = await AuthApi.getCurrentUser()
// if (response.code === 200 || response.code === 0) {
// user.value = response.data
// localStorage.setItem('user', JSON.stringify(response.data))
// return { success: true, message: '获取用户信息成功' }
// } else {
// return { success: false, message: response.message || '获取用户信息失败' }
// }
// } catch (error: any) {
// console.error('获取用户信息失败:', error)
// // 如果是401错误说明token已过期自动登出
// if (error.response?.status === 401) {
// await logout()
// return { success: false, message: '登录已过期,请重新登录' }
// }
// return { success: false, message: '获取用户信息失败' }
// } finally {
// isLoading.value = false
// }
return { success: false, message: '无法获取用户信息' }
}
const updateProfile = async (profileData: any) => {
isLoading.value = true
try {
const response = await AuthApi.updateProfile(profileData)
if (response.code === 200) {
user.value = response.data
localStorage.setItem('user', JSON.stringify(response.data))
return { success: true, message: '更新成功' }
} else {
return { success: false, message: response.message || '更新失败' }
}
} catch (error: any) {
console.error('更新用户资料失败:', error)
let message = '更新失败'
if (error.response?.data?.message) {
message = error.response.data.message
}
return { success: false, message }
} finally {
isLoading.value = false
}
}
const initializeAuth = async () => {
const savedUser = localStorage.getItem('user')
const savedToken = localStorage.getItem('X-Access-Token')
if (savedUser && savedToken) {
try {
user.value = JSON.parse(savedUser)
token.value = savedToken
// 验证token是否仍然有效
await getCurrentUser()
} catch (error) {
console.error('Failed to parse saved user data or token expired:', error)
await logout()
}
}
}
return {
// 状态
user,
token,
isLoading,
// 计算属性
isLoggedIn,
isStudent,
isTeacher,
isAdmin,
// 方法
login,
register,
logout,
getCurrentUser,
updateProfile,
initializeAuth
}
})