diff --git a/business/jxcallback/scheduler/defsch/defsch.go b/business/jxcallback/scheduler/defsch/defsch.go index 54938ccdf..df1985903 100644 --- a/business/jxcallback/scheduler/defsch/defsch.go +++ b/business/jxcallback/scheduler/defsch/defsch.go @@ -19,8 +19,8 @@ import ( ) const ( - time2Delivered = 1 * time.Hour // 正常从下单到送达的时间。 - time2Schedule3rdCarrier = 330 * time.Hour // 京东要求5分钟后才能转自送,保险起见,设置为5分半钟 + time2Delivered = 1 * time.Hour // 正常从下单到送达的时间。 + time2Schedule3rdCarrier = 60 * time.Minute // 京东要求5分钟后才能转自送,保险起见,设置为5分半钟 // time2Schedule3rdCarrierGap4OrderStatus = 3 * time.Minute // 京东要求是运单状态为待抢单且超时5分钟,但为了防止没有运单事件,所以就拣货完成事件开始算,添加3分钟 time2AutoPickupMin = 15 * time.Minute time2AutoPickupGap = 5 * 60 //随机5分钟 @@ -247,9 +247,7 @@ func (s *DefScheduler) OnOrderStatusChanged(status *model.OrderStatus, isPending globals.SugarLogger.Infof("OnOrderStatusChanged [运营2]订单orderID:%s可能被手动点击送达,会对程序状态产生不利影响,请通知门店不要这样操作!", status.VendorOrderID) } } - if (savedOrderInfo.order.DeliveryFlag & model.OrderDeliveryFlagMaskScheduleDisabled) == 0 { - s.cancelOtherWaybills(savedOrderInfo, curWaybill, partner.CancelWaybillReasonOther, partner.CancelWaybillReasonStrOrderAlreadyFinished) - } + s.cancelOtherWaybills(savedOrderInfo, curWaybill, partner.CancelWaybillReasonOther, partner.CancelWaybillReasonStrOrderAlreadyFinished) s.orderMap.Delete(jxutils.GetUniversalOrderIDFromOrderStatus(status)) } } else if status.LockStatus != model.OrderStatusUnknown { @@ -268,149 +266,149 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo // todo 当前收到的事件顺序有时是乱的,不能严格限制,暂时放开 // if order.Status < model.OrderStatusFinishedPickup || order.Status > model.OrderStatusEndBegin { // 如果当前order状态是不应该出现运单状态 // globals.SugarLogger.Infof("OnWaybillStatusChanged orderID:%s status:%s is not suitable for waybill", order.VendorOrderID, model.OrderStatusName[order.Status]) - // s.CancelWaybill(bill) + // s.ProxyCancelWaybill(order, bill) // s.stopTimer(savedOrderInfo) // s.orderMap.Delete(jxutils.GetUniversalOrderIDFromOrderStatus(model.Order2Status(order))) // return nil // } - if (order.DeliveryFlag & model.OrderDeliveryFlagMaskScheduleDisabled) == 0 { // 如果被停止调度,整个不动作 - if bill.Status == model.WaybillStatusNew { - s.addWaybill2Map(savedOrderInfo, bill) - if !isPending { - if order.Status > model.OrderStatusEndBegin { - s.CancelWaybill(bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) - } else if order.WaybillVendorID != model.VendorIDUnknown { - globals.SugarLogger.Debugf("OnWaybillStatusChanged multiple waybill created, bill:%v", bill) - if order.VendorID == bill.WaybillVendorID { // 是购物平台运单 - if order.VendorID != order.WaybillVendorID { // 既有运单不是购物平台运单 - globals.SugarLogger.Infof("OnWaybillStatusChanged bill:%v purchase platform bill came later than others, strange!!!", bill) - oldBill := savedOrderInfo.waybills[order.WaybillVendorID] - if oldBill != nil { - s.CancelWaybill(oldBill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) - } else { - globals.SugarLogger.Warnf("OnWaybillStatusChanged bill:%v, oldBill is null, strange!!!", bill) - } + // if (order.DeliveryFlag & model.OrderDeliveryFlagMaskScheduleDisabled) == 0 { // 如果被停止调度,整个不动作 + if bill.Status == model.WaybillStatusNew { + s.addWaybill2Map(savedOrderInfo, bill) + if !isPending { + if order.Status > model.OrderStatusEndBegin { + s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) + } else if order.WaybillVendorID != model.VendorIDUnknown { + globals.SugarLogger.Debugf("OnWaybillStatusChanged multiple waybill created, bill:%v", bill) + if order.VendorID == bill.WaybillVendorID { // 是购物平台运单 + if order.VendorID != order.WaybillVendorID { // 既有运单不是购物平台运单 + globals.SugarLogger.Infof("OnWaybillStatusChanged bill:%v purchase platform bill came later than others, strange!!!", bill) + oldBill := savedOrderInfo.waybills[order.WaybillVendorID] + if oldBill != nil { + s.ProxyCancelWaybill(order, oldBill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) + } else { + globals.SugarLogger.Warnf("OnWaybillStatusChanged bill:%v, oldBill is null, strange!!!", bill) } - bill.WaybillVendorID = model.VendorIDUnknown - s.updateOrderByBill(order, bill, false) - } else { - s.CancelWaybill(bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) } - } - } - // 只有购物平台的新运单消息才会启动抢单TIMER - if bill.OrderVendorID == bill.WaybillVendorID { - s.resetTimer(savedOrderInfo, bill, isPending) - } - } else { - switch bill.Status { - case model.WaybillStatusAccepted: - s.resetTimer(savedOrderInfo, bill, isPending) - if !isPending { - // todo 购买平台的运单,优先级最高,但这样写也可能带来问题,即在这个时间,因为之前3方已经接单,已经发出了转自送请求(而且可能成功了),所以加个状态判断 - if order.WaybillVendorID == model.VendorIDUnknown || - (order.VendorID == bill.WaybillVendorID && order.VendorID != order.WaybillVendorID && (order.DeliveryFlag&model.OrderDeliveryFlagMaskPurcahseDisabled) == 0) { - if order.WaybillVendorID != model.VendorIDUnknown { - // 进到这里的原因是,在这个时间点,购物平台物流已经抢单(但抢单消息还没有被收到)(比如:818810379000941) - globals.SugarLogger.Infof("OnWaybillStatusChanged orderID:%s purchase platform waybill arrvied later, may case problem", order.VendorOrderID) - } - s.updateOrderByBill(order, bill, false) - s.cancelOtherWaybills(savedOrderInfo, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) - if bill.WaybillVendorID != bill.OrderVendorID { - if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore { - s.SelfDeliverDelievering(savedOrderInfo.order, "") - } else { - s.swtich2SelfDeliverWithRetry(savedOrderInfo, bill, 2, 10*time.Second) - } - } - if !isPending { - weixinmsg.NotifyWaybillStatus(bill, order) - } - } else if !s.isBillCandidate(order, bill) && bill.WaybillVendorID != order.VendorID { - // 发生这种情况的原因就是两个接单事件几乎同时到达(来不及取消),也算正常 - s.CancelWaybill(bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) - globals.SugarLogger.Infof("OnWaybillStatusChanged Accepted orderID:%s got multiple bill:%v", order.VendorOrderID, bill) - } - } - case model.WaybillStatusAcceptCanceled: - if s.isBillCandidate(order, bill) { - s.resetTimer(savedOrderInfo, bill, isPending) - if !isPending { - bill.WaybillVendorID = model.VendorIDUnknown - s.updateOrderByBill(order, bill, false) - - s.createWaybillOn3rdProviders(savedOrderInfo, bill) - } - } else if order.WaybillVendorID != model.VendorIDUnknown { - s.CancelWaybill(bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) - globals.SugarLogger.Warnf("OnWaybillStatusChanged AcceptCanceled orderID:%s got multiple bill:%v, order details:%v", order.VendorOrderID, bill, order) - } - case model.WaybillStatusCourierArrived: // do nothing - s.resetTimer(savedOrderInfo, bill, isPending) - if s.isBillCandidate(order, bill) { + bill.WaybillVendorID = model.VendorIDUnknown + s.updateOrderByBill(order, bill, false) } else { - // s.CancelWaybill(bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) - globals.SugarLogger.Infof("OnWaybillStatusChanged CourierArrived order(%d, %s) bill(%d, %s), bill:%v shouldn't get here", order.WaybillVendorID, order.VendorWaybillID, bill.WaybillVendorID, bill.VendorWaybillID, bill) - } - case model.WaybillStatusFailed: // todo WaybillStatusFailed理解成订单整个失败了,不需要再尝试创建运单了,注意这里应该加个zabbix日志的报警 - s.removeWaybillFromMap(savedOrderInfo, bill.WaybillVendorID) - if s.isBillCandidate(order, bill) { - s.resetTimer(savedOrderInfo, bill, isPending) - if !isPending { - globals.SugarLogger.Infof("OnWaybillStatusChanged WaybillStatusFailed, bill:%v", bill) - bill.WaybillVendorID = model.VendorIDUnknown - s.updateOrderByBill(order, bill, false) - } - } else { - // 创建运单失败时,可能到这里来(比如:818874313000121) - globals.SugarLogger.Infof("OnWaybillStatusChanged Failed bill:%v shouldn't got here, order details:%v", bill, order) - } - case model.WaybillStatusCanceled: - s.removeWaybillFromMap(savedOrderInfo, bill.WaybillVendorID) - if s.isBillCandidate(order, bill) || order.WaybillVendorID == model.VendorIDUnknown { - s.resetTimer(savedOrderInfo, bill, isPending) - if !isPending { - if order.WaybillVendorID != model.VendorIDUnknown { - bill.WaybillVendorID = model.VendorIDUnknown - s.updateOrderByBill(order, bill, false) - } - if bill.WaybillVendorID != order.VendorID { // 3方的运单取消才会重新发起创建3方订单,购物平台的运单取消后,它本身还会再创建新运单(NewWabill事件有相应TIMER)),至少京东是这样的,暂时按京东的行为来 - s.createWaybillOn3rdProviders(savedOrderInfo, nil) - } - } - } - case model.WaybillStatusDelivering: - s.resetTimer(savedOrderInfo, bill, isPending) - if s.isBillCandidate(order, bill) { - // do nothing - } else { - // s.CancelWaybill(bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) - globals.SugarLogger.Infof("OnWaybillStatusChanged Delivering order(%d, %s) bill(%d, %s), bill:%v shouldn't get here", order.WaybillVendorID, order.VendorWaybillID, bill.WaybillVendorID, bill.VendorWaybillID, bill) - } - case model.WaybillStatusDelivered: - s.resetTimer(savedOrderInfo, bill, isPending) - s.removeWaybillFromMap(savedOrderInfo, bill.WaybillVendorID) - if order.VendorID != bill.WaybillVendorID && !isPending { - if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore { - s.SelfDeliverDelievered(order, "") - } else { - s.Swtich2SelfDelivered(order, "") - } - } - if !s.isBillCandidate(order, bill) { - // 一般只会消息乱序才会到这里,即新订单消息在运单接单消息后到达 - // 典型的一个:1223633660228537567 - globals.SugarLogger.Infof("OnWaybillStatusChanged Delivered order(%d, %s) bill(%d, %s), bill:%v shouldn't get here", order.WaybillVendorID, order.VendorWaybillID, bill.WaybillVendorID, bill.VendorWaybillID, bill) - if order.WaybillVendorID == model.VendorIDUnknown { - s.updateOrderByBill(order, bill, false) - } - } - if !isPending { - weixinmsg.NotifyWaybillStatus(bill, order) + s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) } } } + // 只有购物平台的新运单消息才会启动抢单TIMER + if bill.OrderVendorID == bill.WaybillVendorID { + s.resetTimer(savedOrderInfo, bill, isPending) + } + } else { + switch bill.Status { + case model.WaybillStatusAccepted: + s.resetTimer(savedOrderInfo, bill, isPending) + if !isPending { + // todo 购买平台的运单,优先级最高,但这样写也可能带来问题,即在这个时间,因为之前3方已经接单,已经发出了转自送请求(而且可能成功了),所以加个状态判断 + if order.WaybillVendorID == model.VendorIDUnknown || + (order.VendorID == bill.WaybillVendorID && order.VendorID != order.WaybillVendorID && (order.DeliveryFlag&model.OrderDeliveryFlagMaskPurcahseDisabled) == 0) { + if order.WaybillVendorID != model.VendorIDUnknown { + // 进到这里的原因是,在这个时间点,购物平台物流已经抢单(但抢单消息还没有被收到)(比如:818810379000941) + globals.SugarLogger.Infof("OnWaybillStatusChanged orderID:%s purchase platform waybill arrvied later, may case problem", order.VendorOrderID) + } + s.updateOrderByBill(order, bill, false) + s.cancelOtherWaybills(savedOrderInfo, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) + if bill.WaybillVendorID != bill.OrderVendorID { + if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore { + s.SelfDeliverDelievering(savedOrderInfo.order, "") + } else { + s.swtich2SelfDeliverWithRetry(savedOrderInfo, bill, 2, 10*time.Second) + } + } + if !isPending { + weixinmsg.NotifyWaybillStatus(bill, order) + } + } else if !s.isBillCandidate(order, bill) && bill.WaybillVendorID != order.VendorID { + // 发生这种情况的原因就是两个接单事件几乎同时到达(来不及取消),也算正常 + s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) + globals.SugarLogger.Infof("OnWaybillStatusChanged Accepted orderID:%s got multiple bill:%v", order.VendorOrderID, bill) + } + } + case model.WaybillStatusAcceptCanceled: + if s.isBillCandidate(order, bill) { + s.resetTimer(savedOrderInfo, bill, isPending) + if !isPending { + bill.WaybillVendorID = model.VendorIDUnknown + s.updateOrderByBill(order, bill, false) + + s.createWaybillOn3rdProviders(savedOrderInfo, bill) + } + } else if order.WaybillVendorID != model.VendorIDUnknown { + s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) + globals.SugarLogger.Warnf("OnWaybillStatusChanged AcceptCanceled orderID:%s got multiple bill:%v, order details:%v", order.VendorOrderID, bill, order) + } + case model.WaybillStatusCourierArrived: // do nothing + s.resetTimer(savedOrderInfo, bill, isPending) + if s.isBillCandidate(order, bill) { + } else { + // s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) + globals.SugarLogger.Infof("OnWaybillStatusChanged CourierArrived order(%d, %s) bill(%d, %s), bill:%v shouldn't get here", order.WaybillVendorID, order.VendorWaybillID, bill.WaybillVendorID, bill.VendorWaybillID, bill) + } + case model.WaybillStatusFailed: // todo WaybillStatusFailed理解成订单整个失败了,不需要再尝试创建运单了,注意这里应该加个zabbix日志的报警 + s.removeWaybillFromMap(savedOrderInfo, bill.WaybillVendorID) + if s.isBillCandidate(order, bill) { + s.resetTimer(savedOrderInfo, bill, isPending) + if !isPending { + globals.SugarLogger.Infof("OnWaybillStatusChanged WaybillStatusFailed, bill:%v", bill) + bill.WaybillVendorID = model.VendorIDUnknown + s.updateOrderByBill(order, bill, false) + } + } else { + // 创建运单失败时,可能到这里来(比如:818874313000121) + globals.SugarLogger.Infof("OnWaybillStatusChanged Failed bill:%v shouldn't got here, order details:%v", bill, order) + } + case model.WaybillStatusCanceled: + s.removeWaybillFromMap(savedOrderInfo, bill.WaybillVendorID) + if s.isBillCandidate(order, bill) || order.WaybillVendorID == model.VendorIDUnknown { + s.resetTimer(savedOrderInfo, bill, isPending) + if !isPending { + if order.WaybillVendorID != model.VendorIDUnknown { + bill.WaybillVendorID = model.VendorIDUnknown + s.updateOrderByBill(order, bill, false) + } + if bill.WaybillVendorID != order.VendorID { // 3方的运单取消才会重新发起创建3方订单,购物平台的运单取消后,它本身还会再创建新运单(NewWabill事件有相应TIMER)),至少京东是这样的,暂时按京东的行为来 + s.createWaybillOn3rdProviders(savedOrderInfo, nil) + } + } + } + case model.WaybillStatusDelivering: + s.resetTimer(savedOrderInfo, bill, isPending) + if s.isBillCandidate(order, bill) { + // do nothing + } else { + // s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) + globals.SugarLogger.Infof("OnWaybillStatusChanged Delivering order(%d, %s) bill(%d, %s), bill:%v shouldn't get here", order.WaybillVendorID, order.VendorWaybillID, bill.WaybillVendorID, bill.VendorWaybillID, bill) + } + case model.WaybillStatusDelivered: + s.resetTimer(savedOrderInfo, bill, isPending) + s.removeWaybillFromMap(savedOrderInfo, bill.WaybillVendorID) + if order.VendorID != bill.WaybillVendorID && !isPending { + if savedOrderInfo.storeDeliveryType == scheduler.StoreDeliveryTypeByStore { + s.SelfDeliverDelievered(order, "") + } else { + s.Swtich2SelfDelivered(order, "") + } + } + if !s.isBillCandidate(order, bill) { + // 一般只会消息乱序才会到这里,即新订单消息在运单接单消息后到达 + // 典型的一个:1223633660228537567 + globals.SugarLogger.Infof("OnWaybillStatusChanged Delivered order(%d, %s) bill(%d, %s), bill:%v shouldn't get here", order.WaybillVendorID, order.VendorWaybillID, bill.WaybillVendorID, bill.VendorWaybillID, bill) + if order.WaybillVendorID == model.VendorIDUnknown { + s.updateOrderByBill(order, bill, false) + } + } + if !isPending { + weixinmsg.NotifyWaybillStatus(bill, order) + } + } } + // } } return err } @@ -493,21 +491,25 @@ func (s *DefScheduler) createWaybillOn3rdProviders(savedOrderInfo *WatchOrderInf func (s *DefScheduler) cancelOtherWaybills(savedOrderInfo *WatchOrderInfo, bill2Keep *model.Waybill, cancelReasonID int, cancelReason string) (err error) { globals.SugarLogger.Debugf("cancelOtherWaybills, orderID:%s, bill:%v", savedOrderInfo.order.VendorOrderID, bill2Keep) - toBeDeleted := []*model.Waybill{} - for _, v := range savedOrderInfo.waybills { - if (v.OrderVendorID != v.WaybillVendorID) && (bill2Keep == nil || !(v.WaybillVendorID == bill2Keep.WaybillVendorID && v.VendorWaybillID == bill2Keep.VendorWaybillID)) { - err2 := s.CancelWaybill(v, cancelReasonID, cancelReason) - if err2 == nil { - toBeDeleted = append(toBeDeleted, v) - } - // 至少返回一个错误 - if err == nil && err2 != nil { - err = err2 + if (savedOrderInfo.order.DeliveryFlag & model.OrderDeliveryFlagMaskScheduleDisabled) == 0 { + toBeDeleted := []*model.Waybill{} + for _, v := range savedOrderInfo.waybills { + if (v.OrderVendorID != v.WaybillVendorID) && (bill2Keep == nil || !(v.WaybillVendorID == bill2Keep.WaybillVendorID && v.VendorWaybillID == bill2Keep.VendorWaybillID)) { + err2 := s.ProxyCancelWaybill(savedOrderInfo.order, v, cancelReasonID, cancelReason) + if err2 == nil { + toBeDeleted = append(toBeDeleted, v) + } + // 至少返回一个错误 + if err == nil && err2 != nil { + err = err2 + } } } - } - for _, v := range toBeDeleted { - s.removeWaybillFromMap(savedOrderInfo, v.WaybillVendorID) + for _, v := range toBeDeleted { + s.removeWaybillFromMap(savedOrderInfo, v.WaybillVendorID) + } + } else { + globals.SugarLogger.Debugf("cancelOtherWaybills, orderID:%s, bill:%v stop schedule", savedOrderInfo.order.VendorOrderID, bill2Keep) } return err } @@ -536,7 +538,7 @@ func (s *DefScheduler) swtich2SelfDeliverWithRetry(savedOrderInfo *WatchOrderInf db := orm.NewOrm() db.Insert(tmpLog) - if s.CancelWaybill(bill, partner.CancelWaybillReasonSwitch2SelfFailed, partner.CancelWaybillReasonStrSwitch2SelfFailed) == nil { + if s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonSwitch2SelfFailed, partner.CancelWaybillReasonStrSwitch2SelfFailed) == nil { // 转自送失败的取消,要将订单中的运单状态更新 if s.isBillCandidate(order, bill) { bill.WaybillVendorID = model.VendorIDUnknown @@ -748,3 +750,12 @@ func (s *DefScheduler) autoPickupGood(order *model.GoodsOrder) (err error) { func (s *DefScheduler) isBillCandidate(order *model.GoodsOrder, bill *model.Waybill) bool { return order.WaybillVendorID == bill.WaybillVendorID && order.VendorWaybillID == bill.VendorWaybillID } + +func (s *DefScheduler) ProxyCancelWaybill(order *model.GoodsOrder, bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) { + globals.SugarLogger.Debugf("ProxyCancelWaybill orderID:%s", order.VendorOrderID) + if (order.DeliveryFlag & model.OrderDeliveryFlagMaskScheduleDisabled) == 0 { + return s.CancelWaybill(bill, cancelReasonID, cancelReason) + } + globals.SugarLogger.Debugf("ProxyCancelWaybill orderID:%s stop schedule, bypass CancelWaybill", order.VendorOrderID) + return nil +}