Merge branch 'feature/REQ-1465' of axzsource.com:universal/infrastructure/backend/msg-center-plat into pre
This commit is contained in:
commit
61853c06b7
@ -110,6 +110,10 @@
|
|||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.axzo.im.center</groupId>
|
||||||
|
<artifactId>im-center-api</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@ -24,4 +24,6 @@ public class MessageSystemConfig {
|
|||||||
*/
|
*/
|
||||||
@Value("${message.common.record.divide-days:-1}")
|
@Value("${message.common.record.divide-days:-1}")
|
||||||
private Integer dataDivideDays;
|
private Integer dataDivideDays;
|
||||||
|
@Value("${message.common.icon.orgIcon:https://axzo-pro.oss-cn-hangzhou.aliyuncs.com/rs_app/ic_org_icon.png}")
|
||||||
|
private String orgIcon;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import cn.axzo.msg.center.domain.dto.SearchModuleDTO;
|
|||||||
import cn.axzo.msg.center.domain.dto.SyncModuleDataDTO;
|
import cn.axzo.msg.center.domain.dto.SyncModuleDataDTO;
|
||||||
import cn.axzo.msg.center.domain.dto.UpdateModuleDTO;
|
import cn.axzo.msg.center.domain.dto.UpdateModuleDTO;
|
||||||
import cn.axzo.msg.center.domain.entity.MessageModule;
|
import cn.axzo.msg.center.domain.entity.MessageModule;
|
||||||
|
import cn.axzo.msg.center.domain.enums.ModuleBizTypeEnum;
|
||||||
import cn.axzo.msg.center.domain.enums.UserTypeEnum;
|
import cn.axzo.msg.center.domain.enums.UserTypeEnum;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
|
||||||
@ -51,4 +52,12 @@ public interface MessageModuleService {
|
|||||||
* @return 对应的模块列表
|
* @return 对应的模块列表
|
||||||
*/
|
*/
|
||||||
List<MessageModule> listByModuleName(String moduleName);
|
List<MessageModule> listByModuleName(String moduleName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过bizType查询模块id列表
|
||||||
|
*
|
||||||
|
* @param bizType 业务类型
|
||||||
|
* @return 模块id列表
|
||||||
|
*/
|
||||||
|
List<Long> listModuleIdByBizType(ModuleBizTypeEnum bizType);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,11 @@ package cn.axzo.msg.center.inside.notices.service.impl;
|
|||||||
import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum;
|
import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum;
|
||||||
import cn.axzo.msg.center.api.enums.ReceiveTypeEnum;
|
import cn.axzo.msg.center.api.enums.ReceiveTypeEnum;
|
||||||
import cn.axzo.msg.center.dal.MessageModuleDao;
|
import cn.axzo.msg.center.dal.MessageModuleDao;
|
||||||
import cn.axzo.msg.center.domain.dto.*;
|
import cn.axzo.msg.center.domain.dto.CreateModuleDTO;
|
||||||
|
import cn.axzo.msg.center.domain.dto.MsgModuleDTO;
|
||||||
|
import cn.axzo.msg.center.domain.dto.SearchModuleDTO;
|
||||||
|
import cn.axzo.msg.center.domain.dto.SyncModuleDataDTO;
|
||||||
|
import cn.axzo.msg.center.domain.dto.UpdateModuleDTO;
|
||||||
import cn.axzo.msg.center.domain.entity.MessageModule;
|
import cn.axzo.msg.center.domain.entity.MessageModule;
|
||||||
import cn.axzo.msg.center.domain.enums.ModuleBizTypeEnum;
|
import cn.axzo.msg.center.domain.enums.ModuleBizTypeEnum;
|
||||||
import cn.axzo.msg.center.domain.enums.UserTypeEnum;
|
import cn.axzo.msg.center.domain.enums.UserTypeEnum;
|
||||||
@ -20,7 +24,12 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -179,4 +188,19 @@ public class MessageModuleServiceImpl implements MessageModuleService {
|
|||||||
.filter(e -> Objects.equals(e.getModuleName(), moduleName))
|
.filter(e -> Objects.equals(e.getModuleName(), moduleName))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Long> listModuleIdByBizType(ModuleBizTypeEnum bizType) {
|
||||||
|
if (Objects.isNull(bizType)) {
|
||||||
|
log.info("bizType is null.");
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return messageModuleDao.lambdaQuery()
|
||||||
|
.eq(MessageModule::getBizType, bizType.getCode())
|
||||||
|
.eq(MessageModule::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||||
|
.select(MessageModule::getId)
|
||||||
|
.list().stream()
|
||||||
|
.map(MessageModule::getId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,6 +28,7 @@ import cn.axzo.msg.center.domain.enums.*;
|
|||||||
import cn.axzo.msg.center.domain.request.InsideCmsReadMsgReq;
|
import cn.axzo.msg.center.domain.request.InsideCmsReadMsgReq;
|
||||||
import cn.axzo.msg.center.inside.notices.event.SendMessageEvent;
|
import cn.axzo.msg.center.inside.notices.event.SendMessageEvent;
|
||||||
import cn.axzo.msg.center.inside.notices.service.MessageRecordService;
|
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;
|
||||||
import cn.azxo.framework.common.utils.LogUtil.ErrorLevel;
|
import cn.azxo.framework.common.utils.LogUtil.ErrorLevel;
|
||||||
import cn.azxo.framework.common.utils.LogUtil.ErrorType;
|
import cn.azxo.framework.common.utils.LogUtil.ErrorType;
|
||||||
@ -37,6 +38,7 @@ import com.alibaba.fastjson.JSON;
|
|||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.text.StrSubstitutor;
|
import org.apache.commons.lang3.text.StrSubstitutor;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@ -84,6 +86,9 @@ public class MessageRecordServiceImpl implements MessageRecordService {
|
|||||||
/*@Resource
|
/*@Resource
|
||||||
private IdentityProfileService identityProfileService;*/
|
private IdentityProfileService identityProfileService;*/
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private GeneralMessageMapperService generalMessageMapperService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增推送消息接口
|
* 新增推送消息接口
|
||||||
*
|
*
|
||||||
@ -132,10 +137,11 @@ public class MessageRecordServiceImpl implements MessageRecordService {
|
|||||||
|
|
||||||
List<MessageRecord> pushMessages = new ArrayList<>();
|
List<MessageRecord> pushMessages = new ArrayList<>();
|
||||||
Lists.partition(Lists.newArrayList(message.getToId()), partitionSize).forEach(toIds -> {
|
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, toIdRecordMap);
|
||||||
pushMessages.addAll(messageRecords);
|
pushMessages.addAll(messageRecords);
|
||||||
});
|
});
|
||||||
|
|
||||||
if(pushAthena) {
|
if(pushAthena) {
|
||||||
asyncPushAthena(message, messageTemplate.getAudioFileName(), messageModule.getModuleName(), pushMessages);
|
asyncPushAthena(message, messageTemplate.getAudioFileName(), messageModule.getModuleName(), pushMessages);
|
||||||
}
|
}
|
||||||
@ -158,7 +164,8 @@ public class MessageRecordServiceImpl implements MessageRecordService {
|
|||||||
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
@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)) {
|
if (CollectionUtils.isEmpty(toIds)) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
@ -172,6 +179,7 @@ public class MessageRecordServiceImpl implements MessageRecordService {
|
|||||||
messageRecord.setToId(0L);
|
messageRecord.setToId(0L);
|
||||||
messageRecord.setPersonId(i);
|
messageRecord.setPersonId(i);
|
||||||
pushMessages.add(messageRecord);
|
pushMessages.add(messageRecord);
|
||||||
|
toIdRecordMap.put(i, messageRecord);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
toIds.forEach(i -> {
|
toIds.forEach(i -> {
|
||||||
@ -183,6 +191,7 @@ public class MessageRecordServiceImpl implements MessageRecordService {
|
|||||||
messageRecord.setPersonId(toldIdPersonIdMap.get(i));
|
messageRecord.setPersonId(toldIdPersonIdMap.get(i));
|
||||||
}
|
}
|
||||||
pushMessages.add(messageRecord);
|
pushMessages.add(messageRecord);
|
||||||
|
toIdRecordMap.put(i, messageRecord);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
messageRecordDao.saveBatch(pushMessages);
|
messageRecordDao.saveBatch(pushMessages);
|
||||||
|
|||||||
@ -24,7 +24,13 @@ import org.springframework.util.CollectionUtils;
|
|||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -188,7 +194,8 @@ public class MessageRelationServiceImpl implements MessageRelationService {
|
|||||||
}
|
}
|
||||||
return messageRelationDao.lambdaQuery()
|
return messageRelationDao.lambdaQuery()
|
||||||
.in(MessageRelation::getModuleId, moduleIds)
|
.in(MessageRelation::getModuleId, moduleIds)
|
||||||
.eq(MessageRelation::getIsDelete, 0)
|
.eq(MessageRelation::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||||
|
.select(MessageRelation::getId)
|
||||||
.list().stream()
|
.list().stream()
|
||||||
.map(MessageRelation::getId)
|
.map(MessageRelation::getId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|||||||
@ -45,7 +45,6 @@ import java.util.function.Function;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description xxx
|
|
||||||
* @author cold_blade
|
* @author cold_blade
|
||||||
* @date 2023/9/13
|
* @date 2023/9/13
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
|
|||||||
@ -0,0 +1,53 @@
|
|||||||
|
package cn.axzo.msg.center.message.controller;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.api.request.CmsMsgQueryReq;
|
||||||
|
import cn.axzo.msg.center.api.response.MessageNewRes;
|
||||||
|
import cn.axzo.msg.center.message.service.GeneralMessageOldService;
|
||||||
|
import cn.axzo.msg.center.message.service.GeneralMessageService;
|
||||||
|
import cn.axzo.msg.center.service.dto.PersonDTO;
|
||||||
|
import cn.axzo.msg.center.service.general.client.GeneralMessageClient;
|
||||||
|
import cn.axzo.msg.center.service.general.request.GeneralMessageOldDataStatisticRequest;
|
||||||
|
import cn.axzo.msg.center.service.general.request.GeneralMessageSendRequest;
|
||||||
|
import cn.axzo.msg.center.service.general.response.GeneralMessageOldDataStatisticResponse;
|
||||||
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
|
import cn.azxo.framework.common.model.Page;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/19
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GeneralMessageController implements GeneralMessageClient {
|
||||||
|
|
||||||
|
private final GeneralMessageService generalMessageService;
|
||||||
|
private final GeneralMessageOldService generalMessageOldService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Void> batchSend(GeneralMessageSendRequest request) {
|
||||||
|
generalMessageService.batchSendMessage(request);
|
||||||
|
return CommonResponse.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<GeneralMessageOldDataStatisticResponse> statisticOldData(
|
||||||
|
GeneralMessageOldDataStatisticRequest request) {
|
||||||
|
return CommonResponse.success(generalMessageService.statisticOldData(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Integer> countUnreadFromOldMessage(GeneralMessageOldDataStatisticRequest request) {
|
||||||
|
PersonDTO person = PersonDTO.from(request.getPersonId(), request.getIdentityId(), request.getIdentityType());
|
||||||
|
return CommonResponse.success(generalMessageOldService.countUnread(person));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Page<MessageNewRes>> pageQueryOldMessage(CmsMsgQueryReq request) {
|
||||||
|
return CommonResponse.success(generalMessageOldService.pageMsgInfo(request));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
package cn.axzo.msg.center.message.controller;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.message.domain.param.MessageGroupNodeSaveOrUpdateParam;
|
||||||
|
import cn.axzo.msg.center.message.service.MessageGroupNodeService;
|
||||||
|
import cn.axzo.msg.center.service.dto.GroupTreeNodeDTO;
|
||||||
|
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
|
||||||
|
import cn.axzo.msg.center.service.group.client.MessageGroupClient;
|
||||||
|
import cn.axzo.msg.center.service.group.request.MessageGroupNodeAddRequest;
|
||||||
|
import cn.axzo.msg.center.service.group.request.MessageGroupNodeUpdateRequest;
|
||||||
|
import cn.axzo.msg.center.service.group.response.MessageGroupTreeNodeResponse;
|
||||||
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息分类管理
|
||||||
|
*
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/17
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class MessageGroupController implements MessageGroupClient {
|
||||||
|
|
||||||
|
private final MessageGroupNodeService messageGroupNodeService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Void> addNode(MessageGroupNodeAddRequest request) {
|
||||||
|
messageGroupNodeService.addGroupNode(MessageGroupNodeSaveOrUpdateParam.from(request));
|
||||||
|
return CommonResponse.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Void> updateNode(MessageGroupNodeUpdateRequest request) {
|
||||||
|
messageGroupNodeService.updateGroupNode(MessageGroupNodeSaveOrUpdateParam.from(request));
|
||||||
|
return CommonResponse.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Void> deleteNode(String nodeCode, Long operatorId) {
|
||||||
|
messageGroupNodeService.deleteGroupNode(operatorId, nodeCode);
|
||||||
|
return CommonResponse.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<List<MessageGroupTreeNodeResponse>> list(MessageCategoryEnum category) {
|
||||||
|
List<MessageGroupTreeNodeResponse> groupTreeNodes = messageGroupNodeService.listGroupTree(category).stream()
|
||||||
|
.map(GroupTreeNodeDTO::toMessageGroupTreeNodeResponse)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return CommonResponse.success(groupTreeNodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,14 +1,30 @@
|
|||||||
package cn.axzo.msg.center.message.controller;
|
package cn.axzo.msg.center.message.controller;
|
||||||
|
|
||||||
import cn.axzo.msg.center.message.domain.param.MessageTemplateCreateParam;
|
import cn.axzo.core.utils.converter.BeanConverter;
|
||||||
|
import cn.axzo.msg.center.message.domain.param.MessageTemplateSaveOrUpdateParam;
|
||||||
|
import cn.axzo.msg.center.message.domain.param.RelationTemplateMapInitParam;
|
||||||
|
import cn.axzo.msg.center.message.domain.vo.RelationTemplateMapInitRequest;
|
||||||
import cn.axzo.msg.center.message.service.MessageTemplateNewService;
|
import cn.axzo.msg.center.message.service.MessageTemplateNewService;
|
||||||
|
import cn.axzo.msg.center.message.service.RelationTemplateMapService;
|
||||||
import cn.axzo.msg.center.service.template.client.MessageTemplateClient;
|
import cn.axzo.msg.center.service.template.client.MessageTemplateClient;
|
||||||
import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest;
|
import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest;
|
||||||
import cn.axzo.msg.center.service.template.request.MessageTemplateMoveToRequest;
|
import cn.axzo.msg.center.service.template.request.MessageTemplatePageRequest;
|
||||||
|
import cn.axzo.msg.center.service.template.request.MessageTemplateUpdateRequest;
|
||||||
|
import cn.axzo.msg.center.service.template.request.MessageTemplateUpdateStatusRequest;
|
||||||
|
import cn.axzo.msg.center.service.template.response.MessageTemplateDetailResponse;
|
||||||
|
import cn.axzo.msg.center.service.template.response.MessageTemplatePageResponse;
|
||||||
import cn.azxo.framework.common.model.CommonResponse;
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
|
import cn.azxo.framework.common.model.Page;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息模板管理
|
* 消息模板管理
|
||||||
*
|
*
|
||||||
@ -21,17 +37,45 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
public class MessageTemplateController implements MessageTemplateClient {
|
public class MessageTemplateController implements MessageTemplateClient {
|
||||||
|
|
||||||
private final MessageTemplateNewService messageTemplateNewService;
|
private final MessageTemplateNewService messageTemplateNewService;
|
||||||
|
private final RelationTemplateMapService relationTemplateMapService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResponse<String> addTemplate(MessageTemplateCreateRequest request) {
|
public CommonResponse<String> save(MessageTemplateCreateRequest request) {
|
||||||
MessageTemplateCreateParam param = MessageTemplateCreateParam.from(request);
|
return CommonResponse.success(
|
||||||
messageTemplateNewService.createTemplate(param);
|
messageTemplateNewService.createTemplate(MessageTemplateSaveOrUpdateParam.from(request)));
|
||||||
return CommonResponse.success(param.getTemplateCode());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResponse<String> batchMove(MessageTemplateMoveToRequest request) {
|
public CommonResponse<Void> update(MessageTemplateUpdateRequest request) {
|
||||||
// TODO: [cold_blade] [P2] 模板关联的批量移动
|
messageTemplateNewService.updateTemplate(MessageTemplateSaveOrUpdateParam.from(request));
|
||||||
return null;
|
return CommonResponse.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<MessageTemplateDetailResponse> detail(String templateCode) {
|
||||||
|
return CommonResponse.success(messageTemplateNewService.detail(templateCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Page<MessageTemplatePageResponse>> page(MessageTemplatePageRequest request) {
|
||||||
|
return CommonResponse.success(messageTemplateNewService.page(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<List<MessageTemplatePageResponse>> listByCodes(Collection<String> templateCodes) {
|
||||||
|
return CommonResponse.success(messageTemplateNewService.listByCodes(templateCodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Void> updateStatus(MessageTemplateUpdateStatusRequest request) {
|
||||||
|
messageTemplateNewService.updateStatus(request.getOperatorId(), request.getTemplateCode(), request.getStatus());
|
||||||
|
return CommonResponse.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/message/template/relation/init", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
|
public CommonResponse<Void> initRelationTemplateMap(@RequestBody @Valid RelationTemplateMapInitRequest request) {
|
||||||
|
RelationTemplateMapInitParam param = BeanConverter.convert(request, RelationTemplateMapInitParam.class);
|
||||||
|
relationTemplateMapService.init(param);
|
||||||
|
return CommonResponse.success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,62 @@
|
|||||||
|
package cn.axzo.msg.center.message.controller;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.common.utils.PageHelperUtil;
|
||||||
|
import cn.axzo.msg.center.message.service.MessageTemplateGroupService;
|
||||||
|
import cn.axzo.msg.center.message.service.MessageTemplateNewService;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageBaseTemplateDTO;
|
||||||
|
import cn.axzo.msg.center.service.group.client.MessageTemplateGroupRelationClient;
|
||||||
|
import cn.axzo.msg.center.service.group.request.MessageTemplateGroupRelationMoveRequest;
|
||||||
|
import cn.axzo.msg.center.service.group.request.MessageTemplateGroupRelationPageRequest;
|
||||||
|
import cn.axzo.msg.center.service.group.request.MessageTemplateGroupRelationRemoveRequest;
|
||||||
|
import cn.axzo.msg.center.service.group.response.MessageTemplateGroupRelationResponse;
|
||||||
|
import cn.axzo.msg.center.service.template.request.MessageTemplatePageRequest;
|
||||||
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
|
import cn.azxo.framework.common.model.Page;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/17
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class MessageTemplateGroupRelationController implements MessageTemplateGroupRelationClient {
|
||||||
|
|
||||||
|
private final MessageTemplateNewService messageTemplateNewService;
|
||||||
|
private final MessageTemplateGroupService messageTemplateGroupService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Page<MessageTemplateGroupRelationResponse>> page(MessageTemplateGroupRelationPageRequest request) {
|
||||||
|
MessageTemplatePageRequest pageRequest = new MessageTemplatePageRequest();
|
||||||
|
pageRequest.setPage(request.getPage());
|
||||||
|
pageRequest.setPageSize(request.getPageSize());
|
||||||
|
pageRequest.setTemplateName(request.getTemplateName());
|
||||||
|
pageRequest.setGroupNodeCode(request.getNodeCode());
|
||||||
|
Page<MessageBaseTemplateDTO> result = messageTemplateNewService.pageBaseTemplate(pageRequest);
|
||||||
|
return CommonResponse.success(PageHelperUtil.convert(result, this::convert));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Void> move(MessageTemplateGroupRelationMoveRequest request) {
|
||||||
|
messageTemplateGroupService.move(request.getCurNodeCode(), request.getTargetNodeCode(),
|
||||||
|
request.getTemplateCodes());
|
||||||
|
return CommonResponse.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Void> remove(MessageTemplateGroupRelationRemoveRequest request) {
|
||||||
|
messageTemplateGroupService.remove(request.getCurNodeCode(), request.getTemplateCodes());
|
||||||
|
return CommonResponse.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MessageTemplateGroupRelationResponse convert(MessageBaseTemplateDTO dto) {
|
||||||
|
MessageTemplateGroupRelationResponse response = new MessageTemplateGroupRelationResponse();
|
||||||
|
response.setTitle(dto.getTitle());
|
||||||
|
response.setTemplateCode(dto.getCode());
|
||||||
|
response.setTemplateName(dto.getName());
|
||||||
|
response.setCreateTimestamp(dto.getCreateTimestamp());
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package cn.axzo.msg.center.message.controller;
|
package cn.axzo.msg.center.message.controller;
|
||||||
|
|
||||||
import cn.axzo.msg.center.message.domain.dto.MessageGroupNodeDTO;
|
import cn.axzo.msg.center.message.domain.dto.MessageGroupNodeStatisticDTO;
|
||||||
import cn.axzo.msg.center.message.domain.dto.PendingMessageDTO;
|
import cn.axzo.msg.center.message.domain.dto.PendingMessageDTO;
|
||||||
import cn.axzo.msg.center.message.domain.param.MessageGroupNodeStatisticParam;
|
import cn.axzo.msg.center.message.domain.param.MessageGroupNodeStatisticParam;
|
||||||
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
|
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
|
||||||
@ -36,10 +36,10 @@ public class PendingMessageNewController implements PendingMessageClient {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResponse<List<MessageGroupNodeResponse>> groupStatistic(MessageGroupNodeStatisticRequest request) {
|
public CommonResponse<List<MessageGroupNodeResponse>> groupStatistic(MessageGroupNodeStatisticRequest request) {
|
||||||
List<MessageGroupNodeDTO> groupNodes = pendingMessageNewService
|
List<MessageGroupNodeStatisticDTO> groupNodes = pendingMessageNewService
|
||||||
.groupStatistic(MessageGroupNodeStatisticParam.from(request));
|
.groupStatistic(MessageGroupNodeStatisticParam.from(request));
|
||||||
return CommonResponse.success(groupNodes.stream()
|
return CommonResponse.success(groupNodes.stream()
|
||||||
.map(MessageGroupNodeDTO::toResponse)
|
.map(MessageGroupNodeStatisticDTO::toResponse)
|
||||||
.collect(Collectors.toList())
|
.collect(Collectors.toList())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,68 @@
|
|||||||
|
package cn.axzo.msg.center.message.domain.dto;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.dto.GroupTreeNodeDTO;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/14
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class GroupTreeNodePathDTO implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -6325338437781927201L;
|
||||||
|
|
||||||
|
private static final String NODE_NAME_PATH_SPLITER = "/";
|
||||||
|
private static final String NODE_CODE_PATH_SPLITER = ":";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结点编码
|
||||||
|
*/
|
||||||
|
private String nodeCode;
|
||||||
|
/**
|
||||||
|
* 结点名称格式的路径
|
||||||
|
*/
|
||||||
|
private String nodeNamePath;
|
||||||
|
/**
|
||||||
|
* 结点编码格式的路径
|
||||||
|
*/
|
||||||
|
private String nodeCodePath;
|
||||||
|
|
||||||
|
public static String parseLeafNodeCode(String nodeCodePath) {
|
||||||
|
if (StringUtils.isBlank(nodeCodePath)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String[] nodeCodes = nodeCodePath.split(NODE_CODE_PATH_SPLITER);
|
||||||
|
// 最后一个为叶节点的结点编码
|
||||||
|
return nodeCodes[nodeCodes.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GroupTreeNodePathDTO of(String nodeCode, Collection<GroupTreeNodeDTO> nodes) {
|
||||||
|
String nodeNamePath = formatPath(GroupTreeNodeDTO::getNodeName, nodes, NODE_NAME_PATH_SPLITER);
|
||||||
|
String nodeCodePath = formatPath(GroupTreeNodeDTO::getNodeCode, nodes, NODE_CODE_PATH_SPLITER);
|
||||||
|
return new GroupTreeNodePathDTO(nodeCode, nodeNamePath, nodeCodePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String formatPath(Function<GroupTreeNodeDTO, String> pathFunc, Collection<GroupTreeNodeDTO> nodes,
|
||||||
|
String spliter) {
|
||||||
|
return nodes.stream().map(pathFunc).collect(Collectors.joining(spliter));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,87 +0,0 @@
|
|||||||
package cn.axzo.msg.center.message.domain.dto;
|
|
||||||
|
|
||||||
import cn.axzo.core.utils.converter.BeanConverter;
|
|
||||||
import cn.axzo.msg.center.domain.entity.MessageGroupNode;
|
|
||||||
import cn.axzo.msg.center.service.enums.MessageGroupNodeCategoryEnum;
|
|
||||||
import cn.axzo.msg.center.service.pending.response.MessageGroupNodeResponse;
|
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description
|
|
||||||
* 消息分类结点DTO
|
|
||||||
*
|
|
||||||
* @author cold_blade
|
|
||||||
* @date 2023/9/26
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
@Setter
|
|
||||||
@Getter
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class MessageGroupNodeDTO implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 5171436359992401120L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结点类型
|
|
||||||
* GENERAL_MESSAGE_CENTER: 消息中心
|
|
||||||
* GENERAL_MESSAGE_MODULE: 消息模块
|
|
||||||
* GENERAL_MESSAGE_CATEGORY: 消息分类
|
|
||||||
* PENDING_MESSAGE_CENTER: 待办中心
|
|
||||||
* PENDING_MESSAGE_MODULE: 待办模块
|
|
||||||
* PENDING_MESSAGE_CATEGORY: 待办分类
|
|
||||||
*/
|
|
||||||
private MessageGroupNodeCategoryEnum category;
|
|
||||||
/**
|
|
||||||
* 结点名称
|
|
||||||
*/
|
|
||||||
private String nodeName;
|
|
||||||
/**
|
|
||||||
* 结点编码
|
|
||||||
*/
|
|
||||||
private String nodeCode;
|
|
||||||
/**
|
|
||||||
* 父节点编码
|
|
||||||
*/
|
|
||||||
private String parentNodeCode;
|
|
||||||
/**
|
|
||||||
* 结点对应的代办数量
|
|
||||||
*/
|
|
||||||
private Integer pendingCount;
|
|
||||||
/**
|
|
||||||
* 子节点列表
|
|
||||||
*/
|
|
||||||
private List<MessageGroupNodeDTO> children;
|
|
||||||
|
|
||||||
public static MessageGroupNodeDTO from(MessageGroupNode groupNode) {
|
|
||||||
return MessageGroupNodeDTO.builder()
|
|
||||||
.category(groupNode.getCategory())
|
|
||||||
.nodeName(groupNode.getName())
|
|
||||||
.nodeCode(groupNode.getCode())
|
|
||||||
.parentNodeCode(groupNode.getParentCode())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public MessageGroupNodeResponse toResponse() {
|
|
||||||
MessageGroupNodeResponse response = BeanConverter.convert(this, MessageGroupNodeResponse.class);
|
|
||||||
List<MessageGroupNodeResponse> children = this.children.stream()
|
|
||||||
.map(MessageGroupNodeDTO::toResponse).collect(Collectors.toList());
|
|
||||||
response.setNodeChildren(children);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return JSON.toJSONString(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
package cn.axzo.msg.center.message.domain.dto;
|
||||||
|
|
||||||
|
import cn.axzo.basics.common.model.IBaseTree;
|
||||||
|
import cn.axzo.core.utils.converter.BeanConverter;
|
||||||
|
import cn.axzo.msg.center.service.dto.GroupTreeNodeDTO;
|
||||||
|
import cn.axzo.msg.center.service.pending.response.MessageGroupNodeResponse;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description
|
||||||
|
* 消息分类结点DTO
|
||||||
|
*
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/9/26
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class MessageGroupNodeStatisticDTO implements IBaseTree<MessageGroupNodeStatisticDTO, String>, Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 5171436359992401120L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 树结点
|
||||||
|
*/
|
||||||
|
private GroupTreeNodeDTO treeNode;
|
||||||
|
/**
|
||||||
|
* 子节点列表
|
||||||
|
*/
|
||||||
|
private List<MessageGroupNodeStatisticDTO> nodeChildren;
|
||||||
|
/**
|
||||||
|
* 结点对应的代办数量
|
||||||
|
*/
|
||||||
|
private Integer pendingCount;
|
||||||
|
|
||||||
|
public static MessageGroupNodeStatisticDTO of(GroupTreeNodeDTO groupNode) {
|
||||||
|
return MessageGroupNodeStatisticDTO.builder()
|
||||||
|
.treeNode(groupNode)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageGroupNodeResponse toResponse() {
|
||||||
|
MessageGroupNodeResponse response = new MessageGroupNodeResponse();
|
||||||
|
response.setCategory(treeNode.getCategory());
|
||||||
|
response.setNodeCode(treeNode.getNodeCode());
|
||||||
|
response.setNodeName(treeNode.getNodeName());
|
||||||
|
response.setParentNodeCode(treeNode.getParentNodeCode());
|
||||||
|
response.setPendingCount(this.pendingCount);
|
||||||
|
List<MessageGroupNodeResponse> children = this.nodeChildren.stream()
|
||||||
|
.map(MessageGroupNodeStatisticDTO::toResponse).collect(Collectors.toList());
|
||||||
|
response.setNodeChildren(children);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNodeCode() {
|
||||||
|
return treeNode.getNodeCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getParentNodeCode() {
|
||||||
|
return treeNode.getParentNodeCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,16 +1,23 @@
|
|||||||
package cn.axzo.msg.center.message.domain.dto;
|
package cn.axzo.msg.center.message.domain.dto;
|
||||||
|
|
||||||
import cn.axzo.msg.center.domain.entity.MessageBaseTemplate;
|
import cn.axzo.msg.center.domain.entity.MessageBaseTemplate;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO;
|
||||||
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
|
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
|
||||||
|
import cn.axzo.msg.center.utils.JSONObjectUtil;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description
|
* @description
|
||||||
@ -45,9 +52,9 @@ public class MessageTemplateDTO implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private String content;
|
private String content;
|
||||||
/**
|
/**
|
||||||
* 卡片信息,json字串
|
* 消息卡片信息标签列表
|
||||||
*/
|
*/
|
||||||
private String cardContent;
|
private List<MessageCardContentItemDTO> msgCardContentItems;
|
||||||
/**
|
/**
|
||||||
* 所属消息类型
|
* 所属消息类型
|
||||||
*/
|
*/
|
||||||
@ -60,6 +67,14 @@ public class MessageTemplateDTO implements Serializable {
|
|||||||
* 模板路由信息
|
* 模板路由信息
|
||||||
*/
|
*/
|
||||||
private List<RawMessageRouterDTO> routers;
|
private List<RawMessageRouterDTO> routers;
|
||||||
|
/**
|
||||||
|
* 推送终端
|
||||||
|
*/
|
||||||
|
private List<PushTerminalEnum> pushTerminals;
|
||||||
|
/**
|
||||||
|
* APP最小版本支持,可不配
|
||||||
|
*/
|
||||||
|
private String minAppVersion;
|
||||||
|
|
||||||
public static MessageTemplateDTO from(MessageBaseTemplate baseTemplate, List<RawMessageRouterDTO> routers) {
|
public static MessageTemplateDTO from(MessageBaseTemplate baseTemplate, List<RawMessageRouterDTO> routers) {
|
||||||
return MessageTemplateDTO.builder()
|
return MessageTemplateDTO.builder()
|
||||||
@ -67,13 +82,24 @@ public class MessageTemplateDTO implements Serializable {
|
|||||||
.code(baseTemplate.getCode())
|
.code(baseTemplate.getCode())
|
||||||
.title(baseTemplate.getTitle())
|
.title(baseTemplate.getTitle())
|
||||||
.content(baseTemplate.getContent())
|
.content(baseTemplate.getContent())
|
||||||
.cardContent(baseTemplate.getCardContent())
|
.msgCardContentItems(JSONObjectUtil.parseArray(baseTemplate.getCardContent(), MessageCardContentItemDTO.class))
|
||||||
.msgCategory(baseTemplate.getMsgCategory())
|
.msgCategory(baseTemplate.getMsgCategory())
|
||||||
.icon(baseTemplate.getIcon())
|
.icon(baseTemplate.getIcon())
|
||||||
.routers(routers)
|
.routers(routers)
|
||||||
|
.pushTerminals(JSON.parseArray(baseTemplate.getPushTerminal(), PushTerminalEnum.class))
|
||||||
|
.minAppVersion(baseTemplate.getMinAppVersion())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, String> toCardContentMap() {
|
||||||
|
if (CollectionUtils.isEmpty(msgCardContentItems)) {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
msgCardContentItems.forEach(e -> map.put(e.getLabel(), e.getValue()));
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return JSON.toJSONString(this);
|
return JSON.toJSONString(this);
|
||||||
|
|||||||
@ -143,6 +143,7 @@ public class PendingMessageDTO implements Serializable {
|
|||||||
.updateTimestamp(DateFormatUtil.toTimestamp(this.updateTime))
|
.updateTimestamp(DateFormatUtil.toTimestamp(this.updateTime))
|
||||||
.routers(this.routers)
|
.routers(this.routers)
|
||||||
.routerParams(this.routerParams)
|
.routerParams(this.routerParams)
|
||||||
|
.bizExtParams("{}")
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,15 @@
|
|||||||
package cn.axzo.msg.center.message.domain.dto;
|
package cn.axzo.msg.center.message.domain.dto;
|
||||||
|
|
||||||
import cn.axzo.msg.center.domain.entity.MessageTemplateRouter;
|
import cn.axzo.msg.center.domain.entity.MessageTemplateRouter;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO;
|
||||||
import cn.axzo.msg.center.service.dto.MessageRouterDTO;
|
import cn.axzo.msg.center.service.dto.MessageRouterDTO;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageRouterTerminalDTO;
|
||||||
|
import cn.axzo.msg.center.service.enums.ButtonStyleEnum;
|
||||||
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
|
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
|
||||||
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
|
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
|
||||||
|
import cn.axzo.msg.center.utils.MessageRouterUtil;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -12,6 +17,8 @@ import lombok.NoArgsConstructor;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description
|
* @description
|
||||||
@ -40,54 +47,96 @@ public class RawMessageRouterDTO implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private RouterCategoryEnum category;
|
private RouterCategoryEnum category;
|
||||||
/**
|
/**
|
||||||
* 页面地址 OR API接口地址
|
* 路由终端
|
||||||
*/
|
*/
|
||||||
private String url;
|
private List<MessageRouterTerminalDTO> terminals;
|
||||||
/**
|
|
||||||
* 页面地址所属应用端(如果是API接口地址,请忽略改字段值)
|
|
||||||
* WEB: web端页面
|
|
||||||
* MINI_PROGRAM: 安心筑小程序端页面
|
|
||||||
* IOS: 原生IOS端页面
|
|
||||||
* ANDROID: 原生Android端页面
|
|
||||||
* WEB_VIEW: H5页面
|
|
||||||
* WECHAT_MINI_PROGRAM: 微信小程序页面
|
|
||||||
*/
|
|
||||||
private TerminalTypeEnum terminalType;
|
|
||||||
/**
|
/**
|
||||||
* 模板编码
|
* 模板编码
|
||||||
*/
|
*/
|
||||||
private String templateCode;
|
private String templateCode;
|
||||||
|
/**
|
||||||
|
* 按钮样式配置
|
||||||
|
*/
|
||||||
|
private List<ButtonStyleEnum> style;
|
||||||
|
|
||||||
public static RawMessageRouterDTO from(MessageTemplateRouter msgTemplateRouter) {
|
public static RawMessageRouterDTO from(List<MessageTemplateRouter> msgTemplateRouters) {
|
||||||
|
MessageTemplateRouter router = msgTemplateRouters.get(0);
|
||||||
|
List<MessageRouterTerminalDTO> terminals = msgTemplateRouters.stream()
|
||||||
|
.map(RawMessageRouterDTO::convert2Terminal)
|
||||||
|
.collect(Collectors.toList());
|
||||||
return RawMessageRouterDTO.builder()
|
return RawMessageRouterDTO.builder()
|
||||||
.desc(msgTemplateRouter.getName())
|
.desc(router.getName())
|
||||||
.url(msgTemplateRouter.getUrl())
|
.category(router.getCategory())
|
||||||
.category(msgTemplateRouter.getCategory())
|
.templateCode(router.getTemplateCode())
|
||||||
.terminalType(msgTemplateRouter.getTerminalType())
|
.style(MessageRouterUtil.parseButtonStyle(router.getStyle()))
|
||||||
.templateCode(msgTemplateRouter.getTemplateCode())
|
.terminals(terminals)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RawMessageRouterDTO from(MessageRouterDTO router, String templateCode) {
|
public static RawMessageRouterDTO from(MessageRouterButtonDTO router, String templateCode) {
|
||||||
return RawMessageRouterDTO.builder()
|
return RawMessageRouterDTO.builder()
|
||||||
.desc(router.getDesc())
|
.desc(router.getDesc())
|
||||||
.url(router.getUrl())
|
|
||||||
.category(router.getCategory())
|
.category(router.getCategory())
|
||||||
.terminalType(router.getTerminalType())
|
.terminals(router.getTerminals())
|
||||||
|
.style(router.getStyle())
|
||||||
.templateCode(templateCode)
|
.templateCode(templateCode)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessageTemplateRouter toMessageTemplateRouter() {
|
public MessageRouterButtonDTO toMessageRouterButton() {
|
||||||
|
return MessageRouterButtonDTO.builder()
|
||||||
|
.desc(this.desc)
|
||||||
|
.category(this.category)
|
||||||
|
.terminals(this.terminals)
|
||||||
|
.style(this.style)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<MessageTemplateRouter> toMessageTemplateRouters() {
|
||||||
|
return this.terminals.stream()
|
||||||
|
.map(this::convert)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageRouterDTO toMessageRouter(TerminalTypeEnum terminalType) {
|
||||||
|
MessageRouterTerminalDTO terminal = MessageRouterUtil.select(this, terminalType);
|
||||||
|
return MessageRouterDTO.builder()
|
||||||
|
.desc(this.desc)
|
||||||
|
.category(this.category)
|
||||||
|
.style(this.style)
|
||||||
|
.terminalType(terminal.getTerminalType())
|
||||||
|
.url(terminal.getUrl())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MessageTemplateRouter convert(MessageRouterTerminalDTO terminal) {
|
||||||
MessageTemplateRouter router = new MessageTemplateRouter();
|
MessageTemplateRouter router = new MessageTemplateRouter();
|
||||||
router.setName(this.desc);
|
router.setName(desc);
|
||||||
router.setUrl(this.url);
|
router.setCategory(category);
|
||||||
router.setCategory(this.category);
|
router.setTemplateCode(templateCode);
|
||||||
router.setTerminalType(this.terminalType);
|
router.setStyle(JSON.toJSONString(style));
|
||||||
router.setTemplateCode(this.templateCode);
|
router.setUrl(terminal.getUrl());
|
||||||
|
router.setTerminalType(terminal.getTerminalType());
|
||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static MessageRouterTerminalDTO convert2Terminal(MessageTemplateRouter router) {
|
||||||
|
return MessageRouterTerminalDTO.builder()
|
||||||
|
.url(router.getUrl())
|
||||||
|
.terminalType(router.getTerminalType())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RawMessageRouterDTO deepClone() {
|
||||||
|
return RawMessageRouterDTO.builder()
|
||||||
|
.desc(this.desc)
|
||||||
|
.category(this.category)
|
||||||
|
.terminals(this.terminals.stream().map(MessageRouterTerminalDTO::deepClone).collect(Collectors.toList()))
|
||||||
|
.templateCode(this.templateCode)
|
||||||
|
.style(Lists.newArrayList(this.getStyle()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return JSON.toJSONString(this);
|
return JSON.toJSONString(this);
|
||||||
|
|||||||
@ -0,0 +1,47 @@
|
|||||||
|
package cn.axzo.msg.center.message.domain.dto;
|
||||||
|
|
||||||
|
import cn.axzo.im.center.api.vo.resp.MessageDispatchResp;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/25
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SendImMessageDTO implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 3385679937092148803L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自然人id
|
||||||
|
*/
|
||||||
|
private Long personId;
|
||||||
|
/**
|
||||||
|
* im消息id
|
||||||
|
*/
|
||||||
|
private String imMsgId;
|
||||||
|
|
||||||
|
public static SendImMessageDTO from(MessageDispatchResp resp) {
|
||||||
|
return SendImMessageDTO.builder()
|
||||||
|
.imMsgId(resp.getMsgid())
|
||||||
|
.personId(Long.parseLong(resp.getPersonId()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
package cn.axzo.msg.center.message.domain.param;
|
||||||
|
|
||||||
|
import cn.axzo.core.utils.converter.BeanConverter;
|
||||||
|
import cn.axzo.msg.center.service.enums.MessageGroupNodeCategoryEnum;
|
||||||
|
import cn.axzo.msg.center.service.group.request.MessageGroupNodeAddRequest;
|
||||||
|
import cn.axzo.msg.center.service.group.request.MessageGroupNodeUpdateRequest;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/17
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class MessageGroupNodeSaveOrUpdateParam {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作者的自然人id
|
||||||
|
*/
|
||||||
|
private Long operatorId;
|
||||||
|
/**
|
||||||
|
* 父节点编码
|
||||||
|
*/
|
||||||
|
private String parentNodeCode;
|
||||||
|
/**
|
||||||
|
* 待添加结点名称
|
||||||
|
*/
|
||||||
|
private String nodeName;
|
||||||
|
/**
|
||||||
|
* 待修改的结点编码
|
||||||
|
*/
|
||||||
|
private String nodeCode;
|
||||||
|
/**
|
||||||
|
* 待添加结点类型
|
||||||
|
* GENERAL_MESSAGE_CENTER: 通知的业务中心
|
||||||
|
* GENERAL_MESSAGE_MODULE: 消息模块
|
||||||
|
* GENERAL_MESSAGE_CATEGORY: 消息分类
|
||||||
|
* PENDING_MESSAGE_CENTER: 待办的业务中心
|
||||||
|
* PENDING_MESSAGE_MODULE: 待办模块
|
||||||
|
* PENDING_MESSAGE_CATEGORY: 待办分类
|
||||||
|
*/
|
||||||
|
private MessageGroupNodeCategoryEnum category;
|
||||||
|
/**
|
||||||
|
* 待添加结点图标
|
||||||
|
*/
|
||||||
|
private String icon;
|
||||||
|
|
||||||
|
public static MessageGroupNodeSaveOrUpdateParam from(MessageGroupNodeAddRequest request) {
|
||||||
|
return BeanConverter.convert(request, MessageGroupNodeSaveOrUpdateParam.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MessageGroupNodeSaveOrUpdateParam from(MessageGroupNodeUpdateRequest request) {
|
||||||
|
return BeanConverter.convert(request, MessageGroupNodeSaveOrUpdateParam.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,90 +0,0 @@
|
|||||||
package cn.axzo.msg.center.message.domain.param;
|
|
||||||
|
|
||||||
import cn.axzo.msg.center.service.dto.MessageRouterDTO;
|
|
||||||
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
|
|
||||||
import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest;
|
|
||||||
import cn.axzo.msg.center.utils.UUIDUtil;
|
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description
|
|
||||||
*
|
|
||||||
* @author cold_blade
|
|
||||||
* @date 2023/10/5
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
@Setter
|
|
||||||
@Getter
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class MessageTemplateCreateParam implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 6657624182580261353L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 模板名称
|
|
||||||
*/
|
|
||||||
private String templateName;
|
|
||||||
/**
|
|
||||||
* 系统自动生成的模板code
|
|
||||||
*/
|
|
||||||
private String templateCode;
|
|
||||||
/**
|
|
||||||
* 所属消息类型
|
|
||||||
* GENERAL_MESSAGE: 普通消息
|
|
||||||
* PENDING_MESSAGE: 待办消息
|
|
||||||
*/
|
|
||||||
private MessageCategoryEnum msgCategory;
|
|
||||||
/**
|
|
||||||
* 模板标题
|
|
||||||
*/
|
|
||||||
private String title;
|
|
||||||
/**
|
|
||||||
* 模板类容
|
|
||||||
*/
|
|
||||||
private String content;
|
|
||||||
/**
|
|
||||||
* 卡片信息,json字串
|
|
||||||
*/
|
|
||||||
private String cardContent;
|
|
||||||
/**
|
|
||||||
* 模板icon
|
|
||||||
*/
|
|
||||||
private String icon;
|
|
||||||
/**
|
|
||||||
* 操作者自然人id
|
|
||||||
*/
|
|
||||||
private Long operatorId;
|
|
||||||
/**
|
|
||||||
* 路由列表
|
|
||||||
*/
|
|
||||||
private List<MessageRouterDTO> routers;
|
|
||||||
|
|
||||||
public static MessageTemplateCreateParam from(MessageTemplateCreateRequest request) {
|
|
||||||
return MessageTemplateCreateParam.builder()
|
|
||||||
.templateName(request.getTemplateName())
|
|
||||||
.templateCode(UUIDUtil.uuidString())
|
|
||||||
.msgCategory(request.getCategory())
|
|
||||||
.title(request.getMsgTitle())
|
|
||||||
.content(request.getMsgContent())
|
|
||||||
.cardContent(request.getMsgCardInfo())
|
|
||||||
.icon(request.getMsgIcon())
|
|
||||||
.operatorId(request.getOperatorId())
|
|
||||||
.routers(request.getRouters())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return JSON.toJSONString(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,118 @@
|
|||||||
|
package cn.axzo.msg.center.message.domain.param;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO;
|
||||||
|
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
|
||||||
|
import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest;
|
||||||
|
import cn.axzo.msg.center.service.template.request.MessageTemplateUpdateRequest;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description
|
||||||
|
*
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/5
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class MessageTemplateSaveOrUpdateParam implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 6657624182580261353L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板名称
|
||||||
|
*/
|
||||||
|
private String templateName;
|
||||||
|
/**
|
||||||
|
* 模板编码
|
||||||
|
*/
|
||||||
|
private String templateCode;
|
||||||
|
/**
|
||||||
|
* 消息分类树的叶结点的结点编码列表
|
||||||
|
*/
|
||||||
|
private List<String> leafGroupNodes;
|
||||||
|
/**
|
||||||
|
* 所属消息类型
|
||||||
|
* GENERAL_MESSAGE: 普通消息
|
||||||
|
* PENDING_MESSAGE: 待办消息
|
||||||
|
*/
|
||||||
|
private MessageCategoryEnum msgCategory;
|
||||||
|
/**
|
||||||
|
* 模板标题
|
||||||
|
*/
|
||||||
|
private String title;
|
||||||
|
/**
|
||||||
|
* 模板类容
|
||||||
|
*/
|
||||||
|
private String content;
|
||||||
|
/**
|
||||||
|
* 消息卡片信息标签列表
|
||||||
|
*/
|
||||||
|
private List<MessageCardContentItemDTO> msgCardContentItems;
|
||||||
|
/**
|
||||||
|
* 模板icon
|
||||||
|
*/
|
||||||
|
private String icon;
|
||||||
|
/**
|
||||||
|
* 操作者自然人id
|
||||||
|
*/
|
||||||
|
private Long operatorId;
|
||||||
|
/**
|
||||||
|
* 路由列表
|
||||||
|
*/
|
||||||
|
private List<MessageRouterButtonDTO> routers;
|
||||||
|
/**
|
||||||
|
* 推送终端配置
|
||||||
|
* B_ENTERPRISE_APP: B-安心筑企业版
|
||||||
|
* C_WORKER_APP: C-安心筑工人版
|
||||||
|
*/
|
||||||
|
private List<PushTerminalEnum> pushTerminals;
|
||||||
|
|
||||||
|
public static MessageTemplateSaveOrUpdateParam from(MessageTemplateCreateRequest request) {
|
||||||
|
return MessageTemplateSaveOrUpdateParam.builder()
|
||||||
|
.templateName(request.getTemplateName())
|
||||||
|
.msgCategory(request.getCategory())
|
||||||
|
.leafGroupNodes(request.getLeafGroupNodes())
|
||||||
|
.title(request.getMsgTitle())
|
||||||
|
.content(request.getMsgContent())
|
||||||
|
.msgCardContentItems(request.getMsgCardContentItems())
|
||||||
|
.icon(request.getMsgIcon())
|
||||||
|
.operatorId(request.getOperatorId())
|
||||||
|
.routers(request.getRouters())
|
||||||
|
.pushTerminals(request.getPushTerminals())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MessageTemplateSaveOrUpdateParam from(MessageTemplateUpdateRequest request) {
|
||||||
|
return MessageTemplateSaveOrUpdateParam.builder()
|
||||||
|
.templateName(request.getTemplateName())
|
||||||
|
.templateCode(request.getTemplateCode())
|
||||||
|
.leafGroupNodes(request.getLeafGroupNodes())
|
||||||
|
.title(request.getMsgTitle())
|
||||||
|
.content(request.getMsgContent())
|
||||||
|
.msgCardContentItems(request.getMsgCardContentItems())
|
||||||
|
.icon(request.getMsgIcon())
|
||||||
|
.operatorId(request.getOperatorId())
|
||||||
|
.routers(request.getRouters())
|
||||||
|
.pushTerminals(request.getPushTerminals())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -69,6 +69,10 @@ public class PendingMessagePushParam implements Serializable {
|
|||||||
* 业务描述eg:流程结点描述
|
* 业务描述eg:流程结点描述
|
||||||
*/
|
*/
|
||||||
private String bizDesc;
|
private String bizDesc;
|
||||||
|
/**
|
||||||
|
* 业务扩展参数,JSON字符串格式
|
||||||
|
*/
|
||||||
|
private String bizExtParams;
|
||||||
/**
|
/**
|
||||||
* 路由参数(json string)
|
* 路由参数(json string)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
package cn.axzo.msg.center.message.domain.param;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/27
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class RelationTemplateMapInitParam {
|
||||||
|
|
||||||
|
private Collection<Long> relationIds;
|
||||||
|
private String groupNodeCode;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,230 @@
|
|||||||
|
package cn.axzo.msg.center.message.domain.vo;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.domain.entity.GeneralMessageRecord;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO;
|
||||||
|
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/19
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class GeneralMessagePushVO implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -9017550674630922381L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息的唯一标识
|
||||||
|
*/
|
||||||
|
private String identityCode;
|
||||||
|
/**
|
||||||
|
* 模板编码
|
||||||
|
*/
|
||||||
|
private String templateCode;
|
||||||
|
/**
|
||||||
|
* 顶部图片 - 模板icon地址
|
||||||
|
*/
|
||||||
|
private String cardBannerUrl;
|
||||||
|
/**
|
||||||
|
* 卡片标题标题 - 消息标题
|
||||||
|
*/
|
||||||
|
private String cardTitle;
|
||||||
|
/**
|
||||||
|
* 详情按钮
|
||||||
|
*/
|
||||||
|
private CardButton cardDetailButton;
|
||||||
|
/**
|
||||||
|
* 副标题 - 消息所属组织信息
|
||||||
|
*/
|
||||||
|
private List<Subtitle> subtitles;
|
||||||
|
/**
|
||||||
|
* 消息内容
|
||||||
|
*/
|
||||||
|
private String cardContent;
|
||||||
|
/**
|
||||||
|
* 卡片信息
|
||||||
|
*/
|
||||||
|
private List<CardExtensionItem> cardExtension;
|
||||||
|
/**
|
||||||
|
* 按钮操作区域
|
||||||
|
*/
|
||||||
|
private List<CardButton> cardButtons;
|
||||||
|
/**
|
||||||
|
* 业务编码
|
||||||
|
*/
|
||||||
|
private String bizCode;
|
||||||
|
/**
|
||||||
|
* 消息发送时间戳
|
||||||
|
*/
|
||||||
|
private Long sendTimestamp;
|
||||||
|
|
||||||
|
public static GeneralMessagePushVO from(GeneralMessageRecord record, String templateIcon, String orgIcon,
|
||||||
|
List<MessageRouterButtonDTO> routerButtons,
|
||||||
|
List<MessageCardContentItemDTO> cardContentItems) {
|
||||||
|
CardButton cardDetailButton = CollectionUtils.isEmpty(routerButtons) ? null : routerButtons.stream()
|
||||||
|
.filter(e -> RouterCategoryEnum.DETAIL.equals(e.getCategory()))
|
||||||
|
.findFirst()
|
||||||
|
.map(CardButton::from)
|
||||||
|
.orElse(null);
|
||||||
|
List<CardButton> cardButtons = CollectionUtils.isEmpty(routerButtons) ? Collections.emptyList() :
|
||||||
|
routerButtons.stream()
|
||||||
|
.filter(e -> !RouterCategoryEnum.DETAIL.equals(e.getCategory()))
|
||||||
|
.filter(MessageRouterButtonDTO::isShowOnCard)
|
||||||
|
.map(CardButton::from)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
List<CardExtensionItem> cardExtension = CollectionUtils.isEmpty(cardContentItems) ? Collections.emptyList() :
|
||||||
|
cardContentItems.stream()
|
||||||
|
.map(CardExtensionItem::from)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
List<Subtitle> subtitles = Collections.emptyList();
|
||||||
|
Optional<Subtitle> subtitleOp = Subtitle.from(record, orgIcon);
|
||||||
|
if (subtitleOp.isPresent()) {
|
||||||
|
subtitles = Lists.newArrayList(subtitleOp.get());
|
||||||
|
}
|
||||||
|
return GeneralMessagePushVO.builder()
|
||||||
|
.identityCode(record.getIdentityCode())
|
||||||
|
.templateCode(record.getTemplateCode())
|
||||||
|
.cardBannerUrl(templateIcon)
|
||||||
|
.cardTitle(record.getTitle())
|
||||||
|
.cardDetailButton(cardDetailButton)
|
||||||
|
.subtitles(subtitles)
|
||||||
|
.cardContent(record.getContent())
|
||||||
|
.cardExtension(cardExtension)
|
||||||
|
.cardButtons(cardButtons)
|
||||||
|
.bizCode(record.getBizCode())
|
||||||
|
.sendTimestamp(record.getCreateAt().getTime())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
static class Subtitle {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图标 - 对应消息所属组织的图标
|
||||||
|
*/
|
||||||
|
private String iconUrl;
|
||||||
|
/**
|
||||||
|
* 标题 - 对应消息所属组织的名称
|
||||||
|
*/
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
static Optional<Subtitle> from(GeneralMessageRecord record, String orgIcon) {
|
||||||
|
if (StringUtils.isBlank(record.getOrgName())) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
return Optional.of(Subtitle.builder()
|
||||||
|
.title(record.getOrgName())
|
||||||
|
.iconUrl(orgIcon)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
static class CardButton {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按钮标题
|
||||||
|
*/
|
||||||
|
private String title;
|
||||||
|
/**
|
||||||
|
* 按钮操作类型: JUMP - 页面跳转, ACTION - 接口调用
|
||||||
|
*/
|
||||||
|
private String action;
|
||||||
|
/**
|
||||||
|
* 按钮样式
|
||||||
|
*/
|
||||||
|
private Boolean isHighlight;
|
||||||
|
/**
|
||||||
|
* 按钮点击后的跳转地址
|
||||||
|
*/
|
||||||
|
private List<ButtonAction> actionPaths;
|
||||||
|
|
||||||
|
static CardButton from(MessageRouterButtonDTO routerButton) {
|
||||||
|
return CardButton.builder()
|
||||||
|
.title(routerButton.getDesc())
|
||||||
|
.action(routerButton.getCategory().name())
|
||||||
|
.isHighlight(routerButton.isHighlight())
|
||||||
|
.actionPaths(routerButton.getTerminals().stream()
|
||||||
|
.map(e -> new ButtonAction(e.getTerminalType().name(), e.getUrl()))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
static class ButtonAction {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 平台
|
||||||
|
*/
|
||||||
|
private String platform;
|
||||||
|
/**
|
||||||
|
* 跳转地址
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
static class CardExtensionItem {
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
private String detail;
|
||||||
|
|
||||||
|
static CardExtensionItem from(MessageCardContentItemDTO cardContentItem) {
|
||||||
|
return CardExtensionItem.builder()
|
||||||
|
.title(cardContentItem.getLabel())
|
||||||
|
.detail(cardContentItem.getValue())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package cn.axzo.msg.center.message.domain.vo;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/27
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class RelationTemplateMapInitRequest {
|
||||||
|
|
||||||
|
private Collection<Long> relationIds;
|
||||||
|
@NotBlank(message = "groupNodeCode is required")
|
||||||
|
private String groupNodeCode;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package cn.axzo.msg.center.message.service;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.api.request.GeneralMessageReq;
|
||||||
|
import cn.axzo.msg.center.domain.entity.MessageRecord;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新老版本消息映射的相关接口
|
||||||
|
*
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/23
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public interface GeneralMessageMapperService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步批量发送消息
|
||||||
|
*
|
||||||
|
* @param request 发送消息时的请求参数
|
||||||
|
* @param toIdMessageRecordMap 接收者身份id与旧消息记录的映射关系
|
||||||
|
*/
|
||||||
|
void asyncBatchSendMessage(GeneralMessageReq request, Map<Long, MessageRecord> toIdMessageRecordMap);
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
package cn.axzo.msg.center.message.service;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.api.request.CmsMsgQueryReq;
|
||||||
|
import cn.axzo.msg.center.api.response.MessageNewRes;
|
||||||
|
import cn.axzo.msg.center.service.dto.PersonDTO;
|
||||||
|
import cn.azxo.framework.common.model.Page;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 旧普通消息的相关接口
|
||||||
|
*
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/24
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public interface GeneralMessageOldService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计未读的消息数量
|
||||||
|
* 注: 该接口作为IM进入旧消息模块的入口,需要过滤双发至IM的消息
|
||||||
|
*
|
||||||
|
* @param person 身份信息
|
||||||
|
* @return 未读消息数量
|
||||||
|
*/
|
||||||
|
int countUnread(PersonDTO person);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计未读的消息数量
|
||||||
|
* 注: 该接口作为IM进入旧消息模块的入口,需要过滤双发至IM的消息
|
||||||
|
*
|
||||||
|
* @param person 身份信息
|
||||||
|
* @param excludeMsgIds 待排除的消息记录id
|
||||||
|
* @return 未读消息数量
|
||||||
|
*/
|
||||||
|
int countUnread(PersonDTO person, List<Long> excludeMsgIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询旧的普通消息记录
|
||||||
|
* 注: 该接口作为IM进入旧消息模块的入口,需要过滤双发至IM的消息
|
||||||
|
*
|
||||||
|
* @param request 分页查询参数
|
||||||
|
* @return 过滤后的旧的普通消息记录
|
||||||
|
*/
|
||||||
|
Page<MessageNewRes> pageMsgInfo(CmsMsgQueryReq request);
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package cn.axzo.msg.center.message.service;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.message.domain.dto.SendImMessageDTO;
|
||||||
|
import cn.axzo.msg.center.service.general.request.GeneralMessageOldDataStatisticRequest;
|
||||||
|
import cn.axzo.msg.center.service.general.request.GeneralMessageSendRequest;
|
||||||
|
import cn.axzo.msg.center.service.general.response.GeneralMessageOldDataStatisticResponse;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/19
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public interface GeneralMessageService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送消息
|
||||||
|
*
|
||||||
|
* @param request 消息所需参数
|
||||||
|
* @return 请求的唯一标识
|
||||||
|
*/
|
||||||
|
List<SendImMessageDTO> batchSendMessage(GeneralMessageSendRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计旧数据
|
||||||
|
*
|
||||||
|
* @param request 统计参数
|
||||||
|
* @return 旧数据的未读数以及最新一条消息
|
||||||
|
*/
|
||||||
|
GeneralMessageOldDataStatisticResponse statisticOldData(GeneralMessageOldDataStatisticRequest request);
|
||||||
|
}
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
package cn.axzo.msg.center.message.service;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.message.domain.param.MessageGroupNodeSaveOrUpdateParam;
|
||||||
|
import cn.axzo.msg.center.service.dto.GroupTreeNodeDTO;
|
||||||
|
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息分类结点管理
|
||||||
|
*
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/14
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public interface MessageGroupNodeService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类结点(叶结点)名称的路径
|
||||||
|
*
|
||||||
|
* @param groupNodeCodePaths 分类结点(叶结点)的编码列表
|
||||||
|
* @return 分类结点(叶结点)名称的路径
|
||||||
|
*/
|
||||||
|
Map<String, String> groupNodeNamePaths(Collection<String> groupNodeCodePaths);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类结点(叶结点)编码的路径
|
||||||
|
*
|
||||||
|
* @param leafGroupNodeCodes 分类结点(叶结点)的编码列表
|
||||||
|
* @return 分类结点(叶结点)编码的路径
|
||||||
|
*/
|
||||||
|
Map<String, String> leafGroupNodeCodePaths(Collection<String> leafGroupNodeCodes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据结点编码查询结点信息
|
||||||
|
*
|
||||||
|
* @param rootNodeCode 结点编码
|
||||||
|
* @return 结点信息
|
||||||
|
*/
|
||||||
|
Optional<GroupTreeNodeDTO> queryRootNode(String rootNodeCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增结点
|
||||||
|
*
|
||||||
|
* @param param 结点内容
|
||||||
|
*/
|
||||||
|
void addGroupNode(MessageGroupNodeSaveOrUpdateParam param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑结点
|
||||||
|
*
|
||||||
|
* @param param 结点内容
|
||||||
|
*/
|
||||||
|
void updateGroupNode(MessageGroupNodeSaveOrUpdateParam param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除结点
|
||||||
|
*
|
||||||
|
* @param operatorId 操作人id
|
||||||
|
* @param nodeCode 待删除结点的编码
|
||||||
|
*/
|
||||||
|
void deleteGroupNode(Long operatorId, String nodeCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询消息/待办 或者两者的分类树
|
||||||
|
* @param category 消息/待办
|
||||||
|
* @return 分类树列表
|
||||||
|
*/
|
||||||
|
List<GroupTreeNodeDTO> listGroupTree(MessageCategoryEnum category);
|
||||||
|
}
|
||||||
@ -1,41 +0,0 @@
|
|||||||
package cn.axzo.msg.center.message.service;
|
|
||||||
|
|
||||||
import cn.axzo.msg.center.message.domain.dto.MessageGroupNodeDTO;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息分类管理
|
|
||||||
*
|
|
||||||
* @author cold_blade
|
|
||||||
* @date 2023/9/20
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
public interface MessageGroupService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过结点编码查询结点信息
|
|
||||||
*
|
|
||||||
* @param nodeCode 结点编码
|
|
||||||
* @return 结点信息
|
|
||||||
*/
|
|
||||||
Optional<MessageGroupNodeDTO> queryByNodeCode(String nodeCode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询指定结点的字节的信息
|
|
||||||
*
|
|
||||||
* @param nodeCode 指定结点编码
|
|
||||||
* @return 子节点列表信息
|
|
||||||
*/
|
|
||||||
List<MessageGroupNodeDTO> listChildren(String nodeCode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 模板关联分类
|
|
||||||
*
|
|
||||||
* @param templateNode 模板编码
|
|
||||||
* @param pathList 分类path列表
|
|
||||||
*/
|
|
||||||
void templateGroup(String templateNode, Collection<String> pathList);
|
|
||||||
}
|
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
package cn.axzo.msg.center.message.service;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.message.domain.dto.GroupTreeNodePathDTO;
|
||||||
|
import cn.axzo.msg.center.service.dto.GroupTreeNodeDTO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息分类树节点缓存管理
|
||||||
|
*
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/14
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public interface MessageGroupTreeNodeCacheService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有有效的分类结点树
|
||||||
|
*
|
||||||
|
* @return 树列表
|
||||||
|
*/
|
||||||
|
List<GroupTreeNodeDTO> listAllGroupTree();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定结点所在的树的根节点
|
||||||
|
*
|
||||||
|
* @param rootNodeCode 结点编码
|
||||||
|
* @return 根节点
|
||||||
|
*/
|
||||||
|
Optional<GroupTreeNodeDTO> queryRootNode(String rootNodeCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据结点编码查询结点信息
|
||||||
|
*
|
||||||
|
* @param groupNodeCode 结点编码
|
||||||
|
* @return 结点信息
|
||||||
|
*/
|
||||||
|
Optional<GroupTreeNodeDTO> queryNode(String groupNodeCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取叶结点对应的树的路径
|
||||||
|
*
|
||||||
|
* @param leafNodeCode 叶结点编码
|
||||||
|
* @return 路径
|
||||||
|
*/
|
||||||
|
Optional<GroupTreeNodePathDTO> queryLeafNodePath(String leafNodeCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新缓存
|
||||||
|
*/
|
||||||
|
void refreshCache();
|
||||||
|
}
|
||||||
@ -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);
|
||||||
|
}
|
||||||
@ -1,6 +1,8 @@
|
|||||||
package cn.axzo.msg.center.message.service;
|
package cn.axzo.msg.center.message.service;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息模板分类管理
|
* 消息模板分类管理
|
||||||
@ -18,4 +20,61 @@ public interface MessageTemplateGroupService {
|
|||||||
* @return 模板编码列表
|
* @return 模板编码列表
|
||||||
*/
|
*/
|
||||||
List<String> listMessageTemplateCodes(String groupNodeCode);
|
List<String> listMessageTemplateCodes(String groupNodeCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板关联分类
|
||||||
|
*
|
||||||
|
* @param templateNode 模板编码
|
||||||
|
* @param groupNodeCodes 分类结点编码列表
|
||||||
|
*/
|
||||||
|
void templateGroup(String templateNode, Collection<String> groupNodeCodes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板关联分类
|
||||||
|
*
|
||||||
|
* @param templateGroupMap 模板编码与分类结点编码列表的map
|
||||||
|
*/
|
||||||
|
void templateGroup(Map<String, List<String>> templateGroupMap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新模板的分类关系
|
||||||
|
*
|
||||||
|
* @param templateNode 模板编码
|
||||||
|
* @param groupNodeCodes 新的模板的分类结点编码
|
||||||
|
*/
|
||||||
|
void updateTemplateGroup(String templateNode, Collection<String> groupNodeCodes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解除模板关联的分类
|
||||||
|
*
|
||||||
|
* @param templateNode 模板编码
|
||||||
|
*/
|
||||||
|
void deleteTemplateGroup(String templateNode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过消息模板编码查询其关联的分类的path
|
||||||
|
*
|
||||||
|
* @param templateCodes 消息模板编码集合
|
||||||
|
* @return 模板编码与分类的path列表的映射关系
|
||||||
|
*/
|
||||||
|
Map<String, List<String>> listMessageTemplateGroupPaths(Collection<String> templateCodes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解除模板与当前分类的关联关系
|
||||||
|
* 注:当模板只关联一个分类时,该关联关系不能解除
|
||||||
|
*
|
||||||
|
* @param curGroupNodeCode 当前分类结点的编码
|
||||||
|
* @param templateCodes 待解除关连关系的模板编码
|
||||||
|
*/
|
||||||
|
void remove(String curGroupNodeCode, Collection<String> templateCodes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解除模板与当前分类的关联关系
|
||||||
|
* 注:当模板只关联一个分类时,该关联关系不能解除
|
||||||
|
*
|
||||||
|
* @param srcGroupNodeCode 源分类结点的编码
|
||||||
|
* @param tgtGroupNodeCode 目标分类结点的编码
|
||||||
|
* @param templateCodes 待变更关连关系的模板编码
|
||||||
|
*/
|
||||||
|
void move(String srcGroupNodeCode, String tgtGroupNodeCode, Collection<String> templateCodes);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,15 @@
|
|||||||
package cn.axzo.msg.center.message.service;
|
package cn.axzo.msg.center.message.service;
|
||||||
|
|
||||||
import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO;
|
import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO;
|
||||||
import cn.axzo.msg.center.message.domain.param.MessageTemplateCreateParam;
|
import cn.axzo.msg.center.message.domain.param.MessageTemplateSaveOrUpdateParam;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageBaseTemplateDTO;
|
||||||
|
import cn.axzo.msg.center.service.enums.StatusEnum;
|
||||||
|
import cn.axzo.msg.center.service.template.request.MessageTemplatePageRequest;
|
||||||
|
import cn.axzo.msg.center.service.template.response.MessageTemplateDetailResponse;
|
||||||
|
import cn.axzo.msg.center.service.template.response.MessageTemplatePageResponse;
|
||||||
|
import cn.azxo.framework.common.model.Page;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@ -20,7 +27,31 @@ public interface MessageTemplateNewService {
|
|||||||
*
|
*
|
||||||
* @param param 模板内容参数
|
* @param param 模板内容参数
|
||||||
*/
|
*/
|
||||||
void createTemplate(MessageTemplateCreateParam param);
|
String createTemplate(MessageTemplateSaveOrUpdateParam param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑模板
|
||||||
|
*
|
||||||
|
* @param param 模板内容参数
|
||||||
|
*/
|
||||||
|
void updateTemplate(MessageTemplateSaveOrUpdateParam param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过模板便阿门查询模板详情
|
||||||
|
*
|
||||||
|
* @param templateCode 模板编码
|
||||||
|
* @return 模板详情信息
|
||||||
|
*/
|
||||||
|
MessageTemplateDetailResponse detail(String templateCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新模板状态
|
||||||
|
*
|
||||||
|
* @param operatorId 操作人id
|
||||||
|
* @param templateCode 模板编码
|
||||||
|
* @param status 新的模板状态
|
||||||
|
*/
|
||||||
|
void updateStatus(Long operatorId, String templateCode, StatusEnum status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过模板编码查询模板信息
|
* 通过模板编码查询模板信息
|
||||||
@ -37,4 +68,28 @@ public interface MessageTemplateNewService {
|
|||||||
* @return 模板信息
|
* @return 模板信息
|
||||||
*/
|
*/
|
||||||
List<MessageTemplateDTO> listByTemplateCodes(List<String> msgTemplateCodes);
|
List<MessageTemplateDTO> listByTemplateCodes(List<String> msgTemplateCodes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询模板数据
|
||||||
|
*
|
||||||
|
* @param request 分页请求参数
|
||||||
|
* @return 模板数据列表
|
||||||
|
*/
|
||||||
|
Page<MessageTemplatePageResponse> page(MessageTemplatePageRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询模板基础数据
|
||||||
|
*
|
||||||
|
* @param request 分页请求参数
|
||||||
|
* @return 模板数据列表
|
||||||
|
*/
|
||||||
|
Page<MessageBaseTemplateDTO> pageBaseTemplate(MessageTemplatePageRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过模板编码查询对应的模板
|
||||||
|
*
|
||||||
|
* @param templateCodes 模板编码集合
|
||||||
|
* @return 模板列表
|
||||||
|
*/
|
||||||
|
List<MessageTemplatePageResponse> listByCodes(Collection<String> templateCodes);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package cn.axzo.msg.center.message.service;
|
package cn.axzo.msg.center.message.service;
|
||||||
|
|
||||||
import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO;
|
import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -30,6 +31,14 @@ public interface MessageTemplateRouterService {
|
|||||||
*/
|
*/
|
||||||
void batchInsert(List<RawMessageRouterDTO> routers);
|
void batchInsert(List<RawMessageRouterDTO> routers);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新模板的路由信息
|
||||||
|
*
|
||||||
|
* @param templateCode 模板编码
|
||||||
|
* @param routers 路由列表
|
||||||
|
*/
|
||||||
|
void updateTemplateRoutes(String templateCode, List<MessageRouterButtonDTO> routers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据消息模板编码查询配置的路由列表
|
* 根据消息模板编码查询配置的路由列表
|
||||||
*
|
*
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
package cn.axzo.msg.center.message.service;
|
package cn.axzo.msg.center.message.service;
|
||||||
|
|
||||||
import cn.axzo.msg.center.message.domain.dto.MessageGroupNodeDTO;
|
import cn.axzo.msg.center.message.domain.dto.MessageGroupNodeStatisticDTO;
|
||||||
import cn.axzo.msg.center.message.domain.dto.PendingMessageDTO;
|
import cn.axzo.msg.center.message.domain.dto.PendingMessageDTO;
|
||||||
import cn.axzo.msg.center.message.domain.param.MessageGroupNodeStatisticParam;
|
import cn.axzo.msg.center.message.domain.param.MessageGroupNodeStatisticParam;
|
||||||
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
|
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
|
||||||
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
|
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
|
||||||
import cn.axzo.msg.center.service.pending.request.PendingMessagePageRequest;
|
import cn.axzo.msg.center.service.pending.request.PendingMessagePageRequest;
|
||||||
import cn.axzo.msg.center.service.pending.request.PendingMessagePushRequest;
|
|
||||||
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
|
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
|
||||||
import cn.azxo.framework.common.model.Page;
|
import cn.azxo.framework.common.model.Page;
|
||||||
|
|
||||||
@ -22,7 +21,7 @@ import java.util.Optional;
|
|||||||
*/
|
*/
|
||||||
public interface PendingMessageNewService {
|
public interface PendingMessageNewService {
|
||||||
|
|
||||||
List<MessageGroupNodeDTO> groupStatistic(MessageGroupNodeStatisticParam param);
|
List<MessageGroupNodeStatisticDTO> groupStatistic(MessageGroupNodeStatisticParam param);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 代办列表分页查询
|
* 代办列表分页查询
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
package cn.axzo.msg.center.message.service;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.message.domain.param.RelationTemplateMapInitParam;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
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);
|
||||||
|
|
||||||
|
void init(RelationTemplateMapInitParam param);
|
||||||
|
}
|
||||||
@ -0,0 +1,146 @@
|
|||||||
|
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.domain.dto.SendImMessageDTO;
|
||||||
|
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.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.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
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
|
||||||
|
public void asyncBatchSendMessage(GeneralMessageReq request, Map<Long, MessageRecord> toIdMessageRecordMap) {
|
||||||
|
log.info("do some check before send im message. relationId:[{}]", request.getRelationId());
|
||||||
|
if (MsgTypeEnum.PENDING_MESSAGE.equals(request.getType())) {
|
||||||
|
log.info("pending message is not supported.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Objects.isNull(request.getRelationId())) {
|
||||||
|
log.info("relation id is null.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (MapUtil.isEmpty(request.getToldIdPersonIdMap())) {
|
||||||
|
// 由于IM那边是根据personId来创建账户的,所以强依赖personId
|
||||||
|
log.info("toIdPersonIdMap is empty.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 异步发送IM消息
|
||||||
|
log.info("start to async send im message. relationId:[{}]", request.getRelationId());
|
||||||
|
CompletableFuture.runAsync(() -> doBatchSendMessage(request, toIdMessageRecordMap),
|
||||||
|
asyncSendMsgExecutorService);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doBatchSendMessage(GeneralMessageReq request, Map<Long, MessageRecord> toIdMessageRecordMap) {
|
||||||
|
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:[{}], templateCode:[{}]", request.getRelationId(), templateCode);
|
||||||
|
try {
|
||||||
|
// 发送IM消息
|
||||||
|
GeneralMessageSendRequest sendImMsgRequest = buildSendRequest(request, templateCode, toIdMessageRecordMap.keySet());
|
||||||
|
// IM消息的发送是基于personId+应用终端的(eg: 工人端/企业端)
|
||||||
|
List<SendImMessageDTO> result = generalMessageService.batchSendMessage(sendImMsgRequest);
|
||||||
|
if (CollectionUtils.isEmpty(result)) {
|
||||||
|
log.info("there is not any person successfully send im message. relationId:[{}]", request.getRelationId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 记录发送了IM消息的旧消息
|
||||||
|
recordSendImMessage(toIdMessageRecordMap, result, request.getToldIdPersonIdMap());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("broke out some exception while sending im message. relationId:[{}]", request.getRelationId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recordSendImMessage(Map<Long, MessageRecord> toIdMessageRecordMap, List<SendImMessageDTO> sendImResult,
|
||||||
|
Map<Long, Long> toIdPersonIdMap) {
|
||||||
|
// 成功发送了IM消息的personId集合
|
||||||
|
Set<Long> sucSendImMsgPersonIds = sendImResult.stream()
|
||||||
|
.map(SendImMessageDTO::getPersonId).collect(Collectors.toSet());
|
||||||
|
// 从入参中的toIdPersonIdMap中筛选发送成功的entry
|
||||||
|
Map<Long, Long> subToIdPersonIdMap = toIdPersonIdMap.entrySet().stream()
|
||||||
|
// 过滤掉personId维度IM消息发送失败的entry
|
||||||
|
.filter(e -> sucSendImMsgPersonIds.contains(e.getValue()))
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
|
Map<Long, Long> msgRecordIdPersonIdMap = toIdMessageRecordMap.entrySet().stream()
|
||||||
|
.filter(e -> subToIdPersonIdMap.containsKey(e.getKey()))
|
||||||
|
.collect(Collectors.toMap(e -> e.getValue().getId(), e -> subToIdPersonIdMap.get(e.getKey())));
|
||||||
|
log.info("record message that has been send im message. msgIds:{}", msgRecordIdPersonIdMap.keySet());
|
||||||
|
// 双发记录
|
||||||
|
messageSendTwiceRecordService.batchSave(msgRecordIdPersonIdMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GeneralMessageSendRequest buildSendRequest(GeneralMessageReq request, String templateCode,
|
||||||
|
Collection<Long> subReceiverIds) {
|
||||||
|
IdentityTypeEnum identityType = PersonIdentityUtil.toIdentityType(request.getReceiveType());
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
package cn.axzo.msg.center.message.service.impl;
|
||||||
|
|
||||||
|
import cn.axzo.basics.common.util.AssertUtil;
|
||||||
|
import cn.axzo.core.domain.PageResult;
|
||||||
|
import cn.axzo.msg.center.api.enums.MsgStateEnum;
|
||||||
|
import cn.axzo.msg.center.api.enums.MsgTypeEnum;
|
||||||
|
import cn.axzo.msg.center.api.request.CmsMsgQueryReq;
|
||||||
|
import cn.axzo.msg.center.api.response.MessageNewRes;
|
||||||
|
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
|
||||||
|
import cn.axzo.msg.center.common.utils.PageHelperUtil;
|
||||||
|
import cn.axzo.msg.center.dal.MessageRecordDao;
|
||||||
|
import cn.axzo.msg.center.domain.entity.MessageRecord;
|
||||||
|
import cn.axzo.msg.center.domain.enums.ModuleBizTypeEnum;
|
||||||
|
import cn.axzo.msg.center.inside.notices.service.MessageCoreService;
|
||||||
|
import cn.axzo.msg.center.inside.notices.service.MessageModuleService;
|
||||||
|
import cn.axzo.msg.center.inside.notices.service.MessageRelationService;
|
||||||
|
import cn.axzo.msg.center.message.service.GeneralMessageOldService;
|
||||||
|
import cn.axzo.msg.center.message.service.MessageSendTwiceRecordService;
|
||||||
|
import cn.axzo.msg.center.service.dto.PersonDTO;
|
||||||
|
import cn.axzo.msg.center.utils.PersonIdentityUtil;
|
||||||
|
import cn.azxo.framework.common.model.Page;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/24
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GeneralMessageOldServiceImpl implements GeneralMessageOldService {
|
||||||
|
|
||||||
|
private final MessageRecordDao messageRecordDao;
|
||||||
|
private final MessageCoreService messageCoreService;
|
||||||
|
private final MessageModuleService messageModuleService;
|
||||||
|
private final MessageRelationService messageRelationService;
|
||||||
|
private final MessageSendTwiceRecordService messageSendTwiceRecordService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countUnread(PersonDTO person) {
|
||||||
|
AssertUtil.isTrue(Objects.nonNull(person) && person.isValid(),
|
||||||
|
"session 异常, 无法执行消息统计查询!, person : " + person);
|
||||||
|
List<Long> sendTwiceMsgIds = messageSendTwiceRecordService.listByPerson(person.getId());
|
||||||
|
return countUnread(person, sendTwiceMsgIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countUnread(PersonDTO person, List<Long> excludeMsgIds) {
|
||||||
|
List<Long> moduleIds = messageModuleService.listModuleIdByBizType(ModuleBizTypeEnum.CONSTRUCTION);
|
||||||
|
List<Long> relationIds = messageRelationService.listRelationIds(moduleIds);
|
||||||
|
if (CollectionUtils.isEmpty(relationIds)) {
|
||||||
|
log.info("the is not any valid relation id.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return messageRecordDao.lambdaQuery()
|
||||||
|
.eq(MessageRecord::getType, MsgTypeEnum.GENERAL_MESSAGE)
|
||||||
|
.in(MessageRecord::getState, MsgStateEnum.unreadStates())
|
||||||
|
.eq(MessageRecord::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||||
|
.eq(MessageRecord::getToId, person.getIdentity().getId())
|
||||||
|
.eq(MessageRecord::getReceiveType, PersonIdentityUtil.toReceiveType(person.getIdentity().getType()))
|
||||||
|
.in(MessageRecord::getRelationId, relationIds)
|
||||||
|
// 排除双发记录表中的数据
|
||||||
|
.notIn(CollectionUtils.isNotEmpty(excludeMsgIds), MessageRecord::getId, excludeMsgIds)
|
||||||
|
.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<MessageNewRes> pageMsgInfo(CmsMsgQueryReq request) {
|
||||||
|
log.info("start to page query general message. request:{}", request);
|
||||||
|
if (CollectionUtils.isEmpty(request.getExcludeMsgIds())) {
|
||||||
|
request.setExcludeMsgIds(messageSendTwiceRecordService.listByPerson(request.getPersonId()));
|
||||||
|
}
|
||||||
|
PageResult<MessageNewRes> result = messageCoreService.listMsgInfo(request);
|
||||||
|
if (CollectionUtils.isEmpty(result.getData())) {
|
||||||
|
return PageHelperUtil.emptyPage(request.getPage(), request.getPageSize());
|
||||||
|
}
|
||||||
|
return Page.toPage(request.getPage(), request.getPageSize(), result.getTotalCount(), result.getData());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,232 @@
|
|||||||
|
package cn.axzo.msg.center.message.service.impl;
|
||||||
|
|
||||||
|
import cn.axzo.framework.domain.web.result.ApiResult;
|
||||||
|
import cn.axzo.im.center.api.feign.MessageApi;
|
||||||
|
import cn.axzo.im.center.api.vo.req.MessageInfo;
|
||||||
|
import cn.axzo.im.center.api.vo.resp.MessageDispatchResp;
|
||||||
|
import cn.axzo.im.center.common.enums.AppTypeEnum;
|
||||||
|
import cn.axzo.msg.center.api.request.CmsMsgQueryReq;
|
||||||
|
import cn.axzo.msg.center.api.response.MessageNewRes;
|
||||||
|
import cn.axzo.msg.center.common.exception.ServiceException;
|
||||||
|
import cn.axzo.msg.center.common.utils.PlaceholderResolver;
|
||||||
|
import cn.axzo.msg.center.dal.GeneralMessageRecordDao;
|
||||||
|
import cn.axzo.msg.center.domain.entity.GeneralMessageRecord;
|
||||||
|
import cn.axzo.msg.center.domain.enums.UserTypeEnum;
|
||||||
|
import cn.axzo.msg.center.inside.notices.config.MessageSystemConfig;
|
||||||
|
import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO;
|
||||||
|
import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO;
|
||||||
|
import cn.axzo.msg.center.message.domain.dto.SendImMessageDTO;
|
||||||
|
import cn.axzo.msg.center.message.domain.vo.GeneralMessagePushVO;
|
||||||
|
import cn.axzo.msg.center.message.service.GeneralMessageOldService;
|
||||||
|
import cn.axzo.msg.center.message.service.GeneralMessageService;
|
||||||
|
import cn.axzo.msg.center.message.service.MessageSendTwiceRecordService;
|
||||||
|
import cn.axzo.msg.center.message.service.MessageTemplateNewService;
|
||||||
|
import cn.axzo.msg.center.service.dto.IdentityDTO;
|
||||||
|
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.IdentityTypeEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
|
||||||
|
import cn.axzo.msg.center.service.general.request.GeneralMessageOldDataStatisticRequest;
|
||||||
|
import cn.axzo.msg.center.service.general.request.GeneralMessageSendRequest;
|
||||||
|
import cn.axzo.msg.center.service.general.response.GeneralMessageOldDataStatisticResponse;
|
||||||
|
import cn.axzo.msg.center.utils.MessageRouterUtil;
|
||||||
|
import cn.axzo.msg.center.utils.PersonIdentityUtil;
|
||||||
|
import cn.axzo.msg.center.utils.UUIDUtil;
|
||||||
|
import cn.azxo.framework.common.model.Page;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/19
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GeneralMessageServiceImpl implements GeneralMessageService {
|
||||||
|
|
||||||
|
private static final PersonDTO SYSTEM_SENDER = PersonDTO.builder()
|
||||||
|
.id(0L)
|
||||||
|
.identity(IdentityDTO.builder().id(0L).type(IdentityTypeEnum.NOT_SUPPORT).build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
private static final ImmutableMap<PushTerminalEnum, AppTypeEnum> PUSH_TERMINAL_APP_MAP = ImmutableMap.of(
|
||||||
|
PushTerminalEnum.B_ENTERPRISE_APP, AppTypeEnum.CMP,
|
||||||
|
PushTerminalEnum.C_WORKER_APP, AppTypeEnum.CM
|
||||||
|
);
|
||||||
|
|
||||||
|
private final MessageApi messageApi;
|
||||||
|
private final MessageSystemConfig messageSystemConfig;
|
||||||
|
private final GeneralMessageRecordDao generalMessageRecordDao;
|
||||||
|
private final GeneralMessageOldService generalMessageOldService;
|
||||||
|
private final MessageTemplateNewService messageTemplateNewService;
|
||||||
|
private final MessageSendTwiceRecordService messageSendTwiceRecordService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
||||||
|
public List<SendImMessageDTO> batchSendMessage(GeneralMessageSendRequest request) {
|
||||||
|
// 查询模板基础信息
|
||||||
|
MessageTemplateDTO template = messageTemplateNewService.queryByTemplateCode(request.getTemplateCode())
|
||||||
|
.orElseThrow(() -> new ServiceException("未查询到对应的模板"));
|
||||||
|
// 构建消息记录并存储
|
||||||
|
List<GeneralMessageRecord> messageRecords = buildMessageRecord(request, template);
|
||||||
|
generalMessageRecordDao.saveBatch(messageRecords);
|
||||||
|
// 发送IM消息
|
||||||
|
return pushImMessage(messageRecords, template);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GeneralMessageOldDataStatisticResponse statisticOldData(GeneralMessageOldDataStatisticRequest request) {
|
||||||
|
// 查询双发的消息记录
|
||||||
|
List<Long> sendTwiceMsgIds = messageSendTwiceRecordService.listByPerson(request.getPersonId());
|
||||||
|
// 分页查询最新一条数据
|
||||||
|
Page<MessageNewRes> result = generalMessageOldService.pageMsgInfo(build(request, sendTwiceMsgIds));
|
||||||
|
// 统计旧的未读普通消息数量
|
||||||
|
int count = generalMessageOldService.countUnread(PersonDTO.from(request.getPersonId(), request.getIdentityId(),
|
||||||
|
request.getIdentityType()), sendTwiceMsgIds);
|
||||||
|
// 编排组合成界面展示的数据结构
|
||||||
|
MessageNewRes msg = CollectionUtils.isNotEmpty(result.getList()) ? result.getList().get(0) : null;
|
||||||
|
return GeneralMessageOldDataStatisticResponse.builder()
|
||||||
|
.unreadCount(count)
|
||||||
|
.latestMsgSendTimestamp(Optional.ofNullable(msg).map(v -> v.getCreateAt().getTime()).orElse(null))
|
||||||
|
.latestMsgContent(Optional.ofNullable(msg).map(MessageNewRes::getContent).orElse(null))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
PersonDTO sender = Objects.isNull(request.getSender()) ? SYSTEM_SENDER : request.getSender();
|
||||||
|
return GeneralMessageRecord.builder()
|
||||||
|
.identityCode(UUIDUtil.uuidString())
|
||||||
|
.senderPersonId(sender.getId())
|
||||||
|
.senderId(sender.getIdentity().getId())
|
||||||
|
.senderType(sender.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()))
|
||||||
|
.orgType(request.getOrgType())
|
||||||
|
.orgId(request.getOrgId())
|
||||||
|
.orgName(request.getOrgName())
|
||||||
|
.state(GeneralMessageStateEnum.HAS_BEEN_SENT)
|
||||||
|
.bizCode(request.getBizCode())
|
||||||
|
.routerParams(request.getRouterParams())
|
||||||
|
.bizExtParams(request.getBizExtParams())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<SendImMessageDTO> pushImMessage(List<GeneralMessageRecord> messageRecords, MessageTemplateDTO template) {
|
||||||
|
if (CollectionUtils.isEmpty(template.getPushTerminals())) {
|
||||||
|
// 模板未配置任何推送终端
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
msgInfo.setToPersonIdList(Sets.newHashSet(messageRecords.stream()
|
||||||
|
.map(e -> String.valueOf(e.getReceiverPersonId()))
|
||||||
|
.collect(Collectors.toSet())));
|
||||||
|
msgInfo.setMsgHeader(record.getTitle());
|
||||||
|
msgInfo.setMsgContent(record.getContent());
|
||||||
|
msgInfo.setMsgTemplateId(record.getTemplateCode());
|
||||||
|
msgInfo.setMsgTemplateContent(JSON.toJSONString(message));
|
||||||
|
// 扩展信息
|
||||||
|
Map<String, String> ext = new HashMap<>();
|
||||||
|
ext.put("minAppVersion", template.getMinAppVersion());
|
||||||
|
if (Objects.nonNull(record.getOrgId()) && record.getOrgId() > 0L) {
|
||||||
|
ext.put("workspaceId", record.getOrgId().toString());
|
||||||
|
}
|
||||||
|
msgInfo.setExtendsInfo(ext);
|
||||||
|
|
||||||
|
ApiResult<List<MessageDispatchResp>> result = messageApi.sendMessage(msgInfo);
|
||||||
|
if (result.isError() || CollectionUtils.isEmpty(result.getData())) {
|
||||||
|
log.warn("failed to batch send im message. result:{}", result);
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return result.getData().stream()
|
||||||
|
.map(SendImMessageDTO::from)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private GeneralMessagePushVO convert(GeneralMessageRecord record, MessageTemplateDTO template) {
|
||||||
|
// 对应模板的路由列表
|
||||||
|
List<RawMessageRouterDTO> rawRouters = template.getRouters();
|
||||||
|
// 解析路由地址
|
||||||
|
List<RawMessageRouterDTO> routers = rawRouters.stream()
|
||||||
|
.map(e -> MessageRouterUtil.parseAndConcatRouteUrl(e, record.getRouterParams()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
// 转化成客户端展示的数据模型
|
||||||
|
List<MessageRouterButtonDTO> routerButtons = routers.stream()
|
||||||
|
.map(RawMessageRouterDTO::toMessageRouterButton)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
// 获取模板卡片信息
|
||||||
|
List<MessageCardContentItemDTO> rawCardContentItems = template.getMsgCardContentItems();
|
||||||
|
List<MessageCardContentItemDTO> cardContentItems = rawCardContentItems;
|
||||||
|
if (CollectionUtils.isNotEmpty(rawCardContentItems) && Objects.nonNull(record.getBizExtParams())
|
||||||
|
&& !record.getBizExtParams().isEmpty()) {
|
||||||
|
// 克隆,避免修改入参
|
||||||
|
cardContentItems = cardContentItems.stream()
|
||||||
|
.map(MessageCardContentItemDTO::deepClone)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
cardContentItems.forEach(e -> {
|
||||||
|
String value = PlaceholderResolver.getDefaultResolver()
|
||||||
|
.resolveByMap(e.getValue(), record.getBizExtParams());
|
||||||
|
e.setValue(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return GeneralMessagePushVO.from(record, template.getIcon(), messageSystemConfig.getOrgIcon(), routerButtons, cardContentItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseString(String string, JSONObject params) {
|
||||||
|
if (Objects.isNull(params)) {
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
return PlaceholderResolver.getDefaultResolver().resolveByMap(string, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CmsMsgQueryReq build(GeneralMessageOldDataStatisticRequest request, List<Long> excludeMsgIds) {
|
||||||
|
UserTypeEnum userType = PersonIdentityUtil.toUserType(request.getIdentityType());
|
||||||
|
CmsMsgQueryReq req = new CmsMsgQueryReq();
|
||||||
|
req.setMsgType(MessageCategoryEnum.GENERAL_MESSAGE.getCode());
|
||||||
|
// 这里查询消息中心全部状态的数据
|
||||||
|
req.setMsgStatus(0);
|
||||||
|
req.setPage(1L);
|
||||||
|
req.setPageSize(1L);
|
||||||
|
req.setPersonId(request.getPersonId());
|
||||||
|
req.setIdentityId(request.getIdentityId());
|
||||||
|
req.setUserType(userType.getValue());
|
||||||
|
req.setExcludeMsgIds(excludeMsgIds);
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,168 @@
|
|||||||
|
package cn.axzo.msg.center.message.service.impl;
|
||||||
|
|
||||||
|
import cn.axzo.basics.common.util.AssertUtil;
|
||||||
|
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
|
||||||
|
import cn.axzo.msg.center.common.exception.ServiceException;
|
||||||
|
import cn.axzo.msg.center.dal.MessageGroupNodeDao;
|
||||||
|
import cn.axzo.msg.center.dal.MessageTemplateGroupDao;
|
||||||
|
import cn.axzo.msg.center.domain.entity.MessageGroupNode;
|
||||||
|
import cn.axzo.msg.center.domain.entity.MessageTemplateGroup;
|
||||||
|
import cn.axzo.msg.center.message.domain.dto.GroupTreeNodePathDTO;
|
||||||
|
import cn.axzo.msg.center.message.domain.param.MessageGroupNodeSaveOrUpdateParam;
|
||||||
|
import cn.axzo.msg.center.message.service.MessageGroupNodeService;
|
||||||
|
import cn.axzo.msg.center.message.service.MessageGroupTreeNodeCacheService;
|
||||||
|
import cn.axzo.msg.center.service.dto.GroupTreeNodeDTO;
|
||||||
|
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
|
||||||
|
import cn.axzo.msg.center.utils.TreeHelperUtil;
|
||||||
|
import cn.axzo.msg.center.utils.UUIDUtil;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/14
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class MessageGroupNodeServiceImpl implements MessageGroupNodeService {
|
||||||
|
|
||||||
|
private final MessageGroupNodeDao messageGroupNodeDao;
|
||||||
|
private final MessageTemplateGroupDao messageTemplateGroupDao;
|
||||||
|
private final MessageGroupTreeNodeCacheService messageGroupTreeNodeCacheService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> groupNodeNamePaths(Collection<String> groupNodeCodePaths) {
|
||||||
|
if (CollectionUtils.isEmpty(groupNodeCodePaths)) {
|
||||||
|
log.info("leafGroupNodeCodes is empty.");
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
return groupNodeCodePaths.stream()
|
||||||
|
.map(GroupTreeNodePathDTO::parseLeafNodeCode)
|
||||||
|
.map(messageGroupTreeNodeCacheService::queryLeafNodePath)
|
||||||
|
.filter(Optional::isPresent)
|
||||||
|
.map(Optional::get)
|
||||||
|
.collect(Collectors.toMap(GroupTreeNodePathDTO::getNodeCodePath,
|
||||||
|
GroupTreeNodePathDTO::getNodeNamePath, (cur, pre) -> cur));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> leafGroupNodeCodePaths(Collection<String> leafGroupNodeCodes) {
|
||||||
|
if (CollectionUtils.isEmpty(leafGroupNodeCodes)) {
|
||||||
|
log.info("leafGroupNodeCodes is empty.");
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
return leafGroupNodeCodes.stream()
|
||||||
|
.map(messageGroupTreeNodeCacheService::queryLeafNodePath)
|
||||||
|
.filter(Optional::isPresent)
|
||||||
|
.map(Optional::get)
|
||||||
|
.collect(Collectors.toMap(GroupTreeNodePathDTO::getNodeCode,
|
||||||
|
GroupTreeNodePathDTO::getNodeCodePath, (cur, pre) -> cur));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<GroupTreeNodeDTO> queryRootNode(String rootNodeCode) {
|
||||||
|
return messageGroupTreeNodeCacheService.queryRootNode(rootNodeCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addGroupNode(MessageGroupNodeSaveOrUpdateParam param) {
|
||||||
|
GroupTreeNodeDTO parent = StringUtils.isBlank(param.getParentNodeCode()) ? null :
|
||||||
|
messageGroupTreeNodeCacheService.queryNode(param.getParentNodeCode())
|
||||||
|
.orElseThrow(() -> new ServiceException("parentNodeCode is invalid"));
|
||||||
|
// 合法性校验
|
||||||
|
checkCreateRule(parent, param);
|
||||||
|
// 存储
|
||||||
|
messageGroupNodeDao.save(convert(param));
|
||||||
|
// 刷新缓存
|
||||||
|
messageGroupTreeNodeCacheService.refreshCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateGroupNode(MessageGroupNodeSaveOrUpdateParam param) {
|
||||||
|
boolean updateResult = messageGroupNodeDao.lambdaUpdate()
|
||||||
|
.eq(MessageGroupNode::getCode, param.getNodeCode())
|
||||||
|
.eq(MessageGroupNode::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||||
|
.set(StringUtils.isNotBlank(param.getNodeName()), MessageGroupNode::getName, param.getNodeName())
|
||||||
|
.set(StringUtils.isNotBlank(param.getIcon()), MessageGroupNode::getIcon, param.getIcon())
|
||||||
|
.set(MessageGroupNode::getUpdaterId, param.getOperatorId())
|
||||||
|
.update();
|
||||||
|
if (updateResult) {
|
||||||
|
// 刷新缓存
|
||||||
|
messageGroupTreeNodeCacheService.refreshCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteGroupNode(Long operatorId, String nodeCode) {
|
||||||
|
if (Objects.isNull(operatorId) || StringUtils.isBlank(nodeCode)) {
|
||||||
|
log.info("the param is invalid. operatorId:[{}], nodeCode:[{}]", operatorId, nodeCode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 合法性校验
|
||||||
|
checkDeleteRule(nodeCode);
|
||||||
|
// 删除结点
|
||||||
|
boolean removeResult = messageGroupNodeDao.lambdaUpdate()
|
||||||
|
.eq(MessageGroupNode::getCode, nodeCode)
|
||||||
|
.remove();
|
||||||
|
if (removeResult) {
|
||||||
|
// 刷新缓存
|
||||||
|
messageGroupTreeNodeCacheService.refreshCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<GroupTreeNodeDTO> listGroupTree(MessageCategoryEnum category) {
|
||||||
|
return messageGroupTreeNodeCacheService.listAllGroupTree().stream()
|
||||||
|
// 查询消息/待办 OR 两者的分类树
|
||||||
|
.filter(e -> Objects.isNull(category)
|
||||||
|
|| Objects.equals(e.getCategory().getMsgCategory(), category))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private MessageGroupNode convert(MessageGroupNodeSaveOrUpdateParam param) {
|
||||||
|
MessageGroupNode groupNode = new MessageGroupNode();
|
||||||
|
groupNode.setCode(UUIDUtil.uuidString());
|
||||||
|
groupNode.setName(param.getNodeName());
|
||||||
|
groupNode.setIcon(param.getIcon());
|
||||||
|
groupNode.setCategory(param.getCategory());
|
||||||
|
groupNode.setParentCode(param.getParentNodeCode());
|
||||||
|
groupNode.setCreatorId(param.getOperatorId());
|
||||||
|
groupNode.setUpdaterId(param.getOperatorId());
|
||||||
|
if (TreeHelperUtil.isLeafNodeCategory(param.getCategory())) {
|
||||||
|
groupNode.setIsLeaf(1);
|
||||||
|
}
|
||||||
|
return groupNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkCreateRule(GroupTreeNodeDTO parent, MessageGroupNodeSaveOrUpdateParam param) {
|
||||||
|
if (Objects.nonNull(parent)) {
|
||||||
|
AssertUtil.isTrue(parent.getCategory().getLevel() < param.getCategory().getLevel(), "父节点的类型非法");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkDeleteRule(String nodeCode) {
|
||||||
|
GroupTreeNodeDTO node = messageGroupTreeNodeCacheService.queryNode(nodeCode)
|
||||||
|
.orElseThrow(() -> new ServiceException(String.format("未找到指定的结点[%s]", nodeCode)));
|
||||||
|
// TODO: [cold_blade] [P2] 异常处理需要检查
|
||||||
|
AssertUtil.isEmpty(node.getNodeChildren(), "删除失败!删除前请删除子级!");
|
||||||
|
// 校验其结点是否被模板关联
|
||||||
|
int cnt = messageTemplateGroupDao.lambdaQuery()
|
||||||
|
.like(MessageTemplateGroup::getPath, nodeCode)
|
||||||
|
.eq(MessageTemplateGroup::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||||
|
.count();
|
||||||
|
AssertUtil.isTrue(cnt == 0, "删除失败!删除前请先转移消息模版!");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,70 +0,0 @@
|
|||||||
package cn.axzo.msg.center.message.service.impl;
|
|
||||||
|
|
||||||
import cn.axzo.msg.center.dal.MessageGroupNodeDao;
|
|
||||||
import cn.axzo.msg.center.dal.MessageTemplateGroupDao;
|
|
||||||
import cn.axzo.msg.center.domain.entity.MessageGroupNode;
|
|
||||||
import cn.axzo.msg.center.domain.entity.MessageTemplateGroup;
|
|
||||||
import cn.axzo.msg.center.message.domain.dto.MessageGroupNodeDTO;
|
|
||||||
import cn.axzo.msg.center.message.service.MessageGroupService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author cold_blade
|
|
||||||
* @date 2023/10/6
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class MessageGroupServiceImpl implements MessageGroupService {
|
|
||||||
|
|
||||||
private final MessageGroupNodeDao messageGroupNodeDao;
|
|
||||||
private final MessageTemplateGroupDao messageTemplateGroupDao;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<MessageGroupNodeDTO> queryByNodeCode(String nodeCode) {
|
|
||||||
if (StringUtils.isBlank(nodeCode)) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
MessageGroupNode groupNode = messageGroupNodeDao.lambdaQuery()
|
|
||||||
.eq(MessageGroupNode::getCode, nodeCode)
|
|
||||||
.eq(MessageGroupNode::getIsDelete, 0)
|
|
||||||
.one();
|
|
||||||
return Optional.ofNullable(groupNode).map(MessageGroupNodeDTO::from);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<MessageGroupNodeDTO> listChildren(String nodeCode) {
|
|
||||||
return messageGroupNodeDao.lambdaQuery()
|
|
||||||
.eq(MessageGroupNode::getParentCode, nodeCode)
|
|
||||||
.eq(MessageGroupNode::getIsDelete, 0)
|
|
||||||
.list().stream()
|
|
||||||
.map(MessageGroupNodeDTO::from)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void templateGroup(String templateNode, Collection<String> pathList) {
|
|
||||||
if (StringUtils.isBlank(templateNode)
|
|
||||||
|| CollectionUtils.isEmpty(pathList)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
List<MessageTemplateGroup> rows = pathList.stream()
|
|
||||||
.map(e -> {
|
|
||||||
MessageTemplateGroup group = new MessageTemplateGroup();
|
|
||||||
group.setTemplateCode(templateNode);
|
|
||||||
group.setPath(e);
|
|
||||||
return group;
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
messageTemplateGroupDao.saveBatch(rows);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,193 @@
|
|||||||
|
package cn.axzo.msg.center.message.service.impl;
|
||||||
|
|
||||||
|
import cn.axzo.basics.common.util.TreeUtil;
|
||||||
|
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
|
||||||
|
import cn.axzo.msg.center.common.redis.RedisUtil;
|
||||||
|
import cn.axzo.msg.center.dal.MessageGroupNodeDao;
|
||||||
|
import cn.axzo.msg.center.domain.entity.MessageGroupNode;
|
||||||
|
import cn.axzo.msg.center.message.domain.dto.GroupTreeNodePathDTO;
|
||||||
|
import cn.axzo.msg.center.message.service.MessageGroupTreeNodeCacheService;
|
||||||
|
import cn.axzo.msg.center.service.dto.GroupTreeNodeDTO;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.compress.utils.Lists;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/14
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNodeCacheService {
|
||||||
|
|
||||||
|
private static final String CACHE_KEY = "msg-center:message:group:cache-key";
|
||||||
|
private static final String CACHE_VALUE = "msg-center:message:group:cache-val";
|
||||||
|
private static final long CACHE_KEY_TIMEOUT_DAYS = 1;
|
||||||
|
|
||||||
|
private final RedisUtil redisUtil;
|
||||||
|
private final MessageGroupNodeDao messageGroupNodeDao;
|
||||||
|
|
||||||
|
private List<GroupTreeNodeDTO> allGroupTreesCache = Collections.emptyList();
|
||||||
|
private List<GroupTreeNodePathDTO> leafTreeNodePathsCache = Collections.emptyList();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<GroupTreeNodeDTO> listAllGroupTree() {
|
||||||
|
return getAllGroupTreesCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<GroupTreeNodeDTO> queryRootNode(String rootNodeCode) {
|
||||||
|
if (StringUtils.isBlank(rootNodeCode)) {
|
||||||
|
log.info("rootNodeCode is blank.");
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
return getAllGroupTreesCache().stream()
|
||||||
|
.filter(e -> Objects.equals(e.getNodeCode(), rootNodeCode))
|
||||||
|
.findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<GroupTreeNodeDTO> queryNode(String groupNodeCode) {
|
||||||
|
if (StringUtils.isBlank(groupNodeCode)) {
|
||||||
|
log.info("groupNodeCode is blank.");
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
return getAllGroupTreesCache().stream()
|
||||||
|
.map(e -> findTreeNode(e, groupNodeCode))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<GroupTreeNodePathDTO> queryLeafNodePath(String leafNodeCode) {
|
||||||
|
if (StringUtils.isBlank(leafNodeCode)) {
|
||||||
|
log.info("leafNodeCode is blank.");
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
return getLeafTreeNodePathsCache().stream()
|
||||||
|
.filter(e -> Objects.equals(e.getNodeCode(), leafNodeCode))
|
||||||
|
.findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void refreshCache() {
|
||||||
|
// 清除redis中的缓存标识
|
||||||
|
redisUtil.getKeyOps().delete(CACHE_KEY);
|
||||||
|
// 本地缓存初始化并更新redis中的缓存标识
|
||||||
|
initialize(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GroupTreeNodeDTO findTreeNode(GroupTreeNodeDTO root, String treeNodeCode) {
|
||||||
|
if (Objects.equals(root.getNodeCode(), treeNodeCode)) {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
LinkedList<GroupTreeNodeDTO> queue = new LinkedList<>(root.getNodeChildren());
|
||||||
|
while (!queue.isEmpty()) {
|
||||||
|
GroupTreeNodeDTO node = queue.pop();
|
||||||
|
Optional<GroupTreeNodeDTO> childOp = node.getChild(treeNodeCode);
|
||||||
|
if (childOp.isPresent()) {
|
||||||
|
return childOp.get();
|
||||||
|
}
|
||||||
|
queue.addAll(node.getNodeChildren());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<GroupTreeNodeDTO> getAllGroupTreesCache() {
|
||||||
|
if (redisUtil.getKeyOps().hasKey(CACHE_KEY)) {
|
||||||
|
// 其它结点进行了本地缓存,但是当前服务进程还未进行缓存
|
||||||
|
if (CollectionUtils.isEmpty(allGroupTreesCache)) {
|
||||||
|
// 本地缓存初始化,不更新redis中的缓存标识
|
||||||
|
initialize(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 本地缓存初始化并更新redis中的缓存标识
|
||||||
|
initialize(true);
|
||||||
|
}
|
||||||
|
return this.allGroupTreesCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<GroupTreeNodePathDTO> getLeafTreeNodePathsCache() {
|
||||||
|
if (redisUtil.getKeyOps().hasKey(CACHE_KEY)) {
|
||||||
|
// 其它结点进行了本地缓存,但是当前服务进程还未进行缓存
|
||||||
|
if (leafTreeNodePathsCache.isEmpty()) {
|
||||||
|
// 本地缓存初始化,不更新redis中的缓存标识
|
||||||
|
initialize(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 本地缓存初始化并更新redis中的缓存标识
|
||||||
|
initialize(true);
|
||||||
|
}
|
||||||
|
return leafTreeNodePathsCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void initialize(boolean refreshCache) {
|
||||||
|
List<GroupTreeNodeDTO> groupNodes = listAllValidNodesFromDB();
|
||||||
|
allGroupTreesCache = TreeUtil.buildTree(groupNodes);
|
||||||
|
leafTreeNodePathsCache = allGroupTreesCache.stream()
|
||||||
|
.flatMap(e -> parseRootNode(e).stream())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (refreshCache) {
|
||||||
|
redisUtil.getStringOps().setIfAbsent(CACHE_KEY, CACHE_VALUE, CACHE_KEY_TIMEOUT_DAYS, TimeUnit.DAYS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<GroupTreeNodeDTO> listAllValidNodesFromDB() {
|
||||||
|
return messageGroupNodeDao.lambdaQuery()
|
||||||
|
.eq(MessageGroupNode::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||||
|
.list().stream()
|
||||||
|
.map(this::convert)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private GroupTreeNodeDTO convert(MessageGroupNode groupNode) {
|
||||||
|
return GroupTreeNodeDTO.builder()
|
||||||
|
.nodeName(groupNode.getName())
|
||||||
|
.nodeCode(groupNode.getCode())
|
||||||
|
.category(groupNode.getCategory())
|
||||||
|
.parentNodeCode(groupNode.getParentCode())
|
||||||
|
.isLeaf(groupNode.getIsLeaf())
|
||||||
|
.status(groupNode.getStatus())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<GroupTreeNodePathDTO> parseRootNode(GroupTreeNodeDTO root) {
|
||||||
|
List<GroupTreeNodePathDTO> paths = Lists.newArrayList();
|
||||||
|
LinkedList<GroupTreeNodeDTO> pathNodeStack = new LinkedList<>();
|
||||||
|
LinkedList<GroupTreeNodeDTO> stack = new LinkedList<>();
|
||||||
|
stack.push(root);
|
||||||
|
while (!stack.isEmpty()) {
|
||||||
|
GroupTreeNodeDTO node = stack.pop();
|
||||||
|
pathNodeStack.push(node);
|
||||||
|
if (CollectionUtils.isEmpty(node.getNodeChildren())) {
|
||||||
|
// 当前结点为树的叶结点(逻辑上的,有可能不是业务维度的叶结点)
|
||||||
|
paths.add(GroupTreeNodePathDTO.of(node.getNodeCode(), reverseStack(pathNodeStack)));
|
||||||
|
pathNodeStack.pop();
|
||||||
|
} else {
|
||||||
|
stack.addAll(node.getNodeChildren());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<GroupTreeNodeDTO> reverseStack(LinkedList<GroupTreeNodeDTO> pathNodeStack) {
|
||||||
|
List<GroupTreeNodeDTO> list = Lists.newArrayList();
|
||||||
|
for (GroupTreeNodeDTO node : pathNodeStack) {
|
||||||
|
list.add(0, node);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
package cn.axzo.msg.center.message.service.impl;
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
return messageSendTwiceRecordDao.lambdaQuery()
|
||||||
|
.eq(MessageSendTwiceRecord::getReceiverPersonId, personId)
|
||||||
|
.last("LIMIT 500")
|
||||||
|
.orderByDesc(MessageSendTwiceRecord::getId)
|
||||||
|
.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,15 +1,26 @@
|
|||||||
package cn.axzo.msg.center.message.service.impl;
|
package cn.axzo.msg.center.message.service.impl;
|
||||||
|
|
||||||
|
import cn.axzo.basics.common.util.AssertUtil;
|
||||||
|
import cn.axzo.framework.core.util.MapUtil;
|
||||||
|
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
|
||||||
import cn.axzo.msg.center.dal.MessageTemplateGroupDao;
|
import cn.axzo.msg.center.dal.MessageTemplateGroupDao;
|
||||||
import cn.axzo.msg.center.domain.entity.MessageTemplateGroup;
|
import cn.axzo.msg.center.domain.entity.MessageTemplateGroup;
|
||||||
|
import cn.axzo.msg.center.message.service.MessageGroupNodeService;
|
||||||
import cn.axzo.msg.center.message.service.MessageTemplateGroupService;
|
import cn.axzo.msg.center.message.service.MessageTemplateGroupService;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,6 +33,7 @@ import java.util.stream.Collectors;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupService {
|
public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupService {
|
||||||
|
|
||||||
|
private final MessageGroupNodeService messageGroupNodeService;
|
||||||
private final MessageTemplateGroupDao messageTemplateGroupDao;
|
private final MessageTemplateGroupDao messageTemplateGroupDao;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -37,4 +49,138 @@ public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupServ
|
|||||||
.map(MessageTemplateGroup::getTemplateCode)
|
.map(MessageTemplateGroup::getTemplateCode)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void templateGroup(String templateNode, Collection<String> groupNodeCodes) {
|
||||||
|
if (StringUtils.isBlank(templateNode)
|
||||||
|
|| CollectionUtils.isEmpty(groupNodeCodes)) {
|
||||||
|
log.info("the param is invalid. templateNode:[{}], groupNodeCodes:{}", templateNode, groupNodeCodes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<String, String> pathMap = messageGroupNodeService.leafGroupNodeCodePaths(groupNodeCodes);
|
||||||
|
List<MessageTemplateGroup> rows = groupNodeCodes.stream()
|
||||||
|
.filter(pathMap::containsKey)
|
||||||
|
.map(e -> {
|
||||||
|
MessageTemplateGroup group = new MessageTemplateGroup();
|
||||||
|
group.setTemplateCode(templateNode);
|
||||||
|
group.setPath(pathMap.get(e));
|
||||||
|
return group;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
messageTemplateGroupDao.saveBatch(rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void templateGroup(Map<String, List<String>> templateGroupMap) {
|
||||||
|
if (MapUtil.isEmpty(templateGroupMap)) {
|
||||||
|
log.info("the templateGroupMap is empty.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Set<String> groupNodes = templateGroupMap.values().stream()
|
||||||
|
.flatMap(Collection::stream)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
Map<String, String> pathMap = messageGroupNodeService.leafGroupNodeCodePaths(groupNodes);
|
||||||
|
List<MessageTemplateGroup> rows = templateGroupMap.entrySet().stream()
|
||||||
|
.flatMap(e -> e.getValue().stream()
|
||||||
|
.filter(pathMap::containsKey)
|
||||||
|
.map(nodeCode -> {
|
||||||
|
MessageTemplateGroup group = new MessageTemplateGroup();
|
||||||
|
group.setTemplateCode(e.getKey());
|
||||||
|
group.setPath(pathMap.get(nodeCode));
|
||||||
|
return group;
|
||||||
|
})
|
||||||
|
).collect(Collectors.toList());
|
||||||
|
messageTemplateGroupDao.saveBatch(rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateTemplateGroup(String templateNode, Collection<String> groupNodeCodes) {
|
||||||
|
// 先解除之前的关联关系
|
||||||
|
deleteTemplateGroup(templateNode);
|
||||||
|
// 构建新的关联关系
|
||||||
|
templateGroup(templateNode, groupNodeCodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteTemplateGroup(String templateNode) {
|
||||||
|
if (StringUtils.isBlank(templateNode)) {
|
||||||
|
log.info("the templateNode is blank.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
messageTemplateGroupDao.lambdaUpdate()
|
||||||
|
.eq(MessageTemplateGroup::getTemplateCode, templateNode)
|
||||||
|
.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, List<String>> listMessageTemplateGroupPaths(Collection<String> templateCodes) {
|
||||||
|
if (CollectionUtils.isEmpty(templateCodes)) {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
return messageTemplateGroupDao.lambdaQuery()
|
||||||
|
.in(MessageTemplateGroup::getTemplateCode, templateCodes)
|
||||||
|
.eq(MessageTemplateGroup::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||||
|
.list().stream()
|
||||||
|
.collect(Collectors.groupingBy(MessageTemplateGroup::getTemplateCode,
|
||||||
|
Collectors.mapping(MessageTemplateGroup::getPath, Collectors.toList())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove(String curGroupNodeCode, Collection<String> templateCodes) {
|
||||||
|
// 参数校验
|
||||||
|
AssertUtil.isTrue(StringUtils.isNotBlank(curGroupNodeCode), "curGroupNodeCode can not be blank");
|
||||||
|
AssertUtil.notEmpty(templateCodes, "templateCodes can not be empty");
|
||||||
|
// 通过分类结点编码获取其对应的结点编码的路径
|
||||||
|
Map<String, String> nodeCodePathMap = messageGroupNodeService
|
||||||
|
.leafGroupNodeCodePaths(Lists.newArrayList(curGroupNodeCode));
|
||||||
|
// 通过能否成功获取到其树路径来校验其有效性
|
||||||
|
AssertUtil.isFalse(nodeCodePathMap.isEmpty(), "curGroupNodeCode is invalid");
|
||||||
|
// 统计指定的模板编码关联的分类数量
|
||||||
|
Map<String, Long> templateCodeList = messageTemplateGroupDao.lambdaQuery()
|
||||||
|
.in(MessageTemplateGroup::getTemplateCode, templateCodes)
|
||||||
|
.eq(MessageTemplateGroup::getPath, nodeCodePathMap.get(curGroupNodeCode))
|
||||||
|
.eq(MessageTemplateGroup::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||||
|
// 这里仅查询模板编码字段即可
|
||||||
|
.select(MessageTemplateGroup::getTemplateCode)
|
||||||
|
.list().stream()
|
||||||
|
.map(MessageTemplateGroup::getTemplateCode)
|
||||||
|
// 内存中来做groupingBy操作
|
||||||
|
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
|
||||||
|
// 筛选出仅关联了一个分类的模板编码
|
||||||
|
List<String> onlyContainsOneTemplateCodes = templateCodeList.entrySet().stream()
|
||||||
|
.filter(e -> Objects.equals(e.getValue(), 1L))
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
AssertUtil.isEmpty(onlyContainsOneTemplateCodes, removeErrorStr(onlyContainsOneTemplateCodes));
|
||||||
|
// 解除关联关系
|
||||||
|
messageTemplateGroupDao.lambdaUpdate()
|
||||||
|
.in(MessageTemplateGroup::getTemplateCode, templateCodes)
|
||||||
|
.eq(MessageTemplateGroup::getPath, nodeCodePathMap.get(curGroupNodeCode))
|
||||||
|
.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void move(String srcGroupNodeCode, String tgtGroupNodeCode, Collection<String> templateCodes) {
|
||||||
|
// 参数校验
|
||||||
|
AssertUtil.isTrue(StringUtils.isNotBlank(srcGroupNodeCode), "srcGroupNodeCode can not be blank");
|
||||||
|
AssertUtil.isTrue(StringUtils.isNotBlank(tgtGroupNodeCode), "tgtGroupNodeCode can not be blank");
|
||||||
|
AssertUtil.notEmpty(templateCodes, "templateCodes can not be empty");
|
||||||
|
// 通过分类结点编码获取其对应的结点编码的路径
|
||||||
|
Map<String, String> nodeCodePathMap = messageGroupNodeService
|
||||||
|
.leafGroupNodeCodePaths(Lists.newArrayList(srcGroupNodeCode, tgtGroupNodeCode));
|
||||||
|
// 通过能否成功获取到其树路径来校验其有效性
|
||||||
|
AssertUtil.isTrue(StringUtils.isNotBlank(nodeCodePathMap.get(srcGroupNodeCode)), "srcGroupNodeCode is invalid");
|
||||||
|
AssertUtil.isTrue(StringUtils.isNotBlank(nodeCodePathMap.get(tgtGroupNodeCode)), "tgtGroupNodeCode is invalid");
|
||||||
|
// 更新分类路径与模板编码的映射关系
|
||||||
|
messageTemplateGroupDao.lambdaUpdate()
|
||||||
|
.eq(MessageTemplateGroup::getPath, nodeCodePathMap.get(srcGroupNodeCode))
|
||||||
|
.in(MessageTemplateGroup::getTemplateCode, templateCodes)
|
||||||
|
.eq(MessageTemplateGroup::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||||
|
.set(MessageTemplateGroup::getPath, nodeCodePathMap.get(tgtGroupNodeCode))
|
||||||
|
.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String removeErrorStr(List<String> onlyContainsOneTemplateCodes) {
|
||||||
|
return String.format("模板:%s。解除关联后,将无关联分类!本次操作无效!",
|
||||||
|
String.join("、", onlyContainsOneTemplateCodes));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +1,42 @@
|
|||||||
package cn.axzo.msg.center.message.service.impl;
|
package cn.axzo.msg.center.message.service.impl;
|
||||||
|
|
||||||
import cn.axzo.core.utils.converter.BeanConverter;
|
import cn.axzo.basics.common.util.AssertUtil;
|
||||||
|
import cn.axzo.msg.center.common.enums.ServiceErrorCodeEnum;
|
||||||
|
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
|
||||||
|
import cn.axzo.msg.center.common.redis.RedisUtil;
|
||||||
|
import cn.axzo.msg.center.common.utils.PageHelperUtil;
|
||||||
import cn.axzo.msg.center.dal.MessageBaseTemplateDao;
|
import cn.axzo.msg.center.dal.MessageBaseTemplateDao;
|
||||||
import cn.axzo.msg.center.domain.entity.MessageBaseTemplate;
|
import cn.axzo.msg.center.domain.entity.MessageBaseTemplate;
|
||||||
|
import cn.axzo.msg.center.message.domain.dto.GroupTreeNodePathDTO;
|
||||||
import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO;
|
import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO;
|
||||||
import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO;
|
import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO;
|
||||||
import cn.axzo.msg.center.message.domain.param.MessageTemplateCreateParam;
|
import cn.axzo.msg.center.message.domain.param.MessageTemplateSaveOrUpdateParam;
|
||||||
|
import cn.axzo.msg.center.message.service.MessageGroupNodeService;
|
||||||
|
import cn.axzo.msg.center.message.service.MessageTemplateGroupService;
|
||||||
import cn.axzo.msg.center.message.service.MessageTemplateNewService;
|
import cn.axzo.msg.center.message.service.MessageTemplateNewService;
|
||||||
import cn.axzo.msg.center.message.service.MessageTemplateRouterService;
|
import cn.axzo.msg.center.message.service.MessageTemplateRouterService;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageBaseTemplateDTO;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO;
|
||||||
|
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.StatusEnum;
|
||||||
|
import cn.axzo.msg.center.service.template.request.MessageTemplatePageRequest;
|
||||||
|
import cn.axzo.msg.center.service.template.response.MessageTemplateDetailResponse;
|
||||||
|
import cn.axzo.msg.center.service.template.response.MessageTemplatePageResponse;
|
||||||
|
import cn.axzo.msg.center.utils.JSONObjectUtil;
|
||||||
|
import cn.axzo.msg.center.utils.UUIDUtil;
|
||||||
|
import cn.azxo.framework.common.model.Page;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -33,19 +56,73 @@ import java.util.stream.Collectors;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class MessageTemplateNewServiceImpl implements MessageTemplateNewService {
|
public class MessageTemplateNewServiceImpl implements MessageTemplateNewService {
|
||||||
|
|
||||||
|
private static final String SAVE_TEMPLATE_MUTEX_KEY = "msg-center:template:save:%s";
|
||||||
|
private static final long TRY_LOCK_TIMEOUT_MILLS = 1000;
|
||||||
|
private static final int RETRY_CNT_MAX = 3;
|
||||||
|
|
||||||
|
private static final int MAX_NUM_ONCE_QUERY = 1000;
|
||||||
|
|
||||||
|
private final RedisUtil redisUtil;
|
||||||
private final MessageBaseTemplateDao messageBaseTemplateDao;
|
private final MessageBaseTemplateDao messageBaseTemplateDao;
|
||||||
|
private final MessageGroupNodeService messageGroupNodeService;
|
||||||
|
private final MessageTemplateGroupService messageTemplateGroupService;
|
||||||
private final MessageTemplateRouterService messageTemplateRouterService;
|
private final MessageTemplateRouterService messageTemplateRouterService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createTemplate(MessageTemplateCreateParam param) {
|
@Transactional(rollbackFor = Exception.class)
|
||||||
// TODO: [cold_blade] [P2] 模板与分类的关系
|
public String createTemplate(MessageTemplateSaveOrUpdateParam param) {
|
||||||
messageBaseTemplateDao.save(convert(param));
|
// 创建模板基础数据
|
||||||
if (CollectionUtils.isNotEmpty(param.getRouters())) {
|
String templateCode = saveTemplate(param);
|
||||||
List<RawMessageRouterDTO> routers = param.getRouters().stream()
|
// 创建模板的路由数据
|
||||||
.map(e -> RawMessageRouterDTO.from(e, param.getTemplateCode()))
|
saveTemplateRouters(param, templateCode);
|
||||||
.collect(Collectors.toList());
|
// 创建模板与分类的关联关系数据
|
||||||
messageTemplateRouterService.batchInsert(routers);
|
messageTemplateGroupService.templateGroup(templateCode, param.getLeafGroupNodes());
|
||||||
|
return templateCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void updateTemplate(MessageTemplateSaveOrUpdateParam param) {
|
||||||
|
// 更新模板基础数据
|
||||||
|
updateBaseTemplate(param);
|
||||||
|
// 更新模板分类信息
|
||||||
|
updateTemplateGroupRelation(param);
|
||||||
|
// 更新模板路由信息
|
||||||
|
updateTemplateRouters(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessageTemplateDetailResponse detail(String templateCode) {
|
||||||
|
if (StringUtils.isBlank(templateCode)) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
MessageBaseTemplate baseTemplate = messageBaseTemplateDao.lambdaQuery()
|
||||||
|
.eq(MessageBaseTemplate::getCode, templateCode)
|
||||||
|
.eq(MessageBaseTemplate::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||||
|
.one();
|
||||||
|
if (Objects.isNull(baseTemplate)) {
|
||||||
|
log.info("there is not any template match the templateCode:[{}]", templateCode);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 获取模板关联分类的path列表
|
||||||
|
List<String> groupNodePaths = messageTemplateGroupService.listMessageTemplateGroupPaths(
|
||||||
|
Lists.newArrayList(templateCode)).getOrDefault(templateCode, Collections.emptyList());
|
||||||
|
List<RawMessageRouterDTO> routers = messageTemplateRouterService.queryByTemplateCode(templateCode);
|
||||||
|
return convert(baseTemplate, groupNodePaths, routers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateStatus(Long operatorId, String templateCode, StatusEnum status) {
|
||||||
|
if (Objects.isNull(operatorId) || StringUtils.isBlank(templateCode) || Objects.isNull(status)) {
|
||||||
|
log.info("the param is invalid. operatorId:[{}], code:[{}], status:[{}]", operatorId, templateCode, status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
messageBaseTemplateDao.lambdaUpdate()
|
||||||
|
.eq(MessageBaseTemplate::getCode, templateCode)
|
||||||
|
.eq(MessageBaseTemplate::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||||
|
.set(MessageBaseTemplate::getStatus, status)
|
||||||
|
.set(MessageBaseTemplate::getUpdaterId, operatorId)
|
||||||
|
.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -87,12 +164,256 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private MessageBaseTemplate convert(MessageTemplateCreateParam param) {
|
@Override
|
||||||
MessageBaseTemplate template = BeanConverter.convert(param, MessageBaseTemplate.class);
|
public Page<MessageTemplatePageResponse> page(MessageTemplatePageRequest request) {
|
||||||
|
List<String> templateCodes = Lists.newArrayList();
|
||||||
|
if (StringUtils.isNotBlank(request.getGroupNodeCode())) {
|
||||||
|
templateCodes = messageTemplateGroupService.listMessageTemplateCodes(request.getGroupNodeCode());
|
||||||
|
if (CollectionUtils.isEmpty(templateCodes)) {
|
||||||
|
// 入参中的分类没有关联任何模板,直接返回查询结果
|
||||||
|
return PageHelperUtil.emptyPage(request.getPage(), request.getPageSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(request.getTemplateCode())) {
|
||||||
|
if (CollectionUtils.isNotEmpty(templateCodes)
|
||||||
|
&& !templateCodes.contains(request.getTemplateCode())) {
|
||||||
|
// 分页查询的入参中没指定的模板编码与分类映射的模板编码无交集
|
||||||
|
return PageHelperUtil.emptyPage(request.getPage(), request.getPageSize());
|
||||||
|
}
|
||||||
|
// 取两者的交集
|
||||||
|
templateCodes = Lists.newArrayList(request.getTemplateCode());
|
||||||
|
}
|
||||||
|
IPage<MessageBaseTemplate> pageRequest = request.toPage();
|
||||||
|
IPage<MessageBaseTemplate> result = messageBaseTemplateDao.lambdaQuery()
|
||||||
|
.like(StringUtils.isNotBlank(request.getTemplateName()),
|
||||||
|
MessageBaseTemplate::getName, request.getTemplateName())
|
||||||
|
.in(CollectionUtils.isNotEmpty(templateCodes),
|
||||||
|
MessageBaseTemplate::getCode, request.getTemplateCode())
|
||||||
|
.eq(Objects.nonNull(request.getCategory()), MessageBaseTemplate::getMsgCategory, request.getCategory())
|
||||||
|
.eq(Objects.nonNull(request.getStatus()), MessageBaseTemplate::getStatus, request.getStatus())
|
||||||
|
.page(pageRequest);
|
||||||
|
if (CollectionUtils.isEmpty(result.getRecords())) {
|
||||||
|
return PageHelperUtil.emptyPage(request.getPage(), request.getPageSize());
|
||||||
|
}
|
||||||
|
templateCodes = result.getRecords().stream().map(MessageBaseTemplate::getCode).collect(Collectors.toList());
|
||||||
|
Map<String, List<String>> groupNodePaths = messageTemplateGroupService
|
||||||
|
.listMessageTemplateGroupPaths(templateCodes);
|
||||||
|
Map<String, String> codeNameMap = messageGroupNodeService.groupNodeNamePaths(groupNodePaths.values().stream()
|
||||||
|
.flatMap(Collection::stream).collect(Collectors.toList()));
|
||||||
|
List<MessageTemplatePageResponse> records = result.getRecords().stream()
|
||||||
|
.map(e -> convert(e, groupNodePaths, codeNameMap))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return Page.toPage(request.getPage(), request.getPageSize(), result.getTotal(), records);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<MessageBaseTemplateDTO> pageBaseTemplate(MessageTemplatePageRequest request) {
|
||||||
|
List<String> templateCodes = Lists.newArrayList();
|
||||||
|
if (StringUtils.isNotBlank(request.getGroupNodeCode())) {
|
||||||
|
templateCodes = messageTemplateGroupService.listMessageTemplateCodes(request.getGroupNodeCode());
|
||||||
|
if (CollectionUtils.isEmpty(templateCodes)) {
|
||||||
|
// 入参中的分类没有关联任何模板,直接返回查询结果
|
||||||
|
return PageHelperUtil.emptyPage(request.getPage(), request.getPageSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(request.getTemplateCode())) {
|
||||||
|
if (CollectionUtils.isNotEmpty(templateCodes)
|
||||||
|
&& !templateCodes.contains(request.getTemplateCode())) {
|
||||||
|
// 分页查询的入参中没指定的模板编码与分类映射的模板编码无交集
|
||||||
|
return PageHelperUtil.emptyPage(request.getPage(), request.getPageSize());
|
||||||
|
}
|
||||||
|
// 取两者的交集
|
||||||
|
templateCodes = Lists.newArrayList(request.getTemplateCode());
|
||||||
|
}
|
||||||
|
IPage<MessageBaseTemplate> pageRequest = request.toPage();
|
||||||
|
IPage<MessageBaseTemplate> result = messageBaseTemplateDao.lambdaQuery()
|
||||||
|
.like(StringUtils.isNotBlank(request.getTemplateName()),
|
||||||
|
MessageBaseTemplate::getName, request.getTemplateName())
|
||||||
|
.in(CollectionUtils.isNotEmpty(templateCodes),
|
||||||
|
MessageBaseTemplate::getCode, request.getTemplateCode())
|
||||||
|
.eq(Objects.nonNull(request.getCategory()), MessageBaseTemplate::getMsgCategory, request.getCategory())
|
||||||
|
.eq(Objects.nonNull(request.getStatus()), MessageBaseTemplate::getStatus, request.getStatus())
|
||||||
|
.page(pageRequest);
|
||||||
|
if (CollectionUtils.isEmpty(result.getRecords())) {
|
||||||
|
return PageHelperUtil.emptyPage(request.getPage(), request.getPageSize());
|
||||||
|
}
|
||||||
|
List<MessageBaseTemplateDTO> records = result.getRecords().stream()
|
||||||
|
.map(this::convert)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return Page.toPage(request.getPage(), request.getPageSize(), result.getTotal(), records);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<MessageTemplatePageResponse> listByCodes(Collection<String> templateCodes) {
|
||||||
|
if (CollectionUtils.isEmpty(templateCodes)) {
|
||||||
|
log.info("the templateCodes is empty.");
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
AssertUtil.isTrue(templateCodes.size() <= MAX_NUM_ONCE_QUERY, "the collection of templateCodes is too large");
|
||||||
|
// 查询模板基础数据
|
||||||
|
List<MessageBaseTemplate> records = messageBaseTemplateDao.lambdaQuery()
|
||||||
|
.in(MessageBaseTemplate::getCode, templateCodes)
|
||||||
|
.eq(MessageBaseTemplate::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||||
|
.list();
|
||||||
|
// 查询模板的分类结点编码path
|
||||||
|
templateCodes = records.stream().map(MessageBaseTemplate::getCode).collect(Collectors.toList());
|
||||||
|
Map<String, List<String>> groupNodePaths = messageTemplateGroupService
|
||||||
|
.listMessageTemplateGroupPaths(templateCodes);
|
||||||
|
// 将模板分类结点编码path转化为分类名称path
|
||||||
|
Map<String, String> codeNameMap = messageGroupNodeService.groupNodeNamePaths(groupNodePaths.values().stream()
|
||||||
|
.flatMap(Collection::stream).collect(Collectors.toList()));
|
||||||
|
// 转化为页面展示的数据模型
|
||||||
|
return records.stream()
|
||||||
|
.map(e -> convert(e, groupNodePaths, codeNameMap))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String saveTemplate(MessageTemplateSaveOrUpdateParam param) {
|
||||||
|
String templateCode = UUIDUtil.uuidString();
|
||||||
|
MessageBaseTemplate template = convert(param);
|
||||||
|
boolean result = doSaveTemplate(template, templateCode);
|
||||||
|
int retryCnt = 0;
|
||||||
|
while (!result && retryCnt++ < RETRY_CNT_MAX) {
|
||||||
|
// 默认重试{@cod RETRY_CNT_MAX}次,若{@code RETRY_CNT_MAX}次后依然失败就报错
|
||||||
|
templateCode = UUIDUtil.uuidString();
|
||||||
|
result = doSaveTemplate(template, templateCode);
|
||||||
|
}
|
||||||
|
AssertUtil.isTrue(result, ServiceErrorCodeEnum.SYSTEM_BUSY.getDesc());
|
||||||
|
return templateCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean doSaveTemplate(MessageBaseTemplate template, String templateCode) {
|
||||||
|
String requestId = UUIDUtil.uuidRawString();
|
||||||
|
try {
|
||||||
|
String opKey = String.format(SAVE_TEMPLATE_MUTEX_KEY, templateCode);
|
||||||
|
boolean lockResult = redisUtil.getLockOps().getLockUntilTimeout(opKey, requestId, TRY_LOCK_TIMEOUT_MILLS);
|
||||||
|
AssertUtil.isTrue(lockResult, ServiceErrorCodeEnum.SYSTEM_BUSY.getDesc());
|
||||||
|
if (isTemplateExist(templateCode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template.setCode(templateCode);
|
||||||
|
messageBaseTemplateDao.save(template);
|
||||||
|
return true;
|
||||||
|
} finally {
|
||||||
|
redisUtil.getLockOps().releaseLock(SAVE_TEMPLATE_MUTEX_KEY, requestId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isTemplateExist(String templateCode) {
|
||||||
|
return messageBaseTemplateDao.lambdaQuery()
|
||||||
|
.eq(MessageBaseTemplate::getCode, templateCode)
|
||||||
|
.eq(MessageBaseTemplate::getIsDelete, 0)
|
||||||
|
.count() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MessageBaseTemplate convert(MessageTemplateSaveOrUpdateParam param) {
|
||||||
|
MessageBaseTemplate template = new MessageBaseTemplate();
|
||||||
template.setName(param.getTemplateName());
|
template.setName(param.getTemplateName());
|
||||||
template.setCode(param.getTemplateCode());
|
template.setMsgCategory(param.getMsgCategory());
|
||||||
|
template.setTitle(param.getTitle());
|
||||||
|
template.setContent(param.getContent());
|
||||||
|
template.setCardContent(JSONObjectUtil.toJSONString(param.getMsgCardContentItems()));
|
||||||
|
template.setIcon(param.getIcon());
|
||||||
|
template.setPushTerminal(JSONObjectUtil.toJSONString(param.getPushTerminals()));
|
||||||
template.setCreatorId(param.getOperatorId());
|
template.setCreatorId(param.getOperatorId());
|
||||||
template.setUpdaterId(param.getOperatorId());
|
template.setUpdaterId(param.getOperatorId());
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void saveTemplateRouters(MessageTemplateSaveOrUpdateParam param, String templateCode) {
|
||||||
|
if (CollectionUtils.isEmpty(param.getRouters())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<RawMessageRouterDTO> routers = param.getRouters().stream()
|
||||||
|
.map(e -> RawMessageRouterDTO.from(e, templateCode))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
messageTemplateRouterService.batchInsert(routers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBaseTemplate(MessageTemplateSaveOrUpdateParam param) {
|
||||||
|
messageBaseTemplateDao.lambdaUpdate()
|
||||||
|
.eq(MessageBaseTemplate::getCode, param.getTemplateCode())
|
||||||
|
.eq(MessageBaseTemplate::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||||
|
.set(MessageBaseTemplate::getUpdaterId, param.getOperatorId())
|
||||||
|
.set(StringUtils.isNotBlank(param.getTemplateName()), MessageBaseTemplate::getName,
|
||||||
|
param.getTemplateName())
|
||||||
|
.set(CollectionUtils.isNotEmpty(param.getPushTerminals()), MessageBaseTemplate::getPushTerminal,
|
||||||
|
JSON.toJSONString(param.getPushTerminals()))
|
||||||
|
.set(StringUtils.isNotBlank(param.getTitle()), MessageBaseTemplate::getTitle, param.getTitle())
|
||||||
|
.set(CollectionUtils.isNotEmpty(param.getMsgCardContentItems()), MessageBaseTemplate::getCardContent,
|
||||||
|
JSONObjectUtil.toJSONString(param.getMsgCardContentItems()))
|
||||||
|
.set(StringUtils.isNotBlank(param.getContent()), MessageBaseTemplate::getContent, param.getContent())
|
||||||
|
.set(StringUtils.isNotBlank(param.getIcon()), MessageBaseTemplate::getIcon, param.getIcon())
|
||||||
|
.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTemplateGroupRelation(MessageTemplateSaveOrUpdateParam param) {
|
||||||
|
if (CollectionUtils.isEmpty(param.getLeafGroupNodes())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
messageTemplateGroupService.updateTemplateGroup(param.getTemplateCode(), param.getLeafGroupNodes());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTemplateRouters(MessageTemplateSaveOrUpdateParam param) {
|
||||||
|
if (CollectionUtils.isEmpty(param.getRouters())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
messageTemplateRouterService.updateTemplateRoutes(param.getTemplateCode(), param.getRouters());
|
||||||
|
}
|
||||||
|
|
||||||
|
private MessageBaseTemplateDTO convert(MessageBaseTemplate record) {
|
||||||
|
return MessageBaseTemplateDTO.builder()
|
||||||
|
.name(record.getName())
|
||||||
|
.code(record.getCode())
|
||||||
|
.msgCategory(record.getMsgCategory())
|
||||||
|
.title(record.getTitle())
|
||||||
|
.content(record.getContent())
|
||||||
|
.cardContentItems(JSONObjectUtil.parseArray(record.getCardContent(), MessageCardContentItemDTO.class))
|
||||||
|
.icon(record.getIcon())
|
||||||
|
.pushTerminals(JSON.parseArray(record.getPushTerminal(), PushTerminalEnum.class))
|
||||||
|
.createTimestamp(record.getCreateAt().getTime())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MessageTemplatePageResponse convert(MessageBaseTemplate record, Map<String, List<String>> groupNodePaths,
|
||||||
|
Map<String, String> codeNameMap) {
|
||||||
|
MessageTemplatePageResponse response = new MessageTemplatePageResponse();
|
||||||
|
response.setTemplateName(record.getName());
|
||||||
|
response.setTemplateCode(record.getCode());
|
||||||
|
response.setTitle(record.getTitle());
|
||||||
|
response.setContent(record.getContent());
|
||||||
|
response.setCategory(record.getMsgCategory());
|
||||||
|
response.setStatus(record.getStatus());
|
||||||
|
List<String> nodeNamePaths = groupNodePaths.getOrDefault(record.getCode(), Collections.emptyList()).stream()
|
||||||
|
.filter(codeNameMap::containsKey)
|
||||||
|
.map(codeNameMap::get)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
response.setGroupNodeNamePaths(nodeNamePaths);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MessageTemplateDetailResponse convert(MessageBaseTemplate record, List<String> groupNodePaths,
|
||||||
|
List<RawMessageRouterDTO> routers) {
|
||||||
|
// 将path解析中解析出分类结点(路径叶结点)的编码
|
||||||
|
List<String> groupNodeCodes = groupNodePaths.stream()
|
||||||
|
.map(GroupTreeNodePathDTO::parseLeafNodeCode)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
// 转化为页面相关的数据模型
|
||||||
|
List<MessageRouterButtonDTO> routerButtons = routers.stream()
|
||||||
|
.map(RawMessageRouterDTO::toMessageRouterButton)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return MessageTemplateDetailResponse.builder()
|
||||||
|
.templateName(record.getName())
|
||||||
|
.category(record.getMsgCategory())
|
||||||
|
.leafGroupNodes(groupNodeCodes)
|
||||||
|
.pushTerminals(JSON.parseArray(record.getPushTerminal(), PushTerminalEnum.class))
|
||||||
|
.msgTitle(record.getTitle())
|
||||||
|
.msgContent(record.getContent())
|
||||||
|
.cardContentItems(JSONObjectUtil.parseArray(record.getCardContent(), MessageCardContentItemDTO.class))
|
||||||
|
.msgIcon(record.getIcon())
|
||||||
|
.routers(routerButtons)
|
||||||
|
.createTimestamp(record.getCreateAt().getTime())
|
||||||
|
.updateTimestamp(record.getUpdateAt().getTime())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import cn.axzo.msg.center.dal.MessageTemplateRouterDao;
|
|||||||
import cn.axzo.msg.center.domain.entity.MessageTemplateRouter;
|
import cn.axzo.msg.center.domain.entity.MessageTemplateRouter;
|
||||||
import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO;
|
import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO;
|
||||||
import cn.axzo.msg.center.message.service.MessageTemplateRouterService;
|
import cn.axzo.msg.center.message.service.MessageTemplateRouterService;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -36,9 +37,7 @@ public class MessageTemplateRouterServiceImpl implements MessageTemplateRouterSe
|
|||||||
log.warn("the template code is blank.");
|
log.warn("the template code is blank.");
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
return messageTemplateRouterDao.listByTemplateCode(Lists.newArrayList(templateCode)).stream()
|
return listByTemplateCodes(Lists.newArrayList(templateCode));
|
||||||
.map(RawMessageRouterDTO::from)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -47,18 +46,49 @@ public class MessageTemplateRouterServiceImpl implements MessageTemplateRouterSe
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<MessageTemplateRouter> messageTemplateRouters = routers.stream()
|
List<MessageTemplateRouter> messageTemplateRouters = routers.stream()
|
||||||
.map(RawMessageRouterDTO::toMessageTemplateRouter)
|
.flatMap(e -> e.toMessageTemplateRouters().stream())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
messageTemplateRouterDao.saveBatch(messageTemplateRouters);
|
messageTemplateRouterDao.saveBatch(messageTemplateRouters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateTemplateRoutes(String templateCode, List<MessageRouterButtonDTO> routers) {
|
||||||
|
if (StringUtils.isBlank(templateCode)
|
||||||
|
|| CollectionUtils.isEmpty(routers)) {
|
||||||
|
log.info("the param is invalid. templateCode:[{}], routers:{}", templateCode, routers);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 移除之前的路由信息
|
||||||
|
messageTemplateRouterDao.lambdaUpdate()
|
||||||
|
.eq(MessageTemplateRouter::getTemplateCode, templateCode)
|
||||||
|
.remove();
|
||||||
|
// 创建信息的路由信息
|
||||||
|
List<RawMessageRouterDTO> newRouters = routers.stream()
|
||||||
|
.map(e -> RawMessageRouterDTO.from(e, templateCode))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
batchInsert(newRouters);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, List<RawMessageRouterDTO>> groupByTemplateCode(List<String> templateCodes) {
|
public Map<String, List<RawMessageRouterDTO>> groupByTemplateCode(List<String> templateCodes) {
|
||||||
if (CollectionUtils.isEmpty(templateCodes)) {
|
if (CollectionUtils.isEmpty(templateCodes)) {
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
}
|
}
|
||||||
return messageTemplateRouterDao.listByTemplateCode(templateCodes).stream()
|
return listByTemplateCodes(templateCodes).stream()
|
||||||
.map(RawMessageRouterDTO::from)
|
|
||||||
.collect(Collectors.groupingBy(RawMessageRouterDTO::getTemplateCode));
|
.collect(Collectors.groupingBy(RawMessageRouterDTO::getTemplateCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<RawMessageRouterDTO> listByTemplateCodes(List<String> templateCodes) {
|
||||||
|
// 根据模板编码进行分组
|
||||||
|
Map<String, List<MessageTemplateRouter>> routers = messageTemplateRouterDao
|
||||||
|
.listByTemplateCode(templateCodes).stream()
|
||||||
|
.collect(Collectors.groupingBy(MessageTemplateRouter::getTemplateCode));
|
||||||
|
return routers.values().stream()
|
||||||
|
.flatMap(e -> {
|
||||||
|
// 模板路由的按钮维度
|
||||||
|
Map<String, List<MessageTemplateRouter>> btnMap = e.stream()
|
||||||
|
.collect(Collectors.groupingBy(MessageTemplateRouter::getName));
|
||||||
|
return btnMap.values().stream().map(RawMessageRouterDTO::from);
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,21 +1,21 @@
|
|||||||
package cn.axzo.msg.center.message.service.impl;
|
package cn.axzo.msg.center.message.service.impl;
|
||||||
|
|
||||||
import cn.axzo.core.utils.converter.BeanConverter;
|
|
||||||
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
|
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
|
||||||
import cn.axzo.msg.center.common.exception.ServiceException;
|
import cn.axzo.msg.center.common.exception.ServiceException;
|
||||||
import cn.axzo.msg.center.common.utils.PlaceholderResolver;
|
import cn.axzo.msg.center.common.utils.PlaceholderResolver;
|
||||||
import cn.axzo.msg.center.dal.PendingMessageRecordDao;
|
import cn.axzo.msg.center.dal.PendingMessageRecordDao;
|
||||||
import cn.axzo.msg.center.domain.entity.PendingMessageRecord;
|
import cn.axzo.msg.center.domain.entity.PendingMessageRecord;
|
||||||
import cn.axzo.msg.center.message.domain.dto.MessageGroupNodeDTO;
|
import cn.axzo.msg.center.message.domain.dto.MessageGroupNodeStatisticDTO;
|
||||||
import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO;
|
import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO;
|
||||||
import cn.axzo.msg.center.message.domain.dto.PendingMessageDTO;
|
import cn.axzo.msg.center.message.domain.dto.PendingMessageDTO;
|
||||||
import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO;
|
import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO;
|
||||||
import cn.axzo.msg.center.message.domain.param.MessageGroupNodeStatisticParam;
|
import cn.axzo.msg.center.message.domain.param.MessageGroupNodeStatisticParam;
|
||||||
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
|
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
|
||||||
import cn.axzo.msg.center.message.service.MessageGroupService;
|
import cn.axzo.msg.center.message.service.MessageGroupNodeService;
|
||||||
import cn.axzo.msg.center.message.service.MessageTemplateGroupService;
|
import cn.axzo.msg.center.message.service.MessageTemplateGroupService;
|
||||||
import cn.axzo.msg.center.message.service.MessageTemplateNewService;
|
import cn.axzo.msg.center.message.service.MessageTemplateNewService;
|
||||||
import cn.axzo.msg.center.message.service.PendingMessageNewService;
|
import cn.axzo.msg.center.message.service.PendingMessageNewService;
|
||||||
|
import cn.axzo.msg.center.service.dto.GroupTreeNodeDTO;
|
||||||
import cn.axzo.msg.center.service.dto.IdentityDTO;
|
import cn.axzo.msg.center.service.dto.IdentityDTO;
|
||||||
import cn.axzo.msg.center.service.dto.MessageRouterDTO;
|
import cn.axzo.msg.center.service.dto.MessageRouterDTO;
|
||||||
import cn.axzo.msg.center.service.dto.PersonDTO;
|
import cn.axzo.msg.center.service.dto.PersonDTO;
|
||||||
@ -27,11 +27,14 @@ import cn.axzo.msg.center.service.enums.PendingMessageStateEnum;
|
|||||||
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
|
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
|
||||||
import cn.axzo.msg.center.service.pending.request.PendingMessagePageRequest;
|
import cn.axzo.msg.center.service.pending.request.PendingMessagePageRequest;
|
||||||
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
|
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
|
||||||
|
import cn.axzo.msg.center.utils.JSONObjectUtil;
|
||||||
import cn.axzo.msg.center.utils.MessageRouterUtil;
|
import cn.axzo.msg.center.utils.MessageRouterUtil;
|
||||||
import cn.axzo.msg.center.utils.OrderFieldParseUtil;
|
import cn.axzo.msg.center.utils.OrderFieldParseUtil;
|
||||||
|
import cn.axzo.msg.center.utils.TreeHelperUtil;
|
||||||
import cn.axzo.msg.center.utils.UUIDUtil;
|
import cn.axzo.msg.center.utils.UUIDUtil;
|
||||||
import cn.azxo.framework.common.model.Page;
|
import cn.azxo.framework.common.model.Page;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||||
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||||
@ -44,10 +47,10 @@ import org.springframework.stereotype.Service;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Stack;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,13 +65,13 @@ import java.util.stream.Collectors;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PendingMessageNewServiceImpl implements PendingMessageNewService {
|
public class PendingMessageNewServiceImpl implements PendingMessageNewService {
|
||||||
|
|
||||||
private final MessageGroupService messageGroupService;
|
|
||||||
private final PendingMessageRecordDao pendingMessageRecordDao;
|
private final PendingMessageRecordDao pendingMessageRecordDao;
|
||||||
|
private final MessageGroupNodeService messageGroupNodeService;
|
||||||
private final MessageTemplateNewService messageTemplateNewService;
|
private final MessageTemplateNewService messageTemplateNewService;
|
||||||
private final MessageTemplateGroupService messageTemplateGroupService;
|
private final MessageTemplateGroupService messageTemplateGroupService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<MessageGroupNodeDTO> groupStatistic(MessageGroupNodeStatisticParam param) {
|
public List<MessageGroupNodeStatisticDTO> groupStatistic(MessageGroupNodeStatisticParam param) {
|
||||||
return param.getGroupNodeCodes().stream()
|
return param.getGroupNodeCodes().stream()
|
||||||
.flatMap(e -> statistic(e, param).stream())
|
.flatMap(e -> statistic(e, param).stream())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@ -169,19 +172,20 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
|
|||||||
.findFirst()
|
.findFirst()
|
||||||
.map(MessageTemplateDTO::getRouters)
|
.map(MessageTemplateDTO::getRouters)
|
||||||
.orElseGet(Collections::emptyList);
|
.orElseGet(Collections::emptyList);
|
||||||
rawRouters = MessageRouterUtil.selectRouter(rawRouters, terminalType);
|
List<MessageRouterDTO> routers = rawRouters.stream()
|
||||||
List<MessageRouterDTO> routers = rawRouters.stream().map(e -> {
|
.map(e -> {
|
||||||
MessageRouterDTO router = BeanConverter.convert(e, MessageRouterDTO.class);
|
MessageRouterDTO router = e.toMessageRouter(terminalType);
|
||||||
// 视情况替换原始URL中的参数变量
|
// 视情况替换原始URL中的参数变量
|
||||||
MessageRouterUtil.parseRouteUrl(router, pendingMessageRecord.getRouterParams());
|
MessageRouterUtil.parseRouteUrl(router, pendingMessageRecord.getRouterParams());
|
||||||
return router;
|
return router;
|
||||||
}).collect(Collectors.toList());
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
pendingMessage.setRouters(routers);
|
pendingMessage.setRouters(routers);
|
||||||
// 获取模板卡片信息
|
// 获取模板卡片信息
|
||||||
String cardContent = messageTemplates.stream()
|
String cardContent = messageTemplates.stream()
|
||||||
.filter(e -> Objects.equals(e.getCode(), pendingMessageRecord.getTemplateCode()))
|
.filter(e -> Objects.equals(e.getCode(), pendingMessageRecord.getTemplateCode()))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.map(MessageTemplateDTO::getCardContent)
|
.map(e -> JSON.toJSONString(e.toCardContentMap()))
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
if (StringUtils.isNotBlank(cardContent) && StringUtils.isNotBlank(pendingMessageRecord.getRouterParams())) {
|
if (StringUtils.isNotBlank(cardContent) && StringUtils.isNotBlank(pendingMessageRecord.getRouterParams())) {
|
||||||
cardContent = PlaceholderResolver.getDefaultResolver()
|
cardContent = PlaceholderResolver.getDefaultResolver()
|
||||||
@ -191,26 +195,23 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
|
|||||||
return pendingMessage;
|
return pendingMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MessageGroupNodeDTO> statistic(String rootNodeCode, MessageGroupNodeStatisticParam param) {
|
private List<MessageGroupNodeStatisticDTO> statistic(String rootNodeCode, MessageGroupNodeStatisticParam param) {
|
||||||
MessageGroupNodeDTO groupNode = messageGroupService.queryByNodeCode(rootNodeCode)
|
GroupTreeNodeDTO rootNode = messageGroupNodeService.queryRootNode(rootNodeCode)
|
||||||
.orElseThrow(() -> new ServiceException("groupNodeCode is invalid."));
|
.orElseThrow(() -> new ServiceException("groupNodeCode is invalid."));
|
||||||
MessageGroupNodeDTO root = groupNode;
|
MessageGroupNodeStatisticDTO rootWrapper = TreeHelperUtil.wrapper(rootNode, MessageGroupNodeStatisticDTO::of);
|
||||||
Stack<MessageGroupNodeDTO> stack = new Stack<>();
|
LinkedList<MessageGroupNodeStatisticDTO> stack = new LinkedList<>();
|
||||||
stack.push(groupNode);
|
stack.push(rootWrapper);
|
||||||
List<MessageGroupNodeDTO> children;
|
MessageGroupNodeStatisticDTO wrapper;
|
||||||
while (!stack.isEmpty()) {
|
while (!stack.isEmpty()) {
|
||||||
// TODO: [cold_blade] [P3] 优化树形分类结点的统计效率
|
wrapper = stack.pop();
|
||||||
groupNode = stack.pop();
|
statistic(wrapper, param);
|
||||||
statistic(groupNode, param);
|
stack.addAll(wrapper.getNodeChildren());
|
||||||
children = messageGroupService.listChildren(groupNode.getNodeCode());
|
|
||||||
groupNode.setChildren(children);
|
|
||||||
children.forEach(stack::push);
|
|
||||||
}
|
}
|
||||||
// 外部传的是根节点,但是前端希望只返回根节点的字节的
|
// 外部传的是根节点,但是前端希望只返回根节点的字节的
|
||||||
return root.getChildren();
|
return rootWrapper.getNodeChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void statistic(MessageGroupNodeDTO groupNode, MessageGroupNodeStatisticParam param) {
|
private void statistic(MessageGroupNodeStatisticDTO groupNode, MessageGroupNodeStatisticParam param) {
|
||||||
List<String> templateCodes = messageTemplateGroupService.listMessageTemplateCodes(groupNode.getNodeCode());
|
List<String> templateCodes = messageTemplateGroupService.listMessageTemplateCodes(groupNode.getNodeCode());
|
||||||
if (CollectionUtils.isEmpty(templateCodes)) {
|
if (CollectionUtils.isEmpty(templateCodes)) {
|
||||||
groupNode.setPendingCount(0);
|
groupNode.setPendingCount(0);
|
||||||
@ -282,10 +283,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
|
|||||||
record.setOrgId(param.getOrgId());
|
record.setOrgId(param.getOrgId());
|
||||||
record.setOrgName(param.getOrgName());
|
record.setOrgName(param.getOrgName());
|
||||||
// 构建业务类信息
|
// 构建业务类信息
|
||||||
record.setBizCode(param.getBizCode());
|
buildBusinessInfo(record, param);
|
||||||
record.setSubBizCode(param.getSubBizCode());
|
|
||||||
record.setBizDesc(param.getBizDesc());
|
|
||||||
record.setBizCategory(param.getBizCategory());
|
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,17 +297,28 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void buildTemplateInfo(PendingMessageRecord record, MessageTemplateDTO msgTemplate, String routeParam) {
|
private void buildTemplateInfo(PendingMessageRecord record, MessageTemplateDTO msgTemplate, String routeParam) {
|
||||||
String title = msgTemplate.getTitle();
|
// TODO:[cold_blade] [P3] 后续其它业务对接的时候,需要明确业务扩展字段和路由参数的分界
|
||||||
String content = msgTemplate.getContent();
|
JSONObject routerParamObj = JSONObjectUtil.parseObject(routeParam);
|
||||||
if (StringUtils.isNotBlank(routeParam)) {
|
String title = PlaceholderResolver
|
||||||
title = PlaceholderResolver
|
.getDefaultResolver().resolveByMap(msgTemplate.getTitle(), routerParamObj);
|
||||||
.getDefaultResolver().resolveByMap(title, JSON.parseObject(routeParam));
|
String content = PlaceholderResolver
|
||||||
content = PlaceholderResolver
|
.getDefaultResolver().resolveByMap(msgTemplate.getContent(), routerParamObj);
|
||||||
.getDefaultResolver().resolveByMap(content, JSON.parseObject(routeParam));
|
|
||||||
}
|
|
||||||
record.setTitle(title);
|
record.setTitle(title);
|
||||||
record.setContent(content);
|
record.setContent(content);
|
||||||
record.setTemplateCode(msgTemplate.getCode());
|
record.setTemplateCode(msgTemplate.getCode());
|
||||||
record.setRouterParams(routeParam);
|
record.setRouterParams(routerParamObj.toJSONString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildBusinessInfo(PendingMessageRecord record, PendingMessagePushParam param) {
|
||||||
|
record.setBizCode(param.getBizCode());
|
||||||
|
record.setSubBizCode(param.getSubBizCode());
|
||||||
|
record.setBizDesc(param.getBizDesc());
|
||||||
|
record.setBizCategory(param.getBizCategory());
|
||||||
|
record.setBizExtParam(JSONObjectUtil.checkAndReturn(param.getBizExtParams()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GroupTreeNodeWrapper {
|
||||||
|
private GroupTreeNodeDTO treeNode;
|
||||||
|
private int pendingCnt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,212 @@
|
|||||||
|
package cn.axzo.msg.center.message.service.impl;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
|
||||||
|
import cn.axzo.msg.center.dal.MessageBaseTemplateDao;
|
||||||
|
import cn.axzo.msg.center.dal.RelationTemplateMapDao;
|
||||||
|
import cn.axzo.msg.center.domain.entity.MessageBaseTemplate;
|
||||||
|
import cn.axzo.msg.center.domain.entity.MessageRelation;
|
||||||
|
import cn.axzo.msg.center.domain.entity.MessageRouter;
|
||||||
|
import cn.axzo.msg.center.domain.entity.MessageTemplate;
|
||||||
|
import cn.axzo.msg.center.domain.entity.RelationTemplateMap;
|
||||||
|
import cn.axzo.msg.center.inside.notices.service.MessageRelationService;
|
||||||
|
import cn.axzo.msg.center.inside.notices.service.MessageRouterService;
|
||||||
|
import cn.axzo.msg.center.inside.notices.service.MessageTemplateService;
|
||||||
|
import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO;
|
||||||
|
import cn.axzo.msg.center.message.domain.param.RelationTemplateMapInitParam;
|
||||||
|
import cn.axzo.msg.center.message.service.MessageTemplateGroupService;
|
||||||
|
import cn.axzo.msg.center.message.service.MessageTemplateRouterService;
|
||||||
|
import cn.axzo.msg.center.message.service.RelationTemplateMapService;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageRouterTerminalDTO;
|
||||||
|
import cn.axzo.msg.center.service.enums.ButtonStyleEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
|
||||||
|
import cn.axzo.msg.center.utils.JSONObjectUtil;
|
||||||
|
import cn.axzo.msg.center.utils.UUIDUtil;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
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.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
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 MessageRouterService messageRouterService;
|
||||||
|
private final MessageRelationService messageRelationService;
|
||||||
|
private final MessageTemplateService messageTemplateService;
|
||||||
|
private final RelationTemplateMapDao relationTemplateMapDao;
|
||||||
|
private final MessageBaseTemplateDao messageBaseTemplateDao;
|
||||||
|
private final MessageTemplateGroupService messageTemplateGroupService;
|
||||||
|
private final MessageTemplateRouterService messageTemplateRouterService;
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void init(RelationTemplateMapInitParam param) {
|
||||||
|
List<MessageRelation> allRelations = messageRelationService.getAllRelations();
|
||||||
|
if (CollectionUtils.isNotEmpty(param.getRelationIds())) {
|
||||||
|
// 指定了需要创建并关联的relationId
|
||||||
|
allRelations = allRelations.stream()
|
||||||
|
.filter(e -> param.getRelationIds().contains(e.getId()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
// relationId与templateId的map
|
||||||
|
Map<Long, Long> relationIdTemplateIdMap = allRelations.stream()
|
||||||
|
.collect(Collectors.toMap(MessageRelation::getId, MessageRelation::getTemplateId));
|
||||||
|
// 获取已经建立关联关系的relationId集合
|
||||||
|
Set<Long> mappedRelationIds = getAllOriginalRelationIds();
|
||||||
|
// 过滤掉已经建立关联关系的relationId
|
||||||
|
relationIdTemplateIdMap = relationIdTemplateIdMap.entrySet().stream()
|
||||||
|
.filter(e -> !mappedRelationIds.contains(e.getKey()))
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
|
// 获取生效中的模板
|
||||||
|
Map<Long, MessageTemplate> messageTemplates = messageTemplateService.getAllTemplates().stream()
|
||||||
|
.collect(Collectors.toMap(MessageTemplate::getId, Function.identity()));
|
||||||
|
// 过滤掉relationId对应的消息模板已经删除的场景
|
||||||
|
relationIdTemplateIdMap = relationIdTemplateIdMap.entrySet().stream()
|
||||||
|
.filter(e -> messageTemplates.containsKey(e.getValue()))
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
|
// 获取真实有效且待建立关联关系的relationId对应的消息模板路由
|
||||||
|
Map<Long, List<MessageRouter>> messageRouters = messageRouterService.getRouterMapByRelationIds(
|
||||||
|
Lists.newArrayList(relationIdTemplateIdMap.keySet())).stream()
|
||||||
|
.collect(Collectors.groupingBy(MessageRouter::getRelationId));
|
||||||
|
// 转化为新模板的数据模型wrapper
|
||||||
|
List<CreateNewTemplateAndMapWrapper> wrappers = relationIdTemplateIdMap.entrySet().stream()
|
||||||
|
.map(e -> convert(e.getKey(), messageTemplates.get(e.getValue()), messageRouters.get(e.getKey())))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
// 批量插入
|
||||||
|
messageBaseTemplateDao.saveBatch(wrappers.stream()
|
||||||
|
.map(CreateNewTemplateAndMapWrapper::getBaseTemplate).collect(Collectors.toList()));
|
||||||
|
messageTemplateRouterService.batchInsert(wrappers.stream()
|
||||||
|
.filter(e -> CollectionUtils.isNotEmpty(e.getRouters()))
|
||||||
|
.flatMap(e -> e.getRouters().stream()).collect(Collectors.toList()));
|
||||||
|
List<String> groupNodes = Lists.newArrayList(param.getGroupNodeCode());
|
||||||
|
Map<String, List<String>> templateGroupNodeMap = wrappers.stream()
|
||||||
|
.map(CreateNewTemplateAndMapWrapper::getBaseTemplate)
|
||||||
|
.collect(Collectors.toMap(MessageBaseTemplate::getCode, e -> groupNodes));
|
||||||
|
messageTemplateGroupService.templateGroup(templateGroupNodeMap);
|
||||||
|
Map<Long, String> relationIdTemplateCodeMap = wrappers.stream()
|
||||||
|
.collect(Collectors
|
||||||
|
.toMap(CreateNewTemplateAndMapWrapper::getRelationId, e -> e.getBaseTemplate().getCode()));
|
||||||
|
mapRelationAndTemplate(relationIdTemplateCodeMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CreateNewTemplateAndMapWrapper convert(Long relationId, MessageTemplate template,
|
||||||
|
List<MessageRouter> routers) {
|
||||||
|
MessageBaseTemplate baseTemplate = convert(template);
|
||||||
|
CreateNewTemplateAndMapWrapper wrapper = CreateNewTemplateAndMapWrapper.builder()
|
||||||
|
.baseTemplate(baseTemplate)
|
||||||
|
.relationId(relationId)
|
||||||
|
.build();
|
||||||
|
if (CollectionUtils.isNotEmpty(routers)) {
|
||||||
|
wrapper.setRouters(Lists.newArrayList(
|
||||||
|
RawMessageRouterDTO.from(convert(routers), baseTemplate.getCode())));
|
||||||
|
}
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MessageBaseTemplate convert(MessageTemplate srcTemplate) {
|
||||||
|
MessageBaseTemplate template = new MessageBaseTemplate();
|
||||||
|
template.setCode(UUIDUtil.uuidString());
|
||||||
|
template.setName("template_" + srcTemplate.getId());
|
||||||
|
template.setMsgCategory(MessageCategoryEnum.GENERAL_MESSAGE);
|
||||||
|
template.setTitle(srcTemplate.getTitle());
|
||||||
|
template.setContent(srcTemplate.getContent());
|
||||||
|
template.setCardContent(JSONObjectUtil.toJSONString(null));
|
||||||
|
template.setPushTerminal(JSONObjectUtil.toJSONString(PushTerminalEnum.values()));
|
||||||
|
template.setCreatorId(0L);
|
||||||
|
template.setUpdaterId(0L);
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MessageRouterButtonDTO convert(List<MessageRouter> routers) {
|
||||||
|
return MessageRouterButtonDTO.builder()
|
||||||
|
.style(Lists.newArrayList(ButtonStyleEnum.values()))
|
||||||
|
.desc("查看详情")
|
||||||
|
.category(RouterCategoryEnum.DETAIL)
|
||||||
|
.terminals(routers.stream().map(this::convert).collect(Collectors.toList()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MessageRouterTerminalDTO convert(MessageRouter router) {
|
||||||
|
return MessageRouterTerminalDTO.builder()
|
||||||
|
.url(router.getRouterUrl())
|
||||||
|
.terminalType(TerminalTypeEnum.codeOf(router.getRouterType().getCode()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<Long> getAllOriginalRelationIds() {
|
||||||
|
return relationTemplateMapDao.lambdaQuery()
|
||||||
|
.select(RelationTemplateMap::getOriginalRelationId)
|
||||||
|
.list().stream().map(RelationTemplateMap::getOriginalRelationId).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
private static class CreateNewTemplateAndMapWrapper {
|
||||||
|
private Long relationId;
|
||||||
|
private MessageBaseTemplate baseTemplate;
|
||||||
|
private List<RawMessageRouterDTO> routers;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,75 @@
|
|||||||
|
package cn.axzo.msg.center.utils;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/13
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public final class JSONObjectUtil {
|
||||||
|
private static final JSONObject EMPTY_JSON_OBJ = new JSONObject();
|
||||||
|
private static final String EMPTY_JSON_OBJ_STR = "{}";
|
||||||
|
private static final String EMPTY_JSON_ARR_STR = "[]";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析JSON字符串,若字符串格式不正确,抛异常
|
||||||
|
*
|
||||||
|
* @param str 待解析的字符串
|
||||||
|
* @return JSONObject
|
||||||
|
*/
|
||||||
|
public static JSONObject parseObject(String str) {
|
||||||
|
if (StringUtils.isBlank(str)) {
|
||||||
|
return EMPTY_JSON_OBJ;
|
||||||
|
}
|
||||||
|
return JSON.parseObject(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析JSON字符串,若字符串格式不正确,抛异常
|
||||||
|
*
|
||||||
|
* @param str 待解析的字符串
|
||||||
|
* @return List<T>
|
||||||
|
*/
|
||||||
|
public static <T> List<T> parseArray(String str, Class<T> clazz) {
|
||||||
|
if (StringUtils.isBlank(str)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return JSON.parseArray(str, clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toJSONString(Object obj) {
|
||||||
|
if (Objects.isNull(obj)) {
|
||||||
|
return EMPTY_JSON_OBJ_STR;
|
||||||
|
}
|
||||||
|
return JSON.toJSONString(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toJSONString(Collection<?> objCollection) {
|
||||||
|
if (CollectionUtils.isEmpty(objCollection)) {
|
||||||
|
return EMPTY_JSON_ARR_STR;
|
||||||
|
}
|
||||||
|
return JSON.toJSONString(objCollection);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验字符串是否为有效的JSON字符串,若字符串格式不正确,抛异常
|
||||||
|
*
|
||||||
|
* @param str 待校验的字符串
|
||||||
|
* @return 原字符串OR空的JSONObject
|
||||||
|
*/
|
||||||
|
public static String checkAndReturn(String str) {
|
||||||
|
return parseObject(str).toJSONString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,17 +3,19 @@ package cn.axzo.msg.center.utils;
|
|||||||
import cn.axzo.msg.center.common.utils.PlaceholderResolver;
|
import cn.axzo.msg.center.common.utils.PlaceholderResolver;
|
||||||
import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO;
|
import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO;
|
||||||
import cn.axzo.msg.center.service.dto.MessageRouterDTO;
|
import cn.axzo.msg.center.service.dto.MessageRouterDTO;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageRouterTerminalDTO;
|
||||||
|
import cn.axzo.msg.center.service.enums.ButtonStyleEnum;
|
||||||
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
|
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
|
||||||
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
|
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -30,31 +32,40 @@ public final class MessageRouterUtil {
|
|||||||
|
|
||||||
// 非法路由参数的定义
|
// 非法路由参数的定义
|
||||||
private static final String INVALID_ROUTER_PARAM = "null";
|
private static final String INVALID_ROUTER_PARAM = "null";
|
||||||
// 当前系统选取路由的优先级策略
|
|
||||||
private static final ImmutableMap<TerminalTypeEnum, Integer> ROUTER_SELECT_ORDER =
|
|
||||||
ImmutableMap.<TerminalTypeEnum, Integer>builder()
|
|
||||||
.put(TerminalTypeEnum.WEB_VIEW, 1)
|
|
||||||
.put(TerminalTypeEnum.MINI_PROGRAM, 2)
|
|
||||||
.put(TerminalTypeEnum.ANDROID, 3)
|
|
||||||
.put(TerminalTypeEnum.IOS, 3)
|
|
||||||
.put(TerminalTypeEnum.WEB, 3)
|
|
||||||
.put(TerminalTypeEnum.WECHAT_MINI_PROGRAM, 3)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据指定的终端类型选取合适的路由
|
* 根据指定的终端类型选取合适的路由
|
||||||
*
|
*
|
||||||
* @param messageRouters 模板配置的路由列表
|
* @param rawMessageRouter 原始的模板路由策略
|
||||||
* @param terminalType 指定的终端类型,可为null
|
* @param terminalType 当前请求的终端类型
|
||||||
* @return 合适的路由
|
* @return 合适的路由数据
|
||||||
*/
|
*/
|
||||||
public static List<RawMessageRouterDTO> selectRouter(List<RawMessageRouterDTO> messageRouters,
|
public static MessageRouterTerminalDTO select(RawMessageRouterDTO rawMessageRouter, TerminalTypeEnum terminalType) {
|
||||||
TerminalTypeEnum terminalType) {
|
if (RouterCategoryEnum.ACTION.equals(rawMessageRouter.getCategory())) {
|
||||||
if (CollectionUtils.isEmpty(messageRouters)) {
|
return rawMessageRouter.getTerminals().get(0);
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
}
|
||||||
return messageRouters.stream()
|
return rawMessageRouter.getTerminals().stream()
|
||||||
.filter(e -> Objects.equals(e.getTerminalType(), terminalType))
|
.filter(e -> Objects.equals(terminalType, e.getTerminalType()))
|
||||||
|
// 若没有匹配的,默认选择第一个然后由前端去进行最终判断
|
||||||
|
.findFirst().orElseGet(() -> rawMessageRouter.getTerminals().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据指定的终端类型选取合适的路由
|
||||||
|
*
|
||||||
|
* @param rawMessageRouter 原始的模板路由策略
|
||||||
|
* @param excludeTerminalType 待排除的终端类型
|
||||||
|
* @return 合适的路由数据
|
||||||
|
*/
|
||||||
|
public static List<MessageRouterTerminalDTO> selectWithout(RawMessageRouterDTO rawMessageRouter,
|
||||||
|
TerminalTypeEnum excludeTerminalType) {
|
||||||
|
if (RouterCategoryEnum.ACTION.equals(rawMessageRouter.getCategory())) {
|
||||||
|
// 如果配置路由是API调用,这与终端无关
|
||||||
|
return rawMessageRouter.getTerminals();
|
||||||
|
}
|
||||||
|
return rawMessageRouter.getTerminals().stream()
|
||||||
|
.filter(e -> !Objects.equals(excludeTerminalType, e.getTerminalType()))
|
||||||
|
// 若没有匹配的,默认选择第一个然后由前端去进行最终判断
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,9 +87,8 @@ public final class MessageRouterUtil {
|
|||||||
* @param routerParam 路由参数
|
* @param routerParam 路由参数
|
||||||
*/
|
*/
|
||||||
public static void parseRouteUrl(MessageRouterDTO router, String routerParam) {
|
public static void parseRouteUrl(MessageRouterDTO router, String routerParam) {
|
||||||
// 路由参数有效且是直接调整页面地址的路由类型
|
// 路由参数有效
|
||||||
if (isRouterParamValid(routerParam)
|
if (isRouterParamValid(routerParam)) {
|
||||||
&& RouterCategoryEnum.JUMP.equals(router.getCategory())) {
|
|
||||||
// 替换原始URL中的参数变量
|
// 替换原始URL中的参数变量
|
||||||
String routerUrl = PlaceholderResolver
|
String routerUrl = PlaceholderResolver
|
||||||
.getDefaultResolver().resolveByMap(router.getUrl(), JSON.parseObject(routerParam));
|
.getDefaultResolver().resolveByMap(router.getUrl(), JSON.parseObject(routerParam));
|
||||||
@ -86,21 +96,54 @@ public final class MessageRouterUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Integer compare(RawMessageRouterDTO src, RawMessageRouterDTO tgt) {
|
/**
|
||||||
if (Objects.isNull(tgt)) {
|
* 解析模板上配置的路由地址,将发送消息时的参数替换上去,并将路由参数追加到模板的路由地址后面,兼容APP端新老版本
|
||||||
// NULL 默认优先级最低
|
*
|
||||||
return 1;
|
* @param router 路由信息
|
||||||
|
* @param routerParam 路由参数
|
||||||
|
* @return RawMessageRouterDTO
|
||||||
|
*/
|
||||||
|
public static RawMessageRouterDTO parseAndConcatRouteUrl(RawMessageRouterDTO router, JSONObject routerParam) {
|
||||||
|
// 路由参数有效
|
||||||
|
if (Objects.nonNull(routerParam) && !routerParam.isEmpty()) {
|
||||||
|
// 拷贝一份,避免修改入参
|
||||||
|
router = router.deepClone();
|
||||||
|
router.getTerminals().forEach(e -> {
|
||||||
|
// 替换原始URL中的参数变量
|
||||||
|
String routerUrl = PlaceholderResolver.getDefaultResolver().resolveByMap(e.getUrl(), routerParam);
|
||||||
|
// 将routerParam追加到原始的URL后面
|
||||||
|
routerUrl = concatRouterParam(routerUrl, routerParam);
|
||||||
|
e.setUrl(routerUrl);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
Integer srcOrder = ROUTER_SELECT_ORDER.get(src.getTerminalType());
|
return router;
|
||||||
Integer tgtOrder = ROUTER_SELECT_ORDER.get(tgt.getTerminalType());
|
}
|
||||||
if (Objects.isNull(srcOrder)) {
|
|
||||||
// 新增的类型未指定优先级的话,则默认最低
|
private static String concatRouterParam(String originalUrl, JSONObject routerParam) {
|
||||||
return 1;
|
StringBuilder paramBuilder = new StringBuilder();
|
||||||
|
for (Map.Entry<String, Object> entry : routerParam.entrySet()) {
|
||||||
|
if (originalUrl.contains(entry.getKey() + "=")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
paramBuilder.append("&").append(entry.getKey()).append("=").append(entry.getValue());
|
||||||
}
|
}
|
||||||
if (Objects.isNull(tgtOrder)) {
|
if (!originalUrl.contains("?")) {
|
||||||
// 新增的类型未指定优先级的话,则默认最低
|
// 替换掉第一个参数分隔符(&)
|
||||||
return -1;
|
paramBuilder.replace(0, 1, "?");
|
||||||
}
|
}
|
||||||
return srcOrder.compareTo(tgtOrder);
|
return originalUrl + paramBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析按钮style
|
||||||
|
*
|
||||||
|
* @param style 按钮style的JSON字串
|
||||||
|
* @return 按钮style的枚举列表
|
||||||
|
*/
|
||||||
|
public static List<ButtonStyleEnum> parseButtonStyle(String style) {
|
||||||
|
if (StringUtils.isBlank(style)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return JSON.parseArray(style, ButtonStyleEnum.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,60 @@
|
|||||||
|
package cn.axzo.msg.center.utils;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.api.enums.ReceiveTypeEnum;
|
||||||
|
import cn.axzo.msg.center.domain.enums.UserTypeEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.IdentityTypeEnum;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/23
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public final class PersonIdentityUtil {
|
||||||
|
|
||||||
|
public static UserTypeEnum toUserType(IdentityTypeEnum identityType) {
|
||||||
|
switch (identityType) {
|
||||||
|
case WORKER:
|
||||||
|
return UserTypeEnum.CM;
|
||||||
|
case WORKER_LEADER:
|
||||||
|
return UserTypeEnum.TEAM;
|
||||||
|
case PRACTITIONER:
|
||||||
|
return UserTypeEnum.CMP;
|
||||||
|
default:
|
||||||
|
return UserTypeEnum.NOT_IDENTITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IdentityTypeEnum toIdentityType(ReceiveTypeEnum receiveType) {
|
||||||
|
if (Objects.isNull(receiveType)) {
|
||||||
|
return IdentityTypeEnum.NOT_SUPPORT;
|
||||||
|
}
|
||||||
|
switch (receiveType) {
|
||||||
|
case CM_WORKER:
|
||||||
|
return IdentityTypeEnum.WORKER;
|
||||||
|
case CM_LEADER:
|
||||||
|
return IdentityTypeEnum.WORKER_LEADER;
|
||||||
|
case CMP_USER:
|
||||||
|
return IdentityTypeEnum.PRACTITIONER;
|
||||||
|
default:
|
||||||
|
return IdentityTypeEnum.NOT_SUPPORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ReceiveTypeEnum toReceiveType(IdentityTypeEnum identityType) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
package cn.axzo.msg.center.utils;
|
||||||
|
|
||||||
|
import cn.axzo.basics.common.model.IBaseTree;
|
||||||
|
import cn.axzo.basics.common.util.AssertUtil;
|
||||||
|
import cn.axzo.msg.center.service.dto.GroupTreeNodeDTO;
|
||||||
|
import cn.axzo.msg.center.service.enums.MessageGroupNodeCategoryEnum;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/16
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public final class TreeHelperUtil {
|
||||||
|
|
||||||
|
public static <T extends IBaseTree<T, O>, O> T wrapper(GroupTreeNodeDTO treeNode,
|
||||||
|
Function<GroupTreeNodeDTO, T> wrapperFunc) {
|
||||||
|
AssertUtil.notNull(treeNode, "treeNode is null");
|
||||||
|
AssertUtil.notNull(wrapperFunc, "wrapperFunc is null");
|
||||||
|
|
||||||
|
final Map<GroupTreeNodeDTO, T> convertMap = Maps.newHashMap();
|
||||||
|
T root = wrapperFunc.apply(treeNode);
|
||||||
|
convertMap.put(treeNode, root);
|
||||||
|
LinkedList<GroupTreeNodeDTO> treeNodeStack = new LinkedList<>();
|
||||||
|
treeNodeStack.push(treeNode);
|
||||||
|
while (!treeNodeStack.isEmpty()) {
|
||||||
|
treeNode = treeNodeStack.pop();
|
||||||
|
List<GroupTreeNodeDTO> children = treeNode.getNodeChildren();
|
||||||
|
convertMap.get(treeNode).setNodeChildren(children.stream()
|
||||||
|
.map(e -> {
|
||||||
|
T wrapper = wrapperFunc.apply(e);
|
||||||
|
convertMap.put(e, wrapper);
|
||||||
|
return wrapper;
|
||||||
|
}).collect(Collectors.toList()));
|
||||||
|
treeNodeStack.addAll(children);
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isLeafNodeCategory(MessageGroupNodeCategoryEnum category) {
|
||||||
|
return MessageGroupNodeCategoryEnum.GENERAL_MESSAGE_CATEGORY.equals(category)
|
||||||
|
|| MessageGroupNodeCategoryEnum.PENDING_MESSAGE_CATEGORY.equals(category);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
@FeignClient(name = "msg-center", url = "${server.serviceUrl}", fallback = InsideMessageRecordApiFallBack.class)
|
@FeignClient(name = "msg-center", url = "${server.serviceUrl:http://msg-center:8080}", fallback = InsideMessageRecordApiFallBack.class)
|
||||||
@Component
|
@Component
|
||||||
public interface InsideMessageRecordApi {
|
public interface InsideMessageRecordApi {
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@FeignClient(name = "msg-center", url = "${server.serviceUrl}", fallback = InsideMessageTemplateApiFallBack.class)
|
@FeignClient(name = "msg-center", url = "${server.serviceUrl:http://msg-center:8080}", fallback = InsideMessageTemplateApiFallBack.class)
|
||||||
@Component
|
@Component
|
||||||
public interface InsideMessageTemplateApi {
|
public interface InsideMessageTemplateApi {
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* 站内消息相关接口
|
* 站内消息相关接口
|
||||||
*/
|
*/
|
||||||
@FeignClient(name = "msg-center", url = "${server.serviceUrl}", fallback = InsideNoticesApiFallBack.class)
|
@FeignClient(name = "msg-center", url = "${server.serviceUrl:http://msg-center:8080}", fallback = InsideNoticesApiFallBack.class)
|
||||||
@Component
|
@Component
|
||||||
public interface InsideNoticesApi {
|
public interface InsideNoticesApi {
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||||||
/**
|
/**
|
||||||
* 发送app push消息,底层使用友盟
|
* 发送app push消息,底层使用友盟
|
||||||
*/
|
*/
|
||||||
@FeignClient(value = "msg-center", url = "${server.serviceUrl}", fallbackFactory = MessagePushApiFallbackFactory.class)
|
@FeignClient(value = "msg-center", url = "${server.serviceUrl:http://msg-center:8080}", fallbackFactory = MessagePushApiFallbackFactory.class)
|
||||||
@Component
|
@Component
|
||||||
public interface MessagePushApi {
|
public interface MessagePushApi {
|
||||||
|
|
||||||
|
|||||||
@ -49,4 +49,11 @@ public enum MsgStateEnum {
|
|||||||
COMPLETE
|
COMPLETE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<MsgStateEnum> unreadStates() {
|
||||||
|
return Lists.newArrayList(
|
||||||
|
HAS_BEEN_SENT,
|
||||||
|
RECEIVED
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -4,6 +4,7 @@ import cn.axzo.basics.common.page.PageRequest;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author : liuchuntao
|
* @author : liuchuntao
|
||||||
@ -58,7 +59,8 @@ public class CmsMsgQueryReq extends PageRequest {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private Long identityId;
|
private Long identityId;
|
||||||
|
/**
|
||||||
|
* 待排除的消息id
|
||||||
|
*/
|
||||||
|
private List<Long> excludeMsgIds;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -92,5 +92,8 @@ public class MessageNewRes {
|
|||||||
*/
|
*/
|
||||||
private Integer oldTypeId;
|
private Integer oldTypeId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private Date createAt;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,53 +0,0 @@
|
|||||||
package cn.axzo.msg.center.service.dto;
|
|
||||||
|
|
||||||
import cn.axzo.msg.center.service.enums.MessageGroupNodeCategoryEnum;
|
|
||||||
import cn.axzo.msg.center.service.enums.StatusEnum;
|
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description
|
|
||||||
*
|
|
||||||
* @author cold_blade
|
|
||||||
* @date 2023/9/23
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
@Setter
|
|
||||||
@Getter
|
|
||||||
public class GroupNodeDTO implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -5935469947222698608L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 模板分组结点名称
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
/**
|
|
||||||
* 模板分组结点名称code
|
|
||||||
*/
|
|
||||||
private String code;
|
|
||||||
/**
|
|
||||||
* 结点类型
|
|
||||||
*/
|
|
||||||
private MessageGroupNodeCategoryEnum category;
|
|
||||||
/**
|
|
||||||
* 父节点
|
|
||||||
*/
|
|
||||||
private String parentCode;
|
|
||||||
/**
|
|
||||||
* 是否为叶节点
|
|
||||||
*/
|
|
||||||
private Integer isLeaf;
|
|
||||||
/**
|
|
||||||
* 状态
|
|
||||||
*/
|
|
||||||
private StatusEnum status;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return JSON.toJSONString(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
package cn.axzo.msg.center.service.dto;
|
||||||
|
|
||||||
|
import cn.axzo.basics.common.model.IBaseTree;
|
||||||
|
import cn.axzo.msg.center.service.enums.MessageGroupNodeCategoryEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.StatusEnum;
|
||||||
|
import cn.axzo.msg.center.service.group.response.MessageGroupTreeNodeResponse;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/14
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class GroupTreeNodeDTO implements IBaseTree<GroupTreeNodeDTO, String>, Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -3244632155934087302L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板分组结点名称
|
||||||
|
*/
|
||||||
|
private String nodeName;
|
||||||
|
/**
|
||||||
|
* 模板分组结点名称code
|
||||||
|
*/
|
||||||
|
private String nodeCode;
|
||||||
|
/**
|
||||||
|
* 结点类型
|
||||||
|
*/
|
||||||
|
private MessageGroupNodeCategoryEnum category;
|
||||||
|
/**
|
||||||
|
* 父节点
|
||||||
|
*/
|
||||||
|
private String parentNodeCode;
|
||||||
|
/**
|
||||||
|
* 是否为叶节点
|
||||||
|
*/
|
||||||
|
private Integer isLeaf;
|
||||||
|
/**
|
||||||
|
* 状态
|
||||||
|
*/
|
||||||
|
private StatusEnum status;
|
||||||
|
/**
|
||||||
|
* 子节点列表
|
||||||
|
*/
|
||||||
|
@Builder.Default
|
||||||
|
private List<GroupTreeNodeDTO> nodeChildren = Collections.emptyList();
|
||||||
|
|
||||||
|
public void setNodeChildren(List<GroupTreeNodeDTO> nodeChildren) {
|
||||||
|
this.nodeChildren = Optional.ofNullable(nodeChildren).orElseGet(Collections::emptyList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageGroupTreeNodeResponse toMessageGroupTreeNodeResponse() {
|
||||||
|
List<MessageGroupTreeNodeResponse> children = Optional.ofNullable(nodeChildren)
|
||||||
|
.map(v -> v.stream().map(GroupTreeNodeDTO::toMessageGroupTreeNodeResponse).collect(Collectors.toList()))
|
||||||
|
.orElseGet(Collections::emptyList);
|
||||||
|
return MessageGroupTreeNodeResponse.builder()
|
||||||
|
.category(category)
|
||||||
|
.nodeName(nodeName)
|
||||||
|
.nodeCode(nodeCode)
|
||||||
|
.parentNodeCode(parentNodeCode)
|
||||||
|
.children(children)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<GroupTreeNodeDTO> getChild(String treeNodeCode) {
|
||||||
|
if (StringUtils.isBlank(treeNodeCode) || Objects.isNull(nodeChildren)) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
return nodeChildren.stream()
|
||||||
|
.filter(e -> Objects.equals(e.getNodeCode(), treeNodeCode))
|
||||||
|
.findFirst();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
package cn.axzo.msg.center.service.dto;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/11
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class MessageBaseTemplateDTO implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -7079227473990043416L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 系统自动生成的模板code
|
||||||
|
*/
|
||||||
|
private String code;
|
||||||
|
/**
|
||||||
|
* 所属消息类型
|
||||||
|
*/
|
||||||
|
private MessageCategoryEnum msgCategory;
|
||||||
|
/**
|
||||||
|
* 模板标题
|
||||||
|
*/
|
||||||
|
private String title;
|
||||||
|
/**
|
||||||
|
* 模板类容
|
||||||
|
*/
|
||||||
|
private String content;
|
||||||
|
/**
|
||||||
|
* 卡片信息标签列表
|
||||||
|
*/
|
||||||
|
private List<MessageCardContentItemDTO> cardContentItems;
|
||||||
|
/**
|
||||||
|
* 模板icon
|
||||||
|
*/
|
||||||
|
private String icon;
|
||||||
|
/**
|
||||||
|
* 推送终端配置列表
|
||||||
|
*/
|
||||||
|
private List<PushTerminalEnum> pushTerminals;
|
||||||
|
/**
|
||||||
|
* 消息模板创建时间戳
|
||||||
|
*/
|
||||||
|
private Long createTimestamp;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
package cn.axzo.msg.center.service.dto;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/20
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class MessageCardContentItemDTO implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -8696875791099408327L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 卡片内容标签
|
||||||
|
*/
|
||||||
|
private String label;
|
||||||
|
/**
|
||||||
|
* 卡片内容标签值
|
||||||
|
*/
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public MessageCardContentItemDTO deepClone() {
|
||||||
|
return MessageCardContentItemDTO.builder()
|
||||||
|
.label(this.label)
|
||||||
|
.value(this.value)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
package cn.axzo.msg.center.service.dto;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.enums.ButtonStyleEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description
|
||||||
|
*
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/9/23
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class MessageRouterButtonDTO implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -9083376003614521781L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由描述
|
||||||
|
*/
|
||||||
|
private String desc;
|
||||||
|
/**
|
||||||
|
* 路由分类
|
||||||
|
* JUMP: 直接跳转
|
||||||
|
* ACTION: 接口调用
|
||||||
|
* DETAIL: 页面详情
|
||||||
|
*/
|
||||||
|
private RouterCategoryEnum category;
|
||||||
|
/**
|
||||||
|
* 按钮样式配置
|
||||||
|
* HIGH_LIGHT: 按钮高亮展示
|
||||||
|
* OVER_CARD: 按钮显示在卡片上
|
||||||
|
*/
|
||||||
|
private List<ButtonStyleEnum> style;
|
||||||
|
/**
|
||||||
|
* 路由终端列表,若当前按钮为ACTION,则只能配一个接口地址
|
||||||
|
*/
|
||||||
|
private List<MessageRouterTerminalDTO> terminals;
|
||||||
|
|
||||||
|
public boolean isHighlight() {
|
||||||
|
return CollectionUtils.isNotEmpty(style)
|
||||||
|
&& style.stream().anyMatch(ButtonStyleEnum.HIGH_LIGHT::equals);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShowOnCard() {
|
||||||
|
return CollectionUtils.isNotEmpty(style)
|
||||||
|
&& style.stream().anyMatch(ButtonStyleEnum.OVER_CARD::equals);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
package cn.axzo.msg.center.service.dto;
|
package cn.axzo.msg.center.service.dto;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.enums.ButtonStyleEnum;
|
||||||
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
|
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
|
||||||
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
|
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
@ -10,6 +11,7 @@ import lombok.NoArgsConstructor;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description
|
* @description
|
||||||
@ -51,6 +53,12 @@ public class MessageRouterDTO implements Serializable {
|
|||||||
* WECHAT_MINI_PROGRAM: 微信小程序页面
|
* WECHAT_MINI_PROGRAM: 微信小程序页面
|
||||||
*/
|
*/
|
||||||
private TerminalTypeEnum terminalType;
|
private TerminalTypeEnum terminalType;
|
||||||
|
/**
|
||||||
|
* 按钮样式配置
|
||||||
|
* HIGH_LIGHT: 按钮高亮展示
|
||||||
|
* OVER_CARD: 按钮显示在卡片
|
||||||
|
*/
|
||||||
|
private List<ButtonStyleEnum> style;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|||||||
@ -0,0 +1,53 @@
|
|||||||
|
package cn.axzo.msg.center.service.dto;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/12
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class MessageRouterTerminalDTO implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 4084885624985898305L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面地址 OR API接口地址
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
/**
|
||||||
|
* 页面地址所属应用端(如果是API接口地址,请忽略改字段值)
|
||||||
|
* WEB: web端页面
|
||||||
|
* MINI_PROGRAM: 安心筑小程序端页面
|
||||||
|
* IOS: 原生IOS端页面
|
||||||
|
* ANDROID: 原生Android端页面
|
||||||
|
* WEB_VIEW: H5页面
|
||||||
|
* WECHAT_MINI_PROGRAM: 微信小程序页面
|
||||||
|
*/
|
||||||
|
private TerminalTypeEnum terminalType;
|
||||||
|
|
||||||
|
public MessageRouterTerminalDTO deepClone() {
|
||||||
|
return MessageRouterTerminalDTO.builder()
|
||||||
|
.terminalType(this.terminalType)
|
||||||
|
.url(this.url)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,6 +9,7 @@ import lombok.NoArgsConstructor;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description
|
* @description
|
||||||
@ -46,6 +47,11 @@ public class PersonDTO implements Serializable {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return Objects.nonNull(id) && id > 0
|
||||||
|
&& Objects.nonNull(identity) && identity.isValid();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return JSON.toJSONString(this);
|
return JSON.toJSONString(this);
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
package cn.axzo.msg.center.service.enums;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按钮style枚举
|
||||||
|
*
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/11
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public enum ButtonStyleEnum {
|
||||||
|
|
||||||
|
HIGH_LIGHT("按钮高亮展示"), OVER_CARD("按钮显示在卡片"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final String desc;
|
||||||
|
}
|
||||||
@ -15,13 +15,15 @@ import lombok.Getter;
|
|||||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public enum MessageGroupNodeCategoryEnum {
|
public enum MessageGroupNodeCategoryEnum {
|
||||||
|
|
||||||
GENERAL_MESSAGE_CENTER("消息中心"),
|
GENERAL_MESSAGE_CENTER("消息中心", 1, MessageCategoryEnum.GENERAL_MESSAGE),
|
||||||
GENERAL_MESSAGE_MODULE("消息模块"),
|
GENERAL_MESSAGE_MODULE("消息模块", 2, MessageCategoryEnum.GENERAL_MESSAGE),
|
||||||
GENERAL_MESSAGE_CATEGORY("消息分类"),
|
GENERAL_MESSAGE_CATEGORY("消息分类", 3, MessageCategoryEnum.GENERAL_MESSAGE),
|
||||||
PENDING_MESSAGE_CENTER("待办中心"),
|
PENDING_MESSAGE_CENTER("待办中心", 1, MessageCategoryEnum.PENDING_MESSAGE),
|
||||||
PENDING_MESSAGE_MODULE("待办模块"),
|
PENDING_MESSAGE_MODULE("待办模块", 2, MessageCategoryEnum.PENDING_MESSAGE),
|
||||||
PENDING_MESSAGE_CATEGORY("待办分类"),
|
PENDING_MESSAGE_CATEGORY("待办分类", 3, MessageCategoryEnum.PENDING_MESSAGE),
|
||||||
;
|
;
|
||||||
|
|
||||||
private final String desc;
|
private final String desc;
|
||||||
|
private final int level;
|
||||||
|
private final MessageCategoryEnum msgCategory;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,29 @@
|
|||||||
|
package cn.axzo.msg.center.service.enums;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 推送终端枚举
|
||||||
|
*
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/11
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public enum PushTerminalEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* B-安心筑企业版
|
||||||
|
*/
|
||||||
|
B_ENTERPRISE_APP("B-安心筑企业版"),
|
||||||
|
/**
|
||||||
|
* C-安心筑工人版
|
||||||
|
*/
|
||||||
|
C_WORKER_APP("C-安心筑工人版"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final String desc;
|
||||||
|
}
|
||||||
@ -16,7 +16,9 @@ import lombok.Getter;
|
|||||||
public enum RouterCategoryEnum {
|
public enum RouterCategoryEnum {
|
||||||
|
|
||||||
JUMP("直接跳转"),
|
JUMP("直接跳转"),
|
||||||
ACTION("接口调用");
|
ACTION("接口调用"),
|
||||||
|
DETAIL("页面详情"),
|
||||||
|
;
|
||||||
|
|
||||||
private final String desc;
|
private final String desc;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import lombok.AccessLevel;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description
|
* @description
|
||||||
*
|
*
|
||||||
@ -20,7 +22,12 @@ public enum TerminalTypeEnum {
|
|||||||
IOS(3, "ios"),
|
IOS(3, "ios"),
|
||||||
ANDROID(4, "android"),
|
ANDROID(4, "android"),
|
||||||
WEB_VIEW(5, "webview"),
|
WEB_VIEW(5, "webview"),
|
||||||
WECHAT_MINI_PROGRAM(6, "wechat mini-program");
|
WECHAT_MINI_PROGRAM(6, "wechat mini-program"),
|
||||||
|
/**
|
||||||
|
* 所有端
|
||||||
|
*/
|
||||||
|
ALL(-1, "all"),
|
||||||
|
;
|
||||||
|
|
||||||
private final Integer code;
|
private final Integer code;
|
||||||
private final String desc;
|
private final String desc;
|
||||||
@ -40,4 +47,10 @@ public enum TerminalTypeEnum {
|
|||||||
}
|
}
|
||||||
return WEB;
|
return WEB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TerminalTypeEnum codeOf(Integer code) {
|
||||||
|
return Arrays.stream(values())
|
||||||
|
.filter(e -> e.code.equals(code))
|
||||||
|
.findFirst().orElse(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,68 @@
|
|||||||
|
package cn.axzo.msg.center.service.general.client;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.api.request.CmsMsgQueryReq;
|
||||||
|
import cn.axzo.msg.center.api.response.MessageNewRes;
|
||||||
|
import cn.axzo.msg.center.service.general.client.fallback.GeneralMessageClientFallback;
|
||||||
|
import cn.axzo.msg.center.service.general.request.GeneralMessageOldDataStatisticRequest;
|
||||||
|
import cn.axzo.msg.center.service.general.request.GeneralMessageSendRequest;
|
||||||
|
import cn.axzo.msg.center.service.general.response.GeneralMessageOldDataStatisticResponse;
|
||||||
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
|
import cn.azxo.framework.common.model.Page;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 普通消息模块
|
||||||
|
*
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@FeignClient(value = "msg-center", url = "${server.serviceUrl:http://msg-center:8080}",
|
||||||
|
fallback = GeneralMessageClientFallback.class)
|
||||||
|
public interface GeneralMessageClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送消息
|
||||||
|
*
|
||||||
|
* @param request 消息所需参数
|
||||||
|
* @return 消息的唯一标识
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@PostMapping(value = "/general-message/send", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
|
CommonResponse<Void> batchSend(@RequestBody @Valid GeneralMessageSendRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计旧消息的未读数以及最新一条消息内容
|
||||||
|
*
|
||||||
|
* @param request 消息所需参数
|
||||||
|
* @return 消息未读数&最新一条消息内容
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/general-message/old-data/statistic", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
|
CommonResponse<GeneralMessageOldDataStatisticResponse> statisticOldData(
|
||||||
|
@RequestBody @Valid GeneralMessageOldDataStatisticRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计旧消息的未读数
|
||||||
|
*
|
||||||
|
* @param request 消息所需参数
|
||||||
|
* @return 消息未读数
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/general-message/old-data/count-unread", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
|
CommonResponse<Integer> countUnreadFromOldMessage(@RequestBody @Valid GeneralMessageOldDataStatisticRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 旧消息的分页查询入口
|
||||||
|
*
|
||||||
|
* @param request 分页查询所需参数
|
||||||
|
* @return 旧消息的分页列表
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/general-message/old-data/page", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
|
CommonResponse<Page<MessageNewRes>> pageQueryOldMessage(@RequestBody @Valid CmsMsgQueryReq request);
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
package cn.axzo.msg.center.service.general.client.fallback;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.api.request.CmsMsgQueryReq;
|
||||||
|
import cn.axzo.msg.center.api.response.MessageNewRes;
|
||||||
|
import cn.axzo.msg.center.service.general.client.GeneralMessageClient;
|
||||||
|
import cn.axzo.msg.center.service.general.request.GeneralMessageOldDataStatisticRequest;
|
||||||
|
import cn.axzo.msg.center.service.general.request.GeneralMessageSendRequest;
|
||||||
|
import cn.axzo.msg.center.service.general.response.GeneralMessageOldDataStatisticResponse;
|
||||||
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
|
import cn.azxo.framework.common.model.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class GeneralMessageClientFallback implements GeneralMessageClient {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Void> batchSend(GeneralMessageSendRequest request) {
|
||||||
|
log.error("fall back while batch sending im message. req:{}", request);
|
||||||
|
return CommonResponse.error("fall back while batch sending im message");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<GeneralMessageOldDataStatisticResponse> statisticOldData(
|
||||||
|
GeneralMessageOldDataStatisticRequest request) {
|
||||||
|
log.error("fall back while statistic old message. req:{}", request);
|
||||||
|
return CommonResponse.error("fall back while statistic old message");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Integer> countUnreadFromOldMessage(GeneralMessageOldDataStatisticRequest request) {
|
||||||
|
log.error("fall back while counting unread old message. request:{}", request);
|
||||||
|
return CommonResponse.error("fall back while counting unread old message");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Page<MessageNewRes>> pageQueryOldMessage(CmsMsgQueryReq request) {
|
||||||
|
log.error("fall back while statistic old message. request:{}", request);
|
||||||
|
return CommonResponse.error("fall back while statistic old message");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
package cn.axzo.msg.center.service.general.request;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.enums.IdentityTypeEnum;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/23
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class GeneralMessageOldDataStatisticRequest implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -7739989493953842047L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自然人id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "personId is required")
|
||||||
|
private Long personId;
|
||||||
|
/**
|
||||||
|
* 身份id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "identityId is required")
|
||||||
|
private Long identityId;
|
||||||
|
/**
|
||||||
|
* 身份类型
|
||||||
|
*/
|
||||||
|
@NotNull(message = "identityType is required")
|
||||||
|
private IdentityTypeEnum identityType;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
package cn.axzo.msg.center.service.general.request;
|
||||||
|
|
||||||
|
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;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description
|
||||||
|
* 发送消息
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class GeneralMessageSendRequest implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -3030926259836918967L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板编码
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "templateCode is required")
|
||||||
|
private String templateCode;
|
||||||
|
/**
|
||||||
|
* 消息发送者信息,可为空,默认模板对应的IM机器人
|
||||||
|
*/
|
||||||
|
private PersonDTO sender;
|
||||||
|
/**
|
||||||
|
* 消息接收信息
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "receiver is required")
|
||||||
|
private Collection<PersonDTO> receiver;
|
||||||
|
/**
|
||||||
|
* 消息所属组织类型
|
||||||
|
*/
|
||||||
|
private OrganizationTypeEnum orgType;
|
||||||
|
/**
|
||||||
|
* 消息所属组织Id
|
||||||
|
*/
|
||||||
|
private Long orgId;
|
||||||
|
/**
|
||||||
|
* 消息所属组织名称
|
||||||
|
*/
|
||||||
|
private String orgName;
|
||||||
|
/**
|
||||||
|
* 发送消息的业务编码
|
||||||
|
*/
|
||||||
|
private String bizCode;
|
||||||
|
/**
|
||||||
|
* 路由参数
|
||||||
|
* 注:该字段仅存放路由相关的变量及对应的值
|
||||||
|
*/
|
||||||
|
private JSONObject routerParams;
|
||||||
|
/**
|
||||||
|
* 业务扩展参数
|
||||||
|
* 注:标题/内容/以及卡片等的变量及对应的值放到该字段
|
||||||
|
*/
|
||||||
|
private JSONObject bizExtParams;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package cn.axzo.msg.center.service.general.response;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description
|
||||||
|
* 普通消息记录统计数模型
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/23
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class GeneralMessageOldDataStatisticResponse implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 5740922087866033787L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息的未读数
|
||||||
|
*/
|
||||||
|
private Integer unreadCount;
|
||||||
|
/**
|
||||||
|
* 最新的一条消息的发送时间戳
|
||||||
|
*/
|
||||||
|
private Long latestMsgSendTimestamp;
|
||||||
|
/**
|
||||||
|
* 最新的一条消息的消息内容
|
||||||
|
*/
|
||||||
|
private String latestMsgContent;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,117 @@
|
|||||||
|
package cn.axzo.msg.center.service.general.response;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.dto.IdentityDTO;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageRouterDTO;
|
||||||
|
import cn.axzo.msg.center.service.enums.OrganizationTypeEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description
|
||||||
|
* 普通消息记录数模型
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/18
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class GeneralMessageResponse implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 5740922087866033787L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息的唯一标识
|
||||||
|
*/
|
||||||
|
private String identityCode;
|
||||||
|
/**
|
||||||
|
* 模板编码
|
||||||
|
*/
|
||||||
|
private String templateCode;
|
||||||
|
/**
|
||||||
|
* 模板icon地址
|
||||||
|
*/
|
||||||
|
private String templateIcon;
|
||||||
|
/**
|
||||||
|
* 消息标题
|
||||||
|
*/
|
||||||
|
private String title;
|
||||||
|
/**
|
||||||
|
* 消息内容
|
||||||
|
*/
|
||||||
|
private String content;
|
||||||
|
/**
|
||||||
|
* 卡片信息
|
||||||
|
*/
|
||||||
|
private String cardContent;
|
||||||
|
/**
|
||||||
|
* 消息发送者自然人id
|
||||||
|
*/
|
||||||
|
private Long senderPersonId;
|
||||||
|
/**
|
||||||
|
* 消息发送者身份
|
||||||
|
*/
|
||||||
|
private IdentityDTO senderIdentity;
|
||||||
|
/**
|
||||||
|
* 消息接收者自然人id
|
||||||
|
*/
|
||||||
|
private Long receiverPersonId;
|
||||||
|
/**
|
||||||
|
* 消息接收者身份
|
||||||
|
*/
|
||||||
|
private IdentityDTO receiverIdentity;
|
||||||
|
/**
|
||||||
|
* 消息所属组织类型
|
||||||
|
*/
|
||||||
|
private OrganizationTypeEnum orgType;
|
||||||
|
/**
|
||||||
|
* 消息所属组织Id
|
||||||
|
*/
|
||||||
|
private Long orgId;
|
||||||
|
/**
|
||||||
|
* 消息所属组织名称
|
||||||
|
*/
|
||||||
|
private String orgName;
|
||||||
|
/**
|
||||||
|
* 业务编码
|
||||||
|
*/
|
||||||
|
private String bizCode;
|
||||||
|
/**
|
||||||
|
* 业务状态描述
|
||||||
|
*/
|
||||||
|
private String bizDesc;
|
||||||
|
/**
|
||||||
|
* 消息发送时间戳
|
||||||
|
*/
|
||||||
|
private Long sendTimestamp;
|
||||||
|
/**
|
||||||
|
* 路由信息,可为空
|
||||||
|
*/
|
||||||
|
private List<MessageRouterDTO> routers;
|
||||||
|
/**
|
||||||
|
* 参数及其对应的值的JSON串
|
||||||
|
*/
|
||||||
|
private JSONObject routerParams;
|
||||||
|
/**
|
||||||
|
* 发送终端,eg:
|
||||||
|
* B_ENTERPRISE_APP:B-安心筑企业版
|
||||||
|
* C_WORKER_APP:C-安心筑工人版
|
||||||
|
*/
|
||||||
|
private List<PushTerminalEnum> pushTerminals;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +1,10 @@
|
|||||||
package cn.axzo.msg.center.service.group.client;
|
package cn.axzo.msg.center.service.group.client;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
|
||||||
import cn.axzo.msg.center.service.group.client.fallback.MessageGroupClientFallback;
|
import cn.axzo.msg.center.service.group.client.fallback.MessageGroupClientFallback;
|
||||||
import cn.axzo.msg.center.service.group.request.MessageGroupNodeAddRequest;
|
import cn.axzo.msg.center.service.group.request.MessageGroupNodeAddRequest;
|
||||||
import cn.axzo.msg.center.service.group.request.MessageGroupNodeUpdateRequest;
|
import cn.axzo.msg.center.service.group.request.MessageGroupNodeUpdateRequest;
|
||||||
|
import cn.axzo.msg.center.service.group.response.MessageGroupTreeNodeResponse;
|
||||||
import cn.azxo.framework.common.model.CommonResponse;
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
import org.springframework.cloud.openfeign.FeignClient;
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
@ -12,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息分类管理
|
* 消息分类管理
|
||||||
@ -40,7 +43,7 @@ public interface MessageGroupClient {
|
|||||||
* @param request 待更新的结点相关数据项
|
* @param request 待更新的结点相关数据项
|
||||||
*/
|
*/
|
||||||
@PostMapping(value = "/message/group/node/update", produces = {MediaType.APPLICATION_JSON_VALUE})
|
@PostMapping(value = "/message/group/node/update", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
CommonResponse<Void> updateStatus(@RequestBody MessageGroupNodeUpdateRequest request);
|
CommonResponse<Void> updateNode(@RequestBody @Valid MessageGroupNodeUpdateRequest request);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除结点
|
* 删除结点
|
||||||
@ -50,4 +53,13 @@ public interface MessageGroupClient {
|
|||||||
@PostMapping(value = "/message/group/node/delete", produces = {MediaType.APPLICATION_JSON_VALUE})
|
@PostMapping(value = "/message/group/node/delete", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
CommonResponse<Void> deleteNode(@RequestParam("nodeCode") String nodeCode,
|
CommonResponse<Void> deleteNode(@RequestParam("nodeCode") String nodeCode,
|
||||||
@RequestParam("operatorId") Long operatorId);
|
@RequestParam("operatorId") Long operatorId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询通知/待办的分类信息
|
||||||
|
*
|
||||||
|
* @param category 消息分类
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/message/group/node/list", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
|
CommonResponse<List<MessageGroupTreeNodeResponse>> list(@RequestParam(value = "category", required = false)
|
||||||
|
MessageCategoryEnum category);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,56 @@
|
|||||||
|
package cn.axzo.msg.center.service.group.client;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.group.client.fallback.MessageGroupClientFallback;
|
||||||
|
import cn.axzo.msg.center.service.group.request.MessageTemplateGroupRelationMoveRequest;
|
||||||
|
import cn.axzo.msg.center.service.group.request.MessageTemplateGroupRelationPageRequest;
|
||||||
|
import cn.axzo.msg.center.service.group.request.MessageTemplateGroupRelationRemoveRequest;
|
||||||
|
import cn.axzo.msg.center.service.group.response.MessageTemplateGroupRelationResponse;
|
||||||
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
|
import cn.azxo.framework.common.model.Page;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/12
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@FeignClient(value = "msg-center", url = "${server.serviceUrl:http://msg-center:8080}",
|
||||||
|
fallback = MessageGroupClientFallback.class)
|
||||||
|
public interface MessageTemplateGroupRelationClient {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询分类下关联的模板列表
|
||||||
|
*
|
||||||
|
* @param request 分类结点的编码及分页参数
|
||||||
|
* @return 模板列表
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/message/template/group-relation/page", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
|
CommonResponse<Page<MessageTemplateGroupRelationResponse>> page(
|
||||||
|
@RequestBody @Valid MessageTemplateGroupRelationPageRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变更模板与分类的关联关系
|
||||||
|
*
|
||||||
|
* @param request 变更分类的相关参数
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/message/template/group-relation/move", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
|
CommonResponse<Void> move(@RequestBody @Valid MessageTemplateGroupRelationMoveRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解除分类与模板的关联关系
|
||||||
|
*
|
||||||
|
* @param request 变更分类的相关参数
|
||||||
|
* @return 关联关系解除失败的模板编码
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/message/template/group-relation/remove", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
|
CommonResponse<Void> remove(@RequestBody @Valid MessageTemplateGroupRelationRemoveRequest request);
|
||||||
|
}
|
||||||
@ -1,12 +1,16 @@
|
|||||||
package cn.axzo.msg.center.service.group.client.fallback;
|
package cn.axzo.msg.center.service.group.client.fallback;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
|
||||||
import cn.axzo.msg.center.service.group.client.MessageGroupClient;
|
import cn.axzo.msg.center.service.group.client.MessageGroupClient;
|
||||||
import cn.axzo.msg.center.service.group.request.MessageGroupNodeAddRequest;
|
import cn.axzo.msg.center.service.group.request.MessageGroupNodeAddRequest;
|
||||||
import cn.axzo.msg.center.service.group.request.MessageGroupNodeUpdateRequest;
|
import cn.axzo.msg.center.service.group.request.MessageGroupNodeUpdateRequest;
|
||||||
|
import cn.axzo.msg.center.service.group.response.MessageGroupTreeNodeResponse;
|
||||||
import cn.azxo.framework.common.model.CommonResponse;
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description
|
* @description
|
||||||
*
|
*
|
||||||
@ -24,7 +28,7 @@ public class MessageGroupClientFallback implements MessageGroupClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResponse<Void> updateStatus(MessageGroupNodeUpdateRequest request) {
|
public CommonResponse<Void> updateNode(MessageGroupNodeUpdateRequest request) {
|
||||||
log.error("fall back while updating message group node. request:{}", request);
|
log.error("fall back while updating message group node. request:{}", request);
|
||||||
return CommonResponse.error("fall back while updating message group node");
|
return CommonResponse.error("fall back while updating message group node");
|
||||||
}
|
}
|
||||||
@ -34,4 +38,10 @@ public class MessageGroupClientFallback implements MessageGroupClient {
|
|||||||
log.error("fall back while deleting message group node. nodeCode:[{}], operatorId:[{}]", nodeCode, operatorId);
|
log.error("fall back while deleting message group node. nodeCode:[{}], operatorId:[{}]", nodeCode, operatorId);
|
||||||
return CommonResponse.error("fall back while deleting message group node");
|
return CommonResponse.error("fall back while deleting message group node");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<List<MessageGroupTreeNodeResponse>> list(MessageCategoryEnum category) {
|
||||||
|
log.error("fall back while listing message group node. category:[{}]", category);
|
||||||
|
return CommonResponse.error("fall back while listing message group node");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,42 @@
|
|||||||
|
package cn.axzo.msg.center.service.group.client.fallback;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.group.client.MessageTemplateGroupRelationClient;
|
||||||
|
import cn.axzo.msg.center.service.group.request.MessageTemplateGroupRelationMoveRequest;
|
||||||
|
import cn.axzo.msg.center.service.group.request.MessageTemplateGroupRelationPageRequest;
|
||||||
|
import cn.axzo.msg.center.service.group.request.MessageTemplateGroupRelationRemoveRequest;
|
||||||
|
import cn.axzo.msg.center.service.group.response.MessageTemplateGroupRelationResponse;
|
||||||
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
|
import cn.azxo.framework.common.model.Page;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/12
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class MessageTemplateGroupRelationClientFallback implements MessageTemplateGroupRelationClient {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Page<MessageTemplateGroupRelationResponse>> page(
|
||||||
|
MessageTemplateGroupRelationPageRequest request) {
|
||||||
|
log.error("fall back while page querying message template group relation. request:{}", request);
|
||||||
|
return CommonResponse.error("fall back while page querying message template group relation");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Void> move(MessageTemplateGroupRelationMoveRequest request) {
|
||||||
|
log.error("fall back while moving message template group relation. request:{}", request);
|
||||||
|
return CommonResponse.error("fall back while moving message template group relation");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Void> remove(MessageTemplateGroupRelationRemoveRequest request) {
|
||||||
|
log.error("fall back while removing message template group relation. request:{}", request);
|
||||||
|
return CommonResponse.error("fall back while removing message template group relation");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -36,13 +36,14 @@ public class MessageGroupNodeAddRequest implements Serializable {
|
|||||||
*/
|
*/
|
||||||
@NotEmpty(message = "nodeName is required")
|
@NotEmpty(message = "nodeName is required")
|
||||||
private String nodeName;
|
private String nodeName;
|
||||||
/**
|
|
||||||
* 待添加结点编码
|
|
||||||
*/
|
|
||||||
@NotEmpty(message = "nodeCode is required")
|
|
||||||
private String nodeCode;
|
|
||||||
/**
|
/**
|
||||||
* 待添加结点类型
|
* 待添加结点类型
|
||||||
|
* GENERAL_MESSAGE_CENTER: 通知的业务中心
|
||||||
|
* GENERAL_MESSAGE_MODULE: 消息模块
|
||||||
|
* GENERAL_MESSAGE_CATEGORY: 消息分类
|
||||||
|
* PENDING_MESSAGE_CENTER: 待办的业务中心
|
||||||
|
* PENDING_MESSAGE_MODULE: 待办模块
|
||||||
|
* PENDING_MESSAGE_CATEGORY: 待办分类
|
||||||
*/
|
*/
|
||||||
@NotNull(message = "category is required")
|
@NotNull(message = "category is required")
|
||||||
private MessageGroupNodeCategoryEnum category;
|
private MessageGroupNodeCategoryEnum category;
|
||||||
|
|||||||
@ -39,6 +39,8 @@ public class MessageGroupNodeUpdateRequest implements Serializable {
|
|||||||
private String nodeName;
|
private String nodeName;
|
||||||
/**
|
/**
|
||||||
* 结点状态
|
* 结点状态
|
||||||
|
* ENABLE: 启用
|
||||||
|
* DISABLE: 禁用
|
||||||
*/
|
*/
|
||||||
private StatusEnum status;
|
private StatusEnum status;
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -0,0 +1,49 @@
|
|||||||
|
package cn.axzo.msg.center.service.group.request;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/12
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class MessageTemplateGroupRelationMoveRequest implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 8336083457743619246L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作者的自然人id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "operatorId is required")
|
||||||
|
private Long operatorId;
|
||||||
|
/**
|
||||||
|
* 模板当前所处的分类结点编码
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "curNodeCode is required")
|
||||||
|
private String curNodeCode;
|
||||||
|
/**
|
||||||
|
* 模板将要移动到的目标分类结点编码
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "targetNodeCode is required")
|
||||||
|
private String targetNodeCode;
|
||||||
|
/**
|
||||||
|
* 选中的模板编码列表
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "templateCodes is required")
|
||||||
|
private List<String> templateCodes;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package cn.axzo.msg.center.service.group.request;
|
||||||
|
|
||||||
|
import cn.axzo.basics.common.page.PageRequest;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/16
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class MessageTemplateGroupRelationPageRequest extends PageRequest implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -4297862224638557525L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分类结点编码
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "nodeCode is required")
|
||||||
|
private String nodeCode;
|
||||||
|
/**
|
||||||
|
* 模板名称
|
||||||
|
*/
|
||||||
|
private String templateName;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package cn.axzo.msg.center.service.group.request;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/12
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class MessageTemplateGroupRelationRemoveRequest implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 8336083457743619246L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作者的自然人id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "operatorId is required")
|
||||||
|
private Long operatorId;
|
||||||
|
/**
|
||||||
|
* 模板当前所处的分类结点编码
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "curNodeCode is required")
|
||||||
|
private String curNodeCode;
|
||||||
|
/**
|
||||||
|
* 选中的模板编码列表
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "templateCodes is required")
|
||||||
|
private List<String> templateCodes;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
package cn.axzo.msg.center.service.group.response;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.enums.MessageGroupNodeCategoryEnum;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/12
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class MessageGroupTreeNodeResponse implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -6741888813327778598L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结点类型
|
||||||
|
* GENERAL_MESSAGE_CENTER: 消息中心
|
||||||
|
* GENERAL_MESSAGE_MODULE: 消息模块
|
||||||
|
* GENERAL_MESSAGE_CATEGORY: 消息分类
|
||||||
|
* PENDING_MESSAGE_CENTER: 待办中心
|
||||||
|
* PENDING_MESSAGE_MODULE: 待办模块
|
||||||
|
* PENDING_MESSAGE_CATEGORY: 待办分类
|
||||||
|
*/
|
||||||
|
private MessageGroupNodeCategoryEnum category;
|
||||||
|
/**
|
||||||
|
* 结点名称
|
||||||
|
*/
|
||||||
|
private String nodeName;
|
||||||
|
/**
|
||||||
|
* 结点编码
|
||||||
|
*/
|
||||||
|
private String nodeCode;
|
||||||
|
/**
|
||||||
|
* 父节点编码
|
||||||
|
*/
|
||||||
|
private String parentNodeCode;
|
||||||
|
/**
|
||||||
|
* 子节点列表
|
||||||
|
*/
|
||||||
|
private List<MessageGroupTreeNodeResponse> children;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
package cn.axzo.msg.center.service.group.response;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/12
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class MessageTemplateGroupRelationResponse implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -5321330362977310550L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板名称
|
||||||
|
*/
|
||||||
|
private String templateName;
|
||||||
|
/**
|
||||||
|
* 模板编码
|
||||||
|
*/
|
||||||
|
private String templateCode;
|
||||||
|
/**
|
||||||
|
* 消息标题
|
||||||
|
*/
|
||||||
|
private String title;
|
||||||
|
/**
|
||||||
|
* 模板创建时间戳
|
||||||
|
*/
|
||||||
|
private Long createTimestamp;
|
||||||
|
}
|
||||||
@ -68,6 +68,10 @@ public class PendingMessagePushRequest implements Serializable {
|
|||||||
* 业务描述eg:流程结点描述
|
* 业务描述eg:流程结点描述
|
||||||
*/
|
*/
|
||||||
private String bizDesc;
|
private String bizDesc;
|
||||||
|
/**
|
||||||
|
* 业务扩展参数,JSON字符串格式
|
||||||
|
*/
|
||||||
|
private String bizExtParams;
|
||||||
/**
|
/**
|
||||||
* 路由参数(json string)
|
* 路由参数(json string)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -93,6 +93,10 @@ public class PendingMessageResponse implements Serializable {
|
|||||||
* 参数及其对应的值的JSON串
|
* 参数及其对应的值的JSON串
|
||||||
*/
|
*/
|
||||||
private String routerParams;
|
private String routerParams;
|
||||||
|
/**
|
||||||
|
* 业务扩展参数
|
||||||
|
*/
|
||||||
|
private String bizExtParams;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|||||||
@ -2,15 +2,23 @@ package cn.axzo.msg.center.service.template.client;
|
|||||||
|
|
||||||
import cn.axzo.msg.center.service.template.client.fallback.MessageTemplateClientFallback;
|
import cn.axzo.msg.center.service.template.client.fallback.MessageTemplateClientFallback;
|
||||||
import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest;
|
import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest;
|
||||||
import cn.axzo.msg.center.service.template.request.MessageTemplateMoveToRequest;
|
import cn.axzo.msg.center.service.template.request.MessageTemplatePageRequest;
|
||||||
|
import cn.axzo.msg.center.service.template.request.MessageTemplateUpdateRequest;
|
||||||
|
import cn.axzo.msg.center.service.template.request.MessageTemplateUpdateStatusRequest;
|
||||||
|
import cn.axzo.msg.center.service.template.response.MessageTemplateDetailResponse;
|
||||||
|
import cn.axzo.msg.center.service.template.response.MessageTemplatePageResponse;
|
||||||
import cn.azxo.framework.common.model.CommonResponse;
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
|
import cn.azxo.framework.common.model.Page;
|
||||||
import org.springframework.cloud.openfeign.FeignClient;
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息模板管理
|
* 消息模板管理
|
||||||
@ -29,15 +37,51 @@ public interface MessageTemplateClient {
|
|||||||
* 添加消息模板
|
* 添加消息模板
|
||||||
*
|
*
|
||||||
* @param request 模板数据模型
|
* @param request 模板数据模型
|
||||||
|
* @return 模板编码
|
||||||
*/
|
*/
|
||||||
@PostMapping(value = "/message/template/add", produces = {MediaType.APPLICATION_JSON_VALUE})
|
@PostMapping(value = "/message/template/add", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
CommonResponse<String> addTemplate(@RequestBody @Valid MessageTemplateCreateRequest request);
|
CommonResponse<String> save(@RequestBody @Valid MessageTemplateCreateRequest request);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量消息模板分类迁移
|
* 编辑消息模板
|
||||||
*
|
*
|
||||||
* @param request 待迁移的关联关系id以及目标分类
|
* @param request 模板数据模型
|
||||||
*/
|
*/
|
||||||
@PostMapping(value = "/message/template/group/batch-move", produces = {MediaType.APPLICATION_JSON_VALUE})
|
@PostMapping(value = "/message/template/update", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
CommonResponse<String> batchMove(@RequestBody @Valid MessageTemplateMoveToRequest request);
|
CommonResponse<Void> update(@RequestBody @Valid MessageTemplateUpdateRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息模板详情
|
||||||
|
*
|
||||||
|
* @param templateCode 消息模板编码
|
||||||
|
* @return 消息模板详情
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/message/template/detail", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
|
CommonResponse<MessageTemplateDetailResponse> detail(@RequestParam("templateCode") String templateCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询模板
|
||||||
|
*
|
||||||
|
* @param request 分页查询参数
|
||||||
|
* @return 模板列表
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/message/template/page", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
|
CommonResponse<Page<MessageTemplatePageResponse>> page(@RequestBody MessageTemplatePageRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过模板编码查询对应的模板
|
||||||
|
*
|
||||||
|
* @param templateCodes 模板编码集合
|
||||||
|
* @return 模板列表
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/message/template/list", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
|
CommonResponse<List<MessageTemplatePageResponse>> listByCodes(@RequestParam("templateCodes") Collection<String> templateCodes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用/禁用消息模板
|
||||||
|
*
|
||||||
|
* @param request 模板状态
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/message/template/update-status", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
|
CommonResponse<Void> updateStatus(@RequestBody @Valid MessageTemplateUpdateStatusRequest request);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,11 +2,19 @@ package cn.axzo.msg.center.service.template.client.fallback;
|
|||||||
|
|
||||||
import cn.axzo.msg.center.service.template.client.MessageTemplateClient;
|
import cn.axzo.msg.center.service.template.client.MessageTemplateClient;
|
||||||
import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest;
|
import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest;
|
||||||
import cn.axzo.msg.center.service.template.request.MessageTemplateMoveToRequest;
|
import cn.axzo.msg.center.service.template.request.MessageTemplatePageRequest;
|
||||||
|
import cn.axzo.msg.center.service.template.request.MessageTemplateUpdateRequest;
|
||||||
|
import cn.axzo.msg.center.service.template.request.MessageTemplateUpdateStatusRequest;
|
||||||
|
import cn.axzo.msg.center.service.template.response.MessageTemplateDetailResponse;
|
||||||
|
import cn.axzo.msg.center.service.template.response.MessageTemplatePageResponse;
|
||||||
import cn.azxo.framework.common.model.CommonResponse;
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
|
import cn.azxo.framework.common.model.Page;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description
|
* @description
|
||||||
*
|
*
|
||||||
@ -18,14 +26,38 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component
|
@Component
|
||||||
public class MessageTemplateClientFallback implements MessageTemplateClient {
|
public class MessageTemplateClientFallback implements MessageTemplateClient {
|
||||||
@Override
|
@Override
|
||||||
public CommonResponse<String> addTemplate(MessageTemplateCreateRequest request) {
|
public CommonResponse<String> save(MessageTemplateCreateRequest request) {
|
||||||
log.error("fall back while adding template. request:{}", request);
|
log.error("fall back while adding template. request:{}", request);
|
||||||
return CommonResponse.error("fall back while adding template");
|
return CommonResponse.error("fall back while adding template");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResponse<String> batchMove(MessageTemplateMoveToRequest request) {
|
public CommonResponse<Void> update(MessageTemplateUpdateRequest request) {
|
||||||
log.error("fall back while batch moving to target group. request:{}", request);
|
log.error("fall back while updating template. request:{}", request);
|
||||||
return CommonResponse.error("fall back while batch moving to target group");
|
return CommonResponse.error("fall back while updating template");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<MessageTemplateDetailResponse> detail(String templateCode) {
|
||||||
|
log.error("fall back while query template detail. templateCode:{}", templateCode);
|
||||||
|
return CommonResponse.error("fall back while query template detail");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Page<MessageTemplatePageResponse>> page(MessageTemplatePageRequest request) {
|
||||||
|
log.error("fall back while paging query template. request:{}", request);
|
||||||
|
return CommonResponse.error("fall back while paging query template");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<List<MessageTemplatePageResponse>> listByCodes(Collection<String> templateCodes) {
|
||||||
|
log.error("fall back while listing templates. templateCodes:{}", templateCodes);
|
||||||
|
return CommonResponse.error("fall back while listing template");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Void> updateStatus(MessageTemplateUpdateStatusRequest request) {
|
||||||
|
log.error("fall back while updating template status. request:{}", request);
|
||||||
|
return CommonResponse.error("fall back while updating template status");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
package cn.axzo.msg.center.service.template.request;
|
package cn.axzo.msg.center.service.template.request;
|
||||||
|
|
||||||
import cn.axzo.msg.center.service.dto.MessageRouterDTO;
|
import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO;
|
||||||
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
|
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@ -43,19 +45,25 @@ public class MessageTemplateCreateRequest implements Serializable {
|
|||||||
@NotNull(message = "category is required")
|
@NotNull(message = "category is required")
|
||||||
private MessageCategoryEnum category;
|
private MessageCategoryEnum category;
|
||||||
/**
|
/**
|
||||||
* 消息分类结点的结点编码列表
|
* 消息分类树的叶结点的结点编码列表
|
||||||
*/
|
*/
|
||||||
@NotEmpty(message = "msgGroupNodeCodes is required")
|
@NotEmpty(message = "leafGroupNodes is required")
|
||||||
private List<String> msgGroupNodeCodes;
|
private List<String> leafGroupNodes;
|
||||||
|
/**
|
||||||
|
* 推送终端配置
|
||||||
|
* B_ENTERPRISE_APP: B-安心筑企业版
|
||||||
|
* C_WORKER_APP: C-安心筑工人版
|
||||||
|
*/
|
||||||
|
private List<PushTerminalEnum> pushTerminals;
|
||||||
/**
|
/**
|
||||||
* 消息标题
|
* 消息标题
|
||||||
*/
|
*/
|
||||||
@NotBlank(message = "msgTitle is required")
|
@NotBlank(message = "msgTitle is required")
|
||||||
private String msgTitle;
|
private String msgTitle;
|
||||||
/**
|
/**
|
||||||
* 消息卡片信息
|
* 消息卡片信息标签列表,可为空
|
||||||
*/
|
*/
|
||||||
private String msgCardInfo;
|
private List<MessageCardContentItemDTO> msgCardContentItems;
|
||||||
/**
|
/**
|
||||||
* 消息内容
|
* 消息内容
|
||||||
*/
|
*/
|
||||||
@ -68,7 +76,7 @@ public class MessageTemplateCreateRequest implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* 路由策略列表
|
* 路由策略列表
|
||||||
*/
|
*/
|
||||||
private List<MessageRouterDTO> routers;
|
private List<MessageRouterButtonDTO> routers;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|||||||
@ -1,40 +0,0 @@
|
|||||||
package cn.axzo.msg.center.service.template.request;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description
|
|
||||||
*
|
|
||||||
* @author cold_blade
|
|
||||||
* @date 2023/9/26
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
@Setter
|
|
||||||
@Getter
|
|
||||||
public class MessageTemplateMoveToRequest implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 6484726175219602690L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 操作者的自然人id
|
|
||||||
*/
|
|
||||||
private Long operatorId;
|
|
||||||
/**
|
|
||||||
* 模板与分类的关联关系的id列表
|
|
||||||
*/
|
|
||||||
private List<Long> templateGroupRelationIds;
|
|
||||||
/**
|
|
||||||
* 迁移的目标分类结点编码
|
|
||||||
*/
|
|
||||||
private String targetGroupNodeCode;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return JSON.toJSONString(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
package cn.axzo.msg.center.service.template.request;
|
||||||
|
|
||||||
|
import cn.axzo.basics.common.page.PageRequest;
|
||||||
|
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.StatusEnum;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/13
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class MessageTemplatePageRequest extends PageRequest implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 3501567663122621175L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板名称
|
||||||
|
*/
|
||||||
|
private String templateName;
|
||||||
|
/**
|
||||||
|
* 模板编码
|
||||||
|
*/
|
||||||
|
private String templateCode;
|
||||||
|
/**
|
||||||
|
* 消息类型
|
||||||
|
* GENERAL_MESSAGE: 普通消息
|
||||||
|
* PENDING_MESSAGE: 待办消息
|
||||||
|
*/
|
||||||
|
private MessageCategoryEnum category;
|
||||||
|
/**
|
||||||
|
* 分类树的结点编码
|
||||||
|
*/
|
||||||
|
private String groupNodeCode;
|
||||||
|
/**
|
||||||
|
* 模板状态
|
||||||
|
* ENABLE: 启用
|
||||||
|
* DISABLE: 禁用
|
||||||
|
*/
|
||||||
|
private StatusEnum status;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
package cn.axzo.msg.center.service.template.request;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO;
|
||||||
|
import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO;
|
||||||
|
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description
|
||||||
|
*
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/11
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class MessageTemplateUpdateRequest implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -2894419272913799317L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作者的自然人id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "operatorId is required")
|
||||||
|
private Long operatorId;
|
||||||
|
/**
|
||||||
|
* 模板编码
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "templateCode is required")
|
||||||
|
private String templateCode;
|
||||||
|
/**
|
||||||
|
* 模板名称
|
||||||
|
*/
|
||||||
|
private String templateName;
|
||||||
|
/**
|
||||||
|
* 消息分类树的叶结点的结点编码列表
|
||||||
|
*/
|
||||||
|
private List<String> leafGroupNodes;
|
||||||
|
/**
|
||||||
|
* 推送终端配置
|
||||||
|
* B_ENTERPRISE_APP: B-安心筑企业版
|
||||||
|
* C_WORKER_APP: C-安心筑工人版
|
||||||
|
*/
|
||||||
|
private List<PushTerminalEnum> pushTerminals;
|
||||||
|
/**
|
||||||
|
* 消息标题
|
||||||
|
*/
|
||||||
|
private String msgTitle;
|
||||||
|
/**
|
||||||
|
* 消息卡片信息标签列表
|
||||||
|
*/
|
||||||
|
private List<MessageCardContentItemDTO> msgCardContentItems;
|
||||||
|
/**
|
||||||
|
* 消息内容
|
||||||
|
*/
|
||||||
|
private String msgContent;
|
||||||
|
/**
|
||||||
|
* 消息图标
|
||||||
|
*/
|
||||||
|
private String msgIcon;
|
||||||
|
/**
|
||||||
|
* 路由策略列表
|
||||||
|
*/
|
||||||
|
private List<MessageRouterButtonDTO> routers;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package cn.axzo.msg.center.service.template.request;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.enums.StatusEnum;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author cold_blade
|
||||||
|
* @date 2023/10/13
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class MessageTemplateUpdateStatusRequest implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 818483349559289586L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作者的自然人id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "operatorId is required")
|
||||||
|
private Long operatorId;
|
||||||
|
/**
|
||||||
|
* 模板编码
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "templateCode is required")
|
||||||
|
private String templateCode;
|
||||||
|
/**
|
||||||
|
* 模板状态
|
||||||
|
* ENABLE: 启用
|
||||||
|
* DISABLE: 禁用
|
||||||
|
*/
|
||||||
|
@NotNull(message = "status is required")
|
||||||
|
private StatusEnum status;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user