Parcourir la source

feat(app): 实现抵扣券活动及兑换功能

- 调整环境变量API地址,适配不同环境请求
- 更新alova配置以匹配最新接口路径
- 扩展全局接口定义,新增实际库存字段
- 修正组件声明,移除WdNavbar无用声明
- 重构pages.json,添加多页面配置及tabBar设置
- 新增活动详情页,实现优惠券信息请求与状态计算
- 重构活动列表页,改用接口分页获取数据
- 添加兑换失败和成功页面,展示兑换结果和操作按钮
- 首页支持加载更多商品,增加分页请求与底部触发
- 优化用户状态管理,实现H5定位兼容及兑换接口调用
- 完善路由声明,支持新增兑换结果页面路径
zhangtao il y a 1 semaine
Parent
commit
43c164c29f

+ 2 - 1
.env.development

@@ -2,8 +2,9 @@
 # 在开发模式下使用 (npm run dev)
 
 # API 基础 URL - 开发环境
-VITE_API_BASE_URL=http://192.168.0.19:8080
+# VITE_API_BASE_URL=http://192.168.0.19:8080
 # VITE_API_BASE_URL=http://192.168.0.11:8080
+VITE_API_BASE_URL=http://192.168.1.166:8080
 
 # 静态资源基础 URL - 测试环境
 VITE_STATIC_BASE_URL=https://zswl-smqjh.oss-cn-chengdu.aliyuncs.com/static/static

+ 1 - 1
.env.production

@@ -2,7 +2,7 @@
 # 在生产构建时使用 (npm run build)
 
 # API 基础 URL - 生产环境
-VITE_API_BASE_URL=https://api.yourapp.com
+VITE_API_BASE_URL=https://smqjh.api.zswlgz.com
 
 # 静态资源基础 URL - 测试环境
 VITE_STATIC_BASE_URL=https://zswl-smqjh.oss-cn-chengdu.aliyuncs.com/static/static

+ 1 - 1
.env.staging

@@ -2,7 +2,7 @@
 # 在测试环境构建时使用
 
 # API 基础 URL - 测试环境
-VITE_API_BASE_URL=http://192.168.0.11:8080
+VITE_API_BASE_URL=http://192.168.0.19:8080
 
 
 # 静态资源基础 URL - 测试环境

+ 1 - 1
alova.config.ts

@@ -13,7 +13,7 @@ export default <Config>{
        * 1. openapi json file url
        * 2. local file
        */
-      input: 'http://127.0.0.1:4523/export/openapi/4?version=2.0',
+      input: 'http://127.0.0.1:4523/export/openapi/2?version=2.0',
       /**
        * input file platform. Currently only swagger is supported.
        * When this parameter is specified, the input field only needs to specify the document address without specifying the openapi file

+ 8 - 0
src/api/globals.d.ts

@@ -859,6 +859,10 @@ export interface CouponInfoAppVo {
    * 库存
    */
   inventoryTotal?: number;
+  /**
+   * 实际库存
+   */
+  inventoryActual?: number;
   /**
    * 含税采购价(元)
    */
@@ -2097,6 +2101,8 @@ declare global {
        *       discountMoney?: number
        *       // 库存
        *       inventoryTotal?: number
+       *       // 实际库存
+       *       inventoryActual?: number
        *       // 含税采购价(元)
        *       purchasePrice?: number
        *       // 优惠券开始时间
@@ -2175,6 +2181,8 @@ declare global {
        *     discountMoney?: number
        *     // 库存
        *     inventoryTotal?: number
+       *     // 实际库存
+       *     inventoryActual?: number
        *     // 含税采购价(元)
        *     purchasePrice?: number
        *     // 优惠券开始时间

+ 0 - 1
src/components.d.ts

@@ -19,7 +19,6 @@ declare module 'vue' {
     WdGap: typeof import('wot-design-uni/components/wd-gap/wd-gap.vue')['default']
     WdIcon: typeof import('wot-design-uni/components/wd-icon/wd-icon.vue')['default']
     WdMessageBox: typeof import('wot-design-uni/components/wd-message-box/wd-message-box.vue')['default']
-    WdNavbar: typeof import('wot-design-uni/components/wd-navbar/wd-navbar.vue')['default']
     WdNotify: typeof import('wot-design-uni/components/wd-notify/wd-notify.vue')['default']
     WdPopup: typeof import('wot-design-uni/components/wd-popup/wd-popup.vue')['default']
     WdRadio: typeof import('wot-design-uni/components/wd-radio/wd-radio.vue')['default']

+ 18 - 0
src/pages.json

@@ -36,6 +36,24 @@
         "navigationStyle": "custom"
       }
     },
+    {
+      "path": "pages/exchangeFail/index",
+      "name": "exchangeFail",
+      "islogin": true,
+      "style": {
+        "navigationBarTitleText": "支付",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/exchangeSuccess/index",
+      "name": "exchangeSuccess",
+      "islogin": true,
+      "style": {
+        "navigationBarTitleText": "支付",
+        "navigationStyle": "custom"
+      }
+    },
     {
       "path": "pages/login/index",
       "name": "login",

+ 55 - 21
src/pages/activityCenter/index.vue

@@ -1,4 +1,6 @@
 <script setup lang="ts">
+import type { CouponInfoAppVo } from '@/api/globals'
+
 definePage({
   name: 'activityCenter-detail',
   islogin: true,
@@ -8,20 +10,48 @@ definePage({
   },
 })
 
-// 活动数据
-const activityInfo = ref({
-  title: '企业用户专享礼包',
-  discount: '抵扣15元(满100元可用)',
-  status: '进行中',
-  activityId: 'SDIE-DLEIJ-31095',
-  stock: 168,
-})
 const staticUrl = import.meta.env.VITE_STATIC_BASE_URL
+const couponInfo = ref<CouponInfoAppVo>()
+
+const { send } = useRequest(couponId => Apis.app.get_smqjh_system_app_api_coupon_findbyid({ params: { couponId } }), {
+  immediate: false,
+}).onSuccess((res) => {
+  couponInfo.value = res.data.data
+})
+
+onLoad((options: any) => {
+  send(options.id)
+})
+
+// 抵扣信息文案
+const discountText = computed(() => {
+  if (!couponInfo.value)
+    return ''
+  const discount = (couponInfo.value.discountMoney || 0) / 100
+  const amount = (couponInfo.value.amountMoney || 0) / 100
+  return `抵扣${discount}元(满${amount}元可用)`
+})
+
+// 活动状态
+const activityStatus = computed(() => {
+  if (!couponInfo.value)
+    return ''
+  const now = Date.now()
+  const start = couponInfo.value.couponStartTime ? new Date(couponInfo.value.couponStartTime).getTime() : 0
+  const end = couponInfo.value.couponEndTime ? new Date(couponInfo.value.couponEndTime).getTime() : 0
+
+  if (start && now < start)
+    return '未开始'
+  if (end && now > end)
+    return '已结束'
+  return '进行中'
+})
+
 // 活动规则
-const rules = ref([
+const rules = computed(() => [
   {
     title: '1.抵扣券',
-    items: ['抵扣15元(满100元可用)'],
+    items: [discountText.value],
   },
   {
     title: '2.使用限制',
@@ -33,28 +63,27 @@ const rules = ref([
   },
   {
     title: '4.有效期',
-    items: ['领取后7天内有效'],
+    items: [`领取后${couponInfo.value?.expirationDate || 7}天内有效`],
   },
 ])
 
 // 领取活动
 function handleClaim() {
-  // TODO: 调用领取接口
-  useGlobalToast().show('领取成功')
+  useUserStore().handleExchange(couponInfo.value)
 }
 </script>
 
 <template>
-  <view class="activity-page pt20rpx">
+  <view v-if="couponInfo" class="activity-page pt20rpx">
     <!-- 活动卡片 -->
     <view class="mx24rpx overflow-hidden rounded-16rpx">
       <view class="pages-bg flex items-center justify-between px24rpx py28rpx">
         <view>
           <view class="text-32rpx text-#333 font-semibold">
-            {{ activityInfo.title }}
+            {{ couponInfo.activityName }}
           </view>
           <view class="mt12rpx text-28rpx">
-            {{ activityInfo.discount }}
+            {{ discountText }}
           </view>
         </view>
         <image
@@ -71,7 +100,7 @@ function handleClaim() {
           活动状态:
         </view>
         <view class="text-#333">
-          {{ activityInfo.status }}
+          {{ activityStatus }}
         </view>
       </view>
       <view class="mt20rpx flex items-center text-28rpx">
@@ -79,7 +108,7 @@ function handleClaim() {
           活动ID:
         </view>
         <view class="text-#333">
-          {{ activityInfo.activityId }}
+          {{ couponInfo.activityId }}
         </view>
       </view>
       <view class="mt20rpx flex items-center text-28rpx">
@@ -87,7 +116,7 @@ function handleClaim() {
           剩余库存:
         </view>
         <view class="text-#333">
-          {{ activityInfo.stock }}张
+          {{ couponInfo.inventoryActual }}张
         </view>
       </view>
     </view>
@@ -113,8 +142,13 @@ function handleClaim() {
 
   <!-- 底部固定按钮 -->
   <FixedLayout>
-    <wd-button block size="large" @click="handleClaim">
-      立即领取
+    <wd-button
+      block
+      size="large"
+      :disabled="couponInfo?.receiveSign || activityStatus !== '进行中'"
+      @click="handleClaim"
+    >
+      {{ couponInfo?.receiveSign ? '已领取' : '立即领取' }}
     </wd-button>
   </FixedLayout>
 </template>

+ 31 - 42
src/pages/activityList/index.vue

@@ -12,35 +12,21 @@ definePage({
 
 const staticUrl = import.meta.env.VITE_STATIC_BASE_URL
 
-// 活动列表数据
-const activityList = ref([
-  {
-    id: 1,
-    title: '企业用户专享礼包',
-    discount: '抵扣15元(满100元可用)',
-    validity: '领取后7天有效',
-    claimed: 832,
-    total: 1000,
-    status: 'unclaimed', // unclaimed: 未领取, claimed: 已领取
-    expireDate: '',
-  },
-  {
-    id: 2,
-    title: '企业用户专享礼包',
-    discount: '抵扣25元(满150元可用)',
-    validity: '',
-    claimed: 0,
-    total: 0,
-    status: 'claimed',
-    expireDate: '2024-12-13 11:12:30',
-  },
-])
-
-// 积分兑换
-function handleExchange(_item: any) {
-  // TODO: 调用积分兑换接口
-  useGlobalToast().show('兑换成功')
-}
+const { data, isLastPage, page, send } = usePagination((pageNum, pageSize) => Apis.app.get_smqjh_system_app_api_coupon_page({ params: {
+  pageNum,
+  pageSize,
+} }), {
+  initialPage: 1,
+  initialPageSize: 10,
+  data: res => res.data?.list,
+  append: true,
+  immediate: false,
+})
+onShow(() => {
+  data.value = []
+  send()
+},
+)
 
 // 查看详情
 function handleViewDetail(item: any) {
@@ -49,13 +35,19 @@ function handleViewDetail(item: any) {
     params: { id: item.id },
   })
 }
+
+onReachBottom(() => {
+  if (!isLastPage.value) {
+    page.value++
+  }
+})
 </script>
 
 <template>
   <view class="activity-list-page px24rpx pt20rpx">
     <!-- 活动卡片列表 -->
     <view
-      v-for="item in activityList"
+      v-for="item in data"
       :key="item.id"
       class="activity-card mb24rpx overflow-hidden rounded-16rpx bg-white"
     >
@@ -63,25 +55,22 @@ function handleViewDetail(item: any) {
         <view class="flex-1">
           <!-- 标题 -->
           <view class="text-32rpx font-semibold">
-            {{ item.title }}
+            {{ item.activityName }}
           </view>
           <!-- 抵扣信息 -->
           <view class="mt16rpx text-28rpx text-#333">
-            {{ item.discount }}
+            抵扣{{ item.discountMoney }}元(满{{ item.amountMoney }}元可用)
           </view>
           <!-- 有效期 -->
-          <view v-if="item.validity" class="mt12rpx text-26rpx text-#666">
-            有效期:{{ item.validity }}
-          </view>
-          <view v-if="item.expireDate" class="mt12rpx text-26rpx text-#666">
-            有效期:{{ item.expireDate }}
+          <view class="mt12rpx text-26rpx text-#666">
+            有效期:{{ item.expirationTime ? item.expirationTime : `领取过后${item.expirationDate}天有效` }}
           </view>
           <!-- 已领取数量 -->
-          <view v-if="item.status === 'unclaimed'" class="mt12rpx text-26rpx text-#666">
-            已领取:{{ item.claimed }}/{{ item.total }}
+          <view class="mt12rpx text-26rpx text-#666">
+            已领取:{{ item.inventoryActual }} / {{ item.inventoryTotal }}
           </view>
           <!-- 状态 -->
-          <view v-if="item.status === 'claimed'" class="mt12rpx text-26rpx text-#666">
+          <view v-if="item.receiveSign" class="mt12rpx text-26rpx text-#666">
             状态:已领取
           </view>
         </view>
@@ -96,10 +85,10 @@ function handleViewDetail(item: any) {
       <!-- 底部按钮 -->
       <view class="flex justify-center pb28rpx">
         <wd-button
-          v-if="item.status === 'unclaimed'"
+          v-if="!item.receiveSign"
           size="small"
           custom-class="exchange-btn"
-          @click="handleExchange(item)"
+          @click="useUserStore().handleExchange(item)"
         >
           积分兑换
         </wd-button>

+ 87 - 0
src/pages/exchangeFail/index.vue

@@ -0,0 +1,87 @@
+<script setup lang="ts">
+import router from '@/router'
+
+definePage({
+  name: 'exchangeFail',
+  islogin: true,
+  style: {
+    navigationBarTitleText: '支付',
+    navigationStyle: 'custom',
+  },
+})
+
+// 页面参数
+const failReason = ref('')
+const StaticUrl = import.meta.env.VITE_STATIC_BASE_URL
+
+onLoad((options: any) => {
+  failReason.value = options.failReason || '活动太火爆,优惠券已领完'
+})
+
+// 联系客服
+function handleContact() {
+  // TODO: 联系客服功能
+  useGlobalToast().show('客服功能开发中')
+}
+
+// 查看其他活动
+function handleViewActivity() {
+  router.back()
+}
+</script>
+
+<template>
+  <view class="min-h-100vh flex flex-col bg-#f5f5f5">
+    <!-- 失败图标区域 -->
+    <view class="flex flex-1 flex-col items-center justify-center">
+      <!-- 虚线边框容器 -->
+      <image
+        :src="`${StaticUrl}/smqjh-reful-pay-error.png`"
+        class="h200rpx w200rpx"
+      />
+
+      <!-- 失败文字 -->
+      <view class="text-32rpx font-semibold">
+        抱歉,领取失败
+      </view>
+
+      <!-- 失败原因 -->
+      <view class="mt20rpx text-28rpx text-#666">
+        失败原因:{{ failReason }}
+      </view>
+
+      <!-- 按钮区域 -->
+      <view class="mt60rpx flex items-center justify-center gap-32rpx px48rpx">
+        <wd-button
+          plain
+          size="large"
+          custom-class="contact-btn"
+          @click="handleContact"
+        >
+          联系客服
+        </wd-button>
+        <wd-button
+          size="large"
+          custom-class="activity-btn"
+          @click="handleViewActivity"
+        >
+          查看其他活动
+        </wd-button>
+      </view>
+    </view>
+  </view>
+</template>
+
+<style lang="scss" scoped>
+:deep(.contact-btn) {
+  min-width: 200rpx !important;
+  border-color: var(--them-color) !important;
+  color: var(--them-color) !important;
+  border-radius: 48rpx !important;
+}
+
+:deep(.activity-btn) {
+  min-width: 200rpx !important;
+  border-radius: 48rpx !important;
+}
+</style>

+ 126 - 0
src/pages/exchangeSuccess/index.vue

@@ -0,0 +1,126 @@
+<script setup lang="ts">
+definePage({
+  name: 'exchangeSuccess',
+  islogin: true,
+  style: {
+    navigationBarTitleText: '支付',
+    navigationStyle: 'custom',
+  },
+})
+
+// 页面参数
+const couponId = ref('')
+const batchNo = ref('')
+const expireDays = ref('')
+const discountMoney = ref(0)
+const amountMoney = ref(0)
+const StaticUrl = import.meta.env.VITE_STATIC_BASE_URL
+
+onLoad((options: any) => {
+  couponId.value = options.couponId || ''
+  batchNo.value = options.batchNo || ''
+  expireDays.value = options.expireDays || ''
+  discountMoney.value = Number(options.discountMoney) || 0
+  amountMoney.value = Number(options.amountMoney) || 0
+})
+
+// 查看抵扣券
+function handleViewVoucher() {
+  uni.switchTab({ url: '/pages/voucher/index' })
+}
+
+// 立即使用
+function handleUseNow() {
+  // TODO: 跳转到使用页面
+  uni.navigateBack()
+}
+</script>
+
+<template>
+  <view class="min-h-100vh bg-#f5f5f5">
+    <!-- 成功图标 -->
+    <view class="flex flex-col items-center pt60rpx">
+      <view class="h80rpx w80rpx flex items-center justify-center rounded-full bg-#9ED605">
+        <wd-icon name="check" size="48rpx" color="#fff" />
+      </view>
+      <view class="mt20rpx text-32rpx text-#9ED605 font-semibold">
+        兑换成功
+      </view>
+    </view>
+
+    <!-- 抵扣券信息卡片 -->
+    <view class="mx24rpx mt40rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="flex items-center">
+        <view class="mr10rpx h30rpx w30rpx">
+          <image
+            class="h-full w-full"
+            :src="`${StaticUrl}/smqjh-reful-juan.png`"
+          />
+        </view>
+        <view class="text-30rpx font-semibold">
+          抵扣{{ discountMoney }}元(满{{ amountMoney }}可用)
+        </view>
+      </view>
+      <view class="mt16rpx text-26rpx text-#999">
+        优惠券已放入"我的抵扣券"
+      </view>
+    </view>
+
+    <!-- 券详情卡片 -->
+    <view class="mx24rpx mt24rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="text-28rpx text-#333">
+        券ID:{{ couponId }}
+      </view>
+      <view class="mt20rpx text-28rpx text-#333">
+        批次号:{{ batchNo }}
+      </view>
+      <view class="mt20rpx text-28rpx text-#333">
+        有效期:{{ expireDays }}天
+      </view>
+    </view>
+
+    <!-- 温馨提示卡片 -->
+    <view class="mx24rpx mt24rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="mb20rpx text-28rpx font-semibold">
+        温馨提示:
+      </view>
+      <view class="text-26rpx text-#666 leading-44rpx">
+        <view>·每单限用1张优惠券</view>
+        <view class="mt8rpx">
+          ·系统会自动选择最优优惠
+        </view>
+        <view class="mt8rpx">
+          ·不支持油站无法使用
+        </view>
+      </view>
+    </view>
+    <view class="mt28rpx flex items-center justify-between gap20rpx px124rpx">
+      <wd-button
+
+        plain block
+        size="large"
+        custom-class="flex-1 view-btn"
+        @click="handleViewVoucher"
+      >
+        查看抵扣券
+      </wd-button>
+      <wd-button
+        block
+        size="large"
+        custom-class="flex-1"
+        @click="handleUseNow"
+      >
+        立即使用
+      </wd-button>
+    </view>
+    <!-- 占位 -->
+    <view class="h200rpx" />
+  </view>
+</template>
+
+<style lang="scss" scoped>
+:deep(.view-btn) {
+  border-color: var(--them-color) !important;
+  color: var(--them-color) !important;
+}
+</style>

+ 10 - 3
src/pages/index/index.vue

@@ -15,7 +15,10 @@ const tabList = ref([
   { label: '价格从低到高', value: 1 },
 ])
 const currentTab = ref(0)
-const { data, send } = usePagination((pageNum, pageSize) => Apis.general.post_smqjh_pms_app_api_v1_product_oil_page({ data: { pageNum, pageSize, lat: useUserStore().lat, lon: useUserStore().lng, sort: currentTab.value } }), {
+const { data, send, isLastPage, page } = usePagination((pageNum, pageSize) =>
+  Apis.general.post_smqjh_pms_app_api_v1_product_oil_page(
+    { data: { pageNum, pageSize, lat: useUserStore().lat, lon: useUserStore().lng, sort: currentTab.value } },
+  ), {
   initialPage: 1,
   initialPageSize: 10,
   immediate: false,
@@ -35,7 +38,11 @@ onMounted(async () => {
   await useUserStore().getLocationH5()
   send()
 })
-
+onReachBottom(() => {
+  if (!isLastPage.value) {
+    page.value++
+  }
+})
 watch(() => currentTab.value, () => {
   send()
 })
@@ -54,7 +61,7 @@ watch(() => currentTab.value, () => {
       </view>
     </wd-sticky>
 
-    <view v-for="item in data" :key="item.storeId" class="relative mb20rpx rounded-16rpx bg-white p24rpx" @click="handleView(item)">
+    <view v-for="item in data" :key="item.storeId" class="relative mb20rpx box-border rounded-16rpx bg-white p24rpx" @click="handleView(item)">
       <view class="mt80rpx flex items-center justify-between">
         <view class="text-36rpx font-semibold">
           {{ item.storeName }}

+ 55 - 34
src/store/user.ts

@@ -1,5 +1,6 @@
 import type { MemberVO } from '@/api/globals'
 import { defineStore } from 'pinia'
+import router from '@/router'
 
 interface userStroe {
   token: string
@@ -26,49 +27,37 @@ export const useUserStore = defineStore('user', {
   }),
   actions: {
 
-    // H5 环境获取位置
+    // H5 环境获取位置(使用 uni.getLocation,兼容微信浏览器)
     getLocationH5() {
       return new Promise((resolve, reject) => {
-        uni.showLoading({ mask: true })
-
-        if (!navigator.geolocation) {
-          uni.hideLoading()
-          useGlobalToast().show('当前浏览器不支持定位功能')
-          return
-        }
-        navigator.geolocation.getCurrentPosition(
-          (position) => {
+        uni.showLoading({ mask: true, title: '获取位置中...' })
+        uni.getLocation({
+          type: 'wgs84',
+          isHighAccuracy: true,
+          altitude: true,
+          success: (res) => {
             uni.hideLoading()
-            console.log('H5位置获取成功', position)
-            this.lat = Number(position.coords.latitude.toFixed(6))
-            this.lng = Number(position.coords.longitude.toFixed(6))
-
+            console.log('H5位置获取成功', res)
+            this.lat = Number(res.latitude.toFixed(6))
+            this.lng = Number(res.longitude.toFixed(6))
             resolve(true)
           },
-          (error) => {
+          fail: (err) => {
             uni.hideLoading()
             reject(new Error('获取位置失败'))
-            console.log('H5获取位置失败', error)
-            switch (error.code) {
-              case error.PERMISSION_DENIED:
-                useGlobalToast().show('用户拒绝了定位请求')
-                break
-              case error.POSITION_UNAVAILABLE:
-                useGlobalToast().show('位置信息不可用')
-                break
-              case error.TIMEOUT:
-                useGlobalToast().show('获取位置超时,请重试')
-                break
-              default:
-                useGlobalToast().show(`获取定位失败:${error.message}`)
+            console.log('H5获取位置失败', err)
+            const errMsg = err.errMsg || ''
+            if (errMsg.includes('auth deny') || errMsg.includes('authorize')) {
+              useGlobalToast().show('请授权位置权限')
+            }
+            else if (errMsg.includes('timeout')) {
+              useGlobalToast().show('获取位置超时,请重试')
+            }
+            else {
+              useGlobalToast().show(`获取定位失败:${errMsg}`)
             }
           },
-          {
-            enableHighAccuracy: true, // 高精度
-            timeout: 10000, // 超时时间 10秒
-            maximumAge: 0, // 不使用缓存
-          },
-        )
+        })
       })
     },
 
@@ -144,5 +133,37 @@ export const useUserStore = defineStore('user', {
         },
       })
     },
+    /**
+     *
+     * @param _item 兑换的券
+     */
+    async handleExchange(_item: any) {
+      uni.showLoading({ mask: true })
+      try {
+        const res = await Apis.app.get_smqjh_system_app_api_coupon_exchangepoints({ params: { couponId: _item.id } })
+        uni.hideLoading()
+        // 兑换成功,跳转成功页
+        router.push({
+          name: 'exchangeSuccess',
+          params: {
+            couponId: res.data?.id || _item.id,
+            batchNo: res.data?.batchId || '',
+            expireDays: res.data?.expirationDate || _item.expirationDate,
+            discountMoney: res.data?.discountMoney || _item.discountMoney,
+            amountMoney: res.data?.amountMoney || _item.amountMoney,
+          },
+        })
+      }
+      catch (error: any) {
+        uni.hideLoading()
+        // 兑换失败,跳转失败页
+        router.push({
+          name: 'exchangeFail',
+          params: {
+            failReason: error?.message || '兑换失败,请稍后重试',
+          },
+        })
+      }
+    },
   },
 })

+ 2 - 0
src/uni-pages.d.ts

@@ -7,6 +7,8 @@ interface NavigateToOptions {
   url: "/pages/activityCenter/index" |
        "/pages/activityList/index" |
        "/pages/confirmOrder/index" |
+       "/pages/exchangeFail/index" |
+       "/pages/exchangeSuccess/index" |
        "/pages/login/index" |
        "/pages/refuelDetaile/index";
 }