# 豆包垃圾分析接口文档

## 接口概述

本接口基于火山引擎豆包AI模型，提供垃圾车辆图片分析功能。通过上传多张垃圾车辆图片，AI会自动识别车棚状态、垃圾类型、轻物质和重物质占比等信息。

**接口路径：** `/douBao/analyzeGarbage`  
**请求方式：** `POST`  
**Content-Type：** `application/json`

---

## 请求参数

### 请求体（GarbageAnalysisParam）

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| imageUrls | List&lt;String&gt; | 是 | 图片URL列表，支持多张图片，至少需要一张 |
| orderSn | String | 否 | 订单号，用于关联订单信息 |
| remark | String | 否 | 备注信息，可提供额外的分析上下文 |

### 参数说明

- **imageUrls**：图片URL列表，支持HTTP/HTTPS协议的图片链接。建议使用可公开访问的图片URL。
- **orderSn**：订单号，用于在分析结果中关联订单信息，便于后续查询和追踪。
- **remark**：备注信息，可以包含订单相关的额外信息，如装货地点、卸货地点等，有助于AI更准确地进行分析。

---

## 响应结果

### 响应体（GarbageAnalysisResult）

| 字段名 | 类型 | 说明 |
|--------|------|------|
| isShedOpened | Boolean | 车棚是否完全打开。true表示已打开，false表示未打开 |
| details | String | 明细信息，车厢内包含的物品列表。格式：物品1(数量描述),物品2(数量描述)，例如：石块(多),木材(少) |
| lightMaterialPercentage | BigDecimal | 轻物质占比（百分比，0-100） |
| heavyMaterialPercentage | BigDecimal | 重物质占比（百分比，0-100） |
| garbageType | String | 垃圾类型，可能的值：拆除垃圾、装修垃圾、抛货 |
| judgmentBasis | String | 判断依据，说明AI判断垃圾类型的原因 |
| analysisTime | Long | 分析时间戳（毫秒） |
| rawResponse | String | AI原始响应内容，用于调试和问题排查 |
| garbageTypes | List&lt;GarbageTypeInfo&gt; | 垃圾类型分析列表（保留字段，用于兼容） |
| totalWeight | BigDecimal | 总重量（单位：千克）（保留字段，用于兼容） |

### GarbageTypeInfo 对象结构（保留字段）

| 字段名 | 类型 | 说明 |
|--------|------|------|
| typeName | String | 垃圾类型名称 |
| category | String | 具体垃圾种类 |
| judgmentBasis | String | 判断依据 |
| percentage | BigDecimal | 占比（百分比，0-100） |
| weight | BigDecimal | 估算重量（单位：千克） |

---

## 请求示例

### 场景一：最小参数（仅图片URL）

**适用场景：** 快速测试，仅提供必要的图片URL

```json
{
  "imageUrls": [
    "https://example.com/garbage-truck-1.jpg"
  ]
}
```

**cURL 命令：**
```bash
curl -X POST "http://localhost:8080/douBao/analyzeGarbage" \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrls": [
      "https://example.com/garbage-truck-1.jpg"
    ]
  }'
```

---

### 场景二：单张图片 + 订单号

**适用场景：** 关联订单信息

```json
{
  "imageUrls": [
    "https://example.com/garbage-truck-1.jpg"
  ],
  "orderSn": "ORD20240101001"
}
```

**cURL 命令：**
```bash
curl -X POST "http://localhost:8080/douBao/analyzeGarbage" \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrls": [
      "https://example.com/garbage-truck-1.jpg"
    ],
    "orderSn": "ORD20240101001"
  }'
```

---

### 场景三：多张图片（推荐）

**适用场景：** 从不同角度拍摄，提高分析准确性

```json
{
  "imageUrls": [
    "https://example.com/garbage-truck-front.jpg",
    "https://example.com/garbage-truck-side.jpg",
    "https://example.com/garbage-truck-back.jpg"
  ],
  "orderSn": "ORD20240101001",
  "remark": "装货地点：南京市建邺区，卸货地点：南京市江宁区"
}
```

**cURL 命令：**
```bash
curl -X POST "http://localhost:8080/douBao/analyzeGarbage" \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrls": [
      "https://example.com/garbage-truck-front.jpg",
      "https://example.com/garbage-truck-side.jpg",
      "https://example.com/garbage-truck-back.jpg"
    ],
    "orderSn": "ORD20240101001",
    "remark": "装货地点：南京市建邺区，卸货地点：南京市江宁区"
  }'
```

---

### 场景四：完整参数示例

**适用场景：** 生产环境，包含所有可选信息

```json
{
  "imageUrls": [
    "https://cdn.example.com/orders/2024/01/01/truck-front-001.jpg",
    "https://cdn.example.com/orders/2024/01/01/truck-side-001.jpg"
  ],
  "orderSn": "ORD20240101001",
  "remark": "订单编号：ORD20240101001；装货地点：南京市建邺区奥体中心；卸货地点：南京市江宁区垃圾处理厂；装货时间：2024-01-01 10:00:00"
}
```

**cURL 命令：**
```bash
curl -X POST "http://localhost:8080/douBao/analyzeGarbage" \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrls": [
      "https://cdn.example.com/orders/2024/01/01/truck-front-001.jpg",
      "https://cdn.example.com/orders/2024/01/01/truck-side-001.jpg"
    ],
    "orderSn": "ORD20240101001",
    "remark": "订单编号：ORD20240101001；装货地点：南京市建邺区奥体中心；卸货地点：南京市江宁区垃圾处理厂；装货时间：2024-01-01 10:00:00"
  }'
```

---

### Java 示例

#### 方式一：使用链式调用（推荐）

```java
import com.njzscloud.supervisory.doubao.param.GarbageAnalysisParam;
import com.njzscloud.supervisory.doubao.result.GarbageAnalysisResult;
import com.njzscloud.common.core.utils.R;
import java.util.Arrays;

// 最小参数
GarbageAnalysisParam param1 = new GarbageAnalysisParam()
    .setImageUrls(Arrays.asList("https://example.com/garbage-truck-1.jpg"));

// 完整参数
GarbageAnalysisParam param2 = new GarbageAnalysisParam()
    .setImageUrls(Arrays.asList(
        "https://example.com/garbage-truck-front.jpg",
        "https://example.com/garbage-truck-side.jpg"
    ))
    .setOrderSn("ORD20240101001")
    .setRemark("装货地点：南京市建邺区，卸货地点：南京市江宁区");

R<GarbageAnalysisResult> result = douBaoController.analyzeGarbage(param2);
if (result.getCode() == 200) {
    GarbageAnalysisResult data = result.getData();
    System.out.println("车棚状态：" + (data.getIsShedOpened() ? "已打开" : "未打开"));
    System.out.println("垃圾类型：" + data.getGarbageType());
    System.out.println("轻物质占比：" + data.getLightMaterialPercentage() + "%");
    System.out.println("重物质占比：" + data.getHeavyMaterialPercentage() + "%");
}
```

#### 方式二：传统方式

```java
GarbageAnalysisParam param = new GarbageAnalysisParam();
param.setImageUrls(Arrays.asList(
    "https://example.com/garbage-truck-1.jpg",
    "https://example.com/garbage-truck-2.jpg"
));
param.setOrderSn("ORD20240101001");
param.setRemark("装货地点：南京市建邺区，卸货地点：南京市江宁区");

R<GarbageAnalysisResult> result = douBaoController.analyzeGarbage(param);
```

---

### JavaScript/Axios 示例

```javascript
// 使用 fetch
fetch('http://localhost:8080/douBao/analyzeGarbage', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    imageUrls: [
      'https://example.com/garbage-truck-1.jpg',
      'https://example.com/garbage-truck-2.jpg'
    ],
    orderSn: 'ORD20240101001',
    remark: '装货地点：南京市建邺区，卸货地点：南京市江宁区'
  })
})
.then(response => response.json())
.then(data => {
  if (data.code === 200) {
    console.log('分析成功：', data.data);
    console.log('车棚状态：', data.data.isShedOpened ? '已打开' : '未打开');
    console.log('垃圾类型：', data.data.garbageType);
  } else {
    console.error('分析失败：', data.msg);
  }
})
.catch(error => console.error('请求错误：', error));

// 使用 axios
import axios from 'axios';

const analyzeGarbage = async () => {
  try {
    const response = await axios.post('http://localhost:8080/douBao/analyzeGarbage', {
      imageUrls: [
        'https://example.com/garbage-truck-1.jpg',
        'https://example.com/garbage-truck-2.jpg'
      ],
      orderSn: 'ORD20240101001',
      remark: '装货地点：南京市建邺区，卸货地点：南京市江宁区'
    });
    
    if (response.data.code === 200) {
      console.log('分析结果：', response.data.data);
    }
  } catch (error) {
    console.error('请求失败：', error);
  }
};
```

---

### Postman/Apifox 测试配置

#### 请求配置
- **请求方式：** `POST`
- **请求URL：** `http://localhost:8080/douBao/analyzeGarbage`
- **Headers：**
  - `Content-Type: application/json`

#### Body（raw JSON）示例

**示例1：最小参数**
```json
{
  "imageUrls": [
    "https://example.com/garbage-truck-1.jpg"
  ]
}
```

**示例2：完整参数**
```json
{
  "imageUrls": [
    "https://example.com/garbage-truck-front.jpg",
    "https://example.com/garbage-truck-side.jpg",
    "https://example.com/garbage-truck-back.jpg"
  ],
  "orderSn": "ORD20240101001",
  "remark": "装货地点：南京市建邺区奥体中心；卸货地点：南京市江宁区垃圾处理厂"
}
```

---

### Python 示例

```python
import requests
import json

url = "http://localhost:8080/douBao/analyzeGarbage"

# 最小参数
payload1 = {
    "imageUrls": [
        "https://example.com/garbage-truck-1.jpg"
    ]
}

# 完整参数
payload2 = {
    "imageUrls": [
        "https://example.com/garbage-truck-front.jpg",
        "https://example.com/garbage-truck-side.jpg"
    ],
    "orderSn": "ORD20240101001",
    "remark": "装货地点：南京市建邺区，卸货地点：南京市江宁区"
}

headers = {
    "Content-Type": "application/json"
}

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

if result.get("code") == 200:
    data = result.get("data")
    print(f"车棚状态：{'已打开' if data.get('isShedOpened') else '未打开'}")
    print(f"垃圾类型：{data.get('garbageType')}")
    print(f"轻物质占比：{data.get('lightMaterialPercentage')}%")
    print(f"重物质占比：{data.get('heavyMaterialPercentage')}%")
else:
    print(f"分析失败：{result.get('msg')}")
```

---

### 测试图片URL说明

**注意：** 实际测试时，请替换为真实可访问的图片URL。图片URL需要满足以下条件：

1. **可公开访问**：图片URL必须可以通过HTTP/HTTPS协议直接访问
2. **支持格式**：建议使用 JPG、PNG 等常见图片格式
3. **图片质量**：建议图片清晰，能够清楚看到车辆和垃圾内容
4. **推荐来源**：
   - OSS对象存储（如阿里云OSS、腾讯云COS等）
   - CDN加速域名
   - 公网可访问的图片服务器

**测试用占位图片（仅供参考，实际使用时请替换）：**
```
https://via.placeholder.com/800x600.jpg?text=Garbage+Truck+Front
https://via.placeholder.com/800x600.jpg?text=Garbage+Truck+Side
```

---

### 本地开发环境测试

如果是在本地开发环境测试，请确保：

1. **服务已启动**：确保Spring Boot应用已启动
2. **端口正确**：默认端口通常是 `8080`，请根据实际配置调整
3. **跨域配置**：如果前端调用，可能需要配置CORS
4. **完整URL示例**：
   - 本地：`http://localhost:8080/douBao/analyzeGarbage`
   - 开发环境：`http://dev.example.com:8080/douBao/analyzeGarbage`
   - 生产环境：`https://api.example.com/douBao/analyzeGarbage`

---

## 响应示例

### 成功响应（车棚已打开）

```json
{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "isShedOpened": true,
    "details": "石块(多),木材(少)",
    "lightMaterialPercentage": 10.00,
    "heavyMaterialPercentage": 90.00,
    "garbageType": "拆除垃圾",
    "judgmentBasis": "车厢内主要为石块,这类垃圾多来自建筑物拆除等工程",
    "analysisTime": 1704067200000,
    "rawResponse": "明细:石块(多),木材(少);轻物质:10%;重物质:90%;垃圾类型:拆除垃圾;判断依据:车厢内主要为石块,这类垃圾多来自建筑物拆除等工程",
    "garbageTypes": null,
    "totalWeight": null
  }
}
```

### 成功响应（车棚未打开）

```json
{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "isShedOpened": false,
    "details": "未打开车棚",
    "lightMaterialPercentage": null,
    "heavyMaterialPercentage": null,
    "garbageType": null,
    "judgmentBasis": null,
    "analysisTime": 1704067200000,
    "rawResponse": "未打开车棚",
    "garbageTypes": null,
    "totalWeight": null
  }
}
```

### 错误响应

```json
{
  "code": 500,
  "msg": "垃圾分析失败：垃圾分析参数不能为空，且必须包含至少一张图片URL",
  "data": null
}
```

---

## 错误码说明

| 错误码 | 说明 |
|--------|------|
| 200 | 请求成功 |
| 400 | 请求参数错误（如：图片URL列表为空） |
| 500 | 服务器内部错误（如：AI服务调用失败、解析失败等） |

---

## 业务逻辑说明

### 分析流程

1. **车棚状态检测**：AI首先判断车棚是否完全打开
   - 如果车棚未完全打开，直接返回"未打开车棚"，不进行后续分析
   - 如果车棚已打开，继续执行垃圾分析

2. **垃圾识别**（仅当车棚已打开时）：
   - 识别车厢内包含的物品类型和数量
   - 如果有多辆车，只分析画面中间的车辆
   - 分析轻物质和重物质的占比（百分比，0-100，两者之和应为100%）
   - 判断垃圾类型：拆除垃圾、装修垃圾或抛货
   - 提供判断依据说明

### 垃圾类型说明

- **拆除垃圾**：主要来自建筑物拆除等工程，通常包含大量石块、混凝土块等重物质
- **装修垃圾**：主要来自室内装修，通常包含白色板材、泡沫、木棍等轻物质
- **抛货**：其他类型的垃圾

---

## 注意事项

1. **图片要求**：
   - 图片URL必须可公开访问
   - 支持HTTP/HTTPS协议
   - 建议图片清晰，能够清楚看到车辆和垃圾内容
   - 支持多张图片，建议从不同角度拍摄

2. **性能考虑**：
   - AI分析需要一定时间，建议设置合理的超时时间
   - 图片数量越多，分析时间可能越长

3. **数据准确性**：
   - AI分析结果仅供参考，建议结合人工审核
   - 如果分析结果不准确，可以通过 `rawResponse` 字段查看AI原始响应进行排查

4. **字段说明**：
   - `garbageTypes` 和 `totalWeight` 为保留字段，当前版本可能为null
   - `isShedOpened` 为false时，其他分析字段（如 `garbageType`、`lightMaterialPercentage` 等）可能为null

5. **格式要求**：
   - AI返回的格式为固定格式，解析失败时会记录警告日志
   - 如果解析结果不完整，建议查看 `rawResponse` 字段获取原始响应

---

## 更新日志

| 版本 | 日期 | 更新内容 |
|------|------|----------|
| 1.0.0 | 2024-01-01 | 初始版本，支持垃圾车辆图片分析功能 |

---

## 联系方式

如有问题或建议，请联系开发团队。

