251 行
9.4 KiB
PHP
251 行
9.4 KiB
PHP
<?php
|
||
namespace Cli\Controller;
|
||
use Think\Controller;
|
||
use Common\Business\OrderSyncService;
|
||
|
||
/**
|
||
* 订单同步定时任务控制器
|
||
* 用于定时同步骑手订单状态到原始订单系统
|
||
*
|
||
* 使用方法:
|
||
* CLI模式:php index.php /Cli/OrderSync/syncRiderOrderStatus
|
||
* Cron示例:* * * * * cd /path/to/project && php index.php /Cli/OrderSync/syncRiderOrderStatus
|
||
*/
|
||
class OrderSyncController extends Controller {
|
||
|
||
/**
|
||
* 同步骑手订单状态到原始订单
|
||
* 当骑手接单后,修改原始订单状态为发货
|
||
* 当骑手配送完成后,修改原始订单状态为完成
|
||
*/
|
||
public function syncRiderOrderStatus() {
|
||
$startTime = microtime(true);
|
||
echo "===== 订单状态同步任务开始 =====\n";
|
||
echo "开始时间:" . date('Y-m-d H:i:s') . "\n\n";
|
||
|
||
try {
|
||
// 1. 检查是否启用自动同步
|
||
if (!$this->isAutoSyncEnabled()) {
|
||
echo "自动同步未启用,任务终止\n";
|
||
$this->log('自动同步未启用,任务终止');
|
||
return;
|
||
}
|
||
|
||
echo "自动同步已启用,开始执行...\n\n";
|
||
|
||
// 2. 同步骑手接单状态(将原始订单状态改为发货)
|
||
$acceptResult = $this->syncAcceptedOrders();
|
||
echo "接单状态同步:成功 {$acceptResult['success']} 个,失败 {$acceptResult['fail']} 个\n";
|
||
|
||
// 注意:骑手配送完成状态的同步已移至骑手端完成订单接口中实时同步
|
||
|
||
// 3. 输出总结
|
||
$totalSuccess = $acceptResult['success'];
|
||
$totalFail = $acceptResult['fail'];
|
||
|
||
echo "\n===== 同步任务完成 =====\n";
|
||
echo "总计:成功 {$totalSuccess} 个,失败 {$totalFail} 个\n";
|
||
echo "耗时:" . round(microtime(true) - $startTime, 2) . " 秒\n";
|
||
echo "结束时间:" . date('Y-m-d H:i:s') . "\n";
|
||
|
||
// 记录日志
|
||
$this->log("同步任务完成,成功 {$totalSuccess} 个,失败 {$totalFail} 个");
|
||
|
||
} catch (\Exception $e) {
|
||
echo "错误:" . $e->getMessage() . "\n";
|
||
echo "堆栈:" . $e->getTraceAsString() . "\n";
|
||
$this->log('同步任务异常:' . $e->getMessage());
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 检查是否启用自动同步
|
||
* @return bool
|
||
*/
|
||
private function isAutoSyncEnabled() {
|
||
$config = M('rider_config')->where(array('merchant_id' => 0))->find();
|
||
if (!$config) {
|
||
// 如果没有配置,尝试获取任意一个商户的配置
|
||
$config = M('rider_config')->where(array('auto_sync_enabled' => 1))->find();
|
||
}
|
||
return $config && $config['auto_sync_enabled'] == 1;
|
||
}
|
||
|
||
/**
|
||
* 同步骑手接单状态
|
||
* 将原始订单状态更新为发货(status=2)
|
||
*
|
||
* @return array 统计结果
|
||
*/
|
||
private function syncAcceptedOrders() {
|
||
$successCount = 0;
|
||
$failCount = 0;
|
||
|
||
// 查询已接单但原订单未发货的骑手订单
|
||
$where = array();
|
||
$where['ro.order_status'] = array('in', array(1, 2, 3, 4, 5)); // 已接单到配送中的状态
|
||
$where['o.status'] = 1; // 原订单状态为未发货
|
||
|
||
$orders = M('rider_order')->alias('ro')
|
||
->join('LEFT JOIN ls_retail_bill_online o ON ro.bill_id = o.bill_id')
|
||
->where($where)
|
||
->field('ro.id as rider_order_id, ro.bill_id, ro.order_status, ro.rider_id, o.status as original_status')
|
||
->select();
|
||
|
||
if (empty($orders)) {
|
||
echo "没有需要同步的接单订单\n";
|
||
return array('success' => 0, 'fail' => 0);
|
||
}
|
||
|
||
echo "找到 " . count($orders) . " 个待同步的接单订单\n";
|
||
|
||
foreach ($orders as $order) {
|
||
try {
|
||
// 更新原始订单状态为发货(status=2)
|
||
$result = M('retail_bill_online')->where(array('bill_id' => $order['bill_id']))->save(array(
|
||
'status' => 2,
|
||
'send_time' => date('Y-m-d H:i:s')
|
||
));
|
||
|
||
if ($result !== false) {
|
||
$successCount++;
|
||
echo " ✓ 订单 {$order['bill_id']} 状态已更新为发货\n";
|
||
|
||
// 记录同步日志
|
||
$this->logSyncStatus(
|
||
$order['bill_id'],
|
||
$order['rider_order_id'],
|
||
$order['rider_id'],
|
||
'accept',
|
||
$order['original_status'],
|
||
2,
|
||
1,
|
||
''
|
||
);
|
||
} else {
|
||
$failCount++;
|
||
echo " ✗ 订单 {$order['bill_id']} 状态更新失败\n";
|
||
|
||
$this->logSyncStatus(
|
||
$order['bill_id'],
|
||
$order['rider_order_id'],
|
||
$order['rider_id'],
|
||
'accept',
|
||
$order['original_status'],
|
||
2,
|
||
0,
|
||
'数据库更新失败'
|
||
);
|
||
}
|
||
|
||
} catch (\Exception $e) {
|
||
$failCount++;
|
||
echo " ✗ 订单 {$order['bill_id']} 处理异常:{$e->getMessage()}\n";
|
||
|
||
$this->logSyncStatus(
|
||
$order['bill_id'],
|
||
$order['rider_order_id'],
|
||
$order['rider_id'],
|
||
'accept',
|
||
$order['original_status'],
|
||
2,
|
||
0,
|
||
$e->getMessage()
|
||
);
|
||
}
|
||
}
|
||
|
||
return array('success' => $successCount, 'fail' => $failCount);
|
||
}
|
||
|
||
/**
|
||
* 记录同步状态日志
|
||
*
|
||
* @param int $billId 原订单ID
|
||
* @param int $riderOrderId 骑手订单ID
|
||
* @param int $riderId 骑手ID
|
||
* @param string $operationType 操作类型
|
||
* @param int $oldStatus 原状态
|
||
* @param int $newStatus 新状态
|
||
* @param int $syncResult 同步结果
|
||
* @param string $errorMsg 错误信息
|
||
*/
|
||
private function logSyncStatus($billId, $riderOrderId, $riderId, $operationType, $oldStatus, $newStatus, $syncResult, $errorMsg = '') {
|
||
$now = date('Y-m-d H:i:s');
|
||
|
||
$logData = array(
|
||
'bill_id' => intval($billId),
|
||
'rider_order_id' => intval($riderOrderId),
|
||
'rider_id' => intval($riderId),
|
||
'operation_type' => $operationType,
|
||
'old_status' => intval($oldStatus),
|
||
'new_status' => intval($newStatus),
|
||
'sync_result' => intval($syncResult),
|
||
'error_msg' => $errorMsg ? $errorMsg : null,
|
||
'sync_time' => $now,
|
||
'retry_count' => 0,
|
||
'add_time' => $now,
|
||
'update_time' => $now,
|
||
);
|
||
|
||
M('rider_order_sync_log')->add($logData);
|
||
}
|
||
|
||
/**
|
||
* 记录运行日志到文件
|
||
*
|
||
* @param string $message 日志消息
|
||
*/
|
||
private function log($message) {
|
||
$logFile = RUNTIME_PATH . 'Logs/OrderSync/' . date('Y-m-d') . '.log';
|
||
$logDir = dirname($logFile);
|
||
|
||
if (!is_dir($logDir)) {
|
||
mkdir($logDir, 0755, true);
|
||
}
|
||
|
||
$logContent = '[' . date('Y-m-d H:i:s') . '] ' . $message . "\n";
|
||
file_put_contents($logFile, $logContent, FILE_APPEND);
|
||
}
|
||
|
||
/**
|
||
* 手动触发批量同步(供管理员使用)
|
||
* 用于将原始订单同步创建为骑手订单
|
||
*/
|
||
public function batchSync() {
|
||
echo "===== 批量订单同步任务开始 =====\n";
|
||
echo "开始时间:" . date('Y-m-d H:i:s') . "\n\n";
|
||
|
||
try {
|
||
$syncService = new OrderSyncService();
|
||
$result = $syncService->batchSyncOrders();
|
||
|
||
if ($result['success']) {
|
||
echo "同步成功:{$result['message']}\n";
|
||
echo "详细信息:\n";
|
||
echo " 成功:{$result['details']['success_count']} 个\n";
|
||
echo " 失败:{$result['details']['fail_count']} 个\n";
|
||
echo " 跳过:{$result['details']['skip_count']} 个\n";
|
||
|
||
if (!empty($result['details']['errors'])) {
|
||
echo "\n错误列表:\n";
|
||
foreach ($result['details']['errors'] as $error) {
|
||
echo " - {$error}\n";
|
||
}
|
||
}
|
||
} else {
|
||
echo "同步失败:{$result['message']}\n";
|
||
}
|
||
|
||
$this->log("批量同步完成:{$result['message']}");
|
||
|
||
} catch (\Exception $e) {
|
||
echo "错误:" . $e->getMessage() . "\n";
|
||
$this->log('批量同步异常:' . $e->getMessage());
|
||
}
|
||
|
||
echo "\n结束时间:" . date('Y-m-d H:i:s') . "\n";
|
||
}
|
||
}
|
||
|