作者 lyh

Merge branch 'master' of http://47.244.231.31:8099/zhl/globalso-v6 into lyh-server

@@ -18,7 +18,7 @@ class FetchTicketProjects extends Command @@ -18,7 +18,7 @@ class FetchTicketProjects extends Command
18 * 18 *
19 * @var string 19 * @var string
20 */ 20 */
21 - protected $signature = 'workorder:fetch-ticket-projects {action}}'; 21 + protected $signature = 'workorder:fetch-ticket-projects {action}';
22 22
23 /** 23 /**
24 * The console command description. 24 * The console command description.
@@ -234,12 +234,12 @@ class FetchTicketProjects extends Command @@ -234,12 +234,12 @@ class FetchTicketProjects extends Command
234 } 234 }
235 235
236 foreach ($items as $item) { 236 foreach ($items as $item) {
237 - $uuid = md5("AICC{$item['id']}");  
238 - $project = TicketProject::where('uuid', $uuid)->first(); 237 + foreach ($item['plans'] as $plan)
  238 + {
239 // 判断套餐是超迹还是域途, 如果 $item['plans'][0]['name'] 包含 '超迹' 则为超迹,否则为域途 239 // 判断套餐是超迹还是域途, 如果 $item['plans'][0]['name'] 包含 '超迹' 则为超迹,否则为域途
240 - $project_cate = Str::contains($item['plans'][0]['name'], '超迹') ? 3 : 4;  
241 - print_r($item['cj_assm']);  
242 - print_r($item['yutu_assm']); 240 + $project_cate = Str::contains($plan['name'], '超迹') ? 3 : 4;
  241 + $uuid = md5("AICC{$item['id']}{$project_cate}");
  242 + $project = TicketProject::where('uuid', $uuid)->first();
243 if ($project_cate == 3) 243 if ($project_cate == 3)
244 { 244 {
245 // 售后服务经理 245 // 售后服务经理
@@ -264,7 +264,7 @@ class FetchTicketProjects extends Command @@ -264,7 +264,7 @@ class FetchTicketProjects extends Command
264 264
265 $fields = [ 265 $fields = [
266 'company_name' => $item['company'], 266 'company_name' => $item['company'],
267 - 'title' => $item['company'] . " - " . $item['plan'], 267 + 'title' => $item['company'] . " - " . $plan['name'],
268 'assm_id' => $assm_id, 268 'assm_id' => $assm_id,
269 'seom_id' => $seom_id, 269 'seom_id' => $seom_id,
270 'engineer_id' => $engineer_id, 270 'engineer_id' => $engineer_id,
@@ -272,9 +272,9 @@ class FetchTicketProjects extends Command @@ -272,9 +272,9 @@ class FetchTicketProjects extends Command
272 'website' => '', 272 'website' => '',
273 'test_website' => '', 273 'test_website' => '',
274 'version' => 1, // 版本号 274 'version' => 1, // 版本号
275 - 'plan' => $item['plans'][0]['name'] ?? '', 275 + 'plan' => $plan['name'] ?? '',
276 'project_cate' => $project_cate, 276 'project_cate' => $project_cate,
277 - 'wechat_group_id' => $item['chatroom'], 277 + 'wechat_group_id' => $item['chatroom_id'],
278 ]; 278 ];
279 279
280 if (!$project) { 280 if (!$project) {
@@ -301,6 +301,7 @@ class FetchTicketProjects extends Command @@ -301,6 +301,7 @@ class FetchTicketProjects extends Command
301 $lastid = $item['id']; 301 $lastid = $item['id'];
302 echo now() . " | INFO | AICC: {$item['id']} {$item['company']} fetch ok \n"; 302 echo now() . " | INFO | AICC: {$item['id']} {$item['company']} fetch ok \n";
303 } 303 }
  304 + }
304 }catch (\Exception $exception){ 305 }catch (\Exception $exception){
305 echo now() . " | ERROR | " . $exception->getMessage() . "\n" . $exception->getTraceAsString() . "\n"; 306 echo now() . " | ERROR | " . $exception->getMessage() . "\n" . $exception->getTraceAsString() . "\n";
306 break; 307 break;
1 -<?php  
2 -  
3 -namespace App\Console\Commands\WorkOrder;  
4 -  
5 -use App\Models\ProjectAssociation\ProjectAssociation;  
6 -use App\Models\Workchat\MessagePush;  
7 -use App\Models\WorkOrder\Tickets;  
8 -use Illuminate\Console\Command;  
9 -  
10 -class PushNotify extends Command  
11 -{  
12 - /**  
13 - * The name and signature of the console command.  
14 - *  
15 - * @var string  
16 - */  
17 - protected $signature = 'workorder:push-notify';  
18 -  
19 - /**  
20 - * The console command description.  
21 - *  
22 - * @var string  
23 - */  
24 - protected $description = 'tickets push notify';  
25 -  
26 - /**  
27 - * Create a new command instance.  
28 - *  
29 - * @return void  
30 - */  
31 - public function __construct()  
32 - {  
33 - parent::__construct();  
34 - }  
35 -  
36 - /**  
37 - * Execute the console command.  
38 - *  
39 - * @return int  
40 - */  
41 - public function handle()  
42 - {  
43 - while (true) {  
44 - try {  
45 - $tick = Tickets::where('ding', 0)  
46 - ->where('submit_side', 2)  
47 -// ->where('project_id', 1)  
48 - ->first();  
49 - if (!$tick) {  
50 - echo now() . " WARNING | 没有待推送的工单\n";  
51 - sleep(3);  
52 - continue;  
53 - }  
54 - $project = $tick->project;  
55 - if ($project->version != 6 || $project->is_del == 1) {  
56 - echo now() . " WARNING | 项目版本或状态异常 \n";  
57 - $tick->ding = 1;  
58 - $tick->save();  
59 - continue;  
60 - }  
61 - $message_push = new MessagePush();  
62 - $message_push->project_id = $project->table_id;  
63 - $message_push->friend_id = ProjectAssociation::where('project_id', $project->table_id)  
64 - ->where('status', ProjectAssociation::STATUS_NORMAL)  
65 - ->where('binding_app', ProjectAssociation::ENTERPRISE_WECHAT)  
66 - ->value('friend_id');  
67 - if (empty($message_push->friend_id))  
68 - {  
69 - echo now() . " WARNING | 项目ID:{$project->table_id} 没有绑定企微群\n";  
70 - $tick->ding = 1;  
71 - $tick->save();  
72 - continue;  
73 - }  
74 - $message_push->content_type = 'Link';  
75 - $message_push->content = json_encode([  
76 - 'title' => '工单查看 - ' . $project->company_name,  
77 - 'desc' => $tick->title,  
78 - 'size' => 0,  
79 - 'thumbSize' => 0,  
80 - 'thumbUrl' => 'https://oa.quanqiusou.cn/logo.ico',  
81 - 'url' => 'https://oa.quanqiusou.cn/tickets?project_id='.$project->uuid  
82 - ], JSON_UNESCAPED_UNICODE);  
83 - $message_push->send_time = now();  
84 - $message_push->type = MessagePush::TYPE_TICKET;  
85 - $message_push->save();  
86 - $tick->ding = 1;  
87 - $tick->save();  
88 - echo now() . " INFO | 项目ID:{$project->table_id} 工单ID:{$tick->id} 推送成功\n";  
89 - }catch (\Exception $exception){  
90 - echo date('Y-m-d H:i:s')." ERROR | ".$exception->getMessage()."\n";  
91 - break;  
92 - }  
93 - }  
94 - }  
95 -}  
@@ -2,6 +2,8 @@ @@ -2,6 +2,8 @@
2 2
3 namespace App\Console\Commands\WorkOrder; 3 namespace App\Console\Commands\WorkOrder;
4 4
  5 +use App\Models\Manage\Manage;
  6 +use App\Models\WorkOrder\TicketChat;
5 use App\Models\WorkOrder\TicketLog; 7 use App\Models\WorkOrder\TicketLog;
6 use App\Services\DingTalkService; 8 use App\Services\DingTalkService;
7 use Illuminate\Console\Command; 9 use Illuminate\Console\Command;
@@ -14,7 +16,7 @@ class WorkOrderDing extends Command @@ -14,7 +16,7 @@ class WorkOrderDing extends Command
14 * 16 *
15 * @var string 17 * @var string
16 */ 18 */
17 - protected $signature = 'workorder:ding'; 19 + protected $signature = 'workorder:ding {action}';
18 20
19 /** 21 /**
20 * The console command description. 22 * The console command description.
@@ -40,11 +42,17 @@ class WorkOrderDing extends Command @@ -40,11 +42,17 @@ class WorkOrderDing extends Command
40 */ 42 */
41 public function handle() 43 public function handle()
42 { 44 {
  45 + $action = $this->argument('action');
  46 + $this->$action();
  47 + }
  48 +
  49 + public function dingLog()
  50 + {
43 while (true) { 51 while (true) {
44 try { 52 try {
45 $log = TicketLog::where('ding', 0)->first(); 53 $log = TicketLog::where('ding', 0)->first();
46 if (!$log) { 54 if (!$log) {
47 - echo now() . " INFO | 没有通知任务\n"; 55 + echo now() . " | INFO | 没有通知任务\n";
48 sleep(3); 56 sleep(3);
49 continue; 57 continue;
50 } 58 }
@@ -55,23 +63,82 @@ class WorkOrderDing extends Command @@ -55,23 +63,82 @@ class WorkOrderDing extends Command
55 )->get('https://oa.cmer.com/api/dingding/user/' . $mobile); 63 )->get('https://oa.cmer.com/api/dingding/user/' . $mobile);
56 if ($response->status() == 200) { 64 if ($response->status() == 200) {
57 $userid = $response->json()['data']['userid']; 65 $userid = $response->json()['data']['userid'];
58 - $text = "**您有新的售后工单**<br>";  
59 - $text .= "工单ID:{$log->work_order_id}<br>";  
60 - $text .= "工单类型:<font color='red'>{$log->workOrder->product}</font><br>";  
61 - $text .= "项目:{$log->workOrder->project->title}<br>";  
62 - $text .= "时间:{$log->created_at}<br>";  
63 $ding = new DingTalkService(); 66 $ding = new DingTalkService();
64 $resp = $ding->danliao(json_encode([ 67 $resp = $ding->danliao(json_encode([
65 - 'text' => $text,  
66 - 'title' => '售后工单通知',  
67 - ]), [$userid]); 68 + 'text' => "您有新的工单(ID: {$log->ticket_id}),请及时处理!",
  69 + 'title' => 'AI协同工单 - ' . $log->ticket->project->title,
  70 + 'picUrl' => 'https://hub.globalso.com/logocm.png',
  71 + 'messageUrl' => 'https://oa.quanqiusou.cn/afterorder?project_id=' . $log->ticket->project->uuid,
  72 + ]), [$userid], 'sampleLink');
68 $log->ding = 1; 73 $log->ding = 1;
  74 + echo now() . " | INFO | 工单ID: {$log->ticket_id} 通知成功\n";
69 }else 75 }else
  76 + {
70 $log->ding = 2; 77 $log->ding = 2;
  78 + echo now() . " | ERROR | 工单ID: {$log->ticket_id} 通知失败\n";
  79 + }
71 $log->save(); 80 $log->save();
72 }catch (\Exception $exception){ 81 }catch (\Exception $exception){
73 - echo now() . " ERROR | ".$exception->getMessage()."\n";  
74 - break; 82 + echo now() . " | ERROR | log ID {$log->id} {$exception->getMessage()} {$exception->getTraceAsString()} \n";
  83 + $log->ding = 2;
  84 + $log->save();
  85 + }
  86 + }
  87 + }
  88 +
  89 + public function dingChat()
  90 + {
  91 + while (true) {
  92 + $chat = TicketChat::where([
  93 + 'ding' => 0,
  94 + 'submit_side' => 2
  95 + ])->first();
  96 +
  97 + if (!$chat) {
  98 + echo now() . " | INFO | 没有通知任务\n";
  99 + sleep(3);
  100 + continue;
  101 + }
  102 +
  103 + try {
  104 + $project = $chat->ticket->project;
  105 +
  106 + // 通知谁?暂时通知A端最近一次提交的chat记录的人,如果没有,则通第一负责人
  107 + $lastChat = TicketChat::where('ticket_id', $chat->ticket_id)
  108 + ->where('submit_side', 1)
  109 + ->orderBy('id', 'desc')
  110 + ->first();
  111 + if ($lastChat) {
  112 + $mobile = Manage::where('id', $lastChat->manage_id)->first()->mobile;
  113 + }else
  114 + {
  115 + $mobile = Manage::where('id', $project->first_engineer)->first()->mobile;
  116 + }
  117 + $response = Http::withBasicAuth(
  118 + env('DINGDING_BASIC_USER'),
  119 + env('DINGDING_BASIC_PASS')
  120 + )->get('https://oa.cmer.com/api/dingding/user/' . $mobile);
  121 + if ($response->status() == 200) {
  122 + $userid = $response->json()['data']['userid'];
  123 + $ding = new DingTalkService();
  124 + $resp = $ding->danliao(json_encode([
  125 + 'text' => "客户对工单(ID: {$chat->ticket_id})进行了补充,请及时查看处理!",
  126 + 'title' => 'AI协同工单 - ' . $project->title,
  127 + 'picUrl' => 'https://hub.globalso.com/logocm.png',
  128 + 'messageUrl' => 'https://oa.quanqiusou.cn/afterorder?project_id=' . $project->uuid,
  129 + ]), [$userid], 'sampleLink');
  130 + $chat->ding = 1;
  131 + echo now() . " | INFO | 工单ID: {$chat->ticket_id} 通知成功\n";
  132 + }else
  133 + {
  134 + $chat->ding = 2;
  135 + echo now() . " | ERROR | 工单ID: {$chat->ticket_id} 通知失败\n";
  136 + }
  137 + $chat->save();
  138 + }catch (\Exception $exception) {
  139 + echo now() . " | ERROR | chat ID {$chat->id} {$exception->getMessage()} {$exception->getTraceAsString()} \n";
  140 + $chat->ding = 2;
  141 + $chat->save();
75 } 142 }
76 } 143 }
77 } 144 }
@@ -17,10 +17,10 @@ class TicketChatController extends Controller @@ -17,10 +17,10 @@ class TicketChatController extends Controller
17 */ 17 */
18 public function index($project_id, $ticket_id) 18 public function index($project_id, $ticket_id)
19 { 19 {
20 - $ticket = Tickets::find($ticket_id);;  
21 - if (!$ticket) return response('工单未找到', 404);  
22 - if ($ticket->project->uuid !== $project_id) return response('无权限查看该工单', 403);  
23 - if ($ticket->project->is_del) return response('项目状态异常', 400); 20 + $ticket = Tickets::find($ticket_id);
  21 + if (!$ticket) return response()->json(['message' => '工单未找到'], 404);
  22 + if ($ticket->project->uuid !== $project_id) return response()->json(['message' => '无权限查看该工单'], 403);
  23 + if ($ticket->project->is_del) return response()->json(['message' => '项目状态异常'], 400);
24 24
25 $chats = TicketChat::where('ticket_id', $ticket->id) 25 $chats = TicketChat::where('ticket_id', $ticket->id)
26 ->get(); 26 ->get();
@@ -47,9 +47,11 @@ class TicketChatController extends Controller @@ -47,9 +47,11 @@ class TicketChatController extends Controller
47 { 47 {
48 $request->validated(); 48 $request->validated();
49 $ticket = Tickets::with(['project'])->find($ticket_id); 49 $ticket = Tickets::with(['project'])->find($ticket_id);
50 - if (!$ticket) return response('工单未找到', 404);  
51 - if ($ticket->project->uuid !== $project_id) return response('无权限查看该工单', 403);  
52 - if ($ticket->project->is_del) return response('项目状态异常', 400); 50 + if (!$ticket) return response()->json(['message' => '工单未找到'], 404);
  51 + if ($ticket->status >= Tickets::STATUS_COMPLETED) return response()->json(['message' => '工单已完成或已关闭'], 400);
  52 +
  53 + if ($ticket->project->uuid !== $project_id) return response()->json(['message' => '无权限查看该工单'], 403);
  54 + if ($ticket->project->is_del) return response()->json(['message' => '项目状态异常'], 400);
53 55
54 $chat = new TicketChat(); 56 $chat = new TicketChat();
55 $chat->ticket_id = $ticket->id; 57 $chat->ticket_id = $ticket->id;
@@ -45,6 +45,7 @@ class TicketChatController extends BaseController @@ -45,6 +45,7 @@ class TicketChatController extends BaseController
45 $validated = $request->validated(); 45 $validated = $request->validated();
46 $ticket = Tickets::find($ticket_id); 46 $ticket = Tickets::find($ticket_id);
47 if (!$ticket) return response('工单未找到', 404); 47 if (!$ticket) return response('工单未找到', 404);
  48 + if ($ticket->status >= Tickets::STATUS_COMPLETED) return response('工单已完成或已关闭', 400);
48 if ($ticket->project->is_del) return response('项目状态异常', 400); 49 if ($ticket->project->is_del) return response('项目状态异常', 400);
49 50
50 $chat = new TicketChat(); 51 $chat = new TicketChat();
@@ -66,7 +66,7 @@ class MessagePush extends Base @@ -66,7 +66,7 @@ class MessagePush extends Base
66 //9-21 点,每条消息及时通知 66 //9-21 点,每条消息及时通知
67 //21-第二天 9 点,整合一起通知 67 //21-第二天 9 点,整合一起通知
68 $hour = date('H', strtotime($submit_at)); 68 $hour = date('H', strtotime($submit_at));
69 - if(($hour >= 9 && $hour < 21) || in_array($project_id, $special_project_ids)) { 69 + if(($hour >= 8 && $hour < 21) || in_array($project_id, $special_project_ids)) {
70 $model = new self(); 70 $model = new self();
71 $model->project_id = $project_id; 71 $model->project_id = $project_id;
72 $model->friend_id = $friend_id; 72 $model->friend_id = $friend_id;
@@ -76,7 +76,7 @@ class MessagePush extends Base @@ -76,7 +76,7 @@ class MessagePush extends Base
76 $model->send_time = $submit_at; 76 $model->send_time = $submit_at;
77 }else{ 77 }else{
78 //定时发送时间 78 //定时发送时间
79 - $send_time = $hour >= 9 ? date('Y-m-d 09:00:00', strtotime($submit_at . '+1 day')) : date('Y-m-d 09:00:00', strtotime($submit_at)); 79 + $send_time = $hour >= 8 ? date('Y-m-d 08:00:00', strtotime($submit_at . '+1 day')) : date('Y-m-d 08:00:00', strtotime($submit_at));
80 $model = self::where('project_id', $project_id)->where('type', self::TYPE_INQUIRY)->where('send_time', $send_time)->first(); 80 $model = self::where('project_id', $project_id)->where('type', self::TYPE_INQUIRY)->where('send_time', $send_time)->first();
81 if(!$model){ 81 if(!$model){
82 $model = new self(); 82 $model = new self();
@@ -86,7 +86,7 @@ class MessagePush extends Base @@ -86,7 +86,7 @@ class MessagePush extends Base
86 $model->ref_ids = $id; 86 $model->ref_ids = $id;
87 $model->countries = $country; 87 $model->countries = $country;
88 $model->send_time = $send_time; 88 $model->send_time = $send_time;
89 - $model->content = '[09:00] 您的全球搜网站收到来自【' . $country . $name . '】的询盘信息,请登录后台或APP进行查看!'; 89 + $model->content = '[08:00] 您的全球搜网站收到来自【' . $country . $name . '】的询盘信息,请登录后台或APP进行查看!';
90 }else{ 90 }else{
91 $ref_ids = explode(',', $model->ref_ids); 91 $ref_ids = explode(',', $model->ref_ids);
92 $ref_ids[] = $id; 92 $ref_ids[] = $id;
@@ -105,7 +105,7 @@ class MessagePush extends Base @@ -105,7 +105,7 @@ class MessagePush extends Base
105 $country = implode(',', $countries); 105 $country = implode(',', $countries);
106 } 106 }
107 } 107 }
108 - $model->content = '[09:00] 您的全球搜网站收到来自【' . $country . '】'.$count.'条询盘信息,请登录后台或APP进行查看!'; 108 + $model->content = '[08:00] 您的全球搜网站收到来自【' . $country . '】'.$count.'条询盘信息,请登录后台或APP进行查看!';
109 } 109 }
110 } 110 }
111 $model->save(); 111 $model->save();
@@ -45,7 +45,7 @@ class DingTalkService @@ -45,7 +45,7 @@ class DingTalkService
45 } 45 }
46 46
47 /** 批量发送私聊消息 */ 47 /** 批量发送私聊消息 */
48 - public function danliao(string $text, array $user_ids) 48 + public function danliao(string $text, array $user_ids, string $msg_key='sampleMarkdown')
49 { 49 {
50 $endpoint = '/v1/danliao'; 50 $endpoint = '/v1/danliao';
51 $payload = [ 51 $payload = [
@@ -53,7 +53,8 @@ class DingTalkService @@ -53,7 +53,8 @@ class DingTalkService
53 "appSecret" => $this->appSecret, 53 "appSecret" => $this->appSecret,
54 "robotCode" => $this->robotCode, 54 "robotCode" => $this->robotCode,
55 "msg_param" => $text, 55 "msg_param" => $text,
56 - "user_ids" => $user_ids 56 + "user_ids" => $user_ids,
  57 + "msg_key" => $msg_key
57 ]; 58 ];
58 return $this->send_request('POST', $this->bashUrl . $endpoint, $payload); 59 return $this->send_request('POST', $this->bashUrl . $endpoint, $payload);
59 } 60 }