Browse Source

登录用户权限控制、菜单权限控制

master
wanghongjun 1 month ago
parent
commit
44524b4591
  1. 35
      app/Http/Controllers/Admin/BaseController.php
  2. 16
      app/Http/Controllers/Admin/RolesController.php
  3. 19
      app/Http/Controllers/Admin/UserController.php
  4. 3
      app/Http/Kernel.php
  5. 80
      app/Http/Middleware/CheckPermission.php
  6. 58
      app/Services/AdminMenuService.php
  7. 34
      app/Services/AdminUsersService.php
  8. 2
      database/migrations/2026_01_27_084640_create_admin_table.php
  9. 176
      database/seeders/AdminMenuSeeder.php
  10. 6
      routes/admin/api.php

35
app/Http/Controllers/Admin/BaseController.php

@ -3,9 +3,12 @@
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Services\AdminMenuService;
use Exception;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException; use Illuminate\Validation\ValidationException;
use Exception; use Psr\SimpleCache\InvalidArgumentException;
class BaseController extends Controller class BaseController extends Controller
{ {
@ -34,4 +37,34 @@ class BaseController extends Controller
}; };
} }
/**
* 功能显示权限
* @param string $className
* @param array $auth
* @return int[]
* @throws InvalidArgumentException
*/
protected function methodShow(string $className, array $auth = []): array
{
$user = Auth::guard('sanctum')->user();
$methodAuthArr = AdminMenuService::auth($user->id);
$authArr = [
$className . '/show' => 0,
$className . '/store' => 0,
$className . '/update' => 0,
$className . '/destroy' => 0,
];
$newArr = [];
foreach ($authArr as $authKey => $value) {
if (in_array($authKey, $methodAuthArr)) {
$authArr[$authKey] = 1;
}
$key = explode('/',$authKey);
$newArr[$key[1]] = $authArr[$authKey];
}
if ($auth) {
$newArr = array_merge($newArr, $auth);
}
return $newArr;
}
} }

16
app/Http/Controllers/Admin/RolesController.php

@ -13,6 +13,7 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException; use Illuminate\Validation\ValidationException;
use Psr\SimpleCache\InvalidArgumentException;
class RolesController extends BaseController class RolesController extends BaseController
{ {
@ -233,4 +234,19 @@ class RolesController extends BaseController
); );
} }
} }
/**
* @return JsonResponse
* @throws InvalidArgumentException
*/
public function rule(): JsonResponse
{
try {
return $this->responseService->success($this->methodShow('roles'));
} catch (Exception $e) {
return $this->responseService->systemError(
__('exception.get_data_failed') . ':' . $e->getMessage()
);
}
}
} }

19
app/Http/Controllers/Admin/UserController.php

@ -12,6 +12,7 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException; use Illuminate\Validation\ValidationException;
use Psr\SimpleCache\InvalidArgumentException;
class UserController extends BaseController class UserController extends BaseController
{ {
@ -38,7 +39,8 @@ class UserController extends BaseController
} }
/** /**
* Display a listing of the resource. * @param Request $request
* @return JsonResponse
*/ */
public function index(Request $request): JsonResponse public function index(Request $request): JsonResponse
{ {
@ -260,4 +262,19 @@ class UserController extends BaseController
); );
} }
} }
/**
* @return JsonResponse
* @throws InvalidArgumentException
*/
public function rule(): JsonResponse
{
try {
return $this->responseService->success($this->methodShow('users'));
} catch (Exception $e) {
return $this->responseService->systemError(
__('exception.get_data_failed') . ':' . $e->getMessage()
);
}
}
} }

3
app/Http/Kernel.php

@ -43,7 +43,8 @@ class Kernel extends HttpKernel
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api', \Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
\Illuminate\Routing\Middleware\SubstituteBindings::class, \Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\ApiResponseMiddleware::class, \App\Http\Middleware\ApiResponseMiddleware::class,
\App\Http\Middleware\LanguageSwitcher::class \App\Http\Middleware\LanguageSwitcher::class,
\App\Http\Middleware\CheckPermission::class,//用户权限中间件
], ],
]; ];

80
app/Http/Middleware/CheckPermission.php

@ -0,0 +1,80 @@
<?php
namespace App\Http\Middleware;
use App\Models\AdminRoleUsers;
use App\Services\AdminMenuService;
use App\Services\ApiResponseService;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Psr\SimpleCache\InvalidArgumentException;
use Symfony\Component\HttpFoundation\Response;
class CheckPermission
{
/**
* @param Request $request
* @param Closure $next
* @return Response
* @throws InvalidArgumentException
*/
public function handle(Request $request, Closure $next): Response
{
if (Auth::guard('sanctum')->check()) {
$action = $request->route()->getCompiled()->getStaticPrefix();
$user = Auth::guard('sanctum')->user();
$user_id = $user->id;
$uriArr = AdminMenuService::auth($user_id);
if ($this->passedOrNot($action, $uriArr)) {
return (new ApiResponseService())->error(
__('middleware.check.user_auth'),
400
);
}
}
return $next($request);
}
/**
* @param $action
* @param $uriArr
* @return bool
*/
protected function passedOrNot($action, $uriArr): bool
{
$characters = '/api/admin/';
$action = ltrim($action, $characters);
if (in_array($action, $uriArr)) {
return false;
}
$methodArr = ['create', 'edit'];
$actionArr = explode('/', trim($action));
$method = $actionArr[1] ?? '';
$newAction = $actionArr[0] ?? '';
// 特殊
if (in_array($newAction, ['logout', 'me'])) {
return false;
}
// 特殊
if (in_array($method, ['rule', 'import'])) {
return false;
}
if ($method == $methodArr[0]) {
$newAction .= '/store';
} elseif($method == $methodArr[1]) {
$newAction .= '/update';
}
if (in_array($newAction, $uriArr)) {
return false;
}
return true;
}
}

58
app/Services/AdminMenuService.php

@ -3,9 +3,12 @@
namespace App\Services; namespace App\Services;
use App\Models\AdminMenu; use App\Models\AdminMenu;
use App\Models\AdminRoleMenu;
use App\Models\AdminRoles; use App\Models\AdminRoles;
use App\Models\AdminRoleUsers; use App\Models\AdminRoleUsers;
use App\Models\AdminUsers; use App\Models\AdminUsers;
use Illuminate\Support\Facades\Cache;
use Psr\SimpleCache\InvalidArgumentException;
final class AdminMenuService final class AdminMenuService
{ {
@ -15,6 +18,22 @@ final class AdminMenuService
*/ */
protected array $adminRoleMenus = []; protected array $adminRoleMenus = [];
/**
* @param array $role_ids
* @return array
*/
public static function getRoleMenuUri(array $role_ids): array
{
$menu_ids = AdminRoleMenu::query()->whereIn('role_id', $role_ids)
->pluck('menu_id')->toArray();
if ($menu_ids) {
$menuWhere = [['status', '=', 1], ['uri', '<>', '']];
return AdminMenu::query()->whereIn('id', $menu_ids)
->where($menuWhere)->pluck('uri')->toArray();
}
return [];
}
/** /**
* 缓存菜单 * 缓存菜单
* @param array $adminRoleMenus * @param array $adminRoleMenus
@ -29,14 +48,20 @@ final class AdminMenuService
/** /**
* 获取菜单 * 获取菜单
* @param array $menus_id * @param array $menus_id
* @param int $is_show
* @return array * @return array
*/ */
public function getMenuTreeList(array $menus_id = []): array public function getMenuTreeList(
{ array $menus_id = [],
int $is_show = 0
): array {
$model = AdminMenu::query(); $model = AdminMenu::query();
if ($menus_id) { if ($menus_id) {
$model->wherein('id', $menus_id); $model->wherein('id', $menus_id);
} }
if ($is_show) {
$model->where('show', 1);
}
$list = $model->orderBy('order') $list = $model->orderBy('order')
->orderBy('id') ->orderBy('id')
->select() ->select()
@ -53,15 +78,40 @@ final class AdminMenuService
public function getUserMenuTreeList($user_id): array public function getUserMenuTreeList($user_id): array
{ {
$AdminUsers = AdminUsers::find($user_id); $AdminUsers = AdminUsers::find($user_id);
$roles_id = $AdminUsers->roles()->where('status', 1)->pluck('id')->toArray(); $roles_id = $AdminUsers->roles()->where('status', 1)->pluck('id')
->toArray();
if (!$roles_id) { if (!$roles_id) {
return []; return [];
} }
$AdminRoles = AdminRoles::find($roles_id[0]); $AdminRoles = AdminRoles::find($roles_id[0]);
$menus_id = $AdminRoles->menus()->where('status', 1)->pluck('id')->toArray(); $menus_id = $AdminRoles->menus()->where('status', 1)->pluck('id')
->toArray();
if (!$menus_id) { if (!$menus_id) {
return []; return [];
} }
return $this->getMenuTreeList($menus_id); return $this->getMenuTreeList($menus_id);
} }
/**
* 用户角色菜单接口访问权限
* @param $user_id
* @return array
* @throws InvalidArgumentException
*/
public static function auth($user_id): array
{
$names = 'adminUserRules';
$key = $names . $user_id;
$uriArr = Cache::tags($names)->get($key);
if (!$uriArr) {
$role_ids = AdminRoleUsers::query()->where('user_id', $user_id)
->pluck('role_id')->toArray();
$uriArr = [];
if ($role_ids) {
$uriArr = AdminMenuService::getRoleMenuUri($role_ids);
}
Cache::tags($names)->set($key, $uriArr, 36000);
}
return $uriArr;
}
} }

34
app/Services/AdminUsersService.php

@ -108,22 +108,26 @@ final class AdminUsersService
// 角色id // 角色id
$role_id = $data['role_id']; $role_id = $data['role_id'];
$oldAdminRoleUsers = AdminRoleUsers::query()->where('user_id', $id) $oldAdminRoleUsers = AdminRoleUsers::query()
->where('user_id', $id)
->where('role_id', $role_id)
->get()->toArray(); ->get()->toArray();
$updateData = [ if (!$oldAdminRoleUsers) {
'role_id' => $role_id, $updateData = [
'updated_at' => get_datetime() 'role_id' => $role_id,
]; 'updated_at' => get_datetime()
AdminRoleUsers::query()->where('user_id', $id)->update($updateData); ];
$newAdminRoleUsers = $oldAdminRoleUsers; AdminRoleUsers::query()->where('user_id', $id)->update($updateData);
$newAdminRoleUsers['role_id'] = $role_id; $newAdminRoleUsers = $oldAdminRoleUsers;
$newAdminRoleUsers['updated_at'] = $updateData['updated_at']; $newAdminRoleUsers['role_id'] = $role_id;
$this->logService->logUpdatedData( $newAdminRoleUsers['updated_at'] = $updateData['updated_at'];
new AdminRoleUsers(), $this->logService->logUpdatedData(
$oldAdminRoleUsers, new AdminRoleUsers(),
'更新用户关联角色', $oldAdminRoleUsers,
$newAdminRoleUsers '更新用户关联角色',
); $newAdminRoleUsers
);
}
// //
$packing_id = $data['packing_id']; $packing_id = $data['packing_id'];

2
database/migrations/2026_01_27_084640_create_admin_table.php

@ -56,7 +56,7 @@ return new class extends Migration
$table->string('title', 50)->comment('菜单标题'); $table->string('title', 50)->comment('菜单标题');
$table->string('icon', 50)->comment('菜单图标'); $table->string('icon', 50)->comment('菜单图标');
$table->string('uri')->nullable()->comment('链接地址'); $table->string('uri')->nullable()->comment('链接地址');
$table->string('permission')->nullable(); $table->string('show')->default(1)->comment('是否显示 0否 1是');
$table->tinyInteger('status')->default(1)->comment('状态 0禁用 1启用'); $table->tinyInteger('status')->default(1)->comment('状态 0禁用 1启用');
$table->timestamps(); $table->timestamps();
$table->innoDb(); $table->innoDb();

176
database/seeders/AdminMenuSeeder.php

@ -22,93 +22,143 @@ class AdminMenuSeeder extends Seeder
$not_datetime = get_datetime(); $not_datetime = get_datetime();
return [ return [
[ [
'id' => 1, 'id' => 1,
'parent_id' => 0, 'parent_id' => 0,
'order' => 0, 'order' => 0,
'title' => '模式管理', 'title' => '模式管理',
'icon' => '', 'icon' => '',
'uri' => '', 'uri' => '',
'permission' => '', 'show' => 1,
'created_at' => $not_datetime 'created_at' => $not_datetime
], ],
[ [
'id' => 2, 'id' => 2,
'parent_id' => 0, 'parent_id' => 0,
'order' => 0, 'order' => 0,
'title' => '车位状态', 'title' => '车位状态',
'icon' => '', 'icon' => '',
'uri' => '', 'uri' => '',
'permission' => '', 'show' => 1,
'created_at' => $not_datetime 'created_at' => $not_datetime
], ],
[ [
'id' => 3, 'id' => 3,
'parent_id' => 0, 'parent_id' => 0,
'order' => 0, 'order' => 0,
'title' => '特别车位管理', 'title' => '特别车位管理',
'icon' => '', 'icon' => '',
'uri' => '', 'uri' => '',
'permission' => '', 'show' => 1,
'created_at' => $not_datetime 'created_at' => $not_datetime
], ],
[ [
'id' => 4, 'id' => 4,
'parent_id' => 0, 'parent_id' => 0,
'order' => 0, 'order' => 0,
'title' => '信息中心', 'title' => '信息中心',
'icon' => '', 'icon' => '',
'uri' => '', 'uri' => '',
'permission' => '', 'show' => 1,
'created_at' => $not_datetime 'created_at' => $not_datetime
], ],
[ [
'id' => 5, 'id' => 5,
'parent_id' => 0, 'parent_id' => 0,
'order' => 0, 'order' => 0,
'title' => '统计报表', 'title' => '统计报表',
'icon' => '', 'icon' => '',
'uri' => '', 'uri' => '',
'permission' => '', 'show' => 1,
'created_at' => $not_datetime 'created_at' => $not_datetime
], ],
[ [
'id' => 6, 'id' => 6,
'parent_id' => 0, 'parent_id' => 0,
'order' => 0, 'order' => 0,
'title' => '设备管理', 'title' => '设备管理',
'icon' => '', 'icon' => '',
'uri' => '', 'uri' => '',
'permission' => '', 'show' => 1,
'created_at' => $not_datetime 'created_at' => $not_datetime
], ],
[ [
'id' => 7, 'id' => 7,
'parent_id' => 0, 'parent_id' => 0,
'order' => 0, 'order' => 0,
'title' => '系统管理', 'title' => '系统管理',
'icon' => '', 'icon' => '',
'uri' => '', 'uri' => '',
'permission' => '', 'show' => 1,
'created_at' => $not_datetime 'created_at' => $not_datetime
], ],
[ [
'id' => 8, 'id' => 8,
'parent_id' => 7, 'parent_id' => 0,
'order' => 0, 'order' => 0,
'title' => '用户管理', 'title' => '用户管理',
'icon' => '', 'icon' => '',
'uri' => '', 'uri' => '',
'permission' => '', 'show' => 1,
'created_at' => $not_datetime 'created_at' => $not_datetime
], ],
[ [
'id' => 9, 'id' => 9,
'parent_id' => 7, 'parent_id' => 0,
'order' => 0, 'order' => 0,
'title' => '角色管理', 'title' => '角色管理',
'icon' => '', 'icon' => '',
'uri' => '', 'uri' => '',
'permission' => '', 'show' => 1,
'created_at' => $not_datetime
],
[
'id' => 10,
'parent_id' => 8,
'order' => 0,
'title' => '只读',
'icon' => '',
'uri' => 'users.index',
'show' => 0,
'created_at' => $not_datetime
],
[
'id' => 11,
'parent_id' => 8,
'order' => 0,
'title' => '查看',
'icon' => '',
'uri' => 'users.show',
'show' => 0,
'created_at' => $not_datetime
],
[
'id' => 12,
'parent_id' => 8,
'order' => 0,
'title' => '添加',
'icon' => '',
'uri' => 'users.store',
'show' => 0,
'created_at' => $not_datetime
],
[
'id' => 13,
'parent_id' => 8,
'order' => 0,
'title' => '编辑',
'icon' => '',
'uri' => 'users.update',
'show' => 0,
'created_at' => $not_datetime
],
[
'id' => 14,
'parent_id' => 8,
'order' => 0,
'title' => '删除',
'icon' => '',
'uri' => 'users.destroy',
'show' => 0,
'created_at' => $not_datetime 'created_at' => $not_datetime
], ],
]; ];

6
routes/admin/api.php

@ -12,7 +12,6 @@ Route::group(['prefix' => 'admin'], function () {
Route::post('/login', [AuthController::class, 'login']); Route::post('/login', [AuthController::class, 'login']);
// get测试区 // get测试区
Route::resource('users', UserController::class);
// 需要认证的接口 // 需要认证的接口
Route::middleware(['admin.auth'])->group(function () { Route::middleware(['admin.auth'])->group(function () {
@ -23,7 +22,10 @@ Route::group(['prefix' => 'admin'], function () {
Route::get('/index', [IndexController::class, 'index']); Route::get('/index', [IndexController::class, 'index']);
Route::get('/menu', [IndexController::class, 'menu']); Route::get('/menu', [IndexController::class, 'menu']);
// 角色 // 角色
Route::resource('roles', RolesController::class); Route::apiResource('roles', RolesController::class);
Route::get('/role/rule', [RolesController::class, 'rule']);
// 用户 // 用户
Route::apiResource('users', UserController::class);
Route::get('/user/rule', [UserController::class, 'rule']);
}); });
}); });

Loading…
Cancel
Save