Product flag, ON_SITE_PICKUP delivery, mini confirm/receive pages; pay skips warehouse auto-advance. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
import { useCallback, useState } from 'react';
|
||||
import { View, Text, Image } from '@tarojs/components';
|
||||
import Taro, { useDidShow, useRouter } from '@tarojs/taro';
|
||||
import PageShell from '../../components/PageShell';
|
||||
import SubPageHeader from '../../components/SubPageHeader';
|
||||
import { request, toast } from '../../lib/api';
|
||||
import { getProductMainImage } from '../../lib/product-images';
|
||||
|
||||
type OrderDetail = {
|
||||
id: string;
|
||||
orderNo?: string;
|
||||
status?: string;
|
||||
payAmount?: number | string;
|
||||
productName?: string;
|
||||
productSpec?: string;
|
||||
quantity?: number;
|
||||
product?: {
|
||||
name?: string;
|
||||
spec?: string;
|
||||
mainImageUrl?: string | null;
|
||||
carouselUrls?: string[] | null;
|
||||
};
|
||||
imageUrl?: string | null;
|
||||
mainImageUrl?: string | null;
|
||||
};
|
||||
|
||||
export default function PickupReceivePage() {
|
||||
const router = useRouter();
|
||||
const orderId = router.params.id ?? router.params.orderId ?? '';
|
||||
const [order, setOrder] = useState<OrderDetail | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
|
||||
const load = useCallback(() => {
|
||||
if (!orderId) return;
|
||||
setLoading(true);
|
||||
request<OrderDetail>(`/trade/orders/${orderId}`)
|
||||
.then((data) => setOrder(data))
|
||||
.catch((e) => toast(e instanceof Error ? e.message : '加载失败'))
|
||||
.finally(() => setLoading(false));
|
||||
}, [orderId]);
|
||||
|
||||
useDidShow(() => {
|
||||
load();
|
||||
});
|
||||
|
||||
async function confirmReceive() {
|
||||
if (!orderId || submitting) return;
|
||||
setSubmitting(true);
|
||||
try {
|
||||
await request(`/trade/orders/${orderId}/confirm-receive`, {
|
||||
method: 'POST',
|
||||
data: {},
|
||||
});
|
||||
toast('确认收货成功', 'success');
|
||||
setTimeout(() => {
|
||||
Taro.redirectTo({ url: '/pages/orders/index?tab=done' });
|
||||
}, 500);
|
||||
} catch (e) {
|
||||
toast(e instanceof Error ? e.message : '确认失败');
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
}
|
||||
|
||||
const name = order?.productName || order?.product?.name || '商品';
|
||||
const spec = order?.productSpec || order?.product?.spec;
|
||||
const image =
|
||||
order?.mainImageUrl ||
|
||||
order?.imageUrl ||
|
||||
(order?.product ? getProductMainImage(order.product) : '') ||
|
||||
'';
|
||||
const amount = Number(order?.payAmount ?? 0);
|
||||
const canConfirm = order?.status === 'PENDING_RECEIVE' || order?.status === 'DELIVERED';
|
||||
|
||||
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="u-muted">请确认已在现场拿到商品后再点击确认收货</Text>
|
||||
</View>
|
||||
|
||||
{loading && !order ? (
|
||||
<View className="order-card">
|
||||
<Text className="u-muted">加载中…</Text>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
{order ? (
|
||||
<>
|
||||
<View className="order-card">
|
||||
<View className="order-row">
|
||||
<Text className="order-row-label">订单号</Text>
|
||||
<Text className="order-row-value">{order.orderNo || '—'}</Text>
|
||||
</View>
|
||||
<View className="order-product-row" style={{ marginTop: 12 }}>
|
||||
<View className="order-product-thumb">
|
||||
{image ? (
|
||||
<Image className="order-product-thumb-img" src={image} mode="aspectFill" />
|
||||
) : null}
|
||||
</View>
|
||||
<View style={{ flex: 1 }}>
|
||||
<Text className="order-product-name">{name}</Text>
|
||||
{spec ? <Text className="u-muted">{spec}</Text> : null}
|
||||
<Text className="u-muted">×{order.quantity ?? 1}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className="order-card">
|
||||
<View className="order-row">
|
||||
<Text className="order-row-label">实付金额</Text>
|
||||
<Text className="order-row-value order-pay-amount">
|
||||
¥{Number.isFinite(amount) ? amount.toFixed(2) : '—'}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
) : null}
|
||||
</View>
|
||||
<View className="pay-bar">
|
||||
<View
|
||||
className="order-confirm-submit"
|
||||
style={{ flex: 1, opacity: canConfirm && !submitting ? 1 : 0.6 }}
|
||||
onClick={() => {
|
||||
if (!canConfirm || submitting) return;
|
||||
void confirmReceive();
|
||||
}}
|
||||
>
|
||||
<Text>{submitting ? '提交中…' : canConfirm ? '确认收货' : '订单状态不可确认'}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</PageShell>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user