Merge remote-tracking branch 'origin/master' into feature/REQ-3488
This commit is contained in:
commit
b1f07dd3a1
@ -173,6 +173,15 @@ public class PendingMessageBizConfig {
|
|||||||
@Getter
|
@Getter
|
||||||
private int todoTitleSearchMaxSize = 5000;
|
private int todoTitleSearchMaxSize = 5000;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private boolean requestReplayWindowEnabled = true;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private long requestReplayWindowExpireTimeInSeconds = 3600L;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Set<String> requestReplayWhitelistTemplateCodes = new HashSet<>();
|
||||||
|
|
||||||
public boolean determineOldMsgStatCacheOn() {
|
public boolean determineOldMsgStatCacheOn() {
|
||||||
return isOldMsgStatCacheOn();
|
return isOldMsgStatCacheOn();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import cn.axzo.msg.center.service.pending.request.CompletePendingBySubCodeReques
|
|||||||
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByCodesRequest;
|
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByCodesRequest;
|
||||||
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByIdRequest;
|
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByIdRequest;
|
||||||
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageRequest;
|
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageRequest;
|
||||||
|
import cn.axzo.msg.center.service.pending.request.FetchTodoByBizRequest;
|
||||||
import cn.axzo.msg.center.service.pending.request.GetPendingTodosRequest;
|
import cn.axzo.msg.center.service.pending.request.GetPendingTodosRequest;
|
||||||
import cn.axzo.msg.center.service.pending.request.GetTodoCountRequest;
|
import cn.axzo.msg.center.service.pending.request.GetTodoCountRequest;
|
||||||
import cn.axzo.msg.center.service.pending.request.GetTodoPageRequest;
|
import cn.axzo.msg.center.service.pending.request.GetTodoPageRequest;
|
||||||
@ -283,6 +284,12 @@ public class PendingMessageNewController implements PendingMessageClient {
|
|||||||
return CommonResponse.success(todoSimpleQueryService.getTodosSimple(request));
|
return CommonResponse.success(todoSimpleQueryService.getTodosSimple(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<List<PendingMessageResponse>> fetchTodosByBiz(FetchTodoByBizRequest request) {
|
||||||
|
log.info("fetchTodosByBiz, request={}", JSON.toJSONString(request));
|
||||||
|
return CommonResponse.success(todoSimpleQueryService.fetchTodosByBiz(request));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResponse<Map<BizCategoryEnum, PendingMessageCountDTO>> getTodosSimpleCount(GetTodoCountRequest request) {
|
public CommonResponse<Map<BizCategoryEnum, PendingMessageCountDTO>> getTodosSimpleCount(GetTodoCountRequest request) {
|
||||||
return CommonResponse.success(todoSimpleQueryService.getTodosSimpleCount(request));
|
return CommonResponse.success(todoSimpleQueryService.getTodosSimpleCount(request));
|
||||||
|
|||||||
@ -14,12 +14,10 @@ import cn.axzo.msg.center.service.enums.OrganizationTypeEnum;
|
|||||||
import cn.axzo.msg.center.service.enums.PendingMessageStateEnum;
|
import cn.axzo.msg.center.service.enums.PendingMessageStateEnum;
|
||||||
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
|
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
|
||||||
import cn.axzo.msg.center.service.enums.TodoType;
|
import cn.axzo.msg.center.service.enums.TodoType;
|
||||||
import cn.axzo.msg.center.service.pending.ClientRequest;
|
|
||||||
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
|
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
|
||||||
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedModelV3;
|
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedModelV3;
|
||||||
import cn.axzo.msg.center.service.template.response.MessageDetailStyle;
|
import cn.axzo.msg.center.service.template.response.MessageDetailStyle;
|
||||||
import cn.axzo.msg.center.utils.DateFormatUtil;
|
import cn.axzo.msg.center.utils.DateFormatUtil;
|
||||||
import cn.hutool.core.date.DateUtil;
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
@ -33,7 +31,6 @@ import java.io.Serializable;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description
|
* @description
|
||||||
@ -285,64 +282,6 @@ public class PendingMessageDTO implements Serializable {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PendingMessageResponse toResponse(ClientRequest request) {
|
|
||||||
boolean isCreatedToday = false;
|
|
||||||
if (createTime != null) {
|
|
||||||
Date createAt = DateFormatUtil.toDate(createTime);
|
|
||||||
isCreatedToday = DateUtil.isSameDay(createAt, new Date());
|
|
||||||
}
|
|
||||||
return PendingMessageResponse.builder()
|
|
||||||
// 发起人单位、项目信息
|
|
||||||
.promoterOuId(promoterOuId)
|
|
||||||
.promoterWorkspaceId(promoterWorkspaceId)
|
|
||||||
.promoterWorkspaceName(promoterWorkspaceName)
|
|
||||||
.promoterWorkspaceType(promoterWorkspaceType)
|
|
||||||
// 接收者单位、项目信息
|
|
||||||
.executorOuId(executorOuId)
|
|
||||||
.executorWorkspaceId(executorWorkspaceId)
|
|
||||||
.executorWorkspaceName(executorWorkspaceName)
|
|
||||||
.executorWorkspaceType(executorWorkspaceType)
|
|
||||||
// 其它信息
|
|
||||||
.bizExtParamObj(bizExtParamObj)
|
|
||||||
.routerExtParamObj(routerExtParamObj)
|
|
||||||
//页面展示
|
|
||||||
.ouId(this.ouId)
|
|
||||||
.workspaceId(workspaceId)
|
|
||||||
.workspaceName(workspaceName)
|
|
||||||
// 样式
|
|
||||||
.detailStyle(detailStyle)
|
|
||||||
.isCreatedToday(isCreatedToday)
|
|
||||||
.isRead(isRead)
|
|
||||||
.todoType(todoType)
|
|
||||||
.proposedButtons(proposedButtons)
|
|
||||||
.templateCategory(templateCategory)
|
|
||||||
.identityCode(this.identityCode)
|
|
||||||
.templateCode(this.templateCode)
|
|
||||||
.title(this.title)
|
|
||||||
.content(this.content)
|
|
||||||
.promoterPersonId(Optional.ofNullable(this.promoter).map(PersonDTO::getId).orElse(null))
|
|
||||||
.promoterName(Optional.ofNullable(this.promoter).map(PersonDTO::getName).orElse(null))
|
|
||||||
.promoterIdentity(Optional.ofNullable(this.promoter).map(PersonDTO::getIdentity).orElse(null))
|
|
||||||
.executorPersonId(Optional.ofNullable(this.executor).map(PersonDTO::getId).orElse(null))
|
|
||||||
.executorName(Optional.ofNullable(this.executor).map(PersonDTO::getName).orElse(null))
|
|
||||||
.executorIdentity(Optional.ofNullable(this.executor).map(PersonDTO::getIdentity).orElse(null))
|
|
||||||
.bizCode(this.bizCode)
|
|
||||||
.subBizCode(this.subBizCode)
|
|
||||||
.bizDesc(this.bizDesc)
|
|
||||||
.bizFlag(this.bizFlag)
|
|
||||||
.state(this.getState())
|
|
||||||
.bizCategory(this.bizCategory)
|
|
||||||
.createTimestamp(DateFormatUtil.toTimestamp(this.createTime))
|
|
||||||
.updateTimestamp(DateFormatUtil.toTimestamp(this.updateTime))
|
|
||||||
.deadlineTimestamp(DateFormatUtil.toTimestamp(this.deadline))
|
|
||||||
.bizFinalStateIcon(Optional.ofNullable(bizFinalState).map(BizFinalStateEnum::getIcon).orElse(null))
|
|
||||||
.bizFinalState(bizFinalState)
|
|
||||||
.modelV3(modelV3)
|
|
||||||
.displayOnCardKeyValues(modelV3.determineDisplayOnCardKeyValues())
|
|
||||||
.cardUrlOpenStrategy(cardUrlOpenStrategy)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return JSON.toJSONString(this);
|
return JSON.toJSONString(this);
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import cn.axzo.msg.center.common.utils.MiscUtils;
|
|||||||
import cn.axzo.msg.center.dal.CardDao;
|
import cn.axzo.msg.center.dal.CardDao;
|
||||||
import cn.axzo.msg.center.domain.entity.Card;
|
import cn.axzo.msg.center.domain.entity.Card;
|
||||||
import cn.axzo.msg.center.domain.entity.MessageTemplateButtonV3;
|
import cn.axzo.msg.center.domain.entity.MessageTemplateButtonV3;
|
||||||
|
import cn.axzo.msg.center.domain.enums.RequestReplayType;
|
||||||
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
|
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
|
||||||
import cn.axzo.msg.center.message.domain.vo.GeneralMessagePushVO;
|
import cn.axzo.msg.center.message.domain.vo.GeneralMessagePushVO;
|
||||||
import cn.axzo.msg.center.message.service.card.broadcast.CardBroadcaster;
|
import cn.axzo.msg.center.message.service.card.broadcast.CardBroadcaster;
|
||||||
@ -18,6 +19,8 @@ import cn.axzo.msg.center.message.service.card.domain.CardGroup;
|
|||||||
import cn.axzo.msg.center.message.service.card.domain.CardSendModel;
|
import cn.axzo.msg.center.message.service.card.domain.CardSendModel;
|
||||||
import cn.axzo.msg.center.message.service.card.log.CardLogger;
|
import cn.axzo.msg.center.message.service.card.log.CardLogger;
|
||||||
import cn.axzo.msg.center.message.service.card.log.CardLoggers;
|
import cn.axzo.msg.center.message.service.card.log.CardLoggers;
|
||||||
|
import cn.axzo.msg.center.message.service.replay.RequestInfo;
|
||||||
|
import cn.axzo.msg.center.message.service.replay.RequestReplayService;
|
||||||
import cn.axzo.msg.center.nimpush.device.PushDeviceService;
|
import cn.axzo.msg.center.nimpush.device.PushDeviceService;
|
||||||
import cn.axzo.msg.center.nimpush.device.PushDeviceSnapshots;
|
import cn.axzo.msg.center.nimpush.device.PushDeviceSnapshots;
|
||||||
import cn.axzo.msg.center.service.ButtonV3;
|
import cn.axzo.msg.center.service.ButtonV3;
|
||||||
@ -69,6 +72,7 @@ public class CardManager {
|
|||||||
private final CardParser cardParser;
|
private final CardParser cardParser;
|
||||||
private final CardBroadcaster cardBroadcaster;
|
private final CardBroadcaster cardBroadcaster;
|
||||||
private final CardProps cardProps;
|
private final CardProps cardProps;
|
||||||
|
private final RequestReplayService requestReplayService;
|
||||||
private final ExecutorService executor = new ThreadPoolExecutor(
|
private final ExecutorService executor = new ThreadPoolExecutor(
|
||||||
5, 15,
|
5, 15,
|
||||||
5L, TimeUnit.MINUTES,
|
5L, TimeUnit.MINUTES,
|
||||||
@ -78,6 +82,16 @@ public class CardManager {
|
|||||||
// 校验参数
|
// 校验参数
|
||||||
BizAssertions.assertNotNull(request.getSender(), "发送人不能为空");
|
BizAssertions.assertNotNull(request.getSender(), "发送人不能为空");
|
||||||
BizAssertions.assertNotEmpty(request.getReceivers(), "接收人不能为空");
|
BizAssertions.assertNotEmpty(request.getReceivers(), "接收人不能为空");
|
||||||
|
RequestInfo requestInfo = new RequestInfo();
|
||||||
|
requestInfo.setTemplateCode(request.getTemplateCode());
|
||||||
|
requestInfo.setBizCode(request.getBizCode());
|
||||||
|
requestInfo.setSubBizCode(request.getSubBizCode());
|
||||||
|
requestInfo.setReplayType(RequestReplayType.IM_CARD_SEND);
|
||||||
|
requestInfo.setRequest(request);
|
||||||
|
return requestReplayService.run(requestInfo, () -> sendImpl(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
private CardSendResponse sendImpl(CardSendRequest request) {
|
||||||
CardTemplate cardTemplate = cardSupport.parseCardTemplate(cardSupport
|
CardTemplate cardTemplate = cardSupport.parseCardTemplate(cardSupport
|
||||||
.ensureImChannelPresent(request.getTemplateCode()), request);
|
.ensureImChannelPresent(request.getTemplateCode()), request);
|
||||||
// 主要逻辑
|
// 主要逻辑
|
||||||
|
|||||||
@ -82,7 +82,7 @@ public class CardSupport {
|
|||||||
cardIdempotentDao.save(idempotent);
|
cardIdempotentDao.save(idempotent);
|
||||||
} catch (DuplicateKeyException e) {
|
} catch (DuplicateKeyException e) {
|
||||||
log.warn("重复创建卡片, request={}", request);
|
log.warn("重复创建卡片, request={}", request);
|
||||||
throw new ServiceException(String.format("重复创建卡片: %s", idempotent));
|
throw new ServiceException(403, String.format("重复创建卡片: %s", idempotent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -79,6 +79,7 @@ public class ModelV3Parser {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitGroupKeyValue(ParsedGroupV3 group, ParsedKV kv) {
|
public void visitGroupKeyValue(ParsedGroupV3 group, ParsedKV kv) {
|
||||||
|
kv.setValueVariable(kv.getValue());
|
||||||
kv.setValue(resolveBizParam(kv.getValue()));
|
kv.setValue(resolveBizParam(kv.getValue()));
|
||||||
|
|
||||||
if (kv.getContentType() == KVContentType.PERSON_ID
|
if (kv.getContentType() == KVContentType.PERSON_ID
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
package cn.axzo.msg.center.message.service.replay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yanglin
|
||||||
|
*/
|
||||||
|
enum RequestAcquireResult {
|
||||||
|
NEW_REQUEST,
|
||||||
|
DUPLICATE_REQUEST,
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package cn.axzo.msg.center.message.service.replay;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.domain.enums.RequestReplayType;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yanglin
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class RequestInfo {
|
||||||
|
private String templateCode;
|
||||||
|
private String bizCode;
|
||||||
|
private String subBizCode;
|
||||||
|
private RequestReplayType replayType;
|
||||||
|
private Object request;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,106 @@
|
|||||||
|
package cn.axzo.msg.center.message.service.replay;
|
||||||
|
|
||||||
|
import cn.axzo.basics.common.exception.ServiceException;
|
||||||
|
import cn.axzo.msg.center.common.utils.BizAssertions;
|
||||||
|
import cn.axzo.msg.center.common.utils.MD5;
|
||||||
|
import cn.axzo.msg.center.dal.RequestReplayDao;
|
||||||
|
import cn.axzo.msg.center.domain.entity.RequestReplay;
|
||||||
|
import cn.axzo.msg.center.inside.notices.config.PendingMessageBizConfig;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yanglin
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class RequestReplayService {
|
||||||
|
|
||||||
|
private final RequestReplayDao requestReplayDao;
|
||||||
|
private final PendingMessageBizConfig cfg;
|
||||||
|
private final RedisTemplate<String, String> redisTemplate;
|
||||||
|
|
||||||
|
public <T> T run(RequestInfo requestInfo, Supplier<T> supplier) {
|
||||||
|
if (!isWindowEnabled(requestInfo))
|
||||||
|
return supplier.get();
|
||||||
|
if (acquire(requestInfo) == RequestAcquireResult.DUPLICATE_REQUEST)
|
||||||
|
throw new ServiceException(403, "重复请求: " + requestInfo);
|
||||||
|
try {
|
||||||
|
return supplier.get();
|
||||||
|
} catch (Exception e) {
|
||||||
|
release(requestInfo);
|
||||||
|
log.warn("run request error, requestInfo={}", requestInfo, e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RequestAcquireResult acquire(RequestInfo info) {
|
||||||
|
try {
|
||||||
|
return acquireRequestImpl(info);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("acquire request error, requestInfo={}", info, e);
|
||||||
|
return RequestAcquireResult.NEW_REQUEST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void release(RequestInfo requestInfo) {
|
||||||
|
if (!isWindowEnabled(requestInfo))
|
||||||
|
return;
|
||||||
|
try {
|
||||||
|
BizAssertions.assertNotNull(requestInfo, "requestInfo is null");
|
||||||
|
redisTemplate.delete(buildKey(hash(requestInfo)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("release request error, requestInfo={}", requestInfo, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RequestAcquireResult acquireRequestImpl(RequestInfo requestInfo) {
|
||||||
|
BizAssertions.assertNotNull(requestInfo, "info is null");
|
||||||
|
BizAssertions.assertNotNull(requestInfo.getRequest(), "request is null");
|
||||||
|
String hash = hash(requestInfo);
|
||||||
|
RequestReplay replay = new RequestReplay();
|
||||||
|
replay.setTemplateCode(requestInfo.getTemplateCode());
|
||||||
|
replay.setBizCode(requestInfo.getBizCode());
|
||||||
|
String subBizCode = requestInfo.getSubBizCode();
|
||||||
|
replay.setSubBizCode(subBizCode == null ? "" : subBizCode);
|
||||||
|
replay.setType(requestInfo.getReplayType());
|
||||||
|
replay.setHash(hash);
|
||||||
|
replay.setRequest(JSON.parseObject(JSON.toJSONString(requestInfo.getRequest())));
|
||||||
|
try {
|
||||||
|
requestReplayDao.save(replay);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("save request error, requestInfo={}", requestInfo, e);
|
||||||
|
}
|
||||||
|
Duration timeout = Duration.ofSeconds(cfg.getRequestReplayWindowExpireTimeInSeconds());
|
||||||
|
Boolean success = redisTemplate.opsForValue().setIfAbsent(buildKey(hash), "", timeout);
|
||||||
|
RequestAcquireResult acquireResult = Boolean.TRUE.equals(success)
|
||||||
|
? RequestAcquireResult.NEW_REQUEST
|
||||||
|
: RequestAcquireResult.DUPLICATE_REQUEST;
|
||||||
|
if (acquireResult == RequestAcquireResult.DUPLICATE_REQUEST)
|
||||||
|
log.warn("duplicate request, requestInfo={}", requestInfo);
|
||||||
|
return acquireResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isWindowEnabled(RequestInfo requestInfo) {
|
||||||
|
return cfg.isRequestReplayWindowEnabled()
|
||||||
|
&& !cfg.getRequestReplayWhitelistTemplateCodes()
|
||||||
|
.contains(requestInfo.getTemplateCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String hash(RequestInfo requestInfo) {
|
||||||
|
String jsonString = JSON.toJSONString(requestInfo.getRequest());
|
||||||
|
return MD5.getMD5Code(jsonString);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String buildKey(String hash) {
|
||||||
|
return String.format("msg-center:request-replay:%s", hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -122,10 +122,12 @@ public class TodoRangeQueryService {
|
|||||||
if (respResult.getList() != null) {
|
if (respResult.getList() != null) {
|
||||||
ArrayList<ParsedKV> keyValues = new ArrayList<>();
|
ArrayList<ParsedKV> keyValues = new ArrayList<>();
|
||||||
for (PendingMessageResponse response : respResult.getList()) {
|
for (PendingMessageResponse response : respResult.getList()) {
|
||||||
|
if (request.isButtonDisplayOnCardAware())
|
||||||
response.determineButtonRouters()
|
response.determineButtonRouters()
|
||||||
.removeIf(btn -> !btn.determineStyles().contains(ButtonStyleEnum.OVER_CARD));
|
.removeIf(btn -> !btn.determineStyles().contains(ButtonStyleEnum.OVER_CARD));
|
||||||
if (response.getModelV3() != null) {
|
if (response.getModelV3() != null) {
|
||||||
response.getModelV3().getButtons().removeIf(btn -> {
|
response.getModelV3().getButtons().removeIf(btn -> {
|
||||||
|
if (!request.isButtonDisplayOnCardAware()) return false;
|
||||||
YesOrNo supportBatchProcess = request.getSupportBatchProcess();
|
YesOrNo supportBatchProcess = request.getSupportBatchProcess();
|
||||||
boolean notBatchProcessQuery = supportBatchProcess == null || supportBatchProcess == YesOrNo.NO;
|
boolean notBatchProcessQuery = supportBatchProcess == null || supportBatchProcess == YesOrNo.NO;
|
||||||
return notBatchProcessQuery && !btn.hasStyle(ButtonStyleEnum.OVER_CARD);
|
return notBatchProcessQuery && !btn.hasStyle(ButtonStyleEnum.OVER_CARD);
|
||||||
@ -151,6 +153,7 @@ public class TodoRangeQueryService {
|
|||||||
PendingMessagePageRequest request, List<String> templateCodes) {
|
PendingMessagePageRequest request, List<String> templateCodes) {
|
||||||
Date startingAt = DateFormatUtil.toDate(LocalDateTime.now().minusDays(90));
|
Date startingAt = DateFormatUtil.toDate(LocalDateTime.now().minusDays(90));
|
||||||
LambdaQueryWrapper<TodoBusiness> query = businessQuery(request.getTitle(), true)
|
LambdaQueryWrapper<TodoBusiness> query = businessQuery(request.getTitle(), true)
|
||||||
|
.in(CollectionUtils.isNotEmpty(request.getTemplateCodes()), TodoBusiness::getTemplateCode, request.getTemplateCodes())
|
||||||
.eq(TodoBusiness::getPromoterPersonId, request.getPersonId())
|
.eq(TodoBusiness::getPromoterPersonId, request.getPersonId())
|
||||||
.eq(TodoBusiness::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
.eq(TodoBusiness::getIsDelete, TableIsDeleteEnum.NORMAL.value)
|
||||||
.gt(TodoBusiness::getCreateAt, startingAt)
|
.gt(TodoBusiness::getCreateAt, startingAt)
|
||||||
@ -186,6 +189,7 @@ public class TodoRangeQueryService {
|
|||||||
LambdaQueryWrapper<Todo> query = todoQuery(query(Todo.class), ouInfo, ouCollector)
|
LambdaQueryWrapper<Todo> query = todoQuery(query(Todo.class), ouInfo, ouCollector)
|
||||||
// 查询的待办类型: COPIED_TO_ME, EXECUTABLE
|
// 查询的待办类型: COPIED_TO_ME, EXECUTABLE
|
||||||
.eq(Todo::getType, request.determineToDoType())
|
.eq(Todo::getType, request.determineToDoType())
|
||||||
|
.in(CollectionUtils.isNotEmpty(request.getTemplateCodes()), Todo::getTemplateCode, request.getTemplateCodes())
|
||||||
.eq(Todo::getExecutorPersonId, request.getPersonId())
|
.eq(Todo::getExecutorPersonId, request.getPersonId())
|
||||||
//判断是否支持批量过滤
|
//判断是否支持批量过滤
|
||||||
.eq(request.getSupportBatchProcess() != null, Todo::getSupportBatchProcess, request.getSupportBatchProcess())
|
.eq(request.getSupportBatchProcess() != null, Todo::getSupportBatchProcess, request.getSupportBatchProcess())
|
||||||
|
|||||||
@ -34,6 +34,7 @@ import cn.axzo.msg.center.service.pending.response.v3.model.ParsedButtonV3;
|
|||||||
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedCardUrl;
|
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedCardUrl;
|
||||||
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedGroupDetail;
|
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedGroupDetail;
|
||||||
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedGroupV3;
|
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.ParsedModelV3;
|
||||||
import cn.axzo.msg.center.service.pending.response.v3.model.SessionUrlInfo;
|
import cn.axzo.msg.center.service.pending.response.v3.model.SessionUrlInfo;
|
||||||
import cn.axzo.msg.center.service.pending.response.v3.model.SessionUrlSelector;
|
import cn.axzo.msg.center.service.pending.response.v3.model.SessionUrlSelector;
|
||||||
@ -262,7 +263,13 @@ public class TodoRespBuilder {
|
|||||||
|
|
||||||
Runnable modelV3Builder = () -> {
|
Runnable modelV3Builder = () -> {
|
||||||
response.setModelV3(parsedModel);
|
response.setModelV3(parsedModel);
|
||||||
response.setDisplayOnCardKeyValues(parsedModel.determineDisplayOnCardKeyValues());
|
List<ParsedKV> keyValues = parsedModel.collectKeyValues();
|
||||||
|
boolean isKeyValueDisplayOnCardAware = request == null || request.isKeyValueDisplayOnCardAware();
|
||||||
|
if (isKeyValueDisplayOnCardAware)
|
||||||
|
keyValues = keyValues.stream()
|
||||||
|
.filter(ParsedKV::isDisplayOnCard)
|
||||||
|
.collect(toList());
|
||||||
|
response.setDisplayOnCardKeyValues(keyValues);
|
||||||
response.setCardUrlOpenStrategy(templateModel.getTemplate().getCardUrlOpenStrategy());
|
response.setCardUrlOpenStrategy(templateModel.getTemplate().getCardUrlOpenStrategy());
|
||||||
ParsedModelV3Walker.walkDown(parsedModel, new ParsedModel3Visitor() {
|
ParsedModelV3Walker.walkDown(parsedModel, new ParsedModel3Visitor() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import cn.axzo.msg.center.service.enums.BizCategoryEnum;
|
|||||||
import cn.axzo.msg.center.service.enums.PendingMessageStateEnum;
|
import cn.axzo.msg.center.service.enums.PendingMessageStateEnum;
|
||||||
import cn.axzo.msg.center.service.enums.TodoQueryType;
|
import cn.axzo.msg.center.service.enums.TodoQueryType;
|
||||||
import cn.axzo.msg.center.service.enums.TodoType;
|
import cn.axzo.msg.center.service.enums.TodoType;
|
||||||
|
import cn.axzo.msg.center.service.pending.request.FetchTodoByBizRequest;
|
||||||
import cn.axzo.msg.center.service.pending.request.GetTodoCountRequest;
|
import cn.axzo.msg.center.service.pending.request.GetTodoCountRequest;
|
||||||
import cn.axzo.msg.center.service.pending.request.GetTodoPageRequest;
|
import cn.axzo.msg.center.service.pending.request.GetTodoPageRequest;
|
||||||
import cn.axzo.msg.center.service.pending.request.GetTodoRequest;
|
import cn.axzo.msg.center.service.pending.request.GetTodoRequest;
|
||||||
@ -26,6 +27,7 @@ import cn.axzo.msg.center.service.pending.request.PendingMessageQueryRequest;
|
|||||||
import cn.axzo.msg.center.service.pending.response.PendingMessageCountDTO;
|
import cn.axzo.msg.center.service.pending.response.PendingMessageCountDTO;
|
||||||
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
|
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
|
||||||
import cn.axzo.msg.center.service.pending.response.PendingMessageSimpleDTO;
|
import cn.axzo.msg.center.service.pending.response.PendingMessageSimpleDTO;
|
||||||
|
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedModelV3;
|
||||||
import cn.azxo.framework.common.model.Page;
|
import cn.azxo.framework.common.model.Page;
|
||||||
import cn.hutool.core.date.StopWatch;
|
import cn.hutool.core.date.StopWatch;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
@ -94,7 +96,9 @@ public class TodoSimpleQueryService {
|
|||||||
if (request.getQueryType() == TodoQueryType.SEND_BY_ME) {
|
if (request.getQueryType() == TodoQueryType.SEND_BY_ME) {
|
||||||
TodoBusiness business = todoBusinessDao.getById(todo.getTodoBusinessId());
|
TodoBusiness business = todoBusinessDao.getById(todo.getTodoBusinessId());
|
||||||
PendingRecordAdapter adapter = todoRespBuilder.buildBusinessAdapter(business);
|
PendingRecordAdapter adapter = todoRespBuilder.buildBusinessAdapter(business);
|
||||||
return todoRespBuilder.toResponse(adapter, request);
|
PendingMessageResponse response = todoRespBuilder.toResponse(adapter, request);
|
||||||
|
v3ExtPopulator.populate(response.getModelV3());
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
PendingMessageResponse response = todoRespBuilder.toResponse(todo, request);
|
PendingMessageResponse response = todoRespBuilder.toResponse(todo, request);
|
||||||
v3ExtPopulator.populate(response.getModelV3());
|
v3ExtPopulator.populate(response.getModelV3());
|
||||||
@ -143,6 +147,27 @@ public class TodoSimpleQueryService {
|
|||||||
return todoRespBuilder.buildTodosSimple(latestTodos);
|
return todoRespBuilder.buildTodosSimple(latestTodos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<PendingMessageResponse> fetchTodosByBiz(FetchTodoByBizRequest request) {
|
||||||
|
List<Todo> todos = todoDao.lambdaQuery()
|
||||||
|
.and(CollectionUtils.isNotEmpty(request.getTodos()), wrapper -> {
|
||||||
|
for (FetchTodoByBizRequest.TodoInfo todo : request.getTodos()) {
|
||||||
|
wrapper.or()
|
||||||
|
.eq(StringUtils.isNotBlank(todo.getTemplateCode()), Todo::getTemplateCode, todo.getTemplateCode())
|
||||||
|
.eq(StringUtils.isNotBlank(todo.getBizCode()), Todo::getBizCode, todo.getBizCode())
|
||||||
|
.eq(StringUtils.isNotBlank(todo.getSubBizCode()), Todo::getSubBizCode, todo.getSubBizCode());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.last("LIMIT " + cfg.getGetTodoSimpleSize())
|
||||||
|
.list();
|
||||||
|
List<PendingMessageResponse> response = todoRespBuilder.toResponse(
|
||||||
|
todoRespBuilder.buildTodoAdapters(todos), request);
|
||||||
|
ParsedModelV3[] models = response.stream()
|
||||||
|
.map(PendingMessageResponse::getModelV3)
|
||||||
|
.toArray(ParsedModelV3[]::new);
|
||||||
|
v3ExtPopulator.populate(models);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
public List<PendingMessageSimpleDTO> getTodosSimple(GetTodoRequest request) {
|
public List<PendingMessageSimpleDTO> getTodosSimple(GetTodoRequest request) {
|
||||||
List<Todo> todos = todoDao.lambdaQuery()
|
List<Todo> todos = todoDao.lambdaQuery()
|
||||||
.in(CollectionUtils.isNotEmpty(request.getIdentityCodes()), Todo::getIdentityCode, request.getIdentityCodes())
|
.in(CollectionUtils.isNotEmpty(request.getIdentityCodes()), Todo::getIdentityCode, request.getIdentityCodes())
|
||||||
|
|||||||
@ -13,11 +13,14 @@ import cn.axzo.msg.center.dal.TodoDao;
|
|||||||
import cn.axzo.msg.center.domain.entity.Todo;
|
import cn.axzo.msg.center.domain.entity.Todo;
|
||||||
import cn.axzo.msg.center.domain.entity.TodoBusiness;
|
import cn.axzo.msg.center.domain.entity.TodoBusiness;
|
||||||
import cn.axzo.msg.center.domain.entity.TodoHandoverMapping;
|
import cn.axzo.msg.center.domain.entity.TodoHandoverMapping;
|
||||||
|
import cn.axzo.msg.center.domain.enums.RequestReplayType;
|
||||||
import cn.axzo.msg.center.domain.persistence.BaseEntityExt;
|
import cn.axzo.msg.center.domain.persistence.BaseEntityExt;
|
||||||
import cn.axzo.msg.center.inside.notices.config.PendingMessageBizConfig;
|
import cn.axzo.msg.center.inside.notices.config.PendingMessageBizConfig;
|
||||||
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
|
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
|
||||||
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
|
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
|
||||||
import cn.axzo.msg.center.message.service.impl.v3.ModelV3Service;
|
import cn.axzo.msg.center.message.service.impl.v3.ModelV3Service;
|
||||||
|
import cn.axzo.msg.center.message.service.replay.RequestInfo;
|
||||||
|
import cn.axzo.msg.center.message.service.replay.RequestReplayService;
|
||||||
import cn.axzo.msg.center.message.service.todo.TodoWithCardWrapper;
|
import cn.axzo.msg.center.message.service.todo.TodoWithCardWrapper;
|
||||||
import cn.axzo.msg.center.message.service.todo.manage.broadcast.TodoBroadcaster;
|
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.broadcast.TodoMqBroadcaster;
|
||||||
@ -101,6 +104,7 @@ public class TodoManager {
|
|||||||
private final TodoBroadcaster todoBroadcaster;
|
private final TodoBroadcaster todoBroadcaster;
|
||||||
private final TransactionTemplate transactionTemplate;
|
private final TransactionTemplate transactionTemplate;
|
||||||
private final TodoWithCardWrapper todoWithCardWrapper;
|
private final TodoWithCardWrapper todoWithCardWrapper;
|
||||||
|
private final RequestReplayService requestReplayService;
|
||||||
|
|
||||||
public List<PushPendingMessageDTO> send(PendingMessagePushParam request) {
|
public List<PushPendingMessageDTO> send(PendingMessagePushParam request) {
|
||||||
TodoRequestContext ctx = TodoRequestContext.create("send", request.normalize());
|
TodoRequestContext ctx = TodoRequestContext.create("send", request.normalize());
|
||||||
@ -109,6 +113,16 @@ public class TodoManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<PushPendingMessageDTO> send(TodoRequestContext ctx, PendingMessagePushParam request) {
|
public List<PushPendingMessageDTO> send(TodoRequestContext ctx, PendingMessagePushParam request) {
|
||||||
|
RequestInfo requestInfo = new RequestInfo();
|
||||||
|
requestInfo.setTemplateCode(request.getTemplateCode());
|
||||||
|
requestInfo.setBizCode(request.getBizCode());
|
||||||
|
requestInfo.setSubBizCode(request.getSubBizCode());
|
||||||
|
requestInfo.setReplayType(RequestReplayType.TODO_SEND);
|
||||||
|
requestInfo.setRequest(request);
|
||||||
|
return requestReplayService.run(requestInfo, () -> sendOrRetry(ctx, request));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<PushPendingMessageDTO> sendOrRetry(TodoRequestContext ctx, PendingMessagePushParam request) {
|
||||||
// 10 seconds at most
|
// 10 seconds at most
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 20; i++) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -16,4 +16,12 @@ public interface ClientRequest {
|
|||||||
return ModelVersion.V3.getVersionNumber();
|
return ModelVersion.V3.getVersionNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default boolean isKeyValueDisplayOnCardAware() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isButtonDisplayOnCardAware() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -7,6 +7,7 @@ import cn.axzo.msg.center.service.pending.request.CompletePendingBySubCodeReques
|
|||||||
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByCodesRequest;
|
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByCodesRequest;
|
||||||
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByIdRequest;
|
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByIdRequest;
|
||||||
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageRequest;
|
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageRequest;
|
||||||
|
import cn.axzo.msg.center.service.pending.request.FetchTodoByBizRequest;
|
||||||
import cn.axzo.msg.center.service.pending.request.GetPendingTodosRequest;
|
import cn.axzo.msg.center.service.pending.request.GetPendingTodosRequest;
|
||||||
import cn.axzo.msg.center.service.pending.request.GetTodoCountRequest;
|
import cn.axzo.msg.center.service.pending.request.GetTodoCountRequest;
|
||||||
import cn.axzo.msg.center.service.pending.request.GetTodoPageRequest;
|
import cn.axzo.msg.center.service.pending.request.GetTodoPageRequest;
|
||||||
@ -347,6 +348,9 @@ public interface PendingMessageClient {
|
|||||||
@PostMapping(value = "/pending-message/record/get-todos-simple", produces = {MediaType.APPLICATION_JSON_VALUE})
|
@PostMapping(value = "/pending-message/record/get-todos-simple", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
CommonResponse<List<PendingMessageSimpleDTO>> getTodosSimple(@RequestBody @Valid GetTodoRequest request);
|
CommonResponse<List<PendingMessageSimpleDTO>> getTodosSimple(@RequestBody @Valid GetTodoRequest request);
|
||||||
|
|
||||||
|
@PostMapping(value = "/pending-message/record/fetch-todos-by-biz", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
|
CommonResponse<List<PendingMessageResponse>> fetchTodosByBiz(@RequestBody @Valid FetchTodoByBizRequest request);
|
||||||
|
|
||||||
@PostMapping(value = "/pending-message/record/get-todos-simple/count", produces = {MediaType.APPLICATION_JSON_VALUE})
|
@PostMapping(value = "/pending-message/record/get-todos-simple/count", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
CommonResponse<Map<BizCategoryEnum, PendingMessageCountDTO>> getTodosSimpleCount(@RequestBody @Valid GetTodoCountRequest request);
|
CommonResponse<Map<BizCategoryEnum, PendingMessageCountDTO>> getTodosSimpleCount(@RequestBody @Valid GetTodoCountRequest request);
|
||||||
|
|
||||||
|
|||||||
@ -47,6 +47,7 @@ public class CardSendRequest implements CardContent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于幂等的唯一编码. 可选, 需要做幂等时传入. 强烈建议传, 不然可能会产生重复的IM消息
|
* 用于幂等的唯一编码. 可选, 需要做幂等时传入. 强烈建议传, 不然可能会产生重复的IM消息
|
||||||
|
* <p>最大长度250
|
||||||
*/
|
*/
|
||||||
private String idempotentCode;
|
private String idempotentCode;
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,44 @@
|
|||||||
|
package cn.axzo.msg.center.service.pending.request;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.service.enums.AppTerminalTypeEnum;
|
||||||
|
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
|
||||||
|
import cn.axzo.msg.center.service.pending.ClientRequest;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yanglin
|
||||||
|
*/
|
||||||
|
@Setter @Getter
|
||||||
|
public class FetchTodoByBizRequest implements ClientRequest {
|
||||||
|
|
||||||
|
@NotEmpty(message = "rows不能为空")
|
||||||
|
private List<TodoInfo> todos = new ArrayList<>();
|
||||||
|
|
||||||
|
public void addTodo(TodoInfo todo) {
|
||||||
|
if (todos == null)
|
||||||
|
todos = new ArrayList<>();
|
||||||
|
todos.add(todo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Setter @Getter
|
||||||
|
public static class TodoInfo {
|
||||||
|
private String templateCode;
|
||||||
|
private String bizCode;
|
||||||
|
private String subBizCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AppTerminalTypeEnum getAppTerminalType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TerminalTypeEnum getTerminalType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -23,6 +23,7 @@ import javax.validation.constraints.NotNull;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description
|
* @description
|
||||||
@ -51,6 +52,10 @@ public class PendingMessagePageRequest extends PageRequest implements ClientRequ
|
|||||||
* 应用终端
|
* 应用终端
|
||||||
*/
|
*/
|
||||||
private AppTerminalTypeEnum appTerminalType;
|
private AppTerminalTypeEnum appTerminalType;
|
||||||
|
/**
|
||||||
|
* 模板编码集合
|
||||||
|
*/
|
||||||
|
private Set<String> templateCodes;
|
||||||
/**
|
/**
|
||||||
* 当前登录账户的自然id(前端不care)
|
* 当前登录账户的自然id(前端不care)
|
||||||
*/
|
*/
|
||||||
@ -153,6 +158,16 @@ public class PendingMessagePageRequest extends PageRequest implements ClientRequ
|
|||||||
*/
|
*/
|
||||||
private Integer modelVersion;
|
private Integer modelVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否根据配置'是否显示在卡片上'过滤key/value
|
||||||
|
*/
|
||||||
|
private boolean isKeyValueDisplayOnCardAware = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否根据配置'是否显示在卡片上'过滤按钮
|
||||||
|
*/
|
||||||
|
private boolean isButtonDisplayOnCardAware = true;
|
||||||
|
|
||||||
// !! 用于排查问题
|
// !! 用于排查问题
|
||||||
private String analysisToken;
|
private String analysisToken;
|
||||||
private AnalysisInfo a = new AnalysisInfo();
|
private AnalysisInfo a = new AnalysisInfo();
|
||||||
|
|||||||
@ -78,6 +78,16 @@ public class PendingMessageQueryRequest implements ClientRequest, Serializable {
|
|||||||
|
|
||||||
private Integer modelVersion;
|
private Integer modelVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否根据配置'是否显示在卡片上'过滤key/value
|
||||||
|
*/
|
||||||
|
private boolean isKeyValueDisplayOnCardAware = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否根据配置'是否显示在卡片上'过滤按钮
|
||||||
|
*/
|
||||||
|
private boolean isButtonDisplayOnCardAware = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return JSON.toJSONString(this);
|
return JSON.toJSONString(this);
|
||||||
|
|||||||
@ -37,6 +37,11 @@ public class ParsedKV {
|
|||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private boolean displayOnCard;
|
private boolean displayOnCard;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原始变量
|
||||||
|
*/
|
||||||
|
private String valueVariable;
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public boolean isValueAbsent() {
|
public boolean isValueAbsent() {
|
||||||
return ValueUtils.isValueAbsent(value);
|
return ValueUtils.isValueAbsent(value);
|
||||||
|
|||||||
@ -67,14 +67,13 @@ public class ParsedModelV3 implements MessageButtonProvider<ParsedButtonV3>, Pus
|
|||||||
return template == null ? null : template.getCode();
|
return template == null ? null : template.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ParsedKV> determineDisplayOnCardKeyValues() {
|
public List<ParsedKV> collectKeyValues() {
|
||||||
return determineGroups().stream()
|
return determineGroups().stream()
|
||||||
.filter(group -> group.getGroupType() == GroupType.KV_VALUES)
|
.filter(group -> group.getGroupType() == GroupType.KV_VALUES)
|
||||||
.map(ParsedGroupV3::getGroupInfo)
|
.map(ParsedGroupV3::getGroupInfo)
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.map(ParsedGroupInfo::getKeyValues)
|
.map(ParsedGroupInfo::getKeyValues)
|
||||||
.flatMap(Collection::stream)
|
.flatMap(Collection::stream)
|
||||||
.filter(ParsedKV::isDisplayOnCard)
|
|
||||||
.collect(toList());
|
.collect(toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,15 @@
|
|||||||
|
package cn.axzo.msg.center.dal;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.dal.mapper.RequestReplayMapper;
|
||||||
|
import cn.axzo.msg.center.domain.entity.RequestReplay;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yanglin
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class RequestReplayDao extends ServiceImpl<RequestReplayMapper, RequestReplay> {
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package cn.axzo.msg.center.dal.mapper;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.domain.entity.RequestReplay;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yanglin
|
||||||
|
*/
|
||||||
|
public interface RequestReplayMapper extends BaseMapper<RequestReplay> {
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
package cn.axzo.msg.center.domain.entity;
|
||||||
|
|
||||||
|
import cn.axzo.msg.center.domain.enums.RequestReplayType;
|
||||||
|
import cn.axzo.msg.center.domain.persistence.BaseEntityExt;
|
||||||
|
import cn.axzo.msg.center.domain.utils.IgnorePropsJsonTypeHandler;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yanglin
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@TableName(value = "request_replay", autoResultMap = true)
|
||||||
|
public class RequestReplay extends BaseEntityExt<RequestReplay> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模版编码
|
||||||
|
*/
|
||||||
|
private String templateCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务编码
|
||||||
|
*/
|
||||||
|
private String bizCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 子业务编码
|
||||||
|
*/
|
||||||
|
private String subBizCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求类型. TODO_SEND: 发送待办, IM_CARD_SEND: 发送IM卡片
|
||||||
|
*/
|
||||||
|
private RequestReplayType type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求的hash值, 具体hash算法未指定
|
||||||
|
*/
|
||||||
|
private String hash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求
|
||||||
|
*/
|
||||||
|
@TableField(typeHandler = IgnorePropsJsonTypeHandler.class)
|
||||||
|
private JSONObject request;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package cn.axzo.msg.center.domain.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yanglin
|
||||||
|
*/
|
||||||
|
public enum RequestReplayType {
|
||||||
|
TODO_SEND,
|
||||||
|
IM_CARD_SEND
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user