sunshibo 3 veckor sedan
förälder
incheckning
536a3597fe
4 ändrade filer med 94 tillägg och 21 borttagningar
  1. 19 11
      api/dining.js
  2. 18 3
      pages/checkout/index.vue
  3. 53 6
      pages/orderInfo/orderDetail.vue
  4. 4 1
      settings/siteSetting.js

+ 19 - 11
api/dining.js

@@ -186,19 +186,27 @@ export const GetMyOrders = (params) =>
 export const GetOrderInfo = (orderId) =>
   api.get({ url: `/store/order/info/${encodeURIComponent(orderId)}` });
 
-// 订单支付(GET /payment/prePay,入参 orderNo、payType、payer、price、subject、storeId 门店ID;返回微信支付调起参数)
-export const PostOrderPay = (params) =>
-  api.get({
+// 订单支付(GET /payment/prePay,入参 orderNo、payType、payer、price、subject、storeId、couponId 优惠券ID、payerId 用户ID;返回微信支付调起参数)
+export const PostOrderPay = (params) => {
+  const query = {
+    orderNo: params.orderNo,
+    payType: 'wechatPayMininProgram',
+    payer: params.payer,
+    price: params.price,
+    subject: params.subject ?? '订单支付',
+    storeId: params.storeId
+  };
+  if (params.couponId != null && params.couponId !== '') {
+    query.couponId = params.couponId;
+  }
+  if (params.payerId != null && params.payerId !== '') {
+    query.payerId = params.payerId;
+  }
+  return api.get({
     url: '/payment/prePay',
-    params: {
-      orderNo: params.orderNo,
-      payType: 'wechatPayMininProgram',
-      payer: params.payer,
-      price: params.price,
-      subject: params.subject ?? '订单支付',
-      storeId: params.storeId
-    }
+    params: query
   });
+};
 
 // 根据第三方订单号查询支付结果(GET /payment/searchOrderByOutTradeNoPath,入参 payType、transactionId、storeId)
 // 支付页调用时不显示全局 loading

+ 18 - 3
pages/checkout/index.vue

@@ -377,12 +377,22 @@ const handleConfirmPay = async () => {
   uni.showLoading({ title: '拉起支付...' });
   try {
     const storeId = orderInfo.value.storeId || uni.getStorageSync('currentStoreId') || '';
+    const u = userStore.getUserInfo || {};
+    const payerId = u.id ?? u.userId ?? u.user_id ?? '';
+    const couponIdVal =
+      orderInfo.value.couponId != null && orderInfo.value.couponId !== ''
+        ? String(orderInfo.value.couponId)
+        : selectedCouponId.value != null && selectedCouponId.value !== ''
+          ? String(selectedCouponId.value)
+          : '';
     const res = await diningApi.PostOrderPay({
       orderNo,
       payer: openid,
       price,
       subject: '订单支付',
-      storeId: storeId || undefined
+      storeId: storeId || undefined,
+      couponId: couponIdVal || undefined,
+      payerId: payerId ? String(payerId) : undefined
     });
     uni.hideLoading();
     uni.requestPayment({
@@ -399,9 +409,14 @@ const handleConfirmPay = async () => {
           diningApi.PostOrderSettlementUnlock({ orderId: oid }).catch((e) => console.warn('解锁订单失败:', e));
         }
         const payType = 'wechatPayMininProgram';
-        const transactionId = orderNo;
+        // 查询支付结果需用 prePay 返回的 transactionId,与订单号 orderNo 可能不同
+        const prePayTid =
+          res?.transactionId ??
+          res?.transaction_id ??
+          res?.outTradeNo ??
+          orderNo;
         const sid = orderInfo.value.storeId || uni.getStorageSync('currentStoreId') || '';
-        const q = [`id=${encodeURIComponent(oid)}`, `payType=${encodeURIComponent(payType)}`, `transactionId=${encodeURIComponent(transactionId)}`];
+        const q = [`id=${encodeURIComponent(oid)}`, `payType=${encodeURIComponent(payType)}`, `transactionId=${encodeURIComponent(String(prePayTid ?? ''))}`];
         if (sid) q.push(`storeId=${encodeURIComponent(sid)}`);
         setTimeout(() => go(`/pages/paymentSuccess/index?${q.join('&')}`), 1500);
       },

+ 53 - 6
pages/orderInfo/orderDetail.vue

@@ -50,9 +50,19 @@
           <view class="info-item-label">餐具费</view>
           <view class="info-item-value">¥{{ priceDetail.tablewareFee }}</view>
         </view>
+        <!-- 已完成订单:优惠金额(满减用 nominalValue;折扣按菜品总价与折扣率计算,与结算页选券逻辑一致) -->
+        <view
+          v-if="orderDetail.orderStatus === 3 && completedOrderDiscountDisplay > 0"
+          class="info-item info-item--coupon"
+        >
+          <view class="info-item-label">优惠金额</view>
+          <view class="info-item-value coupon-value">
+            <text class="coupon-amount">-¥{{ formatPrice(completedOrderDiscountDisplay) }}</text>
+          </view>
+        </view>
         <view class="price-line">
           <view class="price-line-label">合计</view>
-          <view class="price-line-value">¥{{ priceDetail.total }}</view>
+          <view class="price-line-value">¥{{ formatPrice(orderSummaryDisplayAmount) }}</view>
         </view>
        
       </view>
@@ -65,7 +75,7 @@
       <view class="card-content">
         <view class="info-item">
           <view class="info-item-label">{{ payMethodText }}</view>
-          <view class="info-item-value">¥{{ priceDetail.total }}</view>
+          <view class="info-item-value">¥{{ formatPrice(orderSummaryDisplayAmount) }}</view>
         </view>
       </view>
     </view>
@@ -177,6 +187,41 @@ const couponDisplayText = computed(() => {
   return p.couponName || '已使用优惠券';
 });
 
+// 已完成订单展示用优惠金额:与 pages/checkout 选券后 discountAmount 计算一致
+// couponType 1 满减:取 nominalValue;2 折扣:菜品总价 × (1 - discountRate/10),discountRate 已为接口值/10
+const completedOrderDiscountDisplay = computed(() => {
+  if (orderDetail.value.orderStatus !== 3) return 0;
+  const p = priceDetail.value;
+  const dishTotalNum = Number(p.dishTotal) || 0;
+  const type = Number(p.couponType);
+
+  if (type === 1) {
+    if (p.nominalValue != null && p.nominalValue !== '') {
+      const nv = Number(p.nominalValue);
+      return Number.isNaN(nv) ? 0 : Math.max(0, nv);
+    }
+    return Math.max(0, Number(p.discountAmount) || 0);
+  }
+  if (type === 2) {
+    if (p.discountRate == null || p.discountRate === '' || dishTotalNum <= 0) return 0;
+    const rate = Number(p.discountRate) || 0;
+    return Math.round(dishTotalNum * (1 - rate / 10) * 100) / 100;
+  }
+  return Math.max(0, Number(p.discountAmount) || 0);
+});
+
+// 合计 / 已完成实付展示:已完成 = 菜品总价 + 餐具费 − 优惠(与结算页 payAmount 一致);未完成 = 接口应付 total
+const orderSummaryDisplayAmount = computed(() => {
+  const p = priceDetail.value;
+  if (orderDetail.value.orderStatus === 3) {
+    const dish = Number(p.dishTotal) || 0;
+    const utensil = Number(p.tablewareFee) || 0;
+    const discount = completedOrderDiscountDisplay.value;
+    return Math.max(0, Math.round((dish + utensil - discount) * 100) / 100);
+  }
+  return Number(p.total) || 0;
+});
+
 // 菜品列表(接口订单明细)
 const foodList = ref([]);
 
@@ -266,21 +311,23 @@ function applyOrderData(data) {
     orderStatus: raw?.orderStatus ?? raw?.status ?? null,
     payType: raw?.payType ?? raw?.payMethod ?? ''
   };
+  const couponInfo = raw?.couponInfo ?? raw?.coupon ?? {};
   const dishTotal = raw?.totalAmount ?? raw?.dishTotal ?? raw?.orderAmount ?? raw?.foodAmount ?? 0;
   const tablewareFee = raw?.tablewareFee ?? raw?.tablewareAmount ?? 0;
   const couponDiscount = raw?.couponAmount ?? raw?.couponDiscount ?? 0;
   const discountAmountVal = Number(raw?.discountAmount ?? raw?.couponAmount ?? raw?.couponDiscount ?? 0) || 0;
   const total = raw?.payAmount ?? raw?.totalAmount ?? raw?.totalPrice ?? 0;
-  const rawDiscountRate = raw?.discountRate ?? raw?.couponInfo?.discountRate ?? raw?.coupon?.discountRate;
+  const rawDiscountRate =
+    raw?.discountRate ?? couponInfo?.discountRate ?? raw?.coupon?.discountRate;
   const discountRateVal = rawDiscountRate != null && rawDiscountRate !== '' ? (Number(rawDiscountRate) || 0) / 10 : null;
   priceDetail.value = {
     dishTotal: formatPrice(dishTotal),
     tablewareFee: formatPrice(tablewareFee),
     couponDiscount: formatPrice(couponDiscount),
     discountAmount: discountAmountVal,
-    couponName: raw?.couponName ?? '',
-    couponType: raw?.couponType ?? null,
-    nominalValue: raw?.nominalValue ?? null,
+    couponName: raw?.couponName ?? couponInfo?.couponName ?? couponInfo?.name ?? '',
+    couponType: raw?.couponType ?? couponInfo?.couponType ?? null,
+    nominalValue: raw?.nominalValue ?? couponInfo?.nominalValue ?? couponInfo?.amount ?? null,
     discountRate: discountRateVal,
     total: formatPrice(total)
   };

+ 4 - 1
settings/siteSetting.js

@@ -4,8 +4,11 @@ export const DEFAULT_CDN_URL = 'https://alien-volume.oss-cn-beijing.aliyuncs.com
 // 文件CDN地址
 export const UPLOAD = 'https://alien-volume.oss-cn-beijing.aliyuncs.com/';
 
-// 请求地址  development 开发 | production 正式
+// uat环境
 export const BASE_API_URL = 'https://uat.ailien.shop/alienDining';
 
+// 测试环境
+// export const BASE_API_URL = 'https://test.ailien.shop/alienDining';
+
 /** 文件上传 请求地址 */
 export const UPLOAD_URL = 'https://api.xxxxxx.cn/File/UploadImg';