|
@@ -1,23 +1,411 @@
|
|
|
package com.fjhx.email.service.impl;
|
|
|
|
|
|
+import cn.hutool.core.bean.BeanUtil;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.fjhx.email.config.exception.ServiceException;
|
|
|
+import com.fjhx.email.entity.*;
|
|
|
+import com.fjhx.email.entity.dto.GetMessagePageDto;
|
|
|
import com.fjhx.email.entity.dto.MailSyncInfo;
|
|
|
import com.fjhx.email.entity.dto.MailboxInfo;
|
|
|
+import com.fjhx.email.entity.vo.MessageDetailVo;
|
|
|
+import com.fjhx.email.entity.vo.MessageVo;
|
|
|
import com.fjhx.email.mapper.MailMapper;
|
|
|
-import com.fjhx.email.service.IMailService;
|
|
|
+import com.fjhx.email.service.*;
|
|
|
+import com.fjhx.email.utils.EmailUtil;
|
|
|
+import com.fjhx.email.utils.ObsFileUtil;
|
|
|
+import com.fjhx.email.utils.PageWrapper;
|
|
|
+import com.sun.mail.imap.IMAPFolder;
|
|
|
+import com.sun.mail.imap.IMAPMessage;
|
|
|
+import com.sun.mail.imap.IMAPStore;
|
|
|
+import lombok.SneakyThrows;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import javax.mail.*;
|
|
|
+import javax.mail.internet.MimeUtility;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.io.UnsupportedEncodingException;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
|
|
|
|
+@Slf4j
|
|
|
@Service
|
|
|
public class MailServiceImpl implements IMailService {
|
|
|
|
|
|
@Autowired
|
|
|
private MailMapper mailMapper;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private IPersonalMessageService personalMessageService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IEnterpriseMessageService enterpriseMessageService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IEnterpriseMessageAddressService enterpriseMessageAddressService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IEnterpriseMessageAttachmentService enterpriseMessageAttachmentService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IEnterpriseMessageContentService enterpriseMessageContentService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IPersonalMessageAddressService personalMessageAddressService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IPersonalMessageAttachmentService personalMessageAttachmentService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IPersonalMessageContentService personalMessageContentService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IPersonalMailboxService personalMailboxService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IEnterpriseMailboxService enterpriseMailboxService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IEnterpriseDomainService enterpriseDomainService;
|
|
|
+
|
|
|
@Override
|
|
|
public List<MailboxInfo> getMailboxInfoListByUserId(List<Long> userIdList) {
|
|
|
return mailMapper.getMailboxInfoListByUserId(userIdList, MailSyncInfo.mailType);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public PageWrapper<MessageVo> getMessagePage(GetMessagePageDto dto) {
|
|
|
+
|
|
|
+ if (dto.getType().equals(1)) {
|
|
|
+ Page<PersonalMessage> page = personalMessageService.page(dto, q -> q
|
|
|
+ .eq(PersonalMessage::getFolderId, dto.getFolderId())
|
|
|
+ .orderByDesc(PersonalMessage::getSendDate)
|
|
|
+ );
|
|
|
+ return new PageWrapper<>(page, MessageVo.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ Page<EnterpriseMessage> page = enterpriseMessageService.page(dto, q -> q
|
|
|
+ .eq(EnterpriseMessage::getFolderId, dto.getFolderId())
|
|
|
+ .orderByDesc(EnterpriseMessage::getSendDate)
|
|
|
+ );
|
|
|
+ return new PageWrapper<>(page, MessageVo.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ @SneakyThrows
|
|
|
+ @Override
|
|
|
+ public MessageDetailVo getMessageDetail(GetMessagePageDto dto) {
|
|
|
+ Long messageId = dto.getMessageId();
|
|
|
+
|
|
|
+ Integer contentSync;
|
|
|
+ Integer addressSync;
|
|
|
+ Integer attachmentSync;
|
|
|
+
|
|
|
+ Integer messageNumber;
|
|
|
+
|
|
|
+ String folderName;
|
|
|
+ Long mailboxId;
|
|
|
+
|
|
|
+ if (dto.getType().equals(1)) {
|
|
|
+ PersonalMessage personalMessage = personalMessageService.getById(messageId);
|
|
|
+ if (personalMessage == null) {
|
|
|
+ throw new ServiceException("没有找到邮箱");
|
|
|
+ }
|
|
|
+ messageNumber = personalMessage.getMessageNumber();
|
|
|
+ contentSync = personalMessage.getContentSync();
|
|
|
+ addressSync = personalMessage.getAddressSync();
|
|
|
+ attachmentSync = personalMessage.getAttachmentSync();
|
|
|
+
|
|
|
+ folderName = personalMessage.getFolderName();
|
|
|
+ mailboxId = personalMessage.getMailboxId();
|
|
|
+ } else {
|
|
|
+ EnterpriseMessage enterpriseMessage = enterpriseMessageService.getById(messageId);
|
|
|
+ if (enterpriseMessage == null) {
|
|
|
+ throw new ServiceException("没有找到邮箱");
|
|
|
+ }
|
|
|
+ messageNumber = enterpriseMessage.getMessageNumber();
|
|
|
+ contentSync = enterpriseMessage.getContentSync();
|
|
|
+ addressSync = enterpriseMessage.getAddressSync();
|
|
|
+ attachmentSync = enterpriseMessage.getAttachmentSync();
|
|
|
+
|
|
|
+ folderName = enterpriseMessage.getFolderName();
|
|
|
+ mailboxId = enterpriseMessage.getMailboxId();
|
|
|
+ }
|
|
|
+
|
|
|
+ MessageDetailVo messageDetailVo = new MessageDetailVo();
|
|
|
+
|
|
|
+ // 正文附件已同步
|
|
|
+ if (contentSync == 1 && addressSync == 1 && attachmentSync == 1) {
|
|
|
+ if (dto.getType().equals(1)) {
|
|
|
+ setPersonalMessageDetailVo(messageDetailVo, messageId);
|
|
|
+ } else {
|
|
|
+ setEnterpriseMessageDetailVo(messageDetailVo, messageId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 未同步
|
|
|
+ else {
|
|
|
+
|
|
|
+ MailboxInfo mailboxInfo = getMailboxInfo(dto.getType(), mailboxId);
|
|
|
+
|
|
|
+ IMAPStore imapStore = EmailUtil.getIMAPStore(mailboxInfo);
|
|
|
+ IMAPFolder folder = (IMAPFolder) imapStore.getFolder(folderName);
|
|
|
+ folder.open(Folder.READ_ONLY);
|
|
|
+ IMAPMessage message = (IMAPMessage) folder.getMessage(messageNumber);
|
|
|
+
|
|
|
+ messageDetailVo.setMessageAttachmentList(new ArrayList<>());
|
|
|
+ getMessageAndAttachment(messageDetailVo, message, messageId);
|
|
|
+
|
|
|
+ messageDetailVo.setMessageAddressList(EmailUtil.mailAddressList(message));
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ for (MessageDetailVo.MessageAttachment messageAttachment : messageDetailVo.getMessageAttachmentList()) {
|
|
|
+ messageAttachment.setUrl(ObsFileUtil.getCompleteUrl(messageAttachment.getUrl()));
|
|
|
+ }
|
|
|
+
|
|
|
+ return messageDetailVo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private MailboxInfo getMailboxInfo(Integer type, Long mailboxId) {
|
|
|
+ MailboxInfo mailboxInfo = new MailboxInfo();
|
|
|
+
|
|
|
+
|
|
|
+ if (type.equals(1)) {
|
|
|
+ PersonalMailbox personalMailbox = personalMailboxService.getById(mailboxId);
|
|
|
+ mailboxInfo.setReceiveHost(personalMailbox.getReceiveHost());
|
|
|
+ mailboxInfo.setReceivePort(personalMailbox.getReceivePort());
|
|
|
+ mailboxInfo.setMailUser(personalMailbox.getMailUser());
|
|
|
+ mailboxInfo.setMailPassword(personalMailbox.getMailPassword());
|
|
|
+
|
|
|
+ return mailboxInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ EnterpriseMailbox enterpriseMailbox = enterpriseMailboxService.getById(mailboxId);
|
|
|
+ EnterpriseDomain enterpriseDomain = enterpriseDomainService.getById(enterpriseMailbox.getDomainId());
|
|
|
+ mailboxInfo.setReceiveHost(enterpriseDomain.getReceiveHost());
|
|
|
+ mailboxInfo.setReceivePort(enterpriseDomain.getReceivePort());
|
|
|
+ mailboxInfo.setMailUser(enterpriseMailbox.getMailUserPrefix() + "@" + enterpriseDomain.getDomanName());
|
|
|
+ mailboxInfo.setMailPassword(enterpriseMailbox.getMailPassword());
|
|
|
+ return mailboxInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void setPersonalMessageDetailVo(MessageDetailVo vo, Long messageId) {
|
|
|
+ List<PersonalMessageAddress> addressList = personalMessageAddressService.list(
|
|
|
+ q -> q.eq(PersonalMessageAddress::getMessageId, messageId));
|
|
|
+ vo.setMessageAddressList(BeanUtil.copyToList(addressList, MessageDetailVo.MessageAddress.class));
|
|
|
+
|
|
|
+ List<PersonalMessageAttachment> attachmentList = personalMessageAttachmentService.list(
|
|
|
+ q -> q.eq(PersonalMessageAttachment::getMessageId, messageId));
|
|
|
+ vo.setMessageAttachmentList(BeanUtil.copyToList(attachmentList, MessageDetailVo.MessageAttachment.class));
|
|
|
+
|
|
|
+ PersonalMessageContent content = personalMessageContentService.getOne(
|
|
|
+ q -> q.eq(PersonalMessageContent::getMessageId, messageId));
|
|
|
+ vo.setContent(content.getContent());
|
|
|
+ }
|
|
|
+
|
|
|
+ private void setEnterpriseMessageDetailVo(MessageDetailVo vo, Long messageId) {
|
|
|
+ List<EnterpriseMessageAddress> addressList = enterpriseMessageAddressService.list(
|
|
|
+ q -> q.eq(EnterpriseMessageAddress::getMessageId, messageId));
|
|
|
+ vo.setMessageAddressList(BeanUtil.copyToList(addressList, MessageDetailVo.MessageAddress.class));
|
|
|
+
|
|
|
+ List<EnterpriseMessageAttachment> attachmentList = enterpriseMessageAttachmentService.list(
|
|
|
+ q -> q.eq(EnterpriseMessageAttachment::getMessageId, messageId));
|
|
|
+ vo.setMessageAttachmentList(BeanUtil.copyToList(attachmentList, MessageDetailVo.MessageAttachment.class));
|
|
|
+
|
|
|
+ EnterpriseMessageContent content = enterpriseMessageContentService.getOne(
|
|
|
+ q -> q.eq(EnterpriseMessageContent::getMessageId, messageId));
|
|
|
+ vo.setContent(content.getContent());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存附件和正文
|
|
|
+ */
|
|
|
+ private void getMessageAndAttachment(MessageDetailVo messageDetailVo, Part part, Long messageId)
|
|
|
+ throws MessagingException, IOException {
|
|
|
+
|
|
|
+ // 正文:文本格式
|
|
|
+ if (part.isMimeType("text/plain")) {
|
|
|
+ addPlain(part, messageDetailVo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 正文:html格式
|
|
|
+ else if (part.isMimeType("text/html")) {
|
|
|
+ addHtml(part, messageDetailVo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 正文:html格式
|
|
|
+ else if (part.isMimeType("text/html; charset=UTF-8")) {
|
|
|
+ addHtmlUtf8(part, messageDetailVo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 大对象
|
|
|
+ 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);
|
|
|
+
|
|
|
+ // 某一个邮件体也有可能是由多个邮件体组成的复杂体
|
|
|
+ String disposition = bodyPart.getDisposition();
|
|
|
+
|
|
|
+ // 正文:html格式
|
|
|
+ if (bodyPart.isMimeType("text/html")) {
|
|
|
+ addHtml(bodyPart, messageDetailVo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 正文:文本格式
|
|
|
+ if (bodyPart.isMimeType("text/plain")) {
|
|
|
+ addPlain(bodyPart, messageDetailVo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 正文:html格式
|
|
|
+ else if (part.isMimeType("text/html; charset=UTF-8")) {
|
|
|
+ addHtmlUtf8(part, messageDetailVo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 附件
|
|
|
+ else if (disposition != null
|
|
|
+ && (disposition.equalsIgnoreCase(Part.ATTACHMENT) || disposition.equalsIgnoreCase(Part.INLINE))) {
|
|
|
+ MessageDetailVo.MessageAttachment messageAttachment = getMessageAttachment(bodyPart);
|
|
|
+ messageDetailVo.getMessageAttachmentList().add(messageAttachment);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 大对象
|
|
|
+ else if (bodyPart.isMimeType("multipart/*")) {
|
|
|
+ getMessageAndAttachment(messageDetailVo, bodyPart, messageId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 其他类型
|
|
|
+ else {
|
|
|
+ String contentType = bodyPart.getContentType();
|
|
|
+ if (contentType.contains("name") || contentType.contains("application")) {
|
|
|
+ MessageDetailVo.MessageAttachment messageAttachment = getMessageAttachment(bodyPart);
|
|
|
+ messageDetailVo.getMessageAttachmentList().add(messageAttachment);
|
|
|
+ } else {
|
|
|
+ if (!contentType.equals("text/html; charset=UTF-8"))
|
|
|
+ log.error("未知文件格式:{} ,邮件id:{},待解析", contentType, messageId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // rfc822
|
|
|
+ else if (part.isMimeType("message/rfc822")) {
|
|
|
+ getMessageAndAttachment(messageDetailVo, (Part) part.getContent(), messageId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 未知格式
|
|
|
+ else {
|
|
|
+ log.error("未知文件格式:{} ,邮件id:{},待解析", part.getContentType(), messageId);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private MessageDetailVo.MessageAttachment getMessageAttachment(Part part)
|
|
|
+ throws MessagingException, IOException {
|
|
|
+
|
|
|
+ InputStream is = part.getInputStream();
|
|
|
+ String fileName = decodeText(part.getFileName());
|
|
|
+
|
|
|
+ String url = ObsFileUtil.uploadFile(fileName, is);
|
|
|
+
|
|
|
+ MessageDetailVo.MessageAttachment messageAttachment = new MessageDetailVo.MessageAttachment();
|
|
|
+ messageAttachment.setUrl(url);
|
|
|
+ messageAttachment.setName(fileName);
|
|
|
+ return messageAttachment;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void addHtml(Part part, MessageDetailVo messageDetailVo) throws MessagingException, IOException {
|
|
|
+ Object content = part.getContent();
|
|
|
+ if (content != null) {
|
|
|
+ messageDetailVo.setContent(content.toString());
|
|
|
+ } else {
|
|
|
+ messageDetailVo.setContent(StringPool.EMPTY);
|
|
|
+ }
|
|
|
+ messageDetailVo.setMimeType("text/html");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void addHtmlUtf8(Part part, MessageDetailVo messageDetailVo) throws MessagingException, IOException {
|
|
|
+ Object content = part.getContent();
|
|
|
+ if (content != null) {
|
|
|
+ messageDetailVo.setContent(content.toString());
|
|
|
+ } else {
|
|
|
+ messageDetailVo.setContent(StringPool.EMPTY);
|
|
|
+ }
|
|
|
+ messageDetailVo.setMimeType("text/html; charset=UTF-8");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void addPlain(Part part, MessageDetailVo messageDetailVo) throws MessagingException, IOException {
|
|
|
+ Object content = part.getContent();
|
|
|
+ if (content != null) {
|
|
|
+ if (ObjectUtil.notEqual(messageDetailVo.getMimeType(), "text/html")) {
|
|
|
+ messageDetailVo.setContent(content.toString());
|
|
|
+ messageDetailVo.setMimeType("text/plain");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 文本解码
|
|
|
+ */
|
|
|
+ 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) {
|
|
|
+ //
|
|
|
+ // BufferedInputStream bis = new BufferedInputStream(is);
|
|
|
+ // ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
+ // BufferedOutputStream bos = new BufferedOutputStream(baos);
|
|
|
+ //
|
|
|
+ // try {
|
|
|
+ // int len;
|
|
|
+ //
|
|
|
+ // while ((len = bis.read()) != -1) {
|
|
|
+ // bos.write(len);
|
|
|
+ // bos.flush();
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // bos.write(is.read());
|
|
|
+ //
|
|
|
+ // // 上次附件至华为云
|
|
|
+ // ObsUpload obsUpload = new ObsUpload();
|
|
|
+ // obsUpload.setFileName(fileName);
|
|
|
+ // obsUpload.setBytes(baos.toByteArray());
|
|
|
+ // R<JSONObject> jsonObjectR = obsClient.uploadHuaWei(obsUpload);
|
|
|
+ // if (jsonObjectR.isSuccess()) {
|
|
|
+ // JSONObject data = jsonObjectR.getData();
|
|
|
+ // return data.getString("path");
|
|
|
+ // }
|
|
|
+ // } catch (Exception e) {
|
|
|
+ // log.error("上传文件出错", e);
|
|
|
+ // throw new ServiceException("获取附件出现错误");
|
|
|
+ // } finally {
|
|
|
+ // IoUtil.close(bos);
|
|
|
+ // IoUtil.close(baos);
|
|
|
+ // IoUtil.close(bis);
|
|
|
+ // IoUtil.close(is);
|
|
|
+ // }
|
|
|
+ // return null;
|
|
|
+ // }
|
|
|
+
|
|
|
}
|