index.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. import tianpan from './modules/tianpan'
  4. import feedback from './feedback'
  5. import healthAlert from './health-alert'
  6. import healthScore from './health-score'
  7. import { switchBackVerify } from '../utils/api.js'
  8. Vue.use(Vuex)
  9. const store = new Vuex.Store({
  10. state: {
  11. token: '',
  12. userId: '',
  13. role: 'parent', // 用户的实际角色(数据库中的角色)
  14. currentRole: 'parent', // 当前视图模式(用于切换查看家长/孩子界面)
  15. familyId: '',
  16. nickname: '',
  17. currentChildId: '',
  18. currentMemberId: '', // 当前切换到的家庭成员ID(family_members表)
  19. currentMemberRole: '', // 当前切换到的家庭成员effectiveRole
  20. children: [],
  21. isSwitchedChild: false, // 家长切换到孩子状态的标记(已废弃,使用 currentView)
  22. isSwitchedMember: false, // 通过family_members切换的标记(已废弃,使用 currentView)
  23. currentView: 'self' // 当前视角: 'self' | 'member'
  24. },
  25. getters: {
  26. hasFamily: function(state) {
  27. return state.familyId !== '' && state.familyId !== null && state.familyId !== 0
  28. }
  29. },
  30. mutations: {
  31. setToken(state, token) {
  32. state.token = token
  33. uni.setStorageSync('token', token)
  34. },
  35. setUserInfo(state, userInfo) {
  36. state.userId = userInfo.userId
  37. state.role = userInfo.role
  38. state.currentRole = userInfo.role
  39. state.familyId = userInfo.familyId
  40. state.nickname = userInfo.nickname
  41. uni.setStorageSync('userId', userInfo.userId)
  42. uni.setStorageSync('role', userInfo.role)
  43. uni.setStorageSync('currentRole', userInfo.role)
  44. state.isSwitchedChild = false
  45. state.currentView = 'self'
  46. uni.setStorageSync('isSwitchedChild', false)
  47. uni.setStorageSync('currentView', 'self')
  48. },
  49. setChildren(state, children) {
  50. state.children = children
  51. if (children.length > 0 && !state.currentChildId) {
  52. state.currentChildId = children[0].id
  53. }
  54. },
  55. setCurrentChild(state, memberId) {
  56. state.currentChildId = memberId
  57. uni.setStorageSync('currentChildId', memberId)
  58. },
  59. // 切换到孩子模式(家长切换)
  60. switchToChild(state, memberId) {
  61. state.currentRole = 'child'
  62. state.currentChildId = memberId
  63. state.isSwitchedChild = true
  64. state.currentView = 'member'
  65. uni.setStorageSync('currentRole', 'child')
  66. uni.setStorageSync('currentChildId', memberId)
  67. uni.setStorageSync('isSwitchedChild', true)
  68. uni.setStorageSync('currentView', 'member')
  69. },
  70. // 切换回家长模式
  71. switchBackToParent(state) {
  72. state.currentRole = 'parent'
  73. state.currentChildId = ''
  74. state.isSwitchedChild = false
  75. state.currentView = 'self'
  76. uni.setStorageSync('currentRole', 'parent')
  77. uni.removeStorageSync('currentChildId')
  78. uni.setStorageSync('isSwitchedChild', false)
  79. uni.setStorageSync('currentView', 'self')
  80. },
  81. // 通过family_members切换到某个成员(member 语义统一入口)
  82. // 注:effectiveRole 为 'child' 时同步设置 currentChildId/isSwitchedChild 兼容旧页面
  83. switchToMember(state, payload) {
  84. state.currentRole = payload.effectiveRole
  85. state.currentMemberId = payload.memberId
  86. state.currentMemberRole = payload.effectiveRole
  87. state.isSwitchedMember = true
  88. state.currentView = 'member'
  89. if (payload.effectiveRole === 'child') {
  90. state.isSwitchedChild = true
  91. state.currentChildId = payload.memberId
  92. }
  93. uni.setStorageSync('currentRole', payload.effectiveRole)
  94. uni.setStorageSync('currentMemberId', payload.memberId)
  95. uni.setStorageSync('currentMemberRole', payload.effectiveRole)
  96. uni.setStorageSync('isSwitchedMember', true)
  97. uni.setStorageSync('currentView', 'member')
  98. if (payload.effectiveRole === 'child') {
  99. uni.setStorageSync('currentChildId', payload.memberId)
  100. uni.setStorageSync('isSwitchedChild', true)
  101. }
  102. },
  103. // 从family_members切换回自己
  104. switchBackFromMember(state) {
  105. var originalRole = uni.getStorageSync('role') || 'parent'
  106. state.currentRole = originalRole
  107. state.currentMemberId = ''
  108. state.currentMemberRole = ''
  109. state.isSwitchedMember = false
  110. state.isSwitchedChild = false
  111. state.currentChildId = ''
  112. state.currentView = 'self'
  113. uni.setStorageSync('currentRole', originalRole)
  114. uni.removeStorageSync('currentMemberId')
  115. uni.removeStorageSync('currentMemberRole')
  116. uni.setStorageSync('isSwitchedMember', false)
  117. uni.removeStorageSync('currentChildId')
  118. uni.setStorageSync('isSwitchedChild', false)
  119. uni.setStorageSync('currentView', 'self')
  120. },
  121. // 切换视图模式(不修改数据库中的实际角色)
  122. switchViewMode(state, role) {
  123. state.currentRole = role
  124. uni.setStorageSync('currentRole', role)
  125. },
  126. // 兼容旧的方法名
  127. switchRole(state, role) {
  128. state.currentRole = role
  129. uni.setStorageSync('currentRole', role)
  130. },
  131. logout(state) {
  132. state.token = ''
  133. state.userId = ''
  134. state.role = 'parent'
  135. state.currentRole = 'parent'
  136. state.familyId = ''
  137. state.nickname = ''
  138. state.currentChildId = ''
  139. state.currentMemberId = ''
  140. state.currentMemberRole = ''
  141. state.children = []
  142. state.isSwitchedChild = false
  143. state.isSwitchedMember = false
  144. state.isSwitchedTeacher = false
  145. state.currentView = 'self'
  146. uni.removeStorageSync('token')
  147. uni.removeStorageSync('currentRole')
  148. uni.removeStorageSync('isSwitchedChild')
  149. uni.removeStorageSync('isSwitchedTeacher')
  150. uni.removeStorageSync('userId')
  151. uni.removeStorageSync('role')
  152. uni.removeStorageSync('openid')
  153. uni.removeStorageSync('userInfo')
  154. uni.removeStorageSync('nickname')
  155. uni.removeStorageSync('currentChildId')
  156. uni.removeStorageSync('currentMemberId')
  157. uni.removeStorageSync('currentMemberRole')
  158. uni.removeStorageSync('isSwitchedMember')
  159. uni.removeStorageSync('currentView')
  160. uni.removeStorageSync('familyId')
  161. },
  162. markNoFamily: function(state) {
  163. if (state.familyId !== '' && state.familyId !== null && state.familyId !== 0) {
  164. console.warn('[STORE] 后端返回 5001 但本地 familyId 非空,已同步本地为无家庭态', state.familyId)
  165. }
  166. state.familyId = ''
  167. uni.removeStorageSync('familyId')
  168. },
  169. setFamilyId: function(state, familyId) {
  170. state.familyId = familyId
  171. // 持久化供冷启动恢复(hasFamily getter 依赖 state.familyId)
  172. uni.setStorageSync('familyId', familyId || '')
  173. }
  174. },
  175. actions: {
  176. login({ commit }, userInfo) {
  177. commit('setToken', userInfo.token)
  178. commit('setUserInfo', userInfo)
  179. },
  180. updateChildren({ commit }, children) {
  181. commit('setChildren', children)
  182. },
  183. // 兼容旧 action:切换成员前检查(effectiveRole 年龄语义保留,用于过滤未成年成员)
  184. switchToChildWithCheck({ commit }, { memberId, members }) {
  185. var hasChildren = members && members.some(function(m) {
  186. return m.effectiveRole === 'child'
  187. })
  188. if (!hasChildren) {
  189. uni.showToast({ title: '家庭中暂无可切换的未成年成员', icon: 'none' })
  190. return false
  191. }
  192. commit('switchToChild', memberId)
  193. return true
  194. },
  195. // 切换到家庭成员前检查(isSwitchable 由后端统一计算:非本人即可切换,含可登录成员)
  196. switchToMemberWithCheck({ commit }, payload) {
  197. var member = payload.member || {}
  198. if (member.isSwitchable === false) {
  199. uni.showToast({ title: '该成员暂不可切换', icon: 'none' })
  200. return false
  201. }
  202. commit('switchToMember', payload)
  203. return true
  204. },
  205. // 带密码校验退出成员切换(返回原用户身份)
  206. async switchBackWithPassword({ commit }, password) {
  207. if (!password) {
  208. uni.showToast({ title: '请输入原用户密码', icon: 'none' })
  209. return false
  210. }
  211. try {
  212. const res = await switchBackVerify(password)
  213. if (res.code === 200) {
  214. commit('switchBackFromMember')
  215. return true
  216. }
  217. uni.showToast({ title: res.message || '密码错误', icon: 'none' })
  218. return false
  219. } catch (e) {
  220. uni.showToast({ title: '校验失败', icon: 'none' })
  221. return false
  222. }
  223. }
  224. }
  225. ,
  226. modules: { tianpan, feedback, healthAlert, healthScore }
  227. })
  228. export default store