Files
monisuo/COMPLETE_DIAGNOSIS_GUIDE.md
sion 62d8c81857 docs: 添加充值审批完整诊断指南
新增:
- COMPLETE_DIAGNOSIS_GUIDE.md - 充值审批余额更新的完整诊断和修复方案
- test_approve.sh - 自动化审批测试脚本

包含:
- 详细测试步骤
- 日志查看方法
- 数据库验证SQL
- 常见问题诊断
- 根本原因分析
- 快速验证方法
2026-03-24 13:33:23 +08:00

351 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 充值审批余额未更新 - 完整诊断和修复方案
**问题**: 充值订单审批通过后,订单状态已更新为"已完成"(status=3),但用户资金账户余额没有增加
**服务状态**: ✅ 已启动 (端口 5010)
**时间**: 2026-03-24 13:31
---
## 🔧 立即测试步骤
### 步骤 1: 准备测试数据
```bash
# 方式A: 使用前端操作
1. 登录用户端
2. 进入"充提"页面
3. 点击"充值"
4. 输入金额例如100 USDT
5. 点击"提交"
6. 点击"确认打款"
# 方式B: 使用API如果有已存在的订单
# 查看待审批订单
curl -X POST http://localhost:5010/admin/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}' | jq -r '.data.token'
# 使用返回的token查询
curl http://localhost:5010/admin/order/pending?type=1&status=2 \
-H "Authorization: Bearer <token>"
```
### 步骤 2: 执行审批并查看日志
**终端1 - 监控日志**:
```bash
cd ~/Desktop/projects/monisuo
tail -f logs/app.log | grep --line-buffered -A30 "FundService.approve"
```
**终端2 - 执行审批**:
```bash
cd ~/Desktop/projects/monisuo
./test_approve.sh
```
### 步骤 3: 查看关键日志输出
**成功的日志应该包含**:
```
[FundService.approve] 步骤1: 查询订单...
- 订单ID: 123
- 订单类型: 充值
- 当前状态: 2
[FundService.approve] 步骤2: 查询资金账户...
- 账户ID: 456
- 用户ID: 789
- 余额: 0.00 <-- 审批前余额
- 冻结: 0.00
[FundService.approve] 步骤3: 确定最终状态: 3 (审批通过)
[FundService.approve] 步骤4: 处理充值通过...
- 审批前余额: 0.00
- 审批前累计充值: 0.00
- 准备更新账户余额: 100.00 <-- 新余额
- 准备更新累计充值: 100.00
- 执行 SQL UPDATE (使用 LambdaUpdateWrapper)...
- 账户更新结果: 1 (1=成功, 0=失败) <-- 必须是1
- 验证更新后余额: 100.00 <-- 验证成功!
- 验证更新后累计充值: 100.00
[FundService.approve] 创建资金流水记录...
- 流水记录创建成功
[充值审批成功] 订单号: F20260324001, 用户ID: 789, 充值金额: 100 USDT
[FundService.approve] 步骤5: 更新订单状态...
- 当前状态: 2
- 目标状态: 3
- 执行 SQL UPDATE (使用 LambdaUpdateWrapper)...
- 订单更新结果: 1 (1=成功, 0=失败)
[FundService.approve] 步骤6: 验证更新结果...
- 验证查询结果: ID=123, 订单号=F20260324001, 状态=3
- 状态验证通过 ✓
[审批完成] 订单号: F20260324001, 订单类型: 充值, 审批结果: 通过, 最终状态: 3
```
---
## ❌ 如果日志显示失败
### 情况1: 账户更新结果: 0
**原因**: UPDATE语句执行失败
**诊断**:
```bash
# 查看完整SQL日志
grep "UPDATE account_fund" logs/app.log | tail -5
```
**修复**: 检查账户是否存在
```sql
SELECT * FROM account_fund WHERE user_id = [ID];
```
### 情况2: 验证更新后余额仍然是旧值
**原因**: 事务回滚或缓存问题
**诊断**:
```bash
# 查看事务日志
grep -i "transaction\|rollback\|commit" logs/app.log | tail -10
```
**修复**: 检查事务配置
### 情况3: 没有任何日志输出
**原因**: 服务未重启或代码未更新
**修复**:
```bash
# 1. 重新编译
cd ~/Desktop/projects/monisuo
mvn clean package -DskipTests
# 2. 重启服务
pkill -f monisuo-1.0.jar
export JAVA_HOME=/opt/homebrew/Cellar/openjdk@17/17.0.18/libexec/openjdk.jdk/Contents/Home
export PATH=$JAVA_HOME/bin:$PATH
nohup java -jar target/monisuo-1.0.jar --server.port=5010 > logs/app.log 2>&1 &
```
---
## ✅ 数据库验证
### 查询订单状态
```sql
SELECT
order_no,
user_id,
amount,
status,
approve_admin_id,
approve_time
FROM order_fund
WHERE order_no = '[订单号]';
```
**期望结果**: status = 3, approve_time 有值
### 查询账户余额(关键!)
```sql
SELECT
user_id,
balance,
total_deposit,
frozen,
update_time
FROM account_fund
WHERE user_id = [ID];
```
**期望结果**:
- balance = 原余额 + 充值金额
- total_deposit = 原累计充值 + 充值金额
- update_time = 审批时间
### 查询资金流水
```sql
SELECT
flow_no,
flow_type,
amount,
balance_before,
balance_after,
related_order_no,
create_time
FROM account_flow
WHERE related_order_no = '[订单号]'
ORDER BY create_time DESC;
```
**期望结果**:
- flow_type = 1 (充值)
- amount = 充值金额
- balance_before = 审批前余额
- balance_after = 审批后余额
---
## 🔍 问题根本原因分析
### 可能的原因
1. **服务未重启** ⭐⭐⭐⭐⭐
- 症状: 代码已修改但日志没有新格式的输出
- 原因: Java应用需要重启才能加载新代码
- 解决: 重启服务
2. **事务回滚**
- 症状: 日志显示更新成功,但数据库未变化
- 原因: 方法后续步骤抛出异常
- 解决: 检查完整日志,修复异常
3. **查询错误账户**
- 症状: 更新了账户,但查询的是另一个账户
- 原因: user_id不匹配
- 解决: 验证订单的user_id和账户的user_id
4. **MyBatis缓存**
- 症状: 数据库已更新,但查询返回旧数据
- 原因: MyBatis一级缓存或二级缓存
- 解决: 清除缓存或禁用缓存
---
## 🛠️ 如果问题依然存在
### 收集以下信息
1. **完整审批日志**
```bash
grep -A100 "审批订单开始" logs/app.log | tail -120 > approval_debug.log
```
2. **SQL执行日志**
```bash
grep "UPDATE\|INSERT" logs/app.log | tail -20 > sql_debug.log
```
3. **事务日志**
```bash
grep -i "transaction\|rollback\|commit" logs/app.log | tail -20 > transaction_debug.log
```
4. **数据库查询结果**
```sql
-- 订单信息
SELECT * FROM order_fund WHERE order_no = '[订单号]';
-- 账户信息
SELECT * FROM account_fund WHERE user_id = [ID];
-- 流水记录
SELECT * FROM account_flow WHERE related_order_no = '[订单号]';
-- 检查是否有多个账户
SELECT * FROM account_fund WHERE user_id = [ID] ORDER BY update_time DESC;
```
---
## 📊 快速验证脚本
使用我创建的测试脚本:
```bash
cd ~/Desktop/projects/monisuo
./test_approve.sh
```
---
## 🎯 预期结果
### 成功的标志
- ✅ 日志显示"账户更新结果: 1"
- ✅ 日志显示"验证更新后余额: [新余额]"
- ✅ 日志显示"充值审批成功"
- ✅ 日志显示"状态验证通过 ✓"
- ✅ 数据库账户余额已增加
- ✅ 流水记录已创建
- ✅ 订单状态为3
### 失败的标志
- ❌ 日志显示"账户更新结果: 0"
- ❌ 日志显示"余额更新失败"
- ❌ 日志显示"Transaction rolled back"
- ❌ 数据库账户余额未变化
- ❌ 没有流水记录
---
## 📝 关键代码位置
**充值审批核心逻辑**: `FundService.java` (行 330-380)
```java
// 充值审批通过时的账户更新逻辑
if (order.getType() == 1 && status == 2) {
// 1. 计算新余额
BigDecimal newBalance = fund.getBalance().add(order.getAmount());
BigDecimal newTotalDeposit = fund.getTotalDeposit().add(order.getAmount());
// 2. 使用 LambdaUpdateWrapper 显式更新
LambdaUpdateWrapper<AccountFund> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(AccountFund::getId, fund.getId())
.set(AccountFund::getBalance, newBalance) // ⭐ 更新余额
.set(AccountFund::getTotalDeposit, newTotalDeposit) // ⭐ 更新累计充值
.set(AccountFund::getUpdateTime, LocalDateTime.now());
// 3. 执行更新
int updateResult = accountFundMapper.update(null, wrapper);
// 4. 验证更新
AccountFund verifyFund = accountFundMapper.selectById(fund.getId());
if (!verifyFund.getBalance().equals(newBalance)) {
throw new RuntimeException("余额更新失败");
}
// 5. 记录流水
assetService.createFlow(...);
}
```
---
**最后更新**: 2026-03-24 13:31
**服务状态**: ✅ 运行中
**测试就绪**: ✅ 是
**下一步**: 执行充值审批测试并查看日志
---
## 🚀 立即开始测试
```bash
# 终端1 - 监控日志
cd ~/Desktop/projects/monisuo
tail -f logs/app.log | grep --line-buffered -A30 "FundService.approve"
# 终端2 - 执行测试
cd ~/Desktop/projects/monisuo
./test_approve.sh
```
或者使用前端操作:
1. 登录管理后台
2. 进入"订单管理" -> "待审批订单"
3. 选择一个充值订单
4. 点击"审批通过"
5. 查看终端1的日志输出