# 消费凭证核验接口文档

## 概述

消费凭证核验接口提供用户上传消费凭证图片（小票、支付记录、订单截图等）的核验能力，系统使用视觉模型（Qwen3-VL-8B-Thinking）分析图片，判断是否为真实消费凭证。仅核验通过的用户才允许进行评论。

接口采用**异步非阻塞**设计，使用线程池执行模型调用，避免阻塞FastAPI事件循环，支持高并发场景。

### 基础URL

所有接口需要通过 **9000网关** 进行访问：

| 环境 | 基础URL |
|------|---------|
| 开发环境 | `http://localhost:9000/multimodal_services/api/v1/consumption-proof` |
| 生产环境 | `http://<gateway-host>:9000/multimodal_services/api/v1/consumption-proof` |

**Content-Type**: `application/json`

### 服务路由说明

- **网关端口**: 9000
- **服务名**: multimodal_services
- **服务端口**: 9009
- **API版本**: v1
- **接口前缀**: /consumption-proof

### 完整URL路径示例

| 接口 | 完整URL路径（通过网关） |
|------|------------------------|
| 消费凭证核验 | `http://localhost:9000/multimodal_services/api/v1/consumption-proof/verify` |

⚠️ **注意**: 请确保URL路径正确，避免重复路径段

---

## 接口列表

| 序号 | 接口 | 方法 | 路径 | 说明 |
|------|------|------|------|------|
| 1 | 消费凭证核验 | POST | `/verify` | 上传消费凭证图片URL列表，核验是否为真实凭证（可选：核验商户是否匹配） |

---

## 1. 消费凭证核验

### 请求

**POST** `/verify`

### 请求参数

| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|--------|------|------|--------|------|
| image_urls | string[] | 是 | - | 消费凭证图片URL列表（如小票、支付记录、订单截图等），1～10张 |
| store_name | string | 否 | "" | 店铺名；若填写则核验凭证中的商户/店铺是否与该店铺一致 |

### 请求示例

```json
{
    "image_urls": [
        "https://example.com/receipt1.jpg",
        "https://example.com/payment_record.png"
    ],
    "store_name": "某某餐厅"
}
```

---

### 响应参数

| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | integer | 响应状态码，200表示成功 |
| message | string | 响应消息 |
| data | object | 核验结果数据 |
| data.can_comment | boolean | 是否允许评论（仅当为真实消费凭证时为true） |
| data.is_valid_proof | boolean | 是否为真实消费凭证 |
| data.proof_type | string/null | 识别到的凭证类型，如"小票"、"支付记录"、"订单截图"等 |
| data.reason | string | 核验结论说明 |
| data.image_results | array | 每张图片的核验结果列表 |
| data.image_results[].image_index | integer | 图片序号（从1开始） |
| data.image_results[].is_valid_proof | boolean | 该图片是否为有效凭证 |
| data.image_results[].proof_type | string | 该图片识别到的凭证类型 |
| data.image_results[].confidence | string | 置信度，如"高"、"中"、"低" |
| data.image_results[].reason | string | 该图片的核验说明 |
| data.error | string | 异常或错误信息，成功时为空 |
| timestamp | float | 响应时间戳（Unix时间戳） |

### 成功响应示例

```json
{
    "code": 200,
    "message": "操作成功",
    "data": {
        "can_comment": true,
        "is_valid_proof": true,
        "proof_type": "小票",
        "reason": "图片为真实消费小票，信息清晰可辨，且商户名称与店铺名一致",
        "image_results": [
            {
                "image_index": 1,
                "is_valid_proof": true,
                "proof_type": "小票",
                "confidence": "高",
                "reason": "包含商户（某某餐厅）、金额、时间等消费信息"
            },
            {
                "image_index": 2,
                "is_valid_proof": false,
                "proof_type": "",
                "confidence": "",
                "reason": "图片模糊，无法识别有效信息"
            }
        ],
        "error": ""
    },
    "timestamp": 1704067200.123
}
```

### 失败响应示例

**参数校验失败（422）**

```json
{
    "code": 422,
    "message": "请求参数不合法",
    "data": null,
    "details": {
        "errors": [
            {
                "loc": ["image_urls"],
                "msg": "ensure this value has at least 1 items",
                "type": "value_error.list.min_items"
            }
        ]
    },
    "timestamp": 1704067200.456
}
```

**业务异常（400）**

```json
{
    "code": 400,
    "message": "图片URL列表为空",
    "data": null,
    "details": {
        "data": {
            "can_comment": false,
            "is_valid_proof": false,
            "proof_type": null,
            "reason": "",
            "image_results": [],
            "error": "图片URL列表为空"
        }
    },
    "timestamp": 1704067200.789
}
```

**服务异常（500）**

```json
{
    "code": 500,
    "message": "服务暂时不可用，请稍后重试",
    "data": null,
    "details": null,
    "timestamp": 1704067200.012
}
```

---

## 业务逻辑说明

### 核验流程

1. **参数校验**：检查image_urls是否为空，数量是否在1～10之间
2. **构建Prompt**：根据图片数量和店铺名构建核验提示词
3. **模型调用**：使用Qwen3-VL-8B-Thinking视觉模型分析图片（在线程池中执行，不阻塞事件循环）
4. **结果解析**：解析模型返回的JSON，提取核验结果
5. **结果判定**：
   - `is_valid_proof`为true时，`can_comment`为true，允许评论
   - `is_valid_proof`为false时，`can_comment`为false，不允许评论
   - 若填写了`store_name`，还会核验凭证中的商户名称是否与店铺名一致

### 支持的凭证类型

- 消费小票/发票
- 支付记录截图
- 订单截图
- 其他包含消费信息的凭证

### 模型判断依据

模型会分析图片中的以下内容：
- 商户名称（若填写store_name，核验是否匹配）
- 消费金额
- 交易时间
- 订单号/流水号
- 其他消费相关信息

## 注意事项

1. **网关访问**：所有接口必须通过9000网关访问，URL格式为 `http://<gateway>:9000/multimodal_services/api/v1/consumption-proof/...`，直接访问9009端口不推荐。
2. **图片要求**：
   - 图片URL必须可公开访问
   - 建议上传清晰、完整的凭证图片
   - 支持的图片格式：jpg、png等常见格式
3. **数量限制**：
   - 最少上传1张图片
   - 最多上传10张图片
4. **店铺名匹配**：
   - `store_name`参数为可选
   - 若填写，模型会核验凭证中的商户名称是否与该店铺名一致
   - 有助于确保用户确实在该店铺消费
5. **响应时间**：
   - 模型推理需要一定时间，请合理设置超时时间（建议10～30秒）
6. **幂等性**：
   - 该接口为查询类接口，可重复调用获取相同结果
