mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-09-22 08:00:53 +00:00
feat: Support more alert method (#11742)
This commit is contained in:
@@ -335,3 +335,8 @@ type AgentInfo struct {
|
||||
NodeName string `json:"nodeName"`
|
||||
NodeAddr string `json:"nodeAddr"`
|
||||
}
|
||||
|
||||
type AlertWebhookConfig struct {
|
||||
DisplayName string `json:"displayName"`
|
||||
Url string `json:"url"`
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||
@@ -586,8 +587,6 @@ func sendAlerts(alert dto.AlertDTO, alertType, quota, quotaType string, params [
|
||||
continue
|
||||
}
|
||||
alertUtil.CreateNewAlertTask(quota, alertType, quotaType, constant.SMS)
|
||||
global.LOG.Infof("%s alert sms push successful", alertType)
|
||||
|
||||
case constant.Email:
|
||||
todayCount, isValid := canSendAlertToday(alertType, quotaType, alert.SendCount, constant.Email)
|
||||
if !isValid {
|
||||
@@ -610,7 +609,25 @@ func sendAlerts(alert dto.AlertDTO, alertType, quota, quotaType string, params [
|
||||
continue
|
||||
}
|
||||
alertUtil.CreateNewAlertTask(quota, alertType, quotaType, constant.Email)
|
||||
global.LOG.Infof("%s alert email push successful", alertType)
|
||||
case constant.WeCom, constant.DingTalk, constant.FeiShu:
|
||||
todayCount, isValid := canSendAlertToday(alertType, quotaType, alert.SendCount, m)
|
||||
if !isValid {
|
||||
continue
|
||||
}
|
||||
var create = dto.AlertLogCreate{
|
||||
Type: alertUtil.GetCronJobType(alert.Type),
|
||||
AlertId: alert.ID,
|
||||
Count: todayCount + 1,
|
||||
}
|
||||
transport := xpack.LoadRequestTransport()
|
||||
agentInfo, _ := xpack.GetAgentInfo()
|
||||
err := xpack.CreateWebhookAlertLog(alertType, alert, create, quotaType, params, m, transport, agentInfo)
|
||||
if err != nil {
|
||||
global.LOG.Infof("%s alert webhook %s push faild, err: %v", alertType, m, err)
|
||||
continue
|
||||
}
|
||||
alertUtil.CreateNewAlertTask(quota, alertUtil.GetCronJobType(alert.Type), quotaType, m)
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -829,30 +846,36 @@ func processAllDisks(alert dto.AlertDTO) error {
|
||||
global.LOG.Errorf("error getting disk list, err: %v", err)
|
||||
return err
|
||||
}
|
||||
var errMsgs []string
|
||||
for _, item := range diskList {
|
||||
if success, err := checkAndCreateDiskAlert(alert, item.Path); err == nil && success {
|
||||
global.LOG.Infof("disk alert pushed successfully for %s", item.Path)
|
||||
err := checkAndCreateDiskAlert(alert, item.Path)
|
||||
if err != nil {
|
||||
errMsg := fmt.Sprintf("disk path %s process failed: %v", item.Path, err)
|
||||
errMsgs = append(errMsgs, errMsg)
|
||||
global.LOG.Errorf(errMsg)
|
||||
continue
|
||||
}
|
||||
}
|
||||
if len(errMsgs) > 0 {
|
||||
return fmt.Errorf("batch process disks failed, error count: %d, details: %s", len(errMsgs), strings.Join(errMsgs, "; "))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func processSingleDisk(alert dto.AlertDTO) error {
|
||||
success, err := checkAndCreateDiskAlert(alert, alert.Project)
|
||||
err := checkAndCreateDiskAlert(alert, alert.Project)
|
||||
if err != nil {
|
||||
global.LOG.Errorf(err.Error())
|
||||
return err
|
||||
}
|
||||
if success {
|
||||
global.LOG.Infof("disk alert pushed successfully for %s", alert.Project)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkAndCreateDiskAlert(alert dto.AlertDTO, path string) (bool, error) {
|
||||
func checkAndCreateDiskAlert(alert dto.AlertDTO, path string) error {
|
||||
usageStat, err := psutil.DISK.GetUsage(path, false)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("error getting disk usage for %s, err: %v", path, err)
|
||||
return false, err
|
||||
return err
|
||||
}
|
||||
|
||||
usedTotal, usedStr := calculateUsedTotal(alert.Cycle, usageStat)
|
||||
@@ -861,13 +884,12 @@ func checkAndCreateDiskAlert(alert dto.AlertDTO, path string) (bool, error) {
|
||||
commonTotal *= 1024 * 1024 * 1024
|
||||
}
|
||||
if usedTotal < commonTotal {
|
||||
return false, nil
|
||||
return nil
|
||||
}
|
||||
global.LOG.Infof("disk「 %s 」usage: %s", path, usedStr)
|
||||
params := createAlertDiskParams(path, usedStr)
|
||||
sender := NewAlertSender(alert, alert.Project)
|
||||
sender.ResourceSend(path, params)
|
||||
return true, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func calculateUsedTotal(cycle uint, usageStat *disk.UsageStat) (float64, string) {
|
||||
|
||||
@@ -30,6 +30,8 @@ func (s *AlertSender) Send(quota string, params []dto.Param) {
|
||||
s.sendSMS(quota, params)
|
||||
case constant.Email:
|
||||
s.sendEmail(quota, params)
|
||||
case constant.WeCom, constant.DingTalk, constant.FeiShu:
|
||||
s.sendWebhook(quota, params, method)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,6 +45,8 @@ func (s *AlertSender) ResourceSend(quota string, params []dto.Param) {
|
||||
s.sendResourceSMS(quota, params)
|
||||
case constant.Email:
|
||||
s.sendResourceEmail(quota, params)
|
||||
case constant.WeCom, constant.DingTalk, constant.FeiShu:
|
||||
s.sendResourceWebhook(quota, params, method)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,9 +68,12 @@ func (s *AlertSender) sendSMS(quota string, params []dto.Param) {
|
||||
Type: s.alert.Type,
|
||||
}
|
||||
|
||||
_ = xpack.CreateSMSAlertLog(s.alert.Type, s.alert, create, quota, params, constant.SMS)
|
||||
err := xpack.CreateSMSAlertLog(s.alert.Type, s.alert, create, quota, params, constant.SMS)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("%s alert sms push failed: %v", s.alert.Type, err)
|
||||
return
|
||||
}
|
||||
alertUtil.CreateNewAlertTask(quota, s.alert.Type, s.quotaType, constant.SMS)
|
||||
global.LOG.Infof("%s alert sms push successful", s.alert.Type)
|
||||
}
|
||||
|
||||
func (s *AlertSender) sendEmail(quota string, params []dto.Param) {
|
||||
@@ -86,9 +93,34 @@ func (s *AlertSender) sendEmail(quota string, params []dto.Param) {
|
||||
|
||||
transport := xpack.LoadRequestTransport()
|
||||
agentInfo, _ := xpack.GetAgentInfo()
|
||||
_ = alertUtil.CreateEmailAlertLog(create, s.alert, params, transport, agentInfo)
|
||||
err := alertUtil.CreateEmailAlertLog(create, s.alert, params, transport, agentInfo)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("%s alert email push failed: %v", s.alert.Type, err)
|
||||
return
|
||||
}
|
||||
alertUtil.CreateNewAlertTask(quota, s.alert.Type, s.quotaType, constant.Email)
|
||||
global.LOG.Infof("%s alert email push successful", s.alert.Type)
|
||||
}
|
||||
|
||||
func (s *AlertSender) sendWebhook(quota string, params []dto.Param, method string) {
|
||||
totalCount, isValid := s.canSendAlert(method)
|
||||
if !isValid {
|
||||
return
|
||||
}
|
||||
|
||||
create := dto.AlertLogCreate{
|
||||
Status: constant.AlertSuccess,
|
||||
Count: totalCount + 1,
|
||||
AlertId: s.alert.ID,
|
||||
Type: s.alert.Type,
|
||||
}
|
||||
transport := xpack.LoadRequestTransport()
|
||||
agentInfo, _ := xpack.GetAgentInfo()
|
||||
err := xpack.CreateWebhookAlertLog(s.alert.Type, s.alert, create, quota, params, method, transport, agentInfo)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("%s alert %s webhook push failed: %v", s.alert.Type, method, err)
|
||||
return
|
||||
}
|
||||
alertUtil.CreateNewAlertTask(quota, s.alert.Type, s.quotaType, method)
|
||||
}
|
||||
|
||||
func (s *AlertSender) sendResourceSMS(quota string, params []dto.Param) {
|
||||
@@ -113,7 +145,6 @@ func (s *AlertSender) sendResourceSMS(quota string, params []dto.Param) {
|
||||
return
|
||||
}
|
||||
alertUtil.CreateNewAlertTask(quota, s.alert.Type, s.quotaType, constant.SMS)
|
||||
global.LOG.Infof("%s alert sms push successful", s.alert.Type)
|
||||
}
|
||||
|
||||
func (s *AlertSender) sendResourceEmail(quota string, params []dto.Param) {
|
||||
@@ -138,7 +169,27 @@ func (s *AlertSender) sendResourceEmail(quota string, params []dto.Param) {
|
||||
return
|
||||
}
|
||||
alertUtil.CreateNewAlertTask(quota, s.alert.Type, s.quotaType, constant.Email)
|
||||
global.LOG.Infof("%s alert email push successful", s.alert.Type)
|
||||
}
|
||||
|
||||
func (s *AlertSender) sendResourceWebhook(quota string, params []dto.Param, method string) {
|
||||
todayCount, isValid := s.canResourceSendAlert(method)
|
||||
if !isValid {
|
||||
return
|
||||
}
|
||||
|
||||
create := dto.AlertLogCreate{
|
||||
Status: constant.AlertSuccess,
|
||||
Count: todayCount + 1,
|
||||
AlertId: s.alert.ID,
|
||||
Type: s.alert.Type,
|
||||
}
|
||||
transport := xpack.LoadRequestTransport()
|
||||
agentInfo, _ := xpack.GetAgentInfo()
|
||||
if err := xpack.CreateWebhookAlertLog(s.alert.Type, s.alert, create, quota, params, method, transport, agentInfo); err != nil {
|
||||
global.LOG.Errorf("failed to send webhook alert: %v", err)
|
||||
return
|
||||
}
|
||||
alertUtil.CreateNewAlertTask(quota, s.alert.Type, s.quotaType, method)
|
||||
}
|
||||
|
||||
func (s *AlertSender) canSendAlert(method string) (uint, bool) {
|
||||
|
||||
@@ -24,4 +24,5 @@ const (
|
||||
WeCom = "weCom"
|
||||
DingTalk = "dingTalk"
|
||||
FeiShu = "feiShu"
|
||||
Custom = "custom"
|
||||
)
|
||||
|
||||
+17
-11
@@ -49,19 +49,24 @@ func CreateEmailAlertLog(create dto.AlertLogCreate, alert dto.AlertDTO, params [
|
||||
return err
|
||||
}
|
||||
create.Method = constant.Email
|
||||
emailConfig, err := alertRepo.GetConfig(alertRepo.WithByType(constant.EmailConfig))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var emailInfo dto.AlertEmailConfig
|
||||
err = json.Unmarshal([]byte(emailConfig.Config), &emailInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if emailInfo.Host == "" {
|
||||
create.Message = "email config is required"
|
||||
create.Status = constant.AlertError
|
||||
return SaveAlertLog(create, &alertLog)
|
||||
}
|
||||
if !global.IsMaster && cfg.IsOffline == constant.StatusEnable {
|
||||
create.Status = constant.AlertPushing
|
||||
return SaveAlertLog(create, &alertLog)
|
||||
} else {
|
||||
emailConfig, err := alertRepo.GetConfig(alertRepo.WithByType(constant.EmailConfig))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var emailInfo dto.AlertEmailConfig
|
||||
err = json.Unmarshal([]byte(emailConfig.Config), &emailInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
username := emailInfo.UserName
|
||||
if username == "" {
|
||||
username = emailInfo.Sender
|
||||
@@ -76,7 +81,7 @@ func CreateEmailAlertLog(create dto.AlertLogCreate, alert dto.AlertDTO, params [
|
||||
Encryption: emailInfo.Encryption,
|
||||
Recipient: emailInfo.Recipient,
|
||||
}
|
||||
content := GetEmailContent(alert.Type, params, agentInfo)
|
||||
content := GetSendContent(alert.Type, params, agentInfo)
|
||||
if content == "" {
|
||||
content = i18n.GetMsgWithMap("CommonAlert", map[string]interface{}{"msg": alert.Title})
|
||||
}
|
||||
@@ -122,6 +127,7 @@ func CreateNewAlertTask(quota, alertType, quotaType, method string) {
|
||||
if err != nil {
|
||||
global.LOG.Errorf("error creating alert tasks, err: %v", err)
|
||||
}
|
||||
global.LOG.Infof("%s alert %s push completed", alertType, method)
|
||||
}
|
||||
|
||||
func ProcessAlertDetail(alert dto.AlertDTO, project string, params []dto.Param, method string) string {
|
||||
@@ -300,7 +306,7 @@ func isWithinTimeRange(savedTimeString string) bool {
|
||||
return now.After(skipTime) && now.Before(endSkipTime)
|
||||
}
|
||||
|
||||
func GetEmailContent(alertType string, params []dto.Param, agentInfo *dto.AgentInfo) string {
|
||||
func GetSendContent(alertType string, params []dto.Param, agentInfo *dto.AgentInfo) string {
|
||||
switch GetCronJobType(alertType) {
|
||||
case "ssl":
|
||||
return i18n.GetMsgWithMap("SSLAlert", map[string]interface{}{"num": getValueByIndex(params, "1"), "day": getValueByIndex(params, "2"), "node": getNodeName(agentInfo), "ip": getNodeIp(agentInfo)})
|
||||
|
||||
@@ -42,9 +42,12 @@ func PushAlert(pushAlert dto.PushAlert) error {
|
||||
AlertId: alert.ID,
|
||||
Count: todayCount + 1,
|
||||
}
|
||||
_ = xpack.CreateTaskScanSMSAlertLog(alert, alert.Type, create, pushAlert, constant.SMS)
|
||||
err = xpack.CreateTaskScanSMSAlertLog(alert, alert.Type, create, pushAlert, constant.SMS)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("%s alert sms push failed: %v", alert.Type, err)
|
||||
continue
|
||||
}
|
||||
alertUtil.CreateNewAlertTask(strconv.Itoa(int(pushAlert.EntryID)), alertUtil.GetCronJobType(alert.Type), strconv.Itoa(int(pushAlert.EntryID)), constant.SMS)
|
||||
global.LOG.Infof("%s %s alert push successful", alert.Type, constant.SMS)
|
||||
case constant.Email:
|
||||
todayCount, _, err := alertRepo.LoadTaskCount(alertUtil.GetCronJobType(alert.Type), strconv.Itoa(int(pushAlert.EntryID)), constant.Email)
|
||||
if err != nil || alert.SendCount <= todayCount {
|
||||
@@ -59,10 +62,28 @@ func PushAlert(pushAlert dto.PushAlert) error {
|
||||
agentInfo, _ := xpack.GetAgentInfo()
|
||||
err = alertUtil.CreateTaskScanEmailAlertLog(alert, create, pushAlert, constant.Email, transport, agentInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
global.LOG.Errorf("%s alert email push failed: %v", alert.Type, err)
|
||||
continue
|
||||
}
|
||||
alertUtil.CreateNewAlertTask(strconv.Itoa(int(pushAlert.EntryID)), alertUtil.GetCronJobType(alert.Type), strconv.Itoa(int(pushAlert.EntryID)), constant.Email)
|
||||
global.LOG.Infof("%s %s alert push successful", alert.Type, constant.Email)
|
||||
case constant.WeCom, constant.DingTalk, constant.FeiShu:
|
||||
todayCount, _, err := alertRepo.LoadTaskCount(alertUtil.GetCronJobType(alert.Type), strconv.Itoa(int(pushAlert.EntryID)), m)
|
||||
if err != nil || alert.SendCount <= todayCount {
|
||||
continue
|
||||
}
|
||||
var create = dto.AlertLogCreate{
|
||||
Type: alertUtil.GetCronJobType(alert.Type),
|
||||
AlertId: alert.ID,
|
||||
Count: todayCount + 1,
|
||||
}
|
||||
transport := xpack.LoadRequestTransport()
|
||||
agentInfo, _ := xpack.GetAgentInfo()
|
||||
err = xpack.CreateTaskScanWebhookAlertLog(alert, alert.Type, create, pushAlert, m, transport, agentInfo)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("%s alert %s webhook push failed: %v", alert.Type, m, err)
|
||||
continue
|
||||
}
|
||||
alertUtil.CreateNewAlertTask(strconv.Itoa(int(pushAlert.EntryID)), alertUtil.GetCronJobType(alert.Type), strconv.Itoa(int(pushAlert.EntryID)), m)
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,14 @@ func CreateSMSAlertLog(alertType string, info dto.AlertDTO, create dto.AlertLogC
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateTaskScanWebhookAlertLog(alert dto.AlertDTO, alertType string, create dto.AlertLogCreate, pushAlert dto.PushAlert, method string, transport *http.Transport, agentInfo *dto.AgentInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateWebhookAlertLog(alertType string, info dto.AlertDTO, create dto.AlertLogCreate, project string, params []dto.Param, method string, transport *http.Transport, agentInfo *dto.AgentInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetLicenseErrorAlert() (uint, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
@@ -7,4 +7,5 @@ const (
|
||||
WeCom = "weCom"
|
||||
DingTalk = "dingTalk"
|
||||
FeiShu = "feiShu"
|
||||
Custom = "custom"
|
||||
)
|
||||
|
||||
@@ -159,9 +159,57 @@ export namespace Alert {
|
||||
recipient: string;
|
||||
}
|
||||
|
||||
export interface CommonAlertConfig {
|
||||
id?: number;
|
||||
type: string;
|
||||
title: string;
|
||||
status: string;
|
||||
config: CommonConfig;
|
||||
}
|
||||
|
||||
export interface CommonConfig {
|
||||
isOffline?: string;
|
||||
alertDailyNum?: number;
|
||||
alertSendTimeRange?: string;
|
||||
}
|
||||
|
||||
export interface EmailConfig {
|
||||
id?: number;
|
||||
type: string;
|
||||
title: string;
|
||||
status: string;
|
||||
config: {
|
||||
status?: string;
|
||||
sender?: string;
|
||||
userName?: string;
|
||||
password?: string;
|
||||
displayName?: string;
|
||||
host?: string;
|
||||
port?: number;
|
||||
encryption?: string;
|
||||
recipient?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface SmsConfig {
|
||||
id?: number;
|
||||
type: string;
|
||||
title: string;
|
||||
status: string;
|
||||
config: {
|
||||
phone?: string;
|
||||
alertDailyNum?: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface WebhookConfig {
|
||||
id?: number;
|
||||
type: string;
|
||||
title: string;
|
||||
status: string;
|
||||
config: {
|
||||
displayName?: string;
|
||||
url?: string;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3939,7 +3939,7 @@ const message = {
|
||||
alertCount: 'Alert Count',
|
||||
clamHelper: 'Trigger alert when scanning infected files',
|
||||
cronJobHelper: 'Trigger alert when task execution fails',
|
||||
licenseHelper: 'Professional version supports SMS alert',
|
||||
licenseHelper: 'Professional version supports more alert',
|
||||
alertCountHelper: 'Maximum daily alarm frequency',
|
||||
alert: 'SMS Alert',
|
||||
logs: 'Alert Logs',
|
||||
@@ -4141,6 +4141,13 @@ const message = {
|
||||
panelLoginRule: 'Panel login alert, sent {0} times per day',
|
||||
sshLoginRule: 'SSH login alert, sent {0} times per day',
|
||||
userNameHelper: 'Username is empty, the sender address will be used by default',
|
||||
alertConfigHelper: 'Configure alert notification channels to receive panel message push',
|
||||
weComConfigHelper: 'WeCom alert notification configuration',
|
||||
wechatConfigHelper: 'WeChat Official Account alert notification configuration',
|
||||
dingTalkConfigHelper: 'DingTalk alert notification configuration',
|
||||
feiShuConfigHelper: 'Feishu alert notification configuration',
|
||||
webhookName: 'Bot name or remark',
|
||||
webhookUrl: 'Webhook URL',
|
||||
},
|
||||
theme: {
|
||||
lingXiaGold: 'Ling Xia Gold',
|
||||
|
||||
@@ -3905,7 +3905,7 @@ const message = {
|
||||
alertCount: 'Número de alertas',
|
||||
clamHelper: 'Generar alerta al detectar archivos infectados en escaneo',
|
||||
cronJobHelper: 'Generar alerta cuando falle la ejecución de una tarea programada',
|
||||
licenseHelper: 'La versión Pro soporta alertas SMS',
|
||||
licenseHelper: 'La versión Pro soporta alertas',
|
||||
alertCountHelper: 'Frecuencia máxima diaria de alertas',
|
||||
alert: 'Alerta SMS',
|
||||
logs: 'Logs de alertas',
|
||||
@@ -4098,6 +4098,13 @@ const message = {
|
||||
panelLoginRule: 'Alerta de login en panel, {0} envíos/día',
|
||||
sshLoginRule: 'Alerta de login SSH, {0} envíos/día',
|
||||
userNameHelper: 'El nombre de usuario está vacío, se usará la dirección del remitente por defecto',
|
||||
alertConfigHelper: 'Configurar canales de notificación de alerta para recibir mensajes push del panel',
|
||||
weComConfigHelper: 'Configuración de notificación de alerta WeCom',
|
||||
wechatConfigHelper: 'Configuración de notificación de alerta de Cuenta Oficial WeChat',
|
||||
dingTalkConfigHelper: 'Configuración de notificación de alerta DingTalk',
|
||||
feiShuConfigHelper: 'Configuración de notificación de alerta Feishu',
|
||||
webhookName: 'Nombre del bot o nota',
|
||||
webhookUrl: 'URL de Webhook',
|
||||
},
|
||||
theme: {
|
||||
lingXiaGold: 'Ling Xia Gold',
|
||||
|
||||
@@ -3828,7 +3828,7 @@ const message = {
|
||||
alertCount: 'アラート数',
|
||||
clamHelper: '感染したファイルをスキャンするときにアラートをトリガーします',
|
||||
cronJobHelper: 'タスクの実行が失敗したときにアラートをトリガーします',
|
||||
licenseHelper: 'プロのバージョンはSMSアラートをサポートします',
|
||||
licenseHelper: 'プロのバージョンはアラートをサポートします',
|
||||
alertCountHelper: '最大毎日のアラーム周波数',
|
||||
alert: 'SMSアラート',
|
||||
logs: 'アラートログ',
|
||||
@@ -4026,6 +4026,13 @@ const message = {
|
||||
panelLoginRule: 'パネルログインアラートは、1日あたり{0}回送信',
|
||||
sshLoginRule: 'SSHログインアラートは、1日あたり{0}回送信',
|
||||
userNameHelper: 'ユーザー名が空の場合、送信者のアドレスがデフォルトで使用されます',
|
||||
alertConfigHelper: 'パネルメッセージプッシュを受信するためのアラート通知チャネルを設定',
|
||||
weComConfigHelper: 'WeComアラート通知設定',
|
||||
wechatConfigHelper: 'WeChat公式アカウントアラート通知設定',
|
||||
dingTalkConfigHelper: 'DingTalkアラート通知設定',
|
||||
feiShuConfigHelper: 'Feishuアラート通知設定',
|
||||
webhookName: 'ボット名または',
|
||||
webhookUrl: 'Webhook URL',
|
||||
},
|
||||
theme: {
|
||||
lingXiaGold: '凌霞金',
|
||||
|
||||
@@ -3756,7 +3756,7 @@ const message = {
|
||||
alertCount: '알림 횟수',
|
||||
clamHelper: '감염된 파일을 스캔할 때 알림 트리거',
|
||||
cronJobHelper: '작업 실행 실패 시 알림 트리거',
|
||||
licenseHelper: '전문 버전에서는 SMS 알림을 지원합니다.',
|
||||
licenseHelper: '전문 버전에서는 알림을 지원합니다.',
|
||||
alertCountHelper: '최대 일일 알림 빈도',
|
||||
alert: 'SMS 알림',
|
||||
logs: '알림 로그',
|
||||
@@ -3949,6 +3949,13 @@ const message = {
|
||||
panelLoginRule: '패널 로그인 알림은 하루 {0}회 전송',
|
||||
sshLoginRule: 'SSH 로그인 알림은 하루 {0}회 전송',
|
||||
userNameHelper: '사용자 이름이 비어 있으면 기본적으로 발신자 주소가 사용됩니다',
|
||||
alertConfigHelper: '패널 메시지 푸시를 수신하기 위한 알림 채널 구성',
|
||||
weComConfigHelper: 'WeCom 알림 구성',
|
||||
wechatConfigHelper: 'WeChat 공식 계정 알림 구성',
|
||||
dingTalkConfigHelper: 'DingTalk 알림 구성',
|
||||
feiShuConfigHelper: 'Feishu 알림 구성',
|
||||
webhookName: '봇 이름 또는 비고',
|
||||
webhookUrl: 'Webhook URL',
|
||||
},
|
||||
theme: {
|
||||
lingXiaGold: '링샤 골드',
|
||||
|
||||
@@ -3898,7 +3898,7 @@ const message = {
|
||||
alertCount: 'Bilangan Amaran',
|
||||
clamHelper: 'Hantar amaran apabila terdapat fail yang dijangkiti semasa imbasan',
|
||||
cronJobHelper: 'Hantar amaran apabila pelaksanaan tugas gagal',
|
||||
licenseHelper: 'Versi profesional menyokong amaran SMS',
|
||||
licenseHelper: 'Versi profesional menyokong amaran',
|
||||
alertCountHelper: 'Kekerapan maksimum amaran harian',
|
||||
alert: 'Amaran SMS',
|
||||
logs: 'Log Amaran',
|
||||
@@ -4104,6 +4104,13 @@ const message = {
|
||||
panelLoginRule: 'Amaran log masuk panel, dihantar {0} kali sehari',
|
||||
sshLoginRule: 'Amaran log masuk SSH, dihantar {0} kali sehari',
|
||||
userNameHelper: 'Nama pengguna kosong, alamat penghantar akan digunakan secara lalai',
|
||||
alertConfigHelper: 'Konfigurasikan saluran pemberitahuan amaran untuk menerima tolakan mesej panel',
|
||||
weComConfigHelper: 'Konfigurasi pemberitahuan amaran WeCom',
|
||||
wechatConfigHelper: 'Konfigurasi pemberitahuan amaran Akaun Rasmi WeChat',
|
||||
dingTalkConfigHelper: 'Konfigurasi pemberitahuan amaran DingTalk',
|
||||
feiShuConfigHelper: 'Konfigurasi pemberitahuan amaran Feishu',
|
||||
webhookName: 'Nama bot atau catatan',
|
||||
webhookUrl: 'URL Webhook',
|
||||
},
|
||||
theme: {
|
||||
lingXiaGold: 'Ling Xia Emas',
|
||||
|
||||
@@ -3919,7 +3919,7 @@ const message = {
|
||||
alertCount: 'Contagem de Alertas',
|
||||
clamHelper: 'Dispara alerta via ao detectar arquivos infectados durante a varredura',
|
||||
cronJobHelper: 'Dispara alerta via ao falhar na execução de tarefas',
|
||||
licenseHelper: 'A versão profissional suporta alertas via SMS',
|
||||
licenseHelper: 'A versão profissional suporta alertas via',
|
||||
alertCountHelper: 'Frequência máxima diária de alertas',
|
||||
alert: 'Alerta por SMS',
|
||||
logs: 'Registros de Alerta',
|
||||
@@ -4124,6 +4124,13 @@ const message = {
|
||||
panelLoginRule: 'Alerta de login no painel, enviado {0} vezes por dia',
|
||||
sshLoginRule: 'Alerta de login SSH, enviado {0} vezes por dia',
|
||||
userNameHelper: 'O nome de usuário está vazio, o endereço do remetente será usado por padrão',
|
||||
alertConfigHelper: 'Configurar canais de notificação de alerta para receber push de mensagens do painel',
|
||||
weComConfigHelper: 'Configuração de notificação de alerta WeCom',
|
||||
wechatConfigHelper: 'Configuração de notificação de alerta da Conta Oficial WeChat',
|
||||
dingTalkConfigHelper: 'Configuração de notificação de alerta DingTalk',
|
||||
feiShuConfigHelper: 'Configuração de notificação de alerta Feishu',
|
||||
webhookName: 'Nome do bot ou observação',
|
||||
webhookUrl: 'URL do Webhook',
|
||||
},
|
||||
theme: {
|
||||
lingXiaGold: 'Ling Xia Gold',
|
||||
|
||||
@@ -3906,7 +3906,7 @@ const message = {
|
||||
alertCount: 'Количество оповещений',
|
||||
clamHelper: 'Отправлять оповещение при обнаружении зараженных файлов',
|
||||
cronJobHelper: 'Отправлять оповещение при сбое выполнения задачи',
|
||||
licenseHelper: 'Профессиональная версия поддерживает SMS-оповещения',
|
||||
licenseHelper: 'Профессиональная версия поддерживает оповещения',
|
||||
alertCountHelper: 'Максимальная дневная частота оповещений',
|
||||
alert: 'SMS Уведомление',
|
||||
logs: 'Журнал Уведомлений',
|
||||
@@ -4115,6 +4115,13 @@ const message = {
|
||||
panelLoginRule: 'Оповещение о входе в панель, отправляется {0} раз в день',
|
||||
sshLoginRule: 'Оповещение о входе по SSH, отправляется {0} раз в день',
|
||||
userNameHelper: 'Имя пользователя не указано, по умолчанию будет использоваться адрес отправителя',
|
||||
alertConfigHelper: 'Настройка каналов уведомлений для получения push-уведомлений от панели',
|
||||
weComConfigHelper: 'Конфигурация уведомлений WeCom',
|
||||
wechatConfigHelper: 'Конфигурация уведомлений официального аккаунта WeChat',
|
||||
dingTalkConfigHelper: 'Конфигурация уведомлений DingTalk',
|
||||
feiShuConfigHelper: 'Конфигурация уведомлений Feishu',
|
||||
webhookName: 'Имя бота или примечание',
|
||||
webhookUrl: 'URL Webhook',
|
||||
},
|
||||
theme: {
|
||||
lingXiaGold: 'Лин Ся Золотой',
|
||||
|
||||
@@ -3978,7 +3978,7 @@ const message = {
|
||||
alertCount: 'Uyarı Sayısı',
|
||||
clamHelper: 'Enfekte dosyalar tarandığında uyarısını tetikle',
|
||||
cronJobHelper: 'Görev yürütme başarısız olduğunda uyarısını tetikle',
|
||||
licenseHelper: 'Profesyonel sürüm SMS uyarısını destekler',
|
||||
licenseHelper: 'Profesyonel sürüm more uyarısını destekler',
|
||||
alertCountHelper: 'Günlük maksimum uyarı sıklığı',
|
||||
alert: 'SMS Uyarısı',
|
||||
logs: 'Uyarı Günlükleri',
|
||||
@@ -4185,6 +4185,13 @@ const message = {
|
||||
panelLoginRule: 'Panel girişi uyarısı, günde {0} kez gönderilir',
|
||||
sshLoginRule: 'SSH girişi uyarısı, günde {0} kez gönderilir',
|
||||
userNameHelper: 'Kullanıcı adı boşsa, varsayılan olarak gönderici adresi kullanılacaktır',
|
||||
alertConfigHelper: 'Panel mesaj gönderimini almak için uyarı bildirim kanallarını yapılandırın',
|
||||
weComConfigHelper: 'WeCom uyarı bildirim yapılandırması',
|
||||
wechatConfigHelper: 'WeChat Resmi Hesap uyarı bildirim yapılandırması',
|
||||
dingTalkConfigHelper: 'DingTalk uyarı bildirim yapılandırması',
|
||||
feiShuConfigHelper: 'Feishu uyarı bildirim yapılandırması',
|
||||
webhookName: 'Bot adı veya not',
|
||||
webhookUrl: 'Webhook URL',
|
||||
},
|
||||
theme: {
|
||||
lingXiaGold: 'Ling Xia Altın',
|
||||
|
||||
@@ -3630,7 +3630,7 @@ const message = {
|
||||
alertCount: '告警次數',
|
||||
clamHelper: '掃描到感染檔案時觸發告警',
|
||||
cronJobHelper: '定時任務執行失敗時將觸發告警',
|
||||
licenseHelper: '專業版支援簡訊告警功能',
|
||||
licenseHelper: '專業版支援更多告警功能',
|
||||
alertCountHelper: '每日最大告警次數',
|
||||
alert: '簡訊告警',
|
||||
logs: '告警日誌',
|
||||
@@ -3824,6 +3824,13 @@ const message = {
|
||||
panelLoginRule: '面板登入告警,每天發送 {0} 次',
|
||||
sshLoginRule: 'SSH 登入告警,每天發送 {0} 次',
|
||||
userNameHelper: '使用者名稱為空時,將預設使用寄件者地址',
|
||||
alertConfigHelper: '配置告警通知通道,用於接收面板訊息推送',
|
||||
weComConfigHelper: '企業微信告警通知配置',
|
||||
wechatConfigHelper: '微信公眾號告警通知配置',
|
||||
dingTalkConfigHelper: '釘釘告警通知配置',
|
||||
feiShuConfigHelper: '飛書告警通知配置',
|
||||
webhookName: '機器人名稱',
|
||||
webhookUrl: 'Webhook 位址',
|
||||
},
|
||||
theme: {
|
||||
lingXiaGold: '凌霞金',
|
||||
|
||||
@@ -3624,7 +3624,7 @@ const message = {
|
||||
alertCount: '告警次数',
|
||||
clamHelper: '扫描到感染文件时触发告警通知',
|
||||
cronJobHelper: '定时任务执行失败时将触发告警通知',
|
||||
licenseHelper: '专业版支持短信告警功能',
|
||||
licenseHelper: '专业版支持更多告警功能',
|
||||
alertCountHelper: '每日最大告警次数',
|
||||
alert: '短信告警',
|
||||
logs: '告警日志',
|
||||
@@ -3814,6 +3814,13 @@ const message = {
|
||||
panelLoginRule: '面板登录告警,每天发送 {0} 次',
|
||||
sshLoginRule: 'SSH 登录告警告警,每天发送 {0} 次',
|
||||
userNameHelper: '用户名为空会默认使用发件箱地址',
|
||||
alertConfigHelper: '配置告警通知通道,用于接收面板消息推送',
|
||||
weComConfigHelper: '企业微信告警通知配置',
|
||||
wechatConfigHelper: '微信公众号告警通知配置',
|
||||
dingTalkConfigHelper: '钉钉告警通知配置',
|
||||
feiShuConfigHelper: '飞书告警通知配置',
|
||||
webhookName: '机器人名称',
|
||||
webhookUrl: 'Webhook 地址',
|
||||
},
|
||||
theme: {
|
||||
lingXiaGold: '凌霞金',
|
||||
|
||||
@@ -722,6 +722,24 @@
|
||||
:disabled="!form.hasAlert || !isProductPro"
|
||||
:label="$t('xpack.alert.sms')"
|
||||
/>
|
||||
<el-option
|
||||
value="weCom"
|
||||
v-if="!globalStore.isIntl"
|
||||
:disabled="!form.hasAlert || !isProductPro"
|
||||
:label="$t('xpack.alert.weCom')"
|
||||
/>
|
||||
<el-option
|
||||
value="dingTalk"
|
||||
v-if="!globalStore.isIntl"
|
||||
:disabled="!form.hasAlert || !isProductPro"
|
||||
:label="$t('xpack.alert.dingTalk')"
|
||||
/>
|
||||
<el-option
|
||||
value="feiShu"
|
||||
v-if="!globalStore.isIntl"
|
||||
:disabled="!form.hasAlert || !isProductPro"
|
||||
:label="$t('xpack.alert.feiShu')"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</LayoutCol>
|
||||
|
||||
@@ -328,6 +328,24 @@
|
||||
:disabled="!globalStore.isProductPro"
|
||||
:label="$t('xpack.alert.sms')"
|
||||
/>
|
||||
<el-option
|
||||
value="weCom"
|
||||
v-if="!globalStore.isIntl"
|
||||
:disabled="!globalStore.isProductPro"
|
||||
:label="$t('xpack.alert.weCom')"
|
||||
/>
|
||||
<el-option
|
||||
value="dingTalk"
|
||||
v-if="!globalStore.isIntl"
|
||||
:disabled="!globalStore.isProductPro"
|
||||
:label="$t('xpack.alert.dingTalk')"
|
||||
/>
|
||||
<el-option
|
||||
value="feiShu"
|
||||
v-if="!globalStore.isIntl"
|
||||
:disabled="!globalStore.isProductPro"
|
||||
:label="$t('xpack.alert.feiShu')"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<span class="input-help">
|
||||
|
||||
@@ -214,7 +214,24 @@ const formatMessage = (row: Alert.AlertInfo) => {
|
||||
};
|
||||
|
||||
const formatMethod = (row: Alert.AlertLog) => {
|
||||
return row.method === 'mail' ? t('xpack.alert.mail') : t('xpack.alert.sms');
|
||||
switch (row.method) {
|
||||
case 'mail':
|
||||
return t('xpack.alert.mail');
|
||||
case 'sms':
|
||||
return t('xpack.alert.sms');
|
||||
case 'dingTalk':
|
||||
return t('xpack.alert.dingTalk');
|
||||
case 'weCom':
|
||||
return t('xpack.alert.weCom');
|
||||
case 'feiShu':
|
||||
return t('xpack.alert.feiShu');
|
||||
case 'wechat':
|
||||
return t('xpack.alert.wechat');
|
||||
case 'webhook':
|
||||
return t('xpack.alert.webhook');
|
||||
default:
|
||||
return t('xpack.alert.unknown');
|
||||
}
|
||||
};
|
||||
|
||||
const formatCount = (row: Alert.AlertInfo) => {
|
||||
|
||||
@@ -40,7 +40,22 @@
|
||||
<LayoutContent :title="$t('commons.button.set')" v-loading="loading" :divider="true">
|
||||
<template #title>{{ $t('xpack.alert.methodConfig') }}</template>
|
||||
<template #main>
|
||||
<div class="grid gap-4 grid-cols-1 md:grid-cols-2 xl:grid-cols-3">
|
||||
<el-alert type="info" :closable="false">
|
||||
<template #title>
|
||||
<div class="flex items-center justify-start">
|
||||
{{ $t('xpack.alert.alertConfigHelper') }}
|
||||
<el-link
|
||||
class="ml-1 text-xs"
|
||||
type="primary"
|
||||
target="_blank"
|
||||
:href="globalStore.docsUrl + '/user_manual/settings/#3'"
|
||||
>
|
||||
{{ $t('commons.button.helpDoc') }}
|
||||
</el-link>
|
||||
</div>
|
||||
</template>
|
||||
</el-alert>
|
||||
<div class="grid gap-4 grid-cols-1 md:grid-cols-2 xl:grid-cols-3 mt-3">
|
||||
<el-card class="rounded-2xl shadow hover:shadow-md transition-all">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<div class="text-lg font-semibold">{{ $t('xpack.alert.emailConfig') }}</div>
|
||||
@@ -67,7 +82,7 @@
|
||||
</div>
|
||||
<div class="text-sm mb-2">{{ $t('xpack.alert.emailConfigHelper') }}</div>
|
||||
<el-divider class="!mb-2 !mt-3" />
|
||||
<div class="text-sm email-form" v-if="emailConfig.id">
|
||||
<div class="text-sm config-form" v-if="emailConfig.id">
|
||||
<el-form
|
||||
@submit.prevent
|
||||
ref="alertFormRef"
|
||||
@@ -117,14 +132,14 @@
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-sm mb-2">
|
||||
<div class="text-sm mb-2 flex items-center justify-start">
|
||||
{{ $t('xpack.alert.alertSmsHelper', [totalSms, usedSms]) }}
|
||||
<el-link class="ml-1 text-xs" @click="goBuy" type="primary" icon="Position">
|
||||
<span class="ml-0.5">{{ $t('xpack.alert.goBuy') }}</span>
|
||||
</el-link>
|
||||
</div>
|
||||
<el-divider class="!mb-2 !mt-3" />
|
||||
<div class="text-sm email-form">
|
||||
<div class="text-sm config-form">
|
||||
<el-form
|
||||
@submit.prevent
|
||||
ref="alertFormRef"
|
||||
@@ -141,6 +156,156 @@
|
||||
</el-form>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card
|
||||
class="rounded-2xl shadow hover:shadow-md transition-all"
|
||||
v-if="globalStore.isProductPro && !globalStore.isIntl"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<div class="text-lg font-semibold">{{ $t('xpack.alert.weCom') }}</div>
|
||||
<div>
|
||||
<el-button
|
||||
plain
|
||||
round
|
||||
size="default"
|
||||
:disabled="!weComConfig.id"
|
||||
@click="onChangeWeCom(weComConfig.id)"
|
||||
>
|
||||
{{ $t('commons.button.edit') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
size="default"
|
||||
plain
|
||||
round
|
||||
:disabled="!weComConfig.id"
|
||||
@click="onDelete(weComConfig.id)"
|
||||
>
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-sm mb-2">{{ $t('xpack.alert.weComConfigHelper') }}</div>
|
||||
<el-divider class="!mb-2 !mt-3" />
|
||||
<div class="text-sm config-form" v-if="weComConfig.id">
|
||||
<el-form
|
||||
@submit.prevent
|
||||
ref="alertFormRef"
|
||||
:label-position="mobile ? 'top' : 'left'"
|
||||
label-width="110px"
|
||||
>
|
||||
<el-form-item :label="$t('xpack.alert.webhookName')" prop="displayName">
|
||||
{{ weComConfig.config.displayName }}
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('xpack.alert.webhookUrl')" prop="url">
|
||||
{{ weComConfig.config.url }}
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-alert v-else center class="alert" style="height: 257px" :closable="false">
|
||||
<el-button size="large" round plain type="primary" @click="onChangeWeCom(0)">
|
||||
{{ $t('commons.button.create') }}{{ $t('xpack.alert.weCom') }}
|
||||
</el-button>
|
||||
</el-alert>
|
||||
</el-card>
|
||||
<el-card
|
||||
class="rounded-2xl shadow hover:shadow-md transition-all"
|
||||
v-if="globalStore.isProductPro && !globalStore.isIntl"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<div class="text-lg font-semibold">{{ $t('xpack.alert.dingTalk') }}</div>
|
||||
<div>
|
||||
<el-button
|
||||
plain
|
||||
round
|
||||
size="default"
|
||||
:disabled="!dingTalkConfig.id"
|
||||
@click="onChangeDingTalk(dingTalkConfig.id)"
|
||||
>
|
||||
{{ $t('commons.button.edit') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
size="default"
|
||||
plain
|
||||
round
|
||||
:disabled="!dingTalkConfig.id"
|
||||
@click="onDelete(dingTalkConfig.id)"
|
||||
>
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-sm mb-2">{{ $t('xpack.alert.dingTalkConfigHelper') }}</div>
|
||||
<el-divider class="!mb-2 !mt-3" />
|
||||
<div class="text-sm config-form" v-if="dingTalkConfig.id">
|
||||
<el-form
|
||||
@submit.prevent
|
||||
ref="alertFormRef"
|
||||
:label-position="mobile ? 'top' : 'left'"
|
||||
label-width="110px"
|
||||
>
|
||||
<el-form-item :label="$t('xpack.alert.webhookName')" prop="displayName">
|
||||
{{ dingTalkConfig.config.displayName }}
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('xpack.alert.webhookUrl')" prop="url">
|
||||
{{ dingTalkConfig.config.url }}
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-alert v-else center class="alert" style="height: 257px" :closable="false">
|
||||
<el-button size="large" round plain type="primary" @click="onChangeDingTalk(0)">
|
||||
{{ $t('commons.button.create') }}{{ $t('xpack.alert.dingTalk') }}
|
||||
</el-button>
|
||||
</el-alert>
|
||||
</el-card>
|
||||
<el-card
|
||||
class="rounded-2xl shadow hover:shadow-md transition-all"
|
||||
v-if="globalStore.isProductPro && !globalStore.isIntl"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<div class="text-lg font-semibold">{{ $t('xpack.alert.feiShu') }}</div>
|
||||
<div>
|
||||
<el-button
|
||||
plain
|
||||
round
|
||||
size="default"
|
||||
:disabled="!feiShuConfig.id"
|
||||
@click="onChangeDingTalk(feiShuConfig.id)"
|
||||
>
|
||||
{{ $t('commons.button.edit') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
size="default"
|
||||
plain
|
||||
round
|
||||
:disabled="!feiShuConfig.id"
|
||||
@click="onDelete(feiShuConfig.id)"
|
||||
>
|
||||
{{ $t('commons.button.delete') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-sm mb-2">{{ $t('xpack.alert.feiShuConfigHelper') }}</div>
|
||||
<el-divider class="!mb-2 !mt-3" />
|
||||
<div class="text-sm config-form" v-if="feiShuConfig.id">
|
||||
<el-form
|
||||
@submit.prevent
|
||||
ref="alertFormRef"
|
||||
:label-position="mobile ? 'top' : 'left'"
|
||||
label-width="110px"
|
||||
>
|
||||
<el-form-item :label="$t('xpack.alert.webhookName')" prop="displayName">
|
||||
{{ feiShuConfig.config.displayName }}
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('xpack.alert.webhookUrl')" prop="url">
|
||||
{{ feiShuConfig.config.url }}
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-alert v-else center class="alert" style="height: 257px" :closable="false">
|
||||
<el-button size="large" round plain type="primary" @click="onChangeFeiShu(0)">
|
||||
{{ $t('commons.button.create') }}{{ $t('xpack.alert.feiShu') }}
|
||||
</el-button>
|
||||
</el-alert>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
</LayoutContent>
|
||||
@@ -148,6 +313,7 @@
|
||||
<EmailDrawer ref="emailRef" @search="search" />
|
||||
<Phone ref="phoneRef" @search="search" />
|
||||
<SendTimeRange ref="sendTimeRangeRef" @search="search" />
|
||||
<WebhookDrawer ref="webHookRef" @search="search" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -162,6 +328,7 @@ import i18n from '@/lang';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import EmailDrawer from '@/views/setting/alert/setting/email/index.vue';
|
||||
import WebhookDrawer from '@/views/setting/alert/setting/webhook/index.vue';
|
||||
import { Alert } from '@/api/interface/alert';
|
||||
import { getLicenseSmsInfo } from '@/api/modules/setting';
|
||||
|
||||
@@ -172,29 +339,13 @@ const loading = ref(false);
|
||||
const alertFormRef = ref<FormInstance>();
|
||||
const phoneRef = ref();
|
||||
const emailRef = ref();
|
||||
const webHookRef = ref();
|
||||
const sendTimeRangeRef = ref();
|
||||
const sendTimeRangeValue = ref();
|
||||
const sendTimeRange = ref();
|
||||
|
||||
const isInitialized = ref(false);
|
||||
export interface EmailConfig {
|
||||
id?: number;
|
||||
type: string;
|
||||
title: string;
|
||||
status: string;
|
||||
config: {
|
||||
status?: string;
|
||||
sender?: string;
|
||||
userName?: string;
|
||||
password?: string;
|
||||
displayName?: string;
|
||||
host?: string;
|
||||
port?: number;
|
||||
encryption?: string;
|
||||
recipient?: string;
|
||||
};
|
||||
}
|
||||
const defaultEmailConfig: EmailConfig = {
|
||||
const defaultEmailConfig: Alert.EmailConfig = {
|
||||
id: undefined,
|
||||
type: 'email',
|
||||
title: 'xpack.alert.emailConfig',
|
||||
@@ -211,19 +362,9 @@ const defaultEmailConfig: EmailConfig = {
|
||||
recipient: '',
|
||||
},
|
||||
};
|
||||
const emailConfig = ref<EmailConfig>({ ...defaultEmailConfig });
|
||||
const emailConfig = ref<Alert.EmailConfig>({ ...defaultEmailConfig });
|
||||
|
||||
export interface CommonConfig {
|
||||
id?: number;
|
||||
type: string;
|
||||
title: string;
|
||||
status: string;
|
||||
config: {
|
||||
isOffline?: string;
|
||||
alertSendTimeRange?: string;
|
||||
};
|
||||
}
|
||||
const defaultCommonConfig: CommonConfig = {
|
||||
const defaultCommonConfig: Alert.CommonConfig = {
|
||||
id: undefined,
|
||||
type: 'common',
|
||||
title: 'xpack.alert.commonConfig',
|
||||
@@ -241,19 +382,9 @@ const defaultCommonConfig: CommonConfig = {
|
||||
},
|
||||
};
|
||||
|
||||
const commonConfig = ref<CommonConfig>({ ...defaultCommonConfig });
|
||||
const commonConfig = ref<Alert.CommonConfig>({ ...defaultCommonConfig });
|
||||
|
||||
export interface SmsConfig {
|
||||
id?: number;
|
||||
type: string;
|
||||
title: string;
|
||||
status: string;
|
||||
config: {
|
||||
phone?: string;
|
||||
alertDailyNum?: number;
|
||||
};
|
||||
}
|
||||
const defaultSmsConfig: SmsConfig = {
|
||||
const defaultSmsConfig: Alert.SmsConfig = {
|
||||
id: undefined,
|
||||
type: 'sms',
|
||||
title: 'xpack.alert.smsConfig',
|
||||
@@ -263,7 +394,43 @@ const defaultSmsConfig: SmsConfig = {
|
||||
alertDailyNum: 50,
|
||||
},
|
||||
};
|
||||
const smsConfig = ref<SmsConfig>({ ...defaultSmsConfig });
|
||||
const smsConfig = ref<Alert.SmsConfig>({ ...defaultSmsConfig });
|
||||
|
||||
const defaultWeComConfig: Alert.WebhookConfig = {
|
||||
id: undefined,
|
||||
type: 'weCom',
|
||||
title: 'xpack.alert.weCom',
|
||||
status: 'Enable',
|
||||
config: {
|
||||
displayName: '',
|
||||
url: '',
|
||||
},
|
||||
};
|
||||
const weComConfig = ref<Alert.WebhookConfig>({ ...defaultWeComConfig });
|
||||
|
||||
const defaultDingTalkConfig: Alert.WebhookConfig = {
|
||||
id: undefined,
|
||||
type: 'dingTalk',
|
||||
title: 'xpack.alert.dingTalk',
|
||||
status: 'Enable',
|
||||
config: {
|
||||
displayName: '',
|
||||
url: '',
|
||||
},
|
||||
};
|
||||
const dingTalkConfig = ref<Alert.WebhookConfig>({ ...defaultDingTalkConfig });
|
||||
|
||||
const defaultFeiShuConfig: Alert.WebhookConfig = {
|
||||
id: undefined,
|
||||
type: 'feiShu',
|
||||
title: 'xpack.alert.feiShu',
|
||||
status: 'Enable',
|
||||
config: {
|
||||
displayName: '',
|
||||
url: '',
|
||||
},
|
||||
};
|
||||
const feiShuConfig = ref<Alert.WebhookConfig>({ ...defaultFeiShuConfig });
|
||||
|
||||
const config = ref<Alert.AlertConfigInfo>({
|
||||
id: 0,
|
||||
@@ -329,6 +496,15 @@ const search = async () => {
|
||||
i18n.global.t('xpack.alert.resourceAlert') +
|
||||
': ' +
|
||||
resourceTimeRange;
|
||||
|
||||
const weComFound = res.data.find((s: any) => s.type === 'weCom');
|
||||
assignConfig(weComFound, weComConfig, defaultWeComConfig);
|
||||
|
||||
const dingTalkFound = res.data.find((s: any) => s.type === 'dingTalk');
|
||||
assignConfig(dingTalkFound, dingTalkConfig, defaultDingTalkConfig);
|
||||
|
||||
const feiShuFound = res.data.find((s: any) => s.type === 'feiShu');
|
||||
assignConfig(feiShuFound, feiShuConfig, defaultFeiShuConfig);
|
||||
isInitialized.value = true;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
@@ -416,6 +592,33 @@ const goBuy = async () => {
|
||||
window.open('https://www.lxware.cn/uc/cloud/licenses/' + uri, '_blank', 'noopener,noreferrer');
|
||||
};
|
||||
|
||||
const onChangeWeCom = (id: number) => {
|
||||
webHookRef.value.acceptParams({
|
||||
id: id,
|
||||
config: weComConfig.value.config,
|
||||
type: 'weCom',
|
||||
title: weComConfig.value.title,
|
||||
});
|
||||
};
|
||||
|
||||
const onChangeDingTalk = (id: number) => {
|
||||
webHookRef.value.acceptParams({
|
||||
id: id,
|
||||
config: dingTalkConfig.value.config,
|
||||
type: 'dingTalk',
|
||||
title: dingTalkConfig.value.title,
|
||||
});
|
||||
};
|
||||
|
||||
const onChangeFeiShu = (id: number) => {
|
||||
webHookRef.value.acceptParams({
|
||||
id: id,
|
||||
config: feiShuConfig.value.config,
|
||||
type: 'feiShu',
|
||||
title: feiShuConfig.value.title,
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
await search();
|
||||
if (globalStore.isProductPro && !globalStore.isIntl) {
|
||||
@@ -427,7 +630,7 @@ onMounted(async () => {
|
||||
.label {
|
||||
color: var(--el-text-color-placeholder);
|
||||
}
|
||||
.email-form {
|
||||
.config-form {
|
||||
.el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<DrawerPro v-model="drawerVisible" :header="$t('xpack.alert.' + form.type)" @close="handleClose" size="736">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:rules="rules"
|
||||
label-position="top"
|
||||
:model="form.config"
|
||||
@submit.prevent
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('xpack.alert.webhookName')" prop="displayName">
|
||||
<el-input v-model="form.config.displayName" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('xpack.alert.webhookUrl')" prop="url">
|
||||
<el-input v-model.trim="form.config.url" :rows="2" type="password" show-password />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSave(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</DrawerPro>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { UpdateAlertConfig } from '@/api/modules/alert';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const rules = {
|
||||
displayName: [Rules.requiredInput],
|
||||
url: [Rules.requiredInput],
|
||||
};
|
||||
interface Config {
|
||||
displayName: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface DialogProps {
|
||||
id: number;
|
||||
type: string;
|
||||
title: string;
|
||||
config: Config;
|
||||
}
|
||||
const drawerVisible = ref();
|
||||
const loading = ref();
|
||||
|
||||
const form = reactive({
|
||||
id: undefined,
|
||||
type: '',
|
||||
title: '',
|
||||
config: {
|
||||
displayName: '',
|
||||
url: '',
|
||||
},
|
||||
});
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
form.id = params.id;
|
||||
form.type = params.type;
|
||||
form.title = params.title;
|
||||
form.config = params.config;
|
||||
drawerVisible.value = true;
|
||||
};
|
||||
|
||||
const onSave = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
loading.value = true;
|
||||
try {
|
||||
const configInfo = form.config;
|
||||
await UpdateAlertConfig({
|
||||
id: form.id,
|
||||
type: form.type,
|
||||
title: form.title,
|
||||
status: 'Enable',
|
||||
config: JSON.stringify(configInfo),
|
||||
});
|
||||
|
||||
loading.value = false;
|
||||
handleClose();
|
||||
emit('search');
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
} catch (error) {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
drawerVisible.value = false;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
||||
@@ -160,6 +160,24 @@
|
||||
:disabled="!dialogData.rowData!.hasAlert || !isProductPro"
|
||||
:label="$t('xpack.alert.sms')"
|
||||
/>
|
||||
<el-option
|
||||
value="weCom"
|
||||
v-if="!globalStore.isIntl"
|
||||
:disabled="!dialogData.rowData!.hasAlert || !isProductPro"
|
||||
:label="$t('xpack.alert.weCom')"
|
||||
/>
|
||||
<el-option
|
||||
value="dingTalk"
|
||||
v-if="!globalStore.isIntl"
|
||||
:disabled="!dialogData.rowData!.hasAlert || !isProductPro"
|
||||
:label="$t('xpack.alert.dingTalk')"
|
||||
/>
|
||||
<el-option
|
||||
value="feiShu"
|
||||
v-if="!globalStore.isIntl"
|
||||
:disabled="!dialogData.rowData!.hasAlert || !isProductPro"
|
||||
:label="$t('xpack.alert.feiShu')"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
|
||||
Reference in New Issue
Block a user