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', ]); $user = $request->user(); $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); } switch ($model) { case TaskHygiene::class: $info = Task::with([ 'taskable' => function (MorphTo $morphTo) { $morphTo->morphWith([ TaskHygiene::class => ['workflow', 'store'], TaskLedger::class => ['store'], ]); }, ])->whereHasMorph( 'taskable', [TaskHygiene::class, TaskLedger::class], function (Builder $query, string $type) use ($user) { switch ($type) { case TaskLedger::class: case TaskHygiene::class: if ($user->isStoreMaster()) { $query->where('store_id', $user->store_id); } else { $query->whereRaw('1!=1'); } break; } } )->findOrFail($id); $info->taskable->setRelation('task', $info->withoutRelations()); break; default: $info = $model::query()->with($include)->findOrFail($id); 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; } }