Explorar el Código

1.1.0 update-20250214优化考务数据同步

xiaofei hace 4 meses
padre
commit
61803396e6

+ 24 - 0
src/main/java/com/qmth/eds/bean/dto/SyncLog.java

@@ -0,0 +1,24 @@
+package com.qmth.eds.bean.dto;
+
+public class SyncLog {
+
+    private String syncDate;
+
+    private String logDetail;
+
+    public String getSyncDate() {
+        return syncDate;
+    }
+
+    public void setSyncDate(String syncDate) {
+        this.syncDate = syncDate;
+    }
+
+    public String getLogDetail() {
+        return logDetail;
+    }
+
+    public void setLogDetail(String logDetail) {
+        this.logDetail = logDetail;
+    }
+}

+ 10 - 0
src/main/java/com/qmth/eds/common/entity/ExamSyncStudent.java

@@ -4,6 +4,7 @@ import com.alibaba.excel.annotation.ExcelIgnore;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.contant.SystemConstant;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
@@ -93,6 +94,15 @@ public class ExamSyncStudent implements Serializable {
     @TableField(exist = false)
     private String cloudMarkingCourseCode;
 
+    public ExamSyncStudent() {
+    }
+
+    public ExamSyncStudent(Long id, Long schoolId, Long examSyncTotalId) {
+        this.id = id;
+        this.schoolId = schoolId;
+        this.examSyncTotalId = examSyncTotalId;
+    }
+
     public Long getId() {
         return id;
     }

+ 34 - 34
src/main/java/com/qmth/eds/common/entity/ExamSyncStudentTemp.java

@@ -15,17 +15,17 @@ public class ExamSyncStudentTemp implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    @ApiModelProperty(value = "id")
-    @JsonSerialize(using = ToStringSerializer.class)
-    private Long id;
-
-    @ApiModelProperty(value = "学校id")
-    @JsonSerialize(using = ToStringSerializer.class)
-    private Long schoolId;
-
-    @ApiModelProperty(value = "汇总表ID")
-    @JsonSerialize(using = ToStringSerializer.class)
-    private Long examSyncTotalId;
+//    @ApiModelProperty(value = "id")
+//    @JsonSerialize(using = ToStringSerializer.class)
+//    private Long id;
+//
+//    @ApiModelProperty(value = "学校id")
+//    @JsonSerialize(using = ToStringSerializer.class)
+//    private Long schoolId;
+//
+//    @ApiModelProperty(value = "汇总表ID")
+//    @JsonSerialize(using = ToStringSerializer.class)
+//    private Long examSyncTotalId;
 
     @ApiModelProperty(value = "学年")
     private String xnm;
@@ -84,29 +84,29 @@ public class ExamSyncStudentTemp implements Serializable {
     @ApiModelProperty(value = "考试备注")
     private String ksbz;
 
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public Long getSchoolId() {
-        return schoolId;
-    }
-
-    public void setSchoolId(Long schoolId) {
-        this.schoolId = schoolId;
-    }
-
-    public Long getExamSyncTotalId() {
-        return examSyncTotalId;
-    }
-
-    public void setExamSyncTotalId(Long examSyncTotalId) {
-        this.examSyncTotalId = examSyncTotalId;
-    }
+//    public Long getId() {
+//        return id;
+//    }
+//
+//    public void setId(Long id) {
+//        this.id = id;
+//    }
+//
+//    public Long getSchoolId() {
+//        return schoolId;
+//    }
+//
+//    public void setSchoolId(Long schoolId) {
+//        this.schoolId = schoolId;
+//    }
+//
+//    public Long getExamSyncTotalId() {
+//        return examSyncTotalId;
+//    }
+//
+//    public void setExamSyncTotalId(Long examSyncTotalId) {
+//        this.examSyncTotalId = examSyncTotalId;
+//    }
 
     public String getXnm() {
         return xnm;

+ 25 - 0
src/main/java/com/qmth/eds/common/entity/ExamSyncTotal.java

@@ -2,6 +2,7 @@ package com.qmth.eds.common.entity;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.eds.common.contant.SystemConstant;
 import com.qmth.eds.core.base.BaseEntity;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -65,9 +66,24 @@ public class ExamSyncTotal extends BaseEntity implements Serializable {
     @ApiModelProperty(value = "是否使用文件")
     private Boolean useFile;
 
+    @ApiModelProperty(value = "同步日志")
+    private String syncLog;
+
     public ExamSyncTotal() {
     }
 
+    public ExamSyncTotal(Long schoolId, String schoolName, Long semesterId, String semesterName, Long examTypeId, String examTypeName) {
+        this.setId(SystemConstant.getDbUuid());
+        this.schoolId = schoolId;
+        this.schoolName = schoolName;
+        this.semesterId = semesterId;
+        this.semesterName = semesterName;
+        this.examTypeId = examTypeId;
+        this.examTypeName = examTypeName;
+        this.downloadStatus = true;
+        this.useFile = true;
+    }
+
     public ExamSyncTotal(Long syncDate, Long schoolId, String schoolName, Long semesterId, String semesterName, Long examTypeId, String examTypeName, Integer colleges, Integer subjects, Integer students, String dataMd5) {
         this.syncDate = syncDate;
         this.schoolId = schoolId;
@@ -203,4 +219,13 @@ public class ExamSyncTotal extends BaseEntity implements Serializable {
     public void setUseFile(Boolean useFile) {
         this.useFile = useFile;
     }
+
+    public String getSyncLog() {
+        return syncLog;
+    }
+
+    public void setSyncLog(String syncLog) {
+        this.syncLog = syncLog;
+    }
 }
+

+ 5 - 5
src/main/java/com/qmth/eds/service/impl/CdutDataSyncServiceImpl.java

@@ -99,11 +99,11 @@ public class CdutDataSyncServiceImpl implements CdutDataSyncService {
             // 调用接口
             List<ExamSyncStudentTemp> examSyncStudentTemps = cdutUtils.getKwData(schoolId, token);
 
-            examSyncStudentTemps.forEach(m -> {
-                m.setId(SystemConstant.getDbUuid());
-                m.setSchoolId(schoolId);
-                m.setExamSyncTotalId(examSyncTotalId);
-            });
+//            examSyncStudentTemps.forEach(m -> {
+//                m.setId(SystemConstant.getDbUuid());
+//                m.setSchoolId(schoolId);
+//                m.setExamSyncTotalId(examSyncTotalId);
+//            });
             // 保存临时考务数据
             examSyncStudentTempService.saveBatch(examSyncStudentTemps);
 

+ 3 - 3
src/main/java/com/qmth/eds/service/impl/ExamSyncStudentServiceTempImpl.java

@@ -11,8 +11,8 @@ import org.springframework.stereotype.Service;
 public class ExamSyncStudentServiceTempImpl extends ServiceImpl<ExamSyncStudentTempMapper, ExamSyncStudentTemp> implements ExamSyncStudentTempService {
     @Override
     public void deleteByExamSyncTotalId(Long examSyncTotalId) {
-        UpdateWrapper<ExamSyncStudentTemp> updateWrapper = new UpdateWrapper<>();
-        updateWrapper.lambda().eq(ExamSyncStudentTemp::getExamSyncTotalId, examSyncTotalId);
-        this.remove(updateWrapper);
+//        UpdateWrapper<ExamSyncStudentTemp> updateWrapper = new UpdateWrapper<>();
+//        updateWrapper.lambda().eq(ExamSyncStudentTemp::getExamSyncTotalId, examSyncTotalId);
+//        this.remove(updateWrapper);
     }
 }

+ 143 - 101
src/main/java/com/qmth/eds/service/impl/WhuDataSyncServiceImpl.java

@@ -1,16 +1,17 @@
 package com.qmth.eds.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.DateUtil;
 import com.alibaba.excel.EasyExcel;
 import com.alibaba.excel.ExcelWriter;
 import com.alibaba.excel.write.metadata.WriteSheet;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.googlecode.aviator.AviatorEvaluator;
 import com.qmth.boot.api.exception.ApiException;
 import com.qmth.eds.bean.dto.ExamSyncStudentDto;
+import com.qmth.eds.bean.dto.SyncLog;
 import com.qmth.eds.bean.dto.coefficient.Coefficient;
 import com.qmth.eds.bean.dto.coefficient.Detail;
 import com.qmth.eds.common.contant.SystemConstant;
@@ -35,10 +36,8 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.ZoneId;
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -64,16 +63,10 @@ public class WhuDataSyncServiceImpl implements WhuDataSyncService {
     private ExamCourseMappingService examCourseMappingService;
     @Resource
     private ExamSyncStudentService examSyncStudentService;
-
-    @Resource
-    private ExamSyncStudentTempService examSyncStudentTempService;
-
     @Resource
     private ExamSyncTotalService examSyncTotalService;
-
     @Resource
     private BasicMessageService basicMessageService;
-
     @Resource
     private ExamAssignService examAssignService;
     @Resource
@@ -93,10 +86,14 @@ public class WhuDataSyncServiceImpl implements WhuDataSyncService {
         String semesterName = examScheduleTask.getSemesterName();
         Long examTypeId = examScheduleTask.getExamTypeId();
         String examTypeName = examScheduleTask.getExamTypeName();
-        File txtFile = null;
-        FileInputStream fis = null;
-        // 汇总表ID
-        Long examSyncTotalId = SystemConstant.getDbUuid();
+
+
+        ExamSyncTotal examSyncTotal = examSyncTotalService.getBySemesterIdAndExamTypeIdAndUseFile(schoolId, semesterId, examTypeId, true);
+        if (examSyncTotal == null) {
+            examSyncTotal = new ExamSyncTotal(schoolId, schoolName, semesterId, semesterName, examTypeId, examTypeName);
+        }
+
+        List<SyncLog> syncLogList = StringUtils.isNotBlank(examSyncTotal.getSyncLog()) ? JSON.parseArray(examSyncTotal.getSyncLog(), SyncLog.class) : new ArrayList<>();
         try {
             // 同步中
             tbSyncTaskService.updateStatusAndResultById(tbSyncTask.getId(), TaskStatusEnum.RUNNING, null, null);
@@ -105,90 +102,134 @@ public class WhuDataSyncServiceImpl implements WhuDataSyncService {
             if (StringUtils.isBlank(token)) {
                 throw ExceptionResultEnum.ERROR.exception("获取AccessToken失败");
             }
-            // 调用接口
+            // 调用接口获取数据
             List<ExamSyncStudentTemp> examSyncStudentTemps = whuUtils.getKwData(schoolId, token);
 
-            examSyncStudentTemps.forEach(m -> {
-                m.setId(SystemConstant.getDbUuid());
-                m.setSchoolId(schoolId);
-                m.setExamSyncTotalId(examSyncTotalId);
-            });
-            // 保存临时考务数据
-            examSyncStudentTempService.saveBatch(examSyncStudentTemps);
-
-            // 生成数据文件,用来比较内容是否有变动
-            txtFile = createTxt(schoolId, examSyncStudentTemps);
             String txtFileMd5 = null;
 
-            if (txtFile != null) {
-                fis = new FileInputStream(txtFile);
-                txtFileMd5 = DigestUtils.md5Hex(fis);
+            long syncDate = System.currentTimeMillis();
+
+            SyncLog syncLog = new SyncLog();
+            syncLog.setSyncDate(DateUtil.formatDateTime(new Date(syncDate)));
+
+            if(StringUtils.isBlank(examSyncTotal.getDataMd5())){
+                txtFileMd5 = md5DataText(schoolId, examSyncStudentTemps);
             }
-            // 校验数据是否变动,若变动,需要新增
-            if (canAddTotal(schoolId, semesterId, examTypeId, examSyncStudentTemps.size(), txtFileMd5)) {
-                // 保存到正式表
-                List<ExamSyncStudent> examSyncStudents = examSyncStudentTemps.stream().map(m -> {
-                    ExamSyncStudent examSyncStudent = new ExamSyncStudent();
-                    BeanUtil.copyProperties(m, examSyncStudent);
-                    examSyncStudent.setId(SystemConstant.getDbUuid());
-                    return examSyncStudent;
-                }).collect(Collectors.toList());
-                examSyncStudentService.saveBatch(examSyncStudents);
-
-                // 将以前数据设置为不可下载
-                examSyncTotalService.updateDownloadStatusBySchoolIdAndSemesterIdAndExamTypeId(schoolId, semesterId, examTypeId);
 
-                // 生成汇总数据
-                long syncDate;
-                if (isAuto) {
-                    ZoneId zone = ZoneId.systemDefault();
-                    Instant instant = LocalDate.now().atStartOfDay().atZone(zone).toInstant();
-                    Date date = Date.from(instant);
-                    syncDate = date.getTime();
+            // 校验数据是否变动,若变动,需要新增
+            if (StringUtils.isBlank(examSyncTotal.getDataMd5()) || examSyncStudentTemps.size() != examSyncTotal.getStudents() || !examSyncTotal.getDataMd5().equals(txtFileMd5 = md5DataText(schoolId, examSyncStudentTemps))) {
+                List<ExamSyncStudent> examSyncStudentList = examSyncStudentService.listByExamSyncTotalId(examSyncTotal);
+
+                Long examSyncTotalId = examSyncTotal.getId();
+                List<ExamSyncStudent> examSyncStudents = new ArrayList<>();
+                if (CollectionUtils.isEmpty(examSyncStudentList)) {
+                    // 保存到正式表
+                    examSyncStudents = examSyncStudentTemps.stream().map(m -> {
+                        ExamSyncStudent examSyncStudent = new ExamSyncStudent(SystemConstant.getDbUuid(), schoolId, examSyncTotalId);
+                        BeanUtil.copyProperties(m, examSyncStudent);
+                        return examSyncStudent;
+                    }).collect(Collectors.toList());
+                    examSyncStudentService.saveBatch(examSyncStudents);
+                    syncLog.setLogDetail("首次新增:" + examSyncStudents.size());
                 } else {
-                    syncDate = System.currentTimeMillis();
+                    List<ExamSyncStudent> examSyncStudentAddList = new ArrayList<>();
+                    List<ExamSyncStudent> examSyncStudentUpdateList = new ArrayList<>();
+                    Map<String, ExamSyncStudent> examSyncStudentMap = examSyncStudentList.stream().collect(Collectors.toMap(m -> spliceParam(m.getXnm(), m.getXqm(), m.getKch(), m.getXh()), Function.identity()));
+                    for (ExamSyncStudentTemp s : examSyncStudentTemps) {
+                        String key = spliceParam(s.getXnm(), s.getXqm(), s.getKch(), s.getXh());
+                        if (examSyncStudentMap.containsKey(key)) {
+                            ExamSyncStudent syncStudent = examSyncStudentMap.get(key);
+                            if (!compareStudent(syncStudent, s)) {
+                                examSyncStudentUpdateList.add(updateExamStudent(syncStudent, s));
+                            }
+                        } else {
+                            ExamSyncStudent examSyncStudent = new ExamSyncStudent(SystemConstant.getDbUuid(), schoolId, examSyncTotalId);
+                            BeanUtil.copyProperties(s, examSyncStudent);
+                            examSyncStudentAddList.add(examSyncStudent);
+                        }
+                    }
+                    // 新增
+                    if (CollectionUtils.isNotEmpty(examSyncStudentAddList)) {
+                        examSyncStudentService.saveBatch(examSyncStudentAddList);
+                    }
+                    // 修改
+                    if (CollectionUtils.isNotEmpty(examSyncStudentUpdateList)) {
+                        examSyncStudentService.saveOrUpdateBatch(examSyncStudentUpdateList);
+                    }
+
+                    examSyncStudents = examSyncStudentService.listByExamSyncTotalId(examSyncTotal);
+                    syncLog.setLogDetail("新增:" + examSyncStudentAddList.size() + ",更新:" + examSyncStudentUpdateList.size());
                 }
-                int colleges = Integer.parseInt(String.valueOf(examSyncStudentTemps.stream().map(ExamSyncStudentTemp::getJgmc).filter(StringUtils::isNotBlank).distinct().count()));
-                int subjects = Integer.parseInt(String.valueOf(examSyncStudentTemps.stream().map(ExamSyncStudentTemp::getKch).filter(StringUtils::isNotBlank).distinct().count()));
-                int students = examSyncStudentTemps.size();
-                ExamSyncTotal examSyncTotal = new ExamSyncTotal(syncDate, schoolId, schoolName, semesterId, semesterName, examTypeId, examTypeName, colleges, subjects, students, txtFileMd5);
-                examSyncTotal.setId(examSyncTotalId);
-                examSyncTotalService.save(examSyncTotal);
+
+                // 生成汇总数据
+                examSyncTotal.setSyncDate(syncDate);
+                int colleges = Integer.parseInt(String.valueOf(examSyncStudents.stream().map(ExamSyncStudent::getJgmc).filter(StringUtils::isNotBlank).distinct().count()));
+                examSyncTotal.setColleges(colleges);
+                int subjects = Integer.parseInt(String.valueOf(examSyncStudents.stream().map(ExamSyncStudent::getKch).filter(StringUtils::isNotBlank).distinct().count()));
+                examSyncTotal.setSubjects(subjects);
+                int students = examSyncStudents.size();
+                examSyncTotal.setStudents(students);
+
+                examSyncTotal.setDataMd5(txtFileMd5);
                 // 生成excel文件
                 File excelFile = createExcel(examSyncTotal, examSyncStudents);
 
                 // 更新文件路径
                 examSyncTotal.setFileName(excelFile.getName());
                 examSyncTotal.setFilePath(excelFile.getPath());
-                examSyncTotalService.updateById(examSyncTotal);
+                syncLogList.add(syncLog);
+                examSyncTotal.setSyncLog(JSON.toJSONString(syncLogList));
+                examSyncTotalService.saveOrUpdate(examSyncTotal);
 
                 // 下载过学校+学期+考试类型  文件的实施人员发送短信
                 basicMessageService.sendTeachDataChangeNotice(schoolId, semesterId, examTypeId);
+            } else {
+                syncLog.setLogDetail("数据无变动");
+                syncLogList.add(syncLog);
+                examSyncTotal.setSyncLog(JSON.toJSONString(syncLogList));
+                examSyncTotalService.updateById(examSyncTotal);
             }
             result = TaskResultEnum.SUCCESS;
         } catch (ApiException | IOException e) {
             result = TaskResultEnum.ERROR;
             errorMessage = errorMessage + e.getMessage();
         } finally {
-            // 删除临时表数据
-            examSyncStudentTempService.deleteByExamSyncTotalId(examSyncTotalId);
             // 更新任务状态
             tbSyncTaskService.updateStatusAndResultById(tbSyncTask.getId(), TaskStatusEnum.FINISH, result, errorMessage);
+        }
+    }
 
-            // 关闭fis流
-            if (fis != null) {
-                try {
-                    fis.close();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
+    private ExamSyncStudent updateExamStudent(ExamSyncStudent s1, ExamSyncStudentTemp s2) {
+        s1.setJxbId(s2.getJxbId());
+        s1.setJxbmc(s2.getJxbmc());
+        s1.setKcmc(s2.getKcmc());
+        s1.setJgh(s2.getJgh());
+        s1.setXm(s2.getXm());
+        s1.setKkbm(s2.getKkbm());
+        s1.setXf(s2.getXf());
+        s1.setXsxm(s2.getXsxm());
+        s1.setJgmc(s2.getJgmc());
+        s1.setZymc(s2.getZymc());
+        s1.setCxbj(s2.getCxbj());
+        s1.setNjdmId(s2.getNjdmId());
+        s1.setZwh(s2.getZwh());
+        s1.setCdmc(s2.getCdmc());
+        s1.setKsbz(s2.getKsbz());
+        return s1;
+    }
 
-            // 删除txt文件
-            if (txtFile != null) {
-                txtFile.delete();
-            }
+    private boolean compareStudent(ExamSyncStudent s1, ExamSyncStudentTemp s2) {
+        String s1String = spliceParam(s1.getJxbId(), s1.getJxbmc(), s1.getKcmc(), s1.getJgh(), s1.getXm(), s1.getKkbm(), s1.getXf(), s1.getXsxm(), s1.getJgmc(), s1.getZymc(), s1.getCxbj(), s1.getNjdmId(), s1.getZwh(), s1.getCdmc(), s1.getKsbz());
+        String s2String = spliceParam(s2.getJxbId(), s2.getJxbmc(), s2.getKcmc(), s2.getJgh(), s2.getXm(), s2.getKkbm(), s2.getXf(), s2.getXsxm(), s2.getJgmc(), s2.getZymc(), s2.getCxbj(), s2.getNjdmId(), s2.getZwh(), s2.getCdmc(), s2.getKsbz());
+        return s1String.equals(s2String);
+    }
+
+    private String spliceParam(String... params) {
+        StringJoiner stringJoiner = new StringJoiner("#");
+        for (String param : params) {
+            stringJoiner.add(param);
         }
+        return stringJoiner.toString();
     }
 
     @Override
@@ -235,7 +276,7 @@ public class WhuDataSyncServiceImpl implements WhuDataSyncService {
                         cloudMarkingScore.setName(m.getString("name"));
                         cloudMarkingScore.setSubjectCode(m.getString("subjectCode"));
                         String remark = m.getString("remark");
-                        if(StringUtils.isNotBlank(remark)){
+                        if (StringUtils.isNotBlank(remark)) {
                             cloudMarkingScore.setSyncCourseCode(remark.trim());
                         } else {
                             cloudMarkingScore.setSyncCourseCode(cloudMarkingScore.getSubjectCode());
@@ -689,40 +730,40 @@ public class WhuDataSyncServiceImpl implements WhuDataSyncService {
     }
 
     /**
-     * 检查数据是否有变动,需要新增一条新同步记录
+     * 生成临时文件,获取文件MD5
      *
-     * @param schoolId   学校ID
-     * @param semesterId 学期ID
-     * @param examTypeId 考试类型ID
-     * @param count      考生数量
-     * @param txtFileMd5 txt文件md5
+     * @param schoolId             学校ID
+     * @param examSyncStudentTemps 考生
      * @return true:可以新增  false:不能新增
      */
-    private boolean canAddTotal(Long schoolId, Long semesterId, Long examTypeId, int count, String txtFileMd5) {
-        // txtFileMd5为空,无法校验,返回true
-        if (txtFileMd5 == null) {
-            return true;
-        }
-
-        // 查询上一次同步数据,先比较数量
-        QueryWrapper<ExamSyncTotal> queryWrapper = new QueryWrapper<>();
-        queryWrapper.lambda().eq(ExamSyncTotal::getSchoolId, schoolId)
-                .eq(ExamSyncTotal::getSemesterId, semesterId)
-                .eq(ExamSyncTotal::getExamTypeId, examTypeId)
-                .orderByDesc(ExamSyncTotal::getSyncDate)
-                .orderByDesc(ExamSyncTotal::getCreateTime);
-        List<ExamSyncTotal> examSyncTotals = examSyncTotalService.list(queryWrapper);
-        // 没有同步记录,返回true
-        if (examSyncTotals.isEmpty()) {
-            return true;
-        }
-        ExamSyncTotal examSyncTotal = examSyncTotals.get(0);
-        // 上一次同步数据量与本次不一样,返回true
-        if (count != examSyncTotal.getStudents()) {
-            return true;
+    private String md5DataText(Long schoolId, List<ExamSyncStudentTemp> examSyncStudentTemps) {
+        String txtFileMd5 = null;
+        File txtFile = null;
+        FileInputStream fis = null;
+        // 生成数据文件,用来比较内容是否有变动
+        try {
+            txtFile = createTxt(schoolId, examSyncStudentTemps);
+            if (txtFile != null) {
+                fis = new FileInputStream(txtFile);
+                txtFileMd5 = DigestUtils.md5Hex(fis);
+            }
+        } catch (Exception e) {
+            log.error("生成临时文件MD5失败");
+        } finally {
+            // 关闭fis流
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            // 删除txt文件
+            if (txtFile != null) {
+                txtFile.delete();
+            }
         }
-        // 数据内容有变动,返回 true
-        return !txtFileMd5.equals(examSyncTotal.getDataMd5());
+        return txtFileMd5;
     }
 
     /**
@@ -848,4 +889,5 @@ public class WhuDataSyncServiceImpl implements WhuDataSyncService {
 
         return file;
     }
+
 }

+ 5 - 0
src/main/resources/db/log/1.1.0.sql

@@ -5,3 +5,8 @@ ALTER TABLE `exam_course_mapping` ADD COLUMN `exam_id` INT(10) NULL COMMENT '云
 ALTER TABLE `exam_course_mapping` ADD INDEX `index_1` (`exam_type_id` ASC, `exam_id` ASC);
 ALTER TABLE `exam_assign` ADD COLUMN `sync_course_code` VARCHAR(45) NULL COMMENT '考务数据课程代码' AFTER `exam_type_id`;
 
+-- 2025-02-13
+ALTER TABLE `exam_sync_total` ADD COLUMN `sync_log` MEDIUMTEXT NULL COMMENT '同步日志' AFTER `update_time`;
+delete FROM exam_sync_total where use_file = 0;
+update exam_sync_total set download_status = 1 where download_status = 0;
+delete from exam_sync_student where exam_sync_total_id in (SELECT id FROM exam_sync_total where use_file = 0);

+ 1 - 2
src/main/resources/mapper/ExamSyncTotalMapper.xml

@@ -2,14 +2,13 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 <mapper namespace="com.qmth.eds.mapper.ExamSyncTotalMapper">
     <select id="listDownloadRecordInfos" resultType="com.qmth.eds.bean.dto.ExamSyncTotalDownloadDto">
-        SELECT est.id,
+        SELECT distinct
                est.school_id      schoolId,
                est.school_name    schoolName,
                est.semester_id    semesterId,
                est.semester_name  semesterName,
                est.exam_type_id   examTypeId,
                est.exam_type_name examTypeName,
-               est.file_name      fileName,
                su.id              userId,
                su.real_name       userName,
                su.mobile_number   mobileNumber