From 4f686170b61424ce182d81d84bb488a8e6eb436a Mon Sep 17 00:00:00 2001 From: wanghongjun <1445693971@qq.com> Date: Wed, 3 Jun 2026 14:03:11 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=9A=E9=81=93=E7=AE=A1=E7=90=86=E6=9D=83?= =?UTF-8?q?=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Admin/ChannelPermissionsController.php | 238 ++++++++++++++++++ app/Models/AdminChannelRole.php | 34 +++ app/Models/ParkingChannel.php | 56 ++++- app/Services/AdminChannelRoleService.php | 141 +++++++++++ ...143449_create_admin_channel_role_table.php | 34 +++ database/seeders/AdminMenuSeeder.php | 5 +- resources/lang/en/log.php | 5 + resources/lang/en/service.php | 3 + resources/lang/en/validation.php | 5 + resources/lang/zh-CN/log.php | 5 + resources/lang/zh-CN/service.php | 3 + resources/lang/zh-CN/validation.php | 5 + resources/lang/zh-TW/log.php | 5 + resources/lang/zh-TW/service.php | 3 + resources/lang/zh-TW/validation.php | 5 + routes/admin/api.php | 9 + 16 files changed, 542 insertions(+), 14 deletions(-) create mode 100644 app/Http/Controllers/Admin/ChannelPermissionsController.php create mode 100644 app/Models/AdminChannelRole.php create mode 100644 app/Services/AdminChannelRoleService.php create mode 100644 database/migrations/2026_06_03_143449_create_admin_channel_role_table.php diff --git a/app/Http/Controllers/Admin/ChannelPermissionsController.php b/app/Http/Controllers/Admin/ChannelPermissionsController.php new file mode 100644 index 0000000..abd9d29 --- /dev/null +++ b/app/Http/Controllers/Admin/ChannelPermissionsController.php @@ -0,0 +1,238 @@ +service = $service; + } + + /** + * @param Request $request + * @return JsonResponse + */ + public function index(Request $request): JsonResponse + { + try { + $query = AdminChannelRole::query(); + + $memberTypeArr = ParkingAdminUserService::$memberType; + $statusArr = AdminChannelRoleService::getStatus(); + // 分页 + $page = $request->input('page', 1); + $perPage = $request->input('per_page', 10); + $total = $query->count(); + $items = $query->latest()->forPage($page, $perPage)->get()->each( + function ($item) use ($memberTypeArr, $statusArr) { + $item['channel_list'] = ParkingChannel::getChannelData( + $item['channel_ids'] + ); + $item['member_type_str'] + = $memberTypeArr[$item['member_type']]; + $item['status_str'] = $statusArr[$item['status']]; + return $item; + } + ); + + return $this->responseService->success([ + 'items' => $items, + 'total' => $total, + 'page' => $page, + 'per_page' => $perPage, + 'last_page' => ceil($total / $perPage), + ]); + } catch (Exception $e) { + $m_prefix = __('exception.exception_handler.resource'); + return $this->responseService->systemError( + $m_prefix . ':' . $e->getMessage() + ); + } + } + + /** + * @return JsonResponse + */ + public function create(): JsonResponse + { + try { + $data = [ + 'member_type_list' => get_select_data( + ParkingAdminUserService::$memberType + ), + 'channel_list' => ParkingChannel::getData(), + 'status_list' => get_select_data( + AdminChannelRoleService::getStatus() + ) + ]; + return $this->responseService->success($data); + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.get_data_failed') . ':' . $e->getMessage() + ); + } + } + + /** + * @param Request $request + * @return JsonResponse + * @throws CustomException + * @throws ValidationException + */ + public function store(Request $request): JsonResponse + { + try { + $this->saveValidator($request->all()); + $this->service->createModel($request->all()); + return $this->responseService->success( + null, + __('admin.save_succeeded') + ); + } catch (ValidationException|CustomException $e) { + throw $e; + } catch (Exception $e) { + return $this->responseService->systemError( + __('admin.operation_failed') . ':' + . $e->getMessage() + ); + } + } + + /** + * @param array $data + * @param int $id + * @return void + * @throws ValidationException + */ + protected function saveValidator(array $data, int $id = 0): void + { + $rules = [ + 'member_type' => 'required', + 'channel_ids' => 'required|array' + ]; + $messages = [ + 'member_type.required' => __( + 'validation.channel_permissions.m_empty' + ), + 'channel_ids.required' => __( + 'validation.channel_permissions.c_empty' + ), + 'channel_ids.array' => __( + 'validation.channel_permissions.c_array' + ) + ]; + if ($id) { + $this->validateId($id, AdminChannelRole::class); + } + $validator = Validator::make($data, $rules, $messages); + + if ($validator->fails()) { + throw new ValidationException($validator); + } + } + + /** + * @param string $id + * @return JsonResponse + */ + public function edit(string $id): JsonResponse + { + try { + $this->validateId($id, AdminChannelRole::class); + $data = [ + 'member_type_list' => get_select_data( + ParkingAdminUserService::$memberType + ), + 'channel_list' => ParkingChannel::getData(), + 'status_list' => get_select_data( + AdminChannelRoleService::getStatus() + ), + 'item' => AdminChannelRole::query()->find($id) + ]; + return $this->responseService->success($data); + } catch (Exception $e) { + return $this->responseService->systemError( + __('exception.get_data_failed') . ':' . $e->getMessage() + ); + } + } + + /** + * @param Request $request + * @param string $id + * @return JsonResponse + * @throws CustomException + * @throws ValidationException + */ + public function update(Request $request, string $id): JsonResponse + { + try { + $this->saveValidator($request->all(), $id); + $this->service->updateModel($request->all(), $id); + return $this->responseService->success( + null, + __('admin.update_succeeded') + ); + } catch (ValidationException|CustomException $e) { + throw $e; + } catch (Exception $e) { + return $this->responseService->systemError( + __('admin.operation_failed') . ':' + . $e->getMessage() + ); + } + } + + /** + * @param string $id + * @return JsonResponse + * @throws CustomException + * @throws ValidationException + */ + public function destroy(string $id): JsonResponse + { + try { + $this->validateId($id, AdminChannelRole::class); + $this->service->deleteModel($id); + return $this->responseService->success( + null, + __('admin.delete_succeeded') + ); + } catch (ValidationException|CustomException $e) { + throw $e; + } catch (Exception $e) { + return $this->responseService->systemError( + __('admin.operation_failed') . ':' + . $e->getMessage() + ); + } + } +} diff --git a/app/Models/AdminChannelRole.php b/app/Models/AdminChannelRole.php new file mode 100644 index 0000000..c10e2d0 --- /dev/null +++ b/app/Models/AdminChannelRole.php @@ -0,0 +1,34 @@ +select(['id', 'name'])->get()->each(function ($item) { + $item['name'] = AdminTranslationService::getTranslationTypeName( + $item['id'], + 6, + $item['name'] + ); + return $item; + }); + } + + + public static function getChannelData($ids) + { + return self::query()->whereIn('id', $ids)->select( + ['id', 'name'] + )->get()->each(function ($item) { + $item['name'] = AdminTranslationService::getTranslationTypeName( + $item['id'], + 6, + $item['name'] + ); + return $item; + }); + } public function getCreatedAtAttribute($value): string { diff --git a/app/Services/AdminChannelRoleService.php b/app/Services/AdminChannelRoleService.php new file mode 100644 index 0000000..6242669 --- /dev/null +++ b/app/Services/AdminChannelRoleService.php @@ -0,0 +1,141 @@ + $value) { + $statusArr[$key] = __('admin.' . $value); + } + return $statusArr; + } + + /** + * @param array $data + * @throws Exception + */ + public function createModel(array $data) + { + try { + DB::beginTransaction(); + + $existsWhere = [ + ['member_type', '=', $data['member_type']] + ]; + if (AdminChannelRole::query()->where($existsWhere)->exists() + ) { + throw new Exception( + __('service.' . $this->menuTitle . '.type_exists') + ); + } + + $channel_ids = implode(',', $data['channel_ids']); + $model = AdminChannelRole::query()->create([ + 'member_type' => $data['member_type'], + 'status' => $data['status'] ?? 1, + 'describe' => $data['describe'] ?? '', + 'channel_ids' => $channel_ids ?? '', + 'created_at' => get_datetime() + ]); + + $this->logService->logCreated( + $model, + $this->menuTitle . '.create' + ); + + DB::commit(); + return $model; + } catch (Exception $e) { + DB::rollBack(); + throw $e; + } + } + + /** + * @param array $data + * @param int $id + * @throws Exception + */ + public function updateModel(array $data, int $id) + { + try { + DB::beginTransaction(); + + // 验证 + $existsWhere = [ + ['member_type', '=', $data['member_type']], + ['id', '<>', $id] + ]; + if (AdminChannelRole::query()->where($existsWhere)->exists() + ) { + throw new Exception( + __('service.' . $this->menuTitle . '.reason_exists') + ); + } + + // 更新 + $model = AdminChannelRole::query()->findOrFail($id); + $oldValues = $model->toArray(); + + $channel_ids = implode(',', $data['channel_ids']); + $model->update([ + 'member_type' => $data['member_type'], + 'status' => $data['status'] ?? 1, + 'describe' => $data['describe'] ?? '', + 'channel_ids' => $channel_ids ?? '', + 'updated_at' => get_datetime() + ]); + + $this->logService->logUpdated( + $model, + $oldValues, + $this->menuTitle . '.update' + ); + + DB::commit(); + return $model; + } catch (Exception $e) { + DB::rollBack(); + throw $e; + } + } + + /** + * @param $id + * @return bool + * @throws Exception + */ + public function deleteModel($id): bool + { + try { + DB::beginTransaction(); + + $model = AdminChannelRole::query()->findOrFail($id); + + $this->logService->logDeleted($model, $this->menuTitle . '.delete'); + + $model->delete(); + + DB::commit(); + return true; + } catch (Exception $e) { + DB::rollBack(); + throw $e; + } + } +} diff --git a/database/migrations/2026_06_03_143449_create_admin_channel_role_table.php b/database/migrations/2026_06_03_143449_create_admin_channel_role_table.php new file mode 100644 index 0000000..578cc4c --- /dev/null +++ b/database/migrations/2026_06_03_143449_create_admin_channel_role_table.php @@ -0,0 +1,34 @@ +id(); + $table->tinyInteger('member_type')->default(1)->comment('会员类型'); + $table->tinyInteger('status')->default(1)->comment('状态'); + $table->string('describe', 255)->default('')->comment('描述'); + $table->text('channel_ids')->comment('允许通道'); + $table->timestamps(); + $table->softDeletes(); + $table->innoDb(); + $table->comment('通道权限'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('admin_channel_role'); + } +}; diff --git a/database/seeders/AdminMenuSeeder.php b/database/seeders/AdminMenuSeeder.php index fd1ebeb..fe8848c 100644 --- a/database/seeders/AdminMenuSeeder.php +++ b/database/seeders/AdminMenuSeeder.php @@ -522,7 +522,10 @@ class AdminMenuSeeder extends Seeder 'uri' => 'channelPermissions', 'page_uri' => '/user/channelPermissions', 'child' => [ - 'read_only' => 'channelPermissions.index' + 'read_only' => 'channelPermissions.index', + 'add' => 'channelPermissions.store', + 'edit' => 'channelPermissions.update', + 'delete' => 'channelPermissions.destroy' ] ] ] diff --git a/resources/lang/en/log.php b/resources/lang/en/log.php index f91c13c..d8c3f46 100644 --- a/resources/lang/en/log.php +++ b/resources/lang/en/log.php @@ -116,5 +116,10 @@ return [ 'create' => 'Create exit reason', 'update' => 'Update the reason for departure', 'delete' => 'Delete exit reason' + ], + 'channel_permissions' => [ + 'create' => 'Create channel permissions', + 'update' => 'Update channel permissions', + 'delete' => 'Delete channel permissions' ] ]; diff --git a/resources/lang/en/service.php b/resources/lang/en/service.php index 9f4c458..a386b6a 100644 --- a/resources/lang/en/service.php +++ b/resources/lang/en/service.php @@ -110,5 +110,8 @@ return [ ], 'departure_management' => [ 'reason_exists' => 'Reason for departure already exists' + ], + 'channel_permissions' => [ + 'type_exists' => 'Channel membership type already exists' ] ]; diff --git a/resources/lang/en/validation.php b/resources/lang/en/validation.php index 204c6f3..61983be 100644 --- a/resources/lang/en/validation.php +++ b/resources/lang/en/validation.php @@ -149,5 +149,10 @@ return [ ], 'departure_management' => [ 'n_empty' => 'Reason for departure cannot be empty', + ], + 'channel_permissions' => [ + 'm_empty' => 'Member type cannot be empty', + 'c_empty' => 'Allow channel not to be empty', + 'c_array' => 'Allow channel data to be an array' ] ]; diff --git a/resources/lang/zh-CN/log.php b/resources/lang/zh-CN/log.php index 2049ab6..9534d00 100644 --- a/resources/lang/zh-CN/log.php +++ b/resources/lang/zh-CN/log.php @@ -116,5 +116,10 @@ return [ 'create' => '创建离场原因', 'update' => '更新离场原因', 'delete' => '删除离场原因' + ], + 'channel_permissions' => [ + 'create' => '创建通道权限', + 'update' => '更新通道权限', + 'delete' => '删除通道权限' ] ]; diff --git a/resources/lang/zh-CN/service.php b/resources/lang/zh-CN/service.php index f174309..61686a1 100644 --- a/resources/lang/zh-CN/service.php +++ b/resources/lang/zh-CN/service.php @@ -110,5 +110,8 @@ return [ ], 'departure_management' => [ 'reason_exists' => '离场原因已存在' + ], + 'channel_permissions' => [ + 'type_exists' => '通道会员类型已存在' ] ]; diff --git a/resources/lang/zh-CN/validation.php b/resources/lang/zh-CN/validation.php index d084f54..4768766 100644 --- a/resources/lang/zh-CN/validation.php +++ b/resources/lang/zh-CN/validation.php @@ -149,5 +149,10 @@ return [ ], 'departure_management' => [ 'n_empty' => '离场原因不能为空', + ], + 'channel_permissions' => [ + 'm_empty' => '会员类型不能为空', + 'c_empty' => '允许通道不能为空', + 'c_array' => '允许通道数据必须是数组' ] ]; diff --git a/resources/lang/zh-TW/log.php b/resources/lang/zh-TW/log.php index e7723de..2a044ae 100644 --- a/resources/lang/zh-TW/log.php +++ b/resources/lang/zh-TW/log.php @@ -116,5 +116,10 @@ return [ 'create' => '創建離場原因', 'update' => '更新離場原因', 'delete' => '删除離場原因' + ], + 'channel_permissions' => [ + 'create' => '創建通道許可權', + 'update' => '更新通道許可權', + 'delete' => '删除通道許可權' ] ]; diff --git a/resources/lang/zh-TW/service.php b/resources/lang/zh-TW/service.php index 7297a80..9362a38 100644 --- a/resources/lang/zh-TW/service.php +++ b/resources/lang/zh-TW/service.php @@ -110,5 +110,8 @@ return [ ], 'departure_management' => [ 'reason_exists' => '離場原因已存在' + ], + 'channel_permissions' => [ + 'type_exists' => '通道會員類型已存在' ] ]; diff --git a/resources/lang/zh-TW/validation.php b/resources/lang/zh-TW/validation.php index 61b823f..ba6d07b 100644 --- a/resources/lang/zh-TW/validation.php +++ b/resources/lang/zh-TW/validation.php @@ -149,5 +149,10 @@ return [ ], 'departure_management' => [ 'n_empty' => '離場原因不能為空', + ], + 'channel_permissions' => [ + 'm_empty' => '會員類型不能為空', + 'c_empty' => '允許通道不能為空', + 'c_array' => '允許通道數據必須是數組' ] ]; diff --git a/routes/admin/api.php b/routes/admin/api.php index 94a3a4e..72a4e26 100644 --- a/routes/admin/api.php +++ b/routes/admin/api.php @@ -34,6 +34,7 @@ use App\Http\Controllers\Admin\RegionalManagementController; use App\Http\Controllers\Admin\ParkingChannelController; use App\Http\Controllers\Admin\GuardBoothManagementController; use App\Http\Controllers\Admin\ParkingDepartureReasonController; +use App\Http\Controllers\Admin\ChannelPermissionsController; Route::group(['prefix' => 'admin'], function () { @@ -282,6 +283,14 @@ Route::group(['prefix' => 'admin'], function () { Route::put('/users/{id}', [UserController::class, 'update']); Route::delete('/users/{id}', [UserController::class, 'destroy']); Route::get('/users/rule', [UserController::class, 'rule']); + // 通道权限管理 + Route::get('/channelPermissions', [ChannelPermissionsController::class, 'index']); + Route::get('/channelPermissions/create', [ChannelPermissionsController::class, 'create']); + Route::post('/channelPermissions', [ChannelPermissionsController::class, 'store']); + Route::get('/channelPermissions/edit/{id}', [ChannelPermissionsController::class, 'edit']); + Route::put('/channelPermissions/{id}', [ChannelPermissionsController::class, 'update']); + Route::delete('/channelPermissions/{id}', [ChannelPermissionsController::class, 'destroy']); + Route::get('/channelPermissions/rule', [ChannelPermissionsController::class, 'rule']); }); // 导出 Route::get('/vipList/import_template', [VipListController::class, 'importTemplate']);