From 73ba13cb9dbf11647da3eb2dc28820661f820ecd Mon Sep 17 00:00:00 2001 From: yanglin Date: Fri, 20 Dec 2024 13:35:34 +0800 Subject: [PATCH] =?UTF-8?q?REQ-3201:=20=E6=8C=89=E9=92=AE=E5=A4=B1?= =?UTF-8?q?=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/v3/msg/CardMappingProcessor.java | 4 - .../message/domain/dto/TemplateModelV3.java | 7 + .../message/service/card/CardController.java | 8 + .../message/service/card/CardManager.java | 152 +++++++++++++----- .../message/service/card/CardParser.java | 15 +- .../message/service/card/CardSupport.java | 9 +- .../service/todo/TodoWithCardWrapper.java | 27 ++-- .../cn/axzo/msg/center/service/ButtonV3.java | 34 ++++ .../service/pending/card/CardClient.java | 18 +++ .../pending/card/domain/CardButtonStates.java | 19 ++- .../service/pending/request/CardContent.java | 4 +- .../pending/request/CardSendRequest.java | 21 ++- .../pending/request/CardStateInfo.java | 11 -- .../request/CardUpdateStateRequest.java | 15 +- .../request/SetActionPerformedRequest.java | 32 ++++ .../response/v3/model/ParsedButtonV3.java | 12 +- .../java/cn/axzo/msg/center/dal/CardDao.java | 13 -- .../axzo/msg/center/domain/entity/Card.java | 6 - .../entity/MessageTemplateButtonV3.java | 3 +- 19 files changed, 288 insertions(+), 122 deletions(-) create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/ButtonV3.java create mode 100644 msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/SetActionPerformedRequest.java diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/v3/msg/CardMappingProcessor.java b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/v3/msg/CardMappingProcessor.java index d9370a98..7a503afb 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/v3/msg/CardMappingProcessor.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/inside/notices/service/impl/v3/msg/CardMappingProcessor.java @@ -8,11 +8,8 @@ import cn.axzo.msg.center.message.domain.dto.TemplateModelV3; import cn.axzo.msg.center.message.service.card.CardManager; import cn.axzo.msg.center.service.dto.PeerPerson; import cn.axzo.msg.center.service.dto.PersonV3DTO; -import cn.axzo.msg.center.service.enums.CardBizState; -import cn.axzo.msg.center.service.enums.CardState; import cn.axzo.msg.center.service.enums.Channel; import cn.axzo.msg.center.service.pending.request.CardSendRequest; -import cn.axzo.msg.center.service.pending.request.CardStateInfo; import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -78,7 +75,6 @@ public class CardMappingProcessor implements EventMappingProcessor { cardRequest.setBizParam(sendBasicInfo.getBizExtParams()); cardRequest.setRouterParam(sendBasicInfo.getRouterParams()); cardRequest.setSubtitle(sendBasicInfo.getSubtitle()); - cardRequest.setStateInfo(CardStateInfo.create(CardState.CREATED, CardBizState.PENDING)); cardManager.send(cardRequest); } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/TemplateModelV3.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/TemplateModelV3.java index e453f140..fa859d31 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/TemplateModelV3.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/domain/dto/TemplateModelV3.java @@ -46,4 +46,11 @@ public class TemplateModelV3 { .findFirst(); } + + public Optional findButton(String buttonCode) { + return buttons.stream() + .filter(btn -> btn.getCode().equals(buttonCode)) + .findFirst(); + } + } \ No newline at end of file diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardController.java index cd5324bf..0318ac76 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardController.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardController.java @@ -4,6 +4,7 @@ import cn.axzo.msg.center.service.pending.card.CardClient; import cn.axzo.msg.center.service.pending.request.CardPresetButtonPressedRequest; import cn.axzo.msg.center.service.pending.request.CardSendRequest; import cn.axzo.msg.center.service.pending.request.CardUpdateStateRequest; +import cn.axzo.msg.center.service.pending.request.SetActionPerformedRequest; import cn.axzo.msg.center.service.pending.response.CardSendResponse; import cn.azxo.framework.common.model.CommonResponse; import lombok.RequiredArgsConstructor; @@ -33,6 +34,13 @@ public class CardController implements CardClient { return CommonResponse.success(); } + @Override + public CommonResponse setActionPerformed(SetActionPerformedRequest request) { + log.info("CardController.setActionPerformed req={}", request); + cardManager.setActionPerformed(request); + return CommonResponse.success(); + } + @Override public CommonResponse firePresetButtonPressed(CardPresetButtonPressedRequest request) { log.info("CardController.firePresetButtonPressed req={}", request); diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardManager.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardManager.java index 3ae7b59a..347ed6be 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardManager.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardManager.java @@ -31,6 +31,7 @@ import cn.axzo.msg.center.service.pending.request.CardSendRequest; import cn.axzo.msg.center.service.pending.request.CardUpdatePresetButtonRequest; import cn.axzo.msg.center.service.pending.request.CardUpdateRequest; import cn.axzo.msg.center.service.pending.request.CardUpdateStateRequest; +import cn.axzo.msg.center.service.pending.request.SetActionPerformedRequest; import cn.axzo.msg.center.service.pending.response.CardSendResponse; import cn.axzo.msg.center.utils.RecordCursor; import lombok.RequiredArgsConstructor; @@ -46,6 +47,7 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; /** * @author yanglin @@ -133,73 +135,104 @@ public class CardManager { } public void updateState(CardUpdateStateRequest request) { - request.getStateInfo().checkForUpdateCardState(); TemplateModelV3 templateModel = cardSupport.ensureImChannelPresent(request.getTemplateCode()); boolean updated = false; // 不要放到for里面去了 - CardRequestContext requestContext = CardRequestContext.create(request); + CardRequestContext requestContext = CardRequestContext.create(request); for (List cards : cardsCursor(request, cardProps.getUpdateCardBatchSize())) { - updated = true; - CardLogger cardLogger = cardLoggers.createLogger(requestContext, cards); - execTransactional(() -> { - cardDao.updateStates(cards, request.getStateInfo()); - rebuildCardContent(templateModel, cards); - cardLogger.reloadAndLogCards("updateState:enqueue"); - }); - updateMessages("updateState", cardLogger, cards); + UpdateCollector collector = new UpdateCollector(requestContext, templateModel); + updated = execTransactional(() -> { + for (Card card : cardDao.reloadCardsForUpdate(cards)) { + Card update = collector.createUpdate(card); + if (request.isCardCompleted()) + update.setCardState(CardState.COMPLETED); + update.setBizState(request.getBizState()); + } + return collector.update("updateState:enqueue"); + }) || updated; + updateMessages("updateState", collector); } BizAssertions.assertTrue(updated, "未找到任何需要更新的卡片, request={}", request); } + void setActionPerformed(SetActionPerformedRequest request) { + TemplateModelV3 templateModel = cardSupport.ensureImChannelPresent(request.getTemplateCode()); + MessageTemplateButtonV3 button = templateModel.findButton(request.getButtonCode()).orElse(null); + BizAssertions.assertNotNull(button, "找不到对应的按钮. buttonCode={}", request.getButtonCode()); + //noinspection DataFlowIssue + BizAssertions.assertTrue(button.isPerformActionAvailable(), + "按钮不支持失效, 未启用'仅待处理可见'. buttonCode={}", request.getButtonCode()); + CardRequestContext requestContext = CardRequestContext.create(request); + for (List cards : cardsCursor(request, cardProps.getUpdateCardBatchSize())) { + UpdateCollector collector = new UpdateCollector(requestContext, templateModel); + execTransactional(() -> { + for (Card card : cardDao.reloadCardsForUpdate(cards)) { + if (card.getCardState() == CardState.COMPLETED) + continue; + CardButtonStates buttonStates = CardButtonStates.create(card.getButtonStates()); + buttonStates.setActionPerformed(button); + Card update = collector.createUpdate(card); + update.setButtonStates(buttonStates.getStates()); + update.setCardState(CardState.COMPLETED); + update.setBizState(request.getCardBizState()); + } + collector.update("setActionPerformed:enqueue"); + }); + updateMessages("setActionPerformed", collector); + } + } + void firePresetButtonPressed(CardPresetButtonPressedRequest request) { Card requestCard = cardDao.findCardByBizMessageId(request.getBizMessageId()).orElse(null); BizAssertions.assertNotNull(requestCard, "找不到对应的卡片, bizMessageId={}", request.getBizMessageId()); List cards = cardDao.collectPersonCards(request.getBizMessageId()); TemplateModelV3 templateModel = cardSupport.ensureImChannelPresent(requestCard.getTemplateCode()); - firePresetButtonPressedImpl(request, templateModel, cards); + FirePresetButtonPressedResult result = firePresetButtonPressedImpl( + request, CardRequestContext.create(request), templateModel, cards); + BizAssertions.assertFalse(result == FirePresetButtonPressedResult.NO_UPDATE, + "卡片已是终状态, 无法'{}'", request.getPresetButtonType().getDesc()); } public void firePresetButtonPressed(CardUpdatePresetButtonRequest request) { TemplateModelV3 templateModel = cardSupport.ensureImChannelPresent(request.getTemplateCode()); + CardRequestContext requestContext = CardRequestContext.create(request); for (List cards : cardsCursor(request, cardProps.getUpdateCardBatchSize())) - firePresetButtonPressedImpl(request, templateModel, cards); + firePresetButtonPressedImpl(request, requestContext, templateModel, cards); } - private void firePresetButtonPressedImpl(CardPresetButtonRequest request, - TemplateModelV3 templateModel, - List cards) { + private FirePresetButtonPressedResult firePresetButtonPressedImpl( + CardPresetButtonRequest request, CardRequestContext requestContext, + TemplateModelV3 templateModel, List cards) { if (CollectionUtils.isEmpty(cards)) { log.info("未找到任何需要更新的卡片, request={}", request); - return; + return FirePresetButtonPressedResult.NO_CARD; } MessageTemplateButtonV3 button = templateModel.findPresetButton(request.getPresetButtonType()).orElse(null); BizAssertions.assertNotNull(button, "找不到对应的预设按钮, request={}", JSON.toJSONString(request)); - CardLogger updateCardLogger = cardLoggers.createLogger(CardRequestContext.create(request)); + UpdateCollector collector = new UpdateCollector(requestContext, templateModel); execTransactional(() -> { - ArrayList updates = new ArrayList<>(cards.size()); for (Card card : cardDao.reloadCardsForUpdate(cards)) { if (card.getCardState() == CardState.COMPLETED) continue; - updateCardLogger.addCard(card); - CardButtonStates buttonStates = CardButtonStates.create(card.getButtonStates()); + Card update = collector.createUpdate(card); //noinspection DataFlowIssue - buttonStates.setActionPerformed(button.getCode()); - Card update = new Card(); - update.setId(card.getId()); - update.setButtonStates(buttonStates.getStates()); - update.setBizState(CardBizState.fromPresetButton(request.getPresetButtonType())); + if (button.isPerformActionAvailable()) { + CardButtonStates buttonStates = CardButtonStates.create(card.getButtonStates()); + buttonStates.setActionPerformed(button); + update.setButtonStates(buttonStates.getStates()); + } update.setCardState(CardState.COMPLETED); - updates.add(update); + update.setBizState(CardBizState.fromPresetButton(request.getPresetButtonType())); } - BizAssertions.assertNotEmpty(updates, "卡片已是终态, 无法'{}'", request.getPresetButtonType().getDesc()); - cardDao.updateBatchById(updates); - rebuildCardContent(templateModel, cards); - updateCardLogger.reloadAndLogCards("presetButtonPressed:enqueue"); + collector.update("presetButtonPressed:enqueue"); }); - if (updateMessages("presetButtonPressed", updateCardLogger, cards)) { - cardBroadcaster.firePresetButtonPressed(cards, request); - updateCardLogger.reloadAndLogCards("presetButtonPressed:mq:success"); + if (updateMessages("presetButtonPressed", collector)) { + cardBroadcaster.firePresetButtonPressed(collector.updatedCards, request); + collector.reloadAndLogCards("presetButtonPressed:mq:success"); } + return collector.updatedCards.isEmpty() + ? FirePresetButtonPressedResult.NO_UPDATE + : FirePresetButtonPressedResult.SUCCESS; } RecordCursor cardsCursor(CardUpdateRequest request, int batchSize) { @@ -239,9 +272,11 @@ public class CardManager { cardDao.updateBatchById(updates); } - private boolean updateMessages(String operation, CardLogger cardLogger, List cards) { + private boolean updateMessages(String operation, UpdateCollector updateCollector) { + if (CollectionUtils.isEmpty(updateCollector.updatedCards)) + return false; UpdateMessageRequest imRequest = new UpdateMessageRequest(); - for (Card card : cardDao.reloadCards(cards)) { + for (Card card : cardDao.reloadCards(updateCollector.updatedCards)) { UpdateMessageRequest.Update update = new UpdateMessageRequest.Update(); update.setBizMessageId(card.getBizMessageId()); Object cardContent = card.getCardContent(); @@ -253,11 +288,11 @@ public class CardManager { log.info("更新IM消息, operation={}, request={}", operation, imRequest); MessageUpdateResponse imResponse = BizAssertions.assertResponse(messageApi.updateMessage(imRequest)); log.info("更新IM消息, operation={}, request={}, response={}", operation, imRequest, imResponse); - cardLogger.reloadAndLogCards(String.format("%s:success", operation)); + updateCollector.updateCardLogger.reloadAndLogCards(String.format("%s:success", operation)); return true; } catch (Exception e) { log.warn("更新IM消息失败, operation={}, request={}", operation, imRequest, e); - cardLogger.reloadAndLogCards(String.format("%s:fail", operation), e); + updateCollector.updateCardLogger.reloadAndLogCards(String.format("%s:fail", operation), e); return false; } } @@ -266,4 +301,47 @@ public class CardManager { transactionTemplate.executeWithoutResult(unused -> runnable.run()); } + private T execTransactional(Supplier runnable) { + return transactionTemplate.execute(status -> runnable.get()); + } + + private enum FirePresetButtonPressedResult { + SUCCESS, NO_CARD, NO_UPDATE + } + + private class UpdateCollector { + + private final CardLogger updateCardLogger; + private final TemplateModelV3 templateModel; + private final List updatedCards = new ArrayList<>(); + private final List updates = new ArrayList<>(); + + UpdateCollector(CardRequestContext requestContext, TemplateModelV3 templateModel) { + this.updateCardLogger = cardLoggers.createLogger(requestContext); + this.templateModel = templateModel; + } + + Card createUpdate(Card card) { + updatedCards.add(card); + updateCardLogger.addCard(card); + Card update = new Card(); + update.setId(card.getId()); + updates.add(update); + return update; + } + + void reloadAndLogCards(String operationContext) { + updateCardLogger.reloadAndLogCards(operationContext); + } + + boolean update(String operationContext) { + if (CollectionUtils.isEmpty(updates)) + return false; + cardDao.updateBatchById(updates); + rebuildCardContent(templateModel, updatedCards); + updateCardLogger.reloadAndLogCards(operationContext); + return true; + } + } + } \ No newline at end of file diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardParser.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardParser.java index c8db6dce..5f530851 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardParser.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardParser.java @@ -14,6 +14,7 @@ import cn.axzo.msg.center.service.enums.CardState; import cn.axzo.msg.center.service.enums.KVContentType; import cn.axzo.msg.center.service.enums.RouterCategoryEnum; import cn.axzo.msg.center.service.enums.TerminalTypeEnum; +import cn.axzo.msg.center.service.pending.card.domain.CardButtonStates; import cn.axzo.msg.center.service.pending.card.domain.CardElementConfig; import cn.axzo.msg.center.service.pending.request.CardContent; import cn.axzo.msg.center.service.pending.request.CardStateInfo; @@ -109,15 +110,23 @@ class CardParser { @Override public void visitButton(ParsedButtonV3 button) { List styles = button.parseStyle(); - if (!styles.contains(ButtonStyleEnum.OVER_CARD)) return; - if (stateInfo.getCardState() == CardState.COMPLETED && button.determinePendingShow()) + if (!styles.contains(ButtonStyleEnum.OVER_CARD)) return; + + boolean isActionPerformed = CardButtonStates + .create(card.getButtonStates()) + .isButtonActionPerformed(button); + + if (card.getStateInfo().getCardState() == CardState.COMPLETED + && button.isPerformActionAvailable() + && !isActionPerformed) + return; + if (bizBody.getCardButtons() == null) bizBody.setCardButtons(new ArrayList<>()); CardButton imButton = new CardButton(); bizBody.getCardButtons().add(imButton); - boolean isActionPerformed = card.isButtonActionPerformed(button.getCode()); imButton.setTitle(isActionPerformed ? button.getActionPerformedName() : button.getName()); imButton.setAction(button.getCategory().name()); imButton.setIsHighlight(styles.contains(ButtonStyleEnum.HIGH_LIGHT)); diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardSupport.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardSupport.java index fda73c65..b0768fdb 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardSupport.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/card/CardSupport.java @@ -10,7 +10,6 @@ import cn.axzo.msg.center.common.utils.BizAssertions; import cn.axzo.msg.center.dal.CardIdempotentDao; import cn.axzo.msg.center.domain.entity.Card; import cn.axzo.msg.center.domain.entity.CardIdempotent; -import cn.axzo.msg.center.inside.notices.config.push.PushProps; import cn.axzo.msg.center.message.domain.dto.TemplateModelV3; import cn.axzo.msg.center.message.domain.vo.GeneralMessagePushVO; import cn.axzo.msg.center.message.service.card.domain.CardGroup; @@ -26,7 +25,6 @@ import cn.axzo.msg.center.service.dto.PeerPerson; import cn.axzo.msg.center.service.enums.MessageChannel; import cn.axzo.msg.center.service.pending.request.CardContent; import cn.axzo.msg.center.service.pending.request.CardSendRequest; -import cn.axzo.msg.center.service.pending.request.CardStateInfo; import cn.axzo.msg.center.service.pending.response.CardInfo; import cn.axzo.msg.center.service.pending.response.v3.ParsedModel3Visitor; import cn.axzo.msg.center.service.pending.response.v3.ParsedModelV3Walker; @@ -61,7 +59,6 @@ public class CardSupport { private final NimPushService nimPushService; private final CardIdempotentDao cardIdempotentDao; private final CardProps cardProps; - private final PushProps pushProps; public static String getBizIdPrefix(String templateCode) { return IdBuilder.builder() @@ -104,10 +101,8 @@ public class CardSupport { card.setBizCode(sendModel.getRequest().determineBizCode()); card.setSubBizCode(sendModel.getRequest().determineSubBizCode()); card.setTemplateCode(sendModel.getRequest().getTemplateCode()); - CardStateInfo stateInfo = sendModel.getRequest().getStateInfo(); - stateInfo.checkForCreateCard(); - card.setBizState(stateInfo.getBizState()); - card.setCardState(stateInfo.getCardState()); + card.setBizState(sendModel.getRequest().getStateInfo().getBizState()); + card.setCardState(sendModel.getRequest().getStateInfo().getCardState()); card.setTitle(sendModel.getTemplate().getTitle()); card.setContent(sendModel.getTemplate().getContent()); card.setCardContent(cardContent); diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/TodoWithCardWrapper.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/TodoWithCardWrapper.java index 447cd911..3b9e574a 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/TodoWithCardWrapper.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/TodoWithCardWrapper.java @@ -12,10 +12,8 @@ import cn.axzo.msg.center.notices.common.constans.CommonConstants; import cn.axzo.msg.center.service.dto.PeerPerson; import cn.axzo.msg.center.service.dto.PersonDTO; import cn.axzo.msg.center.service.enums.CardBizState; -import cn.axzo.msg.center.service.enums.CardState; import cn.axzo.msg.center.service.enums.PresetButtonType; import cn.axzo.msg.center.service.pending.request.CardSendRequest; -import cn.axzo.msg.center.service.pending.request.CardStateInfo; import cn.axzo.msg.center.service.pending.request.CardUpdatePresetButtonRequest; import cn.axzo.msg.center.service.pending.request.CardUpdateStateRequest; import cn.axzo.msg.center.service.pending.request.PresetButtonPressedRequest; @@ -171,7 +169,7 @@ public class TodoWithCardWrapper { * 卡片更新状态-完成 */ public void cardCompleteStateByTodoList(List todoList) { - this.cardUpdateStateByTodoList(todoList,CardBizState.END, CardState.COMPLETED); + this.cardUpdateStateByTodoList(todoList,CardBizState.END, true); } /** @@ -179,38 +177,39 @@ public class TodoWithCardWrapper { * 暂时不需要 */ public void cardRollbackStateByTodoList(List todoList) { - this.cardUpdateStateByTodoList(todoList, CardBizState.ABORTED, CardState.CREATED); + this.cardUpdateStateByTodoList(todoList, CardBizState.ABORTED, false); } /** * 卡片更新状态-撤销 */ public void cardRevokeStateByTodoList(List todoList) { - this.cardUpdateStateByTodoList(todoList, CardBizState.REVOKED, CardState.CREATED); + this.cardUpdateStateByTodoList(todoList, CardBizState.REVOKED, false); } /** * 卡片更新状态-执行中 */ public void cardProcessingStateByTodoList(List todoList) { - this.cardUpdateStateByTodoList(todoList, CardBizState.PENDING, CardState.CREATED); + this.cardUpdateStateByTodoList(todoList, CardBizState.PENDING, false); } /** * 卡片更新完成状态 */ - private void cardUpdateStateByTodoList(List todoList, CardBizState bizState, CardState cardState) { - log.info("TodoWithCardWrapper#cardUpdateStateByTodoList start,todoList:{},bizState:{},cardState:{}", JSON.toJSONString(todoList), bizState, cardState); + private void cardUpdateStateByTodoList(List todoList, CardBizState bizState, boolean setCardCompleted) { + log.info("TodoWithCardWrapper#cardUpdateStateByTodoList start,todoList:{},bizState:{},setCardCompleted:{}", JSON.toJSONString(todoList), bizState, setCardCompleted); if (CollectionUtils.isEmpty(todoList)) { return; } TodoRequestContext ctx = TodoRequestContext.create("todoSyncCardState", todoList); ctx.addLogContent("bizState", bizState); - ctx.addLogContent("cardState", cardState); + ctx.addLogContent("cardState", bizState); + ctx.addLogContent("setCardCompleted", setCardCompleted); try { for (Todo todo : todoList) { //1 构建对象 - CardUpdateStateRequest updateStateRequest = this.buildCardUpdateStateRequest(todo, bizState, cardState); + CardUpdateStateRequest updateStateRequest = this.buildCardUpdateStateRequest(todo, bizState, setCardCompleted); //2 更新状态 cardManager.updateState(updateStateRequest); ctx.addLogContent("cardUpdateStateByTodoList", "success"); @@ -226,12 +225,11 @@ public class TodoWithCardWrapper { /** * 构建卡片状态更新对象 */ - private CardUpdateStateRequest buildCardUpdateStateRequest(Todo todo, CardBizState bizState, CardState cardState) { + private CardUpdateStateRequest buildCardUpdateStateRequest(Todo todo, CardBizState bizState, boolean setCardCompleted) { CardUpdateStateRequest updateStateRequest = new CardUpdateStateRequest(); - CardStateInfo cardStateInfo - = CardStateInfo.create(cardState,bizState); - updateStateRequest.setStateInfo(cardStateInfo); + updateStateRequest.setBizState(bizState); + updateStateRequest.setCardCompleted(setCardCompleted); updateStateRequest.setAppCode(CommonConstants.TODO_SYSN_CARD_APP_CODE); updateStateRequest.setTemplateCode(todo.getTemplateCode()); @@ -263,7 +261,6 @@ public class TodoWithCardWrapper { if (StringUtils.isNotBlank(param.getRouterParams())) { sendRequest.setRouterParam(JSON.parseObject(param.getRouterParams())); } - sendRequest.setStateInfo(CardStateInfo.create(CardState.CREATED, CardBizState.PENDING)); sendRequest.setIdempotentCode(IdBuilder.builder() .append(param.getBizCode()) diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/ButtonV3.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/ButtonV3.java new file mode 100644 index 00000000..13e3b174 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/ButtonV3.java @@ -0,0 +1,34 @@ +package cn.axzo.msg.center.service; + +import cn.axzo.msg.center.service.enums.PresetButtonType; + +/** + * @author yanglin + */ +public interface ButtonV3 { + + String getName(); + + String getCode(); + + String getActionPerformedName(); + + PresetButtonType getPresetBtnType(); + + Boolean getPendingShow(); + + Boolean getExecutorShow(); + + default boolean determineIsPendingShow() { + return getPendingShow() != null && getPendingShow(); + } + + default boolean determineIsExecutorShow() { + return getExecutorShow() != null && getExecutorShow(); + } + + default boolean isPerformActionAvailable() { + return determineIsPendingShow(); + } + +} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/card/CardClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/card/CardClient.java index 8720ebe4..84161f70 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/card/CardClient.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/card/CardClient.java @@ -3,6 +3,7 @@ package cn.axzo.msg.center.service.pending.card; import cn.axzo.msg.center.service.pending.request.CardPresetButtonPressedRequest; import cn.axzo.msg.center.service.pending.request.CardSendRequest; import cn.axzo.msg.center.service.pending.request.CardUpdateStateRequest; +import cn.axzo.msg.center.service.pending.request.SetActionPerformedRequest; import cn.axzo.msg.center.service.pending.response.CardSendResponse; import cn.azxo.framework.common.model.CommonResponse; import org.springframework.cloud.openfeign.FeignClient; @@ -20,16 +21,33 @@ import javax.validation.Valid; @FeignClient(value = "msg-center", url = "${server.serviceUrl:http://msg-center:8080}") public interface CardClient { + /** + * 发送卡片 + */ @PostMapping(value = "/api/card/send", produces = {MediaType.APPLICATION_JSON_VALUE}) CommonResponse send( @RequestBody @Valid CardSendRequest request); + /** + * 更新卡片状态 + */ @PostMapping(value = "/api/card/updateState", produces = {MediaType.APPLICATION_JSON_VALUE}) CommonResponse updateState( @RequestBody @Valid CardUpdateStateRequest request); + /** + * 设置按钮失效, 且卡片状态设置为已经完成 + */ + @PostMapping(value = "/api/card/setActionPerformed", + produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse setActionPerformed( + @RequestBody @Valid SetActionPerformedRequest request); + + /** + * 点击预设按钮 + */ @PostMapping(value = "/api/card/firePresetButtonPressed", produces = {MediaType.APPLICATION_JSON_VALUE}) CommonResponse firePresetButtonPressed( diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/card/domain/CardButtonStates.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/card/domain/CardButtonStates.java index 0c46505b..16f3565b 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/card/domain/CardButtonStates.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/card/domain/CardButtonStates.java @@ -1,5 +1,7 @@ package cn.axzo.msg.center.service.pending.card.domain; +import cn.axzo.basics.common.exception.ServiceException; +import cn.axzo.msg.center.service.ButtonV3; import lombok.AccessLevel; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -22,18 +24,25 @@ public class CardButtonStates { buttonStates == null ? Collections.emptyList(): buttonStates)); } - public void setActionPerformed(String buttonCode) { - states.removeIf(s -> s.getButtonCode().equals(buttonCode)); + public void setActionPerformed(ButtonV3 button) { + ensureNoButtonActionPerformed(); + states.removeIf(s -> s.getButtonCode().equals(button.getCode())); CardButtonState state = new CardButtonState(); - state.setButtonCode(buttonCode); + state.setButtonCode(button.getCode()); state.setIsActionPerformed(true); states.add(state); } - public boolean isButtonActionPerformed(String buttonCode) { + private void ensureNoButtonActionPerformed() { + boolean noActionPerformedButton = states.stream().noneMatch(CardButtonState::determineIsActionPerformed); + if (!noActionPerformedButton) + throw new ServiceException("无法设置多个按钮失效, 是否更改过配置?"); + } + + public boolean isButtonActionPerformed(ButtonV3 button) { return states.stream() .anyMatch(state -> { - boolean isTheButton = state.getButtonCode().equals(buttonCode); + boolean isTheButton = state.getButtonCode().equals(button.getCode()); boolean actionPerformed = state.determineIsActionPerformed(); return isTheButton && actionPerformed; }); diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardContent.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardContent.java index 280d0d72..1f2c2aaf 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardContent.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardContent.java @@ -1,8 +1,10 @@ package cn.axzo.msg.center.service.pending.request; +import cn.axzo.msg.center.service.pending.card.domain.CardButtonState; import com.alibaba.fastjson.JSONObject; import javax.validation.constraints.NotNull; +import java.util.List; /** * @author yanglin @@ -13,7 +15,7 @@ public interface CardContent { CardStateInfo getStateInfo(); - boolean isButtonActionPerformed(String buttonCode); + List getButtonStates(); String getSubtitle(); diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardSendRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardSendRequest.java index 2c4471a2..a3cafe17 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardSendRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardSendRequest.java @@ -1,16 +1,22 @@ package cn.axzo.msg.center.service.pending.request; import cn.axzo.msg.center.service.dto.PeerPerson; +import cn.axzo.msg.center.service.enums.CardBizState; +import cn.axzo.msg.center.service.enums.CardState; +import cn.axzo.msg.center.service.pending.card.domain.CardButtonState; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Getter; import lombok.Setter; -import javax.validation.Valid; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; +import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -80,15 +86,14 @@ public class CardSendRequest implements CardContent { */ private boolean returnCards = false; - /** - * 状态信息 - */ - @Valid @NotNull(message = "状态不能为空") - private CardStateInfo stateInfo; + @Override @JsonIgnore @JSONField(serialize = false, defaultValue = "false") + public CardStateInfo getStateInfo() { + return CardStateInfo.create(CardState.CREATED, CardBizState.PENDING); + } @Override - public boolean isButtonActionPerformed(String buttonCode) { - return false; + public List getButtonStates() { + return Collections.emptyList(); } @Override diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardStateInfo.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardStateInfo.java index 101246c0..35a16f7a 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardStateInfo.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardStateInfo.java @@ -1,6 +1,5 @@ package cn.axzo.msg.center.service.pending.request; -import cn.axzo.basics.common.exception.ServiceException; import cn.axzo.msg.center.service.enums.CardBizState; import cn.axzo.msg.center.service.enums.CardState; import lombok.Getter; @@ -23,16 +22,6 @@ public class CardStateInfo { */ private CardState cardState; - public void checkForCreateCard() { - if (bizState == null || cardState == null) - throw new ServiceException("创建卡片时, bizState和cardState必须同时设置"); - } - - public void checkForUpdateCardState() { - if (bizState == null && cardState == null) - throw new ServiceException("更新卡片状态时, bizState和cardState至少设置一个"); - } - /** * 构建对象 */ diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardUpdateStateRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardUpdateStateRequest.java index 7d50c350..36cec508 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardUpdateStateRequest.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/CardUpdateStateRequest.java @@ -1,12 +1,10 @@ package cn.axzo.msg.center.service.pending.request; +import cn.axzo.msg.center.service.enums.CardBizState; import com.alibaba.fastjson.JSON; import lombok.Getter; import lombok.Setter; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; - /** * @author yanglin */ @@ -15,13 +13,18 @@ import javax.validation.constraints.NotNull; public class CardUpdateStateRequest extends CardUpdateRequest { /** - * 卡片状态 + * 业务状态, 结合模版配置控制状态戳(状态图片) */ - @Valid @NotNull(message = "状态不能为空") - private CardStateInfo stateInfo; + private CardBizState bizState; + + /** + * 是否将卡片设置为完成状态, 结合模版配置控制按钮可见性 + */ + private boolean cardCompleted = false; @Override public String toString() { return JSON.toJSONString(this); } + } \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/SetActionPerformedRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/SetActionPerformedRequest.java new file mode 100644 index 00000000..5c34e8ba --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/SetActionPerformedRequest.java @@ -0,0 +1,32 @@ +package cn.axzo.msg.center.service.pending.request; + +import cn.axzo.msg.center.service.enums.CardBizState; +import com.alibaba.fastjson.JSON; +import lombok.Getter; +import lombok.Setter; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * @author yanglin + */ +@Setter +@Getter +public class SetActionPerformedRequest extends CardUpdateRequest { + + /** + * 需要设置失效的按钮编辑 + */ + @NotBlank(message = "按钮编码不能为空") + private String buttonCode; + + @NotNull(message = "卡片业务状态不能为空") + private CardBizState cardBizState = CardBizState.COMPLETED; + + @Override + public String toString() { + return JSON.toJSONString(this); + } + +} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedButtonV3.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedButtonV3.java index 1189de99..f308b86f 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedButtonV3.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/response/v3/model/ParsedButtonV3.java @@ -1,5 +1,6 @@ package cn.axzo.msg.center.service.pending.response.v3.model; +import cn.axzo.msg.center.service.ButtonV3; import cn.axzo.msg.center.service.domain.UrlConfig; import cn.axzo.msg.center.service.enums.ButtonStyleEnum; import cn.axzo.msg.center.service.enums.PresetButtonType; @@ -22,7 +23,7 @@ import java.util.List; */ @Setter @Getter -public class ParsedButtonV3 implements MessageButton { +public class ParsedButtonV3 implements MessageButton, ButtonV3 { private Long id; @@ -102,10 +103,6 @@ public class ParsedButtonV3 implements MessageButton { return priority == null ? Integer.MAX_VALUE : priority; } - public boolean determinePendingShow() { - return pendingShow != null && pendingShow; - } - public List parseStyle() { if (style == null) return Collections.emptyList(); return JSON.parseArray(style.toJSONString(), ButtonStyleEnum.class); @@ -124,4 +121,9 @@ public class ParsedButtonV3 implements MessageButton { public String toString() { return JSON.toJSONString(this); } + + @Override + public PresetButtonType getPresetBtnType() { + return presetButtonType; + } } \ No newline at end of file diff --git a/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/CardDao.java b/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/CardDao.java index 5b8f3c0e..2c7ffc3a 100644 --- a/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/CardDao.java +++ b/msg-center-dal/src/main/java/cn/axzo/msg/center/dal/CardDao.java @@ -5,7 +5,6 @@ import cn.axzo.im.center.api.vo.resp.UpdatableMessageSendResult; import cn.axzo.msg.center.dal.mapper.CardMapper; import cn.axzo.msg.center.domain.entity.Card; import cn.axzo.msg.center.domain.persistence.BaseEntityExt; -import cn.axzo.msg.center.service.pending.request.CardStateInfo; import cn.axzo.msg.center.util.DeleteAwareInterceptor; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; @@ -17,7 +16,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; import static java.util.stream.Collectors.toList; @@ -28,17 +26,6 @@ import static java.util.stream.Collectors.toList; @Component public class CardDao extends ServiceImpl { - public void updateStates(List cards, CardStateInfo stateInfo) { - List cardIds = cards.stream() - .map(BaseEntityExt::getId) - .collect(Collectors.toList()); - lambdaUpdate() - .in(Card::getId, cardIds) - .set(stateInfo.getBizState() != null, Card::getBizState, stateInfo.getBizState()) - .set(stateInfo.getCardState() != null, Card::getCardState, stateInfo.getCardState()) - .update(); - } - public List collectPersonCards(String oneOfBizMessageId) { Card card = findCardByBizMessageId(oneOfBizMessageId).orElse(null); if (card == null) return Collections.emptyList(); diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/Card.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/Card.java index 6463b9c0..721ccb27 100644 --- a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/Card.java +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/Card.java @@ -8,7 +8,6 @@ import cn.axzo.msg.center.domain.utils.IgnorePropsJsonTypeHandler; import cn.axzo.msg.center.service.enums.CardBizState; import cn.axzo.msg.center.service.enums.CardState; import cn.axzo.msg.center.service.pending.card.domain.CardButtonState; -import cn.axzo.msg.center.service.pending.card.domain.CardButtonStates; import cn.axzo.msg.center.service.pending.request.CardContent; import cn.axzo.msg.center.service.pending.request.CardStateInfo; import com.alibaba.fastjson.JSONObject; @@ -183,11 +182,6 @@ public class Card extends BaseEntityExt implements CardContent { return cardStateInfo; } - @Override - public boolean isButtonActionPerformed(String buttonCode) { - return CardButtonStates.create(buttonStates).isButtonActionPerformed(buttonCode); - } - @Override public JSONObject getBizParam() { return bizParam; diff --git a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateButtonV3.java b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateButtonV3.java index 1326d2aa..c836328f 100644 --- a/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateButtonV3.java +++ b/msg-center-domain/src/main/java/cn/axzo/msg/center/domain/entity/MessageTemplateButtonV3.java @@ -1,6 +1,7 @@ package cn.axzo.msg.center.domain.entity; import cn.axzo.msg.center.domain.utils.IgnorePropsJsonTypeHandler; +import cn.axzo.msg.center.service.ButtonV3; import cn.axzo.msg.center.service.domain.UrlConfig; import cn.axzo.msg.center.service.enums.PresetButtonType; import cn.axzo.msg.center.service.enums.RouterButtonSourceEnum; @@ -19,7 +20,7 @@ import lombok.Setter; @Setter @Getter @TableName(value = "message_template_button_v3", autoResultMap = true) -public class MessageTemplateButtonV3 extends BaseEntityWithOperator { +public class MessageTemplateButtonV3 extends BaseEntityWithOperator implements ButtonV3 { /** * 按钮名称