From 3248315f6e35b367c9414c332e2574ef683edafb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Mon, 9 Mar 2026 12:17:29 +0800 Subject: [PATCH] =?UTF-8?q?refactor(shop):=20=E7=A7=BB=E9=99=A4=E6=B0=B4?= =?UTF-8?q?=E7=A5=A8=E5=A5=97=E7=A5=A8=E5=95=86=E5=93=81=E9=85=8D=E9=80=81?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E9=80=89=E6=8B=A9=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除了配送时间相关的状态管理和日期选择器组件 - 移除了配送时间验证和格式化逻辑 - 更新了订单提交流程,不再传递配送时间参数 - 修改支付回调处理,支持自定义成功行为和跳转逻辑 - 简化了水票商品的购买流程,移除配送时间相关校验 --- src/shop/orderConfirm/index.tsx | 137 ++++++++++++-------------------- src/utils/payment.ts | 31 +++++--- 2 files changed, 73 insertions(+), 95 deletions(-) diff --git a/src/shop/orderConfirm/index.tsx b/src/shop/orderConfirm/index.tsx index c6765b0..003e473 100644 --- a/src/shop/orderConfirm/index.tsx +++ b/src/shop/orderConfirm/index.tsx @@ -1,4 +1,4 @@ -import {useEffect, useMemo, useState} from "react"; +import {useEffect, useState} from "react"; import { Image, Button, @@ -9,7 +9,6 @@ import { ActionSheet, Popup, InputNumber, - DatePicker, ConfigProvider } from '@nutui/nutui-react-taro' import {Location, ArrowRight} from '@nutui/icons-react-taro' @@ -39,7 +38,6 @@ import { filterUsableCoupons, filterUnusableCoupons } from "@/utils/couponUtils"; -import dayjs from 'dayjs' import type {ShopStore} from "@/api/shop/shopStore/model"; import {getShopStore, listShopStore} from "@/api/shop/shopStore"; import {getSelectedStoreFromStorage, saveSelectedStoreToStorage} from "@/utils/storeSelection"; @@ -57,18 +55,6 @@ const OrderConfirm = () => { const [loading, setLoading] = useState(true) const [error, setError] = useState('') const [payLoading, setPayLoading] = useState(false) - // 配送时间(仅水票套票商品需要) - // 当日截单时间:超过该时间下单,最早配送日顺延到次日(避免 21:00 下单仍显示“当天配送”) - const DELIVERY_CUTOFF_HOUR = 21 - const getMinSendDate = () => { - const now = dayjs() - const cutoff = now.hour(DELIVERY_CUTOFF_HOUR).minute(0).second(0).millisecond(0) - const startOfToday = now.startOf('day') - // >= 截单时间则最早只能选次日 - return now.isSame(cutoff) || now.isAfter(cutoff) ? startOfToday.add(1, 'day') : startOfToday - } - const [sendTime, setSendTime] = useState(() => getMinSendDate().toDate()) - const [sendTimePickerVisible, setSendTimePickerVisible] = useState(false) // 水票套票活动(若存在则按规则限制最小购买量等) const [ticketTemplate, setTicketTemplate] = useState(null) @@ -122,10 +108,6 @@ const OrderConfirm = () => { })() const minBuyQty = isTicketTemplateActive ? ticketMinBuyQty : 1 - const sendTimeText = useMemo(() => { - return dayjs(sendTime).format('YYYY-MM-DD') - }, [sendTime]) - const getGiftTicketQty = (buyQty: number) => { if (!isTicketTemplateActive) return 0 const multiplier = Number(ticketTemplate?.giftMultiplier || 0) @@ -451,22 +433,7 @@ const OrderConfirm = () => { return; } - // 水票套票商品:保存配送时间到 ShopOrder.sendStartTime - if (hasTicketTemplate && !sendTime) { - Taro.showToast({ title: '请选择配送时间', icon: 'none' }) - return - } - if (hasTicketTemplate) { - const min = getMinSendDate() - if (dayjs(sendTime).isBefore(min, 'day')) { - setSendTime(min.toDate()) - Taro.showToast({ - title: `已过当日${DELIVERY_CUTOFF_HOUR}点截单,最早配送:${min.format('YYYY-MM-DD')}`, - icon: 'none' - }) - return - } - } + // 购买水票(囤券预付费)与水票核销(下单履约)为两个独立动作:下单页不再选择配送时间。 // 水票套票活动:最小购买量校验 if (isTicketTemplateActive && quantity < minBuyQty) { @@ -530,9 +497,6 @@ const OrderConfirm = () => { comments: goods.name, deliveryType: 0, buyerRemarks: orderRemark, - sendStartTime: hasTicketTemplate - ? dayjs(sendTime).startOf('day').format('YYYY-MM-DD HH:mm:ss') - : undefined, couponId: parseInt(String(bestCoupon.id), 10) } ); @@ -540,7 +504,31 @@ const OrderConfirm = () => { console.log('🎯 使用推荐优惠券的订单数据:', updatedOrderData); // 执行支付 - await PaymentHandler.pay(updatedOrderData, currentPaymentType); + await PaymentHandler.pay(updatedOrderData, currentPaymentType, hasTicketTemplate ? { + onSuccess: async () => { + const id = goods.goodsId + try { + const res = await Taro.showModal({ + title: '提示', + content: '是否立刻送水?', + confirmText: '立刻送水', + cancelText: '稍后' + }) + if (res?.confirm) { + if (id) { + await Taro.redirectTo({ url: `/user/ticket/use?goodsId=${id}` }) + } else { + await Taro.redirectTo({ url: '/user/ticket/index' }) + } + } else { + await Taro.redirectTo({ url: '/user/ticket/index' }) + } + } catch (_e) { + await Taro.redirectTo({ url: '/user/ticket/index' }) + } + return false + } + } : undefined); return; // 提前返回,避免重复执行支付 } else { // 用户选择不使用优惠券,继续支付 @@ -558,9 +546,6 @@ const OrderConfirm = () => { comments: '桂乐淘', deliveryType: 0, buyerRemarks: orderRemark, - sendStartTime: hasTicketTemplate - ? dayjs(sendTime).startOf('day').format('YYYY-MM-DD HH:mm:ss') - : undefined, // 🔧 确保 couponId 是正确的数字类型,且不传递 undefined couponId: selectedCoupon ? parseInt(String(selectedCoupon.id), 10) : undefined } @@ -595,7 +580,31 @@ const OrderConfirm = () => { }); // 执行支付 - 移除这里的成功提示,让PaymentHandler统一处理 - await PaymentHandler.pay(orderData, paymentType); + await PaymentHandler.pay(orderData, paymentType, hasTicketTemplate ? { + onSuccess: async () => { + const id = goods.goodsId + try { + const res = await Taro.showModal({ + title: '提示', + content: '是否立刻送水?', + confirmText: '立刻送水', + cancelText: '稍后' + }) + if (res?.confirm) { + if (id) { + await Taro.redirectTo({ url: `/user/ticket/use?goodsId=${id}` }) + } else { + await Taro.redirectTo({ url: '/user/ticket/index' }) + } + } else { + await Taro.redirectTo({ url: '/user/ticket/index' }) + } + } catch (_e) { + await Taro.redirectTo({ url: '/user/ticket/index' }) + } + return false + } + } : undefined); // ✅ 移除双重成功提示 - PaymentHandler会处理成功提示 // Taro.showToast({ @@ -760,10 +769,7 @@ const OrderConfirm = () => { }) useEffect(() => { - // 切换商品时重置配送时间,避免沿用上一次选择 if (!isLoggedIn()) return - setSendTime(getMinSendDate().toDate()) - setSendTimePickerVisible(false) loadAllData() }, [goodsId]); @@ -822,28 +828,6 @@ const OrderConfirm = () => { )} - {hasTicketTemplate && ( - - - {sendTimeText} - - - )} - onClick={() => { - // 若页面停留跨过截单时间,打开选择器前再校正一次最早可选日期 - const min = getMinSendDate() - if (dayjs(sendTime).isBefore(min, 'day')) { - setSendTime(min.toDate()) - } - setSendTimePickerVisible(true) - }} - /> - - )} - {/**/} {/* { - setSendTimePickerVisible(false)} - onCancel={() => setSendTimePickerVisible(false)} - onConfirm={(_options, selectedValue) => { - const [y, m, d] = (selectedValue || []).map(v => Number(v)) - const next = new Date(y, (m || 1) - 1, d || 1, 0, 0, 0) - setSendTime(next) - setSendTimePickerVisible(false) - }} - /> -
diff --git a/src/utils/payment.ts b/src/utils/payment.ts index 9b81d29..94a83e5 100644 --- a/src/utils/payment.ts +++ b/src/utils/payment.ts @@ -19,7 +19,8 @@ export enum PaymentType { * 支付结果回调 */ export interface PaymentCallback { - onSuccess?: () => void; + // Return `false` to skip default "支付成功" toast + redirect. + onSuccess?: () => void | boolean | Promise; onError?: (error: string) => void; onComplete?: () => void; } @@ -118,17 +119,27 @@ export class PaymentHandler { if (paymentSuccess) { console.log('支付成功,订单号:', result.orderNo); - Taro.showToast({ - title: '支付成功', - icon: 'success' - }); + // 先收起 loading,避免遮挡 modal/toast + try { + Taro.hideLoading(); + } catch (_e) { + // ignore + } - callback?.onSuccess?.(); + const onSuccessResult = await callback?.onSuccess?.(); + const skipDefaultSuccessBehavior = onSuccessResult === false; - // 跳转到订单页面 - setTimeout(() => { - Taro.navigateTo({ url: '/user/order/order' }); - }, 2000); + if (!skipDefaultSuccessBehavior) { + Taro.showToast({ + title: '支付成功', + icon: 'success' + }); + + // 跳转到订单页面 + setTimeout(() => { + Taro.navigateTo({ url: '/user/order/order' }); + }, 2000); + } } else { throw new Error('支付未完成'); }