feat: 优化批量余额查询和用户模型权限检查

- 添加批量余额查询并发限制,避免数据库连接池耗尽
- 支持余额加载 pending 状态和前端自动重试机制
- 添加用户可用模型 API,统一使用 AccessRestrictions
- 修复用户表单编辑时数组引用共享导致的数据覆盖问题
- 添加数据库连接池配置说明到 .env.example
This commit is contained in:
fawney19
2026-01-28 01:01:05 +08:00
parent 8e0695e9d9
commit 1e0255d0ed
12 changed files with 411 additions and 64 deletions

View File

@@ -408,28 +408,28 @@ class UserService:
"""获取用户可用的模型
通过 GlobalModel + Model 关联查询用户可用模型
逻辑:用户可用提供商 -> Provider 的 Model 实现 -> 关联的 GlobalModel
逻辑:使用 AccessRestrictions 统一处理 allowed_providers 和 allowed_models 限制
"""
# 获取用户可用的提供商
if user.role == UserRole.ADMIN:
# 管理员可以使用所有活动提供商
provider_ids = [
p.id for p in db.query(Provider.id).filter(Provider.is_active == True).all()
]
else:
# 普通用户使用关联的提供商
provider_ids = [p.id for p in user.providers]
from src.api.base.models_service import AccessRestrictions
if not provider_ids:
# 使用 AccessRestrictions 类来处理限制(与 /v1/models 逻辑一致)
restrictions = AccessRestrictions.from_api_key_and_user(api_key=None, user=user)
# 获取所有活跃的 Provider ID
all_active_provider_ids = [
p.id for p in db.query(Provider.id).filter(Provider.is_active == True).all()
]
if not all_active_provider_ids:
return []
# 查询这些提供商的所有活跃 Model关联 GlobalModel
models = (
# 查询所有活跃 Model关联 GlobalModel
all_models = (
db.query(Model)
.join(GlobalModel, Model.global_model_id == GlobalModel.id)
.filter(
and_(
Model.provider_id.in_(provider_ids),
Model.provider_id.in_(all_active_provider_ids),
Model.is_active == True,
GlobalModel.is_active == True,
)
@@ -437,6 +437,14 @@ class UserService:
.all()
)
logger.debug(f"用户 {user.email} 可用模型: {len(models)} 个 (提供商数: {len(provider_ids)})")
# 应用访问限制过滤
filtered_models = []
for model in all_models:
model_name = model.global_model.name if model.global_model else model.provider_model_name
# 使用 AccessRestrictions.is_model_allowed 检查模型是否可访问
if restrictions.is_model_allowed(model_name, model.provider_id):
filtered_models.append(model)
return models
logger.debug(f"用户 {user.email} 可用模型: {len(filtered_models)}")
return filtered_models