|
@@ -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;
|
|
|
}
|
|
|
+
|
|
|
}
|