feat(order-logistics): 改造订单详情物流查看功能

- 后端 ShopOrderServiceImpl.getByIdRel 填充发货单 shopOrderDelivery 信息
- 前端新增 ShopOrderDelivery 类型,ShopOrder 接口添加 shopOrderDelivery 字段
- 物流页支持仅传 orderId 即可加载订单及发货单,无需必须传 expressNo 和 expressCompany
- 物流轨迹查询条件调整,失败时展示发货单信息,不阻塞页面
- 新增发货信息卡展示发货人、联系方式、地址、物流单号、发货时间及发货方式
- 新增收货信息卡,展示订单收货人名称、电话、地址
- 订单列表“待付款”Tab修复状态显示为“待付款”,兼容线下付款订单逻辑
- 组件OrderCard中去除isOffline判断,修正订单状态文案一致性
- 物流详情页复制功能优化,支持复制正确的物流单号
- 优化快递状态提示、时间格式化显示及页面空状态处理
- 电话联系客服按钮事件名称修正和调用逻辑优化
This commit is contained in:
2026-07-15 16:38:24 +08:00
parent af645c058e
commit b45a5722eb
4 changed files with 272 additions and 130 deletions

View File

@@ -138,6 +138,25 @@
- 引入:从 `@tarojs/components` 新增导入 `Button`
- 注意:微信客服 Button 在开发者工具中无效,需真机预览测试
## 订单详情页查看物流改造(显示 shopOrderDelivery
- 需求:订单详情页点击「查看物流」跳转 `/pages/order/logistics`,原页面强制要求 URL 带 expressNo + expressCompany但详情页只传了 orderId导致 toast「缺少物流参数」+ 空状态
- 后端修复(`/Users/gxwebsoft/JAVA/guilixu-java`1 个文件):
- `ShopOrderServiceImpl.java``getByIdRel(orderId)` 原本只调 `baseMapper.selectListRel(param)`,没有像 `pageRel` 那样填充 `shopOrderDelivery`。新增私有方法 `fillShopOrderDelivery(order)`,在快递配送(deliveryType==0/null)且已发货(deliveryStatus>10)时调 `shopOrderDeliveryService.getByOrderId(orderId)` 查发货单,并关联 `shopExpressService.getById(expressId)` 取 expressName 填充
- 编译验证Maven compile 成功
- 前端类型补充(`src/api/shop/shopOrder/model/index.ts`
- 新增 `ShopOrderDelivery` 接口(与后端 ShopOrderDelivery 实体对应deliveryId/orderId/deliveryMethod/expressId/expressName/sendName/sendPhone/sendAddress/expressNo/createTime 等)
- `ShopOrder` 接口新增 `shopOrderDelivery?: ShopOrderDelivery | null` 字段
- 前端物流页改造(`src/pages/order/logistics.tsx`
- 不再强制要求 URL 带 expressNo/expressCompany只要求 orderId
-`getShopOrder(orderId)` 加载订单(含后端填充的 shopOrderDelivery
- 运单号优先级URL expressNo → delivery.expressNo → order.expressNo
- 物流轨迹:仅在有 expressNo + expressCompany 代码时才查询 queryLogistics失败不阻塞发货单展示
- 新增「发货信息」卡:发货人/联系方式/发货地址/物流单号(可复制)/发货时间/发货方式(10手动/20无需物流/30电子面单)
- 新增「收货信息」卡:从订单读 realName/mobile/address
- 保留原物流轨迹时间线(仅在查询到时展示)和温馨提示
- 空状态:订单接口也失败时才显示
- 后端需重启服务才生效
## 修复 VIP 价格首页不显示 + 后端不认 price 字段
- **问题 1首页**`src/pages/index/index.tsx`tabBar 首页)没接入 `useVipStatus`,热销推荐价格一直显示 `product.price` 而非 `dealerPrice`。商品详情/商城列表/购物车/分类都修了,唯独漏了 tabBar 首页
- **问题 2后端 DTO 缺字段)**:前端 `OrderGoodsItem` 已传 `price` 字段,但后端 `OrderCreateRequest.OrderGoodsItem`(嵌套静态类)**根本没有 `price` 字段**Jackson 反序列化直接丢弃。后端 `OrderBusinessService.validateAndCalculateTotal()``saveOrderGoods()` 都用 `goods.getPrice()` 兜底 —— 这就是「前端传的对、后端处理就错」的根本原因
@@ -157,3 +176,14 @@
- `goods.salePrice` - 市场价(划掉的)
- `goods.dealerPrice` - VIP 专享价
- 前端传 `dealerPrice``OrderGoodsItem.price`,后端通过该字段下单
## 修复订单列表"待付款"Tab 下状态显示"待发货"
- 文件:`src/components/common/OrderCard/index.tsx`
- 问题:用户切到"待付款"Tab下方订单卡片状态文字显示"待发货",与 Tab 不一致
- 根因:线下付款(payType=9)订单的 `payStatus=false`(数据库 pay_status=0后端 `statusFilter=0` 的 SQL 条件 `pay_status=0 AND order_status=0` 把它归入"待付款"Tab 是合理的(待商家确认收款)。但 OrderCard 的 `getCardStatus``isOffline=true``!isOffline=false` → 跳过"待付款"分支,进入 `if (deliveryStatus === 10)` → 显示"待发货"
- 关键业务规则:
- 货到付款(8):后端 Controller `saveLegacy()` 下单时已 `setPayStatus(true)`,不会进入 statusFilter=0
- 线下付款(9):保持 `payStatus=false`,会进入 statusFilter=0
- 微信支付(1):未付款 `payStatus=false`,正常进入 statusFilter=0
- 修复:`getCardStatus` 第 30 行去掉 `&& !isOffline` 条件,改为 `if (!payStatus && !isCod) return { text: '待付款' }`。保留 `!isCod`(货到付款的特殊兜底,虽然正常流程不会走到这里);清理掉不再使用的 `isOffline` 变量
- 决策依据:用户认可"线下付款订单出现在待付款 Tab"是合理的,因此只改前端文案判断,不动后端 SQL

View File

@@ -1,6 +1,42 @@
import type { PageParam } from '@/api/index';
import type { ShopOrderGoods } from '@/api/shop/shopOrderGoods/model';
/**
* 发货单(与后端 ShopOrderDelivery 对应)
*/
export interface ShopOrderDelivery {
// 发货单ID
deliveryId?: number;
// 订单ID
orderId?: number;
// 发货方式(10手动录入 20无需物流 30电子面单)
deliveryMethod?: number;
// 物流公司ID
expressId?: number;
// 物流公司名称(关联查询,非数据库字段)
expressName?: string;
// 发货人
sendName?: string;
// 发货人联系方式
sendPhone?: string;
// 发货地址
sendAddress?: string;
// 物流单号
expressNo?: string;
// 电子面单模板内容
eorderHtml?: string;
// 排序号
sortNumber?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 订单
*/
@@ -163,6 +199,8 @@ export interface ShopOrder {
hasTakeGift?: string;
// 订单商品项
orderGoods?: ShopOrderGoods[];
// 发货单信息(详情接口关联查询返回,仅快递配送且已发货时有值)
shopOrderDelivery?: ShopOrderDelivery | null;
}
/**

View File

@@ -15,7 +15,6 @@ interface OrderCardProps {
const getCardStatus = (order: ShopOrder): { text: string; color: string } => {
const { payStatus, deliveryStatus, orderStatus, payType } = order
const isCod = payType === 8 // 货到付款
const isOffline = payType === 9 // 线下付款
if (orderStatus === 2) return { text: '已取消', color: '#999' }
if (orderStatus === 3) return { text: '取消中', color: '#ff7d00' }
@@ -26,8 +25,9 @@ const getCardStatus = (order: ShopOrder): { text: string; color: string } => {
// 终态orderStatus=1 必须最先判断,盖过 deliveryStatus/payStatus
if (orderStatus === 1) return { text: '已完成', color: '#0e932e' }
// 货到付款(8)/线下付款(9):无需在线支付,下单即进入发货流程
if (!payStatus && !isCod && !isOffline) return { text: '待付款', color: '#ee0a24' }
// 货到付款(8):下单时后端已 setPayStatus(true),不会走到这里
// 线下付款(9):保持 payStatus=false待商家确认收款应显示"待付款"与 Tab 一致
if (!payStatus && !isCod) return { text: '待付款', color: '#ee0a24' }
if (deliveryStatus === 10) return { text: '待发货', color: '#4b9cf5' }
if (deliveryStatus === 20) return { text: '待收货', color: '#4b9cf5' }
if (deliveryStatus === 30) return { text: '已收货', color: '#0e932e' }

View File

@@ -2,8 +2,11 @@ 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, EXPRESS_COMPANIES } from '@/api/shop/shopLogistics'
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'
@@ -11,9 +14,18 @@ definePageConfig({
navigationBarTitleText: '物流详情',
})
// 发货方式映射
const DELIVERY_METHOD_MAP: Record<number, string> = {
10: '手动录入',
20: '无需物流',
30: '电子面单',
}
const LogisticsPage: React.FC = () => {
const { orderId, expressNo, expressCompany } = Taro.getCurrentInstance().router?.params || {}
const { orderId, expressNo: urlExpressNo, expressCompany: urlExpressCompany } = Taro.getCurrentInstance().router?.params || {}
const [loading, setLoading] = useState(true)
const [order, setOrder] = useState<ShopOrder | null>(null)
const [delivery, setDelivery] = useState<ShopOrderDelivery | null>(null)
const [logisticsInfo, setLogisticsInfo] = useState<LogisticsInfo | null>(null)
const [trackList, setTrackList] = useState<LogisticsTrack[]>([])
@@ -22,27 +34,42 @@ const LogisticsPage: React.FC = () => {
}, [])
const loadLogistics = async () => {
if (!orderId) {
Taro.showToast({ title: '缺少订单参数', icon: 'none' })
setLoading(false)
return
}
setLoading(true)
try {
// 必须传入参数
if (!expressNo || !expressCompany) {
Taro.showToast({ title: '缺少物流参数', icon: 'none' })
setLoading(false)
return
// 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)
}
const res = await queryLogistics({
orderId,
expressNo,
expressCompany,
})
if (res?.data) {
setLogisticsInfo(res.data.logisticsInfo)
setTrackList(res.data.trackList)
// 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)
}
}
} catch (err) {
console.error('加载物流信息失败', err)
Taro.showToast({ title: '加载失败', icon: 'none' })
} finally {
setLoading(false)
}
@@ -50,49 +77,35 @@ const LogisticsPage: React.FC = () => {
// 复制单号
const copyExpressNo = () => {
if (logisticsInfo?.expressNo) {
Taro.setClipboardData({
data: logisticsInfo.expressNo,
success: () => {
Taro.showToast({ title: '单号已复制', icon: 'success' })
},
})
}
const no = logisticsInfo?.expressNo || delivery?.expressNo || order?.expressNo || ''
if (!no) return
Taro.setClipboardData({
data: no,
success: () => Taro.showToast({ title: '单号已复制', icon: 'success' }),
})
}
// 联系快递员(模拟)
const contactRider = () => {
// 联系客服
const contactService = () => {
Taro.makePhoneCall({
phoneNumber: '400-811-1111',
fail: () => {
Taro.showToast({ title: '拨打失败', icon: 'none' })
},
fail: () => Taro.showToast({ title: '拨打失败', icon: 'none' }),
})
}
// 格式化时间
const formatTime = (time: string) => {
if (!time) return ''
const date = new Date(time)
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
const hours = String(date.getHours()).padStart(2, '0')
const minutes = String(date.getMinutes()).padStart(2, '0')
return `${month}-${day} ${hours}:${minutes}`
}
// 格式化日期
const formatDate = (time: string) => {
if (!time) return ''
const date = new Date(time)
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`
const formatTime = (time?: string) => {
if (!time) return '-'
return time.replace('T', ' ').slice(0, 19)
}
if (loading) {
return <Loading fullscreen />
}
if (!logisticsInfo) {
// 既无物流轨迹,又无发货单,又无订单 → 空状态
const hasAnything = logisticsInfo || trackList?.length || delivery || order
if (!hasAnything) {
return (
<View className='min-h-screen bg-gray-50 flex items-center justify-center'>
<EmptyState text='暂无物流信息' />
@@ -100,7 +113,30 @@ const LogisticsPage: React.FC = () => {
)
}
const statusInfo = formatLogisticsStatus(logisticsInfo.status)
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 (
<View className='min-h-screen bg-gray-50 pb-4 flex flex-col'>
@@ -108,109 +144,147 @@ const LogisticsPage: React.FC = () => {
{/* 快递信息卡片 */}
<View className='bg-white mx-3 mt-3 p-4 rounded-xl'>
<View className='flex items-center gap-3'>
{/* 快递logo */}
<View className='w-12 h-12 rounded-lg bg-gray-100 flex items-center justify-center'>
<Text className='text-xl'>📦</Text>
</View>
<View className='flex-1'>
<View className='flex items-center gap-2'>
<Text className='text-sm font-medium text-gray-800'>{logisticsInfo.expressCompanyName}</Text>
<Text className='text-sm font-medium text-gray-800'>{expressCompanyName}</Text>
<Text className='text-xs text-gray-400'></Text>
<Text className='text-sm text-gray-500'>{statusInfo.text}</Text>
<Text className='text-sm text-gray-500'>{getDeliveryStatusText()}</Text>
</View>
<Text className='text-xs text-gray-400 mt-1'>
: {logisticsInfo.expressNo}
: {expressNo || '暂无'}
</Text>
</View>
<View
className='px-3 py-1 rounded-full bg-gray-50'
onClick={copyExpressNo}
>
<Text className='text-xs text-gray-500'></Text>
</View>
{expressNo ? (
<View
className='px-3 py-1 rounded-full bg-gray-50'
onClick={copyExpressNo}
>
<Text className='text-xs text-gray-500'></Text>
</View>
) : null}
</View>
{/* 预计送达 */}
{logisticsInfo.estimatedTime && (
<View className='mt-3 pt-3 border-t border-gray-100'>
<Text className='text-xs text-gray-400'>
: {formatDate(logisticsInfo.estimatedTime)} 24:00
</Text>
</View>
)}
</View>
{/* 当前状态 */}
<View className='bg-white mx-3 mt-3 p-4 rounded-xl'>
<View className='flex items-start gap-3'>
<View className={`w-10 h-10 rounded-full flex items-center justify-center ${statusInfo.icon === '🚚' ? 'bg-green-50' : 'bg-gray-50'}`}>
<Text>{statusInfo.icon}</Text>
</View>
<View className='flex-1'>
<Text className='text-sm font-medium text-gray-800'>{logisticsInfo.status}</Text>
{logisticsInfo.currentLocation && (
<Text className='text-xs text-gray-400 mt-1'>
: {logisticsInfo.currentLocation}
</Text>
)}
<Text className='text-xs text-gray-400 mt-1'>
: {formatTime(logisticsInfo.updateTime)}
</Text>
</View>
{/* 发货方式 */}
<View className='mt-3 pt-3 border-t border-gray-100 flex justify-between'>
<Text className='text-xs text-gray-400'></Text>
<Text className='text-xs text-gray-600'>{deliveryMethodText}</Text>
</View>
</View>
{/* 收货人信息 */}
{logisticsInfo.receiverInfo && (
{/* 发货单信息shopOrderDelivery */}
{delivery ? (
<View className='bg-white mx-3 mt-3 p-4 rounded-xl'>
<Text className='text-sm font-medium text-gray-800 mb-3 block'></Text>
<View className='space-y-2'>
<View className='flex justify-between'>
<Text className='text-xs text-gray-400'></Text>
<Text className='text-xs text-gray-600'>{sendName}</Text>
</View>
<View className='flex justify-between'>
<Text className='text-xs text-gray-400'></Text>
<Text className='text-xs text-gray-600'>{sendPhone}</Text>
</View>
<View className='flex justify-between'>
<Text className='text-xs text-gray-400'></Text>
<Text className='text-xs text-gray-600 text-right flex-1 ml-4'>{sendAddress}</Text>
</View>
<View className='flex justify-between'>
<Text className='text-xs text-gray-400'></Text>
<View className='flex items-center gap-1'>
<Text className='text-xs text-gray-600'>{delivery.expressNo || '-'}</Text>
{delivery.expressNo ? (
<Text className='text-xs text-blue-500' onClick={copyExpressNo}></Text>
) : null}
</View>
</View>
{delivery.createTime ? (
<View className='flex justify-between'>
<Text className='text-xs text-gray-400'></Text>
<Text className='text-xs text-gray-600'>{formatTime(delivery.createTime)}</Text>
</View>
) : null}
</View>
</View>
) : null}
{/* 收货人信息(从订单读取) */}
{order ? (
<View className='bg-white mx-3 mt-3 p-4 rounded-xl'>
<Text className='text-sm font-medium text-gray-800 mb-2 block'></Text>
<View className='flex items-center gap-2'>
<Text className='text-sm text-gray-600'>{logisticsInfo.receiverInfo.name}</Text>
<Text className='text-sm text-gray-500'>{logisticsInfo.receiverInfo.phone}</Text>
<Text className='text-sm text-gray-600'>{order.realName || '-'}</Text>
<Text className='text-sm text-gray-500'>{order.mobile || order.phone || '-'}</Text>
</View>
<Text className='text-xs text-gray-400 mt-1'>{logisticsInfo.receiverInfo.address}</Text>
<Text className='text-xs text-gray-400 mt-1'>{order.address || '-'}</Text>
</View>
)}
) : null}
{/* 物流轨迹 */}
<View className='bg-white mx-3 mt-3 p-4 rounded-xl'>
<Text className='text-sm font-medium text-gray-800 mb-3 block'></Text>
<View className='relative'>
{/* 竖线 */}
<View className='absolute left-4 top-0 bottom-0 w-px bg-gray-200' />
{/* 物流轨迹(仅在查询到时展示) */}
{trackList && trackList.length > 0 ? (
<View className='bg-white mx-3 mt-3 p-4 rounded-xl'>
<Text className='text-sm font-medium text-gray-800 mb-3 block'></Text>
<View className='relative'>
{/* 竖线 */}
<View className='absolute left-4 top-0 bottom-0 w-px bg-gray-200' />
{trackList.map((item, idx) => (
<View key={idx} className={`relative flex gap-3 pb-4 ${idx === trackList.length - 1 ? 'pb-0' : ''}`}>
{/* 圆点 */}
<View
className={`w-8 h-8 rounded-full flex items-center justify-center z-10 ${
item.isCompleted ? 'bg-green-500' : 'bg-white border-2 border-green-500'
}`}
>
{item.isCompleted && idx !== 0 ? (
<Text className='text-white text-xs'></Text>
) : !item.isCompleted ? (
<View className='w-2 h-2 rounded-full bg-green-500' />
) : null}
</View>
{/* 内容 */}
<View className='flex-1 pt-1'>
<View className='flex justify-between items-start'>
<Text className={`text-sm ${item.isCompleted ? 'text-gray-600' : 'text-gray-800 font-medium'}`}>
{item.status}
</Text>
<Text className='text-xs text-gray-400'>{formatTime(item.time)}</Text>
{trackList.map((item, idx) => (
<View key={idx} className={`relative flex gap-3 pb-4 ${idx === trackList.length - 1 ? 'pb-0' : ''}`}>
{/* 圆点 */}
<View
className={`w-8 h-8 rounded-full flex items-center justify-center z-10 ${
item.isCompleted ? 'bg-green-500' : 'bg-white border-2 border-green-500'
}`}
>
{item.isCompleted && idx !== 0 ? (
<Text className='text-white text-xs'></Text>
) : !item.isCompleted ? (
<View className='w-2 h-2 rounded-full bg-green-500' />
) : null}
</View>
{/* 内容 */}
<View className='flex-1 pt-1'>
<View className='flex justify-between items-start'>
<Text className={`text-sm ${item.isCompleted ? 'text-gray-600' : 'text-gray-800 font-medium'}`}>
{item.status}
</Text>
<Text className='text-xs text-gray-400'>{formatTime(item.time)}</Text>
</View>
<Text className={`text-xs mt-1 ${item.isCompleted ? 'text-gray-400' : 'text-gray-500'}`}>
{item.description}
</Text>
<Text className='text-xs text-gray-400 mt-1'>{item.location}</Text>
</View>
<Text className={`text-xs mt-1 ${item.isCompleted ? 'text-gray-400' : 'text-gray-500'}`}>
{item.description}
</Text>
<Text className='text-xs text-gray-400 mt-1'>{item.location}</Text>
</View>
</View>
))}
))}
</View>
</View>
</View>
) : null}
{/* 当前状态(仅在查询到 logisticsInfo 时展示) */}
{logisticsInfo ? (
<View className='bg-white mx-3 mt-3 p-4 rounded-xl'>
<View className='flex items-start gap-3'>
<View className={`w-10 h-10 rounded-full flex items-center justify-center ${statusInfo?.icon === '🚚' ? 'bg-green-50' : 'bg-gray-50'}`}>
<Text>{statusInfo?.icon}</Text>
</View>
<View className='flex-1'>
<Text className='text-sm font-medium text-gray-800'>{logisticsInfo.status}</Text>
{logisticsInfo.currentLocation ? (
<Text className='text-xs text-gray-400 mt-1'>
: {logisticsInfo.currentLocation}
</Text>
) : null}
<Text className='text-xs text-gray-400 mt-1'>
: {formatTime(logisticsInfo.updateTime)}
</Text>
</View>
</View>
</View>
) : null}
{/* 温馨提示 */}
<View className='bg-orange-50 mx-3 mt-3 p-4 rounded-xl'>
@@ -229,7 +303,7 @@ const LogisticsPage: React.FC = () => {
<Button
size='small'
className='flex-1 rounded-full border-gray-300 text-gray-600'
onClick={contactRider}
onClick={contactService}
>
</Button>