推送 4 条核单侧改造接口变更 changelog(PR1 线下收款 / PR2 子表扩列 / PR3 recon+payout / PR5 submit收口)

这个提交包含在:
yaosutu 2026-07-07 17:59:33 +08:00
父节点 532afb1c97
当前提交 83cbc282aa
共有 4 个文件被更改,包括 807 次插入0 次删除

查看文件

@ -0,0 +1,193 @@
# 线下收款登记(司机现场代收人 / 对公转账)
- **变更日期**: 2026-07-07
- **端类型**: 管理后台
- **变更类型**: 新增接口
- **Issue**: https://git.1814.love:8443/wx/HL/issues/4763
- **PR**: https://git.1814.love:8443/wx/HL/pulls/4766
---
## 1. 接口背景
核单 epic PR1。核单流程中,定制师需要记录非微信支付渠道的线下收款司机现场代收人现金、对公转账,并确保订单 `paid_amount` 实时更新。
登记成功后事务层推进 `paid_amount` 累加并重算 `pay_status`(PARTIAL_PAID/FULLY_PAID)。
已撤销的凭据行保留在列表供审计溯源。
---
## 2. 变更清单
| 序号 | 方法 | 路径 | 说明 |
|------|------|------|------|
| 1 | POST | `/v3/admin/order/{orderId}/payment/manual-receipt` | 登记线下收款 |
| 2 | DELETE | `/v3/admin/order/{orderId}/payment/manual-receipt/{receiptId}` | 撤销线下收款(转删,行保留) |
| 3 | GET | `/v3/admin/order/{orderId}/payment/manual-receipt` | 查询订单线下收款列表 |
---
## 3. 接口详情
| 项 | 说明 |
|-----|------|
| 认证 | JWT Bearer(管理端), Gateway 注入 X-Admin-Id/X-Admin-RealName |
| 幂等性 | POST 非幂等; DELETE 幂等守卫(已撤销返 520406 |
| 限流 | 网关全局限流 |
| 订单状态白名单 | 仅 CANCELLED 拒绝,其余状态(含已结算)均可登记 |
---
## 4. 接口入参
### 4.1 路径参数(三个接口通用)
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| orderId | Long | 是 | 订单 ID |
DELETE 额外路径参数: receiptId (Long, 必, 凭据 ID 由 POST 响应获取)
### 4.2 请求体(POST)
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| channel | String | 是 | 收款渠道: DRIVER_CASH/BANK_TRANSFER |
| payType | String | 是 | 款项类型: DEPOSIT/BALANCE/FULL |
| amount | BigDecimal | 是 | >0 |
| receivedAt | LocalDateTime | 否 | 可补录历史,不传默认当前 |
| transferRef | String | 条件必填 | `BANK_TRANSFER`时必填 |
| collectorStaffId | Long | 条件必填 | `DRIVER_CASH`时必填且属本订单人员 |
| voucherUrls | List<String> | 否 | 凭证图片 URL |
| remark | String | 否 | 备注, max 500 |
**DELETE 请求体**: voidReason (String, 否, 撤销原因)
---
## 5. 出参字段
POST/DELETE 返回单条 `ManualReceiptVO`,GET 返回 `List<ManualReceiptVO>`
> `paidAmountAfter`/`payStatusAfter` 仅在 POST/DELETE 响应有値,GET 列表为 null。
| 字段 | 类型 | 说明 |
|------|------|------|
| id | String(Long) | 凭据 ID(雪花序列化) |
| orderId | String(Long) | 订单 ID |
| channel | String | DRIVER_CASH/BANK_TRANSFER |
| channelLabel | String | 渠道显示标签 |
| payType | String | DEPOSIT/BALANCE/FULL |
| payTypeLabel | String | 款项显示标签 |
| amount | BigDecimal | 收款金额 |
| receivedAt | LocalDateTime | 收款时间 |
| collectorStaffId | String(Long) | 代收人 assignmentId, 仅 DRIVER_CASH 有値 |
| collectorStaffName | String | 代收人姓名, 仅 DRIVER_CASH 有値 |
| transferRef | String | 流水号, 仅 BANK_TRANSFER 有値 |
| voucherUrls | List<String> | 凭证图片 URL |
| remark | String | 备注 |
| operatorName | String | 登记人姓名 |
| createTime | LocalDateTime | 登记时间 |
| voided | Boolean | 是否已撤销 |
| voidedByName/voidedAt/voidReason | - | 撤销时有値 |
| paidAmountAfter | BigDecimal | 操作后订单累计已付金额, GET 为 null |
| payStatusAfter | String | 操作后订单支付状态, GET 为 null |
---
## 6. 枚举/数据字典
**channel:** DRIVER_CASH(司机现场代收人) / BANK_TRANSFER(对公转账)
**payType:** DEPOSIT(订金) / BALANCE(尾款) / FULL(全款)
**payStatusAfter:** UNPAID(未付款) / PARTIAL_PAID(已付订金) / FULLY_PAID(已付全款)
---
## 7. 错误码
| 错误码 | 含义 | 触发场景 |
|--------|------|---------|
| 520401 | 收款渠道非法 | channel not DRIVER_CASH/BANK_TRANSFER |
| 520402 | 对公转账必填转账流水号 | channel=BANK_TRANSFER & transferRef 为空 |
| 520403 | 必须指定代收人 | channel=DRIVER_CASH & collectorStaffId 为空 |
| 520404 | 代收人不属本订单人员 | collectorStaffId 不在order_staff_assignment中 |
| 520405 | 凭据不存在 | receiptId 非法 |
| 520406 | 已撤销,无法重复 | 对已撤销行再 DELETE |
| 520407 | 订单已取消,不允许登记 | 订单状态为 CANCELLED |
| 520408 | 收款金额必须>0 | amount<=0 |
---
## 8. 示例
### 8.1 典型成功 -- 登记司机现场代收人尾款
请求:
```http
POST /v3/admin/order/1234567890123456/payment/manual-receipt
Content-Type: application/json
X-Admin-RealName: 扎西师傅
{
"channel": "DRIVER_CASH",
"payType": "BALANCE",
"amount": 8800.00,
"collectorStaffId": "9800001001",
"remark": "客户现场支付尾款"
}
```
响应:
```json
{
"code": 200,
"data": {
"id": "1900000001000001",
"channelLabel": "司机现场代收人",
"payTypeLabel": "尾款",
"amount": 8800.00,
"collectorStaffName": "扎西师傅",
"voided": false,
"paidAmountAfter": 24800.00,
"payStatusAfter": "FULLY_PAID"
}
}
```
### 8.2 边界 -- 对公转账,补录历史时间
```json
{
"channel": "BANK_TRANSFER",
"payType": "DEPOSIT",
"amount": 5000.00,
"receivedAt": "2026-06-20T10:00:00",
"transferRef": "GZL20260620001"
}
```
返回: paidAmountAfter 为当前累计已付金额。
### 8.3 业务失败 -- DRIVER_CASH 未指定代收人
```json
{
"channel": "DRIVER_CASH",
"amount": 3000.00
}
```
```json
{
"code": 520403,
"msg": "司机现场必须指定代收人"
}
```
---
## 9. 业务边界
**适用:** 客户现金付款 / 对公转账补录
**不适用:** 微信支付/支付宝 / 订单已取消
**特殊边界:**
- 同一订单可登记多条,每条独立计入`paid_amount`
- 撤销后`paid_amount`同事务回退,行记录保留
- paidAmountAfter/payStatusAfter 仅在 POST/DELETE 响应, GET 列表为 null
---
## 12. 注意事项
- id/orderId 均为 Long 雪花,序列化为字符串,前端禁 Number
- collectorStaffId 属于本订单人员配置(order_staff_assignment)中选取
- 登记后在核单对账页查看`paid_amount`,需重请 GET /v3/admin/order/{orderId}/settlement/recon
---
## 13. 关联/联系人
- Issue: https://git.1814.love:8443/wx/HL/issues/4763
- PR: https://git.1814.love:8443/wx/HL/pulls/4766
- Commit: https://git.1814.love:8443/wx/HL/commit/076bd285a5cc87665fdf431f9fe0a704dcdd7a33
- 后端负责人: 腰苏图

查看文件

@ -0,0 +1,228 @@
# 核单子表扩列
- **变更日期**: 2026-07-07
- **端类型**: 管理后台
- **变更类型**: 修改接口
- **Issue**: https://git.1814.love:8443/wx/HL/issues/4764
- **PR**: https://git.1814.love:8443/wx/HL/pulls/4767
---
## 1. 接口背景
核单 epic PR2。核单三个子表车席、馨票、人员费用分别扩充字段,具体
- 车席 Step 1: `HotelItemVO` 新增 `voucherUrls`(住宿凭证图片)
- 馨票 Step 2: `TicketItemVO` 新增 `paymentMethod` / `voucherUrls``scenicAssignmentId` 由可空改必填(❗ 破坏兆容)
- 人员费用 Step 3: `StaffFeeItemVO` 新增 `reimburse``SettlementStaffFeesSaveRespVO` 新增 `isPrimaryReporter` / `reimburse`
---
## 2. 变更清单
| 序号 | 方法 | 路径 | 说明 |
|------|------|------|------|
| 1 | GET | `/v3/admin/order/{orderId}/settlement/step1` | Step 1 查询,`HotelItemVO` +`voucherUrls` |
| 2 | PUT | `/v3/admin/order/{orderId}/settlement/step1` | Step 1 保存,入参`HotelItemVO` +`voucherUrls` |
| 3 | GET | `/v3/admin/order/{orderId}/settlement/step2` | Step 2 查询,`TicketItemVO` +`paymentMethod`/`voucherUrls`; `scenicAssignmentId` 由可空改必填 |
| 4 | PUT | `/v3/admin/order/{orderId}/settlement/step2` | Step 2 保存,同上 |
| 5 | GET | `/v3/admin/order/{orderId}/settlement/step3` | Step 3 查询,响应 +`isPrimaryReporter`/`reimburse` |
| 6 | PUT | `/v3/admin/order/{orderId}/settlement/step3` | Step 3 保存,入参 +`reimburse` |
---
## 3. 接口详情
| 项 | 说明 |
|-----|------|
| 认证 | JWT Bearer(管理端) |
| 幂等性 | PUT 非幂等(每次全量覆写子表) |
| 核单状态 | 仅允许在 settlement_status=IN_PROGRESS 时调用 |
---
## 4. 接口入参
### 4.1 路径参数(六个接口通用)
| orderId | Long | 是 | 订单 ID |
### 4.2 Step 1 PUT 请求体(`List<HotelItemVO>`
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | Long | 否 | 空表新建行 |
| hotelAssignmentId | Long | 否 | 酒店配置 ID |
| stayDate | LocalDate | 是 | 入住日期 |
| roomType | String | 否 | 房间类型 |
| roomCount | Integer | 是 | 房间数量 |
| plannedCost | BigDecimal | 否 | 计划成本 |
| actualCost | BigDecimal | 否 | 实际成本 |
| paymentMethod | String | 否 | SIGNED/COMPANY_PAID/CASH_PAID |
| settleType | String | 否 | 派生行类型cash/sign/company |
| remark | String | 否 | 备注 |
| **voucherUrls** | List<String> | 否 | **✨ 新增): 住宿凭证图片 URL |
### 4.3 Step 2 PUT 请求体(`List<TicketItemVO>`
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| sourceType | String | 是 | SCENIC_ASSIGNMENT/ACTIVITY_ASSIGNMENT |
| **scenicAssignmentId** | Long | **是** | **❗ 破坏兆容:旧可空,新必填** |
| dayDate | LocalDate | 是 | 游玩日期 |
| ticketCount | Integer | 是 | 馨票人数 |
| ticketUnitPrice | BigDecimal | 否 | 单价 |
| actualCost | BigDecimal | 否 | 实际成本 |
| **paymentMethod** | String | 否 | **✨ 新增**: SIGNED/COMPANY_PAID/CASH_PAID |
| **voucherUrls** | List<String> | 否 | **✨ 新增**: 馨票凭证图片 URL |
| remark | String | 否 | 备注 |
### 4.4 Step 3 PUT 请求体(`List<StaffFeeItemVO>`
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | Long | 否 | 实体主键 |
| staffRole | String | 是 | LEADER/DRIVER/GUIDE/PHOTOGRAPHER/OTHER |
| staffId | Long | 否 | 人员 ID |
| detail | Object | 否 | 按角色不同, 见 §6 |
| **reimburse** | BigDecimal | 否 | **✨ 新增**: 小算补助金额,⊰ 0 |
| remark | String | 否 | 备注 |
---
## 5. 出参字段
### Step 1 GET 响应(`List<HotelItemVO>`
> 新增 **`voucherUrls`** (List<String>)
### Step 2 GET 响应(`List<TicketItemVO>`
> 新增 **`paymentMethod`** (String) / **`voucherUrls`** (List<String>)
### Step 3 GET 响应(`SettlementStaffFeesSaveRespVO`
`StaffFeeRespItemVO` 内嵌子字段:
| 字段 | 类型 | 说明 |
|------|------|------|
| **isPrimaryReporter** | Boolean | **✨ 新增**: 是否主报账人,由 AssignmentService 实时派生 |
| **reimburse** | BigDecimal | **✨ 新增**: 小算补助金额,入参回显 |
---
## 6. 枚举/数据字典
**paymentMethod / settleType**
| 値 | 含义 |
|------|------|
| SIGNED | 签单结算(酒店收取相应金额) |
| COMPANY_PAID | 公司已付(公库打款) |
| CASH_PAID | 现付(司机墙付) |
**staffRole**
| 値 | 含义 |
|------|------|
| LEADER | 地接 |
| DRIVER | 司机 |
| GUIDE | 导游 |
| PHOTOGRAPHER | 摄影师 |
| OTHER | 其他 |
**detail 结构(按角色)**
- DRIVER: `{is_used, daily_fee, extra_cost, days[{date,is_used}]}`
- GUIDE/PHOTOGRAPHER: `{persons[{staffId,days[{date,is_used}]}], per_day}`
- LEADER: `{days, per_day}`
- OTHER: `[{name, amount}]`
---
## 7. 错误码
| 错误码 | 含义 | 触发场景 |
|--------|------|---------|
| 584028 | ❗ 破坏兆容 -- 馨票行必须关联资源配置 | Step 2 PUT 中 scenicAssignmentId 为空(曾可空,现必填) |
| 584001-584009 | Step 1 酒店校验错 | - |
| 584010-584018 | Step 2 馨票校验错 | - |
| 584020-584027 | Step 3 人员费用校验错 | - |
---
## 8. 示例
### 8.1 典型成功 -- Step 2 PUT `scenicAssignmentId`必填)
```http
PUT /v3/admin/order/1234567890123456/settlement/step2
Content-Type: application/json
[{
"sourceType": "SCENIC_ASSIGNMENT",
"scenicAssignmentId": 98001,
"dayDate": "2026-07-10",
"ticketCount": 4,
"actualCost": 1200.00,
"paymentMethod": "CASH_PAID",
"voucherUrls": ["https://oss.example.com/ticket.jpg"]
}]
```
响应: 200 OK
### 8.2 边界 -- Step 3 GET `isPrimaryReporter` = true
```json
{
"code": 200,
"data": {
"items": [{
"staffRole": "DRIVER",
"isPrimaryReporter": true,
"reimburse": 500.00
}]
}
}
```
### 8.3 业务失败 -- scenicAssignmentId 为空触发 584028
```json
[{
"sourceType": "SCENIC_ASSIGNMENT",
"scenicAssignmentId": null,
"dayDate": "2026-07-10"
}]
```
```json
{
"code": 584028,
"msg": "馨票行必须关联资源配置(现必填,曾可空)"
}
```
---
## 9. 业务边界
适用: 核单流程中内 (settlement_status=IN_PROGRESS)
不适用: 已提交或已结算
特殊边界:
- Step 1 `voucherUrls`: 不传默空列表,传空删除已传的凭证
- Step 2 scenicAssignmentId: 必填,不再允许自由录入 (破坏兆容!)
- Step 3 isPrimaryReporter: 实时派生,前端只读
---
## 10. 修改前后对比
### Step 2 `TicketItemVO` 字段变化
| 字段 | 修改前 | 修改后 |
|------|------|------|
| scenicAssignmentId | 可空 | 必填 (❗破坏兆容) |
| paymentMethod | 无 | 新增 String |
| voucherUrls | 无 | 新增 List<String> |
### Step 3 `StaffFeeRespItemVO` 字段变化
| 字段 | 修改前 | 修改后 |
|------|------|------|
| isPrimaryReporter | 无 | 新增 Boolean |
| reimburse | 无 | 新增 BigDecimal |
---
## 11. 影响评估/回滚
破坏兆容: scenicAssignmentId 旧可空, 新必填。前端补充 scenicAssignmentId字段后提交。
回滚: 无需回滚,此为小版本内造数据制约。
---
## 12. 注意事项
- scenicAssignmentId 必填是 **破坏兆容变更**
- isPrimaryReporter 实时计算,前端只读
---
## 13. 关联/联系人
- Issue: https://git.1814.love:8443/wx/HL/issues/4764
- PR: https://git.1814.love:8443/wx/HL/pulls/4767
- Commit: https://git.1814.love:8443/wx/HL/commit/3fdb51f5aac7ee6bee58f8e9ab125d82859eaffd
- 后端负责人: 腰苏图

查看文件

@ -0,0 +1,213 @@
# 核单对账(recon)+小算抨款(payout) 新增接口
- **变更日期**: 2026-07-07
- **端类型**: 管理后台
- **变更类型**: 新增接口
- **Issue**: https://git.1814.love:8443/wx/HL/issues/4768
- **PR**: https://git.1814.love:8443/wx/HL/pulls/4770
---
## 1. 接口背景
核单 epic PR3。在核单单子表喅录完毕后,定制师需要进行两项补充
1. **recon** (对账): 录入市属司机代收尾款信息、转账信息、预支冲抵确认、签字单回收
2. **payout** (小算抨款): 查看干系人员应收金额,并确认转账状态
recon 派生字段说明:
- 入参字段(数据库存储): customerCashToDriver / customerCashCollectedFlag / otherCollect / transferStatus / transferDate / transferRef / advanceSettledFlag / signedVoucher
- 派生字段(实时派生): driverCollected / publicPrepaid / primaryDue / advanceOutstanding / reconNet
- 公式: reconNet = driverCollected - publicPrepaid - primaryDue - advanceOutstanding
---
## 2. 变更清单
| 序号 | 方法 | 路径 | 说明 |
|------|------|------|------|
| 1 | GET | `/v3/admin/order/{orderId}/settlement/recon` | 核单对账查询 |
| 2 | PUT | `/v3/admin/order/{orderId}/settlement/recon` | 核单对账保存 |
| 3 | GET | `/v3/admin/order/{orderId}/settlement/payout` | 小算抨款列表查询 |
| 4 | PUT | `/v3/admin/order/{orderId}/settlement/payout` | 小算抨款状态更新 |
---
## 3. 接口详情
| 项 | 说明 |
|-----|------|
| 认证 | JWT Bearer(管理端) |
| 幂等性 | PUT recon: upsert(同一 orderId 却覆)。 PUT payout: 幂等守卫(匹配需授权人员) |
| HEDAN状态 | settlement_status=IN_PROGRESS 时可调用 |
---
## 4. 接口入参
### 4.1 路径参数(四个接口通用)
| orderId | Long | 是 | 订单 ID |
### 4.2 PUT recon 请求体(`SettlementReconSaveReqVO`
全部字段可空, null=保持现有値 (upsert 语义):
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| customerCashToDriver | BigDecimal | 否 | 司机代收尾款 (null=累加 DRIVER_CASH) |
| customerCashCollectedFlag | Boolean | 否 | 尾款是否已收 |
| otherCollect | List<OtherCollectItemVO> | 否 | 其他代收项 |
| transferStatus | String | 否 | PENDING/COMPLETED |
| transferDate | LocalDate | 否 | 转账日期 |
| transferRef | String | 条件 | transferStatus=COMPLETED 时必填 |
| advanceSettledFlag | Boolean | 否 | 预支确认冲扣 |
| signedVoucher | SignedVoucherVO | 否 | 签字单回收,详见 4.2.1 |
#### 4.2.1 OtherCollectItemVO
| name | String | 项目名称 |
| amount | BigDecimal | 金额 |
| collectedFlag | Boolean | 是否已收 |
#### 4.2.2 SignedVoucherVO
| files | List<FileItem> | 签字单文件列表 |
| note | String | 备注 |
FileItem: { name(文件名), url(OSS 地址) }
### 4.3 PUT payout 请求体(`SettlementPayoutSaveReqVO`
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| items | List<Item> | 是 | 抨款列表 |
Item 字段:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| staffId | Long | 否 | 人员 ID |
| staffRole | String | 是 | LEADER/DRIVER/GUIDE/PHOTOGRAPHER/OTHER |
| staffName | String | 是 | 展示性 |
| settleStatus | String | 是 | PENDING/COMPLETED |
| settledDate | LocalDate | 否 | 收款日期 |
| transferRef | String | 否 | 转账流水号 |
---
## 5. 出参字段
### GET recon 响应(`SettlementReconRespVO`
| 字段 | 类型 | 说明 |
|------|------|------|
| customerCashToDriver | BigDecimal | 司机代收尾款 |
| customerCashCollectedFlag | Boolean | 尾款是否已收 |
| otherCollect | List<OtherCollectItemVO> | 其他代收 |
| transferStatus | String | 转账状态 PENDING/COMPLETED |
| transferDate | LocalDate | 转账日期 |
| transferRef | String | 转账流水号 |
| advanceSettledFlag | Boolean | 预支冲扣确认 |
| signedVoucher | SignedVoucherVO | 签字单回收 |
| primaryName | String | 主报账人姓名,实时派生 |
| primaryRole | String | 主报账人角色,实时派生 |
| driverCollected | BigDecimal | 司机实际代收 = customerCashToDriver + Σ DRIVER_CASH |
| publicPrepaid | BigDecimal | 公库预付 |
| primaryDue | BigDecimal | 主报账人应付 |
| advanceOutstanding | BigDecimal | 预支未充 |
| reconNet | BigDecimal | **对账夹算** = driverCollected - publicPrepaid - primaryDue - advanceOutstanding |
### GET payout 响应(`List<SettlementPayoutItemVO>`
| 字段 | 类型 | 说明 |
|------|------|------|
| staffId | Long | 人员 ID |
| staffName | String | 姓名 |
| staffRole | String | 角色: LEADER/DRIVER/GUIDE/PHOTOGRAPHER/OTHER |
| laborCost | BigDecimal | 工资/劳务费 |
| reimburse | BigDecimal | 小算补助金额 |
| dueAmount | BigDecimal | **应付** = laborCost + reimburse |
| settleStatus | String | PENDING/COMPLETED |
| settledDate | LocalDate | 实际收款日期 |
| transferRef | String | 转账流水号 |
---
## 6. 枚举/数据字典
**transferStatus**
| 値 | 含义 |
|------|------|
| PENDING | 待转 |
| COMPLETED | 已转账 |
**settleStatus (payout)**
| 値 | 含义 |
|------|------|
| PENDING | 待抨款 |
| COMPLETED | 已抨款 |
---
## 7. 错误码
| 错误码 | 含义 |
|--------|------|
| 584xxx | settlement_status 未为 IN_PROGRESS |
---
## 8. 示例
### 8.1 典型成功 -- GET recon
```json
{
"code": 200,
"data": {
"customerCashToDriver": 2000.00,
"transferStatus": "PENDING",
"primaryName": "张三",
"driverCollected": 3500.00,
"publicPrepaid": 1200.00,
"primaryDue": 800.00,
"advanceOutstanding": 0.00,
"reconNet": 1500.00
}
}
```
### 8.2 边界 -- PUT recon, transferStatus=COMPLETED+transferRef
```http
PUT /v3/admin/order/1234567890123456/settlement/recon
{
"transferStatus": "COMPLETED",
"transferDate": "2026-07-10",
"transferRef": "202607100001"
}
```
```json
{
"code": 200,
"data": null
}
```
### 8.3 业务失败 -- transferRef 为空触发错误
```json
{
"transferStatus": "COMPLETED"
}
```
```json
{
"code": 584xxx,
"msg": "transferRef 必填( transferStatus=COMPLETED"
}
```
---
## 9. 业务边界
适用: settlement_status=IN_PROGRESS
不适用: 已提交或已结算
特殊边界:
- reconNet 为负属正常现象
- payout staffId 可空(外请按实填 null)
---
## 12. 注意事项
- reconNet 公式: driverCollected - publicPrepaid - primaryDue - advanceOutstanding
- PUT recon: null 字段保持现有値,仅传变动字段
---
## 13. 关联/联系人
- Issue: https://git.1814.love:8443/wx/HL/issues/4768
- PR: https://git.1814.love:8443/wx/HL/pulls/4770
- Commit: https://git.1814.love:8443/wx/HL/commit/cbff5a4d2f0706732c360c0ec99609c4687e2749
- 后端负责人: 腰苏图

查看文件

@ -0,0 +1,173 @@
# 核单 Step 6 submit 收口务 (修改接口)
- **变更日期**: 2026-07-07
- **端类型**: 管理后台
- **变更类型**: 修改接口
- **Issue**: https://git.1814.love:8443/wx/HL/issues/4780
- **PR**: https://git.1814.love:8443/wx/HL/pulls/4783
---
## 1. 接口背景
核单 epic PR5。 Step 6 submit (POST `/v3/admin/order/{orderId}/settlement/step6/submit`) 有两项修改:
1. **出参新增 `warnings` 字段(软预警列表)**: 软预警不阻塑提交,提交定制师补传凭证
2. **`orderStatusAfter` 値变更**: 将 "已结算" 改为 "待财务复核"
**submit 阈条件新增** (任一不满即返错误):
- 584081: recon 对账数据不完整 (财务人员要地接确认尾款))
- 584082: 尾款未收全 (customerCashCollectedFlag=false 时)
- 584083: 转账未完成 (transferStatus != COMPLETED 时)
- 584084: 预支未冲扣 (advanceSettledFlag=false 时)
- 584085: payout 未全部 COMPLETED (有人员尚未抨款))
---
## 2. 变更清单
| 变更项 | 内容 |
|------|------|
| orderStatusAfter | "已结算" -> "待财务复核" (❗ 破坏兆容) |
| 新增 `warnings` | List<String>, 软预警列表,不阻塑,可空 |
| submit 阈条件 | 584081/084082/584083/584084/584085 新增 |
---
## 3. 接口详情
| 项 | 说明 |
|-----|------|
| 方法 | POST |
| 路径 | /v3/admin/order/{orderId}/settlement/step6/submit |
| 认证 | JWT Bearer(管理端) |
| 幂等性 | 非幂等(重复提交不幂) |
| 核单状态 | settlement_status=IN_PROGRESS |
---
## 4. 接口入参
### 4.1 路径参数
| orderId | Long | 是 | 订单 ID |
### 4.2 请求体
无 (空请求体)
---
## 5. 出参字段(`SettlementSubmitRespVO`
| 字段 | 类型 | 说明 |
|------|------|------|
| summaryId | Long | settlement_summary 主键 |
| orderId | Long | 订单 ID |
| settledAt | LocalDateTime | 核单完成时间 |
| totalAmount | BigDecimal | 订单总金额快照 |
| paidAmount | BigDecimal | 已付金额快照 |
| balanceAmount | BigDecimal | 尾款金额 |
| roomCost | BigDecimal | 住宿实际成本 |
| ticketCost | BigDecimal | 门票实际成本 |
| staffCost | BigDecimal | 人员费用实际成本 |
| subsidyCost | BigDecimal | 补助实际成本 |
| insurancePremium | BigDecimal | 保险实际保费 |
| totalActualCost | BigDecimal | 总实际成本=四子表+保险 |
| driverTransferAmount | BigDecimal | 给司机转账金额 |
| profitAmount | BigDecimal | 公司毛利 |
| profitRate | BigDecimal | 毛利率(小数) |
| **orderStatusAfter** | String | **❗ 广报 "待财务复核" (修改前: "已结算")** |
| mqTriggered | Boolean | OrderSettledEvent 是否触发成功 |
| **warnings** | List<String> | **✨ 新增**: 软预警, 不阻塑, null=无预警 |
---
## 6. 枚举/数据字典
无枚举字段。 orderStatusAfter 是文本展示.
---
## 7. 错误码
| 错误码 | 含义 | 触发场景 |
|--------|------|---------|
| 584081 | recon 对账数据不完整 | 未完全填写 recon 数据 |
| 584082 | 尾款未收 | customerCashCollectedFlag=false |
| 584083 | 转账未完成 | transferStatus != COMPLETED |
| 584084 | 预支未冲扣 | advanceSettledFlag=false |
| 584085 | payout 未封 COMPLETED | 有人员尚未抨款 |
---
## 8. 示例
### 8.1 典型成功 -- 提交后带 warnings
```json
{
"code": 200,
"data": {
"summaryId": 9600000000001,
"orderId": 1234567890123456,
"orderStatusAfter": "待财务复核",
"totalAmount": 24800.00,
"paidAmount": 24800.00,
"balanceAmount": 0.00,
"totalActualCost": 23120.00,
"profitAmount": 1680.00,
"profitRate": 0.0677,
"mqTriggered": true,
"warnings": ["住宿 D2 现付缺凭证"]
}
}
```
### 8.2 边界 -- warnings 为空,全部验完整
```json
{
"code": 200,
"data": {
"orderStatusAfter": "待财务复核",
"mqTriggered": true,
"warnings": null
}
}
```
### 8.3 业务失败 -- recon 未完全填写触发 584081
```json
{
"code": 584081,
"msg": "对账数据不完整,请先完善 recon 信息"
}
```
---
## 9. 业务边界
适用: settlement_status=IN_PROGRESS
不适用: 已提交或已结算
特殊边界:
- warnings 列表不为空时,定制师详阅并处理(如补传凭证)
---
## 10. 修改前后对比
| 字段 / 行为 | 修改前 | 修改后 |
|------|------|------|
| orderStatusAfter | "已结算" | "待财务复核" |
| warnings | 无 | List<String> (可空,软预警列表) |
| submit 阈条件 | 仅 SETTLEMENT_STATUS_NOT_IN_PROGRESS | +584081~584085 |
---
## 11. 影响评估/回滚
**破坏兆容:** orderStatusAfter 变为 "待财务复核" -- 前端如果硬编 "已结算" 却仅需更新判断逻辑。
**前端同步上线:**
- 提交后状态按 "待财务复核" 展示,不再 "已结算"
- warnings 非空时展示提示,建议定制师补传凯缺凭证
**回滚方案:** 无需回滚,状态变更属正常业务流程变更。
---
## 12. 注意事酹
- orderStatusAfter 修改是 **破坏兆容变更**,前端需更新判断逻辑
- warnings 列表需备意 null (展示套带信息或展示 toast)
---
## 13. 关联/联系人
- Issue: https://git.1814.love:8443/wx/HL/issues/4780
- PR: https://git.1814.love:8443/wx/HL/pulls/4783
- Commit: https://git.1814.love:8443/wx/HL/commit/f4877036d4d8f8ac2d56573a16f81a30e1dc2b43
- 后端负责人: 腰苏图