init
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""Pydantic数据模型"""
|
||||
@@ -0,0 +1,57 @@
|
||||
"""章节相关的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="章节状态")
|
||||
|
||||
|
||||
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="章节状态")
|
||||
|
||||
|
||||
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
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class ChapterListResponse(BaseModel):
|
||||
"""章节列表响应模型"""
|
||||
total: int
|
||||
items: list[ChapterResponse]
|
||||
@@ -0,0 +1,67 @@
|
||||
"""角色相关的Pydantic模型"""
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional, List, Dict, Any
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class CharacterBase(BaseModel):
|
||||
"""角色基础模型"""
|
||||
name: str = Field(..., description="角色/组织姓名")
|
||||
age: Optional[str] = Field(None, description="年龄")
|
||||
gender: Optional[str] = Field(None, description="性别")
|
||||
is_organization: bool = Field(False, description="是否为组织")
|
||||
role_type: Optional[str] = Field(None, description="角色类型:protagonist/supporting/antagonist")
|
||||
personality: Optional[str] = Field(None, description="性格特点/组织特性")
|
||||
background: Optional[str] = Field(None, description="背景故事")
|
||||
appearance: Optional[str] = Field(None, description="外貌特征")
|
||||
relationships: Optional[str] = Field(None, description="人际关系(JSON)")
|
||||
organization_type: Optional[str] = Field(None, description="组织类型")
|
||||
organization_purpose: Optional[str] = Field(None, description="组织目的")
|
||||
organization_members: Optional[str] = Field(None, description="组织成员(JSON)")
|
||||
traits: Optional[str] = Field(None, description="特征标签(JSON)")
|
||||
|
||||
|
||||
class CharacterUpdate(BaseModel):
|
||||
"""更新角色的请求模型"""
|
||||
name: Optional[str] = None
|
||||
age: Optional[str] = None
|
||||
gender: Optional[str] = None
|
||||
is_organization: Optional[bool] = None
|
||||
role_type: Optional[str] = None
|
||||
personality: Optional[str] = None
|
||||
background: Optional[str] = None
|
||||
appearance: Optional[str] = None
|
||||
relationships: Optional[str] = None
|
||||
organization_type: Optional[str] = None
|
||||
organization_purpose: Optional[str] = None
|
||||
organization_members: Optional[str] = None
|
||||
traits: Optional[str] = None
|
||||
|
||||
|
||||
class CharacterResponse(CharacterBase):
|
||||
"""角色响应模型"""
|
||||
id: str
|
||||
project_id: str
|
||||
avatar_url: Optional[str] = None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class CharacterGenerateRequest(BaseModel):
|
||||
"""AI生成角色的请求模型"""
|
||||
project_id: str = Field(..., description="项目ID")
|
||||
name: Optional[str] = Field(None, description="角色名称")
|
||||
role_type: Optional[str] = Field(None, description="角色类型")
|
||||
background: Optional[str] = Field(None, description="角色背景")
|
||||
requirements: Optional[str] = Field(None, description="特殊要求")
|
||||
provider: Optional[str] = Field(None, description="AI提供商")
|
||||
model: Optional[str] = Field(None, description="AI模型")
|
||||
|
||||
|
||||
class CharacterListResponse(BaseModel):
|
||||
"""角色列表响应模型"""
|
||||
total: int
|
||||
items: List[CharacterResponse]
|
||||
@@ -0,0 +1,88 @@
|
||||
"""大纲相关的Pydantic模型"""
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class OutlineBase(BaseModel):
|
||||
"""大纲基础模型"""
|
||||
title: str = Field(..., description="章节标题")
|
||||
content: str = Field(..., description="章节内容概要")
|
||||
|
||||
|
||||
class OutlineCreate(BaseModel):
|
||||
"""创建大纲的请求模型"""
|
||||
project_id: str = Field(..., description="所属项目ID")
|
||||
title: str = Field(..., description="章节标题")
|
||||
content: str = Field(..., description="章节内容概要")
|
||||
order_index: int = Field(..., description="章节序号", ge=1)
|
||||
structure: Optional[str] = Field(None, description="结构化大纲数据(JSON)")
|
||||
|
||||
|
||||
class OutlineUpdate(BaseModel):
|
||||
"""更新大纲的请求模型"""
|
||||
title: Optional[str] = None
|
||||
content: Optional[str] = None
|
||||
# order_index 不允许通过普通更新修改,只能通过 reorder_outlines 接口批量调整
|
||||
# structure 暂不支持修改
|
||||
|
||||
|
||||
class OutlineResponse(BaseModel):
|
||||
"""大纲响应模型"""
|
||||
id: str
|
||||
project_id: str
|
||||
title: str
|
||||
content: str
|
||||
structure: Optional[str] = None
|
||||
order_index: int
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class OutlineGenerateRequest(BaseModel):
|
||||
"""AI生成大纲的请求模型 - 支持全新生成和智能续写"""
|
||||
project_id: str = Field(..., description="项目ID")
|
||||
genre: Optional[str] = Field(None, description="小说类型,如:玄幻、都市、悬疑等")
|
||||
theme: str = Field(..., description="小说主题")
|
||||
chapter_count: int = Field(..., ge=1, description="章节数量")
|
||||
narrative_perspective: str = Field(..., description="叙事视角")
|
||||
world_context: Optional[dict] = Field(None, description="世界观背景")
|
||||
characters_context: Optional[list] = Field(None, description="角色信息")
|
||||
target_words: int = Field(100000, description="目标字数")
|
||||
requirements: Optional[str] = Field(None, description="其他特殊要求")
|
||||
provider: Optional[str] = Field(None, description="AI提供商")
|
||||
model: Optional[str] = Field(None, description="AI模型")
|
||||
|
||||
# 续写相关参数
|
||||
mode: str = Field("auto", description="生成模式: auto(自动判断), new(全新生成), continue(续写)")
|
||||
story_direction: Optional[str] = Field(None, description="故事发展方向提示(续写时使用)")
|
||||
plot_stage: str = Field("development", description="情节阶段: development(发展), climax(高潮), ending(结局)")
|
||||
keep_existing: bool = Field(False, description="是否保留现有大纲(续写时)")
|
||||
|
||||
|
||||
class ChapterOutlineGenerateRequest(BaseModel):
|
||||
"""为单个章节生成大纲的请求模型"""
|
||||
outline_id: str = Field(..., description="大纲ID")
|
||||
context: Optional[str] = Field(None, description="额外上下文")
|
||||
provider: Optional[str] = Field(None, description="AI提供商")
|
||||
model: Optional[str] = Field(None, description="AI模型")
|
||||
|
||||
|
||||
class OutlineListResponse(BaseModel):
|
||||
"""大纲列表响应模型"""
|
||||
total: int
|
||||
items: list[OutlineResponse]
|
||||
|
||||
|
||||
class OutlineReorderItem(BaseModel):
|
||||
"""单个大纲重排序项"""
|
||||
id: str = Field(..., description="大纲ID")
|
||||
order_index: int = Field(..., description="新的序号", ge=1)
|
||||
|
||||
|
||||
class OutlineReorderRequest(BaseModel):
|
||||
"""大纲批量重排序请求"""
|
||||
orders: list[OutlineReorderItem] = Field(..., description="排序列表")
|
||||
@@ -0,0 +1,20 @@
|
||||
"""AI去味相关的Pydantic模型"""
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class PolishRequest(BaseModel):
|
||||
"""AI去味请求模型"""
|
||||
original_text: str = Field(..., description="原始文本(AI生成的文本)")
|
||||
project_id: Optional[int] = Field(None, description="项目ID(可选,用于记录历史)")
|
||||
provider: Optional[str] = Field(None, description="AI提供商")
|
||||
model: Optional[str] = Field(None, description="AI模型")
|
||||
temperature: Optional[float] = Field(0.8, description="温度参数,建议0.7-0.9")
|
||||
|
||||
|
||||
class PolishResponse(BaseModel):
|
||||
"""AI去味响应模型"""
|
||||
original_text: str = Field(..., description="原始文本")
|
||||
polished_text: str = Field(..., description="去味后的文本")
|
||||
word_count_before: int = Field(..., description="处理前字数")
|
||||
word_count_after: int = Field(..., description="处理后字数")
|
||||
@@ -0,0 +1,83 @@
|
||||
"""项目相关的Pydantic模型"""
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class ProjectBase(BaseModel):
|
||||
"""项目基础模型"""
|
||||
title: str = Field(..., description="项目标题")
|
||||
description: Optional[str] = Field(None, description="项目描述")
|
||||
theme: Optional[str] = Field(None, description="主题")
|
||||
genre: Optional[str] = Field(None, description="小说类型")
|
||||
target_words: Optional[int] = Field(None, description="目标字数")
|
||||
|
||||
|
||||
class ProjectCreate(ProjectBase):
|
||||
"""创建项目的请求模型"""
|
||||
pass
|
||||
|
||||
|
||||
class ProjectUpdate(BaseModel):
|
||||
"""更新项目的请求模型"""
|
||||
title: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
theme: Optional[str] = None
|
||||
genre: Optional[str] = None
|
||||
target_words: Optional[int] = None
|
||||
status: Optional[str] = None
|
||||
# wizard_status 和 wizard_step 只能通过向导API修改,普通更新不允许
|
||||
world_time_period: Optional[str] = None
|
||||
world_location: Optional[str] = None
|
||||
world_atmosphere: Optional[str] = None
|
||||
world_rules: Optional[str] = None
|
||||
chapter_count: Optional[int] = None
|
||||
narrative_perspective: Optional[str] = None
|
||||
character_count: Optional[int] = None
|
||||
# current_words 由章节内容自动计算,不允许手动修改
|
||||
|
||||
|
||||
class ProjectResponse(ProjectBase):
|
||||
"""项目响应模型"""
|
||||
id: str # UUID字符串
|
||||
status: str
|
||||
current_words: int
|
||||
wizard_status: Optional[str] = None
|
||||
wizard_step: Optional[int] = None
|
||||
world_time_period: Optional[str] = None
|
||||
world_location: Optional[str] = None
|
||||
world_atmosphere: Optional[str] = None
|
||||
world_rules: Optional[str] = None
|
||||
chapter_count: Optional[int] = None
|
||||
narrative_perspective: Optional[str] = None
|
||||
character_count: Optional[int] = None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class ProjectListResponse(BaseModel):
|
||||
"""项目列表响应模型"""
|
||||
total: int
|
||||
items: list[ProjectResponse]
|
||||
|
||||
|
||||
class ProjectWizardRequest(BaseModel):
|
||||
"""项目创建向导请求模型"""
|
||||
title: str = Field(..., description="书名")
|
||||
theme: str = Field(..., description="主题")
|
||||
genre: Optional[str] = Field(None, description="类型")
|
||||
chapter_count: int = Field(..., ge=1, description="章节数量")
|
||||
narrative_perspective: str = Field(..., description="叙事视角")
|
||||
character_count: int = Field(5, ge=5, description="角色数量(至少5个)")
|
||||
target_words: Optional[int] = Field(None, description="目标字数")
|
||||
|
||||
|
||||
class WorldBuildingResponse(BaseModel):
|
||||
"""世界构建响应模型"""
|
||||
time_period: str = Field(..., description="时间背景")
|
||||
location: str = Field(..., description="地理位置")
|
||||
atmosphere: str = Field(..., description="氛围基调")
|
||||
rules: str = Field(..., description="世界规则")
|
||||
@@ -0,0 +1,204 @@
|
||||
"""关系管理相关的Pydantic模型"""
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional, List
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
# ============ 关系类型相关 ============
|
||||
|
||||
class RelationshipTypeResponse(BaseModel):
|
||||
"""关系类型响应模型"""
|
||||
id: int
|
||||
name: str
|
||||
category: str
|
||||
reverse_name: Optional[str] = None
|
||||
intimacy_range: Optional[str] = None
|
||||
icon: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ============ 角色关系相关 ============
|
||||
|
||||
class CharacterRelationshipBase(BaseModel):
|
||||
"""角色关系基础模型"""
|
||||
relationship_type_id: Optional[int] = Field(None, description="关系类型ID")
|
||||
relationship_name: Optional[str] = Field(None, description="自定义关系名称")
|
||||
intimacy_level: int = Field(50, ge=0, le=100, description="亲密度:0-100")
|
||||
status: str = Field("active", description="状态:active/broken/past/complicated")
|
||||
description: Optional[str] = Field(None, description="关系描述")
|
||||
started_at: Optional[str] = Field(None, description="关系开始时间(故事时间)")
|
||||
ended_at: Optional[str] = Field(None, description="关系结束时间")
|
||||
|
||||
|
||||
class CharacterRelationshipCreate(CharacterRelationshipBase):
|
||||
"""创建角色关系的请求模型"""
|
||||
project_id: str = Field(..., description="项目ID")
|
||||
character_from_id: str = Field(..., description="角色A的ID")
|
||||
character_to_id: str = Field(..., description="角色B的ID")
|
||||
|
||||
|
||||
class CharacterRelationshipUpdate(BaseModel):
|
||||
"""更新角色关系的请求模型"""
|
||||
relationship_type_id: Optional[int] = None
|
||||
relationship_name: Optional[str] = None
|
||||
intimacy_level: Optional[int] = Field(None, ge=0, le=100)
|
||||
status: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
started_at: Optional[str] = None
|
||||
ended_at: Optional[str] = None
|
||||
|
||||
|
||||
class CharacterRelationshipResponse(CharacterRelationshipBase):
|
||||
"""角色关系响应模型"""
|
||||
id: str
|
||||
project_id: str
|
||||
character_from_id: str
|
||||
character_to_id: str
|
||||
source: str
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class RelationshipGraphNode(BaseModel):
|
||||
"""关系图谱节点"""
|
||||
id: str
|
||||
name: str
|
||||
type: str # character / organization
|
||||
role_type: Optional[str] = None
|
||||
avatar: Optional[str] = None
|
||||
|
||||
|
||||
class RelationshipGraphLink(BaseModel):
|
||||
"""关系图谱连线"""
|
||||
source: str
|
||||
target: str
|
||||
relationship: str
|
||||
intimacy: int
|
||||
status: str
|
||||
|
||||
|
||||
class RelationshipGraphData(BaseModel):
|
||||
"""关系图谱数据"""
|
||||
nodes: List[RelationshipGraphNode]
|
||||
links: List[RelationshipGraphLink]
|
||||
|
||||
|
||||
# ============ 组织相关 ============
|
||||
|
||||
class OrganizationBase(BaseModel):
|
||||
"""组织基础模型"""
|
||||
parent_org_id: Optional[str] = Field(None, description="父组织ID")
|
||||
level: int = Field(0, description="组织层级")
|
||||
power_level: int = Field(50, ge=0, le=100, description="势力等级")
|
||||
location: Optional[str] = Field(None, description="所在地")
|
||||
motto: Optional[str] = Field(None, description="组织宗旨")
|
||||
color: Optional[str] = Field(None, description="代表颜色")
|
||||
|
||||
|
||||
class OrganizationCreate(OrganizationBase):
|
||||
"""创建组织的请求模型"""
|
||||
character_id: str = Field(..., description="关联的角色ID(组织记录)")
|
||||
project_id: str = Field(..., description="项目ID")
|
||||
|
||||
|
||||
class OrganizationUpdate(BaseModel):
|
||||
"""更新组织的请求模型"""
|
||||
parent_org_id: Optional[str] = None
|
||||
level: Optional[int] = None
|
||||
power_level: Optional[int] = Field(None, ge=0, le=100)
|
||||
location: Optional[str] = None
|
||||
motto: Optional[str] = None
|
||||
color: Optional[str] = None
|
||||
|
||||
|
||||
class OrganizationResponse(OrganizationBase):
|
||||
"""组织响应模型"""
|
||||
id: str
|
||||
character_id: str
|
||||
project_id: str
|
||||
member_count: int
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class OrganizationDetailResponse(BaseModel):
|
||||
"""组织详情响应(包含基本信息)"""
|
||||
id: str
|
||||
character_id: str
|
||||
name: str
|
||||
type: Optional[str] = None
|
||||
purpose: Optional[str] = None
|
||||
member_count: int
|
||||
power_level: int
|
||||
location: Optional[str] = None
|
||||
motto: Optional[str] = None
|
||||
color: Optional[str] = None
|
||||
|
||||
|
||||
# ============ 组织成员相关 ============
|
||||
|
||||
class OrganizationMemberBase(BaseModel):
|
||||
"""组织成员基础模型"""
|
||||
position: str = Field(..., description="职位名称")
|
||||
rank: int = Field(0, description="职位等级")
|
||||
status: str = Field("active", description="状态:active/retired/expelled/deceased")
|
||||
joined_at: Optional[str] = Field(None, description="加入时间(故事时间)")
|
||||
left_at: Optional[str] = Field(None, description="离开时间")
|
||||
loyalty: int = Field(50, ge=0, le=100, description="忠诚度")
|
||||
contribution: int = Field(0, ge=0, le=100, description="贡献度")
|
||||
notes: Optional[str] = Field(None, description="备注")
|
||||
|
||||
|
||||
class OrganizationMemberCreate(OrganizationMemberBase):
|
||||
"""创建组织成员的请求模型"""
|
||||
character_id: str = Field(..., description="角色ID")
|
||||
|
||||
|
||||
class OrganizationMemberUpdate(BaseModel):
|
||||
"""更新组织成员的请求模型"""
|
||||
position: Optional[str] = None
|
||||
rank: Optional[int] = None
|
||||
status: Optional[str] = None
|
||||
joined_at: Optional[str] = None
|
||||
left_at: Optional[str] = None
|
||||
loyalty: Optional[int] = Field(None, ge=0, le=100)
|
||||
contribution: Optional[int] = Field(None, ge=0, le=100)
|
||||
notes: Optional[str] = None
|
||||
|
||||
|
||||
class OrganizationMemberResponse(OrganizationMemberBase):
|
||||
"""组织成员响应模型"""
|
||||
id: str
|
||||
organization_id: str
|
||||
character_id: str
|
||||
source: str
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class OrganizationMemberDetailResponse(BaseModel):
|
||||
"""组织成员详情响应(包含角色信息)"""
|
||||
id: str
|
||||
character_id: str
|
||||
character_name: str
|
||||
position: str
|
||||
rank: int
|
||||
loyalty: int
|
||||
contribution: int
|
||||
status: str
|
||||
joined_at: Optional[str] = None
|
||||
left_at: Optional[str] = None
|
||||
notes: Optional[str] = None
|
||||
Reference in New Issue
Block a user