自动补偿实现:
要求方法调用的过程中,失败的时候,系统有办法进行自动重试,重试达到一定次数后,钉钉通知开发。
实现设计:注解,反射,定时任务
自动一般涉及到定时任务。
钉钉群通知消息核心代码
钉钉群通知消息核心代码

application-local.yml
message:
config:
dingDistributeMessageBody: 新的订单来啦~\n用户id:%s\n设备类型:%s\nAPP版本:%s\n商品:%s\n实付:%s元\n支付方式:%s\n下单时间:%s\n首次分配时间:%s\n负责同事:%s
钉钉订单监听消息
@Slf4j
@Component
@SuppressWarnings("PMD")
public class DingOrderDistributeMessageListener implements MessageListener {
@Autowired
private MessageConfig messageConfig;
@Override
public Action consume(Message message, ConsumeContext consumeContext) {
try {
boolean notifyOpen = messageConfig.getNotifyDistributeOpen();
if (!notifyOpen) {
log.info("订单分配通知开关已关闭/未配置 messageOpen:{}", notifyOpen);
return Action.CommitMessage;
}
String dingWebHookUrl = messageConfig.getDingDistributeUrl();
String orderSecret = messageConfig.getDingDistributeSecret();
String messageBody = messageConfig.getDingDistributeMessageBody();
if (StringUtils.isEmpty(messageBody) || StringUtils.isEmpty(dingWebHookUrl)
|| StringUtils.isEmpty(orderSecret)) {
log.info("发送订单分配钉钉消息, 消息配置项未配置");
return Action.CommitMessage;
}
String requestBody = new String(message.getBody(), StandardCharsets.UTF_8);
DingOrderDistributeMessage orderMessage = JSONObject.parseObject(requestBody,
DingOrderDistributeMessage.class);
String sendMessage = String.format(messageBody, "\n", orderMessage.getCode() + "\n",
orderMessage.getDeviceType() + "\n", orderMessage.getAppVersion() + "\n",
orderMessage.getGoodsName() + "\n", orderMessage.getPayAmount() + "\n",
orderMessage.getPayType() + "\n", orderMessage.getPlaceTime() + "\n",
orderMessage.getDistributeTime() + "\n", orderMessage.getAdminUserName());
List<String> mobileList = new ArrayList<>();
if (StringUtils.isNotEmpty(orderMessage.getAdminUserPhone())) {
mobileList.add(orderMessage.getAdminUserPhone());
}
String dingMessage = DingMessageUtil.generateMessageBody(sendMessage, false, mobileList);
DingMessageUtil.sendMessage(orderSecret, dingMessage, dingWebHookUrl);
return Action.CommitMessage;
} catch (Exception e) {
log.error("发送报告钉钉消息出现异常:{}", e);
return Action.ReconsumeLater;
}
}
}
MessageConfig 是个实体类
@ConfigurationProperties(prefix = "message.config")
@Component
@Data
public class MessageConfig {
@ApiModelProperty("钉钉报告机密钥")
private String dingReportSecret;
@ApiModelProperty("钉钉报告地址")
private String dingReportUrl;
@ApiModelProperty("钉钉报告密钥")
private String dingOrderSecret;
@ApiModelProperty("钉钉订单消息图片地址")
private String dingOrderPicUrl;
@ApiModelProperty("钉钉订单消息头部")
private String dingOrderTitle;
@ApiModelProperty("订单钉钉报告地址")
private String dingOrderUrl;
@ApiModelProperty("订单路由地址")
private String orderRouteUrl;
@ApiModelProperty("钉钉订单消息体")
private String dingOrderMessageBody;
@ApiModelProperty("钉钉报告消息体")
private String dingReportMessageBody;
@ApiModelProperty("消息开关")
private Boolean notifyOpen;
@ApiModelProperty("钉钉日报")
private String dingDailyReportMessageBody;
@ApiModelProperty("订单分配通知开关")
private Boolean notifyDistributeOpen;
@ApiModelProperty("分配订单通知密钥")
private String dingDistributeSecret;
@ApiModelProperty("分配通知地址")
private String dingDistributeUrl;
@ApiModelProperty("订单分配消息主体")
private String dingDistributeMessageBody;
}
微服务实际去调用这钉钉消息
public void sendOrderDistributeMessage(Order order, String adminUserName, String adminUserPhone,
Date distributeTime) {
log.info("发送订单分配钉钉消息 order:{}, adminUserName:{}, adminUserPhone:{}, distributeTime:{}", order,
adminUserName, adminUserPhone, distributeTime);
Order dbOrder = orderService.getByOrderNo(order.getOrderNo());
OrderItemGoods goods = orderService.getOrderItemGoodsByOrderNo(order.getOrderNo());
DingOrderDistributeMessage orderMessage = new DingOrderDistributeMessage();
orderMessage.setGoodsName(goods.getGoodsName());
String suffix = "元";
String payType = dbOrder.getPayTypeChannel().getName();
PayTypeChannel payTypeChannel = dbOrder.getPayTypeChannel();
switch (payTypeChannel) {
case APPLE_IN:
payType = "苹果支付";
break;
case WX_MWEB:
case WX_APP:
case WX_JSAPI:
case WX_MICROPAY:
case WX_NATIVE:
payType = "微信";
break;
case SSCM:
suffix = "上上贝";
payType = "上上贝";
break;
case ALIPAY_PC:
case ALIPAY_QR:
case ALIPAY_WAP:
case ALIPAY_MOBILE:
payType = "支付宝";
break;
default:
break;
}
orderMessage.setPayType(payType);
orderMessage.setPayAmount(AmountUtils.changeFen2Yuan(order.getPayAmount()) + suffix);
orderMessage.setPlaceTime(DateUtils.formatYYYYMMDDHHMMSS(order.getPlaceTime()));
User user = userRemoteService.getById(order.getPlaceUserId()).getData();
orderMessage.setUserName(user.getUsername());
orderMessage.setCode(user.getCode());
orderMessage.setOrderNo(order.getOrderNo());
List<UserChannel> userChannelList = userRemoteService.getUserChannelList().getData();
Map<String, String> userChannelMap = userChannelList.stream()
.collect(Collectors.toMap(UserChannel::getChannelCode, UserChannel::getChannelName));
orderMessage.setDeviceType(userChannelMap.get(user.getChannelCode()));
orderMessage.setAppVersion(user.getVersionName());
orderMessage.setDistributeTime(DateUtils.formatYYYYMMDDHHMMSS(distributeTime));
orderMessage.setAdminUserName(adminUserName);
orderMessage.setAdminUserPhone(adminUserPhone);
mqSend.sendDingOrderDistributeMessage(orderMessage);
}
void sendDingOrderDistributeMessage(DingOrderDistributeMessage orderMessage);
@Override
public void sendDingOrderDistributeMessage(DingOrderDistributeMessage orderMessage) {
String message = JSON.toJSONString(orderMessage);
LOGGER.info("sendPayOrderMessage take success send message to mq message = {}", message);
producerUtil.sendAsyncMsg(orderConfig.getOrderTopic(), orderConfig.getOrderTopicDistributeDingTag(),
message, orderMessage.getOrderNo());
}
```
> 本文使用 [文章同步助手](https://juejin.cn/post/6940875049587097631) 同步