没有显示处理model.WaybillStatusCourierArrived事件,导致TIMER没有停掉,又执行了在第3方门店创建运单操作。(改为只要收到了大于NEW的运单事件,都将TIMER停掉,状态需要添加TIMER的,再自行添加)

然后createWaybillOn3rdProviders又没有判断状态,导致又重新创建运单(添加状态判断,另外将所有TIMER事件中的逻辑都添加状态判断,合适后才真正执行)
This commit is contained in:
gazebo
2018-07-24 15:50:24 +08:00
parent a5baa5c46e
commit ca9bf8f0a3
3 changed files with 104 additions and 75 deletions

View File

@@ -214,7 +214,7 @@ func (c *WaybillController) getMTPSShopID(order *model.GoodsOrder, db orm.Ormer)
retVal = "test_0001"
}
} else {
globals.SugarLogger.Errorf("getMTPSShopID can not find mtps store info for orderID:%s, store:%d, num:%d, error:%v", order.VendorOrderID, JxStoreID, num, err)
globals.SugarLogger.Infof("getMTPSShopID can not find mtps store info for orderID:%s, store:%d, num:%d, error:%v", order.VendorOrderID, JxStoreID, num, err)
if err == nil {
err = ErrCanNotFindMTPSStore
}

View File

@@ -92,31 +92,28 @@ func (s *DefScheduler) OnOrderNew(order *model.GoodsOrder) (err error) {
func (s *DefScheduler) OnOrderStatusChanged(status *model.OrderStatus) (err error) {
if status.Status > model.OrderStatusUnknown { // 只处理状态转换,一般消息不处理
globals.SugarLogger.Debugf("OnOrderStatusChanged, status:%v", status)
if savedOrderInfo := s.loadSavedOrderFromMap(status); savedOrderInfo != nil {
s.updateOrderByStatus(savedOrderInfo.order, status)
if status.Status > model.OrderStatusUnknown && status.Status < model.OrderStatusEndBegin {
if !(status.Status == model.OrderStatusFinishedPickup && len(savedOrderInfo.waybills) > 0) { //饿了么还观察到运单消息早于拣货完成消息
gap := 0 * time.Second
beginTime := status.StatusTime
if status.Status == model.OrderStatusNew {
beginTime = time.Now()
} else if status.Status == model.OrderStatusAccepted {
gap = time.Duration(rand.Int63n(int64(time2AutoPickupGap)))
beginTime = s.getBeginTime4LatestPickup(savedOrderInfo.order)
} else if status.Status == model.OrderStatusFinishedPickup {
// 召唤三方配送
// 正常应该是只依赖于购物平台的第一个运单消息但饿了么有观察到极少数情况下没有此事件所以还是需要在这里加个保险的TIMER来驱动运单调度
gap = time2Schedule3rdCarrierGap4OrderStatus
}
s.resetTimer(savedOrderInfo, status.Status, beginTime, gap)
savedOrderInfo := s.loadSavedOrderFromMap(status)
s.updateOrderByStatus(savedOrderInfo.order, status)
if status.Status > model.OrderStatusUnknown && status.Status < model.OrderStatusEndBegin {
if !(status.Status == model.OrderStatusFinishedPickup && len(savedOrderInfo.waybills) > 0) { //饿了么还观察到运单消息早于拣货完成消息
gap := 0 * time.Second
beginTime := status.StatusTime
if status.Status == model.OrderStatusNew {
beginTime = time.Now()
} else if status.Status == model.OrderStatusAccepted {
gap = time.Duration(rand.Int63n(int64(time2AutoPickupGap)))
beginTime = s.getBeginTime4LatestPickup(savedOrderInfo.order)
} else if status.Status == model.OrderStatusFinishedPickup {
// 召唤三方配送
// 正常应该是只依赖于购物平台的第一个运单消息但饿了么有观察到极少数情况下没有此事件所以还是需要在这里加个保险的TIMER来驱动运单调度
gap = time2Schedule3rdCarrierGap4OrderStatus
}
} else {
s.stopTimer(savedOrderInfo)
s.cancelOtherWaybills(savedOrderInfo, nil)
s.orderMap.Delete(jxutils.GetUniversalOrderIDFromOrderStatus(status))
s.resetTimer(savedOrderInfo, status.Status, beginTime, gap)
}
} else {
err = scheduler.ErrCanNotFindOrder
s.stopTimer(savedOrderInfo)
s.cancelOtherWaybills(savedOrderInfo, nil)
s.orderMap.Delete(jxutils.GetUniversalOrderIDFromOrderStatus(status))
}
}
return err
@@ -126,9 +123,10 @@ func (s *DefScheduler) OnOrderStatusChanged(status *model.OrderStatus) (err erro
func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill) (err error) {
if bill.Status > model.WaybillStatusUnknown {
globals.SugarLogger.Debugf("OnWaybillStatusChanged, bill:%v", bill)
if savedOrderInfo := s.loadSavedOrderFromMap(model.Waybill2Status(bill)); savedOrderInfo != nil {
s.addWaybill2Map(savedOrderInfo, bill) // 这样写的原因是因为调试时,程度从中途运行,没有接受到WaybillStatusNew事件
savedOrderInfo := s.loadSavedOrderFromMap(model.Waybill2Status(bill))
if bill.Status >= model.WaybillStatusNew {
if bill.Status == model.WaybillStatusNew {
s.addWaybill2Map(savedOrderInfo, bill)
if bill.OrderVendorID == bill.WaybillVendorID {
if savedOrderInfo.timerStatus == model.OrderStatusFinishedPickup { // 如果当前TIMER还是OrderStatusFinishedPickup在OnOrderStatusChanged中设置的则重置
s.resetTimer(savedOrderInfo, model.OrderStatusFinishedPickup, bill.StatusTime, 0)
@@ -136,53 +134,59 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill) (err error) {
globals.SugarLogger.Infof("OnWaybillStatusChanged met other timer, status:%d", savedOrderInfo.timerStatus)
}
}
if savedOrderInfo.order.WaybillVendorID != model.VendorIDUnknown {
if savedOrderInfo.order.WaybillVendorID != model.VendorIDUnknown && savedOrderInfo.order.WaybillVendorID != bill.WaybillVendorID {
globals.SugarLogger.Infof("OnWaybillStatusChanged multiple waybill created, bill:%v", bill)
if bill.WaybillVendorID != bill.WaybillVendorID {
s.CancelWaybill(bill)
}
}
} else {
if savedOrderInfo.order.WaybillVendorID == model.VendorIDUnknown || savedOrderInfo.order.WaybillVendorID == bill.WaybillVendorID {
s.stopTimer(savedOrderInfo) // todo 这样写可能不太合适!!!
}
switch bill.Status {
case model.WaybillStatusAccepted:
s.stopTimer(savedOrderInfo) // todo 这里应该另外启动一个TIMER
s.cancelOtherWaybills(savedOrderInfo, bill)
s.CurOrderManager.UpdateWaybillVendorID(bill)
savedOrderInfo.order.WaybillVendorID = bill.WaybillVendorID
case model.WaybillStatusAcceptCanceled:
if savedOrderInfo.order.WaybillVendorID == bill.WaybillVendorID {
s.createWaybillOn3rdProviders(savedOrderInfo.order, bill)
bill.WaybillVendorID = model.VendorIDUnknown
if savedOrderInfo.order.WaybillVendorID == model.WaybillStatusUnknown {
s.CurOrderManager.UpdateWaybillVendorID(bill)
savedOrderInfo.order.WaybillVendorID = bill.WaybillVendorID
} else {
globals.SugarLogger.Infof("orderID:%s got multiple bill:%v, order details:%v", savedOrderInfo.order.VendorOrderID, bill, savedOrderInfo.order)
}
case model.WaybillStatusAcceptCanceled:
if savedOrderInfo.order.WaybillVendorID == bill.WaybillVendorID {
bill.WaybillVendorID = model.VendorIDUnknown
s.CurOrderManager.UpdateWaybillVendorID(bill)
savedOrderInfo.order.WaybillVendorID = model.VendorIDUnknown
s.createWaybillOn3rdProviders(savedOrderInfo.order, bill)
}
case model.WaybillStatusCourierArrived: // do nothing
case model.WaybillStatusFailed: // todo WaybillStatusFailed理解成订单整个失败了不需要再尝试创建运单了注意这里应该加个zabbix日志的报警
s.removeWaybillFromMap(savedOrderInfo, bill)
globals.SugarLogger.Infof("OnWaybillStatusChanged WaybillStatusFailed, bill:%v", bill)
case model.WaybillStatusCanceled:
s.removeWaybillFromMap(savedOrderInfo, bill)
if savedOrderInfo.order.WaybillVendorID == bill.WaybillVendorID {
s.createWaybillOn3rdProviders(savedOrderInfo.order, nil)
bill.WaybillVendorID = model.VendorIDUnknown
s.CurOrderManager.UpdateWaybillVendorID(bill)
savedOrderInfo.order.WaybillVendorID = bill.WaybillVendorID
savedOrderInfo.order.WaybillVendorID = model.VendorIDUnknown
savedOrderInfo.order.Status = model.OrderStatusFinishedPickup // 如果运单被取消且是主运单将订单状态强制回滚到model.OrderStatusFinishedPickup
s.createWaybillOn3rdProviders(savedOrderInfo.order, nil)
}
case model.WaybillStatusDelivering:
if savedOrderInfo.order.VendorID != bill.WaybillVendorID {
if savedOrderInfo.order.WaybillVendorID == bill.WaybillVendorID && savedOrderInfo.order.VendorID != bill.WaybillVendorID {
s.SelfDeliverDelievering(savedOrderInfo.order)
}
case model.WaybillStatusDelivered:
s.removeWaybillFromMap(savedOrderInfo, bill)
if savedOrderInfo.order.VendorID != bill.WaybillVendorID {
if savedOrderInfo.order.WaybillVendorID == bill.WaybillVendorID && savedOrderInfo.order.VendorID != bill.WaybillVendorID {
s.SelfDeliverDelievered(savedOrderInfo.order)
}
}
}
} else {
err = scheduler.ErrCanNotFindOrder
}
}
return err
@@ -209,23 +213,27 @@ func (s *DefScheduler) removeWaybillFromMap(savedOrderInfo *WatchOrderInfo, bill
}
func (s *DefScheduler) createWaybillOn3rdProviders(order *model.GoodsOrder, excludeBill *model.Waybill) (err error) {
globals.SugarLogger.Debugf("createWaybillOn3rdProviders, orderID:%s, excludeBill:%v", order.VendorOrderID, excludeBill)
if s.isOrderSupport3rdDelivery(order) {
successCount := 0
for vendorID := range s.DeliveryPlatformHandlers {
if excludeBill == nil || vendorID != excludeBill.WaybillVendorID {
if err = s.CreateWaybill(vendorID, order); err == nil {
successCount++
globals.SugarLogger.Debugf("createWaybillOn3rdProviders, orderID:%s, status:%d, excludeBill:%v", order.VendorOrderID, order.Status, excludeBill)
if order.Status == model.OrderStatusFinishedPickup {
if s.isOrderSupport3rdDelivery(order) {
successCount := 0
for vendorID := range s.DeliveryPlatformHandlers {
if excludeBill == nil || vendorID != excludeBill.WaybillVendorID {
if err = s.CreateWaybill(vendorID, order); err == nil {
successCount++
}
}
}
if successCount != 0 {
return nil
}
globals.SugarLogger.Warnf("createWaybillOn3rdProviders, orderID:%s all failed", order.VendorOrderID)
return scheduler.ErrCanNotCreateAtLeastOneWaybill
}
if successCount != 0 {
return nil
}
globals.SugarLogger.Warnf("createWaybillOn3rdProviders, orderID:%s all failed", order.VendorOrderID)
return scheduler.ErrCanNotCreateAtLeastOneWaybill
globals.SugarLogger.Debugf("createWaybillOn3rdProviders, orderID:%s, store:%d dont't support 3rd delivery platform", order.VendorOrderID, jxutils.GetJxStoreIDFromOrder(order))
} else {
globals.SugarLogger.Debugf("createWaybillOn3rdProviders, orderID:%s, status:%d doesn't match model.OrderStatusFinishedPickup, bypass", order.VendorOrderID, order.Status)
}
globals.SugarLogger.Debugf("createWaybillOn3rdProviders, orderID:%s, store:%d dont't support 3rd delivery platform", order.VendorOrderID, jxutils.GetJxStoreIDFromOrder(order))
return nil
}
@@ -302,12 +310,13 @@ func (s *DefScheduler) stopTimer(savedOrderInfo *WatchOrderInfo) {
if savedOrderInfo.timer != nil {
globals.SugarLogger.Debugf("stopTimer orderid:%v", savedOrderInfo.order.VendorOrderID)
savedOrderInfo.timer.Stop()
savedOrderInfo.timerStatus = 0
}
}
func (s *DefScheduler) resetTimer(savedOrderInfo *WatchOrderInfo, status int, beginTime time.Time, gap time.Duration) {
globals.SugarLogger.Debugf("resetTimer status:%v, orderID:%s", status, savedOrderInfo.order.VendorOrderID)
if status >= savedOrderInfo.timerStatus { // 新设置的TIMER不能覆盖状态在其后的TIMER
if status >= savedOrderInfo.timerStatus { // 新设置的TIMER不能覆盖状态在其后的TIMER,如果状态回绕,需要注意
s.stopTimer(savedOrderInfo)
config := s.mergeOrderStatusConfig(status, s.GetPurchasePlatformFromVendorID(savedOrderInfo.order.VendorID).GetStatusActionConfig(status))
if config != nil && config.TimeoutAction != nil {

View File

@@ -110,49 +110,69 @@ func (c *BaseScheduler) GetDeliveryPlatformFromVendorID(vendorID int) DeliveryPl
func (c *BaseScheduler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool) (err error) {
globals.SugarLogger.Infof("AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt)
if c.IsReallyCallPlatformAPI {
err = utils.CallFuncLogError(func() error {
return c.GetPurchasePlatformFromVendorID(order.VendorID).AcceptOrRefuseOrder(order, isAcceptIt)
}, "AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt)
if order.Status == model.OrderStatusNew {
if c.IsReallyCallPlatformAPI {
err = utils.CallFuncLogError(func() error {
return c.GetPurchasePlatformFromVendorID(order.VendorID).AcceptOrRefuseOrder(order, isAcceptIt)
}, "AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt)
}
} else {
globals.SugarLogger.Infof("AcceptOrRefuseOrder orderID:%s, status:%d is not suitable, isAcceptIt:%t", order.VendorOrderID, order.Status, isAcceptIt)
}
return err
}
func (c *BaseScheduler) PickedUpGoods(order *model.GoodsOrder) (err error) {
globals.SugarLogger.Infof("PickedUpGoods orderID:%s", order.VendorOrderID)
if c.IsReallyCallPlatformAPI {
err = utils.CallFuncLogError(func() error {
return c.GetPurchasePlatformFromVendorID(order.VendorID).PickedUpGoods(order)
}, "PickedUpGoods orderID:%s", order.VendorOrderID)
if order.Status == model.OrderStatusAccepted {
if c.IsReallyCallPlatformAPI {
err = utils.CallFuncLogError(func() error {
return c.GetPurchasePlatformFromVendorID(order.VendorID).PickedUpGoods(order)
}, "PickedUpGoods orderID:%s", order.VendorOrderID)
}
} else {
globals.SugarLogger.Infof("PickedUpGoods orderID:%s, status:%d is not suitable", order.VendorOrderID, order.Status)
}
return err
}
func (c *BaseScheduler) Swtich2SelfDeliver(order *model.GoodsOrder) (err error) {
globals.SugarLogger.Infof("Swtich2SelfDeliver orderID:%s", order.VendorOrderID)
if c.IsReallyCallPlatformAPI {
err = utils.CallFuncLogError(func() error {
return c.GetPurchasePlatformFromVendorID(order.VendorID).Swtich2SelfDeliver(order)
}, "Swtich2SelfDeliver orderID:%s", order.VendorOrderID)
if order.Status == model.OrderStatusFinishedPickup {
if c.IsReallyCallPlatformAPI {
err = utils.CallFuncLogError(func() error {
return c.GetPurchasePlatformFromVendorID(order.VendorID).Swtich2SelfDeliver(order)
}, "Swtich2SelfDeliver orderID:%s", order.VendorOrderID)
}
} else {
globals.SugarLogger.Infof("Swtich2SelfDeliver orderID:%s, status:% is not suitable", order.VendorOrderID, order.Status)
}
return err
}
func (c *BaseScheduler) SelfDeliverDelievering(order *model.GoodsOrder) (err error) {
globals.SugarLogger.Infof("SelfDeliverDelievering orderID:%s", order.VendorOrderID)
if c.IsReallyCallPlatformAPI {
err = utils.CallFuncLogError(func() error {
return c.GetPurchasePlatformFromVendorID(order.VendorID).SelfDeliverDelievering(order)
}, "SelfDeliverDelievering orderID:%s", order.VendorOrderID)
if order.Status == model.OrderStatusFinishedPickup {
if c.IsReallyCallPlatformAPI {
err = utils.CallFuncLogError(func() error {
return c.GetPurchasePlatformFromVendorID(order.VendorID).SelfDeliverDelievering(order)
}, "SelfDeliverDelievering orderID:%s", order.VendorOrderID)
}
} else {
globals.SugarLogger.Infof("SelfDeliverDelievering orderID:%s, status:%d is not suitable", order.VendorOrderID, order.Status)
}
return err
}
func (c *BaseScheduler) SelfDeliverDelievered(order *model.GoodsOrder) (err error) {
globals.SugarLogger.Infof("SelfDeliverDelievered orderID:%s", order.VendorOrderID)
if c.IsReallyCallPlatformAPI {
err = utils.CallFuncLogError(func() error {
return c.GetPurchasePlatformFromVendorID(order.VendorID).SelfDeliverDelievered(order)
}, "SelfDeliverDelievered orderID:%s", order.VendorOrderID)
if order.Status == model.OrderStatusDelivering {
if c.IsReallyCallPlatformAPI {
err = utils.CallFuncLogError(func() error {
return c.GetPurchasePlatformFromVendorID(order.VendorID).SelfDeliverDelievered(order)
}, "SelfDeliverDelievered orderID:%s", order.VendorOrderID)
}
} else {
globals.SugarLogger.Infof("SelfDeliverDelievered orderID:%s, status:%d is not suitable", order.VendorOrderID, order.Status)
}
return err
}