From 72d223ef206d09b5cb6b3809966509e59a0e54d1 Mon Sep 17 00:00:00 2001 From: luofu Date: Wed, 11 Oct 2023 17:31:55 +0800 Subject: [PATCH 01/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=E5=AE=9A?= =?UTF-8?q?=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景: https://jira.axzo.cn/browse/REQ-1465?goToView=1 修改: test 影响: 无 --- .../axzo/msg/center/message/domain/dto/PendingMessageDTO.java | 1 + .../service/pending/response/PendingMessageResponse.java | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/PendingMessageDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/PendingMessageDTO.java index d073790c..cc0e4727 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/PendingMessageDTO.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/PendingMessageDTO.java @@ -143,6 +143,7 @@ public class PendingMessageDTO implements Serializable { .updateTimestamp(DateFormatUtil.toTimestamp(this.updateTime)) .routers(this.routers) .routerParams(this.routerParams) + .bizExtParams("{}") .build(); } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/PendingMessageResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/PendingMessageResponse.java index 643408cf..a8461f70 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/PendingMessageResponse.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/PendingMessageResponse.java @@ -93,6 +93,10 @@ public class PendingMessageResponse implements Serializable { * 参数及其对应的值的JSON串 */ private String routerParams; + /** + * 业务扩展参数 + */ + private String bizExtParams; @Override public String toString() { From a36813f81fac827b6c8454ba7ecc92ecd96b8a3b Mon Sep 17 00:00:00 2001 From: luofu Date: Thu, 12 Oct 2023 09:49:55 +0800 Subject: [PATCH 02/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=E5=AE=9A?= =?UTF-8?q?=E4=B9=89?= 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、创建接口 2、修改接口 3、详情接口 影响: 无 --- .../controller/MessageTemplateController.java | 14 +++- .../service/dto/MessageBaseTemplateDTO.java | 66 +++++++++++++++++ .../center/service/dto/MessageRouterDTO.java | 6 ++ .../center/service/enums/ButtonStyleEnum.java | 22 ++++++ .../service/enums/PushTerminalEnum.java | 22 ++++++ .../client/MessageTemplateClient.java | 24 ++++-- .../MessageTemplateClientFallback.java | 16 ++-- .../request/MessageTemplateCreateRequest.java | 11 ++- .../request/MessageTemplateUpdateRequest.java | 74 +++++++++++++++++++ .../MessageTemplateDetailResponse.java | 73 ++++++++++++++++++ .../domain/entity/MessageBaseTemplate.java | 4 + .../domain/entity/MessageTemplateRouter.java | 4 + .../domain/entity/PendingMessageRecord.java | 4 + 13 files changed, 322 insertions(+), 18 deletions(-) create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageBaseTemplateDTO.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/ButtonStyleEnum.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.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 d8e9d4d0..e0d1b56c 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 @@ -4,7 +4,7 @@ import cn.axzo.msg.center.message.domain.param.MessageTemplateCreateParam; import cn.axzo.msg.center.message.service.MessageTemplateNewService; 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.MessageTemplateMoveToRequest; +import cn.axzo.msg.center.service.template.response.MessageTemplateDetailResponse; import cn.azxo.framework.common.model.CommonResponse; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.RestController; @@ -23,15 +23,21 @@ public class MessageTemplateController implements MessageTemplateClient { private final MessageTemplateNewService messageTemplateNewService; @Override - public CommonResponse addTemplate(MessageTemplateCreateRequest request) { + public CommonResponse save(MessageTemplateCreateRequest request) { MessageTemplateCreateParam param = MessageTemplateCreateParam.from(request); messageTemplateNewService.createTemplate(param); return CommonResponse.success(param.getTemplateCode()); } @Override - public CommonResponse batchMove(MessageTemplateMoveToRequest request) { - // TODO: [cold_blade] [P2] 模板关联的批量移动 + public CommonResponse update(MessageTemplateCreateRequest request) { + // TODO:[cold_blade] [P0] update template + return null; + } + + @Override + public CommonResponse detail(String templateCode) { + // TODO:[cold_blade] [P0] query template return null; } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageBaseTemplateDTO.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageBaseTemplateDTO.java new file mode 100644 index 00000000..3ae986b1 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageBaseTemplateDTO.java @@ -0,0 +1,66 @@ +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; + /** + * 卡片信息,json字串 + */ + private String cardContent; + /** + * 模板icon + */ + private String icon; + /** + * 推送终端配置列表 + */ + private List pushTerminals; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterDTO.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterDTO.java index 9afba13a..3322b087 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterDTO.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterDTO.java @@ -1,5 +1,6 @@ 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.TerminalTypeEnum; import com.alibaba.fastjson.JSON; @@ -10,6 +11,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; import java.io.Serializable; +import java.util.List; /** * @description @@ -51,6 +53,10 @@ public class MessageRouterDTO implements Serializable { * WECHAT_MINI_PROGRAM: 微信小程序页面 */ private TerminalTypeEnum terminalType; + /** + * 按钮样式配置 + */ + private List style; @Override public String toString() { diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/ButtonStyleEnum.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/ButtonStyleEnum.java new file mode 100644 index 00000000..8aad56c5 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/ButtonStyleEnum.java @@ -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; +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java new file mode 100644 index 00000000..a475125a --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java @@ -0,0 +1,22 @@ +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_ENTERPRISE_APP("B-安心筑企业版"), C_WORKER_APP("C-安心筑工人版"), + ; + + private final String desc; +} 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 325c6d2f..5eda61fe 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 @@ -2,13 +2,14 @@ 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.request.MessageTemplateCreateRequest; -import cn.axzo.msg.center.service.template.request.MessageTemplateMoveToRequest; +import cn.axzo.msg.center.service.template.response.MessageTemplateDetailResponse; import cn.azxo.framework.common.model.CommonResponse; 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 org.springframework.web.bind.annotation.RequestParam; import javax.validation.Valid; @@ -29,15 +30,26 @@ public interface MessageTemplateClient { * 添加消息模板 * * @param request 模板数据模型 + * @return 模板编码 */ @PostMapping(value = "/message/template/add", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse addTemplate(@RequestBody @Valid MessageTemplateCreateRequest request); + CommonResponse save(@RequestBody @Valid MessageTemplateCreateRequest request); /** - * 批量消息模板分类迁移 + * 添加消息模板 * - * @param request 待迁移的关联关系id以及目标分类 + * @param request 模板数据模型 + * @return 模板编码 */ - @PostMapping(value = "/message/template/group/batch-move", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse batchMove(@RequestBody @Valid MessageTemplateMoveToRequest request); + @PostMapping(value = "/message/template/update", produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse update(@RequestBody @Valid MessageTemplateCreateRequest request); + + /** + * 消息模板详情 + * + * @param templateCode 消息模板编码 + * @return 消息模板详情 + */ + @PostMapping(value = "/message/template/detail", produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse detail(@RequestParam("templateCode") String templateCode); } 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 1b79f7d7..27d91041 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 @@ -2,7 +2,7 @@ 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.request.MessageTemplateCreateRequest; -import cn.axzo.msg.center.service.template.request.MessageTemplateMoveToRequest; +import cn.axzo.msg.center.service.template.response.MessageTemplateDetailResponse; import cn.azxo.framework.common.model.CommonResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -18,14 +18,20 @@ import org.springframework.stereotype.Component; @Component public class MessageTemplateClientFallback implements MessageTemplateClient { @Override - public CommonResponse addTemplate(MessageTemplateCreateRequest request) { + public CommonResponse save(MessageTemplateCreateRequest request) { log.error("fall back while adding template. request:{}", request); return CommonResponse.error("fall back while adding template"); } @Override - public CommonResponse batchMove(MessageTemplateMoveToRequest request) { - log.error("fall back while batch moving to target group. request:{}", request); - return CommonResponse.error("fall back while batch moving to target group"); + public CommonResponse update(MessageTemplateCreateRequest request) { + log.error("fall back while updating template. request:{}", request); + return CommonResponse.error("fall back while updating template"); + } + + @Override + public CommonResponse detail(String templateCode) { + log.error("fall back while query template detail. templateCode:{}", templateCode); + return CommonResponse.error("fall back while query template detail"); } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java index f4cec735..14440e03 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java @@ -2,6 +2,7 @@ package cn.axzo.msg.center.service.template.request; import cn.axzo.msg.center.service.dto.MessageRouterDTO; import cn.axzo.msg.center.service.enums.MessageCategoryEnum; +import cn.axzo.msg.center.service.enums.PushTerminalEnum; import com.alibaba.fastjson.JSON; import lombok.Getter; import lombok.Setter; @@ -43,10 +44,14 @@ public class MessageTemplateCreateRequest implements Serializable { @NotNull(message = "category is required") private MessageCategoryEnum category; /** - * 消息分类结点的结点编码列表 + * 消息分类的树结点编码路径列表 eg: aa:bb:cc */ - @NotEmpty(message = "msgGroupNodeCodes is required") - private List msgGroupNodeCodes; + @NotEmpty(message = "groupPaths is required") + private List groupPaths; + /** + * 推送终端配置 + */ + private List pushTerminals; /** * 消息标题 */ diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java new file mode 100644 index 00000000..5ec82aa1 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java @@ -0,0 +1,74 @@ +package cn.axzo.msg.center.service.template.request; + +import cn.axzo.msg.center.service.dto.MessageRouterDTO; +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.NotEmpty; +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 = "templateName is required") + private String templateName; + /** + * 消息分类的树结点编码路径列表 eg: aa:bb:cc + */ + @NotEmpty(message = "groupPaths is required") + private List groupPaths; + /** + * 推送终端配置 + */ + private List pushTerminals; + /** + * 消息标题 + */ + @NotBlank(message = "msgTitle is required") + private String msgTitle; + /** + * 消息卡片信息 + */ + private String msgCardInfo; + /** + * 消息内容 + */ + @NotBlank(message = "msgContent is required") + private String msgContent; + /** + * 消息图标 + */ + private String msgIcon; + /** + * 路由策略列表 + */ + private List routers; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java new file mode 100644 index 00000000..6599deb3 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java @@ -0,0 +1,73 @@ +package cn.axzo.msg.center.service.template.response; + +import cn.axzo.msg.center.service.dto.MessageRouterDTO; +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 MessageTemplateDetailResponse implements Serializable { + + private static final long serialVersionUID = 6772912658753264863L; + + /** + * 模板名称 + */ + private String templateName; + /** + * 消息类型 + * GENERAL_MESSAGE: 普通消息 + * PENDING_MESSAGE: 待办消息 + */ + private MessageCategoryEnum category; + /** + * 消息分类的树结点编码路径列表 eg: aa:bb:cc + */ + private List groupPaths; + /** + * 推送终端配置 + */ + private List pushTerminals; + /** + * 消息标题 + */ + private String msgTitle; + /** + * 消息卡片信息 + */ + private String msgCardInfo; + /** + * 消息内容 + */ + private String msgContent; + /** + * 消息图标 + */ + private String msgIcon; + /** + * 路由策略列表 + */ + private List routers; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageBaseTemplate.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageBaseTemplate.java index b652f869..a608450f 100644 --- a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageBaseTemplate.java +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageBaseTemplate.java @@ -51,6 +51,10 @@ public class MessageBaseTemplate extends BaseEntity impleme * 模板icon */ private String icon; + /** + * 推送终端配置 JSON字串 + */ + private String pushTerminal; /** * 创建者自然人id */ diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateRouter.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateRouter.java index 68215289..8ef1f5f7 100644 --- a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateRouter.java +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateRouter.java @@ -44,6 +44,10 @@ public class MessageTemplateRouter extends BaseEntity imp * 路由地址 */ private String url; + /** + * 按钮style配置 + */ + private String style; @Override public String toString() { diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/PendingMessageRecord.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/PendingMessageRecord.java index e519ed29..06322e2a 100644 --- a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/PendingMessageRecord.java +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/PendingMessageRecord.java @@ -98,6 +98,10 @@ public class PendingMessageRecord extends BaseEntity imple * 业务描述eg:流程结点描述 */ private String bizDesc; + /** + * 业务扩展参数 + */ + private String bizExtParam; /** * 路由参数(留存) */ From 0c042e1559e155434262332f33f7c2a624ddde51 Mon Sep 17 00:00:00 2001 From: luofu Date: Thu, 12 Oct 2023 17:18:59 +0800 Subject: [PATCH 03/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=E5=AE=9A?= =?UTF-8?q?=E4=B9=89?= 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、创建接口 2、修改接口 3、详情接口 影响: 无 --- .../controller/MessageTemplateController.java | 3 +- .../domain/dto/RawMessageRouterDTO.java | 73 ++++++++++++------- .../param/MessageTemplateCreateParam.java | 3 +- .../MessageTemplateRouterServiceImpl.java | 24 ++++-- .../impl/PendingMessageNewServiceImpl.java | 16 ++-- .../msg/center/utils/MessageRouterUtil.java | 55 ++++---------- .../service/dto/MessageRouterButtonDTO.java | 54 ++++++++++++++ .../service/dto/MessageRouterTerminalDTO.java | 46 ++++++++++++ .../service/enums/TerminalTypeEnum.java | 7 +- .../client/MessageTemplateClient.java | 3 +- .../MessageTemplateClientFallback.java | 3 +- .../request/MessageTemplateCreateRequest.java | 4 +- .../request/MessageTemplateUpdateRequest.java | 4 +- 13 files changed, 203 insertions(+), 92 deletions(-) create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterTerminalDTO.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 e0d1b56c..8de9e4b4 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 @@ -4,6 +4,7 @@ import cn.axzo.msg.center.message.domain.param.MessageTemplateCreateParam; import cn.axzo.msg.center.message.service.MessageTemplateNewService; 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.MessageTemplateUpdateRequest; import cn.axzo.msg.center.service.template.response.MessageTemplateDetailResponse; import cn.azxo.framework.common.model.CommonResponse; import lombok.RequiredArgsConstructor; @@ -30,7 +31,7 @@ public class MessageTemplateController implements MessageTemplateClient { } @Override - public CommonResponse update(MessageTemplateCreateRequest request) { + public CommonResponse update(MessageTemplateUpdateRequest request) { // TODO:[cold_blade] [P0] update template return null; } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java index 1c8ea27a..ba1ee845 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java @@ -1,9 +1,13 @@ package cn.axzo.msg.center.message.domain.dto; 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.MessageRouterTerminalDTO; +import cn.axzo.msg.center.service.enums.ButtonStyleEnum; import cn.axzo.msg.center.service.enums.RouterCategoryEnum; import cn.axzo.msg.center.service.enums.TerminalTypeEnum; +import cn.axzo.msg.center.utils.MessageRouterUtil; import com.alibaba.fastjson.JSON; import lombok.AllArgsConstructor; import lombok.Builder; @@ -12,6 +16,8 @@ import lombok.NoArgsConstructor; import lombok.Setter; import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; /** * @description @@ -40,51 +46,64 @@ public class RawMessageRouterDTO implements Serializable { */ private RouterCategoryEnum category; /** - * 页面地址 OR API接口地址 + * 路由终端 */ - private String url; - /** - * 页面地址所属应用端(如果是API接口地址,请忽略改字段值) - * WEB: web端页面 - * MINI_PROGRAM: 安心筑小程序端页面 - * IOS: 原生IOS端页面 - * ANDROID: 原生Android端页面 - * WEB_VIEW: H5页面 - * WECHAT_MINI_PROGRAM: 微信小程序页面 - */ - private TerminalTypeEnum terminalType; + private List terminals; /** * 模板编码 */ private String templateCode; + /** + * 按钮样式配置 + */ + private List style; - public static RawMessageRouterDTO from(MessageTemplateRouter msgTemplateRouter) { + public static RawMessageRouterDTO from(List msgTemplateRouters) { + MessageTemplateRouter router = msgTemplateRouters.get(0); return RawMessageRouterDTO.builder() - .desc(msgTemplateRouter.getName()) - .url(msgTemplateRouter.getUrl()) - .category(msgTemplateRouter.getCategory()) - .terminalType(msgTemplateRouter.getTerminalType()) - .templateCode(msgTemplateRouter.getTemplateCode()) + .desc(router.getName()) + .category(router.getCategory()) + .templateCode(router.getTemplateCode()) + .style(JSON.parseArray(router.getStyle(), ButtonStyleEnum.class)) + .terminals(JSON.parseArray(router.getStyle(), MessageRouterTerminalDTO.class)) .build(); } - public static RawMessageRouterDTO from(MessageRouterDTO router, String templateCode) { + public static RawMessageRouterDTO from(MessageRouterButtonDTO router, String templateCode) { return RawMessageRouterDTO.builder() .desc(router.getDesc()) - .url(router.getUrl()) .category(router.getCategory()) - .terminalType(router.getTerminalType()) + .terminals(router.getTerminals()) + .style(router.getStyle()) .templateCode(templateCode) .build(); } - public MessageTemplateRouter toMessageTemplateRouter() { + public List 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(); - router.setName(this.desc); - router.setUrl(this.url); - router.setCategory(this.category); - router.setTerminalType(this.terminalType); - router.setTemplateCode(this.templateCode); + router.setName(desc); + router.setCategory(category); + router.setTemplateCode(templateCode); + router.setStyle(JSON.toJSONString(style)); + router.setUrl(terminal.getUrl()); + router.setTerminalType(terminal.getTerminalType()); return router; } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateCreateParam.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateCreateParam.java index f99c1cbe..b1151d5d 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateCreateParam.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateCreateParam.java @@ -1,5 +1,6 @@ package cn.axzo.msg.center.message.domain.param; +import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO; 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; @@ -67,7 +68,7 @@ public class MessageTemplateCreateParam implements Serializable { /** * 路由列表 */ - private List routers; + private List routers; public static MessageTemplateCreateParam from(MessageTemplateCreateRequest request) { return MessageTemplateCreateParam.builder() diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java index 8a0ca09d..6572992f 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java @@ -36,9 +36,7 @@ public class MessageTemplateRouterServiceImpl implements MessageTemplateRouterSe log.warn("the template code is blank."); return Collections.emptyList(); } - return messageTemplateRouterDao.listByTemplateCode(Lists.newArrayList(templateCode)).stream() - .map(RawMessageRouterDTO::from) - .collect(Collectors.toList()); + return listByTemplateCodes(Lists.newArrayList(templateCode)); } @Override @@ -47,7 +45,7 @@ public class MessageTemplateRouterServiceImpl implements MessageTemplateRouterSe return; } List messageTemplateRouters = routers.stream() - .map(RawMessageRouterDTO::toMessageTemplateRouter) + .flatMap(e -> e.toMessageTemplateRouters().stream()) .collect(Collectors.toList()); messageTemplateRouterDao.saveBatch(messageTemplateRouters); } @@ -57,8 +55,22 @@ public class MessageTemplateRouterServiceImpl implements MessageTemplateRouterSe if (CollectionUtils.isEmpty(templateCodes)) { return Collections.emptyMap(); } - return messageTemplateRouterDao.listByTemplateCode(templateCodes).stream() - .map(RawMessageRouterDTO::from) + return listByTemplateCodes(templateCodes).stream() .collect(Collectors.groupingBy(RawMessageRouterDTO::getTemplateCode)); } + + private List listByTemplateCodes(List templateCodes) { + // 根据模板编码进行分组 + Map> routers = messageTemplateRouterDao + .listByTemplateCode(templateCodes).stream() + .collect(Collectors.groupingBy(MessageTemplateRouter::getTemplateCode)); + return routers.values().stream() + .flatMap(e -> { + // 模板路由的按钮维度 + Map> btnMap = e.stream() + .collect(Collectors.groupingBy(MessageTemplateRouter::getName)); + return btnMap.values().stream() + .map(RawMessageRouterDTO::from); + }).collect(Collectors.toList()); + } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java index 079a52d6..fcbc418b 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java @@ -1,6 +1,5 @@ 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.exception.ServiceException; import cn.axzo.msg.center.common.utils.PlaceholderResolver; @@ -169,13 +168,14 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService { .findFirst() .map(MessageTemplateDTO::getRouters) .orElseGet(Collections::emptyList); - rawRouters = MessageRouterUtil.selectRouter(rawRouters, terminalType); - List routers = rawRouters.stream().map(e -> { - MessageRouterDTO router = BeanConverter.convert(e, MessageRouterDTO.class); - // 视情况替换原始URL中的参数变量 - MessageRouterUtil.parseRouteUrl(router, pendingMessageRecord.getRouterParams()); - return router; - }).collect(Collectors.toList()); + List routers = rawRouters.stream() + .map(e -> { + MessageRouterDTO router = e.toMessageRouter(terminalType); + // 视情况替换原始URL中的参数变量 + MessageRouterUtil.parseRouteUrl(router, pendingMessageRecord.getRouterParams()); + return router; + }) + .collect(Collectors.toList()); pendingMessage.setRouters(routers); // 获取模板卡片信息 String cardContent = messageTemplates.stream() diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java b/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java index 1ec2d748..d04bcfe1 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java @@ -3,10 +3,10 @@ package cn.axzo.msg.center.utils; import cn.axzo.msg.center.common.utils.PlaceholderResolver; import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO; import cn.axzo.msg.center.service.dto.MessageRouterDTO; +import cn.axzo.msg.center.service.dto.MessageRouterTerminalDTO; import cn.axzo.msg.center.service.enums.RouterCategoryEnum; import cn.axzo.msg.center.service.enums.TerminalTypeEnum; import com.alibaba.fastjson.JSON; -import com.google.common.collect.ImmutableMap; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.apache.commons.collections.CollectionUtils; @@ -30,32 +30,22 @@ public final class MessageRouterUtil { // 非法路由参数的定义 private static final String INVALID_ROUTER_PARAM = "null"; - // 当前系统选取路由的优先级策略 - private static final ImmutableMap ROUTER_SELECT_ORDER = - ImmutableMap.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 terminalType 指定的终端类型,可为null - * @return 合适的路由 + * @param rawMessageRouter 原始的模板路由策略 + * @param terminalType 当前请求的终端类型 + * @return 合适的路由数据 */ - public static List selectRouter(List messageRouters, - TerminalTypeEnum terminalType) { - if (CollectionUtils.isEmpty(messageRouters)) { - return Collections.emptyList(); + public static MessageRouterTerminalDTO select(RawMessageRouterDTO rawMessageRouter, TerminalTypeEnum terminalType) { + if (RouterCategoryEnum.ACTION.equals(rawMessageRouter.getCategory())) { + return rawMessageRouter.getTerminals().get(0); } - return messageRouters.stream() - .filter(e -> Objects.equals(e.getTerminalType(), terminalType)) - .collect(Collectors.toList()); + return rawMessageRouter.getTerminals().stream() + .filter(e -> Objects.equals(terminalType, e.getTerminalType())) + // 若没有匹配的,默认选择第一个然后由前端去进行最终判断 + .findFirst().orElseGet(() -> rawMessageRouter.getTerminals().get(0)); } /** @@ -76,31 +66,12 @@ public final class MessageRouterUtil { * @param routerParam 路由参数 */ public static void parseRouteUrl(MessageRouterDTO router, String routerParam) { - // 路由参数有效且是直接调整页面地址的路由类型 - if (isRouterParamValid(routerParam) - && RouterCategoryEnum.JUMP.equals(router.getCategory())) { + // 路由参数有效 + if (isRouterParamValid(routerParam)) { // 替换原始URL中的参数变量 String routerUrl = PlaceholderResolver .getDefaultResolver().resolveByMap(router.getUrl(), JSON.parseObject(routerParam)); router.setUrl(routerUrl); } } - - private static Integer compare(RawMessageRouterDTO src, RawMessageRouterDTO tgt) { - if (Objects.isNull(tgt)) { - // NULL 默认优先级最低 - return 1; - } - Integer srcOrder = ROUTER_SELECT_ORDER.get(src.getTerminalType()); - Integer tgtOrder = ROUTER_SELECT_ORDER.get(tgt.getTerminalType()); - if (Objects.isNull(srcOrder)) { - // 新增的类型未指定优先级的话,则默认最低 - return 1; - } - if (Objects.isNull(tgtOrder)) { - // 新增的类型未指定优先级的话,则默认最低 - return -1; - } - return srcOrder.compareTo(tgtOrder); - } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java new file mode 100644 index 00000000..996e0f3d --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java @@ -0,0 +1,54 @@ +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 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: 接口调用 + */ + private RouterCategoryEnum category; + /** + * 按钮样式配置 + */ + private List style; + /** + * 路由终端列表,若当前按钮为ACTION,则只能配一个接口地址 + */ + private List terminals; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterTerminalDTO.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterTerminalDTO.java new file mode 100644 index 00000000..b4769b3a --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterTerminalDTO.java @@ -0,0 +1,46 @@ +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; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/TerminalTypeEnum.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/TerminalTypeEnum.java index 1394e4fc..6f1fde50 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/TerminalTypeEnum.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/TerminalTypeEnum.java @@ -20,7 +20,12 @@ public enum TerminalTypeEnum { IOS(3, "ios"), ANDROID(4, "android"), 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 String desc; 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 5eda61fe..90673954 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 @@ -2,6 +2,7 @@ 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.request.MessageTemplateCreateRequest; +import cn.axzo.msg.center.service.template.request.MessageTemplateUpdateRequest; import cn.axzo.msg.center.service.template.response.MessageTemplateDetailResponse; import cn.azxo.framework.common.model.CommonResponse; import org.springframework.cloud.openfeign.FeignClient; @@ -42,7 +43,7 @@ public interface MessageTemplateClient { * @return 模板编码 */ @PostMapping(value = "/message/template/update", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse update(@RequestBody @Valid MessageTemplateCreateRequest request); + CommonResponse update(@RequestBody @Valid MessageTemplateUpdateRequest request); /** * 消息模板详情 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 27d91041..cc0d75ae 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 @@ -2,6 +2,7 @@ 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.request.MessageTemplateCreateRequest; +import cn.axzo.msg.center.service.template.request.MessageTemplateUpdateRequest; import cn.axzo.msg.center.service.template.response.MessageTemplateDetailResponse; import cn.azxo.framework.common.model.CommonResponse; import lombok.extern.slf4j.Slf4j; @@ -24,7 +25,7 @@ public class MessageTemplateClientFallback implements MessageTemplateClient { } @Override - public CommonResponse update(MessageTemplateCreateRequest request) { + public CommonResponse update(MessageTemplateUpdateRequest request) { log.error("fall back while updating template. request:{}", request); return CommonResponse.error("fall back while updating template"); } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java index 14440e03..e3648cdb 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java @@ -1,6 +1,6 @@ package cn.axzo.msg.center.service.template.request; -import cn.axzo.msg.center.service.dto.MessageRouterDTO; +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 com.alibaba.fastjson.JSON; @@ -73,7 +73,7 @@ public class MessageTemplateCreateRequest implements Serializable { /** * 路由策略列表 */ - private List routers; + private List routers; @Override public String toString() { diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java index 5ec82aa1..73f35827 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java @@ -1,6 +1,6 @@ package cn.axzo.msg.center.service.template.request; -import cn.axzo.msg.center.service.dto.MessageRouterDTO; +import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO; import cn.axzo.msg.center.service.enums.PushTerminalEnum; import com.alibaba.fastjson.JSON; import lombok.Getter; @@ -65,7 +65,7 @@ public class MessageTemplateUpdateRequest implements Serializable { /** * 路由策略列表 */ - private List routers; + private List routers; @Override public String toString() { From db4e03716a0cb2269b9136d4e905e61c6b9469fb Mon Sep 17 00:00:00 2001 From: luofu Date: Thu, 12 Oct 2023 18:17:58 +0800 Subject: [PATCH 04/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=E5=AE=9A?= =?UTF-8?q?=E4=B9=89?= 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、查询分类树接口 2、分页查询分类关联的模板接口 3、变更模板分类的关联关系接口 4、解除模板分类的关联关系接口 影响: 无 --- .../group/client/MessageGroupClient.java | 11 ++++ .../MessageTemplateGroupRelationClient.java | 54 +++++++++++++++++++ .../fallback/MessageGroupClientFallback.java | 10 ++++ ...geTemplateGroupRelationClientFallback.java | 40 ++++++++++++++ ...ssageTemplateGroupRelationMoveRequest.java | 43 +++++++++++++++ ...ageTemplateGroupRelationRemoveRequest.java | 38 +++++++++++++ .../MessageGroupTreeNodeResponse.java | 47 ++++++++++++++++ .../MessageTemplateGroupRelationResponse.java | 35 ++++++++++++ .../request/MessageTemplateMoveToRequest.java | 40 -------------- 9 files changed, 278 insertions(+), 40 deletions(-) create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageTemplateGroupRelationClientFallback.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationMoveRequest.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationRemoveRequest.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/group/response/MessageGroupTreeNodeResponse.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/group/response/MessageTemplateGroupRelationResponse.java delete mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateMoveToRequest.java 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 611167eb..582fae14 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 @@ -1,8 +1,10 @@ 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.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 org.springframework.cloud.openfeign.FeignClient; import org.springframework.http.MediaType; @@ -12,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import javax.validation.Valid; +import java.util.List; /** * 消息分类管理 @@ -50,4 +53,12 @@ public interface MessageGroupClient { @PostMapping(value = "/message/group/node/delete", produces = {MediaType.APPLICATION_JSON_VALUE}) CommonResponse deleteNode(@RequestParam("nodeCode") String nodeCode, @RequestParam("operatorId") Long operatorId); + + /** + * 查询通知/待办的分类信息 + * + * @param category 消息分类 + */ + @PostMapping(value = "/message/group/node/list", produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse> list(@RequestParam("category") MessageCategoryEnum category); } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java new file mode 100644 index 00000000..92ced945 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java @@ -0,0 +1,54 @@ +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.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 org.springframework.web.bind.annotation.RequestParam; + +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 nodeCode 分类结点的编码 + * @return 模板列表 + */ + @PostMapping(value = "/message/template/group-relation/page", produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse> page(@RequestParam("nodeCode") String nodeCode); + + /** + * 变更模板与分类的关联关系 + * + * @param request 变更分类的相关参数 + */ + @PostMapping(value = "/message/template/group-relation/move", produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse move(@RequestBody MessageTemplateGroupRelationMoveRequest request); + + /** + * 变更模板与分类的关联关系 + * + * @param request 变更分类的相关参数 + * @return 关联关系解除失败的模板编码 + */ + @PostMapping(value = "/message/template/group-relation/remove", produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse> remove(@RequestBody MessageTemplateGroupRelationRemoveRequest request); +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageGroupClientFallback.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageGroupClientFallback.java index 9c350661..f53866ae 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageGroupClientFallback.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageGroupClientFallback.java @@ -1,12 +1,16 @@ 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.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.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import java.util.List; + /** * @description * @@ -34,4 +38,10 @@ public class MessageGroupClientFallback implements MessageGroupClient { log.error("fall back while deleting message group node. nodeCode:[{}], operatorId:[{}]", nodeCode, operatorId); return CommonResponse.error("fall back while deleting message group node"); } + + @Override + public CommonResponse> list(MessageCategoryEnum category) { + log.error("fall back while listing message group node. category:[{}]", category); + return CommonResponse.error("fall back while listing message group node"); + } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageTemplateGroupRelationClientFallback.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageTemplateGroupRelationClientFallback.java new file mode 100644 index 00000000..39915a7e --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageTemplateGroupRelationClientFallback.java @@ -0,0 +1,40 @@ +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.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(String nodeCode) { + log.error("fall back while page querying message template group relation. nodeCode:{}", nodeCode); + return CommonResponse.error("fall back while page querying message template group relation"); + } + + @Override + public CommonResponse 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> 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"); + } +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationMoveRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationMoveRequest.java new file mode 100644 index 00000000..f4bc2bbc --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationMoveRequest.java @@ -0,0 +1,43 @@ +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 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; + + /** + * 模板当前所处的分类结点编码 + */ + @NotBlank(message = "curNodeCode is required") + private String curNodeCode; + /** + * 模板将要移动到的目标分类结点编码 + */ + @NotBlank(message = "targetNodeCode is required") + private String targetNodeCode; + /** + * 选中的模板编码列表 + */ + @NotEmpty(message = "templateCodes is required") + private List templateCodes; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationRemoveRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationRemoveRequest.java new file mode 100644 index 00000000..1a395421 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationRemoveRequest.java @@ -0,0 +1,38 @@ +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 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; + + /** + * 模板当前所处的分类结点编码 + */ + @NotBlank(message = "curNodeCode is required") + private String curNodeCode; + /** + * 选中的模板编码列表 + */ + @NotEmpty(message = "templateCodes is required") + private List templateCodes; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} 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 new file mode 100644 index 00000000..b3be1f48 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/response/MessageGroupTreeNodeResponse.java @@ -0,0 +1,47 @@ +package cn.axzo.msg.center.service.group.response; + +import cn.axzo.msg.center.service.enums.MessageGroupNodeCategoryEnum; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; +import java.util.List; + +/** + * @author cold_blade + * @date 2023/10/12 + * @version 1.0 + */ +@Setter +@Getter +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 children; +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/response/MessageTemplateGroupRelationResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/response/MessageTemplateGroupRelationResponse.java new file mode 100644 index 00000000..a184e65b --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/response/MessageTemplateGroupRelationResponse.java @@ -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; +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateMoveToRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateMoveToRequest.java deleted file mode 100644 index c7bee961..00000000 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateMoveToRequest.java +++ /dev/null @@ -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 templateGroupRelationIds; - /** - * 迁移的目标分类结点编码 - */ - private String targetGroupNodeCode; - - @Override - public String toString() { - return JSON.toJSONString(this); - } -} From 420fa8da394a03b5f3ced739693807b44970e2a5 Mon Sep 17 00:00:00 2001 From: luofu Date: Fri, 13 Oct 2023 09:50:09 +0800 Subject: [PATCH 05/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=E5=AE=9A?= =?UTF-8?q?=E4=B9=89?= 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、查询分类树接口 2、分页查询分类关联的模板接口 3、变更模板分类的关联关系接口 4、解除模板分类的关联关系接口 影响: 无 --- .../template/response/MessageTemplateDetailResponse.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java index 6599deb3..de1bf007 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java @@ -1,6 +1,6 @@ package cn.axzo.msg.center.service.template.response; -import cn.axzo.msg.center.service.dto.MessageRouterDTO; +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 com.alibaba.fastjson.JSON; @@ -64,7 +64,7 @@ public class MessageTemplateDetailResponse implements Serializable { /** * 路由策略列表 */ - private List routers; + private List routers; @Override public String toString() { From 079abfca285427604a446a0da3bb90dc02ed0548 Mon Sep 17 00:00:00 2001 From: luofu Date: Fri, 13 Oct 2023 10:25:10 +0800 Subject: [PATCH 06/50] =?UTF-8?q?docs(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=E5=87=BA?= =?UTF-8?q?=E5=8F=82=E7=9A=84=E6=B3=A8=E9=87=8A=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景: https://jira.axzo.cn/browse/REQ-1465?goToView=1 修改: 消息模板相关接口出参的注释说明 影响: 无 --- .../msg/center/service/dto/MessageRouterButtonDTO.java | 2 ++ .../axzo/msg/center/service/enums/PushTerminalEnum.java | 9 ++++++++- .../group/request/MessageGroupNodeAddRequest.java | 6 ++++++ .../group/request/MessageGroupNodeUpdateRequest.java | 2 ++ .../template/request/MessageTemplateCreateRequest.java | 6 ++++-- .../template/request/MessageTemplateUpdateRequest.java | 6 ++++-- .../template/response/MessageTemplateDetailResponse.java | 6 ++++-- 7 files changed, 30 insertions(+), 7 deletions(-) diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java index 996e0f3d..fef15deb 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java @@ -40,6 +40,8 @@ public class MessageRouterButtonDTO implements Serializable { private RouterCategoryEnum category; /** * 按钮样式配置 + * HIGH_LIGHT: 按钮高亮展示 + * OVER_CARD: 按钮显示在卡片上 */ private List style; /** diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java index a475125a..c52deaf6 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java @@ -15,7 +15,14 @@ import lombok.Getter; @AllArgsConstructor(access = AccessLevel.PRIVATE) public enum PushTerminalEnum { - B_ENTERPRISE_APP("B-安心筑企业版"), C_WORKER_APP("C-安心筑工人版"), + /** + * B-安心筑企业版 + */ + B_ENTERPRISE_APP("B-安心筑企业版"), + /** + * C-安心筑工人版 + */ + C_WORKER_APP("C-安心筑工人版"), ; private final String desc; 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 852c215b..d38db2b4 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 @@ -43,6 +43,12 @@ public class MessageGroupNodeAddRequest implements Serializable { 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") private MessageGroupNodeCategoryEnum category; diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageGroupNodeUpdateRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageGroupNodeUpdateRequest.java index de903960..1c33d1da 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageGroupNodeUpdateRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageGroupNodeUpdateRequest.java @@ -39,6 +39,8 @@ public class MessageGroupNodeUpdateRequest implements Serializable { private String nodeName; /** * 结点状态 + * ENABLE: 启用 + * DISABLE: 禁用 */ private StatusEnum status; /** diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java index e3648cdb..3b963f14 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java @@ -44,12 +44,14 @@ public class MessageTemplateCreateRequest implements Serializable { @NotNull(message = "category is required") private MessageCategoryEnum category; /** - * 消息分类的树结点编码路径列表 eg: aa:bb:cc + * 消息分类的树结点编码路径列表 eg: OMS待办中心/施工管理/发薪 */ @NotEmpty(message = "groupPaths is required") private List groupPaths; /** * 推送终端配置 + * B_ENTERPRISE_APP: B-安心筑企业版 + * C_WORKER_APP: C-安心筑工人版 */ private List pushTerminals; /** @@ -58,7 +60,7 @@ public class MessageTemplateCreateRequest implements Serializable { @NotBlank(message = "msgTitle is required") private String msgTitle; /** - * 消息卡片信息 + * 消息卡片信息,JSON字串 */ private String msgCardInfo; /** diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java index 73f35827..2346ed49 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java @@ -36,12 +36,14 @@ public class MessageTemplateUpdateRequest implements Serializable { @NotBlank(message = "templateName is required") private String templateName; /** - * 消息分类的树结点编码路径列表 eg: aa:bb:cc + * 消息分类的树结点编码路径列表 eg: OMS待办中心/施工管理/发薪 */ @NotEmpty(message = "groupPaths is required") private List groupPaths; /** * 推送终端配置 + * B_ENTERPRISE_APP: B-安心筑企业版 + * C_WORKER_APP: C-安心筑工人版 */ private List pushTerminals; /** @@ -50,7 +52,7 @@ public class MessageTemplateUpdateRequest implements Serializable { @NotBlank(message = "msgTitle is required") private String msgTitle; /** - * 消息卡片信息 + * 消息卡片信息,JSON字串 */ private String msgCardInfo; /** diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java index de1bf007..65c68302 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java @@ -38,11 +38,13 @@ public class MessageTemplateDetailResponse implements Serializable { */ private MessageCategoryEnum category; /** - * 消息分类的树结点编码路径列表 eg: aa:bb:cc + * 消息分类的树结点编码路径列表 eg: OMS待办中心/施工管理/发薪 */ private List groupPaths; /** * 推送终端配置 + * B_ENTERPRISE_APP: B-安心筑企业版 + * C_WORKER_APP: C-安心筑工人版 */ private List pushTerminals; /** @@ -50,7 +52,7 @@ public class MessageTemplateDetailResponse implements Serializable { */ private String msgTitle; /** - * 消息卡片信息 + * 消息卡片信息,JSON字串 */ private String msgCardInfo; /** From 1fea7e4b139299b97f9e9b2f58a359bf3f930979 Mon Sep 17 00:00:00 2001 From: luofu Date: Fri, 13 Oct 2023 10:56:40 +0800 Subject: [PATCH 07/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景: https://jira.axzo.cn/browse/REQ-1465?goToView=1 修改: 消息模板相关接口参数调整 影响: 无 --- .../msg/center/service/group/client/MessageGroupClient.java | 2 +- .../group/client/MessageTemplateGroupRelationClient.java | 5 +++-- .../request/MessageTemplateGroupRelationMoveRequest.java | 6 ++++++ .../request/MessageTemplateGroupRelationRemoveRequest.java | 6 ++++++ 4 files changed, 16 insertions(+), 3 deletions(-) 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 582fae14..b3ec732a 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 @@ -43,7 +43,7 @@ public interface MessageGroupClient { * @param request 待更新的结点相关数据项 */ @PostMapping(value = "/message/group/node/update", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse updateStatus(@RequestBody MessageGroupNodeUpdateRequest request); + CommonResponse updateStatus(@RequestBody @Valid MessageGroupNodeUpdateRequest request); /** * 删除结点 diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java index 92ced945..8cbf7ab5 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java @@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; +import javax.validation.Valid; import java.util.List; /** @@ -41,7 +42,7 @@ public interface MessageTemplateGroupRelationClient { * @param request 变更分类的相关参数 */ @PostMapping(value = "/message/template/group-relation/move", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse move(@RequestBody MessageTemplateGroupRelationMoveRequest request); + CommonResponse move(@RequestBody @Valid MessageTemplateGroupRelationMoveRequest request); /** * 变更模板与分类的关联关系 @@ -50,5 +51,5 @@ public interface MessageTemplateGroupRelationClient { * @return 关联关系解除失败的模板编码 */ @PostMapping(value = "/message/template/group-relation/remove", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse> remove(@RequestBody MessageTemplateGroupRelationRemoveRequest request); + CommonResponse> remove(@RequestBody @Valid MessageTemplateGroupRelationRemoveRequest request); } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationMoveRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationMoveRequest.java index f4bc2bbc..bcfff02e 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationMoveRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationMoveRequest.java @@ -6,6 +6,7 @@ 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; @@ -20,6 +21,11 @@ public class MessageTemplateGroupRelationMoveRequest implements Serializable { private static final long serialVersionUID = 8336083457743619246L; + /** + * 操作者的自然人id + */ + @NotNull(message = "operatorId is required") + private Long operatorId; /** * 模板当前所处的分类结点编码 */ diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationRemoveRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationRemoveRequest.java index 1a395421..72f97e15 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationRemoveRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationRemoveRequest.java @@ -6,6 +6,7 @@ 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; @@ -20,6 +21,11 @@ public class MessageTemplateGroupRelationRemoveRequest implements Serializable { private static final long serialVersionUID = 8336083457743619246L; + /** + * 操作者的自然人id + */ + @NotNull(message = "operatorId is required") + private Long operatorId; /** * 模板当前所处的分类结点编码 */ From 3c0801ec02bfb9518c2008fa82de49b060b1e104 Mon Sep 17 00:00:00 2001 From: luofu Date: Fri, 13 Oct 2023 11:09:36 +0800 Subject: [PATCH 08/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景: https://jira.axzo.cn/browse/REQ-1465?goToView=1 修改: 消息模板相关接口参数调整 影响: 无 --- .../template/request/MessageTemplateCreateRequest.java | 6 +++--- .../template/request/MessageTemplateUpdateRequest.java | 6 +++--- .../template/response/MessageTemplateDetailResponse.java | 6 ++++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java index 3b963f14..1241a76c 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java @@ -44,10 +44,10 @@ public class MessageTemplateCreateRequest implements Serializable { @NotNull(message = "category is required") private MessageCategoryEnum category; /** - * 消息分类的树结点编码路径列表 eg: OMS待办中心/施工管理/发薪 + * 消息分类树的叶结点的结点编码列表 */ - @NotEmpty(message = "groupPaths is required") - private List groupPaths; + @NotEmpty(message = "leafGroupNodes is required") + private List leafGroupNodes; /** * 推送终端配置 * B_ENTERPRISE_APP: B-安心筑企业版 diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java index 2346ed49..52ca1801 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java @@ -36,10 +36,10 @@ public class MessageTemplateUpdateRequest implements Serializable { @NotBlank(message = "templateName is required") private String templateName; /** - * 消息分类的树结点编码路径列表 eg: OMS待办中心/施工管理/发薪 + * 消息分类树的叶结点的结点编码列表 */ - @NotEmpty(message = "groupPaths is required") - private List groupPaths; + @NotEmpty(message = "leafGroupNodes is required") + private List leafGroupNodes; /** * 推送终端配置 * B_ENTERPRISE_APP: B-安心筑企业版 diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java index 65c68302..67e29201 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java @@ -10,6 +10,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import javax.validation.constraints.NotEmpty; import java.io.Serializable; import java.util.List; @@ -38,9 +39,10 @@ public class MessageTemplateDetailResponse implements Serializable { */ private MessageCategoryEnum category; /** - * 消息分类的树结点编码路径列表 eg: OMS待办中心/施工管理/发薪 + * 消息分类树的叶结点的结点编码列表 */ - private List groupPaths; + @NotEmpty(message = "leafGroupNodes is required") + private List leafGroupNodes; /** * 推送终端配置 * B_ENTERPRISE_APP: B-安心筑企业版 From 7d6ba5b65244b8dcb226f0a287dce0427bd5b752 Mon Sep 17 00:00:00 2001 From: luofu Date: Fri, 13 Oct 2023 11:32:30 +0800 Subject: [PATCH 09/50] =?UTF-8?q?feat(REQ-1465):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=88=86=E7=B1=BB=E7=BB=93=E7=82=B9=E5=87=BD=E6=95=B0=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景: https://jira.axzo.cn/browse/REQ-1465?goToView=1 修改: updateStatus -> updateNode 影响: 无 --- .../msg/center/service/group/client/MessageGroupClient.java | 2 +- .../group/client/fallback/MessageGroupClientFallback.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 b3ec732a..c44dc076 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 @@ -43,7 +43,7 @@ public interface MessageGroupClient { * @param request 待更新的结点相关数据项 */ @PostMapping(value = "/message/group/node/update", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse updateStatus(@RequestBody @Valid MessageGroupNodeUpdateRequest request); + CommonResponse updateNode(@RequestBody @Valid MessageGroupNodeUpdateRequest request); /** * 删除结点 diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageGroupClientFallback.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageGroupClientFallback.java index f53866ae..b72f583b 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageGroupClientFallback.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageGroupClientFallback.java @@ -28,7 +28,7 @@ public class MessageGroupClientFallback implements MessageGroupClient { } @Override - public CommonResponse updateStatus(MessageGroupNodeUpdateRequest request) { + public CommonResponse updateNode(MessageGroupNodeUpdateRequest request) { log.error("fall back while updating message group node. request:{}", request); return CommonResponse.error("fall back while updating message group node"); } From cc350a3afa667852f08194b616e76ac4796cc387 Mon Sep 17 00:00:00 2001 From: luofu Date: Fri, 13 Oct 2023 14:54:08 +0800 Subject: [PATCH 10/50] =?UTF-8?q?feat(REQ-1465):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=9B=B8=E5=85=B3=E6=93=8D=E4=BD=9C=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= 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、新增模板分页查询接口 2、新增更新模板状态接口 影响: 无 --- .../controller/MessageTemplateController.java | 16 +++++ .../client/MessageTemplateClient.java | 24 +++++++- .../MessageTemplateClientFallback.java | 16 +++++ .../request/MessageTemplatePageRequest.java | 45 ++++++++++++++ .../MessageTemplateUpdateStatusRequest.java | 32 ++++++++++ .../response/MessageTemplatePageResponse.java | 59 +++++++++++++++++++ 6 files changed, 190 insertions(+), 2 deletions(-) create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplatePageRequest.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateStatusRequest.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplatePageResponse.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 8de9e4b4..564597ea 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 @@ -4,9 +4,13 @@ import cn.axzo.msg.center.message.domain.param.MessageTemplateCreateParam; import cn.axzo.msg.center.message.service.MessageTemplateNewService; 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.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.Page; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.RestController; @@ -41,4 +45,16 @@ public class MessageTemplateController implements MessageTemplateClient { // TODO:[cold_blade] [P0] query template return null; } + + @Override + public CommonResponse> page(MessageTemplatePageRequest request) { + // TODO:[cold_blade] [P0] page query template + return null; + } + + @Override + public CommonResponse updateStatus(MessageTemplateUpdateStatusRequest request) { + // TODO:[cold_blade] [P0] update template status + return null; + } } 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 90673954..2c7d0178 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 @@ -2,9 +2,13 @@ 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.request.MessageTemplateCreateRequest; +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.Page; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; @@ -37,10 +41,9 @@ public interface MessageTemplateClient { CommonResponse save(@RequestBody @Valid MessageTemplateCreateRequest request); /** - * 添加消息模板 + * 编辑消息模板 * * @param request 模板数据模型 - * @return 模板编码 */ @PostMapping(value = "/message/template/update", produces = {MediaType.APPLICATION_JSON_VALUE}) CommonResponse update(@RequestBody @Valid MessageTemplateUpdateRequest request); @@ -53,4 +56,21 @@ public interface MessageTemplateClient { */ @PostMapping(value = "/message/template/detail", produces = {MediaType.APPLICATION_JSON_VALUE}) CommonResponse detail(@RequestParam("templateCode") String templateCode); + + /** + * 分页查询模板 + * + * @param request 分页查询参数 + * @return 模板列表 + */ + @PostMapping(value = "/message/template/page", produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse> page(@RequestBody MessageTemplatePageRequest request); + + /** + * 启用/禁用消息模板 + * + * @param request 模板状态 + */ + @PostMapping(value = "/message/template/update-status", produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse updateStatus(@RequestBody @Valid MessageTemplateUpdateStatusRequest request); } 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 cc0d75ae..f0d56970 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 @@ -2,9 +2,13 @@ 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.request.MessageTemplateCreateRequest; +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.Page; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -35,4 +39,16 @@ public class MessageTemplateClientFallback implements MessageTemplateClient { log.error("fall back while query template detail. templateCode:{}", templateCode); return CommonResponse.error("fall back while query template detail"); } + + @Override + public CommonResponse> 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 updateStatus(MessageTemplateUpdateStatusRequest request) { + log.error("fall back while updating template status. request:{}", request); + return CommonResponse.error("fall back while updating template status"); + } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplatePageRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplatePageRequest.java new file mode 100644 index 00000000..067b21d5 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplatePageRequest.java @@ -0,0 +1,45 @@ +package cn.axzo.msg.center.service.template.request; + +import cn.axzo.msg.center.service.enums.MessageCategoryEnum; +import cn.axzo.msg.center.service.enums.StatusEnum; +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 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; +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateStatusRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateStatusRequest.java new file mode 100644 index 00000000..50e2f7c8 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateStatusRequest.java @@ -0,0 +1,32 @@ +package cn.axzo.msg.center.service.template.request; + +import cn.axzo.msg.center.service.enums.StatusEnum; +import lombok.Getter; +import lombok.Setter; + +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; + /** + * 模板状态 + * ENABLE: 启用 + * DISABLE: 禁用 + */ + private StatusEnum status; +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplatePageResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplatePageResponse.java new file mode 100644 index 00000000..8f7df96b --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplatePageResponse.java @@ -0,0 +1,59 @@ +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; + +/** + * @author cold_blade + * @date 2023/10/12 + * @version 1.0 + */ +@Setter +@Getter +public class MessageTemplatePageResponse 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 String groupNodePath; + /** + * 模板状态 + * ENABLE: 启用 + * DISABLE: 禁用 + */ + private StatusEnum status; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} From e6130b9ec74fe5bfdabb63865f5d4dc8baa3dc17 Mon Sep 17 00:00:00 2001 From: luofu Date: Fri, 13 Oct 2023 15:05:02 +0800 Subject: [PATCH 11/50] =?UTF-8?q?feat(REQ-1465):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=9B=B8=E5=85=B3=E6=93=8D=E4=BD=9C=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= 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、新增模板分页查询接口 2、新增更新模板状态接口 影响: 无 --- .../template/request/MessageTemplatePageRequest.java | 6 ++++++ .../request/MessageTemplateUpdateStatusRequest.java | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplatePageRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplatePageRequest.java index 067b21d5..b2f7cc42 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplatePageRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplatePageRequest.java @@ -2,6 +2,7 @@ package cn.axzo.msg.center.service.template.request; 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; @@ -42,4 +43,9 @@ public class MessageTemplatePageRequest implements Serializable { * DISABLE: 禁用 */ private StatusEnum status; + + @Override + public String toString() { + return JSON.toJSONString(this); + } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateStatusRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateStatusRequest.java index 50e2f7c8..e3fd9759 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateStatusRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateStatusRequest.java @@ -1,9 +1,11 @@ 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; @@ -23,10 +25,20 @@ public class MessageTemplateUpdateStatusRequest implements Serializable { */ @NotNull(message = "operatorId is required") private Long operatorId; + /** + * 模板编码 + */ + @NotBlank(message = "templateCode is required") + private String templateCode; /** * 模板状态 * ENABLE: 启用 * DISABLE: 禁用 */ private StatusEnum status; + + @Override + public String toString() { + return JSON.toJSONString(this); + } } From 6869e5f3e5b55ad550f3b1d2230e3919c797210e Mon Sep 17 00:00:00 2001 From: luofu Date: Fri, 13 Oct 2023 16:41:50 +0800 Subject: [PATCH 12/50] =?UTF-8?q?feat(REQ-1465):=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=A8=A1=E5=9E=8B?= 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、处理数据模型变更引起的空指针问题 影响: 无 --- .../message/domain/dto/RawMessageRouterDTO.java | 14 ++++++++++++-- .../impl/MessageTemplateRouterServiceImpl.java | 3 +-- .../axzo/msg/center/utils/MessageRouterUtil.java | 16 ++++++++++++++-- .../MessageTemplateUpdateStatusRequest.java | 1 + 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java index ba1ee845..d37ccedb 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java @@ -60,12 +60,15 @@ public class RawMessageRouterDTO implements Serializable { public static RawMessageRouterDTO from(List msgTemplateRouters) { MessageTemplateRouter router = msgTemplateRouters.get(0); + List terminals = msgTemplateRouters.stream() + .map(RawMessageRouterDTO::convert2Terminal) + .collect(Collectors.toList()); return RawMessageRouterDTO.builder() .desc(router.getName()) .category(router.getCategory()) .templateCode(router.getTemplateCode()) - .style(JSON.parseArray(router.getStyle(), ButtonStyleEnum.class)) - .terminals(JSON.parseArray(router.getStyle(), MessageRouterTerminalDTO.class)) + .style(MessageRouterUtil.parseButtonStyle(router.getStyle())) + .terminals(terminals) .build(); } @@ -107,6 +110,13 @@ public class RawMessageRouterDTO implements Serializable { return router; } + private static MessageRouterTerminalDTO convert2Terminal(MessageTemplateRouter router) { + return MessageRouterTerminalDTO.builder() + .url(router.getUrl()) + .terminalType(router.getTerminalType()) + .build(); + } + @Override public String toString() { return JSON.toJSONString(this); diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java index 6572992f..59e73f4a 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java @@ -69,8 +69,7 @@ public class MessageTemplateRouterServiceImpl implements MessageTemplateRouterSe // 模板路由的按钮维度 Map> btnMap = e.stream() .collect(Collectors.groupingBy(MessageTemplateRouter::getName)); - return btnMap.values().stream() - .map(RawMessageRouterDTO::from); + return btnMap.values().stream().map(RawMessageRouterDTO::from); }).collect(Collectors.toList()); } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java b/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java index d04bcfe1..9c752d85 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java @@ -4,18 +4,17 @@ import cn.axzo.msg.center.common.utils.PlaceholderResolver; import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO; 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.TerminalTypeEnum; import com.alibaba.fastjson.JSON; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; /** * @description @@ -74,4 +73,17 @@ public final class MessageRouterUtil { router.setUrl(routerUrl); } } + + /** + * 解析按钮style + * + * @param style 按钮style的JSON字串 + * @return 按钮style的枚举列表 + */ + public static List parseButtonStyle(String style) { + if (StringUtils.isBlank(style)) { + return Collections.emptyList(); + } + return JSON.parseArray(style, ButtonStyleEnum.class); + } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateStatusRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateStatusRequest.java index e3fd9759..3443615d 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateStatusRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateStatusRequest.java @@ -35,6 +35,7 @@ public class MessageTemplateUpdateStatusRequest implements Serializable { * ENABLE: 启用 * DISABLE: 禁用 */ + @NotNull(message = "status is required") private StatusEnum status; @Override From 2aedc6301f92a79fb61a993baf7de090bdde470a Mon Sep 17 00:00:00 2001 From: luofu Date: Fri, 13 Oct 2023 17:26:15 +0800 Subject: [PATCH 13/50] =?UTF-8?q?feat(REQ-1465):=20=E5=BE=85=E5=8A=9E?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E8=A1=A8=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= 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、待办记录表新增业务扩展参数字段 影响: 无 --- .../domain/param/PendingMessagePushParam.java | 4 ++ .../impl/PendingMessageNewServiceImpl.java | 30 ++++++++------ .../axzo/msg/center/utils/JSONObjectUtil.java | 40 +++++++++++++++++++ .../request/PendingMessagePushRequest.java | 4 ++ 4 files changed, 65 insertions(+), 13 deletions(-) create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/utils/JSONObjectUtil.java diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/PendingMessagePushParam.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/PendingMessagePushParam.java index 429b0a31..61f726f7 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/PendingMessagePushParam.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/PendingMessagePushParam.java @@ -69,6 +69,10 @@ public class PendingMessagePushParam implements Serializable { * 业务描述eg:流程结点描述 */ private String bizDesc; + /** + * 业务扩展参数,JSON字符串格式 + */ + private String bizExtParams; /** * 路由参数(json string) */ diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java index fcbc418b..fd9312ba 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java @@ -26,11 +26,13 @@ import cn.axzo.msg.center.service.enums.PendingMessageStateEnum; import cn.axzo.msg.center.service.enums.TerminalTypeEnum; import cn.axzo.msg.center.service.pending.request.PendingMessagePageRequest; 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.OrderFieldParseUtil; 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.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; @@ -282,10 +284,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService { record.setOrgId(param.getOrgId()); record.setOrgName(param.getOrgName()); // 构建业务类信息 - record.setBizCode(param.getBizCode()); - record.setSubBizCode(param.getSubBizCode()); - record.setBizDesc(param.getBizDesc()); - record.setBizCategory(param.getBizCategory()); + buildBusinessInfo(record, param); return record; } @@ -299,17 +298,22 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService { } private void buildTemplateInfo(PendingMessageRecord record, MessageTemplateDTO msgTemplate, String routeParam) { - String title = msgTemplate.getTitle(); - String content = msgTemplate.getContent(); - if (StringUtils.isNotBlank(routeParam)) { - title = PlaceholderResolver - .getDefaultResolver().resolveByMap(title, JSON.parseObject(routeParam)); - content = PlaceholderResolver - .getDefaultResolver().resolveByMap(content, JSON.parseObject(routeParam)); - } + JSONObject routerParamObj = JSONObjectUtil.parseObject(routeParam); + String title = PlaceholderResolver + .getDefaultResolver().resolveByMap(msgTemplate.getTitle(), routerParamObj); + String content = PlaceholderResolver + .getDefaultResolver().resolveByMap(msgTemplate.getContent(), routerParamObj); record.setTitle(title); record.setContent(content); 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())); } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/utils/JSONObjectUtil.java b/inside-notices/src/main/java/cn/axzo/msg/center/utils/JSONObjectUtil.java new file mode 100644 index 00000000..d22d57cc --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/utils/JSONObjectUtil.java @@ -0,0 +1,40 @@ +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.lang3.StringUtils; + +/** + * @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(); + + /** + * 解析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 原字符串OR空的JSONObject + */ + public static String checkAndReturn(String str) { + return parseObject(str).toJSONString(); + } +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/PendingMessagePushRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/PendingMessagePushRequest.java index ab8182c3..ad983d88 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/PendingMessagePushRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/PendingMessagePushRequest.java @@ -68,6 +68,10 @@ public class PendingMessagePushRequest implements Serializable { * 业务描述eg:流程结点描述 */ private String bizDesc; + /** + * 业务扩展参数,JSON字符串格式 + */ + private String bizExtParams; /** * 路由参数(json string) */ From feb18c9c2e62f2c10a3da699f2775682ef40e80e Mon Sep 17 00:00:00 2001 From: luofu Date: Mon, 16 Oct 2023 11:12:00 +0800 Subject: [PATCH 14/50] =?UTF-8?q?feat(REQ-1465):=20=E5=BE=85=E5=8A=9E?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E8=A1=A8=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= 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、待办记录表新增业务扩展参数字段 影响: 无 --- inside-notices/pom.xml | 5 + .../controller/MessageTemplateController.java | 5 +- .../PendingMessageNewController.java | 6 +- .../domain/dto/GroupTreeNodePathDTO.java | 58 ++++++ .../domain/dto/MessageGroupNodeDTO.java | 87 -------- .../dto/MessageGroupNodeStatisticDTO.java | 76 +++++++ .../param/MessageTemplateCreateParam.java | 19 +- .../service/MessageGroupNodeService.java | 41 ++++ .../message/service/MessageGroupService.java | 41 ---- .../MessageGroupTreeNodeCacheService.java | 53 +++++ .../service/MessageTemplateGroupService.java | 9 + .../service/MessageTemplateNewService.java | 2 +- .../service/PendingMessageNewService.java | 5 +- .../impl/MessageGroupNodeServiceImpl.java | 62 ++++++ .../service/impl/MessageGroupServiceImpl.java | 70 ------- .../MessageGroupTreeNodeCacheServiceImpl.java | 185 ++++++++++++++++++ .../impl/MessageTemplateGroupServiceImpl.java | 23 +++ .../impl/MessageTemplateNewServiceImpl.java | 88 +++++++-- .../impl/PendingMessageNewServiceImpl.java | 43 ++-- .../axzo/msg/center/utils/JSONObjectUtil.java | 20 ++ .../axzo/msg/center/utils/TreeHelperUtil.java | 44 +++++ .../msg/center/service/dto/GroupNodeDTO.java | 53 ----- .../center/service/dto/GroupTreeNodeDTO.java | 71 +++++++ .../common/enums/ServiceErrorCodeEnum.java | 23 +++ 24 files changed, 791 insertions(+), 298 deletions(-) create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GroupTreeNodePathDTO.java delete mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageGroupNodeDTO.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageGroupNodeStatisticDTO.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupNodeService.java delete mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupService.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupTreeNodeCacheService.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupNodeServiceImpl.java delete mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupServiceImpl.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupTreeNodeCacheServiceImpl.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/utils/TreeHelperUtil.java delete mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/GroupNodeDTO.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/GroupTreeNodeDTO.java create mode 100644 msg-center-common/src/main/java/cn/axzo/msg/center/common/enums/ServiceErrorCodeEnum.java diff --git a/inside-notices/pom.xml b/inside-notices/pom.xml index fc0a36ac..7d64c516 100644 --- a/inside-notices/pom.xml +++ b/inside-notices/pom.xml @@ -110,6 +110,11 @@ 1.0.0-SNAPSHOT compile + + + cn.axzo.pokonyan + pokonyan + \ No newline at end of file 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 564597ea..9fdc269d 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 @@ -29,9 +29,8 @@ public class MessageTemplateController implements MessageTemplateClient { @Override public CommonResponse save(MessageTemplateCreateRequest request) { - MessageTemplateCreateParam param = MessageTemplateCreateParam.from(request); - messageTemplateNewService.createTemplate(param); - return CommonResponse.success(param.getTemplateCode()); + return CommonResponse.success( + messageTemplateNewService.createTemplate(MessageTemplateCreateParam.from(request))); } @Override diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PendingMessageNewController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PendingMessageNewController.java index 90d07020..f825ad98 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PendingMessageNewController.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PendingMessageNewController.java @@ -1,6 +1,6 @@ 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.param.MessageGroupNodeStatisticParam; import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam; @@ -36,10 +36,10 @@ public class PendingMessageNewController implements PendingMessageClient { @Override public CommonResponse> groupStatistic(MessageGroupNodeStatisticRequest request) { - List groupNodes = pendingMessageNewService + List groupNodes = pendingMessageNewService .groupStatistic(MessageGroupNodeStatisticParam.from(request)); return CommonResponse.success(groupNodes.stream() - .map(MessageGroupNodeDTO::toResponse) + .map(MessageGroupNodeStatisticDTO::toResponse) .collect(Collectors.toList()) ); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GroupTreeNodePathDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GroupTreeNodePathDTO.java new file mode 100644 index 00000000..ad2d43b4 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GroupTreeNodePathDTO.java @@ -0,0 +1,58 @@ +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 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 GroupTreeNodePathDTO of(String nodeCode, Collection 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 pathFunc, Collection nodes, + String spliter) { + return nodes.stream().map(pathFunc).collect(Collectors.joining(spliter)); + } + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageGroupNodeDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageGroupNodeDTO.java deleted file mode 100644 index 37bd6303..00000000 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageGroupNodeDTO.java +++ /dev/null @@ -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 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 children = this.children.stream() - .map(MessageGroupNodeDTO::toResponse).collect(Collectors.toList()); - response.setNodeChildren(children); - return response; - } - - @Override - public String toString() { - return JSON.toJSONString(this); - } -} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageGroupNodeStatisticDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageGroupNodeStatisticDTO.java new file mode 100644 index 00000000..f5cef354 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageGroupNodeStatisticDTO.java @@ -0,0 +1,76 @@ +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, Serializable { + + private static final long serialVersionUID = 5171436359992401120L; + + /** + * 树结点 + */ + private GroupTreeNodeDTO treeNode; + /** + * 子节点列表 + */ + private List nodeChildren; + /** + * 结点对应的代办数量 + */ + private Integer pendingCount; + + public static MessageGroupNodeStatisticDTO of(GroupTreeNodeDTO groupNode) { + return MessageGroupNodeStatisticDTO.builder() + .treeNode(groupNode) + .build(); + } + + public MessageGroupNodeResponse toResponse() { + MessageGroupNodeResponse response = BeanConverter.convert(this, MessageGroupNodeResponse.class); + List 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(); + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateCreateParam.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateCreateParam.java index b1151d5d..c516a122 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateCreateParam.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateCreateParam.java @@ -1,10 +1,10 @@ package cn.axzo.msg.center.message.domain.param; import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO; -import cn.axzo.msg.center.service.dto.MessageRouterDTO; 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.utils.UUIDUtil; +import cn.axzo.msg.center.utils.JSONObjectUtil; import com.alibaba.fastjson.JSON; import lombok.AllArgsConstructor; import lombok.Builder; @@ -36,9 +36,9 @@ public class MessageTemplateCreateParam implements Serializable { */ private String templateName; /** - * 系统自动生成的模板code + * 消息分类树的叶结点的结点编码列表 */ - private String templateCode; + private List leafGroupNodes; /** * 所属消息类型 * GENERAL_MESSAGE: 普通消息 @@ -69,18 +69,25 @@ public class MessageTemplateCreateParam implements Serializable { * 路由列表 */ private List routers; + /** + * 推送终端配置 + * B_ENTERPRISE_APP: B-安心筑企业版 + * C_WORKER_APP: C-安心筑工人版 + */ + private List pushTerminals; public static MessageTemplateCreateParam from(MessageTemplateCreateRequest request) { return MessageTemplateCreateParam.builder() .templateName(request.getTemplateName()) - .templateCode(UUIDUtil.uuidString()) .msgCategory(request.getCategory()) + .leafGroupNodes(request.getLeafGroupNodes()) .title(request.getMsgTitle()) .content(request.getMsgContent()) - .cardContent(request.getMsgCardInfo()) + .cardContent(JSONObjectUtil.checkAndReturn(request.getMsgCardInfo())) .icon(request.getMsgIcon()) .operatorId(request.getOperatorId()) .routers(request.getRouters()) + .pushTerminals(request.getPushTerminals()) .build(); } 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 new file mode 100644 index 00000000..773a1d48 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupNodeService.java @@ -0,0 +1,41 @@ +package cn.axzo.msg.center.message.service; + +import cn.axzo.msg.center.service.dto.GroupTreeNodeDTO; + +import java.util.Collection; +import java.util.Map; +import java.util.Optional; + +/** + * 消息分类结点管理 + * + * @author cold_blade + * @date 2023/10/14 + * @version 1.0 + */ +public interface MessageGroupNodeService { + + /** + * 获取分类结点(叶结点)名称的路径 + * + * @param leafGroupNodeCodes 分类结点(叶结点)的编码列表 + * @return 分类结点(叶结点)名称的路径 + */ + Map leafGroupNodeNamePaths(Collection leafGroupNodeCodes); + + /** + * 获取分类结点(叶结点)编码的路径 + * + * @param leafGroupNodeCodes 分类结点(叶结点)的编码列表 + * @return 分类结点(叶结点)编码的路径 + */ + Map leafGroupNodeCodePaths(Collection leafGroupNodeCodes); + + /** + * 根据结点编码查询结点信息 + * + * @param rootNodeCode 结点编码 + * @return 结点信息 + */ + Optional queryRootNode(String rootNodeCode); +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupService.java deleted file mode 100644 index 66dabe02..00000000 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupService.java +++ /dev/null @@ -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 queryByNodeCode(String nodeCode); - - /** - * 查询指定结点的字节的信息 - * - * @param nodeCode 指定结点编码 - * @return 子节点列表信息 - */ - List listChildren(String nodeCode); - - /** - * 模板关联分类 - * - * @param templateNode 模板编码 - * @param pathList 分类path列表 - */ - void templateGroup(String templateNode, Collection pathList); -} 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 new file mode 100644 index 00000000..2b283f46 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageGroupTreeNodeCacheService.java @@ -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 listAllRootNodes(); + + /** + * 获取指定结点所在的树的根节点 + * + * @param rootNodeCode 结点编码 + * @return 根节点 + */ + Optional queryRootNode(String rootNodeCode); + + /** + * 根据结点编码查询结点信息 + * + * @param groupNodeCode 结点编码 + * @return 结点信息 + */ + Optional queryNode(String groupNodeCode); + + /** + * 获取叶结点对应的树的路径 + * + * @param leafNodeCode 叶结点编码 + * @return 路径 + */ + Optional queryLeafNodePath(String leafNodeCode); + + /** + * 刷新缓存 + */ + void refreshCache(); +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java index f830e062..3ed0499d 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java @@ -1,5 +1,6 @@ package cn.axzo.msg.center.message.service; +import java.util.Collection; import java.util.List; /** @@ -18,4 +19,12 @@ public interface MessageTemplateGroupService { * @return 模板编码列表 */ List listMessageTemplateCodes(String groupNodeCode); + + /** + * 模板关联分类 + * + * @param templateNode 模板编码 + * @param groupNodeCodes 分类结点编码列表 + */ + void templateGroup(String templateNode, Collection groupNodeCodes); } 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 6836bb14..9175cd74 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 @@ -20,7 +20,7 @@ public interface MessageTemplateNewService { * * @param param 模板内容参数 */ - void createTemplate(MessageTemplateCreateParam param); + String createTemplate(MessageTemplateCreateParam param); /** * 通过模板编码查询模板信息 diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/PendingMessageNewService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/PendingMessageNewService.java index df132a34..be931eef 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/PendingMessageNewService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/PendingMessageNewService.java @@ -1,12 +1,11 @@ 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.param.MessageGroupNodeStatisticParam; import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam; 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.PendingMessagePushRequest; import cn.axzo.msg.center.service.pending.response.PendingMessageResponse; import cn.azxo.framework.common.model.Page; @@ -22,7 +21,7 @@ import java.util.Optional; */ public interface PendingMessageNewService { - List groupStatistic(MessageGroupNodeStatisticParam param); + List groupStatistic(MessageGroupNodeStatisticParam param); /** * 代办列表分页查询 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 new file mode 100644 index 00000000..77a9ac7a --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupNodeServiceImpl.java @@ -0,0 +1,62 @@ +package cn.axzo.msg.center.message.service.impl; + +import cn.axzo.msg.center.message.domain.dto.GroupTreeNodePathDTO; +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 lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +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 MessageGroupTreeNodeCacheService messageGroupTreeNodeCacheService; + + @Override + public Map leafGroupNodeNamePaths(Collection 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::getNodeNamePath, (cur, pre) -> cur)); + } + + @Override + public Map leafGroupNodeCodePaths(Collection 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 queryRootNode(String rootNodeCode) { + return messageGroupTreeNodeCacheService.queryRootNode(rootNodeCode); + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupServiceImpl.java deleted file mode 100644 index 0ca69898..00000000 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupServiceImpl.java +++ /dev/null @@ -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 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 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 pathList) { - if (StringUtils.isBlank(templateNode) - || CollectionUtils.isEmpty(pathList)) { - return; - } - List rows = pathList.stream() - .map(e -> { - MessageTemplateGroup group = new MessageTemplateGroup(); - group.setTemplateCode(templateNode); - group.setPath(e); - return group; - }).collect(Collectors.toList()); - messageTemplateGroupDao.saveBatch(rows); - } -} 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 new file mode 100644 index 00000000..ddb47614 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageGroupTreeNodeCacheServiceImpl.java @@ -0,0 +1,185 @@ +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.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 cn.axzo.pokonyan.config.redis.RedisUtil; +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 MessageGroupNodeDao messageGroupNodeDao; + + private List allGroupTreeRootNodesCache = Collections.emptyList(); + private List leafTreeNodePathsCache = Collections.emptyList(); + + @Override + public List listAllRootNodes() { + return getAllGroupTreeRootNodesCache(); + } + + @Override + public Optional queryRootNode(String rootNodeCode) { + if (StringUtils.isBlank(rootNodeCode)) { + log.info("rootNodeCode is blank."); + return Optional.empty(); + } + return getAllGroupTreeRootNodesCache().stream() + .filter(e -> Objects.equals(e.getNodeCode(), rootNodeCode)) + .findFirst(); + } + + @Override + public Optional queryNode(String groupNodeCode) { + if (StringUtils.isBlank(groupNodeCode)) { + log.info("groupNodeCode is blank."); + return Optional.empty(); + } + return getAllGroupTreeRootNodesCache().stream() + .map(e -> findTreeNode(e, groupNodeCode)) + .filter(Objects::nonNull) + .findFirst(); + } + + @Override + public Optional 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 void refreshCache() { + // 清除redis中的缓存标识 + RedisUtil.KeyOps.delete(CACHE_KEY); + // 清除本地缓存 + allGroupTreeRootNodesCache = Collections.emptyList(); + leafTreeNodePathsCache = Collections.emptyList(); + } + + private GroupTreeNodeDTO findTreeNode(GroupTreeNodeDTO root, String treeNodeCode) { + if (Objects.equals(root.getNodeCode(), treeNodeCode)) { + return root; + } + LinkedList queue = new LinkedList<>(root.getNodeChildren()); + while (!queue.isEmpty()) { + GroupTreeNodeDTO node = queue.pop(); + Optional childOp = node.getChild(treeNodeCode); + if (childOp.isPresent()) { + return childOp.get(); + } + queue.addAll(node.getNodeChildren()); + } + return null; + } + + private List getAllGroupTreeRootNodesCache() { + if (RedisUtil.KeyOps.hasKey(CACHE_KEY)) { + // 其它结点进行了本地缓存,但是当前服务进程还未进行缓存 + if (CollectionUtils.isEmpty(allGroupTreeRootNodesCache)) { + // 本地缓存初始化,不更新redis中的缓存标识 + initialize(false); + } + } else { + // 本地缓存初始化并更新redis中的缓存标识 + initialize(true); + } + return this.allGroupTreeRootNodesCache; + } + + private List getLeafTreeNodePathsCache() { + if (RedisUtil.KeyOps.hasKey(CACHE_KEY)) { + // 其它结点进行了本地缓存,但是当前服务进程还未进行缓存 + if (leafTreeNodePathsCache.isEmpty()) { + // 本地缓存初始化,不更新redis中的缓存标识 + initialize(false); + } + } else { + // 本地缓存初始化并更新redis中的缓存标识 + initialize(true); + } + return leafTreeNodePathsCache; + } + + private synchronized void initialize(boolean refreshCache) { + List groupNodes = listAllValidNodesFromDB(); + allGroupTreeRootNodesCache = TreeUtil.buildTree(groupNodes); + leafTreeNodePathsCache = allGroupTreeRootNodesCache.stream() + .flatMap(e -> parseRootNode(e).stream()) + .collect(Collectors.toList()); + if (refreshCache) { + RedisUtil.StringOps.setIfAbsent(CACHE_KEY, CACHE_VALUE, CACHE_KEY_TIMEOUT_DAYS, TimeUnit.DAYS); + } + } + + private List 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 parseRootNode(GroupTreeNodeDTO root) { + List paths = Lists.newArrayList(); + LinkedList pathNodeStack = new LinkedList<>(); + LinkedList 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(), pathNodeStack)); + pathNodeStack.pop(); + } else { + stack.addAll(node.getNodeChildren()); + } + } + return paths; + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java index cfcd1b34..24288fc0 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java @@ -2,14 +2,18 @@ package cn.axzo.msg.center.message.service.impl; import cn.axzo.msg.center.dal.MessageTemplateGroupDao; 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 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.stream.Collectors; /** @@ -22,6 +26,7 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupService { + private final MessageGroupNodeService messageGroupNodeService; private final MessageTemplateGroupDao messageTemplateGroupDao; @Override @@ -37,4 +42,22 @@ public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupServ .map(MessageTemplateGroup::getTemplateCode) .collect(Collectors.toList()); } + + @Override + public void templateGroup(String templateNode, Collection groupNodeCodes) { + if (StringUtils.isBlank(templateNode) + || CollectionUtils.isEmpty(groupNodeCodes)) { + return; + } + Map pathMap = messageGroupNodeService.leafGroupNodeCodePaths(groupNodeCodes); + List 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); + } } 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 5a149989..50da105e 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 @@ -1,18 +1,24 @@ 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.dal.MessageBaseTemplateDao; import cn.axzo.msg.center.domain.entity.MessageBaseTemplate; 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.param.MessageTemplateCreateParam; +import cn.axzo.msg.center.message.service.MessageTemplateGroupService; import cn.axzo.msg.center.message.service.MessageTemplateNewService; import cn.axzo.msg.center.message.service.MessageTemplateRouterService; +import cn.axzo.msg.center.utils.JSONObjectUtil; +import cn.axzo.msg.center.utils.UUIDUtil; +import cn.axzo.pokonyan.config.redis.RedisUtil; 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 org.springframework.transaction.annotation.Transactional; import java.util.Collections; import java.util.List; @@ -33,19 +39,24 @@ import java.util.stream.Collectors; @RequiredArgsConstructor 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 final MessageBaseTemplateDao messageBaseTemplateDao; + private final MessageTemplateGroupService messageTemplateGroupService; private final MessageTemplateRouterService messageTemplateRouterService; @Override - public void createTemplate(MessageTemplateCreateParam param) { - // TODO: [cold_blade] [P2] 模板与分类的关系 - messageBaseTemplateDao.save(convert(param)); - if (CollectionUtils.isNotEmpty(param.getRouters())) { - List routers = param.getRouters().stream() - .map(e -> RawMessageRouterDTO.from(e, param.getTemplateCode())) - .collect(Collectors.toList()); - messageTemplateRouterService.batchInsert(routers); - } + @Transactional(rollbackFor = Exception.class) + public String createTemplate(MessageTemplateCreateParam param) { + // 创建模板基础数据 + String templateCode = saveTemplate(param); + // 创建模板的路由数据 + saveTemplateRouters(param, templateCode); + // 创建模板与分类的关联关系数据 + messageTemplateGroupService.templateGroup(templateCode, param.getLeafGroupNodes()); + return templateCode; } @Override @@ -87,12 +98,65 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService .collect(Collectors.toList()); } + private String saveTemplate(MessageTemplateCreateParam 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.LockOps.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.LockOps.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(MessageTemplateCreateParam param) { - MessageBaseTemplate template = BeanConverter.convert(param, MessageBaseTemplate.class); + MessageBaseTemplate template = new MessageBaseTemplate(); template.setName(param.getTemplateName()); - template.setCode(param.getTemplateCode()); + template.setMsgCategory(param.getMsgCategory()); + template.setTitle(param.getTitle()); + template.setContent(param.getContent()); + template.setCardContent(JSONObjectUtil.checkAndReturn(param.getCardContent())); + template.setIcon(param.getIcon()); + template.setPushTerminal(JSONObjectUtil.toJSONString(param.getPushTerminals())); template.setCreatorId(param.getOperatorId()); template.setUpdaterId(param.getOperatorId()); return template; } + + private void saveTemplateRouters(MessageTemplateCreateParam param, String templateCode) { + if (CollectionUtils.isEmpty(param.getRouters())) { + return; + } + List routers = param.getRouters().stream() + .map(e -> RawMessageRouterDTO.from(e, templateCode)) + .collect(Collectors.toList()); + messageTemplateRouterService.batchInsert(routers); + } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java index fd9312ba..027e62d8 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java @@ -5,16 +5,17 @@ import cn.axzo.msg.center.common.exception.ServiceException; 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.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.PendingMessageDTO; 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.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.MessageTemplateNewService; 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.MessageRouterDTO; import cn.axzo.msg.center.service.dto.PersonDTO; @@ -29,6 +30,7 @@ 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.OrderFieldParseUtil; +import cn.axzo.msg.center.utils.TreeHelperUtil; import cn.axzo.msg.center.utils.UUIDUtil; import cn.azxo.framework.common.model.Page; import com.alibaba.fastjson.JSON; @@ -45,10 +47,10 @@ import org.springframework.stereotype.Service; import java.util.Collection; import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.Stack; import java.util.stream.Collectors; /** @@ -63,13 +65,13 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class PendingMessageNewServiceImpl implements PendingMessageNewService { - private final MessageGroupService messageGroupService; private final PendingMessageRecordDao pendingMessageRecordDao; + private final MessageGroupNodeService messageGroupNodeService; private final MessageTemplateNewService messageTemplateNewService; private final MessageTemplateGroupService messageTemplateGroupService; @Override - public List groupStatistic(MessageGroupNodeStatisticParam param) { + public List groupStatistic(MessageGroupNodeStatisticParam param) { return param.getGroupNodeCodes().stream() .flatMap(e -> statistic(e, param).stream()) .collect(Collectors.toList()); @@ -193,26 +195,23 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService { return pendingMessage; } - private List statistic(String rootNodeCode, MessageGroupNodeStatisticParam param) { - MessageGroupNodeDTO groupNode = messageGroupService.queryByNodeCode(rootNodeCode) + private List statistic(String rootNodeCode, MessageGroupNodeStatisticParam param) { + GroupTreeNodeDTO rootNode = messageGroupNodeService.queryRootNode(rootNodeCode) .orElseThrow(() -> new ServiceException("groupNodeCode is invalid.")); - MessageGroupNodeDTO root = groupNode; - Stack stack = new Stack<>(); - stack.push(groupNode); - List children; + MessageGroupNodeStatisticDTO rootWrapper = TreeHelperUtil.wrapper(rootNode, MessageGroupNodeStatisticDTO::of); + LinkedList stack = new LinkedList<>(); + stack.push(rootWrapper); + MessageGroupNodeStatisticDTO wrapper; while (!stack.isEmpty()) { - // TODO: [cold_blade] [P3] 优化树形分类结点的统计效率 - groupNode = stack.pop(); - statistic(groupNode, param); - children = messageGroupService.listChildren(groupNode.getNodeCode()); - groupNode.setChildren(children); - children.forEach(stack::push); + wrapper = stack.pop(); + statistic(wrapper, param); + stack.addAll(wrapper.getNodeChildren()); } // 外部传的是根节点,但是前端希望只返回根节点的字节的 - return root.getChildren(); + return rootWrapper.getNodeChildren(); } - private void statistic(MessageGroupNodeDTO groupNode, MessageGroupNodeStatisticParam param) { + private void statistic(MessageGroupNodeStatisticDTO groupNode, MessageGroupNodeStatisticParam param) { List templateCodes = messageTemplateGroupService.listMessageTemplateCodes(groupNode.getNodeCode()); if (CollectionUtils.isEmpty(templateCodes)) { groupNode.setPendingCount(0); @@ -298,6 +297,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService { } private void buildTemplateInfo(PendingMessageRecord record, MessageTemplateDTO msgTemplate, String routeParam) { + // TODO:[cold_blade] [P3] 后续其它业务对接的时候,需要明确业务扩展字段和路由参数的分界 JSONObject routerParamObj = JSONObjectUtil.parseObject(routeParam); String title = PlaceholderResolver .getDefaultResolver().resolveByMap(msgTemplate.getTitle(), routerParamObj); @@ -316,4 +316,9 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService { record.setBizCategory(param.getBizCategory()); record.setBizExtParam(JSONObjectUtil.checkAndReturn(param.getBizExtParams())); } + + private static class GroupTreeNodeWrapper { + private GroupTreeNodeDTO treeNode; + private int pendingCnt; + } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/utils/JSONObjectUtil.java b/inside-notices/src/main/java/cn/axzo/msg/center/utils/JSONObjectUtil.java index d22d57cc..a5770691 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/utils/JSONObjectUtil.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/utils/JSONObjectUtil.java @@ -4,8 +4,12 @@ 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.Objects; + /** * @author cold_blade * @date 2023/10/13 @@ -14,6 +18,8 @@ import org.apache.commons.lang3.StringUtils; @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字符串,若字符串格式不正确,抛异常 @@ -28,6 +34,20 @@ public final class JSONObjectUtil { return JSON.parseObject(str); } + 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字符串,若字符串格式不正确,抛异常 * 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 new file mode 100644 index 00000000..0a8a57e0 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/utils/TreeHelperUtil.java @@ -0,0 +1,44 @@ +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 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 , O> T wrapper(GroupTreeNodeDTO treeNode, + Function wrapperFunc) { + AssertUtil.notNull(treeNode, "treeNode is null"); + AssertUtil.notNull(wrapperFunc, "wrapperFunc is null"); + + final Map convertMap = Maps.newHashMap(); + T wrapper = wrapperFunc.apply(treeNode); + convertMap.put(treeNode, wrapper); + LinkedList treeNodeStack = new LinkedList<>(); + treeNodeStack.push(treeNode); + while (!treeNodeStack.isEmpty()) { + treeNode = treeNodeStack.pop(); + List children = treeNode.getNodeChildren(); + convertMap.get(treeNode).setNodeChildren(children.stream() + .map(e -> convertMap.put(e, wrapperFunc.apply(e))) + .collect(Collectors.toList())); + treeNodeStack.addAll(children); + } + return wrapper; + } +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/GroupNodeDTO.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/GroupNodeDTO.java deleted file mode 100644 index 256ada15..00000000 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/GroupNodeDTO.java +++ /dev/null @@ -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); - } -} 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 new file mode 100644 index 00000000..187101b5 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/GroupTreeNodeDTO.java @@ -0,0 +1,71 @@ +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 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; + +/** + * @author cold_blade + * @date 2023/10/14 + * @version 1.0 + */ +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class GroupTreeNodeDTO implements IBaseTree, 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 nodeChildren = Collections.emptyList(); + + public Optional getChild(String treeNodeCode) { + if (StringUtils.isBlank(treeNodeCode)) { + return Optional.empty(); + } + return getNodeChildren().stream() + .filter(e -> Objects.equals(e.getNodeCode(), treeNodeCode)) + .findFirst(); + } +} diff --git a/msg-center-common/src/main/java/cn/axzo/msg/center/common/enums/ServiceErrorCodeEnum.java b/msg-center-common/src/main/java/cn/axzo/msg/center/common/enums/ServiceErrorCodeEnum.java new file mode 100644 index 00000000..e84dab97 --- /dev/null +++ b/msg-center-common/src/main/java/cn/axzo/msg/center/common/enums/ServiceErrorCodeEnum.java @@ -0,0 +1,23 @@ +package cn.axzo.msg.center.common.enums; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author cold_blade + * @date 2023/10/14 + * @version 1.0 + */ +@Getter +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public enum ServiceErrorCodeEnum { + + SYSTEM_BUSY("E0002", "系统繁忙,请稍后重试"), + + PARAM_IS_INVALID("E0020", "参数异常"), + ; + + private final String code; + private final String desc; +} From 0b54e0b1b5028717b8710826d5cc88cffeb8b7f5 Mon Sep 17 00:00:00 2001 From: luofu Date: Mon, 16 Oct 2023 18:26:19 +0800 Subject: [PATCH 15/50] =?UTF-8?q?fix(REQ-1465):=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E5=8C=85=E5=BC=95=E5=85=A5=E5=AF=BC=E8=87=B4=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= 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、删除新引入的包; 2、redis相关功能自己实现 影响: 无 --- inside-notices/pom.xml | 5 - .../MessageGroupTreeNodeCacheServiceImpl.java | 2 +- .../impl/MessageTemplateNewServiceImpl.java | 2 +- .../msg/center/common/utils/RedisUtil.java | 409 ++++++++++++++++++ 4 files changed, 411 insertions(+), 7 deletions(-) create mode 100644 msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/RedisUtil.java diff --git a/inside-notices/pom.xml b/inside-notices/pom.xml index 7d64c516..fc0a36ac 100644 --- a/inside-notices/pom.xml +++ b/inside-notices/pom.xml @@ -110,11 +110,6 @@ 1.0.0-SNAPSHOT compile - - - cn.axzo.pokonyan - pokonyan - \ No newline at end of file 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 ddb47614..118de001 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 @@ -2,12 +2,12 @@ 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.utils.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 cn.axzo.pokonyan.config.redis.RedisUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; 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 50da105e..810f528e 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 @@ -2,6 +2,7 @@ package cn.axzo.msg.center.message.service.impl; import cn.axzo.basics.common.util.AssertUtil; import cn.axzo.msg.center.common.enums.ServiceErrorCodeEnum; +import cn.axzo.msg.center.common.utils.RedisUtil; import cn.axzo.msg.center.dal.MessageBaseTemplateDao; import cn.axzo.msg.center.domain.entity.MessageBaseTemplate; import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO; @@ -12,7 +13,6 @@ import cn.axzo.msg.center.message.service.MessageTemplateNewService; import cn.axzo.msg.center.message.service.MessageTemplateRouterService; import cn.axzo.msg.center.utils.JSONObjectUtil; import cn.axzo.msg.center.utils.UUIDUtil; -import cn.axzo.pokonyan.config.redis.RedisUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; diff --git a/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/RedisUtil.java b/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/RedisUtil.java new file mode 100644 index 00000000..fe650fb1 --- /dev/null +++ b/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/RedisUtil.java @@ -0,0 +1,409 @@ +package cn.axzo.msg.center.common.utils; + +import cn.hutool.extra.spring.SpringUtil; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisStringCommands; +import org.springframework.data.redis.connection.ReturnType; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.core.types.Expiration; + +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import java.util.Collection; +import java.util.concurrent.TimeUnit; + +/** + * @author cold_blade + * @date 2023/10/16 + * @version 1.0 + */ +@Slf4j +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class RedisUtil implements InitializingBean { + + /** + * 使用StringRedisTemplate(,其是RedisTemplate的定制化升级) + */ + private static StringRedisTemplate redisTemplate; + + @Override + public void afterPropertiesSet() throws Exception { + RedisUtil.redisTemplate = SpringUtil.getBean(StringRedisTemplate.class); + } + + /** + * key相关操作 + */ + public static class KeyOps { + + /** + * 根据key, 删除redis中的对应key-value + * 注: 若删除失败, 则返回false。 + * 若redis中,不存在该key, 那么返回的也是false。 + * 所以,不能因为返回了false,就认为redis中一定还存 + * 在该key对应的key-value。 + * + * @param key 要删除的key + * @return 删除是否成功 + */ + public static Boolean delete(String key) { + log.info("delete(...) => key= {}", key); + // 返回值只可能为true/false, 不可能为null + Boolean result = redisTemplate.delete(key); + log.info("delete(...) => result= {}", result); + if (result == null) { + throw new RedisOpsResultIsNullException(); + } + return result; + } + + /** + * 根据keys, 批量删除key-value + * + * 注: 若redis中,不存在对应的key, 那么计数不会加1, 即: + * redis中存在的key-value里,有名为a1、a2的key, + * 删除时,传的集合是a1、a2、a3,那么返回结果为2。 + * + * @param keys + * 要删除的key集合 + * @return 删除了的key-value个数 + */ + public static Long delete(Collection keys) { + log.info("delete(...) => keys= {}", keys); + Long count = redisTemplate.delete(keys); + log.info("delete(...) => count= {}", count); + if (count == null) { + throw new RedisOpsResultIsNullException(); + } + return count; + } + + /** + * redis中是否存在,指定key的key-value + * + * @param key 指定的key + * @return 是否存在对应的key-value + */ + public static Boolean hasKey(String key) { + log.info("hasKey(...) => key= {}", key); + Boolean result = redisTemplate.hasKey(key); + log.info("hasKey(...) => result= {}", result); + if (result == null) { + throw new RedisOpsResultIsNullException(); + } + return result; + } + + /** + * 给指定的key对应的key-value设置: 多久过时 + * + * 注:过时后,redis会自动删除对应的key-value。 + * 注:若key不存在,那么也会返回false。 + * + * @param key 指定的key + * @param timeout 过时时间 + * @param unit timeout的单位 + * @return 操作是否成功 + */ + public static Boolean expire(String key, Long timeout, TimeUnit unit) { + log.info("expire(...) => key= {}, timeout= {}, unit= {}", key, timeout, unit); + Boolean result = redisTemplate.expire(key, timeout, unit); + log.info("expire(...) => result is= {}", result); + if (result == null) { + throw new RedisOpsResultIsNullException(); + } + return result; + } + } + + /** + * string相关操作 + * + * 提示: redis中String的数据结构可参考resources/data-structure/String(字符串)的数据结构(示例一).png + * redis中String的数据结构可参考resources/data-structure/String(字符串)的数据结构(示例二).png + */ + public static class StringOps { + + /** + * 设置key-value + * 注: 若已存在相同的key, 那么原来的key-value会被丢弃。 + * + * @param key key + * @param value key对应的value + */ + public static void set(String key, String value) { + log.info("set(...) => key= {}, value= {}", key, value); + redisTemplate.opsForValue().set(key, value); + } + + /** + * 设置key-value + * 注: 若已存在相同的key, 那么原来的key-value会被丢弃 + * + * @param key key + * @param value key对应的value + * @param timeout 过时时长 + * @param unit timeout的单位 + */ + public static void setEx(String key, String value, Long timeout, TimeUnit unit) { + log.info("setEx(...) => key= {}, value= {}, timeout= {}, unit= {}", key, value, timeout, unit); + redisTemplate.opsForValue().set(key, value, timeout, unit); + } + + /** + * 若不存在key时, 向redis中添加key-value, 返回成功/失败。 + * 若存在,则不作任何操作, 返回false。 + * + * @param key key + * @param value key对应的value + * + * @return set是否成功 + */ + public static Boolean setIfAbsent(String key, String value) { + log.info("setIfAbsent(...) => key= {}, value= {}", key, value); + Boolean result = redisTemplate.opsForValue().setIfAbsent(key, value); + log.info("setIfAbsent(...) => result= {}", result); + if (result == null) { + throw new RedisOpsResultIsNullException(); + } + return result; + } + + /** + * 若不存在key时, 向redis中添加一个(具有超时时长的)key-value, 返回成功/失败。 + * 若存在,则不作任何操作, 返回false。 + * + * @param key key + * @param value key对应的value + * @param timeout 超时时长 + * @param unit timeout的单位 + * + * @return set是否成功 + */ + public static Boolean setIfAbsent(String key, String value, Long timeout, TimeUnit unit) { + log.info("setIfAbsent(...) => key= {}, value= {}, key= {}, value= {}", key, value, timeout, unit); + Boolean result = redisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit); + log.info("setIfAbsent(...) => result= {}", result); + if (result == null) { + throw new RedisOpsResultIsNullException(); + } + return result; + } + + /** + * 根据key,获取到对应的value值 + * 注: 若key不存在, 则返回null。 + * + * @param key key-value对应的key + * @return 该key对应的值。 + */ + public static String get(String key) { + log.info("get(...) => key= {}", key); + String result = redisTemplate.opsForValue().get(key); + log.info("get(...) => result= {} ", result); + return result; + } + } + + /** + * redis分布式锁. + * + * 使用方式(示例): + * Boolean flag = false; + * String lockName = "sichuan:mianyang:fucheng:ds"; + * String lockValue = UUID.randomUUID().toString(); + * try { + * // 非阻塞获取(锁的最大存活时间采用默认值) + * flag = RedisUtil.LockOps.getLock(lockName, lockValue); + * // 非阻塞获取e.g. + * flag = RedisUtil.LockOps.getLock(lockName, lockValue, 3, TimeUnit.SECONDS); + * // 阻塞获取(锁的最大存活时间采用默认值) + * flag = RedisUtil.LockOps.getLockUntilTimeout(lockName, lockValue, 2000); + * // 阻塞获取e.g. + * flag = RedisUtil.LockOps.getLockUntilTimeout(lockName, lockValue, 2, TimeUnit.SECONDS, 2000); + * // your logic + * // ... + * } finally { + * if (flag) { + * RedisUtil.LockOps.releaseLock(lockName, lockValue); + * } + * } + */ + public static class LockOps { + + /** lua脚本, 保证 释放锁脚本 的原子性(以避免, 并发场景下, 释放了别人的锁) */ + private static final String RELEASE_LOCK_LUA; + + /** 分布式锁默认(最大)存活时长 */ + public static final long DEFAULT_LOCK_TIMEOUT = 3; + + /** DEFAULT_LOCK_TIMEOUT的单位 */ + public static final TimeUnit DEFAULT_TIMEOUT_UNIT = TimeUnit.SECONDS; + + static { + // 不论lua中0是否代表失败; 对于java的Boolean而言, 返回0, 则会被解析为false + RELEASE_LOCK_LUA = "if redis.call('get',KEYS[1]) == ARGV[1] " + + "then " + + " return redis.call('del',KEYS[1]) " + + "else " + + " return 0 " + + "end "; + } + + /** + * 获取(分布式)锁. + * 注: 获取结果是即时返回的、是非阻塞的。 + * + * @see LockOps#getLock(String, String, Long, TimeUnit) + */ + public static Boolean getLock(final String key, final String value) { + return getLock(key, value, DEFAULT_LOCK_TIMEOUT, DEFAULT_TIMEOUT_UNIT); + } + + /** + * 获取(分布式)锁。 + * 若成功, 则直接返回; + * 若失败, 则进行重试, 直到成功 或 超时为止。 + * 注: 获取结果是阻塞的, 要么成功, 要么超时, 才返回。 + * + * @param retryTimeoutLimit 重试的超时时长(ms) + * 其它参数可详见: + * @see LockOps#getLock(String, String, Long, TimeUnit) + * + * @return 是否成功 + */ + public static Boolean getLockUntilTimeout(final String key, final String value, final Long retryTimeoutLimit) { + return getLockUntilTimeout(key, value, DEFAULT_LOCK_TIMEOUT, DEFAULT_TIMEOUT_UNIT, + retryTimeoutLimit); + } + + /** + * 获取(分布式)锁。 + * 若成功, 则直接返回; + * 若失败, 则进行重试, 直到成功 或 超时为止。 + * 注: 获取结果是阻塞的, 要么成功, 要么超时, 才返回。 + * + * @param retryTimeoutLimit 重试的超时时长(ms) + * 其它参数可详见: + * @see LockOps#getLock(String, String, Long, TimeUnit, Boolean) + * + * @return 是否成功 + */ + public static Boolean getLockUntilTimeout(final String key, final String value, + final Long timeout, final TimeUnit unit, + final Long retryTimeoutLimit) { + log.info("getLockUntilTimeout(...) => key= {}, value= {}, timeout= {}, unit= {}, " + + "retryTimeoutLimit= {}ms", key, value, timeout, unit, retryTimeoutLimit); + long startTime = Instant.now().toEpochMilli(); + long now = startTime; + do { + try { + Boolean alreadyGotLock = getLock(key, value, timeout, unit, false); + if (alreadyGotLock) { + log.info("getLockUntilTimeout(...) => consume time= {}ms, result= true", now - startTime); + return true; + } + } catch (Exception e) { + log.warn("getLockUntilTimeout(...) => try to get lock failure!", e); + } + now = Instant.now().toEpochMilli(); + } while (now < startTime + retryTimeoutLimit); + log.info("getLockUntilTimeout(...) => consume time= {}ms, result= false", now - startTime); + return false; + } + + /** + * 获取(分布式)锁 + * 注: 获取结果是即时返回的、是非阻塞的。 + * + * @see LockOps#getLock(String, String, Long, TimeUnit, Boolean) + */ + public static Boolean getLock(final String key, final String value, final Long timeout, final TimeUnit unit) { + return getLock(key, value, timeout, unit, true); + } + + /** + * 获取(分布式)锁 + * 注: 获取结果是即时返回的、是非阻塞的。 + * + * @param key 锁名 + * @param value + * 锁名对应的value + * 注: value一般采用全局唯一的值, 如: requestId、uuid等。 + * 这样, 释放锁的时候, 可以再次验证value值, + * 保证自己上的锁只能被自己释放, 而不会被别人释放。 + * 当然, 如果锁超时时, 会被redis自动删除释放。 + * @param timeout + * 锁的(最大)存活时长 + * 注: 一般的, 获取锁与释放锁 都是成对使用的, 在锁在达到(最大)存活时长之前,都会被主动释放。 + * 但是在某些情况下(如:程序获取锁后,释放锁前,崩了),锁得不到释放, 这时就需要等锁过 + * 了(最大)存活时长后,被redis自动删除清理了。这样就能保证redis中不会留下死数据。 + * @param unit timeout的单位 + * @param recordLog 是否记录日志 + * + * @return 是否成功 + */ + public static Boolean getLock(final String key, final String value, + final Long timeout, final TimeUnit unit, + Boolean recordLog) { + if (recordLog) { + log.info("getLock(...) => key= {}, value= {}, timeout= {}, unit= {}, recordLog= {}", + key, value, timeout, unit, recordLog); + } + Boolean result = redisTemplate.execute((RedisConnection connection) -> + connection.set(key.getBytes(StandardCharsets.UTF_8), + value.getBytes(StandardCharsets.UTF_8), + Expiration.seconds(unit.toSeconds(timeout)), + RedisStringCommands.SetOption.SET_IF_ABSENT) + ); + if (recordLog) { + log.info("getLock(...) => result= {}", result); + } + if (result == null) { + throw new RedisOpsResultIsNullException(); + } + return result; + } + + /** + * 释放(分布式)锁 + * 注: 此方式能(通过value的唯一性)保证: 自己加的锁, 只能被自己释放。 + * 注: 锁超时时, 也会被redis自动删除释放。 + * + * @param key 锁名 + * @param value 锁名对应的value + * + * @return 释放锁是否成功 + */ + public static Boolean releaseLock(final String key, final String value) { + log.info("releaseLock(...) => key= {}, lockValue= {}", key, value); + Boolean result = redisTemplate.execute((RedisConnection connection) -> + connection.eval(RELEASE_LOCK_LUA.getBytes(), + ReturnType.BOOLEAN, 1, + key.getBytes(StandardCharsets.UTF_8), value.getBytes(StandardCharsets.UTF_8)) + ); + log.info("releaseLock(...) => result= {}", result); + if (result == null) { + throw new RedisOpsResultIsNullException(); + } + return result; + } + } + + public static class RedisOpsResultIsNullException extends NullPointerException { + + private static final long serialVersionUID = 7727166544003942512L; + + public RedisOpsResultIsNullException() { + super(); + } + + public RedisOpsResultIsNullException(String message) { + super(message); + } + } +} From 4cbc8a127d7006542e5ed93525d20618ef161e11 Mon Sep 17 00:00:00 2001 From: luofu Date: Mon, 16 Oct 2023 18:38:39 +0800 Subject: [PATCH 16/50] =?UTF-8?q?feat(REQ-1465):=20=E5=BE=85=E5=8A=9E?= =?UTF-8?q?=E5=88=86=E7=B1=BB=E5=85=B3=E8=81=94=E5=85=B3=E7=B3=BB=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E6=9F=A5=E8=AF=A2=E6=8E=A5=E5=8F=A3=E5=85=A5=E5=8F=82?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= 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、待办分类关联关系分页查询接口入参新增分页相关的数据属性 影响: 无 --- .../MessageTemplateGroupRelationClient.java | 6 ++-- ...geTemplateGroupRelationClientFallback.java | 6 ++-- ...ssageTemplateGroupRelationPageRequest.java | 32 +++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationPageRequest.java diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java index 8cbf7ab5..634b843f 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java @@ -2,6 +2,7 @@ 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; @@ -30,11 +31,12 @@ public interface MessageTemplateGroupRelationClient { /** * 分页查询分类下关联的模板列表 * - * @param nodeCode 分类结点的编码 + * @param request 分类结点的编码及分页参数 * @return 模板列表 */ @PostMapping(value = "/message/template/group-relation/page", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse> page(@RequestParam("nodeCode") String nodeCode); + CommonResponse> page( + @RequestBody @Valid MessageTemplateGroupRelationPageRequest request); /** * 变更模板与分类的关联关系 diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageTemplateGroupRelationClientFallback.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageTemplateGroupRelationClientFallback.java index 39915a7e..e4a07054 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageTemplateGroupRelationClientFallback.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageTemplateGroupRelationClientFallback.java @@ -2,6 +2,7 @@ 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; @@ -21,8 +22,9 @@ import java.util.List; public class MessageTemplateGroupRelationClientFallback implements MessageTemplateGroupRelationClient { @Override - public CommonResponse> page(String nodeCode) { - log.error("fall back while page querying message template group relation. nodeCode:{}", nodeCode); + public CommonResponse> 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"); } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationPageRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationPageRequest.java new file mode 100644 index 00000000..200bd48f --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationPageRequest.java @@ -0,0 +1,32 @@ +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; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} From 23014760bf0b9b224c1a2a0f196ec4d70fe167be Mon Sep 17 00:00:00 2001 From: luofu Date: Tue, 17 Oct 2023 10:26:02 +0800 Subject: [PATCH 17/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E5=88=86=E9=A1=B5=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、消息模板分页查询接口实现 影响: 无 --- .../domain/dto/GroupTreeNodePathDTO.java | 10 +++ .../service/MessageGroupNodeService.java | 4 +- .../service/MessageTemplateGroupService.java | 9 +++ .../service/MessageTemplateNewService.java | 11 +++ .../impl/MessageGroupNodeServiceImpl.java | 7 +- .../impl/MessageTemplateGroupServiceImpl.java | 14 ++++ .../impl/MessageTemplateNewServiceImpl.java | 68 +++++++++++++++++++ .../request/MessageTemplatePageRequest.java | 3 +- .../response/MessageTemplatePageResponse.java | 3 +- .../center/common/utils/PageHelperUtil.java | 20 ++++++ .../domain/entity/MessageBaseTemplate.java | 7 ++ 11 files changed, 149 insertions(+), 7 deletions(-) create mode 100644 msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/PageHelperUtil.java diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GroupTreeNodePathDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GroupTreeNodePathDTO.java index ad2d43b4..3f0318a6 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GroupTreeNodePathDTO.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GroupTreeNodePathDTO.java @@ -6,6 +6,7 @@ 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; @@ -40,6 +41,15 @@ public class GroupTreeNodePathDTO implements Serializable { */ 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 nodes) { String nodeNamePath = formatPath(GroupTreeNodeDTO::getNodeName, nodes, NODE_NAME_PATH_SPLITER); String nodeCodePath = formatPath(GroupTreeNodeDTO::getNodeCode, nodes, NODE_CODE_PATH_SPLITER); 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 773a1d48..427db337 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 @@ -18,10 +18,10 @@ public interface MessageGroupNodeService { /** * 获取分类结点(叶结点)名称的路径 * - * @param leafGroupNodeCodes 分类结点(叶结点)的编码列表 + * @param groupNodeCodePaths 分类结点(叶结点)的编码列表 * @return 分类结点(叶结点)名称的路径 */ - Map leafGroupNodeNamePaths(Collection leafGroupNodeCodes); + Map groupNodeNamePaths(Collection groupNodeCodePaths); /** * 获取分类结点(叶结点)编码的路径 diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java index 3ed0499d..b966013e 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java @@ -2,6 +2,7 @@ package cn.axzo.msg.center.message.service; import java.util.Collection; import java.util.List; +import java.util.Map; /** * 消息模板分类管理 @@ -27,4 +28,12 @@ public interface MessageTemplateGroupService { * @param groupNodeCodes 分类结点编码列表 */ void templateGroup(String templateNode, Collection groupNodeCodes); + + /** + * 通过消息模板编码查询其关联的分类的path + * + * @param templateCodes 消息模板编码集合 + * @return 模板编码与分类的path列表的映射关系 + */ + Map> listMessageTemplateGroupPaths(Collection templateCodes); } 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 9175cd74..71029e7b 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 @@ -2,6 +2,9 @@ package cn.axzo.msg.center.message.service; import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO; import cn.axzo.msg.center.message.domain.param.MessageTemplateCreateParam; +import cn.axzo.msg.center.service.template.request.MessageTemplatePageRequest; +import cn.axzo.msg.center.service.template.response.MessageTemplatePageResponse; +import cn.azxo.framework.common.model.Page; import java.util.List; import java.util.Optional; @@ -37,4 +40,12 @@ public interface MessageTemplateNewService { * @return 模板信息 */ List listByTemplateCodes(List msgTemplateCodes); + + /** + * 分页查询模板数据 + * + * @param request 分页请求参数 + * @return 模板数据列表 + */ + Page page(MessageTemplatePageRequest request); } 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 77a9ac7a..78931a84 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 @@ -28,12 +28,13 @@ public class MessageGroupNodeServiceImpl implements MessageGroupNodeService { private final MessageGroupTreeNodeCacheService messageGroupTreeNodeCacheService; @Override - public Map leafGroupNodeNamePaths(Collection leafGroupNodeCodes) { - if (CollectionUtils.isEmpty(leafGroupNodeCodes)) { + public Map groupNodeNamePaths(Collection groupNodeCodePaths) { + if (CollectionUtils.isEmpty(groupNodeCodePaths)) { log.info("leafGroupNodeCodes is empty."); return Collections.emptyMap(); } - return leafGroupNodeCodes.stream() + return groupNodeCodePaths.stream() + .map(GroupTreeNodePathDTO::parseLeafNodeCode) .map(messageGroupTreeNodeCacheService::queryLeafNodePath) .filter(Optional::isPresent) .map(Optional::get) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java index 24288fc0..b733406c 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java @@ -1,5 +1,6 @@ package cn.axzo.msg.center.message.service.impl; +import cn.axzo.msg.center.common.enums.TableIsDeleteEnum; import cn.axzo.msg.center.dal.MessageTemplateGroupDao; import cn.axzo.msg.center.domain.entity.MessageTemplateGroup; import cn.axzo.msg.center.message.service.MessageGroupNodeService; @@ -60,4 +61,17 @@ public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupServ }).collect(Collectors.toList()); messageTemplateGroupDao.saveBatch(rows); } + + @Override + public Map> listMessageTemplateGroupPaths(Collection 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()))); + } } 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 810f528e..d34241fd 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 @@ -2,17 +2,24 @@ package cn.axzo.msg.center.message.service.impl; import cn.axzo.basics.common.util.AssertUtil; import cn.axzo.msg.center.common.enums.ServiceErrorCodeEnum; +import cn.axzo.msg.center.common.utils.PageHelperUtil; import cn.axzo.msg.center.common.utils.RedisUtil; import cn.axzo.msg.center.dal.MessageBaseTemplateDao; import cn.axzo.msg.center.domain.entity.MessageBaseTemplate; 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.param.MessageTemplateCreateParam; +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.MessageTemplateRouterService; +import cn.axzo.msg.center.service.template.request.MessageTemplatePageRequest; +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.baomidou.mybatisplus.core.metadata.IPage; +import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -20,6 +27,7 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -44,6 +52,7 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService private static final int RETRY_CNT_MAX = 3; private final MessageBaseTemplateDao messageBaseTemplateDao; + private final MessageGroupNodeService messageGroupNodeService; private final MessageTemplateGroupService messageTemplateGroupService; private final MessageTemplateRouterService messageTemplateRouterService; @@ -98,6 +107,48 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService .collect(Collectors.toList()); } + @Override + public Page page(MessageTemplatePageRequest request) { + List 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 pageRequest = request.toPage(); + IPage 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> groupNodePaths = messageTemplateGroupService + .listMessageTemplateGroupPaths(templateCodes); + Map codeNameMap = messageGroupNodeService.groupNodeNamePaths(groupNodePaths.values().stream() + .flatMap(Collection::stream).collect(Collectors.toList())); + List records = result.getRecords().stream() + .map(e -> convert(e, groupNodePaths, codeNameMap)) + .collect(Collectors.toList()); + return Page.toPage(request.getPage(), request.getPageSize(), result.getTotal(), records); + } + private String saveTemplate(MessageTemplateCreateParam param) { String templateCode = UUIDUtil.uuidString(); MessageBaseTemplate template = convert(param); @@ -150,6 +201,23 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService return template; } + private MessageTemplatePageResponse convert(MessageBaseTemplate record, Map> groupNodePaths, + Map 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 nodeNamePaths = groupNodePaths.getOrDefault(record.getCode(), Collections.emptyList()).stream() + .filter(codeNameMap::containsKey) + .map(codeNameMap::get) + .collect(Collectors.toList()); + response.setGroupNodeNamePaths(nodeNamePaths); + return response; + } + private void saveTemplateRouters(MessageTemplateCreateParam param, String templateCode) { if (CollectionUtils.isEmpty(param.getRouters())) { return; diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplatePageRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplatePageRequest.java index b2f7cc42..0532e639 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplatePageRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplatePageRequest.java @@ -1,5 +1,6 @@ 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; @@ -15,7 +16,7 @@ import java.io.Serializable; */ @Setter @Getter -public class MessageTemplatePageRequest implements Serializable { +public class MessageTemplatePageRequest extends PageRequest implements Serializable { private static final long serialVersionUID = 3501567663122621175L; diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplatePageResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplatePageResponse.java index 8f7df96b..ef0806c2 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplatePageResponse.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplatePageResponse.java @@ -7,6 +7,7 @@ import lombok.Getter; import lombok.Setter; import java.io.Serializable; +import java.util.List; /** * @author cold_blade @@ -44,7 +45,7 @@ public class MessageTemplatePageResponse implements Serializable { /** * 分类路径,eg:发薪管理/发薪提醒/提醒工人 */ - private String groupNodePath; + private List groupNodeNamePaths; /** * 模板状态 * ENABLE: 启用 diff --git a/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/PageHelperUtil.java b/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/PageHelperUtil.java new file mode 100644 index 00000000..4d3a6b79 --- /dev/null +++ b/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/PageHelperUtil.java @@ -0,0 +1,20 @@ +package cn.axzo.msg.center.common.utils; + +import cn.azxo.framework.common.model.Page; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +import java.util.Collections; + +/** + * @author cold_blade + * @date 2023/10/16 + * @version 1.0 + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class PageHelperUtil { + + public static Page emptyPage(Long pageNum, Long pageSize) { + return Page.toPage(pageNum, pageSize, 0L, Collections.emptyList()); + } +} diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageBaseTemplate.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageBaseTemplate.java index a608450f..2c425cf7 100644 --- a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageBaseTemplate.java +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageBaseTemplate.java @@ -2,6 +2,7 @@ package cn.axzo.msg.center.domain.entity; import cn.axzo.msg.center.domain.persistence.BaseEntity; import cn.axzo.msg.center.service.enums.MessageCategoryEnum; +import cn.axzo.msg.center.service.enums.StatusEnum; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Getter; @@ -51,6 +52,12 @@ public class MessageBaseTemplate extends BaseEntity impleme * 模板icon */ private String icon; + /** + * 模板状态 + * ENABLE: 启用 + * DISABLE: 禁用 + */ + private StatusEnum status; /** * 推送终端配置 JSON字串 */ From 5a8fe60c208e09d0f44ed10db7fc6fd399bd0f68 Mon Sep 17 00:00:00 2001 From: luofu Date: Tue, 17 Oct 2023 12:35:01 +0800 Subject: [PATCH 18/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E5=88=86=E9=A1=B5=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 | 3 +- .../MessageGroupTreeNodeCacheServiceImpl.java | 11 +-- .../impl/MessageTemplateNewServiceImpl.java | 7 +- .../common/{utils => redis}/RedisUtil.java | 90 +++++++++---------- .../axzo/msg/center/RedisConfiguration.java | 50 +++++++++++ 5 files changed, 106 insertions(+), 55 deletions(-) rename msg-center-common/src/main/java/cn/axzo/msg/center/common/{utils => redis}/RedisUtil.java (84%) create mode 100644 start/src/main/java/cn/axzo/msg/center/RedisConfiguration.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 9fdc269d..789b0af5 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 @@ -47,8 +47,7 @@ public class MessageTemplateController implements MessageTemplateClient { @Override public CommonResponse> page(MessageTemplatePageRequest request) { - // TODO:[cold_blade] [P0] page query template - return null; + return CommonResponse.success(messageTemplateNewService.page(request)); } @Override 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 118de001..b9cdd89e 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 @@ -2,7 +2,7 @@ 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.utils.RedisUtil; +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; @@ -37,6 +37,7 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod 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 allGroupTreeRootNodesCache = Collections.emptyList(); @@ -84,7 +85,7 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod @Override public void refreshCache() { // 清除redis中的缓存标识 - RedisUtil.KeyOps.delete(CACHE_KEY); + redisUtil.getKeyOps().delete(CACHE_KEY); // 清除本地缓存 allGroupTreeRootNodesCache = Collections.emptyList(); leafTreeNodePathsCache = Collections.emptyList(); @@ -107,7 +108,7 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod } private List getAllGroupTreeRootNodesCache() { - if (RedisUtil.KeyOps.hasKey(CACHE_KEY)) { + if (redisUtil.getKeyOps().hasKey(CACHE_KEY)) { // 其它结点进行了本地缓存,但是当前服务进程还未进行缓存 if (CollectionUtils.isEmpty(allGroupTreeRootNodesCache)) { // 本地缓存初始化,不更新redis中的缓存标识 @@ -121,7 +122,7 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod } private List getLeafTreeNodePathsCache() { - if (RedisUtil.KeyOps.hasKey(CACHE_KEY)) { + if (redisUtil.getKeyOps().hasKey(CACHE_KEY)) { // 其它结点进行了本地缓存,但是当前服务进程还未进行缓存 if (leafTreeNodePathsCache.isEmpty()) { // 本地缓存初始化,不更新redis中的缓存标识 @@ -141,7 +142,7 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod .flatMap(e -> parseRootNode(e).stream()) .collect(Collectors.toList()); if (refreshCache) { - RedisUtil.StringOps.setIfAbsent(CACHE_KEY, CACHE_VALUE, CACHE_KEY_TIMEOUT_DAYS, TimeUnit.DAYS); + redisUtil.getStringOps().setIfAbsent(CACHE_KEY, CACHE_VALUE, CACHE_KEY_TIMEOUT_DAYS, TimeUnit.DAYS); } } 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 d34241fd..e6a1d08f 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 @@ -2,8 +2,8 @@ package cn.axzo.msg.center.message.service.impl; import cn.axzo.basics.common.util.AssertUtil; import cn.axzo.msg.center.common.enums.ServiceErrorCodeEnum; +import cn.axzo.msg.center.common.redis.RedisUtil; import cn.axzo.msg.center.common.utils.PageHelperUtil; -import cn.axzo.msg.center.common.utils.RedisUtil; import cn.axzo.msg.center.dal.MessageBaseTemplateDao; import cn.axzo.msg.center.domain.entity.MessageBaseTemplate; import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO; @@ -51,6 +51,7 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService private static final long TRY_LOCK_TIMEOUT_MILLS = 1000; private static final int RETRY_CNT_MAX = 3; + private final RedisUtil redisUtil; private final MessageBaseTemplateDao messageBaseTemplateDao; private final MessageGroupNodeService messageGroupNodeService; private final MessageTemplateGroupService messageTemplateGroupService; @@ -167,7 +168,7 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService String requestId = UUIDUtil.uuidRawString(); try { String opKey = String.format(SAVE_TEMPLATE_MUTEX_KEY, templateCode); - boolean lockResult = RedisUtil.LockOps.getLockUntilTimeout(opKey, requestId, TRY_LOCK_TIMEOUT_MILLS); + boolean lockResult = redisUtil.getLockOps().getLockUntilTimeout(opKey, requestId, TRY_LOCK_TIMEOUT_MILLS); AssertUtil.isTrue(lockResult, ServiceErrorCodeEnum.SYSTEM_BUSY.getDesc()); if (isTemplateExist(templateCode)) { return false; @@ -176,7 +177,7 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService messageBaseTemplateDao.save(template); return true; } finally { - RedisUtil.LockOps.releaseLock(SAVE_TEMPLATE_MUTEX_KEY, requestId); + redisUtil.getLockOps().releaseLock(SAVE_TEMPLATE_MUTEX_KEY, requestId); } } diff --git a/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/RedisUtil.java b/msg-center-common/src/main/java/cn/axzo/msg/center/common/redis/RedisUtil.java similarity index 84% rename from msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/RedisUtil.java rename to msg-center-common/src/main/java/cn/axzo/msg/center/common/redis/RedisUtil.java index fe650fb1..ccc5b449 100644 --- a/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/RedisUtil.java +++ b/msg-center-common/src/main/java/cn/axzo/msg/center/common/redis/RedisUtil.java @@ -1,15 +1,16 @@ -package cn.axzo.msg.center.common.utils; +package cn.axzo.msg.center.common.redis; -import cn.hutool.extra.spring.SpringUtil; import lombok.AccessLevel; +import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.InitializingBean; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisStringCommands; import org.springframework.data.redis.connection.ReturnType; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.types.Expiration; +import org.springframework.stereotype.Component; import java.nio.charset.StandardCharsets; import java.time.Instant; @@ -22,23 +23,25 @@ import java.util.concurrent.TimeUnit; * @version 1.0 */ @Slf4j -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class RedisUtil implements InitializingBean { +@Getter +@Component +@RequiredArgsConstructor +public class RedisUtil { /** * 使用StringRedisTemplate(,其是RedisTemplate的定制化升级) */ - private static StringRedisTemplate redisTemplate; + private final StringRedisTemplate redisTemplate; - @Override - public void afterPropertiesSet() throws Exception { - RedisUtil.redisTemplate = SpringUtil.getBean(StringRedisTemplate.class); - } + private final KeyOps keyOps = new KeyOps(); + private final StringOps stringOps = new StringOps(); + private final LockOps lockOps = new LockOps(); /** * key相关操作 */ - public static class KeyOps { + @NoArgsConstructor(access = AccessLevel.PRIVATE) + public class KeyOps { /** * 根据key, 删除redis中的对应key-value @@ -50,7 +53,7 @@ public final class RedisUtil implements InitializingBean { * @param key 要删除的key * @return 删除是否成功 */ - public static Boolean delete(String key) { + public Boolean delete(String key) { log.info("delete(...) => key= {}", key); // 返回值只可能为true/false, 不可能为null Boolean result = redisTemplate.delete(key); @@ -72,7 +75,7 @@ public final class RedisUtil implements InitializingBean { * 要删除的key集合 * @return 删除了的key-value个数 */ - public static Long delete(Collection keys) { + public Long delete(Collection keys) { log.info("delete(...) => keys= {}", keys); Long count = redisTemplate.delete(keys); log.info("delete(...) => count= {}", count); @@ -88,7 +91,7 @@ public final class RedisUtil implements InitializingBean { * @param key 指定的key * @return 是否存在对应的key-value */ - public static Boolean hasKey(String key) { + public Boolean hasKey(String key) { log.info("hasKey(...) => key= {}", key); Boolean result = redisTemplate.hasKey(key); log.info("hasKey(...) => result= {}", result); @@ -109,7 +112,7 @@ public final class RedisUtil implements InitializingBean { * @param unit timeout的单位 * @return 操作是否成功 */ - public static Boolean expire(String key, Long timeout, TimeUnit unit) { + public Boolean expire(String key, Long timeout, TimeUnit unit) { log.info("expire(...) => key= {}, timeout= {}, unit= {}", key, timeout, unit); Boolean result = redisTemplate.expire(key, timeout, unit); log.info("expire(...) => result is= {}", result); @@ -126,7 +129,8 @@ public final class RedisUtil implements InitializingBean { * 提示: redis中String的数据结构可参考resources/data-structure/String(字符串)的数据结构(示例一).png * redis中String的数据结构可参考resources/data-structure/String(字符串)的数据结构(示例二).png */ - public static class StringOps { + @NoArgsConstructor(access = AccessLevel.PRIVATE) + public class StringOps { /** * 设置key-value @@ -135,7 +139,7 @@ public final class RedisUtil implements InitializingBean { * @param key key * @param value key对应的value */ - public static void set(String key, String value) { + public void set(String key, String value) { log.info("set(...) => key= {}, value= {}", key, value); redisTemplate.opsForValue().set(key, value); } @@ -149,7 +153,7 @@ public final class RedisUtil implements InitializingBean { * @param timeout 过时时长 * @param unit timeout的单位 */ - public static void setEx(String key, String value, Long timeout, TimeUnit unit) { + public void setEx(String key, String value, Long timeout, TimeUnit unit) { log.info("setEx(...) => key= {}, value= {}, timeout= {}, unit= {}", key, value, timeout, unit); redisTemplate.opsForValue().set(key, value, timeout, unit); } @@ -163,7 +167,7 @@ public final class RedisUtil implements InitializingBean { * * @return set是否成功 */ - public static Boolean setIfAbsent(String key, String value) { + public Boolean setIfAbsent(String key, String value) { log.info("setIfAbsent(...) => key= {}, value= {}", key, value); Boolean result = redisTemplate.opsForValue().setIfAbsent(key, value); log.info("setIfAbsent(...) => result= {}", result); @@ -184,7 +188,7 @@ public final class RedisUtil implements InitializingBean { * * @return set是否成功 */ - public static Boolean setIfAbsent(String key, String value, Long timeout, TimeUnit unit) { + public Boolean setIfAbsent(String key, String value, Long timeout, TimeUnit unit) { log.info("setIfAbsent(...) => key= {}, value= {}, key= {}, value= {}", key, value, timeout, unit); Boolean result = redisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit); log.info("setIfAbsent(...) => result= {}", result); @@ -201,7 +205,7 @@ public final class RedisUtil implements InitializingBean { * @param key key-value对应的key * @return 该key对应的值。 */ - public static String get(String key) { + public String get(String key) { log.info("get(...) => key= {}", key); String result = redisTemplate.opsForValue().get(key); log.info("get(...) => result= {} ", result); @@ -233,26 +237,22 @@ public final class RedisUtil implements InitializingBean { * } * } */ - public static class LockOps { + @NoArgsConstructor(access = AccessLevel.PRIVATE) + public class LockOps { /** lua脚本, 保证 释放锁脚本 的原子性(以避免, 并发场景下, 释放了别人的锁) */ - private static final String RELEASE_LOCK_LUA; + private final String RELEASE_LOCK_LUA = "if redis.call('get',KEYS[1]) == ARGV[1] " + + "then " + + " return redis.call('del',KEYS[1]) " + + "else " + + " return 0 " + + "end "; /** 分布式锁默认(最大)存活时长 */ - public static final long DEFAULT_LOCK_TIMEOUT = 3; + public final long DEFAULT_LOCK_TIMEOUT = 3; /** DEFAULT_LOCK_TIMEOUT的单位 */ - public static final TimeUnit DEFAULT_TIMEOUT_UNIT = TimeUnit.SECONDS; - - static { - // 不论lua中0是否代表失败; 对于java的Boolean而言, 返回0, 则会被解析为false - RELEASE_LOCK_LUA = "if redis.call('get',KEYS[1]) == ARGV[1] " - + "then " - + " return redis.call('del',KEYS[1]) " - + "else " - + " return 0 " - + "end "; - } + public final TimeUnit DEFAULT_TIMEOUT_UNIT = TimeUnit.SECONDS; /** * 获取(分布式)锁. @@ -260,7 +260,7 @@ public final class RedisUtil implements InitializingBean { * * @see LockOps#getLock(String, String, Long, TimeUnit) */ - public static Boolean getLock(final String key, final String value) { + public Boolean getLock(final String key, final String value) { return getLock(key, value, DEFAULT_LOCK_TIMEOUT, DEFAULT_TIMEOUT_UNIT); } @@ -276,7 +276,7 @@ public final class RedisUtil implements InitializingBean { * * @return 是否成功 */ - public static Boolean getLockUntilTimeout(final String key, final String value, final Long retryTimeoutLimit) { + public Boolean getLockUntilTimeout(final String key, final String value, final Long retryTimeoutLimit) { return getLockUntilTimeout(key, value, DEFAULT_LOCK_TIMEOUT, DEFAULT_TIMEOUT_UNIT, retryTimeoutLimit); } @@ -293,9 +293,9 @@ public final class RedisUtil implements InitializingBean { * * @return 是否成功 */ - public static Boolean getLockUntilTimeout(final String key, final String value, - final Long timeout, final TimeUnit unit, - final Long retryTimeoutLimit) { + public Boolean getLockUntilTimeout(final String key, final String value, + final Long timeout, final TimeUnit unit, + final Long retryTimeoutLimit) { log.info("getLockUntilTimeout(...) => key= {}, value= {}, timeout= {}, unit= {}, " + "retryTimeoutLimit= {}ms", key, value, timeout, unit, retryTimeoutLimit); long startTime = Instant.now().toEpochMilli(); @@ -322,7 +322,7 @@ public final class RedisUtil implements InitializingBean { * * @see LockOps#getLock(String, String, Long, TimeUnit, Boolean) */ - public static Boolean getLock(final String key, final String value, final Long timeout, final TimeUnit unit) { + public Boolean getLock(final String key, final String value, final Long timeout, final TimeUnit unit) { return getLock(key, value, timeout, unit, true); } @@ -347,9 +347,9 @@ public final class RedisUtil implements InitializingBean { * * @return 是否成功 */ - public static Boolean getLock(final String key, final String value, - final Long timeout, final TimeUnit unit, - Boolean recordLog) { + public Boolean getLock(final String key, final String value, + final Long timeout, final TimeUnit unit, + Boolean recordLog) { if (recordLog) { log.info("getLock(...) => key= {}, value= {}, timeout= {}, unit= {}, recordLog= {}", key, value, timeout, unit, recordLog); @@ -379,7 +379,7 @@ public final class RedisUtil implements InitializingBean { * * @return 释放锁是否成功 */ - public static Boolean releaseLock(final String key, final String value) { + public Boolean releaseLock(final String key, final String value) { log.info("releaseLock(...) => key= {}, lockValue= {}", key, value); Boolean result = redisTemplate.execute((RedisConnection connection) -> connection.eval(RELEASE_LOCK_LUA.getBytes(), diff --git a/start/src/main/java/cn/axzo/msg/center/RedisConfiguration.java b/start/src/main/java/cn/axzo/msg/center/RedisConfiguration.java new file mode 100644 index 00000000..453472d7 --- /dev/null +++ b/start/src/main/java/cn/axzo/msg/center/RedisConfiguration.java @@ -0,0 +1,50 @@ +package cn.axzo.msg.center; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * @author cold_blade + * @date 2023/10/17 + * @version 1.0 + */ +@Configuration +public class RedisConfiguration { + + @Bean + public RedisSerializer redisKeySerializer() { + return new StringRedisSerializer(); + } + + @Bean + public RedisSerializer redisValueSerializer() { + return new StringRedisSerializer(); + } + + /** + * RedisTemplate配置 + */ + @Bean + public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory, + RedisSerializer redisKeySerializer, + RedisSerializer redisValueSerializer) { + StringRedisTemplate redisTemplate = new StringRedisTemplate(); + redisTemplate.setConnectionFactory(factory); + + //设置Key的序列化采用StringRedisSerializer + redisTemplate.setKeySerializer(redisKeySerializer); + redisTemplate.setHashKeySerializer(redisKeySerializer); + + //设置值的序列化 + redisTemplate.setValueSerializer(redisValueSerializer); + redisTemplate.setHashValueSerializer(redisValueSerializer); + + redisTemplate.afterPropertiesSet(); + + return redisTemplate; + } +} From 5415bed9b11b13ec3e9aeec38aa243c0a93d92f0 Mon Sep 17 00:00:00 2001 From: luofu Date: Tue, 17 Oct 2023 14:06:38 +0800 Subject: [PATCH 19/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E6=9F=A5=E8=AF=A2=E8=AF=A6=E6=83=85=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 | 3 +- .../domain/dto/RawMessageRouterDTO.java | 9 +++ .../service/MessageTemplateNewService.java | 9 +++ .../impl/MessageTemplateNewServiceImpl.java | 65 +++++++++++++++++-- .../MessageTemplateDetailResponse.java | 9 ++- 5 files changed, 85 insertions(+), 10 deletions(-) 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 789b0af5..8bccabcb 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 @@ -41,8 +41,7 @@ public class MessageTemplateController implements MessageTemplateClient { @Override public CommonResponse detail(String templateCode) { - // TODO:[cold_blade] [P0] query template - return null; + return CommonResponse.success(messageTemplateNewService.detail(templateCode)); } @Override diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java index d37ccedb..16bf0eae 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java @@ -82,6 +82,15 @@ public class RawMessageRouterDTO implements Serializable { .build(); } + public MessageRouterButtonDTO toMessageRouterButton() { + return MessageRouterButtonDTO.builder() + .desc(this.desc) + .category(this.category) + .terminals(this.terminals) + .style(this.style) + .build(); + } + public List toMessageTemplateRouters() { return this.terminals.stream() .map(this::convert) 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 71029e7b..cfac04f4 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 @@ -3,6 +3,7 @@ package cn.axzo.msg.center.message.service; import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO; import cn.axzo.msg.center.message.domain.param.MessageTemplateCreateParam; 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; @@ -25,6 +26,14 @@ public interface MessageTemplateNewService { */ String createTemplate(MessageTemplateCreateParam param); + /** + * 通过模板便阿门查询模板详情 + * + * @param templateCode 模板编码 + * @return 模板详情信息 + */ + MessageTemplateDetailResponse detail(String templateCode); + /** * 通过模板编码查询模板信息 * 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 e6a1d08f..015851a8 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 @@ -2,10 +2,12 @@ package cn.axzo.msg.center.message.service.impl; 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.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.RawMessageRouterDTO; import cn.axzo.msg.center.message.domain.param.MessageTemplateCreateParam; @@ -13,11 +15,15 @@ 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.MessageTemplateRouterService; +import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO; +import cn.axzo.msg.center.service.enums.PushTerminalEnum; 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; @@ -69,6 +75,26 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService return templateCode; } + @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 groupNodePaths = messageTemplateGroupService.listMessageTemplateGroupPaths( + Lists.newArrayList(templateCode)).getOrDefault(templateCode, Collections.emptyList()); + List routers = messageTemplateRouterService.queryByTemplateCode(templateCode); + return convert(baseTemplate, groupNodePaths, routers); + } + @Override public Optional queryByTemplateCode(String msgTemplateCode) { if (StringUtils.isBlank(msgTemplateCode)) { @@ -202,6 +228,16 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService return template; } + private void saveTemplateRouters(MessageTemplateCreateParam param, String templateCode) { + if (CollectionUtils.isEmpty(param.getRouters())) { + return; + } + List routers = param.getRouters().stream() + .map(e -> RawMessageRouterDTO.from(e, templateCode)) + .collect(Collectors.toList()); + messageTemplateRouterService.batchInsert(routers); + } + private MessageTemplatePageResponse convert(MessageBaseTemplate record, Map> groupNodePaths, Map codeNameMap) { MessageTemplatePageResponse response = new MessageTemplatePageResponse(); @@ -219,13 +255,28 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService return response; } - private void saveTemplateRouters(MessageTemplateCreateParam param, String templateCode) { - if (CollectionUtils.isEmpty(param.getRouters())) { - return; - } - List routers = param.getRouters().stream() - .map(e -> RawMessageRouterDTO.from(e, templateCode)) + private MessageTemplateDetailResponse convert(MessageBaseTemplate record, List groupNodePaths, + List routers) { + // 将path解析中解析出分类结点(路径叶结点)的编码 + List groupNodeCodes = groupNodePaths.stream() + .map(GroupTreeNodePathDTO::parseLeafNodeCode) .collect(Collectors.toList()); - messageTemplateRouterService.batchInsert(routers); + // 转化为页面相关的数据模型 + List 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()) + .msgCardInfo(record.getCardContent()) + .msgIcon(record.getIcon()) + .routers(routerButtons) + .createTimestamp(record.getCreateAt().getTime()) + .updateTimestamp(record.getUpdateAt().getTime()) + .build(); } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java index 67e29201..9299d1f3 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java @@ -41,7 +41,6 @@ public class MessageTemplateDetailResponse implements Serializable { /** * 消息分类树的叶结点的结点编码列表 */ - @NotEmpty(message = "leafGroupNodes is required") private List leafGroupNodes; /** * 推送终端配置 @@ -69,6 +68,14 @@ public class MessageTemplateDetailResponse implements Serializable { * 路由策略列表 */ private List routers; + /** + * 模板创建时间戳 + */ + private Long createTimestamp; + /** + * 模板更新时间戳 + */ + private Long updateTimestamp; @Override public String toString() { From ec9e2823aada7b6958c047e0908716a90096f703 Mon Sep 17 00:00:00 2001 From: luofu Date: Tue, 17 Oct 2023 15:16:28 +0800 Subject: [PATCH 20/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E6=9B=B4=E6=96=B0=E6=8E=A5=E5=8F=A3=E5=AE=9E?= =?UTF-8?q?=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 | 12 ++-- ... => MessageTemplateSaveOrUpdateParam.java} | 26 ++++++- .../service/MessageTemplateGroupService.java | 15 +++++ .../service/MessageTemplateNewService.java | 21 +++++- .../service/MessageTemplateRouterService.java | 9 +++ .../impl/MessageTemplateGroupServiceImpl.java | 21 ++++++ .../impl/MessageTemplateNewServiceImpl.java | 67 +++++++++++++++++-- .../MessageTemplateRouterServiceImpl.java | 21 ++++++ .../request/MessageTemplateUpdateRequest.java | 10 +-- 9 files changed, 181 insertions(+), 21 deletions(-) rename inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/{MessageTemplateCreateParam.java => MessageTemplateSaveOrUpdateParam.java} (68%) 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 8bccabcb..1e87ed82 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 @@ -1,6 +1,6 @@ package cn.axzo.msg.center.message.controller; -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.MessageTemplateNewService; import cn.axzo.msg.center.service.template.client.MessageTemplateClient; import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest; @@ -30,13 +30,13 @@ public class MessageTemplateController implements MessageTemplateClient { @Override public CommonResponse save(MessageTemplateCreateRequest request) { return CommonResponse.success( - messageTemplateNewService.createTemplate(MessageTemplateCreateParam.from(request))); + messageTemplateNewService.createTemplate(MessageTemplateSaveOrUpdateParam.from(request))); } @Override public CommonResponse update(MessageTemplateUpdateRequest request) { - // TODO:[cold_blade] [P0] update template - return null; + messageTemplateNewService.updateTemplate(MessageTemplateSaveOrUpdateParam.from(request)); + return CommonResponse.success(); } @Override @@ -51,7 +51,7 @@ public class MessageTemplateController implements MessageTemplateClient { @Override public CommonResponse updateStatus(MessageTemplateUpdateStatusRequest request) { - // TODO:[cold_blade] [P0] update template status - return null; + messageTemplateNewService.updateStatus(request.getOperatorId(), request.getTemplateCode(), request.getStatus()); + return CommonResponse.success(); } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateCreateParam.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateSaveOrUpdateParam.java similarity index 68% rename from inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateCreateParam.java rename to inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateSaveOrUpdateParam.java index c516a122..c27944c1 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateCreateParam.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateSaveOrUpdateParam.java @@ -4,6 +4,7 @@ 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 cn.axzo.msg.center.utils.JSONObjectUtil; import com.alibaba.fastjson.JSON; import lombok.AllArgsConstructor; @@ -27,7 +28,7 @@ import java.util.List; @Builder @NoArgsConstructor @AllArgsConstructor -public class MessageTemplateCreateParam implements Serializable { +public class MessageTemplateSaveOrUpdateParam implements Serializable { private static final long serialVersionUID = 6657624182580261353L; @@ -35,6 +36,10 @@ public class MessageTemplateCreateParam implements Serializable { * 模板名称 */ private String templateName; + /** + * 模板编码 + */ + private String templateCode; /** * 消息分类树的叶结点的结点编码列表 */ @@ -76,8 +81,8 @@ public class MessageTemplateCreateParam implements Serializable { */ private List pushTerminals; - public static MessageTemplateCreateParam from(MessageTemplateCreateRequest request) { - return MessageTemplateCreateParam.builder() + public static MessageTemplateSaveOrUpdateParam from(MessageTemplateCreateRequest request) { + return MessageTemplateSaveOrUpdateParam.builder() .templateName(request.getTemplateName()) .msgCategory(request.getCategory()) .leafGroupNodes(request.getLeafGroupNodes()) @@ -91,6 +96,21 @@ public class MessageTemplateCreateParam implements Serializable { .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()) + .cardContent(JSONObjectUtil.checkAndReturn(request.getMsgCardInfo())) + .icon(request.getMsgIcon()) + .operatorId(request.getOperatorId()) + .routers(request.getRouters()) + .pushTerminals(request.getPushTerminals()) + .build(); + } + @Override public String toString() { return JSON.toJSONString(this); diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java index b966013e..ca7e4230 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java @@ -29,6 +29,21 @@ public interface MessageTemplateGroupService { */ void templateGroup(String templateNode, Collection groupNodeCodes); + /** + * 更新模板的分类关系 + * + * @param templateNode 模板编码 + * @param groupNodeCodes 新的模板的分类结点编码 + */ + void updateTemplateGroup(String templateNode, Collection groupNodeCodes); + + /** + * 解除模板关联的分类 + * + * @param templateNode 模板编码 + */ + void deleteTemplateGroup(String templateNode); + /** * 通过消息模板编码查询其关联的分类的path * 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 cfac04f4..7644190d 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 @@ -1,7 +1,8 @@ package cn.axzo.msg.center.message.service; 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.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; @@ -24,7 +25,14 @@ public interface MessageTemplateNewService { * * @param param 模板内容参数 */ - String createTemplate(MessageTemplateCreateParam param); + String createTemplate(MessageTemplateSaveOrUpdateParam param); + + /** + * 编辑模板 + * + * @param param 模板内容参数 + */ + void updateTemplate(MessageTemplateSaveOrUpdateParam param); /** * 通过模板便阿门查询模板详情 @@ -34,6 +42,15 @@ public interface MessageTemplateNewService { */ MessageTemplateDetailResponse detail(String templateCode); + /** + * 更新模板状态 + * + * @param operatorId 操作人id + * @param templateCode 模板编码 + * @param status 新的模板状态 + */ + void updateStatus(Long operatorId, String templateCode, StatusEnum status); + /** * 通过模板编码查询模板信息 * diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateRouterService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateRouterService.java index 915b43c1..51d71044 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateRouterService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateRouterService.java @@ -1,6 +1,7 @@ package cn.axzo.msg.center.message.service; import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO; +import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO; import java.util.List; import java.util.Map; @@ -30,6 +31,14 @@ public interface MessageTemplateRouterService { */ void batchInsert(List routers); + /** + * 更新模板的路由信息 + * + * @param templateCode 模板编码 + * @param routers 路由列表 + */ + void updateTemplateRoutes(String templateCode, List routers); + /** * 根据消息模板编码查询配置的路由列表 * diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java index b733406c..5eb0a2ea 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java @@ -48,6 +48,7 @@ public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupServ public void templateGroup(String templateNode, Collection groupNodeCodes) { if (StringUtils.isBlank(templateNode) || CollectionUtils.isEmpty(groupNodeCodes)) { + log.info("the param is invalid. templateNode:[{}], groupNodeCodes:{}", templateNode, groupNodeCodes); return; } Map pathMap = messageGroupNodeService.leafGroupNodeCodePaths(groupNodeCodes); @@ -62,6 +63,26 @@ public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupServ messageTemplateGroupDao.saveBatch(rows); } + @Override + public void updateTemplateGroup(String templateNode, Collection 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) + .eq(MessageTemplateGroup::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .remove(); + } + @Override public Map> listMessageTemplateGroupPaths(Collection templateCodes) { if (CollectionUtils.isEmpty(templateCodes)) { 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 015851a8..55ed7fc6 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 @@ -10,13 +10,14 @@ 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.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.MessageTemplateRouterService; 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; @@ -65,7 +66,7 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService @Override @Transactional(rollbackFor = Exception.class) - public String createTemplate(MessageTemplateCreateParam param) { + public String createTemplate(MessageTemplateSaveOrUpdateParam param) { // 创建模板基础数据 String templateCode = saveTemplate(param); // 创建模板的路由数据 @@ -75,6 +76,17 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService 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)) { @@ -95,6 +107,20 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService 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 public Optional queryByTemplateCode(String msgTemplateCode) { if (StringUtils.isBlank(msgTemplateCode)) { @@ -176,7 +202,7 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService return Page.toPage(request.getPage(), request.getPageSize(), result.getTotal(), records); } - private String saveTemplate(MessageTemplateCreateParam param) { + private String saveTemplate(MessageTemplateSaveOrUpdateParam param) { String templateCode = UUIDUtil.uuidString(); MessageBaseTemplate template = convert(param); boolean result = doSaveTemplate(template, templateCode); @@ -214,7 +240,7 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService .count() > 0; } - private MessageBaseTemplate convert(MessageTemplateCreateParam param) { + private MessageBaseTemplate convert(MessageTemplateSaveOrUpdateParam param) { MessageBaseTemplate template = new MessageBaseTemplate(); template.setName(param.getTemplateName()); template.setMsgCategory(param.getMsgCategory()); @@ -228,7 +254,7 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService return template; } - private void saveTemplateRouters(MessageTemplateCreateParam param, String templateCode) { + private void saveTemplateRouters(MessageTemplateSaveOrUpdateParam param, String templateCode) { if (CollectionUtils.isEmpty(param.getRouters())) { return; } @@ -238,6 +264,37 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService 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, + param.getPushTerminals()) + .set(StringUtils.isNotBlank(param.getTitle()), MessageBaseTemplate::getTitle, param.getTitle()) + .set(StringUtils.isNotBlank(param.getCardContent()), MessageBaseTemplate::getCardContent, + param.getCardContent()) + .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 MessageTemplatePageResponse convert(MessageBaseTemplate record, Map> groupNodePaths, Map codeNameMap) { MessageTemplatePageResponse response = new MessageTemplatePageResponse(); diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java index 59e73f4a..078711c0 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java @@ -1,9 +1,11 @@ package cn.axzo.msg.center.message.service.impl; +import cn.axzo.msg.center.common.enums.TableIsDeleteEnum; import cn.axzo.msg.center.dal.MessageTemplateRouterDao; import cn.axzo.msg.center.domain.entity.MessageTemplateRouter; import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO; import cn.axzo.msg.center.message.service.MessageTemplateRouterService; +import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO; import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -50,6 +52,25 @@ public class MessageTemplateRouterServiceImpl implements MessageTemplateRouterSe messageTemplateRouterDao.saveBatch(messageTemplateRouters); } + @Override + public void updateTemplateRoutes(String templateCode, List 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) + .eq(MessageTemplateRouter::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .remove(); + // 创建信息的路由信息 + List newRouters = routers.stream() + .map(e -> RawMessageRouterDTO.from(e, templateCode)) + .collect(Collectors.toList()); + batchInsert(newRouters); + } + @Override public Map> groupByTemplateCode(List templateCodes) { if (CollectionUtils.isEmpty(templateCodes)) { diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java index 52ca1801..d0e8429d 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java @@ -7,7 +7,6 @@ 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; @@ -30,15 +29,18 @@ public class MessageTemplateUpdateRequest implements Serializable { */ @NotNull(message = "operatorId is required") private Long operatorId; + /** + * 模板编码 + */ + @NotBlank(message = "templateCode is required") + private String templateCode; /** * 模板名称 */ - @NotBlank(message = "templateName is required") private String templateName; /** * 消息分类树的叶结点的结点编码列表 */ - @NotEmpty(message = "leafGroupNodes is required") private List leafGroupNodes; /** * 推送终端配置 @@ -49,7 +51,6 @@ public class MessageTemplateUpdateRequest implements Serializable { /** * 消息标题 */ - @NotBlank(message = "msgTitle is required") private String msgTitle; /** * 消息卡片信息,JSON字串 @@ -58,7 +59,6 @@ public class MessageTemplateUpdateRequest implements Serializable { /** * 消息内容 */ - @NotBlank(message = "msgContent is required") private String msgContent; /** * 消息图标 From 874676b89760ab82696036a97df54d01b4a07d97 Mon Sep 17 00:00:00 2001 From: luofu Date: Tue, 17 Oct 2023 16:26:25 +0800 Subject: [PATCH 21/50] =?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 22/50] =?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); + } } From e18b59125aab8143c6488dbac615e8be3352aba4 Mon Sep 17 00:00:00 2001 From: luofu Date: Wed, 18 Oct 2023 09:25:34 +0800 Subject: [PATCH 23/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E4=B8=8E=E5=88=86=E7=B1=BB=E5=85=B3=E8=81=94?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E6=8E=A5=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、消息模板与分类关联模块接口实现 影响: 无 --- ...essageTemplateGroupRelationController.java | 61 +++++++++++++++++++ .../service/MessageTemplateNewService.java | 9 +++ .../impl/MessageTemplateNewServiceImpl.java | 52 ++++++++++++++++ .../service/dto/MessageBaseTemplateDTO.java | 4 ++ ...ssageTemplateGroupRelationPageRequest.java | 4 ++ .../center/common/utils/PageHelperUtil.java | 11 ++++ 6 files changed, 141 insertions(+) create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageTemplateGroupRelationController.java diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageTemplateGroupRelationController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageTemplateGroupRelationController.java new file mode 100644 index 00000000..19f03b33 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageTemplateGroupRelationController.java @@ -0,0 +1,61 @@ +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; + +import java.util.List; + +/** + * @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(MessageTemplateGroupRelationPageRequest request) { + MessageTemplatePageRequest pageRequest = new MessageTemplatePageRequest(); + pageRequest.setPage(request.getPage()); + pageRequest.setPageSize(request.getPageSize()); + pageRequest.setTemplateName(request.getTemplateName()); + pageRequest.setGroupNodeCode(request.getNodeCode()); + Page result = messageTemplateNewService.pageBaseTemplate(pageRequest); + return CommonResponse.success(PageHelperUtil.convert(result, this::convert)); + } + + @Override + public CommonResponse move(MessageTemplateGroupRelationMoveRequest request) { + return null; + } + + @Override + public CommonResponse> remove(MessageTemplateGroupRelationRemoveRequest request) { + return null; + } + + 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; + } +} 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 5ce92b17..74d94bf8 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 @@ -2,6 +2,7 @@ package cn.axzo.msg.center.message.service; import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO; 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; @@ -76,6 +77,14 @@ public interface MessageTemplateNewService { */ Page page(MessageTemplatePageRequest request); + /** + * 分页查询模板基础数据 + * + * @param request 分页请求参数 + * @return 模板数据列表 + */ + Page pageBaseTemplate(MessageTemplatePageRequest request); + /** * 通过模板编码查询对应的模板 * 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 479119f6..cfeb374c 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 @@ -15,6 +15,7 @@ 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.MessageTemplateRouterService; +import cn.axzo.msg.center.service.dto.MessageBaseTemplateDTO; import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO; import cn.axzo.msg.center.service.enums.PushTerminalEnum; import cn.axzo.msg.center.service.enums.StatusEnum; @@ -204,6 +205,43 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService return Page.toPage(request.getPage(), request.getPageSize(), result.getTotal(), records); } + @Override + public Page pageBaseTemplate(MessageTemplatePageRequest request) { + List 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 pageRequest = request.toPage(); + IPage 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 records = result.getRecords().stream() + .map(this::convert) + .collect(Collectors.toList()); + return Page.toPage(request.getPage(), request.getPageSize(), result.getTotal(), records); + } + @Override public List listByCodes(Collection templateCodes) { if (CollectionUtils.isEmpty(templateCodes)) { @@ -322,6 +360,20 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService 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()) + .cardContent(record.getCardContent()) + .icon(record.getIcon()) + .pushTerminals(JSON.parseArray(record.getPushTerminal(), PushTerminalEnum.class)) + .createTimestamp(record.getCreateAt().getTime()) + .build(); + } + private MessageTemplatePageResponse convert(MessageBaseTemplate record, Map> groupNodePaths, Map codeNameMap) { MessageTemplatePageResponse response = new MessageTemplatePageResponse(); diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageBaseTemplateDTO.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageBaseTemplateDTO.java index 3ae986b1..521e9405 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageBaseTemplateDTO.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageBaseTemplateDTO.java @@ -58,6 +58,10 @@ public class MessageBaseTemplateDTO implements Serializable { * 推送终端配置列表 */ private List pushTerminals; + /** + * 消息模板创建时间戳 + */ + private Long createTimestamp; @Override public String toString() { diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationPageRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationPageRequest.java index 200bd48f..4544126c 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationPageRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/request/MessageTemplateGroupRelationPageRequest.java @@ -24,6 +24,10 @@ public class MessageTemplateGroupRelationPageRequest extends PageRequest impleme */ @NotBlank(message = "nodeCode is required") private String nodeCode; + /** + * 模板名称 + */ + private String templateName; @Override public String toString() { diff --git a/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/PageHelperUtil.java b/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/PageHelperUtil.java index 4d3a6b79..12158c79 100644 --- a/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/PageHelperUtil.java +++ b/msg-center-common/src/main/java/cn/axzo/msg/center/common/utils/PageHelperUtil.java @@ -5,6 +5,8 @@ import lombok.AccessLevel; import lombok.NoArgsConstructor; import java.util.Collections; +import java.util.function.Function; +import java.util.stream.Collectors; /** * @author cold_blade @@ -17,4 +19,13 @@ public final class PageHelperUtil { public static Page emptyPage(Long pageNum, Long pageSize) { return Page.toPage(pageNum, pageSize, 0L, Collections.emptyList()); } + + public static Page convert(Page page, Function convertFunc) { + Page tgtPage = new Page<>(); + tgtPage.setPageNum(page.getPageNum()); + tgtPage.setPageSize(page.getPageSize()); + tgtPage.setTotalElements(page.getTotalElements()); + tgtPage.setList(page.getList().stream().map(convertFunc).collect(Collectors.toList())); + return tgtPage; + } } From 7c64db8aa398a38398c8aa30c64da8b4237b8572 Mon Sep 17 00:00:00 2001 From: luofu Date: Wed, 18 Oct 2023 09:54:07 +0800 Subject: [PATCH 24/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E6=9B=B4=E6=96=B0=E6=8E=A5=E5=8F=A3=E5=A4=84?= =?UTF-8?q?=E7=90=86?= 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、消息模板更新接口调整 影响: 无 --- .../message/service/impl/MessageTemplateNewServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 cfeb374c..0dbf7c79 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 @@ -337,7 +337,7 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService .set(StringUtils.isNotBlank(param.getTemplateName()), MessageBaseTemplate::getName, param.getTemplateName()) .set(CollectionUtils.isNotEmpty(param.getPushTerminals()), MessageBaseTemplate::getPushTerminal, - param.getPushTerminals()) + JSON.toJSONString(param.getPushTerminals())) .set(StringUtils.isNotBlank(param.getTitle()), MessageBaseTemplate::getTitle, param.getTitle()) .set(StringUtils.isNotBlank(param.getCardContent()), MessageBaseTemplate::getCardContent, param.getCardContent()) From 1297380f13b5faeda072ff484745204a7075a478 Mon Sep 17 00:00:00 2001 From: luofu Date: Wed, 18 Oct 2023 10:23:43 +0800 Subject: [PATCH 25/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E5=88=86=E7=B1=BB=E6=A0=91=E6=93=8D=E4=BD=9C=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E8=B0=83=E6=95=B4?= 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、消息分类树操作模块功能调整 影响: 无 --- .../service/impl/MessageGroupNodeServiceImpl.java | 9 ++++++--- .../axzo/msg/center/service/dto/GroupTreeNodeDTO.java | 11 ++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) 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 ebdc4c92..58a9d7ca 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 @@ -79,8 +79,9 @@ public class MessageGroupNodeServiceImpl implements MessageGroupNodeService { @Override public void addGroupNode(MessageGroupNodeSaveOrUpdateParam param) { - GroupTreeNodeDTO parent = messageGroupTreeNodeCacheService.queryNode(param.getParentNodeCode()) - .orElseThrow(() -> new ServiceException("parentNodeCode is invalid")); + GroupTreeNodeDTO parent = StringUtils.isBlank(param.getParentNodeCode()) ? null : + messageGroupTreeNodeCacheService.queryNode(param.getParentNodeCode()) + .orElseThrow(() -> new ServiceException("parentNodeCode is invalid")); // 合法性校验 checkCreateRule(parent, param); // 存储 @@ -148,7 +149,9 @@ public class MessageGroupNodeServiceImpl implements MessageGroupNodeService { } private void checkCreateRule(GroupTreeNodeDTO parent, MessageGroupNodeSaveOrUpdateParam param) { - AssertUtil.isTrue(parent.getCategory().getLevel() < param.getCategory().getLevel(), "父节点的类型非法"); + if (Objects.nonNull(parent)) { + AssertUtil.isTrue(parent.getCategory().getLevel() < param.getCategory().getLevel(), "父节点的类型非法"); + } } private void checkDeleteRule(String nodeCode) { 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 e360c55a..21c25890 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 @@ -63,22 +63,23 @@ public class GroupTreeNodeDTO implements IBaseTree, Se private List nodeChildren = Collections.emptyList(); public MessageGroupTreeNodeResponse toMessageGroupTreeNodeResponse() { + List 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(nodeChildren.stream() - .map(GroupTreeNodeDTO::toMessageGroupTreeNodeResponse) - .collect(Collectors.toList())) + .children(children) .build(); } public Optional getChild(String treeNodeCode) { - if (StringUtils.isBlank(treeNodeCode)) { + if (StringUtils.isBlank(treeNodeCode) || Objects.isNull(nodeChildren)) { return Optional.empty(); } - return getNodeChildren().stream() + return nodeChildren.stream() .filter(e -> Objects.equals(e.getNodeCode(), treeNodeCode)) .findFirst(); } From eccd88fca64178e54566214f0ed6075d48476699 Mon Sep 17 00:00:00 2001 From: luofu Date: Wed, 18 Oct 2023 17:56:36 +0800 Subject: [PATCH 26/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E5=88=86=E7=B1=BB=E6=A0=91=E6=93=8D=E4=BD=9C=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E8=B0=83=E6=95=B4?= 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、消息分类树操作模块功能调整 影响: 无 --- ...essageTemplateGroupRelationController.java | 11 +-- .../service/MessageTemplateGroupService.java | 19 ++++++ .../impl/MessageGroupNodeServiceImpl.java | 1 + .../impl/MessageTemplateGroupServiceImpl.java | 68 +++++++++++++++++++ .../MessageTemplateRouterServiceImpl.java | 1 + .../MessageTemplateGroupRelationClient.java | 5 +- ...geTemplateGroupRelationClientFallback.java | 2 +- 7 files changed, 98 insertions(+), 9 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageTemplateGroupRelationController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageTemplateGroupRelationController.java index 19f03b33..a72a10cd 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageTemplateGroupRelationController.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/MessageTemplateGroupRelationController.java @@ -15,8 +15,6 @@ import cn.azxo.framework.common.model.Page; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - /** * @author cold_blade * @date 2023/10/17 @@ -42,12 +40,15 @@ public class MessageTemplateGroupRelationController implements MessageTemplateGr @Override public CommonResponse move(MessageTemplateGroupRelationMoveRequest request) { - return null; + messageTemplateGroupService.move(request.getCurNodeCode(), request.getTargetNodeCode(), + request.getTemplateCodes()); + return CommonResponse.success(); } @Override - public CommonResponse> remove(MessageTemplateGroupRelationRemoveRequest request) { - return null; + public CommonResponse remove(MessageTemplateGroupRelationRemoveRequest request) { + messageTemplateGroupService.remove(request.getCurNodeCode(), request.getTemplateCodes()); + return CommonResponse.success(); } private MessageTemplateGroupRelationResponse convert(MessageBaseTemplateDTO dto) { diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java index ca7e4230..0c7e2ec1 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java @@ -51,4 +51,23 @@ public interface MessageTemplateGroupService { * @return 模板编码与分类的path列表的映射关系 */ Map> listMessageTemplateGroupPaths(Collection templateCodes); + + /** + * 解除模板与当前分类的关联关系 + * 注:当模板只关联一个分类时,该关联关系不能解除 + * + * @param curGroupNodeCode 当前分类结点的编码 + * @param templateCodes 待解除关连关系的模板编码 + */ + void remove(String curGroupNodeCode, Collection templateCodes); + + /** + * 解除模板与当前分类的关联关系 + * 注:当模板只关联一个分类时,该关联关系不能解除 + * + * @param srcGroupNodeCode 源分类结点的编码 + * @param tgtGroupNodeCode 目标分类结点的编码 + * @param templateCodes 待变更关连关系的模板编码 + */ + void move(String srcGroupNodeCode, String tgtGroupNodeCode, 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 58a9d7ca..0f642542 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 @@ -117,6 +117,7 @@ public class MessageGroupNodeServiceImpl implements MessageGroupNodeService { boolean removeResult = messageGroupNodeDao.lambdaUpdate() .eq(MessageGroupNode::getCode, nodeCode) .eq(MessageGroupNode::getIsDelete, TableIsDeleteEnum.NORMAL.value) + // TODO: [cold_blade] [P2] 这里需要逻辑删除而非物理删除 .remove(); if (removeResult) { // 刷新缓存 diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java index 5eb0a2ea..3ab0d607 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java @@ -1,10 +1,12 @@ 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.dal.MessageTemplateGroupDao; 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 lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -15,6 +17,8 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -80,6 +84,7 @@ public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupServ messageTemplateGroupDao.lambdaUpdate() .eq(MessageTemplateGroup::getTemplateCode, templateNode) .eq(MessageTemplateGroup::getIsDelete, TableIsDeleteEnum.NORMAL.value) + // TODO: [cold_blade] [P2] 这里需要逻辑删除而非物理删除 .remove(); } @@ -95,4 +100,67 @@ public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupServ .collect(Collectors.groupingBy(MessageTemplateGroup::getTemplateCode, Collectors.mapping(MessageTemplateGroup::getPath, Collectors.toList()))); } + + @Override + public void remove(String curGroupNodeCode, Collection templateCodes) { + // TODO: [cold_blade] + // 参数校验 + AssertUtil.isTrue(StringUtils.isNotBlank(curGroupNodeCode), "curGroupNodeCode can not be blank"); + AssertUtil.notEmpty(templateCodes, "templateCodes can not be empty"); + // 通过分类结点编码获取其对应的结点编码的路径 + Map nodeCodePathMap = messageGroupNodeService + .leafGroupNodeCodePaths(Lists.newArrayList(curGroupNodeCode)); + // 通过能否成功获取到其树路径来校验其有效性 + AssertUtil.isFalse(nodeCodePathMap.isEmpty(), "curGroupNodeCode is invalid"); + // 统计指定的模板编码关联的分类数量 + Map 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 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)) + .eq(MessageTemplateGroup::getIsDelete, TableIsDeleteEnum.NORMAL.value) + // TODO: [cold_blade] [P2] 这里需要逻辑删除而非物理删除 + .remove(); + } + + @Override + public void move(String srcGroupNodeCode, String tgtGroupNodeCode, Collection 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 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 onlyContainsOneTemplateCodes) { + return String.format("模板:%s。解除关联后,将无关联分类!本次操作无效!", + String.join("、", onlyContainsOneTemplateCodes)); + } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java index 078711c0..553ca5c0 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java @@ -63,6 +63,7 @@ public class MessageTemplateRouterServiceImpl implements MessageTemplateRouterSe messageTemplateRouterDao.lambdaUpdate() .eq(MessageTemplateRouter::getTemplateCode, templateCode) .eq(MessageTemplateRouter::getIsDelete, TableIsDeleteEnum.NORMAL.value) + // TODO: [cold_blade] [P2] 这里需要逻辑删除而非物理删除 .remove(); // 创建信息的路由信息 List newRouters = routers.stream() diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java index 634b843f..4b96fd86 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/MessageTemplateGroupRelationClient.java @@ -12,7 +12,6 @@ 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 org.springframework.web.bind.annotation.RequestParam; import javax.validation.Valid; import java.util.List; @@ -47,11 +46,11 @@ public interface MessageTemplateGroupRelationClient { CommonResponse move(@RequestBody @Valid MessageTemplateGroupRelationMoveRequest request); /** - * 变更模板与分类的关联关系 + * 解除分类与模板的关联关系 * * @param request 变更分类的相关参数 * @return 关联关系解除失败的模板编码 */ @PostMapping(value = "/message/template/group-relation/remove", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse> remove(@RequestBody @Valid MessageTemplateGroupRelationRemoveRequest request); + CommonResponse remove(@RequestBody @Valid MessageTemplateGroupRelationRemoveRequest request); } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageTemplateGroupRelationClientFallback.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageTemplateGroupRelationClientFallback.java index e4a07054..36fe2be7 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageTemplateGroupRelationClientFallback.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/group/client/fallback/MessageTemplateGroupRelationClientFallback.java @@ -35,7 +35,7 @@ public class MessageTemplateGroupRelationClientFallback implements MessageTempla } @Override - public CommonResponse> remove(MessageTemplateGroupRelationRemoveRequest request) { + public CommonResponse 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"); } From bd1cb276a050a94c41620a04bf5a71b03d7c08c1 Mon Sep 17 00:00:00 2001 From: luofu Date: Wed, 18 Oct 2023 20:05:55 +0800 Subject: [PATCH 27/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E5=88=86=E7=B1=BB=E6=A0=91=E6=93=8D=E4=BD=9C=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E8=B0=83=E6=95=B4?= 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、消息分类树操作模块功能调整 影响: 无 --- .../domain/dto/MessageGroupNodeStatisticDTO.java | 7 ++++++- .../cn/axzo/msg/center/utils/TreeHelperUtil.java | 13 ++++++++----- .../msg/center/service/dto/GroupTreeNodeDTO.java | 4 ++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageGroupNodeStatisticDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageGroupNodeStatisticDTO.java index f5cef354..9368d462 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageGroupNodeStatisticDTO.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageGroupNodeStatisticDTO.java @@ -52,7 +52,12 @@ public class MessageGroupNodeStatisticDTO implements IBaseTree children = this.nodeChildren.stream() .map(MessageGroupNodeStatisticDTO::toResponse).collect(Collectors.toList()); response.setNodeChildren(children); 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 b1965b72..4a890a6e 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 @@ -28,19 +28,22 @@ public final class TreeHelperUtil { AssertUtil.notNull(wrapperFunc, "wrapperFunc is null"); final Map convertMap = Maps.newHashMap(); - T wrapper = wrapperFunc.apply(treeNode); - convertMap.put(treeNode, wrapper); + T root = wrapperFunc.apply(treeNode); + convertMap.put(treeNode, root); LinkedList treeNodeStack = new LinkedList<>(); treeNodeStack.push(treeNode); while (!treeNodeStack.isEmpty()) { treeNode = treeNodeStack.pop(); List children = treeNode.getNodeChildren(); convertMap.get(treeNode).setNodeChildren(children.stream() - .map(e -> convertMap.put(e, wrapperFunc.apply(e))) - .collect(Collectors.toList())); + .map(e -> { + T wrapper = wrapperFunc.apply(e); + convertMap.put(e, wrapper); + return wrapper; + }).collect(Collectors.toList())); treeNodeStack.addAll(children); } - return wrapper; + return root; } public static boolean isLeafNodeCategory(MessageGroupNodeCategoryEnum 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 21c25890..9425101c 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 @@ -62,6 +62,10 @@ public class GroupTreeNodeDTO implements IBaseTree, Se @Builder.Default private List nodeChildren = Collections.emptyList(); + public void setNodeChildren(List nodeChildren) { + this.nodeChildren = Optional.ofNullable(nodeChildren).orElseGet(Collections::emptyList); + } + public MessageGroupTreeNodeResponse toMessageGroupTreeNodeResponse() { List children = Optional.ofNullable(nodeChildren) .map(v -> v.stream().map(GroupTreeNodeDTO::toMessageGroupTreeNodeResponse).collect(Collectors.toList())) From 15d259836fcd55dacd1ff747e1463c1dd613c5d6 Mon Sep 17 00:00:00 2001 From: luofu Date: Thu, 19 Oct 2023 18:53:45 +0800 Subject: [PATCH 28/50] =?UTF-8?q?feat(REQ-1465):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=8F=91=E9=80=81=E6=99=AE=E9=80=9A=E6=B6=88=E6=81=AF=E5=8F=91?= =?UTF-8?q?=E9=80=81=E6=8E=A5=E5=8F=A3?= 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、新增发送普通消息发送接口 影响: 无 --- inside-notices/pom.xml | 4 + .../controller/GeneralMessageController.java | 27 ++++ .../domain/dto/GeneralMessagePushDTO.java | 87 +++++++++++ .../domain/dto/MessageTemplateDTO.java | 11 ++ .../service/GeneralMessageService.java | 19 +++ .../impl/GeneralMessageServiceImpl.java | 145 ++++++++++++++++++ .../msg/center/utils/MessageRouterUtil.java | 38 +++++ .../center/service/dto/MessageRouterDTO.java | 2 + .../service/enums/PushTerminalEnum.java | 5 +- .../service/enums/RouterCategoryEnum.java | 4 +- .../general/client/GeneralMessageClient.java | 34 ++++ .../GeneralMessageClientFallback.java | 23 +++ .../request/GeneralMessageSendRequest.java | 89 +++++++++++ .../response/GeneralMessageResponse.java | 117 ++++++++++++++ .../center/dal/GeneralMessageRecordDao.java | 18 +++ .../domain/entity/GeneralMessageRecord.java | 47 ++++-- .../domain/entity/MessageBaseTemplate.java | 4 + .../java/cn/axzo/msg/center/FeignConfig.java | 66 ++++++++ .../cn/axzo/msg/center/MsgCenterConfig.java | 6 +- 19 files changed, 732 insertions(+), 14 deletions(-) create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GeneralMessagePushDTO.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/general/request/GeneralMessageSendRequest.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/general/response/GeneralMessageResponse.java create mode 100644 msg-center-dal/src/main/java/cn/axzo/msg/center/dal/GeneralMessageRecordDao.java create mode 100644 start/src/main/java/cn/axzo/msg/center/FeignConfig.java diff --git a/inside-notices/pom.xml b/inside-notices/pom.xml index fc0a36ac..bbf4aa3b 100644 --- a/inside-notices/pom.xml +++ b/inside-notices/pom.xml @@ -110,6 +110,10 @@ 1.0.0-SNAPSHOT compile + + cn.axzo.im.center + im-center-api + \ No newline at end of file diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java new file mode 100644 index 00000000..0f25e885 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java @@ -0,0 +1,27 @@ +package cn.axzo.msg.center.message.controller; + +import cn.axzo.msg.center.message.service.GeneralMessageService; +import cn.axzo.msg.center.service.general.client.GeneralMessageClient; +import cn.axzo.msg.center.service.general.request.GeneralMessageSendRequest; +import cn.azxo.framework.common.model.CommonResponse; +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; + + @Override + public CommonResponse sendMessage(GeneralMessageSendRequest request) { + return CommonResponse.success(generalMessageService.sendMessage(request)); + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GeneralMessagePushDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GeneralMessagePushDTO.java new file mode 100644 index 00000000..fdb9959d --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GeneralMessagePushDTO.java @@ -0,0 +1,87 @@ +package cn.axzo.msg.center.message.domain.dto; + +import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO; +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 java.io.Serializable; +import java.util.List; + +/** + * @author cold_blade + * @date 2023/10/19 + * @version 1.0 + */ +@Setter +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class GeneralMessagePushDTO implements Serializable { + + private static final long serialVersionUID = -9017550674630922381L; + + /** + * 消息的唯一标识 + */ + private String identityCode; + /** + * 模板编码 + */ + private String templateCode; + /** + * 模板icon地址 + */ + private String templateIcon; + /** + * 消息标题 + */ + private String title; + /** + * 消息内容 + */ + private String content; + /** + * 卡片信息 + */ + private String cardContent; + /** + * 消息所属组织类型 + */ + private OrganizationTypeEnum orgType; + /** + * 消息所属组织Id + */ + private Long orgId; + /** + * 消息所属组织名称 + */ + private String orgName; + /** + * 业务编码 + */ + private String bizCode; + /** + * 消息发送时间戳 + */ + private Long sendTimestamp; + /** + * 路由信息,可为空 + */ + private List routers; + /** + * 参数及其对应的值的JSON串 + */ + private JSONObject routerParams; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageTemplateDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageTemplateDTO.java index 88fafc90..d5f7551f 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageTemplateDTO.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageTemplateDTO.java @@ -2,6 +2,7 @@ package cn.axzo.msg.center.message.domain.dto; import cn.axzo.msg.center.domain.entity.MessageBaseTemplate; 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; @@ -60,6 +61,14 @@ public class MessageTemplateDTO implements Serializable { * 模板路由信息 */ private List routers; + /** + * 推送终端 + */ + private List pushTerminals; + /** + * APP最小版本支持,可不配 + */ + private String minAppVersion; public static MessageTemplateDTO from(MessageBaseTemplate baseTemplate, List routers) { return MessageTemplateDTO.builder() @@ -71,6 +80,8 @@ public class MessageTemplateDTO implements Serializable { .msgCategory(baseTemplate.getMsgCategory()) .icon(baseTemplate.getIcon()) .routers(routers) + .pushTerminals(JSON.parseArray(baseTemplate.getPushTerminal(), PushTerminalEnum.class)) + .minAppVersion(baseTemplate.getMinAppVersion()) .build(); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java new file mode 100644 index 00000000..29ca9089 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java @@ -0,0 +1,19 @@ +package cn.axzo.msg.center.message.service; + +import cn.axzo.msg.center.service.general.request.GeneralMessageSendRequest; + +/** + * @author cold_blade + * @date 2023/10/19 + * @version 1.0 + */ +public interface GeneralMessageService { + + /** + * 发送消息 + * + * @param request 消息所需参数 + * @return 消息的唯一标识 + */ + String sendMessage(GeneralMessageSendRequest request); +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java new file mode 100644 index 00000000..1d720553 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java @@ -0,0 +1,145 @@ +package cn.axzo.msg.center.message.service.impl; + +import cn.axzo.im.center.api.feign.MessageApi; +import cn.axzo.im.center.api.vo.req.MessageInfo; +import cn.axzo.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.message.domain.dto.GeneralMessagePushDTO; +import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO; +import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO; +import cn.axzo.msg.center.message.service.GeneralMessageService; +import cn.axzo.msg.center.message.service.MessageTemplateNewService; +import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO; +import cn.axzo.msg.center.service.enums.GeneralMessageStateEnum; +import cn.axzo.msg.center.service.enums.PushTerminalEnum; +import cn.axzo.msg.center.service.general.request.GeneralMessageSendRequest; +import cn.axzo.msg.center.utils.MessageRouterUtil; +import cn.axzo.msg.center.utils.UUIDUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Lists; +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.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @author cold_blade + * @date 2023/10/19 + * @version 1.0 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class GeneralMessageServiceImpl implements GeneralMessageService { + + private final MessageApi messageApi; + private final MessageTemplateNewService messageTemplateNewService; + private final GeneralMessageRecordDao generalMessageRecordDao; + + @Override + public String sendMessage(GeneralMessageSendRequest request) { + // 查询模板基础信息 + MessageTemplateDTO template = messageTemplateNewService.queryByTemplateCode(request.getTemplateCode()) + .orElseThrow(() -> new ServiceException("未查询到对应的模板")); + // 构建消息记录并存储 + GeneralMessageRecord messageRecord = buildMessageRecord(request, template); + generalMessageRecordDao.save(messageRecord); + // 推送 + pushMessage(messageRecord, template); + return messageRecord.getIdentityCode(); + } + + private GeneralMessageRecord buildMessageRecord(GeneralMessageSendRequest request, MessageTemplateDTO template) { + return GeneralMessageRecord.builder() + .identityCode(UUIDUtil.uuidString()) + .senderId(request.getSenderPersonId()) + .senderId(request.getSenderIdentity().getId()) + .senderType(request.getSenderIdentity().getType()) + .receiverPersonId(request.getReceiverPersonId()) + .receiverId(request.getReceiverIdentity().getId()) + .receiverType(request.getReceiverIdentity().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 void pushMessage(GeneralMessageRecord record, MessageTemplateDTO template) { + if (CollectionUtils.isEmpty(template.getPushTerminals())) { + // 模板未配置任何推送终端 + return; + } + List appTypes = template.getPushTerminals().stream() + .map(PushTerminalEnum::getImTerminalFlag).collect(Collectors.toList()); + GeneralMessagePushDTO message = convert(record, template); + MessageInfo msgInfo = new MessageInfo(); + msgInfo.setAppTypeList(appTypes); + msgInfo.setPersonId(String.valueOf(record.getSenderPersonId())); + msgInfo.setToPersonIdList(Lists.newArrayList(String.valueOf(record.getReceiverPersonId()))); + msgInfo.setMsgHeader(record.getTitle()); + msgInfo.setMsgContent(record.getContent()); + msgInfo.setMsgTemplateId(record.getTemplateCode()); + msgInfo.setMsgTemplateContent(JSON.toJSONString(message)); + // 扩展信息 + Map ext = new HashMap<>(); + ext.put("minAppVersion", template.getMinAppVersion()); + msgInfo.setExtendsInfo(ext); + + messageApi.sendMessage(msgInfo); + } + + private GeneralMessagePushDTO convert(GeneralMessageRecord record, MessageTemplateDTO template) { + // 对应模板的路由列表 + List rawRouters = template.getRouters(); + // 视情况替换原始URL中的参数变量 + rawRouters.forEach(e -> MessageRouterUtil.parseRouteUrl(e, record.getRouterParams())); + // 转化成客户端展示的数据模型 + List routerButtons = rawRouters.stream() + .map(RawMessageRouterDTO::toMessageRouterButton) + .collect(Collectors.toList()); + // 获取模板卡片信息 + String cardContent = template.getCardContent(); + if (StringUtils.isNotBlank(cardContent)) { + cardContent = PlaceholderResolver.getDefaultResolver().resolveByMap(cardContent, record.getBizExtParams()); + } + return GeneralMessagePushDTO.builder() + .identityCode(record.getIdentityCode()) + .templateCode(template.getCode()) + .templateIcon(template.getIcon()) + .title(record.getTitle()) + .content(record.getContent()) + .cardContent(cardContent) + .orgType(record.getOrgType()) + .orgId(record.getOrgId()) + .orgName(record.getOrgName()) + .bizCode(record.getBizCode()) + .sendTimestamp(System.currentTimeMillis()) + .routers(routerButtons) + .routerParams(record.getRouterParams()) + .build(); + } + + private String parseString(String string, JSONObject params) { + if (Objects.isNull(params)) { + return string; + } + return PlaceholderResolver.getDefaultResolver().resolveByMap(string, params); + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java b/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java index 9c752d85..3e75c0b2 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java @@ -8,6 +8,7 @@ import cn.axzo.msg.center.service.enums.ButtonStyleEnum; import cn.axzo.msg.center.service.enums.RouterCategoryEnum; import cn.axzo.msg.center.service.enums.TerminalTypeEnum; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.apache.commons.lang3.StringUtils; @@ -15,6 +16,7 @@ import org.apache.commons.lang3.StringUtils; import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; /** * @description @@ -47,6 +49,25 @@ public final class MessageRouterUtil { .findFirst().orElseGet(() -> rawMessageRouter.getTerminals().get(0)); } + /** + * 根据指定的终端类型选取合适的路由 + * + * @param rawMessageRouter 原始的模板路由策略 + * @param excludeTerminalType 待排除的终端类型 + * @return 合适的路由数据 + */ + public static List 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()); + } + /** * 判断路由参数的合法性 * @@ -74,6 +95,23 @@ public final class MessageRouterUtil { } } + /** + * 解析模板上配置的路由地址,并将发送消息时的参数替换上去 + * + * @param router 路由信息 + * @param routerParam 路由参数 + */ + public static void parseRouteUrl(RawMessageRouterDTO router, JSONObject routerParam) { + // 路由参数有效 + if (Objects.nonNull(routerParam)) { + router.getTerminals().forEach(e -> { + // 替换原始URL中的参数变量 + String routerUrl = PlaceholderResolver.getDefaultResolver().resolveByMap(e.getUrl(), routerParam); + e.setUrl(routerUrl); + }); + } + } + /** * 解析按钮style * diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterDTO.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterDTO.java index 3322b087..85576af1 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterDTO.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterDTO.java @@ -55,6 +55,8 @@ public class MessageRouterDTO implements Serializable { private TerminalTypeEnum terminalType; /** * 按钮样式配置 + * HIGH_LIGHT: 按钮高亮展示 + * OVER_CARD: 按钮显示在卡片 */ private List style; diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java index c52deaf6..834616a0 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java @@ -18,12 +18,13 @@ public enum PushTerminalEnum { /** * B-安心筑企业版 */ - B_ENTERPRISE_APP("B-安心筑企业版"), + B_ENTERPRISE_APP("B-安心筑企业版", "ENTERPRISE"), /** * C-安心筑工人版 */ - C_WORKER_APP("C-安心筑工人版"), + C_WORKER_APP("C-安心筑工人版", "WORKER"), ; private final String desc; + private final String imTerminalFlag; } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/RouterCategoryEnum.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/RouterCategoryEnum.java index 04a10dcd..33e4b405 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/RouterCategoryEnum.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/RouterCategoryEnum.java @@ -16,7 +16,9 @@ import lombok.Getter; public enum RouterCategoryEnum { JUMP("直接跳转"), - ACTION("接口调用"); + ACTION("接口调用"), + DETAIL("页面详情"), + ; private final String desc; } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java new file mode 100644 index 00000000..a93a0ebf --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java @@ -0,0 +1,34 @@ +package cn.axzo.msg.center.service.general.client; + +import cn.axzo.msg.center.service.general.request.GeneralMessageSendRequest; +import cn.axzo.msg.center.service.pending.client.fallback.PendingMessageClientFallback; +import cn.azxo.framework.common.model.CommonResponse; +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 = PendingMessageClientFallback.class) +public interface GeneralMessageClient { + + /** + * 发送消息 + * + * @param request 消息所需参数 + * @return 消息的唯一标识 + */ + @PostMapping(value = "/general-message/send", produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse sendMessage(@RequestBody @Valid GeneralMessageSendRequest request); +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java new file mode 100644 index 00000000..3179b879 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java @@ -0,0 +1,23 @@ +package cn.axzo.msg.center.service.general.client.fallback; + +import cn.axzo.msg.center.service.general.client.GeneralMessageClient; +import cn.axzo.msg.center.service.general.request.GeneralMessageSendRequest; +import cn.azxo.framework.common.model.CommonResponse; +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 sendMessage(GeneralMessageSendRequest request) { + log.error("fall back while sending message. req:{}", request); + return CommonResponse.error("fall back while sending message"); + } +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/request/GeneralMessageSendRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/request/GeneralMessageSendRequest.java new file mode 100644 index 00000000..3fa18cda --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/request/GeneralMessageSendRequest.java @@ -0,0 +1,89 @@ +package cn.axzo.msg.center.service.general.request; + +import cn.axzo.msg.center.service.dto.IdentityDTO; +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.NotNull; +import java.io.Serializable; + +/** + * @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; + /** + * 消息发送者自然人id + */ + @NotNull(message = "senderPersonId is required") + private Long senderPersonId; + /** + * 消息发送者身份 + */ + @NotNull(message = "senderIdentity is required") + private IdentityDTO senderIdentity; + /** + * 消息接收者自然人id + */ + @NotNull(message = "receiverPersonId is required") + private Long receiverPersonId; + /** + * 消息接收者身份 + */ + @NotNull(message = "receiverIdentity is required") + private IdentityDTO receiverIdentity; + /** + * 消息所属组织类型 + */ + 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); + } +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/response/GeneralMessageResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/response/GeneralMessageResponse.java new file mode 100644 index 00000000..b5c8150c --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/response/GeneralMessageResponse.java @@ -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 routers; + /** + * 参数及其对应的值的JSON串 + */ + private JSONObject routerParams; + /** + * 发送终端,eg: + * B_ENTERPRISE_APP:B-安心筑企业版 + * C_WORKER_APP:C-安心筑工人版 + */ + private List pushTerminals; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/GeneralMessageRecordDao.java b/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/GeneralMessageRecordDao.java new file mode 100644 index 00000000..2f06d009 --- /dev/null +++ b/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/GeneralMessageRecordDao.java @@ -0,0 +1,18 @@ +package cn.axzo.msg.center.dal; + +import cn.axzo.msg.center.dal.mapper.GeneralMessageRecordMapper; +import cn.axzo.msg.center.domain.entity.GeneralMessageRecord; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @description + * @author cold_blade + * @date 2023/10/5 + * @version 1.0 + */ +@Slf4j +@Component +public class GeneralMessageRecordDao extends ServiceImpl { +} diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/GeneralMessageRecord.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/GeneralMessageRecord.java index dd744f9e..fa25220f 100644 --- a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/GeneralMessageRecord.java +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/GeneralMessageRecord.java @@ -5,8 +5,14 @@ import cn.axzo.msg.center.service.enums.GeneralMessageStateEnum; import cn.axzo.msg.center.service.enums.IdentityTypeEnum; import cn.axzo.msg.center.service.enums.OrganizationTypeEnum; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; import java.io.Serializable; @@ -20,27 +26,42 @@ import java.io.Serializable; */ @Setter @Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor @TableName("general_message_record") public class GeneralMessageRecord extends BaseEntity implements Serializable { private static final long serialVersionUID = -1271402884501451185L; /** - * 发送者ID + * 消息的唯一标识 + */ + private String identityCode; + /** + * 发送者自然人 ID + */ + private Long senderPersonId; + /** + * 发送者身份ID */ private Long senderId; /** - * 接收者ID + * 发送者身份类型 + */ + private IdentityTypeEnum senderType; + /** + * 接收者自然人 ID + */ + private Long receiverPersonId; + /** + * 接收者身份ID */ private Long receiverId; /** - * 接收者类型 + * 接收者身份类型 */ private IdentityTypeEnum receiverType; - /** - * 自然人 ID - */ - private Long personId; /** * 模板编码 */ @@ -76,13 +97,19 @@ public class GeneralMessageRecord extends BaseEntity imple /** * 路由参数(留存) */ - private String routerParams; + @TableField(typeHandler = FastjsonTypeHandler.class) + private JSONObject routerParams; /** - * 重试次数 + * 业务扩展参数 + */ + @TableField(typeHandler = FastjsonTypeHandler.class) + private JSONObject bizExtParams; + /** + * 推送重试次数 */ private Integer retryCount; /** - * 最终失败原因 + * 推送最终失败原因 */ private String failCause; diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageBaseTemplate.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageBaseTemplate.java index 2c425cf7..1b8cd7dd 100644 --- a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageBaseTemplate.java +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageBaseTemplate.java @@ -62,6 +62,10 @@ public class MessageBaseTemplate extends BaseEntity impleme * 推送终端配置 JSON字串 */ private String pushTerminal; + /** + * APP最小版本支持,可不配 + */ + private String minAppVersion; /** * 创建者自然人id */ diff --git a/start/src/main/java/cn/axzo/msg/center/FeignConfig.java b/start/src/main/java/cn/axzo/msg/center/FeignConfig.java new file mode 100644 index 00000000..08d1b731 --- /dev/null +++ b/start/src/main/java/cn/axzo/msg/center/FeignConfig.java @@ -0,0 +1,66 @@ +package cn.axzo.msg.center; + +import cn.hutool.core.util.ReflectUtil; +import feign.RequestInterceptor; +import feign.RequestTemplate; +import feign.Target; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.EnvironmentAware; +import org.springframework.context.annotation.Profile; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Field; +import java.util.Map; +import java.util.Objects; + +/** + * @author cold_blade + * @date 2023/10/19 + * @version 1.0 + */ +@Slf4j +@Component +@Profile({"dev", "test", "local"}) +public class FeignConfig implements RequestInterceptor, EnvironmentAware { + private Environment environment; + + @Value("${imCenterEngineEnvUrl:http://dev-app.axzo.cn/msg-center}") + private String imCenter; + + private static String POD_NAMESPACE; + + static { + Map env = System.getenv(); + if (env != null) { + POD_NAMESPACE = env.get("MY_POD_NAMESPACE"); + } + log.info("init FeignConfig, POD_NAMESPACE value is {}", POD_NAMESPACE); + } + + @SneakyThrows + @Override + public void apply(RequestTemplate requestTemplate) { + if (POD_NAMESPACE == null) { + Target.HardCodedTarget target = (Target.HardCodedTarget) requestTemplate.feignTarget(); + String url = requestTemplate.feignTarget().url(); + // 如需修改微服务地址,建议通过外部化参数来调整 + url = url.replace("http://im-center:8080", imCenter); + String profile = environment.getProperty("spring.profiles.active"); + if (Objects.equals(profile, "test") && url.contains("dev-app.axzo.cn")) { + url = url.replace("dev-app", "test-api"); + } + requestTemplate.target(url); + Field field = ReflectUtil.getField(target.getClass(), "url"); + field.setAccessible(true); + field.set(target, url); + } + } + + @Override + public void setEnvironment(Environment environment) { + this.environment = environment; + } +} diff --git a/start/src/main/java/cn/axzo/msg/center/MsgCenterConfig.java b/start/src/main/java/cn/axzo/msg/center/MsgCenterConfig.java index 6077f8e4..00f72b58 100644 --- a/start/src/main/java/cn/axzo/msg/center/MsgCenterConfig.java +++ b/start/src/main/java/cn/axzo/msg/center/MsgCenterConfig.java @@ -3,6 +3,8 @@ package cn.axzo.msg.center; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Configuration; +import static cn.axzo.msg.center.MsgCenterConfig.IM_CENTER; + /** * @author cn * @version 1.0 @@ -10,6 +12,8 @@ import org.springframework.context.annotation.Configuration; * @date 2023/5/30 11:33 */ @Configuration -@EnableFeignClients +@EnableFeignClients(basePackages = {IM_CENTER}) public class MsgCenterConfig { + + public static final String IM_CENTER = "cn.axzo.im.center.api.feign"; } From 0220a12b9dd80e10008bc4b79755aa75de828bb1 Mon Sep 17 00:00:00 2001 From: luofu Date: Fri, 20 Oct 2023 16:18:24 +0800 Subject: [PATCH 29/50] =?UTF-8?q?feat(REQ-1465):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=8F=91=E9=80=81=E6=99=AE=E9=80=9A=E6=B6=88=E6=81=AF=E5=8F=91?= =?UTF-8?q?=E9=80=81=E6=8E=A5=E5=8F=A3?= 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、对接IM的消息发送接口 影响: 无 --- .../impl/GeneralMessageServiceImpl.java | 6 +++--- .../service/enums/PushTerminalEnum.java | 4 ++-- .../java/cn/axzo/msg/center/FeignConfig.java | 21 +++++-------------- 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java index 1d720553..0a953830 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java @@ -54,7 +54,7 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { // 构建消息记录并存储 GeneralMessageRecord messageRecord = buildMessageRecord(request, template); generalMessageRecordDao.save(messageRecord); - // 推送 + // 异步推送 pushMessage(messageRecord, template); return messageRecord.getIdentityCode(); } @@ -62,7 +62,7 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { private GeneralMessageRecord buildMessageRecord(GeneralMessageSendRequest request, MessageTemplateDTO template) { return GeneralMessageRecord.builder() .identityCode(UUIDUtil.uuidString()) - .senderId(request.getSenderPersonId()) + .senderPersonId(request.getSenderPersonId()) .senderId(request.getSenderIdentity().getId()) .senderType(request.getSenderIdentity().getType()) .receiverPersonId(request.getReceiverPersonId()) @@ -91,7 +91,7 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { GeneralMessagePushDTO message = convert(record, template); MessageInfo msgInfo = new MessageInfo(); msgInfo.setAppTypeList(appTypes); - msgInfo.setPersonId(String.valueOf(record.getSenderPersonId())); + // TODO: [cold_blade] [P2] 第一期只支持发送机器人相关的消息 msgInfo.setToPersonIdList(Lists.newArrayList(String.valueOf(record.getReceiverPersonId()))); msgInfo.setMsgHeader(record.getTitle()); msgInfo.setMsgContent(record.getContent()); diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java index 834616a0..7bd7117c 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java @@ -18,11 +18,11 @@ public enum PushTerminalEnum { /** * B-安心筑企业版 */ - B_ENTERPRISE_APP("B-安心筑企业版", "ENTERPRISE"), + B_ENTERPRISE_APP("B-安心筑企业版", "CMP"), /** * C-安心筑工人版 */ - C_WORKER_APP("C-安心筑工人版", "WORKER"), + C_WORKER_APP("C-安心筑工人版", "CM"), ; private final String desc; diff --git a/start/src/main/java/cn/axzo/msg/center/FeignConfig.java b/start/src/main/java/cn/axzo/msg/center/FeignConfig.java index 08d1b731..363da982 100644 --- a/start/src/main/java/cn/axzo/msg/center/FeignConfig.java +++ b/start/src/main/java/cn/axzo/msg/center/FeignConfig.java @@ -1,18 +1,15 @@ package cn.axzo.msg.center; -import cn.hutool.core.util.ReflectUtil; import feign.RequestInterceptor; import feign.RequestTemplate; import feign.Target; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.EnvironmentAware; import org.springframework.context.annotation.Profile; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; -import java.lang.reflect.Field; import java.util.Map; import java.util.Objects; @@ -27,9 +24,6 @@ import java.util.Objects; public class FeignConfig implements RequestInterceptor, EnvironmentAware { private Environment environment; - @Value("${imCenterEngineEnvUrl:http://dev-app.axzo.cn/msg-center}") - private String imCenter; - private static String POD_NAMESPACE; static { @@ -44,18 +38,13 @@ public class FeignConfig implements RequestInterceptor, EnvironmentAware { @Override public void apply(RequestTemplate requestTemplate) { if (POD_NAMESPACE == null) { - Target.HardCodedTarget target = (Target.HardCodedTarget) requestTemplate.feignTarget(); - String url = requestTemplate.feignTarget().url(); - // 如需修改微服务地址,建议通过外部化参数来调整 - url = url.replace("http://im-center:8080", imCenter); + Target target = requestTemplate.feignTarget(); String profile = environment.getProperty("spring.profiles.active"); - if (Objects.equals(profile, "test") && url.contains("dev-app.axzo.cn")) { - url = url.replace("dev-app", "test-api"); + if (Objects.equals(profile, "dev")) { + requestTemplate.target("http://dev-app.axzo.cn/" + target.name()); + } else if (Objects.equals(profile, "test")) { + requestTemplate.target("http://test-api.axzo.cn/" + target.name()); } - requestTemplate.target(url); - Field field = ReflectUtil.getField(target.getClass(), "url"); - field.setAccessible(true); - field.set(target, url); } } From 035617254b71d06c3dab0cc56c9f02d347587ecc Mon Sep 17 00:00:00 2001 From: luofu Date: Sat, 21 Oct 2023 11:38:18 +0800 Subject: [PATCH 30/50] =?UTF-8?q?feat(REQ-1465):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=8F=91=E9=80=81=E6=99=AE=E9=80=9A=E6=B6=88=E6=81=AF=E5=8F=91?= =?UTF-8?q?=E9=80=81=E6=8E=A5=E5=8F=A3?= 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、对接IM的消息发送接口 影响: 无 --- .../domain/dto/GeneralMessagePushDTO.java | 87 ------- .../domain/dto/MessageTemplateDTO.java | 21 +- .../domain/dto/RawMessageRouterDTO.java | 11 + .../MessageTemplateSaveOrUpdateParam.java | 10 +- .../domain/vo/GeneralMessagePushVO.java | 214 ++++++++++++++++++ .../impl/GeneralMessageServiceImpl.java | 50 ++-- .../impl/MessageTemplateNewServiceImpl.java | 11 +- .../impl/PendingMessageNewServiceImpl.java | 2 +- .../axzo/msg/center/utils/JSONObjectUtil.java | 15 ++ .../msg/center/utils/MessageRouterUtil.java | 25 +- .../service/dto/MessageBaseTemplateDTO.java | 4 +- .../dto/MessageCardContentItemDTO.java | 46 ++++ .../service/dto/MessageRouterButtonDTO.java | 1 + .../service/dto/MessageRouterTerminalDTO.java | 7 + .../request/MessageTemplateCreateRequest.java | 5 +- .../request/MessageTemplateUpdateRequest.java | 5 +- .../MessageTemplateDetailResponse.java | 5 +- 17 files changed, 382 insertions(+), 137 deletions(-) delete mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GeneralMessagePushDTO.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/GeneralMessagePushVO.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageCardContentItemDTO.java diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GeneralMessagePushDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GeneralMessagePushDTO.java deleted file mode 100644 index fdb9959d..00000000 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/GeneralMessagePushDTO.java +++ /dev/null @@ -1,87 +0,0 @@ -package cn.axzo.msg.center.message.domain.dto; - -import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO; -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 java.io.Serializable; -import java.util.List; - -/** - * @author cold_blade - * @date 2023/10/19 - * @version 1.0 - */ -@Setter -@Getter -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class GeneralMessagePushDTO implements Serializable { - - private static final long serialVersionUID = -9017550674630922381L; - - /** - * 消息的唯一标识 - */ - private String identityCode; - /** - * 模板编码 - */ - private String templateCode; - /** - * 模板icon地址 - */ - private String templateIcon; - /** - * 消息标题 - */ - private String title; - /** - * 消息内容 - */ - private String content; - /** - * 卡片信息 - */ - private String cardContent; - /** - * 消息所属组织类型 - */ - private OrganizationTypeEnum orgType; - /** - * 消息所属组织Id - */ - private Long orgId; - /** - * 消息所属组织名称 - */ - private String orgName; - /** - * 业务编码 - */ - private String bizCode; - /** - * 消息发送时间戳 - */ - private Long sendTimestamp; - /** - * 路由信息,可为空 - */ - private List routers; - /** - * 参数及其对应的值的JSON串 - */ - private JSONObject routerParams; - - @Override - public String toString() { - return JSON.toJSONString(this); - } -} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageTemplateDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageTemplateDTO.java index d5f7551f..37e39d7e 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageTemplateDTO.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageTemplateDTO.java @@ -1,17 +1,23 @@ package cn.axzo.msg.center.message.domain.dto; 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.PushTerminalEnum; +import cn.axzo.msg.center.utils.JSONObjectUtil; 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.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @description @@ -46,9 +52,9 @@ public class MessageTemplateDTO implements Serializable { */ private String content; /** - * 卡片信息,json字串 + * 消息卡片信息标签列表 */ - private String cardContent; + private List msgCardContentItems; /** * 所属消息类型 */ @@ -76,7 +82,7 @@ public class MessageTemplateDTO implements Serializable { .code(baseTemplate.getCode()) .title(baseTemplate.getTitle()) .content(baseTemplate.getContent()) - .cardContent(baseTemplate.getCardContent()) + .msgCardContentItems(JSONObjectUtil.parseArray(baseTemplate.getCardContent(), MessageCardContentItemDTO.class)) .msgCategory(baseTemplate.getMsgCategory()) .icon(baseTemplate.getIcon()) .routers(routers) @@ -85,6 +91,15 @@ public class MessageTemplateDTO implements Serializable { .build(); } + public Map toCardContentMap() { + if (CollectionUtils.isEmpty(msgCardContentItems)) { + return Collections.emptyMap(); + } + Map map = new HashMap<>(); + msgCardContentItems.forEach(e -> map.put(e.getLabel(), e.getValue())); + return map; + } + @Override public String toString() { return JSON.toJSONString(this); diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java index 16bf0eae..d478c6be 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/RawMessageRouterDTO.java @@ -9,6 +9,7 @@ import cn.axzo.msg.center.service.enums.RouterCategoryEnum; import cn.axzo.msg.center.service.enums.TerminalTypeEnum; import cn.axzo.msg.center.utils.MessageRouterUtil; import com.alibaba.fastjson.JSON; +import com.google.common.collect.Lists; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -126,6 +127,16 @@ public class RawMessageRouterDTO implements Serializable { .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 public String toString() { return JSON.toJSONString(this); diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateSaveOrUpdateParam.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateSaveOrUpdateParam.java index c27944c1..baa17a8e 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateSaveOrUpdateParam.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/MessageTemplateSaveOrUpdateParam.java @@ -1,11 +1,11 @@ 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 cn.axzo.msg.center.utils.JSONObjectUtil; import com.alibaba.fastjson.JSON; import lombok.AllArgsConstructor; import lombok.Builder; @@ -59,9 +59,9 @@ public class MessageTemplateSaveOrUpdateParam implements Serializable { */ private String content; /** - * 卡片信息,json字串 + * 消息卡片信息标签列表 */ - private String cardContent; + private List msgCardContentItems; /** * 模板icon */ @@ -88,7 +88,7 @@ public class MessageTemplateSaveOrUpdateParam implements Serializable { .leafGroupNodes(request.getLeafGroupNodes()) .title(request.getMsgTitle()) .content(request.getMsgContent()) - .cardContent(JSONObjectUtil.checkAndReturn(request.getMsgCardInfo())) + .msgCardContentItems(request.getMsgCardContentItems()) .icon(request.getMsgIcon()) .operatorId(request.getOperatorId()) .routers(request.getRouters()) @@ -103,7 +103,7 @@ public class MessageTemplateSaveOrUpdateParam implements Serializable { .leafGroupNodes(request.getLeafGroupNodes()) .title(request.getMsgTitle()) .content(request.getMsgContent()) - .cardContent(JSONObjectUtil.checkAndReturn(request.getMsgCardInfo())) + .msgCardContentItems(request.getMsgCardContentItems()) .icon(request.getMsgIcon()) .operatorId(request.getOperatorId()) .routers(request.getRouters()) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/GeneralMessagePushVO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/GeneralMessagePushVO.java new file mode 100644 index 00000000..607a95c9 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/GeneralMessagePushVO.java @@ -0,0 +1,214 @@ +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 java.io.Serializable; +import java.util.Collections; +import java.util.List; +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 subtitles; + /** + * 消息内容 + */ + private String cardContent; + /** + * 卡片信息 + */ + private List cardExtension; + /** + * 按钮操作区域 + */ + private List cardButtons; + /** + * 业务编码 + */ + private String bizCode; + /** + * 消息发送时间戳 + */ + private Long sendTimestamp; + + public static GeneralMessagePushVO from(GeneralMessageRecord record, String templateIcon, String orgIcon, + List routerButtons, + List cardContentItems) { + CardButton cardDetailButton = CollectionUtils.isEmpty(routerButtons) ? null : routerButtons.stream() + .filter(e -> RouterCategoryEnum.DETAIL.equals(e.getCategory())) + .findFirst() + .map(CardButton::from) + .orElse(null); + List cardButtons = CollectionUtils.isEmpty(routerButtons) ? Collections.emptyList() : + routerButtons.stream() + .filter(e -> !RouterCategoryEnum.DETAIL.equals(e.getCategory())) + .map(CardButton::from) + .collect(Collectors.toList()); + List cardExtension = CollectionUtils.isEmpty(cardContentItems) ? Collections.emptyList() : + cardContentItems.stream() + .map(CardExtensionItem::from) + .collect(Collectors.toList()); + return GeneralMessagePushVO.builder() + .identityCode(record.getIdentityCode()) + .templateCode(record.getTemplateCode()) + .cardBannerUrl(templateIcon) + .cardTitle(record.getTitle()) + .cardDetailButton(cardDetailButton) + .subtitles(Lists.newArrayList(Subtitle.from(record, orgIcon))) + .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 Subtitle from(GeneralMessageRecord record, String orgIcon) { + return 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 List actionPaths; + + static CardButton from(MessageRouterButtonDTO routerButton) { + return CardButton.builder() + .title(routerButton.getDesc()) + .action(routerButton.getCategory().name()) + .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); + } + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java index 0a953830..ac202bfb 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java @@ -6,11 +6,12 @@ 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.message.domain.dto.GeneralMessagePushDTO; 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.vo.GeneralMessagePushVO; import cn.axzo.msg.center.message.service.GeneralMessageService; import cn.axzo.msg.center.message.service.MessageTemplateNewService; +import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO; import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO; import cn.axzo.msg.center.service.enums.GeneralMessageStateEnum; import cn.axzo.msg.center.service.enums.PushTerminalEnum; @@ -23,7 +24,6 @@ import com.google.common.collect.Lists; 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.HashMap; @@ -42,6 +42,8 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class GeneralMessageServiceImpl implements GeneralMessageService { + private final String orgIcon = "www.baidu.com"; + private final MessageApi messageApi; private final MessageTemplateNewService messageTemplateNewService; private final GeneralMessageRecordDao generalMessageRecordDao; @@ -88,7 +90,7 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { } List appTypes = template.getPushTerminals().stream() .map(PushTerminalEnum::getImTerminalFlag).collect(Collectors.toList()); - GeneralMessagePushDTO message = convert(record, template); + GeneralMessagePushVO message = convert(record, template); MessageInfo msgInfo = new MessageInfo(); msgInfo.setAppTypeList(appTypes); // TODO: [cold_blade] [P2] 第一期只支持发送机器人相关的消息 @@ -105,35 +107,33 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { messageApi.sendMessage(msgInfo); } - private GeneralMessagePushDTO convert(GeneralMessageRecord record, MessageTemplateDTO template) { + private GeneralMessagePushVO convert(GeneralMessageRecord record, MessageTemplateDTO template) { // 对应模板的路由列表 List rawRouters = template.getRouters(); - // 视情况替换原始URL中的参数变量 - rawRouters.forEach(e -> MessageRouterUtil.parseRouteUrl(e, record.getRouterParams())); + // 解析路由地址 + List routers = rawRouters.stream() + .map(e -> MessageRouterUtil.parseAndConcatRouteUrl(e, record.getRouterParams())) + .collect(Collectors.toList()); // 转化成客户端展示的数据模型 - List routerButtons = rawRouters.stream() + List routerButtons = routers.stream() .map(RawMessageRouterDTO::toMessageRouterButton) .collect(Collectors.toList()); // 获取模板卡片信息 - String cardContent = template.getCardContent(); - if (StringUtils.isNotBlank(cardContent)) { - cardContent = PlaceholderResolver.getDefaultResolver().resolveByMap(cardContent, record.getBizExtParams()); + List rawCardContentItems = template.getMsgCardContentItems(); + List 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 GeneralMessagePushDTO.builder() - .identityCode(record.getIdentityCode()) - .templateCode(template.getCode()) - .templateIcon(template.getIcon()) - .title(record.getTitle()) - .content(record.getContent()) - .cardContent(cardContent) - .orgType(record.getOrgType()) - .orgId(record.getOrgId()) - .orgName(record.getOrgName()) - .bizCode(record.getBizCode()) - .sendTimestamp(System.currentTimeMillis()) - .routers(routerButtons) - .routerParams(record.getRouterParams()) - .build(); + return GeneralMessagePushVO.from(record, template.getIcon(), orgIcon, routerButtons, cardContentItems); } private String parseString(String string, JSONObject params) { 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 0dbf7c79..5191441d 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 @@ -16,6 +16,7 @@ import cn.axzo.msg.center.message.service.MessageTemplateGroupService; import cn.axzo.msg.center.message.service.MessageTemplateNewService; 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; @@ -311,7 +312,7 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService template.setMsgCategory(param.getMsgCategory()); template.setTitle(param.getTitle()); template.setContent(param.getContent()); - template.setCardContent(JSONObjectUtil.checkAndReturn(param.getCardContent())); + template.setCardContent(JSONObjectUtil.toJSONString(param.getMsgCardContentItems())); template.setIcon(param.getIcon()); template.setPushTerminal(JSONObjectUtil.toJSONString(param.getPushTerminals())); template.setCreatorId(param.getOperatorId()); @@ -339,8 +340,8 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService .set(CollectionUtils.isNotEmpty(param.getPushTerminals()), MessageBaseTemplate::getPushTerminal, JSON.toJSONString(param.getPushTerminals())) .set(StringUtils.isNotBlank(param.getTitle()), MessageBaseTemplate::getTitle, param.getTitle()) - .set(StringUtils.isNotBlank(param.getCardContent()), MessageBaseTemplate::getCardContent, - param.getCardContent()) + .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(); @@ -367,7 +368,7 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService .msgCategory(record.getMsgCategory()) .title(record.getTitle()) .content(record.getContent()) - .cardContent(record.getCardContent()) + .cardContentItems(JSONObjectUtil.parseArray(record.getCardContent(), MessageCardContentItemDTO.class)) .icon(record.getIcon()) .pushTerminals(JSON.parseArray(record.getPushTerminal(), PushTerminalEnum.class)) .createTimestamp(record.getCreateAt().getTime()) @@ -408,7 +409,7 @@ public class MessageTemplateNewServiceImpl implements MessageTemplateNewService .pushTerminals(JSON.parseArray(record.getPushTerminal(), PushTerminalEnum.class)) .msgTitle(record.getTitle()) .msgContent(record.getContent()) - .msgCardInfo(record.getCardContent()) + .cardContentItems(JSONObjectUtil.parseArray(record.getCardContent(), MessageCardContentItemDTO.class)) .msgIcon(record.getIcon()) .routers(routerButtons) .createTimestamp(record.getCreateAt().getTime()) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java index 027e62d8..7253c6b6 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java @@ -185,7 +185,7 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService { String cardContent = messageTemplates.stream() .filter(e -> Objects.equals(e.getCode(), pendingMessageRecord.getTemplateCode())) .findFirst() - .map(MessageTemplateDTO::getCardContent) + .map(e -> JSON.toJSONString(e.toCardContentMap())) .orElse(null); if (StringUtils.isNotBlank(cardContent) && StringUtils.isNotBlank(pendingMessageRecord.getRouterParams())) { cardContent = PlaceholderResolver.getDefaultResolver() diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/utils/JSONObjectUtil.java b/inside-notices/src/main/java/cn/axzo/msg/center/utils/JSONObjectUtil.java index a5770691..b84d2992 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/utils/JSONObjectUtil.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/utils/JSONObjectUtil.java @@ -8,6 +8,8 @@ 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; /** @@ -34,6 +36,19 @@ public final class JSONObjectUtil { return JSON.parseObject(str); } + /** + * 解析JSON字符串,若字符串格式不正确,抛异常 + * + * @param str 待解析的字符串 + * @return List + */ + public static List parseArray(String str, Class 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; diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java b/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java index 3e75c0b2..0b370d57 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java @@ -15,6 +15,7 @@ import org.apache.commons.lang3.StringUtils; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; @@ -96,20 +97,38 @@ public final class MessageRouterUtil { } /** - * 解析模板上配置的路由地址,并将发送消息时的参数替换上去 + * 解析模板上配置的路由地址,将发送消息时的参数替换上去,并将路由参数追加到模板的路由地址后面,兼容APP端新老版本 * * @param router 路由信息 * @param routerParam 路由参数 + * @return RawMessageRouterDTO */ - public static void parseRouteUrl(RawMessageRouterDTO router, JSONObject routerParam) { + public static RawMessageRouterDTO parseAndConcatRouteUrl(RawMessageRouterDTO router, JSONObject routerParam) { // 路由参数有效 - if (Objects.nonNull(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); }); } + return router; + } + + private static String concatRouterParam(String originalUrl, JSONObject routerParam) { + StringBuilder concatUrlBuilder = new StringBuilder(originalUrl); + if (!originalUrl.contains("?")) { + concatUrlBuilder.append("?"); + } + + for (Map.Entry entry : routerParam.entrySet()) { + concatUrlBuilder.append("&").append(entry.getKey()).append("=").append(entry.getValue()); + } + return concatUrlBuilder.toString(); } /** diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageBaseTemplateDTO.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageBaseTemplateDTO.java index 521e9405..61a730d6 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageBaseTemplateDTO.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageBaseTemplateDTO.java @@ -47,9 +47,9 @@ public class MessageBaseTemplateDTO implements Serializable { */ private String content; /** - * 卡片信息,json字串 + * 卡片信息标签列表 */ - private String cardContent; + private List cardContentItems; /** * 模板icon */ diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageCardContentItemDTO.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageCardContentItemDTO.java new file mode 100644 index 00000000..0f01379e --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageCardContentItemDTO.java @@ -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); + } +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java index fef15deb..f6490a70 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java @@ -36,6 +36,7 @@ public class MessageRouterButtonDTO implements Serializable { * 路由分类 * JUMP: 直接跳转 * ACTION: 接口调用 + * DETAIL: 页面详情 */ private RouterCategoryEnum category; /** diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterTerminalDTO.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterTerminalDTO.java index b4769b3a..a660b78c 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterTerminalDTO.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterTerminalDTO.java @@ -39,6 +39,13 @@ public class MessageRouterTerminalDTO implements Serializable { */ private TerminalTypeEnum terminalType; + public MessageRouterTerminalDTO deepClone() { + return MessageRouterTerminalDTO.builder() + .terminalType(this.terminalType) + .url(this.url) + .build(); + } + @Override public String toString() { return JSON.toJSONString(this); diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java index 1241a76c..6699b9ab 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateCreateRequest.java @@ -1,5 +1,6 @@ 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.MessageCategoryEnum; import cn.axzo.msg.center.service.enums.PushTerminalEnum; @@ -60,9 +61,9 @@ public class MessageTemplateCreateRequest implements Serializable { @NotBlank(message = "msgTitle is required") private String msgTitle; /** - * 消息卡片信息,JSON字串 + * 消息卡片信息标签列表,可为空 */ - private String msgCardInfo; + private List msgCardContentItems; /** * 消息内容 */ diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java index d0e8429d..92020c2b 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/request/MessageTemplateUpdateRequest.java @@ -1,5 +1,6 @@ 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; @@ -53,9 +54,9 @@ public class MessageTemplateUpdateRequest implements Serializable { */ private String msgTitle; /** - * 消息卡片信息,JSON字串 + * 消息卡片信息标签列表 */ - private String msgCardInfo; + private List msgCardContentItems; /** * 消息内容 */ diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java index 9299d1f3..74fb8806 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/template/response/MessageTemplateDetailResponse.java @@ -1,5 +1,6 @@ package cn.axzo.msg.center.service.template.response; +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; @@ -53,9 +54,9 @@ public class MessageTemplateDetailResponse implements Serializable { */ private String msgTitle; /** - * 消息卡片信息,JSON字串 + * 卡片信息标签列表 */ - private String msgCardInfo; + private List cardContentItems; /** * 消息内容 */ From 9ea4d9413542106e9f4738216562cf92cbd5e9f4 Mon Sep 17 00:00:00 2001 From: luofu Date: Sat, 21 Oct 2023 16:26:56 +0800 Subject: [PATCH 31/50] =?UTF-8?q?feat(REQ-1465):=20IM=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=AE=9A=E4=B9=89?= 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、IM数据格式定义 影响: 无 --- .../message/domain/vo/GeneralMessagePushVO.java | 6 ++++++ .../service/impl/GeneralMessageServiceImpl.java | 3 ++- .../center/service/dto/MessageRouterButtonDTO.java | 11 +++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/GeneralMessagePushVO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/GeneralMessagePushVO.java index 607a95c9..14369b77 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/GeneralMessagePushVO.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/GeneralMessagePushVO.java @@ -88,6 +88,7 @@ public class GeneralMessagePushVO implements Serializable { List 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 cardExtension = CollectionUtils.isEmpty(cardContentItems) ? Collections.emptyList() : @@ -158,6 +159,10 @@ public class GeneralMessagePushVO implements Serializable { * 按钮操作类型: JUMP - 页面跳转, ACTION - 接口调用 */ private String action; + /** + * 按钮样式 + */ + private Boolean isHighlight; /** * 按钮点击后的跳转地址 */ @@ -167,6 +172,7 @@ public class GeneralMessagePushVO implements Serializable { 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()) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java index ac202bfb..6e99cd94 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java @@ -42,7 +42,8 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class GeneralMessageServiceImpl implements GeneralMessageService { - private final String orgIcon = "www.baidu.com"; + // TODO:[cold_blade] [P2] 图片icon的最好配置在nacos上 + private final String orgIcon = "https://axzo-pro.oss-cn-hangzhou.aliyuncs.com/rs_app/ic_org_icon.png"; private final MessageApi messageApi; private final MessageTemplateNewService messageTemplateNewService; diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java index f6490a70..a4bd8e0d 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/MessageRouterButtonDTO.java @@ -8,6 +8,7 @@ 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; @@ -50,6 +51,16 @@ public class MessageRouterButtonDTO implements Serializable { */ private List 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); From 19812ec3d3ed098842f63e1ef39b61939ba8f809 Mon Sep 17 00:00:00 2001 From: luofu Date: Mon, 23 Oct 2023 20:07:09 +0800 Subject: [PATCH 32/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E5=8F=8C=E5=8F=91=E5=8A=9F=E8=83=BD=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、消息双发功能实现 影响: 无 --- .../impl/MessageRecordServiceImpl.java | 15 ++- .../impl/RawMessageRecordServiceImpl.java | 2 - .../controller/GeneralMessageController.java | 2 +- .../service/GeneralMessageMapperService.java | 29 +++++ .../service/GeneralMessageService.java | 4 +- .../MessageSendTwiceRecordService.java | 21 +++ .../service/RelationTemplateMapService.java | 18 +++ .../impl/GeneralMessageMapperServiceImpl.java | 123 ++++++++++++++++++ .../impl/GeneralMessageServiceImpl.java | 50 ++++--- .../MessageSendTwiceRecordServiceImpl.java | 61 +++++++++ .../impl/RelationTemplateMapServiceImpl.java | 64 +++++++++ .../msg/center/utils/PersonIdentityUtil.java | 48 +++++++ .../service/enums/PushTerminalEnum.java | 5 +- .../request/GeneralMessageSendRequest.java | 26 ++-- .../center/dal/MessageSendTwiceRecordDao.java | 18 +++ .../center/dal/RelationTemplateMapDao.java | 18 +++ .../mapper/MessageSendTwiceRecordMapper.java | 12 ++ .../dal/mapper/RelationTemplateMapMapper.java | 12 ++ .../domain/entity/MessageSendTwiceRecord.java | 36 +++++ .../domain/entity/RelationTemplateMap.java | 36 +++++ 20 files changed, 555 insertions(+), 45 deletions(-) create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageMapperService.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageSendTwiceRecordService.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/RelationTemplateMapService.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageMapperServiceImpl.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageSendTwiceRecordServiceImpl.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/RelationTemplateMapServiceImpl.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java create mode 100644 msg-center-dal/src/main/java/cn/axzo/msg/center/dal/MessageSendTwiceRecordDao.java create mode 100644 msg-center-dal/src/main/java/cn/axzo/msg/center/dal/RelationTemplateMapDao.java create mode 100644 msg-center-dal/src/main/java/cn/axzo/msg/center/dal/mapper/MessageSendTwiceRecordMapper.java create mode 100644 msg-center-dal/src/main/java/cn/axzo/msg/center/dal/mapper/RelationTemplateMapMapper.java create mode 100644 msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageSendTwiceRecord.java create mode 100644 msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/RelationTemplateMap.java diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRecordServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRecordServiceImpl.java index 77d4b860..6d0addaa 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRecordServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRecordServiceImpl.java @@ -28,6 +28,7 @@ import cn.axzo.msg.center.domain.enums.*; import cn.axzo.msg.center.domain.request.InsideCmsReadMsgReq; import cn.axzo.msg.center.inside.notices.event.SendMessageEvent; import cn.axzo.msg.center.inside.notices.service.MessageRecordService; +import cn.axzo.msg.center.message.service.GeneralMessageMapperService; import cn.azxo.framework.common.utils.LogUtil; import cn.azxo.framework.common.utils.LogUtil.ErrorLevel; import cn.azxo.framework.common.utils.LogUtil.ErrorType; @@ -37,6 +38,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.metadata.IPage; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.text.StrSubstitutor; import org.springframework.beans.factory.annotation.Value; @@ -84,6 +86,9 @@ public class MessageRecordServiceImpl implements MessageRecordService { /*@Resource private IdentityProfileService identityProfileService;*/ + @Resource + private GeneralMessageMapperService generalMessageMapperService; + /** * 新增推送消息接口 * @@ -132,10 +137,11 @@ public class MessageRecordServiceImpl implements MessageRecordService { List pushMessages = new ArrayList<>(); Lists.partition(Lists.newArrayList(message.getToId()), partitionSize).forEach(toIds -> { - List messageRecords = saveBatch(basic, toIds, message.getToldIdPersonIdMap()); + Map toIdRecordMap = Maps.newHashMap(); + List messageRecords = saveBatch(basic, toIds, message.getToldIdPersonIdMap(), toIdRecordMap); + generalMessageMapperService.asyncBatchSendMessage(message, toIds, toIdRecordMap); pushMessages.addAll(messageRecords); }); - if(pushAthena) { asyncPushAthena(message, messageTemplate.getAudioFileName(), messageModule.getModuleName(), pushMessages); } @@ -158,7 +164,8 @@ public class MessageRecordServiceImpl implements MessageRecordService { @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) - public List saveBatch(MessageRecord basic, List toIds, Map toldIdPersonIdMap) { + public List saveBatch(MessageRecord basic, List toIds, Map toldIdPersonIdMap, + Map toIdRecordMap) { if (CollectionUtils.isEmpty(toIds)) { return Collections.emptyList(); } @@ -172,6 +179,7 @@ public class MessageRecordServiceImpl implements MessageRecordService { messageRecord.setToId(0L); messageRecord.setPersonId(i); pushMessages.add(messageRecord); + toIdRecordMap.put(i, messageRecord); }); } else { toIds.forEach(i -> { @@ -183,6 +191,7 @@ public class MessageRecordServiceImpl implements MessageRecordService { messageRecord.setPersonId(toldIdPersonIdMap.get(i)); } pushMessages.add(messageRecord); + toIdRecordMap.put(i, messageRecord); }); } messageRecordDao.saveBatch(pushMessages); diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/RawMessageRecordServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/RawMessageRecordServiceImpl.java index 422099cd..0e45686b 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/RawMessageRecordServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/RawMessageRecordServiceImpl.java @@ -44,11 +44,9 @@ import java.util.function.Function; import java.util.stream.Collectors; /** - * @description xxx * @author cold_blade * @date 2023/9/13 * @version 1.0 - * TODO: [cold_blade]待优化 */ @Slf4j @Service diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java index 0f25e885..3ea0b329 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java @@ -22,6 +22,6 @@ public class GeneralMessageController implements GeneralMessageClient { @Override public CommonResponse sendMessage(GeneralMessageSendRequest request) { - return CommonResponse.success(generalMessageService.sendMessage(request)); + return CommonResponse.success(generalMessageService.batchSendMessage(request)); } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageMapperService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageMapperService.java new file mode 100644 index 00000000..7033f110 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageMapperService.java @@ -0,0 +1,29 @@ +package cn.axzo.msg.center.message.service; + +import cn.axzo.msg.center.api.request.GeneralMessageReq; +import cn.axzo.msg.center.domain.entity.MessageRecord; +import cn.axzo.msg.center.service.dto.PersonDTO; + +import java.util.List; +import java.util.Map; + +/** + * 新老版本消息映射的相关接口 + * + * @author cold_blade + * @date 2023/10/23 + * @version 1.0 + */ +public interface GeneralMessageMapperService { + + /** + * 异步批量发送消息 + * + * @param request 发送消息时的请求参数 + * @param subReceiverIds 接收者id列表 + * @param toIdMessageRecordMap 接收者身份id与旧消息记录的映射关系 + * @return 批量发送消息请求的requestId + */ + String asyncBatchSendMessage(GeneralMessageReq request, List subReceiverIds, + Map toIdMessageRecordMap); +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java index 29ca9089..7f6a98c6 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java @@ -13,7 +13,7 @@ public interface GeneralMessageService { * 发送消息 * * @param request 消息所需参数 - * @return 消息的唯一标识 + * @return 请求的唯一标识 */ - String sendMessage(GeneralMessageSendRequest request); + String batchSendMessage(GeneralMessageSendRequest request); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageSendTwiceRecordService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageSendTwiceRecordService.java new file mode 100644 index 00000000..144c6c4e --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageSendTwiceRecordService.java @@ -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 listByPerson(Long personId); + + void batchSave(Map msgRecordIdPersonIdMap); +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/RelationTemplateMapService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/RelationTemplateMapService.java new file mode 100644 index 00000000..2210cbcc --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/RelationTemplateMapService.java @@ -0,0 +1,18 @@ +package cn.axzo.msg.center.message.service; + +import java.util.Map; +import java.util.Optional; + +/** + * 新老模板的关联关系service + * + * @author cold_blade + * @date 2023/10/23 + * @version 1.0 + */ +public interface RelationTemplateMapService { + + Optional queryByRelationId(Long relationId); + + void mapRelationAndTemplate(Map map); +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageMapperServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageMapperServiceImpl.java new file mode 100644 index 00000000..cf7e1e67 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageMapperServiceImpl.java @@ -0,0 +1,123 @@ +package cn.axzo.msg.center.message.service.impl; + +import cn.axzo.msg.center.api.enums.MsgTypeEnum; +import cn.axzo.msg.center.api.request.GeneralMessageReq; +import cn.axzo.msg.center.domain.entity.MessageRecord; +import cn.axzo.msg.center.message.service.GeneralMessageMapperService; +import cn.axzo.msg.center.message.service.GeneralMessageService; +import cn.axzo.msg.center.message.service.MessageSendTwiceRecordService; +import cn.axzo.msg.center.message.service.RelationTemplateMapService; +import cn.axzo.msg.center.service.dto.PersonDTO; +import cn.axzo.msg.center.service.enums.IdentityTypeEnum; +import cn.axzo.msg.center.service.enums.OrganizationTypeEnum; +import cn.axzo.msg.center.service.general.request.GeneralMessageSendRequest; +import cn.axzo.msg.center.utils.PersonIdentityUtil; +import cn.axzo.msg.center.utils.UUIDUtil; +import cn.hutool.core.map.MapUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import jodd.util.concurrent.ThreadFactoryBuilder; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * @author cold_blade + * @date 2023/10/23 + * @version 1.0 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class GeneralMessageMapperServiceImpl implements GeneralMessageMapperService { + + private final ThreadFactory asyncSendMsgThreadFactory = ThreadFactoryBuilder.create() + .setDaemon(true).setNameFormat("ASYNC_SEND_IM_MESSAGE_%d").get(); + private final ExecutorService asyncSendMsgExecutorService = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, + new ArrayBlockingQueue<>(1024), asyncSendMsgThreadFactory); + + private final GeneralMessageService generalMessageService; + private final RelationTemplateMapService relationTemplateMapService; + private final MessageSendTwiceRecordService messageSendTwiceRecordService; + + @Override + @Transactional(rollbackFor = Exception.class) + public String asyncBatchSendMessage(GeneralMessageReq request, List subReceiverIds, + Map toIdMessageRecordMap) { + if (MsgTypeEnum.PENDING_MESSAGE.equals(request.getType())) { + log.info("pending message is not supported."); + return UUIDUtil.uuidRawString(); + } + if (Objects.isNull(request.getRelationId()) || MapUtil.isEmpty(request.getToldIdPersonIdMap())) { + log.info("param is invalid. relationId:[{}], toIdPersonIdMap:{}", request.getRelationId(), + request.getToldIdPersonIdMap()); + return UUIDUtil.uuidRawString(); + } + Optional identityTypeOp = PersonIdentityUtil.toIdentityType(request.getReceiveType()); + if (!identityTypeOp.isPresent()) { + log.info("identity is invalid. relationId:[{}], receiveType:{}", request.getRelationId(), + request.getReceiveType()); + return UUIDUtil.uuidRawString(); + } + // 异步发送IM消息 + CompletableFuture.runAsync(() -> doBatchSendMessage(request, subReceiverIds, toIdMessageRecordMap, + identityTypeOp.get()), asyncSendMsgExecutorService); + return UUIDUtil.uuidRawString(); + } + + private void doBatchSendMessage(GeneralMessageReq request, List subReceiverIds, + Map toIdMessageRecordMap, IdentityTypeEnum identityType) { + String templateCode = relationTemplateMapService.queryByRelationId(request.getRelationId()).orElse(null); + if (StringUtils.isBlank(templateCode)) { + log.info("the relationId([{}]) is not map any new message template. ", request.getRelationId()); + return; + } + log.info("start to send im message. relationId:[{}]", request.getRelationId()); + Map msgRecordIdPersonIdMap = toIdMessageRecordMap.entrySet().stream() + .filter(e -> request.getToldIdPersonIdMap().containsKey(e.getKey())) + .collect(Collectors.toMap(e -> e.getValue().getId(), e -> request.getToldIdPersonIdMap().get(e.getKey()))); + log.info("message send twice. relationId:[{}], msgIds:{}", request.getRelationId(), msgRecordIdPersonIdMap.values()); + // 双发记录 + messageSendTwiceRecordService.batchSave(msgRecordIdPersonIdMap); + // 发送IM消息 + generalMessageService.batchSendMessage(convert(request, templateCode, subReceiverIds, identityType)); + } + + private GeneralMessageSendRequest convert(GeneralMessageReq request, String templateCode, + List subReceiverIds, IdentityTypeEnum identityType) { + List 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(); + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java index 6e99cd94..0812a6cd 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java @@ -2,6 +2,7 @@ package cn.axzo.msg.center.message.service.impl; import cn.axzo.im.center.api.feign.MessageApi; import cn.axzo.im.center.api.vo.req.MessageInfo; +import cn.axzo.im.center.common.enums.AppTypeEnum; import cn.axzo.msg.center.common.exception.ServiceException; import cn.axzo.msg.center.common.utils.PlaceholderResolver; import cn.axzo.msg.center.dal.GeneralMessageRecordDao; @@ -13,6 +14,7 @@ import cn.axzo.msg.center.message.service.GeneralMessageService; import cn.axzo.msg.center.message.service.MessageTemplateNewService; import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO; import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO; +import cn.axzo.msg.center.service.dto.PersonDTO; import cn.axzo.msg.center.service.enums.GeneralMessageStateEnum; import cn.axzo.msg.center.service.enums.PushTerminalEnum; import cn.axzo.msg.center.service.general.request.GeneralMessageSendRequest; @@ -20,6 +22,7 @@ import cn.axzo.msg.center.utils.MessageRouterUtil; import cn.axzo.msg.center.utils.UUIDUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -42,6 +45,11 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class GeneralMessageServiceImpl implements GeneralMessageService { + private static final ImmutableMap PUSH_TERMINAL_APP_MAP = ImmutableMap.of( + PushTerminalEnum.B_ENTERPRISE_APP, AppTypeEnum.CMP, + PushTerminalEnum.C_WORKER_APP, AppTypeEnum.CM + ); + // TODO:[cold_blade] [P2] 图片icon的最好配置在nacos上 private final String orgIcon = "https://axzo-pro.oss-cn-hangzhou.aliyuncs.com/rs_app/ic_org_icon.png"; @@ -50,27 +58,34 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { private final GeneralMessageRecordDao generalMessageRecordDao; @Override - public String sendMessage(GeneralMessageSendRequest request) { + public String batchSendMessage(GeneralMessageSendRequest request) { // 查询模板基础信息 MessageTemplateDTO template = messageTemplateNewService.queryByTemplateCode(request.getTemplateCode()) .orElseThrow(() -> new ServiceException("未查询到对应的模板")); // 构建消息记录并存储 - GeneralMessageRecord messageRecord = buildMessageRecord(request, template); - generalMessageRecordDao.save(messageRecord); + List messageRecords = buildMessageRecord(request, template); + generalMessageRecordDao.saveBatch(messageRecords); // 异步推送 - pushMessage(messageRecord, template); - return messageRecord.getIdentityCode(); + pushMessage(messageRecords, template); + return UUIDUtil.uuidRawString(); } - private GeneralMessageRecord buildMessageRecord(GeneralMessageSendRequest request, MessageTemplateDTO template) { + private List buildMessageRecord(GeneralMessageSendRequest request, MessageTemplateDTO template) { + return request.getReceiver().stream() + .map(e -> buildMessageRecord(request, e, template)) + .collect(Collectors.toList()); + } + + private GeneralMessageRecord buildMessageRecord(GeneralMessageSendRequest request, PersonDTO receiver, + MessageTemplateDTO template) { return GeneralMessageRecord.builder() .identityCode(UUIDUtil.uuidString()) - .senderPersonId(request.getSenderPersonId()) - .senderId(request.getSenderIdentity().getId()) - .senderType(request.getSenderIdentity().getType()) - .receiverPersonId(request.getReceiverPersonId()) - .receiverId(request.getReceiverIdentity().getId()) - .receiverType(request.getReceiverIdentity().getType()) + .senderPersonId(request.getSender().getId()) + .senderId(request.getSender().getIdentity().getId()) + .senderType(request.getSender().getIdentity().getType()) + .receiverPersonId(receiver.getId()) + .receiverId(receiver.getIdentity().getId()) + .receiverType(receiver.getIdentity().getType()) .templateCode(template.getCode()) .title(parseString(template.getTitle(), request.getBizExtParams())) .content(parseString(template.getContent(), request.getBizExtParams())) @@ -84,18 +99,21 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { .build(); } - private void pushMessage(GeneralMessageRecord record, MessageTemplateDTO template) { + private void pushMessage(List messageRecords, MessageTemplateDTO template) { if (CollectionUtils.isEmpty(template.getPushTerminals())) { // 模板未配置任何推送终端 return; } - List appTypes = template.getPushTerminals().stream() - .map(PushTerminalEnum::getImTerminalFlag).collect(Collectors.toList()); + GeneralMessageRecord record = messageRecords.get(0); + List appTypes = template.getPushTerminals().stream() + .map(PUSH_TERMINAL_APP_MAP::get).collect(Collectors.toList()); GeneralMessagePushVO message = convert(record, template); MessageInfo msgInfo = new MessageInfo(); msgInfo.setAppTypeList(appTypes); // TODO: [cold_blade] [P2] 第一期只支持发送机器人相关的消息 - msgInfo.setToPersonIdList(Lists.newArrayList(String.valueOf(record.getReceiverPersonId()))); + msgInfo.setToPersonIdList(Lists.newArrayList(messageRecords.stream() + .map(e -> String.valueOf(e.getReceiverPersonId())) + .collect(Collectors.toSet()))); msgInfo.setMsgHeader(record.getTitle()); msgInfo.setMsgContent(record.getContent()); msgInfo.setMsgTemplateId(record.getTemplateCode()); diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageSendTwiceRecordServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageSendTwiceRecordServiceImpl.java new file mode 100644 index 00000000..093dccdc --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageSendTwiceRecordServiceImpl.java @@ -0,0 +1,61 @@ +package cn.axzo.msg.center.message.service.impl; + +import cn.axzo.msg.center.common.enums.TableIsDeleteEnum; +import cn.axzo.msg.center.dal.MessageSendTwiceRecordDao; +import cn.axzo.msg.center.domain.entity.MessageSendTwiceRecord; +import cn.axzo.msg.center.message.service.MessageSendTwiceRecordService; +import cn.hutool.core.map.MapUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @description xxx + * @author cold_blade + * @date 2023/10/23 + * @version 1.0 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class MessageSendTwiceRecordServiceImpl implements MessageSendTwiceRecordService { + + private final MessageSendTwiceRecordDao messageSendTwiceRecordDao; + + @Override + public List listByPerson(Long personId) { + if (Objects.isNull(personId)) { + log.info("personId is null."); + return Collections.emptyList(); + } + // TODO:[cold_blade] [P2] 此处的代码仅做一个双发兜底的策略,后期应当全走新的消息发送流程 + return messageSendTwiceRecordDao.lambdaQuery() + .eq(MessageSendTwiceRecord::getReceiverPersonId, personId) + .eq(MessageSendTwiceRecord::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .select(MessageSendTwiceRecord::getOriginalMsgId) + .list().stream() + .map(MessageSendTwiceRecord::getOriginalMsgId) + .collect(Collectors.toList()); + } + + @Override + public void batchSave(Map msgRecordIdPersonIdMap) { + if (MapUtil.isEmpty(msgRecordIdPersonIdMap)) { + return; + } + List 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); + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/RelationTemplateMapServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/RelationTemplateMapServiceImpl.java new file mode 100644 index 00000000..bcd4f513 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/RelationTemplateMapServiceImpl.java @@ -0,0 +1,64 @@ +package cn.axzo.msg.center.message.service.impl; + +import cn.axzo.msg.center.common.enums.TableIsDeleteEnum; +import cn.axzo.msg.center.dal.RelationTemplateMapDao; +import cn.axzo.msg.center.domain.entity.RelationTemplateMap; +import cn.axzo.msg.center.message.service.RelationTemplateMapService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * 新老模板映射关系service + * + * @author cold_blade + * @date 2023/10/23 + * @version 1.0 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class RelationTemplateMapServiceImpl implements RelationTemplateMapService { + + private final RelationTemplateMapDao relationTemplateMapDao; + + @Override + public Optional 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 map) { + if (Objects.isNull(map) || map.isEmpty()) { + return; + } + relationTemplateMapDao.lambdaUpdate() + .in(RelationTemplateMap::getOriginalRelationId, map.keySet()) + .eq(RelationTemplateMap::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .remove(); + List 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); + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java b/inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java new file mode 100644 index 00000000..7cec1cb7 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java @@ -0,0 +1,48 @@ +package cn.axzo.msg.center.utils; + +import cn.axzo.msg.center.api.enums.ReceiveTypeEnum; +import cn.axzo.msg.center.service.enums.IdentityTypeEnum; +import cn.axzo.pudge.core.service.ServiceException; + +import java.util.Objects; +import java.util.Optional; + +/** + * @description xxx + * @author cold_blade + * @date 2023/10/23 + * @version 1.0 + */ +public class PersonIdentityUtil { + + public static ReceiveTypeEnum receiveType(Integer identityTypeCode) { + IdentityTypeEnum identityType = IdentityTypeEnum.codeOf(identityTypeCode) + .orElseThrow(() -> new ServiceException("档案身份类型不匹配 code:" + identityTypeCode)); + switch (identityType) { + case WORKER: + return ReceiveTypeEnum.CM_WORKER; + case WORKER_LEADER: + return ReceiveTypeEnum.CM_LEADER; + case PRACTITIONER: + return ReceiveTypeEnum.CMP_USER; + default: + return ReceiveTypeEnum.NOT_IDENTITY; + } + } + + public static Optional toIdentityType(ReceiveTypeEnum receiveType) { + if (Objects.isNull(receiveType)) { + return Optional.empty(); + } + switch (receiveType) { + case CM_WORKER: + return Optional.of(IdentityTypeEnum.WORKER); + case CM_LEADER: + return Optional.of(IdentityTypeEnum.WORKER_LEADER); + case CMP_USER: + return Optional.of(IdentityTypeEnum.PRACTITIONER); + default: + return Optional.empty(); + } + } +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java index 7bd7117c..c52deaf6 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java @@ -18,13 +18,12 @@ public enum PushTerminalEnum { /** * B-安心筑企业版 */ - B_ENTERPRISE_APP("B-安心筑企业版", "CMP"), + B_ENTERPRISE_APP("B-安心筑企业版"), /** * C-安心筑工人版 */ - C_WORKER_APP("C-安心筑工人版", "CM"), + C_WORKER_APP("C-安心筑工人版"), ; private final String desc; - private final String imTerminalFlag; } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/request/GeneralMessageSendRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/request/GeneralMessageSendRequest.java index 3fa18cda..74595539 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/request/GeneralMessageSendRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/request/GeneralMessageSendRequest.java @@ -1,6 +1,6 @@ package cn.axzo.msg.center.service.general.request; -import cn.axzo.msg.center.service.dto.IdentityDTO; +import cn.axzo.msg.center.service.dto.PersonDTO; import cn.axzo.msg.center.service.enums.OrganizationTypeEnum; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; @@ -11,8 +11,9 @@ import lombok.NoArgsConstructor; import lombok.Setter; import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import javax.validation.constraints.NotEmpty; import java.io.Serializable; +import java.util.Collection; /** * @description @@ -36,25 +37,14 @@ public class GeneralMessageSendRequest implements Serializable { @NotBlank(message = "templateCode is required") private String templateCode; /** - * 消息发送者自然人id + * 消息发送者信息,可为空,默认模板对应的IM机器人 */ - @NotNull(message = "senderPersonId is required") - private Long senderPersonId; + private PersonDTO sender; /** - * 消息发送者身份 + * 消息接收信息 */ - @NotNull(message = "senderIdentity is required") - private IdentityDTO senderIdentity; - /** - * 消息接收者自然人id - */ - @NotNull(message = "receiverPersonId is required") - private Long receiverPersonId; - /** - * 消息接收者身份 - */ - @NotNull(message = "receiverIdentity is required") - private IdentityDTO receiverIdentity; + @NotEmpty(message = "receiver is required") + private Collection receiver; /** * 消息所属组织类型 */ diff --git a/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/MessageSendTwiceRecordDao.java b/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/MessageSendTwiceRecordDao.java new file mode 100644 index 00000000..d570dfac --- /dev/null +++ b/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/MessageSendTwiceRecordDao.java @@ -0,0 +1,18 @@ +package cn.axzo.msg.center.dal; + +import cn.axzo.msg.center.dal.mapper.MessageSendTwiceRecordMapper; +import cn.axzo.msg.center.domain.entity.MessageSendTwiceRecord; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @description + * @author cold_blade + * @date 2023/10/21 + * @version 1.0 + */ +@Slf4j +@Component +public class MessageSendTwiceRecordDao extends ServiceImpl { +} diff --git a/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/RelationTemplateMapDao.java b/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/RelationTemplateMapDao.java new file mode 100644 index 00000000..fcc7bdf8 --- /dev/null +++ b/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/RelationTemplateMapDao.java @@ -0,0 +1,18 @@ +package cn.axzo.msg.center.dal; + +import cn.axzo.msg.center.dal.mapper.RelationTemplateMapMapper; +import cn.axzo.msg.center.domain.entity.RelationTemplateMap; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @description + * @author cold_blade + * @date 2023/10/21 + * @version 1.0 + */ +@Slf4j +@Component +public class RelationTemplateMapDao extends ServiceImpl { +} diff --git a/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/mapper/MessageSendTwiceRecordMapper.java b/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/mapper/MessageSendTwiceRecordMapper.java new file mode 100644 index 00000000..f350674e --- /dev/null +++ b/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/mapper/MessageSendTwiceRecordMapper.java @@ -0,0 +1,12 @@ +package cn.axzo.msg.center.dal.mapper; + +import cn.axzo.msg.center.domain.entity.MessageSendTwiceRecord; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @author cold_blade + * @date 2023/10/21 + * @version 1.0 + */ +public interface MessageSendTwiceRecordMapper extends BaseMapper { +} diff --git a/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/mapper/RelationTemplateMapMapper.java b/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/mapper/RelationTemplateMapMapper.java new file mode 100644 index 00000000..df72e22e --- /dev/null +++ b/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/mapper/RelationTemplateMapMapper.java @@ -0,0 +1,12 @@ +package cn.axzo.msg.center.dal.mapper; + +import cn.axzo.msg.center.domain.entity.RelationTemplateMap; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @author cold_blade + * @date 2023/10/21 + * @version 1.0 + */ +public interface RelationTemplateMapMapper extends BaseMapper { +} diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageSendTwiceRecord.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageSendTwiceRecord.java new file mode 100644 index 00000000..1fe2184c --- /dev/null +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageSendTwiceRecord.java @@ -0,0 +1,36 @@ +package cn.axzo.msg.center.domain.entity; + +import cn.axzo.msg.center.domain.persistence.BaseEntity; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +/** + * @author cold_blade + * @date 2023/10/21 + * @version 1.0 + */ +@Setter +@Getter +@TableName("message_send_twice_record") +public class MessageSendTwiceRecord extends BaseEntity implements Serializable { + + private static final long serialVersionUID = 3517821492158061709L; + + /** + * 原有消息记录id + */ + private Long originalMsgId; + /** + * 接收者自然人 ID + */ + private Long receiverPersonId; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/RelationTemplateMap.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/RelationTemplateMap.java new file mode 100644 index 00000000..5cf8cc36 --- /dev/null +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/RelationTemplateMap.java @@ -0,0 +1,36 @@ +package cn.axzo.msg.center.domain.entity; + +import cn.axzo.msg.center.domain.persistence.BaseEntity; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +/** + * @author cold_blade + * @date 2023/10/21 + * @version 1.0 + */ +@Setter +@Getter +@TableName("relation_template_map") +public class RelationTemplateMap extends BaseEntity implements Serializable { + + private static final long serialVersionUID = 2716916154882729387L; + + /** + * 新消息模板编码 + */ + private String templateCode; + /** + * 原有的模板关联关系id + */ + private Long originalRelationId; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} From 347709b5e69ff7ea13032cb249866711e18ce593 Mon Sep 17 00:00:00 2001 From: luofu Date: Tue, 24 Oct 2023 09:25:21 +0800 Subject: [PATCH 33/50] =?UTF-8?q?feat(REQ-1465):=20IM=E6=97=A7=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E5=85=A5=E5=8F=A3?= 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、IM旧消息入口 影响: 无 --- .../controller/GeneralMessageController.java | 10 +++- .../service/GeneralMessageService.java | 10 ++++ .../impl/GeneralMessageServiceImpl.java | 38 ++++++++++++++- .../msg/center/utils/PersonIdentityUtil.java | 14 +++--- .../center/api/response/MessageNewRes.java | 5 +- .../general/client/GeneralMessageClient.java | 14 +++++- .../GeneralMessageClientFallback.java | 11 ++++- ...GeneralMessageOldDataStatisticRequest.java | 48 +++++++++++++++++++ ...eneralMessageOldDataStatisticResponse.java | 45 +++++++++++++++++ .../resources/mapper/MessageRecordMapper.xml | 3 +- .../center/domain/dto/MessageNewResDTO.java | 5 +- 11 files changed, 188 insertions(+), 15 deletions(-) create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/general/request/GeneralMessageOldDataStatisticRequest.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/general/response/GeneralMessageOldDataStatisticResponse.java diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java index 3ea0b329..ce7b9679 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java @@ -2,7 +2,9 @@ package cn.axzo.msg.center.message.controller; import cn.axzo.msg.center.message.service.GeneralMessageService; 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 lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -21,7 +23,13 @@ public class GeneralMessageController implements GeneralMessageClient { private final GeneralMessageService generalMessageService; @Override - public CommonResponse sendMessage(GeneralMessageSendRequest request) { + public CommonResponse statisticOldData(GeneralMessageSendRequest request) { return CommonResponse.success(generalMessageService.batchSendMessage(request)); } + + @Override + public CommonResponse statisticOldData( + GeneralMessageOldDataStatisticRequest request) { + return CommonResponse.success(generalMessageService.statisticOldData(request)); + } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java index 7f6a98c6..e1f66514 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java @@ -1,6 +1,8 @@ package cn.axzo.msg.center.message.service; +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; /** * @author cold_blade @@ -16,4 +18,12 @@ public interface GeneralMessageService { * @return 请求的唯一标识 */ String batchSendMessage(GeneralMessageSendRequest request); + + /** + * 统计旧数据 + * + * @param request 统计参数 + * @return 旧数据的未读数以及最新一条消息 + */ + GeneralMessageOldDataStatisticResponse statisticOldData(GeneralMessageOldDataStatisticRequest request); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java index 0812a6cd..9e8692ef 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java @@ -1,12 +1,18 @@ package cn.axzo.msg.center.message.service.impl; +import cn.axzo.core.domain.PageResult; import cn.axzo.im.center.api.feign.MessageApi; import cn.axzo.im.center.api.vo.req.MessageInfo; import cn.axzo.im.center.common.enums.AppTypeEnum; +import cn.axzo.msg.center.api.request.CmsMsgQueryReq; +import cn.axzo.msg.center.api.response.MessageNewRes; +import cn.axzo.msg.center.api.response.MessageTotalRes; 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.service.MessageRecordService; 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.vo.GeneralMessagePushVO; @@ -16,9 +22,13 @@ 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.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 com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; @@ -33,6 +43,7 @@ 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; /** @@ -54,8 +65,9 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { private final String orgIcon = "https://axzo-pro.oss-cn-hangzhou.aliyuncs.com/rs_app/ic_org_icon.png"; private final MessageApi messageApi; - private final MessageTemplateNewService messageTemplateNewService; + private final MessageRecordService messageRecordService; private final GeneralMessageRecordDao generalMessageRecordDao; + private final MessageTemplateNewService messageTemplateNewService; @Override public String batchSendMessage(GeneralMessageSendRequest request) { @@ -70,6 +82,30 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { return UUIDUtil.uuidRawString(); } + @Override + public GeneralMessageOldDataStatisticResponse statisticOldData(GeneralMessageOldDataStatisticRequest request) { + // TODO: [cold_blade] [P0] 统计旧数据接口实现 + 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); + // TODO: [cold_blade] [P0] 需要排除IM中的消息 + PageResult result = messageRecordService.pageMsgInfo(req, request.getPersonId(), + request.getIdentityId(), userType); + MessageTotalRes res = messageRecordService.statisticsMsg4Total(request.getPersonId(), + request.getIdentityId(), userType); + + MessageNewRes msg = CollectionUtils.isNotEmpty(result.getData()) ? result.getData().get(0) : null; + return GeneralMessageOldDataStatisticResponse.builder() + .unreadCount(res.getMsgTotal()) + .latestMsgSendTimestamp(Optional.ofNullable(msg).map(v -> v.getCreateAt().getTime()).orElse(null)) + .latestMsgContent(Optional.ofNullable(msg).map(MessageNewRes::getContent).orElse(null)) + .build(); + } + private List buildMessageRecord(GeneralMessageSendRequest request, MessageTemplateDTO template) { return request.getReceiver().stream() .map(e -> buildMessageRecord(request, e, template)) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java b/inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java index 7cec1cb7..aef338c5 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java @@ -1,8 +1,8 @@ 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 cn.axzo.pudge.core.service.ServiceException; import java.util.Objects; import java.util.Optional; @@ -15,18 +15,16 @@ import java.util.Optional; */ public class PersonIdentityUtil { - public static ReceiveTypeEnum receiveType(Integer identityTypeCode) { - IdentityTypeEnum identityType = IdentityTypeEnum.codeOf(identityTypeCode) - .orElseThrow(() -> new ServiceException("档案身份类型不匹配 code:" + identityTypeCode)); + public static UserTypeEnum toUserType(IdentityTypeEnum identityType) { switch (identityType) { case WORKER: - return ReceiveTypeEnum.CM_WORKER; + return UserTypeEnum.CM; case WORKER_LEADER: - return ReceiveTypeEnum.CM_LEADER; + return UserTypeEnum.TEAM; case PRACTITIONER: - return ReceiveTypeEnum.CMP_USER; + return UserTypeEnum.CMP; default: - return ReceiveTypeEnum.NOT_IDENTITY; + return UserTypeEnum.NOT_IDENTITY; } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/api/response/MessageNewRes.java b/msg-center-api/src/main/java/cn/axzo/msg/center/api/response/MessageNewRes.java index 4da66b6e..d959abfe 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/api/response/MessageNewRes.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/api/response/MessageNewRes.java @@ -92,5 +92,8 @@ public class MessageNewRes { */ private Integer oldTypeId; - + /** + * 创建时间 + */ + private Date createAt; } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java index a93a0ebf..a3a45ada 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java @@ -1,6 +1,8 @@ package cn.axzo.msg.center.service.general.client; +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.service.pending.client.fallback.PendingMessageClientFallback; import cn.azxo.framework.common.model.CommonResponse; import org.springframework.cloud.openfeign.FeignClient; @@ -30,5 +32,15 @@ public interface GeneralMessageClient { * @return 消息的唯一标识 */ @PostMapping(value = "/general-message/send", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse sendMessage(@RequestBody @Valid GeneralMessageSendRequest request); + CommonResponse statisticOldData(@RequestBody @Valid GeneralMessageSendRequest request); + + /** + * 发送消息 + * + * @param request 消息所需参数 + * @return 消息的唯一标识 + */ + @PostMapping(value = "/general-message/old-data/statistic", produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse statisticOldData( + @RequestBody @Valid GeneralMessageOldDataStatisticRequest request); } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java index 3179b879..a81bbb74 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java @@ -1,7 +1,9 @@ package cn.axzo.msg.center.service.general.client.fallback; 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 lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -16,8 +18,15 @@ import org.springframework.stereotype.Component; public class GeneralMessageClientFallback implements GeneralMessageClient { @Override - public CommonResponse sendMessage(GeneralMessageSendRequest request) { + public CommonResponse statisticOldData(GeneralMessageSendRequest request) { log.error("fall back while sending message. req:{}", request); return CommonResponse.error("fall back while sending message"); } + + @Override + public CommonResponse statisticOldData( + GeneralMessageOldDataStatisticRequest request) { + log.error("fall back while statistic old message. req:{}", request); + return CommonResponse.error("fall back while statistic old message"); + } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/request/GeneralMessageOldDataStatisticRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/request/GeneralMessageOldDataStatisticRequest.java new file mode 100644 index 00000000..04a88331 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/request/GeneralMessageOldDataStatisticRequest.java @@ -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); + } +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/response/GeneralMessageOldDataStatisticResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/response/GeneralMessageOldDataStatisticResponse.java new file mode 100644 index 00000000..8c7ac695 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/response/GeneralMessageOldDataStatisticResponse.java @@ -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); + } +} diff --git a/msg-center-dal/src/main/resources/mapper/MessageRecordMapper.xml b/msg-center-dal/src/main/resources/mapper/MessageRecordMapper.xml index e3ce7543..627fe2bf 100644 --- a/msg-center-dal/src/main/resources/mapper/MessageRecordMapper.xml +++ b/msg-center-dal/src/main/resources/mapper/MessageRecordMapper.xml @@ -40,7 +40,8 @@ record.extra as ext, record.router_params as routerParam, record.relation_id as relationId, - record.old_type_id as oldTypeId + record.old_type_id as oldTypeId, + record.create_at as createAt from message_record record join message_relation relation diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/dto/MessageNewResDTO.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/dto/MessageNewResDTO.java index c5f3196e..780a0242 100644 --- a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/dto/MessageNewResDTO.java +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/dto/MessageNewResDTO.java @@ -92,5 +92,8 @@ public class MessageNewResDTO { */ private Integer oldTypeId; - + /** + * 创建时间 + */ + private Date createAt; } From 067d38852267016db7176a2d88a07f80109d8f77 Mon Sep 17 00:00:00 2001 From: luofu Date: Tue, 24 Oct 2023 09:57:23 +0800 Subject: [PATCH 34/50] =?UTF-8?q?docs(REQ-1465):=20=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E8=B0=83=E6=95=B4?= 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、IM接口注释调整 影响: 无 --- .../center/service/general/client/GeneralMessageClient.java | 4 ++-- .../response/GeneralMessageOldDataStatisticResponse.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java index a3a45ada..c2e5d26f 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java @@ -35,10 +35,10 @@ public interface GeneralMessageClient { CommonResponse statisticOldData(@RequestBody @Valid GeneralMessageSendRequest request); /** - * 发送消息 + * 统计旧消息的未读数以及最新一条消息内容 * * @param request 消息所需参数 - * @return 消息的唯一标识 + * @return 消息未读数&最新一条消息内容 */ @PostMapping(value = "/general-message/old-data/statistic", produces = {MediaType.APPLICATION_JSON_VALUE}) CommonResponse statisticOldData( diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/response/GeneralMessageOldDataStatisticResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/response/GeneralMessageOldDataStatisticResponse.java index 8c7ac695..f864a589 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/response/GeneralMessageOldDataStatisticResponse.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/response/GeneralMessageOldDataStatisticResponse.java @@ -26,7 +26,7 @@ public class GeneralMessageOldDataStatisticResponse implements Serializable { private static final long serialVersionUID = 5740922087866033787L; /** - * 消息的唯一标识 + * 消息的未读数 */ private Integer unreadCount; /** From 741ac640bc387c75d7524d2ad486be27e3cc7898 Mon Sep 17 00:00:00 2001 From: luofu Date: Tue, 24 Oct 2023 15:15:45 +0800 Subject: [PATCH 35/50] =?UTF-8?q?docs(REQ-1465):=20=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E8=B0=83=E6=95=B4?= 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、IM接口注释调整 影响: 无 --- .../notices/service/MessageModuleService.java | 9 ++ .../service/MessageRelationService.java | 3 + .../impl/MessageModuleServiceImpl.java | 28 ++++++- .../impl/MessageRelationServiceImpl.java | 23 +++++- .../service/GeneralMessageOldService.java | 46 +++++++++++ .../impl/GeneralMessageOldServiceImpl.java | 82 +++++++++++++++++++ .../impl/GeneralMessageServiceImpl.java | 48 +++++++---- .../msg/center/utils/PersonIdentityUtil.java | 13 +++ .../msg/center/api/enums/MsgStateEnum.java | 7 ++ .../center/api/request/CmsMsgQueryReq.java | 8 +- .../msg/center/service/dto/PersonDTO.java | 6 ++ .../resources/mapper/MessageRecordMapper.xml | 7 +- .../center/domain/dto/CmsMsgQueryReqDTO.java | 5 ++ 13 files changed, 260 insertions(+), 25 deletions(-) create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageOldService.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageOldServiceImpl.java diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/MessageModuleService.java b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/MessageModuleService.java index dd3a1d80..722352dc 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/MessageModuleService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/MessageModuleService.java @@ -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.UpdateModuleDTO; 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 com.baomidou.mybatisplus.core.metadata.IPage; @@ -51,4 +52,12 @@ public interface MessageModuleService { * @return 对应的模块列表 */ List listByModuleName(String moduleName); + + /** + * 通过bizType查询模块id列表 + * + * @param bizType 业务类型 + * @return 模块id列表 + */ + List listModuleIdByBizType(ModuleBizTypeEnum bizType); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/MessageRelationService.java b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/MessageRelationService.java index 4b80ceb8..0cda1597 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/MessageRelationService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/MessageRelationService.java @@ -8,6 +8,7 @@ import cn.axzo.msg.center.domain.entity.MessageRelation; import com.baomidou.mybatisplus.core.metadata.IPage; import java.time.LocalDateTime; +import java.util.Collection; import java.util.List; import java.util.Set; @@ -37,4 +38,6 @@ public interface MessageRelationService { void delete(Long id); void syncData(List dtoList); + + List listRelationIdsByModuleIds(Collection moduleIds); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageModuleServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageModuleServiceImpl.java index bd25ab5c..8c19edc4 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageModuleServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageModuleServiceImpl.java @@ -3,7 +3,11 @@ package cn.axzo.msg.center.inside.notices.service.impl; import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; import cn.axzo.msg.center.api.enums.ReceiveTypeEnum; 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.enums.ModuleBizTypeEnum; import cn.axzo.msg.center.domain.enums.UserTypeEnum; @@ -20,7 +24,12 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; 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; /** @@ -179,4 +188,19 @@ public class MessageModuleServiceImpl implements MessageModuleService { .filter(e -> Objects.equals(e.getModuleName(), moduleName)) .collect(Collectors.toList()); } + + @Override + public List 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()); + } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRelationServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRelationServiceImpl.java index 18d5b616..d6d40226 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRelationServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRelationServiceImpl.java @@ -24,7 +24,13 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; 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; /** @@ -180,4 +186,19 @@ public class MessageRelationServiceImpl implements MessageRelationService { }); } + + @Override + public List listRelationIdsByModuleIds(Collection moduleIds) { + if (CollectionUtils.isEmpty(moduleIds)) { + log.info("moduleIds is empty."); + return Collections.emptyList(); + } + return messageRelationDao.lambdaQuery() + .eq(BaseEntity::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .in(MessageRelation::getModuleId, moduleIds) + .select(MessageRelation::getId) + .list().stream() + .map(MessageRelation::getId) + .collect(Collectors.toList()); + } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageOldService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageOldService.java new file mode 100644 index 00000000..b4049ed6 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageOldService.java @@ -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 excludeMsgIds); + + /** + * 分页查询旧的普通消息记录 + * 注: 该接口作为IM进入旧消息模块的入口,需要过滤双发至IM的消息 + * + * @param request 分页查询参数 + * @return 过滤后的旧的普通消息记录 + */ + Page pageMsgInfo(CmsMsgQueryReq request); +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageOldServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageOldServiceImpl.java new file mode 100644 index 00000000..15147517 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageOldServiceImpl.java @@ -0,0 +1,82 @@ +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.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 sendTwiceMsgIds = messageSendTwiceRecordService.listByPerson(person.getId()); + return countUnread(person, sendTwiceMsgIds); + } + + @Override + public int countUnread(PersonDTO person, List excludeMsgIds) { + List moduleIds = messageModuleService.listModuleIdByBizType(ModuleBizTypeEnum.CONSTRUCTION); + List relationIds = messageRelationService.listRelationIdsByModuleIds(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 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 pageResult = messageCoreService.listMsgInfo(request); + return Page.toPage(request.getPage(), request.getPageSize(), pageResult.getTotalCount(), pageResult.getData()); + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java index 9e8692ef..bdd38787 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java @@ -1,12 +1,10 @@ package cn.axzo.msg.center.message.service.impl; -import cn.axzo.core.domain.PageResult; import cn.axzo.im.center.api.feign.MessageApi; import cn.axzo.im.center.api.vo.req.MessageInfo; import cn.axzo.im.center.common.enums.AppTypeEnum; import cn.axzo.msg.center.api.request.CmsMsgQueryReq; import cn.axzo.msg.center.api.response.MessageNewRes; -import cn.axzo.msg.center.api.response.MessageTotalRes; import cn.axzo.msg.center.common.exception.ServiceException; import cn.axzo.msg.center.common.utils.PlaceholderResolver; import cn.axzo.msg.center.dal.GeneralMessageRecordDao; @@ -16,7 +14,9 @@ import cn.axzo.msg.center.inside.notices.service.MessageRecordService; 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.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.MessageCardContentItemDTO; import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO; @@ -30,6 +30,7 @@ import cn.axzo.msg.center.service.general.response.GeneralMessageOldDataStatisti 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; @@ -67,7 +68,9 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { private final MessageApi messageApi; private final MessageRecordService messageRecordService; private final GeneralMessageRecordDao generalMessageRecordDao; + private final GeneralMessageOldService generalMessageOldService; private final MessageTemplateNewService messageTemplateNewService; + private final MessageSendTwiceRecordService messageSendTwiceRecordService; @Override public String batchSendMessage(GeneralMessageSendRequest request) { @@ -84,23 +87,17 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { @Override public GeneralMessageOldDataStatisticResponse statisticOldData(GeneralMessageOldDataStatisticRequest request) { - // TODO: [cold_blade] [P0] 统计旧数据接口实现 - 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); - // TODO: [cold_blade] [P0] 需要排除IM中的消息 - PageResult result = messageRecordService.pageMsgInfo(req, request.getPersonId(), - request.getIdentityId(), userType); - MessageTotalRes res = messageRecordService.statisticsMsg4Total(request.getPersonId(), - request.getIdentityId(), userType); - - MessageNewRes msg = CollectionUtils.isNotEmpty(result.getData()) ? result.getData().get(0) : null; + // 查询双发的消息记录 + List sendTwiceMsgIds = messageSendTwiceRecordService.listByPerson(request.getPersonId()); + // 分页查询最新一条数据 + Page 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(res.getMsgTotal()) + .unreadCount(count) .latestMsgSendTimestamp(Optional.ofNullable(msg).map(v -> v.getCreateAt().getTime()).orElse(null)) .latestMsgContent(Optional.ofNullable(msg).map(MessageNewRes::getContent).orElse(null)) .build(); @@ -197,4 +194,19 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { } return PlaceholderResolver.getDefaultResolver().resolveByMap(string, params); } + + private CmsMsgQueryReq build(GeneralMessageOldDataStatisticRequest request, List 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; + } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java b/inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java index aef338c5..62fa1be7 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java @@ -43,4 +43,17 @@ public class PersonIdentityUtil { return Optional.empty(); } } + + 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; + } + } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/api/enums/MsgStateEnum.java b/msg-center-api/src/main/java/cn/axzo/msg/center/api/enums/MsgStateEnum.java index 2ff96325..382f97ad 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/api/enums/MsgStateEnum.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/api/enums/MsgStateEnum.java @@ -49,4 +49,11 @@ public enum MsgStateEnum { COMPLETE ); } + + public static List unreadStates() { + return Lists.newArrayList( + HAS_BEEN_SENT, + RECEIVED + ); + } } \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/CmsMsgQueryReq.java b/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/CmsMsgQueryReq.java index 3cd15dd9..1fd8b3c5 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/CmsMsgQueryReq.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/CmsMsgQueryReq.java @@ -4,6 +4,7 @@ import cn.axzo.basics.common.page.PageRequest; import lombok.Data; import javax.validation.constraints.NotNull; +import java.util.List; /** * @author : liuchuntao @@ -58,7 +59,8 @@ public class CmsMsgQueryReq extends PageRequest { * */ private Long identityId; - - - + /** + * 待排除的消息id + */ + private List excludeMsgIds; } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/PersonDTO.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/PersonDTO.java index fad40f2d..33a108a0 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/PersonDTO.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/dto/PersonDTO.java @@ -9,6 +9,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; import java.io.Serializable; +import java.util.Objects; /** * @description @@ -46,6 +47,11 @@ public class PersonDTO implements Serializable { .build(); } + public boolean isValid() { + return Objects.nonNull(id) && id > 0 + && Objects.nonNull(identity) && identity.isValid(); + } + @Override public String toString() { return JSON.toJSONString(this); diff --git a/msg-center-dal/src/main/resources/mapper/MessageRecordMapper.xml b/msg-center-dal/src/main/resources/mapper/MessageRecordMapper.xml index 627fe2bf..7075d6ec 100644 --- a/msg-center-dal/src/main/resources/mapper/MessageRecordMapper.xml +++ b/msg-center-dal/src/main/resources/mapper/MessageRecordMapper.xml @@ -66,7 +66,12 @@ #{item} - + + and record.id not in + + #{item} + + and record.create_at > DATE_FORMAT((CURDATE() - INTERVAL 3 YEAR),'%Y-%m-%d') order by record.create_at desc,record.id desc diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/dto/CmsMsgQueryReqDTO.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/dto/CmsMsgQueryReqDTO.java index 186f47cd..f00d7205 100644 --- a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/dto/CmsMsgQueryReqDTO.java +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/dto/CmsMsgQueryReqDTO.java @@ -4,6 +4,7 @@ import cn.axzo.basics.common.page.PageRequest; import lombok.Data; import javax.validation.constraints.NotNull; +import java.util.List; @Data public class CmsMsgQueryReqDTO extends PageRequest { @@ -34,4 +35,8 @@ public class CmsMsgQueryReqDTO extends PageRequest { * 待办、消息模块类型Id - 针对待办使用 */ private Long moduleId; + /** + * 待排除的消息id + */ + private List excludeMsgIds; } From 661a393fa242f3e72da32b8f6eca3e320ed90864 Mon Sep 17 00:00:00 2001 From: luofu Date: Tue, 24 Oct 2023 15:59:18 +0800 Subject: [PATCH 36/50] =?UTF-8?q?feat(REQ-1465):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=97=A7=E6=B6=88=E6=81=AF=E7=9A=84=E7=BB=9F=E8=AE=A1=E5=8F=8A?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E6=9F=A5=E8=AF=A2=E6=8E=A5=E5=8F=A3?= 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、新增旧消息的统计及分页查询接口 影响: 无 --- .../impl/MessageRelationServiceImpl.java | 3 ++- .../controller/GeneralMessageController.java | 21 ++++++++++++++-- .../general/client/GeneralMessageClient.java | 25 +++++++++++++++++-- .../GeneralMessageClientFallback.java | 19 ++++++++++++-- 4 files changed, 61 insertions(+), 7 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRelationServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRelationServiceImpl.java index eea30ac8..11180058 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRelationServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRelationServiceImpl.java @@ -194,7 +194,8 @@ public class MessageRelationServiceImpl implements MessageRelationService { } return messageRelationDao.lambdaQuery() .in(MessageRelation::getModuleId, moduleIds) - .eq(MessageRelation::getIsDelete, 0) + .eq(MessageRelation::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .select(MessageRelation::getId) .list().stream() .map(MessageRelation::getId) .collect(Collectors.toList()); diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java index ce7b9679..84949057 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java @@ -1,11 +1,16 @@ 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; @@ -21,15 +26,27 @@ import org.springframework.web.bind.annotation.RestController; public class GeneralMessageController implements GeneralMessageClient { private final GeneralMessageService generalMessageService; + private final GeneralMessageOldService generalMessageOldService; @Override - public CommonResponse statisticOldData(GeneralMessageSendRequest request) { + public CommonResponse pageQueryOldMessage(GeneralMessageSendRequest request) { return CommonResponse.success(generalMessageService.batchSendMessage(request)); } @Override - public CommonResponse statisticOldData( + public CommonResponse pageQueryOldMessage( GeneralMessageOldDataStatisticRequest request) { return CommonResponse.success(generalMessageService.statisticOldData(request)); } + + @Override + public CommonResponse countUnreadFromOldMessage(GeneralMessageOldDataStatisticRequest request) { + PersonDTO person = PersonDTO.from(request.getPersonId(), request.getIdentityId(), request.getIdentityType()); + return CommonResponse.success(generalMessageOldService.countUnread(person)); + } + + @Override + public CommonResponse> pageQueryOldMessage(CmsMsgQueryReq request) { + return CommonResponse.success(generalMessageOldService.pageMsgInfo(request)); + } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java index c2e5d26f..c072f6fd 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java @@ -1,10 +1,13 @@ 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.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.service.pending.client.fallback.PendingMessageClientFallback; 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; @@ -32,7 +35,7 @@ public interface GeneralMessageClient { * @return 消息的唯一标识 */ @PostMapping(value = "/general-message/send", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse statisticOldData(@RequestBody @Valid GeneralMessageSendRequest request); + CommonResponse pageQueryOldMessage(@RequestBody @Valid GeneralMessageSendRequest request); /** * 统计旧消息的未读数以及最新一条消息内容 @@ -41,6 +44,24 @@ public interface GeneralMessageClient { * @return 消息未读数&最新一条消息内容 */ @PostMapping(value = "/general-message/old-data/statistic", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse statisticOldData( + CommonResponse pageQueryOldMessage( @RequestBody @Valid GeneralMessageOldDataStatisticRequest request); + + /** + * 统计旧消息的未读数 + * + * @param request 消息所需参数 + * @return 消息未读数 + */ + @PostMapping(value = "/general-message/old-data/count-unread", produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse countUnreadFromOldMessage(@RequestBody @Valid GeneralMessageOldDataStatisticRequest request); + + /** + * 旧消息的分页查询入口 + * + * @param request 分页查询所需参数 + * @return 旧消息的分页列表 + */ + @PostMapping(value = "/general-message/old-data/page", produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse> pageQueryOldMessage(@RequestBody @Valid CmsMsgQueryReq request); } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java index a81bbb74..76708c28 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java @@ -1,10 +1,13 @@ 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; @@ -18,15 +21,27 @@ import org.springframework.stereotype.Component; public class GeneralMessageClientFallback implements GeneralMessageClient { @Override - public CommonResponse statisticOldData(GeneralMessageSendRequest request) { + public CommonResponse pageQueryOldMessage(GeneralMessageSendRequest request) { log.error("fall back while sending message. req:{}", request); return CommonResponse.error("fall back while sending message"); } @Override - public CommonResponse statisticOldData( + public CommonResponse pageQueryOldMessage( GeneralMessageOldDataStatisticRequest request) { log.error("fall back while statistic old message. req:{}", request); return CommonResponse.error("fall back while statistic old message"); } + + @Override + public CommonResponse 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> pageQueryOldMessage(CmsMsgQueryReq request) { + log.error("fall back while statistic old message. request:{}", request); + return CommonResponse.error("fall back while statistic old message"); + } } From fc54aae6ac143cfeb9138854c96a651d40440c5e Mon Sep 17 00:00:00 2001 From: luofu Date: Tue, 24 Oct 2023 16:08:49 +0800 Subject: [PATCH 37/50] =?UTF-8?q?feat(REQ-1465):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=97=A7=E6=B6=88=E6=81=AF=E7=9A=84=E7=BB=9F=E8=AE=A1=E5=8F=8A?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E6=9F=A5=E8=AF=A2=E6=8E=A5=E5=8F=A3?= 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、新增旧消息的统计及分页查询接口 影响: 无 --- .../msg/center/message/controller/GeneralMessageController.java | 2 +- .../msg/center/service/general/client/GeneralMessageClient.java | 2 +- .../general/client/fallback/GeneralMessageClientFallback.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java index 84949057..face93a4 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java @@ -34,7 +34,7 @@ public class GeneralMessageController implements GeneralMessageClient { } @Override - public CommonResponse pageQueryOldMessage( + public CommonResponse statisticOldData( GeneralMessageOldDataStatisticRequest request) { return CommonResponse.success(generalMessageService.statisticOldData(request)); } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java index c072f6fd..e69800b1 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java @@ -44,7 +44,7 @@ public interface GeneralMessageClient { * @return 消息未读数&最新一条消息内容 */ @PostMapping(value = "/general-message/old-data/statistic", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse pageQueryOldMessage( + CommonResponse statisticOldData( @RequestBody @Valid GeneralMessageOldDataStatisticRequest request); /** diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java index 76708c28..92bb88ce 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java @@ -27,7 +27,7 @@ public class GeneralMessageClientFallback implements GeneralMessageClient { } @Override - public CommonResponse pageQueryOldMessage( + public CommonResponse statisticOldData( GeneralMessageOldDataStatisticRequest request) { log.error("fall back while statistic old message. req:{}", request); return CommonResponse.error("fall back while statistic old message"); From 91fabb91b29d66c305807927f4a3b6cc8ee37783 Mon Sep 17 00:00:00 2001 From: luofu Date: Wed, 25 Oct 2023 11:16:26 +0800 Subject: [PATCH 38/50] =?UTF-8?q?feat(REQ-1465):=20=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=95=B0=E6=8D=AE=E6=A8=A1=E5=9E=8B=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E5=88=A0=E9=99=A4=E7=9A=84=E6=94=AF=E6=8C=81?= 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、模板相关数据模型逻辑删除的支持 影响: 无 --- .../notices/config/MessageSystemConfig.java | 2 + .../impl/GeneralMessageServiceImpl.java | 9 ++-- .../impl/MessageGroupNodeServiceImpl.java | 2 - .../impl/MessageTemplateGroupServiceImpl.java | 5 --- .../MessageTemplateRouterServiceImpl.java | 3 -- .../center/api/InsideMessageRecordApi.java | 2 +- .../center/api/InsideMessageTemplateApi.java | 2 +- .../axzo/msg/center/api/InsideNoticesApi.java | 2 +- .../axzo/msg/center/api/MessagePushApi.java | 2 +- .../domain/entity/MessageGroupNode.java | 4 +- .../domain/entity/MessageTemplateGroup.java | 4 +- .../domain/entity/MessageTemplateRouter.java | 4 +- .../domain/persistence/BaseEntityExt.java | 45 +++++++++++++++++++ 13 files changed, 60 insertions(+), 26 deletions(-) create mode 100644 msg-center-domain/src/main/java/cn/axzo/msg/center/domain/persistence/BaseEntityExt.java diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/config/MessageSystemConfig.java b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/config/MessageSystemConfig.java index 49f7041c..113845a8 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/config/MessageSystemConfig.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/config/MessageSystemConfig.java @@ -24,4 +24,6 @@ public class MessageSystemConfig { */ @Value("${message.common.record.divide-days:-1}") 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; } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java index bdd38787..140f590e 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java @@ -10,7 +10,7 @@ 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.service.MessageRecordService; +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.vo.GeneralMessagePushVO; @@ -62,11 +62,8 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { PushTerminalEnum.C_WORKER_APP, AppTypeEnum.CM ); - // TODO:[cold_blade] [P2] 图片icon的最好配置在nacos上 - private final String orgIcon = "https://axzo-pro.oss-cn-hangzhou.aliyuncs.com/rs_app/ic_org_icon.png"; - private final MessageApi messageApi; - private final MessageRecordService messageRecordService; + private final MessageSystemConfig messageSystemConfig; private final GeneralMessageRecordDao generalMessageRecordDao; private final GeneralMessageOldService generalMessageOldService; private final MessageTemplateNewService messageTemplateNewService; @@ -185,7 +182,7 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { e.setValue(value); }); } - return GeneralMessagePushVO.from(record, template.getIcon(), orgIcon, routerButtons, cardContentItems); + return GeneralMessagePushVO.from(record, template.getIcon(), messageSystemConfig.getOrgIcon(), routerButtons, cardContentItems); } private String parseString(String string, JSONObject params) { 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 0f642542..97680abd 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 @@ -116,8 +116,6 @@ public class MessageGroupNodeServiceImpl implements MessageGroupNodeService { // 删除结点 boolean removeResult = messageGroupNodeDao.lambdaUpdate() .eq(MessageGroupNode::getCode, nodeCode) - .eq(MessageGroupNode::getIsDelete, TableIsDeleteEnum.NORMAL.value) - // TODO: [cold_blade] [P2] 这里需要逻辑删除而非物理删除 .remove(); if (removeResult) { // 刷新缓存 diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java index 3ab0d607..eb753d69 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java @@ -83,8 +83,6 @@ public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupServ } messageTemplateGroupDao.lambdaUpdate() .eq(MessageTemplateGroup::getTemplateCode, templateNode) - .eq(MessageTemplateGroup::getIsDelete, TableIsDeleteEnum.NORMAL.value) - // TODO: [cold_blade] [P2] 这里需要逻辑删除而非物理删除 .remove(); } @@ -103,7 +101,6 @@ public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupServ @Override public void remove(String curGroupNodeCode, Collection templateCodes) { - // TODO: [cold_blade] // 参数校验 AssertUtil.isTrue(StringUtils.isNotBlank(curGroupNodeCode), "curGroupNodeCode can not be blank"); AssertUtil.notEmpty(templateCodes, "templateCodes can not be empty"); @@ -133,8 +130,6 @@ public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupServ messageTemplateGroupDao.lambdaUpdate() .in(MessageTemplateGroup::getTemplateCode, templateCodes) .eq(MessageTemplateGroup::getPath, nodeCodePathMap.get(curGroupNodeCode)) - .eq(MessageTemplateGroup::getIsDelete, TableIsDeleteEnum.NORMAL.value) - // TODO: [cold_blade] [P2] 这里需要逻辑删除而非物理删除 .remove(); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java index 553ca5c0..bab7e237 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java @@ -1,6 +1,5 @@ package cn.axzo.msg.center.message.service.impl; -import cn.axzo.msg.center.common.enums.TableIsDeleteEnum; import cn.axzo.msg.center.dal.MessageTemplateRouterDao; import cn.axzo.msg.center.domain.entity.MessageTemplateRouter; import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO; @@ -62,8 +61,6 @@ public class MessageTemplateRouterServiceImpl implements MessageTemplateRouterSe // 移除之前的路由信息 messageTemplateRouterDao.lambdaUpdate() .eq(MessageTemplateRouter::getTemplateCode, templateCode) - .eq(MessageTemplateRouter::getIsDelete, TableIsDeleteEnum.NORMAL.value) - // TODO: [cold_blade] [P2] 这里需要逻辑删除而非物理删除 .remove(); // 创建信息的路由信息 List newRouters = routers.stream() diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/api/InsideMessageRecordApi.java b/msg-center-api/src/main/java/cn/axzo/msg/center/api/InsideMessageRecordApi.java index 2fc65bf1..afb50d09 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/api/InsideMessageRecordApi.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/api/InsideMessageRecordApi.java @@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.RequestBody; 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 public interface InsideMessageRecordApi { diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/api/InsideMessageTemplateApi.java b/msg-center-api/src/main/java/cn/axzo/msg/center/api/InsideMessageTemplateApi.java index f77a7f37..2045687d 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/api/InsideMessageTemplateApi.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/api/InsideMessageTemplateApi.java @@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.*; 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 public interface InsideMessageTemplateApi { diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/api/InsideNoticesApi.java b/msg-center-api/src/main/java/cn/axzo/msg/center/api/InsideNoticesApi.java index addc0dc8..7a338415 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/api/InsideNoticesApi.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/api/InsideNoticesApi.java @@ -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 public interface InsideNoticesApi { diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/api/MessagePushApi.java b/msg-center-api/src/main/java/cn/axzo/msg/center/api/MessagePushApi.java index 8fbb477e..498333c2 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/api/MessagePushApi.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/api/MessagePushApi.java @@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.RequestBody; /** * 发送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 public interface MessagePushApi { diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageGroupNode.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageGroupNode.java index 75509df6..f349f496 100644 --- a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageGroupNode.java +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageGroupNode.java @@ -1,6 +1,6 @@ package cn.axzo.msg.center.domain.entity; -import cn.axzo.msg.center.domain.persistence.BaseEntity; +import cn.axzo.msg.center.domain.persistence.BaseEntityExt; import cn.axzo.msg.center.service.enums.MessageGroupNodeCategoryEnum; import cn.axzo.msg.center.service.enums.StatusEnum; import com.alibaba.fastjson.JSON; @@ -18,7 +18,7 @@ import java.io.Serializable; */ @Setter @Getter -public class MessageGroupNode extends BaseEntity implements Serializable { +public class MessageGroupNode extends BaseEntityExt implements Serializable { private static final long serialVersionUID = -4536503805143925884L; diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateGroup.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateGroup.java index 766c4f6a..b5b78a72 100644 --- a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateGroup.java +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateGroup.java @@ -1,6 +1,6 @@ package cn.axzo.msg.center.domain.entity; -import cn.axzo.msg.center.domain.persistence.BaseEntity; +import cn.axzo.msg.center.domain.persistence.BaseEntityExt; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Getter; @@ -19,7 +19,7 @@ import java.io.Serializable; @Setter @Getter @TableName("message_template_group") -public class MessageTemplateGroup extends BaseEntity implements Serializable { +public class MessageTemplateGroup extends BaseEntityExt implements Serializable { private static final long serialVersionUID = 3902204750978588588L; diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateRouter.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateRouter.java index 8ef1f5f7..861831c3 100644 --- a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateRouter.java +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateRouter.java @@ -1,6 +1,6 @@ package cn.axzo.msg.center.domain.entity; -import cn.axzo.msg.center.domain.persistence.BaseEntity; +import cn.axzo.msg.center.domain.persistence.BaseEntityExt; import cn.axzo.msg.center.service.enums.RouterCategoryEnum; import cn.axzo.msg.center.service.enums.TerminalTypeEnum; import com.alibaba.fastjson.JSON; @@ -20,7 +20,7 @@ import java.io.Serializable; @Setter @Getter @TableName("message_template_router") -public class MessageTemplateRouter extends BaseEntity implements Serializable { +public class MessageTemplateRouter extends BaseEntityExt implements Serializable { private static final long serialVersionUID = 6549664208396593182L; diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/persistence/BaseEntityExt.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/persistence/BaseEntityExt.java new file mode 100644 index 00000000..580c65ef --- /dev/null +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/persistence/BaseEntityExt.java @@ -0,0 +1,45 @@ +package cn.axzo.msg.center.domain.persistence; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; +import java.util.Date; + +/** + * @author cold_blade + * @date 2023/10/24 + * @version 1.0 + */ +@Setter +@Getter +public abstract class BaseEntityExt> extends Model implements Serializable { + + private static final long serialVersionUID = -420591992046546211L; + + /** + * id + */ + @TableId(type = IdType.AUTO) + protected Long id; + + /** + * 创建时间 + */ + protected Date createAt; + + /** + * 修改时间 + */ + protected Date updateAt; + + /** + * 是否删除 0正常,1删除 + */ + @TableLogic(delval = "id", value = "0") + protected Long isDelete = 0L; +} From 96f1234bc5ab0b9404339c46dfb3a5c3fb4d13a7 Mon Sep 17 00:00:00 2001 From: luofu Date: Wed, 25 Oct 2023 15:35:10 +0800 Subject: [PATCH 39/50] =?UTF-8?q?feat(REQ-1465):=20=E5=8F=8C=E5=8F=91?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E4=BC=98=E5=8C=96=E8=B0=83=E6=95=B4?= 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、双发模块优化调整 影响: 无 --- .../impl/MessageRecordServiceImpl.java | 2 +- .../controller/GeneralMessageController.java | 5 +- .../message/domain/dto/SendImMessageDTO.java | 47 +++++++++++ .../service/GeneralMessageMapperService.java | 6 +- .../service/GeneralMessageService.java | 5 +- .../impl/GeneralMessageMapperServiceImpl.java | 83 ++++++++++++------- .../impl/GeneralMessageServiceImpl.java | 28 +++++-- .../msg/center/utils/PersonIdentityUtil.java | 19 +++-- .../general/client/GeneralMessageClient.java | 7 +- .../GeneralMessageClientFallback.java | 6 +- 10 files changed, 145 insertions(+), 63 deletions(-) create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/SendImMessageDTO.java diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRecordServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRecordServiceImpl.java index 68b5928e..cbc4ce60 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRecordServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/MessageRecordServiceImpl.java @@ -139,7 +139,7 @@ public class MessageRecordServiceImpl implements MessageRecordService { Lists.partition(Lists.newArrayList(message.getToId()), partitionSize).forEach(toIds -> { Map toIdRecordMap = Maps.newHashMap(); List messageRecords = saveBatch(basic, toIds, message.getToldIdPersonIdMap(), toIdRecordMap); - generalMessageMapperService.asyncBatchSendMessage(message, toIds, toIdRecordMap); + generalMessageMapperService.asyncBatchSendMessage(message, toIdRecordMap); pushMessages.addAll(messageRecords); }); if(pushAthena) { diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java index face93a4..a921596a 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java @@ -29,8 +29,9 @@ public class GeneralMessageController implements GeneralMessageClient { private final GeneralMessageOldService generalMessageOldService; @Override - public CommonResponse pageQueryOldMessage(GeneralMessageSendRequest request) { - return CommonResponse.success(generalMessageService.batchSendMessage(request)); + public CommonResponse batchSend(GeneralMessageSendRequest request) { + generalMessageService.batchSendMessage(request); + return CommonResponse.success(); } @Override diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/SendImMessageDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/SendImMessageDTO.java new file mode 100644 index 00000000..650088e9 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/SendImMessageDTO.java @@ -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); + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageMapperService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageMapperService.java index 7033f110..c30c5165 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageMapperService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageMapperService.java @@ -2,7 +2,6 @@ package cn.axzo.msg.center.message.service; import cn.axzo.msg.center.api.request.GeneralMessageReq; import cn.axzo.msg.center.domain.entity.MessageRecord; -import cn.axzo.msg.center.service.dto.PersonDTO; import java.util.List; import java.util.Map; @@ -20,10 +19,7 @@ public interface GeneralMessageMapperService { * 异步批量发送消息 * * @param request 发送消息时的请求参数 - * @param subReceiverIds 接收者id列表 * @param toIdMessageRecordMap 接收者身份id与旧消息记录的映射关系 - * @return 批量发送消息请求的requestId */ - String asyncBatchSendMessage(GeneralMessageReq request, List subReceiverIds, - Map toIdMessageRecordMap); + void asyncBatchSendMessage(GeneralMessageReq request, Map toIdMessageRecordMap); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java index e1f66514..eb2fa03a 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageService.java @@ -1,9 +1,12 @@ 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 @@ -17,7 +20,7 @@ public interface GeneralMessageService { * @param request 消息所需参数 * @return 请求的唯一标识 */ - String batchSendMessage(GeneralMessageSendRequest request); + List batchSendMessage(GeneralMessageSendRequest request); /** * 统计旧数据 diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageMapperServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageMapperServiceImpl.java index cf7e1e67..c56761a4 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageMapperServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageMapperServiceImpl.java @@ -3,6 +3,7 @@ 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; @@ -12,21 +13,22 @@ import cn.axzo.msg.center.service.enums.IdentityTypeEnum; import cn.axzo.msg.center.service.enums.OrganizationTypeEnum; import cn.axzo.msg.center.service.general.request.GeneralMessageSendRequest; import cn.axzo.msg.center.utils.PersonIdentityUtil; -import cn.axzo.msg.center.utils.UUIDUtil; import cn.hutool.core.map.MapUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import jodd.util.concurrent.ThreadFactoryBuilder; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; +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; @@ -55,50 +57,69 @@ public class GeneralMessageMapperServiceImpl implements GeneralMessageMapperServ private final MessageSendTwiceRecordService messageSendTwiceRecordService; @Override - @Transactional(rollbackFor = Exception.class) - public String asyncBatchSendMessage(GeneralMessageReq request, List subReceiverIds, - Map toIdMessageRecordMap) { + public void asyncBatchSendMessage(GeneralMessageReq request, Map toIdMessageRecordMap) { if (MsgTypeEnum.PENDING_MESSAGE.equals(request.getType())) { log.info("pending message is not supported."); - return UUIDUtil.uuidRawString(); + return; } - if (Objects.isNull(request.getRelationId()) || MapUtil.isEmpty(request.getToldIdPersonIdMap())) { - log.info("param is invalid. relationId:[{}], toIdPersonIdMap:{}", request.getRelationId(), - request.getToldIdPersonIdMap()); - return UUIDUtil.uuidRawString(); + if (Objects.isNull(request.getRelationId())) { + log.info("relation id is null."); + return; } - Optional identityTypeOp = PersonIdentityUtil.toIdentityType(request.getReceiveType()); - if (!identityTypeOp.isPresent()) { - log.info("identity is invalid. relationId:[{}], receiveType:{}", request.getRelationId(), - request.getReceiveType()); - return UUIDUtil.uuidRawString(); + if (MapUtil.isEmpty(request.getToldIdPersonIdMap())) { + // 由于IM那边是根据personId来创建账户的,所以强依赖personId + log.info("toIdPersonIdMap is empty."); + return; } // 异步发送IM消息 - CompletableFuture.runAsync(() -> doBatchSendMessage(request, subReceiverIds, toIdMessageRecordMap, - identityTypeOp.get()), asyncSendMsgExecutorService); - return UUIDUtil.uuidRawString(); + CompletableFuture.runAsync(() -> doBatchSendMessage(request, toIdMessageRecordMap), + asyncSendMsgExecutorService); } - private void doBatchSendMessage(GeneralMessageReq request, List subReceiverIds, - Map toIdMessageRecordMap, IdentityTypeEnum identityType) { + private void doBatchSendMessage(GeneralMessageReq request, Map 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:[{}]", request.getRelationId()); - Map msgRecordIdPersonIdMap = toIdMessageRecordMap.entrySet().stream() - .filter(e -> request.getToldIdPersonIdMap().containsKey(e.getKey())) - .collect(Collectors.toMap(e -> e.getValue().getId(), e -> request.getToldIdPersonIdMap().get(e.getKey()))); - log.info("message send twice. relationId:[{}], msgIds:{}", request.getRelationId(), msgRecordIdPersonIdMap.values()); - // 双发记录 - messageSendTwiceRecordService.batchSave(msgRecordIdPersonIdMap); - // 发送IM消息 - generalMessageService.batchSendMessage(convert(request, templateCode, subReceiverIds, identityType)); + 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 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 GeneralMessageSendRequest convert(GeneralMessageReq request, String templateCode, - List subReceiverIds, IdentityTypeEnum identityType) { + private void recordSendImMessage(Map toIdMessageRecordMap, List sendImResult, + Map toIdPersonIdMap) { + // 成功发送了IM消息的personId集合 + Set sucSendImMsgPersonIds = sendImResult.stream() + .map(SendImMessageDTO::getPersonId).collect(Collectors.toSet()); + // 从入参中的toIdPersonIdMap中筛选发送成功的entry + Map subToIdPersonIdMap = toIdPersonIdMap.entrySet().stream() + // 过滤掉personId维度IM消息发送失败的entry + .filter(e -> sucSendImMsgPersonIds.contains(e.getValue())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + Map 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 subReceiverIds) { + IdentityTypeEnum identityType = PersonIdentityUtil.toIdentityType(request.getReceiveType()); List receivers = subReceiverIds.stream() .filter(request.getToldIdPersonIdMap()::containsKey) .map(e -> PersonDTO.from(request.getToldIdPersonIdMap().get(e), e, identityType)) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java index 140f590e..0fab0c6a 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java @@ -1,7 +1,9 @@ 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; @@ -13,6 +15,7 @@ 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; @@ -39,7 +42,10 @@ 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; @@ -70,16 +76,16 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { private final MessageSendTwiceRecordService messageSendTwiceRecordService; @Override - public String batchSendMessage(GeneralMessageSendRequest request) { + @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) + public List batchSendMessage(GeneralMessageSendRequest request) { // 查询模板基础信息 MessageTemplateDTO template = messageTemplateNewService.queryByTemplateCode(request.getTemplateCode()) .orElseThrow(() -> new ServiceException("未查询到对应的模板")); // 构建消息记录并存储 List messageRecords = buildMessageRecord(request, template); generalMessageRecordDao.saveBatch(messageRecords); - // 异步推送 - pushMessage(messageRecords, template); - return UUIDUtil.uuidRawString(); + // 发送IM消息 + return pushImMessage(messageRecords, template); } @Override @@ -129,10 +135,10 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { .build(); } - private void pushMessage(List messageRecords, MessageTemplateDTO template) { + private List pushImMessage(List messageRecords, MessageTemplateDTO template) { if (CollectionUtils.isEmpty(template.getPushTerminals())) { // 模板未配置任何推送终端 - return; + return Collections.emptyList(); } GeneralMessageRecord record = messageRecords.get(0); List appTypes = template.getPushTerminals().stream() @@ -140,7 +146,6 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { GeneralMessagePushVO message = convert(record, template); MessageInfo msgInfo = new MessageInfo(); msgInfo.setAppTypeList(appTypes); - // TODO: [cold_blade] [P2] 第一期只支持发送机器人相关的消息 msgInfo.setToPersonIdList(Lists.newArrayList(messageRecords.stream() .map(e -> String.valueOf(e.getReceiverPersonId())) .collect(Collectors.toSet()))); @@ -153,7 +158,14 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { ext.put("minAppVersion", template.getMinAppVersion()); msgInfo.setExtendsInfo(ext); - messageApi.sendMessage(msgInfo); + ApiResult> 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) { diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java b/inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java index 62fa1be7..d567fdcd 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/utils/PersonIdentityUtil.java @@ -3,17 +3,18 @@ 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; -import java.util.Optional; /** - * @description xxx * @author cold_blade * @date 2023/10/23 * @version 1.0 */ -public class PersonIdentityUtil { +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class PersonIdentityUtil { public static UserTypeEnum toUserType(IdentityTypeEnum identityType) { switch (identityType) { @@ -28,19 +29,19 @@ public class PersonIdentityUtil { } } - public static Optional toIdentityType(ReceiveTypeEnum receiveType) { + public static IdentityTypeEnum toIdentityType(ReceiveTypeEnum receiveType) { if (Objects.isNull(receiveType)) { - return Optional.empty(); + return IdentityTypeEnum.NOT_SUPPORT; } switch (receiveType) { case CM_WORKER: - return Optional.of(IdentityTypeEnum.WORKER); + return IdentityTypeEnum.WORKER; case CM_LEADER: - return Optional.of(IdentityTypeEnum.WORKER_LEADER); + return IdentityTypeEnum.WORKER_LEADER; case CMP_USER: - return Optional.of(IdentityTypeEnum.PRACTITIONER); + return IdentityTypeEnum.PRACTITIONER; default: - return Optional.empty(); + return IdentityTypeEnum.NOT_SUPPORT; } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java index e69800b1..581798c6 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java @@ -2,10 +2,10 @@ 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.axzo.msg.center.service.pending.client.fallback.PendingMessageClientFallback; import cn.azxo.framework.common.model.CommonResponse; import cn.azxo.framework.common.model.Page; import org.springframework.cloud.openfeign.FeignClient; @@ -25,7 +25,7 @@ import javax.validation.Valid; */ @Component @FeignClient(value = "msg-center", url = "${server.serviceUrl:http://msg-center:8080}", - fallback = PendingMessageClientFallback.class) + fallback = GeneralMessageClientFallback.class) public interface GeneralMessageClient { /** @@ -34,8 +34,9 @@ public interface GeneralMessageClient { * @param request 消息所需参数 * @return 消息的唯一标识 */ + @Deprecated @PostMapping(value = "/general-message/send", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse pageQueryOldMessage(@RequestBody @Valid GeneralMessageSendRequest request); + CommonResponse batchSend(@RequestBody @Valid GeneralMessageSendRequest request); /** * 统计旧消息的未读数以及最新一条消息内容 diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java index 92bb88ce..ac6d965e 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java @@ -21,9 +21,9 @@ import org.springframework.stereotype.Component; public class GeneralMessageClientFallback implements GeneralMessageClient { @Override - public CommonResponse pageQueryOldMessage(GeneralMessageSendRequest request) { - log.error("fall back while sending message. req:{}", request); - return CommonResponse.error("fall back while sending message"); + public CommonResponse 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 From 485c3c5596e983cd1f3837873057a6aebf616bf2 Mon Sep 17 00:00:00 2001 From: luofu Date: Wed, 25 Oct 2023 18:47:41 +0800 Subject: [PATCH 40/50] =?UTF-8?q?feat(REQ-1465):=20page=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E8=B0=83=E6=95=B4?= 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、page数据模型调整 影响: 无 --- .../message/controller/GeneralMessageController.java | 4 ++-- .../message/service/GeneralMessageOldService.java | 4 ++-- .../service/impl/GeneralMessageOldServiceImpl.java | 6 ++---- .../service/impl/GeneralMessageServiceImpl.java | 10 +++++----- .../service/general/client/GeneralMessageClient.java | 4 ++-- .../client/fallback/GeneralMessageClientFallback.java | 4 ++-- 6 files changed, 15 insertions(+), 17 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java index a921596a..19919c84 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java @@ -1,5 +1,6 @@ package cn.axzo.msg.center.message.controller; +import cn.axzo.core.domain.PageResult; import cn.axzo.msg.center.api.request.CmsMsgQueryReq; import cn.axzo.msg.center.api.response.MessageNewRes; import cn.axzo.msg.center.message.service.GeneralMessageOldService; @@ -10,7 +11,6 @@ import cn.axzo.msg.center.service.general.request.GeneralMessageOldDataStatistic 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; @@ -47,7 +47,7 @@ public class GeneralMessageController implements GeneralMessageClient { } @Override - public CommonResponse> pageQueryOldMessage(CmsMsgQueryReq request) { + public CommonResponse> pageQueryOldMessage(CmsMsgQueryReq request) { return CommonResponse.success(generalMessageOldService.pageMsgInfo(request)); } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageOldService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageOldService.java index b4049ed6..db0bc7e4 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageOldService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageOldService.java @@ -1,9 +1,9 @@ package cn.axzo.msg.center.message.service; +import cn.axzo.core.domain.PageResult; 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; @@ -42,5 +42,5 @@ public interface GeneralMessageOldService { * @param request 分页查询参数 * @return 过滤后的旧的普通消息记录 */ - Page pageMsgInfo(CmsMsgQueryReq request); + PageResult pageMsgInfo(CmsMsgQueryReq request); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageOldServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageOldServiceImpl.java index d204dc6d..c2c902a9 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageOldServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageOldServiceImpl.java @@ -17,7 +17,6 @@ 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; @@ -71,12 +70,11 @@ public class GeneralMessageOldServiceImpl implements GeneralMessageOldService { } @Override - public Page pageMsgInfo(CmsMsgQueryReq request) { + public PageResult 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 pageResult = messageCoreService.listMsgInfo(request); - return Page.toPage(request.getPage(), request.getPageSize(), pageResult.getTotalCount(), pageResult.getData()); + return messageCoreService.listMsgInfo(request); } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java index 0fab0c6a..4282cda2 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java @@ -1,5 +1,6 @@ package cn.axzo.msg.center.message.service.impl; +import cn.axzo.core.domain.PageResult; 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; @@ -33,11 +34,10 @@ import cn.axzo.msg.center.service.general.response.GeneralMessageOldDataStatisti 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.Lists; +import com.google.common.collect.Sets; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -93,12 +93,12 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { // 查询双发的消息记录 List sendTwiceMsgIds = messageSendTwiceRecordService.listByPerson(request.getPersonId()); // 分页查询最新一条数据 - Page result = generalMessageOldService.pageMsgInfo(build(request, sendTwiceMsgIds)); + PageResult 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; + MessageNewRes msg = CollectionUtils.isNotEmpty(result.getData()) ? result.getData().get(0) : null; return GeneralMessageOldDataStatisticResponse.builder() .unreadCount(count) .latestMsgSendTimestamp(Optional.ofNullable(msg).map(v -> v.getCreateAt().getTime()).orElse(null)) @@ -146,7 +146,7 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { GeneralMessagePushVO message = convert(record, template); MessageInfo msgInfo = new MessageInfo(); msgInfo.setAppTypeList(appTypes); - msgInfo.setToPersonIdList(Lists.newArrayList(messageRecords.stream() + msgInfo.setToPersonIdList(Sets.newHashSet(messageRecords.stream() .map(e -> String.valueOf(e.getReceiverPersonId())) .collect(Collectors.toSet()))); msgInfo.setMsgHeader(record.getTitle()); diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java index 581798c6..c9f2e090 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java @@ -1,5 +1,6 @@ package cn.axzo.msg.center.service.general.client; +import cn.axzo.core.domain.PageResult; 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; @@ -7,7 +8,6 @@ import cn.axzo.msg.center.service.general.request.GeneralMessageOldDataStatistic 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; @@ -64,5 +64,5 @@ public interface GeneralMessageClient { * @return 旧消息的分页列表 */ @PostMapping(value = "/general-message/old-data/page", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse> pageQueryOldMessage(@RequestBody @Valid CmsMsgQueryReq request); + CommonResponse> pageQueryOldMessage(@RequestBody @Valid CmsMsgQueryReq request); } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java index ac6d965e..af49657f 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java @@ -1,5 +1,6 @@ package cn.axzo.msg.center.service.general.client.fallback; +import cn.axzo.core.domain.PageResult; 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; @@ -7,7 +8,6 @@ import cn.axzo.msg.center.service.general.request.GeneralMessageOldDataStatistic 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; @@ -40,7 +40,7 @@ public class GeneralMessageClientFallback implements GeneralMessageClient { } @Override - public CommonResponse> pageQueryOldMessage(CmsMsgQueryReq request) { + public CommonResponse> pageQueryOldMessage(CmsMsgQueryReq request) { log.error("fall back while statistic old message. request:{}", request); return CommonResponse.error("fall back while statistic old message"); } From 8164d8916b682a26b31946e1947417a532d4bd64 Mon Sep 17 00:00:00 2001 From: luofu Date: Thu, 26 Oct 2023 09:53:53 +0800 Subject: [PATCH 41/50] =?UTF-8?q?feat(REQ-1465):=20page=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E8=B0=83=E6=95=B4?= 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、page数据模型调整 影响: 无 --- .../message/controller/GeneralMessageController.java | 4 ++-- .../message/service/GeneralMessageOldService.java | 4 ++-- .../service/impl/GeneralMessageOldServiceImpl.java | 10 ++++++++-- .../service/impl/GeneralMessageServiceImpl.java | 6 +++--- .../service/general/client/GeneralMessageClient.java | 4 ++-- .../client/fallback/GeneralMessageClientFallback.java | 4 ++-- 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java index 19919c84..a921596a 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/GeneralMessageController.java @@ -1,6 +1,5 @@ package cn.axzo.msg.center.message.controller; -import cn.axzo.core.domain.PageResult; import cn.axzo.msg.center.api.request.CmsMsgQueryReq; import cn.axzo.msg.center.api.response.MessageNewRes; import cn.axzo.msg.center.message.service.GeneralMessageOldService; @@ -11,6 +10,7 @@ import cn.axzo.msg.center.service.general.request.GeneralMessageOldDataStatistic 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; @@ -47,7 +47,7 @@ public class GeneralMessageController implements GeneralMessageClient { } @Override - public CommonResponse> pageQueryOldMessage(CmsMsgQueryReq request) { + public CommonResponse> pageQueryOldMessage(CmsMsgQueryReq request) { return CommonResponse.success(generalMessageOldService.pageMsgInfo(request)); } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageOldService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageOldService.java index db0bc7e4..b4049ed6 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageOldService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/GeneralMessageOldService.java @@ -1,9 +1,9 @@ package cn.axzo.msg.center.message.service; -import cn.axzo.core.domain.PageResult; 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; @@ -42,5 +42,5 @@ public interface GeneralMessageOldService { * @param request 分页查询参数 * @return 过滤后的旧的普通消息记录 */ - PageResult pageMsgInfo(CmsMsgQueryReq request); + Page pageMsgInfo(CmsMsgQueryReq request); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageOldServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageOldServiceImpl.java index c2c902a9..bd978636 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageOldServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageOldServiceImpl.java @@ -7,6 +7,7 @@ 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; @@ -17,6 +18,7 @@ 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; @@ -70,11 +72,15 @@ public class GeneralMessageOldServiceImpl implements GeneralMessageOldService { } @Override - public PageResult pageMsgInfo(CmsMsgQueryReq request) { + public Page pageMsgInfo(CmsMsgQueryReq request) { log.info("start to page query general message. request:{}", request); if (CollectionUtils.isEmpty(request.getExcludeMsgIds())) { request.setExcludeMsgIds(messageSendTwiceRecordService.listByPerson(request.getPersonId())); } - return messageCoreService.listMsgInfo(request); + PageResult 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()); } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java index 4282cda2..34a2234f 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java @@ -1,6 +1,5 @@ package cn.axzo.msg.center.message.service.impl; -import cn.axzo.core.domain.PageResult; 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; @@ -34,6 +33,7 @@ import cn.axzo.msg.center.service.general.response.GeneralMessageOldDataStatisti 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; @@ -93,12 +93,12 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { // 查询双发的消息记录 List sendTwiceMsgIds = messageSendTwiceRecordService.listByPerson(request.getPersonId()); // 分页查询最新一条数据 - PageResult result = generalMessageOldService.pageMsgInfo(build(request, sendTwiceMsgIds)); + Page result = generalMessageOldService.pageMsgInfo(build(request, sendTwiceMsgIds)); // 统计旧的未读普通消息数量 int count = generalMessageOldService.countUnread(PersonDTO.from(request.getPersonId(), request.getIdentityId(), request.getIdentityType()), sendTwiceMsgIds); // 编排组合成界面展示的数据结构 - MessageNewRes msg = CollectionUtils.isNotEmpty(result.getData()) ? result.getData().get(0) : null; + 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)) diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java index c9f2e090..581798c6 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/GeneralMessageClient.java @@ -1,6 +1,5 @@ package cn.axzo.msg.center.service.general.client; -import cn.axzo.core.domain.PageResult; 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; @@ -8,6 +7,7 @@ import cn.axzo.msg.center.service.general.request.GeneralMessageOldDataStatistic 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; @@ -64,5 +64,5 @@ public interface GeneralMessageClient { * @return 旧消息的分页列表 */ @PostMapping(value = "/general-message/old-data/page", produces = {MediaType.APPLICATION_JSON_VALUE}) - CommonResponse> pageQueryOldMessage(@RequestBody @Valid CmsMsgQueryReq request); + CommonResponse> pageQueryOldMessage(@RequestBody @Valid CmsMsgQueryReq request); } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java index af49657f..ac6d965e 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/general/client/fallback/GeneralMessageClientFallback.java @@ -1,6 +1,5 @@ package cn.axzo.msg.center.service.general.client.fallback; -import cn.axzo.core.domain.PageResult; 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; @@ -8,6 +7,7 @@ import cn.axzo.msg.center.service.general.request.GeneralMessageOldDataStatistic 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; @@ -40,7 +40,7 @@ public class GeneralMessageClientFallback implements GeneralMessageClient { } @Override - public CommonResponse> pageQueryOldMessage(CmsMsgQueryReq request) { + public CommonResponse> pageQueryOldMessage(CmsMsgQueryReq request) { log.error("fall back while statistic old message. request:{}", request); return CommonResponse.error("fall back while statistic old message"); } From c181a3f35175eaf582fefecc88781d2d527570da Mon Sep 17 00:00:00 2001 From: luofu Date: Thu, 26 Oct 2023 13:51:53 +0800 Subject: [PATCH 42/50] =?UTF-8?q?docs(REQ-1465):=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=BC=82=E6=AD=A5=E5=8F=91=E9=80=81IM=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../message/service/impl/GeneralMessageMapperServiceImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageMapperServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageMapperServiceImpl.java index c56761a4..46288909 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageMapperServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageMapperServiceImpl.java @@ -58,6 +58,7 @@ public class GeneralMessageMapperServiceImpl implements GeneralMessageMapperServ @Override public void asyncBatchSendMessage(GeneralMessageReq request, Map 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; @@ -72,6 +73,7 @@ public class GeneralMessageMapperServiceImpl implements GeneralMessageMapperServ return; } // 异步发送IM消息 + log.info("start to async send im message. relationId:[{}]", request.getRelationId()); CompletableFuture.runAsync(() -> doBatchSendMessage(request, toIdMessageRecordMap), asyncSendMsgExecutorService); } From cdd7baacd7311cdf8c8cdc1444aa9767c5e756fd Mon Sep 17 00:00:00 2001 From: luofu Date: Thu, 26 Oct 2023 15:09:37 +0800 Subject: [PATCH 43/50] =?UTF-8?q?feat(REQ-1465):=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=8F=91=E9=80=81=E8=80=85=E4=B8=8D=E4=BC=A0=E5=8F=82=E7=9A=84?= =?UTF-8?q?=E5=9C=BA=E6=99=AF?= 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、处理发送者不传参的场景 影响: 无 --- .../service/impl/GeneralMessageServiceImpl.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java index 34a2234f..d5696601 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java @@ -21,10 +21,12 @@ 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; @@ -63,6 +65,11 @@ import java.util.stream.Collectors; @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 PUSH_TERMINAL_APP_MAP = ImmutableMap.of( PushTerminalEnum.B_ENTERPRISE_APP, AppTypeEnum.CMP, PushTerminalEnum.C_WORKER_APP, AppTypeEnum.CM @@ -114,11 +121,12 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { 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(request.getSender().getId()) - .senderId(request.getSender().getIdentity().getId()) - .senderType(request.getSender().getIdentity().getType()) + .senderPersonId(sender.getId()) + .senderId(sender.getIdentity().getId()) + .senderType(sender.getIdentity().getType()) .receiverPersonId(receiver.getId()) .receiverId(receiver.getIdentity().getId()) .receiverType(receiver.getIdentity().getType()) From 3d5f030311115085a4976f6e3d9612414b79cdf5 Mon Sep 17 00:00:00 2001 From: luofu Date: Thu, 26 Oct 2023 16:31:46 +0800 Subject: [PATCH 44/50] =?UTF-8?q?feat(REQ-1465):=20=E7=9F=AD=E4=BF=A1?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E5=88=9B=E5=BB=BA=E6=B5=81=E7=A8=8B=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= 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、短信模板创建流程优化 影响: 无 --- .../notices/service/impl/PlatServiceImpl.java | 51 ++++++++----------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/PlatServiceImpl.java b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/PlatServiceImpl.java index 6576179a..53ec52a5 100644 --- a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/PlatServiceImpl.java +++ b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/PlatServiceImpl.java @@ -49,16 +49,10 @@ public class PlatServiceImpl implements PlatService { @Override @Transactional(rollbackFor = Exception.class) public void createTemplate(CreateTemplateRequestDto request) { - // FIXME: 临时方案,将渠道信息放到remark中 String remark = request.getRemark(); ChannelHandlerEnum channel = parseChannel(remark); checkCreateTemplate(request, channel); - if (StringUtils.isNotBlank(remark)) { - // 恢复remark的原始值 - request.setRemark(PlaceholderResolver.getDefaultResolver().resolve(remark, "")); - } - insertMessageApp(request.getServiceName()); insertMessageTemplate(request); @@ -69,14 +63,9 @@ public class PlatServiceImpl implements PlatService { } private ChannelHandlerEnum parseChannel(String expStr) { - if (StringUtils.isBlank(expStr)) { - return ChannelHandlerEnum.ALI_YUN; - } - // FIXME:临时方案,后期有前端资源的时候需要改造接口的出入参 - return ChannelHandlerEnum.valueOf( - PlaceholderResolver.getDefaultResolver().resolveSequenceParamName(expStr).get(0) - ); + return ChannelHandlerEnum.ALI_YUN; } + /** * 插入app */ @@ -98,26 +87,26 @@ public class PlatServiceImpl implements PlatService { * 参数校验 */ private void checkCreateTemplate(CreateTemplateRequestDto request, ChannelHandlerEnum channel) { - if(request == null){ - throw new BizException(ReturnCodeEnum.FAIL,"参数不能为空"); + if (request == null) { + throw new BizException(ReturnCodeEnum.FAIL, "参数不能为空"); } - if(request.getServiceName() == null){ - throw new BizException(ReturnCodeEnum.FAIL,"服务名称不能为空"); + if (request.getServiceName() == null) { + throw new BizException(ReturnCodeEnum.FAIL, "服务名称不能为空"); } - if(request.getMessageTemplateType() == null){ - throw new BizException(ReturnCodeEnum.FAIL,"模板类型不能为空"); + if (request.getMessageTemplateType() == null) { + throw new BizException(ReturnCodeEnum.FAIL, "模板类型不能为空"); } - if(StringUtils.isBlank(request.getTemplateNo())){ - throw new BizException(ReturnCodeEnum.FAIL,"短信模板编码不能为空"); + if (StringUtils.isBlank(request.getTemplateNo())) { + throw new BizException(ReturnCodeEnum.FAIL, "短信模板编码不能为空"); } - if(StringUtils.isBlank(request.getTemplateAliNo())){ - throw new BizException(ReturnCodeEnum.FAIL,"阿里短信模板编码不能为空"); + if (StringUtils.isBlank(request.getTemplateAliNo())) { + throw new BizException(ReturnCodeEnum.FAIL, "阿里短信模板编码不能为空"); } - if(StringUtils.isBlank(request.getTitle())){ - throw new BizException(ReturnCodeEnum.FAIL,"标题不能为空"); + if (StringUtils.isBlank(request.getTitle())) { + throw new BizException(ReturnCodeEnum.FAIL, "标题不能为空"); } - if(StringUtils.isBlank(request.getTemplateContent())){ - throw new BizException(ReturnCodeEnum.FAIL,"模板内容不能为空"); + if (StringUtils.isBlank(request.getTemplateContent())) { + throw new BizException(ReturnCodeEnum.FAIL, "模板内容不能为空"); } // 判断短信编码是否存在 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); @@ -126,12 +115,12 @@ public class PlatServiceImpl implements PlatService { // 一个内部模板可以映射多个渠道商 queryWrapper.eq(MNSChannelMessageTemplate::getInnerTemplateNo, request.getTemplateNo()); List list = mnsChannelMessageTemplateMapper.selectList(queryWrapper); - if(CollectionUtils.isNotEmpty(list)){ + if (CollectionUtils.isNotEmpty(list)) { MNSChannelMessageTemplate channelMessageTemplate = list.get(0); String templateNo = channelMessageTemplate.getTemplateNo(); String innerTemplateNo = channelMessageTemplate.getInnerTemplateNo(); String templatNo = templateNo.equals(request.getTemplateAliNo()) ? templateNo : innerTemplateNo; - throw new BizException(ReturnCodeEnum.FAIL,"模板编码已存在:" + templatNo); + throw new BizException(ReturnCodeEnum.FAIL, "模板编码已存在:" + templatNo); } } @@ -261,8 +250,8 @@ public class PlatServiceImpl implements PlatService { @Override @Transactional(rollbackFor = Exception.class) public void delete(String templateNo) { - if(StringUtils.isBlank(templateNo)){ - throw new BizException(ReturnCodeEnum.FAIL,"短信模板编码不能为空"); + if (StringUtils.isBlank(templateNo)) { + throw new BizException(ReturnCodeEnum.FAIL, "短信模板编码不能为空"); } mnsMessageTemplateMapper.deleteByTemplateNo(templateNo); From da732d8702eb0c20c4d2177d1f9a065c35e5d32b Mon Sep 17 00:00:00 2001 From: luofu Date: Thu, 26 Oct 2023 17:15:03 +0800 Subject: [PATCH 45/50] =?UTF-8?q?feat(REQ-1465):=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E5=8F=82=E6=95=B0=E6=8B=BC=E6=8E=A5=E7=AE=97?= =?UTF-8?q?=E6=B3=95=E4=BF=AE=E6=94=B9?= 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、消息路由参数拼接算法修改 影响: 无 --- .../axzo/msg/center/utils/MessageRouterUtil.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java b/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java index 0b370d57..658c47f1 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java @@ -120,15 +120,15 @@ public final class MessageRouterUtil { } private static String concatRouterParam(String originalUrl, JSONObject routerParam) { - StringBuilder concatUrlBuilder = new StringBuilder(originalUrl); - if (!originalUrl.contains("?")) { - concatUrlBuilder.append("?"); - } - + StringBuilder paramBuilder = new StringBuilder(); for (Map.Entry entry : routerParam.entrySet()) { - concatUrlBuilder.append("&").append(entry.getKey()).append("=").append(entry.getValue()); + paramBuilder.append("&").append(entry.getKey()).append("=").append(entry.getValue()); } - return concatUrlBuilder.toString(); + if (!originalUrl.contains("?")) { + // 替换掉第一个参数分隔符(&) + paramBuilder.replace(0, 1, "?"); + } + return originalUrl + paramBuilder; } /** From dd9aecdaff723fbce2f3be6afb8214472357b0af Mon Sep 17 00:00:00 2001 From: luofu Date: Fri, 27 Oct 2023 14:24:19 +0800 Subject: [PATCH 46/50] =?UTF-8?q?feat(REQ-1465):=20=E6=96=B0=E8=80=81?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E6=A8=A1=E6=9D=BF=E6=98=A0=E5=B0=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=88=9D=E5=A7=8B=E5=8C=96=E5=8A=9F=E8=83=BD?= 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 | 16 ++ .../param/RelationTemplateMapInitParam.java | 31 ++++ .../vo/RelationTemplateMapInitRequest.java | 33 ++++ .../service/MessageTemplateGroupService.java | 7 + .../service/RelationTemplateMapService.java | 5 + .../impl/MessageTemplateGroupServiceImpl.java | 25 +++ .../impl/RelationTemplateMapServiceImpl.java | 148 ++++++++++++++++++ .../service/enums/TerminalTypeEnum.java | 8 + .../domain/entity/RelationTemplateMap.java | 4 +- start/src/main/resources/bootstrap.yml | 2 +- 10 files changed, 276 insertions(+), 3 deletions(-) create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/RelationTemplateMapInitParam.java create mode 100644 inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/RelationTemplateMapInitRequest.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 629ed2c9..c24681cd 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 @@ -1,7 +1,11 @@ package cn.axzo.msg.center.message.controller; +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.RelationTemplateMapService; 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.MessageTemplatePageRequest; @@ -12,8 +16,12 @@ import cn.axzo.msg.center.service.template.response.MessageTemplatePageResponse; import cn.azxo.framework.common.model.CommonResponse; import cn.azxo.framework.common.model.Page; 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 javax.validation.Valid; import java.util.Collection; import java.util.List; @@ -29,6 +37,7 @@ import java.util.List; public class MessageTemplateController implements MessageTemplateClient { private final MessageTemplateNewService messageTemplateNewService; + private final RelationTemplateMapService relationTemplateMapService; @Override public CommonResponse save(MessageTemplateCreateRequest request) { @@ -62,4 +71,11 @@ public class MessageTemplateController implements MessageTemplateClient { messageTemplateNewService.updateStatus(request.getOperatorId(), request.getTemplateCode(), request.getStatus()); return CommonResponse.success(); } + + @PostMapping(value = "/message/template/relation/init", produces = {MediaType.APPLICATION_JSON_VALUE}) + public CommonResponse initRelationTemplateMap(@RequestBody @Valid RelationTemplateMapInitRequest request) { + RelationTemplateMapInitParam param = BeanConverter.convert(request, RelationTemplateMapInitParam.class); + relationTemplateMapService.init(param); + return CommonResponse.success(); + } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/RelationTemplateMapInitParam.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/RelationTemplateMapInitParam.java new file mode 100644 index 00000000..cb1bca6a --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/param/RelationTemplateMapInitParam.java @@ -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 relationIds; + private String groupNodeCode; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/RelationTemplateMapInitRequest.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/RelationTemplateMapInitRequest.java new file mode 100644 index 00000000..f8a49139 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/RelationTemplateMapInitRequest.java @@ -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 relationIds; + @NotBlank(message = "groupNodeCode is required") + private String groupNodeCode; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java index 0c7e2ec1..0cd3bf30 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/MessageTemplateGroupService.java @@ -29,6 +29,13 @@ public interface MessageTemplateGroupService { */ void templateGroup(String templateNode, Collection groupNodeCodes); + /** + * 模板关联分类 + * + * @param templateGroupMap 模板编码与分类结点编码列表的map + */ + void templateGroup(Map> templateGroupMap); + /** * 更新模板的分类关系 * diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/RelationTemplateMapService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/RelationTemplateMapService.java index 2210cbcc..327b90ec 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/RelationTemplateMapService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/RelationTemplateMapService.java @@ -1,5 +1,8 @@ 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; @@ -15,4 +18,6 @@ public interface RelationTemplateMapService { Optional queryByRelationId(Long relationId); void mapRelationAndTemplate(Map map); + + void init(RelationTemplateMapInitParam param); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java index eb753d69..d7d1045d 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateGroupServiceImpl.java @@ -1,6 +1,7 @@ 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.domain.entity.MessageTemplateGroup; @@ -18,6 +19,7 @@ import java.util.Collections; 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; @@ -67,6 +69,29 @@ public class MessageTemplateGroupServiceImpl implements MessageTemplateGroupServ messageTemplateGroupDao.saveBatch(rows); } + @Override + public void templateGroup(Map> templateGroupMap) { + if (MapUtil.isEmpty(templateGroupMap)) { + log.info("the templateGroupMap is empty."); + return; + } + Set groupNodes = templateGroupMap.values().stream() + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + Map pathMap = messageGroupNodeService.leafGroupNodeCodePaths(groupNodes); + List 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 groupNodeCodes) { // 先解除之前的关联关系 diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/RelationTemplateMapServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/RelationTemplateMapServiceImpl.java index bcd4f513..381a60ec 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/RelationTemplateMapServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/RelationTemplateMapServiceImpl.java @@ -1,11 +1,39 @@ 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; @@ -13,6 +41,8 @@ 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; /** @@ -27,7 +57,13 @@ import java.util.stream.Collectors; @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 queryByRelationId(Long relationId) { @@ -61,4 +97,116 @@ public class RelationTemplateMapServiceImpl implements RelationTemplateMapServic }).collect(Collectors.toList()); relationTemplateMapDao.saveBatch(rows); } + + @Override + @Transactional(rollbackFor = Exception.class) + public void init(RelationTemplateMapInitParam param) { + List 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 relationIdTemplateIdMap = allRelations.stream() + .collect(Collectors.toMap(MessageRelation::getId, MessageRelation::getTemplateId)); + // 获取已经建立关联关系的relationId集合 + Set mappedRelationIds = getAllOriginalRelationIds(); + // 过滤掉已经建立关联关系的relationId + relationIdTemplateIdMap = relationIdTemplateIdMap.entrySet().stream() + .filter(e -> !mappedRelationIds.contains(e.getKey())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + // 获取生效中的模板 + Map 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> messageRouters = messageRouterService.getRouterMapByRelationIds( + Lists.newArrayList(relationIdTemplateIdMap.keySet())).stream() + .collect(Collectors.groupingBy(MessageRouter::getRelationId)); + // 转化为新模板的数据模型wrapper + List 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 groupNodes = Lists.newArrayList(param.getGroupNodeCode()); + Map> templateGroupNodeMap = wrappers.stream() + .map(CreateNewTemplateAndMapWrapper::getBaseTemplate) + .collect(Collectors.toMap(MessageBaseTemplate::getCode, e -> groupNodes)); + messageTemplateGroupService.templateGroup(templateGroupNodeMap); + Map relationIdTemplateCodeMap = wrappers.stream() + .collect(Collectors + .toMap(CreateNewTemplateAndMapWrapper::getRelationId, e -> e.getBaseTemplate().getCode())); + mapRelationAndTemplate(relationIdTemplateCodeMap); + } + + private CreateNewTemplateAndMapWrapper convert(Long relationId, MessageTemplate template, + List 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 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 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 routers; + } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/TerminalTypeEnum.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/TerminalTypeEnum.java index 6f1fde50..f9daae5f 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/TerminalTypeEnum.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/TerminalTypeEnum.java @@ -4,6 +4,8 @@ import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; +import java.util.Arrays; + /** * @description * @@ -45,4 +47,10 @@ public enum TerminalTypeEnum { } return WEB; } + + public static TerminalTypeEnum codeOf(Integer code) { + return Arrays.stream(values()) + .filter(e -> e.code.equals(code)) + .findFirst().orElse(null); + } } diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/RelationTemplateMap.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/RelationTemplateMap.java index 5cf8cc36..c61775f2 100644 --- a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/RelationTemplateMap.java +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/RelationTemplateMap.java @@ -1,6 +1,6 @@ package cn.axzo.msg.center.domain.entity; -import cn.axzo.msg.center.domain.persistence.BaseEntity; +import cn.axzo.msg.center.domain.persistence.BaseEntityExt; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Getter; @@ -16,7 +16,7 @@ import java.io.Serializable; @Setter @Getter @TableName("relation_template_map") -public class RelationTemplateMap extends BaseEntity implements Serializable { +public class RelationTemplateMap extends BaseEntityExt implements Serializable { private static final long serialVersionUID = 2716916154882729387L; diff --git a/start/src/main/resources/bootstrap.yml b/start/src/main/resources/bootstrap.yml index 6178cbd1..88309f4f 100644 --- a/start/src/main/resources/bootstrap.yml +++ b/start/src/main/resources/bootstrap.yml @@ -7,7 +7,7 @@ spring: nacos: config: #nacos 服务地址 - server-addr: ${NACOS_HOST:dev-nacos.axzo.cn}:${NACOS_PORT:80} + server-addr: ${NACOS_HOST:https://dev-nacos.axzo.cn}:${NACOS_PORT:443} # 文件格式 file-extension: yaml # 指定命名空间 From da3b850b9c4a1a9a9e2c42e87415e34b8bead415 Mon Sep 17 00:00:00 2001 From: luofu Date: Fri, 27 Oct 2023 17:01:48 +0800 Subject: [PATCH 47/50] =?UTF-8?q?feat(REQ-1465):=20=E5=AD=90=E6=A0=87?= =?UTF-8?q?=E9=A2=98=E6=95=B0=E6=8D=AE=E8=BF=87=E6=BB=A4?= 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、子标题数据过滤 影响: 无 --- .../domain/vo/GeneralMessagePushVO.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/GeneralMessagePushVO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/GeneralMessagePushVO.java index 14369b77..5216d5b6 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/GeneralMessagePushVO.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/vo/GeneralMessagePushVO.java @@ -12,10 +12,12 @@ 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; /** @@ -95,13 +97,18 @@ public class GeneralMessagePushVO implements Serializable { cardContentItems.stream() .map(CardExtensionItem::from) .collect(Collectors.toList()); + List subtitles = Collections.emptyList(); + Optional 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(Lists.newArrayList(Subtitle.from(record, orgIcon))) + .subtitles(subtitles) .cardContent(record.getContent()) .cardExtension(cardExtension) .cardButtons(cardButtons) @@ -131,11 +138,14 @@ public class GeneralMessagePushVO implements Serializable { */ private String title; - static Subtitle from(GeneralMessageRecord record, String orgIcon) { - return Subtitle.builder() + static Optional from(GeneralMessageRecord record, String orgIcon) { + if (StringUtils.isBlank(record.getOrgName())) { + return Optional.empty(); + } + return Optional.of(Subtitle.builder() .title(record.getOrgName()) .iconUrl(orgIcon) - .build(); + .build()); } @Override From 8902a36fe282c27794dc05a1efba14b7abe95dfb Mon Sep 17 00:00:00 2001 From: luofu Date: Mon, 30 Oct 2023 14:27:50 +0800 Subject: [PATCH 48/50] =?UTF-8?q?feat(REQ-1465):=20=E5=AD=90=E6=A0=87?= =?UTF-8?q?=E9=A2=98=E6=95=B0=E6=8D=AE=E8=BF=87=E6=BB=A4?= 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、子标题数据过滤 影响: 无 --- .../service/impl/MessageSendTwiceRecordServiceImpl.java | 5 ++--- .../msg/center/domain/entity/MessageSendTwiceRecord.java | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageSendTwiceRecordServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageSendTwiceRecordServiceImpl.java index 093dccdc..05c66a8a 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageSendTwiceRecordServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageSendTwiceRecordServiceImpl.java @@ -1,6 +1,5 @@ package cn.axzo.msg.center.message.service.impl; -import cn.axzo.msg.center.common.enums.TableIsDeleteEnum; import cn.axzo.msg.center.dal.MessageSendTwiceRecordDao; import cn.axzo.msg.center.domain.entity.MessageSendTwiceRecord; import cn.axzo.msg.center.message.service.MessageSendTwiceRecordService; @@ -34,10 +33,10 @@ public class MessageSendTwiceRecordServiceImpl implements MessageSendTwiceRecord log.info("personId is null."); return Collections.emptyList(); } - // TODO:[cold_blade] [P2] 此处的代码仅做一个双发兜底的策略,后期应当全走新的消息发送流程 return messageSendTwiceRecordDao.lambdaQuery() .eq(MessageSendTwiceRecord::getReceiverPersonId, personId) - .eq(MessageSendTwiceRecord::getIsDelete, TableIsDeleteEnum.NORMAL.value) + .last("LIMIT 500") + .orderByDesc(MessageSendTwiceRecord::getId) .select(MessageSendTwiceRecord::getOriginalMsgId) .list().stream() .map(MessageSendTwiceRecord::getOriginalMsgId) diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageSendTwiceRecord.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageSendTwiceRecord.java index 1fe2184c..1f2457f7 100644 --- a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageSendTwiceRecord.java +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageSendTwiceRecord.java @@ -1,6 +1,6 @@ package cn.axzo.msg.center.domain.entity; -import cn.axzo.msg.center.domain.persistence.BaseEntity; +import cn.axzo.msg.center.domain.persistence.BaseEntityExt; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Getter; @@ -16,7 +16,7 @@ import java.io.Serializable; @Setter @Getter @TableName("message_send_twice_record") -public class MessageSendTwiceRecord extends BaseEntity implements Serializable { +public class MessageSendTwiceRecord extends BaseEntityExt implements Serializable { private static final long serialVersionUID = 3517821492158061709L; From 75bd1d92abfab908f29278fd5f2d75cb59f651db Mon Sep 17 00:00:00 2001 From: luofu Date: Mon, 30 Oct 2023 15:22:39 +0800 Subject: [PATCH 49/50] =?UTF-8?q?feat(REQ-1465):=20IM=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=89=A9=E5=B1=95=E5=AD=97=E6=AE=B5=E6=96=B0=E5=A2=9EorgId?= =?UTF-8?q?=E6=95=B0=E6=8D=AE?= 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、IM消息扩展字段新增orgId数据 影响: 无 --- .../center/message/service/impl/GeneralMessageServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java index d5696601..0ab4e86a 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/GeneralMessageServiceImpl.java @@ -164,6 +164,9 @@ public class GeneralMessageServiceImpl implements GeneralMessageService { // 扩展信息 Map 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> result = messageApi.sendMessage(msgInfo); From 756a5f4f53c99c98d85574eb79d0258e29096974 Mon Sep 17 00:00:00 2001 From: luofu Date: Mon, 30 Oct 2023 20:21:49 +0800 Subject: [PATCH 50/50] =?UTF-8?q?feat(REQ-1465):=20IM=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=89=A9=E5=B1=95=E5=AD=97=E6=AE=B5=E6=96=B0=E5=A2=9EorgId?= =?UTF-8?q?=E6=95=B0=E6=8D=AE?= 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、IM消息扩展字段新增orgId数据 影响: 无 --- .../main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java b/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java index 658c47f1..05afda6b 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/utils/MessageRouterUtil.java @@ -122,6 +122,9 @@ public final class MessageRouterUtil { private static String concatRouterParam(String originalUrl, JSONObject routerParam) { StringBuilder paramBuilder = new StringBuilder(); for (Map.Entry entry : routerParam.entrySet()) { + if (originalUrl.contains(entry.getKey() + "=")) { + continue; + } paramBuilder.append("&").append(entry.getKey()).append("=").append(entry.getValue()); } if (!originalUrl.contains("?")) {