From afaa14d58d8003b837f47d69508e09217a3e2aff Mon Sep 17 00:00:00 2001 From: panliang <1163816051@qq.com> Date: Wed, 27 Mar 2024 14:04:24 +0800 Subject: [PATCH] =?UTF-8?q?=20admin=20=E5=AE=A1=E6=A0=B8=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Store/StoreController.php | 41 +------ .../Controllers/System/WorkflowController.php | 105 ++++++++++++++++++ app/Admin/Services/WorkFlowService.php | 59 ++++++++++ app/Admin/routes.php | 3 + app/Contracts/Checkable.php | 22 ++++ app/Enums/CheckStatus.php | 47 ++++++++ app/Enums/CheckType.php | 22 ++++ app/Models/Employee.php | 5 + app/Models/Workflow.php | 17 +++ app/Models/WorkflowLog.php | 11 ++ ...24_03_27_113404_create_workflows_table.php | 52 +++++++++ database/seeders/AdminPermissionSeeder.php | 10 +- database/seeders/WorkflowSeeder.php | 18 +++ lang/zh_CN/workflow.php | 12 ++ 14 files changed, 384 insertions(+), 40 deletions(-) create mode 100644 app/Admin/Controllers/System/WorkflowController.php create mode 100644 app/Admin/Services/WorkFlowService.php create mode 100644 app/Contracts/Checkable.php create mode 100644 app/Enums/CheckStatus.php create mode 100644 app/Enums/CheckType.php create mode 100644 app/Models/Workflow.php create mode 100644 app/Models/WorkflowLog.php create mode 100644 database/migrations/2024_03_27_113404_create_workflows_table.php create mode 100644 database/seeders/WorkflowSeeder.php create mode 100644 lang/zh_CN/workflow.php diff --git a/app/Admin/Controllers/Store/StoreController.php b/app/Admin/Controllers/Store/StoreController.php index 1baa6bb..ba58c3f 100644 --- a/app/Admin/Controllers/Store/StoreController.php +++ b/app/Admin/Controllers/Store/StoreController.php @@ -4,7 +4,7 @@ namespace App\Admin\Controllers\Store; use App\Models\{Store, Employee}; use Illuminate\Http\Request; -use App\Enums\{BusinessStatus, StoreRole}; +use App\Enums\{BusinessStatus, StoreRole, EmployeeStatus}; use App\Admin\Services\StoreService; use Slowlyo\OwlAdmin\Admin; use Slowlyo\OwlAdmin\Renderers\Form; @@ -81,9 +81,10 @@ class StoreController extends AdminController return $this->baseForm()->title('')->body([ amisMake()->TextControl()->name('title')->label(__('store.title'))->required(), amisMake()->SelectControl()->name('master_id')->label(__('store.master_id')) - ->source(admin_url('hr/employees?_action=getData')) + ->source(admin_url('hr/employees?_action=getData&_all=1&employee_status=' . EmployeeStatus::Online->value)) ->labelField('name') ->valueField('id') + ->searchable() ->required(), amisMake()->TreeSelectControl()->name('category_id')->label(__('store.category_id')) ->source(admin_url('api/keywords/tree-list?parent_key=store_category')) @@ -121,40 +122,4 @@ class StoreController extends AdminController ]); return $this->baseDetail()->title('')->body([$detail]); } - - public function employees($id) - { - $store = Store::findOrFail($id); - $list = $store->employees()->wherePivot('role', StoreRole::Employee)->get(); - return $this->response()->success($list); - } - - public function employeeAdd($id, Request $request) - { - $employees = $request->input('employees'); - $store = Store::findOrFail($id); - $service = $this->service; - if ($service->attachEmployee($store, $employees)) { - return $this->response()->success(); - } - return $this->response()->fail($service->getError()); - } - - public function employeeDestroy($id, Request $request) - { - $employees = $request->input('employees'); - $store = Store::findOrFail($id); - $service = $this->service; - if ($service->destroyEmployee($store, is_array($employees) ? $employees : explode(',', $employees))) { - return $this->response()->success(); - } - return $this->response()->fail($service->getError()); - } - - public function employeeOptions() - { - $ignore = DB::table('store_employees')->pluck('employee_id'); - $list = Employee::select(['name as label', 'id as value', 'phone'])->whereNotIn('id', $ignore)->get(); - return $this->response()->success($list); - } } diff --git a/app/Admin/Controllers/System/WorkflowController.php b/app/Admin/Controllers/System/WorkflowController.php new file mode 100644 index 0000000..65e62c7 --- /dev/null +++ b/app/Admin/Controllers/System/WorkflowController.php @@ -0,0 +1,105 @@ +baseCRUD() + ->tableLayout('fixed') + ->headerToolbar([ + $this->createButton(), + ...$this->baseHeaderToolBar(), + ]) + ->bulkActions([]) + ->filter($this->baseFilter()->body([ + amis()->GroupControl()->mode('horizontal')->body([ + amisMake()->TextControl()->name('search')->label(__('admin.keyword'))->placeholder(__('workflow.key') . '/' . __('workflow.name'))->columnRatio(3)->clearable(), + ]) + ])) + ->columns([ + amisMake()->TableColumn()->name('id')->label(__('workflow.id')), + amisMake()->TableColumn()->name('key')->label(__('workflow.key')), + amisMake()->TableColumn()->name('name')->label(__('workflow.name')), + $this->rowActions([ + $this->rowShowButton(), + $this->rowEditButton(), + $this->rowDeleteButton(), + ]), + ]); + + return $this->baseList($crud); + } + + public function form($edit): Form + { + return $this->baseForm()->title('')->body([ + amisMake()->TextControl()->name('key')->label(__('workflow.key'))->required(), + amisMake()->TextControl()->name('name')->label(__('workflow.name'))->required(), + amisMake()->ArrayControl()->name('config')->label(__('workflow.config'))->items(amisMake()->ComboControl()->items([ + amisMake()->SelectControl()->options(CheckType::options())->name('type')->label(__('workflow.type')), + amisMake()->SelectControl() + ->options($this->getJobOptions()) + ->labelField('name') + ->valueField('key') + ->name('job') + // ->visibleOn('${config.type == '.CheckType::Job->value.'}') + ->label(CheckType::Job->text()), + amisMake()->SelectControl() + ->options($this->getEmployeeOptions()) + ->labelField('name') + ->valueField('id') + ->searchable() + ->name('user') + // ->visibleOn('${config.type == '.CheckType::User->value.'}') + ->label(CheckType::User->text()), + ])), + ]); + } + + public function detail(): Form + { + $detail = amisMake()->Property()->items([ + ['label' => __('workflow.key'), 'content' => '${key}'], + ['label' => __('workflow.name'), 'content' => '${name}'], + ['label' => __('workflow.config'), 'content' => amisMake()->Steps()->labelPlacement('horizontal')->source('${config}'), 'span' => 3], + ]); + return $this->baseDetail()->title('')->body($detail); + } + + public function getJobOptions() + { + if (!$this->jobOptions) { + $this->jobOptions = Keyword::where('parent_key', 'job')->get(); + } + + return $this->jobOptions; + } + + public function getEmployeeOptions() + { + if (!$this->employeeOptions) { + $this->employeeOptions = Employee::enable()->get(); + } + + return $this->employeeOptions; + } + +} diff --git a/app/Admin/Services/WorkFlowService.php b/app/Admin/Services/WorkFlowService.php new file mode 100644 index 0000000..458fd5f --- /dev/null +++ b/app/Admin/Services/WorkFlowService.php @@ -0,0 +1,59 @@ + &$item) { + $item['title'] = match($item['type']) { + CheckType::Job->value => CheckType::Job->text(), + CheckType::User->value => CheckType::User->text(), + }; + $item['subTitle'] = match($item['type']) { + CheckType::Job->value => Keyword::where('key', $item['job'])->value('name'), + CheckType::User->value => Employee::where('id', $item['user'])->value('name'), + }; + $item['value'] = match($item['type']) { + CheckType::Job->value => $item['job'], + CheckType::User->value => $item['user'], + }; + $item['sort'] = $key + 1; + } + } + return $data; + } + + public function validate($data, $model = null) + { + $createRules = [ + 'key' => ['required', Rule::unique('workflows', 'key')], + 'name' => ['required'], + ]; + $updateRules = [ + 'key' => [Rule::unique('workflows', 'key')->ignore($model?->id)] + ]; + $validator = Validator::make($data, $model ? $updateRules : $createRules, [ + 'key.unique' => ':input 已经存在' + ]); + if ($validator->fails()) { + return $validator->errors()->first(); + } + return true; + } +} \ No newline at end of file diff --git a/app/Admin/routes.php b/app/Admin/routes.php index 5b4f669..7a87064 100644 --- a/app/Admin/routes.php +++ b/app/Admin/routes.php @@ -10,6 +10,7 @@ use App\Admin\Controllers\System\AdminRoleController; use App\Admin\Controllers\System\AdminUserController; use App\Admin\Controllers\BaseKeywordController; use App\Admin\Controllers\System\KeywordController; +use App\Admin\Controllers\System\WorkflowController; use Illuminate\Routing\Router; use Illuminate\Support\Facades\Route; @@ -98,6 +99,8 @@ Route::group([ $router->resource('settings', \App\Admin\Controllers\SettingController::class); // 数据字典 $router->resource('keywords', KeywordController::class); + + $router->resource('workflows', WorkflowController::class); }); $router->resource('articles', \App\Admin\Controllers\ArticleController::class); diff --git a/app/Contracts/Checkable.php b/app/Contracts/Checkable.php new file mode 100644 index 0000000..43f67e7 --- /dev/null +++ b/app/Contracts/Checkable.php @@ -0,0 +1,22 @@ +value => '未审核', + static::Processing->value => '审核中', + static::Success->value => '审核通过', + static::Fail->value => '审核不通过', + static::Cancel->value => '已取消', + ]; + } + + public function text() + { + return data_get(self::options(), $this->value); + } + + public static function coplorMap() + { + // 'active' | 'inactive' | 'error' | 'success' | 'processing' | 'warning' | + return [ + static::None->value => 'active', + static::Processing->value => 'processing', + static::Success->value => 'success', + static::Fail->value => 'error', + static::Cancel->value => 'inactive', + ]; + } + + public function color() + { + return data_get(self::coplorMap(), $this->value); + } +} diff --git a/app/Enums/CheckType.php b/app/Enums/CheckType.php new file mode 100644 index 0000000..df2072c --- /dev/null +++ b/app/Enums/CheckType.php @@ -0,0 +1,22 @@ +value => '职务', + self::User->value => '员工', + ]; + } + + public function text() + { + return data_get(self::options(), $this->value); + } +} diff --git a/app/Models/Employee.php b/app/Models/Employee.php index fcab8f5..52faed0 100644 --- a/app/Models/Employee.php +++ b/app/Models/Employee.php @@ -61,6 +61,11 @@ class Employee extends Model return $this->belongsToMany(Store::class, 'store_employees', 'employee_id', 'store_id')->withPivot(['role']); } + public function scopeEnable($q) + { + return $q->where('employee_status', EmployeeStatus::Online); + } + protected function employeeStatusText(): Attribute { return new Attribute( diff --git a/app/Models/Workflow.php b/app/Models/Workflow.php new file mode 100644 index 0000000..5cff090 --- /dev/null +++ b/app/Models/Workflow.php @@ -0,0 +1,17 @@ + 'array' + ]; +} diff --git a/app/Models/WorkflowLog.php b/app/Models/WorkflowLog.php new file mode 100644 index 0000000..10ceb97 --- /dev/null +++ b/app/Models/WorkflowLog.php @@ -0,0 +1,11 @@ +id(); + $table->string('key')->unique(); + $table->string('name')->comment('名称'); + $table->json('config')->nullable()->comment('流程配置{type,value,sort}'); + $table->timestamps(); + + $table->comment('审核流程'); + }); + + Schema::create('workflow_logs', function (Blueprint $table) { + $table->id(); + $table->unsignedBigInteger('batch_id')->comment('批次号(为同一批审核流程设置一个ID)'); + $table->string('check_type')->comment('审核类型{job, user}'); + $table->string('check_value')->comment('审核类型值'); + $table->string('check_name')->comment('审核名称(展示用)'); + $table->unsignedBigInteger('user_id')->comment('申请人(employees.id)'); + $table->nullableMorphs('subject'); + $table->json('subject_data')->nullable('审核内容'); + $table->unsignedTinyInteger('is_enable')->default(0)->comment('操作状态(0: 不可操作, 1: 可操作)'); + $table->unsignedBigInteger('check_user_id')->nullable()->comment('实际审核人(admin_users.id)'); + $table->timestamp('checked_at')->nullable()->comment('审核时间'); + $table->string('remarks')->nullable()->comment('审核备注'); + $table->unsignedTinyInteger('check_status')->default(0)->comment('审核状态(0: 待审核, 1: 审核通过, 2: 审核不通过)'); + $table->unsignedInteger('sort')->default(0)->comment('顺序(asc)'); + $table->timestamps(); + + $table->comment('审核流水'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('workflows'); + } +}; diff --git a/database/seeders/AdminPermissionSeeder.php b/database/seeders/AdminPermissionSeeder.php index 2c29890..7b1f9c0 100644 --- a/database/seeders/AdminPermissionSeeder.php +++ b/database/seeders/AdminPermissionSeeder.php @@ -15,8 +15,8 @@ class AdminPermissionSeeder extends Seeder */ public function run() { - // AdminMenu::truncate(); - // AdminPermission::truncate(); + AdminMenu::truncate(); + AdminPermission::truncate(); $data = [ /* |-------------------------------------------------------------------------- @@ -168,6 +168,12 @@ class AdminPermissionSeeder extends Seeder 'resource' => ['list', 'create', 'update', 'delete'], 'children' => [], ], + 'workflows' => [ + 'name' => '审核流程', + 'icon' => '', + 'uri' => '/system/workflows', + 'resource' => true, + ], ], ], ]; diff --git a/database/seeders/WorkflowSeeder.php b/database/seeders/WorkflowSeeder.php new file mode 100644 index 0000000..2859fe2 --- /dev/null +++ b/database/seeders/WorkflowSeeder.php @@ -0,0 +1,18 @@ + 'ID', + 'created_at' => '创建时间', + 'updated_at' => '更新时间', + 'key' => 'KEY', + 'name' => '名称', + 'config' => '流程配置', + 'type' => '审核类型', + 'value' => '审核人', +];