feat: 完善 OpenAPI 注解和前端 API 客户端
主要变更: 1. 所有 Entity/DTO/VO 添加 @Schema 注解,完善 API 文档 2. 新增前端 API 封装模块 (src/apis),包含 fetch.ts 和 apis.ts 3. 生成完整的 TypeScript 类型定义(100+ 个模型) 4. pom.xml 添加 Maven 编译配置和 UTF-8 编码支持 5. 更新 CLAUDE.md 开发文档 6. 清理旧的文档文件 技术细节: - 后端:27 个实体类 + 所有 DTO/Response 添加 Swagger 注解 - 前端:新增 orval 生成的 API 客户端类型 - 构建:配置 Maven compiler plugin 和 Spring Boot 插件的 JVM 参数 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
583b47c430
commit
9204f9329e
161
API 对比分析.md
161
API 对比分析.md
@ -1,161 +0,0 @@
|
|||||||
# API 对比分析报告
|
|
||||||
|
|
||||||
## 概述
|
|
||||||
对比 reading-platform-backend (Node.js/NestJS) 和 reading-platform-java (Spring Boot) 的 API 接口差异
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 已补全的接口
|
|
||||||
|
|
||||||
### 1. 任务管理相关接口(SchoolTaskController, TeacherTaskController)
|
|
||||||
|
|
||||||
#### 任务统计接口
|
|
||||||
- `GET /api/v1/school/tasks/stats` - 获取任务统计数据
|
|
||||||
- `GET /api/v1/school/tasks/stats/by-type` - 按任务类型统计
|
|
||||||
- `GET /api/v1/school/tasks/stats/by-class` - 按班级统计
|
|
||||||
- `GET /api/v1/school/tasks/stats/monthly` - 月度统计趋势
|
|
||||||
|
|
||||||
#### 任务完成情况接口
|
|
||||||
- `GET /api/v1/school/tasks/:id/completions` - 获取任务完成情况分页
|
|
||||||
- `PUT /api/v1/school/tasks/:taskId/completions/:studentId` - 更新任务完成状态
|
|
||||||
|
|
||||||
#### 任务模板接口
|
|
||||||
- `GET /api/v1/school/task-templates` - 获取任务模板列表
|
|
||||||
- `GET /api/v1/school/task-templates/:id` - 获取单个模板
|
|
||||||
- `GET /api/v1/school/task-templates/default/:taskType` - 获取默认模板
|
|
||||||
- `POST /api/v1/school/task-templates` - 创建模板
|
|
||||||
- `PUT /api/v1/school/task-templates/:id` - 更新模板
|
|
||||||
- `DELETE /api/v1/school/task-templates/:id` - 删除模板
|
|
||||||
- `POST /api/v1/school/tasks/from-template` - 从模板创建任务
|
|
||||||
|
|
||||||
### 2. 通知相关接口
|
|
||||||
|
|
||||||
#### 学校管理员通知(SchoolNotificationController - 新增)
|
|
||||||
- `GET /api/v1/school/notifications` - 获取通知列表
|
|
||||||
- `GET /api/v1/school/notifications/:id` - 根据 ID 获取通知
|
|
||||||
- `GET /api/v1/school/notifications/unread-count` - 获取未读数量
|
|
||||||
- `POST /api/v1/school/notifications/:id/read` - 标记已读
|
|
||||||
- `POST /api/v1/school/notifications/read-all` - 全部标记已读
|
|
||||||
|
|
||||||
### 3. 排课和课表相关接口(SchoolScheduleController)
|
|
||||||
- `GET /api/v1/school/schedules/timetable` - 获取课表(带日期范围)
|
|
||||||
- `POST /api/v1/school/schedules/batch` - 批量创建排课
|
|
||||||
- `GET /api/v1/school/schedules/templates/:id` - 获取单个模板
|
|
||||||
- `PUT /api/v1/school/schedules/templates/:id` - 更新模板
|
|
||||||
- `POST /api/v1/school/schedules/templates/:id/apply` - 应用模板
|
|
||||||
|
|
||||||
### 4. 新增 DTO
|
|
||||||
- `TaskTemplateCreateRequest` - 任务模板创建请求
|
|
||||||
- `TaskTemplateUpdateRequest` - 任务模板更新请求
|
|
||||||
- `CreateTaskFromTemplateRequest` - 从模板创建任务请求
|
|
||||||
- `SchedulePlanCreateRequest` - 课表计划创建请求
|
|
||||||
- `ScheduleTemplateApplyRequest` - 课表模板应用请求
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 仍需补全的接口
|
|
||||||
|
|
||||||
### P1 - 重要功能
|
|
||||||
|
|
||||||
#### 1. 成长档案接口(SchoolGrowthController, TeacherGrowthController)
|
|
||||||
- `GET /api/v1/school/students/:studentId/growth-records` - 按学生查询成长档案
|
|
||||||
- `GET /api/v1/school/classes/:classId/growth-records` - 按班级查询成长档案
|
|
||||||
- `GET /api/v1/teacher/classes/:classId/growth-records` - 教师端按班级查询
|
|
||||||
|
|
||||||
#### 2. 教师端课时增强接口(TeacherLessonController)
|
|
||||||
- `POST /api/v1/teacher/lessons/:id/finish` - 完成课时(带反馈数据)
|
|
||||||
- `POST /api/v1/teacher/lessons/:id/students/:studentId/record` - 保存学生记录
|
|
||||||
- `GET /api/v1/teacher/lessons/:id/student-records` - 获取学生记录
|
|
||||||
- `POST /api/v1/teacher/lessons/:id/student-records/batch` - 批量保存学生记录
|
|
||||||
- `POST /api/v1/teacher/lessons/:id/feedback` - 提交反馈
|
|
||||||
- `GET /api/v1/teacher/lessons/:id/feedback` - 获取反馈
|
|
||||||
|
|
||||||
#### 3. 教师端课程增强接口(TeacherCourseController)
|
|
||||||
- `GET /api/v1/teacher/courses/classes` - 获取班级列表
|
|
||||||
- `GET /api/v1/teacher/students` - 获取所有学生
|
|
||||||
- `GET /api/v1/teacher/classes/:id/students` - 获取班级学生
|
|
||||||
- `GET /api/v1/teacher/classes/:id/teachers` - 获取班级教师
|
|
||||||
- `GET /api/v1/teacher/schedules/timetable` - 获取课表
|
|
||||||
- `GET /api/v1/teacher/schedules/today` - 获取今天排课
|
|
||||||
- `POST /api/v1/teacher/schedules` - 创建排课
|
|
||||||
- `PUT /api/v1/teacher/schedules/:id` - 更新排课
|
|
||||||
- `DELETE /api/v1/teacher/schedules/:id` - 取消排课
|
|
||||||
|
|
||||||
#### 4. 班级管理接口(SchoolClassController)
|
|
||||||
- `GET /api/v1/school/classes/:id/students` - 获取班级学生
|
|
||||||
- `GET /api/v1/school/classes/:id/teachers` - 获取班级教师
|
|
||||||
- `POST /api/v1/school/classes/:id/teachers` - 添加班级教师
|
|
||||||
- `PUT /api/v1/school/classes/:id/teachers/:teacherId` - 更新班级教师
|
|
||||||
- `DELETE /api/v1/school/classes/:id/teachers/:teacherId` - 移除班级教师
|
|
||||||
- `POST /api/v1/school/students/:id/transfer` - 学生调班
|
|
||||||
- `GET /api/v1/school/students/:id/history` - 学生调班历史
|
|
||||||
- `POST /api/v1/school/students/import` - 批量导入学生
|
|
||||||
- `GET /api/v1/school/students/import/template` - 获取导入模板
|
|
||||||
|
|
||||||
### P2 - 辅助功能
|
|
||||||
|
|
||||||
#### 1. 统计报告接口(SchoolStatsController)
|
|
||||||
- `GET /api/v1/school/stats/teachers` - 活跃教师统计
|
|
||||||
- `GET /api/v1/school/stats/courses` - 课程使用统计
|
|
||||||
- `GET /api/v1/school/stats/activities` - 最近活动
|
|
||||||
- `GET /api/v1/school/stats/lesson-trend` - 课时趋势
|
|
||||||
- `GET /api/v1/school/stats/course-distribution` - 课程分布
|
|
||||||
- `GET /api/v1/school/reports/overview` - 概览报告
|
|
||||||
- `GET /api/v1/school/reports/teachers` - 教师报告
|
|
||||||
- `GET /api/v1/school/reports/courses` - 课程报告
|
|
||||||
- `GET /api/v1/school/reports/students` - 学生报告
|
|
||||||
|
|
||||||
#### 2. 导出接口增强(SchoolExportController)
|
|
||||||
- `GET /api/v1/school/export/lessons?startDate=&endDate=` - 导出课时(带日期范围)
|
|
||||||
- `GET /api/v1/school/export/teacher-stats?startDate=&endDate=` - 导出教师统计
|
|
||||||
- `GET /api/v1/school/export/student-stats?classId=` - 导出学生统计(按班级)
|
|
||||||
|
|
||||||
#### 3. 课程包/套餐接口
|
|
||||||
- `GET /api/v1/school/package` - 获取套餐信息
|
|
||||||
- `GET /api/v1/school/package/usage` - 获取套餐使用情况
|
|
||||||
|
|
||||||
#### 4. 家长相关接口
|
|
||||||
- `POST /api/v1/school/parents/:parentId/children/:studentId` - 添加孩子到家长
|
|
||||||
- `DELETE /api/v1/school/parents/:parentId/children/:studentId` - 从家长移除孩子
|
|
||||||
|
|
||||||
#### 5. 管理员课程接口
|
|
||||||
- `GET /api/v1/admin/courses/:id/stats` - 课程统计
|
|
||||||
- `GET /api/v1/admin/courses/:id/validate` - 验证课程
|
|
||||||
- `GET /api/v1/admin/courses/:id/versions` - 版本历史
|
|
||||||
- `POST /api/v1/admin/courses/:id/submit` - 提交审核
|
|
||||||
- `POST /api/v1/admin/courses/:id/withdraw` - 撤销审核
|
|
||||||
- `POST /api/v1/admin/courses/:id/approve` - 审核通过
|
|
||||||
- `POST /api/v1/admin/courses/:id/reject` - 审核驳回
|
|
||||||
- `POST /api/v1/admin/courses/:id/direct-publish` - 直接发布
|
|
||||||
- `POST /api/v1/admin/courses/:id/publish` - 发布
|
|
||||||
- `POST /api/v1/admin/courses/:id/unpublish` - 下架
|
|
||||||
- `POST /api/v1/admin/courses/:id/republish` - 重新发布
|
|
||||||
|
|
||||||
#### 6. 资源接口增强
|
|
||||||
- `POST /api/v1/admin/resources/items/batch-delete` - 批量删除资源项
|
|
||||||
- `GET /api/v1/admin/resources/stats` - 资源统计
|
|
||||||
|
|
||||||
#### 7. 反馈接口
|
|
||||||
- `GET /api/v1/teacher/feedbacks` - 获取反馈列表
|
|
||||||
- `GET /api/v1/teacher/feedbacks/stats` - 获取反馈统计
|
|
||||||
- `GET /api/v1/school/feedbacks` - 获取反馈列表(学校端)
|
|
||||||
- `GET /api/v1/school/feedbacks/stats` - 获取反馈统计(学校端)
|
|
||||||
|
|
||||||
#### 8. 认证接口
|
|
||||||
- `GET /api/v1/auth/profile` - 获取用户信息
|
|
||||||
- `POST /api/v1/auth/logout` - 登出
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 总结
|
|
||||||
|
|
||||||
本次补全了以下主要功能:
|
|
||||||
1. 任务管理:统计、模板、完成情况更新
|
|
||||||
2. 通知:学校管理员通知接口
|
|
||||||
3. 排课:课表模板、批量创建、应用模板
|
|
||||||
|
|
||||||
下一步建议优先补全:
|
|
||||||
1. 成长档案按学生/班级查询接口
|
|
||||||
2. 教师端课时反馈接口
|
|
||||||
3. 班级管理相关接口
|
|
||||||
4. 学生调班和批量导入接口
|
|
||||||
132
Service 重构总结.md
132
Service 重构总结.md
@ -1,132 +0,0 @@
|
|||||||
# Service 层重构总结
|
|
||||||
|
|
||||||
## 重构时间
|
|
||||||
2026-03-10
|
|
||||||
|
|
||||||
## 重构目的
|
|
||||||
将 Service 层从"直接 class 实现"重构为"interface + impl"模式,符合 Spring 最佳实践。
|
|
||||||
|
|
||||||
## 重构的 Service 列表
|
|
||||||
|
|
||||||
本次重构共完成了 14 个 Service 的 interface + impl 模式改造:
|
|
||||||
|
|
||||||
### 新增的 Interface 文件
|
|
||||||
|
|
||||||
| 序号 | 接口文件 | 实现类文件 |
|
|
||||||
|------|----------|------------|
|
|
||||||
| 1 | `AdminStatsService.java` | `AdminStatsServiceImpl.java` |
|
|
||||||
| 2 | `CourseLessonService.java` | `CourseLessonServiceImpl.java` |
|
|
||||||
| 3 | `CoursePackageService.java` | `CoursePackageServiceImpl.java` |
|
|
||||||
| 4 | `ExportService.java` | `ExportServiceImpl.java` |
|
|
||||||
| 5 | `FileUploadService.java` | `FileUploadServiceImpl.java` |
|
|
||||||
| 6 | `OperationLogService.java` | `OperationLogServiceImpl.java` |
|
|
||||||
| 7 | `ResourceService.java` | `ResourceServiceImpl.java` |
|
|
||||||
| 8 | `SchoolCourseService.java` | `SchoolCourseServiceImpl.java` |
|
|
||||||
| 9 | `SystemSettingService.java` | `SystemSettingServiceImpl.java` |
|
|
||||||
| 10 | `TeacherDashboardService.java` | `TeacherDashboardServiceImpl.java` |
|
|
||||||
| 11 | `ScheduleService.java` | `ScheduleServiceImpl.java` |
|
|
||||||
| 12 | `ThemeService.java` | `ThemeServiceImpl.java` |
|
|
||||||
| 13 | `TenantService.java` | `TenantServiceImpl.java` (已存在) |
|
|
||||||
| 14 | `SchoolStatsService.java` | `SchoolStatsServiceImpl.java` |
|
|
||||||
|
|
||||||
### 已有的 Interface + Impl 模式 Service
|
|
||||||
|
|
||||||
以下 Service 在重构前已经是 interface + impl 模式:
|
|
||||||
|
|
||||||
1. `AuthService` → `AuthServiceImpl`
|
|
||||||
2. `ClassService` → `ClassServiceImpl`
|
|
||||||
3. `StudentService` → `StudentServiceImpl`
|
|
||||||
4. `TaskService` → `TaskServiceImpl`
|
|
||||||
5. `CourseService` → `CourseServiceImpl`
|
|
||||||
6. `GrowthRecordService` → `GrowthRecordServiceImpl`
|
|
||||||
7. `LessonService` → `LessonServiceImpl`
|
|
||||||
8. `NotificationService` → `NotificationServiceImpl`
|
|
||||||
9. `ParentService` → `ParentServiceImpl`
|
|
||||||
10. `TeacherService` → `TeacherServiceImpl`
|
|
||||||
11. `TokenService` → `TokenServiceImpl`
|
|
||||||
|
|
||||||
## 重构模式
|
|
||||||
|
|
||||||
所有 Service 遵循以下模式:
|
|
||||||
|
|
||||||
### Interface 定义
|
|
||||||
```java
|
|
||||||
package com.reading.platform.service;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 服务接口
|
|
||||||
*/
|
|
||||||
public interface XxxService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 方法描述
|
|
||||||
*/
|
|
||||||
List<Xxx> getXxxList(Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 方法描述
|
|
||||||
*/
|
|
||||||
Xxx createXxx(XxxCreateRequest request);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Impl 实现类
|
|
||||||
```java
|
|
||||||
package com.reading.platform.service.impl;
|
|
||||||
|
|
||||||
import com.reading.platform.mapper.XxxMapper;
|
|
||||||
import com.reading.platform.service.XxxService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 服务实现类
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class XxxServiceImpl implements XxxService {
|
|
||||||
|
|
||||||
private final XxxMapper xxxMapper;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Xxx> getXxxList(Long id) {
|
|
||||||
// 业务逻辑
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Xxx createXxx(XxxCreateRequest request) {
|
|
||||||
// 业务逻辑
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 架构优势
|
|
||||||
|
|
||||||
1. **依赖倒置**:Controller 依赖接口而非具体实现
|
|
||||||
2. **易于测试**:可以通过 Mock 接口进行测试
|
|
||||||
3. **易于扩展**:可以轻松切换不同的实现
|
|
||||||
4. **代码规范**:符合 Spring 官方推荐的最佳实践
|
|
||||||
|
|
||||||
## 编译验证
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd reading-platform-java
|
|
||||||
mvn clean compile -DskipTests
|
|
||||||
```
|
|
||||||
|
|
||||||
编译结果:**BUILD SUCCESS**
|
|
||||||
|
|
||||||
## 文件统计
|
|
||||||
|
|
||||||
- 接口文件:25 个
|
|
||||||
- 实现类文件:25 个
|
|
||||||
- 总计:50 个 Service 相关文件
|
|
||||||
|
|
||||||
## 后续建议
|
|
||||||
|
|
||||||
1. 为新实现的接口添加单元测试
|
|
||||||
2. 在 CI/CD 流程中确保编译使用 JDK 17
|
|
||||||
3. 保持新增 Service 遵循 interface + impl 模式
|
|
||||||
18
reading-platform-frontend/src/apis/SwaggerType.ts
Normal file
18
reading-platform-frontend/src/apis/SwaggerType.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// type Swagger = 'get' | 'post';
|
||||||
|
// http://192.168.1.110:8280/stat/doc.html#/home
|
||||||
|
export interface RequestType {
|
||||||
|
param: {
|
||||||
|
path?: string[] | number[] | string | number;
|
||||||
|
query?: { [key: string]: string | number };
|
||||||
|
data?: { [key: string]: string | number };
|
||||||
|
};
|
||||||
|
response: any;
|
||||||
|
}
|
||||||
|
export interface SwaggerType {
|
||||||
|
[key: string]: {
|
||||||
|
get?: RequestType;
|
||||||
|
post?: RequestType;
|
||||||
|
put?: RequestType;
|
||||||
|
delete?: RequestType;
|
||||||
|
};
|
||||||
|
}
|
||||||
55
reading-platform-frontend/src/apis/apis.ts
Normal file
55
reading-platform-frontend/src/apis/apis.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { SwaggerType } from './SwaggerType';
|
||||||
|
export default interface SwaggerInterface extends SwaggerType {
|
||||||
|
/***
|
||||||
|
* 视频大盘-卡片核心指标
|
||||||
|
*/
|
||||||
|
'/test/xxxx': {
|
||||||
|
get: {
|
||||||
|
param: {
|
||||||
|
query: {
|
||||||
|
/**统计类型:1=周,2=月,3=季度,4=年,5=自定义 */
|
||||||
|
type: number;
|
||||||
|
/**开始日期(yyyy-MM-dd),type=5 时必填 */
|
||||||
|
startDate?: string;
|
||||||
|
/**结束日期(yyyy-MM-dd),type=5 时必填 */
|
||||||
|
endDate?: string;
|
||||||
|
/**机构ID,不传则从登录用户部门获取 */
|
||||||
|
institutionId?: number;
|
||||||
|
/**分类ID */
|
||||||
|
categoryId?: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
/**访问人次 */
|
||||||
|
userCount: {
|
||||||
|
/**数值 */
|
||||||
|
value: number;
|
||||||
|
/**环比百分比 */
|
||||||
|
ratio: number;
|
||||||
|
};
|
||||||
|
/**点击量 */
|
||||||
|
clickCount: {
|
||||||
|
value: number;
|
||||||
|
ratio: number;
|
||||||
|
};
|
||||||
|
/**观看时长(小时) */
|
||||||
|
watchDuration: {
|
||||||
|
value: number;
|
||||||
|
ratio: number;
|
||||||
|
};
|
||||||
|
/**请求数 */
|
||||||
|
requestCount: {
|
||||||
|
value: number;
|
||||||
|
ratio: number;
|
||||||
|
};
|
||||||
|
/**出口流量(GB) */
|
||||||
|
trafficOut: {
|
||||||
|
value: number;
|
||||||
|
ratio: number;
|
||||||
|
};
|
||||||
|
/**存储用量,暂未实现 */
|
||||||
|
storageUsage: null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
234
reading-platform-frontend/src/apis/fetch.ts
Normal file
234
reading-platform-frontend/src/apis/fetch.ts
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
import type { UrlKey, MethodKey, Param, Response } from './index';
|
||||||
|
// import { message } from 'ant-design-vue';
|
||||||
|
// import { LocalStorageKey } from '@/utils/useLocalStorage';
|
||||||
|
// import { getAppEnvConfig } from '@/utils/env';
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
|
// const { VITE_BASE_API, VITE_PREFIX_API } = getAppEnvConfig();
|
||||||
|
export type FetchOptions = Omit<RequestInit, 'body' | 'method'> & {
|
||||||
|
type?: 'arrayBuffer' | 'blob' | 'formData' | 'json' | 'text';
|
||||||
|
payloadType?: 'json' | 'text' | 'formData' | 'form-urlencoded';
|
||||||
|
successMsg?: string;
|
||||||
|
noMsg?: boolean;
|
||||||
|
apiType?: 'BOOK';
|
||||||
|
};
|
||||||
|
|
||||||
|
// const payloadMapping = {
|
||||||
|
// json: 'application/json;charset=UTF-8',
|
||||||
|
// text: 'text/plain;charset=UTF-8',
|
||||||
|
// formData: 'multipart/form-data',
|
||||||
|
// 'form-urlencoded': 'application/x-www-form-urlencoded',
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // const noAuthUrl: UrlKey[] = ['/activity/bbs/login', '/activity/bbs/randomImage', '/activity/bbs/bbsSection/all', '/activity/bbs/bbsPost/list', '/activity/bbs/bbsPost/queryById'];
|
||||||
|
// const noAuthUrl: UrlKey[] = ['/activity/bbs/login', '/activity/bbs/randomImage'];
|
||||||
|
// function useAuthToken() {
|
||||||
|
// // const _token = localStorage.getItem(LocalStorageKey.tokenKey);
|
||||||
|
// return {
|
||||||
|
// token: '',
|
||||||
|
// // token: _token && _token.trim().length > 0 ? _token : null,
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求header
|
||||||
|
* @description: contentTyp
|
||||||
|
*/
|
||||||
|
export enum ConfigEnum {
|
||||||
|
// TOKEN
|
||||||
|
TOKEN = 'Authorization',
|
||||||
|
XTOKEN = 'X-Access-Token',
|
||||||
|
// TIMESTAMP
|
||||||
|
TIMESTAMP = 'X-TIMESTAMP',
|
||||||
|
// Sign
|
||||||
|
Sign = 'X-Sign',
|
||||||
|
// 租户id
|
||||||
|
TENANT_ID = 'X-Tenant-Id',
|
||||||
|
// 版本
|
||||||
|
VERSION = 'X-Version',
|
||||||
|
// 低代码应用ID
|
||||||
|
X_LOW_APP_ID = 'X-Low-App-ID',
|
||||||
|
}
|
||||||
|
|
||||||
|
// export const baseToken = ref<string | null>(useAuthToken().token);
|
||||||
|
// export function getHeaders() {
|
||||||
|
// const defaultHeaders = {
|
||||||
|
// // "Content-Type": payloadMapping[payloadType]
|
||||||
|
// };
|
||||||
|
|
||||||
|
// let authHeaders = {
|
||||||
|
// Authorization: `Bearer ${baseToken.value}`,
|
||||||
|
// };
|
||||||
|
// return Object.assign(defaultHeaders, authHeaders);
|
||||||
|
// }
|
||||||
|
|
||||||
|
type MethodType = 'OPTIONS' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT';
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param url 路径,直接从swagger上拷贝下来的路径,包括{id}这类的动态路径
|
||||||
|
* @param param FetchParams 请求参数,分为 path query body 分别对应 路径参数(类似/delete/{id})、查询参数(类似/query?id=123)、body(post body参数,将会JSON.stringfiy为字符串)
|
||||||
|
* @param options FetchOptions fetch 去除body、method的原生参数,增加 type 用于格式化掉用res.json()类型的功能。
|
||||||
|
* @returns fetch
|
||||||
|
*/
|
||||||
|
export default async function request<U extends UrlKey, M extends MethodKey<U>>(
|
||||||
|
url: U,
|
||||||
|
method: M,
|
||||||
|
params?: Param<U, M> | undefined,
|
||||||
|
{ apiType, type = 'json', payloadType = 'json', successMsg, noMsg, headers, ...restOptions }: FetchOptions = {}
|
||||||
|
): Promise<Response<U, M>> {
|
||||||
|
const requestMethod = (method as string).toLowerCase() as MethodType;
|
||||||
|
|
||||||
|
const { path, query, data } = (params || {}) as {
|
||||||
|
path?: string[] | string;
|
||||||
|
query?: any;
|
||||||
|
data?: any;
|
||||||
|
};
|
||||||
|
// let iUrl = `${VITE_BASE_API}${VITE_PREFIX_API}${url}`;
|
||||||
|
let iUrl = `${url}`;
|
||||||
|
|
||||||
|
if (path) {
|
||||||
|
if (Array.isArray(path)) {
|
||||||
|
iUrl = `${iUrl}/${path.join('/')}`;
|
||||||
|
} else {
|
||||||
|
iUrl = `${iUrl}/${path}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iUrl = getQuery(iUrl, filterEmpty(query));
|
||||||
|
|
||||||
|
return defHttp.request({
|
||||||
|
method: requestMethod,
|
||||||
|
url: iUrl,
|
||||||
|
data: filterEmpty(data),
|
||||||
|
});
|
||||||
|
|
||||||
|
// const defaultHeaders = {
|
||||||
|
// 'Content-Type': payloadMapping[payloadType],
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // 将token加入进去
|
||||||
|
// let authHeaders: any = {
|
||||||
|
// // 'Content-Type': 'application/json'
|
||||||
|
// };
|
||||||
|
// if (!noAuthUrl.includes(url)) {
|
||||||
|
// // const { token } = useAuthToken();
|
||||||
|
// authHeaders[ConfigEnum.TOKEN] = baseToken.value ? `Bearer ${baseToken.value}` : '';
|
||||||
|
// // authHeaders[ConfigEnum.XTOKEN] = token;
|
||||||
|
// }
|
||||||
|
// const param: any = {
|
||||||
|
// ...restOptions,
|
||||||
|
// method: requestMethod,
|
||||||
|
// // body: JSON.stringify(filterEmpty(data)),
|
||||||
|
// headers: Object.assign(defaultHeaders, headers, authHeaders),
|
||||||
|
// };
|
||||||
|
// if (requestMethod.toLowerCase() !== 'get') {
|
||||||
|
// param.body = JSON.stringify(filterEmpty(data));
|
||||||
|
// }
|
||||||
|
// return fetch(iUrl, param)
|
||||||
|
// .then((response) => response.json())
|
||||||
|
// .then((res: any) => {
|
||||||
|
// if (res.code === 200 || res.code === 0) {
|
||||||
|
// if (requestMethod.toLowerCase() != 'get' || successMsg) {
|
||||||
|
// if (!noMsg) {
|
||||||
|
// showToast(successMsg || '操作成功', 'success');
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return res.result;
|
||||||
|
// } else if (res.code === 401) {
|
||||||
|
// baseToken.value = null;
|
||||||
|
// showToast('登录已过期', 'error');
|
||||||
|
// } else {
|
||||||
|
// let msg = res.message;
|
||||||
|
// if (res.code === 402) {
|
||||||
|
// } else if (res.code === 403) {
|
||||||
|
// } else {
|
||||||
|
// }
|
||||||
|
// showToast(msg, 'error');
|
||||||
|
// }
|
||||||
|
|
||||||
|
// throw new Error(JSON.stringify(res));
|
||||||
|
// })
|
||||||
|
// .catch((err) => {
|
||||||
|
// console.error('fetch Error', err);
|
||||||
|
|
||||||
|
// throw err;
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
function filterEmpty(obj: any = {}): any {
|
||||||
|
const _obj: any = {};
|
||||||
|
for (const key in obj) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||||
|
const element = obj[key];
|
||||||
|
if (!(element === null || element === undefined || String(element).trim().length < 1)) {
|
||||||
|
_obj[key] = element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getQuery(iUrl: string, query: { [key: string]: string }): string {
|
||||||
|
if (!query) {
|
||||||
|
return iUrl;
|
||||||
|
}
|
||||||
|
const keys: string[] = [];
|
||||||
|
for (const key in query) {
|
||||||
|
keys.push(`${key}=${query[key]}`);
|
||||||
|
}
|
||||||
|
return `${iUrl}?${keys.join('&')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// type MsgType = 'error' | 'success' | 'loading' | 'info' | 'warning';
|
||||||
|
// function showToast(msg: string, type: MsgType) {
|
||||||
|
// message[type](msg);
|
||||||
|
// }
|
||||||
|
|
||||||
|
type CallbackObjs = {
|
||||||
|
loading: boolean;
|
||||||
|
callback: Function[][];
|
||||||
|
};
|
||||||
|
type Requests = {
|
||||||
|
userOpenid: CallbackObjs;
|
||||||
|
};
|
||||||
|
type RequestsName = keyof Requests;
|
||||||
|
const requests = reactive<Requests>({
|
||||||
|
userOpenid: {
|
||||||
|
loading: false,
|
||||||
|
callback: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 请求节流封装
|
||||||
|
* @param name 求节nameKey
|
||||||
|
* @param requestCallback
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getRequests(name: RequestsName, requestCallback: Function) {
|
||||||
|
// const requestInfo = requests[name];
|
||||||
|
//
|
||||||
|
if (requests[name].loading) {
|
||||||
|
return new Promise<[]>((resolve, reject) => {
|
||||||
|
requests[name].callback.push([resolve, reject]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
requests[name].loading = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await requestCallback();
|
||||||
|
requests[name].callback.forEach((callbacks) => {
|
||||||
|
const [resolve, reject] = callbacks;
|
||||||
|
!!resolve && resolve(data);
|
||||||
|
});
|
||||||
|
requests[name].loading = false;
|
||||||
|
requests[name].callback = [];
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
requests[name].callback.forEach((callbacks) => {
|
||||||
|
const [resolve, reject] = callbacks;
|
||||||
|
reject([]);
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
requests[name].loading = false;
|
||||||
|
requests[name].callback = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
24
reading-platform-frontend/src/apis/index.ts
Normal file
24
reading-platform-frontend/src/apis/index.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import apis from './apis';
|
||||||
|
type SwaggerInterface = apis;
|
||||||
|
|
||||||
|
export type UrlKey = keyof SwaggerInterface;
|
||||||
|
export type MethodKey<U extends UrlKey> = string & keyof SwaggerInterface[U];
|
||||||
|
|
||||||
|
type SwaggerInterfaceSingle<U extends UrlKey, M extends MethodKey<U>> = SwaggerInterface[U][M];
|
||||||
|
type SwaggerField<U extends UrlKey, M extends MethodKey<U>> = keyof SwaggerInterfaceSingle<U, M>;
|
||||||
|
type SwaggerFieldType<
|
||||||
|
U extends UrlKey,
|
||||||
|
M extends MethodKey<U>,
|
||||||
|
F extends SwaggerField<U, M>,
|
||||||
|
> = SwaggerInterfaceSingle<U, M>[F];
|
||||||
|
|
||||||
|
export type Param<U extends UrlKey, M extends MethodKey<U>> = SwaggerFieldType<
|
||||||
|
U,
|
||||||
|
M,
|
||||||
|
'param' & SwaggerField<U, M>
|
||||||
|
>;
|
||||||
|
export type Response<U extends UrlKey, M extends MethodKey<U>> = SwaggerFieldType<
|
||||||
|
U,
|
||||||
|
M,
|
||||||
|
'response' & SwaggerField<U, M>
|
||||||
|
>;
|
||||||
@ -1,29 +1,56 @@
|
|||||||
package com.reading.platform.entity;
|
package com.reading.platform.entity;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.*;
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 班级-教师关联实体
|
* 班级 - 教师关联实体
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("class_teachers")
|
@TableName("class_teachers")
|
||||||
|
@Schema(description = "班级教师关联")
|
||||||
public class ClassTeacher {
|
public class ClassTeacher {
|
||||||
|
|
||||||
@TableId(type = IdType.AUTO)
|
@Schema(description = "ID", accessMode = Schema.AccessMode.READ_ONLY)
|
||||||
private Long id;
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
private String id;
|
||||||
|
|
||||||
private Long classId;
|
private String classId;
|
||||||
|
|
||||||
private Long teacherId;
|
private String teacherId;
|
||||||
|
|
||||||
private String role;
|
private String role;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否主教
|
||||||
|
*/
|
||||||
|
private Boolean isPrimary;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序
|
||||||
|
*/
|
||||||
|
private Integer sortOrder;
|
||||||
|
|
||||||
|
@Schema(description = "创建人用户名", accessMode = Schema.AccessMode.READ_ONLY)
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private String createdBy;
|
||||||
|
|
||||||
|
@Schema(description = "更新人用户名", accessMode = Schema.AccessMode.READ_ONLY)
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private String updatedBy;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间", accessMode = Schema.AccessMode.READ_ONLY)
|
||||||
@TableField(fill = FieldFill.INSERT)
|
@TableField(fill = FieldFill.INSERT)
|
||||||
private LocalDateTime createdAt;
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
@Schema(description = "更新时间", accessMode = Schema.AccessMode.READ_ONLY)
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
|
||||||
|
@Schema(description = "逻辑删除标志", accessMode = Schema.AccessMode.READ_ONLY)
|
||||||
@TableLogic
|
@TableLogic
|
||||||
private Integer deleted;
|
private Integer deleted;
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,57 @@
|
|||||||
|
package com.reading.platform.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 班级-教师关联实体
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("class_teachers")
|
||||||
|
@Schema(description = "班级教师关联")
|
||||||
|
public class ClassTeacher {
|
||||||
|
|
||||||
|
@Schema(description = "ID", accessMode = Schema.AccessMode.READ_ONLY)
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String classId;
|
||||||
|
|
||||||
|
private String teacherId;
|
||||||
|
|
||||||
|
private String role;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否主教
|
||||||
|
*/
|
||||||
|
private Boolean isPrimary;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序
|
||||||
|
*/
|
||||||
|
private Integer sortOrder;
|
||||||
|
|
||||||
|
@Schema(description = "创建人用户名", accessMode = Schema.AccessMode.READ_ONLY)
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private String createdBy;
|
||||||
|
|
||||||
|
@Schema(description = "更新人用户名", accessMode = Schema.AccessMode.READ_ONLY)
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private String updatedBy;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间", accessMode = Schema.AccessMode.READ_ONLY)
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
@Schema(description = "更新时间", accessMode = Schema.AccessMode.READ_ONLY)
|
||||||
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
|
||||||
|
@Schema(description = "逻辑删除标志", accessMode = Schema.AccessMode.READ_ONLY)
|
||||||
|
@TableLogic
|
||||||
|
private Integer deleted;
|
||||||
|
|
||||||
|
}
|
||||||
346
前端实际调用接口对比.md
346
前端实际调用接口对比.md
@ -1,346 +0,0 @@
|
|||||||
# 前端实际调用但 Java 后端缺失的接口
|
|
||||||
|
|
||||||
## 分析方法
|
|
||||||
- 对比 `reading-platform-frontend/src/api/generated/api.ts` 中的实际调用
|
|
||||||
- 检查 `reading-platform-java/src/main/java/com/reading/platform/controller` 中的实现
|
|
||||||
- 只列出前端实际调用但 Java 后端缺失的接口
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ 已实现的接口列表
|
|
||||||
|
|
||||||
### 1. 认证接口 (AuthController)
|
|
||||||
- ✅ `POST /api/v1/auth/login` - 登录
|
|
||||||
- ✅ `POST /api/v1/auth/logout` - 登出
|
|
||||||
- ✅ `POST /api/v1/auth/change-password` - 修改密码
|
|
||||||
- ✅ `GET /api/v1/auth/me` - 获取当前用户信息
|
|
||||||
|
|
||||||
### 2. 文件接口 (FileUploadController)
|
|
||||||
- ✅ `POST /api/v1/files/upload` - 上传文件
|
|
||||||
- ✅ `DELETE /api/v1/files/delete` - 删除文件
|
|
||||||
|
|
||||||
### 3. 教师端 - 任务 (TeacherTaskController)
|
|
||||||
- ✅ `GET /api/v1/teacher/tasks` - 获取任务分页
|
|
||||||
- ✅ `POST /api/v1/teacher/tasks` - 创建任务
|
|
||||||
- ✅ `GET /api/v1/teacher/tasks/{id}` - 根据 ID 获取任务
|
|
||||||
- ✅ `PUT /api/v1/teacher/tasks/{id}` - 更新任务
|
|
||||||
- ✅ `DELETE /api/v1/teacher/tasks/{id}` - 删除任务
|
|
||||||
|
|
||||||
### 4. 教师端 - 课时 (TeacherLessonController)
|
|
||||||
- ✅ `GET /api/v1/teacher/lessons` - 获取课时分页
|
|
||||||
- ✅ `POST /api/v1/teacher/lessons` - 创建课时
|
|
||||||
- ✅ `GET /api/v1/teacher/lessons/{id}` - 根据 ID 获取课时
|
|
||||||
- ✅ `PUT /api/v1/teacher/lessons/{id}` - 更新课时
|
|
||||||
- ✅ `POST /api/v1/teacher/lessons/{id}/start` - 开始课时
|
|
||||||
- ✅ `POST /api/v1/teacher/lessons/{id}/complete` - 完成课时
|
|
||||||
- ✅ `POST /api/v1/teacher/lessons/{id}/cancel` - 取消课时
|
|
||||||
- ✅ `GET /api/v1/teacher/lessons/today` - 获取今天课时
|
|
||||||
|
|
||||||
### 5. 教师端 - 成长档案 (TeacherGrowthController)
|
|
||||||
- ✅ `GET /api/v1/teacher/growth-records` - 获取成长档案分页
|
|
||||||
- ✅ `POST /api/v1/teacher/growth-records` - 创建成长档案
|
|
||||||
- ✅ `GET /api/v1/teacher/growth-records/{id}` - 根据 ID 获取成长档案
|
|
||||||
- ✅ `PUT /api/v1/teacher/growth-records/{id}` - 更新成长档案
|
|
||||||
- ✅ `DELETE /api/v1/teacher/growth-records/{id}` - 删除成长档案
|
|
||||||
|
|
||||||
### 6. 教师端 - 通知 (TeacherNotificationController)
|
|
||||||
- ✅ `GET /api/v1/teacher/notifications` - 获取通知分页
|
|
||||||
- ✅ `GET /api/v1/teacher/notifications/{id}` - 根据 ID 获取通知
|
|
||||||
- ✅ `GET /api/v1/teacher/notifications/unread-count` - 获取未读数量
|
|
||||||
- ✅ `POST /api/v1/teacher/notifications/{id}/read` - 标记已读
|
|
||||||
- ✅ `POST /api/v1/teacher/notifications/read-all` - 全部标记已读
|
|
||||||
|
|
||||||
### 7. 教师端 - 课程 (TeacherCourseController)
|
|
||||||
- ✅ `GET /api/v1/teacher/courses` - 获取课程分页
|
|
||||||
- ✅ `GET /api/v1/teacher/courses/{id}` - 根据 ID 获取课程
|
|
||||||
- ✅ `GET /api/v1/teacher/courses/all` - 获取所有课程
|
|
||||||
|
|
||||||
### 8. 教师端 - 课程课时 (TeacherCourseLessonController)
|
|
||||||
- ✅ `GET /api/v1/teacher/courses/{courseId}/lessons` - 获取课程课时列表
|
|
||||||
- ✅ `GET /api/v1/teacher/courses/{courseId}/lessons/{id}` - 根据 ID 获取课时
|
|
||||||
|
|
||||||
### 9. 教师端 - 校本课程 (TeacherSchoolCourseController)
|
|
||||||
- ✅ `GET /api/v1/teacher/school-courses` - 获取校本课程分页
|
|
||||||
- ✅ `GET /api/v1/teacher/school-courses/{id}` - 根据 ID 获取校本课程
|
|
||||||
|
|
||||||
### 10. 教师端 - 课表 (TeacherScheduleController)
|
|
||||||
- ✅ `GET /api/v1/teacher/schedules` - 获取课表计划分页
|
|
||||||
- ✅ `GET /api/v1/teacher/schedules/{id}` - 根据 ID 获取课表计划
|
|
||||||
|
|
||||||
### 11. 教师端 - 仪表板 (TeacherDashboardController)
|
|
||||||
- ✅ `GET /api/v1/teacher/dashboard` - 获取仪表板数据
|
|
||||||
- ✅ `GET /api/v1/teacher/dashboard/weekly` - 获取周统计
|
|
||||||
- ✅ `GET /api/v1/teacher/dashboard/today` - 获取今天数据
|
|
||||||
|
|
||||||
### 12. 学校管理员 - 教师 (SchoolTeacherController)
|
|
||||||
- ✅ `GET /api/v1/school/teachers` - 获取教师分页
|
|
||||||
- ✅ `POST /api/v1/school/teachers` - 创建教师
|
|
||||||
- ✅ `GET /api/v1/school/teachers/{id}` - 根据 ID 获取教师
|
|
||||||
- ✅ `PUT /api/v1/school/teachers/{id}` - 更新教师
|
|
||||||
- ✅ `DELETE /api/v1/school/teachers/{id}` - 删除教师
|
|
||||||
- ✅ `POST /api/v1/school/teachers/{id}/reset-password` - 重置密码
|
|
||||||
|
|
||||||
### 13. 学校管理员 - 任务 (SchoolTaskController)
|
|
||||||
- ✅ `GET /api/v1/school/tasks` - 获取任务分页
|
|
||||||
- ✅ `POST /api/v1/school/tasks` - 创建任务
|
|
||||||
- ✅ `GET /api/v1/school/tasks/{id}` - 根据 ID 获取任务
|
|
||||||
- ✅ `PUT /api/v1/school/tasks/{id}` - 更新任务
|
|
||||||
- ✅ `DELETE /api/v1/school/tasks/{id}` - 删除任务
|
|
||||||
|
|
||||||
### 14. 学校管理员 - 学生 (SchoolStudentController)
|
|
||||||
- ✅ `GET /api/v1/school/students` - 获取学生分页
|
|
||||||
- ✅ `POST /api/v1/school/students` - 创建学生
|
|
||||||
- ✅ `GET /api/v1/school/students/{id}` - 根据 ID 获取学生
|
|
||||||
- ✅ `PUT /api/v1/school/students/{id}` - 更新学生
|
|
||||||
- ✅ `DELETE /api/v1/school/students/{id}` - 删除学生
|
|
||||||
|
|
||||||
### 15. 学校管理员 - 校本课程 (SchoolCourseController)
|
|
||||||
- ✅ `GET /api/v1/school/school-courses` - 获取校本课程分页
|
|
||||||
- ✅ `POST /api/v1/school/school-courses` - 创建校本课程
|
|
||||||
- ✅ `GET /api/v1/school/school-courses/{id}` - 根据 ID 获取校本课程
|
|
||||||
- ✅ `PUT /api/v1/school/school-courses/{id}` - 更新校本课程
|
|
||||||
- ✅ `DELETE /api/v1/school/school-courses/{id}` - 删除校本课程
|
|
||||||
|
|
||||||
### 16. 学校管理员 - 课表 (SchoolScheduleController)
|
|
||||||
- ✅ `GET /api/v1/school/schedules` - 获取课表计划分页
|
|
||||||
- ✅ `POST /api/v1/school/schedules` - 创建课表计划
|
|
||||||
- ✅ `GET /api/v1/school/schedules/{id}` - 根据 ID 获取课表计划
|
|
||||||
- ✅ `PUT /api/v1/school/schedules/{id}` - 更新课表计划
|
|
||||||
- ✅ `DELETE /api/v1/school/schedules/{id}` - 删除课表计划
|
|
||||||
- ✅ `GET /api/v1/school/schedules/templates` - 获取课表模板分页
|
|
||||||
- ✅ `POST /api/v1/school/schedules/templates` - 创建课表模板
|
|
||||||
- ✅ `GET /api/v1/school/schedules/templates/{id}` - 根据 ID 获取课表模板
|
|
||||||
- ✅ `PUT /api/v1/school/schedules/templates/{id}` - 更新课表模板
|
|
||||||
- ✅ `DELETE /api/v1/school/schedules/templates/{id}` - 删除课表模板
|
|
||||||
- ✅ `POST /api/v1/school/schedules/templates/{id}/apply` - 应用课表模板
|
|
||||||
|
|
||||||
### 17. 学校管理员 - 家长 (SchoolParentController)
|
|
||||||
- ✅ `GET /api/v1/school/parents` - 获取家长分页
|
|
||||||
- ✅ `POST /api/v1/school/parents` - 创建家长
|
|
||||||
- ✅ `GET /api/v1/school/parents/{id}` - 根据 ID 获取家长
|
|
||||||
- ✅ `PUT /api/v1/school/parents/{id}` - 更新家长
|
|
||||||
- ✅ `DELETE /api/v1/school/parents/{id}` - 删除家长
|
|
||||||
- ✅ `POST /api/v1/school/parents/{id}/reset-password` - 重置密码
|
|
||||||
- ✅ `POST /api/v1/school/parents/{parentId}/students/{studentId}` - 绑定学生
|
|
||||||
- ✅ `DELETE /api/v1/school/parents/{parentId}/students/{studentId}` - 解绑学生
|
|
||||||
|
|
||||||
### 18. 学校管理员 - 成长档案 (SchoolGrowthController)
|
|
||||||
- ✅ `GET /api/v1/school/growth-records` - 获取成长档案分页
|
|
||||||
- ✅ `POST /api/v1/school/growth-records` - 创建成长档案
|
|
||||||
- ✅ `GET /api/v1/school/growth-records/{id}` - 根据 ID 获取成长档案
|
|
||||||
- ✅ `PUT /api/v1/school/growth-records/{id}` - 更新成长档案
|
|
||||||
- ✅ `DELETE /api/v1/school/growth-records/{id}` - 删除成长档案
|
|
||||||
|
|
||||||
### 19. 学校管理员 - 班级 (SchoolClassController)
|
|
||||||
- ✅ `GET /api/v1/school/classes` - 获取班级分页
|
|
||||||
- ✅ `POST /api/v1/school/classes` - 创建班级
|
|
||||||
- ✅ `GET /api/v1/school/classes/{id}` - 根据 ID 获取班级
|
|
||||||
- ✅ `PUT /api/v1/school/classes/{id}` - 更新班级
|
|
||||||
- ✅ `DELETE /api/v1/school/classes/{id}` - 删除班级
|
|
||||||
- ✅ `POST /api/v1/school/classes/{id}/teachers` - 分配教师到班级
|
|
||||||
- ✅ `POST /api/v1/school/classes/{id}/students` - 分配学生到班级
|
|
||||||
|
|
||||||
### 20. 学校管理员 - 通知 (SchoolNotificationController)
|
|
||||||
- ✅ `GET /api/v1/school/notifications` - 获取通知分页
|
|
||||||
- ✅ `GET /api/v1/school/notifications/{id}` - 根据 ID 获取通知
|
|
||||||
- ✅ `GET /api/v1/school/notifications/unread-count` - 获取未读数量
|
|
||||||
- ✅ `POST /api/v1/school/notifications/{id}/read` - 标记已读
|
|
||||||
- ✅ `POST /api/v1/school/notifications/read-all` - 全部标记已读
|
|
||||||
|
|
||||||
### 21. 学校管理员 - 统计 (SchoolStatsController)
|
|
||||||
- ✅ `GET /api/v1/school/stats` - 获取统计数据
|
|
||||||
|
|
||||||
### 22. 学校管理员 - 操作日志 (SchoolOperationLogController)
|
|
||||||
- ✅ `GET /api/v1/school/operation-logs` - 获取操作日志分页
|
|
||||||
|
|
||||||
### 23. 学校管理员 - 导出 (SchoolExportController)
|
|
||||||
- ✅ `GET /api/v1/school/export/teachers` - 导出教师数据
|
|
||||||
- ✅ `GET /api/v1/school/export/students` - 导出学生数据
|
|
||||||
- ✅ `GET /api/v1/school/export/lessons` - 导出课时数据
|
|
||||||
- ✅ `GET /api/v1/school/export/growth-records` - 导出成长档案
|
|
||||||
|
|
||||||
### 24. 学校管理员 - 课程包 (SchoolCoursePackageController)
|
|
||||||
- ✅ `GET /api/v1/school/course-packages` - 获取课程包分页
|
|
||||||
- ✅ `GET /api/v1/school/course-packages/{id}` - 根据 ID 获取课程包
|
|
||||||
|
|
||||||
### 25. 家长端 - 孩子 (ParentChildController)
|
|
||||||
- ✅ `GET /api/v1/parent/children` - 获取我的孩子
|
|
||||||
- ✅ `GET /api/v1/parent/children/{id}` - 根据 ID 获取孩子
|
|
||||||
|
|
||||||
### 26. 家长端 - 任务 (ParentTaskController)
|
|
||||||
- ✅ `GET /api/v1/parent/tasks/{id}` - 根据 ID 获取任务
|
|
||||||
- ✅ `GET /api/v1/parent/tasks/student/{studentId}` - 根据学生 ID 获取任务
|
|
||||||
- ✅ `POST /api/v1/parent/tasks/{taskId}/complete` - 完成任务
|
|
||||||
|
|
||||||
### 27. 家长端 - 通知 (ParentNotificationController)
|
|
||||||
- ✅ `GET /api/v1/parent/notifications` - 获取通知分页
|
|
||||||
- ✅ `GET /api/v1/parent/notifications/{id}` - 根据 ID 获取通知
|
|
||||||
- ✅ `GET /api/v1/parent/notifications/unread-count` - 获取未读数量
|
|
||||||
- ✅ `POST /api/v1/parent/notifications/{id}/read` - 标记已读
|
|
||||||
- ✅ `POST /api/v1/parent/notifications/read-all` - 全部标记已读
|
|
||||||
|
|
||||||
### 28. 家长端 - 成长档案 (ParentGrowthController)
|
|
||||||
- ✅ `GET /api/v1/parent/growth-records` - 获取成长档案分页
|
|
||||||
- ✅ `POST /api/v1/parent/growth-records` - 创建成长档案
|
|
||||||
- ✅ `GET /api/v1/parent/growth-records/{id}` - 根据 ID 获取成长档案
|
|
||||||
- ✅ `PUT /api/v1/parent/growth-records/{id}` - 更新成长档案
|
|
||||||
- ✅ `DELETE /api/v1/parent/growth-records/{id}` - 删除成长档案
|
|
||||||
- ✅ `GET /api/v1/parent/growth-records/student/{studentId}` - 根据学生 ID 获取成长档案
|
|
||||||
- ✅ `GET /api/v1/parent/growth-records/student/{studentId}/recent` - 获取最近成长档案
|
|
||||||
|
|
||||||
### 29. 管理员端 - 租户 (AdminTenantController)
|
|
||||||
- ✅ `GET /api/v1/admin/tenants` - 获取租户分页
|
|
||||||
- ✅ `POST /api/v1/admin/tenants` - 创建租户
|
|
||||||
- ✅ `GET /api/v1/admin/tenants/{id}` - 根据 ID 获取租户
|
|
||||||
- ✅ `PUT /api/v1/admin/tenants/{id}` - 更新租户
|
|
||||||
- ✅ `DELETE /api/v1/admin/tenants/{id}` - 删除租户
|
|
||||||
- ✅ `GET /api/v1/admin/tenants/active` - 获取活跃租户
|
|
||||||
- ✅ `PUT /api/v1/admin/tenants/{id}/status` - 更新租户状态
|
|
||||||
- ✅ `PUT /api/v1/admin/tenants/{id}/quota` - 更新租户配额
|
|
||||||
- ✅ `POST /api/v1/admin/tenants/{id}/reset-password` - 重置密码
|
|
||||||
|
|
||||||
### 30. 管理员端 - 主题 (AdminThemeController)
|
|
||||||
- ✅ `GET /api/v1/admin/themes` - 获取主题分页
|
|
||||||
- ✅ `POST /api/v1/admin/themes` - 创建主题
|
|
||||||
- ✅ `GET /api/v1/admin/themes/{id}` - 根据 ID 获取主题
|
|
||||||
- ✅ `PUT /api/v1/admin/themes/{id}` - 更新主题
|
|
||||||
- ✅ `DELETE /api/v1/admin/themes/{id}` - 删除主题
|
|
||||||
|
|
||||||
### 31. 管理员端 - 资源 (AdminResourceController)
|
|
||||||
- ✅ `GET /api/v1/admin/resources/libraries` - 获取资源库分页
|
|
||||||
- ✅ `POST /api/v1/admin/resources/libraries` - 创建资源库
|
|
||||||
- ✅ `GET /api/v1/admin/resources/libraries/{id}` - 根据 ID 获取资源库
|
|
||||||
- ✅ `PUT /api/v1/admin/resources/libraries/{id}` - 更新资源库
|
|
||||||
- ✅ `DELETE /api/v1/admin/resources/libraries/{id}` - 删除资源库
|
|
||||||
- ✅ `GET /api/v1/admin/resources/items` - 获取资源项分页
|
|
||||||
- ✅ `POST /api/v1/admin/resources/items` - 创建资源项
|
|
||||||
- ✅ `GET /api/v1/admin/resources/items/{id}` - 根据 ID 获取资源项
|
|
||||||
- ✅ `PUT /api/v1/admin/resources/items/{id}` - 更新资源项
|
|
||||||
- ✅ `DELETE /api/v1/admin/resources/items/{id}` - 删除资源项
|
|
||||||
|
|
||||||
### 32. 管理员端 - 课程包 (AdminCoursePackageController)
|
|
||||||
- ✅ `GET /api/v1/admin/packages` - 获取课程包分页
|
|
||||||
- ✅ `POST /api/v1/admin/packages` - 创建课程包
|
|
||||||
- ✅ `GET /api/v1/admin/packages/{id}` - 根据 ID 获取课程包
|
|
||||||
- ✅ `PUT /api/v1/admin/packages/{id}` - 更新课程包
|
|
||||||
- ✅ `DELETE /api/v1/admin/packages/{id}` - 删除课程包
|
|
||||||
- ✅ `POST /api/v1/admin/packages/{id}/submit` - 提交审核
|
|
||||||
- ✅ `POST /api/v1/admin/packages/{id}/review` - 审核
|
|
||||||
- ✅ `POST /api/v1/admin/packages/{id}/publish` - 发布
|
|
||||||
- ✅ `POST /api/v1/admin/packages/{id}/offline` - 下架
|
|
||||||
|
|
||||||
### 33. 管理员端 - 课程 (AdminCourseController)
|
|
||||||
- ✅ `GET /api/v1/admin/courses` - 获取课程分页
|
|
||||||
- ✅ `POST /api/v1/admin/courses` - 创建课程
|
|
||||||
- ✅ `GET /api/v1/admin/courses/{id}` - 根据 ID 获取课程
|
|
||||||
- ✅ `PUT /api/v1/admin/courses/{id}` - 更新课程
|
|
||||||
- ✅ `DELETE /api/v1/admin/courses/{id}` - 删除课程
|
|
||||||
- ✅ `GET /api/v1/admin/courses/review` - 获取待审核课程
|
|
||||||
- ✅ `POST /api/v1/admin/courses/{id}/submit` - 提交审核
|
|
||||||
- ✅ `POST /api/v1/admin/courses/{id}/approve` - 审核通过
|
|
||||||
- ✅ `POST /api/v1/admin/courses/{id}/reject` - 审核驳回
|
|
||||||
- ✅ `POST /api/v1/admin/courses/{id}/publish` - 发布
|
|
||||||
- ✅ `POST /api/v1/admin/courses/{id}/direct-publish` - 直接发布
|
|
||||||
- ✅ `POST /api/v1/admin/courses/{id}/withdraw` - 撤销审核
|
|
||||||
- ✅ `POST /api/v1/admin/courses/{id}/unpublish` - 下架
|
|
||||||
- ✅ `POST /api/v1/admin/courses/{id}/republish` - 重新发布
|
|
||||||
- ✅ `POST /api/v1/admin/courses/{id}/archive` - 归档
|
|
||||||
|
|
||||||
### 34. 管理员端 - 课程课时 (AdminCourseLessonController)
|
|
||||||
- ✅ `GET /api/v1/admin/courses/{courseId}/lessons` - 获取课程课时列表
|
|
||||||
- ✅ `POST /api/v1/admin/courses/{courseId}/lessons` - 创建课程课时
|
|
||||||
- ✅ `GET /api/v1/admin/courses/{courseId}/lessons/{id}` - 根据 ID 获取课时
|
|
||||||
- ✅ `PUT /api/v1/admin/courses/{courseId}/lessons/{id}` - 更新课程课时
|
|
||||||
- ✅ `DELETE /api/v1/admin/courses/{courseId}/lessons/{id}` - 删除课程课时
|
|
||||||
|
|
||||||
### 35. 管理员端 - 统计 (AdminStatsController)
|
|
||||||
- ✅ `GET /api/v1/admin/stats` - 获取整体统计数据
|
|
||||||
- ✅ `GET /api/v1/admin/stats/trend` - 获取趋势数据
|
|
||||||
- ✅ `GET /api/v1/admin/stats/tenants/active` - 获取活跃租户
|
|
||||||
- ✅ `GET /api/v1/admin/stats/courses/popular` - 获取热门课程
|
|
||||||
- ✅ `GET /api/v1/admin/stats/activities` - 获取最近活动
|
|
||||||
|
|
||||||
### 36. 管理员端 - 操作日志 (AdminOperationLogController)
|
|
||||||
- ✅ `GET /api/v1/admin/operation-logs` - 获取操作日志分页
|
|
||||||
|
|
||||||
### 37. 管理员端 - 设置 (AdminSettingsController)
|
|
||||||
- ✅ `GET /api/v1/admin/settings` - 获取系统设置
|
|
||||||
- ✅ `PUT /api/v1/admin/settings` - 更新系统设置
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ❌ 缺失接口列表
|
|
||||||
|
|
||||||
### 1. 学校管理员端 - 班级 (SchoolClassController)
|
|
||||||
|
|
||||||
前端调用但 Java 后端缺失:
|
|
||||||
- ❌ `DELETE /api/v1/school/classes/{id}/teachers/{teacherId}` - 移除班级教师
|
|
||||||
- ❌ `DELETE /api/v1/school/classes/{id}/students/{studentId}` - 移除班级学生
|
|
||||||
|
|
||||||
Java 后端已有:
|
|
||||||
- ✅ `POST /api/v1/school/classes/{id}/teachers` - 分配教师到班级
|
|
||||||
- ✅ `POST /api/v1/school/classes/{id}/students` - 分配学生到班级
|
|
||||||
|
|
||||||
### 2. 学校管理员端 - 学生 (SchoolStudentController)
|
|
||||||
|
|
||||||
前端调用但 Java 后端缺失:
|
|
||||||
- ❌ `POST /api/v1/school/students/import` - 批量导入学生
|
|
||||||
- ❌ `GET /api/v1/school/students/import/template` - 获取导入模板
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 总结
|
|
||||||
|
|
||||||
绝大部分接口已经在 Java 后端实现,仅剩以下缺失接口需要补全:
|
|
||||||
|
|
||||||
### P0 - 核心功能缺失(必须补全)
|
|
||||||
暂无
|
|
||||||
|
|
||||||
### P1 - 重要功能缺失
|
|
||||||
暂无
|
|
||||||
|
|
||||||
### P2 - 辅助功能缺失
|
|
||||||
暂无
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 本次补全的接口
|
|
||||||
|
|
||||||
### 1. 学校管理员端 - 班级 (SchoolClassController)
|
|
||||||
新增接口:
|
|
||||||
- ✅ `DELETE /api/v1/school/classes/{id}/teachers/{teacherId}` - 移除班级教师
|
|
||||||
- ✅ `DELETE /api/v1/school/classes/{id}/students/{studentId}` - 移除班级学生
|
|
||||||
|
|
||||||
新增 Service 方法 (ClassService):
|
|
||||||
- `void removeTeacher(Long classId, Long teacherId)`
|
|
||||||
- `void removeStudent(Long classId, Long studentId)`
|
|
||||||
|
|
||||||
### 2. 学校管理员端 - 学生 (SchoolStudentController)
|
|
||||||
新增接口:
|
|
||||||
- ✅ `POST /api/v1/school/students/import` - 批量导入学生
|
|
||||||
- ✅ `GET /api/v1/school/students/import/template` - 获取导入模板
|
|
||||||
|
|
||||||
新增 Service 方法 (StudentService):
|
|
||||||
- `List<Student> importStudents(Long tenantId, List<StudentCreateRequest> requests)`
|
|
||||||
|
|
||||||
### 3. 学校统计接口 (SchoolStatsController + SchoolStatsService)
|
|
||||||
新增接口:
|
|
||||||
- ✅ `GET /api/v1/school/stats/teachers` - 获取活跃教师统计
|
|
||||||
- ✅ `GET /api/v1/school/stats/courses` - 获取课程使用统计
|
|
||||||
- ✅ `GET /api/v1/school/stats/activities` - 获取最近活动记录
|
|
||||||
- ✅ `GET /api/v1/school/stats/lesson-trend` - 获取课时趋势(最近 N 个月)
|
|
||||||
- ✅ `GET /api/v1/school/stats/course-distribution` - 获取课程分布统计(饼图数据)
|
|
||||||
|
|
||||||
新增 Service 方法 (SchoolStatsService):
|
|
||||||
- `List<Map<String, Object>> getActiveTeachers(Long tenantId, Integer limit)`
|
|
||||||
- `List<Map<String, Object>> getCourseUsageStats(Long tenantId)`
|
|
||||||
- `List<Map<String, Object>> getRecentActivities(Long tenantId, Integer limit)`
|
|
||||||
- `List<Map<String, Object>> getLessonTrend(Long tenantId, Integer months)`
|
|
||||||
- `List<Map<String, Object>> getCourseDistribution(Long tenantId)`
|
|
||||||
- `String formatActivityTitle(Lesson lesson)` - 私有方法,格式化活动标题
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 最终结论
|
|
||||||
|
|
||||||
**前端实际调用的所有接口已在 Java 后端全部实现。**
|
|
||||||
228
补全接口修复总结.md
228
补全接口修复总结.md
@ -1,228 +0,0 @@
|
|||||||
# API 接口补全修复总结
|
|
||||||
|
|
||||||
## 修复日期
|
|
||||||
2026-03-09
|
|
||||||
|
|
||||||
## 问题修复
|
|
||||||
|
|
||||||
### Bug 修复
|
|
||||||
修复了 `TaskServiceImpl.java` 中使用 `ClassEntity` 的错误,改为使用 `Clazz`(因为 `class` 是 Java 关键字,项目中使用 `Clazz` 作为班级实体名称)。
|
|
||||||
|
|
||||||
**修改位置**: `reading-platform-java/src/main/java/com/reading/platform/service/impl/TaskServiceImpl.java`
|
|
||||||
- 第 284 行:`List<ClassEntity> classes` → `List<Clazz> classes`
|
|
||||||
- 第 288 行:`for (ClassEntity cls : classes)` → `for (Clazz cls : classes)`
|
|
||||||
|
|
||||||
### 数据库迁移
|
|
||||||
新增数据库迁移脚本 `V7__fix_schedule_plans.sql`,为 `schedule_plans` 表添加以下字段:
|
|
||||||
- `course_id` - 课程 ID
|
|
||||||
- `teacher_id` - 教师 ID
|
|
||||||
- `day_of_week` - 星期几 (1-7)
|
|
||||||
- `period` - 节次
|
|
||||||
- `start_time` - 开始时间
|
|
||||||
- `end_time` - 结束时间
|
|
||||||
- `location` - 教室/地点
|
|
||||||
- `note` - 备注
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 已补全的 API 接口
|
|
||||||
|
|
||||||
### 1. 任务管理接口
|
|
||||||
|
|
||||||
#### 新增 Service 方法 (TaskService)
|
|
||||||
```java
|
|
||||||
// 任务统计
|
|
||||||
Map<String, Object> getTaskStats(Long tenantId);
|
|
||||||
Map<String, Object> getStatsByType(Long tenantId);
|
|
||||||
List<Map<String, Object>> getStatsByClass(Long tenantId);
|
|
||||||
List<Map<String, Object>> getMonthlyStats(Long tenantId, Integer months);
|
|
||||||
|
|
||||||
// 任务完成情况
|
|
||||||
Page<TaskCompletion> getTaskCompletions(Long tenantId, Long taskId, Integer pageNum, Integer pageSize, String status);
|
|
||||||
TaskCompletion updateTaskCompletion(Long tenantId, Long taskId, Long studentId, String status, String feedback);
|
|
||||||
|
|
||||||
// 任务模板
|
|
||||||
Page<TaskTemplate> getTemplatePage(Long tenantId, Integer pageNum, Integer pageSize, String keyword, String type);
|
|
||||||
TaskTemplate getTemplateById(Long tenantId, Long id);
|
|
||||||
TaskTemplate getDefaultTemplate(Long tenantId, String taskType);
|
|
||||||
TaskTemplate createTemplate(Long tenantId, Long creatorId, TaskTemplateCreateRequest request);
|
|
||||||
TaskTemplate updateTemplate(Long tenantId, Long id, TaskTemplateUpdateRequest request);
|
|
||||||
void deleteTemplate(Long tenantId, Long id);
|
|
||||||
Task createTaskFromTemplate(Long tenantId, Long creatorId, String creatorRole, CreateTaskFromTemplateRequest request);
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 新增 Controller 端点
|
|
||||||
|
|
||||||
**SchoolTaskController** (学校管理员 - 任务管理):
|
|
||||||
- `GET /api/v1/school/tasks/stats` - 获取任务统计数据
|
|
||||||
- `GET /api/v1/school/tasks/stats/by-type` - 按任务类型统计
|
|
||||||
- `GET /api/v1/school/tasks/stats/by-class` - 按班级统计
|
|
||||||
- `GET /api/v1/school/tasks/stats/monthly` - 月度统计趋势
|
|
||||||
- `GET /api/v1/school/tasks/:id/completions` - 获取任务完成情况分页
|
|
||||||
- `PUT /api/v1/school/tasks/:taskId/completions/:studentId` - 更新任务完成状态
|
|
||||||
- `GET /api/v1/school/task-templates` - 获取任务模板列表
|
|
||||||
- `GET /api/v1/school/task-templates/:id` - 获取单个模板
|
|
||||||
- `GET /api/v1/school/task-templates/default/:taskType` - 获取默认模板
|
|
||||||
- `POST /api/v1/school/task-templates` - 创建任务模板
|
|
||||||
- `PUT /api/v1/school/task-templates/:id` - 更新任务模板
|
|
||||||
- `DELETE /api/v1/school/task-templates/:id` - 删除任务模板
|
|
||||||
- `POST /api/v1/school/tasks/from-template` - 从模板创建任务
|
|
||||||
|
|
||||||
**TeacherTaskController** (教师端 - 任务管理):
|
|
||||||
- `GET /api/v1/teacher/tasks/stats` - 获取任务统计数据
|
|
||||||
- `GET /api/v1/teacher/tasks/stats/by-type` - 按任务类型统计
|
|
||||||
- `GET /api/v1/teacher/tasks/stats/by-class` - 按班级统计
|
|
||||||
- `GET /api/v1/teacher/tasks/stats/monthly` - 月度统计趋势
|
|
||||||
- `GET /api/v1/teacher/tasks/:id/completions` - 获取任务完成情况分页
|
|
||||||
- `PUT /api/v1/teacher/tasks/:taskId/completions/:studentId` - 更新任务完成状态
|
|
||||||
- `GET /api/v1/teacher/task-templates` - 获取任务模板列表
|
|
||||||
- `GET /api/v1/teacher/task-templates/:id` - 获取单个模板
|
|
||||||
- `GET /api/v1/teacher/task-templates/default/:taskType` - 获取默认模板
|
|
||||||
- `POST /api/v1/teacher/tasks/from-template` - 从模板创建任务
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. 通知接口
|
|
||||||
|
|
||||||
**新增 SchoolNotificationController** (学校管理员 - 通知):
|
|
||||||
- `GET /api/v1/school/notifications` - 获取通知列表
|
|
||||||
- `GET /api/v1/school/notifications/:id` - 根据 ID 获取通知
|
|
||||||
- `GET /api/v1/school/notifications/unread-count` - 获取未读数量
|
|
||||||
- `POST /api/v1/school/notifications/:id/read` - 标记已读
|
|
||||||
- `POST /api/v1/school/notifications/read-all` - 全部标记已读
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. 排课和课表接口
|
|
||||||
|
|
||||||
#### 新增 Service 方法 (ScheduleService)
|
|
||||||
```java
|
|
||||||
Page<SchedulePlan> getSchedulePlans(int pageNum, int pageSize, Long tenantId, Long classId, LocalDate startDate, LocalDate endDate);
|
|
||||||
List<Map<String, Object>> getTimetable(Long tenantId, LocalDate startDate, LocalDate endDate, Long classId);
|
|
||||||
List<SchedulePlan> batchCreateSchedules(Long tenantId, Long userId, List<SchedulePlanCreateRequest> requests);
|
|
||||||
ScheduleTemplate updateScheduleTemplate(Long id, ScheduleTemplate template);
|
|
||||||
List<SchedulePlan> applyScheduleTemplate(Long tenantId, Long templateId, ScheduleTemplateApplyRequest request);
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 新增 Controller 端点 (SchoolScheduleController)
|
|
||||||
- `GET /api/v1/school/schedules/timetable` - 获取课表(带日期范围)
|
|
||||||
- `POST /api/v1/school/schedules/batch` - 批量创建排课
|
|
||||||
- `GET /api/v1/school/schedules/templates/:id` - 获取单个模板
|
|
||||||
- `PUT /api/v1/school/schedules/templates/:id` - 更新模板
|
|
||||||
- `POST /api/v1/school/schedules/templates/:id/apply` - 应用模板
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4. 实体类增强
|
|
||||||
|
|
||||||
**SchedulePlan** (新增字段):
|
|
||||||
- `courseId` - 课程 ID
|
|
||||||
- `teacherId` - 教师 ID
|
|
||||||
- `dayOfWeek` - 星期几 (1-7)
|
|
||||||
- `period` - 节次
|
|
||||||
- `startTime` - 开始时间
|
|
||||||
- `endTime` - 结束时间
|
|
||||||
- `location` - 教室/地点
|
|
||||||
- `note` - 备注
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 5. 新增 DTO
|
|
||||||
|
|
||||||
**TaskTemplateCreateRequest** - 任务模板创建请求
|
|
||||||
```java
|
|
||||||
- name: 模板名称
|
|
||||||
- description: 模板描述
|
|
||||||
- type: 任务类型
|
|
||||||
- content: 任务内容模板
|
|
||||||
- isPublic: 是否公共模板
|
|
||||||
```
|
|
||||||
|
|
||||||
**TaskTemplateUpdateRequest** - 任务模板更新请求
|
|
||||||
|
|
||||||
**CreateTaskFromTemplateRequest** - 从模板创建任务请求
|
|
||||||
```java
|
|
||||||
- templateId: 模板 ID
|
|
||||||
- targetIds: 目标 ID 列表
|
|
||||||
- targetType: 目标类型 (CLASS/STUDENT)
|
|
||||||
- startDate: 开始日期
|
|
||||||
- endDate: 截止日期
|
|
||||||
```
|
|
||||||
|
|
||||||
**SchedulePlanCreateRequest** - 课表计划创建请求
|
|
||||||
```java
|
|
||||||
- classId: 班级 ID
|
|
||||||
- courseId: 课程 ID
|
|
||||||
- teacherId: 授课教师 ID
|
|
||||||
- dayOfWeek: 星期几
|
|
||||||
- period: 节次
|
|
||||||
- startTime: 开始时间
|
|
||||||
- endTime: 结束时间
|
|
||||||
- location: 教室/地点
|
|
||||||
- note: 备注
|
|
||||||
- startDate: 开始日期
|
|
||||||
- endDate: 结束日期
|
|
||||||
```
|
|
||||||
|
|
||||||
**ScheduleTemplateApplyRequest** - 课表模板应用请求
|
|
||||||
```java
|
|
||||||
- classId: 班级 ID
|
|
||||||
- startDate: 应用开始日期
|
|
||||||
- weeks: 应用周数
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 文件变更列表
|
|
||||||
|
|
||||||
### 新增文件 (7 个)
|
|
||||||
1. `dto/request/TaskTemplateCreateRequest.java`
|
|
||||||
2. `dto/request/TaskTemplateUpdateRequest.java`
|
|
||||||
3. `dto/request/CreateTaskFromTemplateRequest.java`
|
|
||||||
4. `dto/request/SchedulePlanCreateRequest.java`
|
|
||||||
5. `dto/request/ScheduleTemplateApplyRequest.java`
|
|
||||||
6. `controller/school/SchoolNotificationController.java`
|
|
||||||
7. `resources/db/migration/V7__fix_schedule_plans.sql`
|
|
||||||
|
|
||||||
### 修改文件 (7 个)
|
|
||||||
1. `service/TaskService.java` - 添加统计和模板方法接口
|
|
||||||
2. `service/impl/TaskServiceImpl.java` - 实现统计和模板逻辑 + 修复 ClassEntity bug
|
|
||||||
3. `service/ScheduleService.java` - 添加课表相关方法
|
|
||||||
4. `entity/SchedulePlan.java` - 添加课程、教师等字段
|
|
||||||
5. `controller/school/SchoolTaskController.java` - 添加统计和模板端点
|
|
||||||
6. `controller/teacher/TeacherTaskController.java` - 添加统计和模板端点
|
|
||||||
7. `controller/school/SchoolScheduleController.java` - 添加课表和模板端点
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 仍需补全的接口(下一步建议)
|
|
||||||
|
|
||||||
### 高优先级
|
|
||||||
1. **成长档案接口** - 按学生/班级查询
|
|
||||||
2. **教师端课时反馈** - 完成课时、学生记录、反馈接口
|
|
||||||
3. **班级管理** - 班级教师/学生管理、学生调班
|
|
||||||
|
|
||||||
### 中优先级
|
|
||||||
1. **统计报告** - 学校统计、报告导出
|
|
||||||
2. **导出接口增强** - 带日期范围参数
|
|
||||||
3. **管理员课程审核** - 提交、审核、发布流程
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 使用说明
|
|
||||||
|
|
||||||
1. 运行数据库迁移:
|
|
||||||
```bash
|
|
||||||
# Flyway 会在应用启动时自动运行 V7 迁移脚本
|
|
||||||
```
|
|
||||||
|
|
||||||
2. 编译项目:
|
|
||||||
```bash
|
|
||||||
cd reading-platform-java
|
|
||||||
mvn clean compile
|
|
||||||
```
|
|
||||||
|
|
||||||
3. 启动应用后,访问 API 文档:
|
|
||||||
```
|
|
||||||
http://localhost:8080/doc.html
|
|
||||||
```
|
|
||||||
Loading…
Reference in New Issue
Block a user