需求:
从数据库查出数据,生成excel表格作为附件,用RabbitMQ发邮件
这里采用的的网易邮箱,要去用来发件的邮箱账号的设置里把POP3/SMTP/IMAP服务打开
org.springframework.boot
spring-boot-starter-mail
spring:
#邮箱配置
mail:
host: smtp.163.com
username: [email protected] #用来发邮箱的邮箱账号
password: xxxxxxxxxxxxxx #打开POP3/SMTP/IMAP服务后,网易会给的邮箱密码
port: 465 # 这个端口根据实际情况配置,一般都是465
protocol: smtp # 这里应该是不用改的
test-connection: false
default-encoding: UTF-8
properties:
mail:
# debug: true
smtp:
auth: true
connectiontimeout: 10000
timeout: 10000
writetimeout: 10000
socketFactory:
class: javax.net.ssl.SSLSocketFactory
port: 465
starttls:
enable: true
required: true
/**
* 发货-B端常规订单邮件发货
* @param consignmentVO
* @return
*/
@PostMapping("/sendOutConsignmentToBMailResend")
public Result sendOutConsignmentToBMailResend (@RequestBody ConsignmentVO consignmentVO) {
try {
outConsignmentService.sendOutConsignmentToBMailResend(consignmentVO);
return FtResultUtil.success();
} catch (Exception e) {
e.printStackTrace();
return FtResultUtil.error(e.getMessage());
}
}
/**
* 发货-B端常规订单邮件发货
* @param consignmentVO
* @return
*/
void sendOutConsignmentToBMailResend(ConsignmentVO consignmentVO);
/**
文件存储地址,
* file:
* uploadPath: D:/files/
* docPath: D:/pdfData/
* excelPath: D:/excel/
*/
@Autowired
private FileUploadConfig fileUploadConfig;
/**
* 发货-B端常规订单邮件发货
*
* @param consignmentVO
* @return
*/
@Override
public void sendOutConsignmentToBMailResend(ConsignmentVO consignmentVO) {
//根据发货表id 查询对应的发货明细中所有的明细集合
Long outConsignmentId = consignmentVO.getOutConsignmentId();
QueryWrapper outConsignmentDetailQueryWrapper = new QueryWrapper<>();
outConsignmentDetailQueryWrapper.eq("cond.out_consignment_id", outConsignmentId);
//outConsignmentDetailQueryWrapper.eq("cond.consignment_status", 1);
outConsignmentDetailQueryWrapper.groupBy("outd.order_details_id");
List outConsignmentList = outConsignmentDetailMapper.selectConsignmentDetailList(outConsignmentDetailQueryWrapper);
if (CollectionUtils.isEmpty(outConsignmentList)) {
throw new RuntimeException("订单数据为null,数据库异常");
}
//----------上边就是查询数据库得到数据集合的代码,下边就是生成表格的代码---------------------------------------------------------------
//2把发货明细集合填充进表格
//定义表格存储全地址
String excelPathAll = "";
try {
//模板路径
String templateFileName = "/templates/orderToBMail.xlsx";
InputStream templateInputStream = this.getClass().getResourceAsStream(templateFileName);
//服务器存储的文件夹地址 wind :D:/excel/
String excelPath = fileUploadConfig.getExcelPath();
//当前日期+UUID作为文件名称
String excelName = LocalDate.now() + "-" + UUID.randomUUID().toString().replaceAll("-", "") + ".xlsx";
//创建输出流
OutputStream out = new FileOutputStream(excelPath + excelName);
//3把表格写到指定文件夹
EasyExcel.write(out, ConsignmentVO.class).withTemplate(templateInputStream).sheet().doFill(outConsignmentList);
//表格存储全地址,文件夹+文件名
excelPathAll = excelPath + excelName;
} catch (FileNotFoundException e) {
throw new RuntimeException("导出表格失败");
}
//封装邮件对象
MailVO mailVO = new MailVO();
//邮件主题
mailVO.setSubject(outConsignmentList.get(0).getBusinessPerson());
//邮件收件人
mailVO.setReceiverEmail(outConsignmentList.get(0).getBusinessMail());
//邮件文本
mailVO.setText(outConsignmentList.get(0).getBusinessPerson());
//邮件附件文件地址
mailVO.setFileUrl(excelPathAll);
//5.mq发消息
rabbitService.sendMessage("mailConsignmentExchangeResend", "mailConsignmentRoutingResend", mailVO);
}
@Autowired
private JavaMailSender mailSender;
@Value("${spring.mail.username}")//写入配置文件中的发件人邮箱账号
private String senderEmail;
//发货-B端常规订单邮件重发, @RabbitListener注解指定交换机,队列,routingKey
@RabbitListener(bindings = @QueueBinding(
exchange = @Exchange(value = "mailConsignmentExchangeResend")
, value = @Queue(value = "mailConsignmentQueueResend", durable = "true", autoDelete = "false")//durable持久化,autoDelete是否自动删除
, key = "mailConsignmentRoutingResend"
))
public void mailConsignmentListenerResend(MailVO mailVO , Message message, Channel channel) {
try {
//5.监听消息,发邮件,这里没有做集群下重复消费的验证,可以优化完善
System.out.println("接收到消息" + message);
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
mimeMessageHelper.setFrom(new InternetAddress("<" + senderEmail + ">"));
//收件人
String receiver = mailVO.getReceiverEmail();
mimeMessageHelper.setTo(receiver);
//主题
mimeMessageHelper.setSubject(mailVO.getSubject());
//文本
mimeMessageHelper.setText(mailVO.getText(), true);
//发送时间
mimeMessageHelper.setSentDate(new Date());
if (!StringUtils.isEmpty(mailVO.getFileUrl())) {
//文件的地址
String fileUrls = mailVO.getFileUrl();
File file = new File(fileUrls);
String fileName = file.getName();
//附件,参数1附件名,参数2文件
mimeMessageHelper.addAttachment(fileName, file);
}
// 发送邮件
mailSender.send(mimeMessage);
//channel信道 basicACk手动应答
//参数1deliveryTag:消息的标识符
//参数2multiple:是否批量应答
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (Exception e) {
e.printStackTrace();
//出现异常,不应答
//判断是否已经重新发消息,1.刚来的消息给一次机会重发,2.已经重发过的,不要再发了打日志转人工
//想多给几次机会就用外力redis记录重发次数
if (message.getMessageProperties().isRedelivered()) {//isRedelivered()是否重新投递
//是重发,拒绝该消息,解开队列堵塞,{}占位符
log.error("消费者应答:此消息已重发,无法再次重发:{}", JSONObject.toJSONString(message));
System.out.println("消费者应答:此消息已重发,无法再次重发");
try {
//basicReject拒绝应答
//参数1deliveryTag:消息的标识符
//参数2requeue:是否把消息放回队列,重发一次
channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
} catch (IOException ex) {
ex.printStackTrace();
}
} else {
//不是重发,刚来,给次机会
System.out.println("消费者第一次重发");
try {
//channel信道 basicNack不应答
//参数1deliveryTag:消息的标识符
//参数2multiple:是否批量应答
//参数3:requeue:是否把消息放回队列,重发一次
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}