# 收益数据不一致根本原因分析 - 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 wrapper = new LambdaQueryWrapper<>(); wrapper.eq(Order::getTeacherId, providerId) .eq(Order::getStatus, 4); // 只统计状态=4的订单 List 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 w = new LambdaQueryWrapper<>(); w.eq(Order::getTeacherId, providerId) .between(Order::getCreateTime, start, end); // 没有状态限制! List 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*