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(), ]), ])) ->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('${title}') ), '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::Pending->value.' and 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::Pending->value.' and 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::Pending->value.' and 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 => ''.$this->planableTypeOptions()[$planableTypeLedger ].'', $planableTypePerformance => ''.$this->planableTypeOptions()[$planableTypePerformance ].'', $planableTypeHygiene => ''.$this->planableTypeOptions()[$planableTypeHygiene ].'', ]; } }