From 3bb3a0f022a873b2bcd895a8bfb9995487ddc22e Mon Sep 17 00:00:00 2001 From: vine_liutk <961510893@qq.com> Date: Fri, 8 Dec 2023 14:46:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=AE=A1=E7=90=86=E5=91=98?= =?UTF-8?q?=E9=94=81=E5=AE=9A=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E8=B6=85=E7=BA=A7=E7=AE=A1=E7=90=86=E5=91=98=E6=89=80=E6=9C=89?= =?UTF-8?q?=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Admin/Controllers/AdminUserController.php | 78 +++++++++ app/Services/Admin/AdminUserService.php | 164 ++++++++++++++++++ ...8_142335_add_lock_to_admin_users_table.php | 30 ++++ 3 files changed, 272 insertions(+) create mode 100644 app/Admin/Controllers/AdminUserController.php create mode 100644 app/Services/Admin/AdminUserService.php create mode 100644 database/migrations/2023_12_08_142335_add_lock_to_admin_users_table.php diff --git a/app/Admin/Controllers/AdminUserController.php b/app/Admin/Controllers/AdminUserController.php new file mode 100644 index 0000000..3a5a8ba --- /dev/null +++ b/app/Admin/Controllers/AdminUserController.php @@ -0,0 +1,78 @@ +baseCRUD() + ->headerToolbar([ + $this->createButton(true), + ...$this->baseHeaderToolBar(), + ]) + ->filter($this->baseFilter()->body( + amisMake()->TextControl('keyword', __('admin.keyword')) + ->size('md') + ->placeholder(__('admin.admin_user.search_username')) + )) + ->quickSaveItemApi(admin_url('quick-edit/admin_users/$id')) + ->itemCheckableOn('${id !== 1}') + ->columns([ + amisMake()->TableColumn('id', 'ID')->sortable(), + amisMake()->TableColumn('avatar', __('admin.admin_user.avatar'))->type('avatar')->src('${avatar}'), + amisMake()->TableColumn('username', __('admin.username')), + amisMake()->TableColumn('name', __('admin.admin_user.name')), + amisMake()->TableColumn('roles', __('admin.admin_user.roles'))->type('each')->items( + amisMake()->Tag()->label('${name}')->className('my-1') + ), + amisMake()->TableColumn('lock', '锁定')->quickEdit(SwitchControl::make()->saveImmediately(true)->mode('inline')->disabledOn('${id === 1}')), + amisMake()->TableColumn('created_at', __('admin.created_at'))->type('datetime')->sortable(true), + Operation::make()->label(__('admin.actions'))->buttons([ + $this->rowEditButton(true)->visibleOn('${id != 1}'), + $this->rowDeleteButton()->visibleOn('${id != 1}'), + ]), + ]); + + return $this->baseList($crud); + } + + public function form(): Form + { + return $this->baseForm()->body([ + amisMake()->ImageControl('avatar', __('admin.admin_user.avatar'))->receiver($this->uploadImagePath()), + amisMake()->TextControl('username', __('admin.username'))->required(), + amisMake()->TextControl('name', __('admin.admin_user.name'))->required(), + amisMake()->TextControl('password', __('admin.password'))->type('input-password')->required()->validations(['minLength' => 6]), + amisMake()->TextControl('confirm_password', __('admin.confirm_password'))->type('input-password')->required()->validations(['minLength' => 6]), + amisMake()->SelectControl('roles', __('admin.admin_user.roles')) + ->searchable() + ->multiple() + ->labelField('name') + ->valueField('id') + ->joinValues(false) + ->extractValue() + ->options(AdminRoleService::make()->query()->get(['id', 'name'])), + SwitchControl::make()->name('lock')->label('锁定')->value(false), + ]); + } + + public function detail(): Form + { + return $this->baseDetail()->body([]); + } +} diff --git a/app/Services/Admin/AdminUserService.php b/app/Services/Admin/AdminUserService.php new file mode 100644 index 0000000..86935da --- /dev/null +++ b/app/Services/Admin/AdminUserService.php @@ -0,0 +1,164 @@ +modelName = Admin::adminUserModel(); + } + + public function getEditData($id): Model|\Illuminate\Database\Eloquent\Collection|Builder|array|null + { + $adminUser = parent::getEditData($id)->makeHidden('password'); + + $adminUser->load('roles'); + + return $adminUser; + } + + public function store($data): bool + { + if ($this->checkUsernameUnique($data['username'])) { + return $this->setError(__('admin.admin_user.username_already_exists')); + } + + if (!data_get($data, 'password')) { + return $this->setError(__('admin.required', ['attribute' => __('admin.password')])); + } + + if (!$this->passwordHandler($data)) { + return false; + } + + $columns = $this->getTableColumns(); + + $model = $this->getModel(); + + return $this->saveData($data, $columns, $model); + } + + public function update($primaryKey, $data): bool + { + if ($this->checkUsernameUnique($data['username'], $primaryKey)) { + return $this->setError(__('admin.admin_user.username_already_exists')); + } + + if (!$this->passwordHandler($data)) { + return false; + } + + $columns = $this->getTableColumns(); + + $model = $this->query()->whereKey($primaryKey)->first(); + + return $this->saveData($data, $columns, $model); + } + + public function checkUsernameUnique($username, $id = 0): bool + { + return $this->query() + ->where('username', $username) + ->when($id, fn($query) => $query->where('id', '<>', $id)) + ->exists(); + } + + public function updateUserSetting($primaryKey, $data): bool + { + if (!$this->passwordHandler($data, $primaryKey)) { + return false; + } + + return parent::update($primaryKey, $data); + } + + public function passwordHandler(&$data, $id = null): bool + { + $password = Arr::get($data, 'password'); + + if ($password) { + if ($password !== Arr::get($data, 'confirm_password')) { + return $this->setError(__('admin.admin_user.password_confirmation')); + } + + if ($id) { + if (!Arr::get($data, 'old_password')) { + return $this->setError(__('admin.admin_user.old_password_required')); + } + + $oldPassword = $this->query()->where('id', $id)->value('password'); + + if (!Hash::check($data['old_password'], $oldPassword)) { + return $this->setError(__('admin.admin_user.old_password_error')); + } + } + + $data['password'] = bcrypt($password); + + unset($data['confirm_password']); + unset($data['old_password']); + } + + return true; + } + + public function list() + { + $keyword = request()->keyword; + + $query = $this + ->query() + ->with('roles') + ->select(['id', 'name', 'username', 'avatar', 'created_at', 'lock']) + ->when($keyword, function ($query) use ($keyword) { + $query->where('username', 'like', "%{$keyword}%")->orWhere('name', 'like', "%{$keyword}%"); + }); + + $items = (clone $query)->paginate(request()->input('perPage', 20))->items(); + $total = (clone $query)->count(); + + return compact('items', 'total'); + } + + /** + * @param $data + * @param array $columns + * @param AdminUser $model + * + * @return bool + */ + protected function saveData($data, array $columns, AdminUser $model): bool + { + $roles = Arr::pull($data, 'roles'); + + foreach ($data as $k => $v) { + if (!in_array($k, $columns)) { + continue; + } + + $model->setAttribute($k, $v); + } + + if ($model->save()) { + $model->roles()->sync(Arr::has($roles, '0.id') ? Arr::pluck($roles, 'id') : $roles); + + return true; + } + + return false; + } +} diff --git a/database/migrations/2023_12_08_142335_add_lock_to_admin_users_table.php b/database/migrations/2023_12_08_142335_add_lock_to_admin_users_table.php new file mode 100644 index 0000000..74751fe --- /dev/null +++ b/database/migrations/2023_12_08_142335_add_lock_to_admin_users_table.php @@ -0,0 +1,30 @@ +unsignedInteger('lock')->default(0)->comment('锁定'); + $table->unsignedInteger('error_num')->default(0)->comment('错误次数'); + $table->timestamp('last_error_at')->nullable()->comment('上次错误时间'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('admin_users', function (Blueprint $table) { + $table->dropColumn(['lock', 'error_num', 'last_error_at']); + }); + } +};