import asyncio from fastapi.logger import logger from sqlalchemy import and_ from apps.forms.role_menu import RoleMenuForm from apps.models.menu import Menu from apps.models.role_menu import RoleMenu from extensions import get_db_session from utils import R from utils.perm_cache import invalidate_role_perms # 根据角色ID查询菜单列表 def get_role_menu_list(role_id): db = get_db_session() # 获取全部菜单列表(仅查询 id、title、parent_id,避免 SELECT * 全量拉取大字段) menuList = db.query(Menu.id, Menu.title, Menu.parent_id).filter(and_(Menu.is_delete == 0, Menu.status == 1)).order_by(Menu.sort.asc()).all() if len(menuList) == 0: return None # 根据角色ID查询角色菜单关系数据 role_menu = db.query(RoleMenu).filter(RoleMenu.role_id == role_id).all() # 菜单ID集合 idList = [] # 遍历角色菜单数据源 if role_menu: for v in role_menu: # 加入数组 idList.append(v.menu_id) # 实例化菜单列表 menu_list = [] # 遍历菜单数据 for menu in menuList: # 菜单ID menu_id = menu.id data = { 'id': menu_id, 'title': menu.title, 'open': True, 'parentId': menu.parent_id, } if menu_id in idList: data['checked'] = True # 加入数组 menu_list.append(data) # 返回结果 return menu_list # 保存角色菜单数据 async def save_role_menu(request, data: RoleMenuForm): def _save(): db = get_db_session() # 角色ID role_id = data.role_id # 菜单ID列表 menuIdList = data.menu_id or [] # 删除当前角色ID相关菜单权限 db.query(RoleMenu).filter(RoleMenu.role_id == role_id).delete() # 处理菜单数据 if menuIdList: new_menus = [] for menu_id in menuIdList: if not menu_id: continue new_menus.append(RoleMenu(role_id=role_id, menu_id=menu_id)) db.add_all(new_menus) return role_id # 同步DB操作放入线程池,避免阻塞事件循环 role_id = await asyncio.to_thread(_save) # 清理该角色下所有用户的权限缓存 await invalidate_role_perms(role_id) # 返回结果 return R.ok()