| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- import { defineStore } from 'pinia'
- import { authApi, profileApi } from '../utils/api'
- /** Normalize vipEndTime from Jackson array [y,m,d,h,m,s] to ISO string */
- function normalizeDate(v) {
- if (!v) return null
- if (Array.isArray(v)) {
- const [y, m, d, h = 0, min = 0, s = 0] = v
- const pad = (n) => String(n).padStart(2, '0')
- return `${y}-${pad(m)}-${pad(d)}T${pad(h)}:${pad(min)}:${pad(s)}`
- }
- return v
- }
- export const useUserStore = defineStore('user', {
- state: () => ({
- token: uni.getStorageSync('token') || '',
- nickname: '',
- avatarUrl: '',
- isVip: false,
- vipType: null,
- vipEndTime: null,
- referralCode: '',
- // Daily quota
- usedCharts: 0,
- maxCharts: 3,
- usedChats: 0,
- maxChats: 3,
- usedAcademic: 0,
- maxAcademic: 1,
- shareCount: 0,
- shareLimit: 1,
- // Commission
- totalCommission: 0,
- availableCommission: 0,
- // US-5.1 Profile fields
- profileIncomplete: false,
- gender: 0,
- birthDate: null,
- bio: '',
- city: '',
- tags: '',
- lookingFor: 0,
- profileComplete: false,
- birthYear: 0,
- birthMonth: 0,
- birthDay: 0
- }),
- getters: {
- isLoggedIn: (state) => !!state.token,
- isVipActive: (state) => {
- if (!state.vipEndTime) return false
- return new Date(state.vipEndTime) > new Date()
- }
- },
- actions: {
- async login(openid, nickname, avatarUrl, referralCode) {
- const data = { openid, nickname, avatarUrl }
- if (referralCode) data.referralCode = referralCode
- const res = await authApi.login(data)
- const tokenStr = res.token || res
- this.token = tokenStr
- uni.setStorageSync('token', tokenStr)
- this.nickname = nickname
- this.avatarUrl = avatarUrl
- // US-5.1 §5-7: Check profile completion
- this.profileIncomplete = res.profileIncomplete === true
- },
- async wechatLogin(code, nickname, avatarUrl, referralCode) {
- const data = { code, nickname, avatarUrl }
- if (referralCode) data.referralCode = referralCode
- const res = await authApi.login(data)
- const tokenStr = res.token || res
- this.token = tokenStr
- uni.setStorageSync('token', tokenStr)
- this.nickname = nickname || '微信用户'
- this.avatarUrl = avatarUrl || ''
- // US-5.1 §5-7: Check profile completion
- this.profileIncomplete = res.profileIncomplete === true
- // Fetch full profile after login
- try { await this.fetchProfile() } catch (e) {}
- },
- async fetchProfile() {
- const user = await profileApi.info()
- this.nickname = user.nickname
- this.avatarUrl = user.avatarUrl
- this.referralCode = user.referralCode
- this.vipType = user.vipType || null
- // Normalize vipEndTime: Jackson may send [2026,6,8,23,59,59]; always store as ISO string
- this.vipEndTime = normalizeDate(user.vipEndTime)
- this.isVip = !!this.vipEndTime && new Date(this.vipEndTime) > new Date()
- // US-5.1 profile fields
- this.gender = user.gender || 0
- this.birthDate = user.birthDate || null
- this.bio = user.bio || ''
- this.city = user.city || ''
- this.tags = user.tags || ''
- this.lookingFor = user.lookingFor || 0
- this.profileComplete = !!user.profileComplete
- this.birthYear = user.birthYear || 0
- this.birthMonth = user.birthMonth || 0
- this.birthDay = user.birthDay || 0
- this.profileIncomplete = !this.profileComplete
- },
- async fetchQuota() {
- try {
- const quota = await profileApi.quota()
- this.usedCharts = quota.dailyChartCount || 0
- this.maxCharts = quota.chartLimit > 0 ? quota.chartLimit : 999
- this.usedChats = quota.dailyChatCount || 0
- this.maxChats = quota.chatLimit > 0 ? quota.chatLimit : 999
- this.shareCount = quota.dailyShareCount || 0
- this.shareLimit = quota.shareLimit > 0 ? quota.shareLimit : 1
- this.usedAcademic = quota.dailyAcademicCount || 0
- this.maxAcademic = quota.academicLimit > 0 ? quota.academicLimit : 1
- } catch (e) { /* ignore */ }
- },
- async fetchCommissionSummary() {
- try {
- const summary = await profileApi.commissionSummary()
- this.totalCommission = summary.totalEarnings || 0
- this.availableCommission = summary.availableBalance || 0
- } catch (e) { /* ignore */ }
- },
- logout() {
- this.token = ''
- this.nickname = ''
- this.avatarUrl = ''
- this.usedCharts = 0
- this.usedChats = 0
- this.usedAcademic = 0
- this.shareCount = 0
- this.shareLimit = 1
- this.maxAcademic = 1
- this.totalCommission = 0
- this.availableCommission = 0
- this.profileIncomplete = false
- this.gender = 0
- this.birthDate = null
- this.bio = ''
- this.city = ''
- this.tags = ''
- this.lookingFor = 0
- this.profileComplete = false
- this.birthYear = 0
- this.birthMonth = 0
- this.birthDay = 0
- uni.removeStorageSync('token')
- }
- }
- })
|