把“章节正文 + 图片”从 chapters 单表/JSON 结构,重构为“章节 chapter + 段落 section + 图片 memoir_images 独立表”的新数据模型,同时联动修改接口、PDF 导出、异步任务、迁移脚本、测试,以及修复 Android 端聊天列表显示问题。 (#9)
* refactor: 表结构重构,新增段落section和图片image新表 * fix: fix android app import error * refactor: 重构文件名 * fix: 优化提示词 * fix: 消息气泡显示位置异常问题 --------- Co-authored-by: yangshilin <2157598560@qq.com>
This commit is contained in:
@@ -13,6 +13,7 @@ from reportlab.lib.units import inch
|
||||
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak, Image as ReportLabImage
|
||||
from reportlab.pdfbase import pdfmetrics
|
||||
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
|
||||
from services.memoir_images.serializers import memoir_image_to_dict
|
||||
from services.memoir_images.parser import PLACEHOLDER_RE
|
||||
from services.memoir_images.schema import IMAGE_STATUS_COMPLETED, normalize_image_assets
|
||||
from services.memoir_images.storage import (
|
||||
@@ -48,6 +49,28 @@ def split_content_blocks(content: str, images: list[dict]) -> list[dict]:
|
||||
return blocks
|
||||
|
||||
|
||||
def sections_to_blocks(sections: list, prepare_fn=None) -> list[dict]:
|
||||
"""
|
||||
从 chapter_sections 生成 PDF 用的 blocks:按 order_index 顺序,每段正文 + 可选一张图。
|
||||
prepare_fn(images) 用于解析签名 URL,默认 _prepare_pdf_image_assets。
|
||||
"""
|
||||
if prepare_fn is None:
|
||||
prepare_fn = _prepare_pdf_image_assets
|
||||
blocks: list[dict] = []
|
||||
for section in sorted(sections, key=lambda s: getattr(s, "order_index", 0)):
|
||||
content = (getattr(section, "content", None) or "").strip()
|
||||
if content:
|
||||
blocks.append({"type": "text", "value": content})
|
||||
img = None
|
||||
if getattr(section, "image_record", None):
|
||||
img = memoir_image_to_dict(section.image_record)
|
||||
if img:
|
||||
prepared = prepare_fn([img])
|
||||
if prepared and prepared[0].get("url"):
|
||||
blocks.append({"type": "image", "url": prepared[0]["url"]})
|
||||
return blocks
|
||||
|
||||
|
||||
def _prepare_pdf_image_assets(images: list[dict]) -> list[dict]:
|
||||
storage = TencentCosStorageService.from_env()
|
||||
prepared_assets: list[dict] = []
|
||||
@@ -148,8 +171,12 @@ class PDFService:
|
||||
story.append(Paragraph(chapter.title, heading_style))
|
||||
story.append(Spacer(1, 0.2 * inch))
|
||||
|
||||
images = _prepare_pdf_image_assets(getattr(chapter, "images", None) or [])
|
||||
blocks = split_content_blocks(chapter.content, images)
|
||||
sections = getattr(chapter, "sections", None) or []
|
||||
if sections:
|
||||
blocks = sections_to_blocks(sections)
|
||||
else:
|
||||
images = _prepare_pdf_image_assets(getattr(chapter, "images", None) or [])
|
||||
blocks = split_content_blocks(getattr(chapter, "content", "") or "", images)
|
||||
|
||||
for block in blocks:
|
||||
if block["type"] == "text":
|
||||
|
||||
Reference in New Issue
Block a user