Merge branch 'feature/REQ-3045' into dev

# Conflicts:
#	inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/TodoSimpleQueryService.java
This commit is contained in:
yanglin 2024-10-18 09:31:54 +08:00
commit bf31ea6f37
50 changed files with 644 additions and 1575 deletions

View File

@ -13,6 +13,7 @@ import cn.axzo.msg.center.inside.notices.service.IYouMengMessageService;
import cn.axzo.msg.center.inside.notices.service.impl.v3.msg.TemplateMessage;
import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO;
import cn.axzo.msg.center.message.service.MessageTemplateNewService;
import cn.axzo.msg.center.message.service.impl.v3.AppLink;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
@ -159,24 +160,24 @@ public class PushYouMengMessageHandler implements EventHandler, InitializingBean
* @param jsonObject
* @param actionPaths
*/
public void resolveRouter(JSONObject jsonObject, List<MessageHistoryUpdatedPayload.ActionPath> actionPaths) {
public void resolveRouter(JSONObject jsonObject, List<AppLink> actionPaths) {
Map<TerminalTypeEnum, MessageHistoryUpdatedPayload.ActionPath> actionPathMap = actionPaths.stream()
.collect(Collectors.toMap(MessageHistoryUpdatedPayload.ActionPath::getPlatform, Function.identity()));
Optional<MessageHistoryUpdatedPayload.ActionPath> routerType = ROUTER_TYPE_SORTED.stream()
Map<TerminalTypeEnum, AppLink> actionPathMap = actionPaths.stream()
.collect(Collectors.toMap(AppLink::getPlatform, Function.identity()));
Optional<AppLink> routerType = ROUTER_TYPE_SORTED.stream()
.map(actionPathMap::get)
.filter(Objects::nonNull)
.findFirst();
routerType.ifPresent(actionPath -> jsonObject.fluentPut("rt", NativeTypeEnum.getByCode(actionPath.getPlatform().getCode()).getMessage()));
Optional<MessageHistoryUpdatedPayload.ActionPath> ios = IOS_URL_SORTED.stream()
Optional<AppLink> ios = IOS_URL_SORTED.stream()
.map(actionPathMap::get)
.filter(Objects::nonNull)
.findFirst();
// IOS的跳转URL
ios.ifPresent(actionPath -> jsonObject.fluentPut("ir", actionPath.getUrl()));
Optional<MessageHistoryUpdatedPayload.ActionPath> android = ANDROID_URL_SORTED.stream()
Optional<AppLink> android = ANDROID_URL_SORTED.stream()
.map(actionPathMap::get)
.filter(Objects::nonNull)
.findFirst();

View File

@ -1,7 +1,7 @@
package cn.axzo.msg.center.event.payload;
import cn.axzo.im.center.common.enums.AppTypeEnum;
import cn.axzo.msg.center.domain.enums.MsgRouteTypeEnum;
import cn.axzo.msg.center.message.service.impl.v3.AppLink;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
@ -144,7 +144,7 @@ public class MessageHistoryUpdatedPayload implements Serializable {
@NoArgsConstructor
@AllArgsConstructor
public static class CardDetailButton {
private List<ActionPath> actionPaths;
private List<AppLink> actionPaths;
}

View File

@ -113,7 +113,7 @@ public class PendingMessageBizConfig {
@Getter
private Set<String> populateWorkspaceIdTemplateCodes = new HashSet<>();
private boolean appendRouterParamsAsQueryParams = false;
private boolean appendRouterParamsAsQueryParams = true;
public boolean isConcatRouterParams(String templateCode) {
if (!appendRouterParamsAsQueryParams)

View File

@ -7,13 +7,13 @@ import cn.axzo.msg.center.api.response.PendingMessageBriefRes;
import cn.axzo.msg.center.api.response.PendingMessageStatisticRes;
import cn.axzo.msg.center.api.response.PendingMessageTemporarilyStatisticRes;
import cn.axzo.msg.center.api.response.PendingMessageTemporarilyTypeRes;
import cn.axzo.msg.center.inside.notices.config.PendingMessageBizConfig;
import cn.axzo.msg.center.inside.notices.service.PendingMessageService;
import cn.azxo.framework.common.model.CommonResponse;
import cn.azxo.framework.common.model.Page;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
/**
@ -31,13 +31,10 @@ public class PendingMessageStatisticController implements PendingMessageServiceA
@Resource
private PendingMessageService pendingMessageService;
@Resource
private PendingMessageBizConfig pendingMessageBizConfig;
@Override
public CommonResponse<List<PendingMessageTemporarilyStatisticRes>> temporarilyStatistic(
PendingMessageTemporarilyStatisticReq request) {
return CommonResponse.success(pendingMessageService.temporarilyStatistic(request));
return CommonResponse.success(Collections.emptyList());
}
@Override

View File

@ -1,10 +1,8 @@
package cn.axzo.msg.center.inside.notices.service;
import cn.axzo.msg.center.api.request.PendingMessagePageReq;
import cn.axzo.msg.center.api.request.PendingMessageTemporarilyStatisticReq;
import cn.axzo.msg.center.api.response.PendingMessageBriefRes;
import cn.axzo.msg.center.api.response.PendingMessageStatisticRes;
import cn.axzo.msg.center.api.response.PendingMessageTemporarilyStatisticRes;
import cn.axzo.msg.center.api.response.PendingMessageTemporarilyTypeRes;
import cn.azxo.framework.common.model.Page;
@ -19,14 +17,6 @@ import java.util.List;
*/
public interface PendingMessageService {
/**
* 统计代办类消息
*
* @param request 统计请求的入参
* @return 符合条件的代办数量
*/
List<PendingMessageTemporarilyStatisticRes> temporarilyStatistic(PendingMessageTemporarilyStatisticReq request);
/**
* 根据消息的临时的业务分类分页查询个人相关的待办消息
*

View File

@ -9,7 +9,6 @@ import cn.axzo.msg.center.api.request.PendingMessageTemporarilyStatisticReq;
import cn.axzo.msg.center.api.response.MessageRouterInfoRes;
import cn.axzo.msg.center.api.response.PendingMessageBriefRes;
import cn.axzo.msg.center.api.response.PendingMessageStatisticRes;
import cn.axzo.msg.center.api.response.PendingMessageTemporarilyStatisticRes;
import cn.axzo.msg.center.api.response.PendingMessageTemporarilyTypeRes;
import cn.axzo.msg.center.common.utils.BeanConvertUtils;
import cn.axzo.msg.center.common.utils.PlaceholderResolver;
@ -29,7 +28,6 @@ import cn.axzo.msg.center.inside.notices.service.MessageRelationService;
import cn.axzo.msg.center.inside.notices.service.MessageRouterService;
import cn.axzo.msg.center.inside.notices.service.PendingMessageService;
import cn.axzo.msg.center.inside.notices.utils.MessageRecordHelper;
import cn.axzo.msg.center.message.service.PendingMessageNewService;
import cn.axzo.msg.center.notices.common.enums.ReturnCodeEnum;
import cn.axzo.msg.center.notices.common.exception.BizException;
import cn.azxo.framework.common.model.Page;
@ -100,28 +98,6 @@ public class PendingMessageServiceImpl implements PendingMessageService {
private final MessageModuleService messageModuleService;
private final MessageRelationService messageRelationService;
private final PendingMessageBizConfig pendingMessageBizConfig;
private final PendingMessageNewService pendingMessageNewService;
@Override
public List<PendingMessageTemporarilyStatisticRes> temporarilyStatistic(PendingMessageTemporarilyStatisticReq request) {
// 参数检测
checkParam(request);
final List<MsgTempBizCategoryConfig> categoryConfigs = pendingMessageBizConfig.tempCategoriesConfig();
if (CollectionUtils.isEmpty(categoryConfigs)) {
log.warn("the nacos config is lost......");
return Collections.emptyList();
}
try {
return categoryConfigs.stream()
// 自然排序,前端仅做渲染,展示顺序的工作由后端配置
.sorted()
.map(e -> statistic(request, e))
.collect(Collectors.toList());
} catch (Exception e) {
log.error("broke out some exception while statistic pending message.", e);
throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "system exception.");
}
}
@Override
public PendingMessageStatisticRes temporarilyPage(PendingMessagePageReq request) {
@ -288,22 +264,6 @@ public class PendingMessageServiceImpl implements PendingMessageService {
return module;
}
private PendingMessageTemporarilyStatisticRes statistic(PendingMessageTemporarilyStatisticReq request,
MsgTempBizCategoryConfig categoryConfig) {
// 统计数量
Integer count = pendingMessageNewService.countUncompleted(request.getPersonId(), categoryConfig.getConfigRelationIds());
PendingMessageTemporarilyStatisticRes res = new PendingMessageTemporarilyStatisticRes();
res.setUnCompletedCount(count);
res.setCategoryCode(categoryConfig.getCategory().name());
res.setCategoryDesc(categoryConfig.getCategory().getDesc());
res.setIconUrl(categoryConfig.getIconUrl());
if (StringUtils.isNotBlank(categoryConfig.getJumpUrl())) {
// 分类指定了具体的跳转地址,则优先使用其指定的地址这里指定为原生APP
res.setRouter(new MessageRouterInfoRes(NativeTypeEnum.H5.getMessage(), categoryConfig.getJumpUrl(), ""));
}
return res;
}
private void checkParam(PendingMessageTemporarilyStatisticReq request) {
if (Objects.isNull(request)
|| Objects.isNull(request.getIdentifyId())) {

View File

@ -10,6 +10,7 @@ import cn.axzo.msg.center.api.response.v3.TemplateSendResultV3;
import cn.axzo.msg.center.common.utils.BizAssertions;
import cn.axzo.msg.center.dal.MessageRecordV3Dao;
import cn.axzo.msg.center.domain.entity.MessageRecordV3;
import cn.axzo.msg.center.domain.entity.MessageTemplateV3;
import cn.axzo.msg.center.inside.notices.service.impl.v3.EventMappingProcessor;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
@ -31,7 +32,7 @@ public class MessageMappingProcessor implements EventMappingProcessor {
private final MessageRecordV3Dao messageRecordV3Dao;
private final TerminalAppMapping terminalAppMapping;
private final MessageTemplateParser templateParser;
private final MessageTemplateParserV3 templateParser;
private final MessageApi messageApi;
/**
@ -48,9 +49,9 @@ public class MessageMappingProcessor implements EventMappingProcessor {
@Override
public void maybeAsyncSend() {
List<AppTypeEnum> appTypes = terminalAppMapping
.toImTypes(template.getTemplate().getPushTerminals());
.toImTypes(getTemplate().determinePushTerminals());
BizAssertions.assertNotEmpty(appTypes, "发送IM消息, 消息模版没有配置IM发送终端, templateCode={}, templateName={}",
template.getTemplate().getCode(), template.getTemplate().getName());
getTemplate().getCode(), getTemplate().getName());
SendTemplateMessageParam request = template.buildImRequest(templateParser, appTypes);
ApiResult<MessageTaskResp> apiResult = messageApi.sendTemplateMessageAsync(request);
log.info("sending im message result, req={}, resp={}",
@ -76,4 +77,8 @@ public class MessageMappingProcessor implements EventMappingProcessor {
return templateResult;
}
private MessageTemplateV3 getTemplate() {
return template.getTemplateModel().getTemplate();
}
}

View File

@ -0,0 +1,113 @@
package cn.axzo.msg.center.inside.notices.service.impl.v3.msg;
import cn.axzo.msg.center.domain.entity.MessageRecordV3;
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
import cn.axzo.msg.center.message.domain.vo.GeneralMessagePushVO;
import cn.axzo.msg.center.message.domain.vo.GeneralMessagePushVO.CardButton;
import cn.axzo.msg.center.message.domain.vo.GeneralMessagePushVO.CardExtensionItem;
import cn.axzo.msg.center.message.domain.vo.GeneralMessagePushVO.Subtitle;
import cn.axzo.msg.center.message.service.impl.v3.AppLink;
import cn.axzo.msg.center.message.service.impl.v3.AppLinkUrlConfigVisitor;
import cn.axzo.msg.center.message.service.impl.v3.ModelV3Parser;
import cn.axzo.msg.center.service.domain.UrlConfig;
import cn.axzo.msg.center.service.domain.UrlConfigWalker;
import cn.axzo.msg.center.service.enums.ButtonStyleEnum;
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.pending.response.v3.ParsedModel3Visitor;
import cn.axzo.msg.center.service.pending.response.v3.ParsedModel3Walker;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedButtonV3;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedGroupV3;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedKV;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedModelV3;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author yanglin
*/
@Component
@RequiredArgsConstructor
public class MessageTemplateParserV3 {
private final ModelV3Parser modelV3Parser;
GeneralMessagePushVO parse(MessageRecordV3 message, TemplateModelV3 templateModel) {
String orgIcon = templateModel.getTemplate().getIcon();
Subtitle subtitle = new Subtitle();
subtitle.setIconUrl(orgIcon);
subtitle.setTitle(message.getSubtitle());
GeneralMessagePushVO im = new GeneralMessagePushVO();
im.setIdentityCode(message.getIdentityCode());
im.setTemplateCode(message.getTemplateCode());
im.setCardBannerUrl(orgIcon);
im.setCardTitle(message.getTitle());
im.setCardContent(message.getContent());
im.setSubtitles(Collections.singletonList(subtitle));
im.setBizCode(message.getBizCode());
im.setSendTimestamp(message.getCreateAt().getTime());
ParsedModelV3 parsedModel = modelV3Parser.parseModel(
templateModel, message, message.getBizExtParams(), message.getRouterParams());
ParsedModel3Walker.walkDown(parsedModel, new ParsedModel3Visitor() {
@Override
public void visitTemplateCardUrlConfig(UrlConfig urlConfig) {
CardButton cardDetailButton = new CardButton();
cardDetailButton.setTitle("详情");
cardDetailButton.setAction(RouterCategoryEnum.JUMP.name());
cardDetailButton.setIsHighlight(false);
cardDetailButton.setActionPaths(getAppLinks(urlConfig));
im.setCardDetailButton(cardDetailButton);
}
@Override
public void visitGroupKeyValue(ParsedGroupV3 group, ParsedKV kv) {
if (!kv.isDisplayOnCard())
return;
if (im.getCardExtension() == null)
im.setCardExtension(new ArrayList<>());
im.getCardExtension().add(new CardExtensionItem(kv.getKey(), kv.getValue()));
}
@Override
public void visitButton(ParsedButtonV3 button) {
List<ButtonStyleEnum> styles = button.parseStyle();
if (!styles.contains(ButtonStyleEnum.OVER_CARD))
return;
if (im.getCardButtons() == null)
im.setCardButtons(new ArrayList<>());
CardButton imButton = new CardButton();
im.getCardButtons().add(imButton);
imButton.setTitle(button.getName());
imButton.setAction(button.getCategory().name());
imButton.setIsHighlight(styles.contains(ButtonStyleEnum.HIGH_LIGHT));
imButton.setIsOverCard(styles.contains(ButtonStyleEnum.OVER_CARD));
if (RouterCategoryEnum.ACTION.equals(button.getCategory())) {
AppLink appLink = new AppLink(TerminalTypeEnum.WEB_VIEW.name(), button.getApiUrl());
imButton.setActionPaths(Collections.singletonList(appLink));
} else {
imButton.setActionPaths(getAppLinks(button.getUrlConfig()));
}
}
});
return im;
}
private List<AppLink> getAppLinks(UrlConfig urlConfig) {
if (urlConfig == null) return Collections.emptyList();
AppLinkUrlConfigVisitor visitor = new AppLinkUrlConfigVisitor();
UrlConfigWalker.walkDown(urlConfig, visitor);
return visitor.getLinks();
}
}

View File

@ -10,7 +10,7 @@ import cn.axzo.msg.center.api.request.v4.MessageSendRequestV4;
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
import cn.axzo.msg.center.common.utils.PlaceholderResolver;
import cn.axzo.msg.center.domain.entity.MessageRecordV3;
import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO;
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
import cn.axzo.msg.center.message.domain.vo.GeneralMessagePushVO;
import cn.axzo.msg.center.service.dto.PersonV3DTO;
import cn.axzo.msg.center.service.enums.Channel;
@ -45,14 +45,14 @@ public class TemplateMessage {
@Getter
private final Channel channel;
@Getter
private final MessageTemplateDTO template;
private final TemplateModelV3 templateModel;
private List<MessageRecordV3> records;
private String title;
private String content;
String getTemplateCode() {
return template.getCode();
return templateModel.getTemplateCode();
}
Collection<Long> getMessageIds() {
@ -86,7 +86,7 @@ public class TemplateMessage {
message.setReceiverOuId(sendBasicInfo.determineReceiversOuId());
message.setReceiverWorkspaceId(sendBasicInfo.determineReceiversWorkspaceId());
message.setBizEventMappingCode(req.getEventMappingCode());
message.setTemplateCode(template.getCode());
message.setTemplateCode(getTemplateCode());
message.setTitle(parseTitle());
message.setContent(parseContent());
OrganizationTypeEnum orgType = sendBasicInfo.getReceiversOrgType();
@ -113,17 +113,17 @@ public class TemplateMessage {
return String.format("%s:%s", BIZ_ID_PREFIX, templateCode);
}
SendTemplateMessageParam buildImRequest(MessageTemplateParser templateParser, List<AppTypeEnum> apps) {
SendTemplateMessageParam buildImRequest(MessageTemplateParserV3 templateParser, List<AppTypeEnum> apps) {
MessageRecordV3 sample = getMessageRecords().get(0);
GeneralMessagePushVO sendVo = templateParser.parse(sample, template);
GeneralMessagePushVO sendVo = templateParser.parse(sample, templateModel);
MessageSendBasicInfoV4 sendBasicInfo = req.getSendBasicInfo();
SendTemplateMessageParam imReq = new SendTemplateMessageParam();
imReq.setBizId(String.format("%s:%s", getBizIdPrefix(template.getCode()), sendBasicInfo.determineBizCode()));
imReq.setSendPriority(template.determineImSendPriority());
imReq.setBizId(String.format("%s:%s", getBizIdPrefix(getTemplateCode()), sendBasicInfo.determineBizCode()));
imReq.setSendPriority(templateModel.getTemplate().determineImSendPriority());
imReq.setMsgHeader(parseTitle());
imReq.setMsgContent(parseContent());
imReq.setMsgTemplateId(template.getCode());
imReq.setMsgTemplateId(getTemplateCode());
imReq.setMsgTemplateContent(JSON.toJSONString(sendVo));
// 接收人
ArrayList<ReceivePerson> receivers = new ArrayList<>();
@ -145,7 +145,7 @@ public class TemplateMessage {
imReq.setReceivePersons(receivers);
// 扩展信息
JSONObject ext = new JSONObject();
ext.put("minAppVersion", template.getMinAppVersion());
ext.put("minAppVersion", templateModel.getTemplate().getMinAppVersion());
if (sample.getReceiverWorkspaceId() != null) {
ext.put("workspaceId", String.valueOf(sample.getReceiverWorkspaceId()));
}
@ -161,7 +161,7 @@ public class TemplateMessage {
String parseTitle() {
if (title == null) {
title = PlaceholderResolver.tryResolve(
template.getTitle(), req.getSendBasicInfo().getBizExtParams());
templateModel.getTemplate().getTitle(), req.getSendBasicInfo().getBizExtParams());
}
return title;
}
@ -169,7 +169,7 @@ public class TemplateMessage {
String parseContent() {
if (content == null) {
content = PlaceholderResolver.tryResolve(
template.getContent(), req.getSendBasicInfo().getBizExtParams());
templateModel.getTemplate().getContent(), req.getSendBasicInfo().getBizExtParams());
}
return content;
}
@ -193,7 +193,7 @@ public class TemplateMessage {
values.put("batchNo", batchNo);
values.put("bizEventMappingCode", req.getEventMappingCode());
values.put("bizCode", req.getSendBasicInfo().getBizCode());
values.put("templateCode", template.getCode());
values.put("templateCode", templateModel.getTemplate().getCode());
values.put("messageIds", getMessageIds());
values.put("receiverPersonIds", getReceiverPersonIds());
return JSON.toJSONString(values);

View File

@ -1,12 +1,12 @@
package cn.axzo.msg.center.inside.notices.service.impl.v3.todo;
import cn.axzo.msg.center.api.request.v3.PendingSendInfo;
import cn.axzo.msg.center.api.request.v4.MessageSendBasicInfoV4;
import cn.axzo.msg.center.api.request.v4.MessageSendRequestV4;
import cn.axzo.msg.center.api.request.v3.PendingSendInfo;
import cn.axzo.msg.center.api.response.v3.MessageSendResultV3;
import cn.axzo.msg.center.api.response.v3.TemplateSendResultV3;
import cn.axzo.msg.center.inside.notices.service.impl.v3.EventMappingProcessor;
import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO;
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
import cn.axzo.msg.center.message.service.todo.manage.TodoManager;
import cn.axzo.msg.center.message.service.todo.manage.TodoRequestContext;
@ -38,7 +38,7 @@ public class TodoMappingProcessor implements EventMappingProcessor {
private final TodoManager todoManager;
private MessageSendRequestV4 req;
private String sendRequestNo;
private MessageTemplateDTO template;
private TemplateModelV3 templateModel;
private Channel channel;
private List<PushPendingMessageDTO> sendResults;
@ -52,7 +52,7 @@ public class TodoMappingProcessor implements EventMappingProcessor {
MessageSendBasicInfoV4 sendBasicInfo = req.getSendBasicInfo();
request.setPromoter(sendBasicInfo.getSender() == null ? null : sendBasicInfo.getSender().asV1());
request.setExecutor(convertReceivers(sendBasicInfo.getReceivers()));
request.setTemplateCode(template.getCode());
request.setTemplateCode(templateModel.getTemplateCode());
request.setOuId(sendBasicInfo.getReceiversOuId());
request.setWorkspaceId(sendBasicInfo.getReceiversWorkspaceId());
request.setPromoterOuId(sendBasicInfo.getSenderOuId());
@ -85,7 +85,7 @@ public class TodoMappingProcessor implements EventMappingProcessor {
@Override
public TemplateSendResultV3 buildTemplateSendResult() {
TemplateSendResultV3 resultV3 = new TemplateSendResultV3(
template.getCode(), channel.name());
templateModel.getTemplateCode(), channel.name());
for (PushPendingMessageDTO todoResult : sendResults)
resultV3.addResult(new MessageSendResultV3(
todoResult.getExecutorPersonId(), todoResult.getId()));

View File

@ -12,8 +12,8 @@ import cn.axzo.msg.center.inside.notices.service.impl.v3.msg.MessageMappingProce
import cn.axzo.msg.center.inside.notices.service.impl.v3.msg.TemplateMessage;
import cn.axzo.msg.center.inside.notices.service.impl.v3.todo.TodoMappingProcessor;
import cn.axzo.msg.center.inside.notices.utils.FunctionalTransactionTemplate;
import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO;
import cn.axzo.msg.center.message.service.MessageTemplateNewService;
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
import cn.axzo.msg.center.message.service.impl.v3.ModelV3Service;
import cn.axzo.msg.center.service.enums.Channel;
import cn.axzo.msg.center.utils.UUIDUtil;
import lombok.RequiredArgsConstructor;
@ -33,7 +33,7 @@ import java.util.List;
@RequiredArgsConstructor
public class MessageServiceV4Impl implements MessageServiceV4 {
private final MessageTemplateNewService messageTemplateNewService;
private final ModelV3Service modelV3Service;
private final FunctionalTransactionTemplate transactionTemplate;
private final ApplicationContext beanFactory;
@ -49,21 +49,21 @@ public class MessageServiceV4Impl implements MessageServiceV4 {
for (TemplateInfo info : request.getTemplates()) {
BizAssertions.assertNotEmpty(info.getTemplateCodes(), "模版编码不能为空");
for (String templateCode : info.getTemplateCodes()) {
MessageTemplateDTO template = messageTemplateNewService
.queryEnableTemplateByCode(templateCode)
TemplateModelV3 templateModel = modelV3Service
.findEnabledByCode(templateCode)
.orElseThrow(() -> new ServiceException(String.format(
"未查询到对应的模板, templateCode=%s", templateCode)));
if (info.getChannel() == Channel.NOTIFICATION) {
// @Scope("prototype") -> we're good
MessageMappingProcessor imProcessor = beanFactory.getBean(MessageMappingProcessor.class);
imProcessor.setTemplate(new TemplateMessage(request, sendRequestNo, info.getChannel(), template));
imProcessor.setTemplate(new TemplateMessage(request, sendRequestNo, info.getChannel(), templateModel));
processors.add(imProcessor);
} else if (info.getChannel() == Channel.PENDING) {
// @Scope("prototype") -> we're good
TodoMappingProcessor todoProcessor = beanFactory.getBean(TodoMappingProcessor.class);
todoProcessor.setSendRequestNo(sendRequestNo);
todoProcessor.setReq(request);
todoProcessor.setTemplate(template);
todoProcessor.setTemplateModel(templateModel);
todoProcessor.setChannel(info.getChannel());
processors.add(todoProcessor);
}

View File

@ -1,9 +1,7 @@
package cn.axzo.msg.center.message.controller;
import cn.axzo.msg.center.api.response.MessageDetailRes;
import cn.axzo.msg.center.message.domain.param.MessageGroupNodeStatisticParam;
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
import cn.axzo.msg.center.message.service.PendingMessageNewService;
import cn.axzo.msg.center.message.service.todo.TodoRangeQueryService;
import cn.axzo.msg.center.message.service.todo.TodoSimpleQueryService;
import cn.axzo.msg.center.message.service.todo.TodoWorkerQueryService;
@ -68,7 +66,6 @@ import java.util.concurrent.TimeUnit;
@RequiredArgsConstructor
public class PendingMessageNewController implements PendingMessageClient {
private final PendingMessageNewService pendingMessageNewService;
private final TodoManager todoManager;
private final TodoRangeQueryService todoRangeQueryService;
private final TodoSimpleQueryService todoSimpleQueryService;
@ -140,11 +137,6 @@ public class PendingMessageNewController implements PendingMessageClient {
return CommonResponse.success(todoWorkerQueryService.getWorkerCalendar(request));
}
@Override
public CommonResponse<Page<MessageDetailRes>> compatiblePageQuery(PendingMessagePageRequest request) {
return CommonResponse.success(pendingMessageNewService.compatiblePageQuery(request));
}
@Override
public CommonResponse<PendingMessageResponse> query(PendingMessageQueryRequest request) {
log.info("query, request={}", JSON.toJSONString(request));
@ -157,14 +149,17 @@ public class PendingMessageNewController implements PendingMessageClient {
@Override
public CommonResponse<PendingMessageResponse> detail(
String msgIdentityCode, TerminalTypeEnum terminalType, TodoQueryType queryType) {
PendingMessageResponse response = todoSimpleQueryService.getDetail(msgIdentityCode, terminalType, queryType);
PendingMessageDetailRequestV3 request = new PendingMessageDetailRequestV3();
request.setMsgIdentityCode(msgIdentityCode);
request.setTerminalType(terminalType);
request.setQueryType(queryType);
PendingMessageResponse response = todoSimpleQueryService.getDetail(request);
return CommonResponse.success(response);
}
@Override
public CommonResponse<PendingMessageResponse> detailV3(PendingMessageDetailRequestV3 requestV3) {
PendingMessageResponse response = todoSimpleQueryService.getDetail(
requestV3.getMsgIdentityCode(), requestV3.getTerminalType(), requestV3.getQueryType());
public CommonResponse<PendingMessageResponse> detailV3(PendingMessageDetailRequestV3 request) {
PendingMessageResponse response = todoSimpleQueryService.getDetail(request);
return CommonResponse.success(response);
}
@ -184,7 +179,7 @@ public class PendingMessageNewController implements PendingMessageClient {
@Override
public CommonResponse<Page<PendingMessageIterateResponse>> iterate(PendingMessageIterateRequest request) {
return CommonResponse.success(pendingMessageNewService.iterate(request));
return CommonResponse.success(Page.zero());
}
@Override

View File

@ -2,20 +2,25 @@ package cn.axzo.msg.center.message.domain.dto;
import cn.axzo.msg.center.api.custombutton.ProposedButtons;
import cn.axzo.msg.center.domain.entity.PendingMessageRecord;
import cn.axzo.msg.center.service.domain.UrlConfig;
import cn.axzo.msg.center.service.dto.IdentityDTO;
import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO;
import cn.axzo.msg.center.service.dto.PersonDTO;
import cn.axzo.msg.center.service.enums.BizCategoryEnum;
import cn.axzo.msg.center.service.enums.BizFinalStateEnum;
import cn.axzo.msg.center.service.enums.CardUrlOpenStrategy;
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
import cn.axzo.msg.center.service.enums.OrganizationTypeEnum;
import cn.axzo.msg.center.service.enums.PendingMessageStateEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.enums.TodoType;
import cn.axzo.msg.center.service.pending.TerminalProvider;
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
import cn.axzo.msg.center.service.pending.response.v3.ModelV2PropsPopulator;
import cn.axzo.msg.center.service.pending.response.v3.ParsedModel3Walker;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedModelV3;
import cn.axzo.msg.center.service.template.response.MessageDetailStyle;
import cn.axzo.msg.center.utils.DateFormatUtil;
import cn.axzo.msg.center.utils.MessageRouterUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
@ -24,6 +29,7 @@ import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import java.io.Serializable;
import java.time.LocalDateTime;
@ -38,6 +44,7 @@ import java.util.Optional;
* @date 2023/9/23
* @version 1.0
*/
@Slf4j
@Setter
@Getter
@Builder
@ -210,6 +217,21 @@ public class PendingMessageDTO implements Serializable {
private JSONObject bizExtParamObj;
private JSONObject routerExtParamObj;
/**
* 基于分组的待办信息
*/
private ParsedModelV3 modelV3;
/**
* 卡片跳转方式. NONE: 无跳转, OPEN_TODO_DETAIL: 打开待办详情, OPEN_CUSTOM_PAGE: 打开指定页面
*/
private CardUrlOpenStrategy cardUrlOpenStrategy;
/**
* 卡片跳转配置. 在links的基础上再包一层, 避免以后卡片增加自己的配置
*/
private UrlConfig cardUrl;
@Deprecated
public static PendingMessageDTO from(PendingMessageRecord pendingMessageRecord) {
// 代办发起者信息
@ -259,13 +281,19 @@ public class PendingMessageDTO implements Serializable {
.build();
}
@Deprecated
public PendingMessageResponse toResponse(TerminalTypeEnum terminalType) {
log.warn("Invoking deprecated API, terminalType: {}", terminalType);
return null;
}
public PendingMessageResponse toResponse(TerminalProvider terminalProvider) {
boolean isCreatedToday = false;
if (createTime != null) {
Date createAt = DateFormatUtil.toDate(createTime);
isCreatedToday = DateUtil.isSameDay(createAt, new Date());
}
return PendingMessageResponse.builder()
PendingMessageResponse response = PendingMessageResponse.builder()
// 发起人单位项目信息
.promoterOuId(promoterOuId)
.promoterWorkspaceId(promoterWorkspaceId)
@ -294,7 +322,6 @@ public class PendingMessageDTO implements Serializable {
.templateCode(this.templateCode)
.title(this.title)
.content(this.content)
.cardItems(this.cardItems)
.promoterPersonId(Optional.ofNullable(this.promoter).map(PersonDTO::getId).orElse(null))
.promoterName(Optional.ofNullable(this.promoter).map(PersonDTO::getName).orElse(null))
.promoterIdentity(Optional.ofNullable(this.promoter).map(PersonDTO::getIdentity).orElse(null))
@ -310,11 +337,16 @@ public class PendingMessageDTO implements Serializable {
.createTimestamp(DateFormatUtil.toTimestamp(this.createTime))
.updateTimestamp(DateFormatUtil.toTimestamp(this.updateTime))
.deadlineTimestamp(DateFormatUtil.toTimestamp(this.deadline))
.detailRouter(MessageRouterUtil.fetchBizDetailRouter(this.msgTemplateRouter, terminalType).orElse(null))
.buttonRouters(MessageRouterUtil.fetchMessageRouterButtons(this.msgTemplateRouter, terminalType))
.bizFinalStateIcon(Optional.ofNullable(bizFinalState).map(BizFinalStateEnum::getIcon).orElse(null))
.bizFinalState(bizFinalState)
.modelV3(modelV3)
.displayOnCardKeyValues(modelV3.determineDisplayOnCardKeyValues())
.cardUrlOpenStrategy(cardUrlOpenStrategy)
.cardUrl(cardUrl)
.build();
if (modelV3 != null)
ParsedModel3Walker.walkDown(modelV3, new ModelV2PropsPopulator(response, terminalProvider));
return response;
}
@Override

View File

@ -7,7 +7,6 @@ import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@ -17,7 +16,7 @@ import java.util.List;
*/
@Setter
@Getter
public class ModelV3 {
public class TemplateModelV3 {
@NotNull private MessageTemplateV3 template;
@NotNull private List<MessageTemplateGroupV3> groups;

View File

@ -2,6 +2,7 @@ package cn.axzo.msg.center.message.domain.vo;
import cn.axzo.msg.center.domain.entity.GeneralMessageRecord;
import cn.axzo.msg.center.message.domain.dto.MessageTemplateRouterDTO;
import cn.axzo.msg.center.message.service.impl.v3.AppLink;
import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO;
import cn.axzo.msg.center.service.enums.ButtonStyleEnum;
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
@ -194,7 +195,7 @@ public class GeneralMessagePushVO implements Serializable {
/**
* 按钮点击后的跳转地址
*/
private List<ButtonAction> actionPaths;
private List<AppLink> actionPaths;
static CardButton from(MessageTemplateRouterDTO.MessageRouteDetailDTO routeDetail) {
return CardButton.builder()
@ -202,7 +203,7 @@ public class GeneralMessagePushVO implements Serializable {
.action(RouterCategoryEnum.JUMP.name())
.isHighlight(false)
.actionPaths(routeDetail.getRouterConfigs().stream()
.map(e -> new ButtonAction(e.getTerminalType().name(), e.getUrl()))
.map(e -> new AppLink(e.getTerminalType().name(), e.getUrl()))
.collect(Collectors.toList())
).build();
}
@ -217,7 +218,7 @@ public class GeneralMessagePushVO implements Serializable {
.isHighlight(buttonStyles.stream().anyMatch(ButtonStyleEnum.HIGH_LIGHT::equals))
.isOverCard(buttonStyles.stream().anyMatch(ButtonStyleEnum.OVER_CARD::equals))
.actionPaths(Lists.newArrayList(
new ButtonAction(TerminalTypeEnum.WEB_VIEW.name(), routerButton.getApiUrl())))
new AppLink(TerminalTypeEnum.WEB_VIEW.name(), routerButton.getApiUrl())))
.build();
}
return CardButton.builder()
@ -226,7 +227,7 @@ public class GeneralMessagePushVO implements Serializable {
.isHighlight(buttonStyles.stream().anyMatch(ButtonStyleEnum.HIGH_LIGHT::equals))
.isOverCard(buttonStyles.stream().anyMatch(ButtonStyleEnum.OVER_CARD::equals))
.actionPaths(routerButton.getRouterConfigs().stream()
.map(e -> new ButtonAction(e.getTerminalType().name(), e.getUrl()))
.map(e -> new AppLink(e.getTerminalType().name(), e.getUrl()))
.collect(Collectors.toList())
).build();
}

View File

@ -1,210 +0,0 @@
package cn.axzo.msg.center.message.service;
import cn.axzo.msg.center.api.response.MessageDetailRes;
import cn.axzo.msg.center.message.domain.dto.PendingMessageDTO;
import cn.axzo.msg.center.message.domain.dto.PendingMessageStatisticDTO;
import cn.axzo.msg.center.message.domain.param.MessageGroupNodeStatisticParam;
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.pending.request.CompletePendingBySubCodeRequest;
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByIdRequest;
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageByBizCodeRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageFixedTemplatePageRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageIterateRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessagePageRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageQueryRequest;
import cn.axzo.msg.center.service.pending.request.RevokePendingMessageByIdRequest;
import cn.axzo.msg.center.service.pending.request.SetHideRequest;
import cn.axzo.msg.center.service.pending.request.UpdatePendingMessageByIdRequest;
import cn.axzo.msg.center.service.pending.response.AnalysisPage;
import cn.axzo.msg.center.service.pending.response.PendingMessageIterateResponse;
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
import cn.axzo.msg.center.service.pending.response.PendingMessageSimpleDTO;
import cn.axzo.msg.center.service.pending.response.PushPendingMessageDTO;
import cn.azxo.framework.common.model.Page;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
/**
* @description
* 待办Service
* @author cold_blade
* @date 2023/9/20
* @version 1.0
*/
public interface PendingMessageNewService {
/**
* 分类统计待办的待处理状态的数量
*
* @param param 统计入参
* @return 分类信息及其对应的待处理的待办数量列表
*/
List<PendingMessageStatisticDTO> groupStatistic(MessageGroupNodeStatisticParam param);
/**
* 统计个人在某个应用终端的待处理的待办数量
*
* @param param 统计入参
* @return 待处理的待办数量
*/
Integer countUncompleted(MessageGroupNodeStatisticParam param);
/**
* 根据模板id列表统计指定的自然人的待办数量
*
* @param personId 自然人id
* @param templateIds 模板id列表
* @return 指定的人的待办数量
*/
Integer countUncompleted(Long personId, Collection<Long> templateIds);
/**
* 代办列表分页查询
*
* @param request 分页查询相关参数
* @return 代办列表
*/
AnalysisPage<PendingMessageResponse> pageQuery(PendingMessagePageRequest request);
/**
* 遍历待办数据
* @param request
* @return
*/
Page<PendingMessageIterateResponse> iterate(PendingMessageIterateRequest request);
/**
* 查询可以用于分页查询的模版
* @param request
*/
List<String> determinePageQueryTemplateCodes(PendingMessagePageRequest request);
/**
* 代办列表分页查询
*
* @param request 分页查询相关参数
* @return 代办列表
*/
List<PendingMessageResponse> getPendingMessageByAppWorker(PendingMessageFixedTemplatePageRequest request);
/**
* 代办列表分页查询
*
* @param request 分页查询相关参数
* @return 代办列表
*/
Page<MessageDetailRes> compatiblePageQuery(PendingMessagePageRequest request);
/**
* 代办列表指定item查询
*
* @param request 查询相关参数
* @return 指定的item数据
*/
PendingMessageResponse query(PendingMessageQueryRequest request);
/**
* 查询代办详情
*
* @param msgIdentityCode 消息的唯一标识
* @param terminalType APP终端类型
* @return 代办详情
*/
Optional<PendingMessageDTO> detail(String msgIdentityCode, TerminalTypeEnum terminalType);
/**
* 发送代办
*
* @param param 代办核心参数
* @return 代办唯一标识
*/
List<PushPendingMessageDTO> push(PendingMessagePushParam param);
/**
* 完成代办
*
* @param requestNo 代办唯一标识
* @return 成功返回 {@code true} 失败返回 {@code false}
*/
Boolean complete(String requestNo);
/**
* 完成代办
*
* @param param 代办唯一标识
* @return 成功返回 {@code true} 失败返回 {@code false}
*/
Boolean completeById(CompletePendingMessageByIdRequest param);
/**
* 撤销代办
*
* @param requestNo 代办唯一标识
* @return 成功返回 {@code true} 失败返回 {@code false}
*/
Boolean revoke(String requestNo);
/**
* 通过ID撤销代办
*
* @param msgId 代办唯一标识
* @return 成功返回 {@code true} 失败返回 {@code false}
*/
Boolean revokeByMsgId(String msgId);
/**
* 通过业务编码和模版编码完成代办
*
* @param param
* @return 成功返回 {@code true} 失败返回 {@code false}
*/
Boolean completeByTemplateCodeBizCode(CompletePendingMessageRequest param);
/**
* 通过业务和子业务编码和模版编码完成代办
*
* @param param
* @return 成功返回 {@code true} 失败返回 {@code false}
*/
Boolean completeByTemplateCodeSubBizCode(CompletePendingBySubCodeRequest param);
/**
* 通过业务编码和模版编码撤销代办
*
* @param param
* @return 成功返回 {@code true} 失败返回 {@code false}
*/
Boolean revokeByTemplateCodeBizCode(CompletePendingMessageRequest param);
/**
* 通过ID撤销代办
*
* @param param
* @return 成功返回 {@code true} 失败返回 {@code false}
*/
Boolean revokeById(RevokePendingMessageByIdRequest param);
/**
* 通过ID编辑代办bizParam
*
* @param param
* @return 成功返回 {@code true} 失败返回 {@code false}
*/
Boolean updateById(UpdatePendingMessageByIdRequest param);
/**
* 通过BizCode获取最新代办
* @param bizCode
* @return
*/
List<PendingMessageSimpleDTO> getLatestByBizCode(PendingMessageByBizCodeRequest bizCode);
/**
* 将待办设置为隐藏
*/
Boolean setHide(SetHideRequest req);
}

View File

@ -16,15 +16,6 @@ import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
import cn.axzo.msg.center.utils.UUIDUtil;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ -35,6 +26,14 @@ import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @description

View File

@ -0,0 +1,44 @@
package cn.axzo.msg.center.message.service.impl.v3;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import lombok.Getter;
import lombok.Setter;
import java.util.Objects;
/**
* @author yanglin
*/
@Getter
@Setter
@SuppressWarnings("unused")
public class AppLink {
private TerminalTypeEnum platform;
private String url;
public AppLink() {
}
public AppLink(TerminalTypeEnum terminalType, String url) {
this(terminalType.name(), url);
}
public AppLink(String platform, String url) {
this.platform = TerminalTypeEnum.valueOf(platform);
this.url = url;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof AppLink)) return false;
AppLink appLink = (AppLink) o;
return Objects.equals(platform, appLink.platform) && Objects.equals(url, appLink.url);
}
@Override
public int hashCode() {
return Objects.hash(platform, url);
}
}

View File

@ -0,0 +1,47 @@
package cn.axzo.msg.center.message.service.impl.v3;
import cn.axzo.msg.center.service.domain.UrlConfigVisitor;
import cn.axzo.msg.center.service.domain.url.AppUrl;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import lombok.Getter;
import java.util.ArrayList;
import java.util.List;
/**
* @author yanglin
*/
@Getter
public class AppLinkUrlConfigVisitor implements UrlConfigVisitor {
private final List<AppLink> links = new ArrayList<>();
@Override
public void visitAppManagerAndroid(AppUrl android) {
if (android.hasUrl())
addLink(new AppLink(TerminalTypeEnum.ANDROID, android.getUrl()));
}
@Override
public void visitAppManagerIos(AppUrl ios) {
if (ios.hasUrl())
addLink(new AppLink(TerminalTypeEnum.IOS, ios.getUrl()));
}
@Override
public void visitAppWorkerAndroid(AppUrl android) {
if (android.hasUrl())
addLink(new AppLink(TerminalTypeEnum.ANDROID, android.getUrl()));
}
@Override
public void visitAppWorkerIos(AppUrl ios) {
if (ios.hasUrl())
addLink(new AppLink(TerminalTypeEnum.IOS, ios.getUrl()));
}
private void addLink(AppLink link) {
if (!links.contains(link))
links.add(link);
}
}

View File

@ -44,6 +44,7 @@ public class ModelV3ExtPopulator {
ArrayList<ParsedKV> personKeyValues = new ArrayList<>();
List<ComponentWorkerGroup> componentWorkerGroups = new ArrayList<>();
for (ParsedModelV3 model : models) {
if (model == null) continue;
personKeyValues.addAll(model.getPersonKeyValues());
componentWorkerGroups.addAll(model.getComponentWorkerGroups());
}

View File

@ -5,7 +5,7 @@ import cn.axzo.framework.jackson.utility.JSON;
import cn.axzo.msg.center.domain.entity.MessageEntity;
import cn.axzo.msg.center.domain.entity.MessageTemplateGroupV3;
import cn.axzo.msg.center.inside.notices.config.PendingMessageBizConfig;
import cn.axzo.msg.center.message.domain.dto.ModelV3;
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
import cn.axzo.msg.center.message.service.todo.manage.TodoExt;
import cn.axzo.msg.center.service.domain.UrlConfig;
import cn.axzo.msg.center.service.domain.UrlConfigVisitor;
@ -28,9 +28,11 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Component;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -48,15 +50,23 @@ public class ModelV3Parser {
private final PendingMessageBizConfig cfg;
public ParsedModelV3 parseModel(ModelV3 model,
public ParsedModelV3 parseModel(TemplateModelV3 templateModel,
MessageEntity entity,
JSONObject bizParam,
JSONObject routerParam) {
return parseModel(templateModel, entity, bizParam, routerParam, routerParam);
}
public ParsedModelV3 parseModel(TemplateModelV3 templateModel,
MessageEntity entity,
JSONObject bizParam,
JSONObject routerParam,
JSONObject appendRouterParam) {
ParsedModelV3 parsedModel = new ParsedModelV3();
parsedModel.setTemplate(BeanMapper.copyBean(model, ParsedTemplateV3.class));
parsedModel.setGroups(copyGroups(model.getGroups()));
parsedModel.setButtons(BeanMapper.copyList(model.getButtons(), ParsedButtonV3.class));
UrlParser urlParser = new UrlParser(entity, routerParam);
parsedModel.setTemplate(BeanMapper.copyBean(templateModel, ParsedTemplateV3.class));
parsedModel.setGroups(copyGroups(templateModel.getGroups()));
parsedModel.setButtons(BeanMapper.copyList(templateModel.getButtons(), ParsedButtonV3.class));
UrlParser urlParser = new UrlParser(entity, routerParam, appendRouterParam);
ParsedModel3Walker.walkDown(parsedModel, new ParsedModel3Visitor() {
@Override
@ -76,6 +86,8 @@ public class ModelV3Parser {
@Override
public void visitGroupKeyValue(ParsedGroupV3 group, ParsedKV kv) {
kv.setValue(getDefaultResolver().resolveByMap(kv.getValue(), bizParam));
group.getGroupInfo().getKeyValuesForDebug().add(kv);
if (kv.getContentType() == KVContentType.PERSON_ID
&& StringUtils.isNotBlank(kv.getValue())
&& NumberUtils.isDigits(kv.getValue())) {
@ -113,8 +125,18 @@ public class ModelV3Parser {
}
private List<ParsedGroupV3> copyGroups(List<MessageTemplateGroupV3> groups) {
String jsonArray = JSON.toJSONString(groups);
return JSON.parseList(jsonArray, ParsedGroupV3.class);
ArrayList<ParsedGroupV3> parsedGroups = new ArrayList<>();
for (MessageTemplateGroupV3 group : groups) {
ParsedGroupV3 parsedGroup = new ParsedGroupV3();
parsedGroup.setId(group.getId());
parsedGroup.setName(group.getName());
parsedGroup.setGroupType(group.getGroupType());
String groupConfigJsonStr = JSON.toJSONString(group.getGroupConfig());
parsedGroup.setGroupInfo(JSON.parseObject(groupConfigJsonStr, ParsedGroupInfo.class));
parsedGroup.setWorkerInfo(null);
parsedGroups.add(parsedGroup);
}
return parsedGroups;
}
public UrlConfig parseUrlConfig(UrlConfig urlConfig,
@ -122,7 +144,7 @@ public class ModelV3Parser {
JSONObject routerParam) {
String json = JSON.toJSONString(urlConfig);
UrlConfig copy = JSON.parseObject(json, UrlConfig.class);
new UrlParser(entity, routerParam).parseUrlConfig(copy);
new UrlParser(entity, routerParam, routerParam).parseUrlConfig(copy);
return copy;
}
@ -131,6 +153,7 @@ public class ModelV3Parser {
final MessageEntity entity;
final JSONObject routerParam;
@Nullable final JSONObject appendRouterParam;
void parseUrlConfig(UrlConfig urlConfig) {
UrlConfigWalker.walkDown(urlConfig, this);
@ -190,7 +213,7 @@ public class ModelV3Parser {
try {
String parsedUrl = getDefaultResolver().resolveByMap(url, routerParam);
if (cfg.isConcatRouterParams(entity.getTemplateCode()))
parsedUrl = appendRouterParam(parsedUrl, routerParam);
parsedUrl = appendRouterParam(parsedUrl, appendRouterParam);
return parsedUrl;
} finally {
if (populateWorkspaceId)
@ -198,7 +221,9 @@ public class ModelV3Parser {
}
}
String appendRouterParam(String url, JSONObject routerParam) {
String appendRouterParam(String url, @Nullable JSONObject routerParam) {
if (routerParam == null)
return url;
Object ctx = routerParam.remove(TodoExt.CTX);
try {
if (routerParam.isEmpty()) {

View File

@ -6,7 +6,7 @@ import cn.axzo.msg.center.dal.MessageTemplateV3Dao;
import cn.axzo.msg.center.domain.entity.MessageTemplateButtonV3;
import cn.axzo.msg.center.domain.entity.MessageTemplateGroupV3;
import cn.axzo.msg.center.domain.entity.MessageTemplateV3;
import cn.axzo.msg.center.message.domain.dto.ModelV3;
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
import cn.axzo.msg.center.service.enums.StatusEnum;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
@ -32,7 +32,7 @@ public class ModelV3Service {
private final MessageTemplateGroupV3Dao messageTemplateGroupV3Dao;
private final MessageTemplateButtonV3Dao messageTemplateButtonV3Dao;
public Optional<ModelV3> findEnabledByCode(String templateCode) {
public Optional<TemplateModelV3> findEnabledByCode(String templateCode) {
MessageTemplateV3 template = messageTemplateV3Dao.lambdaQuery()
.eq(MessageTemplateV3::getCode, templateCode)
.eq(MessageTemplateV3::getIsDelete, 0)
@ -44,7 +44,7 @@ public class ModelV3Service {
return Optional.of(builder.build(template));
}
public List<ModelV3> getByCodes(List<String> templateCodes) {
public List<TemplateModelV3> getByCodes(List<String> templateCodes) {
if (CollectionUtils.isEmpty(templateCodes))
return Collections.emptyList();
List<MessageTemplateV3> templates = messageTemplateV3Dao.lambdaQuery()
@ -79,12 +79,12 @@ public class ModelV3Service {
}
}
ModelV3 build(MessageTemplateV3 template) {
ModelV3 model = new ModelV3();
model.setTemplate(template);
model.setGroups(templateCode2Groups.getOrDefault(template.getCode(), Collections.emptyList()));
model.setButtons(templateCode2Buttons.getOrDefault(template.getCode(), Collections.emptyList()));
return model;
TemplateModelV3 build(MessageTemplateV3 template) {
TemplateModelV3 templateModel = new TemplateModelV3();
templateModel.setTemplate(template);
templateModel.setGroups(templateCode2Groups.getOrDefault(template.getCode(), Collections.emptyList()));
templateModel.setButtons(templateCode2Buttons.getOrDefault(template.getCode(), Collections.emptyList()));
return templateModel;
}
}

View File

@ -101,7 +101,7 @@ public class TodoRangeQueryService {
// 可执行的/抄送我的
pageResult = pageQueryTodo(request, templateCodes);
List<PendingMessageResponse> messages = todoRespBuilder
.convertAdapter2MessageResponse(pageResult.getList(), request.getTerminalType());
.convertAdapter2MessageResponse(pageResult.getList(), request);
if (request.determineQueryTemplateTerminals())
todoTerminalHelper.populateTemplateTerminals(messages);
messages.forEach(message -> message.setQueryType(request.getQueryType()));
@ -380,7 +380,7 @@ public class TodoRangeQueryService {
.in(CollectionUtils.isNotEmpty(request.getTemplateCodes()), Todo::getTemplateCode, request.getTemplateCodes())
.last("LIMIT " + request.determineLimit()));
List<PendingRecordAdapter> message = todoRespBuilder.buildTodoAdapters(todos);
return todoRespBuilder.convertAdapter2MessageResponse(message, request.getTerminalType());
return todoRespBuilder.convertAdapter2MessageResponse(message, request);
}
@RequiredArgsConstructor

View File

@ -8,11 +8,11 @@ import cn.axzo.msg.center.dal.TodoDao;
import cn.axzo.msg.center.domain.entity.PendingRecordAdapter;
import cn.axzo.msg.center.domain.entity.Todo;
import cn.axzo.msg.center.domain.entity.TodoBusiness;
import cn.axzo.msg.center.message.domain.dto.MessageTemplateDTO;
import cn.axzo.msg.center.message.domain.dto.PendingMessageDTO;
import cn.axzo.msg.center.message.service.MessageTemplateNewService;
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
import cn.axzo.msg.center.message.service.impl.PendingMessageNewServiceImpl;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.message.service.impl.v3.ModelV3Service;
import cn.axzo.msg.center.service.pending.TerminalProvider;
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
import cn.axzo.msg.center.service.pending.response.PendingMessageSimpleDTO;
import lombok.RequiredArgsConstructor;
@ -40,22 +40,22 @@ class TodoRespBuilder {
private final TodoBusinessDao todoBusinessDao;
private final TodoDao todoDao;
private final MessageTemplateNewService messageTemplateNewService;
private final PendingMessageNewServiceImpl pendingMessageNewServiceImpl;
private final ModelV3Service modelV3Service;
// batch convert to old model to reuse the code and save some time
PendingMessageResponse convertAdapter2MessageResponse(
PendingRecordAdapter adapter, TerminalTypeEnum terminalType) {
PendingRecordAdapter adapter, TerminalProvider terminalProvider) {
List<PendingMessageResponse> responses = convertAdapter2MessageResponse(
Collections.singletonList(adapter), terminalType);
Collections.singletonList(adapter), terminalProvider);
return responses.get(0);
}
List<PendingMessageResponse> convertAdapter2MessageResponse(
List<PendingRecordAdapter> adapters, TerminalTypeEnum terminalType) {
List<PendingRecordAdapter> adapters, TerminalProvider terminalProvider) {
return convertAdapter2MessageDTO(adapters).stream()
.map(i -> i.toResponse(terminalType))
.map(i -> i.toResponse(terminalProvider))
.collect(toList());
}
@ -66,10 +66,9 @@ class TodoRespBuilder {
.distinct()
.collect(toList());
// 重新查询模版的收益大于成本
List<MessageTemplateDTO> messageTemplates = messageTemplateNewService
.listByTemplateCodes(templateCodes);
List<TemplateModelV3> templateModels = modelV3Service.getByCodes(templateCodes);
return adapters.stream()
.map(adapter -> pendingMessageNewServiceImpl.convert(adapter, messageTemplates))
.map(adapter -> pendingMessageNewServiceImpl.convertV3(adapter, templateModels))
.collect(toList());
}
@ -87,8 +86,8 @@ class TodoRespBuilder {
templateCodes.add(business.getTemplateCode());
if (todo != null)
templateCodes.add(todo.getTemplateCode());
List<MessageTemplateDTO> messageTemplates = messageTemplateNewService.listByTemplateCodes(templateCodes);
return pendingMessageNewServiceImpl.convert(adapter, messageTemplates);
List<TemplateModelV3> templateModels = modelV3Service.getByCodes(templateCodes);
return pendingMessageNewServiceImpl.convertV3(adapter, templateModels);
}
// !! build adapters

View File

@ -8,11 +8,13 @@ import cn.axzo.msg.center.domain.entity.PendingRecordAdapter;
import cn.axzo.msg.center.domain.entity.Todo;
import cn.axzo.msg.center.domain.entity.TodoBusiness;
import cn.axzo.msg.center.inside.notices.config.PendingMessageBizConfig;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.message.service.impl.v3.ModelV3ExtPopulator;
import cn.axzo.msg.center.service.enums.TodoQueryType;
import cn.axzo.msg.center.service.enums.TodoType;
import cn.axzo.msg.center.service.pending.TerminalProvider;
import cn.axzo.msg.center.service.pending.request.GetTodoRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageByBizCodeRequest;
import cn.axzo.msg.center.service.pending.request.PendingMessageDetailRequestV3;
import cn.axzo.msg.center.service.pending.request.PendingMessageQueryRequest;
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
import cn.axzo.msg.center.service.pending.response.PendingMessageSimpleDTO;
@ -43,6 +45,7 @@ public class TodoSimpleQueryService {
private final TodoDao todoDao;
private final TodoRespBuilder todoRespBuilder;
private final PendingMessageBizConfig cfg;
private final ModelV3ExtPopulator modelV3ExtPopulator;
public PendingMessageResponse query(PendingMessageQueryRequest req) {
// 虽然通过code可以查询到唯一的记录, 把一些事情交给数据库去库, 成本不高
@ -61,24 +64,27 @@ public class TodoSimpleQueryService {
.like(StringUtils.isNotBlank(req.getTitle()), TodoBusiness::getTitle, req.getTitle())
.last("LIMIT 1")
.one();
return todoRespBuilder
PendingMessageResponse response = todoRespBuilder
.convertTodoToMessage(business, todo)
.toResponse(req.getTerminalType());
.toResponse(req);
modelV3ExtPopulator.populate(response.getModelV3());
return response;
}
public PendingMessageResponse getDetail(
String identityCode, TerminalTypeEnum terminalType, TodoQueryType queryType) {
Todo todo = todoDao.findTodoByCode(identityCode).orElse(null);
public PendingMessageResponse getDetail(PendingMessageDetailRequestV3 request) {
Todo todo = todoDao.findTodoByCode(request.getMsgIdentityCode()).orElse(null);
if (todo == null)
return null;
if (queryType == TodoQueryType.SEND_BY_ME) {
if (request.getQueryType() == TodoQueryType.SEND_BY_ME) {
TodoBusiness business = todoBusinessDao.getById(todo.getTodoBusinessId());
PendingRecordAdapter adapter = todoRespBuilder.buildBusinessAdapter(business);
return todoRespBuilder.convertAdapter2MessageResponse(adapter, terminalType);
return todoRespBuilder.convertAdapter2MessageResponse(adapter, request);
}
return todoRespBuilder
PendingMessageResponse response = todoRespBuilder
.convertTodoToMessage(todo)
.toResponse(terminalType);
.toResponse(request);
modelV3ExtPopulator.populate(response.getModelV3());
return response;
}
public PendingMessageResponse getLatestTodoByBiz(
@ -90,7 +96,7 @@ public class TodoSimpleQueryService {
return null;
return todoRespBuilder
.convertTodoToMessage(todo)
.toResponse(null);
.toResponse((TerminalProvider) null);
}
public List<PendingMessageSimpleDTO> getLatestTodosByBiz(PendingMessageByBizCodeRequest param) {

View File

@ -141,7 +141,7 @@ public class TodoWorkerQueryService {
});
}
List<PendingRecordAdapter> adapters = todoRespBuilder.buildTodoAdapters(todos);
return todoRespBuilder.convertAdapter2MessageResponse(adapters, request.getTerminalType());
return todoRespBuilder.convertAdapter2MessageResponse(adapters, request);
}
}

View File

@ -3,7 +3,7 @@ package cn.axzo.msg.center.message.service.todo.manage;
import cn.axzo.msg.center.common.utils.BizAssertions;
import cn.axzo.msg.center.common.utils.PlaceholderResolver;
import cn.axzo.msg.center.domain.entity.Todo;
import cn.axzo.msg.center.message.domain.dto.ModelV3;
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
import cn.axzo.msg.center.service.util.JSONUtils;
import com.alibaba.fastjson.JSONObject;
@ -21,7 +21,7 @@ public class TodoExt {
public static final String CTX = "ctx";
private final PendingMessagePushParam request;
private final ModelV3 model;
private final TemplateModelV3 templateModel;
private JSONObject bizExt;
private JSONObject routerExt;
@ -48,7 +48,7 @@ public class TodoExt {
if (title == null) {
JSONObject ext = (JSONObject)parseBizExtParams().clone();
ext.put(CTX, ImmutableMap.of("request", request));
title = PlaceholderResolver.tryResolve(model.getTemplate().getTitle(), ext);
title = PlaceholderResolver.tryResolve(templateModel.getTemplate().getTitle(), ext);
}
return title;
}
@ -57,7 +57,7 @@ public class TodoExt {
if (content == null) {
JSONObject ext = (JSONObject)parseBizExtParams().clone();
ext.put(CTX, ImmutableMap.of("request", request));
content = PlaceholderResolver.tryResolve(model.getTemplate().getContent(), ext);
content = PlaceholderResolver.tryResolve(templateModel.getTemplate().getContent(), ext);
}
return content;
}

View File

@ -14,7 +14,7 @@ import cn.axzo.msg.center.domain.entity.TodoBusiness;
import cn.axzo.msg.center.domain.entity.TodoHandoverMapping;
import cn.axzo.msg.center.domain.persistence.BaseEntityExt;
import cn.axzo.msg.center.inside.notices.config.PendingMessageBizConfig;
import cn.axzo.msg.center.message.domain.dto.ModelV3;
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
import cn.axzo.msg.center.message.service.impl.v3.ModelV3Service;
import cn.axzo.msg.center.message.service.todo.manage.broadcast.TodoBroadcaster;
@ -121,7 +121,7 @@ public class TodoManager {
*/
private List<PushPendingMessageDTO> sendImpl(TodoRequestContext ctx, PendingMessagePushParam request) {
// 可能会存在重新查询模版的情况, 成本不高
ModelV3 model = modelV3Service.findEnabledByCode(request.getTemplateCode())
TemplateModelV3 templateModel = modelV3Service.findEnabledByCode(request.getTemplateCode())
.orElseThrow(() -> new ServiceException(
String.format("Can't find template. templateCode=%s", request.getTemplateCode())));
BizAssertions.assertNotEmpty(request.getExecutor(), "接受者不能为空");
@ -131,7 +131,7 @@ public class TodoManager {
// 1. 让他们改造, 传bizCode
// 2. 待办自动生成bizCode
// 3. 如果是系统生成的待办, 那么就不会有问题. 目前生成上有2个模版(进场出场)都是系统生成的
boolean genBizCode = cfg.getGenBizCodeTemplates().contains(model.getTemplateCode());
boolean genBizCode = cfg.getGenBizCodeTemplates().contains(templateModel.getTemplateCode());
if (genBizCode)
request.setBizCode(UUIDUtil.uuidString());
else if (StringUtils.isBlank(request.getBizCode()))
@ -142,7 +142,7 @@ public class TodoManager {
.findByBiz(request.getTemplateCode(), request.getBizCode(), true)
.orElse(null);
boolean businessCreated = false;
TodoExt ext = new TodoExt(request, model);
TodoExt ext = new TodoExt(request, templateModel);
if (business == null) {
business = todoRecordBuilder.buildBusiness(request, ext);
business.getRecordExt().setGenBizCode(genBizCode);
@ -152,8 +152,8 @@ public class TodoManager {
//批量默认为false
YesOrNo supportBatchProcess = request.getSupportBatchProcess() == null ? YesOrNo.NO : request.getSupportBatchProcess();
//业务待办设置是否批量处理
if (model.getTemplateCategory() == MessageCategoryEnum.BIZ_PENDING_MESSAGE
&& model.hasPresetButtons())
if (templateModel.getTemplateCategory() == MessageCategoryEnum.BIZ_PENDING_MESSAGE
&& templateModel.hasPresetButtons())
supportBatchProcess = YesOrNo.YES;
request.setSupportBatchProcess(supportBatchProcess);
List<Todo> todos = todoRecordBuilder.buildTodos(
@ -167,8 +167,8 @@ public class TodoManager {
todoBroadcaster.fireTodoUpdates("send", todos);
// 记录日志
// @formatter:off
ctx.addLogContent("templateTitle", model.getTemplate().getTitle())
.addLogContent("templateContent", model.getTemplate().getContent())
ctx.addLogContent("templateTitle", templateModel.getTemplate().getTitle())
.addLogContent("templateContent", templateModel.getTemplate().getContent())
.addLogContent("title", ext.parseTitle())
.addLogContent("content", ext.parseContent())
.addLogContent("bizExtParams", ext.parseBizExtParams())
@ -179,7 +179,7 @@ public class TodoManager {
if (businessCreated)
todoLogger.logBusinessUpdated(ctx, business);
todoLogger.logTodosUpdated(ctx, todos);
applicationContext.publishEvent(new NewTodoEvent(this, model, todos));
applicationContext.publishEvent(new NewTodoEvent(this, templateModel, todos));
return todos.stream()
.map(todo -> new PushPendingMessageDTO(
todo.getId(), todo.getIdentityCode(),

View File

@ -1,7 +1,7 @@
package cn.axzo.msg.center.message.service.todo.manage.event;
import cn.axzo.msg.center.domain.entity.Todo;
import cn.axzo.msg.center.message.domain.dto.ModelV3;
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
import com.alibaba.fastjson.JSON;
import lombok.Getter;
import org.springframework.context.ApplicationEvent;
@ -14,19 +14,19 @@ import java.util.List;
*/
@Getter
public class NewTodoEvent extends ApplicationEvent {
private final ModelV3 model;
private final TemplateModelV3 templateModel;
private final List<Todo> todos;
public NewTodoEvent(Object source, ModelV3 model, List<Todo> todos) {
public NewTodoEvent(Object source, TemplateModelV3 templateModel, List<Todo> todos) {
super(source);
this.model = model;
this.templateModel = templateModel;
this.todos = todos;
}
@Override
public String toString() {
HashMap<String, Object> fields = new HashMap<>();
fields.put("model", model);
fields.put("model", templateModel);
fields.put("todos", todos);
return JSON.toJSONString(fields);
}

View File

@ -4,18 +4,16 @@ import cn.axzo.msg.center.dal.TodoBusinessDao;
import cn.axzo.msg.center.dal.TodoBusinesses;
import cn.axzo.msg.center.domain.entity.Todo;
import cn.axzo.msg.center.domain.entity.TodoBusiness;
import cn.axzo.msg.center.message.domain.dto.ModelV3;
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
import cn.axzo.msg.center.message.service.impl.v3.AppLink;
import cn.axzo.msg.center.message.service.impl.v3.AppLinkUrlConfigVisitor;
import cn.axzo.msg.center.message.service.impl.v3.ModelV3Parser;
import cn.axzo.msg.center.message.service.todo.manage.TodoExt;
import cn.axzo.msg.center.message.service.youmeng.YoumengPush;
import cn.axzo.msg.center.message.service.youmeng.YoumengPush.PushNavigation;
import cn.axzo.msg.center.message.service.youmeng.YoumengTemplateClient;
import cn.axzo.msg.center.service.domain.CardUrlConfig;
import cn.axzo.msg.center.service.domain.UrlConfig;
import cn.axzo.msg.center.service.domain.UrlConfigVisitor;
import cn.axzo.msg.center.service.domain.UrlConfigWalker;
import cn.axzo.msg.center.service.domain.url.AppUrl;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -27,7 +25,7 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -48,7 +46,7 @@ class TodoPushSender implements ApplicationListener<NewTodoEvent> {
log.info("Prepare sending todo push. event={}", event);
ArrayList<YoumengPush> pushes = new ArrayList<>();
for (Todo todo : event.getTodos()) {
Set<PushNavigation> navigations = determineNavigations(event.getModel(), todo);
List<AppLink> navigations = determineNavigations(event.getTemplateModel(), todo);
if (CollectionUtils.isEmpty(navigations))
continue;
YoumengPush push = new YoumengPush();
@ -56,19 +54,19 @@ class TodoPushSender implements ApplicationListener<NewTodoEvent> {
push.setContent(todo.getContent());
push.setReceiverPersonId(todo.getExecutorPersonId());
push.setReceiverOuId(todo.getOuId());
push.setNavigations(navigations);
push.setAppLinks(navigations);
pushes.add(push);
}
if (CollectionUtils.isNotEmpty(pushes))
youmengTemplateClient.asyncSend(event.getModel().getTemplate().getId(), pushes);
youmengTemplateClient.asyncSend(event.getTemplateModel().getTemplate().getId(), pushes);
}
private Set<PushNavigation> determineNavigations(ModelV3 model, Todo todo) {
CardUrlConfig cardUrlConfig = model.getTemplate().getCardUrlConfig();
if (cardUrlConfig == null) return Collections.emptySet();
private List<AppLink> determineNavigations(TemplateModelV3 templateModel, Todo todo) {
CardUrlConfig cardUrlConfig = templateModel.getTemplate().getCardUrlConfig();
if (cardUrlConfig == null) return Collections.emptyList();
UrlConfig urlConfig = cardUrlConfig.getUrlConfig();
if (urlConfig == null)
return Collections.emptySet();
return Collections.emptyList();
JSONObject routerParam = todo.getRouterParams();
if (routerParam == null)
routerParam = new JSONObject();
@ -79,33 +77,9 @@ class TodoPushSender implements ApplicationListener<NewTodoEvent> {
ctx.put("todo", todo);
routerParam.put(TodoExt.CTX, ctx);
Set<PushNavigation> navigations = new HashSet<>();
UrlConfig parsedUrlConfig = modelV3Parser.parseUrlConfig(urlConfig, todo, routerParam);
UrlConfigWalker.walkDown(parsedUrlConfig, new UrlConfigVisitor() {
@Override
public void visitAppManagerAndroid(AppUrl android) {
if (android.hasUrl())
navigations.add(new PushNavigation(TerminalTypeEnum.ANDROID, android.getUrl()));
}
@Override
public void visitAppManagerIos(AppUrl ios) {
if (ios.hasUrl())
navigations.add(new PushNavigation(TerminalTypeEnum.IOS, ios.getUrl()));
}
@Override
public void visitAppWorkerAndroid(AppUrl android) {
if (android.hasUrl())
navigations.add(new PushNavigation(TerminalTypeEnum.ANDROID, android.getUrl()));
}
@Override
public void visitAppWorkerIos(AppUrl ios) {
if (ios.hasUrl())
navigations.add(new PushNavigation(TerminalTypeEnum.IOS, ios.getUrl()));
}
});
return navigations;
AppLinkUrlConfigVisitor visitor = new AppLinkUrlConfigVisitor();
UrlConfigWalker.walkDown(parsedUrlConfig, visitor);
return visitor.getLinks();
}
}

View File

@ -1,14 +1,9 @@
package cn.axzo.msg.center.message.service.youmeng;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import lombok.AllArgsConstructor;
import cn.axzo.msg.center.message.service.impl.v3.AppLink;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* @author yanglin
@ -20,31 +15,10 @@ public class YoumengPush {
private String content;
private Long receiverPersonId;
private Long receiverOuId;
private Set<PushNavigation> navigations;
private List<AppLink> appLinks;
Long determineReceiverOuId() {
return receiverOuId == null ? 0L : receiverOuId;
}
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class PushNavigation {
private TerminalTypeEnum platform;
private String url;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PushNavigation)) return false;
PushNavigation that = (PushNavigation) o;
return platform == that.platform && Objects.equals(url, that.url);
}
@Override
public int hashCode() {
return Objects.hash(platform, url);
}
}
}

View File

@ -6,8 +6,8 @@ import cn.axzo.msg.center.dal.mapper.MessageBaseTemplateMapper;
import cn.axzo.msg.center.domain.entity.MessageBaseTemplate;
import cn.axzo.msg.center.domain.entity.MessageBaseTemplate.PushData;
import cn.axzo.msg.center.event.outer.PushYouMengMessageHandler;
import cn.axzo.msg.center.event.payload.MessageHistoryUpdatedPayload.ActionPath;
import cn.axzo.msg.center.inside.notices.service.IYouMengMessageService;
import cn.axzo.msg.center.message.service.impl.v3.AppLink;
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
@ -114,9 +114,9 @@ public class YoumengTemplateClient {
jsonObject.fluentPut("audio", pushData.getVoiceFile());
}
if (push.getNavigations() != null) {
List<ActionPath> paths = push.getNavigations().stream()
.map(p -> new ActionPath(p.getPlatform(), p.getUrl()))
if (push.getAppLinks() != null) {
List<AppLink> paths = push.getAppLinks().stream()
.map(p -> new AppLink(p.getPlatform(), p.getUrl()))
.collect(toList());
pushYouMengMessageHandler.resolveRouter(jsonObject, paths);
}

View File

@ -325,15 +325,15 @@ public class MigrateMessageTemplateV3Job {
TerminalTypeEnum.WEB_VIEW,
TerminalTypeEnum.MINI_PROGRAM,
TerminalTypeEnum.WECHAT_MINI_PROGRAM).ifPresent(router -> {
AppUrl appUrl = new AppUrl();
appUrl.setUrl(router.getUrl());
AppUrl app = new AppUrl();
app.setUrl(router.getUrl());
if (terminals.contains(PushTerminalEnum.B_ENTERPRISE_APP)) {
urlConfig.getOrCreateAppManager().setIos(appUrl);
urlConfig.getOrCreateAppManager().setAndroid(appUrl);
urlConfig.getOrCreateAppManager().setIos(app);
urlConfig.getOrCreateAppManager().setAndroid(app);
}
if (terminals.contains(PushTerminalEnum.C_WORKER_APP)) {
urlConfig.getOrCreateAppWorker().setIos(appUrl);
urlConfig.getOrCreateAppWorker().setAndroid(appUrl);
urlConfig.getOrCreateAppWorker().setIos(app);
urlConfig.getOrCreateAppWorker().setAndroid(app);
}
});

View File

@ -0,0 +1,15 @@
package cn.axzo.msg.center.service.pending;
import cn.axzo.msg.center.service.enums.AppTerminalTypeEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
/**
* @author yanglin
*/
public interface TerminalProvider {
TerminalTypeEnum getTerminalType();
AppTerminalTypeEnum getAppTerminalType();
}

View File

@ -1,6 +1,5 @@
package cn.axzo.msg.center.service.pending.client;
import cn.axzo.msg.center.api.response.MessageDetailRes;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.enums.TodoQueryType;
import cn.axzo.msg.center.service.pending.request.CompletePendingBySubCodeRequest;
@ -136,16 +135,6 @@ public interface PendingMessageClient {
@PostMapping(value = "/pending-message/getPendingMessageByAppWorker", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<List<PendingMessageResponse>> getPendingMessageByAppWorker(@RequestBody @Valid PendingMessageFixedTemplatePageRequest request);
/**
* 代办列表分页查询
*
* @param request 分页查询相关参数
* @return 代办列表
*/
@Deprecated
@PostMapping(value = "/pending-message/record/compatible/page", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<Page<MessageDetailRes>> compatiblePageQuery(@RequestBody @Valid PendingMessagePageRequest request);
/**
* 代办列表指定待办的查询
*
@ -171,7 +160,7 @@ public interface PendingMessageClient {
@PostMapping(value = "/pending-message/record/detailV3", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<PendingMessageResponse> detailV3(
@RequestBody @Valid PendingMessageDetailRequestV3 requestV3);
@RequestBody @Valid PendingMessageDetailRequestV3 request);
/**
* 根据bizCode查询待办详情

View File

@ -2,6 +2,7 @@ package cn.axzo.msg.center.service.pending.request;
import cn.axzo.msg.center.service.enums.AppTerminalTypeEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.pending.TerminalProvider;
import lombok.Getter;
import lombok.Setter;
@ -13,7 +14,7 @@ import java.util.Set;
*/
@Setter
@Getter
public class GetPendingTodosRequest {
public class GetPendingTodosRequest implements TerminalProvider {
/**
* 待办执行人id
*/

View File

@ -3,6 +3,7 @@ package cn.axzo.msg.center.service.pending.request;
import cn.axzo.msg.center.service.enums.AppTerminalTypeEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.enums.TodoQueryType;
import cn.axzo.msg.center.service.pending.TerminalProvider;
import lombok.Getter;
import lombok.Setter;
@ -11,7 +12,7 @@ import lombok.Setter;
*/
@Setter
@Getter
public class PendingMessageDetailRequestV3 {
public class PendingMessageDetailRequestV3 implements TerminalProvider {
private String msgIdentityCode;
private TerminalTypeEnum terminalType;
private AppTerminalTypeEnum appTerminalType;

View File

@ -4,6 +4,7 @@ import cn.axzo.basics.common.page.PageRequest;
import cn.axzo.msg.center.service.enums.AppTerminalTypeEnum;
import cn.axzo.msg.center.service.enums.IdentityTypeEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.pending.TerminalProvider;
import com.alibaba.fastjson.JSON;
import lombok.Getter;
import lombok.Setter;
@ -21,7 +22,7 @@ import java.util.Date;
*/
@Setter
@Getter
public class PendingMessageFixedTemplatePageRequest implements Serializable {
public class PendingMessageFixedTemplatePageRequest implements TerminalProvider, Serializable {
private static final long serialVersionUID = 7172093131252325437L;
/**

View File

@ -11,6 +11,7 @@ import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.enums.TodoQueryType;
import cn.axzo.msg.center.service.enums.TodoType;
import cn.axzo.msg.center.service.enums.YesOrNo;
import cn.axzo.msg.center.service.pending.TerminalProvider;
import com.alibaba.fastjson.JSON;
import lombok.Data;
import lombok.Getter;
@ -32,7 +33,7 @@ import java.util.Collections;
*/
@Setter
@Getter
public class PendingMessagePageRequest extends PageRequest implements Serializable {
public class PendingMessagePageRequest extends PageRequest implements TerminalProvider, Serializable {
private static final long serialVersionUID = 7172093131252325437L;

View File

@ -5,6 +5,7 @@ import cn.axzo.msg.center.service.enums.BizFinalStateEnum;
import cn.axzo.msg.center.service.enums.PendingMessageStateEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.enums.TodoQueryType;
import cn.axzo.msg.center.service.pending.TerminalProvider;
import com.alibaba.fastjson.JSON;
import lombok.Getter;
import lombok.Setter;
@ -21,7 +22,7 @@ import java.io.Serializable;
*/
@Setter
@Getter
public class PendingMessageQueryRequest implements Serializable {
public class PendingMessageQueryRequest implements TerminalProvider, Serializable {
private static final long serialVersionUID = 3981382821433771344L;

View File

@ -2,6 +2,7 @@ package cn.axzo.msg.center.service.pending.request;
import cn.axzo.msg.center.service.enums.AppTerminalTypeEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.pending.TerminalProvider;
import com.alibaba.fastjson.JSON;
import lombok.Getter;
import lombok.Setter;
@ -18,7 +19,7 @@ import java.util.Collection;
*/
@Setter
@Getter
public class PendingMessageStatisticForWorkerRequest implements Serializable {
public class PendingMessageStatisticForWorkerRequest implements TerminalProvider, Serializable {
private static final long serialVersionUID = 9160942889637654608L;

View File

@ -2,7 +2,7 @@ package cn.axzo.msg.center.service.pending.response;
import cn.axzo.msg.center.api.custombutton.ProposedButtonFilter;
import cn.axzo.msg.center.api.custombutton.ProposedButtons;
import cn.axzo.msg.center.service.domain.CardUrlConfig;
import cn.axzo.msg.center.service.domain.UrlConfig;
import cn.axzo.msg.center.service.dto.ButtonRouterDTO;
import cn.axzo.msg.center.service.dto.DetailRouterDTO;
import cn.axzo.msg.center.service.dto.IdentityDTO;
@ -14,11 +14,9 @@ import cn.axzo.msg.center.service.enums.CardUrlOpenStrategy;
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
import cn.axzo.msg.center.service.enums.OrganizationTypeEnum;
import cn.axzo.msg.center.service.enums.PendingMessageStateEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.enums.TodoQueryType;
import cn.axzo.msg.center.service.enums.TodoType;
import cn.axzo.msg.center.service.pending.response.v3.ModelV2PropsPopulator;
import cn.axzo.msg.center.service.pending.response.v3.ParsedModel3Walker;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedKV;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedModelV3;
import cn.axzo.msg.center.service.template.response.MessageDetailStyle;
import com.alibaba.fastjson.JSON;
@ -30,7 +28,6 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -68,7 +65,6 @@ public class PendingMessageResponse implements Serializable, TodoButtonProvider
/**
* 卡片信息
*/
@Deprecated
private List<MessageCardContentItemDTO> cardItems;
/**
* 代办发起者自然人id
@ -188,7 +184,6 @@ public class PendingMessageResponse implements Serializable, TodoButtonProvider
/**
* 按钮路由
*/
@Deprecated
private List<ButtonRouterDTO> buttonRouters;
/**
* 业务终态的印章图片地址
@ -259,24 +254,20 @@ public class PendingMessageResponse implements Serializable, TodoButtonProvider
*/
private ParsedModelV3 modelV3;
/**
* 显示到卡片上的键值对
*/
private List<ParsedKV> displayOnCardKeyValues;
/**
* 卡片跳转方式. NONE: 无跳转, OPEN_TODO_DETAIL: 打开待办详情, OPEN_CUSTOM_PAGE: 打开指定页面
*/
private CardUrlOpenStrategy cardUrlOpenStrategy;
/**
* 卡片跳转配置. 在links的基础上再包一层, 避免以后卡片增加自己的配置
* 卡片跳转
*/
private CardUrlConfig cardUrlConfig;
public void populateV2Props(TerminalTypeEnum terminalTypeInRequest,
AppTerminalTypeEnum appTypeInRequest) {
if (modelV3 == null) return;
cardItems = new ArrayList<>();
buttonRouters = new ArrayList<>();
ParsedModel3Walker.walkDown(modelV3, new ModelV2PropsPopulator(
this, terminalTypeInRequest, appTypeInRequest));
}
private UrlConfig cardUrl;
public void adjustProposedButtons(boolean forPromoter) {
ProposedButtonFilter.adjustProposedButtons(this, forPromoter);

View File

@ -1,44 +1,39 @@
package cn.axzo.msg.center.service.pending.response.v3;
import cn.axzo.msg.center.service.domain.MobileUrlConfig;
import cn.axzo.msg.center.service.domain.UrlConfig;
import cn.axzo.msg.center.service.domain.parse.TerminalUrl;
import cn.axzo.msg.center.service.domain.url.WebUrl;
import cn.axzo.msg.center.service.dto.ButtonRouterDTO;
import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO;
import cn.axzo.msg.center.service.enums.AppTerminalTypeEnum;
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.pending.TerminalProvider;
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedButtonV3;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedGroupV3;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedKV;
import lombok.RequiredArgsConstructor;
import cn.axzo.msg.center.service.pending.response.v3.model.TerminalUrlParser;
import java.util.Optional;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.function.Supplier;
import static cn.axzo.msg.center.service.enums.AppTerminalTypeEnum.B_ENTERPRISE_APP;
import static cn.axzo.msg.center.service.enums.AppTerminalTypeEnum.CMS_WEB_PC;
import static cn.axzo.msg.center.service.enums.AppTerminalTypeEnum.C_WORKER_APP;
import static cn.axzo.msg.center.service.enums.AppTerminalTypeEnum.OMS_WEB_PC;
import static cn.axzo.msg.center.service.enums.AppTerminalTypeEnum.PC_GA_GENERAL;
/**
* @author yanglin
*/
@RequiredArgsConstructor
public class ModelV2PropsPopulator implements ParsedModel3Visitor {
private final PendingMessageResponse response;
private final TerminalTypeEnum terminalTypeInRequest;
private final AppTerminalTypeEnum appTypeInRequest;
@Nullable private final TerminalUrlParser terminalUrlParser;
public ModelV2PropsPopulator(PendingMessageResponse response, TerminalProvider terminalProvider) {
this.response = response;
this.terminalUrlParser = terminalProvider == null ? null : new TerminalUrlParser(terminalProvider);
}
@Override
public void visitGroupKeyValue(ParsedGroupV3 group, ParsedKV kv) {
MessageCardContentItemDTO cardItem = new MessageCardContentItemDTO();
cardItem.setLabel(kv.getKey());
cardItem.setValue(kv.getValue());
if (response.getCardItems() == null)
response.setCardItems(new ArrayList<>());
response.getCardItems().add(cardItem);
}
@ -46,7 +41,7 @@ public class ModelV2PropsPopulator implements ParsedModel3Visitor {
public void visitButton(ParsedButtonV3 buttonV3) {
Supplier<ButtonRouterDTO> factory = () -> {
ButtonRouterDTO buttonV2 = new ButtonRouterDTO();
buttonV2.setDesc("from model v3");
buttonV2.setDesc(buttonV3.getName());
buttonV2.setCategory(buttonV3.getCategory());
buttonV2.setPresetButtonType(buttonV3.getPresetBtnType());
buttonV2.setStyle(buttonV3.parseStyle());
@ -54,6 +49,8 @@ public class ModelV2PropsPopulator implements ParsedModel3Visitor {
buttonV2.setPendingShow(buttonV3.getPendingShow());
buttonV2.setKey(buttonV3.getCode());
buttonV2.setSource(buttonV3.getSource());
if (response.getButtonRouters() == null)
response.setButtonRouters(new ArrayList<>());
response.getButtonRouters().add(buttonV2);
return buttonV2;
};
@ -62,57 +59,14 @@ public class ModelV2PropsPopulator implements ParsedModel3Visitor {
buttonV2.setUrl(buttonV3.getApiUrl());
return;
}
parseTerminalUrl(buttonV3.getUrlConfig()).ifPresent(terminalUrl -> {
ButtonRouterDTO buttonV2 = factory.get();
buttonV2.setUrl(terminalUrl.getUrl());
buttonV2.setTerminalType(terminalUrl.getTerminalType());
});
}
/**
* 根据请求客户端真实的终端类型来选择对应的URL
*/
public Optional<TerminalUrl> parseTerminalUrl(UrlConfig config) {
if (appTypeInRequest == null)
return Optional.empty();
if (config == null) return Optional.empty();
// PC(CMS)
TerminalUrl pcCms = selectWeb(CMS_WEB_PC, config.getPcCms());
if (pcCms != null) return Optional.of(pcCms);
// PC(OMS)
TerminalUrl pcOms = selectWeb(OMS_WEB_PC, config.getPcOms());
if (pcOms != null) return Optional.of(pcOms);
// PC(政务系统)
TerminalUrl pcGaGeneral = selectWeb(PC_GA_GENERAL, config.getPcGaGeneral());
if (pcGaGeneral != null) return Optional.of(pcGaGeneral);
// APP工人端
TerminalUrl appWorker = selectApp(C_WORKER_APP, config.getAppWorker());
if (appWorker != null) return Optional.of(appWorker);
// APP管理端
TerminalUrl appManager = selectApp(B_ENTERPRISE_APP, config.getAppManager());
return Optional.ofNullable(appManager);
}
private TerminalUrl selectWeb(
AppTerminalTypeEnum selectAppType, WebUrl webUrl) {
if (appTypeInRequest != selectAppType)
return null;
if (webUrl == null)
return null;
return new TerminalUrl(TerminalTypeEnum.WEB, webUrl.getUrl());
}
private TerminalUrl selectApp(
AppTerminalTypeEnum selectAppType, MobileUrlConfig mobileUrl) {
if (appTypeInRequest != selectAppType)
return null;
if (mobileUrl == null)
return null;
if (mobileUrl.getIos() != null && terminalTypeInRequest == TerminalTypeEnum.IOS)
return new TerminalUrl(TerminalTypeEnum.IOS, mobileUrl.getIos().getUrl());
if (mobileUrl.getAndroid() != null && terminalTypeInRequest == TerminalTypeEnum.ANDROID)
return new TerminalUrl(TerminalTypeEnum.ANDROID, mobileUrl.getAndroid().getUrl());
return null;
if (terminalUrlParser == null) return;
terminalUrlParser
.parseTerminalUrl(buttonV3.getUrlConfig())
.ifPresent(terminalUrl -> {
ButtonRouterDTO buttonV2 = factory.get();
buttonV2.setUrl(terminalUrl.getUrl());
buttonV2.setTerminalType(terminalUrl.getTerminalType());
});
}
}

View File

@ -1,9 +1,12 @@
package cn.axzo.msg.center.service.pending.response.v3.model;
import cn.axzo.msg.center.service.domain.DetailConfig;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
/**
@ -23,6 +26,11 @@ public class ParsedGroupInfo {
*/
private DetailConfig detail;
/**
* 用于debug, 前端忽略
*/
private List<ParsedKV> keyValuesForDebug = new ArrayList<>();
public void removeEmptyValues() {
if (keyValues == null) return;
keyValues.removeIf(ParsedKV::isValueEmpty);

View File

@ -3,8 +3,8 @@ package cn.axzo.msg.center.service.pending.response.v3.model;
import cn.axzo.msg.center.service.enums.GroupType;
import lombok.Getter;
import lombok.Setter;
import org.jetbrains.annotations.NotNull;
import javax.validation.constraints.NotNull;
import java.util.Collections;
import java.util.List;
@ -42,7 +42,7 @@ public class ParsedGroupV3 {
private WorkerInfo workerInfo;
@NotNull
public List<ParsedKV> getKeyValues() {
public List<ParsedKV> determineKeyValues() {
return groupInfo == null ? Collections.emptyList() : groupInfo.getKeyValues();
}
}

View File

@ -7,8 +7,10 @@ import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import static java.util.stream.Collectors.toList;
@ -20,10 +22,11 @@ import static java.util.stream.Collectors.toList;
public class ParsedModelV3 {
/**
* 模板. 对前端来说没用
* 前端忽略
*/
@JsonIgnore @JSONField(serialize = false)
private ParsedTemplateV3 template;
/**
* 分组
*/
@ -46,6 +49,17 @@ public class ParsedModelV3 {
@JsonIgnore @JSONField(serialize = false)
private List<ComponentWorkerGroup> componentWorkerGroups = new ArrayList<>();
public List<ParsedKV> determineDisplayOnCardKeyValues() {
return determineGroups().stream()
.filter(group -> group.getGroupType() == GroupType.KV_VALUES)
.map(ParsedGroupV3::getGroupInfo)
.filter(Objects::nonNull)
.map(ParsedGroupInfo::getKeyValues)
.flatMap(Collection::stream)
.filter(ParsedKV::isDisplayOnCard)
.collect(toList());
}
public void addPersonKV(ParsedKV kv) {
personKeyValues.add(kv);
}
@ -71,7 +85,7 @@ public class ParsedModelV3 {
public void removeEmptyKVGroups() {
groups.removeIf(g -> {
boolean isKVGroup = g.getGroupType() == GroupType.KV_VALUES;
return isKVGroup && g.getKeyValues().isEmpty();
return isKVGroup && g.determineKeyValues().isEmpty();
});
}

View File

@ -0,0 +1,77 @@
package cn.axzo.msg.center.service.pending.response.v3.model;
import cn.axzo.msg.center.service.domain.MobileUrlConfig;
import cn.axzo.msg.center.service.domain.UrlConfig;
import cn.axzo.msg.center.service.domain.parse.TerminalUrl;
import cn.axzo.msg.center.service.domain.url.WebUrl;
import cn.axzo.msg.center.service.enums.AppTerminalTypeEnum;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import cn.axzo.msg.center.service.pending.TerminalProvider;
import lombok.RequiredArgsConstructor;
import java.util.Optional;
import static cn.axzo.msg.center.service.enums.AppTerminalTypeEnum.B_ENTERPRISE_APP;
import static cn.axzo.msg.center.service.enums.AppTerminalTypeEnum.CMS_WEB_PC;
import static cn.axzo.msg.center.service.enums.AppTerminalTypeEnum.C_WORKER_APP;
import static cn.axzo.msg.center.service.enums.AppTerminalTypeEnum.OMS_WEB_PC;
import static cn.axzo.msg.center.service.enums.AppTerminalTypeEnum.PC_GA_GENERAL;
/**
* @author yanglin
*/
@RequiredArgsConstructor
public class TerminalUrlParser {
private final TerminalProvider terminalProvider;
/**
* 根据请求客户端真实的终端类型来选择对应的URL
*/
public Optional<TerminalUrl> parseTerminalUrl(UrlConfig config) {
if (config == null) return Optional.empty();
// PC(CMS)
TerminalUrl pcCms = selectWeb(CMS_WEB_PC, config.getPcCms());
if (pcCms != null) return Optional.of(pcCms);
// PC(OMS)
TerminalUrl pcOms = selectWeb(OMS_WEB_PC, config.getPcOms());
if (pcOms != null) return Optional.of(pcOms);
// PC(政务系统)
TerminalUrl pcGaGeneral = selectWeb(PC_GA_GENERAL, config.getPcGaGeneral());
if (pcGaGeneral != null) return Optional.of(pcGaGeneral);
// APP工人端
TerminalUrl appWorker = selectApp(C_WORKER_APP, config.getAppWorker());
if (appWorker != null) return Optional.of(appWorker);
// APP管理端
TerminalUrl appManager = selectApp(B_ENTERPRISE_APP, config.getAppManager());
return Optional.ofNullable(appManager);
}
private TerminalUrl selectWeb(
AppTerminalTypeEnum selectAppType, WebUrl webUrl) {
if (terminalProvider == null)
return null;
if (terminalProvider.getAppTerminalType() != selectAppType)
return null;
if (webUrl == null)
return null;
return new TerminalUrl(TerminalTypeEnum.WEB, webUrl.getUrl());
}
private TerminalUrl selectApp(
AppTerminalTypeEnum selectAppType, MobileUrlConfig mobileUrl) {
if (terminalProvider == null)
return null;
if (terminalProvider.getAppTerminalType() != selectAppType)
return null;
if (mobileUrl == null)
return null;
TerminalTypeEnum terminalType = terminalProvider.getTerminalType();
if (mobileUrl.getIos() != null && terminalType == TerminalTypeEnum.IOS)
return new TerminalUrl(TerminalTypeEnum.IOS, mobileUrl.getIos().getUrl());
if (mobileUrl.getAndroid() != null && terminalType == TerminalTypeEnum.ANDROID)
return new TerminalUrl(TerminalTypeEnum.ANDROID, mobileUrl.getAndroid().getUrl());
return null;
}
}

View File

@ -7,6 +7,7 @@ import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -185,14 +186,15 @@ public class PlaceholderResolver {
* @return 替换完成后的字符串
*/
public String resolveByMap(String content, final Map<String, Object> valueMap) {
Map<String, Object> key2Value = valueMap == null ? Collections.emptyMap() : valueMap;
try {
// 支持级联: person.addresses[1].info
return TemplateParser.parseDollarSign(content, valueMap);
return TemplateParser.parseDollarSign(content, key2Value);
} catch (Exception e) {
log.warn("error eval {}, parameters={}", content, JSON.toJSONString(valueMap), e);
log.warn("error eval {}, parameters={}", content, JSON.toJSONString(key2Value), e);
// fallback
return resolveByRule(content,
placeholderValue -> String.valueOf(valueMap.get(placeholderValue)));
placeholderValue -> String.valueOf(key2Value.get(placeholderValue)));
}
}

View File

@ -1,11 +1,14 @@
package cn.axzo.msg.center.domain.entity;
import cn.axzo.im.center.api.feign.SendPriority;
import cn.axzo.msg.center.domain.utils.IgnorePropsJsonTypeHandler;
import cn.axzo.msg.center.service.domain.CardUrlConfig;
import cn.axzo.msg.center.service.enums.CardUrlOpenStrategy;
import cn.axzo.msg.center.service.enums.MessageCategoryEnum;
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
import cn.axzo.msg.center.service.enums.StatusEnum;
import cn.axzo.msg.center.service.enums.YesOrNo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
@ -13,6 +16,10 @@ import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.StringUtils;
import java.util.Collections;
import java.util.List;
/**
* @author yanglin
@ -106,6 +113,16 @@ public class MessageTemplateV3 extends BaseEntityWithOperator<MessageTemplateV3>
@TableField(typeHandler = IgnorePropsJsonTypeHandler.class)
private RecordExt recordExt;
public Integer determineImSendPriority() {
return imSendPriority == null ? SendPriority.TEMPLATE_MESSAGE.getPriority() : imSendPriority;
}
public List<PushTerminalEnum> determinePushTerminals() {
if (StringUtils.isBlank(pushTerminal))
return Collections.emptyList();
return JSON.parseArray(pushTerminal, PushTerminalEnum.class);
}
public RecordExt getOrCreateRecordExt() {
if (recordExt == null) recordExt = new RecordExt();
return recordExt;