diff --git a/inside-notices/pom.xml b/inside-notices/pom.xml index 17f7fc5d..1de8e909 100644 --- a/inside-notices/pom.xml +++ b/inside-notices/pom.xml @@ -153,6 +153,10 @@ cn.axzo.im.center im-center-api + + cn.axzo.meepo + meepo-api + cn.axzo.basics basics-profiles-api diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/config/PendingMessageBizConfig.java b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/config/PendingMessageBizConfig.java index 8927a38c..07dccdb9 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/config/PendingMessageBizConfig.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/config/PendingMessageBizConfig.java @@ -113,7 +113,11 @@ public class PendingMessageBizConfig { @Getter private Set populateWorkspaceIdTemplateCodes = new HashSet<>(); + private boolean appendRouterParamsAsQueryParams = false; + public boolean isConcatRouterParams(String templateCode) { + if (!appendRouterParamsAsQueryParams) + return false; return dontConcatRouterParamsTemplateCodes == null || !dontConcatRouterParamsTemplateCodes.contains(templateCode); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PendingMessageNewController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PendingMessageNewController.java index 67e50a8e..7b4b92b1 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PendingMessageNewController.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PendingMessageNewController.java @@ -19,6 +19,7 @@ import cn.axzo.msg.center.service.pending.request.GetPendingTodosRequest; 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.PendingMessageCountUncompletedRequest; +import cn.axzo.msg.center.service.pending.request.PendingMessageDetailRequestV3; 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; @@ -160,6 +161,11 @@ public class PendingMessageNewController implements PendingMessageClient { return CommonResponse.success(response); } + @Override + public CommonResponse detailV3(PendingMessageDetailRequestV3 requestV3) { + return CommonResponse.success(); + } + @Override public CommonResponse getLatestTodoByBiz( String templateCode, String bizCode, String subBizCode, String todoType) { diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageTemplateModelV3.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/ModelV3.java similarity index 58% rename from inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageTemplateModelV3.java rename to inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/ModelV3.java index 0f0e048e..c61a94b8 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/MessageTemplateModelV3.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/ModelV3.java @@ -3,8 +3,11 @@ package cn.axzo.msg.center.message.domain.dto; 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.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; @@ -14,7 +17,7 @@ import java.util.List; */ @Setter @Getter -public class MessageTemplateModelV3 { +public class ModelV3 { @NotNull private MessageTemplateV3 template; @NotNull private List groups; @@ -24,4 +27,13 @@ public class MessageTemplateModelV3 { return template.getCode(); } + public MessageCategoryEnum getTemplateCategory() { + return template.getMsgCategory(); + } + + public boolean hasPresetButtons() { + return buttons.stream() + .anyMatch(btn -> btn.getCategory() == RouterCategoryEnum.PRESET_BUTTON); + } + } \ No newline at end of file diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java index a7dd9a0f..e1702209 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/PendingMessageNewServiceImpl.java @@ -45,7 +45,6 @@ import cn.axzo.msg.center.message.service.MessageGroupNodeService; import cn.axzo.msg.center.message.service.MessageTemplateGroupService; import cn.axzo.msg.center.message.service.MessageTemplateNewService; import cn.axzo.msg.center.message.service.PendingMessageNewService; -import cn.axzo.msg.center.message.service.impl.v3.model.OldTemplateModelPropsPopulator; import cn.axzo.msg.center.message.service.todo.MigrateUtils; import cn.axzo.msg.center.message.service.todo.manage.TodoExt; import cn.axzo.msg.center.notices.common.enums.IsDeletedEnum; @@ -156,7 +155,6 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService { private final PendingMessageBizConfig pendingMessageBizConfig; private final MessageGroupNodeDao messageGroupNodeDao; private final MessageRouterUtil messageRouterUtil;; - private final OldTemplateModelPropsPopulator oldTemplateModelPropsPopulator; @Value("${msg.center.pending.hide-seconds:60}") private int pendingDefaultHideSeconds; diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/ModelV3ExtPopulator.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/ModelV3ExtPopulator.java new file mode 100644 index 00000000..3cfb0c34 --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/ModelV3ExtPopulator.java @@ -0,0 +1,132 @@ +package cn.axzo.msg.center.message.service.impl.v3; + +import cn.axzo.basics.profiles.api.UserProfileServiceApi; +import cn.axzo.basics.profiles.dto.basic.BasicDto; +import cn.axzo.basics.profiles.dto.basic.PersonProfileDto; +import cn.axzo.basics.profiles.dto.basic.ProfessionTagDto; +import cn.axzo.basics.profiles.dto.basic.WorkerProfileDto; +import cn.axzo.meepo.api.BankCardApi; +import cn.axzo.meepo.api.dto.response.WorkerBankCardRes; +import cn.axzo.msg.center.common.utils.BizAssertions; +import cn.axzo.msg.center.service.pending.response.v3.model.ComponentWorkerGroup; +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.pending.response.v3.model.PersonInfo; +import cn.axzo.msg.center.service.pending.response.v3.model.WorkerInfo; +import cn.axzo.trade.datasecurity.core.util.DataSecurityHelper; +import lombok.RequiredArgsConstructor; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static java.util.function.Function.identity; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; + +/** + * @author yanglin + */ +@Component +@RequiredArgsConstructor +public class ModelV3ExtPopulator { + + private final UserProfileServiceApi userProfileServiceApi; + private final BankCardApi bankCardApi; + + public void populate(ParsedModelV3... models) { + ArrayList personKeyValues = new ArrayList<>(); + List componentWorkerGroups = new ArrayList<>(); + for (ParsedModelV3 model : models) { + personKeyValues.addAll(model.getPersonKeyValues()); + componentWorkerGroups.addAll(model.getComponentWorkerGroups()); + } + populatePersonKV(personKeyValues); + populateComponentWorkGroup(componentWorkerGroups); + } + + private void populatePersonKV(List keyValues) { + if (CollectionUtils.isEmpty(keyValues)) return; + List personIds = keyValues.stream() + .map(ParsedKV::getValueAsLong) + .filter(Objects::nonNull) + .distinct() + .collect(toList()); + Map personId2Profile = BizAssertions.assertResponse( + userProfileServiceApi.postPersonProfiles(personIds)).stream() + .collect(toMap(BasicDto::getId, identity())); + for (ParsedKV kv : keyValues) { + Long personId = kv.getValueAsLong(); + if (personId == null) continue; + PersonProfileDto profile = personId2Profile.get(personId); + if (profile == null) continue; + PersonInfo personInfo = new PersonInfo(); + personInfo.setRealName(profile.getRealName()); + personInfo.setAvatar(profile.getAvatarUrl()); + personInfo.setMobilePhone(profile.getPhone()); + personInfo.setMobilePhoneCiphertext(DataSecurityHelper.encrypt(profile.getPhone())); + kv.setPersonInfo(personInfo); + } + } + + private void populateComponentWorkGroup(List groups) { + if (CollectionUtils.isEmpty(groups)) return; + List personIds = groups.stream() + .map(ComponentWorkerGroup::getPersonId) + .distinct() + .collect(toList()); + Map personId2WorkerProfile = BizAssertions.assertResponse( + userProfileServiceApi.postWorkerProfileList(personIds)).stream() + .collect(toMap(workerProfileDto -> workerProfileDto.getPersonProfile().getId(), identity())); + Map> personId2BankCard = BizAssertions.assertResponse( + bankCardApi.batchGetBankByAxzoUserId(personIds)).stream() + .collect(groupingBy(WorkerBankCardRes::getPersonId)); + for (ComponentWorkerGroup workerGroup : groups) { + WorkerProfileDto worker = personId2WorkerProfile.get(workerGroup.getPersonId()); + if (worker == null) continue; + PersonProfileDto person = worker.getPersonProfile(); + WorkerInfo workerInfo = new WorkerInfo(); + workerInfo.setName(person.getRealName()); + workerInfo.setIcon(person.getAvatarUrl()); + workerInfo.setPhone(person.getPhone()); + workerInfo.setPhoneCiphertext(DataSecurityHelper.encrypt(person.getPhone())); + workerInfo.setBirthday(person.getBirthday()); + workerInfo.setNationality(person.getNationality()); + workerInfo.setIdNumber(person.getIdNumber()); + workerInfo.setIdNumberCiphertext(DataSecurityHelper.encrypt(person.getIdNumber())); + workerInfo.setIdentityValid(isWorkerIdentityValid(worker)); + List bankCards = personId2BankCard.get(workerGroup.getPersonId()); + workerInfo.setCardValid(CollectionUtils.isNotEmpty(bankCards) + && StringUtils.isNotBlank(bankCards.get(0).getBankCardNo())); + workerInfo.setProfessionNames(worker.getProfessionTags().stream() + .map(ProfessionTagDto::getProfessionName) + .collect(joining("、"))); + workerGroup.getGroup().setWorkerInfo(workerInfo); + } + } + + /** + * 从yoke拷贝过来的 + */ + private boolean isWorkerIdentityValid(WorkerProfileDto worker) { + if (worker == null) return false; + PersonProfileDto personProfile = worker.getPersonProfile(); + return !(null == personProfile + || !StringUtils.isNotBlank(personProfile.getIdNumber()) + || !StringUtils.isNotBlank(personProfile.getRealName()) + || !StringUtils.isNotBlank(personProfile.getSex().toString()) + || !StringUtils.isNotBlank(personProfile.getNationality()) + || null == personProfile.getBirthday() + || !StringUtils.isNotBlank(personProfile.getIdAddress()) + || !StringUtils.isNotBlank(personProfile.getIdAuthority()) + || null == personProfile.getIdStartDate() + || null == personProfile.getIdEndDate() + || !StringUtils.isNotBlank(personProfile.getAvatarUrl())); + } +} \ No newline at end of file diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/ModelV3Parser.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/ModelV3Parser.java new file mode 100644 index 00000000..71a4e9cd --- /dev/null +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/ModelV3Parser.java @@ -0,0 +1,243 @@ +package cn.axzo.msg.center.message.service.impl.v3; + +import cn.axzo.basics.common.BeanMapper; +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.service.todo.manage.TodoExt; +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.domain.url.WebUrl; +import cn.axzo.msg.center.service.enums.GroupType; +import cn.axzo.msg.center.service.enums.KVContentType; +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.ComponentWorkerGroup; +import cn.axzo.msg.center.service.pending.response.v3.model.ParsedButtonV3; +import cn.axzo.msg.center.service.pending.response.v3.model.ParsedGroupInfo; +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 cn.axzo.msg.center.service.pending.response.v3.model.ParsedTemplateV3; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.stereotype.Component; + +import java.net.URLEncoder; +import java.util.List; +import java.util.Map; + +import static cn.axzo.msg.center.common.utils.PlaceholderResolver.getDefaultResolver; + +/** + * @author yanglin + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class ModelV3Parser { + + private static final String CUSTOMER_PERSON_ID = "customerPersonId"; + + private final PendingMessageBizConfig cfg; + + public ParsedModelV3 parseModel(ModelV3 model, + MessageEntity entity, + JSONObject bizParam, + JSONObject routerParam) { + 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); + ParsedModel3Walker.walkDown(parsedModel, new ParsedModel3Visitor() { + + @Override + public void visitTemplateCardUrlConfig(UrlConfig urlConfig) { + urlParser.parseUrlConfig(urlConfig); + } + + @Override + public void visitGroup(ParsedGroupV3 group) { + if (group.getGroupType() == GroupType.COMPONENT_WORKER) { + Long personId = bizParam.getLong(CUSTOMER_PERSON_ID); + if (personId != null && personId > 0) + parsedModel.addComponentWorkerGroup(new ComponentWorkerGroup(group, personId)); + } + } + + @Override + public void visitGroupKeyValue(ParsedGroupV3 group, ParsedKV kv) { + kv.setValue(getDefaultResolver().resolveByMap(kv.getValue(), bizParam)); + if (kv.getContentType() == KVContentType.PERSON_ID + && StringUtils.isNotBlank(kv.getValue()) + && NumberUtils.isDigits(kv.getValue())) { + parsedModel.addPersonKV(kv); + } + } + + @Override + public void exitGroupInfo(ParsedGroupV3 group, ParsedGroupInfo groupInfo) { + groupInfo.removeEmptyValues(); + } + + @Override + public void visitGroupDetailUrl(ParsedGroupV3 group, UrlConfig urlConfig) { + urlParser.parseUrlConfig(urlConfig); + } + + @Override + public void visitButton(ParsedButtonV3 button) { + button.setApiUrl(urlParser.parseUrl(button.getApiUrl())); + } + + @Override + public void visitButtonUrlConfig(ParsedButtonV3 button, UrlConfig urlConfig) { + urlParser.parseUrlConfig(urlConfig); + } + + @Override + public void exitModel(ParsedModelV3 model) { + model.removeEmptyKVGroups(); + } + }); + + return parsedModel; + } + + private List copyGroups(List groups) { + String jsonArray = JSON.toJSONString(groups); + return JSON.parseList(jsonArray, ParsedGroupV3.class); + } + + public UrlConfig parseUrlConfig(UrlConfig urlConfig, + MessageEntity entity, + JSONObject routerParam) { + String json = JSON.toJSONString(urlConfig); + UrlConfig copy = JSON.parseObject(json, UrlConfig.class); + new UrlParser(entity, routerParam).parseUrlConfig(copy); + return copy; + } + + @RequiredArgsConstructor + private class UrlParser implements UrlConfigVisitor { + + final MessageEntity entity; + final JSONObject routerParam; + + void parseUrlConfig(UrlConfig urlConfig) { + UrlConfigWalker.walkDown(urlConfig, this); + } + + @Override + public void visitPcOms(WebUrl pcOms) { + pcOms.setUrl(parseUrl(pcOms.getUrl())); + } + + @Override + public void visitPcCms(WebUrl pcCms) { + pcCms.setUrl(parseUrl(pcCms.getUrl())); + } + + @Override + public void visitPcGaGeneral(WebUrl pcGaGeneral) { + pcGaGeneral.setUrl(parseUrl(pcGaGeneral.getUrl())); + } + + @Override + public void visitAppWorkerIos(AppUrl ios) { + ios.setUrl(parseUrl(ios.getUrl())); + } + + @Override + public void visitAppWorkerAndroid(AppUrl android) { + android.setUrl(parseUrl(android.getUrl())); + } + + @Override + public void visitAppManagerIos(AppUrl ios) { + ios.setUrl(parseUrl(ios.getUrl())); + } + + @Override + public void visitAppManagerAndroid(AppUrl android) { + android.setUrl(parseUrl(android.getUrl())); + } + + String parseUrl(String url) { + if (StringUtils.isBlank(url)) + return url; + boolean populateWorkspaceId = + // @formatter:off + cfg.getPopulateWorkspaceIdTemplateCodes().contains(entity.getTemplateCode()) + + && entity.getReceiverWorkspaceId() != null + && entity.getReceiverWorkspaceId() > 0L + + && !routerParam.containsKey("workspaceId") + + && url.matches(".*\\$\\{\\s*workspaceId\\s*}.*"); + // @formatter:on + if (populateWorkspaceId) + routerParam.put("workspaceId", entity.getReceiverWorkspaceId()); + try { + String parsedUrl = getDefaultResolver().resolveByMap(url, routerParam); + if (cfg.isConcatRouterParams(entity.getTemplateCode())) + parsedUrl = appendRouterParam(parsedUrl, routerParam); + return parsedUrl; + } finally { + if (populateWorkspaceId) + routerParam.remove("workspaceId"); + } + } + + String appendRouterParam(String url, JSONObject routerParam) { + Object ctx = routerParam.remove(TodoExt.CTX); + try { + if (routerParam.isEmpty()) { + return url; + } + StringBuilder paramBuilder = new StringBuilder(); + for (Map.Entry entry : routerParam.entrySet()) { + if (url.contains(entry.getKey() + "=")) { + continue; + } + String value = tryEncode(entry.getValue()); + paramBuilder.append("&").append(entry.getKey()).append("=").append(value); + } + if (StringUtils.isBlank(paramBuilder.toString())) { + return url; + } + if (!url.contains("?")) { + // 替换掉第一个参数分隔符(&) + paramBuilder.replace(0, 1, "?"); + } + return url + paramBuilder; + } finally { + if (ctx != null) { + routerParam.put(TodoExt.CTX, ctx); + } + } + } + + String tryEncode(Object o) { + String value = String.valueOf(o); + try { + value = URLEncoder.encode(value, "UTF-8"); + } catch (Exception e) { + log.warn("error encode pending dynamic value. value={}", value); + } + return value; + } + + } + + +} \ No newline at end of file diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/model/TemplateModelV3Service.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/ModelV3Service.java similarity index 77% rename from inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/model/TemplateModelV3Service.java rename to inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/ModelV3Service.java index 511d4c65..11e28b6a 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/model/TemplateModelV3Service.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/ModelV3Service.java @@ -1,4 +1,4 @@ -package cn.axzo.msg.center.message.service.impl.v3.model; +package cn.axzo.msg.center.message.service.impl.v3; import cn.axzo.msg.center.dal.MessageTemplateButtonV3Dao; import cn.axzo.msg.center.dal.MessageTemplateGroupV3Dao; @@ -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.MessageTemplateModelV3; +import cn.axzo.msg.center.message.domain.dto.ModelV3; import cn.axzo.msg.center.service.enums.StatusEnum; import lombok.RequiredArgsConstructor; import org.apache.commons.collections4.CollectionUtils; @@ -26,14 +26,13 @@ import static java.util.stream.Collectors.toList; */ @Service @RequiredArgsConstructor -public class TemplateModelV3Service { +public class ModelV3Service { private final MessageTemplateV3Dao messageTemplateV3Dao; private final MessageTemplateGroupV3Dao messageTemplateGroupV3Dao; private final MessageTemplateButtonV3Dao messageTemplateButtonV3Dao; - private final TemplateModelV3PropsParser propsParser; - public Optional findEnabledByCode(String templateCode, boolean parseProps) { + public Optional findEnabledByCode(String templateCode) { MessageTemplateV3 template = messageTemplateV3Dao.lambdaQuery() .eq(MessageTemplateV3::getCode, templateCode) .eq(MessageTemplateV3::getIsDelete, 0) @@ -41,18 +40,18 @@ public class TemplateModelV3Service { .one(); if (template == null) return Optional.empty(); - ModelBuilder builder = new ModelBuilder(parseProps, templateCode); + ModelBuilder builder = new ModelBuilder(templateCode); return Optional.of(builder.build(template)); } - public List getByCodes(List templateCodes, boolean parseProps) { + public List getByCodes(List templateCodes) { if (CollectionUtils.isEmpty(templateCodes)) return Collections.emptyList(); List templates = messageTemplateV3Dao.lambdaQuery() .in(MessageTemplateV3::getCode, templateCodes) .eq(MessageTemplateV3::getIsDelete, 0) .list(); - ModelBuilder builder = new ModelBuilder(parseProps, templateCodes.toArray(new String[0])); + ModelBuilder builder = new ModelBuilder(templateCodes.toArray(new String[0])); return templates.stream() .map(builder::build) .collect(toList()); @@ -61,12 +60,10 @@ public class TemplateModelV3Service { @RequiredArgsConstructor private class ModelBuilder { - final boolean parseProps; final Map> templateCode2Groups; final Map> templateCode2Buttons; - ModelBuilder(boolean parseProps, String... templateCodes) { - this.parseProps = parseProps; + ModelBuilder(String... templateCodes) { if (templateCodes.length > 0) { templateCode2Groups = messageTemplateGroupV3Dao.lambdaQuery() .in(MessageTemplateGroupV3::getTemplateCode, Arrays.asList(templateCodes)) @@ -82,12 +79,11 @@ public class TemplateModelV3Service { } } - MessageTemplateModelV3 build(MessageTemplateV3 template) { - MessageTemplateModelV3 model = new MessageTemplateModelV3(); + 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())); - propsParser.parse(model); return model; } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/model/OldTemplateModelPropsPopulator.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/model/OldTemplateModelPropsPopulator.java deleted file mode 100644 index bb21f1bb..00000000 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/model/OldTemplateModelPropsPopulator.java +++ /dev/null @@ -1,10 +0,0 @@ -package cn.axzo.msg.center.message.service.impl.v3.model; - -import org.springframework.stereotype.Component; - -/** - * @author yanglin - */ -@Component -public class OldTemplateModelPropsPopulator { -} \ No newline at end of file diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/model/TemplateModelV3PropsParser.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/model/TemplateModelV3PropsParser.java deleted file mode 100644 index 4a699b58..00000000 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/v3/model/TemplateModelV3PropsParser.java +++ /dev/null @@ -1,15 +0,0 @@ -package cn.axzo.msg.center.message.service.impl.v3.model; - -import cn.axzo.msg.center.message.domain.dto.MessageTemplateModelV3; -import org.springframework.stereotype.Component; - -/** - * @author yanglin - */ -@Component -class TemplateModelV3PropsParser { - - void parse(MessageTemplateModelV3 model) { - } - -} \ No newline at end of file diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/TodoExt.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/TodoExt.java index c4ab3df7..d18e27e9 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/TodoExt.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/TodoExt.java @@ -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.MessageTemplateDTO; +import cn.axzo.msg.center.message.domain.dto.ModelV3; 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 MessageTemplateDTO template; + private final ModelV3 model; 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(template.getTitle(), ext); + title = PlaceholderResolver.tryResolve(model.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(template.getContent(), ext); + content = PlaceholderResolver.tryResolve(model.getTemplate().getContent(), ext); } return content; } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/TodoManager.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/TodoManager.java index 7f186e33..72b0e8e1 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/TodoManager.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/TodoManager.java @@ -14,9 +14,9 @@ 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.MessageTemplateDTO; +import cn.axzo.msg.center.message.domain.dto.ModelV3; import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam; -import cn.axzo.msg.center.message.service.MessageTemplateNewService; +import cn.axzo.msg.center.message.service.impl.v3.ModelV3Service; import cn.axzo.msg.center.message.service.todo.manage.broadcast.TodoBroadcaster; import cn.axzo.msg.center.message.service.todo.manage.broadcast.TodoMqBroadcaster; import cn.axzo.msg.center.message.service.todo.manage.event.HandoverEvent; @@ -88,7 +88,7 @@ public class TodoManager { private final TodoRecordBuilder todoRecordBuilder; private final TodoLogger todoLogger; private final TodoMqBroadcaster todoMqBroadcaster; - private final MessageTemplateNewService messageTemplateNewService; + private final ModelV3Service modelV3Service; private final MqProducer mqProducer; private final ErrorAssembler errorAssembler; private final PendingMessageBizConfig cfg; @@ -121,8 +121,7 @@ public class TodoManager { */ private List sendImpl(TodoRequestContext ctx, PendingMessagePushParam request) { // 可能会存在重新查询模版的情况, 成本不高 - MessageTemplateDTO template = messageTemplateNewService - .queryEnableTemplateByCode(request.getTemplateCode()) + ModelV3 model = modelV3Service.findEnabledByCode(request.getTemplateCode()) .orElseThrow(() -> new ServiceException( String.format("Can't find template. templateCode=%s", request.getTemplateCode()))); BizAssertions.assertNotEmpty(request.getExecutor(), "接受者不能为空"); @@ -132,7 +131,7 @@ public class TodoManager { // 1. 让他们改造, 传bizCode // 2. 待办自动生成bizCode // 3. 如果是系统生成的待办, 那么就不会有问题. 目前生成上有2个模版(进场、出场)都是系统生成的 - boolean genBizCode = cfg.getGenBizCodeTemplates().contains(template.getCode()); + boolean genBizCode = cfg.getGenBizCodeTemplates().contains(model.getTemplateCode()); if (genBizCode) request.setBizCode(UUIDUtil.uuidString()); else if (StringUtils.isBlank(request.getBizCode())) @@ -143,7 +142,7 @@ public class TodoManager { .findByBiz(request.getTemplateCode(), request.getBizCode(), true) .orElse(null); boolean businessCreated = false; - TodoExt ext = new TodoExt(request, template); + TodoExt ext = new TodoExt(request, model); if (business == null) { business = todoRecordBuilder.buildBusiness(request, ext); business.getRecordExt().setGenBizCode(genBizCode); @@ -153,8 +152,8 @@ public class TodoManager { //批量默认为false YesOrNo supportBatchProcess = request.getSupportBatchProcess() == null ? YesOrNo.NO : request.getSupportBatchProcess(); //业务待办设置是否批量处理 - if (template.getMsgCategory() == MessageCategoryEnum.BIZ_PENDING_MESSAGE - && template.hasPresetButtons()) + if (model.getTemplateCategory() == MessageCategoryEnum.BIZ_PENDING_MESSAGE + && model.hasPresetButtons()) supportBatchProcess = YesOrNo.YES; request.setSupportBatchProcess(supportBatchProcess); List todos = todoRecordBuilder.buildTodos( @@ -168,8 +167,8 @@ public class TodoManager { todoBroadcaster.fireTodoUpdates("send", todos); // 记录日志 // @formatter:off - ctx.addLogContent("templateTitle", template.getTitle()) - .addLogContent("templateContent", template.getContent()) + ctx.addLogContent("templateTitle", model.getTemplate().getTitle()) + .addLogContent("templateContent", model.getTemplate().getContent()) .addLogContent("title", ext.parseTitle()) .addLogContent("content", ext.parseContent()) .addLogContent("bizExtParams", ext.parseBizExtParams()) @@ -180,7 +179,7 @@ public class TodoManager { if (businessCreated) todoLogger.logBusinessUpdated(ctx, business); todoLogger.logTodosUpdated(ctx, todos); - applicationContext.publishEvent(new NewTodoEvent(this, template, todos)); + applicationContext.publishEvent(new NewTodoEvent(this, model, todos)); return todos.stream() .map(todo -> new PushPendingMessageDTO( todo.getId(), todo.getIdentityCode(), diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/event/NewTodoEvent.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/event/NewTodoEvent.java index 0f20bc95..35e4c818 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/event/NewTodoEvent.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/event/NewTodoEvent.java @@ -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.MessageTemplateDTO; +import cn.axzo.msg.center.message.domain.dto.ModelV3; 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 MessageTemplateDTO template; + private final ModelV3 model; private final List todos; - public NewTodoEvent(Object source, MessageTemplateDTO template, List todos) { + public NewTodoEvent(Object source, ModelV3 model, List todos) { super(source); - this.template = template; + this.model = model; this.todos = todos; } @Override public String toString() { HashMap fields = new HashMap<>(); - fields.put("template", template); + fields.put("model", model); fields.put("todos", todos); return JSON.toJSONString(fields); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/event/TodoPushSender.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/event/TodoPushSender.java index 6f05d001..f0494b9c 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/event/TodoPushSender.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/event/TodoPushSender.java @@ -4,15 +4,18 @@ 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.MessageTemplateDTO; -import cn.axzo.msg.center.message.domain.dto.MessageTemplateRouterDTO; -import cn.axzo.msg.center.message.domain.dto.MessageTemplateRouterDTO.MessageRouteDetailDTO; -import cn.axzo.msg.center.message.domain.dto.MessageTemplateRouterDTO.MessageRouterConfigDTO; +import cn.axzo.msg.center.message.domain.dto.ModelV3; +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.utils.MessageRouterUtil; +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; @@ -24,8 +27,9 @@ import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.List; +import java.util.HashSet; import java.util.Map; +import java.util.Set; /** * @author yanglin @@ -36,53 +40,72 @@ import java.util.Map; class TodoPushSender implements ApplicationListener { private final YoumengTemplateClient youmengTemplateClient; - private final MessageRouterUtil messageRouterUtil; private final TodoBusinessDao todoBusinessDao; + private final ModelV3Parser modelV3Parser; @Override public void onApplicationEvent(@NotNull NewTodoEvent event) { log.info("Prepare sending todo push. event={}", event); ArrayList pushes = new ArrayList<>(); for (Todo todo : event.getTodos()) { + Set navigations = determineNavigations(event.getModel(), todo); + if (CollectionUtils.isEmpty(navigations)) + continue; YoumengPush push = new YoumengPush(); push.setTitle(todo.getTitle()); push.setContent(todo.getContent()); push.setReceiverPersonId(todo.getExecutorPersonId()); push.setReceiverOuId(todo.getOuId()); - push.setNavigations(determineNavigations(event.getTemplate(), todo)); + push.setNavigations(navigations); pushes.add(push); } - youmengTemplateClient.asyncSend(event.getTemplate().getId(), pushes); + if (CollectionUtils.isNotEmpty(pushes)) + youmengTemplateClient.asyncSend(event.getModel().getTemplate().getId(), pushes); } - private List determineNavigations(MessageTemplateDTO template, Todo todo) { - if (template.getMsgTemplateRouter() == null) - return Collections.emptyList(); - MessageRouteDetailDTO detail = template.getMsgTemplateRouter().getRouteDetail(); - if (detail == null) - return Collections.emptyList(); - List routerConfigs = detail.getRouterConfigs(); - if (CollectionUtils.isEmpty(routerConfigs)) - return Collections.emptyList(); + private Set determineNavigations(ModelV3 model, Todo todo) { + CardUrlConfig cardUrlConfig = model.getTemplate().getCardUrlConfig(); + if (cardUrlConfig == null) return Collections.emptySet(); + UrlConfig urlConfig = cardUrlConfig.getUrlConfig(); + if (urlConfig == null) + return Collections.emptySet(); JSONObject routerParam = todo.getRouterParams(); - if (routerParam == null) { + if (routerParam == null) routerParam = new JSONObject(); - } TodoBusinesses businesses = todoBusinessDao.getBusinesses(todo); TodoBusiness business = businesses.findBusiness(todo).orElse(null); Map ctx = new HashMap<>(); ctx.put("business", business); ctx.put("todo", todo); routerParam.put(TodoExt.CTX, ctx); - MessageTemplateRouterDTO router = messageRouterUtil.parseAndConcatRouteUrl( - todo, template, template.getMsgTemplateRouter(), routerParam); - if (router == null) - return Collections.emptyList(); - ArrayList navigations = new ArrayList<>(); - for (MessageRouterConfigDTO routerCfg : router.getRouteDetail().getRouterConfigs()) { - String url = template.isCardJumpToBiz() ? routerCfg.getUrl() : ""; - navigations.add(new PushNavigation(routerCfg.getTerminalType(), url)); - } + + Set 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; } } \ No newline at end of file diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/youmeng/YoumengPush.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/youmeng/YoumengPush.java index 9a69f748..c881479b 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/youmeng/YoumengPush.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/youmeng/YoumengPush.java @@ -3,9 +3,12 @@ package cn.axzo.msg.center.message.service.youmeng; import cn.axzo.msg.center.service.enums.TerminalTypeEnum; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.Getter; import lombok.NoArgsConstructor; import java.util.List; +import java.util.Objects; +import java.util.Set; /** * @author yanglin @@ -17,18 +20,31 @@ public class YoumengPush { private String content; private Long receiverPersonId; private Long receiverOuId; - private List navigations; + private Set navigations; Long determineReceiverOuId() { return receiverOuId == null ? 0L : receiverOuId; } - @Data + @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); + } } } \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/GroupConfig.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/GroupConfig.java index 0f333bd2..69a3292b 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/GroupConfig.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/GroupConfig.java @@ -2,6 +2,7 @@ package cn.axzo.msg.center.service.domain; import lombok.Getter; import lombok.Setter; +import org.apache.commons.lang3.StringUtils; import java.util.List; @@ -22,4 +23,12 @@ public class GroupConfig { */ private DetailConfig detail; + public void removeEmptyValues() { + if (keyValues == null) return; + keyValues.removeIf(kv -> { + String value = kv.getValue(); + return StringUtils.isBlank(value) || "null".equalsIgnoreCase(value); + }); + } + } \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/UrlConfig.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/UrlConfig.java index e31b3750..7dd29897 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/UrlConfig.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/UrlConfig.java @@ -1,18 +1,13 @@ package cn.axzo.msg.center.service.domain; -import cn.axzo.msg.center.service.domain.parse.TerminalUrl; -import cn.axzo.msg.center.service.domain.parse.TerminalUrlParser; import cn.axzo.msg.center.service.domain.url.AppUrl; import cn.axzo.msg.center.service.domain.url.WebUrl; -import cn.axzo.msg.center.service.enums.AppTerminalTypeEnum; import cn.axzo.msg.center.service.enums.WebPageOpenStrategy; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Getter; import lombok.Setter; -import java.util.List; - /** * REQ-3045 * @@ -47,10 +42,6 @@ public class UrlConfig { */ private MobileUrlConfig appManager; - public List parse(AppTerminalTypeEnum appType) { - return new TerminalUrlParser(this, appType).parse(); - } - @JsonIgnore @JSONField(serialize = false) public WebUrl getOrCreatePcOms() { if (pcOms == null) diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/UrlConfigVisitor.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/UrlConfigVisitor.java new file mode 100644 index 00000000..8eac5aac --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/UrlConfigVisitor.java @@ -0,0 +1,31 @@ +package cn.axzo.msg.center.service.domain; + +import cn.axzo.msg.center.service.domain.url.AppUrl; +import cn.axzo.msg.center.service.domain.url.WebUrl; + +/** + * @author yanglin + */ +public interface UrlConfigVisitor { + + default void visitUrlConfig(UrlConfig urlConfig) {}; + + default void visitPcOms(WebUrl pcOms) {}; + + default void visitPcCms(WebUrl pcCms) {}; + + default void visitPcGaGeneral(WebUrl pcGaGeneral) {}; + + default void visitAppWorker(MobileUrlConfig appWorker) {}; + + default void visitAppWorkerIos(AppUrl ios) {}; + + default void visitAppWorkerAndroid(AppUrl android) {}; + + default void visitAppManager(MobileUrlConfig appWorker) {}; + + default void visitAppManagerIos(AppUrl ios) {}; + + default void visitAppManagerAndroid(AppUrl android) {}; + +} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/UrlConfigWalker.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/UrlConfigWalker.java new file mode 100644 index 00000000..c8efcd3c --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/UrlConfigWalker.java @@ -0,0 +1,51 @@ +package cn.axzo.msg.center.service.domain; + +/** + * @author yanglin + */ +public class UrlConfigWalker { + + public static void walkDown(UrlConfig urlConfig, UrlConfigVisitor visitor) { + if (urlConfig == null) return; + visitor.visitUrlConfig(urlConfig); + visitPcOms(urlConfig, visitor); + visitPcCms(urlConfig, visitor); + visitPcGaGeneral(urlConfig, visitor); + visitAppWorker(urlConfig, visitor); + visitAppManager(urlConfig, visitor); + } + + private static void visitPcOms(UrlConfig urlConfig, UrlConfigVisitor visitor) { + if (urlConfig.getPcOms() != null) + visitor.visitPcOms(urlConfig.getPcOms()); + } + + private static void visitPcCms(UrlConfig urlConfig, UrlConfigVisitor visitor) { + if (urlConfig.getPcCms() != null) + visitor.visitPcCms(urlConfig.getPcCms()); + } + + private static void visitPcGaGeneral(UrlConfig urlConfig, UrlConfigVisitor visitor) { + if (urlConfig.getPcGaGeneral() != null) + visitor.visitPcGaGeneral(urlConfig.getPcGaGeneral()); + } + + private static void visitAppWorker(UrlConfig urlConfig, UrlConfigVisitor visitor) { + if (urlConfig.getAppWorker() == null) return; + visitor.visitAppWorker(urlConfig.getAppWorker()); + if (urlConfig.getAppWorker().getIos() != null) + visitor.visitAppWorkerIos(urlConfig.getAppWorker().getIos()); + if (urlConfig.getAppWorker().getAndroid() != null) + visitor.visitAppWorkerAndroid(urlConfig.getAppWorker().getAndroid()); + } + + private static void visitAppManager(UrlConfig urlConfig, UrlConfigVisitor visitor) { + if (urlConfig.getAppManager() == null) return; + visitor.visitAppManager(urlConfig.getAppManager()); + if (urlConfig.getAppManager().getIos() != null) + visitor.visitAppManagerIos(urlConfig.getAppManager().getIos()); + if (urlConfig.getAppManager().getAndroid() != null) + visitor.visitAppManagerAndroid(urlConfig.getAppManager().getAndroid()); + } + +} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/parse/TerminalUrlParser.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/parse/TerminalUrlParser.java deleted file mode 100644 index 5ef34266..00000000 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/domain/parse/TerminalUrlParser.java +++ /dev/null @@ -1,78 +0,0 @@ -package cn.axzo.msg.center.service.domain.parse; - -import cn.axzo.msg.center.service.domain.MobileUrlConfig; -import cn.axzo.msg.center.service.domain.UrlConfig; -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 lombok.RequiredArgsConstructor; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -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 UrlConfig config; - private final AppTerminalTypeEnum requestType; - - /** - * 根据请求客户端真实的终端类型来选择对应的URL - */ - public List parse() { - ArrayList urls = new ArrayList<>(); - - // !! 只会命中其一 - - // PC(CMS) - selectWeb(CMS_WEB_PC, config.getPcCms()).ifPresent(urls::add); - // PC(OMS) - selectWeb(OMS_WEB_PC, config.getPcOms()).ifPresent(urls::add); - // PC(政务系统) - selectWeb(PC_GA_GENERAL, config.getPcGaGeneral()).ifPresent(urls::add); - - // !! 只会命中其一 - - // APP工人端 - urls.addAll(selectApp(C_WORKER_APP, config.getAppWorker())); - // APP管理端 - urls.addAll(selectApp(B_ENTERPRISE_APP, config.getAppManager())); - - return urls; - } - - private Optional selectWeb( - AppTerminalTypeEnum selectType, WebUrl webUrl) { - if (requestType != selectType) - return Optional.empty(); - if (webUrl == null) - return Optional.empty(); - return Optional.of(new TerminalUrl(TerminalTypeEnum.WEB, webUrl.getUrl())); - } - - private List selectApp( - AppTerminalTypeEnum selectType, MobileUrlConfig mobileUrl) { - if (requestType != selectType) - return Collections.emptyList(); - if (mobileUrl == null) - return Collections.emptyList(); - ArrayList urls = new ArrayList<>(); - if (mobileUrl.getIos() != null) - urls.add(new TerminalUrl(TerminalTypeEnum.IOS, mobileUrl.getIos().getUrl())); - if (mobileUrl.getAndroid() != null) - urls.add(new TerminalUrl(TerminalTypeEnum.ANDROID, mobileUrl.getAndroid().getUrl())); - return urls; - } - -} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/client/PendingMessageClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/client/PendingMessageClient.java index d6bb50e7..05019a78 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/client/PendingMessageClient.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/client/PendingMessageClient.java @@ -10,6 +10,7 @@ import cn.axzo.msg.center.service.pending.request.GetPendingTodosRequest; 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.PendingMessageCountUncompletedRequest; +import cn.axzo.msg.center.service.pending.request.PendingMessageDetailRequestV3; 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; @@ -161,12 +162,18 @@ public interface PendingMessageClient { * @param terminalType APP终端类型 * @return 代办详情 */ + @Deprecated @PostMapping(value = "/pending-message/record/detail", produces = {MediaType.APPLICATION_JSON_VALUE}) CommonResponse detail(@RequestParam("msgIdentityCode") String msgIdentityCode, @RequestParam("terminalType") TerminalTypeEnum terminalType, @RequestParam(value = "queryType", required = false) TodoQueryType queryType); + @Deprecated + @PostMapping(value = "/pending-message/record/detailV3", produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse detailV3( + @RequestBody @Valid PendingMessageDetailRequestV3 requestV3); + /** * 根据bizCode查询待办详情 * diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/GetPendingTodosRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/GetPendingTodosRequest.java index 8bc24855..d5c6d60d 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/GetPendingTodosRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/GetPendingTodosRequest.java @@ -1,5 +1,6 @@ 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 lombok.Getter; import lombok.Setter; @@ -36,6 +37,8 @@ public class GetPendingTodosRequest { private TerminalTypeEnum terminalType; + private AppTerminalTypeEnum appTerminalType; + public int determineLimit() { if (limit <= 0) return 10; diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/PendingMessageDetailRequestV3.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/PendingMessageDetailRequestV3.java new file mode 100644 index 00000000..dba5ba73 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/PendingMessageDetailRequestV3.java @@ -0,0 +1,19 @@ +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 lombok.Getter; +import lombok.Setter; + +/** + * @author yanglin + */ +@Setter +@Getter +public class PendingMessageDetailRequestV3 { + private String msgIdentityCode; + private TerminalTypeEnum terminalType; + private AppTerminalTypeEnum appTerminalType; + private TodoQueryType queryType; +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/PendingMessageQueryRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/PendingMessageQueryRequest.java index 131cc44d..21500cd0 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/PendingMessageQueryRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/PendingMessageQueryRequest.java @@ -1,5 +1,6 @@ package cn.axzo.msg.center.service.pending.request; +import cn.axzo.msg.center.service.enums.AppTerminalTypeEnum; import cn.axzo.msg.center.service.enums.BizFinalStateEnum; import cn.axzo.msg.center.service.enums.PendingMessageStateEnum; import cn.axzo.msg.center.service.enums.TerminalTypeEnum; @@ -34,6 +35,7 @@ public class PendingMessageQueryRequest implements Serializable { * WECHAT_MINI_PROGRAM: 微信小程序页面 */ private TerminalTypeEnum terminalType; + private AppTerminalTypeEnum appTerminalType; /** * 代办消息状态 * UNSENT: 未发送 diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/PendingMessageResponse.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/PendingMessageResponse.java index 8b1bf77f..d5901ee9 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/PendingMessageResponse.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/PendingMessageResponse.java @@ -2,6 +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.dto.ButtonRouterDTO; import cn.axzo.msg.center.service.dto.DetailRouterDTO; import cn.axzo.msg.center.service.dto.IdentityDTO; @@ -9,12 +10,16 @@ import cn.axzo.msg.center.service.dto.MessageCardContentItemDTO; import cn.axzo.msg.center.service.enums.AppTerminalTypeEnum; 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.TodoQueryType; import cn.axzo.msg.center.service.enums.TodoType; -import cn.axzo.msg.center.service.pending.response.v3.TodoModelV3; +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 com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; @@ -25,15 +30,15 @@ import lombok.NoArgsConstructor; import lombok.Setter; import java.io.Serializable; +import java.util.ArrayList; import java.util.Date; import java.util.List; /** - * @description - * 代办消息记录页面展示数模型 * @author cold_blade - * @date 2023/9/23 * @version 1.0 + * @description 代办消息记录页面展示数模型 + * @date 2023/9/23 */ @Setter @Getter @@ -63,6 +68,7 @@ public class PendingMessageResponse implements Serializable, TodoButtonProvider /** * 卡片信息 */ + @Deprecated private List cardItems; /** * 代办发起者自然人id @@ -177,10 +183,12 @@ public class PendingMessageResponse implements Serializable, TodoButtonProvider /** * 业务详情路由 */ + @Deprecated private DetailRouterDTO detailRouter; /** * 按钮路由 */ + @Deprecated private List buttonRouters; /** * 业务终态的印章图片地址 @@ -221,10 +229,10 @@ public class PendingMessageResponse implements Serializable, TodoButtonProvider /** * 查询类型 - * HAS_BEEN_SENT: 待处理 - * COMPLETED: 已处理 - * SEND_BY_ME: 我发起 - * COPIED_TO_ME: 抄送我 + * HAS_BEEN_SENT: 待处理 + * COMPLETED: 已处理 + * SEND_BY_ME: 我发起 + * COPIED_TO_ME: 抄送我 */ private TodoQueryType queryType; @@ -249,7 +257,26 @@ public class PendingMessageResponse implements Serializable, TodoButtonProvider /** * 基于分组的待办信息 */ - private TodoModelV3 modelV3; + private ParsedModelV3 modelV3; + + /** + * 卡片跳转方式. 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)); + } public void adjustProposedButtons(boolean forPromoter) { ProposedButtonFilter.adjustProposedButtons(this, forPromoter); diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/ModelV2PropsPopulator.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/ModelV2PropsPopulator.java new file mode 100644 index 00000000..11794471 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/ModelV2PropsPopulator.java @@ -0,0 +1,118 @@ +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.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 java.util.Optional; +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; + + @Override + public void visitGroupKeyValue(ParsedGroupV3 group, ParsedKV kv) { + MessageCardContentItemDTO cardItem = new MessageCardContentItemDTO(); + cardItem.setLabel(kv.getKey()); + cardItem.setValue(kv.getValue()); + response.getCardItems().add(cardItem); + } + + @Override + public void visitButton(ParsedButtonV3 buttonV3) { + Supplier factory = () -> { + ButtonRouterDTO buttonV2 = new ButtonRouterDTO(); + buttonV2.setDesc("from model v3"); + buttonV2.setCategory(buttonV3.getCategory()); + buttonV2.setPresetButtonType(buttonV3.getPresetBtnType()); + buttonV2.setStyle(buttonV3.parseStyle()); + buttonV2.setExecutorShow(buttonV3.getExecutorShow()); + buttonV2.setPendingShow(buttonV3.getPendingShow()); + buttonV2.setKey(buttonV3.getCode()); + buttonV2.setSource(buttonV3.getSource()); + response.getButtonRouters().add(buttonV2); + return buttonV2; + }; + if (buttonV3.getCategory() != RouterCategoryEnum.JUMP) { + ButtonRouterDTO buttonV2 = factory.get(); + 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 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; + } + +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/ParsedModel3Visitor.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/ParsedModel3Visitor.java new file mode 100644 index 00000000..bf9084c3 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/ParsedModel3Visitor.java @@ -0,0 +1,57 @@ +package cn.axzo.msg.center.service.pending.response.v3; + +import cn.axzo.msg.center.service.domain.DetailConfig; +import cn.axzo.msg.center.service.domain.UrlConfig; +import cn.axzo.msg.center.service.pending.response.v3.model.ParsedButtonV3; +import cn.axzo.msg.center.service.pending.response.v3.model.ParsedGroupInfo; +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 cn.axzo.msg.center.service.pending.response.v3.model.ParsedTemplateV3; + +/** + * @author yanglin + */ +public interface ParsedModel3Visitor { + + default void visitModel(ParsedModelV3 model) {} + + default void exitModel(ParsedModelV3 model) {} + + default void visitTemplate(ParsedTemplateV3 template) {} + + default void exitTemplate(ParsedTemplateV3 template) {} + + default void visitTemplateCardUrlConfig(UrlConfig urlConfig) {} + + default void exitTemplateCardUrlConfig(UrlConfig urlConfig) {} + + default void visitGroup(ParsedGroupV3 group) {} + + default void exitGroup(ParsedGroupV3 group) {} + + default void visitGroupInfo(ParsedGroupV3 group, ParsedGroupInfo groupInfo) {} + + default void exitGroupInfo(ParsedGroupV3 group, ParsedGroupInfo groupInfo) {} + + default void visitGroupKeyValue(ParsedGroupV3 group, ParsedKV kv) {} + + default void exitGroupKeyValue(ParsedGroupV3 group, ParsedKV kv) {} + + default void visitGroupDetail(ParsedGroupV3 group, DetailConfig detailConfig) {} + + default void exitGroupDetail(ParsedGroupV3 group, DetailConfig detailConfig) {} + + default void visitGroupDetailUrl(ParsedGroupV3 group, UrlConfig urlConfig) {} + + default void exitGroupDetailUrl(ParsedGroupV3 group, UrlConfig urlConfig) {} + + default void visitButton(ParsedButtonV3 button) {} + + default void exitButton(ParsedButtonV3 button) {} + + default void visitButtonUrlConfig(ParsedButtonV3 button, UrlConfig urlConfig) {} + + default void exitButtonUrlConfig(ParsedButtonV3 button, UrlConfig urlConfig) {} + +} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/ParsedModel3Walker.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/ParsedModel3Walker.java new file mode 100644 index 00000000..6770b37e --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/ParsedModel3Walker.java @@ -0,0 +1,83 @@ +package cn.axzo.msg.center.service.pending.response.v3; + +import cn.axzo.msg.center.service.domain.CardUrlConfig; +import cn.axzo.msg.center.service.pending.response.v3.model.ParsedButtonV3; +import cn.axzo.msg.center.service.pending.response.v3.model.ParsedGroupInfo; +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 cn.axzo.msg.center.service.pending.response.v3.model.ParsedTemplateV3; + +/** + * @author yanglin + */ +public class ParsedModel3Walker { + + public static void walkDown(ParsedModelV3 model, ParsedModel3Visitor visitor) { + if (model == null) return; + visitor.visitModel(model); + ParsedTemplateV3 template = model.getTemplate(); + visitor.visitTemplate(template); + visitCard(visitor, template); + for (ParsedGroupV3 group : model.determineGroups()) + visitGroup(visitor, group); + for (ParsedButtonV3 button : model.determineButtons()) + visitButton(visitor, button); + visitor.exitTemplate(template); + visitor.exitModel(model); + } + + private static void visitCard(ParsedModel3Visitor visitor, + ParsedTemplateV3 template) { + CardUrlConfig cardUrlConfig = template.getCardUrlConfig(); + if (cardUrlConfig != null && cardUrlConfig.getUrlConfig() != null) { + visitor.visitTemplateCardUrlConfig(cardUrlConfig.getUrlConfig()); + visitor.exitTemplateCardUrlConfig(cardUrlConfig.getUrlConfig()); + } + } + + private static void visitGroup(ParsedModel3Visitor visitor, ParsedGroupV3 group) { + visitor.visitGroup(group); + ParsedGroupInfo groupInfo = group.getGroupInfo(); + if (groupInfo != null) { + visitor.visitGroupInfo(group, groupInfo); + visitGroupKeyValues(visitor, group, groupInfo); + visitGroupDetail(visitor, group, groupInfo); + visitor.exitGroupInfo(group, groupInfo); + } + visitor.exitGroup(group); + } + + private static void visitGroupKeyValues(ParsedModel3Visitor visitor, + ParsedGroupV3 group, + ParsedGroupInfo groupInfo) { + if (groupInfo.getKeyValues() == null) return; + for (ParsedKV kv : groupInfo.getKeyValues()) { + visitor.visitGroupKeyValue(group, kv); + visitor.exitGroupKeyValue(group, kv); + } + } + + private static void visitGroupDetail(ParsedModel3Visitor visitor, + ParsedGroupV3 group, + ParsedGroupInfo groupInfo) { + if (groupInfo.getDetail() == null) return; + visitor.visitGroupDetail(group, groupInfo.getDetail()); + if (groupInfo.getDetail().getUrlConfig() != null) { + visitor.visitGroupDetailUrl(group, groupInfo.getDetail().getUrlConfig()); + visitor.exitGroupDetailUrl(group, groupInfo.getDetail().getUrlConfig()); + } + visitor.exitGroupDetail(group, groupInfo.getDetail()); + } + + private static void visitButton(ParsedModel3Visitor visitor, + ParsedButtonV3 button) { + visitor.visitButton(button); + if (button.getUrlConfig() != null) { + visitor.visitButtonUrlConfig(button, button.getUrlConfig()); + visitor.exitButtonUrlConfig(button, button.getUrlConfig()); + } + visitor.exitButton(button); + } + +} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/TodoModelV3.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/TodoModelV3.java deleted file mode 100644 index c093985c..00000000 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/TodoModelV3.java +++ /dev/null @@ -1,42 +0,0 @@ -package cn.axzo.msg.center.service.pending.response.v3; - -import cn.axzo.msg.center.service.enums.GroupType; -import lombok.Getter; -import lombok.Setter; - -import java.util.Collections; -import java.util.List; - -import static java.util.stream.Collectors.toList; - -/** - * @author yanglin - */ -@Setter -@Getter -public class TodoModelV3 { - - /** - * 分组 - */ - private List groups; - /** - * 按钮 - */ - private List buttons; - - public List getGroups(GroupType type) { - return determineGroups().stream() - .filter(group -> group.getGroupType() == type) - .collect(toList()); - } - - public List determineGroups() { - return groups == null ? Collections.emptyList() : groups; - } - - public List determineButtons() { - return buttons == null ? Collections.emptyList() : buttons; - } - -} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ComponentWorkerGroup.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ComponentWorkerGroup.java new file mode 100644 index 00000000..7d1c33e7 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ComponentWorkerGroup.java @@ -0,0 +1,14 @@ +package cn.axzo.msg.center.service.pending.response.v3.model; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * @author yanglin + */ +@Getter +@RequiredArgsConstructor +public class ComponentWorkerGroup { + private final ParsedGroupV3 group; + private final Long personId; +} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/TodoButtonV3.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedButtonV3.java similarity index 75% rename from msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/TodoButtonV3.java rename to msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedButtonV3.java index 3809e987..cde75152 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/TodoButtonV3.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedButtonV3.java @@ -1,19 +1,24 @@ -package cn.axzo.msg.center.service.pending.response.v3; +package cn.axzo.msg.center.service.pending.response.v3.model; import cn.axzo.msg.center.service.domain.UrlConfig; +import cn.axzo.msg.center.service.enums.ButtonStyleEnum; import cn.axzo.msg.center.service.enums.PresetButtonType; import cn.axzo.msg.center.service.enums.RouterButtonSourceEnum; import cn.axzo.msg.center.service.enums.RouterCategoryEnum; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import lombok.Getter; import lombok.Setter; +import java.util.Collections; +import java.util.List; + /** * @author yanglin */ @Setter @Getter -public class TodoButtonV3 { +public class ParsedButtonV3 { private Long id; @@ -72,4 +77,8 @@ public class TodoButtonV3 { */ private Integer priority; + public List parseStyle() { + if (style == null) return Collections.emptyList(); + return JSON.parseArray(style.toJSONString(), ButtonStyleEnum.class); + } } \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedGroupInfo.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedGroupInfo.java new file mode 100644 index 00000000..3187a4c0 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedGroupInfo.java @@ -0,0 +1,30 @@ +package cn.axzo.msg.center.service.pending.response.v3.model; + +import cn.axzo.msg.center.service.domain.DetailConfig; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +/** + * @author yanglin + */ +@Setter +@Getter +public class ParsedGroupInfo { + + /** + * key/value的列表 + */ + private List keyValues; + + /** + * 详情的配置 + */ + private DetailConfig detail; + + public void removeEmptyValues() { + if (keyValues == null) return; + keyValues.removeIf(ParsedKV::isValueEmpty); + } +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/TodoGroupV3.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedGroupV3.java similarity index 62% rename from msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/TodoGroupV3.java rename to msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedGroupV3.java index 80e49406..c2da3744 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/TodoGroupV3.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedGroupV3.java @@ -1,16 +1,19 @@ -package cn.axzo.msg.center.service.pending.response.v3; +package cn.axzo.msg.center.service.pending.response.v3.model; -import cn.axzo.msg.center.service.domain.GroupConfig; import cn.axzo.msg.center.service.enums.GroupType; import lombok.Getter; import lombok.Setter; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; /** * @author yanglin */ @Setter @Getter -public class TodoGroupV3 { +public class ParsedGroupV3 { private Long id; @@ -29,7 +32,7 @@ public class TodoGroupV3 { /** * 分组信息. groupType=KV_VALUES读这个信息 */ - private GroupConfig groupInfo; + private ParsedGroupInfo groupInfo; /** * 工人卡片信息. groupType=COMPONENT_WORKER读这个信息 @@ -38,4 +41,8 @@ public class TodoGroupV3 { */ private WorkerInfo workerInfo; + @NotNull + public List getKeyValues() { + return groupInfo == null ? Collections.emptyList() : groupInfo.getKeyValues(); + } } \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedKV.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedKV.java new file mode 100644 index 00000000..6ac88291 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedKV.java @@ -0,0 +1,54 @@ +package cn.axzo.msg.center.service.pending.response.v3.model; + +import cn.axzo.msg.center.service.enums.KVContentType; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; + +/** + * @author yanglin + */ +@Setter +@Getter +public class ParsedKV { + + /** + * 内容的类型. TEXT: 文本, PHONE: 手机号, ATTACHMENT: 附件, PERSON_ID: 自然人ID + */ + private KVContentType contentType; + + /** + * 键: 项目 + */ + private String key; + + /** + * 值 + */ + private String value; + + /** + * 是否显示在卡片上 + */ + private boolean displayOnCard; + + public boolean isValueEmpty() { + return StringUtils.isBlank(value) || "null".equalsIgnoreCase(value); + } + + public Long getValueAsLong() { + if (isValueEmpty()) + return null; + if (!NumberUtils.isDigits(value)) + return null; + return Long.parseLong(value); + } + + // !! 额外信息 + + /** + * contentType=PERSON_ID时的人员信息, 由yoke填充 + */ + private PersonInfo personInfo; +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedModelV3.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedModelV3.java new file mode 100644 index 00000000..743a32a3 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedModelV3.java @@ -0,0 +1,78 @@ +package cn.axzo.msg.center.service.pending.response.v3.model; + +import cn.axzo.msg.center.service.enums.GroupType; +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.Collections; +import java.util.List; + +import static java.util.stream.Collectors.toList; + +/** + * @author yanglin + */ +@Setter +@Getter +public class ParsedModelV3 { + + /** + * 模板. 对前端来说没用 + */ + @JsonIgnore @JSONField(serialize = false) + private ParsedTemplateV3 template; + /** + * 分组 + */ + private List groups; + + /** + * 按钮 + */ + private List buttons; + + /** + * 前端忽略 + */ + @JsonIgnore @JSONField(serialize = false) + private List personKeyValues = new ArrayList<>(); + + /** + * 前端忽略 + */ + @JsonIgnore @JSONField(serialize = false) + private List componentWorkerGroups = new ArrayList<>(); + + public void addPersonKV(ParsedKV kv) { + personKeyValues.add(kv); + } + + public void addComponentWorkerGroup(ComponentWorkerGroup group) { + componentWorkerGroups.add(group); + } + + public List getGroups(GroupType type) { + return determineGroups().stream() + .filter(group -> group.getGroupType() == type) + .collect(toList()); + } + + public List determineGroups() { + return groups == null ? Collections.emptyList() : groups; + } + + public List determineButtons() { + return buttons == null ? Collections.emptyList() : buttons; + } + + public void removeEmptyKVGroups() { + groups.removeIf(g -> { + boolean isKVGroup = g.getGroupType() == GroupType.KV_VALUES; + return isKVGroup && g.getKeyValues().isEmpty(); + }); + } + +} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedTemplateV3.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedTemplateV3.java new file mode 100644 index 00000000..f90facd7 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedTemplateV3.java @@ -0,0 +1,93 @@ +package cn.axzo.msg.center.service.pending.response.v3.model; + +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.StatusEnum; +import cn.axzo.msg.center.service.enums.YesOrNo; +import com.alibaba.fastjson.JSONObject; +import lombok.Getter; +import lombok.Setter; + +/** + * @author yanglin + */ +@Setter +@Getter +public class ParsedTemplateV3 { + /** + * 模板名称 + */ + private String name; + + /** + * 系统自动生成的模板code + */ + private String code; + + /** + * 所属消息类型 + */ + private MessageCategoryEnum msgCategory; + + /** + * 模板标题 + */ + private String title; + + /** + * 模板类容 + */ + private String content; + + /** + * 消息详情样式. BIZ_COMMON: 业务待办能用, FLOW_COMMON: 审批待办能用, 其它动态配置的 + */ + private String detailStyleCode; + + /** + * 模板icon + */ + private String icon; + + /** + * APP最小版本支持,可不配 + */ + private String minAppVersion; + + /** + * 模板状态 + */ + private StatusEnum status; + + /** + * 推送终端配置 JSON字串 + */ + private String pushTerminal; + + /** + * 卡片跳转方式. NONE: 无跳转, OPEN_TODO_DETAIL: 打开待办详情, OPEN_CUSTOM_PAGE: 打开指定页面 + */ + private CardUrlOpenStrategy cardUrlOpenStrategy; + + /** + * 卡片跳转配置. 在links的基础上再包一层, 避免以后卡片增加自己的配置 + */ + private CardUrlConfig cardUrlConfig; + + /** + * IM发送优先级 + */ + private Integer imSendPriority; + + /** + * push配置 + */ + private JSONObject pushData; + + /** + * 是否显示在列表中. YES: 是, NO: 否 + */ + private YesOrNo displayOnList; + +} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/PersonInfo.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/PersonInfo.java new file mode 100644 index 00000000..d4390af4 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/PersonInfo.java @@ -0,0 +1,33 @@ +package cn.axzo.msg.center.service.pending.response.v3.model; + +import cn.axzo.trade.datasecurity.sd.extension.annotation.SDCellPhoneField; +import lombok.Getter; +import lombok.Setter; + +/** + * @author yanglin + */ +@Setter +@Getter +public class PersonInfo { + /** + * 用户姓名 + */ + private String realName; + + /** + * 用户头像 + */ + private String avatar; + + /** + * 手机号, 未加密 + */ + @SDCellPhoneField + private String mobilePhone; + + /** + * 加密手机号 + */ + private String mobilePhoneCiphertext; +} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/WorkerInfo.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/WorkerInfo.java similarity index 94% rename from msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/WorkerInfo.java rename to msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/WorkerInfo.java index 14d8b989..256cdf98 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/WorkerInfo.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/WorkerInfo.java @@ -1,4 +1,4 @@ -package cn.axzo.msg.center.service.pending.response.v3; +package cn.axzo.msg.center.service.pending.response.v3.model; import cn.axzo.trade.datasecurity.sd.extension.annotation.SDCellPhoneField; import cn.axzo.trade.datasecurity.sd.extension.annotation.SDIdCardField; diff --git a/start/src/main/java/cn/axzo/msg/center/MsgCenterApplication.java b/start/src/main/java/cn/axzo/msg/center/MsgCenterApplication.java index f433d020..7045ae72 100644 --- a/start/src/main/java/cn/axzo/msg/center/MsgCenterApplication.java +++ b/start/src/main/java/cn/axzo/msg/center/MsgCenterApplication.java @@ -25,7 +25,8 @@ import org.springframework.core.env.Environment; "cn.axzo.pluto.api", "cn.axzo.basics.profiles.api", "cn.axzo.apollo.api", - "cn.axzo.msg.center.inside.notices.service.impl" + "cn.axzo.msg.center.inside.notices.service.impl", + "cn.axzo.meepo.api" }) /*@EnableAsync*/ public class MsgCenterApplication { diff --git a/start/src/test/java/cn/axzo/msg/center/message/service/youmeng/YoumengTemplateClientTest.java b/start/src/test/java/cn/axzo/msg/center/message/service/youmeng/YoumengTemplateClientTest.java deleted file mode 100644 index 9b334f2f..00000000 --- a/start/src/test/java/cn/axzo/msg/center/message/service/youmeng/YoumengTemplateClientTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.axzo.msg.center.message.service.youmeng; - -import cn.axzo.msg.center.MsgCenterApplication; -import cn.axzo.msg.center.service.enums.TerminalTypeEnum; -import com.google.common.util.concurrent.Uninterruptibles; -import lombok.RequiredArgsConstructor; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.Collections; -import java.util.concurrent.TimeUnit; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * @author yanglin - */ -@SpringBootTest(classes = MsgCenterApplication.class) -@RequiredArgsConstructor(onConstructor_ = @Autowired) -class YoumengTemplateClientTest { - - private final YoumengTemplateClient youmengTemplateClient; - - @Test - void foo() { - YoumengPush push = new YoumengPush(); - push.setTitle("aaa"); - push.setContent("bbb"); - push.setReceiverOuId(3L); - push.setReceiverPersonId(444L); - YoumengPush.PushNavigation navigation = new YoumengPush.PushNavigation(); - navigation.setUrl("test_url"); - navigation.setPlatform(TerminalTypeEnum.ANDROID); - push.setNavigations(Collections.singletonList(navigation)); - youmengTemplateClient.syncSend(590L, Collections.singletonList(push)); - Uninterruptibles.sleepUninterruptibly(1, TimeUnit.MINUTES); - } - -} \ No newline at end of file