292 lines
8.6 KiB
Markdown
292 lines
8.6 KiB
Markdown
|
|
# 🔍 家长端日历功能问题诊断
|
|||
|
|
|
|||
|
|
**诊断时间**: 2026-01-24
|
|||
|
|
**问题描述**: 家长端日历功能无法显示数据,之前可以看到日历上显示待上课的数量、已完成服务的数量,下方会显示订单,点击订单显示订单详情
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔍 问题分析
|
|||
|
|
|
|||
|
|
### 1. 后端API问题
|
|||
|
|
|
|||
|
|
**文件**: `peidu/backend/src/main/java/com/peidu/service/impl/CalendarServiceImpl.java`
|
|||
|
|
|
|||
|
|
**问题1:订单状态筛选错误**
|
|||
|
|
```java
|
|||
|
|
// ❌ 当前代码:只查询状态为 2, 3, 4 的订单
|
|||
|
|
queryWrapper.in("status", Arrays.asList(2, 3, 4)) // 待服务、服务中、已完成
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**实际订单状态定义**:
|
|||
|
|
- 0: 待支付
|
|||
|
|
- 1: 待接单(已支付)
|
|||
|
|
- 2: 待服务(已接单)
|
|||
|
|
- 3: 服务中
|
|||
|
|
- 4: 已完成
|
|||
|
|
|
|||
|
|
**问题**:
|
|||
|
|
- 缺少状态 1(待接单/已支付)的订单
|
|||
|
|
- 家长支付后的订单状态是 1,但日历不显示
|
|||
|
|
|
|||
|
|
**问题2:统计数据状态映射错误**
|
|||
|
|
```java
|
|||
|
|
// ❌ 当前代码
|
|||
|
|
stats.put("pendingCount", orders.stream().filter(o -> o.getStatus() == 2).count());
|
|||
|
|
stats.put("ongoingCount", orders.stream().filter(o -> o.getStatus() == 3).count());
|
|||
|
|
stats.put("completedCount", orders.stream().filter(o -> o.getStatus() == 4).count());
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**问题**:
|
|||
|
|
- `pendingCount` 应该包含状态 1 和 2(待接单 + 待服务)
|
|||
|
|
- 统计数据不准确
|
|||
|
|
|
|||
|
|
**问题3:用户ID硬编码**
|
|||
|
|
```java
|
|||
|
|
// ❌ Controller中硬编码
|
|||
|
|
private Long getCurrentUserId() {
|
|||
|
|
return 1L; // 固定返回用户ID 1
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**问题**:
|
|||
|
|
- 所有用户看到的都是用户ID=1的数据
|
|||
|
|
- 无法显示当前登录用户的订单
|
|||
|
|
|
|||
|
|
### 2. 前端问题
|
|||
|
|
|
|||
|
|
**文件**: `peidu/uniapp/src/user-package/pages/calendar/index.vue`
|
|||
|
|
|
|||
|
|
**问题1:日历组件缺失**
|
|||
|
|
```vue
|
|||
|
|
<calendar
|
|||
|
|
:scheduleData="scheduleData"
|
|||
|
|
role="parent"
|
|||
|
|
@date-select="handleDateSelect"
|
|||
|
|
@month-change="handleMonthChange"
|
|||
|
|
@schedule-click="handleScheduleClick"
|
|||
|
|
/>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**问题**:
|
|||
|
|
- 引用了 `@/components/calendar/calendar.vue` 组件
|
|||
|
|
- 但这个组件可能不存在或有问题
|
|||
|
|
|
|||
|
|
**问题2:API调用路径**
|
|||
|
|
```javascript
|
|||
|
|
const res = await calendarApi.getAppointments(startDate, endDate)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**需要检查**:
|
|||
|
|
- `calendarApi` 是否正确定义
|
|||
|
|
- API路径是否正确
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ✅ 修复方案
|
|||
|
|
|
|||
|
|
### 1. 修复后端订单状态筛选
|
|||
|
|
|
|||
|
|
**修改文件**: `peidu/backend/src/main/java/com/peidu/service/impl/CalendarServiceImpl.java`
|
|||
|
|
|
|||
|
|
#### 修复 getAppointments 方法
|
|||
|
|
```java
|
|||
|
|
@Override
|
|||
|
|
public List<AppointmentVO> getAppointments(Long userId, LocalDate startDate, LocalDate endDate) {
|
|||
|
|
log.info("查询用户预约记录, userId: {}, startDate: {}, endDate: {}", userId, startDate, endDate);
|
|||
|
|
|
|||
|
|
// ✅ 修复:包含所有有效状态的订单(1-待接单, 2-待服务, 3-服务中, 4-已完成)
|
|||
|
|
QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
|
|||
|
|
queryWrapper.eq("user_id", userId)
|
|||
|
|
.ge("service_date", startDate)
|
|||
|
|
.le("service_date", endDate)
|
|||
|
|
.in("status", Arrays.asList(1, 2, 3, 4)) // ✅ 增加状态1
|
|||
|
|
.eq("deleted", 0)
|
|||
|
|
.orderByAsc("service_date", "time_slot");
|
|||
|
|
|
|||
|
|
List<Order> orders = orderMapper.selectList(queryWrapper);
|
|||
|
|
|
|||
|
|
log.info("查询到 {} 条订单记录", orders.size());
|
|||
|
|
|
|||
|
|
return orders.stream()
|
|||
|
|
.map(this::convertToAppointmentVO)
|
|||
|
|
.collect(Collectors.toList());
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 修复 getDailyServices 方法
|
|||
|
|
```java
|
|||
|
|
@Override
|
|||
|
|
public List<ServiceDetailVO> getDailyServices(Long userId, LocalDate date) {
|
|||
|
|
log.info("查询指定日期的服务详情, userId: {}, date: {}", userId, date);
|
|||
|
|
|
|||
|
|
// ✅ 修复:包含所有有效状态
|
|||
|
|
QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
|
|||
|
|
queryWrapper.eq("user_id", userId)
|
|||
|
|
.eq("service_date", date)
|
|||
|
|
.in("status", Arrays.asList(1, 2, 3, 4)) // ✅ 增加状态1
|
|||
|
|
.eq("deleted", 0)
|
|||
|
|
.orderByAsc("time_slot");
|
|||
|
|
|
|||
|
|
List<Order> orders = orderMapper.selectList(queryWrapper);
|
|||
|
|
|
|||
|
|
log.info("查询到 {} 条服务记录", orders.size());
|
|||
|
|
|
|||
|
|
return orders.stream()
|
|||
|
|
.map(this::convertToServiceDetailVO)
|
|||
|
|
.collect(Collectors.toList());
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 修复 getMonthlyStats 方法
|
|||
|
|
```java
|
|||
|
|
@Override
|
|||
|
|
public Map<String, Object> getMonthlyStats(Long userId, Integer year, Integer month) {
|
|||
|
|
log.info("查询当月预约统计, userId: {}, year: {}, month: {}", userId, year, month);
|
|||
|
|
|
|||
|
|
LocalDate startDate = LocalDate.of(year, month, 1);
|
|||
|
|
LocalDate endDate = startDate.plusMonths(1).minusDays(1);
|
|||
|
|
|
|||
|
|
QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
|
|||
|
|
queryWrapper.eq("user_id", userId)
|
|||
|
|
.ge("service_date", startDate)
|
|||
|
|
.le("service_date", endDate)
|
|||
|
|
.eq("deleted", 0);
|
|||
|
|
|
|||
|
|
List<Order> orders = orderMapper.selectList(queryWrapper);
|
|||
|
|
|
|||
|
|
// ✅ 修复:正确统计各状态数量
|
|||
|
|
Map<String, Object> stats = new HashMap<>();
|
|||
|
|
stats.put("totalCount", orders.size());
|
|||
|
|
// 待服务 = 待接单(1) + 待服务(2)
|
|||
|
|
stats.put("pendingCount", orders.stream()
|
|||
|
|
.filter(o -> o.getStatus() == 1 || o.getStatus() == 2)
|
|||
|
|
.count());
|
|||
|
|
// 服务中
|
|||
|
|
stats.put("ongoingCount", orders.stream()
|
|||
|
|
.filter(o -> o.getStatus() == 3)
|
|||
|
|
.count());
|
|||
|
|
// 已完成
|
|||
|
|
stats.put("completedCount", orders.stream()
|
|||
|
|
.filter(o -> o.getStatus() == 4)
|
|||
|
|
.count());
|
|||
|
|
|
|||
|
|
return stats;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 修复用户ID获取
|
|||
|
|
|
|||
|
|
**修改文件**: `peidu/backend/src/main/java/com/peidu/controller/CalendarController.java`
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
/**
|
|||
|
|
* 获取当前用户ID
|
|||
|
|
* ✅ 从请求头或token中获取
|
|||
|
|
*/
|
|||
|
|
private Long getCurrentUserId() {
|
|||
|
|
// 方案1:从请求头获取
|
|||
|
|
HttpServletRequest request =
|
|||
|
|
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
|
|||
|
|
.getRequest();
|
|||
|
|
String userIdStr = request.getHeader("userId");
|
|||
|
|
if (userIdStr != null) {
|
|||
|
|
return Long.parseLong(userIdStr);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 方案2:从session获取
|
|||
|
|
Object userInfo = request.getSession().getAttribute("userInfo");
|
|||
|
|
if (userInfo != null) {
|
|||
|
|
// 根据实际UserInfo类结构获取ID
|
|||
|
|
return ((UserInfo) userInfo).getId();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 默认返回1(仅用于测试)
|
|||
|
|
log.warn("无法获取当前用户ID,使用默认值1");
|
|||
|
|
return 1L;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 修复状态文本映射
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
/**
|
|||
|
|
* 获取状态文本
|
|||
|
|
* ✅ 修复状态映射
|
|||
|
|
*/
|
|||
|
|
private String getStatusText(Integer status) {
|
|||
|
|
switch (status) {
|
|||
|
|
case 0: return "待支付";
|
|||
|
|
case 1: return "待接单"; // ✅ 修复:已支付,等待陪伴员接单
|
|||
|
|
case 2: return "待服务"; // ✅ 修复:已接单,等待服务
|
|||
|
|
case 3: return "服务中";
|
|||
|
|
case 4: return "已完成";
|
|||
|
|
case -1: return "已取消";
|
|||
|
|
case -2: return "退款中";
|
|||
|
|
case -3: return "已退款";
|
|||
|
|
default: return "未知状态";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📋 需要修改的文件
|
|||
|
|
|
|||
|
|
1. **后端**
|
|||
|
|
- `peidu/backend/src/main/java/com/peidu/service/impl/CalendarServiceImpl.java`
|
|||
|
|
- 修复 `getAppointments` 方法的状态筛选
|
|||
|
|
- 修复 `getDailyServices` 方法的状态筛选
|
|||
|
|
- 修复 `getMonthlyStats` 方法的统计逻辑
|
|||
|
|
- 修复 `getStatusText` 方法的状态映射
|
|||
|
|
|
|||
|
|
- `peidu/backend/src/main/java/com/peidu/controller/CalendarController.java`
|
|||
|
|
- 修复 `getCurrentUserId` 方法,从请求中获取真实用户ID
|
|||
|
|
|
|||
|
|
2. **前端**(需要进一步检查)
|
|||
|
|
- 检查 `@/components/calendar/calendar.vue` 组件是否存在
|
|||
|
|
- 检查 `@/api/index.js` 中的 `calendarApi` 定义
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🧪 测试步骤
|
|||
|
|
|
|||
|
|
1. **修复后端代码**
|
|||
|
|
```bash
|
|||
|
|
cd peidu/backend
|
|||
|
|
mvn clean compile
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **重启后端服务**
|
|||
|
|
|
|||
|
|
3. **测试API**
|
|||
|
|
- 访问 `/api/calendar/appointments?startDate=2026-01-01&endDate=2026-01-31`
|
|||
|
|
- 检查返回的订单是否包含状态1的订单
|
|||
|
|
|
|||
|
|
4. **测试前端**
|
|||
|
|
- 登录家长端
|
|||
|
|
- 进入日历页面
|
|||
|
|
- 检查是否显示订单数据
|
|||
|
|
- 点击日期查看详情
|
|||
|
|
- 点击订单跳转到详情页
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 预期效果
|
|||
|
|
|
|||
|
|
修复后,家长端日历应该:
|
|||
|
|
1. ✅ 显示所有已支付的订单(状态 1, 2, 3, 4)
|
|||
|
|
2. ✅ 日历上显示每天的订单数量
|
|||
|
|
3. ✅ 统计数据正确显示(总数、待服务、已完成)
|
|||
|
|
4. ✅ 点击日期显示当天的订单列表
|
|||
|
|
5. ✅ 点击订单跳转到订单详情页
|
|||
|
|
6. ✅ 每个用户只看到自己的订单数据
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 注意事项
|
|||
|
|
|
|||
|
|
1. **订单状态定义要统一**:确保前后端对订单状态的理解一致
|
|||
|
|
2. **用户ID获取**:需要根据实际的认证方式调整
|
|||
|
|
3. **日历组件**:如果组件不存在,需要创建或使用第三方组件
|
|||
|
|
4. **数据权限**:确保用户只能看到自己的订单数据
|