Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
d0439bc8b5
@ -3,15 +3,24 @@ package com.reading.platform.controller.teacher;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.reading.platform.common.mapper.ClassMapper;
|
||||
import com.reading.platform.common.mapper.CourseMapper;
|
||||
import com.reading.platform.common.mapper.StudentMapper;
|
||||
import com.reading.platform.common.mapper.TeacherMapper;
|
||||
import com.reading.platform.common.response.PageResult;
|
||||
import com.reading.platform.common.response.Result;
|
||||
import com.reading.platform.common.security.SecurityUtils;
|
||||
import com.reading.platform.dto.response.ClassResponse;
|
||||
import com.reading.platform.dto.response.CourseResponse;
|
||||
import com.reading.platform.dto.response.StudentResponse;
|
||||
import com.reading.platform.dto.response.TeacherResponse;
|
||||
import com.reading.platform.entity.ClassTeacher;
|
||||
import com.reading.platform.entity.Clazz;
|
||||
import com.reading.platform.entity.Course;
|
||||
import com.reading.platform.entity.Student;
|
||||
import com.reading.platform.entity.Teacher;
|
||||
import com.reading.platform.service.ClassService;
|
||||
import com.reading.platform.service.CourseService;
|
||||
import com.reading.platform.service.StudentService;
|
||||
import com.reading.platform.service.TeacherService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -20,6 +29,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Tag(name = "Teacher - Course", description = "Course APIs for Teacher")
|
||||
@RestController
|
||||
@ -29,8 +39,12 @@ public class TeacherCourseController {
|
||||
|
||||
private final CourseService courseService;
|
||||
private final ClassService classService;
|
||||
private final StudentService studentService;
|
||||
private final TeacherService teacherService;
|
||||
private final CourseMapper courseMapper;
|
||||
private final ClassMapper classMapper;
|
||||
private final StudentMapper studentMapper;
|
||||
private final TeacherMapper teacherMapper;
|
||||
|
||||
@Operation(summary = "Get teacher's classes")
|
||||
@GetMapping("/classes")
|
||||
@ -69,39 +83,57 @@ public class TeacherCourseController {
|
||||
|
||||
@Operation(summary = "Get all students of teacher")
|
||||
@GetMapping("/students")
|
||||
public Result<Map<String, Object>> getAllStudents(
|
||||
public Result<PageResult<StudentResponse>> getAllStudents(
|
||||
@RequestParam(required = false, defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(required = false, defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(required = false) String keyword) {
|
||||
Long teacherId = SecurityUtils.getCurrentUserId();
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("records", List.of());
|
||||
result.put("total", 0);
|
||||
result.put("teacherId", teacherId);
|
||||
return Result.success(result);
|
||||
Long tenantId = SecurityUtils.getCurrentTenantId();
|
||||
|
||||
// 获取教师教授的所有班级
|
||||
List<Clazz> classes = classService.getActiveClassesByTenantId(tenantId);
|
||||
List<Long> classIds = classes.stream()
|
||||
.filter(clazz -> {
|
||||
// 检查教师是否教授该班级
|
||||
List<Long> teacherIds = classService.getTeacherIdsByClassId(clazz.getId());
|
||||
return teacherIds.contains(teacherId);
|
||||
})
|
||||
.map(Clazz::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (classIds.isEmpty()) {
|
||||
return Result.success(PageResult.of(List.of(), 0L, (long) pageNum, (long) pageSize));
|
||||
}
|
||||
|
||||
// 分页获取学生
|
||||
Page<Student> page = new Page<>(pageNum, pageSize);
|
||||
List<Student> students = studentService.getStudentsByClassIds(classIds, keyword, page);
|
||||
|
||||
List<StudentResponse> voList = studentMapper.toVO(students);
|
||||
return Result.success(PageResult.of(voList, page.getTotal(), page.getCurrent(), page.getSize()));
|
||||
}
|
||||
|
||||
@Operation(summary = "Get students of class")
|
||||
@GetMapping("/classes/{id}/students")
|
||||
public Result<Map<String, Object>> getClassStudents(
|
||||
public Result<PageResult<StudentResponse>> getClassStudents(
|
||||
@PathVariable Long id,
|
||||
@RequestParam(required = false, defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(required = false, defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(required = false) String keyword) {
|
||||
Long teacherId = SecurityUtils.getCurrentUserId();
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("records", List.of());
|
||||
result.put("total", 0);
|
||||
result.put("teacherId", teacherId);
|
||||
result.put("classId", id);
|
||||
return Result.success(result);
|
||||
Page<Student> page = studentService.getStudentsByClassId(id, pageNum, pageSize);
|
||||
List<StudentResponse> voList = studentMapper.toVO(page.getRecords());
|
||||
return Result.success(PageResult.of(voList, page.getTotal(), page.getCurrent(), page.getSize()));
|
||||
}
|
||||
|
||||
@Operation(summary = "Get teachers of class")
|
||||
@GetMapping("/classes/{id}/teachers")
|
||||
public Result<List<Map<String, Object>>> getClassTeachers(@PathVariable Long id) {
|
||||
Long teacherId = SecurityUtils.getCurrentUserId();
|
||||
return Result.success(List.of());
|
||||
public Result<List<TeacherResponse>> getClassTeachers(@PathVariable Long id) {
|
||||
List<Long> teacherIds = classService.getTeacherIdsByClassId(id);
|
||||
if (teacherIds.isEmpty()) {
|
||||
return Result.success(List.of());
|
||||
}
|
||||
List<Teacher> teachers = teacherService.getTeachersByIds(teacherIds);
|
||||
return Result.success(teacherMapper.toVO(teachers));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,15 +1,20 @@
|
||||
package com.reading.platform.controller.teacher;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.reading.platform.common.annotation.RequireRole;
|
||||
import com.reading.platform.common.enums.UserRole;
|
||||
import com.reading.platform.common.mapper.LessonFeedbackMapper;
|
||||
import com.reading.platform.common.response.PageResult;
|
||||
import com.reading.platform.common.response.Result;
|
||||
import com.reading.platform.common.security.SecurityUtils;
|
||||
import com.reading.platform.dto.response.LessonFeedbackResponse;
|
||||
import com.reading.platform.entity.LessonFeedback;
|
||||
import com.reading.platform.service.TeacherFeedbackService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -23,28 +28,25 @@ import java.util.Map;
|
||||
@RequireRole(UserRole.TEACHER)
|
||||
public class TeacherFeedbackController {
|
||||
|
||||
private final TeacherFeedbackService teacherFeedbackService;
|
||||
private final LessonFeedbackMapper lessonFeedbackMapper;
|
||||
|
||||
@GetMapping
|
||||
@Operation(summary = "获取反馈列表")
|
||||
public Result<Map<String, Object>> getFeedbacks(
|
||||
public Result<PageResult<LessonFeedbackResponse>> getFeedbacks(
|
||||
@RequestParam(required = false, defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(required = false, defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(required = false) String type) {
|
||||
@RequestParam(required = false, defaultValue = "10") Integer pageSize) {
|
||||
Long teacherId = SecurityUtils.getCurrentUserId();
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("records", List.of());
|
||||
result.put("total", 0);
|
||||
result.put("teacherId", teacherId);
|
||||
return Result.success(result);
|
||||
Page<LessonFeedback> page = teacherFeedbackService.getTeacherFeedbacks(teacherId, pageNum, pageSize);
|
||||
List<LessonFeedbackResponse> voList = lessonFeedbackMapper.toVO(page.getRecords());
|
||||
return Result.success(PageResult.of(voList, page.getTotal(), page.getCurrent(), page.getSize()));
|
||||
}
|
||||
|
||||
@GetMapping("/stats")
|
||||
@Operation(summary = "获取反馈统计")
|
||||
public Result<Map<String, Object>> getFeedbackStats() {
|
||||
Long teacherId = SecurityUtils.getCurrentUserId();
|
||||
Map<String, Object> stats = new HashMap<>();
|
||||
stats.put("totalFeedbacks", 0);
|
||||
stats.put("byType", new HashMap<>());
|
||||
stats.put("teacherId", teacherId);
|
||||
Map<String, Object> stats = teacherFeedbackService.getFeedbackStats(teacherId);
|
||||
return Result.success(stats);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,13 +2,19 @@ package com.reading.platform.controller.teacher;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.reading.platform.common.mapper.LessonMapper;
|
||||
import com.reading.platform.common.mapper.StudentRecordMapper;
|
||||
import com.reading.platform.common.response.PageResult;
|
||||
import com.reading.platform.common.response.Result;
|
||||
import com.reading.platform.common.security.SecurityUtils;
|
||||
import com.reading.platform.dto.request.LessonCreateRequest;
|
||||
import com.reading.platform.dto.request.LessonProgressRequest;
|
||||
import com.reading.platform.dto.request.LessonUpdateRequest;
|
||||
import com.reading.platform.dto.request.StudentRecordRequest;
|
||||
import com.reading.platform.dto.response.LessonResponse;
|
||||
import com.reading.platform.dto.response.StudentRecordResponse;
|
||||
import com.reading.platform.entity.Lesson;
|
||||
import com.reading.platform.entity.LessonFeedback;
|
||||
import com.reading.platform.entity.StudentRecord;
|
||||
import com.reading.platform.service.LessonService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@ -28,6 +34,7 @@ public class TeacherLessonController {
|
||||
|
||||
private final LessonService lessonService;
|
||||
private final LessonMapper lessonMapper;
|
||||
private final StudentRecordMapper studentRecordMapper;
|
||||
|
||||
@Operation(summary = "Create lesson")
|
||||
@PostMapping
|
||||
@ -94,4 +101,65 @@ public class TeacherLessonController {
|
||||
return Result.success(lessonMapper.toVO(lessons));
|
||||
}
|
||||
|
||||
@Operation(summary = "Get student records")
|
||||
@GetMapping("/{id}/students/records")
|
||||
public Result<List<StudentRecordResponse>> getStudentRecords(@PathVariable Long id) {
|
||||
List<StudentRecord> records = lessonService.getStudentRecords(id);
|
||||
List<StudentRecordResponse> voList = studentRecordMapper.toVO(records);
|
||||
return Result.success(voList);
|
||||
}
|
||||
|
||||
@Operation(summary = "Save student record")
|
||||
@PostMapping("/{id}/students/{studentId}/record")
|
||||
public Result<StudentRecordResponse> saveStudentRecord(
|
||||
@PathVariable Long id,
|
||||
@PathVariable Long studentId,
|
||||
@RequestBody StudentRecordRequest request) {
|
||||
StudentRecord record = lessonService.saveStudentRecord(id, studentId, request);
|
||||
return Result.success(studentRecordMapper.toVO(record));
|
||||
}
|
||||
|
||||
@Operation(summary = "Batch save student records")
|
||||
@PostMapping("/{id}/students/batch-records")
|
||||
public Result<List<StudentRecordResponse>> batchSaveStudentRecords(
|
||||
@PathVariable Long id,
|
||||
@RequestBody List<StudentRecordRequest> requests) {
|
||||
List<StudentRecord> records = lessonService.batchSaveStudentRecords(id, requests);
|
||||
List<StudentRecordResponse> voList = studentRecordMapper.toVO(records);
|
||||
return Result.success(voList);
|
||||
}
|
||||
|
||||
@Operation(summary = "Get lesson feedback")
|
||||
@GetMapping("/{id}/feedback")
|
||||
public Result<LessonFeedback> getLessonFeedback(@PathVariable Long id) {
|
||||
LessonFeedback feedback = lessonService.getLessonFeedback(id);
|
||||
return Result.success(feedback != null ? feedback : null);
|
||||
}
|
||||
|
||||
@Operation(summary = "Submit lesson feedback")
|
||||
@PostMapping("/{id}/feedback")
|
||||
public Result<LessonFeedback> submitFeedback(
|
||||
@PathVariable Long id,
|
||||
@RequestBody com.reading.platform.dto.request.LessonFeedbackRequest request) {
|
||||
Long teacherId = SecurityUtils.getCurrentUserId();
|
||||
LessonFeedback feedback = lessonService.submitFeedback(id, teacherId, request.getContent(), request.getRating());
|
||||
return Result.success(feedback);
|
||||
}
|
||||
|
||||
@Operation(summary = "Save lesson progress")
|
||||
@PutMapping("/{id}/progress")
|
||||
public Result<Void> saveLessonProgress(
|
||||
@PathVariable Long id,
|
||||
@RequestBody LessonProgressRequest request) {
|
||||
lessonService.saveLessonProgress(id, request);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Operation(summary = "Get lesson progress")
|
||||
@GetMapping("/{id}/progress")
|
||||
public Result<LessonResponse> getLessonProgress(@PathVariable Long id) {
|
||||
Lesson lesson = lessonService.getLessonProgress(id);
|
||||
return Result.success(lessonMapper.toVO(lesson));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,18 +1,27 @@
|
||||
package com.reading.platform.controller.teacher;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.reading.platform.common.annotation.RequireRole;
|
||||
import com.reading.platform.common.enums.UserRole;
|
||||
import com.reading.platform.common.mapper.SchedulePlanMapper;
|
||||
import com.reading.platform.common.response.PageResult;
|
||||
import com.reading.platform.common.response.Result;
|
||||
import com.reading.platform.common.security.SecurityUtils;
|
||||
import com.reading.platform.dto.request.SchedulePlanCreateRequest;
|
||||
import com.reading.platform.dto.request.SchedulePlanUpdateRequest;
|
||||
import com.reading.platform.dto.response.SchedulePlanResponse;
|
||||
import com.reading.platform.dto.response.TimetableResponse;
|
||||
import com.reading.platform.entity.SchedulePlan;
|
||||
import com.reading.platform.service.TeacherScheduleService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 教师端 - 排课管理
|
||||
@ -24,73 +33,70 @@ import java.util.Map;
|
||||
@RequireRole(UserRole.TEACHER)
|
||||
public class TeacherScheduleController {
|
||||
|
||||
private final TeacherScheduleService teacherScheduleService;
|
||||
private final SchedulePlanMapper schedulePlanMapper;
|
||||
|
||||
@GetMapping
|
||||
@Operation(summary = "获取教师排课列表")
|
||||
public Result<Map<String, Object>> getSchedules(
|
||||
@RequestParam(required = false) String startDate,
|
||||
@RequestParam(required = false) String endDate) {
|
||||
public Result<PageResult<SchedulePlanResponse>> getSchedules(
|
||||
@RequestParam(required = false, defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(required = false, defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
|
||||
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
|
||||
Long teacherId = SecurityUtils.getCurrentUserId();
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("records", List.of());
|
||||
result.put("total", 0);
|
||||
result.put("teacherId", teacherId);
|
||||
return Result.success(result);
|
||||
Page<SchedulePlan> page = teacherScheduleService.getTeacherSchedules(teacherId, pageNum, pageSize, startDate, endDate);
|
||||
List<SchedulePlanResponse> voList = schedulePlanMapper.toVO(page.getRecords());
|
||||
return Result.success(PageResult.of(voList, page.getTotal(), page.getCurrent(), page.getSize()));
|
||||
}
|
||||
|
||||
@GetMapping("/timetable")
|
||||
@Operation(summary = "获取教师课程表")
|
||||
public Result<Map<String, Object>> getTimetable(
|
||||
@RequestParam(required = false) String startDate,
|
||||
@RequestParam(required = false) String endDate) {
|
||||
public Result<List<TimetableResponse>> getTimetable(
|
||||
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
|
||||
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
|
||||
Long teacherId = SecurityUtils.getCurrentUserId();
|
||||
Map<String, Object> timetable = new HashMap<>();
|
||||
timetable.put("teacherId", teacherId);
|
||||
timetable.put("classes", List.of());
|
||||
List<TimetableResponse> timetable = teacherScheduleService.getTimetable(teacherId, startDate, endDate);
|
||||
return Result.success(timetable);
|
||||
}
|
||||
|
||||
@GetMapping("/today")
|
||||
@Operation(summary = "获取今日排课")
|
||||
public Result<List<Map<String, Object>>> getTodaySchedules() {
|
||||
public Result<List<SchedulePlanResponse>> getTodaySchedules() {
|
||||
Long teacherId = SecurityUtils.getCurrentUserId();
|
||||
return Result.success(List.of());
|
||||
List<SchedulePlan> schedules = teacherScheduleService.getTodaySchedules(teacherId);
|
||||
List<SchedulePlanResponse> voList = schedulePlanMapper.toVO(schedules);
|
||||
return Result.success(voList);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@Operation(summary = "获取排课详情")
|
||||
public Result<Map<String, Object>> getSchedule(@PathVariable Long id) {
|
||||
Map<String, Object> schedule = new HashMap<>();
|
||||
schedule.put("id", id);
|
||||
schedule.put("message", "排课详情待实现");
|
||||
return Result.success(schedule);
|
||||
public Result<SchedulePlanResponse> getSchedule(@PathVariable Long id) {
|
||||
SchedulePlan schedule = teacherScheduleService.getScheduleById(id);
|
||||
return Result.success(schedulePlanMapper.toVO(schedule));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "创建排课")
|
||||
public Result<Map<String, Object>> createSchedule(@RequestBody Map<String, Object> request) {
|
||||
public Result<SchedulePlanResponse> createSchedule(@Valid @RequestBody SchedulePlanCreateRequest request) {
|
||||
Long teacherId = SecurityUtils.getCurrentUserId();
|
||||
Long tenantId = SecurityUtils.getCurrentTenantId();
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("message", "创建排课功能待实现");
|
||||
result.put("teacherId", teacherId);
|
||||
result.put("tenantId", tenantId);
|
||||
return Result.success(result);
|
||||
SchedulePlan schedule = teacherScheduleService.createSchedule(tenantId, teacherId, request);
|
||||
return Result.success(schedulePlanMapper.toVO(schedule));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
@Operation(summary = "更新排课")
|
||||
public Result<Map<String, Object>> updateSchedule(
|
||||
public Result<SchedulePlanResponse> updateSchedule(
|
||||
@PathVariable Long id,
|
||||
@RequestBody Map<String, Object> request) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("message", "更新排课功能待实现");
|
||||
result.put("id", id);
|
||||
return Result.success(result);
|
||||
@RequestBody SchedulePlanUpdateRequest request) {
|
||||
SchedulePlan schedule = teacherScheduleService.updateSchedule(id, request);
|
||||
return Result.success(schedulePlanMapper.toVO(schedule));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@Operation(summary = "取消排课")
|
||||
public Result<Void> cancelSchedule(@PathVariable Long id) {
|
||||
teacherScheduleService.cancelSchedule(id);
|
||||
return Result.success();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,17 +1,25 @@
|
||||
package com.reading.platform.controller.teacher;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.reading.platform.common.annotation.RequireRole;
|
||||
import com.reading.platform.common.enums.UserRole;
|
||||
import com.reading.platform.common.mapper.TaskTemplateMapper;
|
||||
import com.reading.platform.common.response.PageResult;
|
||||
import com.reading.platform.common.response.Result;
|
||||
import com.reading.platform.common.security.SecurityUtils;
|
||||
import com.reading.platform.dto.request.CreateTaskFromTemplateRequest;
|
||||
import com.reading.platform.dto.request.TaskTemplateCreateRequest;
|
||||
import com.reading.platform.dto.response.TaskTemplateResponse;
|
||||
import com.reading.platform.entity.Task;
|
||||
import com.reading.platform.entity.TaskTemplate;
|
||||
import com.reading.platform.service.TaskTemplateService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 教师端 - 任务模板
|
||||
@ -23,72 +31,67 @@ import java.util.Map;
|
||||
@RequireRole(UserRole.TEACHER)
|
||||
public class TeacherTaskTemplateController {
|
||||
|
||||
private final TaskTemplateService taskTemplateService;
|
||||
private final TaskTemplateMapper taskTemplateMapper;
|
||||
|
||||
@GetMapping
|
||||
@Operation(summary = "获取模板列表")
|
||||
public Result<Map<String, Object>> getTemplates(
|
||||
public Result<PageResult<TaskTemplateResponse>> getTemplates(
|
||||
@RequestParam(required = false, defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(required = false, defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(required = false) String type) {
|
||||
Long tenantId = SecurityUtils.getCurrentTenantId();
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("records", List.of());
|
||||
result.put("total", 0);
|
||||
result.put("tenantId", tenantId);
|
||||
return Result.success(result);
|
||||
Page<TaskTemplate> page = taskTemplateService.getTemplates(tenantId, pageNum, pageSize, type);
|
||||
List<TaskTemplateResponse> voList = taskTemplateMapper.toVO(page.getRecords());
|
||||
return Result.success(PageResult.of(voList, page.getTotal(), page.getCurrent(), page.getSize()));
|
||||
}
|
||||
|
||||
@GetMapping("/default/{type}")
|
||||
@Operation(summary = "获取默认模板")
|
||||
public Result<Map<String, Object>> getDefaultTemplate(@PathVariable String type) {
|
||||
Map<String, Object> template = new HashMap<>();
|
||||
template.put("type", type);
|
||||
template.put("message", "默认模板待实现");
|
||||
return Result.success(template);
|
||||
public Result<TaskTemplateResponse> getDefaultTemplate(@PathVariable String type) {
|
||||
Long tenantId = SecurityUtils.getCurrentTenantId();
|
||||
TaskTemplate template = taskTemplateService.getDefaultTemplate(tenantId, type);
|
||||
return template != null ? Result.success(taskTemplateMapper.toVO(template)) : Result.success(null);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@Operation(summary = "获取模板详情")
|
||||
public Result<Map<String, Object>> getTemplate(@PathVariable Long id) {
|
||||
Map<String, Object> template = new HashMap<>();
|
||||
template.put("id", id);
|
||||
template.put("message", "模板详情待实现");
|
||||
return Result.success(template);
|
||||
public Result<TaskTemplateResponse> getTemplate(@PathVariable Long id) {
|
||||
TaskTemplate template = taskTemplateService.getTemplateById(id);
|
||||
return Result.success(taskTemplateMapper.toVO(template));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "创建模板")
|
||||
public Result<Map<String, Object>> createTemplate(@RequestBody Map<String, Object> request) {
|
||||
public Result<TaskTemplateResponse> createTemplate(@Valid @RequestBody TaskTemplateCreateRequest request) {
|
||||
Long tenantId = SecurityUtils.getCurrentTenantId();
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("message", "创建模板功能待实现");
|
||||
result.put("tenantId", tenantId);
|
||||
return Result.success(result);
|
||||
Long userId = SecurityUtils.getCurrentUserId();
|
||||
TaskTemplate template = taskTemplateService.createTemplate(tenantId, userId, request);
|
||||
return Result.success(taskTemplateMapper.toVO(template));
|
||||
}
|
||||
|
||||
@PostMapping("/from-template")
|
||||
@Operation(summary = "从模板创建任务")
|
||||
public Result<Map<String, Object>> createFromTemplate(@RequestBody Map<String, Object> request) {
|
||||
public Result<Task> createFromTemplate(@Valid @RequestBody CreateTaskFromTemplateRequest request) {
|
||||
Long tenantId = SecurityUtils.getCurrentTenantId();
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("message", "从模板创建任务功能待实现");
|
||||
result.put("tenantId", tenantId);
|
||||
return Result.success(result);
|
||||
Long userId = SecurityUtils.getCurrentUserId();
|
||||
Task task = taskTemplateService.createTaskFromTemplate(tenantId, userId, request.getTemplateId(), request);
|
||||
return Result.success(task);
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
@Operation(summary = "更新模板")
|
||||
public Result<Map<String, Object>> updateTemplate(
|
||||
public Result<TaskTemplateResponse> updateTemplate(
|
||||
@PathVariable Long id,
|
||||
@RequestBody Map<String, Object> request) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("message", "更新模板功能待实现");
|
||||
result.put("id", id);
|
||||
return Result.success(result);
|
||||
@RequestBody TaskTemplateCreateRequest request) {
|
||||
TaskTemplate template = taskTemplateService.updateTemplate(id, request);
|
||||
return Result.success(taskTemplateMapper.toVO(template));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@Operation(summary = "删除模板")
|
||||
public Result<Void> deleteTemplate(@PathVariable Long id) {
|
||||
taskTemplateService.deleteTemplate(id);
|
||||
return Result.success();
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
package com.reading.platform.dto.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 从模板创建任务请求
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "从模板创建任务请求")
|
||||
public class CreateTaskFromTemplateRequest {
|
||||
|
||||
@Schema(description = "模板 ID")
|
||||
private Long templateId;
|
||||
|
||||
@NotBlank(message = "任务标题不能为空")
|
||||
@Schema(description = "任务标题")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "任务描述")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "开始日期")
|
||||
private String startDate;
|
||||
|
||||
@Schema(description = "截止日期")
|
||||
private String endDate;
|
||||
|
||||
@Schema(description = "目标类型:class-班级,student-学生")
|
||||
private String targetType;
|
||||
|
||||
@Schema(description = "目标 IDs")
|
||||
private java.util.List<Long> targetIds;
|
||||
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package com.reading.platform.dto.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 课程反馈提交请求
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "课程反馈提交请求")
|
||||
public class LessonFeedbackRequest {
|
||||
|
||||
@Schema(description = "反馈内容")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "总体评分 (1-5)")
|
||||
@Min(value = 1, message = "评分最小值为 1")
|
||||
@Max(value = 5, message = "评分最大值为 5")
|
||||
private Integer rating;
|
||||
|
||||
@Schema(description = "教学设计评分 (1-5)")
|
||||
@Min(value = 1, message = "评分最小值为 1")
|
||||
@Max(value = 5, message = "评分最大值为 5")
|
||||
private Integer designQuality;
|
||||
|
||||
@Schema(description = "学生参与度评分 (1-5)")
|
||||
@Min(value = 1, message = "评分最小值为 1")
|
||||
@Max(value = 5, message = "评分最大值为 5")
|
||||
private Integer participation;
|
||||
|
||||
@Schema(description = "目标达成度评分 (1-5)")
|
||||
@Min(value = 1, message = "评分最小值为 1")
|
||||
@Max(value = 5, message = "评分最大值为 5")
|
||||
private Integer goalAchievement;
|
||||
|
||||
@Schema(description = "各步骤反馈 (JSON 数组)")
|
||||
private String stepFeedbacks;
|
||||
|
||||
@Schema(description = "优点")
|
||||
private String pros;
|
||||
|
||||
@Schema(description = "建议")
|
||||
private String suggestions;
|
||||
|
||||
@Schema(description = "已完成的活动")
|
||||
private String activitiesDone;
|
||||
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package com.reading.platform.dto.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 课程进度保存请求
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "课程进度保存请求")
|
||||
public class LessonProgressRequest {
|
||||
|
||||
@Schema(description = "当前课程 ID")
|
||||
private Integer currentLessonId;
|
||||
|
||||
@Schema(description = "当前步骤 ID")
|
||||
private Integer currentStepId;
|
||||
|
||||
@Schema(description = "课程 ID 列表 (JSON)")
|
||||
private String lessonIds;
|
||||
|
||||
@Schema(description = "已完成课程 ID 列表 (JSON)")
|
||||
private String completedLessonIds;
|
||||
|
||||
@Schema(description = "进度数据 (JSON)")
|
||||
private String progressData;
|
||||
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package com.reading.platform.dto.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 日程计划创建请求
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "日程计划创建请求")
|
||||
public class SchedulePlanCreateRequest {
|
||||
|
||||
@NotBlank(message = "计划名称不能为空")
|
||||
@Schema(description = "计划名称")
|
||||
private String name;
|
||||
|
||||
@NotNull(message = "班级 ID 不能为空")
|
||||
@Schema(description = "班级 ID")
|
||||
private Long classId;
|
||||
|
||||
@Schema(description = "课程 ID")
|
||||
private Long courseId;
|
||||
|
||||
@Schema(description = "教师 ID")
|
||||
private Long teacherId;
|
||||
|
||||
@Schema(description = "排课日期")
|
||||
private LocalDate scheduledDate;
|
||||
|
||||
@Schema(description = "时间段 (如:09:00-10:00)")
|
||||
private String scheduledTime;
|
||||
|
||||
@Schema(description = "星期几 (1-7)")
|
||||
private Integer weekDay;
|
||||
|
||||
@Schema(description = "重复方式 (NONE/WEEKLY)")
|
||||
private String repeatType;
|
||||
|
||||
@Schema(description = "重复截止日期")
|
||||
private LocalDate repeatEndDate;
|
||||
|
||||
@Schema(description = "来源 (SCHOOL/TEACHER)")
|
||||
private String source;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String note;
|
||||
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package com.reading.platform.dto.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 日程计划更新请求
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "日程计划更新请求")
|
||||
public class SchedulePlanUpdateRequest {
|
||||
|
||||
@Schema(description = "计划名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "课程 ID")
|
||||
private Long courseId;
|
||||
|
||||
@Schema(description = "教师 ID")
|
||||
private Long teacherId;
|
||||
|
||||
@Schema(description = "排课日期")
|
||||
private LocalDate scheduledDate;
|
||||
|
||||
@Schema(description = "时间段 (如:09:00-10:00)")
|
||||
private String scheduledTime;
|
||||
|
||||
@Schema(description = "星期几 (1-7)")
|
||||
private Integer weekDay;
|
||||
|
||||
@Schema(description = "重复方式 (NONE/WEEKLY)")
|
||||
private String repeatType;
|
||||
|
||||
@Schema(description = "重复截止日期")
|
||||
private LocalDate repeatEndDate;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String note;
|
||||
|
||||
@Schema(description = "状态")
|
||||
private String status;
|
||||
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package com.reading.platform.dto.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 学生记录保存请求
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "学生记录保存请求")
|
||||
public class StudentRecordRequest {
|
||||
|
||||
@NotNull(message = "学生 ID 不能为空")
|
||||
@Schema(description = "学生 ID")
|
||||
private Long studentId;
|
||||
|
||||
@Schema(description = "出勤状态")
|
||||
private String attendance;
|
||||
|
||||
@Schema(description = "专注度评分 (1-5)")
|
||||
private Integer focus;
|
||||
|
||||
@Schema(description = "参与度评分 (1-5)")
|
||||
private Integer participation;
|
||||
|
||||
@Schema(description = "兴趣度评分 (1-5)")
|
||||
private Integer interest;
|
||||
|
||||
@Schema(description = "理解度评分 (1-5)")
|
||||
private Integer understanding;
|
||||
|
||||
@Schema(description = "领域达成 (JSON 数组)")
|
||||
private String domainAchievements;
|
||||
|
||||
@Schema(description = "表现评价")
|
||||
private String performance;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String notes;
|
||||
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package com.reading.platform.dto.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 任务模板创建请求
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "任务模板创建请求")
|
||||
public class TaskTemplateCreateRequest {
|
||||
|
||||
@NotBlank(message = "模板名称不能为空")
|
||||
@Schema(description = "模板名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "模板描述")
|
||||
private String description;
|
||||
|
||||
@Schema(description = "模板类型")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "任务类型")
|
||||
private String taskType;
|
||||
|
||||
@Schema(description = "关联课程 ID")
|
||||
private Long relatedCourseId;
|
||||
|
||||
@Schema(description = "默认持续时间 (天)")
|
||||
private Integer defaultDuration;
|
||||
|
||||
@Schema(description = "是否默认模板")
|
||||
private Integer isDefault;
|
||||
|
||||
@Schema(description = "模板内容")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "是否公开")
|
||||
private Integer isPublic;
|
||||
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package com.reading.platform.dto.response;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 课表响应
|
||||
* 用于按日期分组返回课表信息
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@Schema(description = "课表响应")
|
||||
public class TimetableResponse {
|
||||
|
||||
@Schema(description = "日期")
|
||||
private LocalDate date;
|
||||
|
||||
@Schema(description = "星期几 (1-7)")
|
||||
private Integer weekDay;
|
||||
|
||||
@Schema(description = "排课列表")
|
||||
private List<SchedulePlanResponse> schedules;
|
||||
|
||||
}
|
||||
@ -23,4 +23,8 @@ public class ClassTeacher extends BaseEntity {
|
||||
@Schema(description = "角色")
|
||||
private String role;
|
||||
|
||||
// 暂时注释掉数据库中不存在的字段
|
||||
// @Schema(description = "是否主班")
|
||||
// private Integer isPrimary;
|
||||
|
||||
}
|
||||
|
||||
@ -29,6 +29,10 @@ public class Clazz extends BaseEntity {
|
||||
@Schema(description = "容纳人数")
|
||||
private Integer capacity;
|
||||
|
||||
// 暂时注释掉数据库中不存在的字段
|
||||
// @Schema(description = "课时数")
|
||||
// private Integer lessonCount;
|
||||
|
||||
@Schema(description = "状态")
|
||||
private String status;
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
|
||||
/**
|
||||
@ -29,6 +30,9 @@ public class Lesson extends BaseEntity {
|
||||
@Schema(description = "教师 ID")
|
||||
private Long teacherId;
|
||||
|
||||
@Schema(description = "排课计划 ID")
|
||||
private Long schedulePlanId;
|
||||
|
||||
@Schema(description = "课程标题")
|
||||
private String title;
|
||||
|
||||
@ -41,12 +45,48 @@ public class Lesson extends BaseEntity {
|
||||
@Schema(description = "结束时间")
|
||||
private LocalTime endTime;
|
||||
|
||||
@Schema(description = "计划上课时间")
|
||||
private LocalDateTime plannedDatetime;
|
||||
|
||||
@Schema(description = "实际上课开始时间")
|
||||
private LocalDateTime startDatetime;
|
||||
|
||||
@Schema(description = "实际上课结束时间")
|
||||
private LocalDateTime endDatetime;
|
||||
|
||||
@Schema(description = "实际时长 (分钟)")
|
||||
private Integer actualDuration;
|
||||
|
||||
@Schema(description = "上课地点")
|
||||
private String location;
|
||||
|
||||
@Schema(description = "状态")
|
||||
private String status;
|
||||
|
||||
@Schema(description = "整体评价")
|
||||
private String overallRating;
|
||||
|
||||
@Schema(description = "参与度评价")
|
||||
private String participationRating;
|
||||
|
||||
@Schema(description = "完成说明")
|
||||
private String completionNote;
|
||||
|
||||
@Schema(description = "进度数据 (JSON)")
|
||||
private String progressData;
|
||||
|
||||
@Schema(description = "当前课程 ID")
|
||||
private Integer currentLessonId;
|
||||
|
||||
@Schema(description = "当前步骤 ID")
|
||||
private Integer currentStepId;
|
||||
|
||||
@Schema(description = "课程 ID 列表 (JSON)")
|
||||
private String lessonIds;
|
||||
|
||||
@Schema(description = "已完成课程 ID 列表 (JSON)")
|
||||
private String completedLessonIds;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String notes;
|
||||
|
||||
|
||||
@ -26,4 +26,25 @@ public class LessonFeedback extends BaseEntity {
|
||||
@Schema(description = "评分")
|
||||
private Integer rating;
|
||||
|
||||
@Schema(description = "教学设计评分 (1-5)")
|
||||
private Integer designQuality;
|
||||
|
||||
@Schema(description = "学生参与度评分 (1-5)")
|
||||
private Integer participation;
|
||||
|
||||
@Schema(description = "目标达成度评分 (1-5)")
|
||||
private Integer goalAchievement;
|
||||
|
||||
@Schema(description = "各步骤反馈 (JSON 数组)")
|
||||
private String stepFeedbacks;
|
||||
|
||||
@Schema(description = "优点")
|
||||
private String pros;
|
||||
|
||||
@Schema(description = "建议")
|
||||
private String suggestions;
|
||||
|
||||
@Schema(description = "已完成的活动")
|
||||
private String activitiesDone;
|
||||
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 日程计划实体
|
||||
@ -25,10 +26,45 @@ public class SchedulePlan extends BaseEntity {
|
||||
@Schema(description = "班级 ID")
|
||||
private Long classId;
|
||||
|
||||
@Schema(description = "开始日期")
|
||||
@Schema(description = "课程 ID")
|
||||
private Long courseId;
|
||||
|
||||
@Schema(description = "教师 ID")
|
||||
private Long teacherId;
|
||||
|
||||
@Schema(description = "排课日期")
|
||||
private LocalDate scheduledDate;
|
||||
|
||||
@Schema(description = "时间段 (如:09:00-10:00)")
|
||||
private String scheduledTime;
|
||||
|
||||
@Schema(description = "星期几 (1-7)")
|
||||
private Integer weekDay;
|
||||
|
||||
@Schema(description = "重复方式 (NONE/WEEKLY)")
|
||||
private String repeatType;
|
||||
|
||||
@Schema(description = "重复截止日期")
|
||||
private LocalDate repeatEndDate;
|
||||
|
||||
@Schema(description = "来源 (SCHOOL/TEACHER)")
|
||||
private String source;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String note;
|
||||
|
||||
@Schema(description = "是否已发送提醒")
|
||||
private Integer reminderSent;
|
||||
|
||||
@Schema(description = "提醒发送时间")
|
||||
private LocalDateTime reminderSentAt;
|
||||
|
||||
@Schema(description = "开始日期(废弃,兼容旧数据)")
|
||||
@Deprecated
|
||||
private LocalDate startDate;
|
||||
|
||||
@Schema(description = "结束日期")
|
||||
@Schema(description = "结束日期(废弃,兼容旧数据)")
|
||||
@Deprecated
|
||||
private LocalDate endDate;
|
||||
|
||||
@Schema(description = "状态")
|
||||
|
||||
@ -29,4 +29,19 @@ public class StudentRecord extends BaseEntity {
|
||||
@Schema(description = "备注")
|
||||
private String notes;
|
||||
|
||||
@Schema(description = "专注度评分 (1-5)")
|
||||
private Integer focus;
|
||||
|
||||
@Schema(description = "参与度评分 (1-5)")
|
||||
private Integer participation;
|
||||
|
||||
@Schema(description = "兴趣度评分 (1-5)")
|
||||
private Integer interest;
|
||||
|
||||
@Schema(description = "理解度评分 (1-5)")
|
||||
private Integer understanding;
|
||||
|
||||
@Schema(description = "领域达成 (JSON 数组)")
|
||||
private String domainAchievements;
|
||||
|
||||
}
|
||||
|
||||
@ -26,6 +26,24 @@ public class TaskTemplate extends BaseEntity {
|
||||
@Schema(description = "模板类型")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "任务类型")
|
||||
private String taskType;
|
||||
|
||||
@Schema(description = "关联课程 ID")
|
||||
private Long relatedCourseId;
|
||||
|
||||
@Schema(description = "默认持续时间 (天)")
|
||||
private Integer defaultDuration;
|
||||
|
||||
@Schema(description = "是否默认模板")
|
||||
private Integer isDefault;
|
||||
|
||||
@Schema(description = "状态")
|
||||
private String status;
|
||||
|
||||
@Schema(description = "创建人 ID")
|
||||
private Long createdBy;
|
||||
|
||||
@Schema(description = "模板内容")
|
||||
private String content;
|
||||
|
||||
|
||||
@ -43,6 +43,13 @@ public class Teacher extends BaseEntity {
|
||||
@Schema(description = "个人简介")
|
||||
private String bio;
|
||||
|
||||
// 暂时注释掉数据库中不存在的字段
|
||||
// @Schema(description = "授课次数")
|
||||
// private Integer lessonCount;
|
||||
|
||||
// @Schema(description = "反馈次数")
|
||||
// private Integer feedbackCount;
|
||||
|
||||
@Schema(description = "状态")
|
||||
private String status;
|
||||
|
||||
|
||||
@ -3,7 +3,11 @@ package com.reading.platform.service;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.reading.platform.dto.request.LessonCreateRequest;
|
||||
import com.reading.platform.dto.request.LessonUpdateRequest;
|
||||
import com.reading.platform.dto.request.LessonProgressRequest;
|
||||
import com.reading.platform.dto.request.StudentRecordRequest;
|
||||
import com.reading.platform.entity.Lesson;
|
||||
import com.reading.platform.entity.LessonFeedback;
|
||||
import com.reading.platform.entity.StudentRecord;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
@ -33,4 +37,39 @@ public interface LessonService extends com.baomidou.mybatisplus.extension.servic
|
||||
|
||||
List<Lesson> getTodayLessons(Long tenantId);
|
||||
|
||||
/**
|
||||
* 获取学生记录列表
|
||||
*/
|
||||
List<StudentRecord> getStudentRecords(Long lessonId);
|
||||
|
||||
/**
|
||||
* 保存学生记录
|
||||
*/
|
||||
StudentRecord saveStudentRecord(Long lessonId, Long studentId, StudentRecordRequest request);
|
||||
|
||||
/**
|
||||
* 批量保存学生记录
|
||||
*/
|
||||
List<StudentRecord> batchSaveStudentRecords(Long lessonId, List<StudentRecordRequest> requests);
|
||||
|
||||
/**
|
||||
* 获取课程反馈
|
||||
*/
|
||||
LessonFeedback getLessonFeedback(Long lessonId);
|
||||
|
||||
/**
|
||||
* 提交课程反馈
|
||||
*/
|
||||
LessonFeedback submitFeedback(Long lessonId, Long teacherId, String content, Integer rating);
|
||||
|
||||
/**
|
||||
* 保存课程进度
|
||||
*/
|
||||
void saveLessonProgress(Long lessonId, LessonProgressRequest request);
|
||||
|
||||
/**
|
||||
* 获取课程进度
|
||||
*/
|
||||
Lesson getLessonProgress(Long lessonId);
|
||||
|
||||
}
|
||||
|
||||
@ -37,6 +37,11 @@ public interface StudentService extends com.baomidou.mybatisplus.extension.servi
|
||||
*/
|
||||
Page<Student> getStudentsByClassId(Long classId, Integer pageNum, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 根据班级 ID 列表查询学生
|
||||
*/
|
||||
List<Student> getStudentsByClassIds(List<Long> classIds, String keyword, Page<Student> page);
|
||||
|
||||
/**
|
||||
* 删除学生
|
||||
*/
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
package com.reading.platform.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.reading.platform.dto.request.CreateTaskFromTemplateRequest;
|
||||
import com.reading.platform.dto.request.TaskTemplateCreateRequest;
|
||||
import com.reading.platform.entity.Task;
|
||||
import com.reading.platform.entity.TaskTemplate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 任务模板服务接口
|
||||
*/
|
||||
public interface TaskTemplateService extends com.baomidou.mybatisplus.extension.service.IService<TaskTemplate> {
|
||||
|
||||
/**
|
||||
* 获取模板列表
|
||||
*/
|
||||
Page<TaskTemplate> getTemplates(Long tenantId, Integer pageNum, Integer pageSize, String type);
|
||||
|
||||
/**
|
||||
* 获取默认模板
|
||||
*/
|
||||
TaskTemplate getDefaultTemplate(Long tenantId, String type);
|
||||
|
||||
/**
|
||||
* 获取模板详情
|
||||
*/
|
||||
TaskTemplate getTemplateById(Long id);
|
||||
|
||||
/**
|
||||
* 创建模板
|
||||
*/
|
||||
TaskTemplate createTemplate(Long tenantId, Long userId, TaskTemplateCreateRequest request);
|
||||
|
||||
/**
|
||||
* 更新模板
|
||||
*/
|
||||
TaskTemplate updateTemplate(Long id, TaskTemplateCreateRequest request);
|
||||
|
||||
/**
|
||||
* 删除模板
|
||||
*/
|
||||
void deleteTemplate(Long id);
|
||||
|
||||
/**
|
||||
* 从模板创建任务
|
||||
*/
|
||||
Task createTaskFromTemplate(Long tenantId, Long userId, Long templateId, CreateTaskFromTemplateRequest request);
|
||||
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.reading.platform.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.reading.platform.entity.LessonFeedback;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 教师端反馈服务接口
|
||||
*/
|
||||
public interface TeacherFeedbackService {
|
||||
|
||||
/**
|
||||
* 获取教师反馈列表
|
||||
*/
|
||||
Page<LessonFeedback> getTeacherFeedbacks(Long teacherId, Integer pageNum, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 获取教师反馈统计
|
||||
*/
|
||||
Map<String, Object> getFeedbackStats(Long teacherId);
|
||||
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package com.reading.platform.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.reading.platform.dto.request.SchedulePlanCreateRequest;
|
||||
import com.reading.platform.dto.request.SchedulePlanUpdateRequest;
|
||||
import com.reading.platform.dto.response.TimetableResponse;
|
||||
import com.reading.platform.entity.SchedulePlan;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 教师端排课服务接口
|
||||
*/
|
||||
public interface TeacherScheduleService extends com.baomidou.mybatisplus.extension.service.IService<SchedulePlan> {
|
||||
|
||||
/**
|
||||
* 获取教师排课列表
|
||||
*/
|
||||
Page<SchedulePlan> getTeacherSchedules(Long teacherId, Integer pageNum, Integer pageSize,
|
||||
LocalDate startDate, LocalDate endDate);
|
||||
|
||||
/**
|
||||
* 获取教师课表(按日期分组)
|
||||
*/
|
||||
List<TimetableResponse> getTimetable(Long teacherId, LocalDate startDate, LocalDate endDate);
|
||||
|
||||
/**
|
||||
* 获取今日排课
|
||||
*/
|
||||
List<SchedulePlan> getTodaySchedules(Long teacherId);
|
||||
|
||||
/**
|
||||
* 创建排课
|
||||
*/
|
||||
SchedulePlan createSchedule(Long tenantId, Long teacherId, SchedulePlanCreateRequest request);
|
||||
|
||||
/**
|
||||
* 更新排课
|
||||
*/
|
||||
SchedulePlan updateSchedule(Long scheduleId, SchedulePlanUpdateRequest request);
|
||||
|
||||
/**
|
||||
* 取消排课
|
||||
*/
|
||||
void cancelSchedule(Long scheduleId);
|
||||
|
||||
/**
|
||||
* 根据 ID 获取排课
|
||||
*/
|
||||
SchedulePlan getScheduleById(Long scheduleId);
|
||||
}
|
||||
@ -6,6 +6,8 @@ import com.reading.platform.dto.request.TeacherCreateRequest;
|
||||
import com.reading.platform.dto.request.TeacherUpdateRequest;
|
||||
import com.reading.platform.entity.Teacher;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 教师服务接口
|
||||
*/
|
||||
@ -41,4 +43,9 @@ public interface TeacherService extends IService<Teacher> {
|
||||
*/
|
||||
void resetPassword(Long id, String newPassword);
|
||||
|
||||
/**
|
||||
* 根据 ID 列表查询教师
|
||||
*/
|
||||
List<Teacher> getTeachersByIds(List<Long> teacherIds);
|
||||
|
||||
}
|
||||
|
||||
@ -7,8 +7,14 @@ import com.reading.platform.common.enums.ErrorCode;
|
||||
import com.reading.platform.common.exception.BusinessException;
|
||||
import com.reading.platform.dto.request.LessonCreateRequest;
|
||||
import com.reading.platform.dto.request.LessonUpdateRequest;
|
||||
import com.reading.platform.dto.request.LessonProgressRequest;
|
||||
import com.reading.platform.dto.request.StudentRecordRequest;
|
||||
import com.reading.platform.entity.Lesson;
|
||||
import com.reading.platform.entity.LessonFeedback;
|
||||
import com.reading.platform.entity.StudentRecord;
|
||||
import com.reading.platform.mapper.LessonFeedbackMapper;
|
||||
import com.reading.platform.mapper.LessonMapper;
|
||||
import com.reading.platform.mapper.StudentRecordMapper;
|
||||
import com.reading.platform.service.LessonService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -17,6 +23,8 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@ -26,6 +34,8 @@ public class LessonServiceImpl extends ServiceImpl<LessonMapper, Lesson>
|
||||
implements LessonService {
|
||||
|
||||
private final LessonMapper lessonMapper;
|
||||
private final StudentRecordMapper studentRecordMapper;
|
||||
private final LessonFeedbackMapper lessonFeedbackMapper;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@ -183,4 +193,159 @@ public class LessonServiceImpl extends ServiceImpl<LessonMapper, Lesson>
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StudentRecord> getStudentRecords(Long lessonId) {
|
||||
log.debug("获取学生记录列表,课程 ID: {}", lessonId);
|
||||
|
||||
return studentRecordMapper.selectList(
|
||||
new LambdaQueryWrapper<StudentRecord>()
|
||||
.eq(StudentRecord::getLessonId, lessonId)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public StudentRecord saveStudentRecord(Long lessonId, Long studentId, StudentRecordRequest request) {
|
||||
log.info("保存学生记录,课程 ID: {}, 学生 ID: {}", lessonId, studentId);
|
||||
|
||||
// 先查询是否已存在
|
||||
StudentRecord record = studentRecordMapper.selectOne(
|
||||
new LambdaQueryWrapper<StudentRecord>()
|
||||
.eq(StudentRecord::getLessonId, lessonId)
|
||||
.eq(StudentRecord::getStudentId, studentId)
|
||||
);
|
||||
|
||||
if (record == null) {
|
||||
record = new StudentRecord();
|
||||
record.setLessonId(lessonId);
|
||||
record.setStudentId(studentId);
|
||||
record.setAttendance(request.getAttendance());
|
||||
record.setFocus(request.getFocus());
|
||||
record.setParticipation(request.getParticipation());
|
||||
record.setInterest(request.getInterest());
|
||||
record.setUnderstanding(request.getUnderstanding());
|
||||
record.setDomainAchievements(request.getDomainAchievements());
|
||||
record.setPerformance(request.getPerformance());
|
||||
record.setNotes(request.getNotes());
|
||||
studentRecordMapper.insert(record);
|
||||
log.info("学生记录创建成功,ID: {}", record.getId());
|
||||
} else {
|
||||
if (request.getAttendance() != null) {
|
||||
record.setAttendance(request.getAttendance());
|
||||
}
|
||||
if (request.getFocus() != null) {
|
||||
record.setFocus(request.getFocus());
|
||||
}
|
||||
if (request.getParticipation() != null) {
|
||||
record.setParticipation(request.getParticipation());
|
||||
}
|
||||
if (request.getInterest() != null) {
|
||||
record.setInterest(request.getInterest());
|
||||
}
|
||||
if (request.getUnderstanding() != null) {
|
||||
record.setUnderstanding(request.getUnderstanding());
|
||||
}
|
||||
if (request.getDomainAchievements() != null) {
|
||||
record.setDomainAchievements(request.getDomainAchievements());
|
||||
}
|
||||
if (request.getPerformance() != null) {
|
||||
record.setPerformance(request.getPerformance());
|
||||
}
|
||||
if (request.getNotes() != null) {
|
||||
record.setNotes(request.getNotes());
|
||||
}
|
||||
studentRecordMapper.updateById(record);
|
||||
log.info("学生记录更新成功,ID: {}", record.getId());
|
||||
}
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public List<StudentRecord> batchSaveStudentRecords(Long lessonId, List<StudentRecordRequest> requests) {
|
||||
log.info("批量保存学生记录,课程 ID: {}, 记录数量:{}", lessonId, requests.size());
|
||||
|
||||
List<StudentRecord> records = new ArrayList<>();
|
||||
for (StudentRecordRequest request : requests) {
|
||||
StudentRecord record = saveStudentRecord(lessonId, request.getStudentId(), request);
|
||||
records.add(record);
|
||||
}
|
||||
|
||||
return records;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LessonFeedback getLessonFeedback(Long lessonId) {
|
||||
log.debug("获取课程反馈,课程 ID: {}", lessonId);
|
||||
|
||||
return lessonFeedbackMapper.selectOne(
|
||||
new LambdaQueryWrapper<LessonFeedback>()
|
||||
.eq(LessonFeedback::getLessonId, lessonId)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public LessonFeedback submitFeedback(Long lessonId, Long teacherId, String content, Integer rating) {
|
||||
log.info("提交课程反馈,课程 ID: {}, 教师 ID: {}", lessonId, teacherId);
|
||||
|
||||
// 先查询是否已存在
|
||||
LessonFeedback feedback = lessonFeedbackMapper.selectOne(
|
||||
new LambdaQueryWrapper<LessonFeedback>()
|
||||
.eq(LessonFeedback::getLessonId, lessonId)
|
||||
.eq(LessonFeedback::getTeacherId, teacherId)
|
||||
);
|
||||
|
||||
if (feedback == null) {
|
||||
feedback = new LessonFeedback();
|
||||
feedback.setLessonId(lessonId);
|
||||
feedback.setTeacherId(teacherId);
|
||||
feedback.setContent(content);
|
||||
feedback.setRating(rating);
|
||||
lessonFeedbackMapper.insert(feedback);
|
||||
log.info("课程反馈创建成功,ID: {}", feedback.getId());
|
||||
} else {
|
||||
feedback.setContent(content);
|
||||
feedback.setRating(rating);
|
||||
lessonFeedbackMapper.updateById(feedback);
|
||||
log.info("课程反馈更新成功,ID: {}", feedback.getId());
|
||||
}
|
||||
|
||||
return feedback;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void saveLessonProgress(Long lessonId, LessonProgressRequest request) {
|
||||
log.info("保存课程进度,课程 ID: {}", lessonId);
|
||||
|
||||
Lesson lesson = getLessonById(lessonId);
|
||||
|
||||
if (request.getCurrentLessonId() != null) {
|
||||
lesson.setCurrentLessonId(request.getCurrentLessonId());
|
||||
}
|
||||
if (request.getCurrentStepId() != null) {
|
||||
lesson.setCurrentStepId(request.getCurrentStepId());
|
||||
}
|
||||
if (StringUtils.hasText(request.getLessonIds())) {
|
||||
lesson.setLessonIds(request.getLessonIds());
|
||||
}
|
||||
if (StringUtils.hasText(request.getCompletedLessonIds())) {
|
||||
lesson.setCompletedLessonIds(request.getCompletedLessonIds());
|
||||
}
|
||||
if (StringUtils.hasText(request.getProgressData())) {
|
||||
lesson.setProgressData(request.getProgressData());
|
||||
}
|
||||
|
||||
lessonMapper.updateById(lesson);
|
||||
log.info("课程进度保存成功,ID: {}", lessonId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lesson getLessonProgress(Long lessonId) {
|
||||
log.debug("获取课程进度,课程 ID: {}", lessonId);
|
||||
return getLessonById(lessonId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -213,4 +213,45 @@ public class StudentServiceImpl extends com.baomidou.mybatisplus.extension.servi
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Student> getStudentsByClassIds(List<Long> classIds, String keyword, Page<Student> page) {
|
||||
log.debug("根据班级 ID 列表查询学生,班级 ID 列表:{}", classIds);
|
||||
|
||||
// 获取班级中活跃的学生 ID
|
||||
List<StudentClassHistory> histories = studentClassHistoryMapper.selectList(
|
||||
new LambdaQueryWrapper<StudentClassHistory>()
|
||||
.in(StudentClassHistory::getClassId, classIds)
|
||||
.eq(StudentClassHistory::getStatus, "active")
|
||||
.isNull(StudentClassHistory::getEndDate)
|
||||
);
|
||||
|
||||
if (histories.isEmpty()) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
List<Long> studentIds = histories.stream()
|
||||
.map(StudentClassHistory::getStudentId)
|
||||
.distinct()
|
||||
.toList();
|
||||
|
||||
if (studentIds.isEmpty()) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.in(Student::getId, studentIds)
|
||||
.eq(Student::getStatus, "active");
|
||||
|
||||
if (StringUtils.hasText(keyword)) {
|
||||
wrapper.and(w -> w
|
||||
.like(Student::getName, keyword)
|
||||
.or()
|
||||
.like(Student::getStudentNo, keyword)
|
||||
);
|
||||
}
|
||||
wrapper.orderByAsc(Student::getName);
|
||||
|
||||
return studentMapper.selectPage(page, wrapper).getRecords();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,210 @@
|
||||
package com.reading.platform.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.reading.platform.common.enums.ErrorCode;
|
||||
import com.reading.platform.common.exception.BusinessException;
|
||||
import com.reading.platform.dto.request.CreateTaskFromTemplateRequest;
|
||||
import com.reading.platform.dto.request.TaskTemplateCreateRequest;
|
||||
import com.reading.platform.entity.Task;
|
||||
import com.reading.platform.entity.TaskTemplate;
|
||||
import com.reading.platform.entity.TaskTarget;
|
||||
import com.reading.platform.mapper.TaskMapper;
|
||||
import com.reading.platform.mapper.TaskTargetMapper;
|
||||
import com.reading.platform.mapper.TaskTemplateMapper;
|
||||
import com.reading.platform.service.TaskTemplateService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 任务模板服务实现
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TaskTemplateServiceImpl extends ServiceImpl<TaskTemplateMapper, TaskTemplate>
|
||||
implements TaskTemplateService {
|
||||
|
||||
private final TaskTemplateMapper taskTemplateMapper;
|
||||
private final TaskMapper taskMapper;
|
||||
private final TaskTargetMapper taskTargetMapper;
|
||||
|
||||
@Override
|
||||
public Page<TaskTemplate> getTemplates(Long tenantId, Integer pageNum, Integer pageSize, String type) {
|
||||
log.debug("获取模板列表,租户 ID: {}, 页码:{}, 类型:{}", tenantId, pageNum, type);
|
||||
|
||||
Page<TaskTemplate> page = new Page<>(pageNum, pageSize);
|
||||
LambdaQueryWrapper<TaskTemplate> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
wrapper.eq(TaskTemplate::getTenantId, tenantId);
|
||||
wrapper.eq(TaskTemplate::getIsPublic, 1);
|
||||
wrapper.eq(TaskTemplate::getStatus, "ACTIVE");
|
||||
|
||||
if (StringUtils.hasText(type)) {
|
||||
wrapper.eq(TaskTemplate::getType, type);
|
||||
}
|
||||
|
||||
wrapper.orderByDesc(TaskTemplate::getCreatedAt);
|
||||
|
||||
return taskTemplateMapper.selectPage(page, wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskTemplate getDefaultTemplate(Long tenantId, String type) {
|
||||
log.debug("获取默认模板,租户 ID: {}, 类型:{}", tenantId, type);
|
||||
|
||||
return taskTemplateMapper.selectOne(
|
||||
new LambdaQueryWrapper<TaskTemplate>()
|
||||
.eq(TaskTemplate::getTenantId, tenantId)
|
||||
.eq(TaskTemplate::getTaskType, type)
|
||||
.eq(TaskTemplate::getIsDefault, 1)
|
||||
.eq(TaskTemplate::getStatus, "ACTIVE")
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskTemplate getTemplateById(Long id) {
|
||||
TaskTemplate template = taskTemplateMapper.selectById(id);
|
||||
if (template == null) {
|
||||
throw new BusinessException(ErrorCode.DATA_NOT_FOUND, "模板不存在");
|
||||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public TaskTemplate createTemplate(Long tenantId, Long userId, TaskTemplateCreateRequest request) {
|
||||
log.info("创建任务模板,租户 ID: {}, 用户 ID: {}", tenantId, userId);
|
||||
|
||||
TaskTemplate template = new TaskTemplate();
|
||||
template.setTenantId(tenantId);
|
||||
template.setName(request.getName());
|
||||
template.setDescription(request.getDescription());
|
||||
template.setType(request.getType());
|
||||
template.setTaskType(request.getTaskType());
|
||||
template.setRelatedCourseId(request.getRelatedCourseId());
|
||||
template.setDefaultDuration(request.getDefaultDuration() != null ? request.getDefaultDuration() : 7);
|
||||
template.setIsDefault(request.getIsDefault() != null ? request.getIsDefault() : 0);
|
||||
template.setStatus("ACTIVE");
|
||||
template.setCreatedBy(userId);
|
||||
template.setContent(request.getContent());
|
||||
template.setIsPublic(request.getIsPublic() != null ? request.getIsPublic() : 0);
|
||||
|
||||
taskTemplateMapper.insert(template);
|
||||
log.info("任务模板创建成功,ID: {}", template.getId());
|
||||
return template;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public TaskTemplate updateTemplate(Long id, TaskTemplateCreateRequest request) {
|
||||
log.info("更新任务模板,ID: {}", id);
|
||||
|
||||
TaskTemplate template = getTemplateById(id);
|
||||
|
||||
if (StringUtils.hasText(request.getName())) {
|
||||
template.setName(request.getName());
|
||||
}
|
||||
if (request.getDescription() != null) {
|
||||
template.setDescription(request.getDescription());
|
||||
}
|
||||
if (request.getType() != null) {
|
||||
template.setType(request.getType());
|
||||
}
|
||||
if (request.getTaskType() != null) {
|
||||
template.setTaskType(request.getTaskType());
|
||||
}
|
||||
if (request.getRelatedCourseId() != null) {
|
||||
template.setRelatedCourseId(request.getRelatedCourseId());
|
||||
}
|
||||
if (request.getDefaultDuration() != null) {
|
||||
template.setDefaultDuration(request.getDefaultDuration());
|
||||
}
|
||||
if (request.getIsDefault() != null) {
|
||||
template.setIsDefault(request.getIsDefault());
|
||||
}
|
||||
if (request.getContent() != null) {
|
||||
template.setContent(request.getContent());
|
||||
}
|
||||
if (request.getIsPublic() != null) {
|
||||
template.setIsPublic(request.getIsPublic());
|
||||
}
|
||||
|
||||
taskTemplateMapper.updateById(template);
|
||||
log.info("任务模板更新成功,ID: {}", id);
|
||||
return template;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void deleteTemplate(Long id) {
|
||||
log.info("删除任务模板,ID: {}", id);
|
||||
|
||||
getTemplateById(id);
|
||||
taskTemplateMapper.deleteById(id);
|
||||
|
||||
log.info("任务模板删除成功,ID: {}", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Task createTaskFromTemplate(Long tenantId, Long userId, Long templateId, CreateTaskFromTemplateRequest request) {
|
||||
log.info("从模板创建任务,模板 ID: {}, 用户 ID: {}", templateId, userId);
|
||||
|
||||
// 获取模板
|
||||
TaskTemplate template = getTemplateById(templateId);
|
||||
|
||||
// 创建任务
|
||||
Task task = new Task();
|
||||
task.setTenantId(tenantId);
|
||||
task.setTitle(request.getTitle());
|
||||
task.setDescription(request.getDescription());
|
||||
task.setType(template.getTaskType());
|
||||
task.setCourseId(template.getRelatedCourseId());
|
||||
|
||||
// 解析日期
|
||||
if (StringUtils.hasText(request.getStartDate())) {
|
||||
try {
|
||||
task.setStartDate(LocalDate.parse(request.getStartDate()));
|
||||
} catch (Exception e) {
|
||||
log.warn("开始日期解析失败:{}", request.getStartDate());
|
||||
}
|
||||
}
|
||||
if (StringUtils.hasText(request.getEndDate())) {
|
||||
try {
|
||||
task.setDueDate(LocalDate.parse(request.getEndDate()));
|
||||
} catch (Exception e) {
|
||||
log.warn("截止日期解析失败:{}", request.getEndDate());
|
||||
}
|
||||
}
|
||||
|
||||
task.setStatus("pending");
|
||||
task.setCreatorId(userId);
|
||||
task.setCreatorRole("TEACHER");
|
||||
|
||||
taskMapper.insert(task);
|
||||
log.info("任务创建成功,ID: {}", task.getId());
|
||||
|
||||
// 创建任务目标
|
||||
if (request.getTargetIds() != null && !request.getTargetIds().isEmpty()) {
|
||||
for (Long targetId : request.getTargetIds()) {
|
||||
TaskTarget target = new TaskTarget();
|
||||
target.setTaskId(task.getId());
|
||||
target.setTargetType(request.getTargetType());
|
||||
target.setTargetId(targetId);
|
||||
taskTargetMapper.insert(target);
|
||||
}
|
||||
log.info("任务目标创建完成,任务 ID: {}", task.getId());
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,101 @@
|
||||
package com.reading.platform.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.reading.platform.entity.Lesson;
|
||||
import com.reading.platform.entity.LessonFeedback;
|
||||
import com.reading.platform.mapper.LessonFeedbackMapper;
|
||||
import com.reading.platform.mapper.LessonMapper;
|
||||
import com.reading.platform.service.TeacherFeedbackService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 教师端反馈服务实现
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TeacherFeedbackServiceImpl implements TeacherFeedbackService {
|
||||
|
||||
private final LessonFeedbackMapper lessonFeedbackMapper;
|
||||
private final LessonMapper lessonMapper;
|
||||
|
||||
@Override
|
||||
public Page<LessonFeedback> getTeacherFeedbacks(Long teacherId, Integer pageNum, Integer pageSize) {
|
||||
log.debug("获取教师反馈列表,教师 ID: {}, 页码:{}", teacherId, pageNum);
|
||||
|
||||
Page<LessonFeedback> page = new Page<>(pageNum, pageSize);
|
||||
|
||||
// 先获取教师的所有课程
|
||||
List<Lesson> lessons = lessonMapper.selectList(
|
||||
new LambdaQueryWrapper<Lesson>()
|
||||
.eq(Lesson::getTeacherId, teacherId)
|
||||
);
|
||||
|
||||
if (lessons.isEmpty()) {
|
||||
return page;
|
||||
}
|
||||
|
||||
List<Long> lessonIds = lessons.stream().map(Lesson::getId).collect(Collectors.toList());
|
||||
|
||||
LambdaQueryWrapper<LessonFeedback> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.in(LessonFeedback::getLessonId, lessonIds)
|
||||
.orderByDesc(LessonFeedback::getCreatedAt);
|
||||
|
||||
return lessonFeedbackMapper.selectPage(page, wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getFeedbackStats(Long teacherId) {
|
||||
log.debug("获取教师反馈统计,教师 ID: {}", teacherId);
|
||||
|
||||
Map<String, Object> stats = new HashMap<>();
|
||||
|
||||
// 获取教师的所有课程
|
||||
List<Lesson> lessons = lessonMapper.selectList(
|
||||
new LambdaQueryWrapper<Lesson>()
|
||||
.eq(Lesson::getTeacherId, teacherId)
|
||||
);
|
||||
|
||||
if (lessons.isEmpty()) {
|
||||
stats.put("totalFeedbacks", 0);
|
||||
stats.put("avgRating", 0.0);
|
||||
stats.put("byRating", new HashMap<>());
|
||||
return stats;
|
||||
}
|
||||
|
||||
List<Long> lessonIds = lessons.stream().map(Lesson::getId).collect(Collectors.toList());
|
||||
|
||||
// 获取反馈列表
|
||||
List<LessonFeedback> feedbacks = lessonFeedbackMapper.selectList(
|
||||
new LambdaQueryWrapper<LessonFeedback>()
|
||||
.in(LessonFeedback::getLessonId, lessonIds)
|
||||
);
|
||||
|
||||
stats.put("totalFeedbacks", feedbacks.size());
|
||||
|
||||
// 计算平均评分
|
||||
double avgRating = feedbacks.stream()
|
||||
.filter(f -> f.getRating() != null)
|
||||
.mapToInt(LessonFeedback::getRating)
|
||||
.average()
|
||||
.orElse(0.0);
|
||||
stats.put("avgRating", avgRating);
|
||||
|
||||
// 按评分分组统计
|
||||
Map<Integer, Long> byRating = feedbacks.stream()
|
||||
.filter(f -> f.getRating() != null)
|
||||
.collect(Collectors.groupingBy(LessonFeedback::getRating, Collectors.counting()));
|
||||
stats.put("byRating", byRating);
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,199 @@
|
||||
package com.reading.platform.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.reading.platform.common.enums.ErrorCode;
|
||||
import com.reading.platform.common.exception.BusinessException;
|
||||
import com.reading.platform.dto.request.SchedulePlanCreateRequest;
|
||||
import com.reading.platform.dto.request.SchedulePlanUpdateRequest;
|
||||
import com.reading.platform.dto.response.SchedulePlanResponse;
|
||||
import com.reading.platform.dto.response.TimetableResponse;
|
||||
import com.reading.platform.entity.SchedulePlan;
|
||||
import com.reading.platform.mapper.SchedulePlanMapper;
|
||||
import com.reading.platform.service.TeacherScheduleService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 教师端排课服务实现
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TeacherScheduleServiceImpl extends ServiceImpl<SchedulePlanMapper, SchedulePlan>
|
||||
implements TeacherScheduleService {
|
||||
|
||||
private final SchedulePlanMapper schedulePlanMapper;
|
||||
|
||||
@Override
|
||||
public Page<SchedulePlan> getTeacherSchedules(Long teacherId, Integer pageNum, Integer pageSize,
|
||||
LocalDate startDate, LocalDate endDate) {
|
||||
Page<SchedulePlan> page = new Page<>(pageNum, pageSize);
|
||||
LambdaQueryWrapper<SchedulePlan> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
wrapper.eq(SchedulePlan::getTeacherId, teacherId);
|
||||
|
||||
if (startDate != null) {
|
||||
wrapper.ge(SchedulePlan::getScheduledDate, startDate);
|
||||
}
|
||||
if (endDate != null) {
|
||||
wrapper.le(SchedulePlan::getScheduledDate, endDate);
|
||||
}
|
||||
|
||||
wrapper.orderByAsc(SchedulePlan::getScheduledDate);
|
||||
|
||||
return schedulePlanMapper.selectPage(page, wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TimetableResponse> getTimetable(Long teacherId, LocalDate startDate, LocalDate endDate) {
|
||||
LambdaQueryWrapper<SchedulePlan> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(SchedulePlan::getTeacherId, teacherId);
|
||||
wrapper.eq(SchedulePlan::getStatus, "ACTIVE");
|
||||
|
||||
if (startDate != null) {
|
||||
wrapper.ge(SchedulePlan::getScheduledDate, startDate);
|
||||
}
|
||||
if (endDate != null) {
|
||||
wrapper.le(SchedulePlan::getScheduledDate, endDate);
|
||||
}
|
||||
|
||||
wrapper.orderByAsc(SchedulePlan::getScheduledDate);
|
||||
|
||||
List<SchedulePlan> schedules = schedulePlanMapper.selectList(wrapper);
|
||||
|
||||
// 按日期分组
|
||||
return schedules.stream()
|
||||
.collect(Collectors.groupingBy(SchedulePlan::getScheduledDate))
|
||||
.entrySet().stream()
|
||||
.map(entry -> {
|
||||
LocalDate date = entry.getKey();
|
||||
List<SchedulePlan> daySchedules = entry.getValue();
|
||||
return TimetableResponse.builder()
|
||||
.date(date)
|
||||
.weekDay(date != null ? date.getDayOfWeek().getValue() : null)
|
||||
.schedules(daySchedules.stream()
|
||||
.map(schedule -> SchedulePlanResponse.builder()
|
||||
.id(schedule.getId())
|
||||
.name(schedule.getName())
|
||||
.classId(schedule.getClassId())
|
||||
.courseId(schedule.getCourseId())
|
||||
.teacherId(schedule.getTeacherId())
|
||||
.scheduledDate(schedule.getScheduledDate())
|
||||
.scheduledTime(schedule.getScheduledTime())
|
||||
.weekDay(schedule.getWeekDay())
|
||||
.repeatType(schedule.getRepeatType())
|
||||
.source(schedule.getSource())
|
||||
.note(schedule.getNote())
|
||||
.status(schedule.getStatus())
|
||||
.build())
|
||||
.collect(Collectors.toList()))
|
||||
.build();
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SchedulePlan> getTodaySchedules(Long teacherId) {
|
||||
LocalDate today = LocalDate.now();
|
||||
LambdaQueryWrapper<SchedulePlan> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(SchedulePlan::getTeacherId, teacherId);
|
||||
wrapper.eq(SchedulePlan::getScheduledDate, today);
|
||||
wrapper.eq(SchedulePlan::getStatus, "ACTIVE");
|
||||
wrapper.orderByAsc(SchedulePlan::getScheduledTime);
|
||||
|
||||
return schedulePlanMapper.selectList(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchedulePlan getScheduleById(Long scheduleId) {
|
||||
SchedulePlan schedulePlan = schedulePlanMapper.selectById(scheduleId);
|
||||
if (schedulePlan == null) {
|
||||
throw new BusinessException(ErrorCode.DATA_NOT_FOUND, "排课计划不存在");
|
||||
}
|
||||
return schedulePlan;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public SchedulePlan createSchedule(Long tenantId, Long teacherId, SchedulePlanCreateRequest request) {
|
||||
SchedulePlan schedulePlan = new SchedulePlan();
|
||||
schedulePlan.setTenantId(tenantId);
|
||||
schedulePlan.setName(request.getName());
|
||||
schedulePlan.setClassId(request.getClassId());
|
||||
schedulePlan.setCourseId(request.getCourseId());
|
||||
schedulePlan.setTeacherId(request.getTeacherId() != null ? request.getTeacherId() : teacherId);
|
||||
schedulePlan.setScheduledDate(request.getScheduledDate());
|
||||
schedulePlan.setScheduledTime(request.getScheduledTime());
|
||||
schedulePlan.setWeekDay(request.getWeekDay());
|
||||
schedulePlan.setRepeatType(request.getRepeatType() != null ? request.getRepeatType() : "NONE");
|
||||
schedulePlan.setRepeatEndDate(request.getRepeatEndDate());
|
||||
schedulePlan.setSource(request.getSource() != null ? request.getSource() : "TEACHER");
|
||||
schedulePlan.setNote(request.getNote());
|
||||
schedulePlan.setStatus("ACTIVE");
|
||||
|
||||
schedulePlanMapper.insert(schedulePlan);
|
||||
log.info("排课创建成功:id={}, name={}, scheduledDate={}",
|
||||
schedulePlan.getId(), schedulePlan.getName(), schedulePlan.getScheduledDate());
|
||||
return schedulePlan;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public SchedulePlan updateSchedule(Long scheduleId, SchedulePlanUpdateRequest request) {
|
||||
SchedulePlan schedulePlan = getScheduleById(scheduleId);
|
||||
|
||||
if (StringUtils.hasText(request.getName())) {
|
||||
schedulePlan.setName(request.getName());
|
||||
}
|
||||
if (request.getCourseId() != null) {
|
||||
schedulePlan.setCourseId(request.getCourseId());
|
||||
}
|
||||
if (request.getTeacherId() != null) {
|
||||
schedulePlan.setTeacherId(request.getTeacherId());
|
||||
}
|
||||
if (request.getScheduledDate() != null) {
|
||||
schedulePlan.setScheduledDate(request.getScheduledDate());
|
||||
}
|
||||
if (StringUtils.hasText(request.getScheduledTime())) {
|
||||
schedulePlan.setScheduledTime(request.getScheduledTime());
|
||||
}
|
||||
if (request.getWeekDay() != null) {
|
||||
schedulePlan.setWeekDay(request.getWeekDay());
|
||||
}
|
||||
if (StringUtils.hasText(request.getRepeatType())) {
|
||||
schedulePlan.setRepeatType(request.getRepeatType());
|
||||
}
|
||||
if (request.getRepeatEndDate() != null) {
|
||||
schedulePlan.setRepeatEndDate(request.getRepeatEndDate());
|
||||
}
|
||||
if (StringUtils.hasText(request.getStatus())) {
|
||||
schedulePlan.setStatus(request.getStatus());
|
||||
}
|
||||
if (request.getNote() != null) {
|
||||
schedulePlan.setNote(request.getNote());
|
||||
}
|
||||
|
||||
schedulePlanMapper.updateById(schedulePlan);
|
||||
log.info("排课更新成功:id={}", scheduleId);
|
||||
return schedulePlan;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void cancelSchedule(Long scheduleId) {
|
||||
SchedulePlan schedulePlan = getScheduleById(scheduleId);
|
||||
schedulePlan.setStatus("CANCELLED");
|
||||
schedulePlanMapper.updateById(schedulePlan);
|
||||
log.info("排课取消成功:id={}", scheduleId);
|
||||
}
|
||||
}
|
||||
@ -16,6 +16,8 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 教师服务实现类
|
||||
*/
|
||||
@ -163,4 +165,19 @@ public class TeacherServiceImpl extends com.baomidou.mybatisplus.extension.servi
|
||||
log.info("密码重置成功,ID: {}", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Teacher> getTeachersByIds(List<Long> teacherIds) {
|
||||
log.debug("根据 ID 列表查询教师,ID 列表:{}", teacherIds);
|
||||
|
||||
if (teacherIds == null || teacherIds.isEmpty()) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
LambdaQueryWrapper<Teacher> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.in(Teacher::getId, teacherIds)
|
||||
.eq(Teacher::getStatus, "active");
|
||||
|
||||
return teacherMapper.selectList(wrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -27,11 +27,14 @@ spring:
|
||||
min-idle: 4
|
||||
|
||||
flyway:
|
||||
enabled: true
|
||||
enabled: true # Flyway 已修复,重新启用
|
||||
locations: classpath:db/migration
|
||||
clean-disabled: true
|
||||
clean-disabled: false
|
||||
validate-on-migrate: false
|
||||
baseline-on-migrate: false
|
||||
baseline-on-migrate: true
|
||||
baseline-version: 0
|
||||
repair-on-migrate: true
|
||||
out-of-order: true
|
||||
|
||||
# Druid 连接池配置(开发环境)
|
||||
druid:
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
-- =====================================================
|
||||
-- 幼儿园阅读平台数据库扩展脚本
|
||||
-- 版本:V13
|
||||
-- 创建时间:2026-03-16
|
||||
-- 描述:添加教师端相关表的缺失字段
|
||||
-- 状态:已手动执行,字段已存在
|
||||
-- =====================================================
|
||||
|
||||
-- 此迁移已执行,所有字段已存在于数据库中
|
||||
-- 如果未来需要重新初始化数据库,请确保此脚本在 V1__init_schema.sql 之后正确执行
|
||||
|
||||
-- 已添加的字段列表:
|
||||
-- 1. schedule_plan 表:course_id, teacher_id, scheduled_date, scheduled_time, week_day, repeat_type, repeat_end_date, source, note, reminder_sent, reminder_sent_at
|
||||
-- 2. lesson_feedback 表:design_quality, participation, goal_achievement, step_feedbacks, pros, suggestions, activities_done
|
||||
-- 3. task_template 表:task_type, related_course_id, default_duration, is_default, status, created_by
|
||||
-- 4. student_record 表:focus, participation, interest, understanding, domain_achievements
|
||||
-- 5. lesson 表:schedule_plan_id, planned_datetime, start_datetime, end_datetime, actual_duration, overall_rating, participation_rating, completion_note, progress_data, current_lesson_id, current_step_id, lesson_ids, completed_lesson_ids
|
||||
-- 6. class_teacher 表:is_primary
|
||||
-- 7. clazz 表:lesson_count
|
||||
-- 8. teacher 表:lesson_count, feedback_count
|
||||
-- 9. course 表:usage_count, teacher_count, avg_rating
|
||||
|
||||
SELECT 'V13 迁移已存在,跳过执行' AS status;
|
||||
@ -0,0 +1,9 @@
|
||||
-- =====================================================
|
||||
-- 幼儿园阅读平台数据库修复脚本
|
||||
-- 版本:V14
|
||||
-- 描述:修复 teacher 表课时统计字段
|
||||
-- 状态:已执行,字段已存在
|
||||
-- =====================================================
|
||||
|
||||
-- 此迁移已执行,所有字段已存在于数据库中
|
||||
SELECT 'V14 迁移已存在,跳过执行' AS status;
|
||||
@ -0,0 +1,9 @@
|
||||
-- =====================================================
|
||||
-- 幼儿园阅读平台数据库修复脚本
|
||||
-- 版本:V15
|
||||
-- 描述:手动修复迁移
|
||||
-- 状态:已执行,字段已存在
|
||||
-- =====================================================
|
||||
|
||||
-- 此迁移已执行,所有字段已存在于数据库中
|
||||
SELECT 'V15 迁移已存在,跳过执行' AS status;
|
||||
Loading…
Reference in New Issue
Block a user