@@ -25,9 +25,10 @@ import (
)
const (
time2Delivered = 1 * time . Hour // 正常从下单到送达的时间。
minute2Schedule3rdCarrier = 20 // 收到平台方自有配送的新运单消息后, 等待创建三方配送运单的时间( 分钟) , 如果是定时达, 会再根据ExpectedDeliveredTime与dingShiDaAheadTime做调整
minMin ute2Schedule3rdCarrier = 5 // 转三方配送最少等待 时间(分钟)
time2Delivered = 1 * time . Hour // 正常从下单到送达的时间。
minute2Schedule3rdCarrier = 20 // 收到平台方自有配送的新运单消息后, 等待创建三方配送运单的时间( 分钟) , 如果是定时达, 会再根据ExpectedDeliveredTime与dingShiDaAheadTime做调整
minute2Schedule3rdCarrier4Ebai = 30 // 饿百的最少转自配送需要的 时间(分钟)
minMinute2Schedule3rdCarrier = 5 // 转三方配送最少等待时间(分钟)
time2AutoPickupMin = 15 * time . Minute // 自动拣货等待时间, 这个只有在没有PickDeadline信息才有用, 否则会根据PickDeadline设置
second2AutoPickupGap = 60 //随机60秒
@@ -71,7 +72,15 @@ type WatchOrderInfo struct {
type StatusActionConfig struct {
partner . StatusActionParams
TimeoutAction func ( savedOrderInfo * WatchOrderInfo ) ( err error ) // 超时后需要执行的动作, 为nil表示此状态不需要执行监控, nil在GetStatusActionConfig返回时表示不修改缺省
TimeoutAction func ( savedOrderInfo * WatchOrderInfo ) ( err error ) // 超时后需要执行的动作, 为nil表示此状态不需要执行监控, nil在GetStatusActionConfig返回时表示不修改缺省
ShouldSetTimer func ( savedOrderInfo * WatchOrderInfo , bill * model . Waybill ) bool
}
func ( c * StatusActionConfig ) CallShouldSetTimer ( savedOrderInfo * WatchOrderInfo , bill * model . Waybill ) bool {
if c . ShouldSetTimer != nil {
return c . ShouldSetTimer ( savedOrderInfo , bill )
}
return true
}
// 重要:此调度器要求同一定单的处理逻辑必须是序列化了的,不然会有并发问题
@@ -164,6 +173,9 @@ func init() {
} )
return nil
} ,
ShouldSetTimer : func ( savedOrderInfo * WatchOrderInfo , bill * model . Waybill ) bool {
return savedOrderInfo . order . Status == model . OrderStatusNew
} ,
} ,
model . OrderStatusAccepted : & StatusActionConfig { // 自动拣货
StatusActionParams : partner . StatusActionParams {
@@ -177,6 +189,9 @@ func init() {
}
return nil
} ,
ShouldSetTimer : func ( savedOrderInfo * WatchOrderInfo , bill * model . Waybill ) bool {
return savedOrderInfo . autoPickupTimeoutMinute > 0
} ,
} ,
model . OrderStatusFinishedPickup : & StatusActionConfig {
StatusActionParams : partner . StatusActionParams {
@@ -190,6 +205,9 @@ func init() {
}
return nil
} ,
ShouldSetTimer : func ( savedOrderInfo * WatchOrderInfo , bill * model . Waybill ) bool {
return savedOrderInfo . storeDeliveryType == scheduler . StoreDeliveryTypeByStore
} ,
} ,
} ,
map [ int ] * StatusActionConfig {
@@ -205,6 +223,27 @@ func init() {
}
return nil
} ,
ShouldSetTimer : func ( savedOrderInfo * WatchOrderInfo , bill * model . Waybill ) bool {
return savedOrderInfo . storeDeliveryType != scheduler . StoreDeliveryTypeByStore && savedOrderInfo . order . VendorID != model . VendorIDEBAI
} ,
} ,
model . WaybillStatusCanceled : & StatusActionConfig {
StatusActionParams : partner . StatusActionParams {
TimerType : partner . TimerTypeBaseOrderCreatedAt ,
Timeout : minute2Schedule3rdCarrier4Ebai * time . Minute ,
} ,
TimeoutAction : func ( savedOrderInfo * WatchOrderInfo ) ( err error ) {
// 饿百转自送的时机不太清楚,暂时禁用超时转自送,在饿百运单取消时还是会自动创建
order := savedOrderInfo . order
if ( order . Status >= model . OrderStatusFinishedPickup && order . Status < model . OrderStatusEndBegin ) && savedOrderInfo . storeDeliveryType != scheduler . StoreDeliveryTypeByStore && order . VendorID == model . VendorIDEBAI { // 非自配送商家使用
return sch . createWaybillOn3rdProviders ( savedOrderInfo , nil )
}
return nil
} ,
ShouldSetTimer : func ( savedOrderInfo * WatchOrderInfo , bill * model . Waybill ) bool {
order := savedOrderInfo . order
return ( order . Status >= model . OrderStatusFinishedPickup && order . Status < model . OrderStatusEndBegin ) && savedOrderInfo . storeDeliveryType != scheduler . StoreDeliveryTypeByStore && order . VendorID == model . VendorIDEBAI
} ,
} ,
} ,
}
@@ -429,7 +468,7 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo
// 之前的条件是order.Status < model.OrderStatusDelivering, 但像订单902322817000122确实有在配送中取消状态, 改成非订单结束状态都可以
// OrderStatusFinishedPickup状态的订单依赖于TIMER重新建运单
if bill . DeliveryFlag & model . WaybillDeliveryFlagMaskActiveCancel == 0 {
if order . Status >= model . OrderStatusFinishedPickup && order . Status < model . OrderStatusEndBegin && ( bill . WaybillVendorID != order . VendorID || order . VendorID == model . VendorIDEBAI ) {
if ( order . Status >= model . OrderStatusFinishedPickup && order . Status < model . OrderStatusEndBegin ) && bill . WaybillVendorID != order . VendorID {
s . createWaybillOn3rdProviders ( savedOrderInfo , nil )
}
}
@@ -468,12 +507,12 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo
weixinmsg . NotifyWaybillStatus ( bill , order , false )
} )
}
case model . WaybillStatusNeverSend: // 平台不配送,直接创建三方运单
s . resetTimer( savedOrderInfo, bill , isPending )
s . removeWaybillFromMap( savedOrderInfo, bill . WaybillVendorID )
if order . WaybillVendorID == model . VendorIDUnknown {
s . createWaybillOn3rdProviders( savedOrderInfo, nil )
}
// case model. WaybillStatusNeverSend: // 平台不配送,直接创建三方运单
// s. resetTimer( savedOrderInfo, bill, isPending)
// s. removeWaybillFromMap( savedOrderInfo, bill. WaybillVendorID)
// if order.WaybillVendorID == model. VendorIDUnknown {
// s. createWaybillOn3rdProviders( savedOrderInfo, nil)
// }
}
s . updateBillsInfo ( savedOrderInfo , bill ) // 更新可能的运单状态变化
}
@@ -660,38 +699,40 @@ func (s *DefScheduler) resetTimer(savedOrderInfo *WatchOrderInfo, bill *model.Wa
s . stopTimer ( savedOrderInfo )
}
if config != nil && config . TimeoutAction != nil && config . TimerType != partner . TimerTypeByPass {
timeout := config . GetRef Timeout ( statusTime )
if config . TimeoutGap != 0 {
timeout += time . Duration ( rand . Intn ( int ( config . TimeoutGap ) ) ) * time . Second
}
if isPending && timeout < pendingOrderTimerMaxSecond * time . Second { // 如果是PENDING的订单, 则将其分布到2--5秒内, 让后续事件有机会执行
timeout = time . Duration ( jxutils . MapValue2Scope ( int64 ( timeout ) , - pendingOrderTimerMinMinSecond * 1000 , pendingOrderTimerMaxSecond * 1000 , pendingOrderTimerMinSecond * 1000 , pendingOrderTimerMaxSecond * 1000 ) ) * time . Millisecond
} else if timeout < 0 {
timeout = 0
}
if timeout == 0 {
config . TimeoutAction ( savedOrderInfo )
} else {
timerName := ""
if statusType == scheduler . TimerStatusTypeOrder {
timerName = model . OrderStatusName [ status ]
} else if statusType == scheduler . TimerStatusTypeWaybill {
timerName = model . WaybillStatusName [ status ]
if config . CallShouldSet Timer ( savedOrderInfo , bill ) {
timeout := config . GetRefTimeout ( statusTime , order . OrderCreatedAt )
if config . TimeoutGap != 0 {
timeout += time . Duration ( rand . Intn ( int ( config . TimeoutGap ) ) ) * time . Second
}
savedOrderInfo . timerStatusType = statusType
savedOrderInfo . timerStatus = status
savedOrderInfo . timerTim e = time. Now ( ) . Add ( timeout )
savedOrderInfo . timer = utils . AfterFuncWithRecover ( timeout , func ( ) {
jxutils . CallMsgHandlerAsync ( func ( ) {
globals . SugarLogger . Debugf ( "fire timer:%s, orderID:%s" , timerName , order . VendorOrderID )
savedOrderInfo := s . loadSavedOrderFromMap ( model . Order2Status ( order ) , true )
config . TimeoutAction ( savedOrderInfo )
savedOrderInfo . timerStatus = 0
savedOrderInfo . timerS tatusType = scheduler . TimerStatusTypeUnknown
} , jxutils . ComposeUniversalOrderID ( or der . VendorOrderID , order . VendorID ) )
} )
if isPending && timeout < pendingOrderTimerMaxSecond * time . Second { // 如果是PENDING的订单, 则将其分布到2--5秒内, 让后续事件有机会执行
timeout = time . Duration ( jxutils . MapValue2Scope ( int64 ( timeout ) , - pendingOrderTimerMinMinSecond * 1000 , pendingOrderTimerMaxSecond * 1000 , pendingOrderTimerMinSecond * 1000 , pendingOrderTimerMaxSecond * 1000 ) ) * time . Millisecond
} els e if timeout < 0 {
timeout = 0
}
if timeout == 0 {
config . TimeoutAction ( savedOrderInfo )
} else {
timerName : = ""
if s tatusType = = scheduler . TimerStatusTypeOrder {
timerName = mo del . OrderStatusName [ status ]
} else if statusType == scheduler . TimerStatusTypeWaybill {
timerName = model . WaybillStatusName [ status ]
}
savedOrderInfo . timerStatusType = statusType
savedOrderInfo . timerStatus = status
savedOrderInfo . timerTime = time . Now ( ) . Add ( timeout )
savedOrderInfo . timer = utils . AfterFuncWithRecover ( timeout , func ( ) {
jxutils . CallMsgHandlerAsync ( func ( ) {
globals . SugarLogger . Debugf ( "fire timer:%s, orderID:%s" , timerName , order . VendorOrderID )
savedOrderInfo := s . loadSavedOrderFromMap ( model . Order2Status ( order ) , true )
config . TimeoutAction ( savedOrderInfo )
savedOrderInfo . timerStatus = 0
savedOrderInfo . timerStatusType = scheduler . TimerStatusTypeUnknown
} , jxutils . ComposeUniversalOrderID ( order . VendorOrderID , order . VendorID ) )
} )
}
globals . SugarLogger . Debugf ( "resetTimer, orderID:%s, status:%d, timeout:%v" , order . VendorOrderID , status , timeout )
}
globals . SugarLogger . Debugf ( "resetTimer, orderID:%s, status:%d, timeout:%v" , order . VendorOrderID , status , timeout )
}
}
}
@@ -701,6 +742,9 @@ func isStatusNewer(curStatusType, curStatus, statusType, status int) bool {
if curStatusType == scheduler . TimerStatusTypeWaybill && statusType == scheduler . TimerStatusTypeOrder && status <= model . OrderStatusFinishedPickup {
return false
}
if curStatusType == scheduler . TimerStatusTypeWaybill {
return curStatus != status
}
return curStatusType != statusType || status >= curStatus
}
@@ -731,7 +775,7 @@ func (s *DefScheduler) mergeOrderStatusConfig(savedOrderInfo *WatchOrderInfo, st
TimeoutGap : - 1 ,
}
timeout := statusTime . Sub ( time . Now ( ) ) + minMinute2Schedule3rdCarrier * time . Minute
if vendorActionParams . GetRefTimeout ( statusTime ) < timeout { // 如果非立即达订单, 根据ExpectedDeliveredTime算出来的timeout太早
if vendorActionParams . GetRefTimeout ( statusTime , order . OrderCreatedAt ) < timeout { // 如果非立即达订单, 根据ExpectedDeliveredTime算出来的timeout太早
vendorActionParams . Timeout = timeout
vendorActionParams . TimeoutGap = 0
}