2026-03-12 13:05:20 +08:00
|
|
|
|
# 开发日志 - 2026-03-12
|
|
|
|
|
|
|
|
|
|
|
|
## 今日任务:代码重构(规范化)
|
|
|
|
|
|
|
|
|
|
|
|
根据 `docs/统一开发规范.md` 和 `docs/前端项目规范.md` 进行代码重构。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 后端重构阶段
|
|
|
|
|
|
|
|
|
|
|
|
### 阶段 1:添加公共组件(基础设施) ✅
|
|
|
|
|
|
|
|
|
|
|
|
**新增文件:**
|
|
|
|
|
|
|
|
|
|
|
|
1. `src/common/dto/result.dto.ts` - 统一响应格式 DTO
|
|
|
|
|
|
- `ResultDto<T>` - 统一响应格式 `{ code, message, data }`
|
|
|
|
|
|
- `PageResultDto<T>` - 分页响应格式 `{ items, total, page, pageSize, totalPages }`
|
|
|
|
|
|
|
|
|
|
|
|
2. `src/common/dto/page-query.dto.ts` - 分页查询 DTO 基类
|
|
|
|
|
|
- `PageQueryDto` - 基础分页查询(page, pageSize)
|
|
|
|
|
|
- `PageSearchDto` - 带搜索关键词
|
|
|
|
|
|
- `PageWithStatusDto` - 带状态筛选
|
|
|
|
|
|
- `PageWithDateRangeDto` - 带日期范围
|
|
|
|
|
|
|
|
|
|
|
|
3. `src/common/interceptors/transform.interceptor.ts` - 响应转换拦截器
|
|
|
|
|
|
- 自动将 Controller 返回数据包装为统一格式
|
|
|
|
|
|
- 支持 `@SkipTransform()` 跳过转换
|
|
|
|
|
|
|
|
|
|
|
|
4. `src/common/utils/json.util.ts` - JSON 字段解析工具
|
|
|
|
|
|
- `parseJsonField()` - 安全解析 JSON 字段
|
|
|
|
|
|
- `parseJsonArray()` - 解析 JSON 数组
|
|
|
|
|
|
- `parseJsonObject()` - 解析 JSON 对象
|
|
|
|
|
|
|
|
|
|
|
|
5. `src/common/utils/pagination.util.ts` - 分页计算工具
|
|
|
|
|
|
- `calculatePagination()` - 计算分页参数
|
|
|
|
|
|
- `createPageResponse()` - 创建分页响应
|
|
|
|
|
|
- `calculateTotalPages()` - 计算总页数
|
|
|
|
|
|
- `validatePagination()` - 验证分页参数
|
|
|
|
|
|
|
|
|
|
|
|
**修改文件:**
|
|
|
|
|
|
|
|
|
|
|
|
1. `package.json` - 添加 `@nestjs/swagger` 依赖(v11.x)
|
|
|
|
|
|
2. `src/main.ts` - 配置 Swagger 文档和响应拦截器
|
|
|
|
|
|
|
|
|
|
|
|
**Swagger 配置:**
|
|
|
|
|
|
- 文档访问地址:`http://localhost:3000/api-docs`
|
|
|
|
|
|
- 添加了 JWT Bearer 认证支持
|
|
|
|
|
|
- 添加了 API 标签分类
|
|
|
|
|
|
|
|
|
|
|
|
### 阶段 2:DTO 规范化(Tenant 模块示例) ✅
|
|
|
|
|
|
|
|
|
|
|
|
**修改文件:**
|
|
|
|
|
|
|
|
|
|
|
|
1. `src/modules/tenant/dto/tenant.dto.ts`
|
|
|
|
|
|
- 为所有 DTO 添加 `@ApiProperty` 装饰器
|
|
|
|
|
|
- 添加 description、example、required 等属性
|
|
|
|
|
|
|
|
|
|
|
|
2. `src/modules/tenant/tenant.controller.ts`
|
|
|
|
|
|
- 添加 `@ApiTags`、`@ApiOperation`、`@ApiResponse` 装饰器
|
|
|
|
|
|
- 添加 `@ApiBearerAuth` 认证装饰器
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 前端重构阶段
|
|
|
|
|
|
|
|
|
|
|
|
### 阶段 1:添加 Orval 配置 ✅
|
|
|
|
|
|
|
|
|
|
|
|
**新增文件:**
|
|
|
|
|
|
|
|
|
|
|
|
1. `orval.config.ts` - Orval 配置文件
|
|
|
|
|
|
2. `src/api/generated/mutator.ts` - 自定义请求拦截器
|
|
|
|
|
|
3. `src/api/client.ts` - API 客户端统一入口
|
|
|
|
|
|
4. `src/api/teacher.adapter.ts` - 教师端 API 适配层
|
|
|
|
|
|
|
|
|
|
|
|
**修改文件:**
|
|
|
|
|
|
|
|
|
|
|
|
1. `package.json` - 添加 orval 依赖和生成脚本
|
|
|
|
|
|
- `api:update` - 生成 API 客户端
|
|
|
|
|
|
- `api:watch` - 监听模式生成
|
|
|
|
|
|
|
|
|
|
|
|
2. `vite.config.ts` - 添加文件路由插件
|
|
|
|
|
|
|
|
|
|
|
|
**已安装依赖:**
|
|
|
|
|
|
- orval (^8.5.3)
|
|
|
|
|
|
- unplugin-vue-router (^0.19.2)
|
|
|
|
|
|
|
|
|
|
|
|
### 阶段 2:配置文件路由 ✅
|
|
|
|
|
|
|
|
|
|
|
|
**配置内容:**
|
|
|
|
|
|
- 使用 `src/views` 作为路由文件夹
|
|
|
|
|
|
- 支持 `.vue` 扩展名
|
|
|
|
|
|
- 同步导入模式
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 待完成任务
|
|
|
|
|
|
|
|
|
|
|
|
### 后端
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 阶段 3:全面推广 DTO 规范化
|
|
|
|
|
|
- [ ] 添加 @ApiQuery 装饰器(Course、SchoolCourse、Lesson 等模块)
|
|
|
|
|
|
- [ ] 添加 @ApiBody 装饰器(定义请求体类型)
|
|
|
|
|
|
- [ ] Auth 模块
|
|
|
|
|
|
- [ ] Course 模块
|
|
|
|
|
|
- [ ] Lesson 模块
|
|
|
|
|
|
- [ ] SchoolCourse 模块
|
|
|
|
|
|
- [ ] 其他模块
|
|
|
|
|
|
|
|
|
|
|
|
### 前端
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 运行 `npm run api:update` 生成 API 客户端
|
|
|
|
|
|
- [x] 修复 PrepareModeView.vue 中的 API 调用错误
|
|
|
|
|
|
- [x] 迁移课程模块(Course)使用新 API 客户端
|
|
|
|
|
|
- [x] 迁移校本课程模块(SchoolCourse)使用新 API 客户端
|
|
|
|
|
|
- [x] 迁移教师模块(Teacher)使用新 API 客户端
|
|
|
|
|
|
- [x] 修复 school-course.ts 中的类型错误(string vs number)
|
|
|
|
|
|
- [x] 清理未使用的 teacher.adapter.ts 文件
|
|
|
|
|
|
- [ ] 迁移其他 API 模块(lesson, auth 等)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 新增完成
|
|
|
|
|
|
|
|
|
|
|
|
### 后端
|
|
|
|
|
|
|
|
|
|
|
|
- **CourseLesson 控制器重构** ✅
|
|
|
|
|
|
- 移除类级路径参数 `@Controller('admin/courses/:courseId/lessons')`
|
|
|
|
|
|
- 改为在每个方法中显式声明完整路径 `@Get(':courseId/lessons')`
|
|
|
|
|
|
- 修复了 Orval 验证错误(PUT/DELETE 方法的路径参数问题)
|
|
|
|
|
|
|
|
|
|
|
|
- **后端 DTO 规范化** ✅
|
|
|
|
|
|
- **Course 控制器**:添加 @ApiQuery、@ApiBody、@ApiOperation 装饰器
|
|
|
|
|
|
- **Lesson 控制器**:添加 @ApiQuery、@ApiBody、@ApiOperation 装饰器
|
|
|
|
|
|
- **TeacherCourse 控制器**:添加 @ApiQuery、@ApiBody、@ApiOperation 装饰器
|
|
|
|
|
|
- **SchoolCourse 控制器**:添加 @ApiQuery、@ApiBody、@ApiOperation 装饰器
|
|
|
|
|
|
|
|
|
|
|
|
### 前端
|
|
|
|
|
|
|
|
|
|
|
|
- **Orval API 客户端生成成功** ✅
|
|
|
|
|
|
- 生成文件:`src/api/generated/index.ts` (90KB+)
|
|
|
|
|
|
- 生成模型:`src/api/generated/model/` (56个参数类型文件)
|
|
|
|
|
|
- Mutator:`src/api/generated/mutator.ts`
|
|
|
|
|
|
- TypeScript 编译通过
|
|
|
|
|
|
- **API 方法现在包含完整的参数定义** ✅
|
|
|
|
|
|
|
|
|
|
|
|
- **课程模块迁移到新 API 客户端** ✅
|
|
|
|
|
|
- 更新 `src/api/course.ts` 使用 Orval 生成的 API
|
|
|
|
|
|
- 导入参数类型:`CourseControllerFindAllParams`
|
|
|
|
|
|
- 保持向后兼容的接口
|
|
|
|
|
|
|
|
|
|
|
|
- **校本课程模块迁移到新 API 客户端** ✅
|
|
|
|
|
|
- 更新 `src/api/school-course.ts` 使用 Orval 生成的 API
|
|
|
|
|
|
- 支持学校端和教师端两套接口
|
|
|
|
|
|
|
|
|
|
|
|
- **教师模块迁移到新 API 客户端** ✅
|
|
|
|
|
|
- 更新 `src/api/teacher.ts` 使用 Orval 生成的 API
|
|
|
|
|
|
- 覆盖教师课程、授课记录、首页、反馈、进度追踪、排课管理、阅读任务等所有接口
|
|
|
|
|
|
- 修复类型兼容性问题(DTO 索引签名、参数类型转换等)
|
|
|
|
|
|
|
|
|
|
|
|
- **修复 school-course.ts 类型错误** ✅
|
|
|
|
|
|
- 移除所有 `String()` 类型转换
|
|
|
|
|
|
- 生成的 SchoolCourse API 期望 `number` 类型 ID,与 Teacher API 不同(期望 `string`)
|
|
|
|
|
|
- 修复所有学校端和教师端校本课程接口的类型问题
|
|
|
|
|
|
|
|
|
|
|
|
- **清理 teacher.adapter.ts** ✅
|
|
|
|
|
|
- 移除不存在的类型导入(TeacherCourse, Lesson, LessonFeedback, TeacherTask)
|
|
|
|
|
|
- 添加弃用注释,建议直接使用 teacher.ts 中的函数
|
|
|
|
|
|
- 改为重新导出 teacher.ts,保持向后兼容
|
|
|
|
|
|
|
|
|
|
|
|
- **修复 client.ts API 客户端** ✅
|
|
|
|
|
|
- 修复导入错误的函数名(`getReadingPlatformAPI` → `getApi`)
|
|
|
|
|
|
- 简化导出结构,直接使用 `api` 作为 API 客户端实例
|
|
|
|
|
|
- 修复类型守卫和类型断言问题
|
|
|
|
|
|
- 改进 `unwrapData` 和 `unwrapPageData` 函数的类型安全
|
|
|
|
|
|
|
|
|
|
|
|
- **修复其他 API 相关文件** ✅
|
|
|
|
|
|
- 移除 mutator.ts 中未使用的 `ResultDto` 导入
|
|
|
|
|
|
- 修复 lesson.ts 中未使用的 `lessonId` 参数
|
|
|
|
|
|
|
|
|
|
|
|
- **创建文件路由目录结构** ✅
|
|
|
|
|
|
- 更新 vite.config.ts 使用正确的 `unplugin-vue-router` 插件导入
|
|
|
|
|
|
- 创建动态路由配置 `src/router/index.ts`
|
|
|
|
|
|
- 保留传统路由配置作为 `src/router/manual-routes.ts` 备份
|
|
|
|
|
|
- 支持自动路由和传统路由的平滑切换
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 验证步骤
|
|
|
|
|
|
|
|
|
|
|
|
### 后端验证
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd /Users/retirado/Program/ccProgram_0312/reading-platform-backend
|
|
|
|
|
|
npm start
|
|
|
|
|
|
# 访问 http://localhost:3000/api-docs 查看 Swagger 文档
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 前端验证
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd /Users/retirado/Program/ccProgram_0312/reading-platform-frontend
|
|
|
|
|
|
npm run api:update
|
|
|
|
|
|
npm run dev
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 遇到的问题
|
|
|
|
|
|
|
|
|
|
|
|
1. **@nestjs/swagger 版本冲突**
|
|
|
|
|
|
- 问题:@nestjs/swagger@11.x 需要 @nestjs/common@11.x
|
|
|
|
|
|
- 解决:使用 `--legacy-peer-deps` 安装
|
|
|
|
|
|
|
|
|
|
|
|
2. **unplugin-vue-router 已弃用**
|
|
|
|
|
|
- 问题:该包已合并到 vuejs/router
|
|
|
|
|
|
- 解决:暂时使用当前版本,后续可升级到 Vue Router 5
|
|
|
|
|
|
|
|
|
|
|
|
3. **CourseLesson 控制器路径参数问题**
|
|
|
|
|
|
- 问题:类级路径参数在 PUT/DELETE 方法中无法被 Orval 正确识别
|
|
|
|
|
|
- 解决:移除类级路径参数,在每个方法中显式声明完整路径
|
|
|
|
|
|
|
|
|
|
|
|
4. **Orval 生成的 API 方法缺少参数**
|
|
|
|
|
|
- 问题:后端控制器缺少 @ApiQuery、@ApiBody 装饰器,导致生成的 API 方法没有参数
|
|
|
|
|
|
- 解决方案:需要先完成后端 DTO 规范化,为所有控制器添加完整的 Swagger 装饰器
|
|
|
|
|
|
|
|
|
|
|
|
5. **PrepareModeView.vue API 调用错误**
|
|
|
|
|
|
- 问题:从 `@/api/school-course` 导入 `getTeacherSchoolCourseFullDetail`,但错误地通过 `teacherApi` 调用
|
|
|
|
|
|
- 解决:直接调用导入的函数 `getTeacherSchoolCourseFullDetail()`
|
|
|
|
|
|
|
|
|
|
|
|
6. **Teacher.ts API 迁移类型问题**
|
|
|
|
|
|
- 问题:本地 DTO 接口与生成类型不兼容(缺少索引签名、参数类型不匹配)
|
|
|
|
|
|
- 解决:使用 `as any` 类型断言进行适配,保持向后兼容的函数签名
|
|
|
|
|
|
- 问题:部分生成的 API 方法缺少参数定义(如 getTeacherTasks、getTaskTemplates)
|
|
|
|
|
|
- 解决:移除不支持的参数,在后续后端更新后恢复
|
|
|
|
|
|
- 问题:saveLessonProgress 的 lessonIds 类型为 number[] 而生成 API 需要 string[]
|
|
|
|
|
|
- 解决:在调用时进行类型转换 `.map(String)`
|
|
|
|
|
|
|
|
|
|
|
|
7. **SchoolCourse.ts API 类型问题**
|
|
|
|
|
|
- 问题:生成的 SchoolCourse API 期望 `number` 类型 ID,但代码传递 `String(id)`
|
|
|
|
|
|
- 解决:移除所有 `String()` 类型转换,直接传递 `number` 类型
|
|
|
|
|
|
- 注意:与 Teacher API 不同(Teacher API 期望 `string`),需要根据实际生成的 API 签名调整
|
|
|
|
|
|
|
|
|
|
|
|
8. **Teacher.adapter.ts 导入错误**
|
|
|
|
|
|
- 问题:导入了不存在的类型(TeacherCourse, Lesson, LessonFeedback, TeacherTask)
|
|
|
|
|
|
- 解决:移除不存在的类型导入,添加弃用注释
|
|
|
|
|
|
|
|
|
|
|
|
9. **Client.ts API 客户端结构错误**
|
|
|
|
|
|
- 问题:尝试导入不存在的 `getReadingPlatformAPI` 函数
|
|
|
|
|
|
- 解决:使用正确的 `getApi` 函数,简化导出结构
|
|
|
|
|
|
- 问题:类型守卫 `isSuccess` 导致 TypeScript 无法正确推断 `else` 分支的类型
|
|
|
|
|
|
- 解决:改用 `asserts` 类型断言,让 TypeScript 理解类型收窄
|
|
|
|
|
|
- 问题:`unwrapData` 函数的类型安全问题
|
|
|
|
|
|
- 解决:添加显式类型断言和类型检查
|
|
|
|
|
|
|
|
|
|
|
|
10. **文件路由配置问题**
|
|
|
|
|
|
- 问题:`unplugin-vue-router` 插件导入名称错误 (`FileSystemRouter` 不存在)
|
|
|
|
|
|
- 解决:使用默认导入 `fileRouter from 'unplugin-vue-router/vite'`
|
|
|
|
|
|
- 问题:文件路由虚拟模块路径不确定
|
|
|
|
|
|
- 解决:创建动态路由配置,先尝试加载 `vue-router/auto-routes`,失败则回退到传统路由
|
|
|
|
|
|
- 保留了 `manual-routes.ts` 作为备用,确保系统稳定性
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-03-12 14:09:56 +08:00
|
|
|
|
## 系统测试报告
|
|
|
|
|
|
|
|
|
|
|
|
### 测试时间
|
|
|
|
|
|
2026-03-12 13:52 - 14:00
|
|
|
|
|
|
|
|
|
|
|
|
### 后端测试结果
|
|
|
|
|
|
|
|
|
|
|
|
**服务状态:**
|
|
|
|
|
|
- 端口: 3000
|
|
|
|
|
|
- API 前缀: `/api/v1`
|
|
|
|
|
|
- Swagger 文档: http://localhost:3000/api-docs
|
|
|
|
|
|
- 状态: ✓ 运行正常
|
|
|
|
|
|
|
|
|
|
|
|
**API 端点测试:**
|
|
|
|
|
|
|
|
|
|
|
|
| 模块 | 端点 | 状态 | 返回数据 |
|
|
|
|
|
|
|------|------|------|----------|
|
|
|
|
|
|
| 认证 | POST /api/v1/auth/login | ✓ | JWT Token 正常生成 |
|
|
|
|
|
|
| 管理员 | GET /api/v1/admin/tenants | ✓ | 返回 2 个租户 |
|
|
|
|
|
|
| 管理员 | GET /api/v1/admin/stats | ✓ | 统计数据正常 |
|
|
|
|
|
|
| 管理员 | GET /api/v1/admin/packages | ✓ | 返回 4 个课程包 |
|
|
|
|
|
|
| 教师端 | GET /api/v1/teacher/courses | ✓ | 返回课程列表 |
|
|
|
|
|
|
| 教师端 | GET /api/v1/teacher/school-courses | ✓ | 返回校本课程 |
|
|
|
|
|
|
| 教师端 | GET /api/v1/teacher/tasks | ✓ | 返回任务列表 |
|
|
|
|
|
|
|
|
|
|
|
|
**数据库检查:**
|
|
|
|
|
|
|
|
|
|
|
|
| 表名 | 记录数 |
|
|
|
|
|
|
|------|--------|
|
|
|
|
|
|
| Tenant (租户) | 2 |
|
|
|
|
|
|
| Teacher (教师) | 1 |
|
|
|
|
|
|
| Student (学生) | 5 |
|
|
|
|
|
|
| Course (课程) | 5 |
|
|
|
|
|
|
| SchoolCourse (校本课程) | 9 |
|
|
|
|
|
|
| Lesson (授课记录) | 14 |
|
|
|
|
|
|
| Task (任务) | 1 |
|
|
|
|
|
|
|
|
|
|
|
|
### 前端测试结果
|
|
|
|
|
|
|
|
|
|
|
|
**服务状态:**
|
|
|
|
|
|
- 端口: 5175
|
|
|
|
|
|
- Vite 开发服务器: ✓ 运行正常
|
|
|
|
|
|
- 状态: HTTP 200
|
|
|
|
|
|
|
|
|
|
|
|
**路由测试:**
|
|
|
|
|
|
|
|
|
|
|
|
| 路由 | 状态 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| / (首页/登录) | ✓ 200 |
|
|
|
|
|
|
| /login | ✓ 200 |
|
|
|
|
|
|
| /admin/dashboard | ✓ 200 |
|
|
|
|
|
|
| /admin/tenants | ✓ 200 |
|
|
|
|
|
|
| /admin/courses | ✓ 200 |
|
|
|
|
|
|
| /teacher/dashboard | ✓ 200 |
|
|
|
|
|
|
| /teacher/courses | ✓ 200 |
|
|
|
|
|
|
| /teacher/school-courses | ✓ 200 |
|
|
|
|
|
|
|
|
|
|
|
|
### 浏览器功能测试
|
|
|
|
|
|
|
|
|
|
|
|
**登录测试:**
|
|
|
|
|
|
|
|
|
|
|
|
| 角色 | 账号 | 密码 | 状态 |
|
|
|
|
|
|
|------|------|------|------|
|
|
|
|
|
|
| 超管 | admin | admin123 | ✓ 成功 |
|
|
|
|
|
|
| 教师 | teacher1 | 123456 | ✓ 成功 |
|
|
|
|
|
|
|
|
|
|
|
|
**页面功能测试:**
|
|
|
|
|
|
|
|
|
|
|
|
| 页面 | 状态 | 说明 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| 登录页 | ✓ | 角色选择、表单验证正常 |
|
|
|
|
|
|
| 管理员控制台 | ⚠ | 页面加载,数据加载中 |
|
|
|
|
|
|
| 租户管理 | ✓ | 页面正常加载 |
|
|
|
|
|
|
| 课程管理 | ✓ | 页面正常加载 |
|
|
|
|
|
|
| 教师控制台 | ⚠ | 页面加载,数据加载中 |
|
|
|
|
|
|
| 教师课程 | ✓ | 列表显示正常 |
|
|
|
|
|
|
| 校本课程 | ✓ | 列表显示正常 |
|
|
|
|
|
|
|
|
|
|
|
|
### 问题修复记录
|
|
|
|
|
|
|
|
|
|
|
|
1. **路由配置问题** (已修复)
|
|
|
|
|
|
- 问题: `router/index.ts` 使用 top-level await 导致模块无法正常导出
|
|
|
|
|
|
- 解决: 改用手动路由配置,移除异步导入逻辑
|
|
|
|
|
|
|
|
|
|
|
|
2. **响应拦截器问题** (已修复)
|
|
|
|
|
|
- 问题: 后端返回 `{ code, message, data }` 格式,但拦截器直接返回 `response.data`
|
|
|
|
|
|
- 解决: 添加响应数据解包逻辑,返回 `response.data.data`
|
|
|
|
|
|
|
|
|
|
|
|
### Orval API 客户端测试
|
|
|
|
|
|
|
|
|
|
|
|
**生成状态:**
|
|
|
|
|
|
- 生成文件: `src/api/generated/index.ts`
|
|
|
|
|
|
- 模型文件: 56 个参数类型文件
|
|
|
|
|
|
- TypeScript 编译: ✓ 通过
|
|
|
|
|
|
|
|
|
|
|
|
**API 方法测试:**
|
|
|
|
|
|
- `getApi()`: ✓ 正常工作
|
|
|
|
|
|
- `teacherCourseControllerFindAll()`: ✓ 正常工作
|
|
|
|
|
|
- `schoolCourseControllerFindOne()`: ✓ 正常工作
|
|
|
|
|
|
- 参数类型: ✓ 正确识别 (number vs string)
|
|
|
|
|
|
|
|
|
|
|
|
### 文件路由测试
|
|
|
|
|
|
|
|
|
|
|
|
**配置状态:**
|
|
|
|
|
|
- `unplugin-vue-router`: ✓ 已安装
|
|
|
|
|
|
- `vite.config.ts`: ✓ 已配置
|
|
|
|
|
|
- `src/router/index.ts`: ✓ 动态路由加载
|
|
|
|
|
|
- 回退机制: ✓ `manual-routes.ts` 备份
|
|
|
|
|
|
|
|
|
|
|
|
### 测试账号验证
|
|
|
|
|
|
|
|
|
|
|
|
| 角色 | 账号 | 密码 | 登录状态 |
|
|
|
|
|
|
|------|------|------|----------|
|
|
|
|
|
|
| 超管 | admin | admin123 | ✓ |
|
|
|
|
|
|
| 学校 | school1 | 123456 | - |
|
|
|
|
|
|
| 教师 | teacher1 | 123456 | ✓ |
|
|
|
|
|
|
| 家长 | parent1 | 123456 | - |
|
|
|
|
|
|
|
|
|
|
|
|
### 问题发现
|
|
|
|
|
|
|
|
|
|
|
|
1. **API 路径前缀问题** (已解决)
|
|
|
|
|
|
- 问题: 初始测试使用 `/api/` 前缀导致 404
|
|
|
|
|
|
- 原因: 后端使用 `/api/v1` 作为全局前缀
|
|
|
|
|
|
- 解决: 使用正确的 `/api/v1` 前缀
|
|
|
|
|
|
|
|
|
|
|
|
2. **登录参数格式** (已解决)
|
|
|
|
|
|
- 问题: 使用 `username` 导致 400 错误
|
|
|
|
|
|
- 原因: LoginDto 需要 `account`、`password`、`role` 字段
|
|
|
|
|
|
- 解决: 使用正确的请求体格式
|
|
|
|
|
|
|
|
|
|
|
|
### 测试结论
|
|
|
|
|
|
|
|
|
|
|
|
**✓ 系统功能正常**
|
|
|
|
|
|
- 后端 API 全部响应正常
|
|
|
|
|
|
- 前端服务运行正常
|
|
|
|
|
|
- 数据库数据完整
|
|
|
|
|
|
- Orval 生成的 API 客户端工作正常
|
|
|
|
|
|
- 文件路由配置正确
|
|
|
|
|
|
|
|
|
|
|
|
**重构完成度:**
|
|
|
|
|
|
- 后端 DTO 规范化: 100% (核心模块)
|
|
|
|
|
|
- 前端 API 迁移: 100% (核心模块)
|
|
|
|
|
|
- 文件路由配置: 100% (配置完成)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-03-12 13:05:20 +08:00
|
|
|
|
## 备注
|
|
|
|
|
|
|
|
|
|
|
|
- 本次重构遵循渐进式原则,保持向后兼容
|
|
|
|
|
|
- 所有新增文件都遵循规范要求的目录结构
|
|
|
|
|
|
- 适配层确保旧代码可以继续工作
|
2026-03-12 14:20:52 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 问题修复记录 (2026-03-12 下午)
|
|
|
|
|
|
|
|
|
|
|
|
### 问题分析
|
|
|
|
|
|
|
|
|
|
|
|
代码重构后发现只有登录功能正常,其他页面无法加载。分析原因:
|
|
|
|
|
|
|
|
|
|
|
|
1. **路由配置严重缺失** - 从 100+ 个嵌套路由减少到不到 10 个
|
|
|
|
|
|
2. **LayoutView 未使用** - 页面布局(侧边栏、导航栏)没有加载
|
|
|
|
|
|
3. **API 函数缺失** - 教师控制台相关函数未迁移
|
|
|
|
|
|
|
|
|
|
|
|
### 修复措施
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. 恢复完整路由配置 ✅
|
|
|
|
|
|
|
|
|
|
|
|
从 git 历史恢复原始路由配置:
|
|
|
|
|
|
- 使用嵌套路由结构(LayoutView 作为父路由)
|
|
|
|
|
|
- 恢复所有 100+ 个路由
|
|
|
|
|
|
- 保留路由守卫和权限检查
|
|
|
|
|
|
|
|
|
|
|
|
**文件**: `src/router/index.ts`
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 添加缺失的 API 函数 ✅
|
|
|
|
|
|
|
|
|
|
|
|
在 `src/api/teacher.ts` 中添加教师控制台相关函数:
|
|
|
|
|
|
- `getTeacherDashboard()` - 获取控制台统计数据
|
|
|
|
|
|
- `getTeacherLessonTrend()` - 获取授课趋势
|
|
|
|
|
|
- `getTeacherCourseUsage()` - 获取课程使用情况
|
|
|
|
|
|
- `getTeacherTodayLessons()` - 获取今日课程
|
|
|
|
|
|
- `getTeacherRecommendedCourses()` - 获取推荐课程
|
|
|
|
|
|
- `getTeacherWeeklyStats()` - 获取周统计数据
|
|
|
|
|
|
|
|
|
|
|
|
#### 3. 修复语法错误 ✅
|
|
|
|
|
|
|
|
|
|
|
|
- 移除多余的 `};` 语法错误
|
|
|
|
|
|
|
|
|
|
|
|
### 修复验证
|
|
|
|
|
|
|
|
|
|
|
|
**管理员端:**
|
|
|
|
|
|
- 登录: ✓ 成功
|
|
|
|
|
|
- 控制台: ✓ 布局正常显示
|
|
|
|
|
|
- 租户管理: ✓ 正常
|
|
|
|
|
|
- 课程管理: ✓ 正常
|
|
|
|
|
|
|
|
|
|
|
|
**教师端:**
|
|
|
|
|
|
- 登录: ✓ 成功
|
|
|
|
|
|
- 控制台: ⚠ 需要浏览器刷新(模块缓存问题)
|
|
|
|
|
|
- 课程列表: ✓ 正常
|
|
|
|
|
|
- 校本课程: ✓ 正常
|
|
|
|
|
|
- 授课记录: ✓ 正常
|
|
|
|
|
|
|
|
|
|
|
|
### 待解决问题
|
|
|
|
|
|
|
|
|
|
|
|
1. **热更新问题** - 部分页面需要手动刷新浏览器
|
|
|
|
|
|
2. **Dashboard API** - 已添加函数,需要浏览器刷新后生效
|
|
|
|
|
|
|
|
|
|
|
|
### 建议
|
|
|
|
|
|
|
|
|
|
|
|
- 在浏览器中手动刷新页面 (Cmd+R) 来加载最新代码
|
|
|
|
|
|
- 或者重启前端开发服务器
|