4 changed files with 322 additions and 11 deletions
@ -0,0 +1,279 @@ |
|||
# createGenTaskPayload 梳理 |
|||
|
|||
本文只说明 `src/layouts/globalPromptPanel/globalPromptPanel.tsx` 里的 `createGenTaskPayload`。 |
|||
它是创建任务接口 `createGenTask()` 的请求体。 |
|||
它也会传给 `useGenerateCost()`,作为普通任务价格计算的同源参数。 |
|||
|
|||
## 1. 它解决什么问题 |
|||
|
|||
`createGenTaskPayload` 把创作面板当前状态整理成后端需要的任务参数。 |
|||
|
|||
它主要合并 4 类数据: |
|||
|
|||
- 当前任务类型:`activeTaskSubType` |
|||
- 当前模型:`activeModelItem` |
|||
- 当前参数:`modelParamFields` 和 `selectedParamValues` |
|||
- 当前输入内容:`chatPrompt`、上传媒体、音色、动作模仿示例、参考主体 |
|||
|
|||
最终结果会用于两个地方: |
|||
|
|||
- `useGenerateCost({ taskPayload: createGenTaskPayload })` |
|||
- `createGenTask(createGenTaskPayload)` |
|||
|
|||
## 2. 整体流程 |
|||
|
|||
```txt |
|||
mediaItems |
|||
└─ splitUploadMediaItems() |
|||
├─ uploadImages |
|||
├─ uploadVideos |
|||
└─ uploadVoice |
|||
|
|||
activeModelItem + activeTaskSubType + modelParamFields + selectedParamValues |
|||
└─ buildComposerTaskSubmitPayload() |
|||
├─ subType |
|||
├─ type |
|||
├─ 模型字段 |
|||
├─ 普通参数 |
|||
└─ extraTaskParams |
|||
|
|||
createGenTaskPayload |
|||
├─ 基础任务参数 |
|||
├─ chatPrompt |
|||
├─ images / videos / voices |
|||
├─ voiceId |
|||
├─ templateVideoMaterialId |
|||
└─ referenceSubjectList |
|||
``` |
|||
|
|||
## 3. 基础任务参数从哪里来 |
|||
|
|||
基础参数来自 `buildComposerTaskSubmitPayload()`。 |
|||
|
|||
这个函数会返回: |
|||
|
|||
- `subType`:当前任务子类型 |
|||
- `type`:任务大类。当前代码里 `1` 是图片类,`2` 是视频类,`3` 是音频类 |
|||
- 模型字段:来自 `buildGenTaskModelPayload(activeModelItem)` |
|||
- 普通参数:来自模型参数和固定参数 |
|||
- `extraTaskParams`:滑块参数,比如 `speed / vol / pitch` |
|||
|
|||
### 3.1 模型字段 |
|||
|
|||
`buildGenTaskModelPayload()` 会把同一个模型信息写成多个字段。 |
|||
这是后端接口约定,不是前端重复写错。 |
|||
|
|||
当前会写入: |
|||
|
|||
- `aiModelName` |
|||
- `aiPlatform` |
|||
- `aiModelId` |
|||
- `model` |
|||
- `aiModelCode` |
|||
- `aiModelCodeAlias` |
|||
|
|||
其中 `aiPlatform`、`model`、`aiModelCode` 都来自 `activeModelItem.code`。 |
|||
|
|||
### 3.2 参数字段 |
|||
|
|||
参数字段来自 `buildComposerTaskParamPayload()`。 |
|||
|
|||
它会做这些事: |
|||
|
|||
- 用 `buildPreferredParamValues()` 给缺失参数补默认值 |
|||
- 找到比例字段,比如 `ratio` |
|||
- 找到分辨率字段,比如 `resolution` |
|||
- 根据比例和分辨率推导 `width / height` |
|||
- 保证请求体里有接口约定的 `ratio` 字段 |
|||
|
|||
### 3.3 滑块参数 |
|||
|
|||
`splitRangeParamsForTaskSubmit()` 会把滑块参数从顶层移到 `extraTaskParams`。 |
|||
|
|||
例子: |
|||
|
|||
```json |
|||
{ |
|||
"resolution": "2K", |
|||
"ratio": "9:16", |
|||
"extraTaskParams": { |
|||
"speed": 1, |
|||
"vol": 0.8, |
|||
"pitch": 0 |
|||
} |
|||
} |
|||
``` |
|||
|
|||
这样做是为了让普通参数留在顶层,同时让 `speed / vol / pitch` 这类范围值走 `extraTaskParams`。 |
|||
|
|||
## 4. 媒体字段怎么来 |
|||
|
|||
上传媒体来自 `splitUploadMediaItems(mediaItems, composerUploadLimits)`。 |
|||
|
|||
它会按类型拆成三列: |
|||
|
|||
- 图片:`uploadImages`,最后写入 `images` |
|||
- 视频:`uploadVideos`,最后写入 `videos` |
|||
- 音频:`uploadVoice`,最后写入 `voices` |
|||
|
|||
它也会按模型上传上限截断对应类型。 |
|||
例如模型最多只收 1 个视频时,后面的上传视频不会进入请求体。 |
|||
|
|||
空数组不会提交。 |
|||
所以代码最后会删除这些空字段: |
|||
|
|||
- `images` |
|||
- `videos` |
|||
- `voices` |
|||
|
|||
## 5. 不同任务的额外处理 |
|||
|
|||
`createGenTaskPayload` 在基础参数之外,会按任务类型补几个字段。 |
|||
|
|||
### 5.1 通用任务 |
|||
|
|||
所有任务都会写入: |
|||
|
|||
- `chatPrompt: chatPrompt.trim()` |
|||
- `images` |
|||
- `videos` |
|||
- `voices` |
|||
|
|||
如果 `chatPrompt` 为空,创建任务前会有校验。 |
|||
动作模仿任务例外,因为它可以只依赖动作示例。 |
|||
|
|||
### 5.2 文本转语音任务 |
|||
|
|||
当 `isVoiceTask` 为 `true` 时,会写入: |
|||
|
|||
- `voiceId` |
|||
|
|||
取值优先级是: |
|||
|
|||
```txt |
|||
selectedVoiceItem?.voiceId > voiceId |
|||
``` |
|||
|
|||
如果最终值为空,代码会删除 `voiceId`。 |
|||
创建任务前也会再校验一次,确保文本转语音必须有音色。 |
|||
|
|||
### 5.3 动作模仿任务 |
|||
|
|||
当 `isActionMimicTask` 为 `true` 时,`videos` 会特殊处理。 |
|||
|
|||
如果用户选了动作模仿示例,代码会把示例视频放到 `videos` 第一位: |
|||
|
|||
```txt |
|||
[selectedActionMimicItem.url, ...uploadMediaPayload.uploadVideos] |
|||
``` |
|||
|
|||
如果选中的是官方示例,还会写入: |
|||
|
|||
- `templateVideoMaterialId` |
|||
|
|||
它来自 `selectedActionMimicItem.id`。 |
|||
如果不是官方示例,这个字段会被删除。 |
|||
|
|||
### 5.4 参考生视频任务 |
|||
|
|||
当 `isReferenceTask` 为 `true` 时,会写入: |
|||
|
|||
- `referenceSubjectList` |
|||
|
|||
这个字段来自 `referenceStructure.referenceSubjectList`。 |
|||
它保存参考主体列表,不只是普通上传图片。 |
|||
|
|||
## 6. 当前请求体大概长什么样 |
|||
|
|||
一个普通图像或视频任务的请求体大概是: |
|||
|
|||
```json |
|||
{ |
|||
"subType": 102, |
|||
"type": 1, |
|||
"aiModelName": "模型名", |
|||
"aiPlatform": "模型 code", |
|||
"aiModelId": 123, |
|||
"model": "模型 code", |
|||
"aiModelCode": "模型 code", |
|||
"aiModelCodeAlias": "别名", |
|||
"resolution": "2K", |
|||
"ratio": "9:16", |
|||
"width": 720, |
|||
"height": 1280, |
|||
"batchSize": 1, |
|||
"chatPrompt": "用户输入的提示词", |
|||
"images": ["https://example.com/a.png"], |
|||
"videos": ["https://example.com/a.mp4"], |
|||
"voices": ["https://example.com/a.mp3"], |
|||
"extraTaskParams": { |
|||
"speed": 1 |
|||
} |
|||
} |
|||
``` |
|||
|
|||
实际字段会根据任务类型、模型参数、上传内容变化。 |
|||
空的 `images / videos / voices` 不会出现在最终请求体里。 |
|||
|
|||
## 7. 创建任务前还有哪些校验 |
|||
|
|||
`createGenTaskPayload` 只负责组装请求体。 |
|||
它不负责全部业务校验。 |
|||
|
|||
点击创建任务时,`handleCreateGenTaskClick()` 还会检查: |
|||
|
|||
- 非动作模仿任务必须有提示词 |
|||
- 当前任务是否满足最少上传数量 |
|||
- 音频素材不能单独提交,必须搭配图片或视频 |
|||
- 动作模仿任务必须选择示例 |
|||
- 文本转语音任务必须选择音色 |
|||
- 用户积分是否足够 |
|||
|
|||
这些校验通过后,才会调用: |
|||
|
|||
```ts |
|||
await createGenTask(createGenTaskPayload); |
|||
``` |
|||
|
|||
## 8. 阅读这段代码时的顺序 |
|||
|
|||
建议按这个顺序看: |
|||
|
|||
1. 先看 `createGenTaskPayload` 本体,知道最终字段有哪些。 |
|||
2. 再看 `buildComposerTaskSubmitPayload()`,理解模型和参数怎么进请求体。 |
|||
3. 再看 `buildComposerTaskParamPayload()`,理解默认参数、比例、分辨率、尺寸。 |
|||
4. 再看 `splitRangeParamsForTaskSubmit()`,理解滑块参数为什么进 `extraTaskParams`。 |
|||
5. 最后看 `handleCreateGenTaskClick()`,理解请求体提交前的校验。 |
|||
|
|||
## 9. 为什么现在看起来杂乱 |
|||
|
|||
这段逻辑承担了两个职责: |
|||
|
|||
- 生成创建任务的请求体 |
|||
- 给价格计算提供同一份任务参数 |
|||
|
|||
同时它还要兼容多种任务类型。 |
|||
所以它会同时碰到模型、参数、媒体、音色、动作示例、参考主体。 |
|||
|
|||
如果后续要继续整理,可以把它拆成一个纯函数,例如: |
|||
|
|||
```ts |
|||
buildCreateGenTaskPayload({ |
|||
activeTaskSubType, |
|||
activeModelItem, |
|||
modelParamFields, |
|||
selectedParamValues, |
|||
chatPrompt, |
|||
uploadMediaPayload, |
|||
selectedVoiceItem, |
|||
voiceId, |
|||
selectedActionMimicItem, |
|||
referenceSubjectList, |
|||
isVoiceTask, |
|||
isActionMimicTask, |
|||
isReferenceTask, |
|||
}) |
|||
``` |
|||
|
|||
这样 `globalPromptPanel.tsx` 只负责传状态。 |
|||
请求体规则可以放到 `utils.ts` 或单独文件里测试。 |
|||
Loading…
Reference in new issue