|
@@ -1,403 +0,0 @@
|
|
|
-package cn.com.qmth.examcloud.core.examwork.service.impl;
|
|
|
-
|
|
|
-import java.io.File;
|
|
|
-import java.io.IOException;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.Calendar;
|
|
|
-import java.util.Collections;
|
|
|
-import java.util.Date;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-import java.util.concurrent.ExecutorService;
|
|
|
-import java.util.concurrent.Executors;
|
|
|
-
|
|
|
-import javax.persistence.CacheRetrieveMode;
|
|
|
-import javax.persistence.EntityManager;
|
|
|
-import javax.persistence.EntityManagerFactory;
|
|
|
-import javax.persistence.EntityTransaction;
|
|
|
-import javax.persistence.PersistenceUnit;
|
|
|
-import javax.persistence.Query;
|
|
|
-
|
|
|
-import org.apache.commons.collections.CollectionUtils;
|
|
|
-import org.apache.commons.io.FileUtils;
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
-import org.apache.poi.ss.usermodel.Sheet;
|
|
|
-import org.apache.poi.ss.usermodel.Workbook;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.beans.factory.annotation.Value;
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
-import org.springframework.transaction.annotation.Transactional;
|
|
|
-
|
|
|
-import com.google.common.collect.Lists;
|
|
|
-import com.google.common.collect.Maps;
|
|
|
-
|
|
|
-import cn.com.qmth.examcloud.commons.base.exception.StatusException;
|
|
|
-import cn.com.qmth.examcloud.commons.base.helpers.poi.ExcelParser;
|
|
|
-import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLog;
|
|
|
-import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLogFactory;
|
|
|
-import cn.com.qmth.examcloud.commons.base.util.DateUtil;
|
|
|
-import cn.com.qmth.examcloud.commons.base.util.DateUtil.DatePatterns;
|
|
|
-import cn.com.qmth.examcloud.core.basic.api.StudentCloudService;
|
|
|
-import cn.com.qmth.examcloud.core.basic.api.request.InsertOrUpdateStudentReq;
|
|
|
-import cn.com.qmth.examcloud.core.basic.api.response.InsertOrUpdateStudentResp;
|
|
|
-import cn.com.qmth.examcloud.core.examwork.dao.ExamStudentTempRepo;
|
|
|
-import cn.com.qmth.examcloud.core.examwork.dao.entity.ExamStudentTempEntity;
|
|
|
-import cn.com.qmth.examcloud.core.examwork.service.ExamStudentImportService;
|
|
|
-import cn.com.qmth.examcloud.core.examwork.service.bean.ExamStudentImportResult;
|
|
|
-import cn.com.qmth.examcloud.core.examwork.service.bean.ExamStudentInfo;
|
|
|
-
|
|
|
-/**
|
|
|
- * 类注释
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @date 2018年7月13日
|
|
|
- * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
|
|
|
- */
|
|
|
-@Service
|
|
|
-public class ExamStudentImportServiceImpl implements ExamStudentImportService {
|
|
|
-
|
|
|
- protected ExamCloudLog log = ExamCloudLogFactory.getLog(this.getClass());
|
|
|
-
|
|
|
- private static final String[] EXCEL_HEADER = new String[]{"姓名", "学号", "身份证号", "学习中心代码",
|
|
|
- "学习中心名称", "课程代码", "课程名称", "试卷类型", "专业", "考点", "信息采集人", "学生电话", "年级"};
|
|
|
-
|
|
|
- @Autowired
|
|
|
- ExamStudentServiceImpl examStudentService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- ExamStudentTempRepo examStudentTempRepo;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- StudentCloudService studentCloudService;
|
|
|
-
|
|
|
- @PersistenceUnit
|
|
|
- private EntityManagerFactory entityManagerFactory;
|
|
|
-
|
|
|
- @Value("${$tempDir}")
|
|
|
- private String $tempDir;
|
|
|
-
|
|
|
- private static ExecutorService executorService = Executors.newFixedThreadPool(50);
|
|
|
-
|
|
|
- @Override
|
|
|
- public ExamStudentImportResult importExamStudent(File file, String fileName, Long rootOrgId,
|
|
|
- Long examId) {
|
|
|
- Workbook workBook = ExcelParser.getWorkBook(file, fileName);
|
|
|
-
|
|
|
- Sheet sheet = workBook.getSheetAt(0);
|
|
|
-
|
|
|
- List<String[]> lineList = ExcelParser.readSheet(sheet, 13);
|
|
|
- ExcelParser.close(workBook);
|
|
|
-
|
|
|
- if (CollectionUtils.isEmpty(lineList)) {
|
|
|
- throw new StatusException("E-651002", "Excel 没有内容");
|
|
|
- }
|
|
|
-
|
|
|
- List<ExamStudentTempEntity> list = Lists.newArrayList();
|
|
|
- long batchId = System.currentTimeMillis();
|
|
|
-
|
|
|
- ExamStudentImportResult result = new ExamStudentImportResult();
|
|
|
- List<Map<String, Object>> failRecords = Collections
|
|
|
- .synchronizedList(new ArrayList<Map<String, Object>>());
|
|
|
- result.setFailRecords(failRecords);
|
|
|
-
|
|
|
- for (int i = 0; i < lineList.size(); i++) {
|
|
|
- String[] line = lineList.get(i);
|
|
|
- if (0 == i) {
|
|
|
- checkExcelHeader(line);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- ExamStudentTempEntity es = new ExamStudentTempEntity();
|
|
|
- es.setLineNum((long) 1 + i);
|
|
|
- es.setRootOrgId(rootOrgId);
|
|
|
- es.setExamId(examId);
|
|
|
- es.setBatchId(batchId);
|
|
|
- es.setName(trimAndNullIfBlank(line[0]));
|
|
|
- es.setStudentCode(trimAndNullIfBlank(line[1]));
|
|
|
- es.setIdentityNumber(trimAndNullIfBlank(line[2]));
|
|
|
- es.setOrgCode(trimAndNullIfBlank(line[3]));
|
|
|
- es.setOrgName(trimAndNullIfBlank(line[4]));
|
|
|
- es.setCourseCode(trimAndNullIfBlank(line[5]));
|
|
|
- es.setCourseName(trimAndNullIfBlank(line[6]));
|
|
|
- es.setPaperType(trimAndNullIfBlank(line[7]));
|
|
|
- es.setSpecialtyName(trimAndNullIfBlank(line[8]));
|
|
|
- es.setExamSite(trimAndNullIfBlank(line[9]));
|
|
|
- es.setInfoCollector(trimAndNullIfBlank(line[10]));
|
|
|
- es.setPhone(trimAndNullIfBlank(line[11]));
|
|
|
- es.setGrade(trimAndNullIfBlank(line[12]));
|
|
|
-
|
|
|
- if (hasError(failRecords, es)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- list.add(es);
|
|
|
- if (0 == i % 100) {
|
|
|
- examStudentTempRepo.save(list);
|
|
|
-
|
|
|
- list = Lists.newArrayList();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- examStudentTempRepo.save(list);
|
|
|
-
|
|
|
- examStudentTempRepo.processExamStudentTemp(batchId);
|
|
|
-
|
|
|
- findError(failRecords, batchId);
|
|
|
-
|
|
|
- delete(batchId);
|
|
|
-
|
|
|
- result.setFailNum(failRecords.size());
|
|
|
-
|
|
|
- String resultFileName = new StringBuilder().append(rootOrgId).append("_").append(examId)
|
|
|
- .append("_").append(DateUtil.getNow(DatePatterns.YYYYMMDDHHMM)).append(".txt")
|
|
|
- .toString();
|
|
|
-
|
|
|
- ExamStudentImportThread thread = new ExamStudentImportThread(failRecords, batchId,
|
|
|
- resultFileName);
|
|
|
- executorService.execute(thread);
|
|
|
-
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 类注释
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @date 2018年7月26日
|
|
|
- * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
|
|
|
- */
|
|
|
- private class ExamStudentImportThread implements Runnable {
|
|
|
-
|
|
|
- private List<Map<String, Object>> failRecords;
|
|
|
-
|
|
|
- private Long batchId;
|
|
|
-
|
|
|
- private String fileName;
|
|
|
-
|
|
|
- public ExamStudentImportThread(List<Map<String, Object>> failRecords, Long batchId,
|
|
|
- String fileName) {
|
|
|
- super();
|
|
|
- this.failRecords = failRecords;
|
|
|
- this.batchId = batchId;
|
|
|
- this.fileName = fileName;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void run() {
|
|
|
- saveExamStudents(failRecords, batchId);
|
|
|
- StringBuilder sb = new StringBuilder();
|
|
|
- for (Map<String, Object> cur : failRecords) {
|
|
|
- sb.append("line:").append(cur.get("lineNum")).append(cur.get("msg")).append("\n");
|
|
|
- }
|
|
|
- File file = new File($tempDir + File.separator + fileName);
|
|
|
- try {
|
|
|
- FileUtils.writeStringToFile(file, sb.toString(), "UTF-8");
|
|
|
- } catch (IOException e) {
|
|
|
- log.error("fail to create file.", e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- private void findError(List<Map<String, Object>> failRecords, long batchId) {
|
|
|
- EntityManager em = entityManagerFactory.createEntityManager();
|
|
|
- Query query = em.createQuery("select s from ExamStudentTempEntity s where "
|
|
|
- + "s.batchId=:batchId and (s.orgId is null or s.courseId is null) order by s.lineNum",
|
|
|
- ExamStudentTempEntity.class);
|
|
|
- query.setHint("javax.persistence.cache.retrieveMode", CacheRetrieveMode.BYPASS);
|
|
|
- query.setParameter("batchId", batchId);
|
|
|
-
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
- List<ExamStudentTempEntity> errorList = query.getResultList();
|
|
|
-
|
|
|
- for (ExamStudentTempEntity cur : errorList) {
|
|
|
- boolean hasError = false;
|
|
|
- StringBuilder sb = new StringBuilder();
|
|
|
- if (null == cur.getOrgId()) {
|
|
|
- sb.append(" 学习中心不存在或禁用");
|
|
|
- hasError = true;
|
|
|
- }
|
|
|
- if (null == cur.getCourseId()) {
|
|
|
- sb.append(" 课程不存在或被禁用");
|
|
|
- hasError = true;
|
|
|
- }
|
|
|
-
|
|
|
- if (hasError) {
|
|
|
- Map<String, Object> map = Maps.newHashMap();
|
|
|
- map.put("lineNum", cur.getLineNum());
|
|
|
- map.put("msg", sb.toString());
|
|
|
- failRecords.add(map);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- public boolean hasError(List<Map<String, Object>> failRecords, ExamStudentTempEntity entity) {
|
|
|
- boolean hasError = false;
|
|
|
- StringBuilder sb = new StringBuilder();
|
|
|
-
|
|
|
- String name = entity.getName();
|
|
|
- if (StringUtils.isBlank(name)) {
|
|
|
- sb.append(" 姓名不能为空");
|
|
|
- hasError = true;
|
|
|
- } else if (20 < name.length()) {
|
|
|
- sb.append(" 姓名不能超过20个字符");
|
|
|
- hasError = true;
|
|
|
- }
|
|
|
-
|
|
|
- String identityNumber = entity.getIdentityNumber();
|
|
|
- if (StringUtils.isBlank(identityNumber)) {
|
|
|
- sb.append(" 身份证号不能为空");
|
|
|
- hasError = true;
|
|
|
- } else if (identityNumber.length() < 6) {
|
|
|
- sb.append(" 身份证号至少为6个字符");
|
|
|
- hasError = true;
|
|
|
- } else if (identityNumber.length() > 30) {
|
|
|
- sb.append(" 身份证号不能超过30个字符");
|
|
|
- hasError = true;
|
|
|
- }
|
|
|
-
|
|
|
- String studentCode = entity.getStudentCode();
|
|
|
- if (StringUtils.isNotBlank(studentCode)) {
|
|
|
- if (studentCode.length() < 6) {
|
|
|
- sb.append(" 学号至少为6个字符");
|
|
|
- hasError = true;
|
|
|
- } else if (studentCode.length() > 30) {
|
|
|
- sb.append(" 学号不能超过30个字符");
|
|
|
- hasError = true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- String courseCode = entity.getCourseCode();
|
|
|
- if (StringUtils.isBlank(courseCode)) {
|
|
|
- sb.append(" 课程代码不能为空");
|
|
|
- hasError = true;
|
|
|
- } else if (courseCode.length() > 30) {
|
|
|
- sb.append(" 课程代码不能超过30个字符");
|
|
|
- hasError = true;
|
|
|
- }
|
|
|
-
|
|
|
- String orgCode = entity.getOrgCode();
|
|
|
- if (StringUtils.isBlank(orgCode)) {
|
|
|
- sb.append(" 学习中心代码不能为空");
|
|
|
- hasError = true;
|
|
|
- } else if (orgCode.length() > 30) {
|
|
|
- sb.append(" 学习中心代码不能超过30个字符");
|
|
|
- hasError = true;
|
|
|
- }
|
|
|
-
|
|
|
- if (hasError) {
|
|
|
- Map<String, Object> map = Maps.newHashMap();
|
|
|
- map.put("lineNum", entity.getLineNum());
|
|
|
- map.put("msg", sb.toString());
|
|
|
- failRecords.add(map);
|
|
|
- }
|
|
|
-
|
|
|
- return hasError;
|
|
|
- }
|
|
|
-
|
|
|
- private void delete(Long batchId) {
|
|
|
- EntityManager em = entityManagerFactory.createEntityManager();
|
|
|
- EntityTransaction transaction = em.getTransaction();
|
|
|
- Query query = em.createQuery(
|
|
|
- "delete from ExamStudentTempEntity s where s.updateTime < :updateTime");
|
|
|
- transaction.begin();
|
|
|
- // 清理过去七天前的数据
|
|
|
- Calendar c = Calendar.getInstance();
|
|
|
- c.setTime(new Date());
|
|
|
- c.add(Calendar.DATE, -7);
|
|
|
- Date d = c.getTime();
|
|
|
- query.setParameter("updateTime", d);
|
|
|
- query.executeUpdate();
|
|
|
- transaction.commit();
|
|
|
- }
|
|
|
-
|
|
|
- private void saveExamStudents(List<Map<String, Object>> failRecords, Long batchId) {
|
|
|
- EntityManager em = entityManagerFactory.createEntityManager();
|
|
|
- Query query = em.createQuery("select s from ExamStudentTempEntity s where "
|
|
|
- + "s.name is not null and s.orgId is not null and s.identityNumber is not null "
|
|
|
- + "and s.courseId is not null and s.batchId=:batchId", ExamStudentTempEntity.class);
|
|
|
- query.setHint("javax.persistence.cache.retrieveMode", CacheRetrieveMode.BYPASS);
|
|
|
- query.setParameter("batchId", batchId);
|
|
|
-
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
- List<ExamStudentTempEntity> list = query.getResultList();
|
|
|
-
|
|
|
- for (ExamStudentTempEntity examStudent : list) {
|
|
|
-
|
|
|
- try {
|
|
|
- saveExamStudent(examStudent);
|
|
|
- } catch (StatusException e) {
|
|
|
- Map<String, Object> map = Maps.newHashMap();
|
|
|
- map.put("lineNum", examStudent.getLineNum());
|
|
|
- map.put("msg", " " + e.getDesc());
|
|
|
- failRecords.add(map);
|
|
|
- } catch (Exception e) {
|
|
|
- Map<String, Object> map = Maps.newHashMap();
|
|
|
- map.put("lineNum", examStudent.getLineNum());
|
|
|
- map.put("msg", " " + e.getMessage());
|
|
|
- failRecords.add(map);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Transactional
|
|
|
- private void saveExamStudent(ExamStudentTempEntity examStudent) {
|
|
|
- InsertOrUpdateStudentReq saveStudentReq = new InsertOrUpdateStudentReq();
|
|
|
- saveStudentReq.setIdentityNumber(examStudent.getIdentityNumber());
|
|
|
- saveStudentReq.setName(examStudent.getName());
|
|
|
- saveStudentReq.setPhoneNumber(examStudent.getPhone());
|
|
|
- saveStudentReq.setOrgCode(examStudent.getOrgCode());
|
|
|
- saveStudentReq.setOrgId(examStudent.getOrgId());
|
|
|
- saveStudentReq.setOrgName(examStudent.getOrgName());
|
|
|
- saveStudentReq.setRootOrgId(examStudent.getRootOrgId());
|
|
|
- saveStudentReq.setStudentCode(examStudent.getStudentCode());
|
|
|
-
|
|
|
- InsertOrUpdateStudentResp insertOrUpdateStudentResp = studentCloudService
|
|
|
- .insertOrUpdateStudent(saveStudentReq);
|
|
|
-
|
|
|
- Long studentId = insertOrUpdateStudentResp.getStudentId();
|
|
|
-
|
|
|
- ExamStudentInfo info = new ExamStudentInfo();
|
|
|
- info.setCourseId(Long.parseLong(examStudent.getCourseId()));
|
|
|
- info.setCourseName(null);
|
|
|
- info.setExamId(examStudent.getExamId());
|
|
|
- info.setIdentityNumber(examStudent.getIdentityNumber());
|
|
|
- info.setPaperType(examStudent.getPaperType());
|
|
|
- info.setRootOrgId(examStudent.getRootOrgId());
|
|
|
- info.setStudentCode(examStudent.getStudentCode());
|
|
|
- info.setStudentName(examStudent.getName());
|
|
|
- info.setStudentId(studentId);
|
|
|
- info.setInfoCollector(examStudent.getInfoCollector());
|
|
|
- info.setGrade(examStudent.getGrade());
|
|
|
- info.setExamSite(examStudent.getExamSite());
|
|
|
- info.setSpecialtyName(examStudent.getSpecialtyName());
|
|
|
-
|
|
|
- ExamStudentInfo savedExamStudent = examStudentService.saveExamStudent(info);
|
|
|
-
|
|
|
- log.debug("examStudentId=" + savedExamStudent.getId());
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 方法注释
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @param s
|
|
|
- * @return
|
|
|
- */
|
|
|
- private String trimAndNullIfBlank(String s) {
|
|
|
- if (StringUtils.isBlank(s)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- return s.trim();
|
|
|
- }
|
|
|
-
|
|
|
- private void checkExcelHeader(String[] header) {
|
|
|
- for (int i = 0; i < EXCEL_HEADER.length; i++) {
|
|
|
- if (!EXCEL_HEADER[i].equals(header[i].trim())) {
|
|
|
- throw new StatusException("E-651001", "Excel 表头错误");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-}
|