24282 2 years ago
commit
9ee7784d17
69 changed files with 2882 additions and 0 deletions
  1. 40 0
      .gitignore
  2. 86 0
      pom.xml
  3. 23 0
      src/main/java/com/fjhx/email/EmailSyncApplication.java
  4. 59 0
      src/main/java/com/fjhx/email/config/TaskPoolConfig.java
  5. 56 0
      src/main/java/com/fjhx/email/config/WebMvcConfig.java
  6. 32 0
      src/main/java/com/fjhx/email/config/base/BaseEntity.java
  7. 72 0
      src/main/java/com/fjhx/email/config/base/BaseSelectVo.java
  8. 69 0
      src/main/java/com/fjhx/email/config/base/BaseService.java
  9. 58 0
      src/main/java/com/fjhx/email/config/base/R.java
  10. 25 0
      src/main/java/com/fjhx/email/config/exception/ServiceException.java
  11. 73 0
      src/main/java/com/fjhx/email/config/exception/UnifiedExceptionHandler.java
  12. 42 0
      src/main/java/com/fjhx/email/config/mybatis/MyMetaObjectHandler.java
  13. 46 0
      src/main/java/com/fjhx/email/config/mybatis/MybatisConfig.java
  14. 18 0
      src/main/java/com/fjhx/email/controller/EnterpriseDomainController.java
  15. 18 0
      src/main/java/com/fjhx/email/controller/EnterpriseFolderController.java
  16. 18 0
      src/main/java/com/fjhx/email/controller/EnterpriseMailboxController.java
  17. 18 0
      src/main/java/com/fjhx/email/controller/EnterpriseMessageController.java
  18. 18 0
      src/main/java/com/fjhx/email/controller/PersonalFolderController.java
  19. 18 0
      src/main/java/com/fjhx/email/controller/PersonalMailboxController.java
  20. 18 0
      src/main/java/com/fjhx/email/controller/PersonalMessageController.java
  21. 80 0
      src/main/java/com/fjhx/email/entity/EnterpriseDomain.java
  22. 48 0
      src/main/java/com/fjhx/email/entity/EnterpriseFolder.java
  23. 70 0
      src/main/java/com/fjhx/email/entity/EnterpriseMailbox.java
  24. 92 0
      src/main/java/com/fjhx/email/entity/EnterpriseMessage.java
  25. 48 0
      src/main/java/com/fjhx/email/entity/PersonalFolder.java
  26. 101 0
      src/main/java/com/fjhx/email/entity/PersonalMailbox.java
  27. 93 0
      src/main/java/com/fjhx/email/entity/PersonalMessage.java
  28. 37 0
      src/main/java/com/fjhx/email/entity/dto/MailFolderInfo.java
  29. 52 0
      src/main/java/com/fjhx/email/entity/dto/MailInfo.java
  30. 67 0
      src/main/java/com/fjhx/email/entity/dto/MailSyncInfo.java
  31. 59 0
      src/main/java/com/fjhx/email/entity/dto/MailboxInfo.java
  32. 20 0
      src/main/java/com/fjhx/email/entity/dto/ObsFile.java
  33. 59 0
      src/main/java/com/fjhx/email/entity/dto/SendDto.java
  34. 39 0
      src/main/java/com/fjhx/email/enums/MailFlagEnum.java
  35. 16 0
      src/main/java/com/fjhx/email/mapper/EnterpriseDomainMapper.java
  36. 16 0
      src/main/java/com/fjhx/email/mapper/EnterpriseFolderMapper.java
  37. 16 0
      src/main/java/com/fjhx/email/mapper/EnterpriseMailboxMapper.java
  38. 16 0
      src/main/java/com/fjhx/email/mapper/EnterpriseMessageMapper.java
  39. 16 0
      src/main/java/com/fjhx/email/mapper/PersonalFolderMapper.java
  40. 16 0
      src/main/java/com/fjhx/email/mapper/PersonalMailboxMapper.java
  41. 16 0
      src/main/java/com/fjhx/email/mapper/PersonalMessageMapper.java
  42. 5 0
      src/main/java/com/fjhx/email/mapper/xml/EnterpriseDomainMapper.xml
  43. 5 0
      src/main/java/com/fjhx/email/mapper/xml/EnterpriseFolderMapper.xml
  44. 5 0
      src/main/java/com/fjhx/email/mapper/xml/EnterpriseMailboxMapper.xml
  45. 5 0
      src/main/java/com/fjhx/email/mapper/xml/EnterpriseMessageMapper.xml
  46. 5 0
      src/main/java/com/fjhx/email/mapper/xml/PersonalFolderMapper.xml
  47. 5 0
      src/main/java/com/fjhx/email/mapper/xml/PersonalMailboxMapper.xml
  48. 5 0
      src/main/java/com/fjhx/email/mapper/xml/PersonalMessageMapper.xml
  49. 16 0
      src/main/java/com/fjhx/email/service/IEnterpriseDomainService.java
  50. 16 0
      src/main/java/com/fjhx/email/service/IEnterpriseFolderService.java
  51. 16 0
      src/main/java/com/fjhx/email/service/IEnterpriseMailboxService.java
  52. 16 0
      src/main/java/com/fjhx/email/service/IEnterpriseMessageService.java
  53. 16 0
      src/main/java/com/fjhx/email/service/IPersonalFolderService.java
  54. 16 0
      src/main/java/com/fjhx/email/service/IPersonalMailboxService.java
  55. 16 0
      src/main/java/com/fjhx/email/service/IPersonalMessageService.java
  56. 471 0
      src/main/java/com/fjhx/email/service/impl/CoreServiceImpl.java
  57. 20 0
      src/main/java/com/fjhx/email/service/impl/EnterpriseDomainServiceImpl.java
  58. 20 0
      src/main/java/com/fjhx/email/service/impl/EnterpriseFolderServiceImpl.java
  59. 20 0
      src/main/java/com/fjhx/email/service/impl/EnterpriseMailboxServiceImpl.java
  60. 20 0
      src/main/java/com/fjhx/email/service/impl/EnterpriseMessageServiceImpl.java
  61. 20 0
      src/main/java/com/fjhx/email/service/impl/PersonalFolderServiceImpl.java
  62. 20 0
      src/main/java/com/fjhx/email/service/impl/PersonalMailboxServiceImpl.java
  63. 20 0
      src/main/java/com/fjhx/email/service/impl/PersonalMessageServiceImpl.java
  64. 189 0
      src/main/java/com/fjhx/email/utils/EmailUtil.java
  65. 54 0
      src/main/java/com/fjhx/email/utils/PageWrapper.java
  66. 18 0
      src/main/resources/application-dev.yml
  67. 6 0
      src/main/resources/application-prod.yml
  68. 29 0
      src/main/resources/application.yml
  69. 44 0
      src/test/java/CodeGeneration.java

+ 40 - 0
.gitignore

@@ -0,0 +1,40 @@
+# Created by .ignore support plugin (hsz.mobi)
+### Java template
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs
+hs_err_pid*
+
+.idea/.gitignore
+.idea/misc.xml
+.idea/modules.xml
+.idea/vcs.xml
+
+.idea
+app-log
+**/target
+**/libraries
+**/*.iml
+
+# 测试环境配置不提交
+fly-admin/src/main/resources/application-dev.yml
+

+ 86 - 0
pom.xml

@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.fjhx</groupId>
+    <artifactId>email-sync</artifactId>
+    <version>1.0</version>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.7.6</version>
+    </parent>
+
+    <dependencies>
+
+        <!-- SpringBoot Web容器 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <!-- mysql数据库驱动 -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+
+        <!-- lombok -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+        <!-- mail -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-mail</artifactId>
+        </dependency>
+
+        <!-- mybatis-plus -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.5.3.1</version>
+        </dependency>
+
+        <!-- hutool -->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.15</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-generator</artifactId>
+            <version>3.5.3.1</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.velocity</groupId>
+            <artifactId>velocity-engine-core</artifactId>
+            <version>2.3</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba.fastjson2</groupId>
+            <artifactId>fastjson2</artifactId>
+            <version>2.0.25</version>
+        </dependency>
+
+    </dependencies>
+
+
+</project>

+ 23 - 0
src/main/java/com/fjhx/email/EmailSyncApplication.java

@@ -0,0 +1,23 @@
+package com.fjhx.email;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@Slf4j
+@EnableScheduling
+@SpringBootApplication
+public class EmailSyncApplication {
+
+    public static void main(String[] args) {
+
+        SpringApplication.run(EmailSyncApplication.class, args);
+
+        log.info("\r\n==================================================================\r\n"
+                + ">>>>> " + EmailSyncApplication.class.getSimpleName() + " is success!\r\n"
+                + "==================================================================");
+
+    }
+
+}

+ 59 - 0
src/main/java/com/fjhx/email/config/TaskPoolConfig.java

@@ -0,0 +1,59 @@
+package com.fjhx.email.config;
+
+import cn.hutool.core.thread.ThreadUtil;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 线程池配置
+ */
+@EnableAsync
+@Configuration
+public class TaskPoolConfig {
+
+    public static final String emailInfoTaskExecutor = "emailInfoTaskExecutor";
+    public static final String emailContentTaskExecutor = "emailContentTaskExecutor";
+
+    /**
+     * 获取邮件基本信息线程池
+     */
+    @Bean(name = emailInfoTaskExecutor)
+    public ThreadPoolExecutor emailInfoTaskExecutor() {
+        return new ThreadPoolExecutor(
+                10,
+                20,
+                60,
+                TimeUnit.SECONDS,
+                new ArrayBlockingQueue<>(30),
+                (runnable, executor) -> {
+                    // 等待5秒之后重新入线程池
+                    ThreadUtil.sleep(3000);
+                    executor.execute(runnable);
+                }
+        );
+    }
+
+    /**
+     * 获取邮件正文、附件、地址线程池
+     */
+    @Bean(name = emailContentTaskExecutor)
+    public ThreadPoolExecutor emailContentTaskExecutor() {
+        return new ThreadPoolExecutor(
+                3,
+                20,
+                60,
+                TimeUnit.SECONDS,
+                new ArrayBlockingQueue<>(20),
+                (runnable, executor) -> {
+                    // 本线程执行
+                    runnable.run();
+                }
+        );
+    }
+
+}

+ 56 - 0
src/main/java/com/fjhx/email/config/WebMvcConfig.java

@@ -0,0 +1,56 @@
+package com.fjhx.email.config;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fjhx.email.utils.PageWrapper;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.List;
+
+/**
+ * WebMvc配置
+ */
+@EnableWebMvc
+@Configuration
+@SuppressWarnings({"unchecked", "rawtypes"})
+public class WebMvcConfig implements WebMvcConfigurer {
+
+    /**
+     * webMvc序列化
+     */
+    @Override
+    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+
+        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
+
+        ObjectMapper objectMapper = converter.getObjectMapper()
+                // 时间格式化
+                .setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
+                .registerModule(new SimpleModule()
+                        // 将Long转换成String
+                        .addSerializer(Long.class, ToStringSerializer.instance)
+                        // 将Page转成PageWrapper
+                        .addSerializer(IPage.class, new JsonSerializer<IPage>() {
+                            @Override
+                            public void serialize(IPage page, JsonGenerator jg, SerializerProvider sp) throws IOException {
+                                jg.writeObject(new PageWrapper(page));
+                            }
+                        })
+                );
+
+        converter.setObjectMapper(objectMapper);
+        converters.add(converter);
+    }
+
+}

+ 32 - 0
src/main/java/com/fjhx/email/config/base/BaseEntity.java

@@ -0,0 +1,32 @@
+package com.fjhx.email.config.base;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.ASSIGN_ID)
+    private Long id;
+
+    /**
+     * 创建时间
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Date updateTime;
+
+}

+ 72 - 0
src/main/java/com/fjhx/email/config/base/BaseSelectVo.java

@@ -0,0 +1,72 @@
+package com.fjhx.email.config.base;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class BaseSelectVo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 页数
+     */
+    private Integer pageNum;
+
+    /**
+     * 每页条数
+     */
+    private Integer pageSize;
+
+    /**
+     * 关键字查询
+     */
+    private String keyword;
+
+    /**
+     * 通用开始时间
+     */
+    private String beginTime;
+
+    /**
+     * 通用结束时间
+     */
+    private String endTime;
+
+    /**
+     * 返回分页实体
+     */
+    public <T> Page<T> getPage() {
+        return new Page<>(getPageNum(), getPageSize());
+    }
+
+    public Integer getPageNum() {
+        return ObjectUtil.defaultIfNull(pageNum, 1);
+    }
+
+    public Integer getPageSize() {
+        return ObjectUtil.defaultIfNull(pageSize, 10);
+    }
+
+    public Date getBeginTime() {
+        if (ObjectUtil.isEmpty(beginTime)) {
+            return null;
+        }
+
+        return DateUtil.beginOfDay(DateUtil.parse(beginTime));
+    }
+
+    public Date getEndTime() {
+        if (ObjectUtil.isEmpty(endTime)) {
+            return null;
+        }
+
+        return DateUtil.endOfDay(DateUtil.parse(endTime));
+    }
+
+}

+ 69 - 0
src/main/java/com/fjhx/email/config/base/BaseService.java

@@ -0,0 +1,69 @@
+package com.fjhx.email.config.base;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+
+@SuppressWarnings("unused")
+public interface BaseService<T> extends IService<T> {
+
+
+    default Page<T> page(BaseSelectVo baseSelectVo, Consumer<LambdaQueryWrapper<T>> consumer) {
+        return page(baseSelectVo.getPage(), Wrappers.<T>lambdaQuery().func(consumer));
+    }
+
+    default long count(Consumer<LambdaQueryWrapper<T>> consumer) {
+        return count(Wrappers.<T>lambdaQuery().func(ObjectUtil.isNotEmpty(consumer), consumer));
+    }
+
+    default T getOne(Consumer<LambdaQueryWrapper<T>> consumer) {
+        return getOne(Wrappers.<T>lambdaQuery().func(ObjectUtil.isNotEmpty(consumer), consumer).last("limit 1"));
+    }
+
+    default List<T> list(Consumer<LambdaQueryWrapper<T>> consumer) {
+        return list(Wrappers.<T>lambdaQuery().func(ObjectUtil.isNotEmpty(consumer), consumer));
+    }
+
+    default List<Map<String, Object>> listMaps(Consumer<LambdaQueryWrapper<T>> consumer) {
+        return listMaps(Wrappers.<T>lambdaQuery().func(ObjectUtil.isNotEmpty(consumer), consumer));
+    }
+
+    default <K> List<K> listK(SFunction<T, K> mapper, Consumer<LambdaQueryWrapper<T>> consumer) {
+        List<T> list = list(Wrappers.<T>lambdaQuery().select(mapper).func(ObjectUtil.isNotEmpty(consumer), consumer));
+        return list.stream().map(mapper).filter(Objects::nonNull).distinct().collect(Collectors.toList());
+    }
+
+    default <K, V> Map<K, V> mapKV(SFunction<T, K> kFun, SFunction<T, V> vFun, Consumer<LambdaQueryWrapper<T>> consumer) {
+        List<T> list = list(Wrappers.<T>lambdaQuery().select(kFun, vFun).func(ObjectUtil.isNotEmpty(consumer), consumer));
+        return list.stream().collect(Collectors.toMap(kFun, vFun, (v1, v2) -> v2));
+    }
+
+    default <K> Map<K, T> mapKEntity(SFunction<T, K> kFun, Consumer<LambdaQueryWrapper<T>> consumer) {
+        List<T> list = list(Wrappers.<T>lambdaQuery().func(ObjectUtil.isNotEmpty(consumer), consumer));
+        return list.stream().collect(Collectors.toMap(kFun, item -> item, (v1, v2) -> v2));
+    }
+
+    default <K> Map<K, List<T>> mapKGroup(SFunction<T, K> kFun, Consumer<LambdaQueryWrapper<T>> consumer) {
+        List<T> list = list(Wrappers.<T>lambdaQuery().func(ObjectUtil.isNotEmpty(consumer), consumer));
+        return list.stream().collect(Collectors.groupingBy(kFun));
+    }
+
+    default boolean update(Consumer<LambdaUpdateWrapper<T>> consumer) {
+        return update(Wrappers.<T>lambdaUpdate().func(ObjectUtil.isNotEmpty(consumer), consumer));
+    }
+
+    default boolean remove(Consumer<LambdaQueryWrapper<T>> consumer) {
+        return remove(Wrappers.<T>lambdaQuery().func(ObjectUtil.isNotEmpty(consumer), consumer));
+    }
+
+}

+ 58 - 0
src/main/java/com/fjhx/email/config/base/R.java

@@ -0,0 +1,58 @@
+package com.fjhx.email.config.base;
+
+import cn.hutool.http.HttpStatus;
+import lombok.Data;
+
+/**
+ * 统一返回结果的类
+ */
+@Data
+public class R {
+
+    // 是否成功
+    private Boolean success;
+
+    // 返回码
+    private Integer code;
+
+    // 返回消息
+    private String message;
+
+    // 返回数据
+    private Object data;
+
+    // 成功
+    public static R ok() {
+        R r = new R();
+        r.setSuccess(true);
+        r.setCode(HttpStatus.HTTP_OK);
+        r.setMessage("成功");
+        return r;
+    }
+
+    // 成功
+    public static R ok(Object obj) {
+        R r = ok();
+        r.data = obj;
+        return r;
+    }
+
+    // 失败
+    public static R error(String errorMsg) {
+        R r = new R();
+        r.setSuccess(false);
+        r.setCode(HttpStatus.HTTP_BAD_REQUEST);
+        r.setMessage(errorMsg);
+        return r;
+    }
+
+    // 失败
+    public static R error(Integer errorCode, String errorMsg) {
+        R r = new R();
+        r.setSuccess(false);
+        r.setCode(errorCode);
+        r.setMessage(errorMsg);
+        return r;
+    }
+
+}

+ 25 - 0
src/main/java/com/fjhx/email/config/exception/ServiceException.java

@@ -0,0 +1,25 @@
+package com.fjhx.email.config.exception;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpStatus;
+import lombok.Getter;
+
+/**
+ * 自定义异常
+ */
+@Getter
+public class ServiceException extends RuntimeException {
+
+    private final Integer errorCode;
+
+    private final String errorMsg;
+
+    // 传入业务异常说明
+    public ServiceException(String errorMsg, Object... params) {
+        super(errorMsg = StrUtil.format(errorMsg, params));
+        this.errorCode = HttpStatus.HTTP_BAD_REQUEST;
+        this.errorMsg = errorMsg;
+    }
+
+
+}

+ 73 - 0
src/main/java/com/fjhx/email/config/exception/UnifiedExceptionHandler.java

@@ -0,0 +1,73 @@
+package com.fjhx.email.config.exception;
+
+import cn.hutool.http.HttpStatus;
+import com.fjhx.email.config.base.R;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Objects;
+
+/**
+ * 异常拦截器
+ */
+@Slf4j
+@RestControllerAdvice
+public class UnifiedExceptionHandler {
+
+    @Autowired
+    private HttpServletRequest request;
+
+    /**
+     * 自定义业务异常
+     */
+    @ExceptionHandler(value = ServiceException.class)
+    public R handleServiceException(ServiceException e) {
+        return R.error(e.getErrorCode(), e.getErrorMsg());
+    }
+
+    /**
+     * 非法数据异常
+     */
+    @ExceptionHandler(value = IllegalArgumentException.class)
+    public R handleIllegalArgumentException(IllegalArgumentException e) {
+        return R.error(HttpStatus.HTTP_BAD_REQUEST, e.getMessage());
+    }
+
+    /**
+     * 请求参数异常
+     */
+    @ExceptionHandler(HttpMessageNotReadableException.class)
+    public R handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
+        log.error(request.getRequestURI(), e);
+
+        if (Objects.requireNonNull(e.getMessage()).contains("JSON parse error")) {
+            return R.error(HttpStatus.HTTP_UNSUPPORTED_TYPE, "参数格式错误");
+        }
+        return R.error(HttpStatus.HTTP_UNSUPPORTED_TYPE, "请使用JSON方式传参");
+    }
+
+    /**
+     * 请求方式异常
+     */
+    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
+    public R handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
+        String method = e.getMethod();
+        log.error("{} 不支持 {} 请求", request.getRequestURI(), method);
+        return R.error(HttpStatus.HTTP_BAD_METHOD, "此方法不支持" + method + "请求");
+    }
+
+    /**
+     * 其他未知异常
+     */
+    @ExceptionHandler(value = Exception.class)
+    public R handleException(Exception e) {
+        log.error(request.getRequestURI(), e);
+        return R.error(HttpStatus.HTTP_INTERNAL_ERROR, "系统出现未知异常,请联系管理员");
+    }
+
+}

+ 42 - 0
src/main/java/com/fjhx/email/config/mybatis/MyMetaObjectHandler.java

@@ -0,0 +1,42 @@
+package com.fjhx.email.config.mybatis;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import org.apache.ibatis.reflection.MetaObject;
+
+import java.util.Date;
+
+/**
+ * 自定义sql字段填充器,自动填充创建修改相关字段
+ */
+public class MyMetaObjectHandler implements MetaObjectHandler {
+
+    private static final String CREATE_TIME = "createTime";
+
+    private static final String UPDATE_TIME = "updateTime";
+
+    /**
+     * 新增模块时,需要添加的字段
+     */
+    @Override
+    public void insertFill(MetaObject metaObject) {
+        Date date = new Date();
+        if (ObjectUtil.isNotEmpty(metaObject.hasSetter(CREATE_TIME))) {
+            setFieldValByName(CREATE_TIME, date, metaObject);
+        }
+        if (ObjectUtil.isNotEmpty(metaObject.hasSetter(UPDATE_TIME))) {
+            setFieldValByName(UPDATE_TIME, date, metaObject);
+        }
+    }
+
+    /**
+     * 编辑模块时,需要添加的字段
+     */
+    @Override
+    public void updateFill(MetaObject metaObject) {
+        if (ObjectUtil.isNotEmpty(metaObject.hasSetter(UPDATE_TIME))) {
+            setFieldValByName(UPDATE_TIME, new Date(), metaObject);
+        }
+    }
+
+}

+ 46 - 0
src/main/java/com/fjhx/email/config/mybatis/MybatisConfig.java

@@ -0,0 +1,46 @@
+package com.fjhx.email.config.mybatis;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+/**
+ * mybatis扩展插件配置
+ */
+@Configuration
+@EnableTransactionManagement
+@MapperScan("com.fjhx.email.mapper")
+public class MybatisConfig {
+
+    /**
+     * 分页插件
+     */
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptorPage() {
+
+        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+
+        // 分页
+        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
+
+        // 乐观锁
+        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
+
+        return interceptor;
+    }
+
+    /**
+     * 自定义公共字段自动注入
+     */
+    @Bean
+    public MetaObjectHandler metaObjectHandler() {
+        return new MyMetaObjectHandler();
+    }
+
+}

+ 18 - 0
src/main/java/com/fjhx/email/controller/EnterpriseDomainController.java

@@ -0,0 +1,18 @@
+package com.fjhx.email.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 企业邮箱域名 前端控制器
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+@RestController
+@RequestMapping("/enterpriseDomain")
+public class EnterpriseDomainController {
+
+}

+ 18 - 0
src/main/java/com/fjhx/email/controller/EnterpriseFolderController.java

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

+ 18 - 0
src/main/java/com/fjhx/email/controller/EnterpriseMailboxController.java

@@ -0,0 +1,18 @@
+package com.fjhx.email.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 企业邮箱 前端控制器
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+@RestController
+@RequestMapping("/enterpriseMailbox")
+public class EnterpriseMailboxController {
+
+}

+ 18 - 0
src/main/java/com/fjhx/email/controller/EnterpriseMessageController.java

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

+ 18 - 0
src/main/java/com/fjhx/email/controller/PersonalFolderController.java

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

+ 18 - 0
src/main/java/com/fjhx/email/controller/PersonalMailboxController.java

@@ -0,0 +1,18 @@
+package com.fjhx.email.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 个人邮箱 前端控制器
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-04
+ */
+@RestController
+@RequestMapping("/personalMailbox")
+public class PersonalMailboxController {
+
+}

+ 18 - 0
src/main/java/com/fjhx/email/controller/PersonalMessageController.java

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

+ 80 - 0
src/main/java/com/fjhx/email/entity/EnterpriseDomain.java

@@ -0,0 +1,80 @@
+package com.fjhx.email.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fjhx.email.config.base.BaseEntity;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 企业邮箱域名
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+@Getter
+@Setter
+@TableName("enterprise_domain")
+public class EnterpriseDomain extends BaseEntity {
+
+    /**
+     * 域名
+     */
+    private String domanName;
+
+    /**
+     * 类型:1国内 2国外
+     */
+    private Byte type;
+
+    /**
+     * 收件host
+     */
+    private String receiveHost;
+
+    /**
+     * 收件端口
+     */
+    private Byte receivePort;
+
+    /**
+     * 收件协议
+     */
+    private String receiveProtocol;
+
+    /**
+     * 发件host
+     */
+    private String sendHost;
+
+    /**
+     * 发件端口
+     */
+    private Byte sendPort;
+
+    /**
+     * 发件协议
+     */
+    private String sendProtocol;
+
+    /**
+     * 租户ID
+     */
+    private String tenantId;
+
+    /**
+     * 创建人id
+     */
+    private Long createUser;
+
+    /**
+     * 修改人id
+     */
+    private Long updateUser;
+
+    /**
+     * 逻辑删除 0未删除 1已删除
+     */
+    private Byte delFlag;
+}

+ 48 - 0
src/main/java/com/fjhx/email/entity/EnterpriseFolder.java

@@ -0,0 +1,48 @@
+package com.fjhx.email.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fjhx.email.config.base.BaseEntity;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 企业邮箱文件夹
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+@Getter
+@Setter
+@TableName("enterprise_folder")
+public class EnterpriseFolder extends BaseEntity {
+
+    /**
+     * 邮箱id
+     */
+    private String mailboxId;
+
+    /**
+     * 文件夹名称
+     */
+    private String name;
+
+    /**
+     * 上次同步邮件number
+     */
+    private Integer lastMessageNumber;
+
+    /**
+     * 上次同步邮件发送时间
+     */
+    private Date lastReceivedDate;
+
+    /**
+     * 同步邮件状态: 1同步 0不同步
+     */
+    private Integer syncStatus;
+}

+ 70 - 0
src/main/java/com/fjhx/email/entity/EnterpriseMailbox.java

@@ -0,0 +1,70 @@
+package com.fjhx.email.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fjhx.email.config.base.BaseEntity;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 企业邮箱
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+@Getter
+@Setter
+@TableName("enterprise_mailbox")
+public class EnterpriseMailbox extends BaseEntity {
+
+    /**
+     * 企业邮箱域名id
+     */
+    private Long domainId;
+
+    /**
+     * mail账号前缀
+     */
+    private String mailUserPrefix;
+
+    /**
+     * mail授权码
+     */
+    private String mailPassword;
+
+    /**
+     * 同步邮件状态: 1同步 0不同步
+     */
+    private Byte syncStatus;
+
+    /**
+     * 默认邮箱: 1默认 0非默认
+     */
+    private Byte defaultStatus;
+
+    /**
+     * 用户id
+     */
+    private Long userId;
+
+    /**
+     * 租户ID
+     */
+    private String tenantId;
+
+    /**
+     * 创建人id
+     */
+    private Long createUser;
+
+    /**
+     * 修改人id
+     */
+    private Long updateUser;
+
+    /**
+     * 逻辑删除 0未删除 1已删除
+     */
+    private Byte delFlag;
+}

+ 92 - 0
src/main/java/com/fjhx/email/entity/EnterpriseMessage.java

@@ -0,0 +1,92 @@
+package com.fjhx.email.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fjhx.email.config.base.BaseEntity;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 企业邮件
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+@Getter
+@Setter
+@TableName("enterprise_message")
+public class EnterpriseMessage extends BaseEntity {
+
+    /**
+     * 邮箱id
+     */
+    private Long mailboxId;
+
+    /**
+     * 文件夹id
+     */
+    private Long folderId;
+
+    /**
+     * 文件夹名称
+     */
+    private String folderName;
+
+    /**
+     * 邮件id
+     */
+    private String messageId;
+
+    /**
+     * 消息数量
+     */
+    private Integer messageNumber;
+
+    /**
+     * 邮件标题
+     */
+    private String subject;
+
+    /**
+     * 邮件标记
+     */
+    private String flags;
+
+    /**
+     * 发件人email
+     */
+    private String fromEmail;
+
+    /**
+     * 发件人名称
+     */
+    private String fromPersonalName;
+
+    /**
+     * 发件类型
+     */
+    private String fromType;
+
+    /**
+     * 发件时间
+     */
+    private Date sendDate;
+
+    /**
+     * 是否同步正文
+     */
+    private Integer contentSync;
+
+    /**
+     * 是否同步地址信息
+     */
+    private Integer addressSync;
+
+    /**
+     * 是否同步附件
+     */
+    private Integer attachmentSync;
+}

+ 48 - 0
src/main/java/com/fjhx/email/entity/PersonalFolder.java

@@ -0,0 +1,48 @@
+package com.fjhx.email.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fjhx.email.config.base.BaseEntity;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 个人邮箱文件夹
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+@Getter
+@Setter
+@TableName("personal_folder")
+public class PersonalFolder extends BaseEntity {
+
+    /**
+     * 邮箱id
+     */
+    private String mailboxId;
+
+    /**
+     * 文件夹名称
+     */
+    private String name;
+
+    /**
+     * 上次同步邮件id
+     */
+    private Integer lastMessageNumber;
+
+    /**
+     * 上次同步邮件发送时间
+     */
+    private Date lastReceivedDate;
+
+    /**
+     * 同步邮件状态: 1同步 0不同步
+     */
+    private Integer syncStatus;
+
+}

+ 101 - 0
src/main/java/com/fjhx/email/entity/PersonalMailbox.java

@@ -0,0 +1,101 @@
+package com.fjhx.email.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fjhx.email.config.base.BaseEntity;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 个人邮箱
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-04
+ */
+@Getter
+@Setter
+@TableName("personal_mailbox")
+public class PersonalMailbox extends BaseEntity {
+
+    /**
+     * mail账号
+     */
+    private String mailUser;
+
+    /**
+     * mail授权码
+     */
+    private String mailPassword;
+
+    /**
+     * 状态:1启用 0禁用
+     */
+    private Integer status;
+
+    /**
+     * 同步邮件状态: 1同步 0不同步
+     */
+    private Integer syncStatus;
+
+    /**
+     * 默认邮箱: 1默认 0非默认
+     */
+    private Integer defaultStatus;
+
+    /**
+     * 收件host
+     */
+    private String receiveHost;
+
+    /**
+     * 收件端口
+     */
+    private Integer receivePort;
+
+    /**
+     * 收件协议
+     */
+    private String receiveProtocol;
+
+    /**
+     * 发件host
+     */
+    private String sendHost;
+
+    /**
+     * 发件端口
+     */
+    private Integer sendPort;
+
+    /**
+     * 发件协议
+     */
+    private String sendProtocol;
+
+    /**
+     * 用户id
+     */
+    private Long userId;
+
+    /**
+     * 租户ID
+     */
+    private String tenantId;
+
+    /**
+     * 创建人id
+     */
+    private Long createUser;
+
+    /**
+     * 修改人id
+     */
+    private Long updateUser;
+
+    /**
+     * 逻辑删除 0未删除 1已删除
+     */
+    private Integer delFlag;
+
+}

+ 93 - 0
src/main/java/com/fjhx/email/entity/PersonalMessage.java

@@ -0,0 +1,93 @@
+package com.fjhx.email.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fjhx.email.config.base.BaseEntity;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 个人邮箱
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+@Getter
+@Setter
+@TableName("personal_message")
+public class PersonalMessage extends BaseEntity {
+
+    /**
+     * 邮箱id
+     */
+    private Long mailboxId;
+
+    /**
+     * 文件夹id
+     */
+    private Long folderId;
+
+    /**
+     * 文件夹名称
+     */
+    private String folderName;
+
+    /**
+     * 邮件id
+     */
+    private String messageId;
+
+    /**
+     * 消息数量
+     */
+    private Integer messageNumber;
+
+    /**
+     * 邮件标题
+     */
+    private String subject;
+
+    /**
+     * 邮件标记
+     */
+    private String flags;
+
+    /**
+     * 发件人email
+     */
+    private String fromEmail;
+
+    /**
+     * 发件人名称
+     */
+    private String fromPersonalName;
+
+    /**
+     * 发件类型
+     */
+    private String fromType;
+
+    /**
+     * 发件时间
+     */
+    private Date sendDate;
+
+    /**
+     * 是否同步正文
+     */
+    private Integer contentSync;
+
+    /**
+     * 是否同步地址信息
+     */
+    private Integer addressSync;
+
+    /**
+     * 是否同步附件
+     */
+    private Integer attachmentSync;
+
+}

+ 37 - 0
src/main/java/com/fjhx/email/entity/dto/MailFolderInfo.java

@@ -0,0 +1,37 @@
+package com.fjhx.email.entity.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+@Getter
+@Setter
+public class MailFolderInfo {
+
+    /**
+     * 文件夹id
+     */
+    private Long id;
+
+    /**
+     * 文件夹名称
+     */
+    private String name;
+
+    /**
+     * 是否跳过
+     */
+    private Boolean skip;
+
+    /**
+     * 上次获取邮件编号
+     */
+    private Integer lastMessageNumber;
+
+    /**
+     * 上次获取邮件时间
+     */
+    private Date lastReceivedDate;
+
+}

+ 52 - 0
src/main/java/com/fjhx/email/entity/dto/MailInfo.java

@@ -0,0 +1,52 @@
+package com.fjhx.email.entity.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+@Getter
+@Setter
+public class MailInfo {
+
+    /**
+     * 邮件id
+     */
+    private String messageId;
+
+    /**
+     * 邮件编号
+     */
+    private Integer messageNumber;
+
+    /**
+     * 邮件标题
+     */
+    private String subject;
+
+    /**
+     * 邮件标签
+     */
+    private String flags;
+
+    /**
+     * 邮件发送时间
+     */
+    private Date sendDate;
+
+    /**
+     * 发送邮件
+     */
+    private String fromEmail;
+
+    /**
+     * 发件人名称
+     */
+    private String fromPersonalName;
+
+    /**
+     * 发件类型
+     */
+    private String fromType;
+
+}

+ 67 - 0
src/main/java/com/fjhx/email/entity/dto/MailSyncInfo.java

@@ -0,0 +1,67 @@
+package com.fjhx.email.entity.dto;
+
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+public class MailSyncInfo {
+
+    /**
+     * 至少要等待多久才会开启下一轮邮件同步
+     */
+    public static Long minWaitingTime;
+
+    /**
+     * 初始化同步天数
+     */
+    public static Integer initDay;
+
+    /**
+     * 多少分钟没同步完成则开启下一轮同步
+     */
+    public static Integer awaitTimeout;
+
+    /**
+     * 超过多少次后将不再同步此邮箱
+     */
+    public static Integer errorNumber;
+
+    /**
+     * 类型:1国内 2国外
+     */
+    public static Integer mailType;
+
+    /**
+     * 需要同步的邮箱账号
+     */
+    public static List<MailboxInfo> mailboxInfoList;
+
+    @Value("${mail.minWaitingTime}")
+    public static void setMinWaitingTime(Long minWaitingTime) {
+        MailSyncInfo.minWaitingTime = minWaitingTime * 1000;
+    }
+
+    @Value("${mail.initDay}")
+    public static void setInitDay(Integer initDay) {
+        MailSyncInfo.initDay = initDay;
+    }
+
+    @Value("${mail.awaitTimeout}")
+    public static void setAwaitTimeout(Integer awaitTimeout) {
+        MailSyncInfo.awaitTimeout = awaitTimeout;
+    }
+
+    @Value("${mail.errorNumber}")
+    public static void setErrorNumber(Integer errorNumber) {
+        MailSyncInfo.errorNumber = errorNumber;
+    }
+
+    @Value("${mail.mailType}")
+    public static void setMailType(Integer mailType) {
+        MailSyncInfo.mailType = mailType;
+    }
+
+}

+ 59 - 0
src/main/java/com/fjhx/email/entity/dto/MailboxInfo.java

@@ -0,0 +1,59 @@
+package com.fjhx.email.entity.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+public class MailboxInfo {
+
+    /**
+     * 类型
+     * 1、个人邮箱
+     * 2、企业邮箱
+     */
+    private Integer type;
+
+    /**
+     * 是否跳过
+     */
+    private Boolean skip;
+
+    /**
+     * id
+     */
+    private Long id;
+
+    /**
+     * mail账号
+     */
+    private String mailUser;
+
+    /**
+     * mail授权码
+     */
+    private String mailPassword;
+
+    /**
+     * 收件host
+     */
+    private String receiveHost;
+
+    /**
+     * 收件端口
+     */
+    private Integer receivePort;
+
+    /**
+     * 收件协议
+     */
+    private String receiveProtocol;
+
+    /**
+     * 文件夹
+     */
+    private List<MailFolderInfo> mailFolderInfoList;
+
+}

+ 20 - 0
src/main/java/com/fjhx/email/entity/dto/ObsFile.java

@@ -0,0 +1,20 @@
+package com.fjhx.email.entity.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class ObsFile {
+
+    /**
+     * 文件名称
+     */
+    private String fileName;
+
+    /**
+     * 文件路径
+     */
+    private String fileUrl;
+
+}

+ 59 - 0
src/main/java/com/fjhx/email/entity/dto/SendDto.java

@@ -0,0 +1,59 @@
+package com.fjhx.email.entity.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+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<ObsFile> fileList;
+
+    @Getter
+    @Setter
+    public static class Address {
+        private String address;
+        private String personal;
+    }
+
+}

+ 39 - 0
src/main/java/com/fjhx/email/enums/MailFlagEnum.java

@@ -0,0 +1,39 @@
+package com.fjhx.email.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import javax.mail.Flags;
+import java.util.HashMap;
+import java.util.Map;
+
+
+@Getter
+@AllArgsConstructor
+public enum MailFlagEnum {
+
+    ANSWERED("1", Flags.Flag.ANSWERED),
+    DELETED("2", Flags.Flag.DELETED),
+    DRAFT("3", Flags.Flag.DRAFT),
+    FLAGGED("4", Flags.Flag.FLAGGED),
+    RECENT("5", Flags.Flag.RECENT),
+    SEEN("6", Flags.Flag.SEEN),
+    USER("7", Flags.Flag.USER),
+    ;
+
+    private final String type;
+    private final Flags.Flag flag;
+
+    private static final Map<Flags.Flag, MailFlagEnum> map = new HashMap<>();
+
+    static {
+        for (MailFlagEnum value : MailFlagEnum.values()) {
+            map.put(value.getFlag(), value);
+        }
+    }
+
+    public static String getType(Flags.Flag flag) {
+        return map.get(flag).getType();
+    }
+
+}

+ 16 - 0
src/main/java/com/fjhx/email/mapper/EnterpriseDomainMapper.java

@@ -0,0 +1,16 @@
+package com.fjhx.email.mapper;
+
+import com.fjhx.email.entity.EnterpriseDomain;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 企业邮箱域名 Mapper 接口
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+public interface EnterpriseDomainMapper extends BaseMapper<EnterpriseDomain> {
+
+}

+ 16 - 0
src/main/java/com/fjhx/email/mapper/EnterpriseFolderMapper.java

@@ -0,0 +1,16 @@
+package com.fjhx.email.mapper;
+
+import com.fjhx.email.entity.EnterpriseFolder;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 企业邮箱文件夹 Mapper 接口
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+public interface EnterpriseFolderMapper extends BaseMapper<EnterpriseFolder> {
+
+}

+ 16 - 0
src/main/java/com/fjhx/email/mapper/EnterpriseMailboxMapper.java

@@ -0,0 +1,16 @@
+package com.fjhx.email.mapper;
+
+import com.fjhx.email.entity.EnterpriseMailbox;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 企业邮箱 Mapper 接口
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+public interface EnterpriseMailboxMapper extends BaseMapper<EnterpriseMailbox> {
+
+}

+ 16 - 0
src/main/java/com/fjhx/email/mapper/EnterpriseMessageMapper.java

@@ -0,0 +1,16 @@
+package com.fjhx.email.mapper;
+
+import com.fjhx.email.entity.EnterpriseMessage;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 企业邮件 Mapper 接口
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+public interface EnterpriseMessageMapper extends BaseMapper<EnterpriseMessage> {
+
+}

+ 16 - 0
src/main/java/com/fjhx/email/mapper/PersonalFolderMapper.java

@@ -0,0 +1,16 @@
+package com.fjhx.email.mapper;
+
+import com.fjhx.email.entity.PersonalFolder;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 个人邮箱文件夹 Mapper 接口
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+public interface PersonalFolderMapper extends BaseMapper<PersonalFolder> {
+
+}

+ 16 - 0
src/main/java/com/fjhx/email/mapper/PersonalMailboxMapper.java

@@ -0,0 +1,16 @@
+package com.fjhx.email.mapper;
+
+import com.fjhx.email.entity.PersonalMailbox;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 个人邮箱 Mapper 接口
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-04
+ */
+public interface PersonalMailboxMapper extends BaseMapper<PersonalMailbox> {
+
+}

+ 16 - 0
src/main/java/com/fjhx/email/mapper/PersonalMessageMapper.java

@@ -0,0 +1,16 @@
+package com.fjhx.email.mapper;
+
+import com.fjhx.email.entity.PersonalMessage;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 个人邮箱 Mapper 接口
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+public interface PersonalMessageMapper extends BaseMapper<PersonalMessage> {
+
+}

+ 5 - 0
src/main/java/com/fjhx/email/mapper/xml/EnterpriseDomainMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.email.mapper.EnterpriseDomainMapper">
+
+</mapper>

+ 5 - 0
src/main/java/com/fjhx/email/mapper/xml/EnterpriseFolderMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.email.mapper.EnterpriseFolderMapper">
+
+</mapper>

+ 5 - 0
src/main/java/com/fjhx/email/mapper/xml/EnterpriseMailboxMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.email.mapper.EnterpriseMailboxMapper">
+
+</mapper>

+ 5 - 0
src/main/java/com/fjhx/email/mapper/xml/EnterpriseMessageMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.email.mapper.EnterpriseMessageMapper">
+
+</mapper>

+ 5 - 0
src/main/java/com/fjhx/email/mapper/xml/PersonalFolderMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.email.mapper.PersonalFolderMapper">
+
+</mapper>

+ 5 - 0
src/main/java/com/fjhx/email/mapper/xml/PersonalMailboxMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.email.mapper.PersonalMailboxMapper">
+
+</mapper>

+ 5 - 0
src/main/java/com/fjhx/email/mapper/xml/PersonalMessageMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.email.mapper.PersonalMessageMapper">
+
+</mapper>

+ 16 - 0
src/main/java/com/fjhx/email/service/IEnterpriseDomainService.java

@@ -0,0 +1,16 @@
+package com.fjhx.email.service;
+
+import com.fjhx.email.entity.EnterpriseDomain;
+import com.fjhx.email.config.base.BaseService;
+
+/**
+ * <p>
+ * 企业邮箱域名 服务类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+public interface IEnterpriseDomainService extends BaseService<EnterpriseDomain> {
+
+}

+ 16 - 0
src/main/java/com/fjhx/email/service/IEnterpriseFolderService.java

@@ -0,0 +1,16 @@
+package com.fjhx.email.service;
+
+import com.fjhx.email.entity.EnterpriseFolder;
+import com.fjhx.email.config.base.BaseService;
+
+/**
+ * <p>
+ * 企业邮箱文件夹 服务类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+public interface IEnterpriseFolderService extends BaseService<EnterpriseFolder> {
+
+}

+ 16 - 0
src/main/java/com/fjhx/email/service/IEnterpriseMailboxService.java

@@ -0,0 +1,16 @@
+package com.fjhx.email.service;
+
+import com.fjhx.email.entity.EnterpriseMailbox;
+import com.fjhx.email.config.base.BaseService;
+
+/**
+ * <p>
+ * 企业邮箱 服务类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+public interface IEnterpriseMailboxService extends BaseService<EnterpriseMailbox> {
+
+}

+ 16 - 0
src/main/java/com/fjhx/email/service/IEnterpriseMessageService.java

@@ -0,0 +1,16 @@
+package com.fjhx.email.service;
+
+import com.fjhx.email.entity.EnterpriseMessage;
+import com.fjhx.email.config.base.BaseService;
+
+/**
+ * <p>
+ * 企业邮件 服务类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+public interface IEnterpriseMessageService extends BaseService<EnterpriseMessage> {
+
+}

+ 16 - 0
src/main/java/com/fjhx/email/service/IPersonalFolderService.java

@@ -0,0 +1,16 @@
+package com.fjhx.email.service;
+
+import com.fjhx.email.entity.PersonalFolder;
+import com.fjhx.email.config.base.BaseService;
+
+/**
+ * <p>
+ * 个人邮箱文件夹 服务类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+public interface IPersonalFolderService extends BaseService<PersonalFolder> {
+
+}

+ 16 - 0
src/main/java/com/fjhx/email/service/IPersonalMailboxService.java

@@ -0,0 +1,16 @@
+package com.fjhx.email.service;
+
+import com.fjhx.email.entity.PersonalMailbox;
+import com.fjhx.email.config.base.BaseService;
+
+/**
+ * <p>
+ * 个人邮箱 服务类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-04
+ */
+public interface IPersonalMailboxService extends BaseService<PersonalMailbox> {
+
+}

+ 16 - 0
src/main/java/com/fjhx/email/service/IPersonalMessageService.java

@@ -0,0 +1,16 @@
+package com.fjhx.email.service;
+
+import com.fjhx.email.config.base.BaseService;
+import com.fjhx.email.entity.PersonalMessage;
+
+/**
+ * <p>
+ * 个人邮箱 服务类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+public interface IPersonalMessageService extends BaseService<PersonalMessage> {
+
+}

+ 471 - 0
src/main/java/com/fjhx/email/service/impl/CoreServiceImpl.java

@@ -0,0 +1,471 @@
+package com.fjhx.email.service.impl;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.thread.ThreadUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson2.JSON;
+import com.fjhx.email.config.TaskPoolConfig;
+import com.fjhx.email.config.base.BaseEntity;
+import com.fjhx.email.entity.*;
+import com.fjhx.email.entity.dto.MailFolderInfo;
+import com.fjhx.email.entity.dto.MailInfo;
+import com.fjhx.email.entity.dto.MailSyncInfo;
+import com.fjhx.email.entity.dto.MailboxInfo;
+import com.fjhx.email.service.*;
+import com.fjhx.email.utils.EmailUtil;
+import com.sun.mail.imap.IMAPMessage;
+import com.sun.mail.imap.IMAPStore;
+import com.sun.mail.util.MailConnectException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+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.InternetAddress;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class CoreServiceImpl implements ApplicationRunner {
+
+    @Autowired
+    private PlatformTransactionManager platformTransactionManager;
+
+    @Autowired
+    private TransactionDefinition transactionDefinition;
+
+    @Autowired
+    @Qualifier(TaskPoolConfig.emailInfoTaskExecutor)
+    private Executor emailTaskExecutor;
+
+    @Autowired
+    private IPersonalMailboxService personalMailboxService;
+
+    @Autowired
+    private IPersonalFolderService personalFolderService;
+
+    @Autowired
+    private IPersonalMessageService personalMessageService;
+
+    @Autowired
+    private IEnterpriseMailboxService enterpriseMailboxService;
+
+    @Autowired
+    private IEnterpriseFolderService enterpriseFolderService;
+
+    @Autowired
+    private IEnterpriseMessageService enterpriseMessageService;
+
+    /**
+     * 累计同步次数
+     */
+    private static int num = 0;
+
+    /**
+     * 单次同步邮件总次数
+     */
+    private static int mailCount;
+
+    /**
+     * 缓存错误次数
+     */
+    private static final Map<Long, Integer> map = new ConcurrentHashMap<>();
+
+    /**
+     * 正在同步的邮箱集合
+     */
+    private static final List<Long> syncMailList = Collections.synchronizedList(new ArrayList<>());
+
+    @Override
+    public void run(ApplicationArguments args) {
+
+
+
+        // 发起邮件同步
+        new Thread(this::monitorMail).start();
+    }
+
+    /**
+     * 邮件同步
+     */
+    public void monitorMail() {
+        try {
+            doMonitorMail();
+        } catch (Exception e) {
+            log.error("未知异常", e);
+        }
+        new Thread(this::monitorMail).start();
+    }
+
+    /**
+     * 执行邮件同步逻辑
+     */
+    private void doMonitorMail() {
+
+        // 所有需要同步的邮件
+        List<MailboxInfo> mailboxInfoList = new ArrayList<>(MailSyncInfo.mailboxInfoList);
+        int mailboxSize = mailboxInfoList.size();
+
+        // 开始处理时间
+        long start = System.currentTimeMillis();
+
+        // 清空抓取邮件数
+        mailCount = 0;
+
+        // 累计同步次数
+        num++;
+
+        // log.info("开始第 {} 伦邮件同步,共同步 {} 个邮箱", num, mailboxSize);
+
+        // 定义一个线程计数器
+        CountDownLatch countDownLatch = new CountDownLatch(mailboxSize);
+
+        // 开启抓取邮件任务
+        for (MailboxInfo mailbox : mailboxInfoList) {
+
+            // 开启异步操作
+            emailTaskExecutor.execute(() -> {
+                try {
+                    synchronousMail(mailbox);
+                } catch (Exception e) {
+                    log.error("发生未知异常", e);
+                }
+                countDownLatch.countDown();
+            });
+
+        }
+
+        try {
+            boolean awaitFlag = countDownLatch.await(5, TimeUnit.MINUTES);
+            if (!awaitFlag) {
+                log.error("超时执行");
+            }
+        } catch (InterruptedException e) {
+            log.error("countDownLatch.await() 发生异常", e);
+        }
+
+        // 结束处理时间
+        long end = System.currentTimeMillis();
+
+        // 处理时间
+        long handleTime = end - start;
+
+        log.info("第 {} 伦邮件同步完成,共同步 {} 个邮箱,{} 封邮件,总耗时 {}", num, mailboxSize, mailCount, DateUtil.formatBetween(handleTime));
+
+        // 处理时间是否小于最小处理时间
+        if (MailSyncInfo.minWaitingTime > handleTime) {
+            ThreadUtil.sleep(MailSyncInfo.minWaitingTime - handleTime);
+        }
+
+    }
+
+    /**
+     * 同步邮箱
+     */
+    private void synchronousMail(MailboxInfo mailboxInfo) {
+
+        Long id = mailboxInfo.getId();
+
+        if (mailboxInfo.getSkip()) {
+            return;
+        }
+
+        if (syncMailList.contains(id)) {
+            log.error("邮箱 {} 同步超时:{}", mailboxInfo.getMailUser(), JSON.toJSONString(mailboxInfo));
+            return;
+        }
+
+        // 开始同步,添加id
+        syncMailList.add(id);
+
+        IMAPStore store = null;
+
+        try {
+
+            // 获取邮件连接
+            store = EmailUtil.getIMAPStore(mailboxInfo);
+
+            List<MailFolderInfo> mailFolderInfoList = mailboxInfo.getMailFolderInfoList();
+
+            // 分别拉取每个文件夹邮件
+            for (MailFolderInfo mailFolder : mailFolderInfoList) {
+
+                // 是否跳过文件夹抓取
+                if (mailFolder.getSkip()) {
+                    continue;
+                }
+
+                Folder folder = store.getFolder(mailFolder.getName());
+
+                try {
+                    // 只读方式打开收件箱
+                    folder.open(Folder.READ_ONLY);
+                } catch (FolderNotFoundException folderNotFoundException) {
+                    mailFolder.setSkip(true);
+                    continue;
+                }
+
+                try {
+                    // 获取文件夹邮件
+                    Message[] messages = folder.getMessages();
+                    if (messages.length == 0) {
+                        continue;
+                    }
+
+                    // 如果邮件最后一封和最后一次同步id相同,则代表没有新邮件
+                    IMAPMessage message = (IMAPMessage) messages[messages.length - 1];
+                    int messageNumber = message.getMessageNumber();
+                    Date receivedDate = message.getReceivedDate();
+
+                    if (Objects.equals(messageNumber, mailFolder.getLastMessageNumber())) {
+                        continue;
+                    }
+
+                    // 拉取邮件
+                    List<MailInfo> mailInfoList = getMailInfoList(mailFolder, messages);
+
+                    Integer lastMessageNumber = mailFolder.getLastMessageNumber();
+                    Date lastReceivedDate = mailFolder.getLastReceivedDate();
+
+                    // 保存最后一份邮件id与收件时间
+                    mailFolder.setLastMessageNumber(messageNumber);
+                    mailFolder.setLastReceivedDate(receivedDate);
+
+                    try {
+                        saveMailInfo(mailboxInfo, mailFolder, mailInfoList);
+                    } catch (Exception e) {
+                        // 回滚
+                        mailFolder.setLastMessageNumber(lastMessageNumber);
+                        mailFolder.setLastReceivedDate(lastReceivedDate);
+                    }
+
+                } finally {
+                    if (folder.isOpen()) {
+                        folder.close();
+                    }
+                }
+            }
+
+            // 删除错误次数
+            map.remove(id);
+
+        } catch (AuthenticationFailedException | MailConnectException exception) {
+
+            // 添加异常次数
+            map.merge(id, 1, Integer::sum);
+
+            // 异常次数连续超过3次,不再同步邮件
+            if (map.get(id) >= MailSyncInfo.errorNumber) {
+                mailboxInfo.setSkip(true);
+                map.remove(id);
+            }
+
+        } catch (Exception e) {
+
+            log.error("邮件同步出错,邮箱信息:{}", JSON.toJSONString(mailboxInfo));
+            e.printStackTrace();
+
+        } finally {
+
+            // 同步完成,删除id
+            syncMailList.remove(id);
+
+            if (store != null) {
+                try {
+                    if (store.isConnected()) {
+                        store.close();
+                    }
+                } catch (MessagingException e) {
+                    log.error("store关闭失败", e);
+                }
+            }
+
+        }
+    }
+
+    /**
+     * 拉取邮件
+     */
+    private List<MailInfo> getMailInfoList(MailFolderInfo mailFolder, Message[] messages) throws MessagingException {
+
+        // 获取最后一次发件id
+        Integer lastMessageNumber = mailFolder.getLastMessageNumber();
+        // 获取最后一次收件的发送时间
+        Date lastReceivedDate = mailFolder.getLastReceivedDate();
+        // 同步时间
+        DateTime date = DateUtil.offsetDay(new Date(), -MailSyncInfo.initDay);
+        // 最多只同步 initDay 天数据
+        if (lastReceivedDate == null || lastReceivedDate.before(date)) {
+            lastReceivedDate = date;
+        }
+
+        // 收件列表
+        List<MailInfo> mailInfoList = new ArrayList<>();
+
+        int length = messages.length;
+        for (int i = length - 1; i >= 0; i--) {
+            IMAPMessage message = (IMAPMessage) messages[i];
+            // 邮件发送时间
+            Date receivedDate = message.getReceivedDate();
+            int messageNumber = message.getMessageNumber();
+            // 邮件id
+            String messageID = message.getMessageID();
+
+            // 最后一封邮件id相同,代表上次同步邮件到这,不继续找之前的邮件了
+            if (ObjectUtil.isNotEmpty(lastMessageNumber)) {
+                if (lastMessageNumber.equals(messageNumber)) {
+                    break;
+                }
+            }
+            // 收件时间在上次收件时间之前,不继续找之前的邮件了
+            if (receivedDate.before(lastReceivedDate) || receivedDate.equals(lastReceivedDate)) {
+                break;
+            }
+
+            // 邮件信息
+            MailInfo mailInfo = new MailInfo();
+            mailInfo.setMessageId(messageID);
+            mailInfo.setMessageNumber(messageNumber);
+            mailInfo.setSubject(message.getSubject());
+            mailInfo.setFlags(EmailUtil.getFlags(message.getFlags()));
+            mailInfo.setSendDate(receivedDate);
+
+            // 保存发件人信息
+            Address[] addresses = message.getFrom();
+            if (addresses != null && addresses.length > 0) {
+                InternetAddress internetAddress = (InternetAddress) addresses[0];
+                mailInfo.setFromEmail(internetAddress.getAddress());
+                mailInfo.setFromPersonalName(internetAddress.getPersonal());
+                mailInfo.setFromType("from");
+            } else {
+                InternetAddress sender = (InternetAddress) message.getSender();
+                if (sender != null) {
+                    mailInfo.setFromEmail(sender.getAddress());
+                    mailInfo.setFromPersonalName(sender.getPersonal());
+                    mailInfo.setFromType("sender");
+                }
+            }
+
+            // 添加到邮件列表
+            mailInfoList.add(0, mailInfo);
+
+            // 添加同步邮件总次数
+            addMailCount();
+        }
+
+        return mailInfoList;
+    }
+
+    /**
+     * 保存邮件数据,更新文件夹最后同步邮件时间
+     */
+    private void saveMailInfo(MailboxInfo mailboxInfo, MailFolderInfo mailFolder, List<MailInfo> mailInfoList) {
+        TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
+        try {
+
+            // 个人邮箱
+            if (mailboxInfo.getType() == 1) {
+
+                // 邮箱是否同步
+                if (mailboxInfo.getSkip()) {
+                    personalMailboxService.update(q -> q.eq(BaseEntity::getId, mailboxInfo.getId()).set(PersonalMailbox::getSyncStatus, mailboxInfo.getSkip() ? 0 : 1).set(BaseEntity::getUpdateTime, new Date()));
+                }
+
+                PersonalFolder personalFolder = new PersonalFolder();
+                personalFolder.setId(mailFolder.getId());
+                personalFolder.setLastMessageNumber(mailFolder.getLastMessageNumber());
+                personalFolder.setLastReceivedDate(mailFolder.getLastReceivedDate());
+                personalFolder.setSyncStatus(mailFolder.getSkip() ? 0 : 1);
+                personalFolderService.updateById(personalFolder);
+
+                if (mailInfoList.size() > 0) {
+                    List<PersonalMessage> personalMessageList = mailInfoList.stream().map(mailInfo -> {
+                        PersonalMessage personalMessage = new PersonalMessage();
+                        personalMessage.setMailboxId(mailboxInfo.getId());
+                        personalMessage.setFolderId(mailFolder.getId());
+                        personalMessage.setFolderName(mailFolder.getName());
+                        personalMessage.setMessageId(mailInfo.getMessageId());
+                        personalMessage.setMessageNumber(mailInfo.getMessageNumber());
+                        personalMessage.setSubject(mailInfo.getSubject());
+                        personalMessage.setFlags(mailInfo.getFlags());
+                        personalMessage.setFromEmail(mailInfo.getFromEmail());
+                        personalMessage.setFromPersonalName(mailInfo.getFromPersonalName());
+                        personalMessage.setFromType(mailInfo.getFromType());
+                        personalMessage.setSendDate(mailInfo.getSendDate());
+                        personalMessage.setContentSync(0);
+                        personalMessage.setAddressSync(0);
+                        personalMessage.setAddressSync(0);
+                        return personalMessage;
+                    }).collect(Collectors.toList());
+                    personalMessageService.saveBatch(personalMessageList);
+                }
+
+            }
+            // 企业邮箱
+            else {
+
+                // 邮箱是否同步
+                if (mailboxInfo.getSkip()) {
+                    enterpriseMailboxService.update(q -> q.eq(BaseEntity::getId, mailboxInfo.getId()).set(EnterpriseMailbox::getSyncStatus, mailboxInfo.getSkip() ? 0 : 1).set(BaseEntity::getUpdateTime, new Date()));
+                }
+
+                EnterpriseFolder enterpriseFolder = new EnterpriseFolder();
+                enterpriseFolder.setId(mailFolder.getId());
+                enterpriseFolder.setLastMessageNumber(mailFolder.getLastMessageNumber());
+                enterpriseFolder.setLastReceivedDate(mailFolder.getLastReceivedDate());
+                enterpriseFolder.setSyncStatus(mailFolder.getSkip() ? 0 : 1);
+                enterpriseFolderService.updateById(enterpriseFolder);
+
+                if (mailInfoList.size() > 0) {
+                    List<EnterpriseMessage> enterpriseMessageList = mailInfoList.stream().map(mailInfo -> {
+                        EnterpriseMessage enterpriseMessage = new EnterpriseMessage();
+                        enterpriseMessage.setMailboxId(mailboxInfo.getId());
+                        enterpriseMessage.setFolderId(mailFolder.getId());
+                        enterpriseMessage.setFolderName(mailFolder.getName());
+                        enterpriseMessage.setMessageId(mailInfo.getMessageId());
+                        enterpriseMessage.setMessageNumber(mailInfo.getMessageNumber());
+                        enterpriseMessage.setSubject(mailInfo.getSubject());
+                        enterpriseMessage.setFlags(mailInfo.getFlags());
+                        enterpriseMessage.setFromEmail(mailInfo.getFromEmail());
+                        enterpriseMessage.setFromPersonalName(mailInfo.getFromPersonalName());
+                        enterpriseMessage.setFromType(mailInfo.getFromType());
+                        enterpriseMessage.setSendDate(mailInfo.getSendDate());
+                        enterpriseMessage.setContentSync(0);
+                        enterpriseMessage.setAddressSync(0);
+                        enterpriseMessage.setAddressSync(0);
+                        return enterpriseMessage;
+                    }).collect(Collectors.toList());
+                    enterpriseMessageService.saveBatch(enterpriseMessageList);
+                }
+
+            }
+
+            // 提交事务
+            platformTransactionManager.commit(transactionStatus);
+        } catch (Exception e) {
+            // 回滚事务
+            platformTransactionManager.rollback(transactionStatus);
+            throw new RuntimeException("保存数据失败");
+        }
+    }
+
+    /**
+     * 添加同步邮件数量
+     */
+    private static synchronized void addMailCount() {
+        mailCount++;
+    }
+
+}

+ 20 - 0
src/main/java/com/fjhx/email/service/impl/EnterpriseDomainServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fjhx.email.service.impl;
+
+import com.fjhx.email.entity.EnterpriseDomain;
+import com.fjhx.email.mapper.EnterpriseDomainMapper;
+import com.fjhx.email.service.IEnterpriseDomainService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 企业邮箱域名 服务实现类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+@Service
+public class EnterpriseDomainServiceImpl extends ServiceImpl<EnterpriseDomainMapper, EnterpriseDomain> implements IEnterpriseDomainService {
+
+}

+ 20 - 0
src/main/java/com/fjhx/email/service/impl/EnterpriseFolderServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fjhx.email.service.impl;
+
+import com.fjhx.email.entity.EnterpriseFolder;
+import com.fjhx.email.mapper.EnterpriseFolderMapper;
+import com.fjhx.email.service.IEnterpriseFolderService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 企业邮箱文件夹 服务实现类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+@Service
+public class EnterpriseFolderServiceImpl extends ServiceImpl<EnterpriseFolderMapper, EnterpriseFolder> implements IEnterpriseFolderService {
+
+}

+ 20 - 0
src/main/java/com/fjhx/email/service/impl/EnterpriseMailboxServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fjhx.email.service.impl;
+
+import com.fjhx.email.entity.EnterpriseMailbox;
+import com.fjhx.email.mapper.EnterpriseMailboxMapper;
+import com.fjhx.email.service.IEnterpriseMailboxService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 企业邮箱 服务实现类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+@Service
+public class EnterpriseMailboxServiceImpl extends ServiceImpl<EnterpriseMailboxMapper, EnterpriseMailbox> implements IEnterpriseMailboxService {
+
+}

+ 20 - 0
src/main/java/com/fjhx/email/service/impl/EnterpriseMessageServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fjhx.email.service.impl;
+
+import com.fjhx.email.entity.EnterpriseMessage;
+import com.fjhx.email.mapper.EnterpriseMessageMapper;
+import com.fjhx.email.service.IEnterpriseMessageService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 企业邮件 服务实现类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+@Service
+public class EnterpriseMessageServiceImpl extends ServiceImpl<EnterpriseMessageMapper, EnterpriseMessage> implements IEnterpriseMessageService {
+
+}

+ 20 - 0
src/main/java/com/fjhx/email/service/impl/PersonalFolderServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fjhx.email.service.impl;
+
+import com.fjhx.email.entity.PersonalFolder;
+import com.fjhx.email.mapper.PersonalFolderMapper;
+import com.fjhx.email.service.IPersonalFolderService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 个人邮箱文件夹 服务实现类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+@Service
+public class PersonalFolderServiceImpl extends ServiceImpl<PersonalFolderMapper, PersonalFolder> implements IPersonalFolderService {
+
+}

+ 20 - 0
src/main/java/com/fjhx/email/service/impl/PersonalMailboxServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fjhx.email.service.impl;
+
+import com.fjhx.email.entity.PersonalMailbox;
+import com.fjhx.email.mapper.PersonalMailboxMapper;
+import com.fjhx.email.service.IPersonalMailboxService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 个人邮箱 服务实现类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-04
+ */
+@Service
+public class PersonalMailboxServiceImpl extends ServiceImpl<PersonalMailboxMapper, PersonalMailbox> implements IPersonalMailboxService {
+
+}

+ 20 - 0
src/main/java/com/fjhx/email/service/impl/PersonalMessageServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fjhx.email.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.email.entity.PersonalMessage;
+import com.fjhx.email.mapper.PersonalMessageMapper;
+import com.fjhx.email.service.IPersonalMessageService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 个人邮箱 服务实现类
+ * </p>
+ *
+ * @author zlj
+ * @since 2023-04-06
+ */
+@Service
+public class PersonalMessageServiceImpl extends ServiceImpl<PersonalMessageMapper, PersonalMessage> implements IPersonalMessageService {
+
+}

+ 189 - 0
src/main/java/com/fjhx/email/utils/EmailUtil.java

@@ -0,0 +1,189 @@
+package com.fjhx.email.utils;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.fjhx.email.entity.dto.MailboxInfo;
+import com.fjhx.email.entity.dto.ObsFile;
+import com.fjhx.email.entity.dto.SendDto;
+import com.fjhx.email.enums.MailFlagEnum;
+import com.sun.mail.imap.IMAPStore;
+import com.sun.mail.smtp.SMTPMessage;
+import com.sun.mail.util.MailSSLSocketFactory;
+
+import javax.activation.DataHandler;
+import javax.mail.*;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.util.*;
+
+public class EmailUtil {
+
+    private static final HashMap<String, String> ImapStoreId = new HashMap<>();
+
+    static {
+        ImapStoreId.put("name", "fjhx");
+        ImapStoreId.put("version", "1.0.0");
+        ImapStoreId.put("vendor", "fjhxClient");
+        ImapStoreId.put("support-email", "fjhx@fjhx.com");
+    }
+
+    /**
+     * 获取imapStore
+     * 993
+     */
+    public static IMAPStore getIMAPStore(MailboxInfo mailboxInfo) throws MessagingException {
+        Properties ImapProperties = new Properties();
+        ImapProperties.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
+
+        Session session = Session.getInstance(ImapProperties);
+        IMAPStore store = (IMAPStore) session.getStore("imap");
+        store.connect(
+                mailboxInfo.getReceiveHost(),
+                mailboxInfo.getReceivePort(),
+                mailboxInfo.getMailUser(),
+                mailboxInfo.getMailPassword());
+        store.connect();
+        store.id(ImapStoreId);
+        return store;
+    }
+
+
+    public static void main(String[] args) throws Exception {
+        ObsFile attachment = new ObsFile();
+        attachment.setFileUrl("https://os.winfaster.cn/fjhx/saas/GrandStar/2023/03/08/png/3092592f2d614d83854fad5e4c107143.png");
+        attachment.setFileName("board-1.png");
+        SendDto.Address address = new SendDto.Address();
+        address.setAddress("2428241269@qq.com");
+        SendDto sendDto = new SendDto();
+        sendDto.setTo(Collections.singletonList(address));
+        sendDto.setFileList(Collections.singletonList(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 {
+
+        // QQ存在一个特性设置SSL加密
+        MailSSLSocketFactory sf = new MailSSLSocketFactory();
+        sf.setTrustAllHosts(true);
+
+        // 创建一个配置文件并保存
+        Properties properties = new Properties();
+        properties.put("mail.host", host);
+        properties.put("mail.user", user);
+        properties.put("mail.password", password);
+        properties.put("mail.transport.protocol", "smtp");
+        properties.put("mail.smtp.auth", true);
+        properties.put("mail.smtp.ssl.enable", true);
+        properties.put("mail.smtp.ssl.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
+
+        // 创建一个session对象
+        Session session = Session.getInstance(properties);
+
+        // 获取连接对象
+        Transport transport = session.getTransport();
+
+        // 创建邮件对象
+        SMTPMessage mimeMessage = new SMTPMessage(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<ObsFile> fileList = sendDto.getFileList();
+        if (ObjectUtil.isNotEmpty(fileList)) {
+            for (ObsFile attachment : fileList) {
+                DataHandler dataHandler = new DataHandler(new URL(attachment.getFileUrl()));
+
+                MimeBodyPart mimeBodyPart = new MimeBodyPart();
+                mimeBodyPart.setDataHandler(dataHandler);
+                mimeBodyPart.setContentID(IdWorker.getIdStr());
+                mimeBodyPart.setFileName(MimeUtility.encodeText(attachment.getFileName()));
+                mimeMultipart.addBodyPart(mimeBodyPart);
+            }
+        }
+
+        // 添加邮件内容
+        mimeMessage.setContent(mimeMultipart);
+
+        // 连接服务器
+        transport.connect(host, user, password);
+        // 发送邮件
+        transport.sendMessage(mimeMessage, new Address[]{new InternetAddress(user)});
+        // 关闭连接
+        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;
+    }
+
+    /**
+     * 获取标签
+     */
+    public static String getFlags(Flags flags) {
+        if (flags == null) {
+            return StringPool.EMPTY;
+        }
+
+        Flags.Flag[] systemFlags = flags.getSystemFlags();
+        if (systemFlags.length == 0) {
+            return StringPool.EMPTY;
+        }
+
+        StringJoiner stringJoiner = new StringJoiner(",");
+        for (Flags.Flag systemFlag : systemFlags) {
+            stringJoiner.add(MailFlagEnum.getType(systemFlag));
+        }
+        return stringJoiner.toString();
+    }
+
+}

+ 54 - 0
src/main/java/com/fjhx/email/utils/PageWrapper.java

@@ -0,0 +1,54 @@
+package com.fjhx.email.utils;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.convert.Convert;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import lombok.Getter;
+
+import java.util.List;
+
+@Getter
+@SuppressWarnings("unused")
+public class PageWrapper<T> {
+
+    /**
+     * 页数
+     */
+    private final Integer pageNum;
+
+    /**
+     * 每页条数
+     */
+    private final Integer pageSize;
+
+    /**
+     * 总条数
+     */
+    private final Integer total;
+
+    /**
+     * 数据列表
+     */
+    private final List<T> rows;
+
+    /**
+     * 包装page成前端需要的格式
+     */
+    public PageWrapper(IPage<T> page) {
+        this.pageNum = Convert.toInt(page.getPages());
+        this.pageSize = Convert.toInt(page.getSize());
+        this.total = Convert.toInt(page.getTotal());
+        this.rows = page.getRecords();
+    }
+
+    /**
+     * 包装page成前端需要的格式,并把数据列表转成指定实体
+     */
+    public PageWrapper(IPage<?> page, Class<T> cls) {
+        this.pageNum = Convert.toInt(page.getPages());
+        this.pageSize = Convert.toInt(page.getSize());
+        this.total = Convert.toInt(page.getTotal());
+        this.rows = BeanUtil.copyToList(page.getRecords(), cls);
+    }
+
+}

+ 18 - 0
src/main/resources/application-dev.yml

@@ -0,0 +1,18 @@
+# spring配置
+spring:
+  datasource:
+    url: jdbc:mysql://36.134.91.96:17330/bytesailing_mail?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai
+    username: fjhx2012mysql
+    password: 3PN-Mzn#vnP&q6d
+
+mail:
+  # 至少要等待多少秒才会开启下一轮邮件同步
+  minWaitingTime: 45
+  # 初始化同步天数
+  initDay: 7
+  # 多少分钟没同步完成则开启下一轮同步
+  awaitTimeout: 5
+  # 超过多少次后将不再同步此邮箱
+  errorNumber: 5
+  # 获取邮箱类型 1国内邮箱 2国外邮箱
+  mailType: 1

+ 6 - 0
src/main/resources/application-prod.yml

@@ -0,0 +1,6 @@
+# spring配置
+spring:
+  datasource:
+    url: jdbc:mysql://36.134.91.96:17330/bytesailing_mes?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai
+    username: fjhx2012mysql
+    password: 3PN-Mzn#vnP&q6d

+ 29 - 0
src/main/resources/application.yml

@@ -0,0 +1,29 @@
+# spring配置
+spring:
+  profiles:
+    active: dev
+
+# 设置端口号
+server:
+  port: 8088
+
+# mybatis-plus相关配置
+mybatis-plus:
+  mapper-locations: classpath:com/fjhx/email/mapper/xml/*.xml
+  configuration:
+    map-underscore-to-camel-case: true
+    cache-enabled: true
+    lazy-loading-enabled: true
+    multiple-result-sets-enabled: true
+  global-config:
+    banner: false
+    db-config:
+      update-strategy: NOT_NULL
+      # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
+      logic-delete-field: delFlag
+      # 逻辑已删除值(默认为 1)
+      logic-delete-value: 1
+      # 逻辑未删除值(默认为 0)
+      logic-not-delete-value: 0
+    enable-sql-runner: true
+

+ 44 - 0
src/test/java/CodeGeneration.java

@@ -0,0 +1,44 @@
+import com.baomidou.mybatisplus.generator.FastAutoGenerator;
+import com.fjhx.email.config.base.BaseEntity;
+import com.fjhx.email.config.base.BaseService;
+
+
+public class CodeGeneration {
+
+    private static final String url = System.getProperty("user.dir") + "\\src\\main\\java\\";
+
+    public static void main(String[] args) {
+        FastAutoGenerator.create(
+                        "jdbc:mysql://36.134.91.96:17330/bytesailing_mail?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai",
+                        "fjhx2012mysql",
+                        "3PN-Mzn#vnP&q6d"
+                )
+                .globalConfig(builder -> builder
+                        // 设置作者
+                        .author("zlj")
+                        // 指定输出目录
+                        .outputDir(url)
+                        // 禁止打开输出目录
+                        .disableOpenDir())
+                .packageConfig(builder -> {
+                    builder.parent("com.fjhx.email"); // 设置父包名
+                })
+                .strategyConfig(builder -> builder
+                        // 设置需要生成的表名
+                        .addInclude("enterprise_domain")
+                        .entityBuilder()
+                        .disableSerialVersionUID()
+                        .superClass(BaseEntity.class)
+                        .addIgnoreColumns("create_time", "update_time")
+                        .enableLombok()
+
+                        .serviceBuilder()
+                        .superServiceClass(BaseService.class)
+
+                        .controllerBuilder()
+                        .enableRestStyle()
+                )
+                .execute();
+    }
+
+}