Files
AIGC/SORA2_INTEGRATION_TASKS.md
blandarebiter 90b5118e45 perf(backend+frontend): 列表API响应体积优化 3.1MB→145KB (↓95.4%)
- 后端: JPQL构造器投影排除LONGTEXT大字段(uploadedImages/videoReferenceImages)
- 后端: DTO层过滤非分镜图类型的base64内联resultUrl
- 前端: 列表缩略图从video改为img loading=lazy,消除172并发请求
- 前端: download函数增加resultUrl懒加载(详情接口兜底)
- 文档: 新增性能优化报告 docs/performance-optimization-report.md
2026-04-10 18:46:37 +08:00

12 KiB
Raw Permalink Blame History

Sora 2 模型集成 — 任务执行清单(后台配置方案)

核心思路:视频生成模型由管理员在系统后台统一指定,用户无感知。后端根据当前配置的模型名自动切换 API 请求参数格式。


一、数据库层4 个表 + 1 个 SQL 脚本)

1.1 SystemSettings 新增 video_model 字段

文件 改动
AIGC/src/main/java/com/example/demo/model/SystemSettings.java 新增 videoModel 字段VARCHAR(50)),默认值 "grok-video-3",加 getter/setter

1.2 任务表新增 video_model 字段(记录创建时使用的模型)

表名 文件 改动
text_to_video_tasks AIGC/src/main/java/com/example/demo/model/TextToVideoTask.java 新增 videoModel 字段VARCHAR(50)),默认值 "grok-video-3",加 getter/setter
image_to_video_tasks AIGC/src/main/java/com/example/demo/model/ImageToVideoTask.java 同上
storyboard_video_tasks AIGC/src/main/java/com/example/demo/model/StoryboardVideoTask.java 同上(注意:已有 imageModel 字段是分镜图模型,新增的 videoModel 是视频生成模型,不冲突)
user_works AIGC/src/main/java/com/example/demo/model/UserWork.java 新增 videoModel 字段VARCHAR(50)),默认值 "grok-video-3"

1.3 数据库迁移脚本

文件 改动
AIGC/init_database.sql 末尾追加 5 条 ALTER TABLE ... ADD COLUMN IF NOT EXISTS video_model VARCHAR(50) DEFAULT 'grok-video-3'system_settings + 3 任务表 + user_works

二、后端 Service 层5 个文件)

2.1 SystemSettingsService — 提供模型配置读取

文件 AIGC/src/main/java/com/example/demo/service/SystemSettingsService.java
getOrCreate() 初始化默认值时设置 videoModel = "grok-video-3"

2.2 RealAIService — 根据模型名切换 API 参数格式(核心改动)

文件 AIGC/src/main/java/com/example/demo/service/RealAIService.java
参数构建逻辑 SystemSettings 读取 videoModel,根据模型名构建不同的请求体
submitTextToVideoTask() 移除外部传入的 videoModel 参数,改为内部读取系统设置。根据模型名选择参数格式(见下方参数对照表)
submitImageToVideoTask() 同上
submitStoryboardVideoTask() 同上
selectXxxModel() 系列 不再使用,模型由系统设置决定

参数对照表

参数 grok-video-3 sora-2 / sora-2-pro
model "grok-video-3" "sora-2""sora-2-pro"
宽高比 "ratio": "3:2" / "2:3" / "1:1"convertAspectRatioToGrokRatio() "size": "1280x720" / "720x1280" 等(convertAspectRatioToSize()
时长 "duration": 整数 5 或 10convertDurationToGrokDuration() "duration": 字符串 "10s" / "15s" / "25s"
分辨率 "resolution": "1080P" / "720P" 通过 size 参数中的像素值体现HD 时选 sora-2-pro
API 端点 /v2/videos/generations /v2/videos/generations(相同)

模型选择逻辑

// 从系统设置读取当前模型
String videoModel = systemSettingsService.getOrCreate().getVideoModel();
if (videoModel == null || videoModel.isEmpty()) {
    videoModel = "grok-video-3"; // 默认值
}

// 根据模型构建请求参数
if (videoModel.startsWith("sora-2")) {
    // Sora 2 参数格式
    requestMap.put("model", hdMode ? "sora-2-pro" : "sora-2");
    requestMap.put("size", convertAspectRatioToSize(aspectRatio, hdMode));
    requestMap.put("duration", duration + "s"); // "10s", "15s"
} else {
    // Grok 参数格式(默认)
    requestMap.put("model", videoModel);
    requestMap.put("ratio", convertAspectRatioToGrokRatio(aspectRatio));
    requestMap.put("duration", convertDurationToGrokDuration(duration));
    requestMap.put("resolution", hdMode ? "1080P" : "720P");
}

2.3 TextToVideoService — 记录模型到任务

文件 AIGC/src/main/java/com/example/demo/service/TextToVideoService.java
createTask() 移除 videoModel 参数,改为从 SystemSettings 读取当前模型,task.setVideoModel(videoModel)
processTaskWithRealAPI() 从 task 读取 videoModel 传给 RealAIService保证使用创建时的模型即使后台后来切换了
retryTask() 复用原任务的 videoModel

2.4 ImageToVideoService — 记录模型到任务

文件 AIGC/src/main/java/com/example/demo/service/ImageToVideoService.java
createTask() 同上逻辑
createTaskByUrl() 同上
processTaskWithRealAPI() 从 task 读取 videoModel 传给 RealAIService
retryTask() 复用原任务的 videoModel

2.5 StoryboardVideoService — 记录模型到任务

文件 AIGC/src/main/java/com/example/demo/service/StoryboardVideoService.java
创建任务方法 SystemSettings 读取当前模型,写入任务
视频生成调用处 从 task 读取 videoModel 传给 RealAIService
retryTask() 复用原任务的 videoModel

2.6 UserWorkService — 创建作品时写入模型

文件 AIGC/src/main/java/com/example/demo/service/UserWorkService.java
createProcessingTextToVideoWork() 从 TextToVideoTask 读取 videoModelwork.setVideoModel(task.getVideoModel())
createProcessingImageToVideoWork() 从 ImageToVideoTask 读取 videoModel,同上
createProcessingStoryboardVideoWork() 从 StoryboardVideoTask 读取 videoModel,同上
createTextToVideoWork() 同上(完成时创建的方法)
createImageToVideoWork() 同上
createStoryboardVideoWork() 同上

三、后端 Controller 层1 个文件)

3.1 PublicApiController — 公共配置接口暴露当前模型

文件 AIGC/src/main/java/com/example/demo/controller/PublicApiController.java
getPublicConfig() 在返回的 config Map 中新增 videoModel 字段(从 SystemSettings 读取),前端据此动态渲染比例/时长选项

四、前端 — 管理后台设置页1 个文件)

4.1 SystemSettings.vue — AI 模型选项卡新增视频模型配置

文件 AIGC/frontend/src/views/SystemSettings.vue
改动 在已有的"AI模型设置"选项卡中新增视频模型选择下拉框el-select选项grok-video-3 / sora-2。保存时写入 SystemSettings

五、前端 — 创建页面动态参数3 个文件)

核心变化:前端启动时从 /api/public/config 获取当前 videoModel,据此动态渲染不同的比例和时长选项。

各模型前端参数对照表

参数 grok-video-3(当前) sora-2 / sora-2-pro
比例选项 3:2(横屏)、2:3(竖屏) 16:9(横屏)、9:16(竖屏)
时长选项 5s10s 10s15sHD 模式下 sora-2-pro 还支持 25s
默认比例 2:3 16:9
默认时长 5 10

5.1 TextToVideoCreate.vue

文件 AIGC/frontend/src/views/TextToVideoCreate.vue
获取模型 onMounted 时调用 /api/public/config 获取 videoModel,存入响应式变量
比例下拉框 <option> 改为动态列表,根据 videoModel 渲染不同选项
时长下拉框 同上,根据 videoModel 渲染不同选项
默认值 模型切换时重置 aspectRatioduration 为对应默认值

5.2 ImageToVideoCreate.vue

文件 AIGC/frontend/src/views/ImageToVideoCreate.vue
改动 同 TextToVideoCreate.vue动态渲染比例/时长选项

5.3 StoryboardVideoCreate.vue

文件 AIGC/frontend/src/views/StoryboardVideoCreate.vue
改动 同上,动态渲染比例/时长选项

实现方式参考

// 模型参数配置表
const MODEL_CONFIGS = {
  'grok-video-3': {
    ratios: [
      { value: '3:2', label: '3:2' },
      { value: '2:3', label: '2:3' }
    ],
    durations: [
      { value: '5', label: '5s' },
      { value: '10', label: '10s' }
    ],
    defaultRatio: '2:3',
    defaultDuration: '5'
  },
  'sora-2': {
    ratios: [
      { value: '16:9', label: '16:9' },
      { value: '9:16', label: '9:16' }
    ],
    durations: [
      { value: '10', label: '10s' },
      { value: '15', label: '15s' }
    ],
    defaultRatio: '16:9',
    defaultDuration: '10'
  }
}

// 从公共配置获取当前模型
const videoModel = ref('grok-video-3')
const currentConfig = computed(() => MODEL_CONFIGS[videoModel.value] || MODEL_CONFIGS['grok-video-3'])

onMounted(async () => {
  const config = await fetch('/api/public/config').then(r => r.json())
  videoModel.value = config.videoModel || 'grok-video-3'
  // 重置为对应模型的默认值
  aspectRatio.value = currentConfig.value.defaultRatio
  duration.value = currentConfig.value.defaultDuration
})
<!-- 比例选项动态渲染 -->
<select v-model="aspectRatio" class="setting-select">
  <option v-for="r in currentConfig.ratios" :key="r.value" :value="r.value">{{ r.label }}</option>
</select>

<!-- 时长选项动态渲染 -->
<select v-model="duration" class="setting-select">
  <option v-for="d in currentConfig.durations" :key="d.value" :value="d.value">{{ d.label }}</option>
</select>

六、前端 — 作品展示2 个文件)

6.1 MyWorks.vue — 显示模型标签

文件 AIGC/frontend/src/views/MyWorks.vue
改动 在作品卡片上新增一个不可点击的 el-tag,根据 work.videoModel 显示模型名称。不同模型用不同颜色区分Sora 2 紫色Grok 蓝色)

6.2 Profile.vue — 个人主页作品集显示模型标签

文件 AIGC/frontend/src/views/Profile.vue
transformWorkData() 新增 videoModel: work.videoModel || 'grok-video-3' 映射
作品卡片模板video-grid .video-thumbnail 区域内新增不可点击的 el-tag 显示模型名,与 MyWorks 保持一致风格
详情弹窗metadata-section 新增一行 metadata-item 显示"视频模型Sora 2 / Grok Video 3"

七、国际化2 个文件)

文件 改动
AIGC/frontend/src/locales/zh.js 新增:videoModel: '视频生成模型'modelGrok: 'Grok Video 3'modelSora2: 'Sora 2'videoModelTip: '切换后新创建的任务将使用所选模型'
AIGC/frontend/src/locales/en.js 新增对应英文翻译

八、积分计算

Sora 2 和 Grok 积分价格统一,不需要改动 calculateCost() 逻辑。


改动汇总

层级 文件数 复杂度
数据库 Model 5SystemSettings + 3 任务表 + UserWork 低(各加 1 个字段)
数据库 SQL 1 5 条 ALTER
后端 Service 6SystemSettingsService + RealAIService + 3 视频 Service + UserWorkService RealAIService 需根据模型分支构建请求参数)
后端 Controller 1PublicApiController 低(公共配置中暴露 videoModel
前端创建页面 3TextToVideoCreate + ImageToVideoCreate + StoryboardVideoCreate (动态渲染比例/时长选项)
前端管理后台 1SystemSettings.vue 低(加下拉框)
前端作品展示 2MyWorks + Profile 低(加标签)
国际化 2 低(加几个 key
合计 ~21 个文件 整体工作量1-2 天

不需要改动的部分

  • 前端 API 层textToVideo.js / imageToVideo.js / storyboardVideo.js— 不传 videoModel比例/时长参数名不变
  • 任务 ID 生成逻辑 — 内部 ID 与模型无关
  • 任务状态轮询 — getTaskStatus() 用 realTaskId 查询,与模型无关
  • COS 存储逻辑 — 存的是视频文件,与模型无关
  • 任务队列调度 — 队列只管调度,不关心模型