8.8 KiB
8.8 KiB
AI 重新修图接口优化需求
1. 背景
图片预览页面支持用户在“原图”Tab 上重新选择修图模板。
用户可能只生成过一种关联图片,例如之前仅生成了“原图精修”,尚未生成“氛围感”图片。此时用户重新修图时,可以同时选择:
- 原图精修模板
- 氛围感修图模板
客户端会调用现有 ai-reretouch 接口,并通过 type = 3 提交两个模板,希望一次创建两个修图输出任务。
2. 问题复现
前置状态
- 原图素材 ID:
702 - 原 AI 修图批次 ID:
61 - 已存在并完成:原图精修
- 从未生成:氛围感图片
请求
POST /api/yf-handset-app/photog/travel-album/ai-reretouch
{
"ai_retouch_batch_id": 61,
"id": 702,
"type": 3,
"refined_template_id": 2,
"atmosphere_template_id": 14
}
字段含义:
| 字段 | 值 | 说明 |
|---|---|---|
ai_retouch_batch_id |
61 |
原 AI 修图批次 ID |
id |
702 |
原图素材 ID |
type |
3 |
同时处理精修和氛围感 |
refined_template_id |
2 |
本次选择的精修模板 |
atmosphere_template_id |
14 |
本次选择的氛围感模板 |
当前响应
{
"code": 100099,
"data": [],
"msg": "仅已完成修图的照片可重新修图",
"time": "2026-08-14 17:41:17"
}
3. 当前问题
从响应判断,后端可能在 type = 3 时要求精修图和氛围感图都已经存在且完成,才允许重新修图。
但本场景中:
- 精修图已经存在,本次需要重新生成,并在成功后覆盖旧精修图。
- 氛围感图从未生成,本次需要创建新的关联图片。
由于氛围感图历史上不存在,接口拒绝了整个请求,导致客户端无法通过一次请求同时完成“覆盖已有精修图”和“新增氛围感图”。
客户端当前请求已经正确传递 type = 3 和两个模板 ID,无需修改请求结构。
4. 期望接口行为
建议将 ai-reretouch 调整为按输出类型分别执行的 upsert(存在则覆盖,不存在则新增) 语义。
对于本次请求:
原图精修
- 请求传入了
refined_template_id。 - 旧精修图已经存在。
- 后端创建新的精修任务。
- 新任务成功后覆盖旧精修图。
- 新任务处理中或失败时保留旧精修图。
氛围感修图
- 请求传入了
atmosphere_template_id。 - 旧氛围感图不存在。
- 后端创建新的氛围感任务。
- 任务成功后,将结果保存为原图的新关联图片。
整体任务
- 一次请求创建两个输出任务:
refined和atmosphere。 - 按两个实际创建的输出预占 2 张修图额度。
- 两个输出分别执行、分别记录状态、分别结算额度。
- 单个输出失败不应影响另一个已经成功的输出。
5. 建议的后端处理规则
5.1 基础校验
建议校验:
- 原图素材存在。
- 原图素材属于指定相册或批次。
- 原图当前状态允许提交 AI 修图任务。
- 请求中至少传入一个与
type匹配的有效模板 ID。 - 用户剩余额度满足本次实际创建的输出数量。
不建议校验:
type = 3时要求精修和氛围感历史结果都必须存在。- 某一种关联图从未生成时直接拒绝整个请求。
5.2 按模板字段创建任务
后端根据本次实际传入的模板字段创建对应任务:
| 请求情况 | 期望处理 |
|---|---|
只传 refined_template_id |
只创建精修任务 |
只传 atmosphere_template_id |
只创建氛围感任务 |
| 两个模板 ID 都传 | 同时创建精修和氛围感任务 |
| 某个模板 ID 未传 | 不处理、不覆盖该类型的已有结果 |
5.3 按输出类型处理已有结果
对于每个实际提交的输出类型,分别判断:
| 历史状态 | 建议处理 |
|---|---|
| 已存在成功结果 | 创建重修任务,新结果成功后替换旧结果 |
| 从未生成 | 创建新任务,成功后新增关联图片 |
| 历史任务失败或已取消 | 允许重新创建任务 |
| 当前已有处理中或排队任务 | 拒绝该类型重复提交,或通过幂等机制复用已有任务 |
5.4 替换时机
继续采用现有 replace_on_success 语义:
- 新结果成功后,才替换同类型旧结果。
- 新任务排队、处理中或失败时,保留旧结果。
- 精修和氛围感分别替换,互不影响。
6. type 参数建议语义
保持现有请求类型和接口路径不变:
type |
语义 | 模板规则 |
|---|---|---|
1 |
只处理精修 | 必须传 refined_template_id,忽略氛围感模板 |
2 |
只处理氛围感 | 必须传 atmosphere_template_id,忽略精修模板 |
3 |
同时处理精修和氛围感 | 根据实际传入的两个模板分别创建任务 |
对于 type = 3:
- 必须传
refined_template_id。 atmosphere_template_id可以选传。- 传入氛围感模板时创建氛围感任务。
- 未传氛围感模板时,只重修精修图,并保留已有氛围感图。
7. 建议处理伪代码
validateOriginalMaterial(request.id)
validateBatch(request.ai_retouch_batch_id)
outputs = []
if request.refined_template_id is not null:
outputs.add(
createTask(
outputType = refined,
templateId = request.refined_template_id,
mode = existingRefinedResult ? replace_on_success : create
)
)
if request.atmosphere_template_id is not null:
outputs.add(
createTask(
outputType = atmosphere,
templateId = request.atmosphere_template_id,
mode = existingAtmosphereResult ? replace_on_success : create
)
)
if outputs is empty:
return invalid_template_error
reserveQuota(outputs.count)
submitTasks(outputs)
注意:实际是否存在旧结果,应按照各自的 output_type 独立查询,不能用“两个类型都已完成”作为 type = 3 的整体前置条件。
8. 期望响应
接口成功响应建议继续返回任务批次信息,并明确本次创建的输出类型。例如:
{
"code": 100000,
"data": {
"ai_retouch_batch_id": 61,
"source_material_id": 702,
"outputs": [
{
"type": "refined",
"mode": "replace_on_success",
"status": "queued"
},
{
"type": "atmosphere",
"mode": "create",
"status": "queued"
}
],
"reserved_units": 2
},
"msg": "AI修图任务已提交"
}
响应结构可沿用现有实现,不强制增加上述字段;关键要求是一次请求能够成功创建两个对应的修图任务。
9. 验收用例
用例一:只有旧精修图,同时提交两个模板
- 历史状态:精修已完成,氛围感不存在。
- 请求:
type = 3,同时传精修和氛围感模板。 - 期望:创建两个任务;精修成功后覆盖,氛围感成功后新增。
用例二:只有旧氛围感图,同时提交两个模板
- 历史状态:精修不存在,氛围感已完成。
- 请求:
type = 3,同时传精修和氛围感模板。 - 期望:创建两个任务;精修成功后新增,氛围感成功后覆盖。
用例三:两种旧结果都存在
- 历史状态:精修、氛围感都已完成。
- 请求:
type = 3,同时传两个模板。 - 期望:创建两个任务,分别在成功后覆盖各自旧结果。
用例四:原图 Tab 只选择精修模板
- 历史状态:精修、氛围感均可能存在。
- 请求:
type = 3,只传refined_template_id。 - 期望:只创建精修任务;不处理、不删除、不覆盖旧氛围感图;预占 1 张额度。
用例五:精修后 Tab 重新修图
- 请求:
type = 1,只传refined_template_id。 - 期望:只创建精修任务,新精修成功后覆盖旧精修图。
用例六:氛围感 Tab 重新修图
- 请求:
type = 2,只传atmosphere_template_id。 - 期望:只创建氛围感任务,新氛围感成功后覆盖旧氛围感图。
用例七:其中一个输出失败
- 请求创建精修和氛围感两个任务。
- 精修成功,氛围感失败。
- 期望:保留成功的新精修结果;氛围感旧图存在时继续保留旧图,不存在时不生成关联图;额度分别结算。
用例八:防止重复提交
- 同一原图、同一输出类型已经存在排队中或处理中的任务。
- 用户再次提交相同任务。
- 期望:通过幂等机制返回原任务,或仅拒绝重复的输出类型,避免重复扣减额度和重复生成结果。
10. 总结
希望 ai-reretouch 支持以下统一语义:
对本次传入模板对应的每种输出独立处理:已有结果则在新任务成功后覆盖,没有结果则新增;未传模板的类型不处理。不要因为某一种关联图历史上从未生成,就拒绝整个重新修图请求。