|
@@ -1,45 +1,59 @@
|
|
package cn.com.qmth.print.manage.service.impl;
|
|
package cn.com.qmth.print.manage.service.impl;
|
|
|
|
|
|
import cn.com.qmth.print.manage.dao.ExamDao;
|
|
import cn.com.qmth.print.manage.dao.ExamDao;
|
|
|
|
+import cn.com.qmth.print.manage.dto.ExamDTO;
|
|
import cn.com.qmth.print.manage.entity.*;
|
|
import cn.com.qmth.print.manage.entity.*;
|
|
|
|
+import cn.com.qmth.print.manage.enums.CheckSort;
|
|
|
|
+import cn.com.qmth.print.manage.enums.GroupType;
|
|
import cn.com.qmth.print.manage.enums.RecordStatus;
|
|
import cn.com.qmth.print.manage.enums.RecordStatus;
|
|
import cn.com.qmth.print.manage.service.*;
|
|
import cn.com.qmth.print.manage.service.*;
|
|
import cn.com.qmth.print.manage.service.query.ExamQuery;
|
|
import cn.com.qmth.print.manage.service.query.ExamQuery;
|
|
|
|
+import cn.com.qmth.print.manage.utils.excel.ExcelError;
|
|
|
|
+import cn.com.qmth.print.manage.utils.excel.ExcelReader;
|
|
import cn.com.qmth.print.manage.vo.ExamVo;
|
|
import cn.com.qmth.print.manage.vo.ExamVo;
|
|
-
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
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 com.qmth.boot.core.exception.StatusException;
|
|
import com.qmth.boot.core.exception.StatusException;
|
|
-
|
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
|
import org.springframework.util.CollectionUtils;
|
|
import org.springframework.util.CollectionUtils;
|
|
-
|
|
|
|
-import java.util.Date;
|
|
|
|
-import java.util.List;
|
|
|
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
|
+
|
|
|
|
+import javax.annotation.Resource;
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
+import java.math.RoundingMode;
|
|
|
|
+import java.time.Year;
|
|
|
|
+import java.util.*;
|
|
|
|
+import java.util.concurrent.atomic.AtomicLong;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
+import java.util.stream.Stream;
|
|
|
|
|
|
@Service
|
|
@Service
|
|
public class ExamServiceImpl extends ServiceImpl<ExamDao, ExamEntity> implements ExamService {
|
|
public class ExamServiceImpl extends ServiceImpl<ExamDao, ExamEntity> implements ExamService {
|
|
|
|
|
|
- @Autowired
|
|
|
|
|
|
+ @Resource
|
|
private ExamUserRelationService examUserRelationService;
|
|
private ExamUserRelationService examUserRelationService;
|
|
|
|
|
|
- @Autowired
|
|
|
|
|
|
+ @Resource
|
|
private ExamStudentService examStudentService;
|
|
private ExamStudentService examStudentService;
|
|
|
|
|
|
- @Autowired
|
|
|
|
|
|
+ @Resource
|
|
private CheckRecordService checkRecordService;
|
|
private CheckRecordService checkRecordService;
|
|
|
|
|
|
- @Autowired
|
|
|
|
|
|
+ @Resource
|
|
private BreakRecordService breakRecordService;
|
|
private BreakRecordService breakRecordService;
|
|
|
|
|
|
- @Autowired
|
|
|
|
|
|
+ @Resource
|
|
private ExamDao examDao;
|
|
private ExamDao examDao;
|
|
|
|
|
|
|
|
+ @Resource
|
|
|
|
+ private OrgService orgService;
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public List<ExamEntity> listByOrgId() {
|
|
public List<ExamEntity> listByOrgId() {
|
|
QueryWrapper<ExamEntity> queryWrapper = new QueryWrapper<>();
|
|
QueryWrapper<ExamEntity> queryWrapper = new QueryWrapper<>();
|
|
@@ -50,7 +64,21 @@ public class ExamServiceImpl extends ServiceImpl<ExamDao, ExamEntity> implements
|
|
@Transactional
|
|
@Transactional
|
|
@Override
|
|
@Override
|
|
public Long saveExam(ExamEntity exam) {
|
|
public Long saveExam(ExamEntity exam) {
|
|
|
|
+ // 同机构下的考试批次名称不能重复校验
|
|
|
|
+ String examName = exam.getName();
|
|
|
|
+ Long orgId = exam.getOrgId();
|
|
|
|
+ ExamEntity nameCheck = this.getOne(new QueryWrapper<ExamEntity>().lambda()
|
|
|
|
+ .eq(ExamEntity::getName, examName)
|
|
|
|
+ .eq(ExamEntity::getOrgId, orgId));
|
|
|
|
+ if (Objects.nonNull(nameCheck)) {
|
|
|
|
+ Long id = nameCheck.getId();
|
|
|
|
+ if (!Objects.equals(id, exam.getId())) {
|
|
|
|
+ throw new StatusException(String.format("批次名称重复! 已经存在名称为[%s]的批次", examName));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
if (exam.getId() != null) {
|
|
if (exam.getId() != null) {
|
|
|
|
+ // 编辑
|
|
ExamEntity examEntity = this.getById(exam.getId());
|
|
ExamEntity examEntity = this.getById(exam.getId());
|
|
if (examEntity == null) {
|
|
if (examEntity == null) {
|
|
throw new StatusException("批次不存在");
|
|
throw new StatusException("批次不存在");
|
|
@@ -88,8 +116,8 @@ public class ExamServiceImpl extends ServiceImpl<ExamDao, ExamEntity> implements
|
|
// 绑定用户
|
|
// 绑定用户
|
|
List<ExamUserRelationEntity> examUserRelationEntities = examUserRelationService.listByExamId(record.getId());
|
|
List<ExamUserRelationEntity> examUserRelationEntities = examUserRelationService.listByExamId(record.getId());
|
|
String userIds = null;
|
|
String userIds = null;
|
|
- if(!CollectionUtils.isEmpty(examUserRelationEntities)){
|
|
|
|
- List<String> ids = examUserRelationEntities.stream().map(m->String.valueOf(m.getUserId())).collect(Collectors.toList());
|
|
|
|
|
|
+ if (!CollectionUtils.isEmpty(examUserRelationEntities)) {
|
|
|
|
+ List<String> ids = examUserRelationEntities.stream().map(m -> String.valueOf(m.getUserId())).collect(Collectors.toList());
|
|
userIds = String.join(",", ids);
|
|
userIds = String.join(",", ids);
|
|
}
|
|
}
|
|
record.setUserIds(userIds);
|
|
record.setUserIds(userIds);
|
|
@@ -115,12 +143,111 @@ public class ExamServiceImpl extends ServiceImpl<ExamDao, ExamEntity> implements
|
|
.filter(m -> m.getStatus().equals(RecordStatus.NORMAL)).count();
|
|
.filter(m -> m.getStatus().equals(RecordStatus.NORMAL)).count();
|
|
record.setBreakNormalLCount(Math.toIntExact(breakNormalLCount));
|
|
record.setBreakNormalLCount(Math.toIntExact(breakNormalLCount));
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // 计算进度
|
|
|
|
+ BigDecimal progress = new BigDecimal(record.getCheckNormalLCount()).divide(new BigDecimal(record.getCheckCount()), 4, RoundingMode.HALF_UP);
|
|
|
|
+ progress = progress.multiply(new BigDecimal(100));
|
|
|
|
+ record.setProgress(progress);
|
|
}
|
|
}
|
|
return iPage;
|
|
return iPage;
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
- public List<ExamEntity> listByUserId(Long userId) {
|
|
|
|
- return examDao.listByUserId(userId);
|
|
|
|
|
|
+ public List<ExamVo> listByUserId(Long userId) {
|
|
|
|
+ List<ExamEntity> examEntityList = examDao.listByUserId(userId);
|
|
|
|
+ return examEntityList.stream().flatMap(e -> {
|
|
|
|
+ ExamVo vo = new ExamVo();
|
|
|
|
+ BeanUtils.copyProperties(e, vo);
|
|
|
|
+
|
|
|
|
+ // 校验数量
|
|
|
|
+ List<CheckRecordEntity> checkRecordEntities = checkRecordService.listByExamId(vo.getId());
|
|
|
|
+ vo.setCheckCount(checkRecordEntities.size());
|
|
|
|
+ if (!CollectionUtils.isEmpty(checkRecordEntities)) {
|
|
|
|
+ long checkNormalLCount = checkRecordEntities.stream()
|
|
|
|
+ .filter(m -> m.getStatus().equals(RecordStatus.NORMAL)).count();
|
|
|
|
+ vo.setCheckNormalLCount(Math.toIntExact(checkNormalLCount));
|
|
|
|
+
|
|
|
|
+ long checkErrorLCount = checkRecordEntities.stream()
|
|
|
|
+ .filter(m -> m.getStatus().equals(RecordStatus.ERROR)).count();
|
|
|
|
+ vo.setCheckErrorCount(Math.toIntExact(checkErrorLCount));
|
|
|
|
+
|
|
|
|
+ // 计算进度
|
|
|
|
+ BigDecimal progress = new BigDecimal(vo.getCheckNormalLCount()).divide(new BigDecimal(vo.getCheckCount()), 4, RoundingMode.HALF_UP);
|
|
|
|
+ progress = progress.multiply(new BigDecimal(100));
|
|
|
|
+ vo.setProgress(progress);
|
|
|
|
+ }
|
|
|
|
+ return Stream.of(vo);
|
|
|
|
+ }).collect(Collectors.toList());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public List<ExcelError> importExams(UserEntity requestUser, Long printLeader, MultipartFile file) throws IOException {
|
|
|
|
+ List<String> examNameDatasource = this.list().stream()
|
|
|
|
+ .map(ExamEntity::getName)
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
+ // 默认机构
|
|
|
|
+ OrgEntity defaultOrg = orgService.findByCode("qmth");
|
|
|
|
+
|
|
|
|
+ List<ExamEntity> examEntityList = new ArrayList<>();
|
|
|
|
+
|
|
|
|
+ ExcelReader excelReader = new ExcelReader(ExamDTO.class);
|
|
|
|
+ AtomicLong sort = new AtomicLong(1L);
|
|
|
|
+ List<ExcelError> excelErrors = excelReader.reader(file.getInputStream(), obj -> {
|
|
|
|
+ try {
|
|
|
|
+ sort.getAndIncrement();
|
|
|
|
+ ExamDTO dto = (ExamDTO) obj;
|
|
|
|
+ String schoolName = dto.getSchoolName();
|
|
|
|
+ Year year = Year.now();
|
|
|
|
+ String examName = (Long.parseLong(year.toString()) + 1) + schoolName;
|
|
|
|
+ if (examNameDatasource.contains(examName)) {
|
|
|
|
+ throw new StatusException(String.format("第[%s]行已有学校名称则,导入不成功", examName));
|
|
|
|
+ }
|
|
|
|
+ ExamEntity examEntity = new ExamEntity();
|
|
|
|
+ examEntity.setOrgId(defaultOrg.getId());
|
|
|
|
+ examEntity.setName(examName);
|
|
|
|
+ examEntity.setEnable(true);
|
|
|
|
+ examEntity.setGroupType(GroupType.COURSE);
|
|
|
|
+ examEntity.setCheckSort(CheckSort.ASC);
|
|
|
|
+ examEntity.setCreateTime(new Date());
|
|
|
|
+ examEntity.setUpdateTime(new Date());
|
|
|
|
+ examEntity.setCreatorId(requestUser.getCreatorId());
|
|
|
|
+ examEntityList.add(examEntity);
|
|
|
|
+ return null;
|
|
|
|
+ } catch (RuntimeException e) {
|
|
|
|
+ // 手动回滚
|
|
|
|
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
|
|
|
|
+ ExcelError excelError = new ExcelError();
|
|
|
|
+ excelError.setExcelErrorType(e.getMessage());
|
|
|
|
+ return excelError;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ String errors = errorsString(excelErrors);
|
|
|
|
+ if (errors.length() > 0) {
|
|
|
|
+ throw new StatusException(errors);
|
|
|
|
+ }
|
|
|
|
+ if (!CollectionUtils.isEmpty(examEntityList)) {
|
|
|
|
+ this.saveBatch(examEntityList);
|
|
|
|
+ }
|
|
|
|
+ return excelErrors;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 拼接导入异常信息
|
|
|
|
+ *
|
|
|
|
+ * @param excelErrors
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private String errorsString(List<ExcelError> excelErrors) {
|
|
|
|
+ StringJoiner sj = new StringJoiner(";");
|
|
|
|
+ if (!excelErrors.isEmpty()) {
|
|
|
|
+ int forint = excelErrors.size() < 10 ? excelErrors.size() : 9;
|
|
|
|
+ for (int i = 0; i < forint; i++) {
|
|
|
|
+ ExcelError excelError = excelErrors.get(i);
|
|
|
|
+ StringBuffer sb = new StringBuffer();
|
|
|
|
+ sb.append("第").append(excelError.getRow()).append("行,").append(excelError.getExcelErrorType());
|
|
|
|
+ sj.add(sb.toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return sj.toString();
|
|
}
|
|
}
|
|
}
|
|
}
|