refactor: 发送站内通知

This commit is contained in:
Captain.B 2021-08-18 18:25:40 +08:00 committed by 刘瑞斌
parent 51db39b341
commit 5800b41ba2
19 changed files with 218 additions and 238 deletions

View File

@ -29,6 +29,7 @@ public interface NoticeConstants {
String NAIL_ROBOT = "NAIL_ROBOT";
String WECHAT_ROBOT = "WECHAT_ROBOT";
String LARK = "LARK";
String IN_SITE = "IN_SITE";
}
interface Event {

View File

@ -24,14 +24,14 @@ public abstract class AbstractNoticeSender implements NoticeSender {
private UserService userService;
protected String getContext(MessageDetail messageDetail, NoticeModel noticeModel) {
// 处理 userIds 中包含的特殊值
handleRealUserIds(messageDetail, noticeModel);
// 如果配置了模版就直接使用模版
if (StringUtils.isNotBlank(messageDetail.getTemplate())) {
return getContent(messageDetail.getTemplate(), noticeModel.getParamMap());
}
// 处理 userIds 中包含的特殊值
List<String> realUserIds = getRealUserIds(messageDetail.getUserIds(), noticeModel, messageDetail.getEvent());
messageDetail.setUserIds(realUserIds);
// 处理 WeCom Ding context
String context = "";
switch (messageDetail.getEvent()) {
@ -54,13 +54,13 @@ public abstract class AbstractNoticeSender implements NoticeSender {
}
protected String getHtmlContext(MessageDetail messageDetail, NoticeModel noticeModel) {
// 处理 userIds 中包含的特殊值
handleRealUserIds(messageDetail, noticeModel);
// 如果配置了模版就直接使用模版
if (StringUtils.isNotBlank(messageDetail.getTemplate())) {
return getContent(messageDetail.getTemplate(), noticeModel.getParamMap());
}
// 处理 userIds 中包含的特殊值
List<String> realUserIds = getRealUserIds(messageDetail.getUserIds(), noticeModel, messageDetail.getEvent());
messageDetail.setUserIds(realUserIds);
// 处理 mail context
String context = "";
@ -96,6 +96,14 @@ public abstract class AbstractNoticeSender implements NoticeSender {
return getContent(context, noticeModel.getParamMap());
}
private void handleRealUserIds(MessageDetail messageDetail, NoticeModel noticeModel) {
List<String> realUserIds = getRealUserIds(messageDetail.getUserIds(), noticeModel, messageDetail.getEvent());
// 排除自己操作的
String operator = noticeModel.getOperator();
realUserIds.remove(operator);
messageDetail.setUserIds(realUserIds);
}
protected String getContent(String template, Map<String, Object> context) {
if (MapUtils.isNotEmpty(context)) {
for (String k : context.keySet()) {
@ -110,10 +118,6 @@ public abstract class AbstractNoticeSender implements NoticeSender {
}
protected List<String> getUserPhones(NoticeModel noticeModel, List<String> userIds) {
// 排除自己操作的
String operator = noticeModel.getOperator();
userIds.remove(operator);
List<UserDetail> list = userService.queryTypeByIds(userIds);
List<String> phoneList = new ArrayList<>();
list.forEach(u -> phoneList.add(u.getPhone()));
@ -122,10 +126,6 @@ public abstract class AbstractNoticeSender implements NoticeSender {
}
protected List<String> getUserEmails(NoticeModel noticeModel, List<String> userIds) {
// 排除自己操作的
String operator = noticeModel.getOperator();
userIds.remove(operator);
List<UserDetail> list = userService.queryTypeByIds(userIds);
List<String> phoneList = new ArrayList<>();
list.forEach(u -> phoneList.add(u.getEmail()));

View File

@ -0,0 +1,37 @@
package io.metersphere.notice.sender.impl;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.notice.domain.MessageDetail;
import io.metersphere.notice.sender.AbstractNoticeSender;
import io.metersphere.notice.sender.NoticeModel;
import io.metersphere.notice.service.NotificationService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
@Component
public class InSiteNoticeSender extends AbstractNoticeSender {
@Resource
private NotificationService notificationService;
public void sendAnnouncement(MessageDetail messageDetail, NoticeModel noticeModel, String context) {
List<String> userIds = messageDetail.getUserIds();
if (CollectionUtils.isEmpty(userIds)) {
return;
}
userIds.forEach(receiver -> {
LogUtil.debug("发送站内通知: {}, 内容: {}", receiver, context);
notificationService.sendAnnouncement(noticeModel.getSubject(), context, receiver);
});
}
@Override
public void send(MessageDetail messageDetail, NoticeModel noticeModel) {
String context = super.getContext(messageDetail, noticeModel);
sendAnnouncement(messageDetail, noticeModel, context);
}
}

View File

@ -1,27 +1,16 @@
package io.metersphere.notice.service;
import com.alibaba.nacos.client.utils.StringUtils;
import io.metersphere.base.domain.User;
import io.metersphere.commons.constants.NoticeConstants;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.organization.QueryOrgMemberRequest;
import io.metersphere.notice.domain.MessageDetail;
import io.metersphere.notice.sender.AbstractNoticeSender;
import io.metersphere.notice.sender.NoticeModel;
import io.metersphere.notice.sender.impl.DingNoticeSender;
import io.metersphere.notice.sender.impl.LarkNoticeSender;
import io.metersphere.notice.sender.impl.MailNoticeSender;
import io.metersphere.notice.sender.impl.WeComNoticeSender;
import io.metersphere.service.UserService;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.RegExUtils;
import org.springframework.scheduling.annotation.Async;
import io.metersphere.notice.sender.impl.*;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
@Component
public class NoticeSendService {
@ -36,9 +25,8 @@ public class NoticeSendService {
@Resource
private NoticeService noticeService;
@Resource
private NotificationService notificationService;
@Resource
private UserService userService;
private InSiteNoticeSender inSiteNoticeSender;
private AbstractNoticeSender getNoticeSender(MessageDetail messageDetail) {
AbstractNoticeSender noticeSender = null;
@ -54,6 +42,10 @@ public class NoticeSendService {
break;
case NoticeConstants.Type.LARK:
noticeSender = larkNoticeSender;
break;
case NoticeConstants.Type.IN_SITE:
noticeSender = inSiteNoticeSender;
break;
default:
break;
}
@ -76,46 +68,16 @@ public class NoticeSendService {
messageDetails = noticeService.searchMessageByType(taskType);
break;
}
QueryOrgMemberRequest request = new QueryOrgMemberRequest();
request.setOrganizationId(SessionUtils.getCurrentOrganizationId());
List<User> orgAllMember = userService.getOrgAllMember(request);
// 异步发送实体通知
// 异步发送通知
messageDetails.stream()
.filter(messageDetail -> StringUtils.equals(messageDetail.getEvent(), noticeModel.getEvent()))
.forEach(messageDetail -> this.getNoticeSender(messageDetail).send(messageDetail, noticeModel));
.forEach(messageDetail -> {
this.getNoticeSender(messageDetail).send(messageDetail, noticeModel);
});
// 异步发送站内通知
sendAnnouncement(noticeModel, orgAllMember);
} catch (Exception e) {
LogUtil.error(e.getMessage(), e);
}
}
@Async
public void sendAnnouncement(NoticeModel noticeModel, List<User> orgAllMember) {
// 替换变量
noticeModel.setContext(getContent(noticeModel));
orgAllMember.forEach(receiver -> {
String context = noticeModel.getContext();
LogUtil.debug("发送站内通知: {}, 内容: {}", receiver.getName(), context);
notificationService.sendAnnouncement(noticeModel.getSubject(), context, receiver.getId());
});
}
private String getContent(NoticeModel noticeModel) {
String template = noticeModel.getContext();
Map<String, Object> paramMap = noticeModel.getParamMap();
if (MapUtils.isNotEmpty(paramMap)) {
for (String k : paramMap.keySet()) {
if (paramMap.get(k) != null) {
template = RegExUtils.replaceAll(template, "\\$\\{" + k + "}", paramMap.get(k).toString());
} else {
template = RegExUtils.replaceAll(template, "\\$\\{" + k + "}", "");
}
}
}
return template;
}
}

View File

@ -15,12 +15,18 @@
</span>
<span>通知数: <span style="color: #783887;">{{ trackNoticeSize }}</span></span>
</template>
<track-home-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"/>
<test-case-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"/>
<test-review-notification @noticeSize="getNoticeSize" :review-receiver-options="reviewReceiverOptions"/>
<test-plan-task-notification @noticeSize="getNoticeSize" :test-plan-receiver-options="testPlanReceiverOptions"/>
<defect-task-notification @noticeSize="getNoticeSize" :defect-receiver-options="defectReceiverOptions"/>
<track-report-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"/>
<track-home-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"
:receive-type-options="receiveTypeOptions"/>
<test-case-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"
:receive-type-options="receiveTypeOptions"/>
<test-review-notification @noticeSize="getNoticeSize" :review-receiver-options="reviewReceiverOptions"
:receive-type-options="receiveTypeOptions"/>
<test-plan-task-notification @noticeSize="getNoticeSize" :test-plan-receiver-options="testPlanReceiverOptions"
:receive-type-options="receiveTypeOptions"/>
<defect-task-notification @noticeSize="getNoticeSize" :defect-receiver-options="defectReceiverOptions"
:receive-type-options="receiveTypeOptions"/>
<track-report-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"
:receive-type-options="receiveTypeOptions"/>
</el-collapse-item>
<el-collapse-item name="3">
<template v-slot:title>
@ -29,10 +35,14 @@
</span>
<span>通知数: <span style="color: #783887;">{{ apiNoticeSize }}</span></span>
</template>
<api-home-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"/>
<api-definition-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"/>
<api-automation-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"/>
<api-report-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"/>
<api-home-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"
:receive-type-options="receiveTypeOptions"/>
<api-definition-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"
:receive-type-options="receiveTypeOptions"/>
<api-automation-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"
:receive-type-options="receiveTypeOptions"/>
<api-report-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"
:receive-type-options="receiveTypeOptions"/>
</el-collapse-item>
<el-collapse-item name="4">
<template v-slot:title>
@ -41,15 +51,18 @@
</span>
<span>通知数: <span style="color: #783887;">{{ performanceNoticeSize }}</span></span>
</template>
<performance-test-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"/>
<performance-report-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"/>
<performance-test-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"
:receive-type-options="receiveTypeOptions"/>
<performance-report-notification @noticeSize="getNoticeSize" :receiver-options="reviewReceiverOptions"
:receive-type-options="receiveTypeOptions"/>
</el-collapse-item>
<el-collapse-item name="1">
<template v-slot:title>
<span style="width: 200px">{{ $t('organization.message.jenkins_task_notification') }}</span>
<span>通知数: <span style="color: #783887;">{{ jenkinsNoticeSize }}</span></span>
</template>
<jenkins-notification @noticeSize="getNoticeSize" :jenkins-receiver-options="jenkinsReceiverOptions"/>
<jenkins-notification @noticeSize="getNoticeSize" :jenkins-receiver-options="jenkinsReceiverOptions"
:receive-type-options="receiveTypeOptions"/>
</el-collapse-item>
</el-collapse>
</div>
@ -119,6 +132,13 @@ export default {
reviewReceiverOptions: [],
//
defectReceiverOptions: [],
receiveTypeOptions: [
{value: 'IN_SITE', label: this.$t('organization.message.in_site')},
{value: 'EMAIL', label: this.$t('organization.message.mail')},
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
{value: 'LARK', label: this.$t('organization.message.lark')}
],
result: {}
};
},

View File

@ -160,6 +160,9 @@ export default {
props: {
receiverOptions: {
type: Array
},
receiveTypeOptions: {
type: Array
}
},
data() {
@ -193,12 +196,6 @@ export default {
{value: 'UPDATE', label: this.$t('commons.update')},
{value: 'DELETE', label: this.$t('commons.delete')},
],
receiveTypeOptions: [
{value: 'EMAIL', label: this.$t('organization.message.mail')},
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
{value: 'LARK', label: this.$t('organization.message.lark')}
],
};
},
methods: {

View File

@ -160,6 +160,9 @@ export default {
props: {
receiverOptions: {
type: Array
},
receiveTypeOptions: {
type: Array
}
},
data() {
@ -196,12 +199,6 @@ export default {
{value: 'CASE_UPDATE', label: 'CASE ' + this.$t('commons.update')},
{value: 'CASE_DELETE', label: 'CASE ' + this.$t('commons.delete')},
],
receiveTypeOptions: [
{value: 'EMAIL', label: this.$t('organization.message.mail')},
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
{value: 'LARK', label: this.$t('organization.message.lark')}
],
};
},
methods: {

View File

@ -160,6 +160,9 @@ export default {
props: {
receiverOptions: {
type: Array
},
receiveTypeOptions: {
type: Array
}
},
data() {
@ -191,12 +194,6 @@ export default {
eventOptions: [
{value: 'CLOSE_SCHEDULE', label: '关闭定时任务'},
],
receiveTypeOptions: [
{value: 'EMAIL', label: this.$t('organization.message.mail')},
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
{value: 'LARK', label: this.$t('organization.message.lark')}
],
};
},
activated() {

View File

@ -160,6 +160,9 @@ export default {
props: {
receiverOptions: {
type: Array
},
receiveTypeOptions: {
type: Array
}
},
data() {
@ -191,12 +194,6 @@ export default {
eventOptions: [
{value: 'DELETE', label: this.$t('commons.delete')},
],
receiveTypeOptions: [
{value: 'EMAIL', label: this.$t('organization.message.mail')},
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
{value: 'LARK', label: this.$t('organization.message.lark')}
],
};
},
methods: {

View File

@ -163,6 +163,9 @@ export default {
props: {
jenkinsReceiverOptions: {
type: Array
},
receiveTypeOptions: {
type: Array
}
},
data() {
@ -216,12 +219,6 @@ export default {
{value: 'EXECUTE_SUCCESSFUL', label: this.$t('schedule.event_success')},
{value: 'EXECUTE_FAILED', label: this.$t('schedule.event_failed')}
],
receiveTypeOptions: [
{value: 'EMAIL', label: this.$t('organization.message.mail')},
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
{value: 'LARK', label: this.$t('organization.message.lark')}
],
};
},
activated() {

View File

@ -160,6 +160,9 @@ export default {
props: {
receiverOptions: {
type: Array
},
receiveTypeOptions: {
type: Array
}
},
data() {
@ -191,12 +194,6 @@ export default {
eventOptions: [
{value: 'DELETE', label: this.$t('commons.delete')},
],
receiveTypeOptions: [
{value: 'EMAIL', label: this.$t('organization.message.mail')},
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
{value: 'LARK', label: this.$t('organization.message.lark')}
],
};
},
methods: {

View File

@ -160,6 +160,9 @@ export default {
props: {
receiverOptions: {
type: Array
},
receiveTypeOptions: {
type: Array
}
},
data() {
@ -193,12 +196,6 @@ export default {
{value: 'UPDATE', label: this.$t('commons.update')},
{value: 'DELETE', label: this.$t('commons.delete')},
],
receiveTypeOptions: [
{value: 'EMAIL', label: this.$t('organization.message.mail')},
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
{value: 'LARK', label: this.$t('organization.message.lark')}
],
};
},
methods: {

View File

@ -160,6 +160,9 @@ export default {
props: {
defectReceiverOptions: {
type: Array
},
receiveTypeOptions: {
type: Array
}
},
data() {
@ -194,13 +197,6 @@ export default {
{value: 'DELETE', label: this.$t('commons.delete')},
{value: 'STATUS_CHANGE', label: '状态变更'},
],
receiveTypeOptions: [
{value: 'EMAIL', label: this.$t('organization.message.mail')},
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
{value: 'LARK', label: this.$t('organization.message.lark')}
],
};
},
methods: {

View File

@ -160,6 +160,9 @@ export default {
props: {
receiverOptions: {
type: Array
},
receiveTypeOptions: {
type: Array
}
},
data() {
@ -194,12 +197,6 @@ export default {
{value: 'DELETE', label: this.$t('commons.delete')},
{value: 'COMMENT', label: this.$t('commons.comment')}
],
receiveTypeOptions: [
{value: 'EMAIL', label: this.$t('organization.message.mail')},
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
{value: 'LARK', label: this.$t('organization.message.lark')}
],
};
},
methods: {

View File

@ -159,6 +159,9 @@ export default {
props: {
testPlanReceiverOptions: {
type: Array
},
receiveTypeOptions: {
type: Array
}
},
data() {
@ -203,12 +206,6 @@ export default {
// {value: 'SUCCESS_ONE_BY_ONE', label: ''},
// {value: 'FAIL_ONE_BY_ONE', label: ''},
],
receiveTypeOptions: [
{value: 'EMAIL', label: this.$t('organization.message.mail')},
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
{value: 'LARK', label: this.$t('organization.message.lark')}
],
};
},
methods: {

View File

@ -159,6 +159,9 @@ export default {
props: {
reviewReceiverOptions: {
type: Array
},
receiveTypeOptions: {
type: Array
}
},
data() {
@ -201,13 +204,6 @@ export default {
{value: 'COMMENT', label: this.$t('commons.comment')},
{value: 'COMPLETE', label: '评审完成'}
],
receiveTypeOptions: [
{value: 'EMAIL', label: this.$t('organization.message.mail')},
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
{value: 'LARK', label: this.$t('organization.message.lark')}
],
};
},
methods: {

View File

@ -160,6 +160,9 @@ export default {
props: {
receiverOptions: {
type: Array
},
receiveTypeOptions: {
type: Array
}
},
data() {
@ -191,12 +194,6 @@ export default {
eventOptions: [
{value: 'CLOSE_SCHEDULE', label: '关闭定时任务'},
],
receiveTypeOptions: [
{value: 'EMAIL', label: this.$t('organization.message.mail')},
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
{value: 'LARK', label: this.$t('organization.message.lark')}
],
};
},
activated() {

View File

@ -160,6 +160,9 @@ export default {
props: {
receiverOptions: {
type: Array
},
receiveTypeOptions: {
type: Array
}
},
data() {
@ -191,12 +194,6 @@ export default {
eventOptions: [
{value: 'DELETE', label: this.$t('commons.delete')},
],
receiveTypeOptions: [
{value: 'EMAIL', label: this.$t('organization.message.mail')},
{value: 'NAIL_ROBOT', label: this.$t('organization.message.nail_robot')},
{value: 'WECHAT_ROBOT', label: this.$t('organization.message.enterprise_wechat_robot')},
{value: 'LARK', label: this.$t('organization.message.lark')}
],
};
},

View File

@ -386,6 +386,7 @@ export default {
defect_task_notification: '缺陷任务通知',
select_receiving_method: '选择接收方式',
mail: '邮件',
in_site: '站内通知',
nail_robot: '钉钉机器人',
enterprise_wechat_robot: '企业微信机器人',
lark: '飞书机器人',