邮件模块 删除mail-module

This commit is contained in:
wangjingyi 2022-05-04 22:31:12 +08:00
parent 0b0e37a3d5
commit ea92b84121
22 changed files with 14 additions and 573 deletions

View File

@ -30,7 +30,6 @@
<module>yudao-spring-boot-starter-biz-operatelog</module>
<module>yudao-spring-boot-starter-biz-dict</module>
<module>yudao-spring-boot-starter-biz-sms</module>
<module>yudao-spring-boot-starter-biz-mail</module>
<module>yudao-spring-boot-starter-activiti</module>
<module>yudao-spring-boot-starter-biz-pay</module>
<module>yudao-spring-boot-starter-biz-weixin</module>

View File

@ -1,65 +0,0 @@
<?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">
<parent>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-framework</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-spring-boot-starter-biz-mail</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-common</artifactId>
</dependency>
<!-- Spring 核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 监控相关 -->
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-util</artifactId> <!-- aliyun 短信需要,进行链路追踪 -->
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<optional>true</optional> <!-- 设置为可选,因为使用到 @VisibleForTesting 用于单元测试 -->
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,21 +0,0 @@
package cn.iocoder.yudao.framework.mail.config;
import cn.iocoder.yudao.framework.mail.core.client.MailClientFactory;
import cn.iocoder.yudao.framework.mail.core.client.impl.MailClientFactoryImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 邮箱配置类
*
* @author 芋道源码
*/
@Configuration
public class YudaoMailAutoConfiguration {
@Bean
public MailClientFactory mailClientFactory() {
return new MailClientFactoryImpl();
}
}

View File

@ -1,23 +0,0 @@
package cn.iocoder.yudao.framework.mail.core.client;
import java.util.List;
/**
* 邮件客户端用于对接各邮箱平台的 SDK实现邮件发送等功能
*
* @author wangjingyi
* @date 2021/4/19 19:21
*/
public interface MailClient {
/**
* 发送邮件
*
* @param from 邮箱账号
* @param content 内容
* @param title 标题
* @param tos 收件人
* @return 邮件发送结果
*/
String sendMail(String from, String content, String title, List<String> tos);
}

View File

@ -1,5 +0,0 @@
package cn.iocoder.yudao.framework.mail.core.client;
public interface MailClientFactory {
MailClient getMailClient();
}

View File

@ -1,17 +0,0 @@
package cn.iocoder.yudao.framework.mail.core.client;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.mail.core.enums.MailFrameworkErrorCodeConstants;
import java.util.function.Function;
/**
* API 的错误码转换为通用的错误码
*
* @see MailCommonResult
* @see MailFrameworkErrorCodeConstants
*
* @author 芋道源码
*/
public interface MailCodeMapping extends Function<String, ErrorCode> {
}

View File

@ -1,68 +0,0 @@
package cn.iocoder.yudao.framework.mail.core.client;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import cn.iocoder.yudao.framework.mail.core.enums.MailFrameworkErrorCodeConstants;
/**
* 短信的 CommonResult 拓展类
*
* 考虑到不同的平台返回的 code msg 是不同的所以统一额外返回 {@link #apiCode} {@link #apiMsg} 字段
*
* 另外一些短信平台例如说阿里云腾讯云会返回一个请求编号用于排查请求失败的问题我们设置到 {@link #apiRequestId} 字段
*
* @author 芋道源码
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MailCommonResult<T> extends CommonResult<T> {
/**
* API 返回错误码
*
* 由于第三方的错误码可能是字符串所以使用 String 类型
*/
private String apiCode;
/**
* API 返回提示
*/
private String apiMsg;
/**
* API 请求编号
*/
private String apiRequestId;
private MailCommonResult() {
}
public static <T> MailCommonResult<T> build(String apiCode, String apiMsg, String apiRequestId,
T data, MailCodeMapping codeMapping) {
Assert.notNull(codeMapping, "参数 codeMapping 不能为空");
MailCommonResult<T> result = new MailCommonResult<T>().setApiCode(apiCode).setApiMsg(apiMsg).setApiRequestId(apiRequestId);
result.setData(data);
// 翻译错误码
if (codeMapping != null) {
ErrorCode errorCode = codeMapping.apply(apiCode);
if (errorCode == null) {
errorCode = MailFrameworkErrorCodeConstants.MAIL_UNKNOWN;
}
result.setCode(errorCode.getCode()).setMsg(errorCode.getMsg());
}
return result;
}
public static <T> MailCommonResult<T> error(Throwable ex) {
MailCommonResult<T> result = new MailCommonResult<>();
result.setCode(MailFrameworkErrorCodeConstants.EXCEPTION.getCode());
result.setMsg(ExceptionUtil.getRootCauseMessage(ex));
return result;
}
}

View File

@ -1,48 +0,0 @@
package cn.iocoder.yudao.framework.mail.core.client.dto;
import lombok.Data;
import java.util.Date;
/**
* 消息接收 Response DTO
*
* @author 芋道源码
*/
@Data
public class MailReceiveRespDTO {
/**
* 是否接收成功
*/
private Boolean success;
/**
* API 接收结果的编码
*/
private String errorCode;
/**
* API 接收结果的说明
*/
private String errorMsg;
/**
* 手机号
*/
private String mobile;
/**
* 用户接收时间
*/
private Date receiveTime;
/**
* 短信 API 发送返回的序号
*/
private String serialNo;
/**
* 短信日志编号
*
* 对应 SysSmsLogDO 的编号
*/
private Long logId;
}

View File

@ -1,18 +0,0 @@
package cn.iocoder.yudao.framework.mail.core.client.dto;
import lombok.Data;
/**
* 短信发送 Response DTO
*
* @author 芋道源码
*/
@Data
public class MailSendRespDTO {
/**
* 短信 API 发送返回的序号
*/
private String serialNo;
}

View File

@ -1,31 +0,0 @@
package cn.iocoder.yudao.framework.mail.core.client.dto;
import lombok.Data;
/**
* 短信模板 Response DTO
*
* @author 芋道源码
*/
@Data
public class MailTemplateRespDTO {
/**
* 模板编号
*/
private String id;
/**
* 短信内容
*/
private String content;
/**
* 审核状态
*
*/
private Integer auditStatus;
/**
* 审核未通过的理由
*/
private String auditReason;
}

View File

@ -1,14 +0,0 @@
package cn.iocoder.yudao.framework.mail.core.client.impl;
import lombok.extern.slf4j.Slf4j;
import cn.iocoder.yudao.framework.mail.core.client.MailClient;
/**
* 短信客户端的抽象类提供模板方法减少子类的冗余代码
*
* @author zzf
* @date 2021/2/1 9:28
*/
@Slf4j
public abstract class AbstractMailClient implements MailClient {
}

View File

@ -1,39 +0,0 @@
package cn.iocoder.yudao.framework.mail.core.client.impl;
import cn.iocoder.yudao.framework.mail.core.client.MailClient;
import cn.iocoder.yudao.framework.mail.core.client.impl.hutool.HutoolMailClient;
import lombok.extern.slf4j.Slf4j;
import cn.iocoder.yudao.framework.mail.core.client.MailClientFactory;
import cn.iocoder.yudao.framework.mail.core.enums.MailChannelEnum;
import org.springframework.validation.annotation.Validated;
import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@Validated
@Slf4j
public class MailClientFactoryImpl implements MailClientFactory {
private final ConcurrentMap<String, AbstractMailClient> channelCodeClients = new ConcurrentHashMap<>();
public MailClientFactoryImpl (){
Arrays.stream(MailChannelEnum.values()).forEach(mailChannelEnum -> {
AbstractMailClient abstractMailClient = createMailClient(mailChannelEnum);
channelCodeClients.put(mailChannelEnum.getCode() , abstractMailClient);
});
}
private AbstractMailClient createMailClient(MailChannelEnum mailChannelEnum) {
switch (mailChannelEnum){
case HUTOOL: return new HutoolMailClient();
}
// 创建失败错误日志 + 抛出异常
log.error("[createMailClient][配置({}) 找不到合适的客户端实现]" , mailChannelEnum);
throw new IllegalArgumentException(String.format("配置(%s) 找不到合适的客户端实现", mailChannelEnum));
}
@Override
public MailClient getMailClient() {
return channelCodeClients.get("HUTOOL");
}
}

View File

@ -1,29 +0,0 @@
package cn.iocoder.yudao.framework.mail.core.client.impl.hutool;
import cn.hutool.extra.mail.MailUtil;
import cn.iocoder.yudao.framework.mail.core.client.impl.AbstractMailClient;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
/**
* 邮件客户端实现
*
* @author wangjingyi
* @date 2021/4/25 14:25
*/
@Slf4j
public class HutoolMailClient extends AbstractMailClient {
@Override
public String sendMail(String from, String content, String title, List<String> tos) {
try{
return MailUtil.send(from , title , content , false , null);
}catch (Exception e){
log.error(e.getMessage());
}
return "";
}
}

View File

@ -1,20 +0,0 @@
package cn.iocoder.yudao.framework.mail.core.client.impl.hutool;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.mail.core.client.MailCodeMapping;
/**
* 阿里云的 SmsCodeMapping 实现类
*
* 参见 https://help.aliyun.com/document_detail/101346.htm 文档
*
* @author 芋道源码
*/
public class HutoolMailCodeMapping implements MailCodeMapping {
@Override
public ErrorCode apply(String apiCode) {
return null;
}
}

View File

@ -1,32 +0,0 @@
package cn.iocoder.yudao.framework.mail.core.enums;
import cn.hutool.core.util.ArrayUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 短信渠道枚举
*
* @author zzf
* @date 2021/1/25 10:56
*/
@Getter
@AllArgsConstructor
public enum MailChannelEnum {
HUTOOL("HUTOOL" , "HUTOOL"),
;
/**
* 编码
*/
private final String code;
/**
* 名字
*/
private final String name;
public static MailChannelEnum getByCode(String code) {
return ArrayUtil.firstMatch(o -> o.getCode().equals(code), values());
}
}

View File

@ -1,47 +0,0 @@
package cn.iocoder.yudao.framework.mail.core.enums;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
/**
* 短信框架的错误码枚举
*
* 短信框架使用 2-001-000-000
*
* @author 芋道源码
*/
public interface MailFrameworkErrorCodeConstants {
ErrorCode MAIL_UNKNOWN = new ErrorCode(2001000000, "未知错误,需要解析");
// ========== 权限 / 限流等相关 2001000100 ==========
ErrorCode SMS_PERMISSION_DENY = new ErrorCode(2001000100, "没有发送短信的权限");
// 云片可以配置 IP 白名单只有在白名单中才可以发送短信
ErrorCode SMS_IP_DENY = new ErrorCode(2001000100, "IP 不允许发送短信");
// 阿里云将短信发送频率限制在正常的业务限流范围内默认短信验证码使用同一签名对同一个手机号验证码支持 1 / 分钟5 / 小时累计 10 /
ErrorCode SMS_SEND_BUSINESS_LIMIT_CONTROL = new ErrorCode(2001000102, "指定手机的发送限流");
// 阿里云已经达到您在控制台设置的短信日发送量限额值在国内消息设置 > 安全设置修改发送总量阈值
ErrorCode SMS_SEND_DAY_LIMIT_CONTROL = new ErrorCode(2001000103, "每天的发送限流");
ErrorCode SMS_SEND_CONTENT_INVALID = new ErrorCode(2001000104, "短信内容有敏感词");
// ========== 模板相关 2001000200 ==========
ErrorCode SMS_TEMPLATE_INVALID = new ErrorCode(2001000200, "短信模板不合法"); // 包括短信模板不存在
ErrorCode SMS_TEMPLATE_PARAM_ERROR = new ErrorCode(2001000201, "模板参数不正确");
// ========== 签名相关 2001000300 ==========
ErrorCode SMS_SIGN_INVALID = new ErrorCode(2001000300, "短信签名不可用");
// ========== 账户相关 2001000400 ==========
ErrorCode SMS_ACCOUNT_MONEY_NOT_ENOUGH = new ErrorCode(2001000400, "账户余额不足");
ErrorCode SMS_ACCOUNT_INVALID = new ErrorCode(2001000401, "apiKey 不存在");
// ========== 其它相关 2001000900 开头 ==========
ErrorCode SMS_API_PARAM_ERROR = new ErrorCode(2001000900, "请求参数缺失");
ErrorCode SMS_MOBILE_INVALID = new ErrorCode(2001000901, "手机格式不正确");
ErrorCode SMS_MOBILE_BLACK = new ErrorCode(2001000902, "手机号在黑名单中");
ErrorCode EXCEPTION = new ErrorCode(2001000999, "调用异常");
}

View File

@ -1,21 +0,0 @@
package cn.iocoder.yudao.framework.mail.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 短信模板的审核状态枚举
*
* @author 芋道源码
*/
@AllArgsConstructor
@Getter
public enum MailTemplateAuditStatusEnum {
CHECKING(1),
SUCCESS(2),
FAIL(3);
private final Integer status;
}

View File

@ -1,52 +0,0 @@
package cn.iocoder.yudao.framework.mail.core.property;
import lombok.Data;
import cn.iocoder.yudao.framework.mail.core.enums.MailChannelEnum;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 短信渠道配置类
*
* @author zzf
* @date 2021/1/25 17:01
*/
@Data
@Validated
public class MailChannelProperties {
/**
* 渠道编号
*/
@NotNull(message = "短信渠道 ID 不能为空")
private Long id;
/**
* 短信签名
*/
@NotEmpty(message = "短信签名不能为空")
private String signature;
/**
* 渠道编码
*
* 枚举 {@link MailChannelEnum}
*/
@NotEmpty(message = "渠道编码不能为空")
private String code;
/**
* 短信 API 的账号
*/
@NotEmpty(message = "短信 API 的账号不能为空")
private String apiKey;
/**
* 短信 API 的秘钥
*/
@NotEmpty(message = "短信 API 的秘钥不能为空")
private String apiSecret;
/**
* 短信发送回调 URL
*/
private String callbackUrl;
}

View File

@ -119,13 +119,17 @@ public interface ErrorCodeConstants {
ErrorCode SOCIAL_USER_UNBIND_NOT_SELF = new ErrorCode(1002018001, "社交解绑失败,非当前用户绑定");
ErrorCode SOCIAL_USER_NOT_FOUND = new ErrorCode(1002018002, "社交授权失败,找不到对应的用户");
// ========== 邮箱账号 1002019000 ==========
ErrorCode MAIL_ACCOUNT_NOT_EXISTS = new ErrorCode(1002019000, "邮箱账号不存在");
ErrorCode MAIL_ACCOUNT_EXISTS = new ErrorCode(1002019001, "邮箱账号存在");
// ========== 系统铭感词 1002019000 =========
ErrorCode SENSITIVE_WORD_NOT_EXISTS = new ErrorCode(1002019000, "系统敏感词在所有标签中都不存在");
ErrorCode SENSITIVE_WORD_EXISTS = new ErrorCode(1002019001, "系统敏感词已在标签中存在");
// ========== 邮箱模版 1002020000 ==========
ErrorCode MAIL_TEMPLATE_NOT_EXISTS = new ErrorCode(1002020000 , "邮箱模版不存在");
ErrorCode MAIL_TEMPLATE_EXISTS = new ErrorCode(1002020001, "邮箱模版存在");
ErrorCode MAIL_RELATE_TEMPLATE_EXISTS = new ErrorCode(1002020002, "存在关联邮箱模版");
// ========== 邮箱账号 1002020000 ==========
ErrorCode MAIL_ACCOUNT_NOT_EXISTS = new ErrorCode(1002020000, "邮箱账号不存在");
ErrorCode MAIL_ACCOUNT_EXISTS = new ErrorCode(1002020001, "邮箱账号存在");
// ========== 邮箱模版 1002021000 ==========
ErrorCode MAIL_TEMPLATE_NOT_EXISTS = new ErrorCode(1002021000 , "邮箱模版不存在");
ErrorCode MAIL_TEMPLATE_EXISTS = new ErrorCode(1002021001, "邮箱模版存在");
ErrorCode MAIL_RELATE_TEMPLATE_EXISTS = new ErrorCode(1002021002, "存在关联邮箱模版");
}

View File

@ -42,10 +42,6 @@
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-dict</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-mail</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-data-permission</artifactId>

View File

@ -1,11 +1,7 @@
package cn.iocoder.yudao.module.system.convert.mail;
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.template.MailTemplateBaseVO;
import cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.MailTemplateCreateReqVO;
import cn.iocoder.yudao.module.system.convert.errorcode.ErrorCodeConvertImpl;
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

View File

@ -13,10 +13,8 @@ import cn.iocoder.yudao.module.system.service.mail.MailLogService;
import cn.iocoder.yudao.module.system.service.mail.MailSendService;
import cn.iocoder.yudao.module.system.service.mail.MailTemplateService;
import lombok.extern.slf4j.Slf4j;
import cn.iocoder.yudao.framework.mail.core.client.MailClientFactory;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.framework.mail.core.client.MailClient;
import javax.annotation.Resource;
import java.util.List;
@ -46,8 +44,6 @@ public class MailSendServiceImpl implements MailSendService {
@Resource
private MailLogService mailLogService;
@Resource
private MailClientFactory mailClientFactory;
@Resource
private MailProducer mailProducer;
@ -80,9 +76,9 @@ public class MailSendServiceImpl implements MailSendService {
@Override
public void doSendMail(MailSendMessage message) {
// TODO @wangjingyi直接使用 hutool 发送不要封装 mail client 因为短信的客户端都是比较统一的
MailClient mailClient = mailClientFactory.getMailClient();
String result = mailClient.sendMail(message.getFrom() , message.getContent() , message.getTitle() , message.getTos());
mailLogService.updateSmsSendResult(message.getLogId() , result);
//MailClient mailClient = mailClientFactory.getMailClient();
//String result = mailClient.sendMail(message.getFrom() , message.getContent() , message.getTitle() , message.getTos());
//mailLogService.updateSmsSendResult(message.getLogId() , result);
}
private MailTemplateDO checkMailTemplateValid(String templateCode) {