v4.0.19版本提交

This commit is contained in:
2026-09-10 09:56:50 +08:00
parent 5d0beb5733
commit 1867e7ea55
23 changed files with 420 additions and 41 deletions
@@ -5,9 +5,10 @@ import Taro, { useRouter } from '@tarojs/taro';
import PageShell from '../../components/PageShell';
import SubPageHeader from '../../components/SubPageHeader';
import { goLogin } from '../../lib/auth-nav';
import { buildPayUrl } from '../../lib/checkout-nav';
import { buildOrderConfirmUrl, buildPayUrl } from '../../lib/checkout-nav';
import { fetchUserProfile } from '../../lib/pay-wechat';
import { request, toast } from '../../lib/api';
import { canBuyOnline } from '../../lib/product-fulfillment';
import { getProductMainImage } from '../../lib/product-images';
import BenefitFigure from '../../components/BenefitFigure';
import OrderQtyControls from '../../components/OrderQtyControls';
@@ -20,6 +21,7 @@ type PreviewProduct = {
price: number;
mainImageUrl?: string | null;
carouselUrls?: string[] | null;
allowOnlinePurchase?: boolean;
};
type OrderPreview = {
@@ -174,13 +176,35 @@ export default function OrderConfirmPickupPage() {
: !quantityOk
? `至少购买 ${minQty}${unitLabel}`
: '提交订单';
const allowOnline = canBuyOnline(preview?.product ?? {});
function goDelivery() {
if (!productId || !allowOnline) return;
Taro.redirectTo({
url: buildOrderConfirmUrl({
productId,
skuId: skuId || undefined,
qty: String(quantity),
}),
});
}
return (
<PageShell variant="sub" className="order-confirm-page" hasFixedFooter>
<SubPageHeader title="现场取货确认" />
<View className="sub-page-body">
<View className="order-card">
<Text className="order-card-title"></Text>
<Text className="order-card-title"></Text>
{allowOnline ? (
<View className="order-fulfillment-switch">
<View className="order-fulfillment-opt" onClick={goDelivery}>
<Text></Text>
</View>
<View className="order-fulfillment-opt order-fulfillment-opt--active">
<Text></Text>
</View>
</View>
) : null}
<Text className="u-muted"> · · </Text>
</View>
@@ -5,13 +5,13 @@ import Taro, { useRouter } from '@tarojs/taro';
import PageShell from '../../components/PageShell';
import SubPageHeader from '../../components/SubPageHeader';
import { goLogin } from '../../lib/auth-nav';
import { buildAddressListUrl, buildPayUrl, readCheckoutContext } from '../../lib/checkout-nav';
import { buildAddressListUrl, buildOrderConfirmPickupUrl, buildPayUrl, readCheckoutContext } from '../../lib/checkout-nav';
import { tryGetClientGpsLocation } from '../../lib/client-location';
import { maskPhone } from '../../lib/phone';
import { fetchUserProfile } from '../../lib/pay-wechat';
import { request, toast } from '../../lib/api';
import DeliveryHintHtml from '../../components/DeliveryHintHtml';
import { canCrossCity, isCrossCityAddress } from '../../lib/product-fulfillment';
import { canCrossCity, canPickupOnSite, isCrossCityAddress } from '../../lib/product-fulfillment';
import { loadLocalDeliveries, matchLocalDelivery, resolveLocalDeliveryHintHtml } from '../../lib/local-delivery';
import { getProductMainImage } from '../../lib/product-images';
import { isDirtyShippingAddress } from '../../lib/shipping-address';
@@ -39,6 +39,7 @@ type PreviewProduct = {
carouselUrls?: string[] | null;
allowCrossCityDelivery?: boolean;
allowOnlinePurchase?: boolean;
allowOnSitePickup?: boolean;
};
type OrderPreview = {
@@ -312,36 +313,63 @@ export default function OrderConfirmPage() {
? `至少购买 ${minQty}${unitLabel}`
: '提交订单';
const displayMsg = msg || addressHint;
const allowPickup = canPickupOnSite(preview?.product ?? {});
function goOnSitePickup() {
if (!productId || !allowPickup) return;
Taro.redirectTo({
url: buildOrderConfirmPickupUrl({
productId,
skuId: skuId || undefined,
qty: quantity,
}),
});
}
return (
<PageShell variant="sub" className="order-confirm-page" hasFixedFooter>
<SubPageHeader title="确认订单" />
<View className="sub-page-body">
<View
className="order-card"
onClick={() =>
Taro.navigateTo({
url: buildAddressListUrl({
productId,
qty: String(quantity),
addressId,
cross: forceCross,
}),
})
}
>
<Text className="order-card-title"></Text>
{selectedAddress ? (
<View>
<View style={{ display: 'flex', gap: '8px', marginBottom: 4 }}>
<Text className="order-card-title" style={{ fontSize: 15 }}>{selectedAddress.receiverName}</Text>
<Text className="u-muted">{maskPhone(selectedAddress.phone)}</Text>
<View className="order-card">
<Text className="order-card-title"></Text>
{allowPickup ? (
<View className="order-fulfillment-switch">
<View className="order-fulfillment-opt order-fulfillment-opt--active">
<Text></Text>
</View>
<View className="order-fulfillment-opt order-fulfillment-opt--pickup" onClick={goOnSitePickup}>
<Text></Text>
</View>
<Text className="u-muted">{formatAddress(selectedAddress)}</Text>
</View>
) : (
<Text className="u-muted"></Text>
)}
) : null}
{allowPickup ? (
<Text className="u-muted order-pickup-guide"></Text>
) : null}
<View
onClick={() =>
Taro.navigateTo({
url: buildAddressListUrl({
productId,
qty: String(quantity),
addressId,
cross: forceCross,
}),
})
}
>
<Text className="order-card-title order-address-title"></Text>
{selectedAddress ? (
<View>
<View style={{ display: 'flex', gap: '8px', marginBottom: 4 }}>
<Text className="order-card-title" style={{ fontSize: 15 }}>{selectedAddress.receiverName}</Text>
<Text className="u-muted">{maskPhone(selectedAddress.phone)}</Text>
</View>
<Text className="u-muted">{formatAddress(selectedAddress)}</Text>
</View>
) : (
<Text className="u-muted"></Text>
)}
</View>
</View>
{!addressOk && addressId ? (
@@ -9,7 +9,7 @@ import WechatShareReady from '../../components/WechatShareReady';
import ContactCsButton from '../../components/ContactCsButton';
import LogisticsRichText from '../../components/LogisticsRichText';
import { request, toast } from '../../lib/api';
import { buildPayUrl } from '../../lib/checkout-nav';
import { buildPayUrl, buildOrderConfirmPickupUrl } from '../../lib/checkout-nav';
import DeliveryHintHtml from '../../components/DeliveryHintHtml';
import { loadLocalDeliveries, matchLocalDelivery, resolveLocalDeliveryHintHtml } from '../../lib/local-delivery';
import {
@@ -45,6 +45,8 @@ type OrderDetail = {
orderNo?: string;
status?: string;
payAmount?: number;
productId?: string;
skuId?: string | null;
productName?: string;
quantity?: number;
qty?: number;
@@ -177,6 +179,11 @@ export default function OrderDetailPage() {
const isReship = !!order?.originOrderId;
const isProxy = !!order && (order.isProxyOrder || order.orderType === 'PROXY');
const canPay = !!order && order.status === 'PENDING_PAY' && !isReship;
const canSwitchPickup =
canPay &&
!isProxy &&
order?.deliveryType !== 'ON_SITE_PICKUP' &&
!!order?.productId;
const canConfirmReceive =
!!order && !isReship && !isProxy && ['PENDING_RECEIVE', 'DELIVERED'].includes(order.status || '');
const canInvoice =
@@ -226,6 +233,17 @@ export default function OrderDetailPage() {
Taro.navigateTo({ url: buildPayUrl({ orderId: order.id }) });
}
function goOnSitePickup() {
if (!order?.productId) return;
Taro.navigateTo({
url: buildOrderConfirmPickupUrl({
productId: String(order.productId),
skuId: order.skuId ? String(order.skuId) : undefined,
qty: quantity,
}),
});
}
function goCustomerService() {
Taro.navigateTo({ url: '/pages/customer-service/index' });
}
@@ -358,6 +376,22 @@ export default function OrderDetailPage() {
</View>
<View className="order-card">
<Text className="order-card-title"></Text>
{canSwitchPickup ? (
<View className="order-fulfillment-switch">
<View className="order-fulfillment-opt order-fulfillment-opt--active">
<Text></Text>
</View>
<View
className="order-fulfillment-opt order-fulfillment-opt--pickup"
onClick={goOnSitePickup}
>
<Text></Text>
</View>
</View>
) : null}
{canSwitchPickup ? (
<Text className="u-muted order-pickup-guide"></Text>
) : null}
{receiverLine || addressText ? (
<>
{receiverLine ? (