全部改动文件总览 后端(8 个文件) 文件 操作 api/insurance/models/ppt_session.py 修改 — 新增 5 个字段 api/insurance/db/migrate_025.py 新建 — 数据库迁移 api/insurance/ppt/renderer.py 修改 — 新增 parse_slides(),deck 返回 api/insurance/ppt/quality_checker.py 新建 — 质量检查 api/insurance/ppt/routes.py 修改 — 新增 5 个接口 api/insurance/generation/celery_tasks.py 修改 — 集成预览+质检+版本化,新增 regenerate 任务 api/insurance/generation/task_service.py 修改 — 注册 regenerate 任务 前端(8 个文件) 文件 操作 frontend/src/utils/ppt-api.ts 修改 — 新增类型和 API 方法 frontend/src/pages/components/ppt/PptSlideCanvas.vue 新建 — Canvas 渲染器 frontend/src/pages/components/ppt/PptResult.vue 重写 — 三栏工作台 + 版本历史 frontend/src/pages/components/ppt/PptUpload.vue 重写 — 双栏 Hero 布局 frontend/src/pages/components/ppt/PptParsing.vue 重写 — 五阶段进度 frontend/src/pages/components/ppt/PptDataReview.vue 修改 — 主题色更新 frontend/src/pages/PptPage.vue 修改 — 步骤描述 + 主题色 frontend/src/pages/PptHistoryPage.vue 重写 — 卡片式布局 新增后端接口 方法 路径 功能 GET /ppt/preview/:id 获取幻灯片 JSON + 质量报告 + 版本历史 PUT /ppt/preview/:id/slide/:index 更新编辑内容 + 显隐 PUT /ppt/preview/:id/quality-confirm 人工质量确认 POST /ppt/preview/:id/regenerate 基于编辑生成新版本
65 KiB
海报生成工作台完整重构修复计划
- 文档版本:v1.0
- 编制日期:2026-07-29
- 适用范围:
api/insurance/poster/、api/insurance/generation/、frontend/src/pages/Poster*、frontend/src/components/poster/- 实施状态:待开发
- 优先级:P0/P1
- 预计工作量:约 24.5 人日,建议预留 20% 风险缓冲
一、文档目的
本计划用于把现有“选择后台产品和模板、生成文案、输出单张 PNG”的海报功能,重构为完整的保险营销内容生产工作台:
创建项目
→ 选择后台产品或上传产品小册子
→ 上传客户计划书和参考素材
→ 异步解析
→ 数据底表 / 来源审计 / QA 校验
→ 人工确认
→ AI 生成视觉方案和文案
→ 生成可编辑画布
→ 人工编辑与版本保存
→ PNG / JPG / PDF / 项目源文件导出
→ 任务、历史、配置版本和审计记录同步到后台
本文是海报模块二期重构的执行基线。当本文与以下旧文档的“海报”部分冲突时,以本文为准;旧文档中的 PPT 整改内容继续有效:
PPT与海报功能完整解决方案.mdPPT与海报功能开发任务清单.mdPPT与海报功能问题整改计划.md
二、目标、边界与关键假设
2.1 建设目标
| 编号 | 目标 | 成功标准 |
|---|---|---|
| G-01 | 用户可自由提供本次创作资料 | 计划书 PDF、产品小册子 PDF、参考图片均可直接上传 |
| G-02 | 后台产品库不再是唯一入口 | 用户可从产品库选择,也可仅在当前项目使用临时小册子 |
| G-03 | AI 生成与内容相符的视觉素材 | AI 根据客户、产品、场景、品牌约束生成 2~4 个真实视觉候选 |
| G-04 | 文字和数字不烘焙进 AI 图片 | 标题、卖点、数字、图表、Logo、免责声明均为独立画布图层 |
| G-05 | 生成前完成真实数据校验 | 每个关键事实可追溯到文件、页码和原文;错误项阻断生成 |
| G-06 | 生成结果可继续编辑 | 支持选择、移动、缩放、改字、换图、图层、撤销重做和自动保存 |
| G-07 | 支持多格式交付 | 首期支持 PNG、JPG、PDF、项目源文件 |
| G-08 | 全链路与后台同步 | 项目、素材、校验、任务、画布版本、导出物和配置快照可恢复、可审计 |
| G-09 | 保持 BaoDan 升级安全 | 自研实现全部位于 api/insurance/ 和独立 frontend/ 项目 |
2.2 不在本期范围
以下能力不进入首期 P0/P1,避免海报编辑器无限扩张:
- 多人同时在线协作编辑;
- 类 Photoshop 的像素级蒙版、钢笔和滤镜系统;
- 视频海报、GIF、动画海报;
- 任意第三方字体商城;
- 用户自定义脚本或 HTML;
- 社交平台自动发布;
- SVG 正式交付;完成兼容性验证后作为 P2;
- 手机端进行精细拖拽排版。
2.3 默认产品假设
| 决策 | 默认方案 | 原因 |
|---|---|---|
| 编辑器主要设备 | 桌面端和大屏平板 | 精细排版不适合手机单手操作 |
| 手机端范围 | 上传、校验、任务查看、预览、基础文字/图片替换 | 保证移动业务连续性,不承诺精细排版 |
| 画布技术 | Fabric.js | 具备文本编辑、对象模型、图层、JSON 序列化和图片导出能力 |
| AI 图片职责 | 生成背景、人物、场景、装饰素材 | 避免 AI 中文和保险数字错误 |
| 画布职责 | 组合图片、文字、数字、图表、Logo、免责声明 | 保证可编辑、可审计、可重复导出 |
| 数据主对象 | 继续使用 PosterRecord |
已具备工作区、版本和任务字段,避免新建重复项目表 |
| 任务系统 | 继续使用 GenerationTask + BaoDan Celery |
不重复建设队列和状态系统 |
| 首期导出 | PNG、JPG、PDF、项目 JSON | 覆盖朋友圈、私聊、打印和继续编辑 |
三、当前基线与必须修复的问题
3.1 已有能力
| 能力 | 现状 | 处理策略 |
|---|---|---|
| 计划书 PDF 上传 | 已实现真实 multipart 上传 | 保留并迁移到项目素材模型 |
| PDF 基础安全检查 | 已检查大小、魔数、加密和页数 | 保留并扩展到所有项目素材 |
| 异步解析 | 已接入 Celery 和任务状态 | 保留,统一为项目级解析任务 |
| 人工修正解析结果 | 前端已有表单 | 重构为事实表和来源审计 |
| AI 文案 | 已支持模板/AI 双模式 | 保留,限制只能引用已确认事实 |
| AI 图片 | 已调用图片模型 | 改为“视觉素材生成”,不直接生成带字成品 |
| 工作区恢复 | 已支持 URL 恢复部分状态 | 扩展为完整项目恢复 |
| 统一任务中心 | 已有 GenerationTask |
增加海报细分操作类型和任务快照 |
| 海报历史 | 已有分页、预览和下载 | 重构为项目历史和导出物列表 |
| 后台模板和模型设置 | 已使用数据库配置 | 增加版本号和任务提交时快照 |
3.2 P0 阻断问题
| 编号 | 问题 | 影响 | 修复阶段 |
|---|---|---|---|
| POSTER2-P0-01 | Worker 保存到 outputs/posters,下载接口只允许 uploads/posters |
生成成功仍可能无法预览或下载 | Phase 0 |
| POSTER2-P0-02 | 用户不能上传产品小册子 | 新产品、临时资料无法开始创作 | Phase 2 |
| POSTER2-P0-03 | confirmedData 缺少后端 Schema 和业务校验 |
错误保险数字可进入生成 | Phase 2 |
| POSTER2-P0-04 | 生成结果不可编辑 | 无法满足修正文案、版式和图片要求 | Phase 4 |
| POSTER2-P0-05 | 只有 PNG 导出 | 无法满足打印、图片质量和继续编辑 | Phase 5 |
3.3 P1 主要问题
| 编号 | 问题 | 影响 | 修复阶段 |
|---|---|---|---|
| POSTER2-P1-01 | AI 图片仍受固定背景模板思维支配 | 与客户、产品和场景的语义匹配不足 | Phase 3 |
| POSTER2-P1-02 | 前后端尺寸值不一致 | 横版、方图可能回退为竖版 | Phase 0 |
| POSTER2-P1-03 | 生成失败时工作区和任务状态可能不一致 | 页面可能永久停留在生成中 | Phase 0 |
| POSTER2-P1-04 | 参考图以 URL/字符串传递 | 无真实上传、权限和生命周期管理 | Phase 2 |
| POSTER2-P1-05 | 生成前绿色核对项不是实际校验 | 制造虚假合规感 | Phase 2 |
| POSTER2-P1-06 | 任务中心和历史记录职责重叠 | 用户无法区分“运行任务”和“可继续编辑项目” | Phase 6 |
| POSTER2-P1-07 | 后台配置没有提交时版本快照 | 无法证明成品使用了哪一版配置 | Phase 1、6 |
| POSTER2-P1-08 | 重新生成会覆盖用户心智中的当前结果 | 缺少候选方案和版本回退 | Phase 3、4 |
四、目标产品流程与信息架构
4.1 页面结构
/poster
├── 新建项目
├── 最近项目
└── 运行中的任务摘要
/poster/:projectId
├── 1. 项目资料
├── 2. 数据校验
├── 3. 创意方案
├── 4. 画布编辑
└── 5. 导出发布
/poster/:projectId/editor
└── 全屏画布编辑器
/poster/history
├── 进行中
├── 已完成
├── 已归档
└── 项目版本 / 导出物
/tasks?artifact_type=poster
└── 只展示解析、AI 生成、合成、导出等运行任务
4.2 五阶段业务流程
阶段 1:项目资料
用户可以任选一种产品资料来源:
- 从后台已审核产品库选择;
- 上传本次使用的产品小册子 PDF;
- 选择后台产品后,再上传补充小册子覆盖本次项目。
本阶段素材区域包括:
- 客户计划书 PDF:必需;
- 产品小册子 PDF:选择后台产品时可选,否则必需;
- 参考图片:可选,最多 6 张;
- Logo/品牌素材:默认从后台保司配置读取,可临时覆盖;
- PDF 密码:仅用于本次解密,不落库。
每个素材显示:
- 原始文件名;
- 文件类型和大小;
- 页数或图片尺寸;
- 上传时间;
- 解析状态;
- 来源:后台库 / 用户上传 / AI 生成;
- 替换、删除和重新解析操作。
阶段 2:数据校验
本阶段使用三个标签页:
| 标签页 | 内容 | 目的 |
|---|---|---|
| 数据底表 | 规范化字段、解析值、确认值、单位 | 集中编辑事实 |
| 来源审计 | 文件、页码、原文片段、置信度 | 证明数据来自哪里 |
| QA 校验 | 错误、警告、通过项 | 决定是否允许生成 |
状态规则:
unreviewed → passed
→ warning → accepted
→ error → fixed → passed
- 存在
error:禁止进入创意方案; - 存在
warning:用户必须逐项接受或修正; - 所有必填事实
passed/accepted:记录确认人和时间,允许生成; - 源文件替换或重新解析:原确认版本失效,必须重新校验。
阶段 3:创意方案
用户填写或选择视觉简报:
- 使用场景:朋友圈、客户私聊、讲座邀请、产品提案、长图说明;
- 目标客群:年龄、家庭阶段、职业、关注点;
- 核心主题:保障、增值、传承、教育、退休等;
- 情绪方向:稳健、温暖、高端、现代、自然;
- 视觉主体:人物、家庭、住宅、城市、自然、抽象金融意象;
- 摄影/插画风格;
- 品牌颜色;
- 禁用元素;
- 参考图片;
- 输出尺寸和画布类型。
生成过程:
- 系统从已确认事实生成受约束文案;
- 系统生成 2~4 个不含文字、Logo 和数字的视觉候选;
- 候选图展示生成理由、风格标签和使用的简报;
- 用户选中一个候选,或只重新生成某个候选;
- 系统使用版式预设生成初始画布 JSON。
阶段 4:画布编辑
全屏工作台布局:
┌──────────────── 顶部工具栏 ────────────────┐
│ 返回 / 保存状态 / 撤销 / 重做 / 缩放 / 预览 / 导出 │
├──────────┬──────────────────────┬───────────┤
│ 页面与素材 │ 可编辑画布 │ 图层与属性 │
│ AI 候选图 │ │ 数据来源 │
│ 品牌素材 │ │ QA 状态 │
└──────────┴──────────────────────┴───────────┘
首期必须支持:
- 文字直接编辑;
- 字体、字号、行高、字间距、颜色、对齐;
- 图片替换、裁剪、缩放、定位;
- 矩形、线条、背景色;
- 数据卡、图标、Logo、免责声明;
- 图层显示、隐藏、锁定、排序;
- 多选、对齐、吸附和安全区;
- 撤销、重做;
- 自动保存;
- 版本历史和恢复;
- 单独重新生成选中的 AI 图片;
- 根据事实数据重新生成文案;
- 事实字段变更后标记关联图层“数据已过期”。
阶段 5:导出发布
导出面板提供:
| 格式 | 用途 | 首期要求 |
|---|---|---|
| PNG | 朋友圈、企微、网页 | 支持 1x/2x,透明背景按画布能力决定 |
| JPG | 体积较小的图片分发 | 可选质量 80/90/100 |
| 打印、客户存档 | 单页海报或多页长图分页 | |
| 项目 JSON | 继续编辑、备份迁移 | 包含画布 Schema 版本,不嵌入密钥和临时 URL |
每个导出物记录:
- 使用的画布版本;
- 使用的事实确认版本;
- 配置快照版本;
- 文件格式、尺寸、大小和 MIME;
- 导出人和导出时间;
- 下载次数;
- 是否为正式交付版。
五、总体技术架构
5.1 架构原则
PosterRecord继续作为项目/工作区根对象,不重命名数据库表;GenerationTask继续作为一次异步执行记录;- 文件统一保存到
INSURANCE_STORAGE_ROOT; - 数据库保存对象键,不保存依赖工作目录的绝对路径;
- AI 生成图片与确定性文字排版分离;
- 画布 JSON 是可编辑成品的唯一事实来源;
- PNG/JPG/PDF 是画布某一版本的不可变导出物;
- 所有模型、Prompt、品牌和模板配置在任务提交时生成快照。
5.2 数据流
flowchart LR
U["用户上传 / 后台产品库"] --> A["项目素材"]
A --> P["Celery 解析任务"]
P --> F["事实与来源证据"]
F --> V["规则校验 + 人工确认"]
V -->|通过| B["创意简报"]
B --> C["文案生成"]
B --> I["AI 视觉候选"]
C --> K["初始画布构建"]
I --> K
K --> E["Fabric.js 编辑器"]
E --> S["画布版本保存"]
S --> X["PNG / JPG / PDF / 项目文件"]
X --> H["项目历史和后台审计"]
5.3 AI 与画布职责边界
| 内容 | AI 图片模型 | LLM | 画布引擎 |
|---|---|---|---|
| 人物、家庭、建筑、自然场景 | ✅ | 组合 | |
| 装饰纹理、氛围背景 | ✅ | 组合 | |
| 标题和正文文案 | ✅ | ✅ 可编辑 | |
| 保费、保额、缴费期等数字 | 只能引用事实 | ✅ 可编辑 | |
| 图表 | 生成结构建议 | ✅ 确定性绘制 | |
| Logo | 禁止生成 | ✅ 使用真实素材 | |
| 免责声明 | 禁止生成 | 规则选择 | ✅ 固定图层 |
六、数据库与迁移设计
6.1 迁移策略
- 新迁移编号从
migrate_026.py开始; - 不删除现有字段和表;
- 旧
PosterRecord自动视为一个项目; - 旧 PNG 作为历史导出物回填;
- 旧
PosterCaseUpload保留兼容读取; - 新流程稳定两个版本后再评估旧字段清理;
- 所有迁移必须幂等并支持 PostgreSQL/MySQL 的现有兼容策略。
6.2 扩展 poster_records
继续作为海报项目根对象,新增字段:
| 字段 | 类型 | 说明 |
|---|---|---|
validation_status |
VARCHAR(20) | pending/running/blocked/warning/passed |
validation_summary_json |
TEXT | 错误、警告、通过数量和确认版本 |
creative_brief_json |
TEXT | 用户创意简报 |
selected_visual_asset_id |
BIGINT | 选中的 AI 视觉素材 |
canvas_schema_version |
VARCHAR(20) | 画布 Schema 版本 |
current_canvas_version |
INTEGER | 当前画布版本号 |
config_snapshot_json |
TEXT | 模型、Prompt、模板、品牌配置快照 |
fact_revision |
INTEGER | 事实数据版本 |
confirmed_fact_revision |
INTEGER | 最近确认的事实版本 |
updated_at |
TIMESTAMP | 项目最后更新时间 |
保留但调整语义:
template_id:从固定背景模板改为版式/品牌预设;copy_content:当前文案图层内容;export_url/export_format:兼容旧接口,指向最近正式导出物;workflow_step:改用sources/validation/creative/editor/export;draft_revision/generated_revision:继续用于乐观锁和生成版本判断。
6.3 新建 poster_project_assets
用途:统一保存本项目所有输入、AI 候选和品牌素材。
| 字段 | 类型 | 约束/说明 |
|---|---|---|
id |
BIGINT | 主键 |
project_id |
BIGINT | INDEX,关联 poster_records.id |
user_id |
VARCHAR(64) | INDEX,所有权校验 |
asset_type |
VARCHAR(30) | case_pdf/product_manual/reference/brand/generated_visual |
source_type |
VARCHAR(20) | upload/library/generated |
source_ref_id |
VARCHAR(64) | 后台产品或保司素材 ID |
file_key |
VARCHAR(500) | storage 对象键 |
original_name |
VARCHAR(200) | 原始文件名 |
mime_type |
VARCHAR(80) | MIME |
file_size |
BIGINT | 字节 |
sha256 |
VARCHAR(64) | 去重和审计 |
page_count |
INTEGER | PDF 页数 |
width / height |
INTEGER | 图片尺寸 |
parse_status |
VARCHAR(20) | pending/queued/parsing/parsed/failed |
parse_task_id |
VARCHAR(36) | 关联 GenerationTask |
metadata_json |
TEXT | EXIF 清理、候选理由、模型信息等 |
created_at |
TIMESTAMP | 创建时间 |
deleted_at |
TIMESTAMP | 软删除 |
索引:
INDEX(project_id, asset_type)INDEX(user_id, created_at)INDEX(sha256)
6.4 新建 poster_fact_items
用途:保存结构化事实、来源证据和人工确认结果。
| 字段 | 类型 | 说明 |
|---|---|---|
id |
BIGINT | 主键 |
project_id |
BIGINT | INDEX |
fact_revision |
INTEGER | 所属事实版本 |
fact_path |
VARCHAR(120) | 如 customer.age、policy.annual_premium |
label |
VARCHAR(100) | 用户可读字段名 |
value_json |
TEXT | 系统解析值 |
confirmed_value_json |
TEXT | 人工确认值 |
unit |
VARCHAR(30) | USD、HKD、年、岁等 |
source_asset_id |
BIGINT | 来源素材 |
source_page |
INTEGER | PDF 页码 |
source_quote |
TEXT | 原文片段,限制长度 |
confidence |
DECIMAL(5,4) | 解析置信度 |
validation_status |
VARCHAR(20) | unreviewed/passed/warning/error/accepted |
validation_code |
VARCHAR(50) | 结构化规则码 |
validation_message |
VARCHAR(500) | 用户可读说明 |
confirmed_by |
VARCHAR(64) | 确认人 |
confirmed_at |
TIMESTAMP | 确认时间 |
created_at / updated_at |
TIMESTAMP | 时间字段 |
唯一约束:
UNIQUE(project_id, fact_revision, fact_path)
6.5 新建 poster_canvas_versions
用途:保存可编辑画布版本,支持自动保存、版本恢复和审计。
| 字段 | 类型 | 说明 |
|---|---|---|
id |
BIGINT | 主键 |
project_id |
BIGINT | INDEX |
version |
INTEGER | 项目内递增版本 |
canvas_schema_version |
VARCHAR(20) | 如 1.0 |
canvas_json |
TEXT | Fabric 画布文档 |
preview_file_key |
VARCHAR(500) | 低分辨率预览 |
fact_revision |
INTEGER | 使用的事实版本 |
config_snapshot_json |
TEXT | 使用的配置快照 |
source_task_id |
VARCHAR(36) | 初始合成任务 ID |
change_summary |
VARCHAR(500) | 自动保存/人工保存/恢复等 |
created_by |
VARCHAR(64) | 操作人 |
created_at |
TIMESTAMP | 创建时间 |
唯一约束:
UNIQUE(project_id, version)
版本策略:
- 自动保存更新当前草稿,不为每次按键创建永久版本;
- 用户点击“保存版本”、生成初稿、导出正式版时创建永久版本;
- 每个项目默认保留最近 30 个永久版本;
- 被导出物引用的版本不得自动清理。
6.6 新建 poster_export_artifacts
用途:保存同一画布版本的多格式导出物。
| 字段 | 类型 | 说明 |
|---|---|---|
id |
BIGINT | 主键 |
project_id |
BIGINT | INDEX |
canvas_version_id |
BIGINT | 关联画布版本 |
task_id |
VARCHAR(36) | 导出任务,可为空 |
format |
VARCHAR(20) | png/jpg/pdf/project_json |
file_key |
VARCHAR(500) | storage 对象键 |
mime_type |
VARCHAR(80) | MIME |
width / height |
INTEGER | 像素尺寸 |
dpi |
INTEGER | PDF/打印参数 |
file_size |
BIGINT | 文件大小 |
status |
VARCHAR(20) | queued/ready/failed |
is_official |
BOOLEAN | 是否正式交付版本 |
download_count |
INTEGER | 下载次数 |
created_by |
VARCHAR(64) | 导出人 |
created_at |
TIMESTAMP | 创建时间 |
6.7 扩展 insurance_generation_tasks
修改:
operation从VARCHAR(10)扩展到VARCHAR(30);- 支持以下操作值:
parse_sourcesvalidate_factsgenerate_copygenerate_visualscompose_canvasexport_artifact
input_snapshot_json必须包含配置版本和输入修订号;output_json保存生成素材 ID、画布版本或导出物 ID;- 失败时同步更新项目或素材状态;
- 增加结构化
error_code,禁止只保存异常字符串。
6.8 旧数据回填
迁移 026 完成:
- 为现有
poster_records填充:validation_status='passed',并标记legacy=true;canvas_schema_version=NULL;current_canvas_version=0。
- 将现有
case_upload_id对应文件注册为case_pdf素材; - 将现有
reference_image_used注册为参考素材;文件不存在时只记录迁移警告; - 将现有
export_url注册为poster_export_artifacts; - 旧项目仍可预览和下载,但只有点击“转换为可编辑项目”后才生成画布;
- 回填过程输出成功、跳过、文件缺失和异常数量。
七、后端 API 设计
7.1 兼容策略
- 保留现有
/poster/products、/poster/records、/poster/download/{id}; - 新页面优先调用工作区接口;
- 旧生成向导通过功能开关保留一个发布周期;
- 新接口统一返回:
{
"code": 0,
"message": "success",
"data": {}
}
7.2 项目接口
| 方法 | URL | 用途 |
|---|---|---|
| POST | /insurance/poster/workspaces |
创建空项目 |
| GET | /insurance/poster/workspaces |
查询本人项目 |
| GET | /insurance/poster/workspaces/{id} |
获取完整项目摘要 |
| PATCH | /insurance/poster/workspaces/{id}/draft |
自动保存步骤、简报和草稿 |
| PUT | /insurance/poster/workspaces/{id}/rename |
重命名 |
| POST | /insurance/poster/workspaces/{id}/copy |
复制项目 |
| PUT | /insurance/poster/workspaces/{id}/archive |
归档 |
| PUT | /insurance/poster/workspaces/{id}/unarchive |
取消归档 |
创建项目请求示例:
{
"title": "宏挚传承保障计划|客户 A",
"useMaskedData": true
}
7.3 素材接口
| 方法 | URL | 用途 |
|---|---|---|
| POST | /poster/workspaces/{id}/assets |
上传 PDF/图片 |
| GET | /poster/workspaces/{id}/assets |
素材列表 |
| DELETE | /poster/workspaces/{id}/assets/{assetId} |
软删除素材 |
| POST | /poster/workspaces/{id}/products/attach |
关联后台产品 |
| POST | /poster/workspaces/{id}/parse |
投递项目解析任务 |
| POST | /poster/workspaces/{id}/assets/{assetId}/retry |
重试单个素材解析 |
上传表单字段:
| 字段 | 必填 | 说明 |
|---|---|---|
assetType |
是 | case_pdf/product_manual/reference/brand |
file |
是 | 文件 |
password |
否 | PDF 密码,不保存 |
replaceAssetId |
否 | 替换指定素材 |
7.4 事实与校验接口
| 方法 | URL | 用途 |
|---|---|---|
| GET | /poster/workspaces/{id}/facts |
获取当前事实版本 |
| PATCH | /poster/workspaces/{id}/facts/{factId} |
修改单个事实 |
| PUT | /poster/workspaces/{id}/facts |
批量保存事实 |
| POST | /poster/workspaces/{id}/validate |
执行服务端校验 |
| POST | /poster/workspaces/{id}/warnings/{factId}/accept |
接受警告 |
| POST | /poster/workspaces/{id}/validation/confirm |
确认当前事实版本 |
| GET | /poster/workspaces/{id}/source-audit |
获取来源审计视图 |
确认接口必须检查:
- 请求事实版本等于项目当前版本;
- 无
error; - 所有必填事实存在来源或有人工补录原因;
- 所有
warning已处理; - 请求用户拥有项目;
- 确认动作写审计日志。
7.5 创意与 AI 接口
| 方法 | URL | 用途 |
|---|---|---|
| PUT | /poster/workspaces/{id}/creative-brief |
保存创意简报 |
| POST | /poster/workspaces/{id}/copy/generate |
生成受约束文案 |
| POST | /poster/workspaces/{id}/visuals/generate |
生成 2~4 个视觉候选 |
| GET | /poster/workspaces/{id}/visuals |
获取候选素材 |
| POST | /poster/workspaces/{id}/visuals/{assetId}/select |
选中候选 |
| POST | /poster/workspaces/{id}/visuals/{assetId}/regenerate |
重新生成指定候选 |
| POST | /poster/workspaces/{id}/canvas/compose |
生成初始画布 |
所有生成接口必须:
- 校验
validation_status='passed'; - 固化事实版本、配置版本和画布输入版本;
- 使用幂等键;
- 3 秒内返回任务 ID;
- 不等待图片模型完成;
- 可通过统一任务接口恢复状态。
7.6 画布接口
| 方法 | URL | 用途 |
|---|---|---|
| GET | /poster/workspaces/{id}/canvas |
获取当前画布 |
| PATCH | /poster/workspaces/{id}/canvas |
自动保存草稿,带乐观锁 |
| POST | /poster/workspaces/{id}/canvas/versions |
创建永久版本 |
| GET | /poster/workspaces/{id}/canvas/versions |
版本列表 |
| POST | /poster/workspaces/{id}/canvas/versions/{version}/restore |
恢复版本 |
| POST | /poster/workspaces/{id}/canvas/preview |
上传低清预览 |
自动保存请求:
{
"expectedRevision": 12,
"canvasSchemaVersion": "1.0",
"canvas": {
"width": 1080,
"height": 1920,
"objects": []
}
}
版本冲突返回明确错误和服务器最新版本,不静默覆盖。
7.7 导出接口
| 方法 | URL | 用途 |
|---|---|---|
| POST | /poster/workspaces/{id}/exports |
创建导出物记录或导出任务 |
| GET | /poster/workspaces/{id}/exports |
导出物列表 |
| GET | /poster/exports/{artifactId}/download |
鉴权下载 |
| PUT | /poster/exports/{artifactId}/official |
标记正式交付版本 |
| DELETE | /poster/exports/{artifactId} |
删除非正式导出物 |
首期采用浏览器高分辨率画布导出,再通过鉴权接口上传成品:
- 前端加载已保存画布版本;
- 在隐藏高分辨率画布渲染;
- PNG/JPG 使用
toBlob; - PDF 将高分辨率画布按页面尺寸嵌入 PDF;
- 上传到后端;
- 后端校验项目所有权、格式、MIME、大小和画布版本;
- 文件写入统一 storage;
- 创建不可变导出物记录。
后续若需要服务端批量导出,再增加独立渲染 Worker,不在首期重复建设。
八、后端模块改造
8.1 建议目录
api/insurance/poster/
├── routes.py # 兼容旧接口
├── service.py # 兼容旧业务
├── project_routes.py # 项目、素材、画布、导出
├── project_service.py # 项目聚合服务
├── asset_service.py # 文件与素材生命周期
├── extraction_service.py # 多资料解析编排
├── fact_schema.py # Pydantic/Schema
├── validation_service.py # 事实与业务规则校验
├── source_audit_service.py # 来源证据
├── creative_service.py # 创意简报和文案约束
├── visual_generator.py # AI 视觉候选
├── canvas_builder.py # 确定性初始画布 JSON
├── export_service.py # 导出物接收、校验和存储
├── storage_service.py # 项目文件路径安全封装
└── schemas/
├── canvas_v1.py
├── creative_brief.py
└── insurance_facts.py
说明:
- 不一次性拆分现有所有函数;
- 旧
routes.py/service.py保持兼容; - 新逻辑放独立文件;
- 迁移完成后逐个旧接口转调新服务;
- 不修改 BaoDan 核心模块。
8.2 解析编排
解析任务输入:
- 项目 ID;
- case PDF 素材 ID;
- product manual 素材 ID 或后台产品快照;
- 当前事实版本;
- 模型配置快照。
解析任务输出:
- 标准事实列表;
- 每个事实的来源文件、页码、原文和置信度;
- 未识别字段;
- 冲突字段;
- 解析错误。
PDF 文本必须作为“不可信数据”传给模型,防止文档中的提示注入覆盖系统指令。
8.3 事实 Schema
首期核心事实:
customer.age
customer.gender
customer.smoking_status
policy.product_name
policy.company_name
policy.currency
policy.sum_assured
policy.annual_premium
policy.payment_period
policy.coverage_period
policy.total_basic_premium
policy.cash_value.*
policy.death_benefit.*
product.features[]
product.exclusions[]
product.disclaimer
不同险种通过 Schema 配置决定必填字段,不强行让所有险种共用完全相同的字段。
8.4 校验规则
| 规则码 | 类型 | 规则 |
|---|---|---|
| REQUIRED_FIELD_MISSING | error | 必填字段缺失 |
| SOURCE_EVIDENCE_MISSING | error | 关键数字无文件、页码或人工补录说明 |
| PRODUCT_NAME_CONFLICT | error | 计划书与产品册产品名无法匹配 |
| CURRENCY_CONFLICT | error | 同一关键金额存在不同币种 |
| PAYMENT_PERIOD_CONFLICT | error | 缴费期在资料间冲突 |
| PREMIUM_OUT_OF_RANGE | warning/error | 保费超出合理数值范围 |
| AGE_OUT_OF_RANGE | error | 年龄不在 0~120 |
| LOW_CONFIDENCE | warning | 置信度低于阈值 |
| MANUAL_OVERRIDE | warning | 用户值与解析值不同 |
| DISCLAIMER_MISSING | error | 无可用免责声明 |
| FACT_REVISION_STALE | error | 校验/生成使用过期事实版本 |
业务规则由后台配置阈值,但规则代码和安全下限保留在服务端。
8.5 配置快照
每次 generate_copy、generate_visuals、compose_canvas、export_artifact 提交时保存:
- 文案模型 provider/model;
- 图片模型 provider/model;
- Prompt 模板 ID、版本和内容哈希;
- 版式预设 ID、版本和内容哈希;
- 保司品牌配置;
- Logo 素材 ID 和哈希;
- 配色方案;
- 免责声明版本;
- 校验规则版本;
- fallback 是否允许;
- 提交时间。
任务执行期间后台设置变化,不影响已提交任务。
九、前端重构计划
9.1 路由
/poster PosterHomePage
/poster/:projectId PosterProjectPage
/poster/:projectId/editor PosterEditorPage
/poster/history PosterProjectsPage
/tasks TasksPage(继续复用)
9.2 页面和组件
frontend/src/
├── pages/
│ ├── PosterHomePage.vue
│ ├── PosterProjectPage.vue
│ ├── PosterEditorPage.vue
│ └── PosterProjectsPage.vue
├── components/poster/
│ ├── sources/
│ │ ├── PosterSourceStep.vue
│ │ ├── ProductSourcePicker.vue
│ │ ├── ProjectAssetUploader.vue
│ │ └── AssetStatusCard.vue
│ ├── validation/
│ │ ├── PosterValidationStep.vue
│ │ ├── FactTable.vue
│ │ ├── SourceAuditPanel.vue
│ │ └── ValidationIssues.vue
│ ├── creative/
│ │ ├── PosterCreativeStep.vue
│ │ ├── CreativeBriefForm.vue
│ │ ├── VisualCandidateGrid.vue
│ │ └── CopyReviewPanel.vue
│ ├── editor/
│ │ ├── PosterCanvas.vue
│ │ ├── EditorToolbar.vue
│ │ ├── AssetLibraryPanel.vue
│ │ ├── LayerPanel.vue
│ │ ├── PropertyPanel.vue
│ │ ├── DataBindingPanel.vue
│ │ └── VersionHistoryDrawer.vue
│ └── export/
│ ├── PosterExportStep.vue
│ ├── ExportSettings.vue
│ └── ExportArtifactList.vue
├── composables/
│ ├── usePosterProject.ts
│ ├── usePosterCanvas.ts
│ ├── usePosterAutosave.ts
│ ├── usePosterTasks.ts
│ └── useUndoRedo.ts
├── types/
│ ├── poster-project.ts
│ ├── poster-canvas.ts
│ └── poster-validation.ts
└── utils/
└── poster-api.ts
9.3 渐进迁移
- 保留当前
PosterPage.vue和四个PosterStep*组件; - 增加
POSTER_WORKBENCH_V2_ENABLED; - 测试账号进入 V2;
- V2 稳定后
/poster指向新首页; - 旧项目继续用旧详情查看;
- 提供“转换为可编辑项目”;
- 一个发布周期后移除旧创建入口;
- 最后再删除确定不再引用的旧组件。
9.4 画布文档 Schema
画布对象除 Fabric 原生字段外,增加业务元数据:
{
"schemaVersion": "1.0",
"width": 1080,
"height": 1920,
"layoutPresetId": 12,
"objects": [
{
"id": "headline",
"type": "textbox",
"role": "headline",
"text": "真正的安全感,是未雨绸缪的从容",
"dataBinding": null,
"locked": false
},
{
"id": "premium-value",
"type": "textbox",
"role": "fact",
"dataBinding": {
"factPath": "policy.annual_premium",
"factRevision": 3,
"format": "currency"
}
}
]
}
业务要求:
- 每个对象必须有稳定
id; - 关键数字图层必须有
dataBinding; - Logo、免责声明和事实图层可配置最小字号和锁定规则;
- 加载时检测事实版本是否过期;
- 画布 JSON 不保存 Blob URL;
- 图片对象只保存后端素材 ID 和鉴权加载地址。
9.5 自动保存
- 用户停止操作 1.5 秒后保存;
- 最长每 10 秒保存一次;
- 路由离开前刷新未提交保存;
- 使用
expectedRevision乐观锁; - 网络失败保留本地待提交队列;
- 恢复网络后重试;
- 版本冲突不自动覆盖,显示“使用服务器版本 / 另存副本”;
- 页面顶部始终显示:保存中、已保存、离线、保存失败。
9.6 撤销与版本
- 前端撤销栈:最近 100 次操作;
- 重载页面后撤销栈不保证保留;
- 永久版本:生成初稿、用户手动保存、正式导出、恢复旧版时创建;
- 恢复旧版本会创建新版本,不重写历史;
- AI 局部重生成前自动创建版本。
9.7 响应式和可访问性
桌面端:
- 完整三栏编辑器;
- 快捷键:
Ctrl/Cmd+Z撤销;Ctrl/Cmd+Shift+Z重做;Ctrl/Cmd+S保存版本;Delete删除;- 方向键微调;
Shift+方向键大步移动。
手机端:
- 五阶段流程可查看;
- 支持上传、校验、选择视觉方案;
- 编辑器进入简化模式,只允许改字、换图、切换预设;
- 提示“精细排版请使用桌面端”,但不阻断查看和导出。
无障碍要求:
- 所有按钮有文字或
aria-label; - 画布对象在图层面板中可用键盘选择;
- 焦点样式可见;
- 状态变化通过
aria-live播报; - 错误不只使用颜色表达;
- 文字与背景对比度满足 WCAG AA;
- 放大到 200% 时校验和导出流程可操作。
十、AI 生成方案
10.1 文案生成
输入仅包括:
- 已确认事实;
- 产品卖点;
- 使用场景;
- 目标客群;
- 品牌语气;
- 文案长度约束;
- 免责声明。
输出使用结构化 Schema:
{
"headline": "",
"subheadline": "",
"sellingPoints": [
{
"title": "",
"description": "",
"factRefs": ["policy.payment_period"]
}
],
"cta": "",
"disclaimer": "",
"unsupportedClaims": []
}
规则:
- 关键数字必须附
factRefs; - 找不到事实时不得编造;
unsupportedClaims非空时阻断进入正式画布;- 文案更改事实数字时立即标记错误;
- AI 原始响应保留审计,但前端默认展示规范化结果。
10.2 视觉生成
Prompt 只描述:
- 场景、人物、环境和情绪;
- 画面构图和安全留白;
- 摄影/插画风格;
- 品牌颜色倾向;
- 输出比例;
- 禁止元素。
必须加入负向约束:
不要生成任何文字、字母、数字、Logo、品牌标识、表格、图表、水印;
不要生成可被误认为真实保险合同或官方证明的文件;
为后续文字排版保留明确安全区域。
候选数默认 3,允许管理员配置 2~4。每个候选保存:
- 完整 Prompt;
- provider/model;
- seed 或供应商返回标识;
- 参考素材;
- 配置快照;
- 生成耗时和费用元数据;
- 失败代码;
- 是否 fallback。
10.3 初始画布构建
canvas_builder.py 根据:
- 输出尺寸;
- 版式预设;
- 已确认文案;
- 已确认事实;
- 选中视觉素材;
- Logo 和品牌配置;
- 免责声明;
生成确定性的画布 JSON。相同输入和版式预设应得到相同的元素位置,避免每次重新生成版式随机漂移。
10.4 局部重新生成
| 操作 | 影响范围 |
|---|---|
| 重新生成视觉图 | 只创建新的图片素材,不改文字和数据 |
| 重新生成标题 | 只更新标题候选,用户确认后替换 |
| 重新生成卖点 | 只更新选中卖点卡 |
| 更换版式预设 | 重排图层,原画布自动保存为版本 |
| 事实数据变更 | 标记绑定图层过期,不自动覆盖人工排版 |
十一、后台配置与同步
11.1 后台配置分类
| 配置 | 后台来源 | 前端用途 |
|---|---|---|
| 文案模型 | SystemSetting |
AI 文案 |
| 图片模型 | SystemSetting |
AI 视觉素材 |
| Prompt 模板 | 现有设置扩展 | 文案、视觉和 QA |
| 海报模板 | PosterTemplate |
改为版式/品牌预设 |
| 文案模板 | PosterCopyTemplate |
快速文案和降级路径 |
| 保司品牌 | PptCompany + Logo 表 |
Logo、品牌色、名称 |
| 产品资料 | PptProduct |
后台审核产品快捷选择 |
| 校验规则 | 系统设置/规则文件 | 字段、阈值和阻断规则 |
| 导出默认值 | 系统设置 | 默认格式、质量和 DPI |
11.2 PosterTemplate 重解释
现有模板不再表示“一张成品背景图”,而表示:
- 版式类别;
- 安全区;
- 文字层级;
- 数据卡样式;
- Logo 和免责声明位置;
- 推荐场景;
- 品牌色;
- AI 视觉 Prompt 片段;
- 负向 Prompt;
- 画布比例。
旧 reference_image 只作为风格参考,不直接作为最终背景。
11.3 配置版本策略
- 每次管理员保存配置,版本号加一;
- 项目页显示“当前项目使用 v3,后台最新 v4”;
- 用户选择:
- 继续使用项目快照;
- 同步最新配置;
- 同步最新配置只更新简报和预设,不静默覆盖画布;
- 新任务永远使用提交时快照;
- 历史项目可查看当时配置,但不显示密钥。
11.4 任务中心和历史记录职责
任务中心:
- 展示正在运行或最近完成的操作;
- 解析、生成视觉、合成、导出各是一条任务;
- 支持取消可取消任务、重试和查看错误;
- 完成后跳转对应项目。
项目历史:
- 展示可继续编辑的项目;
- 显示资料、校验状态、当前画布、版本和导出物;
- 支持复制、归档、恢复、继续编辑;
- 不重复承担任务进度明细。
十二、安全、隐私与合规
12.1 文件安全
- PDF:扩展名、MIME、魔数、大小、页数、加密、损坏检查;
- 图片:仅允许 PNG/JPG/WebP,使用 Pillow 解码并重编码;
- 删除 EXIF 和地理位置;
- 默认限制:
- 单个 PDF 50 MB;
- 单个图片 15 MB;
- 单项目 PDF 合计 100 MB;
- 参考图最多 6 张;
- 使用 SHA-256 审计;
- 所有下载通过鉴权接口;
- 路径校验使用
os.path.commonpath; - API 和 Worker 共享同一持久化 volume。
12.2 权限
- 普通用户只能访问本人项目、素材、任务、版本和导出物;
- 主管是否可查看团队项目复用现有数据权限;
- 管理员默认只能看配置,不自动获得客户原始 PDF 权限;
- 需要查看业务数据时必须经过现有角色权限和审计;
- 素材 ID、画布 ID、导出物 ID 均执行所有权校验。
12.3 隐私
- PDF 密码不落库、不写日志;
- Prompt 默认脱敏;
- 模型请求根据
useMaskedData替换客户和产品敏感名称; - 日志不保存完整保费、保额和客户姓名;
- 参考人物照片上传前提示用户确认授权;
- 数据保留期限到期后删除源文件、临时图和未引用候选;
- 正式导出物和审计记录按后台策略保留。
12.4 合规
- 生成前强制校验;
- AI 文案只能引用已确认事实;
- Logo 使用真实素材,不允许图片模型生成;
- 免责声明是受保护图层;
- 正式导出前再次检查事实版本;
- 事实已变化时禁止导出旧画布为“正式版”;
- 每份正式导出物关联确认人、确认时间和配置快照;
- fallback 成品必须明确标记生成方式,不伪装成 AI 成功。
十三、分阶段实施计划
Phase 0:紧急闭环修复与回归基线
预计工作量:1.5 人日
目标:先修复当前功能的确定性故障,建立后续重构基线。
任务:
- POSTER2-0001 修复输出目录和下载白名单不一致;
- POSTER2-0002 抽取统一
PosterStorageService; - POSTER2-0003 修复前后端尺寸枚举和映射;
- POSTER2-0004 生成异常时同步
PosterRecord和GenerationTask; - POSTER2-0005 轮询连续失败时显示可恢复错误;
- POSTER2-0006 增加竖版、横版、方图生成回归测试;
- POSTER2-0007 增加“生成成功后可预览和下载”集成测试;
- POSTER2-0008 准备脱敏计划书、小册子和预期事实样例;
- POSTER2-0009 记录现有接口和数据库快照。
完成标准:
- 三种尺寸均生成正确方向;
- Worker 生成文件可由 API 下载;
- 容器重启后文件仍存在;
- 生成失败不会永久显示进行中;
- 同一组样例可重复执行。
Phase 1:项目数据模型、迁移和基础 API
预计工作量:2.5 人日
目标:建立项目素材、事实、画布版本和导出物的数据基础。
任务:
- POSTER2-0101 编写
migrate_026.py; - POSTER2-0102 扩展
PosterRecord; - POSTER2-0103 新增四个 SQLAlchemy 模型;
- POSTER2-0104 扩展
GenerationTask.operation; - POSTER2-0105 添加索引和唯一约束;
- POSTER2-0106 实现旧记录回填;
- POSTER2-0107 实现创建空项目 API;
- POSTER2-0108 扩展工作区详情和自动保存;
- POSTER2-0109 实现配置快照服务;
- POSTER2-0110 增加迁移幂等、空库和旧数据测试。
完成标准:
- 空数据库迁移一次成功;
- 迁移重复运行无副作用;
- 旧记录仍可查询和下载;
- 可以在上传前创建项目;
- 项目草稿支持乐观锁;
- 任务可保存大于 10 字符的操作类型。
Phase 2:自由上传、解析、来源审计和校验门
预计工作量:3 人日
目标:用户可上传两类 PDF,且错误数据不能进入生成。
任务:
- POSTER2-0201 实现项目素材上传 API;
- POSTER2-0202 支持计划书和小册子独立上传/替换;
- POSTER2-0203 支持后台产品关联;
- POSTER2-0204 支持参考图片和临时 Logo 上传;
- POSTER2-0205 图片重编码、EXIF 清理和安全限制;
- POSTER2-0206 项目级解析任务;
- POSTER2-0207 标准事实 Schema;
- POSTER2-0208 事实来源文件、页码和原文记录;
- POSTER2-0209 校验规则引擎;
- POSTER2-0210 错误阻断、警告接受和确认接口;
- POSTER2-0211 前端项目资料页;
- POSTER2-0212 前端数据底表、来源审计和 QA;
- POSTER2-0213 替换源文件后确认失效;
- POSTER2-0214 上传、解析和校验自动化测试。
完成标准:
- 不选择后台产品也可上传两份 PDF;
- 每个关键数字可定位到文件和页码;
- 任一错误项存在时无法生成;
- 警告必须显式接受;
- 确认记录包含用户、时间和事实版本;
- 替换资料后旧确认自动失效。
Phase 3:AI 文案、视觉候选和初始画布
预计工作量:3.5 人日
目标:AI 生成与资料语义匹配的视觉素材,而不是固定背景模板成品。
任务:
- POSTER2-0301 定义创意简报 Schema;
- POSTER2-0302 重构文案 Prompt,只允许引用确认事实;
- POSTER2-0303 增加文案结构化输出校验;
- POSTER2-0304 增加 unsupported claim 检查;
- POSTER2-0305 重构图片 Prompt,禁止文字、数字和 Logo;
- POSTER2-0306 生成 2~4 个视觉候选;
- POSTER2-0307 候选图记录 Prompt、模型、参考图和费用元数据;
- POSTER2-0308 支持选择和局部重新生成;
- POSTER2-0309 将
PosterTemplate改造为版式/品牌预设; - POSTER2-0310 实现
canvas_builder.py; - POSTER2-0311 创建初始画布版本;
- POSTER2-0312 前端创意简报和候选选择页面;
- POSTER2-0313 AI 失败、限流和 fallback 契约测试。
完成标准:
- AI 候选图不包含可见文字和伪造 Logo;
- 视觉候选明确对应客户、产品和场景简报;
- 用户可单独重生成一张候选;
- 重新生成图片不改变已确认事实;
- 文案中的数字全部有事实引用;
- 可从选中候选生成初始画布 JSON。
Phase 4:可编辑画布
预计工作量:5.5 人日
目标:生成结果可以在浏览器内进行专业、可恢复编辑。
任务:
- POSTER2-0401 Fabric.js 技术验证:中文字体、长图、序列化和 2x 导出;
- POSTER2-0402 定义 Canvas Schema v1;
- POSTER2-0403 实现画布加载和保存;
- POSTER2-0404 实现文字编辑;
- POSTER2-0405 实现图片替换和裁剪;
- POSTER2-0406 实现基础形状和背景;
- POSTER2-0407 实现数据卡、图标、Logo、免责声明组件;
- POSTER2-0408 实现图层面板;
- POSTER2-0409 实现属性面板;
- POSTER2-0410 实现多选、对齐、吸附和安全区;
- POSTER2-0411 实现撤销、重做和快捷键;
- POSTER2-0412 实现自动保存和离线待提交;
- POSTER2-0413 实现版本创建、列表和恢复;
- POSTER2-0414 实现事实绑定和过期提醒;
- POSTER2-0415 实现局部 AI 图片替换;
- POSTER2-0416 实现桌面/平板布局和手机简化模式;
- POSTER2-0417 画布 Schema、版本冲突和恢复测试。
完成标准:
- 用户可以修改示例海报全部文字;
- 用户可以移动、缩放、替换图片和调整图层;
- 刷新页面后画布恢复;
- 撤销、重做至少覆盖最近 100 次操作;
- 两个标签页同时修改时不会静默覆盖;
- 关键数字图层可追溯到事实;
- 恢复旧版本不会删除新版本。
Phase 5:多格式导出
预计工作量:2.5 人日
目标:输出可管理、可追溯的多格式交付物。
任务:
- POSTER2-0501 高分辨率隐藏画布渲染;
- POSTER2-0502 PNG 1x/2x 导出;
- POSTER2-0503 JPG 质量选项;
- POSTER2-0504 PDF 页面尺寸和分页;
- POSTER2-0505 项目 JSON 导出与导入校验;
- POSTER2-0506 导出物上传、MIME 和所有权校验;
- POSTER2-0507 导出物列表和鉴权下载;
- POSTER2-0508 正式交付版标记;
- POSTER2-0509 字体缺失和图片跨域检查;
- POSTER2-0510 各格式视觉快照测试。
完成标准:
- 同一画布可生成 PNG、JPG、PDF 和项目 JSON;
- 四种文件均可重新下载;
- 导出物与画布版本、事实版本和配置快照关联;
- 导出前发现事实过期时禁止标记正式版;
- 图片尺寸、方向和文件 MIME 正确;
- 导入项目 JSON 后版式不明显漂移。
Phase 6:项目历史、任务中心和后台同步
预计工作量:2.5 人日
目标:所有内容与后台形成可恢复、可审计闭环。
任务:
- POSTER2-0601 重构海报历史为项目列表;
- POSTER2-0602 增加项目继续编辑、复制、归档和恢复;
- POSTER2-0603 项目详情展示素材、校验、版本和导出物;
- POSTER2-0604 任务中心展示细分操作;
- POSTER2-0605 任务完成跳转项目;
- POSTER2-0606 后台模板增加版式 Schema 和版本;
- POSTER2-0607 后台 Prompt、品牌和校验规则版本化;
- POSTER2-0608 前端配置版本差异提示;
- POSTER2-0609 同步最新配置但不覆盖画布;
- POSTER2-0610 旧项目“转换为可编辑项目”;
- POSTER2-0611 数据权限和审计日志测试。
完成标准:
- 用户离开页面后任务继续运行;
- 从历史项目可以恢复到上次步骤;
- 任务中心不再承担项目历史职责;
- 后台配置变化不会改变已提交任务;
- 用户可以看见项目配置版本与最新版本差异;
- 普通用户不能访问他人项目和导出物。
Phase 7:安全、性能、灰度和上线
预计工作量:3.5 人日
目标:达到生产上线标准。
任务:
- POSTER2-0701 上传安全和资源限制测试;
- POSTER2-0702 PDF Prompt 注入测试;
- POSTER2-0703 跨用户访问测试;
- POSTER2-0704 Prompt、日志和错误脱敏;
- POSTER2-0705 数据清理和保留策略;
- POSTER2-0706 项目、任务、存储、模型 readiness;
- POSTER2-0707 关键指标和结构化日志;
- POSTER2-0708 前端性能和大画布测试;
- POSTER2-0709 无障碍和键盘流程测试;
- POSTER2-0710 迁移演练;
- POSTER2-0711 灰度开关和回滚演练;
- POSTER2-0712 更新需求、API、测试、部署和变更日志;
- POSTER2-0713 业务方使用真实脱敏案例验收。
完成标准:
- P0/P1 自动化用例全部通过;
- 无跨用户数据访问;
- 日志不含 PDF 密码、密钥和完整客户敏感数据;
- 迁移可重复执行;
- 关闭 V2 开关可回到旧流程;
- 旧项目和新项目均可查询;
- 回滚演练成功。
十四、测试计划
14.1 单元测试
后端:
- 文件类型、大小、页数和路径安全;
- 事实 Schema;
- 各险种必填字段;
- 来源证据;
- 数值、币种和缴费期交叉校验;
- warning 接受和 error 阻断;
- 配置快照;
- AI 结构化响应;
- Canvas Schema;
- storage 对象键;
- 旧数据回填;
- 幂等键和任务状态同步。
前端:
- 项目状态恢复;
- 素材上传状态;
- 校验门;
- 创意简报;
- 画布对象序列化;
- 撤销重做;
- 自动保存;
- 乐观锁冲突;
- 导出参数。
建议补充:
- Vitest;
- Vue Test Utils;
- Canvas 相关函数尽量抽成无 DOM 的纯函数。
14.2 API 集成测试
| 场景 | 预期 |
|---|---|
| 只上传计划书,不选产品也不传小册子 | 阻断并提示缺少产品资料 |
| 选择后台产品 + 上传计划书 | 可解析 |
| 上传计划书 + 小册子 | 可解析 |
| 跨用户读取项目 | 404/无权限 |
| 修改事实后未重新确认就生成 | 拒绝 |
| warning 未接受 | 拒绝 |
| 重复点击生成 | 返回同一活跃任务 |
| Worker 失败 | 项目和任务均为 failed |
| 旧项目下载 | 保持可用 |
| 导出不存在的画布版本 | 拒绝 |
14.3 端到端测试
主路径:
创建项目
→ 上传两份 PDF
→ 等待解析
→ 修正低置信度字段
→ 查看来源页码
→ 确认
→ 填写创意简报
→ 生成 3 个视觉候选
→ 选择候选
→ 进入画布
→ 修改标题和图片
→ 保存版本
→ 导出 PNG、JPG、PDF
→ 离开页面
→ 从历史恢复
→ 再次下载
异常路径:
- 加密 PDF 密码错误;
- PDF 损坏;
- 产品名冲突;
- 币种冲突;
- 图片模型超时;
- 文案模型返回非 JSON;
- 上传中断;
- 页面刷新;
- 两个标签页并发编辑;
- storage 暂时不可用;
- 字体加载失败;
- 超长标题;
- 100 个画布对象;
- 800×12000 长图。
14.4 视觉回归
固定三套脱敏基准:
- 高端传承竖版;
- 产品利益长图;
- 朋友圈方图。
对以下内容进行截图差异检查:
- 初始画布;
- 编辑后画布;
- 1x PNG;
- 2x PNG;
- PDF 首屏;
- 恢复版本后的画布。
字体渲染允许小范围像素差异,但不能出现:
- 文字截断;
- 数字错位;
- 图片拉伸;
- Logo 变形;
- 免责声明缺失;
- 横竖版方向错误。
14.5 性能标准
| 指标 | 目标 |
|---|---|
| 创建项目 | P95 < 1 秒 |
| 上传接口返回 | 保存和投递任务后 P95 < 3 秒 |
| 项目详情 | P95 < 1.5 秒 |
| 自动保存 | P95 < 1 秒 |
| 画布首次可操作 | 桌面宽带 < 3 秒,不含大图后台加载 |
| 画布拖拽 | 常见 50 个对象保持接近 60 FPS |
| 导出 1080×1920 PNG | 常见设备 < 10 秒 |
| 任务状态刷新 | 2 秒轮询,错误后指数退避 |
AI 解析和生成耗时不设置绝对秒数 SLA,但必须持续显示状态、允许离开页面并可恢复。
十五、监控与可观测性
15.1 指标
- 项目创建成功率;
- PDF 上传/解析成功率;
- 平均解析耗时;
- 必填字段缺失率;
- 低置信度字段比例;
- 生成前校验阻断率;
- 文案生成成功率;
- 图片生成成功率;
- fallback 使用率;
- 平均每项目候选图数量;
- 画布保存失败率;
- 版本冲突率;
- PNG/JPG/PDF 导出成功率;
- 文件下载失败率;
- 单项目模型费用。
15.2 结构化日志字段
request_id
user_id_masked
project_id
asset_id
task_id
operation
fact_revision
canvas_version
config_version
provider
model
status
error_code
latency_ms
fallback_reason
禁止记录:
- API Key;
- PDF 密码;
- 完整客户姓名;
- 完整身份证件;
- 未脱敏的保费/保额组合;
- 完整 PDF 原文;
- Base64 图片。
15.3 健康检查
readiness 应检查:
- 数据库;
- Redis;
- Celery Worker 心跳;
- storage 可读写;
- 至少一个可用文案模型;
- 至少一个可用图片模型或明确允许 fallback;
- 至少一个启用版式预设;
- 必需字体是否存在;
- 磁盘剩余空间。
十六、发布、灰度与回滚
16.1 功能开关
POSTER_WORKBENCH_V2_ENABLED
POSTER_USER_MANUAL_UPLOAD_ENABLED
POSTER_AI_VISUAL_CANDIDATES_ENABLED
POSTER_CANVAS_EDITOR_ENABLED
POSTER_MULTI_EXPORT_ENABLED
POSTER_LEGACY_CREATE_ENABLED
16.2 上线顺序
- 部署 Phase 0 修复;
- 部署迁移 026 和新 API,但不开新入口;
- 管理员测试自由上传和校验;
- 开放 AI 视觉候选;
- 开放画布编辑器;
- 开放多格式导出;
- 5% 销售用户灰度;
- 25% 用户;
- 全量;
- 保留旧创建入口一个发布周期;
- 关闭旧创建入口。
16.3 上线前检查
- 数据库和 storage 备份;
- 导出迁移历史;
- 在生产数据副本执行迁移 026;
- 统计旧海报记录、文件存在率和回填结果;
- 验证旧海报预览下载;
- 验证 API/Worker 共享 volume;
- 验证字体;
- 验证模型连接;
- 准备灰度账号;
- 准备回滚版本;
- 完成 P0/P1 回归。
16.4 回滚原则
- 优先关闭 V2 功能开关,不执行破坏性数据库回滚;
- 新表和新增字段保留;
- 旧接口和旧记录继续工作;
- 新项目在回滚期间保持只读和可下载;
- storage 不删除新文件;
- 代码回滚不回滚已确认事实和审计记录;
- 修复后重新开启 V2。
16.5 回滚触发条件
- 出现跨用户项目或文件访问;
- 事实校验失效仍可生成;
- 正式导出缺少关键数字或免责声明;
- 新迁移导致旧项目不可读;
- 文件下载失败率持续高于 5%;
- 任务重复计费;
- 画布自动保存持续失败;
- 导出物与画布版本不一致;
- 模型密钥或客户敏感信息泄露。
十七、工作量、人员和里程碑
17.1 工作量
| 阶段 | 人日 |
|---|---|
| Phase 0:紧急闭环 | 1.5 |
| Phase 1:数据模型与 API | 2.5 |
| Phase 2:上传、解析与校验 | 3.0 |
| Phase 3:AI 视觉与初始画布 | 3.5 |
| Phase 4:画布编辑器 | 5.5 |
| Phase 5:多格式导出 | 2.5 |
| Phase 6:历史、任务与后台同步 | 2.5 |
| Phase 7:测试、灰度和上线 | 3.5 |
| 基础合计 | 24.5 |
| 建议风险缓冲(约 20%) | 4.5~5.0 |
| 计划预算 | 约 29 人日 |
不包含:
- 外部模型账号、额度和网络审批等待;
- 业务方准备真实脱敏样例;
- 法务/合规确认时间;
- 新字体商业授权;
- SVG、多人协作、视频海报。
17.2 人员建议
单人开发:
- 预计 5~6 周;
- Phase 4 画布编辑器风险集中;
- 必须严格按阶段验收,禁止并行铺开全部功能。
双人开发:
- 后端:Phase 0~3、数据、任务、校验和导出接口;
- 前端:Phase 2 页面、Phase 4 编辑器、Phase 5 导出;
- 预计 3~4 周,集成阶段保留至少 4 人日。
17.3 里程碑
| 里程碑 | 包含阶段 | 可交付结果 |
|---|---|---|
| M0 基础可用 | Phase 0 | 当前 PNG 流程稳定 |
| M1 事实可信 | Phase 1~2 | 自由上传 + 来源审计 + 校验门 |
| M2 AI 视觉正确 | Phase 3 | AI 候选图 + 结构化初始画布 |
| M3 可编辑交付 | Phase 4~5 | 画布编辑 + 多格式导出 |
| M4 生产上线 | Phase 6~7 | 后台闭环 + 灰度 + 回滚 |
每个里程碑完成后再进入下一里程碑,不以“页面已出现”代替端到端验收。
十八、风险与应对
| 风险 | 概率 | 影响 | 应对 |
|---|---|---|---|
| Fabric.js 中文字体和长图导出差异 | 中 | 高 | Phase 4 第一项先做技术验证,不通过则切换 SVG/HTML 方案 |
| 图片模型生成文字或伪 Logo | 高 | 高 | 负向 Prompt、结果人工选择、Logo 独立图层 |
| PDF 解析事实不稳定 | 中 | 高 | Schema、来源证据、置信度、人工确认和阻断规则 |
| 画布 JSON 版本升级困难 | 中 | 高 | 明确 Schema 版本和迁移函数,不直接暴露 Fabric 原始格式为永久契约 |
| 大图导致浏览器内存高 | 中 | 中 | 素材缩略图、按需加载、隐藏高分辨率画布只在导出时创建 |
| 自动保存覆盖冲突 | 中 | 高 | 乐观锁、本地待提交、冲突另存副本 |
| 模型费用增加 | 中 | 中 | 候选数上限、幂等、局部重生成、费用指标 |
| 配置修改影响排队任务 | 中 | 高 | 提交时配置快照 |
| 旧项目无法转为可编辑 | 中 | 中 | 保持旧下载;转换时用旧图作为锁定背景并叠加可编辑文字 |
| 手机端画布难用 | 高 | 中 | 手机只做简化编辑,桌面完成精细排版 |
| PDF 导出字体缺失 | 中 | 高 | 预加载授权字体、导出前字体检查、失败阻断而非静默替换 |
| 参考照片存在隐私风险 | 中 | 高 | 上传提示授权、EXIF 清理、保留期限、权限和审计 |
十九、文件级修改清单
19.1 后端新增
| 文件 | 用途 |
|---|---|
api/insurance/db/migrate_026.py |
新表、字段、索引和旧数据回填 |
api/insurance/models/poster_project_asset.py |
项目素材 |
api/insurance/models/poster_fact_item.py |
事实与来源 |
api/insurance/models/poster_canvas_version.py |
画布版本 |
api/insurance/models/poster_export_artifact.py |
导出物 |
api/insurance/poster/project_routes.py |
新工作区接口 |
api/insurance/poster/project_service.py |
项目聚合服务 |
api/insurance/poster/asset_service.py |
素材生命周期 |
api/insurance/poster/extraction_service.py |
项目解析编排 |
api/insurance/poster/validation_service.py |
规则校验 |
api/insurance/poster/source_audit_service.py |
来源审计 |
api/insurance/poster/creative_service.py |
创意简报和文案 |
api/insurance/poster/visual_generator.py |
AI 视觉候选 |
api/insurance/poster/canvas_builder.py |
初始画布 |
api/insurance/poster/export_service.py |
导出物 |
api/insurance/poster/storage_service.py |
安全文件访问 |
api/insurance/poster/schemas/* |
事实、简报和画布 Schema |
19.2 后端修改
| 文件 | 修改 |
|---|---|
api/insurance/models/poster_record.py |
项目、校验、画布、配置快照字段 |
api/insurance/models/generation_task.py |
操作类型和任务输出 |
api/insurance/poster/routes.py |
旧接口兼容和下载转调 |
api/insurance/poster/service.py |
旧流程转调新项目服务 |
api/insurance/poster/image_generator.py |
视觉素材 Prompt 和尺寸统一 |
api/insurance/poster/copy_generator.py |
事实引用和结构化输出 |
api/insurance/poster/tasks.py |
项目解析任务 |
api/insurance/generation/celery_tasks.py |
新任务操作、状态同步和错误码 |
api/insurance/generation/routes.py |
工作区详情和任务恢复 |
api/insurance/routes.py |
注册新 Blueprint |
api/insurance/config.py |
文件和功能开关 |
api/insurance/models/__init__.py |
注册模型 |
api/insurance/requirements.txt |
仅增加实际使用的导出/校验依赖 |
docker-compose.dify.yml |
API/Worker storage 和开关 |
19.3 前端新增和修改
| 文件 | 修改 |
|---|---|
frontend/package.json |
Fabric.js、PDF 导出和测试依赖 |
frontend/src/router/* |
新项目和编辑器路由 |
frontend/src/pages/PosterPage.vue |
切换到 V2 首页/兼容入口 |
frontend/src/pages/PosterHistoryPage.vue |
改为项目历史 |
frontend/src/utils/poster-api.ts |
项目、素材、校验、画布和导出 API |
frontend/src/composables/useWorkspace.ts |
完整项目状态恢复 |
frontend/src/components/GenerationTaskDock.vue |
海报细分任务和跳转 |
frontend/src/pages/admin/PosterTemplatesAdmin.vue |
版式预设、版本和 Prompt |
frontend/src/pages/admin/PptSettingsAdmin.vue |
校验、导出和配置版本 |
frontend/src/pages/PosterEditorPage.vue |
全屏编辑器 |
frontend/src/components/poster/** |
新五阶段组件 |
19.4 测试
建议新增:
tests/poster_storage_test.py
tests/poster_project_migration_test.py
tests/poster_asset_api_test.py
tests/poster_fact_validation_test.py
tests/poster_source_audit_test.py
tests/poster_visual_generation_test.py
tests/poster_canvas_api_test.py
tests/poster_export_test.py
tests/poster_permissions_test.py
tests/poster_task_lifecycle_test.py
frontend/src/**/__tests__/*
frontend/e2e/poster-workbench.spec.ts
二十、文档同步清单
实施过程中必须同步:
| 文档 | 更新内容 |
|---|---|
保险智能客服系统_需求文档.md |
海报项目、校验、画布、导出业务规则 |
保险智能客服系统_API接口文档.md |
新接口、错误码、请求响应 |
保险智能客服系统_测试用例.md |
P0/P1 和端到端用例 |
PPT与海报功能开发任务清单.md |
增加二期任务编号和状态 |
部署文档_完整版.md |
依赖、字体、storage、开关和 Worker |
API_curl示例.md |
项目、素材、校验、生成和导出示例 |
CHANGELOG.md |
每个发布阶段的新增、修复和变更 |
docs/README.md |
本计划索引 |
二十一、完成定义
只有全部满足以下条件,海报工作台二期才可标记为完成:
- 用户可直接上传计划书和产品小册子;
- 用户也可选择后台审核产品;
- 参考图和 Logo 通过真实文件上传管理;
- 所有关键事实有来源或人工补录说明;
- 错误数据无法进入生成;
- 警告已显式处理;
- AI 生成视觉素材,不在图片中生成正式文字和数字;
- 文案数字全部绑定已确认事实;
- 生成结果是可编辑画布;
- 画布支持撤销、重做、自动保存和版本恢复;
- 页面刷新和任务完成后可恢复项目;
- 支持 PNG、JPG、PDF 和项目源文件;
- 导出物关联画布、事实和配置版本;
- 任务中心和项目历史职责清晰;
- 后台配置提交时快照可审计;
- 旧海报仍可预览下载;
- API/Worker 共享持久化 storage;
- 普通用户不能访问他人数据;
- P0/P1 自动化测试全部通过;
- 迁移、灰度和回滚演练完成;
- 相关需求、API、测试、部署和变更日志已同步。
二十二、开发启动前待确认项
以下决策不阻塞计划编写,但必须在对应 Phase 开发前确认:
| 编号 | 决策 | 推荐默认值 | 最晚确认阶段 |
|---|---|---|---|
| D-01 | 手机是否要求完整画布编辑 | 否,手机使用简化编辑 | Phase 4 |
| D-02 | 首期 PDF 是否接受栅格化单页 | 接受,保证视觉一致 | Phase 5 |
| D-03 | 项目源文件是否允许用户重新导入 | 允许,但严格校验 Schema | Phase 5 |
| D-04 | 用户上传小册子是否可进入公共产品库 | 仅显式提交审核后进入 | Phase 2 |
| D-05 | 每次默认生成几个视觉候选 | 3 个 | Phase 3 |
| D-06 | AI 图片失败是否允许 fallback | 默认允许,但必须清晰标记 | Phase 3 |
| D-07 | 正式导出是否必须二次人工确认 | 建议必须 | Phase 5 |
| D-08 | 项目和原始 PDF 默认保留时间 | 沿用后台当前保留策略 | Phase 7 |
| D-09 | 首期支持哪些授权中文字体 | 至少 2 套品牌字体 | Phase 4 |
| D-10 | SVG 是否进入首发 | 不进入,作为 P2 | Phase 5 |
二十三、建议的第一批实施内容
第一批开发只做 Phase 0 和 Phase 1,不立即进入画布编辑器:
修复下载目录
→ 修复尺寸映射
→ 修复失败状态同步
→ 建立回归样例
→ 创建迁移 026
→ 建立项目素材、事实、画布版本、导出物模型
→ 创建空项目和工作区 API
→ 完成旧数据回填测试
完成这一批后,数据库和文件模型稳定,后续上传、校验、AI 和画布可以并行推进;如果基础模型未稳定就直接开发编辑器,极易出现画布、历史、导出和任务各自保存一套数据的问题。