File size: 7,632 Bytes
7c15d35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
from sqlalchemy import Column, Integer, String, DateTime, Text, Boolean, ForeignKey, Float
from sqlalchemy.orm import relationship
from datetime import datetime
from app.database import Base
from app.config import settings


class User(Base):
    """用户表"""
    __tablename__ = "users"
    
    id = Column(Integer, primary_key=True, index=True)
    card_key = Column(String(255), unique=True, index=True, nullable=False)
    access_link = Column(String(255), unique=True, index=True, nullable=False)
    is_active = Column(Boolean, default=True)
    created_at = Column(DateTime, default=datetime.utcnow)
    last_used = Column(DateTime, nullable=True)
    usage_limit = Column(Integer, default=settings.DEFAULT_USAGE_LIMIT)
    usage_count = Column(Integer, default=0)
    
    # 关系
    sessions = relationship("OptimizationSession", back_populates="user")
    prompts = relationship("CustomPrompt", back_populates="user")
    saved_specs = relationship("SavedSpec", back_populates="user", cascade="all, delete-orphan")


class CustomPrompt(Base):
    """自定义提示词表"""
    __tablename__ = "custom_prompts"
    
    id = Column(Integer, primary_key=True, index=True)
    user_id = Column(Integer, ForeignKey("users.id"), nullable=True)
    name = Column(String(255), nullable=False)
    stage = Column(String(50), nullable=False)  # 'polish' 或 'enhance'
    content = Column(Text, nullable=False)
    is_default = Column(Boolean, default=False)
    is_system = Column(Boolean, default=False)  # 系统预设提示词
    is_active = Column(Boolean, default=True)  # 是否启用
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关系
    user = relationship("User", back_populates="prompts")


class OptimizationSession(Base):
    """优化会话表"""
    __tablename__ = "optimization_sessions"
    
    id = Column(Integer, primary_key=True, index=True)
    user_id = Column(Integer, ForeignKey("users.id"), index=True)
    session_id = Column(String(255), unique=True, index=True)
    original_text = Column(Text)
    current_stage = Column(String(50))  # 'polish' 或 'enhance'
    status = Column(String(50), index=True)  # 'queued', 'processing', 'completed', 'failed'
    progress = Column(Float, default=0.0)
    current_position = Column(Integer, default=0)  # 当前处理的段落位置
    total_segments = Column(Integer, default=0)  # 总段落数
    error_message = Column(Text, nullable=True)
    failed_segment_index = Column(Integer, nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow, index=True)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    completed_at = Column(DateTime, nullable=True)
    
    # 模型配置
    polish_model = Column(String(100), nullable=True)
    polish_api_key = Column(String(255), nullable=True)
    polish_base_url = Column(String(255), nullable=True)
    enhance_model = Column(String(100), nullable=True)
    enhance_api_key = Column(String(255), nullable=True)
    enhance_base_url = Column(String(255), nullable=True)
    emotion_model = Column(String(100), nullable=True)
    emotion_api_key = Column(String(255), nullable=True)
    emotion_base_url = Column(String(255), nullable=True)
    
    # 处理模式: 'paper_polish', 'paper_enhance', 'paper_polish_enhance', 'emotion_polish'
    processing_mode = Column(String(50), default='paper_polish_enhance')
    
    # 关系
    user = relationship("User", back_populates="sessions")
    segments = relationship("OptimizationSegment", back_populates="session", cascade="all, delete-orphan")
    history = relationship("SessionHistory", back_populates="session", cascade="all, delete-orphan")

    @property
    def completed_segments(self) -> int:
        """Return how many segments finished successfully."""
        return sum(1 for segment in self.segments if segment.status == "completed")


class OptimizationSegment(Base):
    """优化段落表"""
    __tablename__ = "optimization_segments"
    
    id = Column(Integer, primary_key=True, index=True)
    session_id = Column(Integer, ForeignKey("optimization_sessions.id"), index=True)
    segment_index = Column(Integer, index=True)  # 段落序号
    stage = Column(String(50))  # 'polish' 或 'enhance'
    original_text = Column(Text)
    polished_text = Column(Text, nullable=True)
    enhanced_text = Column(Text, nullable=True)
    status = Column(String(50), index=True)  # 'pending', 'processing', 'completed', 'failed'
    is_title = Column(Boolean, default=False)
    created_at = Column(DateTime, default=datetime.utcnow)
    completed_at = Column(DateTime, nullable=True)
    
    # 关系
    session = relationship("OptimizationSession", back_populates="segments")


class SessionHistory(Base):
    """会话历史表 (用于AI上下文)"""
    __tablename__ = "session_history"
    
    id = Column(Integer, primary_key=True, index=True)
    session_id = Column(Integer, ForeignKey("optimization_sessions.id"))
    stage = Column(String(50))  # 'polish' 或 'enhance'
    history_data = Column(Text)  # JSON格式的历史会话
    is_compressed = Column(Boolean, default=False)
    character_count = Column(Integer, default=0)  # 汉字数量
    created_at = Column(DateTime, default=datetime.utcnow)
    
    # 关系
    session = relationship("OptimizationSession", back_populates="history")


class ChangeLog(Base):
    """变更对照记录表 (用于学术审计)"""
    __tablename__ = "change_logs"
    
    id = Column(Integer, primary_key=True, index=True)
    session_id = Column(Integer, ForeignKey("optimization_sessions.id"), index=True)
    segment_index = Column(Integer, index=True)
    stage = Column(String(50), index=True)  # 'polish' 或 'enhance'
    before_text = Column(Text)
    after_text = Column(Text)
    changes_detail = Column(Text)  # JSON格式的详细变更
    created_at = Column(DateTime, default=datetime.utcnow)


class QueueStatus(Base):
    """队列状态表"""
    __tablename__ = "queue_status"
    
    id = Column(Integer, primary_key=True, index=True)
    session_id = Column(String(255), unique=True, index=True)
    user_id = Column(Integer, ForeignKey("users.id"))
    position = Column(Integer)  # 队列位置
    status = Column(String(50))  # 'queued' 或 'processing'
    created_at = Column(DateTime, default=datetime.utcnow)
    started_at = Column(DateTime, nullable=True)


class SystemSetting(Base):
    """系统设置表"""
    __tablename__ = "system_settings"

    id = Column(Integer, primary_key=True, index=True)
    key = Column(String(100), unique=True, nullable=False)
    value = Column(String(255), nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)


class SavedSpec(Base):
    """用户保存的排版规范表"""
    __tablename__ = "saved_specs"

    id = Column(Integer, primary_key=True, index=True)
    user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True)
    name = Column(String(100), nullable=False)
    description = Column(String(500), nullable=True)
    spec_json = Column(Text, nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    # 关系
    user = relationship("User", back_populates="saved_specs")