|
@@ -23,6 +23,9 @@ import lombok.SneakyThrows;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.PlatformTransactionManager;
|
|
|
+import org.springframework.transaction.TransactionDefinition;
|
|
|
+import org.springframework.transaction.TransactionStatus;
|
|
|
|
|
|
import javax.mail.*;
|
|
|
import javax.mail.internet.MimeUtility;
|
|
@@ -31,6 +34,8 @@ import java.io.InputStream;
|
|
|
import java.io.UnsupportedEncodingException;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
|
+import java.util.concurrent.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
@Slf4j
|
|
|
@Service
|
|
@@ -72,6 +77,23 @@ public class MailServiceImpl implements IMailService {
|
|
|
@Autowired
|
|
|
private IEnterpriseDomainService enterpriseDomainService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private TransactionDefinition transactionDefinition;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private PlatformTransactionManager platformTransactionManager;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建一个线程池
|
|
|
+ */
|
|
|
+ private static final ExecutorService executorService = new ThreadPoolExecutor(
|
|
|
+ 5,
|
|
|
+ 10,
|
|
|
+ 1,
|
|
|
+ TimeUnit.MINUTES,
|
|
|
+ new ArrayBlockingQueue<>(10)
|
|
|
+ );
|
|
|
+
|
|
|
@Override
|
|
|
public List<MailboxInfo> getMailboxInfoListByUserId(List<Long> userIdList) {
|
|
|
return mailMapper.getMailboxInfoListByUserId(userIdList, MailSyncInfo.mailType);
|
|
@@ -155,10 +177,34 @@ public class MailServiceImpl implements IMailService {
|
|
|
folder.open(Folder.READ_ONLY);
|
|
|
IMAPMessage message = (IMAPMessage) folder.getMessage(messageNumber);
|
|
|
|
|
|
- messageDetailVo.setMessageAttachmentList(new ArrayList<>());
|
|
|
- getMessageAndAttachment(messageDetailVo, message, messageId);
|
|
|
|
|
|
- messageDetailVo.setMessageAddressList(EmailUtil.mailAddressList(message));
|
|
|
+ List<CompletableFuture<MessageDetailVo.MessageAttachment>> list = new ArrayList<>();
|
|
|
+
|
|
|
+ CompletableFuture<Void> attachmentFuture = CompletableFuture.runAsync(() -> {
|
|
|
+
|
|
|
+ getMessageAndAttachment(messageDetailVo, message, messageId, list);
|
|
|
+
|
|
|
+ List<MessageDetailVo.MessageAttachment> messageAttachmentList = list.stream()
|
|
|
+ .map(CompletableFuture::join).collect(Collectors.toList());
|
|
|
+
|
|
|
+ messageDetailVo.setMessageAttachmentList(messageAttachmentList);
|
|
|
+
|
|
|
+ }, executorService);
|
|
|
+
|
|
|
+ CompletableFuture<Void> addressFuture = CompletableFuture.runAsync(() ->
|
|
|
+ messageDetailVo.setMessageAddressList(EmailUtil.mailAddressList(message)), executorService);
|
|
|
+
|
|
|
+ CompletableFuture.allOf(attachmentFuture, addressFuture).join();
|
|
|
+
|
|
|
+ // Integer contentSync;
|
|
|
+ // Integer addressSync;
|
|
|
+ // Integer attachmentSync;
|
|
|
+ // messageId
|
|
|
+ // messageDetailVo
|
|
|
+
|
|
|
+ new Thread(() ->
|
|
|
+ saveMessageDetail(contentSync, addressSync, attachmentSync, messageId, messageDetailVo, dto.getType())
|
|
|
+ ).start();
|
|
|
|
|
|
}
|
|
|
|
|
@@ -169,6 +215,97 @@ public class MailServiceImpl implements IMailService {
|
|
|
return messageDetailVo;
|
|
|
}
|
|
|
|
|
|
+ private void saveMessageDetail(Integer contentSync, Integer addressSync, Integer attachmentSync,
|
|
|
+ Long messageId, MessageDetailVo messageDetailVo, Integer type) {
|
|
|
+
|
|
|
+ TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
|
|
|
+
|
|
|
+ try {
|
|
|
+ if (type == 1) {
|
|
|
+ if (contentSync == 0) {
|
|
|
+ PersonalMessageContent personalMessageContent = new PersonalMessageContent();
|
|
|
+ personalMessageContent.setMessageId(messageId);
|
|
|
+ personalMessageContent.setContent(messageDetailVo.getContent());
|
|
|
+ personalMessageContent.setMimeType(messageDetailVo.getMimeType());
|
|
|
+ personalMessageContentService.save(personalMessageContent);
|
|
|
+ }
|
|
|
+ if (addressSync == 0) {
|
|
|
+ List<MessageDetailVo.MessageAddress> messageAddressList = messageDetailVo.getMessageAddressList();
|
|
|
+ List<PersonalMessageAddress> personalMessageContentService = messageAddressList.stream().map(item -> {
|
|
|
+ PersonalMessageAddress personalMessageAddress = new PersonalMessageAddress();
|
|
|
+ personalMessageAddress.setMessageId(messageId);
|
|
|
+ personalMessageAddress.setPersonalName(item.getPersonalName());
|
|
|
+ personalMessageAddress.setType(item.getType());
|
|
|
+ personalMessageAddress.setEmail(item.getEmail());
|
|
|
+ return personalMessageAddress;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ personalMessageAddressService.saveBatch(personalMessageContentService);
|
|
|
+ }
|
|
|
+ if (attachmentSync == 0) {
|
|
|
+ List<MessageDetailVo.MessageAttachment> messageAttachmentList = messageDetailVo.getMessageAttachmentList();
|
|
|
+
|
|
|
+ List<PersonalMessageAttachment> messageAttachments = messageAttachmentList.stream().map(item -> {
|
|
|
+ PersonalMessageAttachment personalMessageAttachment = new PersonalMessageAttachment();
|
|
|
+ personalMessageAttachment.setName(item.getName());
|
|
|
+ personalMessageAttachment.setUrl(item.getUrl());
|
|
|
+ personalMessageAttachment.setMessageId(messageId);
|
|
|
+ return personalMessageAttachment;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ personalMessageAttachmentService.saveBatch(messageAttachments);
|
|
|
+ }
|
|
|
+ personalMessageService.update(q -> q.eq(PersonalMessage::getId, messageId)
|
|
|
+ .set(PersonalMessage::getAddressSync, 1)
|
|
|
+ .set(PersonalMessage::getContentSync, 1)
|
|
|
+ .set(PersonalMessage::getAttachmentSync, 1)
|
|
|
+ );
|
|
|
+
|
|
|
+ } else {
|
|
|
+ if (contentSync == 0) {
|
|
|
+ EnterpriseMessageContent enterpriseMessageContent = new EnterpriseMessageContent();
|
|
|
+ enterpriseMessageContent.setMessageId(messageId);
|
|
|
+ enterpriseMessageContent.setContent(messageDetailVo.getContent());
|
|
|
+ enterpriseMessageContent.setMimeType(messageDetailVo.getMimeType());
|
|
|
+ enterpriseMessageContentService.save(enterpriseMessageContent);
|
|
|
+ }
|
|
|
+ if (addressSync == 0) {
|
|
|
+ List<MessageDetailVo.MessageAddress> messageAddressList = messageDetailVo.getMessageAddressList();
|
|
|
+ List<EnterpriseMessageAddress> enterpriseMessageAddressList = messageAddressList.stream().map(item -> {
|
|
|
+ EnterpriseMessageAddress enterpriseMessageAddress = new EnterpriseMessageAddress();
|
|
|
+ enterpriseMessageAddress.setMessageId(messageId);
|
|
|
+ enterpriseMessageAddress.setPersonalName(item.getPersonalName());
|
|
|
+ enterpriseMessageAddress.setType(item.getType());
|
|
|
+ enterpriseMessageAddress.setEmail(item.getEmail());
|
|
|
+ return enterpriseMessageAddress;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ enterpriseMessageAddressService.saveBatch(enterpriseMessageAddressList);
|
|
|
+ }
|
|
|
+ if (attachmentSync == 0) {
|
|
|
+ List<MessageDetailVo.MessageAttachment> messageAttachmentList = messageDetailVo.getMessageAttachmentList();
|
|
|
+ List<EnterpriseMessageAttachment> messageAttachments = messageAttachmentList.stream().map(item -> {
|
|
|
+ EnterpriseMessageAttachment enterpriseMessageAttachment = new EnterpriseMessageAttachment();
|
|
|
+ enterpriseMessageAttachment.setName(item.getName());
|
|
|
+ enterpriseMessageAttachment.setUrl(item.getUrl());
|
|
|
+ enterpriseMessageAttachment.setMessageId(messageId);
|
|
|
+ return enterpriseMessageAttachment;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ enterpriseMessageAttachmentService.saveBatch(messageAttachments);
|
|
|
+ }
|
|
|
+ enterpriseMessageService.update(q -> q.eq(EnterpriseMessage::getId, messageId)
|
|
|
+ .set(EnterpriseMessage::getAddressSync, 1)
|
|
|
+ .set(EnterpriseMessage::getContentSync, 1)
|
|
|
+ .set(EnterpriseMessage::getAttachmentSync, 1)
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提交事务
|
|
|
+ platformTransactionManager.commit(transactionStatus);
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 回滚事务
|
|
|
+ platformTransactionManager.rollback(transactionStatus);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
private MailboxInfo getMailboxInfo(Integer type, Long mailboxId) {
|
|
|
MailboxInfo mailboxInfo = new MailboxInfo();
|
|
|
|
|
@@ -224,8 +361,9 @@ public class MailServiceImpl implements IMailService {
|
|
|
/**
|
|
|
* 保存附件和正文
|
|
|
*/
|
|
|
- private void getMessageAndAttachment(MessageDetailVo messageDetailVo, Part part, Long messageId)
|
|
|
- throws MessagingException, IOException {
|
|
|
+ @SneakyThrows
|
|
|
+ private void getMessageAndAttachment(MessageDetailVo messageDetailVo, Part part, Long messageId,
|
|
|
+ List<CompletableFuture<MessageDetailVo.MessageAttachment>> completableFutureList) {
|
|
|
|
|
|
// 正文:文本格式
|
|
|
if (part.isMimeType("text/plain")) {
|
|
@@ -277,21 +415,20 @@ public class MailServiceImpl implements IMailService {
|
|
|
// 附件
|
|
|
else if (disposition != null
|
|
|
&& (disposition.equalsIgnoreCase(Part.ATTACHMENT) || disposition.equalsIgnoreCase(Part.INLINE))) {
|
|
|
- MessageDetailVo.MessageAttachment messageAttachment = getMessageAttachment(bodyPart);
|
|
|
- messageDetailVo.getMessageAttachmentList().add(messageAttachment);
|
|
|
+ completableFutureList.add(CompletableFuture.supplyAsync(() -> getMessageAttachment(bodyPart), executorService));
|
|
|
}
|
|
|
|
|
|
// 大对象
|
|
|
else if (bodyPart.isMimeType("multipart/*")) {
|
|
|
- getMessageAndAttachment(messageDetailVo, bodyPart, messageId);
|
|
|
+ getMessageAndAttachment(messageDetailVo, bodyPart, messageId, completableFutureList);
|
|
|
}
|
|
|
|
|
|
// 其他类型
|
|
|
else {
|
|
|
String contentType = bodyPart.getContentType();
|
|
|
if (contentType.contains("name") || contentType.contains("application")) {
|
|
|
- MessageDetailVo.MessageAttachment messageAttachment = getMessageAttachment(bodyPart);
|
|
|
- messageDetailVo.getMessageAttachmentList().add(messageAttachment);
|
|
|
+ completableFutureList.add(CompletableFuture.supplyAsync(() -> getMessageAttachment(bodyPart), executorService));
|
|
|
+
|
|
|
} else {
|
|
|
if (!contentType.equals("text/html; charset=UTF-8"))
|
|
|
log.error("未知文件格式:{} ,邮件id:{},待解析", contentType, messageId);
|
|
@@ -303,7 +440,7 @@ public class MailServiceImpl implements IMailService {
|
|
|
|
|
|
// rfc822
|
|
|
else if (part.isMimeType("message/rfc822")) {
|
|
|
- getMessageAndAttachment(messageDetailVo, (Part) part.getContent(), messageId);
|
|
|
+ getMessageAndAttachment(messageDetailVo, (Part) part.getContent(), messageId, completableFutureList);
|
|
|
}
|
|
|
|
|
|
// 未知格式
|
|
@@ -313,9 +450,8 @@ public class MailServiceImpl implements IMailService {
|
|
|
|
|
|
}
|
|
|
|
|
|
- private MessageDetailVo.MessageAttachment getMessageAttachment(Part part)
|
|
|
- throws MessagingException, IOException {
|
|
|
-
|
|
|
+ @SneakyThrows
|
|
|
+ private MessageDetailVo.MessageAttachment getMessageAttachment(Part part) {
|
|
|
InputStream is = part.getInputStream();
|
|
|
String fileName = decodeText(part.getFileName());
|
|
|
|
|
@@ -368,44 +504,4 @@ public class MailServiceImpl implements IMailService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // /**
|
|
|
- // * 上传文件
|
|
|
- // */
|
|
|
- // 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;
|
|
|
- // }
|
|
|
-
|
|
|
}
|