peixue-dev/Archive/[一次性]收益数据不一致根本原因-2026-01-31.md

179 lines
4.6 KiB
Markdown
Raw Permalink Normal View History

2026-02-28 17:26:03 +08:00
# 收益数据不一致根本原因分析 - 2026-01-31
## 问题现象
收益查看页面显示:
- **顶部"总收益"**¥222
- **下方"本月总收益"**¥1774
## 数据流追踪
### 1. 顶部"总收益"¥222
**前端调用:**
```javascript
// earnings.vue - loadOverview()
GET /api/provider/earnings/stats?type=overview
使用字段res.data.totalEarnings
```
**后端处理:**
```java
// ProviderController.java - getEarningsStats()
if ("overview".equals(type)) {
overview.put("totalEarnings", stats.getTotalEarnings());
// stats 来自 providerService.getEarningsStats(providerId)
}
```
**数据来源:**
```java
// ProviderServiceImpl.java - getEarningsStats()
// 统计总收益(从已完成的订单中计算)
LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Order::getTeacherId, providerId)
.eq(Order::getStatus, 4); // 只统计状态=4的订单
List<Order> orders = orderMapper.selectList(wrapper);
BigDecimal totalEarnings = orders.stream()
.map(Order::getPayAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
```
**结论:顶部"总收益"只统计了 `status=4` 的订单**
---
### 2. 下方"本月总收益"¥1774
**前端调用:**
```javascript
// earnings.vue - loadStats()
GET /api/provider/earnings/stats?type=month
使用字段res.data.earnings
```
**后端处理:**
```java
// ProviderController.java - getEarningsStats()
if ("month".equals(type)) {
LocalDateTime start = now.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
LocalDateTime end = now.withHour(23).withMinute(59).withSecond(59);
LambdaQueryWrapper<Order> w = new LambdaQueryWrapper<>();
w.eq(Order::getTeacherId, providerId)
.between(Order::getCreateTime, start, end); // 没有状态限制!
List<Order> periodOrders = orderMapper.selectList(w);
BigDecimal earnings = periodOrders.stream()
.map(Order::getPayAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
```
**结论:下方"本月总收益"统计了本月所有状态的订单**
---
## 根本原因
**两个接口的统计逻辑不一致:**
1. **`type=overview`(总收益)**
- 只统计 `status=4`(已完成)的订单
- 不限制时间范围
- 结果¥222
2. **`type=month`(本月收益)**
- 统计本月所有状态的订单(包括待支付、进行中、已完成等)
- 限制时间范围为本月
- 结果¥1774
## 问题分析
### 为什么本月收益比总收益还大?
**可能的情况:**
1. **订单状态分布**
```
本月订单:
- status=1待支付¥500
- status=2已支付¥400
- status=3进行中¥652
- status=4已完成¥222
总计¥1774
```
2. **历史订单少**
- 服务商可能是新注册的
- 历史上只有¥222的已完成订单
- 本月有很多新订单但还未完成
## 修复方案
### 方案1统一统计逻辑推荐
**让两个接口使用相同的统计规则:**
```java
// 修改 getEarningsStats() 方法
// 总收益应该统计所有已完成的订单,不限时间
wrapper.eq(Order::getTeacherId, providerId)
.eq(Order::getStatus, 4); // 已完成
// 本月收益也应该只统计已完成的订单
w.eq(Order::getTeacherId, providerId)
.eq(Order::getStatus, 4) // 添加状态限制
.between(Order::getCreateTime, start, end);
```
### 方案2修改前端显示
**明确标注统计范围:**
- 顶部:累计已完成收益
- 下方:本月全部订单金额
### 方案3分别显示
**提供更详细的统计:**
```
总收益¥222已完成
本月订单¥1774
- 已完成¥222
- 进行中¥652
- 待支付¥900
```
## 建议修复步骤
1. **确认业务需求**
- "总收益"应该统计什么?(已完成?全部?)
- "本月收益"应该统计什么?(已完成?全部?)
2. **统一后端逻辑**
- 修改 `ProviderServiceImpl.getEarningsStats()`
- 修改 `ProviderController.getEarningsStats()` 中的 `type=month` 分支
3. **添加状态过滤**
```java
// 建议:只统计已完成的订单
.eq(Order::getStatus, 4)
```
4. **测试验证**
- 验证总收益 = 所有已完成订单金额
- 验证本月收益 = 本月已完成订单金额
## 相关文件
- 前端:`peidu/uniapp/src/provider-package/pages/provider/earnings.vue`
- 后端Controller`peidu/backend/src/main/java/com/peidu/controller/ProviderController.java`
- 后端Service`peidu/backend/src/main/java/com/peidu/service/impl/ProviderServiceImpl.java`
- VO定义`peidu/backend/src/main/java/com/peidu/vo/EarningsStatsVO.java`
---
*分析时间2026-01-31*