user.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import { defineStore } from 'pinia'
  2. import { authApi, profileApi } from '../utils/api'
  3. export const useUserStore = defineStore('user', {
  4. state: () => ({
  5. token: uni.getStorageSync('token') || '',
  6. nickname: '',
  7. avatarUrl: '',
  8. isVip: false,
  9. vipType: null,
  10. vipEndTime: null,
  11. referralCode: '',
  12. // Daily quota
  13. usedCharts: 0,
  14. maxCharts: 3,
  15. usedChats: 0,
  16. maxChats: 3,
  17. usedAcademic: 0,
  18. maxAcademic: 1,
  19. shareCount: 0,
  20. shareLimit: 1,
  21. // Commission
  22. totalCommission: 0,
  23. availableCommission: 0,
  24. // US-5.1 Profile fields
  25. profileIncomplete: false,
  26. gender: 0,
  27. birthDate: null,
  28. bio: '',
  29. city: '',
  30. tags: '',
  31. lookingFor: 0,
  32. profileComplete: false,
  33. birthYear: 0,
  34. birthMonth: 0,
  35. birthDay: 0
  36. }),
  37. getters: {
  38. isLoggedIn: (state) => !!state.token,
  39. isVipActive: (state) => {
  40. if (!state.vipEndTime) return false
  41. return new Date(state.vipEndTime) > new Date()
  42. }
  43. },
  44. actions: {
  45. async login(openid, nickname, avatarUrl, referralCode) {
  46. const data = { openid, nickname, avatarUrl }
  47. if (referralCode) data.referralCode = referralCode
  48. const res = await authApi.login(data)
  49. const tokenStr = res.token || res
  50. this.token = tokenStr
  51. uni.setStorageSync('token', tokenStr)
  52. this.nickname = nickname
  53. this.avatarUrl = avatarUrl
  54. // US-5.1 §5-7: Check profile completion
  55. this.profileIncomplete = res.profileIncomplete === true
  56. },
  57. async wechatLogin(code, nickname, avatarUrl) {
  58. const data = { code, nickname, avatarUrl }
  59. const res = await authApi.login(data)
  60. const tokenStr = res.token || res
  61. this.token = tokenStr
  62. uni.setStorageSync('token', tokenStr)
  63. this.nickname = nickname || '微信用户'
  64. this.avatarUrl = avatarUrl || ''
  65. // US-5.1 §5-7: Check profile completion
  66. this.profileIncomplete = res.profileIncomplete === true
  67. // Fetch full profile after login
  68. try { await this.fetchProfile() } catch (e) {}
  69. },
  70. async fetchProfile() {
  71. const user = await profileApi.info()
  72. this.nickname = user.nickname
  73. this.avatarUrl = user.avatarUrl
  74. this.referralCode = user.referralCode
  75. this.isVip = !!user.vipEndTime && new Date(user.vipEndTime) > new Date()
  76. this.vipType = user.vipType || null
  77. this.vipEndTime = user.vipEndTime
  78. // US-5.1 profile fields
  79. this.gender = user.gender || 0
  80. this.birthDate = user.birthDate || null
  81. this.bio = user.bio || ''
  82. this.city = user.city || ''
  83. this.tags = user.tags || ''
  84. this.lookingFor = user.lookingFor || 0
  85. this.profileComplete = !!user.profileComplete
  86. this.birthYear = user.birthYear || 0
  87. this.birthMonth = user.birthMonth || 0
  88. this.birthDay = user.birthDay || 0
  89. this.profileIncomplete = !this.profileComplete
  90. },
  91. async fetchQuota() {
  92. try {
  93. const quota = await profileApi.quota()
  94. this.usedCharts = quota.dailyChartCount || 0
  95. this.maxCharts = quota.chartLimit > 0 ? quota.chartLimit : 999
  96. this.usedChats = quota.dailyChatCount || 0
  97. this.maxChats = quota.chatLimit > 0 ? quota.chatLimit : 999
  98. this.shareCount = quota.dailyShareCount || 0
  99. this.shareLimit = quota.shareLimit > 0 ? quota.shareLimit : 1
  100. this.usedAcademic = quota.dailyAcademicCount || 0
  101. this.maxAcademic = quota.academicLimit > 0 ? quota.academicLimit : 1
  102. } catch (e) { /* ignore */ }
  103. },
  104. async fetchCommissionSummary() {
  105. try {
  106. const summary = await profileApi.commissionSummary()
  107. this.totalCommission = summary.totalEarnings || 0
  108. this.availableCommission = summary.availableBalance || 0
  109. } catch (e) { /* ignore */ }
  110. },
  111. logout() {
  112. this.token = ''
  113. this.nickname = ''
  114. this.avatarUrl = ''
  115. this.usedCharts = 0
  116. this.usedChats = 0
  117. this.usedAcademic = 0
  118. this.shareCount = 0
  119. this.shareLimit = 1
  120. this.maxAcademic = 1
  121. this.totalCommission = 0
  122. this.availableCommission = 0
  123. this.profileIncomplete = false
  124. this.gender = 0
  125. this.birthDate = null
  126. this.bio = ''
  127. this.city = ''
  128. this.tags = ''
  129. this.lookingFor = 0
  130. this.profileComplete = false
  131. this.birthYear = 0
  132. this.birthMonth = 0
  133. this.birthDay = 0
  134. uni.removeStorageSync('token')
  135. }
  136. }
  137. })