Browse Source

违纪、状态导入改异步任务

xiatian 8 tháng trước cách đây
mục cha
commit
895ea811ac

+ 9 - 1
src/main/java/cn/com/qmth/scancentral/consumer/AnswerDataExportConsumer.java

@@ -1,5 +1,7 @@
 package cn.com.qmth.scancentral.consumer;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Service;
@@ -11,6 +13,8 @@ import cn.com.qmth.scancentral.vo.subject.DataExportTaskVo;
 @Service
 public class AnswerDataExportConsumer implements Runnable {
 
+    protected static final Logger log = LoggerFactory.getLogger(AnswerDataExportConsumer.class);
+
     private DataExportTaskVo vo;
 
     @Autowired
@@ -18,7 +22,11 @@ public class AnswerDataExportConsumer implements Runnable {
 
     @Override
     public void run() {
-        subjectService.answerDataExportDispose(vo);
+        try {
+            subjectService.answerDataExportDispose(vo);
+        } catch (Exception e) {
+            log.error("DBF导出出错", e);
+        }
     }
 
     public DataExportTaskVo getVo() {

+ 40 - 0
src/main/java/cn/com/qmth/scancentral/consumer/BreachImportConsumer.java

@@ -0,0 +1,40 @@
+package cn.com.qmth.scancentral.consumer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Service;
+
+import cn.com.qmth.scancentral.service.StudentService;
+import cn.com.qmth.scancentral.vo.asynctask.BreachAndStatusImportTaskVo;
+
+@Scope("prototype")
+@Service
+public class BreachImportConsumer implements Runnable {
+
+    protected static final Logger log = LoggerFactory.getLogger(BreachImportConsumer.class);
+
+    private BreachAndStatusImportTaskVo vo;
+
+    @Autowired
+    private StudentService studentService;
+
+    @Override
+    public void run() {
+        try {
+            studentService.breachImportDispose(vo);
+        } catch (Exception e) {
+            log.error("违纪导入出错", e);
+        }
+    }
+
+    public BreachAndStatusImportTaskVo getVo() {
+        return vo;
+    }
+
+    public void setVo(BreachAndStatusImportTaskVo vo) {
+        this.vo = vo;
+    }
+
+}

+ 40 - 0
src/main/java/cn/com/qmth/scancentral/consumer/CustStatusImportConsumer.java

@@ -0,0 +1,40 @@
+package cn.com.qmth.scancentral.consumer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Service;
+
+import cn.com.qmth.scancentral.service.StudentService;
+import cn.com.qmth.scancentral.vo.asynctask.BreachAndStatusImportTaskVo;
+
+@Scope("prototype")
+@Service
+public class CustStatusImportConsumer implements Runnable {
+
+    protected static final Logger log = LoggerFactory.getLogger(CustStatusImportConsumer.class);
+
+    private BreachAndStatusImportTaskVo vo;
+
+    @Autowired
+    private StudentService studentService;
+
+    @Override
+    public void run() {
+        try {
+            studentService.custStatusImportDispose(vo);
+        } catch (Exception e) {
+            log.error("违纪导入出错", e);
+        }
+    }
+
+    public BreachAndStatusImportTaskVo getVo() {
+        return vo;
+    }
+
+    public void setVo(BreachAndStatusImportTaskVo vo) {
+        this.vo = vo;
+    }
+
+}

+ 4 - 4
src/main/java/cn/com/qmth/scancentral/controller/admin/StudentController.java

@@ -24,10 +24,10 @@ import com.qmth.boot.tools.iterator.PageListIterator;
 import cn.com.qmth.scancentral.controller.BaseController;
 import cn.com.qmth.scancentral.service.StudentService;
 import cn.com.qmth.scancentral.util.ResouceUtil;
-import cn.com.qmth.scancentral.vo.ImportBreachResult;
 import cn.com.qmth.scancentral.vo.student.StudentAnswerVo;
 import cn.com.qmth.scancentral.vo.student.StudentPageQuery;
 import cn.com.qmth.scancentral.vo.student.StudentPageVo;
+import cn.com.qmth.scancentral.vo.subject.TaskIdVo;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 
@@ -81,7 +81,7 @@ public class StudentController extends BaseController {
 
     @ApiOperation(value = "违纪导入")
     @PostMapping("breach/import")
-    public ImportBreachResult breachImport(@RequestParam Long examId, @RequestParam String subjectCode,
+    public TaskIdVo breachImport(@RequestParam Long examId, @RequestParam String subjectCode,
             @RequestParam MultipartFile file) {
         return studentService.breachImport(examId, subjectCode, file);
     }
@@ -92,9 +92,9 @@ public class StudentController extends BaseController {
         exportFile("考生状态导入模板.txt", ResouceUtil.getStream("templates/cust-status-import.txt"));
     }
 
-    @ApiOperation(value = "违纪导入")
+    @ApiOperation(value = "考生状态导入")
     @PostMapping("cust-status/import")
-    public ImportBreachResult custStatusImport(@RequestParam Long examId, @RequestParam String subjectCode,
+    public TaskIdVo custStatusImport(@RequestParam Long examId, @RequestParam String subjectCode,
             @RequestParam MultipartFile file) {
         return studentService.custStatusImport(examId, subjectCode, file);
     }

+ 1 - 2
src/main/java/cn/com/qmth/scancentral/controller/admin/SubjectController.java

@@ -1,6 +1,5 @@
 package cn.com.qmth.scancentral.controller.admin;
 
-import java.io.File;
 import java.io.FileInputStream;
 import java.util.List;
 
@@ -82,6 +81,6 @@ public class SubjectController extends BaseController {
         if (vo.getTotalCount() != (vo.getProgressCount())) {
             throw new ParameterException("导出任务未结束");
         }
-        exportFile(vo.getFileName(), new FileInputStream(new File(vo.getFilePath())));
+        exportFile(vo.getFileName(), new FileInputStream(vo.getFile()));
     }
 }

+ 53 - 11
src/main/java/cn/com/qmth/scancentral/service/StudentService.java

@@ -10,25 +10,62 @@ import org.springframework.web.multipart.MultipartFile;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.boot.core.collection.PageResult;
 
-import cn.com.qmth.scancentral.bean.*;
+import cn.com.qmth.scancentral.bean.AbsentQueryDomain;
+import cn.com.qmth.scancentral.bean.AnswerDeleteDomain;
+import cn.com.qmth.scancentral.bean.AnswerQueryDomain;
+import cn.com.qmth.scancentral.bean.AssignedQueryDomain;
+import cn.com.qmth.scancentral.bean.ImportCetAbsentDomain;
+import cn.com.qmth.scancentral.bean.ImportStudentDomain;
+import cn.com.qmth.scancentral.bean.PageDeleteDomain;
+import cn.com.qmth.scancentral.bean.User;
 import cn.com.qmth.scancentral.bean.omredit.OmrEditDomain;
 import cn.com.qmth.scancentral.bean.omredit.OmrFieldEditDomain;
 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.*;
-import cn.com.qmth.scancentral.vo.*;
+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;
+import cn.com.qmth.scancentral.enums.ScanStatus;
+import cn.com.qmth.scancentral.enums.UploadStatus;
+import cn.com.qmth.scancentral.vo.AbsentInfoVo;
+import cn.com.qmth.scancentral.vo.AbsentManualImportVo;
+import cn.com.qmth.scancentral.vo.AbsentQueryVo;
+import cn.com.qmth.scancentral.vo.AnswerDeleteVo;
+import cn.com.qmth.scancentral.vo.AnswerExportK12Vo;
+import cn.com.qmth.scancentral.vo.AnswerExportVo;
+import cn.com.qmth.scancentral.vo.AnswerRefixVo;
+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;
+import cn.com.qmth.scancentral.vo.ScanAnswerInfoVo;
+import cn.com.qmth.scancentral.vo.StudentUploadVo;
+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.assginedcheck.AssginedTaskResult;
 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.examroom.ExamRoomScannedQuery;
 import cn.com.qmth.scancentral.vo.examroom.ExamRoomScannedVo;
-import cn.com.qmth.scancentral.vo.student.*;
+import cn.com.qmth.scancentral.vo.student.StudentAnswerVo;
+import cn.com.qmth.scancentral.vo.student.StudentExamRoomVo;
+import cn.com.qmth.scancentral.vo.student.StudentPageQuery;
+import cn.com.qmth.scancentral.vo.student.StudentPageVo;
+import cn.com.qmth.scancentral.vo.student.StudentQuery;
+import cn.com.qmth.scancentral.vo.student.StudentVo;
 import cn.com.qmth.scancentral.vo.studentimport.StudentCountVo;
 import cn.com.qmth.scancentral.vo.subject.SubjectScanProgressVo;
+import cn.com.qmth.scancentral.vo.subject.TaskIdVo;
 import cn.com.qmth.scancentral.vo.task.TaskStatusVo;
 
 public interface StudentService extends IService<StudentEntity> {
@@ -141,7 +178,7 @@ public interface StudentService extends IService<StudentEntity> {
 
     ImportResult importExamStatus(Long examId, ExamStatusCheckMode mode, InputStream inputStream) throws IOException;
 
-    int getCountByExamAndAssignedCheckCount(Long examId, String subjectCode,int assignedCheckCount, OP op);
+    int getCountByExamAndAssignedCheckCount(Long examId, String subjectCode, int assignedCheckCount, OP op);
 
     int countByExamIdAndExamStatus(Long examId, ExamStatus examStatus);
 
@@ -155,15 +192,16 @@ public interface StudentService extends IService<StudentEntity> {
 
     boolean hasAppliedAssignedCheckTask(StudentEntity t, String account);
 
-    TaskStatusVo getAssignedCheckTaskStatus(Long examId,String subjectCode, User user);
+    TaskStatusVo getAssignedCheckTaskStatus(Long examId, String subjectCode, User user);
 
-    void releaseAssignedCheckTaskByUser(Long examId,String subjectCode, String account);
+    void releaseAssignedCheckTaskByUser(Long examId, String subjectCode, String account);
 
     AssignedTaskSaveVo submitAssignedCheckTask(AssginedTaskResult result, User user);
 
-    PageResult<AnswerQueryVo> getAssignedCheckTaskHistory(Long examId,String subjectCode, Long pageNumber,Long pageSize, User user);
+    PageResult<AnswerQueryVo> getAssignedCheckTaskHistory(Long examId, String subjectCode, Long pageNumber,
+            Long pageSize, User user);
 
-    AnswerQueryVo getAssignedCheckTask(Long examId,String subjectCode, User user);
+    AnswerQueryVo getAssignedCheckTask(Long examId, String subjectCode, User user);
 
     StudentAnswerVo studentAnswer(Long batchId, Long studentId);
 
@@ -185,9 +223,9 @@ public interface StudentService extends IService<StudentEntity> {
 
     UpdateTimeVo omrFieldEdit(User accessUser, OmrFieldEditDomain domain);
 
-    ImportBreachResult breachImport(Long examId, String subjectCode, MultipartFile file);
+    TaskIdVo breachImport(Long examId, String subjectCode, MultipartFile file);
 
-    ImportBreachResult custStatusImport(Long examId, String subjectCode, MultipartFile file);
+    TaskIdVo custStatusImport(Long examId, String subjectCode, MultipartFile file);
 
     List<StudentCountVo> countStudent(Long examId);
 
@@ -198,4 +236,8 @@ public interface StudentService extends IService<StudentEntity> {
     int countCetMarking(ExportCetMarkingQueryVo query);
 
     void updateImageCheckStatus(Long id, ImageCheckStatus failed);
+
+    void breachImportDispose(BreachAndStatusImportTaskVo vo);
+
+    void custStatusImportDispose(BreachAndStatusImportTaskVo vo);
 }

+ 2 - 4
src/main/java/cn/com/qmth/scancentral/service/impl/AsyncTaskServiceImpl.java

@@ -1,6 +1,5 @@
 package cn.com.qmth.scancentral.service.impl;
 
-import java.io.File;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -38,9 +37,8 @@ public class AsyncTaskServiceImpl implements AsyncTaskService {
             if (now - taskActive.get(k) > timeOut) {
                 AsyncTaskVo vo = tasks.get(k);
                 if (vo != null) {
-                    if (vo.getFilePath() != null) {
-                        File f = new File(vo.getFilePath()).getParentFile();
-                        FileUtil.deleteDirectory(f);
+                    if (vo.getTempDir() != null && vo.getTempDir().exists()) {
+                        FileUtil.deleteDirectory(vo.getTempDir());
                     }
                     tasks.remove(k);
                 }

+ 327 - 176
src/main/java/cn/com/qmth/scancentral/service/impl/StudentServiceImpl.java

@@ -1,8 +1,24 @@
 package cn.com.qmth.scancentral.service.impl;
 
-import java.io.*;
+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.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+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 java.util.stream.Collectors;
 
 import javax.validation.constraints.NotNull;
@@ -35,7 +51,14 @@ import com.qmth.boot.tools.excel.ExcelReader;
 import com.qmth.boot.tools.excel.enums.ExcelType;
 import com.qmth.boot.tools.uuid.FastUUID;
 
-import cn.com.qmth.scancentral.bean.*;
+import cn.com.qmth.scancentral.bean.AbsentQueryDomain;
+import cn.com.qmth.scancentral.bean.AnswerDeleteDomain;
+import cn.com.qmth.scancentral.bean.AnswerQueryDomain;
+import cn.com.qmth.scancentral.bean.AssignedQueryDomain;
+import cn.com.qmth.scancentral.bean.ImportCetAbsentDomain;
+import cn.com.qmth.scancentral.bean.ImportStudentDomain;
+import cn.com.qmth.scancentral.bean.PageDeleteDomain;
+import cn.com.qmth.scancentral.bean.User;
 import cn.com.qmth.scancentral.bean.answersave.ArrayResult;
 import cn.com.qmth.scancentral.bean.answersave.BoolResult;
 import cn.com.qmth.scancentral.bean.answersave.StringResult;
@@ -46,32 +69,98 @@ import cn.com.qmth.scancentral.bean.refix.AnswerRefixDomain;
 import cn.com.qmth.scancentral.bean.refix.PageRefixDomain;
 import cn.com.qmth.scancentral.bean.refix.PaperRefixDomain;
 import cn.com.qmth.scancentral.config.SysProperty;
+import cn.com.qmth.scancentral.consumer.BreachImportConsumer;
+import cn.com.qmth.scancentral.consumer.CustStatusImportConsumer;
 import cn.com.qmth.scancentral.dao.StudentDao;
-import cn.com.qmth.scancentral.entity.*;
-import cn.com.qmth.scancentral.enums.*;
+import cn.com.qmth.scancentral.entity.AnswerCardEntity;
+import cn.com.qmth.scancentral.entity.ExamEntity;
+import cn.com.qmth.scancentral.entity.OmrGroupEntity;
+import cn.com.qmth.scancentral.entity.PaperEntity;
+import cn.com.qmth.scancentral.entity.PaperPageEntity;
+import cn.com.qmth.scancentral.entity.QuestionEntity;
+import cn.com.qmth.scancentral.entity.StudentEntity;
+import cn.com.qmth.scancentral.entity.StudentPaperEntity;
+import cn.com.qmth.scancentral.entity.SubjectEntity;
+import cn.com.qmth.scancentral.entity.UserEntity;
+import cn.com.qmth.scancentral.enums.ExamMode;
+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.LockType;
+import cn.com.qmth.scancentral.enums.OP;
+import cn.com.qmth.scancentral.enums.OmrField;
+import cn.com.qmth.scancentral.enums.Role;
+import cn.com.qmth.scancentral.enums.ScanStatus;
+import cn.com.qmth.scancentral.enums.UploadStatus;
 import cn.com.qmth.scancentral.exception.NotFoundExceptions;
 import cn.com.qmth.scancentral.exception.ParameterExceptions;
 import cn.com.qmth.scancentral.model.ManualAbsentImportDTO;
-import cn.com.qmth.scancentral.service.*;
+import cn.com.qmth.scancentral.service.AnswerCardService;
+import cn.com.qmth.scancentral.service.AnswerCardSubjectService;
+import cn.com.qmth.scancentral.service.AssignedCheckHistoryService;
+import cn.com.qmth.scancentral.service.AsyncTaskService;
+import cn.com.qmth.scancentral.service.BatchService;
+import cn.com.qmth.scancentral.service.ExamService;
+import cn.com.qmth.scancentral.service.FileService;
+import cn.com.qmth.scancentral.service.OmrGroupService;
+import cn.com.qmth.scancentral.service.OmrTaskService;
+import cn.com.qmth.scancentral.service.PaperPageService;
+import cn.com.qmth.scancentral.service.PaperService;
+import cn.com.qmth.scancentral.service.QuestionService;
+import cn.com.qmth.scancentral.service.StudentPaperService;
+import cn.com.qmth.scancentral.service.StudentService;
+import cn.com.qmth.scancentral.service.SubjectService;
+import cn.com.qmth.scancentral.service.ToolExportService;
+import cn.com.qmth.scancentral.service.UserService;
+import cn.com.qmth.scancentral.support.SpringContextHolder;
 import cn.com.qmth.scancentral.support.TaskLock;
 import cn.com.qmth.scancentral.support.TaskLockUtil;
 import cn.com.qmth.scancentral.util.BatchGetDataUtil;
 import cn.com.qmth.scancentral.util.BatchSetDataUtil;
 import cn.com.qmth.scancentral.util.MD5Util;
 import cn.com.qmth.scancentral.util.PageUtil;
-import cn.com.qmth.scancentral.vo.*;
-import cn.com.qmth.scancentral.vo.answerquery.*;
+import cn.com.qmth.scancentral.vo.AbsentInfoVo;
+import cn.com.qmth.scancentral.vo.AbsentManualImportVo;
+import cn.com.qmth.scancentral.vo.AbsentQueryVo;
+import cn.com.qmth.scancentral.vo.AnswerDeleteVo;
+import cn.com.qmth.scancentral.vo.AnswerExportK12Vo;
+import cn.com.qmth.scancentral.vo.AnswerExportVo;
+import cn.com.qmth.scancentral.vo.AnswerRefixVo;
+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;
+import cn.com.qmth.scancentral.vo.ScanAnswerInfoVo;
+import cn.com.qmth.scancentral.vo.StudentUploadVo;
+import cn.com.qmth.scancentral.vo.UpdateTimeVo;
+import cn.com.qmth.scancentral.vo.answerquery.AnswerPageVo;
+import cn.com.qmth.scancentral.vo.answerquery.AnswerPaperVo;
+import cn.com.qmth.scancentral.vo.answerquery.AnswerQueryParam;
+import cn.com.qmth.scancentral.vo.answerquery.AnswerQueryVo;
+import cn.com.qmth.scancentral.vo.answerquery.StudentPaperVo;
 import cn.com.qmth.scancentral.vo.assginedcheck.AssginedTaskResult;
 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.examroom.ExamRoomScannedQuery;
 import cn.com.qmth.scancentral.vo.examroom.ExamRoomScannedVo;
 import cn.com.qmth.scancentral.vo.paper.PaperCetVo;
 import cn.com.qmth.scancentral.vo.paper.PaperPageCetVo;
-import cn.com.qmth.scancentral.vo.student.*;
+import cn.com.qmth.scancentral.vo.student.StudentAnswerVo;
+import cn.com.qmth.scancentral.vo.student.StudentExamRoomVo;
+import cn.com.qmth.scancentral.vo.student.StudentPageQuery;
+import cn.com.qmth.scancentral.vo.student.StudentPageVo;
+import cn.com.qmth.scancentral.vo.student.StudentQuery;
+import cn.com.qmth.scancentral.vo.student.StudentVo;
 import cn.com.qmth.scancentral.vo.studentimport.StudentCountVo;
 import cn.com.qmth.scancentral.vo.subject.SubjectScanProgressVo;
+import cn.com.qmth.scancentral.vo.subject.TaskIdVo;
 import cn.com.qmth.scancentral.vo.task.TaskStatusVo;
 
 @Service
@@ -79,6 +168,11 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
 
     private static final Logger log = LoggerFactory.getLogger(StudentService.class);
 
+    private static ExecutorService exec;
+
+    @Autowired
+    private AsyncTaskService asyncTaskService;
+
     @Autowired
     private PaperService paperService;
 
@@ -130,6 +224,23 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
     @Autowired
     private FileService fileService;
 
+    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);
+                        }
+                    }
+                });
+    }
+
     /**
      * 整体更新考生绑定的paper并刷新考生状态,若集合为空则表示考生无扫描结果,需要在外部调用处对考生上锁
      *
@@ -185,7 +296,8 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
             // 获取paper详情更新考生状态
             PaperEntity paper = paperService.getById(studentPaper.getPaperId());
             student.setAssigned(student.getAssigned() || paper.getAssigned());
-//            student.setAssignedSuspect(student.getAssignedSuspect() || paper.getAssignedSuspect());
+            // student.setAssignedSuspect(student.getAssignedSuspect() ||
+            // paper.getAssignedSuspect());
             student.setQuestionFilled(student.getQuestionFilled() || paper.getQuestionFilled());
             student.setSubjectiveFilled(student.getSubjectiveFilled() || paper.getSubjectiveFilled());
             student.setCardNumber(paper.getCardNumber());
@@ -1673,10 +1785,10 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
     }
 
     @Override
-    public int getCountByExamAndAssignedCheckCount(Long examId,String subjectCode, int assignedCheckCount, OP op) {
+    public int getCountByExamAndAssignedCheckCount(Long examId, String subjectCode, int assignedCheckCount, OP op) {
         LambdaQueryWrapper<StudentEntity> wrapper = new LambdaQueryWrapper<>();
         wrapper.eq(StudentEntity::getExamId, examId);
-        if(subjectCode!=null){
+        if (subjectCode != null) {
             wrapper.eq(StudentEntity::getSubjectCode, subjectCode);
         }
         wrapper.eq(StudentEntity::getAssigned, true);
@@ -1766,7 +1878,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
                     pvo.setId(p.getPaperId());
                     pvo.setNumber(p.getNumber());
                     pvo.setAssigned(p.getAssigned());
-//                    pvo.setAssignedSuspect(p.getAssignedSuspect());
+                    // pvo.setAssignedSuspect(p.getAssignedSuspect());
                     papers.add(pvo);
                     paperMap.put(p.getPaperId(), pvo);
                 }
@@ -1812,7 +1924,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
 
     @Override
     public boolean apply(StudentEntity t, String account) {
-        TaskLock taskLock = TaskLockUtil.getAssignedCheckTask(t.getExamId()+"_"+t.getSubjectCode());
+        TaskLock taskLock = TaskLockUtil.getAssignedCheckTask(t.getExamId() + "_" + t.getSubjectCode());
         boolean lock = taskLock.add(t.getId(), account);
         // 上锁失败直接返回
         if (!lock) {
@@ -1829,26 +1941,26 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
 
     @Override
     public boolean hasAppliedAssignedCheckTask(StudentEntity t, String account) {
-        TaskLock taskLock = TaskLockUtil.getAssignedCheckTask(t.getExamId()+"_"+t.getSubjectCode());
+        TaskLock taskLock = TaskLockUtil.getAssignedCheckTask(t.getExamId() + "_" + t.getSubjectCode());
         return taskLock.exist(t.getId(), account);
     }
 
     @Override
-    public TaskStatusVo getAssignedCheckTaskStatus(Long examId,String subjectCode, User user) {
+    public TaskStatusVo getAssignedCheckTaskStatus(Long examId, String subjectCode, User user) {
         TaskStatusVo status = new TaskStatusVo();
         if (Role.AUDITOR.equals(user.getRole())) {
-            status.setFinishCount(assignedCheckHistoryService.getCountByUserId(user.getId(), examId,subjectCode));
-            status.setTodoCount(this.getCountByExamAndAssignedCheckCount(examId,subjectCode, 0, OP.EQ));
+            status.setFinishCount(assignedCheckHistoryService.getCountByUserId(user.getId(), examId, subjectCode));
+            status.setTodoCount(this.getCountByExamAndAssignedCheckCount(examId, subjectCode, 0, OP.EQ));
         } else {
-            status.setFinishCount(this.getCountByExamAndAssignedCheckCount(examId,subjectCode, 2, OP.GE));
-            status.setTodoCount(this.getCountByExamAndAssignedCheckCount(examId, subjectCode,1, OP.EQ));
+            status.setFinishCount(this.getCountByExamAndAssignedCheckCount(examId, subjectCode, 2, OP.GE));
+            status.setTodoCount(this.getCountByExamAndAssignedCheckCount(examId, subjectCode, 1, OP.EQ));
         }
         return status;
     }
 
     @Override
-    public void releaseAssignedCheckTaskByUser(Long examId,String subjectCode , String account) {
-        TaskLock taskLock = TaskLockUtil.getAssignedCheckTask(examId+"_"+subjectCode);
+    public void releaseAssignedCheckTaskByUser(Long examId, String subjectCode, String account) {
+        TaskLock taskLock = TaskLockUtil.getAssignedCheckTask(examId + "_" + subjectCode);
         taskLock.clear(account);
     }
 
@@ -1864,10 +1976,11 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
         concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().lock();
         try {
             assignedCheckHistoryService.save(user.getId(), student.getId(), student.getExamId());
-//            for (AssignedTaskResultPaper paper : result.getPapers()) {
-//                paperService.updatePaperAssignedSuspect(student.getId(), paper.getNumber(), result.getAssignedSuspect());
-//            }
-//            updateStudentByPaper(user, student.getId(), false);
+            // for (AssignedTaskResultPaper paper : result.getPapers()) {
+            // paperService.updatePaperAssignedSuspect(student.getId(),
+            // paper.getNumber(), result.getAssignedSuspect());
+            // }
+            // updateStudentByPaper(user, student.getId(), false);
             student.setAbsentSuspect(result.getAssignedSuspect());
             saveOrUpdate(student);
             updateAssignedCheckCount(student.getId(), false);
@@ -1876,31 +1989,33 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
         }
         AssignedTaskSaveVo vo = new AssignedTaskSaveVo();
         vo.setId(student.getId());
-        vo.setStatus(this.getAssignedCheckTaskStatus(student.getExamId(),student.getSubjectCode(), user));
+        vo.setStatus(this.getAssignedCheckTaskStatus(student.getExamId(), student.getSubjectCode(), user));
         return vo;
     }
 
     @Override
-    public PageResult<AnswerQueryVo> getAssignedCheckTaskHistory(Long examId,String subjectCode,Long pageNumber, Long pageSize, User user) {
-        IPage<AnswerQueryVo> result = this.baseMapper.getAssignedCheckTaskHistory(new Page<>(pageNumber, pageSize),examId,subjectCode,user.getId());
+    public PageResult<AnswerQueryVo> getAssignedCheckTaskHistory(Long examId, String subjectCode, Long pageNumber,
+            Long pageSize, User user) {
+        IPage<AnswerQueryVo> result = this.baseMapper.getAssignedCheckTaskHistory(new Page<>(pageNumber, pageSize),
+                examId, subjectCode, user.getId());
         for (AnswerQueryVo t : result.getRecords()) {
             t = toTaskVo(t);
         }
-        return  PageUtil.of(result);
+        return PageUtil.of(result);
     }
 
     @Override
-    public AnswerQueryVo getAssignedCheckTask(Long examId,String subjectCode, User user) {
+    public AnswerQueryVo getAssignedCheckTask(Long examId, String subjectCode, User user) {
         int retry = 0;
         AnswerQueryVo task = null;
         int checkCount = 0;
         if (Role.AUDITOR.equals(user.getRole())) {
             checkCount = 0;
-        }else{
+        } else {
             checkCount = 1;
         }
         while (task == null) {
-            List<AnswerQueryVo> list = this.findUnCheck(examId,subjectCode,checkCount, retry * 20, 20);
+            List<AnswerQueryVo> list = this.findUnCheck(examId, subjectCode, checkCount, retry * 20, 20);
             if (list.isEmpty()) {
                 break;
             }
@@ -1921,8 +2036,9 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
         return task;
     }
 
-    private List<AnswerQueryVo> findUnCheck(Long examId,String subjectCode,int checkCount, int pageNumber, int pageSize) {
-        return this.baseMapper.findUnCheck(examId,subjectCode, checkCount,pageNumber, pageSize );
+    private List<AnswerQueryVo> findUnCheck(Long examId, String subjectCode, int checkCount, int pageNumber,
+            int pageSize) {
+        return this.baseMapper.findUnCheck(examId, subjectCode, checkCount, pageNumber, pageSize);
     }
 
     private AnswerQueryVo toTaskVo(AnswerQueryVo t) {
@@ -1962,7 +2078,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
                 pvo.setId(p.getPaperId());
                 pvo.setNumber(p.getNumber());
                 pvo.setAssigned(p.getAssigned());
-//                pvo.setAssignedSuspect(p.getAssignedSuspect());
+                // pvo.setAssignedSuspect(p.getAssignedSuspect());
                 papers.add(pvo);
                 paperMap.put(p.getPaperId(), pvo);
             }
@@ -2112,88 +2228,109 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
     }
 
     @Override
-    public ImportBreachResult breachImport(Long examId, String subjectCode, MultipartFile file) {
+    public TaskIdVo breachImport(Long examId, String subjectCode, MultipartFile file) {
+        if (!file.getName().toLowerCase().endsWith(".txt")) {
+            throw new ParameterException("只能是txt文件");
+        }
+        String taskId = FastUUID.get();
         // 暂存临时文件
-        File temDir = new File("temp/" + FastUUID.get() + "/");
+        File temDir = new File("temp/" + taskId + "/");
+        temDir.mkdirs();
+        File txt = new File(temDir.getAbsolutePath() + "/breach.txt");
         try {
-            temDir.mkdirs();
-            File excel = new File(temDir.getAbsolutePath() + "/breach.txt");
-            try {
-                file.transferTo(excel);
-            } catch (Exception e) {
-                throw new RuntimeException("系统错误", e);
+            file.transferTo(txt);
+            List<String> list = FileUtils.readLines(txt, "utf-8");
+            if (CollectionUtils.isEmpty(list) || list.size() <= 1) {
+                throw new ParameterException("文件内容为空");
+            }
+            BreachAndStatusImportTaskVo vo = new BreachAndStatusImportTaskVo();
+            vo.setTaskId(taskId);
+            vo.setTotalCount(list.size() - 1);
+            vo.setExamId(examId);
+            vo.setSubjectCode(subjectCode);
+            vo.setSuccess(true);
+            vo.setProgress(0.0);
+            vo.setTempDir(temDir);
+            vo.setFile(txt);
+            vo.setSuccess(true);
+            BreachImportConsumer com = SpringContextHolder.getBean(BreachImportConsumer.class);
+            com.setVo(vo);
+            exec.execute(com);
+            asyncTaskService.addTask(vo);
+            return TaskIdVo.create(vo.getTaskId());
+        } catch (Exception e) {
+            throw new RuntimeException("系统错误", e);
+        }
+
+    }
+
+    @Override
+    public void breachImportDispose(BreachAndStatusImportTaskVo vo) {
+        InputStream in = null;
+        try {
+            in = new FileInputStream(vo.getFile());
+            breachImportCheck(vo, in);
+        } catch (ParameterException e) {
+            vo.setErrMsg(e.getMessage());
+            vo.setSuccess(false);
+            throw e;
+        } catch (Exception e) {
+            vo.setErrMsg("系统错误");
+            vo.setSuccess(false);
+            throw new ParameterException("系统错误", e);
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                }
             }
-            // 校验Excel
-            ImportBreachResult ret = null;
-            InputStream in = null;
+        }
+        // 根据校验结果上传文件
+        if (vo.getSuccess()) {
+            InputStream excelIn = null;
             try {
-                in = new FileInputStream(excel);
-                ret = breachImportCheck(examId, subjectCode, in);
+                String md5 = MD5Util.md5Hex(vo.getFile());
+                excelIn = new FileInputStream(vo.getFile());
+                fileService.uploadBreach(excelIn, md5, vo.getExamId(), vo.getSubjectCode());
             } catch (IOException e) {
-                throw new RuntimeException("系统错误", e);
+                throw new ParameterException("系统错误", e);
             } finally {
-                if (in != null) {
+                if (excelIn != null) {
                     try {
-                        in.close();
+                        excelIn.close();
                     } catch (IOException e) {
                     }
                 }
             }
-            // 根据校验结果上传文件
-            if (ret != null && ret.getSuccess()) {
-                InputStream excelIn = null;
-                try {
-                    String md5 = MD5Util.md5Hex(excel);
-                    excelIn = new FileInputStream(excel);
-                    fileService.uploadBreach(excelIn, md5, examId, subjectCode);
-                } catch (IOException e) {
-                    throw new RuntimeException("系统错误", e);
-                } finally {
-                    if (excelIn != null) {
-                        try {
-                            excelIn.close();
-                        } catch (IOException e) {
-                        }
-                    }
-                }
-                File info = new File(temDir.getAbsolutePath() + "/breach-info.txt");
-                InputStream infoIn = null;
-                try {
-                    FileUtils.write(info, ret.getBreachCount().toString(), "utf-8");
-                    String md5 = MD5Util.md5Hex(info);
-                    infoIn = new FileInputStream(info);
-                    fileService.uploadBreachInfo(infoIn, md5, examId, subjectCode);
-                } catch (IOException e) {
-                    throw new RuntimeException("系统错误", e);
-                } finally {
-                    if (infoIn != null) {
-                        try {
-                            infoIn.close();
-                        } catch (IOException e) {
-                        }
-                    }
-                }
-            }
-            return ret;
-        } finally {
+            File info = new File(vo.getTempDir().getAbsolutePath() + "/breach-info.txt");
+            InputStream infoIn = null;
             try {
-                FileUtils.deleteDirectory(temDir);
+                FileUtils.write(info, vo.getProgressCount() + "", "utf-8");
+                String md5 = MD5Util.md5Hex(info);
+                infoIn = new FileInputStream(info);
+                fileService.uploadBreachInfo(infoIn, md5, vo.getExamId(), vo.getSubjectCode());
             } catch (IOException e) {
-                throw new RuntimeException("系统错误", e);
+                throw new ParameterException("系统错误", e);
+            } finally {
+                if (infoIn != null) {
+                    try {
+                        infoIn.close();
+                    } catch (IOException e) {
+                    }
+                }
             }
+            vo.setTotalCount(vo.getProgressCount());
         }
     }
 
-    private ImportBreachResult breachImportCheck(Long examId, String subjectCode, InputStream in) {
+    private void breachImportCheck(BreachAndStatusImportTaskVo vo, InputStream in) {
         List<String> lineList = null;
         try {
             lineList = IOUtils.readLines(in, "UTF-8");
         } catch (IOException e) {
-            throw new StatusException("读取文件出错", e);
+            throw new ParameterException("读取文件出错", e);
         }
-        ImportBreachResult ret = new ImportBreachResult();
-        List<String> failRecords = new ArrayList<>();
-        ret.setErrMsg(failRecords);
         Set<String> examNumberSet = new HashSet<>();
         for (int i = 0; i < lineList.size(); i++) {
             String lineString = lineList.get(i);
@@ -2209,7 +2346,8 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
                 if (StringUtils.isBlank(examNumber)) {
                     msg.append("  准考证号不能为空");
                 } else {
-                    StudentEntity s = findByExamAndSubjectCodeAndExamNumber(examId, subjectCode, examNumber);
+                    StudentEntity s = findByExamAndSubjectCodeAndExamNumber(vo.getExamId(), vo.getSubjectCode(),
+                            examNumber);
                     if (s == null) {
                         msg.append("  准考证号未找到");
                     } else {
@@ -2222,21 +2360,17 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
                 }
 
                 String breach = trimAndNullIfBlank(line[1]);
-                if (StringUtils.isNotBlank(breach)) {
-                    ret.setBreachCount(ret.getBreachCount() + 1);
+                if (StringUtils.isBlank(breach)) {
+                    msg.append("  违纪不能为空");
+                } else {
+                    vo.setProgressCount(vo.getProgressCount() + 1);
                 }
             }
             if (msg.length() > 0) {
-                failRecords.add(errorMsg(i + 2, msg.toString()));
+                throw new ParameterException(errorMsg(i + 2, msg.toString()));
             }
         }
 
-        if (CollectionUtils.isNotEmpty(failRecords)) {
-            ret.setSuccess(false);
-            return ret;
-        }
-        ret.setSuccess(true);
-        return ret;
     }
 
     private String errorMsg(int lineNum, String msg) {
@@ -2244,88 +2378,108 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
     }
 
     @Override
-    public ImportBreachResult custStatusImport(Long examId, String subjectCode, MultipartFile file) {
+    public TaskIdVo custStatusImport(Long examId, String subjectCode, MultipartFile file) {
+        if (!file.getName().toLowerCase().endsWith(".txt")) {
+            throw new ParameterException("只能是txt文件");
+        }
+        String taskId = FastUUID.get();
         // 暂存临时文件
-        File temDir = new File("temp/" + FastUUID.get() + "/");
+        File temDir = new File("temp/" + taskId + "/");
+        temDir.mkdirs();
+        File txt = new File(temDir.getAbsolutePath() + "/cust-status.txt");
         try {
-            temDir.mkdirs();
-            File excel = new File(temDir.getAbsolutePath() + "/cust-status.txt");
-            try {
-                file.transferTo(excel);
-            } catch (Exception e) {
-                throw new RuntimeException("系统错误", e);
+            file.transferTo(txt);
+            List<String> list = FileUtils.readLines(txt, "utf-8");
+            if (CollectionUtils.isEmpty(list) || list.size() <= 1) {
+                throw new ParameterException("文件内容为空");
+            }
+            BreachAndStatusImportTaskVo vo = new BreachAndStatusImportTaskVo();
+            vo.setTaskId(taskId);
+            vo.setTotalCount(list.size() - 1);
+            vo.setExamId(examId);
+            vo.setSubjectCode(subjectCode);
+            vo.setSuccess(true);
+            vo.setProgress(0.0);
+            vo.setTempDir(temDir);
+            vo.setFile(txt);
+            vo.setSuccess(true);
+            CustStatusImportConsumer com = SpringContextHolder.getBean(CustStatusImportConsumer.class);
+            com.setVo(vo);
+            exec.execute(com);
+            asyncTaskService.addTask(vo);
+            return TaskIdVo.create(vo.getTaskId());
+        } catch (Exception e) {
+            throw new RuntimeException("系统错误", e);
+        }
+    }
+
+    @Override
+    public void custStatusImportDispose(BreachAndStatusImportTaskVo vo) {
+        InputStream in = null;
+        try {
+            in = new FileInputStream(vo.getFile());
+            custStatusImportCheck(vo, in);
+        } catch (ParameterException e) {
+            vo.setErrMsg(e.getMessage());
+            vo.setSuccess(false);
+            throw e;
+        } catch (Exception e) {
+            vo.setErrMsg("系统错误");
+            vo.setSuccess(false);
+            throw new ParameterException("系统错误", e);
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                }
             }
-            // 校验Excel
-            ImportBreachResult ret = null;
-            InputStream in = null;
+        }
+        // 根据校验结果上传文件
+        if (vo.getSuccess()) {
+            InputStream excelIn = null;
             try {
-                in = new FileInputStream(excel);
-                ret = custStatusImportCheck(examId, subjectCode, in);
+                String md5 = MD5Util.md5Hex(vo.getFile());
+                excelIn = new FileInputStream(vo.getFile());
+                fileService.uploadCustStatus(excelIn, md5, vo.getExamId(), vo.getSubjectCode());
             } catch (IOException e) {
-                throw new RuntimeException("系统错误", e);
+                throw new ParameterException("系统错误", e);
             } finally {
-                if (in != null) {
+                if (excelIn != null) {
                     try {
-                        in.close();
+                        excelIn.close();
                     } catch (IOException e) {
                     }
                 }
             }
-            // 根据校验结果上传文件
-            if (ret != null && ret.getSuccess()) {
-                InputStream excelIn = null;
-                try {
-                    String md5 = MD5Util.md5Hex(excel);
-                    excelIn = new FileInputStream(excel);
-                    fileService.uploadCustStatus(in, md5, examId, subjectCode);
-                } catch (IOException e) {
-                    throw new RuntimeException("系统错误", e);
-                } finally {
-                    if (excelIn != null) {
-                        try {
-                            excelIn.close();
-                        } catch (IOException e) {
-                        }
-                    }
-                }
-                File info = new File(temDir.getAbsolutePath() + "/cust-status-info.txt");
-                InputStream infoIn = null;
-                try {
-                    FileUtils.write(info, ret.getBreachCount().toString(), "utf-8");
-                    String md5 = MD5Util.md5Hex(info);
-                    infoIn = new FileInputStream(info);
-                    fileService.uploadCustStatusInfo(infoIn, md5, examId, subjectCode);
-                } catch (IOException e) {
-                    throw new RuntimeException("系统错误", e);
-                } finally {
-                    if (infoIn != null) {
-                        try {
-                            infoIn.close();
-                        } catch (IOException e) {
-                        }
-                    }
-                }
-            }
-            return ret;
-        } finally {
+            File info = new File(vo.getTempDir().getAbsolutePath() + "/cust-status-info.txt");
+            InputStream infoIn = null;
             try {
-                FileUtils.deleteDirectory(temDir);
+                FileUtils.write(info, vo.getProgressCount() + "", "utf-8");
+                String md5 = MD5Util.md5Hex(info);
+                infoIn = new FileInputStream(info);
+                fileService.uploadCustStatusInfo(infoIn, md5, vo.getExamId(), vo.getSubjectCode());
             } catch (IOException e) {
-                throw new RuntimeException("系统错误", e);
+                throw new ParameterException("系统错误", e);
+            } finally {
+                if (infoIn != null) {
+                    try {
+                        infoIn.close();
+                    } catch (IOException e) {
+                    }
+                }
             }
+            vo.setTotalCount(vo.getProgressCount());
         }
     }
 
-    private ImportBreachResult custStatusImportCheck(Long examId, String subjectCode, InputStream in) {
+    private void custStatusImportCheck(BreachAndStatusImportTaskVo vo, InputStream in) {
         List<String> lineList = null;
         try {
             lineList = IOUtils.readLines(in, "UTF-8");
         } catch (IOException e) {
-            throw new StatusException("读取文件出错", e);
+            throw new ParameterException("读取文件出错", e);
         }
-        ImportBreachResult ret = new ImportBreachResult();
-        List<String> failRecords = new ArrayList<>();
-        ret.setErrMsg(failRecords);
         Set<String> examNumberSet = new HashSet<>();
         for (int i = 0; i < lineList.size(); i++) {
             String lineString = lineList.get(i);
@@ -2342,7 +2496,8 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
                 if (StringUtils.isBlank(examNumber)) {
                     msg.append("  准考证号不能为空");
                 } else {
-                    StudentEntity s = findByExamAndSubjectCodeAndExamNumber(examId, subjectCode, examNumber);
+                    StudentEntity s = findByExamAndSubjectCodeAndExamNumber(vo.getExamId(), vo.getSubjectCode(),
+                            examNumber);
                     if (s == null) {
                         msg.append("  准考证号未找到");
                     } else {
@@ -2355,21 +2510,17 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, StudentEntity> i
                 }
 
                 String breach = trimAndNullIfBlank(line[1]);
-                if (StringUtils.isNotBlank(breach)) {
-                    ret.setBreachCount(ret.getBreachCount() + 1);
+                if (StringUtils.isBlank(breach)) {
+                    msg.append("  考生状态不能为空");
+                } else {
+                    vo.setProgressCount(vo.getProgressCount() + 1);
                 }
             }
             if (msg.length() > 0) {
-                failRecords.add(errorMsg(i + 2, msg.toString()));
+                throw new ParameterException(errorMsg(i + 2, msg.toString()));
             }
         }
 
-        if (CollectionUtils.isNotEmpty(failRecords)) {
-            ret.setSuccess(false);
-            return ret;
-        }
-        ret.setSuccess(true);
-        return ret;
     }
 
     @Override

+ 4 - 2
src/main/java/cn/com/qmth/scancentral/service/impl/SubjectServiceImpl.java

@@ -376,7 +376,8 @@ public class SubjectServiceImpl extends MppServiceImpl<SubjectDao, SubjectEntity
             ExamEntity exam = examService.getById(vo.getExamId());
             SubjectEntity subejct = this.findByExamIdAndCode(vo.getExamId(), vo.getSubjectCode());
             vo.setFileName(subejct.getName() + "_" + exam.getScanSite() + "_OMR.dbf");
-            vo.setFilePath(dbf.getAbsolutePath());
+            vo.setFile(dbf);
+            vo.setTempDir(temDir);
         } catch (StatusException e) {
             vo.setSuccess(false);
             vo.setErrMsg(e.getMessage());
@@ -588,7 +589,8 @@ public class SubjectServiceImpl extends MppServiceImpl<SubjectDao, SubjectEntity
             ExamEntity exam = examService.getById(vo.getExamId());
             vo.setFileName(exam.getScanSite() + "_" + vo.getTotalCount() + "_"
                     + DateUtil.format(new Date(), DateUtil.DatePatterns.YYYYMMDDHH) + ".dbf");
-            vo.setFilePath(dbf.getAbsolutePath());
+            vo.setFile(dbf);
+            vo.setTempDir(temDir);
         } catch (StatusException e) {
             vo.setSuccess(false);
             vo.setErrMsg(e.getMessage());

+ 0 - 47
src/main/java/cn/com/qmth/scancentral/vo/ImportBreachResult.java

@@ -1,47 +0,0 @@
-package cn.com.qmth.scancentral.vo;
-
-import java.util.List;
-
-public class ImportBreachResult {
-
-    private Boolean success;
-
-    private Integer successCount = 0;
-
-    private Integer breachCount = 0;
-
-    private List<String> errMsg;
-
-    public Boolean getSuccess() {
-        return success;
-    }
-
-    public void setSuccess(Boolean success) {
-        this.success = success;
-    }
-
-    public Integer getSuccessCount() {
-        return successCount;
-    }
-
-    public void setSuccessCount(Integer successCount) {
-        this.successCount = successCount;
-    }
-
-    public List<String> getErrMsg() {
-        return errMsg;
-    }
-
-    public void setErrMsg(List<String> errMsg) {
-        this.errMsg = errMsg;
-    }
-
-    public Integer getBreachCount() {
-        return breachCount;
-    }
-
-    public void setBreachCount(Integer breachCount) {
-        this.breachCount = breachCount;
-    }
-
-}

+ 19 - 5
src/main/java/cn/com/qmth/scancentral/vo/asynctask/AsyncTaskVo.java

@@ -1,10 +1,16 @@
 package cn.com.qmth.scancentral.vo.asynctask;
 
+import java.io.File;
+
 public class AsyncTaskVo {
 
     private String taskId;
 
-    private String filePath;
+    // 需要清除的临时目录
+    private File tempDir;
+
+    // 导入、导出的文件
+    private File file;
 
     private Double progress;
 
@@ -44,12 +50,20 @@ public class AsyncTaskVo {
         this.errMsg = errMsg;
     }
 
-    public String getFilePath() {
-        return filePath;
+    public File getFile() {
+        return file;
+    }
+
+    public void setFile(File file) {
+        this.file = file;
+    }
+
+    public File getTempDir() {
+        return tempDir;
     }
 
-    public void setFilePath(String filePath) {
-        this.filePath = filePath;
+    public void setTempDir(File tempDir) {
+        this.tempDir = tempDir;
     }
 
 }

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

@@ -0,0 +1,45 @@
+package cn.com.qmth.scancentral.vo.asynctask;
+
+public class BreachAndStatusImportTaskVo extends AsyncTaskVo {
+
+    private Long examId;
+
+    private String subjectCode;
+
+    private int totalCount;
+
+    private int progressCount;
+
+    public Long getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
+
+    public String getSubjectCode() {
+        return subjectCode;
+    }
+
+    public void setSubjectCode(String subjectCode) {
+        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;
+    }
+
+}

+ 1 - 1
src/main/resources/mapper/BatchMapper.xml

@@ -276,7 +276,7 @@
     </select>
     <select id="studentList"
             resultType="cn.com.qmth.scancentral.vo.batch.BatchStudentSimpleVo">
-        select s.id studentId, s.name studentName, s.exam_number
+        select distinct s.id studentId, s.name studentName, s.exam_number
         from sc_batch_paper b
                  left join sc_student s on b.student_id = s.id
         where b.batch_id = #{batchId}