# 充值审批余额未更新 - 紧急诊断和修复方案

**问题**: 充值审批成功后，用户资金账户余额没有增加

**紧急程度**: 🔴 高危

**时间**: 2026-03-24 11:45

---

## 🚨 立即检查清单

### 1. 服务是否重启？（最可能的原因）

```bash
# 检查服务运行时间
ps -p $(pgrep -f monisuo-1.0.jar) -o lstart,etime

# 如果运行时间早于代码提交时间，说明没有重启
# 代码提交时间: 2026-03-24 11:36
# 如果服务运行时间早于这个时间，必须重启！
```

**重启服务**:
```bash
# 停止旧服务
pkill -f "monisuo-1.0.jar"

# 启动新服务
cd ~/Desktop/projects/monisuo
nohup java -jar target/monisuo-1.0.jar > logs/spring.log 2>&1 &

# 查看日志
tail -f logs/spring.log
```

---

### 2. 查看审批日志

```bash
# 查找最近的审批日志
grep -A30 "充值审批成功" logs/spring.log | tail -50

# 应该看到：
# ✅ [FundService.approve] 步骤4: 处理充值通过...
# ✅ 审批前余额: 0.00
# ✅ 准备更新账户余额: 100.00
# ✅ 执行 SQL UPDATE (使用 LambdaUpdateWrapper)...
# ✅ 账户更新结果: 1 (1=成功, 0=失败)
# ✅ 验证更新后余额: 100.00
# ✅ [充值审批成功] ...
```

---

### 3. 数据库验证

```sql
-- 1. 查询订单状态
SELECT order_no, user_id, amount, status, approve_time 
FROM order_fund 
WHERE order_no = '订单号';

-- 2. 查询账户余额（关键！）
SELECT user_id, balance, total_deposit, update_time 
FROM account_fund 
WHERE user_id = [用户ID];

-- 3. 查询流水记录
SELECT * FROM account_flow 
WHERE related_order_no = '订单号'
ORDER BY create_time DESC;

-- 4. 如果余额未更新，手动更新（临时方案）
UPDATE account_fund 
SET balance = balance + [充值金额],
    total_deposit = total_deposit + [充值金额],
    update_time = NOW()
WHERE user_id = [用户ID];
```

---

## 🔍 问题分析

### 当前代码逻辑（已修复版本）

```java
// FundService.approve() - 充值审批通过
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. 验证更新
    if (updateResult <= 0) {
        throw new RuntimeException("充值审批更新账户余额失败");
    }
    
    // 5. 再次查询验证
    AccountFund verifyFund = accountFundMapper.selectById(fund.getId());
    if (!verifyFund.getBalance().equals(newBalance)) {
        throw new RuntimeException("余额更新失败");
    }
    
    // 6. 记录流水
    assetService.createFlow(userId, 1, amount, balanceBefore, newBalance, "USDT", orderNo, "充值");
}
```

### 可能的问题点

#### 问题1: 服务未重启 ⭐⭐⭐⭐⭐
**症状**: 代码已修改，但服务还在运行旧版本
**原因**: Java 应用需要重启才能加载新代码
**解决**: 重启服务

#### 问题2: 事务回滚
**症状**: 日志显示更新成功，但数据库未变化
**原因**: 事务在后续步骤失败并回滚
**验证**: 查看日志是否有异常
**解决**: 修复后续步骤的错误

#### 问题3: 查询错误账户
**症状**: 更新了账户，但查询的是另一个账户
**原因**: user_id 不匹配
**验证**: 检查订单的 user_id 和账户的 user_id
**解决**: 确保查询条件正确

#### 问题4: MyBatis 缓存
**症状**: 数据库已更新，但查询返回旧数据
**原因**: MyBatis 一级缓存或二级缓存
**解决**: 清除缓存或禁用缓存

---

## 🔧 修复方案

### 方案 A: 立即重启服务（推荐）

```bash
cd ~/Desktop/projects/monisuo
pkill -f "monisuo-1.0.jar"
nohup java -jar target/monisuo-1.0.jar > logs/spring.log 2>&1 &
```

**验证**:
1. 执行一次充值审批
2. 查看日志是否有"账户更新结果: 1"
3. 查询数据库确认余额增加

---

### 方案 B: 添加强制清除缓存

修改 `FundService.approve()`:

```java
// 在方法开始添加
@Autowired
private SqlSession sqlSession;

@Transactional
public void approve(...) {
    // 强制清除 MyBatis 缓存
    sqlSession.clearCache();
    
    // ... 原有逻辑
}
```

---

### 方案 C: 添加最终验证和重试

在 `FundService.approve()` 方法最后添加:

```java
// 在方法最后添加最终验证
AccountFund finalFund = accountFundMapper.selectById(fund.getId());
System.out.println("[最终验证] 数据库实际余额: " + finalFund.getBalance());

if (!finalFund.getBalance().equals(newBalance)) {
    System.err.println("[严重错误] 余额更新失败!");
    System.err.println("  - 期望余额: " + newBalance);
    System.err.println("  - 实际余额: " + finalFund.getBalance());
    
    // 尝试再次更新
    int retryResult = accountFundMapper.update(null, wrapper);
    System.out.println("[重试更新] 结果: " + retryResult);
    
    if (retryResult <= 0) {
        throw new RuntimeException("余额更新失败，事务将回滚");
    }
}
```

---

### 方案 D: 检查事务配置

确认 `SpcCloudApplication.java` 是否有 `@EnableTransactionManagement`:

```java
@SpringBootApplication
@EnableTransactionManagement  // ⭐ 必须有这个
public class SpcCloudApplication {
    // ...
}
```

---

## 📊 验证脚本

使用我创建的验证脚本:

```bash
chmod +x ~/Desktop/projects/monisuo/verify_balance.sh
./verify_balance.sh
```

---

## 🎯 执行步骤

### 步骤1: 立即重启服务

```bash
cd ~/Desktop/projects/monisuo
pkill -f "monisuo-1.0.jar"
nohup java -jar target/monisuo-1.0.jar > logs/spring.log 2>&1 &
```

### 步骤2: 测试审批

1. 登录管理后台
2. 进入"订单管理" -> "待审批订单"
3. 选择一个充值订单
4. 点击"审批通过"
5. **不要关闭页面**

### 步骤3: 立即查看日志

```bash
tail -f logs/spring.log | grep -A20 "FundService.approve"
```

**应该看到**:
```
[FundService.approve] 步骤4: 处理充值通过...
  - 审批前余额: 0.00
  - 准备更新账户余额: 100.00
  - 执行 SQL UPDATE (使用 LambdaUpdateWrapper)...
  - 账户更新结果: 1 (1=成功, 0=失败)  <-- 必须是 1
  - 验证更新后余额: 100.00
[充值审批成功] 订单号: xxx, 充值金额: 100 USDT
```

### 步骤4: 数据库验证

```sql
-- 查询订单状态（应该是3）
SELECT order_no, status, approve_time FROM order_fund WHERE order_no = '订单号';

-- 查询账户余额（应该增加了）
SELECT user_id, balance, total_deposit FROM account_fund WHERE user_id = [用户ID];

-- 查询流水记录（应该有记录）
SELECT * FROM account_flow WHERE related_order_no = '订单号';
```

---

## ❌ 如果问题依然存在

提供以下信息:

1. **服务启动时间**
```bash
ps -p $(pgrep -f monisuo-1.0.jar) -o lstart
```

2. **完整审批日志**
```bash
grep -A50 "审批订单开始" logs/spring.log | tail -60
```

3. **数据库查询结果**
```sql
-- 订单信息
SELECT * FROM order_fund WHERE order_no = '订单号';

-- 账户信息
SELECT * FROM account_fund WHERE user_id = [用户ID];

-- 流水记录
SELECT * FROM account_flow WHERE related_order_no = '订单号';
```

4. **事务日志**
```bash
grep -i "transaction\|rollback\|commit" logs/spring.log | tail -20
```

---

**最后更新**: 2026-03-24 11:45
**状态**: 等待重启服务并测试
**预期修复时间**: 5分钟
