全新popiart网站 react项目重构
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

7.2 KiB

createGenTaskPayload 梳理

本文只说明 src/layouts/globalPromptPanel/globalPromptPanel.tsx 里的 createGenTaskPayload。 它是创建任务接口 createGenTask() 的请求体。 它也会传给 useGenerateCost(),作为普通任务价格计算的同源参数。

1. 它解决什么问题

createGenTaskPayload 把创作面板当前状态整理成后端需要的任务参数。

它主要合并 4 类数据:

  • 当前任务类型:activeTaskSubType
  • 当前模型:activeModelItem
  • 当前参数:modelParamFieldsselectedParamValues
  • 当前输入内容: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() 会把同一个模型信息写成多个字段。 这是后端接口约定,不是前端重复写错。

当前会写入:

  • aiModelName
  • aiPlatform
  • aiModelId
  • model
  • aiModelCode
  • aiModelCodeAlias

其中 aiPlatformmodelaiModelCode 都来自 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 个视频时,后面的上传视频不会进入请求体。

空数组不会提交。 所以代码最后会删除这些空字段:

  • images
  • videos
  • voices

5. 不同任务的额外处理

createGenTaskPayload 在基础参数之外,会按任务类型补几个字段。

5.1 通用任务

所有任务都会写入:

  • chatPrompt: chatPrompt.trim()
  • images
  • videos
  • voices

如果 chatPrompt 为空,创建任务前会有校验。 动作模仿任务例外,因为它可以只依赖动作示例。

5.2 文本转语音任务

isVoiceTasktrue 时,会写入:

  • voiceId

取值优先级是:

selectedVoiceItem?.voiceId > voiceId

如果最终值为空,代码会删除 voiceId。 创建任务前也会再校验一次,确保文本转语音必须有音色。

5.3 动作模仿任务

isActionMimicTasktrue 时,videos 会特殊处理。

如果用户选了动作模仿示例,代码会把示例视频放到 videos 第一位:

[selectedActionMimicItem.url, ...uploadMediaPayload.uploadVideos]

如果选中的是官方示例,还会写入:

  • templateVideoMaterialId

它来自 selectedActionMimicItem.id。 如果不是官方示例,这个字段会被删除。

5.4 参考生视频任务

isReferenceTasktrue 时,会写入:

  • 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. 阅读这段代码时的顺序

建议按这个顺序看:

  1. 先看 createGenTaskPayload 本体,知道最终字段有哪些。
  2. 再看 buildComposerTaskSubmitPayload(),理解模型和参数怎么进请求体。
  3. 再看 buildComposerTaskParamPayload(),理解默认参数、比例、分辨率、尺寸。
  4. 再看 splitRangeParamsForTaskSubmit(),理解滑块参数为什么进 extraTaskParams
  5. 最后看 handleCreateGenTaskClick(),理解请求体提交前的校验。

9. 为什么现在看起来杂乱

这段逻辑承担了两个职责:

  • 生成创建任务的请求体
  • 给价格计算提供同一份任务参数

同时它还要兼容多种任务类型。 所以它会同时碰到模型、参数、媒体、音色、动作示例、参考主体。

如果后续要继续整理,可以把它拆成一个纯函数,例如:

buildCreateGenTaskPayload({
  activeTaskSubType,
  activeModelItem,
  modelParamFields,
  selectedParamValues,
  chatPrompt,
  uploadMediaPayload,
  selectedVoiceItem,
  voiceId,
  selectedActionMimicItem,
  referenceSubjectList,
  isVoiceTask,
  isActionMimicTask,
  isReferenceTask,
})

这样 globalPromptPanel.tsx 只负责传状态。 请求体规则可以放到 utils.ts 或单独文件里测试。