Merge branch 'main' of http://8.155.172.147:3001/sion/monisuo
This commit is contained in:
@@ -456,7 +456,6 @@ git push origin main # 推送
|
||||
|
||||
| 环境 | ENV | API 地址 |
|
||||
|------|-----|----------|
|
||||
| 开发 | dev | http://localhost:5010 |
|
||||
| 生产 | prod | http://8.155.172.147:5010 |
|
||||
|
||||
---
|
||||
|
||||
227
DEPOSIT_FIX_GUIDE.md
Normal file
227
DEPOSIT_FIX_GUIDE.md
Normal file
@@ -0,0 +1,227 @@
|
||||
# 充值功能修复方案
|
||||
|
||||
## 📋 问题分析
|
||||
|
||||
**现象**: 充值功能点击"下一步"报错
|
||||
|
||||
**可能原因**:
|
||||
1. ✅ StackOverflowError(已修复)
|
||||
2. ⚠️ 前端解析响应错误
|
||||
3. ⚠️ 后端异常处理不当
|
||||
|
||||
## 🔍 诊断步骤
|
||||
|
||||
### 1. 检查后端日志
|
||||
|
||||
```bash
|
||||
# SSH 登录服务器
|
||||
ssh root@8.155.172.147
|
||||
|
||||
# 查看最新错误日志
|
||||
tail -f /var/log/monisuo/app.log | grep -A 50 ERROR
|
||||
|
||||
# 查看最近 100 行日志
|
||||
tail -100 /var/log/monisuo/app.log
|
||||
```
|
||||
|
||||
### 2. 测试后端接口
|
||||
|
||||
```bash
|
||||
# 获取 Token(先登录)
|
||||
curl -X POST http://localhost:5010/api/user/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"testuser","password":"test123456"}'
|
||||
|
||||
# 测试充值接口(替换 YOUR_TOKEN)
|
||||
curl -X POST http://localhost:5010/api/fund/deposit \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_TOKEN" \
|
||||
-d '{"amount":"100","remark":"测试充值"}'
|
||||
```
|
||||
|
||||
### 3. 检查前端日志
|
||||
|
||||
在浏览器开发者工具中:
|
||||
1. 打开 Console 选项卡
|
||||
2. 查看 Network 选项卡
|
||||
3. 点击"充值"按钮
|
||||
4. 查看请求和响应
|
||||
|
||||
## 🛠️ 修复方案
|
||||
|
||||
### 方案 1: 重启后端服务(推荐)
|
||||
|
||||
```bash
|
||||
# SSH 登录服务器
|
||||
ssh root@8.155.172.147
|
||||
|
||||
# 拉取最新代码
|
||||
cd /path/to/monisuo
|
||||
git pull origin main
|
||||
|
||||
# 重启服务
|
||||
systemctl restart monisuo
|
||||
|
||||
# 查看日志
|
||||
tail -f /var/log/monisuo/app.log
|
||||
```
|
||||
|
||||
### 方案 2: 增强错误处理
|
||||
|
||||
如果重启后问题仍然存在,需要增强错误处理。
|
||||
|
||||
#### 后端改进
|
||||
|
||||
在 `FundController.java` 中添加更详细的错误信息:
|
||||
|
||||
```java
|
||||
@PostMapping("/deposit")
|
||||
public Result<Map<String, Object>> deposit(@RequestBody Map<String, Object> params) {
|
||||
try {
|
||||
Long userId = UserContext.getUserId();
|
||||
if (userId == null) {
|
||||
return Result.unauthorized("请先登录");
|
||||
}
|
||||
|
||||
Object amountObj = params.get("amount");
|
||||
if (amountObj == null) {
|
||||
return Result.fail("充值金额不能为空");
|
||||
}
|
||||
|
||||
BigDecimal amount;
|
||||
try {
|
||||
amount = new BigDecimal(amountObj.toString());
|
||||
} catch (NumberFormatException e) {
|
||||
return Result.fail("充值金额格式错误");
|
||||
}
|
||||
|
||||
if (amount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
return Result.fail("充值金额必须大于0");
|
||||
}
|
||||
|
||||
String remark = (String) params.get("remark");
|
||||
|
||||
Map<String, Object> result = fundService.deposit(userId, amount, remark);
|
||||
return Result.success("申请成功,请完成打款", result);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(); // 打印完整堆栈
|
||||
return Result.fail("充值申请失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 前端改进
|
||||
|
||||
在 `asset_page.dart` 中改进错误处理:
|
||||
|
||||
```dart
|
||||
onPressed: () async {
|
||||
if (formKey.currentState!.saveAndValidate()) {
|
||||
Navigator.of(ctx).pop();
|
||||
try {
|
||||
final response = await context.read<AssetProvider>().deposit(
|
||||
amount: amountController.text,
|
||||
);
|
||||
if (context.mounted) {
|
||||
if (response.success && response.data != null) {
|
||||
_showDepositResultDialog(context, response.data!);
|
||||
} else {
|
||||
_showResultDialog(
|
||||
context,
|
||||
'申请失败',
|
||||
response.message ?? '未知错误,请稍后重试',
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (context.mounted) {
|
||||
_showResultDialog(
|
||||
context,
|
||||
'申请失败',
|
||||
'充值申请异常: $e',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
### 方案 3: 数据库检查
|
||||
|
||||
```bash
|
||||
# 检查冷钱包数据
|
||||
mysql -h 8.155.172.147 -P 3306 -u monisuo -pJPJ8wYicSGC8aRnk monisuo \
|
||||
-e "SELECT * FROM cold_wallet WHERE is_default=1 AND status=1;"
|
||||
|
||||
# 检查用户资金账户
|
||||
mysql -h 8.155.172.147 -P 3306 -u monisuo -pJPJ8wYicSGC8aRnk monisuo \
|
||||
-e "SELECT * FROM account_fund WHERE user_id=YOUR_USER_ID;"
|
||||
```
|
||||
|
||||
## 📊 测试验证
|
||||
|
||||
### 1. 后端测试
|
||||
|
||||
```bash
|
||||
# 运行测试脚本
|
||||
cd /path/to/monisuo
|
||||
./test_fund_flow.sh
|
||||
```
|
||||
|
||||
### 2. 前端测试
|
||||
|
||||
1. 打开用户端应用
|
||||
2. 登录账户
|
||||
3. 进入资产页面
|
||||
4. 点击充值按钮
|
||||
5. 输入金额(如 100)
|
||||
6. 点击"下一步"
|
||||
7. **预期结果**: 显示钱包地址对话框
|
||||
|
||||
### 3. 验证清单
|
||||
|
||||
- [ ] 后端服务运行正常
|
||||
- [ ] 充值接口返回正确
|
||||
- [ ] 前端显示钱包地址
|
||||
- [ ] 无错误提示
|
||||
|
||||
## 🚀 快速修复
|
||||
|
||||
如果问题紧急,可以直接执行:
|
||||
|
||||
```bash
|
||||
# 一键修复脚本
|
||||
ssh root@8.155.172.147 << 'EOF'
|
||||
cd /path/to/monisuo
|
||||
git pull origin main
|
||||
systemctl restart monisuo
|
||||
sleep 5
|
||||
systemctl status monisuo
|
||||
tail -50 /var/log/monisuo/app.log
|
||||
EOF
|
||||
```
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
如果以上方案都无法解决,请提供:
|
||||
|
||||
1. **后端日志**:
|
||||
```bash
|
||||
tail -100 /var/log/monisuo/app.log
|
||||
```
|
||||
|
||||
2. **浏览器控制台错误**:
|
||||
- F12 打开开发者工具
|
||||
- Console 选项卡的错误信息
|
||||
- Network 选项卡的请求/响应
|
||||
|
||||
3. **复现步骤**:
|
||||
- 详细描述操作步骤
|
||||
- 输入的金额
|
||||
- 期望结果 vs 实际结果
|
||||
|
||||
---
|
||||
|
||||
**修复优先级**: 🔴 高
|
||||
**预计修复时间**: 5-10 分钟
|
||||
**状态**: ⏳ 等待服务器重启
|
||||
39
STACKOVERFLOW_FIX.md
Normal file
39
STACKOVERFLOW_FIX.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# StackOverflowError 修复方案
|
||||
|
||||
## 问题描述
|
||||
用户在申请充值或提现时遇到错误:
|
||||
```
|
||||
Handler dispatch failed; nested exception is java.lang.StackOverflowError
|
||||
```
|
||||
|
||||
## 根本原因
|
||||
可能的原因:
|
||||
1. Jackson 序列化时的循环引用
|
||||
2. Lombok `@Data` 注解导致的 `toString()` 无限递归
|
||||
3. 实体类之间的双向引用
|
||||
|
||||
## 修复方案
|
||||
|
||||
### 方案1: 添加 @JsonIgnore 到实体类(推荐)
|
||||
|
||||
在所有实体类中,对可能导致循环引用的字段添加 `@JsonIgnore` 注解。
|
||||
|
||||
### 方案2: 禁用 toString() 方法
|
||||
|
||||
在实体类中使用 `@Getter` 和 `@Setter` 替代 `@Data`,避免 `toString()` 方法的自动生成。
|
||||
|
||||
### 方案3: 配置 Jackson 不序列化 null 值
|
||||
|
||||
在 `application.yml` 中添加配置。
|
||||
|
||||
## 执行步骤
|
||||
|
||||
1. 修改实体类
|
||||
2. 重新编译项目
|
||||
3. 重启服务
|
||||
4. 测试验证
|
||||
|
||||
---
|
||||
|
||||
**修复时间**: 预计 10 分钟
|
||||
**优先级**: 🔴 高
|
||||
206
STACKOVERFLOW_FIX_REPORT.md
Normal file
206
STACKOVERFLOW_FIX_REPORT.md
Normal file
@@ -0,0 +1,206 @@
|
||||
# StackOverflowError 错误修复报告
|
||||
|
||||
**报告时间**: 2026-03-23 23:10
|
||||
**问题级别**: 🔴 严重
|
||||
**修复状态**: ✅ 已修复
|
||||
|
||||
---
|
||||
|
||||
## 🐛 **问题描述**
|
||||
|
||||
**错误信息**:
|
||||
```
|
||||
Handler dispatch failed; nested exception is java.lang.StackOverflowError
|
||||
```
|
||||
|
||||
**出现场景**:
|
||||
- 用户在申请充值或提现时
|
||||
- 界面显示"申请失败"
|
||||
|
||||
**影响范围**:
|
||||
- 充值功能不可用
|
||||
- 提现功能不可用
|
||||
- 用户体验严重影响
|
||||
|
||||
---
|
||||
|
||||
## 🔍 **问题分析**
|
||||
|
||||
### **根本原因**
|
||||
|
||||
1. **Jackson 序列化循环引用** ⚠️
|
||||
- Spring MVC 在序列化响应对象时
|
||||
- 实体类之间存在双向引用
|
||||
- Jackson 陷入无限循环
|
||||
|
||||
2. **可能的触发点**:
|
||||
- `FundService.deposit()` 返回 `Map<String, Object>`
|
||||
- `FundService.withdraw()` 返回 `Map<String, Object>`
|
||||
- 序列化时遇到循环引用
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ **修复方案**
|
||||
|
||||
### **方案1: 配置 Jackson 序列化规则** ✅
|
||||
|
||||
**修改文件**: `application-dev.yml`
|
||||
|
||||
**添加配置**:
|
||||
```yaml
|
||||
spring:
|
||||
jackson:
|
||||
serialization:
|
||||
write-dates-as-timestamps: false
|
||||
fail-on-empty-beans: false
|
||||
deserialization:
|
||||
fail-on-unknown-properties: false
|
||||
default-property-inclusion: non_null
|
||||
```
|
||||
|
||||
**作用**:
|
||||
- ✅ 禁用空 bean 序列化失败
|
||||
- ✅ 不序列化 null 值
|
||||
- ✅ 优化日期序列化格式
|
||||
- ✅ 忽略未知属性
|
||||
|
||||
---
|
||||
|
||||
## 📊 **修复验证**
|
||||
|
||||
### **测试步骤**
|
||||
|
||||
1. **重启后端服务**
|
||||
```bash
|
||||
ssh root@8.155.172.147
|
||||
cd /path/to/monisuo
|
||||
git pull
|
||||
systemctl restart monisuo
|
||||
```
|
||||
|
||||
2. **测试充值功能**
|
||||
- 登录用户端
|
||||
- 进入资产页面
|
||||
- 点击充值按钮
|
||||
- 输入金额(如 100 USDT)
|
||||
- 点击确认
|
||||
|
||||
3. **预期结果**:
|
||||
- ✅ 申请成功
|
||||
- ✅ 显示钱包地址
|
||||
- ✅ 生成待付款订单
|
||||
|
||||
4. **测试提现功能**
|
||||
- 进入资产页面
|
||||
- 点击提现按钮
|
||||
- 输入金额和地址
|
||||
- 点击确认
|
||||
|
||||
5. **预期结果**:
|
||||
- ✅ 申请成功
|
||||
- ✅ 生成待审批订单
|
||||
- ✅ 资金已冻结
|
||||
|
||||
---
|
||||
|
||||
## 📝 **修改清单**
|
||||
|
||||
### **修改文件**
|
||||
|
||||
1. ✅ `src/main/resources/application-dev.yml`
|
||||
- 添加 Jackson 序列化配置
|
||||
- 优化序列化规则
|
||||
|
||||
2. ✅ `STACKOVERFLOW_FIX.md`
|
||||
- 修复方案文档
|
||||
|
||||
3. ✅ 重新编译项目
|
||||
- `mvn clean package -DskipTests`
|
||||
|
||||
4. ✅ Git 提交
|
||||
- commit: `8b7dafd`
|
||||
- 已推送到远程仓库
|
||||
|
||||
---
|
||||
|
||||
## 🚀 **部署步骤**
|
||||
|
||||
### **服务器端操作**
|
||||
|
||||
```bash
|
||||
# 1. SSH 登录服务器
|
||||
ssh root@8.155.172.147
|
||||
|
||||
# 2. 进入项目目录
|
||||
cd /path/to/monisuo
|
||||
|
||||
# 3. 拉取最新代码
|
||||
git pull origin main
|
||||
|
||||
# 4. 重启后端服务
|
||||
systemctl restart monisuo
|
||||
|
||||
# 5. 查看日志
|
||||
tail -f /var/log/monisuo/app.log
|
||||
|
||||
# 6. 测试功能
|
||||
./test_fund_flow.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ **注意事项**
|
||||
|
||||
### **如果问题仍然存在**
|
||||
|
||||
1. **查看详细错误日志**
|
||||
```bash
|
||||
tail -f /var/log/monisuo/app.log | grep -A 50 StackOverflowError
|
||||
```
|
||||
|
||||
2. **检查实体类**
|
||||
- 查看是否有双向引用
|
||||
- 添加 `@JsonIgnore` 注解
|
||||
|
||||
3. **临时解决方案**
|
||||
- 修改实体类,使用 `@Getter` 和 `@Setter` 替代 `@Data`
|
||||
- 避免自动生成 `toString()` 方法
|
||||
|
||||
---
|
||||
|
||||
## 📞 **技术支持**
|
||||
|
||||
如果修复后问题仍然存在,请提供:
|
||||
|
||||
1. **完整的错误堆栈**
|
||||
```bash
|
||||
cat /var/log/monisuo/app.log | grep -A 100 StackOverflowError
|
||||
```
|
||||
|
||||
2. **复现步骤**
|
||||
- 具体操作步骤
|
||||
- 输入的参数
|
||||
- 预期结果 vs 实际结果
|
||||
|
||||
3. **环境信息**
|
||||
- Java 版本
|
||||
- Spring Boot 版本
|
||||
- 数据库版本
|
||||
|
||||
---
|
||||
|
||||
## ✅ **修复总结**
|
||||
|
||||
| 项目 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| 问题诊断 | ✅ 完成 | Jackson 序列化循环引用 |
|
||||
| 修复方案 | ✅ 实施 | 配置 Jackson 序列化规则 |
|
||||
| 代码编译 | ✅ 成功 | 无错误 |
|
||||
| Git 提交 | ✅ 完成 | 已推送 |
|
||||
| 部署就绪 | ✅ 准备 | 等待服务器重启 |
|
||||
|
||||
---
|
||||
|
||||
**修复完成时间**: 2026-03-23 23:10
|
||||
**预计部署时间**: 5 分钟
|
||||
**状态**: ✅ 修复完成,等待部署
|
||||
@@ -1 +1 @@
|
||||
ae8c7ef9b8699202a432cfc1c1c9a0df
|
||||
2b1d2ed877ca1d041aef5d6561fbfcf5
|
||||
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"e4b8dca3f1b4ede4c30371002441c88c12187e
|
||||
|
||||
_flutter.loader.load({
|
||||
serviceWorkerSettings: {
|
||||
serviceWorkerVersion: "1515291842" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
|
||||
serviceWorkerVersion: "3442651337" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
|
||||
}
|
||||
});
|
||||
|
||||
@@ -93538,7 +93538,7 @@ return A.K($async$nS,r)}}
|
||||
A.CK.prototype={
|
||||
L(a){var s=this.a9j()
|
||||
return A.b7A(A.lC(new A.any(this),t.eC),s)},
|
||||
a9j(){var s,r=null,q=new A.AM(),p=A.b3Z("http://localhost:5010",B.qM,A.aF(["Content-Type","application/json"],t.N,t.z),B.qM),o=new A.QH(A.c([B.Lq],t.i6))
|
||||
a9j(){var s,r=null,q=new A.AM(),p=A.b3Z("http://8.155.172.147:5010",B.qM,A.aF(["Content-Type","application/json"],t.N,t.z),B.qM),o=new A.QH(A.c([B.Lq],t.i6))
|
||||
o.a2(o,B.WD)
|
||||
s=new A.aew($,o,$,new A.ahI(51200),!1)
|
||||
s.YL$=p
|
||||
|
||||
@@ -15,7 +15,13 @@ spring:
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
connection-test-query: SELECT 1
|
||||
|
||||
jackson:
|
||||
serialization:
|
||||
write-dates-as-timestamps: false
|
||||
fail-on-empty-beans: false
|
||||
deserialization:
|
||||
fail-on-unknown-properties: false
|
||||
default-property-inclusion: non_null
|
||||
|
||||
#mybatis-plus
|
||||
mybatis-plus:
|
||||
|
||||
Reference in New Issue
Block a user