# 标签模块接口对接文档

## 1. 接口概述

标签模块提供了一系列RESTful API接口，用于标签模板的管理、标签的触发检查、生成、预览和打印。本文档详细描述了这些接口的使用方法、请求参数和响应格式。

### 1.1 接口基础信息

- **基础URL**：`http://{服务器地址}:{端口}/api/tags`
- **测试环境请求地址**：`http://172.232.21.79:5002`
- **正式环境请求地址**：`https://lr.tooexp.com`
- **请求方式**：POST/GET/PUT/DELETE
- **数据格式**：JSON
- **响应格式**：JSON

### 1.2 状态码说明

| 状态码 | 描述 |
|-------|------|
| 200 | 操作成功 |
| 400 | 请求参数错误或操作失败 |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |

### 1.3 错误码说明

| 错误码 | 描述 |
|-------|------|
| 0 | 操作成功 |
| 1001 | 标签模板不存在 |
| 1002 | 标签触发条件不满足 |
| 1003 | 标签生成失败 |
| 1004 | 标签渲染失败 |
| 9999 | 系统内部错误 |

## 2. 接口详细说明

### 2.1 标签模板管理

#### 2.1.1 获取标签模板列表

**接口路径**：`/templates`
**请求方法**：GET
**功能描述**：获取所有标签模板列表

**请求参数**：无

**响应格式**：

**成功响应**：

```json
{
  "code": 0,
  "message": "获取成功",
  "data": [
    {
      "id": 1,
      "tagType": "STOP",
      "name": "Stop标签",
      "templateConfig": "{\"width\": 4, \"height\": 6, \"elements\": [...]}",
      "triggerRule": "{\"type\": \"time\", \"days\": 5}",
      "isActive": true,
      "createdAt": "2026-01-30T10:00:00Z",
      "updatedAt": "2026-01-30T10:00:00Z"
    }
  ]
}
```

**失败响应**：

```json
{
  "code": 9999,
  "message": "系统内部错误"
}
```

#### 2.1.2 创建标签模板

**接口路径**：`/templates`
**请求方法**：POST
**功能描述**：创建新的标签模板

**请求参数**：

| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| tagType | string | 是 | 标签类型 | "STOP" |
| name | string | 是 | 标签名称 | "Stop标签" |
| templateConfig | string | 是 | 模板配置（JSON格式） | "{\"width\": 4, \"height\": 6, \"elements\": [...]}" |
| triggerRule | string | 是 | 触发规则（JSON格式） | "{\"type\": \"time\", \"days\": 5}" |
| isActive | bool | 否 | 是否启用，默认true | true |

**请求示例**：

```json
{
  "tagType": "STOP",
  "name": "Stop标签",
  "templateConfig": "{\"width\": 4, \"height\": 6, \"elements\": [{\"type\": \"text\", \"content\": \"Stop\", \"x\": 0.5, \"y\": 0.5, \"fontSize\": 24, \"bold\": true}, {\"type\": \"text\", \"content\": \"${neutralWaybillNumber}\", \"x\": 0.5, \"y\": 1.5, \"fontSize\": 12}, {\"type\": \"barcode\", \"content\": \"${neutralWaybillNumber}\", \"x\": 0.5, \"y\": 2.0, \"width\": 3.0, \"height\": 1.0, \"symbology\": \"CODE128\"}, {\"type\": \"text\", \"content\": \"Customer: ${customerId}\", \"x\": 0.5, \"y\": 3.5, \"fontSize\": 10}]}",
  "triggerRule": "{\"type\": \"time\", \"days\": 5}",
  "isActive": true
}
```

**响应格式**：

**成功响应**：

```json
{
  "code": 0,
  "message": "创建成功",
  "data": {
    "id": 1,
    "tagType": "STOP",
    "name": "Stop标签",
    "templateConfig": "{\"width\": 4, \"height\": 6, \"elements\": [...]}",
    "triggerRule": "{\"type\": \"time\", \"days\": 5}",
    "isActive": true,
    "createdAt": "2026-01-30T10:00:00Z",
    "updatedAt": "2026-01-30T10:00:00Z"
  }
}
```

**失败响应**：

```json
{
  "code": 400,
  "message": "标签类型已存在"
}
```

#### 2.1.3 更新标签模板

**接口路径**：`/templates/{id}`
**请求方法**：PUT
**功能描述**：更新指定的标签模板

**请求参数**：

| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| id | int | 是 | 模板ID（路径参数） | 1 |
| name | string | 否 | 标签名称 | "Stop标签（更新）" |
| templateConfig | string | 否 | 模板配置（JSON格式） | "{\"width\": 4, \"height\": 6, \"elements\": [...]}" |
| triggerRule | string | 否 | 触发规则（JSON格式） | "{\"type\": \"time\", \"days\": 5}" |
| isActive | bool | 否 | 是否启用 | true |

**请求示例**：

```json
{
  "name": "Stop标签（更新）",
  "templateConfig": "{\"width\": 4, \"height\": 6, \"elements\": [...]}",
  "isActive": true
}
```

**响应格式**：

**成功响应**：

```json
{
  "code": 0,
  "message": "更新成功",
  "data": {
    "id": 1,
    "tagType": "STOP",
    "name": "Stop标签（更新）",
    "templateConfig": "{\"width\": 4, \"height\": 6, \"elements\": [...]}",
    "triggerRule": "{\"type\": \"time\", \"days\": 5}",
    "isActive": true,
    "createdAt": "2026-01-30T10:00:00Z",
    "updatedAt": "2026-01-30T11:00:00Z"
  }
}
```

**失败响应**：

```json
{
  "code": 1001,
  "message": "标签模板不存在"
}
```

#### 2.1.4 删除标签模板

**接口路径**：`/templates/{id}`
**请求方法**：DELETE
**功能描述**：删除指定的标签模板

**请求参数**：

| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| id | int | 是 | 模板ID（路径参数） | 1 |

**响应格式**：

**成功响应**：

```json
{
  "code": 0,
  "message": "删除成功"
}
```

**失败响应**：

```json
{
  "code": 1001,
  "message": "标签模板不存在"
}
```

### 2.2 标签触发与生成

#### 2.2.1 检查标签触发

**接口路径**：`/check-trigger`
**请求方法**：POST
**功能描述**：检查是否触发指定类型的标签

**请求参数**：

| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| neutralWaybillNumber | string | 是 | 中性单号 | "1234567890" |
| customerId | int | 是 | 客户编码 | 123 |
| tagTypes | array[string] | 是 | 标签类型列表 | ["STOP"] |

**请求示例**：

```json
{
  "neutralWaybillNumber": "1234567890",
  "customerId": 123,
  "tagTypes": ["STOP"]
}
```

**响应格式**：

**成功响应**：

```json
{
  "code": 0,
  "message": "检查成功",
  "data": {
    "shouldTrigger": true,
    "triggerType": "STOP"
  }
}
```

**失败响应**：

```json
{
  "code": 1002,
  "message": "标签触发条件不满足"
}
```

#### 2.2.2 生成标签

**接口路径**：`/generate`
**请求方法**：POST
**功能描述**：生成指定类型的标签

**请求参数**：

| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| tagType | string | 是 | 标签类型 | "STOP" |
| neutralWaybillNumber | string | 是 | 中性单号 | "1234567890" |
| customerId | int | 是 | 客户编码 | 123 |

**请求示例**：

```json
{
  "tagType": "STOP",
  "neutralWaybillNumber": "1234567890",
  "customerId": 123
}
```

**响应格式**：

**成功响应**：

```json
{
  "code": 0,
  "message": "生成成功",
  "data": {
    "id": 1,
    "tagType": "STOP",
    "templateId": 1,
    "neutralWaybillNumber": "1234567890",
    "customerId": 123,
    "status": "ACTIVE",
    "triggerTime": "2026-01-30T10:00:00Z",
    "createdAt": "2026-01-30T10:00:00Z",
    "updatedAt": "2026-01-30T10:00:00Z"
  }
}
```

**失败响应**：

```json
{
  "code": 1003,
  "message": "标签生成失败"
}
```

### 2.3 标签渲染

#### 2.3.1 渲染为HTML（预览）

**接口路径**：`/render/html`
**请求方法**：POST
**功能描述**：将标签渲染为HTML格式，用于预览

**请求参数**：

| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| templateId | int | 是 | 模板ID | 1 |
| data | object | 是 | 标签数据 | {"neutralWaybillNumber": "1234567890", "customerId": 123} |

**请求示例**：

```json
{
  "templateId": 1,
  "data": {
    "neutralWaybillNumber": "1234567890",
    "customerId": 123
  }
}
```

**响应格式**：

**成功响应**：

```json
{
  "code": 0,
  "message": "渲染成功",
  "data": {
    "html": "<div style='width:4in; height:6in; border:1px solid black; padding:0.25in;'><div style='position:absolute; left:0.5in; top:0.5in; font-size:24pt; font-weight:bold;'>Stop</div><div style='position:absolute; left:0.5in; top:1.5in; font-size:12pt;'>1234567890</div><div style='position:absolute; left:0.5in; top:2.0in; width:3.0in; height:1.0in;'><img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA...' style='width:100%; height:100%;' /></div><div style='position:absolute; left:0.5in; top:3.5in; font-size:10pt;'>Customer: 123</div></div>"
  }
}
```

**失败响应**：

```json
{
  "code": 1004,
  "message": "标签渲染失败"
}
```

#### 2.3.2 渲染为ZPL（打印）

**接口路径**：`/render/zpl`
**请求方法**：POST
**功能描述**：将标签渲染为ZPL格式，用于打印

**请求参数**：

| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| templateId | int | 是 | 模板ID | 1 |
| data | object | 是 | 标签数据 | {"neutralWaybillNumber": "1234567890", "customerId": 123} |

**请求示例**：

```json
{
  "templateId": 1,
  "data": {
    "neutralWaybillNumber": "1234567890",
    "customerId": 123
  }
}
```

**响应格式**：

**成功响应**：

```json
{
  "code": 0,
  "message": "渲染成功",
  "data": {
    "zpl": "^XA^CWZ,E:TT0003M_.FNT^FS^FO100,100^A0N,48,48^FDStop^FS^FO100,200^A0N,24,24^FD1234567890^FS^FO100,300^BY3^BCN,100,Y,N,N^FD1234567890^FS^FO100,450^A0N,20,20^FDCustomer: 123^FS^XZ"
  }
}
```

**失败响应**：

```json
{
  "code": 1004,
  "message": "标签渲染失败"
}
```

### 2.4 标签实例管理

#### 2.4.1 获取标签实例列表

**接口路径**：`/instances`
**请求方法**：GET
**功能描述**：获取标签实例列表

**请求参数**：

| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| neutralWaybillNumber | string | 否 | 中性单号 | "1234567890" |
| customerId | int | 否 | 客户编码 | 123 |
| tagType | string | 否 | 标签类型 | "STOP" |
| status | string | 否 | 状态 | "ACTIVE" |
| page | int | 否 | 页码，默认1 | 1 |
| pageSize | int | 否 | 每页大小，默认10 | 10 |

**响应格式**：

**成功响应**：

```json
{
  "code": 0,
  "message": "获取成功",
  "data": {
    "items": [
      {
        "id": 1,
        "tagType": "STOP",
        "templateId": 1,
        "neutralWaybillNumber": "1234567890",
        "customerId": 123,
        "status": "ACTIVE",
        "triggerTime": "2026-01-30T10:00:00Z",
        "createdAt": "2026-01-30T10:00:00Z",
        "updatedAt": "2026-01-30T10:00:00Z"
      }
    ],
    "total": 1,
    "page": 1,
    "pageSize": 10
  }
}
```

**失败响应**：

```json
{
  "code": 9999,
  "message": "系统内部错误"
}
```

#### 2.4.2 获取标签实例详情

**接口路径**：`/instances/{id}`
**请求方法**：GET
**功能描述**：获取指定标签实例的详细信息

**请求参数**：

| 参数名 | 类型 | 必填 | 描述 | 示例值 |
|-------|------|------|------|--------|
| id | long | 是 | 实例ID（路径参数） | 1 |

**响应格式**：

**成功响应**：

```json
{
  "code": 0,
  "message": "获取成功",
  "data": {
    "id": 1,
    "tagType": "STOP",
    "templateId": 1,
    "neutralWaybillNumber": "1234567890",
    "customerId": 123,
    "status": "ACTIVE",
    "triggerTime": "2026-01-30T10:00:00Z",
    "createdAt": "2026-01-30T10:00:00Z",
    "updatedAt": "2026-01-30T10:00:00Z"
  }
}
```

**失败响应**：

```json
{
  "code": 404,
  "message": "标签实例不存在"
}
```

## 3. 接口调用示例

### 3.1 使用cURL调用

#### 3.1.1 检查标签触发

```bash
curl -X POST "http://172.232.21.79:5002/api/tags/check-trigger" \
  -H "Content-Type: application/json" \
  -d '{"neutralWaybillNumber": "1234567890", "customerId": 123, "tagTypes": ["STOP"]}'
```

#### 3.1.2 生成标签

```bash
curl -X POST "http://172.232.21.79:5002/api/tags/generate" \
  -H "Content-Type: application/json" \
  -d '{"tagType": "STOP", "neutralWaybillNumber": "1234567890", "customerId": 123}'
```

#### 3.1.3 渲染标签为HTML

```bash
curl -X POST "http://172.232.21.79:5002/api/tags/render/html" \
  -H "Content-Type: application/json" \
  -d '{"templateId": 1, "data": {"neutralWaybillNumber": "1234567890", "customerId": 123}}'
```

### 3.2 使用PowerShell调用

#### 3.2.1 检查标签触发

```powershell
Invoke-RestMethod -Uri "http://172.232.21.79:5002/api/tags/check-trigger" `
  -Method POST `
  -ContentType "application/json" `
  -Body '{"neutralWaybillNumber": "1234567890", "customerId": 123, "tagTypes": ["STOP"]}'
```

#### 3.2.2 生成标签

```powershell
Invoke-RestMethod -Uri "http://172.232.21.79:5002/api/tags/generate" `
  -Method POST `
  -ContentType "application/json" `
  -Body '{"tagType": "STOP", "neutralWaybillNumber": "1234567890", "customerId": 123}'
```

#### 3.2.3 渲染标签为HTML

```powershell
Invoke-RestMethod -Uri "http://172.232.21.79:5002/api/tags/render/html" `
  -Method POST `
  -ContentType "application/json" `
  -Body '{"templateId": 1, "data": {"neutralWaybillNumber": "1234567890", "customerId": 123}}'
```

## 4. 业务流程示例

### 4.1 STOP标签触发流程

1. **扫描中性单号**：前端扫描中性单号，获取扫描时间T
2. **检查触发条件**：前端调用 `/check-trigger` 接口，检查是否触发STOP标签
3. **后端计算**：后端查询第一次扫描时间T，计算T+5截止时间，检查是否有尾程标签
4. **触发标签**：如果超过T+5且无尾程标签，后端返回触发信号
5. **生成标签**：前端调用 `/generate` 接口，生成STOP标签
6. **渲染预览**：前端调用 `/render/html` 接口，预览标签效果
7. **打印标签**：前端调用 `/render/zpl` 接口，获取ZPL格式并打印标签

### 4.2 流程示例

```
# 1. 检查是否触发STOP标签
POST /api/tags/check-trigger
{
  "neutralWaybillNumber": "1234567890",
  "customerId": 123,
  "tagTypes": ["STOP"]
}

# 2. 生成STOP标签
POST /api/tags/generate
{
  "tagType": "STOP",
  "neutralWaybillNumber": "1234567890",
  "customerId": 123
}

# 3. 预览标签
POST /api/tags/render/html
{
  "templateId": 1,
  "data": {
    "neutralWaybillNumber": "1234567890",
    "customerId": 123
  }
}

# 4. 打印标签
POST /api/tags/render/zpl
{
  "templateId": 1,
  "data": {
    "neutralWaybillNumber": "1234567890",
    "customerId": 123
  }
}
```

## 5. 注意事项

### 5.1 标签模板管理

- 标签类型（tagType）必须唯一
- 模板配置和触发规则必须是有效的JSON格式
- 模板配置中的变量名必须与实际数据字段匹配

### 5.2 标签触发

- STOP标签的触发条件：超过T+5且无尾程标签
- T为第一次扫描时间，T+5为5天后的23:59:59
- 触发检查会查询扫描记录表（label_scan_history）

### 5.3 标签渲染

- HTML渲染用于前端预览，不适合直接打印
- ZPL渲染用于标签打印机，需要确保打印机支持ZPL格式
- 条形码生成需要确保内容长度符合所选码制的要求

### 5.4 性能考虑

- 标签触发检查可能涉及多次数据库查询，建议合理使用缓存
- 标签渲染特别是条形码生成可能较耗时，建议异步处理
- 批量操作时，建议限制单次处理数量

## 6. 常见问题

### 6.1 标签触发失败

**可能原因**：
- 第一次扫描时间不存在
- 未超过T+5截止时间
- 已有尾程标签

**解决方案**：
- 确认扫描记录是否存在
- 检查当前时间是否超过T+5
- 确认是否已录入尾程标签

### 6.2 标签渲染失败

**可能原因**：
- 模板ID不存在
- 模板配置格式错误
- 数据字段缺失

**解决方案**：
- 确认模板ID是否正确
- 检查模板配置是否为有效JSON
- 确保提供了所有必要的数据字段

### 6.3 标签打印失败

**可能原因**：
- 打印机不支持ZPL格式
- 标签尺寸设置错误
- 条形码内容不符合要求

**解决方案**：
- 确认打印机支持ZPL格式
- 检查标签尺寸设置是否正确
- 确保条形码内容长度符合所选码制的要求

## 7. 接口版本管理

| 版本 | 变更内容 | 发布日期 |
|------|----------|----------|
| v1.0 | 初始版本，包含所有基础接口 | 2026-01-30 |

## 8. 联系信息

如有接口使用问题，请联系系统管理员或开发团队。