供应商结算管理 — 技术方案
依据:供应商结算管理功能需求.md(v1.1)
关联:../交易订单管理/交易订单管理技术方案.md(v1.4)、交易订单管理功能需求.md(v1.3)
表与生成逻辑:sql/biz_supplier_settlement.sql 已存在;结算单仅在订单 completePay 时由 SettlementOnPayService 插入
1. 技术架构
| 项 |
说明 |
| 整体 |
RuoYi v3.9.2(springboot2 分支)单体后端 + 若依 Vue2 前端 |
| 运行时 |
JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid |
| 数据库 |
MySQL 5.7.39,InnoDB,utf8mb4 |
| 代码包 |
com.ruoyi.web.modules.trading(与交易订单同包) |
本模块职责
| 能力 |
实现方 |
说明 |
| 生成结算单 |
交易订单 completePay |
SettlementOnPayService + SettlementFeeCalculator + SettlementNoGenerator(已实现) |
| 列表 / 详情 / 完成结算 |
本模块 Controller/Service |
待实现 |
| 打印结算凭证 |
前端 |
调详情接口渲染,无独立打印 API |
| 跳转订单详情 |
— |
不提供(需求 v1.1) |
后端分层
| 组件 |
职责 |
BizSupplierSettlementController |
GET /list、GET /{id}、PUT /completeSettle |
IBizSupplierSettlementService / BizSupplierSettlementServiceImpl |
查询、完成结算事务 |
SettlementValidation(建议) |
结算凭证校验;完成结算前置条件 |
SettlementRules(建议) |
状态常量、提示语 |
BizSupplierSettlementMapper |
扩充分页列表、selectById、updateCompleteSettle |
| 复用 |
SettlementOnPayService、SettlementFeeCalculator、SupplierRules.feeMethodName |
业务摘要
| 场景 |
行为 |
| 列表 |
del_flag=0;settlementNo、orderNo 模糊 AND;create_time DESC;JOIN biz_supplier 取 supplierName |
| 详情 |
主表全字段 + 收费快照 + 凭证 + 状态中文;无订单跳转字段/接口 |
| 完成结算 |
@Transactional:settlement_status=0 → 1,写凭证与 settle_finish_time;不回写订单 |
| 新增/改/删 |
不提供 |
初始化脚本:sql/biz_supplier_settlement.sql(与订单脚本独立执行即可)
2. 源码位置
| 类型 |
路径 |
| Controller |
.../controller/BizSupplierSettlementController.java |
| Service |
.../service/IBizSupplierSettlementService.java、.../impl/BizSupplierSettlementServiceImpl.java |
| 校验 |
.../support/SettlementValidation.java、SettlementRules.java |
| 订单侧生成(已有) |
.../support/SettlementOnPayService.java、SettlementNoGenerator.java、SettlementFeeCalculator.java |
| Mapper |
.../mapper/BizSupplierSettlementMapper.java |
| XML |
mapper/trading/BizSupplierSettlementMapper.xml |
| 实体 |
.../domain/BizSupplierSettlement.java(需补凭证字段 getter/setter) |
| 测试 |
.../test/.../BizSupplierSettlementServiceImplTest.java、BizSupplierSettlementControllerApiTest.java |
3. 数据库设计
3.1 主表 biz_supplier_settlement(已建表)
一笔订单一条记录;uk_order_id 保证 1:1。金额与费率在订单完成支付时写入,本模块只读展示,完成结算仅更新状态与凭证。
| 字段名 |
类型 |
非空 |
默认值 |
说明 |
id |
bigint(20) |
Y |
自增 |
主键 |
settlement_no |
varchar(14) |
Y |
— |
JSD+YYYYMMDD+3 位序号,唯一 |
order_id |
bigint(20) |
Y |
— |
biz_trade_order.id,唯一 |
order_no |
varchar(11) |
Y |
— |
冗余,列表按关联订单号模糊 |
supplier_id |
bigint(20) |
Y |
— |
冗余 |
total_heads |
int(11) |
Y |
— |
来自订单 |
total_amount |
decimal(12,2) |
Y |
— |
来自订单(元) |
fee_method |
tinyint(4) |
Y |
— |
快照:1 按户 2 按头 3 按额 |
fee_standard |
decimal(12,2) |
N |
NULL |
快照:元/头 |
transaction_fee_rate |
decimal(5,2) |
N |
NULL |
快照:交易费率 % |
management_fee_rate |
decimal(5,2) |
N |
NULL |
快照:管理费率 % |
service_fee_amount |
decimal(12,2) |
Y |
— |
服务费(生成时计算固化) |
payable_amount |
decimal(12,2) |
Y |
— |
实际应付 = 总金额 − 服务费 |
settlement_status |
char(1) |
Y |
'0' |
0 待结算 1 已完成 |
settle_voucher_url |
varchar(512) |
N |
NULL |
完成结算时写入 |
settle_voucher_path |
varchar(512) |
N |
NULL |
完成结算时写入 |
settle_finish_time |
datetime |
N |
NULL |
结算完成时间 |
del_flag |
char(1) |
Y |
'0' |
0 存在 2 逻辑删除 |
create_by / create_time / update_by / update_time |
若依惯例 |
— |
— |
结算创建时间 = create_time |
remark |
varchar(500) |
N |
NULL |
备注 |
索引:PRIMARY KEY (id);UNIQUE uk_settlement_no;UNIQUE uk_order_id;KEY idx_order_no;KEY idx_supplier;KEY idx_settlement_status;KEY idx_create_time;KEY idx_del_flag。
DDL:sql/biz_supplier_settlement.sql(无需新增表)。
3.2 关联表(只读)
| 表 |
用途 |
biz_trade_order |
完成结算前校验:订单 order_status=1、del_flag=0 |
biz_supplier |
列表/详情 supplier_name |
3.3 枚举
| 字段 |
值 |
含义 |
settlement_status |
0 / 1 |
待结算 / 已完成 |
del_flag |
0 / 2 |
正常 / 已删 |
fee_method |
1 / 2 / 3 |
按户 / 按头 / 按额(与 biz_supplier 一致) |
3.4 与订单表关系
biz_trade_order (1) ──uk_order_id──► biz_supplier_settlement (1)
- 订单
order_status=0:无结算行。
- 订单
completePay 成功:插入一行 settlement_status=0。
- 本模块
completeSettle 成功:settlement_status=1;订单仍为 order_status=1。
4. 字段命名(JSON 小驼峰)
| JSON |
库表 |
说明 |
id |
id |
主键 |
settlementNo |
settlement_no |
结算单编号 |
orderId |
order_id |
关联订单 ID(详情展示,不用于跳转) |
orderNo |
order_no |
关联订单编号;列表筛选项 |
supplierId |
supplier_id |
|
supplierName |
— |
JOIN biz_supplier |
totalHeads |
total_heads |
|
totalAmount |
total_amount |
|
feeMethod |
fee_method |
1/2/3 |
feeMethodName |
— |
SupplierRules.feeMethodName |
feeStandard |
fee_standard |
按头快照 |
transactionFeeRate |
transaction_fee_rate |
按额快照 % |
managementFeeRate |
management_fee_rate |
按额快照 % |
serviceFeeAmount |
service_fee_amount |
|
payableAmount |
payable_amount |
|
settlementStatus |
settlement_status |
0/1 |
settlementStatusName |
— |
待结算 / 已完成 |
settleVoucherUrl / settleVoucherPath |
结算凭证 |
完成结算入参;已完成可预览 |
createTime |
create_time |
结算创建时间 |
settleFinishTime |
settle_finish_time |
结算完成时间 |
settlementNo(筛) |
settlement_no |
列表模糊 LIKE |
orderNo(筛) |
order_no |
列表模糊 LIKE |
5. 核心业务实现
5.1 结算单生成(订单模块,已实现)
触发:PUT /tradeMarket/tradeOrder/completePay 事务内调用 SettlementOnPayService.createFromOrder。
| 步骤 |
说明 |
| 幂等 |
selectByOrderId 已存在 → 抛错,订单保持待支付 |
| 编号 |
SettlementNoGenerator:JSD+日期+3 位;当日超 999 与订单编号策略一致抛错 |
| 费用 |
SettlementFeeCalculator:HALF_UP 2 位小数;快照 fee_* 与 service_fee_amount、payable_amount |
| 初始状态 |
settlement_status=0;凭证、完成时间为空 |
公式(与功能需求 §3.5 一致):
fee_method=1 → serviceFee = 0
fee_method=2 → serviceFee = totalHeads × feeStandard
fee_method=3 → serviceFee = totalAmount × (transactionFeeRate + managementFeeRate) / 100
payableAmount = totalAmount − serviceFee
5.2 完成结算 completeSettle(本模块)
接口:PUT /tradeMarket/supplierSettlement/completeSettle
事务步骤(全部成功或回滚):
SettlementValidation.validateSettleVoucher:id、settleVoucherUrl、settleVoucherPath 非空;后缀 jpg|jpeg|png(与 TradeOrderValidation.validatePayVoucher 规则一致;大小 ≤10MB 由 /common/upload 保证)。
selectBizSupplierSettlementById:del_flag=0;settlement_status=0;否则「仅待结算状态可完成结算」。
biz_trade_order:order_id 对应订单 order_status=1 且 del_flag=0;否则业务异常。
UPDATE biz_supplier_settlement SET settlement_status='1', settle_voucher_url=?, settle_voucher_path=?, settle_finish_time=now(), update_by=?, update_time=now() WHERE id=? AND settlement_status='0' AND del_flag='0';updated=0 → 已完成或并发冲突提示。
- 不
UPDATE 订单表。
幂等:已完成不展示「完成结算」;接口层对 settlement_status=1 直接拒绝。
5.3 列表 / 详情
- 列表 SQL:
FROM biz_supplier_settlement s LEFT JOIN biz_supplier sup ON s.supplier_id = sup.id AND sup.del_flag='0' WHERE s.del_flag='0'。
- 详情:在列表字段基础上返回收费快照明细(
feeMethod + 对应费率字段);不组装订单 lineList、支付凭证。
- 排序:
s.create_time DESC, s.id DESC。
- 默认分页:
pageSize=20。
5.4 实体与 Mapper 补齐(实现时注意)
当前 BizSupplierSettlement / BizSupplierSettlementMapper.xml 仅支持 insert、selectByOrderId、编号序号查询。实现本模块前需:
- 实体增加
settleVoucherUrl、settleVoucherPath;resultMap 映射 settle_finish_time 及凭证列。
- 新增
selectBizSupplierSettlementList、selectBizSupplierSettlementById、updateCompleteSettle。
6. 接口设计
Base Path:/tradeMarket/supplierSettlement
权限:tradeMarket:supplierSettlement:list|query|settle
响应:AjaxResult / TableDataInfo(code、msg、rows/data)
| 说明 |
HTTP |
URI |
权限 |
| 分页列表 |
GET |
/list |
list |
| 详情 |
GET |
/{id} |
query |
| 完成结算 |
PUT |
/completeSettle |
settle |
本期无 POST/DELETE/PUT / 全量修改。打印凭证由前端根据详情数据生成,无 /print 接口。
6.1 列表 GET /list
| 参数 |
类型 |
必填 |
说明 |
pageNum |
int |
N |
默认 1 |
pageSize |
int |
N |
默认 20 |
settlementNo |
string |
N |
结算单编号模糊 |
orderNo |
string |
N |
关联订单编号模糊 |
- 条件:
del_flag=0;两筛选项同时传则 AND。
- 行字段:功能需求 §5.2 所列(小驼峰见 §4)。
settlementStatus=0:操作区「完成结算」「查看」;1:「打印凭证」「查看」(前端按权限显隐)。
6.2 详情 GET /{id}
data:BizSupplierSettlement 全量展示字段 + supplierName + feeMethodName + settlementStatusName。
- 不返回订单跳转 URL;不嵌套订单明细
lineList。
6.3 完成结算 PUT /completeSettle
| Body |
必填 |
说明 |
id |
Y |
结算单主键 |
settleVoucherUrl |
Y |
先 POST /common/upload |
settleVoucherPath |
Y |
上传返回路径 |
- 成功:
code=200;settlementStatus=1;settleFinishTime 有值。
- 失败:保持
settlement_status=0;msg 示例见功能需求 §12。
6.4 前端联调(共享)
| 用途 |
接口 |
| 结算凭证上传 |
POST /common/upload |
| 查订单(用户自行) |
GET /tradeMarket/tradeOrder/list?orderNo=…(非本模块跳转) |
7. 关联方案:交易订单管理
7.1 职责边界
| 能力 |
交易订单 |
供应商结算(本模块) |
写 biz_supplier_settlement |
completePay 插入 |
— |
| 读 / 完成结算 |
— |
list / {id} / completeSettle |
| 支付凭证 |
订单表 |
— |
| 结算凭证 |
— |
结算表 |
| 平台业务终点 |
订单已完成 |
结算已完成(需求 v1.1) |
| 跨模块跳转 |
— |
禁止跳转订单详情 |
7.2 端到端时序
sequenceDiagram
participant O as tradeOrder
participant S as supplierSettlement
O->>O: completePay(支付凭证)
O->>S: insert 待结算+费用快照
S->>S: completeSettle(结算凭证)
Note over S: 不回写订单;流程结束
7.3 状态对照
订单 order_status: 0 待支付 ──completePay──► 1 已完成
结算 settlement_status: (无) ──生成──► 0 待结算 ──completeSettle──► 1 已完成 [平台终点]
7.4 异常协同(实现校验要点)
| 场景 |
处理 |
| 订单支付失败 |
无结算行 |
| 订单支付成功 |
必有 1 条 settlement_status=0 |
| 结算完成失败 |
保持待结算,可重试 |
| 结算已完成 |
拒绝 completeSettle;订单仍已完成 |
| 订单已逻辑删除 |
不应存在结算;若存在则完成结算校验失败 |
7.5 与订单技术方案交叉引用
| 订单方案章节 |
本模块对应 |
§3.3 biz_supplier_settlement |
§3.1 同表 |
§5.4 completePay |
§5.1 生成逻辑 |
| §7.2 结算接口建议 |
§6 定稿接口 |
| §7.3 状态一致性 |
§7.3 |
8. 菜单与权限(示例)
| 类型 |
名称 |
权限标识 |
| 菜单 |
供应商结算管理 |
tradeMarket:supplierSettlement:list |
| 按钮 |
查询 |
tradeMarket:supplierSettlement:query |
| 按钮 |
完成结算 |
tradeMarket:supplierSettlement:settle |
组件路径建议:tradeMarket/supplierSettlement/index(与 tradeOrder/index 并列,无路由参数跳转订单)。
9. 交付清单
10. 修订记录
| 版本 |
说明 |
| 1.0 |
初稿:对齐功能需求 v1.1;复用已有表与订单侧生成逻辑;列表/详情/完成结算接口;与交易订单关联方案 |