feat(reconciliation): 新增对账文件查询下载及批量补推接口
- 新增GET接口支持按对账月份查询及下载对账文件,文件为CSV格式 - 实现每月3号生成上月完成订单对账文件,文件名格式统一规范 - 支持对账文件内容字段定义及编码格式为UTF-8-BOM以兼容Excel - 新增POST接口支持手动批量补推服务完成通知,支持权益码列表和时间范围筛选 - 实现补推接口的数量限制、幂等处理和dryRun试运行模式 - 添加详细业务规则、输入输出字段及验收标准 - 补充对账流程和批量补推流程的PlantUML流程图及步骤说明
This commit is contained in:
parent
601129a28d
commit
d96a8b2a13
File diff suppressed because it is too large
Load Diff
278
docs/需求文档-PRD.md
278
docs/需求文档-PRD.md
|
|
@ -10,6 +10,9 @@
|
|||
| 服务取消接口 | 接收取消请求,作废券码 | [3.1.2](#312-服务取消接口) |
|
||||
| 订单过期积分查询接口 | 查询过期幸福点信息 | [3.1.4](#314-订单过期积分查询接口) |
|
||||
| 服务详情查询接口 | 获取券码链接展示服务详情 | [3.1.6](#316-服务详情查询接口) |
|
||||
| 对账文件查询接口 | 查询可用的对账文件列表 | [3.4.3](#343-对账文件查询接口) |
|
||||
| 对账文件下载接口 | 根据文件ID下载对账文件 | [3.4.4](#344-对账文件下载接口) |
|
||||
| 批量补推接口 | 手动批量触发服务完成通知 | [3.4.5](#345-批量补推接口) |
|
||||
|
||||
### 调用下游的接口(调用邮储银行API)
|
||||
|
||||
|
|
@ -730,6 +733,132 @@
|
|||
|
||||
---
|
||||
|
||||
#### 3.4.3 对账单下载接口
|
||||
|
||||
**功能描述**:提供GET方式直接下载对账文件,用于管理员或运营人员获取本地处理后的对账数据
|
||||
|
||||
**接口信息**:
|
||||
- 请求方式:GET
|
||||
- 接口路径:/api/v1/reconciliation/download
|
||||
|
||||
**业务规则**:
|
||||
1. 每月3号生成上月服务状态为「服务已完成(300)」的权益订单对账文件
|
||||
2. 对账月份规则:服务完成时间所在月份为对账月份
|
||||
- 例如:服务完成时间 202512210000,对账月份为 2025年12月,对账文件在 2026年1月3日生成
|
||||
3. 对账文件名称格式:`RIGHTS_SERVICE_CHK_{providerCode}_{reconMonth}.csv`
|
||||
- 例如:`RIGHTS_SERVICE_CHK_A101_202512.csv`
|
||||
4. 支持按对账月份查询和下载
|
||||
5. 文件格式为CSV,内容与邮储对账文件格式一致
|
||||
|
||||
**输入**:
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|-----|------|-----|------|
|
||||
| reconMonth | String | M | 对账月份,格式:YYYYMM,例如:202512 |
|
||||
| providerCode | String | C | 服务厂商编号,默认为当前服务商编号,例如:A101 |
|
||||
|
||||
**输出**:
|
||||
直接返回文件流,Content-Type: text/csv,Content-Disposition: attachment; filename="RIGHTS_SERVICE_CHK_A101_202512.csv"
|
||||
|
||||
**对账文件内容字段**:
|
||||
| 序号 | 字段名 | 说明 |
|
||||
|-----|-------|------|
|
||||
| 1 | 统计月份 | YYYYMM |
|
||||
| 2 | 一分机构序号 | province_inst_no |
|
||||
| 3 | 一分机构名称 | 根据机构号映射 |
|
||||
| 4 | 网点机构属性 | 01-自营,02-代理 |
|
||||
| 5 | 积分客户服务编码 | type字段 |
|
||||
| 6 | 服务内容 | 服务名称 |
|
||||
| 7 | 预约时间 | appointment_time,格式:yyyyMMddHHmmss |
|
||||
| 8 | 实际完成时间 | key_usage_time,格式:yyyyMMddHHmmss |
|
||||
| 9 | 权益兑换码 | code字段 |
|
||||
| 10 | 订单号 | order_no |
|
||||
| 11 | 券码状态 | key_status:1-正常,2-已核销,3-已作废,4-已过期 |
|
||||
|
||||
**验收标准**:
|
||||
- [ ] GET请求能正确下载对账文件
|
||||
- [ ] 对账月份参数校验:格式必须为YYYYMM,且不能超过当前月份
|
||||
- [ ] 对账文件只包含status=300(服务已完成)的订单
|
||||
- [ ] 对账文件按服务完成时间所在月份归档
|
||||
- [ ] 文件名格式正确:RIGHTS_SERVICE_CHK_{providerCode}_{reconMonth}.csv
|
||||
- [ ] 对账月份不存在数据时返回空文件或提示"暂无对账数据"
|
||||
- [ ] 文件内容编码为UTF-8-BOM(兼容Excel中文显示)
|
||||
|
||||
**测试用例**:
|
||||
|
||||
| 用例编号 | 测试场景 | 前置条件 | 输入数据 | 预期结果 |
|
||||
|---------|---------|---------|---------|----------|
|
||||
| TC-3.4.3-001 | 正常下载对账文件 | 2025年12月有已完成订单 | reconMonth=202512 | 返回CSV文件流,文件名正确 |
|
||||
| TC-3.4.3-002 | 对账月份格式错误 | - | reconMonth=2025-12 | code=2, msg="参数错误" |
|
||||
| TC-3.4.3-003 | 对账月份超过当前月 | 当前为2026年1月 | reconMonth=202602 | code=4, msg="对账月份不能超过上月" |
|
||||
| TC-3.4.3-004 | 对账月份无数据 | 2025年11月无已完成订单 | reconMonth=202511 | code=4, msg="暂无对账数据" |
|
||||
| TC-3.4.3-005 | 指定服务商编号 | A101有数据,B101无数据 | reconMonth=202512, providerCode=B101 | code=4, msg="暂无对账数据" |
|
||||
|
||||
---
|
||||
|
||||
#### 3.4.4 批量补推接口
|
||||
|
||||
**功能描述**:手动批量触发服务完成通知,用于处理蓝色兄弟已核销但邮储银行未收到服务完成通知的订单
|
||||
|
||||
**接口信息**:
|
||||
- 请求方式:POST
|
||||
- 接口路径:/api/v1/reconciliation/batch-repush
|
||||
|
||||
**业务规则**:
|
||||
1. 查询本地订单状态为「服务已预约(200)」且券码状态为「已核销(2)」的订单
|
||||
2. 批量创建服务完成通知任务(task_type=1)
|
||||
3. 支持按时间范围、权益码列表筛选
|
||||
4. 单次补推数量限制:最多100笔
|
||||
5. 幂等处理:已存在相同类型的待处理任务时跳过
|
||||
|
||||
**输入**:
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|-----|------|-----|------|
|
||||
| codes | String[] | C | 权益码列表,最多100个,与时间范围二选一 |
|
||||
| startTime | String | C | 开始时间,格式:yyyyMMddHHmmss,与codes二选一 |
|
||||
| endTime | String | C | 结束时间,格式:yyyyMMddHHmmss,与codes二选一 |
|
||||
| dryRun | boolean | C | 是否试运行,默认false。true时只返回待补推订单列表,不实际创建任务 |
|
||||
|
||||
**输出**(data字段内容):
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|-----|------|-----|------|
|
||||
| totalCount | int | M | 符合条件的订单总数 |
|
||||
| createdCount | int | M | 新创建的任务数(dryRun=true时为0) |
|
||||
| skippedCount | int | M | 跳过的订单数(已有待处理任务) |
|
||||
| orders | Object[] | C | 订单列表(dryRun=true时返回) |
|
||||
| orders[].orderNo | String | M | 订单号 |
|
||||
| orders[].code | String | M | 权益码 |
|
||||
| orders[].status | int | M | 订单状态 |
|
||||
| orders[].keyStatus | int | M | 券码状态 |
|
||||
| orders[].keyUsageTime | String | C | 核销时间 |
|
||||
| orders[].hasTask | boolean | M | 是否已有待处理任务 |
|
||||
|
||||
**验收标准**:
|
||||
- [ ] 只处理本地status=200(已预约)且key_status=2(已核销)的订单
|
||||
- [ ] 权益码列表和时间范围必须二选一
|
||||
- [ ] 权益码列表最多100个,超过返回"单次补推数量不能超过100笔"
|
||||
- [ ] 时间范围查询结果超过100笔时返回"符合条件的订单超过100笔,请缩小时间范围或使用权益码列表"
|
||||
- [ ] 幂等处理:订单已有task_type=1且status!=2(已完成)的任务时跳过
|
||||
- [ ] dryRun=true时只查询不创建任务
|
||||
- [ ] 创建的任务trigger_source=2(主动查询/手动触发)
|
||||
- [ ] 补推成功后返回创建的任务数和跳过的订单数
|
||||
|
||||
**测试用例**:
|
||||
|
||||
| 用例编号 | 测试场景 | 前置条件 | 输入数据 | 预期结果 |
|
||||
|---------|---------|---------|---------|----------|
|
||||
| TC-3.4.4-001 | 按权益码批量补推 | 3笔订单status=200,key_status=2 | codes=["code1","code2","code3"] | code=0, createdCount=3 |
|
||||
| TC-3.4.4-002 | 按时间范围批量补推 | 2笔订单符合条件 | startTime=20251201000000, endTime=20251231235959 | code=0, createdCount=2 |
|
||||
| TC-3.4.4-003 | 试运行模式 | 2笔订单符合条件 | codes=["code1","code2"], dryRun=true | code=0, createdCount=0, orders返回2笔 |
|
||||
| TC-3.4.4-004 | 权益码超过100个 | - | codes=[101个权益码] | code=2, msg="单次补推数量不能超过100笔" |
|
||||
| TC-3.4.4-005 | 时间范围结果超100笔 | 150笔订单符合条件 | startTime/endTime | code=4, msg="符合条件的订单超过100笔" |
|
||||
| TC-3.4.4-006 | 参数缺失 | - | 不传codes和时间范围 | code=2, msg="参数错误:权益码列表和时间范围必须二选一" |
|
||||
| TC-3.4.4-007 | 幂等-已有待处理任务 | code1已有task_type=1,status=0的任务 | codes=["code1"] | code=0, createdCount=0, skippedCount=1 |
|
||||
| TC-3.4.4-008 | 订单状态不符合 | 订单status=300(已完成) | codes=["code1"] | code=0, totalCount=0 |
|
||||
| TC-3.4.4-009 | 券码状态不符合 | 订单key_status=1(正常) | codes=["code1"] | code=0, totalCount=0 |
|
||||
| TC-3.4.4-010 | 混合场景 | 2笔符合,1笔已有任务,1笔状态不符 | codes=[4个权益码] | code=0, totalCount=2, createdCount=1, skippedCount=1 |
|
||||
|
||||
---
|
||||
|
||||
### 3.5 安全与加密模块
|
||||
|
||||
#### 3.5.1 邮储银行加解密(SM2/SM4/AES)
|
||||
|
|
@ -1415,7 +1544,154 @@ stop
|
|||
|
||||
### 6.4 月度对账流程
|
||||
|
||||
TODO
|
||||
```plantuml
|
||||
@startuml 月度对账流程
|
||||
start
|
||||
|
||||
:定时任务触发(每月3号);
|
||||
|
||||
:查询上月status=300(已完成)的订单;
|
||||
note right: 对账月份=服务完成时间所在月
|
||||
|
||||
if (有订单数据?) then (无)
|
||||
:跳过,不生成对账文件;
|
||||
stop
|
||||
endif
|
||||
|
||||
:生成对账文件;
|
||||
note right: RIGHTS_SERVICE_CHK_{providerCode}_{reconMonth}.csv
|
||||
|
||||
:调用邮储对账文件查询接口;
|
||||
note right: 5s超时
|
||||
|
||||
if (获取文件列表成功?) then (否)
|
||||
:记录错误,等待重试;
|
||||
stop
|
||||
endif
|
||||
|
||||
:调用邮储对账文件下载接口;
|
||||
note right: 5s超时
|
||||
|
||||
if (下载成功?) then (否)
|
||||
:记录错误,等待重试;
|
||||
stop
|
||||
endif
|
||||
|
||||
:SM4解密对账文件;
|
||||
|
||||
:解析对账文件内容;
|
||||
|
||||
while (遍历邮储对账记录?) is (有)
|
||||
:根据权益码查询本地订单;
|
||||
|
||||
if (本地订单存在?) then (否)
|
||||
:记录差异-本地缺失;
|
||||
elseif (状态一致?) then (否)
|
||||
:记录差异-状态不一致;
|
||||
:创建服务完成通知任务;
|
||||
else (是)
|
||||
:标记为已对账;
|
||||
endif
|
||||
endwhile (无)
|
||||
|
||||
:保存对账结果;
|
||||
|
||||
if (有差异?) then (是)
|
||||
:发送告警通知;
|
||||
endif
|
||||
|
||||
:生成对账报告;
|
||||
|
||||
stop
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
||||
**流程步骤说明**:
|
||||
|
||||
| 步骤 | 操作 | 说明 |
|
||||
|-----|------|------|
|
||||
| 1 | 定时触发 | 每月3号执行 |
|
||||
| 2 | 查询本地订单 | 查询上月status=300(已完成)的订单 |
|
||||
| 3 | 生成对账文件 | 生成CSV格式对账文件 |
|
||||
| 4 | 获取邮储对账文件 | 调用邮储查询和下载接口(5s超时) |
|
||||
| 5 | SM4解密 | 使用SM4密钥解密对账文件 |
|
||||
| 6 | 数据核对 | 逐笔对比邮储和本地数据 |
|
||||
| 7 | 差异处理 | 本地缺失或状态不一致时创建补推任务 |
|
||||
| 8 | 生成报告 | 保存对账结果,有差异时发送告警 |
|
||||
|
||||
**对账月份规则**:
|
||||
|
||||
| 服务完成时间 | 对账月份 | 对账文件生成时间 | 对账文件名 |
|
||||
|--------------|---------|--------------|----------|
|
||||
| 202512210000 | 202512 | 2026年1月3日 | RIGHTS_SERVICE_CHK_A101_202512.csv |
|
||||
| 202601010000 | 202601 | 2026年2月3日 | RIGHTS_SERVICE_CHK_A101_202601.csv |
|
||||
|
||||
### 6.4.1 批量补推流程
|
||||
|
||||
```plantuml
|
||||
@startuml 批量补推流程
|
||||
start
|
||||
|
||||
:接收补推请求;
|
||||
|
||||
if (参数校验?) then (失败)
|
||||
:返回参数错误;
|
||||
stop
|
||||
endif
|
||||
|
||||
if (传入codes?) then (是)
|
||||
if (codes数量>100?) then (是)
|
||||
:返回"单次补推不能超过100笔";
|
||||
stop
|
||||
endif
|
||||
:按权益码列表查询订单;
|
||||
else (否)
|
||||
:按时间范围查询订单;
|
||||
if (结果数量>100?) then (是)
|
||||
:返回"符合条件订单超过100笔";
|
||||
stop
|
||||
endif
|
||||
endif
|
||||
|
||||
:筛选status=200且key_status=2的订单;
|
||||
|
||||
if (dryRun=true?) then (是)
|
||||
:返回待补推订单列表;
|
||||
stop
|
||||
endif
|
||||
|
||||
while (遍历订单?) is (有)
|
||||
:检查是否已有待处理任务;
|
||||
|
||||
if (已有任务?) then (是)
|
||||
:skippedCount++;
|
||||
else (否)
|
||||
:创建服务完成通知任务;
|
||||
note right: task_type=1\ntrigger_source=2
|
||||
:createdCount++;
|
||||
endif
|
||||
endwhile (无)
|
||||
|
||||
:返回补推结果;
|
||||
note right: totalCount, createdCount, skippedCount
|
||||
|
||||
stop
|
||||
|
||||
@enduml
|
||||
```
|
||||
|
||||
**流程步骤说明**:
|
||||
|
||||
| 步骤 | 操作 | 说明 |
|
||||
|-----|------|------|
|
||||
| 1 | 参数校验 | codes和时间范围必须二选一 |
|
||||
| 2 | 数量校验 | 单次最多处理100笔 |
|
||||
| 3 | 查询订单 | 筛选status=200且key_status=2的订单 |
|
||||
| 4 | 试运行判断 | dryRun=true时只查询不创建任务 |
|
||||
| 5 | 幂等检查 | 已有待处理任务的订单跳过 |
|
||||
| 6 | 创建任务 | task_type=1, trigger_source=2 |
|
||||
| 7 | 返回结果 | 包含创建数量和跳过数量 |
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue