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

591 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 速创生图接口调用示例
## 一、数据库配置说明
### 1. 执行SQL脚本
```bash
# 在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
```bash
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
```bash
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
```bash
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 示例
```javascript
// 文生图 - 正方形
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 示例
```python
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 单张参考图
```bash
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数组
```bash
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 示例
```javascript
// 图生图 - 单张参考图
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);
```
```javascript
// 图生图 - 多张参考图
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 示例
```python
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. 查询单个任务详情
```bash
curl -X GET "http://localhost:8081/user/ai/tasks/TASK-20251026153045123-4567" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
```
**响应示例:**
```json
{
"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. 查询任务列表(按类型筛选)
#### 查询所有文生图任务
```bash
curl -X GET "http://localhost:8081/user/ai/tasks/list?page=1&size=10&taskType=text_to_image" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
```
#### 查询所有图生图任务
```bash
curl -X GET "http://localhost:8081/user/ai/tasks/list?page=1&size=10&taskType=image_to_image" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
```
#### 查询所有生图任务(不区分类型)
```bash
curl -X GET "http://localhost:8081/user/ai/tasks/list?page=1&size=10&status=completed" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
```
### 3. JavaScript 轮询示例
```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", "一只可爱的柴犬");
```
---
## 六、查询积分余额
```bash
curl -X GET "http://localhost:8081/user/points/consumption/balance" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
```
**响应示例:**
```json
{
"code": 200,
"message": "success",
"data": {
"userId": 17563793187762127,
"balance": 850,
"expireTime": null
}
}
```
---
## 七、完整流程示例(前端实现)
```javascript
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 | 服务器错误 | 联系管理员 |
### 错误处理示例
```javascript
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 推送任务完成通知