6.7 KiB
6.7 KiB
物流追踪系统同步完成报告
问题分析
用户疑问
"定时任务找不到快递单号,明明订单里有快递单号"
根本原因
定时任务查询的是 zyt_express_tracking 表(物流追踪表),而不是 zyt_tcm_prescription_order 表(订单表)。
这两个表是分离的:
- 订单表:存储业务订单信息,包括快递单号
- 物流追踪表:专门存储物流追踪信息和轨迹历史
需要将订单表中的快递单号同步到物流追踪表,定时任务才能找到并更新。
解决方案
1. 创建同步命令
创建了 SyncTrackingNumbers 命令,用于将订单表中的快递单号同步到物流追踪表。
文件:server/app/command/SyncTrackingNumbers.php
使用方法:
php think express:sync
2. 注册命令
在 server/config/console.php 中注册了两个命令:
'commands' => [
'express:auto-update' => 'app\\command\\ExpressAutoUpdate', // 自动更新
'express:sync' => 'app\\command\\SyncTrackingNumbers', // 同步快递单号
],
3. 执行同步
$ php think express:sync
开始同步现有订单快递单号...
找到 1 个有快递单号的订单
跳过: JD0230761381812 (已存在)
========================================
同步完成!
========================================
总数: 1
成功: 0
跳过: 1
失败: 0
耗时: 0.28秒
当前状态
物流追踪记录状态
快递单号: JD0230761381812
快递公司: auto
当前状态: 3 - 已签收
是否签收: 是
自动更新: 禁用
下次更新时间: 1970-01-01 08:00:00 (0)
当前时间: 2026-04-07 17:12:50
是否应该更新: 否
不更新原因: 自动更新未启用 已签收 状态为终态
为什么定时任务总数为0?
答案:这是正常的!
这个快递单号已经是"已签收"状态(state=3),系统自动:
- 停止了自动更新(
auto_update = 0) - 标记为已签收(
is_signed = 1) - 状态为终态(state = 3)
定时任务的过滤条件:
$list = ExpressTracking::where('auto_update', 1) // ✗ 当前为0
->where('next_update_time', '<=', $now) // ✗ 当前为0
->where('is_signed', 0) // ✗ 当前为1
->whereNotIn('current_state', [3, 4, 5]) // ✗ 当前为3
->whereNull('delete_time')
->limit($limit)
->select();
所有条件都不满足,所以不会被查询到。这是设计的预期行为,避免浪费查询次数。
工作流程
新订单的物流追踪流程
-
订单创建/编辑时
ExpressTrackingService::createOrUpdate([ 'order_id' => $orderId, 'order_type' => 'prescription', 'tracking_number' => $trackingNumber, 'express_company' => $expressCompany, 'recipient_phone' => $phone, 'recipient_name' => $name, 'recipient_address' => $address, ]);- 创建物流追踪记录
- 立即查询一次物流信息
- 设置
auto_update = 1(启用自动更新) - 设置
next_update_time = now(立即更新)
-
定时任务自动更新
php think express:auto-update- 每10分钟执行一次
- 只查询未签收的订单
- 更新物流信息和轨迹
- 检测状态变更
-
签收后自动停止
- 检测到签收状态(state=3)
- 设置
is_signed = 1 - 设置
auto_update = 0(停止自动更新) - 记录签收时间
现有订单的同步
对于已有的订单(如当前的 JD0230761381812),需要手动同步:
# 同步现有订单快递单号
php think express:sync
# 同步后会立即查询一次物流信息
# 如果已签收,会自动停止更新
测试验证
1. 检查物流追踪记录
php check_tracking_status.php
2. 测试同步命令
php think express:sync
3. 测试自动更新
php think express:auto-update
4. 查看日志
tail -f runtime/log/202X-XX-XX.log
下一步操作
1. 集成到订单系统
在订单创建/编辑的控制器或逻辑层中添加:
文件:server/app/adminapi/logic/tcm/PrescriptionOrderLogic.php
use app\common\service\ExpressTrackingService;
// 在保存订单后
if (!empty($params['tracking_number'])) {
ExpressTrackingService::createOrUpdate([
'order_id' => $orderId,
'order_type' => 'prescription',
'tracking_number' => $params['tracking_number'],
'express_company' => $params['express_company'] ?? 'auto',
'recipient_phone' => $params['recipient_phone'],
'recipient_name' => $params['recipient_name'],
'recipient_address' => $params['shipping_address'],
]);
}
2. 配置定时任务
Windows(任务计划程序)
schtasks /create /tn "ExpressAutoUpdate" /tr "php D:\web\zyt\server\think express:auto-update" /sc minute /mo 10
Linux(crontab)
crontab -e
# 添加以下行
0,10,20,30,40,50 * * * * cd /path/to/server && php think express:auto-update >> /dev/null 2>&1
3. 测试新订单
- 创建一个新订单,填写快递单号
- 检查
zyt_express_tracking表是否自动创建记录 - 等待10分钟,查看是否自动更新
- 查看
zyt_express_trace表是否有轨迹记录
相关文件
核心文件
server/app/common/service/ExpressTrackingService.php- 物流追踪服务server/app/command/ExpressAutoUpdate.php- 自动更新命令server/app/command/SyncTrackingNumbers.php- 同步命令server/config/console.php- 命令注册
数据库
server/database/migrations/create_express_tracking_tables.sql- 创建表server/database/migrations/sync_existing_tracking_numbers.sql- 同步SQL
工具脚本
server/install_tracking_tables.php- 安装表server/check_tracking_status.php- 检查状态
文档
EXPRESS_TRACKING_SYSTEM.md- 系统架构EXPRESS_TRACKING_QUICKSTART.md- 快速开始EXPRESS_TRACKING_FIXES.md- 修复记录EXPRESS_TRACKING_COMMAND_FIX.md- 命令修复EXPRESS_TRACKING_SYNC_COMPLETE.md- 本文档
总结
✅ 问题已解决:订单表和物流追踪表已同步
✅ 定时任务正常工作:正确过滤已签收订单
✅ 自动停止机制:签收后自动停止更新,节省查询次数
✅ 同步命令可用:php think express:sync
✅ 自动更新命令可用:php think express:auto-update
当前状态:系统已就绪,等待新订单测试。现有订单(JD0230761381812)已签收,不会再更新。
建议:
- 在订单创建/编辑时集成
ExpressTrackingService::createOrUpdate() - 配置定时任务(每10分钟执行一次)
- 创建一个新的未签收订单进行完整测试