ソースを参照

feat(payment): 添加抵扣券支持及优化订单支付流程

- 新增优惠券列表接口及数据类型支持
- 确认订单页集成抵扣券选择与自动推荐功能
- 优化支付流程,支持小桔H5支付地址跳转
- 订单列表和详情页实现取消订单和立即支付功能
- 更新取消订单逻辑,统一使用全局确认弹窗
- 订单详情新增联系客服功能,统一跳转微信客服
- 更新环境配置,添加小桔支付重定向URL
- 在index.html中引入微信JS SDK脚本
- 修复部分UI布局及交互细节,提升体验
zhangtao 3 日 前
コミット
e275caa1ec

+ 5 - 2
.env.development

@@ -2,9 +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
+# VITE_API_BASE_URL=http://192.168.1.166:8080
 # VITE_API_BASE_URL=https://smqjh.api.zswlgz.com
 # VITE_API_BASE_URL=https://7a8e0952.r28.cpolar.top
 # VITE_API_BASE_URL=https://52e7774d.r24.cpolar.top
@@ -13,3 +13,6 @@ VITE_API_BASE_URL=http://192.168.1.166:8080
 VITE_STATIC_BASE_URL=https://zswl-smqjh.oss-cn-chengdu.aliyuncs.com/static/static
 # 环境名称
 VITE_ENV_NAME=development
+
+# 重定向 URL
+VITE_REDIRECT_URL=https://smqjh.ddjy.zswlgz.com/

+ 1 - 0
.env.production

@@ -8,3 +8,4 @@ VITE_API_BASE_URL=https://smqjh.api.zswlgz.com
 VITE_STATIC_BASE_URL=https://zswl-smqjh.oss-cn-chengdu.aliyuncs.com/static/static
 # 环境名称
 VITE_ENV_NAME=production
+VITE_REDIRECT_URL=https://smqjh.ddjy.zswlgz.com/

+ 1 - 0
.env.staging

@@ -10,3 +10,4 @@ VITE_STATIC_BASE_URL=https://zswl-smqjh.oss-cn-chengdu.aliyuncs.com/static/stati
 
 # 环境名称
 VITE_ENV_NAME=staging
+VITE_REDIRECT_URL=https://smqjh.ddjy.zswlgz.com/

+ 1 - 0
index.html

@@ -17,5 +17,6 @@
   <body>
     <div id="app"><!--app-html--></div>
     <script type="module" src="/src/main.ts"></script>
+    <script src="http://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
   </body>
 </html>

+ 1 - 0
src/api/apiDefinitions.ts

@@ -34,6 +34,7 @@ export default {
   'app.get_app_api_coupon_exchangeinfo': ['GET', '/app-api/coupon/exchangeInfo'],
   'app.get_app_api_coupon_exchangepoints': ['GET', '/app-api/coupon/exchangePoints'],
   'app.get_smqjh_system_app_api_coupon_findlist': ['GET', '/smqjh-system/app-api/coupon/findList'],
+  'app.get_app_api_coupon_findlist': ['GET', '/app-api/coupon/findList'],
   'general.post_smqjh_auth_oauth2_token': ['POST', '/smqjh-auth/oauth2/token'],
   'general.post_smqjh_auth_api_v1_auth_sms_code': ['POST', '/smqjh-auth/api/v1/auth/sms_code'],
   'general.get_api_v1_auth_captcha': ['GET', '/api/v1/auth/captcha'],

+ 86 - 2
src/api/globals.d.ts

@@ -537,7 +537,7 @@ export interface OmsOrderOilPageQuery {
    */
   status?: number;
 }
-export interface NotifyOrderInfoRequest {
+export interface NotifyOrderInfoRequestDto {
   /**
    * 外部用户号(第三方平台UserId)
    */
@@ -1918,6 +1918,14 @@ export interface OmsOrderOilPageVO {
    * 订单过期时间
    */
   expireTime?: string;
+  /**
+   * 小桔H5支付地址
+   */
+  payUrl?: string;
+  /**
+   * 微信交易号
+   */
+  transactionId?: string;
 }
 export interface DataOmsOrderOilPageVO {
   list?: OmsOrderOilPageVO[];
@@ -2446,6 +2454,10 @@ export interface OmsOrderOilVO {
    * 优惠卷id
    */
   allowanceId?: string;
+  /**
+   * 小桔H5支付地址
+   */
+  payUrl?: string;
   /**
    * 小桔价、折扣价、优惠价
    */
@@ -3897,6 +3909,64 @@ declare global {
       get_smqjh_system_app_api_coupon_findlist<Config extends Alova2MethodConfig<ResultListCouponInfoAppVo>>(
         config?: Config
       ): Alova2Method<ResultListCouponInfoAppVo, 'app.get_smqjh_system_app_api_coupon_findlist', Config>;
+      /**
+       * ---
+       *
+       * [GET] 优惠券活动列表查询
+       *
+       * **path:** /app-api/coupon/findList
+       *
+       * ---
+       *
+       * **Response**
+       * ```ts
+       * type Response = {
+       *   // 返回状态码
+       *   code?: string
+       *   // 返回数据对象
+       *   // [items] start
+       *   // [items] end
+       *   data?: Array<{
+       *     // id
+       *     id?: string
+       *     // 活动id
+       *     activityId?: string
+       *     // 活动名称
+       *     activityName?: string
+       *     // 优惠类型 1.满减、2.立减
+       *     promotionType?: number
+       *     // 门槛(单位(分)) 满减时的需要达到什么金额
+       *     amountMoney?: number
+       *     // 面额(单位(分)) 优惠的金额
+       *     discountMoney?: number
+       *     // 库存
+       *     inventoryTotal?: number
+       *     // 实际库存
+       *     inventoryActual?: number
+       *     // 含税采购价(元)
+       *     purchasePrice?: number
+       *     // 优惠券开始时间
+       *     couponStartTime?: string
+       *     // 优惠券结束时间
+       *     couponEndTime?: string
+       *     // 有效期,领取后多少天内有效(单位天)
+       *     expirationDate?: number
+       *     // 创建时间
+       *     createTime?: string
+       *     // 更新时间
+       *     updateTime?: string
+       *     // 标识是否有领取数
+       *     receiveSign?: boolean
+       *     // 过期时间
+       *     expirationTime?: string
+       *   }>
+       *   msg?: string
+       * }
+       * ```
+       */
+      get_app_api_coupon_findlist<Config extends Alova2MethodConfig<ResultListCouponInfoAppVo>>(
+        config?: Config
+      ): Alova2Method<ResultListCouponInfoAppVo, 'app.get_app_api_coupon_findlist', Config>;
     };
     general: {
       /**
@@ -6824,6 +6894,10 @@ declare global {
        *       cancelTime?: string
        *       // 订单过期时间
        *       expireTime?: string
+       *       // 小桔H5支付地址
+       *       payUrl?: string
+       *       // 微信交易号
+       *       transactionId?: string
        *     }>
        *     total?: number
        *   }
@@ -6899,6 +6973,10 @@ declare global {
        *       cancelTime?: string
        *       // 订单过期时间
        *       expireTime?: string
+       *       // 小桔H5支付地址
+       *       payUrl?: string
+       *       // 微信交易号
+       *       transactionId?: string
        *     }>
        *     total?: number
        *   }
@@ -7373,7 +7451,7 @@ declare global {
        */
       post_api_v1_oil_callback_third_party<
         Config extends Alova2MethodConfig<Result> & {
-          data: NotifyOrderInfoRequest;
+          data: NotifyOrderInfoRequestDto;
         }
       >(
         config: Config
@@ -7785,6 +7863,8 @@ declare global {
        *         activityName?: string
        *         // 优惠卷id
        *         allowanceId?: string
+       *         // 小桔H5支付地址
+       *         payUrl?: string
        *         // 小桔价、折扣价、优惠价
        *         vipPrice?: number
        *       }
@@ -8209,6 +8289,8 @@ declare global {
        *       activityName?: string
        *       // 优惠卷id
        *       allowanceId?: string
+       *       // 小桔H5支付地址
+       *       payUrl?: string
        *       // 小桔价、折扣价、优惠价
        *       vipPrice?: number
        *     }
@@ -8626,6 +8708,8 @@ declare global {
        *       activityName?: string
        *       // 优惠卷id
        *       allowanceId?: string
+       *       // 小桔H5支付地址
+       *       payUrl?: string
        *       // 小桔价、折扣价、优惠价
        *       vipPrice?: number
        *     }

+ 130 - 34
src/pages/confirmOrder/index.vue

@@ -1,5 +1,6 @@
 <script setup lang="ts">
-import type { GasStationDetailVO, QueryCalPriceResponse } from '@/api/globals'
+import type { AppMemberCouponOrderVO, GasStationDetailVO, QueryCalPriceResponse } from '@/api/globals'
+import router from '@/router'
 
 definePage({ name: 'confimOrder', islogin: true, style: { navigationBarTitleText: '下单', navigationStyle: 'custom' } })
 const showModel = ref(false)
@@ -13,6 +14,8 @@ const refuelMoney = ref(null)
 const showModelReful = ref(false)
 const { lat, lng } = storeToRefs(useUserStore())
 const ThreePrice = ref<QueryCalPriceResponse>()
+const dkList = ref<AppMemberCouponOrderVO>()
+const isSeletDk = ref(false)
 onLoad(async (options: any) => {
   await getData(options.storeId)
 })
@@ -62,6 +65,20 @@ async function handleBlur() {
   // if (Number(refuelMoney.value) < 10) {
   //   return useGlobalToast().show('最小金额为10元')
   // }
+  if (!storeDetail.value)
+    return
+  if (!storeDetail.value.allowanceClientScheme) {
+    const res = await Apis.app.get_smqjh_system_app_api_membercoupon_findplaceorderlist({
+      params: {
+        storeId: storeDetail.value?.storeId,
+        orderAmount: Number(refuelMoney.value) * 100,
+      },
+    })
+
+    dkList.value = res.data
+  }
+}
+async function getMoney() {
   if (!storeDetail.value)
     return
   const nams = storeDetail.value?.itemInfoList?.find(item => item.itemId === refuelNumber.value)?.itemName
@@ -72,16 +89,9 @@ async function handleBlur() {
     openChannel: 0,
     outUserId: '',
     mobile: '',
+    promotionInfo: selectDk.value === 'nodk' ? [] : [{ allowanceId: selectDk.value }],
   } })
   ThreePrice.value = data
-  console.log(data)
-  const res = await Apis.app.get_smqjh_system_app_api_membercoupon_findplaceorderlist({
-    params: {
-      storeId: storeDetail.value?.storeId,
-      orderAmount: Number(refuelMoney.value) * 100,
-    },
-  })
-  console.log(res)
 }
 async function goPay() {
   uni.showLoading({ mask: true })
@@ -102,10 +112,11 @@ async function goPay() {
       storePrice: Number(priceData.value?.storePrice),
       storeId: storeDetail.value?.storeId,
       itemName: priceData.value?.itemName,
+      promotionInfo: selectDk.value === 'nodk' ? [] : [{ allowanceId: selectDk.value }],
     } })
-    const url = `${res.data}&redirectUrl=https://smqjh.admin.zswlgz.com/h5`
+    console.log(res, '===============================================支付')
     // #ifdef H5
-    window.location.href = url
+    useUserStore().handleCommonPath(res.data as string)
     // #endif
     uni.hideLoading()
   }
@@ -113,6 +124,24 @@ async function goPay() {
     uni.hideLoading()
   }
 }
+function handleSelectDk() {
+  console.log(selectDk.value, '==============')
+  if (selectDk.value === 'nodk') {
+    return '不使用抵扣券'
+  }
+  if (dkList.value?.appCouponOrderOptimalVO?.allowanceId === selectDk.value) {
+    return `${getSelectDkInfo()?.discountMoney}元`
+  }
+  else {
+    return `${getSelectDkInfo()?.discountMoney}元`
+  }
+}
+function getSelectDkInfo() {
+  if (dkList.value?.appCouponOrderOptimalVO?.allowanceId === selectDk.value) {
+    return dkList.value?.appCouponOrderOptimalVO
+  }
+  return dkList.value?.appCouponOrderVOList?.find(item => item.allowanceId === selectDk.value)
+}
 </script>
 
 <template>
@@ -177,28 +206,30 @@ async function goPay() {
           最小金额10元
         </view>
       </view>
-      <view class="mt20rpx rounded-16rpx bg-white px24rpx py28rpx">
+      <view v-if="refuelMoney" class="mt20rpx rounded-16rpx bg-white px24rpx py28rpx">
         <view class="flex items-center">
           <view class="mr20rpx text-28rpx font-semibold">
             抵扣券
           </view>
-          <wd-button size="small">
+          <wd-button size="small" @click="router.push({ name: 'activityList' })">
             去兑换
           </wd-button>
         </view>
-        <view class="mt24rpx flex items-center justify-between rounded-8rpx bg-#F9F9F9 px24rpx py20rpx" @click="showModelJf = true">
+        <view class="mt24rpx flex items-center justify-between rounded-8rpx bg-#F9F9F9 px24rpx py20rpx" @click="showModelJf = true && !storeDetail.allowanceClientScheme">
           <view class="text-28rpx text-#aaa">
-            暂无抵扣券
+            {{ storeDetail.allowanceClientScheme ? '该加油站不可使用抵扣券' : isSeletDk && selectDk ? handleSelectDk() : '暂无抵扣券' }}
           </view>
           <wd-icon name="arrow-down" size="32rpx" color="#aaa" />
         </view>
-        <view class="mt16rpx">
-          已选:满200元可抵扣100元(最优)
-        </view>
-        <view class="mt16rpx">
-          抵扣金额:-¥100
-        </view>
-        <template v-if="ThreePrice && refuelMoney">
+        <template v-if="selectDk !== 'nodk' && isSeletDk">
+          <view class="mt16rpx">
+            已选:满{{ getSelectDkInfo()?.amountMoney }}元可抵扣{{ getSelectDkInfo()?.discountMoney }}元 {{ dkList?.appCouponOrderOptimalVO?.allowanceId === selectDk ? '(最优)' : '' }}
+          </view>
+          <view class="mt16rpx">
+            抵扣金额:-¥{{ getSelectDkInfo()?.discountMoney }}
+          </view>
+        </template>
+        <template v-if="selectDk && ThreePrice && refuelMoney">
           <view class="mb20rpx mt24rpx text-32rpx font-semibold">
             价格明细
           </view>
@@ -212,13 +243,13 @@ async function goPay() {
             <view class="text-#aaa">
               抵扣券
             </view>
-            <view>-¥100</view>
+            <view>-¥{{ getSelectDkInfo()?.discountMoney || 0 }}</view>
           </view>
           <view class="mt20rpx flex items-center justify-between text-28rpx">
             <view class="text-#aaa">
               服务费
             </view>
-            <view>+¥{{ ThreePrice.promotionAmount ? ThreePrice.promotionAmount / 100 : 0 }}</view>
+            <view>+¥{{ ThreePrice.serviceFee ? ThreePrice.serviceFee / 100 : 0 }}</view>
           </view>
 
           <view class="my24rpx h2rpx w-full bg-#F0F0F0" />
@@ -284,9 +315,9 @@ async function goPay() {
             <view class="text-28rpx">
               不使用抵扣券
             </view>
-            <wd-radio :value="1" />
+            <wd-radio value="nodk" />
           </view>
-          <view class="mt24rpx">
+          <view v-if="dkList?.appCouponOrderOptimalVO" class="mt24rpx">
             <view class="text-28rpx">
               自动推荐
             </view>
@@ -296,10 +327,10 @@ async function goPay() {
                   <view class="text-40rpx text-#ff4d3a font-semibold">
                     <text class="text-24rpx">
-                    </text> 100
+                    </text> {{ dkList.appCouponOrderOptimalVO.discountMoney }}
                   </view>
                   <view class="ml20rpx text-32rpx font-semibold">
-                    满200元可用
+                    {{ dkList.appCouponOrderOptimalVO.amountMoney ? `满${dkList.appCouponOrderOptimalVO.amountMoney}元可用` : '无使用门槛' }}
                   </view>
                 </view>
                 <view class="mt24rpx flex items-center text-#aaa">
@@ -307,30 +338,95 @@ async function goPay() {
                     可抵扣
                   </view>
                   <view class="ml20rpx text-24rpx font-semibold">
-                    有效期:2022-01-01至2022-01-01
+                    有效期:{{ dkList.appCouponOrderOptimalVO.expirationTime }}
                   </view>
                 </view>
               </view>
               <view class="h-full w134rpx flex items-center justify-center border-l-2rpx border-l-#FF4D3A border-l-dashed">
-                <wd-radio :value="1" />
+                <wd-radio :value="dkList.appCouponOrderOptimalVO.allowanceId as string" />
               </view>
               <view class="absolute right-150rpx h30rpx w30rpx rounded-full bg-white -top-10rpx" />
               <view class="absolute right-150rpx h30rpx w30rpx rounded-full bg-white -bottom-10rpx" />
             </view>
           </view>
+          <scroll-view scroll-y class="h600rpx pb40rpx">
+            <view v-if="dkList?.appCouponOrderVOList" class="mt24rpx">
+              <view class="text-28rpx">
+                其他可用券
+              </view>
+              <view v-for="item in dkList.appCouponOrderVOList" :key="item.allowanceId" class="relative mt20rpx box-border h144rpx flex items-center justify-between rounded-16rpx bg-[rgba(255,77,58,0.1)] px28rpx py24rpx">
+                <view class="flex-1">
+                  <view class="flex items-center">
+                    <view class="text-40rpx text-#ff4d3a font-semibold">
+                      <text class="text-24rpx">
+                        ¥
+                      </text> {{ item.discountMoney }}
+                    </view>
+                    <view class="ml20rpx text-32rpx font-semibold">
+                      {{ item.amountMoney ? `满${item.amountMoney}元可用` : '无使用门槛' }}
+                    </view>
+                  </view>
+                  <view class="mt24rpx flex items-center text-#aaa">
+                    <view class="text-center text-20rpx">
+                      可抵扣
+                    </view>
+                    <view class="ml20rpx text-24rpx font-semibold">
+                      有效期:{{ item.expirationTime }}
+                    </view>
+                  </view>
+                </view>
+                <view class="h-full w134rpx flex items-center justify-center border-l-2rpx border-l-#FF4D3A border-l-dashed">
+                  <wd-radio :value="item.allowanceId as string" />
+                </view>
+                <view class="absolute right-150rpx h30rpx w30rpx rounded-full bg-white -top-10rpx" />
+                <view class="absolute right-150rpx h30rpx w30rpx rounded-full bg-white -bottom-10rpx" />
+              </view>
+            </view>
+            <view v-if="dkList?.appCouponNoOrderVOList" class="mt24rpx">
+              <view class="text-28rpx">
+                不可用
+              </view>
+              <view v-for="item in dkList.appCouponNoOrderVOList" :key="item.allowanceId" class="relative mt20rpx box-border h144rpx flex items-center justify-between rounded-16rpx bg-[#E6E6E6] px28rpx py24rpx">
+                <view class="flex-1">
+                  <view class="flex items-center">
+                    <view class="text-40rpx text-#AAAAAA font-semibold">
+                      <text class="text-24rpx">
+                        ¥
+                      </text> {{ item.discountMoney }}
+                    </view>
+                    <view class="ml20rpx text-32rpx text-#646464 font-semibold">
+                      {{ item.amountMoney ? `满${item.amountMoney}元可用` : '无使用门槛' }}
+                    </view>
+                  </view>
+                  <view class="mt24rpx flex items-center text-#aaa">
+                    <view class="text-center text-20rpx">
+                      可抵扣
+                    </view>
+                    <view class="ml20rpx text-24rpx font-semibold">
+                      有效期:{{ item.expirationTime }}
+                    </view>
+                  </view>
+                </view>
+                <view class="h-full w134rpx flex items-center justify-center border-l-2rpx border-l-#AAAAAA border-l-dashed">
+                  <wd-radio :value="item.allowanceId as string" disabled />
+                </view>
+                <view class="absolute right-150rpx h30rpx w30rpx rounded-full bg-white -top-10rpx" />
+                <view class="absolute right-150rpx h30rpx w30rpx rounded-full bg-white -bottom-10rpx" />
+              </view>
+            </view>
+          </scroll-view>
         </wd-radio-group>
       </view>
-      <view class="h200rpx" />
       <template #footer>
         <view class="my24rpx h2rpx w-full bg-#F0F0F0" />
-        <wd-button block size="large">
+        <wd-button block size="large" @click="showModelJf = false, isSeletDk = true, getMoney()">
           确认选择
         </wd-button>
       </template>
     </Zpopup>
     <FixedLayout>
-      <view :class="[ThreePrice && refuelMoney && 'justify-between flex items-center']">
-        <view v-if="ThreePrice && refuelMoney" class="text-32rpx text-#FF4A39 font-semibold">
+      <view :class="[selectDk && ThreePrice && refuelMoney && 'justify-between flex items-center']">
+        <view v-if="selectDk && ThreePrice && refuelMoney" class="text-32rpx text-#FF4A39 font-semibold">
           <text class="text-24rpx">
           </text><text>{{ ThreePrice?.realPrice ? ThreePrice?.realPrice / 100 : 0 }}</text>

+ 61 - 80
src/pages/order/index.vue

@@ -19,7 +19,7 @@ const tabList = ref([
 const currentTab = ref(0)
 
 // 分页请求
-const { data, send, isLastPage, page, reload } = usePagination(
+const { data, isLastPage, page, reload } = usePagination(
   (pageNum, pageSize) => Apis.general.post_smqjh_oms_api_v1_oil_order_findoilorderpage({
     data: { pageNum, pageSize, status: currentTab.value },
   }),
@@ -63,32 +63,13 @@ function getCountdownTime(expireTime?: string): number {
 
 // 取消订单
 async function handleCancelOrder(item: OmsOrderOilPageVO) {
-  useGlobalMessage().confirm({
-    title: '提示',
-    msg: '确定要取消该订单吗?',
-    success: async () => {
-      uni.showLoading({ mask: true })
-      try {
-        await Apis.general.post_smqjh_oms_api_v1_oil_order_cancel({ params: { orderId: item.orderNumber as string } })
-        useGlobalToast().show('取消成功')
-        // 刷新列表
-        data.value = []
-        page.value = 1
-        send()
-      }
-      catch {
-        useGlobalToast().show('取消失败')
-      }
-      finally {
-        uni.hideLoading()
-      }
-    },
-  })
+  await useUserStore().handleCommonCancelOrder(item.orderNumber as string)
+  reload()
 }
 
 // 付款(占位)
 function handlePay(_item: OmsOrderOilPageVO) {
-  useGlobalToast().show('功能开发中')
+  useUserStore().handleCommonPath(_item.payUrl as string)
 }
 
 // 申请开票(占位)
@@ -114,7 +95,7 @@ onReachBottom(() => {
       <view
         v-for="item in tabList"
         :key="item.value"
-        class="mr40rpx py24rpx text-28rpx"
+        class="py24rpx text-28rpx"
         :class="[currentTab === item.value ? 'text-[var(--them-color)] font-semibold border-b-4rpx border-[var(--them-color)]' : 'text-#666']"
         @click="handleTabChange(item.value)"
       >
@@ -128,70 +109,70 @@ onReachBottom(() => {
         v-for="item in data"
         :key="item.orderNumber"
         class="mb20rpx rounded-16rpx bg-white px24rpx py28rpx"
-        @click="router.push({ name: 'orderDetail', params: { orderNo: item.orderNumber as string } })"
       >
-        <!-- 头部:油站名称 + 状态 -->
-        <view class="flex justify-between">
-          <view class="text-30rpx font-semibold">
-            {{ item.brandName ? `${item.brandName}·` : '' }}{{ item.storeName }}
-          </view>
-          <!-- 待支付状态显示倒计时 -->
-          <view v-if="item.oilOrderStatus === 1" class="w300rpx flex items-center justify-end text-24rpx text-#1890ff">
-            待支付(<wd-count-down :time="getCountdownTime(item.expireTime)" format="还剩mm:ss" />)
-          </view>
-          <view v-else class="text-24rpx text-#666">
-            {{ getStatusText(item.oilOrderStatus) }}
+        <view @click="router.push({ name: 'orderDetail', params: { orderNo: item.orderNumber as string } })">
+          <!-- 头部:油站名称 + 状态 -->
+          <view class="flex justify-between">
+            <view class="text-30rpx font-semibold">
+              {{ item.brandName ? `${item.brandName}·` : '' }}{{ item.storeName }}
+            </view>
+            <!-- 待支付状态显示倒计时 -->
+            <view v-if="item.oilOrderStatus === 1" class="w300rpx flex items-center justify-end text-24rpx text-#1890ff">
+              待支付(<wd-count-down :time="getCountdownTime(item.expireTime)" format="还剩mm:ss" />)
+            </view>
+            <view v-else class="text-24rpx text-#666">
+              {{ getStatusText(item.oilOrderStatus) }}
+            </view>
           </view>
-        </view>
 
-        <!-- 油号 | 油枪 -->
-        <view class="mt16rpx text-26rpx text-#999">
-          {{ item.itemName }} | {{ item.gunNo }}号枪
-        </view>
+          <!-- 油号 | 油枪 -->
+          <view class="mt16rpx text-26rpx text-#999">
+            {{ item.itemName }} | {{ item.gunNo }}号枪
+          </view>
 
-        <!-- 订单金额 -->
-        <view class="mt12rpx text-26rpx text-#999">
-          订单金额:<text class="text-#333">
-            ¥{{ item.totalMoney }}
-          </text>
-        </view>
+          <!-- 订单金额 -->
+          <view class="mt12rpx text-26rpx text-#999">
+            订单金额:<text class="text-#333">
+              ¥{{ item.totalMoney }}
+            </text>
+          </view>
 
-        <!-- 根据状态显示不同金额 -->
-        <view v-if="item.oilOrderStatus === 1" class="mt12rpx text-26rpx text-#999">
-          需付金额:<text class="text-#333">
-            ¥{{ item.realMoney }}
-          </text>
-        </view>
-        <view v-else-if="item.oilOrderStatus === 2" class="mt12rpx text-26rpx text-#999">
-          实付金额:<text class="text-#333">
-            ¥{{ item.realMoney }}
-          </text>
-        </view>
-        <view v-else-if="item.oilOrderStatus === 6" class="mt12rpx text-26rpx text-#999">
-          退款金额:<text class="text-#333">
-            ¥{{ item.realMoney }}
-          </text>
-        </view>
+          <!-- 根据状态显示不同金额 -->
+          <view v-if="item.oilOrderStatus === 1" class="mt12rpx text-26rpx text-#999">
+            需付金额:<text class="text-#333">
+              ¥{{ item.realMoney }}
+            </text>
+          </view>
+          <view v-else-if="item.oilOrderStatus === 2" class="mt12rpx text-26rpx text-#999">
+            实付金额:<text class="text-#333">
+              ¥{{ item.realMoney }}
+            </text>
+          </view>
+          <view v-else-if="item.oilOrderStatus === 6" class="mt12rpx text-26rpx text-#999">
+            退款金额:<text class="text-#333">
+              ¥{{ item.realMoney }}
+            </text>
+          </view>
 
-        <!-- 根据状态显示不同时间 -->
-        <view v-if="item.oilOrderStatus === 1" class="mt12rpx text-26rpx text-#999">
-          下单时间:{{ item.createTime }}
-        </view>
-        <view v-else-if="item.oilOrderStatus === 2" class="mt12rpx text-26rpx text-#999">
-          支付时间:{{ item.payTime }}
-        </view>
-        <view v-else-if="item.oilOrderStatus === 6" class="mt12rpx text-26rpx text-#999">
-          退款时间:{{ item.refundTime }}
-        </view>
-        <view v-else-if="item.oilOrderStatus === 9" class="mt12rpx text-26rpx text-#999">
-          取消时间:{{ item.cancelTime }}
-        </view>
+          <!-- 根据状态显示不同时间 -->
+          <view v-if="item.oilOrderStatus === 1" class="mt12rpx text-26rpx text-#999">
+            下单时间:{{ item.createTime }}
+          </view>
+          <view v-else-if="item.oilOrderStatus === 2" class="mt12rpx text-26rpx text-#999">
+            支付时间:{{ item.payTime }}
+          </view>
+          <view v-else-if="item.oilOrderStatus === 6" class="mt12rpx text-26rpx text-#999">
+            退款时间:{{ item.refundTime }}
+          </view>
+          <view v-else-if="item.oilOrderStatus === 9" class="mt12rpx text-26rpx text-#999">
+            取消时间:{{ item.cancelTime }}
+          </view>
 
-        <!-- 已支付显示合作方订单号 -->
-        <view v-if="item.oilOrderStatus === 2 && item.thirdOrderId" class="mt12rpx text-26rpx text-#999">
-          合作方订单号:{{ item.thirdOrderId }}
+          <!-- 已支付显示合作方订单号 -->
+          <view v-if="item.oilOrderStatus === 2 && item.thirdOrderId" class="mt12rpx text-26rpx text-#999">
+            合作方订单号:{{ item.thirdOrderId }}
+          </view>
         </view>
-
         <!-- 操作按钮 -->
         <view v-if="item.oilOrderStatus === 1" class="mt20rpx flex items-center justify-end gap-20rpx">
           <wd-button plain size="small" custom-class="action-btn" @click="handleCancelOrder(item)">

+ 13 - 24
src/pages/orderDetail/index.vue

@@ -59,18 +59,14 @@ function handleCopy(text?: string) {
 }
 
 // 取消订单(占位)
-function handleCancelOrder() {
-  useGlobalToast().show('功能开发中')
+async function handleCancelOrder() {
+  await useUserStore().handleCommonCancelOrder(orderInfo.value?.orderNumber as string)
+  send(orderNo.value)
 }
 
 // 立即支付(占位)
 function handlePay() {
-  useGlobalToast().show('功能开发中')
-}
-
-// 联系客服(占位)
-function handleContact() {
-  useGlobalToast().show('功能开发中')
+  useUserStore().handleCommonPath(oilInfo.value?.payUrl as string)
 }
 
 // 跳转首页
@@ -78,6 +74,9 @@ function handleGoHome() {
   router.pushTab({ name: 'home' })
   useTabbar().setTabbarItemActive('home')
 }
+function handleContact() {
+  window.location.href = `weixin://dl/business/?appid=wx43b5b906cc30ed0b&path=subPack-xsb/orderDetaile/index&query=${orderInfo.value?.orderNumber}&env_version=release`
+}
 </script>
 
 <template>
@@ -103,22 +102,10 @@ function handleGoHome() {
         </view>
       </template>
 
-      <!-- 已支付 - 操作图标 -->
-      <template v-else-if="orderInfo.oilOrderStatus === 2">
-        <view class="flex items-center gap-48rpx">
-          <view class="flex flex-col items-center" @click="handleContact">
-            <wd-icon name="chat" size="48rpx" color="#333" />
-            <text class="mt8rpx text-24rpx">
-              联系客服
-            </text>
-          </view>
-        </view>
-      </template>
-
       <!-- 已退款 - 联系客服 -->
-      <template v-else-if="orderInfo.oilOrderStatus === 6">
-        <view class="flex items-center gap-48rpx">
-          <view class="flex flex-col items-center" @click="handleContact">
+      <template v-else-if="orderInfo.oilOrderStatus === 6 || orderInfo.oilOrderStatus === 2">
+        <view class="flex items-center gap-48rpx" @click="handleContact">
+          <view class="flex flex-col items-center">
             <wd-icon name="chat" size="48rpx" color="#333" />
             <text class="mt8rpx text-24rpx">
               联系客服
@@ -257,7 +244,9 @@ function handleGoHome() {
       <view class="text-26rpx text-#666 leading-48rpx">
         <view>支付方式:微信支付</view>
         <view>支付状态:成功</view>
-        <view>支付流水号:{{ orderInfo.transactionId || '-' }}</view>
+        <view class="break-all">
+          支付流水号:{{ orderInfo.transactionId || '-' }}
+        </view>
       </view>
     </view>
 

+ 31 - 30
src/pages/voucher/index.vue

@@ -104,7 +104,7 @@ watch(() => currentTab.value, () => {
       <view
         v-for="item in tabList"
         :key="item.value"
-        class="mr48rpx py24rpx text-28rpx"
+        class="py24rpx text-28rpx"
         :class="[currentTab === item.value ? 'text-[var(--them-color)] font-semibold border-b-4rpx border-[var(--them-color)]' : 'text-#666']"
         @click="handleTabChange(item.value)"
       >
@@ -118,39 +118,40 @@ watch(() => currentTab.value, () => {
         v-for="item in data"
         :key="item.id"
         class="mb20rpx rounded-16rpx bg-white px24rpx py28rpx"
-        @click="router.push({ name: 'voucherDetail', params: { id: item.id as string } })"
       >
-        <!-- 券信息头部 -->
-        <view class="flex items-center justify-between">
-          <view class="flex items-center">
-            <image
-              :src="`${StaticUrl}/smqjh-reful-juan.png`"
-              class="mr12rpx h32rpx w32rpx"
-            />
-            <view class="text-30rpx font-semibold">
-              抵扣{{ item.discountMoney }}元(满{{ item.amountMoney }}元可用)
+        <view @click="router.push({ name: 'voucherDetail', params: { id: item.id as string } })">
+          <!-- 券信息头部 -->
+          <view class="flex items-center justify-between">
+            <view class="flex items-center">
+              <image
+                :src="`${StaticUrl}/smqjh-reful-juan.png`"
+                class="mr12rpx h32rpx w32rpx"
+              />
+              <view class="text-30rpx font-semibold">
+                抵扣{{ item.discountMoney }}元(满{{ item.amountMoney }}元可用)
+              </view>
+            </view>
+            <!-- 待支付倒计时 -->
+            <view v-if="item.lockStatus === 1 && currentTab === 2" class="text-24rpx text-#1890ff">
+              待支付(<wd-count-down :time="getCountdownTime(item.orderCreateTime)" format="还剩mm:ss" />)
             </view>
           </view>
-          <!-- 待支付倒计时 -->
-          <view v-if="item.lockStatus === 1 && currentTab === 2" class="text-24rpx text-#1890ff">
-            待支付(<wd-count-down :time="getCountdownTime(item.orderCreateTime)" format="还剩mm:ss" />)
-          </view>
-        </view>
 
-        <!-- 券详情 -->
-        <view class="mt16rpx text-26rpx text-#999">
-          适用:全部合作油站
-        </view>
-        <view class="mt12rpx text-26rpx text-#999">
-          有效期至:{{ item.expirationTime }}
-        </view>
-        <view class="mt12rpx text-26rpx text-#999">
-          可抵扣:<text class="text-#ff4d3a">
-            ¥{{ item.discountMoney }}
-          </text>
-        </view>
-        <view class="mt12rpx text-26rpx text-#999">
-          状态:{{ statusMap.get(item.useStatus as number) || '' }}
+          <!-- 券详情 -->
+          <view class="mt16rpx text-26rpx text-#999">
+            适用:全部合作油站
+          </view>
+          <view class="mt12rpx text-26rpx text-#999">
+            有效期至:{{ item.expirationTime }}
+          </view>
+          <view class="mt12rpx text-26rpx text-#999">
+            可抵扣:<text class="text-#ff4d3a">
+              ¥{{ item.discountMoney }}
+            </text>
+          </view>
+          <view class="mt12rpx text-26rpx text-#999">
+            状态:{{ statusMap.get(item.useStatus as number) || '' }}
+          </view>
         </view>
 
         <!-- 操作按钮区域 -->

+ 1 - 1
src/router/index.ts

@@ -39,7 +39,7 @@ router.beforeEach((to, from, next) => {
   console.log('🚀 beforeEach 守卫触发:', { to, from }, '')
   const { token, redirectName } = storeToRefs(useUserStore())
   if (to.name === 'login') {
-    redirectName.value = appendParamsToPath(String(from.path), from.params as any)
+    redirectName.value = appendParamsToPath(String(from.path), from.query as any)
     console.log(redirectName.value, ' redirectName.value')
   }
   if (!whitePathName().includes(to.name) && !token.value) {

+ 38 - 0
src/store/user.ts

@@ -208,5 +208,43 @@ export const useUserStore = defineStore('user', {
         })
       }
     },
+    /**
+     * 取消订单
+     * @param orderId 订单ID
+     */
+    async handleCommonCancelOrder(orderId: string) {
+      return new Promise((resolve, reject) => {
+        useGlobalMessage().confirm({
+          title: '提示',
+          msg: '确定要取消该订单吗?',
+          zIndex: 9999,
+          success: async () => {
+            uni.showLoading({ mask: true })
+            try {
+              await Apis.general.post_smqjh_oms_api_v1_oil_order_cancel({ params: { orderId } })
+              useGlobalToast().show('取消成功')
+              resolve(true)
+            }
+            catch {
+              useGlobalToast().show('取消失败')
+              reject(new Error('取消失败'))
+            }
+            finally {
+              uni.hideLoading()
+            }
+          },
+        })
+      })
+    },
+    /**
+     * 拉起小橘支付
+     * @param path
+     */
+    handleCommonPath(path: string) {
+      uni.showLoading({ mask: true })
+      const url = import.meta.env.VITE_REDIRECT_URL
+      window.location.href = `${path}&redirectUrl=${url}`
+      uni.hideLoading()
+    },
   },
 })