HealthDimensionsSection.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. <!-- 空数据 -->
  12. <view v-else-if="!healthData.dimensions || healthData.dimensions.length === 0" class="empty-state">
  13. <text class="empty-tip">暂无健康数据</text>
  14. </view>
  15. <!-- 维度列表 -->
  16. <view v-else class="dimension-grid">
  17. <view
  18. class="dimension-item"
  19. v-for="dim in healthData.dimensions"
  20. :key="dim.dimension || dim.key"
  21. @click="goDimensionDetail(dim)">
  22. <text class="dimension-icon">{{ getDimIcon(dim.dimension || dim.key) }}</text>
  23. <text class="dimension-name">{{ dim.label }}</text>
  24. <view class="dimension-score-bar">
  25. <view
  26. class="dimension-score-fill"
  27. :style="'width:' + Math.min(100, dim.score || 0) + '%'"></view>
  28. </view>
  29. <text class="dimension-score">{{ dim.score || 0 }}分</text>
  30. </view>
  31. </view>
  32. </view>
  33. </template>
  34. <script>
  35. var DIM_ICONS = {
  36. growth: '\u{1F4AA}',
  37. sleep: '\u{1F634}',
  38. vision: '\u{1F441}',
  39. immunity: '\u{1F6E1}',
  40. nutrition: '\u{1F966}',
  41. gut: '\u{1F9A9}',
  42. exercise: '\u{1F3C3}',
  43. body: '\u{1F3C3}',
  44. mind: '\u{1F9E0}',
  45. wisdom: '\u{1F4D6}',
  46. action: '\u{1F331}',
  47. wealth: '\u{1F4B0}',
  48. social: '\u{1F91D}',
  49. family: '\u{1F46A}'
  50. }
  51. export default {
  52. props: {
  53. healthData: { type: Object, default: null },
  54. activeChildId: { type: [Number, String], default: null }
  55. },
  56. methods: {
  57. getDimIcon: function(key) {
  58. return DIM_ICONS[key] || '\u{2B50}'
  59. },
  60. goHealthDimensions: function() {
  61. if (!this.activeChildId) {
  62. uni.showToast({ title: '请先选择孩子', icon: 'none' })
  63. return
  64. }
  65. uni.navigateTo({ url: '/pages/body-detail/health-dimensions?childId=' + this.activeChildId })
  66. },
  67. goDimensionDetail: function(dim) {
  68. var key = dim.dimension || dim.key
  69. if (!key) return
  70. uni.navigateTo({ url: '/pages/body-detail/dimension-detail?dimension=' + key + '&childId=' + this.activeChildId })
  71. }
  72. }
  73. }
  74. </script>
  75. <style scoped>
  76. .health-dimensions-section {
  77. margin: 20rpx 20rpx;
  78. background: #FFFFFF;
  79. border-radius: 24rpx;
  80. padding: 24rpx 24rpx 32rpx;
  81. box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
  82. }
  83. .section-header {
  84. display: flex;
  85. justify-content: space-between;
  86. align-items: center;
  87. margin-bottom: 24rpx;
  88. }
  89. .section-title {
  90. font-size: 30rpx;
  91. font-weight: bold;
  92. color: #333;
  93. }
  94. .section-more {
  95. font-size: 24rpx;
  96. color: #FF8C42;
  97. }
  98. .loading-state, .empty-state {
  99. display: flex;
  100. justify-content: center;
  101. padding: 40rpx 0;
  102. }
  103. .loading-text, .empty-tip {
  104. font-size: 24rpx;
  105. color: #999;
  106. }
  107. .dimension-grid {
  108. display: flex;
  109. flex-wrap: wrap;
  110. gap: 20rpx;
  111. }
  112. .dimension-item {
  113. width: calc(33.33% - 14rpx);
  114. display: flex;
  115. flex-direction: column;
  116. align-items: center;
  117. padding: 16rpx 0;
  118. }
  119. .dimension-icon {
  120. font-size: 40rpx;
  121. margin-bottom: 8rpx;
  122. }
  123. .dimension-name {
  124. font-size: 24rpx;
  125. color: #333;
  126. font-weight: 500;
  127. margin-bottom: 10rpx;
  128. }
  129. .dimension-score-bar {
  130. width: 100%;
  131. height: 8rpx;
  132. background: #F5F5F5;
  133. border-radius: 4rpx;
  134. overflow: hidden;
  135. margin-bottom: 6rpx;
  136. }
  137. .dimension-score-fill {
  138. height: 100%;
  139. background: linear-gradient(90deg, #FF8C42, #FFB088);
  140. border-radius: 4rpx;
  141. transition: width 0.3s;
  142. }
  143. .dimension-score {
  144. font-size: 22rpx;
  145. color: #FF8C42;
  146. font-weight: 500;
  147. }
  148. </style>