baodan/api/insurance/models/poster_record.py

106 lines
6.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""海报生成记录模型。"""
from sqlalchemy import Column, String, Text, BigInteger, Integer, TIMESTAMP, func
from insurance.db.compat import db
class PosterRecord(db.Model):
"""海报生成记录表。"""
__tablename__ = "poster_records"
id = Column(BigInteger, primary_key=True, autoincrement=True)
user_id = Column(String(50), nullable=False, comment="用户 ID")
product_id = Column(String(50), nullable=True, comment="产品 ID")
product_source_type = Column(String(20), nullable=True, comment="library_product/user_material")
product_source_id = Column(String(64), nullable=True, comment="产品来源 ID")
product_snapshot_json = Column(Text, nullable=True, comment="提交生成时的产品快照 JSON")
case_upload_id = Column(BigInteger, nullable=True, comment="关联计划书上传 ID")
template_id = Column(BigInteger, nullable=True, comment="海报模板 ID")
copy_mode = Column(String(20), nullable=True, comment="文案模式: template/ai")
copy_content = Column(Text, nullable=True, comment="最终文案 JSON")
ai_raw_content = Column(Text, nullable=True, comment="AI 原始文案 JSON合规留痕")
export_url = Column(String(500), nullable=True, comment="导出文件地址")
export_format = Column(String(10), nullable=True, comment="导出格式: png/jpg")
export_size = Column(String(20), nullable=True, comment="导出尺寸")
reference_image_used = Column(String(500), nullable=True, comment="使用的参考图(合规留痕)")
prompt_used = Column(Text, nullable=True, comment="完整 prompt合规留痕")
generation_mode = Column(String(20), nullable=True, comment="生成方式: ai/fallback")
image_provider = Column(String(50), nullable=True, comment="图片供应商")
image_model = Column(String(100), nullable=True, comment="图片模型名称")
task_status = Column(String(20), default="pending", comment="任务状态: pending/queued/generating/background_ready/done/failed")
task_progress = Column(db.Integer, default=0, comment="任务进度 0-100")
task_error = Column(Text, nullable=True, comment="任务错误信息")
extra_data = Column(Text, nullable=True, comment="扩展数据 JSON如品牌策略、输出模式")
document_json = Column(Text, nullable=True, comment="可编辑海报文档 JSON")
document_revision = Column(Integer, default=1, comment="海报文档版本")
background_file_url = Column(String(500), nullable=True, comment="AI 背景图文件地址")
compliance_json = Column(Text, nullable=True, comment="服务端合规检查结果 JSON")
compliance_revision = Column(String(64), nullable=True, comment="合规文案哈希")
# 工作区字段migrate_022
title = Column(String(200), default="", comment="工作区名称")
workflow_step = Column(String(20), default="product", comment="当前业务步骤")
draft_status = Column(String(20), default="active", comment="active/archived")
draft_revision = Column(Integer, default=1, comment="当前草稿版本")
generated_revision = Column(Integer, default=0, comment="最新成品版本")
latest_task_id = Column(String(36), nullable=True, comment="最近任务 ID")
archived_at = Column(TIMESTAMP, nullable=True, comment="归档时间")
started_at = Column(TIMESTAMP, nullable=True, comment="任务开始时间")
finished_at = Column(TIMESTAMP, nullable=True, comment="任务完成时间")
created_at = Column(TIMESTAMP, server_default=func.now())
def to_dict(self):
import json
def _safe_json(text):
if not text:
return None
try:
return json.loads(text)
except (json.JSONDecodeError, TypeError):
return None
return {
"id": self.id,
"userId": self.user_id,
"productId": self.product_id,
"productSource": {
"type": self.product_source_type or "library_product",
"id": self.product_source_id or self.product_id,
},
"productSnapshot": _safe_json(self.product_snapshot_json),
"caseUploadId": self.case_upload_id,
"templateId": self.template_id,
"copyMode": self.copy_mode,
"copyContent": _safe_json(self.copy_content),
"aiRawContent": _safe_json(self.ai_raw_content),
"exportUrl": self.export_url,
"exportFormat": self.export_format,
"exportSize": self.export_size,
"referenceImageUsed": self.reference_image_used,
"promptUsed": self.prompt_used,
"generationMode": self.generation_mode,
"imageProvider": self.image_provider,
"imageModel": self.image_model,
"taskStatus": self.task_status,
"taskProgress": self.task_progress,
"taskError": self.task_error,
"extraData": _safe_json(self.extra_data),
"document": _safe_json(self.document_json),
"documentRevision": self.document_revision or 1,
"backgroundUrl": (
f"/insurance/poster/records/{self.id}/background"
if self.background_file_url else None
),
"compliance": _safe_json(self.compliance_json),
"complianceRevision": self.compliance_revision or "",
"title": self.title or "",
"workflowStep": self.workflow_step or "product",
"draftStatus": self.draft_status or "active",
"draftRevision": self.draft_revision or 1,
"generatedRevision": self.generated_revision or 0,
"latestTaskId": self.latest_task_id,
"archivedAt": self.archived_at.isoformat() if self.archived_at else None,
"startedAt": self.started_at.isoformat() if self.started_at else None,
"finishedAt": self.finished_at.isoformat() if self.finished_at else None,
"createdAt": self.created_at.isoformat() if self.created_at else None,
}