You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
4.1 KiB
Python
143 lines
4.1 KiB
Python
from iti.applications.extensions import eventbus
|
|
from iti.applications.common.events import (
|
|
UserEvents,
|
|
UserRelEvents,
|
|
RoleEvents,
|
|
MenuEvents,
|
|
RoleRelEvents,
|
|
)
|
|
from iti.applications.models import User, Role, SysMenu, sys_role_menu, sys_user_role
|
|
from iti.applications.extensions import cache_simple, db
|
|
from sqlalchemy import select, distinct
|
|
|
|
|
|
class UserCacheEventHandler:
|
|
"""
|
|
用户数据缓存 事件处理器
|
|
"""
|
|
|
|
def __init__(self, app=None):
|
|
if app:
|
|
self.init_app(app)
|
|
|
|
def init_app(self, app):
|
|
self.app = app
|
|
self._register_handlers()
|
|
|
|
def _register_handlers(self):
|
|
"""
|
|
注册事件处理器
|
|
"""
|
|
|
|
# 用户
|
|
eventbus.register_handler(
|
|
UserEvents.USER_UPDATED,
|
|
self._handle_user_updated,
|
|
order=-1,
|
|
async_mode=True,
|
|
)
|
|
eventbus.register_handler(
|
|
UserEvents.USER_DELETED,
|
|
self._handle_user_deleted,
|
|
order=-1,
|
|
async_mode=True,
|
|
)
|
|
eventbus.register_handler(
|
|
UserEvents.USER_AUTH_REFRESHED,
|
|
self._handle_user_updated,
|
|
order=-1,
|
|
async_mode=True,
|
|
)
|
|
eventbus.register_handler(
|
|
UserEvents.USER_LOGOUT,
|
|
self._handle_user_updated,
|
|
order=-1,
|
|
async_mode=True,
|
|
)
|
|
eventbus.register_handler(
|
|
UserEvents.USER_PASSWORD_UPDATED,
|
|
self._handle_user_updated,
|
|
order=-1,
|
|
async_mode=True,
|
|
)
|
|
|
|
# 用户关系
|
|
eventbus.register_handler(
|
|
UserRelEvents.USER_ROLES_UPDATED,
|
|
self._handle_user_updated,
|
|
order=-1,
|
|
async_mode=True,
|
|
)
|
|
eventbus.register_handler(
|
|
UserRelEvents.USER_DEPTS_UPDATED,
|
|
self._handle_user_updated,
|
|
order=-1,
|
|
async_mode=True,
|
|
)
|
|
|
|
# 角色删除
|
|
eventbus.register_handler(
|
|
RoleEvents.ROLE_DELETED,
|
|
self._handle_role_changed,
|
|
order=-1,
|
|
async_mode=True,
|
|
)
|
|
eventbus.register_handler(
|
|
RoleRelEvents.ROLE_MENUS_UPDATED.value,
|
|
self._handle_role_changed,
|
|
order=-1,
|
|
async_mode=True,
|
|
)
|
|
|
|
# 菜单
|
|
eventbus.register_handler(
|
|
MenuEvents.MENU_UPDATED,
|
|
self._handle_menu_updated,
|
|
order=-1,
|
|
async_mode=True,
|
|
)
|
|
eventbus.register_handler(
|
|
MenuEvents.MENU_DELETED,
|
|
self._handle_menu_deleted,
|
|
order=-1,
|
|
async_mode=True,
|
|
)
|
|
|
|
def _invalidate_user_cache(self, user_id):
|
|
"""
|
|
清理用户缓存
|
|
"""
|
|
|
|
if user_id:
|
|
cache_simple.delete(f"user_{user_id}")
|
|
|
|
def _handle_user_updated(self, user: User):
|
|
self._invalidate_user_cache(user.id)
|
|
|
|
def _handle_user_deleted(self, user_id):
|
|
self._invalidate_user_cache(user_id)
|
|
|
|
def _handle_role_changed(self, role: Role):
|
|
# 角色关联的用户缓存都应该被删除
|
|
if role.users:
|
|
for user in role.users:
|
|
self._invalidate_user_cache(user.id)
|
|
|
|
def _handle_menu_updated(self, menu: SysMenu, old_menu: SysMenu):
|
|
# 若菜单更新了权限字段
|
|
if old_menu and old_menu.auth_code != menu.auth_code:
|
|
# 与该菜单相关的角色的用户缓存都应该被删除
|
|
# 查询菜单相关的角色关联的所有用户ID
|
|
self._handle_menu_deleted(menu)
|
|
|
|
def _handle_menu_deleted(self, menu: SysMenu):
|
|
# 与该菜单相关的角色的用户缓存都应该被删除
|
|
# 查询菜单相关的角色关联的所有用户ID
|
|
user_ids = db.session.scalars(
|
|
select(distinct(sys_user_role.c.user_id))
|
|
.join(sys_user_role, sys_role_menu.c.role_id == sys_user_role.c.role_id)
|
|
.where(sys_role_menu.c.menu_id == menu.id)
|
|
).all()
|
|
for user_id in user_ids:
|
|
self._invalidate_user_cache(user_id)
|