fix: 教培

dev-tmp1
zhanglei 2026-08-25 11:04:19 +08:00
parent 397c04e154
commit 76722c58e4
11 changed files with 113 additions and 9 deletions

View File

@ -69,7 +69,7 @@ public class ClassCourseController {
return PageResponse.of(page.getRecords(), page.getTotal()); return PageResponse.of(page.getRecords(), page.getTotal());
} }
@ApiOperation("我的课程") @ApiOperation("我的学习")
@GetMapping("/myCoursePage") @GetMapping("/myCoursePage")
public SingleResponse<List<ClassCourseVO>> myCoursePage() { public SingleResponse<List<ClassCourseVO>> myCoursePage() {
List<ClassCourseVO> list = classCourseService.myCoursePage(); List<ClassCourseVO> list = classCourseService.myCoursePage();

View File

@ -54,4 +54,7 @@ public class ClassStudentExamRecordDTO {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime endTime; private LocalDateTime endTime;
@ApiModelProperty("正确题数")
private Integer correctCount;
} }

View File

@ -54,4 +54,5 @@ public class ClassStudentExamRecordDO extends BaseEntity {
@TableField("end_time") @TableField("end_time")
private LocalDateTime endTime; private LocalDateTime endTime;
private Integer correctCount;
} }

View File

@ -22,4 +22,7 @@ public class ClassStudentExamRecordPageQuery extends BasePageQuery {
@ApiModelProperty("是否通过0-未通过1-通过)") @ApiModelProperty("是否通过0-未通过1-通过)")
private Integer passed; private Integer passed;
@ApiModelProperty("试卷名称")
private String paperName;
} }

View File

@ -40,6 +40,8 @@ public class ClassStudentExamRecordVO extends BaseVO {
@ApiModelProperty("错误题数") @ApiModelProperty("错误题数")
private Integer wrongCount; private Integer wrongCount;
@ApiModelProperty("正确题数")
private Integer correctCount;
@ApiModelProperty("正确率(百分比)") @ApiModelProperty("正确率(百分比)")
private BigDecimal accuracy; private BigDecimal accuracy;

View File

@ -22,9 +22,11 @@ import org.qinan.safetyeval.infrastructure.adapter.auth.AuthUserContextAdapter;
import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults; import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.time.Duration; import java.time.Duration;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Collections; import java.util.Collections;
@ -107,10 +109,13 @@ public class ClassCourseServiceImpl extends ServiceImpl<ClassCourseMapper, Class
.eq(ClassCourseDO::getId, id) .eq(ClassCourseDO::getId, id)
.eq(ClassCourseDO::getDeleteEnum, DeleteEnum.FALSE.getCode()) .eq(ClassCourseDO::getDeleteEnum, DeleteEnum.FALSE.getCode())
.one(); .one();
return classCourseConvertor.convertEToVo(entity); ClassCourseVO classCourseVO = classCourseConvertor.convertEToVo(entity);
fillStudentCount(Collections.singletonList(classCourseVO), Long.valueOf(classCourseVO.getClassId()));
return classCourseVO;
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public boolean saveCourse(ClassCourseDTO dto) { public boolean saveCourse(ClassCourseDTO dto) {
return this.save(buildEntity(dto)); return this.save(buildEntity(dto));
} }
@ -122,6 +127,7 @@ public class ClassCourseServiceImpl extends ServiceImpl<ClassCourseMapper, Class
* @return * @return
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class)
public boolean saveCourseBatch(List<ClassCourseDTO> dtoList) { public boolean saveCourseBatch(List<ClassCourseDTO> dtoList) {
List<ClassCourseDO> entities = dtoList.stream().map(this::buildEntity).collect(Collectors.toList()); List<ClassCourseDO> entities = dtoList.stream().map(this::buildEntity).collect(Collectors.toList());
return this.saveBatch(entities); return this.saveBatch(entities);
@ -133,17 +139,62 @@ public class ClassCourseServiceImpl extends ServiceImpl<ClassCourseMapper, Class
* @param dto * @param dto
* @return * @return
*/ */
private ClassCourseDO buildEntity(ClassCourseDTO dto) { public ClassCourseDO buildEntity(ClassCourseDTO dto) {
ClassCourseDO entity = classCourseConvertor.convertDtoToE(dto); ClassCourseDO entity = classCourseConvertor.convertDtoToE(dto);
InsertFieldDefaults.apply(entity); InsertFieldDefaults.apply(entity);
entity.setUpdateTime(LocalDateTime.now()); entity.setUpdateTime(LocalDateTime.now());
List<CoursewareManagementDO> coursewareManagementDOS = coursewareManagementMapper.selectBatchIds(CollectionUtils.isEmpty(dto.getCoursewareId()) ? Collections.singletonList(0L) : dto.getCoursewareId());
// 判空
if (entity.getRequiredTotalHours() != null) {
entity.setRequiredTotalHours(entity.getRequiredTotalHours().add(coursewareManagementDOS.stream().map(CoursewareManagementDO::getClassHourDuration).reduce(BigDecimal.ZERO, BigDecimal::add)));
} else {
entity.setRequiredTotalHours(coursewareManagementDOS.stream().map(CoursewareManagementDO::getClassHourDuration).reduce(BigDecimal.ZERO, BigDecimal::add));
}
if (entity.getVideoDuration() != null) {
entity.setVideoDuration(entity.getVideoDuration().add(coursewareManagementDOS.stream().map(CoursewareManagementDO::getCreditHours).reduce(BigDecimal.ZERO, BigDecimal::add)));
} else {
entity.setVideoDuration(coursewareManagementDOS.stream().map(CoursewareManagementDO::getCreditHours).reduce(BigDecimal.ZERO, BigDecimal::add));
}
// 学员回填数据(要求学时)
for (ClassStudentDO classStudentDO : classStudentMapper.selectList(new LambdaQueryWrapper<ClassStudentDO>()
.eq(ClassStudentDO::getClassId, entity.getClassId()))) {
if (classStudentDO.getRequiredHours() != null) {
classStudentDO.setRequiredHours(classStudentDO.getRequiredHours().add(entity.getVideoDuration()));
} else {
classStudentDO.setRequiredHours(entity.getVideoDuration());
}
classStudentMapper.updateById(classStudentDO);
}
return entity; return entity;
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public boolean updateCourse(ClassCourseDTO dto) { public boolean updateCourse(ClassCourseDTO dto) {
ClassCourseDO entity = classCourseConvertor.convertDtoToE(dto); ClassCourseDO entity = classCourseConvertor.convertDtoToE(dto);
InsertFieldDefaults.applyForUpdate(entity); InsertFieldDefaults.applyForUpdate(entity);
List<CoursewareManagementDO> coursewareManagementDOS = coursewareManagementMapper.selectBatchIds(CollectionUtils.isEmpty(dto.getCoursewareId()) ? Collections.singletonList(0L) : dto.getCoursewareId());
// 判空
if (entity.getRequiredTotalHours() != null) {
entity.setRequiredTotalHours(entity.getRequiredTotalHours().add(coursewareManagementDOS.stream().map(CoursewareManagementDO::getClassHourDuration).reduce(BigDecimal.ZERO, BigDecimal::add)));
} else {
entity.setRequiredTotalHours(coursewareManagementDOS.stream().map(CoursewareManagementDO::getClassHourDuration).reduce(BigDecimal.ZERO, BigDecimal::add));
}
if (entity.getVideoDuration() != null) {
entity.setVideoDuration(entity.getVideoDuration().add(coursewareManagementDOS.stream().map(CoursewareManagementDO::getCreditHours).reduce(BigDecimal.ZERO, BigDecimal::add)));
} else {
entity.setVideoDuration(coursewareManagementDOS.stream().map(CoursewareManagementDO::getCreditHours).reduce(BigDecimal.ZERO, BigDecimal::add));
}
// 学员回填数据(要求学时)
for (ClassStudentDO classStudentDO : classStudentMapper.selectList(new LambdaQueryWrapper<ClassStudentDO>()
.eq(ClassStudentDO::getClassId, entity.getClassId()))) {
if (classStudentDO.getRequiredHours() != null) {
classStudentDO.setRequiredHours(classStudentDO.getRequiredHours().add(entity.getVideoDuration()));
} else {
classStudentDO.setRequiredHours(entity.getVideoDuration());
}
classStudentMapper.updateById(classStudentDO);
}
return this.updateById(entity); return this.updateById(entity);
} }

View File

@ -134,9 +134,9 @@ public class ClassManagementServiceImpl extends ServiceImpl<ClassManagementMappe
public Boolean complete(ClassManagementDTO dto) { public Boolean complete(ClassManagementDTO dto) {
ClassManagementDO classManagementDO = baseMapper.selectById(dto.getId()); ClassManagementDO classManagementDO = baseMapper.selectById(dto.getId());
LocalDate start = classManagementDO.getStartDate().toLocalDate(); LocalDate start = classManagementDO.getStartDate().toLocalDate();
LocalDate end = classManagementDO.getDelayTime().toLocalDate(); LocalDate end = classManagementDO.getDelayTime() != null ? classManagementDO.getDelayTime().toLocalDate() : null;
;
if (Objects.isNull(end)) { if (Objects.isNull(end) || end.isBefore(classManagementDO.getEndDate().toLocalDate())) {
end = classManagementDO.getEndDate().toLocalDate(); end = classManagementDO.getEndDate().toLocalDate();
} }
LocalDate now = LocalDate.now(); LocalDate now = LocalDate.now();

View File

@ -35,6 +35,7 @@ public class ClassStudentExamRecordServiceImpl extends ServiceImpl<ClassStudentE
.eq(query.getStudentId() != null, ClassStudentExamRecordDO::getStudentId, query.getStudentId()) .eq(query.getStudentId() != null, ClassStudentExamRecordDO::getStudentId, query.getStudentId())
.eq(query.getPaperExamId() != null, ClassStudentExamRecordDO::getPaperExamId, query.getPaperExamId()) .eq(query.getPaperExamId() != null, ClassStudentExamRecordDO::getPaperExamId, query.getPaperExamId())
.eq(query.getPassed() != null, ClassStudentExamRecordDO::getPassed, query.getPassed()) .eq(query.getPassed() != null, ClassStudentExamRecordDO::getPassed, query.getPassed())
.eq(query.getPaperName() != null, ClassStudentExamRecordDO::getPaperName, query.getPaperName())
.orderByDesc(ClassStudentExamRecordDO::getCreateTime) .orderByDesc(ClassStudentExamRecordDO::getCreateTime)
.page(new Page<>(query.getCurrent(), query.getSize())) .page(new Page<>(query.getCurrent(), query.getSize()))
.convert(classStudentExamRecordConvertor::convertEToVo); .convert(classStudentExamRecordConvertor::convertEToVo);

View File

@ -14,6 +14,7 @@ import org.qinan.cedu.service.ClassStudentLearningRecordService;
import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults; import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -50,6 +51,7 @@ public class ClassStudentLearningRecordServiceImpl extends ServiceImpl<ClassStud
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public boolean saveRecord(ClassStudentLearningRecordDTO dto) { public boolean saveRecord(ClassStudentLearningRecordDTO dto) {
ClassStudentLearningRecordDO entity = classStudentLearningRecordConvertor.convertDtoToE(dto); ClassStudentLearningRecordDO entity = classStudentLearningRecordConvertor.convertDtoToE(dto);
InsertFieldDefaults.apply(entity); InsertFieldDefaults.apply(entity);
@ -57,9 +59,15 @@ public class ClassStudentLearningRecordServiceImpl extends ServiceImpl<ClassStud
if (entity.getStudyStatus() == null) { if (entity.getStudyStatus() == null) {
entity.setStudyStatus(0); entity.setStudyStatus(0);
} }
callbackFillStudent(entity);
return this.save(entity); return this.save(entity);
} }
public void callbackFillStudent(ClassStudentLearningRecordDO entity) {
}
@Transactional(rollbackFor = Exception.class)
@Override @Override
public boolean updateRecord(ClassStudentLearningRecordDTO dto) { public boolean updateRecord(ClassStudentLearningRecordDTO dto) {
ClassStudentLearningRecordDO entity = classStudentLearningRecordConvertor.convertDtoToE(dto); ClassStudentLearningRecordDO entity = classStudentLearningRecordConvertor.convertDtoToE(dto);

View File

@ -1,24 +1,33 @@
package org.qinan.cedu.service.impl; 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.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.qinan.cedu.convertor.ClassStudentConvertor; import org.qinan.cedu.convertor.ClassStudentConvertor;
import org.qinan.cedu.enums.DeleteEnum; import org.qinan.cedu.enums.DeleteEnum;
import org.qinan.cedu.mapper.ClassCourseMapper;
import org.qinan.cedu.mapper.ClassStudentMapper; import org.qinan.cedu.mapper.ClassStudentMapper;
import org.qinan.cedu.mapper.CoursewareManagementMapper;
import org.qinan.cedu.model.dto.ClassStudentDTO; import org.qinan.cedu.model.dto.ClassStudentDTO;
import org.qinan.cedu.model.entity.ClassCourseDO;
import org.qinan.cedu.model.entity.ClassStudentDO; import org.qinan.cedu.model.entity.ClassStudentDO;
import org.qinan.cedu.model.entity.CoursewareManagementDO;
import org.qinan.cedu.model.query.ClassStudentPageQuery; import org.qinan.cedu.model.query.ClassStudentPageQuery;
import org.qinan.cedu.model.vo.ClassStudentVO; import org.qinan.cedu.model.vo.ClassStudentVO;
import org.qinan.cedu.service.ClassStudentService; import org.qinan.cedu.service.ClassStudentService;
import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults; import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -30,6 +39,10 @@ public class ClassStudentServiceImpl extends ServiceImpl<ClassStudentMapper, Cla
@Autowired @Autowired
private ClassStudentConvertor classStudentConvertor; private ClassStudentConvertor classStudentConvertor;
@Autowired
private CoursewareManagementMapper coursewareManagementMapper;
@Autowired
private ClassCourseMapper classCourseMapper;
@Override @Override
public IPage<ClassStudentVO> pageQuery(ClassStudentPageQuery query) { public IPage<ClassStudentVO> pageQuery(ClassStudentPageQuery query) {
@ -58,6 +71,7 @@ public class ClassStudentServiceImpl extends ServiceImpl<ClassStudentMapper, Cla
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public boolean saveStudent(ClassStudentDTO dto) { public boolean saveStudent(ClassStudentDTO dto) {
return this.save(buildEntity(dto)); return this.save(buildEntity(dto));
} }
@ -80,7 +94,7 @@ public class ClassStudentServiceImpl extends ServiceImpl<ClassStudentMapper, Cla
* @param dto * @param dto
* @return * @return
*/ */
private ClassStudentDO buildEntity(ClassStudentDTO dto) { public ClassStudentDO buildEntity(ClassStudentDTO dto) {
ClassStudentDO entity = classStudentConvertor.convertDtoToE(dto); ClassStudentDO entity = classStudentConvertor.convertDtoToE(dto);
InsertFieldDefaults.apply(entity); InsertFieldDefaults.apply(entity);
entity.setUpdateTime(LocalDateTime.now()); entity.setUpdateTime(LocalDateTime.now());
@ -96,13 +110,34 @@ public class ClassStudentServiceImpl extends ServiceImpl<ClassStudentMapper, Cla
if (entity.getExamStatus() == null) { if (entity.getExamStatus() == null) {
entity.setExamStatus(0); entity.setExamStatus(0);
} }
List<Long> coursewareIds = classCourseMapper.selectList(new LambdaQueryWrapper<ClassCourseDO>()
.eq(ClassCourseDO::getClassId, entity.getClassId()))
.stream()
.map(ClassCourseDO::getCoursewareId)
.flatMap(List::stream)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
List<CoursewareManagementDO> coursewareManagementDOS = coursewareManagementMapper.selectBatchIds(CollectionUtils.isEmpty(coursewareIds) ? Collections.singletonList(0L) : coursewareIds);
entity.setRequiredHours(coursewareManagementDOS.stream().map(CoursewareManagementDO::getCreditHours).reduce(BigDecimal.ZERO, BigDecimal::add));
return entity; return entity;
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public boolean updateStudent(ClassStudentDTO dto) { public boolean updateStudent(ClassStudentDTO dto) {
ClassStudentDO entity = classStudentConvertor.convertDtoToE(dto); ClassStudentDO entity = classStudentConvertor.convertDtoToE(dto);
InsertFieldDefaults.applyForUpdate(entity); InsertFieldDefaults.applyForUpdate(entity);
List<Long> coursewareIds = classCourseMapper.selectList(new LambdaQueryWrapper<ClassCourseDO>()
.eq(ClassCourseDO::getClassId, entity.getClassId()))
.stream()
.map(ClassCourseDO::getCoursewareId)
.flatMap(List::stream)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
List<CoursewareManagementDO> coursewareManagementDOS = coursewareManagementMapper.selectBatchIds(CollectionUtils.isEmpty(coursewareIds) ? Collections.singletonList(0L) : coursewareIds);
entity.setRequiredHours(coursewareManagementDOS.stream().map(CoursewareManagementDO::getCreditHours).reduce(BigDecimal.ZERO, BigDecimal::add));
return this.updateById(entity); return this.updateById(entity);
} }

View File

@ -51,8 +51,8 @@ public class ClassManagementStateJob implements Job {
for (ClassManagementDO classManagementDO : classManagementDOS) { for (ClassManagementDO classManagementDO : classManagementDOS) {
log.info("班级管理状态检查 {}", classManagementDO.getClassName()); log.info("班级管理状态检查 {}", classManagementDO.getClassName());
LocalDate start = classManagementDO.getStartDate().toLocalDate(); LocalDate start = classManagementDO.getStartDate().toLocalDate();
LocalDate end = classManagementDO.getDelayTime().toLocalDate(); LocalDate end = classManagementDO.getDelayTime() != null ? classManagementDO.getDelayTime().toLocalDate() : null;
if (Objects.isNull(end)) { if (Objects.isNull(end) || end.isBefore(classManagementDO.getEndDate().toLocalDate())) {
end = classManagementDO.getEndDate().toLocalDate(); end = classManagementDO.getEndDate().toLocalDate();
} }
ClassStatusEnum pendingStart; ClassStatusEnum pendingStart;