|
@@ -1,5 +1,8 @@
|
|
|
package cn.com.qmth.scancentral.service.impl;
|
|
|
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Calendar;
|
|
|
import java.util.HashMap;
|
|
@@ -7,8 +10,14 @@ import java.util.HashSet;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Set;
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
+import java.util.concurrent.LinkedBlockingQueue;
|
|
|
+import java.util.concurrent.ThreadPoolExecutor;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
|
+import org.apache.commons.io.FileUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
@@ -17,29 +26,44 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
|
|
|
import com.qmth.boot.core.exception.ParameterException;
|
|
|
+import com.qmth.boot.core.exception.StatusException;
|
|
|
import com.qmth.boot.core.fss.store.FileStore;
|
|
|
+import com.qmth.boot.tools.uuid.FastUUID;
|
|
|
|
|
|
import cn.com.qmth.scancentral.bean.ImportSubjectDomain;
|
|
|
import cn.com.qmth.scancentral.bean.SubjectConfigDomain;
|
|
|
import cn.com.qmth.scancentral.bean.User;
|
|
|
+import cn.com.qmth.scancentral.consumer.AnswerDataExportConsumer;
|
|
|
import cn.com.qmth.scancentral.dao.SubjectDao;
|
|
|
+import cn.com.qmth.scancentral.entity.MarkSiteEntity;
|
|
|
import cn.com.qmth.scancentral.entity.SubjectEntity;
|
|
|
+import cn.com.qmth.scancentral.enums.ExamStatus;
|
|
|
import cn.com.qmth.scancentral.service.BatchPaperService;
|
|
|
+import cn.com.qmth.scancentral.service.DataExportTaskService;
|
|
|
import cn.com.qmth.scancentral.service.FileService;
|
|
|
+import cn.com.qmth.scancentral.service.MarkSiteService;
|
|
|
import cn.com.qmth.scancentral.service.StudentService;
|
|
|
import cn.com.qmth.scancentral.service.SubjectService;
|
|
|
+import cn.com.qmth.scancentral.support.SpringContextHolder;
|
|
|
import cn.com.qmth.scancentral.util.Calculator;
|
|
|
import cn.com.qmth.scancentral.util.FileUtil;
|
|
|
+import cn.com.qmth.scancentral.vo.ExportCetMarkingQueryVo;
|
|
|
+import cn.com.qmth.scancentral.vo.ExportCetVo;
|
|
|
+import cn.com.qmth.scancentral.vo.ImportStudentQueryVo;
|
|
|
import cn.com.qmth.scancentral.vo.SubjectConfigVo;
|
|
|
import cn.com.qmth.scancentral.vo.examinfo.SubjectConfig;
|
|
|
+import cn.com.qmth.scancentral.vo.subject.DataExportTaskVo;
|
|
|
import cn.com.qmth.scancentral.vo.subject.ScanProgressVo;
|
|
|
import cn.com.qmth.scancentral.vo.subject.SubjectBreachVo;
|
|
|
import cn.com.qmth.scancentral.vo.subject.SubjectCustStatusVo;
|
|
|
import cn.com.qmth.scancentral.vo.subject.SubjectScanProgressVo;
|
|
|
+import cn.com.qmth.scancentral.vo.subject.TaskIdVo;
|
|
|
|
|
|
@Service
|
|
|
public class SubjectServiceImpl extends MppServiceImpl<SubjectDao, SubjectEntity> implements SubjectService {
|
|
|
|
|
|
+ private static ExecutorService exec;
|
|
|
+
|
|
|
@Autowired
|
|
|
private StudentService studentService;
|
|
|
|
|
@@ -52,6 +76,29 @@ public class SubjectServiceImpl extends MppServiceImpl<SubjectDao, SubjectEntity
|
|
|
@Autowired
|
|
|
private BatchPaperService batchPaperService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private DataExportTaskService dataExportTaskService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private MarkSiteService markSiteService;
|
|
|
+
|
|
|
+ static {
|
|
|
+ int threadCount = 5;
|
|
|
+ exec = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.SECONDS,
|
|
|
+ new LinkedBlockingQueue<>(threadCount * 2), r -> {
|
|
|
+ Thread t = new Thread(r);
|
|
|
+ return t;
|
|
|
+ }, (r, executor) -> {
|
|
|
+ if (!executor.isShutdown()) {
|
|
|
+ try {
|
|
|
+ executor.getQueue().put(r);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
@Transactional
|
|
|
@Override
|
|
|
public int cleanByExamId(Long examId, String subjectCode) {
|
|
@@ -239,4 +286,131 @@ public class SubjectServiceImpl extends MppServiceImpl<SubjectDao, SubjectEntity
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public TaskIdVo answerDataExport(Long examId, String subjectCode) {
|
|
|
+ ImportStudentQueryVo sreq = new ImportStudentQueryVo();
|
|
|
+ sreq.setExamId(examId);
|
|
|
+ int scount = studentService.countByQuery(sreq);
|
|
|
+ if (scount == 0) {
|
|
|
+ throw new StatusException("没有考生信息");
|
|
|
+ }
|
|
|
+ DataExportTaskVo vo = new DataExportTaskVo();
|
|
|
+ vo.setExamId(examId);
|
|
|
+ vo.setSubjectCode(subjectCode);
|
|
|
+ vo.setSuccess(true);
|
|
|
+ vo.setProgress(0.0);
|
|
|
+ vo.setFileName("扫描答案.dbf");
|
|
|
+ AnswerDataExportConsumer com = SpringContextHolder.getBean(AnswerDataExportConsumer.class);
|
|
|
+ com.setVo(vo);
|
|
|
+ exec.execute(com);
|
|
|
+ dataExportTaskService.addTask(vo);
|
|
|
+ return TaskIdVo.create(vo.getTaskId());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void answerDataExportDispose(DataExportTaskVo vo) {
|
|
|
+ File temDir = new File("temp/" + FastUUID.get() + "/");
|
|
|
+ temDir.mkdirs();
|
|
|
+ ExportCetMarkingQueryVo req = new ExportCetMarkingQueryVo();
|
|
|
+ req.setExamId(vo.getExamId());
|
|
|
+ req.setPageSize(100000);
|
|
|
+ int pageNumber = 0;
|
|
|
+ req.setPageNumber(pageNumber);
|
|
|
+ Set<String> examNumbers = new HashSet<>();
|
|
|
+ Map<String, MarkSiteEntity> cms = readCetMarking(vo.getExamId());
|
|
|
+ while (true) {
|
|
|
+ req.setPageNumber(++pageNumber);
|
|
|
+ List<ExportCetVo> list = studentService.exportCetData(req);
|
|
|
+ if (CollectionUtils.isEmpty(list)) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ exportAnswer(examNumbers, temDir, list, cms);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void exportAnswer(Set<String> examNumbers, File temDir, List<ExportCetVo> list,
|
|
|
+ Map<String, MarkSiteEntity> cms) {
|
|
|
+ Map<String, List<String>> subjects = new HashMap<>();
|
|
|
+ for (ExportCetVo data : list) {
|
|
|
+ String key = data.getSubjectCode() + "-" + data.getExamNumber();
|
|
|
+ if (examNumbers.contains(key)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ examNumbers.add(key);
|
|
|
+ List<String> line = new ArrayList<>();
|
|
|
+ line.add(data.getExamNumber());
|
|
|
+ line.add(data.getName());
|
|
|
+ if (ExamStatus.ABSENT.equals(data.getExamStatus())) {
|
|
|
+ line.add("1");
|
|
|
+ } else {
|
|
|
+ line.add("0");
|
|
|
+ }
|
|
|
+ line.add(data.getSubjectCode());
|
|
|
+ line.add(data.getAnswer());
|
|
|
+ line.add(data.getCardFirst() + "");
|
|
|
+ line.add(data.getCardSecond() + "");
|
|
|
+ line.add(StringUtils.isBlank(data.getBreachCode()) ? "0" : data.getBreachCode());
|
|
|
+ line.add(data.getPaperType());
|
|
|
+ int subjectCode = Integer.valueOf(data.getExamNumber().substring(9, 10));
|
|
|
+ String markingCode;
|
|
|
+ if (subjectCode >= 3 && subjectCode <= 9) {
|
|
|
+ markingCode = "88";
|
|
|
+ } else {
|
|
|
+ if (ExamStatus.ABSENT.equals(data.getExamStatus()) || "000000".equals(data.getPaperType())
|
|
|
+ || "999999".equals(data.getPaperType())) {
|
|
|
+ markingCode = "00";
|
|
|
+ } else {
|
|
|
+ int site = Integer.valueOf(data.getExamNumber().substring(10, 13));
|
|
|
+ MarkSiteEntity cm = cms.get(data.getSubjectCode() + "-" + data.getPaperType());
|
|
|
+ if (cm == null) {
|
|
|
+ throw new StatusException(
|
|
|
+ "未找到评卷点数据,SubjectCode:" + data.getSubjectCode() + " PaperType:" + data.getPaperType());
|
|
|
+ }
|
|
|
+ if (site % 2 == 0) {
|
|
|
+ markingCode = cm.getEvenNumber();
|
|
|
+ } else {
|
|
|
+ markingCode = cm.getOddNumber();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ line.add(markingCode);
|
|
|
+ List<String> lines = subjects.get(data.getSubjectCode());
|
|
|
+ if (lines == null) {
|
|
|
+ lines = new ArrayList<>();
|
|
|
+ subjects.put(data.getSubjectCode(), lines);
|
|
|
+ }
|
|
|
+ lines.add(StringUtils.join(line, ","));
|
|
|
+ }
|
|
|
+ writeResult(subjects, temDir, "answer-data.txt");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void writeResult(Map<String, List<String>> subjects, File rootDir, String fileName) {
|
|
|
+ for (String k : subjects.keySet()) {
|
|
|
+ File file = new File(rootDir.getAbsolutePath() + "/" + k + "/" + fileName);
|
|
|
+ file.getParentFile().mkdirs();
|
|
|
+ if (!file.exists()) {
|
|
|
+ try {
|
|
|
+ file.createNewFile();
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new StatusException("", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ FileUtils.writeLines(file, StandardCharsets.UTF_8.name(), subjects.get(k), true);
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new StatusException("文件处理出错", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, MarkSiteEntity> readCetMarking(Long examId) {
|
|
|
+ Map<String, MarkSiteEntity> ret = new HashMap<>();
|
|
|
+ List<MarkSiteEntity> list = markSiteService.findByExam(examId);
|
|
|
+ if (CollectionUtils.isNotEmpty(list)) {
|
|
|
+ for (MarkSiteEntity e : list) {
|
|
|
+ ret.put(e.getSubjectCode() + "-" + e.getPaperType(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
}
|