|
@@ -1,16 +1,25 @@
|
|
|
package cn.com.qmth.examcloud.core.oe.admin.service.impl;
|
|
|
|
|
|
+import cn.com.qmth.examcloud.api.commons.enums.ExamType;
|
|
|
import cn.com.qmth.examcloud.api.commons.security.bean.UserDataRule;
|
|
|
+import cn.com.qmth.examcloud.commons.util.DateUtil;
|
|
|
+import cn.com.qmth.examcloud.commons.util.StringUtil;
|
|
|
import cn.com.qmth.examcloud.core.oe.admin.base.jpa.SpecUtils;
|
|
|
import cn.com.qmth.examcloud.core.oe.admin.base.utils.Check;
|
|
|
import cn.com.qmth.examcloud.core.oe.admin.base.utils.DateUtils;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.dao.ExamRecordFileAnswerRepo;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.dao.entity.ExamRecordFileAnswerEntity;
|
|
|
import cn.com.qmth.examcloud.core.oe.admin.dao.enums.CourseLevel;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.dao.enums.IsSuccess;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.dao.enums.TrueFalse;
|
|
|
import cn.com.qmth.examcloud.core.oe.admin.service.ExamRecordDetailService;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.service.bean.examrecord.ExamRecordFileAnswerInfo;
|
|
|
import cn.com.qmth.examcloud.core.oe.admin.service.bean.examrecord.ExamRecordInfo;
|
|
|
import cn.com.qmth.examcloud.core.oe.admin.service.bean.examrecord.ExamRecordQuery;
|
|
|
import cn.com.qmth.examcloud.support.cache.CacheHelper;
|
|
|
-import cn.com.qmth.examcloud.support.cache.bean.CourseCacheBean;
|
|
|
-import cn.com.qmth.examcloud.support.cache.bean.ExamSettingsCacheBean;
|
|
|
+import cn.com.qmth.examcloud.support.cache.bean.*;
|
|
|
+import cn.com.qmth.examcloud.support.enums.ExamProperties;
|
|
|
+import cn.com.qmth.examcloud.support.fss.FssHelper;
|
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.slf4j.Logger;
|
|
@@ -23,6 +32,7 @@ import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
@@ -32,6 +42,9 @@ public class ExamRecordDetailServiceImpl implements ExamRecordDetailService {
|
|
|
|
|
|
private static final Logger log = LoggerFactory.getLogger(ExamRecordDetailServiceImpl.class);
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private ExamRecordFileAnswerRepo examRecordFileAnswerRepo;
|
|
|
+
|
|
|
@Autowired
|
|
|
private JdbcTemplate jdbcTemplate;
|
|
|
|
|
@@ -71,6 +84,15 @@ public class ExamRecordDetailServiceImpl implements ExamRecordDetailService {
|
|
|
ExamSettingsCacheBean examCache = CacheHelper.getExamSettings(examId);
|
|
|
Map<Long, String> orgMaps = new HashMap<>();
|
|
|
Map<Long, CourseCacheBean> courseMaps = new HashMap<>();
|
|
|
+ Map<Long, ExamStageCacheBean> examStageMaps = new HashMap<>();
|
|
|
+ Map<Long, StudentCacheBean> studentMaps = new HashMap<>();
|
|
|
+
|
|
|
+ //考试 是否开启身份检测
|
|
|
+ boolean faceEnable = false;
|
|
|
+ if (ExamType.ONLINE.name().equals(examCache.getExamType())) {
|
|
|
+ ExamPropertyCacheBean property = CacheHelper.getExamProperty(examId, ExamProperties.IS_FACE_ENABLE.name());
|
|
|
+ faceEnable = property != null && StringUtil.isTrue(property.getValue());
|
|
|
+ }
|
|
|
|
|
|
for (ExamRecordInfo info : list) {
|
|
|
// 考试名称
|
|
@@ -95,8 +117,42 @@ public class ExamRecordDetailServiceImpl implements ExamRecordDetailService {
|
|
|
info.setCourseLevel(CourseLevel.getCourseLevel(course.getLevel()).getTitle());
|
|
|
info.setCourseNameAndCode(info.getCourseName() + "(" + info.getCourseCode() + ")");
|
|
|
|
|
|
+ // 场次信息
|
|
|
+ if (info.getExamStageId() != null) {
|
|
|
+ ExamStageCacheBean examStage = examStageMaps.get(info.getExamStageId());
|
|
|
+ if (examStage == null) {
|
|
|
+ examStage = CacheHelper.getExamStage(examId, info.getExamStageId());
|
|
|
+ examStageMaps.put(info.getExamStageId(), examStage);
|
|
|
+ }
|
|
|
+ info.setExamStageOrder(examStage.getStageOrder());
|
|
|
+ info.setStageStartTime(examStage.getStartTime());
|
|
|
+ info.setStageEndTime(examStage.getEndTime());
|
|
|
+ info.setExamStage(examStage.getStageOrder() + "("
|
|
|
+ + DateUtil.format(examStage.getStartTime(), DateUtil.DatePatterns.CHINA_DEFAULT) + "至"
|
|
|
+ + DateUtil.format(examStage.getEndTime(), DateUtil.DatePatterns.CHINA_DEFAULT) + ")");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 学生信息
|
|
|
+ StudentCacheBean student = studentMaps.get(info.getStudentId());
|
|
|
+ if (student == null) {
|
|
|
+ student = CacheHelper.getStudent(info.getStudentId());
|
|
|
+ studentMaps.put(info.getStudentId(), student);
|
|
|
+ }
|
|
|
+ info.setPhone(student.getPhoneNumber());
|
|
|
+
|
|
|
info.setDataId(info.getId());
|
|
|
info.setHasVirtual(StringUtils.isNotBlank(info.getVirtualCameraNames()));
|
|
|
+ info.setShowReAudit(faceEnable);
|
|
|
+ info.setStudentNumber(info.getStudentId() + "" + info.getExamStudentId());
|
|
|
+
|
|
|
+ if (info.getSubjectiveTotalScore() == null) {
|
|
|
+ info.setSubjectiveTotalScore("0");
|
|
|
+ }
|
|
|
+
|
|
|
+ //违纪标志
|
|
|
+ info.setDisciplineSign(TrueFalse.of(info.getIsWarn()));
|
|
|
+ info.setIsIllegality("1".equals(info.getIsIllegality()) ? "是" : "否");
|
|
|
+
|
|
|
if (info.getStartTime() != null) {
|
|
|
info.setPaperStartTime(DateUtils.format(info.getStartTime()));
|
|
|
} else {
|
|
@@ -104,10 +160,52 @@ public class ExamRecordDetailServiceImpl implements ExamRecordDetailService {
|
|
|
}
|
|
|
if (info.getEndTime() != null) {
|
|
|
info.setPaperSubmitTime(DateUtils.format(info.getEndTime()));
|
|
|
+ info.setIsSubmit("是");
|
|
|
} else {
|
|
|
info.setPaperSubmitTime("");
|
|
|
+ info.setIsSubmit("否");
|
|
|
}
|
|
|
+
|
|
|
+ //每次考试持续时间
|
|
|
+ if (info.getStartTime() != null && info.getEndTime() != null) {
|
|
|
+ if (info.getUsedExamTime() != null) {
|
|
|
+ info.setExamTime(info.getUsedExamTime() > 0 ? DateUtils.diff(info.getUsedExamTime()) : "");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ info.setExamTime("");
|
|
|
+ }
|
|
|
+
|
|
|
+ IsSuccess result = IsSuccess.strToEnum(info.getFaceVerifyResult());
|
|
|
+ if (result != null) {
|
|
|
+ info.setFaceVerifyResult(result.getDesc());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ExamType.OFFLINE.name().equals(examCache.getExamType())) {
|
|
|
+ // 离线考试作答文件
|
|
|
+ List<ExamRecordFileAnswerEntity> fileAnswers = examRecordFileAnswerRepo.findByExamRecordDataId(info.getId());
|
|
|
+ info.setOfflineFiles(this.ofFileAnswer(fileAnswers));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<ExamRecordFileAnswerInfo> ofFileAnswer(List<ExamRecordFileAnswerEntity> entities) {
|
|
|
+ List<ExamRecordFileAnswerInfo> result = new ArrayList<>();
|
|
|
+
|
|
|
+ for (ExamRecordFileAnswerEntity entity : entities) {
|
|
|
+ ExamRecordFileAnswerInfo info = new ExamRecordFileAnswerInfo();
|
|
|
+ info.setId(entity.getId());
|
|
|
+ info.setExamRecordDataId(entity.getExamRecordDataId());
|
|
|
+ info.setOfflineFileName(entity.getFileName());
|
|
|
+ info.setOriginalFileName(entity.getOriginalFileName());
|
|
|
+ info.setFileType(entity.getFileType());
|
|
|
+ info.setSuffix(entity.getSuffix());
|
|
|
+ info.setProperties(entity.getProperties());
|
|
|
+
|
|
|
+ info.setOfflineFileUrl(FssHelper.finalFileUrl(entity.getFileUrl()));
|
|
|
+ result.add(info);
|
|
|
}
|
|
|
+
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
private String queryExamRecordDetailListSql(ExamRecordQuery query, boolean isCount
|
|
@@ -117,6 +215,8 @@ public class ExamRecordDetailServiceImpl implements ExamRecordDetailService {
|
|
|
sql.append(" select count(DISTINCT rd.id)");
|
|
|
} else {
|
|
|
sql.append(" select rd.*,a.audit_user_name,sco.objective_score objectiveTotalScore,");
|
|
|
+ sql.append(" sco.subjective_score subjectiveTotalScore,sco.total_score paperTotalScore,");
|
|
|
+ sql.append(" es.grade,es.specialty_name,");
|
|
|
sql.append(" (select GROUP_CONCAT(DISTINCT pr.source_ip) from ec_oe_exam_process_record pr")
|
|
|
.append(" where pr.exam_record_data_id = rd.id) ip,");
|
|
|
sql.append(" (select GROUP_CONCAT(DISTINCT cm.name) from ec_oe_exam_capture_camera_info cm")
|
|
@@ -124,6 +224,7 @@ public class ExamRecordDetailServiceImpl implements ExamRecordDetailService {
|
|
|
}
|
|
|
|
|
|
sql.append(" from ec_oe_exam_record_data rd");
|
|
|
+ sql.append(" left join ec_oe_exam_student es on es.exam_student_id = rd.exam_student_id");
|
|
|
sql.append(" left join ec_oe_exam_audit a on a.exam_record_data_id = rd.id");
|
|
|
sql.append(" left join ec_oe_exam_score sco on sco.exam_record_data_id = rd.id");
|
|
|
|
|
@@ -209,6 +310,17 @@ public class ExamRecordDetailServiceImpl implements ExamRecordDetailService {
|
|
|
sql.append(" and rd.switch_screen_count <= ").append(query.getSwitchScreenCountEnd());
|
|
|
}
|
|
|
|
|
|
+ if (StringUtils.isNotBlank(query.getAuditUserName())) {
|
|
|
+ sql.append(" and a.audit_user_name like '").append(query.getAuditUserName()).append("%'");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StringUtils.isNotBlank(query.getIp())) {
|
|
|
+ sql.append(" and exists (");
|
|
|
+ sql.append(" select 1 from ec_oe_exam_process_record pr where pr.exam_record_data_id = rd.id");
|
|
|
+ sql.append(" and pr.source_ip = '").append(query.getIp()).append("'");
|
|
|
+ sql.append(" )");
|
|
|
+ }
|
|
|
+
|
|
|
if (query.getHasVirtual() != null) {
|
|
|
sql.append(" and").append(query.getHasVirtual() ? " exists" : " not exists");
|
|
|
sql.append(" (");
|
|
@@ -227,20 +339,6 @@ public class ExamRecordDetailServiceImpl implements ExamRecordDetailService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (StringUtils.isNotBlank(query.getAuditUserName())) {
|
|
|
- sql.append(" and exists (");
|
|
|
- sql.append(" select 1 from ec_oe_exam_audit aa where aa.exam_record_data_id = rd.id");
|
|
|
- sql.append(" and aa.audit_user_name like '").append(query.getAuditUserName()).append("%'");
|
|
|
- sql.append(" )");
|
|
|
- }
|
|
|
-
|
|
|
- if (StringUtils.isNotBlank(query.getIp())) {
|
|
|
- sql.append(" and exists (");
|
|
|
- sql.append(" select 1 from ec_oe_exam_process_record pr where pr.exam_record_data_id = rd.id");
|
|
|
- sql.append(" and pr.source_ip = '").append(query.getIp()).append("'");
|
|
|
- sql.append(" )");
|
|
|
- }
|
|
|
-
|
|
|
if (!isCount) {
|
|
|
sql.append(" group by rd.id");
|
|
|
|