update. 完善用户相关基础数据的模型与接口配置

This commit is contained in:
2026-04-07 12:52:26 +08:00
parent 53e91fa458
commit ae80234f65
11 changed files with 778 additions and 61 deletions
+93
View File
@@ -0,0 +1,93 @@
from typing import List
from django.core.cache import cache
from loguru import logger
from users.models import User, Menu # 替换为你的实际 app 名
def get_user_permissions(user_id: int) -> List[str]:
"""
获取用户所有按钮级权限标识(permission_code
利用 Django ORM 的多对多关系链式查询
"""
cache_key = f"user_permissions_{user_id}"
permissions = cache.get(cache_key)
logger.info(f"当前缓存的权限列表:{permissions}")
if permissions is None:
try:
# 链式查询:用户 → 角色 → 菜单(仅按钮类型)
permissions = list(
Menu.objects.filter(
roles__users__id=user_id, # 通过 roles__users 反向关联到用户
menu_type=2, # 2 = 按钮
status=True
)
.values_list('permission_code', flat=True)
.distinct()
)
logger.info(f"当前获取到的权限列表:{permissions}")
cache.set(cache_key, permissions, 3600) # 缓存1小时
except User.DoesNotExist:
return []
logger.info(f"当前用户的权限列表:{permissions}")
return permissions
def has_permission(user_id: int, permission_code: str) -> bool:
"""检查用户是否拥有指定权限"""
if not permission_code:
return True
return permission_code in get_user_permissions(user_id)
def clear_user_permissions_cache(user_id: int):
"""清除用户权限缓存(当角色或菜单变更时调用)"""
cache.delete(f"user_permissions_{user_id}")
# 批量清除缓存的辅助函数(可选)
def clear_all_users_permissions_cache():
"""清除所有用户权限缓存(谨慎使用)"""
# 实际项目中可通过信号或更精细的方式处理
cache.clear() # 或遍历已知用户ID
def build_menu_tree(menus):
"""高效构建菜单树(O(n) 时间复杂度)"""
# 1. 将菜单列表转为字典,key=id
menu_dict = {}
for menu in menus:
menu_dict[menu.id] = {
'id': menu.id,
'name': menu.name,
'code': menu.code,
'path': menu.path,
'component': menu.component,
'icon': menu.icon,
'order_num': menu.order_num,
'parent_id': menu.parent_id, # ✅ 只存 ID,避免对象引用
'permission_code': menu.permission_code,
'menu_type': menu.menu_type,
'children': [] # 初始化为空列表
}
# 2. 构建树结构
tree = []
for menu_id, node in menu_dict.items():
parent_id = node['parent_id']
if parent_id is None or parent_id not in menu_dict:
# 根节点(parent_id 为 None 或指向不存在的父节点)
tree.append(node)
else:
# 添加到父节点的 children
menu_dict[parent_id]['children'].append(node)
# 3. (可选)按 order_num 排序
def sort_children(nodes):
nodes.sort(key=lambda x: x['order_num'] or 0)
for node in nodes:
sort_children(node['children'])
sort_children(tree)
return tree