feat: 通知

This commit is contained in:
裴浩宇 2024-04-30 18:32:13 +08:00
parent 9bc028e89f
commit e595c0e0e6
11 changed files with 222 additions and 64 deletions

View File

@ -1,2 +0,0 @@
cd /app/
sh start.sh restart

View File

@ -140,6 +140,11 @@
<classifier>jdk15</classifier>
<!-- jdk版本 -->
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

View File

@ -1,17 +0,0 @@
# 指定是基于哪个基础镜像
FROM openjdk:8
# 作者信息
MAINTAINER PNKX
# 挂载点声明
VOLUME /tmp
# 将本地的一个文件或目录,拷贝到容器的文件或目录里
ADD pnkx-admin.jar pnkx-admin.jar
# 将容器的8000端口暴露给外部访问。
EXPOSE 8068
# 当容器运行起来时执行使用运行jar的指令
ENTRYPOINT ["java", "-jar", "pnkx-admin.jar"]

View File

@ -106,3 +106,8 @@ xss:
excludes: /system/notice/*
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*
feishu:
# 飞书机器人的webhook地址
webhook:
url: https://open.feishu.cn/open-apis/bot/v2/hook/ae03114d-aa0d-4348-b12e-9bd7e2911399

View File

@ -0,0 +1,24 @@
import com.pnkx.framework.notify.NotifyContext;
import com.pnkx.framework.notify.impl.EmailNotifyStrategy;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import javax.annotation.Resource;
/**
* NotifyTest
*
* @author 裴浩宇
* @version 1.0
* @date 2024/4/30 17:21
* @description 通知测试类
*/
public class NotifyTest {
@Test
public void notifyTest() throws Exception {
NotifyContext notifyContext = new NotifyContext(new EmailNotifyStrategy());
notifyContext.send("617594538@qq.com", "测试通知");
}
}

View File

@ -0,0 +1,39 @@
package com.pnkx.common.utils.email;
import com.pnkx.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import javax.validation.constraints.Email;
import java.util.Arrays;
import java.util.Objects;
import java.util.regex.Pattern;
/**
* EmailUtils
*
* @author 裴浩宇
* @version 1.0
* @date 2024/4/30 17:36
* @description 邮件工具类
*/
public class EmailUtils {
public static String[] validEmail(String emails) {
if (StringUtils.isNotBlank(emails)) {
return Arrays.stream(emails.split(","))
.filter(email -> isEmail(email.trim()))
.distinct()
.toArray(String[]::new);
}
return null;
}
public static Boolean isEmail(String email) {
String regEx1 = "^([a-z0-9A-Z]+[-|.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
return Pattern.compile(regEx1).matcher(email.trim()).matches();
}
}

View File

@ -0,0 +1,21 @@
package com.pnkx.framework.notify;
/**
* NotifyContext
*
* @author 裴浩宇
* @version 1.0
* @date 2024/4/30 17:09
* @description 通知策略上下文
*/
public class NotifyContext {
private final NotifyStrategy strategy;
public NotifyContext(NotifyStrategy strategy) {
this.strategy = strategy;
}
public void send(String recipient, String message) throws Exception {
strategy.sendNotification(recipient, message);
}
}

View File

@ -0,0 +1,18 @@
package com.pnkx.framework.notify;
/**
* NotifyStrategy
*
* @author 裴浩宇
* @version 1.0
* @date 2024/4/30 16:50
* @description 通知接口
*/
public interface NotifyStrategy {
/**
* 发送通知
* @param recipient 接收者
* @param message 消息内容
*/
void sendNotification(String recipient, String message) throws Exception;
}

View File

@ -0,0 +1,36 @@
package com.pnkx.framework.notify.impl;
import com.pnkx.common.exception.ServiceException;
import com.pnkx.common.utils.StringUtils;
import com.pnkx.common.utils.email.EmailUtils;
import com.pnkx.framework.notify.NotifyStrategy;
import com.pnkx.system.domain.SysEmail;
import com.pnkx.system.service.ISysEmailService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import java.util.Arrays;
import java.util.Objects;
import java.util.regex.Pattern;
/**
* EmailNotifyStrategy
*
* @author 裴浩宇
* @version 1.0
* @date 2024/4/30 16:56
* @description 邮箱方式
*/
@Component
public class EmailNotifyStrategy implements NotifyStrategy {
@Override
public void sendNotification(String recipient, String message) throws Exception {
}
}

View File

@ -0,0 +1,71 @@
package com.pnkx.framework.notify.impl;
import com.pnkx.common.core.controller.BaseController;
import com.pnkx.framework.notify.NotifyStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
/**
* FeishuNotifyStrategy
*
* @author 裴浩宇
* @version 1.0
* @date 2024/4/30 17:04
* @description 飞书通知
*/
@Component
public class FeishuNotifyStrategy implements NotifyStrategy {
protected final Logger logger = LoggerFactory.getLogger(FeishuNotifyStrategy.class);
@Value("${feishu.webhook.url}")
private String webhookUrl;
@Override
public void sendNotification(String recipient, String message) {
try {
URL url = new URL(webhookUrl);
HttpURLConnection connection = getHttpURLConnection(message, url);
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
logger.info("飞书通知成功");
} else {
logger.error("飞书通知失败,响应码:{}", responseCode);
}
} catch (Exception e) {
logger.error("发送飞书通知时发生错误:{}", e.getMessage());
}
}
/**
* 获取HttpURLConnection
* @param message 通知内容
* @param url webhook地址
* @return HttpURLConnection
* @throws IOException 异常
*/
private static HttpURLConnection getHttpURLConnection(String message, URL url) throws IOException {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
connection.setDoOutput(true);
String jsonInputString = "{\"msg_type\":\"text\",\"content\":{\"text\":\"" + message + "\"}}";
try (OutputStream os = connection.getOutputStream()) {
byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
return connection;
}
}

View File

@ -2,6 +2,7 @@ package com.pnkx.system.service.impl;
import com.pnkx.common.utils.DateUtils;
import com.pnkx.common.utils.StringUtils;
import com.pnkx.common.utils.email.EmailUtils;
import com.pnkx.system.domain.SysEmail;
import com.pnkx.system.mapper.SysEmailMapper;
import com.pnkx.system.service.ISysEmailService;
@ -100,61 +101,18 @@ public class SysEmailServiceImpl implements ISysEmailService {
@Transactional
public void sendMail(SysEmail email) throws MessagingException {
sysEmailMapper.insertSysEmail(email);
String[] to = validEmail(email.getReceiverEmail());
String[] to = EmailUtils.validEmail(email.getReceiverEmail());
if (to != null && to.length > 0) {
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
if (StringUtils.isNotEmpty(email.getCcEmail())) {
helper.setCc(Objects.requireNonNull(validEmail(email.getCcEmail())));
helper.setCc(Objects.requireNonNull(EmailUtils.validEmail(email.getCcEmail())));
}
helper.setSubject(email.getSubject());
helper.setText(email.getContent(), true);
javaMailSender.send(message);
}
}
private String[] validEmail(String emails) {
if (StringUtils.isNotBlank(emails)) {
return Arrays.stream(emails.split(","))
.filter(this::isEmail)
.distinct()
.toArray(String[]::new);
}
return null;
}
private Boolean isEmail(String email) {
String regEx1 = "^([a-z0-9A-Z]+[-|.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
return Pattern.compile(regEx1).matcher(email.trim()).matches();
}
private static String getInvalidAddresses(Throwable e) {
if (e == null) {
return null;
}
if (e instanceof MailSendException) {
for (Exception exception : ((MailSendException) e).getMessageExceptions()) {
if (exception instanceof SendFailedException) {
return getStringAddress(((SendFailedException) exception).getInvalidAddresses());
}
}
}
if (e instanceof SendFailedException) {
return getStringAddress(((SendFailedException) e).getInvalidAddresses());
}
return null;
}
private static String getStringAddress(Address[] address) {
List<String> invalid = new ArrayList<>();
for (Address a : address) {
String aa = ((InternetAddress) a).getAddress();
if (!StringUtils.isEmpty(aa)) {
invalid.add(aa);
}
}
return invalid.stream().distinct().collect(Collectors.joining(","));
}
}