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']; $masterId = (int)$order['master_id']; Db::startTrans(); try { // 1. 退回待接单状态(公海接单大厅) Db::name('order')->where('id', $orderId)->update([ 'status' => OrderStatus::PENDING_ACCEPT, 'master_id' => 0, 'accept_time' => 0, 'updatetime' => time(), ]); // 2. 插入订单状态变迁日志 Db::name('order_log')->insert([ 'order_id' => $orderId, 'from_status'=> OrderStatus::ACCEPTED, 'to_status' => OrderStatus::PENDING_ACCEPT, 'remark' => '师傅接单后超2小时未联系客户,系统自动退回公海大厅', 'operator' => 'system', 'op_id' => 0, 'createtime' => time(), ]); // 3. 对原接单师傅扣减信用分(扣 2 分)与推送警告 if ($masterId > 0) { $master = Db::name('master')->where('id', $masterId)->lock(true)->find(); if ($master) { $newScore = max(0, (float)$master['credit_score'] - 2.0); Db::name('master')->where('id', $masterId)->update([ 'credit_score' => $newScore, 'updatetime' => time(), ]); // 记录信誉流水表(如表存在) if (Db::query("SHOW TABLES LIKE '%master_credit_log%'")) { Db::name('master_credit_log')->insert([ 'master_id' => $masterId, 'type' => 'contact_timeout', 'score' => -2.0, 'balance' => $newScore, 'order_id' => $orderId, 'remark' => '接单后超2小时未首联,违规扣除信誉分', 'createtime' => time(), ]); } // 给师傅发送通知 Db::name('message')->insert([ 'user_type' => 'master', 'user_id' => (int)$master['user_id'], 'title' => '接单超时退单警告', 'content' => "订单 {$order['order_no']} 因超过2小时未联系客户,已被系统回收退回公海,扣除信誉分 2 分", 'type' => 'order', 'target_id' => $orderId, 'is_read' => 0, 'createtime' => time(), ]); } } Db::commit(); $recycled++; $output->writeln(" [OK] 订单 #{$orderId} ({$order['order_no']}) 超时退单成功,已重置回公海大厅"); } catch (\Exception $e) { Db::rollback(); $output->writeln(" [FAIL] 订单 #{$orderId} 超时退单失败: " . $e->getMessage()); } } $output->writeln("[OrderRecycle] 执行结束,成功回收 {$recycled} 笔"); } }