This commit is contained in:
xiamuceer
2025-10-30 11:14:43 +08:00
parent b97410d973
commit 0f6c2d344a
91 changed files with 22309 additions and 0 deletions
+26
View File
@@ -0,0 +1,26 @@
"""数据库模型"""
from app.models.project import Project
from app.models.outline import Outline
from app.models.character import Character
from app.models.chapter import Chapter
from app.models.generation_history import GenerationHistory
from app.models.settings import Settings
from app.models.relationship import (
RelationshipType,
CharacterRelationship,
Organization,
OrganizationMember
)
__all__ = [
"Project",
"Outline",
"Character",
"Chapter",
"GenerationHistory",
"Settings",
"RelationshipType",
"CharacterRelationship",
"Organization",
"OrganizationMember",
]
+24
View File
@@ -0,0 +1,24 @@
"""章节数据模型"""
from sqlalchemy import Column, String, Text, Integer, DateTime, ForeignKey
from sqlalchemy.sql import func
from app.database import Base
import uuid
class Chapter(Base):
"""章节表"""
__tablename__ = "chapters"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
project_id = Column(String(36), ForeignKey("projects.id", ondelete="CASCADE"), nullable=False)
chapter_number = Column(Integer, nullable=False, comment="章节序号")
title = Column(String(200), nullable=False, comment="章节标题")
content = Column(Text, comment="章节内容")
summary = Column(Text, comment="章节摘要")
word_count = Column(Integer, default=0, comment="字数统计")
status = Column(String(20), default="draft", comment="章节状态")
created_at = Column(DateTime, server_default=func.now(), comment="创建时间")
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment="更新时间")
def __repr__(self):
return f"<Chapter(id={self.id}, chapter_number={self.chapter_number}, title={self.title})>"
+44
View File
@@ -0,0 +1,44 @@
"""角色数据模型"""
from sqlalchemy import Column, String, Text, DateTime, ForeignKey, Boolean
from sqlalchemy.sql import func
from app.database import Base
import uuid
class Character(Base):
"""角色表(包括角色和组织)"""
__tablename__ = "characters"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
project_id = Column(String(36), ForeignKey("projects.id", ondelete="CASCADE"), nullable=False)
# 基本信息
name = Column(String(100), nullable=False, comment="角色/组织名称")
age = Column(String(20), comment="年龄")
gender = Column(String(20), comment="性别")
is_organization = Column(Boolean, default=False, comment="是否为组织")
# 角色类型:protagonist(主角)/supporting(配角)/antagonist(反派)
role_type = Column(String(50), comment="角色类型")
# 角色详细信息
personality = Column(Text, comment="性格特点/组织特性")
background = Column(Text, comment="背景故事")
appearance = Column(Text, comment="外貌描述")
relationships = Column(Text, comment="人物关系(JSON)")
# 组织特有字段
organization_type = Column(String(100), comment="组织类型")
organization_purpose = Column(String(500), comment="组织目的")
organization_members = Column(Text, comment="组织成员(JSON)")
# 其他
avatar_url = Column(String(500), comment="头像URL")
traits = Column(Text, comment="特征标签(JSON)")
created_at = Column(DateTime, server_default=func.now(), comment="创建时间")
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment="更新时间")
def __repr__(self):
entity_type = "组织" if self.is_organization else "角色"
return f"<Character(id={self.id}, name={self.name}, type={entity_type})>"
+23
View File
@@ -0,0 +1,23 @@
"""生成历史数据模型"""
from sqlalchemy import Column, String, Text, Integer, Float, DateTime, ForeignKey
from sqlalchemy.sql import func
from app.database import Base
import uuid
class GenerationHistory(Base):
"""生成历史表"""
__tablename__ = "generation_history"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
project_id = Column(String(36), ForeignKey("projects.id", ondelete="CASCADE"), nullable=False)
chapter_id = Column(String(36), ForeignKey("chapters.id", ondelete="SET NULL"), nullable=True)
prompt = Column(Text, comment="使用的提示词")
generated_content = Column(Text, comment="生成的内容")
model = Column(String(50), comment="使用的模型")
tokens_used = Column(Integer, comment="消耗的token数")
generation_time = Column(Float, comment="生成耗时(秒)")
created_at = Column(DateTime, server_default=func.now(), comment="创建时间")
def __repr__(self):
return f"<GenerationHistory(id={self.id}, model={self.model})>"
+22
View File
@@ -0,0 +1,22 @@
"""大纲数据模型"""
from sqlalchemy import Column, String, Text, Integer, DateTime, ForeignKey
from sqlalchemy.sql import func
from app.database import Base
import uuid
class Outline(Base):
"""大纲表"""
__tablename__ = "outlines"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
project_id = Column(String(36), ForeignKey("projects.id", ondelete="CASCADE"), nullable=False)
title = Column(String(200), nullable=False, comment="大纲标题")
content = Column(Text, comment="大纲内容")
structure = Column(Text, comment="结构化大纲数据(JSON)")
order_index = Column(Integer, comment="排序序号")
created_at = Column(DateTime, server_default=func.now(), comment="创建时间")
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment="更新时间")
def __repr__(self):
return f"<Outline(id={self.id}, title={self.title})>"
+38
View File
@@ -0,0 +1,38 @@
"""项目数据模型"""
from sqlalchemy import Column, String, Text, DateTime, Integer
from sqlalchemy.sql import func
from app.database import Base
import uuid
class Project(Base):
"""项目表"""
__tablename__ = "projects"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
title = Column(String(200), nullable=False, comment="项目标题")
description = Column(Text, comment="项目简介")
theme = Column(Text, comment="主题")
genre = Column(String(50), comment="小说类型")
target_words = Column(Integer, default=0, comment="目标字数")
current_words = Column(Integer, default=0, comment="当前字数")
status = Column(String(20), default="planning", comment="创作状态")
wizard_status = Column(String(20), default="incomplete", comment="向导完成状态: incomplete/completed")
wizard_step = Column(Integer, default=0, comment="向导当前步骤: 0-4")
# 世界构建字段
world_time_period = Column(Text, comment="时间背景")
world_location = Column(Text, comment="地理位置")
world_atmosphere = Column(Text, comment="氛围基调")
world_rules = Column(Text, comment="世界规则")
# 项目配置
chapter_count = Column(Integer, comment="章节数量")
narrative_perspective = Column(String(50), comment="叙事视角:first_person/third_person/omniscient")
character_count = Column(Integer, default=5, comment="角色数量")
created_at = Column(DateTime, server_default=func.now(), comment="创建时间")
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment="更新时间")
def __repr__(self):
return f"<Project(id={self.id}, title={self.title})>"
+116
View File
@@ -0,0 +1,116 @@
"""角色关系和组织管理数据模型"""
from sqlalchemy import Column, String, Integer, Text, DateTime, ForeignKey, Boolean
from sqlalchemy.sql import func
from app.database import Base
import uuid
class RelationshipType(Base):
"""关系类型定义表"""
__tablename__ = "relationship_types"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
name = Column(String(50), nullable=False, comment="关系名称")
category = Column(String(20), nullable=False, comment="分类:family/social/hostile/professional")
reverse_name = Column(String(50), comment="反向关系名称")
intimacy_range = Column(String(20), comment="亲密度范围:high/medium/low")
icon = Column(String(50), comment="图标标识")
description = Column(Text, comment="关系描述")
created_at = Column(DateTime, server_default=func.now(), comment="创建时间")
def __repr__(self):
return f"<RelationshipType(id={self.id}, name={self.name}, category={self.category})>"
class CharacterRelationship(Base):
"""角色关系表"""
__tablename__ = "character_relationships"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="关系ID")
project_id = Column(String(36), ForeignKey("projects.id", ondelete="CASCADE"), nullable=False, index=True, comment="项目ID")
# 关系双方
character_from_id = Column(String(36), ForeignKey("characters.id", ondelete="CASCADE"), nullable=False, index=True, comment="角色A的ID")
character_to_id = Column(String(36), ForeignKey("characters.id", ondelete="CASCADE"), nullable=False, index=True, comment="角色B的ID")
# 关系类型
relationship_type_id = Column(Integer, ForeignKey("relationship_types.id"), index=True, comment="关系类型ID")
relationship_name = Column(String(100), comment="自定义关系名称")
# 关系属性
intimacy_level = Column(Integer, default=50, comment="亲密度:0-100")
status = Column(String(20), default="active", comment="状态:active/broken/past/complicated")
description = Column(Text, comment="关系详细描述")
# 故事时间线
started_at = Column(String(100), comment="关系开始时间(故事时间)")
ended_at = Column(String(100), comment="关系结束时间(故事时间)")
# 来源标识
source = Column(String(20), default="ai", comment="来源:ai/manual/imported")
created_at = Column(DateTime, server_default=func.now(), comment="创建时间")
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment="更新时间")
def __repr__(self):
return f"<CharacterRelationship(id={self.id}, from={self.character_from_id}, to={self.character_to_id})>"
class Organization(Base):
"""组织详情表"""
__tablename__ = "organizations"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="组织ID")
character_id = Column(String(36), ForeignKey("characters.id", ondelete="CASCADE"), nullable=False, unique=True, comment="关联的角色ID")
project_id = Column(String(36), ForeignKey("projects.id", ondelete="CASCADE"), nullable=False, index=True, comment="项目ID")
# 组织层级
parent_org_id = Column(String(36), ForeignKey("organizations.id", ondelete="SET NULL"), comment="父组织ID")
level = Column(Integer, default=0, comment="组织层级")
# 组织属性
power_level = Column(Integer, default=50, comment="势力等级:0-100")
member_count = Column(Integer, default=0, comment="成员数量")
location = Column(Text, comment="所在地")
# 组织特色
motto = Column(String(200), comment="宗旨/口号")
color = Column(String(20), comment="代表颜色")
created_at = Column(DateTime, server_default=func.now(), comment="创建时间")
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment="更新时间")
def __repr__(self):
return f"<Organization(id={self.id}, character_id={self.character_id})>"
class OrganizationMember(Base):
"""组织成员关系表"""
__tablename__ = "organization_members"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="成员关系ID")
organization_id = Column(String(36), ForeignKey("organizations.id", ondelete="CASCADE"), nullable=False, index=True, comment="组织ID")
character_id = Column(String(36), ForeignKey("characters.id", ondelete="CASCADE"), nullable=False, index=True, comment="角色ID")
# 职位信息
position = Column(String(100), nullable=False, comment="职位名称")
rank = Column(Integer, default=0, comment="职位等级")
# 成员状态
status = Column(String(20), default="active", comment="状态:active/retired/expelled/deceased")
joined_at = Column(String(100), comment="加入时间(故事时间)")
left_at = Column(String(100), comment="离开时间(故事时间)")
# 成员属性
loyalty = Column(Integer, default=50, comment="忠诚度:0-100")
contribution = Column(Integer, default=0, comment="贡献度:0-100")
# 来源标识
source = Column(String(20), default="ai", comment="来源:ai/manual")
notes = Column(Text, comment="备注")
created_at = Column(DateTime, server_default=func.now(), comment="创建时间")
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment="更新时间")
def __repr__(self):
return f"<OrganizationMember(id={self.id}, org={self.organization_id}, char={self.character_id})>"
+24
View File
@@ -0,0 +1,24 @@
"""设置数据模型"""
from sqlalchemy import Column, String, Text, Float, Integer, DateTime
from sqlalchemy.sql import func
from app.database import Base
import uuid
class Settings(Base):
"""设置表"""
__tablename__ = "settings"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
api_provider = Column(String(50), default="openai", comment="API提供商")
api_key = Column(String(500), comment="API密钥")
api_base_url = Column(String(500), comment="自定义API地址")
model_name = Column(String(100), default="gpt-4", comment="模型名称")
temperature = Column(Float, default=0.7, comment="温度参数")
max_tokens = Column(Integer, default=2000, comment="最大token数")
preferences = Column(Text, comment="其他偏好设置(JSON)")
created_at = Column(DateTime, server_default=func.now(), comment="创建时间")
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment="更新时间")
def __repr__(self):
return f"<Settings(id={self.id}, api_provider={self.api_provider})>"