This commit is contained in:
yanglin 2025-01-03 17:31:23 +08:00
parent 2dead472b0
commit e72a7e1e83
22 changed files with 399 additions and 131 deletions

View File

@ -7,6 +7,8 @@ import cn.axzo.msg.center.message.domain.vo.GeneralMessagePushVO.CardExtensionIt
import cn.axzo.msg.center.message.service.impl.v3.AppLink;
import cn.axzo.msg.center.message.service.impl.v3.NativeAppLinkUrlConfigVisitor;
import cn.axzo.msg.center.message.service.impl.v3.V3ExtPopulator;
import cn.axzo.msg.center.message.service.card.interceptor.CardButtonInterceptor;
import cn.axzo.msg.center.message.service.card.interceptor.CardButtonInterceptorFactory;
import cn.axzo.msg.center.service.domain.UrlConfig;
import cn.axzo.msg.center.service.domain.UrlConfigWalker;
import cn.axzo.msg.center.service.enums.ButtonStyleEnum;
@ -25,8 +27,8 @@ 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.ParsedTemplateV3;
import cn.axzo.msg.center.service.pending.response.v3.model.PersonInfo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
@ -38,12 +40,23 @@ import java.util.List;
* @author yanglin
*/
@Component
@RequiredArgsConstructor
class CardParser {
private final MessageSystemConfig messageSystemConfig;
private final V3ExtPopulator v3ExtPopulator;
private final CardProps cardProps;
private final CardButtonInterceptorFactory[] interceptorFactories;
CardParser(MessageSystemConfig messageSystemConfig,
V3ExtPopulator v3ExtPopulator,
CardProps cardProps,
ObjectProvider<CardButtonInterceptorFactory[]> interceptorFactoryProvider) {
this.messageSystemConfig = messageSystemConfig;
this.v3ExtPopulator = v3ExtPopulator;
this.cardProps = cardProps;
this.interceptorFactories = interceptorFactoryProvider
.getIfAvailable(() -> new CardButtonInterceptorFactory[0]);
}
GeneralMessagePushVO parseCardContent(CardTemplate cardTemplate, CardContent card) {
ParsedTemplateV3 template = cardTemplate.getTemplate();
@ -76,6 +89,7 @@ class CardParser {
bizBody.addDebugInfo("bizState", stateInfo.getBizState());
bizBody.addDebugInfo("cardState", stateInfo.getCardState());
bizBody.addDebugInfo("isUpdatable", cardTemplate.isUpdatable());
CardButtonInterceptor buttonInterceptor = getButtonInterceptor(card);
ParsedModelV3Walker.walkDown(cardTemplate.getParsedModel(), new ParsedModel3Visitor() {
@Override
public void visitTemplateCardUrlConfig(UrlConfig urlConfig) {
@ -113,16 +127,21 @@ class CardParser {
*/
@Override
public void visitButton(ParsedButtonV3 button) {
List<ButtonStyleEnum> styles = button.parseStyle();
if (!styles.contains(ButtonStyleEnum.OVER_CARD))
return;
boolean isActionPerformed = CardButtonStates
.create(card.getButtonStates())
.isButtonActionPerformed(button);
Boolean isVisibleOnCard = buttonInterceptor
.isVisibleOnCard(button)
.orElse(() -> button.getStyles().contains(ButtonStyleEnum.OVER_CARD));
if (!isVisibleOnCard) return;
boolean isPerformActionAvailable = buttonInterceptor
.isPerformActionAvailable(button)
.orElse(button.isPerformActionAvailable());
Boolean isActionPerformed = buttonInterceptor
.isActionPerformed(button)
.orElse(CardButtonStates
.create(card.getButtonStates())
.isButtonActionPerformed(button));
if (card.getStateInfo().getCardState() == CardState.COMPLETED
&& button.isPerformActionAvailable()
&& isPerformActionAvailable
&& !isActionPerformed)
return;
@ -131,9 +150,12 @@ class CardParser {
CardButton imButton = new CardButton();
bizBody.getCardButtons().add(imButton);
imButton.setTitle(isActionPerformed ? button.getActionPerformedName() : button.getName());
String actionPerformed = buttonInterceptor
.getActionPerformedName(button)
.orElse(button.getActionPerformedName());
imButton.setTitle(isActionPerformed ? actionPerformed : button.getName());
imButton.setAction(button.getCategory().name());
imButton.setIsHighlight(styles.contains(ButtonStyleEnum.HIGH_LIGHT));
imButton.setIsHighlight(button.getStyles().contains(ButtonStyleEnum.HIGH_LIGHT));
imButton.setExecutorShow(button.getExecutorShow());
imButton.setActionPerformed(isActionPerformed);
if (button.getUrlConfig().hasUrl())
@ -170,4 +192,13 @@ class CardParser {
return visitor.getLinks();
}
private CardButtonInterceptor getButtonInterceptor(CardContent card) {
for (CardButtonInterceptorFactory factory : interceptorFactories) {
CardButtonInterceptor interceptor = factory.create(card);
if (interceptor != null)
return interceptor;
}
return CardButtonInterceptor.NOT_SURE;
}
}

View File

@ -0,0 +1,43 @@
package cn.axzo.msg.center.message.service.card.interceptor;
import cn.axzo.msg.center.service.ButtonV3;
import cn.axzo.msg.center.utils.desision.DecisionValue;
/**
* @author yanglin
*/
public interface CardButtonInterceptor {
DecisionValue<Boolean> isPerformActionAvailable(ButtonV3 button);
DecisionValue<Boolean> isActionPerformed(ButtonV3 button);
DecisionValue<String> getActionPerformedName(ButtonV3 button);
DecisionValue<Boolean> isVisibleOnCard(ButtonV3 button);
CardButtonInterceptor NOT_SURE = new CardButtonInterceptor() {
@Override
public DecisionValue<Boolean> isPerformActionAvailable(ButtonV3 button) {
return DecisionValue.notSure();
}
@Override
public DecisionValue<Boolean> isActionPerformed(ButtonV3 button) {
return DecisionValue.notSure();
}
@Override
public DecisionValue<String> getActionPerformedName(ButtonV3 button) {
return DecisionValue.notSure();
}
@Override
public DecisionValue<Boolean> isVisibleOnCard(ButtonV3 button) {
return DecisionValue.notSure();
}
};
}

View File

@ -0,0 +1,15 @@
package cn.axzo.msg.center.message.service.card.interceptor;
import cn.axzo.msg.center.service.pending.request.CardContent;
import javax.annotation.Nullable;
/**
* @author yanglin
*/
public interface CardButtonInterceptorFactory {
@Nullable
CardButtonInterceptor create(CardContent card);
}

View File

@ -89,7 +89,7 @@ public class ModelV2PropsPopulator implements ParsedModel3Visitor {
buttonV2.setDesc(buttonV3.getName());
buttonV2.setCategory(buttonV3.getCategory());
buttonV2.setPresetButtonType(buttonV3.getPresetButtonType());
buttonV2.setStyle(buttonV3.parseStyle());
buttonV2.setStyle(buttonV3.getStyles());
buttonV2.setExecutorShow(buttonV3.getExecutorShow());
buttonV2.setPendingShow(buttonV3.getPendingShow());
buttonV2.setKey(buttonV3.getCode());

View File

@ -6,12 +6,14 @@ import cn.axzo.framework.rocketmq.EventHandler;
import cn.axzo.msg.center.api.mq.CardPresetButtonPressedMessage;
import cn.axzo.msg.center.service.enums.MqMessageType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
/**
* @author yanglin
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class CardSyncTodoHandler implements EventHandler, InitializingBean {
@ -22,6 +24,7 @@ public class CardSyncTodoHandler implements EventHandler, InitializingBean {
@Override
public void onEvent(Event event, EventConsumer.Context context) {
CardPresetButtonPressedMessage message = event.normalizedData(CardPresetButtonPressedMessage.class);
log.info("received CardPresetButtonPressedMessage: {}", message);
todoSyncCardService.syncCardPresetButtonPressed(message);
}

View File

@ -18,12 +18,12 @@ import cn.axzo.msg.center.service.dto.PeerPerson;
import cn.axzo.msg.center.service.enums.BizCategoryEnum;
import cn.axzo.msg.center.service.enums.BizFinalStateEnum;
import cn.axzo.msg.center.service.enums.CardBizState;
import cn.axzo.msg.center.service.enums.CodeDefinition;
import cn.axzo.msg.center.service.enums.MessageChannel;
import cn.axzo.msg.center.service.enums.PendingMessageStateEnum;
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.PresetButtonPressedRequest;
import cn.axzo.msg.center.service.pending.request.SetActionPerformedRequest;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Sets;
import lombok.RequiredArgsConstructor;
@ -31,16 +31,20 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.util.Optional;
/**
* @author yanglin
*/
@Slf4j
@Component
@RequiredArgsConstructor
class TodoSyncCardService {
public class TodoSyncCardService {
private static final String TODO_IDENTITY_CODE_BIZ_PARAM_KEY = "____todo_identity_code____";
private static final String APP_CODE = "msg-center:todo";
private static final String TODO_IDENTITY_CODE_BIZ_PARAM_KEY = "____todo_identity_code____";
private static final String TODO_TYPE_BIZ_PARAM_KEY = "____todo_type____";
private static final String TODO_CATEGORY_BIZ_PARAM_KEY = "____todo_category____";
private final TodoDao todoDao;
private final TodoBusinessDao todoBusinessDao;
@ -50,7 +54,7 @@ class TodoSyncCardService {
private final TodoManager todoManager;
void onMessage(Event event, TodoUpdateMessage message) {
log.info("TodoSyncStateToCardService.onMessage: {}", message);
log.info("received TodoUpdateMessage: {}", message);
try {
sync(event, message);
} catch (Exception e) {
@ -87,13 +91,10 @@ class TodoSyncCardService {
return;
}
if (todo.getState() == PendingMessageStateEnum.HAS_BEEN_SENT
|| todo.getState() == PendingMessageStateEnum.CREATED) {
|| todo.getState() == PendingMessageStateEnum.CREATED)
sendCard(event, business, todo);
} else {
else
updateCardState(event, business, todo);
if (business.getBizCategory() == BizCategoryEnum.FLOW)
maybeSetFlowActionPerformed(event, business, todo);
}
}
private void sendCard(Event event, TodoBusiness business, Todo todo) {
@ -108,19 +109,24 @@ class TodoSyncCardService {
todo.getExecutorPersonId(), todo.getOuId(), todo.getOrgId())));
JSONObject bizParam = todo.bizParam();
bizParam.put(TODO_IDENTITY_CODE_BIZ_PARAM_KEY, todo.getIdentityCode());
bizParam.put(TODO_TYPE_BIZ_PARAM_KEY, todo.getType().getCode());
bizParam.put(TODO_CATEGORY_BIZ_PARAM_KEY, business.getBizCategory().getCode());
request.setBizParam(bizParam);
request.setRouterParam(todo.routerParam());
request.setReturnCards(false);
TodoRequestContext ctx = TodoRequestContext
.create("sendCard", event)
.addLogContent("sendCardRequest", request);
try {
log.info("TodoSyncStateToCardService.sendCard: todo={}", todo);
cardManager.send(request);
TodoRequestContext ctx = TodoRequestContext
.create("sendCard", event)
.addLogContent("sendCardRequest", request);
todoLogger.logTodoUpdated(ctx, todo);
log.info("TodoSyncStateToCardService.sendCard: success, todo={}", todo);
} catch (CardIdempotentException ignored) {
log.warn("TodoSyncStateToCardService.sendCard: idempotent, todo={}", todo);
} catch (Exception e) {
log.warn("TodoSyncStateToCardService.sendCard: error, todo={}", todo, e);
todoLogger.logTodoUpdated(ctx.copy().addLogContent("exception", e), todo);
}
}
@ -132,77 +138,36 @@ class TodoSyncCardService {
request.setSubBizCode(todo.getSubBizCode());
request.setReceivers(Sets.newHashSet(PeerPerson.create(
todo.getExecutorPersonId(), todo.getOuId(), todo.getOrgId())));
request.setBizState(getBizState(business, todo));
request.setBizState(business.getBizCategory() == BizCategoryEnum.FLOW
? determineCardBizStateForFlowTodo(business)
: determineCardBizStateForBizTodo(todo));
request.setCardCompleted(todo.getState() == PendingMessageStateEnum.COMPLETED);
TodoRequestContext ctx = TodoRequestContext
.create("updateCardState", event)
.addLogContent("updateCardStateRequest", request)
.addLogContent("todo", todo);
if (request.isValid()) {
cardManager.updateState(request);
todoLogger.logTodoUpdated(
ctx.copy().addLogContent("updateCardStateResult", "success"),
todo);
try {
cardManager.updateState(request);
todoLogger.logTodoUpdated(ctx.copy().addLogContent("updateCardStateResult", "success"), todo);
} catch (Exception e) {
log.warn("TodoSyncStateToCardService.updateCardState: error, todo={}", todo, e);
todoLogger.logTodoUpdated(ctx.copy().addLogContent("exception", e), todo);
}
} else {
log.info("TodoSyncStateToCardService.updateCardState: invalid request, todo={}", todo);
todoLogger.logTodoUpdated(
ctx.copy().addLogContent("updateCardStateResult", "invalid update card state request"),
todo);
todoLogger.logTodoUpdated(ctx.copy().addLogContent("updateCardStateResult", "invalid update card state request"), todo);
}
}
private void maybeSetFlowActionPerformed(Event event, TodoBusiness business, Todo todo) {
if (business.getBizFinalState() == null || !business.getBizFinalState().isEnableActionPerformed()) {
log.warn("TodoSyncStateToCardService.updateFlowButtonStates:" +
" bizFinalState is null or not action performable, business={}, todo={}", business, todo);
return;
}
SetActionPerformedRequest request = new SetActionPerformedRequest();
request.setAppCode(APP_CODE);
request.setTemplateCode(todo.getTemplateCode());
request.setBizCode(todo.getBizCode());
request.setSubBizCode(todo.getSubBizCode());
request.setReceivers(Sets.newHashSet(PeerPerson.create(
todo.getExecutorPersonId(), todo.getOuId(), todo.getOrgId())));
request.setButtonCode(business.getBizFinalState().getButtonCode());
request.setCardBizState(getBizState(business, todo));
cardManager.setActionPerformed(request);
TodoRequestContext ctx = TodoRequestContext
.create("updateCardFlowButtonStates", event)
.addLogContent("todo", todo);
todoLogger.logTodoUpdated(ctx, todo);
}
private CardBizState getBizState(TodoBusiness business, Todo todo) {
if (business.getBizCategory() == BizCategoryEnum.OTHER) {
if (todo.getState() == PendingMessageStateEnum.COMPLETED)
return CardBizState.COMPLETED;
if (todo.getState() == PendingMessageStateEnum.PROCESSING)
return CardBizState.IN_PROGRESS;
if (todo.getState() == PendingMessageStateEnum.RETRACT)
return CardBizState.REVOKED;
return null;
}
if (business.getBizFinalState() == BizFinalStateEnum.COMPLETED)
return CardBizState.COMPLETED;
if (business.getBizFinalState() == BizFinalStateEnum.RETRACT)
return CardBizState.REVOKED;
if (business.getBizFinalState() == BizFinalStateEnum.PASSED)
return CardBizState.AGREED;
if (business.getBizFinalState() == BizFinalStateEnum.REJECTED)
return CardBizState.REJECTED;
if (business.getBizFinalState() == BizFinalStateEnum.ABORTED)
return CardBizState.ABORTED;
return null;
}
void syncCardPresetButtonPressed(CardPresetButtonPressedMessage message) {
log.info("TodoSyncStateToCardService.onCardPresetButtonPressed: {}", message);
if(!APP_CODE.equals(message.getCardInfo().getAppCode())) {
if (!APP_CODE.equals(message.getCardInfo().getAppCode())) {
log.info("TodoSyncStateToCardService.onCardPresetButtonPressed: not msg-center:todo, message={}", message);
return;
}
String identityCode = message.getCardInfo().getBizParam().getString(TODO_IDENTITY_CODE_BIZ_PARAM_KEY);
String identityCode = message.getCardInfo()
.determineBizParam().getString(TODO_IDENTITY_CODE_BIZ_PARAM_KEY);
if (StringUtils.isBlank(identityCode)) {
log.warn("TodoSyncStateToCardService.onCardPresetButtonPressed: identityCode is blank, message={}", message);
return;
@ -217,8 +182,51 @@ class TodoSyncCardService {
request.setPresetButtonType(message.getPresetButtonType());
request.setOperatorId(message.getOperatorId());
request.setOperatorName(message.getOperatorName());
todoManager.firePresetButtonPressed(request, false);
todoLogger.logTodoUpdated(TodoRequestContext.create("syncCardState", message), todo);
TodoRequestContext ctx = TodoRequestContext.create("syncCardState", message);
try {
todoManager.firePresetButtonPressed(request, false);
todoLogger.logTodoUpdated(ctx, todo);
} catch (Exception e) {
todoLogger.logTodoUpdated(ctx.copy().addLogContent("exception", e), todo);
}
}
private static CardBizState determineCardBizStateForBizTodo(Todo todo) {
if (todo.getState() == PendingMessageStateEnum.COMPLETED)
return CardBizState.COMPLETED;
if (todo.getState() == PendingMessageStateEnum.PROCESSING)
return CardBizState.PROCESSING;
if (todo.getState() == PendingMessageStateEnum.RETRACT)
return CardBizState.REVOKED;
return null;
}
private static CardBizState determineCardBizStateForFlowTodo(TodoBusiness business) {
if (business.getBizFinalState() == BizFinalStateEnum.COMPLETED)
return CardBizState.COMPLETED;
if (business.getBizFinalState() == BizFinalStateEnum.RETRACT)
return CardBizState.REVOKED;
if (business.getBizFinalState() == BizFinalStateEnum.PASSED)
return CardBizState.AGREED;
if (business.getBizFinalState() == BizFinalStateEnum.REJECTED)
return CardBizState.REJECTED;
if (business.getBizFinalState() == BizFinalStateEnum.ABORTED)
return CardBizState.ABORTED;
return null;
}
public static Optional<BizCategoryEnum> findTodoBizCategory(JSONObject bizParam) {
if (bizParam == null)
return Optional.empty();
String category = bizParam.getString(TODO_CATEGORY_BIZ_PARAM_KEY);
return CodeDefinition.findByCode(BizCategoryEnum.class, category);
}
public static Optional<String> findTodoIdentityCode(JSONObject bizParam) {
if (bizParam == null)
return Optional.empty();
String identityCode = bizParam.getString(TODO_IDENTITY_CODE_BIZ_PARAM_KEY);
return Optional.ofNullable(identityCode);
}
}

View File

@ -0,0 +1,62 @@
package cn.axzo.msg.center.message.service.todo.card.flow;
import cn.axzo.msg.center.domain.entity.Todo;
import cn.axzo.msg.center.message.service.card.interceptor.CardButtonInterceptor;
import cn.axzo.msg.center.service.ButtonV3;
import cn.axzo.msg.center.service.enums.BizFinalStateEnum;
import cn.axzo.msg.center.service.enums.PendingMessageStateEnum;
import cn.axzo.msg.center.service.enums.RouterButtonSourceEnum;
import cn.axzo.msg.center.utils.desision.DecisionValue;
import lombok.RequiredArgsConstructor;
import java.util.Optional;
/**
* @author yanglin
*/
@RequiredArgsConstructor
class FlowTodoCardButtonInterceptor implements CardButtonInterceptor {
private final Todo todo;
@Override
public DecisionValue<Boolean> isPerformActionAvailable(ButtonV3 button) {
BizFinalStateEnum state = findPerformActionAvailableState(button).orElse(null);
if (state == null)
return DecisionValue.notSure();
return DecisionValue.decide(state.isEnableActionPerformed());
}
@Override
public DecisionValue<Boolean> isActionPerformed(ButtonV3 button) {
BizFinalStateEnum state = findPerformActionAvailableState(button).orElse(null);
if (state == null)
return DecisionValue.notSure();
//todo
return null;
}
@Override
public DecisionValue<String> getActionPerformedName(ButtonV3 button) {
BizFinalStateEnum state = findPerformActionAvailableState(button).orElse(null);
if (state == null)
return DecisionValue.notSure();
//todo
return DecisionValue.decide(state.getActionPerformedName());
}
@Override
public DecisionValue<Boolean> isVisibleOnCard(ButtonV3 button) {
if (button.getSource() == RouterButtonSourceEnum.SYSTEM
&& todo.getState() == PendingMessageStateEnum.PROCESSING)
return DecisionValue.decide(false);
return null;
}
private Optional<BizFinalStateEnum> findPerformActionAvailableState(ButtonV3 button) {
if (button.getSource() == RouterButtonSourceEnum.CUSTOM)
return Optional.empty();
return BizFinalStateEnum.findByButtonCode(button.getCode());
}
}

View File

@ -0,0 +1,42 @@
package cn.axzo.msg.center.message.service.todo.card.flow;
import cn.axzo.msg.center.dal.TodoDao;
import cn.axzo.msg.center.domain.entity.Todo;
import cn.axzo.msg.center.message.service.card.interceptor.CardButtonInterceptor;
import cn.axzo.msg.center.message.service.card.interceptor.CardButtonInterceptorFactory;
import cn.axzo.msg.center.message.service.todo.card.TodoSyncCardService;
import cn.axzo.msg.center.service.enums.BizCategoryEnum;
import cn.axzo.msg.center.service.pending.request.CardContent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Nullable;
/**
* @author yanglin
*/
@Slf4j
@Component
@RequiredArgsConstructor
class FlowTodoCardButtonInterceptorFactory implements CardButtonInterceptorFactory {
private final TodoDao todoDao;
@Override @Nullable
public CardButtonInterceptor create(CardContent card) {
String identityCode = TodoSyncCardService.findTodoIdentityCode(card.getBizParam()).orElse(null);
if (identityCode == null)
return null;
BizCategoryEnum category = TodoSyncCardService.findTodoBizCategory(card.getBizParam()).orElse(null);
if (category != BizCategoryEnum.FLOW)
return null;
Todo todo = todoDao.findTodoByCode(identityCode).orElse(null);
if (todo == null) {
log.warn("todo not found. identityCode={}", identityCode);
return null;
}
return new FlowTodoCardButtonInterceptor(todo);
}
}

View File

@ -3,6 +3,7 @@ package cn.axzo.msg.center.message.service.todo.manage;
import cn.axzo.msg.center.common.utils.BizAssertions;
import cn.axzo.msg.center.utils.UUIDUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Throwables;
import lombok.Getter;
import java.util.HashMap;
@ -62,8 +63,12 @@ public class TodoRequestContext {
public TodoRequestContext addLogContent(String name, Object value) {
if (name == null || value == null)
return this;
if (!logContents.containsKey(name))
logContents.put(name, value);
if (!logContents.containsKey(name)) {
if (value instanceof Throwable)
logContents.put(name, Throwables.getStackTraceAsString((Throwable) value));
else
logContents.put(name, value);
}
return this;
}

View File

@ -11,6 +11,7 @@ import cn.axzo.msg.center.message.service.todo.manage.TodoExt;
import cn.axzo.msg.center.mq.MqMessageRecord;
import cn.axzo.msg.center.mq.MqProducer;
import cn.axzo.msg.center.service.enums.MqMessageType;
import cn.axzo.msg.center.service.util.IdBuilder;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
@ -40,7 +41,11 @@ public class TodoMqBroadcaster {
mqProducer.send(MqMessageRecord
.builder(MqMessageType.TODO_STATE_UPDATE, message)
.messageKey(todo.getId())
.shardingKey(todo.getTemplateCode())
.shardingKey(IdBuilder.builder()
.append(todo.getTemplateCode())
.append(todo.getBizCode())
.append(todo.getSubBizCode())
.build())
.build());
}

View File

@ -157,7 +157,6 @@ public class RocketMQConfig {
@Override
public void onMessage(MessageExt message) {
log.info("CardChangeStateSyncTodoListener onMessage,message:{}", JSON.toJSONString(message));
super.onEvent(message, eventConsumer);
}
}

View File

@ -0,0 +1,8 @@
package cn.axzo.msg.center.utils.desision;
/**
* @author yanglin
*/
public enum Decision {
NOT_SURE, DECIDED
}

View File

@ -0,0 +1,36 @@
package cn.axzo.msg.center.utils.desision;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import java.util.function.Supplier;
/**
* @author yanglin
*/
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class DecisionValue<T> {
private static final DecisionValue<?> NOT_SURE = new DecisionValue<>(Decision.NOT_SURE, null);
private final Decision decision;
private final T value;
@SuppressWarnings("unchecked")
public static <T> DecisionValue<T> notSure() {
return (DecisionValue<T>)NOT_SURE;
}
public static <T> DecisionValue<T> decide(T value) {
return new DecisionValue<>(Decision.DECIDED, value);
}
public T orElse(Supplier<T> supplier) {
return decision == Decision.DECIDED ? value : supplier.get();
}
public T orElse(T value) {
return decision == Decision.DECIDED ? this.value : value;
}
}

View File

@ -148,4 +148,9 @@ public class CardInfo {
*/
private String subtitle;
public JSONObject determineBizParam() {
if (bizParam == null)
bizParam = new JSONObject();
return bizParam;
}
}

View File

@ -1,11 +1,12 @@
package cn.axzo.msg.center.service;
import cn.axzo.msg.center.service.enums.BizFinalStateEnum;
import cn.axzo.msg.center.service.enums.CodeDefinition;
import cn.axzo.msg.center.service.enums.ButtonStyleEnum;
import cn.axzo.msg.center.service.enums.PresetButtonType;
import cn.axzo.msg.center.service.enums.RouterButtonSourceEnum;
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
import java.util.List;
/**
* @author yanglin
*/
@ -27,19 +28,13 @@ public interface ButtonV3 {
RouterButtonSourceEnum getSource();
List<ButtonStyleEnum> getStyles();
default boolean determineIsPendingShow() {
return getPendingShow() != null && getPendingShow();
}
default boolean determineIsExecutorShow() {
return getExecutorShow() != null && getExecutorShow();
}
default boolean isPerformActionAvailable() {
if (getSource() == RouterButtonSourceEnum.SYSTEM) {
BizFinalStateEnum bizFinalState = CodeDefinition.findByCode(BizFinalStateEnum.class, getCode()).orElse(null);
return bizFinalState != null && bizFinalState.isEnableActionPerformed();
}
return determineIsPendingShow() || getCategory() == RouterCategoryEnum.PRESET_BUTTON;
}

View File

@ -3,6 +3,9 @@ package cn.axzo.msg.center.service.enums;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import java.util.Optional;
/**
* @author cold_blade
@ -17,30 +20,42 @@ public enum BizFinalStateEnum implements CodeDefinition<String> {
/**
* 已处理
*/
COMPLETED("", false, "https://static.axzo.cn/fe-static/uni-icon/public/seal-1%23_%241699341908382.png"),
COMPLETED("", "", "https://static.axzo.cn/fe-static/uni-icon/public/seal-1%23_%241699341908382.png"),
/**
* 已撤销
*/
RETRACT("BPMN_REVOCATION", true, "https://static.axzo.cn/fe-static/uni-icon/native/%E5%8E%9F%E7%A8%BF%23_%241711338477975.png"),
RETRACT("BPMN_REVOCATION", "已撤销", "https://static.axzo.cn/fe-static/uni-icon/native/%E5%8E%9F%E7%A8%BF%23_%241711338477975.png"),
/**
* 已通过
*/
PASSED("BPMN_APPROVE", true, "https://static.axzo.cn/fe-static/uni-icon/public/seal-4%23_%241699341908374.png"),
PASSED("BPMN_APPROVE", "已同意", "https://static.axzo.cn/fe-static/uni-icon/public/seal-4%23_%241699341908374.png"),
/**
* 已拒绝
*/
REJECTED("BPMN_REJECT", true, "https://static.axzo.cn/fe-static/uni-icon/public/seal-2%23_%241699341908381.png"),
REJECTED("BPMN_REJECT", "已驳回", "https://static.axzo.cn/fe-static/uni-icon/public/seal-2%23_%241699341908381.png"),
/**
* 已终止
*/
ABORTED("", false, "https://axzo-public.oss-cn-chengdu.aliyuncs.com/%E5%8D%B0%E7%AB%A0-%E8%AF%A6%E6%83%85end.png");
ABORTED("", "", "https://axzo-public.oss-cn-chengdu.aliyuncs.com/%E5%8D%B0%E7%AB%A0-%E8%AF%A6%E6%83%85end.png");
private final String buttonCode;
private final boolean enableActionPerformed;
private final String actionPerformedName;
private final String icon;
@Override
public String getCode() {
return name();
}
public static Optional<BizFinalStateEnum> findByButtonCode(String buttonCode) {
for (BizFinalStateEnum value : values()) {
if (value.buttonCode.equals(buttonCode))
return Optional.of(value);
}
return Optional.empty();
}
public boolean isEnableActionPerformed() {
return StringUtils.isNotBlank(actionPerformedName);
}
}

View File

@ -26,7 +26,7 @@ public enum CardBizState implements CodeDefinition<String> {
ABORTED("已中止", true, "https://axzo-public.oss-cn-chengdu.aliyuncs.com/msg-center/todo_card_state/card_biz_state_aborted_20241220.png"),
COMPLETED("已处理", true, "https://axzo-public.oss-cn-chengdu.aliyuncs.com/msg-center/todo_card_state/card_biz_state_completed_20241220.png"),
END("已完结", true, "https://axzo-public.oss-cn-chengdu.aliyuncs.com/msg-center/todo_card_state/card_biz_state_end_20241220.png"),
IN_PROGRESS("进行中", false, "https://axzo-public.oss-cn-chengdu.aliyuncs.com/msg-center/todo_card_state/card_biz_state_inprogress_20241220.png")
PROCESSING("进行中", false, "https://axzo-public.oss-cn-chengdu.aliyuncs.com/msg-center/todo_card_state/card_biz_state_inprogress_20241220.png")
;

View File

@ -11,15 +11,14 @@ import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public enum CardState implements CodeDefinition<String> {
CREATED("待处理"),
SEND_SUCCESS("发送成功"),
COMPLETED("已完成"),
CREATED("未发送"),
SEND_SUCCESS("待处理"),
COMPLETED("待处理"),
;
private final String name;
@Override
public String getCode() {
return name();

View File

@ -1,18 +0,0 @@
package cn.axzo.msg.center.service.pending.response;
import cn.axzo.msg.center.api.custombutton.ProposedButtons;
import cn.axzo.msg.center.service.dto.ButtonRouterDTO;
import java.util.List;
/**
* @author yanglin
*/
@Deprecated
public interface TodoButtonProvider {
List<ButtonRouterDTO> getButtonRouters();
ProposedButtons getProposedButtons();
}

View File

@ -103,13 +103,8 @@ public class ParsedButtonV3 implements MessageButton, ButtonV3 {
return priority == null ? Integer.MAX_VALUE : priority;
}
public List<ButtonStyleEnum> parseStyle() {
if (style == null) return Collections.emptyList();
return JSON.parseArray(style.toJSONString(), ButtonStyleEnum.class);
}
public boolean hasStyle(ButtonStyleEnum style) {
return parseStyle().contains(style);
return getStyles().contains(style);
}
@Override
@ -126,4 +121,10 @@ public class ParsedButtonV3 implements MessageButton, ButtonV3 {
public PresetButtonType getPresetBtnType() {
return presetButtonType;
}
@Override
public List<ButtonStyleEnum> getStyles() {
if (style == null) return Collections.emptyList();
return JSON.parseArray(style.toJSONString(), ButtonStyleEnum.class);
}
}

View File

@ -45,4 +45,8 @@ public class IdBuilder {
return buf.stream().map(String::valueOf).collect(joining(":"));
}
@Override
public String toString() {
return build();
}
}

View File

@ -3,6 +3,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.ButtonStyleEnum;
import cn.axzo.msg.center.service.enums.PresetButtonType;
import cn.axzo.msg.center.service.enums.RouterButtonSourceEnum;
import cn.axzo.msg.center.service.enums.RouterCategoryEnum;
@ -14,6 +15,9 @@ import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import lombok.Getter;
import lombok.Setter;
import java.util.Collections;
import java.util.List;
/**
* @author yanglin
*/
@ -102,6 +106,12 @@ public class MessageTemplateButtonV3 extends BaseEntityWithOperator<MessageTempl
return recordExt;
}
@Override
public List<ButtonStyleEnum> getStyles() {
if (style == null) return Collections.emptyList();
return JSON.parseArray(style.toJSONString(), ButtonStyleEnum.class);
}
@Setter
@Getter
public static class RecordExt {