HealthDimensionsSection.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. <template>
  2. <view class="health-dimensions-section">
  3. <view class="section-header">
  4. <text class="section-title">七维健康全景</text>
  5. <text class="section-more" @click="goHealthDimensions">查看详情 ›</text>
  6. </view>
  7. <!-- 加载态 -->
  8. <view v-if="!healthData" class="loading-state">
  9. <text class="loading-text">加载中...</text>
  10. </view>
  11. <!-- 维度列表(无数据时显示7项默认值,分数为0) -->
  12. <view v-else class="dimension-grid">
  13. <view
  14. class="dimension-item"
  15. v-for="dim in displayDimensions"
  16. :key="dim.dimension || dim.key"
  17. @click="goDimensionDetail(dim)">
  18. <text class="dimension-icon">{{ getDimIcon(dim.dimension || dim.key) }}</text>
  19. <text class="dimension-name">{{ dim.label }}</text>
  20. <view class="dimension-score-bar">
  21. <view
  22. class="dimension-score-fill"
  23. :style="'width:' + Math.min(100, (dim.score || 0)) + '%'"></view>
  24. </view>
  25. <text class="dimension-score">{{ dim.score || 0 }}分</text>
  26. </view>
  27. </view>
  28. </view>
  29. </template>
  30. <script>
  31. var DIM_ICONS = {
  32. growth: '\u{1F4AA}',
  33. sleep: '\u{1F634}',
  34. vision: '\u{1F441}',
  35. immunity: '\u{1F6E1}',
  36. nutrition: '\u{1F966}',
  37. gut: '\u{1F9A9}',
  38. exercise: '\u{1F3C3}',
  39. body: '\u{1F3C3}',
  40. mind: '\u{1F9E0}',
  41. wisdom: '\u{1F4D6}',
  42. action: '\u{1F331}',
  43. wealth: '\u{1F4B0}',
  44. social: '\u{1F91D}',
  45. family: '\u{1F46A}'
  46. }
  47. var DEFAULT_DIMENSIONS = [
  48. { dimension: 'growth', label: '成长发育', score: 0 },
  49. { dimension: 'sleep', label: '睡眠', score: 0 },
  50. { dimension: 'vision', label: '视力', score: 0 },
  51. { dimension: 'immunity', label: '免疫力', score: 0 },
  52. { dimension: 'nutrition', label: '营养', score: 0 },
  53. { dimension: 'gut', label: '肠道', score: 0 },
  54. { dimension: 'exercise', label: '运动', score: 0 }
  55. ]
  56. export default {
  57. props: {
  58. healthData: { type: Object, default: null },
  59. activeChildId: { type: [Number, String], default: null }
  60. },
  61. computed: {
  62. displayDimensions: function() {
  63. if (this.healthData && this.healthData.dimensions && this.healthData.dimensions.length > 0) {
  64. return this.healthData.dimensions
  65. }
  66. return DEFAULT_DIMENSIONS
  67. }
  68. },
  69. methods: {
  70. getDimIcon: function(key) {
  71. return DIM_ICONS[key] || '\u{2B50}'
  72. },
  73. goHealthDimensions: function() {
  74. // FIX: 移除阻塞弹窗,始终允许导航
  75. uni.navigateTo({ url: '/pages/body-detail/health-dimensions?childId=' + (this.activeChildId || '') })
  76. },
  77. goDimensionDetail: function(dim) {
  78. var key = dim.dimension || dim.key
  79. if (!key) return
  80. uni.navigateTo({ url: '/pages/body-detail/dimension-detail?dimension=' + key + '&childId=' + (this.activeChildId || '') })
  81. }
  82. }
  83. }
  84. </script>
  85. <style scoped>
  86. .health-dimensions-section {
  87. margin: 20rpx 20rpx;
  88. background: #FFFFFF;
  89. border-radius: 24rpx;
  90. padding: 24rpx 24rpx 32rpx;
  91. box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
  92. }
  93. .section-header {
  94. display: flex;
  95. justify-content: space-between;
  96. align-items: center;
  97. margin-bottom: 24rpx;
  98. }
  99. .section-title {
  100. font-size: 30rpx;
  101. font-weight: bold;
  102. color: #333;
  103. }
  104. .section-more {
  105. font-size: 24rpx;
  106. color: #FF8C42;
  107. }
  108. .loading-state, .empty-state {
  109. display: flex;
  110. justify-content: center;
  111. padding: 40rpx 0;
  112. }
  113. .loading-text, .empty-tip {
  114. font-size: 24rpx;
  115. color: #999;
  116. }
  117. .dimension-grid {
  118. display: flex;
  119. flex-wrap: wrap;
  120. gap: 20rpx;
  121. }
  122. .dimension-item {
  123. width: calc(33.33% - 14rpx);
  124. display: flex;
  125. flex-direction: column;
  126. align-items: center;
  127. padding: 16rpx 0;
  128. }
  129. .dimension-icon {
  130. font-size: 40rpx;
  131. margin-bottom: 8rpx;
  132. }
  133. .dimension-name {
  134. font-size: 24rpx;
  135. color: #333;
  136. font-weight: 500;
  137. margin-bottom: 10rpx;
  138. }
  139. .dimension-score-bar {
  140. width: 100%;
  141. height: 8rpx;
  142. background: #F5F5F5;
  143. border-radius: 4rpx;
  144. overflow: hidden;
  145. margin-bottom: 6rpx;
  146. }
  147. .dimension-score-fill {
  148. height: 100%;
  149. background: linear-gradient(90deg, #FF8C42, #FFB088);
  150. border-radius: 4rpx;
  151. transition: width 0.3s;
  152. }
  153. .dimension-score {
  154. font-size: 22rpx;
  155. color: #FF8C42;
  156. font-weight: 500;
  157. }
  158. </style>