kindergarten_java/docs/test-logs/school/2026-03-21-export-feature.md
En b361b1885b fix: 教师端首页今日课程 courseName 和 className 关联查询
问题:
- 今日课程功能只查询了 lesson 表,没有 JOIN 关联表
- TeacherLessonVO 的 courseName 和 className 字段为 null
- 前端无法显示课程名称和班级名称

修复:
- LessonMapper 新增 selectTodayLessonsWithDetails() 方法
- 通过 LEFT JOIN course_package 和 clazz 表获取名称
- TeacherStatsServiceImpl 重写 getTodayLessons() 方法
- 添加类型转换辅助方法 (getLong/getString/getLocalDate/getLocalTime/getLocalDateTime)

影响范围:
- 教师端首页 - 今日课程模块
- API: GET /api/v1/teacher/today-lessons
- API: GET /api/v1/teacher/dashboard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 18:43:47 +08:00

304 lines
9.2 KiB
Markdown
Raw 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-03-21
**测试人员**: Claude
**功能模块**: 学校端数据概览 - 数据导出
---
## 实现内容
### 后端实现
#### 1. 添加依赖
- 添加 `EasyExcel 3.3.4` 依赖到 `pom.xml`
#### 2. 新建文件
- `dto/response/LessonExportVO.java` - 授课记录导出 VO
- `dto/response/TeacherPerformanceExportVO.java` - 教师绩效导出 VO
- `dto/response/StudentStatExportVO.java` - 学生统计导出 VO
- `service/SchoolExportService.java` - 导出服务接口
- `service/impl/SchoolExportServiceImpl.java` - 导出服务实现
#### 3. 修改文件
- `mapper/LessonMapper.java` - 添加三个导出查询方法
- `controller/school/SchoolExportController.java` - 实现导出接口
### 前端实现
#### 修改文件
- `src/api/school.ts` - 增强导出函数,处理空数据时返回的 JSON 响应
---
## 测试步骤
### 后端测试
#### 1. 启动后端服务(端口 8481
```bash
export JAVA_HOME="/f/Java/jdk-17"
export SERVER_PORT=8481
cd reading-platform-java
mvn spring-boot:run
```
#### 2. 使用 Swagger 测试接口
访问http://localhost:8481/doc.html
测试以下接口:
- `GET /api/v1/school/export/lessons` - 授课记录导出
- `GET /api/v1/school/export/teacher-stats` - 教师绩效导出
- `GET /api/v1/school/export/student-stats` - 学生统计导出
#### 3. 验证空数据响应
当没有数据时,应返回 JSON
```json
{
"code": 404,
"message": "指定时间范围内暂无授课记录",
"data": null
}
```
---
## 测试用例
### 用例 1导出授课记录
**请求参数**:
- startDate: 2026-03-01
- endDate: 2026-03-21
**预期结果**:
- 成功:下载 Excel 文件,包含授课日期、授课时间、班级名称、教师姓名、课程名称、课程类型、学生人数、平均参与度、评价反馈
- 无数据:返回 JSON 响应 `{code: 404, message: "指定时间范围内暂无授课记录"}`
### 用例 2导出教师绩效统计
**请求参数**:
- startDate: 2026-03-01
- endDate: 2026-03-21
**预期结果**:
- 成功:下载 Excel 文件,包含教师姓名、所属班级、授课次数、课程数量、活跃等级、最后活跃时间、平均参与度
- 无数据:返回 JSON 响应 `{code: 404, message: "指定时间范围内暂无教师绩效数据"}`
### 用例 3导出学生统计
**请求参数**:
- classId: 可选
**预期结果**:
- 成功:下载 Excel 文件,包含学生姓名、性别、班级、授课次数、平均参与度、平均专注度
- 无数据:返回 JSON 响应 `{code: 404, message: "暂无学生统计数据"}`
---
## 前端测试
### 1. 启动前端服务(端口 5174
```bash
export VITE_APP_PORT=5174
cd reading-platform-frontend
npm run dev
```
### 2. 访问学校端数据概览页面
访问http://localhost:5174/school/dashboard
### 3. 测试导出功能
1. 点击"授课记录"导出按钮
2. 点击"教师绩效"导出按钮
3. 点击"学生统计"导出按钮
**预期结果**:
- 有数据时:自动下载 Excel 文件,提示"导出成功"
- 无数据时:提示"暂无数据"或相应错误消息
---
## 导出字段设计
### 授课记录导出 (LessonExportVO)
| Excel 列名 | 字段 | 类型 | 数据来源 |
|-----------|------|------|----------|
| 授课日期 | lessonDate | LocalDate | lesson.lesson_date |
| 授课时间 | timeRange | String | lesson.start_time ~ end_time |
| 班级名称 | className | String | clazz.name |
| 教师姓名 | teacherName | String | teacher.name |
| 课程名称 | courseName | String | course_package.name |
| 课程类型 | lessonType | String | lesson.lesson_type |
| 学生人数 | studentCount | Integer | student_record count |
| 平均参与度 | avgParticipation | Double | avg(student_record.participation) |
| 评价反馈 | feedbackContent | String | lesson_feedback.content |
### 教师绩效导出 (TeacherPerformanceExportVO)
| Excel 列名 | 字段 | 类型 | 数据来源 |
|-----------|------|------|----------|
| 教师姓名 | teacherName | String | teacher.name |
| 所属班级 | classNames | String | GROUP_CONCAT(clazz.name) |
| 授课次数 | lessonCount | Integer | COUNT(lesson.id) |
| 课程数量 | courseCount | Integer | COUNT(DISTINCT course_id) |
| 活跃等级 | activityLevel | String | CASE WHEN |
| 最后活跃时间 | lastActiveAt | LocalDateTime | MAX(end_datetime) |
| 平均参与度 | avgParticipation | Double | AVG(participation) |
### 学生统计导出 (StudentStatExportVO)
| Excel 列名 | 字段 | 类型 | 数据来源 |
|-----------|------|------|----------|
| 学生姓名 | studentName | String | student.name |
| 性别 | gender | String | student.gender |
| 班级 | className | String | clazz.name |
| 授课次数 | lessonCount | Integer | COUNT(lesson.id) |
| 平均参与度 | avgParticipation | Double | AVG(participation) |
| 平均专注度 | avgFocus | Double | AVG(focus) |
---
## 注意事项
1. **日期范围处理**:前端传入日期字符串,后端解析为 LocalDate
2. **文件名编码**:中文文件名使用 URLEncoder 编码
3. **空数据处理**:没有数据时返回 JSON 响应,不生成 Excel 文件
4. **Content-Type 判断**:前端需要判断响应头,区分 Excel 和 JSON 响应
5. **权限验证**:通过 `@RequireRole(UserRole.SCHOOL)` 确保只导出当前租户数据
---
## 待办事项
- [ ] 后端服务启动验证
- [ ] Swagger 接口测试
- [ ] 前端页面功能测试
- [ ] 空数据场景测试
- [ ] 大数据量导出性能测试
---
## 测试结果
| 测试项 | 状态 | 备注 |
|--------|------|------|
| 编译通过 | ✅ | 后端编译成功 |
| 授课记录导出 | ✅ | HTTP 200生成 Excel 文件 (5.6KB, 39 条记录) |
| 教师绩效导出 | ✅ | HTTP 200生成 Excel 文件 (4.1KB, 10 条记录) |
| 学生统计导出 | ✅ | HTTP 200生成 Excel 文件 |
| 空数据处理 | ✅ | 返回 JSON `{code: 404, message: "指定时间范围内暂无授课记录"}` |
| 前端服务 | ✅ | 端口 5174 正常运行 |
---
## 问题修复
### 修复 1: 授课记录日期时间为空
**问题**: 授课日期和授课时间字段在 Excel 中显示为空
**原因**:
1. SQL 返回的 Map 使用下划线命名 (`lesson_date`),但 Java 代码获取驼峰命名 (`lessonDate`)
2. SQL 返回的是 `java.sql.Date``java.sql.Time` 类型,不能直接转换为 `LocalDate``LocalTime`
**解决**:
```java
// 日期转换
Object dateObj = row.get("lesson_date");
if (dateObj instanceof java.sql.Date) {
vo.setLessonDate(((java.sql.Date) dateObj).toLocalDate());
}
// 时间转换
Object startTimeObj = row.get("start_time");
if (startTimeObj instanceof java.sql.Time) {
vo.setTimeRange(((java.sql.Time) startTimeObj).toLocalTime().format(TIME_FORMATTER) + ...);
}
```
### 修复 2: 教师绩效活跃等级未翻译
**问题**: Excel 中活跃等级显示为 `HIGH`/`MEDIUM`/`LOW`/`INACTIVE` 英文代码
**解决**: 添加翻译方法 `translateActivityLevel()`:
```java
private String translateActivityLevel(String code) {
switch (code) {
case "HIGH": return "高";
case "MEDIUM": return "中";
case "LOW": return "低";
case "INACTIVE": return "未活跃";
default: return code;
}
}
```
---
## 测试详情
### 后端接口测试结果
**测试时间**: 2026-03-21
#### 1. 授课记录导出
- **接口**: `GET /api/v1/school/export/lessons?startDate=2026-03-01&endDate=2026-03-21`
- **状态**: ✅ 通过
- **响应**: HTTP 200Microsoft Excel 2007+ 文件格式
- **包含字段**: 授课日期、授课时间、班级名称、教师姓名、课程名称、状态、学生人数、平均参与度、备注
#### 2. 教师绩效导出
- **接口**: `GET /api/v1/school/export/teacher-stats?startDate=2026-03-01&endDate=2026-03-21`
- **状态**: ✅ 通过
- **响应**: HTTP 200Microsoft Excel 2007+ 文件格式
- **包含字段**: 教师姓名、所属班级、授课次数、课程数量、活跃等级、最后活跃时间、平均参与度
#### 3. 学生统计导出
- **接口**: `GET /api/v1/school/export/student-stats`
- **状态**: ✅ 通过
- **响应**: HTTP 200Microsoft Excel 2007+ 文件格式
- **包含字段**: 学生姓名、性别、年级、授课次数、平均参与度、平均专注度
#### 4. 空数据处理测试
- **接口**: `GET /api/v1/school/export/lessons?startDate=2020-01-01&endDate=2020-01-07`
- **状态**: ✅ 通过
- **响应**: `{"code":404,"message":"指定时间范围内暂无授课记录"}`
---
## 修复记录
1. **修复 lesson_type 字段不存在问题**
- 问题:`lesson` 表没有 `lesson_type` 字段
- 解决:移除 SQL 中的 `l.lesson_type`,改用 `l.status``l.notes`
2. **修复 student 表 class_id 字段不存在问题**
- 问题:`student` 表没有 `class_id` 字段
- 解决:改用 `s.grade` 作为 `className` 显示
---
## 前端测试
### 访问地址
- 前端http://localhost:5174
- 后端http://localhost:8481
- 登录账号school1 / 123456
### 测试步骤
1. 访问 http://localhost:5174/login 登录学校账号
2. 进入"数据概览"页面
3. 点击"授课记录"、"教师绩效"、"学生统计"导出按钮
### 预期结果
- 有数据时:自动下载 Excel 文件message 提示"导出成功"
- 无数据时message 提示"暂无数据"