feat: Provider 异步删除、可配置密码策略、Hub 超时优化及多项改进

- 新增 Provider 异步删除任务系统,后台分阶段删除子资源并清理残留引用
- 新增可配置密码策略等级(weak/medium/strong),支持系统设置面板调整
- aether-hub 升级至 0.1.4,idle timeout 支持禁用(设为 0),worker 默认超时调整为 120s
- OAuth 手动续期增加 Redis 分布式锁,防止并发刷新冲突
- ProxyNode 心跳检测改为 asyncio.to_thread,避免阻塞事件循环
- 删除 ModelMultiSelect 和 useInvalidModels,MultiSelect 组件通用化
- 明确 allowed_providers/allowed_api_formats 的 NULL 与空数组语义
- 前端 StandaloneKeyFormDialog、UserFormDialog 等多处 UI 优化
- 新增 Alembic 迁移脚本清理 Provider 删除后的残留引用
- 补充相关测试用例
This commit is contained in:
fawney19
2026-03-12 01:11:35 +08:00
parent 0d770d1c4d
commit 6e51a3f45d
55 changed files with 3219 additions and 862 deletions

View File

@@ -11,6 +11,7 @@ from typing import Any, Literal
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
from ..core.enums import UserRole
from ..core.validators import PasswordValidator
# ========== 认证相关 ==========
@@ -112,15 +113,10 @@ class RegisterRequest(BaseModel):
@classmethod
@field_validator("password")
def validate_password(cls, v: Any) -> Any:
"""验证密码强度"""
if len(v) < 6:
raise ValueError("密码至少需要6个字符")
if not re.search(r"[A-Z]", v):
raise ValueError("密码必须包含至少一个大写字母")
if not re.search(r"[a-z]", v):
raise ValueError("密码必须包含至少一个小写字母")
if not re.search(r"\d", v):
raise ValueError("密码必须包含至少一个数字")
"""基础校验(长度上下限),策略级别校验在服务层按系统配置执行。"""
valid, error_msg = PasswordValidator.validate(v)
if not valid:
raise ValueError(error_msg or "密码格式无效")
return v
@@ -231,6 +227,7 @@ class RegistrationSettingsResponse(BaseModel):
enable_registration: bool
require_email_verification: bool
email_configured: bool = Field(description="是否配置了邮箱服务")
password_policy_level: str = Field(description="密码策略等级weak/medium/strong")
# ========== 用户管理 ==========
@@ -320,15 +317,10 @@ class CreateUserRequest(BaseModel):
@classmethod
@field_validator("password")
def validate_password(cls, v: Any) -> Any:
"""验证密码强度"""
if len(v) < 6:
raise ValueError("密码至少需要6个字符")
if not re.search(r"[A-Z]", v):
raise ValueError("密码必须包含至少一个大写字母")
if not re.search(r"[a-z]", v):
raise ValueError("密码必须包含至少一个小写字母")
if not re.search(r"\d", v):
raise ValueError("密码必须包含至少一个数字")
"""基础校验(长度上下限),策略级别校验在服务层按系统配置执行。"""
valid, error_msg = PasswordValidator.validate(v)
if not valid:
raise ValueError(error_msg or "密码格式无效")
return v
@@ -645,6 +637,7 @@ class SystemSettingsRequest(BaseModel):
default_provider: str | None = None
default_model: str | None = None
enable_usage_tracking: bool | None = None
password_policy_level: Literal["weak", "medium", "strong"] | None = None
class SystemSettingsResponse(BaseModel):
@@ -653,6 +646,7 @@ class SystemSettingsResponse(BaseModel):
default_provider: str | None
default_model: str | None
enable_usage_tracking: bool
password_policy_level: str
# ========== 使用统计 ==========