FamilyMemberCard.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template>
  2. <view class="member-card" :class="{ 'member-card--selected': isSelected }" @click="handleClick">
  3. <view class="member-card__avatar" :class="avatarColorClass">
  4. <image v-if="member.avatar" class="member-card__avatar-img" :src="member.avatar" mode="aspectFill" />
  5. <text v-else class="member-card__avatar-text">{{ member.nickname && member.nickname[0] || '?' }}</text>
  6. </view>
  7. <text class="member-card__name">{{ member.nickname }}</text>
  8. <view class="member-card__tags">
  9. <text class="member-card__role">{{ member.roleLabel || (member.memberType === 'child' ? '孩子' : '家长') }}</text>
  10. <text v-if="member.danLevel" class="member-card__dan">{{ member.danLevel }}</text>
  11. </view>
  12. <view v-if="isSelected" class="member-card__check">
  13. <text class="member-card__check-icon">✓</text>
  14. </view>
  15. </view>
  16. </template>
  17. <script>
  18. export default {
  19. name: 'FamilyMemberCard',
  20. props: {
  21. member: { type: Object, required: true },
  22. isSelected: { type: Boolean, default: false }
  23. },
  24. computed: {
  25. avatarColorClass: function() {
  26. var isParent = this.member.memberType === 'parent' || this.member.role === 'parent'
  27. if (isParent) return 'avatar-color--parent'
  28. return 'avatar-color--child-' + (this.member.id % 6)
  29. }
  30. },
  31. methods: {
  32. handleClick() {
  33. this.$emit('select', this.member)
  34. }
  35. }
  36. }
  37. </script>
  38. <style scoped>
  39. .member-card {
  40. display: inline-flex;
  41. flex-direction: column;
  42. align-items: center;
  43. width: 120rpx;
  44. padding: 16rpx 8rpx 12rpx;
  45. border-radius: 16rpx;
  46. background: #FFFFFF;
  47. border: 2rpx solid transparent;
  48. position: relative;
  49. transition: all 0.2s ease;
  50. }
  51. .member-card--selected {
  52. border-color: #5B9BD5;
  53. background: #EBF5FF;
  54. }
  55. .member-card__avatar {
  56. width: 72rpx;
  57. height: 72rpx;
  58. border-radius: 50%;
  59. display: flex;
  60. align-items: center;
  61. justify-content: center;
  62. margin-bottom: 8rpx;
  63. overflow: hidden;
  64. }
  65. .member-card__avatar-img {
  66. width: 72rpx;
  67. height: 72rpx;
  68. border-radius: 50%;
  69. }
  70. .member-card__avatar-text {
  71. font-size: 32rpx;
  72. font-weight: 600;
  73. color: #FFFFFF;
  74. }
  75. .member-card__name {
  76. font-size: 22rpx;
  77. color: #1E293B;
  78. font-weight: 500;
  79. max-width: 104rpx;
  80. overflow: hidden;
  81. text-overflow: ellipsis;
  82. white-space: nowrap;
  83. text-align: center;
  84. line-height: 1.3;
  85. }
  86. .member-card__tags {
  87. display: flex;
  88. flex-direction: column;
  89. align-items: center;
  90. margin-top: 4rpx;
  91. }
  92. .member-card__role {
  93. font-size: 18rpx;
  94. color: #64748B;
  95. line-height: 1.3;
  96. }
  97. .member-card__dan {
  98. font-size: 18rpx;
  99. color: #F97316;
  100. font-weight: 600;
  101. line-height: 1.3;
  102. }
  103. .member-card__check {
  104. position: absolute;
  105. bottom: 0;
  106. right: 0;
  107. width: 32rpx;
  108. height: 32rpx;
  109. background: #5B9BD5;
  110. border-radius: 50% 0 16rpx 0;
  111. display: flex;
  112. align-items: center;
  113. justify-content: center;
  114. }
  115. .member-card__check-icon {
  116. font-size: 18rpx;
  117. color: #FFFFFF;
  118. font-weight: 700;
  119. }
  120. /* Avatar colors — 家长统一蓝色,孩子多彩渐变 */
  121. .avatar-color--parent {
  122. background: linear-gradient(135deg, #5B9BD5, #3A7CC4);
  123. }
  124. .avatar-color--child-0 { background: linear-gradient(135deg, #5B9BD5, #3A7CC4); }
  125. .avatar-color--child-1 { background: linear-gradient(135deg, #0EA5E9, #6366F1); }
  126. .avatar-color--child-2 { background: linear-gradient(135deg, #10B981, #059669); }
  127. .avatar-color--child-3 { background: linear-gradient(135deg, #EC4899, #E11D48); }
  128. .avatar-color--child-4 { background: linear-gradient(135deg, #84CC16, #65A30D); }
  129. .avatar-color--child-5 { background: linear-gradient(135deg, #8B5CF6, #6D28D9); }
  130. </style>