fix:2.5.0

1. 修复前端通知类型切换时没有清除上一个值
2. 修复retry通知场景值错误
3. 支持钉钉和飞书at all
4. 优化邮箱通知不换行问题
This commit is contained in:
byteblogs168 2023-12-09 19:09:20 +08:00
parent a273259101
commit 4a7a00789b
16 changed files with 153 additions and 109 deletions

View File

@ -15,5 +15,4 @@ public class DingDingAttribute {
private List<String> ats;
private boolean isAtAll;
}

View File

@ -18,5 +18,4 @@ public class LarkAttribute {
private List<String> ats;
private boolean isAtAll;
}

View File

@ -23,18 +23,14 @@ public class DingdingAlarm extends AbstractAlarm<AlarmContext> {
@Override
public boolean asyncSendMessage(AlarmContext context) {
DingDingAttribute dingDingAttribute = JsonUtil.parseObject(context.getNotifyAttribute(), DingDingAttribute.class);
threadPoolExecutor.execute(() ->
DingDingUtils.sendMessage(DingDingUtils.buildSendRequest(context.getTitle(), context.getText(),dingDingAttribute.getAts(),dingDingAttribute.isAtAll()), dingDingAttribute.getWebhookUrl()));
threadPoolExecutor.execute(() -> syncSendMessage(context));
return true;
}
@Override
public boolean syncSendMessage(AlarmContext context) {
DingDingAttribute dingDingAttribute = JsonUtil.parseObject(context.getNotifyAttribute(), DingDingAttribute.class);
return DingDingUtils.sendMessage(DingDingUtils.buildSendRequest(context.getTitle(), context.getText(),dingDingAttribute.getAts(),dingDingAttribute.isAtAll()), dingDingAttribute.getWebhookUrl());
return DingDingUtils.sendMessage(DingDingUtils.buildSendRequest(context.getTitle(), context.getText(),dingDingAttribute.getAts()), dingDingAttribute.getWebhookUrl());
}
@Override

View File

@ -33,7 +33,9 @@ public class EmailAlarm extends AbstractAlarm<AlarmContext> {
String notifyAttribute = alarmContext.getNotifyAttribute();
EmailAttribute emailAttribute = JsonUtil.parseObject(notifyAttribute, EmailAttribute.class);
emailAttribute.setAuth(true);
MailUtil.send(emailAttribute, emailAttribute.getTos(), alarmContext.getTitle(), alarmContext.getText(), true);
String text = alarmContext.getText();
text = text.replaceAll("\n", "<br/>");
MailUtil.send(emailAttribute, emailAttribute.getTos(), alarmContext.getTitle(), text, true);
return true;
}

View File

@ -1,10 +1,13 @@
package com.aizuda.easy.retry.common.core.alarm.strategy;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.aizuda.easy.retry.common.core.alarm.AlarmContext;
import com.aizuda.easy.retry.common.core.alarm.LarkAttribute;
import com.aizuda.easy.retry.common.core.constant.SystemConstants;
import com.aizuda.easy.retry.common.core.enums.AlarmTypeEnum;
import com.aizuda.easy.retry.common.core.log.LogUtils;
import com.aizuda.easy.retry.common.core.util.JsonUtil;
@ -14,6 +17,7 @@ import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.HashMap;
@ -32,7 +36,6 @@ import java.util.Map;
public class LarkAlarm extends AbstractAlarm<AlarmContext> {
public static final String atLabel = "<at id={0}></at>";
@Override
@ -51,18 +54,17 @@ public class LarkAlarm extends AbstractAlarm<AlarmContext> {
@Override
public boolean syncSendMessage(AlarmContext context) {
LarkAttribute larkAttribute = JsonUtil.parseObject(context.getNotifyAttribute(), LarkAttribute.class);
Map<String, Object> map = new HashMap<>();
map.put("header", buildHeader(context.getTitle()));
map.put("elements", buildElements(context.getText(),larkAttribute.getAts(),larkAttribute.isAtAll()));
LarkMessage builder = LarkMessage.builder()
.msgType("interactive")
.card(map).build();
try {
LarkAttribute larkAttribute = JsonUtil.parseObject(context.getNotifyAttribute(), LarkAttribute.class);
Map<String, Object> map = new HashMap<>();
map.put("header", buildHeader(context.getTitle()));
map.put("elements", buildElements(context.getText(), larkAttribute.getAts()));
LarkMessage builder = LarkMessage.builder()
.msgType("interactive")
.card(map).build();
HttpRequest post = HttpUtil.createPost(larkAttribute.getWebhookUrl());
HttpRequest request = post.body(JsonUtil.toJsonString(builder), ContentType.JSON.toString());
HttpResponse execute = request.execute();
@ -75,10 +77,10 @@ public class LarkAlarm extends AbstractAlarm<AlarmContext> {
return true;
}
private List buildElements(String text,List<String> ats,boolean isAtAll) {
private List buildElements(String text, List<String> ats) {
Map<String, String> map = new HashMap<>();
map.put("tag", "markdown");
map.put("content", getAtText(text,ats,isAtAll));
map.put("content", getAtText(text, ats));
return Collections.singletonList(map);
}
@ -114,14 +116,17 @@ public class LarkAlarm extends AbstractAlarm<AlarmContext> {
private Map<String, Object> card;
}
public String getAtText(String text, List<String> ats, boolean isAtAll) {
public String getAtText(String text, List<String> ats) {
if (CollectionUtils.isEmpty(ats)) {
return "";
}
StringBuilder sb = new StringBuilder(text);
if (isAtAll) {
sb.append(MessageFormat.format(atLabel, "all"));
if (ats.stream().map(String::toLowerCase).anyMatch(SystemConstants.AT_ALL::equals)) {
sb.append(MessageFormat.format(atLabel, SystemConstants.AT_ALL));
} else {
if (!CollectionUtils.isEmpty(ats)) {
ats.forEach(at -> sb.append(MessageFormat.format(atLabel, at)));
}
ats.stream().filter(StrUtil::isNotBlank)
.forEach(at -> sb.append(MessageFormat.format(atLabel, at)));
}
return sb.toString();
}

View File

@ -91,4 +91,9 @@ public interface SystemConstants {
* 默认名称空间
*/
String DEFAULT_NAMESPACE = "764d604ec6fc45f68cd92514c40e9e1a";
/**
* AT 所有人
*/
String AT_ALL = "all";
}

View File

@ -1,5 +1,7 @@
package com.aizuda.easy.retry.common.core.util;
import cn.hutool.core.util.StrUtil;
import com.aizuda.easy.retry.common.core.constant.SystemConstants;
import com.aizuda.easy.retry.common.core.log.LogUtils;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
@ -10,7 +12,9 @@ import org.springframework.util.StringUtils;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author: www.byteblogs.com
@ -44,18 +48,20 @@ public class DingDingUtils {
* @param text
* @return
*/
public static OapiRobotSendRequest buildSendRequest(String title, String text, List<String> ats,boolean isAtAll) {
public static OapiRobotSendRequest buildSendRequest(String title, String text, List<String> ats) {
OapiRobotSendRequest request = new OapiRobotSendRequest();
request.setMsgtype("markdown");
OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
markdown.setTitle(title);
markdown.setText(subTextLength(getAtText(ats,text)));
request.setMarkdown(markdown);
markdown.setText(subTextLength(getAtText(ats, text)));
OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
at.setAtMobiles(ats);
at.setIsAtAll(isAtAll);
request.setAt(at);
if (!CollectionUtils.isEmpty(ats)) {
at.setIsAtAll(ats.stream().map(String::toLowerCase).anyMatch(SystemConstants.AT_ALL::equals));
}
return request;
}
@ -64,18 +70,18 @@ public class DingDingUtils {
return text;
}
StringBuilder sb = new StringBuilder(text);
ats.forEach(at -> sb.append(MessageFormat.format(atLabel, at)));
ats.stream().filter(StrUtil::isNotBlank)
.forEach(at -> sb.append(MessageFormat.format(atLabel, at)));
return sb.toString();
}
/**
*
* @param request
*/
public static boolean sendMessage(OapiRobotSendRequest request, String url){
public static boolean sendMessage(OapiRobotSendRequest request, String url) {
try {
if (StringUtils.isEmpty(url)) {
if (StrUtil.isNotBlank(url)) {
return false;
}
DingTalkClient client = new DefaultDingTalkClient(url);
@ -83,7 +89,7 @@ public class DingDingUtils {
return true;
} catch (Exception e) {
LogUtils.error(log,"dingDingProcessNotify", e);
LogUtils.error(log, "dingDingProcessNotify", e);
}
return false;

View File

@ -10,6 +10,8 @@ import com.aizuda.easy.retry.template.datasource.persistence.po.NotifyConfig;
import com.aizuda.easy.retry.template.datasource.persistence.po.RetryDeadLetter;
import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTask;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
@ -24,8 +26,16 @@ public interface AlarmInfoConverter {
AlarmInfoConverter INSTANCE = Mappers.getMapper(AlarmInfoConverter.class);
@Mappings(
@Mapping(source = "retryCount", target = "count")
)
List<RetryAlarmInfo> retryTaskToAlarmInfo(List<RetryTask> retryTasks);
@Mappings(
@Mapping(source = "retryCount", target = "count")
)
RetryAlarmInfo retryTaskToAlarmInfo(RetryTask retryTask);
List<RetryAlarmInfo> deadLetterToAlarmInfo(List<RetryDeadLetter> retryDeadLetters);
List<NotifyConfigInfo> retryToNotifyConfigInfos(List<NotifyConfig> notifyConfigs);

View File

@ -118,6 +118,12 @@ public abstract class AbstractAlarm<E extends ApplicationEvent, A extends AlarmI
}
}
if (Objects.nonNull(alarmDTO.getCount()) && Objects.nonNull(notifyConfig.getNotifyThreshold())) {
if (notifyConfig.getNotifyThreshold() > alarmDTO.getCount()) {
continue;
}
}
AlarmContext context = buildAlarmContext(alarmDTO, notifyConfig);
Alarm<AlarmContext> alarmType = easyRetryAlarmFactory.getAlarmType(
notifyConfig.getNotifyType());

View File

@ -1,13 +1,18 @@
package com.aizuda.easy.retry.server.common.dto;
import lombok.Data;
/**
* @author xiaowoniu
* @date 2023-12-03 10:15:37
* @since 2.5.0
*/
@Data
public class AlarmInfo {
private String namespaceId;
private String groupName;
private Integer count;
}

View File

@ -1,38 +1,25 @@
package com.aizuda.easy.retry.server.job.task.support.listener;
import com.aizuda.easy.retry.common.core.alarm.Alarm;
import com.aizuda.easy.retry.common.core.alarm.AlarmContext;
import com.aizuda.easy.retry.common.core.alarm.EasyRetryAlarmFactory;
import com.aizuda.easy.retry.common.core.enums.JobNotifySceneEnum;
import com.aizuda.easy.retry.common.core.enums.StatusEnum;
import com.aizuda.easy.retry.common.core.log.LogUtils;
import com.aizuda.easy.retry.common.core.util.EnvironmentUtils;
import com.aizuda.easy.retry.common.core.util.HostUtils;
import com.aizuda.easy.retry.server.common.AlarmInfoConverter;
import com.aizuda.easy.retry.server.common.Lifecycle;
import com.aizuda.easy.retry.server.common.alarm.AbstractJobAlarm;
import com.aizuda.easy.retry.server.common.dto.JobAlarmInfo;
import com.aizuda.easy.retry.server.common.dto.NotifyConfigInfo;
import com.aizuda.easy.retry.server.common.triple.ImmutableTriple;
import com.aizuda.easy.retry.server.common.triple.Triple;
import com.aizuda.easy.retry.server.common.util.DateUtils;
import com.aizuda.easy.retry.server.job.task.support.event.JobTaskFailAlarmEvent;
import com.aizuda.easy.retry.template.datasource.persistence.dataobject.JobBatchResponseDO;
import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobNotifyConfigMapper;
import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobTaskBatchMapper;
import com.aizuda.easy.retry.template.datasource.persistence.po.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.util.*;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.stream.Collectors;
/**
@ -49,16 +36,14 @@ public class JobTaskFailAlarmListener extends AbstractJobAlarm<JobTaskFailAlarmE
@Autowired
private JobTaskBatchMapper jobTaskBatchMapper;
@Autowired
private EasyRetryAlarmFactory easyRetryAlarmFactory;
/**
* job任务失败数据
*/
private LinkedBlockingQueue<Long> queue = new LinkedBlockingQueue<>(1000);
private static String jobTaskFailTextMessagesFormatter =
"<font face=\"微软雅黑\" color=#ff0000 size=4>{}环境 Job任务执行失败</font> \n" +
"<font face=\"微软雅黑\" color=#ff0000 size=4>{}环境 Job任务执行失败</font> \n" +
"> 空间ID:{} \n" +
"> 组名称:{} \n" +
"> 任务名称:{} \n" +
"> 执行器名称:{} \n" +
@ -83,6 +68,7 @@ public class JobTaskFailAlarmListener extends AbstractJobAlarm<JobTaskFailAlarmE
return AlarmContext.build()
.text(jobTaskFailTextMessagesFormatter,
EnvironmentUtils.getActiveProfile(),
alarmDTO.getNamespaceId(),
alarmDTO.getGroupName(),
alarmDTO.getJobName(),
alarmDTO.getExecutorInfo(),

View File

@ -55,6 +55,7 @@ public class RetryTaskFailDeadLetterAlarmListener extends AbstractRetryAlarm<Ret
private static String retryTaskDeadTextMessagesFormatter =
"<font face=\"微软雅黑\" color=#ff0000 size=4>{}环境 重试任务失败进入死信队列</font> \n" +
"> 空间ID:{} \n" +
"> 组名称:{} \n" +
"> 执行器名称:{} \n" +
"> 场景名称:{} \n" +
@ -85,6 +86,7 @@ public class RetryTaskFailDeadLetterAlarmListener extends AbstractRetryAlarm<Ret
// 预警
return AlarmContext.build().text(retryTaskDeadTextMessagesFormatter,
EnvironmentUtils.getActiveProfile(),
retryAlarmInfo.getNamespaceId(),
retryAlarmInfo.getGroupName(),
retryAlarmInfo.getExecutorName(),
retryAlarmInfo.getSceneName(),
@ -102,6 +104,6 @@ public class RetryTaskFailDeadLetterAlarmListener extends AbstractRetryAlarm<Ret
@Override
protected int getNotifyScene() {
return NotifySceneEnum.MAX_RETRY.getNotifyScene();
return NotifySceneEnum.RETRY_TASK_ENTER_DEAD_LETTER.getNotifyScene();
}
}

View File

@ -50,6 +50,7 @@ public class RetryTaskFailMoreThresholdAlarmListener extends
private LinkedBlockingQueue<RetryTask> queue = new LinkedBlockingQueue<>(1000);
private static String retryTaskFailMoreThresholdMessagesFormatter =
"<font face=\"微软雅黑\" color=#ff0000 size=4>{}环境 重试任务失败数量超过阈值</font> \n" +
"> 空间ID:{} \n" +
"> 组名称:{} \n" +
"> 执行器名称:{} \n" +
"> 场景名称:{} \n" +
@ -82,6 +83,7 @@ public class RetryTaskFailMoreThresholdAlarmListener extends
// 预警
return AlarmContext.build().text(retryTaskFailMoreThresholdMessagesFormatter,
EnvironmentUtils.getActiveProfile(),
retryAlarmInfo.getNamespaceId(),
retryAlarmInfo.getGroupName(),
retryAlarmInfo.getExecutorName(),
retryAlarmInfo.getSceneName(),
@ -100,6 +102,6 @@ public class RetryTaskFailMoreThresholdAlarmListener extends
@Override
protected int getNotifyScene() {
return NotifySceneEnum.MAX_RETRY_ERROR.getNotifyScene();
return NotifySceneEnum.RETRY_TASK_REACH_THRESHOLD.getNotifyScene();
}
}

View File

@ -102,7 +102,7 @@
import { getAllGroupNameList } from '@/api/manage'
import { STable } from '@/components'
import { getJobList, jobNameList, jobNotifyConfigPageList } from '@/api/jobApi'
const enums = require('@/utils/retryEnum')
const enums = require('@/utils/jobEnum')
export default {
name: 'JobNotifyList',

View File

@ -153,7 +153,7 @@
<a-modal :visible="visible" title="添加配置" @ok="handleOk" @cancel="handlerCancel" width="1000px">
<a-form :form="notifyAttributeForm" @submit="handleSubmit" :body-style="{padding: '0px 0px'}" v-bind="formItemLayout" >
<a-form-item
v-if="this.notifyTypeValue === '1'"
v-if="this.tempNotifyTypeValue === '1'"
label="钉钉URL">
<a-input
placeholder="请输入钉钉URL"
@ -162,19 +162,19 @@
{rules: [{ required: true, message: '请输入钉钉URL', whitespace: true}]}
]" />
</a-form-item>
<a-form-item v-if="this.notifyTypeValue === '1'">
<a-form-item v-if="this.tempNotifyTypeValue === '1'">
<span slot="label">@人手机号或钉钉号&nbsp;<a :href="officialWebsite + '/pages/32e4a0/#被@人手机号是何物' +''" target="_blank"> <a-icon type="question-circle-o" /></a></span>
<a-input
placeholder="请输入被@人手机号或钉钉号"
type="textarea"
v-if="this.notifyTypeValue === '1'"
v-if="this.tempNotifyTypeValue === '1'"
v-decorator="[
'ats',
{rules: [{ required: true, message: '请输入被@人手机号或钉钉号', whitespace: true}]}
{rules: [{ required: false, message: '请输入被@人手机号或钉钉号', whitespace: true}]}
]" />
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '4'"
v-if="this.tempNotifyTypeValue === '4'"
label="飞书URL">
<a-input
placeholder="请输入飞书URL"
@ -184,56 +184,56 @@
]" />
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '4'">
v-if="this.tempNotifyTypeValue === '4'">
<span slot="label">@负责人用户id&nbsp;<a :href="officialWebsite + '/pages/32e4a0/#被@人open_id是何物' +''" target="_blank"> <a-icon type="question-circle-o" /></a></span>
<a-input
placeholder="请输入被@人open_id"
type="textarea"
v-if="this.notifyTypeValue === '4'"
v-if="this.tempNotifyTypeValue === '4'"
v-decorator="[
'ats',
{rules: [{ required: true, message: '请输入被@人open_id', whitespace: true}]}
{rules: [{ required: false, message: '请输入被@人open_id', whitespace: true}]}
]" />
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
label="用户名">
<a-input
placeholder="请输入用户名"
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
v-decorator="[
'user',
{rules: [{ required: true, message: '请输入用户名', whitespace: true}]}
]" />
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
label="密码">
<a-input
placeholder="请输入密码"
type="password"
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
v-decorator="[
'pass',
{rules: [{ required: true, message: '请输入密码', whitespace: true}]}
]"/>
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
label="SMTP地址">
<a-input
placeholder="请输入邮件服务器的SMTP地址"
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
v-decorator="[
'host',
{rules: [{ required: true, message: '请输入邮件服务器的SMTP地址', whitespace: true}]}
]"/>
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
label="SMTP端口">
<a-input
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
placeholder="请输入邮件服务器的SMTP端口"
v-decorator="[
'port',
@ -241,10 +241,10 @@
]"/>
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
label="发件人">
<a-input
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
placeholder="请输入发件人"
v-decorator="[
'from',
@ -252,10 +252,10 @@
]"/>
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
label="收件人">
<a-input
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
placeholder="请输入收件人"
v-decorator="[
'tos',
@ -312,6 +312,7 @@ export default {
visible: false,
count: 0,
notifyTypeValue: '1',
tempNotifyTypeValue: '1',
notifyAttribute: '',
notifyThresholdDisabled: ['1'],
sceneNameDisabled: ['3', '4'],
@ -348,11 +349,16 @@ export default {
this.form.resetFields()
},
buildNotifyAttribute (formData) {
formData.ats = formData.ats && formData.ats.replace(/\s+/g, '').split(',')
if (formData.ats) {
formData.ats = formData.ats && formData.ats.replace(/\s+/g, '').split(',')
}
return JSON.stringify(formData)
},
handleChange (notifyType) {
this.notifyTypeValue = notifyType
this.tempNotifyTypeValue = notifyType
this.form.setFieldsValue({
notifyAttribute: ''
})
},
changeGroup (value) {
getJobList({ groupName: value }).then((res) => {
@ -379,10 +385,11 @@ export default {
}
},
handleBlur () {
this.notifyAttributeForm.resetFields()
new Promise((resolve) => {
setTimeout(resolve, 100)
}).then(() => {
if (this.formType === 'edit') {
if (this.formType === 'edit' && this.tempNotifyTypeValue === this.notifyTypeValue) {
const formData = pick(JSON.parse(this.notifyAttribute), ['webhookUrl', 'ats', 'user', 'pass', 'host', 'port', 'from', 'tos'])
this.notifyAttributeForm.getFieldDecorator(`webhookUrl`, { initialValue: formData.webhookUrl, preserve: true })
if (formData.ats) {
@ -394,7 +401,11 @@ export default {
this.notifyAttributeForm.getFieldDecorator(`port`, { initialValue: formData.port, preserve: true })
this.notifyAttributeForm.getFieldDecorator(`from`, { initialValue: formData.from, preserve: true })
this.notifyAttributeForm.getFieldDecorator(`tos`, { initialValue: formData.tos, preserve: true })
} else {
this.notifyAttributeForm.getFieldDecorator(`webhookUrl`, { initialValue: '', preserve: true })
this.notifyAttributeForm.getFieldDecorator(`ats`, { initialValue: '', preserve: true })
}
this.visible = !this.visible
})
},
@ -410,6 +421,7 @@ export default {
form.setFieldsValue({
notifyAttribute: this.parseJson(formData)
})
this.notifyTypeValue = this.tempNotifyTypeValue
this.visible = false
}
})
@ -454,6 +466,7 @@ export default {
formData.rateLimiterStatus = formData.rateLimiterStatus.toString()
formData.rateLimiterThreshold = formData.rateLimiterThreshold.toString()
this.notifyTypeValue = formData.notifyType
this.tempNotifyTypeValue = formData.notifyType
this.notifyAttribute = formData.notifyAttribute
this.notifySceneValue = formData.notifyScene
this.rateLimiterStatusValue = formData.rateLimiterStatus

View File

@ -56,14 +56,14 @@
<a-row class="form-row" :gutter="16">
<a-col :lg="18" :md="12" :sm="24">
<a-form-item label="组">
<a-select placeholder="请选择组" v-decorator="['groupName', { rules: [{ required: true, message: '请选择组' }] }]" @change="value => changeGroup(value)">
<a-select placeholder="请选择组" v-decorator="['groupName', { rules: [{ required: true, message: '请选择组' }] }]" @change="value => changeGroup(value)">
<a-select-option v-for="item in groupNameList" :value="item" :key="item">{{ item }}</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="6" :md="12" :sm="24">
<a-form-item label="场景">
<a-select :disabled="sceneNameDisabled.includes(this.notifySceneValue)" placeholder="请选择场景" v-decorator="['sceneName', { rules: [{ required: !sceneNameDisabled.includes(this.notifySceneValue), message: '请选择场景' }] }]" >
<a-select :disabled="sceneNameDisabled.includes(this.notifySceneValue)" placeholder="请选择场景" v-decorator="['sceneName', { rules: [{ required: !sceneNameDisabled.includes(this.notifySceneValue), message: '请选择场景' }] }]" >
<a-select-option v-for="item in sceneList" :value="item.sceneName" :key="item.sceneName">{{ item.sceneName }}</a-select-option>
</a-select>
</a-form-item>
@ -103,21 +103,21 @@
<a-row class="form-row" :gutter="16">
<a-col :lg="8" :md="12" :sm="24">
<a-form-item label="限流状态">
<a-select :disabled="rateLimiterStatusDisabled.includes(this.notifySceneValue)" placeholder="请选择限流状态" @change="changeRateLimiterStatus" v-decorator="['rateLimiterStatus',{initialValue: '0', rules: [{ required: true, message: '请选择限流状态'}]}]" >
<a-select :disabled="rateLimiterStatusDisabled.includes(this.notifySceneValue)" placeholder="请选择限流状态" @change="changeRateLimiterStatus" v-decorator="['rateLimiterStatus',{initialValue: '0', rules: [{ required: true, message: '请选择限流状态'}]}]" >
<a-select-option :value="index" v-for="(item, index) in rateLimiterStatusList" :key="index">{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="8" :md="12" :sm="24">
<a-form-item label="每秒限流阈值">
<a-input-number :disabled="rateLimiterThresholdDisabled.includes(this.rateLimiterStatusValue)" id="inputNumber" :min="1" style="width: -webkit-fill-available" v-decorator= "['rateLimiterThreshold',{initialValue: '100',rules: [{ required: !rateLimiterThresholdDisabled.includes(this.rateLimiterStatusValue), message: '请输入通知阈值' }]}]" />
</a-form-item>
<a-input-number :disabled="rateLimiterThresholdDisabled.includes(this.rateLimiterStatusValue)" id="inputNumber" :min="1" style="width: -webkit-fill-available" v-decorator="['rateLimiterThreshold',{initialValue: '100',rules: [{ required: !rateLimiterThresholdDisabled.includes(this.rateLimiterStatusValue), message: '请输入通知阈值' }]}]" />
</a-form-item>
</a-col>
<a-col :lg="8" :md="12" :sm="24">
<a-form-item label="状态">
<a-select
placeholder="请选择状态"
v-decorator="[
placeholder="请选择状态"
v-decorator="[
'notifyStatus',
{
initialValue: '1',
@ -153,7 +153,7 @@
<a-modal :visible="visible" title="添加配置" @ok="handleOk" @cancel="handlerCancel" width="1000px">
<a-form :form="notifyAttributeForm" @submit="handleSubmit" :body-style="{padding: '0px 0px'}" v-bind="formItemLayout" >
<a-form-item
v-if="this.notifyTypeValue === '1'"
v-if="this.tempNotifyTypeValue === '1'"
label="钉钉URL">
<a-input
placeholder="请输入钉钉URL"
@ -162,19 +162,19 @@
{rules: [{ required: true, message: '请输入钉钉URL', whitespace: true}]}
]" />
</a-form-item>
<a-form-item v-if="this.notifyTypeValue === '1'">
<a-form-item v-if="this.tempNotifyTypeValue === '1'">
<span slot="label">@人手机号或钉钉号&nbsp;<a :href="officialWebsite + '/pages/32e4a0/#被被@人手机号或钉钉号是何物' +''" target="_blank"> <a-icon type="question-circle-o" /></a></span>
<a-input
placeholder="请输入被@人手机号或钉钉号"
type="textarea"
v-if="this.notifyTypeValue === '1'"
v-if="this.tempNotifyTypeValue === '1'"
v-decorator="[
'ats',
{rules: [{ required: false, message: '请输入被@人手机号或钉钉号', whitespace: true}]}
]" />
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '4'"
v-if="this.tempNotifyTypeValue === '4'"
label="飞书URL">
<a-input
placeholder="请输入飞书URL"
@ -184,56 +184,56 @@
]" />
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '4'">
v-if="this.tempNotifyTypeValue === '4'">
<span slot="label">@人用户id&nbsp;<a :href="officialWebsite + '/pages/32e4a0/#被@人open_id是何物' +''" target="_blank"> <a-icon type="question-circle-o" /></a></span>
<a-input
placeholder="请输入被@人open_id"
type="textarea"
v-if="this.notifyTypeValue === '4'"
v-if="this.tempNotifyTypeValue === '4'"
v-decorator="[
'ats',
{rules: [{ required: false, message: '请输入被@人open_id', whitespace: true}]}
]" />
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
label="用户名">
<a-input
placeholder="请输入用户名"
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
v-decorator="[
'user',
{rules: [{ required: true, message: '请输入用户名', whitespace: true}]}
]" />
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
label="密码">
<a-input
placeholder="请输入密码"
type="password"
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
v-decorator="[
'pass',
{rules: [{ required: true, message: '请输入密码', whitespace: true}]}
]"/>
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
label="SMTP地址">
<a-input
placeholder="请输入邮件服务器的SMTP地址"
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
v-decorator="[
'host',
{rules: [{ required: true, message: '请输入邮件服务器的SMTP地址', whitespace: true}]}
]"/>
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
label="SMTP端口">
<a-input
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
placeholder="请输入邮件服务器的SMTP端口"
v-decorator="[
'port',
@ -241,10 +241,10 @@
]"/>
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
label="发件人">
<a-input
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
placeholder="请输入发件人"
v-decorator="[
'from',
@ -252,10 +252,10 @@
]"/>
</a-form-item>
<a-form-item
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
label="收件人">
<a-input
v-if="this.notifyTypeValue === '2'"
v-if="this.tempNotifyTypeValue === '2'"
placeholder="请输入收件人"
v-decorator="[
'tos',
@ -312,6 +312,7 @@ export default {
visible: false,
count: 0,
notifyTypeValue: '1',
tempNotifyTypeValue: '1',
notifyAttribute: '',
notifyThresholdDisabled: ['3', '4', '6'],
sceneNameDisabled: ['3', '4'],
@ -348,11 +349,16 @@ export default {
this.form.resetFields()
},
buildNotifyAttribute (formData) {
formData.ats = formData.ats && formData.ats.replace(/\s+/g, '').split(',')
if (formData.ats) {
formData.ats = formData.ats && formData.ats.replace(/\s+/g, '').split(',')
}
return JSON.stringify(formData)
},
handleChange (notifyType) {
this.notifyTypeValue = notifyType
this.tempNotifyTypeValue = notifyType
this.form.setFieldsValue({
notifyAttribute: ''
})
},
changeGroup (value) {
getSceneList({ groupName: value }).then((res) => {
@ -382,7 +388,7 @@ export default {
new Promise((resolve) => {
setTimeout(resolve, 100)
}).then(() => {
if (this.formType === 'edit') {
if (this.formType === 'edit' && this.tempNotifyTypeValue === this.notifyTypeValue) {
const formData = pick(JSON.parse(this.notifyAttribute), ['webhookUrl', 'ats', 'user', 'pass', 'host', 'port', 'from', 'tos'])
this.notifyAttributeForm.getFieldDecorator(`webhookUrl`, { initialValue: formData.webhookUrl, preserve: true })
if (formData.ats) {
@ -410,6 +416,7 @@ export default {
form.setFieldsValue({
notifyAttribute: this.parseJson(formData)
})
this.notifyTypeValue = this.tempNotifyTypeValue
this.visible = false
}
})
@ -454,6 +461,7 @@ export default {
formData.rateLimiterStatus = formData.rateLimiterStatus.toString()
formData.rateLimiterThreshold = formData.rateLimiterThreshold.toString()
this.notifyTypeValue = formData.notifyType
this.tempNotifyTypeValue = formData.notifyType
this.notifyAttribute = formData.notifyAttribute
this.notifySceneValue = formData.notifyScene
this.rateLimiterStatusValue = formData.rateLimiterStatus