24282 2 年之前
父节点
当前提交
ab66bb2706
共有 2 个文件被更改,包括 56 次插入30 次删除
  1. 36 30
      src/main/java/com/fjhx/service/impl/AccountServiceImpl.java
  2. 20 0
      src/main/java/com/fjhx/vo/ProgressVo.java

+ 36 - 30
src/main/java/com/fjhx/service/impl/AccountServiceImpl.java

@@ -33,10 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.context.ServletContextAware;
 
 import javax.servlet.ServletContext;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 import java.util.concurrent.Executor;
 import java.util.stream.Collectors;
 
@@ -82,6 +79,16 @@ public class AccountServiceImpl implements IAccountService, ServletContextAware
     public void setServletContext(ServletContext servletContext) {
         syncExecutor.execute(this::syncMessageContent);
         syncExecutor.execute(this::syncMessageAttachment);
+
+        syncExecutor.execute(() -> {
+            ThreadUtil.sleep(1000 * 10);
+            Collection<String> keys = RedisCache.keys(RedisConstant.PROGRESS_KEY + "*");
+            for (String key : keys) {
+                ProgressVo progressVo = RedisCache.get(key);
+                this.asyncReadEmail(progressVo);
+            }
+        });
+
     }
 
     /**
@@ -216,6 +223,7 @@ public class AccountServiceImpl implements IAccountService, ServletContextAware
         if (emailInfo != null) {
             return emailInfo;
         }
+        ProgressVo progressVo;
         try {
             // 保存账号信息到数据库
             emailInfo = BeanUtil.copyProperties(bindingVo, EmailInfo.class);
@@ -223,14 +231,14 @@ public class AccountServiceImpl implements IAccountService, ServletContextAware
             // 添加账号
             RetryUtil.execute(() -> EmailEngineUtil.createAccount(bindingVo), 3, 3000L);
             // redis添加同步进度
-            this.progressInitialization(bindingVo);
+            progressVo = this.progressInitialization(emailInfo.getId(), bindingVo);
         } catch (Exception e) {
             RetryUtil.execute(() -> EmailEngineUtil.deleteAccount(bindingVo.getEmail()), 5, 3000L);
             throw new ServiceException("添加邮箱失败");
         }
 
         // 异步遍历文件夹下的所有邮件
-        this.asyncReadEmail(emailInfo.getId(), bindingVo, 0);
+        this.asyncReadEmail(progressVo);
         return emailInfo;
     }
 
@@ -259,7 +267,7 @@ public class AccountServiceImpl implements IAccountService, ServletContextAware
     /**
      * 同步邮件进度初始化
      */
-    private void progressInitialization(BindingVo bindingVo) {
+    private ProgressVo progressInitialization(Long emailInfoId, BindingVo bindingVo) {
         String email = bindingVo.getEmail();
         int pages = bindingVo.getPages();
 
@@ -267,51 +275,52 @@ public class AccountServiceImpl implements IAccountService, ServletContextAware
         MessageVo messageVo = RetryUtil.executeT(() -> EmailEngineUtil.getMessageList(email, bindingVo.getPath(), 0, 1), 5, 3000L);
 
         ProgressVo progressVo = new ProgressVo();
+        progressVo.setPage(0);
+        progressVo.setPages(messageVo.getPages() > pages ? pages : messageVo.getPages());
+        progressVo.setPath(bindingVo.getPath());
         progressVo.setEmail(email);
+        progressVo.setEmailInfoId(emailInfoId);
         progressVo.setTotalMessageCount(messageVo.getTotal() > pages * SIZE ? pages * SIZE : messageVo.getTotal());
         progressVo.setCompleteMessageCount(0);
         progressVo.setPercentage(0);
         RedisCache.set(RedisConstant.PROGRESS_KEY + email, progressVo);
+        return progressVo;
     }
 
     /**
      * 异步读取文件
      */
-    private void asyncReadEmail(Long emailInfoId, BindingVo bindingVo, Integer pageFlag) {
-        String email = bindingVo.getEmail();
-        String mailbox = bindingVo.getPath();
-        int pages = bindingVo.getPages();
+    private void asyncReadEmail(ProgressVo progressVo) {
+        String email = progressVo.getEmail();
+        String mailbox = progressVo.getPath();
+        Long emailInfoId = progressVo.getEmailInfoId();
 
         syncMailboxExecutor.execute(() -> {
-            int page = pageFlag;
             try {
-                while (page < pages) {
-                    int itemPage = page;
+                Integer page = progressVo.getPage();
+                while (page < progressVo.getPages()) {
                     // 分页获取文件夹邮件
-                    MessageVo result = EmailEngineUtil.getMessageList(email, mailbox, itemPage, SIZE);
+                    MessageVo result = EmailEngineUtil.getMessageList(email, mailbox, page, SIZE);
                     // 邮件信息
                     List<MessageVo.MessagesDTO> messagesDTOList = result.getMessages();
                     // 批量保存邮件信息
                     this.saveBatchMessage(emailInfoId, email, messagesDTOList);
-                    // 更新同步邮件进度
-                    this.synchronizationProgress(email, messagesDTOList);
-                    page++;
 
+                    // 更新同步邮件进度
+                    progressVo.setPage(++page);
+                    this.synchronizationProgress(progressVo);
                     ThreadUtil.sleep(1000L);
                 }
             } catch (EmailEngineException e) {
                 log.error("同步邮件列表失败,等待3分钟");
                 ThreadUtil.sleep(1000 * 60 * 3);
-                asyncReadEmail(emailInfoId, bindingVo, page);
+                asyncReadEmail(progressVo);
             } catch (Exception e) {
                 log.error("未知原因同步邮件失败:{}", email, e);
+                ThreadUtil.sleep(1000 * 60 * 60);
+                asyncReadEmail(progressVo);
             }
         });
-
-        String redisKey = RedisConstant.PROGRESS_KEY + email;
-        ProgressVo progressVo = RedisCache.get(redisKey);
-        progressVo.setPercentage(100);
-        RedisCache.set(redisKey, progressVo);
     }
 
     /**
@@ -392,14 +401,11 @@ public class AccountServiceImpl implements IAccountService, ServletContextAware
     /**
      * 同步邮件进度
      */
-    private void synchronizationProgress(String email, List<MessageVo.MessagesDTO> messagesDTOList) {
-        String redisKey = RedisConstant.PROGRESS_KEY + email;
-        ProgressVo progressVo = RedisCache.get(redisKey);
-        int completeMessageCount = progressVo.getCompleteMessageCount() + messagesDTOList.size();
-
+    private void synchronizationProgress(ProgressVo progressVo) {
+        int completeMessageCount = progressVo.getCompleteMessageCount() + SIZE;
         progressVo.setCompleteMessageCount(completeMessageCount);
         progressVo.setPercentage(100 * completeMessageCount / progressVo.getTotalMessageCount());
-        RedisCache.set(redisKey, progressVo);
+        RedisCache.set(RedisConstant.PROGRESS_KEY + progressVo.getEmail(), progressVo);
     }
 
     /**

+ 20 - 0
src/main/java/com/fjhx/vo/ProgressVo.java

@@ -10,11 +10,31 @@ public class ProgressVo implements Serializable {
     private static final long serialVersionUID = 1L;
 
     /**
+     * 同步页数
+     */
+    private Integer page;
+
+    /**
+     * 总页数
+     */
+    private Integer pages;
+
+    /**
      * 邮箱
      */
     private String email;
 
     /**
+     * 邮件id
+     */
+    private Long emailInfoId;
+
+    /**
+     * 路径
+     */
+    private String path;
+
+    /**
      * 所有需要同步的邮件数量
      */
     private Integer totalMessageCount;