Pārlūkot izejas kodu

短信功能改造,使用平台短信组件。
bug修改
学生导入、用户导入增加错误文件下载功能

xiaofei 2 gadi atpakaļ
vecāks
revīzija
483ed07b46
37 mainītis faili ar 665 papildinājumiem un 598 dzēšanām
  1. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/activiti/custom/listener/ProcessEventListener.java
  2. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/BasicMessage.java
  3. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/BasicMessageService.java
  4. 17 12
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicMessageServiceImpl.java
  5. 12 14
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/DownloadServiceImpl.java
  6. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPrintPlanServiceImpl.java
  7. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncBasicClazzImportService.java
  8. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncCreatePdfTempleteService.java
  9. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncExaminationImportTemplateService.java
  10. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncStatisticsDataImportService.java
  11. 10 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncStudentDataImportService.java
  12. 9 6
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncSysUserDataImportService.java
  13. 5 7
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/importData/AsyncImportTaskTemplete.java
  14. 157 102
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/TaskLogicServiceImpl.java
  15. 0 141
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/SmsUtils.java
  16. 1 0
      distributed-print-business/src/main/resources/mapper/TFFlowApproveMapper.xml
  17. 1 1
      distributed-print/src/main/java/com/qmth/distributed/print/api/BasicMessageController.java
  18. 3 0
      distributed-print/src/main/java/com/qmth/distributed/print/api/SysController.java
  19. 2 0
      distributed-print/src/main/java/com/qmth/distributed/print/api/TBTaskController.java
  20. 4 31
      distributed-print/src/main/resources/application.properties
  21. 1 8
      distributed-print/src/test/java/com/qmth/distributed/print/ServiceTest.java
  22. 5 0
      pom.xml
  23. 4 0
      teachcloud-common/pom.xml
  24. 89 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/dto/excel/export/BasicStudentErrorExportDto.java
  25. 81 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/dto/excel/export/SysUserErrorExportDto.java
  26. 23 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/result/SmsResponseResult.java
  27. 11 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/result/TaskListResult.java
  28. 0 12
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/config/DictionaryConfig.java
  29. 2 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/contant/SystemConstant.java
  30. 0 197
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/domain/SmsDomain.java
  31. 1 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/DownloadFileEnum.java
  32. 1 3
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/MessageEnum.java
  33. 2 2
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/impl/BasicStudentServiceImpl.java
  34. 16 52
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/impl/BasicVerifyCodeServiceImpl.java
  35. 18 1
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/util/ExcelUtil.java
  36. 181 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/util/SmsSendUtil.java
  37. 1 0
      teachcloud-common/src/main/resources/mapper/TBTaskMapper.xml

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/activiti/custom/listener/ProcessEventListener.java

@@ -6,7 +6,7 @@ import com.qmth.distributed.print.business.bean.result.FlowTaskResult;
 import com.qmth.distributed.print.business.entity.ExamTask;
 import com.qmth.distributed.print.business.entity.TFFlowLog;
 import com.qmth.distributed.print.business.enums.CustomFlowMultipleUserApproveTypeEnum;
-import com.qmth.distributed.print.business.enums.MessageEnum;
+import com.qmth.teachcloud.common.enums.MessageEnum;
 import com.qmth.distributed.print.business.service.ActivitiService;
 import com.qmth.distributed.print.business.service.BasicMessageService;
 import com.qmth.distributed.print.business.service.PrintCommonService;

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/BasicMessage.java

@@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
-import com.qmth.distributed.print.business.enums.MessageEnum;
+import com.qmth.teachcloud.common.enums.MessageEnum;
 import com.qmth.teachcloud.common.base.BaseEntity;
 import io.swagger.annotations.ApiModelProperty;
 

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/BasicMessageService.java

@@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.distributed.print.business.entity.BasicMessage;
 import com.qmth.distributed.print.business.entity.ExamTask;
-import com.qmth.distributed.print.business.enums.MessageEnum;
+import com.qmth.teachcloud.common.enums.MessageEnum;
 import com.qmth.teachcloud.common.bean.params.ApproveUserResult;
 import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.common.enums.EnumResult;

+ 17 - 12
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicMessageServiceImpl.java

@@ -8,11 +8,11 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.distributed.print.business.entity.BasicMessage;
 import com.qmth.distributed.print.business.entity.ExamTask;
-import com.qmth.distributed.print.business.enums.MessageEnum;
+import com.qmth.teachcloud.common.bean.result.SmsResponseResult;
+import com.qmth.teachcloud.common.enums.MessageEnum;
 import com.qmth.distributed.print.business.mapper.BasicMessageMapper;
 import com.qmth.distributed.print.business.service.BasicMessageService;
 import com.qmth.distributed.print.business.service.ExamTaskService;
-import com.qmth.distributed.print.business.util.SmsUtils;
 import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
 import com.qmth.teachcloud.common.bean.params.ApproveUserResult;
 import com.qmth.teachcloud.common.contant.SpringContextHolder;
@@ -25,6 +25,7 @@ import com.qmth.teachcloud.common.service.BasicRoleDataPermissionService;
 import com.qmth.teachcloud.common.service.CommonCacheService;
 import com.qmth.teachcloud.common.service.SysConfigService;
 import com.qmth.teachcloud.common.util.ServletUtil;
+import com.qmth.teachcloud.common.util.SmsSendUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
@@ -47,7 +48,9 @@ public class BasicMessageServiceImpl extends ServiceImpl<BasicMessageMapper, Bas
     private CommonCacheService commonCacheService;
 
     @Resource
-    private SmsUtils smsUtils;
+    private SmsSendUtil smsSendUtil;
+
+
 
     @Resource
     private BasicRoleDataPermissionService basicRoleDataPermissionService;
@@ -116,7 +119,7 @@ public class BasicMessageServiceImpl extends ServiceImpl<BasicMessageMapper, Bas
         String templateCode = null;
         try {
             // code和content
-            Map<String, String> enumInfo = smsUtils.getCodeAndContentByEnum(messageType);
+            Map<String, String> enumInfo = smsSendUtil.getCodeAndContentByEnum(messageType);
             if (!enumInfo.containsKey("templateCode")) {
                 throw ExceptionResultEnum.ERROR.exception("未找到短信模板Code");
             }
@@ -149,12 +152,13 @@ public class BasicMessageServiceImpl extends ServiceImpl<BasicMessageMapper, Bas
             }
 
             // 调用阿里云短信平台发送短信
-            SendSmsResponse sendSmsResponse = smsUtils.sendSms(mobileNumber, templateCode, variableParams);
-            if (sendSmsResponse == null) {
+            Map<String, Object> templateParam = JSON.parseObject(variableParams, Map.class);
+            SmsResponseResult smsResponseResult = smsSendUtil.sendSms(mobileNumber, templateCode, templateParam);
+            if (!SmsSendUtil.OK.equals(smsResponseResult.getCode())) {
                 throw ExceptionResultEnum.ERROR.exception("阿里云短信发送接口调用失败");
             }
-            basicMessage.setSendStatus(sendSmsResponse.getCode());
-            basicMessage.setSendResult(sendSmsResponse.getMessage());
+            basicMessage.setSendStatus(smsResponseResult.getCode());
+            basicMessage.setSendResult(smsResponseResult.getMessage());
 
         } catch (Exception e) {
             basicMessage.setSendStatus("SYSTEM_ERROR");
@@ -195,12 +199,13 @@ public class BasicMessageServiceImpl extends ServiceImpl<BasicMessageMapper, Bas
 
             if (!StringUtils.isBlank(basicMessage.getMobileNumber())) {
                 // 调用阿里云短信平台发送短信
-                SendSmsResponse sendSmsResponse = smsUtils.sendSms(basicMessage.getMobileNumber(), basicMessage.getTemplateCode(), basicMessage.getVariableParams());
-                if (sendSmsResponse == null) {
+                Map<String, Object> templateParam = JSON.parseObject(basicMessage.getVariableParams(), Map.class);
+                SmsResponseResult smsResponseResult = smsSendUtil.sendSms(basicMessage.getMobileNumber(), basicMessage.getTemplateCode(), templateParam);
+                if (!SmsSendUtil.OK.equals(smsResponseResult.getCode())) {
                     throw ExceptionResultEnum.ERROR.exception("阿里云短信发送接口调用失败");
                 }
-                basicMessage.setSendStatus(sendSmsResponse.getCode());
-                basicMessage.setSendResult(sendSmsResponse.getMessage());
+                basicMessage.setSendStatus(smsResponseResult.getCode());
+                basicMessage.setSendResult(smsResponseResult.getMessage());
             }
         } catch (Exception e) {
             basicMessage.setSendStatus("SYSTEM_ERROR");

+ 12 - 14
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/DownloadServiceImpl.java

@@ -134,21 +134,19 @@ public class DownloadServiceImpl implements DownloadService {
 
                 // 试卷附件id
                 Long attachmentId = paperInfo.getAttachmentId();
-                if (attachmentId == null) {
-                    throw ExceptionResultEnum.ERROR.exception("命题任务没有上传试卷,无法下载");
+                if (attachmentId != null) {
+                    // 试卷
+                    BasicAttachment attachment = basicAttachmentMapper.selectById(attachmentId);
+                    if (attachment == null) {
+                        throw ExceptionResultEnum.ERROR.exception("附件数据异常");
+                    }
+                    String paperPath = rootPath + File.separator + examTask.getCourseName() + SystemConstant.HYPHEN + examTask.getCourseCode() + File.separator + examTask.getPaperNumber();
+                    String fileName = "试卷" + "_" + attachment.getName() + "_" + paperType + attachment.getType();
+                    fileList.add(attachmentCommonService.downloadFile(paperPath, fileName, attachment));
                 }
+
                 // 题卡id
                 Long cardId = paperInfo.getCardId();
-
-                // 试卷
-                BasicAttachment attachment = basicAttachmentMapper.selectById(attachmentId);
-                if (attachment == null) {
-                    throw ExceptionResultEnum.ERROR.exception("附件数据异常");
-                }
-                String paperPath = rootPath + File.separator + examTask.getCourseName() + SystemConstant.HYPHEN + examTask.getCourseCode() + File.separator + examTask.getPaperNumber();
-                String fileName = "试卷" + "_" + attachment.getName() + "_" + paperType + attachment.getType();
-                fileList.add(attachmentCommonService.downloadFile(paperPath, fileName, attachment));
-
                 // 题卡
                 if (cardId != null) {
                     ExamCard examCard = examCardMapper.selectById(cardId);
@@ -169,7 +167,7 @@ public class DownloadServiceImpl implements DownloadService {
 
                     // html
                     File htmlFile = new File(cardHtmlPath);
-                    if(!htmlFile.exists()){
+                    if (!htmlFile.exists()) {
                         htmlFile.getParentFile().mkdirs();
                         htmlFile.createNewFile();
                     }
@@ -178,7 +176,7 @@ public class DownloadServiceImpl implements DownloadService {
                     fileList.add(htmlFile);
                     // 转pdf文件
                     File pdfFile = new File(cardPdfPath);
-                    if(!pdfFile.exists()){
+                    if (!pdfFile.exists()) {
                         pdfFile.getParentFile().mkdirs();
                         pdfFile.createNewFile();
                     }

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPrintPlanServiceImpl.java

@@ -15,7 +15,7 @@ import com.qmth.distributed.print.business.bean.result.PrintPlanResult;
 import com.qmth.distributed.print.business.bean.result.TemplatePrintInfoResult;
 import com.qmth.distributed.print.business.entity.*;
 import com.qmth.distributed.print.business.enums.ExamDetailStatusEnum;
-import com.qmth.distributed.print.business.enums.MessageEnum;
+import com.qmth.teachcloud.common.enums.MessageEnum;
 import com.qmth.distributed.print.business.enums.PrintPlanStatusEnum;
 import com.qmth.distributed.print.business.enums.SyncCardTypeEnum;
 import com.qmth.distributed.print.business.mapper.ExamPrintPlanMapper;

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncBasicClazzImportService.java

@@ -52,7 +52,7 @@ public class AsyncBasicClazzImportService extends AsyncImportTaskTemplete {
             Map<String, Object> result = taskLogicService.executeImportBasicClazzLogic(map);
 
 
-            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, Long.valueOf(String.valueOf(result.get("dataCount"))), FINISH_SIZE));
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, Long.valueOf(String.valueOf(result.get("dataCount"))), FINISH_ERROR_SIZE));
             tbTask.setResult(TaskResultEnum.SUCCESS);
         }catch (Exception e){
             log.error(SystemConstant.LOG_ERROR, e);

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncCreatePdfTempleteService.java

@@ -59,7 +59,7 @@ public class AsyncCreatePdfTempleteService extends AsyncCreateTaskTemplete {
             TaskLogicService taskLogicService = SpringContextHolder.getBean(TaskLogicService.class);
             taskLogicService.createPdfPrepose(map);
             taskLogicService.executeCreatePdfLogic(map);
-            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, map.get("size"), FINISH_SIZE));
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, map.get("size"), FINISH_ERROR_SIZE));
             tbTask.setResult(TaskResultEnum.SUCCESS);
         } catch (Exception e) {
             log.error(SystemConstant.LOG_ERROR, e);

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncExaminationImportTemplateService.java

@@ -66,7 +66,7 @@ public class AsyncExaminationImportTemplateService extends AsyncImportTaskTemple
                 examTaskService.checkDataByExamination(examDetailId, user);
             }
 
-            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, Long.valueOf(String.valueOf(result.get("dataCount"))), FINISH_SIZE));
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, Long.valueOf(String.valueOf(result.get("dataCount"))), FINISH_ERROR_SIZE));
             tbTask.setResult(TaskResultEnum.SUCCESS);
         } catch (Exception e) {
             log.error(SystemConstant.LOG_ERROR, e);

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncStatisticsDataImportService.java

@@ -50,7 +50,7 @@ public class AsyncStatisticsDataImportService extends AsyncImportTaskTemplete {
             TaskLogicService taskLogicService = SpringContextHolder.getBean(TaskLogicService.class);
             // 执行导入
             Map<String, Object> result = taskLogicService.executeImportStatisticsLogic(map);
-            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, Long.valueOf(String.valueOf(result.get("dataCount"))), FINISH_SIZE));
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, Long.valueOf(String.valueOf(result.get("dataCount"))), FINISH_ERROR_SIZE));
             tbTask.setResult(TaskResultEnum.SUCCESS);
         } catch (Exception e) {
             log.error(SystemConstant.LOG_ERROR, e);

+ 10 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncStudentDataImportService.java

@@ -4,6 +4,8 @@ import cn.hutool.core.date.DateUtil;
 import com.qmth.boot.api.exception.ApiException;
 import com.qmth.distributed.print.business.templete.importData.AsyncImportTaskTemplete;
 import com.qmth.distributed.print.business.templete.service.TaskLogicService;
+import com.qmth.teachcloud.common.bean.dto.excel.BasicStudentImportDto;
+import com.qmth.teachcloud.common.bean.dto.excel.export.BasicStudentErrorExportDto;
 import com.qmth.teachcloud.common.contant.SpringContextHolder;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.SysUser;
@@ -12,12 +14,14 @@ import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.enums.TaskResultEnum;
 import com.qmth.teachcloud.common.enums.TaskStatusEnum;
 import com.qmth.teachcloud.common.service.TBTaskService;
+import com.qmth.teachcloud.common.util.ExcelUtil;
 import com.qmth.teachcloud.common.util.Result;
 import com.qmth.teachcloud.common.util.ResultUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.text.MessageFormat;
@@ -51,8 +55,13 @@ public class AsyncStudentDataImportService extends AsyncImportTaskTemplete {
             // 执行导入基础学生数据
             Map<String, Object> result = taskLogicService.executeImportBasicStudentLogic(map);
 
+            //错误数据,生成文件
+            if (result.containsKey(SystemConstant.ERROR_DATA_LIST)) {
+                List<BasicStudentErrorExportDto> errorDataList = (List<BasicStudentErrorExportDto>) result.get(SystemConstant.ERROR_DATA_LIST);
+                super.createErrorFile(tbTask, BasicStudentErrorExportDto.class, errorDataList);
+            }
 
-            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, Long.valueOf(String.valueOf(result.get("dataCount"))), FINISH_SIZE));
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}{4}{5}{6}{7}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, Long.valueOf(String.valueOf(result.get(SystemConstant.DATA_COUNT))), FINISH_TOTAL_SIZE, Long.valueOf(String.valueOf(result.get(SystemConstant.SUCCESS_DATA_COUNT))), FINISH_SUCCESS_SIZE, Long.valueOf(String.valueOf(result.get(SystemConstant.ERROR_DATA_COUNT))), FINISH_ERROR_SIZE));
             tbTask.setResult(TaskResultEnum.SUCCESS);
         }catch (Exception e){
             log.error(SystemConstant.LOG_ERROR, e);

+ 9 - 6
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncSysUserDataImportService.java

@@ -6,6 +6,7 @@ import com.qmth.boot.api.exception.ApiException;
 import com.qmth.distributed.print.business.service.CloudUserPushService;
 import com.qmth.distributed.print.business.templete.importData.AsyncImportTaskTemplete;
 import com.qmth.distributed.print.business.templete.service.TaskLogicService;
+import com.qmth.teachcloud.common.bean.dto.excel.export.BasicStudentErrorExportDto;
 import com.qmth.teachcloud.common.contant.SpringContextHolder;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.SysUser;
@@ -57,6 +58,13 @@ public class AsyncSysUserDataImportService extends AsyncImportTaskTemplete {
 
             // 执行导入基础用户数据
             Map<String, Object> result = taskLogicService.executeImportSysUserLogic(map);
+
+            //错误数据,生成文件
+            if (result.containsKey(SystemConstant.ERROR_DATA_LIST)) {
+                List<BasicStudentErrorExportDto> errorDataList = (List<BasicStudentErrorExportDto>) result.get(SystemConstant.ERROR_DATA_LIST);
+                super.createErrorFile(tbTask, BasicStudentErrorExportDto.class, errorDataList);
+            }
+
             // 执行用户同步数据
             SysUser sysUser = (SysUser) map.get(SystemConstant.SYS_USER);
             List<Long> userIdList = JSON.parseArray(String.valueOf(result.get("userIdList")), Long.class);
@@ -64,12 +72,7 @@ public class AsyncSysUserDataImportService extends AsyncImportTaskTemplete {
                 cloudUserPushService.pushCloudUser(userIdList, sysUser);
             }
 
-            //错误数据,生成文件
-            if (result.containsKey(SystemConstant.ERROR_DATA_LIST)) {
-                // todo 生成错误数据文件
-            }
-
-            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, Long.valueOf(String.valueOf(result.get("dataCount"))), FINISH_SIZE));
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}{4}{5}{6}{7}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, Long.valueOf(String.valueOf(result.get(SystemConstant.DATA_COUNT))), FINISH_TOTAL_SIZE, Long.valueOf(String.valueOf(result.get(SystemConstant.SUCCESS_DATA_COUNT))), FINISH_SUCCESS_SIZE, Long.valueOf(String.valueOf(result.get(SystemConstant.ERROR_DATA_COUNT))), FINISH_ERROR_SIZE));
             tbTask.setResult(TaskResultEnum.SUCCESS);
         } catch (Exception e) {
             log.error(SystemConstant.LOG_ERROR, e);

+ 5 - 7
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/importData/AsyncImportTaskTemplete.java

@@ -39,7 +39,9 @@ public abstract class AsyncImportTaskTemplete {
     public static final String EXCEPTION_TITLE = "->数据处理发生异常!";
     public static final String EXCEPTION_DATA = "错误信息:";
     public static final String FINISH_TITLE = "->数据处理结束,共处理了";
-    public static final String FINISH_SIZE = "条数据";
+    public static final String FINISH_TOTAL_SIZE = "条数据,成功";
+    public static final String FINISH_SUCCESS_SIZE = "条数据,失败";
+    public static final String FINISH_ERROR_SIZE = "条数据";
     public static final String EXCEPTION_CREATE_TXT_TITLE = "->创建导出日志时发生异常!";
 
     /**
@@ -135,7 +137,7 @@ public abstract class AsyncImportTaskTemplete {
                 stringJoiner.add(dictionaryConfig.fssPublicDomain().getConfig()).add(File.separator);
             }
             stringJoiner = SystemConstant.getDirName(stringJoiner, UploadFileEnum.FILE, true);
-            stringJoiner.add(SystemConstant.getNanoId()).add(SystemConstant.TXT_PREFIX);
+            stringJoiner.add(SystemConstant.getNanoId()).add(SystemConstant.EXCEL_PREFIX);
 
             String txtDirName = stringJoiner.toString();
             excelFileTemp = SystemConstant.getFileTempVar(SystemConstant.EXCEL_PREFIX);
@@ -153,17 +155,13 @@ public abstract class AsyncImportTaskTemplete {
             json.put(SystemConstant.PATH, stringJoiner.toString());
             json.put(SystemConstant.TYPE, ossStr);
             json.put(SystemConstant.UPLOAD_TYPE, UploadFileEnum.FILE);
-            tbTask.setReportFilePath(json.toJSONString());
+            tbTask.setErrorFilePath(json.toJSONString());
 
         } catch (Exception e) {
             StringJoiner stringJoinerSummary = new StringJoiner("").add(tbTask.getSummary()).add("\n");
             stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), EXCEPTION_CREATE_TXT_TITLE, EXCEPTION_DATA, e.getMessage()));
 
             String summary = stringJoinerSummary.toString();
-            if (summary.length() >= 65535) {
-                summary = "Data too long : " + summary.substring(0, 100) + "......" + summary.substring(summary.length() - 100);
-            }
-
             tbTask.setSummary(summary);
             tbTask.setResult(TaskResultEnum.ERROR);
             if (e instanceof ApiException) {

+ 157 - 102
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/TaskLogicServiceImpl.java

@@ -25,6 +25,8 @@ import com.qmth.distributed.print.business.util.HtmlToPdfUtil;
 import com.qmth.teachcloud.common.annotation.ExcelDBFieldDesc;
 import com.qmth.teachcloud.common.base.BaseEntity;
 import com.qmth.teachcloud.common.bean.dto.excel.*;
+import com.qmth.teachcloud.common.bean.dto.excel.export.BasicStudentErrorExportDto;
+import com.qmth.teachcloud.common.bean.dto.excel.export.SysUserErrorExportDto;
 import com.qmth.teachcloud.common.bean.params.ArraysParams;
 import com.qmth.teachcloud.common.config.DictionaryConfig;
 import com.qmth.teachcloud.common.contant.SystemConstant;
@@ -44,6 +46,7 @@ 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.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.data.redis.core.RedisTemplate;
@@ -1362,10 +1365,11 @@ public class TaskLogicServiceImpl implements TaskLogicService {
     @Override
     public Map<String, Object> executeImportBasicStudentLogic(Map<String, Object> map) throws Exception {
         InputStream inputStream = (InputStream) map.get("inputStream");
-        System.out.println(inputStream);
         List<String> studentCodeList = new ArrayList<>();
+        List<BasicStudentErrorExportDto> errorDataList = new ArrayList<>();
+        AtomicInteger totalInteger = new AtomicInteger(0);
+        AtomicInteger successInteger = new AtomicInteger(0);
         List<LinkedMultiValueMap<Integer, Object>> finalList = ExcelUtil.excelReader(inputStream, Lists.newArrayList(BasicStudentImportDto.class, DescribeImportDto.class), (finalExcelList, finalColumnNameList, finalExcelErrorList) -> {
-            List<ExcelError> excelErrorTemp = new ArrayList<>();
             Map<String, String> checkCodeMap = new HashMap<>();
             Map<String, String> checkPhoneMap = new HashMap<>();
             for (int i = 0; i < finalExcelList.size(); i++) {
@@ -1377,17 +1381,28 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                 }
                 for (int y = 0; y < Objects.requireNonNull(basicStudentImportDtoList).size(); y++) {
                     BasicStudentImportDto basicStudentImportDto = (BasicStudentImportDto) basicStudentImportDtoList.get(y);
+                    totalInteger.getAndIncrement();
+
+                    BasicStudentErrorExportDto basicStudentErrorExportDto = new BasicStudentErrorExportDto();
+                    BeanUtils.copyProperties(basicStudentImportDto, basicStudentErrorExportDto);
+
+
                     String studentName = basicStudentImportDto.getStudentName();
                     String studentCode = basicStudentImportDto.getStudentCode();
                     String phoneNumber = basicStudentImportDto.getPhoneNumber();
                     String clazzName = basicStudentImportDto.getClazzName();
                     studentCodeList.add(studentCode);
 
-                    // 检验excel中
+                    StringJoiner errorStringJoiner = new StringJoiner(";");
+                    String errorStringEmpty = ExcelUtil.checkExcelField(basicStudentImportDto);
+                    if (errorStringEmpty.length() > 0) {
+                        errorStringJoiner.add(errorStringEmpty);
+                    }
+
                     // 检验学号
                     if (SystemConstant.strNotNull(studentCode)) {
                         if (checkCodeMap.containsKey(studentCode)) {
-                            throw ExceptionResultEnum.ERROR.exception("导入的excel中包含在重复的【学生编号】:" + studentCode);
+                            errorStringJoiner.add("学号[" + studentCode + "]重复");
                         } else {
                             checkCodeMap.put(studentCode, studentName);
                         }
@@ -1395,28 +1410,39 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                     // 如果电话有值则检验电话excel中唯一性
                     if (SystemConstant.strNotNull(phoneNumber)) {
                         if (checkPhoneMap.containsKey(phoneNumber)) {
-                            throw ExceptionResultEnum.ERROR.exception("导入的excel中包含在重复的【电话号码】:" + phoneNumber);
+                            errorStringJoiner.add("手机号[" + phoneNumber + "]重复");
                         } else {
                             checkPhoneMap.put(phoneNumber, studentCode);
                         }
                     }
 
-                    excelErrorTemp.addAll(ExcelUtil.checkExcelField(basicStudentImportDto, y, i));
-                    if (Objects.isNull(studentCode) || studentCode.length() > 30 || !studentCode.matches(SystemConstant.REGULAR_EXPRESSION_OF_CODE)) {
-                        excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[学号]不符合输入规范"));
-                    }
                     if (Objects.isNull(studentName) || studentName.length() > 30) {
-                        excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[学生名称]不符合输入规范"));
+                        errorStringJoiner.add("[姓名]最长30个字符");
+                    }
+                    if (Objects.isNull(studentCode) || studentCode.length() > 30 || !studentCode.matches(SystemConstant.REGULAR_EXPRESSION_OF_CODE)) {
+                        errorStringJoiner.add("[学号]最长30个字符");
                     }
                     if (Objects.nonNull(phoneNumber) && !phoneNumber.matches(SystemConstant.REGULAR_EXPRESSION_OF_PHONE)) {
-                        excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[电话号码]不符合输入规范"));
+                        errorStringJoiner.add("[手机号]不符合规范");
+                    }
+                    String errorString = errorStringJoiner.toString();
+                    if (errorString.length() > 0) {
+                        basicStudentErrorExportDto.setErrorMsg(errorString);
+                        errorDataList.add(basicStudentErrorExportDto);
+                        basicStudentImportDtoList.remove(y);
+                    } else {
+                        // 校验通过的数据
+                        successInteger.getAndIncrement();
                     }
                 }
             }
-            if (excelErrorTemp.size() > 0) {
-                throw ExceptionResultEnum.ERROR.exception(JSONObject.toJSONString(excelErrorTemp));
+            if (!errorDataList.isEmpty()) {
+                map.put(SystemConstant.ERROR_DATA_LIST, errorDataList);
             }
             map.put("studentCodeList", studentCodeList);
+            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;
         });
         return basicStudentService.executeBasicStudentImportLogic(finalList, map);
@@ -1426,40 +1452,52 @@ public class TaskLogicServiceImpl implements TaskLogicService {
     @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) -> {
-            List<ExcelError> excelErrorTemp = new ArrayList<>();
             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);
-                assert sysUserImportDtoList != null;
-                if (sysUserImportDtoList.get(0) instanceof DescribeImportDto) {
+                if (sysUserImportDtoList.isEmpty() || sysUserImportDtoList.get(0) instanceof DescribeImportDto) {
                     continue;
                 }
-                map.put("dataCount", sysUserImportDtoList.size());
+                map.put(SystemConstant.DATA_COUNT, sysUserImportDtoList.size());
                 List<SysUserImportDto> duplicateData = new ArrayList<>();
                 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 code = sysUserImportDto.getCode();
                     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(code)) {
                         SysUserImportDto primaryCell = checkDtoMap.get(code);
                         String priName = primaryCell.getName();
                         String priPhoneNumber = primaryCell.getPhoneNumber();
                         String priOrgName = primaryCell.getOrgName();
                         if (!Objects.equals(priName, name)) {
-                            throw ExceptionResultEnum.ERROR.exception("【工号】 :" + code + ",的用户存在不同的用户名称异常");
+                            errorStringJoiner.add("工号[" + code + "]的用户存在不同的姓名");
                         }
                         if (!Objects.equals(priPhoneNumber, phoneNumber)) {
-                            throw ExceptionResultEnum.ERROR.exception("【工号】 :" + code + ",的用户存在不同的手机号异常");
+                            errorStringJoiner.add("工号[" + code + "]的用户存在不同的手机号");
                         }
                         if (!Objects.equals(priOrgName, orgName)) {
-                            throw ExceptionResultEnum.ERROR.exception("【工号】 :" + code + ",的用户存在不同的组织架构异常");
+                            errorStringJoiner.add("工号[" + code + "]的用户存在不同的组织架构");
                         }
                         String priRoleName = primaryCell.getRoleName();
                         if (SystemConstant.strNotNull(roleName)) {
@@ -1471,22 +1509,33 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                         checkDtoMap.put(code, sysUserImportDto);
                     }
 
-                    excelErrorTemp.addAll(ExcelUtil.checkExcelField(sysUserImportDto, y, i));
                     if (Objects.isNull(code) || code.length() > 30 || !code.matches(SystemConstant.REGULAR_EXPRESSION_OF_CODE)) {
-                        excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[工号]不符合输入规范"));
+                        errorStringJoiner.add("[工号]不符合规范,最长30个字符");
                     }
                     if (Objects.isNull(name) || name.length() > 30) {
-                        excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[姓名]不符合输入规范"));
+                        errorStringJoiner.add("[姓名]不符合输入规范,最长30个字符");
                     }
                     if (Objects.nonNull(phoneNumber) && !phoneNumber.matches(SystemConstant.REGULAR_EXPRESSION_OF_PHONE)) {
-                        excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[电话号码]不符合输入规范"));
+                        errorStringJoiner.add("[手机号]不符合输入规范");
+                    }
+
+                    String errorString = errorStringJoiner.toString();
+                    if (errorString.length() > 0) {
+                        sysUserErrorExportDto.setErrorMsg(errorString);
+                        errorDataList.add(sysUserErrorExportDto);
+                        sysUserImportDtoList.remove(y);
+                    } else {
+                        // 校验通过的数据
+                        successInteger.getAndIncrement();
                     }
                 }
-                sysUserImportDtoList.removeAll(duplicateData);
             }
-            if (excelErrorTemp.size() > 0) {
-                throw ExceptionResultEnum.ERROR.exception(JSONObject.toJSONString(excelErrorTemp));
+            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;
         });
         return sysUserService.executeSysUserImportLogic(finalList, map);
@@ -1624,9 +1673,9 @@ public class TaskLogicServiceImpl implements TaskLogicService {
             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;
+            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;
 
             fos = new ByteArrayOutputStream();
@@ -1870,41 +1919,43 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                                 Long examCardId = examTaskPaperFileDto.getExamCardId();
                                 Long cardRuleId = examTaskPaperFileDto.getCardRuleId();
                                 ExamCard examCard = examCardService.getById(examCardId);
-                                ExamCardDetail examCardDetail = examCardDetailService.getByCardId(examCardId);
-                                String htmlContent;
-                                if (MakeMethodEnum.SELECT.equals(examCard.getMakeMethod()) && CardCreateMethodEnum.UPLOAD.equals(examCard.getCreateMethod())) {
-                                    htmlContent = createPdfUtil.resetHtmlTemplateBar(examCardDetail.getHtmlContent());
-                                } else {
-                                    BasicCardRule basicCardRule = basicCardRuleService.getById(cardRuleId);
-                                    htmlContent = createPdfUtil.replaceHtmlCard(examCardDetail, basicCardRule);
-                                }
+                                if (examCard != null) {
+                                    ExamCardDetail examCardDetail = examCardDetailService.getByCardId(examCardId);
+                                    String htmlContent;
+                                    if (MakeMethodEnum.SELECT.equals(examCard.getMakeMethod()) && CardCreateMethodEnum.UPLOAD.equals(examCard.getCreateMethod())) {
+                                        htmlContent = createPdfUtil.resetHtmlTemplateBar(examCardDetail.getHtmlContent());
+                                    } else {
+                                        BasicCardRule basicCardRule = basicCardRuleService.getById(cardRuleId);
+                                        htmlContent = createPdfUtil.replaceHtmlCard(examCardDetail, basicCardRule);
+                                    }
 
-                                byte[] bytes = htmlContent.getBytes(StandardCharsets.UTF_8);
-                                String cardName = "题卡-";
-                                if (namedByCourseInfo) {
-                                    cardName = cardName + course;
-                                }
-                                if (namedByPaperNumber) {
-                                    cardName = cardName + paperNumber;
-                                }
-                                if (namedByOriginalFile) {
-                                    cardName = cardName + examCardService.getById(examCardId).getTitle();
-                                }
-                                cardName = cardName + SystemConstant.HYPHEN + examTaskPaperFileDto.getPaperType();
-                                String cardLocalHtmlPath = filePath + cardName + SystemConstant.HTML_PREFIX;
-                                String cardLocalPdfPath = filePath + cardName + SystemConstant.PDF_PREFIX;
+                                    byte[] bytes = htmlContent.getBytes(StandardCharsets.UTF_8);
+                                    String cardName = "题卡-";
+                                    if (namedByCourseInfo) {
+                                        cardName = cardName + course;
+                                    }
+                                    if (namedByPaperNumber) {
+                                        cardName = cardName + paperNumber;
+                                    }
+                                    if (namedByOriginalFile) {
+                                        cardName = cardName + examCardService.getById(examCardId).getTitle();
+                                    }
+                                    cardName = cardName + SystemConstant.HYPHEN + examTaskPaperFileDto.getPaperType();
+                                    String cardLocalHtmlPath = filePath + cardName + SystemConstant.HTML_PREFIX;
+                                    String cardLocalPdfPath = filePath + cardName + SystemConstant.PDF_PREFIX;
 
-                                File localFile = new File(cardLocalHtmlPath);
-                                if (!localFile.getParentFile().exists()) {
-                                    boolean mkr = localFile.getParentFile().mkdirs();
-                                }
-                                FileCopyUtils.copy(bytes, localFile);
+                                    File localFile = new File(cardLocalHtmlPath);
+                                    if (!localFile.getParentFile().exists()) {
+                                        boolean mkr = localFile.getParentFile().mkdirs();
+                                    }
+                                    FileCopyUtils.copy(bytes, localFile);
 
-                                File pdfFile = new File(cardLocalPdfPath);
-                                if (!pdfFile.exists()) {
-                                    boolean cf = pdfFile.createNewFile();
+                                    File pdfFile = new File(cardLocalPdfPath);
+                                    if (!pdfFile.exists()) {
+                                        boolean cf = pdfFile.createNewFile();
+                                    }
+                                    HtmlToPdfUtil.convert(cardLocalHtmlPath, cardLocalPdfPath, PageSizeEnum.A3);
                                 }
-                                HtmlToPdfUtil.convert(cardLocalHtmlPath, cardLocalPdfPath, PageSizeEnum.A3);
                                 specialSuccessMessage = "";
                                 courseCount = 1;
                             }
@@ -1924,10 +1975,12 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                                 paperName = paperName + SystemConstant.HYPHEN + examTaskPaperFileDto.getPaperType();
                                 String paperLocalPath = filePath + paperName + examTaskPaperFileDto.getPaperSuffix();
                                 String paperPath = examTaskPaperFileDto.getPaperPath();
-                                if (oss || (!oss && dictionaryConfig.fssPrivateDomain().getConfig().startsWith(SystemConstant.START_PARENT))) {
-                                    fileStoreUtil.ossDownload(paperPath, paperLocalPath, fileStoreUtil.getUploadEnumByPath(paperPath).getFssType());
-                                } else {
-                                    FileUtil.copyFile(paperPath, paperLocalPath);
+                                if (StringUtils.isNotBlank(paperPath)) {
+                                    if (oss || (!oss && dictionaryConfig.fssPrivateDomain().getConfig().startsWith(SystemConstant.START_PARENT))) {
+                                        fileStoreUtil.ossDownload(paperPath, paperLocalPath, fileStoreUtil.getUploadEnumByPath(paperPath).getFssType());
+                                    } else {
+                                        FileUtil.copyFile(paperPath, paperLocalPath);
+                                    }
                                 }
                                 courseCount = 1;
                             }
@@ -1938,41 +1991,42 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                                 Long examCardId = examTaskPaperFileDto.getExamCardId();
                                 Long cardRuleId = examTaskPaperFileDto.getCardRuleId();
                                 ExamCard examCard = examCardService.getById(examCardId);
-                                ExamCardDetail examCardDetail = examCardDetailService.getByCardId(examCardId);
-                                String htmlContent;
-                                if (MakeMethodEnum.SELECT.equals(examCard.getMakeMethod()) && CardCreateMethodEnum.UPLOAD.equals(examCard.getCreateMethod())) {
-                                    htmlContent = createPdfUtil.resetHtmlTemplateBar(examCardDetail.getHtmlContent());
-                                } else {
-                                    BasicCardRule basicCardRule = basicCardRuleService.getById(cardRuleId);
-                                    htmlContent = createPdfUtil.replaceHtmlCard(examCardDetail, basicCardRule);
-                                }
+                                if (examCard == null) {
+                                    ExamCardDetail examCardDetail = examCardDetailService.getByCardId(examCardId);
+                                    String htmlContent;
+                                    if (MakeMethodEnum.SELECT.equals(examCard.getMakeMethod()) && CardCreateMethodEnum.UPLOAD.equals(examCard.getCreateMethod())) {
+                                        htmlContent = createPdfUtil.resetHtmlTemplateBar(examCardDetail.getHtmlContent());
+                                    } else {
+                                        BasicCardRule basicCardRule = basicCardRuleService.getById(cardRuleId);
+                                        htmlContent = createPdfUtil.replaceHtmlCard(examCardDetail, basicCardRule);
+                                    }
 
-                                byte[] bytes = htmlContent.getBytes(StandardCharsets.UTF_8);
-                                String cardName = "题卡-";
-                                if (namedByCourseInfo) {
-                                    cardName = cardName + course;
-                                }
-                                if (namedByPaperNumber) {
-                                    cardName = cardName + paperNumber;
-                                }
-                                if (namedByOriginalFile) {
-                                    cardName = cardName + examCardService.getById(examCardId).getTitle();
-                                }
-                                cardName = cardName + SystemConstant.HYPHEN + examTaskPaperFileDto.getPaperType();
-                                String cardLocalHtmlPath = filePath + cardName + SystemConstant.HTML_PREFIX;
-                                String cardLocalPdfPath = filePath + cardName + SystemConstant.PDF_PREFIX;
-                                File localCardFile = new File(cardLocalHtmlPath);
-                                if (!localCardFile.getParentFile().exists()) {
-                                    boolean mkr = localCardFile.getParentFile().mkdirs();
-                                }
-                                FileCopyUtils.copy(bytes, localCardFile);
+                                    byte[] bytes = htmlContent.getBytes(StandardCharsets.UTF_8);
+                                    String cardName = "题卡-";
+                                    if (namedByCourseInfo) {
+                                        cardName = cardName + course;
+                                    }
+                                    if (namedByPaperNumber) {
+                                        cardName = cardName + paperNumber;
+                                    }
+                                    if (namedByOriginalFile) {
+                                        cardName = cardName + examCardService.getById(examCardId).getTitle();
+                                    }
+                                    cardName = cardName + SystemConstant.HYPHEN + examTaskPaperFileDto.getPaperType();
+                                    String cardLocalHtmlPath = filePath + cardName + SystemConstant.HTML_PREFIX;
+                                    String cardLocalPdfPath = filePath + cardName + SystemConstant.PDF_PREFIX;
+                                    File localCardFile = new File(cardLocalHtmlPath);
+                                    if (!localCardFile.getParentFile().exists()) {
+                                        boolean mkr = localCardFile.getParentFile().mkdirs();
+                                    }
+                                    FileCopyUtils.copy(bytes, localCardFile);
 
-                                File cardPdfFile = new File(cardLocalPdfPath);
-                                if (!cardPdfFile.exists()) {
-                                    boolean cf = cardPdfFile.createNewFile();
+                                    File cardPdfFile = new File(cardLocalPdfPath);
+                                    if (!cardPdfFile.exists()) {
+                                        boolean cf = cardPdfFile.createNewFile();
+                                    }
+                                    HtmlToPdfUtil.convert(cardLocalHtmlPath, cardLocalPdfPath, PageSizeEnum.A3);
                                 }
-                                HtmlToPdfUtil.convert(cardLocalHtmlPath, cardLocalPdfPath, PageSizeEnum.A3);
-
                                 // 试卷
                                 String paperName = "试卷-";
                                 if (namedByCourseInfo) {
@@ -1987,11 +2041,12 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                                 paperName = paperName + SystemConstant.HYPHEN + examTaskPaperFileDto.getPaperType();
                                 String paperLocalPath = filePath + paperName + examTaskPaperFileDto.getPaperSuffix();
                                 String paperPath = examTaskPaperFileDto.getPaperPath();
-
-                                if (oss || (!oss && dictionaryConfig.fssPrivateDomain().getConfig().startsWith(SystemConstant.START_PARENT))) {
-                                    fileStoreUtil.ossDownload(paperPath, paperLocalPath, fileStoreUtil.getUploadEnumByPath(paperPath).getFssType());
-                                } else {
-                                    FileUtil.copyFile(paperPath, paperLocalPath);
+                                if (StringUtils.isNotBlank(paperPath)) {
+                                    if (oss || (!oss && dictionaryConfig.fssPrivateDomain().getConfig().startsWith(SystemConstant.START_PARENT))) {
+                                        fileStoreUtil.ossDownload(paperPath, paperLocalPath, fileStoreUtil.getUploadEnumByPath(paperPath).getFssType());
+                                    } else {
+                                        FileUtil.copyFile(paperPath, paperLocalPath);
+                                    }
                                 }
                                 courseCount = 1;
                             }

+ 0 - 141
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/SmsUtils.java

@@ -1,141 +0,0 @@
-package com.qmth.distributed.print.business.util;
-
-import com.aliyuncs.DefaultAcsClient;
-import com.aliyuncs.IAcsClient;
-import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
-import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
-import com.aliyuncs.exceptions.ClientException;
-import com.aliyuncs.http.MethodType;
-import com.aliyuncs.profile.DefaultProfile;
-import com.aliyuncs.profile.IClientProfile;
-import com.qmth.distributed.print.business.enums.MessageEnum;
-import com.qmth.teachcloud.common.config.DictionaryConfig;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.Resource;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @Date: 2021/11/5.
- */
-@Component
-public class SmsUtils {
-
-    @Resource
-    private DictionaryConfig dictionaryConfig;
-
-    /**
-     * 发送短信
-     *
-     * @param mobileNumber
-     * @param templateCode
-     * @param variableParams
-     * @return
-     * @throws ClientException
-     */
-    public SendSmsResponse sendSms(String mobileNumber, String templateCode, String variableParams) throws ClientException {
-        System.setProperty("sun.net.client.defaultConnectTimeout", "180000");
-        System.setProperty("sun.net.client.defaultReadTimeout", "18000");
-        // 初始化ascClient需要的几个参数
-        final String product = "Dysmsapi";// 短信API产品名称(短信产品名固定,无需修改)
-        final String domain = "dysmsapi.aliyuncs.com";// 短信API产品域名(接口地址固定,无需修改)
-        // 替换成你的AK
-        final String accessKeyId = dictionaryConfig.smsDomain().getAliyunSMSKey();// 你的accessKeyId,参考本文档步骤2
-        final String accessKeySecret = dictionaryConfig.smsDomain().getAliyunSMSSecret();// 你的accessKeySecret,参考本文档步骤2
-        // 初始化ascClient,暂时不支持多region(请勿修改)
-        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
-        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
-        IAcsClient acsClient = new DefaultAcsClient(profile);
-        // 组装请求对象
-        SendSmsRequest request = new SendSmsRequest();
-        // 使用post提交
-        request.setMethod(MethodType.POST);
-        // 必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式;发送国际/港澳台消息时,接收号码格式为00+国际区号+号码,如“0085200000000”
-        request.setPhoneNumbers(mobileNumber);
-        // 必填:短信签名-可在短信控制台中找到
-        request.setSignName(dictionaryConfig.smsDomain().getAliyunSMSSignName());
-        // 必填:短信模板-可在短信控制台中找到
-        request.setTemplateCode(templateCode);
-        // 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
-        // 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
-        request.setTemplateParam(variableParams);
-        // 可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
-        // request.setSmsUpExtendCode("90997");
-        // 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
-//             request.setOutId("yourOutId");
-        // 请求失败这里会抛ClientException异常
-
-        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
-        return sendSmsResponse;
-    }
-
-    public Map<String, String> getCodeAndContentByEnum(MessageEnum messageEnum) {
-        Map<String, String> result = new HashMap<>();
-        String templateContent = null;
-        String templateCode = null;
-        switch (messageEnum) {
-            case NOTICE_OF_AUDIT_PASS:
-                templateCode = dictionaryConfig.smsDomain().getAliyunSMSAuditPassCode();
-                templateContent = messageEnum.getTemplate();
-                break;
-            case NOTICE_OF_AUDIT_NOT_PASS:
-                templateCode = dictionaryConfig.smsDomain().getAliyunSMSAuditNotPassCode();
-                templateContent = messageEnum.getTemplate();
-                break;
-            case NOTICE_OF_EXAM_TASK_CREATED:
-                templateCode = dictionaryConfig.smsDomain().getAliyunSMSExamTaskCreatedCode();
-                templateContent = messageEnum.getTemplate();
-                break;
-            case NOTICE_OF_EXAM_TASK_WILL_EXPIRE:
-                templateCode = dictionaryConfig.smsDomain().getAliyunSMSExamTaskWillExpireCode();
-                templateContent = messageEnum.getTemplate();
-                break;
-            case NOTICE_OF_EXAM_TASK_OVERDUE:
-                templateCode = dictionaryConfig.smsDomain().getAliyunSMSExamTaskOverdueCode();
-                templateContent = messageEnum.getTemplate();
-                break;
-            case NOTICE_OF_ALLOCATION_WILL_EXPIRE:
-                templateCode = dictionaryConfig.smsDomain().getAliyunSMSAllocationWillExpireCode();
-                templateContent = messageEnum.getTemplate();
-                break;
-            case NOTICE_OF_ALLOCATION_OVERDUE:
-                templateCode = dictionaryConfig.smsDomain().getAliyunSMSAllocationOverdueCode();
-                templateContent = messageEnum.getTemplate();
-                break;
-            case NOTICE_OF_AUDIT_CREATED:
-                templateCode = dictionaryConfig.smsDomain().getAliyunSMSAuditCreatedCode();
-                templateContent = messageEnum.getTemplate();
-                break;
-            case NOTICE_OF_AUDIT_REVIEW:
-                templateCode = dictionaryConfig.smsDomain().getAliyunSMSAuditReviewCode();
-                templateContent = messageEnum.getTemplate();
-                break;
-            case NOTICE_OF_AUDIT_WILL_EXPIRE:
-                templateCode = dictionaryConfig.smsDomain().getAliyunSMSAuditWillExpireCode();
-                templateContent = messageEnum.getTemplate();
-                break;
-            case NOTICE_OF_AUDIT_OVERDUE:
-                templateCode = dictionaryConfig.smsDomain().getAliyunSMSAuditOverdueCode();
-                templateContent = messageEnum.getTemplate();
-                break;
-            case NOTICE_OF_AUDIT_REJECT:
-                templateCode = dictionaryConfig.smsDomain().getAliyunSMSAuditRejectCode();
-                templateContent = messageEnum.getTemplate();
-                break;
-            case NOTICE_OF_UPLOAD_STRUCTURE:
-                templateCode = dictionaryConfig.smsDomain().getAliyunSMSUploadStructureCode();
-                templateContent = messageEnum.getTemplate();
-                break;
-            case NOTICE_OF_AUDIT_COPY_USER:
-                templateCode = dictionaryConfig.smsDomain().getAliyunSMSAuditCopyUserCode();
-                templateContent = messageEnum.getTemplate();
-                break;
-            default:
-                break;
-        }
-        result.put("templateContent", templateContent);
-        result.put("templateCode", templateCode);
-        return result;
-    }
-}

+ 1 - 0
distributed-print-business/src/main/resources/mapper/TFFlowApproveMapper.xml

@@ -103,5 +103,6 @@
                 and temp.pendApproveUserName like concat('%',#{pendApproveUserName},'%')
             </if>
         </where>
+        order by temp.createTime desc
     </select>
 </mapper>

+ 1 - 1
distributed-print/src/main/java/com/qmth/distributed/print/api/BasicMessageController.java

@@ -3,7 +3,7 @@ package com.qmth.distributed.print.api;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.qmth.boot.api.constant.ApiConstant;
 import com.qmth.distributed.print.business.entity.BasicMessage;
-import com.qmth.distributed.print.business.enums.MessageEnum;
+import com.qmth.teachcloud.common.enums.MessageEnum;
 import com.qmth.distributed.print.business.service.BasicMessageService;
 import com.qmth.teachcloud.common.annotation.OperationLogDetail;
 import com.qmth.teachcloud.common.contant.SystemConstant;

+ 3 - 0
distributed-print/src/main/java/com/qmth/distributed/print/api/SysController.java

@@ -589,6 +589,9 @@ public class SysController {
                 case RESULT:
                     path = tbTask.getResultFilePath();
                     break;
+                case ERROR_FILE:
+                    path = tbTask.getErrorFilePath();
+                    break;
                 default:
                     break;
             }

+ 2 - 0
distributed-print/src/main/java/com/qmth/distributed/print/api/TBTaskController.java

@@ -125,6 +125,8 @@ public class TBTaskController {
                         && Objects.isNull(taskListResult.getErrorMessage())) {
                     taskListResult.setResetCreatePdf(true);
                 }
+                // 下载类型
+                taskListResult.setDownloadType(taskListResult.getHasImportFile() ? DownloadFileEnum.IMPORT_FILE.name() : DownloadFileEnum.RESULT.name());
             }
         }
         return ResultUtil.ok(taskListResultIPage);

+ 4 - 31
distributed-print/src/main/resources/application.properties

@@ -100,34 +100,7 @@ spring.jackson.time-zone=GMT+8
 com.qmth.logging.root-level=info
 com.qmth.logging.file-path=/Users/king/Downloads/distributed-print.log
 
-#aliyun SMS key
-sms.config.aliyunSMSKey=LTAI4Fi8jVRYT49QBXU9x5QX
-#aliyun SMS secret
-sms.config.aliyunSMSSecret=97aBLBfkQR5mzCiQa82yWLAH57eUd8
-sms.config.aliyunSMSSignName=\u9038\u6559\u4E91
-sms.config.aliyunSMSTplCode=SMS_147416565
-sms.config.aliyunSMSAuditPassCode=SMS_216425141
-sms.config.aliyunSMSAuditNotPassCode=SMS_216275156
-#\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0368\u05AA
-sms.config.aliyunSMSExamTaskCreatedCode=SMS_217436292
-#\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uCD7D\uFFFD\uFFFD\u0524\uFFFD\uFFFD\u0368\u05AA
-sms.config.aliyunSMSExamTaskWillExpireCode=SMS_217436295
-#\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0368\u05AA
-sms.config.aliyunSMSExamTaskOverdueCode=SMS_217426313
-#\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uCD7D\uFFFD\uFFFD\u0524\uFFFD\uFFFD\u0368\u05AA
-sms.config.aliyunSMSAllocationWillExpireCode=SMS_217406305
-#\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0368\u05AA
-sms.config.aliyunSMSAllocationOverdueCode=SMS_217406308
-#\uFFFD\uFFFD\u02F4\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0368\u05AA
-sms.config.aliyunSMSAuditCreatedCode=SMS_237216000
-#\uFFFD\uFFFD\u02F4\uFFFD\uFFFD\uFFFD\uFFFD\u07B8\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0368\u05AA
-sms.config.aliyunSMSAuditReviewCode=SMS_237216002
-#\uFFFD\uFFFD\u02F4\uFFFD\uFFFD\uCD7D\uFFFD\uFFFD\u0524\uFFFD\uFFFD\u0368\u05AA
-sms.config.aliyunSMSAuditWillExpireCode=SMS_217436302
-#\uFFFD\uFFFD\u02F4\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0368\u05AA
-sms.config.aliyunSMSAuditOverdueCode=SMS_217416271
-#\uFFFD\uFFFD\uFFFD\uFFFD
-sms.config.aliyunSMSAuditRejectCode=SMS_237206063
-# \uFFFD\u053E\uFFFD\u1E79\uFFFD\uFFFD\uFFFD\uFFFD\u03F4\uFFFD\u0368\u05AA
-sms.config.aliyunSMSUploadStructureCode=SMS_237201068
-sms.config.aliyunSMSAuditCopyUserCode=SMS_237206065
+#com.qmth.solar.access-key=274f823e5f59410f8b3bb6edcd8e2b6e
+#com.qmth.solar.access-secret=y7AO6W0TOdTF8HpWBwGHbp3wfIHsmUKr
+
+com.qmth.sms.server=https://solar.qmth.com.cn

+ 1 - 8
distributed-print/src/test/java/com/qmth/distributed/print/ServiceTest.java

@@ -3,34 +3,27 @@ package com.qmth.distributed.print;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.qmth.boot.tools.io.IOUtils;
 import com.qmth.distributed.print.business.bean.dto.examObject.ExamObjectDto;
 import com.qmth.distributed.print.business.bean.marking.CardJpgResult;
 import com.qmth.distributed.print.business.entity.ExamCardDetail;
 import com.qmth.distributed.print.business.entity.ExamPrintPlan;
 import com.qmth.distributed.print.business.entity.ExamStudent;
-import com.qmth.distributed.print.business.enums.ExamObjectType;
-import com.qmth.distributed.print.business.enums.MessageEnum;
+import com.qmth.teachcloud.common.enums.MessageEnum;
 import com.qmth.distributed.print.business.mapper.ExamStudentMapper;
 import com.qmth.distributed.print.business.service.*;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.BasicAttachment;
 import com.qmth.teachcloud.common.entity.BasicCourse;
 import com.qmth.teachcloud.common.entity.BasicPrintConfig;
-import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.common.service.BasicCourseService;
 import com.qmth.teachcloud.common.service.BasicVerifyCodeService;
 import com.qmth.teachcloud.common.util.ConvertUtil;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.mock.web.MockMultipartFile;
 import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
-import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.List;

+ 5 - 0
pom.xml

@@ -152,6 +152,11 @@
                 <artifactId>core-retrofit</artifactId>
                 <version>${qmth.boot.version}</version>
             </dependency>
+            <dependency>
+                <groupId>com.qmth.boot</groupId>
+                <artifactId>core-sms</artifactId>
+                <version>${qmth.boot.version}</version>
+            </dependency>
             <dependency>
                 <groupId>io.springfox</groupId>
                 <artifactId>springfox-swagger-ui</artifactId>

+ 4 - 0
teachcloud-common/pom.xml

@@ -50,6 +50,10 @@
             <groupId>com.qmth.boot</groupId>
             <artifactId>core-retrofit</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.qmth.boot</groupId>
+            <artifactId>core-sms</artifactId>
+        </dependency>
         <dependency>
             <groupId>io.netty</groupId>
             <artifactId>netty-all</artifactId>

+ 89 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/dto/excel/export/BasicStudentErrorExportDto.java

@@ -0,0 +1,89 @@
+package com.qmth.teachcloud.common.bean.dto.excel.export;
+
+import com.qmth.teachcloud.common.annotation.ExcelImportTempleteVaild;
+import com.qmth.teachcloud.common.annotation.ExcelProperty;
+
+import java.io.Serializable;
+
+/**
+ * @Description: 基础学生数据错误数据导出类
+ */
+@ExcelImportTempleteVaild(value = true)
+public class BasicStudentErrorExportDto implements Serializable {
+    @ExcelProperty(name = "姓名", index = 1)
+    private String studentName;
+
+    @ExcelProperty(name = "学号", index = 2)
+    private String studentCode;
+
+    @ExcelProperty(name = "手机号", index = 3)
+    private String phoneNumber;
+
+    @ExcelProperty(name = "学院", index = 4)
+    private String collegeName;
+
+    @ExcelProperty(name = "专业", index = 5)
+    private String majorName;
+
+    @ExcelProperty(name = "班级", index = 6)
+    private String clazzName;
+
+    @ExcelProperty(name = "错误原因", index = 7)
+    private String errorMsg;
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+
+    public String getStudentCode() {
+        return studentCode;
+    }
+
+    public void setStudentCode(String studentCode) {
+        this.studentCode = studentCode;
+    }
+
+    public String getPhoneNumber() {
+        return phoneNumber;
+    }
+
+    public void setPhoneNumber(String phoneNumber) {
+        this.phoneNumber = phoneNumber;
+    }
+
+    public String getCollegeName() {
+        return collegeName;
+    }
+
+    public void setCollegeName(String collegeName) {
+        this.collegeName = collegeName;
+    }
+
+    public String getMajorName() {
+        return majorName;
+    }
+
+    public void setMajorName(String majorName) {
+        this.majorName = majorName;
+    }
+
+    public String getClazzName() {
+        return clazzName;
+    }
+
+    public void setClazzName(String clazzName) {
+        this.clazzName = clazzName;
+    }
+
+    public String getErrorMsg() {
+        return errorMsg;
+    }
+
+    public void setErrorMsg(String errorMsg) {
+        this.errorMsg = errorMsg;
+    }
+}

+ 81 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/dto/excel/export/SysUserErrorExportDto.java

@@ -0,0 +1,81 @@
+package com.qmth.teachcloud.common.bean.dto.excel.export;
+
+import com.qmth.teachcloud.common.annotation.ExcelImportTempleteVaild;
+import com.qmth.teachcloud.common.annotation.ExcelNote;
+import com.qmth.teachcloud.common.annotation.ExcelProperty;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @Description: 系统用户错误数据导出Dto
+ */
+@ExcelImportTempleteVaild(value = true)
+public class SysUserErrorExportDto implements Serializable {
+
+    @ExcelProperty(name = "姓名", index = 1)
+    private String name;
+
+    @ExcelProperty(name = "工号", index = 2)
+    private String code;
+
+    @ExcelProperty(name = "手机号", index = 3)
+    private String phoneNumber;
+
+    @ExcelProperty(name = "组织架构", index = 4)
+    private String orgName;
+
+    @ExcelProperty(name = "角色", index = 5)
+    private String roleName;
+
+    @ExcelProperty(name = "错误原因", index = 6)
+    private String errorMsg;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getPhoneNumber() {
+        return phoneNumber;
+    }
+
+    public void setPhoneNumber(String phoneNumber) {
+        this.phoneNumber = phoneNumber;
+    }
+
+    public String getOrgName() {
+        return orgName;
+    }
+
+    public void setOrgName(String orgName) {
+        this.orgName = orgName;
+    }
+
+    public String getRoleName() {
+        return roleName;
+    }
+
+    public void setRoleName(String roleName) {
+        this.roleName = roleName;
+    }
+
+    public String getErrorMsg() {
+        return errorMsg;
+    }
+
+    public void setErrorMsg(String errorMsg) {
+        this.errorMsg = errorMsg;
+    }
+}

+ 23 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/result/SmsResponseResult.java

@@ -0,0 +1,23 @@
+package com.qmth.teachcloud.common.bean.result;
+
+public class SmsResponseResult {
+
+    private String code;
+    private String message;
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+}

+ 11 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/result/TaskListResult.java

@@ -61,6 +61,9 @@ public class TaskListResult implements Serializable {
     @ApiModelProperty(value = "是否有报告文件")
     Boolean hasReportFile;
 
+    @ApiModelProperty(value = "是否有错误文件")
+    Boolean hasErrorFile;
+
     @ApiModelProperty(value = "是否重新生成pdf")
     boolean resetCreatePdf;
 
@@ -198,4 +201,12 @@ public class TaskListResult implements Serializable {
     public void setHasReportFile(Boolean hasReportFile) {
         this.hasReportFile = hasReportFile;
     }
+
+    public Boolean getHasErrorFile() {
+        return hasErrorFile;
+    }
+
+    public void setHasErrorFile(Boolean hasErrorFile) {
+        this.hasErrorFile = hasErrorFile;
+    }
 }

+ 0 - 12
teachcloud-common/src/main/java/com/qmth/teachcloud/common/config/DictionaryConfig.java

@@ -2,7 +2,6 @@ package com.qmth.teachcloud.common.config;
 
 import com.qmth.teachcloud.common.domain.FssPrivateDomain;
 import com.qmth.teachcloud.common.domain.FssPublicDomain;
-import com.qmth.teachcloud.common.domain.SmsDomain;
 import com.qmth.teachcloud.common.domain.SysDomain;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.context.annotation.Bean;
@@ -29,17 +28,6 @@ public class DictionaryConfig {
         return new SysDomain();
     }
 
-    /**
-     * 短信配置
-     *
-     * @return
-     */
-    @Bean
-    @ConfigurationProperties(prefix = "sms.config")
-    public SmsDomain smsDomain() {
-        return new SmsDomain();
-    }
-
     @Bean
     @ConfigurationProperties(prefix = "com.qmth.fss.public", ignoreUnknownFields = false)
     public FssPublicDomain fssPublicDomain() {

+ 2 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/contant/SystemConstant.java

@@ -269,6 +269,8 @@ public class SystemConstant {
 
     public static final String ERROR_DATA_LIST = "errorDataList";
     public static final String DATA_COUNT = "dataCount";
+    public static final String SUCCESS_DATA_COUNT = "successDataCount";
+    public static final String ERROR_DATA_COUNT = "errorDataCount";
     public static final List<Long> MENU_MANAGE = Arrays.asList(507L, 508L, 530L, 531L, 675L, 676L, 795L, 796L, 797L, 798L, 799L, 800L, 801L, 802L);
     public static final float PAPER_DEVIATION = 2;
     public static final String COMMA_OF_ENGLISH = ",";

+ 0 - 197
teachcloud-common/src/main/java/com/qmth/teachcloud/common/domain/SmsDomain.java

@@ -1,197 +0,0 @@
-package com.qmth.teachcloud.common.domain;
-
-/**
- * 短信参数
- */
-public class SmsDomain {
-
-//    String smsNormalCode;
-//    Integer codeExpiredTime;
-//    Integer codeSendInterval;
-    String aliyunSMSKey;
-    String aliyunSMSSecret;
-    String aliyunSMSSignName;
-    String aliyunSMSTplCode;
-    String aliyunSMSAuditPassCode;
-    String aliyunSMSAuditNotPassCode;
-    String aliyunSMSExamTaskCreatedCode;
-    String aliyunSMSExamTaskWillExpireCode;
-    String aliyunSMSExamTaskOverdueCode;
-    String aliyunSMSAllocationWillExpireCode;
-    String aliyunSMSAllocationOverdueCode;
-    String aliyunSMSAuditCreatedCode;
-    String aliyunSMSAuditReviewCode;
-    String aliyunSMSAuditWillExpireCode;
-    String aliyunSMSAuditOverdueCode;
-    String aliyunSMSAuditRejectCode;
-    String aliyunSMSUploadStructureCode;
-    String aliyunSMSAuditCopyUserCode;
-
-//    public String getSmsNormalCode() {
-//        return smsNormalCode;
-//    }
-//
-//    public void setSmsNormalCode(String smsNormalCode) {
-//        this.smsNormalCode = smsNormalCode;
-//    }
-//
-//    public Integer getCodeExpiredTime() {
-//        return codeExpiredTime;
-//    }
-//
-//    public void setCodeExpiredTime(Integer codeExpiredTime) {
-//        this.codeExpiredTime = codeExpiredTime;
-//    }
-//
-//    public Integer getCodeSendInterval() {
-//        return codeSendInterval;
-//    }
-//
-//    public void setCodeSendInterval(Integer codeSendInterval) {
-//        this.codeSendInterval = codeSendInterval;
-//    }
-
-    public String getAliyunSMSKey() {
-        return aliyunSMSKey;
-    }
-
-    public void setAliyunSMSKey(String aliyunSMSKey) {
-        this.aliyunSMSKey = aliyunSMSKey;
-    }
-
-    public String getAliyunSMSSecret() {
-        return aliyunSMSSecret;
-    }
-
-    public void setAliyunSMSSecret(String aliyunSMSSecret) {
-        this.aliyunSMSSecret = aliyunSMSSecret;
-    }
-
-    public String getAliyunSMSSignName() {
-        return aliyunSMSSignName;
-    }
-
-    public void setAliyunSMSSignName(String aliyunSMSSignName) {
-        this.aliyunSMSSignName = aliyunSMSSignName;
-    }
-
-    public String getAliyunSMSTplCode() {
-        return aliyunSMSTplCode;
-    }
-
-    public void setAliyunSMSTplCode(String aliyunSMSTplCode) {
-        this.aliyunSMSTplCode = aliyunSMSTplCode;
-    }
-
-    public String getAliyunSMSAuditPassCode() {
-        return aliyunSMSAuditPassCode;
-    }
-
-    public void setAliyunSMSAuditPassCode(String aliyunSMSAuditPassCode) {
-        this.aliyunSMSAuditPassCode = aliyunSMSAuditPassCode;
-    }
-
-    public String getAliyunSMSAuditNotPassCode() {
-        return aliyunSMSAuditNotPassCode;
-    }
-
-    public void setAliyunSMSAuditNotPassCode(String aliyunSMSAuditNotPassCode) {
-        this.aliyunSMSAuditNotPassCode = aliyunSMSAuditNotPassCode;
-    }
-
-    public String getAliyunSMSExamTaskCreatedCode() {
-        return aliyunSMSExamTaskCreatedCode;
-    }
-
-    public void setAliyunSMSExamTaskCreatedCode(String aliyunSMSExamTaskCreatedCode) {
-        this.aliyunSMSExamTaskCreatedCode = aliyunSMSExamTaskCreatedCode;
-    }
-
-    public String getAliyunSMSExamTaskWillExpireCode() {
-        return aliyunSMSExamTaskWillExpireCode;
-    }
-
-    public void setAliyunSMSExamTaskWillExpireCode(String aliyunSMSExamTaskWillExpireCode) {
-        this.aliyunSMSExamTaskWillExpireCode = aliyunSMSExamTaskWillExpireCode;
-    }
-
-    public String getAliyunSMSExamTaskOverdueCode() {
-        return aliyunSMSExamTaskOverdueCode;
-    }
-
-    public void setAliyunSMSExamTaskOverdueCode(String aliyunSMSExamTaskOverdueCode) {
-        this.aliyunSMSExamTaskOverdueCode = aliyunSMSExamTaskOverdueCode;
-    }
-
-    public String getAliyunSMSAllocationWillExpireCode() {
-        return aliyunSMSAllocationWillExpireCode;
-    }
-
-    public void setAliyunSMSAllocationWillExpireCode(String aliyunSMSAllocationWillExpireCode) {
-        this.aliyunSMSAllocationWillExpireCode = aliyunSMSAllocationWillExpireCode;
-    }
-
-    public String getAliyunSMSAllocationOverdueCode() {
-        return aliyunSMSAllocationOverdueCode;
-    }
-
-    public void setAliyunSMSAllocationOverdueCode(String aliyunSMSAllocationOverdueCode) {
-        this.aliyunSMSAllocationOverdueCode = aliyunSMSAllocationOverdueCode;
-    }
-
-    public String getAliyunSMSAuditCreatedCode() {
-        return aliyunSMSAuditCreatedCode;
-    }
-
-    public void setAliyunSMSAuditCreatedCode(String aliyunSMSAuditCreatedCode) {
-        this.aliyunSMSAuditCreatedCode = aliyunSMSAuditCreatedCode;
-    }
-
-    public String getAliyunSMSAuditReviewCode() {
-        return aliyunSMSAuditReviewCode;
-    }
-
-    public void setAliyunSMSAuditReviewCode(String aliyunSMSAuditReviewCode) {
-        this.aliyunSMSAuditReviewCode = aliyunSMSAuditReviewCode;
-    }
-
-    public String getAliyunSMSAuditWillExpireCode() {
-        return aliyunSMSAuditWillExpireCode;
-    }
-
-    public void setAliyunSMSAuditWillExpireCode(String aliyunSMSAuditWillExpireCode) {
-        this.aliyunSMSAuditWillExpireCode = aliyunSMSAuditWillExpireCode;
-    }
-
-    public String getAliyunSMSAuditOverdueCode() {
-        return aliyunSMSAuditOverdueCode;
-    }
-
-    public void setAliyunSMSAuditOverdueCode(String aliyunSMSAuditOverdueCode) {
-        this.aliyunSMSAuditOverdueCode = aliyunSMSAuditOverdueCode;
-    }
-
-    public String getAliyunSMSAuditRejectCode() {
-        return aliyunSMSAuditRejectCode;
-    }
-
-    public void setAliyunSMSAuditRejectCode(String aliyunSMSAuditRejectCode) {
-        this.aliyunSMSAuditRejectCode = aliyunSMSAuditRejectCode;
-    }
-
-    public String getAliyunSMSUploadStructureCode() {
-        return aliyunSMSUploadStructureCode;
-    }
-
-    public void setAliyunSMSUploadStructureCode(String aliyunSMSUploadStructureCode) {
-        this.aliyunSMSUploadStructureCode = aliyunSMSUploadStructureCode;
-    }
-
-    public String getAliyunSMSAuditCopyUserCode() {
-        return aliyunSMSAuditCopyUserCode;
-    }
-
-    public void setAliyunSMSAuditCopyUserCode(String aliyunSMSAuditCopyUserCode) {
-        this.aliyunSMSAuditCopyUserCode = aliyunSMSAuditCopyUserCode;
-    }
-}

+ 1 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/DownloadFileEnum.java

@@ -16,6 +16,7 @@ public enum DownloadFileEnum {
     TASK_REPORT("任务报告文件"),
 
     SYNC_REPORT("同步报告文件"),
+    ERROR_FILE("错误数据文件"),
 
     RESULT("导出文件");
 

+ 1 - 3
distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/MessageEnum.java → teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/MessageEnum.java

@@ -1,6 +1,4 @@
-package com.qmth.distributed.print.business.enums;
-
-import com.qmth.teachcloud.common.enums.EnumResult;
+package com.qmth.teachcloud.common.enums;
 
 import java.util.ArrayList;
 import java.util.List;

+ 2 - 2
teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/impl/BasicStudentServiceImpl.java

@@ -287,8 +287,8 @@ public class BasicStudentServiceImpl extends ServiceImpl<BasicStudentMapper, Bas
             LinkedMultiValueMap<Integer, Object> excelMap = finalList.get(i);
             List<Object> basicStudentImportDtoList = excelMap.get(i);
 
-            assert basicStudentImportDtoList != null;
-            if (basicStudentImportDtoList.get(0) instanceof DescribeImportDto) {
+//            assert !basicStudentImportDtoList.isEmpty();
+            if (basicStudentImportDtoList.isEmpty() || basicStudentImportDtoList.get(0) instanceof DescribeImportDto) {
                 continue;
             }
             List<BasicStudentImportDto> datasource = basicStudentImportDtoList.stream().map(e -> {

+ 16 - 52
teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/impl/BasicVerifyCodeServiceImpl.java

@@ -1,15 +1,8 @@
 package com.qmth.teachcloud.common.service.impl;
 
-import com.aliyuncs.DefaultAcsClient;
-import com.aliyuncs.IAcsClient;
-import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
-import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
-import com.aliyuncs.exceptions.ClientException;
-import com.aliyuncs.http.MethodType;
-import com.aliyuncs.profile.DefaultProfile;
-import com.aliyuncs.profile.IClientProfile;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.teachcloud.common.bean.result.SmsResponseResult;
 import com.qmth.teachcloud.common.config.DictionaryConfig;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.BasicVerifyCode;
@@ -20,13 +13,12 @@ import com.qmth.teachcloud.common.mapper.BasicVerifyCodeMapper;
 import com.qmth.teachcloud.common.service.BasicVerifyCodeService;
 import com.qmth.teachcloud.common.service.CommonCacheService;
 import com.qmth.teachcloud.common.service.SysConfigService;
+import com.qmth.teachcloud.common.util.SmsSendUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Optional;
+import java.util.*;
 
 /**
  * <p>
@@ -39,15 +31,15 @@ import java.util.Optional;
 @Service
 public class BasicVerifyCodeServiceImpl extends ServiceImpl<BasicVerifyCodeMapper, BasicVerifyCode> implements BasicVerifyCodeService {
 
-    @Autowired
-    private DictionaryConfig dictionaryConfig;
-
     @Autowired
     private SysConfigService sysConfigService;
 
     @Resource
     CommonCacheService commonCacheService;
 
+    @Resource
+    SmsSendUtil smsSendUtil;
+
     @Override
     public void sendVeirfyCode(String mobileNumber, SysUser sysUser) {
         SysConfig sysConfig = sysConfigService.getByKey(SystemConstant.SYS_CODE_ENABLE);
@@ -73,38 +65,14 @@ public class BasicVerifyCodeServiceImpl extends ServiceImpl<BasicVerifyCodeMappe
             StringBuilder sb = new StringBuilder();
             sb.append((int) ((Math.random() * 9 + 1) * 1000));
             String verifyCode = sb.toString();
-            System.setProperty("sun.net.client.defaultConnectTimeout", "180000");
-            System.setProperty("sun.net.client.defaultReadTimeout", "18000");
-            // 初始化ascClient需要的几个参数
-            final String product = "Dysmsapi";// 短信API产品名称(短信产品名固定,无需修改)
-            final String domain = "dysmsapi.aliyuncs.com";// 短信API产品域名(接口地址固定,无需修改)
-            // 替换成你的AK
-            final String accessKeyId = dictionaryConfig.smsDomain().getAliyunSMSKey();// 你的accessKeyId,参考本文档步骤2
-            final String accessKeySecret = dictionaryConfig.smsDomain().getAliyunSMSSecret();// 你的accessKeySecret,参考本文档步骤2
-            // 初始化ascClient,暂时不支持多region(请勿修改)
-            IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
-            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
-            IAcsClient acsClient = new DefaultAcsClient(profile);
-            // 组装请求对象
-            SendSmsRequest request = new SendSmsRequest();
-            // 使用post提交
-            request.setMethod(MethodType.POST);
-            // 必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式;发送国际/港澳台消息时,接收号码格式为00+国际区号+号码,如“0085200000000”
-            request.setPhoneNumbers(mobileNumber);
-            // 必填:短信签名-可在短信控制台中找到
-            request.setSignName(dictionaryConfig.smsDomain().getAliyunSMSSignName());
-            // 必填:短信模板-可在短信控制台中找到
-            request.setTemplateCode(dictionaryConfig.smsDomain().getAliyunSMSTplCode());
-            // 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
-            // 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
-            request.setTemplateParam("{\"code\":\"" + verifyCode + "\"}");
-            // 可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
-            // request.setSmsUpExtendCode("90997");
-            // 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
-            // request.setOutId("yourOutId");
-            // 请求失败这里会抛ClientException异常
-            SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
-            if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
+
+            Map<String, Object> templateParam = new HashMap<>();
+            templateParam.put("code", verifyCode);
+
+            // 调用短信发送公共接口
+            SmsResponseResult smsResponseResult = smsSendUtil.sendSms(mobileNumber, SystemConstant.SMS_TPL_CODE, templateParam);
+
+            if (SmsSendUtil.OK.equals(smsResponseResult.getCode())) {
                 // 请求成功
                 SysConfig sysConfigSmsExpiredTime = commonCacheService.addSysConfigCache(SystemConstant.CODE_EXPIRED_TIME);
                 Optional.ofNullable(sysConfigSmsExpiredTime).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未配置短信验证码有效时间"));
@@ -129,13 +97,9 @@ public class BasicVerifyCodeServiceImpl extends ServiceImpl<BasicVerifyCodeMappe
                     this.updateById(basicVerifyCode);
                 }
             } else {
-                if ("isv.MOBILE_NUMBER_ILLEGAL".equals(sendSmsResponse.getCode())) {
-                    throw ExceptionResultEnum.ERROR.exception("非法手机号");
-                } else {
-                    throw ExceptionResultEnum.ERROR.exception(sendSmsResponse.getMessage());
-                }
+                throw ExceptionResultEnum.ERROR.exception(smsResponseResult.getMessage());
             }
-        } catch (ClientException e) {
+        } catch (Exception e) {
             throw ExceptionResultEnum.ERROR.exception("请重新获取验证码");
         }
     }

+ 18 - 1
teachcloud-common/src/main/java/com/qmth/teachcloud/common/util/ExcelUtil.java

@@ -175,7 +175,9 @@ public class ExcelUtil {
                         if (y == 0 && i == 0) {
                             for (Field field : fields) {
                                 ExcelNote excelNote = field.getAnnotation(ExcelNote.class);
-                                headList.add(excelNote.value());
+                                if(Objects.nonNull(excelNote)) {
+                                    headList.add(excelNote.value());
+                                }
                             }
                         }
                         ExcelImportTempleteVaild excelImportTempleteVaild = o.getClass().getDeclaredAnnotation(ExcelImportTempleteVaild.class);
@@ -348,6 +350,21 @@ public class ExcelUtil {
         return excelErrorList;
     }
 
+    public static String checkExcelField(Object obj) throws IllegalAccessException {
+        StringJoiner stringJoiner = new StringJoiner(";");
+        Field[] fields = obj.getClass().getDeclaredFields();
+        for (int i = 0; i < fields.length; i++) {
+            Field field = fields[i];
+            field.setAccessible(true);
+            Annotation annotation = field.getAnnotation(NotNull.class);
+            ExcelNote note = field.getAnnotation(ExcelNote.class);
+            if ((Objects.isNull(field.get(obj)) || Objects.equals("", field.get(obj))) && Objects.nonNull(annotation)) {
+                stringJoiner.add(note.value() + "必填");
+            }
+        }
+        return stringJoiner.toString();
+    }
+
     /**
      * 验证excel中某一行是否全部为空
      *

+ 181 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/util/SmsSendUtil.java

@@ -0,0 +1,181 @@
+package com.qmth.teachcloud.common.util;
+
+import com.alibaba.fastjson.JSONObject;
+import com.qmth.boot.api.exception.ApiException;
+import com.qmth.boot.core.sms.model.SmsSendRequest;
+import com.qmth.boot.core.sms.model.SmsSendResponse;
+import com.qmth.boot.core.sms.service.SmsService;
+import com.qmth.teachcloud.common.bean.result.SmsResponseResult;
+import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.entity.SysConfig;
+import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
+import com.qmth.teachcloud.common.enums.MessageEnum;
+import com.qmth.teachcloud.common.service.CommonCacheService;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 短信发送工具类
+ */
+@Component
+public class SmsSendUtil {
+
+    private static final Logger log = LoggerFactory.getLogger(SmsSendUtil.class);
+
+    public static final String OK = "OK";
+    private static final String ERROR = "ERROR";
+
+    @Resource
+    private SmsService smsService;
+
+    @Resource
+    CommonCacheService commonCacheService;
+
+
+    /**
+     * 短信发送接口
+     *
+     * @param phoneNumber   发送手机号
+     * @param configKey     参数key
+     * @param templateParam 模版变量
+     * @return bizId 本次操作业务标识
+     */
+    public SmsResponseResult sendSms(String phoneNumber, String configKey, Map<String, Object> templateParam) {
+        validPhoneNumber(phoneNumber);
+        SmsSendRequest smsSendRequest = new SmsSendRequest();
+        // 必填,发送手机号
+        smsSendRequest.setPhoneNumber(phoneNumber);
+        // 必填,短信签名
+        String signName = getConfigValue(SystemConstant.SMS_SIGN_NAME);
+        smsSendRequest.setSignName(signName);
+        // 必填,短信模版编号
+        String templateCode = getConfigValue(configKey);
+        smsSendRequest.setTemplateCode(templateCode);
+        //模版变量,可选
+        if (templateParam != null && !templateParam.isEmpty()) {
+            smsSendRequest.setTemplateParam(templateParam);
+        }
+        SmsResponseResult smsResponseResult = new SmsResponseResult();
+        try {
+            SmsSendResponse smsSendResponse = smsService.sendSms(smsSendRequest);
+            if (smsSendResponse == null) {
+                throw ExceptionResultEnum.ERROR.exception("短信发送失败");
+            }
+            smsResponseResult.setCode(OK);
+            smsResponseResult.setMessage(smsSendResponse.getBizId());
+        } catch (ApiException e) {
+            smsResponseResult.setCode(OK);
+            smsResponseResult.setMessage(e.getMessage());
+        }
+        return smsResponseResult;
+    }
+
+    /**
+     * 校验手机号
+     *
+     * @param phoneNumber 手机号
+     */
+    private void validPhoneNumber(String phoneNumber) {
+        if (StringUtils.isBlank(phoneNumber)) {
+            throw ExceptionResultEnum.ERROR.exception("手机号不能为空");
+        }
+        if (phoneNumber.length() != 11) {
+            throw ExceptionResultEnum.ERROR.exception("手机号长度必须为11位");
+        }
+    }
+
+    /**
+     * 校验文件存储配置参数
+     *
+     * @param configKey 参数key
+     */
+    private String getConfigValue(String configKey) {
+        if (StringUtils.isBlank(configKey)) {
+            throw ExceptionResultEnum.ERROR.exception("参数key值不能为空");
+        }
+        SysConfig sysConfig = commonCacheService.addSysConfigCache(configKey);
+        if (sysConfig == null) {
+            throw ExceptionResultEnum.ERROR.exception("参数key[" + configKey + "]数据不存在");
+        }
+        if (StringUtils.isBlank(sysConfig.getConfigValue())) {
+            throw ExceptionResultEnum.ERROR.exception("参数key[" + configKey + "]对应值不能为空");
+        }
+        return sysConfig.getConfigValue();
+    }
+
+    public Map<String, String> getCodeAndContentByEnum(MessageEnum messageEnum) {
+        Map<String, String> result = new HashMap<>();
+        String templateContent = null;
+        String templateCode = null;
+        switch (messageEnum) {
+            case NOTICE_OF_AUDIT_PASS:
+                templateCode = SystemConstant.SMS_AUDIT_PASS_CODE;
+                templateContent = messageEnum.getTemplate();
+                break;
+            case NOTICE_OF_AUDIT_NOT_PASS:
+                templateCode = SystemConstant.SMS_AUDIT_NOT_PASS_CODE;
+                templateContent = messageEnum.getTemplate();
+                break;
+            case NOTICE_OF_EXAM_TASK_CREATED:
+                templateCode = SystemConstant.SMS_EXAM_TASK_CREATE_CODE;
+                templateContent = messageEnum.getTemplate();
+                break;
+            case NOTICE_OF_EXAM_TASK_WILL_EXPIRE:
+                templateCode = SystemConstant.SMS_EXAM_TASK_WILL_EXPIRE_CODE;
+                templateContent = messageEnum.getTemplate();
+                break;
+            case NOTICE_OF_EXAM_TASK_OVERDUE:
+                templateCode = SystemConstant.SMS_EXAM_TASK_OVERDUE_CODE;
+                templateContent = messageEnum.getTemplate();
+                break;
+            case NOTICE_OF_ALLOCATION_WILL_EXPIRE:
+                templateCode = SystemConstant.SMS_ALLOCATION_WILL_EXPIRE_CODE;
+                templateContent = messageEnum.getTemplate();
+                break;
+            case NOTICE_OF_ALLOCATION_OVERDUE:
+                templateCode = SystemConstant.SMS_ALLOCATION_OVERDUE_CODE;
+                templateContent = messageEnum.getTemplate();
+                break;
+            case NOTICE_OF_AUDIT_CREATED:
+                templateCode = SystemConstant.SMS_AUDIT_CREATE_CODE;
+                templateContent = messageEnum.getTemplate();
+                break;
+            case NOTICE_OF_AUDIT_REVIEW:
+                templateCode = SystemConstant.SMS_AUDIT_REVIEW_CODE;
+                templateContent = messageEnum.getTemplate();
+                break;
+            case NOTICE_OF_AUDIT_WILL_EXPIRE:
+                templateCode = SystemConstant.SMS_AUDIT_WILL_EXPIRE_CODE;
+                templateContent = messageEnum.getTemplate();
+                break;
+            case NOTICE_OF_AUDIT_OVERDUE:
+                templateCode = SystemConstant.SMS_AUDIT_OVERDUE_CODE;
+                templateContent = messageEnum.getTemplate();
+                break;
+            case NOTICE_OF_AUDIT_REJECT:
+                templateCode = SystemConstant.SMS_AUDIT_REJECT_CODE;
+                templateContent = messageEnum.getTemplate();
+                break;
+            case NOTICE_OF_UPLOAD_STRUCTURE:
+                templateCode = SystemConstant.SMS_UPLOAD_STRUCTURE_CODE;
+                templateContent = messageEnum.getTemplate();
+                break;
+            case NOTICE_OF_AUDIT_COPY_USER:
+                templateCode = SystemConstant.SMS_AUDIT_COPY_USER_CODE;
+                templateContent = messageEnum.getTemplate();
+                break;
+            default:
+                break;
+        }
+        result.put("templateContent", templateContent);
+        result.put("templateCode", templateCode);
+        return result;
+    }
+
+}

+ 1 - 0
teachcloud-common/src/main/resources/mapper/TBTaskMapper.xml

@@ -16,6 +16,7 @@
             if(ISNULL(tbt.import_file_path),false,true) as hasImportFile,
             if(ISNULL(tbt.result_file_path),false,true) or if(ISNULL(tbt.import_file_path),false,true) as hasResultFile,
             if(ISNULL(tbt.report_file_path),false,true) as hasReportFile,
+            if(ISNULL(tbt.error_file_path),false,true) as hasErrorFile,
             tbt.reset_count as resetCount,
             tbt.error_message as errorMessage
             from