Files
zyt/server/app/mcp/service/PermissionService.php
T
2026-09-24 09:45:44 +08:00

97 lines
3.2 KiB
PHP

<?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;
}
}