CircleCard.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <template>
  2. <view class="circle-card" :class="{ compact: compact }" @tap="$emit('click')">
  3. <view class="circle-card-left">
  4. <view class="circle-icon-wrap" :style="{ background: iconBg(type) }">
  5. <text class="circle-icon">{{ typeIcon(type) }}</text>
  6. </view>
  7. </view>
  8. <view class="circle-card-body">
  9. <text class="circle-name">{{ circle.name }}</text>
  10. <text class="circle-source">{{ sourceLabel(matchSource) }}</text>
  11. </view>
  12. <view class="circle-card-right">
  13. <text class="circle-count">{{ memberCount }}人</text>
  14. </view>
  15. </view>
  16. </template>
  17. <script>
  18. import { BrandColors } from '../../../utils/brand-colors.js'
  19. export default {
  20. name: 'CircleCard',
  21. props: {
  22. circle: {
  23. type: Object,
  24. required: true
  25. },
  26. compact: {
  27. type: Boolean,
  28. default: false
  29. }
  30. },
  31. computed: {
  32. type: function() {
  33. return this.circle && this.circle.type || 'topic'
  34. },
  35. matchSource: function() {
  36. return this.circle && this.circle.matchSource || ''
  37. },
  38. memberCount: function() {
  39. return this.circle && this.circle.memberCount || 0
  40. }
  41. },
  42. methods: {
  43. typeIcon: function(type) {
  44. var map = {
  45. activity: '\u{1F3AF}',
  46. ability: '\u{1F9E0}',
  47. health: '\u{1F4AA}',
  48. product: '\u{1F6CD}',
  49. provider: '\u{1F468}\u200D\u{1F3EB}',
  50. topic: '\u{1F4AC}',
  51. hobby: '\u{1F3A8}'
  52. }
  53. return map[type] || '\u{1F30D}'
  54. },
  55. iconBg: function(type) {
  56. var map = {
  57. activity: '#E0F7FA',
  58. ability: BrandColors.tintPurpleSoft,
  59. health: BrandColors.tintOrangeSoft,
  60. product: BrandColors.tintGreenSoft,
  61. provider: '#E3F2FD',
  62. topic: BrandColors.tintPinkSoft,
  63. hobby: '#FFF8E1'
  64. }
  65. return map[type] || '#F5F5F5'
  66. },
  67. sourceLabel: function(source) {
  68. var map = {
  69. activity: '源于共同活动',
  70. assessment: '源于共同测评',
  71. health_report: '源于健康状况',
  72. product: '源于共同商品',
  73. teacher: '源于同一规划师',
  74. article: '源于共同阅读',
  75. game: '源于共同游戏'
  76. }
  77. return map[source] || '源于共同兴趣'
  78. }
  79. }
  80. }
  81. </script>
  82. <style scoped lang="scss">
  83. .circle-card {
  84. display: flex;
  85. flex-direction: row;
  86. align-items: center;
  87. background: $app-surface;
  88. border-radius: 16rpx;
  89. padding: 20rpx;
  90. box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
  91. margin-bottom: 12rpx;
  92. }
  93. .circle-card:active {
  94. opacity: 0.8;
  95. }
  96. .circle-card.compact {
  97. padding: 12rpx;
  98. margin-bottom: 0;
  99. }
  100. .circle-card-left {
  101. margin-right: 16rpx;
  102. }
  103. .circle-icon-wrap {
  104. width: 64rpx;
  105. height: 64rpx;
  106. border-radius: 50%;
  107. display: flex;
  108. align-items: center;
  109. justify-content: center;
  110. }
  111. .circle-icon {
  112. font-size: 32rpx;
  113. }
  114. .circle-card-body {
  115. flex: 1;
  116. display: flex;
  117. flex-direction: column;
  118. }
  119. .circle-name {
  120. font-size: 28rpx;
  121. font-weight: 600;
  122. color: $facade-text-strong;
  123. }
  124. .circle-source {
  125. font-size: 22rpx;
  126. color: $facade-text-muted;
  127. }
  128. .circle-card-right {
  129. margin-left: 12rpx;
  130. }
  131. .circle-count {
  132. font-size: 22rpx;
  133. color: $brand-primary;
  134. background: $uni-primary-pale;
  135. padding: 4rpx 12rpx;
  136. border-radius: 20rpx;
  137. }
  138. </style>