HealthBadge.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <template>
  2. <view class="health-badge" v-if="levelInfo">
  3. <view class="badge-icon-wrap" :class="'badge-lv-' + (levelInfo.levelNum || 1)">
  4. <text class="badge-icon">{{ levelInfo.badgeIcon || '🌱' }}</text>
  5. </view>
  6. <view class="badge-info">
  7. <text class="badge-title">{{ levelInfo.title || '健康探索者' }}</text>
  8. <view class="badge-level-row">
  9. <text class="badge-level">L{{ levelInfo.levelNum || 1 }}</text>
  10. <text class="badge-score">{{ score }} 分</text>
  11. </view>
  12. <view class="badge-progress-bar" v-if="progress < 100">
  13. <view class="badge-progress-fill" :style="{ width: progress + '%' }"></view>
  14. </view>
  15. <text class="badge-next" v-if="nextLevel && progress < 100">
  16. 再{{ nextLevel.minScore - score }}分升级「{{ nextLevel.title }}」
  17. </text>
  18. <text class="badge-next" v-else-if="progress >= 100">
  19. 已达最高等级!
  20. </text>
  21. </view>
  22. </view>
  23. </template>
  24. <script>
  25. export default {
  26. props: {
  27. levelInfo: { type: Object, default: null },
  28. score: { type: Number, default: 0 },
  29. progress: { type: Number, default: 0 },
  30. nextLevel: { type: Object, default: null },
  31. streakDays: { type: Number, default: 0 }
  32. }
  33. }
  34. </script>
  35. <style scoped>
  36. .health-badge {
  37. display: flex;
  38. align-items: center;
  39. gap: 16rpx;
  40. padding: 20rpx 24rpx;
  41. background: linear-gradient(135deg, #F0FDF4, #ECFDF5);
  42. border-radius: 20rpx;
  43. margin: 0 20rpx 16rpx 20rpx;
  44. }
  45. .badge-icon-wrap {
  46. width: 80rpx;
  47. height: 80rpx;
  48. border-radius: 50%;
  49. display: flex;
  50. align-items: center;
  51. justify-content: center;
  52. flex-shrink: 0;
  53. }
  54. .badge-lv-1 { background: #D1FAE5; }
  55. .badge-lv-2 { background: #A7F3D0; }
  56. .badge-lv-3 { background: #FEF3C7; }
  57. .badge-lv-4 { background: #FED7AA; }
  58. .badge-lv-5 { background: #FECDD3; }
  59. .badge-icon { font-size: 40rpx; }
  60. .badge-info { flex: 1; min-width: 0; }
  61. .badge-title {
  62. font-size: 28rpx;
  63. font-weight: 700;
  64. color: #065F46;
  65. }
  66. .badge-level-row {
  67. display: flex;
  68. align-items: center;
  69. gap: 12rpx;
  70. margin-top: 4rpx;
  71. }
  72. .badge-level {
  73. font-size: 22rpx;
  74. color: #047857;
  75. font-weight: 600;
  76. }
  77. .badge-score {
  78. font-size: 22rpx;
  79. color: #6B7280;
  80. }
  81. .badge-progress-bar {
  82. height: 8rpx;
  83. background: #D1FAE5;
  84. border-radius: 999rpx;
  85. overflow: hidden;
  86. margin-top: 8rpx;
  87. }
  88. .badge-progress-fill {
  89. height: 100%;
  90. background: linear-gradient(90deg, #10B981, #34D399);
  91. border-radius: 999rpx;
  92. transition: width 0.5s ease;
  93. }
  94. .badge-next {
  95. font-size: 20rpx;
  96. color: #6B7280;
  97. margin-top: 4rpx;
  98. display: block;
  99. }
  100. </style>