peixue-dev/Archive/[一次性]收益明细功能实现-2026-01-31.md

220 lines
6.5 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元但"收益明细"列表显示"暂无收益记录"。
## 问题原因
后端接口 `/api/provider/earnings/detail` 只是返回空列表,没有实现真正的查询逻辑。
```java
// 原代码
Map<String, Object> 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<Object> 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<Order> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Order::getTeacherId, providerId)
.eq(Order::getStatus, 4) // 只查询已完成订单
.between(Order::getCreateTime, start, end)
.orderByDesc(Order::getCreateTime);
// 4. 分页查询
Page<Order> pageParam = new Page<>(page, size);
Page<Order> orderPage = orderMapper.selectPage(pageParam, wrapper);
// 5. 转换数据格式
List<Map<String, Object>> records = orderPage.getRecords().stream()
.map(order -> {
Map<String, Object> 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<String, Object> 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*