添加管理员锁定功能,取消超级管理员所有操作
parent
124d464951
commit
3bb3a0f022
|
|
@ -0,0 +1,78 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Admin\Controllers;
|
||||||
|
|
||||||
|
use Slowlyo\OwlAdmin\Renderers\Page;
|
||||||
|
use Slowlyo\OwlAdmin\Renderers\Form;
|
||||||
|
use Slowlyo\OwlAdmin\Renderers\Operation;
|
||||||
|
use Slowlyo\OwlAdmin\Renderers\SwitchControl;
|
||||||
|
use Slowlyo\OwlAdmin\Renderers\TableColumn;
|
||||||
|
use App\Services\Admin\AdminUserService;
|
||||||
|
use Slowlyo\OwlAdmin\Services\AdminRoleService;
|
||||||
|
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property AdminUserService $service
|
||||||
|
*/
|
||||||
|
class AdminUserController extends AdminController
|
||||||
|
{
|
||||||
|
protected string $serviceName = AdminUserService::class;
|
||||||
|
|
||||||
|
public function list(): Page
|
||||||
|
{
|
||||||
|
$crud = $this->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([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,164 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Admin;
|
||||||
|
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
use Slowlyo\OwlAdmin\Admin;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Slowlyo\OwlAdmin\Models\AdminUser;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method AdminUser getModel()
|
||||||
|
* @method AdminUser|Builder query()
|
||||||
|
*/
|
||||||
|
class AdminUserService extends BaseService
|
||||||
|
{
|
||||||
|
protected string $modelName;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('admin_users', function (Blueprint $table) {
|
||||||
|
$table->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']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue