Przeglądaj źródła

云帆bug修复

24282 2 lat temu
rodzic
commit
01465e137a
18 zmienionych plików z 621 dodań i 109 usunięć
  1. 4 2
      bladex-saas-project/new-mail/src/main/java/com/fjhx/config/TaskPoolConfig.java
  2. 0 18
      bladex-saas-project/new-mail/src/main/java/com/fjhx/controller/MailAddressController.java
  3. 0 18
      bladex-saas-project/new-mail/src/main/java/com/fjhx/controller/MailAttachmentController.java
  4. 0 18
      bladex-saas-project/new-mail/src/main/java/com/fjhx/controller/MailFolderController.java
  5. 67 2
      bladex-saas-project/new-mail/src/main/java/com/fjhx/controller/MailInfoController.java
  6. 0 18
      bladex-saas-project/new-mail/src/main/java/com/fjhx/controller/MailMessageController.java
  7. 0 19
      bladex-saas-project/new-mail/src/main/java/com/fjhx/controller/MailboxController.java
  8. 57 0
      bladex-saas-project/new-mail/src/main/java/com/fjhx/dto/SendDto.java
  9. 5 0
      bladex-saas-project/new-mail/src/main/java/com/fjhx/entity/MailAttachment.java
  10. 15 0
      bladex-saas-project/new-mail/src/main/java/com/fjhx/entity/MailInfo.java
  11. 0 4
      bladex-saas-project/new-mail/src/main/java/com/fjhx/entity/MailMessage.java
  12. 3 0
      bladex-saas-project/new-mail/src/main/java/com/fjhx/service/MailFolderService.java
  13. 3 0
      bladex-saas-project/new-mail/src/main/java/com/fjhx/service/MailInfoService.java
  14. 12 4
      bladex-saas-project/new-mail/src/main/java/com/fjhx/service/impl/CoreServiceImpl.java
  15. 243 2
      bladex-saas-project/new-mail/src/main/java/com/fjhx/service/impl/MailFolderServiceImpl.java
  16. 25 0
      bladex-saas-project/new-mail/src/main/java/com/fjhx/service/impl/MailInfoServiceImpl.java
  17. 167 4
      bladex-saas-project/new-mail/src/main/java/com/fjhx/utils/EmailUtil.java
  18. 20 0
      bladex-saas-project/new-mail/src/main/java/com/fjhx/vo/MailDetailsVo.java

+ 4 - 2
bladex-saas-project/new-mail/src/main/java/com/fjhx/config/TaskPoolConfig.java

@@ -1,5 +1,6 @@
 package com.fjhx.config;
 
+import cn.hutool.core.thread.ThreadUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -28,8 +29,9 @@ public class TaskPoolConfig {
                 TimeUnit.SECONDS,
                 new ArrayBlockingQueue<>(20),
                 (runnable, executor) -> {
-                    log.info("线程池已满,由原线程执行");
-                    runnable.run();
+                    // 等待30秒之后重新入线程池
+                    ThreadUtil.sleep(30 * 1000);
+                    executor.execute(runnable);
                 }
         );
     }

+ 0 - 18
bladex-saas-project/new-mail/src/main/java/com/fjhx/controller/MailAddressController.java

@@ -1,18 +0,0 @@
-package com.fjhx.controller;
-
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * <p>
- * 邮件关联地址表 前端控制器
- * </p>
- *
- * @author zlj
- * @since 2023-03-06
- */
-@RestController
-@RequestMapping("/mailAddress")
-public class MailAddressController {
-
-}

+ 0 - 18
bladex-saas-project/new-mail/src/main/java/com/fjhx/controller/MailAttachmentController.java

@@ -1,18 +0,0 @@
-package com.fjhx.controller;
-
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * <p>
- *  前端控制器
- * </p>
- *
- * @author zlj
- * @since 2023-03-06
- */
-@RestController
-@RequestMapping("/mailAttachment")
-public class MailAttachmentController {
-
-}

+ 0 - 18
bladex-saas-project/new-mail/src/main/java/com/fjhx/controller/MailFolderController.java

@@ -1,18 +0,0 @@
-package com.fjhx.controller;
-
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * <p>
- * 邮箱文件夹 前端控制器
- * </p>
- *
- * @author zlj
- * @since 2023-03-06
- */
-@RestController
-@RequestMapping("/mailFolder")
-public class MailFolderController {
-
-}

+ 67 - 2
bladex-saas-project/new-mail/src/main/java/com/fjhx/controller/MailInfoController.java

@@ -1,7 +1,20 @@
 package com.fjhx.controller;
 
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.fjhx.dto.SendDto;
+import com.fjhx.entity.MailFolder;
+import com.fjhx.entity.MailInfo;
+import com.fjhx.entity.Mailbox;
+import com.fjhx.service.MailFolderService;
+import com.fjhx.service.MailInfoService;
+import com.fjhx.service.MailboxService;
+import com.fjhx.vo.MailDetailsVo;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.api.R;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 /**
  * <p>
@@ -15,7 +28,59 @@ import org.springframework.web.bind.annotation.RestController;
 @RequestMapping("/mailInfo")
 public class MailInfoController {
 
+    @Autowired
+    private MailFolderService mailFolderService;
+
+    @Autowired
+    private MailInfoService mailInfoService;
+
+    @Autowired
+    private MailboxService mailboxService;
+
+    /**
+     * 获取文件夹列表
+     */
+    @GetMapping("/mailboxList")
+    public R mailboxList(@RequestParam String userId) {
+        List<Mailbox> list = mailboxService.list(Wrappers.<Mailbox>lambdaQuery()
+                .eq(Mailbox::getUserId, userId).eq(Mailbox::getTenantId, AuthUtil.getTenantId()));
+        return R.data(list);
+    }
+
+
+    /**
+     * 获取文件夹列表
+     */
+    @GetMapping("/folderList")
+    public R folderList(@RequestParam("mailboxId") String mailboxId) {
+        List<MailFolder> list = mailFolderService.list(
+                Wrappers.<MailFolder>lambdaQuery().eq(MailFolder::getMailboxId, mailboxId));
+        return R.data(list);
+    }
+
+    /**
+     * 获取邮件列表
+     */
+    @GetMapping
+    public R getMailInfo(@RequestParam("folderId") Long folderId) {
+        List<MailInfo> list = mailInfoService.list(
+                Wrappers.<MailInfo>lambdaQuery().eq(MailInfo::getFolderId, folderId).orderByDesc(MailInfo::getId));
+        return R.data(list);
+    }
 
+    /**
+     * 邮箱详情
+     */
+    @GetMapping("/details")
+    public R details(@RequestParam("mailId") Long mailId) {
+        MailDetailsVo mailDetailsVo = mailFolderService.getDetails(mailId);
+        return R.data(mailDetailsVo);
+    }
 
+    @PostMapping("/send")
+    public R send(@RequestBody SendDto dto) {
+        mailInfoService.send(dto);
+        return R.success();
+    }
 
 }

+ 0 - 18
bladex-saas-project/new-mail/src/main/java/com/fjhx/controller/MailMessageController.java

@@ -1,18 +0,0 @@
-package com.fjhx.controller;
-
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * <p>
- * 邮件正文 前端控制器
- * </p>
- *
- * @author zlj
- * @since 2023-03-06
- */
-@RestController
-@RequestMapping("/mailMessage")
-public class MailMessageController {
-
-}

+ 0 - 19
bladex-saas-project/new-mail/src/main/java/com/fjhx/controller/MailboxController.java

@@ -1,19 +0,0 @@
-package com.fjhx.controller;
-
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * <p>
- * 业务员邮箱信息表 前端控制器
- * </p>
- *
- * @author zlj
- * @since 2023-03-06
- */
-@RestController
-@RequestMapping("/mailbox")
-public class MailboxController {
-
-
-}

+ 57 - 0
bladex-saas-project/new-mail/src/main/java/com/fjhx/dto/SendDto.java

@@ -0,0 +1,57 @@
+package com.fjhx.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springblade.system.attachment.entity.Attachment;
+
+import java.util.List;
+
+@Getter
+@Setter
+public class SendDto {
+
+    /**
+     * 邮箱id
+     */
+    String mailboxId;
+
+    /**
+     * 发送
+     */
+    private List<Address> to;
+    /**
+     * 抄送
+     */
+    private List<Address> cc;
+    /**
+     * 密送
+     */
+    private List<Address> bcc;
+    /**
+     * 回复
+     */
+    private List<Address> replyTo;
+
+    /**
+     * 标题
+     */
+    private String subject;
+
+    /**
+     * 正文
+     */
+    private String content;
+
+    /**
+     * 附件
+     */
+    private List<Attachment> attachmentList;
+
+    @Getter
+    @Setter
+    public static class Address {
+        private String address;
+        private String personal;
+    }
+
+}

+ 5 - 0
bladex-saas-project/new-mail/src/main/java/com/fjhx/entity/MailAttachment.java

@@ -31,6 +31,11 @@ public class MailAttachment implements Serializable {
     private Long id;
 
     /**
+     * 邮件主表id
+     */
+    private Long mailInfoId;
+
+    /**
      * 附件名称
      */
     private String name;

+ 15 - 0
bladex-saas-project/new-mail/src/main/java/com/fjhx/entity/MailInfo.java

@@ -90,4 +90,19 @@ public class MailInfo implements Serializable {
      */
     private Date createTime;
 
+    /**
+     * 是否同步正文
+     */
+    private Integer messageSync;
+
+    /**
+     * 是否同步地址信息
+     */
+    private Integer addressSync;
+
+    /**
+     * 是否同步附件
+     */
+    private Integer attachmentSync;
+
 }

+ 0 - 4
bladex-saas-project/new-mail/src/main/java/com/fjhx/entity/MailMessage.java

@@ -44,8 +44,4 @@ public class MailMessage implements Serializable {
      */
     private String mimeType;
 
-    /**
-     * 编码
-     */
-    private String encoding;
 }

+ 3 - 0
bladex-saas-project/new-mail/src/main/java/com/fjhx/service/MailFolderService.java

@@ -2,6 +2,7 @@ package com.fjhx.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fjhx.entity.MailFolder;
+import com.fjhx.vo.MailDetailsVo;
 
 /**
  * <p>
@@ -13,4 +14,6 @@ import com.fjhx.entity.MailFolder;
  */
 public interface MailFolderService extends IService<MailFolder> {
 
+    MailDetailsVo getDetails(Long mailId);
+
 }

+ 3 - 0
bladex-saas-project/new-mail/src/main/java/com/fjhx/service/MailInfoService.java

@@ -1,6 +1,7 @@
 package com.fjhx.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.fjhx.dto.SendDto;
 import com.fjhx.entity.MailInfo;
 
 /**
@@ -13,4 +14,6 @@ import com.fjhx.entity.MailInfo;
  */
 public interface MailInfoService extends IService<MailInfo> {
 
+    void send(SendDto dto);
+
 }

+ 12 - 4
bladex-saas-project/new-mail/src/main/java/com/fjhx/service/impl/CoreServiceImpl.java

@@ -65,7 +65,7 @@ public class CoreServiceImpl {
     // 单次同步邮件总次数
     private static int mailCount;
     // 最小等待时间
-    private static final long minWaitingTime = 1000 * 60 * 5;
+    private static final long minWaitingTime = 1000 * 60 * 3;
     // 初始化同步邮件天数
     private static final int initDay = 7;
 
@@ -89,6 +89,12 @@ public class CoreServiceImpl {
     }
 
     @PostConstruct
+    public void init() {
+        // 发起邮件同步
+        new Thread(this::monitorMail).start();
+    }
+
+
     public void monitorMail() {
 
         // 开始处理时间
@@ -106,7 +112,7 @@ public class CoreServiceImpl {
         log.info("开始第 {} 伦邮件同步,共同步 {} 个邮箱", num, list.size());
 
         // 定义一个线程计数器
-        CountDownLatch countDownLatch = new CountDownLatch(list.size());
+        // CountDownLatch countDownLatch = new CountDownLatch(list.size());
 
         // 开启抓取邮件任务
         for (Mailbox mailbox : list) {
@@ -250,8 +256,10 @@ public class CoreServiceImpl {
             mailInfo.setFolderId(mailFolder.getId());
             mailInfo.setFolderName(mailFolder.getName());
 
-            InternetAddress internetAddress = (InternetAddress) message.getSender();
-            if (internetAddress != null) {
+
+            InternetAddress[] internetAddresses = (InternetAddress[]) message.getFrom();
+            if (internetAddresses.length > 0) {
+                InternetAddress internetAddress = internetAddresses[0];
                 mailInfo.setFromEmail(internetAddress.getAddress());
                 mailInfo.setFromPersonalName(internetAddress.getPersonal());
                 mailInfo.setFromType(internetAddress.getType());

+ 243 - 2
bladex-saas-project/new-mail/src/main/java/com/fjhx/service/impl/MailFolderServiceImpl.java

@@ -1,11 +1,36 @@
 package com.fjhx.service.impl;
 
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.fjhx.entity.MailFolder;
+import com.fjhx.entity.*;
 import com.fjhx.mapper.MailFolderMapper;
-import com.fjhx.service.MailFolderService;
+import com.fjhx.service.*;
+import com.fjhx.utils.EmailUtil;
+import com.fjhx.vo.MailDetailsVo;
+import com.sun.mail.imap.IMAPFolder;
+import com.sun.mail.imap.IMAPStore;
+import lombok.extern.slf4j.Slf4j;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.StringPool;
+import org.springblade.resource.entity.ObsUpload;
+import org.springblade.resource.feign.IObsClient;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import javax.mail.*;
+import javax.mail.internet.MimeUtility;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
 /**
  * <p>
  * 邮箱文件夹 服务实现类
@@ -14,7 +39,223 @@ import org.springframework.stereotype.Service;
  * @author zlj
  * @since 2023-03-06
  */
+@Slf4j
 @Service
 public class MailFolderServiceImpl extends ServiceImpl<MailFolderMapper, MailFolder> implements MailFolderService {
 
+    @Autowired
+    private MailInfoService mailInfoService;
+
+    @Autowired
+    private MailAddressService mailAddressService;
+
+    @Autowired
+    private MailboxService mailboxService;
+
+    @Autowired
+    private MailMessageService mailMessageService;
+
+    @Autowired
+    private MailAttachmentService mailAttachmentService;
+
+    @Autowired
+    private IObsClient obsClient;
+
+    @Override
+    public MailDetailsVo getDetails(Long mailId) {
+        MailDetailsVo mailDetailsVo = new MailDetailsVo();
+
+        MailInfo mailInfo = mailInfoService.getById(mailId);
+        if (mailInfo == null) {
+            throw new ServiceException("没有找到邮件信息");
+        }
+
+        Integer messageSync = mailInfo.getMessageSync();
+        Integer addressSync = mailInfo.getAddressSync();
+        Integer attachmentSync = mailInfo.getAttachmentSync();
+
+        if (ObjectUtil.notEqual(messageSync, 1) || ObjectUtil.notEqual(addressSync, 1) || ObjectUtil.notEqual(attachmentSync, 1)) {
+            Mailbox mailbox = mailboxService.getById(mailInfo.getMailboxId());
+            IMAPStore imapStore = null;
+            IMAPFolder folder = null;
+            try {
+                imapStore = EmailUtil.getIMAPStore(mailbox.getMailHost(), mailbox.getMailboxName(), mailbox.getMailboxPwd());
+                folder = (IMAPFolder) imapStore.getFolder(mailInfo.getFolderName());
+                folder.open(Folder.READ_ONLY);
+                Message message = folder.getMessage(mailInfo.getMessageNumber());
+
+                // 同步地址
+                if (ObjectUtil.notEqual(addressSync, 1)) {
+                    List<MailAddress> mailAddressList = EmailUtil.mailAddressList(message, mailId);
+                    mailDetailsVo.setMailAddressList(mailAddressList);
+                    new Thread(() -> {
+                        mailAddressService.saveBatch(mailAddressList);
+                        mailInfoService.update(Wrappers.<MailInfo>lambdaUpdate()
+                                .eq(MailInfo::getId, mailId).set(MailInfo::getAddressSync, 1));
+                    }).start();
+                }
+
+                // 附件正文
+                if (ObjectUtil.notEqual(messageSync, 1) || ObjectUtil.notEqual(attachmentSync, 1)) {
+                    MailMessage mailMessage = new MailMessage();
+                    mailMessage.setMailInfoId(mailId);
+
+                    List<MailAttachment> mailAttachmentList = new ArrayList<>();
+
+                    mailDetailsVo.setMessage(mailMessage);
+                    mailDetailsVo.setMailAttachmentList(mailAttachmentList);
+
+                    saveMessageAndAttachment(mailDetailsVo, message);
+
+                    new Thread(() -> {
+                        mailMessageService.save(mailMessage);
+                        mailAttachmentService.saveBatch(mailAttachmentList);
+
+                        mailInfoService.update(Wrappers.<MailInfo>lambdaUpdate().eq(MailInfo::getId, mailId)
+                                .set(MailInfo::getMessageSync, 1).set(MailInfo::getAttachmentSync, 1));
+                    }).start();
+
+                }
+
+            } catch (Exception e) {
+                log.error("获取邮件出错", e);
+                throw new ServiceException("获取邮件出错");
+            } finally {
+                try {
+                    if (imapStore != null) {
+                        if (imapStore.isConnected()) {
+                            imapStore.close();
+                        }
+                    }
+                    if (folder != null) {
+                        if (folder.isOpen()) {
+                            folder.close();
+                        }
+                    }
+                } catch (MessagingException e) {
+                    log.error("关闭链接失败", e);
+                }
+            }
+        }
+
+        if (Objects.equals(addressSync, 1)) {
+            List<MailAddress> mailAddressList = mailAddressService.list(Wrappers.<MailAddress>lambdaQuery().eq(MailAddress::getMailInfoId, mailId));
+            mailDetailsVo.setMailAddressList(mailAddressList);
+        }
+        if (Objects.equals(messageSync, 1)) {
+            List<MailMessage> list = mailMessageService.list(Wrappers.<MailMessage>lambdaQuery().eq(MailMessage::getMailInfoId, mailId));
+            if (list.size() > 0)
+                mailDetailsVo.setMessage(list.get(0));
+        }
+        if (Objects.equals(attachmentSync, 1)) {
+            List<MailAttachment> list = mailAttachmentService.list(Wrappers.<MailAttachment>lambdaQuery().eq(MailAttachment::getMailInfoId, mailId));
+            mailDetailsVo.setMailAttachmentList(list);
+        }
+
+        return mailDetailsVo;
+    }
+
+
+    // 保存附件和正文
+    private void saveMessageAndAttachment(MailDetailsVo mailDetailsVo, Part part) throws MessagingException, IOException {
+
+        MailMessage message = mailDetailsVo.getMessage();
+        List<MailAttachment> mailAttachmentList = mailDetailsVo.getMailAttachmentList();
+        String contentType = part.getContentType();
+
+        String disposition = part.getDisposition();
+
+        // 处理附件
+        if ((disposition != null && (disposition.equalsIgnoreCase(Part.ATTACHMENT) || disposition.equalsIgnoreCase(Part.INLINE)))
+                || (contentType.contains("name") || contentType.contains("application"))) {
+
+            InputStream is = part.getInputStream();
+            String fileName = decodeText(part.getFileName());
+
+            String path = uploadFile(is, fileName);
+            MailAttachment mailAttachment = new MailAttachment();
+            mailAttachment.setName(fileName);
+            mailAttachment.setUrl(path);
+            mailAttachment.setMailInfoId(message.getMailInfoId());
+            mailAttachmentList.add(mailAttachment);
+
+        }
+        // html格式
+        else if (part.isMimeType("text/html")) {
+            Object content = part.getContent();
+            if (content != null) {
+                message.setContent(content.toString());
+            } else {
+                message.setContent(StringPool.EMPTY);
+            }
+            message.setMimeType("text/html");
+        }
+        // 文本格式
+        else if (part.isMimeType("text/plain")) {
+            Object content = part.getContent();
+            if (content != null) {
+                if (ObjectUtil.notEqual(message.getMimeType(), "text/html")) {
+                    message.setContent(content.toString());
+                    message.setMimeType("text/plain");
+                }
+            }
+        }
+        // 复杂体邮件
+        else if (part.isMimeType("multipart/*")) {
+            Multipart multipart = (Multipart) part.getContent();
+            // 复杂体邮件包含多个邮件体
+            int partCount = multipart.getCount();
+            for (int i = 0; i < partCount; i++) {
+                // 获得复杂体邮件中其中一个邮件体
+                BodyPart bodyPart = multipart.getBodyPart(i);
+                saveMessageAndAttachment(mailDetailsVo, bodyPart);
+            }
+
+        }
+        // 未知格式
+        else {
+            log.error("未知文件格式:{} ,待解析", contentType);
+        }
+
+    }
+
+    /**
+     * 文本解码
+     *
+     * @param encodeText 解码MimeUtility.encodeText(String text)方法编码后的文本
+     * @return 解码后的文本
+     */
+    private String decodeText(String encodeText) throws UnsupportedEncodingException {
+        if (encodeText == null || StringPool.EMPTY.equals(encodeText)) {
+            return StringPool.EMPTY;
+        } else {
+            return MimeUtility.decodeText(encodeText);
+        }
+    }
+
+    /**
+     * 上传文件
+     */
+    private String uploadFile(InputStream is, String fileName) {
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        try {
+            bos.write(is.read());
+            ObsUpload obsUpload = new ObsUpload();
+            obsUpload.setFileName(fileName);
+            obsUpload.setBytes(bos.toByteArray());
+            R<JSONObject> jsonObjectR = obsClient.uploadHuaWei(obsUpload);
+            if (jsonObjectR.isSuccess()) {
+                JSONObject data = jsonObjectR.getData();
+                return data.getString("path");
+            }
+        } catch (Exception e) {
+            log.error("上传文件出错", e);
+        } finally {
+            IoUtil.close(bos);
+            IoUtil.close(is);
+        }
+        return null;
+    }
+
 }

+ 25 - 0
bladex-saas-project/new-mail/src/main/java/com/fjhx/service/impl/MailInfoServiceImpl.java

@@ -1,10 +1,18 @@
 package com.fjhx.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.dto.SendDto;
 import com.fjhx.entity.MailInfo;
+import com.fjhx.entity.Mailbox;
 import com.fjhx.mapper.MailInfoMapper;
 import com.fjhx.service.MailInfoService;
+import com.fjhx.service.MailboxService;
+import com.fjhx.utils.EmailUtil;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springblade.core.log.exception.ServiceException;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 /**
@@ -15,9 +23,26 @@ import org.springframework.stereotype.Service;
  * @author zlj
  * @since 2023-03-06
  */
+@Slf4j
 @Service
 @AllArgsConstructor
 public class MailInfoServiceImpl extends ServiceImpl<MailInfoMapper, MailInfo> implements MailInfoService {
 
+    @Autowired
+    private MailboxService mailboxService;
+
+    @Override
+    public void send(SendDto dto) {
+        String mailboxId = dto.getMailboxId();
+        Mailbox mailbox = mailboxService.getById(mailboxId);
+
+        try {
+            EmailUtil.sendMail(mailbox.getMailHost(), mailbox.getMailboxName(), mailbox.getMailboxPwd(), dto);
+        } catch (Exception e) {
+            log.error("发送邮件失败:sendInfo:{},mailbox:{}", JSON.toJSONString(dto), JSON.toJSONString(mailbox));
+            throw new ServiceException("发送邮件失败");
+        }
+
+    }
 
 }

+ 167 - 4
bladex-saas-project/new-mail/src/main/java/com/fjhx/utils/EmailUtil.java

@@ -1,21 +1,30 @@
 package com.fjhx.utils;
 
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.fjhx.dto.SendDto;
+import com.fjhx.entity.MailAddress;
 import com.fjhx.entity.MailFolder;
 import com.fjhx.enums.MailFlagEnum;
 import com.sun.mail.imap.IMAPFolder;
 import com.sun.mail.imap.IMAPStore;
+import com.sun.mail.util.MailSSLSocketFactory;
 import org.springblade.core.tool.utils.StringPool;
+import org.springblade.system.attachment.entity.Attachment;
 
-import javax.mail.Flags;
-import javax.mail.MessagingException;
-import javax.mail.Session;
+import javax.activation.DataHandler;
+import javax.mail.*;
+import javax.mail.internet.*;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
 import java.util.*;
 
 public class EmailUtil {
 
     private static final Properties props = new Properties();
     private static final HashMap<String, String> map = new HashMap<>();
+    private static final Session session;
+
     static {
         props.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
 
@@ -23,13 +32,14 @@ public class EmailUtil {
         map.put("version", "1.0.0");
         map.put("vendor", "myClient");
         map.put("support-email", "fjhx@fjhx.com");
+
+        session = Session.getInstance(props);
     }
 
     /**
      * 获取store
      */
     public static IMAPStore getIMAPStore(String host, String user, String password) throws MessagingException {
-        Session session = Session.getInstance(props);
         IMAPStore store = (IMAPStore) session.getStore("imap");
         store.connect(host, 993, user, password);
         store.id(map);
@@ -67,6 +77,159 @@ public class EmailUtil {
         return stringJoiner.toString();
     }
 
+    /**
+     * 获取收件人、抄送人、密送人、回复人
+     */
+    public static List<MailAddress> mailAddressList(Message message, Long mainInfoId) throws MessagingException {
+        Address[] to = message.getRecipients(Message.RecipientType.TO);
+        Address[] cc = message.getRecipients(Message.RecipientType.CC);
+        Address[] bcc = message.getRecipients(Message.RecipientType.BCC);
+        Address[] replyTo = message.getReplyTo();
+
+        List<MailAddress> mailAddressList = new ArrayList<>();
+        addMailAddressList(mailAddressList, to, mainInfoId, 1);
+        addMailAddressList(mailAddressList, cc, mainInfoId, 2);
+        addMailAddressList(mailAddressList, bcc, mainInfoId, 3);
+        addMailAddressList(mailAddressList, replyTo, mainInfoId, 4);
+        return mailAddressList;
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        Attachment attachment = new Attachment();
+        attachment.setPath("https://os.winfaster.cn/fjhx/saas/GOLDSUN/2023/03/06/pdf/a69898863c834e68b19942ad26a49e10.pdf");
+        attachment.setRealName("测试.pdf");
+
+        SendDto sendDto = new SendDto();
+        SendDto.Address address = new SendDto.Address();
+        address.setAddress("2428241269@qq.com");
+        address.setPersonal("测试小小张");
+        sendDto.setTo(Arrays.asList(address));
+
+        sendDto.setAttachmentList(Arrays.asList(attachment));
+
+        sendDto.setSubject("测试标题");
+        sendDto.setContent("测试内容");
+        sendMail("imap.qq.com", "2428241269@qq.com", "kdypajdrwfhtdihb", sendDto);
+    }
+
+
+    public static void sendMail(String host, String user, String password, SendDto sendDto) throws Exception {
+
+        // 创建一个配置文件并保存
+        Properties properties = new Properties();
+        properties.setProperty("mail.host", host);
+        properties.setProperty("mail.transport.protocol", "smtp");
+        properties.setProperty("mail.smtp.auth", "true");
+
+        // QQ存在一个特性设置SSL加密
+        MailSSLSocketFactory sf = new MailSSLSocketFactory();
+        sf.setTrustAllHosts(true);
+        properties.put("mail.smtp.ssl.enable", "true");
+        properties.put("mail.smtp.ssl.socketFactory", sf);
+
+        // 创建一个session对象
+        Session session = Session.getDefaultInstance(properties, new Authenticator() {
+            @Override
+            protected PasswordAuthentication getPasswordAuthentication() {
+                return new PasswordAuthentication(user, password);
+            }
+        });
+
+        // 获取连接对象
+        Transport transport = session.getTransport();
+
+        // 连接服务器
+        transport.connect(host, user, password);
+
+        // 创建邮件对象
+        MimeMessage mimeMessage = new MimeMessage(session);
+
+        // // 邮件发送人
+        mimeMessage.setFrom(new InternetAddress(user));
+
+        List<SendDto.Address> to = sendDto.getTo();
+        if (ObjectUtil.isNotEmpty(to)) {
+            mimeMessage.setRecipients(Message.RecipientType.TO, getAddresses(to));
+        }
+
+        List<SendDto.Address> cc = sendDto.getCc();
+        if (ObjectUtil.isNotEmpty(cc)) {
+            mimeMessage.setRecipients(Message.RecipientType.CC, getAddresses(cc));
+        }
+
+        List<SendDto.Address> bcc = sendDto.getBcc();
+        if (ObjectUtil.isNotEmpty(bcc)) {
+            mimeMessage.setRecipients(Message.RecipientType.BCC, getAddresses(bcc));
+        }
+
+        List<SendDto.Address> replyTo = sendDto.getReplyTo();
+        if (ObjectUtil.isNotEmpty(replyTo)) {
+            mimeMessage.setReplyTo(getAddresses(replyTo));
+        }
+        // 邮件标题
+        mimeMessage.setSubject(sendDto.getSubject());
+
+        // 邮件内容大对象
+        MimeMultipart mimeMultipart = new MimeMultipart();
+
+        // 对象内添加正文
+        BodyPart content = new MimeBodyPart();
+        content.setContent(sendDto.getContent(), "text/html;charset=UTF-8");
+        mimeMultipart.addBodyPart(content);
+
+        // 对象内添加邮件
+        List<Attachment> attachmentList = sendDto.getAttachmentList();
+        if (ObjectUtil.isNotEmpty(attachmentList)) {
+            for (Attachment attachment : attachmentList) {
+                DataHandler dataHandler = new DataHandler(new URL(attachment.getPath()));
+
+                MimeBodyPart mimeBodyPart = new MimeBodyPart();
+                mimeBodyPart.setDataHandler(dataHandler);
+                mimeBodyPart.setContentID(IdWorker.getIdStr());
+                mimeBodyPart.setFileName(MimeUtility.encodeText(attachment.getRealName()));
+                mimeMultipart.addBodyPart(mimeBodyPart);
+            }
+        }
+
+        mimeMessage.setContent(mimeMultipart);
+
+        // 发送邮件
+        transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
+
+        // 关闭连接
+        transport.close();
+
+    }
+
+    private static InternetAddress[] getAddresses(List<SendDto.Address> addressList) throws UnsupportedEncodingException {
+        InternetAddress[] internetAddresses = new InternetAddress[addressList.size()];
+        for (int i = 0; i < addressList.size(); i++) {
+            InternetAddress internetAddress = new InternetAddress();
+            internetAddress.setPersonal(addressList.get(i).getPersonal(), "utf-8");
+            internetAddress.setAddress(addressList.get(i).getAddress());
+            internetAddresses[i] = internetAddress;
+        }
+        return internetAddresses;
+    }
+
+    private static void addMailAddressList(List<MailAddress> mailAddressList, Address[] addresses, Long mainInfoId, Integer type) {
+        if (addresses == null) {
+            return;
+        }
+        for (Address address : addresses) {
+            InternetAddress internetAddress = (InternetAddress) address;
+
+            MailAddress mailAddress = new MailAddress();
+            mailAddress.setType(type);
+            mailAddress.setEmail(internetAddress.getAddress());
+            mailAddress.setPersonalName(internetAddress.getPersonal());
+            mailAddress.setMailInfoId(mainInfoId);
+            mailAddressList.add(mailAddress);
+        }
+    }
+
+
     private static void addMailFolderList(List<MailFolder> mailFolderList, IMAPFolder[] folders, String mailboxId) throws MessagingException {
         for (IMAPFolder folder : folders) {
             int type = folder.getType();

+ 20 - 0
bladex-saas-project/new-mail/src/main/java/com/fjhx/vo/MailDetailsVo.java

@@ -0,0 +1,20 @@
+package com.fjhx.vo;
+
+import com.fjhx.entity.MailAddress;
+import com.fjhx.entity.MailAttachment;
+import com.fjhx.entity.MailMessage;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class MailDetailsVo {
+
+
+    List<MailAddress> mailAddressList;
+
+    MailMessage message;
+
+    List<MailAttachment> mailAttachmentList;
+
+}