From 874676b89760ab82696036a97df54d01b4a07d97 Mon Sep 17 00:00:00 2001 From: luofu Date: Tue, 17 Oct 2023 16:26:25 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E5=88=97=E8=A1=A8=E6=9F=A5=E8=AF=A2=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景: https://jira.axzo.cn/browse/REQ-1465?goToView=1 修改: 1、消息模板列表查询接口实现 影响: 无 --- .../controller/MessageTemplateController.java | 8 +++ .../service/MessageTemplateNewService.java | 9 +++ .../impl/MessageGroupNodeServiceImpl.java | 2 +- .../MessageGroupTreeNodeCacheServiceImpl.java | 10 +++- .../impl/MessageTemplateNewServiceImpl.java | 27 +++++++++ .../client/MessageTemplateClient.java | 11 ++++ .../MessageTemplateClientFallback.java | 9 +++ .../response/MessageTemplateListResponse.java | 60 +++++++++++++++++++ 8 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateListResponse.java diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageTemplateController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageTemplateController.java index 1e87ed82..629ed2c9 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageTemplateController.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageTemplateController.java @@ -14,6 +14,9 @@ import cn.azxo.framework.common.model.Page; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.RestController; +import java.util.Collection; +import java.util.List; + /** * 消息模板管理 * @@ -49,6 +52,11 @@ public class MessageTemplateController implements MessageTemplateClient { return CommonResponse.success(messageTemplateNewService.page(request)); } + @Override + public CommonResponse> listByCodes(Collection templateCodes) { + return CommonResponse.success(messageTemplateNewService.listByCodes(templateCodes)); + } + @Override public CommonResponse updateStatus(MessageTemplateUpdateStatusRequest request) { messageTemplateNewService.updateStatus(request.getOperatorId(), request.getTemplateCode(), request.getStatus()); diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateNewService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateNewService.java index 7644190d..5ce92b17 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateNewService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateNewService.java @@ -8,6 +8,7 @@ import cn.axzo.msg.center.service.template.response.MessageTemplateDetailRespons 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.Optional; @@ -74,4 +75,12 @@ public interface MessageTemplateNewService { * @return 模板数据列表 */ Page page(MessageTemplatePageRequest request); + + /** + * 通过模板编码查询对应的模板 + * + * @param templateCodes 模板编码集合 + * @return 模板列表 + */ + List listByCodes(Collection templateCodes); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupNodeServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupNodeServiceImpl.java index 78931a84..250ff90d 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupNodeServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupNodeServiceImpl.java @@ -38,7 +38,7 @@ public class MessageGroupNodeServiceImpl implements MessageGroupNodeService { .map(messageGroupTreeNodeCacheService::queryLeafNodePath) .filter(Optional::isPresent) .map(Optional::get) - .collect(Collectors.toMap(GroupTreeNodePathDTO::getNodeCode, + .collect(Collectors.toMap(GroupTreeNodePathDTO::getNodeCodePath, GroupTreeNodePathDTO::getNodeNamePath, (cur, pre) -> cur)); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupTreeNodeCacheServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupTreeNodeCacheServiceImpl.java index b9cdd89e..bf82772f 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupTreeNodeCacheServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupTreeNodeCacheServiceImpl.java @@ -175,7 +175,7 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod pathNodeStack.push(node); if (CollectionUtils.isEmpty(node.getNodeChildren())) { // 当前结点为树的叶结点(逻辑上的,有可能不是业务维度的叶结点) - paths.add(GroupTreeNodePathDTO.of(node.getNodeCode(), pathNodeStack)); + paths.add(GroupTreeNodePathDTO.of(node.getNodeCode(), reverseStack(pathNodeStack))); pathNodeStack.pop(); } else { stack.addAll(node.getNodeChildren()); @@ -183,4 +183,12 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod } return paths; } + + private List reverseStack(LinkedList pathNodeStack) { + List list = Lists.newArrayList(); + for (GroupTreeNodeDTO node : pathNodeStack) { + list.add(0, node); + } + return list; + } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateNewServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateNewServiceImpl.java index 55ed7fc6..479119f6 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateNewServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateNewServiceImpl.java @@ -58,6 +58,8 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService 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 MessageGroupNodeService messageGroupNodeService; @@ -202,6 +204,31 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService return Page.toPage(request.getPage(), request.getPageSize(), result.getTotal(), records); } + @Override + public List listByCodes(Collection 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 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> groupNodePaths = messageTemplateGroupService + .listMessageTemplateGroupPaths(templateCodes); + // 将模板分类结点编码path转化为分类名称path + Map 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); diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/client/MessageTemplateClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/client/MessageTemplateClient.java index 2c7d0178..a189a694 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/client/MessageTemplateClient.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/client/MessageTemplateClient.java @@ -17,6 +17,8 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import javax.validation.Valid; +import java.util.Collection; +import java.util.List; /** * 消息模板管理 @@ -66,6 +68,15 @@ public interface MessageTemplateClient { @PostMapping(value = "/message/template/page", produces = {MediaType.APPLICATION_JSON_VALUE}) CommonResponse> page(@RequestBody MessageTemplatePageRequest request); + /** + * 通过模板编码查询对应的模板 + * + * @param templateCodes 模板编码集合 + * @return 模板列表 + */ + @PostMapping(value = "/message/template/list", produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse> listByCodes(@RequestParam("templateCodes") Collection templateCodes); + /** * 启用/禁用消息模板 * diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/client/fallback/MessageTemplateClientFallback.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/client/fallback/MessageTemplateClientFallback.java index f0d56970..646b9b3e 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/client/fallback/MessageTemplateClientFallback.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/client/fallback/MessageTemplateClientFallback.java @@ -12,6 +12,9 @@ import cn.azxo.framework.common.model.Page; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import java.util.Collection; +import java.util.List; + /** * @description * @@ -46,6 +49,12 @@ public class MessageTemplateClientFallback implements MessageTemplateClient { return CommonResponse.error("fall back while paging query template"); } + @Override + public CommonResponse> listByCodes(Collection templateCodes) { + log.error("fall back while listing templates. templateCodes:{}", templateCodes); + return CommonResponse.error("fall back while listing template"); + } + @Override public CommonResponse updateStatus(MessageTemplateUpdateStatusRequest request) { log.error("fall back while updating template status. request:{}", request); diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateListResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateListResponse.java new file mode 100644 index 00000000..eac67c94 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateListResponse.java @@ -0,0 +1,60 @@ +package cn.axzo.msg.center.service.template.response; + +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; +import java.util.List; + +/** + * @author cold_blade + * @date 2023/10/17 + * @version 1.0 + */ +@Setter +@Getter +public class MessageTemplateListResponse implements Serializable { + + private static final long serialVersionUID = 4748193413608569743L; + + /** + * 模板名称 + */ + private String templateName; + /** + * 模板编码 + */ + private String templateCode; + /** + * 消息类型 + * GENERAL_MESSAGE: 普通消息 + * PENDING_MESSAGE: 待办消息 + */ + private MessageCategoryEnum category; + /** + * 消息标题 + */ + private String title; + /** + * 消息内容 + */ + private String content; + /** + * 分类路径,eg:发薪管理/发薪提醒/提醒工人 + */ + private List groupNodeNamePaths; + /** + * 模板状态 + * ENABLE: 启用 + * DISABLE: 禁用 + */ + private StatusEnum status; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} From 458846ca15329128f74072f9df03739f5254c801 Mon Sep 17 00:00:00 2001 From: luofu Date: Tue, 17 Oct 2023 18:24:43 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E5=88=86=E7=B1=BB=E7=9B=B8=E5=85=B3=E6=A8=A1=E5=9D=97=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景: https://jira.axzo.cn/browse/REQ-1465?goToView=1 修改: 1、消息分类相关模块接口实现 影响: 无 --- .../controller/MessageGroupController.java | 56 ++++++++++ .../MessageGroupNodeSaveOrUpdateParam.java | 69 ++++++++++++ .../service/MessageGroupNodeService.java | 32 ++++++ .../MessageGroupTreeNodeCacheService.java | 6 +- .../impl/MessageGroupNodeServiceImpl.java | 103 ++++++++++++++++++ .../MessageGroupTreeNodeCacheServiceImpl.java | 27 +++-- .../axzo/msg/center/utils/TreeHelperUtil.java | 6 + .../center/service/dto/GroupTreeNodeDTO.java | 14 +++ .../enums/MessageGroupNodeCategoryEnum.java | 14 ++- .../group/client/MessageGroupClient.java | 3 +- .../request/MessageGroupNodeAddRequest.java | 5 - .../MessageGroupTreeNodeResponse.java | 12 ++ 12 files changed, 318 insertions(+), 29 deletions(-) create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageGroupController.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageGroupNodeSaveOrUpdateParam.java diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageGroupController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageGroupController.java new file mode 100644 index 00000000..631c0490 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageGroupController.java @@ -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 addNode(MessageGroupNodeAddRequest request) { + messageGroupNodeService.addGroupNode(MessageGroupNodeSaveOrUpdateParam.from(request)); + return CommonResponse.success(); + } + + @Override + public CommonResponse updateNode(MessageGroupNodeUpdateRequest request) { + messageGroupNodeService.updateGroupNode(MessageGroupNodeSaveOrUpdateParam.from(request)); + return CommonResponse.success(); + } + + @Override + public CommonResponse deleteNode(String nodeCode, Long operatorId) { + messageGroupNodeService.deleteGroupNode(operatorId, nodeCode); + return CommonResponse.success(); + } + + @Override + public CommonResponse> list(MessageCategoryEnum category) { + List groupTreeNodes = messageGroupNodeService.listGroupTree(category).stream() + .map(GroupTreeNodeDTO::toMessageGroupTreeNodeResponse) + .collect(Collectors.toList()); + return CommonResponse.success(groupTreeNodes); + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageGroupNodeSaveOrUpdateParam.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageGroupNodeSaveOrUpdateParam.java new file mode 100644 index 00000000..161a68aa --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageGroupNodeSaveOrUpdateParam.java @@ -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); + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupNodeService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupNodeService.java index 427db337..3a328708 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupNodeService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupNodeService.java @@ -1,8 +1,11 @@ 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; @@ -38,4 +41,33 @@ public interface MessageGroupNodeService { * @return 结点信息 */ Optional 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 listGroupTree(MessageCategoryEnum category); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupTreeNodeCacheService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupTreeNodeCacheService.java index 2b283f46..dca2c097 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupTreeNodeCacheService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupTreeNodeCacheService.java @@ -16,11 +16,11 @@ import java.util.Optional; public interface MessageGroupTreeNodeCacheService { /** - * 获取所有有效的分类结点树的根节点 + * 获取所有有效的分类结点树 * - * @return 树根节点列表 + * @return 树列表 */ - List listAllRootNodes(); + List listAllGroupTree(); /** * 获取指定结点所在的树的根节点 diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupNodeServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupNodeServiceImpl.java index 250ff90d..ebdc4c92 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupNodeServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupNodeServiceImpl.java @@ -1,17 +1,31 @@ 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; @@ -25,6 +39,8 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class MessageGroupNodeServiceImpl implements MessageGroupNodeService { + private final MessageGroupNodeDao messageGroupNodeDao; + private final MessageTemplateGroupDao messageTemplateGroupDao; private final MessageGroupTreeNodeCacheService messageGroupTreeNodeCacheService; @Override @@ -60,4 +76,91 @@ public class MessageGroupNodeServiceImpl implements MessageGroupNodeService { public Optional queryRootNode(String rootNodeCode) { return messageGroupTreeNodeCacheService.queryRootNode(rootNodeCode); } + + @Override + public void addGroupNode(MessageGroupNodeSaveOrUpdateParam param) { + GroupTreeNodeDTO parent = 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) + .eq(MessageGroupNode::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .remove(); + if (removeResult) { + // 刷新缓存 + messageGroupTreeNodeCacheService.refreshCache(); + } + } + + @Override + public List 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) { + 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, "删除失败!删除前请先转移消息模版!"); + } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupTreeNodeCacheServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupTreeNodeCacheServiceImpl.java index bf82772f..fa06350e 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupTreeNodeCacheServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupTreeNodeCacheServiceImpl.java @@ -40,12 +40,12 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod private final RedisUtil redisUtil; private final MessageGroupNodeDao messageGroupNodeDao; - private List allGroupTreeRootNodesCache = Collections.emptyList(); + private List allGroupTreesCache = Collections.emptyList(); private List leafTreeNodePathsCache = Collections.emptyList(); @Override - public List listAllRootNodes() { - return getAllGroupTreeRootNodesCache(); + public List listAllGroupTree() { + return getAllGroupTreesCache(); } @Override @@ -54,7 +54,7 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod log.info("rootNodeCode is blank."); return Optional.empty(); } - return getAllGroupTreeRootNodesCache().stream() + return getAllGroupTreesCache().stream() .filter(e -> Objects.equals(e.getNodeCode(), rootNodeCode)) .findFirst(); } @@ -65,7 +65,7 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod log.info("groupNodeCode is blank."); return Optional.empty(); } - return getAllGroupTreeRootNodesCache().stream() + return getAllGroupTreesCache().stream() .map(e -> findTreeNode(e, groupNodeCode)) .filter(Objects::nonNull) .findFirst(); @@ -83,12 +83,11 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod } @Override - public void refreshCache() { + public synchronized void refreshCache() { // 清除redis中的缓存标识 redisUtil.getKeyOps().delete(CACHE_KEY); - // 清除本地缓存 - allGroupTreeRootNodesCache = Collections.emptyList(); - leafTreeNodePathsCache = Collections.emptyList(); + // 本地缓存初始化并更新redis中的缓存标识 + initialize(true); } private GroupTreeNodeDTO findTreeNode(GroupTreeNodeDTO root, String treeNodeCode) { @@ -107,10 +106,10 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod return null; } - private List getAllGroupTreeRootNodesCache() { + private List getAllGroupTreesCache() { if (redisUtil.getKeyOps().hasKey(CACHE_KEY)) { // 其它结点进行了本地缓存,但是当前服务进程还未进行缓存 - if (CollectionUtils.isEmpty(allGroupTreeRootNodesCache)) { + if (CollectionUtils.isEmpty(allGroupTreesCache)) { // 本地缓存初始化,不更新redis中的缓存标识 initialize(false); } @@ -118,7 +117,7 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod // 本地缓存初始化并更新redis中的缓存标识 initialize(true); } - return this.allGroupTreeRootNodesCache; + return this.allGroupTreesCache; } private List getLeafTreeNodePathsCache() { @@ -137,8 +136,8 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod private synchronized void initialize(boolean refreshCache) { List groupNodes = listAllValidNodesFromDB(); - allGroupTreeRootNodesCache = TreeUtil.buildTree(groupNodes); - leafTreeNodePathsCache = allGroupTreeRootNodesCache.stream() + allGroupTreesCache = TreeUtil.buildTree(groupNodes); + leafTreeNodePathsCache = allGroupTreesCache.stream() .flatMap(e -> parseRootNode(e).stream()) .collect(Collectors.toList()); if (refreshCache) { diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/utils/TreeHelperUtil.java b/inside-notices/src/main/java/cn/axzo/msg/center/utils/TreeHelperUtil.java index 0a8a57e0..b1965b72 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/utils/TreeHelperUtil.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/utils/TreeHelperUtil.java @@ -3,6 +3,7 @@ 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; @@ -41,4 +42,9 @@ public final class TreeHelperUtil { } return wrapper; } + + public static boolean isLeafNodeCategory(MessageGroupNodeCategoryEnum category) { + return MessageGroupNodeCategoryEnum.GENERAL_MESSAGE_CATEGORY.equals(category) + || MessageGroupNodeCategoryEnum.PENDING_MESSAGE_CATEGORY.equals(category); + } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/GroupTreeNodeDTO.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/GroupTreeNodeDTO.java index 187101b5..e360c55a 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/GroupTreeNodeDTO.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/GroupTreeNodeDTO.java @@ -3,6 +3,7 @@ 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; @@ -15,6 +16,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; /** * @author cold_blade @@ -60,6 +62,18 @@ public class GroupTreeNodeDTO implements IBaseTree, Se @Builder.Default private List nodeChildren = Collections.emptyList(); + public MessageGroupTreeNodeResponse toMessageGroupTreeNodeResponse() { + return MessageGroupTreeNodeResponse.builder() + .category(category) + .nodeName(nodeName) + .nodeCode(nodeCode) + .parentNodeCode(parentNodeCode) + .children(nodeChildren.stream() + .map(GroupTreeNodeDTO::toMessageGroupTreeNodeResponse) + .collect(Collectors.toList())) + .build(); + } + public Optional getChild(String treeNodeCode) { if (StringUtils.isBlank(treeNodeCode)) { return Optional.empty(); diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/MessageGroupNodeCategoryEnum.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/MessageGroupNodeCategoryEnum.java index 0727b216..f85abe17 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/MessageGroupNodeCategoryEnum.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/MessageGroupNodeCategoryEnum.java @@ -15,13 +15,15 @@ import lombok.Getter; @AllArgsConstructor(access = AccessLevel.PRIVATE) public enum MessageGroupNodeCategoryEnum { - GENERAL_MESSAGE_CENTER("消息中心"), - GENERAL_MESSAGE_MODULE("消息模块"), - GENERAL_MESSAGE_CATEGORY("消息分类"), - PENDING_MESSAGE_CENTER("待办中心"), - PENDING_MESSAGE_MODULE("待办模块"), - PENDING_MESSAGE_CATEGORY("待办分类"), + GENERAL_MESSAGE_CENTER("消息中心", 1, MessageCategoryEnum.GENERAL_MESSAGE), + GENERAL_MESSAGE_MODULE("消息模块", 2, MessageCategoryEnum.GENERAL_MESSAGE), + GENERAL_MESSAGE_CATEGORY("消息分类", 3, MessageCategoryEnum.GENERAL_MESSAGE), + PENDING_MESSAGE_CENTER("待办中心", 1, MessageCategoryEnum.PENDING_MESSAGE), + PENDING_MESSAGE_MODULE("待办模块", 2, MessageCategoryEnum.PENDING_MESSAGE), + PENDING_MESSAGE_CATEGORY("待办分类", 3, MessageCategoryEnum.PENDING_MESSAGE), ; private final String desc; + private final int level; + private final MessageCategoryEnum msgCategory; } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageGroupClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageGroupClient.java index c44dc076..04c8bb65 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageGroupClient.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageGroupClient.java @@ -60,5 +60,6 @@ public interface MessageGroupClient { * @param category 消息分类 */ @PostMapping(value = "/message/group/node/list", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse> list(@RequestParam("category") MessageCategoryEnum category); + CommonResponse> list(@RequestParam(value = "category", required = false) + MessageCategoryEnum category); } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageGroupNodeAddRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageGroupNodeAddRequest.java index d38db2b4..fd7ffaab 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageGroupNodeAddRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageGroupNodeAddRequest.java @@ -36,11 +36,6 @@ public class MessageGroupNodeAddRequest implements Serializable { */ @NotEmpty(message = "nodeName is required") private String nodeName; - /** - * 待添加结点编码 - */ - @NotEmpty(message = "nodeCode is required") - private String nodeCode; /** * 待添加结点类型 * GENERAL_MESSAGE_CENTER: 通知的业务中心 diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/response/MessageGroupTreeNodeResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/response/MessageGroupTreeNodeResponse.java index b3be1f48..e2b31149 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/response/MessageGroupTreeNodeResponse.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/response/MessageGroupTreeNodeResponse.java @@ -1,7 +1,11 @@ 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; @@ -14,6 +18,9 @@ import java.util.List; */ @Setter @Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor public class MessageGroupTreeNodeResponse implements Serializable { private static final long serialVersionUID = -6741888813327778598L; @@ -44,4 +51,9 @@ public class MessageGroupTreeNodeResponse implements Serializable { * 子节点列表 */ private List children; + + @Override + public String toString() { + return JSON.toJSONString(this); + } }