|
@@ -0,0 +1,306 @@
|
|
|
+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.commons.util.DateUtil;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.base.Constants;
|
|
|
+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.AuditStatus;
|
|
|
+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.SelectType;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.service.ExamRecordAlreadyAuditService;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.service.IllegallyTypeService;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.service.bean.examaudit.ExamAuditEntityConvert;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.service.bean.examaudit.ExamAuditExcel;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.service.bean.examaudit.ExamAuditInfo;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.service.bean.examaudit.ExamAuditQuery;
|
|
|
+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.ExamStageCacheBean;
|
|
|
+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.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class ExamRecordAlreadyAuditServiceImpl implements ExamRecordAlreadyAuditService {
|
|
|
+
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(ExamRecordAlreadyAuditServiceImpl.class);
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IllegallyTypeService illegallyTypeService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private JdbcTemplate jdbcTemplate;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Page<ExamAuditInfo> getExamRecordAlreadyAuditList(ExamAuditQuery 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.queryExamRecordAlreadyAuditListSql(query, true, courseRule, orgRule);
|
|
|
+ String querySql = this.queryExamRecordAlreadyAuditListSql(query, false, courseRule, orgRule);
|
|
|
+ String pageSql = querySql + " limit " + offset + "," + query.getPageSize();
|
|
|
+ log.debug(pageSql);
|
|
|
+
|
|
|
+ Long totalElements = jdbcTemplate.queryForObject(countSql, Long.class);
|
|
|
+ if (totalElements == null || totalElements == 0) {
|
|
|
+ return Page.empty(pageable);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<ExamAuditInfo> list = jdbcTemplate.query(pageSql, new BeanPropertyRowMapper(ExamAuditInfo.class));
|
|
|
+ if (CollectionUtils.isEmpty(list)) {
|
|
|
+ return Page.empty(pageable);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 填充其它信息
|
|
|
+ this.fillOtherInfo(list, query.getExamId());
|
|
|
+
|
|
|
+ return new PageImpl<>(list, pageable, totalElements);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<ExamAuditExcel> getExamRecordAlreadyAuditListForExport(ExamAuditQuery query, UserDataRule courseRule, UserDataRule orgRule) {
|
|
|
+ Check.isNull(query, "请求参数不能为空!");
|
|
|
+ Check.isNull(query.getExamId(), "请先选择考试!");
|
|
|
+ query.setSelectType(SelectType.EXPORT);
|
|
|
+
|
|
|
+ if (courseRule.assertEmptyQueryResult() || orgRule.assertEmptyQueryResult()) {
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 仅导出结果
|
|
|
+ String querySql = this.queryExamRecordAlreadyAuditListSql(query, false, courseRule, orgRule);
|
|
|
+ log.debug(querySql);
|
|
|
+ List<ExamAuditInfo> list = jdbcTemplate.query(querySql, new BeanPropertyRowMapper(ExamAuditInfo.class));
|
|
|
+
|
|
|
+ // 填充其它信息
|
|
|
+ this.fillOtherInfo(list, query.getExamId());
|
|
|
+
|
|
|
+ return ExamAuditEntityConvert.ofExcel(list);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void fillOtherInfo(List<ExamAuditInfo> list, Long examId) {
|
|
|
+ ExamSettingsCacheBean examCache = CacheHelper.getExamSettings(examId);
|
|
|
+ Map<Long, String> orgMaps = new HashMap<>();
|
|
|
+ Map<Long, CourseCacheBean> courseMaps = new HashMap<>();
|
|
|
+ Map<Long, ExamStageCacheBean> examStageMaps = new HashMap<>();
|
|
|
+
|
|
|
+ Map<String, String> illegallyTypeMaps = illegallyTypeService.getIllegallyTypes(examCache.getRootOrgId());
|
|
|
+
|
|
|
+ for (ExamAuditInfo 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());
|
|
|
+
|
|
|
+ // 场次信息
|
|
|
+ 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.setStartTime(examStage.getStartTime());
|
|
|
+ info.setEndTime(examStage.getEndTime());
|
|
|
+ info.setExamStage(examStage.getStageOrder() + "("
|
|
|
+ + DateUtil.format(examStage.getStartTime(), DateUtil.DatePatterns.CHINA_DEFAULT) + "至"
|
|
|
+ + DateUtil.format(examStage.getEndTime(), DateUtil.DatePatterns.CHINA_DEFAULT) + ")");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 违规类型名称
|
|
|
+ info.setDisciplineType(illegallyTypeMaps.get(info.getDisciplineType()));
|
|
|
+ info.setStatus(AuditStatus.getTitle(info.getStatus()));
|
|
|
+ IsSuccess result = IsSuccess.strToEnum(info.getFaceVerifyResult());
|
|
|
+ if (result != null) {
|
|
|
+ info.setFaceVerifyResult(result.getDesc());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private String queryExamRecordAlreadyAuditListSql(ExamAuditQuery 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.id AS examRecordDataId,rd.exam_id,rd.exam_type,");
|
|
|
+ sql.append(" rd.course_id,rd.org_id,rd.exam_stage_id,rd.student_id,");
|
|
|
+ sql.append(" rd.exam_student_id,rd.student_code,rd.student_name,rd.identity_number,");
|
|
|
+ sql.append(" rd.start_time AS paperStartTime,rd.end_time AS paperSubmitTime,rd.exam_order,");
|
|
|
+ sql.append(" rd.face_total_count,rd.face_success_count,rd.face_failed_count,");
|
|
|
+ sql.append(" rd.face_success_percent,rd.face_stranger_count,rd.face_verify_result,");
|
|
|
+ sql.append(" rd.switch_screen_count,sco.objective_score,a.id,a.status,a.discipline_type,");
|
|
|
+ sql.append(" a.discipline_detail,a.audit_user_name,a.update_time AS paperAuditTime,");
|
|
|
+ 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(" 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_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 != 'EXAM_INVALID'");
|
|
|
+
|
|
|
+ sql.append(" and exists (");
|
|
|
+ sql.append(" select aa.exam_record_data_id from ec_oe_exam_audit aa");
|
|
|
+ sql.append(" where aa.exam_record_data_id = rd.id");
|
|
|
+ if (StringUtils.isNotBlank(query.getStatus())) {
|
|
|
+ sql.append(" and aa.status = '").append(query.getStatus()).append("'");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(query.getDisciplineType())) {
|
|
|
+ sql.append(" and aa.discipline_type = '").append(query.getDisciplineType()).append("'");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(query.getAuditStartTime()) && StringUtils.isNotBlank(query.getAuditEndTime())) {
|
|
|
+ sql.append(" and aa.update_time >= '").append(query.getAuditStartTime()).append("'");
|
|
|
+ sql.append(" and aa.update_time <= '").append(query.getAuditEndTime()).append("'");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(query.getAuditType())) {
|
|
|
+ if ("1".equals(query.getAuditType())) {
|
|
|
+ // 系统审核
|
|
|
+ sql.append(" and aa.audit_user_name = '").append(Constants.AUDIT_USER_NAME).append("'");
|
|
|
+ } else {
|
|
|
+ // 人工审核
|
|
|
+ if (StringUtils.isNotBlank(query.getAuditUserName())) {
|
|
|
+ if (Constants.AUDIT_USER_NAME.equals(query.getAuditUserName())) {
|
|
|
+ // 排除SYSTEM关键字
|
|
|
+ sql.append(" and aa.audit_user_name != '").append(Constants.AUDIT_USER_NAME).append("'");
|
|
|
+ }
|
|
|
+ sql.append(" and aa.audit_user_name like '").append(query.getAuditUserName()).append("%'");
|
|
|
+ } else {
|
|
|
+ sql.append(" and aa.audit_user_name != '").append(Constants.AUDIT_USER_NAME).append("'");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (StringUtils.isNotBlank(query.getAuditUserName())) {
|
|
|
+ sql.append(" and aa.audit_user_name like '").append(query.getAuditUserName()).append("%'");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ sql.append(" )");
|
|
|
+
|
|
|
+ if (query.getExamRecordDataId() != null) {
|
|
|
+ sql.append(" and rd.id = ").append(query.getExamRecordDataId());
|
|
|
+ }
|
|
|
+
|
|
|
+ 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 (query.getSwitchScreenCountStart() != null) {
|
|
|
+ sql.append(" and rd.switch_screen_count >= ").append(query.getSwitchScreenCountStart());
|
|
|
+ }
|
|
|
+ if (query.getSwitchScreenCountEnd() != null) {
|
|
|
+ sql.append(" and rd.switch_screen_count <= ").append(query.getSwitchScreenCountEnd());
|
|
|
+ }
|
|
|
+
|
|
|
+ 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 (!isCount) {
|
|
|
+ sql.append(" group by rd.id");
|
|
|
+
|
|
|
+ if (SelectType.EXPORT != query.getSelectType()) {
|
|
|
+ // sql.append(" order by rd.id desc");
|
|
|
+ sql.append(" order by rd.update_time desc");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return sql.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+}
|