optimize notice template (#1301)

This commit is contained in:
Eden4701
2023-10-26 11:16:11 +08:00
committed by ruanliang01
parent f1a7538ee4
commit b87bd48811
37 changed files with 304 additions and 366 deletions
@@ -39,8 +39,8 @@ import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_ONLY;
import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_WRITE;
/**
* Notification strategy entity
* 通知策略
* Notification template entity
* 通知模版
*
*
*/
@@ -78,9 +78,8 @@ public class NoticeTemplate {
@Schema(title = "Is it a preset template: true- preset template false- custom template.",
description = "是否为预设模板: true-预设模板 false-自定义模板",
accessMode = READ_WRITE)
@NotNull
private Boolean presetTemplate;
@Column(columnDefinition = "boolean default false")
private boolean preset = false;
@Schema(title = "Template content",
description = "模板内容",
@@ -93,8 +92,8 @@ public class NoticeTemplate {
"${contentLabel} : ${content}", accessMode = READ_WRITE)
@Length(max = 100000)
@NotBlank
@Column(name = "template_content", columnDefinition = "MEDIUMTEXT")
private String templateContent;
@Column(name = "content", columnDefinition = "MEDIUMTEXT")
private String content;
@Schema(title = "The creator of this record", description = "此条记录创建者", example = "tom", accessMode = READ_ONLY)
@CreatedBy
Executable → Regular
View File

Before

Width:  |  Height:  |  Size: 328 KiB

After

Width:  |  Height:  |  Size: 328 KiB

Executable → Regular
View File

Before

Width:  |  Height:  |  Size: 851 KiB

After

Width:  |  Height:  |  Size: 851 KiB

@@ -27,12 +27,12 @@ import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate;
import org.dromara.hertzbeat.common.support.event.SystemConfigChangeEvent;
import org.dromara.hertzbeat.common.util.ResourceBundleUtil;
import org.dromara.hertzbeat.manager.component.alerter.AlertNotifyHandler;
import org.dromara.hertzbeat.manager.service.NoticeConfigService;
import org.springframework.context.event.EventListener;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.time.Instant;
import java.time.ZoneId;
@@ -54,16 +54,17 @@ abstract class AbstractAlertNotifyHandlerImpl implements AlertNotifyHandler {
protected ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter");
@Resource
protected RestTemplate restTemplate;
@Resource
protected AlerterProperties alerterProperties;
@Resource
protected NoticeConfigService noticeConfigService;
protected String renderContent(NoticeTemplate noticeTemplate, Alert alert) throws TemplateException, IOException {
StringTemplateLoader stringLoader = new StringTemplateLoader();
freemarker.template.Template templateRes = null;
Configuration cfg = new Configuration();
freemarker.template.Template templateRes;
Configuration cfg = new Configuration(Configuration.VERSION_2_3_0);
Map<String, String> model = new HashMap<>(16);
model.put("title", bundle.getString("alerter.notify.title"));
@@ -89,16 +90,16 @@ abstract class AbstractAlertNotifyHandlerImpl implements AlertNotifyHandler {
model.put("contentLabel", bundle.getString("alerter.notify.content"));
model.put("content", alert.getContent());
if (noticeTemplate == null) {
String path = this.getClass().getResource("/").getPath();
cfg.setDirectoryForTemplateLoading(new File(path + "templates/"));
cfg.setDefaultEncoding("utf-8");
templateRes = cfg.getTemplate(templateName() + ".txt");
} else {
String templateName = "freemakerTemplate";
stringLoader.putTemplate(templateName, noticeTemplate.getTemplateContent());
cfg.setTemplateLoader(stringLoader);
templateRes = cfg.getTemplate(templateName, Locale.CHINESE);
noticeTemplate = noticeConfigService.getDefaultNoticeTemplateByType(type());
}
if (noticeTemplate == null) {
log.error("{} does not have mapping default notice template. type: {}.", templateName(), type());
throw new NullPointerException(type() + " does not have mapping default notice template");
}
String templateName = "freeMakerTemplate";
stringLoader.putTemplate(templateName, noticeTemplate.getContent());
cfg.setTemplateLoader(stringLoader);
templateRes = cfg.getTemplate(templateName, Locale.CHINESE);
String template = FreeMarkerTemplateUtils.processTemplateIntoString(templateRes, model);
return template.replaceAll("((\r\n)|\n)[\\s\t ]*(\\1)+", "$1");
}
@@ -24,7 +24,6 @@ import org.dromara.hertzbeat.common.entity.dto.Message;
import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver;
import org.dromara.hertzbeat.common.entity.manager.NoticeRule;
import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate;
import org.dromara.hertzbeat.common.util.Pair;
import org.dromara.hertzbeat.manager.service.NoticeConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
@@ -33,13 +32,7 @@ import org.springframework.web.bind.annotation.*;
import javax.persistence.criteria.Predicate;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static org.dromara.hertzbeat.common.constants.CommonConstants.FAIL_CODE;
@@ -171,7 +164,7 @@ public class NoticeConfigController {
// Returns success if it does not exist or if the deletion is successful
// todo 不存在或删除成功都返回成功
Optional<NoticeTemplate> noticeTemplate = noticeConfigService.getNoticeTemplatesById(templateId);
if (noticeTemplate == null) {
if (noticeTemplate.isEmpty()) {
return ResponseEntity.ok(Message.success("The specified notification template could not be queried, please check whether the parameters are correct"));
}
noticeConfigService.deleteNoticeTemplate(templateId);
@@ -182,7 +175,7 @@ public class NoticeConfigController {
@Operation(summary = "Get a list of message notification templates based on query filter items",
description = "根据查询过滤项获取消息通知模板列表")
public ResponseEntity<Message<List<NoticeTemplate>>> getTemplates(
@Parameter(description = "en: Template name,zh: 模板名称,模糊查询", example = "rule1") @RequestParam(required = false) final String name) {
@Parameter(description = "Template name | 模板名称,模糊查询", example = "rule1") @RequestParam(required = false) final String name) {
Specification<NoticeTemplate> specification = (root, query, criteriaBuilder) -> {
Predicate predicate = criteriaBuilder.conjunction();
@@ -197,30 +190,6 @@ public class NoticeConfigController {
return ResponseEntity.ok(message);
}
@GetMapping(path = "/default_templates")
@Operation(summary = "Get a list of message notification templates based on query filter items",
description = "根据查询过滤项获取预设消息通知模板列表")
public ResponseEntity<Message<List<NoticeTemplate> >> getDefaultTemplates(
@Parameter(description = "en: Template name,zh: 模板名称,模糊查询", example = "rule1") @RequestParam(required = false) final String name) throws IOException {
List<NoticeTemplate> defaultTemplatePage=new ArrayList<>();
Long intitId=1000L;
String path="manager/src/main/resources/templates/";
File file = new File(path);
String[] fs=file.list();
for(String f:fs){
NoticeTemplate tmp=new NoticeTemplate();
tmp.setId(intitId);
tmp.setName(f.replace(".txt", "").replace(".html", ""));
tmp.setPresetTemplate(true);
tmp.setTemplateContent(Files.readString(Paths.get(path+f)));
intitId++;
defaultTemplatePage.add(tmp);
}
Message<List<NoticeTemplate> > message = Message.success(defaultTemplatePage);
return ResponseEntity.ok(message);
}
@PostMapping(path = "/receiver/send-test-msg")
@Operation(summary = "Send test msg to receiver", description = "给指定接收人发送测试消息")
public ResponseEntity<Message<Void>> sendTestMsg(@Valid @RequestBody NoticeReceiver noticeReceiver) {
@@ -230,4 +199,4 @@ public class NoticeConfigController {
}
return ResponseEntity.ok(Message.fail(FAIL_CODE, "Notify service not available, please check config!"));
}
}
}
@@ -27,14 +27,6 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
*
*/
public interface NoticeTemplateDao extends JpaRepository<NoticeTemplate, Long>, JpaSpecificationExecutor<NoticeTemplate> {
/**
* 通过模板类型和预设模板标识查找通知模板
*
* @param type Byte type 模板类型
* @param defaultTemplate Boolean defaultTemplate 预设模板标识
* @return 通知模板
*/
NoticeTemplate findNoticeTemplateByTypeAndPresetTemplate(Byte type, Boolean defaultTemplate);
}
@@ -42,7 +42,6 @@ public interface NoticeConfigService {
* @return Search result 查询结果
*/
List<NoticeReceiver> getNoticeReceivers(Specification<NoticeReceiver> specification);
// Map<NoticeReceiver,NoticeTemplate> getNoticeReceiversAndTemplate(Specification<NoticeReceiver> specification);
/**
* Dynamic conditional query
@@ -190,16 +189,14 @@ public interface NoticeConfigService {
Optional<NoticeTemplate> getNoticeTemplatesById(Long templateId);
/**
* Query specific notification templates according to the template type and default
* 根据模板类型和预设模板标识查询具体通知规则
* Query specific notification templates according to the template type
* 根据模板类型查询具体模版
*
* @param type Template type 模板类型
* @param defaultTemplate Preset template identification 预设模板标识
* @return Notification Template Entity 通知模板实体
*/
NoticeTemplate findNoticeTemplateByTypeAndDefault(Byte type, Boolean defaultTemplate);
NoticeTemplate getDefaultNoticeTemplateByType(Byte type);
/**
* alert Send test message
* 告警 发送测试消息
@@ -24,16 +24,16 @@ import org.dromara.hertzbeat.alert.AlerterProperties;
import org.dromara.hertzbeat.common.entity.alerter.Alert;
import org.dromara.hertzbeat.common.constants.CommonConstants;
import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate;
import org.dromara.hertzbeat.common.support.event.SystemConfigChangeEvent;
import org.dromara.hertzbeat.common.util.ResourceBundleUtil;
import org.dromara.hertzbeat.manager.service.MailService;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hertzbeat.manager.service.NoticeConfigService;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
@@ -44,7 +44,6 @@ import java.util.*;
*
*
* @version 1.0
*
*/
@Slf4j
@Service
@@ -53,53 +52,59 @@ public class MailServiceImpl implements MailService {
@Resource
private AlerterProperties alerterProperties;
@Resource
protected NoticeConfigService noticeConfigService;
private ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter");
@Override
public String buildAlertHtmlTemplate(final Alert alert, NoticeTemplate noticeTemplate) throws IOException, TemplateException {
freemarker.template.Template templateMail=null;
Configuration cfg = new Configuration();
freemarker.template.Template templateMail = null;
Configuration cfg = new Configuration(Configuration.VERSION_2_3_0);
String monitorId = null;
String monitorName = null;
if (alert.getTags() != null) {
monitorId = alert.getTags().get(CommonConstants.TAG_MONITOR_ID);
monitorName = alert.getTags().get(CommonConstants.TAG_MONITOR_NAME);
}
monitorId = monitorId == null? "External Alarm, No ID" : monitorId;
monitorName = monitorName == null? "External Alarm, No Name" : monitorName;
monitorId = monitorId == null ? "External Alarm, No ID" : monitorId;
monitorName = monitorName == null ? "External Alarm, No Name" : monitorName;
// Introduce thymeleaf context parameters to render pages
Map<String, String> model = new HashMap<>(16);
model.put("nameTitle", bundle.getString("alerter.notify.title"));
model.put("nameMonitorId", bundle.getString("alerter.notify.monitorId"));
model.put("nameMonitorName", bundle.getString("alerter.notify.monitorName"));
model.put("target", alert.getTarget());
model.put("nameTitle", bundle.getString("alerter.notify.title"));
model.put("nameMonitorId", bundle.getString("alerter.notify.monitorId"));
model.put("nameMonitorName", bundle.getString("alerter.notify.monitorName"));
model.put("target", alert.getTarget());
model.put("monitorId", monitorId);
model.put("monitorName", monitorName);
model.put("nameTarget", bundle.getString("alerter.notify.target"));
model.put("nameConsole", bundle.getString("alerter.notify.console"));
model.put("namePriority", bundle.getString("alerter.notify.priority"));
model.put("priority", bundle.getString("alerter.priority." + alert.getPriority()));
model.put("monitorName", monitorName);
model.put("nameTarget", bundle.getString("alerter.notify.target"));
model.put("nameConsole", bundle.getString("alerter.notify.console"));
model.put("namePriority", bundle.getString("alerter.notify.priority"));
model.put("priority", bundle.getString("alerter.priority." + alert.getPriority()));
model.put("nameTriggerTime", bundle.getString("alerter.notify.triggerTime"));
model.put("consoleUrl", alerterProperties.getConsoleUrl());
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String triggerTime = simpleDateFormat.format(new Date(alert.getLastAlarmTime()));
model.put("lastTriggerTime",triggerTime);
model.put("lastTriggerTime", triggerTime);
model.put("nameContent", bundle.getString("alerter.notify.content"));
model.put("content", alert.getContent());
if(noticeTemplate==null){
String path = this.getClass().getResource("/").getPath();
cfg.setDirectoryForTemplateLoading(new File(path+"templates/"));
cfg.setDefaultEncoding("utf-8");
templateMail = cfg.getTemplate("mailAlarm.html");
if (noticeTemplate == null) {
noticeTemplate = noticeConfigService.getDefaultNoticeTemplateByType((byte)1);
}
else {
StringTemplateLoader stringLoader = new StringTemplateLoader();
String templateName = "mailTemplate";
stringLoader.putTemplate(templateName, noticeTemplate.getTemplateContent());
cfg.setTemplateLoader(stringLoader);
templateMail= cfg.getTemplate(templateName, Locale.CHINESE);
if (noticeTemplate == null) {
throw new NullPointerException("email does not have mapping default notice template");
}
String template = FreeMarkerTemplateUtils.processTemplateIntoString(templateMail, model);
return template;
StringTemplateLoader stringLoader = new StringTemplateLoader();
String templateName = "mailTemplate";
stringLoader.putTemplate(templateName, noticeTemplate.getContent());
cfg.setTemplateLoader(stringLoader);
templateMail = cfg.getTemplate(templateName, Locale.CHINESE);
return FreeMarkerTemplateUtils.processTemplateIntoString(templateMail, model);
}
@EventListener(SystemConfigChangeEvent.class)
public void onEvent(SystemConfigChangeEvent event) {
log.info("{} receive system config change event: {}.", this.getClass().getName(), event.getSource());
this.bundle = ResourceBundleUtil.getBundle("alerter");
}
}
@@ -22,6 +22,7 @@ import org.dromara.hertzbeat.common.cache.CacheFactory;
import org.dromara.hertzbeat.common.cache.ICacheService;
import org.dromara.hertzbeat.common.constants.CommonConstants;
import org.dromara.hertzbeat.common.entity.alerter.Alert;
import org.dromara.hertzbeat.common.entity.job.Job;
import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver;
import org.dromara.hertzbeat.common.entity.manager.NoticeRule;
import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate;
@@ -31,16 +32,24 @@ import org.dromara.hertzbeat.manager.dao.NoticeRuleDao;
import org.dromara.hertzbeat.manager.dao.NoticeTemplateDao;
import org.dromara.hertzbeat.manager.service.NoticeConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -49,14 +58,17 @@ import java.util.stream.Collectors;
*
*/
@Service
@Order(value = Ordered.HIGHEST_PRECEDENCE)
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class NoticeConfigServiceImpl implements NoticeConfigService {
public class NoticeConfigServiceImpl implements NoticeConfigService, CommandLineRunner {
private static final String ALERT_TEST_TARGET = "Test Target";
private static final String ALERT_TEST_CONTENT = "test send msg! \n This is the test data. It is proved that it can be received successfully";
private static final Map<Byte, NoticeTemplate> PRESET_TEMPLATE = new HashMap<>(16);
@Autowired
private NoticeReceiverDao noticeReceiverDao;
@@ -78,7 +90,9 @@ public class NoticeConfigServiceImpl implements NoticeConfigService {
@Override
public List<NoticeTemplate> getNoticeTemplates(Specification<NoticeTemplate> specification) {
return noticeTemplateDao.findAll(specification);
List<NoticeTemplate> defaultTemplates = new LinkedList<>(PRESET_TEMPLATE.values());
defaultTemplates.addAll(noticeTemplateDao.findAll(specification));
return defaultTemplates;
}
@Override
@@ -223,8 +237,11 @@ public class NoticeConfigServiceImpl implements NoticeConfigService {
}
@Override
public NoticeTemplate findNoticeTemplateByTypeAndDefault(Byte type, Boolean defaultTemplate) {
return noticeTemplateDao.findNoticeTemplateByTypeAndPresetTemplate(type, defaultTemplate);
public NoticeTemplate getDefaultNoticeTemplateByType(Byte type) {
if (type == null) {
return null;
}
return PRESET_TEMPLATE.get(type);
}
@Override
@@ -236,14 +253,51 @@ public class NoticeConfigServiceImpl implements NoticeConfigService {
alert.setFirstAlarmTime(System.currentTimeMillis());
alert.setLastAlarmTime(System.currentTimeMillis());
alert.setPriority(CommonConstants.ALERT_PRIORITY_CODE_CRITICAL);
Byte type = noticeReceiver.getType();
Boolean defaultTemplate = true;
NoticeTemplate noticeTemplate = findNoticeTemplateByTypeAndDefault(type, defaultTemplate);
return dispatcherAlarm.sendNoticeMsg(noticeReceiver, noticeTemplate, alert);
return dispatcherAlarm.sendNoticeMsg(noticeReceiver, null, alert);
}
private void clearNoticeRulesCache() {
ICacheService<String, Object> noticeCache = CacheFactory.getNoticeCache();
noticeCache.remove(CommonConstants.CACHE_NOTICE_RULE);
}
@Override
public void run(String... args) throws Exception {
try {
log.info("load default notice template in internal jar");
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("classpath:templates/*.*");
for (Resource resource : resources) {
if (resource.getFilename() == null || (!resource.getFilename().endsWith("txt") && !resource.getFilename().endsWith("html"))) {
log.warn("Ignore the template file {}.", resource.getFilename());
continue;
}
try (InputStream inputStream = resource.getInputStream()) {
byte[] bytes = new byte[inputStream.available()];
inputStream.read(bytes);
String content = new String(bytes, StandardCharsets.UTF_8);
NoticeTemplate template = new NoticeTemplate();
String name = resource.getFilename().replace(".txt", "").replace(".html", "");
String[] names = name.split("-");
if (names.length != 2) {
log.warn("Ignore the template file {}.", resource.getFilename());
continue;
}
byte type = Byte.parseByte(names[0]);
name = names[1];
template.setName(name);
template.setType(type);
template.setPreset(true);
template.setContent(content);
template.setGmtUpdate(LocalDateTime.now());
PRESET_TEMPLATE.put(template.getType(), template);
} catch (IOException e) {
log.error(e.getMessage(), e);
log.error("Ignore this template file: {}.", resource.getFilename());
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
@@ -36,7 +36,7 @@ class DingTalkRobotAlertNotifyHandlerImplTest extends AbstractSpringIntegrationT
NoticeTemplate noticeTemplate=new NoticeTemplate();
noticeTemplate.setId(1L);
noticeTemplate.setName("dingding");
noticeTemplate.setTemplateContent("#### [${title}]\n" +
noticeTemplate.setContent("#### [${title}]\n" +
"##### **${targetLabel}** : ${target}\n" +
"<#if (monitorId??)>##### **${monitorIdLabel}** : ${monitorId} </#if>\n" +
"<#if (monitorName??)>##### **${monitorNameLabel}** : ${monitorName} </#if>\n" +
@@ -40,7 +40,7 @@ class DiscordBotAlertNotifyHandlerImplTest extends AbstractSpringIntegrationTest
var noticeTemplate=new NoticeTemplate();
noticeTemplate.setId(1L);
noticeTemplate.setName("DiscordBot");
noticeTemplate.setTemplateContent("${targetLabel} : ${target}\n" +
noticeTemplate.setContent("${targetLabel} : ${target}\n" +
"<#if (monitorId??)>${monitorIdLabel} : ${monitorId} </#if>\n" +
"<#if (monitorName??)>${monitorNameLabel} : ${monitorName} </#if>\n" +
"${priorityLabel} : ${priority}\n" +
@@ -36,7 +36,7 @@ class FlyBookAlertNotifyHandlerImplTest extends AbstractSpringIntegrationTest {
NoticeTemplate noticeTemplate=new NoticeTemplate();
noticeTemplate.setId(1L);
noticeTemplate.setName("FlyBook");
noticeTemplate.setTemplateContent("{targetLabel} : ${target}\n" +
noticeTemplate.setContent("{targetLabel} : ${target}\n" +
"<#if (monitorId??)>${monitorIdLabel} : ${monitorId} </#if>\n" +
"<#if (monitorName??)>${monitorNameLabel} : ${monitorName} </#if>\n" +
"${priorityLabel} : ${priority}\n" +
@@ -75,7 +75,7 @@ class HuaweiCloudSmnAlertNotifyHandlerImplTest extends AbstractSpringIntegration
var noticeTemplate=new NoticeTemplate();
noticeTemplate.setId(1L);
noticeTemplate.setName("HuaWeiCloud");
noticeTemplate.setTemplateContent("[${title}]\n" +
noticeTemplate.setContent("[${title}]\n" +
"${targetLabel} : ${target}\n" +
"<#if (monitorId??)>${monitorIdLabel} : ${monitorId} </#if>\n" +
"<#if (monitorName??)>${monitorNameLabel} : ${monitorName} </#if>\n" +
@@ -42,7 +42,7 @@ class SlackAlertNotifyHandlerImplTest extends AbstractSpringIntegrationTest {
var noticeTemplate=new NoticeTemplate();
noticeTemplate.setId(1L);
noticeTemplate.setName("Slack");
noticeTemplate.setTemplateContent("*[${title}]*\n" +
noticeTemplate.setContent("*[${title}]*\n" +
"${targetLabel} : ${target}\n" +
"<#if (monitorId??)>${monitorIdLabel} : ${monitorId} </#if>\n" +
"<#if (monitorName??)>${monitorNameLabel} : ${monitorName} </#if>\n" +
@@ -43,7 +43,7 @@ class TelegramBotAlertNotifyHandlerImplTest extends AbstractSpringIntegrationTes
NoticeTemplate noticeTemplate=new NoticeTemplate();
noticeTemplate.setId(1L);
noticeTemplate.setName("Telegram");
noticeTemplate.setTemplateContent("[${title}]\n" +
noticeTemplate.setContent("[${title}]\n" +
"${targetLabel} : ${target}\n" +
"<#if (monitorId??)>${monitorIdLabel} : ${monitorId} </#if>\n" +
"<#if (monitorName??)>${monitorNameLabel} : ${monitorName} </#if>\n" +
@@ -48,7 +48,7 @@ public class WeChatAppAlertNotifyHandlerImplTest extends AbstractSpringIntegrati
NoticeTemplate noticeTemplate=new NoticeTemplate();
noticeTemplate.setId(1L);
noticeTemplate.setName("WeChatApp");
noticeTemplate.setTemplateContent("");
noticeTemplate.setContent("");
Map<String, String> map = new HashMap<>();
map.put(CommonConstants.TAG_MONITOR_ID, "Mock monitor id");
map.put(CommonConstants.TAG_MONITOR_NAME, "Mock monitor name");
@@ -39,7 +39,7 @@ class WeWorkRobotAlertNotifyHandlerImplTest extends AbstractSpringIntegrationTes
NoticeTemplate noticeTemplate=new NoticeTemplate();
noticeTemplate.setId(1L);
noticeTemplate.setName("WeWork");
noticeTemplate.setTemplateContent("[${title}]\n" +
noticeTemplate.setContent("[${title}]\n" +
"${targetLabel} : ${target}\n" +
"<#if (monitorId??)>${monitorIdLabel} : ${monitorId} </#if>\n" +
"<#if (monitorName??)>${monitorNameLabel} : ${monitorName} </#if>\n" +
@@ -78,7 +78,7 @@ class NoticeConfigControllerTest {
NoticeTemplate template = new NoticeTemplate();
template.setId(5L);
template.setName("Dingding");
template.setTemplateContent("[${title}]\n" +
template.setContent("[${title}]\n" +
"${targetLabel} : ${target}\n" +
"<#if (monitorId??)>${monitorIdLabel} : ${monitorId} </#if>\n" +
"<#if (monitorName??)>${monitorNameLabel} : ${monitorName} </#if>\n" +
@@ -6,26 +6,21 @@ import org.dromara.hertzbeat.common.constants.CommonConstants;
import org.dromara.hertzbeat.common.entity.alerter.Alert;
import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate;
import org.dromara.hertzbeat.manager.service.impl.MailServiceImpl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import java.io.IOException;
import java.util.Map;
import java.util.ResourceBundle;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.lenient;
/**
* Test case for {@link MailService}
@@ -59,9 +54,9 @@ class MailServiceTest {
alert.setPriority(CommonConstants.ALERT_PRIORITY_CODE_CRITICAL);
noticeTemplate.setId(1L);
noticeTemplate.setName("test");
noticeTemplate.setTemplateContent("result");
noticeTemplate.setContent("result");
assertEquals("result", mailService.buildAlertHtmlTemplate(alert,noticeTemplate));
assertNotNull(mailService.buildAlertHtmlTemplate(alert,noticeTemplate));
}
}
}
Executable → Regular
View File
Executable → Regular
View File
+2 -2
View File
@@ -4,10 +4,10 @@ export class NoticeTemplate {
// 通知信息方式: 0-手机短信 1-邮箱 2-webhook 3-微信公众号 4-企业微信机器人 5-钉钉机器人 6-飞书机器人
// 7-Telegram机器人 8-SlackWebHook 9-Discord机器人 10-企业微信应用消息 11-华为云SMN
type!: number;
presetTemplate!: boolean;
preset!: boolean;
creator!: string;
modifier!: string;
templateContent!: string;
content!: string;
gmtCreate!: number;
gmtUpdate!: number;
}
@@ -134,161 +134,6 @@
</tbody>
</nz-table>
</nz-tab>
<!-- 自定义通知模板 -->
<nz-tab [nzTitle]="'alert.notice.template' | i18n">
<div style="margin-bottom: 20px">
<button (click)="syncTemplate()" nz-button nzType="primary">
<i nz-icon nzTheme="outline" nzType="sync"></i>
{{ 'common.refresh' | i18n }}
</button>
<button (click)="onNewNoticeTemplate()" nz-button nzType="primary">
<i nz-icon nzTheme="outline" nzType="appstore-add"></i>
{{ 'alert.notice.template.new' | i18n }}
</button>
</div>
<nz-table
#templateFixedTable
[nzData]="templates.concat(defaultTemplates)"
[nzLoading]="templateTableLoading"
[nzScroll]="{ x: '1240px', y: '100%' }"
nzFrontPagination="false"
>
<thead>
<tr>
<th nzAlign="center" nzWidth="25%">{{ 'alert.notice.template.name' | i18n }}</th>
<th nzAlign="center" nzWidth="15%">{{ 'alert.notice.template.supplier' | i18n }}</th>
<th nzAlign="center" nzWidth="15%">{{ 'common.edit-time' | i18n }}</th>
<th nzAlign="center" nzWidth="25%">{{ 'common.edit' | i18n }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of templateFixedTable.data">
<td nzAlign="center">
<span>{{ data.name }}</span>
</td>
<td nzAlign="center">
<span *ngIf="data.presetTemplate == false">
<nz-tag *ngIf="data.type == 0" nzColor="orange">
<span>{{ 'alert.applier.type.sms' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 1" nzColor="orange">
<span>{{ 'alert.applier.type.email' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 2" nzColor="orange">
<span>WebHook</span>
</nz-tag>
<nz-tag *ngIf="data.type == 3" nzColor="orange">
<span>{{ 'alert.applier.type.wechat' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 4" nzColor="orange">
<span>{{ 'alert.applier.type.wework' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 5" nzColor="orange">
<span>{{ 'alert.applier.type.ding' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 6" nzColor="orange">
<span>{{ 'alert.applier.type.fei-shu' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 7" nzColor="orange">
<span>{{ 'alert.applier.type.telegram' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 8" nzColor="orange">
<span>{{ 'alert.applier.type.slack' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 9" nzColor="orange">
<span>{{ 'alert.applier.type.discord' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 10" nzColor="orange">
<span>{{ 'alert.applier.type.weChatApp' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 11" nzColor="orange">
<span>{{ 'alert.applier.type.smn' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 12" nzColor="orange">
<span>{{ 'alert.applier.type.serverchan' | i18n }}</span>
</nz-tag>
</span>
<span *ngIf="data.presetTemplate == true">
<nz-tag *ngIf="data.name == 'sms'" nzColor="orange">
<span>{{ 'alert.applier.type.sms' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'mailAlarm'" nzColor="orange">
<span>{{ 'alert.applier.type.email' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'WebHook'" nzColor="orange">
<span>WebHook</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'wechat'" nzColor="orange">
<span>{{ 'alert.applier.type.wechat' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifyWeWorkRobot'" nzColor="orange">
<span>{{ 'alert.applier.type.wework' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifyDingTalkRobot'" nzColor="orange">
<span>{{ 'alert.applier.type.ding' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifyFlyBook'" nzColor="orange">
<span>{{ 'alert.applier.type.fei-shu' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifyTelegramBot'" nzColor="orange">
<span>{{ 'alert.applier.type.telegram' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifySlack'" nzColor="orange">
<span>{{ 'alert.applier.type.slack' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifyDiscordBot'" nzColor="orange">
<span>{{ 'alert.applier.type.discord' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifyWeWorkApp'" nzColor="orange">
<span>{{ 'alert.applier.type.weChatApp' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifySmn'" nzColor="orange">
<span>{{ 'alert.applier.type.smn' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifyServerChan'" nzColor="orange">
<span>{{ 'alert.applier.type.serverchan' | i18n }}</span>
</nz-tag>
</span>
</td>
<td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date : 'YYYY-MM-dd HH:mm:ss' }}</td>
<td nzAlign="center">
<span *ngIf="data.presetTemplate == false">
<button
(click)="onEditOneNoticeTemplate(data)"
[nzTooltipTitle]="'alert.notice.template.edit' | i18n"
nz-button
nz-tooltip
nzType="primary"
>
<i nz-icon nzTheme="outline" nzType="edit"></i>
</button>
<button
(click)="onDeleteOneNoticeTemplate(data.id)"
[nzTooltipTitle]="'alert.notice.template.delete' | i18n"
nz-button
nz-tooltip
nzDanger
nzType="primary"
>
<i nz-icon nzTheme="outline" nzType="delete"></i>
</button>
</span>
<span *ngIf="data.presetTemplate == true">
<button
(click)="onShowOneNoticeTemplate(data)"
[nzTooltipTitle]="'alert.notice.template.showExample' | i18n"
nz-button
nz-tooltip
nzType="primary"
>
<i nz-icon nzTheme="outline" nzType="question-circle"></i>
</button>
</span>
</td>
</tr>
</tbody>
</nz-table>
</nz-tab>
<nz-tab [nzTitle]="'alert.notice.rule' | i18n">
<div style="margin-bottom: 20px">
<button (click)="syncRule()" nz-button nzType="primary">
@@ -363,9 +208,163 @@
</tbody>
</nz-table>
</nz-tab>
<nz-tab [nzTitle]="'alert.notice.template' | i18n">
<div style="margin-bottom: 20px">
<button (click)="syncTemplate()" nz-button nzType="primary">
<i nz-icon nzTheme="outline" nzType="sync"></i>
{{ 'common.refresh' | i18n }}
</button>
<button (click)="onNewNoticeTemplate()" nz-button nzType="primary">
<i nz-icon nzTheme="outline" nzType="appstore-add"></i>
{{ 'alert.notice.template.new' | i18n }}
</button>
</div>
<nz-table
#templateFixedTable
[nzData]="templates"
[nzLoading]="templateTableLoading"
[nzScroll]="{ x: '1240px', y: '100%' }"
nzFrontPagination="false"
>
<thead>
<tr>
<th nzAlign="center" nzWidth="25%">{{ 'alert.notice.template.name' | i18n }}</th>
<th nzAlign="center" nzWidth="15%">{{ 'alert.notice.template.type' | i18n }}</th>
<th nzAlign="center" nzWidth="15%">{{ 'common.edit-time' | i18n }}</th>
<th nzAlign="center" nzWidth="25%">{{ 'common.edit' | i18n }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of templateFixedTable.data">
<td nzAlign="center">
<span>{{ data.name }}</span>
</td>
<td nzAlign="center">
<span *ngIf="!data.preset">
<nz-tag *ngIf="data.type == 0" nzColor="orange">
<span>{{ 'alert.applier.type.sms' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 1" nzColor="orange">
<span>{{ 'alert.applier.type.email' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 2" nzColor="orange">
<span>WebHook</span>
</nz-tag>
<nz-tag *ngIf="data.type == 3" nzColor="orange">
<span>{{ 'alert.applier.type.wechat' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 4" nzColor="orange">
<span>{{ 'alert.applier.type.wework' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 5" nzColor="orange">
<span>{{ 'alert.applier.type.ding' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 6" nzColor="orange">
<span>{{ 'alert.applier.type.fei-shu' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 7" nzColor="orange">
<span>{{ 'alert.applier.type.telegram' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 8" nzColor="orange">
<span>{{ 'alert.applier.type.slack' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 9" nzColor="orange">
<span>{{ 'alert.applier.type.discord' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 10" nzColor="orange">
<span>{{ 'alert.applier.type.weChatApp' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 11" nzColor="orange">
<span>{{ 'alert.applier.type.smn' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.type == 12" nzColor="orange">
<span>{{ 'alert.applier.type.serverchan' | i18n }}</span>
</nz-tag>
</span>
<span *ngIf="data.preset">
<nz-tag *ngIf="data.name == 'sms'" nzColor="orange">
<span>{{ 'alert.applier.type.sms' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'mailAlarm'" nzColor="orange">
<span>{{ 'alert.applier.type.email' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'WebHook'" nzColor="orange">
<span>WebHook</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'wechat'" nzColor="orange">
<span>{{ 'alert.applier.type.wechat' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifyWeWorkRobot'" nzColor="orange">
<span>{{ 'alert.applier.type.wework' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifyDingTalkRobot'" nzColor="orange">
<span>{{ 'alert.applier.type.ding' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifyFlyBook'" nzColor="orange">
<span>{{ 'alert.applier.type.fei-shu' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifyTelegramBot'" nzColor="orange">
<span>{{ 'alert.applier.type.telegram' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifySlack'" nzColor="orange">
<span>{{ 'alert.applier.type.slack' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifyDiscordBot'" nzColor="orange">
<span>{{ 'alert.applier.type.discord' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifyWeWorkApp'" nzColor="orange">
<span>{{ 'alert.applier.type.weChatApp' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifySmn'" nzColor="orange">
<span>{{ 'alert.applier.type.smn' | i18n }}</span>
</nz-tag>
<nz-tag *ngIf="data.name == 'alertNotifyServerChan'" nzColor="orange">
<span>{{ 'alert.applier.type.serverchan' | i18n }}</span>
</nz-tag>
</span>
</td>
<td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date : 'YYYY-MM-dd HH:mm:ss' }}</td>
<td nzAlign="center">
<span *ngIf="!data.preset">
<button
(click)="onEditOneNoticeTemplate(data)"
[nzTooltipTitle]="'alert.notice.template.edit' | i18n"
nz-button
nz-tooltip
nzType="primary"
>
<i nz-icon nzTheme="outline" nzType="edit"></i>
</button>
<button
(click)="onDeleteOneNoticeTemplate(data.id)"
[nzTooltipTitle]="'alert.notice.template.delete' | i18n"
nz-button
nz-tooltip
nzDanger
nzType="primary"
>
<i nz-icon nzTheme="outline" nzType="delete"></i>
</button>
</span>
<span *ngIf="data.preset">
<button
(click)="onShowOneNoticeTemplate(data)"
[nzTooltipTitle]="'alert.notice.template.showExample' | i18n"
nz-button
nz-tooltip
nzType="primary"
>
<i nz-icon nzTheme="outline" nzType="eye"></i>
</button>
</span>
</td>
</tr>
</tbody>
</nz-table>
</nz-tab>
</nz-tabset>
<!-- 新增或修改通知接收配置弹出框 -->
<!-- 新增或修改通知策略弹出框 -->
<nz-modal
(nzOnCancel)="onManageRuleModalCancel()"
(nzOnOk)="onManageRuleModalOk()"
@@ -506,7 +505,7 @@
</form>
</div>
</nz-modal>
<!-- 新增或修改通知接收配置弹出框 -->
<!-- 新增或修改消息接收人弹出框 -->
<nz-modal
(nzOnCancel)="onManageReceiverModalCancel()"
(nzOnOk)="onManageReceiverModalOk()"
@@ -730,62 +729,6 @@
</form>
</div>
</nz-modal>
<!-- 新增或修改通知策略弹出框 -->
<nz-modal
(nzOnCancel)="onManageTemplateModalCancel()"
(nzOnOk)="onManageTemplateModalOk()"
[(nzVisible)]="isManageTemplateModalVisible"
[nzOkLoading]="isManageTemplateModalOkLoading"
[nzTitle]="isManageTemplateModalAdd ? ('alert.notice.template.new' | i18n) : ('alert.notice.template.edit' | i18n)"
nzMaskClosable="false"
nzWidth="40%"
>
<div *nzModalContent class="-inner-content">
<form #templateForm="ngForm" nz-form>
<nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="template_name" nzRequired="true">{{ 'alert.notice.template.name' | i18n }}</nz-form-label>
<nz-form-control [nzErrorTip]="'validation.required' | i18n" [nzSpan]="12">
<input [(ngModel)]="template.name" id="template_name" name="template_name" nz-input required type="text" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzFor="type" nzRequired="true" nzSpan="7">{{ 'alert.notice.receiver.type' | i18n }} </nz-form-label>
<nz-form-control [nzErrorTip]="'validation.required' | i18n" nzSpan="12">
<nz-select [(ngModel)]="template.type" [nzOptionOverflowSize]="10" id="type1" name="type" nzPlaceHolder="Choose" required>
<nz-option [nzLabel]="'alert.applier.type.sms' | i18n" [nzValue]="0"></nz-option>
<nz-option [nzLabel]="'alert.applier.type.email' | i18n" [nzValue]="1"></nz-option>
<nz-option [nzValue]="2" nzLabel="WebHook"></nz-option>
<nz-option [nzLabel]="'alert.applier.type.discord' | i18n" [nzValue]="9"></nz-option>
<nz-option [nzLabel]="'alert.applier.type.slack' | i18n" [nzValue]="8"></nz-option>
<nz-option [nzLabel]="'alert.applier.type.wework' | i18n" [nzValue]="4"></nz-option>
<nz-option [nzLabel]="'alert.applier.type.ding' | i18n" [nzValue]="5"></nz-option>
<nz-option [nzLabel]="'alert.applier.type.fei-shu' | i18n" [nzValue]="6"></nz-option>
<nz-option [nzLabel]="'alert.applier.type.telegram' | i18n" [nzValue]="7"></nz-option>
<nz-option [nzLabel]="'alert.applier.type.weChatApp' | i18n" [nzValue]="10"></nz-option>
<nz-option [nzLabel]="'alert.applier.type.smn' | i18n" [nzValue]="11"></nz-option>
<nz-option [nzLabel]="'alert.applier.type.serverchan' | i18n" [nzValue]="12"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="template_content" nzRequired="true">{{ 'alert.notice.template.content' | i18n }}</nz-form-label>
<nz-form-control [nzErrorTip]="'validation.required' | i18n" [nzSpan]="12">
<textarea
[(ngModel)]="template.templateContent"
id="template_content"
name="template_content"
nz-input
required
style="white-space: nowrap; overflow: scroll; height: 120px"
type="textarea"
></textarea>
</nz-form-control>
</nz-form-item>
</form>
</div>
</nz-modal>
<!-- 新增或修改通知模板弹出框 -->
<nz-modal
(nzOnCancel)="onManageTemplateModalCancel()"
@@ -829,7 +772,7 @@
<nz-form-label [nzSpan]="7" nzFor="template_content" nzRequired="true">{{ 'alert.notice.template.content' | i18n }}</nz-form-label>
<nz-form-control [nzErrorTip]="'validation.required' | i18n" [nzSpan]="12">
<textarea
[(ngModel)]="template.templateContent"
[(ngModel)]="template.content"
id="template_content"
name="template_content"
nz-input
@@ -854,7 +797,7 @@
>
<div *nzModalContent class="-inner-content">
<textarea
[(ngModel)]="template.templateContent"
[(ngModel)]="template.content"
id="template_content_example"
name="template_content"
style="white-space: nowrap; overflow: scroll; width: 100%; height: 200px"
@@ -22,7 +22,6 @@ export class AlertNoticeComponent implements OnInit {
receivers!: NoticeReceiver[];
receiverTableLoading: boolean = true;
templates: NoticeTemplate[] = [];
defaultTemplates: NoticeTemplate[] = [];
templateTableLoading: boolean = true;
rules!: NoticeRule[];
ruleTableLoading: boolean = true;
@@ -127,22 +126,6 @@ export class AlertNoticeComponent implements OnInit {
templatesInit$.unsubscribe();
}
);
let defalutTemplatesInit$ = this.noticeTemplateSvc.getDefaultNoticeTemplates().subscribe(
message => {
this.templateTableLoading = false;
if (message.code === 0) {
this.defaultTemplates = message.data;
} else {
console.warn(message.msg);
}
defalutTemplatesInit$.unsubscribe();
},
error => {
console.error(error.msg);
this.templateTableLoading = false;
defalutTemplatesInit$.unsubscribe();
}
);
}
loadRulesTable() {
@@ -773,7 +756,7 @@ export class AlertNoticeComponent implements OnInit {
onManageTemplateModalOk() {
this.isManageTemplateModalOkLoading = true;
if (this.isManageTemplateModalAdd) {
this.template.presetTemplate = false;
this.template.preset = false;
const modalOk$ = this.noticeTemplateSvc
.newNoticeTemplate(this.template)
.pipe(
+1 -1
View File
@@ -229,7 +229,7 @@
"alert.notice.template.delete": "Delete Template",
"alert.notice.template.name": "Template Name",
"alert.notice.template.example": "Template Example",
"alert.notice.template.supplier": "Supplier Name",
"alert.notice.template.type": "Notice Type",
"alert.notice.template.content": "Template Content",
"alert.notice.receiver": "Message Receiver",
"alert.notice.receiver.new": "New Receiver",
+1 -1
View File
@@ -229,7 +229,7 @@
"alert.notice.template.delete": "删除通知模板",
"alert.notice.template.name": "模板名称",
"alert.notice.template.example": "模板示例",
"alert.notice.template.supplier": "供应商名称",
"alert.notice.template.type": "通知方式",
"alert.notice.template.content": "通知模板内容",
"alert.notice.receiver": "消息接收人",
"alert.notice.receiver.new": "新增接收人",
+1 -1
View File
@@ -228,7 +228,7 @@
"alert.notice.template.delete": "刪除通知模板",
"alert.notice.template.name": "模板名稱",
"alert.notice.template.example": "模板實例",
"alert.notice.template.supplier": "供應商名稱",
"alert.notice.template.type": "通知方式",
"alert.notice.template.content": "通知模板内容",
"alert.notice.receiver": "消息接收人",
"alert.notice.receiver.new": "新增接收人",