Merge branch 'hbb' into workorder
正在显示
12 个修改的文件
包含
323 行增加
和
106 行删除
| @@ -56,65 +56,99 @@ class FetchTicketProjects extends Command | @@ -56,65 +56,99 @@ class FetchTicketProjects extends Command | ||
| 56 | */ | 56 | */ |
| 57 | public function fetchV5() | 57 | public function fetchV5() |
| 58 | { | 58 | { |
| 59 | - # pm 项目经理 assm 售后服务经理 | ||
| 60 | - $response = Http::get('https://www.quanqiusou.cn/extend_api/webs/globalso_all.php'); | ||
| 61 | - if ($response->status() == 200) { | ||
| 62 | - $items = $response->json(); | ||
| 63 | - foreach ($items as $item) { | ||
| 64 | - # V5: 版本号+postid | ||
| 65 | - $uuid = md5("V5{$item['postid']}"); | ||
| 66 | - $project = TicketProject::where('uuid', $uuid)->first(); | ||
| 67 | - $assm_id = Manage::where('name', $item['assm'])->value('id') ?? Manage::where('name', '张鸿飞')->value('id') ?? 0; //售后服务经理 | ||
| 68 | - $seom_id = Manage::where('name', $item['yhs'])->value('id') ?? Manage::where('name', '陶婵')->value('id') ?? 0; //优化师 | ||
| 69 | - // 如果 $item['cate'] 包含”推广“字符,则 $engineer_name = $item['assm'] | ||
| 70 | - /** | ||
| 71 | - * 第一负责人逻即说明: | ||
| 72 | - * 优化推广项目:找售后服务经理??鸿飞 | ||
| 73 | - * 建站类项目: 找杨长远 | ||
| 74 | - */ | ||
| 75 | - $engineer_id = (strpos($item['cate'], '推广') !== false) ? $assm_id : Manage::where('name', '杨长远')->value('id') ?? 0; | 59 | + $page = 1; |
| 60 | + $postids = []; | ||
| 76 | 61 | ||
| 77 | - $fields = [ | ||
| 78 | - 'post_id' => $item['postid'], | ||
| 79 | - 'company_name' => $item['company'], | ||
| 80 | - 'title' => $item['title'], | ||
| 81 | - 'engineer_id' => $engineer_id, // 第一负责人 | ||
| 82 | - 'assm_id' => $assm_id, | ||
| 83 | - 'seom_id' => $seom_id, | ||
| 84 | - 'website' => $item['main_url'] ?? '', | ||
| 85 | - 'test_website' => $item['test_url'] ?? '', | ||
| 86 | - 'is_del' => 0, | ||
| 87 | - 'plan' => $item['plan'] ?? '', | ||
| 88 | - 'project_cate' => 1, | ||
| 89 | - ]; | ||
| 90 | - if (!$project) { | ||
| 91 | - $new = new TicketProject(); | ||
| 92 | - $new->uuid = $uuid; | ||
| 93 | - $new->version = 5; | ||
| 94 | - $new->table_id = 0; | ||
| 95 | - foreach ($fields as $k => $v) { | ||
| 96 | - $new->$k = $v; | ||
| 97 | - } | ||
| 98 | - $new->save(); | ||
| 99 | - } else { | ||
| 100 | - $changed = false; | ||
| 101 | - foreach ($fields as $k => $v) { | ||
| 102 | - if ($project->$k != $v) { | ||
| 103 | - $project->$k = $v; | ||
| 104 | - $changed = true; | 62 | + while (true) { |
| 63 | + $response = Http::get('https://www.quanqiusou.cn/extend_api/webs/globalso_all.php?page=' . $page); | ||
| 64 | + if ($response->status() == 200) { | ||
| 65 | + $resp_json = $response->json(); | ||
| 66 | + $items = $resp_json['data'] ?? []; | ||
| 67 | + if (empty($items)) | ||
| 68 | + { | ||
| 69 | + echo now() . " | INFO | V5: not found items on page $page \n"; | ||
| 70 | + break; | ||
| 71 | + } | ||
| 72 | + foreach ($items as $item) { | ||
| 73 | + # V5: 版本号+postid | ||
| 74 | + $uuid = md5("V5{$item['postid']}"); | ||
| 75 | + $project = TicketProject::where('uuid', $uuid)->first(); | ||
| 76 | + | ||
| 77 | + // 项目状态, 根据 $item['cate'] 判断,建站中,建站客户,推广 | ||
| 78 | + if (strpos($item['cate'], '推广') !== false) | ||
| 79 | + $status=3; // 推广 | ||
| 80 | + elseif ($item['cate'] == "建站客户") | ||
| 81 | + $status=2; // 建站客户 | ||
| 82 | + elseif ($item['cate'] == "建站中") | ||
| 83 | + $status=1; // 建站中 | ||
| 84 | + | ||
| 85 | + $assm_id = Manage::where('name', $item['assm'])->value('id') ?? Manage::where('name', '张鸿飞')->value('id') ?? 0; //售后服务经理 | ||
| 86 | + $seom_id = Manage::where('name', $item['yhs'])->value('id') ?? Manage::where('name', '陶婵')->value('id') ?? 0; //优化师 | ||
| 87 | + $pm_id = Manage::where('name', $item['pm'])->value('id') ?? Manage::where('name', '李洁玉')->value('id') ?? 0; // 项目经理 | ||
| 88 | + | ||
| 89 | + /** | ||
| 90 | + * 第一负责人逻即说明: | ||
| 91 | + * 优化推广项目:找售后服务经理??鸿飞 | ||
| 92 | + * 建站中:项目经理 | ||
| 93 | + * 建站完成:杨长远 | ||
| 94 | + */ | ||
| 95 | + | ||
| 96 | + if ($status == 3) | ||
| 97 | + $engineer_id = $assm_id; // 推广类项目找售后服务经理 | ||
| 98 | + elseif ($status == 2) | ||
| 99 | + $engineer_id = Manage::where('name', '杨长远')->value('id') ?? 0; //建站完成 | ||
| 100 | + elseif ($status == 1) | ||
| 101 | + $engineer_id = $pm_id; // 建站中找项目经理 | ||
| 102 | + | ||
| 103 | + $fields = [ | ||
| 104 | + 'post_id' => $item['postid'], | ||
| 105 | + 'company_name' => $item['company'], | ||
| 106 | + 'title' => $item['title'] . " - V5", | ||
| 107 | + 'engineer_id' => $engineer_id, // 第一负责人 | ||
| 108 | + 'assm_id' => $assm_id, | ||
| 109 | + 'seom_id' => $seom_id, | ||
| 110 | + 'website' => $item['main_url'] ?? '', | ||
| 111 | + 'test_website' => $item['test_url'] ?? '', | ||
| 112 | + 'is_del' => 0, | ||
| 113 | + 'plan' => $item['plan'] ?? '', | ||
| 114 | + 'project_cate' => 1, | ||
| 115 | + 'pm_id' => $pm_id, | ||
| 116 | + 'status' => $status, // 项目状态 | ||
| 117 | + 'wechat_group_id' => $item['wx_id'] | ||
| 118 | + ]; | ||
| 119 | + if (!$project) { | ||
| 120 | + $new = new TicketProject(); | ||
| 121 | + $new->uuid = $uuid; | ||
| 122 | + $new->version = 5; | ||
| 123 | + $new->table_id = 0; | ||
| 124 | + foreach ($fields as $k => $v) { | ||
| 125 | + $new->$k = $v; | ||
| 126 | + } | ||
| 127 | + $new->save(); | ||
| 128 | + } else { | ||
| 129 | + $changed = false; | ||
| 130 | + foreach ($fields as $k => $v) { | ||
| 131 | + if ($project->$k != $v) { | ||
| 132 | + $project->$k = $v; | ||
| 133 | + $changed = true; | ||
| 134 | + } | ||
| 135 | + } | ||
| 136 | + if ($changed) { | ||
| 137 | + $project->save(); | ||
| 105 | } | 138 | } |
| 106 | } | 139 | } |
| 107 | - if ($changed) { | ||
| 108 | - $project->save(); | ||
| 109 | - } | 140 | + echo now() . " | INFO | V5: {$item['postid']} {$item['company']} fetch ok \n"; |
| 110 | } | 141 | } |
| 142 | + $page++; | ||
| 143 | + $postids = array_merge($postids, collect($items)->pluck('postid')->toArray()); | ||
| 111 | } | 144 | } |
| 112 | - $postids = collect($items)->pluck('postid')->toArray(); | 145 | + } |
| 146 | + if ($postids) | ||
| 147 | + { | ||
| 113 | // 软删除 gl_ticket_projects 中不存在的项目 | 148 | // 软删除 gl_ticket_projects 中不存在的项目 |
| 114 | TicketProject::where('version', 5) | 149 | TicketProject::where('version', 5) |
| 115 | ->whereNotIn('post_id', $postids) | 150 | ->whereNotIn('post_id', $postids) |
| 116 | ->update(['is_del' => 1]); | 151 | ->update(['is_del' => 1]); |
| 117 | - echo date("Y-m-d H:i:s") . " V5: fetch completed, total " . count($items) . " items\n"; | ||
| 118 | } | 152 | } |
| 119 | } | 153 | } |
| 120 | 154 | ||
| @@ -142,26 +176,35 @@ class FetchTicketProjects extends Command | @@ -142,26 +176,35 @@ class FetchTicketProjects extends Command | ||
| 142 | foreach ($items as $item) { | 176 | foreach ($items as $item) { |
| 143 | $uuid = md5("V6{$item->id}"); | 177 | $uuid = md5("V6{$item->id}"); |
| 144 | $project = TicketProject::where('uuid', $uuid)->first(); | 178 | $project = TicketProject::where('uuid', $uuid)->first(); |
| 179 | + // 项目状态 | ||
| 180 | + if ($item->type == Project::TYPE_ONE) | ||
| 181 | + $status = 1; // 建站中 | ||
| 182 | + elseif ($item->type == Project::TYPE_THREE) | ||
| 183 | + $status = 2; // 建站完成 | ||
| 184 | + else | ||
| 185 | + $status = 3; // 推广找售后服务经理 | ||
| 186 | + | ||
| 145 | // 售后服务经理 | 187 | // 售后服务经理 |
| 146 | $assm_id = collect([ | 188 | $assm_id = collect([ |
| 147 | ManageHr::find($item->deploy_optimize->manager_mid)->manage_id ?? 0, | 189 | ManageHr::find($item->deploy_optimize->manager_mid)->manage_id ?? 0, |
| 148 | ManageHr::find($item->deploy_optimize->tech_leader)->manage_id ?? 0, | 190 | ManageHr::find($item->deploy_optimize->tech_leader)->manage_id ?? 0, |
| 149 | 8, //张鸿飞 | 191 | 8, //张鸿飞 |
| 150 | ])->first(fn($v) => $v !== null && $v !== 0, 0); | 192 | ])->first(fn($v) => $v !== null && $v !== 0, 0); |
| 193 | + | ||
| 151 | // 优化师 | 194 | // 优化师 |
| 152 | - $optimist_mid = ManageHr::find($item->deploy_optimize->optimist_mid) ? ManageHr::find($item->deploy_optimize->optimist_mid)->manage_id : 0; | ||
| 153 | - $seom_id = $optimist_mid ? $optimist_mid : $assm_id; | ||
| 154 | - /** | ||
| 155 | - * 第一负责人逻辑 | ||
| 156 | - * 建站类项目:找杨长远 | ||
| 157 | - * 推广类:找售后 | ||
| 158 | - */ | ||
| 159 | - if ($item->type == Project::TYPE_THREE) { | ||
| 160 | - $engineer_id = Manage::where('name', '杨长远')->value('id') ?? 0; // 建站类项目找杨长远 | ||
| 161 | - }else { | ||
| 162 | - // 其他找售后服务经理 | ||
| 163 | - $engineer_id = $assm_id; | ||
| 164 | - } | 195 | + $seom_id = ManageHr::find($item->deploy_optimize->optimist_mid) ? ManageHr::find($item->deploy_optimize->optimist_mid)->manage_id : 0; |
| 196 | + | ||
| 197 | + // 项目经理 | ||
| 198 | + $pm_id = ManageHr::find($item->deploy_build->manager_mid)->manage_id ?? ManageHr::where('name', '李洁玉')->value('manage_id') ?? 0; | ||
| 199 | + | ||
| 200 | + // 第一负责人 | ||
| 201 | + if ($status == 1) | ||
| 202 | + $engineer_id = $pm_id; // 建站中找项目经理 | ||
| 203 | + elseif ($status == 2) | ||
| 204 | + $engineer_id = Manage::where('name', '杨长远')->value('id') ?? 0; // 建站完成找杨长远 | ||
| 205 | + else | ||
| 206 | + $engineer_id = $assm_id; // 推广找售后服务经理 | ||
| 207 | + | ||
| 165 | $is_del = ( | 208 | $is_del = ( |
| 166 | $item->extend_type == 5 | 209 | $item->extend_type == 5 |
| 167 | || $item->type == 8 | 210 | || $item->type == 8 |
| @@ -171,7 +214,7 @@ class FetchTicketProjects extends Command | @@ -171,7 +214,7 @@ class FetchTicketProjects extends Command | ||
| 171 | 214 | ||
| 172 | $fields = [ | 215 | $fields = [ |
| 173 | 'company_name' => $item->company, | 216 | 'company_name' => $item->company, |
| 174 | - 'title' => $item->title, | 217 | + 'title' => $item->title . " - V6", |
| 175 | 'assm_id' => $assm_id, | 218 | 'assm_id' => $assm_id, |
| 176 | 'seom_id' => $seom_id, | 219 | 'seom_id' => $seom_id, |
| 177 | 'engineer_id' => $engineer_id, | 220 | 'engineer_id' => $engineer_id, |
| @@ -181,10 +224,12 @@ class FetchTicketProjects extends Command | @@ -181,10 +224,12 @@ class FetchTicketProjects extends Command | ||
| 181 | 'version' => empty($item->version) ? 7 : $item->version, // 版本号 | 224 | 'version' => empty($item->version) ? 7 : $item->version, // 版本号 |
| 182 | 'plan' => $item->planMap()[$item->deploy_build->plan] ?? '', | 225 | 'plan' => $item->planMap()[$item->deploy_build->plan] ?? '', |
| 183 | 'project_cate' => 2, | 226 | 'project_cate' => 2, |
| 184 | - 'wechat_group_id' => ProjectAssociation::where('project_id', $project->table_id) | 227 | + 'wechat_group_id' => ProjectAssociation::where('project_id', $item->id) |
| 185 | ->where('status', ProjectAssociation::STATUS_NORMAL) | 228 | ->where('status', ProjectAssociation::STATUS_NORMAL) |
| 186 | ->where('binding_app', ProjectAssociation::ENTERPRISE_WECHAT) | 229 | ->where('binding_app', ProjectAssociation::ENTERPRISE_WECHAT) |
| 187 | - ->value('friend_id') | 230 | + ->value('friend_id'), |
| 231 | + 'pm_id' => $pm_id, | ||
| 232 | + 'status' => $status, // 项目状态 | ||
| 188 | ]; | 233 | ]; |
| 189 | if (!$project) { | 234 | if (!$project) { |
| 190 | $project = new TicketProject(); | 235 | $project = new TicketProject(); |
| @@ -8,10 +8,8 @@ use App\Http\Requests\Api\WorkOrder\TicketStoreRequest; | @@ -8,10 +8,8 @@ use App\Http\Requests\Api\WorkOrder\TicketStoreRequest; | ||
| 8 | use App\Models\WorkOrder\TicketLog; | 8 | use App\Models\WorkOrder\TicketLog; |
| 9 | use App\Models\WorkOrder\TicketProject; | 9 | use App\Models\WorkOrder\TicketProject; |
| 10 | use App\Models\WorkOrder\Tickets; | 10 | use App\Models\WorkOrder\Tickets; |
| 11 | -use Darabonba\GatewaySpi\Models\InterceptorContext\response; | ||
| 12 | use Illuminate\Http\Request; | 11 | use Illuminate\Http\Request; |
| 13 | use Illuminate\Support\Facades\DB; | 12 | use Illuminate\Support\Facades\DB; |
| 14 | -use Illuminate\Support\Facades\Http; | ||
| 15 | 13 | ||
| 16 | class TicketController extends BaseController | 14 | class TicketController extends BaseController |
| 17 | { | 15 | { |
| @@ -29,8 +27,11 @@ class TicketController extends BaseController | @@ -29,8 +27,11 @@ class TicketController extends BaseController | ||
| 29 | $size = (int)$request->input('size', 10); | 27 | $size = (int)$request->input('size', 10); |
| 30 | 28 | ||
| 31 | $tickets = Tickets::with([ | 29 | $tickets = Tickets::with([ |
| 32 | - 'project:*', | ||
| 33 | - 'logs.engineer:id,name', | 30 | + 'project.pm', |
| 31 | + 'project.assm', | ||
| 32 | + 'project.seom', | ||
| 33 | + 'project.first_engineer', | ||
| 34 | + 'logs.engineer', | ||
| 34 | ]) | 35 | ]) |
| 35 | ->where('project_id', $project->id) | 36 | ->where('project_id', $project->id) |
| 36 | // ->where('submit_side', 2) | 37 | // ->where('submit_side', 2) |
| @@ -85,9 +86,7 @@ class TicketController extends BaseController | @@ -85,9 +86,7 @@ class TicketController extends BaseController | ||
| 85 | $ticket->submit_side = 2; // 2 for B-side submission | 86 | $ticket->submit_side = 2; // 2 for B-side submission |
| 86 | $ticket->submit_username = $request->input('submit_username'); | 87 | $ticket->submit_username = $request->input('submit_username'); |
| 87 | $ticket->save(); | 88 | $ticket->save(); |
| 88 | - $log = new TicketLog(); | ||
| 89 | - $log->engineer_id = $project->engineer_id; // 默认第一负责人 | ||
| 90 | - $ticket->logs()->save($log); | 89 | + $ticket->saveEngineers([$project->engineer_id]); |
| 91 | $project->pushWechatGroupMsg("客户新增了工单(ID:{$ticket->id}),请及时处理!"); | 90 | $project->pushWechatGroupMsg("客户新增了工单(ID:{$ticket->id}),请及时处理!"); |
| 92 | return $ticket; | 91 | return $ticket; |
| 93 | }); | 92 | }); |
| @@ -143,10 +142,10 @@ class TicketController extends BaseController | @@ -143,10 +142,10 @@ class TicketController extends BaseController | ||
| 143 | public function projectInfo($project_id) | 142 | public function projectInfo($project_id) |
| 144 | { | 143 | { |
| 145 | $project = TicketProject::with([ | 144 | $project = TicketProject::with([ |
| 146 | - 'projectV6:id,company', | ||
| 147 | - 'assm:id,name', | ||
| 148 | - 'seom:id,name', | ||
| 149 | - 'first_engineer:id,name', | 145 | + 'pm', |
| 146 | + 'assm', | ||
| 147 | + 'seom', | ||
| 148 | + 'first_engineer', | ||
| 150 | ]) | 149 | ]) |
| 151 | ->where('uuid', $project_id)->first(); | 150 | ->where('uuid', $project_id)->first(); |
| 152 | if (!$project) return $this->response('未找到项目', 404); | 151 | if (!$project) return $this->response('未找到项目', 404); |
| @@ -8,7 +8,7 @@ use App\Http\Requests\Aside\WorkOrder\AsideTicketStoreRequest; | @@ -8,7 +8,7 @@ use App\Http\Requests\Aside\WorkOrder\AsideTicketStoreRequest; | ||
| 8 | use App\Http\Requests\Aside\WorkOrder\AsideTicketListRequest; | 8 | use App\Http\Requests\Aside\WorkOrder\AsideTicketListRequest; |
| 9 | use App\Http\Requests\Aside\WorkOrder\AsideTicketUpdateRequest; | 9 | use App\Http\Requests\Aside\WorkOrder\AsideTicketUpdateRequest; |
| 10 | use App\Http\Requests\Aside\WorkOrder\TicketProjectListRequest; | 10 | use App\Http\Requests\Aside\WorkOrder\TicketProjectListRequest; |
| 11 | -use App\Models\Workchat\MessagePush; | 11 | +use App\Models\Manage\ManageHr; |
| 12 | use App\Models\WorkOrder\TicketLog; | 12 | use App\Models\WorkOrder\TicketLog; |
| 13 | use App\Models\WorkOrder\TicketProject; | 13 | use App\Models\WorkOrder\TicketProject; |
| 14 | use App\Models\WorkOrder\Tickets; | 14 | use App\Models\WorkOrder\Tickets; |
| @@ -26,8 +26,8 @@ class AsideTicketController extends BaseController | @@ -26,8 +26,8 @@ class AsideTicketController extends BaseController | ||
| 26 | { | 26 | { |
| 27 | $validated = $request->validated(); | 27 | $validated = $request->validated(); |
| 28 | $lists = Tickets::with([ | 28 | $lists = Tickets::with([ |
| 29 | - 'logs.engineer:id,name', | ||
| 30 | - 'project', | 29 | + 'logs.engineer', |
| 30 | + 'project.pm', | ||
| 31 | ]) | 31 | ]) |
| 32 | ->when(!empty($validated['engineer_id']), function ($query) use ($validated) { | 32 | ->when(!empty($validated['engineer_id']), function ($query) use ($validated) { |
| 33 | // 查 gl_tickets 表 submit_user_id 或 gl_ticket_logs 表 engineer_id | 33 | // 查 gl_tickets 表 submit_user_id 或 gl_ticket_logs 表 engineer_id |
| @@ -51,6 +51,10 @@ class AsideTicketController extends BaseController | @@ -51,6 +51,10 @@ class AsideTicketController extends BaseController | ||
| 51 | $status = $request->input('status'); | 51 | $status = $request->input('status'); |
| 52 | return $query->where('status', $status); | 52 | return $query->where('status', $status); |
| 53 | }) | 53 | }) |
| 54 | + ->when($request->input('star') !== null, function ($query) use ($request) { | ||
| 55 | + $star = $request->input('star'); | ||
| 56 | + return $query->where('star', $star); | ||
| 57 | + }) | ||
| 54 | ->when($request->input('search'), function ($query) use ($request) { | 58 | ->when($request->input('search'), function ($query) use ($request) { |
| 55 | // search 查 gl_tickets.title 或 gl_ticket_projects.title 或 gl_ticket_projects.company_name | 59 | // search 查 gl_tickets.title 或 gl_ticket_projects.title 或 gl_ticket_projects.company_name |
| 56 | $search = $request->input('search'); | 60 | $search = $request->input('search'); |
| @@ -92,7 +96,31 @@ class AsideTicketController extends BaseController | @@ -92,7 +96,31 @@ class AsideTicketController extends BaseController | ||
| 92 | public function projectList(TicketProjectListRequest $request) | 96 | public function projectList(TicketProjectListRequest $request) |
| 93 | { | 97 | { |
| 94 | $validated = $request->validated(); | 98 | $validated = $request->validated(); |
| 99 | + $dept_id = ManageHr::where('manage_id', $this->manage['id']) | ||
| 100 | + ->value('dept_id'); | ||
| 101 | + | ||
| 95 | $lists = TicketProject::where('is_del', 0) | 102 | $lists = TicketProject::where('is_del', 0) |
| 103 | + ->when(($this->manage['role'] != 1 && $dept_id != 5), function ($query) use ($dept_id) { | ||
| 104 | + /** | ||
| 105 | + * 超管看所有项目 $this->manage['role']=1 | ||
| 106 | + * 全球搜: 技术部ID 1、售后部ID 2 | ||
| 107 | + * 超迹AI: AICC技术部 ID 4 | ||
| 108 | + * 域途:域途运营部 ID 17 | ||
| 109 | + */ | ||
| 110 | + if (in_array($dept_id, [1, 2])) { | ||
| 111 | + // V5 V6 | ||
| 112 | + return $query->whereIn('project_cate', [1, 2]); | ||
| 113 | + }elseif ($dept_id == 4) { | ||
| 114 | + // 超迹AI | ||
| 115 | + return $query->where('project_cate', 3); | ||
| 116 | + }elseif ($dept_id == 17){ | ||
| 117 | + // 域途 | ||
| 118 | + return $query->where('project_cate', 4); | ||
| 119 | + }else{ | ||
| 120 | + // 其他部门,不允许看数据 | ||
| 121 | + return $query->where('id', 0); // 返回空结果 | ||
| 122 | + } | ||
| 123 | + }) | ||
| 96 | ->when(!empty($validated['search']), function ($query) use ($validated) { | 124 | ->when(!empty($validated['search']), function ($query) use ($validated) { |
| 97 | // 查找项目名称或公司名称 | 125 | // 查找项目名称或公司名称 |
| 98 | $search = $validated['search']; | 126 | $search = $validated['search']; |
| @@ -141,13 +169,12 @@ class AsideTicketController extends BaseController | @@ -141,13 +169,12 @@ class AsideTicketController extends BaseController | ||
| 141 | $ticket->submit_side = 1; // 1 for A-side submission | 169 | $ticket->submit_side = 1; // 1 for A-side submission |
| 142 | $ticket->submit_user_id = $this->manage['id']; | 170 | $ticket->submit_user_id = $this->manage['id']; |
| 143 | $ticket->submit_username = $this->manage['name']; | 171 | $ticket->submit_username = $this->manage['name']; |
| 172 | + $ticket->star = $request->input('star', 3); | ||
| 173 | + $ticket->plan_end_at = $request->input('plan_end_at', null); | ||
| 144 | $ticket->save(); | 174 | $ticket->save(); |
| 145 | - // A 端提工单,都是针对客户提的需求等开发任务;比如翻译,修改页面等。。。 | ||
| 146 | - foreach ($request->input('engineer_ids', []) as $engineer_id) { | ||
| 147 | - $log = new TicketLog(); | ||
| 148 | - $log->engineer_id = $engineer_id; | ||
| 149 | - $ticket->logs()->save($log); | ||
| 150 | - } | 175 | + |
| 176 | + // 分配工单参与人 | ||
| 177 | + $ticket->saveEngineers($request->input('engineer_ids', [])); | ||
| 151 | $project->pushWechatGroupMsg("创贸({$ticket->submit_username})新增了工单(ID:{$ticket->id}),请及时处理!"); | 178 | $project->pushWechatGroupMsg("创贸({$ticket->submit_username})新增了工单(ID:{$ticket->id}),请及时处理!"); |
| 152 | return $ticket; | 179 | return $ticket; |
| 153 | }); | 180 | }); |
| @@ -186,19 +213,11 @@ class AsideTicketController extends BaseController | @@ -186,19 +213,11 @@ class AsideTicketController extends BaseController | ||
| 186 | // 开始修改 | 213 | // 开始修改 |
| 187 | $result = DB::transaction(function () use ($request, $ticket) { | 214 | $result = DB::transaction(function () use ($request, $ticket) { |
| 188 | if ($request->input('engineer_ids')) | 215 | if ($request->input('engineer_ids')) |
| 189 | - { | ||
| 190 | - // 有邀请工程师协同处理 | ||
| 191 | - foreach ($request->input('engineer_ids') as $engineer_id) | ||
| 192 | - { | ||
| 193 | - try { | ||
| 194 | - // 利用唯一索引去重 | ||
| 195 | - $new_log = new TicketLog(); | ||
| 196 | - $new_log->engineer_id = $engineer_id; | ||
| 197 | - $ticket->logs()->save($new_log); | ||
| 198 | - }catch (\Exception $exception){} | ||
| 199 | - } | ||
| 200 | - } | 216 | + $ticket->saveEngineers($request->input('engineer_ids')); |
| 201 | 217 | ||
| 218 | + // 其他字段有提交数据才修改,比如star plan_end_at | ||
| 219 | + $ticket->star = $request->input('star', $ticket->star); | ||
| 220 | + $ticket->plan_end_at = $request->input('plan_end_at', $ticket->plan_end_at); | ||
| 202 | $ticket->reply = $request->input('reply', null); | 221 | $ticket->reply = $request->input('reply', null); |
| 203 | $ticket->status = $request->input('status', $ticket->status); | 222 | $ticket->status = $request->input('status', $ticket->status); |
| 204 | if ($ticket->status == Tickets::STATUS_COMPLETED) | 223 | if ($ticket->status == Tickets::STATUS_COMPLETED) |
| @@ -78,6 +78,7 @@ class AsideTicketLogController extends BaseController | @@ -78,6 +78,7 @@ class AsideTicketLogController extends BaseController | ||
| 78 | // 是否有未完成的子任务 | 78 | // 是否有未完成的子任务 |
| 79 | $pending = $ticket->logs() | 79 | $pending = $ticket->logs() |
| 80 | ->where('status', '<', TicketLog::STATUS_COMPLETED) | 80 | ->where('status', '<', TicketLog::STATUS_COMPLETED) |
| 81 | + ->where('is_engineer', 1) | ||
| 81 | ->count(); | 82 | ->count(); |
| 82 | if ($pending) | 83 | if ($pending) |
| 83 | { | 84 | { |
| @@ -89,6 +90,7 @@ class AsideTicketLogController extends BaseController | @@ -89,6 +90,7 @@ class AsideTicketLogController extends BaseController | ||
| 89 | $ticket->end_at = now(); | 90 | $ticket->end_at = now(); |
| 90 | $project = $ticket->project; | 91 | $project = $ticket->project; |
| 91 | $project->pushWechatGroupMsg("工单(ID:{$ticket->id})已全部完成,请访问查看详情!"); | 92 | $project->pushWechatGroupMsg("工单(ID:{$ticket->id})已全部完成,请访问查看详情!"); |
| 93 | + $ticket->pushDing('finish'); | ||
| 92 | } | 94 | } |
| 93 | $ticket->save(); | 95 | $ticket->save(); |
| 94 | return $log; | 96 | return $log; |
| @@ -26,6 +26,7 @@ class AsideTicketListRequest extends FormRequest | @@ -26,6 +26,7 @@ class AsideTicketListRequest extends FormRequest | ||
| 26 | return [ | 26 | return [ |
| 27 | 'project_id' => 'nullable|string', | 27 | 'project_id' => 'nullable|string', |
| 28 | 'status' => 'nullable|in:0,1,2,3|integer', | 28 | 'status' => 'nullable|in:0,1,2,3|integer', |
| 29 | + 'star' => 'nullable|in:1,2,3|integer', | ||
| 29 | 'search' => 'nullable|string', // 搜索关键词 | 30 | 'search' => 'nullable|string', // 搜索关键词 |
| 30 | 'engineer_id' => 'nullable|integer', // 工程师ID | 31 | 'engineer_id' => 'nullable|integer', // 工程师ID |
| 31 | 'page' => 'nullable|integer', | 32 | 'page' => 'nullable|integer', |
| @@ -29,6 +29,8 @@ class AsideTicketStoreRequest extends FormRequest | @@ -29,6 +29,8 @@ class AsideTicketStoreRequest extends FormRequest | ||
| 29 | 'content' => 'required|string', | 29 | 'content' => 'required|string', |
| 30 | 'files' => 'nullable|array', | 30 | 'files' => 'nullable|array', |
| 31 | 'engineer_ids' => 'array', | 31 | 'engineer_ids' => 'array', |
| 32 | + 'star' => 'nullable|in:1,2,3|integer', | ||
| 33 | + 'plan_end_at' => 'nullable|date', | ||
| 32 | ]; | 34 | ]; |
| 33 | } | 35 | } |
| 34 | } | 36 | } |
| @@ -27,6 +27,8 @@ class AsideTicketUpdateRequest extends FormRequest | @@ -27,6 +27,8 @@ class AsideTicketUpdateRequest extends FormRequest | ||
| 27 | 'status' => 'nullable|in:0,1,2,3|integer', | 27 | 'status' => 'nullable|in:0,1,2,3|integer', |
| 28 | 'reply' => 'nullable|string', | 28 | 'reply' => 'nullable|string', |
| 29 | 'engineer_ids' => 'nullable|array', | 29 | 'engineer_ids' => 'nullable|array', |
| 30 | + 'star' => 'nullable|in:1,2,3|integer', | ||
| 31 | + 'plan_end_at' => 'nullable|date', | ||
| 30 | ]; | 32 | ]; |
| 31 | } | 33 | } |
| 32 | } | 34 | } |
app/Models/WorkOrder/TicketDing.php
0 → 100644
| @@ -4,6 +4,7 @@ namespace App\Models\WorkOrder; | @@ -4,6 +4,7 @@ namespace App\Models\WorkOrder; | ||
| 4 | 4 | ||
| 5 | use App\Models\Base; | 5 | use App\Models\Base; |
| 6 | use App\Models\Manage\Manage; | 6 | use App\Models\Manage\Manage; |
| 7 | +use App\Models\Manage\ManageHr; | ||
| 7 | use Illuminate\Database\Eloquent\Factories\HasFactory; | 8 | use Illuminate\Database\Eloquent\Factories\HasFactory; |
| 8 | 9 | ||
| 9 | class TicketLog extends Base | 10 | class TicketLog extends Base |
| @@ -19,8 +20,8 @@ class TicketLog extends Base | @@ -19,8 +20,8 @@ class TicketLog extends Base | ||
| 19 | 20 | ||
| 20 | public function engineer() | 21 | public function engineer() |
| 21 | { | 22 | { |
| 22 | - return $this->belongsTo(Manage::class, 'engineer_id', 'id') | ||
| 23 | - ->select(['id', 'name', 'mobile']); | 23 | + return $this->belongsTo(ManageHr::class, 'engineer_id', 'manage_id') |
| 24 | + ->select(['manage_id', 'name', 'nickname']); | ||
| 24 | } | 25 | } |
| 25 | 26 | ||
| 26 | public function ticket() | 27 | public function ticket() |
| @@ -4,6 +4,7 @@ namespace App\Models\WorkOrder; | @@ -4,6 +4,7 @@ namespace App\Models\WorkOrder; | ||
| 4 | 4 | ||
| 5 | use App\Models\Base; | 5 | use App\Models\Base; |
| 6 | use App\Models\Manage\Manage; | 6 | use App\Models\Manage\Manage; |
| 7 | +use App\Models\Manage\ManageHr; | ||
| 7 | use App\Models\Project\Project; | 8 | use App\Models\Project\Project; |
| 8 | use App\Models\ProjectAssociation\ProjectAssociation; | 9 | use App\Models\ProjectAssociation\ProjectAssociation; |
| 9 | use App\Models\Workchat\MessagePush; | 10 | use App\Models\Workchat\MessagePush; |
| @@ -21,18 +22,24 @@ class TicketProject extends Base | @@ -21,18 +22,24 @@ class TicketProject extends Base | ||
| 21 | ->where('version', 6); | 22 | ->where('version', 6); |
| 22 | } | 23 | } |
| 23 | 24 | ||
| 25 | + // 项目经理 | ||
| 26 | + public function pm() | ||
| 27 | + { | ||
| 28 | + return $this->hasOne(ManageHr::class, 'manage_id', 'pm_id')->select(['manage_id', 'name', 'nickname']); | ||
| 29 | + } | ||
| 30 | + | ||
| 24 | //售后服务经理 | 31 | //售后服务经理 |
| 25 | public function assm() | 32 | public function assm() |
| 26 | { | 33 | { |
| 27 | - return $this->hasOne(Manage::class, 'id', 'assm_id') | ||
| 28 | - ->select(['id', 'name']); | 34 | + return $this->hasOne(ManageHr::class, 'manage_id', 'assm_id') |
| 35 | + ->select(['manage_id', 'name', 'nickname']); | ||
| 29 | } | 36 | } |
| 30 | 37 | ||
| 31 | // 优化师 | 38 | // 优化师 |
| 32 | public function seom() | 39 | public function seom() |
| 33 | { | 40 | { |
| 34 | - return $this->hasOne(Manage::class, 'id', 'seom_id') | ||
| 35 | - ->select(['id', 'name']); | 41 | + return $this->hasOne(ManageHr::class, 'manage_id', 'seom_id') |
| 42 | + ->select(['manage_id', 'name', 'nickname']); | ||
| 36 | } | 43 | } |
| 37 | 44 | ||
| 38 | /** | 45 | /** |
| @@ -40,8 +47,8 @@ class TicketProject extends Base | @@ -40,8 +47,8 @@ class TicketProject extends Base | ||
| 40 | */ | 47 | */ |
| 41 | public function first_engineer() | 48 | public function first_engineer() |
| 42 | { | 49 | { |
| 43 | - return $this->hasOne(Manage::class, 'id', 'engineer_id') | ||
| 44 | - ->select(['id', 'name']); | 50 | + return $this->hasOne(ManageHr::class, 'manage_id', 'engineer_id') |
| 51 | + ->select(['manage_id', 'name', 'nickname']); | ||
| 45 | } | 52 | } |
| 46 | 53 | ||
| 47 | /** | 54 | /** |
| @@ -3,7 +3,9 @@ | @@ -3,7 +3,9 @@ | ||
| 3 | namespace App\Models\WorkOrder; | 3 | namespace App\Models\WorkOrder; |
| 4 | 4 | ||
| 5 | use App\Models\Base; | 5 | use App\Models\Base; |
| 6 | +use App\Models\Manage\ManageHr; | ||
| 6 | use Illuminate\Database\Eloquent\Factories\HasFactory; | 7 | use Illuminate\Database\Eloquent\Factories\HasFactory; |
| 8 | +use Illuminate\Support\Facades\Log; | ||
| 7 | 9 | ||
| 8 | class Tickets extends Base | 10 | class Tickets extends Base |
| 9 | { | 11 | { |
| @@ -32,4 +34,90 @@ class Tickets extends Base | @@ -32,4 +34,90 @@ class Tickets extends Base | ||
| 32 | { | 34 | { |
| 33 | return $this->belongsTo(TicketProject::class, 'project_id', 'id'); | 35 | return $this->belongsTo(TicketProject::class, 'project_id', 'id'); |
| 34 | } | 36 | } |
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * 当前工单,保存参与的人员到 gl_ticket_logs 表 | ||
| 40 | + * 逻辑说明: | ||
| 41 | + * 1. 如果当前项目是超迹,要把徐莹和第一负责人加进去,为参与人 | ||
| 42 | + * 2. 若是域途项目,把黄小玉和第一负责人加进去,为参与人 | ||
| 43 | + */ | ||
| 44 | + public function saveEngineers($engineer_ids = []) | ||
| 45 | + { | ||
| 46 | + $canyu = [ | ||
| 47 | + $this->project->engineer_id, // 第一负责人 | ||
| 48 | + ]; | ||
| 49 | + | ||
| 50 | + if ($this->project->project_cate == 3) | ||
| 51 | + $canyu[] = 20; // 徐莹 | ||
| 52 | + elseif ($this->project->project_cate == 4) | ||
| 53 | + $canyu[] = 85; // 黄小玉 | ||
| 54 | + | ||
| 55 | + $all_engineer_ids = array_unique(array_merge($canyu, $engineer_ids)); | ||
| 56 | + | ||
| 57 | + foreach ($all_engineer_ids as $engineer_id) | ||
| 58 | + { | ||
| 59 | + try { | ||
| 60 | + $log = $this->logs()->where('engineer_id', $engineer_id)->first(); | ||
| 61 | + if ($log && $log->is_engineer != in_array($engineer_id, $engineer_ids)) | ||
| 62 | + { | ||
| 63 | + $log->is_engineer = in_array($engineer_id, $engineer_ids); | ||
| 64 | + $log->save(); | ||
| 65 | + }else | ||
| 66 | + { | ||
| 67 | + // 利用唯一索引去重 | ||
| 68 | + $log = new TicketLog(); | ||
| 69 | + $log->engineer_id = $engineer_id; | ||
| 70 | + $log->is_engineer = in_array($engineer_id, $engineer_ids); | ||
| 71 | + $this->logs()->save($log); | ||
| 72 | + } | ||
| 73 | + }catch (\Exception $exception){ | ||
| 74 | + Log::error(" | ERRPR | Ticket saveEngineers {$exception->getMessage()} \n {$exception->getTraceAsString()}"); | ||
| 75 | + } | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + // 删除没有参与当前工单的人员(若之前已有) | ||
| 79 | + $this->logs()->whereNotIn('engineer_id', $all_engineer_ids)->delete(); | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + /** | ||
| 83 | + * TODO 这个是一个补充功能 | ||
| 84 | + * 那些情况需要推送钉钉内部通知? | ||
| 85 | + * 1. 客户提交了工单 | ||
| 86 | + * - 通知第一负责人 (gl_ticket_logs 表做了标记) | ||
| 87 | + * 2. 客户补充了工单 | ||
| 88 | + * - 通知最近的聊天技术(gl_ticket_chats 表做了标记) | ||
| 89 | + * 3. 技术完成了工单 | ||
| 90 | + * - 通知第一负责人 (暂无,所以这里做补充,如果以后要把上面的逻辑也加进来也可以,只是我为了偷懒,暂时只考虑完成工单请款) | ||
| 91 | + */ | ||
| 92 | + public function pushDing($type = 'finish') | ||
| 93 | + { | ||
| 94 | + try { | ||
| 95 | + $ding = new TicketDing(); | ||
| 96 | + $ding->msgKey = 'sampleLink'; | ||
| 97 | + $ding->table_name = 'gl_tickets'; | ||
| 98 | + $ding->table_id = $this->id; | ||
| 99 | + | ||
| 100 | + if ($type == 'finish') | ||
| 101 | + { | ||
| 102 | + // 所以技术完成了工单,通知第一负责人 和 工单的提交人 | ||
| 103 | + $ding->userIds = [$this->project->engineer_id]; | ||
| 104 | + if ($this->submit_side == 1) { | ||
| 105 | + // A 端提的,还要通知提交人 | ||
| 106 | + $ding->userIds[] = $this->submit_user_id; | ||
| 107 | + // 去重 | ||
| 108 | + $ding->userIds = array_unique($ding->userIds); | ||
| 109 | + } | ||
| 110 | + $ding->msgParam = json_encode([ | ||
| 111 | + 'text' => "工单(ID: {$this->id}),已经全部完成,请访问查看详情!", | ||
| 112 | + 'title' => 'AI协同工单 - ' . $this->project->title, | ||
| 113 | + 'picUrl' => 'https://hub.globalso.com/logocm.png', | ||
| 114 | + 'messageUrl' => 'https://oa.quanqiusou.cn/afterorder?project_id=' . $this->project->uuid, | ||
| 115 | + ], JSON_UNESCAPED_UNICODE); | ||
| 116 | + $ding->save(); | ||
| 117 | + } | ||
| 118 | + }catch (\Exception $exception){ | ||
| 119 | + Log::error(" | ERRPR | Ticket {$exception->getMessage()} \n {$exception->getTraceAsString()}"); | ||
| 120 | + } | ||
| 121 | + } | ||
| 122 | + | ||
| 35 | } | 123 | } |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use Illuminate\Database\Migrations\Migration; | ||
| 4 | +use Illuminate\Database\Schema\Blueprint; | ||
| 5 | +use Illuminate\Support\Facades\Schema; | ||
| 6 | + | ||
| 7 | +class CreateTicketDingsTable extends Migration | ||
| 8 | +{ | ||
| 9 | + /** | ||
| 10 | + * Run the migrations. | ||
| 11 | + * | ||
| 12 | + * @return void | ||
| 13 | + */ | ||
| 14 | + public function up() | ||
| 15 | + { | ||
| 16 | + Schema::create('gl_ticket_dings', function (Blueprint $table) { | ||
| 17 | + $table->id(); | ||
| 18 | + $table->json('userIds')->comment('接收人ID列表'); | ||
| 19 | + $table->string('msgKey')->default('sampleMarkdown')->comment('消息模板标识'); | ||
| 20 | + $table->json('msgParam')->comment('消息内容参数,JSON格式'); | ||
| 21 | + $table->smallInteger('status')->default(0)->index()->comment('发送状态:0-未发送,1-已发送,2-发送失败'); | ||
| 22 | + $table->string('errorMsg')->nullable()->comment('错误信息,发送失败时记录'); | ||
| 23 | + $table->string('table_name', 50)->nullable()->comment('关联表名称'); | ||
| 24 | + $table->string('table_id', 50)->nullable()->comment('关联表ID'); | ||
| 25 | + $table->timestamps(); | ||
| 26 | + }); | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + /** | ||
| 30 | + * Reverse the migrations. | ||
| 31 | + * | ||
| 32 | + * @return void | ||
| 33 | + */ | ||
| 34 | + public function down() | ||
| 35 | + { | ||
| 36 | + Schema::dropIfExists('gl_ticket_dings'); | ||
| 37 | + } | ||
| 38 | +} |
-
请 注册 或 登录 后发表评论