|
@@ -1,17 +1,44 @@
|
|
|
package com.qmth.teachcloud.mark.service.impl;
|
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.qmth.boot.core.exception.ParameterException;
|
|
|
+import com.qmth.teachcloud.common.entity.MarkStudent;
|
|
|
import com.qmth.teachcloud.common.entity.SysUser;
|
|
|
import com.qmth.teachcloud.common.enums.scan.ConditionType;
|
|
|
+import com.qmth.teachcloud.common.enums.scan.OmrField;
|
|
|
+import com.qmth.teachcloud.common.service.MarkStudentService;
|
|
|
+import com.qmth.teachcloud.mark.bean.OmrTaskItem;
|
|
|
+import com.qmth.teachcloud.mark.bean.OmrTaskPage;
|
|
|
import com.qmth.teachcloud.mark.dto.ScanOmrTaskDto;
|
|
|
+import com.qmth.teachcloud.mark.dto.ScanOmrTaskPageDto;
|
|
|
import com.qmth.teachcloud.mark.dto.ScanOmrTaskResultDto;
|
|
|
import com.qmth.teachcloud.mark.dto.ScanOmrTaskSaveDto;
|
|
|
import com.qmth.teachcloud.mark.dto.ScanOmrTaskStatusDto;
|
|
|
import com.qmth.teachcloud.mark.entity.ScanOmrTask;
|
|
|
+import com.qmth.teachcloud.mark.entity.ScanPaper;
|
|
|
+import com.qmth.teachcloud.mark.entity.ScanPaperPage;
|
|
|
+import com.qmth.teachcloud.mark.entity.ScanStudentPaper;
|
|
|
+import com.qmth.teachcloud.mark.enums.OmrTaskStatus;
|
|
|
import com.qmth.teachcloud.mark.mapper.ScanOmrTaskMapper;
|
|
|
import com.qmth.teachcloud.mark.service.ScanOmrTaskService;
|
|
|
+import com.qmth.teachcloud.mark.service.ScanPaperPageService;
|
|
|
+import com.qmth.teachcloud.mark.service.ScanPaperService;
|
|
|
+import com.qmth.teachcloud.mark.service.ScanStudentPaperService;
|
|
|
+import com.qmth.teachcloud.mark.utils.TaskLock;
|
|
|
+import com.qmth.teachcloud.mark.utils.TaskLockUtil;
|
|
|
|
|
|
/**
|
|
|
* <p>
|
|
@@ -23,17 +50,246 @@ import com.qmth.teachcloud.mark.service.ScanOmrTaskService;
|
|
|
*/
|
|
|
@Service
|
|
|
public class ScanOmrTaskServiceImpl extends ServiceImpl<ScanOmrTaskMapper, ScanOmrTask> implements ScanOmrTaskService {
|
|
|
+ @Autowired
|
|
|
+ private ScanStudentPaperService studentPaperService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private MarkStudentService studentService;
|
|
|
+ @Autowired
|
|
|
+ private ScanPaperService paperService;
|
|
|
+ @Autowired
|
|
|
+ private ScanPaperPageService pageService;
|
|
|
+
|
|
|
+ private static final String OMR_SUSPECT = "?";
|
|
|
|
|
|
+ private static final String OMR_BLANK = "#";
|
|
|
+
|
|
|
@Override
|
|
|
public ScanOmrTask buildTask(ConditionType c, Long studentId) {
|
|
|
- // TODO Auto-generated method stub
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
+ private List<ScanStudentPaper> clearAndToDispose(ConditionType c, Long studentId) {
|
|
|
+ List<ScanStudentPaper> spes = studentPaperService.findByStudentId(studentId);
|
|
|
+ if (CollectionUtils.isEmpty(spes)) {
|
|
|
+ return spes;
|
|
|
+ }
|
|
|
+ List<ScanOmrTask> tasks = getByStudent(c, studentId);
|
|
|
+ if (CollectionUtils.isEmpty(tasks)) {
|
|
|
+ return spes;
|
|
|
+ }
|
|
|
+ Map<Integer, Long> speMap = new HashMap<>();
|
|
|
+ for (ScanStudentPaper spe : spes) {
|
|
|
+ speMap.put(spe.getPaperNumber(), spe.getPaperId());
|
|
|
+ }
|
|
|
+ Map<Integer, Long> taskMap = new HashMap<>();
|
|
|
+ for (ScanOmrTask t : tasks) {
|
|
|
+ taskMap.put(t.getPaperNumber(), t.getPaperId());
|
|
|
+ }
|
|
|
+ if (ConditionType.FILL_SUSPECT.equals(c)) {
|
|
|
+ List<ScanStudentPaper> ret = new ArrayList<>();
|
|
|
+ for (ScanStudentPaper spe : spes) {
|
|
|
+ Long paperId = taskMap.get(spe.getPaperNumber());
|
|
|
+ if (paperId == null) {// 没有task的直接创建
|
|
|
+ ret.add(spe);
|
|
|
+ } else if (paperId.longValue() != spe.getPaperId().longValue()) {// 和task不一致的删除并创建
|
|
|
+ delete(c, studentId, paperId);
|
|
|
+ ret.add(spe);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (ScanOmrTask t : tasks) {
|
|
|
+ if (speMap.get(t.getPaperNumber()) == null) {// 不在绑定关系的task删除
|
|
|
+ delete(c, studentId, t.getPaperId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+ } else {
|
|
|
+ if (spes.size() != tasks.size()) {// 数量不一致的删除重建
|
|
|
+ delete(c, studentId);
|
|
|
+ return spes;
|
|
|
+ }
|
|
|
+ for (ScanOmrTask t : tasks) {
|
|
|
+ if (!t.getPaperId().equals(speMap.get(t.getPaperNumber()))) {// 有一个不一致的删除重建
|
|
|
+ delete(c, studentId);
|
|
|
+ return spes;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;// 完全一致的不处理
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<ScanOmrTask> getByStudent(ConditionType c, Long studentId) {
|
|
|
+ QueryWrapper<ScanOmrTask> wrapper = new QueryWrapper<>();
|
|
|
+ LambdaQueryWrapper<ScanOmrTask> lw = wrapper.lambda();
|
|
|
+ lw.eq(ScanOmrTask::getConditions, c);
|
|
|
+ lw.eq(ScanOmrTask::getStudentId, studentId);
|
|
|
+ return baseMapper.selectList(wrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void delete( ConditionType c, Long studentId, Long paperId) {
|
|
|
+ UpdateWrapper<ScanOmrTask> wrapper = new UpdateWrapper<>();
|
|
|
+ LambdaUpdateWrapper<ScanOmrTask> lw = wrapper.lambda();
|
|
|
+ lw.eq(ScanOmrTask::getConditions, c);
|
|
|
+ lw.eq(ScanOmrTask::getStudentId, studentId);
|
|
|
+ lw.eq(ScanOmrTask::getPaperId, paperId);
|
|
|
+ this.baseMapper.delete(wrapper);
|
|
|
+ }
|
|
|
+ private void delete( ConditionType c, Long studentId) {
|
|
|
+ UpdateWrapper<ScanOmrTask> wrapper = new UpdateWrapper<>();
|
|
|
+ LambdaUpdateWrapper<ScanOmrTask> lw = wrapper.lambda();
|
|
|
+ lw.eq(ScanOmrTask::getConditions, c);
|
|
|
+ lw.eq(ScanOmrTask::getStudentId, studentId);
|
|
|
+ this.baseMapper.delete(wrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean isAllBlank(List<ScanStudentPaper> paperIds) {
|
|
|
+ for (ScanStudentPaper spe : paperIds) {
|
|
|
+ ScanPaper paper = paperService.getById(spe.getPaperId());
|
|
|
+ if (paper == null) {
|
|
|
+ throw new ParameterException("paper不存在");
|
|
|
+ }
|
|
|
+ List<ScanPaperPage> pageList = pageService.listByPaperId(spe.getPaperId());
|
|
|
+ for (ScanPaperPage pageEntity : pageList) {
|
|
|
+ for (int i = 0; pageEntity.getQuestion() != null && pageEntity.getQuestion().getResult() != null
|
|
|
+ && i < pageEntity.getQuestion().getResult().size(); i++) {
|
|
|
+ String result = pageEntity.getQuestion().getResult().get(i);
|
|
|
+ if (!"#".equals(result)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
@Override
|
|
|
public ScanOmrTaskDto getTask(Long examId, Long userId) {
|
|
|
- // TODO Auto-generated method stub
|
|
|
- return null;
|
|
|
+ int retry = 0;
|
|
|
+ ScanOmrTaskDto task = null;
|
|
|
+ while (task == null) {
|
|
|
+ List<ScanOmrTask> list = this.findUnMarked(examId, retry * 20, 20, OmrTaskStatus.WAITING);
|
|
|
+ if (list.isEmpty()) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ for (ScanOmrTask t : list) {
|
|
|
+ if (this.apply(t, userId.toString())) {
|
|
|
+ task = toTaskVo(t, false);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (task == null) {
|
|
|
+ retry++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return task;
|
|
|
+ }
|
|
|
+
|
|
|
+ private ScanOmrTaskDto toTaskVo(ScanOmrTask task, boolean history) {
|
|
|
+ ScanOmrTaskDto vo = new ScanOmrTaskDto();
|
|
|
+ MarkStudent student = studentService.getById(task.getStudentId());
|
|
|
+ vo.setCardNumber(task.getCardNumber());
|
|
|
+ vo.setStudentCode(student.getStudentCode());
|
|
|
+ vo.setId(task.getId());
|
|
|
+ vo.setName(student.getStudentName());
|
|
|
+ vo.setPaperId(task.getPaperId());
|
|
|
+ vo.setPaperNumber(task.getPaperNumber());
|
|
|
+ vo.setSubjectCode(student.getCourseCode());
|
|
|
+ vo.setSubjectName(student.getCourseName());
|
|
|
+ List<ScanOmrTaskPageDto> pages = new ArrayList<>();
|
|
|
+ for (OmrTaskPage taskPage : task.getPages()) {
|
|
|
+ ScanOmrTaskPageDto page = new ScanOmrTaskPageDto();
|
|
|
+ Map<Integer, List<String>> question = new HashMap<>();
|
|
|
+ Map<Integer, List<String>> selective = new HashMap<>();
|
|
|
+ for (OmrTaskItem item : taskPage.getItems()) {
|
|
|
+ if (OmrField.ABSENT.equals(item.getField())) {
|
|
|
+ page.setAbsent(getBooleanItem(item, history));
|
|
|
+ }
|
|
|
+ if (OmrField.BREACH.equals(item.getField())) {
|
|
|
+ page.setBreach(getBooleanItem(item, history));
|
|
|
+ }
|
|
|
+ if (OmrField.PAPER_TYPE.equals(item.getField())) {
|
|
|
+ page.setPaperType(getStringItem(item, history));
|
|
|
+ }
|
|
|
+ if (OmrField.QUESTION.equals(item.getField())) {
|
|
|
+ List<String> content = getStringItem(item, history);
|
|
|
+ if (content != null) {
|
|
|
+ question.put(item.getIndex(), content);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (OmrField.SELECTIVE.equals(item.getField())) {
|
|
|
+ List<String> content = getStringItem(item, history);
|
|
|
+ if (content != null) {
|
|
|
+ selective.put(item.getIndex(), content);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (question.size() > 0) {
|
|
|
+ page.setQuestion(question);
|
|
|
+ }
|
|
|
+ if (selective.size() > 0) {
|
|
|
+ page.setSelective(selective);
|
|
|
+ }
|
|
|
+ // 有需要仲裁的数据才返回结构
|
|
|
+ if (page.getAbsent() != null || page.getBreach() != null || page.getPaperType() != null
|
|
|
+ || page.getQuestion() != null || page.getSelective() != null) {
|
|
|
+ page.setIndex(taskPage.getIndex());
|
|
|
+ ScanPaperPage p = pageService.findPaperIdAndIndex(task.getPaperId(), taskPage.getIndex());
|
|
|
+ page.setRecogData(p.getRecogData());
|
|
|
+ page.setUri(p.getSheetPath());
|
|
|
+ pages.add(page);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ vo.setPages(pages);
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<String> getStringItem(OmrTaskItem item, boolean history) {
|
|
|
+ List<String> value = new ArrayList<>();
|
|
|
+ value.add(item.getOmrResult());
|
|
|
+ if (history && item.getFirstResult() != null && item.getSecondResult() == null) {
|
|
|
+ value.add(item.getFirstResult());
|
|
|
+ } else if (history && item.getSecondResult() != null) {
|
|
|
+ value.add(item.getSecondResult());
|
|
|
+ }
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<Boolean> getBooleanItem(OmrTaskItem item, boolean history) {
|
|
|
+ List<Boolean> value = new ArrayList<>();
|
|
|
+ value.add(Boolean.valueOf(item.getOmrResult()));
|
|
|
+ if (history && item.getFirstResult() != null && item.getSecondResult() == null) {
|
|
|
+ value.add(Boolean.valueOf(item.getFirstResult()));
|
|
|
+ } else if (history && item.getSecondResult() != null) {
|
|
|
+ value.add(Boolean.valueOf(item.getSecondResult()));
|
|
|
+ }
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<ScanOmrTask> findUnMarked(Long examId, int pageNumber, int pageSize, OmrTaskStatus status) {
|
|
|
+ return this.baseMapper.findUnMarked(examId, pageNumber, pageSize, status);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean apply(ScanOmrTask t, String userId) {
|
|
|
+ TaskLock taskLock = TaskLockUtil.getOmrTask(t.getExamId().toString());
|
|
|
+ boolean lock = taskLock.add(t.getId(), 1, userId);
|
|
|
+ // 上锁失败直接返回
|
|
|
+ if (!lock) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // 重复校验任务状态
|
|
|
+ if (t.getStatus().equals(OmrTaskStatus.WAITING)) {
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ taskLock.remove(t.getId(), 1);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean hasApplied(ScanOmrTask t, String userId) {
|
|
|
+ TaskLock taskLock = TaskLockUtil.getOmrTask(t.getExamId().toString());
|
|
|
+ return taskLock.exist(t.getId(), 1, userId);
|
|
|
}
|
|
|
|
|
|
@Override
|