fix: 教培

dev-tmp1
zhanglei 2026-08-24 15:06:50 +08:00
parent 1329ddc81a
commit 49274de68a
10 changed files with 183 additions and 3 deletions

View File

@ -7,6 +7,7 @@ import io.swagger.annotations.ApiParam;
import org.qinan.cedu.model.dto.ClassCourseDTO;
import org.qinan.cedu.model.query.ClassCoursePageQuery;
import org.qinan.cedu.model.vo.ClassCourseVO;
import org.qinan.cedu.model.vo.ExamStatisticsAndRecordVO;
import org.qinan.cedu.service.ClassCourseService;
import org.qinan.safetyeval.client.dto.PageResponse;
import org.qinan.safetyeval.client.dto.SingleResponse;
@ -67,4 +68,18 @@ public class ClassCourseController {
IPage<ClassCourseVO> page = classCourseService.pageQuery(query);
return PageResponse.of(page.getRecords(), page.getTotal());
}
@ApiOperation("我的课程")
@GetMapping("/myCoursePage")
public SingleResponse<List<ClassCourseVO>> myCoursePage() {
List<ClassCourseVO> list = classCourseService.myCoursePage();
return SingleResponse.success(list);
}
@ApiOperation("成绩查询")
@GetMapping("/scoreQuery")
public SingleResponse<ExamStatisticsAndRecordVO> scoreQuery() {
ExamStatisticsAndRecordVO examStatisticsAndRecordVO = classCourseService.scoreQuery();
return SingleResponse.success(examStatisticsAndRecordVO);
}
}

View File

@ -1,5 +1,6 @@
package org.qinan.cedu.model.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -55,4 +56,7 @@ public class ClassStudentDTO {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime entryTime;
@TableField("student_id")
private String studentId;
}

View File

@ -63,4 +63,7 @@ public class ClassStudentDO extends BaseEntity {
@TableField("entry_time")
private LocalDateTime entryTime;
@TableField("student_id")
private String studentId;
}

View File

@ -1,10 +1,13 @@
package org.qinan.cedu.model.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
/**
@ -38,4 +41,18 @@ public class ClassCourseVO extends BaseVO {
@ApiModelProperty("已完成学员数")
private Long completedCount;
@ApiModelProperty("app: 学员完成状态: 0未完成,1未学习,2完成")
private Integer completed;
@ApiModelProperty("培训结束日期")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime endDate;
@ApiModelProperty("app: 班级名称")
private String className;
@ApiModelProperty("归属课件")
private List<CoursewareManagementVO> coursewareList;
}

View File

@ -53,4 +53,10 @@ public class ClassStudentExamRecordVO extends BaseVO {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime endTime;
@ApiModelProperty("app: 班级名称")
private String className;
@ApiModelProperty("app: 考试时长分钟")
private Integer examDurationMinutes;
}

View File

@ -1,5 +1,6 @@
package org.qinan.cedu.model.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -54,4 +55,7 @@ public class ClassStudentVO extends BaseVO {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime entryTime;
@TableField("student_id")
private String studentId;
}

View File

@ -0,0 +1,26 @@
package org.qinan.cedu.model.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
*
* @TableName class_student_exam_record
*/
@Data
public class ExamStatisticsAndRecordVO {
// 参加考试次数
@ApiModelProperty("参加考试次数")
private int totalExams;
// 合格次数
@ApiModelProperty("合格次数")
private int passedExams;
// 不合格次数
@ApiModelProperty("不合格次数")
private int failedExams;
@ApiModelProperty("考试记录")
private List<ClassStudentExamRecordVO> classStudentExamRecordVO;
}

View File

@ -6,6 +6,7 @@ import org.qinan.cedu.model.dto.ClassCourseDTO;
import org.qinan.cedu.model.entity.ClassCourseDO;
import org.qinan.cedu.model.query.ClassCoursePageQuery;
import org.qinan.cedu.model.vo.ClassCourseVO;
import org.qinan.cedu.model.vo.ExamStatisticsAndRecordVO;
import java.util.List;
@ -31,4 +32,9 @@ public interface ClassCourseService extends IService<ClassCourseDO> {
boolean updateCourse(ClassCourseDTO dto);
boolean deleteById(Long id);
List<ClassCourseVO> myCoursePage();
ExamStatisticsAndRecordVO scoreQuery();
}

View File

@ -1,25 +1,33 @@
package org.qinan.cedu.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.qinan.cedu.convertor.ClassCourseConvertor;
import org.qinan.cedu.convertor.ClassStudentExamRecordConvertor;
import org.qinan.cedu.convertor.CourseRelCoursewareConvertor;
import org.qinan.cedu.convertor.CoursewareManagementConvertor;
import org.qinan.cedu.enums.DeleteEnum;
import org.qinan.cedu.mapper.ClassCourseMapper;
import org.qinan.cedu.mapper.ClassStudentLearningRecordMapper;
import org.qinan.cedu.mapper.*;
import org.qinan.cedu.model.dto.ClassCourseDTO;
import org.qinan.cedu.model.entity.ClassCourseDO;
import org.qinan.cedu.model.entity.*;
import org.qinan.cedu.model.query.ClassCoursePageQuery;
import org.qinan.cedu.model.vo.ClassCourseVO;
import org.qinan.cedu.model.vo.ClassStudentExamRecordVO;
import org.qinan.cedu.model.vo.CourseStudentStatVO;
import org.qinan.cedu.model.vo.ExamStatisticsAndRecordVO;
import org.qinan.cedu.service.ClassCourseService;
import org.qinan.safetyeval.infrastructure.adapter.auth.AuthUserContextAdapter;
import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@ -37,6 +45,22 @@ public class ClassCourseServiceImpl extends ServiceImpl<ClassCourseMapper, Class
@Autowired
private ClassStudentLearningRecordMapper learningRecordMapper;
@Autowired
private ClassStudentMapper classStudentMapper;
@Autowired
private ClassManagementMapper classManagementMapper;
@Autowired
private CourseRelCoursewareConvertor courseRelCoursewareConvertor;
@Autowired
private CourseRelCoursewareMapper courseRelCoursewareMapper;
@Autowired
private CoursewareManagementMapper coursewareManagementMapper;
@Autowired
private CoursewareManagementConvertor coursewareManagementConvertor;
@Autowired
private ClassStudentExamRecordMapper classStudentExamRecordMapper;
@Autowired
private ClassStudentExamRecordConvertor classStudentExamRecordConvertor;
@Override
public IPage<ClassCourseVO> pageQuery(ClassCoursePageQuery query) {
@ -127,4 +151,78 @@ public class ClassCourseServiceImpl extends ServiceImpl<ClassCourseMapper, Class
public boolean deleteById(Long id) {
return baseMapper.deleteById(id) > 0;
}
@Override
public List<ClassCourseVO> myCoursePage() {
List<Long> classId = classStudentMapper.selectList(new LambdaQueryWrapper<ClassStudentDO>()
.eq(ClassStudentDO::getStudentId, AuthUserContextAdapter.getCurrentUserId()))
.stream().map(ClassStudentDO::getClassId).distinct().collect(Collectors.toList());
List<ClassCourseDO> classCourseDOS = baseMapper.selectList(new LambdaQueryWrapper<ClassCourseDO>()
.eq(ClassCourseDO::getClassId, CollectionUtils.isEmpty(classId) ? Collections.singletonList(0L) : classId)
.eq(ClassCourseDO::getDeleteEnum, DeleteEnum.FALSE.getCode()));
//查询班级
Map<Long, ClassManagementDO> collectClassMap = classManagementMapper.selectList(new LambdaQueryWrapper<ClassManagementDO>()
.in(ClassManagementDO::getId, CollectionUtils.isEmpty(classId) ? Collections.singletonList(0L) : classId))
.stream().collect(Collectors.toMap(ClassManagementDO::getId, Function.identity()));
return classCourseDOS.stream().map(item -> {
ClassCourseVO classCourseVO = classCourseConvertor.convertEToVo(item);
List<ClassStudentLearningRecordDO> classStudentLearningRecordDOS = learningRecordMapper.selectList(new LambdaQueryWrapper<ClassStudentLearningRecordDO>()
.eq(ClassStudentLearningRecordDO::getStudentId, AuthUserContextAdapter.getCurrentUserId())
.eq(ClassStudentLearningRecordDO::getCourseId, item.getId())
.eq(ClassStudentLearningRecordDO::getClassId, item.getClassId()));
// getStudyStatus()都为2就是完成, 否则为未完成
int completed = classStudentLearningRecordDOS.stream().allMatch(record -> record.getStudyStatus() != null && record.getStudyStatus() == 2) ? 2 : 0;
ClassManagementDO classManagementDO = collectClassMap.get(item.getClassId());
if (classManagementDO != null) {
classCourseVO.setClassName(classManagementDO.getClassName());
LocalDateTime endDate = classManagementDO.getEndDate();
if (classManagementDO.getDelayTime() != null && classManagementDO.getDelayTime().isAfter(endDate)) {
endDate = classManagementDO.getDelayTime();
}
classCourseVO.setEndDate(endDate);
}
if (completed == 0) {
LocalDateTime endDate = classCourseVO.getEndDate();
if (LocalDateTime.now().isBefore(endDate)) {
classCourseVO.setCompleted(1);
}
}
classCourseVO.setCompleted(completed);
// 查询课件
classCourseVO.setCoursewareList(coursewareManagementMapper.selectBatchIds(item.getCoursewareId())
.stream().map(coursewareManagementConvertor::convertEToVo).collect(Collectors.toList()));
return classCourseVO;
}).collect(Collectors.toList());
}
@Override
public ExamStatisticsAndRecordVO scoreQuery() {
ExamStatisticsAndRecordVO examStatisticsAndRecordVO = new ExamStatisticsAndRecordVO();
List<Long> classId = classStudentMapper.selectList(new LambdaQueryWrapper<ClassStudentDO>()
.eq(ClassStudentDO::getStudentId, AuthUserContextAdapter.getCurrentUserId()))
.stream().map(ClassStudentDO::getClassId).distinct().collect(Collectors.toList());
List<ClassStudentExamRecordDO> classStudentExamRecordDOS = classStudentExamRecordMapper.selectList(new LambdaQueryWrapper<ClassStudentExamRecordDO>()
.eq(ClassStudentExamRecordDO::getStudentId, AuthUserContextAdapter.getCurrentUserId())
.in(ClassStudentExamRecordDO::getClassId, CollectionUtils.isEmpty(classId) ? Collections.singletonList(0L) : classId));
//查询班级
Map<Long, ClassManagementDO> collectClassMap = classManagementMapper.selectList(new LambdaQueryWrapper<ClassManagementDO>()
.in(ClassManagementDO::getId, CollectionUtils.isEmpty(classId) ? Collections.singletonList(0L) : classId))
.stream().collect(Collectors.toMap(ClassManagementDO::getId, Function.identity()));
examStatisticsAndRecordVO.setClassStudentExamRecordVO(classStudentExamRecordDOS.stream().map(item -> {
ClassStudentExamRecordVO classStudentExamRecordVO = classStudentExamRecordConvertor.convertEToVo(item);
ClassManagementDO classManagementDO = collectClassMap.get(item.getClassId());
if (classManagementDO != null) {
classStudentExamRecordVO.setClassName(classManagementDO.getClassName());
}
// 结束时间 - 开始时间 = 时长
Duration duration = Duration.between(item.getStartTime(), item.getEndTime());
classStudentExamRecordVO.setExamDurationMinutes((int) duration.toMinutes());
return classStudentExamRecordVO;
}).collect(Collectors.toList()));
// 设置: 参加考试次数, 合格次数, 不合格次数 @ApiModelProperty("是否通过0-未通过1-通过)")passed
examStatisticsAndRecordVO.setTotalExams(classStudentExamRecordDOS.size());
examStatisticsAndRecordVO.setPassedExams((int) classStudentExamRecordDOS.stream().filter(record -> record.getPassed() != null && record.getPassed() == 1).count());
examStatisticsAndRecordVO.setFailedExams((int) classStudentExamRecordDOS.stream().filter(record -> record.getPassed() != null && record.getPassed() == 0).count());
return examStatisticsAndRecordVO;
}
}

View File

@ -80,6 +80,7 @@ create table class_student
study_status int default 0 null comment '学习状态0-未学习1-学习中2-已学完3-已完成',
exam_status int default 0 null comment '考试状态0-不考试1-待考试2-考试未通过3-考试通过4-未参加',
entry_time datetime null comment '入班时间',
student_id varchar(20) null comment '学员(来源id)',
delete_enum varchar(32) null comment '删除标识true false',
remarks varchar(255) null comment '备注',
create_name varchar(50) null comment '创建人姓名',