醉梦人间三千年 7 månader sedan
förälder
incheckning
e94739f59b
29 ändrade filer med 1095 tillägg och 108 borttagningar
  1. 10 0
      app/Enums/Common/ErrorMessage.php
  2. 12 0
      app/Enums/System/MenuType.php
  3. 6 5
      app/Exceptions/Handler.php
  4. 20 17
      app/Http/Controllers/Backend/Server/System/AuthController.php
  5. 39 5
      app/Http/Controllers/Backend/Server/System/DictTypeController.php
  6. 1 1
      app/Http/Controllers/Backend/Server/System/MenuController.php
  7. 76 0
      app/Http/Controllers/Backend/Server/System/RoleController.php
  8. 59 0
      app/Http/Controllers/Backend/Server/System/UserController.php
  9. 52 4
      app/Http/Services/Backend/Server/System/DictTypeService.php
  10. 2 3
      app/Http/Services/Backend/Server/System/MenuService.php
  11. 5 0
      app/Models/System/DictType.php
  12. 26 68
      app/Models/System/Menu.php
  13. 66 0
      app/Models/System/Role.php
  14. 7 3
      app/Models/System/User.php
  15. 1 1
      bootstrap/providers.php
  16. 186 0
      config/permission.php
  17. 1 1
      database/migrations/0001_01_01_000000_create_system_users_table.php
  18. 152 0
      database/migrations/2024_08_14_093112_create_permission_tables.php
  19. 33 0
      database/migrations/2024_08_26_111055_create_system_dict_type_table.php
  20. 38 0
      database/migrations/2024_08_27_031435_create_system_dict_data_table.php
  21. 64 0
      database/migrations/2024_08_29_032939_create_system_menus_table.php
  22. 1 0
      database/seeders/DatabaseSeeder.php
  23. 29 0
      database/seeders/SystemDictTableSeeder.php
  24. 60 0
      database/seeders/SystemMenusTableSeeder.php
  25. 21 0
      database/seeders/SystemModelHasRolesTableSeeder.php
  26. 56 0
      database/seeders/SystemPermissionsTableSeeder.php
  27. 28 0
      database/seeders/SystemRoleHasPermissionsTableSeeder.php
  28. 22 0
      database/seeders/SystemRolesTableSeeder.php
  29. 22 0
      database/seeders/SystemUsersTableSeeder.php

+ 10 - 0
app/Enums/Common/ErrorMessage.php

@@ -0,0 +1,10 @@
+<?php declare(strict_types=1);
+
+namespace App\Enums\Common;
+
+use BenSampo\Enum\Enum;
+
+final class ErrorMessage extends Enum
+{
+    const DICT_TYPE_DUPLICATE = '字典类型重复'; // 关闭
+}

+ 12 - 0
app/Enums/System/MenuType.php

@@ -0,0 +1,12 @@
+<?php declare(strict_types=1);
+
+namespace App\Enums\System;
+
+use BenSampo\Enum\Enum;
+
+final class MenuType extends Enum
+{
+    const DIR = 1;
+    const MENU = 2;
+    const BUTTON = 3;
+}

+ 6 - 5
app/Exceptions/Handler.php

@@ -47,10 +47,11 @@ class Handler
         }
 
         if ($e instanceof ApiException) {
-            $status = match ($code) {
-                Response::HTTP_UNPROCESSABLE_ENTITY => 200, // 表单验证
-                default => $code,
-            };
+//            $status = match ($code) {
+//                Response::HTTP_UNPROCESSABLE_ENTITY => 200, // 表单验证
+//                default => $code,
+//            };
+            $status = 200;
             // 400 错误请求
             // 401 未授权
             // 403 禁止访问
@@ -60,7 +61,7 @@ class Handler
             // 500 服务器内部错误
 
         }
-        return response()->json(['code' => $code, 'message' => $message], $status);
+        return response()->json(['code' => $code, 'msg' => $message], $status);
     }
 
 }

+ 20 - 17
app/Http/Controllers/Backend/Server/System/AuthController.php

@@ -17,6 +17,7 @@ use App\Models\System\Role;
 use App\Models\System\User;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Support\Arr;
+use Illuminate\Support\Facades\Auth;
 use function PHPUnit\Framework\isEmpty;
 
 class AuthController extends Controller
@@ -36,8 +37,8 @@ class AuthController extends Controller
         $permissionInfo = ['user' => null, 'roles' => [], 'permissions' => [], 'menus' => []];
 
         // 1.1 获得用户信息
-        $user = request()->user();
-        if (!$user || $user->status !== 0) return self::success($permissionInfo);
+        $user = Auth::user();
+        if (!$user || $user['status'] !== 0) return self::success($permissionInfo);
         $permissionInfo['user'] = $user->only(['id', 'nickname', 'avatar']);
 
         // 1.2 获得角色列表
@@ -54,10 +55,10 @@ class AuthController extends Controller
         // 菜单树
 //        $menus = $allPermissions->where('status', 0)->whereIn('type', [1, 2])->whereIn('pivot.role_id', $roles->pluck('id'))->all();
 //        if (empty($menus)) return self::success($permissionInfo);
-        $permissionInfo['menus'] = self::buildMenuTree($menus->whereIn('type', [1, 2])->all());
+
+        $permissionInfo['menus'] = self::buildMenuTree($menus->toArray());
         // 权限标识信息
-        dd($user->getAllPermissions());
-        $permissions = $user->getAllPermissions()->where('status', 0)->whereIn('pivot.role_id', $roles->pluck('id'))->whereNotNull('permission')->pluck('permission');
+        $permissions = $user->getAllPermissions()->whereIn('pivot.role_id', $roles->pluck('id'))->pluck('name');
         $permissionInfo['permissions'] = $permissions;
 
         return self::success($permissionInfo);
@@ -68,9 +69,11 @@ class AuthController extends Controller
         // 移除按钮
         $removeKeys = [];
         $menuList = collect($menuList);
+
         $menuList->each(function ($value, $key) use (&$removeKeys) {
-            if ($value['type'] === 3) $removeKeys[] = $key;
+            if ($value->type === 3) $removeKeys[] = $key;
         });
+
         // 移除指定的项目
         $menuList = $menuList->forget($removeKeys);
 
@@ -81,17 +84,17 @@ class AuthController extends Controller
         $menuMap = collect([]);
 
         $menuList->each(function ($value) use (&$menuMap) {
-            $menuMap[$value['id']] = [
-                "id" => $value['id'],
-                "parentId" => $value['parent_id'],
-                "name" => $value['name'],
-                "path" => $value['path'],
-                "component" => $value['component'],
-                "componentName" => $value['component_name'],
-                "icon" => $value['icon'],
-                "visible" => !!$value['visible'],
-                "keepAlive" => !!$value['keep_alive'],
-                "alwaysShow" => !!$value['always_show'],
+            $menuMap[$value->id] = [
+                "id" => $value->id,
+                "parentId" => $value->parent_id,
+                "name" => $value->name,
+                "path" => $value->path,
+                "component" => $value->component,
+                "componentName" => $value->component_name,
+                "icon" => $value->icon,
+                "visible" => !!$value->visible,
+                "keepAlive" => !!$value->keep_alive,
+                "alwaysShow" => !!$value->always_show,
                 "children" => null
             ];
         });

+ 39 - 5
app/Http/Controllers/Backend/Server/System/DictTypeController.php

@@ -11,21 +11,55 @@ namespace App\Http\Controllers\Backend\Server\System;
 use App\Http\Controllers\Controller;
 use App\Http\Requests\Request;
 use App\Http\Services\Backend\Server\System\DictTypeService;
+use App\Http\Services\Backend\Server\System\MenuService;
 use App\Models\System\DictType;
 use Illuminate\Http\JsonResponse;
 
 class DictTypeController extends Controller
 {
-    public function index(Request $request)
+    private DictTypeService $dictTypeService;
+
+    function __construct(DictTypeService $dictTypeService)
+    {
+        $this->dictTypeService = $dictTypeService;
+//        $this->middleware('permission:system:menu:query|system:menu:create|system:menu:update|system:menu:delete', ['only' => ['index', 'show']]);
+//        $this->middleware('permission:system:menu:create', ['only' => ['create', 'store']]);
+//        $this->middleware('permission:system:menu:update', ['only' => ['edit', 'update']]);
+//        $this->middleware('permission:system:menu:delete', ['only' => ['destroy']]);
+    }
+
+    public function index(Request $request): JsonResponse
+    {
+        $params = $request->safe()->only(['name', 'type', 'status', 'createTime']);
+        $params['pageNo'] = $request->get('pageNo', 1);
+        $params['pageSize'] = $request->get('pageSize', 10);
+        $res = $this->dictTypeService->getDictTypeList($params);
+        return self::success($res);
+    }
+
+    public function show($id)
     {
-        $dictTypePage = DictType::query()->paginate(10);
-        return self::success(['list' => $dictTypePage->items(),'total' => $dictTypePage->total()]);
+        $res = $this->dictTypeService->getDictType($id);
+        return self::success($res);
+    }
+
+    public function store(Request $request): JsonResponse
+    {
+        $data = $request->only(['name', 'type', 'status', 'remark']);
+        $res = $this->dictTypeService->createDictType($data);
+        return self::success($res);
     }
 
-    public function store(Request $request)
+    public function update(Request $request, int $id)
     {
         $params = $request->all();
-        $res = (new DictTypeService())->createDictType($params);
+        $this->dictTypeService->updateDictType($params, $id);
+        return self::success(true);
+    }
+
+    public function destroy(int $id)
+    {
+        $res = $this->dictTypeService->deleteDictType($id);
         return self::success($res);
     }
 }

+ 1 - 1
app/Http/Controllers/Backend/Server/System/MenuController.php

@@ -25,7 +25,7 @@ class MenuController extends Controller
     function __construct(MenuService $menuService)
     {
         $this->menuService = $menuService;
-        $this->middleware('permission:test|system-menu-query|system-menu-create|system-menu-update|system-menu-delete', ['only' => ['index', 'show']]);
+        $this->middleware('permission:system:menu:query|system:menu:create|system:menu:update|system:menu:delete', ['only' => ['index', 'show']]);
 //        $this->middleware('permission:system:menu:create', ['only' => ['create', 'store']]);
 //        $this->middleware('permission:system:menu:update', ['only' => ['edit', 'update']]);
 //        $this->middleware('permission:system:menu:delete', ['only' => ['destroy']]);

+ 76 - 0
app/Http/Controllers/Backend/Server/System/RoleController.php

@@ -0,0 +1,76 @@
+<?php
+
+namespace App\Http\Controllers\Backend\Server\System;
+
+use App\Exceptions\ApiException;
+use App\Http\Controllers\Controller;
+use App\Http\Services\Backend\Server\System\RoleService;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
+
+class RoleController extends Controller
+{
+    private RoleService $roleService;
+
+    public function __construct(RoleService $roleService)
+    {
+        $this->roleService = $roleService;
+    }
+
+    public function index(Request $request): JsonResponse
+    {
+        // 处理首页逻辑
+        $params = $request->all();
+        $res = $this->roleService->getRoleList($params);
+        return self::success($res);
+    }
+
+    public function show($id)
+    {
+        // 处理显示单个用户的逻辑
+    }
+
+    public function create()
+    {
+        // 显示创建用户的表单
+    }
+
+    /**
+     * @throws ApiException
+     */
+    public function store(Request $request): JsonResponse
+    {
+        $params = $request->all();
+        $res = $this->roleService->createRole($params);
+        return self::success($res);
+    }
+
+    public function edit($id)
+    {
+        // 显示编辑用户的表单
+    }
+
+    /**
+     * @throws ApiException
+     */
+    public function update(Request $request, $id): JsonResponse
+    {
+        // 更新用户逻辑
+        $params = $request->all();
+        $res = $this->roleService->updateRole($params, $id);
+        return self::success(!!$res);
+    }
+
+    public function destroy($id): JsonResponse
+    {
+        // 删除用户逻辑
+        $res = $this->roleService->deleteRole($id);
+        return self::success(!!$res);
+    }
+
+//    public function permissions($id)
+//    {
+//        $res = $this->roleService->getRolePermissions($id);
+//        return self::success($res);
+//    }
+}

+ 59 - 0
app/Http/Controllers/Backend/Server/System/UserController.php

@@ -0,0 +1,59 @@
+<?php
+
+namespace App\Http\Controllers\Backend\Server\System;
+
+use App\Http\Controllers\Backend\Server\Controller;
+use App\Http\Requests\Backend\Server\System\UserRequest;
+use App\Models\System\User;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Hash;
+
+class UserController extends Controller
+{
+    public function index()
+    {
+        // 处理首页逻辑
+        return 'index';
+    }
+
+    public function show($id)
+    {
+        // 处理显示单个用户的逻辑
+    }
+
+    public function create()
+    {
+        // 显示创建用户的表单
+    }
+
+    public function store(UserRequest $request)
+    {
+        // 存储新创建的用户逻辑
+        User::query()->create([
+            'name' => $request->string('name'),
+            'password' => Hash::make($request->string('password')),
+        ]);
+
+        return response()->noContent();
+//        event(new Registered($user));
+//
+//        Auth::login($user);
+//
+//        return response()->noContent();
+    }
+
+    public function edit($id)
+    {
+        // 显示编辑用户的表单
+    }
+
+    public function update(Request $request, $id)
+    {
+        // 更新用户逻辑
+    }
+
+    public function destroy($id)
+    {
+        // 删除用户逻辑
+    }
+}

+ 52 - 4
app/Http/Services/Backend/Server/System/DictTypeService.php

@@ -8,18 +8,66 @@
 
 namespace App\Http\Services\Backend\Server\System;
 
+use App\Enums\Common\ErrorMessage;
 use App\Http\Services\Service;
 use App\Models\System\DictType;
+use Symfony\Component\HttpFoundation\Response;
 
 class DictTypeService extends Service
 {
+    protected array $selectColumn = ['id', 'name', 'remark', 'status', 'type'];
+
+    public function getDictType($id)
+    {
+        return DictType::query()->select($this->selectColumn)->find($id);
+    }
+
+    public function getDictTypeList($params): array
+    {
+        $dictType = DictType::query();
+        !empty($params['name']) && $dictType->whereLike('name', $params['name']);
+        !empty($params['type']) && $dictType->where('type', $params['type']);
+        !empty($params['status']) && $dictType->where('status', $params['status']);
+        !empty($params['createTime']) && $dictType->whereIn('created_at', $params['createTime']);
+        $select = ['id', 'name', 'remark', 'status', 'type', 'creator', 'created_at'];
+        $dictTypePage = DictType::query()->paginate($params['pageSize'], $select, 'page', $params['pageNo']);
+        return ['list' => $dictTypePage->items(), 'total' => $dictTypePage->total()];
+    }
+
     public function createDictType($data)
     {
-        // 校验字典类型的名字的唯一性
-        // 校验字典类型的类型的唯一性
+        // 校验字典类型的唯一性
+        $this->isExistType($data['name'], $data['type']);
 
         // 插入字典类型
-        $menu = self::toModel($data, DictType::class);
-        return $menu->create($menu->getAttributes())->id;
+        $dictType = self::toModel($data, DictType::class);
+        return $dictType->create($dictType->getAttributes())->id;
     }
+
+    public function updateDictType($data, $id)
+    {
+        empty($id) && self::error();
+        // 校验字典类型的唯一性
+        $this->isExistType($data['name'], $data['type'], $id);
+
+        // 插入字典类型
+        $dictType = self::toModel($data, DictType::class);
+        $dictType->where('id', $id)->update($dictType->getAttributes());
+    }
+
+    public function deleteDictType(int $id)
+    {
+        // 校验是否存在字典数据
+        return DictType::query()->find($id)->delete();
+    }
+
+    protected function isExistType($name, $type, $id = null)
+    {
+        $dict_id = DictType::query()->where('name', $name)->where('type', $type)->value('id');
+        if (!empty($dict_id) && $dict_id !== $id) {
+            // 写入日志
+            self::error(ErrorMessage::DICT_TYPE_DUPLICATE, Response::HTTP_UNPROCESSABLE_ENTITY);
+        }
+    }
+
 }

+ 2 - 3
app/Http/Services/Backend/Server/System/MenuService.php

@@ -12,7 +12,6 @@ use App\Enums\System\MenuType;
 use App\Exceptions\ApiException;
 use App\Http\Services\Service;
 use App\Models\System\Menu;
-use Illuminate\Support\Arr;
 use Symfony\Component\HttpFoundation\Response;
 
 class MenuService extends Service
@@ -78,9 +77,9 @@ class MenuService extends Service
     public function getMenuList($params = []): array
     {
         $menu = Menu::query();
-        $select = ['id','name','permission','type','sort','parent_id as parentId','path','icon','component','component_name as componentName','status','visible','keep_alive as keepAlive','always_show as alwaysShow'];
+        $select = ['id','name','type','sort','parent_id as parentId','path','icon','component','component_name as componentName','status','visible','keep_alive as keepAlive','always_show as alwaysShow'];
         !empty($params['name']) && $menu->whereLike('name', "%{$params['name']}%");
-        !empty($params['status']) && $menu->where('status', $params['status']);
+        !is_null($params['status']) && $menu->where('status', $params['status']);
         return $menu->orderBy('sort')->select($select)->get()->toArray();
     }
 

+ 5 - 0
app/Models/System/DictType.php

@@ -5,6 +5,7 @@ namespace App\Models\System;
 use App\Exceptions\ApiException;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\DB;
 use Spatie\Permission\Contracts\Permission as PermissionContract;
@@ -15,6 +16,10 @@ use Symfony\Component\HttpFoundation\Response;
 
 class DictType extends Model
 {
+    use SoftDeletes;
+
     protected $table = 'system_dict_type';
 
+    protected $guarded = [];
+
 }

+ 26 - 68
app/Models/System/Menu.php

@@ -3,106 +3,64 @@
 namespace App\Models\System;
 
 use App\Exceptions\ApiException;
-use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\DB;
-use Spatie\Permission\Contracts\Permission as PermissionContract;
-use Spatie\Permission\Exceptions\PermissionAlreadyExists;
 use Spatie\Permission\Guard;
-use Spatie\Permission\Models\Permission;
+use Spatie\Permission\Traits\HasPermissions;
 use Symfony\Component\HttpFoundation\Response;
 
-class Menu extends Permission
+class Menu extends Model
 {
-    protected $attributes = [
-        'title' => 'name'
-//        'name' => 'title',
-//        'permission' => 'name'
-    ];
+//    use HasPermissions;
+
+    protected $table = 'system_menus';
+
+    protected $attributes = [];
 
     public static $snakeAttributes = false;
 
-    protected $appends = ['title'];
+    protected $appends = ['permission'];
 
     protected $casts = [
-        'visible' => 'bool',
-        'keepAlive' => 'bool',
-        'alwaysShow' => 'bool',
+//        'visible' => 'bool',
+//        'keepAlive' => 'bool',
+//        'alwaysShow' => 'bool',
 //        'parent_id' => 'camel'
     ];
 
-    /**
-     * @throws ApiException
-     */
-    public static function create(array $attributes = [])
-    {
-        $attributes['guard_name'] = $attributes['guard_name'] ?? Guard::getDefaultName(static::class);
-        if (isset($attributes['permission']) && $attributes['permission']) {
-            $permission = static::getPermission(['permission' => $attributes['permission'], 'guard_name' => $attributes['guard_name']]);
-            if ($permission) {
-                throw new ApiException(['code' => Response::HTTP_UNPROCESSABLE_ENTITY, 'message' => 'PERMISSION_ALREADY_EXISTS']);
-            }
-        }
-        return static::query()->create($attributes);
-    }
-
-    /**
-     * @param array $attributes
-     * @param array $options
-     * @throws ApiException
-     */
-    public function update(array $attributes = [], array $options = []): void
-    {
-        $attributes['guard_name'] = $attributes['guard_name'] ?? Guard::getDefaultName(static::class);
-        if (isset($attributes['permission']) && $attributes['permission']) {
-            $permission = static::getPermission(['permission' => $attributes['permission'], 'guard_name' => $attributes['guard_name']]);
-            if ($permission && $permission->id !== $attributes['id']) {
-                throw new ApiException(['code' => Response::HTTP_UNPROCESSABLE_ENTITY, 'message' => 'PERMISSION_ALREADY_EXISTS']);
-            }
-        }
-        static::query()->where('id', $attributes['id'])->update($attributes, $options);
-        Cache::forget(config('permission.cache.key'));
-    }
-
-    public function setTitleAttribute($value)
-    {
-        $this->attributes['name'] =  $value;
-    }
-
-    public function getTitleAttribute()
-    {
-        return $this->attributes['name'];
-    }
-
-    public function setNameAttribute($value)
+    public function getPermissionAttribute()
     {
-        $this->attributes['permission'] =  $value;
-    }
-
-    public function getNameAttribute()
-    {
-        return $this->attributes['permission'];
+        $tableNames = config('permission.table_names');
+        $permission_ids = DB::table($tableNames['model_has_permissions'])->where('model_type', Menu::class)->where('model_id', $this->attributes['id'])->pluck('permission_id');
+        $permission_names = DB::table($tableNames['permissions'])->whereIn('id', $permission_ids)->pluck('name');
+        return implode('|', $permission_names->toArray());
     }
 
     public function setComponentNameAttribute($value)
     {
-        $this->attributes['component_name'] =  $value;
+        $this->attributes['component_name'] = $value;
     }
 
     public function setVisibleAttribute($value)
     {
-        $this->attributes['visible'] =  $value ? 1 : 0;
+        $this->attributes['visible'] = $value ? 1 : 0;
     }
 
     public function setAlwaysShowAttribute($value)
     {
-        $this->attributes['always_show'] =  $value ? 1 : 0;
+        $this->attributes['always_show'] = $value ? 1 : 0;
     }
 
+
+//    public function getVisibleAttribute($value)
+//    {
+//        $this->attributes['visible'] = !$value;
+//    }
+
     public function setKeepAliveAttribute($value)
     {
-        $this->attributes['keep_alive'] =  $value ? 1 : 0;
+        $this->attributes['keep_alive'] = $value ? 1 : 0;
     }
 
 }

+ 66 - 0
app/Models/System/Role.php

@@ -0,0 +1,66 @@
+<?php
+
+namespace App\Models\System;
+
+use Illuminate\Support\Facades\DB;
+use Spatie\Permission\Models\Role as PermissionRole;
+use Spatie\Permission\Traits\HasPermissions;
+use Spatie\Permission\Traits\RefreshesPermissionCache;
+
+class Role extends PermissionRole
+{
+    use HasPermissions;
+    use RefreshesPermissionCache;
+
+    public static function getMenus(array $role_ids)
+    {
+        $menu_ids = DB::table('system_role_has_menus')->whereIn('role_id',$role_ids)->pluck('menu_id')->all();
+        return DB::table('system_menus')->whereIn('id',$menu_ids)->where('status', 0)->get();
+    }
+//    public function __construct(array $attributes = [])
+//    {
+//        parent::__construct($attributes);
+//    }
+//
+//    /**
+//     * @throws ApiException
+//     */
+//    public static function create(array $attributes = [])
+//    {
+//        // 校验角色的唯一字段是否重复
+//        $role = self::getRoleByParam($attributes);
+//        $role && throw new ApiException(['code' => Response::HTTP_UNPROCESSABLE_ENTITY, 'message' => 'ROLE_CODE_DUPLICATE']);
+//        return static::query()->create($attributes);
+//    }
+//
+//    /**
+//     * @throws ApiException
+//     */
+//    public function update(array $attributes = [], array $options = []): bool|int
+//    {
+//        // 校验角色的唯一字段是否重复
+//        $role = self::getRoleByParam($attributes);
+//        $role && $role->id !== $attributes['id'] && throw new ApiException(['code' => Response::HTTP_UNPROCESSABLE_ENTITY, 'message' => 'ROLE_CODE_DUPLICATE']);
+//        // 获取角色的所有权限
+//        $permissions = $role->getPermissionNames();
+//        // 存在权限并清空权限缓存
+//        count($permissions) && Cache::forget(config('permission.cache.key'));
+//        return static::query()->where('id', $attributes['id'])->update($attributes, $options);
+//    }
+//
+//    private static function getRoleByParam(array &$attributes = []): PermissionRole|null
+//    {
+//        // 校验角色的唯一字段是否重复
+//        $attributes['guard_name'] = $attributes['guard_name'] ?? Guard::getDefaultName(static::class);
+//        $params = ['code' => $attributes['code'], 'guard_name' => $attributes['guard_name']];
+//        if (app(PermissionRegistrar::class)->teams) {
+//            $teamsKey = app(PermissionRegistrar::class)->teamsKey;
+//            if (array_key_exists($teamsKey, $attributes)) {
+//                $params[$teamsKey] = $attributes[$teamsKey];
+//            } else {
+//                $attributes[$teamsKey] = getPermissionsTeamId();
+//            }
+//        }
+//        return static::findByParam($params);
+//    }
+}

+ 7 - 3
app/Models/User.php → app/Models/System/User.php

@@ -1,15 +1,18 @@
 <?php
 
-namespace App\Models;
+namespace App\Models\System;
 
-// use Illuminate\Contracts\Auth\MustVerifyEmail;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Foundation\Auth\User as Authenticatable;
 use Illuminate\Notifications\Notifiable;
+use Laravel\Sanctum\HasApiTokens;
+use Spatie\Permission\Traits\HasRoles;
 
 class User extends Authenticatable
 {
-    use HasFactory, Notifiable;
+    use HasApiTokens, HasRoles, HasFactory, Notifiable;
+
+    protected $table = 'system_users';
 
     /**
      * The attributes that are mass assignable.
@@ -42,6 +45,7 @@ class User extends Authenticatable
         return [
             'email_verified_at' => 'datetime',
             'password' => 'hashed',
+            'last_activity_at' => 'datetime'
         ];
     }
 }

+ 1 - 1
bootstrap/providers.php

@@ -1,5 +1,5 @@
 <?php
 
 return [
-    App\Providers\AppServiceProvider::class,
+    App\Providers\AppServiceProvider::class
 ];

+ 186 - 0
config/permission.php

@@ -0,0 +1,186 @@
+<?php
+
+return [
+
+    'models' => [
+
+        /*
+         * When using the "HasPermissions" trait from this package, we need to know which
+         * Eloquent model should be used to retrieve your permissions. Of course, it
+         * is often just the "Permission" model but you may use whatever you like.
+         *
+         * The model you want to use as a Permission model needs to implement the
+         * `Spatie\Permission\Contracts\Permission` contract.
+         */
+
+        'permission' => Spatie\Permission\Models\Permission::class,
+
+        /*
+         * When using the "HasRoles" trait from this package, we need to know which
+         * Eloquent model should be used to retrieve your roles. Of course, it
+         * is often just the "Role" model but you may use whatever you like.
+         *
+         * The model you want to use as a Role model needs to implement the
+         * `Spatie\Permission\Contracts\Role` contract.
+         */
+
+        'role' => Spatie\Permission\Models\Role::class,
+
+    ],
+
+    'table_names' => [
+
+        /*
+         * When using the "HasRoles" trait from this package, we need to know which
+         * table should be used to retrieve your roles. We have chosen a basic
+         * default value but you may easily change it to any table you like.
+         */
+
+        'roles' => 'system_roles',
+
+        /*
+         * When using the "HasPermissions" trait from this package, we need to know which
+         * table should be used to retrieve your permissions. We have chosen a basic
+         * default value but you may easily change it to any table you like.
+         */
+
+        'permissions' => 'system_permissions',
+
+        /*
+         * When using the "HasPermissions" trait from this package, we need to know which
+         * table should be used to retrieve your models permissions. We have chosen a
+         * basic default value but you may easily change it to any table you like.
+         */
+
+        'model_has_permissions' => 'model_has_permissions',
+
+        /*
+         * When using the "HasRoles" trait from this package, we need to know which
+         * table should be used to retrieve your models roles. We have chosen a
+         * basic default value but you may easily change it to any table you like.
+         */
+
+        'model_has_roles' => 'model_has_roles',
+
+        /*
+         * When using the "HasRoles" trait from this package, we need to know which
+         * table should be used to retrieve your roles permissions. We have chosen a
+         * basic default value but you may easily change it to any table you like.
+         */
+
+        'role_has_permissions' => 'role_has_permissions',
+    ],
+
+    'column_names' => [
+        /*
+         * Change this if you want to name the related pivots other than defaults
+         */
+        'role_pivot_key' => null, //default 'role_id',
+        'permission_pivot_key' => null, //default 'permission_id',
+
+        /*
+         * Change this if you want to name the related model primary key other than
+         * `model_id`.
+         *
+         * For example, this would be nice if your primary keys are all UUIDs. In
+         * that case, name this `model_uuid`.
+         */
+
+        'model_morph_key' => 'model_id',
+
+        /*
+         * Change this if you want to use the teams feature and your related model's
+         * foreign key is other than `team_id`.
+         */
+
+        'team_foreign_key' => 'team_id',
+    ],
+
+    /*
+     * When set to true, the method for checking permissions will be registered on the gate.
+     * Set this to false if you want to implement custom logic for checking permissions.
+     */
+
+    'register_permission_check_method' => true,
+
+    /*
+     * When set to true, Laravel\Octane\Events\OperationTerminated event listener will be registered
+     * this will refresh permissions on every TickTerminated, TaskTerminated and RequestTerminated
+     * NOTE: This should not be needed in most cases, but an Octane/Vapor combination benefited from it.
+     */
+    'register_octane_reset_listener' => false,
+
+    /*
+     * Teams Feature.
+     * When set to true the package implements teams using the 'team_foreign_key'.
+     * If you want the migrations to register the 'team_foreign_key', you must
+     * set this to true before doing the migration.
+     * If you already did the migration then you must make a new migration to also
+     * add 'team_foreign_key' to 'roles', 'model_has_roles', and 'model_has_permissions'
+     * (view the latest version of this package's migration file)
+     */
+
+    'teams' => false,
+
+    /*
+     * Passport Client Credentials Grant
+     * When set to true the package will use Passports Client to check permissions
+     */
+
+    'use_passport_client_credentials' => false,
+
+    /*
+     * When set to true, the required permission names are added to exception messages.
+     * This could be considered an information leak in some contexts, so the default
+     * setting is false here for optimum safety.
+     */
+
+    'display_permission_in_exception' => false,
+
+    /*
+     * When set to true, the required role names are added to exception messages.
+     * This could be considered an information leak in some contexts, so the default
+     * setting is false here for optimum safety.
+     */
+
+    'display_role_in_exception' => false,
+
+    /*
+     * By default wildcard permission lookups are disabled.
+     * See documentation to understand supported syntax.
+     */
+
+    'enable_wildcard_permission' => false,
+
+    /*
+     * The class to use for interpreting wildcard permissions.
+     * If you need to modify delimiters, override the class and specify its name here.
+     */
+    // 'permission.wildcard_permission' => Spatie\Permission\WildcardPermission::class,
+
+    /* Cache-specific settings */
+
+    'cache' => [
+
+        /*
+         * By default all permissions are cached for 24 hours to speed up performance.
+         * When permissions or roles are updated the cache is flushed automatically.
+         */
+
+        'expiration_time' => \DateInterval::createFromDateString('24 hours'),
+
+        /*
+         * The cache key used to store all permissions.
+         */
+
+        'key' => 'spatie.permission.cache',
+
+        /*
+         * You may optionally indicate a specific cache driver to use for permission and
+         * role caching using any of the `store` drivers listed in the cache.php config
+         * file. Using 'default' here means to use the `default` set in cache.php.
+         */
+
+        'store' => 'default',
+    ],
+];

+ 1 - 1
database/migrations/0001_01_01_000000_create_system_users_table.php

@@ -25,7 +25,7 @@ return new class extends Migration
             $table->string('ip_address', 45)->nullable()->comment('最后登录IP');
             $table->timestamp('last_activity_at')->nullable()->comment('最后登录时间');
             $table->text('remark')->nullable()->comment('备注');
-            $table->tinyInteger('status')->default(0)->comment('账户状态 (1正常 0停用)');
+            $table->tinyInteger('status')->default(0)->comment('账户状态 (0正常 1停用)');
             $table->bigInteger('creator')->nullable()->comment('创建者');
             $table->bigInteger('updater')->nullable()->comment('更新者');
             $table->rememberToken();

+ 152 - 0
database/migrations/2024_08_14_093112_create_permission_tables.php

@@ -0,0 +1,152 @@
+<?php
+
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+return new class extends Migration {
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        $teams = config('permission.teams');
+        $tableNames = config('permission.table_names');
+        $columnNames = config('permission.column_names');
+        $pivotRole = $columnNames['role_pivot_key'] ?? 'role_id';
+        $pivotPermission = $columnNames['permission_pivot_key'] ?? 'permission_id';
+
+        if (empty($tableNames)) {
+            throw new \Exception('Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.');
+        }
+        if ($teams && empty($columnNames['team_foreign_key'] ?? null)) {
+            throw new \Exception('Error: team_foreign_key on config/permission.php not loaded. Run [php artisan config:clear] and try again.');
+        }
+
+        Schema::create($tableNames['permissions'], function (Blueprint $table) {
+            //$table->engine('InnoDB');
+            $table->bigIncrements('id'); // permission id
+            $table->string('name')->comment('权限名称');       // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format)
+            $table->string('guard_name')->default('web'); // For MyISAM use string('guard_name', 25);
+            $table->timestamps();
+
+            $table->unique(['name', 'guard_name']);
+        });
+
+        Schema::create($tableNames['roles'], function (Blueprint $table) use ($teams, $columnNames) {
+            //$table->engine('InnoDB');
+            $table->bigIncrements('id'); // role id
+            if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing
+                $table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable();
+                $table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index');
+            }
+            $table->string('name')->comment('角色名称');       // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format)
+            $table->string('guard_name')->default('web'); // For MyISAM use string('guard_name', 25);
+            $table->string('code', 100)->default('')->comment('角色权限标识');
+            $table->integer('sort')->default(0)->comment('显示顺序');
+            $table->tinyInteger('data_scope')->default(1)->comment('数据范围(1:全部数据 2:指定部门数据 3:所属部门数据 4:所属部门及下级数据)');
+            $table->json('data_scope_dept_ids')->nullable()->comment('数据范围(指定部门)');
+            $table->tinyInteger('status')->default(0)->comment('角色状态');
+            $table->tinyInteger('type')->comment('角色类型');
+            $table->text('remark')->nullable()->comment('备注');
+            $table->string('creator', 64)->nullable()->comment('创建者');
+            $table->string('updater', 64)->nullable()->comment('更新者');
+            $table->timestamps();
+            $table->softDeletes();
+
+            if ($teams || config('permission.testing')) {
+                $table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']);
+            } else {
+                $table->unique(['name', 'guard_name']);
+            }
+
+        });
+
+        Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames, $pivotPermission, $teams) {
+            $table->unsignedBigInteger($pivotPermission);
+
+            $table->string('model_type');
+            $table->unsignedBigInteger($columnNames['model_morph_key']);
+            $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index');
+
+            $table->foreign($pivotPermission)
+                ->references('id') // permission id
+                ->on($tableNames['permissions'])
+                ->onDelete('cascade');
+            if ($teams) {
+                $table->unsignedBigInteger($columnNames['team_foreign_key']);
+                $table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index');
+
+                $table->primary([$columnNames['team_foreign_key'], $pivotPermission, $columnNames['model_morph_key'], 'model_type'],
+                    'model_has_permissions_permission_model_type_primary');
+            } else {
+                $table->primary([$pivotPermission, $columnNames['model_morph_key'], 'model_type'],
+                    'model_has_permissions_permission_model_type_primary');
+            }
+
+        });
+
+        Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames, $pivotRole, $teams) {
+            $table->unsignedBigInteger($pivotRole);
+
+            $table->string('model_type');
+            $table->unsignedBigInteger($columnNames['model_morph_key']);
+            $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index');
+
+            $table->foreign($pivotRole)
+                ->references('id') // role id
+                ->on($tableNames['roles'])
+                ->onDelete('cascade');
+            if ($teams) {
+                $table->unsignedBigInteger($columnNames['team_foreign_key']);
+                $table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index');
+
+                $table->primary([$columnNames['team_foreign_key'], $pivotRole, $columnNames['model_morph_key'], 'model_type'],
+                    'model_has_roles_role_model_type_primary');
+            } else {
+                $table->primary([$pivotRole, $columnNames['model_morph_key'], 'model_type'],
+                    'model_has_roles_role_model_type_primary');
+            }
+        });
+
+        Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames, $pivotRole, $pivotPermission) {
+            $table->unsignedBigInteger($pivotPermission);
+            $table->unsignedBigInteger($pivotRole);
+
+            $table->foreign($pivotPermission)
+                ->references('id') // permission id
+                ->on($tableNames['permissions'])
+                ->onDelete('cascade');
+
+            $table->foreign($pivotRole)
+                ->references('id') // role id
+                ->on($tableNames['roles'])
+                ->onDelete('cascade');
+
+            $table->primary([$pivotPermission, $pivotRole], 'role_has_permissions_permission_id_role_id_primary');
+        });
+
+        app('cache')
+            ->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null)
+            ->forget(config('permission.cache.key'));
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        $tableNames = config('permission.table_names');
+
+        if (empty($tableNames)) {
+            throw new \Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.');
+        }
+
+        Schema::drop($tableNames['role_has_permissions']);
+        Schema::drop($tableNames['model_has_roles']);
+        Schema::drop($tableNames['model_has_permissions']);
+        Schema::drop($tableNames['roles']);
+        Schema::drop($tableNames['permissions']);
+    }
+};

+ 33 - 0
database/migrations/2024_08_26_111055_create_system_dict_type_table.php

@@ -0,0 +1,33 @@
+<?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::create('system_dict_type', function (Blueprint $table) {
+            $table->id()->comment('字典主键');
+            $table->string('name', 100)->comment('字典名称');
+            $table->string('type', 100)->comment('字典类型');
+            $table->tinyInteger('status')->default(0)->comment('状态(0正常 1停用)');
+            $table->string('remark', 500)->nullable()->comment('备注');
+            $table->string('creator', 64)->nullable()->comment('创建者');
+            $table->string('updater', 64)->nullable()->comment('更新者');
+            $table->timestamps();
+            $table->softDeletes();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('system_dict_type');
+    }
+};

+ 38 - 0
database/migrations/2024_08_27_031435_create_system_dict_data_table.php

@@ -0,0 +1,38 @@
+<?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::create('system_dict_data', function (Blueprint $table) {
+            $table->id()->comment('字典编码');
+            $table->integer('sort')->default(0)->comment('字典排序');
+            $table->string('label', 100)->comment('字典标签');
+            $table->string('value', 100)->comment('字典键值');
+            $table->string('dict_type', 100)->comment('字典类型');
+            $table->tinyInteger('status')->default(0)->comment('状态(0正常 1停用)');
+            $table->string('color_type', 100)->nullable()->comment('颜色类型');
+            $table->string('css_class', 100)->nullable()->comment('css 样式');
+            $table->string('remark', 500)->nullable()->comment('备注');
+            $table->string('creator', 64)->nullable()->comment('创建者');
+            $table->string('updater', 64)->nullable()->comment('更新者');
+            $table->timestamps();
+            $table->softDeletes();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('system_dict_data');
+    }
+};

+ 64 - 0
database/migrations/2024_08_29_032939_create_system_menus_table.php

@@ -0,0 +1,64 @@
+<?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
+    {
+        $tableNames = config('permission.table_names');
+
+        if (empty($tableNames)) {
+            throw new \Exception('Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.');
+        }
+
+        Schema::create('system_menus', function (Blueprint $table) {
+            $table->bigIncrements('id'); // permission id
+            $table->string('name', 50)->comment('菜单名称');
+            $table->tinyInteger('type')->comment('菜单类型');
+            $table->integer('sort')->default(0)->comment('显示顺序');
+            $table->bigInteger('parent_id')->default(0)->comment('父菜单ID');
+            $table->string('path', 200)->nullable()->comment('路由地址');
+            $table->string('icon', 100)->nullable()->comment('菜单图标');
+            $table->string('component')->nullable()->comment('组件路径');
+            $table->string('component_name')->nullable()->comment('组件名');
+            $table->tinyInteger('status')->default(0)->comment('菜单状态');
+            $table->tinyInteger('visible')->default(1)->comment('是否可见');
+            $table->tinyInteger('keep_alive')->default(1)->comment('是否缓存');
+            $table->tinyInteger('always_show')->default(1)->comment('是否总是显示');
+            $table->string('creator', 64)->nullable()->comment('创建者');
+            $table->string('updater', 64)->nullable()->comment('更新者');
+            $table->timestamps();
+        });
+
+        Schema::create('system_role_has_menus', function (Blueprint $table) use ($tableNames) {
+            $table->bigIncrements('id');
+            $table->unsignedBigInteger('menu_id');
+            $table->unsignedBigInteger('role_id');
+
+            $table->foreign('menu_id')
+                ->references('id')
+                ->on('system_menus')
+                ->onDelete('cascade');
+
+            $table->foreign('role_id')
+                ->references('id')
+                ->on($tableNames['roles'])
+                ->onDelete('cascade');
+
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('system_menus');
+    }
+};

+ 1 - 0
database/seeders/DatabaseSeeder.php

@@ -20,6 +20,7 @@ class DatabaseSeeder extends Seeder
             SystemMenusTableSeeder::class,
             SystemPermissionsTableSeeder::class,
             SystemRoleHasPermissionsTableSeeder::class,
+            SystemDictTableSeeder::class
             // 其他Seeder类...
         ]);
     }

+ 29 - 0
database/seeders/SystemDictTableSeeder.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace Database\Seeders;
+
+use Illuminate\Database\Console\Seeds\WithoutModelEvents;
+use Illuminate\Database\Seeder;
+use Illuminate\Support\Facades\DB;
+
+class SystemDictTableSeeder extends Seeder
+{
+    /**
+     * Run the database seeds.
+     */
+    public function run(): void
+    {
+        //
+        DB::table('system_dict_type')->insert(['id' => 10, 'name' => '系统状态', 'type' => 'common_status', 'creator' => '系统']);
+        //DB::table('system_dict_type')->insert(['id' => 110, 'name' => '角色类型', 'type' => 'system_role_type', 'creator' => '系统']);
+
+        DB::table('system_dict_data')->insert(['label' => '开启', 'value' => 0, 'dict_type' => 'common_status', 'creator' => '系统']);
+        DB::table('system_dict_data')->insert(['label' => '关闭', 'value' => 1, 'dict_type' => 'common_status', 'creator' => '系统']);
+
+
+        DB::table('system_dict_data')->insert(['label' => '目录', 'value' => 1, 'dict_type' => 'system_menu_type', 'creator' => '系统']);
+        DB::table('system_dict_data')->insert(['label' => '菜单', 'value' => 2, 'dict_type' => 'system_menu_type', 'creator' => '系统']);
+        DB::table('system_dict_data')->insert(['label' => '按钮', 'value' => 3, 'dict_type' => 'system_menu_type', 'creator' => '系统']);
+
+    }
+}

+ 60 - 0
database/seeders/SystemMenusTableSeeder.php

@@ -0,0 +1,60 @@
+<?php
+
+namespace Database\Seeders;
+
+use App\Models\System\Menu;
+use Illuminate\Database\Console\Seeds\WithoutModelEvents;
+use Illuminate\Database\Seeder;
+use Illuminate\Support\Facades\DB;
+
+class SystemMenusTableSeeder extends Seeder
+{
+    /**
+     * Run the database seeds.
+     */
+    public function run(): void
+    {
+        // 目录
+        DB::table('system_menus')->insert(['id' => 1, 'name' => '系统菜单', 'type' => 1, 'path' => '/system', 'icon' => 'ep:tools', 'creator' => '系统']);
+
+        // 菜单
+        DB::table('system_menus')->insert(['id' => 100, 'name' => '用户管理', 'type' => 2, 'parent_id' => 1, 'path' => 'user', 'icon' => 'ep:avatar', 'creator' => '系统']);
+        DB::table('system_menus')->insert(['id' => 110, 'name' => '角色管理', 'type' => 2, 'parent_id' => 1, 'path' => 'role', 'icon' => 'ep:user', 'component' => 'system/role/index', 'component_name' => 'SystemRole', 'creator' => '系统']);
+        DB::table('system_menus')->insert(['id' => 120, 'name' => '菜单管理', 'type' => 2, 'parent_id' => 1, 'path' => 'menu', 'icon' => 'ep:menu', 'component' => 'system/menu/index', 'component_name' => 'SystemMenu', 'creator' => '系统']);
+        DB::table('system_menus')->insert(['id' => 130, 'name' => '部门管理', 'type' => 2, 'parent_id' => 1, 'path' => 'menu', 'icon' => 'ep:menu', 'component' => 'system/menu/index', 'component_name' => 'SystemMenu', 'creator' => '系统']);
+        DB::table('system_menus')->insert(['id' => 140, 'name' => '岗位管理', 'type' => 2, 'parent_id' => 1, 'path' => 'menu', 'icon' => 'ep:menu', 'component' => 'system/menu/index', 'component_name' => 'SystemMenu', 'creator' => '系统']);
+        DB::table('system_menus')->insert(['id' => 150, 'name' => '字典管理', 'type' => 2, 'parent_id' => 1, 'path' => 'dict', 'icon' => 'ep:collection', 'component' => 'system/dict/index', 'component_name' => 'SystemDictType', 'creator' => '系统']);
+
+        // 按钮
+        // 菜单管理
+        DB::table('system_menus')->insert(['id' => 121, 'name' => '菜单查询', 'type' => 3, 'parent_id' => 120, 'creator' => '系统']);
+        DB::table('system_menus')->insert(['id' => 122, 'name' => '菜单新增', 'type' => 3, 'parent_id' => 120, 'creator' => '系统']);
+        DB::table('system_menus')->insert(['id' => 123, 'name' => '菜单修改', 'type' => 3, 'parent_id' => 120, 'creator' => '系统']);
+        DB::table('system_menus')->insert(['id' => 124, 'name' => '菜单删除', 'type' => 3, 'parent_id' => 120, 'creator' => '系统']);
+        // 字典管理
+        DB::table('system_menus')->insert(['id' => 151, 'name' => '字典查询', 'type' => 3, 'parent_id' => 150, 'creator' => '系统']);
+        DB::table('system_menus')->insert(['id' => 152, 'name' => '字典新增', 'type' => 3, 'parent_id' => 150, 'creator' => '系统']);
+        DB::table('system_menus')->insert(['id' => 153, 'name' => '字典修改', 'type' => 3, 'parent_id' => 150, 'creator' => '系统']);
+        DB::table('system_menus')->insert(['id' => 154, 'name' => '字典删除', 'type' => 3, 'parent_id' => 150, 'creator' => '系统']);
+        DB::table('system_menus')->insert(['id' => 155, 'name' => '字典导出', 'type' => 3, 'parent_id' => 150, 'creator' => '系统']);
+
+
+        // 角色菜单
+        // 菜单管理
+        DB::table('system_role_has_menus')->insert(['menu_id' => 1, 'role_id' => 1]);
+        DB::table('system_role_has_menus')->insert(['menu_id' => 120, 'role_id' => 1]);
+        DB::table('system_role_has_menus')->insert(['menu_id' => 121, 'role_id' => 1]);
+        DB::table('system_role_has_menus')->insert(['menu_id' => 122, 'role_id' => 1]);
+        DB::table('system_role_has_menus')->insert(['menu_id' => 123, 'role_id' => 1]);
+        DB::table('system_role_has_menus')->insert(['menu_id' => 124, 'role_id' => 1]);
+        // 字典管理
+        DB::table('system_role_has_menus')->insert(['menu_id' => 150, 'role_id' => 1]);
+        DB::table('system_role_has_menus')->insert(['menu_id' => 151, 'role_id' => 1]);
+        DB::table('system_role_has_menus')->insert(['menu_id' => 152, 'role_id' => 1]);
+        DB::table('system_role_has_menus')->insert(['menu_id' => 153, 'role_id' => 1]);
+        DB::table('system_role_has_menus')->insert(['menu_id' => 154, 'role_id' => 1]);
+        DB::table('system_role_has_menus')->insert(['menu_id' => 155, 'role_id' => 1]);
+
+
+    }
+}

+ 21 - 0
database/seeders/SystemModelHasRolesTableSeeder.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace Database\Seeders;
+
+use App\Models\System\User;
+use Illuminate\Database\Console\Seeds\WithoutModelEvents;
+use Illuminate\Database\Seeder;
+use Illuminate\Support\Facades\DB;
+
+class SystemModelHasRolesTableSeeder extends Seeder
+{
+    /**
+     * Run the database seeds.
+     */
+    public function run(): void
+    {
+        //
+        DB::table('model_has_roles')->insert(['role_id' => 1, 'model_type' => User::class, 'model_id' => 1]);
+
+    }
+}

+ 56 - 0
database/seeders/SystemPermissionsTableSeeder.php

@@ -0,0 +1,56 @@
+<?php
+
+namespace Database\Seeders;
+
+use App\Models\System\Menu;
+use Illuminate\Database\Console\Seeds\WithoutModelEvents;
+use Illuminate\Database\Seeder;
+use Illuminate\Support\Facades\DB;
+
+class SystemPermissionsTableSeeder extends Seeder
+{
+    /**
+     * Run the database seeds.
+     */
+    public function run(): void
+    {
+        //
+        DB::table('system_permissions')->insert(['name' => 'system:user:query']);
+        DB::table('system_permissions')->insert(['name' => 'system:user:create']);
+        DB::table('system_permissions')->insert(['name' => 'system:user:update']);
+        DB::table('system_permissions')->insert(['name' => 'system:user:delete']);
+        DB::table('system_permissions')->insert(['name' => 'system:user:export']);
+        DB::table('system_permissions')->insert(['name' => 'system:user:import']);
+        DB::table('system_permissions')->insert(['name' => 'system:user:update-password']);
+
+        DB::table('system_permissions')->insert(['name' => 'system:role:query']);
+        DB::table('system_permissions')->insert(['name' => 'system:role:create']);
+        DB::table('system_permissions')->insert(['name' => 'system:role:update']);
+        DB::table('system_permissions')->insert(['name' => 'system:role:delete']);
+        DB::table('system_permissions')->insert(['name' => 'system:role:export']);
+
+        DB::table('system_permissions')->insert(['id' => 121,'name' => 'system:menu:query']);
+        DB::table('system_permissions')->insert(['id' => 122,'name' => 'system:menu:create']);
+        DB::table('system_permissions')->insert(['id' => 123,'name' => 'system:menu:update']);
+        DB::table('system_permissions')->insert(['id' => 124,'name' => 'system:menu:delete']);
+
+        DB::table('model_has_permissions')->insert(['permission_id' => 121,'model_type' => Menu::class, 'model_id' => 121]);
+        DB::table('model_has_permissions')->insert(['permission_id' => 122,'model_type' => Menu::class, 'model_id' => 122]);
+        DB::table('model_has_permissions')->insert(['permission_id' => 123,'model_type' => Menu::class, 'model_id' => 123]);
+        DB::table('model_has_permissions')->insert(['permission_id' => 124,'model_type' => Menu::class, 'model_id' => 124]);
+
+        // 字典管理
+        DB::table('system_permissions')->insert(['id' => 151,'name' => 'system:dict:query']);
+        DB::table('system_permissions')->insert(['id' => 152,'name' => 'system:dict:create']);
+        DB::table('system_permissions')->insert(['id' => 153,'name' => 'system:dict:update']);
+        DB::table('system_permissions')->insert(['id' => 154,'name' => 'system:dict:delete']);
+        DB::table('system_permissions')->insert(['id' => 155,'name' => 'system:dict:export']);
+
+        DB::table('model_has_permissions')->insert(['permission_id' => 151,'model_type' => Menu::class, 'model_id' => 151]);
+        DB::table('model_has_permissions')->insert(['permission_id' => 152,'model_type' => Menu::class, 'model_id' => 152]);
+        DB::table('model_has_permissions')->insert(['permission_id' => 153,'model_type' => Menu::class, 'model_id' => 153]);
+        DB::table('model_has_permissions')->insert(['permission_id' => 154,'model_type' => Menu::class, 'model_id' => 154]);
+        DB::table('model_has_permissions')->insert(['permission_id' => 155,'model_type' => Menu::class, 'model_id' => 155]);
+
+    }
+}

+ 28 - 0
database/seeders/SystemRoleHasPermissionsTableSeeder.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace Database\Seeders;
+
+use Illuminate\Database\Console\Seeds\WithoutModelEvents;
+use Illuminate\Database\Seeder;
+use Illuminate\Support\Facades\DB;
+
+class SystemRoleHasPermissionsTableSeeder extends Seeder
+{
+    /**
+     * Run the database seeds.
+     */
+    public function run(): void
+    {
+        // 菜单权限
+        DB::table('role_has_permissions')->insert(['permission_id' => 121, 'role_id' => 1]);
+        DB::table('role_has_permissions')->insert(['permission_id' => 122, 'role_id' => 1]);
+        DB::table('role_has_permissions')->insert(['permission_id' => 123, 'role_id' => 1]);
+        DB::table('role_has_permissions')->insert(['permission_id' => 124, 'role_id' => 1]);
+        // 字典管理
+        DB::table('role_has_permissions')->insert(['permission_id' => 151, 'role_id' => 1]);
+        DB::table('role_has_permissions')->insert(['permission_id' => 152, 'role_id' => 1]);
+        DB::table('role_has_permissions')->insert(['permission_id' => 153, 'role_id' => 1]);
+        DB::table('role_has_permissions')->insert(['permission_id' => 154, 'role_id' => 1]);
+        DB::table('role_has_permissions')->insert(['permission_id' => 155, 'role_id' => 1]);
+    }
+}

+ 22 - 0
database/seeders/SystemRolesTableSeeder.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace Database\Seeders;
+
+use Illuminate\Database\Console\Seeds\WithoutModelEvents;
+use Illuminate\Database\Seeder;
+use Illuminate\Support\Facades\DB;
+
+class SystemRolesTableSeeder extends Seeder
+{
+    /**
+     * Run the database seeds.
+     */
+    public function run(): void
+    {
+        $tableNames = config('permission.table_names');
+
+        //
+        DB::table($tableNames['roles'])->insert(['id' => 1, 'name' => '超级管理员', 'code' => 'super_admin', 'type' => 1, 'creator' => '系统']);
+
+    }
+}

+ 22 - 0
database/seeders/SystemUsersTableSeeder.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace Database\Seeders;
+
+use App\Models\System\User;
+use Illuminate\Database\Console\Seeds\WithoutModelEvents;
+use Illuminate\Database\Seeder;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Hash;
+
+class SystemUsersTableSeeder extends Seeder
+{
+    /**
+     * Run the database seeds.
+     */
+    public function run(): void
+    {
+        //
+        DB::table('system_users')->insert(['id' => 1, 'name' => 'administrator', 'password' => '$2y$12$FD.RtwKBvPN.9dHRf00/7O3u447/YACyY.daCb9Ctblm3IQPRosTW']);
+        DB::table('system_users')->insert(['id' => 2, 'name' => 'admin', 'password' => Hash::make('admin')]);
+    }
+}