from collections.abc import Sequence from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from backend.app.admin.model import data_scope_rule, role_data_scope, role_menu, user_role from backend.core.conf import settings from backend.database.redis import redis_client class UserCacheManager: """用户缓存管理""" @staticmethod async def clear(user_ids: Sequence[int]) -> None: """ 清理用户缓存 :param user_ids: 用户 ID 列表 :return: """ if user_ids: await redis_client.delete(*[f'{settings.JWT_USER_REDIS_PREFIX}:{user_id}' for user_id in user_ids]) async def clear_by_role_id(self, db: AsyncSession, role_ids: list[int]) -> None: """ 通过角色 ID 清理用户缓存 :param db: 数据库会话 :param role_ids: 角色 ID 列表 :return: """ stmt = select(user_role.c.user_id).where(user_role.c.role_id.in_(role_ids)).distinct() result = await db.execute(stmt) user_ids = result.scalars().all() await self.clear(user_ids) async def clear_by_menu_id(self, db: AsyncSession, menu_ids: list[int]) -> None: """ 通过菜单 ID 清理用户缓存 :param db: 数据库会话 :param menu_ids: 菜单 ID 列表 :return: """ stmt = ( select(user_role.c.user_id) .join(role_menu, user_role.c.role_id == role_menu.c.role_id) .where(role_menu.c.menu_id.in_(menu_ids)) .distinct() ) result = await db.execute(stmt) user_ids = result.scalars().all() await self.clear(user_ids) async def clear_by_data_scope_id(self, db: AsyncSession, scope_ids: list[int]) -> None: """ 通过数据范围 ID 清理用户缓存 :param db: 数据库会话 :param scope_ids: 数据范围 ID 列表 :return: """ stmt = ( select(user_role.c.user_id) .join(role_data_scope, user_role.c.role_id == role_data_scope.c.role_id) .where(role_data_scope.c.data_scope_id.in_(scope_ids)) .distinct() ) result = await db.execute(stmt) user_ids = result.scalars().all() await self.clear(user_ids) async def clear_by_data_rule_id(self, db: AsyncSession, rule_ids: list[int]) -> None: """ 通过数据规则 ID 清理用户缓存 :param db: 数据库会话 :param rule_ids: 数据规则 ID 列表 :return: """ stmt = ( select(user_role.c.user_id) .join(role_data_scope, user_role.c.role_id == role_data_scope.c.role_id) .join(data_scope_rule, role_data_scope.c.data_scope_id == data_scope_rule.c.data_scope_id) .where(data_scope_rule.c.data_rule_id.in_(rule_ids)) .distinct() ) result = await db.execute(stmt) user_ids = result.scalars().all() await self.clear(user_ids) user_cache_manager: UserCacheManager = UserCacheManager()