123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878 |
- package cn.com.qmth.scancentral.service.impl;
- import cn.com.qmth.scancentral.bean.BatchCreateDomain;
- import cn.com.qmth.scancentral.bean.BatchQueryDomain;
- import cn.com.qmth.scancentral.bean.User;
- import cn.com.qmth.scancentral.bean.WorkloadDomain;
- import cn.com.qmth.scancentral.bean.answersave.AnswerDomain;
- import cn.com.qmth.scancentral.bean.answersave.AnswerPaper;
- import cn.com.qmth.scancentral.dao.BatchDao;
- import cn.com.qmth.scancentral.entity.*;
- import cn.com.qmth.scancentral.enums.*;
- import cn.com.qmth.scancentral.exception.NotFoundExceptions;
- import cn.com.qmth.scancentral.exception.ParameterExceptions;
- import cn.com.qmth.scancentral.service.*;
- import cn.com.qmth.scancentral.support.TaskLock;
- import cn.com.qmth.scancentral.support.TaskLockUtil;
- import cn.com.qmth.scancentral.util.PageUtil;
- import cn.com.qmth.scancentral.vo.*;
- import cn.com.qmth.scancentral.vo.batch.*;
- import cn.com.qmth.scancentral.vo.batchdetail.BatchDetailDO;
- import cn.com.qmth.scancentral.vo.batchdetail.BatchDetailVo;
- import cn.com.qmth.scancentral.vo.batchdetail.BatchStudentVo;
- import cn.com.qmth.scancentral.vo.checkimage.CheckImageSubmitVo;
- import cn.com.qmth.scancentral.vo.device.DeviceVo;
- import cn.com.qmth.scancentral.vo.paper.PaperVo;
- import cn.com.qmth.scancentral.vo.task.TaskStatusVo;
- import cn.com.qmth.scancentral.vo.verify.VerifyStudentVo;
- import cn.com.qmth.scancentral.vo.verify.VerifyTaskVo;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
- import com.baomidou.mybatisplus.core.metadata.IPage;
- 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.concurrent.service.ConcurrentService;
- import com.qmth.boot.core.exception.ParameterException;
- import com.qmth.boot.core.exception.StatusException;
- import org.apache.commons.collections4.CollectionUtils;
- import org.apache.commons.lang.math.RandomUtils;
- import org.apache.commons.lang3.StringUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import org.springframework.web.multipart.MultipartFile;
- import java.util.*;
- @Service
- public class BatchServiceImpl extends ServiceImpl<BatchDao, BatchEntity> implements BatchService {
- @Autowired
- private ExamService examService;
- @Autowired
- private StudentService studentService;
- @Autowired
- private PaperService paperService;
- @Autowired
- private PaperPageService paperPageService;
- @Autowired
- private BatchPaperService batchPaperService;
- @Autowired
- private AnswerCardService answerCardService;
- @Autowired
- private AnswerCardSubjectService answerCardSubjectService;
- @Autowired
- private ConcurrentService concurrentService;
- @Autowired
- private FileService fileService;
- @Autowired
- private FilePropertyService filePropertyService;
- @Autowired
- private SubjectService subjectService;
- @Autowired
- private AssignedCheckHistoryService assignedCheckHistoryService;
- @Override
- public BatchEntity checkBatchStatus(BatchEntity b) {
- if (b == null) {
- throw new ParameterException("批次未找到");
- }
- if (BatchStatus.FINISH.equals(b.getStatus())) {
- throw new ParameterException("批次已经完成");
- }
- if (VerifyStatus.WAITING.equals(b.getVerifyStatus())) {
- throw new ParameterException("批次正在审核中");
- }
- if (VerifyStatus.REJECT.equals(b.getVerifyStatus())) {
- throw new ParameterException("批次审核不通过");
- }
- return b;
- }
- @Transactional
- @Override
- public BatchCreateVo batchCreate(BatchCreateDomain domain, User user) {
- ExamEntity exam = examService.getById(domain.getExamId());
- if (exam == null) {
- throw ParameterExceptions.EXAM_NOT_FOUND;
- }
- List<Rescan> rescan = new ArrayList<>();
- String packageCode = null;
- for (String examNumber : domain.getExamNumbers()) {
- StudentEntity student = studentService.findByExamAndSubjectCodeAndExamNumber(domain.getExamId(),
- domain.getSubjectCode(), examNumber);
- if (student == null) {
- throw new ParameterException("未找到考生信息:" + examNumber);
- }
- if (exam.getScanByPackage() != null && exam.getScanByPackage()) {
- if (packageCode == null) {
- packageCode = student.getPackageCode();
- } else {
- if (!packageCode.equals(student.getPackageCode())) {
- throw new ParameterException("考生[" + examNumber + "]卷袋编号与其它考生不一致");
- }
- }
- if (domain.getSubjectCode() != null && !domain.getSubjectCode().equals(student.getSubjectCode())) {
- throw new ParameterException("考生[" + examNumber + "]科目代码与[" + domain.getSubjectCode() + "]不一致");
- }
- }
- Rescan rc = getRescan(student);
- if (rc != null) {
- rescan.add(rc);
- }
- }
- if (exam.getScanByPackage() != null && exam.getScanByPackage()) {
- if (StringUtils.isBlank(domain.getSubjectCode())) {
- throw new ParameterException("整袋模式下科目代码不能为空");
- }
- List<StudentEntity> ss = studentService.findByExamAndPackage(domain.getExamId(), packageCode,
- domain.getSubjectCode());
- if (CollectionUtils.isEmpty(ss) || ss.size() != domain.getExamNumbers().size()) {
- throw new ParameterException("该批次考生数量与卷袋考生数量不一致");
- }
- }
- BatchEntity b = new BatchEntity();
- b.setExamId(domain.getExamId());
- b.setDevice(user.getAccount());
- b.setPackageCode(packageCode);
- b.setSubjectCode(domain.getSubjectCode());
- b.setAssignedCount(0);
- b.setScanCount(0);
- b.setStatus(BatchStatus.INIT);
- this.save(b);
- BatchCreateVo vo = new BatchCreateVo();
- vo.setRescan(rescan);
- vo.setId(b.getId());
- vo.setCreateTime(b.getCreateTime());
- vo.setEnableSyncVerify(exam.getEnableSyncVerify());
- return vo;
- }
- private Rescan getRescan(StudentEntity student) {
- Rescan res = new Rescan();
- res.setExamNumber(student.getExamNumber());
- List<PaperVo> papers = paperService.findStudentPaper(student.getId());
- List<Paper> resPapers = new ArrayList<>();
- res.setPapers(resPapers);
- if (CollectionUtils.isEmpty(papers)) {
- return null;
- }
- PaperVo first = papers.get(0);
- res.setBatchId(first.getBatchId());
- res.setDevice(first.getDevice());
- res.setCreateTime(first.getCreateTime());
- for (PaperVo paper : papers) {
- Paper p = new Paper();
- p.setId(paper.getId());
- p.setNumber(paper.getNumber());
- p.setMismatch(paper.getMismatch());
- List<String> pages = new ArrayList<>();
- p.setPages(pages);
- List<PaperPageEntity> paperPages = paperPageService.listByPaperId(paper.getId());
- if (CollectionUtils.isNotEmpty(paperPages)) {
- for (PaperPageEntity pp : paperPages) {
- pages.add(pp.getSheetPath());
- }
- }
- resPapers.add(p);
- }
- return res;
- }
- @Override
- public int getCountByExam(Long examId) {
- QueryWrapper<BatchEntity> wrapper = new QueryWrapper<>();
- LambdaQueryWrapper<BatchEntity> lw = wrapper.lambda();
- lw.eq(BatchEntity::getExamId, examId);
- return this.count(wrapper);
- }
- @Override
- public int getValidCountByExam(Long examId) {
- QueryWrapper<BatchEntity> wrapper = new QueryWrapper<>();
- LambdaQueryWrapper<BatchEntity> lw = wrapper.lambda();
- lw.and(param -> {
- param.or().isNull(BatchEntity::getVerifyStatus);
- param.or().ne(BatchEntity::getVerifyStatus, VerifyStatus.REJECT);
- });
- lw.eq(BatchEntity::getExamId, examId);
- lw.gt(BatchEntity::getScanCount, 0);
- return this.count(wrapper);
- }
- @Override
- public int getVerifyCount(Long examId) {
- QueryWrapper<BatchEntity> wrapper = new QueryWrapper<>();
- LambdaQueryWrapper<BatchEntity> lw = wrapper.lambda();
- lw.eq(BatchEntity::getExamId, examId);
- lw.eq(BatchEntity::getVerifyStatus, VerifyStatus.WAITING);
- return this.count(wrapper);
- }
- @Transactional
- @Override
- public SheetUploadVo sheetUpload(Long batchId, String examNumber, Integer paperNumber, Integer pageIndex,
- MultipartFile multipartFile, String md5) {
- BatchEntity batch = checkBatchStatus(getById(batchId));
- try {
- String path = fileService.uploadSheet(multipartFile.getInputStream(), md5, batch.getExamId(), batchId,
- examNumber, paperNumber, pageIndex);
- filePropertyService.save(batch.getExamId(), path, md5, multipartFile.getSize());
- return SheetUploadVo.create(path);
- } catch (Exception e) {
- log.error("原图上传失败,batchId=" + batch + ", examNumber=" + examNumber + ", paperNumber=" + paperNumber
- + ", pageIndex=" + pageIndex, e);
- throw new StatusException("原图上传失败", e);
- }
- }
- @Transactional
- @Override
- public SliceUploadVo sliceUpload(Long batchId, String examNumber, Integer paperNumber, Integer pageIndex,
- Integer index, MultipartFile multipartFile, String md5) {
- BatchEntity batch = checkBatchStatus(getById(batchId));
- try {
- String path = fileService.uploadSlice(multipartFile.getInputStream(), md5, batch.getExamId(), batchId,
- examNumber, paperNumber, pageIndex, index);
- filePropertyService.save(batch.getExamId(), path, md5, multipartFile.getSize());
- return SliceUploadVo.create(path);
- } catch (Exception e) {
- log.error("裁切图上传失败,batchId=" + batch + ", examNumber=" + examNumber + ", paperNumber=" + paperNumber
- + ", pageIndex=" + pageIndex + ", index=" + index, e);
- throw new StatusException("裁切图上传失败", e);
- }
- }
- @Transactional
- @Override
- public AnswerSaveVo batchSave(AnswerDomain domain, User user) {
- BatchEntity batch = checkBatchStatus(getById(domain.getBatchId()));
- ExamEntity exam = examService.getById(batch.getExamId());
- if (exam == null) {
- throw ParameterExceptions.EXAM_NOT_FOUND;
- }
- String examNumber = domain.getExamNumber();
- StudentEntity student = studentService.findByExamAndSubjectCodeAndExamNumber(batch.getExamId(),
- domain.getSubjectCode(), examNumber);
- if (student == null) {
- throw new ParameterException("考生信息未找到");
- }
- AnswerCardEntity answerCard = answerCardService.findByExamAndNumber(batch.getExamId(), domain.getCardNumber());
- if (answerCard == null) {
- throw new ParameterException("卡格式信息未找到");
- }
- // 整袋扫描验证packageCode
- if (exam.getScanByPackage() != null && exam.getScanByPackage()) {
- if (!StringUtils.equals(batch.getPackageCode(), student.getPackageCode())) {
- throw new ParameterException("与批次卷袋号不一致");
- }
- }
- // 验证卡格式所属科目
- boolean allowSubject = answerCardSubjectService.checkSubject(answerCard.getExamId(), answerCard.getNumber(),
- student.getSubjectCode());
- if (!allowSubject) {
- throw new ParameterException("卡格式与考生科目不一致");
- }
- // 不允许缺页时,保存张数需要与卡格式定义一致
- if (!exam.getAllowUnexistPaper() && domain.getPapers().size() != answerCard.getPaperCount()) {
- throw new ParameterException("卡格式张数不一致");
- }
- List<String> paperTypeBarcodeContents = exam.getPaperTypeBarcodeContent();
- SubjectEntity subject = subjectService.findByExamIdAndCode(student.getExamId(), student.getSubjectCode());
- if (subject.getPaperTypeBarcodeContent() != null && !subject.getPaperTypeBarcodeContent().isEmpty()) {
- paperTypeBarcodeContents = subject.getPaperTypeBarcodeContent();
- }
- boolean studentAssigned = false;
- List<StudentPaperEntity> studentPaperList = new ArrayList<>();
- for (AnswerPaper answerPaper : domain.getPapers()) {
- // 验证page数量
- answerPaper.answerCardValidate(answerCard);
- Integer paperNumber = answerPaper.getNumber();
- PaperEntity paper = findOrCreatePaper(batch, student, paperNumber, user);
- // 设置paper属性
- paper.setExamId(batch.getExamId());
- paper.setCardNumber(answerCard.getNumber());
- paper.setNumber(paperNumber);
- paper.setMismatch(false);
- paper.setQuestionFilled(false);
- paper.setAssignedSuspect(false);
- paper.setSubjectiveFilled(answerPaper.getSubjectiveFilled());
- paper.setOmrExamNumber(answerPaper.getOmrExamNumber());
- paper.setAssigned(answerPaper.getAssigned());
- // 保存paper与page到数据库
- paperService.savePaperAndPages(paper, answerPaper.buildPageList(paperTypeBarcodeContents));
- // 记录paper与batch关联关系
- batchPaperService.update(batch, paper, student.getId(), paperNumber, false);
- // 创建student与paper的关联关系
- studentPaperList.add(new StudentPaperEntity(student.getId(), paperNumber, paper.getId()));
- studentAssigned = studentAssigned || paper.getAssigned();
- }
- // 更新批次统计数量,改到finish的时候更新
- // updateAssignedCount(batch.getId());
- // updateScanCount(batch.getId());
- // 不开启实时审核,或者没有人工绑定的情况下,或者当前批次无需审核,直接更新考生扫描状态
- if (VerifyStatus.CANCEL.equals(batch.getVerifyStatus()) || exam.getEnableSyncVerify() == null
- || !exam.getEnableSyncVerify() || !studentAssigned) {
- concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().lock();
- try {
- studentService.updateStudentAndPaper(user, student.getId(), studentPaperList);
- studentService.updateAssignedCheckCount(student.getId(), true);
- } finally {
- concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().unlock();
- }
- }
- return AnswerSaveVo.create(findStudentCountByBatch(batch.getId()));
- }
- private PaperEntity findOrCreatePaper(BatchEntity batch, StudentEntity student, Integer paperNumber, User user) {
- PaperEntity paper = null;
- // 尝试重用已有paper对象
- BatchPaperEntity batchPaper = batchPaperService.findByBatchIdAndStudentIdAndPaperNumber(batch.getId(),
- student.getId(), paperNumber);
- if (batchPaper != null) {
- paper = paperService.getById(batchPaper.getPaperId());
- }
- // 构造全新paper对象
- if (paper == null) {
- paper = new PaperEntity();
- paper.setCreateTime(System.currentTimeMillis());
- paper.setCreatorId(user.getId());
- }
- return paper;
- }
- private void updateBatchAssignedStudentData(User user, Long batchId, Long examId) {
- List<BatchPaperEntity> batchPaperList = batchPaperService.findByBatchId(batchId);
- Map<Long, List<StudentPaperEntity>> studentMap = new HashMap<>();
- for (BatchPaperEntity batchPaper : batchPaperList) {
- studentMap.computeIfAbsent(batchPaper.getStudentId(), key -> new ArrayList<>()).add(new StudentPaperEntity(
- batchPaper.getStudentId(), batchPaper.getPaperNumber(), batchPaper.getPaperId()));
- }
- for (Map.Entry<Long, List<StudentPaperEntity>> entry : studentMap.entrySet()) {
- concurrentService.getReadWriteLock(LockType.STUDENT + "-" + entry.getKey()).writeLock().lock();
- try {
- studentService.updateStudentAndPaper(user, entry.getKey(), entry.getValue());
- assignedCheckHistoryService.save(user.getId(), entry.getKey(), examId);
- studentService.updateAssignedCheckCount(entry.getKey(), false);
- } finally {
- concurrentService.getReadWriteLock(LockType.STUDENT + "-" + entry.getKey()).writeLock().unlock();
- }
- }
- }
- @Transactional
- @Override
- public void verify(Long batchId, Boolean comfirm, User user) {
- BatchEntity entity = this.getById(batchId);
- if (entity == null) {
- throw new ParameterException("批次不存在");
- }
- if (!VerifyStatus.WAITING.equals(entity.getVerifyStatus())) {
- throw new ParameterException("批次已被处理");
- }
- if (comfirm) {
- updateBatchAssignedStudentData(user, batchId, entity.getExamId());
- entity.setVerifyStatus(VerifyStatus.CONFIRM);
- } else {
- entity.setVerifyStatus(VerifyStatus.REJECT);
- }
- entity.setUpdateTime(System.currentTimeMillis());
- this.saveOrUpdate(entity);
- }
- @Transactional
- @Override
- public BatchVerifyVo batchVerify(Long id) {
- BatchEntity entity = this.getById(id);
- if (entity == null) {
- throw new ParameterException("批次不存在");
- }
- Integer count = findStudentCountByBatch(id);
- if (count == null || count == 0) {
- throw new ParameterException("该批次未上传图片");
- }
- if (entity.getVerifyStatus() == null) {
- ExamEntity exam = examService.getById(entity.getExamId());
- if (exam.getEnableSyncVerify() == null || !exam.getEnableSyncVerify()) {
- throw new ParameterException("考试未启用实时审核");
- }
- entity.setVerifyStatus(VerifyStatus.WAITING);
- this.saveOrUpdate(entity);
- }
- BatchVerifyVo vo = new BatchVerifyVo();
- vo.setStatus(entity.getVerifyStatus());
- vo.setUpdateTime(entity.getUpdateTime());
- return vo;
- }
- @Transactional
- @Override
- public BatchFinishVo batchFinish(Long id) {
- BatchEntity entity = this.getById(id);
- if (entity == null) {
- throw new ParameterException("批次不存在");
- }
- checkBatchStatus(entity);
- ExamEntity exam = examService.getById(entity.getExamId());
- if (exam.getScanByPackage() != null && exam.getScanByPackage()) {
- checkStudentCount(entity);
- }
- List<BatchPaperEntity> saveList = new ArrayList<BatchPaperEntity>();
- if (exam.getImageCheckRatio() == 1) {
- List<BatchPaperEntity> papers = batchPaperService.findByBatchId(id);
- for (BatchPaperEntity batchPaperEntity : papers) {
- batchPaperEntity.setNeedCheck(true);
- saveList.add(batchPaperEntity);
- }
- } else {
- List<Long> studentIds = batchPaperService.findStudentIdByBatchId(id);
- int checkCount = (int) (studentIds.size() * exam.getImageCheckRatio());
- if (checkCount > 0) {
- Set<Long> checkIds = new HashSet<Long>();
- while (checkIds.size() < checkCount) {
- Long studentId = studentIds.get(RandomUtils.nextInt(studentIds.size()));
- checkIds.add(studentId);
- }
- List<BatchPaperEntity> papers = batchPaperService.findByBatchIdAndStudentIds(id, checkIds);
- for (BatchPaperEntity batchPaperEntity : papers) {
- batchPaperEntity.setNeedCheck(true);
- saveList.add(batchPaperEntity);
- }
- }
- }
- if (!saveList.isEmpty()) {
- batchPaperService.saveOrUpdateBatchByMultiId(saveList);
- entity.setCheckStatus(CheckStatus.WAITING);
- }
- entity.setStatus(BatchStatus.FINISH);
- this.saveOrUpdate(entity);
- updateAssignedCount(entity.getId());
- updateScanCount(entity.getId());
- BatchFinishVo vo = new BatchFinishVo();
- vo.setStatus(entity.getStatus());
- vo.setUpdateTime(System.currentTimeMillis());
- return vo;
- }
- private void checkStudentCount(BatchEntity entity) {
- List<BatchPaperEntity> papers = batchPaperService.findByBatchId(entity.getId());
- List<StudentEntity> students = studentService.findByExamAndPackage(entity.getExamId(), entity.getPackageCode(),
- entity.getSubjectCode());
- if (CollectionUtils.isEmpty(papers) && CollectionUtils.isEmpty(students)) {
- return;
- }
- if (CollectionUtils.isEmpty(papers) || CollectionUtils.isEmpty(students)) {
- throw new ParameterException("卷袋考生有未扫描");
- }
- Set<Long> ps = new HashSet<>();
- Set<Long> ss = new HashSet<>();
- for (BatchPaperEntity p : papers) {
- ps.add(p.getStudentId());
- }
- for (StudentEntity s : students) {
- ss.add(s.getId());
- }
- if (ps.size() != ss.size()) {
- throw new ParameterException("卷袋考生有未扫描");
- }
- for (Long p : ps) {
- if (!ss.contains(p)) {
- throw new ParameterException("卷袋考生有未扫描");
- }
- }
- }
- @Transactional
- @Override
- public void updateScanCount(Long id) {
- baseMapper.updateScanCount(id);
- }
- @Transactional
- @Override
- public void updateAssignedCount(Long id) {
- baseMapper.updateAssignedCount(id);
- }
- @Override
- public PageResult<BatchQueryVo> batchQuery(BatchQueryDomain query) {
- IPage<BatchQueryVo> iPage = baseMapper.batchQueryPage(new Page<>(query.getPageNumber(), query.getPageSize()),
- query);
- // TODO 需要后续补充incomplete逻辑
- return PageUtil.of(iPage);
- }
- @Override
- public List<Long> batchSummary(BatchQueryDomain query) {
- // TODO 需要后续补充incomplete逻辑
- return baseMapper.batchSummary(query);
- }
- @Override
- public BatchDetailVo batchDetail(Long id) {
- BatchEntity batchEntity = this.getById(id);
- BatchDetailVo vo = new BatchDetailVo();
- vo.update(batchEntity);
- Map<Long, BatchStudentVo> map = new LinkedHashMap<>();
- List<BatchDetailDO> list = baseMapper.batchDetailList(id);
- for (BatchDetailDO item : list) {
- BatchStudentVo detail = map.computeIfAbsent(item.getId(), key -> BatchStudentVo.build(item));
- // 判断是否人工绑定
- detail.setAssigned(detail.getAssigned() || item.getAssigned());
- // 判断是否识别缺考
- if (item.getAbsent() != null && item.getAbsent().getResult()) {
- detail.setOmrAbsent(true);
- }
- // 创建paper与page对象
- detail.findOrCreatePaper(item).addPage(item);
- }
- vo.setStudents(new ArrayList<>(map.values()));
- return vo;
- }
- @Override
- public VerifyTaskVo getVerifyTask(Long examId, User user) {
- int retry = 1;
- VerifyTaskVo task = null;
- while (task == null) {
- List<BatchEntity> list = this.findUnVerify(examId, retry, 20, VerifyStatus.WAITING).getRecords();
- if (list.isEmpty()) {
- break;
- }
- for (BatchEntity t : list) {
- if (this.applyVerifyTask(t, user.getAccount())) {
- task = toVerifyTaskVo(t);
- break;
- }
- }
- if (task == null) {
- retry++;
- }
- }
- if (task == null) {
- throw NotFoundExceptions.NO_SYNC_VERIFY_TASK;
- }
- return task;
- }
- private VerifyTaskVo toVerifyTaskVo(BatchEntity batch) {
- VerifyTaskVo vo = new VerifyTaskVo();
- vo.setBatchId(batch.getId());
- vo.setCreateTime(batch.getCreateTime());
- vo.setDevice(batch.getDevice());
- vo.setPackageCode(batch.getPackageCode());
- Map<Long, VerifyStudentVo> studentMap = new LinkedHashMap<>();
- List<BatchDetailDO> list = baseMapper.batchDetailList(batch.getId());
- for (BatchDetailDO item : list) {
- VerifyStudentVo student = studentMap.computeIfAbsent(item.getId(), key -> VerifyStudentVo.build(item));
- student.findOrCreatePaper(item).getPages().add(item.getSheetPath());
- }
- vo.setStudents(new ArrayList<>(studentMap.values()));
- return vo;
- }
- @Override
- public boolean applyVerifyTask(BatchEntity t, String user) {
- TaskLock taskLock = TaskLockUtil.getVerifyTask(t.getExamId().toString());
- boolean lock = taskLock.add(t.getId(), user);
- // 上锁失败直接返回
- if (!lock) {
- return false;
- }
- // 重复校验任务状态
- if (VerifyStatus.WAITING.equals(t.getVerifyStatus())) {
- return true;
- } else {
- taskLock.remove(t.getId().toString());
- return false;
- }
- }
- @Override
- public void releaseVerifyTask(Long examId, String account) {
- TaskLock taskLock = TaskLockUtil.getVerifyTask(examId.toString());
- taskLock.clear(account);
- }
- @Override
- public void releaseVerifyTask(BatchEntity t) {
- TaskLock taskLock = TaskLockUtil.getVerifyTask(t.getExamId().toString());
- taskLock.remove(t.getId().toString());
- }
- @Override
- public boolean hasAppliedVerifyTask(BatchEntity t, String user) {
- TaskLock taskLock = TaskLockUtil.getVerifyTask(t.getExamId().toString());
- return taskLock.exist(t.getId(), user);
- }
- @Override
- public IPage<BatchEntity> findUnVerify(Long examId, int pageNumber, int pageSize, VerifyStatus status) {
- return this.baseMapper.findUnVerify(new Page<>(pageNumber, pageSize), examId, status);
- }
- @Override
- public List<String> batchScanner(Long examId) {
- return baseMapper.batchScanner(examId);
- }
- @Override
- public List<ScannerWorkloadVo> workload(WorkloadDomain domain) {
- Long examId = domain.getExamId();
- Long startTime = domain.getStartTime();
- Long endTime = domain.getEndTime();
- if (examId == null) {
- throw new ParameterException("examId不能为空");
- }
- return baseMapper.workload(examId, startTime, endTime);
- }
- @Override
- public Integer findStudentCountByBatch(Long batchId) {
- return baseMapper.findStudentCountByBatch(batchId);
- }
- @Override
- public BatchEntity findByPaperId(Long paperId) {
- return baseMapper.selectById(batchPaperService.findByPaperId(paperId).getBatchId());
- }
- @Override
- public TaskStatusVo getCheckImageStatus(Long examId, User user) {
- TaskStatusVo vo = new TaskStatusVo();
- vo.setFinishCount(this.getCheckCountByExamId(examId, CheckStatus.FINISH, user));
- vo.setTodoCount(this.getCheckCountByExamId(examId, CheckStatus.WAITING, user));
- return vo;
- }
- @Override
- public VerifyTaskVo getCheckImageTask(Long examId, User user) {
- int retry = 1;
- VerifyTaskVo task = null;
- while (task == null) {
- List<BatchEntity> list = this.findUnCheck(examId, retry, 20, BatchStatus.FINISH, CheckStatus.WAITING)
- .getRecords();
- if (list.isEmpty()) {
- break;
- }
- for (BatchEntity t : list) {
- if (this.applyCheckImageTask(t, user.getAccount())) {
- task = toCheckTaskVo(t);
- break;
- }
- }
- if (task == null) {
- retry++;
- }
- }
- if (task == null) {
- throw NotFoundExceptions.NO_SYNC_VERIFY_TASK;
- }
- return task;
- }
- private VerifyTaskVo toCheckTaskVo(BatchEntity batch) {
- VerifyTaskVo vo = new VerifyTaskVo();
- vo.setBatchId(batch.getId());
- vo.setCreateTime(batch.getCreateTime());
- vo.setDevice(batch.getDevice());
- vo.setPackageCode(batch.getPackageCode());
- Map<Long, VerifyStudentVo> studentMap = new LinkedHashMap<>();
- List<BatchDetailDO> list = baseMapper.batchDetailListToCheck(batch.getId(), true);
- for (BatchDetailDO item : list) {
- VerifyStudentVo student = studentMap.computeIfAbsent(item.getId(), key -> VerifyStudentVo.build(item));
- student.findOrCreatePaper(item).getPages().add(item.getSheetPath());
- }
- vo.setStudents(new ArrayList<>(studentMap.values()));
- return vo;
- }
- @Override
- public VerifyTaskVo getHistoryCheckImageTask(Long examId, Long batchId, User user) {
- if (examId == null) {
- throw new ParameterException("examId不能为空");
- }
- if (user.getId() == null) {
- throw new ParameterException("userId不能为空");
- }
- BatchEntity batchEntity = this.baseMapper.getHistory(examId, batchId, user.getId(), CheckStatus.FINISH);
- if (batchEntity == null) {
- throw NotFoundExceptions.NO_CHECK_IMAGE_TASK;
- }
- VerifyTaskVo task = toCheckTaskVo(batchEntity);
- return task;
- }
- @Transactional
- @Override
- public CheckImageSubmitVo submitCheckImageTask(Long examId, Long batchId, User user) {
- BatchEntity entity = this.getById(batchId);
- if (entity == null) {
- throw new ParameterException("批次不存在");
- }
- if (entity.getCheckStatus() == CheckStatus.FINISH) {
- throw new ParameterException("该批次已经被审核");
- }
- entity.setCheckStatus(CheckStatus.FINISH);
- entity.setCheckImageTime(System.currentTimeMillis());
- entity.setCheckImageUserId(user.getId());
- this.saveOrUpdate(entity);
- this.releaseCheckImageTask(entity);
- CheckImageSubmitVo vo = new CheckImageSubmitVo();
- vo.setBatchId(batchId);
- vo.setUpdateTime(entity.getUpdateTime());
- vo.getStatus().setFinishCount(this.getCheckCountByExamId(examId, CheckStatus.FINISH, user));
- vo.getStatus().setTodoCount(this.getCheckCountByExamId(examId, CheckStatus.WAITING, user));
- return vo;
- }
- @Override
- public void releaseCheckImageTask(Long examId, User user) {
- TaskLock taskLock = TaskLockUtil.getCheckTask(examId.toString());
- taskLock.clear(user.getAccount());
- }
- @Override
- public int getCheckCountByExamId(Long examId, CheckStatus status, User user) {
- QueryWrapper<BatchEntity> wrapper = new QueryWrapper<>();
- LambdaQueryWrapper<BatchEntity> lw = wrapper.lambda();
- lw.eq(BatchEntity::getExamId, examId);
- lw.eq(BatchEntity::getCheckStatus, status);
- lw.eq(BatchEntity::getStatus, BatchStatus.FINISH);
- // 审核员只统计自身已完成的数量
- if (status == CheckStatus.FINISH && user.getRole() == Role.AUDITOR) {
- lw.eq(BatchEntity::getCheckImageUserId, user.getId());
- }
- return this.count(wrapper);
- }
- @Override
- public void releaseCheckImageTask(BatchEntity t) {
- TaskLock taskLock = TaskLockUtil.getCheckTask(t.getExamId().toString());
- taskLock.remove(t.getId().toString());
- }
- @Override
- public IPage<BatchEntity> findUnCheck(Long examId, int pageNumber, int pageSize, BatchStatus batchStatus,
- CheckStatus checkStatus) {
- return this.baseMapper.findUnCheck(new Page<>(pageNumber, pageSize), examId, batchStatus, checkStatus);
- }
- @Override
- public boolean applyCheckImageTask(BatchEntity t, String user) {
- TaskLock taskLock = TaskLockUtil.getCheckTask(t.getExamId().toString());
- boolean lock = taskLock.add(t.getId(), user);
- // 上锁失败直接返回
- if (!lock) {
- return false;
- }
- // 重复校验任务状态
- if (CheckStatus.WAITING.equals(t.getCheckStatus())) {
- return true;
- } else {
- taskLock.remove(t.getId().toString());
- return false;
- }
- }
- @Override
- @Transactional
- public void batchVerifyCancel(User user, Long examId) {
- QueryWrapper<BatchEntity> wrapper = new QueryWrapper<>();
- LambdaQueryWrapper<BatchEntity> lw = wrapper.lambda();
- lw.eq(BatchEntity::getExamId, examId);
- lw.eq(BatchEntity::getVerifyStatus, VerifyStatus.WAITING);
- List<BatchEntity> list = this.list(lw);
- for (BatchEntity batch : list) {
- List<BatchPaperEntity> batchPaperList = batchPaperService.findByBatchId(batch.getId());
- Map<Long, List<StudentPaperEntity>> studentMap = new HashMap<>();
- for (BatchPaperEntity batchPaper : batchPaperList) {
- studentMap.computeIfAbsent(batchPaper.getStudentId(), key -> new ArrayList<>())
- .add(new StudentPaperEntity(batchPaper.getStudentId(), batchPaper.getPaperNumber(),
- batchPaper.getPaperId()));
- }
- for (Map.Entry<Long, List<StudentPaperEntity>> entry : studentMap.entrySet()) {
- concurrentService.getReadWriteLock(LockType.STUDENT + "-" + entry.getKey()).writeLock().lock();
- try {
- studentService.updateStudentAndPaper(user, entry.getKey(), entry.getValue());
- studentService.updateAssignedCheckCount(entry.getKey(), true);
- } finally {
- concurrentService.getReadWriteLock(LockType.STUDENT + "-" + entry.getKey()).writeLock().unlock();
- }
- }
- batch.setVerifyStatus(VerifyStatus.CANCEL);
- }
- this.updateBatchById(list);
- }
- @Override
- @Transactional
- public void updateBatchCount() {
- QueryWrapper<BatchEntity> wrapper = new QueryWrapper<>();
- LambdaQueryWrapper<BatchEntity> lw = wrapper.lambda();
- lw.eq(BatchEntity::getStatus, BatchStatus.INIT);
- List<BatchEntity> list = this.list(lw);
- for (BatchEntity batch : list) {
- updateAssignedCount(batch.getId());
- updateScanCount(batch.getId());
- }
- }
- @Override
- public List<SubjectVo> subjectList(BatchSubjectQuery req) {
- if (req.getExamId() == null) {
- throw new ParameterException("考试id不能为空");
- }
- return this.baseMapper.subjectList(req);
- }
- @Override
- public List<DeviceVo> deviceList(BatchDeviceQuery req) {
- if (req.getExamId() == null) {
- throw new ParameterException("考试id不能为空");
- }
- if (StringUtils.isBlank(req.getSubjectCode())) {
- throw new ParameterException("科目代码不能为空");
- }
- return this.baseMapper.deviceList(req);
- }
- @Override
- public List<BatchVo> batchList(BatchQuery req) {
- if (req.getExamId() == null) {
- throw new ParameterException("考试id不能为空");
- }
- if (StringUtils.isBlank(req.getSubjectCode())) {
- throw new ParameterException("科目代码不能为空");
- }
- if (StringUtils.isBlank(req.getDevice())) {
- throw new ParameterException("设备不能为空");
- }
- return this.baseMapper.batchList(req);
- }
- @Override
- public List<BatchStudentSimpleVo> studentList(Long batchId) {
- if (batchId == null) {
- throw new ParameterException("批次id不能为空");
- }
- return this.baseMapper.studentList(batchId);
- }
- }
|