validate([ 'subject_type' => 'required', ]); $subjectType = $request->input('subject_type'); $model = Relation::getMorphedModel($subjectType); $resource = $this->mapResource($model); $user = $request->user(); $include = ['workflow']; if ($request->input('include')) { $explodes = explode(',', $request->input('include')); $include = array_merge($include, $explodes); } $query = $model::query()->with($include) ->whereHas('workflow', fn($q) => $q->where('check_status', CheckStatus::Processing)) ->whereHas('workflow.logs', fn($q) => $q->own($user)) ->orderBy('created_at', 'desc'); $list = $query->paginate($request->input('per_page')); switch ($model) { case TaskHygiene::class: $list->loadMissing(['task', 'store']); $list->through(function (TaskHygiene $item) { return tap($item->task)->setRelation('taskable', $item->unsetRelation('task')); }); break; } return $resource::collection($list); } public function show($id, Request $request) { $request->validate([ 'subject_type' => 'required', ]); $subjectType = $request->input('subject_type'); $model = Relation::getMorphedModel($subjectType); $resource = $this->mapResource($model); $include = ['workflow']; if ($request->input('include')) { $explodes = explode(',', $request->input('include')); $include = array_merge($include, $explodes); } $info = $model::query()->with($include)->findOrFail($id); switch ($model) { case TaskHygiene::class: $info = tap($info->task)->setRelation('taskable', $info->unsetRelation('task')); break; } return $resource::make($info); } public function logs($id, Request $request) { $request->validate([ 'subject_type' => 'required', ]); $check = WorkflowCheck::where('subject_type', $request->input('subject_type'))->where('subject_id', $id)->firstOrFail(); $logs = $check->logs()->sort()->get(); return WorkflowLogResource::collection($logs); } public function cancel($id, Request $request, WorkFlowService $workFlowService) { $request->validate([ 'subject_type' => 'required', ]); $check = WorkflowCheck::where('subject_type', $request->input('subject_type'))->where('subject_id', $id)->firstOrFail(); try { DB::beginTransaction(); if (!$workFlowService->cancel($check)) { throw new RuntimeException($workFlowService->getError()); } DB::commit(); return response('', Response::HTTP_OK); } catch (\Exception $e) { DB::rollBack(); throw new RuntimeException($e->getMessage()); } } public function check($id, Request $request, WorkFlowService $workFlowService) { $request->validate([ 'subject_type' => 'required', 'status' => ['required'], 'remarks' => [Rule::requiredIf(fn() => !$request->input('status'))] ], [ 'remarks.required_if' => '未通过原因必填', ]); $check = WorkflowCheck::where('subject_type', $request->input('subject_type'))->where('subject_id', $id)->firstOrFail(); $user = $request->user(); try { DB::beginTransaction(); $log = $check->logs()->where('check_status', CheckStatus::Processing)->first(); if (!$log) { throw new RuntimeException('审核已经完成'); } if (!$workFlowService->check($user, $log, !!$request->input('status'), ['remarks' => $request->input('remarks')])) { throw new RuntimeException($workFlowService->getError()); } DB::commit(); return response('', Response::HTTP_OK); } catch (\Exception $e) { DB::rollBack(); throw new RuntimeException($e->getMessage()); } } protected function mapResource(string $model) { $class = match ($model) { TaskHygiene::class => TaskResource::class, default => 'App\\Http\\Resources\\'.class_basename($model).'Resource', }; if (! class_exists($class)) { throw new RuntimeException('未知的 subject_type'); } return $class; } }