更新
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\mcp\service;
|
||||
|
||||
use app\adminapi\logic\auth\AuthLogic;
|
||||
use app\common\model\auth\SystemMenu;
|
||||
use think\helper\Str;
|
||||
|
||||
/**
|
||||
* 权限点判断:与后台 AuthMiddleware 使用同一套数据(菜单 perms + 角色菜单),但**默认拒绝**——
|
||||
* 只有在菜单中登记且未停用的权限点才可能被放行,不继承后台“未登记接口任何人可访问”的规则。
|
||||
* PHP-FPM 每个请求独立,静态缓存只在本次请求内有效。
|
||||
*/
|
||||
class PermissionService
|
||||
{
|
||||
private static ?array $enabled = null;
|
||||
|
||||
private static array $adminPerms = [];
|
||||
|
||||
private static ?array $menus = null;
|
||||
|
||||
/** 与 AuthMiddleware::formatUrl 相同的规范化方式 */
|
||||
public static function normalize(string $perm): string
|
||||
{
|
||||
return strtolower(Str::camel(trim($perm)));
|
||||
}
|
||||
|
||||
/** 已登记且未停用的全部权限点(规范化后作为键) */
|
||||
public static function enabledPerms(): array
|
||||
{
|
||||
if (self::$enabled === null) {
|
||||
self::$enabled = array_flip(array_map([self::class, 'normalize'], AuthLogic::getAllAuth()));
|
||||
}
|
||||
return self::$enabled;
|
||||
}
|
||||
|
||||
public static function isRegistered(string $perm): bool
|
||||
{
|
||||
return isset(self::enabledPerms()[self::normalize($perm)]);
|
||||
}
|
||||
|
||||
/** 账号通过角色获得的权限点(规范化后作为键) */
|
||||
public static function adminPerms(int $adminId): array
|
||||
{
|
||||
if (!isset(self::$adminPerms[$adminId])) {
|
||||
self::$adminPerms[$adminId] = array_flip(array_map([self::class, 'normalize'], AuthLogic::getAuthByAdminId($adminId)));
|
||||
}
|
||||
return self::$adminPerms[$adminId];
|
||||
}
|
||||
|
||||
/**
|
||||
* 全部未停用菜单:规范化 perms => [name, parent_name, top_name],供数据目录取中文名称和业务分组。
|
||||
*/
|
||||
public static function menuIndex(): array
|
||||
{
|
||||
if (self::$menus !== null) {
|
||||
return self::$menus;
|
||||
}
|
||||
$rows = SystemMenu::where('is_disable', 0)->field('id,pid,type,name,perms')->select()->toArray();
|
||||
$byId = array_column($rows, null, 'id');
|
||||
$index = [];
|
||||
foreach ($rows as $row) {
|
||||
if ((string) $row['perms'] === '') {
|
||||
continue;
|
||||
}
|
||||
$parent = $byId[$row['pid']] ?? null;
|
||||
$top = $parent;
|
||||
$guard = 0;
|
||||
while ($top && !empty($byId[$top['pid']] ?? null) && $guard++ < 10) {
|
||||
$top = $byId[$top['pid']];
|
||||
}
|
||||
foreach (explode(':', (string) $row['perms']) as $perm) {
|
||||
$key = self::normalize($perm);
|
||||
if ($key === '' || isset($index[$key])) {
|
||||
continue;
|
||||
}
|
||||
$index[$key] = [
|
||||
'name' => (string) $row['name'],
|
||||
'type' => (string) $row['type'],
|
||||
'parent' => $parent ? (string) $parent['name'] : '',
|
||||
'top' => $top ? (string) $top['name'] : '',
|
||||
];
|
||||
}
|
||||
}
|
||||
return self::$menus = $index;
|
||||
}
|
||||
|
||||
/** 测试用:清空本请求内的缓存 */
|
||||
public static function reset(): void
|
||||
{
|
||||
self::$enabled = null;
|
||||
self::$adminPerms = [];
|
||||
self::$menus = null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user