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

179 lines
4.6 KiB
Markdown
Raw Permalink 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.

# 收益数据不一致根本原因分析 - 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*