Skip to content

AI 漫剧后端建设方案评审稿 ​

文档状态:方案评审
当前版本:v0.1
适用范围:@fx/ic、@fuxishi/infinite-canvas-vue、@fuxishi/infinite-canvas-core、Java 主业务后端、Python AI 服务
说明:本文档保留早期方案、评审意见和演进记录。文中“待实现”“尚未接入”等表述均以对应日期为准, 不代表当前状态;当前实现以仓库代码、最新 Flyway migration 和 docs/backend/ 下的详细契约为准。

实现状态更新(2026-09-28) ​

  • Java 生成任务创建和重试已改为在业务事务内写入 drama_generation_task_outbox;定时发布器轮询 PENDING 记录并投递 Kafka,投递失败时记录尝试次数、错误和下次重试时间。投递箱表现并入基线迁移 V5__create_drama_core_schema.sql(2026-10-10 迁移规整),默认每 5 秒轮询一次、每批最多 20 条。
  • Python drama_ai 已增加 aiokafka 消费者,使用手动提交 offset,并接入 FastAPI 生命周期的启动和停止流程。Java 状态回调失败现在会抛出异常,防止消费者将未完成回调的消息视为成功;成功状态回调已移出模型执行异常处理分支。
  • 已观察到 Java 启动后定时查询 Outbox,查询返回 Total: 0 仅表示当次没有符合条件的待投递记录,不能据此判断 Kafka 连通性。
  • 本地 git diff --check 已通过。Python 的 ruff 和测试尚未完成:本机尝试在 D 盘使用 Python 3.14 安装依赖时,asyncmy==0.2.11 因缺少 Microsoft C++ Build Tools 而构建失败;本次生成的 D 盘虚拟环境、解释器、缓存和临时文件已按要求清理。
  • 当时下一步是在服务器配置 Python 运行环境及 Kafka 连接参数,并核对目标数据库中的迁移状态;使用有效项目和默认模型创建测试任务,依次确认 Outbox PENDING → SENT、Python 消费、Java 任务状态回调及失败重试。该段为 2026-09-28 历史记录;当前 Provider 代码已接入,真实账号端到端验收仍需按部署文档执行。

实现状态更新(2026-09-20) ​

  • Java 后端已完成并通过测试:drama_generation_task 任务生命周期、分页查询、幂等创建、取消、重试和状态回调。
  • Java agent 适配层已接入 Python AI 服务,支持基地址、内部 Token、连接超时和读取超时配置。
  • Java 模型管理模块已完成模型、供应商和 Prompt 模板的分页查询、创建、更新、删除、启停管理,以及按能力查询和默认模型查询。
  • 模型管理数据库迁移 V4__create_model_management_schema.sql(原 V6,2026-10-10 规整重编号)已包含通用模型表、供应商、模型能力、Prompt 模板及基础数据;系统菜单种子 V2__seed_system_data.sql 已补充模型管理菜单和超级员工权限关联。
  • 管理端已接入模型管理页面 /model/manage,包含模型、供应商和 Prompt 模板三个列表,使用 FxProTable 并对接 @fx/api-admin 模型管理接口。
  • Python drama_ai 已完成能力查询、任务投递、异步编排和任务包结构;该条为 2026-09-20 的阶段记录,后续已补齐 LLM、图片、音频、视频和 ffmpeg 执行入口。
  • 当前本地未安装 Python 工具链,未执行 uv/ruff;Java 已执行 mvn test,30 个测试全部通过。
  • 线上部署前仍需完成真实 Provider 配置、数据库迁移初始化和 Java → Python → Java 端到端联调。

1. 背景和目标 ​

当前前端已经具备三层画布能力:

text
packages/ic
  -> packages/infinite-canvas-vue
  -> packages/infinite-canvas-core

其中:

  • @fx/ic 是面向产品的无限画布业务封装。
  • @fuxishi/infinite-canvas-vue 是 Vue 3 适配层。
  • @fuxishi/infinite-canvas-core 是画布图模型和执行内核。

后端需要为 AI 漫剧提供以下能力:

  • 漫剧项目管理。
  • 画布保存、加载和版本恢复。
  • 剧本、角色、分镜、素材和剧集管理。
  • AI 生成任务创建、执行、查询、取消和重试。
  • Python 模型服务调用。
  • 图片、音频和视频资源管理。
  • 多人协作时的数据一致性和权限控制。

本方案的核心目标是:

text
让前端画布可以可靠保存和恢复,
让 Java 管理稳定业务,
让 Python 专注 AI 能力,
让后续模型和部署方式可以替换。
林:
建议只控制音频声音源文件,后续使用该源文件进行台词生成,不需要一句话一句话的去控制,可以减少工作量,也更方便进行管理和维护。

补充(音色选型参考):

音色源文件方案可参考开源项目 MOSS-TTS-Nano(音色克隆 / 语音合成),在线演示见 HuggingFace Spaces - MOSS-TTS-Nano。

2. 总体架构 ​

推荐采用 Java + Python 双服务协作:

text
┌──────────────────────┐
│      前端业务页面     │
│  项目页 / 画布页 / 面板 │
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│       @fx/ic          │
│ 产品画布业务封装       │
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ infinite-canvas-vue   │
│ Vue 适配和事件桥接     │
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ infinite-canvas-core  │
│ 图模型 / DSL / 执行引擎 │
└──────────┬───────────┘
           │ HTTP
           ▼
┌──────────────────────┐       ┌──────────────────────┐
│   Java 主业务后端      │──────▶│   Python AI 服务      │
│ 项目 / 画布 / 权限 / 任务 │      │ Prompt / 模型 / 生成   │
└──────────┬───────────┘       └──────────┬───────────┘
           │                              │
           ▼                              ▼
      MySQL / Redis                    模型供应商
           │                              │
           └──────────────┬───────────────┘
                          ▼
                       对象存储
   林:
   python对接ai模块,对接后返回的数据最好是通过后端在传回前端实现漫剧生成,所以应该是双箭头,方便后续的记录管理,回溯、留痕等工作。
   应该在加一个日志,执行记录什么的,方便后续排查维护,在现阶段就可以加上。

3. 各层职责 ​

3.1 infinite-canvas-core ​

代码位置:

text
packages/infinite-canvas-core

负责:

  • GraphNode、GraphEdge、GraphGroup 图模型。
  • 节点、连线、分组和选择状态。
  • 命令系统和撤销重做。
  • DSL 序列化和反序列化。
  • 视口状态。
  • 拓扑排序和前端执行引擎。
  • 执行状态和执行事件。

该层不应该包含:

  • Java API 调用。
  • 漫剧项目权限。
  • 数据库访问。
  • 模型供应商逻辑。
  • 具体业务页面状态。

3.2 infinite-canvas-vue ​

代码位置:

text
packages/infinite-canvas-vue

负责:

  • Vue 3 组件适配。
  • v-model:nodes、v-model:edges、v-model:groups。
  • 画布事件转发。
  • Vue slot 节点内容渲染。
  • 引擎 API expose。

正式业务接入时,建议业务页面持有画布数据,不让组件内部状态成为唯一数据来源。

3.3 @fx/ic ​

代码位置:

text
packages/ic

包名:

text
@fx/ic

负责:

  • 产品级画布封装。
  • 默认工具栏。
  • 添加节点菜单。
  • 默认节点卡片。
  • 素材库、角色库、生成历史等产品动作事件。
  • 产品视觉和交互约定。

当前已注册的节点类型:

text
text-gen        文本生成
image-gen       图片生成
video-gen       视频生成
smart-edit      智能剪辑(Beta)
audio-gen       音频生成
script-gen      脚本生成
director        导演台

frame-inspect(逐帧拉片)在添加菜单中占位展示,尚未注册为节点类型。

当前产品动作(底部工具栏 action 事件,add-node 由封装内部消化不外抛):

text
tool-mode           移动模式
open-workflow       打开工具箱
open-asset          素材库
character-library   角色库
history             生成历史
keyboard            快捷键
contact             教程

当前菜单动作(menuSelect 事件外抛):

text
upload                    上传
pick-from-history         从生成历史选择
save-asset                保存到我的资产(占位禁用)
create-subject            创建主体(占位禁用)
copy-to-clipboard         复制到剪贴板(右键菜单)
group-rate                组评级(右键菜单,label 为分值)
reference-node            参考节点(out 挂起菜单)

@fx/ic 不应直接负责:

  • 项目保存。
  • Java API 请求。
  • AI 任务状态管理。
  • 数据库模型。

这些能力由业务页面或独立的画布仓储适配层负责。

3.4 Java 主业务后端 ​

代码位置:

text
backend/java/src/main/java/com/zyease/modules

负责:

  • 漫剧项目和业务实体。
  • 用户、项目成员和权限。
  • 画布文档和版本。
  • AI 任务生命周期。
  • 业务事务和状态流转。
  • 服务端 DSL 校验。
  • 素材业务引用。
  • 对前端提供稳定 API。

3.5 Python AI 服务 ​

代码位置:

text
backend/python/app/modules/drama_ai

负责:

  • Prompt 编排。
  • 大语言模型调用。
  • 图片、音频和视频模型调用。
  • 模型供应商适配。
  • AI 长耗时任务执行。
  • 模型响应解析和错误处理。

Python 不负责 Java 漫剧业务实体的主生命周期。

林:3.4跟3.5,这两个应该先经过谁?不能只经过一个模块,最好是先走Java进行数据备份/处理,如何python返回执行结果,拿Java后端做一个踏板,可以单独分个模块,这样数据不怕丢失,就算Java的业务用不到也走一遍这个模块,以防数据丢失或者吞数据什么的。

4. Java 模块规划 ​

建议使用以下结构:

text
com.zyease.modules.drama
├── project/
│   ├── controller/
│   ├── dto/
│   ├── entity/
│   ├── mapper/
│   ├── service/
│   └── vo/
├── canvas/
│   ├── controller/
│   ├── dto/
│   ├── entity/
│   ├── mapper/
│   ├── service/
│   └── vo/
├── script/
├── storyboard/
├── character/
├── asset/
├── generation/
├── episode/
└── constant/

职责划分:

子模块职责
project漫剧项目、项目配置、项目成员
canvas画布文档、画布版本、视口和 DSL
script剧本、章节、场景、对白
storyboard分镜镜头、画面描述、镜头参数
character角色资料、形象设定、声音设定
asset图片、音频、视频和上传文件
generationAI 生成任务、状态、重试、回调
episode漫剧集数、审核、发布和下线
constant状态、任务类型和节点白名单

模块边界约束:

  • drama_project 只由 modules/drama/project 维护,包括 Entity、Mapper、Service 和 Controller。
  • modules/drama/generation 只维护生成任务,不再定义 DramaProject、DramaProjectMapper、DramaProjectService 或项目 Controller。
  • 生成任务需要校验项目归属时,直接依赖 modules/drama/project/service/DramaProjectService,避免同名 Spring Bean、MyBatis Mapper 和 MyBatis TypeAlias 冲突。 Java agent 模块负责 Python 服务适配,不承载漫剧业务实体:
text
drama  = 漫剧业务
agent  = AI 服务调用适配

4.1 通用模型管理模块 ​

模型管理是平台通用能力,不使用 drama_ 前缀,位于:

text
backend/java/src/main/java/com/zyease/modules/model

当前包含:

能力说明
供应商管理维护供应商名称、API 基地址、API 版本、密钥、状态和扩展配置
模型管理维护供应商关联、模型名称、类型、能力、上下文长度、价格、状态和模型配置
Prompt 模板按能力维护模板内容、版本、变量定义和启用状态
模型查询按能力查询可用模型,按模型类型获取默认模型

模型供应商类型已覆盖 OpenAI、Anthropic、Google、Azure、xAI、Mistral、DeepSeek、智谱、阿里云、腾讯、字节、月之暗面、MiniMax、阶跃、百度、讯飞、零一万物、OpenRouter 和 Ollama 等基础数据。

管理端页面位于:

text
frontend/web/src/views/model/index.vue
frontend/web/src/views/model/ModelList.vue
frontend/web/src/views/model/ProviderList.vue
frontend/web/src/views/model/PromptTemplateList.vue
packages/api/admin/src/model.ts

页面通过 FxSegmented 切换三个管理视图,列表统一使用 FxProTable,支持筛选、分页、新增、编辑、启停和删除。供应商编辑时 API Key 留空表示保留原密钥。

5. 画布数据模型 ​

5.1 前端 DSL ​

当前 Core 使用版本化 DSL:

节点包含:

text
id
type
x
y
width
data
title
muted
collapsed
parentId

连线包含:

text
id
kind
source
target
data

5.2 存储策略 ​

第一阶段建议保存完整画布快照:

text
drama_canvas
drama_canvas_revision

不要第一版就把每个节点、连线和分组拆成多张表。原因:

  • 前端已经通过命令批量修改图数据。
  • 撤销和重做是前端本地行为。
  • 画布保存天然适合快照。
  • 单节点同步会增加并发冲突和请求数量。
  • DSL 已经是前端明确的存储格式。

后续如果需要按节点检索、统计或分析,可以增加投影表:

text
drama_canvas_node_projection

投影表只用于查询,不作为画布的唯一事实来源。

5.3 drama_canvas ​

建议字段:

text
id
project_id
name
current_revision
document_json
created_at
updated_at
creator_id

其中:

text
document_json JSON

保存完整 DSL 文档。

5.4 drama_canvas_revision ​

建议字段:

text
id
canvas_id
revision_no
document_json
change_summary
created_at
creator_id

每次业务保存产生一个新版本,是否对纯视口变化产生版本需要单独确定。

6. 画布保存和版本控制 ​

6.1 获取画布 ​

http
GET /api/v1/drama/projects/{projectId}/canvas

响应示例:

json
{
  "canvasId": 1,
  "projectId": 100,
  "revision": 12,
  "document": {
    "version": 1,
    "meta": {},
    "nodes": [],
    "edges": [],
    "groups": []
  }
}

6.2 保存画布 ​

http
PUT /api/v1/drama/projects/{projectId}/canvas

请求示例:

json
{
  "expectedRevision": 12,
  "document": {
    "version": 1,
    "meta": {},
    "nodes": [],
    "edges": [],
    "groups": []
  }
}

保存时使用乐观锁:

text
expectedRevision == currentRevision

版本不一致时返回:

http
409 Conflict

前端可以提示用户重新加载、比较版本或覆盖保存。

6.3 版本接口 ​

http
GET /api/v1/drama/canvases/{canvasId}/revisions
POST /api/v1/drama/canvases/{canvasId}/revisions/{revision}/restore

6.4 前端保存时机 ​

建议:

事件保存策略
节点新增、删除、连线、分组500 至 1000 ms 防抖保存
节点拖动node-drag-stop 后保存
撤销、重做保存完整快照
视口变化1 至 2 秒防抖,或作为用户偏好单独保存
node-drag-move不请求后端
pointermove不请求后端

7. 节点类型和业务数据契约 ​

7.1 第一阶段兼容现有类型 ​

当前 @fx/ic 注册的是:

text
text
image
audio
video

后端第一阶段必须兼容这些类型,不要直接要求前端改为:

text
ai.llm
ai.image
ai.audio
ai.video

如果未来需要更细的节点分类,使用 DSL 版本迁移,而不是直接破坏已有数据。

例如:

text
DSL v1: text / image / audio / video
DSL v2: drama.script / ai.image / ai.audio / ai.video

7.2 node.data 使用原则 ​

适合放入 node.data:

  • 节点 UI 配置。
  • Prompt 模板 ID。
  • 模型参数。
  • 业务实体 ID。
  • 资源引用 ID。
  • 生成任务 ID。

不适合放入 node.data:

  • 图片二进制。
  • 音频二进制。
  • 视频二进制。
  • 完整模型原始响应。
  • 不受限制的大型 Prompt 历史。
  • 运行中的执行状态。

节点数据示例:

json
{
  "id": "node_01",
  "type": "text",
  "data": {
    "assetId": 1001,
    "generationTaskId": 2001,
    "promptTemplateId": "drama-script-v1"
  }
}

7.3 节点白名单 ​

Java 服务端需要维护可用节点类型白名单:

text
text
image
audio
video

服务端导入或执行画布时校验:

  • 节点类型是否允许。
  • 节点数量是否超限。
  • 节点 data 大小是否超限。
  • 连线是否引用存在的节点。
  • 连线端口是否存在。
  • 图是否存在非法环。
  • 当前用户是否有对应 AI 能力权限。

8. AI 生成任务 ​

8.1 任务流程 ​

text
前端点击生成
  -> Java 校验项目权限和画布
  -> Java 创建 drama_generation_task
  -> Java 调用 Python
  -> Python 执行模型任务
  -> Python 返回结果或回调 Java
  -> Java 更新任务状态
  -> Java 保存剧本、素材或剧集数据

8.2 任务类型 ​

text
SCRIPT
STORYBOARD
CHARACTER_IMAGE
SCENE_IMAGE
VOICE
VIDEO
FULL_EPISODE

8.3 任务状态 ​

text
PENDING
RUNNING
SUCCEEDED
FAILED
CANCELLED

8.4 drama_generation_task ​

已实现功能 ​

Java 端(modules/drama/generation) ​
  • 表结构:任务生命周期(PENDING/RUNNING/SUCCEEDED/FAILED/CANCELLED)、进度、重试次数、模型供应商、结果 URL
  • 服务层:DramaGenerationTaskService,支持任务创建、查询、取消、重试、状态回调
  • 控制器:DramaGenerationTaskController,RESTful 接口,支持分页和幂等投递
  • 项目归属校验:复用 modules/drama/project/service/DramaProjectService,不在 generation 模块内重复定义项目相关 Bean 或实体
  • 枚举:DramaTaskType(SCRIPT/STORYBOARD/IMAGE/AUDIO/VIDEO)、DramaTaskStatus
Java 端(modules/agent) ​
  • HTTP 客户端:DramaAiClient,调用 Python AI 服务,支持超时和鉴权
  • 跨服务 DTO:DramaAiSubmitRequest/Response、DramaAiStatusUpdateRequest
  • 配置:application.yml 新增 drama-ai 配置段(baseUrl、token、超时)
Python 端(app/modules/drama_ai) ​
  • 路由:/api/v1/internal/drama-ai/capabilities(能力查询)、/api/v1/internal/drama-ai/tasks(任务投递)
  • 服务:DramaAiService,负责异步任务编排、进度更新和 Java 状态回调
  • 契约:schema.py,任务类型使用小写 script/storyboard/image/audio/video,与 Java 投递 DTO 对齐
  • 任务包:tasks/ 已补齐基类和剧本、分镜、图片、音频、视频任务入口;未配置真实 Provider 时显式失败,不伪造成功结果
  • 供应商:providers/ 保留供应商适配边界;后续已接入 LLM、图片、音频、视频和 ffmpeg 执行入口,线上仍需配置真实账号并验收
  • 回调实现:使用 Python 标准库 urllib,不额外引入未声明的 HTTP 依赖
异步流程 ​
  1. Java POST /api/v1/drama/tasks 创建任务并保存为 PENDING。
  2. Java 通过 DramaAiClient 调用 Python POST /api/v1/internal/drama-ai/tasks。
  3. Python 后台任务执行器按小写任务类型选择任务入口,并先回调 Java RUNNING。
  4. Python 完成或失败后回调 Java POST /api/v1/drama/tasks/{id}/status。
  5. Java 作为任务状态唯一事实来源,更新 SUCCEEDED 或 FAILED;素材入库、剧本/分镜采纳和业务回填已在后续阶段实现。

后续扩展记录(当时待实现) ​

1. drama_asset 表(林老师任务) ​
  • 已落地生成结果并关联 drama_generation_task
  • 已支持素材登记和相关业务实体回填;CDN 加速仍取决于存储配置
2. 剧本→分镜→图片→配音→视频链路(后续已落地) ​
  • drama_episode:一集一项目结构,已落地时间线和导出接口
  • drama_character:角色管理,已落地参考图和音色设定
  • drama_script:剧本和台词管理,已落地任务结果采纳
  • drama_storyboard:分镜管理,已落地任务结果采纳和逐镜图片回填
3. 性能优化和成本统计(部分已落地,部分仍为后续增强) ​
  • 生成用量、日限额、并发限制和预算预留:已落地
  • 更完整的模型成本统计、任务监控和告警:后续增强
4. 生成质量优化(部分已落地,部分仍为后续增强) ​
  • 通用 Prompt 模板管理:已落地于模型管理模块
  • A/B 测试和效果评估:后续增强

建议字段:

text
id
project_id
canvas_id
canvas_revision
task_type
status
progress
provider
model
request_json
result_json
error_message
retry_count
started_at
finished_at
created_at
updated_at
creator_id

设计原则:

  • request_json 保存脱敏后的输入摘要。
  • result_json 保存结构化结果摘要。
  • 大文件不放在任务表中。
  • Prompt 保存模板 ID 和版本。
  • 任务支持幂等键。
  • 任务状态由 Java 作为业务侧唯一事实来源。

9. 素材和对象存储 ​

图片、音频和视频应该存储在对象存储中,MySQL 只保存元数据。

9.1 drama_asset ​

当前状态 ​

  • 已实现:任务成功回调后创建素材并回填 result_asset_id,台词行和分镜等业务实体按任务参数自动回填
  • 功能:关联 drama_generation_task,支持文件上传和 CDN 加速
  • 依赖:对象存储、签名 URL 和 CDN 能力取决于部署环境配置

已实现关联 ​

  • drama_generation_task.result_url:生成结果资源地址
  • drama_generation_task.result_asset_id:已关联生成结果素材

建议字段:

text
id
project_id
asset_type
storage_key
url
mime_type
file_size
checksum
width
height
duration
provider
model
source_task_id
metadata_json
created_at
updated_at
creator_id

画布节点只保存资源引用:

json
{
  "assetRef": {
    "assetId": 1001,
    "role": "character-reference"
  }
}

这样对象存储 URL 变化时,不需要修改整张画布。

10. Python AI 服务设计 ​

建议结构:

text
backend/python/app/modules/drama_ai/
├── __init__.py
├── router.py
├── schema.py
├── service.py
├── providers/
│   ├── llm/
│   ├── image/
│   ├── audio/
│   └── video/
├── prompts/
└── tasks/

约束:

  • router.py 只处理 HTTP 协议。
  • 模型 SDK 只能放在 providers/。
  • service.py 负责能力编排和回调,不保存 Java 漫剧业务实体。
  • 长耗时任务放在 tasks/,任务基类统一接收供应商、模型和请求参数。
  • 当前任务入口未配置真实 Provider 时必须显式失败,禁止返回伪造的生成结果。
  • 模型供应商错误转换为统一内部错误。
  • API Key 通过环境变量或密钥管理系统注入。
  • Java 回调地址通过 JAVA_BACKEND_BASE_URL 配置,默认指向 http://localhost:8080。
  • Python 服务不新增未声明的运行时依赖;当前状态回调使用标准库 urllib。

当前可以保留能力检查接口:

http
GET /api/v1/internal/drama-ai/capabilities

正式生成接口上线前,需要补充:

  • 服务间鉴权。
  • 请求签名或网关限制。
  • 超时。
  • 重试。
  • 幂等键。
  • 回调验签。
  • 任务取消。

11. 前端执行和服务端执行 ​

现有 Core 有浏览器端 ExecutionEngine,可以支持两种模式:

前端执行 ​

适用于:

  • 画布交互预览。
  • 节点流程演示。
  • 本地调试。
  • 不涉及正式资源生成的操作。

服务端执行 ​

适用于:

  • 正式生成剧本。
  • 正式生成图片。
  • 正式生成音频和视频。
  • 需要保存结果的生产任务。

前端执行结果不能直接作为正式业务结果。Java 服务端必须重新校验 DSL 和权限。

12. 服务端 DSL 校验 ​

Java 导入或执行画布时建议分层校验:

结构校验 ​

  • JSON 是否可解析。
  • DSL version 是否支持。
  • meta 是否正确。
  • nodes、edges、groups 是否为数组。
  • 必填字段和字段类型是否正确。

引用校验 ​

  • 节点 ID 不重复。
  • 连线 ID 不重复。
  • 连线两端节点存在。
  • 端口 ID 合法。
  • 组成员节点存在。

业务校验 ​

  • 节点类型在白名单中。
  • 项目状态允许编辑或执行。
  • 用户具备项目权限。
  • AI 能力允许当前用户使用。
  • 参数、Prompt 和任务规模不超过限制。

执行校验 ​

  • flow 边是否形成合法执行图。
  • 是否存在环。
  • 并发节点数是否超限。
  • 任务预算和资源配额是否足够。

前端 Core 中已有 JSON Schema 和导入校验逻辑,建议将该 Schema 作为前后端共同契约来源。

13. 需要先解决的前端契约问题 ​

当前需要确认 infinite-canvas-core 的类型定义、解析器和 JSON Schema 是否完全一致。

重点检查:

  • groups 是否完整出现在 JSON Schema。
  • title 是否完整出现在节点 Schema。
  • muted 是否完整出现在节点 Schema。
  • collapsed 是否完整出现在节点 Schema。
  • bounds 是否完整出现在分组 Schema。
  • 前端导出、前端导入和后端校验是否使用同一版本规则。

相关位置:

text
packages/infinite-canvas-core/src/serializer/types.ts
packages/infinite-canvas-core/src/serializer/serialize.ts
packages/infinite-canvas-core/src/serializer/parse.ts
packages/infinite-canvas-core/src/serializer/schema.ts

在 Java 正式接入 DSL 前,建议先钉死 DSL v1:

text
前端导出成功
  -> 后端校验成功
  -> 后端保存成功
  -> 后端返回
  -> 前端重新导入成功
  -> 再导出保持语义一致

14. 数据库命名规范 ​

漫剧业务表统一使用:

text
drama_

通用模型管理表不使用 drama_ 前缀,使用以下表名:

text
model_provider
model
model_capability
prompt_template

建议表:

text
drama_project
drama_canvas
drama_canvas_revision
drama_script
drama_script_chapter
drama_character
drama_storyboard
drama_asset
drama_generation_task
drama_episode

普通业务表原则上包含:

text
id
created_at
updated_at
creator_id

约束:

  • 字段使用 snake_case。
  • 外键使用 _id 后缀。
  • 状态字段使用 status。
  • JSON 字段用于非固定结构数据。
  • 大文件使用对象存储。
  • 新表通过 Flyway migration 创建。
  • 禁止修改已经执行过的历史 migration。

15. API 初版规划 ​

项目 ​

http
POST /api/v1/drama/projects
GET /api/v1/drama/projects
GET /api/v1/drama/projects/{projectId}
PATCH /api/v1/drama/projects/{projectId}
DELETE /api/v1/drama/projects/{projectId}

画布 ​

http
GET /api/v1/drama/projects/{projectId}/canvas
PUT /api/v1/drama/projects/{projectId}/canvas
GET /api/v1/drama/canvases/{canvasId}/revisions
POST /api/v1/drama/canvases/{canvasId}/revisions/{revision}/restore

AI 生成任务 ​

http
POST /api/v1/drama/projects/{projectId}/generation-tasks
GET /api/v1/drama/projects/{projectId}/generation-tasks
GET /api/v1/drama/generation-tasks/{taskId}
POST /api/v1/drama/generation-tasks/{taskId}/cancel
POST /api/v1/drama/generation-tasks/{taskId}/retry

素材 ​

http
GET /api/v1/drama/projects/{projectId}/assets
POST /api/v1/drama/projects/{projectId}/assets/upload
GET /api/v1/drama/assets/{assetId}
DELETE /api/v1/drama/assets/{assetId}

通用模型管理 ​

供应商接口:

http
GET /api/v1/model/providers
POST /api/v1/model/providers
PUT /api/v1/model/providers/{id}
DELETE /api/v1/model/providers/{id}
PUT /api/v1/model/providers/{id}/status/{status}

模型接口:

http
GET /api/v1/model
POST /api/v1/model
PUT /api/v1/model/{id}
DELETE /api/v1/model/{id}
PUT /api/v1/model/{id}/status/{status}
GET /api/v1/model/capability/{capability}
GET /api/v1/model/default/{modelType}

Prompt 模板接口:

http
GET /api/v1/prompt-template
POST /api/v1/prompt-template
PUT /api/v1/prompt-template/{id}
DELETE /api/v1/prompt-template/{id}
PUT /api/v1/prompt-template/{id}/status/{status}
GET /api/v1/prompt-template/latest/{capability}

以上接口中,模型、供应商和 Prompt 模板的增删改查及状态管理已经落地;漫剧项目、画布、素材等接口也已在后续阶段落地,具体路径以当前 Controller 和 @fx/api-admin 为准。

上述接口中,早期方案曾将项目、画布、AI 生成任务和素材接口列为规划;这些能力已在后续阶段实现,当前路径以代码和最新接口文档为准。

16. 第一条业务闭环 ​

建议第一阶段只做“文本生成剧本”:

text
创建项目
  -> 打开画布
  -> 添加 text 节点
  -> 输入主题和要求
  -> Java 创建 SCRIPT 任务
  -> Python 调用大模型
  -> 返回结构化剧本
  -> Java 保存剧本和任务结果
  -> 前端展示结果

第一条闭环需要确认:

  • 剧本结果格式。
  • Prompt 模板格式。
  • 任务请求和响应协议。
  • 任务是同步返回还是异步返回。
  • Python 回调还是 Java 轮询。
  • 画布节点与剧本实体如何关联。
  • 失败是否自动重试。

建议默认采用:

text
Java 创建任务
  -> Python 异步执行
  -> Java 查询任务状态

后续再根据实际需要增加回调和消息队列。

17. 分阶段实施计划 ​

阶段一:画布持久化 ​

  • 确认 DSL v1。
  • 完成项目表。
  • 完成画布表。
  • 完成画布版本表。
  • 完成加载、保存和恢复接口。
  • 完成乐观锁。
  • 完成前端画布仓储适配。

阶段二:文本生成剧本 ​

  • 完成 SCRIPT 任务。
  • 完成 Java 到 Python 的请求协议。
  • 完成 Python LLM Provider。
  • 完成任务状态查询。
  • 完成剧本结果保存。

阶段三:角色和分镜 ​

  • 从剧本提取角色。
  • 生成角色设定。
  • 生成场景和分镜。
  • 将角色和分镜关联到画布节点。

阶段四:图片、配音和视频 ​

  • 角色图生成。
  • 场景图生成。
  • 配音生成。
  • 视频片段生成。
  • 素材入库和对象存储。

阶段五:成片和发布 ​

  • 多素材合成。
  • 剧集管理。
  • 审核。
  • 发布和下线。

阶段六:实时协作 ​

只有确定需要多人同时编辑时,再评估:

text
WebSocket
操作日志
CRDT / Yjs
在线成员
实时光标

当前使用版本号和乐观锁即可,不建议一开始直接引入 CRDT。

18. 主要风险和应对 ​

风险影响应对
DSL 前后端不一致画布无法恢复统一 Schema 和版本迁移
画布组件内部持有状态数据无法可靠保存业务页面持有节点和边
AI 任务同步等待请求超时任务 ID + 异步执行
模型供应商绑定业务替换模型困难Python Provider 适配层
大文件进入 JSON 或 MySQL性能和存储问题对象存储 + 素材元数据
重复点击产生重复任务成本和数据重复幂等键
两人同时保存覆盖数据丢失revision 乐观锁
直接信任前端 DSL越权或非法执行Java 服务端重新校验
过早引入实时协作开发复杂度过高第一阶段先做版本控制

19. 待评审问题 ​

正式落地前,需要团队确认:

  1. 第一阶段是否确定为“文本生成剧本”。

  2. drama_canvas 是否保存完整 DSL 快照。

  3. 视口变化是否产生画布版本。

  4. Python 使用轮询还是回调通知 Java。

  5. 是否需要消息队列。

  6. 第一阶段使用哪些模型供应商。

  7. text/image/audio/video 是否作为长期兼容节点类型。

  8. 剧本、角色、分镜是否全部独立落库。

  9. 是否需要管理后台查看 AI 任务和生成历史。

  10. 是否允许一个项目拥有多个画布。

  11. 对象存储沿用现有文件服务还是单独增加漫剧资源空间。

  12. 画布历史版本保留数量和清理策略。

    林:画布/纯文本生成都可以,两个要求,1,允许用户使用自己设计的角色跟场景或者其他东西,2,对应角色的音频也允许用户自己上传去进行配对,我们只负责使用对应音频去做配音。

    需要消息队列,为了防止数据丢失,导致漫剧生成奇奇怪怪的。

    不允许一个项目使用多个画布,一集一个项目去实现,而不是一部剧一个项目。

    不需要独立落库,允许用户一个一个上传,我们只进行一个资源拼接,和对应效果呈现。

20. 结论 ​

建议采用以下边界:

text
@fx/ic
  = 产品画布业务封装

infinite-canvas-vue
  = Vue 适配和响应式桥接

infinite-canvas-core
  = 图模型、DSL、执行内核

Java drama
  = 漫剧业务、画布存储、权限、任务生命周期

Java agent
  = Python 服务调用适配

Python drama_ai
  = Prompt、模型调用、AI 任务执行

drama_asset
  = 生成资源元数据

第一步建议只完成:

text
项目创建
  -> 画布保存
  -> 画布加载
  -> 画布版本恢复
  -> 文本生成剧本任务

待这条链路和数据契约确认后,再开始创建正式数据库迁移和业务接口。

当前 Java 画布持久化第一版已经落地以下接口:

http
POST /api/v1/drama/projects
GET /api/v1/drama/projects
GET /api/v1/drama/projects/{projectId}/canvas
PUT /api/v1/drama/projects/{projectId}/canvas
GET /api/v1/drama/projects/{projectId}/canvas/revisions
POST /api/v1/drama/projects/{projectId}/canvas/revisions/{revision}/restore

对应迁移脚本(历史记录,当前已并入基线):

text
早期曾使用独立的 `V3__create_drama_canvas_schema.sql`;当前迁移已规整为 V1~V8,画布属于 V5 漫剧核心基线。

当前开发环境默认关闭 Flyway。确认远程测试库可以初始化时,可临时设置:

powershell
$env:FLYWAY_ENABLED = "true"
$env:APP_ENV = "dev"

首次初始化后建议恢复:

powershell
$env:FLYWAY_ENABLED = "false"

林:目前以实现视频生成成功为首要目标,降低使用次数,生成成本。

前端画布对接 ​

前端目前已经完成 Java 画布接口的第一版接入,边界如下:

text
frontend/web
  -> @fx/api-admin
  -> Java /api/v1/drama/*
  -> drama_project / drama_canvas / drama_canvas_revision

@fx/ic
  -> @fuxishi/infinite-canvas-vue
  -> @fuxishi/infinite-canvas-core serializer
  -> infinite-canvas DSL v1

已接入能力 ​

  • 管理端 /drama/canvas 页面。
  • 项目列表和项目创建。
  • 创建项目后自动加载默认画布。
  • 画布节点、连线、分组和视口通过 DSL v1 持久化。
  • 使用 expected_revision 防止多人或多标签页覆盖新版本。
  • 历史版本查询和恢复。
  • 前端节点类型 text-gen、image-gen、audio-gen、video-gen 与 Java 校验白名单一致。

前端代码入口 ​

text
packages/api/admin/src/drama.ts
packages/ic/src/components/fx-ic.vue
packages/ic/src/types.ts
frontend/web/src/views/drama/canvas.vue
frontend/web/src/router/static-routes.ts

@fx/api-admin 只定义请求和数据类型,不保存页面状态。管理端页面负责当前项目、 当前 revision、历史版本列表和加载状态。@fx/ic 只负责画布交互、DSL 导入导出, 不直接请求后端。

推荐的调用方式:

ts
const document = canvasRef.value.getDocument(project.name)
await adminApi.drama.canvas.save(project.id, {
  expected_revision: currentRevision,
  document,
  change_summary: "前端画布保存",
})

服务端返回的 document 可直接传回:

ts
canvasRef.value.setDocument(response.data.document)

当前限制 ​

  • 画布持久化、AI 任务、素材和流水线代码已经落地;真实数据库和线上服务联调仍需按部署环境验收。
  • Python 已接入 LLM、图片、音频、视频和 ffmpeg 执行入口;真实供应商账号、模型配置和费用链路仍需验证。
  • 任务状态回调路径已统一为 /api/v1/drama/tasks/{id}/status,线上部署时需要通过 JAVA_BACKEND_BASE_URL 配置 Java 地址。
  • 项目权限仍是创建者权限,项目成员协作权限待后续实现。
  • 画布节点中的 AI 参数只作为 node.data 保存,生成任务使用独立 DTO 传递。
  • drama_asset 已落地,生成结果可按任务回调自动创建素材并回填相关业务实体。
  • 目标环境的数据库迁移仍需人工核对;仓库当前迁移版本为 V8,Flyway 是否启用取决于部署配置。
  • 本地未安装 Python 工具链,本地未执行 uv/ruff;部署环境需要补充 Python 依赖、静态检查和端到端验证。

后续开发顺序 ​

  1. 在目标环境核对并验证当前 V1~V8 migration,不能只依据早期文件名判断迁移状态。
  2. 若数据库已经执行过旧版 V2,不能依赖修改历史 migration 自动补充菜单,应通过全新数据库重放种子,或增加后续补丁 migration 同步模型管理菜单和角色权限。
  3. 配置真实模型供应商和 API Key,完成 Provider 的目标环境联调。
  4. 完成 Java → Python → Java 状态回调端到端测试,验证任务成功、失败、重试和超时场景。
  5. 验证生成结果写入 drama_asset 以及剧本、分镜、台词行和流水线结果的业务回填。
  6. 为 @fx/ic 增加节点参数编辑、任务状态展示和脏状态提示。

Last updated: