160 lines
4.5 KiB
PHP
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]);
|
|
}
|
|
}
|