TASK: 发送邮件功能及发送失败后的重试机制
This commit is contained in:
@@ -0,0 +1,96 @@
|
|||||||
|
package com.ai.da.common.RabbitMQ;
|
||||||
|
|
||||||
|
|
||||||
|
import com.ai.da.common.utils.MailUtil;
|
||||||
|
import com.ai.da.model.dto.BasicEmailParamDTO;
|
||||||
|
import com.ai.da.service.EmailService;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.rabbitmq.client.Channel;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||||
|
import org.springframework.core.io.InputStreamSource;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import software.amazon.awssdk.core.exception.RetryableException;
|
||||||
|
import org.springframework.amqp.core.Message;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import javax.mail.MessagingException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class EmailRetryConsumer {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MailUtil mailUtil;
|
||||||
|
@Resource
|
||||||
|
private MQPublisher mqPublisher;
|
||||||
|
@Resource
|
||||||
|
private EmailService emailService;
|
||||||
|
|
||||||
|
// @RabbitListener(queues = "#{rabbitMQProperties.deadLetter.queue}")
|
||||||
|
public void handleRetry(Map<String, String> mailParams, Message message, Channel channel) throws IOException {
|
||||||
|
long tag = message.getMessageProperties().getDeliveryTag();
|
||||||
|
try {
|
||||||
|
log.info("死信队列收到消息:{}", message);
|
||||||
|
// 处理邮件发送参数
|
||||||
|
BasicEmailParamDTO basicEmailParamDTO = JSONObject.parseObject(mailParams.get("dto"), BasicEmailParamDTO.class);
|
||||||
|
String fileName = mailParams.get("filename");
|
||||||
|
InputStreamSource inputStreamSource = Objects.isNull(mailParams.get("source")) ?
|
||||||
|
null : JSONObject.parseObject(mailParams.get("source"), InputStreamSource.class);
|
||||||
|
JSONObject templateParams = JSONObject.parseObject(mailParams.get("templateParams"), JSONObject.class);
|
||||||
|
String templateName = mailParams.get("templatePath");
|
||||||
|
long logId = Long.parseLong(mailParams.get("logId"));
|
||||||
|
basicEmailParamDTO.setContent(mailUtil.setContent(templateParams, templateName));
|
||||||
|
// 发邮件
|
||||||
|
int lastReturnCode = mailUtil.sendMail(basicEmailParamDTO, fileName, inputStreamSource);
|
||||||
|
if (lastReturnCode == 250) {
|
||||||
|
log.info("邮件发送成功!Subject : {}", basicEmailParamDTO.getSubject());
|
||||||
|
emailService.updateStatus(logId, EmailService.DELIVERED);
|
||||||
|
} else if (lastReturnCode == 450) {
|
||||||
|
log.info("目标邮箱 {} 暂时不可用,请稍后重试", (Object) basicEmailParamDTO.getMailTo());
|
||||||
|
// 重试
|
||||||
|
retry(mailParams, message, channel, tag, logId);
|
||||||
|
} else if (lastReturnCode == 550) {
|
||||||
|
log.info("目标邮箱 {} 不可用,邮件发送失败", (Object) basicEmailParamDTO.getMailTo());
|
||||||
|
emailService.updateStatus(logId, EmailService.FAILED);
|
||||||
|
} else {
|
||||||
|
log.info("邮件发送失败,Subject : {}, 状态码: {}", basicEmailParamDTO.getSubject(), lastReturnCode);
|
||||||
|
retry(mailParams, message, channel, tag, logId);
|
||||||
|
emailService.updateStatus(logId, EmailService.FAILED);
|
||||||
|
}
|
||||||
|
channel.basicAck(tag, false);
|
||||||
|
} catch (RetryableException e) {
|
||||||
|
log.info("邮件重试发生异常:RetryableException -> {}", e.getMessage());
|
||||||
|
channel.basicAck(tag, false); // 确认原消息
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("邮件重试发生异常:Exception -> {}", e.getMessage());
|
||||||
|
channel.basicAck(tag, false); // 确认原消息
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getRetryAttempt(Message message) {
|
||||||
|
Integer attempt = message.getMessageProperties()
|
||||||
|
.getHeader("x-retry-attempt");
|
||||||
|
return attempt != null ? attempt : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void retry(Map<String, String> mailParams, Message message, Channel channel, long tag, long logId) throws IOException{
|
||||||
|
int attempt = getRetryAttempt(message);
|
||||||
|
if (attempt >= 3) { // 最大重试次数
|
||||||
|
channel.basicReject(tag, false);
|
||||||
|
emailService.updateStatus(logId, EmailService.FAILED);
|
||||||
|
log.error("重试结束,邮件最终发送失败: {}", mailParams);
|
||||||
|
} else {
|
||||||
|
log.info("重新将邮件信息发送到重试队列");
|
||||||
|
mqPublisher.sendEmailMsg(mailParams, attempt);
|
||||||
|
channel.basicAck(tag, false); // 确认原消息
|
||||||
|
// 更新数据库
|
||||||
|
emailService.updateRetryCount(logId, attempt + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.ai.da.common.RabbitMQ;
|
package com.ai.da.common.RabbitMQ;
|
||||||
|
|
||||||
import org.springframework.amqp.core.Queue;
|
import org.springframework.amqp.core.*;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -40,4 +40,43 @@ public class MQConfig {
|
|||||||
public Queue relightResultQueue() {
|
public Queue relightResultQueue() {
|
||||||
return new Queue(rabbitMQProperties.getQueues().getRelightResult());
|
return new Queue(rabbitMQProperties.getQueues().getRelightResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Queue poseTransformQueue() {
|
||||||
|
return new Queue(rabbitMQProperties.getQueues().getPoseTransform());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Queue mailRetryQueue() {
|
||||||
|
// 普通队列,不绑定DLX(首次失败后才进入MQ)
|
||||||
|
// durable 持久化队列
|
||||||
|
return QueueBuilder.durable(rabbitMQProperties.getQueues().getEmailRetry())
|
||||||
|
// 关键参数:绑定死信交换机
|
||||||
|
.withArgument("x-dead-letter-exchange", rabbitMQProperties.getDeadLetter().getExchange())
|
||||||
|
// 可选:指定死信路由键(默认使用原消息的路由键)
|
||||||
|
.withArgument("x-dead-letter-routing-key", rabbitMQProperties.getDeadLetter().getRoutingKey())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增死信交换机
|
||||||
|
@Bean
|
||||||
|
public DirectExchange deadLetterExchange() {
|
||||||
|
return new DirectExchange(rabbitMQProperties.getDeadLetter().getExchange());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增死信队列
|
||||||
|
@Bean
|
||||||
|
public Queue deadLetterQueue() {
|
||||||
|
return QueueBuilder.durable(rabbitMQProperties.getDeadLetter().getQueue()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绑定死信队列
|
||||||
|
@Bean
|
||||||
|
public Binding deadLetterBinding() {
|
||||||
|
return BindingBuilder.bind(deadLetterQueue())
|
||||||
|
.to(deadLetterExchange())
|
||||||
|
.with(rabbitMQProperties.getDeadLetter().getRoutingKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@@ -18,12 +19,38 @@ public class MQPublisher {
|
|||||||
private AmqpTemplate amqpTemplate;
|
private AmqpTemplate amqpTemplate;
|
||||||
|
|
||||||
public void sendGenerateMessage(String mm) {
|
public void sendGenerateMessage(String mm) {
|
||||||
log.info("send message: " + mm);
|
log.info("send generate message: {}", mm);
|
||||||
amqpTemplate.convertAndSend(rabbitMQProperties.getQueues().getGenerate(), mm);
|
amqpTemplate.convertAndSend(rabbitMQProperties.getQueues().getGenerate(), mm);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendSRMessage(String mm) {
|
public void sendSRMessage(String mm) {
|
||||||
log.info("send message: " + mm);
|
log.info("send message: {}", mm);
|
||||||
amqpTemplate.convertAndSend(rabbitMQProperties.getQueues().getSr(), mm);
|
amqpTemplate.convertAndSend(rabbitMQProperties.getQueues().getSr(), mm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param mailParams 含有的字段
|
||||||
|
* {"dto": basicEmailParamDTO, "filename": fileName, "source": inputStreamSource,
|
||||||
|
* "templateParams": jsonObject, "templatePath": path}
|
||||||
|
* 邮件发送参数,附件文件名,附件数据
|
||||||
|
* @param retryTimes 重试次数(初始为0)
|
||||||
|
*/
|
||||||
|
public void sendEmailMsg(Map<String, String> mailParams, int retryTimes){
|
||||||
|
log.info("send email MQ message: {} ", mailParams);
|
||||||
|
// // 重新入队(指数退避) 时间单位:毫秒
|
||||||
|
long newDelay = (long) (5000 * Math.pow(2, retryTimes + 1));
|
||||||
|
log.info("send email MQ delay: {} ms, retry attempt: {}", newDelay, retryTimes + 1);
|
||||||
|
amqpTemplate.convertAndSend(
|
||||||
|
rabbitMQProperties.getQueues().getEmailRetry(),
|
||||||
|
mailParams,
|
||||||
|
m -> {
|
||||||
|
m.getMessageProperties().setExpiration(String.valueOf(newDelay));
|
||||||
|
m.getMessageProperties().setHeader("x-retry-attempt", retryTimes + 1);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ public class RabbitMQProperties {
|
|||||||
|
|
||||||
private Queues queues;
|
private Queues queues;
|
||||||
private Exchange exchange;
|
private Exchange exchange;
|
||||||
|
private DeadLetter deadLetter; // 新增死信配置
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class Queues {
|
public static class Queues {
|
||||||
@@ -21,6 +22,7 @@ public class RabbitMQProperties {
|
|||||||
private String toProductImageResult;
|
private String toProductImageResult;
|
||||||
private String relightResult;
|
private String relightResult;
|
||||||
private String poseTransform;
|
private String poseTransform;
|
||||||
|
private String emailRetry;
|
||||||
private String designBatch;
|
private String designBatch;
|
||||||
private String relightBatch;
|
private String relightBatch;
|
||||||
private String toProductImageBatch;
|
private String toProductImageBatch;
|
||||||
@@ -31,5 +33,13 @@ public class RabbitMQProperties {
|
|||||||
public static class Exchange {
|
public static class Exchange {
|
||||||
private String generate;
|
private String generate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增死信配置内部类
|
||||||
|
@Data
|
||||||
|
public static class DeadLetter {
|
||||||
|
private String exchange;
|
||||||
|
private String queue;
|
||||||
|
private String routingKey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -140,6 +140,14 @@ public class MailUtil {
|
|||||||
return basicEmailParamDTO;
|
return basicEmailParamDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BasicEmailParamDTO setBasicEmailParams(List<String> mailTo, String title) throws AddressException {
|
||||||
|
BasicEmailParamDTO basicEmailParamDTO = new BasicEmailParamDTO();
|
||||||
|
basicEmailParamDTO.setSenderUserMail("info@aida.com.hk");
|
||||||
|
basicEmailParamDTO.setMailTo(getInternetAddressList(mailTo));
|
||||||
|
basicEmailParamDTO.setSubject(title);
|
||||||
|
return basicEmailParamDTO;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将地址转换为InternetAddress类型
|
* 将地址转换为InternetAddress类型
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.data.redis.core.HashOperations;
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.data.redis.core.ZSetOperations;
|
import org.springframework.data.redis.core.ZSetOperations;
|
||||||
|
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
@@ -18,6 +18,8 @@ import javax.annotation.Resource;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -527,4 +529,69 @@ public class RedisUtil {
|
|||||||
return new ProgressDTO(0, 0, false);
|
return new ProgressDTO(0, 0, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lua脚本(原子化操作)
|
||||||
|
/*private static final String RATE_LIMIT_SCRIPT =
|
||||||
|
"local current = redis.call('INCR', KEYS[1])\n" +
|
||||||
|
"if tonumber(current) == 1 then\n" +
|
||||||
|
" redis.call('EXPIRE', KEYS[1], ARGV[1])\n" +
|
||||||
|
"end\n" +
|
||||||
|
"return tonumber(current) <= tonumber(ARGV[2])";*/
|
||||||
|
private static final String RATE_LIMIT_SCRIPT =
|
||||||
|
"local current = redis.call('INCR', KEYS[1])\n" +
|
||||||
|
"local ttl = redis.call('TTL', KEYS[1])\n" +
|
||||||
|
"if tonumber(current) == 1 or tonumber(ttl) == -1 then\n" +
|
||||||
|
" redis.call('EXPIRE', KEYS[1], ARGV[1])\n" +
|
||||||
|
"end\n" +
|
||||||
|
"return tonumber(current) <= tonumber(ARGV[2])";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否允许发送
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return true-允许发送,false-已超限
|
||||||
|
*/
|
||||||
|
public boolean allowSend(Long userId) {
|
||||||
|
String hourKey = getCurrentHourKey(userId);
|
||||||
|
|
||||||
|
// 执行Lua脚本
|
||||||
|
List<String> keys = Collections.singletonList(hourKey);
|
||||||
|
List<Long> args = Arrays.asList(
|
||||||
|
3600L, // 1小时过期
|
||||||
|
10L // 限制数量 一小时只能向普通用户发10封
|
||||||
|
);
|
||||||
|
|
||||||
|
Boolean result = redisTemplate.execute(
|
||||||
|
new DefaultRedisScript<>(RATE_LIMIT_SCRIPT, Boolean.class),
|
||||||
|
keys,
|
||||||
|
args.toArray()
|
||||||
|
);
|
||||||
|
|
||||||
|
return Boolean.TRUE.equals(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前小时的Key
|
||||||
|
* 格式:email_limit:{userId}:{yyyyMMddHH}
|
||||||
|
*/
|
||||||
|
private String getCurrentHourKey(Long userId) {
|
||||||
|
String hour = LocalDateTime.now()
|
||||||
|
.format(DateTimeFormatter.ofPattern("yyyyMMddHH"));
|
||||||
|
return String.format("email_limit:%s:%s", userId, hour);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前已发送数量
|
||||||
|
*/
|
||||||
|
public int getCurrentCount(Long userId) {
|
||||||
|
String key = getCurrentHourKey(userId);
|
||||||
|
String val = redisTemplate.opsForValue().get(key);
|
||||||
|
int count;
|
||||||
|
if (StringUtils.isBlank(val)){
|
||||||
|
count = 0;
|
||||||
|
}else {
|
||||||
|
count = Integer.parseInt(val);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -426,45 +426,7 @@ public class SendEmailUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static Long GENERATE_EXCEPTION_WARNING_ID = 122589L;
|
// todo ?需要保留吗
|
||||||
|
|
||||||
public static void sendGenerateExceptionWarning(String message) {
|
|
||||||
try {
|
|
||||||
// 实例化一个认证对象
|
|
||||||
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
|
||||||
HttpProfile httpProfile = new HttpProfile();
|
|
||||||
httpProfile.setEndpoint("ses.tencentcloudapi.com");
|
|
||||||
ClientProfile clientProfile = new ClientProfile();
|
|
||||||
clientProfile.setHttpProfile(httpProfile);
|
|
||||||
SesClient client = new SesClient(cred, "ap-hongkong", clientProfile);
|
|
||||||
SendEmailRequest req = new SendEmailRequest();
|
|
||||||
req.setFromEmailAddress(CODE_CREATE_SEND_ADDRESS);
|
|
||||||
req.setDestination(new String[]{"xupei3360@163.com"});
|
|
||||||
|
|
||||||
// 根据邮件类型设置不同的主题和模板
|
|
||||||
String subject = "";
|
|
||||||
Template template = new Template();
|
|
||||||
subject = "Warning: AiDA 3.0 Generate Exception Warning";
|
|
||||||
template.setTemplateID(GENERATE_EXCEPTION_WARNING_ID);
|
|
||||||
|
|
||||||
JSONObject parameter = new JSONObject();
|
|
||||||
parameter.put("errorMessage", message);
|
|
||||||
parameter.put("time", DateUtil.dateToStr(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS));
|
|
||||||
|
|
||||||
template.setTemplateData(parameter.toJSONString());
|
|
||||||
|
|
||||||
req.setSubject(subject);
|
|
||||||
req.setTemplate(template);
|
|
||||||
|
|
||||||
// 发送邮件
|
|
||||||
SendEmailResponse resp = client.SendEmail(req);
|
|
||||||
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
|
|
||||||
} catch (TencentCloudSDKException e) {
|
|
||||||
log.info("邮件发送失败###{}", e.toString());
|
|
||||||
throw new BusinessException("failed.to.send.mail");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static Long QUESTIONNAIRE_FEEDBACK_EN_ID = 124151L;
|
private final static Long QUESTIONNAIRE_FEEDBACK_EN_ID = 124151L;
|
||||||
private final static Long QUESTIONNAIRE_FEEDBACK_CN_ID = 124156L;
|
private final static Long QUESTIONNAIRE_FEEDBACK_CN_ID = 124156L;
|
||||||
|
|
||||||
@@ -606,6 +568,7 @@ public class SendEmailUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo 目前该定时器已取消,是否需要保留该模板?
|
||||||
private final static Long NEW_USER_REGISTER_NOTIFICATION_EN = 126919L;
|
private final static Long NEW_USER_REGISTER_NOTIFICATION_EN = 126919L;
|
||||||
|
|
||||||
public static void notificationForRegisterUser(String receiverAddress) {
|
public static void notificationForRegisterUser(String receiverAddress) {
|
||||||
@@ -644,51 +607,6 @@ public class SendEmailUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static Long CHANGE_MAILBOX_CONFIRM_CN = 128278L;
|
|
||||||
private final static Long CHANGE_MAILBOX_CONFIRM_EN = 128277L;
|
|
||||||
|
|
||||||
public static void changeMailboxConfirm(String receiverAddress, String language, String name, String link) {
|
|
||||||
try {
|
|
||||||
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
|
||||||
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
|
||||||
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
|
||||||
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
|
||||||
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
|
||||||
HttpProfile httpProfile = new HttpProfile();
|
|
||||||
httpProfile.setEndpoint("ses.tencentcloudapi.com");
|
|
||||||
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
|
||||||
ClientProfile clientProfile = new ClientProfile();
|
|
||||||
clientProfile.setHttpProfile(httpProfile);
|
|
||||||
// 实例化要请求产品的client对象,clientProfile是可选的
|
|
||||||
SesClient client = new SesClient(cred, "ap-hongkong", clientProfile);
|
|
||||||
// 实例化一个请求对象,每个接口都会对应一个request对象
|
|
||||||
SendEmailRequest req = new SendEmailRequest();
|
|
||||||
req.setFromEmailAddress(SEND_ADDRESS);
|
|
||||||
req.setDestination(new String[]{receiverAddress});
|
|
||||||
Template template = new Template();
|
|
||||||
if (language.equals("ENGLISH")) {
|
|
||||||
req.setSubject("Change the email address bound to the AiDA account");
|
|
||||||
template.setTemplateID(CHANGE_MAILBOX_CONFIRM_EN);
|
|
||||||
} else {
|
|
||||||
req.setSubject("更换AiDA账号绑定的邮箱地址");
|
|
||||||
template.setTemplateID(CHANGE_MAILBOX_CONFIRM_CN);
|
|
||||||
}
|
|
||||||
JSONObject param = new JSONObject();
|
|
||||||
param.put("userName", name);
|
|
||||||
param.put("link", link);
|
|
||||||
|
|
||||||
template.setTemplateData(param.toJSONString());
|
|
||||||
req.setTemplate(template);
|
|
||||||
|
|
||||||
// 返回的resp是一个SendEmailResponse的实例,与请求对象对应
|
|
||||||
SendEmailResponse resp = client.SendEmail(req);
|
|
||||||
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
|
|
||||||
} catch (TencentCloudSDKException e) {
|
|
||||||
log.info("邮件发送失败###{}", e.toString());
|
|
||||||
throw new BusinessException("failed.to.send.mail");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static Long UPLOAD_TIMEOUT_REMINDER = 128324L;
|
private final static Long UPLOAD_TIMEOUT_REMINDER = 128324L;
|
||||||
|
|
||||||
public static void uploadTimeoutReminder(String userName, String time) {
|
public static void uploadTimeoutReminder(String userName, String time) {
|
||||||
@@ -732,7 +650,7 @@ public class SendEmailUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static Long HALFPRICEPROMOTION_CN_ID = 128582L;
|
/*private final static Long HALFPRICEPROMOTION_CN_ID = 128582L;
|
||||||
private final static Long HALFPRICEPROMOTION_EN_ID = 128583L;
|
private final static Long HALFPRICEPROMOTION_EN_ID = 128583L;
|
||||||
|
|
||||||
public static void halfPricePromotion(Account account, String senderAddress, int type) {
|
public static void halfPricePromotion(Account account, String senderAddress, int type) {
|
||||||
@@ -821,7 +739,7 @@ public class SendEmailUtil {
|
|||||||
log.info("邮件发送失败###{}", e.toString());
|
log.info("邮件发送失败###{}", e.toString());
|
||||||
throw new BusinessException("failed.to.send.mail");
|
throw new BusinessException("failed.to.send.mail");
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
private final static Long CANCEL_MERCHANT_EN = 130720L;
|
private final static Long CANCEL_MERCHANT_EN = 130720L;
|
||||||
// private final static Long NEW_MERCHANT_EN = 130721L;
|
// private final static Long NEW_MERCHANT_EN = 130721L;
|
||||||
@@ -1074,4 +992,52 @@ public class SendEmailUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final static Long CN_2025_618 = 141425L;
|
||||||
|
private final static Long EN_2025_618 = 141424L;
|
||||||
|
public static void send618PromotionEmailTemp(String receiver, String language){
|
||||||
|
try {
|
||||||
|
// 实例化一个认证对象
|
||||||
|
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
||||||
|
HttpProfile httpProfile = new HttpProfile();
|
||||||
|
httpProfile.setEndpoint("ses.tencentcloudapi.com");
|
||||||
|
ClientProfile clientProfile = new ClientProfile();
|
||||||
|
clientProfile.setHttpProfile(httpProfile);
|
||||||
|
SesClient client = new SesClient(cred, "ap-hongkong", clientProfile);
|
||||||
|
SendEmailRequest req = new SendEmailRequest();
|
||||||
|
req.setFromEmailAddress(CODE_CREATE_SEND_ADDRESS);
|
||||||
|
req.setDestination(new String[]{receiver});
|
||||||
|
|
||||||
|
// 根据邮件类型设置不同的主题和模板
|
||||||
|
String subject = "";
|
||||||
|
Template template = new Template();
|
||||||
|
// if (type == 1) {
|
||||||
|
// subject = "Upcoming System Upgrade for AiDA 3.0";
|
||||||
|
// template.setTemplateID(UPGRADE_NOTIFICATION_ID);
|
||||||
|
// }else {
|
||||||
|
// subject = "即将到来的AiDA 3.0系统升级";
|
||||||
|
// template.setTemplateID(UPGRADE_NOTIFICATION_ID_CHINESE);
|
||||||
|
// }
|
||||||
|
if (language.equals("ENGLISH")) {
|
||||||
|
subject = "Welcome back !Subscribe AiDA with the discount code to enjoy 50% OFF!";
|
||||||
|
template.setTemplateID(EN_2025_618);
|
||||||
|
}else {
|
||||||
|
subject = "设计时速狂飙!AiDA 618半价让灵感永不限流!";
|
||||||
|
template.setTemplateID(CN_2025_618);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.setSubject(subject);
|
||||||
|
req.setTemplate(template);
|
||||||
|
|
||||||
|
// 发送邮件
|
||||||
|
SendEmailResponse resp = client.SendEmail(req);
|
||||||
|
log.info("邮件发送成功,收件人地址:{}", receiver);
|
||||||
|
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
|
||||||
|
} catch (TencentCloudSDKException e) {
|
||||||
|
log.info(receiver);
|
||||||
|
log.error("邮件发送失败###{},收件人地址:{}", e.toString(), receiver);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ import java.util.List;
|
|||||||
|
|
||||||
public interface EmailService {
|
public interface EmailService {
|
||||||
|
|
||||||
|
String FAILED = "failed";
|
||||||
|
String DELIVERED = "delivered";
|
||||||
|
String RETRYING = "retrying";
|
||||||
|
|
||||||
void loadSingleEmailTemplate(String templatePath);
|
void loadSingleEmailTemplate(String templatePath);
|
||||||
|
|
||||||
@@ -30,6 +33,10 @@ public interface EmailService {
|
|||||||
|
|
||||||
void sendEmail(List<String> mailTo, JSONObject jsonObject, String templateName, String title, String fileName, InputStreamSource inputStreamSource);
|
void sendEmail(List<String> mailTo, JSONObject jsonObject, String templateName, String title, String fileName, InputStreamSource inputStreamSource);
|
||||||
|
|
||||||
|
void updateRetryCount(Long logId, int retryCount);
|
||||||
|
|
||||||
|
void updateStatus(Long logId, String status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 适用于 : 需要自定义发件人信息
|
* 适用于 : 需要自定义发件人信息
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
|||||||
private ProductCouponsMapper productCouponsMapper;
|
private ProductCouponsMapper productCouponsMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private RedisUtil redisUtil;
|
private RedisUtil redisUtil;
|
||||||
|
@Resource
|
||||||
|
private EmailService emailService;
|
||||||
|
|
||||||
// 推广者注册
|
// 推广者注册
|
||||||
public Boolean registerAsAnAffiliate(String promotionMethod){
|
public Boolean registerAsAnAffiliate(String promotionMethod){
|
||||||
@@ -75,6 +77,7 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
|||||||
String developer = "xupei3360@163.com";
|
String developer = "xupei3360@163.com";
|
||||||
String[] receiverEmail = {merchantEmail, developer};
|
String[] receiverEmail = {merchantEmail, developer};
|
||||||
SendEmailUtil.affiliateEmailReminder(receiverEmail, new AffiliateEmailParamsDTO(userHolder.getUsername(), promotionMethod), "new");
|
SendEmailUtil.affiliateEmailReminder(receiverEmail, new AffiliateEmailParamsDTO(userHolder.getUsername(), promotionMethod), "new");
|
||||||
|
// emailService.affiliateEmailReminder(Arrays.asList(/*merchantEmail,*/ developer), new AffiliateEmailParamsDTO(userHolder.getUsername(), promotionMethod), "new");
|
||||||
}else {
|
}else {
|
||||||
throw new BusinessException("You have registered an Affiliate", ResultEnum.PROMPT.getCode());
|
throw new BusinessException("You have registered an Affiliate", ResultEnum.PROMPT.getCode());
|
||||||
}
|
}
|
||||||
@@ -175,8 +178,10 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
|||||||
String userName = account.getUserName();
|
String userName = account.getUserName();
|
||||||
if (isApproved){
|
if (isApproved){
|
||||||
SendEmailUtil.affiliateEmailReminder(userEmail, new AffiliateEmailParamsDTO(userName), "accepted");
|
SendEmailUtil.affiliateEmailReminder(userEmail, new AffiliateEmailParamsDTO(userName), "accepted");
|
||||||
|
// emailService.affiliateEmailReminder(Collections.singletonList(account.getUserEmail()), new AffiliateEmailParamsDTO(userName), "accepted");
|
||||||
}else {
|
}else {
|
||||||
SendEmailUtil.affiliateEmailReminder(userEmail, new AffiliateEmailParamsDTO(userName), "refused");
|
SendEmailUtil.affiliateEmailReminder(userEmail, new AffiliateEmailParamsDTO(userName), "refused");
|
||||||
|
// emailService.affiliateEmailReminder(Collections.singletonList(account.getUserEmail()), new AffiliateEmailParamsDTO(userName), "refused");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -332,6 +337,7 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
|||||||
String[] receiverEmail = {merchantEmail, developer};
|
String[] receiverEmail = {merchantEmail, developer};
|
||||||
// 邮件通知
|
// 邮件通知
|
||||||
SendEmailUtil.affiliateEmailReminder(receiverEmail, affiliateEmailParamsDTO, "summary");
|
SendEmailUtil.affiliateEmailReminder(receiverEmail, affiliateEmailParamsDTO, "summary");
|
||||||
|
// emailService.affiliateEmailReminder(Arrays.asList(/*merchantEmail,*/ developer), affiliateEmailParamsDTO, "summary");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
|
|
||||||
// @Resource
|
// @Resource
|
||||||
// private RedisUtil redisUtil;
|
// private RedisUtil redisUtil;
|
||||||
|
@Resource
|
||||||
|
private EmailService emailService;
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@Override
|
@Override
|
||||||
@@ -138,6 +140,7 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
// 邮件通知 一天最多通知3次
|
// 邮件通知 一天最多通知3次
|
||||||
log.info("上传超过5秒,发送邮件通知");
|
log.info("上传超过5秒,发送邮件通知");
|
||||||
SendEmailUtil.uploadTimeoutReminder(userInfo.getUsername(), String.valueOf(((end - start) / 1000)));
|
SendEmailUtil.uploadTimeoutReminder(userInfo.getUsername(), String.valueOf(((end - start) / 1000)));
|
||||||
|
// emailService.uploadTimeoutReminder(userInfo.getUsername(), String.valueOf(((end - start) / 1000)));
|
||||||
redisUtil.increaseCount(RedisUtil.UPLOAD_TIMEOUT_REMINDER_COUNTER);
|
redisUtil.increaseCount(RedisUtil.UPLOAD_TIMEOUT_REMINDER_COUNTER);
|
||||||
}
|
}
|
||||||
return collectionElementVO;
|
return collectionElementVO;
|
||||||
|
|||||||
@@ -1,16 +1,22 @@
|
|||||||
package com.ai.da.service.impl;
|
package com.ai.da.service.impl;
|
||||||
|
|
||||||
|
import com.ai.da.common.RabbitMQ.MQPublisher;
|
||||||
|
import com.ai.da.common.config.exception.BusinessException;
|
||||||
|
import com.ai.da.common.response.ResultEnum;
|
||||||
import com.ai.da.common.utils.DateUtil;
|
import com.ai.da.common.utils.DateUtil;
|
||||||
import com.ai.da.common.utils.MailUtil;
|
import com.ai.da.common.utils.MailUtil;
|
||||||
|
import com.ai.da.common.utils.RedisUtil;
|
||||||
import com.ai.da.mapper.primary.EmailLogMapper;
|
import com.ai.da.mapper.primary.EmailLogMapper;
|
||||||
import com.ai.da.mapper.primary.EmailTemplateMapper;
|
import com.ai.da.mapper.primary.EmailTemplateMapper;
|
||||||
import com.ai.da.mapper.primary.entity.*;
|
import com.ai.da.mapper.primary.entity.*;
|
||||||
import com.ai.da.model.dto.AffiliateEmailParamsDTO;
|
import com.ai.da.model.dto.AffiliateEmailParamsDTO;
|
||||||
import com.ai.da.model.dto.BasicEmailParamDTO;
|
import com.ai.da.model.dto.BasicEmailParamDTO;
|
||||||
import com.ai.da.model.dto.SubscriptionEmailParamsDTO;
|
import com.ai.da.model.dto.SubscriptionEmailParamsDTO;
|
||||||
|
import com.ai.da.service.AccountService;
|
||||||
import com.ai.da.service.EmailService;
|
import com.ai.da.service.EmailService;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.core.io.InputStreamSource;
|
import org.springframework.core.io.InputStreamSource;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -38,6 +44,12 @@ public class EmailServiceImpl implements EmailService {
|
|||||||
private EmailTemplateMapper emailTemplateMapper;
|
private EmailTemplateMapper emailTemplateMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private EmailLogMapper emailLogMapper;
|
private EmailLogMapper emailLogMapper;
|
||||||
|
@Resource
|
||||||
|
private AccountService accountService;
|
||||||
|
@Resource
|
||||||
|
private RedisUtil redisUtil;
|
||||||
|
@Resource
|
||||||
|
private MQPublisher mqPublisher;
|
||||||
|
|
||||||
public void loadSingleEmailTemplate(String templatePath){
|
public void loadSingleEmailTemplate(String templatePath){
|
||||||
// 获取 ClassLoader
|
// 获取 ClassLoader
|
||||||
@@ -146,6 +158,14 @@ public class EmailServiceImpl implements EmailService {
|
|||||||
* @param inputStreamSource 附件
|
* @param inputStreamSource 附件
|
||||||
*/
|
*/
|
||||||
public void sendEmail(List<String> mailTo, JSONObject jsonObject, String templateName, String title, String fileName, InputStreamSource inputStreamSource) {
|
public void sendEmail(List<String> mailTo, JSONObject jsonObject, String templateName, String title, String fileName, InputStreamSource inputStreamSource) {
|
||||||
|
if (mailTo.size() == 1){
|
||||||
|
String receiver = mailTo.get(0);
|
||||||
|
Account account = accountService.getBaseMapper().selectOne(new QueryWrapper<Account>().eq("user_email", receiver));
|
||||||
|
if (Objects.nonNull(account)){
|
||||||
|
boolean b = redisUtil.allowSend(account.getId());
|
||||||
|
if (!b){throw new BusinessException("email.count.limit", ResultEnum.PROMPT.getCode());}
|
||||||
|
}
|
||||||
|
}
|
||||||
EmailTemplate emailTemplate = getEmailTemplateByName(templateName);
|
EmailTemplate emailTemplate = getEmailTemplateByName(templateName);
|
||||||
if (Objects.isNull(emailTemplate)){
|
if (Objects.isNull(emailTemplate)){
|
||||||
log.error("Email template: {}, dose not exist!", templateName);
|
log.error("Email template: {}, dose not exist!", templateName);
|
||||||
@@ -155,16 +175,6 @@ public class EmailServiceImpl implements EmailService {
|
|||||||
BasicEmailParamDTO basicEmailParamDTO = mailUtil.setBasicEmailParams(mailTo, jsonObject, emailTemplate.getTemplatePath(), title);
|
BasicEmailParamDTO basicEmailParamDTO = mailUtil.setBasicEmailParams(mailTo, jsonObject, emailTemplate.getTemplatePath(), title);
|
||||||
int lastReturnCode = mailUtil.sendMail(basicEmailParamDTO, fileName, inputStreamSource);
|
int lastReturnCode = mailUtil.sendMail(basicEmailParamDTO, fileName, inputStreamSource);
|
||||||
|
|
||||||
if (lastReturnCode == 250) {
|
|
||||||
log.info("邮件发送成功!Subject : {}", basicEmailParamDTO.getSubject());
|
|
||||||
} else if (lastReturnCode == 450) {
|
|
||||||
log.info("目标邮箱 {} 暂时不可用,请稍后重试", mailTo);
|
|
||||||
} else if (lastReturnCode == 550) {
|
|
||||||
log.info("目标邮箱 {} 不可用,邮件发送失败", mailTo);
|
|
||||||
} else {
|
|
||||||
log.info("邮件发送失败,Subject : {}, 状态码: {}", basicEmailParamDTO.getSubject(), lastReturnCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
EmailLog emailLog = new EmailLog();
|
EmailLog emailLog = new EmailLog();
|
||||||
emailLog.setTemplateId(emailTemplate.getId());
|
emailLog.setTemplateId(emailTemplate.getId());
|
||||||
if (Objects.nonNull(jsonObject)) emailLog.setParameter(jsonObject.toString());
|
if (Objects.nonNull(jsonObject)) emailLog.setParameter(jsonObject.toString());
|
||||||
@@ -174,24 +184,79 @@ public class EmailServiceImpl implements EmailService {
|
|||||||
emailLog.setCreateTime(LocalDateTime.now());
|
emailLog.setCreateTime(LocalDateTime.now());
|
||||||
switch (lastReturnCode) {
|
switch (lastReturnCode) {
|
||||||
case 0:
|
case 0:
|
||||||
|
case 550:
|
||||||
|
emailLog.setStatus(FAILED);
|
||||||
break;
|
break;
|
||||||
case 250:
|
case 250:
|
||||||
emailLog.setStatus("delivered");
|
emailLog.setStatus(DELIVERED);
|
||||||
break;
|
break;
|
||||||
case 450:
|
case 450:
|
||||||
emailLog.setStatus("retrying");
|
emailLog.setStatus(RETRYING);
|
||||||
break;
|
|
||||||
case 550:
|
|
||||||
emailLog.setStatus("failed");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
emailLogMapper.insert(emailLog);
|
emailLogMapper.insert(emailLog);
|
||||||
|
|
||||||
|
if (lastReturnCode == 250) {
|
||||||
|
log.info("邮件发送成功!Subject : {}", basicEmailParamDTO.getSubject());
|
||||||
|
} else if (lastReturnCode == 450) {
|
||||||
|
log.info("目标邮箱 {} 暂时不可用,请稍后重试", mailTo);
|
||||||
|
Map<String, String> params = setRetryParams(mailTo, jsonObject, emailTemplate.getTemplatePath(), title, fileName, inputStreamSource, emailLog.getId());
|
||||||
|
// 异步重试
|
||||||
|
mqPublisher.sendEmailMsg(params, 0);
|
||||||
|
// 更新数据库重试次数
|
||||||
|
emailLog.setRetryCount(1);
|
||||||
|
emailLog.setUpdateTime(LocalDateTime.now());
|
||||||
|
emailLogMapper.updateById(emailLog);
|
||||||
|
} else if (lastReturnCode == 550) {
|
||||||
|
log.info("目标邮箱 {} 不可用,邮件发送失败", mailTo);
|
||||||
|
} else {
|
||||||
|
log.info("邮件发送失败,Subject : {}, 状态码: {}", basicEmailParamDTO.getSubject(), lastReturnCode);
|
||||||
|
Map<String, String> params = setRetryParams(mailTo, jsonObject, emailTemplate.getTemplatePath(), title, fileName, inputStreamSource, emailLog.getId());
|
||||||
|
// 异步重试
|
||||||
|
mqPublisher.sendEmailMsg(params, 0);
|
||||||
|
// 更新数据库重试次数
|
||||||
|
emailLog.setRetryCount(1);
|
||||||
|
emailLog.setUpdateTime(LocalDateTime.now());
|
||||||
|
emailLogMapper.updateById(emailLog);
|
||||||
|
}
|
||||||
} catch (MessagingException e) {
|
} catch (MessagingException e) {
|
||||||
|
// 计数回滚
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateRetryCount(Long logId, int retryCount){
|
||||||
|
UpdateWrapper<EmailLog> uw = new UpdateWrapper<>();
|
||||||
|
uw.eq("id", logId);
|
||||||
|
uw.set("retry_count", retryCount);
|
||||||
|
uw.set("update_time", LocalDateTime.now());
|
||||||
|
|
||||||
|
emailLogMapper.update(null, uw);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateStatus(Long logId, String status){
|
||||||
|
UpdateWrapper<EmailLog> uw = new UpdateWrapper<>();
|
||||||
|
uw.eq("id", logId);
|
||||||
|
uw.set("status", status);
|
||||||
|
uw.set("update_time", LocalDateTime.now());
|
||||||
|
|
||||||
|
emailLogMapper.update(null, uw);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> setRetryParams(List<String> mailTo, JSONObject jsonObject, String templatePath,
|
||||||
|
String title, String fileName, InputStreamSource inputStreamSource, Long logId) throws AddressException {
|
||||||
|
BasicEmailParamDTO dto = mailUtil.setBasicEmailParams(mailTo, title);
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
params.put("dto", JSONObject.toJSONString(dto));
|
||||||
|
params.put("filename", fileName);
|
||||||
|
String source = Objects.nonNull(inputStreamSource) ? inputStreamSource.toString() : null;
|
||||||
|
params.put("source", source);
|
||||||
|
params.put("templateParams", JSONObject.toJSONString(jsonObject));
|
||||||
|
params.put("templatePath", templatePath);
|
||||||
|
params.put("logId", logId.toString());
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 适用于 : 需要自定义发件人信息
|
* 适用于 : 需要自定义发件人信息
|
||||||
* @param jsonObject 模板参数
|
* @param jsonObject 模板参数
|
||||||
@@ -246,6 +311,12 @@ public class EmailServiceImpl implements EmailService {
|
|||||||
return emailTemplates.get(0);
|
return emailTemplates.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void asyncRetry(BasicEmailParamDTO basicEmailParamDTO, String fileName, InputStreamSource inputStreamSource){
|
||||||
|
// todo
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 登入主题
|
// 登入主题
|
||||||
public final String LOGIN_SUBJECT = "Log on";
|
public final String LOGIN_SUBJECT = "Log on";
|
||||||
// 忘记密码主题
|
// 忘记密码主题
|
||||||
|
|||||||
@@ -266,6 +266,8 @@ public class StripeServiceImpl implements StripeService {
|
|||||||
return Price.create(priceCreateParams.build());
|
return Price.create(priceCreateParams.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private EmailService emailService;
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Boolean notify(HttpServletRequest request) {
|
public Boolean notify(HttpServletRequest request) {
|
||||||
@@ -1054,6 +1056,7 @@ public class StripeServiceImpl implements StripeService {
|
|||||||
setSubscriptionParams(paymentInfo, subscriptionInfo, orderByOrderNo, emailParamsDTO, language);
|
setSubscriptionParams(paymentInfo, subscriptionInfo, orderByOrderNo, emailParamsDTO, language);
|
||||||
|
|
||||||
boolean b = SendEmailUtil.subscriptionEmailReminder(type, emailParamsDTO, language, account.getUserEmail());
|
boolean b = SendEmailUtil.subscriptionEmailReminder(type, emailParamsDTO, language, account.getUserEmail());
|
||||||
|
// boolean b = emailService.subscriptionEmailReminder(type, emailParamsDTO, language, account.getUserEmail());
|
||||||
if (!b) return false;
|
if (!b) return false;
|
||||||
|
|
||||||
// 邮件通知成功后,更新标志
|
// 邮件通知成功后,更新标志
|
||||||
@@ -1092,6 +1095,7 @@ public class StripeServiceImpl implements StripeService {
|
|||||||
emailParamsDTO.setLast4(paymentInfo.getLast4());
|
emailParamsDTO.setLast4(paymentInfo.getLast4());
|
||||||
|
|
||||||
boolean b = SendEmailUtil.subscriptionEmailReminder("fail_new", emailParamsDTO, language, account.getUserEmail());
|
boolean b = SendEmailUtil.subscriptionEmailReminder("fail_new", emailParamsDTO, language, account.getUserEmail());
|
||||||
|
// boolean b = emailService.subscriptionEmailReminder("fail_new", emailParamsDTO, language, account.getUserEmail());
|
||||||
if (!b) return false;
|
if (!b) return false;
|
||||||
|
|
||||||
// 邮件通知成功后,更新标志
|
// 邮件通知成功后,更新标志
|
||||||
@@ -1154,6 +1158,7 @@ public class StripeServiceImpl implements StripeService {
|
|||||||
|
|
||||||
// 4、发邮件
|
// 4、发邮件
|
||||||
boolean b = SendEmailUtil.subscriptionEmailReminder("fail_renewal", emailParamsDTO, language, account.getUserEmail());
|
boolean b = SendEmailUtil.subscriptionEmailReminder("fail_renewal", emailParamsDTO, language, account.getUserEmail());
|
||||||
|
// boolean b = emailService.subscriptionEmailReminder("fail_renewal", emailParamsDTO, language, account.getUserEmail());
|
||||||
if (!b) return false;
|
if (!b) return false;
|
||||||
|
|
||||||
PaymentInfo payment = new PaymentInfo();
|
PaymentInfo payment = new PaymentInfo();
|
||||||
|
|||||||
Reference in New Issue
Block a user