246 lines
7.3 KiB
JavaScript
246 lines
7.3 KiB
JavaScript
/**
|
||
* 用户状态管理模块
|
||
* Requirements: 1.2, 9.1, 9.2
|
||
*/
|
||
|
||
import { defineStore } from 'pinia'
|
||
import {
|
||
getToken, setToken, removeToken,
|
||
getUserInfo, setUserInfo, removeUserInfo,
|
||
getGenderPreference, setGenderPreference
|
||
} from '../utils/storage.js'
|
||
import { getMyProfile } from '../api/profile.js'
|
||
|
||
/**
|
||
* 用户状态定义
|
||
* @typedef {Object} UserState
|
||
* @property {string} token - JWT token
|
||
* @property {number} userId - 用户ID
|
||
* @property {string} nickname - 昵称
|
||
* @property {string} avatar - 头像
|
||
* @property {string} xiangQinNo - 相亲号
|
||
* @property {boolean} isProfileCompleted - 资料是否完成
|
||
* @property {boolean} isMember - 是否会员
|
||
* @property {number} memberLevel - 会员等级
|
||
* @property {boolean} isRealName - 是否实名
|
||
* @property {number} genderPreference - 性别偏好 (1男 2女)
|
||
*/
|
||
|
||
export const useUserStore = defineStore('user', {
|
||
state: () => ({
|
||
token: getToken() || '',
|
||
userId: 0,
|
||
nickname: '',
|
||
avatar: '',
|
||
xiangQinNo: '',
|
||
isProfileCompleted: false,
|
||
auditStatus: 0, // 审核状态:0-未提交资料 1-已通过审核 2-审核中 3-已拒绝
|
||
isMember: false,
|
||
memberLevel: 0,
|
||
isRealName: false,
|
||
isFollowServiceAccount: false, // 是否关注服务号
|
||
genderPreference: getGenderPreference() || 0,
|
||
/** 上次从服务器刷新用户信息的时间戳(用于节流) */
|
||
lastRefreshTime: 0
|
||
}),
|
||
|
||
getters: {
|
||
/**
|
||
* 是否已登录
|
||
* Property 17: Login State UI - token为空或无效时显示登录提示
|
||
*/
|
||
isLoggedIn: (state) => !!state.token && state.token.length > 0,
|
||
|
||
/**
|
||
* 是否需要完善资料
|
||
* Property 18: Profile Completion UI - 资料未完成时显示"立即填写"按钮
|
||
*/
|
||
needCompleteProfile: (state) => !state.isProfileCompleted,
|
||
|
||
/**
|
||
* 是否资料审核中(auditStatus = 2)
|
||
*/
|
||
isProfileAuditing: (state) => state.auditStatus === 2,
|
||
|
||
/**
|
||
* 是否需要选择性别偏好
|
||
*/
|
||
needSelectGender: (state) => state.genderPreference === 0
|
||
},
|
||
|
||
actions: {
|
||
/**
|
||
* 登录 - 设置token和用户信息
|
||
* @param {Object} loginData - 登录返回数据
|
||
* @param {string} loginData.token - JWT token
|
||
* @param {Object} loginData.userInfo - 用户信息
|
||
*/
|
||
login(loginData) {
|
||
const { token, userInfo } = loginData
|
||
|
||
// 存储token
|
||
this.token = token
|
||
setToken(token)
|
||
|
||
// 更新用户信息
|
||
if (userInfo) {
|
||
this.updateUserInfo(userInfo)
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 登出 - 清除所有用户状态
|
||
*/
|
||
logout() {
|
||
// 清除token
|
||
this.token = ''
|
||
removeToken()
|
||
|
||
// 清除用户信息
|
||
this.userId = 0
|
||
this.nickname = ''
|
||
this.avatar = ''
|
||
this.xiangQinNo = ''
|
||
this.isProfileCompleted = false
|
||
this.auditStatus = 0
|
||
this.isMember = false
|
||
this.memberLevel = 0
|
||
this.isRealName = false
|
||
this.isFollowServiceAccount = false
|
||
removeUserInfo()
|
||
},
|
||
|
||
/**
|
||
* 更新用户信息
|
||
* @param {Object} userInfo - 用户信息对象
|
||
*/
|
||
updateUserInfo(userInfo) {
|
||
if (!userInfo) return
|
||
|
||
if (userInfo.userId !== undefined) this.userId = userInfo.userId
|
||
if (userInfo.nickname !== undefined) this.nickname = userInfo.nickname
|
||
if (userInfo.avatar !== undefined) this.avatar = userInfo.avatar
|
||
if (userInfo.xiangQinNo !== undefined) this.xiangQinNo = userInfo.xiangQinNo
|
||
if (userInfo.isProfileCompleted !== undefined) this.isProfileCompleted = userInfo.isProfileCompleted
|
||
if (userInfo.auditStatus !== undefined) this.auditStatus = userInfo.auditStatus
|
||
if (userInfo.isMember !== undefined) this.isMember = userInfo.isMember
|
||
if (userInfo.memberLevel !== undefined) this.memberLevel = userInfo.memberLevel
|
||
if (userInfo.isRealName !== undefined) this.isRealName = userInfo.isRealName
|
||
if (userInfo.isFollowServiceAccount !== undefined) this.isFollowServiceAccount = userInfo.isFollowServiceAccount
|
||
|
||
// 持久化用户信息
|
||
setUserInfo({
|
||
userId: this.userId,
|
||
nickname: this.nickname,
|
||
avatar: this.avatar,
|
||
xiangQinNo: this.xiangQinNo,
|
||
isProfileCompleted: this.isProfileCompleted,
|
||
auditStatus: this.auditStatus,
|
||
isMember: this.isMember,
|
||
memberLevel: this.memberLevel,
|
||
isRealName: this.isRealName,
|
||
isFollowServiceAccount: this.isFollowServiceAccount
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 设置性别偏好
|
||
* @param {number} gender - 1男 2女
|
||
*/
|
||
setGenderPref(gender) {
|
||
this.genderPreference = gender
|
||
setGenderPreference(gender)
|
||
},
|
||
|
||
/**
|
||
* 从存储恢复用户状态
|
||
*/
|
||
restoreFromStorage() {
|
||
const token = getToken()
|
||
const userInfo = getUserInfo()
|
||
const genderPref = getGenderPreference()
|
||
|
||
if (token) {
|
||
this.token = token
|
||
}
|
||
|
||
if (userInfo) {
|
||
this.userId = userInfo.userId || 0
|
||
this.nickname = userInfo.nickname || ''
|
||
this.avatar = userInfo.avatar || ''
|
||
this.xiangQinNo = userInfo.xiangQinNo || ''
|
||
this.isProfileCompleted = userInfo.isProfileCompleted || false
|
||
this.auditStatus = userInfo.auditStatus !== undefined ? userInfo.auditStatus : 0
|
||
this.isMember = userInfo.isMember || false
|
||
this.memberLevel = userInfo.memberLevel || 0
|
||
this.isRealName = userInfo.isRealName || false
|
||
this.isFollowServiceAccount = userInfo.isFollowServiceAccount || false
|
||
}
|
||
|
||
if (genderPref) {
|
||
this.genderPreference = genderPref
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 设置资料完成状态
|
||
* @param {boolean} completed - 是否完成
|
||
*/
|
||
setProfileCompleted(completed) {
|
||
this.isProfileCompleted = completed
|
||
this.updateUserInfo({ isProfileCompleted: completed })
|
||
},
|
||
|
||
/**
|
||
* 设置会员状态
|
||
* @param {boolean} isMember - 是否会员
|
||
* @param {number} level - 会员等级
|
||
*/
|
||
setMemberStatus(isMember, level = 0) {
|
||
this.isMember = isMember
|
||
this.memberLevel = level
|
||
this.updateUserInfo({ isMember, memberLevel: level })
|
||
},
|
||
|
||
/**
|
||
* 设置实名状态
|
||
* @param {boolean} isRealName - 是否实名
|
||
*/
|
||
setRealNameStatus(isRealName) {
|
||
this.isRealName = isRealName
|
||
this.updateUserInfo({ isRealName })
|
||
},
|
||
|
||
/**
|
||
* 从服务器刷新用户信息
|
||
* 用于同步后台修改的用户状态(如会员等级变更)
|
||
*/
|
||
async refreshFromServer() {
|
||
if (!this.token) return
|
||
|
||
try {
|
||
const res = await getMyProfile()
|
||
if (res && res.code === 0 && res.data) {
|
||
const data = res.data
|
||
this.updateUserInfo({
|
||
userId: data.userId,
|
||
nickname: data.nickname,
|
||
avatar: data.avatar,
|
||
xiangQinNo: data.xiangQinNo,
|
||
isProfileCompleted: data.auditStatus === 1,
|
||
auditStatus: data.auditStatus,
|
||
isMember: data.isMember,
|
||
memberLevel: data.memberLevel,
|
||
isRealName: data.isRealName,
|
||
isFollowServiceAccount: data.isFollowServiceAccount
|
||
})
|
||
// 更新刷新时间戳
|
||
this.lastRefreshTime = Date.now()
|
||
}
|
||
} catch (error) {
|
||
console.error('刷新用户信息失败:', error)
|
||
}
|
||
}
|
||
}
|
||
})
|