store-manage/app/Http/Controllers/Api/TaskController.php

169 lines
5.3 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Admin\Services\WorkFlowService;
use App\Enums\TaskHygieneStatus;
use App\Exceptions\RuntimeException;
use App\Http\Resources\TaskResource;
use App\Models\Task;
use App\Models\TaskHygiene;
use App\Models\TaskLedger;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Throwable;
class TaskController extends Controller
{
public function index(Request $request)
{
/** @var \App\Models\Employee */
$user = $request->user();
$orderBy = <<<'MySQL'
CASE
WHEN task_status = 1 THEN 100
WHEN task_status = 9 THEN 50
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', 'DESC')
->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;
}
}
}