REQ-3046: backup

This commit is contained in:
yanglin 2024-10-16 18:16:34 +08:00
parent 8744cd20c5
commit 00b9c6728c
28 changed files with 561 additions and 216 deletions

View File

@ -153,6 +153,10 @@
<groupId>cn.axzo.im.center</groupId>
<artifactId>im-center-api</artifactId>
</dependency>
<dependency>
<groupId>cn.axzo.meepo</groupId>
<artifactId>meepo-api</artifactId>
</dependency>
<dependency>
<groupId>cn.axzo.basics</groupId>
<artifactId>basics-profiles-api</artifactId>

View File

@ -18,6 +18,7 @@ import cn.axzo.msg.center.service.pending.request.CompletePendingMessageRequest;
import cn.axzo.msg.center.service.pending.request.GetPendingTodosRequest;
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;
@ -158,6 +159,11 @@ public class PendingMessageNewController implements PendingMessageClient {
return CommonResponse.success(response);
}
@Override
public CommonResponse<PendingMessageResponse> detailV3(PendingMessageDetailRequestV3 requestV3) {
return CommonResponse.success();
}
@Override
public CommonResponse<PendingMessageResponse> getLatestTodoByBiz(
String templateCode, String bizCode, String subBizCode, String todoType) {

View File

@ -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<ParsedKV> personKeyValues = new ArrayList<>();
List<ComponentWorkerGroup> componentWorkerGroups = new ArrayList<>();
for (ParsedModelV3 model : models) {
personKeyValues.addAll(model.getPersonKeyValues());
componentWorkerGroups.addAll(model.getComponentWorkerGroups());
}
populatePersonKV(personKeyValues);
populateComponentWorkGroup(componentWorkerGroups);
}
private void populatePersonKV(List<ParsedKV> keyValues) {
if (CollectionUtils.isEmpty(keyValues)) return;
List<Long> personIds = keyValues.stream()
.map(ParsedKV::getValueAsLong)
.filter(Objects::nonNull)
.distinct()
.collect(toList());
Map<Long, PersonProfileDto> 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<ComponentWorkerGroup> groups) {
if (CollectionUtils.isEmpty(groups)) return;
List<Long> personIds = groups.stream()
.map(ComponentWorkerGroup::getPersonId)
.distinct()
.collect(toList());
Map<Long, WorkerProfileDto> personId2WorkerProfile = BizAssertions.assertResponse(
userProfileServiceApi.postWorkerProfileList(personIds)).stream()
.collect(toMap(workerProfileDto -> workerProfileDto.getPersonProfile().getId(), identity()));
Map<Long, List<WorkerBankCardRes>> 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<WorkerBankCardRes> 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()));
}
}

View File

@ -1,31 +1,37 @@
package cn.axzo.msg.center.message.service.impl.v3.model;
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.GroupConfig;
import cn.axzo.msg.center.service.domain.KVConfig;
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.pending.response.v3.ParsedButtonV3;
import cn.axzo.msg.center.service.pending.response.v3.ParsedGroupV3;
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.ParsedModelV3;
import cn.axzo.msg.center.service.pending.response.v3.ParsedTemplateV3;
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;
@ -38,6 +44,8 @@ import static cn.axzo.msg.center.common.utils.PlaceholderResolver.getDefaultReso
@RequiredArgsConstructor
public class ModelV3Parser {
private static final String CUSTOMER_PERSON_ID = "customerPersonId";
private final PendingMessageBizConfig cfg;
public ParsedModelV3 parseModel(ModelV3 model,
@ -46,7 +54,7 @@ public class ModelV3Parser {
JSONObject routerParam) {
ParsedModelV3 parsedModel = new ParsedModelV3();
parsedModel.setTemplate(BeanMapper.copyBean(model, ParsedTemplateV3.class));
parsedModel.setGroups(BeanMapper.copyList(model.getGroups(), ParsedGroupV3.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() {
@ -57,12 +65,26 @@ public class ModelV3Parser {
}
@Override
public void visitGroupKeyValue(ParsedGroupV3 group, KVConfig kv) {
kv.setValue(getDefaultResolver().resolveByMap(kv.getValue(), bizParam));
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 exitGroupInfo(ParsedGroupV3 group, GroupConfig groupInfo) {
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();
}
@ -90,6 +112,11 @@ public class ModelV3Parser {
return parsedModel;
}
private List<ParsedGroupV3> copyGroups(List<MessageTemplateGroupV3> groups) {
String jsonArray = JSON.toJSONString(groups);
return JSON.parseList(jsonArray, ParsedGroupV3.class);
}
public UrlConfig parseUrlConfig(UrlConfig urlConfig,
MessageEntity entity,
JSONObject routerParam) {
@ -100,13 +127,14 @@ public class ModelV3Parser {
}
@RequiredArgsConstructor
private class UrlParser {
private class UrlParser implements UrlConfigVisitor {
final MessageEntity entity;
final JSONObject routerParam;
void parseUrlConfig(UrlConfig urlConfig) {
UrlConfigWalker.walkDown(urlConfig, new UrlConfigVisitor() {
UrlConfigWalker.walkDown(urlConfig, this);
}
@Override
public void visitPcOms(WebUrl pcOms) {
@ -143,9 +171,6 @@ public class ModelV3Parser {
android.setUrl(parseUrl(android.getUrl()));
}
});
}
String parseUrl(String url) {
if (StringUtils.isBlank(url))
return url;

View File

@ -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;

View File

@ -16,7 +16,7 @@ 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.param.PendingMessagePushParam;
import cn.axzo.msg.center.message.service.impl.v3.model.ModelV3Service;
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;

View File

@ -5,7 +5,7 @@ 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.service.impl.v3.model.ModelV3Parser;
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;

View File

@ -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;
/**
* <a href="https://docs.dingtalk.com/i/nodes/14lgGw3P8v9Yk4yaF0aAo9NbJ5daZ90D">REQ-3045</a>
*
@ -47,10 +42,6 @@ public class UrlConfig {
*/
private MobileUrlConfig appManager;
public List<TerminalUrl> parse(AppTerminalTypeEnum appType) {
return new TerminalUrlParser(this, appType).parse();
}
@JsonIgnore @JSONField(serialize = false)
public WebUrl getOrCreatePcOms() {
if (pcOms == null)

View File

@ -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<TerminalUrl> parse() {
ArrayList<TerminalUrl> 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<TerminalUrl> 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<TerminalUrl> selectApp(
AppTerminalTypeEnum selectType, MobileUrlConfig mobileUrl) {
if (requestType != selectType)
return Collections.emptyList();
if (mobileUrl == null)
return Collections.emptyList();
ArrayList<TerminalUrl> 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;
}
}

View File

@ -9,6 +9,7 @@ import cn.axzo.msg.center.service.pending.request.CompletePendingMessageRequest;
import cn.axzo.msg.center.service.pending.request.GetPendingTodosRequest;
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;
@ -159,12 +160,18 @@ public interface PendingMessageClient {
* @param terminalType APP终端类型
* @return 代办详情
*/
@Deprecated
@PostMapping(value = "/pending-message/record/detail", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<PendingMessageResponse> 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<PendingMessageResponse> detailV3(
@RequestBody @Valid PendingMessageDetailRequestV3 requestV3);
/**
* 根据bizCode查询待办详情
*

View File

@ -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;

View File

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

View File

@ -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: 未发送

View File

@ -3,7 +3,6 @@ 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.KVConfig;
import cn.axzo.msg.center.service.dto.ButtonRouterDTO;
import cn.axzo.msg.center.service.dto.DetailRouterDTO;
import cn.axzo.msg.center.service.dto.IdentityDTO;
@ -15,13 +14,12 @@ 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.ParsedButtonV3;
import cn.axzo.msg.center.service.pending.response.v3.ParsedGroupV3;
import cn.axzo.msg.center.service.pending.response.v3.ParsedModel3Visitor;
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.ParsedModelV3;
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;
@ -271,24 +269,13 @@ public class PendingMessageResponse implements Serializable, TodoButtonProvider
*/
private CardUrlConfig cardUrlConfig;
public void populatePreviousModelProps(AppTerminalTypeEnum appType) {
public void populateV2Props(TerminalTypeEnum terminalTypeInRequest,
AppTerminalTypeEnum appTypeInRequest) {
if (modelV3 == null) return;
cardItems = new ArrayList<>();
buttonRouters = new ArrayList<>();
ParsedModel3Walker.walkDown(modelV3, new ParsedModel3Visitor() {
@Override
public void visitGroupKeyValue(ParsedGroupV3 group, KVConfig kv) {
MessageCardContentItemDTO cardItem = new MessageCardContentItemDTO();
cardItem.setLabel(kv.getKey());
cardItem.setValue(kv.getValue());
cardItems.add(cardItem);
}
@Override
public void visitButton(ParsedButtonV3 button) {
buttonRouters.add(new ButtonRouterDTO());
}
});
ParsedModel3Walker.walkDown(modelV3, new ModelV2PropsPopulator(
this, terminalTypeInRequest, appTypeInRequest));
}
public void adjustProposedButtons(boolean forPromoter) {

View File

@ -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<ButtonRouterDTO> 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<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;
}
}

View File

@ -1,9 +1,13 @@
package cn.axzo.msg.center.service.pending.response.v3;
import cn.axzo.msg.center.service.domain.DetailConfig;
import cn.axzo.msg.center.service.domain.GroupConfig;
import cn.axzo.msg.center.service.domain.KVConfig;
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
@ -26,13 +30,13 @@ public interface ParsedModel3Visitor {
default void exitGroup(ParsedGroupV3 group) {}
default void visitGroupInfo(ParsedGroupV3 group, GroupConfig groupInfo) {}
default void visitGroupInfo(ParsedGroupV3 group, ParsedGroupInfo groupInfo) {}
default void exitGroupInfo(ParsedGroupV3 group, GroupConfig groupInfo) {}
default void exitGroupInfo(ParsedGroupV3 group, ParsedGroupInfo groupInfo) {}
default void visitGroupKeyValue(ParsedGroupV3 group, KVConfig kv) {}
default void visitGroupKeyValue(ParsedGroupV3 group, ParsedKV kv) {}
default void exitGroupKeyValue(ParsedGroupV3 group, KVConfig kv) {}
default void exitGroupKeyValue(ParsedGroupV3 group, ParsedKV kv) {}
default void visitGroupDetail(ParsedGroupV3 group, DetailConfig detailConfig) {}

View File

@ -1,8 +1,12 @@
package cn.axzo.msg.center.service.pending.response.v3;
import cn.axzo.msg.center.service.domain.CardUrlConfig;
import cn.axzo.msg.center.service.domain.GroupConfig;
import cn.axzo.msg.center.service.domain.KVConfig;
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
@ -34,7 +38,7 @@ public class ParsedModel3Walker {
private static void visitGroup(ParsedModel3Visitor visitor, ParsedGroupV3 group) {
visitor.visitGroup(group);
GroupConfig groupInfo = group.getGroupInfo();
ParsedGroupInfo groupInfo = group.getGroupInfo();
if (groupInfo != null) {
visitor.visitGroupInfo(group, groupInfo);
visitGroupKeyValues(visitor, group, groupInfo);
@ -46,9 +50,9 @@ public class ParsedModel3Walker {
private static void visitGroupKeyValues(ParsedModel3Visitor visitor,
ParsedGroupV3 group,
GroupConfig groupInfo) {
ParsedGroupInfo groupInfo) {
if (groupInfo.getKeyValues() == null) return;
for (KVConfig kv : groupInfo.getKeyValues()) {
for (ParsedKV kv : groupInfo.getKeyValues()) {
visitor.visitGroupKeyValue(group, kv);
visitor.exitGroupKeyValue(group, kv);
}
@ -56,7 +60,7 @@ public class ParsedModel3Walker {
private static void visitGroupDetail(ParsedModel3Visitor visitor,
ParsedGroupV3 group,
GroupConfig groupInfo) {
ParsedGroupInfo groupInfo) {
if (groupInfo.getDetail() == null) return;
visitor.visitGroupDetail(group, groupInfo.getDetail());
if (groupInfo.getDetail().getUrlConfig() != null) {

View File

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

View File

@ -1,13 +1,18 @@
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
*/
@ -72,4 +77,8 @@ public class ParsedButtonV3 {
*/
private Integer priority;
public List<ButtonStyleEnum> parseStyle() {
if (style == null) return Collections.emptyList();
return JSON.parseArray(style.toJSONString(), ButtonStyleEnum.class);
}
}

View File

@ -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<ParsedKV> keyValues;
/**
* 详情的配置
*/
private DetailConfig detail;
public void removeEmptyValues() {
if (keyValues == null) return;
keyValues.removeIf(ParsedKV::isValueEmpty);
}
}

View File

@ -1,7 +1,5 @@
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.domain.KVConfig;
import cn.axzo.msg.center.service.enums.GroupType;
import lombok.Getter;
import lombok.Setter;
@ -34,7 +32,7 @@ public class ParsedGroupV3 {
/**
* 分组信息. groupType=KV_VALUES读这个信息
*/
private GroupConfig groupInfo;
private ParsedGroupInfo groupInfo;
/**
* 工人卡片信息. groupType=COMPONENT_WORKER读这个信息
@ -44,7 +42,7 @@ public class ParsedGroupV3 {
private WorkerInfo workerInfo;
@NotNull
public List<KVConfig> getKeyValues() {
public List<ParsedKV> getKeyValues() {
return groupInfo == null ? Collections.emptyList() : groupInfo.getKeyValues();
}
}

View File

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

View File

@ -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.msg.center.service.enums.GroupType;
import com.alibaba.fastjson.annotation.JSONField;
@ -6,6 +6,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -21,7 +22,8 @@ public class ParsedModelV3 {
/**
* 模板. 对前端来说没用
*/
@JsonIgnore @JSONField(serialize = false) private ParsedTemplateV3 template;
@JsonIgnore @JSONField(serialize = false)
private ParsedTemplateV3 template;
/**
* 分组
*/
@ -32,6 +34,26 @@ public class ParsedModelV3 {
*/
private List<ParsedButtonV3> buttons;
/**
* 前端忽略
*/
@JsonIgnore @JSONField(serialize = false)
private List<ParsedKV> personKeyValues = new ArrayList<>();
/**
* 前端忽略
*/
@JsonIgnore @JSONField(serialize = false)
private List<ComponentWorkerGroup> componentWorkerGroups = new ArrayList<>();
public void addPersonKV(ParsedKV kv) {
personKeyValues.add(kv);
}
public void addComponentWorkerGroup(ComponentWorkerGroup group) {
componentWorkerGroups.add(group);
}
public List<ParsedGroupV3> getGroups(GroupType type) {
return determineGroups().stream()
.filter(group -> group.getGroupType() == type)

View File

@ -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.msg.center.service.domain.CardUrlConfig;
import cn.axzo.msg.center.service.enums.CardUrlOpenStrategy;

View File

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

View File

@ -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;

View File

@ -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 {

View File

@ -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);
}
}