package cn.com.qmth.scancentral.service.impl; import cn.com.qmth.scancentral.bean.ImportExamDomain; import cn.com.qmth.scancentral.bean.User; import cn.com.qmth.scancentral.dao.ExamDao; import cn.com.qmth.scancentral.entity.ExamEntity; import cn.com.qmth.scancentral.entity.ExamSummaryEntity; import cn.com.qmth.scancentral.enums.*; import cn.com.qmth.scancentral.exception.ParameterExceptions; import cn.com.qmth.scancentral.service.*; import cn.com.qmth.scancentral.util.JsonMapper; import cn.com.qmth.scancentral.util.MathUtil; import cn.com.qmth.scancentral.util.PageUtil; import cn.com.qmth.scancentral.vo.ExamConfigVo; import cn.com.qmth.scancentral.vo.ExamVo; import cn.com.qmth.scancentral.vo.auditor.AuditorOverview; import cn.com.qmth.scancentral.vo.checkimage.RatioVo; import cn.com.qmth.scancentral.vo.examinfo.ExamEdit; import cn.com.qmth.scancentral.vo.examinfo.ExamOverview; import cn.com.qmth.scancentral.vo.examinfo.ExamQuery; import cn.com.qmth.scancentral.vo.omr.OmrTaskOverview; import cn.com.qmth.scancentral.vo.scanexaminfo.ScanExamInfoVo; import cn.com.qmth.scancentral.vo.scanexamlist.ScanExamListQuery; import cn.com.qmth.scancentral.vo.scanexamlist.ScanExamListVo; import cn.com.qmth.scancentral.vo.studentimport.StudentImportConfigVo; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.qmth.boot.core.collection.PageResult; import com.qmth.boot.core.exception.ParameterException; import com.qmth.boot.core.security.exception.AuthorizationException; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service public class ExamServiceImpl extends ServiceImpl implements ExamService { private static final Logger log = LoggerFactory.getLogger(ExamServiceImpl.class); @Autowired private AnswerCardService answerCardService; @Autowired private PackageCardService packageCardService; @Autowired private OmrTaskService omrTaskService; @Autowired private PackageTaskService packageTaskService; @Autowired private StudentService studentService; @Autowired private SubjectService subjectService; @Autowired private BatchService batchService; @Autowired private OmrGroupService omrGroupService; @Autowired private ExamSummaryService examSummaryService; @Override public PageResult pageQuery(ExamQuery query, User user) { query.setEnable(true); IPage iPage = this.baseMapper.pageExam(new Page<>(query.getPageNumber(), query.getPageSize()), query); return PageUtil.of(iPage); } @Override public List listEnable() { return list(new LambdaQueryWrapper().eq(ExamEntity::getEnable, true)); } @Override public Long save(ExamEdit exam) { if (StringUtils.isBlank(exam.getName())) { throw new ParameterException("考试名称不能为空"); } if (StringUtils.length(exam.getName()) > 100) { throw new ParameterException("考试名称限制100字以内"); } if (exam.getId() != null) { // 修改考试 ExamEntity examEntity = this.getById(exam.getId()); if (examEntity == null) { throw ParameterExceptions.EXAM_NOT_FOUND; } LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.set(ExamEntity::getUpdateTime, System.currentTimeMillis()); updateWrapper.set(ExamEntity::getUpdaterId, exam.getOperateUserId()); updateWrapper.set(ExamEntity::getName, exam.getName()); updateWrapper.eq(ExamEntity::getId, exam.getId()); this.update(updateWrapper); return exam.getId(); } // 新增考试 ExamEntity examEntity = new ExamEntity(); examEntity.setName(exam.getName()); examEntity.setEnable(true); examEntity.setCreatorId(exam.getOperateUserId()); examEntity.setUpdaterId(exam.getOperateUserId()); examEntity.setCreateTime(System.currentTimeMillis()); examEntity.setUpdateTime(System.currentTimeMillis()); examEntity.setMode(ExamMode.CET); examEntity.setScanByPackage(true); examEntity.setAllowUnexistPaper(false); examEntity.setAnswerFrontCardType(1); examEntity.setEnableSinglePageAnswer(false); examEntity.setEnableUpload(false); examEntity.setEnableSyncVerify(true); examEntity.setImageTransferMode(ImageTransferMode.CET); examEntity.setImageCheckRatio(1d); // examEntity.setImageCheckOrder(null); // examEntity.setScannerAssignedMaxCount(null); // examEntity.setScannerAssignedVerifyPassword(null); // examEntity.setPaperTypeBarcodeContent(null); // examEntity.setAbsentBarcodeContent(null); // examEntity.setDataSyncTime(null); // examEntity.setCardSyncTime(null); // examEntity.setExamNumberFillCount(null); this.save(examEntity); log.warn("新增考试成功! examId:{}", examEntity.getId()); return examEntity.getId(); } @Override public ExamOverview getExamOverview(Long examId, User accessUser) { ExamEntity exam = this.getById(examId); if (exam == null) { throw ParameterExceptions.EXAM_NOT_FOUND; } ExamOverview vo = new ExamOverview(); vo.setId(examId); vo.setName(exam.getName()); ExamSummaryEntity summary = examSummaryService.find(examId); vo.getBasic().setStudentCount(summary.getStudentCount()); vo.getBasic().setSubjectCount(summary.getSubjectCount()); vo.getBasic().setCardCount(answerCardService.getCountByExam(examId)); int scannedTotalCount = summary.getAnswerScannedCount() + summary.getAnswerUnexistCount(); double scannedRate = MathUtil.percentage(summary.getAnswerScannedCount(), scannedTotalCount); vo.getScan().setScannedRate(scannedRate); vo.getScan().setScannedCount(summary.getAnswerScannedCount()); vo.getScan().setUnexistCount(summary.getAnswerUnexistCount()); int imageCheckCount = batchService.getCheckCountByExamId(examId, CheckStatus.FINISH, accessUser); int imageCheckTodoCount = batchService.getCheckCountByExamId(examId, CheckStatus.WAITING, accessUser); int imageCheckTotalCount = imageCheckCount + imageCheckTodoCount; double imageCheckRate = MathUtil.percentage(imageCheckCount, imageCheckTotalCount); vo.getScan().setImageCheckRate(imageCheckRate); vo.getScan().setImageCheckCount(imageCheckCount); vo.getScan().setImageCheckTodoCount(imageCheckTodoCount); int auditorTodoCount = studentService.getCountByExamAndAssignedCheckCount(examId, 0, OP.EQ); int auditorFinishCount = studentService.getCountByExamAndAssignedCheckCount(examId, 0, OP.GT); int adminTodoCount = studentService.getCountByExamAndAssignedCheckCount(examId, 1, OP.EQ); int adminFinishCount = studentService.getCountByExamAndAssignedCheckCount(examId, 2, OP.GE); int auditorTotalCount = auditorTodoCount + auditorFinishCount; double auditorFinishRate = MathUtil.percentage(auditorFinishCount, auditorTotalCount); int adminTotalCount = adminTodoCount + adminFinishCount; double adminFinishRate = MathUtil.percentage(adminFinishCount, adminTotalCount); vo.getAssignedCheck().setAuditorTodoCount(auditorTodoCount); vo.getAssignedCheck().setAuditorFinishCount(auditorFinishCount); vo.getAssignedCheck().setAuditorFinishRate(auditorFinishRate); vo.getAssignedCheck().setAdminTodoCount(adminTodoCount); vo.getAssignedCheck().setAdminFinishCount(adminFinishCount); vo.getAssignedCheck().setAdminFinishRate(adminFinishRate); OmrTaskOverview suspectOverview = omrTaskService.countByExamIdAndFixed(examId, true); OmrTaskOverview customizeOverview = omrTaskService.countByExamIdAndFixed(examId, false); int suspectFinishCount = suspectOverview.getProcessedCount() + suspectOverview.getArbitrateCount(); int suspectTodoCount = suspectOverview.getWaitingCount() + suspectOverview.getWaitArbitrateCount(); double suspectFinishRate = MathUtil.percentage(suspectFinishCount, suspectOverview.getTotalCount()); int customizeFinishCount = customizeOverview.getProcessedCount() + customizeOverview.getArbitrateCount(); int customizeTodoCount = customizeOverview.getWaitingCount() + customizeOverview.getWaitArbitrateCount(); double customizeFinishRate = MathUtil.percentage(customizeFinishCount, customizeOverview.getTotalCount()); vo.getOmr().setSuspectFinishCount(suspectFinishCount); vo.getOmr().setSuspectTodoCount(suspectTodoCount); vo.getOmr().setSuspectFinishRate(suspectFinishRate); vo.getOmr().setCustomizeFinishCount(customizeFinishCount); vo.getOmr().setCustomizeTodoCount(customizeTodoCount); vo.getOmr().setCustomizeFinishRate(customizeFinishRate); int absentCount = studentService.countByExamIdAndExamStatus(examId, ExamStatus.ABSENT); int okCount = studentService.countByExamIdAndExamStatus(examId, ExamStatus.OK); int todoCount = studentService.countByExamIdAndExamStatus(examId, ExamStatus.UNCHECK); vo.getAbsentCheck().setAbsentCount(absentCount); vo.getAbsentCheck().setOkCount(okCount); vo.getAbsentCheck().setTodoCount(todoCount); return vo; } @Override public ScanExamInfoVo getScanExamInfo(Long id, User accessUser) { ExamEntity exam = this.getById(id); if (exam == null || (exam.getEnable() != null && !exam.getEnable())) { throw ParameterExceptions.EXAM_NOT_FOUND; } ExamSummaryEntity es = examSummaryService.find(exam.getId()); ScanExamInfoVo vo = new ScanExamInfoVo(); vo.setId(id); vo.setName(exam.getName()); vo.getExamConfig().setAllowUnexistPaper(exam.getAllowUnexistPaper()); vo.getExamConfig().setAnswerFrontCardType(exam.getAnswerFrontCardType()); vo.getExamConfig().setImageTransferMode(exam.getImageTransferMode()); vo.getExamConfig().setEnableSinglePageAnswer(exam.getEnableSinglePageAnswer()); vo.getExamConfig().setMode(exam.getMode()); vo.getExamConfig().setScanByPackage(exam.getScanByPackage()); vo.getExamConfig().setEnableSyncVerify(exam.getEnableSyncVerify()); vo.getExamConfig().setAbsentBarcodeContent(exam.getAbsentBarcodeContent()); vo.getExamConfig().setPaperTypeBarcodeContent(exam.getPaperTypeBarcodeContent()); vo.getAnswerScan().setCardCount(answerCardService.getCountByExam(id)); vo.getAnswerScan().setTotalCount(es.getStudentCount()); vo.getAnswerScan().setScannedCount(es.getAnswerScannedCount()); vo.getPackageScan().setCardCount(packageCardService.getCountByExam(id)); vo.getPackageScan().setTotalCount(es.getPackageTotalCount()); vo.getPackageScan().setScannedCount(es.getPackageScannedCount()); vo.getOmrTask().setTodoCount(omrTaskService.getCountByExamAndStatus(id, TaskStatus.WAITING)); vo.getOmrTask().setFinishCount(omrTaskService.getCountByExamAndStatus(id, TaskStatus.PROCESSED)); vo.getPackageTask().setTodoCount(packageTaskService.getCountByExamAndStatus(id, TaskStatus.WAITING)); vo.getPackageTask().setFinishCount(packageTaskService.getCountByExamAndStatus(id, TaskStatus.PROCESSED)); vo.setSubjectConfig(subjectService.listConfigByExamId(id)); return vo; } @Override public List getScanExamList() { ScanExamListQuery query = new ScanExamListQuery(); query.setEnable(true); return this.baseMapper.getExamList(query); } @Override public ExamConfigVo getConfigInfo(Long examId) { ExamEntity exam = this.getById(examId); if (exam == null) { throw ParameterExceptions.EXAM_NOT_FOUND; } ExamConfigVo vo = new ExamConfigVo(); vo.setExamId(exam.getId()); vo.setPaperTypeBarcodeContent(exam.getPaperTypeBarcodeContent()); vo.setImageCheckRatio(exam.getImageCheckRatio()); vo.setImageCheckOrder(exam.getImageCheckOrder()); vo.setEnableSyncVerify(exam.getEnableSyncVerify()); vo.setScannerAssignedMaxCount(exam.getScannerAssignedMaxCount()); vo.setScannerAssignedVerifyPassword(exam.getScannerAssignedVerifyPassword()); return vo; } @Transactional @Override public void saveConfig(ExamConfigVo config, User user) { if (!Role.SCHOOL_ADMIN.equals(user.getRole())) { throw AuthorizationException.NO_PERMISSION; } ExamEntity exam = this.getById(config.getExamId()); if (exam == null) { throw ParameterExceptions.EXAM_NOT_FOUND; } LambdaUpdateWrapper updateWrapper = Wrappers.lambdaUpdate(ExamEntity.class); if (config.getPaperTypeBarcodeContent() != null) { updateWrapper.setSql("paper_type_barcode_content = '" + new JsonMapper().toJson(config.getPaperTypeBarcodeContent()) + "'"); } if (config.getImageCheckRatio() != null) { updateWrapper.set(ExamEntity::getImageCheckRatio, config.getImageCheckRatio()); } if (StringUtils.isNotBlank(config.getImageCheckOrder())) { updateWrapper.set(ExamEntity::getImageCheckOrder, config.getImageCheckOrder()); } if (config.getEnableSyncVerify() != null) { updateWrapper.set(ExamEntity::getEnableSyncVerify, config.getEnableSyncVerify()); } if (config.getScannerAssignedMaxCount() != null) { updateWrapper.set(ExamEntity::getScannerAssignedMaxCount, config.getScannerAssignedMaxCount()); } if (StringUtils.isNotBlank(config.getScannerAssignedVerifyPassword())) { updateWrapper.set(ExamEntity::getScannerAssignedVerifyPassword, config.getScannerAssignedVerifyPassword()); } updateWrapper.set(ExamEntity::getUpdateTime, System.currentTimeMillis()); updateWrapper.set(ExamEntity::getUpdaterId, user.getId()); updateWrapper.eq(ExamEntity::getId, config.getExamId()); this.update(updateWrapper); if (config.getEnableSyncVerify() != null && !config.getEnableSyncVerify()) { // batchService.batchVerifyCancel(user, config.getExamId()); } } @Override public StudentImportConfigVo getStudentImportConfig(Long examId) { if (examId == null) { throw new ParameterException("examId不能为空"); } ExamEntity exam = this.getById(examId); if (exam == null) { throw ParameterExceptions.EXAM_NOT_FOUND; } StudentImportConfigVo config = new StudentImportConfigVo(); config.setExamId(examId); config.setYear(exam.getYear()); config.setYearHalf(exam.getYearHalf()); return config; } @Override public void saveStudentImportConfig(StudentImportConfigVo config) { if (config.getExamId() == null) { throw new ParameterException("examId不能为空"); } if (config.getYear() == null) { throw new ParameterException("考试年度不能为空"); } if (config.getYearHalf() == null) { throw new ParameterException("考次不能为空"); } ExamEntity exam = this.getById(config.getExamId()); if (exam == null) { throw ParameterExceptions.EXAM_NOT_FOUND; } LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.set(ExamEntity::getYear, config.getYear()); updateWrapper.set(ExamEntity::getYearHalf, config.getYearHalf()); updateWrapper.set(ExamEntity::getUpdateTime, System.currentTimeMillis()); updateWrapper.eq(ExamEntity::getId, exam.getId()); this.update(updateWrapper); } @Transactional @Override public ExamEntity save(ImportExamDomain domain) { if (SystemMode.MARKINGCLOUD.equals(SystemMode.current())) { throw new ParameterException("非本地模式不支持此功能"); } if (domain.getAllowUnexistPaper() == null) { throw new ParameterException("AllowUnexistPaper 不能为空"); } if (domain.getEnableSinglePageAnswer() == null) { throw new ParameterException("EnableSinglePageAnswer 不能为空"); } if (domain.getEnableSyncVerify() == null) { throw new ParameterException("EnableSyncVerify 不能为空"); } if (domain.getScanByPackage() == null) { throw new ParameterException("ScanByPackage 不能为空"); } if (domain.getAbsentBarcodeContent() == null) { throw new ParameterException("AbsentBarcodeContent 不能为空"); } if (domain.getAnswerFrontCardType() == null) { throw new ParameterException("AnswerFrontCardType 不能为空"); } if (domain.getImageTransferMode() == null) { domain.setImageTransferMode(ImageTransferMode.OFF); // throw new ParameterException("ImageTransferMode 不能为空"); } if (domain.getMode() == null) { throw new ParameterException("ExamMode 不能为空"); } if (domain.getPaperTypeBarcodeContent() == null) { throw new ParameterException("PaperTypeBarcodeContent 不能为空"); } if (domain.getExamNumberFillCount() == null) { throw new ParameterException("ExamNumberFillCount 不能为空"); } ExamEntity exam = new ExamEntity(); exam.setId(domain.getId()); exam.setName(domain.getName()); exam.setEnable(true); exam.setEnableUpload(false); exam.setImageCheckRatio(0d); exam.setAllowUnexistPaper(domain.getAllowUnexistPaper()); exam.setEnableSinglePageAnswer(domain.getEnableSinglePageAnswer()); exam.setEnableSyncVerify(domain.getEnableSyncVerify()); exam.setScanByPackage(domain.getScanByPackage()); exam.setAbsentBarcodeContent(domain.getAbsentBarcodeContent()); exam.setAnswerFrontCardType(domain.getAnswerFrontCardType()); exam.setImageTransferMode(domain.getImageTransferMode()); exam.setMode(domain.getMode()); exam.setPaperTypeBarcodeContent(domain.getPaperTypeBarcodeContent()); if (getById(domain.getId()) == null) { omrGroupService.addFixOmrCondition(1L, exam.getId(), null); } exam.setExamNumberFillCount(domain.getExamNumberFillCount()); this.saveOrUpdate(exam); return exam; } @Override public RatioVo updateRatio(Long examId, Double ratio) { if (ratio == null || ratio < 0 || ratio > 1) { throw new ParameterException("ratio 不符合"); } ExamEntity exam = this.getById(examId); if (exam == null) { throw new ParameterException("Exam 不能为空"); } exam.setImageCheckRatio(ratio); this.updateById(exam); return new RatioVo(ratio); } @Transactional @Override public void updateDataSyncTime(Long examId) { ExamEntity exam = this.getById(examId); if (exam == null) { throw new ParameterException("Exam 不能为空"); } exam.setDataSyncTime(System.currentTimeMillis()); this.updateById(exam); } @Transactional @Override public void updateCardSyncTime(Long examId) { ExamEntity exam = this.getById(examId); if (exam == null) { throw new ParameterException("Exam 不能为空"); } exam.setCardSyncTime(System.currentTimeMillis()); this.updateById(exam); } @Override public void updateExamNumberFillCount(Long examId, Integer examNumberFillCount) { ExamEntity exam = this.getById(examId); if (exam == null) { throw new ParameterException("Exam 不能为空"); } exam.setExamNumberFillCount(examNumberFillCount); this.updateById(exam); } @Override @Transactional public ExamEntity updateEnableSyncVerify(User user, Long examId, Boolean enableSyncVerify) { ExamEntity exam = this.getById(examId); if (exam == null) { throw ParameterExceptions.EXAM_NOT_FOUND; } if (enableSyncVerify == false) { batchService.batchVerifyCancel(user, examId); } exam.setEnableSyncVerify(enableSyncVerify); this.saveOrUpdate(exam); return exam; } @Override public AuditorOverview getAuditorOverview(Long examId, User user) { if (!user.getRole().equals(Role.AUDITOR)) { throw new ParameterException("user 不是审核员"); } ExamEntity exam = this.getById(examId); if (exam == null) { throw ParameterExceptions.EXAM_NOT_FOUND; } AuditorOverview vo = new AuditorOverview(); vo.setId(examId); vo.setName(exam.getName()); vo.getVerifyTask().setTodoCount(batchService.getVerifyCount(examId)); vo.getImageCheckTask().setCheckRatio(exam.getImageCheckRatio()); vo.getImageCheckTask().setFinishCount(batchService.getCheckCountByExamId(examId, CheckStatus.FINISH, user)); vo.getImageCheckTask().setTodoCount(batchService.getCheckCountByExamId(examId, CheckStatus.WAITING, user)); vo.getAssignedCheck().setTodoCount(studentService.getCountByExamAndAssignedCheckCount(examId, 0, OP.EQ)); return vo; } @Transactional @Override public void scanSiteSave(Long examId, String scanStie) { LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.set(ExamEntity::getScanSite, scanStie); updateWrapper.eq(ExamEntity::getId, examId); this.update(updateWrapper); } @Override public String getScanSite(Long examId) { return this.getById(examId).getScanSite(); } }