|
@@ -1,27 +1,38 @@
|
|
|
package cn.com.qmth.scancloud.tools.service.impl;
|
|
|
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFRow;
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFSheet;
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+
|
|
|
+import com.fasterxml.jackson.databind.JsonNode;
|
|
|
+
|
|
|
import cn.com.qmth.scancloud.tools.config.SysProperty;
|
|
|
+import cn.com.qmth.scancloud.tools.enums.ExamStatus;
|
|
|
import cn.com.qmth.scancloud.tools.enums.TaskType;
|
|
|
-import cn.com.qmth.scancloud.tools.model.ExamStudent;
|
|
|
+import cn.com.qmth.scancloud.tools.model.CetMarking;
|
|
|
+import cn.com.qmth.scancloud.tools.model.ExportCetVo;
|
|
|
import cn.com.qmth.scancloud.tools.service.AbstractTask;
|
|
|
import cn.com.qmth.scancloud.tools.utils.FileHelper;
|
|
|
import cn.com.qmth.scancloud.tools.utils.HttpHelper;
|
|
|
import cn.com.qmth.scancloud.tools.utils.JsonHelper;
|
|
|
import cn.com.qmth.scancloud.tools.utils.StatusException;
|
|
|
-import com.fasterxml.jackson.databind.JsonNode;
|
|
|
-import org.apache.commons.collections4.CollectionUtils;
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
-import org.slf4j.Logger;
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
-
|
|
|
-import java.io.File;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
|
|
|
/**
|
|
|
- * 考生扫描结果导出
|
|
|
+ * 考生扫描结果和评卷数据导出
|
|
|
*/
|
|
|
public class ObjectiveQuestionExportTask extends AbstractTask {
|
|
|
|
|
@@ -46,8 +57,6 @@ public class ObjectiveQuestionExportTask extends AbstractTask {
|
|
|
params = new HashMap<>();
|
|
|
}
|
|
|
params.put("examId", examId);
|
|
|
- params.put("scanStatus", "SCANNED");
|
|
|
- params.put("withAnswer", true);
|
|
|
|
|
|
String url = SysProperty.SCAN_SERVER_URL + "/api/tool/exam/student/count";
|
|
|
String json = JsonHelper.toJson(params);
|
|
@@ -63,26 +72,27 @@ public class ObjectiveQuestionExportTask extends AbstractTask {
|
|
|
log.warn("未查询到相关考生!");
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+ Map<String, CetMarking> cms = readCetMarking();
|
|
|
// 分批处理
|
|
|
- String filePath = String.format("%s/export-%s.txt", SysProperty.DATA_DIR, System.currentTimeMillis());
|
|
|
- String queryUrl = SysProperty.SCAN_SERVER_URL + "/api/tool/exam/student/find";
|
|
|
+ String filePath = String.format("%s/export-slice-data.txt", SysProperty.DATA_DIR);
|
|
|
+ String answerFilePath = String.format("%s/export-answer-data.txt", SysProperty.DATA_DIR);
|
|
|
+ String queryUrl = SysProperty.SCAN_SERVER_URL + "/api/tool/export/cet/data";
|
|
|
params.put("pageSize", 100);
|
|
|
int pageNumber = 0;
|
|
|
int sum = 0;
|
|
|
-
|
|
|
+ Set<String> examNumbers=new HashSet<>();
|
|
|
while (true) {
|
|
|
params.put("pageNumber", ++pageNumber);
|
|
|
String queryJson = JsonHelper.toJson(params);
|
|
|
String queryResult = HttpHelper.post(queryUrl, queryJson);
|
|
|
|
|
|
- List<ExamStudent> list = JsonHelper.toList(queryResult, ExamStudent.class);
|
|
|
+ List<ExportCetVo> list = JsonHelper.toList(queryResult, ExportCetVo.class);
|
|
|
if (CollectionUtils.isEmpty(list)) {
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- this.export(list, filePath);
|
|
|
-
|
|
|
+ exportMarking(list, filePath, cms,examNumbers);
|
|
|
+ exportAnswer(list, answerFilePath, cms,examNumbers);
|
|
|
sum += list.size();
|
|
|
float rate = sum * 100f / total;
|
|
|
log.info("已处理数:{} 进度:{}%", sum, rate);
|
|
@@ -90,25 +100,129 @@ public class ObjectiveQuestionExportTask extends AbstractTask {
|
|
|
|
|
|
log.info("导出文件:" + filePath);
|
|
|
}
|
|
|
-
|
|
|
- private void export(List<ExamStudent> list, String filePath) {
|
|
|
- // OW客观题结果格式:准考证号,科目代码,客观题,卷型
|
|
|
- String template = "%s,%s,%s,%s";
|
|
|
-
|
|
|
+
|
|
|
+ private void exportAnswer(List<ExportCetVo> list, String filePath, Map<String, CetMarking> cms,Set<String> examNumbers) {
|
|
|
List<String> lines = new ArrayList<>();
|
|
|
- for (ExamStudent data : list) {
|
|
|
- // 客观题 按“;”分割
|
|
|
- String answers = CollectionUtils.isNotEmpty(data.getAnswer())
|
|
|
- ? StringUtils.join(data.getAnswer(), ";") : "";
|
|
|
+ for (ExportCetVo data : list) {
|
|
|
+ if(examNumbers.contains(data.getExamNumber())) {
|
|
|
+ log.warn("有重复数据,准考证号:{}", data.getExamNumber());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ examNumbers.add(data.getExamNumber());
|
|
|
+ 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(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 {
|
|
|
+ int site = Integer.valueOf(data.getExamNumber().substring(10, 13));
|
|
|
+ if(site%2==0) {
|
|
|
+ markingCode=cms.get(data.getPaperType()).getEvenNumber();
|
|
|
+ }else {
|
|
|
+ markingCode=cms.get(data.getPaperType()).getOddNumber();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ line.add(markingCode);
|
|
|
+ lines.add(StringUtils.join(line, ","));
|
|
|
+ }
|
|
|
|
|
|
- // 如果没有卷型识别结果默认用1,有的话用实际的识别结果
|
|
|
- String paperType = (StringUtils.isNotEmpty(data.getPaperType())) ? data.getPaperType() : "1";
|
|
|
+ File file = new File(filePath);
|
|
|
+ if (file.exists()) {
|
|
|
+ file.delete();
|
|
|
+ }
|
|
|
+ FileHelper.writeLines(file, lines, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void exportMarking(List<ExportCetVo> list, String filePath, Map<String, CetMarking> cms,Set<String> examNumbers) {
|
|
|
+ String template = "%s,%s,%s";
|
|
|
|
|
|
- lines.add(String.format(template, data.getExamNumber(), data.getSubjectCode(), answers, paperType));
|
|
|
+ List<String> lines = new ArrayList<>();
|
|
|
+ for (ExportCetVo data : list) {
|
|
|
+ if(examNumbers.contains(data.getExamNumber())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ examNumbers.add(data.getExamNumber());
|
|
|
+ int subjectCode = Integer.valueOf(data.getExamNumber().substring(9, 10));
|
|
|
+ String markingCode;
|
|
|
+ if (subjectCode >= 3 && subjectCode <= 9) {
|
|
|
+ markingCode = "88";
|
|
|
+ }else {
|
|
|
+ int site = Integer.valueOf(data.getExamNumber().substring(10, 13));
|
|
|
+ if(site%2==0) {
|
|
|
+ markingCode=cms.get(data.getPaperType()).getEvenNumber();
|
|
|
+ }else {
|
|
|
+ markingCode=cms.get(data.getPaperType()).getOddNumber();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lines.add(String.format(template, data.getExamNumber(), markingCode,
|
|
|
+ StringUtils.join(data.getSliceImageInfo(), ";")));
|
|
|
}
|
|
|
|
|
|
File file = new File(filePath);
|
|
|
+ if (file.exists()) {
|
|
|
+ file.delete();
|
|
|
+ }
|
|
|
FileHelper.writeLines(file, lines, true);
|
|
|
}
|
|
|
|
|
|
+ private Map<String, CetMarking> readCetMarking() {
|
|
|
+ if (StringUtils.isBlank(SysProperty.MARKING_PLACE)) {
|
|
|
+ throw new StatusException("【scan.tool.marking-place】未配置!");
|
|
|
+ }
|
|
|
+ File file = new File(SysProperty.MARKING_PLACE);
|
|
|
+ if (!file.exists()) {
|
|
|
+ throw new StatusException("文件不存在:" + SysProperty.MARKING_PLACE);
|
|
|
+ }
|
|
|
+ List<CetMarking> list = new ArrayList<CetMarking>();
|
|
|
+ XSSFWorkbook wb = null;
|
|
|
+ try {
|
|
|
+ wb = new XSSFWorkbook(SysProperty.MARKING_PLACE);
|
|
|
+ XSSFSheet sheet = wb.getSheetAt(0);
|
|
|
+ int rows = sheet.getLastRowNum();
|
|
|
+ for (int i = 1; i <= rows; i++) {
|
|
|
+ CetMarking cm = new CetMarking();
|
|
|
+ list.add(cm);
|
|
|
+ XSSFRow row = sheet.getRow(i);
|
|
|
+ if (StringUtils.isBlank(row.getCell(3).getStringCellValue())
|
|
|
+ || StringUtils.isBlank(row.getCell(5).getStringCellValue())
|
|
|
+ || StringUtils.isBlank(row.getCell(6).getStringCellValue())) {
|
|
|
+ throw new StatusException("评卷点文件中第" + (i + 1) + "行,条形码值、奇数考场评卷点代码、偶数考场评卷点代码都不能为空");
|
|
|
+ }
|
|
|
+ cm.setPaperType(row.getCell(3).getStringCellValue());
|
|
|
+ cm.setOddNumber(row.getCell(5).getStringCellValue());
|
|
|
+ cm.setEvenNumber(row.getCell(7).getStringCellValue());
|
|
|
+ }
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("系统错误", e);
|
|
|
+ throw new StatusException("系统错误");
|
|
|
+ } finally {
|
|
|
+ if (wb != null) {
|
|
|
+ try {
|
|
|
+ wb.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (list.size() == 0) {
|
|
|
+ throw new StatusException("文件内容为空:" + SysProperty.MARKING_PLACE);
|
|
|
+ }
|
|
|
+ Map<String, CetMarking> map = list.stream()
|
|
|
+ .collect(Collectors.toMap(CetMarking::getPaperType, c -> c, (key1, key2) -> key2));
|
|
|
+
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
}
|