2026/8/29 6:07:34

货运搬家小程序从0到1(九):钱包与分账,每一分钱都要对得上

货运搬家小程序从0到1(九):钱包与分账,每一分钱都要对得上 业务闭环的最后一环钱。司机完单后钱怎么分、怎么提现这部分代码不多但设计错了后期要命值得专门一篇。结算完单瞬间分账司机点完成运输时同一个事务里完成结算// 完单 结算同一事务updateStatus(orderId,IN_PROGRESS,COMPLETED);BigDecimalincomeorder.getTotalFee().multiply(BigDecimal.ONE.subtract(platformRate));// platformRate0.10driver.setBalance(driver.getBalance().add(income));// 加余额walletFlowMapper.insert(收入流水(income));// 记流水平台抽成率放在配置里kuaiban.platform-rate: 0.10改抽成不发版。注意抽成的计算方向收入 总价 × (1 - 抽成率)而不是抽成 总价 × 抽成率收入 总价 - 抽成。两个算法在 BigDecimal 下可能出现分位不一致总收入 平台抽成 ≠ 订单总价差 1 分钱。先定钱归谁剩下的归另一方账才平。流水所有资金变动的唯一事实钱包流水表只认三种类型type含义方向PAY用户支付订单记录平台收入侧INCOME司机完单收入司机 WITHDRAW司机提现司机 −status: 0待打款 / 1已打款核心对账恒等式司机余额 SUM(INCOME) − SUM(已打款 WITHDRAW)。写成单元测试放那儿谁改钱包代码跑一遍余额对不上立刻爆红。提现异步审批先扣后打提现是唯一需要冻结语义的操作publicvoidwithdraw(BigDecimalamount){if(amount.compareTo(BigDecimal.TEN)0)thrownewBizException(最低提现 10 元);// 乐观扣减余额防止并发重复提现introwsdriverMapper.deductBalance(driverId,amount);if(rows0)thrownewBizException(余额不足);// 生成 WITHDRAW 流水status0待打款}流程司机申请 → 余额立即扣减防止拿同一笔钱反复申请→ 后台财务页看到待打款列表 → 管理员线下打款 → 点已打款流水置为 status1。第一版不做自动打款需要企业付款到零钱接口有门槛和费率人工打款 系统记账完全够用而且对账时每笔钱都有清晰的申请→打款链路。一个真实教训别人的有同行的平台提现没做先扣后打司机 10 秒内点了两次提现同一笔余额提了两份。人工打款时才发现钱已经出去了。提现的并发安全比抢单更容易被忽视。本篇成果支付 → 分账 → 提现全链路资金闭环恒等式测试通过。业务侧就齐了接下来三篇写管理后台Vue3 Element Plus 搭建、数据看板然后是联调与上线。