| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- <?php
- namespace app\api\controller;
- use app\common\util\AppMsg;
- use think\Controller;
- use think\Db;
- class AiDispatch extends Controller
- {
- private $url = "http://121.36.46.135:8000/api/v1/dispatch";
- public function dispatch()
- {
- try {
- // 获取需要分派的组织ID,缓存1小时
- $orgIds = cache('ai_send');
- if (!$orgIds) {
- $configId = Db::name('config')
- ->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;
- }
- }
|