121 lines
4.6 KiB
Python
121 lines
4.6 KiB
Python
"""章节相关的Pydantic模型"""
|
|
from pydantic import BaseModel, Field
|
|
from typing import Optional
|
|
from datetime import datetime
|
|
|
|
|
|
class ChapterBase(BaseModel):
|
|
"""章节基础模型"""
|
|
title: str = Field(..., description="章节标题")
|
|
chapter_number: int = Field(..., description="章节序号")
|
|
content: Optional[str] = Field(None, description="章节内容")
|
|
summary: Optional[str] = Field(None, description="章节摘要")
|
|
word_count: Optional[int] = Field(0, description="字数")
|
|
status: Optional[str] = Field("draft", description="章节状态")
|
|
outline_id: Optional[str] = Field(None, description="关联的大纲ID")
|
|
sub_index: Optional[int] = Field(1, description="大纲下的子章节序号")
|
|
expansion_plan: Optional[str] = Field(None, description="展开规划详情(JSON)")
|
|
|
|
|
|
class ChapterCreate(BaseModel):
|
|
"""创建章节的请求模型"""
|
|
project_id: str = Field(..., description="所属项目ID")
|
|
title: str = Field(..., description="章节标题")
|
|
chapter_number: int = Field(..., description="章节序号")
|
|
content: Optional[str] = Field(None, description="章节内容")
|
|
summary: Optional[str] = Field(None, description="章节摘要")
|
|
status: Optional[str] = Field("draft", description="章节状态")
|
|
outline_id: Optional[str] = Field(None, description="关联的大纲ID")
|
|
sub_index: Optional[int] = Field(1, description="大纲下的子章节序号")
|
|
expansion_plan: Optional[str] = Field(None, description="展开规划详情(JSON)")
|
|
|
|
|
|
class ChapterUpdate(BaseModel):
|
|
"""更新章节的请求模型"""
|
|
title: Optional[str] = None
|
|
content: Optional[str] = None
|
|
# chapter_number 不允许修改,只能通过大纲的重排序来调整
|
|
summary: Optional[str] = None
|
|
# word_count 自动计算,不允许手动修改
|
|
status: Optional[str] = None
|
|
|
|
|
|
class ChapterResponse(BaseModel):
|
|
"""章节响应模型"""
|
|
id: str
|
|
project_id: str
|
|
title: str
|
|
chapter_number: int
|
|
content: Optional[str] = None
|
|
summary: Optional[str] = None
|
|
word_count: int = 0
|
|
status: str
|
|
outline_id: Optional[str] = None
|
|
sub_index: Optional[int] = 1
|
|
expansion_plan: Optional[str] = None
|
|
outline_title: Optional[str] = None # 大纲标题(从Outline表联查)
|
|
outline_order: Optional[int] = None # 大纲排序序号(从Outline表联查)
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class ChapterListResponse(BaseModel):
|
|
"""章节列表响应模型"""
|
|
total: int
|
|
items: list[ChapterResponse]
|
|
|
|
|
|
class ChapterGenerateRequest(BaseModel):
|
|
"""AI生成章节内容的请求模型"""
|
|
style_id: Optional[int] = Field(None, description="写作风格ID,不提供则不使用任何风格")
|
|
target_word_count: Optional[int] = Field(
|
|
3000,
|
|
description="目标字数,默认3000字",
|
|
ge=500, # 最小500字
|
|
le=10000 # 最大10000字
|
|
)
|
|
enable_mcp: bool = Field(True, description="是否启用MCP工具增强(搜索参考资料)")
|
|
|
|
|
|
class BatchGenerateRequest(BaseModel):
|
|
"""批量生成章节的请求模型"""
|
|
start_chapter_number: int = Field(..., description="起始章节序号")
|
|
count: int = Field(..., description="生成章节数量", ge=1, le=20)
|
|
style_id: Optional[int] = Field(None, description="写作风格ID")
|
|
target_word_count: Optional[int] = Field(
|
|
3000,
|
|
description="目标字数,默认3000字",
|
|
ge=500,
|
|
le=10000
|
|
)
|
|
enable_analysis: bool = Field(False, description="是否启用同步分析")
|
|
enable_mcp: bool = Field(True, description="是否启用MCP工具增强(搜索参考资料)")
|
|
max_retries: int = Field(3, description="每个章节的最大重试次数", ge=0, le=5)
|
|
|
|
|
|
class BatchGenerateResponse(BaseModel):
|
|
"""批量生成响应模型"""
|
|
batch_id: str = Field(..., description="批次ID")
|
|
message: str = Field(..., description="响应消息")
|
|
chapters_to_generate: list[dict] = Field(..., description="待生成章节列表")
|
|
estimated_time_minutes: int = Field(..., description="预估耗时(分钟)")
|
|
|
|
|
|
class BatchGenerateStatusResponse(BaseModel):
|
|
"""批量生成状态响应模型"""
|
|
batch_id: str
|
|
status: str
|
|
total: int
|
|
completed: int
|
|
current_chapter_id: Optional[str] = None
|
|
current_chapter_number: Optional[int] = None
|
|
current_retry_count: Optional[int] = None
|
|
max_retries: Optional[int] = None
|
|
failed_chapters: list[dict] = []
|
|
created_at: Optional[str] = None
|
|
started_at: Optional[str] = None
|
|
completed_at: Optional[str] = None
|
|
error_message: Optional[str] = None |