|
@@ -28,7 +28,6 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
|
import java.util.concurrent.Executor;
|
|
|
-import java.util.stream.Collectors;
|
|
|
|
|
|
@Slf4j
|
|
|
@Service
|
|
@@ -57,26 +56,28 @@ public class AccountServiceImpl implements IAccountService {
|
|
|
@Override
|
|
|
public EmailInfo binding(BindingVo bindingVo) {
|
|
|
|
|
|
- String email = bindingVo.getEmail();
|
|
|
+ try {
|
|
|
+ String email = bindingVo.getEmail();
|
|
|
|
|
|
- EmailInfo emailInfo = emailInfoService.getOne(Wrappers.<EmailInfo>lambdaQuery().eq(EmailInfo::getEmail, email));
|
|
|
- // 如果存在,直接返回邮箱信息
|
|
|
- if (emailInfo != null) {
|
|
|
+ EmailInfo emailInfo = emailInfoService.getOne(Wrappers.<EmailInfo>lambdaQuery().eq(EmailInfo::getEmail, email));
|
|
|
+ // 如果存在,直接返回邮箱信息
|
|
|
+ if (emailInfo != null) {
|
|
|
+ return emailInfo;
|
|
|
+ }
|
|
|
+ // 保存账号信息到数据库
|
|
|
+ emailInfo = this.saveEmailInfo(bindingVo);
|
|
|
+ // 添加账号
|
|
|
+ EmailEngineUtil.createAccount(bindingVo);
|
|
|
+ // redis添加同步进度
|
|
|
+ this.progressInitialization(bindingVo);
|
|
|
+ // 异步遍历文件夹下的所有邮件
|
|
|
+ this.asyncReadEmail(emailInfo.getId(), bindingVo);
|
|
|
return emailInfo;
|
|
|
+ } catch (Exception e) {
|
|
|
+ EmailEngineUtil.deleteAccount(bindingVo.getEmail());
|
|
|
+ throw e;
|
|
|
}
|
|
|
- // 保存账号信息到数据库
|
|
|
- emailInfo = this.saveEmailInfo(bindingVo);
|
|
|
- // 添加账号
|
|
|
- EmailEngineUtil.createAccount(bindingVo);
|
|
|
- // 查询邮箱文件夹
|
|
|
- List<EmailMailboxVo.MailboxesDTO> mailboxList = EmailEngineUtil.getMailboxList(email);
|
|
|
- // 添加邮箱文件夹
|
|
|
- List<EmailMailbox> emailMailboxList = this.saveEmailMailbox(mailboxList, emailInfo.getId(), email);
|
|
|
- // redis添加同步进度
|
|
|
- this.synchronizationProgressInitialization(email, bindingVo.getPages(), mailboxList);
|
|
|
- // 异步遍历文件夹下的所有邮件
|
|
|
- // this.asyncReadEmail(email, bindingVo.getPages(), emailMailboxList);
|
|
|
- return emailInfo;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@@ -95,15 +96,6 @@ public class AccountServiceImpl implements IAccountService {
|
|
|
case MESSAGE_UPDATED:
|
|
|
this.handleMessageUpdatedEvent(listenerVo);
|
|
|
break;
|
|
|
- case MAILBOX_NEW:
|
|
|
- this.handleMailboxNewEvent(listenerVo);
|
|
|
- break;
|
|
|
- case MAILBOX_DELETED:
|
|
|
- this.handleMailboxDeleteEvent(listenerVo);
|
|
|
- break;
|
|
|
- case MAILBOX_RESET:
|
|
|
- this.handleMailboxResetEvent(listenerVo);
|
|
|
- break;
|
|
|
default:
|
|
|
log.error("监听到未知事件:{}", JSONObject.toJSONString(listenerVo));
|
|
|
}
|
|
@@ -125,99 +117,83 @@ public class AccountServiceImpl implements IAccountService {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 添加邮箱文件夹
|
|
|
- */
|
|
|
- private List<EmailMailbox> saveEmailMailbox(List<EmailMailboxVo.MailboxesDTO> mailboxDTOList, Long emailInfoId, String email) {
|
|
|
-
|
|
|
- List<EmailMailbox> mailboxList = mailboxDTOList.stream().map(item -> {
|
|
|
- EmailMailbox emailMailbox = BeanUtil.copyProperties(item, EmailMailbox.class);
|
|
|
- emailMailbox.setEmailInfoId(emailInfoId);
|
|
|
- emailMailbox.setEmail(email);
|
|
|
- emailMailbox.setIsShow(true);
|
|
|
- emailMailbox.setInitialize(false);
|
|
|
- return emailMailbox;
|
|
|
- }).distinct().collect(Collectors.toList());
|
|
|
-
|
|
|
- emailMailboxService.saveBatch(mailboxList);
|
|
|
-
|
|
|
- return mailboxList;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
* 同步邮件进度初始化
|
|
|
*/
|
|
|
- private void synchronizationProgressInitialization(String email, int pages, List<EmailMailboxVo.MailboxesDTO> mailboxList) {
|
|
|
+ private void progressInitialization(BindingVo bindingVo) {
|
|
|
+ String email = bindingVo.getEmail();
|
|
|
+ int pages = bindingVo.getPages();
|
|
|
|
|
|
ProgressVo progressVo = new ProgressVo();
|
|
|
-
|
|
|
-
|
|
|
- List<ProgressVo.Details> detailsList = BeanUtil.copyToList(mailboxList, ProgressVo.Details.class);
|
|
|
-
|
|
|
- int totalMessageCount = 0;
|
|
|
-
|
|
|
- for (ProgressVo.Details detail : detailsList) {
|
|
|
- detail.setMessages(detail.getMessages() > pages * 10 ? pages * 10 : detail.getMessages());
|
|
|
- detail.setCompleteMessageCount(0);
|
|
|
- detail.setPercentage(0);
|
|
|
- totalMessageCount += detail.getMessages();
|
|
|
- }
|
|
|
-
|
|
|
progressVo.setEmail(email);
|
|
|
- progressVo.setTotalMessageCount(totalMessageCount);
|
|
|
progressVo.setCompleteMessageCount(0);
|
|
|
progressVo.setPercentage(0);
|
|
|
- progressVo.setDetailsList(detailsList);
|
|
|
+ progressVo.setInit(false);
|
|
|
+ RedisCache.set(RedisConstant.PROGRESS_KEY + email, progressVo);
|
|
|
+
|
|
|
+ ThreadUtil.sleep(1000L);
|
|
|
|
|
|
+ MessageVo messageVo = EmailEngineUtil.getMessageList(email, bindingVo.getPath(), 1);
|
|
|
+ progressVo.setInit(true);
|
|
|
+ progressVo.setTotalMessageCount(messageVo.getTotal() > pages * 10 ? pages * 10 : messageVo.getTotal());
|
|
|
RedisCache.set(RedisConstant.PROGRESS_KEY + email, progressVo);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 异步读取文件
|
|
|
*/
|
|
|
- private void asyncReadEmail(String email, int pages, List<EmailMailbox> emailMailboxList) {
|
|
|
+ private void asyncReadEmail(Long emailInfoId, BindingVo bindingVo) {
|
|
|
+ String email = bindingVo.getEmail();
|
|
|
+ int pages = bindingVo.getPages();
|
|
|
+ String mailbox = bindingVo.getPath();
|
|
|
+
|
|
|
executor.execute(() -> {
|
|
|
ThreadUtil.sleep(3000);
|
|
|
|
|
|
// 记录上次消息id,防止循环查询分页过程中接收到了新邮件,出现邮件重复问题
|
|
|
List<String> lastMessageIdList = new ArrayList<>();
|
|
|
|
|
|
- // 遍历每个邮箱
|
|
|
- for (EmailMailbox emailMailbox : emailMailboxList) {
|
|
|
- int page = 0;
|
|
|
- while (page < pages) {
|
|
|
- MessageVo result = EmailEngineUtil.getMessageList(email, emailMailbox.getPath(), page);
|
|
|
- List<MessageVo.MessagesDTO> messagesDTOList = result.getMessages();
|
|
|
- if (messagesDTOList.size() > 0) {
|
|
|
- List<EmailMessage> emailMessageList = this.saveBatchMessage(email, lastMessageIdList, emailMailbox, messagesDTOList);
|
|
|
- this.synchronizationProgress(email, messagesDTOList, emailMailbox);
|
|
|
-
|
|
|
- lastMessageIdList.clear();
|
|
|
- for (EmailMessage emailMessage : emailMessageList) {
|
|
|
- lastMessageIdList.add(emailMessage.getMessageId());
|
|
|
- }
|
|
|
+ int page = 0;
|
|
|
+ while (page < pages) {
|
|
|
+ MessageVo result = EmailEngineUtil.getMessageList(email, mailbox, page);
|
|
|
+ List<MessageVo.MessagesDTO> messagesDTOList = result.getMessages();
|
|
|
+ if (messagesDTOList.size() > 0) {
|
|
|
+ // 批量保存邮件信息
|
|
|
+ List<EmailMessage> emailMessageList = this.saveBatchMessage(emailInfoId, email, lastMessageIdList, messagesDTOList);
|
|
|
+
|
|
|
+ // 更新同步邮件进度
|
|
|
+ this.synchronizationProgress(email, messagesDTOList);
|
|
|
+
|
|
|
+ // 记录上次保存的邮件id
|
|
|
+ lastMessageIdList.clear();
|
|
|
+ for (EmailMessage emailMessage : emailMessageList) {
|
|
|
+ lastMessageIdList.add(emailMessage.getMessageId());
|
|
|
}
|
|
|
- page++;
|
|
|
+
|
|
|
+ ThreadUtil.sleep(3000);
|
|
|
}
|
|
|
+ page++;
|
|
|
}
|
|
|
+
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 批量保存邮件信息
|
|
|
*/
|
|
|
- private List<EmailMessage> saveBatchMessage(String email, List<String> lastMessageId, EmailMailbox emailMailbox, List<MessageVo.MessagesDTO> messageList) {
|
|
|
+ private List<EmailMessage> saveBatchMessage(Long emailInfoId, String email, List<String> lastMessageId, List<MessageVo.MessagesDTO> messageList) {
|
|
|
List<EmailMessage> emailMessageList = new ArrayList<>();
|
|
|
List<EmailMessageSend> emailMessageSendList = new ArrayList<>();
|
|
|
List<EmailMessageAttachment> emailMessageAttachmentList = new ArrayList<>();
|
|
|
|
|
|
for (MessageVo.MessagesDTO messagesDTO : messageList) {
|
|
|
+
|
|
|
// 已添加过的邮件则跳过
|
|
|
if (lastMessageId.contains(messagesDTO.getId())) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
// 生成邮件实体
|
|
|
- EmailMessage emailMessage = this.createMessage(email, emailMailbox, messagesDTO);
|
|
|
+ EmailMessage emailMessage = this.createMessage(emailInfoId, email, messagesDTO);
|
|
|
emailMessageList.add(emailMessage);
|
|
|
|
|
|
// 添加推送信息
|
|
@@ -240,15 +216,13 @@ public class AccountServiceImpl implements IAccountService {
|
|
|
/**
|
|
|
* 生成邮件实体
|
|
|
*/
|
|
|
- private EmailMessage createMessage(String email, EmailMailbox emailMailbox, MessageVo.MessagesDTO messagesDTO) {
|
|
|
+ private EmailMessage createMessage(Long emailInfoId, String email, MessageVo.MessagesDTO messagesDTO) {
|
|
|
|
|
|
EmailMessage emailMessage = new EmailMessage();
|
|
|
emailMessage.setId(IdWorker.getId());
|
|
|
emailMessage.setMessageId(messagesDTO.getId());
|
|
|
- emailMessage.setEmailInfoId(emailMailbox.getEmailInfoId());
|
|
|
- emailMessage.setEmail(emailMailbox.getEmail());
|
|
|
- emailMessage.setEmailMailboxId(emailMailbox.getId());
|
|
|
- emailMessage.setEmailMailboxPath(emailMailbox.getPath());
|
|
|
+ emailMessage.setEmailInfoId(emailInfoId);
|
|
|
+ emailMessage.setEmail(email);
|
|
|
emailMessage.setUnseen(messagesDTO.getUnseen());
|
|
|
emailMessage.setFlagged(messagesDTO.getFlagged());
|
|
|
emailMessage.setSubject(messagesDTO.getSubject());
|
|
@@ -357,26 +331,11 @@ public class AccountServiceImpl implements IAccountService {
|
|
|
/**
|
|
|
* 同步邮件进度
|
|
|
*/
|
|
|
- private void synchronizationProgress(String email, List<MessageVo.MessagesDTO> messagesDTOList, EmailMailbox emailMailbox) {
|
|
|
-
|
|
|
+ private void synchronizationProgress(String email, List<MessageVo.MessagesDTO> messagesDTOList) {
|
|
|
ProgressVo progressVo = RedisCache.get(RedisConstant.PROGRESS_KEY + email);
|
|
|
int completeMessageCount = progressVo.getCompleteMessageCount() + messagesDTOList.size();
|
|
|
progressVo.setCompleteMessageCount(completeMessageCount);
|
|
|
progressVo.setPercentage(100 * completeMessageCount / progressVo.getTotalMessageCount());
|
|
|
-
|
|
|
- for (ProgressVo.Details details : progressVo.getDetailsList()) {
|
|
|
- if (details.getPath().equals(emailMailbox.getPath())) {
|
|
|
- int detailsCompleteMessageCount = details.getCompleteMessageCount() + messagesDTOList.size();
|
|
|
- details.setCompleteMessageCount(detailsCompleteMessageCount);
|
|
|
- if (details.getMessages() == 0) {
|
|
|
- details.setPercentage(100);
|
|
|
- } else {
|
|
|
- details.setPercentage(100 * detailsCompleteMessageCount / details.getMessages());
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
RedisCache.set(RedisConstant.PROGRESS_KEY + email, progressVo);
|
|
|
}
|
|
|
|
|
@@ -386,17 +345,14 @@ public class AccountServiceImpl implements IAccountService {
|
|
|
private void handleMessageNewEvent(ListenerVo listenerVo) {
|
|
|
// 查询邮箱
|
|
|
String account = listenerVo.getAccount();
|
|
|
- String path = listenerVo.getPath();
|
|
|
|
|
|
- EmailMailbox emailMailbox;
|
|
|
+ EmailInfo emailInfo;
|
|
|
try {
|
|
|
- emailMailbox = RetryUtil.execute(() -> {
|
|
|
- EmailMailbox tempEmailMailbox = emailMailboxService.getOne(Wrappers.<EmailMailbox>lambdaQuery()
|
|
|
- .eq(EmailMailbox::getPath, path)
|
|
|
- .eq(EmailMailbox::getEmail, account)
|
|
|
- );
|
|
|
- Assert.notNull(tempEmailMailbox, "未找到邮箱信息");
|
|
|
- return tempEmailMailbox;
|
|
|
+ emailInfo = RetryUtil.execute(() -> {
|
|
|
+ EmailInfo tempEmailInfo = emailInfoService.getOne(Wrappers.<EmailInfo>lambdaQuery()
|
|
|
+ .eq(EmailInfo::getEmail, account));
|
|
|
+ Assert.notNull(tempEmailInfo, "未找到邮箱信息");
|
|
|
+ return tempEmailInfo;
|
|
|
});
|
|
|
} catch (Exception e) {
|
|
|
log.error("查找邮箱失败", e);
|
|
@@ -407,7 +363,7 @@ public class AccountServiceImpl implements IAccountService {
|
|
|
MessageVo.MessagesDTO messagesDTO = listenerVo.getData().toJavaObject(MessageVo.MessagesDTO.class);
|
|
|
|
|
|
// 保存邮件
|
|
|
- EmailMessage emailMessage = this.createMessage(account, emailMailbox, messagesDTO);
|
|
|
+ EmailMessage emailMessage = this.createMessage(emailInfo.getId(), emailInfo.getEmail(), messagesDTO);
|
|
|
emailMessageService.save(emailMessage);
|
|
|
|
|
|
// 保存推送人信息
|
|
@@ -437,48 +393,4 @@ public class AccountServiceImpl implements IAccountService {
|
|
|
log.error("邮件flag改变:{}", JSON.toJSONString(listenerVo));
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 新增文件夹事件
|
|
|
- */
|
|
|
- private void handleMailboxNewEvent(ListenerVo listenerVo) {
|
|
|
-
|
|
|
- EmailMailboxVo.MailboxesDTO mailboxesDTO = listenerVo.getData().toJavaObject(EmailMailboxVo.MailboxesDTO.class);
|
|
|
-
|
|
|
- EmailInfo emailInfo = emailInfoService.getOne(
|
|
|
- Wrappers.<EmailInfo>lambdaQuery().eq(EmailInfo::getEmail, listenerVo.getAccount()));
|
|
|
-
|
|
|
- EmailMailbox emailMailbox = new EmailMailbox();
|
|
|
- emailMailbox.setEmailInfoId(emailInfo.getId());
|
|
|
- emailMailbox.setEmail(emailInfo.getEmail());
|
|
|
- emailMailbox.setName(mailboxesDTO.getName());
|
|
|
- emailMailbox.setPath(mailboxesDTO.getPath());
|
|
|
- emailMailbox.setIsShow(true);
|
|
|
- emailMailbox.setInitialize(true);
|
|
|
- emailMailboxService.save(emailMailbox);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 删除文件夹事件
|
|
|
- */
|
|
|
- private void handleMailboxDeleteEvent(ListenerVo listenerVo) {
|
|
|
- EmailMailboxVo.MailboxesDTO mailboxesDTO = listenerVo.getData().toJavaObject(EmailMailboxVo.MailboxesDTO.class);
|
|
|
-
|
|
|
- boolean remove = emailMailboxService.remove(Wrappers.<EmailMailbox>lambdaQuery()
|
|
|
- .eq(EmailMailbox::getPath, mailboxesDTO.getPath())
|
|
|
- .eq(EmailMailbox::getEmail, listenerVo.getAccount())
|
|
|
- );
|
|
|
-
|
|
|
- if (!remove) {
|
|
|
- log.error("文件夹删除失败:email '{}',path '{}'", listenerVo.getAccount(), mailboxesDTO.getPath());
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 更新文件夹事件
|
|
|
- */
|
|
|
- public void handleMailboxResetEvent(ListenerVo listenerVo) {
|
|
|
- log.error("更新文件夹:{}", JSON.toJSONString(listenerVo));
|
|
|
- }
|
|
|
-
|
|
|
}
|