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

290 lines
12 KiB
Markdown
Raw Permalink 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.

# 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 或 10`convertDurationToGrokDuration()` | `"duration"`: 字符串 `"10s"` / `"15s"` / `"25s"` |
| 分辨率 | `"resolution"`: `"1080P"` / `"720P"` | 通过 `size` 参数中的像素值体现HD 时选 sora-2-pro |
| API 端点 | `/v2/videos/generations` | `/v2/videos/generations`(相同) |
#### 模型选择逻辑
```java
// 从系统设置读取当前模型
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 读取 `videoModel``work.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`(竖屏) |
| 时长选项 | `5s``10s` | `10s``15s`HD 模式下 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` 渲染不同选项 |
| 默认值 | 模型切换时重置 `aspectRatio``duration` 为对应默认值 |
### 5.2 ImageToVideoCreate.vue
| 文件 | `AIGC/frontend/src/views/ImageToVideoCreate.vue` |
|------|------|
| 改动 | 同 TextToVideoCreate.vue动态渲染比例/时长选项 |
### 5.3 StoryboardVideoCreate.vue
| 文件 | `AIGC/frontend/src/views/StoryboardVideoCreate.vue` |
|------|------|
| 改动 | 同上,动态渲染比例/时长选项 |
#### 实现方式参考
```javascript
// 模型参数配置表
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
})
```
```html
<!-- 比例选项动态渲染 -->
<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 存储逻辑 — 存的是视频文件,与模型无关
- ❌ 任务队列调度 — 队列只管调度,不关心模型