Authored by TANLING

极速优化

package com.yohoufo.order.event;
import com.yohobuy.ufo.model.order.resp.FastDeliveryReq;
import com.yohoufo.common.alarm.Event;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FastDeliveryChangeEvent extends Event {
FastDeliveryReq fastDeliveryReq;
Opt opt;
public enum Opt{
Delivery, Cancel
}
}
... ...
... ... @@ -27,6 +27,7 @@ import com.yohoufo.dal.order.model.*;
import com.yohoufo.order.constants.MetaKey;
import com.yohoufo.order.event.DeliverNoticeEvent;
import com.yohoufo.order.event.ErpBuyerOrderEvent;
import com.yohoufo.order.event.FastDeliveryChangeEvent;
import com.yohoufo.order.event.SellerCancelDeliverEvent;
import com.yohoufo.order.model.OperateTransferExpressInfo;
import com.yohoufo.order.model.dto.PreSaleOrderConfig;
... ... @@ -201,37 +202,13 @@ public class BuyerOrderPaymentService extends AbstractOrderPaymentService {
orderInfo.setStatus(orderStatusCode);
// 极速 不管是寄存还是发货 都需要通知卖家发货
if (fastDeliveryProxyService.isFastDeliveryGoods(orderInfo.getSkup())){
String wayBillCode = fastDeliveryProxyService.getVRWaybillCode(orderInfo.getOrderCode());
try{
retryer.call(()->{
// 同时生成物流单号,通知第三方发货
FastDeliveryReq fastDeliveryReq = FastDeliveryReq.builder()
.sellerUid(orderInfo.getSellerUid())
.skup(orderInfo.getSkup())
.waybillCode(wayBillCode)
.orderCode(orderInfo.getOrderCode())
.build();
fastDeliveryProxyService.delivery(fastDeliveryReq);
return null;
});
}catch (Exception e){
logger.warn("fast delivery delivery fail, e {}", e);
}
FastDeliveryChangeEvent fastDeliveryEvent = new FastDeliveryChangeEvent(FastDeliveryReq.builder()
.sellerUid(orderInfo.getSellerUid())
.skup(orderInfo.getSkup())
.orderCode(orderInfo.getOrderCode())
.build(), FastDeliveryChangeEvent.Opt.Delivery);
EventBusPublisher.publishEvent(fastDeliveryEvent);
// 卖家自动发货
executors.submit(()->{
SellerDeliverToDepotReq sdtdReq = SellerDeliverToDepotReq.builder()
.sellerUid(orderInfo.getSellerUid())
.orderCode(orderInfo.getOrderCode())
.wayBillCode(wayBillCode)
.depotNum(DepotType.NJ.getCode())
.expressCompanyId(0)
.build();
expressInfoService.deliverToDepot(sdtdReq);
});
}
return result;
}
... ...
package com.yohoufo.order.service.handler;
import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.github.rholder.retry.WaitStrategies;
import com.yohobuy.ufo.model.order.constants.DepotType;
import com.yohobuy.ufo.model.order.req.SellerDeliverToDepotReq;
import com.yohobuy.ufo.model.order.resp.FastDeliveryReq;
import com.yohoufo.common.alarm.CommonAlarmEventPublisher;
import com.yohoufo.common.alarm.IEventHandler;
import com.yohoufo.order.event.FastDeliveryChangeEvent;
import com.yohoufo.order.service.IExpressInfoService;
import com.yohoufo.order.service.proxy.FastDeliveryProxyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@Component
public class FastDeliveryChangeHandler implements IEventHandler<FastDeliveryChangeEvent> {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
FastDeliveryProxyService fastDeliveryProxyService;
Retryer<Void> retryer = RetryerBuilder.<Void>newBuilder()
.retryIfRuntimeException()
.withStopStrategy(StopStrategies.stopAfterAttempt(2))
.withWaitStrategy(WaitStrategies.fixedWait(50, TimeUnit.MILLISECONDS)).build();
private ExecutorService executors = Executors.newFixedThreadPool(1);
@Autowired
private IExpressInfoService expressInfoService;
@Override
public void handle(FastDeliveryChangeEvent event) {
if (event.getOpt() == null || event.getFastDeliveryReq()== null){
logger.warn("req required, please check param");
return;
}
if (!fastDeliveryProxyService.isFastDeliveryGoods(event.getFastDeliveryReq().getSkup())){
logger.info("skup is not fastDelivery, no need handle");
return;
}
switch (event.getOpt()){
case Delivery:
FastDeliveryReq fastDeliveryReq = event.getFastDeliveryReq();
// 生成虚拟单号
String wayBillCode = fastDeliveryProxyService.getVRWaybillCode(fastDeliveryReq.getOrderCode());
fastDeliveryReq.setWaybillCode(wayBillCode);
try{
retryer.call(()->{
fastDeliveryProxyService.delivery(fastDeliveryReq);
return null;
});
}catch (Exception e){
// 多次重试失败后,报警
CommonAlarmEventPublisher.publish("极速订单通知第三方发货", "fast.delivery.delivery", "sku:["+fastDeliveryReq.getSkup()+"]");
logger.warn("multi fast delivery delivery fail, alarm, e {}", e);
}
// 卖家自动发货
executors.submit(()->{
SellerDeliverToDepotReq sdtdReq = SellerDeliverToDepotReq.builder()
.sellerUid(fastDeliveryReq.getSellerUid())
.orderCode(fastDeliveryReq.getOrderCode())
.wayBillCode(wayBillCode)
.depotNum(DepotType.NJ.getCode())
.expressCompanyId(0)
.build();
expressInfoService.deliverToDepot(sdtdReq);
});
case Cancel:
try{
retryer.call(()->{
fastDeliveryProxyService.cancel(event.getFastDeliveryReq());
return null;
});
}catch (Exception e){
// 多次重试失败后,报警
CommonAlarmEventPublisher.publish("极速订单释放库存", "fast.delivery.cancel", "sku:["+event.getFastDeliveryReq().getSkup()+"]");
logger.warn("multi fast delivery cancel fail, alarm, e {}", e);
}
default:
logger.warn("no exist opt type, please check param");
}
}
}
... ...
... ... @@ -393,10 +393,10 @@ public class BuyerOrderCancelService {
inBoxFacade.buyerCancelBeforeDepotReceive(buyerOrder, penaltyAmount.toPlainString(), psog, useDepositGoods);
}
if (fastDeliveryProxyService.isFastDeliveryGoods(skup)) {
FastDeliveryReq req = FastDeliveryReq.builder().sellerUid(psog.getUid()).skup(skup).needReShelves(true).build();
fastDeliveryProxyService.cancel(req);
}
FastDeliveryChangeEvent fastDeliverEvent = new FastDeliveryChangeEvent(
FastDeliveryReq.builder().sellerUid(psog.getUid()).skup(skup).needReShelves(true).build(),
FastDeliveryChangeEvent.Opt.Cancel);
EventBusPublisher.publishEvent(fastDeliverEvent);
//整个过程异步去执行(考虑退费依赖订单状态)
//(退费)退保证金给卖家
... ... @@ -416,8 +416,6 @@ public class BuyerOrderCancelService {
EventBusPublisher.publishEvent(new UfoInfluxdbEvent(new UfoInfluxdbVo.Builder().setMeasurement(InfluxdbMeasurementEnum.MEASUREMENT_ORDER_CANCEL)
.addInitField(InfluxdbFieldEnum.FIELD_COUNT).build())); // 统计取消订单的次数
//
if (useDepositGoods) {
String depositCode = bdrEvent.getDepositCode();
logger.info("cancel buyer order Before Depot Receive trigger DepositGoodsCompensateAsyncEvent orderCode {} depositCode {}", orderCode, depositCode);
... ...
... ... @@ -452,15 +452,14 @@ public class BuyerOrderServiceImpl implements IBuyerOrderService {
boolean isReturnSuccess = productProxyService.returnStorage(skup);
// 急速发货的场合,取消订单
if (fastDeliveryProxyService.isFastDeliveryGoods(skup)){
fastDeliveryProxyService.cancel(FastDeliveryReq.builder().sellerUid(psog.getUid()).skup(skup).needReShelves(false).build());
}
FastDeliveryChangeEvent fastDeliverEvent = new FastDeliveryChangeEvent(
FastDeliveryReq.builder().sellerUid(psog.getUid()).skup(skup).needReShelves(false).build(),
FastDeliveryChangeEvent.Opt.Cancel);
EventBusPublisher.publishEvent(fastDeliverEvent);
//如有用券则退券
buyerOrderCancelService.asyncRefundCoupon(buyerUid, orderCode, BuyerRefundCouponEvent.BizCase.PAY_TIME_OUT);
//
inBoxFacade.noticSellerWhenBuyerCancel(sellerUid, psog);
buyerNoticeFacade.buyerCancelOrder(orderRequest.getUid(), orderCode);
... ...
package com.yohoufo.order.service.impl;
import com.yohobuy.ufo.model.order.resp.FastDeliveryReq;
import com.yohoufo.common.alarm.EventBusPublisher;
import com.yohoufo.order.event.FastDeliveryChangeEvent;
import com.yohoufo.order.model.dto.OrderBuilder;
import org.springframework.stereotype.Component;
@Component
public class FastDeliverySubmitServiceImpl extends SubmitOrderServiceImpl{
@Override
protected void subtractStorage(OrderBuilder orderBuilder) {
// 先减我方库存
super.subtractStorage(orderBuilder);
// 再减第三方库存,失败也无需恢复我方库存
FastDeliveryReq fastDeliveryReq = FastDeliveryReq.builder()
.price(orderBuilder.getSellerOrderGoods().getGoodsPrice())
.productCode(orderBuilder.getProductCode())
.sizeName(orderBuilder.getSellerOrderGoods().getSizeName())
.sellerUid(orderBuilder.getSellerOrderGoods().getUid())
.skup(orderBuilder.getSkup()).build();
fastDeliveryProxyService.lockSkup(fastDeliveryReq);
}
@Override
protected void returnStrorageEx(OrderBuilder orderBuilder) {
super.returnStrorageEx(orderBuilder);
FastDeliveryChangeEvent fastDeliverEvent = new FastDeliveryChangeEvent(
FastDeliveryReq.builder().sellerUid(orderBuilder.getUid()).skup(orderBuilder.getSkup()).needReShelves(false).build(),
FastDeliveryChangeEvent.Opt.Cancel);
EventBusPublisher.publishEvent(fastDeliverEvent);
}
}
... ...
package com.yohoufo.order.service.impl;
import com.yohobuy.ufo.model.order.common.OrderAttributes;
import com.yohoufo.order.service.ISubmitOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class OrderSubmitServiceFactory {
@Autowired
ISubmitOrderService ordeCreationService;
@Autowired
FastDeliverySubmitServiceImpl fastDeliverySubmitService;
public ISubmitOrderService getOrderSubmitService(Integer originalAttributes){
if (originalAttributes == OrderAttributes.FAST_DELIVERY.getCode()){
return fastDeliverySubmitService;
}else{
return ordeCreationService;
}
}
}
... ...
... ... @@ -82,7 +82,7 @@ public class ShoppingServiceImpl implements IShoppingService {
OrderCodeGenerator orderCodeGenerator;
@Autowired
ISubmitOrderService ordeCreationService;
OrderSubmitServiceFactory orderSubmitServiceFactory;
@Autowired
ServiceCaller serviceCaller;
... ... @@ -477,8 +477,9 @@ public class ShoppingServiceImpl implements IShoppingService {
DeliveryWayUtils::findDeliveryWayCodeBySkupType,
psog, chargeContext,
shoppingRequest.getBusinessClient());
ISubmitOrderService submitOrderService = orderSubmitServiceFactory.getOrderSubmitService(orderBuilder.getOriginalAttributes());
submitResult = ordeCreationService.doSubmitOrder(orderBuilder);
submitResult = submitOrderService.doSubmitOrder(orderBuilder);
}finally {
if(locked){
distributedLock.unlock();
... ...
... ... @@ -12,6 +12,7 @@ import com.yohobuy.ufo.model.order.common.OrderStatus;
import com.yohobuy.ufo.model.order.resp.FastDeliveryReq;
import com.yohobuy.ufo.model.promotion.response.promotionActivity.PromotionActivityRspBo;
import com.yohoufo.common.alarm.CommonAlarmEventPublisher;
import com.yohoufo.common.alarm.EventBusPublisher;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.dal.order.*;
import com.yohoufo.dal.order.model.*;
... ... @@ -84,21 +85,9 @@ public class SubmitOrderServiceImpl implements ISubmitOrderService {
BuyerOrderSubmitResult result = null;
try {
// 极速发货通知第三方
if (orderBuilder.getOriginalAttributes() == OrderAttributes.FAST_DELIVERY.getCode()){
FastDeliveryReq fastDeliveryReq = FastDeliveryReq.builder()
.price(orderBuilder.getSellerOrderGoods().getGoodsPrice())
.productCode(orderBuilder.getProductCode())
.sizeName(orderBuilder.getSellerOrderGoods().getSizeName())
.sellerUid(orderBuilder.getSellerOrderGoods().getUid())
.skup(orderBuilder.getSkup()).build();
fastDeliveryProxyService.lockSkup(fastDeliveryReq);
}
tryLockDepositGoodsIf(orderBuilder);
// 减库存
productProxyService.subtractStorage(orderBuilder.getProductId(), orderBuilder.getSkup());
subtractStorage(orderBuilder);
try{
... ... @@ -139,14 +128,19 @@ public class SubmitOrderServiceImpl implements ISubmitOrderService {
}
}
private void returnStrorageEx(OrderBuilder orderBuilder) {
protected void subtractStorage(OrderBuilder orderBuilder) {
// 减库存
productProxyService.subtractStorage(orderBuilder.getProductId(), orderBuilder.getSkup());
}
protected void returnStrorageEx(OrderBuilder orderBuilder) {
try{
// 还库存
productProxyService.returnStorage(orderBuilder.getSkup());
if (fastDeliveryProxyService.isFastDeliveryGoods(orderBuilder.getSkup())){
fastDeliveryProxyService.cancel(FastDeliveryReq.builder().sellerUid(orderBuilder.getUid()).skup(orderBuilder.getSkup()).needReShelves(false).build());
}
}catch (Exception ex0){
CommonAlarmEventPublisher.publish("还库存失败", "ufo.product.cancelSaleSkup", "sku:["+orderBuilder.getSkup()+"]");
... ...
... ... @@ -7,6 +7,7 @@ import com.yohoufo.common.ApiResponse;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.order.utils.LoggerUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
... ... @@ -21,7 +22,7 @@ import java.util.concurrent.TimeUnit;
@Component
public class BaseServiceCaller {
private final static Logger logger = LoggerUtils.getBuyerOrderLogger();
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private ServiceCaller serviceCaller;
... ...