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' /** * @typedef {Object} UserProfile * @property {string} [registerTime] * @property {string} [createTime] * @property {string} [mobile] * @property {number} [remainingPoints] * @property {number} [remainingStorage] * @property {number} [usedStorage] * @property {number} [totalStorage] * @property {number} [totalRecharge] */ export const useUserStore = defineStore('user', () => { const isLoggedIn = ref(false) const isHydrated = ref(false) // 基础信息 const userId = ref('') const nickname = ref('') const avatar = ref('') const mobile = ref('') // 档案数据(来自 MemberUserProfile) /** @type {import('vue').Ref} */ 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, mobile: mobile.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 || '' mobile.value = saved.mobile || '' 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 || '' mobile.value = data.mobile || '' } // 获取用户信息 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 || '' mobile.value = userInfo.mobile || '' 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 = '' mobile.value = '' profile.value = null await remove(STORAGE_KEY) } return { isHydrated, isLoggedIn, userId, nickname, avatar, mobile, profile, remainingPoints, remainingStorage, usedStorage, totalStorage, totalRecharge, displayName, displayAvatar, login, fetchUserInfo, fetchUserProfile, logout, } }) export default useUserStore