Эх сурвалжийг харах

增加数据同步云阅卷功能

xiaof 4 жил өмнө
parent
commit
5fbee074b5
26 өөрчлөгдсөн 374 нэмэгдсэн , 78 устгасан
  1. 65 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/SyncExamCardDto.java
  2. 40 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/SyncExamStudentDto.java
  3. 0 10
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/domain/SyncDataDomain.java
  4. 10 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamCard.java
  5. 3 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamCardMapper.java
  6. 3 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamDetailMapper.java
  7. 2 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamStudentMapper.java
  8. 2 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/DataSyncService.java
  9. 3 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamCardService.java
  10. 3 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamDetailService.java
  11. 2 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamPrintPlanService.java
  12. 2 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamStudentService.java
  13. 122 56
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/DataSyncServiceImpl.java
  14. 6 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamCardServiceImpl.java
  15. 5 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailServiceImpl.java
  16. 8 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPrintPlanServiceImpl.java
  17. 2 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamStudentServiceImpl.java
  18. 6 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/TBSyncTaskServiceImpl.java
  19. 1 1
      distributed-print-business/src/main/resources/db/init-data.sql
  20. 24 0
      distributed-print-business/src/main/resources/db/init-table.sql
  21. 24 0
      distributed-print-business/src/main/resources/mapper/ExamCardMapper.xml
  22. 13 0
      distributed-print-business/src/main/resources/mapper/ExamDetailMapper.xml
  23. 10 2
      distributed-print-business/src/main/resources/mapper/ExamStudentMapper.xml
  24. 8 1
      distributed-print-task/src/main/java/com/qmth/distributed/print/task/job/service/impl/JobServiceImpl.java
  25. 9 0
      distributed-print/src/main/java/com/qmth/distributed/print/api/ExamPrintPlanController.java
  26. 1 3
      distributed-print/src/main/resources/application.properties

+ 65 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/SyncExamCardDto.java

@@ -0,0 +1,65 @@
+package com.qmth.distributed.print.business.bean.dto;
+
+import com.qmth.distributed.print.business.entity.ExamCard;
+
+/**
+ * @Description: 题卡同步 DTO
+ */
+public class SyncExamCardDto extends ExamCard {
+
+    private String courseCode;
+
+    private String courseName;
+
+    private String paperNumber;
+
+    private String title;
+
+    private String content;
+
+    @Override
+    public String getCourseCode() {
+        return courseCode;
+    }
+
+    @Override
+    public void setCourseCode(String courseCode) {
+        this.courseCode = courseCode;
+    }
+
+    @Override
+    public String getCourseName() {
+        return courseName;
+    }
+
+    @Override
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
+
+    public String getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(String paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+
+    @Override
+    public String getTitle() {
+        return title;
+    }
+
+    @Override
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+}

+ 40 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/SyncExamStudentDto.java

@@ -0,0 +1,40 @@
+package com.qmth.distributed.print.business.bean.dto;
+
+import com.qmth.distributed.print.business.entity.ExamStudent;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Description: 考生同步 DTO
+ */
+public class SyncExamStudentDto extends ExamStudent {
+
+    private String courseCode;
+
+    private String courseName;
+
+    private String paperNumber;
+
+    public String getCourseCode() {
+        return courseCode;
+    }
+
+    public void setCourseCode(String courseCode) {
+        this.courseCode = courseCode;
+    }
+
+    public String getCourseName() {
+        return courseName;
+    }
+
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
+
+    public String getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(String paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+}

+ 0 - 10
distributed-print-business/src/main/java/com/qmth/distributed/print/business/domain/SyncDataDomain.java

@@ -5,8 +5,6 @@ package com.qmth.distributed.print.business.domain;
  */
 public class SyncDataDomain {
 
-    boolean sync;
-
     String hostUrl;
 
     String examSaveUrl;
@@ -15,14 +13,6 @@ public class SyncDataDomain {
 
     String cardUploadUrl;
 
-    public boolean isSync() {
-        return sync;
-    }
-
-    public void setSync(boolean sync) {
-        this.sync = sync;
-    }
-
     public String getHostUrl() {
         return hostUrl;
     }

+ 10 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamCard.java

@@ -58,6 +58,9 @@ public class ExamCard extends BaseEntity implements Serializable {
     @TableField("template_id")
     private Long templateId;
 
+    @TableField("sync_status")
+    private Boolean syncStatus;
+
     public Long getSchoolId() {
         return schoolId;
     }
@@ -122,4 +125,11 @@ public class ExamCard extends BaseEntity implements Serializable {
         this.templateId = templateId;
     }
 
+    public Boolean getSyncStatus() {
+        return syncStatus;
+    }
+
+    public void setSyncStatus(Boolean syncStatus) {
+        this.syncStatus = syncStatus;
+    }
 }

+ 3 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamCardMapper.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qmth.distributed.print.business.bean.dto.CardCustDto;
 import com.qmth.distributed.print.business.bean.dto.CardDetailDto;
+import com.qmth.distributed.print.business.bean.dto.SyncExamCardDto;
 import com.qmth.distributed.print.business.entity.ExamCard;
 import org.apache.ibatis.annotations.Param;
 
@@ -29,4 +30,6 @@ public interface ExamCardMapper extends BaseMapper<ExamCard> {
     List<ExamCard> listCustom(@Param("schoolId") Long schoolId, @Param("orgId") Long orgId, @Param("courseCode") String courseCode, @Param("type") String type);
 
     CardDetailDto getCardDetailBySelect(Long cardId);
+
+    List<SyncExamCardDto> listSyncCardByCourseCodeAndPaperNumber(@Param("schoolId") Long schoolId, @Param("courseCode") String courseCode, @Param("paperNumber") String paperNumber);
 }

+ 3 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamDetailMapper.java

@@ -7,6 +7,7 @@ import com.qmth.distributed.print.business.bean.dto.*;
 import com.qmth.distributed.print.business.bean.result.ExaminationDetailResult;
 import com.qmth.distributed.print.business.bean.result.ExaminationResult;
 import com.qmth.distributed.print.business.entity.ExamDetail;
+import com.qmth.distributed.print.business.entity.ExamDetailCourse;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
@@ -55,4 +56,6 @@ public interface ExamDetailMapper extends BaseMapper<ExamDetail> {
     List<Map> listStudentByExamDetailId(@Param("schoolId") Long schoolId, @Param("examDetailId") Long examDetailId, @Param("ticketNumber") String ticketNumber, @Param("type") String type);
 
     Integer selectPaperCount(@Param("schoolId") Long schoolId, @Param("printPlanId") Long printPlanId, @Param("status") String status, @Param("courseCode") String courseCode, @Param("paperNumber") String paperNumber, @Param("examPlace") String examPlace, @Param("examRoom") String examRoom, @Param("examStartTime") Long examStartTime, @Param("examEndTime") Long examEndTime, @Param("orgIds") Set<Long> orgIds);
+
+    List<ExamDetailCourse> listSyncPaperNumberByPrintPlanId(Long printPlanId);
 }

+ 2 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamStudentMapper.java

@@ -2,6 +2,7 @@ package com.qmth.distributed.print.business.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.qmth.distributed.print.business.bean.dto.ExamStudentCourseDto;
+import com.qmth.distributed.print.business.bean.dto.SyncExamStudentDto;
 import com.qmth.distributed.print.business.entity.ExamStudent;
 import org.apache.ibatis.annotations.Param;
 
@@ -29,5 +30,5 @@ public interface ExamStudentMapper extends BaseMapper<ExamStudent> {
      */
     List<ExamStudentCourseDto> queryBySchoolIdAndExamDetailCourseIds(@Param("schoolId") Long schoolId, @Param("examDetailCourseIds") List<Long> examDetailCourseIds);
 
-    List<ExamStudent> listStudentByPrintPlanIdAndSyncStatus(Long printPlanId);
+    List<SyncExamStudentDto> listStudentByPrintPlanIdAndSyncStatus(Long printPlanId);
 }

+ 2 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/DataSyncService.java

@@ -6,4 +6,6 @@ package com.qmth.distributed.print.business.service;
  */
 public interface DataSyncService {
     void syncToCloudReview();
+
+    void syncDataCloud(Long printPlanId);
 }

+ 3 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamCardService.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.distributed.print.business.bean.dto.CardCustDto;
 import com.qmth.distributed.print.business.bean.dto.CardDetailDto;
+import com.qmth.distributed.print.business.bean.dto.SyncExamCardDto;
 import com.qmth.distributed.print.business.bean.params.ArraysParams;
 import com.qmth.distributed.print.business.bean.params.ExamCardParams;
 import com.qmth.distributed.print.business.entity.ExamCard;
@@ -36,4 +37,6 @@ public interface ExamCardService extends IService<ExamCard> {
     List<ExamCard> listSelectCard(String courseCode, Long cardRuleId, String paperType);
 
     void downloadFiles(HttpServletResponse response, ArraysParams arraysParams);
+
+    List<SyncExamCardDto> listSyncCardByCourseCodeAndPaperNumber(Long schoolId, String courseCode, String paperNumber);
 }

+ 3 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamDetailService.java

@@ -8,6 +8,7 @@ import com.qmth.distributed.print.business.bean.result.ExaminationDetailResult;
 import com.qmth.distributed.print.business.bean.result.ExaminationResult;
 import com.qmth.distributed.print.business.bean.result.SummarizedDataResult;
 import com.qmth.distributed.print.business.entity.ExamDetail;
+import com.qmth.distributed.print.business.entity.ExamDetailCourse;
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
@@ -182,4 +183,6 @@ public interface ExamDetailService extends IService<ExamDetail> {
     List<ExamDetail> listByCourseCodeAndPaperNumberAndPaperTypeIsNull(Long schoolId, String courseCode, String paperNumber);
 
     List<ExamDetail> listByCourseCodeAndPaperNumber(Long schoolId, String courseCode, String paperNumber);
+
+    List<ExamDetailCourse> listSyncPaperNumberByPrintPlanId(Long printPlanId);
 }

+ 2 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamPrintPlanService.java

@@ -87,4 +87,6 @@ public interface ExamPrintPlanService extends IService<ExamPrintPlan> {
     IPage<ClientPrintStatisticsDto> listClientPrintStatistics(Page<ClientPrintStatisticsDto> page, Long schoolId, String printPlanId, String examPlace, Long examStartTime, Long examEndTime, String courseCode, String paperNumber, Set<Long> orgIds);
 
     ClientPrintStatisticsTotalDto clientStatisticsTotalData(String printPlanId, String examPlace, Long examStartTime, Long examEndTime, String courseCode, String paperNumber);
+
+    void syncDataCloud(Long printPlanId);
 }

+ 2 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamStudentService.java

@@ -2,6 +2,7 @@ package com.qmth.distributed.print.business.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.distributed.print.business.bean.dto.ExamStudentCourseDto;
+import com.qmth.distributed.print.business.bean.dto.SyncExamStudentDto;
 import com.qmth.distributed.print.business.entity.ExamDetailCourse;
 import com.qmth.distributed.print.business.entity.ExamStudent;
 
@@ -33,5 +34,5 @@ public interface ExamStudentService extends IService<ExamStudent> {
      */
     List<ExamStudentCourseDto> queryBySchoolIdAndExamDetailCourseIds(Long schoolId, List<Long> examDetailCourseIds);
 
-    List<ExamStudent> listStudentByPrintPlanIdAndSyncStatus(Long printPlanId);
+    List<SyncExamStudentDto> listStudentByPrintPlanIdAndSyncStatus(Long printPlanId);
 }

+ 122 - 56
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/DataSyncServiceImpl.java

@@ -5,11 +5,10 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.qmth.boot.tools.signature.SignatureType;
+import com.qmth.distributed.print.business.bean.dto.SyncExamCardDto;
+import com.qmth.distributed.print.business.bean.dto.SyncExamStudentDto;
 import com.qmth.distributed.print.business.config.DictionaryConfig;
-import com.qmth.distributed.print.business.entity.BasicSchool;
-import com.qmth.distributed.print.business.entity.ExamPrintPlan;
-import com.qmth.distributed.print.business.entity.ExamStudent;
-import com.qmth.distributed.print.business.entity.TBSyncTask;
+import com.qmth.distributed.print.business.entity.*;
 import com.qmth.distributed.print.business.enums.PrintPlanStatusEnum;
 import com.qmth.distributed.print.business.enums.TaskResultEnum;
 import com.qmth.distributed.print.business.enums.TaskStatusEnum;
@@ -18,12 +17,14 @@ import com.qmth.distributed.print.business.util.HttpKit;
 import com.qmth.distributed.print.common.SignatureEntityTest;
 import com.qmth.distributed.print.common.contant.SystemConstant;
 import com.qmth.distributed.print.common.enums.ExceptionResultEnum;
+import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
+import java.io.*;
 import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -49,12 +50,21 @@ public class DataSyncServiceImpl implements DataSyncService {
     @Autowired
     private ExamStudentService examStudentService;
 
+    @Autowired
+    private ExamDetailService examDetailService;
+
+    @Autowired
+    private ExamCardService examCardService;
+
     private ExecutorService executors = Executors.newFixedThreadPool(5);
 
     private static final String SAVE_EXAM_TYPE = "MULTI_MEDIA";
     private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
     private static final String POST_METHOD = "POST";
 
+    /**
+     * 定时任务批量同步
+     */
     @Override
     public void syncToCloudReview() {
         // 查询可同步计划(同步状态为空:未同步,false:同步失败)
@@ -69,6 +79,22 @@ public class DataSyncServiceImpl implements DataSyncService {
         }
     }
 
+    /**
+     * 单个同步
+     * @param printPlanId
+     */
+    @Override
+    public void syncDataCloud(Long printPlanId) {
+        ExamPrintPlan examPrintPlan = examPrintPlanService.getById(printPlanId);
+        if(examPrintPlan == null){
+            throw ExceptionResultEnum.ERROR.exception("印刷计划数据异常");
+        }
+        if(Objects.nonNull(examPrintPlan.getSyncStatus()) && examPrintPlan.getSyncStatus()){
+            throw ExceptionResultEnum.ERROR.exception("印刷计划数据同步成功");
+        }
+        executors.execute(syncData(examPrintPlan));
+    }
+
     private TimerTask syncData(ExamPrintPlan examPrintPlan) {
         return new TimerTask() {
             @Override
@@ -89,18 +115,30 @@ public class DataSyncServiceImpl implements DataSyncService {
         try {
             // 校验同步url
             validatUrl();
+            UpdateWrapper<TBSyncTask> tbSyncTaskUpdateWrapper = new UpdateWrapper<>();
+            tbSyncTaskUpdateWrapper.lambda().set(TBSyncTask::getStatus, TaskStatusEnum.RUNNING).eq(TBSyncTask::getId, syncTask.getId());
+            tbSyncTaskService.update(tbSyncTaskUpdateWrapper);
+
             // 同步计划 -> 对应云阅卷考试
-            Long thirdRelateId = saveExam(examPrintPlan);
+            ExamPrintPlan printPlan = examSave(examPrintPlan);
             // 考试同步成功,才能同步考生和题卡
-            if (Objects.nonNull(thirdRelateId)) {
-
+            if (Objects.nonNull(printPlan.getThirdRelateId())) {
+                studentSave(printPlan);
+                cardUpload(printPlan);
             }
 
+            // 更新计划状态
+            UpdateWrapper<ExamPrintPlan> updateWrapper = new UpdateWrapper<>();
+            updateWrapper.lambda().set(ExamPrintPlan::getSyncStatus, true).eq(ExamPrintPlan::getId, examPrintPlan.getId());
+            examPrintPlanService.update(updateWrapper);
+
+            // 更新日志表
+            syncTask.setResult(TaskResultEnum.SUCCESS);
         } catch (Exception e) {
-            syncTask.setStatus(TaskStatusEnum.FINISH);
             syncTask.setResult(TaskResultEnum.ERROR);
             syncTask.setErrorMessage(e.getMessage());
         } finally {
+            syncTask.setStatus(TaskStatusEnum.FINISH);
             tbSyncTaskService.saveOrUpdate(syncTask);
         }
 
@@ -126,7 +164,7 @@ public class DataSyncServiceImpl implements DataSyncService {
      * @param examPrintPlan
      * @return
      */
-    public Long saveExam(ExamPrintPlan examPrintPlan) {
+    public ExamPrintPlan examSave(ExamPrintPlan examPrintPlan) {
         String hostUrl = dictionaryConfig.syncDataDomain().getHostUrl();
         String examSaveUrl = dictionaryConfig.syncDataDomain().getExamSaveUrl();
         String postUrl = hostUrl.concat(examSaveUrl);
@@ -143,9 +181,9 @@ public class DataSyncServiceImpl implements DataSyncService {
             if (jsonObject.containsKey("id")) {
                 Long id = Long.valueOf(jsonObject.get("id").toString());
                 UpdateWrapper<ExamPrintPlan> updateWrapper = new UpdateWrapper<>();
-                updateWrapper.lambda().set(ExamPrintPlan::getThirdRelateId, id).set(ExamPrintPlan::getSyncStatus, true);
+                updateWrapper.lambda().set(ExamPrintPlan::getThirdRelateId, id).eq(ExamPrintPlan::getId, examPrintPlan.getId());
                 examPrintPlanService.update(updateWrapper);
-                return id;
+                return examPrintPlanService.getById(examPrintPlan.getId());
             }
         } catch (Exception e) {
             throw ExceptionResultEnum.ERROR.exception(e.getMessage());
@@ -159,14 +197,13 @@ public class DataSyncServiceImpl implements DataSyncService {
      *
      * @return
      */
-    public void saveStudent(ExamPrintPlan examPrintPlan) {
+    public void studentSave(ExamPrintPlan examPrintPlan) {
         String hostUrl = dictionaryConfig.syncDataDomain().getHostUrl();
         String studentSaveUrl = dictionaryConfig.syncDataDomain().getStudentSaveUrl();
         String postUrl = hostUrl.concat(studentSaveUrl);
 
-        List<ExamStudent> examStudents = examStudentService.listStudentByPrintPlanIdAndSyncStatus(examPrintPlan.getId());
-        for (ExamStudent examStudent : examStudents) {
-            Map<String, Object> resultMap = new HashMap<>();
+        List<SyncExamStudentDto> examStudents = examStudentService.listStudentByPrintPlanIdAndSyncStatus(examPrintPlan.getId());
+        for (SyncExamStudentDto examStudent : examStudents) {
             try {
                 //参数
                 Map<String, String> map = new HashMap<>();
@@ -175,10 +212,10 @@ public class DataSyncServiceImpl implements DataSyncService {
                 map.put("studentCode", examStudent.getStudentCode());
                 map.put("name", examStudent.getStudentName());
                 map.put("college", "无");
-//                map.put("className", examStudent.get());
+                map.put("className", getClassName(examStudent.getExtendFields()));
                 map.put("teacher", "无");
-//                map.put("subjectCode", examStudent.get());
-//                map.put("subjectName", tcPExamStudent.getCourseName());
+                map.put("subjectCode", examStudent.getPaperNumber()); // 取试卷编号
+                map.put("subjectName", examStudent.getCourseName());
 
                 String result = HttpKit.sendPost(postUrl, getHeaders(examPrintPlan.getSchoolId(), studentSaveUrl), map, null, null, null);
                 JSONObject jsonObject = JSONObject.parseObject(result);
@@ -198,69 +235,61 @@ public class DataSyncServiceImpl implements DataSyncService {
      *
      * @return
      */
-    /*public void saveCard(ExamPrintPlan examPrintPlan) {
+    public void cardUpload(ExamPrintPlan examPrintPlan) {
         String hostUrl = dictionaryConfig.syncDataDomain().getHostUrl();
-        String studentSaveUrl = dictionaryConfig.syncDataDomain().getStudentSaveUrl();
-        String postUrl = hostUrl.concat(studentSaveUrl);
-        List<TcPCard> cards = tcPCardMapper.selectListNotSyncSuccess(tcPExam.getId());
-        cards.forEach(tcPCard -> {
-            //题卡卡内容
-            QueryWrapper<TcPCardDetail> tcPCardDetailQueryWrapper = new QueryWrapper<>();
-            tcPCardDetailQueryWrapper.lambda().eq(TcPCardDetail::getCardId, tcPCard.getId());
-            TcPCardDetail tcPCardDetail = tcPCardDetailMapper.selectOne(tcPCardDetailQueryWrapper);
-
-            Map<String, Object> resultMap = new HashMap<>();
-            if (StringUtils.isNotEmpty(tcPCardDetail.getContent())) {
+        String cardUploadUrl = dictionaryConfig.syncDataDomain().getCardUploadUrl();
+        String postUrl = hostUrl.concat(cardUploadUrl);
+        List<ExamDetailCourse> examDetailCourses = examDetailService.listSyncPaperNumberByPrintPlanId(examPrintPlan.getId());
+        if (CollectionUtils.isEmpty(examDetailCourses)) {
+            return;
+        }
+        for (ExamDetailCourse examDetailCours : examDetailCourses) {
+            List<SyncExamCardDto> syncExamCardDtos = examCardService.listSyncCardByCourseCodeAndPaperNumber(examDetailCours.getSchoolId(), examDetailCours.getCourseCode(), examDetailCours.getPaperNumber());
+            if (CollectionUtils.isEmpty(syncExamCardDtos) || syncExamCardDtos.size() != 1) {
+                throw ExceptionResultEnum.ERROR.exception(String.format("数据异常,通过学校:%s,课程代码:%s,试卷编号:%s查出多个题卡数据", examDetailCours.getSchoolId(), examDetailCours.getCourseCode(), examDetailCours.getPaperNumber()));
+            }
+
+            SyncExamCardDto syncExamCardDto = syncExamCardDtos.get(0);
+            if (StringUtils.isNotEmpty(syncExamCardDto.getContent())) {
                 //生成json文件
                 File file = null;
                 try {
-                    String filePath = makeDirs();
-                    file = FileHelper.createJsonFile(filePath);
-                    createFile(file, tcPCardDetail.getContent());
+                    String filePath = SystemConstant.TEMP_FILES_DIR + File.separator + "card-upload" + File.separator + System.currentTimeMillis();
+                    file = createJsonFile(filePath, syncExamCardDto.getContent());
                     Map<String, String> files = new HashMap<>();
                     if (file.exists()) {
-                        files.put(tcPCard.getTitle(), file.getPath());
+                        files.put(syncExamCardDto.getTitle(), file.getPath());
                     }
 
-                    log.info("同步题卡:考试id:{},题卡id:{},开始同步", tcPExam.getId(), tcPCard.getId());
                     //表单数据
                     Map<String, String> formText = new HashMap<>();
-                    formText.put("examId", String.valueOf(tcPExam.getExternalId()));
-                    formText.put("subjectCode", tcPCard.getCourseCode());
+                    formText.put("examId", String.valueOf(examPrintPlan.getThirdRelateId()));
+                    formText.put("subjectCode", syncExamCardDto.getPaperNumber());
                     formText.put("format", "json");
                     formText.put("md5", DigestUtils.md5Hex(new FileInputStream(file)));
 
 
-                    log.info("同步题卡:考试id:{},题卡id:{},请求url:{}, 表单参数:{},表头参数:{},发送请求", tcPExam.getId(), tcPCard.getId(), url, JSONObject.toJSONString(formText), JSONObject.toJSONString(getHeaders(cardUrl)));
-                    String result = HttpKit.sendPost(url, getHeaders(cardUrl), formText, files, null, null);
+                    String result = HttpKit.sendPost(postUrl, getHeaders(examDetailCours.getSchoolId(), cardUploadUrl), formText, files, null, null);
                     JSONObject jsonObject = JSONObject.parseObject(result);
                     if (jsonObject.containsKey("success")) {
-                        log.info("同步题卡:考试id:{},题卡id:{},请求成功,返回数据:{}", tcPExam.getId(), tcPCard.getId(), result);
-                        resultMap.put("success", true);
-                        resultMap.put("msg", jsonObject.get("success"));
+                        String success = jsonObject.get("success").toString();
+                        if (Boolean.valueOf(success)) {
+                            UpdateWrapper<ExamCard> updateWrapper = new UpdateWrapper<>();
+                            updateWrapper.lambda().set(ExamCard::getSyncStatus, true).eq(ExamCard::getId, syncExamCardDto.getId());
+                            examCardService.update(updateWrapper);
+                        }
                     }
                 } catch (Exception e) {
-                    resultMap.put("success", false);
-                    resultMap.put("msg", e.getMessage());
+                    throw ExceptionResultEnum.ERROR.exception(e.getMessage());
                 } finally {
                     if (file != null && file.exists()) {
                         file.delete();
                     }
                 }
-            } else {
-                resultMap.put("success", false);
-                resultMap.put("msg", "题卡内容为空");
             }
-            Boolean success = Boolean.valueOf(resultMap.get("success").toString());
-            String msg = resultMap.get("msg").toString();
-            log.info("同步题卡:考试id:{},题卡id:{},请求状态:{},返回数据:{}", tcPExam.getId(), tcPCard.getId(), success, msg);
 
-            String relaName = tcPCard.getCourseName().concat("(").concat(tcPCard.getCourseCode()).concat(")");
-            TcPExamSyncRecord tcPExamSyncRecord = new TcPExamSyncRecord(tcPExam.getId(), "card", tcPCard.getId(), relaName, success, msg);
-            saveSyncRecord(tcPExamSyncRecord, "card", cards.size());
-            log.info("同步题卡:考试id:{},题卡id:{},保存同步记录成功,保存参数:{}", tcPExam.getId(), tcPCard.getId(), JSONObject.toJSONString(tcPExamSyncRecord));
-        });
-    }*/
+        }
+    }
 
     /**
      * http请求头
@@ -296,4 +325,41 @@ public class DataSyncServiceImpl implements DataSyncService {
         String signature = SignatureEntityTest.build(SignatureType.SECRET, POST_METHOD, url, time, basicSchool.getAccessKey(), basicSchool.getAccessSecret());
         return signature;
     }
+
+    private String getClassName(String extendCloumn) {
+        List<Map> mapList = JSONObject.parseArray(extendCloumn, Map.class);
+        for (Map map : mapList) {
+            if (Objects.equals("className", map.get("code").toString())) {
+                return map.get("value").toString();
+            }
+        }
+        return "无";
+    }
+
+    /*
+     * 生成文件
+     * @param file 文件路径+文件名称
+     * @param conent 要生成的文件内容
+     */
+    public static File createJsonFile(String url, String conent) {
+
+        File file = new File(url);
+        if (!file.exists()) {
+            file.mkdirs();
+        }
+        BufferedWriter out = null;
+        file = new File(file, UUID.randomUUID().toString() + ".json");
+        try {
+            file.createNewFile();
+            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));
+            out.write(conent);
+        } catch (Exception e) {
+        } finally {
+            try {
+                out.close();
+            } catch (IOException e) {
+            }
+        }
+        return file;
+    }
 }

+ 6 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamCardServiceImpl.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.distributed.print.business.bean.dto.CardCustDto;
 import com.qmth.distributed.print.business.bean.dto.CardDetailDto;
+import com.qmth.distributed.print.business.bean.dto.SyncExamCardDto;
 import com.qmth.distributed.print.business.bean.params.ArraysParams;
 import com.qmth.distributed.print.business.bean.params.ExamCardParams;
 import com.qmth.distributed.print.business.entity.*;
@@ -246,6 +247,11 @@ public class ExamCardServiceImpl extends ServiceImpl<ExamCardMapper, ExamCard> i
         commonService.downloadFileAndZip(response, rootPath, time);
     }
 
+    @Override
+    public List<SyncExamCardDto> listSyncCardByCourseCodeAndPaperNumber(Long schoolId, String courseCode, String paperNumber) {
+        return this.baseMapper.listSyncCardByCourseCodeAndPaperNumber(schoolId, courseCode, paperNumber);
+    }
+
 
     /**
      * 数据验证

+ 5 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailServiceImpl.java

@@ -748,6 +748,11 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
         return null;
     }
 
+    @Override
+    public List<ExamDetailCourse> listSyncPaperNumberByPrintPlanId(Long printPlanId) {
+        return this.baseMapper.listSyncPaperNumberByPrintPlanId(printPlanId);
+    }
+
     @Transactional(rollbackFor = Exception.class)
     @Override
     public void deleteExaminationData(Long printPlanId) {

+ 8 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPrintPlanServiceImpl.java

@@ -72,6 +72,9 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
     @Autowired
     private ClientPrintDataService clientPrintDataService;
 
+    @Autowired
+    private DataSyncService dataSyncService;
+
     @Transactional(rollbackFor = Exception.class)
     @Override
     public IPage<PrintPlanResult> printPlanPage(Long schoolId, Long printPlanId, PrintPlanStatusEnum status, Long startTime, Long endTime, int pageNumber, int pageSize) {
@@ -389,6 +392,11 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
         return clientPrintStatisticsTotalDto;
     }
 
+    @Override
+    public void syncDataCloud(Long printPlanId) {
+        dataSyncService.syncDataCloud(printPlanId);
+    }
+
 
     /**
      * 查找子机构

+ 2 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamStudentServiceImpl.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.distributed.print.business.bean.dto.ExamStudentCourseDto;
+import com.qmth.distributed.print.business.bean.dto.SyncExamStudentDto;
 import com.qmth.distributed.print.business.entity.ExamDetailCourse;
 import com.qmth.distributed.print.business.entity.ExamStudent;
 import com.qmth.distributed.print.business.mapper.ExamStudentMapper;
@@ -75,7 +76,7 @@ public class ExamStudentServiceImpl extends ServiceImpl<ExamStudentMapper, ExamS
     }
 
     @Override
-    public List<ExamStudent> listStudentByPrintPlanIdAndSyncStatus(Long printPlanId) {
+    public List<SyncExamStudentDto> listStudentByPrintPlanIdAndSyncStatus(Long printPlanId) {
         return this.baseMapper.listStudentByPrintPlanIdAndSyncStatus(printPlanId);
     }
 }

+ 6 - 2
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/TBSyncTaskServiceImpl.java

@@ -8,6 +8,7 @@ import com.qmth.distributed.print.business.enums.TaskStatusEnum;
 import com.qmth.distributed.print.business.mapper.TBSyncTaskMapper;
 import com.qmth.distributed.print.business.service.TBSyncTaskService;
 import com.qmth.distributed.print.common.contant.SystemConstant;
+import com.qmth.distributed.print.common.enums.ExceptionResultEnum;
 import org.springframework.stereotype.Service;
 
 /**
@@ -19,9 +20,12 @@ public class TBSyncTaskServiceImpl extends ServiceImpl<TBSyncTaskMapper, TBSyncT
     public TBSyncTask saveTask(ExamPrintPlan examPrintPlan) {
         QueryWrapper<TBSyncTask> queryWrapper = new QueryWrapper<>();
         queryWrapper.lambda().eq(TBSyncTask::getSchoolId, examPrintPlan.getSchoolId())
-                .eq(TBSyncTask::getPrintPlanId, examPrintPlan.getId());
+                .eq(TBSyncTask::getPrintPlanId, examPrintPlan.getId())
+                .ne(TBSyncTask::getStatus, TaskStatusEnum.FINISH);
         TBSyncTask tbSyncTask = this.getOne(queryWrapper);
-        if (tbSyncTask == null) {
+        if (tbSyncTask != null) {
+            throw ExceptionResultEnum.ERROR.exception("计划下有数据正在同步");
+        } else {
             tbSyncTask = new TBSyncTask();
             tbSyncTask.setId(SystemConstant.getDbUuid());
             tbSyncTask.setSchoolId(examPrintPlan.getSchoolId());

+ 1 - 1
distributed-print-business/src/main/resources/db/init-data.sql

@@ -5,4 +5,4 @@ INSERT INTO `sys_config` VALUES (2, 'sys.warning.days', '预警天数', '3',NULL
 INSERT INTO `sys_config` VALUES (3, 'sys.code.enable', '是否启用短信验证码', 'true', 'true-启用,false-禁用', 1, NULL, NULL, NULL);
 INSERT INTO `sys_config` VALUES (4, 'sys.message.enable', '是否启用短信消息提示', 'true', 'true-启用,false-禁用', 1, NULL, NULL, NULL);
 INSERT INTO `sys_config` VALUES (5, 'sys.message.resendCount', '失败短信重试次数', '3', NULL, 1, NULL, NULL, NULL);
-
+INSERT INTO `sys_config` VALUES (6, 'sys.sync.enable', '是否开启数据同步云阅卷', 'true', 'true-启用,false-禁用', 1, NULL, NULL, NULL);

+ 24 - 0
distributed-print-business/src/main/resources/db/init-table.sql

@@ -274,6 +274,7 @@ CREATE TABLE `exam_card`  (
   `update_time` bigint(20) NULL DEFAULT NULL,
   `type` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '题卡类型:GENERIC-通卡,CUSTOM-自定义',
   `template_id` bigint(20) NULL DEFAULT NULL COMMENT 'type=GENERIC时必传',
+  `sync_status` tinyint(1) NULL COMMENT '是否同步成功',
   PRIMARY KEY (`id`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '题卡' ROW_FORMAT = Dynamic;
 
@@ -371,6 +372,8 @@ CREATE TABLE `exam_print_plan`  (
   `create_time` bigint(20) NULL DEFAULT NULL,
   `update_id` bigint(20) NULL DEFAULT NULL,
   `update_time` bigint(20) NULL DEFAULT NULL,
+  `third_relate_id` bigint(20) NULL COMMENT '第三方系统关联ID(目前只有云阅卷)',
+  `sync_status` tinyint(1) NULL COMMENT '是否同步成功',
   PRIMARY KEY (`id`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '印刷计划管理' ROW_FORMAT = Dynamic;
 
@@ -395,6 +398,7 @@ CREATE TABLE `exam_student`  (
   `update_id` bigint(20) NULL DEFAULT NULL,
   `update_time` bigint(20) NULL DEFAULT NULL,
   `attachment_id` bigint(20) NULL DEFAULT NULL COMMENT '附件id',
+  `sync_status` tinyint(1) NULL COMMENT '是否同步成功',
   PRIMARY KEY (`id`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '考生' ROW_FORMAT = Dynamic;
 
@@ -1603,6 +1607,26 @@ CREATE TABLE `t_b_task`  (
   PRIMARY KEY (`id`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '导入导出任务表' ROW_FORMAT = Dynamic;
 
+-- ----------------------------
+-- Table structure for t_b_sync_task
+-- ----------------------------
+DROP TABLE IF EXISTS `t_b_sync_task`;
+CREATE TABLE `t_b_sync_task`  (
+  `id` bigint(20) NOT NULL COMMENT '主键',
+  `school_id` bigint(20) NULL DEFAULT NULL COMMENT '学校id',
+  `print_plan_id` bigint(20) NULL DEFAULT NULL COMMENT '印刷计划id',
+  `print_plan_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+  `status` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务状态,INIT:未开始,RUNNING:进行中,FINISH:已完成',
+  `summary` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '实时摘要信息',
+  `result` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '数据结果,SUCCESS:成功,ERROR:失败',
+  `create_id` bigint(20) NULL DEFAULT NULL COMMENT '创建人id',
+  `create_time` bigint(20) NULL DEFAULT NULL COMMENT '创建时间',
+  `remark` mediumtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '备注',
+  `reset_count` int(11) NULL DEFAULT 0 COMMENT '重试次数',
+  `error_message` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '人工错误原因',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '导入导出任务表' ROW_FORMAT = Dynamic;
+
 -- ----------------------------
 -- Table structure for t_g_error
 -- ----------------------------

+ 24 - 0
distributed-print-business/src/main/resources/mapper/ExamCardMapper.xml

@@ -150,4 +150,28 @@
             exam_card_detail b ON a.id = b.card_id
         where a.id = #{cardId}
     </select>
+    <select id="listSyncCardByCourseCodeAndPaperNumber"
+            resultType="com.qmth.distributed.print.business.bean.dto.SyncExamCardDto">
+        SELECT
+            c.id,
+            a.school_id schoolId,
+            a.course_code courseCode,
+            a.paper_number paperNumber,
+            c.title,
+            d.content
+        FROM
+            exam_task a
+                LEFT JOIN
+            exam_task_detail b ON a.id = b.exam_task_id
+                LEFT JOIN
+            exam_card c ON b.card_id = c.id
+                LEFT JOIN
+            exam_card_detail d ON c.id = d.card_id
+        WHERE
+            a.school_id = #{schoolId}
+                AND a.course_code = #{courseCode}
+                AND a.paper_number = #{paperNumber}
+                AND c.status = 'SUBMIT'
+                AND c.make_method != 'SELECT'
+    </select>
 </mapper>

+ 13 - 0
distributed-print-business/src/main/resources/mapper/ExamDetailMapper.xml

@@ -396,5 +396,18 @@
             </if>
         </where>
     </select>
+    <select id="listSyncPaperNumberByPrintPlanId"
+            resultType="com.qmth.distributed.print.business.entity.ExamDetailCourse">
+        SELECT DISTINCT
+            b.school_id schoolId,
+            b.course_code courseCode,
+            b.paper_number paperNumber
+        FROM
+            exam_detail a
+                LEFT JOIN
+            exam_detail_course b ON a.id = b.exam_detail_id
+        WHERE
+            a.print_plan_id = #{printPlanId}
+    </select>
 
 </mapper>

+ 10 - 2
distributed-print-business/src/main/resources/mapper/ExamStudentMapper.xml

@@ -86,9 +86,17 @@
             order by edc.course_code
     </select>
     <select id="listStudentByPrintPlanIdAndSyncStatus"
-            resultType="com.qmth.distributed.print.business.entity.ExamStudent">
+            resultType="com.qmth.distributed.print.business.bean.dto.SyncExamStudentDto">
         SELECT
-            *
+            a.id,
+            b.course_code courseCode,
+            b.course_name courseName,
+            b.paper_number paperNumber,
+            a.student_name studentName,
+            a.student_code studentCode,
+            a.ticket_number ticketNumber,
+            a.extend_fields extendFields,
+            a.paper_type paperType
         FROM
             exam_student a
                 LEFT JOIN

+ 8 - 1
distributed-print-task/src/main/java/com/qmth/distributed/print/task/job/service/impl/JobServiceImpl.java

@@ -3,6 +3,7 @@ package com.qmth.distributed.print.task.job.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.qmth.distributed.print.business.entity.ExamDetail;
 import com.qmth.distributed.print.business.entity.ExamPrintPlan;
+import com.qmth.distributed.print.business.entity.SysConfig;
 import com.qmth.distributed.print.business.enums.PrintPlanStatusEnum;
 import com.qmth.distributed.print.business.service.*;
 import com.qmth.distributed.print.task.job.service.JobService;
@@ -49,6 +50,9 @@ public class JobServiceImpl implements JobService {
     @Autowired
     DataSyncService dataSyncService;
 
+    @Autowired
+    private SysConfigService sysConfigService;
+
     @Override
     public void updateSchoolInfo() throws IOException {
         orgCenterDataDisposeService.updateSchoolInfo();
@@ -79,7 +83,10 @@ public class JobServiceImpl implements JobService {
         examPrintPlanService.saveOrUpdateBatch(examPrintPlanList);
 
         // 2021-05-20 同步数据到云阅卷
-        dataSyncService.syncToCloudReview();
+        SysConfig sysConfig = sysConfigService.getByKey("sys.code.enable");
+        if(Objects.nonNull(sysConfig) && sysConfig.getConfigValue() == "true") {
+            dataSyncService.syncToCloudReview();
+        }
     }
 
     /**

+ 9 - 0
distributed-print/src/main/java/com/qmth/distributed/print/api/ExamPrintPlanController.java

@@ -315,5 +315,14 @@ public class ExamPrintPlanController {
         TBTask tbTask = Objects.nonNull(map.get(SystemConstant.TASK)) ? (TBTask) map.get(SystemConstant.TASK) : null;
         return Objects.nonNull(tbTask) ? ResultUtil.ok(new EditResult(tbTask.getId())) : ResultUtil.error("创建任务失败");
     }
+
+    @ApiOperation(value = "同步失败-手动同步")
+    @RequestMapping(value = "/sync_data_cloud", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = EditResult.class)})
+    @Aac(auth = BOOL.FALSE)
+    public Result syncDataCloud(@RequestParam(value = "printPlanId") Long printPlanId) throws Exception {
+        examPrintPlanService.syncDataCloud(printPlanId);
+        return ResultUtil.ok(true);
+    }
 }
 

+ 1 - 3
distributed-print/src/main/resources/application.properties

@@ -96,9 +96,7 @@ com.qmth.logging.file-path=/Users/king/Downloads/distributed-print.log
 spring.profiles.include=task
 
 #云阅卷相关url
-#是否同步
-sync.config.sync=false
-sync.config.hostUrl=https://www.markingcloud.com
+sync.config.hostUrl=http://localhost:8080/
 #同步考试
 sync.config.examSaveUrl=/api/exam/save
 #同步考生