|
@@ -0,0 +1,1327 @@
|
|
|
+package com.qmth.distributed.print.business.templete.service.impl;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.google.common.collect.Lists;
|
|
|
+import com.google.common.reflect.TypeToken;
|
|
|
+import com.google.gson.Gson;
|
|
|
+import com.qmth.boot.api.exception.ApiException;
|
|
|
+import com.qmth.distributed.print.business.bean.dto.*;
|
|
|
+import com.qmth.distributed.print.business.bean.params.DownloadPaperFileParam;
|
|
|
+import com.qmth.distributed.print.business.bean.result.TSyncExamStudentScoreResult;
|
|
|
+import com.qmth.distributed.print.business.entity.*;
|
|
|
+import com.qmth.distributed.print.business.enums.ImageTrajectoryEnum;
|
|
|
+import com.qmth.distributed.print.business.enums.PaperFileDownloadContentEnum;
|
|
|
+import com.qmth.distributed.print.business.enums.PaperFileDownloadExposureStatusEnum;
|
|
|
+import com.qmth.distributed.print.business.enums.PrintPlanStatusEnum;
|
|
|
+import com.qmth.distributed.print.business.service.*;
|
|
|
+import com.qmth.distributed.print.business.templete.service.DownloadLogicService;
|
|
|
+import com.qmth.distributed.print.business.templete.service.TaskLogicService;
|
|
|
+import com.qmth.distributed.print.business.util.CreatePdfUtil;
|
|
|
+import com.qmth.teachcloud.common.annotation.ExcelDBFieldDesc;
|
|
|
+import com.qmth.teachcloud.common.base.BaseEntity;
|
|
|
+import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
|
|
|
+import com.qmth.teachcloud.common.bean.dto.excel.DescribeImportDto;
|
|
|
+import com.qmth.teachcloud.common.bean.dto.excel.StatisticsImportDto;
|
|
|
+import com.qmth.teachcloud.common.bean.dto.excel.SysUserImportDto;
|
|
|
+import com.qmth.teachcloud.common.bean.dto.excel.export.SysUserErrorExportDto;
|
|
|
+import com.qmth.teachcloud.common.bean.examRule.CodeNameEnableValue;
|
|
|
+import com.qmth.teachcloud.common.bean.examRule.FieldsDto;
|
|
|
+import com.qmth.teachcloud.common.bean.params.ArraysParams;
|
|
|
+import com.qmth.teachcloud.common.bean.result.DictionaryResult;
|
|
|
+import com.qmth.teachcloud.common.bean.vo.PaperInfoVo;
|
|
|
+import com.qmth.teachcloud.common.bean.vo.PrintPathVo;
|
|
|
+import com.qmth.teachcloud.common.config.DictionaryConfig;
|
|
|
+import com.qmth.teachcloud.common.contant.SystemConstant;
|
|
|
+import com.qmth.teachcloud.common.entity.*;
|
|
|
+import com.qmth.teachcloud.common.enums.*;
|
|
|
+import com.qmth.teachcloud.common.service.*;
|
|
|
+import com.qmth.teachcloud.common.util.*;
|
|
|
+import com.qmth.teachcloud.common.util.excel.ExcelError;
|
|
|
+import org.apache.commons.codec.digest.DigestUtils;
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
+import org.apache.commons.io.FileUtils;
|
|
|
+import org.apache.commons.io.FilenameUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
|
|
+import org.apache.poi.ss.usermodel.Cell;
|
|
|
+import org.apache.poi.ss.usermodel.Row;
|
|
|
+import org.apache.poi.ss.usermodel.Sheet;
|
|
|
+import org.apache.poi.ss.usermodel.Workbook;
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.context.annotation.Lazy;
|
|
|
+import org.springframework.dao.DuplicateKeyException;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.util.FileCopyUtils;
|
|
|
+import org.springframework.util.LinkedMultiValueMap;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.io.ByteArrayInputStream;
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
+import java.io.File;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.lang.reflect.Field;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.atomic.AtomicInteger;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @Description: 任务处理逻辑impl
|
|
|
+ * @Param:
|
|
|
+ * @return:
|
|
|
+ * @Author: wangliang
|
|
|
+ * @Date: 2021/3/29
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class DownloadLogicServiceImpl implements DownloadLogicService {
|
|
|
+ private final static Logger log = LoggerFactory.getLogger(DownloadLogicServiceImpl.class);
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ ExamPrintPlanService examPrintPlanService;
|
|
|
+ @Resource
|
|
|
+ ExamTaskService examTaskService;
|
|
|
+ @Resource
|
|
|
+ ExamTaskDetailService examTaskDetailService;
|
|
|
+ @Resource
|
|
|
+ ExamCardService examCardService;
|
|
|
+ @Resource
|
|
|
+ BasicAttachmentService basicAttachmentService;
|
|
|
+ @Resource
|
|
|
+ ExamDetailService examDetailService;
|
|
|
+ @Resource
|
|
|
+ BasicCourseService basicCourseService;
|
|
|
+ @Resource
|
|
|
+ CreatePdfUtil createPdfUtil;
|
|
|
+ @Resource
|
|
|
+ TBTaskPdfService tbTaskPdfService;
|
|
|
+ @Resource
|
|
|
+ BasicRoleDataPermissionService basicRoleDataPermissionService;
|
|
|
+ @Resource
|
|
|
+ SysUserService sysUserService;
|
|
|
+ @Resource
|
|
|
+ FileStoreUtil fileStoreUtil;
|
|
|
+ @Resource
|
|
|
+ SysOrgService sysOrgService;
|
|
|
+ @Resource
|
|
|
+ TCStatisticsService tcStatisticsService;
|
|
|
+ @Resource
|
|
|
+ TCStatisticsTempService tcStatisticsTempService;
|
|
|
+ @Resource
|
|
|
+ TSyncExamStudentScoreService tSyncExamStudentScoreService;
|
|
|
+ @Resource
|
|
|
+ @Lazy
|
|
|
+ PrintCommonService printCommonService;
|
|
|
+ @Resource
|
|
|
+ DownloadService downloadService;
|
|
|
+ @Resource
|
|
|
+ TeachClazzService teachClazzService;
|
|
|
+ @Resource
|
|
|
+ DictionaryConfig dictionaryConfig;
|
|
|
+ @Resource
|
|
|
+ FileUploadService fileUploadService;
|
|
|
+
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> executeExaminationLogic(Map<String, Object> map) throws Exception {
|
|
|
+ List<ExaminationExportDto> examinationExportDtoList = examDetailService.findExaminationExportDtoDatasource(map);
|
|
|
+
|
|
|
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
|
+ ExcelUtil.excelMake(ExaminationExportDto.class, examinationExportDtoList, outputStream);
|
|
|
+ InputStream in = new ByteArrayInputStream(outputStream.toByteArray());
|
|
|
+
|
|
|
+ StringJoiner stringJoiner = SystemConstant.getDirName(UploadFileEnum.FILE, true);
|
|
|
+ stringJoiner.add(SystemConstant.getNanoId()).add(".").add(SystemConstant.XLSX);
|
|
|
+
|
|
|
+ JSONObject jsonObject = new JSONObject();
|
|
|
+ String dirName = FileUtil.replaceSplit(stringJoiner.toString());
|
|
|
+ boolean oss = dictionaryConfig.sysDomain().isOss();
|
|
|
+ if (oss || (!oss && dictionaryConfig.fssPrivateDomain().getConfig().startsWith(SystemConstant.START_PARENT))) {//上传至oss
|
|
|
+ fileStoreUtil.ossUpload(dirName, in, DigestUtils.md5Hex(new ByteArrayInputStream(outputStream.toByteArray())), fileStoreUtil.getUploadEnumByPath(dirName).getFssType());
|
|
|
+ jsonObject.put(SystemConstant.TYPE, oss ? SystemConstant.OSS : SystemConstant.LOCAL);
|
|
|
+ jsonObject.put(SystemConstant.PATH, dirName);
|
|
|
+ } else {
|
|
|
+ dirName = FileUtil.replaceSplit((dictionaryConfig.fssPublicDomain().getConfig() + File.separator + dirName));
|
|
|
+ fileStoreUtil.copyInputStreamToFile(in, new File(stringJoiner.toString()), DigestUtils.md5Hex(new ByteArrayInputStream(outputStream.toByteArray())), LocalCatalogEnum.LOCAL_FILE);
|
|
|
+ jsonObject.put(SystemConstant.TYPE, SystemConstant.LOCAL);
|
|
|
+ jsonObject.put(SystemConstant.PATH, dirName);
|
|
|
+ }
|
|
|
+ jsonObject.put(SystemConstant.UPLOAD_TYPE, UploadFileEnum.FILE);
|
|
|
+ map.put(SystemConstant.PATH, jsonObject.toString());
|
|
|
+ map.put(SystemConstant.DATA_COUNT, examinationExportDtoList.size());
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> executeImportExaminationLogic(Map<String, Object> map) throws Exception {
|
|
|
+ SysUser sysUser = (SysUser) map.get(SystemConstant.USER);
|
|
|
+ TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
|
|
|
+ InputStream inputStream = (InputStream) map.get("inputStream");
|
|
|
+ Long printPlanId = tbTask.getPrintPlanId();
|
|
|
+ Long schoolId = tbTask.getSchoolId();
|
|
|
+ ExamPrintPlan examPrintPlan = examPrintPlanService.getById(printPlanId);
|
|
|
+ if (examPrintPlan == null) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("印刷计划不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ String printPlanName = examPrintPlan.getName();
|
|
|
+ if (!tbTaskPdfService.countByPrintPlanIdAndEntityId(schoolId, printPlanId)) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("印刷计划[" + printPlanName + "]有考场正在生成PDF文件,无法导入考务数据");
|
|
|
+ }
|
|
|
+ PrintPlanStatusEnum printPlanStatus = examPrintPlan.getStatus();
|
|
|
+ if (PrintPlanStatusEnum.NEW != printPlanStatus && PrintPlanStatusEnum.READY != printPlanStatus) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("印刷计划状态为[" + PrintPlanStatusEnum.NEW.getName() + "、" + PrintPlanStatusEnum.READY.getName() + "]时才可导入,当前状态[" + printPlanStatus.getName() + "]");
|
|
|
+ }
|
|
|
+ // 该学校有效考务规则字段
|
|
|
+ List<FieldsDto> fieldsDtoList = examDetailService.findExaminationFields(schoolId);
|
|
|
+
|
|
|
+ String importFilePath = tbTask.getImportFilePath();
|
|
|
+ Map importFilePathMap = JSONObject.parseObject(importFilePath);
|
|
|
+ String path = String.valueOf(importFilePathMap.get(SystemConstant.PATH));
|
|
|
+ Workbook workbook;
|
|
|
+ if (path.endsWith(SystemConstant.XLSX)) {
|
|
|
+ workbook = new XSSFWorkbook(inputStream);
|
|
|
+ } else if (path.endsWith(SystemConstant.XLS)) {
|
|
|
+ workbook = new HSSFWorkbook(inputStream);
|
|
|
+ } else {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("不支持的文件格式。只允许上传后缀为" + SystemConstant.XLSX + "、" + SystemConstant.XLS + "的文件");
|
|
|
+ }
|
|
|
+ // 读取第一个工作表
|
|
|
+ Sheet sheet = workbook.getSheetAt(0);
|
|
|
+ if (sheet.getLastRowNum() == 0 && sheet.getPhysicalNumberOfRows() == 0) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("第一个sheet为空,考务数据必须放在第一个sheet(工作表)内");
|
|
|
+ }
|
|
|
+ // 第一行为说明内容,不能为空
|
|
|
+ if (sheet.getRow(0) == null || !sheet.getRow(0).getCell(0).getStringCellValue().startsWith("说明")) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("表格第一行为说明内容,不能为空,且必须以\"说明\"开头");
|
|
|
+ }
|
|
|
+ // 第二行为表头,不能为空,且校验第一列为学号
|
|
|
+// if (sheet.getRow(1) == null || !"学号".equals(sheet.getRow(1).getCell(0).getStringCellValue())) {
|
|
|
+// throw ExceptionResultEnum.ERROR.exception("表格第二行为表头,不能为空,且第一列必须为\"学号\"");
|
|
|
+// }
|
|
|
+ // 获取sheet行数
|
|
|
+ int totalRows = sheet.getLastRowNum() + 1;
|
|
|
+ // 获取sheet列数(列数从第二行开始记录,因为第一行是说明内容)
|
|
|
+ int totalCells = 0;
|
|
|
+ if (totalRows > 2 && sheet.getRow(1) != null) {
|
|
|
+ totalCells = sheet.getRow(1).getPhysicalNumberOfCells();
|
|
|
+ }
|
|
|
+ // 获取sheet的title(第二行为表头)
|
|
|
+ Row head = sheet.getRow(1);
|
|
|
+ List<String> headList = new ArrayList<>();
|
|
|
+ // 将必填字段匹配excel解析的表头索引
|
|
|
+ for (int i = 0; i < totalCells; i++) {
|
|
|
+ String cellValue = String.valueOf(ExcelUtil.convert(head.getCell(i)));
|
|
|
+ for (FieldsDto fieldsDto : fieldsDtoList) {
|
|
|
+ if (cellValue.equals(fieldsDto.getName())) {
|
|
|
+ // 如果通用规则必填字段和excel表头匹配上了,则为该必选字段设置其在excel中的索引,并跳出循环体
|
|
|
+ fieldsDto.setIndex(i);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ headList.add(cellValue);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 搜索所有有效字段 excel中的表头是否包含
|
|
|
+ for (FieldsDto fieldsDto : fieldsDtoList) {
|
|
|
+ if (!headList.contains(fieldsDto.getName())) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("考务数据必填字段[" + fieldsDto.getName() + "]在表头中不存在");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ List<ExaminationImportDto> examinationImportDtoList = new ArrayList<>();
|
|
|
+
|
|
|
+ // 文件中课程代码对应的课程名称Map
|
|
|
+ Map<String, String> courseCodeNameInExcelMap = new HashMap<>();
|
|
|
+ // 课程管理中课程代码-课程名
|
|
|
+ Map<String, String> courseCodeNameInBasicCourseMap = new HashMap<>();
|
|
|
+ List<BasicCourse> basicCourseList = basicCourseService.list(new QueryWrapper<BasicCourse>().lambda().eq(BasicCourse::getSchoolId, schoolId));
|
|
|
+ basicCourseList.forEach(e -> {
|
|
|
+ courseCodeNameInBasicCourseMap.put(e.getCode(), e.getName());
|
|
|
+ });
|
|
|
+ // 文件中试卷编号对应多个课程代码
|
|
|
+ Map<String, String> paperNumberWithCourseCodeInExcelMap = new HashMap<>();
|
|
|
+ // 试卷编号在考试下有多个命题任务map
|
|
|
+ Map<String, Integer> paperNumberWithExamTaskMap = new HashMap<>();
|
|
|
+ Map<String, String> paperNumberCoureseSequenceMap = new HashMap<>();
|
|
|
+ // 命题任务中试卷编号对应的课程代码map
|
|
|
+ Map<String, String> paperNumberWithCourseCodeInExamTaskMap = new HashMap<>();
|
|
|
+
|
|
|
+ Long examId = examPrintPlan.getExamId();
|
|
|
+ List<ExamTask> examTaskList = examTaskService.list(new QueryWrapper<ExamTask>()
|
|
|
+ .lambda()
|
|
|
+ .eq(ExamTask::getSchoolId, schoolId)
|
|
|
+ .eq(ExamTask::getExamId, examId));
|
|
|
+ for (ExamTask examTask : examTaskList) {
|
|
|
+ String paperNumber = examTask.getPaperNumber();
|
|
|
+ String courseCode = examTask.getCourseCode();
|
|
|
+ paperNumberWithCourseCodeInExamTaskMap.put(paperNumber, courseCode);
|
|
|
+ if (paperNumberWithExamTaskMap.containsKey(paperNumber)) {
|
|
|
+ int count = paperNumberWithExamTaskMap.get(paperNumber);
|
|
|
+ paperNumberWithExamTaskMap.put(paperNumber, count);
|
|
|
+ } else {
|
|
|
+ paperNumberWithExamTaskMap.put(paperNumber, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ paperNumberCoureseSequenceMap.put(paperNumber, String.valueOf(examTask.getId()));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 从第三行开始为数据(第一行说明,第二行表头,第三行往后为数据)
|
|
|
+ for (int r = 2; r < totalRows; r++) {
|
|
|
+ // excel中的数据错误
|
|
|
+ StringJoiner errorRowDate = new StringJoiner(";\r\n");
|
|
|
+ Row row = sheet.getRow(r);
|
|
|
+ if (row == null || ExcelUtil.isRowAllCellEmpty(row, head)) {
|
|
|
+ // excel中整行为空,直接跳过
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 备选字段
|
|
|
+ List<FieldsDto> secondaryFieldList = new ArrayList<>();
|
|
|
+
|
|
|
+ ExaminationImportDto examinationImportDto = new ExaminationImportDto();
|
|
|
+ Field[] examinationImportDtoFields = examinationImportDto.getClass().getDeclaredFields();
|
|
|
+ List<CodeNameEnableValue> requiredFields = new ArrayList<>();
|
|
|
+ for (FieldsDto fieldsDto : fieldsDtoList) {
|
|
|
+ boolean match = false;
|
|
|
+ String name = fieldsDto.getName();
|
|
|
+ String code = fieldsDto.getCode();
|
|
|
+ int index = fieldsDto.getIndex();
|
|
|
+ String level = fieldsDto.getLevel();
|
|
|
+
|
|
|
+ if (Objects.nonNull(row)) {
|
|
|
+ Cell cell = row.getCell(index);
|
|
|
+ String cellValue = cell == null ? null : String.valueOf(ExcelUtil.convert(cell));
|
|
|
+ if (cellValue == null || cellValue.length() < 1 || cellValue.equals("null")) {
|
|
|
+ cellValue = "";
|
|
|
+ errorRowDate.add("第" + (r + 1) + "行,第" + (index + 1) + "列,字段[" + name + "]必填");
|
|
|
+ }
|
|
|
+
|
|
|
+ for (Field examinationImportDtoField : examinationImportDtoFields) {
|
|
|
+ ExcelDBFieldDesc excelDBFieldDesc = examinationImportDtoField.getAnnotation(ExcelDBFieldDesc.class);
|
|
|
+ if (excelDBFieldDesc == null) {
|
|
|
+ // 如果没有注解,说明该数据库必须字段不是从excel中获得的,直接跳过
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 如果数据库字段中文名和必填字段中文名称对应,则通过反射为数据库必选字段赋值
|
|
|
+ String dbName = excelDBFieldDesc.name();
|
|
|
+ int dbLength = excelDBFieldDesc.length();
|
|
|
+ if (dbName.equals(name)) {
|
|
|
+ if (dbLength > 0) {
|
|
|
+ SystemConstant.verifyLength(cellValue, dbLength, dbName);
|
|
|
+ }
|
|
|
+ examinationImportDtoField.setAccessible(true);
|
|
|
+ examinationImportDtoField.set(examinationImportDto, cellValue);
|
|
|
+ match = true;
|
|
|
+
|
|
|
+ // 匹配上为必选字段
|
|
|
+ CodeNameEnableValue codeNameEnableValue = new CodeNameEnableValue();
|
|
|
+ codeNameEnableValue.setCode(code);
|
|
|
+ codeNameEnableValue.setName(name);
|
|
|
+ codeNameEnableValue.setEnable(true);
|
|
|
+ codeNameEnableValue.setValue(cellValue);
|
|
|
+ requiredFields.add(codeNameEnableValue);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!match || "secondary".equals(level)) {
|
|
|
+ // 必选+扩展字段不能匹配到数据库中的字段存放 或者 该字段为扩展字段,则添加到扩展字段中
|
|
|
+ FieldsDto secondaryField = new FieldsDto();
|
|
|
+ secondaryField.setCode(code);
|
|
|
+ secondaryField.setName(name);
|
|
|
+ secondaryField.setEnable(true);
|
|
|
+ secondaryField.setValue(cellValue);
|
|
|
+ secondaryFieldList.add(secondaryField);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ examinationImportDto.setRequiredFieldList(requiredFields);
|
|
|
+ examinationImportDto.setSecondaryFieldList(secondaryFieldList);
|
|
|
+ examinationImportDto.setSchoolId(schoolId);
|
|
|
+ // 解析时间
|
|
|
+ try {
|
|
|
+ Map<String, Object> timeMap = ConvertUtil.analyzeStartAndEndTime(examinationImportDto.getExamDate(), examinationImportDto.getExamTime());
|
|
|
+ String examStartTime = String.valueOf(timeMap.get("startTime"));
|
|
|
+ String examEndTime = String.valueOf(timeMap.get("endTime"));
|
|
|
+ examinationImportDto.setExamStartTime(examStartTime);
|
|
|
+ examinationImportDto.setExamEndTime(examEndTime);
|
|
|
+ } catch (Exception e) {
|
|
|
+ errorRowDate.add(e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 唯一关系校验
|
|
|
+ String courseCode = examinationImportDto.getCourseCode();
|
|
|
+ String courseName = examinationImportDto.getCourseName();
|
|
|
+ String paperNumber = examinationImportDto.getPaperNumber();
|
|
|
+ String studentCode = examinationImportDto.getStudentCode();
|
|
|
+ String teacherName = examinationImportDto.getTeacherName();
|
|
|
+ if (StringUtils.isNotBlank(teacherName)) {
|
|
|
+ SysUser user = sysUserService.getByLoginName(schoolId, teacherName);
|
|
|
+ if (user == null) {
|
|
|
+ errorRowDate.add("任课老师[" + teacherName + "]在用户管理中不存在");
|
|
|
+ } else {
|
|
|
+ examinationImportDto.setTeacherId(user.getId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!SystemConstant.isOneNull(courseCode, courseName)) {
|
|
|
+ // 校验1 - 文件中课程代码对应多个不同的课程名称
|
|
|
+ if (courseCodeNameInExcelMap.containsKey(courseCode)) {
|
|
|
+ String name = courseCodeNameInExcelMap.get(courseCode);
|
|
|
+ if (!courseName.equals(name)) {
|
|
|
+ errorRowDate.add("文件中课程代码[" + courseCode + "]对应多个不同的课程名称");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ courseCodeNameInExcelMap.put(courseCode, courseName);
|
|
|
+ }
|
|
|
+ // 校验2 - 文件中课程代码对应的课程名称和课程管理中对应课程名称不一致
|
|
|
+ String basicName = courseCodeNameInBasicCourseMap.get(courseCode);
|
|
|
+ if (StringUtils.isBlank(basicName)) {
|
|
|
+ errorRowDate.add(String.format("文件中课程代码[%s]对应课程名称为[%s],课程管理中课程不存在", courseCode, courseName));
|
|
|
+ } else if (!courseName.equals(basicName)) {
|
|
|
+ errorRowDate.add(String.format("文件中课程代码[%s]对应课程名称为[%s],课程管理中对应课程名称为[%s]", courseCode, courseName, basicName));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!RegexUtil.validStudentCode(studentCode)) {
|
|
|
+ errorRowDate.add("文件中学号[" + studentCode + "]不对,学号只能由数字、字母组成");
|
|
|
+ }
|
|
|
+ if (!SystemConstant.isOneNull(paperNumber, courseCode)) {
|
|
|
+ // 检验4 - 文件中试卷编号[%s]对应多个不同的课程代码[%s]
|
|
|
+ if (paperNumberWithCourseCodeInExcelMap.containsKey(paperNumber)) {
|
|
|
+ String code = paperNumberWithCourseCodeInExcelMap.get(paperNumber);
|
|
|
+ if (!courseCode.equals(code)) {
|
|
|
+ errorRowDate.add(String.format("文件中试卷编号[%s]对应多个不同的课程代码", paperNumber));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ paperNumberWithCourseCodeInExcelMap.put(paperNumber, courseCode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (SystemConstant.strNotNull(paperNumber)) {
|
|
|
+ //检验5 - 试卷编号[%s]在考试[%s]下有多条命题任务,请联系管理员处理
|
|
|
+ if (paperNumberWithExamTaskMap.containsKey(paperNumber)) {
|
|
|
+ int count = paperNumberWithExamTaskMap.get(paperNumber);
|
|
|
+ if (count > 1) {
|
|
|
+ errorRowDate.add(String.format("试卷编号[%s]在考试[%s]下有多条命题任务,请联系管理员处理", paperNumber, count));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!SystemConstant.isOneNull(paperNumber, courseCode)) {
|
|
|
+ //检验6 - 文件中试卷编号[%s]对应课程代码为[%s],命题任务中对应课程代码为[%s]
|
|
|
+ if (paperNumberWithCourseCodeInExamTaskMap.containsKey(paperNumber)) {
|
|
|
+ String code = paperNumberWithCourseCodeInExamTaskMap.get(paperNumber);
|
|
|
+ if (!courseCode.equals(code)) {
|
|
|
+ errorRowDate.add(String.format("文件中试卷编号[%s]对应课程代码为[%s],命题任务中对应课程代码为[%s]", paperNumber, courseCode, code));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ examinationImportDto.setCoursePaperId(paperNumberCoureseSequenceMap.get(paperNumber));
|
|
|
+ examinationImportDto.setErrorMessage(errorRowDate.toString());
|
|
|
+ examinationImportDtoList.add(examinationImportDto);
|
|
|
+ }
|
|
|
+ List<String> errorList = examinationImportDtoList.stream()
|
|
|
+ .map(ExaminationImportDto::getErrorMessage)
|
|
|
+ .filter(SystemConstant::strNotNull)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (!CollectionUtils.isEmpty(errorList)) {
|
|
|
+ // 优先处理excel每个独立行的数据异常
|
|
|
+ map.put(SystemConstant.ERROR_DATA_LIST, examinationImportDtoList);
|
|
|
+ map.put("errorList", errorList);
|
|
|
+ map.put("fieldsDtoList", fieldsDtoList);
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 按考点+开始时间+课程代码+考场排序
|
|
|
+ examinationImportDtoList.sort(Comparator.comparing(ExaminationImportDto::getExamPlace)
|
|
|
+ .thenComparing(ExaminationImportDto::getExamStartTime)
|
|
|
+ .thenComparing(ExaminationImportDto::getCourseCode)
|
|
|
+ .thenComparing(ExaminationImportDto::getExamRoom)
|
|
|
+ );
|
|
|
+
|
|
|
+ // 卷袋号生成规则
|
|
|
+ try {
|
|
|
+ // 组装exam_detail数据
|
|
|
+ List<Long> examDetailIdList = examDetailService.disposeExamDataByExaminationExcel(examPrintPlan, examinationImportDtoList, sysUser);
|
|
|
+ // 更改印刷计划状态
|
|
|
+ examPrintPlan.setStatus(PrintPlanStatusEnum.READY);
|
|
|
+ examPrintPlanService.updateById(examPrintPlan);
|
|
|
+
|
|
|
+ map.put("examDetailIdList", examDetailIdList);
|
|
|
+ map.put("dataCount", examinationImportDtoList.size());
|
|
|
+ } catch (Exception e) {
|
|
|
+ if (e instanceof DuplicateKeyException) {
|
|
|
+ String errorColumn = e.getCause().toString();
|
|
|
+ String columnStr = errorColumn.substring(errorColumn.lastIndexOf("key") + 3, errorColumn.length()).replaceAll("'", "");
|
|
|
+ String[] data = errorColumn.split("-");
|
|
|
+ data[1] = data[1].substring(0, data[1].indexOf("'"));
|
|
|
+ throw ExceptionResultEnum.SQL_ERROR.exception("[" + FieldUniqueEnum.convertToTitle(columnStr) + "'" + data[1] + "']" + "数据不允许重复插入");
|
|
|
+ } else if (e instanceof ApiException) {
|
|
|
+ ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
|
|
|
+ } else {
|
|
|
+ ResultUtil.error(e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 下载pdf
|
|
|
+ *
|
|
|
+ * @param map
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional
|
|
|
+ public Map<String, Object> executeDownloadPdfLogic(Map<String, Object> map) {
|
|
|
+ List<File> sourceFileList = new ArrayList<>();
|
|
|
+ File zipFile = null;
|
|
|
+ String zipLocalRootPath = null;
|
|
|
+ try {
|
|
|
+ TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
|
|
|
+ JSONArray jsonArray = JSONArray.parseArray(tbTask.getRemark());
|
|
|
+ ArraysParams arraysParams = new ArraysParams(jsonArray.toArray(new Long[jsonArray.size()]));
|
|
|
+ if (Objects.isNull(arraysParams) || arraysParams.getIds().length == 0) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("请选择要下载的数据");
|
|
|
+ }
|
|
|
+
|
|
|
+ List<ExamDetailPdfDownloadDto> examDetailList = examDetailService.findPdfDownload(Arrays.asList(arraysParams.getIds()));
|
|
|
+ if (CollectionUtils.isNotEmpty(examDetailList)) {
|
|
|
+ Long time = System.currentTimeMillis();
|
|
|
+
|
|
|
+ zipFile = SystemConstant.getFileTempDirVar(SystemConstant.ZIP_PREFIX);
|
|
|
+ zipLocalRootPath = zipFile.getParent() + File.separator + time;
|
|
|
+
|
|
|
+ for (ExamDetailPdfDownloadDto e : examDetailList) {
|
|
|
+ StringJoiner dirPath = new StringJoiner("")
|
|
|
+ .add(zipLocalRootPath).add(File.separator)
|
|
|
+ .add(e.getSemesterName()).add(File.separator)
|
|
|
+ .add(e.getExamName()).add(File.separator)
|
|
|
+ .add(e.getCourseNameCode()).add(File.separator)
|
|
|
+ .add(e.getPackageCode()).add(File.separator)
|
|
|
+ .add(e.getCourseNameCode()).add(SystemConstant.HYPHEN)
|
|
|
+ .add(e.getPaperNumber()).add(SystemConstant.HYPHEN);
|
|
|
+ //试卷合并文件
|
|
|
+ if (Objects.nonNull(e.getAttachmentId())) {
|
|
|
+ BasicAttachment attachment = basicAttachmentService.getById(e.getAttachmentId());
|
|
|
+ if (attachment != null) {
|
|
|
+ String fileName = dirPath + PdfTypeEnum.PAPER.getTitle() + SystemConstant.PDF_PREFIX;
|
|
|
+ File paperFile = fileUploadService.downloadFile(attachment, fileName);
|
|
|
+ if (Objects.nonNull(paperFile)) {
|
|
|
+ sourceFileList.add(paperFile);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //题卡合并文件
|
|
|
+ if (Objects.nonNull(e.getCardAttachmentId())) {
|
|
|
+ BasicAttachment cardAttachment = basicAttachmentService.getById(e.getCardAttachmentId());
|
|
|
+ if (cardAttachment != null) {
|
|
|
+ String fileName = dirPath + PdfTypeEnum.CARD_A3.getTitle() + SystemConstant.PDF_PREFIX;
|
|
|
+ File cardFile = fileUploadService.downloadFile(cardAttachment, fileName);
|
|
|
+ if (Objects.nonNull(cardFile)) {
|
|
|
+ sourceFileList.add(cardFile);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //卷袋贴/签到表/登记表文件
|
|
|
+ if (Objects.nonNull(e.getAttachmentPath())) {
|
|
|
+ JSONObject js = JSONObject.parseObject(e.getAttachmentPath());
|
|
|
+ List<PrintPathVo> printPathVoList = JSON.parseArray(js.getString(SystemConstant.PATH), PrintPathVo.class);
|
|
|
+ for (PrintPathVo pathVo : printPathVoList) {
|
|
|
+ String fileName = dirPath + pathVo.getPrintType().getName() + SystemConstant.PDF_PREFIX;
|
|
|
+ File cardFile = fileUploadService.downloadFile(pathVo.getType(), pathVo.getUploadType(), pathVo.getPdfPath(), fileName);
|
|
|
+ if (Objects.nonNull(cardFile)) {
|
|
|
+ sourceFileList.add(cardFile);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!CollectionUtils.isEmpty(sourceFileList)) {
|
|
|
+ boolean oss = dictionaryConfig.sysDomain().isOss();
|
|
|
+ StringJoiner stringJoiner = new StringJoiner("");
|
|
|
+ if (!oss && Objects.nonNull(dictionaryConfig.fssPublicDomain()) && !StringUtils.isBlank(dictionaryConfig.fssPublicDomain().getConfig()) && !dictionaryConfig.fssPublicDomain().getConfig().startsWith(SystemConstant.START_PARENT)) {
|
|
|
+ stringJoiner.add(dictionaryConfig.fssPublicDomain().getConfig()).add(File.separator);
|
|
|
+ }
|
|
|
+ stringJoiner = SystemConstant.getDirName(stringJoiner, UploadFileEnum.FILE, true);
|
|
|
+ stringJoiner.add("印刷任务管理_批量下载PDF_" + time).add(SystemConstant.ZIP_PREFIX);
|
|
|
+ String zipDirName = FileUtil.replaceSplit(stringJoiner.toString());
|
|
|
+ JSONObject jsonObject = SystemConstant.createZip(zipFile, zipLocalRootPath, zipDirName);
|
|
|
+ tbTask.setResultFilePath(jsonObject.toJSONString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ map.put(SystemConstant.SIZE, Objects.nonNull(sourceFileList) ? sourceFileList.size() : 0);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(SystemConstant.LOG_ERROR, e);
|
|
|
+ if (e instanceof ApiException) {
|
|
|
+ ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
|
|
|
+ } else {
|
|
|
+ ResultUtil.error(e.getMessage());
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ if (Objects.nonNull(zipFile)) {
|
|
|
+ zipFile.delete();
|
|
|
+ }
|
|
|
+ if (Objects.nonNull(zipLocalRootPath)) {
|
|
|
+ ConvertUtil.delFolder(zipLocalRootPath);
|
|
|
+ }
|
|
|
+ if (!CollectionUtils.isEmpty(sourceFileList)) {
|
|
|
+ for (File file : sourceFileList) {
|
|
|
+ file.delete();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> executeExportPaperAndCardLogic(Map<String, Object> map) {
|
|
|
+ String zipLocalRootPath = null;
|
|
|
+ File zipFile = null;
|
|
|
+ List<File> sourceFileList = null;
|
|
|
+ try {
|
|
|
+ sourceFileList = new ArrayList<>();
|
|
|
+ TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
|
|
|
+
|
|
|
+ Long time = System.currentTimeMillis();
|
|
|
+ boolean oss = dictionaryConfig.sysDomain().isOss();
|
|
|
+ StringJoiner stringJoiner = new StringJoiner("");
|
|
|
+ if (!oss && Objects.nonNull(dictionaryConfig.fssPublicDomain()) && !StringUtils.isBlank(dictionaryConfig.fssPublicDomain().getConfig()) && !dictionaryConfig.fssPublicDomain().getConfig().startsWith(SystemConstant.START_PARENT)) {
|
|
|
+ stringJoiner.add(dictionaryConfig.fssPublicDomain().getConfig()).add(File.separator);
|
|
|
+ }
|
|
|
+ stringJoiner = SystemConstant.getDirName(stringJoiner, UploadFileEnum.FILE, true);
|
|
|
+ stringJoiner.add("卷库查询管理试卷、空白题卡批量下载_" + time).add(SystemConstant.ZIP_PREFIX);
|
|
|
+
|
|
|
+ String zipDirName = FileUtil.replaceSplit(stringJoiner.toString());
|
|
|
+ zipFile = SystemConstant.getFileTempDirVar(SystemConstant.ZIP_PREFIX);
|
|
|
+ zipLocalRootPath = zipFile.getParent() + File.separator + time;
|
|
|
+
|
|
|
+ List<ExamTaskDetailDto> examTasks = (List<ExamTaskDetailDto>) map.get("examTasks");
|
|
|
+ for (ExamTaskDetailDto examTask : examTasks) {
|
|
|
+ ExamTaskDetailPdfDownloadDto examTaskDetailPdfDownloadDto = examTaskDetailService.findPdfDownload(Long.valueOf(examTask.getId()));
|
|
|
+
|
|
|
+ StringJoiner dirPath = new StringJoiner("");
|
|
|
+ dirPath = dirPath.add(zipLocalRootPath).add(File.separator)
|
|
|
+ .add(examTaskDetailPdfDownloadDto.getSemesterName()).add(File.separator)
|
|
|
+ .add(examTaskDetailPdfDownloadDto.getExamName()).add(File.separator)
|
|
|
+ .add(examTaskDetailPdfDownloadDto.getCourseNameCode().replaceAll(" ", "")).add(File.separator)
|
|
|
+ .add(examTaskDetailPdfDownloadDto.getPaperNumber()).add(File.separator)
|
|
|
+ .add(examTaskDetailPdfDownloadDto.getCourseNameCode().replaceAll(" ", "")).add(SystemConstant.HYPHEN)
|
|
|
+ .add(examTaskDetailPdfDownloadDto.getPaperNumber()).add(SystemConstant.HYPHEN);
|
|
|
+ // 试卷
|
|
|
+ String paperAttachmentIds = examTaskDetailPdfDownloadDto.getPaperAttachmentIds();
|
|
|
+ if (StringUtils.isNotBlank(paperAttachmentIds)) {
|
|
|
+ List<PaperInfoVo> paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(paperAttachmentIds);
|
|
|
+ if (CollectionUtils.isEmpty(paperInfoVoList)) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("试卷信息不存在");
|
|
|
+ }
|
|
|
+ for (PaperInfoVo paperInfoVo : paperInfoVoList) {
|
|
|
+ Long attachmentId = Long.valueOf(paperInfoVo.getAttachmentId());
|
|
|
+ String name = paperInfoVo.getName();
|
|
|
+ if (Objects.nonNull(attachmentId)) {
|
|
|
+ BasicAttachment attachment = basicAttachmentService.getById(attachmentId);
|
|
|
+ if (Objects.nonNull(attachment)) {
|
|
|
+ String fileName = dirPath + "试卷" + SystemConstant.HYPHEN + name + attachment.getType();
|
|
|
+ File paperFile = fileUploadService.downloadFile(attachment, fileName);
|
|
|
+ sourceFileList.add(paperFile);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Long cardId = Long.valueOf(paperInfoVo.getCardId());
|
|
|
+ ExamCard examCard = examCardService.getById(cardId);
|
|
|
+ Optional.ofNullable(examCard).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("找不到答题卡"));
|
|
|
+
|
|
|
+ String cardHtmlPath = dirPath + "题卡" + SystemConstant.HYPHEN + name + SystemConstant.HTML_PREFIX;
|
|
|
+ String cardPdfPath = dirPath + "题卡" + SystemConstant.HYPHEN + name + SystemConstant.PDF_PREFIX;
|
|
|
+ // 通用题卡
|
|
|
+ String htmlContent = createPdfUtil.replaceBlankHtmlContent(examCard.getHtmlContent(), examCard.getCourseId());
|
|
|
+ // html
|
|
|
+ File localFile = new File(cardHtmlPath);
|
|
|
+ if (!localFile.exists()) {
|
|
|
+ localFile.getParentFile().mkdirs();
|
|
|
+ localFile.createNewFile();
|
|
|
+ }
|
|
|
+ // 生成html文件
|
|
|
+ FileCopyUtils.copy(htmlContent.getBytes(StandardCharsets.UTF_8), localFile);
|
|
|
+ sourceFileList.add(localFile);
|
|
|
+ // 转pdf文件
|
|
|
+ File file = new File(cardPdfPath);
|
|
|
+ if (!file.exists()) {
|
|
|
+ file.getParentFile().mkdirs();
|
|
|
+ file.createNewFile();
|
|
|
+ }
|
|
|
+ HtmlToPdfUtil.convert(cardHtmlPath, cardPdfPath, PageSizeEnum.A3);
|
|
|
+ sourceFileList.add(file);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ JSONObject jsonObject = SystemConstant.createZip(zipFile, zipLocalRootPath, zipDirName);
|
|
|
+ tbTask.setResultFilePath(jsonObject.toJSONString());
|
|
|
+ map.put(SystemConstant.DATA_COUNT, examTasks.size());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(SystemConstant.LOG_ERROR, e);
|
|
|
+ if (e instanceof ApiException) {
|
|
|
+ ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
|
|
|
+ } else {
|
|
|
+ ResultUtil.error(e.getMessage());
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ if (Objects.nonNull(zipFile)) {
|
|
|
+ zipFile.delete();
|
|
|
+ }
|
|
|
+ if (Objects.nonNull(zipLocalRootPath)) {
|
|
|
+ ConvertUtil.delFolder(zipLocalRootPath);
|
|
|
+ }
|
|
|
+ if (!CollectionUtils.isEmpty(sourceFileList)) {
|
|
|
+ for (File file : sourceFileList) {
|
|
|
+ file.delete();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Transactional
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> executeImportSysUserLogic(Map<String, Object> map) throws Exception {
|
|
|
+ InputStream inputStream = (InputStream) map.get("inputStream");
|
|
|
+
|
|
|
+ List<SysUserErrorExportDto> errorDataList = new ArrayList<>();
|
|
|
+ AtomicInteger totalInteger = new AtomicInteger(0);
|
|
|
+ AtomicInteger successInteger = new AtomicInteger(0);
|
|
|
+ List<LinkedMultiValueMap<Integer, Object>> finalList = ExcelUtil.excelReader(inputStream, Lists.newArrayList(SysUserImportDto.class, DescribeImportDto.class), (finalExcelList, finalColumnNameList, finalExcelErrorList) -> {
|
|
|
+ Map<String, SysUserImportDto> checkDtoMap = new HashMap<>();
|
|
|
+
|
|
|
+ for (int i = 0; i < finalExcelList.size(); i++) {
|
|
|
+ LinkedMultiValueMap<Integer, Object> excelMap = finalExcelList.get(i);
|
|
|
+ List<Object> sysUserImportDtoList = excelMap.get(i);
|
|
|
+ if (CollectionUtils.isEmpty(sysUserImportDtoList)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ map.put(SystemConstant.DATA_COUNT, sysUserImportDtoList.size());
|
|
|
+ List<SysUserImportDto> removeDataList = new ArrayList<>();
|
|
|
+ Map<String, Integer> phoneNumberMap = new HashMap<>();
|
|
|
+ for (int y = 0; y < Objects.requireNonNull(sysUserImportDtoList).size(); y++) {
|
|
|
+ SysUserImportDto sysUserImportDto = (SysUserImportDto) sysUserImportDtoList.get(y);
|
|
|
+ totalInteger.getAndIncrement();
|
|
|
+ SysUserErrorExportDto sysUserErrorExportDto = new SysUserErrorExportDto();
|
|
|
+ BeanUtils.copyProperties(sysUserImportDto, sysUserErrorExportDto);
|
|
|
+
|
|
|
+ String name = sysUserImportDto.getName();
|
|
|
+ String loginName = sysUserImportDto.getLoginName();
|
|
|
+ String phoneNumber = sysUserImportDto.getPhoneNumber();
|
|
|
+ String orgName = sysUserImportDto.getOrgName();
|
|
|
+ String roleName = sysUserImportDto.getRoleName();
|
|
|
+
|
|
|
+ StringJoiner errorStringJoiner = new StringJoiner(";");
|
|
|
+ String errorStringEmpty = ExcelUtil.checkExcelField(sysUserImportDto);
|
|
|
+ if (errorStringEmpty.length() > 0) {
|
|
|
+ errorStringJoiner.add(errorStringEmpty);
|
|
|
+ }
|
|
|
+ if (checkDtoMap.containsKey(loginName)) {
|
|
|
+ SysUserImportDto primaryCell = checkDtoMap.get(loginName);
|
|
|
+ String priName = primaryCell.getName();
|
|
|
+ String priPhoneNumber = primaryCell.getPhoneNumber();
|
|
|
+ String priOrgName = primaryCell.getOrgName();
|
|
|
+ if (!Objects.equals(priName, name)) {
|
|
|
+ errorStringJoiner.add("用户名/工号[" + loginName + "]的用户存在不同的姓名");
|
|
|
+ }
|
|
|
+ if (!Objects.equals(priPhoneNumber, phoneNumber)) {
|
|
|
+ errorStringJoiner.add("用户名/工号[" + loginName + "]的用户存在不同的手机号");
|
|
|
+ }
|
|
|
+ if (!Objects.equals(priOrgName, orgName)) {
|
|
|
+ errorStringJoiner.add("用户名/工号[" + loginName + "]的用户存在不同的组织架构");
|
|
|
+ }
|
|
|
+ String priRoleName = primaryCell.getRoleName();
|
|
|
+ if (SystemConstant.strNotNull(roleName)) {
|
|
|
+ priRoleName = priRoleName + SystemConstant.COMMA + roleName;
|
|
|
+ primaryCell.setRoleName(priRoleName);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ checkDtoMap.put(loginName, sysUserImportDto);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StringUtils.isNotBlank(loginName) && !loginName.matches(SystemConstant.REGULAR_EXPRESSION_OF_CODE)) {
|
|
|
+ errorStringJoiner.add("用户名/工号[" + loginName + "]不符合规范");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(phoneNumber) && !phoneNumber.matches(SystemConstant.REGULAR_EXPRESSION_OF_PHONE)) {
|
|
|
+ errorStringJoiner.add("手机号[" + phoneNumber + "]不符合输入规范");
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(phoneNumber)) {
|
|
|
+ if (phoneNumberMap.containsKey(phoneNumber)) {
|
|
|
+ errorStringJoiner.add("手机号[" + phoneNumber + "]在文件中重复");
|
|
|
+ } else {
|
|
|
+ phoneNumberMap.put(phoneNumber, y);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String errorString = errorStringJoiner.toString();
|
|
|
+ if (errorString.length() > 0) {
|
|
|
+ sysUserErrorExportDto.setErrorMsg(errorString);
|
|
|
+ errorDataList.add(sysUserErrorExportDto);
|
|
|
+ removeDataList.add(sysUserImportDto);
|
|
|
+ } else {
|
|
|
+ // 校验通过的数据
|
|
|
+ successInteger.getAndIncrement();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ sysUserImportDtoList.removeAll(removeDataList);
|
|
|
+ }
|
|
|
+ if (!errorDataList.isEmpty()) {
|
|
|
+ map.put(SystemConstant.ERROR_DATA_LIST, errorDataList);
|
|
|
+ }
|
|
|
+ map.put(SystemConstant.DATA_COUNT, totalInteger.get());
|
|
|
+ map.put(SystemConstant.SUCCESS_DATA_COUNT, successInteger.get());
|
|
|
+ map.put(SystemConstant.ERROR_DATA_COUNT, errorDataList.size());
|
|
|
+ return finalExcelList;
|
|
|
+ }, 2);
|
|
|
+ return sysUserService.executeSysUserImportLogic(finalList, map);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional
|
|
|
+ public Map<String, Object> executeImportStatisticsLogic(Map<String, Object> map) throws Exception {
|
|
|
+ InputStream inputStream = (InputStream) map.get("inputStream");
|
|
|
+ Long examId = SystemConstant.convertIdToLong(String.valueOf(map.get("examId")));
|
|
|
+ SysUser sysUser = (SysUser) map.get(SystemConstant.USER);
|
|
|
+
|
|
|
+ List<LinkedMultiValueMap<Integer, Object>> finalList = ExcelUtil.excelReader(inputStream, Lists.newArrayList(StatisticsImportDto.class), (finalExcelList, finalColumnNameList, finalExcelErrorList) -> {
|
|
|
+ // 只允许导入一个sheet
|
|
|
+ if (finalExcelList.size() > 1) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("excel中只允许有一个sheet");
|
|
|
+ }
|
|
|
+ if (finalExcelErrorList.size() > 0) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception(JSONObject.toJSONString(finalExcelErrorList));
|
|
|
+ }
|
|
|
+ List<ExcelError> excelErrorTemp = new ArrayList<>();
|
|
|
+ // 校验系统中是否存在
|
|
|
+ Map<String, SysOrg> collegeOrgMap = new HashMap<>();
|
|
|
+ Map<String, SysOrg> teachingRoomMap = new HashMap<>();
|
|
|
+ Map<String, BasicCourse> courseMap = new HashMap<>();
|
|
|
+ Map<String, DictionaryResult> clazzMap = new HashMap<>();
|
|
|
+ String batchNo = SystemConstant.getNanoId();
|
|
|
+ List<TCStatisticsTemp> tcStatisticsImportTempList = new ArrayList<>();
|
|
|
+
|
|
|
+ for (int i = 0; i < finalExcelList.size(); i++) {
|
|
|
+ LinkedMultiValueMap<Integer, Object> excelMap = finalExcelList.get(i);
|
|
|
+ List<Object> statisticsTempList = excelMap.get(i);
|
|
|
+ for (int y = 0; y < Objects.requireNonNull(statisticsTempList).size(); y++) {
|
|
|
+ StatisticsImportDto statisticsImportDto = (StatisticsImportDto) statisticsTempList.get(y);
|
|
|
+ SysOrg collegeOrg = this.validSysOrgExists(collegeOrgMap, statisticsImportDto.getCollegeName(), sysUser.getSchoolId(), excelErrorTemp, (y + 1), (i + 1), "开课学院");
|
|
|
+ SysOrg teachingRoomOrg = this.validSysOrgExists(teachingRoomMap, statisticsImportDto.getTeachingRoomName(), sysUser.getSchoolId(), excelErrorTemp, (y + 1), (i + 1), "开课学院");
|
|
|
+ BasicCourse basicCourse = this.validBasicCourseExists(courseMap, statisticsImportDto.getCourseName(), sysUser.getSchoolId(), statisticsImportDto.getCourseCode(), excelErrorTemp, (y + 1), (i + 1));
|
|
|
+ String teacherName = statisticsImportDto.getTeacherName();
|
|
|
+ String clazzNames = statisticsImportDto.getClazzName();
|
|
|
+ List<DictionaryResult> dictionaryResultList = new ArrayList<>();
|
|
|
+ for (String clazzName : clazzNames.split(",")) {
|
|
|
+ DictionaryResult clazz = this.validBasicClazzExists(clazzMap, clazzName, sysUser.getSchoolId(), excelErrorTemp, (y + 1), (i + 1));
|
|
|
+ dictionaryResultList.add(clazz);
|
|
|
+ }
|
|
|
+ String clazzIds = dictionaryResultList.stream().map(e -> String.valueOf(e.getId())).collect(Collectors.joining(","));
|
|
|
+
|
|
|
+
|
|
|
+ if (excelErrorTemp.size() == 0) {
|
|
|
+
|
|
|
+ TCStatisticsTemp tcStatistics = new TCStatisticsTemp(
|
|
|
+ examId,
|
|
|
+ collegeOrg.getId(),
|
|
|
+ collegeOrg.getName(),
|
|
|
+ teachingRoomOrg.getId(),
|
|
|
+ teachingRoomOrg.getName(),
|
|
|
+ basicCourse.getName(),
|
|
|
+ basicCourse.getCode(),
|
|
|
+ teacherName,
|
|
|
+ clazzIds,
|
|
|
+ clazzNames,
|
|
|
+ batchNo,
|
|
|
+ sysUser.getId());
|
|
|
+ tcStatisticsImportTempList.add(tcStatistics);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (excelErrorTemp.size() > 0) {
|
|
|
+ List<String> errors = excelErrorTemp.stream().map(ExcelError::getExcelErrorType).collect(Collectors.toList());
|
|
|
+ throw ExceptionResultEnum.ERROR.exception(JSONObject.toJSONString(errors));
|
|
|
+ }
|
|
|
+ //加入删除(根据考试id和当前登录人)
|
|
|
+ tcStatisticsService.removeImportData(examId, sysUser.getId());
|
|
|
+ tcStatisticsTempService.saveBatch(tcStatisticsImportTempList);
|
|
|
+ map.put("dataCount", tcStatisticsImportTempList.size());
|
|
|
+ tcStatisticsService.importJoinData(tcStatisticsImportTempList);
|
|
|
+ tcStatisticsTempService.removeByIds(tcStatisticsImportTempList.stream().map(BaseEntity::getId).collect(Collectors.toSet()));
|
|
|
+ return finalExcelList;
|
|
|
+ }, 2);
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 成绩导出
|
|
|
+ *
|
|
|
+ * @param map
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> executeExportScoreLogic(Map<String, Object> map) throws Exception {
|
|
|
+ ByteArrayOutputStream fos = null;
|
|
|
+ try {
|
|
|
+ SysUser sysUser = (SysUser) map.get(SystemConstant.USER);
|
|
|
+ Long semesterId = null, examId = null, clazzId = null;
|
|
|
+ String courseCode = null;
|
|
|
+ semesterId = Objects.nonNull(map.get("semesterId")) ? Long.valueOf(map.get("semesterId").toString()) : null;
|
|
|
+ examId = Objects.nonNull(map.get("examId")) ? Long.valueOf(map.get("examId").toString()) : null;
|
|
|
+ clazzId = Objects.nonNull(map.get("clazzId")) ? Long.valueOf(map.get("clazzId").toString()) : null;
|
|
|
+ courseCode = Objects.nonNull(map.get("courseCode")) ? (String) map.get("courseCode") : null;
|
|
|
+ String servletPath = Objects.nonNull(map.get("servletPath")) ? (String) map.get("servletPath") : null;
|
|
|
+
|
|
|
+ fos = new ByteArrayOutputStream();
|
|
|
+ List<TSyncExamStudentScoreResult> tSyncExamStudentScoreResultList = tSyncExamStudentScoreService.export(sysUser, semesterId, examId, clazzId, courseCode, servletPath);
|
|
|
+ ExcelUtil.excelMake(TSyncExamStudentScoreResult.class, tSyncExamStudentScoreResultList, fos);
|
|
|
+ String excelExportFilePath = printCommonService.saveTaskAttachment(fos, (boolean) map.get(SystemConstant.OSS));
|
|
|
+ map.computeIfAbsent("count", v -> Objects.isNull(tSyncExamStudentScoreResultList) ? 0 : tSyncExamStudentScoreResultList.size());
|
|
|
+ TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
|
|
|
+ tbTask.setResultFilePath(excelExportFilePath);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(SystemConstant.LOG_ERROR, e);
|
|
|
+ } finally {
|
|
|
+ if (Objects.nonNull(fos)) {
|
|
|
+ fos.flush();
|
|
|
+ fos.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 成绩轨迹下载
|
|
|
+ *
|
|
|
+ * @param map
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional
|
|
|
+ public Map<String, Object> executeDownloadScoreLogic(Map<String, Object> map) throws Exception {
|
|
|
+ File zipFile = null;
|
|
|
+ List<File> sourceFiles = null;
|
|
|
+ List<TSyncExamStudentScore> errorTSyncExamStudentScoreList = null;
|
|
|
+ boolean oss = dictionaryConfig.sysDomain().isOss();
|
|
|
+ try {
|
|
|
+ SysUser sysUser = (SysUser) map.get(SystemConstant.USER);
|
|
|
+ Long semesterId = null, examId = null, clazzId = null;
|
|
|
+ String courseCode = null;
|
|
|
+ semesterId = Objects.nonNull(map.get("semesterId")) ? (Long) map.get("semesterId") : null;
|
|
|
+ examId = Objects.nonNull(map.get("examId")) ? (Long) map.get("examId") : null;
|
|
|
+ clazzId = Objects.nonNull(map.get("clazzId")) ? (Long) map.get("clazzId") : null;
|
|
|
+ courseCode = Objects.nonNull(map.get("courseCode")) ? (String) map.get("courseCode") : null;
|
|
|
+
|
|
|
+ String servletPath = Objects.nonNull(map.get("servletPath")) ? (String) map.get("servletPath") : null;
|
|
|
+
|
|
|
+ List<TSyncExamStudentScoreResult> tSyncExamStudentScoreResultList = tSyncExamStudentScoreService.export(sysUser, semesterId, examId, clazzId, courseCode, servletPath);
|
|
|
+ if (Objects.nonNull(tSyncExamStudentScoreResultList) && tSyncExamStudentScoreResultList.size() > 0) {
|
|
|
+ List<TSyncExamStudentScore> tSyncExamStudentScoreList = new Gson().fromJson(JacksonUtil.parseJson(tSyncExamStudentScoreResultList), new TypeToken<List<TSyncExamStudentScore>>() {
|
|
|
+ }.getType());
|
|
|
+ Long time = System.currentTimeMillis();
|
|
|
+ StringJoiner stringJoiner = new StringJoiner("");
|
|
|
+ if (!oss && Objects.nonNull(dictionaryConfig.fssPublicDomain()) && !StringUtils.isBlank(dictionaryConfig.fssPublicDomain().getConfig()) && !dictionaryConfig.fssPublicDomain().getConfig().startsWith(SystemConstant.START_PARENT)) {
|
|
|
+ stringJoiner.add(dictionaryConfig.fssPublicDomain().getConfig()).add(File.separator);
|
|
|
+ }
|
|
|
+ stringJoiner = SystemConstant.getDirName(stringJoiner, UploadFileEnum.FILE, true);
|
|
|
+ stringJoiner.add("成绩轨迹下载_" + time).add(SystemConstant.ZIP_PREFIX);
|
|
|
+
|
|
|
+ String zipDirName = FileUtil.replaceSplit(stringJoiner.toString());
|
|
|
+ zipFile = SystemConstant.getFileTempDirVar(SystemConstant.ZIP_PREFIX);
|
|
|
+
|
|
|
+ sourceFiles = new LinkedList<>();
|
|
|
+ List<TSyncExamStudentScore> updateTSyncExamStudentScoreList = new ArrayList<>();
|
|
|
+ errorTSyncExamStudentScoreList = new ArrayList<>();
|
|
|
+ for (TSyncExamStudentScore t : tSyncExamStudentScoreList) {
|
|
|
+ try {
|
|
|
+ boolean update = Objects.isNull(t.getTrajectoryUrls()) ? true : false;
|
|
|
+ t = tSyncExamStudentScoreService.createImageTrajectory(t, ImageTrajectoryEnum.DOWNLOAD, false, sysUser.getId());
|
|
|
+ if (Objects.nonNull(t.getTrajectoryFileList())) {
|
|
|
+ sourceFiles.addAll(t.getTrajectoryFileList());
|
|
|
+ } else {
|
|
|
+ errorTSyncExamStudentScoreList.add(t);
|
|
|
+ }
|
|
|
+ if (update || Objects.isNull(t.getTrajectoryUrls())) {
|
|
|
+ updateTSyncExamStudentScoreList.add(t);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(SystemConstant.LOG_ERROR, e);
|
|
|
+ errorTSyncExamStudentScoreList.add(t);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ tSyncExamStudentScoreService.saveOrUpdateBatch(updateTSyncExamStudentScoreList);
|
|
|
+ if (!sourceFiles.isEmpty()) {
|
|
|
+ JSONObject jsonObject = SystemConstant.createZip(zipFile, sourceFiles, zipDirName);
|
|
|
+ TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
|
|
|
+ tbTask.setResultFilePath(jsonObject.toJSONString());
|
|
|
+ } else {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("阅卷方式未使用轨迹阅卷,无轨迹图");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("没有可下载数据");
|
|
|
+ }
|
|
|
+ map.computeIfAbsent("count", v -> tSyncExamStudentScoreResultList.size());
|
|
|
+ if (Objects.nonNull(errorTSyncExamStudentScoreList) && errorTSyncExamStudentScoreList.size() > 0) {
|
|
|
+ StringJoiner stringJoiner = new StringJoiner("").add("\r\n");
|
|
|
+ for (TSyncExamStudentScore t : errorTSyncExamStudentScoreList) {
|
|
|
+ stringJoiner.add("[").add(t.getName()).add(",").add(t.getExamNumber()).add("]\r\n");
|
|
|
+ }
|
|
|
+ List<TSyncExamStudentScore> finalErrorTSyncExamStudentScoreList = errorTSyncExamStudentScoreList;
|
|
|
+ map.computeIfAbsent("error", v -> "其中未下载成功数据" + finalErrorTSyncExamStudentScoreList.size() + "条:" + stringJoiner.toString());
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(SystemConstant.LOG_ERROR, e);
|
|
|
+ if (e instanceof ApiException) {
|
|
|
+ ResultUtil.error((ApiException) e, e.getMessage());
|
|
|
+ } else {
|
|
|
+ ResultUtil.error(e.getMessage());
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ if (Objects.nonNull(zipFile)) {
|
|
|
+ zipFile.delete();
|
|
|
+ }
|
|
|
+ if (oss && !CollectionUtils.isEmpty(sourceFiles)) {
|
|
|
+ for (File f : sourceFiles) {
|
|
|
+ f.delete();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> executeDownloadPaperFileBatch(Map<String, Object> map) {
|
|
|
+ TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
|
|
|
+ DownloadPaperFileParam downloadPaperFileParam = (DownloadPaperFileParam) map.get("downloadPaperFileParam");
|
|
|
+ Long semesterId = downloadPaperFileParam.getSemesterId();
|
|
|
+ Long examId = downloadPaperFileParam.getExamId();
|
|
|
+ Long orgId = downloadPaperFileParam.getOrgId();
|
|
|
+ PaperFileDownloadContentEnum paperFileDownloadContent = downloadPaperFileParam.getPaperFileDownloadContentType();
|
|
|
+ if (paperFileDownloadContent == null) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("请选择下载文件");
|
|
|
+ }
|
|
|
+ PaperFileDownloadExposureStatusEnum paperFileDownloadExposureStatus = downloadPaperFileParam.getPaperFileDownloadExposureStatus();
|
|
|
+ if ((PaperFileDownloadContentEnum.ONLY_PAPER.equals(paperFileDownloadContent) || PaperFileDownloadContentEnum.PAPER_AND_CARD.equals(paperFileDownloadContent)) && Objects.isNull(paperFileDownloadExposureStatus)) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("请选择试卷状态");
|
|
|
+ }
|
|
|
+ Boolean namedByCourseInfo = downloadPaperFileParam.getNamedByCourseInfo();
|
|
|
+ Boolean namedByPaperNumber = downloadPaperFileParam.getNamedByPaperNumber();
|
|
|
+ Boolean namedByOriginalFile = downloadPaperFileParam.getNamedByOriginalFile();
|
|
|
+ if (!namedByCourseInfo && !namedByPaperNumber && !namedByOriginalFile) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception("请选择至少一种命名规则");
|
|
|
+ }
|
|
|
+
|
|
|
+ String courseName = downloadPaperFileParam.getCourseName();
|
|
|
+ Set<Long> idSet = downloadPaperFileParam.getIdSet();
|
|
|
+
|
|
|
+ File zipFile = null;
|
|
|
+ String zipLocalRootPath = null;
|
|
|
+ try {
|
|
|
+ boolean oss = dictionaryConfig.sysDomain().isOss();
|
|
|
+ StringJoiner stringJoiner = new StringJoiner("");
|
|
|
+ if (!oss && Objects.nonNull(dictionaryConfig.fssPublicDomain()) && !StringUtils.isBlank(dictionaryConfig.fssPublicDomain().getConfig()) && !dictionaryConfig.fssPublicDomain().getConfig().startsWith(SystemConstant.START_PARENT)) {
|
|
|
+ stringJoiner.add(dictionaryConfig.fssPublicDomain().getConfig()).add(File.separator);
|
|
|
+ }
|
|
|
+ stringJoiner = SystemConstant.getDirName(stringJoiner, UploadFileEnum.FILE, true);
|
|
|
+ stringJoiner.add("批量下载文件_" + System.currentTimeMillis()).add(SystemConstant.ZIP_PREFIX);
|
|
|
+
|
|
|
+ String zipDirName = FileUtil.replaceSplit(stringJoiner.toString());
|
|
|
+ zipFile = SystemConstant.getFileTempDirVarForZip(SystemConstant.getNanoId(), SystemConstant.ZIP_PREFIX);
|
|
|
+ zipLocalRootPath = zipFile.getParent() + File.separator + System.currentTimeMillis();
|
|
|
+
|
|
|
+ boolean downloadPaper = paperFileDownloadContent != null && (PaperFileDownloadContentEnum.ONLY_PAPER.equals(paperFileDownloadContent) || PaperFileDownloadContentEnum.PAPER_AND_CARD.equals(paperFileDownloadContent));
|
|
|
+ boolean downloadCard = paperFileDownloadContent != null && (PaperFileDownloadContentEnum.ONLY_CARD.equals(paperFileDownloadContent) || PaperFileDownloadContentEnum.PAPER_AND_CARD.equals(paperFileDownloadContent));
|
|
|
+
|
|
|
+ SysUser requestUser = (SysUser) map.get(SystemConstant.USER);
|
|
|
+ DataPermissionRule dpr = null;
|
|
|
+ if (CollectionUtils.isEmpty(idSet)) {
|
|
|
+ dpr = basicRoleDataPermissionService.findDataPermission(653L, requestUser);
|
|
|
+ }
|
|
|
+ // 查询待下载数据
|
|
|
+ List<ExamTaskDetailDto> examTaskDetailDtoList = downloadService.listExamQuery(semesterId, examId, orgId, courseName, idSet, dpr);
|
|
|
+ List<ExamTaskPaperExportDto> examTaskPaperExportDtoList = new ArrayList<>();
|
|
|
+ for (ExamTaskDetailDto examTaskDetailDto : examTaskDetailDtoList) {
|
|
|
+ ExamTaskPaperExportDto examTaskPaperExportDto = new ExamTaskPaperExportDto(examTaskDetailDto);
|
|
|
+ examTaskPaperExportDtoList.add(examTaskPaperExportDto);
|
|
|
+ List<PaperInfoVo> paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(examTaskDetailDto.getPaperAttachmentIds());
|
|
|
+ // 选择曝光卷型
|
|
|
+ if (PaperFileDownloadExposureStatusEnum.EXPOSED_PAPER.equals(paperFileDownloadExposureStatus)) {
|
|
|
+ if (StringUtils.isBlank(examTaskDetailDto.getExposedPaperType())) {
|
|
|
+ examTaskPaperExportDto.setResult("没有曝光卷型,下载失败");
|
|
|
+ continue;
|
|
|
+ } else {
|
|
|
+ paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(examTaskDetailDto.getPaperAttachmentIds(), examTaskDetailDto.getExposedPaperType());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 选择未曝光卷型
|
|
|
+ if (PaperFileDownloadExposureStatusEnum.UNEXPOSED_PAPER.equals(paperFileDownloadExposureStatus)) {
|
|
|
+ if (StringUtils.isBlank(examTaskDetailDto.getUnexposedPaperType())) {
|
|
|
+ examTaskPaperExportDto.setResult("没有未曝光卷型,下载失败");
|
|
|
+ continue;
|
|
|
+ } else {
|
|
|
+ paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(examTaskDetailDto.getPaperAttachmentIds(), examTaskDetailDto.getUnexposedPaperType());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (CollectionUtils.isEmpty(paperInfoVoList)) {
|
|
|
+ examTaskPaperExportDto.setResult("所选试卷状态未查询到上传的试卷信息,下载失败");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 命名规则
|
|
|
+ StringJoiner sj = new StringJoiner(SystemConstant.HYPHEN);
|
|
|
+ if (namedByCourseInfo) {
|
|
|
+ sj.add(examTaskDetailDto.getCourseName()).add(examTaskDetailDto.getCourseCode());
|
|
|
+ }
|
|
|
+ if (namedByPaperNumber) {
|
|
|
+ sj.add(examTaskDetailDto.getPaperNumber());
|
|
|
+ }
|
|
|
+ String fileNamePath = sj.toString();
|
|
|
+
|
|
|
+ // 目录规则(课程名称(课程代码)/试卷编号)
|
|
|
+ String secondPath = examTaskDetailDto.getCourseName() + SystemConstant.HYPHEN + examTaskDetailDto.getCourseCode() + File.separator + examTaskDetailDto.getPaperNumber();
|
|
|
+ for (PaperInfoVo paperInfoVo : paperInfoVoList) {
|
|
|
+ // 下载试卷
|
|
|
+ if (downloadPaper) {
|
|
|
+ // 不管什么命名规则,默认都加上卷型前缀
|
|
|
+ String paperFileNamePath = "试卷" + SystemConstant.HYPHEN + paperInfoVo.getName() + SystemConstant.HYPHEN + fileNamePath;
|
|
|
+ // 原文件名
|
|
|
+ if (namedByOriginalFile) {
|
|
|
+ paperFileNamePath = paperFileNamePath + SystemConstant.HYPHEN + paperInfoVo.getFilename();
|
|
|
+ } else {
|
|
|
+ paperFileNamePath = paperFileNamePath + "." + FilenameUtils.getExtension(paperInfoVo.getFilename());
|
|
|
+ }
|
|
|
+ Long attachmentId = Long.valueOf(paperInfoVo.getAttachmentId());
|
|
|
+ if (Objects.nonNull(attachmentId)) {
|
|
|
+ BasicAttachment attachment = basicAttachmentService.getById(attachmentId);
|
|
|
+ if (Objects.nonNull(attachment)) {
|
|
|
+ String fileName = trimWhiteSpace(zipLocalRootPath + File.separator + secondPath + File.separator + spliceFileName(paperFileNamePath, SystemConstant.PDF_PREFIX));
|
|
|
+ fileUploadService.downloadFile(attachment, fileName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 下载题卡
|
|
|
+ if (downloadCard) {
|
|
|
+ Long cardId = Long.valueOf(paperInfoVo.getCardId());
|
|
|
+ ExamCard examCard = examCardService.getById(cardId);
|
|
|
+ Optional.ofNullable(examCard).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("找不到答题卡"));
|
|
|
+
|
|
|
+ String cardHtmlPath = zipLocalRootPath + File.separator + secondPath + File.separator + "题卡" + SystemConstant.HYPHEN + paperInfoVo.getName() + SystemConstant.HYPHEN + fileNamePath;
|
|
|
+ String cardPdfPath = zipLocalRootPath + File.separator + secondPath + File.separator + "题卡" + SystemConstant.HYPHEN + paperInfoVo.getName() + SystemConstant.HYPHEN + fileNamePath;
|
|
|
+ // 原文件名
|
|
|
+ if (namedByOriginalFile) {
|
|
|
+ cardHtmlPath = trimWhiteSpace(cardHtmlPath + SystemConstant.HYPHEN + examCard.getTitle() + SystemConstant.HTML_PREFIX);
|
|
|
+ cardPdfPath = trimWhiteSpace(cardPdfPath + SystemConstant.HYPHEN + examCard.getTitle() + SystemConstant.PDF_PREFIX);
|
|
|
+ } else {
|
|
|
+ cardHtmlPath = trimWhiteSpace(cardHtmlPath + SystemConstant.HTML_PREFIX);
|
|
|
+ cardPdfPath = trimWhiteSpace(cardPdfPath + SystemConstant.PDF_PREFIX);
|
|
|
+ }
|
|
|
+
|
|
|
+ // html
|
|
|
+ File localFile = new File(cardHtmlPath);
|
|
|
+ if (!localFile.exists()) {
|
|
|
+ localFile.getParentFile().mkdirs();
|
|
|
+ localFile.createNewFile();
|
|
|
+ }
|
|
|
+ // 通用题卡
|
|
|
+ String htmlContent = createPdfUtil.replaceBlankHtmlContent(examCard.getHtmlContent(), examCard.getCourseId());
|
|
|
+ // 生成html文件
|
|
|
+ FileCopyUtils.copy(htmlContent.getBytes(StandardCharsets.UTF_8), localFile);
|
|
|
+ // 转pdf文件
|
|
|
+ File file = new File(cardPdfPath);
|
|
|
+ if (!file.exists()) {
|
|
|
+ file.getParentFile().mkdirs();
|
|
|
+ file.createNewFile();
|
|
|
+ }
|
|
|
+ HtmlToPdfUtil.convert(cardHtmlPath, cardPdfPath, PageSizeEnum.A3);
|
|
|
+ }
|
|
|
+ examTaskPaperExportDto.setResult("下载成功");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 导出文件excel
|
|
|
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
|
+ ExcelUtil.excelMake(ExamTaskPaperExportDto.class, examTaskPaperExportDtoList, outputStream);
|
|
|
+ InputStream in = new ByteArrayInputStream(outputStream.toByteArray());
|
|
|
+
|
|
|
+ String excelLocalPath = zipLocalRootPath + File.separator + "下载清单" + "." + SystemConstant.XLSX;
|
|
|
+ FileUtils.copyInputStreamToFile(in, new File(excelLocalPath));
|
|
|
+ // 所有试卷
|
|
|
+ JSONObject jsonObject = SystemConstant.createZip(zipFile, zipLocalRootPath, zipDirName);
|
|
|
+ tbTask.setResultFilePath(jsonObject.toJSONString());
|
|
|
+ map.put("count", examTaskDetailDtoList.size());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(SystemConstant.LOG_ERROR, e);
|
|
|
+ } finally {
|
|
|
+ if (Objects.nonNull(zipFile)) {
|
|
|
+ zipFile.delete();
|
|
|
+ }
|
|
|
+ if (Objects.nonNull(zipLocalRootPath)) {
|
|
|
+ ConvertUtil.delFolder(zipLocalRootPath);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 验证机构是否存在
|
|
|
+ *
|
|
|
+ * @param orgMap 机构map
|
|
|
+ * @param key 机构名称
|
|
|
+ * @param schoolId 学校id
|
|
|
+ * @param excelErrorTemp 错误信息
|
|
|
+ * @param row 行
|
|
|
+ * @param sheet 区
|
|
|
+ * @param cloumnName cloumnName
|
|
|
+ * @return 机构
|
|
|
+ */
|
|
|
+ private SysOrg validSysOrgExists(Map<String, SysOrg> orgMap,
|
|
|
+ String key,
|
|
|
+ Long schoolId,
|
|
|
+ List<ExcelError> excelErrorTemp,
|
|
|
+ int row,
|
|
|
+ int sheet,
|
|
|
+ String cloumnName) {
|
|
|
+ SysOrg sysOrg = null;
|
|
|
+ if (!orgMap.containsKey(key)) {//不存在查询
|
|
|
+ QueryWrapper<SysOrg> sysOrgQueryWrapper = new QueryWrapper<>();
|
|
|
+ sysOrgQueryWrapper.lambda().eq(SysOrg::getSchoolId, schoolId)
|
|
|
+ .eq(SysOrg::getName, key)
|
|
|
+ .eq(SysOrg::getEnable, true);
|
|
|
+ sysOrg = sysOrgService.getOne(sysOrgQueryWrapper);
|
|
|
+ } else {
|
|
|
+ sysOrg = orgMap.get(key);
|
|
|
+ }
|
|
|
+ if (Objects.isNull(sysOrg)) {
|
|
|
+ excelErrorTemp.add(new ExcelError(row, "excel第" + sheet + "个sheet第" + row + "行[" + cloumnName + "]不存在"));
|
|
|
+ } else {
|
|
|
+ SysOrg finalSysOrg = sysOrg;
|
|
|
+ orgMap.computeIfAbsent(key, v -> finalSysOrg);
|
|
|
+ }
|
|
|
+ return sysOrg;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 验证课程是否存在
|
|
|
+ *
|
|
|
+ * @param courseMap courseMap
|
|
|
+ * @param key 课程名称
|
|
|
+ * @param schoolId 学校id
|
|
|
+ * @param value 课程编号
|
|
|
+ * @param excelErrorTemp 错误信息
|
|
|
+ * @param row 行
|
|
|
+ * @param sheet 区
|
|
|
+ * @return 基础课程
|
|
|
+ */
|
|
|
+ private BasicCourse validBasicCourseExists(Map<String, BasicCourse> courseMap,
|
|
|
+ String key,
|
|
|
+ Long schoolId,
|
|
|
+ String value,
|
|
|
+ List<ExcelError> excelErrorTemp,
|
|
|
+ int row,
|
|
|
+ int sheet) {
|
|
|
+ BasicCourse basicCourse = null;
|
|
|
+ if (!courseMap.containsKey(key)) {//不存在查询
|
|
|
+ QueryWrapper<BasicCourse> basicCourseQueryWrapper = new QueryWrapper<>();
|
|
|
+ basicCourseQueryWrapper.lambda().eq(BasicCourse::getSchoolId, schoolId)
|
|
|
+ .eq(BasicCourse::getName, key)
|
|
|
+ .eq(BasicCourse::getCode, value)
|
|
|
+ .eq(BasicCourse::getEnable, true);
|
|
|
+ basicCourse = basicCourseService.getOne(basicCourseQueryWrapper);
|
|
|
+ } else {
|
|
|
+ basicCourse = courseMap.get(key);
|
|
|
+ }
|
|
|
+ if (Objects.isNull(basicCourse)) {
|
|
|
+ excelErrorTemp.add(new ExcelError(row, "excel第" + sheet + "个sheet第" + row + "行[" + "课程代码" + "]不存在"));
|
|
|
+ } else {
|
|
|
+ BasicCourse finalBasicCourse = basicCourse;
|
|
|
+ courseMap.computeIfAbsent(key, v -> finalBasicCourse);
|
|
|
+ }
|
|
|
+ return basicCourse;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 验证班级是否存在
|
|
|
+ *
|
|
|
+ * @param clazzMap 班级map
|
|
|
+ * @param key 班级名称
|
|
|
+ * @param schoolId 学校id
|
|
|
+ * @param excelErrorTemp 错误信息
|
|
|
+ * @param row 行
|
|
|
+ * @param sheet 区
|
|
|
+ * @return 班级信息
|
|
|
+ */
|
|
|
+ private DictionaryResult validBasicClazzExists(Map<String, DictionaryResult> clazzMap,
|
|
|
+ String key,
|
|
|
+ Long schoolId,
|
|
|
+ List<ExcelError> excelErrorTemp,
|
|
|
+ int row,
|
|
|
+ int sheet) {
|
|
|
+ DictionaryResult clazz = null;
|
|
|
+ if (!clazzMap.containsKey(key)) {//不存在查询
|
|
|
+ TeachClazz teachClazz = teachClazzService.getOne(new QueryWrapper<TeachClazz>().lambda().eq(TeachClazz::getSchoolId, schoolId).eq(TeachClazz::getClazzName, key));
|
|
|
+ if (Objects.nonNull(teachClazz)) {
|
|
|
+ clazz = new DictionaryResult();
|
|
|
+ clazz.setId(teachClazz.getId());
|
|
|
+ clazz.setName(teachClazz.getClazzName());
|
|
|
+ } else {
|
|
|
+// QueryWrapper<BasicClazz> basicClazzQueryWrapper = new QueryWrapper<>();
|
|
|
+// basicClazzQueryWrapper.lambda().eq(BasicClazz::getSchoolId, schoolId)
|
|
|
+// .eq(BasicClazz::getClazzName, key)
|
|
|
+// .eq(BasicClazz::getEnable, true);
|
|
|
+// BasicClazz basicClazz = basicClazzService.getOne(basicClazzQueryWrapper);
|
|
|
+// if (Objects.nonNull(basicClazz)) {
|
|
|
+// clazz = new DictionaryResult();
|
|
|
+// clazz.setId(basicClazz.getId());
|
|
|
+// clazz.setName(basicClazz.getClazzName());
|
|
|
+// }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ clazz = clazzMap.get(key);
|
|
|
+ }
|
|
|
+ if (Objects.isNull(clazz)) {
|
|
|
+ excelErrorTemp.add(new ExcelError(row, "excel第" + sheet + "个sheet第" + row + "行[" + "班级名称" + "]不存在"));
|
|
|
+ } else {
|
|
|
+ DictionaryResult finalClazz = clazz;
|
|
|
+ clazzMap.computeIfAbsent(key, v -> finalClazz);
|
|
|
+ }
|
|
|
+ return clazz;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 过滤掉所有空格(前、中、后)
|
|
|
+ *
|
|
|
+ * @param value value
|
|
|
+ */
|
|
|
+ private static String trimWhiteSpace(String value) {
|
|
|
+ return StringUtils.deleteWhitespace(value);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 校验并拼接文件名(后缀)
|
|
|
+ *
|
|
|
+ * @param fileName 原文件名
|
|
|
+ * @param suffix 后缀
|
|
|
+ */
|
|
|
+ private static String spliceFileName(String fileName, String suffix) {
|
|
|
+ if (StringUtils.isAnyBlank(fileName, suffix)) {
|
|
|
+ return fileName;
|
|
|
+ }
|
|
|
+ if (!suffix.startsWith(SystemConstant.ORG_POINT)) {
|
|
|
+ suffix = SystemConstant.ORG_POINT + suffix;
|
|
|
+ }
|
|
|
+ if (!fileName.endsWith(suffix)) {
|
|
|
+ return fileName + suffix;
|
|
|
+ }
|
|
|
+ return fileName;
|
|
|
+ }
|
|
|
+}
|