chargeVoucher.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. <script setup lang="ts">
  2. import router from '@/router'
  3. import { StaticUrl } from '@/config'
  4. const { userInfo } = storeToRefs(useUserStore())
  5. definePage({
  6. name: 'charge-voucher',
  7. islogin: true,
  8. style: {
  9. navigationBarTitleText: '',
  10. navigationStyle: 'custom',
  11. },
  12. })
  13. const { statusBarHeight, MenuButtonHeight, opcity } = storeToRefs(useSysStore())
  14. const couponBalance = ref()
  15. onLoad((options: any) => {
  16. console.log(options, '路由参数')
  17. couponBalance.value = options.couponBalance
  18. })
  19. onMounted(() => {
  20. opcity.value = 0
  21. getRechargeLevels()
  22. })
  23. onPageScroll((e) => {
  24. const calculatedOpacity = e.scrollTop / 100
  25. opcity.value = Math.min(1, Math.max(0.1, calculatedOpacity))
  26. })
  27. const selectIndex = ref<number>()
  28. /**
  29. * 获取充值挡位
  30. */
  31. const rechargeLevels = ref<Api.RechargeLevel[]>([])
  32. async function getRechargeLevels() {
  33. const res = await Apis.charge.getReChargeLevel({})
  34. rechargeLevels.value = res.data
  35. }
  36. function selectVoucher(index: number) {
  37. selectIndex.value = index
  38. console.log('Selected voucher index:', index)
  39. }
  40. // 安全获取充值档位
  41. function getSelectedLevel(): Api.RechargeLevel | undefined {
  42. if (selectIndex.value === undefined || !rechargeLevels.value)
  43. return undefined
  44. return rechargeLevels.value[selectIndex.value]
  45. }
  46. async function handleH5PayResult(orderNumber: string) {
  47. const isPaySuccess = await useUserStore().pollOrderPaySuccess(orderNumber)
  48. if (isPaySuccess) {
  49. router.replace({ name: 'charge-buy-a-ticket-list' })
  50. return
  51. }
  52. useGlobalToast().show({ msg: '暂未查询到支付成功,请稍后在订单列表查看' })
  53. }
  54. /**
  55. * 提交支付
  56. */
  57. async function submitPay() {
  58. if (selectIndex.value === undefined) {
  59. return useGlobalMessage().alert('请选择充值金额')
  60. }
  61. const selectedLevel = getSelectedLevel()
  62. if (!selectedLevel) {
  63. return
  64. }
  65. try {
  66. await uni.showLoading({ title: '下单中...', mask: true })
  67. const orderRes = await Apis.charge.addPurchaseRecord({
  68. data: {
  69. couponAmount: selectedLevel.money,
  70. consigneeName: userInfo.value?.nickName || '',
  71. consigneeMobile: userInfo.value?.mobile || '',
  72. },
  73. })
  74. const orderNumber = orderRes.data
  75. if (!orderNumber) {
  76. uni.hideLoading()
  77. await uni.showToast({ title: '下单失败', icon: 'none' })
  78. return
  79. }
  80. // #ifdef MP-WEIXIN
  81. const payRes = await Apis.charge.wxJsApiPay({
  82. data: {
  83. orderNumber,
  84. },
  85. })
  86. uni.hideLoading()
  87. await useUserStore().getWxCommonPayment(payRes.data)
  88. await useUserStore().paySuccess('charge-buy-a-ticket-list', 'subPack-charge/chargeBuyaTicketList/chargeBuyaTicketList')
  89. // #endif
  90. // #ifdef H5
  91. uni.hideLoading()
  92. useUserStore().handleCommonWechatPay(orderNumber, 'wx')
  93. await handleH5PayResult(orderNumber)
  94. // #endif
  95. }
  96. catch (error) {
  97. uni.hideLoading()
  98. console.error('支付失败:', error)
  99. await useUserStore().payError('charge-buy-a-ticket-list', 'subPack-charge/chargeBuyaTicketList/chargeBuyaTicketList')
  100. }
  101. }
  102. /**
  103. * 申请退款
  104. */
  105. function refund() {
  106. useGlobalMessage().confirm({
  107. title: '提示',
  108. msg: '退款按照购券记录进行逐笔退款,可能产生多笔退款到账记录,请注意查收。',
  109. success: async () => {
  110. const res = await Apis.charge.userCouponRefund({})
  111. if (res.code === '00000') {
  112. useGlobalMessage().confirm({
  113. title: '提示',
  114. msg: '申请退款成功,预计3个工作日内分一笔或多笔退还,到期如未到账请联系客服!',
  115. success: () => {
  116. router.back()
  117. },
  118. fail: () => {
  119. },
  120. })
  121. }
  122. },
  123. })
  124. }
  125. </script>
  126. <template>
  127. <view class="min-h-screen" :style="{ backgroundImage: `url(${StaticUrl}/buy-center-bg.png)`, backgroundSize: 'cover', backgroundPosition: 'center' }">
  128. <wd-navbar
  129. title="购券中心" :custom-style="`background-color: rgba(226, 255, 145, ${opcity})`" :bordered="false"
  130. :z-index="99" safe-area-inset-top left-arrow fixed @click-left="router.back()"
  131. />
  132. <view :style="{ paddingTop: `${(Number(statusBarHeight) || 44) + MenuButtonHeight + 12}px` }" class="px24rpx">
  133. <view class="h-342rpx" />
  134. <view class="relative rounded-16rpx from-[#E1FF90] via-[#FAFFEE] to-[#FFFFFF] bg-gradient-to-b p-12rpx">
  135. <image
  136. class="absolute right-12rpx top-12rpx h-144rpx w-144rpx"
  137. :src="`${StaticUrl}/buy-center-cardIcon.png`"
  138. mode="scaleToFill"
  139. />
  140. <view class="mt-16rpx text-center">
  141. <view class="text-28rpx">
  142. 平台券金额
  143. </view>
  144. <view class="mt-16rpx text-28rpx font-800">
  145. {{ couponBalance }}
  146. <text class="text-24rpx">
  147. </text>
  148. </view>
  149. </view>
  150. <view class="mb-16rpx mt-28rpx flex items-center justify-around text-28rpx">
  151. <view @click="router.push({ name: 'charge-buy-a-ticket-list' })">
  152. 充值记录
  153. </view>
  154. <view class="h-40rpx w-2rpx bg-#E6E6E6" />
  155. <view @click="refund">
  156. 退款
  157. </view>
  158. </view>
  159. </view>
  160. <view class="mt-20rpx">
  161. <view class="text-32rpx font-bold">
  162. 本次充值
  163. </view>
  164. <view class="mt-24rpx flex flex-wrap items-center justify-start gap-20rpx">
  165. <view v-for="(item, index) in rechargeLevels" :key="index" class="h-136rpx w-220rpx text-center" :class="selectIndex === index ? 'text-[#9ED605]' : 'text-#2B303Ac'" :style="{ backgroundImage: `url(${StaticUrl}/${selectIndex === index ? 'buy-center-rechargesel' : 'buy-center-recharge'}.png)`, backgroundSize: 'cover', backgroundPosition: 'center' }" @click="selectVoucher(index)">
  166. <view class="h-80rpx text-28rpx font-bold line-height-[80rpx]">
  167. {{ item?.money }}<text class="text-24rpx">
  168. </text>
  169. </view>
  170. <view class="h-46rpx text-28rpx font-bold line-height-[46rpx] font-italic">
  171. {{ item?.name }}
  172. </view>
  173. </view>
  174. </view>
  175. </view>
  176. <view class="mt-24rpx">
  177. <view class="font-bold">
  178. 温馨提示
  179. </view>
  180. <view class="mt-24rpx text-24rpx text-#AAAAAA">
  181. <view>1.平台券仅限本平台使用,不可转赠和出售。</view>
  182. <view class="mt-20rpx">
  183. 2.平台券仅可用于本平台充电服务,若订单金额超过平台券余额,
  184. 需补足差价;若余额有剩余,可留存下次使用;剩余平台券余额支
  185. 持手动退款。
  186. </view>
  187. <view class="mt-20rpx">
  188. 3.平台保留调整平台券使用规则的权利,调整前将提前公告。
  189. 如有疑问,请联系客服。
  190. </view>
  191. </view>
  192. </view>
  193. <view
  194. class="fixed bottom-66rpx left-24rpx h-100rpx w-702rpx rounded-16rpx text-center text-28rpx font-800 line-height-[100rpx]"
  195. :class="selectIndex === undefined ? 'bg-[#CCCCCC] text-white' : 'bg-[linear-gradient(90deg,#DBFC81_0%,#9ED605_100%)] text-black shadow-[inset_0rpx_6rpx_20rpx_2rpx_#FFFFFF]'"
  196. @click="submitPay"
  197. >
  198. 立即支付
  199. </view>
  200. </view>
  201. </view>
  202. </template>
  203. <style lang="scss" scoped></style>