where($userField, $currentUserId); break; case 'same_role': // 同角色权限:访问同角色的数据 $userIds = self::getSameRoleUserIds($currentRoleId); $query->whereIn($userField, $userIds); break; case 'role_tree': // 角色树权限:访问自己角色及子角色的数据 $userIds = self::getRoleTreeUserIds($currentRoleId); $query->whereIn($userField, $userIds); break; case 'relation': // 从属关系权限:访问自己及下属的数据 $userIds = self::getRelationUserIds($currentUserId); $query->whereIn($userField, $userIds); break; default: // 默认个人权限 $query->where($userField, $currentUserId); } } /** * 应用数据权限到创建/更新操作 * * @param mixed $target 创建时为数组,更新时为Model对象 * @param string $type 权限类型 * @param int $currentUserId 当前用户ID * @param int $currentRoleId 当前角色ID * @param array $newData 更新时的数据 * @param string $userField 用户ID字段名 * @param string $roleField 角色ID字段名 */ public static function applyMutationPermission( &$target, string $type, int $currentUserId, int $currentRoleId, array $newData = [], string $userField = 'admin_id', string $roleField = 'role_id' ): void { // 超管不需要检查 if (self::isSuperAdmin($currentUserId)) { return; } switch ($type) { case 'personal': self::handlePersonalPermission($target, $newData, $userField, $currentUserId); break; case 'same_role': self::handleSameRolePermission($target, $newData, $userField, $roleField, $currentRoleId); break; case 'role_tree': self::handleRoleTreePermission($target, $newData, $userField, $roleField, $currentRoleId); break; case 'relation': self::handleRelationPermission($target, $newData, $userField, $currentUserId); break; default: throw new BusinessException("未定义的数据权限类型: $type", 403); } } /** * 获取同角色的用户ID列表 * * @param int $roleId 角色ID * @return array 用户ID列表 */ public static function getSameRoleUserIds(int $roleId): array { return Db::table('user_roles') ->where('role_id', $roleId) ->pluck('user_id') ->toArray(); } /** * 获取角色树下的所有用户ID列表 * * @param int $roleId 当前角色ID * @return array 用户ID列表 */ public static function getRoleTreeUserIds(int $roleId): array { // 获取角色树中的所有角色ID $roleIds = self::getRoleTreeIds($roleId); // 获取这些角色下的所有用户ID return Db::table('user_roles') ->whereIn('role_id', $roleIds) ->pluck('user_id') ->toArray(); } /** * 获取从属关系下的用户ID列表(包括自己和下属) * * @param int $userId 当前用户ID * @return array 用户ID列表 */ public static function getRelationUserIds(int $userId): array { // 获取所有下属用户ID(递归) $subordinateIds = self::getSubordinateIds($userId); // 返回自己和所有下属的ID return array_merge([$userId], $subordinateIds); } /** * 获取直接下属的用户ID列表 * * @param int $userId 用户ID * @return array 直接下属用户ID列表 */ public static function getDirectSubordinateIds(int $userId): array { return Db::table('user') ->where('report_to', $userId) ->pluck('id') ->toArray(); } /** * 递归获取所有下属用户ID列表 * * @param int $userId 用户ID * @return array 所有下属用户ID列表 */ private static function getSubordinateIds(int $userId): array { $subordinates = self::getDirectSubordinateIds($userId); $allSubordinates = $subordinates; foreach ($subordinates as $subordinateId) { $allSubordinates = array_merge($allSubordinates, self::getSubordinateIds($subordinateId)); } return $allSubordinates; } /** * 处理个人权限 */ private static function handlePersonalPermission( &$target, array $newData, string $userField, int $currentUserId ): void { if (is_array($target)) { // 创建时强制设置用户ID $target[$userField] = $currentUserId; } else { // 更新时校验原始记录 if ($target->{$userField} !== $currentUserId) { throw new BusinessException("无权操作该记录", 403); } // 禁止变更归属字段 if (isset($newData[$userField]) && $newData[$userField] !== $currentUserId) { throw new BusinessException("无权变更归属字段", 403); } } } /** * 处理同角色权限 */ private static function handleSameRolePermission( &$target, array $newData, string $userField, string $roleField, int $currentRoleId ): void { // 获取同角色用户ID列表 $sameRoleUserIds = self::getSameRoleUserIds($currentRoleId); if (is_array($target)) { // 创建时设置归属用户并校验 if (isset($target[$userField])) { if (!in_array($target[$userField], $sameRoleUserIds)) { throw new BusinessException("无权为指定用户创建数据", 403); } } else { $target[$userField] = $currentRoleId; } } else { // 更新时校验原始记录 if (!in_array($target->{$userField}, $sameRoleUserIds)) { throw new BusinessException("无权操作该记录", 403); } // 禁止变更归属字段到无权限的用户 if (isset($newData[$userField]) && !in_array($newData[$userField], $sameRoleUserIds)) { throw new BusinessException("无权变更归属字段", 403); } } } /** * 处理角色树权限 */ private static function handleRoleTreePermission( &$target, array $newData, string $userField, string $roleField, int $currentRoleId ): void { // 获取角色树用户ID列表 $roleTreeUserIds = self::getRoleTreeUserIds($currentRoleId); if (is_array($target)) { // 创建时校验用户是否在允许范围内 if (isset($target[$userField])) { if (!in_array($target[$userField], $roleTreeUserIds)) { throw new BusinessException("无权为指定用户创建数据", 403); } } else { $target[$userField] = $currentRoleId; } } else { // 更新时校验原始记录用户 if (!in_array($target->{$userField}, $roleTreeUserIds)) { throw new BusinessException("无权操作该记录", 403); } // 校验新用户是否在允许范围内 if (isset($newData[$userField])) { if (!in_array($newData[$userField], $roleTreeUserIds)) { throw new BusinessException("无权变更用户字段", 403); } } } } /** * 处理从属关系权限 */ private static function handleRelationPermission( &$target, array $newData, string $userField, int $currentUserId ): void { // 获取从属关系用户ID列表 $relationUserIds = self::getRelationUserIds($currentUserId); if (is_array($target)) { // 创建时校验用户是否在允许范围内 if (isset($target[$userField])) { if (!in_array($target[$userField], $relationUserIds)) { throw new BusinessException("无权为指定用户创建数据", 403); } } else { $target[$userField] = $currentUserId; } } else { // 更新时校验原始记录用户 if (!in_array($target->{$userField}, $relationUserIds)) { throw new BusinessException("无权操作该记录", 403); } // 校验新用户是否在允许范围内 if (isset($newData[$userField])) { if (!in_array($newData[$userField], $relationUserIds)) { throw new BusinessException("无权变更用户字段", 403); } } } } /** * 获取角色树ID(当前角色及其所有子角色) * 从数据库中动态获取角色树关系 */ private static function getRoleTreeIds(int $roleId): array { static $roleTreeCache = []; if (isset($roleTreeCache[$roleId])) { return $roleTreeCache[$roleId]; } // 从数据库中递归获取角色树 $ids = [$roleId]; $queue = [$roleId]; while (!empty($queue)) { $current = array_shift($queue); // 查找当前角色的所有子角色 $childRoles = Db::table('roles') ->where('parent_id', $current) ->where('status', 1) // 只获取启用的角色 ->pluck('id') ->toArray(); foreach ($childRoles as $childId) { if (!in_array($childId, $ids)) { $ids[] = $childId; $queue[] = $childId; } } } $roleTreeCache[$roleId] = $ids; return $ids; } /** * 检查是否为超管 * * @param int $userId 用户ID * @return bool 是否为超管 */ public static function isSuperAdmin(int $userId): bool { // 检查用户是否关联了超级管理员角色 // 假设角色ID为1的是超级管理员角色 $superAdminRoleId = 1; return Db::table('user_roles') ->where('user_id', $userId) ->where('role_id', $superAdminRoleId) ->exists(); } /** * 获取用户的角色ID * * @param int $userId 用户ID * @return int 角色ID */ public static function getUserIdRoleId(int $userId): int { // 从 user_roles 表中获取当前用户的角色ID $roleId = Db::table('user_roles') ->where('user_id', $userId) ->value('role_id'); return $roleId ?: 0; } /** * 获取用户的所有角色ID(包括继承的角色) * * @param int $userId 用户ID * @return array 角色ID列表 */ public static function getUserAllRoleIds(int $userId): array { // 获取用户直接关联的角色 $directRoleIds = Db::table('user_roles') ->where('user_id', $userId) ->pluck('role_id') ->toArray(); // 获取所有继承的角色 $allRoleIds = []; foreach ($directRoleIds as $roleId) { $allRoleIds = array_merge($allRoleIds, self::getRoleTreeIds($roleId)); } // 去重并返回 return array_unique($allRoleIds); } }