red-packet-popup.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. this.selectedIndex = index;
  64. },
  65. confirm() {
  66. if (this.list && this.list.length > 0 && this.selectedIndex !== -1) {
  67. this.$emit('confirm', this.list[this.selectedIndex]);
  68. } else {
  69. this.$emit('confirm', null);
  70. }
  71. this.close();
  72. }
  73. }
  74. }
  75. </script>
  76. <style lang="scss" scoped>
  77. .red-packet-popup {
  78. height: 100%;
  79. max-height: 80vh;
  80. display: flex;
  81. flex-direction: column;
  82. overflow: hidden;
  83. .popup-header {
  84. padding: 30rpx;
  85. text-align: center;
  86. font-size: 32rpx;
  87. font-weight: bold;
  88. position: sticky;
  89. top: 0;
  90. background-color: #fff;
  91. border-bottom: 1rpx solid #eee;
  92. .close-icon {
  93. position: absolute;
  94. right: 30rpx;
  95. top: 40rpx;
  96. }
  97. }
  98. .packet-list {
  99. flex: 1;
  100. padding: 20rpx;
  101. box-sizing: border-box;
  102. height: 600rpx; // Give it a fixed height for scroll
  103. overflow-y: auto;
  104. .packet-item {
  105. display: flex;
  106. align-items: center;
  107. padding: 20rpx 30rpx;
  108. border-bottom: 1rpx solid #f5f5f5;
  109. .packet-info {
  110. flex: 1;
  111. .packet-name {
  112. font-size: 30rpx;
  113. color: #ff4500;
  114. font-weight: bold;
  115. margin-bottom: 10rpx;
  116. }
  117. .packet-desc {
  118. font-size: 26rpx;
  119. color: #333;
  120. margin-bottom: 6rpx;
  121. }
  122. .packet-time {
  123. font-size: 22rpx;
  124. color: #999;
  125. }
  126. }
  127. }
  128. }
  129. .empty-state {
  130. display: flex;
  131. flex-direction: column;
  132. align-items: center;
  133. justify-content: center;
  134. padding: 60rpx 0;
  135. .empty-text {
  136. color: #999;
  137. font-size: 28rpx;
  138. margin-top: 20rpx;
  139. }
  140. }
  141. .popup-footer {
  142. padding: 20rpx 40rpx;
  143. padding-bottom: env(safe-area-inset-bottom);
  144. }
  145. }
  146. </style>