|
@@ -0,0 +1,240 @@
|
|
|
+package cn.com.qmth.examcloud.core.oe.admin.service.impl;
|
|
|
+
|
|
|
+import cn.com.qmth.examcloud.api.commons.security.bean.UserDataRule;
|
|
|
+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.dao.enums.CourseLevel;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.service.ExamRecordWaitingAuditService;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.service.IllegallyTypeService;
|
|
|
+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 org.apache.commons.collections4.CollectionUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.data.domain.Page;
|
|
|
+import org.springframework.data.domain.PageImpl;
|
|
|
+import org.springframework.data.domain.Pageable;
|
|
|
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
|
|
+import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class ExamRecordWaitingAuditServiceImpl implements ExamRecordWaitingAuditService {
|
|
|
+
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(ExamRecordWaitingAuditServiceImpl.class);
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IllegallyTypeService illegallyTypeService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private JdbcTemplate jdbcTemplate;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Page<ExamRecordInfo> getExamRecordWaitingAuditList(ExamRecordQuery query, UserDataRule courseRule, UserDataRule orgRule) {
|
|
|
+ Check.isNull(query, "请求参数不能为空!");
|
|
|
+ Check.isNull(query.getExamId(), "请先选择考试!");
|
|
|
+
|
|
|
+ Pageable pageable = SpecUtils.buildPageable(query.getPageNo(), query.getPageSize());
|
|
|
+ if (courseRule.assertEmptyQueryResult() || orgRule.assertEmptyQueryResult()) {
|
|
|
+ return Page.empty(pageable);
|
|
|
+ }
|
|
|
+
|
|
|
+ int offset = (query.getPageNo() - 1) * query.getPageSize();
|
|
|
+ String countSql = this.queryExamRecordWaitingAuditListSql(query, true, courseRule, orgRule);
|
|
|
+ String querySql = this.queryExamRecordWaitingAuditListSql(query, false, courseRule, orgRule);
|
|
|
+ String pageSql = querySql + " limit " + offset + "," + query.getPageSize();
|
|
|
+
|
|
|
+ Long totalElements = jdbcTemplate.queryForObject(countSql, Long.class);
|
|
|
+ if (totalElements == null || totalElements == 0) {
|
|
|
+ return Page.empty(pageable);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<ExamRecordInfo> list = jdbcTemplate.query(pageSql, new BeanPropertyRowMapper(ExamRecordInfo.class));
|
|
|
+ if (CollectionUtils.isEmpty(list)) {
|
|
|
+ return Page.empty(pageable);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 填充其它信息
|
|
|
+ this.fillOtherInfo(list, query.getExamId());
|
|
|
+
|
|
|
+ return new PageImpl<>(list, pageable, totalElements);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void fillOtherInfo(List<ExamRecordInfo> list, Long examId) {
|
|
|
+ ExamSettingsCacheBean examCache = CacheHelper.getExamSettings(examId);
|
|
|
+ Map<Long, String> orgMaps = new HashMap<>();
|
|
|
+ Map<Long, CourseCacheBean> courseMaps = new HashMap<>();
|
|
|
+
|
|
|
+ for (ExamRecordInfo info : list) {
|
|
|
+ // 考试名称
|
|
|
+ info.setExamName(examCache.getName());
|
|
|
+
|
|
|
+ // 学习中心名称
|
|
|
+ String orgName = orgMaps.get(info.getOrgId());
|
|
|
+ if (orgName == null) {
|
|
|
+ orgName = CacheHelper.getOrg(info.getOrgId()).getName();
|
|
|
+ orgMaps.put(info.getOrgId(), orgName);
|
|
|
+ }
|
|
|
+ info.setOrgName(orgName);
|
|
|
+
|
|
|
+ // 课程信息
|
|
|
+ CourseCacheBean course = courseMaps.get(info.getCourseId());
|
|
|
+ if (course == null) {
|
|
|
+ course = CacheHelper.getCourse(info.getCourseId());
|
|
|
+ courseMaps.put(info.getCourseId(), course);
|
|
|
+ }
|
|
|
+ info.setCourseCode(course.getCode());
|
|
|
+ info.setCourseName(course.getName());
|
|
|
+ info.setCourseLevel(CourseLevel.getCourseLevel(course.getLevel()).getTitle());
|
|
|
+ info.setCourseNameAndCode(info.getCourseName() + "(" + info.getCourseCode() + ")");
|
|
|
+
|
|
|
+ info.setDataId(info.getId());
|
|
|
+ info.setHasVirtual(StringUtils.isNotBlank(info.getVirtualCameraNames()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private String queryExamRecordWaitingAuditListSql(ExamRecordQuery query, boolean isCount
|
|
|
+ , UserDataRule courseRule, UserDataRule orgRule) {
|
|
|
+ StringBuilder sql = new StringBuilder();
|
|
|
+ if (isCount) {
|
|
|
+ sql.append(" select count(DISTINCT rd.id)");
|
|
|
+ } else {
|
|
|
+ sql.append(" select rd.*,a.audit_user_name,sco.objective_score objectiveTotalScore,");
|
|
|
+ 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")
|
|
|
+ .append(" where cm.exam_record_data_id = rd.id and cm.virtual_camera = 1) virtualCameraNames");
|
|
|
+ }
|
|
|
+
|
|
|
+ sql.append(" from ec_oe_exam_record_data rd");
|
|
|
+ sql.append(" left join ec_oe_exam_audit a on a.exam_record_data_id = rd.id");
|
|
|
+ sql.append(" left join ec_oe_exam_warn w on w.exam_record_data_id = rd.id");
|
|
|
+ sql.append(" left join ec_oe_exam_score sco on sco.exam_record_data_id = rd.id");
|
|
|
+
|
|
|
+ sql.append(" where rd.exam_id = ").append(query.getExamId());
|
|
|
+ sql.append(" and rd.exam_record_status in ('EXAM_END','EXAM_OVERDUE')");
|
|
|
+ sql.append(" and rd.is_audit = 0");
|
|
|
+ sql.append(" and rd.is_illegality = 0");
|
|
|
+ if (query.getIsWarn() != null) {
|
|
|
+ sql.append(" and rd.is_warn = ").append(query.getIsWarn() ? "1" : "0");
|
|
|
+ }
|
|
|
+ if (query.getExamRecordId() != null) {
|
|
|
+ sql.append(" and rd.id = ").append(query.getExamRecordId());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (courseRule.assertNeedQueryRefIds()) {
|
|
|
+ // 限定课程数据权限范围
|
|
|
+ if (query.getCourseId() != null) {
|
|
|
+ if (courseRule.getRefIds().contains(query.getCourseId())) {
|
|
|
+ sql.append(" and rd.course_id = ").append(query.getCourseId());
|
|
|
+ } else {
|
|
|
+ // 不在数据权限范围内,无效查询
|
|
|
+ sql.append(" and rd.course_id = -1");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ sql.append(" and rd.course_id in (").append(StringUtils.join(courseRule.getRefIds(), ",")).append(")");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 未限定数据权限
|
|
|
+ if (query.getCourseId() != null) {
|
|
|
+ sql.append(" and rd.course_id = ").append(query.getCourseId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (orgRule.assertNeedQueryRefIds()) {
|
|
|
+ // 限定机构数据权限范围
|
|
|
+ if (query.getOrgId() != null) {
|
|
|
+ if (orgRule.getRefIds().contains(query.getOrgId())) {
|
|
|
+ sql.append(" and rd.org_id = ").append(query.getOrgId());
|
|
|
+ } else {
|
|
|
+ // 不在数据权限范围内,无效查询
|
|
|
+ sql.append(" and rd.org_id = -1");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ sql.append(" and rd.org_id in (").append(StringUtils.join(orgRule.getRefIds(), ",")).append(")");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 未限定数据权限
|
|
|
+ if (query.getOrgId() != null) {
|
|
|
+ sql.append(" and rd.org_id = ").append(query.getOrgId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (query.getExamStageId() != null) {
|
|
|
+ sql.append(" and rd.exam_stage_id = ").append(query.getExamStageId());
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(query.getCourseLevel())) {
|
|
|
+ sql.append(" and rd.course_level = '").append(query.getCourseLevel()).append("'");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(query.getIdentityNumber())) {
|
|
|
+ sql.append(" and rd.identity_number like '").append(query.getIdentityNumber()).append("%'");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(query.getStudentCode())) {
|
|
|
+ sql.append(" and rd.student_code like '").append(query.getStudentCode()).append("%'");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(query.getStudentName())) {
|
|
|
+ sql.append(" and rd.student_name like '").append(query.getStudentName()).append("%'");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StringUtils.isNotBlank(query.getStartTime()) && StringUtils.isNotBlank(query.getEndTime())) {
|
|
|
+ sql.append(" and rd.start_time >= '").append(query.getStartTime()).append("'");
|
|
|
+ sql.append(" and rd.start_time <= '").append(query.getEndTime()).append("'");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StringUtils.isNotBlank(query.getSubmitStartTime()) && StringUtils.isNotBlank(query.getSubmitEndTime())) {
|
|
|
+ sql.append(" and rd.end_time >= '").append(query.getSubmitStartTime()).append("'");
|
|
|
+ sql.append(" and rd.end_time <= '").append(query.getSubmitEndTime()).append("'");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (query.getFaceSuccessPercentLower() != null && query.getFaceSuccessPercentUpper() != null) {
|
|
|
+ sql.append(" and rd.face_success_percent >= ").append(query.getFaceSuccessPercentLower());
|
|
|
+ sql.append(" and rd.face_success_percent <= ").append(query.getFaceSuccessPercentUpper());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (query.getLivenessSuccessPercentLower() != null && query.getLivenessSuccessPercentUpper() != null) {
|
|
|
+ sql.append(" and rd.baidu_face_liveness_success_percent >= ").append(query.getLivenessSuccessPercentLower());
|
|
|
+ sql.append(" and rd.baidu_face_liveness_success_percent <= ").append(query.getLivenessSuccessPercentUpper());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (query.getHasStranger() != null) {
|
|
|
+ if (query.getHasStranger()) {
|
|
|
+ sql.append(" and rd.face_stranger_count > 0");
|
|
|
+ } else {
|
|
|
+ sql.append(" and rd.face_stranger_count = 0");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (query.getHasVirtual() != null) {
|
|
|
+ if (query.getHasVirtual()) {
|
|
|
+ sql.append(" and exists(");
|
|
|
+ sql.append(" select 1 from ec_oe_exam_capture_camera_info v where v.exam_record_data_id = rd.id and v.virtual_camera = 1");
|
|
|
+ sql.append(" )");
|
|
|
+ } else {
|
|
|
+ sql.append(" and not exists(");
|
|
|
+ sql.append(" select 1 from ec_oe_exam_capture_camera_info v where v.exam_record_data_id = rd.id and v.virtual_camera = 1");
|
|
|
+ sql.append(" )");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StringUtils.isNotBlank(query.getWarnType())) {
|
|
|
+ sql.append(" and w.warn_type = '").append(query.getWarnType()).append("'");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!isCount) {
|
|
|
+ sql.append(" group by rd.id");
|
|
|
+ sql.append(" order by rd.id desc");
|
|
|
+ }
|
|
|
+
|
|
|
+ return sql.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+}
|