FamilyHealthRanking.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. <template>
  2. <view class="family-ranking" v-if="list && list.length > 0">
  3. <view class="ranking-header">
  4. <text class="ranking-title">👨‍👩‍👧‍👦 家庭健康榜</text>
  5. <text class="ranking-total">全家积分: {{ totalScore }}</text>
  6. </view>
  7. <view class="ranking-list">
  8. <view class="ranking-item" v-for="(m, idx) in list" :key="m.memberId">
  9. <text class="rank-medal">{{ idx === 0 ? '🥇' : idx === 1 ? '🥈' : idx === 2 ? '🥉' : '#' + m.rank }}</text>
  10. <image class="rank-avatar" :src="m.avatar || '/static/default-avatar.png'" mode="aspectFill"></image>
  11. <view class="rank-info">
  12. <text class="rank-name">{{ m.name }}</text>
  13. <text class="rank-level">{{ m.levelTitle || '' }}</text>
  14. </view>
  15. <view class="rank-score-wrap">
  16. <text class="rank-score">{{ m.score }}</text>
  17. <text class="rank-unit">分</text>
  18. </view>
  19. <text class="rank-streak" v-if="m.streakDays && m.streakDays > 0">🔥 {{ m.streakDays }}天</text>
  20. </view>
  21. </view>
  22. </view>
  23. </template>
  24. <script>
  25. export default {
  26. props: {
  27. list: { type: Array, default: function() { return [] } },
  28. totalScore: { type: Number, default: 0 }
  29. }
  30. }
  31. </script>
  32. <style scoped>
  33. .family-ranking {
  34. background: #fff;
  35. border-radius: 20rpx;
  36. margin: 0 20rpx 20rpx 20rpx;
  37. padding: 20rpx;
  38. box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
  39. }
  40. .ranking-header {
  41. display: flex;
  42. justify-content: space-between;
  43. align-items: center;
  44. margin-bottom: 16rpx;
  45. }
  46. .ranking-title {
  47. font-size: 30rpx;
  48. font-weight: 700;
  49. color: #1E293B;
  50. }
  51. .ranking-total {
  52. font-size: 24rpx;
  53. color: #F97316;
  54. font-weight: 600;
  55. }
  56. .ranking-item {
  57. display: flex;
  58. align-items: center;
  59. gap: 12rpx;
  60. padding: 12rpx 0;
  61. border-bottom: 1rpx solid #F1F5F9;
  62. }
  63. .ranking-item:last-child { border-bottom: none; }
  64. .rank-medal { font-size: 32rpx; width: 48rpx; text-align: center; }
  65. .rank-avatar {
  66. width: 56rpx;
  67. height: 56rpx;
  68. border-radius: 50%;
  69. flex-shrink: 0;
  70. }
  71. .rank-info { flex: 1; min-width: 0; }
  72. .rank-name {
  73. font-size: 26rpx;
  74. font-weight: 600;
  75. color: #334155;
  76. }
  77. .rank-level {
  78. font-size: 20rpx;
  79. color: #94A3B8;
  80. margin-top: 2rpx;
  81. display: block;
  82. }
  83. .rank-score-wrap {
  84. display: flex;
  85. align-items: baseline;
  86. gap: 4rpx;
  87. }
  88. .rank-score {
  89. font-size: 32rpx;
  90. font-weight: 700;
  91. color: #10B981;
  92. }
  93. .rank-unit {
  94. font-size: 22rpx;
  95. color: #94A3B8;
  96. }
  97. .rank-streak {
  98. font-size: 22rpx;
  99. color: #F97316;
  100. white-space: nowrap;
  101. }
  102. </style>