where('name', 'org_ai_send') ->value('id'); $orgIds = Db::name('config_org') ->where('config_id', $configId) ->where('value', 1) ->column('org_id'); cache('ai_send', $orgIds); } if (!empty($orgIds)) { foreach ($orgIds as $orgId) { $this->assignToWorker($orgId); } } } catch (\Throwable $e) { echo '出错了~'; \think\facade\Log::error('dispatch error: ' . $e->getMessage()); } } public function assignToWorker($orgId) { try { // 获取组织的AI时间间隔(秒),缓存1小时 $second = cache('ai_time_' . $orgId); if ($second === false) { $configId = Db::name('config')->where('name', 'org_ai_time')->value('id'); $value = Db::name('config_org')->where('config_id', $configId)->where('org_id', $orgId)->value('value'); $second = intval($value ?: 0); cache('ai_time_' . $orgId, $second); } $second = intval($second) * 60; // 查询最近订单,按时间正序,限制20条 $orders = Db::name('orders') ->where('del', 0) ->where('order_mode', 1) ->where('org_id', $orgId) ->whereIn('work_type_mode', [1,2,3,4]) ->when($second, function ($query) use ($second) { $query->whereTime('create_time', '<=', date('Y-m-d H:i:s', time() - $second)); })->whereNotExists(function ($query) { $query->table('ai_send_fail') ->whereColumn('ai_send_fail.order_id', 'orders.id'); }) ->field('id,sn,dep_id,work_type_mode') ->order('id desc') ->limit(20) ->select(); if (empty($orders)) { return; } foreach ($orders as &$order) { $mode = $order['work_type_mode']; $workers = $this->getWorkersByMode($mode, $orgId); // 构建派工数据 $data = [ 'dispatch_type' => $mode, 'notify' => "http://wy.yjafw.com/api/ai_dispatch/notify", 'task' => [ 'task_id' => $order['id'], ], 'workers' => $workers, ]; if ($mode == 1) { // 获取部门用户 $users = Db::name('dep')->where('id', $order['dep_id'])->value('users'); $taskUsers = $users ? explode(',', $users) : []; $data['task']['users'] = $taskUsers; $typeId = Db::name('order_repair')->where('order_id', $order['id'])->value('type_id'); if (!$typeId){ continue; } $data['task']['required_skill'] = Db::name('order_type')->where('id', $typeId)->value('parent_id') ?? 0; }elseif ($mode == 3) { $users = Db::name('order_convey') ->alias('a') ->join('address b', 'b.id = a.start') ->where('a.order_id', $order['id']) ->value('b.users'); $taskUsers = $users ? explode(',', $users) : []; $data['task']['users'] = $taskUsers; } $res = $this->curl_post($this->url, json_encode($data, JSON_UNESCAPED_UNICODE)); // echo $res . PHP_EOL; \think\facade\Log::info('Dispatch result: ' . $res); } unset($order); } catch (\Throwable $e) { echo $e->getMessage(); \think\facade\Log::error('assignToWorker error: ' . $e->getMessage()); } } /** * 获取指定模式和组织下的可用工作人员 */ private function getWorkersByMode($mode, $orgId) { $workers = []; $users = cache('workers_mode_'.$mode.'_org_' . $orgId); if (!$users) { $roles = (new \app\common\model\WorkTypeMode())->getRoles($mode, $orgId); $roleIds = Db::name('roles') ->whereIn('parent_id', array_column($roles, 'id')) ->where('org_id', $orgId) ->where('del', 0) ->where('enable', 1) ->column('id'); if (empty($roleIds)) return []; // 获取用户信息 $users = Db::name('user_roles') ->alias('ur') ->join('user u', 'u.id = ur.user_id') ->where('u.del', 0) ->where('u.enable', 1) ->whereIn('ur.roles_id', $roleIds) ->where('u.work', 1) ->field('u.id as worker_id, u.real_name as name, u.label as skills') ->select(); if (empty($users)){ return []; } cache('workers_mode_'.$mode.'_org_' . $orgId,$users); } // 批量查询每个用户当前任务数,避免循环内count $userIds = array_column($users, 'worker_id'); $todoCounts = Db::name('todo') ->where('org_id', $orgId) ->where('del', 0) ->whereIn('to_user_id', $userIds) ->whereIn('todo_mode', [1,2,3]) ->where('create_yyyymm', date('Ym')) ->group('to_user_id') ->column('COUNT(*) as total_counts,COUNT(CASE WHEN todo_mode IN (1,2) THEN 1 END) as current_counts', 'to_user_id'); foreach ($users as $user) { $user['current_orders'] = $todoCounts[$user['worker_id']]['current_counts'] ?? 0; $user['month_orders'] = $todoCounts[$user['worker_id']]['total_counts'] ?? 0; if ($mode == 1) { $user['skills'] = $user['skills'] ? explode(',', $user['skills']) : []; } $workers[] = $user; } return $workers; } public function addTodo($orderId,$workerId) { $time = getTime(); $order = Db::name('orders') ->where('id',$orderId) ->field('org_id,work_type_mode,is_deal') ->find(); if (!$order){ return false; } $todoData = [ 'order_id' => $orderId, 'todo_content' => "", 'create_user_id' => -1, 'org_id' => $order['org_id'], 'create_time' => $time, 'todo_mode' => 1, 'work_type_mode' => $order['work_type_mode'], 'create_yyyy' => date('Y'), 'create_yyyymm' => date('Ym'), 'create_yyyymmdd' => date('Ymd'), 'to_user_id' => $workerId, ]; $todoData['sn'] = get_unique_sn(get_config('sn_prefix')); $todoId = Db::name('todo') ->insertGetId($todoData); $taskData = [ 'org_id' => $order['org_id'], 'type' => 1, 'start_time' => $time, 'create_time' => $time, ]; $taskData['user_id'] = $workerId; $taskData['bus_id'] = $todoId; Db::name('ai_send_success') ->insert([ 'org_id' => $order['org_id'], 'order_id' => $orderId, 'todo_id' => $todoId, 'user_id' => $workerId, 'create_time' => $time, 'mode'=>$order['work_type_mode'], ]); $res = Db::name('task') ->insert($taskData); $deal = $order['is_deal']; if(check_two_dispatch($workerId)==1){ $deal = 1; $dLog = [ 'user_id'=>$workerId, 'to_user_id'=>$workerId, 'create_time' => $time, 'content' => '', 'order_id' => $orderId, 'roles_id' => 0 ]; $res = Db::name('dispatch_log') ->insert($dLog); } $r = Db::name('orders') ->where('id',$orderId) ->update(['is_deal'=>$deal,'order_mode'=>4]); send_jpush([$workerId],AppMsg::PUSH_WORKER_ORDER_SEND,'',['id'=>$todoId]); } public function notify() { $json = file_get_contents('php://input'); $data = json_decode($json, true); if ($data){ if (!empty($data['order_id'])){ if (!empty($data['worker_id'])){ $this->addTodo($data['order_id'], $data['worker_id']); }else{ $order = Db::name('orders') ->where('id',$data['order_id']) ->field('org_id,work_type_mode,is_deal') ->find(); Db::name('ai_send_fail')->insert([ 'org_id' => $order['org_id'], 'order_id' => $data['order_id'], 'create_time' => getTime(), 'mode'=>$order['work_type_mode'], 'msg'=>$order['message'] ?? '', ]); } } } trace('ai派单:数据错误','error'); } function curl_post($url , $data=array()){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json; charset=utf-8'));//重点 // POST数据 curl_setopt($ch, CURLOPT_POST, 1); // 把post的变量加上 curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $output = curl_exec($ch); curl_close($ch); return $output; } }