7.5 KiB
createGenTaskPayload 梳理
本文只说明 src/layouts/globalPromptPanel/globalPromptPanel.tsx 里的 createGenTaskPayload。
它是创建任务接口 createGenTask() 的请求体。
它也会传给 useGenerateCost(),作为普通任务价格计算的同源参数。
1. 它解决什么问题
createGenTaskPayload 把创作面板当前状态整理成后端需要的任务参数。
它主要合并 4 类数据:
- 当前任务类型:
activeTaskSubType - 当前模型:
activeModelItem - 当前参数:
modelParamFields和selectedParamValues - 当前输入内容:
chatPrompt、上传媒体、音色、动作模仿示例、参考主体
最终结果会用于两个地方:
useGenerateCost({ taskPayload: createGenTaskPayload })createGenTask(createGenTaskPayload)
2. 整体流程
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() 会把同一个模型信息写成多个字段。
这是后端接口约定,不是前端重复写错。
当前会写入:
aiModelNameaiPlatformaiModelIdmodelaiModelCodeaiModelCodeAlias
其中 aiPlatform、model、aiModelCode 都来自 activeModelItem.code。
3.2 参数字段
参数字段来自 buildComposerTaskParamPayload()。
它会做这些事:
- 用
buildPreferredParamValues()给缺失参数补默认值 - 找到比例字段,比如
ratio - 找到分辨率字段,比如
resolution - 根据比例和分辨率推导
width / height - 保证请求体里有接口约定的
ratio字段
3.3 滑块参数
splitRangeParamsForTaskSubmit() 会把滑块参数从顶层移到 extraTaskParams。
例子:
{
"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 个视频时,后面的上传视频不会进入请求体。
空数组不会提交。 所以代码最后会删除这些空字段:
imagesvideosvoices
5. 不同任务的额外处理
createGenTaskPayload 在基础参数之外,会按任务类型补几个字段。
5.1 通用任务
所有任务都会写入:
chatPrompt: chatPrompt.trim()imagesvideosvoices
如果 chatPrompt 为空,创建任务前会有校验。
动作模仿任务例外,因为它可以只依赖动作示例。
5.2 文本转语音任务
当 isVoiceTask 为 true 时,会写入:
voiceId
取值优先级是:
selectedVoiceItem?.voiceId > voiceId
如果最终值为空,代码会删除 voiceId。
创建任务前也会再校验一次,确保文本转语音必须有音色。
5.3 动作模仿任务
当 isActionMimicTask 为 true 时,videos 会特殊处理。
如果用户选了动作模仿示例,代码会把示例视频放到 videos 第一位:
[selectedActionMimicItem.url, ...uploadMediaPayload.uploadVideos]
如果选中的是官方示例,还会写入:
templateVideoMaterialId
它来自 selectedActionMimicItem.id。
如果不是官方示例,这个字段会被删除。
5.4 参考生视频任务
当 isReferenceTask 为 true 时,会写入:
referenceSubjectList
这个字段来自 referenceStructure.referenceSubjectList。
它保存参考主体列表,不只是普通上传图片。
6. 当前请求体大概长什么样
一个普通图像或视频任务的请求体大概是:
{
"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() 还会检查:
- 非动作模仿任务必须有提示词
- 当前任务是否满足最少上传数量
- 音频素材不能单独提交,必须搭配图片或视频
- 动作模仿任务必须选择示例
- 文本转语音任务必须选择音色
- 用户积分是否足够
这些校验通过后,才会调用:
await createGenTask(createGenTaskPayload);
8. 阅读这段代码时的顺序
建议按这个顺序看:
- 先看
createGenTaskPayload本体,知道最终字段有哪些。 - 再看
buildComposerTaskSubmitPayload(),理解模型和参数怎么进请求体。 - 再看
buildComposerTaskParamPayload(),理解默认参数、比例、分辨率、尺寸。 - 再看
splitRangeParamsForTaskSubmit(),理解滑块参数为什么进extraTaskParams。 - 最后看
handleCreateGenTaskClick(),理解请求体提交前的校验。
9. 为什么现在看起来杂乱
这段逻辑承担了两个职责:
- 生成创建任务的请求体
- 给价格计算提供同一份任务参数
同时它还要兼容多种任务类型。 所以它会同时碰到模型、参数、媒体、音色、动作示例、参考主体。
如果后续要继续整理,可以把它拆成一个纯函数,例如:
buildCreateGenTaskPayload({
activeTaskSubType,
activeModelItem,
modelParamFields,
selectedParamValues,
chatPrompt,
uploadMediaPayload,
selectedVoiceItem,
voiceId,
selectedActionMimicItem,
referenceSubjectList,
isVoiceTask,
isActionMimicTask,
isReferenceTask,
})
这样 globalPromptPanel.tsx 只负责传状态。
请求体规则可以放到 utils.ts 或单独文件里测试。