Unverified Commit 14e8d146 authored by aiwenmo's avatar aiwenmo Committed by GitHub

[Feature-309][alert] Add Email Alert Type

[Feature-309][alert] Add Email Alert Type
parents a6d8bbff 07bc1356
......@@ -8,11 +8,12 @@ package com.dlink.alert;
**/
public enum ShowType {
TABLE(0, "markdown"), // 通用markdown格式
MARKDOWN(0, "markdown"), // 通用markdown格式
TEXT(1, "text"), //通用文本格式
POST(2, "post"), // 飞书的富文本msgType
ATTACHMENT(3, "attachment"), // 邮件相关 普通邮件
TABLE_ATTACHMENT(4, "table attachment"); // 邮件相关 邮件表格类型
TABLE(0, "table"), // table格式
ATTACHMENT(3, "attachment"), // 邮件相关 只发送附件
TABLE_ATTACHMENT(4, "table attachment"); // 邮件相关 邮件表格+附件
private int code;
private String value;
......
......@@ -128,7 +128,7 @@ public class DingTalkSender {
items.put("msgtype", msgType);
Map<String, Object> text = new HashMap<>();
items.put(msgType, text);
if (ShowType.TABLE.getValue().equals(msgType)) {
if (ShowType.MARKDOWN.getValue().equals(msgType)) {
generateMarkdownMsg(title, content, text);
} else {
generateTextMsg(title, content, text);
......
......@@ -45,7 +45,7 @@ public class DingTalkTest {
config.put(DingTalkConstants.KEYWORD, "Dlinky-Fink 钉钉告警测试");
config.put(DingTalkConstants.WEB_HOOK, "url");
config.put(DingTalkConstants.MSG_TYPE, ShowType.TABLE.getValue());
config.put(DingTalkConstants.MSG_TYPE, ShowType.MARKDOWN.getValue());
config.put(DingTalkConstants.PROXY_ENABLE, "false");
config.put(DingTalkConstants.PASSWORD, "password");
......
<?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>
<artifactId>dlink-alert</artifactId>
<groupId>com.dlink</groupId>
<version>0.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dlink-alert-email</artifactId>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.dlink</groupId>
<artifactId>dlink-alert-base</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1.1-jre</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.dlink.alert.email;
import com.dlink.alert.AbstractAlert;
import com.dlink.alert.AlertResult;
/**
* EmailAlert
* @author zhumingye
* @date: 2022/4/2
**/
public class EmailAlert extends AbstractAlert {
@Override
public String getType() {
return EmailConstants.TYPE;
}
@Override
public AlertResult send(String title, String content) {
MailSender mailSender=new MailSender(getConfig().getParam());
return mailSender.send(title,content);
}
}
package com.dlink.alert.email;
/**
* EmailConstants 邮件常量
* @author zhumingye
* @date: 2022/4/3
**/
public final class EmailConstants {
public static final String TYPE = "Email";
public static final String PLUGIN_DEFAULT_EMAIL_RECEIVERS = "receiver.name";
public static final String NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERS = "receivers";
public static final String PLUGIN_DEFAULT_EMAIL_RECEIVERCCS = "receiverCcs";
public static final String NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERCCS = "receiverCcs";
public static final String NAME_MAIL_PROTOCOL = "mail.protocol";
public static final String MAIL_SMTP_HOST = "mail.smtp.host";
public static final String NAME_MAIL_SMTP_HOST = "serverHost";
public static final String MAIL_SMTP_PORT = "mail.smtp.port";
public static final String NAME_MAIL_SMTP_PORT = "serverPort";
public static final String MAIL_SENDER = "sender.name";
public static final String NAME_MAIL_SENDER = "sender";
public static final String MAIL_SMTP_AUTH = "mail.smtp.auth";
public static final String NAME_MAIL_SMTP_AUTH = "enableSmtpAuth";
public static final String MAIL_USER = "mail.smtp.user";
public static final String NAME_MAIL_USER = "User";
public static final String MAIL_PASSWD = "mail.smtp.passwd";
public static final String NAME_MAIL_PASSWD = "Password";
public static final String MAIL_SMTP_STARTTLS_ENABLE = "mail.smtp.starttls.enable";
public static final String NAME_MAIL_SMTP_STARTTLS_ENABLE = "starttlsEnable";
public static final String MAIL_SMTP_SSL_ENABLE = "mail.smtp.ssl.enable";
public static final String NAME_MAIL_SMTP_SSL_ENABLE = "sslEnable";
public static final String MAIL_SMTP_SSL_TRUST = "mail.smtp.ssl.trust";
public static final String NAME_MAIL_SMTP_SSL_TRUST = "smtpSslTrust";
public static final String XLS_FILE_PATH = "xls.file.path";
public static final String NAME_SHOW_TYPE = "msgtype";
public static final String MAIL_TRANSPORT_PROTOCOL = "mail.transport.protocol";
public static final String TEXT_HTML_CHARSET_UTF_8 = "text/html;charset=utf-8";
public static final int NUMBER_1000 = 1000;
public static final String TR = "<tr>";
public static final String TD = "<td>";
public static final String TD_END = "</td>";
public static final String TR_END = "</tr>";
public static final String TH = "<th>";
public static final String TH_COLSPAN = "<th colspan=2 >";
public static final String TH_END = "</th>";
public static final String TAB = "\t";
public static final String LINE = "\n";
public static final String LEFT = ">";
public static final String HTML_HEADER_PREFIX = "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>"
+ "<html>"
+ "<head>"
+ "<title>Dlinky</title>"
+ "<meta name='Keywords' content=''>"
+ "<meta name='Description' content=''>"
+ "<style type=\"text/css\">"
+ "table {margin-top:0px;padding-top:0px;border:1px solid;font-size: 14px;color: #333333;border-width: 1px;border-color: #666666;border-collapse: collapse;}"
+ "table th {border-width: 1px;padding: 8px;border-style: solid;border-color: #666666;background-color: #dedede;text-align: left;}"
+ "table td {border-width: 1px;padding: 8px;border-style: solid;border-color: #666666;background-color: #ffffff;text-align: left;}"
+ "</style>"
+ "</head>"
+ "<body style=\"margin:0;padding:0\"><table border=\"1px\" cellpadding=\"5px\" cellspacing=\"-10px\"> ";
public static final String TABLE_BODY_HTML_TAIL = "</table></body></html>";
public static final String UTF_8 = "UTF-8";
public static final String EXCEL_SUFFIX_XLSX = ".xlsx";
public static final String SINGLE_SLASH = "/";
private EmailConstants() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}
package com.dlink.alert.email;
import com.dlink.alert.AlertException;
import com.dlink.utils.JSONUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* ExcelUtils excel工具类
* @author zhumingye
* @date: 2022/4/3
**/
public final class ExcelUtils {
private static final int XLSX_WINDOW_ROW = 10000;
private static final Logger logger = LoggerFactory.getLogger(ExcelUtils.class);
private ExcelUtils() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
/**
* generate excel file
*
* @param content the content
* @param title the title
* @param xlsFilePath the xls path
*/
public static void genExcelFile(String content, String title, String xlsFilePath) {
File file = new File(xlsFilePath);
if (!file.exists() && !file.mkdirs()) {
logger.error("Create xlsx directory error, path:{}", xlsFilePath);
throw new AlertException("Create xlsx directory error");
}
List<LinkedHashMap> itemsList = JSONUtil.toList(content, LinkedHashMap.class);
if (CollectionUtils.isEmpty(itemsList)) {
logger.error("itemsList is null");
throw new AlertException("itemsList is null");
}
LinkedHashMap<String, Object> headerMap = itemsList.get(0);
List<String> headerList = new ArrayList<>();
for (Map.Entry<String, Object> en : headerMap.entrySet()) {
headerList.add(en.getKey());
}
try (SXSSFWorkbook wb = new SXSSFWorkbook(XLSX_WINDOW_ROW);
FileOutputStream fos = new FileOutputStream(String.format("%s/%s.xlsx", xlsFilePath, title))) {
// declare a workbook
// generate a table
Sheet sheet = wb.createSheet();
Row row = sheet.createRow(0);
//set the height of the first line
row.setHeight((short) 500);
//set Horizontal right
CellStyle cellStyle = wb.createCellStyle();
cellStyle.setAlignment(HorizontalAlignment.RIGHT);
//setting excel headers
for (int i = 0; i < headerList.size(); i++) {
Cell cell = row.createCell(i);
cell.setCellStyle(cellStyle);
cell.setCellValue(headerList.get(i));
}
//setting excel body
int rowIndex = 1;
for (LinkedHashMap<String, Object> itemsMap : itemsList) {
Object[] values = itemsMap.values().toArray();
row = sheet.createRow(rowIndex);
//setting excel body height
row.setHeight((short) 500);
rowIndex++;
for (int j = 0; j < values.length; j++) {
Cell cell1 = row.createCell(j);
cell1.setCellStyle(cellStyle);
if (values[j] instanceof Number) {
cell1.setCellValue(Double.parseDouble(String.valueOf(values[j])));
} else {
cell1.setCellValue(String.valueOf(values[j]));
}
}
}
for (int i = 0; i < headerList.size(); i++) {
sheet.setColumnWidth(i, headerList.get(i).length() * 800);
}
//setting file output
wb.write(fos);
wb.dispose();
} catch (Exception e) {
throw new AlertException("generate excel error", e);
}
}
}
package com.dlink.alert.email.template;
import com.dlink.alert.ShowType;
/**
* @Author: zhumingye
* @date: 2022/4/3
* @Description: 邮件告警模板接口
*/
public interface AlertTemplate {
String getMessageFromTemplate(String title,String content, ShowType showType, boolean showAll);
/**
* default showAll is true
* @param content alert message content
* @param showType show type
* @return a message from a specified alert template
*/
default String getMessageFromTemplate(String title,String content, ShowType showType) {
return getMessageFromTemplate(title,content, showType, true);
}
}
package com.dlink.alert.email.template;
import com.dlink.alert.ShowType;
import com.dlink.alert.email.EmailConstants;
import com.dlink.utils.JSONUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import static java.util.Objects.requireNonNull;
/**
* @Author: zhumingye
* @date: 2022/4/3
* @Description: 邮件告警Html模板
*/
public class DefaultHTMLTemplate implements AlertTemplate {
public static final Logger logger = LoggerFactory.getLogger(DefaultHTMLTemplate.class);
@Override
public String getMessageFromTemplate(String title , String content, ShowType showType, boolean showAll) {
switch (showType) {
case TABLE:
return getTableTypeMessage(title,content, showAll);
case TEXT:
return getTextTypeMessage(title,content);
default:
throw new IllegalArgumentException(String.format("not support showType: %s in DefaultHTMLTemplate", showType));
}
}
/**
* get alert message which type is TABLE
*
* @param content message content
* @param showAll weather to show all
* @return alert message
*/
private String getTableTypeMessage(String title ,String content, boolean showAll) {
if (StringUtils.isNotEmpty(content)) {
List<LinkedHashMap> mapItemsList = JSONUtil.toList(content,LinkedHashMap.class);
if (!showAll && mapItemsList.size() > EmailConstants.NUMBER_1000) {
mapItemsList = mapItemsList.subList(0, EmailConstants.NUMBER_1000);
}
StringBuilder contents = new StringBuilder(200);
boolean flag = true;
for (LinkedHashMap<String, Object> mapItems : mapItemsList) {
Set<Map.Entry<String, Object>> entries = mapItems.entrySet();
Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
StringBuilder t = new StringBuilder(EmailConstants.TR);
StringBuilder cs = new StringBuilder(EmailConstants.TR);
while (iterator.hasNext()) {
Map.Entry<String, Object> entry = iterator.next();
t.append(EmailConstants.TH).append(entry.getKey()).append(EmailConstants.TH_END);
cs.append(EmailConstants.TD).append(entry.getValue()).append(EmailConstants.TD_END);
}
t.append(EmailConstants.TR_END);
cs.append(EmailConstants.TR_END);
if (flag) {
title = t.toString();
}
flag = false;
contents.append(cs);
}
return getMessageFromHtmlTemplate(title, contents.toString());
}
return content;
}
/**
* get alert message which type is TEXT
* @param content message content
* @return alert message
*/
private String getTextTypeMessage(String title ,String content) {
StringBuilder stringBuilder = new StringBuilder(100);
if (StringUtils.isNotEmpty(content)) {
List<LinkedHashMap> linkedHashMaps = JSONUtil.toList(content, LinkedHashMap.class);
if (linkedHashMaps.size() > EmailConstants.NUMBER_1000) {
linkedHashMaps = linkedHashMaps.subList(0, EmailConstants.NUMBER_1000);
}
stringBuilder.append(EmailConstants.TR).append(EmailConstants.TH_COLSPAN).append(title).append(EmailConstants.TH_END).append(EmailConstants.TR_END);
for (LinkedHashMap<String, Object> mapItems : linkedHashMaps) {
Set<Map.Entry<String, Object>> entries = mapItems.entrySet();
Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<String, Object> entry = iterator.next();
stringBuilder.append(EmailConstants.TR);
stringBuilder.append(EmailConstants.TD).append(entry.getKey()).append(EmailConstants.TD_END);
stringBuilder.append(EmailConstants.TD).append(entry.getValue()).append(EmailConstants.TD_END);
stringBuilder.append(EmailConstants.TR_END);
}
}
return getMessageFromHtmlTemplate(title, stringBuilder.toString());
}
return stringBuilder.toString();
}
/**
* get alert message from a html template
*
* @param title message title
* @param content message content
* @return alert message which use html template
*/
private String getMessageFromHtmlTemplate(String title, String content) {
requireNonNull(content, "content must not null");
String htmlTableThead = StringUtils.isEmpty(title) ? "" : String.format("<thead>%s</thead>%n", title);
return EmailConstants.HTML_HEADER_PREFIX + htmlTableThead + content + EmailConstants.TABLE_BODY_HTML_TAIL;
}
}
com.dlink.alert.email.EmailAlert
\ No newline at end of file
package com.dlink.alert.email;
import com.dlink.alert.AlertResult;
import com.dlink.alert.ShowType;
import com.dlink.alert.email.template.AlertTemplate;
import com.dlink.alert.email.template.DefaultHTMLTemplate;
import com.dlink.utils.JSONUtil;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
public class EmailSenderTest {
private static final Logger logger = LoggerFactory.getLogger(EmailSenderTest.class);
static MailSender mailSender;
private static Map<String, String> emailConfig = new HashMap<>();
private static AlertTemplate alertTemplate;
String title = "Dlinky Email Alert";
String content = "[{\"id\":\"69\","
+ "\"name\":\"UserBehavior-0--1193959466\","
+ "\"Job name\": \"Start workflow\","
+ "\"State\": \"SUCCESS\","
+ "\"Recovery\":\"NO\","
+ "\"Run time\": \"1\","
+ "\"Start time\": \"2018-08-06 10:31:34.0\","
+ "\"End time\": \"2018-08-06 10:31:49.0\","
+ "\"Host\": \"192.168.xx.xx\","
+ "\"Notify group\" :\"4\"}]";
@BeforeClass
public static void initEmailConfig() {
emailConfig.put(EmailConstants.NAME_MAIL_PROTOCOL, "smtp");
emailConfig.put(EmailConstants.NAME_MAIL_SMTP_HOST, "smtp.mxhichina.com");
emailConfig.put(EmailConstants.NAME_MAIL_SMTP_PORT, "465");
emailConfig.put(EmailConstants.NAME_MAIL_SENDER, "aliyun.sdaDXZxDFSDFasa.cn");
emailConfig.put(EmailConstants.NAME_MAIL_USER, "aliyun.sdaDXZxDFSDFasay.cn");
emailConfig.put(EmailConstants.NAME_MAIL_PASSWD, "5vffgdsf123132q8");
emailConfig.put(EmailConstants.NAME_MAIL_SMTP_AUTH, "true");
emailConfig.put(EmailConstants.NAME_MAIL_SMTP_STARTTLS_ENABLE, "true");
emailConfig.put(EmailConstants.NAME_MAIL_SMTP_SSL_ENABLE, "true");
emailConfig.put(EmailConstants.NAME_MAIL_SMTP_SSL_TRUST, "smtp.mxhichina.com");
emailConfig.put(EmailConstants.NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERS, "user1@qq.com,user2@163.com");
emailConfig.put(EmailConstants.NAME_PLUGIN_DEFAULT_EMAIL_RECEIVERCCS, "user3@qq.com");
emailConfig.put(EmailConstants.NAME_SHOW_TYPE, ShowType.TEXT.getValue());
alertTemplate = new DefaultHTMLTemplate();
mailSender = new MailSender(emailConfig);
}
@Test
public void testTextSendMails() {
AlertResult alertResult = mailSender.send(title, content);
Assert.assertEquals(true, alertResult.getSuccess()); // 格式需要调整
}
@Test
public void testSendTableMail() {
emailConfig.put(EmailConstants.NAME_SHOW_TYPE, ShowType.TABLE.getValue());
mailSender = new MailSender(emailConfig);
AlertResult alertResult = mailSender.send(title, content);
Assert.assertEquals(true, alertResult.getSuccess());
}
@Test
public void testAttachmentFile() {
emailConfig.put(EmailConstants.NAME_SHOW_TYPE, ShowType.ATTACHMENT.getValue());
mailSender = new MailSender(emailConfig);
AlertResult alertResult = mailSender.send(title, content);
Assert.assertEquals(true, alertResult.getSuccess());
}
@Test
public void testTableAttachmentFile() {
emailConfig.put(EmailConstants.NAME_SHOW_TYPE, ShowType.TABLE_ATTACHMENT.getValue());
mailSender = new MailSender(emailConfig);
AlertResult alertResult = mailSender.send(title, content);
Assert.assertEquals(true, alertResult.getSuccess());
}
@Test
public void testGenTextEmail() {
List<LinkedHashMap> linkedHashMaps = JSONUtil.toList(content, LinkedHashMap.class);
if (linkedHashMaps.size() > EmailConstants.NUMBER_1000) {
linkedHashMaps = linkedHashMaps.subList(0, EmailConstants.NUMBER_1000);
}
StringBuilder stringBuilder = new StringBuilder(100);
stringBuilder.append(EmailConstants.TR).append(EmailConstants.TH_COLSPAN).append(title).append(EmailConstants.TH_END).append(EmailConstants.TR_END);
for (LinkedHashMap<String, Object> mapItems : linkedHashMaps) {
Set<Map.Entry<String, Object>> entries = mapItems.entrySet();
Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<String, Object> entry = iterator.next();
stringBuilder.append(EmailConstants.TR);
stringBuilder.append(EmailConstants.TD).append(entry.getKey()).append(EmailConstants.TD_END);
stringBuilder.append(EmailConstants.TD).append(entry.getValue()).append(EmailConstants.TD_END);
stringBuilder.append(EmailConstants.TR_END);
}
System.out.println(stringBuilder.toString());
}
}
}
\ No newline at end of file
......@@ -5,10 +5,9 @@
<parent>
<artifactId>dlink-alert</artifactId>
<groupId>com.dlink</groupId>
<version>0.6.1-SNAPSHOT</version>
<version>0.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dlink-alert-feishu</artifactId>
<packaging>jar</packaging>
......
......@@ -182,7 +182,7 @@ public class WeChatSender {
private String markdownByAlert(String title, String content,List<String> userList) {
String result = "";
if (showType.equals(ShowType.TABLE.getValue())) {
if (showType.equals(ShowType.MARKDOWN.getValue())) {
result = markdownTable(title, content,userList,sendType);
} else if (showType.equals(ShowType.TEXT.getValue())) {
result = markdownText(title, content,userList,sendType);
......
......@@ -70,7 +70,7 @@ public class WeChatSenderTest {
);
weChatConfig.put(WeChatConstants.USERS, "all");
weChatConfig.put(WeChatConstants.TEAM_SEND_MSG, "msg");
weChatConfig.put(WeChatConstants.SHOW_TYPE, ShowType.TABLE.getValue());// default is "table"
weChatConfig.put(WeChatConstants.SHOW_TYPE, ShowType.MARKDOWN.getValue());// default is "table"
weChatConfig.put(WeChatConstants.SEND_TYPE, WeChatType.APP.getValue());
}
......@@ -96,7 +96,7 @@ public class WeChatSenderTest {
weChatConfig.put(WeChatConstants.WEBHOOK, "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=8xxxxxxxxxxxxxxxxx6fe13396c");
weChatConfig.put(WeChatConstants.SEND_TYPE, WeChatType.CHAT.getValue());
weChatConfig.put(WeChatConstants.USER_SEND_MSG,WeChatConstants.WEBHOOK_TEMPLATE);
weChatConfig.put(WeChatConstants.SHOW_TYPE, ShowType.TABLE.getValue());
weChatConfig.put(WeChatConstants.SHOW_TYPE, ShowType.MARKDOWN.getValue());
weChatConfig.put(WeChatConstants.KEYWORD, "Dlinky企微WEBHOOK MarkDown方式 告警测试");
WeChatSender weChatSender = new WeChatSender(weChatConfig);
AlertResult alertResult = weChatSender.send("TEXT-TEST", contentTest);
......
......@@ -16,7 +16,7 @@
<module>dlink-alert-dingtalk</module>
<module>dlink-alert-wechat</module>
<module>dlink-alert-feishu</module>
<!-- <module>dlink-alert-email</module>-->
<module>dlink-alert-email</module>
</modules>
<properties>
......
......@@ -190,6 +190,14 @@
<include>dlink-alert-feishu-${project.version}.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.parent.basedir}/dlink-alert/dlink-alert-email/target
</directory>
<outputDirectory>lib</outputDirectory>
<includes>
<include>dlink-alert-email-${project.version}.jar</include>
</includes>
</fileSet>
<!-- 将模块dlink-extends的常用jar文件放到打包目录/plugins下 -->
<!--<fileSet>
<directory>${project.parent.basedir}/dlink-extends/target
......
......@@ -90,6 +90,11 @@
<artifactId>dlink-alert-feishu</artifactId>
<scope>${scope.runtime}</scope>
</dependency>
<dependency>
<groupId>com.dlink</groupId>
<artifactId>dlink-alert-email</artifactId>
<scope>${scope.runtime}</scope>
</dependency>
<dependency>
<groupId>com.dlink</groupId>
<artifactId>dlink-metadata-mysql</artifactId>
......
......@@ -10,6 +10,7 @@ import DingTalkForm from "@/pages/AlertInstance/components/DingTalkForm";
import {createOrModifyAlertInstance} from "@/pages/AlertInstance/service";
import WeChatForm from "@/pages/AlertInstance/components/WeChatForm";
import FeiShuForm from "@/pages/AlertInstance/components/FeiShuForm";
import EmailForm from "@/pages/AlertInstance/components/EmailForm";
export type UpdateFormProps = {
onCancel: (flag?: boolean, formVals?: Partial<AlertInstanceTableListItem>) => void;
......@@ -115,6 +116,19 @@ const AlertInstanceChooseForm: React.FC<UpdateFormProps> = (props) => {
}}
/>:undefined
}
{(values?.type == ALERT_TYPE.EMAIL || alertType == ALERT_TYPE.EMAIL)?
<EmailForm
onCancel={() => {
setAlertType(undefined);
handleChooseModalVisible();
}}
modalVisible={values?.type == ALERT_TYPE.EMAIL || alertType == ALERT_TYPE.EMAIL}
values={values}
onSubmit={(value) => {
onSubmit(value);
}}
/>:undefined
}
</Modal>
);
};
......
import React, {useState} from 'react';
import {Button, Divider, Form, Input, Modal, Radio, Switch} from 'antd';
import {AlertInstanceTableListItem} from "@/pages/AlertInstance/data";
import {buildJSONData, getJSONData} from "@/pages/AlertInstance/function";
import {ALERT_TYPE} from "@/pages/AlertInstance/conf";
export type AlertInstanceFormProps = {
onCancel: (flag?: boolean) => void;
onSubmit: (values: Partial<AlertInstanceTableListItem>) => void;
modalVisible: boolean;
values: Partial<AlertInstanceTableListItem>;
};
const formLayout = {
labelCol: {span: 7},
wrapperCol: {span: 13},
};
const FeiShuForm: React.FC<AlertInstanceFormProps> = (props) => {
const [form] = Form.useForm();
const [formVals, setFormVals] = useState<Partial<AlertInstanceTableListItem>>({
id: props.values?.id,
name: props.values?.name,
type: ALERT_TYPE.EMAIL,
params: props.values?.params,
enabled: props.values?.enabled,
});
const {
onSubmit: handleSubmit,
onCancel: handleModalVisible,
modalVisible,
} = props;
const onValuesChange = (change: any,all: any)=>{
setFormVals({...formVals,...change});
};
const submitForm = async () => {
const fieldsValue = await form.validateFields();
setFormVals(buildJSONData(formVals,fieldsValue));
handleSubmit(buildJSONData(formVals,fieldsValue));
};
const renderContent = (vals) => {
return (
<>
<Divider>邮箱配置</Divider>
<Form.Item
name="name"
label="名称"
rules={[{required: true, message: '请输入邮箱配置名称!'}]}
>
<Input placeholder="请输入邮件配置名称"/>
</Form.Item>
<Form.Item
name="receivers"
label="收件人"
rules={[{required: true, message: '请输入收件人邮箱!多个英文逗号隔开'}]}
>
<Input.TextArea placeholder="请输入收件人邮箱!多个英文逗号隔开!" allowClear autoSize={{minRows: 1, maxRows: 5}}/>
</Form.Item>
<Form.Item
name="receiverCcs"
label="抄送人"
>
<Input.TextArea placeholder="请输入抄送人邮箱!多个英文逗号隔开!" allowClear autoSize={{minRows: 1, maxRows: 5}}/>
</Form.Item>
<Form.Item
name="serverHost"
label="邮件服务器Host"
rules={[{required: true, message: '请输入收件人邮箱!多个英文逗号隔开'}]}
>
<Input placeholder="请输入邮件服务器Host"/>
</Form.Item>
<Form.Item
name="serverPort"
label="邮件服务器Port"
rules={[{required: true, message: '请输入邮件服务器Port!'}]}
>
<Input placeholder="请输入邮件服务器Port"/>
</Form.Item>
<Form.Item
name="sender"
label="发送者sender昵称"
rules={[{required: true, message: '请输入发送者sender昵称'}]}
>
<Input placeholder="请输入邮件服务器发送者sender"/>
</Form.Item>
<Form.Item
name="enableSmtpAuth"
label="是否开启邮箱验证"
>
<Switch checkedChildren="是" unCheckedChildren="否"
defaultChecked={vals.enableSmtpAuth}/>
</Form.Item>
{vals.enableSmtpAuth &&
<>
<Form.Item
name="User"
label="邮箱用户名"
rules={[{required: true, message: '请输入邮箱用户名!'}]}
>
<Input allowClear placeholder="请输入邮箱用户名"/>
</Form.Item>
<Form.Item
name="Password"
label="邮箱密码"
rules={[{required: true, message: '请输入邮箱密码/授权码!'}]}
>
<Input.Password allowClear placeholder="请输入邮箱密码! 注意:密码为授权码"/>
</Form.Item>
</>}
<Form.Item
name="starttlsEnable"
label="是否开启tls证书验证"
>
<Switch checkedChildren="是" unCheckedChildren="否"
defaultChecked={vals.starttlsEnable}/>
</Form.Item>
<Form.Item
name="sslEnable"
label="是否开启SSL验证"
>
<Switch checkedChildren="是" unCheckedChildren="否"
defaultChecked={vals.sslEnable}/>
</Form.Item>
{ ( vals.sslEnable ) &&
<Form.Item
name="smtpSslTrust"
label="受信任域"
rules={[{required: true, message: '你已经开启tls证书验证! 此项必填!'}]}
>
<Input placeholder="请输入受信任域"/>
</Form.Item>
}
<Form.Item
name="enabled"
label="是否启用">
<Switch checkedChildren="启用" unCheckedChildren="禁用"
defaultChecked={vals.enabled}/>
</Form.Item>
<Form.Item
name="msgtype"
label="展示方式"
rules={[{required: true, message: '请选择展示方式!'}]}
>
<Radio.Group >
<Radio value='text'>文本</Radio>
<Radio value='table'>表格</Radio>
<Radio value='attachment'>附件</Radio>
<Radio value='table attachment'>表格附件</Radio>
</Radio.Group>
</Form.Item>
{(vals.msgtype === "attachment" || vals.msgtype === "table attachment") &&
<>
<Form.Item
name="xls.file.path"
label="XLS存放目录"
>
<Input allowClear placeholder="请输入XLS存放目录! 默认为 /tmp/xls"/>
</Form.Item>
</> }
</>
);
};
const renderFooter = () => {
return (
<>
<Button onClick={() => handleModalVisible(false)}>取消</Button>
<Button type="primary" onClick={() => submitForm()}>
完成
</Button>
</>
);
};
return (
<Modal
width={1200}
bodyStyle={{padding: '32px 40px 48px'}}
destroyOnClose
title={formVals.id?"维护报警实例配置":"创建报警实例配置"}
visible={modalVisible}
footer={renderFooter()}
onCancel={() => handleModalVisible()}
>
<Form
{...formLayout}
form={form}
initialValues={getJSONData(formVals)}
onValuesChange={onValuesChange}
>
{renderContent(getJSONData(formVals))}
</Form>
</Modal>
);
};
export default FeiShuForm;
......@@ -6,6 +6,7 @@ export const ALERT_TYPE = {
DINGTALK:'DingTalk',
WECHAT:'WeChat',
FEISHU:'FeiShu',
EMAIL:'Email',
};
export const ALERT_CONFIG_LIST: AlertConfig[] = [{
......@@ -14,5 +15,7 @@ export const ALERT_CONFIG_LIST: AlertConfig[] = [{
type: ALERT_TYPE.WECHAT,
},{
type: ALERT_TYPE.FEISHU,
},{
type: ALERT_TYPE.EMAIL,
}
];
......@@ -11,6 +11,8 @@ export const getAlertIcon = (type: string) => {
return (<Icon component={WeChatSvg}/>);
case ALERT_TYPE.FEISHU:
return (<Icon component={FeiShuSvg}/>);
case ALERT_TYPE.EMAIL:
return (<Icon component={EmailSvg}/>);
default:
return (<Icon component={DefaultSvg}/>);
}
......@@ -61,6 +63,15 @@ export const FeiShuSvg = () => (
</svg>
);
export const EmailSvg = () => (
<svg t="1648906363188" className="icon" viewBox="0 0 1036 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="6427" width={svgSize} height={svgSize}>
<path
d="M41.451064 207.245088c-22.617114 31.327496-36.391838 69.3863-36.391838 110.965278l0 382.754381c0 41.387619 13.71128 79.446423 36.201503 110.648053l316.950675-368.974539L41.451064 207.245088 41.451064 207.245088zM933.812955 159.38608c-29.728068-19.416212-65.157999-30.883381-103.216803-30.883381L194.767915 128.502699c-40.044018 0-77.008908 12.559037-107.637486 33.69952l421.449681 313.109184L933.812955 159.38608 933.812955 159.38608zM980.778616 203.529463 658.953933 442.569698l321.115532 373.848547c24.861224-32.03767 40.238446-71.821769 40.238446-115.516944L1020.307911 318.210365C1020.24549 274.902 1005.184469 235.498572 980.778616 203.529463L980.778616 203.529463zM527.292288 540.342512c-2.116197 1.602498-4.740978 0.76748-6.985088 1.792832-4.037966 1.666966-7.366781 3.01159-11.657504 2.948145-4.361331 0.063445-7.689123-1.281179-11.728112-2.948145-2.306532-1.026376-4.931313-0.190335-7.04751-1.730411l-80.537268-59.904345L86.490863 856.334349c30.693046 21.400403 67.979254 34.148751 108.278075 34.148751l635.827213 0c38.058804 0 73.42529-11.403724 103.090936-30.755468L607.891977 480.500589 527.292288 540.342512 527.292288 540.342512zM527.292288 540.342512"
p-id="6428" fill="#1296db" data-spm-anchor-id="a313x.7781069.0.i7" className=""></path>
</svg>
);
export const DefaultSvg = () => (
<svg t="1648879472114" className="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
......
import React, {useRef, useState} from "react";
import {DownOutlined, PlusOutlined} from '@ant-design/icons';
import {ActionType, ProColumns} from "@ant-design/pro-table";
import {Button, message, Input, Drawer, Modal, Dropdown, Menu} from 'antd';
import {PageContainer, FooterToolbar} from '@ant-design/pro-layout';
import ProTable from '@ant-design/pro-table';
import ProTable, {ActionType, ProColumns} from "@ant-design/pro-table";
import {Button, Drawer, Dropdown, Menu, Modal} from 'antd';
import {FooterToolbar, PageContainer} from '@ant-design/pro-layout';
import ProDescriptions from '@ant-design/pro-descriptions';
import {AlertInstanceTableListItem} from "@/pages/AlertInstance/data";
import {handleAddOrUpdate, handleRemove, queryData, updateEnabled} from "@/components/Common/crud";
import {handleRemove, queryData, updateEnabled} from "@/components/Common/crud";
import AlertInstanceChooseForm from "@/pages/AlertInstance/components/AlertInstanceChooseForm";
const url = '/api/alertInstance';
......@@ -92,12 +91,20 @@ const AlertInstanceTableList: React.FC<{}> = (props: any) => {
},{
text: 'WeChat',
value: 'WeChat',
},{
text: 'FeiShu',
value: 'FeiShu',
},{
text: 'Email',
value: 'Email',
}
],
filterMultiple: false,
valueEnum: {
'DingTalk': {text: 'DingTalk'},
'WeChat': {text: 'WeChat'},
'FeiShu': {text: 'FeiShu'},
'Email': {text: 'Email'},
},
},
{
......
......@@ -312,6 +312,11 @@
<artifactId>dlink-alert-feishu</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.dlink</groupId>
<artifactId>dlink-alert-email</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.dlink</groupId>
<artifactId>dlink-daemon</artifactId>
......
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