Files
chat/backend/app/service/AdminScopeService.php
T
2026-07-22 10:18:59 +08:00

160 lines
4.5 KiB
PHP

<?php
namespace app\service;
use app\model\Role;
use app\model\User;
use app\service\DepartmentService as DeptSvc;
use app\service\PermissionCatalog;
class AdminScopeService
{
public static function permissions(array $authUser): array
{
$perms = $authUser['role_permissions'] ?? [];
if (!is_array($perms)) {
$perms = [];
}
return PermissionCatalog::normalize($perms);
}
public static function hasPermission(array $authUser, string $key): bool
{
$perms = self::permissions($authUser);
// 超级管理员 / 旧 admin 角色:全部放行
if (($authUser['role'] ?? '') === 'admin' && empty($authUser['role_id'])) {
return true;
}
if (($authUser['role_slug'] ?? '') === 'super_admin') {
return true;
}
return PermissionCatalog::hasCode($perms, $key);
}
public static function hasAny(array $authUser, array $keys): bool
{
foreach ($keys as $key) {
if (self::hasPermission($authUser, $key)) {
return true;
}
}
return false;
}
public static function canAccessAdmin(array $authUser): bool
{
if (($authUser['role'] ?? '') === 'admin') {
return true;
}
return self::hasPermission($authUser, 'can_access_admin');
}
public static function requirePermission(array $authUser, string $key): void
{
if (!self::hasPermission($authUser, $key)) {
throw new \think\exception\HttpResponseException(json([
'code' => 1,
'message' => '无操作权限',
'data' => null,
], 403));
}
}
public static function requireAny(array $authUser, array $keys): void
{
if (!self::hasAny($authUser, $keys)) {
throw new \think\exception\HttpResponseException(json([
'code' => 1,
'message' => '无操作权限',
'data' => null,
], 403));
}
}
/**
* @return int[]|null null 表示可见全部用户
*/
public static function visibleUserIds(array $authUser): ?array
{
if (self::hasPermission($authUser, 'btn:conv:view_all')
|| self::hasPermission($authUser, 'can_view_all_conversations')) {
return null;
}
if (self::hasPermission($authUser, 'btn:conv:view_subordinate')
|| self::hasPermission($authUser, 'can_view_subordinate_conversations')) {
$departmentId = (int) ($authUser['department_id'] ?? 0);
if ($departmentId <= 0) {
return [(int) $authUser['id']];
}
$deptIds = DeptSvc::descendantIds($departmentId);
$userIds = DeptSvc::userIdsInDepartments($deptIds);
return array_values(array_unique(array_map('intval', $userIds)));
}
if (($authUser['role'] ?? '') === 'admin') {
return null;
}
return [(int) $authUser['id']];
}
public static function canViewUser(array $authUser, int $targetUserId): bool
{
$visible = self::visibleUserIds($authUser);
if ($visible === null) {
return true;
}
return in_array($targetUserId, $visible, true);
}
public static function canViewConversation(array $authUser, int $conversationUserId): bool
{
return self::canViewUser($authUser, $conversationUserId);
}
public static function applyUserScope($query, array $authUser, string $alias = 'u')
{
$visible = self::visibleUserIds($authUser);
if ($visible !== null) {
$query->whereIn("{$alias}.id", $visible ?: [0]);
}
return $query;
}
public static function applyConversationScope($query, array $authUser, string $conversationAlias = 'c')
{
$visible = self::visibleUserIds($authUser);
if ($visible !== null) {
$query->whereIn("{$conversationAlias}.user_id", $visible ?: [0]);
}
return $query;
}
public static function syncLegacyRoleField(int $userId, ?int $roleId): void
{
if (!$roleId) {
return;
}
$role = Role::find($roleId);
if (!$role) {
return;
}
$permissions = PermissionCatalog::normalize($role->permissions ?? []);
$legacyRole = !empty($permissions['can_access_admin']) ? 'admin' : 'user';
User::where('id', $userId)->update(['role' => $legacyRole]);
}
}