Build lightweight AI agent admin

This commit is contained in:
Codex
2026-06-08 18:14:59 +08:00
commit e164840f43
2530 changed files with 435693 additions and 0 deletions
+114
View File
@@ -0,0 +1,114 @@
"""
用户信息缓存模块
将用户的动态权限信息(role_ids, dept_id, is_superuser)缓存到 Redis
中间件从 Redis 获取而非从 JWT token 中读取,确保角色变更后权限立即生效。
缓存 key: user_info:{user_id}
缓存内容: {"role_ids": [...], "dept_id": "...", "is_superuser": true/false}
默认 TTL: 300秒(5分钟),缓存未命中时从数据库加载
"""
import json
from typing import Optional, Dict, Any, List
from utils.redis import RedisClient
USER_INFO_CACHE_PREFIX = "user_info:"
USER_INFO_CACHE_TTL = 300 # 5分钟
async def get_cached_user_info(user_id: str) -> Optional[Dict[str, Any]]:
"""
从 Redis 获取用户信息缓存
:param user_id: 用户ID
:return: 用户信息字典,未命中返回 None
"""
redis = await RedisClient.get_client()
value = await redis.get(f"{USER_INFO_CACHE_PREFIX}{user_id}")
if value:
try:
return json.loads(value)
except json.JSONDecodeError:
return None
return None
async def set_cached_user_info(
user_id: str,
role_ids: List[str],
dept_id: Optional[str],
is_superuser: bool
) -> None:
"""
写入用户信息缓存到 Redis
:param user_id: 用户ID
:param role_ids: 角色ID列表
:param dept_id: 部门ID
:param is_superuser: 是否超级管理员
"""
redis = await RedisClient.get_client()
data = json.dumps({
"role_ids": role_ids,
"dept_id": dept_id,
"is_superuser": is_superuser,
}, ensure_ascii=False)
await redis.set(
f"{USER_INFO_CACHE_PREFIX}{user_id}",
data,
ex=USER_INFO_CACHE_TTL
)
async def delete_cached_user_info(user_id: str) -> None:
"""
删除用户信息缓存(角色/部门等变更时调用)
:param user_id: 用户ID
"""
redis = await RedisClient.get_client()
await redis.delete(f"{USER_INFO_CACHE_PREFIX}{user_id}")
async def delete_all_cached_user_info() -> None:
"""
删除所有用户信息缓存(角色权限配置变更时调用)
"""
redis = await RedisClient.get_client()
cursor = 0
while True:
cursor, keys = await redis.scan(cursor, match=f"{USER_INFO_CACHE_PREFIX}*", count=100)
if keys:
await redis.delete(*keys)
if cursor == 0:
break
async def load_user_info_from_db(user_id: str) -> Optional[Dict[str, Any]]:
"""
从数据库加载用户信息并写入缓存
:param user_id: 用户ID
:return: 用户信息字典,用户不存在返回 None
"""
from app.database import AsyncSessionLocal
from core.user.service import UserService
async with AsyncSessionLocal() as db:
user = await UserService.get_by_id(db, user_id)
if not user:
return None
role_ids = await UserService.get_user_role_ids(db, user_id)
info = {
"role_ids": role_ids,
"dept_id": user.dept_id,
"is_superuser": user.is_superuser,
}
# 写入缓存
await set_cached_user_info(user_id, role_ids, user.dept_id, user.is_superuser)
return info