Merge branch 'feature/REQ-1465' into 'dev'

Feature/req 1465

See merge request universal/infrastructure/backend/msg-center-plat!62
This commit is contained in:
罗福 2023-10-12 10:21:34 +00:00
commit 823f121dd0
30 changed files with 798 additions and 145 deletions

View File

@ -4,7 +4,8 @@ import cn.axzo.msg.center.message.domain.param.MessageTemplateCreateParam;
import cn.axzo.msg.center.message.service.MessageTemplateNewService; import cn.axzo.msg.center.message.service.MessageTemplateNewService;
import cn.axzo.msg.center.service.template.client.MessageTemplateClient; import cn.axzo.msg.center.service.template.client.MessageTemplateClient;
import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest; import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest;
import cn.axzo.msg.center.service.template.request.MessageTemplateMoveToRequest; import cn.axzo.msg.center.service.template.request.MessageTemplateUpdateRequest;
import cn.axzo.msg.center.service.template.response.MessageTemplateDetailResponse;
import cn.azxo.framework.common.model.CommonResponse; import cn.azxo.framework.common.model.CommonResponse;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -23,15 +24,21 @@ public class MessageTemplateController implements MessageTemplateClient {
private final MessageTemplateNewService messageTemplateNewService; private final MessageTemplateNewService messageTemplateNewService;
@Override @Override
public CommonResponse<String> addTemplate(MessageTemplateCreateRequest request) { public CommonResponse<String> save(MessageTemplateCreateRequest request) {
MessageTemplateCreateParam param = MessageTemplateCreateParam.from(request); MessageTemplateCreateParam param = MessageTemplateCreateParam.from(request);
messageTemplateNewService.createTemplate(param); messageTemplateNewService.createTemplate(param);
return CommonResponse.success(param.getTemplateCode()); return CommonResponse.success(param.getTemplateCode());
} }
@Override @Override
public CommonResponse<String> batchMove(MessageTemplateMoveToRequest request) { public CommonResponse<Void> update(MessageTemplateUpdateRequest request) {
// TODO: [cold_blade] [P2] 模板关联的批量移动 // TODO:[cold_blade] [P0] update template
return null;
}
@Override
public CommonResponse<MessageTemplateDetailResponse> detail(String templateCode) {
// TODO:[cold_blade] [P0] query template
return null; return null;
} }
} }

View File

@ -1,9 +1,13 @@
package cn.axzo.msg.center.message.domain.dto; package cn.axzo.msg.center.message.domain.dto;
import cn.axzo.msg.center.domain.entity.MessageTemplateRouter; import cn.axzo.msg.center.domain.entity.MessageTemplateRouter;
import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO;
import cn.axzo.msg.center.service.dto.MessageRouterDTO; import cn.axzo.msg.center.service.dto.MessageRouterDTO;
import cn.axzo.msg.center.service.dto.MessageRouterTerminalDTO;
import cn.axzo.msg.center.service.enums.ButtonStyleEnum;
import cn.axzo.msg.center.service.enums.RouterCategoryEnum; import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum; import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.utils.MessageRouterUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
@ -12,6 +16,8 @@ import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;
/** /**
* @description * @description
@ -40,51 +46,64 @@ public class RawMessageRouterDTO implements Serializable {
*/ */
private RouterCategoryEnum category; private RouterCategoryEnum category;
/** /**
* 页面地址 OR API接口地址 * 路由终端
*/ */
private String url; private List<MessageRouterTerminalDTO> terminals;
/**
* 页面地址所属应用端(如果是API接口地址,请忽略改字段值)
* WEB: web端页面
* MINI_PROGRAM: 安心筑小程序端页面
* IOS: 原生IOS端页面
* ANDROID: 原生Android端页面
* WEB_VIEW: H5页面
* WECHAT_MINI_PROGRAM: 微信小程序页面
*/
private TerminalTypeEnum terminalType;
/** /**
* 模板编码 * 模板编码
*/ */
private String templateCode; private String templateCode;
/**
* 按钮样式配置
*/
private List<ButtonStyleEnum> style;
public static RawMessageRouterDTO from(MessageTemplateRouter msgTemplateRouter) { public static RawMessageRouterDTO from(List<MessageTemplateRouter> msgTemplateRouters) {
MessageTemplateRouter router = msgTemplateRouters.get(0);
return RawMessageRouterDTO.builder() return RawMessageRouterDTO.builder()
.desc(msgTemplateRouter.getName()) .desc(router.getName())
.url(msgTemplateRouter.getUrl()) .category(router.getCategory())
.category(msgTemplateRouter.getCategory()) .templateCode(router.getTemplateCode())
.terminalType(msgTemplateRouter.getTerminalType()) .style(JSON.parseArray(router.getStyle(), ButtonStyleEnum.class))
.templateCode(msgTemplateRouter.getTemplateCode()) .terminals(JSON.parseArray(router.getStyle(), MessageRouterTerminalDTO.class))
.build(); .build();
} }
public static RawMessageRouterDTO from(MessageRouterDTO router, String templateCode) { public static RawMessageRouterDTO from(MessageRouterButtonDTO router, String templateCode) {
return RawMessageRouterDTO.builder() return RawMessageRouterDTO.builder()
.desc(router.getDesc()) .desc(router.getDesc())
.url(router.getUrl())
.category(router.getCategory()) .category(router.getCategory())
.terminalType(router.getTerminalType()) .terminals(router.getTerminals())
.style(router.getStyle())
.templateCode(templateCode) .templateCode(templateCode)
.build(); .build();
} }
public MessageTemplateRouter toMessageTemplateRouter() { public List<MessageTemplateRouter> toMessageTemplateRouters() {
return this.terminals.stream()
.map(this::convert)
.collect(Collectors.toList());
}
public MessageRouterDTO toMessageRouter(TerminalTypeEnum terminalType) {
MessageRouterTerminalDTO terminal = MessageRouterUtil.select(this, terminalType);
return MessageRouterDTO.builder()
.desc(this.desc)
.category(this.category)
.style(this.style)
.terminalType(terminal.getTerminalType())
.url(terminal.getUrl())
.build();
}
private MessageTemplateRouter convert(MessageRouterTerminalDTO terminal) {
MessageTemplateRouter router = new MessageTemplateRouter(); MessageTemplateRouter router = new MessageTemplateRouter();
router.setName(this.desc); router.setName(desc);
router.setUrl(this.url); router.setCategory(category);
router.setCategory(this.category); router.setTemplateCode(templateCode);
router.setTerminalType(this.terminalType); router.setStyle(JSON.toJSONString(style));
router.setTemplateCode(this.templateCode); router.setUrl(terminal.getUrl());
router.setTerminalType(terminal.getTerminalType());
return router; return router;
} }

View File

@ -1,5 +1,6 @@
package cn.axzo.msg.center.message.domain.param; package cn.axzo.msg.center.message.domain.param;
import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO;
import cn.axzo.msg.center.service.dto.MessageRouterDTO; import cn.axzo.msg.center.service.dto.MessageRouterDTO;
import cn.axzo.msg.center.service.enums.MessageCategoryEnum; import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest; import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest;
@ -67,7 +68,7 @@ public class MessageTemplateCreateParam implements Serializable {
/** /**
* 路由列表 * 路由列表
*/ */
private List<MessageRouterDTO> routers; private List<MessageRouterButtonDTO> routers;
public static MessageTemplateCreateParam from(MessageTemplateCreateRequest request) { public static MessageTemplateCreateParam from(MessageTemplateCreateRequest request) {
return MessageTemplateCreateParam.builder() return MessageTemplateCreateParam.builder()

View File

@ -36,9 +36,7 @@ public class MessageTemplateRouterServiceImpl implements MessageTemplateRouterSe
log.warn("the template code is blank."); log.warn("the template code is blank.");
return Collections.emptyList(); return Collections.emptyList();
} }
return messageTemplateRouterDao.listByTemplateCode(Lists.newArrayList(templateCode)).stream() return listByTemplateCodes(Lists.newArrayList(templateCode));
.map(RawMessageRouterDTO::from)
.collect(Collectors.toList());
} }
@Override @Override
@ -47,7 +45,7 @@ public class MessageTemplateRouterServiceImpl implements MessageTemplateRouterSe
return; return;
} }
List<MessageTemplateRouter> messageTemplateRouters = routers.stream() List<MessageTemplateRouter> messageTemplateRouters = routers.stream()
.map(RawMessageRouterDTO::toMessageTemplateRouter) .flatMap(e -> e.toMessageTemplateRouters().stream())
.collect(Collectors.toList()); .collect(Collectors.toList());
messageTemplateRouterDao.saveBatch(messageTemplateRouters); messageTemplateRouterDao.saveBatch(messageTemplateRouters);
} }
@ -57,8 +55,22 @@ public class MessageTemplateRouterServiceImpl implements MessageTemplateRouterSe
if (CollectionUtils.isEmpty(templateCodes)) { if (CollectionUtils.isEmpty(templateCodes)) {
return Collections.emptyMap(); return Collections.emptyMap();
} }
return messageTemplateRouterDao.listByTemplateCode(templateCodes).stream() return listByTemplateCodes(templateCodes).stream()
.map(RawMessageRouterDTO::from)
.collect(Collectors.groupingBy(RawMessageRouterDTO::getTemplateCode)); .collect(Collectors.groupingBy(RawMessageRouterDTO::getTemplateCode));
} }
private List<RawMessageRouterDTO> listByTemplateCodes(List<String> templateCodes) {
// 根据模板编码进行分组
Map<String, List<MessageTemplateRouter>> routers = messageTemplateRouterDao
.listByTemplateCode(templateCodes).stream()
.collect(Collectors.groupingBy(MessageTemplateRouter::getTemplateCode));
return routers.values().stream()
.flatMap(e -> {
// 模板路由的按钮维度
Map<String, List<MessageTemplateRouter>> btnMap = e.stream()
.collect(Collectors.groupingBy(MessageTemplateRouter::getName));
return btnMap.values().stream()
.map(RawMessageRouterDTO::from);
}).collect(Collectors.toList());
}
} }

View File

@ -1,6 +1,5 @@
package cn.axzo.msg.center.message.service.impl; package cn.axzo.msg.center.message.service.impl;
import cn.axzo.core.utils.converter.BeanConverter;
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum; import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
import cn.axzo.msg.center.common.exception.ServiceException; import cn.axzo.msg.center.common.exception.ServiceException;
import cn.axzo.msg.center.common.utils.PlaceholderResolver; import cn.axzo.msg.center.common.utils.PlaceholderResolver;
@ -169,13 +168,14 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
.findFirst() .findFirst()
.map(MessageTemplateDTO::getRouters) .map(MessageTemplateDTO::getRouters)
.orElseGet(Collections::emptyList); .orElseGet(Collections::emptyList);
rawRouters = MessageRouterUtil.selectRouter(rawRouters, terminalType); List<MessageRouterDTO> routers = rawRouters.stream()
List<MessageRouterDTO> routers = rawRouters.stream().map(e -> { .map(e -> {
MessageRouterDTO router = BeanConverter.convert(e, MessageRouterDTO.class); MessageRouterDTO router = e.toMessageRouter(terminalType);
// 视情况替换原始URL中的参数变量 // 视情况替换原始URL中的参数变量
MessageRouterUtil.parseRouteUrl(router, pendingMessageRecord.getRouterParams()); MessageRouterUtil.parseRouteUrl(router, pendingMessageRecord.getRouterParams());
return router; return router;
}).collect(Collectors.toList()); })
.collect(Collectors.toList());
pendingMessage.setRouters(routers); pendingMessage.setRouters(routers);
// 获取模板卡片信息 // 获取模板卡片信息
String cardContent = messageTemplates.stream() String cardContent = messageTemplates.stream()

View File

@ -3,10 +3,10 @@ package cn.axzo.msg.center.utils;
import cn.axzo.msg.center.common.utils.PlaceholderResolver; import cn.axzo.msg.center.common.utils.PlaceholderResolver;
import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO; import cn.axzo.msg.center.message.domain.dto.RawMessageRouterDTO;
import cn.axzo.msg.center.service.dto.MessageRouterDTO; import cn.axzo.msg.center.service.dto.MessageRouterDTO;
import cn.axzo.msg.center.service.dto.MessageRouterTerminalDTO;
import cn.axzo.msg.center.service.enums.RouterCategoryEnum; import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum; import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.google.common.collect.ImmutableMap;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
@ -30,32 +30,22 @@ public final class MessageRouterUtil {
// 非法路由参数的定义 // 非法路由参数的定义
private static final String INVALID_ROUTER_PARAM = "null"; private static final String INVALID_ROUTER_PARAM = "null";
// 当前系统选取路由的优先级策略
private static final ImmutableMap<TerminalTypeEnum, Integer> ROUTER_SELECT_ORDER =
ImmutableMap.<TerminalTypeEnum, Integer>builder()
.put(TerminalTypeEnum.WEB_VIEW, 1)
.put(TerminalTypeEnum.MINI_PROGRAM, 2)
.put(TerminalTypeEnum.ANDROID, 3)
.put(TerminalTypeEnum.IOS, 3)
.put(TerminalTypeEnum.WEB, 3)
.put(TerminalTypeEnum.WECHAT_MINI_PROGRAM, 3)
.build();
/** /**
* 根据指定的终端类型选取合适的路由 * 根据指定的终端类型选取合适的路由
* *
* @param messageRouters 模板配置的路由列表 * @param rawMessageRouter 原始的模板路由策略
* @param terminalType 指定的终端类型可为null * @param terminalType 当前请求的终端类型
* @return 合适的路由 * @return 合适的路由数据
*/ */
public static List<RawMessageRouterDTO> selectRouter(List<RawMessageRouterDTO> messageRouters, public static MessageRouterTerminalDTO select(RawMessageRouterDTO rawMessageRouter, TerminalTypeEnum terminalType) {
TerminalTypeEnum terminalType) { if (RouterCategoryEnum.ACTION.equals(rawMessageRouter.getCategory())) {
if (CollectionUtils.isEmpty(messageRouters)) { return rawMessageRouter.getTerminals().get(0);
return Collections.emptyList();
} }
return messageRouters.stream() return rawMessageRouter.getTerminals().stream()
.filter(e -> Objects.equals(e.getTerminalType(), terminalType)) .filter(e -> Objects.equals(terminalType, e.getTerminalType()))
.collect(Collectors.toList()); // 若没有匹配的默认选择第一个然后由前端去进行最终判断
.findFirst().orElseGet(() -> rawMessageRouter.getTerminals().get(0));
} }
/** /**
@ -76,31 +66,12 @@ public final class MessageRouterUtil {
* @param routerParam 路由参数 * @param routerParam 路由参数
*/ */
public static void parseRouteUrl(MessageRouterDTO router, String routerParam) { public static void parseRouteUrl(MessageRouterDTO router, String routerParam) {
// 路由参数有效且是直接调整页面地址的路由类型 // 路由参数有效
if (isRouterParamValid(routerParam) if (isRouterParamValid(routerParam)) {
&& RouterCategoryEnum.JUMP.equals(router.getCategory())) {
// 替换原始URL中的参数变量 // 替换原始URL中的参数变量
String routerUrl = PlaceholderResolver String routerUrl = PlaceholderResolver
.getDefaultResolver().resolveByMap(router.getUrl(), JSON.parseObject(routerParam)); .getDefaultResolver().resolveByMap(router.getUrl(), JSON.parseObject(routerParam));
router.setUrl(routerUrl); router.setUrl(routerUrl);
} }
} }
private static Integer compare(RawMessageRouterDTO src, RawMessageRouterDTO tgt) {
if (Objects.isNull(tgt)) {
// NULL 默认优先级最低
return 1;
}
Integer srcOrder = ROUTER_SELECT_ORDER.get(src.getTerminalType());
Integer tgtOrder = ROUTER_SELECT_ORDER.get(tgt.getTerminalType());
if (Objects.isNull(srcOrder)) {
// 新增的类型未指定优先级的话,则默认最低
return 1;
}
if (Objects.isNull(tgtOrder)) {
// 新增的类型未指定优先级的话,则默认最低
return -1;
}
return srcOrder.compareTo(tgtOrder);
}
} }

View File

@ -0,0 +1,66 @@
package cn.axzo.msg.center.service.dto;
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.io.Serializable;
import java.util.List;
/**
* @author cold_blade
* @date 2023/10/11
* @version 1.0
*/
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MessageBaseTemplateDTO implements Serializable {
private static final long serialVersionUID = -7079227473990043416L;
/**
* 模板名称
*/
private String name;
/**
* 系统自动生成的模板code
*/
private String code;
/**
* 所属消息类型
*/
private MessageCategoryEnum msgCategory;
/**
* 模板标题
*/
private String title;
/**
* 模板类容
*/
private String content;
/**
* 卡片信息,json字串
*/
private String cardContent;
/**
* 模板icon
*/
private String icon;
/**
* 推送终端配置列表
*/
private List<PushTerminalEnum> pushTerminals;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,54 @@
package cn.axzo.msg.center.service.dto;
import cn.axzo.msg.center.service.enums.ButtonStyleEnum;
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.io.Serializable;
import java.util.List;
/**
* @description
*
* @author cold_blade
* @date 2023/9/23
* @version 1.0
*/
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MessageRouterButtonDTO implements Serializable {
private static final long serialVersionUID = -9083376003614521781L;
/**
* 路由描述
*/
private String desc;
/**
* 路由分类
* JUMP: 直接跳转
* ACTION: 接口调用
*/
private RouterCategoryEnum category;
/**
* 按钮样式配置
*/
private List<ButtonStyleEnum> style;
/**
* 路由终端列表若当前按钮为ACTION则只能配一个接口地址
*/
private List<MessageRouterTerminalDTO> terminals;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -1,5 +1,6 @@
package cn.axzo.msg.center.service.dto; package cn.axzo.msg.center.service.dto;
import cn.axzo.msg.center.service.enums.ButtonStyleEnum;
import cn.axzo.msg.center.service.enums.RouterCategoryEnum; import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum; import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
@ -10,6 +11,7 @@ import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
/** /**
* @description * @description
@ -51,6 +53,10 @@ public class MessageRouterDTO implements Serializable {
* WECHAT_MINI_PROGRAM: 微信小程序页面 * WECHAT_MINI_PROGRAM: 微信小程序页面
*/ */
private TerminalTypeEnum terminalType; private TerminalTypeEnum terminalType;
/**
* 按钮样式配置
*/
private List<ButtonStyleEnum> style;
@Override @Override
public String toString() { public String toString() {

View File

@ -0,0 +1,46 @@
package cn.axzo.msg.center.service.dto;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.io.Serializable;
/**
* @author cold_blade
* @date 2023/10/12
* @version 1.0
*/
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MessageRouterTerminalDTO implements Serializable {
private static final long serialVersionUID = 4084885624985898305L;
/**
* 页面地址 OR API接口地址
*/
private String url;
/**
* 页面地址所属应用端(如果是API接口地址,请忽略改字段值)
* WEB: web端页面
* MINI_PROGRAM: 安心筑小程序端页面
* IOS: 原生IOS端页面
* ANDROID: 原生Android端页面
* WEB_VIEW: H5页面
* WECHAT_MINI_PROGRAM: 微信小程序页面
*/
private TerminalTypeEnum terminalType;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,22 @@
package cn.axzo.msg.center.service.enums;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 按钮style枚举
*
* @author cold_blade
* @date 2023/10/11
* @version 1.0
*/
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum ButtonStyleEnum {
HIGH_LIGHT("按钮高亮展示"), OVER_CARD("按钮显示在卡片"),
;
private final String desc;
}

View File

@ -0,0 +1,22 @@
package cn.axzo.msg.center.service.enums;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 推送终端枚举
*
* @author cold_blade
* @date 2023/10/11
* @version 1.0
*/
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum PushTerminalEnum {
B_ENTERPRISE_APP("B-安心筑企业版"), C_WORKER_APP("C-安心筑工人版"),
;
private final String desc;
}

View File

@ -20,7 +20,12 @@ public enum TerminalTypeEnum {
IOS(3, "ios"), IOS(3, "ios"),
ANDROID(4, "android"), ANDROID(4, "android"),
WEB_VIEW(5, "webview"), WEB_VIEW(5, "webview"),
WECHAT_MINI_PROGRAM(6, "wechat mini-program"); WECHAT_MINI_PROGRAM(6, "wechat mini-program"),
/**
* 所有端
*/
ALL(-1, "all"),
;
private final Integer code; private final Integer code;
private final String desc; private final String desc;

View File

@ -1,8 +1,10 @@
package cn.axzo.msg.center.service.group.client; package cn.axzo.msg.center.service.group.client;
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
import cn.axzo.msg.center.service.group.client.fallback.MessageGroupClientFallback; import cn.axzo.msg.center.service.group.client.fallback.MessageGroupClientFallback;
import cn.axzo.msg.center.service.group.request.MessageGroupNodeAddRequest; import cn.axzo.msg.center.service.group.request.MessageGroupNodeAddRequest;
import cn.axzo.msg.center.service.group.request.MessageGroupNodeUpdateRequest; import cn.axzo.msg.center.service.group.request.MessageGroupNodeUpdateRequest;
import cn.axzo.msg.center.service.group.response.MessageGroupTreeNodeResponse;
import cn.azxo.framework.common.model.CommonResponse; import cn.azxo.framework.common.model.CommonResponse;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -12,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.List;
/** /**
* 消息分类管理 * 消息分类管理
@ -50,4 +53,12 @@ public interface MessageGroupClient {
@PostMapping(value = "/message/group/node/delete", produces = {MediaType.APPLICATION_JSON_VALUE}) @PostMapping(value = "/message/group/node/delete", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<Void> deleteNode(@RequestParam("nodeCode") String nodeCode, CommonResponse<Void> deleteNode(@RequestParam("nodeCode") String nodeCode,
@RequestParam("operatorId") Long operatorId); @RequestParam("operatorId") Long operatorId);
/**
* 查询通知/待办的分类信息
*
* @param category 消息分类
*/
@PostMapping(value = "/message/group/node/list", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<List<MessageGroupTreeNodeResponse>> list(@RequestParam("category") MessageCategoryEnum category);
} }

View File

@ -0,0 +1,54 @@
package cn.axzo.msg.center.service.group.client;
import cn.axzo.msg.center.service.group.client.fallback.MessageGroupClientFallback;
import cn.axzo.msg.center.service.group.request.MessageTemplateGroupRelationMoveRequest;
import cn.axzo.msg.center.service.group.request.MessageTemplateGroupRelationRemoveRequest;
import cn.axzo.msg.center.service.group.response.MessageTemplateGroupRelationResponse;
import cn.azxo.framework.common.model.CommonResponse;
import cn.azxo.framework.common.model.Page;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* @author cold_blade
* @date 2023/10/12
* @version 1.0
*/
@Component
@FeignClient(value = "msg-center", url = "${server.serviceUrl:http://msg-center:8080}",
fallback = MessageGroupClientFallback.class)
public interface MessageTemplateGroupRelationClient {
/**
* 分页查询分类下关联的模板列表
*
* @param nodeCode 分类结点的编码
* @return 模板列表
*/
@PostMapping(value = "/message/template/group-relation/page", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<Page<MessageTemplateGroupRelationResponse>> page(@RequestParam("nodeCode") String nodeCode);
/**
* 变更模板与分类的关联关系
*
* @param request 变更分类的相关参数
*/
@PostMapping(value = "/message/template/group-relation/move", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<Void> move(@RequestBody MessageTemplateGroupRelationMoveRequest request);
/**
* 变更模板与分类的关联关系
*
* @param request 变更分类的相关参数
* @return 关联关系解除失败的模板编码
*/
@PostMapping(value = "/message/template/group-relation/remove", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<List<String>> remove(@RequestBody MessageTemplateGroupRelationRemoveRequest request);
}

View File

@ -1,12 +1,16 @@
package cn.axzo.msg.center.service.group.client.fallback; package cn.axzo.msg.center.service.group.client.fallback;
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
import cn.axzo.msg.center.service.group.client.MessageGroupClient; import cn.axzo.msg.center.service.group.client.MessageGroupClient;
import cn.axzo.msg.center.service.group.request.MessageGroupNodeAddRequest; import cn.axzo.msg.center.service.group.request.MessageGroupNodeAddRequest;
import cn.axzo.msg.center.service.group.request.MessageGroupNodeUpdateRequest; import cn.axzo.msg.center.service.group.request.MessageGroupNodeUpdateRequest;
import cn.axzo.msg.center.service.group.response.MessageGroupTreeNodeResponse;
import cn.azxo.framework.common.model.CommonResponse; import cn.azxo.framework.common.model.CommonResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List;
/** /**
* @description * @description
* *
@ -34,4 +38,10 @@ public class MessageGroupClientFallback implements MessageGroupClient {
log.error("fall back while deleting message group node. nodeCode:[{}], operatorId:[{}]", nodeCode, operatorId); log.error("fall back while deleting message group node. nodeCode:[{}], operatorId:[{}]", nodeCode, operatorId);
return CommonResponse.error("fall back while deleting message group node"); return CommonResponse.error("fall back while deleting message group node");
} }
@Override
public CommonResponse<List<MessageGroupTreeNodeResponse>> list(MessageCategoryEnum category) {
log.error("fall back while listing message group node. category:[{}]", category);
return CommonResponse.error("fall back while listing message group node");
}
} }

View File

@ -0,0 +1,40 @@
package cn.axzo.msg.center.service.group.client.fallback;
import cn.axzo.msg.center.service.group.client.MessageTemplateGroupRelationClient;
import cn.axzo.msg.center.service.group.request.MessageTemplateGroupRelationMoveRequest;
import cn.axzo.msg.center.service.group.request.MessageTemplateGroupRelationRemoveRequest;
import cn.axzo.msg.center.service.group.response.MessageTemplateGroupRelationResponse;
import cn.azxo.framework.common.model.CommonResponse;
import cn.azxo.framework.common.model.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author cold_blade
* @date 2023/10/12
* @version 1.0
*/
@Slf4j
@Component
public class MessageTemplateGroupRelationClientFallback implements MessageTemplateGroupRelationClient {
@Override
public CommonResponse<Page<MessageTemplateGroupRelationResponse>> page(String nodeCode) {
log.error("fall back while page querying message template group relation. nodeCode:{}", nodeCode);
return CommonResponse.error("fall back while page querying message template group relation");
}
@Override
public CommonResponse<Void> move(MessageTemplateGroupRelationMoveRequest request) {
log.error("fall back while moving message template group relation. request:{}", request);
return CommonResponse.error("fall back while moving message template group relation");
}
@Override
public CommonResponse<List<String>> remove(MessageTemplateGroupRelationRemoveRequest request) {
log.error("fall back while removing message template group relation. request:{}", request);
return CommonResponse.error("fall back while removing message template group relation");
}
}

View File

@ -0,0 +1,43 @@
package cn.axzo.msg.center.service.group.request;
import com.alibaba.fastjson.JSON;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
import java.util.List;
/**
* @author cold_blade
* @date 2023/10/12
* @version 1.0
*/
@Setter
@Getter
public class MessageTemplateGroupRelationMoveRequest implements Serializable {
private static final long serialVersionUID = 8336083457743619246L;
/**
* 模板当前所处的分类结点编码
*/
@NotBlank(message = "curNodeCode is required")
private String curNodeCode;
/**
* 模板将要移动到的目标分类结点编码
*/
@NotBlank(message = "targetNodeCode is required")
private String targetNodeCode;
/**
* 选中的模板编码列表
*/
@NotEmpty(message = "templateCodes is required")
private List<String> templateCodes;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,38 @@
package cn.axzo.msg.center.service.group.request;
import com.alibaba.fastjson.JSON;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
import java.util.List;
/**
* @author cold_blade
* @date 2023/10/12
* @version 1.0
*/
@Setter
@Getter
public class MessageTemplateGroupRelationRemoveRequest implements Serializable {
private static final long serialVersionUID = 8336083457743619246L;
/**
* 模板当前所处的分类结点编码
*/
@NotBlank(message = "curNodeCode is required")
private String curNodeCode;
/**
* 选中的模板编码列表
*/
@NotEmpty(message = "templateCodes is required")
private List<String> templateCodes;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,47 @@
package cn.axzo.msg.center.service.group.response;
import cn.axzo.msg.center.service.enums.MessageGroupNodeCategoryEnum;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.List;
/**
* @author cold_blade
* @date 2023/10/12
* @version 1.0
*/
@Setter
@Getter
public class MessageGroupTreeNodeResponse implements Serializable {
private static final long serialVersionUID = -6741888813327778598L;
/**
* 结点类型
* GENERAL_MESSAGE_CENTER: 消息中心
* GENERAL_MESSAGE_MODULE: 消息模块
* GENERAL_MESSAGE_CATEGORY: 消息分类
* PENDING_MESSAGE_CENTER: 待办中心
* PENDING_MESSAGE_MODULE: 待办模块
* PENDING_MESSAGE_CATEGORY: 待办分类
*/
private MessageGroupNodeCategoryEnum category;
/**
* 结点名称
*/
private String nodeName;
/**
* 结点编码
*/
private String nodeCode;
/**
* 父节点编码
*/
private String parentNodeCode;
/**
* 子节点列表
*/
private List<MessageGroupTreeNodeResponse> children;
}

View File

@ -0,0 +1,35 @@
package cn.axzo.msg.center.service.group.response;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
* @author cold_blade
* @date 2023/10/12
* @version 1.0
*/
@Setter
@Getter
public class MessageTemplateGroupRelationResponse implements Serializable {
private static final long serialVersionUID = -5321330362977310550L;
/**
* 模板名称
*/
private String templateName;
/**
* 模板编码
*/
private String templateCode;
/**
* 消息标题
*/
private String title;
/**
* 模板创建时间戳
*/
private Long createTimestamp;
}

View File

@ -2,13 +2,15 @@ package cn.axzo.msg.center.service.template.client;
import cn.axzo.msg.center.service.template.client.fallback.MessageTemplateClientFallback; import cn.axzo.msg.center.service.template.client.fallback.MessageTemplateClientFallback;
import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest; import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest;
import cn.axzo.msg.center.service.template.request.MessageTemplateMoveToRequest; import cn.axzo.msg.center.service.template.request.MessageTemplateUpdateRequest;
import cn.axzo.msg.center.service.template.response.MessageTemplateDetailResponse;
import cn.azxo.framework.common.model.CommonResponse; import cn.azxo.framework.common.model.CommonResponse;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import javax.validation.Valid; import javax.validation.Valid;
@ -29,15 +31,26 @@ public interface MessageTemplateClient {
* 添加消息模板 * 添加消息模板
* *
* @param request 模板数据模型 * @param request 模板数据模型
* @return 模板编码
*/ */
@PostMapping(value = "/message/template/add", produces = {MediaType.APPLICATION_JSON_VALUE}) @PostMapping(value = "/message/template/add", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<String> addTemplate(@RequestBody @Valid MessageTemplateCreateRequest request); CommonResponse<String> save(@RequestBody @Valid MessageTemplateCreateRequest request);
/** /**
* 批量消息模板分类迁移 * 添加消息模板
* *
* @param request 待迁移的关联关系id以及目标分类 * @param request 模板数据模型
* @return 模板编码
*/ */
@PostMapping(value = "/message/template/group/batch-move", produces = {MediaType.APPLICATION_JSON_VALUE}) @PostMapping(value = "/message/template/update", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<String> batchMove(@RequestBody @Valid MessageTemplateMoveToRequest request); CommonResponse<Void> update(@RequestBody @Valid MessageTemplateUpdateRequest request);
/**
* 消息模板详情
*
* @param templateCode 消息模板编码
* @return 消息模板详情
*/
@PostMapping(value = "/message/template/detail", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<MessageTemplateDetailResponse> detail(@RequestParam("templateCode") String templateCode);
} }

View File

@ -2,7 +2,8 @@ package cn.axzo.msg.center.service.template.client.fallback;
import cn.axzo.msg.center.service.template.client.MessageTemplateClient; import cn.axzo.msg.center.service.template.client.MessageTemplateClient;
import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest; import cn.axzo.msg.center.service.template.request.MessageTemplateCreateRequest;
import cn.axzo.msg.center.service.template.request.MessageTemplateMoveToRequest; import cn.axzo.msg.center.service.template.request.MessageTemplateUpdateRequest;
import cn.axzo.msg.center.service.template.response.MessageTemplateDetailResponse;
import cn.azxo.framework.common.model.CommonResponse; import cn.azxo.framework.common.model.CommonResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -18,14 +19,20 @@ import org.springframework.stereotype.Component;
@Component @Component
public class MessageTemplateClientFallback implements MessageTemplateClient { public class MessageTemplateClientFallback implements MessageTemplateClient {
@Override @Override
public CommonResponse<String> addTemplate(MessageTemplateCreateRequest request) { public CommonResponse<String> save(MessageTemplateCreateRequest request) {
log.error("fall back while adding template. request:{}", request); log.error("fall back while adding template. request:{}", request);
return CommonResponse.error("fall back while adding template"); return CommonResponse.error("fall back while adding template");
} }
@Override @Override
public CommonResponse<String> batchMove(MessageTemplateMoveToRequest request) { public CommonResponse<Void> update(MessageTemplateUpdateRequest request) {
log.error("fall back while batch moving to target group. request:{}", request); log.error("fall back while updating template. request:{}", request);
return CommonResponse.error("fall back while batch moving to target group"); return CommonResponse.error("fall back while updating template");
}
@Override
public CommonResponse<MessageTemplateDetailResponse> detail(String templateCode) {
log.error("fall back while query template detail. templateCode:{}", templateCode);
return CommonResponse.error("fall back while query template detail");
} }
} }

View File

@ -1,7 +1,8 @@
package cn.axzo.msg.center.service.template.request; package cn.axzo.msg.center.service.template.request;
import cn.axzo.msg.center.service.dto.MessageRouterDTO; import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO;
import cn.axzo.msg.center.service.enums.MessageCategoryEnum; import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -43,10 +44,14 @@ public class MessageTemplateCreateRequest implements Serializable {
@NotNull(message = "category is required") @NotNull(message = "category is required")
private MessageCategoryEnum category; private MessageCategoryEnum category;
/** /**
* 消息分类结点的结点编码列表 * 消息分类结点编码路径列表 eg: aa:bb:cc
*/ */
@NotEmpty(message = "msgGroupNodeCodes is required") @NotEmpty(message = "groupPaths is required")
private List<String> msgGroupNodeCodes; private List<String> groupPaths;
/**
* 推送终端配置
*/
private List<PushTerminalEnum> pushTerminals;
/** /**
* 消息标题 * 消息标题
*/ */
@ -68,7 +73,7 @@ public class MessageTemplateCreateRequest implements Serializable {
/** /**
* 路由策略列表 * 路由策略列表
*/ */
private List<MessageRouterDTO> routers; private List<MessageRouterButtonDTO> routers;
@Override @Override
public String toString() { public String toString() {

View File

@ -1,40 +0,0 @@
package cn.axzo.msg.center.service.template.request;
import com.alibaba.fastjson.JSON;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.List;
/**
* @description
*
* @author cold_blade
* @date 2023/9/26
* @version 1.0
*/
@Setter
@Getter
public class MessageTemplateMoveToRequest implements Serializable {
private static final long serialVersionUID = 6484726175219602690L;
/**
* 操作者的自然人id
*/
private Long operatorId;
/**
* 模板与分类的关联关系的id列表
*/
private List<Long> templateGroupRelationIds;
/**
* 迁移的目标分类结点编码
*/
private String targetGroupNodeCode;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,74 @@
package cn.axzo.msg.center.service.template.request;
import cn.axzo.msg.center.service.dto.MessageRouterButtonDTO;
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
import com.alibaba.fastjson.JSON;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* @description
*
* @author cold_blade
* @date 2023/10/11
* @version 1.0
*/
@Setter
@Getter
public class MessageTemplateUpdateRequest implements Serializable {
private static final long serialVersionUID = -2894419272913799317L;
/**
* 操作者的自然人id
*/
@NotNull(message = "operatorId is required")
private Long operatorId;
/**
* 模板名称
*/
@NotBlank(message = "templateName is required")
private String templateName;
/**
* 消息分类的树结点编码路径列表 eg: aa:bb:cc
*/
@NotEmpty(message = "groupPaths is required")
private List<String> groupPaths;
/**
* 推送终端配置
*/
private List<PushTerminalEnum> pushTerminals;
/**
* 消息标题
*/
@NotBlank(message = "msgTitle is required")
private String msgTitle;
/**
* 消息卡片信息
*/
private String msgCardInfo;
/**
* 消息内容
*/
@NotBlank(message = "msgContent is required")
private String msgContent;
/**
* 消息图标
*/
private String msgIcon;
/**
* 路由策略列表
*/
private List<MessageRouterButtonDTO> routers;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,73 @@
package cn.axzo.msg.center.service.template.response;
import cn.axzo.msg.center.service.dto.MessageRouterDTO;
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.io.Serializable;
import java.util.List;
/**
* @author cold_blade
* @date 2023/10/11
* @version 1.0
*/
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MessageTemplateDetailResponse implements Serializable {
private static final long serialVersionUID = 6772912658753264863L;
/**
* 模板名称
*/
private String templateName;
/**
* 消息类型
* GENERAL_MESSAGE: 普通消息
* PENDING_MESSAGE: 待办消息
*/
private MessageCategoryEnum category;
/**
* 消息分类的树结点编码路径列表 eg: aa:bb:cc
*/
private List<String> groupPaths;
/**
* 推送终端配置
*/
private List<PushTerminalEnum> pushTerminals;
/**
* 消息标题
*/
private String msgTitle;
/**
* 消息卡片信息
*/
private String msgCardInfo;
/**
* 消息内容
*/
private String msgContent;
/**
* 消息图标
*/
private String msgIcon;
/**
* 路由策略列表
*/
private List<MessageRouterDTO> routers;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -51,6 +51,10 @@ public class MessageBaseTemplate extends BaseEntity<MessageBaseTemplate> impleme
* 模板icon * 模板icon
*/ */
private String icon; private String icon;
/**
* 推送终端配置 JSON字串
*/
private String pushTerminal;
/** /**
* 创建者自然人id * 创建者自然人id
*/ */

View File

@ -44,6 +44,10 @@ public class MessageTemplateRouter extends BaseEntity<MessageTemplateRouter> imp
* 路由地址 * 路由地址
*/ */
private String url; private String url;
/**
* 按钮style配置
*/
private String style;
@Override @Override
public String toString() { public String toString() {

View File

@ -98,6 +98,10 @@ public class PendingMessageRecord extends BaseEntity<PendingMessageRecord> imple
* 业务描述eg:流程结点描述 * 业务描述eg:流程结点描述
*/ */
private String bizDesc; private String bizDesc;
/**
* 业务扩展参数
*/
private String bizExtParam;
/** /**
* 路由参数留存 * 路由参数留存
*/ */