|
@@ -0,0 +1,201 @@
|
|
|
+package cn.com.qmth.dp.examcloud.oe.modules.get_continued_count;
|
|
|
+
|
|
|
+import cn.com.qmth.examcloud.commons.helpers.ObjectHolder;
|
|
|
+import cn.com.qmth.examcloud.commons.helpers.poi.ExcelWriter;
|
|
|
+import cn.com.qmth.examcloud.commons.util.JsonUtil;
|
|
|
+import com.google.common.collect.Lists;
|
|
|
+import com.google.common.collect.Maps;
|
|
|
+import com.google.common.collect.Sets;
|
|
|
+import com.mongodb.MongoException;
|
|
|
+import io.swagger.models.auth.In;
|
|
|
+import org.apache.commons.collections.CollectionUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.bson.Document;
|
|
|
+import org.jsoup.Jsoup;
|
|
|
+import org.jsoup.safety.Whitelist;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.dao.DataAccessException;
|
|
|
+import org.springframework.data.mongodb.core.DocumentCallbackHandler;
|
|
|
+import org.springframework.data.mongodb.core.MongoTemplate;
|
|
|
+import org.springframework.data.mongodb.core.query.Criteria;
|
|
|
+import org.springframework.data.mongodb.core.query.Query;
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
+import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
+import org.springframework.scheduling.annotation.Async;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @Description 获取考生断点次数
|
|
|
+ * @Author lideyin
|
|
|
+ * @Date 2020/7/7 11:17
|
|
|
+ * @Version 1.0
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class GetStudentContinutedCountService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ JdbcTemplate jdbcTemplate;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ MongoTemplate mongoTemplate;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ RedisTemplate<String, Object> redisTemplate;
|
|
|
+
|
|
|
+ public void start(Long examId) throws Exception {
|
|
|
+ System.out.println("开始初始化数据...");
|
|
|
+ List<Map<String, Object>> examStudentList = getExamStudentList(examId);
|
|
|
+
|
|
|
+ //已同步的考试记录数据
|
|
|
+ Map<Long, Integer> syncedDataMap = getFinalExamRecordContinuedCountList(examId);
|
|
|
+
|
|
|
+ System.out.println("初始化数据完成,准备导出数据...");
|
|
|
+ int stuTotal = examStudentList.size();
|
|
|
+ int i = 0;
|
|
|
+ for (Map<String, Object> map : examStudentList) {
|
|
|
+ i++;
|
|
|
+ Long ss = System.currentTimeMillis();
|
|
|
+ System.out.println("stuTotal: " + stuTotal + "; count: " + i);
|
|
|
+ Long examRecordDataId = (Long) map.get("exam_record_data_id");
|
|
|
+ String examRecordDataKey = String.format("OE_ERD:%s", examRecordDataId);
|
|
|
+ Long st = System.currentTimeMillis();
|
|
|
+ Object oData = redisTemplate.opsForValue().get(examRecordDataKey);
|
|
|
+ System.out.println(String.format("%s:.1.redis中取数据耗时:%s ms",i,(System.currentTimeMillis()-st)));
|
|
|
+
|
|
|
+ //缓存中有数据则从缓存中取数据,没有则从数据库中取
|
|
|
+ if (oData != null) {
|
|
|
+ Map<String, Object> erdMap = (Map<String, Object>) oData;
|
|
|
+ Object oContinuedCount = erdMap.get("continued_count");
|
|
|
+ Integer continuedCount;
|
|
|
+ if (oContinuedCount == null) {
|
|
|
+ continuedCount = 0;
|
|
|
+ } else {
|
|
|
+ continuedCount = (Integer) oContinuedCount;
|
|
|
+ }
|
|
|
+ map.put("continued_count", continuedCount);
|
|
|
+ }
|
|
|
+ //从正式库中取数据
|
|
|
+ else {
|
|
|
+
|
|
|
+ st = System.currentTimeMillis();
|
|
|
+ Integer continuedCount = syncedDataMap.get(examRecordDataId);
|
|
|
+ System.out.println(String.format("%s:.2.map中取断点数耗时:%s ms",i,(System.currentTimeMillis()-st)));
|
|
|
+
|
|
|
+ //从已同步的缓存 中找不到则再从库中实时取,
|
|
|
+ if (null == continuedCount) {
|
|
|
+ map.put("continued_count", getFinalContinuedCount(examRecordDataId));
|
|
|
+ }
|
|
|
+ //直接从已同步的缓存中取
|
|
|
+ else {
|
|
|
+ st = System.currentTimeMillis();
|
|
|
+ map.put("continued_count", continuedCount);
|
|
|
+ System.out.println(String.format("%s:.3.结果map中放数据耗时:%s ms",i,(System.currentTimeMillis()-st)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ System.out.println(String.format("%s:.完成一次循环.合计耗时:%s ms",i,(System.currentTimeMillis()-st)));
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.println("准备导出数据完成,开始导出...");
|
|
|
+
|
|
|
+ List<Object[]> datas = Lists.newArrayList();
|
|
|
+ int total = examStudentList.size();
|
|
|
+ int count = 0;
|
|
|
+ for (Map<String, Object> cur : examStudentList) {
|
|
|
+ count++;
|
|
|
+ System.out.println("total: " + total + "; count: " + count);
|
|
|
+ String student_name = String.valueOf(cur.get("student_name"));
|
|
|
+ String student_code = String.valueOf(cur.get("student_code"));
|
|
|
+ String identity_number = String.valueOf(cur.get("identity_number"));
|
|
|
+ String exam_record_data_id = String.valueOf(cur.get("exam_record_data_id"));
|
|
|
+ String start_time = String.valueOf(cur.get("start_time"));
|
|
|
+ String course_code = String.valueOf(cur.get("course_code"));
|
|
|
+ String course_name = String.valueOf(cur.get("course_name"));
|
|
|
+ String continued_count = String.valueOf(cur.get("continued_count"));
|
|
|
+
|
|
|
+
|
|
|
+ Object[] row = new Object[]{student_name, student_code, identity_number,
|
|
|
+ exam_record_data_id, start_time, course_code, course_name, continued_count};
|
|
|
+
|
|
|
+ datas.add(row);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ String filePath = "D:/Temp/student-continuedCount-" + examId + ".xlsx";
|
|
|
+
|
|
|
+ final String[] EXCEL_HEADER = new String[]{"姓名", "学号", "身份证号",
|
|
|
+ "考试记录id", "开考时间", "课程代码", "课程名称", "断点次数"};
|
|
|
+
|
|
|
+ ExcelWriter.write(EXCEL_HEADER, new Class[]
|
|
|
+
|
|
|
+ {
|
|
|
+ String.class, String.class, String.class, String.class,
|
|
|
+ String.class, String.class, String.class, String.class
|
|
|
+ }, datas, new
|
|
|
+
|
|
|
+ File(filePath));
|
|
|
+
|
|
|
+ System.out.println("OVER ! examId=" + examId);
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<Map<String, Object>> getExamStudentList(Long examId) {
|
|
|
+ String sql = "select " +
|
|
|
+ "t2.student_name,t2.student_code,t2.identity_number,t1.id as exam_record_data_id, t1.start_time, " +
|
|
|
+ "t2.course_code,t3.`name` as course_name " +
|
|
|
+ "from ec_oes_exam_record_data t1 " +
|
|
|
+ "inner join ec_oe_exam_student t2 on t1.exam_student_id=t2.exam_student_id " +
|
|
|
+ "inner join ec_b_course t3 on t1.course_id=t3.id " +
|
|
|
+ "where t1.exam_id=?";
|
|
|
+ Object[] args = new Object[]{examId};
|
|
|
+ return jdbcTemplate.queryForList(sql, args);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取已同步的考试下的所有断点次数
|
|
|
+ *
|
|
|
+ * @param examId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Map<Long, Integer> getFinalExamRecordContinuedCountList(Long examId) {
|
|
|
+ String sql = "select t2.cache_id, t1.continued_count from ec_oe_exam_record_data t1\n" +
|
|
|
+ "inner join ec_oe_exam_record_data_sync t2 on t1.id=t2.db_id\n" +
|
|
|
+ "where t1.exam_id=?";
|
|
|
+ Object[] args = new Object[]{examId};
|
|
|
+ List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql, args);
|
|
|
+ if (null == mapList || mapList.isEmpty()) {
|
|
|
+ return new HashMap<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<Long, Integer> resultMap = new HashMap<>();
|
|
|
+ for (Map<String, Object> map : mapList) {
|
|
|
+ Integer continued_count = map.get("continued_count") == null
|
|
|
+ ? 0
|
|
|
+ : Integer.valueOf(map.get("continued_count").toString());
|
|
|
+ resultMap.put(Long.valueOf(map.get("cache_id").toString()), continued_count);
|
|
|
+ }
|
|
|
+
|
|
|
+ return resultMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取已同步的考试下的所有断点次数
|
|
|
+ *
|
|
|
+ * @param cacheId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Integer getFinalContinuedCount(Long cacheId) {
|
|
|
+ String sql = "select t1.continued_count from ec_oe_exam_record_data t1\n" +
|
|
|
+ "inner join ec_oe_exam_record_data_sync t2 on t1.id=t2.db_id\n" +
|
|
|
+ "where t1.cache_id=?";
|
|
|
+ Object[] args = new Object[]{cacheId};
|
|
|
+ List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql, args);
|
|
|
+ if (null == mapList || mapList.isEmpty()) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return Integer.valueOf(mapList.get(0).get("continued_count").toString());
|
|
|
+ }
|
|
|
+}
|