Merge branch 'feature/REQ-1507' of axzsource.com:universal/infrastructure/backend/msg-center-plat into dev

This commit is contained in:
luofu 2023-11-20 08:49:37 +08:00
commit 4969c3f732
10 changed files with 215 additions and 1 deletions

View File

@ -1,5 +1,6 @@
package cn.axzo.msg.center.message.controller;
import cn.axzo.msg.center.api.response.MessageDetailRes;
import cn.axzo.msg.center.message.domain.dto.PendingMessageDTO;
import cn.axzo.msg.center.message.domain.dto.PendingMessageStatisticDTO;
import cn.axzo.msg.center.message.domain.param.MessageGroupNodeStatisticParam;
@ -60,6 +61,11 @@ public class PendingMessageNewController implements PendingMessageClient {
return CommonResponse.success(pendingMessageNewService.pageQuery(request));
}
@Override
public CommonResponse<Page<MessageDetailRes>> compatiblePageQuery(PendingMessagePageRequest request) {
return CommonResponse.success(pendingMessageNewService.compatiblePageQuery(request));
}
@Override
public CommonResponse<PendingMessageResponse> query(PendingMessageQueryRequest request) {
return CommonResponse.success(pendingMessageNewService.query(request));

View File

@ -10,6 +10,7 @@ import org.apache.commons.lang3.StringUtils;
import java.io.Serializable;
import java.util.Collection;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -65,6 +66,16 @@ public class GroupTreeNodePathDTO implements Serializable {
return nodes.stream().map(pathFunc).collect(Collectors.joining(spliter));
}
public boolean equals(GroupTreeNodePathDTO treeNodePath) {
return Objects.nonNull(treeNodePath)
&& Objects.equals(nodeCode, treeNodePath.getNodeCode())
&& Objects.equals(nodeCodePath, treeNodePath.getNodeCodePath());
}
public boolean equals(String nodeCodePath) {
return Objects.equals(nodeCodePath, this.nodeCodePath);
}
@Override
public String toString() {
return JSON.toJSONString(this);

View File

@ -5,6 +5,8 @@ import cn.axzo.msg.center.service.dto.IdentityDTO;
import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO;
import cn.axzo.msg.center.service.dto.PersonDTO;
import cn.axzo.msg.center.service.enums.BizCategoryEnum;
import cn.axzo.msg.center.service.enums.OrganizationTypeEnum;
import cn.axzo.msg.center.service.enums.PendingMessageStateEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
import cn.axzo.msg.center.utils.DateFormatUtil;
@ -53,6 +55,10 @@ public class PendingMessageDTO implements Serializable {
* 消息内容
*/
private String content;
/**
* 待办状态
*/
private PendingMessageStateEnum state;
/**
* 卡片信息
*/
@ -89,6 +95,10 @@ public class PendingMessageDTO implements Serializable {
* 工作台名称
*/
private String workspaceName;
/**
* 类型
*/
private OrganizationTypeEnum organizationType;
/**
* 待办发起人的
*/
@ -117,6 +127,10 @@ public class PendingMessageDTO implements Serializable {
* 业务终态的印章图片地址
*/
private String bizFinalStateIcon;
/**
* 路由参数
*/
private String routerParam;
public static PendingMessageDTO from(PendingMessageRecord pendingMessageRecord) {
// 代办发起者信息
@ -142,6 +156,7 @@ public class PendingMessageDTO implements Serializable {
.templateCode(pendingMessageRecord.getTemplateCode())
.title(pendingMessageRecord.getTitle())
.content(pendingMessageRecord.getContent())
.state(pendingMessageRecord.getState())
.promoter(promoter)
.executor(executor)
.bizCode(pendingMessageRecord.getBizCode())
@ -150,11 +165,13 @@ public class PendingMessageDTO implements Serializable {
.bizFlag(pendingMessageRecord.getBizFlag())
.workspaceId(pendingMessageRecord.getOrgId())
.workspaceName(pendingMessageRecord.getOrgName())
.organizationType(pendingMessageRecord.getOrgType())
.ouId(pendingMessageRecord.getOuId())
.bizCategory(pendingMessageRecord.getBizCategory())
.deadline(DateFormatUtil.toLocalDateTime(pendingMessageRecord.getDeadline()))
.createTime(DateFormatUtil.toLocalDateTime(pendingMessageRecord.getCreateAt()))
.updateTime(DateFormatUtil.toLocalDateTime(pendingMessageRecord.getUpdateAt()))
.routerParam(pendingMessageRecord.getRouterParams())
.build();
}

View File

@ -21,6 +21,14 @@ public interface MessageTemplateGroupService {
*/
List<String> listMessageTemplateCodes(Collection<String> leafNodePathCodes);
/**
* 通过分组结点编码路径查询关联的模板编码列表
*
* @param leafNodePathCodes 分组结点编码路径列表
* @return 模板编码列表
*/
Map<String, List<String>> groupingByMessageTemplateCodes(Collection<String> leafNodePathCodes);
/**
* 模板关联分类
*

View File

@ -1,5 +1,6 @@
package cn.axzo.msg.center.message.service;
import cn.axzo.msg.center.api.response.MessageDetailRes;
import cn.axzo.msg.center.message.domain.dto.PendingMessageDTO;
import cn.axzo.msg.center.message.domain.dto.PendingMessageStatisticDTO;
import cn.axzo.msg.center.message.domain.param.MessageGroupNodeStatisticParam;
@ -59,6 +60,14 @@ public interface PendingMessageNewService {
*/
Page<PendingMessageResponse> pageQuery(PendingMessagePageRequest request);
/**
* 代办列表分页查询
*
* @param request 分页查询相关参数
* @return 代办列表
*/
Page<MessageDetailRes> compatiblePageQuery(PendingMessagePageRequest request);
/**
* 代办列表指定item查询
*

View File

@ -8,6 +8,7 @@ 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 com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
@ -39,7 +40,7 @@ public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupServ
@Override
public List<String> listMessageTemplateCodes(Collection<String> leafNodePathCodes) {
if (CollectionUtils.isEmpty(leafNodePathCodes)) {
log.info("groupNodePathCodes is empty.");
log.info("leafNodePathCodes is empty.");
return Collections.emptyList();
}
return messageTemplateGroupDao.lambdaQuery()
@ -50,6 +51,25 @@ public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupServ
.collect(Collectors.toList());
}
@Override
public Map<String, List<String>> groupingByMessageTemplateCodes(Collection<String> leafNodePathCodes) {
if (CollectionUtils.isEmpty(leafNodePathCodes)) {
log.info("leafNodePathCodes is empty.");
return Collections.emptyMap();
}
Map<String, List<MessageTemplateGroup>> groupingBy = messageTemplateGroupDao.lambdaQuery()
.in(MessageTemplateGroup::getPath, leafNodePathCodes)
.select(MessageTemplateGroup::getPath, MessageTemplateGroup::getTemplateCode)
.list().stream()
.collect(Collectors.groupingBy(MessageTemplateGroup::getTemplateCode));
final Map<String, List<String>> result = Maps.newHashMap();
groupingBy.forEach((key, value) -> {
List<String> paths = value.stream().map(MessageTemplateGroup::getPath).collect(Collectors.toList());
result.put(key, paths);
});
return result;
}
@Override
public void templateGroup(String templateNode, Collection<String> groupNodeCodes) {
if (StringUtils.isBlank(templateNode)

View File

@ -131,6 +131,8 @@ public class PendingMessageDataInitServiceImpl implements PendingMessageDataInit
pendingMsgRecord.setFailCause(String.valueOf(record.getId()));
//
pendingMsgRecord.setIdentityCode(UUIDUtil.uuidString());
pendingMsgRecord.setCreateAt(record.getCreateAt());
pendingMsgRecord.setUpdateAt(record.getUpdateAt());
return pendingMsgRecord;
}

View File

@ -3,12 +3,17 @@ package cn.axzo.msg.center.message.service.impl;
import cn.axzo.apollo.core.web.Result;
import cn.axzo.apollo.workspace.api.workspace.WorkspaceApi;
import cn.axzo.apollo.workspace.api.workspace.res.SimpleWorkspaceRes;
import cn.axzo.framework.core.util.MapUtil;
import cn.axzo.msg.center.api.enums.MsgRecordTerminalTypeEnum;
import cn.axzo.msg.center.api.enums.MsgStateEnum;
import cn.axzo.msg.center.api.response.MessageDetailRes;
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
import cn.axzo.msg.center.common.exception.ServiceException;
import cn.axzo.msg.center.common.utils.PageHelperUtil;
import cn.axzo.msg.center.common.utils.PlaceholderResolver;
import cn.axzo.msg.center.dal.PendingMessageRecordDao;
import cn.axzo.msg.center.domain.entity.PendingMessageRecord;
import cn.axzo.msg.center.domain.enums.NativeTypeEnum;
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.MessageTemplateRouterDTO;
@ -20,6 +25,8 @@ 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.PendingMessageNewService;
import cn.axzo.msg.center.service.dto.ButtonRouterDTO;
import cn.axzo.msg.center.service.dto.DetailRouterDTO;
import cn.axzo.msg.center.service.dto.IdentityDTO;
import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO;
import cn.axzo.msg.center.service.dto.PersonDTO;
@ -30,6 +37,7 @@ import cn.axzo.msg.center.service.enums.MessageGroupCategoryEnum;
import cn.axzo.msg.center.service.enums.OrganizationTypeEnum;
import cn.axzo.msg.center.service.enums.PendingMessageRoleCategoryEnum;
import cn.axzo.msg.center.service.enums.PendingMessageStateEnum;
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByIdRequest;
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageRequest;
@ -37,6 +45,7 @@ import cn.axzo.msg.center.service.pending.request.PendingMessagePageRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageQueryRequest;
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
import cn.axzo.msg.center.service.pending.response.PushPendingMessageDTO;
import cn.axzo.msg.center.utils.DateFormatUtil;
import cn.axzo.msg.center.utils.JSONObjectUtil;
import cn.axzo.msg.center.utils.MessageCardUtil;
import cn.axzo.msg.center.utils.MessageRouterUtil;
@ -55,9 +64,13 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.Collection;
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.function.Function;
import java.util.stream.Collectors;
/**
@ -168,6 +181,68 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
return Page.toPage(request.getPage(), request.getPageSize(), result.getTotal(), responseRecords);
}
@Deprecated
@Override
public Page<MessageDetailRes> compatiblePageQuery(PendingMessagePageRequest request) {
List<String> groupTreeRootNodeCodes = messageGroupNodeService
.listGroupTreeRootNodeCodes(MessageGroupCategoryEnum.PENDING, request.getAppTerminalType());
PersonDTO operator = PersonDTO.from(request.getPersonId(), request.getIdentityId(), request.getIdentityType());
// 开始构建分页查询条件
LambdaQueryChainWrapper<PendingMessageRecord> query = pendingMessageRecordDao.lambdaQuery();
// 构建人维度的查询条件
buildPersonCondition(query, request.getWithIdentify(), request.getRoleCategory(), operator);
// 模板的分类对代办进行分组过滤
List<GroupTreeNodePathDTO> leafNodePaths = messageGroupNodeService
.leafGroupNodeCodePathsByRootNodeCodes(groupTreeRootNodeCodes);
if (StringUtils.isNotBlank(request.getGroupNodeCode())) {
GroupTreeNodePathDTO nodePath = messageGroupNodeService.queryLeafGroupNodeCodePath(request.getGroupNodeCode())
.orElse(null);
if (Objects.isNull(nodePath)
|| leafNodePaths.stream().noneMatch(e -> e.equals(nodePath))) {
// 如果该分类未关联任何模板直接返回空集合
log.info("invalid group node code...");
return PageHelperUtil.emptyPage(request.getPage(), request.getPageSize());
}
leafNodePaths = Lists.newArrayList(nodePath);
}
List<String> paths = leafNodePaths.stream().map(GroupTreeNodePathDTO::getNodeCodePath).collect(Collectors.toList());
Map<String, List<String>> templateCodesPathMap = messageTemplateGroupService.groupingByMessageTemplateCodes(paths);
if (MapUtil.isEmpty(templateCodesPathMap)) {
// 如果该分类未关联任何模板直接返回空集合
log.info("there is not any template matched... appTerminal:[{}]", request.getAppTerminalType());
return PageHelperUtil.emptyPage(request.getPage(), request.getPageSize());
}
query.in(PendingMessageRecord::getTemplateCode, templateCodesPathMap.keySet());
// 构建排序条件
buildSortCondition(query, request.getOrderFields());
IPage<PendingMessageRecord> result = query.page(request.toPage());
if (CollectionUtils.isEmpty(result.getRecords())) {
return Page.toPage(request.getPage(), request.getPageSize(), result.getTotal(), Collections.emptyList());
}
List<String> templateCodes = result.getRecords().stream().map(PendingMessageRecord::getTemplateCode)
.collect(Collectors.toList());
List<MessageTemplateDTO> messageTemplates = messageTemplateNewService.listByTemplateCodes(templateCodes);
Map<String, GroupTreeNodePathDTO> tmpMap = leafNodePaths.stream()
.collect(Collectors.toMap(GroupTreeNodePathDTO::getNodeCodePath, Function.identity(), (pre, next) -> next));
final Map<String, String> templateCodeNodeNameMap = new HashMap<>();
templateCodes.stream()
.filter(templateCodesPathMap::containsKey)
.forEach(e -> {
List<GroupTreeNodePathDTO> codePaths = templateCodesPathMap.get(e).stream()
.map(tmpMap::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(codePaths)) {
templateCodeNodeNameMap.put(e, codePaths.get(0).getNodeName());
}
});
List<MessageDetailRes> records = result.getRecords().stream()
.map(e -> convert(e, messageTemplates))
.map(e -> convert(e, templateCodeNodeNameMap, request.getTerminalType()))
.collect(Collectors.toList());
return Page.toPage(request.getPage(), request.getPageSize(), result.getTotal(), records);
}
@Override
public PendingMessageResponse query(PendingMessageQueryRequest request) {
return pendingMessageRecordDao.queryByIdentityCode(request.getMsgIdentityCode())
@ -313,6 +388,54 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
return pendingMessage;
}
private MessageDetailRes convert(PendingMessageDTO response, Map<String, String> templateCodeNodeNameMap,
TerminalTypeEnum terminalType) {
MessageDetailRes res = new MessageDetailRes();
res.setMsgTitle(response.getTitle());
res.setContent(response.getContent());
res.setModuleName(templateCodeNodeNameMap.get(response.getTemplateCode()));
res.setTerminalId(response.getWorkspaceId());
res.setTerminalName(response.getWorkspaceName());
res.setTerminalType(MsgRecordTerminalTypeEnum.valueOf(response.getOrganizationType().name()));
res.setState(MsgStateEnum.getByCode(response.getState().getCode()));
res.setMsgTimestamp(DateFormatUtil.toTimestamp(response.getCreateTime()));
res.setRouterParam(response.getRouterParam());
buildRouter(res, response.getMsgTemplateRouter(), terminalType);
return res;
}
private void buildRouter(MessageDetailRes detail, MessageTemplateRouterDTO router, TerminalTypeEnum terminalType) {
if (Objects.isNull(router)) {
return;
}
DetailRouterDTO detailRouter = MessageRouterUtil.fetchBizDetailRouter(router, terminalType).orElse(null);
if (Objects.nonNull(detailRouter)) {
NativeTypeEnum nativeType = NativeTypeEnum.getByCode(detailRouter.getTerminalType().getCode());
if (Objects.isNull(nativeType)) {
return;
}
detail.setRouteUrl(detailRouter.getUrl());
detail.setRouteType(nativeType.getMessage());
return;
}
List<ButtonRouterDTO> buttonRouters = MessageRouterUtil.fetchMessageRouterButtons(router, terminalType);
if (CollectionUtils.isEmpty(buttonRouters)) {
return;
}
ButtonRouterDTO btnRouter = buttonRouters.stream()
.filter(e -> Objects.equals(e.getCategory(), RouterCategoryEnum.JUMP))
.findFirst().orElse(null);
if (Objects.isNull(btnRouter)) {
return;
}
NativeTypeEnum nativeType = NativeTypeEnum.getByCode(btnRouter.getTerminalType().getCode());
if (Objects.isNull(nativeType)) {
return;
}
detail.setRouteUrl(btnRouter.getUrl());
detail.setRouteType(nativeType.getMessage());
}
private PendingMessageStatisticDTO statistic(GroupTreeNodePathDTO leafNodePath, MessageGroupNodeStatisticParam param) {
PendingMessageStatisticDTO dto = PendingMessageStatisticDTO.of(leafNodePath);
dto.setPendingCount(doStatistic(leafNodePath, param));

View File

@ -1,5 +1,6 @@
package cn.axzo.msg.center.service.pending.client;
import cn.axzo.msg.center.api.response.MessageDetailRes;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.pending.client.fallback.PendingMessageClientFallback;
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByIdRequest;
@ -65,6 +66,16 @@ public interface PendingMessageClient {
@PostMapping(value = "/pending-message/record/page", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<Page<PendingMessageResponse>> pageQuery(@RequestBody @Valid PendingMessagePageRequest request);
/**
* 代办列表分页查询
*
* @param request 分页查询相关参数
* @return 代办列表
*/
@Deprecated
@PostMapping(value = "/pending-message/record/compatible/page", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<Page<MessageDetailRes>> compatiblePageQuery(@RequestBody @Valid PendingMessagePageRequest request);
/**
* 代办列表指定待办的查询
*

View File

@ -1,5 +1,6 @@
package cn.axzo.msg.center.service.pending.client.fallback;
import cn.axzo.msg.center.api.response.MessageDetailRes;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.pending.client.PendingMessageClient;
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByIdRequest;
@ -48,6 +49,12 @@ public class PendingMessageClientFallback implements PendingMessageClient {
return CommonResponse.error("fall back while page querying pending message");
}
@Override
public CommonResponse<Page<MessageDetailRes>> compatiblePageQuery(PendingMessagePageRequest request) {
log.error("fall back while page querying pending message. req:{}", request);
return CommonResponse.error("fall back while page querying pending message");
}
@Override
public CommonResponse<PendingMessageResponse> query(PendingMessageQueryRequest request) {
log.error("fall back while querying pending message. req:{}", request);