Files

16 KiB
Raw Permalink Blame History

AI 修图接口文档

接口列表

# 方法 路径 用途
1 GET /api/yf-handset-app/photog/travel-album/material-list 获取相册网格素材和预览初始数据
2 GET /api/yf-handset-app/photog/travel-album/material-info 获取/刷新当前原图及关联图
3 GET /api/yf-handset-app/photog/travel-album/ai-retouch-options 获取 AI 模板、选择规则和剩余额度
4 POST /api/yf-handset-app/photog/travel-album/ai-retouch 提交首次修图或重新修图任务
5 GET /api/yf-handset-app/photog/travel-album/ai-retouch-job-info 查询 AI 修图任务进度和结果
6 POST /api/yf-handset-app/photog/travel-album/delete-material 单张/批量删除素材及关联图

接口详情

获取相册素材列表

GET /api/yf-handset-app/photog/travel-album/material-list?user_equity_travel_id=88&limit=30&cursor=opaque_cursor&sort=created_at_desc
参数 必填 说明
user_equity_travel_id 是 相册 ID
limit 否 默认 30,最大 100
cursor 否 服务端返回的不透明游标,首页不传
sort 否 created_at_desc 或 created_at_asc
material_type 否 original、cover;不传表示全部

响应:

{
  "code": 100000,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": "2031",
        "user_equity_travel_id": "88",
        "material_type": "original",
        "original_asset": {
          "id": "asset_8001",
          "url": "https://cdn.example.com/albums/88/IMG_1024.jpg",
          "thumbnail_url": "https://cdn.example.com/albums/88/IMG_1024_thumb.jpg",
          "file_name": "IMG_1024.jpg",
          "mime_type": "image/jpeg",
          "file_size": 4821931,
          "width": 4032,
          "height": 3024,
          "version": 1,
          "created_at": "2026-08-09T01:00:00.000Z"
        },
        "display_status": "uploaded",
        "variant_slots": [],
        "revision": 7,
        "created_at": "2026-08-09T01:00:00.000Z",
        "updated_at": "2026-08-11T07:30:18.000Z"
      }
    ],
    "next_cursor": "next_opaque_cursor",
    "has_more": true
  }
}
  • 只返回网格顶层素材:原图和独立封面。
  • 原图如存在关联图,variant_slots 包含预览页 Tab 初始数据。
  • 建议使用游标分页,因为 AI 任务完成时可能实时插入封面素材。

获取/刷新单个原图项目

GET /api/yf-handset-app/photog/travel-album/material-info?user_equity_travel_id=88&material_id=2031

查询参数 user_equity_travel_id 和 material_id 均必填。响应的 data 直接返完整 material_project,字段与列表 Item 完全一致。该接口供预览页刷新和提交后定向更新使用。

如 material_id 已删除,返回 404 MATERIAL_NOT_FOUND。

获取 AI 修图选项

GET /api/yf-handset-app/photog/travel-album/ai-retouch-options?user_equity_travel_id=88&scope=batch&source_count=4
scope 使用场景
batch 网格多选 AI 修图,或预览页尚无 AI 结果 Tab 时首次修图
all_variants 预览页已有 AI 结果 Tab;当前为原图、精修后或氛围感均使用此范围
refined_only 仅重修精修结果的接口能力,当前客户端无独立入口
atmosphere_only 仅重修氛围感结果的接口能力,当前客户端无独立入口

user_equity_travel_id、scope 和 source_count 均必填。source_count 用于计算封面模板是否显示和必选。

响应:

{
  "code": 100000,
  "msg": "success",
  "data": {
    "scope": "batch",
    "source_count": 4,
    "groups": [
      {
        "type": "refined",
        "title": "原图精修",
        "required": true,
        "selection_mode": "single",
        "quota_cost": {
          "mode": "per_source",
          "units": 1
        },
        "templates": [
          {
            "id": "tpl_refined_12",
            "name": "清透精修",
            "preview_url": "https://cdn.example.com/templates/refined_12.jpg",
            "before_url": "https://cdn.example.com/templates/refined_12_before.jpg",
            "after_url": "https://cdn.example.com/templates/refined_12_after.jpg",
            "enabled": true
          }
        ]
      },
      {
        "type": "atmosphere",
        "title": "氛围感修图",
        "required": false,
        "selection_mode": "single",
        "quota_cost": {
          "mode": "per_source",
          "units": 1
        },
        "templates": [
          {
            "id": "tpl_atmosphere_06",
            "name": "暖阳",
            "preview_url": "https://cdn.example.com/templates/atmosphere_06.jpg",
            "before_url": "https://cdn.example.com/templates/atmosphere_06_before.jpg",
            "after_url": "https://cdn.example.com/templates/atmosphere_06_after.jpg",
            "enabled": true
          }
        ]
      },
      {
        "type": "cover",
        "title": "封面风格模板",
        "required": true,
        "selection_mode": "single",
        "quota_cost": {
          "mode": "per_job",
          "units": 0
        },
        "templates": [
          {
            "id": "tpl_cover_03",
            "name": "旅行画册",
            "preview_url": "https://cdn.example.com/templates/cover_03.jpg",
            "before_url": "https://cdn.example.com/templates/cover_03_before.jpg",
            "after_url": "https://cdn.example.com/templates/cover_03_after.jpg",
            "enabled": true
          }
        ]
      }
    ],
    "quota": {
      "unit": "retouch_time",
      "remaining": 12,
      "reserved": 3,
      "display_text": "剩余 12 次",
      "updated_at": "2026-08-11T07:29:58.000Z"
    },
    "limits": {
      "minimum_source_count": 1,
      "maximum_source_count": 50,
      "cover_minimum_source_count": 4
    }
  }
}

设计要点:

  • 不再让 App 传 scenic_id,后端从相册归属景区获取可用模板。
  • 由后端返回 required 和可见分组,避免多端各写一套“4 张显示封面”规则。
  • preview_url 用于模板卡片缩略图;before_url 与 after_url 必须是同尺寸、同构图的配对图片,供客户端滑动对比。
  • 客户端可默认选中必选分组的第一个可用模板,可选分组默认不选。
  • 此接口用于 UI 配置;提交时后端仍必须根据真实素材 ID 重新校验。
  • 同一响应返回当前用户的剩余可用额度和每类输出的额度单价,弹窗无需再发起第二个额度请求。
  • quota.remaining 是扣除其他未完成任务已预占数量后、当前立即可用的额度;弹窗底部使用此值显示“剩余 N 次”。
  • 额度文案位于模板选择弹窗的固定底部区域,不随中间模板列表滚动。
  • quota.reserved 是当前用户其他未完成任务的预占额度,仅用于解释账户状态。
  • 客户端预估本次消耗时,对已选输出求和:per_source 类型为 source_count * units,per_job 类型为 units。封面始终为 0。
  • 本文档默认精修和氛围感每生成一张各消耗 1 次。如实际商业规则变更,后端只需调整 quota_cost,客户端不需改接口。

创建 AI 修图任务

POST /api/yf-handset-app/photog/travel-album/ai-retouch
Idempotency-Key: 9A7820CE-78AB-45C6-9E0F-5DF268995379
Content-Type: application/json

5.4.1 网格批量修图

{
  "user_equity_travel_id": "88",
  "scope": "batch",
  "source_material_ids": ["2031", "2032", "2033", "2034"],
  "outputs": [
    {
      "type": "refined",
      "template_id": "tpl_refined_12"
    },
    {
      "type": "atmosphere",
      "template_id": "tpl_atmosphere_06"
    },
    {
      "type": "cover",
      "template_id": "tpl_cover_03"
    }
  ]
}

5.4.2 预览页已有 AI 结果 Tab

{
  "user_equity_travel_id": "88",
  "scope": "all_variants",
  "source_material_ids": ["2031"],
  "outputs": [
    {
      "type": "atmosphere",
      "template_id": "tpl_atmosphere_09"
    }
  ]
}

已有精修或氛围感结果时,无论当前位于原图、精修后还是氛围感 Tab,精修和氛围感模板均为选填,但至少选择一种。outputs 只传本次选中的结果类型;缺失表示“本次不处理”,不表示删除或覆盖对应的已有结果。

5.4.3 只重新精修

{
  "user_equity_travel_id": "88",
  "scope": "refined_only",
  "source_material_ids": ["2031"],
  "outputs": [
    {
      "type": "refined",
      "template_id": "tpl_refined_18"
    }
  ]
}

5.4.4 只重新生成氛围感

{
  "user_equity_travel_id": "88",
  "scope": "atmosphere_only",
  "source_material_ids": ["2031"],
  "outputs": [
    {
      "type": "atmosphere",
      "template_id": "tpl_atmosphere_11"
    }
  ]
}

5.4.5 提交校验矩阵

scope 原图数 精修 氛围感 封面
batch 1 至 50 必选 可选 少于 4 张禁止;4 张及以上必选
all_variants 必须为 1 可选(与氛围感至少一项) 可选(与精修至少一项) 禁止
refined_only 必须为 1 必选 禁止 禁止
atmosphere_only 必须为 1 禁止 必选 禁止

另外:

  • source_material_ids 必须去重,且全部为 original 类型。
  • 模板必须启用、类型匹配,且适用于相册所属景区。
  • 后端必须使用提交时的最新额度计费规则重新计算消耗,不信任客户端的预估数值。
  • 封面输出不论首次生成、重试或任务结果如何,额度消耗始终为 0。
  • 每个输出槽位均采用 replace_on_success:成功后替换旧版本,失败保留旧版本。
  • 批量选中已有 AI 结果的原图时,允许重新生成,只覆盖本次 outputs 列出的类型。
  • 同一原图、同一槽位已有 queued/processing 任务时,整次请求返回 409 RETOUCH_TARGET_BUSY,并列出冲突项。

5.4.6 提交响应

HTTP 状态码:202 Accepted

{
  "code": 100000,
  "msg": "AI 修图任务已提交",
  "data": {
    "job": {
      "id": "job_01K2E4",
      "user_equity_travel_id": "88",
      "scope": "all_variants",
      "status": "queued",
      "source_material_ids": ["2031"],
      "progress": {
        "total": 2,
        "queued": 2,
        "processing": 0,
        "succeeded": 0,
        "failed": 0
      },
      "created_at": "2026-08-11T07:30:15.123Z",
      "started_at": null,
      "finished_at": null
    },
    "quota_reservation": {
      "before_remaining": 12,
      "reserved_units": 2,
      "remaining_after_reservation": 10,
      "cover_units": 0
    },
    "affected_projects": [
      {
        "id": "2031",
        "user_equity_travel_id": "88",
        "material_type": "original",
        "original_asset": {
          "id": "asset_8001",
          "url": "https://cdn.example.com/albums/88/IMG_1024.jpg",
          "thumbnail_url": "https://cdn.example.com/albums/88/IMG_1024_thumb.jpg",
          "file_name": "IMG_1024.jpg",
          "mime_type": "image/jpeg",
          "file_size": 4821931,
          "width": 4032,
          "height": 3024,
          "version": 1,
          "created_at": "2026-08-09T01:00:00.000Z"
        },
        "display_status": "pending",
        "variant_slots": [
          {
            "type": "refined",
            "asset": null,
            "latest_generation": {
              "job_id": "job_01K2E4",
              "status": "queued",
              "is_replacement": false,
              "template": {
                "id": "tpl_refined_15",
                "name": "自然精修"
              },
              "requested_at": "2026-08-11T07:30:15.123Z",
              "started_at": null,
              "finished_at": null,
              "error": null
            }
          },
          {
            "type": "atmosphere",
            "asset": null,
            "latest_generation": {
              "job_id": "job_01K2E4",
              "status": "queued",
              "is_replacement": false,
              "template": {
                "id": "tpl_atmosphere_09",
                "name": "暖阳"
              },
              "requested_at": "2026-08-11T07:30:15.123Z",
              "started_at": null,
              "finished_at": null,
              "error": null
            }
          }
        ],
        "revision": 8,
        "created_at": "2026-08-09T01:00:00.000Z",
        "updated_at": "2026-08-11T07:30:15.123Z"
      }
    ]
  }
}

必须返回 job.id、quota_reservation 和更新后的 affected_projects。客户端用 remaining_after_reservation 立即更新剩余额度,并更新 Cell 状态;已有 asset 的重修 Tab 可同步显示处理态,首次生成且 asset = null 的槽位不显示 Tab。

查询 AI 修图任务

GET /api/yf-handset-app/photog/travel-album/ai-retouch-job-info?user_equity_travel_id=88&job_id=job_01K2E4

响应:

{
  "code": 100000,
  "msg": "success",
  "data": {
    "id": "job_01K2E4",
    "user_equity_travel_id": "88",
    "scope": "batch",
    "status": "partially_succeeded",
    "source_material_ids": ["2031", "2032", "2033", "2034"],
    "progress": {
      "total": 9,
      "queued": 0,
      "processing": 0,
      "succeeded": 8,
      "failed": 1
    },
    "quota_settlement": {
      "status": "settled",
      "reserved_units": 8,
      "consumed_units": 7,
      "released_units": 1,
      "cover_units": 0
    },
    "targets": [
      {
        "source_material_id": "2031",
        "output_type": "refined",
        "status": "succeeded",
        "result_asset_id": "asset_9201",
        "error": null
      },
      {
        "source_material_id": "2032",
        "output_type": "atmosphere",
        "status": "failed",
        "result_asset_id": null,
        "error": {
          "code": "AI_PROVIDER_TIMEOUT",
          "message": "AI 服务处理超时,请重试",
          "retryable": true
        }
      },
      {
        "source_material_id": null,
        "output_type": "cover",
        "status": "succeeded",
        "result_material_id": "cover_301",
        "error": null
      }
    ],
    "created_at": "2026-08-11T07:30:15.123Z",
    "started_at": "2026-08-11T07:30:18.000Z",
    "finished_at": "2026-08-11T07:33:00.000Z"
  }
}
整体状态 含义
queued 已受理,尚无子任务开始
processing 至少一个子任务正在执行,且尚未全部完成
succeeded 所有子任务成功
partially_succeeded 子任务全部结束,且既有成功也有失败
failed 子任务全部结束,没有任何成功结果
canceled 任务因素材删除或管理操作被取消

额度结算规则:

  • 任务提交成功时先预占所有非封面子任务的额度,封面不进入预占。
  • 每个精修/氛围感子任务成功后,将对应预占转为实际消耗。
  • 子任务失败或取消时释放对应预占。因此部分成功示例中,预占 8 次、成功消耗 7 次、失败退回 1 次。
  • quota_settlement.status 取值为 reserved | partially_settled | settled。

客户端如只关心当前预览图,优先调用单素材接口;本接口主要用于批量进度、问题排查和任务详情。

批量删除素材

POST /api/yf-handset-app/photog/travel-album/delete-material
Content-Type: application/json

请求:

{
  "user_equity_travel_id": "88",
  "material_ids": ["2031", "2032", "cover_301"]
}

为兼容旧客户端,原单张请求体继续有效:

{
  "id": "2031"
}

新请求使用 user_equity_travel_id + material_ids,旧请求使用 id,两组参数不同时传入。

响应:

{
  "code": 100000,
  "msg": "删除成功",
  "data": {
    "deleted_material_ids": ["2031", "2032", "cover_301"],
    "deleted_variant_asset_ids": ["asset_9101", "asset_9102"],
    "canceled_job_ids": ["job_01K2E4"],
    "oss_cleanup_status": "scheduled"
  }
}

语义:

  • 传入原图 ID:级联软删除精修图、氛围感图,并取消该原图的未完成子任务。
  • 传入独立封面 ID:只删除该封面素材。
  • 删除原图不级联删除以它为输入之一的已生成封面。
  • 数据库业务删除采用一个事务,默认全部成功或全部失败。
  • 任一 ID 不属于当前相册或无权删除时,整次请求失败。已删除的 ID 可视为幂等成功。
  • OSS 文件清理异步执行,不影响业务删除成功。