feat(REQ-1465): 消息双发功能实现
背景: https://jira.axzo.cn/browse/REQ-1465?goToView=1 修改: 1、消息双发功能实现 影响: 无
This commit is contained in:
parent
9ea4d94135
commit
19812ec3d3
@ -28,6 +28,7 @@ import cn.axzo.msg.center.domain.enums.*;
|
||||
import cn.axzo.msg.center.domain.request.InsideCmsReadMsgReq;
|
||||
import cn.axzo.msg.center.inside.notices.event.SendMessageEvent;
|
||||
import cn.axzo.msg.center.inside.notices.service.MessageRecordService;
|
||||
import cn.axzo.msg.center.message.service.GeneralMessageMapperService;
|
||||
import cn.azxo.framework.common.utils.LogUtil;
|
||||
import cn.azxo.framework.common.utils.LogUtil.ErrorLevel;
|
||||
import cn.azxo.framework.common.utils.LogUtil.ErrorType;
|
||||
@ -37,6 +38,7 @@ import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.text.StrSubstitutor;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -84,6 +86,9 @@ public class MessageRecordServiceImpl implements MessageRecordService {
|
||||
/*@Resource
|
||||
private IdentityProfileService identityProfileService;*/
|
||||
|
||||
@Resource
|
||||
private GeneralMessageMapperService generalMessageMapperService;
|
||||
|
||||
/**
|
||||
* 新增推送消息接口
|
||||
*
|
||||
@ -132,10 +137,11 @@ public class MessageRecordServiceImpl implements MessageRecordService {
|
||||
|
||||
List<MessageRecord> pushMessages = new ArrayList<>();
|
||||
Lists.partition(Lists.newArrayList(message.getToId()), partitionSize).forEach(toIds -> {
|
||||
List<MessageRecord> messageRecords = saveBatch(basic, toIds, message.getToldIdPersonIdMap());
|
||||
Map<Long, MessageRecord> toIdRecordMap = Maps.newHashMap();
|
||||
List<MessageRecord> messageRecords = saveBatch(basic, toIds, message.getToldIdPersonIdMap(), toIdRecordMap);
|
||||
generalMessageMapperService.asyncBatchSendMessage(message, toIds, toIdRecordMap);
|
||||
pushMessages.addAll(messageRecords);
|
||||
});
|
||||
|
||||
if(pushAthena) {
|
||||
asyncPushAthena(message, messageTemplate.getAudioFileName(), messageModule.getModuleName(), pushMessages);
|
||||
}
|
||||
@ -158,7 +164,8 @@ public class MessageRecordServiceImpl implements MessageRecordService {
|
||||
|
||||
|
||||
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
||||
public List<MessageRecord> saveBatch(MessageRecord basic, List<Long> toIds, Map<Long, Long> toldIdPersonIdMap) {
|
||||
public List<MessageRecord> saveBatch(MessageRecord basic, List<Long> toIds, Map<Long, Long> toldIdPersonIdMap,
|
||||
Map<Long, MessageRecord> toIdRecordMap) {
|
||||
if (CollectionUtils.isEmpty(toIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@ -172,6 +179,7 @@ public class MessageRecordServiceImpl implements MessageRecordService {
|
||||
messageRecord.setToId(0L);
|
||||
messageRecord.setPersonId(i);
|
||||
pushMessages.add(messageRecord);
|
||||
toIdRecordMap.put(i, messageRecord);
|
||||
});
|
||||
} else {
|
||||
toIds.forEach(i -> {
|
||||
@ -183,6 +191,7 @@ public class MessageRecordServiceImpl implements MessageRecordService {
|
||||
messageRecord.setPersonId(toldIdPersonIdMap.get(i));
|
||||
}
|
||||
pushMessages.add(messageRecord);
|
||||
toIdRecordMap.put(i, messageRecord);
|
||||
});
|
||||
}
|
||||
messageRecordDao.saveBatch(pushMessages);
|
||||
|
||||
@ -44,11 +44,9 @@ import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @description xxx
|
||||
* @author cold_blade
|
||||
* @date 2023/9/13
|
||||
* @version 1.0
|
||||
* TODO: [cold_blade]待优化
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
|
||||
@ -22,6 +22,6 @@ public class GeneralMessageController implements GeneralMessageClient {
|
||||
|
||||
@Override
|
||||
public CommonResponse<String> sendMessage(GeneralMessageSendRequest request) {
|
||||
return CommonResponse.success(generalMessageService.sendMessage(request));
|
||||
return CommonResponse.success(generalMessageService.batchSendMessage(request));
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
package cn.axzo.msg.center.message.service;
|
||||
|
||||
import cn.axzo.msg.center.api.request.GeneralMessageReq;
|
||||
import cn.axzo.msg.center.domain.entity.MessageRecord;
|
||||
import cn.axzo.msg.center.service.dto.PersonDTO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 新老版本消息映射的相关接口
|
||||
*
|
||||
* @author cold_blade
|
||||
* @date 2023/10/23
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface GeneralMessageMapperService {
|
||||
|
||||
/**
|
||||
* 异步批量发送消息
|
||||
*
|
||||
* @param request 发送消息时的请求参数
|
||||
* @param subReceiverIds 接收者id列表
|
||||
* @param toIdMessageRecordMap 接收者身份id与旧消息记录的映射关系
|
||||
* @return 批量发送消息请求的requestId
|
||||
*/
|
||||
String asyncBatchSendMessage(GeneralMessageReq request, List<Long> subReceiverIds,
|
||||
Map<Long, MessageRecord> toIdMessageRecordMap);
|
||||
}
|
||||
@ -13,7 +13,7 @@ public interface GeneralMessageService {
|
||||
* 发送消息
|
||||
*
|
||||
* @param request 消息所需参数
|
||||
* @return 消息的唯一标识
|
||||
* @return 请求的唯一标识
|
||||
*/
|
||||
String sendMessage(GeneralMessageSendRequest request);
|
||||
String batchSendMessage(GeneralMessageSendRequest request);
|
||||
}
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
package cn.axzo.msg.center.message.service;
|
||||
|
||||
import cn.axzo.msg.center.api.request.GeneralMessageReq;
|
||||
import cn.axzo.msg.center.service.dto.PersonDTO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 双发消息记录service
|
||||
*
|
||||
* @author cold_blade
|
||||
* @date 2023/10/23
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface MessageSendTwiceRecordService {
|
||||
|
||||
List<Long> listByPerson(Long personId);
|
||||
|
||||
void batchSave(Map<Long, Long> msgRecordIdPersonIdMap);
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package cn.axzo.msg.center.message.service;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 新老模板的关联关系service
|
||||
*
|
||||
* @author cold_blade
|
||||
* @date 2023/10/23
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface RelationTemplateMapService {
|
||||
|
||||
Optional<String> queryByRelationId(Long relationId);
|
||||
|
||||
void mapRelationAndTemplate(Map<Long, String> map);
|
||||
}
|
||||
@ -0,0 +1,123 @@
|
||||
package cn.axzo.msg.center.message.service.impl;
|
||||
|
||||
import cn.axzo.msg.center.api.enums.MsgTypeEnum;
|
||||
import cn.axzo.msg.center.api.request.GeneralMessageReq;
|
||||
import cn.axzo.msg.center.domain.entity.MessageRecord;
|
||||
import cn.axzo.msg.center.message.service.GeneralMessageMapperService;
|
||||
import cn.axzo.msg.center.message.service.GeneralMessageService;
|
||||
import cn.axzo.msg.center.message.service.MessageSendTwiceRecordService;
|
||||
import cn.axzo.msg.center.message.service.RelationTemplateMapService;
|
||||
import cn.axzo.msg.center.service.dto.PersonDTO;
|
||||
import cn.axzo.msg.center.service.enums.IdentityTypeEnum;
|
||||
import cn.axzo.msg.center.service.enums.OrganizationTypeEnum;
|
||||
import cn.axzo.msg.center.service.general.request.GeneralMessageSendRequest;
|
||||
import cn.axzo.msg.center.utils.PersonIdentityUtil;
|
||||
import cn.axzo.msg.center.utils.UUIDUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import jodd.util.concurrent.ThreadFactoryBuilder;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author cold_blade
|
||||
* @date 2023/10/23
|
||||
* @version 1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class GeneralMessageMapperServiceImpl implements GeneralMessageMapperService {
|
||||
|
||||
private final ThreadFactory asyncSendMsgThreadFactory = ThreadFactoryBuilder.create()
|
||||
.setDaemon(true).setNameFormat("ASYNC_SEND_IM_MESSAGE_%d").get();
|
||||
private final ExecutorService asyncSendMsgExecutorService = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS,
|
||||
new ArrayBlockingQueue<>(1024), asyncSendMsgThreadFactory);
|
||||
|
||||
private final GeneralMessageService generalMessageService;
|
||||
private final RelationTemplateMapService relationTemplateMapService;
|
||||
private final MessageSendTwiceRecordService messageSendTwiceRecordService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String asyncBatchSendMessage(GeneralMessageReq request, List<Long> subReceiverIds,
|
||||
Map<Long, MessageRecord> toIdMessageRecordMap) {
|
||||
if (MsgTypeEnum.PENDING_MESSAGE.equals(request.getType())) {
|
||||
log.info("pending message is not supported.");
|
||||
return UUIDUtil.uuidRawString();
|
||||
}
|
||||
if (Objects.isNull(request.getRelationId()) || MapUtil.isEmpty(request.getToldIdPersonIdMap())) {
|
||||
log.info("param is invalid. relationId:[{}], toIdPersonIdMap:{}", request.getRelationId(),
|
||||
request.getToldIdPersonIdMap());
|
||||
return UUIDUtil.uuidRawString();
|
||||
}
|
||||
Optional<IdentityTypeEnum> identityTypeOp = PersonIdentityUtil.toIdentityType(request.getReceiveType());
|
||||
if (!identityTypeOp.isPresent()) {
|
||||
log.info("identity is invalid. relationId:[{}], receiveType:{}", request.getRelationId(),
|
||||
request.getReceiveType());
|
||||
return UUIDUtil.uuidRawString();
|
||||
}
|
||||
// 异步发送IM消息
|
||||
CompletableFuture.runAsync(() -> doBatchSendMessage(request, subReceiverIds, toIdMessageRecordMap,
|
||||
identityTypeOp.get()), asyncSendMsgExecutorService);
|
||||
return UUIDUtil.uuidRawString();
|
||||
}
|
||||
|
||||
private void doBatchSendMessage(GeneralMessageReq request, List<Long> subReceiverIds,
|
||||
Map<Long, MessageRecord> toIdMessageRecordMap, IdentityTypeEnum identityType) {
|
||||
String templateCode = relationTemplateMapService.queryByRelationId(request.getRelationId()).orElse(null);
|
||||
if (StringUtils.isBlank(templateCode)) {
|
||||
log.info("the relationId([{}]) is not map any new message template. ", request.getRelationId());
|
||||
return;
|
||||
}
|
||||
log.info("start to send im message. relationId:[{}]", request.getRelationId());
|
||||
Map<Long, Long> msgRecordIdPersonIdMap = toIdMessageRecordMap.entrySet().stream()
|
||||
.filter(e -> request.getToldIdPersonIdMap().containsKey(e.getKey()))
|
||||
.collect(Collectors.toMap(e -> e.getValue().getId(), e -> request.getToldIdPersonIdMap().get(e.getKey())));
|
||||
log.info("message send twice. relationId:[{}], msgIds:{}", request.getRelationId(), msgRecordIdPersonIdMap.values());
|
||||
// 双发记录
|
||||
messageSendTwiceRecordService.batchSave(msgRecordIdPersonIdMap);
|
||||
// 发送IM消息
|
||||
generalMessageService.batchSendMessage(convert(request, templateCode, subReceiverIds, identityType));
|
||||
}
|
||||
|
||||
private GeneralMessageSendRequest convert(GeneralMessageReq request, String templateCode,
|
||||
List<Long> subReceiverIds, IdentityTypeEnum identityType) {
|
||||
List<PersonDTO> receivers = subReceiverIds.stream()
|
||||
.filter(request.getToldIdPersonIdMap()::containsKey)
|
||||
.map(e -> PersonDTO.from(request.getToldIdPersonIdMap().get(e), e, identityType))
|
||||
.collect(Collectors.toList());
|
||||
OrganizationTypeEnum orgType = Objects.isNull(request.getTerminalType()) ? OrganizationTypeEnum.UNKNOWN :
|
||||
OrganizationTypeEnum.valueOf(request.getTerminalType().name());
|
||||
return GeneralMessageSendRequest.builder()
|
||||
.templateCode(templateCode)
|
||||
.receiver(receivers)
|
||||
.orgType(orgType)
|
||||
.orgName(request.getTerminalName())
|
||||
.orgId(request.getTerminalId())
|
||||
.bizCode(Optional.ofNullable(request.getBizId()).map(String::valueOf).orElse(""))
|
||||
.routerParams(Optional.ofNullable(request.getRouterParams())
|
||||
.map(v -> JSONObject.parseObject(JSON.toJSONString(v)))
|
||||
.orElseGet(JSONObject::new))
|
||||
.bizExtParams(Optional.ofNullable(request.getMsgParams())
|
||||
.map(v -> JSONObject.parseObject(JSON.toJSONString(v)))
|
||||
.orElseGet(JSONObject::new))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@ package cn.axzo.msg.center.message.service.impl;
|
||||
|
||||
import cn.axzo.im.center.api.feign.MessageApi;
|
||||
import cn.axzo.im.center.api.vo.req.MessageInfo;
|
||||
import cn.axzo.im.center.common.enums.AppTypeEnum;
|
||||
import cn.axzo.msg.center.common.exception.ServiceException;
|
||||
import cn.axzo.msg.center.common.utils.PlaceholderResolver;
|
||||
import cn.axzo.msg.center.dal.GeneralMessageRecordDao;
|
||||
@ -13,6 +14,7 @@ import cn.axzo.msg.center.message.service.GeneralMessageService;
|
||||
import cn.axzo.msg.center.message.service.MessageTemplateNewService;
|
||||
import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO;
|
||||
import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO;
|
||||
import cn.axzo.msg.center.service.dto.PersonDTO;
|
||||
import cn.axzo.msg.center.service.enums.GeneralMessageStateEnum;
|
||||
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
|
||||
import cn.axzo.msg.center.service.general.request.GeneralMessageSendRequest;
|
||||
@ -20,6 +22,7 @@ import cn.axzo.msg.center.utils.MessageRouterUtil;
|
||||
import cn.axzo.msg.center.utils.UUIDUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -42,6 +45,11 @@ import java.util.stream.Collectors;
|
||||
@RequiredArgsConstructor
|
||||
public class GeneralMessageServiceImpl implements GeneralMessageService {
|
||||
|
||||
private static final ImmutableMap<PushTerminalEnum, AppTypeEnum> PUSH_TERMINAL_APP_MAP = ImmutableMap.of(
|
||||
PushTerminalEnum.B_ENTERPRISE_APP, AppTypeEnum.CMP,
|
||||
PushTerminalEnum.C_WORKER_APP, AppTypeEnum.CM
|
||||
);
|
||||
|
||||
// TODO:[cold_blade] [P2] 图片icon的最好配置在nacos上
|
||||
private final String orgIcon = "https://axzo-pro.oss-cn-hangzhou.aliyuncs.com/rs_app/ic_org_icon.png";
|
||||
|
||||
@ -50,27 +58,34 @@ public class GeneralMessageServiceImpl implements GeneralMessageService {
|
||||
private final GeneralMessageRecordDao generalMessageRecordDao;
|
||||
|
||||
@Override
|
||||
public String sendMessage(GeneralMessageSendRequest request) {
|
||||
public String batchSendMessage(GeneralMessageSendRequest request) {
|
||||
// 查询模板基础信息
|
||||
MessageTemplateDTO template = messageTemplateNewService.queryByTemplateCode(request.getTemplateCode())
|
||||
.orElseThrow(() -> new ServiceException("未查询到对应的模板"));
|
||||
// 构建消息记录并存储
|
||||
GeneralMessageRecord messageRecord = buildMessageRecord(request, template);
|
||||
generalMessageRecordDao.save(messageRecord);
|
||||
List<GeneralMessageRecord> messageRecords = buildMessageRecord(request, template);
|
||||
generalMessageRecordDao.saveBatch(messageRecords);
|
||||
// 异步推送
|
||||
pushMessage(messageRecord, template);
|
||||
return messageRecord.getIdentityCode();
|
||||
pushMessage(messageRecords, template);
|
||||
return UUIDUtil.uuidRawString();
|
||||
}
|
||||
|
||||
private GeneralMessageRecord buildMessageRecord(GeneralMessageSendRequest request, MessageTemplateDTO template) {
|
||||
private List<GeneralMessageRecord> buildMessageRecord(GeneralMessageSendRequest request, MessageTemplateDTO template) {
|
||||
return request.getReceiver().stream()
|
||||
.map(e -> buildMessageRecord(request, e, template))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private GeneralMessageRecord buildMessageRecord(GeneralMessageSendRequest request, PersonDTO receiver,
|
||||
MessageTemplateDTO template) {
|
||||
return GeneralMessageRecord.builder()
|
||||
.identityCode(UUIDUtil.uuidString())
|
||||
.senderPersonId(request.getSenderPersonId())
|
||||
.senderId(request.getSenderIdentity().getId())
|
||||
.senderType(request.getSenderIdentity().getType())
|
||||
.receiverPersonId(request.getReceiverPersonId())
|
||||
.receiverId(request.getReceiverIdentity().getId())
|
||||
.receiverType(request.getReceiverIdentity().getType())
|
||||
.senderPersonId(request.getSender().getId())
|
||||
.senderId(request.getSender().getIdentity().getId())
|
||||
.senderType(request.getSender().getIdentity().getType())
|
||||
.receiverPersonId(receiver.getId())
|
||||
.receiverId(receiver.getIdentity().getId())
|
||||
.receiverType(receiver.getIdentity().getType())
|
||||
.templateCode(template.getCode())
|
||||
.title(parseString(template.getTitle(), request.getBizExtParams()))
|
||||
.content(parseString(template.getContent(), request.getBizExtParams()))
|
||||
@ -84,18 +99,21 @@ public class GeneralMessageServiceImpl implements GeneralMessageService {
|
||||
.build();
|
||||
}
|
||||
|
||||
private void pushMessage(GeneralMessageRecord record, MessageTemplateDTO template) {
|
||||
private void pushMessage(List<GeneralMessageRecord> messageRecords, MessageTemplateDTO template) {
|
||||
if (CollectionUtils.isEmpty(template.getPushTerminals())) {
|
||||
// 模板未配置任何推送终端
|
||||
return;
|
||||
}
|
||||
List<String> appTypes = template.getPushTerminals().stream()
|
||||
.map(PushTerminalEnum::getImTerminalFlag).collect(Collectors.toList());
|
||||
GeneralMessageRecord record = messageRecords.get(0);
|
||||
List<AppTypeEnum> appTypes = template.getPushTerminals().stream()
|
||||
.map(PUSH_TERMINAL_APP_MAP::get).collect(Collectors.toList());
|
||||
GeneralMessagePushVO message = convert(record, template);
|
||||
MessageInfo msgInfo = new MessageInfo();
|
||||
msgInfo.setAppTypeList(appTypes);
|
||||
// TODO: [cold_blade] [P2] 第一期只支持发送机器人相关的消息
|
||||
msgInfo.setToPersonIdList(Lists.newArrayList(String.valueOf(record.getReceiverPersonId())));
|
||||
msgInfo.setToPersonIdList(Lists.newArrayList(messageRecords.stream()
|
||||
.map(e -> String.valueOf(e.getReceiverPersonId()))
|
||||
.collect(Collectors.toSet())));
|
||||
msgInfo.setMsgHeader(record.getTitle());
|
||||
msgInfo.setMsgContent(record.getContent());
|
||||
msgInfo.setMsgTemplateId(record.getTemplateCode());
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
package cn.axzo.msg.center.message.service.impl;
|
||||
|
||||
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
|
||||
import cn.axzo.msg.center.dal.MessageSendTwiceRecordDao;
|
||||
import cn.axzo.msg.center.domain.entity.MessageSendTwiceRecord;
|
||||
import cn.axzo.msg.center.message.service.MessageSendTwiceRecordService;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @description xxx
|
||||
* @author cold_blade
|
||||
* @date 2023/10/23
|
||||
* @version 1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class MessageSendTwiceRecordServiceImpl implements MessageSendTwiceRecordService {
|
||||
|
||||
private final MessageSendTwiceRecordDao messageSendTwiceRecordDao;
|
||||
|
||||
@Override
|
||||
public List<Long> listByPerson(Long personId) {
|
||||
if (Objects.isNull(personId)) {
|
||||
log.info("personId is null.");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// TODO:[cold_blade] [P2] 此处的代码仅做一个双发兜底的策略,后期应当全走新的消息发送流程
|
||||
return messageSendTwiceRecordDao.lambdaQuery()
|
||||
.eq(MessageSendTwiceRecord::getReceiverPersonId, personId)
|
||||
.eq(MessageSendTwiceRecord::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||
.select(MessageSendTwiceRecord::getOriginalMsgId)
|
||||
.list().stream()
|
||||
.map(MessageSendTwiceRecord::getOriginalMsgId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void batchSave(Map<Long, Long> msgRecordIdPersonIdMap) {
|
||||
if (MapUtil.isEmpty(msgRecordIdPersonIdMap)) {
|
||||
return;
|
||||
}
|
||||
List<MessageSendTwiceRecord> records = msgRecordIdPersonIdMap.entrySet().stream()
|
||||
.map(e -> {
|
||||
MessageSendTwiceRecord record = new MessageSendTwiceRecord();
|
||||
record.setReceiverPersonId(e.getValue());
|
||||
record.setOriginalMsgId(e.getKey());
|
||||
return record;
|
||||
}).collect(Collectors.toList());
|
||||
messageSendTwiceRecordDao.saveBatch(records);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
package cn.axzo.msg.center.message.service.impl;
|
||||
|
||||
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
|
||||
import cn.axzo.msg.center.dal.RelationTemplateMapDao;
|
||||
import cn.axzo.msg.center.domain.entity.RelationTemplateMap;
|
||||
import cn.axzo.msg.center.message.service.RelationTemplateMapService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 新老模板映射关系service
|
||||
*
|
||||
* @author cold_blade
|
||||
* @date 2023/10/23
|
||||
* @version 1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class RelationTemplateMapServiceImpl implements RelationTemplateMapService {
|
||||
|
||||
private final RelationTemplateMapDao relationTemplateMapDao;
|
||||
|
||||
@Override
|
||||
public Optional<String> queryByRelationId(Long relationId) {
|
||||
if (Objects.isNull(relationId)) {
|
||||
log.info("relationId is null");
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.ofNullable(relationTemplateMapDao.lambdaQuery()
|
||||
.eq(RelationTemplateMap::getOriginalRelationId, relationId)
|
||||
.eq(RelationTemplateMap::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||
.one()
|
||||
).map(RelationTemplateMap::getTemplateCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void mapRelationAndTemplate(Map<Long, String> map) {
|
||||
if (Objects.isNull(map) || map.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
relationTemplateMapDao.lambdaUpdate()
|
||||
.in(RelationTemplateMap::getOriginalRelationId, map.keySet())
|
||||
.eq(RelationTemplateMap::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||
.remove();
|
||||
List<RelationTemplateMap> rows = map.entrySet().stream()
|
||||
.map(e -> {
|
||||
RelationTemplateMap row = new RelationTemplateMap();
|
||||
row.setOriginalRelationId(e.getKey());
|
||||
row.setTemplateCode(e.getValue());
|
||||
return row;
|
||||
}).collect(Collectors.toList());
|
||||
relationTemplateMapDao.saveBatch(rows);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package cn.axzo.msg.center.utils;
|
||||
|
||||
import cn.axzo.msg.center.api.enums.ReceiveTypeEnum;
|
||||
import cn.axzo.msg.center.service.enums.IdentityTypeEnum;
|
||||
import cn.axzo.pudge.core.service.ServiceException;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @description xxx
|
||||
* @author cold_blade
|
||||
* @date 2023/10/23
|
||||
* @version 1.0
|
||||
*/
|
||||
public class PersonIdentityUtil {
|
||||
|
||||
public static ReceiveTypeEnum receiveType(Integer identityTypeCode) {
|
||||
IdentityTypeEnum identityType = IdentityTypeEnum.codeOf(identityTypeCode)
|
||||
.orElseThrow(() -> new ServiceException("档案身份类型不匹配 code:" + identityTypeCode));
|
||||
switch (identityType) {
|
||||
case WORKER:
|
||||
return ReceiveTypeEnum.CM_WORKER;
|
||||
case WORKER_LEADER:
|
||||
return ReceiveTypeEnum.CM_LEADER;
|
||||
case PRACTITIONER:
|
||||
return ReceiveTypeEnum.CMP_USER;
|
||||
default:
|
||||
return ReceiveTypeEnum.NOT_IDENTITY;
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<IdentityTypeEnum> toIdentityType(ReceiveTypeEnum receiveType) {
|
||||
if (Objects.isNull(receiveType)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
switch (receiveType) {
|
||||
case CM_WORKER:
|
||||
return Optional.of(IdentityTypeEnum.WORKER);
|
||||
case CM_LEADER:
|
||||
return Optional.of(IdentityTypeEnum.WORKER_LEADER);
|
||||
case CMP_USER:
|
||||
return Optional.of(IdentityTypeEnum.PRACTITIONER);
|
||||
default:
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -18,13 +18,12 @@ public enum PushTerminalEnum {
|
||||
/**
|
||||
* B-安心筑企业版
|
||||
*/
|
||||
B_ENTERPRISE_APP("B-安心筑企业版", "CMP"),
|
||||
B_ENTERPRISE_APP("B-安心筑企业版"),
|
||||
/**
|
||||
* C-安心筑工人版
|
||||
*/
|
||||
C_WORKER_APP("C-安心筑工人版", "CM"),
|
||||
C_WORKER_APP("C-安心筑工人版"),
|
||||
;
|
||||
|
||||
private final String desc;
|
||||
private final String imTerminalFlag;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package cn.axzo.msg.center.service.general.request;
|
||||
|
||||
import cn.axzo.msg.center.service.dto.IdentityDTO;
|
||||
import cn.axzo.msg.center.service.dto.PersonDTO;
|
||||
import cn.axzo.msg.center.service.enums.OrganizationTypeEnum;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
@ -11,8 +11,9 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @description
|
||||
@ -36,25 +37,14 @@ public class GeneralMessageSendRequest implements Serializable {
|
||||
@NotBlank(message = "templateCode is required")
|
||||
private String templateCode;
|
||||
/**
|
||||
* 消息发送者自然人id
|
||||
* 消息发送者信息,可为空,默认模板对应的IM机器人
|
||||
*/
|
||||
@NotNull(message = "senderPersonId is required")
|
||||
private Long senderPersonId;
|
||||
private PersonDTO sender;
|
||||
/**
|
||||
* 消息发送者身份
|
||||
* 消息接收信息
|
||||
*/
|
||||
@NotNull(message = "senderIdentity is required")
|
||||
private IdentityDTO senderIdentity;
|
||||
/**
|
||||
* 消息接收者自然人id
|
||||
*/
|
||||
@NotNull(message = "receiverPersonId is required")
|
||||
private Long receiverPersonId;
|
||||
/**
|
||||
* 消息接收者身份
|
||||
*/
|
||||
@NotNull(message = "receiverIdentity is required")
|
||||
private IdentityDTO receiverIdentity;
|
||||
@NotEmpty(message = "receiver is required")
|
||||
private Collection<PersonDTO> receiver;
|
||||
/**
|
||||
* 消息所属组织类型
|
||||
*/
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package cn.axzo.msg.center.dal;
|
||||
|
||||
import cn.axzo.msg.center.dal.mapper.MessageSendTwiceRecordMapper;
|
||||
import cn.axzo.msg.center.domain.entity.MessageSendTwiceRecord;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @description
|
||||
* @author cold_blade
|
||||
* @date 2023/10/21
|
||||
* @version 1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class MessageSendTwiceRecordDao extends ServiceImpl<MessageSendTwiceRecordMapper, MessageSendTwiceRecord> {
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package cn.axzo.msg.center.dal;
|
||||
|
||||
import cn.axzo.msg.center.dal.mapper.RelationTemplateMapMapper;
|
||||
import cn.axzo.msg.center.domain.entity.RelationTemplateMap;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @description
|
||||
* @author cold_blade
|
||||
* @date 2023/10/21
|
||||
* @version 1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class RelationTemplateMapDao extends ServiceImpl<RelationTemplateMapMapper, RelationTemplateMap> {
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package cn.axzo.msg.center.dal.mapper;
|
||||
|
||||
import cn.axzo.msg.center.domain.entity.MessageSendTwiceRecord;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @author cold_blade
|
||||
* @date 2023/10/21
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface MessageSendTwiceRecordMapper extends BaseMapper<MessageSendTwiceRecord> {
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package cn.axzo.msg.center.dal.mapper;
|
||||
|
||||
import cn.axzo.msg.center.domain.entity.RelationTemplateMap;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @author cold_blade
|
||||
* @date 2023/10/21
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface RelationTemplateMapMapper extends BaseMapper<RelationTemplateMap> {
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package cn.axzo.msg.center.domain.entity;
|
||||
|
||||
import cn.axzo.msg.center.domain.persistence.BaseEntity;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author cold_blade
|
||||
* @date 2023/10/21
|
||||
* @version 1.0
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@TableName("message_send_twice_record")
|
||||
public class MessageSendTwiceRecord extends BaseEntity<MessageSendTwiceRecord> implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3517821492158061709L;
|
||||
|
||||
/**
|
||||
* 原有消息记录id
|
||||
*/
|
||||
private Long originalMsgId;
|
||||
/**
|
||||
* 接收者自然人 ID
|
||||
*/
|
||||
private Long receiverPersonId;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JSON.toJSONString(this);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package cn.axzo.msg.center.domain.entity;
|
||||
|
||||
import cn.axzo.msg.center.domain.persistence.BaseEntity;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author cold_blade
|
||||
* @date 2023/10/21
|
||||
* @version 1.0
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@TableName("relation_template_map")
|
||||
public class RelationTemplateMap extends BaseEntity<RelationTemplateMap> implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 2716916154882729387L;
|
||||
|
||||
/**
|
||||
* 新消息模板编码
|
||||
*/
|
||||
private String templateCode;
|
||||
/**
|
||||
* 原有的模板关联关系id
|
||||
*/
|
||||
private Long originalRelationId;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JSON.toJSONString(this);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user