REQ-3201: 按钮失效

This commit is contained in:
yanglin 2024-12-20 13:35:34 +08:00
parent 008e1b4e8e
commit 73ba13cb9d
19 changed files with 288 additions and 122 deletions

View File

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

View File

@ -46,4 +46,11 @@ public class TemplateModelV3 {
.findFirst();
}
public Optional<MessageTemplateButtonV3> findButton(String buttonCode) {
return buttons.stream()
.filter(btn -> btn.getCode().equals(buttonCode))
.findFirst();
}
}

View File

@ -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<Void> setActionPerformed(SetActionPerformedRequest request) {
log.info("CardController.setActionPerformed req={}", request);
cardManager.setActionPerformed(request);
return CommonResponse.success();
}
@Override
public CommonResponse<Void> firePresetButtonPressed(CardPresetButtonPressedRequest request) {
log.info("CardController.firePresetButtonPressed req={}", request);

View File

@ -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<CardUpdateStateRequest> requestContext = CardRequestContext.create(request);
for (List<Card> 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<SetActionPerformedRequest> requestContext = CardRequestContext.create(request);
for (List<Card> 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<Card> 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<CardUpdatePresetButtonRequest> requestContext = CardRequestContext.create(request);
for (List<Card> cards : cardsCursor(request, cardProps.getUpdateCardBatchSize()))
firePresetButtonPressedImpl(request, templateModel, cards);
firePresetButtonPressedImpl(request, requestContext, templateModel, cards);
}
private void firePresetButtonPressedImpl(CardPresetButtonRequest request,
TemplateModelV3 templateModel,
List<Card> cards) {
private FirePresetButtonPressedResult firePresetButtonPressedImpl(
CardPresetButtonRequest request, CardRequestContext<?> requestContext,
TemplateModelV3 templateModel, List<Card> 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<Card> 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<Card> cardsCursor(CardUpdateRequest request, int batchSize) {
@ -239,9 +272,11 @@ public class CardManager {
cardDao.updateBatchById(updates);
}
private boolean updateMessages(String operation, CardLogger cardLogger, List<Card> 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> T execTransactional(Supplier<T> 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<Card> updatedCards = new ArrayList<>();
private final List<Card> 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;
}
}
}

View File

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

View File

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

View File

@ -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<Todo> 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<Todo> todoList) {
this.cardUpdateStateByTodoList(todoList, CardBizState.ABORTED, CardState.CREATED);
this.cardUpdateStateByTodoList(todoList, CardBizState.ABORTED, false);
}
/**
* 卡片更新状态-撤销
*/
public void cardRevokeStateByTodoList(List<Todo> todoList) {
this.cardUpdateStateByTodoList(todoList, CardBizState.REVOKED, CardState.CREATED);
this.cardUpdateStateByTodoList(todoList, CardBizState.REVOKED, false);
}
/**
* 卡片更新状态-执行中
*/
public void cardProcessingStateByTodoList(List<Todo> todoList) {
this.cardUpdateStateByTodoList(todoList, CardBizState.PENDING, CardState.CREATED);
this.cardUpdateStateByTodoList(todoList, CardBizState.PENDING, false);
}
/**
* 卡片更新完成状态
*/
private void cardUpdateStateByTodoList(List<Todo> todoList, CardBizState bizState, CardState cardState) {
log.info("TodoWithCardWrapper#cardUpdateStateByTodoList start,todoList:{},bizState:{},cardState:{}", JSON.toJSONString(todoList), bizState, cardState);
private void cardUpdateStateByTodoList(List<Todo> 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())

View File

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

View File

@ -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<CardSendResponse> send(
@RequestBody @Valid CardSendRequest request);
/**
* 更新卡片状态
*/
@PostMapping(value = "/api/card/updateState",
produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<Void> updateState(
@RequestBody @Valid CardUpdateStateRequest request);
/**
* 设置按钮失效, 且卡片状态设置为已经完成
*/
@PostMapping(value = "/api/card/setActionPerformed",
produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<Void> setActionPerformed(
@RequestBody @Valid SetActionPerformedRequest request);
/**
* 点击预设按钮
*/
@PostMapping(value = "/api/card/firePresetButtonPressed",
produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<Void> firePresetButtonPressed(

View File

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

View File

@ -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<CardButtonState> getButtonStates();
String getSubtitle();

View File

@ -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<CardButtonState> getButtonStates() {
return Collections.emptyList();
}
@Override

View File

@ -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至少设置一个");
}
/**
* 构建对象
*/

View File

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

View File

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

View File

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

View File

@ -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<CardMapper, Card> {
public void updateStates(List<Card> cards, CardStateInfo stateInfo) {
List<Long> 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<Card> collectPersonCards(String oneOfBizMessageId) {
Card card = findCardByBizMessageId(oneOfBizMessageId).orElse(null);
if (card == null) return Collections.emptyList();

View File

@ -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<Card> implements CardContent {
return cardStateInfo;
}
@Override
public boolean isButtonActionPerformed(String buttonCode) {
return CardButtonStates.create(buttonStates).isButtonActionPerformed(buttonCode);
}
@Override
public JSONObject getBizParam() {
return bizParam;

View File

@ -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<MessageTemplateButtonV3> {
public class MessageTemplateButtonV3 extends BaseEntityWithOperator<MessageTemplateButtonV3> implements ButtonV3 {
/**
* 按钮名称