Jelajahi Sumber

消息服务-邮箱发送

linhuili 3 tahun lalu
induk
melakukan
13700e2346
26 mengubah file dengan 566 tambahan dan 64 penghapusan
  1. 1 1
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/controller/MessageController.java
  2. 1 1
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/controller/MessageTypeController.java
  3. 1 1
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/controller/SenderRegisterController.java
  4. 1 1
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/dao/MessageMapper.java
  5. 1 1
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/dao/MessageTypeMapper.java
  6. 1 1
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/dao/SenderRegisterMapper.java
  7. 30 0
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/model/dto/AttachmentDTO.java
  8. 1 1
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/model/MessageType.java
  9. 11 3
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/model/MessageVO.java
  10. 1 1
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/model/SenderRegister.java
  11. 1 2
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/service/IMessageService.java
  12. 1 2
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/service/IMessageTypeService.java
  13. 1 2
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/service/ISenderRegisterService.java
  14. 2 8
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/service/impl/MessageServiceImpl.java
  15. 1 6
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/service/impl/MessageTypeServiceImpl.java
  16. 1 3
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/service/impl/SenderRegisterServiceImpl.java
  17. 2 2
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/sender/controller/MessageSenderController.java
  18. 3 3
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/sender/service/IMessageSender.java
  19. 3 3
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/sender/service/MessageSenderFactory.java
  20. 2 3
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/sender/service/impl/AppMessageSender.java
  21. 131 4
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/sender/service/impl/MailMessageSender.java
  22. 2 3
      dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/sender/service/impl/SmsMessageSender.java
  23. 14 12
      dmp-cloud/dmp-message/src/main/resources/db/init/schema.sql
  24. 12 0
      dmp-common/pom.xml
  25. 63 0
      dmp-common/src/main/java/com/persagy/dmp/common/utils/Base64Utils.java
  26. 278 0
      dmp-common/src/main/java/com/persagy/dmp/common/utils/ExcelUtils.java

+ 1 - 1
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/controller/MessageController.java

@@ -10,7 +10,7 @@ import com.persagy.dmp.common.constant.ValidEnum;
 import com.persagy.dmp.common.exception.BusinessException;
 import com.persagy.dmp.common.model.response.CommonResult;
 import com.persagy.dmp.common.utils.ResultHelper;
-import com.persagy.dmp.message.model.MessageVO;
+import com.persagy.dmp.message.model.vo.MessageVO;
 import com.persagy.dmp.message.service.IMessageService;
 import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;

+ 1 - 1
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/controller/MessageTypeController.java

@@ -9,7 +9,7 @@ import com.persagy.dmp.common.constant.ResponseCode;
 import com.persagy.dmp.common.exception.BusinessException;
 import com.persagy.dmp.common.model.response.CommonResult;
 import com.persagy.dmp.common.utils.ResultHelper;
-import com.persagy.dmp.message.model.MessageType;
+import com.persagy.dmp.message.model.vo.MessageType;
 import com.persagy.dmp.message.service.IMessageTypeService;
 import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;

+ 1 - 1
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/controller/SenderRegisterController.java

@@ -9,7 +9,7 @@ import com.persagy.dmp.common.constant.ResponseCode;
 import com.persagy.dmp.common.exception.BusinessException;
 import com.persagy.dmp.common.model.response.CommonResult;
 import com.persagy.dmp.common.utils.ResultHelper;
-import com.persagy.dmp.message.model.SenderRegister;
+import com.persagy.dmp.message.model.vo.SenderRegister;
 import com.persagy.dmp.message.service.ISenderRegisterService;
 import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;

+ 1 - 1
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/dao/MessageMapper.java

@@ -1,7 +1,7 @@
 package com.persagy.dmp.message.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.persagy.dmp.message.model.MessageVO;
+import com.persagy.dmp.message.model.vo.MessageVO;
 import org.apache.ibatis.annotations.Mapper;
 
 /**

+ 1 - 1
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/dao/MessageTypeMapper.java

@@ -1,7 +1,7 @@
 package com.persagy.dmp.message.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.persagy.dmp.message.model.MessageType;
+import com.persagy.dmp.message.model.vo.MessageType;
 import org.apache.ibatis.annotations.Mapper;
 
 /**

+ 1 - 1
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/dao/SenderRegisterMapper.java

@@ -1,7 +1,7 @@
 package com.persagy.dmp.message.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.persagy.dmp.message.model.SenderRegister;
+import com.persagy.dmp.message.model.vo.SenderRegister;
 import org.apache.ibatis.annotations.Mapper;
 
 /**

+ 30 - 0
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/model/dto/AttachmentDTO.java

@@ -0,0 +1,30 @@
+package com.persagy.dmp.message.model.dto;
+
+import com.alibaba.fastjson.JSONArray;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 邮件所附属附件DTO
+ * @author linhuili
+ * @date 2021-09-30
+ */
+@Data
+public class AttachmentDTO {
+
+    /** 附件名称 */
+    private String attachmentName;
+
+    /** 附件base64字符串 */
+    private String attachmentValue;
+
+    /** sheet页名称 */
+    private String sheetName;
+
+    /** sheetLines */
+    private JSONArray sheetLines;
+
+    /** 此参数生成带excel的附件,数组为每一行数据 */
+    private List<AttachmentDTO> attachmentExcelArray;
+}

+ 1 - 1
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/model/MessageType.java

@@ -1,4 +1,4 @@
-package com.persagy.dmp.message.model;
+package com.persagy.dmp.message.model.vo;
 
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.persagy.dmp.common.model.entity.BaseEntity;

+ 11 - 3
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/model/MessageVO.java

@@ -1,12 +1,15 @@
-package com.persagy.dmp.message.model;
+package com.persagy.dmp.message.model.vo;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
 import com.persagy.dmp.common.model.entity.AuditableEntity;
+import com.persagy.dmp.message.model.dto.AttachmentDTO;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
-import org.hibernate.validator.constraints.Length;
 
 import javax.validation.constraints.NotNull;
+import java.util.List;
 
 /**
  * 消息
@@ -21,14 +24,19 @@ public class MessageVO extends AuditableEntity {
     /** 消息类型 */
     @NotNull(message = "消息类型ID不允许为空")
     private String typeId;
-    /** 接收用户 */
+    /** 接收用户,多个接收者可以用逗号分隔,最多100个地址 */
     private String userId;
+    /** 抄送用户, 多个抄送者可以用逗号分隔,最多100个地址(主要用于邮箱发送) */
+    private String copyToUserId;
     /** 消息标题 */
     @NotNull(message = "消息标题不允许为空")
     private String title;
     /** 消息详情 */
     @NotNull(message = "消息内容不允许为空")
     private String content;
+    /** 消息附件 */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<AttachmentDTO> attachments;
     /** 关联业务主键 */
     private String businessId;
     /** 所属项目 */

+ 1 - 1
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/model/SenderRegister.java

@@ -1,4 +1,4 @@
-package com.persagy.dmp.message.model;
+package com.persagy.dmp.message.model.vo;
 
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.persagy.dmp.common.model.entity.BaseEntity;

+ 1 - 2
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/service/IMessageService.java

@@ -2,8 +2,7 @@ package com.persagy.dmp.message.service;
 
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.persagy.dmp.message.model.MessageVO;
-import com.persagy.dmp.message.model.SenderRegister;
+import com.persagy.dmp.message.model.vo.MessageVO;
 import com.persagy.dmp.sender.service.IMessageSender;
 
 import java.util.List;

+ 1 - 2
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/service/IMessageTypeService.java

@@ -2,8 +2,7 @@ package com.persagy.dmp.message.service;
 
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.persagy.dmp.basic.model.QueryCriteria;
-import com.persagy.dmp.message.model.MessageType;
+import com.persagy.dmp.message.model.vo.MessageType;
 
 import java.util.List;
 

+ 1 - 2
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/service/ISenderRegisterService.java

@@ -2,8 +2,7 @@ package com.persagy.dmp.message.service;
 
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.persagy.dmp.message.model.MessageType;
-import com.persagy.dmp.message.model.SenderRegister;
+import com.persagy.dmp.message.model.vo.SenderRegister;
 
 import java.util.List;
 

+ 2 - 8
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/service/impl/MessageServiceImpl.java

@@ -1,17 +1,14 @@
 package com.persagy.dmp.message.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.text.StrFormatter;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.persagy.dmp.common.constant.ValidEnum;
 import com.persagy.dmp.common.exception.BusinessException;
 import com.persagy.dmp.message.dao.MessageMapper;
-import com.persagy.dmp.message.model.MessageType;
-import com.persagy.dmp.message.model.MessageVO;
-import com.persagy.dmp.message.model.SenderRegister;
+import com.persagy.dmp.message.model.vo.MessageVO;
+import com.persagy.dmp.message.model.vo.SenderRegister;
 import com.persagy.dmp.message.service.IMessageService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Primary;
@@ -19,9 +16,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 /**
  * 消息 服务实现
@@ -122,5 +117,4 @@ public class MessageServiceImpl extends ServiceImpl<MessageMapper, MessageVO> im
     public List<MessageVO> load(List<String> ids) {
         return dao.selectBatchIds(ids);
     }
-
 }

+ 1 - 6
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/service/impl/MessageTypeServiceImpl.java

@@ -4,17 +4,13 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.text.StrFormatter;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.persagy.dmp.basic.model.QueryCriteria;
-import com.persagy.dmp.common.constant.ResponseCode;
 import com.persagy.dmp.common.constant.ValidEnum;
 import com.persagy.dmp.common.exception.BusinessException;
 import com.persagy.dmp.message.dao.MessageTypeMapper;
-import com.persagy.dmp.message.model.MessageType;
+import com.persagy.dmp.message.model.vo.MessageType;
 import com.persagy.dmp.message.service.IMessageTypeService;
-import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -23,7 +19,6 @@ import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 /**
  * 消息类型 服务实现

+ 1 - 3
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/message/service/impl/SenderRegisterServiceImpl.java

@@ -9,9 +9,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.persagy.dmp.common.constant.ValidEnum;
 import com.persagy.dmp.common.exception.BusinessException;
 import com.persagy.dmp.message.dao.SenderRegisterMapper;
-import com.persagy.dmp.message.dao.SenderRegisterMapper;
-import com.persagy.dmp.message.model.SenderRegister;
-import com.persagy.dmp.message.model.SenderRegister;
+import com.persagy.dmp.message.model.vo.SenderRegister;
 import com.persagy.dmp.message.service.ISenderRegisterService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;

+ 2 - 2
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/sender/controller/MessageSenderController.java

@@ -3,7 +3,7 @@ package com.persagy.dmp.sender.controller;
 import com.persagy.dmp.common.constant.ResponseCode;
 import com.persagy.dmp.common.exception.BusinessException;
 import com.persagy.dmp.common.model.response.CommonResult;
-import com.persagy.dmp.message.model.MessageVO;
+import com.persagy.dmp.message.model.vo.MessageVO;
 import com.persagy.dmp.sender.service.IMessageSender;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -28,7 +28,7 @@ public class MessageSenderController {
      * @param messageVO
      */
     @PostMapping("/send")
-    public CommonResult<MessageVO> send(@RequestBody MessageVO messageVO){
+    public CommonResult<MessageVO> send(@RequestBody MessageVO messageVO) throws Exception{
        if(messageVO == null){
            throw new BusinessException(ResponseCode.A0400.getCode(), "消息体不能为空!");
        }

+ 3 - 3
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/sender/service/IMessageSender.java

@@ -1,7 +1,7 @@
 package com.persagy.dmp.sender.service;
 
-import com.persagy.dmp.message.model.MessageVO;
-import com.persagy.dmp.message.model.SenderRegister;
+import com.persagy.dmp.message.model.vo.MessageVO;
+import com.persagy.dmp.message.model.vo.SenderRegister;
 
 /**
  * 消息 执行接口
@@ -21,5 +21,5 @@ public interface IMessageSender {
      * 发送消息
      * @param vo
      */
-    void send(MessageVO vo);
+    void send(MessageVO vo) throws Exception;
 }

+ 3 - 3
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/sender/service/MessageSenderFactory.java

@@ -5,8 +5,8 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
 import com.persagy.dmp.common.helper.SpringHelper;
-import com.persagy.dmp.message.model.MessageVO;
-import com.persagy.dmp.message.model.SenderRegister;
+import com.persagy.dmp.message.model.vo.MessageVO;
+import com.persagy.dmp.message.model.vo.SenderRegister;
 import com.persagy.dmp.message.service.ISenderRegisterService;
 import lombok.extern.slf4j.Slf4j;
 
@@ -29,7 +29,7 @@ public class MessageSenderFactory {
      * 发送消息
      * @param vo
      */
-    public void sendMessage(MessageVO vo) {
+    public void sendMessage(MessageVO vo) throws Exception{
         if(vo == null || StrUtil.isBlank(vo.getTypeId())
                 || StrUtil.isBlank(vo.getSendChannel())) {
             return;

+ 2 - 3
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/sender/service/impl/AppMessageSender.java

@@ -9,11 +9,10 @@ import com.aliyuncs.profile.IClientProfile;
 import com.aliyuncs.push.model.v20160801.PushRequest;
 import com.aliyuncs.push.model.v20160801.PushResponse;
 import com.aliyuncs.utils.ParameterHelper;
-import com.persagy.dmp.message.model.MessageVO;
-import com.persagy.dmp.message.model.SenderRegister;
+import com.persagy.dmp.message.model.vo.MessageVO;
+import com.persagy.dmp.message.model.vo.SenderRegister;
 import com.persagy.dmp.sender.service.IMessageSender;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Service;
 
 import java.util.Date;

+ 131 - 4
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/sender/service/impl/MailMessageSender.java

@@ -1,13 +1,26 @@
 package com.persagy.dmp.sender.service.impl;
 
-import com.persagy.dmp.message.model.MessageVO;
-import com.persagy.dmp.message.model.SenderRegister;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.IdUtil;
+import com.persagy.dmp.common.exception.BusinessException;
+import com.persagy.dmp.common.utils.Base64Utils;
+import com.persagy.dmp.common.utils.ExcelUtils;
+import com.persagy.dmp.message.model.dto.AttachmentDTO;
+import com.persagy.dmp.message.model.vo.MessageVO;
+import com.persagy.dmp.message.model.vo.SenderRegister;
 import com.persagy.dmp.sender.service.IMessageSender;
+import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.mail.javamail.JavaMailSenderImpl;
-import org.springframework.stereotype.Component;
+import org.springframework.mail.javamail.MimeMessageHelper;
 import org.springframework.stereotype.Service;
 
+import javax.mail.internet.MimeMessage;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
 import java.util.Properties;
 
 /**
@@ -21,6 +34,9 @@ public class MailMessageSender implements IMessageSender {
     @Autowired
     private JavaMailSenderImpl mailSender;
 
+    @Value("${spring.mail.username}")
+    private String userFrom;
+
     @Override
     public boolean initParam(SenderRegister register) {
         Properties javaMailProperties = new Properties();
@@ -32,7 +48,118 @@ public class MailMessageSender implements IMessageSender {
     }
 
     @Override
-    public void send(MessageVO vo) {
+    public void send(MessageVO vo) throws Exception{
+        //邮件发送参数校验
+        checkParam(vo);
+        //邮件发送
+        this.push(vo);
+    }
+
+    /**
+     * 邮件发送
+     * @param vo
+     */
+    private void push(MessageVO vo){
+        MimeMessage mimeMessage = this.mailSender.createMimeMessage();
+        List<String> tempFiles = new ArrayList<>();
+        MimeMessageHelper helper = null;
+        try {
+            helper = new MimeMessageHelper(mimeMessage, true);
+            //设置发送人
+            helper.setFrom(userFrom);
+            //设置接收人
+            helper.setTo(vo.getUserId());
+            //设置抄送人
+            if (StringUtils.isNotEmpty(vo.getCopyToUserId())) {
+                helper.setCc(vo.getCopyToUserId().split(","));
+            }
+            //设置主题
+            helper.setSubject(vo.getTitle());
+            //设置邮件内容
+            helper.setText(vo.getContent());
+
+            //设置邮件附件信息
+            List<AttachmentDTO> attachments = vo.getAttachments();
+            String html = "";
+            for (AttachmentDTO attachment : attachments) {
+                //根据附件base64字符串添加附件信息
+                if(StringUtils.isNotEmpty(attachment.getAttachmentValue())){
+                    File file = Base64Utils.base64ToFile(attachment.getAttachmentValue());
+                    helper.addAttachment(attachment.getAttachmentName(), file);
+                    tempFiles.add(file.getAbsolutePath());
+                    continue;
+                }
+
+                //根据sheet页填充附件内容
+                ExcelUtils.ExcelModel excelModel = new ExcelUtils.ExcelModel();
+                for (int i = 0; i < attachment.getAttachmentExcelArray().size(); i++) {
+                    AttachmentDTO attachmentExcel = attachment.getAttachmentExcelArray().get(i);
+                    ExcelUtils.ExcelModel sheet = new ExcelUtils.ExcelModel();
+                    sheet.setSheetName(attachmentExcel.getSheetName());
+                    sheet.setSheetLines(attachmentExcel.getSheetLines());
+                    html += ExcelUtils.html(attachmentExcel.getSheetLines());
+                    excelModel.addSheet(sheet);
+                }
+                //添加附件信息
+                String tempFile = attachment.getAttachmentName().endsWith("xls") ? IdUtil.simpleUUID() + "xls" : IdUtil.simpleUUID() + ".xlsx";
+                ExcelUtils.writeInfoToExcel(tempFile, excelModel);
+                helper.addAttachment(attachment.getAttachmentName(), new File(tempFile));
+                tempFiles.add(tempFile);
+            }
+            //邮件发送
+            mailSender.send(mimeMessage);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }finally {
+            //删除临时文件
+            if (tempFiles.size() > 0) {
+                for (String tempFile : tempFiles) {
+                    ExcelUtils.deleteFile(tempFile);
+                }
+            }
+        }
+    }
+
+    /**
+     * 邮箱发送请求校验
+     * @param messageVO
+     * @throws Exception
+     */
+    private void checkParam(MessageVO messageVO) throws Exception{
+        //校验邮箱发送时间是否超时
+        long creationTime = messageVO.getCreationTime().getDate().getTime();
+        long nowDate = new Date().getTime();
+        if(nowDate - creationTime > 1000*60*10){
+            throw new BusinessException("请求超时");
+        }
+        List<AttachmentDTO> attachments = messageVO.getAttachments();
+        if(CollUtil.isNotEmpty(attachments)){
+            for (AttachmentDTO attachment : attachments) {
+                String attachmentName = attachment.getAttachmentName();
+                //附件名称校验
+                if(StringUtils.isNotEmpty(attachmentName)){
+                    throw new BusinessException("附件名称不能为空");
+                }
 
+                //附件内容校验
+                String attachmentValue = attachment.getAttachmentValue();
+                List<AttachmentDTO> attachmentExcelArray = attachment.getAttachmentExcelArray();
+                if (StringUtils.isEmpty(attachmentValue) && CollUtil.isEmpty(attachmentExcelArray)) {
+                    throw new BusinessException("attachmentValue或attachmentExcelArray不能同时为空");
+                }
+                if(CollUtil.isNotEmpty(attachmentExcelArray)){
+                    for (AttachmentDTO attach : attachmentExcelArray) {
+                        //sheet页名称非空校验
+                        if(StringUtils.isEmpty(attach.getSheetName())){
+                            throw new BusinessException("未设置excel sheet名称");
+                        }
+                        //excel内容非空校验
+                        if(CollUtil.isEmpty(attach.getSheetLines())){
+                            throw new BusinessException("excel未设置内容");
+                        }
+                    }
+                }
+            }
+        }
     }
 }

+ 2 - 3
dmp-cloud/dmp-message/src/main/java/com/persagy/dmp/sender/service/impl/SmsMessageSender.java

@@ -1,9 +1,8 @@
 package com.persagy.dmp.sender.service.impl;
 
-import com.persagy.dmp.message.model.MessageVO;
-import com.persagy.dmp.message.model.SenderRegister;
+import com.persagy.dmp.message.model.vo.MessageVO;
+import com.persagy.dmp.message.model.vo.SenderRegister;
 import com.persagy.dmp.sender.service.IMessageSender;
-import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Service;
 
 /**

+ 14 - 12
dmp-cloud/dmp-message/src/main/resources/db/init/schema.sql

@@ -45,18 +45,20 @@ CREATE TABLE IF NOT EXISTS "dt_message" (
 "id" varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '主键id',
 "type_id" varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '消息类型',
 "user_id" varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '接收用户',
-"title" varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '消息标题',
-"content" text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '消息详情',
-"business_id" varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '关联业务主键',
-"project_id" varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '所属项目',
-"send_channel" varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '发送渠道',
+"copy_to_user_id" text COMMENT '抄送用户,多个抄送者可以用逗号分隔,最多100个地址(主要用于邮箱发送)',
+"title" varchar(255) NOT NULL,
+"content" text NOT NULL,
+"business_id" varchar(40) DEFAULT NULL,
+"project_id" varchar(40) DEFAULT NULL,
+"send_channel" varchar(255) NOT NULL COMMENT '发送渠道',
 "read_flag" tinyint(1) DEFAULT NULL COMMENT '已读标示',
 "top_flag" tinyint(1) DEFAULT NULL COMMENT '置顶标示',
-"creator" varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '创建人',
-"creation_time" char(14) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '创建时间',
-"modifier" varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '最后修改人',
-"modified_time" char(14) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '最后修改时间',
-"valid" tinyint(1) DEFAULT NULL COMMENT '合法标识',
-"ts" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '乐观锁',
+"attachments" json DEFAULT NULL COMMENT '附件',
+"creator" varchar(32) DEFAULT NULL,
+"creation_time" char(14) DEFAULT NULL,
+"modifier" varchar(32) DEFAULT NULL,
+"modified_time" char(14) DEFAULT NULL,
+"valid" tinyint(1) DEFAULT NULL,
+"ts" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
 PRIMARY KEY ("id") USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3

+ 12 - 0
dmp-common/pom.xml

@@ -36,5 +36,17 @@
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>3.17</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>3.17</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 </project>

+ 63 - 0
dmp-common/src/main/java/com/persagy/dmp/common/utils/Base64Utils.java

@@ -0,0 +1,63 @@
+package com.persagy.dmp.common.utils;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Base64;
+
+
+ /**
+ * Base64Utils
+ * @author linhuili
+ * @date 2021-09-30
+ */
+public class Base64Utils {
+
+     /**
+      * base64编码格式的数据转成文件
+      * @param base64
+      * @return
+      */
+    public static File base64ToFile(String base64) {
+
+        if (base64 == null || "".equals(base64)) {
+            return null;
+        }
+        byte[] buff = Base64.getDecoder().decode(base64);
+        File file = null;
+        FileOutputStream fout = null;
+        try {
+            file = File.createTempFile("tmp", null);
+            fout = new FileOutputStream(file);
+            fout.write(buff);
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if (fout != null) {
+                try {
+                    fout.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return file;
+    }
+
+
+    public static String encryptToBase64(String filePath) {
+        if (filePath == null) {
+            return null;
+        }
+        try {
+            byte[] b = Files.readAllBytes(Paths.get(filePath));
+            return Base64.getEncoder().encodeToString(b);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+
+    }
+
+}

+ 278 - 0
dmp-common/src/main/java/com/persagy/dmp/common/utils/ExcelUtils.java

@@ -0,0 +1,278 @@
+package com.persagy.dmp.common.utils;
+
+
+import com.alibaba.fastjson.JSONArray;
+import lombok.Data;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * ExcelUtils
+ * @author linhuili
+ * @date 2021-09-30
+ */
+public class ExcelUtils {
+
+    public static void main(String[] args) throws Exception {
+        // 读测试
+     /*   InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("excel/equipment.xlsx");
+        List<List<String>> result = getExcelSheetInfo(in,"设备");*/
+
+        // 写测试
+        ExcelModel excelModel = new ExcelModel();
+
+        JSONArray rowList = new JSONArray();
+        JSONArray columnList = new JSONArray();
+        columnList.add("1你好");
+        columnList.add("2");
+        columnList.add("3");
+        rowList.add(columnList);
+        ExcelModel sheet1 = new ExcelModel();
+        sheet1.setSheetName("1");
+        sheet1.setSheetLines(rowList);
+
+        ExcelModel sheet2 = new ExcelModel();
+        sheet2.setSheetName("2");
+        sheet2.setSheetLines(rowList);
+        excelModel.addSheet(sheet1);
+        excelModel.addSheet(sheet2);
+        writeInfoToExcel("temp.xls", excelModel);
+    }
+
+    @Data
+    public static class ExcelModel {
+        private List<ExcelModel> sheetDatas;
+        private String sheetName;
+        private JSONArray sheetLines;
+
+        public void addSheet(ExcelModel sheet) {
+            if (sheetDatas == null) {
+                sheetDatas = new ArrayList<>();
+            }
+            sheetDatas.add(sheet);
+        }
+    }
+
+
+    /**
+     * description 读取excel模版 将数据写入excel
+     *
+     * @param filePath   生成的excel文件的path
+     * @param excelModel excel数据
+     * @return void
+     * @author feng
+     * @since 17:35 2018/7/11
+     */
+    public static void writeInfoToExcel(String filePath, ExcelModel excelModel) throws Exception {
+        // 根据模板,创建工作簿
+        Workbook workBook = null;
+        // 输出流
+        OutputStream out = null;
+        try {
+            out = new FileOutputStream(new File(filePath));
+            int maxLines = 65535;
+            if (filePath.endsWith("xls")) {
+                workBook = new HSSFWorkbook();
+            } else {
+                maxLines = 1048575;
+                workBook = new SXSSFWorkbook(10000);
+            }
+            for (ExcelModel sheetData : excelModel.getSheetDatas()) {
+                JSONArray rowInfoList = sheetData.getSheetLines();
+                String sheetName = sheetData.getSheetName();
+                Sheet sheet = workBook.createSheet(sheetName);
+                // 输出流
+                for (int rowNumber = 0; rowNumber < rowInfoList.size(); rowNumber++) {
+                    if (rowNumber == maxLines) {
+                        break;
+                    }
+                    JSONArray lines = rowInfoList.getJSONArray(rowNumber);
+                    for (int columnNumber = 0; columnNumber < lines.size(); columnNumber++) {
+                        createCell(workBook, sheet, rowNumber, columnNumber, lines.getString(columnNumber));
+                    }
+                }
+            }
+
+            workBook.write(out);
+        } finally {
+            if (out != null) {
+                out.flush();
+                out.close();
+            }
+            if (workBook != null) {
+                workBook.close();
+            }
+        }
+    }
+
+    /**
+     * description 读取excel信息
+     *
+     * @param in        文件输入流
+     * @param sheetName sheet名称
+     * @return java.util.List<java.util.List < java.lang.String>> 行信息的集合
+     * @author feng
+     * @since 16:16 2018/7/11
+     */
+    public static List<List<String>> getExcelSheetInfo(InputStream in, String sheetName) throws Exception {
+        Workbook workBook = WorkbookFactory.create(in);
+        // 遍历excel中的sheet
+        for (int numSheet = 0; numSheet < workBook.getNumberOfSheets(); numSheet++) {
+            List<List<String>> resultInfo = new ArrayList<>();
+            Sheet sheet = workBook.getSheetAt(numSheet);
+            if (sheet == null || !sheetName.equals(sheet.getSheetName())) {
+                continue;
+            }
+
+            int lastColumnNum = 0;
+            for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) {
+                Row row = sheet.getRow(rowNum);
+                if (row == null) {
+                    continue;
+                }
+                if (lastColumnNum < row.getLastCellNum()) {
+                    lastColumnNum = row.getLastCellNum();
+                }
+            }
+
+            for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) {
+                Row row = sheet.getRow(rowNum);
+                ArrayList<String> curarr = new ArrayList<>();
+                if (row == null) {
+                    for (int columnNum = 0; columnNum < lastColumnNum; columnNum++) {
+                        curarr.add("");
+                    }
+                } else {
+                    for (int columnNum = 0; columnNum < lastColumnNum; columnNum++) {
+                        Cell cell = row.getCell(columnNum);
+                        curarr.add(getCellStringValue(cell));
+                    }
+                }
+                resultInfo.add(curarr);
+            }
+            return resultInfo;
+
+        }
+        return null;
+    }
+
+    /**
+     * 创建excel
+     * @param workbook
+     * @param sheet
+     * @param rowNumber
+     * @param cellNumber
+     * @param content
+     */
+    public static void createCell(Workbook workbook, Sheet sheet, int rowNumber, int cellNumber, String content) {
+
+        Row row = sheet.getRow(rowNumber);
+        if (row == null) {
+            row = sheet.createRow(rowNumber);
+        }
+
+        Cell cell = row.getCell(cellNumber);
+        if (cell == null) {
+            cell = row.createCell(cellNumber);
+        }
+
+        CellStyle cellStyle = workbook.createCellStyle();
+        cellStyle.setAlignment(HorizontalAlignment.CENTER);
+        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+
+        cell.setCellStyle(cellStyle);
+        if (content == null) {
+            content = "";
+        }
+        cell.setCellValue(content);
+    }
+
+    /**
+     * 获取单元格值
+     * @param cell
+     * @return
+     * @throws Exception
+     */
+    public static String getCellStringValue(Cell cell) throws Exception {
+        if (cell == null) {
+            return "";
+        }
+        String value;
+        switch (cell.getCellTypeEnum()) {
+            case STRING:
+                value = cell.getStringCellValue();
+                break;
+            case NUMERIC:
+                if (DateUtil.isCellDateFormatted(cell)) {
+                    value = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(cell.getDateCellValue());
+                } else {
+                    value = new BigDecimal(Double.toString(cell.getNumericCellValue())).longValue() + "";
+                }
+                break;
+            case BOOLEAN:
+                value = String.valueOf(cell.getBooleanCellValue());
+                break;
+            case BLANK:
+                value = "";
+                break;
+            case ERROR:
+                throw new Exception("can not resolve this cell! CELL_TYPE_ERROR! ");
+            case FORMULA:
+                value = cell.getCellFormula();
+                break;
+            default:
+                value = cell.getStringCellValue();
+                break;
+        }
+
+        return value;
+    }
+
+    /**
+     * 删除单个文件
+     *
+     * @param sPath 被删除文件的文件名
+     */
+    public static void deleteFile(String sPath) {
+        File file = new File(sPath);
+        // 路径为文件且不为空则进行删除
+        if (file.isFile() && file.exists()) {
+            file.delete();
+        }
+    }
+
+
+    /**
+     * 生成html格式的数据
+     * @param datas
+     * @return
+     */
+    public static String html(JSONArray datas){
+        StringBuilder content = new StringBuilder("<html><head><style>.table-d table {background: #000;margin-top: 50px;}.table-d table td {background: #FFF;" +
+                "font-size: 11.0pt;font-weight: 400;font-style: normal;text-decoration: none;font-family: 宋体;white-space: nowrap}</style></head><body>");
+        content.append("<div class=\"table-d\"><table width=\"auto\" border=\"0\" cellspacing=\"1\" cellpadding=\"0\">");
+        for (int i = 0; i < datas.size(); i++) {
+            JSONArray data = datas.getJSONArray(i);
+            content.append("<tr>");
+            for (int i1 = 0; i1 < data.size(); i1++) {
+                content.append("<td>" + data.getString(i1) + "</td>"); //第一列
+            }
+            content.append("</tr>");
+        }
+        content.append("</div></table>");
+        content.append("</body></html>");
+        return content.toString();
+    }
+
+}