xiatian 3 mesi fa
parent
commit
7664dcf460

+ 2 - 7
db/am_db.sql

@@ -36,16 +36,11 @@ CREATE TABLE `am_student_score` (
   `create_time` datetime DEFAULT NULL,
   `update_time` datetime DEFAULT NULL,
   `question_id` bigint NOT NULL,
-  `exam_id` bigint NOT NULL,
-  `subject_code` varchar(255) COLLATE utf8mb4_bin NOT NULL,
-  `student_code` varchar(255) COLLATE utf8mb4_bin NOT NULL,
-  `main_number` int NOT NULL,
-  `sub_number` 	 varchar(255) NOT NULL,
+  `exam_number` varchar(255) COLLATE utf8mb4_bin NOT NULL,
   `answer_status` varchar(255) NOT NULL,
   `score_status` varchar(255) NOT NULL,
   `answer` longtext COLLATE utf8mb4_bin DEFAULT NULL,
   `ai_score` double DEFAULT NULL,
-  `score_ratio` double DEFAULT NULL,
   `marking_score` double DEFAULT NULL,
   `err_msg` varchar(2000) COLLATE utf8mb4_bin DEFAULT NULL,
   `score_none` bit(1) DEFAULT NULL,
@@ -53,5 +48,5 @@ CREATE TABLE `am_student_score` (
   `sheet` varchar(1000) DEFAULT NULL,
   `slice` varchar(500) DEFAULT NULL,
   PRIMARY KEY (`id`),
-  UNIQUE KEY `IDX_STUDENT_SCORE_01` (`exam_id`, `subject_code`, `student_code`,`question_id`)
+  UNIQUE KEY `IDX_STUDENT_SCORE_01` (`question_id`,`exam_number`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

BIN
file/question-import.xlsx


+ 5 - 5
src/main/java/cn/com/qmth/am/bean/StudentScoreInfo.java

@@ -4,7 +4,7 @@ public class StudentScoreInfo {
 
     private Long questionId;
 
-    private String studentCode;
+    private String examNumber;
 
     public Long getQuestionId() {
         return questionId;
@@ -14,12 +14,12 @@ public class StudentScoreInfo {
         this.questionId = questionId;
     }
 
-    public String getStudentCode() {
-        return studentCode;
+    public String getExamNUmber() {
+        return examNumber;
     }
 
-    public void setStudentCode(String studentCode) {
-        this.studentCode = studentCode;
+    public void setExamNumber(String examNumber) {
+        this.examNumber = examNumber;
     }
 
 }

+ 4 - 26
src/main/java/cn/com/qmth/am/config/InitData.java

@@ -1,60 +1,38 @@
 package cn.com.qmth.am.config;
 
 import java.io.File;
-import java.util.List;
 
-import org.apache.commons.collections4.CollectionUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.stereotype.Component;
 
-import com.qmth.boot.core.solar.model.OrgInfo;
-import com.qmth.boot.core.solar.service.SolarService;
-
+import cn.com.qmth.am.service.QuestionService;
 import cn.com.qmth.am.service.StudentScoreService;
 
 @Component
 public class InitData implements CommandLineRunner {
 
-    private static final Logger log = LoggerFactory.getLogger(InitData.class);
-
     @Autowired
     private SysProperty sysProperty;
 
-    @Autowired
-    private SolarService solarService;
-
     @Autowired
     private StudentScoreService studentScoreService;
 
-    // @Autowired
-    // private OcrService ocrService;
+    @Autowired
+    private QuestionService questionService;
 
     @Override
     public void run(String... args) throws Exception {
-        List<OrgInfo> orgs = null;
-        try {
-            orgs = solarService.getOrgList();
-        } catch (Exception e) {
-            log.error("激活授权失败");
-            System.exit(1);
-        }
-        if (CollectionUtils.isEmpty(orgs)) {
-            log.error("授权信息有误");
-            System.exit(1);
-        }
         File dataDir = new File(sysProperty.getDataDir());
         if (!dataDir.exists()) {
             dataDir.mkdir();
         }
         resetTaskStatus();
-        // ocrService.ocr();
     }
 
     private void resetTaskStatus() {
         studentScoreService.resetStatus();
+        questionService.resetStatus();
     }
 
 }

+ 0 - 13
src/main/java/cn/com/qmth/am/config/SysProperty.java

@@ -3,8 +3,6 @@ package cn.com.qmth.am.config;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
-import cn.com.qmth.am.enums.DataType;
-
 @Component
 public class SysProperty {
 
@@ -23,9 +21,6 @@ public class SysProperty {
     @Value("${am.image-server}")
     private String imageServer;
 
-    @Value("${am.data-type}")
-    private DataType dataType;
-
     @Value("${am.marking-thread-count:2}")
     private Integer markingThreadCount;
 
@@ -66,14 +61,6 @@ public class SysProperty {
         this.imageServer = imageServer;
     }
 
-    public DataType getDataType() {
-        return dataType;
-    }
-
-    public void setDataType(DataType dataType) {
-        this.dataType = dataType;
-    }
-
     public String getDataDir() {
         return dataDir;
     }

+ 6 - 7
src/main/java/cn/com/qmth/am/consumer/OcrConsumer.java

@@ -1,6 +1,5 @@
 package cn.com.qmth.am.consumer;
 
-import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 
 import org.springframework.beans.factory.annotation.Autowired;
@@ -19,7 +18,7 @@ public class OcrConsumer implements Runnable {
 
     private StudentScoreEntity score;
 
-    private Map<Long, QuestionEntity> quetions;
+    private QuestionEntity quetion;
 
     @Autowired
     private StudentService studentService;
@@ -27,7 +26,7 @@ public class OcrConsumer implements Runnable {
     @Override
     public void run() {
         try {
-            studentService.buildImage(score, quetions);
+            studentService.buildImage(score, quetion);
         } finally {
             endGate.countDown();
         }
@@ -49,12 +48,12 @@ public class OcrConsumer implements Runnable {
         this.score = score;
     }
 
-    public Map<Long, QuestionEntity> getQuetions() {
-        return quetions;
+    public QuestionEntity getQuetion() {
+        return quetion;
     }
 
-    public void setQuetions(Map<Long, QuestionEntity> quetions) {
-        this.quetions = quetions;
+    public void setQuetion(QuestionEntity quetion) {
+        this.quetion = quetion;
     }
 
 }

+ 1 - 7
src/main/java/cn/com/qmth/am/controller/AdminController.java

@@ -31,7 +31,6 @@ import com.qmth.boot.core.concurrent.service.ConcurrentService;
 
 import cn.com.qmth.am.bean.DataKey;
 import cn.com.qmth.am.config.SysProperty;
-import cn.com.qmth.am.dao.stmms.StmmsDao;
 import cn.com.qmth.am.entity.QuestionEntity;
 import cn.com.qmth.am.entity.StudentScoreEntity;
 import cn.com.qmth.am.enums.DataStatus;
@@ -63,9 +62,6 @@ public class AdminController {
     @Autowired
     private ConcurrentService concurrentService;
 
-    @Autowired
-    private StmmsDao stmmsDao;
-
     @ApiOperation(value = "分析数据")
     @RequestMapping(value = "fenxi", method = RequestMethod.GET)
     public void fenxi(HttpServletResponse response, @RequestParam Long examId,
@@ -80,8 +76,7 @@ public class AdminController {
         }
         sb.append("试题数:" + qs.size() + "\r\n");
         for (QuestionEntity q : qs) {
-            List<StudentScoreEntity> scores = studentScoreService.findBy(examId, q.getSubjectCode(), q.getMainNumber(),
-                    q.getSubNumber(), exZero, count, score);
+            List<StudentScoreEntity> scores = studentScoreService.findBy(q.getId(), exZero, count, score);
             if (CollectionUtils.isEmpty(scores)) {
                 sb.append(q.getSubjectCode() + "|" + q.getMainNumber() + "|" + q.getSubNumber() + "| 相关系数:- \r\n");
             } else {
@@ -265,7 +260,6 @@ public class AdminController {
             }
             qsCourse = cset.size();
         }
-        sb.append("stmms:" + stmmsDao.getName() + "\r\n");
         sb.append("ocr任务是否开启:" + (sysProperty.getOcrTaskEnable() ? "是" : "否") + "\r\n");
         sb.append("评分任务是否开启:" + (sysProperty.getMarkingTaskEnable() ? "是" : "否") + "\r\n");
         sb.append("试卷科目总数:" + qsCourse + "\r\n");

+ 8 - 1
src/main/java/cn/com/qmth/am/dao/stmms/StmmsDao.java

@@ -1,9 +1,16 @@
 package cn.com.qmth.am.dao.stmms;
 
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+
 import com.baomidou.dynamic.datasource.annotation.DS;
 
+import cn.com.qmth.am.entity.StudentScoreEntity;
+
 @DS("data-source-stmms")
 public interface StmmsDao {
 
-    String getName();
+    List<StudentScoreEntity> getMarkStudent(@Param("examId") Long examId, @Param("subjectCode") String subjectCode,
+            @Param("mainNumber") Integer mainNumber, @Param("subNumber") String subNumber);
 }

+ 5 - 56
src/main/java/cn/com/qmth/am/entity/StudentScoreEntity.java

@@ -17,15 +17,7 @@ public class StudentScoreEntity extends IdEntity {
 
     private Long questionId;
 
-    private Long examId;
-
-    private String subjectCode;
-
-    private String studentCode;
-
-    private Integer mainNumber;
-
-    private String subNumber;
+    private String examNumber;
 
     // 机评分
     private Double aiScore;
@@ -33,9 +25,6 @@ public class StudentScoreEntity extends IdEntity {
     // 人评分
     private Double markingScore;
 
-    // 机评得分率
-    private Double scoreRatio;
-
     // ocr状态
     private DataStatus answerStatus;
 
@@ -60,22 +49,6 @@ public class StudentScoreEntity extends IdEntity {
 
     private String slice;
 
-    public Integer getMainNumber() {
-        return mainNumber;
-    }
-
-    public void setMainNumber(Integer mainNumber) {
-        this.mainNumber = mainNumber;
-    }
-
-    public String getSubNumber() {
-        return subNumber;
-    }
-
-    public void setSubNumber(String subNumber) {
-        this.subNumber = subNumber;
-    }
-
     public Double getAiScore() {
         return aiScore;
     }
@@ -92,14 +65,6 @@ public class StudentScoreEntity extends IdEntity {
         this.markingScore = markingScore;
     }
 
-    public Double getScoreRatio() {
-        return scoreRatio;
-    }
-
-    public void setScoreRatio(Double scoreRatio) {
-        this.scoreRatio = scoreRatio;
-    }
-
     public String getErrMsg() {
         return errMsg;
     }
@@ -108,28 +73,12 @@ public class StudentScoreEntity extends IdEntity {
         this.errMsg = errMsg;
     }
 
-    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 String getStudentCode() {
-        return studentCode;
+    public String getExamNumber() {
+        return examNumber;
     }
 
-    public void setStudentCode(String studentCode) {
-        this.studentCode = studentCode;
+    public void setExamNumber(String examNumber) {
+        this.examNumber = examNumber;
     }
 
     public DataStatus getAnswerStatus() {

+ 14 - 5
src/main/java/cn/com/qmth/am/service/QuestionService.java

@@ -7,17 +7,26 @@ import com.baomidou.mybatisplus.extension.service.IService;
 
 import cn.com.qmth.am.bean.ImportResult;
 import cn.com.qmth.am.entity.QuestionEntity;
+import cn.com.qmth.am.enums.DataStatus;
 
 /**
  * 类注释
  */
-public interface QuestionService  extends IService<QuestionEntity> {
+public interface QuestionService extends IService<QuestionEntity> {
 
-	void importQuestion();
+    void importQuestion();
 
-	public ImportResult disposeFile(InputStream inputStream);
+    List<QuestionEntity> findToDispose();
 
-	List<QuestionEntity> findByExamId(Long examId);
+    public ImportResult disposeFile(InputStream inputStream);
 
-	void removeBy(Long examId, String subjectCode);
+    List<QuestionEntity> findByExamId(Long examId);
+
+    void removeBy(Long examId, String subjectCode);
+
+    void updateStatus(Long id, DataStatus processing);
+
+    List<QuestionEntity> findByExamIdAndSubject(Long examId, String subjectCode);
+
+    void resetStatus();
 }

+ 13 - 0
src/main/java/cn/com/qmth/am/service/StmmsService.java

@@ -0,0 +1,13 @@
+package cn.com.qmth.am.service;
+
+import java.util.List;
+
+import cn.com.qmth.am.entity.StudentScoreEntity;
+
+/**
+ * 类注释
+ */
+public interface StmmsService {
+
+    List<StudentScoreEntity> getMarkStudent(Long examId, String subjectCode, Integer mainNumber, String subNumber);
+}

+ 3 - 11
src/main/java/cn/com/qmth/am/service/StudentScoreService.java

@@ -6,7 +6,6 @@ import java.util.Map;
 import com.baomidou.mybatisplus.extension.service.IService;
 
 import cn.com.qmth.am.bean.AnswerImageDto;
-import cn.com.qmth.am.bean.StudentInfo;
 import cn.com.qmth.am.bean.StudentScoreImageDto;
 import cn.com.qmth.am.entity.QuestionEntity;
 import cn.com.qmth.am.entity.StudentScoreEntity;
@@ -17,14 +16,10 @@ import cn.com.qmth.am.enums.DataStatus;
  */
 public interface StudentScoreService extends IService<StudentScoreEntity> {
 
-    void importScore();
-
     void updateAnswerErr(Long id, String string);
 
     void createSlice(StudentScoreEntity score, QuestionEntity q, Map<Integer, AnswerImageDto> answerImages);
 
-    // StudentScoreImageDto pollStudentScoreImage();
-
     void ocr(StudentScoreImageDto dto);
 
     void aiMarking(StudentScoreEntity score);
@@ -39,13 +34,10 @@ public interface StudentScoreService extends IService<StudentScoreEntity> {
 
     void removeBy(Long examId, String subjectCode);
 
-    List<StudentScoreEntity> findBy(Long examId, String subjectCode, Integer mainNumber, String subNumber,
-            Boolean exZero, Integer count, Integer score);
-
-    // List<StudentScoreEntity> findToAiMarking(Long studentId);
-
-    void addStudentScore(List<StudentInfo> students);
+    List<StudentScoreEntity> findBy(Long questionId, Boolean exZero, Integer count, Integer score);
 
     List<StudentScoreEntity> findAllToOcr();
 
+    void saveByQuestion(QuestionEntity q, List<StudentScoreEntity> scores);
+
 }

+ 2 - 10
src/main/java/cn/com/qmth/am/service/StudentService.java

@@ -1,10 +1,8 @@
 package cn.com.qmth.am.service;
 
-import java.io.InputStream;
 import java.util.Map;
 
 import cn.com.qmth.am.bean.AnswerImageDto;
-import cn.com.qmth.am.bean.ImportResult;
 import cn.com.qmth.am.entity.QuestionEntity;
 import cn.com.qmth.am.entity.StudentScoreEntity;
 
@@ -15,15 +13,9 @@ public interface StudentService {
 
     void importStudent();
 
-    ImportResult disposeFile(InputStream inputStream);
+    void buildImage(StudentScoreEntity score, QuestionEntity quetion);
 
-    void buildImage(StudentScoreEntity score, Map<Long, QuestionEntity> quetions);
-
-    // List<StudentScoreEntity> getOrCreateScores(StudentEntity student,
-    // Map<Long, QuestionEntity> quetions);
-
-    void createSlice(StudentScoreEntity score, Map<Long, QuestionEntity> quetions,
-            Map<Integer, AnswerImageDto> answerImages);
+    void createSlice(StudentScoreEntity score, QuestionEntity quetion, Map<Integer, AnswerImageDto> answerImages);
 
     void reset(Long examId, String subjectCode);
 

+ 63 - 1
src/main/java/cn/com/qmth/am/service/impl/QuestionServiceImpl.java

@@ -26,6 +26,8 @@ import org.springframework.transaction.annotation.Transactional;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.boot.core.exception.StatusException;
 import com.qmth.boot.tools.excel.ExcelReader;
@@ -38,7 +40,9 @@ import cn.com.qmth.am.bean.ds.StandardAnswer;
 import cn.com.qmth.am.config.SysProperty;
 import cn.com.qmth.am.dao.local.QuestionDao;
 import cn.com.qmth.am.entity.QuestionEntity;
+import cn.com.qmth.am.enums.DataStatus;
 import cn.com.qmth.am.enums.ImportFileName;
+import cn.com.qmth.am.enums.PromptTemplate;
 import cn.com.qmth.am.service.QuestionService;
 
 @Service
@@ -49,7 +53,7 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionDao, QuestionEntity
     private Pattern scoreRex = Pattern.compile("\\[\\[([0-9][0-9]*(.[0-9]+){0,1})分\\]\\]");
 
     private static final String[] EXCEL_HEADER = new String[] { "考试ID", "科目代码", "科目名称", "题目名称", "大题号", "小题号", "满分",
-            "试题内容", "试题答案", "作答坐标" };
+            "试题内容", "试题答案", "作答坐标", "模版文件" };
 
     @Autowired
     private SysProperty sysProperty;
@@ -179,6 +183,7 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionDao, QuestionEntity
             StringBuilder msg = new StringBuilder();
 
             QuestionEntity imp = new QuestionEntity();
+            imp.setStatus(DataStatus.WAITING);
             String examId = trimAndNullIfBlank(line.get(EXCEL_HEADER[0]));
             if (StringUtils.isBlank(examId)) {
                 msg.append("  考试ID不能为空");
@@ -285,6 +290,18 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionDao, QuestionEntity
                 }
             }
 
+            String template = trimAndNullIfBlank(line.get(EXCEL_HEADER[10]));
+            if (StringUtils.isBlank(imageSlice)) {
+                msg.append("  模版文件不能为空");
+            } else {
+                PromptTemplate val = PromptTemplate.getByCode(template);
+                if (val == null) {
+                    msg.append("  模版文件有误");
+                } else {
+                    imp.setPromptTemplate(val);
+                }
+            }
+
             if (msg.length() > 0) {
                 failRecords.add(errorMsg(i + 2, msg.toString()));
             } else {
@@ -444,6 +461,7 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionDao, QuestionEntity
                 up.setImageSlice(s.getImageSlice());
                 up.setContent(s.getContent());
                 up.setAnswer(s.getAnswer());
+                up.setPromptTemplate(s.getPromptTemplate());
                 updates.add(up);
             }
         }
@@ -466,6 +484,19 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionDao, QuestionEntity
         return this.list(wrapper);
     }
 
+    @Override
+    public List<QuestionEntity> findByExamIdAndSubject(Long examId, String subjectCode) {
+        QueryWrapper<QuestionEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<QuestionEntity> lw = wrapper.lambda();
+        lw.eq(QuestionEntity::getExamId, examId);
+        if (StringUtils.isNotBlank(subjectCode)) {
+            lw.eq(QuestionEntity::getSubjectCode, subjectCode);
+        }
+        lw.orderByAsc(QuestionEntity::getSubjectCode).orderByAsc(QuestionEntity::getMainNumber)
+                .orderByAsc(QuestionEntity::getSubNumber);
+        return this.list(wrapper);
+    }
+
     @Transactional
     @Override
     public void removeBy(Long examId, String subjectCode) {
@@ -478,4 +509,35 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionDao, QuestionEntity
         this.remove(wrapper);
     }
 
+    @Override
+    public List<QuestionEntity> findToDispose() {
+        QueryWrapper<QuestionEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<QuestionEntity> lw = wrapper.lambda();
+        lw.in(QuestionEntity::getStatus, DataStatus.WAITING, DataStatus.FAILED);
+        lw.orderByAsc(QuestionEntity::getExamId).orderByAsc(QuestionEntity::getSubjectCode)
+                .orderByAsc(QuestionEntity::getMainNumber).orderByAsc(QuestionEntity::getSubNumber);
+        return this.list(wrapper);
+    }
+
+    @Transactional
+    @Override
+    public void updateStatus(Long id, DataStatus st) {
+        UpdateWrapper<QuestionEntity> wrapper = new UpdateWrapper<>();
+        LambdaUpdateWrapper<QuestionEntity> lw = wrapper.lambda();
+        lw.set(QuestionEntity::getStatus, st);
+        lw.eq(QuestionEntity::getId, id);
+        this.update(wrapper);
+    }
+
+    @Transactional
+    @Override
+    public void resetStatus() {
+        UpdateWrapper<QuestionEntity> wrapper = new UpdateWrapper<>();
+        LambdaUpdateWrapper<QuestionEntity> lw = wrapper.lambda();
+        lw.set(QuestionEntity::getStatus, DataStatus.WAITING);
+        lw.eq(QuestionEntity::getStatus, DataStatus.PROCESSING);
+        this.update(wrapper);
+
+    }
+
 }

+ 27 - 0
src/main/java/cn/com/qmth/am/service/impl/StmmsServiceImpl.java

@@ -0,0 +1,27 @@
+package cn.com.qmth.am.service.impl;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+
+import cn.com.qmth.am.dao.stmms.StmmsDao;
+import cn.com.qmth.am.entity.StudentScoreEntity;
+import cn.com.qmth.am.service.StmmsService;
+
+@Service
+@DS("data-source-stmms")
+public class StmmsServiceImpl implements StmmsService {
+
+    @Autowired
+    private StmmsDao stmmsDao;
+
+    @Override
+    public List<StudentScoreEntity> getMarkStudent(Long examId, String subjectCode, Integer mainNumber,
+            String subNumber) {
+        return stmmsDao.getMarkStudent(examId, subjectCode, mainNumber, subNumber);
+    }
+
+}

+ 41 - 331
src/main/java/cn/com/qmth/am/service/impl/StudentScoreServiceImpl.java

@@ -1,22 +1,14 @@
 package cn.com.qmth.am.service.impl;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Comparator;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,18 +25,12 @@ import com.qmth.boot.core.exception.StatusException;
 import com.qmth.boot.core.retrofit.exception.RetrofitResponseError;
 import com.qmth.boot.core.solar.model.OrgInfo;
 import com.qmth.boot.core.solar.service.SolarService;
-import com.qmth.boot.tools.excel.ExcelReader;
-import com.qmth.boot.tools.excel.enums.ExcelType;
-import com.qmth.boot.tools.excel.model.DataMap;
 import com.qmth.boot.tools.models.ByteArray;
 
 import cn.com.qmth.am.bean.AiMarkingDto;
 import cn.com.qmth.am.bean.AnswerImageDto;
 import cn.com.qmth.am.bean.AutoScoreEnRequest;
 import cn.com.qmth.am.bean.ImageSlice;
-import cn.com.qmth.am.bean.ImportResult;
-import cn.com.qmth.am.bean.StudentInfo;
-import cn.com.qmth.am.bean.StudentScoreDto;
 import cn.com.qmth.am.bean.StudentScoreImageDto;
 import cn.com.qmth.am.bean.StudentScoreInfo;
 import cn.com.qmth.am.bean.ds.AutoScoreResult;
@@ -53,8 +39,6 @@ import cn.com.qmth.am.dao.local.StudentScoreDao;
 import cn.com.qmth.am.entity.QuestionEntity;
 import cn.com.qmth.am.entity.StudentScoreEntity;
 import cn.com.qmth.am.enums.DataStatus;
-import cn.com.qmth.am.enums.DataType;
-import cn.com.qmth.am.enums.ImportFileName;
 import cn.com.qmth.am.service.DsMarkingService;
 import cn.com.qmth.am.service.QuestionService;
 import cn.com.qmth.am.service.StudentScoreService;
@@ -68,10 +52,6 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
 
     private static final Logger log = LoggerFactory.getLogger(StudentScoreService.class);
 
-    // private static BlockingQueue<StudentScoreImageDto> queue;
-
-    private static final String[] EXCEL_HEADER = new String[] { "考试ID", "科目代码", "考生编号", "大题号", "小题号", "评分" };
-
     @Autowired
     private SysProperty sysProperty;
 
@@ -83,287 +63,29 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
 
     @Autowired
     private QuestionService questionService;
-    // static {
-    // int threadCount = Runtime.getRuntime().availableProcessors();
-    // queue = new ArrayBlockingQueue<>(threadCount * 2);
-    // }
-
-    @Override
-    public void importScore() {
-        File dir = new File(sysProperty.getDataDir());
-        File[] fs = dir.listFiles();
-        if (fs == null || fs.length == 0) {
-            return;
-        }
-        for (File file : fs) {
-            if (!file.isFile() || !file.getName().equals(ImportFileName.SCORE_IMPORT.getName())) {
-                continue;
-            }
-            InputStream inputStream = null;
-            ImportResult ret = null;
-            try {
-                inputStream = new FileInputStream(file);
-                ret = disposeFile(inputStream);
-            } catch (Exception e) {
-                String errMsg;
-                if (e instanceof FileNotFoundException) {
-                    errMsg = "未找到文件:" + file.getAbsolutePath();
-                } else {
-                    errMsg = "系统错误:" + e.getMessage();
-                    log.error("系统错误", e);
-                }
-                ret = new ImportResult(errMsg);
-            } finally {
-                if (inputStream != null) {
-                    try {
-                        inputStream.close();
-                    } catch (IOException e) {
-                    }
-                }
-            }
-            moveFile(dir, file, ret);
-        }
-    }
-
-    private void moveFile(File dir, File file, ImportResult ret) {
-        try {
-            boolean succss = CollectionUtils.isEmpty(ret.getErrMsg());
-            if (succss) {
-                File sucDir = new File(dir.getAbsoluteFile() + "/success/");
-                if (!sucDir.exists()) {
-                    sucDir.mkdir();
-                }
-                File targetFile = new File(sucDir.getAbsoluteFile() + "/" + file.getName());
-                if (targetFile.exists()) {
-                    targetFile.delete();
-                }
-                FileUtils.copyFile(file, targetFile);
-                file.delete();
-                String fname = file.getName().substring(0, file.getName().lastIndexOf("."));
-                File msgFile = new File(sucDir.getAbsoluteFile() + "/" + fname + "_info.txt");
-                if (msgFile.exists()) {
-                    msgFile.delete();
-                }
-                FileUtils.write(msgFile, ret.getCountInfo(), "utf-8");
-            } else {
-                File sucDir = new File(dir.getAbsoluteFile() + "/failed/");
-                if (!sucDir.exists()) {
-                    sucDir.mkdir();
-                }
-                File targetFile = new File(sucDir.getAbsoluteFile() + "/" + file.getName());
-                if (targetFile.exists()) {
-                    targetFile.delete();
-                }
-                FileUtils.copyFile(file, targetFile);
-                file.delete();
-                String fname = file.getName().substring(0, file.getName().lastIndexOf("."));
-                File msgFile = new File(sucDir.getAbsoluteFile() + "/" + fname + "_info.txt");
-                if (msgFile.exists()) {
-                    msgFile.delete();
-                }
-                FileUtils.writeLines(msgFile, StandardCharsets.UTF_8.name(), ret.getErrMsg());
-            }
-        } catch (IOException e) {
-            throw new StatusException("文件处理出错", e);
-        }
-
-    }
-
-    private String errorMsg(int lineNum, String msg) {
-        return "第" + lineNum + "行 " + msg;
-    }
-
-    private String trimAndNullIfBlank(String s) {
-        if (StringUtils.isBlank(s)) {
-            return null;
-        }
-        return s.trim();
-    }
-
-    @SuppressWarnings("deprecation")
-    private ImportResult disposeFile(InputStream inputStream) {
-        List<DataMap> lineList = null;
-        ExcelReader reader = ExcelReader.create(ExcelType.XLSX, inputStream, 0);
-        try {
-            lineList = reader.getDataMapList();
-        } catch (Exception e) {
-            throw new StatusException("Excel 解析失败");
-        }
-        if (!Arrays.equals(EXCEL_HEADER, reader.getColumnNames())) {
-            throw new StatusException("Excel表头错误");
-        }
-        if (CollectionUtils.isEmpty(lineList)) {
-            throw new StatusException("Excel无内容");
-        }
-        if (100001 < lineList.size()) {
-            throw new StatusException("数据行数不能超过100000");
-        }
-        List<StudentScoreDto> ss = new ArrayList<>();
-        ImportResult ret = new ImportResult();
-        List<String> failRecords = new ArrayList<>();
-        ret.setErrMsg(failRecords);
-        for (int i = 0; i < lineList.size(); i++) {
-            DataMap line = lineList.get(i);
-
-            StringBuilder msg = new StringBuilder();
-
-            StudentScoreDto imp = new StudentScoreDto();
-            String examId = trimAndNullIfBlank(line.get(EXCEL_HEADER[0]));
-            if (StringUtils.isBlank(examId)) {
-                msg.append("  考试ID不能为空");
-            } else if (examId.length() > 20) {
-                msg.append("  考试ID不能超过20个字符");
-            } else {
-                try {
-                    Long examIdVal = Long.parseLong(examId);
-                    imp.setExamId(examIdVal);
-                } catch (NumberFormatException e) {
-                    msg.append("  考试ID只能是数字");
-                }
-            }
-
-            String subjectCode = trimAndNullIfBlank(line.get(EXCEL_HEADER[1]));
-            if (StringUtils.isBlank(subjectCode)) {
-                msg.append("  科目代码不能为空");
-            } else if (subjectCode.length() > 100) {
-                msg.append("  科目代码不能超过100个字符");
-            }
-            imp.setSubjectCode(subjectCode);
-
-            String studentCode = trimAndNullIfBlank(line.get(EXCEL_HEADER[2]));
-            if (StringUtils.isBlank(studentCode)) {
-                msg.append("  考生编号不能为空");
-            } else if (studentCode.length() > 100) {
-                msg.append("  考生编号不能超过100个字符");
-            }
-            imp.setStudentCode(studentCode);
-
-            String mainNum = trimAndNullIfBlank(line.get(EXCEL_HEADER[3]));
-            if (StringUtils.isBlank(mainNum)) {
-                msg.append("  大题号不能为空");
-            } else if (mainNum.length() > 10) {
-                msg.append("  大题号不能超过10个字符");
-            } else {
-                try {
-                    Integer mainNumVal = Integer.parseInt(mainNum);
-                    if (mainNumVal <= 0) {
-                        msg.append("  大题号必须大于0");
-                    }
-                    imp.setMainNumber(mainNumVal);
-                } catch (NumberFormatException e) {
-                    msg.append("  大题号格式错误");
-                }
-            }
-
-            String subNum = trimAndNullIfBlank(line.get(EXCEL_HEADER[4]));
-            if (StringUtils.isBlank(subNum)) {
-                msg.append("  小题号不能为空");
-            } else if (subNum.length() > 10) {
-                msg.append("  小题号不能超过10个字符");
-            }
-            imp.setSubNumber(subNum);
-
-            String score = trimAndNullIfBlank(line.get(EXCEL_HEADER[5]));
-            if (StringUtils.isBlank(score)) {
-                msg.append("  评分不能为空");
-            } else if (score.length() > 10) {
-                msg.append("  评分不能超过10个字符");
-            } else {
-                try {
-                    Double scoreVal = Double.parseDouble(score);
-                    imp.setMarkingScore(scoreVal);
-                } catch (NumberFormatException e) {
-                    msg.append("  评分格式错误");
-                }
-            }
-
-            if (msg.length() > 0) {
-                failRecords.add(errorMsg(i + 2, msg.toString()));
-            } else {
-                ss.add(imp);
-            }
-
-        }
-
-        if (CollectionUtils.isNotEmpty(failRecords)) {
-            return ret;
-        }
-        try {
-            updateScoreBatch(ret, ss);
-        } catch (Exception e) {
-            failRecords.add("系统错误:" + e.getMessage());
-        }
-        return ret;
-    }
-
-    private void updateScoreBatch(ImportResult ret, List<StudentScoreDto> ss) {
-        if (CollectionUtils.isEmpty(ss)) {
-            ret.setCountInfo("更新数量:0");
-            return;
-        }
-        int count = 0;
-        for (StudentScoreDto s : ss) {
-            count = count + updateScore(s);
-        }
-        ret.setCountInfo("更新数量:" + count);
-    }
-
-    private int updateScore(StudentScoreDto dto) {
-        UpdateWrapper<StudentScoreEntity> wrapper = new UpdateWrapper<>();
-        LambdaUpdateWrapper<StudentScoreEntity> lw = wrapper.lambda();
-        lw.set(StudentScoreEntity::getMarkingScore, dto.getMarkingScore());
-        lw.eq(StudentScoreEntity::getExamId, dto.getExamId());
-        lw.eq(StudentScoreEntity::getSubjectCode, dto.getSubjectCode());
-        lw.eq(StudentScoreEntity::getStudentCode, dto.getStudentCode());
-        lw.eq(StudentScoreEntity::getMainNumber, dto.getMainNumber());
-        lw.eq(StudentScoreEntity::getSubNumber, dto.getSubNumber());
-        return this.update(wrapper) ? 1 : 0;
-    }
 
     @Transactional
     @Override
-    public void addStudentScore(List<StudentInfo> ss) {
-        List<QuestionEntity> qs = questionService.list();
-        if (CollectionUtils.isEmpty(qs)) {
+    public void saveByQuestion(QuestionEntity q, List<StudentScoreEntity> ss) {
+        if (q == null) {
             throw new StatusException("试题信息为空");
         }
-        Map<String, List<QuestionEntity>> qmap = new HashMap<>();
-        for (QuestionEntity q : qs) {
-            String key = q.getExamId() + "-" + q.getSubjectCode();
-            List<QuestionEntity> tem = qmap.get(key);
-            if (tem == null) {
-                tem = new ArrayList<>();
-                qmap.put(key, tem);
-            }
-            tem.add(q);
-        }
         Set<String> allStudent = getAllStudent();
 
-        BatchSetDataUtil<StudentInfo> bs = new BatchSetDataUtil<StudentInfo>() {
+        BatchSetDataUtil<StudentScoreEntity> bs = new BatchSetDataUtil<StudentScoreEntity>() {
 
             @Override
-            protected void setData(List<StudentInfo> dataList) {
+            protected void setData(List<StudentScoreEntity> dataList) {
                 List<StudentScoreEntity> adds = new ArrayList<>();
-                for (StudentInfo stu : dataList) {
-                    String key = stu.getExamId() + "-" + stu.getSubjectCode();
-                    if (qmap.get(key) == null) {
-                        throw new StatusException("试题信息为空:" + key);
-                    }
-                    for (QuestionEntity q : qmap.get(key)) {
-                        String scorekey = q.getId() + "-" + stu.getStudentCode();
-                        if (!allStudent.contains(scorekey)) {
-                            StudentScoreEntity s = new StudentScoreEntity();
-                            adds.add(s);
-                            allStudent.add(scorekey);
-                            s.setQuestionId(q.getId());
-                            s.setExamId(stu.getExamId());
-                            s.setAnswerStatus(DataStatus.WAITING);
-                            s.setMainNumber(q.getMainNumber());
-                            s.setScoreStatus(DataStatus.WAITING);
-                            s.setStudentCode(stu.getStudentCode());
-                            s.setSubjectCode(stu.getSubjectCode());
-                            s.setSubNumber(q.getSubNumber());
-                        }
+                for (StudentScoreEntity stu : dataList) {
+                    String scorekey = q.getId() + "-" + stu.getExamNumber();
+                    if (!allStudent.contains(scorekey)) {
+                        adds.add(stu);
+                        allStudent.add(scorekey);
+                        stu.setQuestionId(q.getId());
+                        stu.setAnswerStatus(DataStatus.WAITING);
+                        stu.setScoreStatus(DataStatus.WAITING);
+                        stu.setExamNumber(stu.getExamNumber());
                     }
                 }
                 if (CollectionUtils.isNotEmpty(adds)) {
@@ -382,7 +104,7 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
             return ret;
         }
         for (StudentScoreInfo s : list) {
-            ret.add(s.getQuestionId() + "-" + s.getStudentCode());
+            ret.add(s.getQuestionId() + "-" + s.getExamNUmber());
         }
         return ret;
     }
@@ -501,38 +223,18 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
     // }
 
     private String getImageUrl(StudentScoreEntity score, QuestionEntity q, Integer pageIndex) {
-        if (DataType.MARKING_CLOUD.equals(sysProperty.getDataType())) {
-            return getImageUrlFromMarkingCloud(score, pageIndex);
-        } else if (DataType.TEACH_CLOUD.equals(sysProperty.getDataType())) {
-            return getImageUrlFromTeachCloud(score, q, pageIndex);
-        } else {
-            throw new StatusException("数据类型错误");
-        }
+        return getImageUrlFromMarkingCloud(score, q, pageIndex);
     }
 
-    private String getImageUrlFromMarkingCloud(StudentScoreEntity score, Integer pageIndex) {
-        return sysProperty.getImageServer() + "/" + getMarkingCloudPath(score.getExamId(),
-                getSuffix(score.getStudentCode()), score.getStudentCode(), pageIndex, "jpg");
+    private String getImageUrlFromMarkingCloud(StudentScoreEntity score, QuestionEntity q, Integer pageIndex) {
+        return sysProperty.getImageServer() + "/" + getMarkingCloudPath(q.getExamId(), getSuffix(score.getExamNumber()),
+                score.getExamNumber(), pageIndex, "jpg");
     }
 
     private static String getSuffix(String input) {
         return StringUtils.trimToEmpty(input).substring(Math.max(0, input.length() - 3));
     }
 
-    private String getImageUrlFromTeachCloud(StudentScoreEntity score, QuestionEntity q, Integer pageIndex) {
-        int paperNum = (pageIndex + 1) / 2;
-        int page = 1;
-        if (pageIndex % 2 == 0) {
-            page = 2;
-        }
-        return sysProperty.getImageServer() + "/" + getTeachCloudPath(score.getExamId(), score.getSubjectCode(),
-                score.getStudentCode(), paperNum, page, "jpg");
-    }
-
-    private String getTeachCloudPath(Object... param) {
-        return String.format("sheet/%d/%s/%s/%d-%d.%s", param);
-    }
-
     private static String getMarkingCloudPath(Object... param) {
         return String.format("sheet/%d/%s/%s-%d.%s", param);
     }
@@ -781,47 +483,55 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
 
     @Override
     public int countBy(Long examId, DataStatus status) {
+        List<QuestionEntity> qs = questionService.findByExamIdAndSubject(examId, null);
+        if (CollectionUtils.isEmpty(qs)) {
+            return 0;
+        }
+        List<Long> qids = qs.stream().map(e -> e.getId()).collect(Collectors.toList());
         QueryWrapper<StudentScoreEntity> wrapper = new QueryWrapper<>();
         LambdaQueryWrapper<StudentScoreEntity> lw = wrapper.lambda();
         if (status != null) {
             lw.eq(StudentScoreEntity::getScoreStatus, status);
         }
-        lw.eq(StudentScoreEntity::getExamId, examId);
+        lw.in(StudentScoreEntity::getQuestionId, qids);
         return this.count(wrapper);
     }
 
     @Transactional
     @Override
     public void removeBy(Long examId, String subjectCode) {
+        List<QuestionEntity> qs = questionService.findByExamIdAndSubject(examId, subjectCode);
+        if (CollectionUtils.isEmpty(qs)) {
+            return;
+        }
+        List<Long> qids = qs.stream().map(e -> e.getId()).collect(Collectors.toList());
         QueryWrapper<StudentScoreEntity> wrapper = new QueryWrapper<>();
         LambdaQueryWrapper<StudentScoreEntity> lw = wrapper.lambda();
-        if (subjectCode != null) {
-            lw.eq(StudentScoreEntity::getSubjectCode, subjectCode);
-        }
-        lw.eq(StudentScoreEntity::getExamId, examId);
+        lw.in(StudentScoreEntity::getQuestionId, qids);
         this.remove(wrapper);
     }
 
     @Override
     public int countOcrBy(Long examId, DataStatus status) {
+        List<QuestionEntity> qs = questionService.findByExamIdAndSubject(examId, null);
+        if (CollectionUtils.isEmpty(qs)) {
+            return 0;
+        }
+        List<Long> qids = qs.stream().map(e -> e.getId()).collect(Collectors.toList());
         QueryWrapper<StudentScoreEntity> wrapper = new QueryWrapper<>();
         LambdaQueryWrapper<StudentScoreEntity> lw = wrapper.lambda();
         if (status != null) {
             lw.eq(StudentScoreEntity::getAnswerStatus, status);
         }
-        lw.eq(StudentScoreEntity::getExamId, examId);
+        lw.in(StudentScoreEntity::getQuestionId, qids);
         return this.count(wrapper);
     }
 
     @Override
-    public List<StudentScoreEntity> findBy(Long examId, String subjectCode, Integer mainNumber, String subNumber,
-            Boolean exZero, Integer count, Integer score) {
+    public List<StudentScoreEntity> findBy(Long questionId, Boolean exZero, Integer count, Integer score) {
         QueryWrapper<StudentScoreEntity> wrapper = new QueryWrapper<>();
         LambdaQueryWrapper<StudentScoreEntity> lw = wrapper.lambda();
-        lw.eq(StudentScoreEntity::getExamId, examId);
-        lw.eq(StudentScoreEntity::getSubjectCode, subjectCode);
-        lw.eq(StudentScoreEntity::getMainNumber, mainNumber);
-        lw.eq(StudentScoreEntity::getSubNumber, subNumber);
+        lw.eq(StudentScoreEntity::getQuestionId, questionId);
         lw.isNotNull(StudentScoreEntity::getAiScore);
         lw.isNotNull(StudentScoreEntity::getMarkingScore);
         lw.and(wq -> {
@@ -855,8 +565,8 @@ public class StudentScoreServiceImpl extends ServiceImpl<StudentScoreDao, Studen
 
                 @Override
                 public int compare(StudentScoreEntity o1, StudentScoreEntity o2) {
-                    String c1 = o1.getStudentCode();
-                    String c2 = o2.getStudentCode();
+                    String c1 = o1.getExamNumber();
+                    String c2 = o2.getExamNumber();
                     return c1.compareTo(c2);
                 }
             });

+ 17 - 217
src/main/java/cn/com/qmth/am/service/impl/StudentServiceImpl.java

@@ -1,22 +1,10 @@
 package cn.com.qmth.am.service.impl;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -24,19 +12,13 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import com.qmth.boot.core.exception.StatusException;
-import com.qmth.boot.tools.excel.ExcelReader;
-import com.qmth.boot.tools.excel.enums.ExcelType;
-import com.qmth.boot.tools.excel.model.DataMap;
 
 import cn.com.qmth.am.bean.AnswerImageDto;
-import cn.com.qmth.am.bean.ImportResult;
-import cn.com.qmth.am.bean.StudentInfo;
-import cn.com.qmth.am.config.SysProperty;
 import cn.com.qmth.am.entity.QuestionEntity;
 import cn.com.qmth.am.entity.StudentScoreEntity;
 import cn.com.qmth.am.enums.DataStatus;
-import cn.com.qmth.am.enums.ImportFileName;
 import cn.com.qmth.am.service.QuestionService;
+import cn.com.qmth.am.service.StmmsService;
 import cn.com.qmth.am.service.StudentScoreService;
 import cn.com.qmth.am.service.StudentService;
 
@@ -45,13 +27,11 @@ public class StudentServiceImpl implements StudentService {
 
     private static final Logger log = LoggerFactory.getLogger(StudentService.class);
 
-    private static final String[] EXCEL_HEADER = new String[] { "考试ID", "科目代码", "考生编号" };
-
     @Autowired
-    private SysProperty sysProperty;
+    private StudentService studentService;
 
     @Autowired
-    private StudentService studentService;
+    private StmmsService stmmsService;
 
     @Autowired
     private StudentScoreService studentScoreService;
@@ -61,217 +41,37 @@ public class StudentServiceImpl implements StudentService {
 
     @Override
     public void importStudent() {
-        File dir = new File(sysProperty.getDataDir());
-        File[] fs = dir.listFiles();
-        if (fs == null || fs.length == 0) {
+        List<QuestionEntity> qs = questionService.findToDispose();
+        if (CollectionUtils.isEmpty(qs)) {
             return;
         }
-        for (File file : fs) {
-            if (!file.isFile() || !file.getName().equals(ImportFileName.STUDENT_IMPORT.getName())) {
+        for (QuestionEntity q : qs) {
+            List<StudentScoreEntity> scores = stmmsService.getMarkStudent(q.getExamId(), q.getSubjectCode(),
+                    q.getMainNumber(), q.getSubNumber());
+            if (CollectionUtils.isEmpty(scores)) {
                 continue;
             }
-            InputStream inputStream = null;
-            ImportResult ret = null;
+            questionService.updateStatus(q.getId(), DataStatus.PROCESSING);
             try {
-                inputStream = new FileInputStream(file);
-                ret = studentService.disposeFile(inputStream);
+                studentScoreService.saveByQuestion(q, scores);
+                questionService.updateStatus(q.getId(), DataStatus.SUCCESS);
             } catch (Exception e) {
-                String errMsg;
-                if (e instanceof FileNotFoundException) {
-                    errMsg = "未找到文件:" + file.getAbsolutePath();
-                } else {
-                    errMsg = "错误:" + e.getMessage();
-                    log.error("系统错误", e);
-                }
-                ret = new ImportResult(errMsg);
-            } finally {
-                if (inputStream != null) {
-                    try {
-                        inputStream.close();
-                    } catch (IOException e) {
-                    }
-                }
-            }
-            moveFile(dir, file, ret);
-        }
-    }
-
-    private void moveFile(File dir, File file, ImportResult ret) {
-        try {
-            boolean succss = CollectionUtils.isEmpty(ret.getErrMsg());
-            if (succss) {
-                File sucDir = new File(dir.getAbsoluteFile() + "/success/");
-                if (!sucDir.exists()) {
-                    sucDir.mkdir();
-                }
-                File targetFile = new File(sucDir.getAbsoluteFile() + "/" + file.getName());
-                if (targetFile.exists()) {
-                    targetFile.delete();
-                }
-                FileUtils.copyFile(file, targetFile);
-                file.delete();
-                String fname = file.getName().substring(0, file.getName().lastIndexOf("."));
-                File msgFile = new File(sucDir.getAbsoluteFile() + "/" + fname + "_info.txt");
-                if (msgFile.exists()) {
-                    msgFile.delete();
-                }
-                FileUtils.write(msgFile, ret.getCountInfo(), "utf-8");
-            } else {
-                File sucDir = new File(dir.getAbsoluteFile() + "/failed/");
-                if (!sucDir.exists()) {
-                    sucDir.mkdir();
-                }
-                File targetFile = new File(sucDir.getAbsoluteFile() + "/" + file.getName());
-                if (targetFile.exists()) {
-                    targetFile.delete();
-                }
-                FileUtils.copyFile(file, targetFile);
-                file.delete();
-                String fname = file.getName().substring(0, file.getName().lastIndexOf("."));
-                File msgFile = new File(sucDir.getAbsoluteFile() + "/" + fname + "_info.txt");
-                if (msgFile.exists()) {
-                    msgFile.delete();
-                }
-                FileUtils.writeLines(msgFile, StandardCharsets.UTF_8.name(), ret.getErrMsg());
-            }
-        } catch (IOException e) {
-            throw new StatusException("文件处理出错", e);
-        }
-
-    }
-
-    private String errorMsg(int lineNum, String msg) {
-        return "第" + lineNum + "行 " + msg;
-    }
-
-    private String trimAndNullIfBlank(String s) {
-        if (StringUtils.isBlank(s)) {
-            return null;
-        }
-        return s.trim();
-    }
-
-    @SuppressWarnings("deprecation")
-    @Transactional
-    @Override
-    public ImportResult disposeFile(InputStream inputStream) {
-        List<DataMap> lineList = null;
-        ExcelReader reader = ExcelReader.create(ExcelType.XLSX, inputStream, 0);
-        try {
-            lineList = reader.getDataMapList();
-        } catch (Exception e) {
-            throw new StatusException("Excel 解析失败");
-        }
-        if (!Arrays.equals(EXCEL_HEADER, reader.getColumnNames())) {
-            throw new StatusException("Excel表头错误");
-        }
-        if (CollectionUtils.isEmpty(lineList)) {
-            throw new StatusException("Excel无内容");
-        }
-        if (100001 < lineList.size()) {
-            throw new StatusException("数据行数不能超过100000");
-        }
-        List<StudentInfo> ss = new ArrayList<>();
-        ImportResult ret = new ImportResult();
-        List<String> failRecords = new ArrayList<>();
-        ret.setErrMsg(failRecords);
-        for (int i = 0; i < lineList.size(); i++) {
-            DataMap line = lineList.get(i);
-
-            StringBuilder msg = new StringBuilder();
-
-            StudentInfo imp = new StudentInfo();
-            String examId = trimAndNullIfBlank(line.get(EXCEL_HEADER[0]));
-            if (StringUtils.isBlank(examId)) {
-                msg.append("  考试ID不能为空");
-            } else if (examId.length() > 20) {
-                msg.append("  考试ID不能超过20个字符");
-            } else {
-                try {
-                    Long examIdVal = Long.parseLong(examId);
-                    imp.setExamId(examIdVal);
-                } catch (NumberFormatException e) {
-                    msg.append("  考试ID只能是数字");
-                }
-            }
-
-            String subjectCode = trimAndNullIfBlank(line.get(EXCEL_HEADER[1]));
-            if (StringUtils.isBlank(subjectCode)) {
-                msg.append("  科目代码不能为空");
-            } else if (subjectCode.length() > 100) {
-                msg.append("  科目代码不能超过100个字符");
+                log.error("同步考生出错", e);
+                questionService.updateStatus(q.getId(), DataStatus.FAILED);
             }
-            imp.setSubjectCode(subjectCode);
-
-            String studentCode = trimAndNullIfBlank(line.get(EXCEL_HEADER[2]));
-            if (StringUtils.isBlank(studentCode)) {
-                msg.append("  考生编号不能为空");
-            } else if (studentCode.length() > 100) {
-                msg.append("  考生编号不能超过100个字符");
-            }
-            imp.setStudentCode(studentCode);
-
-            if (msg.length() > 0) {
-                failRecords.add(errorMsg(i + 2, msg.toString()));
-            } else {
-                ss.add(imp);
-            }
-
-        }
-
-        if (CollectionUtils.isNotEmpty(failRecords)) {
-            return ret;
-        }
-        try {
-            saveStudentBatch(ret, ss);
-        } catch (StatusException e) {
-            failRecords.add("错误:" + e.getMessage());
-        }
-        return ret;
-    }
-
-    private void saveStudentBatch(ImportResult ret, List<StudentInfo> ss) {
-        if (CollectionUtils.isEmpty(ss)) {
-            ret.setCountInfo("新增数量:0");
-            return;
-        }
-        // List<StudentEntity> all = this.list();
-        Set<String> set = new HashSet<>();
-        // if (CollectionUtils.isNotEmpty(all)) {
-        // for (StudentEntity s : all) {
-        // String key = s.getExamId() + "-" + s.getSubjectCode() + "-" +
-        // s.getStudentCode();
-        // set.add(key);
-        // }
-        // }
-        List<StudentInfo> adds = new ArrayList<>();
-        for (StudentInfo s : ss) {
-            String key = s.getExamId() + "-" + s.getSubjectCode() + "-" + s.getStudentCode();
-            if (!set.contains(key)) {
-                adds.add(s);
-            } else {
-                set.add(key);
-            }
-        }
-        if (CollectionUtils.isNotEmpty(adds)) {
-            // saveBatch(adds);
-            studentScoreService.addStudentScore(adds);
         }
-        // ret.setCountInfo("新增数量:" + adds.size());
     }
 
     @Override
-    public void buildImage(StudentScoreEntity score, Map<Long, QuestionEntity> quetions) {
+    public void buildImage(StudentScoreEntity score, QuestionEntity quetion) {
         Map<Integer, AnswerImageDto> answerImages = new HashMap<>();
         if (DataStatus.WAITING.equals(score.getAnswerStatus()) || DataStatus.FAILED.equals(score.getAnswerStatus())) {
-            studentService.createSlice(score, quetions, answerImages);
+            studentService.createSlice(score, quetion, answerImages);
         }
     }
 
     @Override
-    public void createSlice(StudentScoreEntity score, Map<Long, QuestionEntity> quetions,
-            Map<Integer, AnswerImageDto> answerImages) {
-        QuestionEntity q = quetions.get(score.getQuestionId());
+    public void createSlice(StudentScoreEntity score, QuestionEntity q, Map<Integer, AnswerImageDto> answerImages) {
         if (q == null) {
             studentScoreService.updateAnswerErr(score.getId(), "未找到试题信息");
             return;

+ 5 - 12
src/main/java/cn/com/qmth/am/task/OcrJob.java

@@ -90,27 +90,20 @@ public class OcrJob {
     }
 
     private void dispose(List<StudentScoreEntity> scores, List<QuestionEntity> qs) {
-        Map<String, Map<Long, QuestionEntity>> qmap = new HashMap<>();
+        Map<Long, QuestionEntity> qmap = new HashMap<>();
         for (QuestionEntity q : qs) {
-            String key = q.getExamId() + "-" + q.getSubjectCode();
-            Map<Long, QuestionEntity> tem = qmap.get(key);
-            if (tem == null) {
-                tem = new HashMap<>();
-                qmap.put(key, tem);
-            }
-            tem.put(q.getId(), q);
+            qmap.put(q.getId(), q);
         }
         CountDownLatch endGate = new CountDownLatch(scores.size());
         for (StudentScoreEntity score : scores) {
             if (!sysProperty.getOcrTaskEnable()) {
                 return;
             }
-            String key = score.getExamId() + "-" + score.getSubjectCode();
-            Map<Long, QuestionEntity> tem = qmap.get(key);
-            if (tem != null) {
+            QuestionEntity q = qmap.get(score.getQuestionId());
+            if (q != null) {
                 OcrConsumer com = SpringContextHolder.getBean(OcrConsumer.class);
                 com.setScore(score);
-                com.setQuetions(tem);
+                com.setQuetion(q);
                 com.setEndGate(endGate);
                 executor.execute(com);
             }

+ 0 - 36
src/main/java/cn/com/qmth/am/task/StudentScoreImportJob.java

@@ -1,36 +0,0 @@
-package cn.com.qmth.am.task;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Service;
-
-import com.qmth.boot.core.concurrent.service.ConcurrentService;
-
-import cn.com.qmth.am.enums.LockType;
-import cn.com.qmth.am.service.StudentScoreService;
-
-@Service
-public class StudentScoreImportJob {
-
-    @Autowired
-    private ConcurrentService concurrentService;
-
-    @Autowired
-    private StudentScoreService studentScoreService;
-
-    @Scheduled(fixedDelay = 5 * 1000, initialDelay = 5 * 1000)
-    public void doJob() {
-        boolean lock = concurrentService.getReadWriteLock(LockType.MARKING_SCORE_IMPORT.name()).writeLock().tryLock();
-        try {
-            if (!lock) {
-                return;
-            }
-            studentScoreService.importScore();
-        } finally {
-            if (lock) {
-                concurrentService.getReadWriteLock(LockType.MARKING_SCORE_IMPORT.name()).writeLock().unlock();
-            }
-        }
-    }
-
-}

+ 9 - 9
src/main/resources/application.properties

@@ -14,11 +14,11 @@ com.qmth.mybatis.block-attack=false
 
 
 spring.datasource.dynamic.datasource.data-source-local.druid.minIdle=10
-spring.datasource.dynamic.datasource.data-source-local.druid.maxActive=100
+spring.datasource.dynamic.datasource.data-source-local.druid.maxActive=50
 
 
-spring.datasource.dynamic.datasource.data-source-local.druid.minIdle=10
-spring.datasource.dynamic.datasource.data-source-local.druid.maxActive=100
+spring.datasource.dynamic.datasource.data-source-stmms.druid.minIdle=2
+spring.datasource.dynamic.datasource.data-source-stmms.druid.maxActive=10
 
 spring.datasource.dynamic.primary=data-source-local
 spring.datasource.dynamic.strict=false
@@ -39,22 +39,22 @@ spring.datasource.dynamic.datasource.data-source-local.url=jdbc:mysql://localhos
 spring.datasource.dynamic.datasource.data-source-local.username=root
 spring.datasource.dynamic.datasource.data-source-local.password=123456
 
-spring.datasource.dynamic.datasource.data-source-stmms.url=jdbc:mysql://localhost:3306/stmms_ft?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2b8&rewriteBatchedStatements=true
-spring.datasource.dynamic.datasource.data-source-stmms.username=root
-spring.datasource.dynamic.datasource.data-source-stmms.password=123456
+spring.datasource.dynamic.datasource.data-source-stmms.url=jdbc:mysql://ww:3306/stmms_ft?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2b8&rewriteBatchedStatements=true
+spring.datasource.dynamic.datasource.data-source-stmms.username=1
+spring.datasource.dynamic.datasource.data-source-stmms.password=1
 
 am.image-server=https://file.markingcloud.com
 am.data-dir=./data
 
 am.ocr-task.enable=false
 am.ocr-thread-count=4
-am.ocr-model=!!solar
+am.ocr-model=
 am.ocr-server=
 am.ocr-key=
 
-am.marking-task.enable=true
+am.marking-task.enable=false
 am.marking-thread-count=4
 am.marking-model=qwen2.5:32b-instruct
 am.marking-server=http://192.168.10.214:11434/api/chat
-am.marking-key=!
+am.marking-key=
 ##################################setting##########################################

+ 8 - 2
src/main/resources/mapper/StmmsMapper.xml

@@ -1,7 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="cn.com.qmth.am.dao.stmms.StmmsDao">
-	<select id="getName" resultType="string">
-		select t.name from b_user t where t.id=1
+	<select id="getMarkStudent"
+		resultType="cn.com.qmth.am.entity.StudentScoreEntity">
+		select s.exam_number,ss.score markingScore
+		from eb_subjective_score ss left join eb_exam_student s on
+		ss.student_id =s.id
+		where
+		ss.exam_id=#{examId} and s.subject_code =#{subjectCode}
+		and s.is_upload=1 and s.subjective_status!='UNMARK' and ss.main_number=#{mainNumber} and ss.sub_number=#{subNumber}
 	</select>
 </mapper>

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

@@ -2,6 +2,6 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="cn.com.qmth.am.dao.local.StudentScoreDao">
 	<select id="getAllList" resultType="cn.com.qmth.am.bean.StudentScoreInfo">
-		select t.question_id,t.student_code from am_student_score t
+		select t.question_id,t.exam_number from am_student_score t
 	</select>
 </mapper>