没有显示处理model.WaybillStatusCourierArrived事件,导致TIMER没有停掉,又执行了在第3方门店创建运单操作。(改为只要收到了大于NEW的运单事件,都将TIMER停掉,状态需要添加TIMER的,再自行添加)
然后createWaybillOn3rdProviders又没有判断状态,导致又重新创建运单(添加状态判断,另外将所有TIMER事件中的逻辑都添加状态判断,合适后才真正执行)
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user