voucher.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <script setup lang="ts">
  2. import router from '@/router'
  3. import { StaticUrl } from '@/config'
  4. // Tab 列表
  5. const tabList = ref([
  6. { label: '可用', value: 2 },
  7. { label: '已使用', value: 1 },
  8. { label: '已过期', value: 5 },
  9. ])
  10. const currentTab = ref(2)
  11. // 状态映射
  12. const statusMap = new Map([
  13. [2, '可用'],
  14. [1, '已使用'],
  15. [5, '已过期'],
  16. ])
  17. // 分页请求
  18. const { data, isLastPage, page, reload } = usePagination(
  19. (pageNum, pageSize) => Apis.app.get_smqjh_system_app_api_membercoupon_page({
  20. params: { pageNum, pageSize, useStatus: currentTab.value },
  21. }),
  22. {
  23. initialPage: 1,
  24. initialPageSize: 10,
  25. immediate: false,
  26. data: res => res.data?.list,
  27. append: true,
  28. },
  29. )
  30. // 切换 Tab
  31. function handleTabChange(value: number) {
  32. currentTab.value = value
  33. page.value = 1
  34. reload()
  35. }
  36. function handleUse(_item: Api.AppMemberCouponVO) {
  37. router.pushTab({ name: 'home' })
  38. useTabbar().setTabbarItemActive('home')
  39. }
  40. // 取消订单(占位)
  41. async function handleCancelOrder(_item: Api.AppMemberCouponVO) {
  42. // useGlobalToast().show('功能开发中')
  43. await useUserStore().handleCommonCancelOrderJY(_item.lockOrderId as string)
  44. reload()
  45. }
  46. // 付款(占位)
  47. function handlePay(_item: Api.AppMemberCouponVO) {
  48. // useGlobalToast().show('功能开发中')
  49. useUserStore().handleCommonGoXiaoJuPay(_item.lockOrderId as string)
  50. }
  51. // 计算倒计时剩余毫秒数
  52. function getCountdownTime(orderCreateTime?: string): number {
  53. if (!orderCreateTime)
  54. return 0
  55. const createTime = new Date(orderCreateTime).getTime()
  56. const expireTime = createTime + 15 * 60 * 1000 // 假设15分钟支付有效期
  57. const remaining = expireTime - Date.now()
  58. return remaining > 0 ? remaining : 0
  59. }
  60. onShow(() => {
  61. page.value = 1
  62. reload()
  63. })
  64. onReachBottom(() => {
  65. if (!isLastPage.value) {
  66. page.value++
  67. }
  68. })
  69. </script>
  70. <template>
  71. <view class="min-h-100vh bg-#f5f5f5">
  72. <!-- Tab 切换 -->
  73. <view class="sticky top-0 z-10 flex items-center justify-between bg-white px24rpx">
  74. <view
  75. v-for="item in tabList"
  76. :key="item.value"
  77. class="py24rpx text-28rpx"
  78. :class="[currentTab === item.value ? 'text-[var(--them-color)] font-semibold border-b-4rpx border-[var(--them-color)]' : 'text-#666']"
  79. @click="handleTabChange(item.value)"
  80. >
  81. {{ item.label }}
  82. </view>
  83. </view>
  84. <!-- 券列表 -->
  85. <view class="px24rpx pt20rpx">
  86. <view
  87. v-for="item in data"
  88. :key="item.id"
  89. class="mb20rpx rounded-16rpx bg-white px24rpx py28rpx"
  90. >
  91. <view @click="router.push({ name: 'voucherDetail', params: { id: item.id as string } })">
  92. <!-- 券信息头部 -->
  93. <view class="flex items-center justify-between">
  94. <view class="flex items-center">
  95. <image
  96. :src="`${StaticUrl}/smqjh-reful-juan.png`"
  97. class="mr12rpx h32rpx w32rpx"
  98. />
  99. <view class="text-30rpx font-semibold">
  100. 抵扣{{ item.discountMoney }}元(满{{ item.amountMoney }}元可用)
  101. </view>
  102. </view>
  103. <!-- 待支付倒计时 -->
  104. <view v-if="item.lockStatus === 1 && currentTab === 2" class="flex items-center text-24rpx text-#1890ff">
  105. 待支付(<wd-count-down :time="getCountdownTime(item.orderCreateTime)" format="还剩mm:ss" />)
  106. </view>
  107. </view>
  108. <!-- 券详情 -->
  109. <view class="mt16rpx text-26rpx text-#999">
  110. 适用:全部合作油站
  111. </view>
  112. <view class="mt12rpx text-26rpx text-#999">
  113. 有效期至:{{ item.expirationTime }}
  114. </view>
  115. <view class="mt12rpx text-26rpx text-#999">
  116. 可抵扣:<text class="text-#ff4d3a">
  117. ¥{{ item.discountMoney }}
  118. </text>
  119. </view>
  120. <view class="mt12rpx text-26rpx text-#999">
  121. 状态:{{ statusMap.get(item.useStatus as number) || '' }}
  122. </view>
  123. </view>
  124. <!-- 操作按钮区域 -->
  125. <view v-if="currentTab === 2" class="mt20rpx">
  126. <!-- 未被锁定 - 显示去使用 -->
  127. <view v-if="item.lockStatus !== 1" class="flex justify-end">
  128. <wd-button size="small" plain custom-class="use-btn" @click="handleUse(item)">
  129. 去使用
  130. </wd-button>
  131. </view>
  132. <!-- 被锁定 - 显示订单信息和操作 -->
  133. <view v-else>
  134. <view class="flex items-center text-26rpx text-#1890ff">
  135. <wd-icon name="info-circle" size="28rpx" color="#1890ff" class="mr8rpx" />
  136. 当前订单未支付,券被占用
  137. </view>
  138. <view class="mt16rpx flex items-center justify-between">
  139. <view class="text-26rpx text-#999">
  140. 订单号:{{ item.lockOrderId }}
  141. </view>
  142. <view class="flex items-center gap-16rpx">
  143. <wd-button size="small" plain custom-class="cancel-btn" @click="handleCancelOrder(item)">
  144. 取消订单
  145. </wd-button>
  146. <wd-button size="small" plain custom-class="pay-btn" @click="handlePay(item)">
  147. 付款
  148. </wd-button>
  149. </view>
  150. </view>
  151. </view>
  152. </view>
  153. </view>
  154. <!-- 空状态 -->
  155. <view v-if="data && data.length === 0" class="flex flex-col items-center pt100rpx">
  156. <StatusTip tip="暂无抵扣券" />
  157. </view>
  158. </view>
  159. </view>
  160. </template>
  161. <style lang="scss" scoped>
  162. :deep(.use-btn) {
  163. border-color: #333 !important;
  164. color: #333 !important;
  165. border-radius: 32rpx !important;
  166. }
  167. :deep(.cancel-btn) {
  168. border-color: #999 !important;
  169. color: #999 !important;
  170. border-radius: 32rpx !important;
  171. }
  172. :deep(.pay-btn) {
  173. border-color: #333 !important;
  174. color: #333 !important;
  175. border-radius: 32rpx !important;
  176. }
  177. :deep(.wd-count-down){
  178. color: #1890ff !important;
  179. }
  180. </style>