import React, { useState, useEffect } from 'react' import { View, Text, ScrollView } from '@tarojs/components' import Taro from '@tarojs/taro' import { Button } from '@nutui/nutui-react-taro' import { queryLogistics, formatLogisticsStatus } from '@/api/shop/shopLogistics' import type { LogisticsInfo, LogisticsTrack } from '@/api/shop/shopLogistics' import { getShopOrder } from '@/api/shop/shopOrder' import type { ShopOrder, ShopOrderDelivery } from '@/api/shop/shopOrder/model' import { OrderStatus } from '@/types/order' import Loading from '@/components/common/Loading' import EmptyState from '@/components/common/EmptyState' definePageConfig({ navigationBarTitleText: '物流详情', }) // 发货方式映射 const DELIVERY_METHOD_MAP: Record = { 10: '手动录入', 20: '无需物流', 30: '电子面单', } const LogisticsPage: React.FC = () => { const { orderId, expressNo: urlExpressNo, expressCompany: urlExpressCompany } = Taro.getCurrentInstance().router?.params || {} const [loading, setLoading] = useState(true) const [order, setOrder] = useState(null) const [delivery, setDelivery] = useState(null) const [logisticsInfo, setLogisticsInfo] = useState(null) const [trackList, setTrackList] = useState([]) useEffect(() => { loadLogistics() }, []) const loadLogistics = async () => { if (!orderId) { Taro.showToast({ title: '缺少订单参数', icon: 'none' }) setLoading(false) return } setLoading(true) try { // 1) 拉取订单详情(含 shopOrderDelivery,由后端 getByIdRel 填充) let orderData: ShopOrder | null = null try { orderData = await getShopOrder(Number(orderId)) } catch (err) { console.error('加载订单信息失败', err) } if (orderData) { setOrder(orderData) setDelivery(orderData.shopOrderDelivery ?? null) } // 2) 决定运单号 / 物流公司:优先 URL 参数,其次订单的 shopOrderDelivery const expressNo = urlExpressNo || orderData?.shopOrderDelivery?.expressNo || orderData?.expressNo || '' // expressCompany 通常是快递公司代码(SF/YTO 等);shopOrderDelivery.expressName 是中文名 const expressCompany = urlExpressCompany || '' // 3) 如果有运单号 + 物流公司代码,尝试查询物流轨迹(失败不阻塞发货单展示) if (expressNo && expressCompany) { try { const res = await queryLogistics({ orderId, expressNo, expressCompany }) if (res?.data) { setLogisticsInfo(res.data.logisticsInfo || null) setTrackList(res.data.trackList || []) } } catch (err) { console.error('查询物流轨迹失败', err) } } } finally { setLoading(false) } } // 复制单号 const copyExpressNo = () => { const no = logisticsInfo?.expressNo || delivery?.expressNo || order?.expressNo || '' if (!no) return Taro.setClipboardData({ data: no, success: () => Taro.showToast({ title: '单号已复制', icon: 'success' }), }) } // 联系客服 const contactService = () => { Taro.makePhoneCall({ phoneNumber: '400-811-1111', fail: () => Taro.showToast({ title: '拨打失败', icon: 'none' }), }) } // 格式化时间 const formatTime = (time?: string) => { if (!time) return '-' return time.replace('T', ' ').slice(0, 19) } if (loading) { return } // 既无物流轨迹,又无发货单,又无订单 → 空状态 const hasAnything = logisticsInfo || trackList?.length || delivery || order if (!hasAnything) { return ( ) } const statusInfo = logisticsInfo ? formatLogisticsStatus(logisticsInfo.status) : null // 发货状态文案:优先用 logisticsInfo.status,否则按订单 deliveryStatus 推断 const getDeliveryStatusText = (): string => { if (logisticsInfo?.status) return logisticsInfo.status const ds = order?.deliveryStatus if (ds === 30) return '部分发货' if (ds === 20) return '已发货' if (ds === 10) return '未发货' if (order?.orderStatus === OrderStatus.Completed) return '已签收' return '已发货' } // 物流公司名:优先 logisticsInfo,其次 delivery.expressName const expressCompanyName = logisticsInfo?.expressCompanyName || delivery?.expressName || '未知物流' // 运单号:优先 logisticsInfo,其次 delivery,最后 order const expressNo = logisticsInfo?.expressNo || delivery?.expressNo || order?.expressNo || '' // 发货人信息 const sendName = delivery?.sendName || order?.expressMerchantName || '-' const sendPhone = delivery?.sendPhone || '-' const sendAddress = delivery?.sendAddress || '-' const deliveryMethodText = delivery?.deliveryMethod != null ? DELIVERY_METHOD_MAP[delivery.deliveryMethod] || '-' : (expressNo ? '手动录入' : '无需物流') return ( {/* 快递信息卡片 */} 📦 {expressCompanyName} {getDeliveryStatusText()} 运单号: {expressNo || '暂无'} {expressNo ? ( 复制 ) : null} {/* 发货方式 */} 发货方式 {deliveryMethodText} {/* 发货单信息(shopOrderDelivery) */} {delivery ? ( 发货信息 发货人 {sendName} 联系方式 {sendPhone} 发货地址 {sendAddress} 物流单号 {delivery.expressNo || '-'} {delivery.expressNo ? ( 复制 ) : null} {delivery.createTime ? ( 发货时间 {formatTime(delivery.createTime)} ) : null} ) : null} {/* 收货人信息(从订单读取) */} {order ? ( 收货信息 {order.realName || '-'} {order.mobile || order.phone || '-'} {order.address || '-'} ) : null} {/* 物流轨迹(仅在查询到时展示) */} {trackList && trackList.length > 0 ? ( 物流详情 {/* 竖线 */} {trackList.map((item, idx) => ( {/* 圆点 */} {item.isCompleted && idx !== 0 ? ( ) : !item.isCompleted ? ( ) : null} {/* 内容 */} {item.status} {formatTime(item.time)} {item.description} {item.location} ))} ) : null} {/* 当前状态(仅在查询到 logisticsInfo 时展示) */} {logisticsInfo ? ( {statusInfo?.icon} {logisticsInfo.status} {logisticsInfo.currentLocation ? ( 当前位于: {logisticsInfo.currentLocation} ) : null} 更新时间: {formatTime(logisticsInfo.updateTime)} ) : null} {/* 温馨提示 */} 温馨提示 1. 快递在运输过程中可能存在延迟,请耐心等待{'\n'} 2. 如有疑问可联系快递公司客服{'\n'} 3. 签收前请检查包裹是否完好 {/* 底部操作 */} ) } export default LogisticsPage