import { useEffect, useRef, useState } from 'react'; import { View, Text, Image } from '@tarojs/components'; 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 { ensurePayReady } from '../../lib/pay-ready'; import { fetchUserProfile } from '../../lib/pay-wechat'; import { request, toast } from '../../lib/api'; import { getProductMainImage } from '../../lib/product-images'; type PreviewProduct = { id: string; name: string; spec?: string; subtitle?: string; price: number; mainImageUrl?: string | null; carouselUrls?: string[] | null; }; type OrderPreview = { product: PreviewProduct; quantity: number; deliveryType: string; productAmount: number; payAmount: number; benefitAmount: number; quantityOk?: boolean; quantityMessage?: string | null; minQty?: number; }; export default function OrderConfirmPickupPage() { const router = useRouter(); const productId = router.params.productId ?? ''; const [quantity, setQuantity] = useState(Math.max(2, Number(router.params.qty || 2))); const [preview, setPreview] = useState(null); const [previewLoading, setPreviewLoading] = useState(false); const [loading, setLoading] = useState(false); const [msg, setMsg] = useState(''); const phonePromptSkipped = useRef(false); useEffect(() => { if (!productId) return; let cancelled = false; setPreviewLoading(true); request('/trade/orders/preview', { method: 'POST', data: { productId, quantity, onSitePickup: true }, }) .then((data) => { if (!cancelled) { setPreview(data); setMsg(data.quantityOk === false ? data.quantityMessage || '' : ''); } }) .catch((e) => { if (!cancelled) { setPreview(null); setMsg(e instanceof Error ? e.message : '加载失败'); } }) .finally(() => { if (!cancelled) setPreviewLoading(false); }); return () => { cancelled = true; }; }, [productId, quantity]); const minQty = preview?.minQty ?? 2; const quantityOk = preview ? preview.quantityOk !== false && quantity >= minQty : false; const canSubmit = !!preview && quantityOk && !loading && !previewLoading; function updateQuantity(next: number) { if (next < minQty) { const tip = `现场提货至少购买 ${minQty} 瓶`; toast(tip); setMsg(tip); if (next < 1) return; setQuantity(next); return; } setQuantity(next); } async function doSubmit() { const order = await request<{ id: string }>('/trade/orders', { method: 'POST', data: { productId, quantity, onSitePickup: true }, }); Taro.redirectTo({ url: buildPayUrl({ orderId: order.id, productId, qty: String(quantity), }), }); } async function submit() { if (!canSubmit) { if (!quantityOk) { const tip = `现场提货至少购买 ${minQty} 瓶`; setMsg(tip); toast(tip); return; } } const returnPath = `/pages/order-confirm-pickup/index?productId=${productId}&qty=${quantity}`; if (!phonePromptSkipped.current) { try { const profile = await fetchUserProfile(); const phoneBound = !!profile.phoneVerified || (!!profile.phone && /^1[3-9]\d{9}$/.test(String(profile.phone))); if (!phoneBound) { const { confirm, cancel } = await Taro.showModal({ title: '建议绑定手机号', content: '绑定后便于订单通知与售后联系;也可跳过,不绑定也能继续下单。', confirmText: '去绑定', cancelText: '暂不绑定', }); if (confirm) { goLogin(returnPath, { needPhone: '1' }); return; } if (cancel) { phonePromptSkipped.current = true; } } } catch { /* 拉取档案失败不阻塞下单 */ } } const ready = await ensurePayReady(returnPath); if (!ready) return; setLoading(true); setMsg(''); try { await doSubmit(); } catch (e) { setMsg(e instanceof Error ? e.message : '下单失败'); } finally { setLoading(false); } } const productImage = preview?.product ? getProductMainImage(preview.product) : ''; const submitLabel = loading ? '提交中…' : !quantityOk ? `至少购买 ${minQty} 瓶` : '提交订单'; return ( 取货方式 现场取货 · 无需填写收货地址 · 免运费 {preview ? ( <> 商品信息 {productImage ? ( ) : null} {preview.product.name} {preview.product.spec ? ( {preview.product.spec} ) : null} ¥{Number(preview.product.price).toFixed(2)} 购买数量 updateQuantity(quantity - 1)} > {quantity} updateQuantity(quantity + 1)}> {!quantityOk ? ( {`现场提货至少购买 ${minQty} 瓶,请调整数量`} ) : null} 费用明细 商品金额 ¥{Number(preview.productAmount).toFixed(2)} 好客权益 ¥{Number(preview.benefitAmount).toFixed(2)} 运费 免运费 ) : previewLoading ? ( 加载订单信息… ) : null} {msg ? ( {msg} ) : null} 应付合计 ¥{preview ? Number(preview.payAmount).toFixed(2) : '—'} { if (!canSubmit) return; void submit(); }} > {submitLabel} ); }