HealthDimensionsSection.vue 3.5 KB

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