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/MessageTemplateDTO.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageTemplateDTO.java
index 88fafc90..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,16 +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
@@ -45,9 +52,9 @@ public class MessageTemplateDTO implements Serializable {
*/
private String content;
/**
- * 卡片信息,json字串
+ * 消息卡片信息标签列表
*/
- private String cardContent;
+ private List msgCardContentItems;
/**
* 所属消息类型
*/
@@ -60,6 +67,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()
@@ -67,13 +82,24 @@ 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)
+ .pushTerminals(JSON.parseArray(baseTemplate.getPushTerminal(), PushTerminalEnum.class))
+ .minAppVersion(baseTemplate.getMinAppVersion())
.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/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..ac202bfb
--- /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.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;
+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.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 String orgIcon = "www.baidu.com";
+
+ 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())
+ .senderPersonId(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());
+ 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.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 GeneralMessagePushVO convert(GeneralMessageRecord record, MessageTemplateDTO template) {
+ // 对应模板的路由列表
+ List rawRouters = template.getRouters();
+ // 解析路由地址
+ List routers = rawRouters.stream()
+ .map(e -> MessageRouterUtil.parseAndConcatRouteUrl(e, record.getRouterParams()))
+ .collect(Collectors.toList());
+ // 转化成客户端展示的数据模型
+ List routerButtons = routers.stream()
+ .map(RawMessageRouterDTO::toMessageRouterButton)
+ .collect(Collectors.toList());
+ // 获取模板卡片信息
+ 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 GeneralMessagePushVO.from(record, template.getIcon(), orgIcon, routerButtons, cardContentItems);
+ }
+
+ 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/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 9c752d85..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
@@ -8,13 +8,16 @@ 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;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
+import java.util.stream.Collectors;
/**
* @description
@@ -47,6 +50,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 +96,41 @@ public final class MessageRouterUtil {
}
}
+ /**
+ * 解析模板上配置的路由地址,将发送消息时的参数替换上去,并将路由参数追加到模板的路由地址后面,兼容APP端新老版本
+ *
+ * @param router 路由信息
+ * @param routerParam 路由参数
+ * @return RawMessageRouterDTO
+ */
+ public static RawMessageRouterDTO parseAndConcatRouteUrl(RawMessageRouterDTO router, JSONObject routerParam) {
+ // 路由参数有效
+ if (Objects.nonNull(routerParam) && !routerParam.isEmpty()) {
+ // 拷贝一份,避免修改入参
+ router = router.deepClone();
+ router.getTerminals().forEach(e -> {
+ // 替换原始URL中的参数变量
+ String routerUrl = PlaceholderResolver.getDefaultResolver().resolveByMap(e.getUrl(), routerParam);
+ // 将routerParam追加到原始的URL后面
+ routerUrl = concatRouterParam(routerUrl, routerParam);
+ e.setUrl(routerUrl);
+ });
+ }
+ 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();
+ }
+
/**
* 解析按钮style
*
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/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/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/enums/PushTerminalEnum.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/PushTerminalEnum.java
index c52deaf6..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,12 +18,13 @@ public enum PushTerminalEnum {
/**
* B-安心筑企业版
*/
- B_ENTERPRISE_APP("B-安心筑企业版"),
+ B_ENTERPRISE_APP("B-安心筑企业版", "CMP"),
/**
* C-安心筑工人版
*/
- C_WORKER_APP("C-安心筑工人版"),
+ C_WORKER_APP("C-安心筑工人版", "CM"),
;
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-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;
/**
* 消息内容
*/
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..363da982
--- /dev/null
+++ b/start/src/main/java/cn/axzo/msg/center/FeignConfig.java
@@ -0,0 +1,55 @@
+package cn.axzo.msg.center;
+
+import feign.RequestInterceptor;
+import feign.RequestTemplate;
+import feign.Target;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.annotation.Profile;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+
+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;
+
+ 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> target = requestTemplate.feignTarget();
+ String profile = environment.getProperty("spring.profiles.active");
+ 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());
+ }
+ }
+ }
+
+ @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";
}