generated from liutk/owl-admin-base
472 lines
21 KiB
PHP
472 lines
21 KiB
PHP
<?php
|
|
|
|
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\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;
|
|
use Slowlyo\OwlAdmin\Renderers\AjaxAction;
|
|
use Slowlyo\OwlAdmin\Renderers\Drawer;
|
|
use Slowlyo\OwlAdmin\Renderers\DrawerAction;
|
|
use Slowlyo\OwlAdmin\Renderers\Form;
|
|
use Slowlyo\OwlAdmin\Renderers\Page;
|
|
use Throwable;
|
|
|
|
/**
|
|
* @property PlanService $service
|
|
*/
|
|
class PlanController extends AdminController
|
|
{
|
|
protected string $serviceName = PlanService::class;
|
|
|
|
public function list(): Page
|
|
{
|
|
$crud = $this->baseCRUD()
|
|
->headerToolbar([
|
|
$this->createTypeButton('drawer', 'lg')
|
|
->visible(Admin::user()->can('admin.plan.plans.create')),
|
|
...$this->baseHeaderToolBar(),
|
|
])
|
|
->bulkActions([])
|
|
->filter($this->baseFilter()->body([
|
|
amis()->GroupControl()->mode('horizontal')->body([
|
|
amis()->TextControl()
|
|
->name('name')
|
|
->label(__('plan.plan.name'))
|
|
->placeholder(__('plan.plan.name'))
|
|
->clearable(),
|
|
|
|
amis()->SelectControl()
|
|
->name('planable_type')
|
|
->label(__('plan.plan.type'))
|
|
->multiple()
|
|
->options($this->planableTypeOptions())
|
|
->clearable(),
|
|
|
|
amis()->SelectControl()
|
|
->name('plan_status')
|
|
->label(__('plan.plan.status'))
|
|
->multiple()
|
|
->options(PlanStatus::options())
|
|
->clearable(),
|
|
]),
|
|
]))
|
|
->filterDefaultVisible()
|
|
->columns([
|
|
amis()->TableColumn('id', __('plan.plan.id')),
|
|
amis()->TableColumn('name', __('plan.plan.name')),
|
|
amis()->TableColumn('planable_type', __('plan.plan.type'))->type('mapping')->map($this->planableTypeLabelMap()),
|
|
amis()->TableColumn('plan_status', __('plan.plan.status'))->type('mapping')->map(PlanStatus::labelMap()),
|
|
amis()->TableColumn('created_at', __('plan.plan.created_at')),
|
|
$this->rowActions([
|
|
$this->rowPublishButton()
|
|
->visible(Admin::user()->can('admin.plan.plans.publish'))
|
|
->visibleOn('${plan_status == '.PlanStatus::Pending->value.'}'),
|
|
$this->rowEditTypeButton('drawer', 'lg')
|
|
->visible(Admin::user()->can('admin.plan.plans.update'))
|
|
->visibleOn('${plan_status == '.PlanStatus::Pending->value.'}'),
|
|
$this->rowDeleteButton()
|
|
->visible(Admin::user()->can('admin.plan.plans.delete'))
|
|
->visibleOn('${plan_status == '.PlanStatus::Pending->value.'}'),
|
|
$this->rowShowButton()
|
|
->visible(Admin::user()->can('admin.plan.plans.view')),
|
|
]),
|
|
]);
|
|
|
|
return $this->baseList($crud);
|
|
}
|
|
|
|
public function form(): Form
|
|
{
|
|
$planableTypePerformance = (new PlanPerformance())->getMorphClass();
|
|
$planableTypeHygiene = (new PlanHygiene())->getMorphClass();
|
|
|
|
return $this->baseForm()->title('')->body([
|
|
amis()->SelectControl()
|
|
->name('planable_type')
|
|
->label(__('plan.plan.type'))
|
|
->options(Arr::except($this->planableTypeOptions(), [(new PlanLedger())->getMorphClass()]))
|
|
->required()
|
|
->disabledOn('${planable_id > 0}'),
|
|
|
|
amis()->TextControl()
|
|
->name('name')
|
|
->label(__('plan.plan.name'))
|
|
->placeholder(__('plan.plan.name'))
|
|
->required(),
|
|
|
|
// 业绩指标
|
|
amis()->MonthControl()
|
|
->name('plan_performance[month]')
|
|
->label(__('plan.plan_performance.month'))
|
|
->value('${planable.month}')
|
|
->required()
|
|
->valueFormat('YYYY-MM')
|
|
->visibleOn('${planable_type == "'.$planableTypePerformance.'"}'),
|
|
amis()->TreeSelectControl()
|
|
->name('plan_performance[store_category_id]')
|
|
->label(__('plan.plan_performance.store_category'))
|
|
->source(admin_url('api/keywords/tree-list?parent_key=store_category'))
|
|
->labelField('name')
|
|
->valueField('key')
|
|
->onlyLeaf(true)
|
|
->value('${planable.store_category_id}')
|
|
->required()
|
|
->visibleOn('${planable_type == "'.$planableTypePerformance.'"}'),
|
|
amis()->SelectControl()
|
|
->name('plan_performance[store_level_id]')
|
|
->label(__('plan.plan_performance.store_level'))
|
|
->source(admin_url('api/keywords/tree-list?parent_key=store_level'))
|
|
->labelField('name')
|
|
->valueField('key')
|
|
->value('${planable.store_level_id}')
|
|
->clearable()
|
|
->visibleOn('${planable_type == "'.$planableTypePerformance.'"}'),
|
|
amis()->NumberControl()
|
|
->name('plan_performance[performance]')
|
|
->label(__('plan.plan_performance.performance'))
|
|
->placeholder(__('plan.plan_performance.performance'))
|
|
->value('${planable.performance}')
|
|
->precision(2)
|
|
->showSteps(false)
|
|
->required()
|
|
->visibleOn('${planable_type == "'.$planableTypePerformance.'"}'),
|
|
|
|
// 清洁卫生
|
|
amis()->MonthControl()
|
|
->name('plan_hygiene[month]')
|
|
->label(__('plan.plan_hygiene.month'))
|
|
->value('${planable.month}')
|
|
->required()
|
|
->valueFormat('YYYY-MM')
|
|
->visibleOn('${planable_type == "'.$planableTypeHygiene.'"}'),
|
|
amis()->SelectControl()
|
|
->name('plan_hygiene[store_ids]')
|
|
->label(__('plan.plan_hygiene.store'))
|
|
->value('${planable.store_ids}')
|
|
->multiple()
|
|
->joinValues(false)
|
|
->extractValue(true)
|
|
->source(admin_url('api/stores?_all=1'))
|
|
->labelField('title')
|
|
->valueField('id')
|
|
->searchable()
|
|
->visibleOn('${planable_type == "'.$planableTypeHygiene.'"}'),
|
|
]);
|
|
}
|
|
|
|
public function detail(): Form
|
|
{
|
|
$planableTypeLedger = (new PlanLedger())->getMorphClass();
|
|
$planableTypePerformance = (new PlanPerformance())->getMorphClass();
|
|
$planableTypeHygiene = (new PlanHygiene())->getMorphClass();
|
|
|
|
return $this->baseDetail()->title('')->body([
|
|
amis()->Property()->items([
|
|
['label' => __('plan.plan.name'), 'content' => '${name}'],
|
|
['label' => __('plan.plan.type'), 'content' => amis()->Mapping()->name('planable_type')->map($this->planableTypeLabelMap())],
|
|
['label' => __('plan.plan.status'), 'content' => amis()->Mapping()->name('plan_status')->map(PlanStatus::labelMap())],
|
|
// 总账录入
|
|
['label' => __('plan.plan_ledger.date'), 'content' => '${planable.date}', 'visibleOn' => '${planable_type == "'.$planableTypeLedger.'"}'],
|
|
// 业绩指标
|
|
['label' => __('plan.plan_performance.month'), 'content' => '${planable.month}', 'visibleOn' => '${planable_type == "'.$planableTypePerformance.'"}'],
|
|
['label' => __('plan.plan_performance.store_category'), 'content' => '${planable.store_category.name}', 'visibleOn' => '${planable_type == "'.$planableTypePerformance.'"}'],
|
|
['label' => __('plan.plan_performance.store_level'), 'content' => '${planable.store_level.name}', 'visibleOn' => '${planable_type == "'.$planableTypePerformance.'"}'],
|
|
['label' => __('plan.plan_performance.performance'), 'content' => '${planable.performance}', 'visibleOn' => '${planable_type == "'.$planableTypePerformance.'"}'],
|
|
// 清洁卫生
|
|
['label' => __('plan.plan_hygiene.month'), 'content' => '${planable.month}', 'visibleOn' => '${planable_type == "'.$planableTypeHygiene.'"}'],
|
|
[
|
|
'label' => __('plan.plan_hygiene.store'),
|
|
'content' => amis()->Each()
|
|
->name('planable.stores')
|
|
->items(
|
|
amis()->Tpl()->tpl('<span class="label label-primary m-l-sm">${title}</span>')
|
|
),
|
|
'visibleOn' => '${planable_type == "'.$planableTypeHygiene.'"}',
|
|
],
|
|
]),
|
|
|
|
amis()->Divider(),
|
|
|
|
// 总账录入
|
|
amis()->CRUDTable()
|
|
->api(admin_url('api/tasks?plan_id=${id}'))
|
|
->columns([
|
|
amis()->TableColumn('taskable.date', __('plan.task_ledger.date')),
|
|
amis()->TableColumn('taskable.store.title', __('plan.task_ledger.store')),
|
|
amis()->TableColumn('taskable.store_master.name', __('plan.task_ledger.store_master')),
|
|
amis()->TableColumn('taskable.task_status', __('plan.task_ledger.status'))->type('mapping')->map(TaskLedgerStatus::labelMap()),
|
|
amis()->TableColumn('completed_at', __('plan.task.completed_at')),
|
|
amis()->TableColumn('created_at', __('plan.task.created_at')),
|
|
])
|
|
->visibleOn('${plan_status == '.PlanStatus::Published->value.' && planable_type == "'.$planableTypeLedger.'"}'),
|
|
|
|
// 业绩指标
|
|
amis()->CRUDTable()
|
|
->name('task-performance-table')
|
|
->api(admin_url('api/tasks?plan_id=${id}'))
|
|
->headerToolbar([
|
|
$this->taskCreateButton()
|
|
->visible(Admin::user()->can('admin.plan.plans.task_create')),
|
|
amis('reload')->align('right'),
|
|
])
|
|
->columns([
|
|
amis()->TableColumn('taskable.month', __('plan.task_performance.month')),
|
|
amis()->TableColumn('taskable.store.title', __('plan.task_performance.store')),
|
|
amis()->TableColumn('taskable.store_master.name', __('plan.task_performance.store_master')),
|
|
amis()->TableColumn('taskable.actual_performance', __('plan.task_performance.actual_performance')),
|
|
amis()->TableColumn('taskable.expected_performance', __('plan.task_performance.expected_performance')),
|
|
amis()->TableColumn('taskable.task_status', __('plan.task_performance.status'))->type('mapping')->map(TaskPerformanceStatus::labelMap()),
|
|
amis()->TableColumn('completed_at', __('plan.task.completed_at')),
|
|
amis()->TableColumn('created_at', __('plan.task.created_at')),
|
|
$this->rowActions([
|
|
$this->taskRowEditButton()
|
|
->visible(Admin::user()->can('admin.plan.plans.task_update')),
|
|
$this->taskRowDeleteButton()
|
|
->visible(Admin::user()->can('admin.plan.plans.task_delete')),
|
|
]),
|
|
])
|
|
->visibleOn('${plan_status == '.PlanStatus::Published->value.' && planable_type == "'.$planableTypePerformance.'"}'),
|
|
|
|
// 清洁卫生
|
|
amis()->CRUDTable()
|
|
->name('task-hygiene-table')
|
|
->api(admin_url('api/tasks?plan_id=${id}'))
|
|
->headerToolbar([
|
|
$this->taskCreateButton()
|
|
->visible(Admin::user()->can('admin.plan.plans.task_create')),
|
|
amis('reload')->align('right'),
|
|
])
|
|
->columns([
|
|
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('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([
|
|
$this->taskRowShowButton()
|
|
->visible(Admin::user()->can('admin.plan.plans.task_view')),
|
|
$this->taskRowDeleteButton()
|
|
->visible(Admin::user()->can('admin.plan.plans.task_delete')),
|
|
]),
|
|
])
|
|
->visibleOn('${plan_status == '.PlanStatus::Published->value.' && planable_type == "'.$planableTypeHygiene.'"}'),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 发布任务计划
|
|
*/
|
|
public function publish($id)
|
|
{
|
|
try {
|
|
DB::transaction(fn () => $this->service->publish($id));
|
|
} catch (Throwable $th) {
|
|
return $this->renderException($th);
|
|
}
|
|
|
|
return $this->response()->successMessage('发布成功');
|
|
}
|
|
|
|
/**
|
|
* 行发布按钮
|
|
*/
|
|
protected function rowPublishButton(): AjaxAction
|
|
{
|
|
return amis()->AjaxAction()
|
|
->label('发布')
|
|
->icon('fa fa-send-o')
|
|
->level('link')
|
|
->confirmText('是否发布选中的任务计划?')
|
|
->api('post:' . admin_url('/plan/plans/${id}/publish'));
|
|
}
|
|
|
|
/**
|
|
* 任务 - 创建按钮
|
|
*/
|
|
protected function taskCreateButton(): DrawerAction
|
|
{
|
|
$planableTypePerformance = (new PlanPerformance())->getMorphClass();
|
|
$planableTypeHygiene = (new PlanHygiene())->getMorphClass();
|
|
|
|
$form = amis()->Form()
|
|
->title('')
|
|
->api('post:'.admin_url('/plan/tasks'))
|
|
->redirect('')
|
|
->body([
|
|
amis()->HiddenControl('plan_id')->value('${id}'),
|
|
// 业绩指标
|
|
amis()->SelectControl('task_performance[store_id]', __('plan.task_performance.store'))
|
|
->source(admin_url('api/stores'))
|
|
->labelField('title')
|
|
->valueField('id')
|
|
->clearable()
|
|
->required()
|
|
->visibleOn('${planable_type == "'.$planableTypePerformance.'"}'),
|
|
amis()->NumberControl()
|
|
->name('task_performance[expected_performance]')
|
|
->label(__('plan.task_performance.expected_performance'))
|
|
->placeholder(__('plan.task_performance.expected_performance'))
|
|
->precision(2)
|
|
->showSteps(false)
|
|
->required()
|
|
->visibleOn('${planable_type == "'.$planableTypePerformance.'"}'),
|
|
// 清洁卫生
|
|
amis()->SelectControl('task_hygiene[store_id]', __('plan.task_hygiene.store'))
|
|
->source(admin_url('api/stores'))
|
|
->labelField('title')
|
|
->valueField('id')
|
|
->clearable()
|
|
->required()
|
|
->visibleOn('${planable_type == "'.$planableTypeHygiene.'"}'),
|
|
])
|
|
->reload('task-performance-table,task-hygiene-table');
|
|
|
|
return DrawerAction::make()
|
|
->label(__('admin.create'))
|
|
->icon('fa fa-add')
|
|
->level('primary')
|
|
->drawer(
|
|
Drawer::make()
|
|
->title(__('admin.create'))
|
|
->size('lg')
|
|
->closeOnOutside()
|
|
->body($form)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 任务 - 行编辑按钮
|
|
*/
|
|
protected function taskRowEditButton(): DrawerAction
|
|
{
|
|
$planableTypePerformance = (new PlanPerformance())->getMorphClass();
|
|
|
|
$form = amis()->Form()
|
|
->title('')
|
|
->api('put:'.admin_url('/plan/tasks/${id}'))
|
|
->redirect('')
|
|
->body([
|
|
amis()->HiddenControl('id'),
|
|
// 任务指标
|
|
amis()->NumberControl()
|
|
->name('task_performance[expected_performance]')
|
|
->label(__('plan.task_performance.expected_performance'))
|
|
->value('${taskable.expected_performance}')
|
|
->precision(2)
|
|
->showSteps(false)
|
|
->required()
|
|
->visibleOn('${planable_type == "'.$planableTypePerformance.'"}'),
|
|
])
|
|
->reload('task-performance-table');
|
|
|
|
return DrawerAction::make()
|
|
->label(__('admin.edit'))
|
|
->icon('fa-regular fa-pen-to-square')
|
|
->level('link')
|
|
->drawer(
|
|
Drawer::make()
|
|
->title(__('admin.edit'))
|
|
->size('lg')
|
|
->closeOnOutside()
|
|
->body($form)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 任务 - 行查看按钮
|
|
*/
|
|
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 (new TaskController())->rowDeleteButton()->api('delete:'.admin_url('/plan/tasks/${id}'));
|
|
}
|
|
|
|
protected function planableTypeOptions(): array
|
|
{
|
|
return [
|
|
(new PlanLedger())->getMorphClass() => '总账录入',
|
|
(new PlanPerformance())->getMorphClass() => '业绩指标',
|
|
(new PlanHygiene())->getMorphClass() => '清洁卫生',
|
|
];
|
|
}
|
|
|
|
protected function planableTypeLabelMap(): array
|
|
{
|
|
$planableTypeLedger = (new PlanLedger())->getMorphClass();
|
|
$planableTypePerformance = (new PlanPerformance())->getMorphClass();
|
|
$planableTypeHygiene = (new PlanHygiene())->getMorphClass();
|
|
|
|
return [
|
|
$planableTypeLedger => '<span class="label label-primary">'.$this->planableTypeOptions()[$planableTypeLedger ].'</span>',
|
|
$planableTypePerformance => '<span class="label label-danger">'.$this->planableTypeOptions()[$planableTypePerformance ].'</span>',
|
|
$planableTypeHygiene => '<span class="label label-success">'.$this->planableTypeOptions()[$planableTypeHygiene ].'</span>',
|
|
];
|
|
}
|
|
}
|