|
|
@@ -0,0 +1,77 @@
|
|
|
+# 洗车系统 (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` 确定 `stationId`(`UserServiceImpl.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`),重复执行不会产生重复结算单
|