所有检测均成功
changelog-filename-gate / validate (push) Successful in 1s
修改原因:hl-ui changelog loop 需要把前端消费进度回写到契约源,避免领取、实现状态与实际交付脱节。 修改内容:将 frontend_status 与已有 legacy frontend 同步为 implemented,记录负责人 hl-ui-codex,并关联 mmg/hl-ui@00ea8e2ad187b6b91626f069fc3a4a5ba5a76e06;发布和验收字段保持不变。 实际验证:回写器已校验目标文件、状态单调性、提交范围和 Front Matter 内容,提交只包含当前 changelog。 Frontend-Status: tools/mcp-api-sync/.changelog-repo/changelogs-v2/2026-07/25_5219_核单原型流迁移-修改接口-管理后台.md
1081 行
34 KiB
Markdown
1081 行
34 KiB
Markdown
---
|
||
frontend_status: "implemented"
|
||
frontend_owner: "hl-ui-codex"
|
||
frontend_ref: "mmg/hl-ui@00ea8e2ad187b6b91626f069fc3a4a5ba5a76e06"
|
||
updated_at: "2026-07-25T08:37:46.681Z"
|
||
---
|
||
# 【修改接口·管理后台】核单原型流迁移 (#5219)
|
||
|
||
> **PR**: #5243 | **服务**: hl-order-service-v3 | **更新时间**: 2026-07-25 16:08
|
||
|
||
## 1. 接口背景
|
||
|
||
核单流程从旧的“财务总览/优惠逐条确认后直接 Step6 提交”调整为原型流:先确认 8 个核单分类,再生成并确认主报账人报账表,再生成并确认单团核算表,最后完成核单。
|
||
|
||
## 2. 变更清单
|
||
|
||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||
|---|------|------|------|----------|------|
|
||
| 1 | 查询八分类确认状态 | GET | `/v3/admin/order/{orderId}/settlement/category-checks` | 新增 | 返回 8 个核单分类的确认状态、行数和来源指纹 |
|
||
| 2 | 确认单个核单分类 | POST | `/v3/admin/order/{orderId}/settlement/category-checks/{category}/confirm` | 新增 | 用最近读取的分类指纹确认单个分类 |
|
||
| 3 | 查询主报账人报账表 | GET | `/v3/admin/order/{orderId}/settlement/reports/reimbursement` | 新增 | 查询主报账表当前快照 |
|
||
| 4 | 生成主报账人报账表 | POST | `/v3/admin/order/{orderId}/settlement/reports/reimbursement/generate` | 新增 | 8 分类全部确认后生成 |
|
||
| 5 | 确认主报账人报账表 | POST | `/v3/admin/order/{orderId}/settlement/reports/reimbursement/confirm` | 新增 | 确认转账、预支和签字单 |
|
||
| 6 | 查询单团核算表 | GET | `/v3/admin/order/{orderId}/settlement/reports/group` | 新增 | 查询单团核算表当前快照 |
|
||
| 7 | 生成单团核算表 | POST | `/v3/admin/order/{orderId}/settlement/reports/group/generate` | 新增 | 主报账表确认后生成 |
|
||
| 8 | 确认单团核算表 | POST | `/v3/admin/order/{orderId}/settlement/reports/group/confirm` | 新增 | 用最近读取的报告指纹确认 |
|
||
| 9 | 完成核单 | POST | `/v3/admin/order/{orderId}/settlement/finalize` | 新增 | 单团核算表确认后提交核单 |
|
||
| 10 | 查询核单应收财务总览 | GET | `/v3/admin/order/{orderId}/settlement/financial-overview` | 修改 | 仍保留查询,但不再返回确认状态/指纹 |
|
||
| 11 | 确认财务总览 | POST | `/v3/admin/order/{orderId}/settlement/financial-overview/confirm` | 删除 | 旧 POST 契约下线 |
|
||
| 12 | 确认单条优惠 | POST | `/v3/admin/order/{orderId}/settlement/financial-overview/discounts/{discountId}/confirm` | 删除 | 旧 POST 契约下线 |
|
||
|
||
## 3. 接口详情
|
||
|
||
### 3.1 查询八分类确认状态
|
||
|
||
- **方法 + 路径**: `GET /v3/admin/order/{orderId}/settlement/category-checks`
|
||
- **接口名**: 查询原型八个核单分类确认状态
|
||
- **认证**: 管理后台 JWT;房务角色不可访问
|
||
- **幂等性**: 幂等,只读
|
||
- **限流**: 无接口级特殊限流
|
||
|
||
**路径参数**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| `orderId` | Long/String | 是 | 订单 ID,必须大于 0 |
|
||
|
||
**请求体**: 无
|
||
|
||
**响应字段**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `orderId` | String | 订单 ID |
|
||
| `allConfirmed` | Boolean | 8 个分类是否全部已确认 |
|
||
| `items` | Array | 分类确认项 |
|
||
| `items[].category` | String | 分类枚举,见 §6.1 |
|
||
| `items[].categoryName` | String | 分类中文名 |
|
||
| `items[].rowCount` | Integer | 当前分类参与核单的行数 |
|
||
| `items[].empty` | Boolean | 当前分类是否为空 |
|
||
| `items[].sourceFingerprint` | String | 当前分类来源事实 SHA-256 |
|
||
| `items[].confirmStatus` | String | `UNCONFIRMED` / `CONFIRMED` |
|
||
| `items[].confirmedBy` | String/null | 确认人 ID |
|
||
| `items[].confirmedByName` | String/null | 确认人名称 |
|
||
| `items[].confirmedAt` | String/null | 确认时间,未确认时为 null |
|
||
|
||
**错误码**
|
||
|
||
| code | 含义 | 触发场景 |
|
||
|------|------|----------|
|
||
| 400 | 参数校验失败 | `orderId <= 0` |
|
||
| 403 | 无访问权限 | 房务角色访问 |
|
||
|
||
**典型成功示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
GET /v3/admin/order/1914050000000001/settlement/category-checks
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"orderId": "1914050000000001",
|
||
"allConfirmed": false,
|
||
"items": [
|
||
{
|
||
"category": "HOTEL",
|
||
"categoryName": "住宿",
|
||
"rowCount": 2,
|
||
"empty": false,
|
||
"sourceFingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||
"confirmStatus": "CONFIRMED",
|
||
"confirmedBy": "10001",
|
||
"confirmedByName": "张三",
|
||
"confirmedAt": "2026-07-25T15:20:00"
|
||
},
|
||
{
|
||
"category": "OTHER_EXPENSE",
|
||
"categoryName": "其他支出",
|
||
"rowCount": 0,
|
||
"empty": true,
|
||
"sourceFingerprint": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||
"confirmStatus": "UNCONFIRMED",
|
||
"confirmedBy": null,
|
||
"confirmedByName": null,
|
||
"confirmedAt": null
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
**边界示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
GET /v3/admin/order/1914050000000001/settlement/category-checks
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"orderId": "1914050000000001",
|
||
"allConfirmed": false,
|
||
"items": [
|
||
{
|
||
"category": "MEAL",
|
||
"categoryName": "餐食",
|
||
"rowCount": 0,
|
||
"empty": true,
|
||
"sourceFingerprint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||
"confirmStatus": "UNCONFIRMED",
|
||
"confirmedBy": null,
|
||
"confirmedByName": null,
|
||
"confirmedAt": null
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
**异常示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
GET /v3/admin/order/0/settlement/category-checks
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 400,
|
||
"msg": "订单 ID 必须大于 0",
|
||
"data": null
|
||
}
|
||
```
|
||
|
||
**业务边界**
|
||
|
||
- 适用:进入核单流程后读取 8 个分类状态。
|
||
- 不适用:房务角色不可查看。
|
||
- 特殊边界:空分类仍需要走显式确认,不能因为 `rowCount=0` 自动通过。
|
||
|
||
### 3.2 确认单个核单分类
|
||
|
||
- **方法 + 路径**: `POST /v3/admin/order/{orderId}/settlement/category-checks/{category}/confirm`
|
||
- **接口名**: 按最近读取指纹确认单个核单分类
|
||
- **认证**: 管理后台 JWT;需要财务写权限;房务角色不可访问
|
||
- **幂等性**: 非纯幂等;相同指纹重复确认不会改变来源事实
|
||
- **限流**: 无接口级特殊限流
|
||
|
||
**路径参数**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| `orderId` | Long/String | 是 | 订单 ID,必须大于 0 |
|
||
| `category` | String | 是 | 分类枚举,大小写不敏感,见 §6.1 |
|
||
|
||
**请求体字段**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 | 校验规则 |
|
||
|------|------|------|------|----------|
|
||
| `expectedSourceFingerprint` | String | 是 | 最近读取的分类来源事实 SHA-256 | 64 位小写十六进制 |
|
||
| `confirmEmpty` | Boolean | 是 | 是否明确确认空分类 | 空分类传 `true`,非空分类传 `false` |
|
||
|
||
**响应字段**: 同 §3.1 `items[]` 单项。
|
||
|
||
**错误码**
|
||
|
||
| code | 含义 | 触发场景 |
|
||
|------|------|----------|
|
||
| 400 | 参数校验失败 | 指纹不是 64 位十六进制、缺少 `confirmEmpty` |
|
||
| 584315 | 核单来源数据已变化,请刷新后重新生成 | 前端传入的指纹与当前分类来源不一致 |
|
||
| 584318 | 空分类必须显式确认,非空分类不得按空分类确认 | `confirmEmpty` 与当前分类是否为空不匹配 |
|
||
| 584319 | 核单存在未知分类或历史迁移数据不完整 | `category` 不是 8 分类枚举 |
|
||
|
||
**典型成功示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
POST /v3/admin/order/1914050000000001/settlement/category-checks/HOTEL/confirm
|
||
Authorization: Bearer <token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"expectedSourceFingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||
"confirmEmpty": false
|
||
}
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"category": "HOTEL",
|
||
"categoryName": "住宿",
|
||
"rowCount": 2,
|
||
"empty": false,
|
||
"sourceFingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||
"confirmStatus": "CONFIRMED",
|
||
"confirmedBy": "10001",
|
||
"confirmedByName": "张三",
|
||
"confirmedAt": "2026-07-25T15:24:00"
|
||
}
|
||
}
|
||
```
|
||
|
||
**边界示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
POST /v3/admin/order/1914050000000001/settlement/category-checks/MEAL/confirm
|
||
Authorization: Bearer <token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"expectedSourceFingerprint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||
"confirmEmpty": true
|
||
}
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"category": "MEAL",
|
||
"categoryName": "餐食",
|
||
"rowCount": 0,
|
||
"empty": true,
|
||
"sourceFingerprint": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||
"confirmStatus": "CONFIRMED",
|
||
"confirmedBy": "10001",
|
||
"confirmedByName": "张三",
|
||
"confirmedAt": "2026-07-25T15:25:00"
|
||
}
|
||
}
|
||
```
|
||
|
||
**异常示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
POST /v3/admin/order/1914050000000001/settlement/category-checks/UNKNOWN/confirm
|
||
Authorization: Bearer <token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"expectedSourceFingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||
"confirmEmpty": false
|
||
}
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 584319,
|
||
"msg": "核单存在未知分类或历史迁移数据不完整",
|
||
"data": null
|
||
}
|
||
```
|
||
|
||
**业务边界**
|
||
|
||
- 适用:确认当前分类数据没有变化。
|
||
- 不适用:前端未先读取 `sourceFingerprint` 时不应直接确认。
|
||
- 特殊边界:`OTHER_INCOME` 确认前会校验其他收入可提交状态。
|
||
|
||
### 3.3 主报账人报账表
|
||
|
||
- **查询**: `GET /v3/admin/order/{orderId}/settlement/reports/reimbursement`
|
||
- **生成**: `POST /v3/admin/order/{orderId}/settlement/reports/reimbursement/generate`
|
||
- **确认**: `POST /v3/admin/order/{orderId}/settlement/reports/reimbursement/confirm`
|
||
- **接口名**: 查询主报账人报账表 / 八分类确认后生成主报账人报账表 / 完成转账、预支及签字门禁后确认主报账人报账表
|
||
- **认证**: 管理后台 JWT;房务角色不可访问
|
||
- **幂等性**: 查询幂等;生成/确认会更新报告状态和确认信息
|
||
- **限流**: 无接口级特殊限流
|
||
|
||
**路径参数**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| `orderId` | Long/String | 是 | 订单 ID,必须大于 0 |
|
||
|
||
**确认请求体字段**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 | 校验规则 |
|
||
|------|------|------|------|----------|
|
||
| `expectedSourceFingerprint` | String | 是 | 最近读取的主报账表来源 SHA-256 | 64 位小写十六进制 |
|
||
| `transferStatus` | String | 否 | 转账状态 | 后端按字符串保存 |
|
||
| `transferDate` | String/date | 否 | 转账日期 | `YYYY-MM-DD` |
|
||
| `transferRef` | String | 否 | 转账流水/备注 | 字符串 |
|
||
| `advanceSettledFlag` | Boolean | 是 | 预支是否已结清 | 不能为空 |
|
||
| `signedVoucher` | Object | 是 | 签字单回收信息 | 不能为空 |
|
||
| `signedVoucher.files` | Array | 否 | 文件列表 | 元素见下 |
|
||
| `signedVoucher.files[].name` | String | 否 | 文件名 | 字符串 |
|
||
| `signedVoucher.files[].url` | String | 否 | OSS 文件地址 | 字符串 |
|
||
| `signedVoucher.note` | String | 否 | 备注 | 字符串 |
|
||
|
||
**响应字段**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `id` | String/null | 主报账记录 ID;未生成时可为 null |
|
||
| `orderId` | String | 订单 ID |
|
||
| `reportStatus` | String | 报告状态,见 §6.2 |
|
||
| `sourceFingerprint` | String | 当前来源 SHA-256 |
|
||
| `primaryReporterId` | String/null | 主报账人 ID |
|
||
| `primaryReporterName` | String/null | 主报账人姓名 |
|
||
| `primaryReporterRole` | String/null | 主报账人角色 |
|
||
| `primaryReporterCollectedAmount` | Decimal | 主报账人代收金额 |
|
||
| `publicPrepaidAmount` | Decimal | 公共预支金额 |
|
||
| `primaryReporterDueAmount` | Decimal | 主报账人应报账金额 |
|
||
| `advanceOutstandingAmount` | Decimal | 未结清预支金额 |
|
||
| `reconNetAmount` | Decimal | 报账净额 |
|
||
| `transferDirection` | String/null | 转账方向 |
|
||
| `transferAmount` | Decimal | 转账金额 |
|
||
| `incomeLines` | Array<Object> | 收入明细行 |
|
||
| `expenseLines` | Array<Object> | 支出明细行 |
|
||
| `advanceLines` | Array<Object> | 预支明细行 |
|
||
| `transferStatus` | String/null | 转账状态 |
|
||
| `transferDate` | String/date/null | 转账日期 |
|
||
| `transferRef` | String/null | 转账流水/备注 |
|
||
| `advanceSettledFlag` | Boolean/null | 预支是否已结清 |
|
||
| `signedVoucher` | Object/null | 签字单信息 |
|
||
| `generatedBy` / `generatedByName` / `generatedAt` | String/String/String | 生成信息 |
|
||
| `confirmedBy` / `confirmedByName` / `confirmedAt` | String/String/String | 确认信息 |
|
||
|
||
**错误码**
|
||
|
||
| code | 含义 | 触发场景 |
|
||
|------|------|----------|
|
||
| 584310 | 八个核单分类尚未全部确认或数据已变化 | 生成主报账表前 8 分类未全部确认或指纹已失效 |
|
||
| 584311 | 主报账表尚未生成 | 查询/确认时还没有可用主报账表 |
|
||
| 584315 | 核单来源数据已变化,请刷新后重新生成 | 确认时传入的报告指纹已过期 |
|
||
| 584316 | 核单报告发生并发变化,请刷新后重试 | 并发确认冲突 |
|
||
| 584317 | 当前报告状态不允许执行该操作 | 当前状态不能生成或确认 |
|
||
|
||
**典型成功示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
POST /v3/admin/order/1914050000000001/settlement/reports/reimbursement/confirm
|
||
Authorization: Bearer <token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"expectedSourceFingerprint": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
|
||
"transferStatus": "TRANSFERRED",
|
||
"transferDate": "2026-07-25",
|
||
"transferRef": "BANK-20260725-001",
|
||
"advanceSettledFlag": true,
|
||
"signedVoucher": {
|
||
"files": [
|
||
{
|
||
"name": "签字单.pdf",
|
||
"url": "https://oss.example.com/voucher.pdf"
|
||
}
|
||
],
|
||
"note": "签字单已回收"
|
||
}
|
||
}
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"id": "9200000000001",
|
||
"orderId": "1914050000000001",
|
||
"reportStatus": "CONFIRMED",
|
||
"sourceFingerprint": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
|
||
"primaryReporterId": "3001",
|
||
"primaryReporterName": "王司机",
|
||
"primaryReporterRole": "DRIVER",
|
||
"primaryReporterCollectedAmount": 2000.00,
|
||
"publicPrepaidAmount": 500.00,
|
||
"primaryReporterDueAmount": 1500.00,
|
||
"advanceOutstandingAmount": 0.00,
|
||
"reconNetAmount": 1500.00,
|
||
"transferDirection": "COMPANY_TO_REPORTER",
|
||
"transferAmount": 1500.00,
|
||
"incomeLines": [],
|
||
"expenseLines": [],
|
||
"advanceLines": [],
|
||
"transferStatus": "TRANSFERRED",
|
||
"transferDate": "2026-07-25",
|
||
"transferRef": "BANK-20260725-001",
|
||
"advanceSettledFlag": true,
|
||
"signedVoucher": {
|
||
"files": [
|
||
{
|
||
"name": "签字单.pdf",
|
||
"url": "https://oss.example.com/voucher.pdf"
|
||
}
|
||
],
|
||
"note": "签字单已回收"
|
||
},
|
||
"generatedBy": "10001",
|
||
"generatedByName": "张三",
|
||
"generatedAt": "2026-07-25T15:30:00",
|
||
"confirmedBy": "10001",
|
||
"confirmedByName": "张三",
|
||
"confirmedAt": "2026-07-25T15:35:00"
|
||
}
|
||
}
|
||
```
|
||
|
||
**边界示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
GET /v3/admin/order/1914050000000001/settlement/reports/reimbursement
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"id": "9200000000001",
|
||
"orderId": "1914050000000001",
|
||
"reportStatus": "STALE",
|
||
"sourceFingerprint": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
|
||
"primaryReporterId": null,
|
||
"primaryReporterName": null,
|
||
"primaryReporterRole": null,
|
||
"primaryReporterCollectedAmount": 0.00,
|
||
"publicPrepaidAmount": 0.00,
|
||
"primaryReporterDueAmount": 0.00,
|
||
"advanceOutstandingAmount": 0.00,
|
||
"reconNetAmount": 0.00,
|
||
"transferDirection": null,
|
||
"transferAmount": 0.00,
|
||
"incomeLines": [],
|
||
"expenseLines": [],
|
||
"advanceLines": [],
|
||
"transferStatus": null,
|
||
"transferDate": null,
|
||
"transferRef": null,
|
||
"advanceSettledFlag": null,
|
||
"signedVoucher": null,
|
||
"generatedBy": "10001",
|
||
"generatedByName": "张三",
|
||
"generatedAt": "2026-07-25T15:30:00",
|
||
"confirmedBy": null,
|
||
"confirmedByName": null,
|
||
"confirmedAt": null
|
||
}
|
||
}
|
||
```
|
||
|
||
**异常示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
POST /v3/admin/order/1914050000000001/settlement/reports/reimbursement/generate
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 584310,
|
||
"msg": "八个核单分类尚未全部确认或数据已变化",
|
||
"data": null
|
||
}
|
||
```
|
||
|
||
**业务边界**
|
||
|
||
- 适用:8 分类全部确认后生成主报账表。
|
||
- 不适用:8 分类未确认完成时不能生成。
|
||
- 特殊边界:查询返回 `STALE` 时表示来源已变化,应重新生成后再确认。
|
||
|
||
### 3.4 单团核算表
|
||
|
||
- **查询**: `GET /v3/admin/order/{orderId}/settlement/reports/group`
|
||
- **生成**: `POST /v3/admin/order/{orderId}/settlement/reports/group/generate`
|
||
- **确认**: `POST /v3/admin/order/{orderId}/settlement/reports/group/confirm`
|
||
- **接口名**: 查询单团核算表 / 主报账表确认后生成单团核算表 / 按最近读取指纹确认单团核算表
|
||
- **认证**: 管理后台 JWT;房务角色不可访问
|
||
- **幂等性**: 查询幂等;生成/确认会更新报告状态和确认信息
|
||
- **限流**: 无接口级特殊限流
|
||
|
||
**路径参数**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| `orderId` | Long/String | 是 | 订单 ID,必须大于 0 |
|
||
|
||
**确认请求体字段**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 | 校验规则 |
|
||
|------|------|------|------|----------|
|
||
| `expectedSourceFingerprint` | String | 是 | 最近读取的单团核算表来源 SHA-256 | 64 位小写十六进制 |
|
||
|
||
**响应字段**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `id` | String/null | 单团核算记录 ID |
|
||
| `orderId` | String | 订单 ID |
|
||
| `reportStatus` | String | 报告状态,见 §6.2 |
|
||
| `sourceFingerprint` | String | 当前来源 SHA-256 |
|
||
| `baseOrderAmount` | Decimal | 订单基础金额 |
|
||
| `otherIncomeAmount` | Decimal | 其他收入金额 |
|
||
| `discountAmount` | Decimal | 优惠金额 |
|
||
| `adjustedReceivableAmount` | Decimal | 调整后应收 |
|
||
| `paidAmount` | Decimal | 已收金额 |
|
||
| `actualRefundedAmount` | Decimal | 实际退款金额 |
|
||
| `netRevenueAmount` | Decimal | 净收入 |
|
||
| `netReceivedAmount` | Decimal | 净已收 |
|
||
| `outstandingAmount` | Decimal | 待收金额 |
|
||
| `hotelCost` | Decimal | 住宿成本 |
|
||
| `ticketCost` | Decimal | 门票/游玩项目成本 |
|
||
| `mealCost` | Decimal | 餐食成本 |
|
||
| `vehicleCost` | Decimal | 车辆成本 |
|
||
| `guideCost` | Decimal | 导游成本 |
|
||
| `photographerCost` | Decimal | 摄影成本 |
|
||
| `otherExpenseCost` | Decimal | 其他支出成本 |
|
||
| `insurancePremium` | Decimal | 保险保费 |
|
||
| `totalCost` | Decimal | 总成本 |
|
||
| `paidCost` | Decimal | 已付成本 |
|
||
| `unpaidCost` | Decimal | 未付成本 |
|
||
| `grossProfit` | Decimal | 毛利 |
|
||
| `grossProfitRate` | Decimal | 毛利率 |
|
||
| `travelerCount` | Integer | 出行人数 |
|
||
| `perCapitaRevenue` | Decimal | 人均收入 |
|
||
| `perCapitaCost` | Decimal | 人均成本 |
|
||
| `perCapitaProfit` | Decimal | 人均利润 |
|
||
| `incomeLines` | Array<Object> | 收入明细行 |
|
||
| `costCategories` | Array<Object> | 成本分类行 |
|
||
| `generatedBy` / `generatedByName` / `generatedAt` | String/String/String | 生成信息 |
|
||
| `confirmedBy` / `confirmedByName` / `confirmedAt` | String/String/String | 确认信息 |
|
||
|
||
**错误码**
|
||
|
||
| code | 含义 | 触发场景 |
|
||
|------|------|----------|
|
||
| 584312 | 主报账表尚未确认或数据已变化 | 生成单团核算表前主报账表未确认或已过期 |
|
||
| 584313 | 单团核算表尚未生成 | 查询/确认时还没有可用单团核算表 |
|
||
| 584315 | 核单来源数据已变化,请刷新后重新生成 | 确认时传入的报告指纹已过期 |
|
||
| 584316 | 核单报告发生并发变化,请刷新后重试 | 并发确认冲突 |
|
||
| 584317 | 当前报告状态不允许执行该操作 | 当前状态不能生成或确认 |
|
||
|
||
**典型成功示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
POST /v3/admin/order/1914050000000001/settlement/reports/group/confirm
|
||
Authorization: Bearer <token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"expectedSourceFingerprint": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||
}
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"id": "9300000000001",
|
||
"orderId": "1914050000000001",
|
||
"reportStatus": "CONFIRMED",
|
||
"sourceFingerprint": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||
"baseOrderAmount": 24800.00,
|
||
"otherIncomeAmount": 500.00,
|
||
"discountAmount": 300.00,
|
||
"adjustedReceivableAmount": 25000.00,
|
||
"paidAmount": 25000.00,
|
||
"actualRefundedAmount": 0.00,
|
||
"netRevenueAmount": 25000.00,
|
||
"netReceivedAmount": 25000.00,
|
||
"outstandingAmount": 0.00,
|
||
"hotelCost": 4280.00,
|
||
"ticketCost": 3680.00,
|
||
"mealCost": 860.00,
|
||
"vehicleCost": 1260.00,
|
||
"guideCost": 800.00,
|
||
"photographerCost": 600.00,
|
||
"otherExpenseCost": 300.00,
|
||
"insurancePremium": 180.00,
|
||
"totalCost": 11960.00,
|
||
"paidCost": 11960.00,
|
||
"unpaidCost": 0.00,
|
||
"grossProfit": 13040.00,
|
||
"grossProfitRate": 0.521600,
|
||
"travelerCount": 5,
|
||
"perCapitaRevenue": 5000.00,
|
||
"perCapitaCost": 2392.00,
|
||
"perCapitaProfit": 2608.00,
|
||
"incomeLines": [],
|
||
"costCategories": [],
|
||
"generatedBy": "10001",
|
||
"generatedByName": "张三",
|
||
"generatedAt": "2026-07-25T15:40:00",
|
||
"confirmedBy": "10001",
|
||
"confirmedByName": "张三",
|
||
"confirmedAt": "2026-07-25T15:45:00"
|
||
}
|
||
}
|
||
```
|
||
|
||
**边界示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
GET /v3/admin/order/1914050000000001/settlement/reports/group
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"id": "9300000000001",
|
||
"orderId": "1914050000000001",
|
||
"reportStatus": "GENERATED",
|
||
"sourceFingerprint": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||
"baseOrderAmount": 0.00,
|
||
"otherIncomeAmount": 0.00,
|
||
"discountAmount": 0.00,
|
||
"adjustedReceivableAmount": 0.00,
|
||
"paidAmount": 0.00,
|
||
"actualRefundedAmount": 0.00,
|
||
"netRevenueAmount": 0.00,
|
||
"netReceivedAmount": 0.00,
|
||
"outstandingAmount": 0.00,
|
||
"hotelCost": 0.00,
|
||
"ticketCost": 0.00,
|
||
"mealCost": 0.00,
|
||
"vehicleCost": 0.00,
|
||
"guideCost": 0.00,
|
||
"photographerCost": 0.00,
|
||
"otherExpenseCost": 0.00,
|
||
"insurancePremium": 0.00,
|
||
"totalCost": 0.00,
|
||
"paidCost": 0.00,
|
||
"unpaidCost": 0.00,
|
||
"grossProfit": 0.00,
|
||
"grossProfitRate": 0.000000,
|
||
"travelerCount": 0,
|
||
"perCapitaRevenue": 0.00,
|
||
"perCapitaCost": 0.00,
|
||
"perCapitaProfit": 0.00,
|
||
"incomeLines": [],
|
||
"costCategories": [],
|
||
"generatedBy": "10001",
|
||
"generatedByName": "张三",
|
||
"generatedAt": "2026-07-25T15:40:00",
|
||
"confirmedBy": null,
|
||
"confirmedByName": null,
|
||
"confirmedAt": null
|
||
}
|
||
}
|
||
```
|
||
|
||
**异常示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
POST /v3/admin/order/1914050000000001/settlement/reports/group/generate
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 584312,
|
||
"msg": "主报账表尚未确认或数据已变化",
|
||
"data": null
|
||
}
|
||
```
|
||
|
||
**业务边界**
|
||
|
||
- 适用:主报账表已确认后生成单团核算表。
|
||
- 不适用:主报账表未确认或为 `STALE` 时不能生成。
|
||
- 特殊边界:金额为 0 时仍返回完整字段,数组字段为空数组。
|
||
|
||
### 3.5 完成核单
|
||
|
||
- **方法 + 路径**: `POST /v3/admin/order/{orderId}/settlement/finalize`
|
||
- **接口名**: 单团核算表确认后完成核单
|
||
- **认证**: 管理后台 JWT;房务角色不可访问
|
||
- **幂等性**: 非幂等;完成后订单进入核单提交后的状态
|
||
- **限流**: 无接口级特殊限流
|
||
|
||
**路径参数**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| `orderId` | Long/String | 是 | 订单 ID,必须大于 0 |
|
||
|
||
**请求体**: 无
|
||
|
||
**响应字段**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `summaryId` | String | 新写入的 settlement summary 主键 |
|
||
| `orderId` | String | 订单 ID |
|
||
| `settledAt` | String | 核单完成时间 |
|
||
| `totalAmount` | Decimal | 订单总金额快照 |
|
||
| `paidAmount` | Decimal | 已付金额快照 |
|
||
| `balanceAmount` | Decimal | 尾款金额快照 |
|
||
| `roomCost` | Decimal | 住宿实际成本 |
|
||
| `ticketCost` | Decimal | 门票实际成本 |
|
||
| `staffCost` | Decimal | 人员费用实际成本 |
|
||
| `subsidyCost` | Decimal | 补助实际成本 |
|
||
| `mealCost` | Decimal | 餐食实际成本 |
|
||
| `otherExpenseCost` | Decimal | 其他支出实际成本,含车辆费用 |
|
||
| `insurancePremium` | Decimal | 保险实际保费 |
|
||
| `totalActualCost` | Decimal | 总实际成本 |
|
||
| `driverTransferAmount` | Decimal | 给司机/主报账人转回金额 |
|
||
| `profitAmount` | Decimal | 公司毛利 |
|
||
| `profitRate` | Decimal | 毛利率 |
|
||
| `orderStatusAfter` | String | 结算后订单状态 |
|
||
| `mqTriggered` | Boolean | 结算事件是否成功触发 |
|
||
| `warnings` | Array<String> | 软预警列表 |
|
||
|
||
**错误码**
|
||
|
||
| code | 含义 | 触发场景 |
|
||
|------|------|----------|
|
||
| 584314 | 单团核算表尚未确认或数据已变化 | finalize 前单团核算表未确认或已过期 |
|
||
| 584317 | 当前报告状态不允许执行该操作 | 当前流程状态不能完成核单 |
|
||
|
||
**典型成功示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
POST /v3/admin/order/1914050000000001/settlement/finalize
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"summaryId": "9400000000001",
|
||
"orderId": "1914050000000001",
|
||
"settledAt": "2026-07-25T15:50:00",
|
||
"totalAmount": 25000.00,
|
||
"paidAmount": 25000.00,
|
||
"balanceAmount": 0.00,
|
||
"roomCost": 4280.00,
|
||
"ticketCost": 3680.00,
|
||
"staffCost": 1400.00,
|
||
"subsidyCost": 0.00,
|
||
"mealCost": 860.00,
|
||
"otherExpenseCost": 1560.00,
|
||
"insurancePremium": 180.00,
|
||
"totalActualCost": 11960.00,
|
||
"driverTransferAmount": 11780.00,
|
||
"profitAmount": 13040.00,
|
||
"profitRate": 0.5216,
|
||
"orderStatusAfter": "待财务复核",
|
||
"mqTriggered": true,
|
||
"warnings": []
|
||
}
|
||
}
|
||
```
|
||
|
||
**边界示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
POST /v3/admin/order/1914050000000001/settlement/finalize
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"summaryId": "9400000000002",
|
||
"orderId": "1914050000000001",
|
||
"settledAt": "2026-07-25T15:55:00",
|
||
"totalAmount": 0.00,
|
||
"paidAmount": 0.00,
|
||
"balanceAmount": 0.00,
|
||
"roomCost": 0.00,
|
||
"ticketCost": 0.00,
|
||
"staffCost": 0.00,
|
||
"subsidyCost": 0.00,
|
||
"mealCost": 0.00,
|
||
"otherExpenseCost": 0.00,
|
||
"insurancePremium": 0.00,
|
||
"totalActualCost": 0.00,
|
||
"driverTransferAmount": 0.00,
|
||
"profitAmount": 0.00,
|
||
"profitRate": 0,
|
||
"orderStatusAfter": "待财务复核",
|
||
"mqTriggered": true,
|
||
"warnings": ["住宿 D2 现付缺凭证"]
|
||
}
|
||
}
|
||
```
|
||
|
||
**异常示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
POST /v3/admin/order/1914050000000001/settlement/finalize
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 584314,
|
||
"msg": "单团核算表尚未确认或数据已变化",
|
||
"data": null
|
||
}
|
||
```
|
||
|
||
**业务边界**
|
||
|
||
- 适用:单团核算表已确认后完成核单。
|
||
- 不适用:单团核算表未确认、已过期或流程状态不允许。
|
||
- 特殊边界:`warnings` 为软预警,不阻塞成功响应。
|
||
|
||
### 3.6 查询核单应收财务总览
|
||
|
||
- **方法 + 路径**: `GET /v3/admin/order/{orderId}/settlement/financial-overview`
|
||
- **接口名**: 查询核单应收财务总览
|
||
- **变更点**: 查询接口保留,但返回字段删除旧确认状态/指纹语义;确认动作迁移到 8 分类和报告流。
|
||
|
||
**响应字段**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `baseOrderAmount` | Decimal | 订单基础金额 |
|
||
| `otherIncomeAmount` | Decimal | 有效增费合计 |
|
||
| `discountAmount` | Decimal | 有效优惠合计 |
|
||
| `adjustedReceivableAmount` | Decimal | 调整后应收 |
|
||
| `onlinePaidAmount` | Decimal | 成功线上支付合计 |
|
||
| `offlinePaidAmount` | Decimal | 有效线下收款合计 |
|
||
| `primaryReporterCollectedAmount` | Decimal | 当前主报账司机正式代收 |
|
||
| `paidAmount` | Decimal | 已收合计 |
|
||
| `actualRefundedAmount` | Decimal | 实际退款合计 |
|
||
| `netPaidAmount` | Decimal | 净已收 |
|
||
| `outstandingAmount` | Decimal | 待收 |
|
||
| `surchargeMirrorMatched` | Boolean | 增费镜像是否匹配权威明细 |
|
||
| `discountMirrorMatched` | Boolean | 优惠镜像是否匹配权威明细 |
|
||
| `paidMirrorMatched` | Boolean | 已收镜像是否匹配权威明细 |
|
||
| `refundedMirrorMatched` | Boolean | 退款镜像是否匹配权威明细 |
|
||
| `discounts` | Array | 当前有效优惠 |
|
||
| `discounts[].discountId` | String | 优惠 ID |
|
||
| `discounts[].name` | String | 优惠名称 |
|
||
| `discounts[].type` | String | 优惠类型 |
|
||
| `discounts[].amount` | Decimal | 优惠金额 |
|
||
|
||
**示例**
|
||
|
||
请求:
|
||
|
||
```http
|
||
GET /v3/admin/order/1914050000000001/settlement/financial-overview
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
响应:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"baseOrderAmount": 24800.00,
|
||
"otherIncomeAmount": 500.00,
|
||
"discountAmount": 300.00,
|
||
"adjustedReceivableAmount": 25000.00,
|
||
"onlinePaidAmount": 22000.00,
|
||
"offlinePaidAmount": 3000.00,
|
||
"primaryReporterCollectedAmount": 2000.00,
|
||
"paidAmount": 25000.00,
|
||
"actualRefundedAmount": 0.00,
|
||
"netPaidAmount": 25000.00,
|
||
"outstandingAmount": 0.00,
|
||
"surchargeMirrorMatched": true,
|
||
"discountMirrorMatched": true,
|
||
"paidMirrorMatched": true,
|
||
"refundedMirrorMatched": true,
|
||
"discounts": [
|
||
{
|
||
"discountId": "9100000000001",
|
||
"name": "老客优惠",
|
||
"type": "CUSTOMER_DISCOUNT",
|
||
"amount": 300.00
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
## 6. 枚举 / 数据字典
|
||
|
||
### 6.1 `category`(SettlementCategory)
|
||
|
||
**所属字段**: 路径参数 `category`、响应 `items[].category` | **类型**: String
|
||
|
||
| 值 | 中文 | 说明 |
|
||
|----|------|------|
|
||
| `HOTEL` | 住宿 | 住宿核单分类 |
|
||
| `TICKET` | 门票/游玩项目 | 门票及游玩项目核单分类 |
|
||
| `MEAL` | 餐食 | 餐食核单分类 |
|
||
| `VEHICLE` | 车辆 | 车辆费用核单分类 |
|
||
| `GUIDE` | 导游 | 导游费用核单分类 |
|
||
| `PHOTOGRAPHER` | 摄影 | 摄影费用核单分类 |
|
||
| `OTHER_INCOME` | 其他收入 | 其他收入核单分类 |
|
||
| `OTHER_EXPENSE` | 其他支出 | 其他支出核单分类 |
|
||
|
||
### 6.2 `reportStatus`(SettlementReportStatus)
|
||
|
||
**所属字段**: `reportStatus` | **类型**: String
|
||
|
||
| 值 | 中文 | 说明 |
|
||
|----|------|------|
|
||
| `GENERATED` | 已生成 | 报告已生成,尚未确认 |
|
||
| `CONFIRMED` | 已确认 | 报告已确认 |
|
||
| `STALE` | 已过期 | 来源事实已变化,需要重新生成 |
|
||
|
||
### 6.3 `confirmStatus`
|
||
|
||
**所属字段**: `items[].confirmStatus` | **类型**: String
|
||
|
||
| 值 | 中文 | 说明 |
|
||
|----|------|------|
|
||
| `UNCONFIRMED` | 未确认 | 分类尚未确认 |
|
||
| `CONFIRMED` | 已确认 | 分类已确认 |
|
||
|
||
## 7. 错误码汇总
|
||
|
||
| code | 含义 | 触发场景 |
|
||
|------|------|----------|
|
||
| 584310 | 八个核单分类尚未全部确认或数据已变化 | 生成主报账表前门禁失败 |
|
||
| 584311 | 主报账表尚未生成 | 主报账表查询/确认前置缺失 |
|
||
| 584312 | 主报账表尚未确认或数据已变化 | 生成单团核算表前门禁失败 |
|
||
| 584313 | 单团核算表尚未生成 | 单团核算表查询/确认前置缺失 |
|
||
| 584314 | 单团核算表尚未确认或数据已变化 | finalize 前门禁失败 |
|
||
| 584315 | 核单来源数据已变化,请刷新后重新生成 | 分类或报告指纹过期 |
|
||
| 584316 | 核单报告发生并发变化,请刷新后重试 | 并发确认冲突 |
|
||
| 584317 | 当前报告状态不允许执行该操作 | 当前状态不能执行生成/确认/finalize |
|
||
| 584318 | 空分类必须显式确认,非空分类不得按空分类确认 | `confirmEmpty` 与分类是否为空不匹配 |
|
||
| 584319 | 核单存在未知分类或历史迁移数据不完整 | 分类枚举非法或历史数据缺失 |
|
||
|
||
## 10. 修改前后对比
|
||
|
||
### 10.1 字段级对比
|
||
|
||
| 接口/字段 | 改前 | 改后 |
|
||
|-----------|------|------|
|
||
| `GET /settlement/financial-overview` | 返回应收总览及逐条优惠确认状态 | 只返回应收总览和优惠明细,不再承载确认流 |
|
||
| `POST /settlement/financial-overview/confirm` 请求体 | `expectedOverviewFingerprint` | 接口删除,改用 `POST /settlement/category-checks/{category}/confirm` 的 `expectedSourceFingerprint` + `confirmEmpty` |
|
||
| `POST /settlement/financial-overview/discounts/{discountId}/confirm` 请求体 | `expectedSourceFingerprint` | 接口删除,优惠纳入 8 分类/报告流 |
|
||
| 主报账表 | 无独立响应结构 | 新增 `SettlementReimbursementReportRespVO` |
|
||
| 单团核算表 | 无独立响应结构 | 新增 `SettlementGroupReportRespVO` |
|
||
| 完成核单 | 旧入口为 `POST /settlement/step6/submit` | 新增原型流入口 `POST /settlement/finalize`,返回 `SettlementSubmitRespVO` |
|
||
|
||
### 10.2 行为级对比
|
||
|
||
| 行为 | 改前 | 改后 |
|
||
|------|------|------|
|
||
| 核单确认门禁 | 财务总览/优惠逐条确认 | 8 分类全部确认 |
|
||
| 报账表 | 无独立生成/确认步骤 | 先生成并确认主报账人报账表 |
|
||
| 单团核算 | 无独立生成/确认步骤 | 主报账表确认后生成并确认单团核算表 |
|
||
| 最终提交 | 直接 Step6 提交 | 单团核算表确认后调用 finalize |
|
||
| 旧 POST 接口 | 可调用 | 下线,调用方需迁移 |
|
||
|
||
## 11. 影响评估 / 回滚
|
||
|
||
### 11.1 影响评估
|
||
|
||
- **是否破坏向后兼容**: 是。两个旧 POST 确认接口删除;财务总览查询响应语义收窄。
|
||
- **前端是否必须同步上线**: 是。核单页面需要按 8 分类确认、主报账表、单团核算表、finalize 的顺序对接。
|
||
- **影响已有数据**: 前端接口层不需要处理数据库迁移细节;历史订单在接口层按当前数据计算状态。
|
||
|
||
### 11.2 回滚方案
|
||
|
||
- **回滚方式**: 回滚 PR #5243 后恢复旧确认流。
|
||
- **回滚后清理**: 前端需恢复旧 `financial-overview/confirm` 和 `discounts/{discountId}/confirm` 调用。
|
||
- **回滚耗时**: 取决于后端回滚与重新部署;前端接口调用需同步回退。
|
||
|
||
## 12. 注意事项
|
||
|
||
- 前端不要继续调用已删除的两个旧 POST 确认接口。
|
||
- 8 分类确认必须使用刚查询到的 `sourceFingerprint`,报告确认必须使用刚查询/生成返回的 `sourceFingerprint`。
|
||
- `STALE` 表示来源已变化,不能继续确认。
|
||
- 空分类确认必须传 `confirmEmpty=true`;非空分类必须传 `false`。
|
||
|
||
## 13. 关联 / 联系人
|
||
|
||
### 13.1 链接
|
||
|
||
- **Issue**: [#5219](https://git.1814.love:8443/wx/HL/issues/5219)
|
||
- **PR**: [#5243](https://git.1814.love:8443/wx/HL/pulls/5243)
|
||
- **Merge commit**: [f64606c](https://git.1814.love:8443/wx/HL/commit/f64606c5cc65b52880aaa8985c61e62e0b90e0ea)
|
||
|
||
### 13.2 联系人
|
||
|
||
- **后端负责人**: @yst
|