Authored by wujiexiang

ufo砍价

... ... @@ -37,6 +37,10 @@ public class BuyerOrderChangeEvent extends OrderChangeEvent {
return buyerOrder;
}
public OrderStatus getTargetStatus() {
return targetStatus;
}
@Override
public String toShortString() {
return new StringBuilder(128).append("BuyerOrderChangeEvent[")
... ... @@ -48,6 +52,9 @@ public class BuyerOrderChangeEvent extends OrderChangeEvent {
}
public enum BizCase {
CANCEL_BYBUYER, CANCEL_BYCS, CANCEL_BYSYSAUTO, CANCEL_BYSELLER, PAY_SUCCESS;
//cancel
CANCEL_BYBUYER, CANCEL_BYCS, CANCEL_BYSYSAUTO, CANCEL_BYSELLER,
//paySuccess
PAY_SUCCESS;
}
}
... ...
... ... @@ -23,7 +23,7 @@ public abstract class OrderChangeEvent extends Event {
*
* @return
*/
abstract OrderCodeType getOrderCodeType();
public abstract OrderCodeType getOrderCodeType();
@Override
... ...
package com.yohoufo.order.service.listener;
import com.yohoufo.dal.order.BuyerOrderMetaMapper;
import com.yohoufo.dal.order.model.BuyerOrder;
import com.yohoufo.order.constants.ActivityTypeEnum;
import com.yohoufo.order.constants.MetaKey;
import com.yohoufo.order.event.BuyerOrderChangeEvent;
import com.yohoufo.order.event.OrderChangeEvent;
import com.yohoufo.order.model.bo.ActivityBo;
import com.yohoufo.order.service.proxy.BargainProxyService;
import com.yohoufo.order.service.support.BuyerOrderMetaMapperSupport;
import com.yohoufo.order.utils.LoggerUtils;
import org.slf4j.Logger;
import com.yohoufo.order.service.listener.processor.BuyerOrderChangeBusinessPostProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Objects;
/**
* Created by jiexiang.wu on 2019/5/23.
*/
@Component
public class BuyOrderChangeListener implements IOrderChangeListener<BuyerOrderChangeEvent> {
final private Logger logger = LoggerUtils.getBuyerOrderLogger();
@Autowired
private BuyerOrderMetaMapperSupport buyerOrderMetaMapperSupport;
@Autowired
private BargainProxyService bargainProxyService;
@Override
public boolean shouldHandle(OrderChangeEvent event) {
return event instanceof BuyerOrderChangeEvent;
}
private BuyerOrderChangeBusinessPostProcessor businessPostProcessor;
@Override
public void handleEvent(BuyerOrderChangeEvent buyerOrderChangeEvent) {
BuyerOrder buyerOrder = buyerOrderChangeEvent.getBuyerOrder();
if (Objects.equals(buyerOrder.getActivityType(), ActivityTypeEnum.BARGAIN.getCode())) {
//砍价订单
handleBargainOrderEvent(buyerOrderChangeEvent.getBizCase(), buyerOrder);
}
}
/**
* 砍价订单
*
* @param bizCase
* @param buyerOrder
*/
private void handleBargainOrderEvent(BuyerOrderChangeEvent.BizCase bizCase, BuyerOrder buyerOrder) {
ActivityBo activityBo = buyerOrderMetaMapperSupport.selectByMetaKey(buyerOrder.getUid(), buyerOrder.getOrderCode(), MetaKey.ACTIVITY_KEY, ActivityBo.class);
if (activityBo == null || activityBo.getUserActivityId() < 0) {
logger.warn("[{}] has no userActivityId for orderCode: {}", buyerOrder.getOrderCode());
return;
}
public void apply(BuyerOrderChangeEvent changeEvent) {
BuyerOrderChangeEvent.BizCase bizCase = changeEvent.getBizCase();
switch (bizCase) {
case CANCEL_BYSYSAUTO:
case CANCEL_BYBUYER:
case CANCEL_BYCS:
case CANCEL_BYSELLER:
bargainProxyService.cancelCutPriceUseRecord(buyerOrder.getUid(), buyerOrder.getOrderCode(), activityBo.getUserActivityId());
businessPostProcessor.cancel(changeEvent.getBuyerOrder(), changeEvent.getBizCase(), changeEvent.getTargetStatus());
break;
case PAY_SUCCESS:
bargainProxyService.payCutPrice(buyerOrder.getUid(), buyerOrder.getOrderCode(), activityBo.getUserActivityId());
businessPostProcessor.paySuccess(changeEvent.getBuyerOrder(), changeEvent.getBizCase(), changeEvent.getTargetStatus());
break;
default:
throw new IllegalStateException("unknown bizCase" + bizCase);
... ...
... ... @@ -7,7 +7,5 @@ import com.yohoufo.order.event.OrderChangeEvent;
*/
public interface IOrderChangeListener<T extends OrderChangeEvent> {
boolean shouldHandle(OrderChangeEvent event);
void handleEvent(T t);
void apply(T event);
}
\ No newline at end of file
... ...
package com.yohoufo.order.service.listener;
import com.google.common.eventbus.Subscribe;
import com.yohobuy.ufo.model.order.common.OrderCodeType;
import com.yohoufo.common.alarm.EventBusPublisher;
import com.yohoufo.common.alarm.IEventHandler;
import com.yohoufo.common.alarm.SmsAlarmEvent;
import com.yohoufo.order.event.BuyerOrderChangeEvent;
import com.yohoufo.order.event.OrderChangeEvent;
import com.yohoufo.order.utils.LoggerUtils;
import org.slf4j.Logger;
... ... @@ -22,7 +24,8 @@ public class OrderChangeListenerContainer implements IEventHandler<OrderChangeEv
final private Logger logger = LoggerUtils.getBuyerOrderLogger();
private List<IOrderChangeListener> listeners = new ArrayList<>();
//购买者监听器
private List<IOrderChangeListener> buyerListeners = new ArrayList<>();
@Autowired
private EventBusPublisher eventBusPublisher;
... ... @@ -33,7 +36,7 @@ public class OrderChangeListenerContainer implements IEventHandler<OrderChangeEv
@PostConstruct
public void initListener() {
listeners.add(buyOrderChangeListener);
buyerListeners.add(buyOrderChangeListener);
}
//触发异步处理
... ... @@ -44,21 +47,27 @@ public class OrderChangeListenerContainer implements IEventHandler<OrderChangeEv
@Override
@Subscribe
public void handle(OrderChangeEvent event) {
logger.info("handle order change event:{}", event);
if (event.getOrderCodeType() == OrderCodeType.BUYER_TYPE) {
buyerOrderChangeHandle((BuyerOrderChangeEvent) event, buyerListeners);
} else {
logger.warn("there is not any listener to handle event:{}", event);
}
}
private void buyerOrderChangeHandle(BuyerOrderChangeEvent event, List<IOrderChangeListener> listeners) {
logger.info("listeners apply buyerOrderChangeEvent:{}", event);
for (IOrderChangeListener listener : listeners) {
try {
if (listener.shouldHandle(event)) {
listener.handleEvent(event);
}
listener.apply(event);
} catch (Exception ex) {
logger.warn("handler:{} handle event:{} error", listener.getClass().getName(), event, ex);
logger.warn("{} apply buyerOrderChangeEvent:{} error", listener.getClass().getName(), event, ex);
//告警
EventBusPublisher.publishEvent(
new SmsAlarmEvent("ufo.orderChangeEvent", "handle_exception",
new SmsAlarmEvent("ufo.buyerOrderChangeEvent", "handle_exception",
listener.getClass().getName() + "(" + event.toShortString() + ")", ex)
);
}
}
logger.info("handle order change event end");
logger.info("listeners apply buyerOrderChangeEvent end");
}
}
... ...
package com.yohoufo.order.service.listener.processor;
import com.google.common.collect.Lists;
import com.yohobuy.ufo.model.order.common.OrderStatus;
import com.yohoufo.common.alarm.EventBusPublisher;
import com.yohoufo.common.alarm.SmsAlarmEvent;
import com.yohoufo.dal.order.model.BuyerOrder;
import com.yohoufo.order.constants.ActivityTypeEnum;
import com.yohoufo.order.constants.MetaKey;
import com.yohoufo.order.event.BuyerOrderChangeEvent;
import com.yohoufo.order.model.bo.ActivityBo;
import com.yohoufo.order.service.proxy.BargainProxyService;
import com.yohoufo.order.service.support.BuyerOrderMetaMapperSupport;
import com.yohoufo.order.utils.LoggerUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Objects;
/**
* Created by jiexiang.wu on 2019/5/24.
* 买家订单状态发生变化后,可以异步处理的业务逻辑,如
* 1.砍价订单需要通知活动模块
* 等等
*/
@Component
public class BuyerOrderChangeBusinessPostProcessor {
final private Logger logger = LoggerUtils.getBuyerOrderLogger();
@Autowired
private BuyerOrderMetaMapperSupport buyerOrderMetaMapperSupport;
@Autowired
private BargainProxyService bargainProxyService;
//业务处理器
private List<BusinessProcessor> processors = Lists.newArrayList(
//砍价
new BargainBusinessProcessor()
);
/**
* 取消业务
*
* @param buyerOrder
* @param bizCase
* @param targetStatus
*/
public void cancel(BuyerOrder buyerOrder, BuyerOrderChangeEvent.BizCase bizCase, OrderStatus targetStatus) {
BusinessProcessorContext context = buildBusinessProcessorContext(buyerOrder, bizCase, targetStatus);
for (BusinessProcessor processor : processors) {
try {
processor.cancel(context);
} catch (Exception ex) {
logger.warn("{} cancel error,context:{}", processor.getClass().getName(), context, ex);
//告警
EventBusPublisher.publishEvent(
new SmsAlarmEvent("ufo.buyerOrderBusinessPostProcessor", "cancel_exception",
processor.getClass().getName() + "(" + buyerOrder.getOrderCode() + ")", ex)
);
}
}
}
/**
* 支付成功
*
* @param buyerOrder
* @param bizCase
* @param targetStatus
*/
public void paySuccess(BuyerOrder buyerOrder, BuyerOrderChangeEvent.BizCase bizCase, OrderStatus targetStatus) {
BusinessProcessorContext context = buildBusinessProcessorContext(buyerOrder, bizCase, targetStatus);
for (BusinessProcessor processor : processors) {
try {
processor.paySuccess(context);
} catch (Exception ex) {
logger.warn("{} paySuccess error,context:{}", processor.getClass().getName(), context, ex);
//告警
EventBusPublisher.publishEvent(
new SmsAlarmEvent("ufo.buyerOrderBusinessPostProcessor", "paySuccess_exception",
processor.getClass().getName() + "(" + buyerOrder.getOrderCode() + ")", ex)
);
}
}
}
public BusinessProcessorContext buildBusinessProcessorContext(BuyerOrder buyerOrder, BuyerOrderChangeEvent.BizCase bizCase, OrderStatus targetStatus) {
BusinessProcessorContext context = new BusinessProcessorContext();
context.buyerOrder = buyerOrder;
context.bizCase = bizCase;
context.targetStatus = targetStatus;
//sql超时,会在listenerContainer层告警
context.activityBo = buyerOrderMetaMapperSupport.selectByMetaKey(buyerOrder.getUid(), buyerOrder.getOrderCode(), MetaKey.ACTIVITY_KEY, ActivityBo.class);
return context;
}
public static class BusinessProcessorContext {
public BuyerOrder buyerOrder;
public BuyerOrderChangeEvent.BizCase bizCase;
//事件发生后的状态,可能为null
public OrderStatus targetStatus;
//活动信息
public ActivityBo activityBo;
@Override
public String toString() {
return "BusinessProcessorContext{" +
"orderCode=" + buyerOrder.getOrderCode() +
", bizCase=" + bizCase +
", targetStatus=" + targetStatus +
'}';
}
}
/**
* 业务处理
* 按照业务归类如下:
* 取消
* 支付成功
* 等等
*/
private interface BusinessProcessor {
//取消
void cancel(BusinessProcessorContext context);
//支付成功
void paySuccess(BusinessProcessorContext context);
}
//砍价业务
private class BargainBusinessProcessor implements BusinessProcessor {
@Override
public void cancel(BusinessProcessorContext context) {
BuyerOrder buyerOrder = context.buyerOrder;
ActivityBo activityBo = context.activityBo;
if (shouldProcess(buyerOrder, activityBo)) {
bargainProxyService.cancelCutPriceUseRecord(buyerOrder.getUid(), buyerOrder.getOrderCode(), activityBo.getUserActivityId());
}
}
@Override
public void paySuccess(BusinessProcessorContext context) {
BuyerOrder buyerOrder = context.buyerOrder;
ActivityBo activityBo = context.activityBo;
if (shouldProcess(buyerOrder, activityBo)) {
bargainProxyService.payCutPrice(buyerOrder.getUid(), buyerOrder.getOrderCode(), activityBo.getUserActivityId());
}
}
public boolean shouldProcess(BuyerOrder buyerOrder, ActivityBo activityBo) {
if (!Objects.equals(buyerOrder.getActivityType(), ActivityTypeEnum.BARGAIN.getCode())) {
return false;
}
if (activityBo == null || activityBo.getUserActivityId() < 0) {
logger.warn("[{}] has no userActivityId", buyerOrder.getOrderCode());
return false;
}
return true;
}
}
}
... ...