feat: 新增多格式文件上传入库与认证体系
- 新增 JWT 认证模块,支持登录/注册/用户管理 - 新增文件上传接口,支持 .txt/.md/.html/.pdf/.docx 等格式解析入库 - 新增检索结果 AI 总结功能 - 新增文本去重缓存机制 - 新增全局认证夹具简化测试 - 新增配置项与环境变量支持 - 完善文档与测试覆盖
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
"""认证相关数据模型"""
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class LoginRequest(BaseModel):
|
||||
"""登录请求"""
|
||||
|
||||
username: str = Field(description="用户名")
|
||||
password: str = Field(description="明文密码")
|
||||
|
||||
|
||||
class RegisterRequest(BaseModel):
|
||||
"""注册请求"""
|
||||
|
||||
username: str = Field(min_length=3, max_length=32, description="用户名(3-32 字符)")
|
||||
password: str = Field(min_length=6, max_length=128, description="密码(6-128 字符)")
|
||||
|
||||
|
||||
class AuthUser(BaseModel):
|
||||
"""对外暴露的用户信息(不含密码)"""
|
||||
|
||||
username: str = Field(description="用户名")
|
||||
role: str = Field(default="user", description="角色:admin | user")
|
||||
created_at: datetime = Field(description="创建时间")
|
||||
|
||||
|
||||
class StoredUser(AuthUser):
|
||||
"""存储层用户:含密码哈希,仅内部使用,不对外暴露"""
|
||||
|
||||
hashed_password: str = Field(description="bcrypt 密码哈希")
|
||||
|
||||
|
||||
class TokenResponse(BaseModel):
|
||||
"""登录成功返回的 token 信息"""
|
||||
|
||||
access_token: str = Field(description="JWT access token")
|
||||
token_type: str = Field(default="bearer", description="token 类型")
|
||||
expires_in: int = Field(description="token 有效期(秒)")
|
||||
user: AuthUser = Field(description="登录用户信息")
|
||||
@@ -49,3 +49,4 @@ class IngestionResult(BaseModel):
|
||||
chunks_count: int = Field(default=0, description="写入的 chunk 数量")
|
||||
tags: list[str] = Field(default_factory=list, description="附加分类标签")
|
||||
category_confidence: float = Field(default=0.0, description="主类目分类置信度")
|
||||
deduplicated: bool = Field(default=False, description="是否命中去重复用旧文档(True 时 document_id 为既有文档 ID)")
|
||||
|
||||
@@ -8,6 +8,7 @@ class SearchRequest(BaseModel):
|
||||
|
||||
query: str = Field(description="查询文本")
|
||||
top_k: int | None = Field(default=None, description="返回结果数,为空时使用 settings.retrieval_final_k")
|
||||
summarize: bool = Field(default=False, description="是否对检索结果生成 AI 总结")
|
||||
|
||||
|
||||
class SearchHit(BaseModel):
|
||||
@@ -21,6 +22,17 @@ class SearchHit(BaseModel):
|
||||
doc_summary: str = Field(default="", description="L1 文档总结,仅用于上下文标注")
|
||||
|
||||
|
||||
class ExtractedInfo(BaseModel):
|
||||
"""AI 从 query 中提取的关键信息"""
|
||||
|
||||
rewrite: str = Field(default="", description="改写后的 query")
|
||||
keywords: list[str] = Field(default_factory=list, description="关键词")
|
||||
entities: list[str] = Field(default_factory=list, description="实体(人名/产品/技术等)")
|
||||
intent: str = Field(default="", description="查询意图分类")
|
||||
time_range: str = Field(default="", description="时间范围,空表示无")
|
||||
categories: list[str] = Field(default_factory=list, description="命中类目名(含未达阈值的候选)")
|
||||
|
||||
|
||||
class SearchResponse(BaseModel):
|
||||
"""检索响应"""
|
||||
|
||||
@@ -28,3 +40,5 @@ class SearchResponse(BaseModel):
|
||||
hits: list[SearchHit] = Field(default_factory=list, description="命中结果列表")
|
||||
routed_categories: list[str] = Field(default_factory=list, description="query 路由命中的类目")
|
||||
fallback: bool = Field(default=False, description="是否走了全库兜底路径")
|
||||
extracted_info: ExtractedInfo | None = Field(default=None, description="AI 提取的 query 关键信息")
|
||||
summary: str | None = Field(default=None, description="检索结果 AI 总结,仅 summarize=true 时返回")
|
||||
|
||||
Reference in New Issue
Block a user