# 【修改接口·管理后台】⚠️ 订单标签移除 tagType 字段及系统分组 (#3941)

> **PR**: #3944 | **服务**: hl-order-service-v3 | **更新时间**: 2026-06-17

## 1. 接口背景

订单标签 `order_tag` 原有 `tagType` 字段（値：`SYSTEM_LOCKED` / `SYSTEM_LOGIC` / `PERSONAL`），用于区分系统自动打标 vs 手工标签，并基于此限制了部分系统标签不可删改。由于系统自动打标功能不再实施，本次统一移除 `tagType` 字段及相关分组/保护逻辑：全部标签统一为「手工挂、可改可删、不分类型」。

## 2. 变更清单

| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | 查询订单已挂标签 | GET | /v3/admin/order/{orderId}/tags | 删除入参 + 出参结构重构 | 删 `includeLibrary` 参数；`attached` 从三组对象改为扁平数组；删 `tagType`、`systemLogicCatalog`、`personalLibrary` |
| 2 | 订单详情 tags[] | GET | /v3/admin/order/{orderId} | 删除出参字段 | `tags[]` 元素删除 `type` 字段 |
| 3 | 订单列表 tags[] | GET | /v3/admin/order/list（或分页接口） | 删除出参字段 | `tags[]` 元素删除 `type` 字段 |

## 3. 接口详情

### 3.1 查询订单已挂标签

- **使用场景**：订单详情页「标签」Tab 加载时调用，展示已挂标签列表供管理员增删。
- **认证**：需要 JWT。
- **幂等性**：是（只读）。
- **限流**：无。

入参变更：删除 query 参数 `includeLibrary`（此参数原已废弃死参，传了也无效，请前端移除对此参数的传递）。

出参结构重构（破坏性变更）：

旧结构 `attached` 为分组对象：
```json
{
  "attached": {
    "systemLocked": [ { "id": "...", "tagName": "...", "tagType": "SYSTEM_LOCKED", ... } ],
    "systemLogic":  [ { "id": "...", "tagName": "...", "tagType": "SYSTEM_LOGIC", ... } ],
    "personal":     [ { "id": "...", "tagName": "...", "tagType": "PERSONAL", ... } ]
  },
  "systemLogicCatalog": ["未定日期"],
  "personalLibrary": [ ... ]
}
```

新结构 `attached` 为扁平数组，无分组、无 tagType：
```json
{
  "attached": [
    { "id": "...", "orderId": "...", "tagName": "...", "tagColor": "...", "creator": "...", "createdAt": "..." }
  ]
}
```

### 3.2 订单详情 tags[]

- **使用场景**：GET /v3/admin/order/{orderId} 返回值中的 `tags` 字段。
- **入参**：无变化。
- **出参变更**：`tags[]` 元素（`TagVO`）删除 `type` 字段，保留 `name`、`color`、`creator`。

### 3.3 订单列表 tags[]

- **使用场景**：订单列表接口返回中每条订单的 `tags` 字段。
- **入参**：无变化。
- **出参变更**：`tags[]` 元素删除 `type` 字段，保留 `name`、`color`、`creator`。

## 4. 接口入参

### 4.1 路径参数 / Query 参数

| 接口 | 字段 | 变更 | 类型 | 说明 |
|------|------|------|------|------|
| GET /v3/admin/order/{orderId}/tags | orderId | 不变 | Long（String格式） | 路径参数，订单 ID |
| GET /v3/admin/order/{orderId}/tags | includeLibrary | **已删除** | Boolean（原） | 原废弃死参，传了无效；请前端移除此参数 |

### 4.2 请求体字段

以上接口均为 GET，无请求体。

## 5. 出参（响应）

### 5.1 GET /v3/admin/order/{orderId}/tags 响应字段

| 字段 | 类型 | 变更 | 说明 |
|------|------|------|------|
| attached | Array | **结构重构** | 由分组对象改为扁平数组，元素为 OrderTagVO |
| systemLogicCatalog | Array | **已删除** | 原固定返回 `["未定日期"]`，已移除 |
| personalLibrary | Array | **已删除** | 原标签库备选列表，已移除 |

OrderTagVO 元素字段：

| 字段 | 类型 | 变更 | 说明 |
|------|------|------|------|
| id | String | 不变 | 订单标签记录 ID |
| orderId | String | 不变 | 所属订单 ID |
| tagName | String | 不变 | 标签名称 |
| tagColor | String | 不变 | 标签颜色，如 `#5B8FF9` |
| creator | String | 不变 | 创建人 |
| createdAt | String | 不变 | 挂标时间，ISO-8601 格式 |
| tagType | String | **已删除** | 原字段（SYSTEM_LOCKED/SYSTEM_LOGIC/PERSONAL），已移除 |

### 5.2 订单详情/列表 tags[] 元素字段（TagVO）

| 字段 | 类型 | 变更 | 说明 |
|------|------|------|------|
| name | String | 不变 | 标签名称 |
| color | String | 不变 | 标签颜色 |
| creator | String | 不变 | 创建人 |
| type | String | **已删除** | 原标签类型字段，已移除 |

## 6. 枚举 / 数据字典

原 `tagType` 枚举（已删除，不再返回）：

| 値 | 含义 | 状态 |
|----|------|------|
| `SYSTEM_LOCKED` | 系统锁定标签（原不可删） | 已删除，不再有此分类 |
| `SYSTEM_LOGIC` | 系统逻辑标签（原不可删） | 已删除，不再有此分类 |
| `PERSONAL` | 手工标签 | 已删除，所有标签统一无类型 |

## 7. 错误码

| code | 含义 | 变更 |
|------|------|------|
| 581412 | SYSTEM_LOCKED 标签不可删除 | **已删除**，不再返回此错误码 |
| 581413 | SYSTEM_LOGIC 标签不可删除 | **已删除**，不再返回此错误码 |
| 581432 | 系统标签不可修改 | **已删除**，不再返回此错误码 |
| 581433 | 无权修改（非创建人） | 保留不变 |

## 8. 示例（3 组：典型 / 边界 / 异常）

### 8.1 典型成功 — 查询订单已挂标签（新结构）

请求：
```
GET /v3/admin/order/2067178767255560193/tags
Authorization: Bearer <token>
```

响应（attached 为扁平数组，无 tagType / systemLogicCatalog / personalLibrary）：
```json
{
  "code": 200,
  "data": {
    "attached": [
      {
        "id": "2067178767255560201",
        "orderId": "2067178767255560193",
        "tagName": "高净値",
        "tagColor": "#5B8FF9",
        "creator": "张管理",
        "createdAt": "2026-06-17T10:00:00"
      },
      {
        "id": "2067178767255560202",
        "orderId": "2067178767255560193",
        "tagName": "重点跟进",
        "tagColor": "#FF6B6B",
        "creator": "李管理",
        "createdAt": "2026-06-16T14:30:00"
      }
    ]
  },
  "message": "ok",
  "success": true
}
```

### 8.2 边界情况 — 订单无标签时返回空数组

请求：
```
GET /v3/admin/order/2067178767255560194/tags
Authorization: Bearer <token>
```

响应：
```json
{
  "code": 200,
  "data": {
    "attached": []
  },
  "message": "ok",
  "success": true
}
```

### 8.3 订单详情/列表 tags[] 结构参考

订单详情/列表接口（GET /v3/admin/order/{orderId} 或列表接口）中 tags 字段示例：
```json
{
  "tags": [
    {
      "name": "高净値",
      "color": "#5B8FF9",
      "creator": "张管理"
    }
  ]
}
```

注意：`type` 字段已删除，不再出现。

## 9. 业务边界

- 适用：所有订单标签均可删除，无论是什么类型（原 SYSTEM_LOCKED/SYSTEM_LOGIC 保护已解除）。
- 适用：任何管理员可以删除/修改自己创建的标签（581433 创建者限制仍保留）。
- 特殊边界：`includeLibrary` 参数即使传了也不报错（后端兼容忽略），但返回结果不含 `personalLibrary` 字段，请前端彻底移除此参数的传递，避免多余请求参数污染 URL。

## 10. 修改前后对比

### 10.1 字段级对比

| 字段 | 改前 | 改后 |
|------|------|------|
| GET .../tags 中 `attached` | 对象 `{ systemLocked: [], systemLogic: [], personal: [] }` | 扁平数组 `[{id, orderId, tagName, tagColor, creator, createdAt}]` |
| GET .../tags 中 `systemLogicCatalog` | `["未定日期"]` | **已删除** |
| GET .../tags 中 `personalLibrary` | 标签库备选列表数组 | **已删除** |
| OrderTagVO 中 `tagType` | `SYSTEM_LOCKED` / `SYSTEM_LOGIC` / `PERSONAL` | **已删除** |
| 订单详情/列表 TagVO 中 `type` | `SYSTEM_LOCKED` / `SYSTEM_LOGIC` / `PERSONAL` | **已删除** |
| 入参 `includeLibrary` | 可传 Boolean（实际已废弃死参） | **已删除** |

### 10.2 行为级对比

| 行为 | 改前 | 改后 |
|------|------|------|
| SYSTEM_LOCKED 标签删除 | 返回 581412 禁止删除 | 可正常删除 |
| SYSTEM_LOGIC 标签删除 | 返回 581413 禁止删除 | 可正常删除 |
| 系统标签修改 | 返回 581432 禁止修改 | 可正常修改 |

## 11. 影响评估 / 回滚

### 11.1 影响评估

- **是否破坏向后兼容**：**是（破坏性变更）**。`attached` 结构从对象改为数组，`tagType`/`systemLogicCatalog`/`personalLibrary`/`type` 字段均已删除，前端需同步更新解析逻辑。
- **前端是否必须同步上线**：**是**。若前端仍按旧结构访问 `attached.systemLocked` / `attached.personal` 等字段，将得到 `undefined`；若仍渲染 `tags[].type`，将得到 `undefined`。

### 11.2 回滚方案

- **回滚方式**：revert PR #3944 并重新部署 hl-order-service-v3 即可恢复旧字段结构。

## 12. 注意事项

- 前端 workaround 清理点：
  1. `GET .../tags` 返回解析：将 `attached.systemLocked` / `attached.systemLogic` / `attached.personal` 的三路分支解析改为直接读取 `attached` 数组。
  2. `systemLogicCatalog` / `personalLibrary` 字段读取逻辑请删除，不再返回。
  3. 订单详情/列表中 `tags[].type` 字段读取/渲染请删除。
  4. 调用 `GET .../tags` 时如有传 `includeLibrary` 参数，请移除。
  5. 原基于 `tagType` 的删除保护逻辑（SYSTEM_LOCKED/SYSTEM_LOGIC 无法删除）已解除，如前端有对应 UI 逻辑（如隐藏删除按钮/报错提示），请检查是否需要调整。
- 测试服已验证：listTags 扁平结构正常、订单详情 tags 无 type 字段、加标签可删、无 SQL 异常。

## 13. 关联 / 联系人

### 13.1 链接

- **Issue**: [#3941](https://git.1814.love:8443/wx/HL/issues/3941)
- **PR**: [#3944](https://git.1814.love:8443/wx/HL/pulls/3944)
- **Merge commit**: [b6f5ca5de](https://git.1814.love:8443/wx/HL/commit/b6f5ca5de)

### 13.2 联系人

- **后端负责人**: @yaosutu
