admin users
parent
40a262983e
commit
0e7a40ff61
|
|
@ -17,6 +17,7 @@
|
||||||
监听sql执行, 打印日志
|
监听sql执行, 打印日志
|
||||||
|
|
||||||
- `app/Providers/QueryLogServiceProvider.php`
|
- `app/Providers/QueryLogServiceProvider.php`
|
||||||
|
- `bootstrap\providers.php`
|
||||||
|
|
||||||
### 无限级分类
|
### 无限级分类
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,12 @@ class KeywordController extends AdminController
|
||||||
->loadDataOnce(true)
|
->loadDataOnce(true)
|
||||||
->footerToolbar([])
|
->footerToolbar([])
|
||||||
->headerToolbar([
|
->headerToolbar([
|
||||||
$this->createButton()->visible($user->can('keywords.create')),
|
$this->createButton()->permission('admin.keywords.create'),
|
||||||
$this->exportAction()->visible($user->can('keywords.export')),
|
$this->exportAction()->permission('admin.keywords.export'),
|
||||||
...$this->baseHeaderToolBar(),
|
...$this->baseHeaderToolBar(),
|
||||||
|
])
|
||||||
|
->bulkActions([
|
||||||
|
$this->bulkDeleteButton()->permission('admin.keywords.delete')
|
||||||
])
|
])
|
||||||
->filter($this->baseFilter()->body([
|
->filter($this->baseFilter()->body([
|
||||||
amis()->GroupControl()->mode('horizontal')->body([
|
amis()->GroupControl()->mode('horizontal')->body([
|
||||||
|
|
@ -44,9 +47,9 @@ class KeywordController extends AdminController
|
||||||
'saveImmediately' => true,
|
'saveImmediately' => true,
|
||||||
]),
|
]),
|
||||||
$this->rowActions([
|
$this->rowActions([
|
||||||
$this->rowShowButton()->visible($user->can('keywords.show')),
|
$this->rowShowButton()->permission('admin.keywords.show'),
|
||||||
$this->rowEditButton()->visible($user->can('keywords.edit')),
|
$this->rowEditButton()->permission('admin.keywords.edit'),
|
||||||
$this->rowDeleteButton()->visible($user->can('keywords.delete')),
|
$this->rowDeleteButton()->permission('admin.keywords.delete'),
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Admin\Controllers;
|
||||||
|
|
||||||
|
use App\Services\UserService;
|
||||||
|
use Slowlyo\OwlAdmin\Controllers\AdminController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户管理
|
||||||
|
*
|
||||||
|
* @property UserService $service
|
||||||
|
*/
|
||||||
|
class UserController extends AdminController
|
||||||
|
{
|
||||||
|
protected string $serviceName = UserService::class;
|
||||||
|
|
||||||
|
public function list()
|
||||||
|
{
|
||||||
|
$crud = $this->baseCRUD()
|
||||||
|
->filterTogglable(false)
|
||||||
|
->columnsTogglable(false)
|
||||||
|
->headerToolbar([
|
||||||
|
$this->createButton('drawer', 'lg')->permission('admin.users.create'),
|
||||||
|
...$this->baseHeaderToolBar(),
|
||||||
|
])
|
||||||
|
->bulkActions([
|
||||||
|
$this->bulkDeleteButton()->permission('admin.users.delete')
|
||||||
|
])
|
||||||
|
->filter($this->baseFilter()->body([
|
||||||
|
amis()->GroupControl()->mode('horizontal')->body([
|
||||||
|
amis()->TextControl()->name('search')->label(__('admin.search'))->columnRatio(3)->clearable(),
|
||||||
|
])
|
||||||
|
]))
|
||||||
|
->columns([
|
||||||
|
amis()->TableColumn()->name('id')->label(__('admin.id')),
|
||||||
|
amis()->TableColumn()->name('avatar')->label(__('users.avatar'))->type('avatar')->src('${avatar}'),
|
||||||
|
amis()->TableColumn()->name('phone')->label(__('users.phone')),
|
||||||
|
amis()->TableColumn()->name('name')->label(__('users.name')),
|
||||||
|
amis()->TableColumn()->name('created_at')->label(__('users.created_at')),
|
||||||
|
$this->rowActions([
|
||||||
|
$this->rowShowButton('drawer', 'lg')->permission('admin.users.show'),
|
||||||
|
$this->rowEditButton('drawer', 'lg')->permission('admin.users.edit'),
|
||||||
|
$this->rowDeleteButton()->permission('admin.users.delete'),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $this->baseList($crud);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function form()
|
||||||
|
{
|
||||||
|
return $this->baseForm()->mode('horizontal')->body([
|
||||||
|
amis()->ImageControl()->name('avatar')->label(__('users.avatar')),
|
||||||
|
amis()->TextControl()->name('phone')->label(__('users.phone'))->required(),
|
||||||
|
amis()->TextControl()->name('name')->label(__('users.name')),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function detail()
|
||||||
|
{
|
||||||
|
return $this->baseDetail()->body(amis()->Property()->items([
|
||||||
|
['label' => __('users.avatar'), 'content' => amis()->Avatar()->src('${avatar}')],
|
||||||
|
['label' => __('users.phone'), 'content' => '${phone}'],
|
||||||
|
['label' => __('users.name'), 'content' => '${name}'],
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use App\Admin\Controllers\HomeController;
|
use App\Admin\Controllers\HomeController;
|
||||||
use App\Admin\Controllers\KeywordController;
|
use App\Admin\Controllers\KeywordController;
|
||||||
|
use App\Admin\Controllers\UserController;
|
||||||
use Illuminate\Routing\Router;
|
use Illuminate\Routing\Router;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
|
|
@ -25,5 +26,6 @@ Route::group([
|
||||||
$router->any('upload_image', [HomeController::class, 'uploadImage']);
|
$router->any('upload_image', [HomeController::class, 'uploadImage']);
|
||||||
$router->any('upload_file', [HomeController::class, 'uploadFile']);
|
$router->any('upload_file', [HomeController::class, 'uploadFile']);
|
||||||
|
|
||||||
|
$router->resource('users', UserController::class);
|
||||||
$router->resource('system/keywords', KeywordController::class);
|
$router->resource('system/keywords', KeywordController::class);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\ModelFilters;
|
||||||
|
|
||||||
|
use EloquentFilter\ModelFilter;
|
||||||
|
|
||||||
|
class UserFilter extends ModelFilter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Related Models that have ModelFilters as well as the method on the ModelFilter
|
||||||
|
* As [relationMethod => [input_key1, input_key2]].
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $relations = [];
|
||||||
|
|
||||||
|
public function search($key)
|
||||||
|
{
|
||||||
|
$str = '%'.$key.'%';
|
||||||
|
return $this->where(fn($q) => $q->where('phone', 'like', $str)->orWhere('name', 'like', $str));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,42 +6,19 @@ namespace App\Models;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
use EloquentFilter\Filterable;
|
||||||
|
use Slowlyo\OwlAdmin\Traits\DatetimeFormatterTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户
|
||||||
|
*/
|
||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
use HasFactory, Notifiable;
|
use HasFactory, Filterable, DatetimeFormatterTrait;
|
||||||
|
|
||||||
/**
|
protected $fillable = ['phone', 'name', 'avatar'];
|
||||||
* The attributes that are mass assignable.
|
|
||||||
*
|
|
||||||
* @var array<int, string>
|
|
||||||
*/
|
|
||||||
protected $fillable = [
|
|
||||||
'name',
|
|
||||||
'email',
|
|
||||||
'password',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
// protected $casts = [
|
||||||
* The attributes that should be hidden for serialization.
|
// 'created_at' => 'datetime:Y-m-d H:i:s',
|
||||||
*
|
// ];
|
||||||
* @var array<int, string>
|
|
||||||
*/
|
|
||||||
protected $hidden = [
|
|
||||||
'password',
|
|
||||||
'remember_token',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the attributes that should be cast.
|
|
||||||
*
|
|
||||||
* @return array<string, string>
|
|
||||||
*/
|
|
||||||
protected function casts(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'email_verified_at' => 'datetime',
|
|
||||||
'password' => 'hashed',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Slowlyo\OwlAdmin\Services\AdminService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户管理
|
||||||
|
*/
|
||||||
|
class UserService extends AdminService
|
||||||
|
{
|
||||||
|
protected string $modelName = User::class;
|
||||||
|
|
||||||
|
public function sortable($query)
|
||||||
|
{
|
||||||
|
$query->orderByDesc('id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function searchable($query)
|
||||||
|
{
|
||||||
|
$query->filter(request()->all());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleted($ids)
|
||||||
|
{
|
||||||
|
$ids = explode(',', $ids);
|
||||||
|
|
||||||
|
$this->query()->where(function ($q) use ($ids) {
|
||||||
|
foreach ($ids as $id) {
|
||||||
|
$q->orWhere('path', 'like', '%-'.$id.'-%');
|
||||||
|
}
|
||||||
|
})->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -68,10 +68,10 @@ return [
|
||||||
'https' => env('ADMIN_HTTPS', false),
|
'https' => env('ADMIN_HTTPS', false),
|
||||||
|
|
||||||
// 是否显示 [开发者工具]
|
// 是否显示 [开发者工具]
|
||||||
'show_development_tools' => env('ADMIN_SHOW_DEVELOPMENT_TOOLS', true),
|
'show_development_tools' => env('ADMIN_SHOW_DEVELOPMENT_TOOLS', false),
|
||||||
|
|
||||||
// 是否显示 [权限] 功能中的自动生成按钮
|
// 是否显示 [权限] 功能中的自动生成按钮
|
||||||
'show_auto_generate_permission_button' => env('ADMIN_SHOW_AUTO_GENERATE_PERMISSION_BUTTON', true),
|
'show_auto_generate_permission_button' => env('ADMIN_SHOW_AUTO_GENERATE_PERMISSION_BUTTON', false),
|
||||||
|
|
||||||
// 扩展
|
// 扩展
|
||||||
'extension' => [
|
'extension' => [
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@ return new class extends Migration
|
||||||
{
|
{
|
||||||
Schema::create('users', function (Blueprint $table) {
|
Schema::create('users', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
|
$table->string('phone')->unique();
|
||||||
|
$table->string('name')->nullable();
|
||||||
|
$table->string('avatar')->nullable();
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?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_permissions', function (Blueprint $table) {
|
||||||
|
$table->dropUnique('admin_permissions_name_unique');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('admin_permissions', function (Blueprint $table) {
|
||||||
|
$table->unique('name');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -23,6 +23,7 @@ class AdminPermissionSeeder extends Seeder
|
||||||
// icon: https://icones.js.org/collection/mdi
|
// icon: https://icones.js.org/collection/mdi
|
||||||
$list = [
|
$list = [
|
||||||
['name' => '首页', 'icon' => 'mdi:home', 'slug' => 'dashboard', 'url' => '/dashboard', 'is_home' => 1],
|
['name' => '首页', 'icon' => 'mdi:home', 'slug' => 'dashboard', 'url' => '/dashboard', 'is_home' => 1],
|
||||||
|
['name' => '用户管理', 'icon' => 'mdi:account', 'slug' => 'users', 'url' => '/users', 'resource' => true],
|
||||||
['name' => '系统管理', 'icon' => 'mdi:cog-outline', 'slug' => 'system', 'url' => '/system', 'children' => [
|
['name' => '系统管理', 'icon' => 'mdi:cog-outline', 'slug' => 'system', 'url' => '/system', 'children' => [
|
||||||
['name' => '管理员', 'icon' => 'mdi:account-cog-outline', 'slug' => 'admin_users', 'url' => '/system/admin_users'],
|
['name' => '管理员', 'icon' => 'mdi:account-cog-outline', 'slug' => 'admin_users', 'url' => '/system/admin_users'],
|
||||||
['name' => '角色', 'icon' => 'mdi:account-box-outline', 'slug' => 'roles', 'url' => '/system/admin_roles'],
|
['name' => '角色', 'icon' => 'mdi:account-box-outline', 'slug' => 'roles', 'url' => '/system/admin_roles'],
|
||||||
|
|
@ -72,7 +73,7 @@ class AdminPermissionSeeder extends Seeder
|
||||||
|
|
||||||
protected function createPermission($item, $pid = 0, $menu = null)
|
protected function createPermission($item, $pid = 0, $menu = null)
|
||||||
{
|
{
|
||||||
$slug = data_get($item, 'slug');
|
$slug = 'admin.'.data_get($item, 'slug');
|
||||||
$url = data_get($item, 'url');
|
$url = data_get($item, 'url');
|
||||||
$method = data_get($item, 'method');
|
$method = data_get($item, 'method');
|
||||||
$permission = AdminPermission::create([
|
$permission = AdminPermission::create([
|
||||||
|
|
@ -109,13 +110,15 @@ class AdminPermissionSeeder extends Seeder
|
||||||
'show' => '详细',
|
'show' => '详细',
|
||||||
'delete' => '删除'
|
'delete' => '删除'
|
||||||
];
|
];
|
||||||
if ($resource == true) {
|
if ($resource) {
|
||||||
|
if ($resource === true) {
|
||||||
return $maps;
|
return $maps;
|
||||||
}
|
}
|
||||||
if (is_array($resource)) {
|
if (is_array($resource)) {
|
||||||
return Arr::only($maps, $resource);
|
return Arr::only($maps, $resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
return data_get($maps, $resource);
|
return data_get($maps, $resource);
|
||||||
}
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -339,4 +339,5 @@ return [
|
||||||
'data_delete' => '删除数据',
|
'data_delete' => '删除数据',
|
||||||
'data_detail' => '获取详情',
|
'data_detail' => '获取详情',
|
||||||
],
|
],
|
||||||
|
'id' => 'ID',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'phone' => '手机号',
|
||||||
|
'name' => '姓名',
|
||||||
|
'avatar' => '头像',
|
||||||
|
'created_at' => '注册时间',
|
||||||
|
];
|
||||||
Loading…
Reference in New Issue