fix(项目管理): 修复消息管理项目用户移除还会发送通知的问题

--bug=1036614 --user=郭雨琦 https://www.tapd.cn/55049933/bugtrace/bugs/view/1155049933001036614
This commit is contained in:
guoyuqi 2024-03-05 18:31:49 +08:00 committed by Craftsman
parent e810e8c8c7
commit 4f8ba53cf2
14 changed files with 107 additions and 59 deletions

View File

@ -15,6 +15,7 @@ import io.metersphere.system.domain.*;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.dto.sdk.request.MessageTaskRequest;
import io.metersphere.system.mapper.CustomFieldMapper;
import io.metersphere.system.mapper.ExtSystemProjectMapper;
import io.metersphere.system.mapper.UserMapper;
import io.metersphere.system.mapper.UserRoleRelationMapper;
import io.metersphere.system.notice.constants.NoticeConstants;
@ -57,6 +58,8 @@ public class NoticeMessageTaskService {
private ExtProjectUserRoleMapper extProjectUserRoleMapper;
@Resource
protected CustomFieldMapper customFieldMapper;
@Resource
private ExtSystemProjectMapper extSystemProjectMapper;
public static final String USER_IDS = "user_ids";
@ -336,9 +339,7 @@ public class NoticeMessageTaskService {
projectRobotExample.createCriteria().andIdIn(robotIds);
List<ProjectRobot> projectRobots = projectRobotMapper.selectByExample(projectRobotExample);
Map<String, ProjectRobot> robotMap = projectRobots.stream().collect(Collectors.toMap(ProjectRobot::getId, item -> item));
UserExample userExample = new UserExample();
userExample.createCriteria().andIdIn(userIds).andDeletedEqualTo(false);
List<User> users = userMapper.selectByExample(userExample);
List<User> users = extSystemProjectMapper.getProjectMemberByUserId(projectId, userIds);
Map<String, String> userNameMap = users.stream().collect(Collectors.toMap(User::getId, User::getName));
Map<String, String> defaultRelatedUserMap = MessageTemplateUtils.getDefaultRelatedUserMap();
userNameMap.putAll(defaultRelatedUserMap);
@ -383,10 +384,12 @@ public class NoticeMessageTaskService {
MessageTaskBlob messageTaskBlob = messageTaskBlobMap.get(messageTask.getId());
List<String> receiverIds = messageTask.getReceivers();
for (String receiverId : receiverIds) {
OptionDTO optionDTO = new OptionDTO();
optionDTO.setId(receiverId);
optionDTO.setName(userNameMap.get(receiverId));
receivers.add(optionDTO);
if (userNameMap.get(receiverId)!=null) {
OptionDTO optionDTO = new OptionDTO();
optionDTO.setId(receiverId);
optionDTO.setName(userNameMap.get(receiverId));
receivers.add(optionDTO);
}
}
String platform = robotMap.get(messageTask.getProjectRobotId()).getPlatform();
String defaultSubject;

View File

@ -1,5 +1,6 @@
package io.metersphere.system.mapper;
import io.metersphere.system.domain.User;
import io.metersphere.system.dto.OrganizationProjectOptionsDTO;
import io.metersphere.system.dto.ProjectDTO;
import io.metersphere.system.dto.ProjectResourcePoolDTO;
@ -31,4 +32,6 @@ public interface ExtSystemProjectMapper {
String selectModuleSettingsByResourceIdAndTable(@Param("resourceId") String resourceId, @Param("resourceTable") String resourceTable);
List<UserExtendDTO> getMemberByProjectId(@Param("projectId") String projectId, @Param("keyword") String keyword);
List<User> getProjectMemberByUserId(@Param("projectId") String projectId, @Param("userIds") List<String> userIds);
}

View File

@ -209,4 +209,19 @@
order by u.name
limit 100
</select>
<select id="getProjectMemberByUserId" resultType="io.metersphere.system.domain.User">
select distinct u.* from user_role_relation urr join `user` u on urr.user_id = u.id
where
u.deleted = 0 and u.enable = 1
<if test="projectId != null and projectId != ''">
and urr.source_id = #{projectId}
</if>
<if test="userIds != null and userIds.size > 0 ">
and u.id in
<foreach collection="userIds" item="userId" open="(" separator="," close=")">
#{userId}
</foreach>
</if>
</select>
</mapper>

View File

@ -21,5 +21,6 @@ public class MessageDetail implements Serializable {
private String template;
private String appKey;
private String appSecret;
private String projectId;
}

View File

@ -25,8 +25,7 @@ import io.metersphere.plan.mapper.TestPlanFollowerMapper;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.LogUtils;
import io.metersphere.system.domain.User;
import io.metersphere.system.domain.UserExample;
import io.metersphere.system.mapper.UserMapper;
import io.metersphere.system.mapper.ExtSystemProjectMapper;
import io.metersphere.system.notice.MessageDetail;
import io.metersphere.system.notice.NoticeModel;
import io.metersphere.system.notice.Receiver;
@ -59,7 +58,8 @@ public abstract class AbstractNoticeSender implements NoticeSender {
@Resource
private CaseReviewFollowerMapper caseReviewFollowerMapper;
@Resource
private UserMapper userMapper;
private ExtSystemProjectMapper extSystemProjectMapper;
protected String getContext(MessageDetail messageDetail, NoticeModel noticeModel) {
//处理自定义字段的值
@ -150,7 +150,7 @@ public abstract class AbstractNoticeSender implements NoticeSender {
// 去重复
List<String> userIds = toUsers.stream().map(Receiver::getUserId).distinct().toList();
LogUtils.info("userIds: ", JSON.toJSONString(userIds));
List<User> users = getUsers(userIds);
List<User> users = getUsers(userIds, messageDetail.getProjectId());
List<String> realUserIds = users.stream().map(User::getId).toList();
return toUsers.stream().filter(t -> realUserIds.contains(t.getUserId())).toList();
}
@ -217,7 +217,7 @@ public abstract class AbstractNoticeSender implements NoticeSender {
.map(t -> new Receiver(t.getUserId(), NotificationConstants.Type.SYSTEM_NOTICE.name()))
.collect(Collectors.toList());
}
case NoticeConstants.TaskType.BUG_TASK -> {
case NoticeConstants.TaskType.BUG_TASK -> {
BugFollowerExample bugFollowerExample = new BugFollowerExample();
bugFollowerExample.createCriteria().andBugIdEqualTo(id);
List<BugFollower> bugFollowers = bugFollowerMapper.selectByExample(bugFollowerExample);
@ -233,12 +233,25 @@ public abstract class AbstractNoticeSender implements NoticeSender {
return receivers;
}
protected List<User> getUsers(List<String> userIds) {
UserExample userExample = new UserExample();
protected List<User> getUsers(List<String> userIds, String projectId) {
if (CollectionUtils.isNotEmpty(userIds)) {
userExample.createCriteria().andIdIn(userIds);
return userMapper.selectByExample(userExample);
return extSystemProjectMapper.getProjectMemberByUserId(projectId, userIds);
} else {
return new ArrayList<>();
}
return new ArrayList<>();
}
protected List<Receiver> getReceivers(List<Receiver> receivers, Boolean excludeSelf, String operator) {
// 排除自己
List<Receiver> realReceivers = new ArrayList<>();
if (excludeSelf) {
for (Receiver receiver : receivers) {
if (!StringUtils.equals(receiver.getUserId(), operator)) {
LogUtils.info("发送人是自己不发");
realReceivers.add(receiver);
}
}
}
return realReceivers;
}
}

View File

@ -42,6 +42,8 @@ public class SendNoticeAspect {
private ThreadLocal<String> source = new ThreadLocal<>();
private final static String ID = "id";
private final static String PROJECT_ID = "projectId";
@Pointcut("@annotation(io.metersphere.system.notice.annotation.SendNotice)")
public void pointcut() {
@ -154,8 +156,15 @@ public class SendNoticeAspect {
LogUtils.info("event:" + event);
String resultStr = JSON.toJSONString(retValue);
Map object = JSON.parseMap(resultStr);
if (MapUtils.isNotEmpty(object) && object.containsKey(ID)) {
resources.add(object);
if (MapUtils.isNotEmpty(object)) {
for (Map resource : resources) {
if (object.containsKey(ID) && resource.get(ID) == null) {
resource.put(ID, object.get(ID));
}
if (object.containsKey(PROJECT_ID) && resource.get(PROJECT_ID) == null) {
resource.put(PROJECT_ID, object.get(PROJECT_ID));
}
}
}
afterReturningNoticeSendService.sendNotice(taskType, event, resources, sessionUser, currentProjectId);
} catch (Exception e) {

View File

@ -7,6 +7,7 @@ import io.metersphere.system.notice.NoticeModel;
import io.metersphere.system.notice.Receiver;
import io.metersphere.system.notice.sender.AbstractNoticeSender;
import io.metersphere.system.notice.utils.DingClient;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;
import java.util.List;
@ -16,15 +17,19 @@ import java.util.stream.Collectors;
public class DingCustomNoticeSender extends AbstractNoticeSender {
public void sendDingCustom(MessageDetail messageDetail, NoticeModel noticeModel, String context) {
List<String> userIds = noticeModel.getReceivers().stream()
List<Receiver> receivers = super.getReceivers(noticeModel.getReceivers(), noticeModel.isExcludeSelf(), noticeModel.getOperator());
if (CollectionUtils.isEmpty(receivers)) {
return;
}
List<String> userIds = receivers.stream()
.map(Receiver::getUserId)
.distinct()
.collect(Collectors.toList());
List<User> users = super.getUsers(userIds);
List<User> users = super.getUsers(userIds, messageDetail.getProjectId());
List<String> mobileList = users.stream().map(User::getPhone).toList();
LogUtils.info("钉钉自定义机器人收件人: {}", userIds);
DingClient.send(messageDetail.getWebhook(), messageDetail.getSubject()+": \n" + context, mobileList);
DingClient.send(messageDetail.getWebhook(), messageDetail.getSubject() + ": \n" + context, mobileList);
}
@Override

View File

@ -17,7 +17,7 @@ import org.springframework.stereotype.Component;
@Component
public class DingEnterPriseNoticeSender extends AbstractNoticeSender {
public void sendDing(MessageDetail messageDetail, NoticeModel noticeModel, String context) throws Exception {
public void sendDing(MessageDetail messageDetail, String context) throws Exception {
Client client = DingEnterPriseNoticeSender.createClient();
GetAccessTokenResponse accessToken = getAccessToken(messageDetail.getAppKey(), messageDetail.getAppSecret());
OrgGroupSendHeaders orgGroupSendHeaders = new OrgGroupSendHeaders();
@ -92,7 +92,7 @@ public class DingEnterPriseNoticeSender extends AbstractNoticeSender {
public void send(MessageDetail messageDetail, NoticeModel noticeModel) {
String context = super.getContext(messageDetail, noticeModel);
try {
sendDing(messageDetail, noticeModel, context);
sendDing(messageDetail, context);
LogUtils.debug("发送钉钉内部机器人结束");
} catch (Exception e) {
LogUtils.error(e);

View File

@ -11,10 +11,8 @@ import io.metersphere.system.notice.sender.AbstractNoticeSender;
import io.metersphere.system.service.NotificationService;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -25,25 +23,12 @@ public class InSiteNoticeSender extends AbstractNoticeSender {
private NotificationService notificationService;
public void sendAnnouncement(MessageDetail messageDetail, NoticeModel noticeModel, String context) {
List<Receiver> receivers = noticeModel.getReceivers();
// 排除自己
List<Receiver> realReceivers = new ArrayList<>();
if (noticeModel.isExcludeSelf() ) {
for (Receiver receiver : receivers) {
if (!StringUtils.equals(receiver.getUserId(), noticeModel.getOperator())) {
LogUtils.info("发送人是自己不发");
realReceivers.add(receiver);
}
}
}
if (CollectionUtils.isEmpty(realReceivers)) {
List<Receiver> receivers = super.getReceivers(noticeModel.getReceivers(), noticeModel.isExcludeSelf(), noticeModel.getOperator());
if (CollectionUtils.isEmpty(receivers)) {
return;
}
LogUtils.info("发送站内通知: {}", realReceivers);
realReceivers.forEach(receiver -> {
LogUtils.info("发送站内通知: {}", receivers);
receivers.forEach(receiver -> {
Map<String, Object> paramMap = noticeModel.getParamMap();
Notification notification = new Notification();
notification.setSubject(noticeModel.getSubject());

View File

@ -7,6 +7,7 @@ import io.metersphere.system.notice.sender.AbstractNoticeSender;
import io.metersphere.system.notice.utils.LarkClient;
import io.metersphere.sdk.util.LogUtils;
import io.metersphere.system.domain.User;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
@ -17,18 +18,23 @@ import java.util.stream.Collectors;
public class LarkNoticeSender extends AbstractNoticeSender {
public void sendLark(MessageDetail messageDetail, NoticeModel noticeModel, String context) {
List<String> userIds = noticeModel.getReceivers().stream()
List<Receiver> receivers = super.getReceivers(noticeModel.getReceivers(), noticeModel.isExcludeSelf(), noticeModel.getOperator());
if (CollectionUtils.isEmpty(receivers)) {
return;
}
List<String> userIds = receivers.stream()
.map(Receiver::getUserId)
.distinct()
.collect(Collectors.toList());
List<User> users = super.getUsers(userIds);
List<User> users = super.getUsers(userIds, messageDetail.getProjectId());
List<String> collect = users.stream()
.map(ud -> "<at email=\"" + ud.getEmail() + "\">" + ud.getName() + "</at>")
.toList();
LogUtils.info("飞书收件人: {}", userIds);
context += StringUtils.join(collect, StringUtils.SPACE);
LarkClient.send(messageDetail.getWebhook(), messageDetail.getSubject()+": \n" + context);
LarkClient.send(messageDetail.getWebhook(), messageDetail.getSubject() + ": \n" + context);
}
@Override

View File

@ -33,17 +33,16 @@ public class MailNoticeSender extends AbstractNoticeSender {
@Resource
private SystemParameterMapper systemParameterMapper;
public void sendMail(String context, NoticeModel noticeModel) throws Exception {
List<String> userIds = noticeModel.getReceivers().stream()
public void sendMail(String context, NoticeModel noticeModel, String projectId) throws Exception {
List<Receiver> receivers = super.getReceivers(noticeModel.getReceivers(), noticeModel.isExcludeSelf(), noticeModel.getOperator());
if (CollectionUtils.isEmpty(receivers)) {
return;
}
List<String> userIds = receivers.stream()
.map(Receiver::getUserId)
.distinct()
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(userIds)) {
return;
}
String[] users = super.getUsers(userIds).stream()
String[] users = super.getUsers(userIds, projectId).stream()
.map(User::getEmail)
.distinct()
.toArray(String[]::new);
@ -156,7 +155,7 @@ public class MailNoticeSender extends AbstractNoticeSender {
public void send(MessageDetail messageDetail, NoticeModel noticeModel) {
String context = super.getContext(messageDetail, noticeModel);
try {
sendMail(context, noticeModel);
sendMail(context, noticeModel, messageDetail.getProjectId());
LogUtils.debug("发送邮件结束");
} catch (Exception e) {
LogUtils.error(e);

View File

@ -7,6 +7,7 @@ import io.metersphere.system.notice.NoticeModel;
import io.metersphere.system.notice.Receiver;
import io.metersphere.system.notice.sender.AbstractNoticeSender;
import io.metersphere.system.notice.utils.WeComClient;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import java.util.List;
@ -16,14 +17,18 @@ import java.util.stream.Collectors;
public class WeComNoticeSender extends AbstractNoticeSender {
public void sendWeCom(MessageDetail messageDetail, NoticeModel noticeModel, String context) {
List<String> userIds = noticeModel.getReceivers().stream()
List<Receiver> receivers = super.getReceivers(noticeModel.getReceivers(), noticeModel.isExcludeSelf(), noticeModel.getOperator());
if (CollectionUtils.isEmpty(receivers)) {
return;
}
List<String> userIds = receivers.stream()
.map(Receiver::getUserId)
.distinct()
.collect(Collectors.toList());
List<User> users = super.getUsers(userIds);
List<User> users = super.getUsers(userIds, messageDetail.getProjectId());
List<String> mobileList = users.stream().map(User::getPhone).toList();
LogUtils.info("企业微信收件人: {}", userIds);
WeComClient.send(messageDetail.getWebhook(), messageDetail.getSubject()+": \n" + context, mobileList);
WeComClient.send(messageDetail.getWebhook(), messageDetail.getSubject() + ": \n" + context, mobileList);
}
@Override

View File

@ -25,7 +25,10 @@ public class WebhookNoticeSender extends AbstractNoticeSender {
private void send(MessageDetail messageDetail, NoticeModel noticeModel, String context) {
List<Receiver> receivers = noticeModel.getReceivers();
List<Receiver> receivers = super.getReceivers(noticeModel.getReceivers(), noticeModel.isExcludeSelf(), noticeModel.getOperator());
if (CollectionUtils.isEmpty(receivers)) {
return;
}
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
if (CollectionUtils.isNotEmpty(receivers)) {

View File

@ -89,6 +89,7 @@ public class MessageDetailService {
messageDetail.setTaskType(messageTask.getTaskType());
messageDetail.setEvent(messageTask.getEvent());
messageDetail.setCreateTime(messageTask.getCreateTime());
messageDetail.setProjectId(messageTask.getProjectId());
String projectRobotId = messageTask.getProjectRobotId();
ProjectRobot projectRobot = projectRobotMap.get(projectRobotId);
//如果当前机器人停止那么当前任务也失效