generated from liutk/owl-admin-base
我的任务
parent
cecce29485
commit
c9bccd7123
|
|
@ -5,6 +5,7 @@ namespace App\Admin\Controllers\Plan;
|
|||
use App\Admin\Controllers\AdminController;
|
||||
use App\Admin\Services\Plan\PlanService;
|
||||
use App\Enums\PlanStatus;
|
||||
use App\Enums\TaskHygieneStatus;
|
||||
use App\Enums\TaskLedgerStatus;
|
||||
use App\Enums\TaskPerformanceStatus;
|
||||
use App\Enums\TaskStatus;
|
||||
|
|
@ -246,12 +247,10 @@ class PlanController extends AdminController
|
|||
amis('reload')->align('right'),
|
||||
])
|
||||
->columns([
|
||||
// amis()->TableColumn('id', __('plan.task.id')),
|
||||
// amis()->TableColumn('name', __('plan.task.name')),
|
||||
amis()->TableColumn('taskable.month', __('plan.task_hygiene.month')),
|
||||
amis()->TableColumn('taskable.store.title', __('plan.task_hygiene.store')),
|
||||
amis()->TableColumn('taskable.store_master.name', __('plan.task_hygiene.store_master')),
|
||||
amis()->TableColumn('task_status', __('plan.task.status'))->type('mapping')->map(TaskStatus::labelMap()),
|
||||
amis()->TableColumn('taskable.task_status', __('plan.task_hygiene.status'))->type('mapping')->map(TaskHygieneStatus::labelMap()),
|
||||
amis()->TableColumn('completed_at', __('plan.task.completed_at')),
|
||||
amis()->TableColumn('created_at', __('plan.task.created_at')),
|
||||
$this->rowActions([
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class TaskController extends AdminController
|
|||
$morphTo->morphWith([
|
||||
TaskLedger::class => ['store', 'storeMaster'],
|
||||
TaskPerformance::class => ['store', 'storeMaster'],
|
||||
TaskHygiene::class => ['store', 'storeMaster'],
|
||||
TaskHygiene::class => ['store', 'storeMaster', 'workflow'],
|
||||
]);
|
||||
},
|
||||
])
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum TaskHygieneStatus: int
|
||||
{
|
||||
case None = 1; // 未开始
|
||||
case Pending = 2; // 待完成
|
||||
case Checking = 3; // 审核中
|
||||
case Unpassed = 4; // 未通过
|
||||
case Success = 5; // 已完成
|
||||
case Failed = 6; // 未完成
|
||||
|
||||
public function text(): string
|
||||
{
|
||||
return self::options()[$this->value];
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return [
|
||||
self::None->value => '未开始',
|
||||
self::Pending->value => '待完成',
|
||||
self::Checking->value => '审核中',
|
||||
self::Unpassed->value => '未通过',
|
||||
self::Success->value => '已完成',
|
||||
self::Failed->value => '未完成',
|
||||
];
|
||||
}
|
||||
|
||||
public static function labelMap(): array
|
||||
{
|
||||
return [
|
||||
self::None->value => '<span class="label bg-gray-500">'.self::None->text().'</span>',
|
||||
self::Pending->value => '<span class="label label-primary">'.self::Pending->text().'</span>',
|
||||
self::Checking->value => '<span class="label bg-danger">'.self::Checking->text().'</span>',
|
||||
self::Unpassed->value => '<span class="label label-warning">'.self::Unpassed->text().'</span>',
|
||||
self::Success->value => '<span class="label label-success">'.self::Success->text().'</span>',
|
||||
self::Failed->value => '<span class="label label-danger">'.self::Failed->text().'</span>',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ enum TaskLedgerStatus: int
|
|||
public static function labelMap(): array
|
||||
{
|
||||
return [
|
||||
self::None->value => '<span class="label bg-purple-500">'.self::None->text().'</span>',
|
||||
self::None->value => '<span class="label bg-gray-500">'.self::None->text().'</span>',
|
||||
self::Pending->value => '<span class="label label-primary">'.self::Pending->text().'</span>',
|
||||
self::Success->value => '<span class="label label-success">'.self::Success->text().'</span>',
|
||||
self::Failed->value => '<span class="label label-danger">'.self::Failed->text().'</span>',
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ enum TaskPerformanceStatus: int
|
|||
public static function labelMap(): array
|
||||
{
|
||||
return [
|
||||
self::None->value => '<span class="label bg-purple-500">'.self::None->text().'</span>',
|
||||
self::None->value => '<span class="label bg-gray-500">'.self::None->text().'</span>',
|
||||
self::Pending->value => '<span class="label label-primary">'.self::Pending->text().'</span>',
|
||||
self::Success->value => '<span class="label label-success">'.self::Success->text().'</span>',
|
||||
self::Failed->value => '<span class="label label-danger">'.self::Failed->text().'</span>',
|
||||
|
|
|
|||
|
|
@ -2,13 +2,19 @@
|
|||
|
||||
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
|
||||
{
|
||||
|
|
@ -25,7 +31,14 @@ class TaskController extends Controller
|
|||
MySQL;
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Collection */
|
||||
$tasks = Task::with(['taskable'])
|
||||
$tasks = Task::with([
|
||||
'taskable' => function (MorphTo $morphTo) {
|
||||
$morphTo->morphWith([
|
||||
TaskHygiene::class => ['task', 'workflow'],
|
||||
TaskLedger::class => ['task'],
|
||||
]);
|
||||
},
|
||||
])
|
||||
->whereHasMorph(
|
||||
'taskable',
|
||||
[TaskHygiene::class, TaskLedger::class],
|
||||
|
|
@ -49,4 +62,66 @@ MySQL;
|
|||
|
||||
return TaskResource::collection($tasks);
|
||||
}
|
||||
|
||||
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()->json();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ class TaskHygieneResource extends JsonResource
|
|||
'store' => StoreResource::make($this->whenLoaded('store')),
|
||||
'description' => $this->resource->description,
|
||||
'photos' => $this->resource->photos,
|
||||
'status' => $this->resource->task_status,
|
||||
'created_at' => $this->resource->created_at->timestamp,
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\TaskHygieneStatus;
|
||||
use App\Traits\HasCheckable;
|
||||
use App\Traits\HasDateTimeFormatter;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
|
|
@ -14,6 +15,10 @@ class TaskHygiene extends Model
|
|||
{
|
||||
use HasCheckable, HasFactory, HasDateTimeFormatter;
|
||||
|
||||
protected $appends = [
|
||||
'task_status',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'month',
|
||||
'store_id',
|
||||
|
|
@ -50,4 +55,38 @@ class TaskHygiene extends Model
|
|||
set: fn (mixed $value) => json_encode(is_array($value) ? $value : []),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务状态
|
||||
*/
|
||||
protected function taskStatus(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: function (mixed $value) {
|
||||
$datetime = now();
|
||||
|
||||
if ($datetime->lt($this->task->start_at)) {
|
||||
return TaskHygieneStatus::None;
|
||||
}
|
||||
|
||||
if ($this->task->isSuccess() || $this->checkSuccess()) {
|
||||
return TaskHygieneStatus::Success;
|
||||
}
|
||||
|
||||
if ($this->checkProcessing()) {
|
||||
return TaskHygieneStatus::Checking;
|
||||
}
|
||||
|
||||
if ($this->checkFail()) {
|
||||
return TaskHygieneStatus::Unpassed;
|
||||
}
|
||||
|
||||
if ($datetime->lt($this->task->end_at)) {
|
||||
return TaskHygieneStatus::Pending;
|
||||
}
|
||||
|
||||
return TaskHygieneStatus::Failed;
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,22 +45,22 @@ class TaskLedger extends Model
|
|||
protected function taskStatus(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: function (mixed $value, array $attributes) {
|
||||
/** @var \App\Models\Task */
|
||||
$task = $this->task;
|
||||
get: function (mixed $value) {
|
||||
$datetime = now();
|
||||
|
||||
if ($task->isSuccess()) {
|
||||
if ($datetime->lt($this->task->start_at)) {
|
||||
return TaskLedgerStatus::None;
|
||||
}
|
||||
|
||||
if ($this->task->isSuccess()) {
|
||||
return TaskLedgerStatus::Success;
|
||||
}
|
||||
|
||||
$datetime = now();
|
||||
|
||||
if ($datetime->lt($task->start_at)) {
|
||||
return TaskLedgerStatus::None;
|
||||
} elseif ($datetime->gte($task->end_at)) {
|
||||
return TaskLedgerStatus::Failed;
|
||||
if ($datetime->lt($this->task->end_at)) {
|
||||
return TaskLedgerStatus::Pending;
|
||||
}
|
||||
return TaskLedgerStatus::Pending;
|
||||
|
||||
return TaskLedgerStatus::Failed;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,20 +55,22 @@ class TaskPerformance extends Model
|
|||
protected function taskStatus(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: function (mixed $value, array $attributes) {
|
||||
if ($this->isSuccess()) {
|
||||
return TaskPerformanceStatus::Success;
|
||||
}
|
||||
|
||||
// 当前时间
|
||||
get: function (mixed $value) {
|
||||
$datetime = now();
|
||||
|
||||
if ($datetime->lt($this->task->start_at)) {
|
||||
return TaskPerformanceStatus::None;
|
||||
} elseif ($datetime->gte($this->task->end_at)) {
|
||||
return TaskPerformanceStatus::Failed;
|
||||
}
|
||||
return TaskPerformanceStatus::Pending;
|
||||
|
||||
if ($this->isSuccess()) {
|
||||
return TaskPerformanceStatus::Success;
|
||||
}
|
||||
|
||||
if ($datetime->lt($this->task->end_at)) {
|
||||
return TaskPerformanceStatus::Pending;
|
||||
}
|
||||
|
||||
return TaskPerformanceStatus::Failed;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,28 +34,36 @@ trait HasCheckable
|
|||
return Str::snake(class_basename(__CLASS__));
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核中
|
||||
*/
|
||||
public function checkProcessing(): bool
|
||||
{
|
||||
return $this->workflow->check_status === CheckStatus::Processing;
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核通过
|
||||
*/
|
||||
public function checkSuccess()
|
||||
public function checkSuccess(): bool
|
||||
{
|
||||
|
||||
return $this->workflow->check_status === CheckStatus::Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核未通过
|
||||
*/
|
||||
public function checkFail()
|
||||
public function checkFail(): bool
|
||||
{
|
||||
|
||||
return $this->workflow->check_status === CheckStatus::Fail;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消申请
|
||||
*/
|
||||
public function checkCancel()
|
||||
public function checkCancel(): bool
|
||||
{
|
||||
|
||||
return $this->workflow->check_status === CheckStatus::Cancel;
|
||||
}
|
||||
|
||||
public function canUpdate(): bool
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ class WorkflowSeeder extends Seeder
|
|||
['key' => 'store_master_commission', 'name' => '店长提成', 'config' => $config, 'created_at' => now(), 'updated_at' => now()],
|
||||
['key' => 'employee_promotion', 'name' => '升职申请', 'config' => $config, 'created_at' => now(), 'updated_at' => now()],
|
||||
['key' => 'agreement', 'name' => '合同审核', 'config' => $config, 'created_at' => now(), 'updated_at' => now()],
|
||||
['key' => 'task_hygiene', 'name' => '清洁卫生', 'config' => $config, 'created_at' => now(), 'updated_at' => now()],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ return [
|
|||
'name' => '任务名称',
|
||||
'status' => '状态',
|
||||
'completed_at' => '完成时间',
|
||||
'created_at' => '创建时间',
|
||||
'created_at' => '发布时间',
|
||||
],
|
||||
|
||||
'task_ledger' => [
|
||||
|
|
|
|||
|
|
@ -55,8 +55,10 @@ Route::group([
|
|||
// 数据上报
|
||||
Route::apiResource('/ledgers', LedgerController::class)->only(['store', 'show']);
|
||||
|
||||
// 任务列表
|
||||
// 我的任务 - 任务列表
|
||||
Route::get('tasks', [TaskController::class, 'index']);
|
||||
// 我的任务 - 提交任务
|
||||
Route::post('tasks/{task}/submit', [TaskController::class, 'submit']);
|
||||
|
||||
// 举报投诉
|
||||
Route::post('complaints', [ComplaintController::class, 'store']);
|
||||
|
|
|
|||
Loading…
Reference in New Issue