deason 9 ماه پیش
والد
کامیت
45856507a0

+ 2 - 2
install/mysql/init/scan_central_db.sql

@@ -34,7 +34,7 @@ CREATE TABLE IF NOT EXISTS `sc_student`
     `create_time`          bigint      DEFAULT NULL,
     `update_time`          bigint      DEFAULT NULL,
     PRIMARY KEY (`id`),
-    UNIQUE KEY `exam_student_subject` (`exam_id`, `exam_number`, `subject_code`),
+    UNIQUE KEY `exam_student_subject` (`exam_id`, `subject_code`, `exam_number`),
     KEY `exam_assigned` (`exam_id`, `assigned`, `assigned_check_count`)
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4;
@@ -91,7 +91,7 @@ CREATE TABLE IF NOT EXISTS `sc_exam`
     `scanner_assigned_verify_password` varchar(50) DEFAULT NULL,
     `year`                             int         DEFAULT NULL,
     `year_half`                        int         DEFAULT NULL,
-    `scan_site` 					varchar(50) 	DEFAULT NULL,
+    `scan_site`                        varchar(50) DEFAULT NULL,
     `data_sync_time`                   bigint      DEFAULT NULL,
     `card_sync_time`                   bigint      DEFAULT NULL,
     `creator_id`                       bigint      DEFAULT NULL,

+ 5 - 0
src/main/java/cn/com/qmth/scancentral/controller/admin/StudentImportController.java

@@ -10,6 +10,7 @@ import cn.com.qmth.scancentral.vo.studentimport.StudentCountVo;
 import cn.com.qmth.scancentral.vo.studentimport.StudentImportConfigVo;
 import com.qmth.boot.api.annotation.Aac;
 import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.boot.core.exception.StatusException;
 import com.qmth.boot.tools.uuid.FastUUID;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -40,6 +41,10 @@ public class StudentImportController extends BaseController {
     @ApiOperation(value = "考生导入")
     @PostMapping("/import")
     public Map<String, Object> studentImport(@RequestParam Long examId, @RequestParam MultipartFile file) throws Exception {
+        if (studentImportService.existRunningStudentImportTask()) {
+            throw new StatusException("有正在运行的考生导入任务,请稍后再试!");
+        }
+
         final String taskId = FastUUID.get();
         studentImportService.studentImport(taskId, examId, file.getOriginalFilename(), file.getBytes());
 

+ 2 - 0
src/main/java/cn/com/qmth/scancentral/service/StudentImportService.java

@@ -11,4 +11,6 @@ public interface StudentImportService {
 
     File studentImportReport(String taskId);
 
+    boolean existRunningStudentImportTask();
+
 }

+ 74 - 10
src/main/java/cn/com/qmth/scancentral/service/impl/StudentImportServiceImpl.java

@@ -1,8 +1,10 @@
 package cn.com.qmth.scancentral.service.impl;
 
+import cn.com.qmth.scancentral.bean.ImportStudentDomain;
 import cn.com.qmth.scancentral.entity.ExamEntity;
 import cn.com.qmth.scancentral.service.ExamService;
 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.util.FileUtil;
 import cn.com.qmth.scancentral.vo.studentimport.ImportTaskVo;
@@ -35,6 +37,9 @@ public class StudentImportServiceImpl implements StudentImportService {
     @Autowired
     private SubjectService subjectService;
 
+    @Autowired
+    private StudentService studentService;
+
     @Override
     public Map<String, Object> studentImportProgress(String taskId) {
         ImportTaskVo task = IMPORT_TASKS.get(taskId);
@@ -69,6 +74,16 @@ public class StudentImportServiceImpl implements StudentImportService {
         return logFile;
     }
 
+    @Override
+    public boolean existRunningStudentImportTask() {
+        for (ImportTaskVo task : IMPORT_TASKS.values()) {
+            if (task.getProgress() < 100d) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     @Async
     @Override
     public void studentImport(String taskId, Long examId, String fileName, byte[] fileBytes) {
@@ -117,29 +132,78 @@ public class StudentImportServiceImpl implements StudentImportService {
 
         List<StudentImportInfo> list = new ArrayList<>();
         List<String> errs = this.parseValues(lines, list, examId, exam.getYear(), exam.getYearHalf());
-        log.warn("解析考生数据共{}条! errCount:{} taskId:{}", list.size(), errs.size(), taskId);
+        log.warn("本次解析考生数据共{}条! errCount:{} taskId:{}", list.size(), errs.size(), taskId);
         if (!errs.isEmpty()) {
-            errs.add("本次执行导入0条,请先处理内容错误!");
+            errs.add(String.format("本次解析考生数据共%s条,执行导入0条,请先处理文件内容错误!", list.size()));
             this.writeLogFile(logFile, StringUtils.join(errs, "\n"));
             task.setProgress(100d);
             return;
         }
 
+        if (list.isEmpty()) {
+            this.writeLogFile(logFile, "本次解析考生数据共0条,请填写有效的数据内容!");
+            task.setProgress(100d);
+            return;
+        }
+
         log.info("执行导入数据库开始... {}", taskId);
         this.writeLogFile(logFile, "执行导入数据库开始...");
 
-        //to do
+        int finishCount = 0;
+        int total = list.size();
+        long startTime = System.currentTimeMillis();
+
         try {
-            for (int i = 1; i <= list.size(); i++) {
-                Thread.sleep(5000);
-                task.setProgress(i * 100d / list.size());
+            int batchNum = 1000;
+            List<ImportStudentDomain> batchList = new ArrayList<>();
+
+            for (int n = 0; n < total; n++) {
+                batchList.add(ofData(list.get(n)));
+
+                if ((n + 1) % batchNum == 0) {
+                    studentService.importStudent(batchList);
+                    finishCount = finishCount + batchList.size();
+                    batchList.clear();
+
+                    double progress = finishCount * 100f / total;
+                    long cost = (System.currentTimeMillis() - startTime) / 1000L;
+                    log.info("已导入:{}条 已耗时:{}秒 进度:{}%", finishCount, cost, progress);
+                    task.setProgress(progress);
+                }
             }
-        } catch (InterruptedException e) {
-            log.error(e.getMessage());
+
+            if (!batchList.isEmpty()) {
+                studentService.importStudent(batchList);
+                finishCount = finishCount + batchList.size();
+            }
+
+            long cost = (System.currentTimeMillis() - startTime) / 1000L;
+            log.info("已导入:{}条 已耗时:{}秒 进度:100%", finishCount, cost);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            this.writeLogFile(logFile, "【错误】导入过程异常终止!");
+        } finally {
+            task.setProgress(100d);
         }
 
         log.info("执行导入数据库结束... {}", taskId);
-        this.writeLogFile(logFile, "本次成功导入0条,失败0条");
+        this.writeLogFile(logFile, String.format("本次解析考生数据共%s条,成功导入%s条,失败导入%s条!", total, finishCount, total - finishCount));
+    }
+
+    private ImportStudentDomain ofData(StudentImportInfo info) {
+        ImportStudentDomain data = new ImportStudentDomain();
+        data.setExamId(info.getExamId());
+        data.setSubjectCode(info.getSubjectCode());
+        data.setExamNumber(info.getExamNumber());
+        data.setName(info.getName());
+        data.setCampusCode(info.getCampusCode());
+        data.setCampusName(info.getCampusName());
+        data.setExamSite(info.getExamSite());
+        data.setExamSiteName(info.getExamSiteName());
+        data.setExamRoom(info.getExamRoom());
+        data.setPackageCode(info.getPackageCode());
+        data.setSeatNumber(info.getSeatNumber());
+        return data;
     }
 
     private List<String> parseValues(List<String> lines, List<StudentImportInfo> list, Long examId, Integer yearConfig, Integer yearHalfConfig) {
@@ -217,8 +281,8 @@ public class StudentImportServiceImpl implements StudentImportService {
             data.setExamId(examId);
             data.setSubjectCode(subjectCode);
             data.setExamNumber(examNumber);
-            data.setName(name);
             data.setStudentCode(examNumber);
+            data.setName(name);
             data.setExamSite(examSite);
             data.setExamSiteName(examSiteName);
             data.setCampusCode(campusCode);

+ 10 - 20
src/main/java/cn/com/qmth/scancentral/vo/studentimport/StudentImportInfo.java

@@ -2,18 +2,16 @@ package cn.com.qmth.scancentral.vo.studentimport;
 
 public class StudentImportInfo {
 
-    private Long id;// 考生ID
-
     private Long examId;// 考试ID
 
     private String subjectCode;// 科目代码
 
     private String examNumber;// 准考证号
 
-    private String name;// 考生姓名
-
     private String studentCode;// 考生编号
 
+    private String name;// 考生姓名
+
     private String campusCode;
 
     private String campusName;// 学习中心
@@ -28,14 +26,6 @@ public class StudentImportInfo {
 
     private String seatNumber;// 座位号
 
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
     public Long getExamId() {
         return examId;
     }
@@ -60,14 +50,6 @@ public class StudentImportInfo {
         this.examNumber = examNumber;
     }
 
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
     public String getStudentCode() {
         return studentCode;
     }
@@ -76,6 +58,14 @@ public class StudentImportInfo {
         this.studentCode = studentCode;
     }
 
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
     public String getCampusCode() {
         return campusCode;
     }