setName('order:recycle') ->setDescription('回收接单超过2小时未首联打卡的超时工单'); } protected function execute(Input $input, Output $output) { // 阈值:当前时间倒推 2 小时 $threshold = time() - (2 * 3600); // 状态为已接单(3),且未首联打卡(contact_time 为 0 或 NULL),且接单时间超 2 小时 $orders = Db::name('order') ->where('status', OrderStatus::ACCEPTED) ->where(function ($query) { $query->whereNull('contact_time')->whereOr('contact_time', 0); }) ->where('accept_time', '>', 0) ->where('accept_time', '<=', $threshold) ->select(); $count = count($orders); $output->writeln("[OrderRecycle] 扫描到 {$count} 笔接单超2小时未首联工单"); $recycled = 0; foreach ($orders as $order) { $orderId = (int)$order['id']; $now = time(); Db::startTrans(); try { $lockedOrder = Db::name('order')->where('id', $orderId)->lock(true)->find(); if (!$lockedOrder || (int)$lockedOrder['status'] !== OrderStatus::ACCEPTED || !empty($lockedOrder['contact_time'])) { Db::rollback(); continue; } $masterId = (int)$lockedOrder['master_id']; $toStatus = $lockedOrder['price_type'] === 'quote' ? OrderStatus::QUOTING : OrderStatus::PENDING_ACCEPT; // 1. 退回待接单/报价中状态(公海接单大厅) Db::name('order')->where('id', $orderId)->update([ 'status' => $toStatus, 'master_id' => 0, 'accept_time' => null, 'updatetime' => $now, ]); if ($lockedOrder['price_type'] === 'quote') { Db::name('order_quote') ->where('order_id', $orderId) ->where('status', 'accept') ->update(['status' => 'wait']); } // 2. 插入订单状态变迁日志(严格对齐 fa_order_log 真实列名) Db::name('order_log')->insert([ 'order_id' => $orderId, 'status' => $toStatus, 'remark' => '师傅接单后超2小时未联系客户,系统自动退回公海大厅', 'operator_type' => 'system', 'operator_id' => 0, 'createtime' => $now, ]); // 3. 给原接单师傅发送超时退单警告通知(严格对齐 fa_message 真实列名,receive_id 传 fa_master.id) if ($masterId > 0) { $master = Db::name('master')->where('id', $masterId)->find(); if ($master) { Db::name('message')->insert([ 'receive_type' => 'master', 'receive_id' => (int)$master['id'], 'type' => 'order', 'title' => '接单超时退单警告', 'content' => "订单 {$lockedOrder['order_no']} 因超过2小时未联系客户,已被系统回收退回接单大厅", 'order_id' => $orderId, 'is_read' => 0, 'createtime' => $now, ]); } } Db::commit(); $recycled++; $output->writeln(" [OK] 订单 #{$orderId} ({$lockedOrder['order_no']}) 超时退单成功,已重置回公海大厅"); } catch (\Exception $e) { Db::rollback(); $output->writeln(" [FAIL] 订单 #{$orderId} 超时退单失败: " . $e->getMessage()); } } $output->writeln("[OrderRecycle] 执行结束,成功回收 {$recycled} 笔"); } }