清洁任务审批流程

main
Jing Li 2024-04-21 17:49:56 +08:00
parent 9b5184cbbf
commit da9b11de12
11 changed files with 174 additions and 27 deletions

View File

@ -4,14 +4,15 @@ namespace App\Admin\Controllers\Plan;
use App\Admin\Controllers\AdminController;
use App\Admin\Services\Plan\PlanService;
use App\Enums\CheckStatus;
use App\Enums\PlanStatus;
use App\Enums\TaskHygieneStatus;
use App\Enums\TaskLedgerStatus;
use App\Enums\TaskPerformanceStatus;
use App\Enums\TaskStatus;
use App\Models\PlanHygiene;
use App\Models\PlanLedger;
use App\Models\PlanPerformance;
use App\Models\TaskHygiene;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Slowlyo\OwlAdmin\Admin;
@ -254,6 +255,8 @@ class PlanController extends AdminController
amis()->TableColumn('completed_at', __('plan.task.completed_at')),
amis()->TableColumn('created_at', __('plan.task.created_at')),
$this->rowActions([
$this->taskRowShowButton()
->visible(Admin::user()->can('admin.plan.plans.task_view')),
$this->taskRowDeleteButton()
->visible(Admin::user()->can('admin.plan.plans.task_delete')),
]),
@ -381,17 +384,66 @@ class PlanController extends AdminController
);
}
/**
* 任务 - 行查看按钮
*/
protected function taskRowShowButton(): DrawerAction
{
$taskDetailId = 'task-detail';
$workflowLogListId = 'task-workflow-service';
$detail = $this->baseDetail()
->id($taskDetailId)
->initApi(admin_url('/plan/tasks/${id}?_action=getData'))
->onEvent([
'inited' => [
'actions' => [
['actionType' => 'reload', 'componentId' => $workflowLogListId],
],
],
])
->body([
amis()->Property()->items([
['label' => __('plan.task_hygiene.month'), 'content' => '${taskable.month}'],
['label' => __('plan.task_hygiene.store'), 'content' => '${taskable.store.title}'],
['label' => __('plan.task_hygiene.store_master'), 'content' => '${taskable.store_master.name}'],
['label' => __('plan.task_hygiene.status'), 'content' => amis()->Mapping()->name('taskable.task_status')->map(TaskHygieneStatus::labelMap())],
['label' => __('plan.task.completed_at'), 'content' => '${completed_at}'],
['label' => __('plan.task.created_at'), 'content' => '${created_at}'],
['label' => __('plan.task_hygiene.description'), 'content' => '${taskable.description}', 'span' => 3],
['label' => __('plan.task_hygiene.photos'), 'content' => amis()->Images()->enlargeAble()->source('${taskable.photos}')->enlargeWithGallary(), 'span' => 3],
['label' => __('workflow_log.check_status'), 'content' => amis()->Mapping()->name('taskable.workflow.check_status')->map(CheckStatus::labelMap())],
['label' => __('workflow_log.checked_at'), 'content' => '${taskable.workflow.checked_at}'],
['label' => __('workflow_log.remarks'), 'content' => '${taskable.workflow.check_remarks}'],
]),
amis()->Divider(),
(new TaskController)->baseWorkflowLogList("{$taskDetailId},task-hygiene-table")
->id($workflowLogListId)
->api(admin_url('/api/workflow/logs?id=${taskable.workflow.id}'))
->visibleOn('${taskable_type === "'.(new TaskHygiene())->getMorphClass().'"}'),
]);
$drawer = Drawer::make()
->title(__('admin.show'))
->size('xl')
->closeOnOutside()
->body($detail);
return DrawerAction::make()
->label(__('admin.show'))
->icon('fa fa-eye')
->level('link')
->drawer($drawer);
}
/**
* 任务 - 行删除按钮
*/
protected function taskRowDeleteButton(): AjaxAction
{
return amis()->AjaxAction()
->label(__('admin.delete'))
->icon('fa-regular fa-trash-can')
->level('link')
->confirmText(__('admin.confirm_delete'))
->api('delete:'.admin_url('/plan/tasks/${id}'));
return (new TaskController())->rowDeleteButton()->api('delete:'.admin_url('/plan/tasks/${id}'));
}
protected function planableTypeOptions(): array

View File

@ -5,20 +5,61 @@ namespace App\Admin\Controllers\Plan;
use App\Admin\Controllers\AdminController;
use App\Admin\Filters\TaskFilter;
use App\Admin\Services\Plan\TaskService;
use App\Enums\CheckStatus;
use App\Enums\TaskHygieneStatus;
use App\Models\Task;
use App\Models\TaskHygiene;
use App\Models\TaskLedger;
use App\Models\TaskPerformance;
use App\Traits\HasCheckActions;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Http\Request;
use Slowlyo\OwlAdmin\Renderers\Form;
/**
* @property TaskService $service
*/
class TaskController extends AdminController
{
use HasCheckActions;
protected string $serviceName = TaskService::class;
public function detail(): Form
{
$taskDetailId = 'task-detail';
$workflowLogListId = 'task-workflow-service';
return $this->baseDetail()->id($taskDetailId)->title('')->onEvent([
'inited' => [
'actions' => [
['actionType' => 'reload', 'componentId' => $workflowLogListId],
],
],
])->body([
amis()->Property()->items([
['label' => __('plan.task_hygiene.month'), 'content' => '${taskable.month}'],
['label' => __('plan.task_hygiene.store'), 'content' => '${taskable.store.title}'],
['label' => __('plan.task_hygiene.store_master'), 'content' => '${taskable.store_master.name}'],
['label' => __('plan.task_hygiene.status'), 'content' => amis()->Mapping()->name('taskable.task_status')->map(TaskHygieneStatus::labelMap())],
['label' => __('plan.task.completed_at'), 'content' => '${completed_at}'],
['label' => __('plan.task.created_at'), 'content' => '${created_at}'],
['label' => __('plan.task_hygiene.description'), 'content' => '${taskable.description}', 'span' => 3],
['label' => __('plan.task_hygiene.photos'), 'content' => amis()->Images()->enlargeAble()->source('${taskable.photos}')->enlargeWithGallary(), 'span' => 3],
['label' => __('workflow_log.check_status'), 'content' => amis()->Mapping()->name('taskable.workflow.check_status')->map(CheckStatus::labelMap())],
['label' => __('workflow_log.checked_at'), 'content' => '${taskable.workflow.checked_at}'],
['label' => __('workflow_log.remarks'), 'content' => '${taskable.workflow.check_remarks}'],
]),
amis()->Divider(),
$this->baseWorkflowLogList($taskDetailId)
->id($workflowLogListId)
->api(admin_url('/api/workflow/logs?id=${taskable.workflow.id}'))
->visibleOn('${taskable_type === "'.(new TaskHygiene())->getMorphClass().'"}'),
]);
}
public function shareList(Request $request)
{
$tasks = Task::filter($request->input(), TaskFilter::class)

View File

@ -52,9 +52,7 @@ class PlanService extends BaseService
],
);
$planableType = Relation::getMorphedModel($data['planable_type']);
switch ($planableType) {
switch (Relation::getMorphedModel($data['planable_type'])) {
// 清洁卫生
case PlanHygiene::class:
$payload = $data['plan_hygiene'] ?? [];
@ -69,7 +67,7 @@ class PlanService extends BaseService
],
);
$planable = PlanPerformance::create($payload);
$planable = PlanHygiene::create($payload);
$planable->plan()->create([
'name' => $data['name'],

View File

@ -12,8 +12,10 @@ use App\Models\PlanPerformance;
use App\Models\Store;
use App\Models\Task;
use App\Models\TaskHygiene;
use App\Models\TaskLedger;
use App\Models\TaskPerformance;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Validator;
@ -27,6 +29,15 @@ class TaskService extends BaseService
protected string $modelFilterName = TaskFilter::class;
public function getDetail($id)
{
if ($task = parent::getDetail($id)) {
$task->taskable->setRelation('task', $task->withoutRelations());
}
return $task;
}
public function store($data): bool
{
if (! isset($data['plan_id'])) {
@ -194,4 +205,19 @@ class TaskService extends BaseService
$tasks->each(fn (Task $task) => $task->taskable()->delete());
}
public function addRelations($query, string $scene = 'list')
{
if (in_array($scene, ['edit', 'detail'])) {
$query->with([
'taskable' => function (MorphTo $morphTo) {
$morphTo->morphWith([
TaskLedger::class => ['store', 'storeMaster'],
TaskPerformance::class => ['store', 'storeMaster'],
TaskHygiene::class => ['store', 'storeMaster', 'workflow'],
]);
},
]);
}
}
}

View File

@ -28,7 +28,7 @@ class WorkFlowService extends BaseService
*
* @param WorkflowCheck $check 待审核记录
* @param Employee $user 申请人
*
*
* @return bool true: 成功, false: 失败, $this->getError(): 错误消息
*/
public function apply(WorkflowCheck $check, Employee $user)

View File

@ -155,6 +155,7 @@ Route::group([
$router->resource('plans', PlanController::class);
$router->post('/plans/{plan}/publish', [PlanController::class, 'publish'])->name('plans.publish');
$router->post('/tasks', [TaskController::class, 'store'])->name('plans.task_create');
$router->get('/tasks/{task}', [TaskController::class, 'show'])->name('plans.task_view');
$router->put('/tasks/{task}', [TaskController::class, 'update'])->name('plans.task_update');
$router->delete('/tasks/{task}', [TaskController::class, 'destroy'])->name('plans.task_delete');
});

View File

@ -78,7 +78,7 @@ MySQL;
throw tap($th, fn ($th) => report($th));
}
return response()->json();
return response()->noContent();
}
protected function handleTaskSubmit(Task $task, Request $request): void

View File

@ -42,6 +42,11 @@ class TaskHygiene extends Model
return $this->belongsTo(Employee::class, 'store_master_id');
}
public function checkSuccess()
{
$this->task->markAsSuccess();
}
protected function photos(): Attribute
{
return Attribute::make(
@ -69,15 +74,15 @@ class TaskHygiene extends Model
return TaskHygieneStatus::None;
}
if ($this->task->isSuccess() || $this->checkSuccess()) {
if ($this->task->isSuccess() || $this->isCheckSuccess()) {
return TaskHygieneStatus::Success;
}
if ($this->checkProcessing()) {
if ($this->isCheckProcessing()) {
return TaskHygieneStatus::Checking;
}
if ($this->checkFail()) {
if ($this->isCheckFail()) {
return TaskHygieneStatus::Unpassed;
}

View File

@ -35,35 +35,55 @@ trait HasCheckable
}
/**
* 审核
* 审核通过
*/
public function checkProcessing(): bool
public function checkApply()
{
return $this->workflow->check_status === CheckStatus::Processing;
}
/**
* 审核通过
*/
public function checkSuccess(): bool
public function checkSuccess()
{
return $this->workflow->check_status === CheckStatus::Success;
}
/**
* 审核未通过
*/
public function checkFail(): bool
public function checkFail()
{
return $this->workflow->check_status === CheckStatus::Fail;
}
/**
* 取消申请
*/
public function checkCancel(): bool
public function checkCancel()
{
return $this->workflow->check_status === CheckStatus::Cancel;
}
/**
* 是否审核中
*/
public function isCheckProcessing(): bool
{
return $this->workflow->check_status === CheckStatus::Processing;
}
/**
* 是否审核通过
*/
public function isCheckSuccess(): bool
{
return $this->workflow->check_status === CheckStatus::Success;
}
/**
* 是否审核未通过
*/
public function isCheckFail(): bool
{
return $this->workflow->check_status === CheckStatus::Fail;
}
public function canUpdate(): bool

View File

@ -182,18 +182,20 @@ class AdminPermissionSeeder extends Seeder
|--------------------------------------------------------------------------
*/
'plan' => [
'name' => '任务管理',
'name' => '任务计划',
'icon' => 'mingcute:send-plane-line',
'uri' => '/plan',
'order' => 4,
'children' => [
'plans' => [
'name' => '任务列表',
'name' => '任务计划',
'icon' => 'tdesign:task',
'uri' => '/plan/plans',
'resource' => true,
'children' => [
'publish' => '发布',
'task_create' => '创建任务',
'task_view' => '查看任务',
'task_update' => '编辑任务',
'task_delete' => '删除任务',
],

View File

@ -56,5 +56,7 @@ return [
'store' => '门店',
'store_master' => '店长',
'status' => '状态',
'description' => '清洁范围',
'photos' => '清洁结果',
],
];