Files
1818web-hoduan/速创生图接口调用示例.md
2025-11-14 17:41:15 +08:00

16 KiB
Raw Blame History

速创生图接口调用示例

一、数据库配置说明

1. 执行SQL脚本

# 在MySQL中执行V9脚本
mysql -u root -p 1818ai < V9__add_suchuang_image_models.sql

2. 配置结果

执行后会在 points_config 表中插入以下模型:

文生图模型4个

model_name description points_cost task_type aspectRatio
sc_soraimg_text_auto 速创生图 文生图-自动比例 30 text_to_image auto
sc_soraimg_text_1x1 速创生图 文生图-正方形(1:1) 30 text_to_image 1:1
sc_soraimg_text_2x3 速创生图 文生图-竖图(2:3) 30 text_to_image 2:3
sc_soraimg_text_3x2 速创生图 文生图-横图(3:2) 30 text_to_image 3:2

图生图模型4个

model_name description points_cost task_type aspectRatio
sc_soraimg_img2img_auto 速创生图 图生图-自动比例 35 image_to_image auto
sc_soraimg_img2img_1x1 速创生图 图生图-正方形(1:1) 35 image_to_image 1:1
sc_soraimg_img2img_2x3 速创生图 图生图-竖图(2:3) 35 image_to_image 2:3
sc_soraimg_img2img_3x2 速创生图 图生图-横图(3:2) 35 image_to_image 3:2

二、接口调用示例

前提条件

  • 用户已登录,获得 JWT Token
  • 或使用 API Key 认证
  • 用户积分充足

基础URL

http://localhost:8081

三、文生图调用示例

1. cURL 示例

1.1 正方形图片1:1

curl -X POST "http://localhost:8081/user/ai/tasks/submit" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{
    "modelName": "sc_soraimg_text_1x1",
    "prompt": "一个可爱的橘猫在窗台上晒太阳,温馨的室内场景,柔和的光线"
  }'

1.2 横图3:2

curl -X POST "http://localhost:8081/user/ai/tasks/submit" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{
    "modelName": "sc_soraimg_text_3x2",
    "prompt": "壮丽的山脉日出,金色阳光洒满山谷,风景摄影风格"
  }'

1.3 竖图2:3

curl -X POST "http://localhost:8081/user/ai/tasks/submit" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{
    "modelName": "sc_soraimg_text_2x3",
    "prompt": "高耸的瀑布从山崖飞流而下,竖构图,气势磅礴"
  }'

2. JavaScript Fetch 示例

// 文生图 - 正方形
const response = await fetch("http://localhost:8081/user/ai/tasks/submit", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${YOUR_JWT_TOKEN}`
  },
  body: JSON.stringify({
    modelName: "sc_soraimg_text_1x1",
    prompt: "科幻风格的未来城市,霓虹灯光,赛博朋克风格"
  })
});

const result = await response.json();
console.log("任务编号:", result.data.taskNo);
console.log("任务状态:", result.data.status);

3. Python Requests 示例

import requests

url = "http://localhost:8081/user/ai/tasks/submit"
headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {YOUR_JWT_TOKEN}"
}
data = {
    "modelName": "sc_soraimg_text_1x1",
    "prompt": "梦幻的樱花树下,粉色花瓣飘落,动漫风格"
}

response = requests.post(url, json=data, headers=headers)
result = response.json()
print(f"任务编号: {result['data']['taskNo']}")
print(f"任务状态: {result['data']['status']}")

四、图生图调用示例

1. cURL 示例

1.1 单张参考图

curl -X POST "http://localhost:8081/user/ai/tasks/submit" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{
    "modelName": "sc_soraimg_img2img_1x1",
    "prompt": "把这张照片转换成可爱的卡通Q版潮玩形象保留原有特征增加萌趣感",
    "imageUrl": "https://oss-1818ai-user-img.oss-cn-hangzhou.aliyuncs.com/user123/photo.jpg"
  }'

1.2 多张参考图JSON数组

curl -X POST "http://localhost:8081/user/ai/tasks/submit" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{
    "modelName": "sc_soraimg_img2img_3x2",
    "prompt": "结合这些参考图的风格,创作一幅新的艺术作品",
    "imageUrl": "[\"https://example.com/ref1.jpg\",\"https://example.com/ref2.jpg\"]"
  }'

2. JavaScript Fetch 示例

// 图生图 - 单张参考图
const response = await fetch("http://localhost:8081/user/ai/tasks/submit", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${YOUR_JWT_TOKEN}`
  },
  body: JSON.stringify({
    modelName: "sc_soraimg_img2img_1x1",
    prompt: "将人物转换为油画风格,色彩浓郁,笔触明显",
    imageUrl: "https://oss-1818ai-user-img.oss-cn-hangzhou.aliyuncs.com/portrait.jpg"
  })
});

const result = await response.json();
console.log("任务编号:", result.data.taskNo);
// 图生图 - 多张参考图
const response = await fetch("http://localhost:8081/user/ai/tasks/submit", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${YOUR_JWT_TOKEN}`
  },
  body: JSON.stringify({
    modelName: "sc_soraimg_img2img_1x1",
    prompt: "融合多张参考图的元素,创作新设计",
    imageUrl: JSON.stringify([
      "https://example.com/ref1.jpg",
      "https://example.com/ref2.jpg",
      "https://example.com/ref3.jpg"
    ])
  })
});

3. Python Requests 示例

import requests
import json

# 图生图 - 单张参考图
url = "http://localhost:8081/user/ai/tasks/submit"
headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {YOUR_JWT_TOKEN}"
}
data = {
    "modelName": "sc_soraimg_img2img_1x1",
    "prompt": "将这张风景照转换为水彩画风格",
    "imageUrl": "https://oss-1818ai-user-img.oss-cn-hangzhou.aliyuncs.com/landscape.jpg"
}

response = requests.post(url, json=data, headers=headers)
result = response.json()

# 图生图 - 多张参考图
data_multi = {
    "modelName": "sc_soraimg_img2img_3x2",
    "prompt": "结合参考图风格创作新作品",
    "imageUrl": json.dumps([
        "https://example.com/ref1.jpg",
        "https://example.com/ref2.jpg"
    ])
}

response = requests.post(url, json=data_multi, headers=headers)

五、查询任务状态

1. 查询单个任务详情

curl -X GET "http://localhost:8081/user/ai/tasks/TASK-20251026153045123-4567" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

响应示例:

{
  "code": 200,
  "message": "success",
  "data": {
    "taskNo": "TASK-20251026153045123-4567",
    "modelName": "sc_soraimg_text_1x1",
    "status": "completed",
    "taskType": "text_to_image",
    "progress": 100,
    "promptSnippet": "一个可爱的橘猫在窗台上晒太阳...",
    "imageUrl": null,
    "resultUrl": "https://oss-1818ai-user-img.oss-cn-hangzhou.aliyuncs.com/results/image_xxx.png",
    "createTime": "2025-10-26T15:30:45",
    "completeTime": "2025-10-26T15:31:12",
    "errorMessage": null
  }
}

2. 查询任务列表(按类型筛选)

查询所有文生图任务

curl -X GET "http://localhost:8081/user/ai/tasks/list?page=1&size=10&taskType=text_to_image" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

查询所有图生图任务

curl -X GET "http://localhost:8081/user/ai/tasks/list?page=1&size=10&taskType=image_to_image" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

查询所有生图任务(不区分类型)

curl -X GET "http://localhost:8081/user/ai/tasks/list?page=1&size=10&status=completed" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

3. JavaScript 轮询示例

// 提交任务后轮询状态
async function submitAndPoll(modelName, prompt, imageUrl = null) {
  // 1. 提交任务
  const submitResponse = await fetch("http://localhost:8081/user/ai/tasks/submit", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": `Bearer ${YOUR_JWT_TOKEN}`
    },
    body: JSON.stringify({
      modelName,
      prompt,
      imageUrl
    })
  });
  
  const submitResult = await submitResponse.json();
  const taskNo = submitResult.data.taskNo;
  console.log(`任务已提交: ${taskNo}`);
  
  // 2. 轮询任务状态每5秒查询一次
  const pollInterval = setInterval(async () => {
    const statusResponse = await fetch(
      `http://localhost:8081/user/ai/tasks/${taskNo}`,
      {
        headers: {
          "Authorization": `Bearer ${YOUR_JWT_TOKEN}`
        }
      }
    );
    
    const statusResult = await statusResponse.json();
    const status = statusResult.data.status;
    const progress = statusResult.data.progress;
    
    console.log(`任务状态: ${status}, 进度: ${progress}%`);
    
    if (status === 'completed') {
      clearInterval(pollInterval);
      console.log(`任务完成!结果: ${statusResult.data.resultUrl}`);
      return statusResult.data.resultUrl;
    }
    
    if (status === 'failed') {
      clearInterval(pollInterval);
      console.error(`任务失败: ${statusResult.data.errorMessage}`);
      return null;
    }
  }, 5000);
}

// 使用示例
submitAndPoll("sc_soraimg_text_1x1", "一只可爱的柴犬");

六、查询积分余额

curl -X GET "http://localhost:8081/user/points/consumption/balance" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

响应示例:

{
  "code": 200,
  "message": "success",
  "data": {
    "userId": 17563793187762127,
    "balance": 850,
    "expireTime": null
  }
}

七、完整流程示例(前端实现)

class SuChuangImageGenerator {
  constructor(token, baseUrl = "http://localhost:8081") {
    this.token = token;
    this.baseUrl = baseUrl;
  }
  
  // 提交文生图任务
  async generateImage(prompt, aspectRatio = "1:1") {
    const modelMap = {
      "auto": "sc_soraimg_text_auto",
      "1:1": "sc_soraimg_text_1x1",
      "2:3": "sc_soraimg_text_2x3",
      "3:2": "sc_soraimg_text_3x2"
    };
    
    const response = await fetch(`${this.baseUrl}/user/ai/tasks/submit`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${this.token}`
      },
      body: JSON.stringify({
        modelName: modelMap[aspectRatio],
        prompt: prompt
      })
    });
    
    const result = await response.json();
    if (result.code === 200) {
      return result.data.taskNo;
    }
    throw new Error(result.message);
  }
  
  // 提交图生图任务
  async transformImage(prompt, imageUrl, aspectRatio = "1:1") {
    const modelMap = {
      "auto": "sc_soraimg_img2img_auto",
      "1:1": "sc_soraimg_img2img_1x1",
      "2:3": "sc_soraimg_img2img_2x3",
      "3:2": "sc_soraimg_img2img_3x2"
    };
    
    const response = await fetch(`${this.baseUrl}/user/ai/tasks/submit`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${this.token}`
      },
      body: JSON.stringify({
        modelName: modelMap[aspectRatio],
        prompt: prompt,
        imageUrl: imageUrl
      })
    });
    
    const result = await response.json();
    if (result.code === 200) {
      return result.data.taskNo;
    }
    throw new Error(result.message);
  }
  
  // 查询任务状态
  async getTaskStatus(taskNo) {
    const response = await fetch(`${this.baseUrl}/user/ai/tasks/${taskNo}`, {
      headers: {
        "Authorization": `Bearer ${this.token}`
      }
    });
    
    const result = await response.json();
    if (result.code === 200) {
      return result.data;
    }
    throw new Error(result.message);
  }
  
  // 等待任务完成(带超时)
  async waitForCompletion(taskNo, timeout = 180000) {
    const startTime = Date.now();
    
    return new Promise((resolve, reject) => {
      const interval = setInterval(async () => {
        try {
          const task = await this.getTaskStatus(taskNo);
          
          if (task.status === 'completed') {
            clearInterval(interval);
            resolve(task.resultUrl);
          } else if (task.status === 'failed') {
            clearInterval(interval);
            reject(new Error(task.errorMessage || '任务失败'));
          } else if (Date.now() - startTime > timeout) {
            clearInterval(interval);
            reject(new Error('任务超时'));
          }
        } catch (error) {
          clearInterval(interval);
          reject(error);
        }
      }, 5000);
    });
  }
  
  // 查询积分余额
  async getBalance() {
    const response = await fetch(`${this.baseUrl}/user/points/consumption/balance`, {
      headers: {
        "Authorization": `Bearer ${this.token}`
      }
    });
    
    const result = await response.json();
    if (result.code === 200) {
      return result.data.balance;
    }
    throw new Error(result.message);
  }
}

// 使用示例
const generator = new SuChuangImageGenerator(YOUR_JWT_TOKEN);

// 文生图
generator.generateImage("一只可爱的柴犬", "1:1")
  .then(taskNo => {
    console.log(`任务已提交: ${taskNo}`);
    return generator.waitForCompletion(taskNo);
  })
  .then(imageUrl => {
    console.log(`图片生成完成: ${imageUrl}`);
  })
  .catch(error => {
    console.error(`生成失败: ${error.message}`);
  });

// 图生图
generator.transformImage(
  "转换为卡通Q版风格",
  "https://example.com/photo.jpg",
  "1:1"
).then(taskNo => {
  console.log(`任务已提交: ${taskNo}`);
  return generator.waitForCompletion(taskNo);
}).then(imageUrl => {
  console.log(`图片转换完成: ${imageUrl}`);
});

八、错误处理

常见错误码

错误码 说明 解决方案
401 未登录或Token过期 重新登录获取Token
402 积分不足 充值积分
400 参数错误 检查请求参数
500 服务器错误 联系管理员

错误处理示例

try {
  const taskNo = await generator.generateImage("测试prompt", "1:1");
  const imageUrl = await generator.waitForCompletion(taskNo);
  console.log("成功:", imageUrl);
} catch (error) {
  if (error.message.includes("积分不足")) {
    console.error("请先充值积分");
    // 跳转到充值页面
  } else if (error.message.includes("未登录")) {
    console.error("请先登录");
    // 跳转到登录页面
  } else {
    console.error("生成失败:", error.message);
  }
}

九、注意事项

  1. 积分消耗

    • 文生图30积分/张
    • 图生图35积分/张
    • 任务提交时立即扣除积分
    • 任务失败会自动退还积分
  2. 图片URL要求

    • 必须是外网可访问的URL
    • 支持 https 和 http 协议
    • 建议使用自有OSS存储的URL
    • 图生图支持单张或多张参考图
  3. 结果存储

    • 生成的图片会自动转存到您的OSS
    • resultUrl 为永久有效的OSS链接
    • 第三方临时URL会被自动替换
  4. 任务状态

    • created: 已创建
    • queued: 排队中
    • processing: 生成中
    • completed: 已完成
    • failed: 失败
  5. 超时时间

    • 生图任务通常在 30-120 秒内完成
    • 建议轮询间隔: 5秒
    • 建议超时时间: 180秒

十、技术支持

如有问题,请联系技术支持或查看服务器日志:

  • 日志会记录完整的提交负载和API响应
  • 错误信息统一为中文,不会乱码
  • 支持 WebSocket 推送任务完成通知