member-wisdom-detail.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. <template>
  2. <view class="detail-container">
  3. <!-- 顶部导航 -->
  4. <view class="nav-bar">
  5. <view class="nav-back" @click="goBack">
  6. <text class="nav-back-icon">&#x2190;</text>
  7. </view>
  8. <text class="nav-title">智 · 成员详情</text>
  9. </view>
  10. <!-- 五维能量条 -->
  11. <FamilyEnergyBar
  12. dimensionCode="wisdom"
  13. :sandboxData="sandboxData"
  14. :dualDimension="dualDimension" />
  15. <!-- 成员信息卡 -->
  16. <view class="member-card" v-if="memberInfo">
  17. <view class="member-avatar wisdom-avatar">
  18. <text class="avatar-text">{{ memberInfo.name && memberInfo.name.charAt(0) || '孩' }}</text>
  19. </view>
  20. <view class="member-info">
  21. <text class="member-name">{{ memberInfo.name || '孩子' }}</text>
  22. <text class="member-role">智慧维度</text>
  23. </view>
  24. <view class="member-score" v-if="dualDimension">
  25. <text class="score-value wisdom-score">{{ dualDimension.energy || 0 }}</text>
  26. <text class="score-label">能量值</text>
  27. </view>
  28. </view>
  29. <!-- 家庭成员关系图谱(只读) -->
  30. <FamilyRelationGraph
  31. dimensionCode="wisdom"
  32. :selfId="selfId"
  33. :members="graphMembers"
  34. :energyMap="energyMapForGraph"
  35. :intimacyMap="intimacyMapForGraph"
  36. :interactive="false" />
  37. <!-- 今日任务 -->
  38. <DimensionTasks
  39. dimensionCode="wisdom"
  40. :tasks="dimensionTasks"
  41. @taskClick="onTaskClick"
  42. @moreTasks="goTasks" />
  43. <!-- 活动 -->
  44. <DimensionActivities
  45. dimensionCode="wisdom"
  46. :activities="dimensionActivities"
  47. @activityClick="goActivityDetail"
  48. @moreActivities="goMoreActivities" />
  49. <!-- 商品 -->
  50. <DimensionProducts
  51. dimensionCode="wisdom"
  52. :products="dimensionProducts"
  53. @productClick="goProductDetail"
  54. @moreProducts="goMoreProducts" />
  55. <!-- 底部占位 -->
  56. <view class="bottom-spacer"></view>
  57. </view>
  58. </template>
  59. <script>
  60. import FamilyEnergyBar from '../../components/FamilyEnergyBar.vue'
  61. import FamilyRelationGraph from '../../components/FamilyRelationGraph.vue'
  62. import DimensionTasks from '../../components/DimensionTasks.vue'
  63. import DimensionActivities from '../../components/DimensionActivities.vue'
  64. import DimensionProducts from '../../components/DimensionProducts.vue'
  65. import { getEnergyOverview, getFamilyEnergySandbox, getTodayTasksByCategory, getActivityList, getProductsByDomain, getChildren } from '../../utils/api.js'
  66. export default {
  67. components: { FamilyEnergyBar, FamilyRelationGraph, DimensionTasks, DimensionActivities, DimensionProducts },
  68. data() {
  69. return {
  70. childId: null,
  71. selfId: null,
  72. memberInfo: null,
  73. graphMembers: [],
  74. energyMapForGraph: {},
  75. intimacyMapForGraph: {},
  76. dimensionTasks: [],
  77. dimensionActivities: [],
  78. dimensionProducts: [],
  79. dualDimension: null,
  80. sandboxData: null
  81. }
  82. },
  83. onLoad: function(options) {
  84. if (options && options.memberId) {
  85. this.selfId = options.memberId
  86. this.childId = options.memberId
  87. this.loadMemberData()
  88. }
  89. },
  90. methods: {
  91. goBack: function() {
  92. uni.navigateBack()
  93. },
  94. loadMemberData: function() {
  95. var self = this
  96. var childId = this.childId
  97. if (!childId) return
  98. getEnergyOverview(childId).then(function(res) {
  99. if (res && res.data) {
  100. self.dualDimension = res.data
  101. }
  102. }).catch(function() {})
  103. getFamilyEnergySandbox(childId).then(function(res) {
  104. if (res && res.data) {
  105. self.sandboxData = res.data.sandboxData || null
  106. self.graphMembers = res.data.members || []
  107. self.energyMapForGraph = res.data.energyMap || {}
  108. self.intimacyMapForGraph = res.data.intimacyMap || {}
  109. }
  110. }).catch(function() {})
  111. getTodayTasksByCategory({ childId: childId, dimension: 'wisdom' }).then(function(res) {
  112. if (res && res.data) {
  113. self.dimensionTasks = res.data.slice(0, 5)
  114. }
  115. }).catch(function() {})
  116. getActivityList({ dimension: 'wisdom', page: 1, size: 5 }).then(function(res) {
  117. if (res && res.data) {
  118. self.dimensionActivities = res.data.records || res.data
  119. }
  120. }).catch(function() {})
  121. getProductsByDomain({ domain: 'wisdom', page: 1, size: 4 }).then(function(res) {
  122. if (res && res.data) {
  123. self.dimensionProducts = res.data.records || res.data
  124. }
  125. }).catch(function() {})
  126. },
  127. onTaskClick: function(task) {},
  128. goTasks: function() { uni.switchTab({ url: '/pages/tasks/tasks' }) },
  129. goActivityDetail: function(id) {},
  130. goMoreActivities: function() {
  131. uni.navigateTo({ url: '/pages/activity/index' })
  132. },
  133. goProductDetail: function(id) {
  134. var token = uni.getStorageSync('token')
  135. if (token) {
  136. uni.navigateTo({ url: '/pages/discover/product-detail/product-detail?id=' + id })
  137. } else {
  138. uni.navigateTo({ url: '/pages/login/login' })
  139. }
  140. },
  141. goMoreProducts: function() {
  142. uni.navigateTo({ url: '/pages/shop/index' })
  143. }
  144. }
  145. }
  146. </script>
  147. <style scoped>
  148. .detail-container {
  149. min-height: 100vh;
  150. background: #f5f7fa;
  151. padding-bottom: 120rpx;
  152. }
  153. .nav-bar {
  154. display: flex;
  155. flex-direction: row;
  156. align-items: center;
  157. padding: 80rpx 30rpx 20rpx;
  158. background: linear-gradient(135deg, #FFD700, #FFA500);
  159. }
  160. .nav-back {
  161. width: 60rpx;
  162. height: 60rpx;
  163. display: flex;
  164. align-items: center;
  165. justify-content: center;
  166. }
  167. .nav-back-icon {
  168. font-size: 36rpx;
  169. color: #fff;
  170. }
  171. .nav-title {
  172. flex: 1;
  173. text-align: center;
  174. font-size: 34rpx;
  175. font-weight: bold;
  176. color: #fff;
  177. margin-right: 60rpx;
  178. }
  179. .member-card {
  180. display: flex;
  181. flex-direction: row;
  182. align-items: center;
  183. background: #fff;
  184. margin: 20rpx 30rpx;
  185. padding: 30rpx;
  186. border-radius: 20rpx;
  187. box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.06);
  188. }
  189. .member-avatar {
  190. width: 100rpx;
  191. height: 100rpx;
  192. border-radius: 50%;
  193. display: flex;
  194. align-items: center;
  195. justify-content: center;
  196. margin-right: 24rpx;
  197. }
  198. .wisdom-avatar {
  199. background: linear-gradient(135deg, #FFD700, #FFA500);
  200. }
  201. .avatar-text {
  202. font-size: 40rpx;
  203. font-weight: bold;
  204. color: #fff;
  205. }
  206. .member-info {
  207. flex: 1;
  208. }
  209. .member-name {
  210. font-size: 32rpx;
  211. font-weight: bold;
  212. color: #333;
  213. display: block;
  214. }
  215. .member-role {
  216. font-size: 24rpx;
  217. color: #999;
  218. margin-top: 6rpx;
  219. display: block;
  220. }
  221. .member-score {
  222. text-align: center;
  223. }
  224. .score-value {
  225. font-size: 40rpx;
  226. font-weight: bold;
  227. display: block;
  228. }
  229. .wisdom-score {
  230. color: #B8860B;
  231. }
  232. .score-label {
  233. font-size: 22rpx;
  234. color: #999;
  235. display: block;
  236. }
  237. .bottom-spacer {
  238. height: 40rpx;
  239. }
  240. </style>