index.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <template>
  2. <view>
  3. <!-- 家长端首页 -->
  4. <parent-index v-if="currentRole === 'parent'" />
  5. <!-- 孩子端首页 -->
  6. <child-index v-else-if="currentRole === 'child'" />
  7. <!-- 成长规划师首页 -->
  8. <teacher-index v-else-if="currentRole === 'teacher'" />
  9. <!-- 默认显示加载中或错误提示 -->
  10. <view v-else class="loading-container">
  11. <text>加载中...</text>
  12. </view>
  13. </view>
  14. </template>
  15. <script>
  16. import ParentIndex from './parent-index.vue'
  17. import ChildIndex from './child-index.vue'
  18. import TeacherIndex from '../teacher/index.vue'
  19. import { acceptParentInvite } from '../../utils/api.js'
  20. export default {
  21. components: {
  22. ParentIndex,
  23. ChildIndex,
  24. TeacherIndex
  25. },
  26. data() {
  27. return {
  28. currentRole: ''
  29. }
  30. },
  31. onLoad(options) {
  32. if (!this.isLoggedIn()) {
  33. this.goDiscover()
  34. return
  35. }
  36. this.syncRoleAndTabBar()
  37. // 检查是否有邀请码参数
  38. if (options.inviteCode && options.type === 'parent_invite') {
  39. this.handleParentInvite(options.inviteCode)
  40. } else {
  41. // 检查是否有存储的邀请码(登录后返回)
  42. const storedCode = uni.getStorageSync('inviteCode')
  43. const storedType = uni.getStorageSync('inviteType')
  44. if (storedCode && storedType === 'parent_invite') {
  45. this.handleParentInvite(storedCode)
  46. // 清除存储
  47. uni.removeStorageSync('inviteCode')
  48. uni.removeStorageSync('inviteType')
  49. }
  50. }
  51. },
  52. onShow() {
  53. if (!this.isLoggedIn()) {
  54. this.goDiscover()
  55. return
  56. }
  57. this.syncRoleAndTabBar()
  58. },
  59. methods: {
  60. isLoggedIn() {
  61. return !!uni.getStorageSync('token')
  62. },
  63. goDiscover() {
  64. uni.switchTab({ url: '/pages/discover/index' })
  65. },
  66. normalizeCurrentRole() {
  67. const role = uni.getStorageSync('role') || 'parent'
  68. const currentRole = uni.getStorageSync('currentRole')
  69. if (!currentRole) {
  70. return role
  71. }
  72. // 非规划师账号不允许落到规划师首页
  73. if (currentRole === 'teacher' && role !== 'teacher') {
  74. return role
  75. }
  76. // 只有家长账号允许切换到孩子视角
  77. if (currentRole === 'child' && role !== 'parent') {
  78. return role
  79. }
  80. return currentRole
  81. },
  82. syncTabBarText(role) {
  83. const secondText = role === 'teacher' ? '家庭管理' : '任务'
  84. const thirdText = role === 'teacher' ? '消息' : '心愿单'
  85. uni.setTabBarItem({ index: 1, text: secondText })
  86. uni.setTabBarItem({ index: 2, text: thirdText })
  87. },
  88. syncRoleAndTabBar() {
  89. this.currentRole = this.normalizeCurrentRole()
  90. uni.setStorageSync('currentRole', this.currentRole)
  91. this.syncTabBarText(this.currentRole)
  92. },
  93. async handleParentInvite(code) {
  94. // 延迟显示,等待登录完成
  95. setTimeout(async () => {
  96. const hasToken = uni.getStorageSync('token')
  97. if (!hasToken) {
  98. // 未登录,先去登录
  99. uni.reLaunch({
  100. url: '/pages/login/login?inviteCode=' + code
  101. })
  102. return
  103. }
  104. // 已登录,显示确认框
  105. uni.showModal({
  106. title: '加入家庭',
  107. content: '您已被邀请加入家庭,是否接受?',
  108. success: async (res) => {
  109. if (res.confirm) {
  110. try {
  111. uni.showLoading({ title: '加入中...' })
  112. const result = await acceptParentInvite(code)
  113. uni.hideLoading()
  114. if (result.code === 200) {
  115. const { familyId, role, token } = result.data
  116. uni.setStorageSync('familyId', familyId)
  117. uni.setStorageSync('role', role)
  118. uni.setStorageSync('token', token)
  119. uni.showToast({ title: '加入成功', icon: 'success' })
  120. // 刷新页面
  121. setTimeout(() => {
  122. uni.reLaunch({ url: '/pages/index/index' })
  123. }, 1500)
  124. }
  125. } catch (e) {
  126. uni.hideLoading()
  127. uni.showToast({ title: e.message || '加入失败', icon: 'none' })
  128. }
  129. }
  130. }
  131. })
  132. }, 500)
  133. }
  134. }
  135. }
  136. </script>
  137. <style>
  138. .loading-container {
  139. display: flex;
  140. justify-content: center;
  141. align-items: center;
  142. height: 100vh;
  143. }
  144. </style>