Przeglądaj źródła

缺考校验改异步任务

xiatian 8 miesięcy temu
rodzic
commit
b18806a1c2

+ 93 - 40
src/main/java/cn/com/qmth/scancentral/controller/admin/CheckController.java

@@ -1,5 +1,6 @@
 package cn.com.qmth.scancentral.controller.admin;
 
+import java.io.File;
 import java.io.IOException;
 import java.net.URLEncoder;
 import java.util.ArrayList;
@@ -12,6 +13,7 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.io.FileUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.task.AsyncTaskExecutor;
 import org.springframework.validation.annotation.Validated;
@@ -26,6 +28,7 @@ import com.qmth.boot.api.annotation.Aac;
 import com.qmth.boot.api.constant.ApiConstant;
 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.ReentrantException;
 import com.qmth.boot.core.exception.StatusException;
 import com.qmth.boot.tools.excel.ExcelWriter;
@@ -33,6 +36,7 @@ import com.qmth.boot.tools.excel.enums.ExcelType;
 import com.qmth.boot.tools.excel.model.DataMap;
 import com.qmth.boot.tools.iterator.PageListIterator;
 import com.qmth.boot.tools.iterator.SingletonIterator;
+import com.qmth.boot.tools.uuid.FastUUID;
 
 import cn.com.qmth.scancentral.bean.AbsentQueryDomain;
 import cn.com.qmth.scancentral.bean.AnswerQueryDomain;
@@ -45,6 +49,7 @@ import cn.com.qmth.scancentral.enums.GroupType;
 import cn.com.qmth.scancentral.enums.LockType;
 import cn.com.qmth.scancentral.exception.ParameterExceptions;
 import cn.com.qmth.scancentral.model.ManualAbsentImportDTO;
+import cn.com.qmth.scancentral.service.AsyncTaskService;
 import cn.com.qmth.scancentral.service.ExamService;
 import cn.com.qmth.scancentral.service.StudentService;
 import cn.com.qmth.scancentral.service.SubjectService;
@@ -58,11 +63,13 @@ import cn.com.qmth.scancentral.vo.ExamStatusSaveVo;
 import cn.com.qmth.scancentral.vo.UpdateTimeVo;
 import cn.com.qmth.scancentral.vo.answerquery.AnswerQueryParam;
 import cn.com.qmth.scancentral.vo.answerquery.AnswerQueryVo;
+import cn.com.qmth.scancentral.vo.asynctask.ExamStatusImportTaskVo;
+import cn.com.qmth.scancentral.vo.asynctask.ExamStatusResetTaskVo;
 import cn.com.qmth.scancentral.vo.student.StudentExamRoomVo;
 import cn.com.qmth.scancentral.vo.student.StudentVo;
+import cn.com.qmth.scancentral.vo.subject.TaskIdVo;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import net.sf.json.JSONObject;
 
 @RestController
 @Api(tags = "缺考接口")
@@ -82,6 +89,9 @@ public class CheckController extends BaseController {
     @Autowired
     private AsyncTaskExecutor taskExecutor;
 
+    @Autowired
+    private AsyncTaskService asyncTaskService;
+
     @Autowired
     private SubjectService subjectService;
 
@@ -265,7 +275,7 @@ public class CheckController extends BaseController {
 
     @ApiOperation(value = "缺考校验导入")
     @RequestMapping(value = "exam-status/import", method = RequestMethod.POST)
-    public JSONObject examStatusImportFile(@RequestParam Long examId, @RequestParam ExamStatusCheckMode mode,
+    public TaskIdVo examStatusImportFile(@RequestParam Long examId, @RequestParam ExamStatusCheckMode mode,
             @RequestParam MultipartFile file) throws IOException {
         ExamEntity exam = examService.getById(examId);
         if (exam == null) {
@@ -273,62 +283,105 @@ public class CheckController extends BaseController {
         }
 
         if (!concurrentService.isLocked(LockType.EXAM_STATUS_RESET + "-" + examId)) {
-            taskExecutor.submit(
-                    new ExamStatusImportThread(examId, mode, file.getInputStream(), studentService, concurrentService));
+            if (!file.getName().toLowerCase().endsWith(".txt")) {
+                throw new ParameterException("只能是txt文件");
+            }
+            String taskId = FastUUID.get();
+            // 暂存临时文件
+            File temDir = new File("temp/" + taskId + "/");
+            temDir.mkdirs();
+            File txt = new File(temDir.getAbsolutePath() + "/data.txt");
+            try {
+                file.transferTo(txt);
+                List<String> list = FileUtils.readLines(txt, "utf-8");
+                if (CollectionUtils.isEmpty(list) || list.size() <= 1) {
+                    throw new ParameterException("文件内容为空");
+                }
+                ExamStatusImportTaskVo vo = new ExamStatusImportTaskVo();
+                vo.setTaskId(taskId);
+                vo.setTotalCount(list.size());
+                vo.setExamId(examId);
+                vo.setMode(mode);
+                vo.setSuccess(true);
+                vo.setProgress(0.0);
+                vo.setTempDir(temDir);
+                vo.setFile(txt);
+                taskExecutor.submit(new ExamStatusImportThread(vo, studentService, concurrentService));
+                asyncTaskService.addTask(vo);
+                return TaskIdVo.create(vo.getTaskId());
+            } catch (Exception e) {
+                throw new ParameterException("系统错误", e);
+            }
         } else {
-            throw new ReentrantException("正在导入,请稍后再试");
+            throw new ParameterException("正在导入,请稍后再试");
         }
-        JSONObject result = new JSONObject();
-        result.put("updateTime", System.currentTimeMillis());
-        result.put("synching", true);
-        return result;
     }
 
-    @ApiOperation(value = "缺考校验导入状态")
-    @RequestMapping(value = "exam-status/import/status", method = RequestMethod.POST)
-    public Map<String, Object> examStatusImportStatus(@RequestParam Long examId) {
-        ExamEntity exam = examService.getById(examId);
-        if (exam == null) {
-            throw ParameterExceptions.EXAM_NOT_FOUND;
-        }
-
-        Map<String, Object> result = new HashMap<String, Object>();
-        result.put("synching", concurrentService.isLocked(LockType.EXAM_STATUS_RESET + "-" + examId));
-        return result;
-    }
+    // @ApiOperation(value = "缺考校验导入状态")
+    // @RequestMapping(value = "exam-status/import/status", method =
+    // RequestMethod.POST)
+    // public Map<String, Object> examStatusImportStatus(@RequestParam Long
+    // examId) {
+    // ExamEntity exam = examService.getById(examId);
+    // if (exam == null) {
+    // throw ParameterExceptions.EXAM_NOT_FOUND;
+    // }
+    //
+    // Map<String, Object> result = new HashMap<String, Object>();
+    // result.put("synching",
+    // concurrentService.isLocked(LockType.EXAM_STATUS_RESET + "-" + examId));
+    // return result;
+    // }
 
     @ApiOperation(value = "缺考校验重新生成")
     @RequestMapping(value = "exam-status/reset", method = RequestMethod.POST)
-    public JSONObject examStatusReset(@RequestParam Long examId, @RequestParam Integer examNumberFillCount) {
+    public TaskIdVo examStatusReset(@RequestParam Long examId, @RequestParam Integer examNumberFillCount) {
         ExamEntity exam = examService.getById(examId);
         if (exam == null) {
             throw ParameterExceptions.EXAM_NOT_FOUND;
         }
 
         if (!concurrentService.isLocked(LockType.EXAM_STATUS_RESET + "-" + examId)) {
-            taskExecutor
-                    .submit(new ExamStatusResetThread(examId, examNumberFillCount, studentService, concurrentService));
+            String taskId = FastUUID.get();
+            try {
+                int total = studentService.getCountByExam(examId);
+                if (total == 0) {
+                    throw new ParameterException("没有要处理的数据");
+                }
+                ExamStatusResetTaskVo vo = new ExamStatusResetTaskVo();
+                vo.setTaskId(taskId);
+                vo.setTotalCount(total + 1);
+                vo.setExamId(examId);
+                vo.setExamNumberFillCount(examNumberFillCount);
+                vo.setSuccess(true);
+                vo.setProgress(0.0);
+                taskExecutor.submit(new ExamStatusResetThread(vo, studentService, concurrentService));
+                asyncTaskService.addTask(vo);
+                return TaskIdVo.create(vo.getTaskId());
+            } catch (Exception e) {
+                throw new ParameterException("系统错误", e);
+            }
+
         } else {
             throw new ReentrantException("正在重新生成,请稍后再试");
         }
-        JSONObject result = new JSONObject();
-        result.put("updateTime", System.currentTimeMillis());
-        result.put("synching", true);
-        return result;
     }
 
-    @ApiOperation(value = "缺考校验重新生成状态")
-    @RequestMapping(value = "exam-status/reset/status", method = RequestMethod.POST)
-    public Map<String, Object> examStatusResetStatus(@RequestParam Long examId) {
-        ExamEntity exam = examService.getById(examId);
-        if (exam == null) {
-            throw ParameterExceptions.EXAM_NOT_FOUND;
-        }
-
-        Map<String, Object> result = new HashMap<String, Object>();
-        result.put("synching", concurrentService.isLocked(LockType.EXAM_STATUS_RESET + "-" + examId));
-        return result;
-    }
+    // @ApiOperation(value = "缺考校验重新生成状态")
+    // @RequestMapping(value = "exam-status/reset/status", method =
+    // RequestMethod.POST)
+    // public Map<String, Object> examStatusResetStatus(@RequestParam Long
+    // examId) {
+    // ExamEntity exam = examService.getById(examId);
+    // if (exam == null) {
+    // throw ParameterExceptions.EXAM_NOT_FOUND;
+    // }
+    //
+    // Map<String, Object> result = new HashMap<String, Object>();
+    // result.put("synching",
+    // concurrentService.isLocked(LockType.EXAM_STATUS_RESET + "-" + examId));
+    // return result;
+    // }
 
     @ApiOperation(value = "缺考校验查询概要")
     @RequestMapping(value = "exam-status/summary", method = RequestMethod.POST)

+ 4 - 6
src/main/java/cn/com/qmth/scancentral/service/StudentService.java

@@ -1,7 +1,5 @@
 package cn.com.qmth.scancentral.service;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.util.Collection;
 import java.util.List;
 
@@ -24,7 +22,6 @@ import cn.com.qmth.scancentral.bean.refix.AnswerRefixDomain;
 import cn.com.qmth.scancentral.entity.StudentEntity;
 import cn.com.qmth.scancentral.entity.StudentPaperEntity;
 import cn.com.qmth.scancentral.enums.ExamStatus;
-import cn.com.qmth.scancentral.enums.ExamStatusCheckMode;
 import cn.com.qmth.scancentral.enums.GroupType;
 import cn.com.qmth.scancentral.enums.ImageCheckStatus;
 import cn.com.qmth.scancentral.enums.OP;
@@ -41,7 +38,6 @@ import cn.com.qmth.scancentral.vo.CampusVo;
 import cn.com.qmth.scancentral.vo.ExamSiteVo;
 import cn.com.qmth.scancentral.vo.ExportCetMarkingQueryVo;
 import cn.com.qmth.scancentral.vo.ExportCetVo;
-import cn.com.qmth.scancentral.vo.ImportResult;
 import cn.com.qmth.scancentral.vo.ImportStudentQueryVo;
 import cn.com.qmth.scancentral.vo.ImportStudentVo;
 import cn.com.qmth.scancentral.vo.PaperDeleteVo;
@@ -55,6 +51,8 @@ import cn.com.qmth.scancentral.vo.assginedcheck.AssignedCheckExamRoomExport;
 import cn.com.qmth.scancentral.vo.assginedcheck.AssignedCheckExport;
 import cn.com.qmth.scancentral.vo.assginedcheck.AssignedTaskSaveVo;
 import cn.com.qmth.scancentral.vo.asynctask.BreachAndStatusImportTaskVo;
+import cn.com.qmth.scancentral.vo.asynctask.ExamStatusImportTaskVo;
+import cn.com.qmth.scancentral.vo.asynctask.ExamStatusResetTaskVo;
 import cn.com.qmth.scancentral.vo.examroom.ExamRoomScannedQuery;
 import cn.com.qmth.scancentral.vo.examroom.ExamRoomScannedVo;
 import cn.com.qmth.scancentral.vo.student.StudentAnswerVo;
@@ -172,11 +170,11 @@ public interface StudentService extends IService<StudentEntity> {
 
     Integer getStudentAnswerCount(Long examId);
 
-    void resetExamStatus(Long examId, Integer examNumberFillCount);
+    void resetExamStatus(ExamStatusResetTaskVo vo);
 
     void updateExamStatus(Long id, ExamStatus examStatus);
 
-    ImportResult importExamStatus(Long examId, ExamStatusCheckMode mode, InputStream inputStream) throws IOException;
+    void importExamStatus(ExamStatusImportTaskVo vo);
 
     int getCountByExamAndAssignedCheckCount(Long examId, String subjectCode, int assignedCheckCount, OP op);
 

+ 32 - 26
src/main/java/cn/com/qmth/scancentral/service/impl/StudentImportServiceImpl.java

@@ -1,13 +1,13 @@
 package cn.com.qmth.scancentral.service.impl;
 
-import cn.com.qmth.scancentral.bean.ImportStudentDomain;
-import cn.com.qmth.scancentral.service.StudentImportService;
-import cn.com.qmth.scancentral.service.StudentService;
-import cn.com.qmth.scancentral.service.SubjectService;
-import cn.com.qmth.scancentral.vo.studentimport.ImportTaskVo;
-import cn.com.qmth.scancentral.vo.studentimport.StudentImportInfo;
-import com.qmth.boot.core.exception.ParameterException;
-import org.apache.commons.io.FileUtils;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Pattern;
+
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -15,11 +15,14 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.regex.Pattern;
+import com.qmth.boot.core.exception.ParameterException;
+
+import cn.com.qmth.scancentral.bean.ImportStudentDomain;
+import cn.com.qmth.scancentral.service.StudentImportService;
+import cn.com.qmth.scancentral.service.StudentService;
+import cn.com.qmth.scancentral.service.SubjectService;
+import cn.com.qmth.scancentral.vo.studentimport.ImportTaskVo;
+import cn.com.qmth.scancentral.vo.studentimport.StudentImportInfo;
 
 @Component
 public class StudentImportServiceImpl implements StudentImportService {
@@ -55,7 +58,8 @@ public class StudentImportServiceImpl implements StudentImportService {
 
     @Async
     @Override
-    public void studentImport(String taskId, List<String> lines, Long examId, Integer yearConfig, Integer yearHalfConfig) {
+    public void studentImport(String taskId, List<String> lines, Long examId, Integer yearConfig,
+            Integer yearHalfConfig) {
         ImportTaskVo task = new ImportTaskVo();
         task.setTaskId(taskId);
         task.setProgress(0d);
@@ -106,7 +110,8 @@ public class StudentImportServiceImpl implements StudentImportService {
             log.info("【考生导入】共{}条 已导入:{}条 已耗时:{}秒 进度:100% taskId:{}", total, finishCount, cost, taskId);
         } catch (Exception e) {
             task.setErrMsg(String.format("导入异常终止,已导入%s条,未导入%s条!", finishCount, total - finishCount));
-            log.error("【考生导入】导入异常终止,已导入{}条,未导入{}条!taskId:{} err:{}", finishCount, total - finishCount, taskId, e.getMessage(), e);
+            log.error("【考生导入】导入异常终止,已导入{}条,未导入{}条!taskId:{} err:{}", finishCount, total - finishCount, taskId,
+                    e.getMessage(), e);
         } finally {
             task.setRunning(false);
         }
@@ -129,7 +134,8 @@ public class StudentImportServiceImpl implements StudentImportService {
         return data;
     }
 
-    private void parseValues(List<String> lines, List<StudentImportInfo> list, Long examId, Integer yearConfig, Integer yearHalfConfig) {
+    private void parseValues(List<String> lines, List<StudentImportInfo> list, Long examId, Integer yearConfig,
+            Integer yearHalfConfig) {
         Set<String> subjectCodes = new HashSet<>();
         Set<String> examNumbers = new HashSet<>();
         Pattern examNumberPattern = Pattern.compile("^[0-9]{15}$");
@@ -213,15 +219,15 @@ public class StudentImportServiceImpl implements StudentImportService {
         }
     }
 
-    private void writeLogFile(File logFile, String content) {
-        if (StringUtils.isEmpty(content)) {
-            return;
-        }
-        try {
-            FileUtils.writeStringToFile(logFile, "\n" + content, "UTF-8", true);
-        } catch (IOException e) {
-            log.error(e.getMessage(), e);
-        }
-    }
+    // private void writeLogFile(File logFile, String content) {
+    // if (StringUtils.isEmpty(content)) {
+    // return;
+    // }
+    // try {
+    // FileUtils.writeStringToFile(logFile, "\n" + content, "UTF-8", true);
+    // } catch (IOException e) {
+    // log.error(e.getMessage(), e);
+    // }
+    // }
 
 }

+ 91 - 96
src/main/java/cn/com/qmth/scancentral/service/impl/StudentServiceImpl.java

@@ -4,8 +4,6 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.LineNumberReader;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Date;
@@ -131,7 +129,6 @@ import cn.com.qmth.scancentral.vo.CampusVo;
 import cn.com.qmth.scancentral.vo.ExamSiteVo;
 import cn.com.qmth.scancentral.vo.ExportCetMarkingQueryVo;
 import cn.com.qmth.scancentral.vo.ExportCetVo;
-import cn.com.qmth.scancentral.vo.ImportResult;
 import cn.com.qmth.scancentral.vo.ImportStudentQueryVo;
 import cn.com.qmth.scancentral.vo.ImportStudentVo;
 import cn.com.qmth.scancentral.vo.PaperDeleteVo;
@@ -148,6 +145,8 @@ import cn.com.qmth.scancentral.vo.assginedcheck.AssignedCheckExamRoomExport;
 import cn.com.qmth.scancentral.vo.assginedcheck.AssignedCheckExport;
 import cn.com.qmth.scancentral.vo.assginedcheck.AssignedTaskSaveVo;
 import cn.com.qmth.scancentral.vo.asynctask.BreachAndStatusImportTaskVo;
+import cn.com.qmth.scancentral.vo.asynctask.ExamStatusImportTaskVo;
+import cn.com.qmth.scancentral.vo.asynctask.ExamStatusResetTaskVo;
 import cn.com.qmth.scancentral.vo.examroom.ExamRoomScannedQuery;
 import cn.com.qmth.scancentral.vo.examroom.ExamRoomScannedVo;
 import cn.com.qmth.scancentral.vo.paper.PaperCetVo;
@@ -1615,7 +1614,9 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
 
     @Override
     @Transactional
-    public void resetExamStatus(Long examId, Integer examNumberFillCount) {
+    public void resetExamStatus(ExamStatusResetTaskVo vo) {
+        Long examId = vo.getExamId();
+        Integer examNumberFillCount = vo.getExamNumberFillCount();
         QueryWrapper<StudentEntity> wrapper = new QueryWrapper<>();
         LambdaQueryWrapper<StudentEntity> lw = wrapper.lambda();
         lw.eq(StudentEntity::getExamId, examId);
@@ -1637,6 +1638,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
             } finally {
                 concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().unlock();
             }
+            vo.setProgress(vo.getProgress() + 1);
         }
         examService.updateExamNumberFillCount(examId, examNumberFillCount);
     }
@@ -1667,107 +1669,100 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
     }
 
     @Override
-    public ImportResult importExamStatus(Long examId, ExamStatusCheckMode mode, InputStream inputStream)
-            throws IOException {
+    public void importExamStatus(ExamStatusImportTaskVo vo) {
+        Map<String, StudentEntity> examNumbers = new HashMap<>();
+        Map<String, Boolean> absentMap = new HashMap<>();
+        List<String> lineList = null;
+        InputStream in = null;
         try {
-            ImportResult ret = new ImportResult();
-            List<String> failRecords = new ArrayList<>();
-            ret.setErrMsg(failRecords);
-            Map<String, StudentEntity> examNumbers = new HashMap<>();
-            Map<String, Boolean> absentMap = new HashMap<>();
-            LineNumberReader lineNumberReader = new LineNumberReader(new InputStreamReader(inputStream));
-            // 获取字符串总长度
-            String line;
-            int i = 0;
-            while ((line = lineNumberReader.readLine()) != null) {
-                i++;
-                if (i == 1) {
-                    continue;// 第一行标题
-                }
-                // 已读字符串长度
-                StringBuilder msg = new StringBuilder();
-                String[] str = line.split(",");
-                if (str.length != 3) {
-                    msg.append("  无法解析,请检查分隔符和数据");
-                    failRecords.add(newError(i, msg.toString()));
-                    continue;
-                }
-                String examNumber = str[0];
-                String absent = str[1];
-                String subjectCode = str[2];
-                if (StringUtils.isBlank(examNumber)) {
-                    examNumber = null;
-                    msg.append("  准考证号不能为空");
-                } else if (examNumber.length() < 15) {
-                    examNumber = null;
-                    msg.append("  准考证号不能小于15位");
-                }
-                if (StringUtils.isBlank(absent)) {
-                    msg.append("  缺考标识不能为空");
-                } else if (!absent.equals("0") && !absent.equals("1")) {
-                    msg.append("  缺考标识只能为0或1");
+            lineList = IOUtils.readLines(in, "UTF-8");
+        } catch (IOException e) {
+            throw new ParameterException("读取文件出错", e);
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
                 }
-                if (examNumber != null) {
-                    if (examNumbers.containsKey(examNumber)) {
-                        msg.append("  准考证号有重复");
+            }
+        }
+        for (int i = 1; i < lineList.size(); i++) {
+            String line = lineList.get(i);
+            if (StringUtils.isBlank(line)) {
+                continue;
+            }
+            // 已读字符串长度
+            StringBuilder msg = new StringBuilder();
+            String[] str = line.split(",");
+            if (str.length != 3) {
+                msg.append("  无法解析,请检查分隔符和数据");
+                throw new ParameterException(newError(i + 1, msg.toString()));
+            }
+            String examNumber = str[0];
+            String absent = str[1];
+            String subjectCode = str[2];
+            if (StringUtils.isBlank(examNumber)) {
+                examNumber = null;
+                msg.append("  准考证号不能为空");
+            } else if (examNumber.length() < 15) {
+                examNumber = null;
+                msg.append("  准考证号不能小于15位");
+            }
+            if (StringUtils.isBlank(absent)) {
+                msg.append("  缺考标识不能为空");
+            } else if (!absent.equals("0") && !absent.equals("1")) {
+                msg.append("  缺考标识只能为0或1");
+            }
+            if (examNumber != null) {
+                if (examNumbers.containsKey(examNumber)) {
+                    msg.append("  准考证号有重复");
+                } else {
+                    StudentEntity student = this.findByExamAndSubjectCodeAndExamNumber(vo.getExamId(), subjectCode,
+                            examNumber);
+                    if (student == null) {
+                        msg.append("  准考证号不存在");
                     } else {
-                        StudentEntity student = this.findByExamAndSubjectCodeAndExamNumber(examId, subjectCode,
-                                examNumber);
-                        if (student == null) {
-                            msg.append("  准考证号不存在");
-                        } else {
-                            examNumbers.put(examNumber, student);
-                            absentMap.put(examNumber, absent.equals("1"));
-                        }
+                        examNumbers.put(examNumber, student);
+                        absentMap.put(examNumber, absent.equals("1"));
                     }
                 }
-                if (msg.length() > 0) {
-                    failRecords.add(newError(i, msg.toString()));
-                    continue;
-                }
             }
-            if (CollectionUtils.isNotEmpty(failRecords)) {
-                return ret;
+            if (msg.length() > 0) {
+                throw new ParameterException(newError(i + 1, msg.toString()));
             }
-            if (ExamStatusCheckMode.OVERRIDE.equals(mode)) {
-                for (StudentEntity student : examNumbers.values()) {
-                    concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().lock();
-                    try {
-                        if (absentMap.get(student.getExamNumber())) {
-                            student.setExamStatus(ExamStatus.ABSENT);
-                        } else {
-                            student.setExamStatus(ExamStatus.OK);
-                        }
-                        saveOrUpdate(student);
-                    } finally {
-                        concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock()
-                                .unlock();
+        }
+        if (ExamStatusCheckMode.OVERRIDE.equals(vo.getMode())) {
+            for (StudentEntity student : examNumbers.values()) {
+                concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().lock();
+                try {
+                    if (absentMap.get(student.getExamNumber())) {
+                        student.setExamStatus(ExamStatus.ABSENT);
+                    } else {
+                        student.setExamStatus(ExamStatus.OK);
                     }
+                    saveOrUpdate(student);
+                    vo.setProgress(vo.getProgress() + 1);
+                } finally {
+                    concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().unlock();
                 }
             }
-            if (ExamStatusCheckMode.COMPARE.equals(mode)) {
-                for (StudentEntity student : examNumbers.values()) {
-                    concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().lock();
-                    try {
-                        if (absentMap.get(student.getExamNumber())
-                                && !ExamStatus.ABSENT.equals(student.getExamStatus())) {
-                            student.setExamStatus(ExamStatus.UNCHECK);
-                        }
-                        if (!absentMap.get(student.getExamNumber()) && !ExamStatus.OK.equals(student.getExamStatus())) {
-                            student.setExamStatus(ExamStatus.UNCHECK);
-                        }
-                        saveOrUpdate(student);
-                    } finally {
-                        concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock()
-                                .unlock();
+        }
+        if (ExamStatusCheckMode.COMPARE.equals(vo.getMode())) {
+            for (StudentEntity student : examNumbers.values()) {
+                concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().lock();
+                try {
+                    if (absentMap.get(student.getExamNumber()) && !ExamStatus.ABSENT.equals(student.getExamStatus())) {
+                        student.setExamStatus(ExamStatus.UNCHECK);
+                    }
+                    if (!absentMap.get(student.getExamNumber()) && !ExamStatus.OK.equals(student.getExamStatus())) {
+                        student.setExamStatus(ExamStatus.UNCHECK);
                     }
+                    saveOrUpdate(student);
+                    vo.setProgress(vo.getProgress() + 1);
+                } finally {
+                    concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().unlock();
                 }
             }
-            return ret;
-        } finally {
-            if (inputStream != null) {
-                inputStream.close();
-            }
         }
     }
 
@@ -2332,7 +2327,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
             throw new ParameterException("读取文件出错", e);
         }
         Set<String> examNumberSet = new HashSet<>();
-        for (int i = 0; i < lineList.size(); i++) {
+        for (int i = 1; i < lineList.size(); i++) {
             String lineString = lineList.get(i);
             if (StringUtils.isBlank(lineString)) {
                 continue;
@@ -2367,7 +2362,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
                 }
             }
             if (msg.length() > 0) {
-                throw new ParameterException(errorMsg(i + 2, msg.toString()));
+                throw new ParameterException(errorMsg(i + 1, msg.toString()));
             }
         }
 
@@ -2481,7 +2476,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
             throw new ParameterException("读取文件出错", e);
         }
         Set<String> examNumberSet = new HashSet<>();
-        for (int i = 0; i < lineList.size(); i++) {
+        for (int i = 1; i < lineList.size(); i++) {
             String lineString = lineList.get(i);
             if (StringUtils.isBlank(lineString)) {
                 continue;
@@ -2517,7 +2512,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
                 }
             }
             if (msg.length() > 0) {
-                throw new ParameterException(errorMsg(i + 2, msg.toString()));
+                throw new ParameterException(errorMsg(i + 1, msg.toString()));
             }
         }
 

+ 19 - 26
src/main/java/cn/com/qmth/scancentral/task/thread/ExamStatusImportThread.java

@@ -1,55 +1,48 @@
 package cn.com.qmth.scancentral.task.thread;
 
-import cn.com.qmth.scancentral.enums.ExamStatusCheckMode;
-import cn.com.qmth.scancentral.enums.LockType;
-import cn.com.qmth.scancentral.service.StudentService;
-import com.qmth.boot.core.concurrent.service.ConcurrentService;
-import com.qmth.boot.core.exception.StatusException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.InputStream;
+import com.qmth.boot.core.concurrent.service.ConcurrentService;
+import com.qmth.boot.core.exception.ParameterException;
+
+import cn.com.qmth.scancentral.enums.LockType;
+import cn.com.qmth.scancentral.service.StudentService;
+import cn.com.qmth.scancentral.vo.asynctask.ExamStatusImportTaskVo;
 
 public class ExamStatusImportThread implements Runnable {
 
     protected static Logger log = LoggerFactory.getLogger(ExamStatusImportThread.class);
 
-    private ExamStatusCheckMode mode;
-
-    private InputStream inputStream;
-
-    private Long examId;
+    private ExamStatusImportTaskVo vo;
 
     private StudentService studentService;
 
     private ConcurrentService concurrentService;
 
-    public ExamStatusImportThread(Long examId, ExamStatusCheckMode mode, InputStream inputStream,
-            StudentService studentService, ConcurrentService concurrentService) {
-        this.examId = examId;
-        this.mode = mode;
-        this.inputStream = inputStream;
+    public ExamStatusImportThread(ExamStatusImportTaskVo vo, StudentService studentService,
+            ConcurrentService concurrentService) {
+        this.vo = vo;
         this.studentService = studentService;
         this.concurrentService = concurrentService;
     }
 
     @Override
     public void run() {
-        if (examId == null) {
-            return;
-        }
-        if (mode == null) {
-            return;
-        }
         try {
-            if (concurrentService.getLock(LockType.EXAM_STATUS_RESET + "-" + examId).tryLock()) {
-                studentService.importExamStatus(examId, mode, inputStream);
+            if (concurrentService.getLock(LockType.EXAM_STATUS_RESET + "-" + vo.getExamId()).tryLock()) {
+                studentService.importExamStatus(vo);
+                vo.setTotalCount(vo.getProgressCount());
             }
+        } catch (ParameterException e) {
+            vo.setErrMsg(e.getMessage());
+            vo.setSuccess(false);
         } catch (Exception e) {
             log.error("exam status import error", e);
-            throw new StatusException("缺考校验导入失败");
+            vo.setErrMsg("缺考校验导入失败");
+            vo.setSuccess(false);
         } finally {
-            concurrentService.getLock(LockType.EXAM_STATUS_RESET + "-" + examId).unlock();
+            concurrentService.getLock(LockType.EXAM_STATUS_RESET + "-" + vo.getExamId()).unlock();
         }
     }
 

+ 19 - 20
src/main/java/cn/com/qmth/scancentral/task/thread/ExamStatusResetThread.java

@@ -1,49 +1,48 @@
 package cn.com.qmth.scancentral.task.thread;
 
-import cn.com.qmth.scancentral.enums.LockType;
-import cn.com.qmth.scancentral.service.StudentService;
-import com.qmth.boot.core.concurrent.service.ConcurrentService;
-import com.qmth.boot.core.exception.StatusException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.qmth.boot.core.concurrent.service.ConcurrentService;
+import com.qmth.boot.core.exception.ParameterException;
+
+import cn.com.qmth.scancentral.enums.LockType;
+import cn.com.qmth.scancentral.service.StudentService;
+import cn.com.qmth.scancentral.vo.asynctask.ExamStatusResetTaskVo;
+
 public class ExamStatusResetThread implements Runnable {
 
     protected static Logger log = LoggerFactory.getLogger(ExamStatusResetThread.class);
 
-    private Integer examNumberFillCount;
-
-    private Long examId;
+    private ExamStatusResetTaskVo vo;
 
     private StudentService studentService;
 
     private ConcurrentService concurrentService;
 
-    public ExamStatusResetThread(Long examId, Integer examNumberFillCount, StudentService studentService,
+    public ExamStatusResetThread(ExamStatusResetTaskVo vo, StudentService studentService,
             ConcurrentService concurrentService) {
-        this.examId = examId;
-        this.examNumberFillCount = examNumberFillCount;
+        this.vo = vo;
         this.studentService = studentService;
         this.concurrentService = concurrentService;
     }
 
     @Override
     public void run() {
-        if (examId == null) {
-            return;
-        }
-        if (examNumberFillCount == null) {
-            return;
-        }
         try {
-            if (concurrentService.getLock(LockType.EXAM_STATUS_RESET + "-" + examId).tryLock()) {
-                studentService.resetExamStatus(examId, examNumberFillCount);
+            if (concurrentService.getLock(LockType.EXAM_STATUS_RESET + "-" + vo.getExamId()).tryLock()) {
+                studentService.resetExamStatus(vo);
+                vo.setTotalCount(vo.getProgressCount());
             }
+        } catch (ParameterException e) {
+            vo.setErrMsg(e.getMessage());
+            vo.setSuccess(false);
         } catch (Exception e) {
             log.error("exam status reset error", e);
-            throw new StatusException("缺考校验重新生成失败");
+            vo.setErrMsg("缺考校验重新生成失败");
+            vo.setSuccess(false);
         } finally {
-            concurrentService.getLock(LockType.EXAM_STATUS_RESET + "-" + examId).unlock();
+            concurrentService.getLock(LockType.EXAM_STATUS_RESET + "-" + vo.getExamId()).unlock();
         }
     }
 

+ 20 - 0
src/main/java/cn/com/qmth/scancentral/vo/asynctask/AsyncTaskVo.java

@@ -18,6 +18,10 @@ public class AsyncTaskVo {
 
     private String errMsg;
 
+    private int totalCount;
+
+    private int progressCount;
+
     public String getTaskId() {
         return taskId;
     }
@@ -66,4 +70,20 @@ public class AsyncTaskVo {
         this.tempDir = tempDir;
     }
 
+    public int getTotalCount() {
+        return totalCount;
+    }
+
+    public void setTotalCount(int totalCount) {
+        this.totalCount = totalCount;
+    }
+
+    public int getProgressCount() {
+        return progressCount;
+    }
+
+    public void setProgressCount(int progressCount) {
+        this.progressCount = progressCount;
+    }
+
 }

+ 0 - 20
src/main/java/cn/com/qmth/scancentral/vo/asynctask/BreachAndStatusImportTaskVo.java

@@ -6,10 +6,6 @@ public class BreachAndStatusImportTaskVo extends AsyncTaskVo {
 
     private String subjectCode;
 
-    private int totalCount;
-
-    private int progressCount;
-
     public Long getExamId() {
         return examId;
     }
@@ -26,20 +22,4 @@ public class BreachAndStatusImportTaskVo extends AsyncTaskVo {
         this.subjectCode = subjectCode;
     }
 
-    public int getTotalCount() {
-        return totalCount;
-    }
-
-    public void setTotalCount(int totalCount) {
-        this.totalCount = totalCount;
-    }
-
-    public int getProgressCount() {
-        return progressCount;
-    }
-
-    public void setProgressCount(int progressCount) {
-        this.progressCount = progressCount;
-    }
-
 }

+ 27 - 0
src/main/java/cn/com/qmth/scancentral/vo/asynctask/ExamStatusImportTaskVo.java

@@ -0,0 +1,27 @@
+package cn.com.qmth.scancentral.vo.asynctask;
+
+import cn.com.qmth.scancentral.enums.ExamStatusCheckMode;
+
+public class ExamStatusImportTaskVo extends AsyncTaskVo {
+
+    private Long examId;
+
+    private ExamStatusCheckMode mode;
+
+    public Long getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
+
+    public ExamStatusCheckMode getMode() {
+        return mode;
+    }
+
+    public void setMode(ExamStatusCheckMode mode) {
+        this.mode = mode;
+    }
+
+}

+ 25 - 0
src/main/java/cn/com/qmth/scancentral/vo/asynctask/ExamStatusResetTaskVo.java

@@ -0,0 +1,25 @@
+package cn.com.qmth.scancentral.vo.asynctask;
+
+public class ExamStatusResetTaskVo extends AsyncTaskVo {
+
+    private Long examId;
+
+    private Integer examNumberFillCount;
+
+    public Long getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
+
+    public Integer getExamNumberFillCount() {
+        return examNumberFillCount;
+    }
+
+    public void setExamNumberFillCount(Integer examNumberFillCount) {
+        this.examNumberFillCount = examNumberFillCount;
+    }
+
+}

+ 0 - 20
src/main/java/cn/com/qmth/scancentral/vo/subject/DataExportTaskVo.java

@@ -10,10 +10,6 @@ public class DataExportTaskVo extends AsyncTaskVo {
 
     private String fileName;
 
-    private int totalCount;
-
-    private int progressCount;
-
     public Long getExamId() {
         return examId;
     }
@@ -38,20 +34,4 @@ public class DataExportTaskVo extends AsyncTaskVo {
         this.fileName = fileName;
     }
 
-    public int getTotalCount() {
-        return totalCount;
-    }
-
-    public void setTotalCount(int totalCount) {
-        this.totalCount = totalCount;
-    }
-
-    public int getProgressCount() {
-        return progressCount;
-    }
-
-    public void setProgressCount(int progressCount) {
-        this.progressCount = progressCount;
-    }
-
 }