CLAUDE.md 3.4 KB

洗车系统 (car-wash-java)

项目结构

car-wash-java/
├── car-wash-entity/      # 实体、VO、SQL 迁移脚本
├── car-wash-mapper/      # MyBatis-Plus Mapper
├── car-wash-service/     # 核心业务逻辑
├── car-wash-common/      # 共享工具(Sa-Token、Redis、AOP)
├── car-wash-admin/       # 管理后台 API(Spring Boot)
├── car-wash-miniapp/     # 微信小程序 API(Spring Boot)
├── car-wash-mp/          # 微信公众号 API(Spring Boot)
├── admin-web/            # 运营管理后台前端(Vue 3 + Element Plus + Vite)
├── admin-h5/             # 运营商 H5(uni-app)
└── admin-web-new/        # 管理后台前端重构版(Vite + Vue 3)

技术栈

  • 后端: Java 21, Spring Boot 3.3.3, MyBatis-Plus 3.x, Sa-Token, Redis + Redisson, RabbitMQ, 微信支付 APIv3
  • 前端: Vue 3 + TypeScript + Vite + Element Plus + Pinia + uni-app
  • 构建: Maven 多模块

核心业务表

用途
t_user 微信小程序用户(station_id 标识归属站点)
t_wash_order 洗车订单(is_cross 标记是否跨店消费)
t_split_record 分账流水,按类型追踪站点间资金流向
t_settlement_record 月度结算单(幂等键 uk_station_period
t_station_account 站点账户余额(available_balance 可提现额)
t_wallet_detail 用户钱包流水(充值/消费/退款)
t_pay_log 微信支付日志(out_trade_no 商户订单号,transaction_id 微信交易号)
t_recharge_config 充值配置(归属 group_id 分组)
t_recharge_config_group 充值配置分组(is_default=1 为默认分组)

结算 V2 模型

月度结算由 SettlementServiceImpl.executeMonthlySettlement() 驱动,每月对上月数据进行结算。

SplitRecord 资金类型: | 类型 | 值 | 方向 | |---|---|---| | TYPE_RECHARGE | 1 | 同一站点收支,from=to | | TYPE_CROSS_EXPEND | 4 | 跨店:归属站 → 消费站 | | TYPE_CROSS_INCOME | 6 | 跨店:归属站 → 消费站(与 EXPEND 配对) | | TYPE_REFUND | 5 | 退款支出 |

月结公式:

feeBase = totalRecharge - totalRefund - totalCrossExpend + totalCrossIncome
platformFee = feeBase × 10%
available = openingBalance + feeBase - platformFee

available > 0 时正常结算,转入站点可提现余额,同时记录平台服务费。负数则结转下期。

关键业务链路

用户注册与站点归属

  • 扫码设备注册:直接通过 shortId 确定 stationIdUserServiceImpl.java:135-137
  • 自主注册:stationId = null,首次消费时在 WashOrderServiceImpl.createOrder() 中自动归属

充值 → 分账

  • 有归属站:WxPayServiceImpl.wxNotify() 中创建 SplitRecord(TYPE_RECHARGE, from=stationId, to=stationId)
  • 无归属站:不创建 SplitRecord,由 OrderSettlementServiceImpl.backfillUnattributedRecharges() 在首次消费结算时追溯补建

消费 → 结算

  • createOrder() → 扣预付款,设置 isCross 标记
  • settleOrder() → 扣款,回填无归属充值,本店跳过/跨店创建分账

注意事项

  • SaToken 注解 @SaIgnore 需要确保被 Spring 代理拦截才能生效
  • 分账记录 tradeNo 与微信支付 transactionId 对应,通过 t_pay_log 桥接 WalletDetail
  • 月结有幂等保护(uk_station_period),重复执行不会产生重复结算单