index.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <template>
  2. <layout-page>
  3. <scroll-view class="scrollBox" scroll-y="true" @scrolltolower="loadingMore">
  4. <view class="defaultBgc content">
  5. <view
  6. v-for="item in items"
  7. :key="item.id"
  8. class="content-item"
  9. :class="{ used: item.status === 2, disabled: item.status === 3 }"
  10. >
  11. <view class="msg">
  12. <view class="item">
  13. <view class="name">{{ item.name }}</view>
  14. <view class="price">
  15. <uni-icons color="#f30" type="icon-renminbi1688" size="16" custom-prefix="iconfont"></uni-icons>
  16. {{ item.price }}
  17. </view>
  18. </view>
  19. <view class="item">
  20. <view class="desc">有效期:{{ item.legalTime }}</view>
  21. <view class="desc">满 {{ item.used }} 可用</view>
  22. </view>
  23. </view>
  24. <view class="use">
  25. <button
  26. class="btn"
  27. :class="{ disabled: item.status !== 1 }"
  28. @tap="handleTo(item.status)"
  29. >{{ item.status === 1 ? '立即使用' : item.status === 2 ? '已使用' : '已过期'}}</button>
  30. </view>
  31. </view>
  32. <uni-load-more :status="more" />
  33. </view>
  34. </scroll-view>
  35. </layout-page>
  36. </template>
  37. <script setup>
  38. import { ref } from 'vue'
  39. import {
  40. getCouponPage
  41. } from '@/api/sign'
  42. import { timesTampChange } from '@/utils/date'
  43. const pageInfo = ref({
  44. pageNo:1,
  45. pageSize: 20
  46. })
  47. const total = ref(0)
  48. const items = ref([])
  49. const more = ref('more')
  50. getMyCoupon()
  51. async function getMyCoupon () {
  52. try {
  53. const { data } = await getCouponPage({ ...pageInfo.value })
  54. if (!data || !data.list || !data.list.length) {
  55. if (pageInfo.value.pageNo === 1) {
  56. more.value = 'more'
  57. return
  58. }
  59. pageInfo.value.pageNo--
  60. more.value = 'more'
  61. return
  62. }
  63. items.value.push(...data.list.map(e => {
  64. return {
  65. ...e,
  66. price: (e.discountPrice / 100).toFixed(2),
  67. legalTime: timesTampChange(e.validStartTime, 'Y-M-D') + ' 至 ' + timesTampChange(e.validEndTime, 'Y-M-D'),
  68. used: (e.usePrice / 100).toFixed(2)
  69. }
  70. }))
  71. total.value = +data.total || 0
  72. more.value = items.value.length >= total.value ? 'noMore' : 'more'
  73. } catch (error) {
  74. if (pageInfo.value.pageNo === 1) {
  75. more.value = 'more'
  76. return
  77. }
  78. pageInfo.value.pageNo--
  79. more.value = 'more'
  80. }
  81. }
  82. function handleTo (status) {
  83. if (status !== 1) {
  84. return
  85. }
  86. wx.navigateToMiniProgram({
  87. appId: 'wx6decdf12f9e7a061', // 目标小程序的 appId
  88. // envVersion: 'develop',
  89. success(res) {
  90. // 打开成功
  91. console.log('成功跳转至小程序:', res);
  92. },
  93. fail(err) {
  94. // 打开失败
  95. uni.showToast({
  96. title: '打开商城失败',
  97. icon: 'none'
  98. })
  99. }
  100. })
  101. }
  102. function loadingMore () {
  103. if (total.value <= 0) {
  104. return
  105. }
  106. if (more.value === 'noMore') {
  107. return
  108. }
  109. more.value = 'loading'
  110. pageInfo.value.pageNo++
  111. getMyCoupon()
  112. }
  113. </script>
  114. <style lang="scss" scoped>
  115. .content {
  116. // height: 100vh;
  117. width: 100vw;
  118. padding: 20rpx;
  119. box-sizing: border-box;
  120. &-item {
  121. margin-bottom: 20rpx;
  122. .msg {
  123. background: #FFF;
  124. padding: 40rpx;
  125. box-sizing: border-box;
  126. -webkit-mask: radial-gradient(circle at 0.375rem 100%, #00000000 0.375rem, red 0) -0.375rem;
  127. position: relative;
  128. &::after {
  129. content: '';
  130. position: absolute;
  131. bottom: 0;
  132. right: 0.375rem;
  133. width: calc( 100% - 0.75rem);
  134. height: 0;
  135. border-top: 2rpx dashed #eee;
  136. }
  137. }
  138. .use {
  139. background: #FFF;
  140. padding: 20rpx;
  141. box-sizing: border-box;
  142. display: flex;
  143. justify-content: flex-end;
  144. font-size: .85em ;
  145. -webkit-mask: radial-gradient(circle at 0.375rem 0%, #0000 0.375rem, red 0) -0.375rem;
  146. .btn {
  147. margin: 0;
  148. position: relative;
  149. border: 0;
  150. display: flex;
  151. align-items: center;
  152. justify-content: center;
  153. box-sizing: border-box;
  154. text-align: center;
  155. text-decoration: none;
  156. white-space: nowrap;
  157. vertical-align: baseline;
  158. transform: translate(0, 0);
  159. padding: 0 0.5rem;
  160. height: 1.5625rem;
  161. width: 200rpx;
  162. border-radius: 1.25rem;
  163. background: linear-gradient(90deg, #ff3000, rgba(255, 48, 0, 0.6));
  164. color: #ffffff;
  165. font-size: 0.75rem;
  166. font-weight: 400;
  167. &.disabled {
  168. background: rgba(130, 130, 130, 0.5);
  169. }
  170. }
  171. }
  172. .item {
  173. display: flex;
  174. align-items: center;
  175. justify-content: space-between;
  176. margin-bottom: 20rpx;
  177. .name {
  178. font-weight: bolder;
  179. font-size: 36rpx;
  180. }
  181. .price {
  182. color: #f30;
  183. font-size: 54rpx;
  184. }
  185. .desc {
  186. color: #999;
  187. font-size: 24rpx;
  188. }
  189. }
  190. }
  191. }
  192. </style>