v4.0.19版本提交
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@dukang/admin-web",
|
||||
"version": "4.0.18",
|
||||
"version": "4.0.19",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@dukang/h5-partner",
|
||||
"version": "4.0.18",
|
||||
"version": "4.0.19",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@dukang/h5-shop",
|
||||
"version": "4.0.18",
|
||||
"version": "4.0.19",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@dukang/mini-user",
|
||||
"version": "4.0.18",
|
||||
"version": "4.0.19",
|
||||
"private": true,
|
||||
"description": "杜康好客 · C 端用户微信小程序(Taro)",
|
||||
"scripts": {
|
||||
|
||||
@@ -52,6 +52,19 @@ export function buildPayUrl(params: {
|
||||
return `/pages/pay/index?${parts.join('&')}`;
|
||||
}
|
||||
|
||||
export function buildOrderConfirmPickupUrl(ctx: {
|
||||
productId: string;
|
||||
skuId?: string;
|
||||
qty?: string | number;
|
||||
}): string {
|
||||
const parts = [`productId=${encodeURIComponent(ctx.productId)}`];
|
||||
if (ctx.skuId) parts.push(`skuId=${encodeURIComponent(ctx.skuId)}`);
|
||||
if (ctx.qty != null && String(ctx.qty).trim()) {
|
||||
parts.push(`qty=${encodeURIComponent(String(ctx.qty))}`);
|
||||
}
|
||||
return `/pages/order-confirm-pickup/index?${parts.join('&')}`;
|
||||
}
|
||||
|
||||
export function readCheckoutContext(params: Record<string, string | undefined>): CheckoutContext {
|
||||
return {
|
||||
productId: params.productId,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { fetchClientConfig } from './pay-wechat';
|
||||
|
||||
/** 与 package.json version 同步(Taro defineConstants 注入),供 minClientVersion 比对 */
|
||||
export const APP_VERSION =
|
||||
(typeof TARO_APP_VERSION !== 'undefined' && String(TARO_APP_VERSION).trim()) || '4.0.4';
|
||||
(typeof TARO_APP_VERSION !== 'undefined' && String(TARO_APP_VERSION).trim()) || '4.0.19';
|
||||
|
||||
export const APP_VERSION_LABEL = `v${APP_VERSION.replace(/^v/i, '')}`;
|
||||
|
||||
|
||||
@@ -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 ? (
|
||||
|
||||
@@ -81,6 +81,49 @@
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
.order-fulfillment-switch {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin: 10px 0 12px;
|
||||
}
|
||||
|
||||
.order-fulfillment-opt {
|
||||
flex: 1;
|
||||
height: 40px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--color-outline, #c8c4be);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: var(--color-on-surface);
|
||||
}
|
||||
|
||||
.order-fulfillment-opt--active {
|
||||
border-color: var(--color-heritage-red);
|
||||
color: var(--color-heritage-red);
|
||||
background: rgba(166, 29, 36, 0.08);
|
||||
}
|
||||
|
||||
.order-fulfillment-opt--pickup {
|
||||
border-color: var(--color-heritage-red);
|
||||
color: var(--color-heritage-red);
|
||||
}
|
||||
|
||||
.order-address-title {
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.order-pickup-guide {
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.order-card--warn {
|
||||
background: rgba(166, 29, 36, 0.06);
|
||||
box-shadow: none;
|
||||
|
||||
Reference in New Issue
Block a user