Files
sionrui/frontend/app/web-gold/src/stores/user.js
2026-02-23 02:05:48 +08:00

132 lines
3.4 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 { ref, computed, watch } from 'vue'
import { defineStore } from 'pinia'
import { getJSON, setJSON, remove } from '@/utils/storage'
import tokenManager from '@gold/utils/token-manager'
import { getUserInfo, clearUserInfoCache } from '@/api/userinfo'
import { getUserProfile } from '@/api/auth'
const STORAGE_KEY = 'user_store_v1'
export const useUserStore = defineStore('user', () => {
const isLoggedIn = ref(false)
const isHydrated = ref(false)
// 基础信息
const userId = ref('')
const nickname = ref('')
const avatar = ref('')
// 档案数据(来自 MemberUserProfile
const profile = ref(null)
const remainingPoints = computed(() => profile.value?.remainingPoints ?? 0)
const remainingStorage = computed(() => profile.value?.remainingStorage ?? 10) // GB
const usedStorage = computed(() => profile.value?.usedStorage ?? 0) // GB
const totalStorage = computed(() => profile.value?.totalStorage ?? 10) // GB
const totalRecharge = computed(() => profile.value?.totalRecharge ?? 0) // 充值金额
const displayName = computed(() => nickname.value || '未命名用户')
const displayAvatar = computed(() => avatar.value || '')
// 持久化数据
const userData = computed(() => ({
isLoggedIn: isLoggedIn.value,
userId: userId.value,
nickname: nickname.value,
avatar: avatar.value,
profile: profile.value,
}))
// 自动持久化
watch(userData, (data) => setJSON(STORAGE_KEY, data), { deep: true })
// 初始化从本地恢复
const hydrateFromStorage = async () => {
const saved = await getJSON(STORAGE_KEY)
if (!saved) return
isLoggedIn.value = !!saved.isLoggedIn
userId.value = saved.userId || ''
nickname.value = saved.nickname || ''
avatar.value = saved.avatar || ''
profile.value = saved.profile || null
}
hydrateFromStorage().then(() => {
isHydrated.value = true
})
// 登录
const login = (data) => {
isLoggedIn.value = true
userId.value = String(data.userId || data.id || '')
nickname.value = data.nickname || ''
avatar.value = data.avatar || ''
}
// 获取用户信息
const fetchUserInfo = async () => {
try {
const userInfo = await getUserInfo()
if (userInfo) {
userId.value = String(userInfo.id || userInfo.userId || '')
nickname.value = userInfo.nickname || ''
avatar.value = userInfo.avatar || ''
isLoggedIn.value = true
}
} catch (error) {
console.error('获取用户信息失败:', error)
}
}
// 获取用户档案
const fetchUserProfile = async () => {
try {
const profileData = await getUserProfile()
if (profileData) {
profile.value = profileData
}
} catch (error) {
console.error('获取用户档案失败:', error)
}
}
// 登出
const logout = async () => {
try {
tokenManager.clearTokens()
clearUserInfoCache()
} catch (e) {
console.error('清空 token 失败:', e)
}
isLoggedIn.value = false
userId.value = ''
nickname.value = ''
avatar.value = ''
profile.value = null
await remove(STORAGE_KEY)
}
return {
isHydrated,
isLoggedIn,
userId,
nickname,
avatar,
profile,
remainingPoints,
remainingStorage,
usedStorage,
totalStorage,
totalRecharge,
displayName,
displayAvatar,
login,
fetchUserInfo,
fetchUserProfile,
logout,
}
})
export default useUserStore