Authored by wujiexiang

Merge branch 'dev_bargain' into test6.9.5

... ... @@ -23,11 +23,12 @@
<result column="seller_delivery_status" jdbcType="INTEGER" property="sellerDeliveryStatus" />
<result column="seller_delivery_deal" jdbcType="INTEGER" property="sellerDeliveryDeal" />
<result column="seller_delivery_deal_again" jdbcType="INTEGER" property="sellerDeliveryDealAgain" />
<result column="activity_type" jdbcType="INTEGER" property="activityType" />
</resultMap>
<sql id="Base_Column_List">
id, uid, order_code, seller_uid, client_type, payment, payment_type, is_cancel, amount,
ship_fee, status, create_time, update_time, buyer_order_status, seller_order_status, channel_no, attributes,platform_delivery_status,
seller_delivery_status,seller_delivery_deal,seller_delivery_deal_again
seller_delivery_status,seller_delivery_deal,seller_delivery_deal_again,activity_type
</sql>
... ...
package com.yohoufo.order.event;
import com.yohobuy.ufo.model.order.common.OrderCodeType;
import com.yohobuy.ufo.model.order.common.OrderStatus;
import com.yohoufo.dal.order.model.BuyerOrder;
/**
* Created by jiexiang.wu on 2019/5/23.
*/
public class BuyerOrderChangeEvent extends OrderChangeEvent {
private BuyerOrder buyerOrder;
private BizCase bizCase;
//事件发生后的状态,可能为null
private OrderStatus targetStatus;
public BuyerOrderChangeEvent(BuyerOrder buyerOrder, BizCase bizCase) {
this(buyerOrder, bizCase, null);
}
public BuyerOrderChangeEvent(BuyerOrder buyerOrder, BizCase bizCase, OrderStatus targetStatus) {
this.buyerOrder = buyerOrder;
this.bizCase = bizCase;
this.targetStatus = targetStatus;
}
... ... @@ -30,7 +37,17 @@ public class BuyerOrderChangeEvent extends OrderChangeEvent {
return buyerOrder;
}
public enum BizCase {
@Override
public String toShortString() {
return new StringBuilder(128).append("BuyerOrderChangeEvent[")
.append("uid=").append(buyerOrder.getUid())
.append(",orderCode=").append(buyerOrder.getOrderCode())
.append(",bizCase=").append(bizCase)
.append(",targetStatus=").append(targetStatus == null ? -999 : targetStatus.getCode())
.append("]").toString();
}
public enum BizCase {
CANCEL_BYBUYER, CANCEL_BYCS, CANCEL_BYSYSAUTO, CANCEL_BYSELLER, PAY_SUCCESS;
}
}
... ...
... ... @@ -2,18 +2,33 @@ package com.yohoufo.order.event;
import com.yohobuy.ufo.model.order.common.OrderCodeType;
import com.yohoufo.common.alarm.Event;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
/**
* Created by jiexiang.wu on 2019/5/23.
* 订单状态发生变化后,有很多事情需要处理,其他有一些可以异步处理,异步服务可以对该类事件进行监控
* @implNote 该直接只能被OrderChangeListenerContainer处理
*/
public abstract class OrderChangeEvent extends Event {
/**
* 简单描述
*
* @return
*/
public abstract String toShortString();
/**
* 订单类型:买家、卖家
*
* @return
*/
abstract OrderCodeType getOrderCodeType();
@Override
public String toString() {
return ReflectionToStringBuilder.toString(this);
}
}
... ...
... ... @@ -3,6 +3,7 @@ package com.yohoufo.order.model.bo;
import lombok.Builder;
import lombok.Data;
import lombok.ToString;
import java.math.BigDecimal;
/**
... ... @@ -18,4 +19,14 @@ public class ActivityBo {
private int activityType;
//减免金额
private BigDecimal activityCutAmount;
//json需要
public ActivityBo() {
}
public ActivityBo(int userActivityId, int activityType, BigDecimal activityCutAmount) {
this.userActivityId = userActivityId;
this.activityType = activityType;
this.activityCutAmount = activityCutAmount;
}
}
... ...
... ... @@ -17,6 +17,7 @@ import com.yohoufo.dal.order.BuyerOrderMetaMapper;
import com.yohoufo.dal.order.SellerOrderGoodsMapper;
import com.yohoufo.dal.order.model.*;
import com.yohoufo.order.constants.MetaKey;
import com.yohoufo.order.event.BuyerOrderChangeEvent;
import com.yohoufo.order.event.DeliverNoticeEvent;
import com.yohoufo.order.event.ErpBuyerOrderEvent;
import com.yohoufo.order.event.SellerCancelDeliverEvent;
... ... @@ -28,6 +29,7 @@ import com.yohoufo.order.service.cache.CacheCleaner;
import com.yohoufo.order.service.cache.CacheKeyBuilder;
import com.yohoufo.order.service.impl.MetaConfigService;
import com.yohoufo.order.service.impl.OrderOverTimeService;
import com.yohoufo.order.service.listener.OrderChangeListenerContainer;
import com.yohoufo.order.service.proxy.DeliveryMinutesService;
import com.yohoufo.order.service.proxy.InBoxFacade;
import com.yohoufo.order.service.proxy.OrderStatusFlowService;
... ... @@ -80,6 +82,9 @@ public class BuyerOrderPaymentService extends AbstractOrderPaymentService {
@Autowired
private OrderOverTimeService orderOverTimeService;
@Autowired
private OrderChangeListenerContainer orderChangeListenerContainer;
/**
* 更新订单状态
* @param orderInfo
... ... @@ -169,6 +174,12 @@ public class BuyerOrderPaymentService extends AbstractOrderPaymentService {
Integer uid = orderInfo.getUid();
Integer sellerUid = orderInfo.getSellerUid();
long orderCode = orderInfo.getOrderCode();
BuyerOrder buyerOrder = buyerOrderMapper.selectByOrderCode(orderCode);
//订单事件
orderChangeListenerContainer.fireAsyncEvent(new BuyerOrderChangeEvent(buyerOrder, BuyerOrderChangeEvent.BizCase.PAY_SUCCESS));
// 通知卖家发货
BuyerOrderGoods buyerOrderGoods = buyerOrderGoodsMapper.selectByOrderCode(uid, orderCode);
int skup = buyerOrderGoods.getSkup();
... ...
... ... @@ -38,6 +38,7 @@ import com.yohoufo.order.service.handler.RefundGoodsMoneyHandler;
import com.yohoufo.order.service.handler.penalty.PenaltyResult;
import com.yohoufo.order.service.handler.penalty.SellerEarnestMoney2BuyerPenaltyCalculator;
import com.yohoufo.order.service.impl.function.BuyerNoticeSender;
import com.yohoufo.order.service.listener.OrderChangeListenerContainer;
import com.yohoufo.order.service.proxy.InBoxFacade;
import com.yohoufo.order.service.proxy.OrderOperateRecordService;
import com.yohoufo.order.service.proxy.OrderStatusFlowService;
... ... @@ -130,6 +131,9 @@ public class AppraiseService {
@Autowired
private ProductMapper productMapper;
@Autowired
private OrderChangeListenerContainer orderChangeListenerContainer;
@Resource(name = "tradeMqProducer")
private YhProducer tradeMqProducer;
... ... @@ -1365,6 +1369,7 @@ public class AppraiseService {
.withRefundCoupon(BuyerRefundCouponEvent.BizCase.APPRAISE_UNSURE)
.withCacheCleaner(cacheCleaner::delete)
.withFailAlarm(AlarmConfig.APPRAISE_UNSURE)
.withOrderChangeListenerContainer(orderChangeListenerContainer)
.cancel();
}
... ...
... ... @@ -22,6 +22,7 @@ import com.yohoufo.order.common.RefundCase;
import com.yohoufo.order.common.TransferCase;
import com.yohoufo.order.constants.AlarmConfig;
import com.yohoufo.order.event.BillLogEvent;
import com.yohoufo.order.event.BuyerOrderChangeEvent;
import com.yohoufo.order.event.BuyerRefundCouponEvent;
import com.yohoufo.order.model.request.PaymentRequest;
import com.yohoufo.order.model.request.TranseferCellNode;
... ... @@ -32,6 +33,7 @@ import com.yohoufo.order.service.handler.penalty.SellerEarnestMoney2BuyerPenalty
import com.yohoufo.order.service.impl.function.BuyerNoticeSender;
import com.yohoufo.order.service.impl.function.RecordSuppleExpressSender;
import com.yohoufo.order.service.impl.function.SellerNoticeSender;
import com.yohoufo.order.service.listener.OrderChangeListenerContainer;
import com.yohoufo.order.service.proxy.OrderStatusFlowService;
import lombok.Data;
import lombok.experimental.Accessors;
... ... @@ -89,6 +91,8 @@ class BuyerOrderCancelHandler {
private Consumer<List<RedisKeyBuilder>> cacheCleaner;
private OrderChangeListenerContainer orderChangeListenerContainer;
BuyerOrderCancelHandler(int uid, long orderCode) {
this.uid = uid;
this.orderCode = orderCode;
... ... @@ -155,6 +159,16 @@ class BuyerOrderCancelHandler {
return this;
}
/**
* 异步事件
* @param orderChangeListenerContainer
* @return
*/
public BuyerOrderCancelHandler withOrderChangeListenerContainer(OrderChangeListenerContainer orderChangeListenerContainer) {
this.orderChangeListenerContainer = orderChangeListenerContainer;
return this;
}
public void cancel() {
log.info("cancel order {} from {} to {}", orderCode, expectStatus, targetStatus);
verify();
... ... @@ -191,6 +205,8 @@ class BuyerOrderCancelHandler {
noticeSeller(sellerOrderGoods);
noticeBuyer(buyerOrder, buyerOrderGoods);
cleanCache(buyerOrder, sellerOrderGoods);
//取消事件
fireAsyncEvent(buyerOrder);
} else {
log.info("cancel order {} fail, order status has changed", orderCode);
throwServiceException("当前状态不可取消订单");
... ... @@ -422,6 +438,14 @@ class BuyerOrderCancelHandler {
}
}
/**
* 订单取消异步事件
* @param buyerOrder
*/
public void fireAsyncEvent(BuyerOrder buyerOrder) {
orderChangeListenerContainer.fireAsyncEvent(new BuyerOrderChangeEvent(buyerOrder, BuyerOrderChangeEvent.BizCase.CANCEL_BYCS, targetStatus));
}
@Data
@Accessors(fluent = true)
class RefundEarnestMoney {
... ...
... ... @@ -29,6 +29,7 @@ import com.yohoufo.order.service.concurrent.ThreadPoolFactory;
import com.yohoufo.order.service.handler.BuyerCancelCompensateComputeHandler;
import com.yohoufo.order.service.handler.RefundEarnestMoneyHandler;
import com.yohoufo.order.service.handler.RefundGoodsMoneyHandler;
import com.yohoufo.order.service.listener.OrderChangeListenerContainer;
import com.yohoufo.order.service.proxy.CouponProxyService;
import com.yohoufo.order.service.proxy.InBoxFacade;
import com.yohoufo.order.service.proxy.OrderStatusFlowService;
... ... @@ -98,6 +99,8 @@ public class BuyerOrderCancelService {
@Autowired
private OrderStatusFlowService orderStatusFlowService;
@Autowired
private OrderChangeListenerContainer orderChangeListenerContainer;
public void cancel(BeforeSellerDeliverEvent bsdEvent){
int buyerUid = bsdEvent.getBuyerUid();
... ... @@ -209,6 +212,7 @@ public class BuyerOrderCancelService {
.withRefundCoupon(BuyerRefundCouponEvent.BizCase.SELLER_DELIVER_TIMEOUT)
.withCacheCleaner(cacheCleaner::delete)
.withFailAlarm(AlarmConfig.DELIVER_TIME_OUT)
.withOrderChangeListenerContainer(orderChangeListenerContainer)
.cancel();
}
... ... @@ -231,6 +235,7 @@ public class BuyerOrderCancelService {
.withRefundCoupon(BuyerRefundCouponEvent.BizCase.SELLER_SHAM_SEND_OUT)
.withCacheCleaner(cacheCleaner::delete)
.withFailAlarm(AlarmConfig.SELLER_SHAM_SEND_OUT)
.withOrderChangeListenerContainer(orderChangeListenerContainer)
.cancel();
}
... ...
... ... @@ -39,6 +39,7 @@ import com.yohoufo.order.service.cache.CacheCleaner;
import com.yohoufo.order.service.cache.CacheKeyBuilder;
import com.yohoufo.order.service.cache.OrderCacheService;
import com.yohoufo.order.service.handler.BuyerCancelCompensateComputeHandler;
import com.yohoufo.order.service.listener.OrderChangeListenerContainer;
import com.yohoufo.order.service.pay.AbstractPayService;
import com.yohoufo.order.service.proxy.InBoxFacade;
import com.yohoufo.order.service.proxy.OrderStatusFlowService;
... ... @@ -110,6 +111,9 @@ public class BuyerOrderServiceImpl implements IBuyerOrderService {
@Autowired
private ProductMapper productMapper;
@Autowired
private OrderChangeListenerContainer orderChangeListenerContainer;
/**
* 提交订单
... ... @@ -346,6 +350,9 @@ public class BuyerOrderServiceImpl implements IBuyerOrderService {
DataNode node = checkBase(orderRequest);
cancelBeforePaid(orderRequest, node, expectStatus, targetStatus);
//取消事件
orderChangeListenerContainer.fireAsyncEvent(new BuyerOrderChangeEvent(node.buyerOrderInDB, BuyerOrderChangeEvent.BizCase.CANCEL_BYSYSAUTO, targetStatus));
//记录状态变更信息
logger.info("in cancelByAuto record status change, orderRequest {}", orderRequest);
orderStatusFlowService.addAsy(orderRequest.getOrderCode(),targetStatus.getCode());
... ... @@ -370,6 +377,8 @@ public class BuyerOrderServiceImpl implements IBuyerOrderService {
targetStatus = OrderStatus.BUYER_CANCEL_BEFORE_PAY;
cancelBeforePaid(orderRequest, node, expectStatus, targetStatus);
orderChangeListenerContainer.fireAsyncEvent(new BuyerOrderChangeEvent(buyerOrder, BuyerOrderChangeEvent.BizCase.CANCEL_BYBUYER, targetStatus));
//记录状态变更信息
logger.info("in doCancel record status WAITING_PAY change, orderRequest {}", orderRequest);
orderStatusFlowService.addAsy(buyerOrder.getOrderCode(),targetStatus.getCode());
... ... @@ -385,6 +394,9 @@ public class BuyerOrderServiceImpl implements IBuyerOrderService {
.amount(buyerOrder.getAmount())
.build();
buyerOrderCancelService.cancel(bsde);
orderChangeListenerContainer.fireAsyncEvent(new BuyerOrderChangeEvent(buyerOrder, BuyerOrderChangeEvent.BizCase.CANCEL_BYBUYER, targetStatus));
//记录状态变更信息
logger.info("in doCancel record status HAS_PAYED change, orderRequest {}", orderRequest);
orderStatusFlowService.addAsy(buyerOrder.getOrderCode(),targetStatus.getCode());
... ... @@ -400,6 +412,10 @@ public class BuyerOrderServiceImpl implements IBuyerOrderService {
.amount(buyerOrder.getAmount())
.build();
buyerOrderCancelService.cancel(bdre);
//取消事件
orderChangeListenerContainer.fireAsyncEvent(new BuyerOrderChangeEvent(buyerOrder, BuyerOrderChangeEvent.BizCase.CANCEL_BYBUYER, targetStatus));
//记录状态变更信息
logger.info("in doCancel record status HAS_PAYED change, orderRequest {}", orderRequest);
orderStatusFlowService.addAsy(buyerOrder.getOrderCode(),targetStatus.getCode());
... ...
... ... @@ -37,6 +37,7 @@ import com.yohoufo.order.service.handler.RefundGoodsMoneyHandler;
import com.yohoufo.order.service.handler.penalty.PenaltyResult;
import com.yohoufo.order.service.handler.penalty.SellerEarnestMoney2BuyerPenaltyCalculator;
import com.yohoufo.order.service.impl.visitor.*;
import com.yohoufo.order.service.listener.OrderChangeListenerContainer;
import com.yohoufo.order.service.pay.AbstractPayService;
import com.yohoufo.order.service.proxy.InBoxFacade;
import com.yohoufo.order.service.proxy.OrderStatusFlowService;
... ... @@ -125,6 +126,10 @@ public class SellerOrderCancelService {
@Autowired
private SellerGoodsStatusFlowService sellerGoodsStatusFlowService;
@Autowired
private OrderChangeListenerContainer orderChangeListenerContainer;
/**
* TODO 如何控制好并发,必须控制不能重复转账 退款
* 使用乐观锁,带着查询到的状态且符合条件时再去更新
... ... @@ -544,6 +549,10 @@ public class SellerOrderCancelService {
BuyerRefundCouponEvent brce = BuyerRefundCouponEvent.builder().bizCase(BuyerRefundCouponEvent.BizCase.SELLER_PLAY_BUYER)
.uid(buyerUid).orderCode(buyerOrderCode).build();
EventBusPublisher.publishEvent(brce);
//取消事件
orderChangeListenerContainer.fireAsyncEvent(new BuyerOrderChangeEvent(buyerOrder, BuyerOrderChangeEvent.BizCase.CANCEL_BYSELLER, targetBOStatus));
//清理买家、卖家订单相关缓存
SellerOrderGoods psog = sellerOrderGoodsMapper.selectByPrimaryKey(sellerOrder.getSkup());
cacheCleaner.delete(Arrays.asList(CacheKeyBuilder.orderListKey(sellerUid, TabType.SELL.getValue()),
... ...
package com.yohoufo.order.service.impl;
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.service.IOrderChangeListener;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Objects;
... ... @@ -13,25 +21,53 @@ import java.util.Objects;
*/
@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;
}
@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;
}
switch (bizCase) {
//处理
case CANCEL_BYSYSAUTO:
case CANCEL_BYBUYER:
case CANCEL_BYCS:
case CANCEL_BYSELLER:
bargainProxyService.cancelCutPriceUseRecord(buyerOrder.getUid(), buyerOrder.getOrderCode(), activityBo.getUserActivityId());
break;
case PAY_SUCCESS:
bargainProxyService.payCutPrice(buyerOrder.getUid(), buyerOrder.getOrderCode(), activityBo.getUserActivityId());
break;
default:
throw new IllegalStateException("unknown bizCase" + bizCase);
}
}
}
}
\ No newline at end of file
... ...
package com.yohoufo.order.service;
package com.yohoufo.order.service.listener;
import com.yohoufo.order.event.OrderChangeEvent;
... ... @@ -7,5 +7,7 @@ import com.yohoufo.order.event.OrderChangeEvent;
*/
public interface IOrderChangeListener<T extends OrderChangeEvent> {
boolean shouldHandle(OrderChangeEvent event);
void handleEvent(T t);
}
\ No newline at end of file
... ...
package com.yohoufo.order.service.impl;
package com.yohoufo.order.service.listener;
import com.google.common.eventbus.Subscribe;
import com.yohoufo.common.alarm.EventBusPublisher;
import com.yohoufo.common.alarm.IEventHandler;
import com.yohoufo.common.alarm.SmsAlarmEvent;
import com.yohoufo.order.event.OrderChangeEvent;
import com.yohoufo.order.service.IOrderChangeListener;
import com.yohoufo.order.utils.LoggerUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -37,22 +37,25 @@ public class OrderChangeListenerContainer implements IEventHandler<OrderChangeEv
}
//触发异步处理
public void fireAsycEvent(OrderChangeEvent event) {
public void fireAsyncEvent(OrderChangeEvent event) {
eventBusPublisher.publishEvent(event);
}
@Override
@Subscribe
public void handle(OrderChangeEvent event) {
logger.info("handle order change event:{}", event);
for (IOrderChangeListener listener : listeners) {
try {
listener.handleEvent(event);
if (listener.shouldHandle(event)) {
listener.handleEvent(event);
}
} catch (Exception ex) {
logger.warn("handler:{} handle event:{} error", listener.getClass().getName(), event, ex);
//告警
EventBusPublisher.publishEvent(
new SmsAlarmEvent("ufo.orderChangeEvent", "handle_exception",
listener.getClass().getName() + "(" + event.toString() + ")", ex)
listener.getClass().getName() + "(" + event.toShortString() + ")", ex)
);
}
}
... ...
... ... @@ -38,7 +38,7 @@ public abstract class AbsServiceCaller {
throw e;
} catch (Exception e) {
logger.warn("doPost fail, url is {} object is {}", url, object, e);
return new ApiResponse.ApiResponseBuilder().code(500).message("服务访问异常").build();
throw e;
}
}
... ...
package com.yohoufo.order.service.support;
import com.alibaba.fastjson.JSON;
import com.yohoufo.dal.order.BuyerOrderMetaMapper;
import com.yohoufo.dal.order.model.BuyerOrderMeta;
import com.yohoufo.order.utils.LoggerUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Created by jiexiang.wu on 2019/5/23.
*/
@Component
public class BuyerOrderMetaMapperSupport {
private final static Logger logger = LoggerUtils.getBuyerOrderLogger();
@Autowired
BuyerOrderMetaMapper buyerOrderMetaMapper;
public <T> T selectByMetaKey(int uid, long orderCode, String metaKey, Class<T> clazz) {
BuyerOrderMeta orderMeta = buyerOrderMetaMapper.selectByMetaKey(uid, orderCode, metaKey);
if (orderMeta == null) {
logger.warn("no orderMeta for orderCode: {}, uid: {}, metaKey: {}", orderCode, uid, metaKey);
return null;
}
return JSON.parseObject(orderMeta.getMetaValue(), clazz);
}
}
... ...