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"; }