MicroActionCard.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <template>
  2. <view class="micro-action-card">
  3. <view class="mac-header">
  4. <text class="mac-title">☕️ 今天的小行动</text>
  5. <text class="mac-status" v-if="completed">已完成 ✅</text>
  6. <text class="mac-status" v-else>点击完成 +1能量</text>
  7. </view>
  8. <view class="mac-body">
  9. <template v-if="loading">
  10. <view class="mac-loading">
  11. <text class="mac-loading-text">加载中...</text>
  12. </view>
  13. </template>
  14. <template v-else-if="completed">
  15. <view class="mac-done">
  16. <view class="mac-done-icon">✓</view>
  17. <text class="mac-done-text">今日微行动已完成</text>
  18. </view>
  19. <text class="mac-energy">+1 身能量</text>
  20. </template>
  21. <template v-else-if="!action">
  22. <view class="mac-empty">
  23. <text class="mac-empty-text">所有行动已就绪</text>
  24. </view>
  25. </template>
  26. <template v-else>
  27. <view class="mac-action-display">
  28. <text class="mac-action-icon">{{ action.icon }}</text>
  29. <text class="mac-action-name">{{ action.name }}</text>
  30. <text class="mac-action-desc">{{ action.description }}</text>
  31. </view>
  32. <view class="mac-action-btn" @click="doComplete">
  33. <text class="mac-btn-text">完成</text>
  34. </view>
  35. </template>
  36. </view>
  37. </view>
  38. </template>
  39. <script>
  40. import api from '@/utils/api.js'
  41. export default {
  42. props: {
  43. memberId: { type: Number, default: null }
  44. },
  45. data: function() {
  46. return {
  47. action: null,
  48. completed: false,
  49. loading: false
  50. }
  51. },
  52. created: function() {
  53. this.loadTodayAction()
  54. },
  55. methods: {
  56. loadTodayAction: function() {
  57. if (!this.memberId) return
  58. var self = this
  59. this.loading = true
  60. api.microActionToday({ memberId: self.memberId }).then(function(res) {
  61. self.loading = false
  62. if (res.data) {
  63. self.action = res.data.action
  64. self.completed = res.data.completed
  65. }
  66. }).catch(function() {
  67. self.loading = false
  68. self.action = null
  69. })
  70. },
  71. doComplete: function() {
  72. if (!this.memberId) {
  73. uni.showToast({ title: '请先选择孩子', icon: 'none' })
  74. return
  75. }
  76. if (!this.action) return
  77. if (this.loading) return
  78. var self = this
  79. this.loading = true
  80. api.microActionComplete({
  81. memberId: self.memberId,
  82. actionId: self.action.id
  83. }).then(function(res) {
  84. self.loading = false
  85. if (res.code === 200) {
  86. self.completed = true
  87. uni.showToast({ title: '太棒了!+1能量', icon: 'none' })
  88. self.$emit('completed')
  89. }
  90. }).catch(function(err) {
  91. self.loading = false
  92. // Error already shown by api.js interceptor
  93. })
  94. }
  95. },
  96. watch: {
  97. memberId: function() {
  98. this.action = null
  99. this.completed = false
  100. this.loadTodayAction()
  101. }
  102. }
  103. }
  104. </script>
  105. <style scoped>
  106. .micro-action-card {
  107. background: linear-gradient(135deg, #FFF7ED, #FFEDD5);
  108. border-radius: 20rpx;
  109. padding: 24rpx;
  110. margin: 20rpx 20rpx 0 20rpx;
  111. box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
  112. border: 1rpx solid #FED7AA;
  113. }
  114. .mac-header {
  115. display: flex;
  116. justify-content: space-between;
  117. align-items: center;
  118. margin-bottom: 16rpx;
  119. }
  120. .mac-title { font-size: 28rpx; font-weight: 700; color: #9A3412; }
  121. .mac-status { font-size: 22rpx; color: #EA580C; }
  122. .mac-body { display: flex; flex-direction: column; align-items: center; }
  123. .mac-loading { padding: 20rpx 0; }
  124. .mac-loading-text { font-size: 24rpx; color: #999; }
  125. .mac-done {
  126. display: flex;
  127. align-items: center;
  128. gap: 12rpx;
  129. padding: 12rpx 0;
  130. }
  131. .mac-done-icon {
  132. width: 48rpx;
  133. height: 48rpx;
  134. border-radius: 24rpx;
  135. background: linear-gradient(135deg, #10B981, #34D399);
  136. color: #fff;
  137. font-size: 24rpx;
  138. display: flex;
  139. align-items: center;
  140. justify-content: center;
  141. }
  142. .mac-done-text { font-size: 28rpx; color: #10B981; font-weight: 600; }
  143. .mac-energy { font-size: 22rpx; color: #999; margin-top: 6rpx; }
  144. .mac-empty { padding: 20rpx 0; }
  145. .mac-empty-text { font-size: 24rpx; color: #999; }
  146. .mac-action-display {
  147. display: flex;
  148. flex-direction: column;
  149. align-items: center;
  150. padding: 12rpx 0;
  151. gap: 8rpx;
  152. }
  153. .mac-action-icon { font-size: 72rpx; }
  154. .mac-action-name { font-size: 36rpx; font-weight: 700; color: #333; }
  155. .mac-action-desc { font-size: 24rpx; color: #888; text-align: center; }
  156. .mac-action-btn {
  157. background: linear-gradient(135deg, #F97316, #FB923C);
  158. color: #fff;
  159. font-size: 28rpx;
  160. font-weight: 600;
  161. padding: 16rpx 80rpx;
  162. border-radius: 40rpx;
  163. margin-top: 16rpx;
  164. }
  165. .mac-action-btn:active { opacity: 0.8; }
  166. .mac-btn-text { color: #fff; }
  167. </style>