import { defineStore } from 'pinia' import { ref, computed } from 'vue' import api from '@/utils/api' import { ElMessage } from 'element-plus' export const useUserStore = defineStore('user', () => { // 状态 const user = ref(null) const token = ref(localStorage.getItem('token') || '') const loading = ref(false) // 计算属性 const isAuthenticated = computed(() => { return !!token.value && !!user.value }) const isAdmin = computed(() => { return user.value?.role === 'admin' }) // 设置token const setToken = (newToken) => { token.value = newToken if (newToken) { localStorage.setItem('token', newToken) api.defaults.headers.common['Authorization'] = `Bearer ${newToken}` } else { localStorage.removeItem('token') delete api.defaults.headers.common['Authorization'] } } // 设置用户信息 const setUser = (userData) => { user.value = userData } // 登录 const login = async (credentials) => { try { loading.value = true const response = await api.post('/auth/login', credentials) if (response.data.token) { setToken(response.data.token) setUser(response.data.user) startStatusCheck() // 登录成功后开始状态检查 ElMessage.success(response.data.message || '登录成功') return { success: true, data: response.data } } } catch (error) { const message = error.response?.data?.message || '登录失败' ElMessage.error(message) return { success: false, message } } finally { loading.value = false } } // 注册 const register = async (userData) => { try { loading.value = true const response = await api.post('/auth/register', userData) if (response.data.token) { setToken(response.data.token) setUser(response.data.user) ElMessage.success(response.data.message || '注册成功') return { success: true, data: response.data } } } catch (error) { const message = error.response?.data?.message || '注册失败' ElMessage.error(message) return { success: false, message } } finally { loading.value = false } } // 登出 const logout = () => { stopStatusCheck() // 登出时停止状态检查 setToken('') setUser(null) ElMessage.success('已退出登录') } // 检查认证状态 const checkAuth = async () => { if (!token.value) { return false } try { // 确保请求头已设置 if (token.value && !api.defaults.headers.common['Authorization']) { api.defaults.headers.common['Authorization'] = `Bearer ${token.value}` } const response = await api.get('/auth/me') setUser(response.data.user) return true } catch (error) { // token无效,清除本地存储 setToken('') setUser(null) return false } } // 更新用户信息 const updateProfile = async (userData) => { try { loading.value = true const response = await api.put(`/users/${user.value.id}`, userData) setUser(response.data.user) ElMessage.success(response.data.message || '更新成功') return { success: true, data: response.data } } catch (error) { const message = error.response?.data?.message || '更新失败' ElMessage.error(message) return { success: false, message } } finally { loading.value = false } } // 修改密码 const changePassword = async (passwordData) => { try { loading.value = true const response = await api.put('/auth/change-password', passwordData) ElMessage.success(response.data.message || '密码修改成功') return { success: true, data: response.data } } catch (error) { const message = error.response?.data?.message || '密码修改失败' ElMessage.error(message) return { success: false, message } } finally { loading.value = false } } // 获取用户详情 const getUserInfo = async (userId) => { try { const response = await api.get(`/users/${userId}`) return { success: true, data: response.data.user } } catch (error) { const message = error.response?.data?.message || '获取用户信息失败' return { success: false, message } } } // 定期检查用户状态(用于检测拉黑等状态变化) let statusCheckInterval = null /** * 开始定期检查用户状态 * 每5分钟检查一次用户状态,确保及时发现被拉黑等情况 */ const startStatusCheck = () => { if (statusCheckInterval) { clearInterval(statusCheckInterval) } statusCheckInterval = setInterval(async () => { if (isAuthenticated.value) { try { await api.get('/auth/me') } catch (error) { // 如果是拉黑错误,API拦截器会自动处理 // 这里不需要额外处理 } } }, 5 * 60 * 1000) // 5分钟检查一次 } /** * 停止定期检查用户状态 */ const stopStatusCheck = () => { if (statusCheckInterval) { clearInterval(statusCheckInterval) statusCheckInterval = null } } return { // 状态 user, token, loading, // 计算属性 isAuthenticated, isAdmin, // 方法 setToken, setUser, login, register, logout, checkAuth, updateProfile, changePassword, getUserInfo, startStatusCheck, stopStatusCheck } })