Commit e03bb3e5 by zhangxingmin

邮件发送

parent cbec3fd9
...@@ -3,7 +3,11 @@ package com.yd.email.api.handler; ...@@ -3,7 +3,11 @@ package com.yd.email.api.handler;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.xxl.job.core.context.XxlJobHelper; import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob; import com.xxl.job.core.handler.annotation.XxlJob;
import com.yd.common.result.Result;
import com.yd.email.api.service.ApiEmailSenderConfigService;
import com.yd.email.api.service.ApiEmailService; import com.yd.email.api.service.ApiEmailService;
import com.yd.email.feign.dto.ApiEmailSenderConfigDto;
import com.yd.email.feign.dto.ApiSendMailDto;
import com.yd.email.feign.enums.EmailTaskStatusEnum; import com.yd.email.feign.enums.EmailTaskStatusEnum;
import com.yd.email.service.model.EmailTask; import com.yd.email.service.model.EmailTask;
import com.yd.email.service.model.EmailTaskRecipients; import com.yd.email.service.model.EmailTaskRecipients;
...@@ -11,6 +15,7 @@ import com.yd.email.service.service.IEmailTaskRecipientsService; ...@@ -11,6 +15,7 @@ import com.yd.email.service.service.IEmailTaskRecipientsService;
import com.yd.email.service.service.IEmailTaskService; import com.yd.email.service.service.IEmailTaskService;
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.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.LocalDateTime; import java.time.LocalDateTime;
...@@ -25,7 +30,7 @@ import java.util.Objects; ...@@ -25,7 +30,7 @@ import java.util.Objects;
*/ */
@Component @Component
@Slf4j @Slf4j
public class MailSendJobHandler { public class EmailSendJobHandler {
@Autowired @Autowired
private IEmailTaskService iEmailTaskService; private IEmailTaskService iEmailTaskService;
...@@ -36,10 +41,13 @@ public class MailSendJobHandler { ...@@ -36,10 +41,13 @@ public class MailSendJobHandler {
@Autowired @Autowired
private ApiEmailService apiEmailService; private ApiEmailService apiEmailService;
@Autowired
private ApiEmailSenderConfigService apiEmailSenderConfigService;
/** /**
* XXL-Job任务执行入口方法 * XXL-Job任务执行入口方法
*/ */
@XxlJob("mailSendJobHandler") @XxlJob("emailSendJobHandler")
public void execute() throws Exception { public void execute() throws Exception {
// 从XXL-Job参数中获取任务ID // 从XXL-Job参数中获取任务ID
String param = XxlJobHelper.getJobParam(); String param = XxlJobHelper.getJobParam();
...@@ -65,6 +73,14 @@ public class MailSendJobHandler { ...@@ -65,6 +73,14 @@ public class MailSendJobHandler {
iEmailTaskService.saveOrUpdate(emailTask); iEmailTaskService.saveOrUpdate(emailTask);
try { try {
//调用邮件服务发送邮件入参DTO
ApiSendMailDto apiSendMailDto = new ApiSendMailDto();
BeanUtils.copyProperties(emailTask,apiSendMailDto);
//根据发件人唯一业务ID获取发件人信息和发件人绑定的服务商信息
Result<ApiEmailSenderConfigDto> result = apiEmailSenderConfigService.getApiEmailSenderConfigDto(emailTask.getSenderBizId());
ApiEmailSenderConfigDto apiEmailSenderConfigDto = result.getData();
BeanUtils.copyProperties(apiEmailSenderConfigDto,apiSendMailDto);
// 查询该任务下的所有收件人信息 // 查询该任务下的所有收件人信息
List<EmailTaskRecipients> recipients = iEmailTaskRecipientsService.queryList(taskBizId); List<EmailTaskRecipients> recipients = iEmailTaskRecipientsService.queryList(taskBizId);
log.info("查询该任务下的所有收件人信息: {}: " + JSON.toJSONString(recipients)); log.info("查询该任务下的所有收件人信息: {}: " + JSON.toJSONString(recipients));
...@@ -77,19 +93,17 @@ public class MailSendJobHandler { ...@@ -77,19 +93,17 @@ public class MailSendJobHandler {
for (EmailTaskRecipients recipient : recipients) { for (EmailTaskRecipients recipient : recipients) {
try { try {
// 处理抄送人列表:将数据库中的逗号分隔字符串转换为List // 处理抄送人列表:将数据库中的逗号分隔字符串转换为List
List<String> ccList = StringUtils.isNotBlank(recipient.getCcEmail()) ? List<String> ccEmailList = StringUtils.isNotBlank(recipient.getCcEmail()) ?
Arrays.asList(recipient.getCcEmail().split(";")) : Arrays.asList(recipient.getCcEmail().split(";")) :
new ArrayList<>(); new ArrayList<>();
log.info("处理抄送人列表:将数据库中的逗号分隔字符串转换为List: {}: " + JSON.toJSONString(ccList)); log.info("处理抄送人列表:将数据库中的逗号分隔字符串转换为List: {}: " + JSON.toJSONString(ccEmailList));
//收件人邮箱(单个)
apiSendMailDto.setReceiveEmail(recipient.getReceiveEmail());
//抄送人邮箱列表
apiSendMailDto.setCcEmailList(ccEmailList);
// 调用邮件服务发送邮件 // 调用邮件服务发送邮件
apiEmailService.sendMail( apiEmailService.sendMail(apiSendMailDto);
emailTask.getSendEmail(), // 发件人地址
recipient.getReceiveEmail(), // 收件人地址
ccList, // 抄送人列表
emailTask.getSubject(), // 邮件主题
emailTask.getContent(), // 邮件内容
emailTask.getAttachmentPath() // 附件路径
);
// 发送成功:更新收件人状态为成功 // 发送成功:更新收件人状态为成功
recipient.setStatus(EmailTaskStatusEnum.SUCCESSFUL.getItemValue()); recipient.setStatus(EmailTaskStatusEnum.SUCCESSFUL.getItemValue());
...@@ -134,4 +148,5 @@ public class MailSendJobHandler { ...@@ -134,4 +148,5 @@ public class MailSendJobHandler {
XxlJobHelper.handleFail("任务执行异常: " + e.getMessage()); XxlJobHelper.handleFail("任务执行异常: " + e.getMessage());
} }
} }
} }
\ No newline at end of file
...@@ -2,6 +2,7 @@ package com.yd.email.api.service; ...@@ -2,6 +2,7 @@ package com.yd.email.api.service;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yd.common.result.Result; import com.yd.common.result.Result;
import com.yd.email.feign.dto.ApiEmailSenderConfigDto;
import com.yd.email.feign.request.ApiEmailSenderConfigAddRequest; import com.yd.email.feign.request.ApiEmailSenderConfigAddRequest;
import com.yd.email.feign.request.ApiEmailSenderConfigEditRequest; import com.yd.email.feign.request.ApiEmailSenderConfigEditRequest;
import com.yd.email.feign.request.ApiEmailSenderConfigPageRequest; import com.yd.email.feign.request.ApiEmailSenderConfigPageRequest;
...@@ -19,4 +20,6 @@ public interface ApiEmailSenderConfigService { ...@@ -19,4 +20,6 @@ public interface ApiEmailSenderConfigService {
Result<ApiEmailSenderConfigDetailResponse> detail(String senderBizId); Result<ApiEmailSenderConfigDetailResponse> detail(String senderBizId);
Result del(String senderBizId); Result del(String senderBizId);
Result<ApiEmailSenderConfigDto> getApiEmailSenderConfigDto(String senderBizId);
} }
package com.yd.email.api.service; package com.yd.email.api.service;
import java.util.List; import com.yd.email.feign.dto.ApiSendMailDto;
public interface ApiEmailService { public interface ApiEmailService {
// 发送邮件的主要方法
void sendMail(String from, String to, List<String> cc, String subject, //发送邮件
String content, String attachmentPath) throws Exception; void sendMail(ApiSendMailDto dto) throws Exception;
} }
package com.yd.email.api.service.impl; package com.yd.email.api.service.impl;
import com.alibaba.fastjson.JSON;
import com.yd.common.enums.CommonEnum; import com.yd.common.enums.CommonEnum;
import com.yd.common.exception.BusinessException; import com.yd.common.exception.BusinessException;
import com.yd.common.result.Result; import com.yd.common.result.Result;
import com.yd.common.utils.DateUtil; import com.yd.common.utils.DateUtil;
import com.yd.common.utils.RandomStringGenerator; import com.yd.common.utils.RandomStringGenerator;
import com.yd.email.api.service.ApiEmailSendService; import com.yd.email.api.service.ApiEmailSendService;
import com.yd.email.api.service.ApiEmailSenderConfigService;
import com.yd.email.api.service.ApiEmailService;
import com.yd.email.api.service.XxlJobService; import com.yd.email.api.service.XxlJobService;
import com.yd.email.feign.dto.ApiEmailSenderConfigDto;
import com.yd.email.feign.dto.ApiSendMailDto;
import com.yd.email.feign.enums.EmailTaskStatusEnum; import com.yd.email.feign.enums.EmailTaskStatusEnum;
import com.yd.email.feign.request.ApiSendEmailRequest; import com.yd.email.feign.request.ApiSendEmailRequest;
import com.yd.email.feign.response.ApiSendEmailResponse; import com.yd.email.feign.response.ApiSendEmailResponse;
...@@ -15,9 +20,14 @@ import com.yd.email.service.model.EmailTaskRecipients; ...@@ -15,9 +20,14 @@ import com.yd.email.service.model.EmailTaskRecipients;
import com.yd.email.service.service.IEmailTaskRecipientsService; import com.yd.email.service.service.IEmailTaskRecipientsService;
import com.yd.email.service.service.IEmailTaskService; import com.yd.email.service.service.IEmailTaskService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -38,6 +48,12 @@ public class ApiEmailSendServiceImpl implements ApiEmailSendService { ...@@ -38,6 +48,12 @@ public class ApiEmailSendServiceImpl implements ApiEmailSendService {
@Autowired @Autowired
private IEmailTaskRecipientsService iEmailTaskRecipientsService; private IEmailTaskRecipientsService iEmailTaskRecipientsService;
@Autowired
private ApiEmailSenderConfigService apiEmailSenderConfigService;
@Autowired
private ApiEmailService apiEmailService;
/** /**
* 发送邮件 * 发送邮件
* @param request * @param request
...@@ -74,8 +90,9 @@ public class ApiEmailSendServiceImpl implements ApiEmailSendService { ...@@ -74,8 +90,9 @@ public class ApiEmailSendServiceImpl implements ApiEmailSendService {
String taskBizId = mailTask.getTaskBizId(); String taskBizId = mailTask.getTaskBizId();
// 保存收件人信息 // 保存收件人信息
List<EmailTaskRecipients> recipientsList = new ArrayList<>();
if (!CollectionUtils.isEmpty(request.getRecipientsDtoList())) { if (!CollectionUtils.isEmpty(request.getRecipientsDtoList())) {
List<EmailTaskRecipients> recipientsList = request.getRecipientsDtoList() recipientsList = request.getRecipientsDtoList()
.stream().map(dto -> { .stream().map(dto -> {
EmailTaskRecipients mailRecipient = new EmailTaskRecipients(); EmailTaskRecipients mailRecipient = new EmailTaskRecipients();
//邮件任务唯一业务ID //邮件任务唯一业务ID
...@@ -93,8 +110,11 @@ public class ApiEmailSendServiceImpl implements ApiEmailSendService { ...@@ -93,8 +110,11 @@ public class ApiEmailSendServiceImpl implements ApiEmailSendService {
//计划发送时间(为空表示立即发送,不为空表示定时发送) //计划发送时间(为空表示立即发送,不为空表示定时发送)
String jobId = ""; String jobId = "";
if (!Objects.isNull(request.getScheduleTime())) { if (!Objects.isNull(request.getScheduleTime())) {
//创建XXL-Job定时任务 //不为空表示定时发送:创建XXL-Job定时任务
jobId = xxlJobService.addScheduleJob(taskBizId, DateUtil.convertDateByLocalDateTime(request.getScheduleTime())); jobId = xxlJobService.addScheduleJob(taskBizId, DateUtil.convertDateByLocalDateTime(request.getScheduleTime()));
}else {
//为空表示立即发送
sendImmediatelyEmail(mailTask,recipientsList);
} }
response.setJobId(jobId); response.setJobId(jobId);
response.setScheduleTime(request.getScheduleTime()); response.setScheduleTime(request.getScheduleTime());
...@@ -102,7 +122,92 @@ public class ApiEmailSendServiceImpl implements ApiEmailSendService { ...@@ -102,7 +122,92 @@ public class ApiEmailSendServiceImpl implements ApiEmailSendService {
return Result.success(response); return Result.success(response);
} catch (Exception e) { } catch (Exception e) {
log.error("创建邮件发送任务失败", e); log.error("创建邮件发送任务失败", e);
throw new BusinessException("创建邮件发送任务失败"); throw new BusinessException("发送邮件异常");
}
}
/**
* 立即发送邮件
* @param emailTask
* @param recipients
* @return
*/
public Result sendImmediatelyEmail(EmailTask emailTask,List<EmailTaskRecipients> recipients) {
try {
//调用邮件服务发送邮件入参DTO
ApiSendMailDto apiSendMailDto = new ApiSendMailDto();
BeanUtils.copyProperties(emailTask,apiSendMailDto);
//根据发件人唯一业务ID获取发件人信息和发件人绑定的服务商信息
Result<ApiEmailSenderConfigDto> result = apiEmailSenderConfigService.getApiEmailSenderConfigDto(emailTask.getSenderBizId());
ApiEmailSenderConfigDto apiEmailSenderConfigDto = result.getData();
BeanUtils.copyProperties(apiEmailSenderConfigDto,apiSendMailDto);
//该任务下的所有收件人信息
log.info("查询该任务下的所有收件人信息: {}: " + JSON.toJSONString(recipients));
// 初始化成功和失败计数器
int successCount = 0;
int failCount = 0;
// 遍历所有收件人,逐个发送邮件
for (EmailTaskRecipients recipient : recipients) {
try {
// 处理抄送人列表:将数据库中的逗号分隔字符串转换为List
List<String> ccEmailList = StringUtils.isNotBlank(recipient.getCcEmail()) ?
Arrays.asList(recipient.getCcEmail().split(";")) :
new ArrayList<>();
log.info("处理抄送人列表:将数据库中的逗号分隔字符串转换为List: {}: " + JSON.toJSONString(ccEmailList));
//收件人邮箱(单个)
apiSendMailDto.setReceiveEmail(recipient.getReceiveEmail());
//抄送人邮箱列表
apiSendMailDto.setCcEmailList(ccEmailList);
// 调用邮件服务发送邮件
apiEmailService.sendMail(apiSendMailDto);
// 发送成功:更新收件人状态为成功
recipient.setStatus(EmailTaskStatusEnum.SUCCESSFUL.getItemValue());
recipient.setSendTime(LocalDateTime.now()); // 记录实际发送时间
iEmailTaskRecipientsService.saveOrUpdate(recipient);
successCount++; // 成功计数加1
} catch (Exception e) {
// 发送失败:记录错误日志
log.error("发送邮件失败: {}", recipient.getReceiveEmail(), e);
// 更新收件人状态为失败
recipient.setStatus(EmailTaskStatusEnum.FAILED.getItemValue());
recipient.setErrorMsg(e.getMessage()); // 保存错误信息
iEmailTaskRecipientsService.saveOrUpdate(recipient);
failCount++; // 失败计数加1
}
}
// 根据发送结果更新邮件任务状态
emailTask.setStatus(failCount == 0 ?
EmailTaskStatusEnum.ALL_SUCCESSFUL.getItemValue() :
EmailTaskStatusEnum.PARTIAL_FAILURE.getItemValue());
iEmailTaskService.saveOrUpdate(emailTask);
// 记录任务完成日志
log.info("邮件发送任务完成: 成功{}个, 失败{}个", successCount, failCount);
// 设置任务执行结果
if (failCount == 0) {
log.info("发送完成: 成功" + successCount + "个");
} else {
log.info("发送完成: 成功" + successCount + "个, 失败" + failCount + "个");
}
} catch (Exception e) {
// 任务执行过程中发生异常
log.error("邮件发送任务执行异常", e);
// 更新任务状态为全部发送失败
emailTask.setStatus(EmailTaskStatusEnum.ALL_FAILED.getItemValue());
iEmailTaskService.saveOrUpdate(emailTask);
// 返回任务执行异常信息
log.error("任务执行异常: " + e.getMessage());
throw new BusinessException("立即发送邮件异常");
} }
return Result.success();
} }
} }
...@@ -9,6 +9,7 @@ import com.yd.common.result.Result; ...@@ -9,6 +9,7 @@ import com.yd.common.result.Result;
import com.yd.common.utils.RandomStringGenerator; import com.yd.common.utils.RandomStringGenerator;
import com.yd.email.api.service.ApiEmailProviderConfigService; import com.yd.email.api.service.ApiEmailProviderConfigService;
import com.yd.email.api.service.ApiEmailSenderConfigService; import com.yd.email.api.service.ApiEmailSenderConfigService;
import com.yd.email.feign.dto.ApiEmailSenderConfigDto;
import com.yd.email.feign.request.ApiEmailSenderConfigAddRequest; import com.yd.email.feign.request.ApiEmailSenderConfigAddRequest;
import com.yd.email.feign.request.ApiEmailSenderConfigEditRequest; import com.yd.email.feign.request.ApiEmailSenderConfigEditRequest;
import com.yd.email.feign.request.ApiEmailSenderConfigPageRequest; import com.yd.email.feign.request.ApiEmailSenderConfigPageRequest;
...@@ -140,6 +141,31 @@ public class ApiEmailSenderConfigServiceImpl implements ApiEmailSenderConfigServ ...@@ -140,6 +141,31 @@ public class ApiEmailSenderConfigServiceImpl implements ApiEmailSenderConfigServ
} }
/** /**
* 根据发件人唯一业务ID获取发件人信息和发件人绑定的服务商信息
* @param senderBizId 发件人唯一业务ID
* @return
*/
@Override
public Result<ApiEmailSenderConfigDto> getApiEmailSenderConfigDto(String senderBizId) {
ApiEmailSenderConfigDto response = new ApiEmailSenderConfigDto();
//校验邮件发件人是否存在
Result<EmailSenderConfig> result = checkEmailSenderConfigIsExist(senderBizId);
EmailSenderConfig emailSenderConfig = result.getData();
//校验邮箱服务商是否存在
Result<EmailProviderConfig> result1 = apiEmailProviderConfigService.checkEmailProviderConfigIsExist(emailSenderConfig.getProviderBizId());
EmailProviderConfig emailProviderConfig = result1.getData();
//拷贝发件人信息
BeanUtils.copyProperties(emailSenderConfig,response);
//拷贝邮件服务商信息
BeanUtils.copyProperties(emailProviderConfig,response);
response.setSendEmail(emailSenderConfig.getEmail());
//发件人邮箱-是否设置SMTP需要身份验证 默认true
response.setMailSmtpAuth("true");
response.setStarttlsEnable("true");
return Result.success(response);
}
/**
* 校验邮件发件人是否存在 * 校验邮件发件人是否存在
* @param senderBizId * @param senderBizId
* @return * @return
......
...@@ -2,10 +2,13 @@ package com.yd.email.api.service.impl; ...@@ -2,10 +2,13 @@ package com.yd.email.api.service.impl;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.yd.email.api.service.ApiEmailService; import com.yd.email.api.service.ApiEmailService;
import com.yd.email.feign.dto.ApiSendMailDto;
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.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.activation.DataHandler; import javax.activation.DataHandler;
import javax.activation.DataSource; import javax.activation.DataSource;
import javax.activation.FileDataSource; import javax.activation.FileDataSource;
...@@ -35,37 +38,42 @@ public class ApiEmailServiceImpl implements ApiEmailService { ...@@ -35,37 +38,42 @@ public class ApiEmailServiceImpl implements ApiEmailService {
@Value("${spring.mail.password}") // 从配置文件中注入发件人密码 @Value("${spring.mail.password}") // 从配置文件中注入发件人密码
private String password; private String password;
// @Autowired // 自动注入邮件任务Mapper(数据库操作接口) /**
// private MailTaskMapper mailTaskMapper; * 发送邮件
// * @param dto
// @Autowired // 自动注入邮件收件人Mapper(数据库操作接口) * @throws Exception
// private MailRecipientMapper mailRecipientMapper; */
// 发送邮件的主要方法
@Override @Override
public void sendMail(String from, String to, List<String> cc, String subject, public void sendMail(ApiSendMailDto dto) throws Exception {
String content, String attachmentPath) throws Exception { log.info("发送邮件的主要方法参数: {}: "
log.info("发送邮件的主要方法参数: {}: " + from + ";" + to + ";" + JSON.toJSONString(cc) + ";" + subject + ";" + content ); + dto.getSendEmail() + ";"
+ dto.getReceiveEmail() + ";"
+ JSON.toJSONString(dto.getCcEmailList())
+ ";" + dto.getSubject() + ";" + dto.getContent() );
// 创建邮件配置属性对象 // 创建邮件配置属性对象
Properties props = new Properties(); Properties props = new Properties();
// 设置SMTP需要身份验证 // 设置SMTP需要身份验证
props.put("mail.smtp.auth", "true"); props.put("mail.smtp.auth", dto.getMailSmtpAuth());
// 启用TLS加密传输 // 启用TLS加密传输
props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.starttls.enable", dto.getStarttlsEnable());
// 设置邮件服务器主机名 // 设置邮件服务器主机名(发件人邮箱-SMTP服务器地址)
props.put("mail.smtp.host", host); props.put("mail.smtp.host", dto.getSmtpHost());
log.info("mail.smtp.host:{}",host); log.info("mail.smtp.host:{}",dto.getSmtpHost());
log.info("spring.mail.username:{}",username); //发件人邮箱(单个)
log.info("spring.mail.password:{}",password); log.info("spring.mail.username:{}",dto.getSendEmail());
//发件人邮箱密码或授权码
log.info("spring.mail.password:{}",dto.getPassword());
// 设置邮件服务器端口号(587是TLS标准端口) // 设置邮件服务器端口号(587是TLS标准端口)
props.put("mail.smtp.port", "587"); //发件人邮箱-SMTP服务器端口
props.put("mail.smtp.port", dto.getSmtpPort());
// 创建邮件会话对象,传入配置和认证器 // 创建邮件会话对象,传入配置和认证器
Session session = Session.getInstance(props, new Authenticator() { Session session = Session.getInstance(props, new Authenticator() {
// 重写获取密码认证的方法 // 重写获取密码认证的方法
protected PasswordAuthentication getPasswordAuthentication() { protected PasswordAuthentication getPasswordAuthentication() {
// 返回用户名密码认证对象 // 返回用户名密码认证对象
return new PasswordAuthentication(username, password); return new PasswordAuthentication(dto.getSendEmail(), dto.getPassword());
} }
}); });
...@@ -74,27 +82,27 @@ public class ApiEmailServiceImpl implements ApiEmailService { ...@@ -74,27 +82,27 @@ public class ApiEmailServiceImpl implements ApiEmailService {
// 创建MIME类型邮件消息对象 // 创建MIME类型邮件消息对象
Message message = new MimeMessage(session); Message message = new MimeMessage(session);
// 设置发件人地址 // 设置发件人地址
message.setFrom(new InternetAddress(from)); message.setFrom(new InternetAddress(dto.getSendEmail()));
// 设置收件人地址(支持多个收件人,用逗号分隔) // 设置收件人地址(支持多个收件人,用逗号分隔)
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(dto.getReceiveEmail()));
// 判断是否有抄送人 // 判断是否有抄送人
if (cc != null && !cc.isEmpty()) { if (!CollectionUtils.isEmpty(dto.getCcEmailList())) {
// 将抄送人列表转换为逗号分隔的字符串 // 将抄送人列表转换为逗号分隔的字符串
String ccAddresses = String.join(",", cc); String ccAddresses = String.join(",", dto.getCcEmailList());
// 设置抄送人地址 // 设置抄送人地址
message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(ccAddresses)); message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(ccAddresses));
} }
// 设置邮件主题 // 设置邮件主题
message.setSubject(subject); message.setSubject(dto.getSubject());
// 设置邮件发送时间(当前时间) // 设置邮件发送时间(当前时间)
message.setSentDate(new Date()); message.setSentDate(new Date());
// 创建邮件正文部分 // 创建邮件正文部分
MimeBodyPart messageBodyPart = new MimeBodyPart(); MimeBodyPart messageBodyPart = new MimeBodyPart();
// 设置正文内容,指定HTML格式和UTF-8编码 // 设置正文内容,指定HTML格式和UTF-8编码
messageBodyPart.setContent(content, "text/html;charset=utf-8"); messageBodyPart.setContent(dto.getContent(), "text/html;charset=utf-8");
// 创建多部分内容容器(用于组合正文和附件) // 创建多部分内容容器(用于组合正文和附件)
Multipart multipart = new MimeMultipart(); Multipart multipart = new MimeMultipart();
...@@ -102,15 +110,15 @@ public class ApiEmailServiceImpl implements ApiEmailService { ...@@ -102,15 +110,15 @@ public class ApiEmailServiceImpl implements ApiEmailService {
multipart.addBodyPart(messageBodyPart); multipart.addBodyPart(messageBodyPart);
// 判断是否有附件路径 // 判断是否有附件路径
if (StringUtils.isNotBlank(attachmentPath)) { if (StringUtils.isNotBlank(dto.getAttachmentPath())) {
// 创建附件部分 // 创建附件部分
MimeBodyPart attachmentPart = new MimeBodyPart(); MimeBodyPart attachmentPart = new MimeBodyPart();
// 创建文件数据源 // 创建文件数据源
DataSource source = new FileDataSource(attachmentPath); DataSource source = new FileDataSource(dto.getAttachmentPath());
// 设置附件的数据处理器 // 设置附件的数据处理器
attachmentPart.setDataHandler(new DataHandler(source)); attachmentPart.setDataHandler(new DataHandler(source));
// 设置附件文件名(使用原文件名) // 设置附件文件名(使用原文件名)
attachmentPart.setFileName(new File(attachmentPath).getName()); attachmentPart.setFileName(new File(dto.getAttachmentPath()).getName());
// 将附件部分添加到多部分容器中 // 将附件部分添加到多部分容器中
multipart.addBodyPart(attachmentPart); multipart.addBodyPart(attachmentPart);
} }
...@@ -121,14 +129,15 @@ public class ApiEmailServiceImpl implements ApiEmailService { ...@@ -121,14 +129,15 @@ public class ApiEmailServiceImpl implements ApiEmailService {
// 发送邮件 // 发送邮件
Transport.send(message); Transport.send(message);
// 记录成功日志 // 记录成功日志
log.info("邮件发送成功: {} -> {}", from, to); log.info("邮件发送成功: {} -> {}", dto.getSendEmail(), dto.getReceiveEmail());
log.info("发送邮件Transport.send(message) {}", JSON.toJSONString(message)); log.info("发送邮件Transport.send(message) {}", JSON.toJSONString(message));
} catch (MessagingException e) { } catch (MessagingException e) {
// 记录失败日志,包含异常信息 // 记录失败日志,包含异常信息
log.error("邮件发送失败: {} -> {}", from, to, e); log.error("邮件发送失败: {} -> {}", dto.getSendEmail(), dto.getReceiveEmail(), e);
// 抛出运行时异常 // 抛出运行时异常
throw new RuntimeException("邮件发送失败: " + e.getMessage()); throw new RuntimeException("邮件发送失败: " + e.getMessage());
} }
} }
} }
\ No newline at end of file
...@@ -39,12 +39,13 @@ public class XxlJobServiceImpl implements XxlJobService { ...@@ -39,12 +39,13 @@ public class XxlJobServiceImpl implements XxlJobService {
// 添加API路径常量 // 添加API路径常量
private static final String API_LOGIN = "/login"; private static final String API_LOGIN = "/login";
private static final String API_JOB_GROUP_LIST = "/jobgroup/pageList"; // 可能是这个路径 private static final String API_JOB_GROUP_LIST = "/jobgroup/pageList";
private static final String API_JOB_ADD = "/jobinfo/add"; private static final String API_JOB_ADD = "/jobinfo/add";
private static final String API_JOB_START = "/jobinfo/start"; private static final String API_JOB_START = "/jobinfo/start";
/** /**
* 登录XXL-Job获取认证Cookie * 登录XXL-Job获取认证Cookie
* @return
*/ */
private boolean loginXxlJob() { private boolean loginXxlJob() {
try { try {
...@@ -77,6 +78,12 @@ public class XxlJobServiceImpl implements XxlJobService { ...@@ -77,6 +78,12 @@ public class XxlJobServiceImpl implements XxlJobService {
} }
} }
/**
* 创建XXL-Job定时任务
* @param taskBizId
* @param scheduleTime
* @return
*/
@Override @Override
public String addScheduleJob(String taskBizId, Date scheduleTime) { public String addScheduleJob(String taskBizId, Date scheduleTime) {
try { try {
...@@ -100,7 +107,7 @@ public class XxlJobServiceImpl implements XxlJobService { ...@@ -100,7 +107,7 @@ public class XxlJobServiceImpl implements XxlJobService {
params.add("scheduleType", "CRON"); params.add("scheduleType", "CRON");
params.add("scheduleConf", cronExpression); params.add("scheduleConf", cronExpression);
params.add("glueType", "BEAN"); params.add("glueType", "BEAN");
params.add("executorHandler", "mailSendJobHandler"); params.add("executorHandler", "emailSendJobHandler");
params.add("executorParam", taskBizId); params.add("executorParam", taskBizId);
params.add("executorRouteStrategy", "FIRST"); params.add("executorRouteStrategy", "FIRST");
params.add("misfireStrategy", "DO_NOTHING"); params.add("misfireStrategy", "DO_NOTHING");
...@@ -146,7 +153,9 @@ public class XxlJobServiceImpl implements XxlJobService { ...@@ -146,7 +153,9 @@ public class XxlJobServiceImpl implements XxlJobService {
} }
/** /**
* 根据执行器AppName获取执行器ID - 修复版本 * 根据执行器AppName获取执行器ID
* @param appName
* @return
*/ */
private Integer getExecutorGroupId(String appName) { private Integer getExecutorGroupId(String appName) {
try { try {
...@@ -174,6 +183,12 @@ public class XxlJobServiceImpl implements XxlJobService { ...@@ -174,6 +183,12 @@ public class XxlJobServiceImpl implements XxlJobService {
} }
} }
/**
* 获取执行器ID
* @param appName
* @param apiPath
* @return
*/
private Integer tryGetExecutorGroupId(String appName, String apiPath) { private Integer tryGetExecutorGroupId(String appName, String apiPath) {
try { try {
String url = adminAddresses + apiPath; String url = adminAddresses + apiPath;
...@@ -236,6 +251,8 @@ public class XxlJobServiceImpl implements XxlJobService { ...@@ -236,6 +251,8 @@ public class XxlJobServiceImpl implements XxlJobService {
/** /**
* 启动XXL-Job任务 * 启动XXL-Job任务
* @param jobId
* @return
*/ */
private boolean startJob(String jobId) { private boolean startJob(String jobId) {
try { try {
...@@ -264,6 +281,11 @@ public class XxlJobServiceImpl implements XxlJobService { ...@@ -264,6 +281,11 @@ public class XxlJobServiceImpl implements XxlJobService {
} }
} }
/**
* date转成Cron表达式
* @param date
* @return
*/
private String convertDateToCron(Date date) { private String convertDateToCron(Date date) {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.setTime(date); calendar.setTime(date);
...@@ -282,10 +304,6 @@ public class XxlJobServiceImpl implements XxlJobService { ...@@ -282,10 +304,6 @@ public class XxlJobServiceImpl implements XxlJobService {
* 从XXL-Job响应中提取真实的jobId * 从XXL-Job响应中提取真实的jobId
* 响应格式: {"code":200,"msg":null,"content":"6"} * 响应格式: {"code":200,"msg":null,"content":"6"}
*/ */
/**
* 从XXL-Job响应中提取真实的jobId
* 响应格式: {"code":200,"msg":null,"content":"6"}
*/
private String extractJobId(String responseBody) { private String extractJobId(String responseBody) {
try { try {
log.info("XXL-Job响应: {}", responseBody); log.info("XXL-Job响应: {}", responseBody);
......
package com.yd.email.feign.dto;
import lombok.Data;
/**
* 邮件发件人配置DTO
*/
@Data
public class ApiEmailSenderConfigDto {
/**
* 发件人唯一业务ID
*/
private String senderBizId;
/**
* 发件人显示名称(姓名/昵称)
*/
private String displayName;
/**
* 发件人邮箱(单个)*
*/
private String sendEmail;
/**
* 发件人邮箱密码或授权码
*/
private String password;
/**
* 是否启用该配置: 0-否, 1-是(字典)
*/
private Integer active;
/**
* 邮箱服务商唯一业务ID
*/
private String providerBizId;
/**
* 邮箱服务商名称
*/
private String providerName;
/**
* 发件人邮箱-SMTP服务器地址
*/
private String smtpHost;
/**
* 发件人邮箱-SMTP服务器端口
*/
private Integer smtpPort;
/**
* 是否启用SSL加密: 0-否, 1-是
*/
private Integer sslEnabled;
/**
* 发件人邮箱-是否设置SMTP需要身份验证 默认true
*/
private String mailSmtpAuth;
/**
* 发件人邮箱-是否启用TLS加密传输 默认true
*/
private String starttlsEnable;
}
package com.yd.email.feign.dto;
import lombok.Data;
import java.util.List;
/**
* 调用邮件服务发送邮件入参DTO
*/
@Data
public class ApiSendMailDto {
/**
* 邮件主题 *
*/
private String subject;
/**
* 邮件内容 *
*/
private String content;
/**
* 发送邮件的附件路径(多个用分号分隔)*
*/
private String attachmentPath;
/**
* 收件人邮箱(单个)
*/
private String receiveEmail;
/**
* 抄送人邮箱列表
*/
private List<String> ccEmailList;
/**
* 发件人邮箱(单个)*
*/
private String sendEmail;
/**
* 发件人邮箱密码或授权码
*/
private String password;
/**
* 发件人邮箱-是否设置SMTP需要身份验证 默认true
*/
private String mailSmtpAuth;
/**
* 发件人邮箱-是否启用TLS加密传输 默认true
*/
private String starttlsEnable;
/**
* 发件人邮箱-SMTP服务器地址
*/
private String smtpHost;
/**
* 发件人邮箱-SMTP服务器端口
*/
private Integer smtpPort;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment