# 收益明细功能实现 - 2026-01-31 ## 问题描述 收益查看页面显示有收益(222元),但"收益明细"列表显示"暂无收益记录"。 ## 问题原因 后端接口 `/api/provider/earnings/detail` 只是返回空列表,没有实现真正的查询逻辑。 ```java // 原代码 Map response = new HashMap<>(); response.put("records", new ArrayList<>()); // 直接返回空列表 response.put("total", 0); return Result.success(response); ``` ## 修复方案 实现收益明细查询功能,从订单表中查询已完成的订单作为收益记录。 ### 实现逻辑 1. **时间范围筛选** - 本月:当前月份第1天到当前时间 - 本季度:当前季度第一个月的第1天到当前时间 - 本年:当前年份1月1日到当前时间 2. **订单筛选条件** - `teacher_id = providerId`(服务商ID) - `status = 4`(只查询已完成订单) - `create_time` 在时间范围内 3. **分页查询** - 支持分页参数:page(页码)、size(每页数量) - 按创建时间倒序排列 4. **数据转换** - 将订单数据转换为前端需要的格式 - 包含:课程名称、学生姓名、日期、金额、状态等 ### 修改后的代码 ```java @GetMapping("/earnings/detail") public Result getEarningsDetail( @RequestHeader("Authorization") String token, @RequestParam(required = false) String type, @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer size) { // 1. 获取服务商ID Long userId = jwtUtil.getUserIdFromToken(token.substring(7)); Long providerId = providerService.getProviderIdByUserId(userId); // 2. 确定时间范围 LocalDateTime now = LocalDateTime.now(); LocalDateTime start; if ("year".equals(type)) { start = now.withDayOfYear(1).withHour(0).withMinute(0).withSecond(0); } else if ("quarter".equals(type)) { int month = now.getMonthValue(); int quarterStartMonth = ((month - 1) / 3) * 3 + 1; start = now.withMonth(quarterStartMonth).withDayOfMonth(1) .withHour(0).withMinute(0).withSecond(0); } else { start = now.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0); } LocalDateTime end = now.withHour(23).withMinute(59).withSecond(59); // 3. 查询已完成订单 LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(Order::getTeacherId, providerId) .eq(Order::getStatus, 4) // 只查询已完成订单 .between(Order::getCreateTime, start, end) .orderByDesc(Order::getCreateTime); // 4. 分页查询 Page pageParam = new Page<>(page, size); Page orderPage = orderMapper.selectPage(pageParam, wrapper); // 5. 转换数据格式 List> records = orderPage.getRecords().stream() .map(order -> { Map record = new HashMap<>(); record.put("id", order.getId()); record.put("courseName", order.getServiceName() != null ? order.getServiceName() : "课程服务"); record.put("studentName", order.getStudentName() != null ? order.getStudentName() : "学生"); record.put("date", order.getCreateTime() != null ? order.getCreateTime().format( DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")) : ""); record.put("type", "income"); record.put("amount", order.getPayAmount() != null ? order.getPayAmount() : BigDecimal.ZERO); record.put("status", "completed"); record.put("statusText", "已结算"); return record; }) .collect(Collectors.toList()); // 6. 返回结果 Map response = new HashMap<>(); response.put("records", records); response.put("total", orderPage.getTotal()); response.put("pages", orderPage.getPages()); response.put("current", orderPage.getCurrent()); return Result.success(response); } ``` ## 返回数据格式 ```json { "code": 200, "message": "success", "data": { "records": [ { "id": 1, "courseName": "数学一对一", "studentName": "张小明", "date": "2026-01-20 14:30", "type": "income", "amount": 100, "status": "completed", "statusText": "已结算" }, { "id": 2, "courseName": "英语口语", "studentName": "李小红", "date": "2026-01-18 10:00", "type": "income", "amount": 122, "status": "completed", "statusText": "已结算" } ], "total": 2, "pages": 1, "current": 1 } } ``` ## 前端展示 收益明细列表会显示: - 课程名称 - 学生姓名 - 服务日期和时间 - 收益金额(绿色显示,带+号) - 状态标签(已结算) ## 验证方法 ### 1. 查看数据库 ```sql -- 查看服务商的已完成订单 SELECT id, service_name, student_name, pay_amount, create_time, status FROM `order` WHERE teacher_id = ? AND status = 4 ORDER BY create_time DESC; ``` ### 2. 测试接口 ```bash # 查询本月收益明细 GET /api/provider/earnings/detail?type=month&page=1&size=10 # 查询本季度收益明细 GET /api/provider/earnings/detail?type=quarter&page=1&size=10 # 查询本年收益明细 GET /api/provider/earnings/detail?type=year&page=1&size=10 ``` ### 3. 前端验证 1. 打开收益查看页面 2. 切换"本月"、"本季度"、"本年"标签 3. 查看"收益明细"列表是否显示订单记录 4. 验证金额、日期、学生信息是否正确 ## 注意事项 1. **只显示已完成订单** - status = 4 的订单才会显示在收益明细中 - 待服务、服务中的订单不会显示 2. **时间范围** - 根据选择的标签(本月/本季度/本年)显示对应时间范围的记录 - 使用订单的 create_time 字段判断 3. **分页支持** - 默认每页显示10条记录 - 支持翻页查看更多记录 4. **数据一致性** - 收益明细的总金额应该等于收益统计中显示的金额 - 如果不一致,需要检查订单状态和时间范围 ## 相关文件 - `peidu/backend/src/main/java/com/peidu/controller/ProviderController.java` - `peidu/uniapp/src/provider-package/pages/provider/earnings.vue` --- *实现时间:2026-01-31*