作者 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
*
* @var string
*/
protected $signature = 'workorder:fetch-ticket-projects {action}}';
protected $signature = 'workorder:fetch-ticket-projects {action}';
/**
* The console command description.
... ... @@ -234,72 +234,73 @@ class FetchTicketProjects extends Command
}
foreach ($items as $item) {
$uuid = md5("AICC{$item['id']}");
$project = TicketProject::where('uuid', $uuid)->first();
// 判断套餐是超迹还是域途, 如果 $item['plans'][0]['name'] 包含 '超迹' 则为超迹,否则为域途
$project_cate = Str::contains($item['plans'][0]['name'], '超迹') ? 3 : 4;
print_r($item['cj_assm']);
print_r($item['yutu_assm']);
if ($project_cate == 3)
{
// 售后服务经理
$assm_id = collect([
ManageHr::where('name', $item['cj_assm']['real_name'] ?? '')->first()->manage_id ?? 0,
20, //徐莹
])->first(fn($v) => $v !== null && $v !== 0, 0);
}else
foreach ($item['plans'] as $plan)
{
// 域途
$assm_id = collect([
ManageHr::where('name', $item['yutu_assm']['real_name'] ?? '')->first()->manage_id ?? 0,
85, //黄小玉
])->first(fn($v) => $v !== null && $v !== 0, 0);
}
// 判断套餐是超迹还是域途, 如果 $item['plans'][0]['name'] 包含 '超迹' 则为超迹,否则为域途
$project_cate = Str::contains($plan['name'], '超迹') ? 3 : 4;
$uuid = md5("AICC{$item['id']}{$project_cate}");
$project = TicketProject::where('uuid', $uuid)->first();
if ($project_cate == 3)
{
// 售后服务经理
$assm_id = collect([
ManageHr::where('name', $item['cj_assm']['real_name'] ?? '')->first()->manage_id ?? 0,
20, //徐莹
])->first(fn($v) => $v !== null && $v !== 0, 0);
}else
{
// 域途
$assm_id = collect([
ManageHr::where('name', $item['yutu_assm']['real_name'] ?? '')->first()->manage_id ?? 0,
85, //黄小玉
])->first(fn($v) => $v !== null && $v !== 0, 0);
}
// 优化师
$seom_id = 0;
// 第一负责人
$engineer_id = $assm_id;
$is_del = 0;
// 优化师
$seom_id = 0;
// 第一负责人
$engineer_id = $assm_id;
$is_del = 0;
$fields = [
'company_name' => $item['company'],
'title' => $item['company'] . " - " . $item['plan'],
'assm_id' => $assm_id,
'seom_id' => $seom_id,
'engineer_id' => $engineer_id,
'is_del' => $is_del,
'website' => '',
'test_website' => '',
'version' => 1, // 版本号
'plan' => $item['plans'][0]['name'] ?? '',
'project_cate' => $project_cate,
'wechat_group_id' => $item['chatroom'],
];
$fields = [
'company_name' => $item['company'],
'title' => $item['company'] . " - " . $plan['name'],
'assm_id' => $assm_id,
'seom_id' => $seom_id,
'engineer_id' => $engineer_id,
'is_del' => $is_del,
'website' => '',
'test_website' => '',
'version' => 1, // 版本号
'plan' => $plan['name'] ?? '',
'project_cate' => $project_cate,
'wechat_group_id' => $item['chatroom_id'],
];
if (!$project) {
$project = new TicketProject();
$project->uuid = $uuid;
$project->post_id = $item['postid'];
$project->table_id = $item['id'];
foreach ($fields as $k => $v) {
$project->$k = $v;
}
$project->save();
} else {
$changed = false;
foreach ($fields as $k => $v) {
if ($project->$k != $v) {
if (!$project) {
$project = new TicketProject();
$project->uuid = $uuid;
$project->post_id = $item['postid'];
$project->table_id = $item['id'];
foreach ($fields as $k => $v) {
$project->$k = $v;
$changed = true;
}
}
if ($changed) {
$project->save();
} else {
$changed = false;
foreach ($fields as $k => $v) {
if ($project->$k != $v) {
$project->$k = $v;
$changed = true;
}
}
if ($changed) {
$project->save();
}
}
$lastid = $item['id'];
echo now() . " | INFO | AICC: {$item['id']} {$item['company']} fetch ok \n";
}
$lastid = $item['id'];
echo now() . " | INFO | AICC: {$item['id']} {$item['company']} fetch ok \n";
}
}catch (\Exception $exception){
echo now() . " | ERROR | " . $exception->getMessage() . "\n" . $exception->getTraceAsString() . "\n";
... ...
<?php
namespace App\Console\Commands\WorkOrder;
use App\Models\ProjectAssociation\ProjectAssociation;
use App\Models\Workchat\MessagePush;
use App\Models\WorkOrder\Tickets;
use Illuminate\Console\Command;
class PushNotify extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'workorder:push-notify';
/**
* The console command description.
*
* @var string
*/
protected $description = 'tickets push notify';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
while (true) {
try {
$tick = Tickets::where('ding', 0)
->where('submit_side', 2)
// ->where('project_id', 1)
->first();
if (!$tick) {
echo now() . " WARNING | 没有待推送的工单\n";
sleep(3);
continue;
}
$project = $tick->project;
if ($project->version != 6 || $project->is_del == 1) {
echo now() . " WARNING | 项目版本或状态异常 \n";
$tick->ding = 1;
$tick->save();
continue;
}
$message_push = new MessagePush();
$message_push->project_id = $project->table_id;
$message_push->friend_id = ProjectAssociation::where('project_id', $project->table_id)
->where('status', ProjectAssociation::STATUS_NORMAL)
->where('binding_app', ProjectAssociation::ENTERPRISE_WECHAT)
->value('friend_id');
if (empty($message_push->friend_id))
{
echo now() . " WARNING | 项目ID:{$project->table_id} 没有绑定企微群\n";
$tick->ding = 1;
$tick->save();
continue;
}
$message_push->content_type = 'Link';
$message_push->content = json_encode([
'title' => '工单查看 - ' . $project->company_name,
'desc' => $tick->title,
'size' => 0,
'thumbSize' => 0,
'thumbUrl' => 'https://oa.quanqiusou.cn/logo.ico',
'url' => 'https://oa.quanqiusou.cn/tickets?project_id='.$project->uuid
], JSON_UNESCAPED_UNICODE);
$message_push->send_time = now();
$message_push->type = MessagePush::TYPE_TICKET;
$message_push->save();
$tick->ding = 1;
$tick->save();
echo now() . " INFO | 项目ID:{$project->table_id} 工单ID:{$tick->id} 推送成功\n";
}catch (\Exception $exception){
echo date('Y-m-d H:i:s')." ERROR | ".$exception->getMessage()."\n";
break;
}
}
}
}
... ... @@ -2,6 +2,8 @@
namespace App\Console\Commands\WorkOrder;
use App\Models\Manage\Manage;
use App\Models\WorkOrder\TicketChat;
use App\Models\WorkOrder\TicketLog;
use App\Services\DingTalkService;
use Illuminate\Console\Command;
... ... @@ -14,7 +16,7 @@ class WorkOrderDing extends Command
*
* @var string
*/
protected $signature = 'workorder:ding';
protected $signature = 'workorder:ding {action}';
/**
* The console command description.
... ... @@ -40,11 +42,17 @@ class WorkOrderDing extends Command
*/
public function handle()
{
$action = $this->argument('action');
$this->$action();
}
public function dingLog()
{
while (true) {
try {
$log = TicketLog::where('ding', 0)->first();
if (!$log) {
echo now() . " INFO | 没有通知任务\n";
echo now() . " | INFO | 没有通知任务\n";
sleep(3);
continue;
}
... ... @@ -55,23 +63,82 @@ class WorkOrderDing extends Command
)->get('https://oa.cmer.com/api/dingding/user/' . $mobile);
if ($response->status() == 200) {
$userid = $response->json()['data']['userid'];
$text = "**您有新的售后工单**<br>";
$text .= "工单ID:{$log->work_order_id}<br>";
$text .= "工单类型:<font color='red'>{$log->workOrder->product}</font><br>";
$text .= "项目:{$log->workOrder->project->title}<br>";
$text .= "时间:{$log->created_at}<br>";
$ding = new DingTalkService();
$resp = $ding->danliao(json_encode([
'text' => $text,
'title' => '售后工单通知',
]), [$userid]);
'text' => "您有新的工单(ID: {$log->ticket_id}),请及时处理!",
'title' => 'AI协同工单 - ' . $log->ticket->project->title,
'picUrl' => 'https://hub.globalso.com/logocm.png',
'messageUrl' => 'https://oa.quanqiusou.cn/afterorder?project_id=' . $log->ticket->project->uuid,
]), [$userid], 'sampleLink');
$log->ding = 1;
echo now() . " | INFO | 工单ID: {$log->ticket_id} 通知成功\n";
}else
{
$log->ding = 2;
echo now() . " | ERROR | 工单ID: {$log->ticket_id} 通知失败\n";
}
$log->save();
}catch (\Exception $exception){
echo now() . " ERROR | ".$exception->getMessage()."\n";
break;
echo now() . " | ERROR | log ID {$log->id} {$exception->getMessage()} {$exception->getTraceAsString()} \n";
$log->ding = 2;
$log->save();
}
}
}
public function dingChat()
{
while (true) {
$chat = TicketChat::where([
'ding' => 0,
'submit_side' => 2
])->first();
if (!$chat) {
echo now() . " | INFO | 没有通知任务\n";
sleep(3);
continue;
}
try {
$project = $chat->ticket->project;
// 通知谁?暂时通知A端最近一次提交的chat记录的人,如果没有,则通第一负责人
$lastChat = TicketChat::where('ticket_id', $chat->ticket_id)
->where('submit_side', 1)
->orderBy('id', 'desc')
->first();
if ($lastChat) {
$mobile = Manage::where('id', $lastChat->manage_id)->first()->mobile;
}else
{
$mobile = Manage::where('id', $project->first_engineer)->first()->mobile;
}
$response = Http::withBasicAuth(
env('DINGDING_BASIC_USER'),
env('DINGDING_BASIC_PASS')
)->get('https://oa.cmer.com/api/dingding/user/' . $mobile);
if ($response->status() == 200) {
$userid = $response->json()['data']['userid'];
$ding = new DingTalkService();
$resp = $ding->danliao(json_encode([
'text' => "客户对工单(ID: {$chat->ticket_id})进行了补充,请及时查看处理!",
'title' => 'AI协同工单 - ' . $project->title,
'picUrl' => 'https://hub.globalso.com/logocm.png',
'messageUrl' => 'https://oa.quanqiusou.cn/afterorder?project_id=' . $project->uuid,
]), [$userid], 'sampleLink');
$chat->ding = 1;
echo now() . " | INFO | 工单ID: {$chat->ticket_id} 通知成功\n";
}else
{
$chat->ding = 2;
echo now() . " | ERROR | 工单ID: {$chat->ticket_id} 通知失败\n";
}
$chat->save();
}catch (\Exception $exception) {
echo now() . " | ERROR | chat ID {$chat->id} {$exception->getMessage()} {$exception->getTraceAsString()} \n";
$chat->ding = 2;
$chat->save();
}
}
}
... ...
... ... @@ -17,10 +17,10 @@ class TicketChatController extends Controller
*/
public function index($project_id, $ticket_id)
{
$ticket = Tickets::find($ticket_id);;
if (!$ticket) return response('工单未找到', 404);
if ($ticket->project->uuid !== $project_id) return response('无权限查看该工单', 403);
if ($ticket->project->is_del) return response('项目状态异常', 400);
$ticket = Tickets::find($ticket_id);
if (!$ticket) return response()->json(['message' => '工单未找到'], 404);
if ($ticket->project->uuid !== $project_id) return response()->json(['message' => '无权限查看该工单'], 403);
if ($ticket->project->is_del) return response()->json(['message' => '项目状态异常'], 400);
$chats = TicketChat::where('ticket_id', $ticket->id)
->get();
... ... @@ -47,9 +47,11 @@ class TicketChatController extends Controller
{
$request->validated();
$ticket = Tickets::with(['project'])->find($ticket_id);
if (!$ticket) return response('工单未找到', 404);
if ($ticket->project->uuid !== $project_id) return response('无权限查看该工单', 403);
if ($ticket->project->is_del) return response('项目状态异常', 400);
if (!$ticket) return response()->json(['message' => '工单未找到'], 404);
if ($ticket->status >= Tickets::STATUS_COMPLETED) return response()->json(['message' => '工单已完成或已关闭'], 400);
if ($ticket->project->uuid !== $project_id) return response()->json(['message' => '无权限查看该工单'], 403);
if ($ticket->project->is_del) return response()->json(['message' => '项目状态异常'], 400);
$chat = new TicketChat();
$chat->ticket_id = $ticket->id;
... ...
... ... @@ -45,6 +45,7 @@ class TicketChatController extends BaseController
$validated = $request->validated();
$ticket = Tickets::find($ticket_id);
if (!$ticket) return response('工单未找到', 404);
if ($ticket->status >= Tickets::STATUS_COMPLETED) return response('工单已完成或已关闭', 400);
if ($ticket->project->is_del) return response('项目状态异常', 400);
$chat = new TicketChat();
... ...
... ... @@ -66,7 +66,7 @@ class MessagePush extends Base
//9-21 点,每条消息及时通知
//21-第二天 9 点,整合一起通知
$hour = date('H', strtotime($submit_at));
if(($hour >= 9 && $hour < 21) || in_array($project_id, $special_project_ids)) {
if(($hour >= 8 && $hour < 21) || in_array($project_id, $special_project_ids)) {
$model = new self();
$model->project_id = $project_id;
$model->friend_id = $friend_id;
... ... @@ -76,7 +76,7 @@ class MessagePush extends Base
$model->send_time = $submit_at;
}else{
//定时发送时间
$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));
$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));
$model = self::where('project_id', $project_id)->where('type', self::TYPE_INQUIRY)->where('send_time', $send_time)->first();
if(!$model){
$model = new self();
... ... @@ -86,7 +86,7 @@ class MessagePush extends Base
$model->ref_ids = $id;
$model->countries = $country;
$model->send_time = $send_time;
$model->content = '[09:00] 您的全球搜网站收到来自【' . $country . $name . '】的询盘信息,请登录后台或APP进行查看!';
$model->content = '[08:00] 您的全球搜网站收到来自【' . $country . $name . '】的询盘信息,请登录后台或APP进行查看!';
}else{
$ref_ids = explode(',', $model->ref_ids);
$ref_ids[] = $id;
... ... @@ -105,7 +105,7 @@ class MessagePush extends Base
$country = implode(',', $countries);
}
}
$model->content = '[09:00] 您的全球搜网站收到来自【' . $country . '】'.$count.'条询盘信息,请登录后台或APP进行查看!';
$model->content = '[08:00] 您的全球搜网站收到来自【' . $country . '】'.$count.'条询盘信息,请登录后台或APP进行查看!';
}
}
$model->save();
... ...
... ... @@ -45,7 +45,7 @@ class DingTalkService
}
/** 批量发送私聊消息 */
public function danliao(string $text, array $user_ids)
public function danliao(string $text, array $user_ids, string $msg_key='sampleMarkdown')
{
$endpoint = '/v1/danliao';
$payload = [
... ... @@ -53,7 +53,8 @@ class DingTalkService
"appSecret" => $this->appSecret,
"robotCode" => $this->robotCode,
"msg_param" => $text,
"user_ids" => $user_ids
"user_ids" => $user_ids,
"msg_key" => $msg_key
];
return $this->send_request('POST', $this->bashUrl . $endpoint, $payload);
}
... ...