user(); $orderBy = <<<'MySQL' CASE WHEN task_status = 1 THEN 100 ELSE 0 END MySQL; /** @var \Illuminate\Database\Eloquent\Collection */ $tasks = Task::with([ 'taskable' => function (MorphTo $morphTo) { $morphTo->morphWith([ TaskHygiene::class => ['workflow'], TaskLedger::class, ]); }, ]) ->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; } } ) ->orderBy(DB::raw($orderBy), 'DESC') ->orderBy('start_at', 'ASC') ->orderBy('end_at', 'ASC') ->simplePaginate($request->query('per_page', 20)); return TaskResource::collection( $tasks->through(function ($task) { $task->taskable->setRelation('task', $task->withoutRelations()); return $task; }) ); } public function show($id, Request $request) { /** @var \App\Models\Employee */ $user = $request->user(); $task = Task::with([ 'taskable' => function (MorphTo $morphTo) { $morphTo->morphWith([ TaskHygiene::class => ['workflow', 'store', 'storeMaster'], TaskLedger::class => ['store', 'storeMaster'], ]); }, ])->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); $task->taskable->setRelation('task', $task->withoutRelations()); return TaskResource::make($task); } public function submit($id, Request $request) { $task = Task::findOrFail($id); try { DB::beginTransaction(); $this->handleTaskSubmit($task, $request); DB::commit(); } catch (Throwable $th) { DB::rollBack(); throw tap($th, fn ($th) => report($th)); } return response()->noContent(); } protected function handleTaskSubmit(Task $task, Request $request): void { /** @var \App\Models\Employee */ $user = $request->user(); switch (Relation::getMorphedModel($task->taskable_type)) { case TaskHygiene::class: $request->validate( rules: [ 'task_hygiene.description' => ['bail', 'required', 'max:255'], 'task_hygiene.photos' => ['bail', 'required', 'array'], ], attributes: [ 'task_hygiene.description' => '清洁范围', 'task_hygiene.photos' => '清洁结果', ], ); switch ($task->taskable->task_status) { case TaskHygieneStatus::None: throw new RuntimeException('任务未开始'); break; case TaskHygieneStatus::Checking: throw new RuntimeException('任务审核中'); break; case TaskHygieneStatus::Success: throw new RuntimeException('任务已完成'); break; } $task->taskable->update($request->input('task_hygiene')); (new WorkFlowService())->apply($task->taskable->workflow, $user); break; default: throw new RuntimeException('任务不可提交'); break; } } }