Преглед изворни кода

邮箱模块:完善 account 账号的增删改查功能

YunaiV пре 2 година
родитељ
комит
0262fa5c15
28 измењених фајлова са 555 додато и 272 уклоњено
  1. 30 0
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/mail/MailSendApi.java
  2. 0 38
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/mail/dto/MailSendReqDTO.java
  3. 39 0
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/mail/dto/MailSendSingleToUserReqDTO.java
  4. 3 6
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java
  5. 0 22
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/mail/MailLogUserTypeEnum.java
  6. 13 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/mail/MailSendApiImpl.java
  7. 6 17
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailAccountController.java
  8. 21 13
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountBaseVO.java
  9. 0 3
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountCreateReqVO.java
  10. 2 13
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountPageReqVO.java
  11. 25 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountRespVO.java
  12. 17 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountSimpleRespVO.java
  13. 0 3
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountUpdateReqVO.java
  14. 17 12
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/mail/MailAccountConvert.java
  15. 5 4
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/mail/MailAccountDO.java
  16. 33 21
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/mail/MailLogDO.java
  17. 5 2
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/mail/MailTemplateDO.java
  18. 4 24
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/mail/MailAccountMapper.java
  19. 7 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/mail/MailTemplateMapper.java
  20. 1 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java
  21. 3 3
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailAccountService.java
  22. 8 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateService.java
  23. 33 80
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/impl/MailAccountServiceImpl.java
  24. 2 3
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/impl/MailLogServiceImpl.java
  25. 10 4
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/impl/MailTemplateServiceImpl.java
  26. 1 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceImpl.java
  27. 44 0
      yudao-ui-admin/src/api/system/mail/account.js
  28. 226 0
      yudao-ui-admin/src/views/system/mail/account/index.vue

+ 30 - 0
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/mail/MailSendApi.java

@@ -1,4 +1,34 @@
 package cn.iocoder.yudao.module.system.api.mail;
 
+import cn.iocoder.yudao.module.system.api.mail.dto.MailSendSingleToUserReqDTO;
+
+import javax.validation.Valid;
+
+/**
+ * 邮箱发送 API 接口
+ *
+ * @author 芋道源码
+ */
 public interface MailSendApi {
+
+    /**
+     * 发送单条邮箱给 Admin 用户
+     *
+     * 在 mail 为空时,使用 userId 加载对应 Admin 的邮箱
+     *
+     * @param reqDTO 发送请求
+     * @return 发送日志编号
+     */
+    Long sendSingleSmsToAdmin(@Valid MailSendSingleToUserReqDTO reqDTO);
+
+    /**
+     * 发送单条邮箱给 Member 用户
+     *
+     * 在 mail 为空时,使用 userId 加载对应 Member 的邮箱
+     *
+     * @param reqDTO 发送请求
+     * @return 发送日志编号
+     */
+    Long sendSingleSmsToMember(@Valid MailSendSingleToUserReqDTO reqDTO);
+
 }

+ 0 - 38
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/mail/dto/MailSendReqDTO.java

@@ -1,38 +0,0 @@
-package cn.iocoder.yudao.module.system.api.mail.dto;
-
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-
-import javax.validation.constraints.Email;
-import javax.validation.constraints.NotNull;
-import java.util.List;
-import java.util.Map;
-
-@ApiModel("管理后台 - 邮件发送 Req VO")
-@Data
-public class MailSendReqDTO { // TODO @wangjingqi:1), 不用空格;2)应该只要传递 templateCode、参数就好,title、from、content、附件应该都是参数里的
-
-    @ApiModelProperty(value = "用户编码",required = true)
-    @NotNull(message = "用户编码不能为空")
-    private String userId;
-
-    @ApiModelProperty(value = "用户类型",required = true)
-    @NotNull(message = "用户类型不能为空")
-    private String userType;
-
-    @ApiModelProperty(value = "邮箱模版id",example = "1024")
-    @NotNull(message = "邮箱模版编码不能为空")
-    private Integer templateCode;
-
-    @ApiModelProperty(value = "邮箱参数")
-    @NotNull(message = "模版参数不能为空")
-    private Map<String,Object> templateParams;
-
-    @ApiModelProperty(value = "收件人",required = true,example = "yudaoyuanma@123.com")
-    @NotNull(message = "收件人不能为空")
-    private List<String> tos;
-
-
-
-}

+ 39 - 0
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/mail/dto/MailSendSingleToUserReqDTO.java

@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.system.api.mail.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotNull;
+import java.util.Map;
+
+/**
+ * 邮件发送 Request DTO
+ *
+ * @author wangjingqi
+ */
+@Data
+public class MailSendSingleToUserReqDTO {
+
+    /**
+     * 用户编号
+     */
+    @NotNull(message = "用户编号不能为空")
+    private String userId;
+    /**
+     * 邮箱
+     */
+    @Email
+    private String mail;
+
+    /**
+     * 邮件模板编号
+     */
+    @NotNull(message = "邮件模板编号不能为空")
+    private String templateCode;
+    /**
+     * 邮件模板参数
+     */
+    @NotNull(message = "邮件模板参数不能为空")
+    private Map<String, Object> templateParams;
+
+}

+ 3 - 6
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java

@@ -141,16 +141,13 @@ public interface ErrorCodeConstants {
     ErrorCode OAUTH2_CODE_NOT_EXISTS = new ErrorCode(1002022000, "code 不存在");
     ErrorCode OAUTH2_CODE_EXPIRE = new ErrorCode(1002022001, "code 已过期");
 
-    // TODO @芋艿:需要重新搞下 mail 错误码
-
-    // ========== 邮箱账号 1002020000 ==========
-    ErrorCode MAIL_ACCOUNT_NOT_EXISTS = new ErrorCode(1002020000, "邮箱账号不存在");
-    ErrorCode MAIL_ACCOUNT_EXISTS = new ErrorCode(1002020001, "邮箱账号存在");
+    // ========== 邮箱账号 1002023000 ==========
+    ErrorCode MAIL_ACCOUNT_NOT_EXISTS = new ErrorCode(1002023000, "邮箱账号不存在");
+    ErrorCode MAIL_ACCOUNT_RELATE_TEMPLATE_EXISTS = new ErrorCode(1002023001, "无法删除,该邮箱账号还有邮件模板");
 
     // ========== 邮箱模版 1002021000 ==========
     ErrorCode MAIL_TEMPLATE_NOT_EXISTS = new ErrorCode(1002021000, "邮箱模版不存在");
     ErrorCode MAIL_TEMPLATE_EXISTS = new ErrorCode(1002021001, "邮箱模版存在");
-    ErrorCode MAIL_ACCOUNT_RELATE_TEMPLATE_EXISTS = new ErrorCode(1002021002, "存在关联邮箱模版");
     ErrorCode MAIL_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1002021003, "模板参数({})缺失");
 
 }

+ 0 - 22
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/mail/MailLogUserTypeEnum.java

@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.system.enums.mail;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 邮件日志用户类型
- *
- * @author wangjingyi
- */
-@Getter
-@AllArgsConstructor
-public enum MailLogUserTypeEnum {
-
-    COMMON (10),
-    VIP (20);
-
-    /**
-     * 类型
-     */
-    private final int userType;
-}

+ 13 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/mail/MailSendApiImpl.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.system.api.mail;
 
+import cn.iocoder.yudao.module.system.api.mail.dto.MailSendSingleToUserReqDTO;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
@@ -10,5 +11,16 @@ import org.springframework.validation.annotation.Validated;
  */
 @Service
 @Validated
-public class MailSendApiImpl implements MailSendApi{
+public class MailSendApiImpl implements MailSendApi {
+
+    @Override
+    public Long sendSingleSmsToAdmin(MailSendSingleToUserReqDTO reqDTO) {
+        return null;
+    }
+
+    @Override
+    public Long sendSingleSmsToMember(MailSendSingleToUserReqDTO reqDTO) {
+        return null;
+    }
+
 }

+ 6 - 17
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailAccountController.java

@@ -3,11 +3,7 @@ package cn.iocoder.yudao.module.system.controller.admin.mail;
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountBaseVO;
-import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountCreateReqVO;
-import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountPageReqVO;
-import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountUpdateReqVO;
-import cn.iocoder.yudao.module.system.controller.admin.mail.vo.send.MailReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.*;
 import cn.iocoder.yudao.module.system.convert.mail.MailAccountConvert;
 import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
 import cn.iocoder.yudao.module.system.service.mail.MailAccountService;
@@ -36,14 +32,14 @@ public class MailAccountController {
     @ApiOperation("创建邮箱账号")
     @PreAuthorize("@ss.hasPermission('system:mail-account:create')")
     public CommonResult<Long> createMailAccount(@Valid @RequestBody MailAccountCreateReqVO createReqVO) {
-        return success(mailAccountService.create(createReqVO));
+        return success(mailAccountService.createMailAccount(createReqVO));
     }
 
     @PutMapping("/update")
     @ApiOperation("修改邮箱账号")
     @PreAuthorize("@ss.hasPermission('system:mail-account:update')")
     public CommonResult<Boolean> updateMailAccount(@Valid @RequestBody MailAccountUpdateReqVO updateReqVO) {
-        mailAccountService.update(updateReqVO);
+        mailAccountService.updateMailAccount(updateReqVO);
         return success(true);
     }
 
@@ -52,18 +48,15 @@ public class MailAccountController {
     @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
     @PreAuthorize("@ss.hasPermission('system:mail-account:delete')")
     public CommonResult<Boolean> deleteMailAccount(@RequestParam Long id) {
-        mailAccountService.delete(id);
+        mailAccountService.deleteMailAccount(id);
         return success(true);
     }
 
-    // TODO @wangjingyi:getMailAccount 和 getMailAccountPage 这两个接口,定义一个对应的 Resp 类哈,参考别的模块。主要不要返回 password 字段。
-    // 一个可以的做法,是 MailAccountBaseVO 不返回 password,然后 MailAccountCreateReqVO、MailAccountUpdateReqVO 添加这个字段 DONE
-
     @GetMapping("/get")
     @ApiOperation("获得邮箱账号")
     @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
     @PreAuthorize("@ss.hasPermission('system:mail-account:get')")
-    public CommonResult<MailAccountBaseVO> getMailAccount(@RequestParam("id") Long id) {
+    public CommonResult<MailAccountRespVO> getMailAccount(@RequestParam("id") Long id) {
         MailAccountDO mailAccountDO = mailAccountService.getMailAccount(id);
         return success(MailAccountConvert.INSTANCE.convert(mailAccountDO));
     }
@@ -76,14 +69,10 @@ public class MailAccountController {
         return success(MailAccountConvert.INSTANCE.convertPage(pageResult));
     }
 
-    // TODO @wangjingyi:getSimpleMailAccountList 单独定义一个类,只返回精简的信息,id,from 即可。像密码之类都是敏感信息,不应该返回 DONE
-
     @GetMapping("/list-all-simple")
     @ApiOperation(value = "获得邮箱账号精简列表")
-    public CommonResult<List<MailAccountBaseVO>> getSimpleMailAccountList() {
+    public CommonResult<List<MailAccountSimpleRespVO>> getSimpleMailAccountList() {
         List<MailAccountDO> list = mailAccountService.getMailAccountList();
-        // 排序后,返回给前端
-        list.sort(Comparator.comparing(MailAccountDO::getId));
         return success(MailAccountConvert.INSTANCE.convertList02(list));
     }
 

+ 21 - 13
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountBaseVO.java

@@ -1,33 +1,41 @@
 package cn.iocoder.yudao.module.system.controller.admin.mail.vo.account;
 
-import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import javax.validation.constraints.Email;
 import javax.validation.constraints.NotNull;
 
-@ApiModel("管理后台 - 邮箱账号基类 Base VO")
+/**
+ * 邮箱账号 Base VO,提供给添加、修改、详细的子 VO 使用
+ * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+ */
 @Data
 public class MailAccountBaseVO {
 
-    @ApiModelProperty(value = "邮箱",required = true,example = "yudaoyuanma@123.com")
-    @NotNull(message = "邮箱必填")
-    @Email(message = "必须是Email格式")
-    private String fromAddress;
+    @ApiModelProperty(value = "邮箱", required = true, example = "yudaoyuanma@123.com")
+    @NotNull(message = "邮箱不能为空")
+    @Email(message = "必须是 Email 格式")
+    private String mail;
 
-    @ApiModelProperty(value = "用户名",required = true,example = "yudao")
-    @NotNull(message = "用户名必填")
+    @ApiModelProperty(value = "用户名", required = true, example = "yudao")
+    @NotNull(message = "用户名不能为空")
     private String username;
 
-    @ApiModelProperty(value = "网站",required = true,example = "www.iocoder.cn")
-    @NotNull(message = "网站必填")
+    @ApiModelProperty(value = "密码", required = true, example = "123456")
+    @NotNull(message = "密码必填")
+    private String password;
+
+    @ApiModelProperty(value = "网站", required = true, example = "www.iocoder.cn")
+    @NotNull(message = "网站不能为空")
     private String host;
 
-    @ApiModelProperty(value = "端口",required = true,example = "80")
+    @ApiModelProperty(value = "端口", required = true, example = "80")
+    @NotNull(message = "端口不能为空")
     private Integer port;
 
-    @ApiModelProperty(value = "是否开启ssl",required = true,example = "2")
-    @NotNull(message = "是否开启ssl必填")
+    @ApiModelProperty(value = "是否开启 ssl", required = true, example = "true")
+    @NotNull(message = "是否开启 ssl 必填")
     private Boolean sslEnable;
+
 }

+ 0 - 3
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountCreateReqVO.java

@@ -14,7 +14,4 @@ import javax.validation.constraints.NotNull;
 @ToString(callSuper = true)
 public class MailAccountCreateReqVO extends MailAccountBaseVO {
 
-    @ApiModelProperty(value = "密码",required = true,example = "123456")
-    @NotNull(message = "密码必填")
-    private String password;
 }

+ 2 - 13
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountPageReqVO.java

@@ -13,21 +13,10 @@ import lombok.ToString;
 @ToString(callSuper = true)
 public class MailAccountPageReqVO extends PageParam {
 
-    @ApiModelProperty(value = "邮箱" , required = true , example = "yudaoyuanma@123.com")
-    private String fromAddress;
+    @ApiModelProperty(value = "邮箱", required = true, example = "yudaoyuanma@123.com")
+    private String mail;
 
     @ApiModelProperty(value = "用户名" , required = true , example = "yudao")
     private String username;
 
-    @ApiModelProperty(value = "密码" , required = true , example = "123456")
-    private String password;
-
-    @ApiModelProperty(value = "网站" , required = true , example = "www.iocoder.cn")
-    private String host;
-
-    @ApiModelProperty(value = "端口" , required = true , example = "80")
-    private String port;
-
-    @ApiModelProperty(value = "是否开启ssl" , required = true , example = "2")
-    private Boolean sslEnable;
 }

+ 25 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountRespVO.java

@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.module.system.controller.admin.mail.vo.account;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+
+@ApiModel("管理后台 - 邮箱账号 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class MailAccountRespVO extends MailAccountBaseVO {
+
+    @ApiModelProperty(value = "编号", required = true, example = "1024")
+    @NotNull(message = "编号不能为空")
+    private Long id;
+
+    @ApiModelProperty(value = "创建时间", required = true)
+    private LocalDateTime createTime;
+
+}

+ 17 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountSimpleRespVO.java

@@ -0,0 +1,17 @@
+package cn.iocoder.yudao.module.system.controller.admin.mail.vo.account;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@ApiModel("管理后台 - 邮箱账号的精简 Response VO")
+@Data
+public class MailAccountSimpleRespVO {
+
+    @ApiModelProperty(value = "邮箱比那好", required = true, example = "1024")
+    private Long id;
+
+    @ApiModelProperty(value = "邮箱", required = true, example = "768541388@qq.com")
+    private String mail;
+
+}

+ 0 - 3
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountUpdateReqVO.java

@@ -18,7 +18,4 @@ public class MailAccountUpdateReqVO extends MailAccountBaseVO {
     @NotNull(message = "编号不能为空")
     private Long id;
 
-    @ApiModelProperty(value = "密码",required = true,example = "123456")
-    @NotNull(message = "密码必填")
-    private String password;
 }

+ 17 - 12
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/mail/MailAccountConvert.java

@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.system.convert.mail;
 import cn.hutool.extra.mail.MailAccount;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountBaseVO;
+import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountSimpleRespVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
 import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage;
 import org.mapstruct.Mapper;
@@ -14,30 +16,33 @@ import java.util.Map;
 
 @Mapper
 public interface MailAccountConvert {
+
     MailAccountConvert INSTANCE = Mappers.getMapper(MailAccountConvert.class);
 
-    MailAccountDO convert (MailAccountBaseVO mailAccountBaseVO);
+    MailAccountDO convert(MailAccountBaseVO bean);
 
-    MailAccountBaseVO convert (MailAccountDO mailAccountDO);
+    MailAccountRespVO convert(MailAccountDO bean);
 
-    PageResult<MailAccountBaseVO>  convertPage(PageResult<MailAccountDO> pageResult);
+    PageResult<MailAccountBaseVO> convertPage(PageResult<MailAccountDO> pageResult);
 
-    List<MailAccountBaseVO> convertList02(List<MailAccountDO> list);
+    List<MailAccountSimpleRespVO> convertList02(List<MailAccountDO> list);
 
-    default MailAccount convertAccount(MailSendMessage mailAccountDO){
+    // TODO 芋艿:改下
+    default MailAccount convertAccount(MailSendMessage bean) {
         return new MailAccount()
-                .setHost(mailAccountDO.getHost())
-                .setPort(mailAccountDO.getPort())
+                .setHost(bean.getHost())
+                .setPort(bean.getPort())
                 .setAuth(true)
-                .setFrom(mailAccountDO.getFromAddress())
-                .setUser(mailAccountDO.getUsername())
-                .setPass(mailAccountDO.getPassword())
-                .setSslEnable(mailAccountDO.getSslEnable());
+                .setFrom(bean.getFromAddress())
+                .setUser(bean.getUsername())
+                .setPass(bean.getPassword())
+                .setSslEnable(bean.getSslEnable());
     }
 
+    // TODO 芋艿:改下
     default Map<String, String> convertToMap(MailAccountDO mailAccountDO , String content) {
         Map<String , String> map = new HashMap<>();
-        map.put("from_address" , mailAccountDO.getFromAddress());
+        map.put("from_address" , mailAccountDO.getMail());
         map.put("username" , mailAccountDO.getUsername());
         map.put("content" , content);
         return map;

+ 5 - 4
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/mail/MailAccountDO.java

@@ -1,14 +1,14 @@
 package cn.iocoder.yudao.module.system.dal.dataobject.mail;
 
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
 /**
- * 邮箱账号
- * 配置发送邮箱的账号
+ * 邮箱账号 DO
+ *
+ * 用途:配置发送邮箱的账号
  *
  * @author wangjingyi
  * @since 2022-03-21
@@ -25,7 +25,8 @@ public class MailAccountDO extends BaseDO {
     /**
      * 邮箱
      */
-    private String fromAddress;
+    private String mail;
+
     /**
      * 用户名
      */

+ 33 - 21
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/mail/MailLogDO.java

@@ -1,7 +1,7 @@
 package cn.iocoder.yudao.module.system.dal.dataobject.mail;
 
+import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import cn.iocoder.yudao.module.system.enums.mail.MailLogUserTypeEnum;
 import cn.iocoder.yudao.module.system.enums.mail.MailSendStatusEnum;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
@@ -13,7 +13,7 @@ import java.util.Date;
 import java.util.Map;
 
 /**
- * 邮箱日志
+ * 邮箱日志 DO
  * 记录每一次邮件的发送
  *
  * @author wangjingyi
@@ -29,7 +29,7 @@ import java.util.Map;
 public class MailLogDO extends BaseDO implements Serializable {
 
     /**
-     * 主键
+     * 日志编号,自增
      */
     private Long id;
 
@@ -37,62 +37,74 @@ public class MailLogDO extends BaseDO implements Serializable {
      * 用户编码
      */
     private Long userId;
-
     /**
      * 用户类型
      *
-     * 冗余 {@link MailLogUserTypeEnum#getUserType}
+     * 枚举 {@link UserTypeEnum}
      */
     private Integer userType;
+    /**
+     * 接收邮箱地址
+     */
+    private String toMail;
 
-    // TODO @wangjingyi:accountId
     /**
      * 邮箱账号编号
+     *
+     * 关联 {@link MailAccountDO#getId()}
      */
     private Long accountId;
-
-    // TODO @wangjingyi:如果是冗余字段,记得 @ 下;DONE
     /**
-     * 邮箱账号
+     * 发送邮箱地址
      *
-     * 冗余 {@link MailAccountDO}
+     * 冗余 {@link MailAccountDO#getMail()}
      */
-    private String fromAddress;
+    private String fromMail;
 
+    // ========= 模板相关字段 =========
     /**
-     * 模版主键
+     * 模版编号
+     *
+     * 关联 {@link MailTemplateDO#getId()}
      */
     private Long templateId;
-
+    /**
+     * 末班编码
+     *
+     * 冗余 {@link MailTemplateDO#getCode()}
+     */
+    private String templateCode;
     /**
      * 模版内容
+     *
+     * 基于 {@link MailTemplateDO#getContent()} 格式化后的内容
      */
     private String templateContent;
-
     /**
+     * 模版参数
+     *
      * 基于 {@link MailTemplateDO#getParams()} 输入后的参数
      */
     @TableField(typeHandler = JacksonTypeHandler.class)
     private Map<String,Object> templateParams;
 
-    /**
-     * 发送时间
-     */
-    private Date sendTime;
-
-    //=========接收相关字段=========
+    // ========= 发送相关字段 =========
     /**
      * 发送状态
      *
      * 枚举 {@link MailSendStatusEnum}
      */
     private Integer sendStatus;
+    /**
+     * 发送时间
+     */
+    private Date sendTime;
 
+    // ========= 接收相关字段 =========
     /**
      * 发送结果
      */
     private String sendResult;
-
     /**
      *  消息ID
      */

+ 5 - 2
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/mail/MailTemplateDO.java

@@ -11,7 +11,7 @@ import lombok.EqualsAndHashCode;
 import java.util.List;
 
 /**
- * 邮箱模版
+ * 邮箱模版 DO
  *
  * @author wangjingyi
  * @since 2022-03-21
@@ -34,9 +34,12 @@ public class MailTemplateDO extends BaseDO {
      */
     private String code;
     /**
-     * 邮箱账号主键
+     * 发送的邮箱账号编号
+     *
+     * 关联 {@link MailAccountDO#getId()}
      */
     private Long accountId;
+
     /**
      * 标题
      */

+ 4 - 24
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/mail/MailAccountMapper.java

@@ -2,37 +2,19 @@ package cn.iocoder.yudao.module.system.dal.mysql.mail;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
 import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountPageReqVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
-import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
-
-import java.util.Date;
 
 @Mapper
 public interface MailAccountMapper extends BaseMapperX<MailAccountDO> {
 
     default PageResult<MailAccountDO> selectPage(MailAccountPageReqVO pageReqVO) {
-        return selectPage(pageReqVO, new QueryWrapperX<MailAccountDO>()
-                .likeIfPresent("from_address" , pageReqVO.getFromAddress())
-                .likeIfPresent("host" , pageReqVO.getHost())
-                .likeIfPresent("username" , pageReqVO.getUsername())
-                .eqIfPresent("password" , pageReqVO.getPassword())
-                .eqIfPresent("port" , pageReqVO.getPort())
-        );
-    }
-
-    default MailAccountDO selectByUserName(String userName){
-        return selectOne(new QueryWrapperX<MailAccountDO>()
-                .eqIfPresent("username" , userName));
-    }
-
-    default MailAccountDO selectByUserNameAndId(String userName,Long id){
-        return selectOne(new QueryWrapperX<MailAccountDO>()
-                .eqIfPresent("username" , userName)
-                .neIfPresent("id" , id));
+        return selectPage(pageReqVO, new LambdaQueryWrapperX<MailAccountDO>()
+                .likeIfPresent(MailAccountDO::getMail, pageReqVO.getMail())
+                .likeIfPresent(MailAccountDO::getUsername , pageReqVO.getUsername()));
     }
 
     default MailAccountDO selectOneByFrom(String from){
@@ -40,6 +22,4 @@ public interface MailAccountMapper extends BaseMapperX<MailAccountDO> {
                 .eqIfPresent("from_address" , from));
     }
 
-    @Select("SELECT COUNT(*) FROM system_mail_account WHERE update_time > #{maxUpdateTime}")
-    Long selectCountByUpdateTimeGt(Date maxUpdateTime);
 }

+ 7 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/mail/MailTemplateMapper.java

@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
 import cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.MailTemplatePageReqVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Select;
 
@@ -36,5 +37,10 @@ public interface MailTemplateMapper extends BaseMapperX<MailTemplateDO> {
     default MailTemplateDO selectOneByAccountId(Long accountId){
         return selectOne(new QueryWrapperX<MailTemplateDO>()
                 .eqIfPresent("account_id" , accountId));
-    };
+    }
+
+    default Long selectCountByAccountId(Long accountId) {
+        return selectCount(MailTemplateDO::getAccountId, accountId);
+    }
+
 }

+ 1 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java

@@ -55,7 +55,7 @@ public class MailProducer {
     public void sendMailSendMessage(Long sendLogId,MailAccountDO mailAccountDO, MailTemplateDO mailTemplateDO, String content,List<KeyValue<String, Object>> templateParams,String to) {
         MailSendMessage message = new MailSendMessage();
         message.setContent(content)
-        .setFromAddress(mailAccountDO.getFromAddress())
+        .setFromAddress(mailAccountDO.getMail())
         .setHost(mailAccountDO.getHost())
         .setPort(mailAccountDO.getPort())
         .setPassword(mailAccountDO.getPassword())

+ 3 - 3
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailAccountService.java

@@ -28,21 +28,21 @@ public interface MailAccountService {
      * @param createReqVO 邮箱账号信息
      * @return 编号
      */
-    Long create(@Valid MailAccountCreateReqVO createReqVO);
+    Long createMailAccount(@Valid MailAccountCreateReqVO createReqVO);
 
     /**
      * 修改邮箱账号
      *
      * @param updateReqVO 邮箱账号信息
      */
-    void update(@Valid MailAccountUpdateReqVO updateReqVO);
+    void updateMailAccount(@Valid MailAccountUpdateReqVO updateReqVO);
 
     /**
      * 删除邮箱账号
      *
      * @param id 编号
      */
-    void delete(Long id);
+    void deleteMailAccount(Long id);
 
     /**
      * 获取邮箱账号信息

+ 8 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateService.java

@@ -85,4 +85,12 @@ public interface MailTemplateService {
      */
     String formatMailTemplateContent(String content, Map<String, String> params);
 
+    /**
+     * 获得指定邮箱账号下的邮件模板数量
+     *
+     * @param accountId 账号编号
+     * @return 数量
+     */
+    long countByAccountId(Long accountId);
+
 }

+ 33 - 80
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/impl/MailAccountServiceImpl.java

@@ -1,32 +1,28 @@
 package cn.iocoder.yudao.module.system.service.mail.impl;
 
-import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountCreateReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountPageReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountUpdateReqVO;
 import cn.iocoder.yudao.module.system.convert.mail.MailAccountConvert;
 import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
-import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO;
-import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO;
 import cn.iocoder.yudao.module.system.dal.mysql.mail.MailAccountMapper;
-import cn.iocoder.yudao.module.system.dal.mysql.mail.MailTemplateMapper;
 import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer;
 import cn.iocoder.yudao.module.system.service.mail.MailAccountService;
+import cn.iocoder.yudao.module.system.service.mail.MailTemplateService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
-import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
-
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.MAIL_ACCOUNT_NOT_EXISTS;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.MAIL_ACCOUNT_RELATE_TEMPLATE_EXISTS;
 
 /**
  * 邮箱账号 Service 实现类
@@ -43,7 +39,7 @@ public class MailAccountServiceImpl implements MailAccountService {
     private MailAccountMapper mailAccountMapper;
 
     @Resource
-    private MailTemplateMapper mailTemplateMapper;
+    private MailTemplateService mailTemplateService;
 
     @Resource
     private MailProducer mailProducer;
@@ -56,75 +52,61 @@ public class MailAccountServiceImpl implements MailAccountService {
      */
     private volatile Map<Long, MailAccountDO> mailAccountCache;
 
-    /**
-     * 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新
-     */
-    private volatile Date maxUpdateTime;
-
     @Override
     @PostConstruct
     public void initLocalCache() {
-        List<MailAccountDO> mailAccountDOList = this.loadMailAccountIfUpdate(maxUpdateTime);
-        if (CollUtil.isEmpty(mailAccountDOList)) {
-            return;
-        }
-
-        // 写入缓存
-        mailAccountCache = CollectionUtils.convertMap(mailAccountDOList, MailAccountDO::getId);
-        maxUpdateTime = CollectionUtils.getMaxValue(mailAccountDOList, MailAccountDO::getUpdateTime);
-        log.info("[initLocalCache][初始化 MailAccount 数量为 {}]", mailAccountDOList.size());
-    }
+        // 第一步:查询数据
+        List<MailAccountDO> accounts = mailAccountMapper.selectList();
+        log.info("[initLocalCache][缓存邮箱账号,数量:{}]", accounts.size());
 
-    private List<MailAccountDO> loadMailAccountIfUpdate(Date maxUpdateTime) {
-        //第一步 判断是否需要更新
-        if(null == maxUpdateTime){ // 如果更新时间为空,说明 DB 一定有新数据
-            log.info("[loadMailAccountIfUpdate][首次加载全量账号信息]");
-        }else{ // 判断数据库中是否有更新的账号信息
-            if (mailAccountMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
-                return null;
-            }
-            log.info("[loadMailAccountIfUpdate][增量加载全量账号信息]");
-        }
-        return mailAccountMapper.selectList();
+        // 第二步:构建缓存
+        mailAccountCache = convertMap(accounts, MailAccountDO::getId);
     }
 
     @Override
-    public Long create(MailAccountCreateReqVO createReqVO) {
-        // username 要校验唯一
-        this.validateMailAccountOnlyByUserName(createReqVO.getUsername());
-        MailAccountDO mailAccountDO = MailAccountConvert.INSTANCE.convert(createReqVO);
-        mailAccountMapper.insert(mailAccountDO);
+    public Long createMailAccount(MailAccountCreateReqVO createReqVO) {
+        // 插入
+        MailAccountDO account = MailAccountConvert.INSTANCE.convert(createReqVO);
+        mailAccountMapper.insert(account);
 
-        // 更新
+        // 发送刷新消息
         mailProducer.sendMailAccountRefreshMessage();
-        return mailAccountDO.getId();
+        return account.getId();
     }
 
     @Override
-    public void update(MailAccountUpdateReqVO updateReqVO) {
-        // username 要校验唯一 TODO @wangjingyi:校验唯一的时候,需要排除掉自己 DONE
-        this.validateMailAccountOnlyByUserNameAndId(updateReqVO.getUsername(),updateReqVO.getId());
-        MailAccountDO mailAccountDO = MailAccountConvert.INSTANCE.convert(updateReqVO);
+    public void updateMailAccount(MailAccountUpdateReqVO updateReqVO) {
         // 校验是否存在
-        validateMailAccountExists(mailAccountDO.getId());
+        validateMailAccountExists(updateReqVO.getId());
 
         // 更新
+        MailAccountDO updateObj = MailAccountConvert.INSTANCE.convert(updateReqVO);
+        mailAccountMapper.updateById(updateObj);
+        // 发送刷新消息
         mailProducer.sendMailAccountRefreshMessage();
-        mailAccountMapper.updateById(mailAccountDO);
     }
 
     @Override
-    public void delete(Long id) {
+    public void deleteMailAccount(Long id) {
         // 校验是否存在账号
         validateMailAccountExists(id);
         // 校验是否存在关联模版
-        validateMailTemplateByAccountId(id);
+        if (mailTemplateService.countByAccountId(id) > 0) {
+            throw exception(MAIL_ACCOUNT_RELATE_TEMPLATE_EXISTS);
+        }
+
         // 删除
         mailAccountMapper.deleteById(id);
-        // 更新
+        // 发送刷新消息
         mailProducer.sendMailAccountRefreshMessage();
     }
 
+    private void validateMailAccountExists(Long id) {
+        if (mailAccountMapper.selectById(id) == null) {
+            throw exception(MAIL_ACCOUNT_NOT_EXISTS);
+        }
+    }
+
     @Override
     public MailAccountDO getMailAccount(Long id) {
         return mailAccountMapper.selectById(id);
@@ -140,33 +122,4 @@ public class MailAccountServiceImpl implements MailAccountService {
         return mailAccountMapper.selectList();
     }
 
-    private void validateMailAccountExists(Long id) {
-        if (mailAccountMapper.selectById(id) == null) {
-            throw exception(MAIL_ACCOUNT_NOT_EXISTS);
-        }
-    }
-
-    private void validateMailAccountOnlyByUserName(String userName){
-        mailAccountCache.forEach((key,value)->{
-            if(value.getUsername().equals(userName)){
-                throw exception(MAIL_ACCOUNT_EXISTS);
-            }
-        });
-    }
-    private void validateMailAccountOnlyByUserNameAndId(String userName,Long id){
-        mailAccountCache.forEach((key , value)->{
-            if (value.getUsername().equals(userName)){
-                if (!key.equals(id)){
-                    throw exception(MAIL_ACCOUNT_EXISTS);
-                }
-            }
-        });
-    }
-    private void validateMailTemplateByAccountId(Long accountId){
-        MailTemplateDO mailTemplateDO =  mailTemplateMapper.selectOneByAccountId(accountId);
-        if (mailTemplateDO != null) {
-            // TODO wangjingyi:MAIL_ACCOUNT_RELATE_TEMPLATE_EXISTS DONE
-            throw exception(MAIL_ACCOUNT_RELATE_TEMPLATE_EXISTS);
-        }
-    }
 }

+ 2 - 3
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/impl/MailLogServiceImpl.java

@@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO;
 import cn.iocoder.yudao.module.system.dal.mysql.mail.MailLogMapper;
 import cn.iocoder.yudao.module.system.enums.mail.MailSendStatusEnum;
 import cn.iocoder.yudao.module.system.service.mail.MailLogService;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
@@ -51,7 +50,7 @@ public class MailLogServiceImpl implements MailLogService {
         logDOBuilder.sendStatus(Objects.equals(isSend, true) ? MailSendStatusEnum.INIT.getStatus()
                 : MailSendStatusEnum.IGNORE.getStatus())
                 // 设置邮箱相关字段
-                .fromAddress(mailAccountDO.getFromAddress())
+                .fromMail(mailAccountDO.getMail())
                 .accountId(mailAccountDO.getId())
                 // TODO @wangjingyi:userId、userType
                 //用户信息
@@ -60,7 +59,7 @@ public class MailLogServiceImpl implements MailLogService {
                 .templateId(template.getId()).templateParams(templateParams).templateContent(templateContent);
 
 
-        logDOBuilder.fromAddress(mailAccountDO.getFromAddress());
+        logDOBuilder.fromMail(mailAccountDO.getMail());
         logDOBuilder.accountId(mailAccountDO.getId());
         // TODO @wangjingyi:每个接收人一条日志。发送多个人,就调用多次,业务方。因为某个邮箱有问题,会导致所有都发送失败。 DONE
         // 设置模板相关字段

+ 10 - 4
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/impl/MailTemplateServiceImpl.java

@@ -53,19 +53,19 @@ public class MailTemplateServiceImpl implements MailTemplateService {
      */
     private volatile Map<Long, MailTemplateDO> mailTemplateCache;
 
-    private volatile Date maxUpdateTime;
-
     @Override
     @PostConstruct
     public void initLocalCache() {
-        List<MailTemplateDO> mailTemplateDOList = this.loadMailTemplateIfUpdate(maxUpdateTime);
+        if (true) {
+            return;
+        }
+        List<MailTemplateDO> mailTemplateDOList = this.loadMailTemplateIfUpdate(null);
         if (CollUtil.isEmpty(mailTemplateDOList)) {
             return;
         }
 
         // 写入缓存
         mailTemplateCache = CollectionUtils.convertMap(mailTemplateDOList, MailTemplateDO::getId);
-        maxUpdateTime = CollectionUtils.getMaxValue(mailTemplateDOList, MailTemplateDO::getUpdateTime);
         log.info("[initLocalCache][初始化 mailTemplate 数量为 {}]", mailTemplateDOList.size());
     }
 
@@ -156,4 +156,10 @@ public class MailTemplateServiceImpl implements MailTemplateService {
         // 第二步,如果有更新,则从数据库加载所有邮件模板
         return mailTemplateMapper.selectList();
     }
+
+    @Override
+    public long countByAccountId(Long accountId) {
+        return mailTemplateMapper.selectCountByAccountId(accountId);
+    }
+
 }

+ 1 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceImpl.java

@@ -81,7 +81,7 @@ public class SmsChannelServiceImpl implements SmsChannelService {
     public void deleteSmsChannel(Long id) {
         // 校验存在
         this.validateSmsChannelExists(id);
-        // 校验是否有字典数据
+        // 校验是否有在使用该账号的模版
         if (smsTemplateService.countByChannelId(id) > 0) {
             throw exception(SMS_CHANNEL_HAS_CHILDREN);
         }

+ 44 - 0
yudao-ui-admin/src/api/system/mail/account.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 创建邮箱账号
+export function createMailAccount(data) {
+  return request({
+    url: '/system/mail-account/create',
+    method: 'post',
+    data: data
+  })
+}
+
+// 更新邮箱账号
+export function updateMailAccount(data) {
+  return request({
+    url: '/system/mail-account/update',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除邮箱账号
+export function deleteMailAccount(id) {
+  return request({
+    url: '/system/mail-account/delete?id=' + id,
+    method: 'delete'
+  })
+}
+
+// 获得邮箱账号
+export function getMailAccount(id) {
+  return request({
+    url: '/system/mail-account/get?id=' + id,
+    method: 'get'
+  })
+}
+
+// 获得邮箱账号分页
+export function getMailAccountPage(query) {
+  return request({
+    url: '/system/mail-account/page',
+    method: 'get',
+    params: query
+  })
+}

+ 226 - 0
yudao-ui-admin/src/views/system/mail/account/index.vue

@@ -0,0 +1,226 @@
+<template>
+  <div class="app-container">
+
+    <!-- 搜索工作栏 -->
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="邮箱" prop="mail">
+        <el-input v-model="queryParams.mail" placeholder="请输入邮箱" clearable @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="用户名" prop="username">
+        <el-input v-model="queryParams.username" placeholder="请输入用户名" clearable @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 操作工具栏 -->
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
+                   v-hasPermi="['system:mail-account:create']">新增</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <!-- 列表 -->
+    <el-table v-loading="loading" :data="list">
+      <el-table-column label="主键" align="center" prop="id" />
+      <el-table-column label="邮箱" align="center" prop="mail" />
+      <el-table-column label="用户名" align="center" prop="username" />
+      <el-table-column label="主机" align="center" prop="host" />
+      <el-table-column label="端口" align="center" prop="port" />
+      <el-table-column label="是否开启 SSL" align="center" prop="sslEnable">
+        <template v-slot="scope">
+          <dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.sslEnable" />
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template v-slot="scope">
+          <span>{{ parseTime(scope.row.createTime) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template v-slot="scope">
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
+                     v-hasPermi="['system:mail-account:update']">修改</el-button>
+          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
+                     v-hasPermi="['system:mail-account:delete']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页组件 -->
+    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
+                @pagination="getList"/>
+
+    <!-- 对话框(添加 / 修改) -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" v-dialogDrag append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+        <el-form-item label="邮箱" prop="mail">
+          <el-input v-model="form.mail" placeholder="请输入邮箱" />
+        </el-form-item>
+        <el-form-item label="用户名" prop="username">
+          <el-input v-model="form.username" placeholder="请输入用户名" />
+        </el-form-item>
+        <el-form-item label="密码" prop="password">
+          <el-input v-model="form.password" placeholder="请输入密码" />
+        </el-form-item>
+        <el-form-item label="主机" prop="host">
+          <el-input v-model="form.host" placeholder="请输入主机" />
+        </el-form-item>
+        <el-form-item label="端口" prop="port">
+          <el-input v-model="form.port" placeholder="请输入端口" />
+        </el-form-item>
+        <el-form-item label="是否开启 SSL" prop="sslEnable">
+          <el-radio-group v-model="form.sslEnable">
+            <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_BOOLEAN_STRING)"
+                      :key="dict.value" :label="dict.value === 'true'">{{dict.label}}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { createMailAccount, updateMailAccount, deleteMailAccount, getMailAccount, getMailAccountPage } from "@/api/system/mail/account";
+
+export default {
+  name: "MailAccount",
+  components: {
+  },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 邮箱账号列表
+      list: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNo: 1,
+        pageSize: 10,
+        mail: null,
+        username: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        mail: [{ required: true, message: "邮箱不能为空", trigger: "blur" }],
+        username: [{ required: true, message: "用户名不能为空", trigger: "blur" }],
+        password: [{ required: true, message: "密码不能为空", trigger: "blur" }],
+        host: [{ required: true, message: "主机不能为空", trigger: "blur" }],
+        port: [{ required: true, message: "端口不能为空", trigger: "blur" }],
+        sslEnable: [{ required: true, message: "是否开启 SSL不能为空", trigger: "blur" }],
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询列表 */
+    getList() {
+      this.loading = true;
+      // 执行查询
+      getMailAccountPage(this.queryParams).then(response => {
+        this.list = response.data.list;
+        this.total = response.data.total;
+        this.loading = false;
+      });
+    },
+    /** 取消按钮 */
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    /** 表单重置 */
+    reset() {
+      this.form = {
+        id: undefined,
+        mail: undefined,
+        username: undefined,
+        password: undefined,
+        host: undefined,
+        port: undefined,
+        sslEnable: true,
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNo = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加邮箱账号";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id;
+      getMailAccount(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改邮箱账号";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (!valid) {
+          return;
+        }
+        // 修改的提交
+        if (this.form.id != null) {
+          updateMailAccount(this.form).then(response => {
+            this.$modal.msgSuccess("修改成功");
+            this.open = false;
+            this.getList();
+          });
+          return;
+        }
+        // 添加的提交
+        createMailAccount(this.form).then(response => {
+          this.$modal.msgSuccess("新增成功");
+          this.open = false;
+          this.getList();
+        });
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const id = row.id;
+      this.$modal.confirm('是否确认删除邮箱账号编号为"' + id + '"的数据项?').then(function() {
+          return deleteMailAccount(id);
+        }).then(() => {
+          this.getList();
+          this.$modal.msgSuccess("删除成功");
+        }).catch(() => {});
+    }
+  }
+};
+</script>