user.js 4.45 KB
/*
 * @Date: 2025-01-08 18:00:00
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2025-07-09 11:22:03
 * @FilePath: /jgdl/src/stores/user.js
 * @Description: 用户状态管理
 */
import { defineStore } from 'pinia'
import { getProfileAPI } from '@/api/index'
import Taro from '@tarojs/taro'

export const useUserStore = defineStore('user', {
    state: () => {
        return {
            userInfo: {
                avatar: '',
                nickname: '',
                phone: '',
                gender: '',
                school: '',
                birthday: '',
                avatar_url: '',
                follower_count: 0,
                order_count: 0,
                favorite_count: 0
            },
            isAuthenticated: false,
            isLoading: false
        }
    },

    getters: {
        /**
         * 检查用户是否已完善基本信息(主要是手机号)
         */
        hasCompleteProfile: (state) => {
            return !!(state.userInfo.phone && state.userInfo.phone.trim())
        },

        /**
         * 检查用户是否已认证
         */
        isUserAuthenticated: (state) => {
            return state.isAuthenticated && state.hasCompleteProfile
        },

        /**
         * 获取用户显示名称
         */
        displayName: (state) => {
            return state.userInfo.nickname || '用户'
        }
    },

    actions: {
        /**
         * 获取用户信息
         */
        async fetchUserInfo() {
            this.isLoading = true
            try {
                const response = await getProfileAPI()
                if (response.code) {
                    this.userInfo = { ...this.userInfo, ...response.data }
                    this.isAuthenticated = true
                    return true
                } else {
                    this.isAuthenticated = false
                    return false
                }
            } catch (error) {
                console.error('获取用户信息失败:', error)
                this.isAuthenticated = false
                return false
            } finally {
                this.isLoading = false
            }
        },

        /**
         * 更新用户信息
         * @param {Object} newUserInfo - 新的用户信息
         */
        updateUserInfo(newUserInfo) {
            this.userInfo = { ...this.userInfo, ...newUserInfo }
        },

        /**
         * 清除用户信息(登出)
         */
        clearUserInfo() {
            this.userInfo = {
                avatar: '',
                nickname: '',
                phone: '',
                gender: '',
                school: '',
                birthday: '',
                avatar_url: '',
                follower_count: 0,
                order_count: 0,
                favorite_count: 0
            }
            this.isAuthenticated = false
        },

        /**
         * 检查并处理权限验证
         * @param {Object} options - 配置选项
         * @param {string} options.redirectUrl - 权限验证失败时的跳转地址
         * @param {string} options.message - 提示消息
         * @param {Function} options.onSuccess - 验证成功的回调
         * @param {Function} options.onFail - 验证失败的回调
         * @returns {Promise<boolean>} 是否通过权限验证
         */
        async checkPermission(options = {}) {
            const {
                redirectUrl = '/pages/register/index',
                message = '请先完善个人信息',
                onSuccess,
                onFail
            } = options

            // 如果用户信息为空,先尝试获取
            if (!this.isAuthenticated) {
                await this.fetchUserInfo()
            }

            // 检查是否有完整的用户信息
            if (this.hasCompleteProfile) {
                onSuccess && onSuccess()
                return true
            } else {
                // 权限验证失败,显示提示并跳转
                Taro.showToast({
                    title: message,
                    icon: 'none',
                    duration: 2000,
                    success: () => {
                        setTimeout(() => {
                            Taro.navigateTo({
                                url: redirectUrl
                            })
                        }, 2000)
                    }
                })
                onFail && onFail()
                return false
            }
        }
    }
})