# 学校端数据导出功能测试记录 **测试日期**: 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 200,Microsoft Excel 2007+ 文件格式 - **包含字段**: 授课日期、授课时间、班级名称、教师姓名、课程名称、状态、学生人数、平均参与度、备注 #### 2. 教师绩效导出 - **接口**: `GET /api/v1/school/export/teacher-stats?startDate=2026-03-01&endDate=2026-03-21` - **状态**: ✅ 通过 - **响应**: HTTP 200,Microsoft Excel 2007+ 文件格式 - **包含字段**: 教师姓名、所属班级、授课次数、课程数量、活跃等级、最后活跃时间、平均参与度 #### 3. 学生统计导出 - **接口**: `GET /api/v1/school/export/student-stats` - **状态**: ✅ 通过 - **响应**: HTTP 200,Microsoft 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 提示"暂无数据"