diff --git a/alerter/src/main/java/org/dromara/hertzbeat/alert/calculate/CalculateAlarm.java b/alerter/src/main/java/org/dromara/hertzbeat/alert/calculate/CalculateAlarm.java index dc611a4be03..49fa3d74afa 100644 --- a/alerter/src/main/java/org/dromara/hertzbeat/alert/calculate/CalculateAlarm.java +++ b/alerter/src/main/java/org/dromara/hertzbeat/alert/calculate/CalculateAlarm.java @@ -23,7 +23,6 @@ import com.googlecode.aviator.exception.ExpressionRuntimeException; import com.googlecode.aviator.exception.ExpressionSyntaxErrorException; import org.dromara.hertzbeat.alert.AlerterWorkerPool; -import org.dromara.hertzbeat.alert.dao.AlertDao; import org.dromara.hertzbeat.alert.reduce.AlarmCommonReduce; import org.dromara.hertzbeat.alert.service.AlertService; import org.dromara.hertzbeat.common.queue.CommonDataQueue; @@ -35,11 +34,13 @@ import org.dromara.hertzbeat.common.entity.manager.Monitor; import org.dromara.hertzbeat.common.entity.message.CollectRep; import org.dromara.hertzbeat.common.constants.CommonConstants; +import org.dromara.hertzbeat.common.support.event.SystemConfigChangeEvent; import org.dromara.hertzbeat.common.util.CommonUtil; import org.dromara.hertzbeat.common.util.ResourceBundleUtil; import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Configuration; +import org.springframework.context.event.EventListener; import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Component; import javax.persistence.criteria.Predicate; import java.util.*; @@ -55,7 +56,7 @@ * * @author tom */ -@Configuration +@Component @Slf4j public class CalculateAlarm { @@ -71,7 +72,7 @@ public class CalculateAlarm { private final CommonDataQueue dataQueue; private final AlertDefineService alertDefineService; private final AlarmCommonReduce alarmCommonReduce; - private final ResourceBundle bundle; + private ResourceBundle bundle; private final AlertService alertService; public CalculateAlarm(AlerterWorkerPool workerPool, CommonDataQueue dataQueue, @@ -366,4 +367,10 @@ private List queryAvailabilityAlerts(long monitorId, Alert restoreAlert) //query results return alertService.getAlerts(specification); } + + @EventListener(SystemConfigChangeEvent.class) + public void onEvent(SystemConfigChangeEvent event) { + log.info("calculate alarm receive system config change event: {}.", event.getSource()); + this.bundle = ResourceBundleUtil.getBundle("alerter"); + } } diff --git a/common/src/main/java/org/dromara/hertzbeat/common/constants/CommonConstants.java b/common/src/main/java/org/dromara/hertzbeat/common/constants/CommonConstants.java index 1902dd7876e..4e6b751d261 100644 --- a/common/src/main/java/org/dromara/hertzbeat/common/constants/CommonConstants.java +++ b/common/src/main/java/org/dromara/hertzbeat/common/constants/CommonConstants.java @@ -291,4 +291,9 @@ public interface CommonConstants { * default main collector name */ String MAIN_COLLECTOR_NODE = "main-default-collector"; + + /** + * locale spilt + */ + String LOCALE_SEPARATOR = "_"; } diff --git a/common/src/main/java/org/dromara/hertzbeat/common/support/event/SystemConfigChangeEvent.java b/common/src/main/java/org/dromara/hertzbeat/common/support/event/SystemConfigChangeEvent.java new file mode 100644 index 00000000000..759831e7811 --- /dev/null +++ b/common/src/main/java/org/dromara/hertzbeat/common/support/event/SystemConfigChangeEvent.java @@ -0,0 +1,14 @@ +package org.dromara.hertzbeat.common.support.event; + +import org.springframework.context.ApplicationEvent; + +/** + * the event for system config change + * @author tom + */ +public class SystemConfigChangeEvent extends ApplicationEvent { + + public SystemConfigChangeEvent(Object source) { + super(source); + } +} diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/AbstractAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/AbstractAlertNotifyHandlerImpl.java index 7092034c7e3..65be6726a7b 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/AbstractAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/AbstractAlertNotifyHandlerImpl.java @@ -17,11 +17,14 @@ package org.dromara.hertzbeat.manager.component.alerter.impl; +import lombok.extern.slf4j.Slf4j; import org.dromara.hertzbeat.alert.AlerterProperties; import org.dromara.hertzbeat.common.entity.alerter.Alert; +import org.dromara.hertzbeat.common.support.event.SystemConfigChangeEvent; import org.dromara.hertzbeat.common.util.CommonUtil; import org.dromara.hertzbeat.common.util.ResourceBundleUtil; import org.dromara.hertzbeat.manager.component.alerter.AlertNotifyHandler; +import org.springframework.context.event.EventListener; import org.springframework.web.client.RestTemplate; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; @@ -37,9 +40,10 @@ * @version 2.1 * Created by Musk.Chen on 2023/1/16 */ -abstract class AbstractAlertNotifyHandlerImpl implements AlertNotifyHandler { +@Slf4j +public abstract class AbstractAlertNotifyHandlerImpl implements AlertNotifyHandler { - protected final ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter"); + protected ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter"); protected static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); @Resource @@ -81,5 +85,10 @@ protected String renderContent(Alert alert) { * @return Thymeleaf模板名称 */ protected abstract String templateName(); - + + @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"); + } } diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DingTalkRobotAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DingTalkRobotAlertNotifyHandlerImpl.java index fc0c111ebb4..95a5951c9f5 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DingTalkRobotAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DingTalkRobotAlertNotifyHandlerImpl.java @@ -36,7 +36,7 @@ @Component @RequiredArgsConstructor @Slf4j -final class DingTalkRobotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { +public class DingTalkRobotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { @Override public void send(NoticeReceiver receiver, Alert alert) { diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DiscordBotAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DiscordBotAlertNotifyHandlerImpl.java index e0295691e6b..6970ec8c894 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DiscordBotAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DiscordBotAlertNotifyHandlerImpl.java @@ -23,7 +23,7 @@ @Component @RequiredArgsConstructor @Slf4j -final class DiscordBotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { +public class DiscordBotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { @Override public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeException { diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java index 981d51bdad6..946f63ae119 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java @@ -23,6 +23,7 @@ import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.GeneralConfig; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +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.dao.GeneralConfigDao; @@ -30,6 +31,7 @@ import org.dromara.hertzbeat.manager.service.MailService; import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.event.EventListener; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.MimeMessageHelper; @@ -47,7 +49,7 @@ @Component @RequiredArgsConstructor @Slf4j -final class EmailAlertNotifyHandlerImpl implements AlertNotifyHandler { +public class EmailAlertNotifyHandlerImpl implements AlertNotifyHandler { private final JavaMailSender javaMailSender; @@ -74,7 +76,7 @@ final class EmailAlertNotifyHandlerImpl implements AlertNotifyHandler { private static final String TYPE = "email"; - private final ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter"); + private ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter"); @Override public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeException { @@ -134,4 +136,10 @@ public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeExcepti public byte type() { return 1; } + + @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"); + } } diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/FlyBookAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/FlyBookAlertNotifyHandlerImpl.java index ae7b338e6c8..1a1cc6a4575 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/FlyBookAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/FlyBookAlertNotifyHandlerImpl.java @@ -40,7 +40,7 @@ @Component @RequiredArgsConstructor @Slf4j -final class FlyBookAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { +public class FlyBookAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { @Override public void send(NoticeReceiver receiver, Alert alert) { diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/HuaweiCloudSmnAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/HuaweiCloudSmnAlertNotifyHandlerImpl.java index 436718a0f0b..1c4797a2e0c 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/HuaweiCloudSmnAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/HuaweiCloudSmnAlertNotifyHandlerImpl.java @@ -26,12 +26,10 @@ import lombok.extern.slf4j.Slf4j; import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; -import org.dromara.hertzbeat.common.util.ResourceBundleUtil; import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; import org.springframework.stereotype.Component; import java.util.Map; -import java.util.ResourceBundle; import java.util.concurrent.ConcurrentHashMap; /** @@ -41,9 +39,7 @@ @Component @RequiredArgsConstructor @Slf4j -final class HuaweiCloudSmnAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { - private final ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter"); - +public class HuaweiCloudSmnAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { private final Map smnClientMap = new ConcurrentHashMap<>(); @Override diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/ServerChanAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/ServerChanAlertNotifyHandlerImpl.java index 10c6c25ba30..01072ad4a48 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/ServerChanAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/ServerChanAlertNotifyHandlerImpl.java @@ -9,8 +9,8 @@ import org.springframework.http.*; import org.springframework.stereotype.Component; /** + * Server酱发送 * @author zqr10159 - * @description Server酱发送 */ @Component @RequiredArgsConstructor diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SlackAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SlackAlertNotifyHandlerImpl.java index 7a7f7b3966d..1e783c9d4d3 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SlackAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SlackAlertNotifyHandlerImpl.java @@ -44,7 +44,7 @@ @Component @RequiredArgsConstructor @Slf4j -final class SlackAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { +public class SlackAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { private static final String SUCCESS = "ok"; private final RestTemplate restTemplate; diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SmsAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SmsAlertNotifyHandlerImpl.java index acea5478741..5ec20257655 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SmsAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SmsAlertNotifyHandlerImpl.java @@ -39,7 +39,7 @@ @RequiredArgsConstructor @Slf4j @ConditionalOnProperty("common.sms.tencent.app-id") -final class SmsAlertNotifyHandlerImpl implements AlertNotifyHandler { +public class SmsAlertNotifyHandlerImpl implements AlertNotifyHandler { private final TencentSmsClient tencentSmsClient; diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/TelegramBotAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/TelegramBotAlertNotifyHandlerImpl.java index cdc0f8fa8ef..55cf535b854 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/TelegramBotAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/TelegramBotAlertNotifyHandlerImpl.java @@ -29,7 +29,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.http.*; import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; /** * Send alarm information by Telegram Bot @@ -42,8 +41,7 @@ @Component @RequiredArgsConstructor @Slf4j -final class TelegramBotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { - private final RestTemplate restTemplate; +public class TelegramBotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { @Override public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeException { diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAlertNotifyHandlerImpl.java index 9acdf9e6dd1..4f5432b0739 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAlertNotifyHandlerImpl.java @@ -25,7 +25,7 @@ * @author Musk.Chen * */ -final class WeChatAlertNotifyHandlerImpl implements AlertNotifyHandler { +public class WeChatAlertNotifyHandlerImpl implements AlertNotifyHandler { @Override public void send(NoticeReceiver receiver, Alert alert) { // todo diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAppAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAppAlertNotifyHandlerImpl.java index e557508af9f..5d63f95ce1e 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAppAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAppAlertNotifyHandlerImpl.java @@ -1,10 +1,10 @@ package org.dromara.hertzbeat.manager.component.alerter.impl; -import com.alibaba.fastjson.JSON; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.util.JsonUtil; import org.dromara.hertzbeat.manager.component.alerter.AlertNotifyHandler; import org.dromara.hertzbeat.manager.pojo.dto.WeChatAppDTO; import org.dromara.hertzbeat.manager.pojo.dto.WeChatAppReq; @@ -21,7 +21,6 @@ /** * WeChat app alert notify impl * @author hdd - * @create 2023/04/04 */ @Component @RequiredArgsConstructor @@ -61,7 +60,7 @@ public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeExcepti if (Objects.nonNull(entityResponse.getBody())) { String accessToken = entityResponse.getBody().getAccessToken(); WeChatAppDTO.TextDTO textDTO = new WeChatAppDTO.TextDTO(); - textDTO.setContent(JSON.toJSONString(alert)); + textDTO.setContent(JsonUtil.toJson(alert)); WeChatAppDTO weChatAppDTO = WeChatAppDTO.builder() .toUser(DEFAULT_ALL) .msgType(DEFAULT_TYPE) diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WebHookAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WebHookAlertNotifyHandlerImpl.java index fe9b1eb3074..2e9a65254b8 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WebHookAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WebHookAlertNotifyHandlerImpl.java @@ -34,7 +34,7 @@ @Component @RequiredArgsConstructor @Slf4j -final class WebHookAlertNotifyHandlerImpl implements AlertNotifyHandler { +public class WebHookAlertNotifyHandlerImpl implements AlertNotifyHandler { private final RestTemplate restTemplate; @Override diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/config/SystemCommandLineRunner.java b/manager/src/main/java/org/dromara/hertzbeat/manager/config/SystemCommandLineRunner.java new file mode 100644 index 00000000000..606c9192744 --- /dev/null +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/config/SystemCommandLineRunner.java @@ -0,0 +1,63 @@ +package org.dromara.hertzbeat.manager.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.dromara.hertzbeat.common.constants.CommonConstants; +import org.dromara.hertzbeat.common.entity.manager.GeneralConfig; +import org.dromara.hertzbeat.manager.dao.GeneralConfigDao; +import org.dromara.hertzbeat.manager.pojo.dto.SystemConfig; +import org.dromara.hertzbeat.manager.service.impl.SystemGeneralConfigServiceImpl; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Locale; +import java.util.TimeZone; + +/** + * @author ceilzcx + * @since 4/7/2023 + */ +@Component +public class SystemCommandLineRunner implements CommandLineRunner { + + private static final Integer LANG_REGION_LENGTH = 2; + + @Resource + private SystemGeneralConfigServiceImpl systemGeneralConfigService; + + @Resource + protected GeneralConfigDao generalConfigDao; + + @Resource + protected ObjectMapper objectMapper; + + @Override + public void run(String... args) throws Exception { + SystemConfig systemConfig = systemGeneralConfigService.getConfig(); + if (systemConfig != null) { + if (systemConfig.getTimeZoneId() != null) { + TimeZone.setDefault(TimeZone.getTimeZone(systemConfig.getTimeZoneId())); + } + if (systemConfig.getLocale() != null) { + String[] arr = systemConfig.getLocale().split(CommonConstants.LOCALE_SEPARATOR); + if (arr.length == LANG_REGION_LENGTH) { + String language = arr[0]; + String country = arr[1]; + Locale.setDefault(new Locale(language, country)); + } + } + } else { + // init system config data + systemConfig = SystemConfig.builder().timeZoneId(TimeZone.getDefault().getID()) + .locale(Locale.getDefault().getLanguage() + CommonConstants.LOCALE_SEPARATOR + + Locale.getDefault().getCountry()) + .build(); + String contentJson = objectMapper.writeValueAsString(systemConfig); + GeneralConfig generalConfig2Save = GeneralConfig.builder() + .type(systemGeneralConfigService.type()) + .content(contentJson) + .build(); + generalConfigDao.save(generalConfig2Save); + } + } +} diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/controller/I18nController.java b/manager/src/main/java/org/dromara/hertzbeat/manager/controller/I18nController.java index 2eabac4ded6..bdf6c120232 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/controller/I18nController.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/controller/I18nController.java @@ -53,8 +53,8 @@ public ResponseEntity>> queryI18n( if (lang == null || "".equals(lang)) { lang = "zh-CN"; } - lang = "zh-cn".equalsIgnoreCase(lang) ? "zh-CN" : lang; - lang = "en-us".equalsIgnoreCase(lang) ? "en-US" : lang; + lang = "zh-cn".equalsIgnoreCase(lang) || "zh_cn".equalsIgnoreCase(lang) ? "zh-CN" : lang; + lang = "en-us".equalsIgnoreCase(lang) || "en_us".equalsIgnoreCase(lang) ? "en-US" : lang; Map i18nResource = appService.getI18nResources(lang); return ResponseEntity.ok(new Message<>(i18nResource)); } diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/pojo/dto/EmailNoticeSender.java b/manager/src/main/java/org/dromara/hertzbeat/manager/pojo/dto/EmailNoticeSender.java index d85d483adae..a7746b66880 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/pojo/dto/EmailNoticeSender.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/pojo/dto/EmailNoticeSender.java @@ -1,6 +1,8 @@ package org.dromara.hertzbeat.manager.pojo.dto; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import javax.validation.constraints.*; @@ -10,6 +12,8 @@ * @author zqr */ @Data +@NoArgsConstructor +@AllArgsConstructor public class EmailNoticeSender { @NotNull(message = "类型不能为空|Type cannot be empty") diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/pojo/dto/SystemConfig.java b/manager/src/main/java/org/dromara/hertzbeat/manager/pojo/dto/SystemConfig.java new file mode 100644 index 00000000000..94ec9ef1eda --- /dev/null +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/pojo/dto/SystemConfig.java @@ -0,0 +1,36 @@ +package org.dromara.hertzbeat.manager.pojo.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 系统配置 + * + * @author ceilzcx + * @since 4/7/2023 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SystemConfig { + + /** + * system time zone + * 系统时区 + */ + private String timeZoneId; + + /** + * system locale language region + * 系统语言地区 + */ + private String locale; + + /** + * layout ui theme + */ + private String theme; +} diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/service/GeneralConfigService.java b/manager/src/main/java/org/dromara/hertzbeat/manager/service/GeneralConfigService.java index d672dc91568..398ebfbe67a 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/service/GeneralConfigService.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/service/GeneralConfigService.java @@ -30,4 +30,10 @@ public interface GeneralConfigService { * @return 查询到的配置 */ T getConfig(); + + /** + * handler after save config + * @param config config + */ + default void handler(T config) {} } diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/AbstractGeneralConfigServiceImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/AbstractGeneralConfigServiceImpl.java index e488497eb81..3381f3afdcd 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/AbstractGeneralConfigServiceImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/AbstractGeneralConfigServiceImpl.java @@ -52,6 +52,7 @@ public void saveConfig(T config) { .build(); generalConfigDao.save(generalConfig2Save); log.info("配置保存成功|Configuration saved successfully"); + handler(getConfig()); } catch (JsonProcessingException e) { throw new IllegalArgumentException("Configuration saved failed: " + e.getMessage()); } diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/MailServiceImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/MailServiceImpl.java index cedbd94569e..939641e23a6 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/MailServiceImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/MailServiceImpl.java @@ -20,9 +20,11 @@ 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.support.event.SystemConfigChangeEvent; import org.dromara.hertzbeat.common.util.ResourceBundleUtil; import org.dromara.hertzbeat.manager.service.MailService; import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; @@ -84,4 +86,10 @@ public String buildAlertHtmlTemplate(final Alert alert) { context.setVariable("lastTriggerTime", alarmTime); return templateEngine.process("mailAlarm", context); } + + @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"); + } } diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/SystemGeneralConfigServiceImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/SystemGeneralConfigServiceImpl.java new file mode 100644 index 00000000000..af9d1177b69 --- /dev/null +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/SystemGeneralConfigServiceImpl.java @@ -0,0 +1,80 @@ +package org.dromara.hertzbeat.manager.service.impl; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.dromara.hertzbeat.common.constants.CommonConstants; +import org.dromara.hertzbeat.common.support.event.SystemConfigChangeEvent; +import org.dromara.hertzbeat.manager.dao.GeneralConfigDao; +import org.dromara.hertzbeat.manager.pojo.dto.SystemConfig; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.lang.reflect.Type; +import java.util.Locale; +import java.util.TimeZone; + +/** + * @author ceilzcx + * @since 4/7/2023 + */ +@Service +public class SystemGeneralConfigServiceImpl extends AbstractGeneralConfigServiceImpl { + + private static final Integer LANG_REGION_LENGTH = 2; + + @Resource + private ApplicationContext applicationContext; + + /** + * 构造方法,传入GeneralConfigDao、ObjectMapper和type。 + * + *

Constructor, passing in GeneralConfigDao, ObjectMapper and type.

+ * + * @param generalConfigDao 配置Dao对象 + * @param objectMapper JSON工具类对象 + */ + protected SystemGeneralConfigServiceImpl(GeneralConfigDao generalConfigDao, ObjectMapper objectMapper) { + super(generalConfigDao, objectMapper); + } + + @Override + public void handler(SystemConfig systemConfig) { + if (systemConfig != null) { + if (systemConfig.getTimeZoneId() != null) { + TimeZone.setDefault(TimeZone.getTimeZone(systemConfig.getTimeZoneId())); + } + if (systemConfig.getLocale() != null) { + String[] arr = systemConfig.getLocale().split(CommonConstants.LOCALE_SEPARATOR); + if (arr.length == LANG_REGION_LENGTH) { + String language = arr[0]; + String country = arr[1]; + Locale.setDefault(new Locale(language, country)); + } + } + applicationContext.publishEvent(new SystemConfigChangeEvent(applicationContext)); + } + } + + @Override + public String type() { + return "system"; + } + + /** + * 该方法用于获取NoticeSender类型的TypeReference,以供后续处理。 + * This method is used to get the TypeReference of NoticeSender type for subsequent processing. + * + * @return NoticeSender类型的TypeReference + * a TypeReference of NoticeSender type + */ + @Override + protected TypeReference getTypeReference() { + return new TypeReference<>() { + @Override + public Type getType() { + return SystemConfig.class; + } + }; + } +} diff --git a/web-app/src/app/pojo/SystemConfig.ts b/web-app/src/app/pojo/SystemConfig.ts new file mode 100644 index 00000000000..dc27a7ef441 --- /dev/null +++ b/web-app/src/app/pojo/SystemConfig.ts @@ -0,0 +1,4 @@ +export class SystemConfig { + timeZoneId!: string; + locale!: string; +} diff --git a/web-app/src/app/routes/setting/setting-routing.module.ts b/web-app/src/app/routes/setting/setting-routing.module.ts index d83934478cd..11fa8eb979d 100644 --- a/web-app/src/app/routes/setting/setting-routing.module.ts +++ b/web-app/src/app/routes/setting/setting-routing.module.ts @@ -4,6 +4,7 @@ import { RouterModule, Routes } from '@angular/router'; import { DefineComponent } from './define/define.component'; import { MessageServerComponent } from './settings/message-server/message-server.component'; import { SettingsComponent } from './settings/settings.component'; +import { SystemConfigComponent } from './settings/system-config/system-config.component'; import { SettingTagsComponent } from './tags/tags.component'; const routes: Routes = [ @@ -18,6 +19,11 @@ const routes: Routes = [ path: 'server', component: MessageServerComponent, data: { titleI18n: 'settings.server' } + }, + { + path: 'config', + component: SystemConfigComponent, + data: { titleI18n: 'settings.system-config' } } ] } diff --git a/web-app/src/app/routes/setting/setting.module.ts b/web-app/src/app/routes/setting/setting.module.ts index cfdecc6fb79..8f090b383e5 100644 --- a/web-app/src/app/routes/setting/setting.module.ts +++ b/web-app/src/app/routes/setting/setting.module.ts @@ -15,9 +15,16 @@ import { DefineComponent } from './define/define.component'; import { SettingRoutingModule } from './setting-routing.module'; import { MessageServerComponent } from './settings/message-server/message-server.component'; import { SettingsComponent } from './settings/settings.component'; +import { SystemConfigComponent } from './settings/system-config/system-config.component'; import { SettingTagsComponent } from './tags/tags.component'; -const COMPONENTS: Array> = [SettingTagsComponent, DefineComponent, SettingsComponent, MessageServerComponent]; +const COMPONENTS: Array> = [ + SettingTagsComponent, + DefineComponent, + SettingsComponent, + MessageServerComponent, + SystemConfigComponent +]; @NgModule({ imports: [ diff --git a/web-app/src/app/routes/setting/settings/settings.component.ts b/web-app/src/app/routes/setting/settings/settings.component.ts index ed252984560..78819403c0c 100644 --- a/web-app/src/app/routes/setting/settings/settings.component.ts +++ b/web-app/src/app/routes/setting/settings/settings.component.ts @@ -20,6 +20,10 @@ export class SettingsComponent implements AfterViewInit, OnDestroy { { key: 'server', title: this.i18nSvc.fanyi('settings.server') + }, + { + key: 'config', + title: this.i18nSvc.fanyi('settings.system-config') } ]; diff --git a/web-app/src/app/routes/setting/settings/system-config/system-config.component.html b/web-app/src/app/routes/setting/settings/system-config/system-config.component.html new file mode 100644 index 00000000000..e7906f9b1b3 --- /dev/null +++ b/web-app/src/app/routes/setting/settings/system-config/system-config.component.html @@ -0,0 +1,57 @@ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
diff --git a/web-app/src/app/routes/setting/settings/system-config/system-config.component.less b/web-app/src/app/routes/setting/settings/system-config/system-config.component.less new file mode 100644 index 00000000000..e69de29bb2d diff --git a/web-app/src/app/routes/setting/settings/system-config/system-config.component.spec.ts b/web-app/src/app/routes/setting/settings/system-config/system-config.component.spec.ts new file mode 100644 index 00000000000..daf4bd7f77f --- /dev/null +++ b/web-app/src/app/routes/setting/settings/system-config/system-config.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SystemConfigComponent } from './system-config.component'; + +describe('SystemConfigComponent', () => { + let component: SystemConfigComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SystemConfigComponent] + }).compileComponents(); + + fixture = TestBed.createComponent(SystemConfigComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/web-app/src/app/routes/setting/settings/system-config/system-config.component.ts b/web-app/src/app/routes/setting/settings/system-config/system-config.component.ts new file mode 100644 index 00000000000..de920befb7e --- /dev/null +++ b/web-app/src/app/routes/setting/settings/system-config/system-config.component.ts @@ -0,0 +1,86 @@ +import { DOCUMENT } from '@angular/common'; +import { ChangeDetectorRef, Component, Inject, OnInit } from '@angular/core'; +import { I18NService } from '@core'; +import { ALAIN_I18N_TOKEN, SettingsService } from '@delon/theme'; +import { NzNotificationService } from 'ng-zorro-antd/notification'; +import { finalize } from 'rxjs/operators'; + +import { SystemConfig } from '../../../../pojo/SystemConfig'; +import { GeneralConfigService } from '../../../../service/general-config.service'; + +@Component({ + selector: 'app-system-config', + templateUrl: './system-config.component.html', + styleUrls: ['./system-config.component.less'] +}) +export class SystemConfigComponent implements OnInit { + constructor( + private cdr: ChangeDetectorRef, + private notifySvc: NzNotificationService, + private configService: GeneralConfigService, + private settings: SettingsService, + @Inject(DOCUMENT) private doc: any, + @Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService + ) {} + + loading = true; + config!: SystemConfig; + + ngOnInit(): void { + this.loadSystemConfig(); + } + + loadSystemConfig() { + this.loading = true; + let configInit$ = this.configService.getGeneralConfig('system').subscribe( + message => { + if (message.code === 0) { + if (message.data) { + this.config = message.data; + } else { + this.config = new SystemConfig(); + } + } else { + console.warn(message.msg); + } + this.loading = false; + configInit$.unsubscribe(); + }, + error => { + console.error(error.msg); + this.loading = false; + configInit$.unsubscribe(); + } + ); + } + + onSaveSystemConfig() { + this.loading = true; + const configOk$ = this.configService + .saveGeneralConfig(this.config, 'system') + .pipe( + finalize(() => { + configOk$.unsubscribe(); + this.loading = false; + }) + ) + .subscribe( + message => { + if (message.code === 0) { + this.notifySvc.success(this.i18nSvc.fanyi('common.notify.apply-success'), ''); + let language = this.config.locale.replace('_', '-'); + this.i18nSvc.loadLangData(language).subscribe(res => { + this.i18nSvc.use(language, res); + this.settings.setLayout('lang', language); + setTimeout(() => this.doc.location.reload()); + }); + } else { + this.notifySvc.error(this.i18nSvc.fanyi('common.notify.apply-fail'), message.msg); + } + }, + error => { + this.notifySvc.error(this.i18nSvc.fanyi('common.notify.apply-fail'), error.msg); + } + ); + } +} diff --git a/web-app/src/assets/i18n/en-US.json b/web-app/src/assets/i18n/en-US.json index 88de8f546ce..e23bca846f0 100644 --- a/web-app/src/assets/i18n/en-US.json +++ b/web-app/src/assets/i18n/en-US.json @@ -446,6 +446,13 @@ "settings.server.email.setting": "Configure Email Server", "settings.server.sms": "SMS Server", "settings.server.sms.setting": "Configure SMS Server", + "settings.system-config": "System Configuration", + "settings.system-config.locale": "System Language", + "settings.system-config.locale.zh_CN": "Simplified Chinese(zh_CN)", + "settings.system-config.locale.zh_TW": "Traditional Chinese(zh_TW)", + "settings.system-config.locale.en_US": "English(en_US)", + "settings.system-config.timezone": "System Time Zone", + "settings.system-config.ok": "Confirm Update", "collector": "Collector", "collector.status": "Online Status", "collector.task": "Number of Tasks", diff --git a/web-app/src/assets/i18n/zh-CN.json b/web-app/src/assets/i18n/zh-CN.json index 4310548d7eb..ed34dc9709d 100644 --- a/web-app/src/assets/i18n/zh-CN.json +++ b/web-app/src/assets/i18n/zh-CN.json @@ -444,6 +444,13 @@ "settings.server.email.setting": "配置邮件服务器", "settings.server.sms": "短信服务器", "settings.server.sms.setting": "配置短信服务器", + "settings.system-config": "系统配置", + "settings.system-config.locale": "系统语言", + "settings.system-config.locale.zh_CN": "简体中文(zh_CN)", + "settings.system-config.locale.zh_TW": "繁体中文(zh_TW)", + "settings.system-config.locale.en_US": "英语(en_US)", + "settings.system-config.timezone": "系统时区", + "settings.system-config.ok": "确认更新", "collector": "采集器", "collector.status": "运行状态", "collector.task": "任务数量", diff --git a/web-app/src/assets/i18n/zh-TW.json b/web-app/src/assets/i18n/zh-TW.json index a694281011f..0dade98f1f5 100644 --- a/web-app/src/assets/i18n/zh-TW.json +++ b/web-app/src/assets/i18n/zh-TW.json @@ -442,6 +442,13 @@ "settings.server.email.setting": "配置郵件服務器", "settings.server.sms": "短信服務器", "settings.server.sms.setting": "配置短信服務器", + "settings.system-config": "系統配置", + "settings.system-config.locale": "系統語言", + "settings.system-config.locale.zh_CN": "簡體中文(zh_CN)", + "settings.system-config.locale.zh_TW": "繁體中文(zh_TW)", + "settings.system-config.locale.en_US": "英語(en_US)", + "settings.system-config.timezone": "系統時區", + "settings.system-config.ok": "確認更新", "collector": "採集器", "collector.status": "運行狀態", "collector.task": "任務數量",