red-packet-popup.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <template>
  2. <u-popup v-model="show" mode="bottom" border-radius="24">
  3. <view class="red-packet-popup">
  4. <view class="popup-header">
  5. <text>选择红包</text>
  6. <u-icon name="close" size="28" color="#999" class="close-icon" @click="close"></u-icon>
  7. </view>
  8. <scroll-view scroll-y class="packet-list" v-if="list && list.length > 0">
  9. <view class="packet-item" v-for="(item, index) in list" :key="index" @click="selectPacket(index)">
  10. <view class="packet-info">
  11. <view class="packet-name">{{ item.couponName }} ¥{{ item.faceMoney }}</view>
  12. <view class="packet-desc">满{{ item.thresholdMoney }}元可用</view>
  13. <view class="packet-time">{{ item.effectStartTime }}至{{ item.effectEndTime }}</view>
  14. </view>
  15. <view class="packet-check">
  16. <u-icon name="checkmark-circle-fill" size="40"
  17. :color="selectedIndex === index ? '#ff4500' : '#ccc'"></u-icon>
  18. </view>
  19. </view>
  20. </scroll-view>
  21. <view class="empty-state" v-else>
  22. <image src="https://shuhi.oss-cn-qingdao.aliyuncs.com/mini/no-data.png"
  23. style="width: 260rpx; height: 260rpx" mode="aspectFit"></image>
  24. <view class="empty-text">暂无可用红包</view>
  25. </view>
  26. <view class="popup-footer" v-if="list && list.length > 0">
  27. <u-button type="primary" shape="circle" @click="confirm">确认</u-button>
  28. </view>
  29. </view>
  30. </u-popup>
  31. </template>
  32. <script>
  33. export default {
  34. props: {
  35. value: {
  36. type: Boolean,
  37. default: false
  38. },
  39. list: {
  40. type: Array,
  41. default: () => []
  42. }
  43. },
  44. data() {
  45. return {
  46. show: false,
  47. selectedIndex: -1,
  48. }
  49. },
  50. watch: {
  51. value(val) {
  52. this.show = val;
  53. },
  54. show(val) {
  55. this.$emit('input', val);
  56. }
  57. },
  58. methods: {
  59. close() {
  60. this.show = false;
  61. },
  62. selectPacket(index) {
  63. if (this.selectedIndex === index) {
  64. // 如果点击的是已选中的项,则取消选中
  65. this.selectedIndex = -1;
  66. } else {
  67. this.selectedIndex = index;
  68. }
  69. },
  70. confirm() {
  71. if (this.list && this.list.length > 0 && this.selectedIndex !== -1) {
  72. this.$emit('confirm', this.list[this.selectedIndex]);
  73. } else {
  74. this.$emit('confirm', null);
  75. }
  76. this.close();
  77. }
  78. }
  79. }
  80. </script>
  81. <style lang="scss" scoped>
  82. .red-packet-popup {
  83. height: 100%;
  84. max-height: 80vh;
  85. display: flex;
  86. flex-direction: column;
  87. overflow: hidden;
  88. .popup-header {
  89. padding: 30rpx;
  90. text-align: center;
  91. font-size: 32rpx;
  92. font-weight: bold;
  93. position: sticky;
  94. top: 0;
  95. background-color: #fff;
  96. border-bottom: 1rpx solid #eee;
  97. .close-icon {
  98. position: absolute;
  99. right: 30rpx;
  100. top: 40rpx;
  101. }
  102. }
  103. .packet-list {
  104. flex: 1;
  105. padding: 20rpx;
  106. box-sizing: border-box;
  107. height: 600rpx; // Give it a fixed height for scroll
  108. overflow-y: auto;
  109. .packet-item {
  110. display: flex;
  111. align-items: center;
  112. padding: 20rpx 30rpx;
  113. border-bottom: 1rpx solid #f5f5f5;
  114. .packet-info {
  115. flex: 1;
  116. .packet-name {
  117. font-size: 30rpx;
  118. color: #ff4500;
  119. font-weight: bold;
  120. margin-bottom: 10rpx;
  121. }
  122. .packet-desc {
  123. font-size: 26rpx;
  124. color: #333;
  125. margin-bottom: 6rpx;
  126. }
  127. .packet-time {
  128. font-size: 22rpx;
  129. color: #999;
  130. }
  131. }
  132. }
  133. }
  134. .empty-state {
  135. display: flex;
  136. flex-direction: column;
  137. align-items: center;
  138. justify-content: center;
  139. padding: 60rpx 0;
  140. .empty-text {
  141. color: #999;
  142. font-size: 28rpx;
  143. margin-top: 20rpx;
  144. }
  145. }
  146. .popup-footer {
  147. padding: 20rpx 40rpx;
  148. padding-bottom: env(safe-area-inset-bottom);
  149. }
  150. }
  151. </style>