- weixin msg added.
- elm sometimes have no delivery msg - elm sometimes delivery msg arrvied before finished pickup - the gap between finished pickup and first delivery msg is big
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"git.rosy.net.cn/baseapi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
"github.com/astaxie/beego/orm"
|
||||
@@ -27,6 +28,7 @@ func (c *OrderController) OnOrderNew(order *model.GoodsOrder) (err error) {
|
||||
if err == nil && !isDuplicated {
|
||||
if err = c.saveOrder(order, false, db); err == nil {
|
||||
err = scheduler.CurrentScheduler.OnOrderNew(order)
|
||||
weixinmsg.NotifyNewOrder(order)
|
||||
}
|
||||
}
|
||||
return err
|
||||
|
||||
@@ -2,6 +2,7 @@ package controller
|
||||
|
||||
import (
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-callback/business/scheduler"
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
@@ -55,6 +56,11 @@ func (w *WaybillController) OnWaybillStatusChanged(bill *model.Waybill) (err err
|
||||
}
|
||||
}
|
||||
}
|
||||
if bill.Status == model.WaybillStatusAccepted || bill.Status == model.WaybillStatusDelivered {
|
||||
if order, err2 := OrderManager.LoadOrder(bill.VendorOrderID, bill.OrderVendorID); err2 == nil {
|
||||
weixinmsg.NotifyWaybillStatus(bill, order)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"git.rosy.net.cn/baseapi/platformapi/autonavi"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
"git.rosy.net.cn/jx-callback/globals/api"
|
||||
)
|
||||
|
||||
@@ -127,7 +126,7 @@ func IntCoordinate2MarsStandard(gpsLng, gpsLat int, coordinateType int) (marsLng
|
||||
case model.CoordinateTypeMapbar:
|
||||
coordSys = autonavi.CoordSysMapbar
|
||||
default:
|
||||
globals.SugarLogger.Errorf("known coordinate type:%d", coordinateType)
|
||||
panic(fmt.Sprintf("known coordinate type:%d", coordinateType))
|
||||
}
|
||||
return api.AutonaviAPI.CoordinateConvert(marsLng, marsLat, coordSys)
|
||||
}
|
||||
@@ -139,3 +138,7 @@ func IntPrice2Standard(value int64) float64 {
|
||||
func StandardPrice2Int(value float64) int64 {
|
||||
return int64(math.Round(value * 100))
|
||||
}
|
||||
|
||||
func IntPrice2StandardString(value int64) string {
|
||||
return fmt.Sprintf("%.2f", IntPrice2Standard(value))
|
||||
}
|
||||
|
||||
183
business/jxutils/weixinmsg/weixinmsg.go
Normal file
183
business/jxutils/weixinmsg/weixinmsg.go
Normal file
@@ -0,0 +1,183 @@
|
||||
package weixinmsg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
"github.com/astaxie/beego/orm"
|
||||
)
|
||||
|
||||
const (
|
||||
WX_TO_ORDER_PAGE_URL = "http://www.jxc4.com/jx/h5/#/?jxStoreId="
|
||||
WX_TO_SHOW_COMMENTS_DETAIL_URL = "http://www.jxc4.com/jx/h5/#/assess-list?jxStoreId=" //展示差评详情的页面
|
||||
//新订单模板消息文字颜色
|
||||
WX_NEW_ORDER_TEMPLATE_COLOR = "#173177"
|
||||
WX_HIGHLEVEL_TEMPLATE_COLOR = "#FF0000" //红色
|
||||
WX_TEMPLATE_VENDERCOLOR_JDDJ = "#47B34F"
|
||||
WX_TEMPLATE_VENDERCOLOR_MT = "#F4A800"
|
||||
WX_TEMPLATE_VENDERCOLOR_ELM = "#0191EA" //蓝色
|
||||
WX_TEMPLATE_VENDERCOLOR_BAD_COMMENTS = "#4F4DA0"
|
||||
|
||||
WX_NEWORDER_TEMPLATE_ID = "_DtNGwmOeR6TkkTVUblxLIlkV2MAPOX57TkvfdqG6nY" //微信新订单推送
|
||||
WX_MTPS_DELIVERY_GRABDONE_TEMPLATE_ID = "h4dkON6AgnHz1XmaksEUB_8Bcir4V8MSexUhC149pPE" //微信美团配送员接单推送
|
||||
WX_MTPS_DELIVERY_DONE_TEMPLATE_ID = "YXdCrQAHZlcZX1htYUiarrLmtkmKAjp7rynjwObgODo" //微信美团配送员配送完成推送
|
||||
WX_MTPS_UNABLE_DELIVER_TEMPLATE_ID = "ZFph5Hp7oLlrzVRXbsKIC_StmaBeB9Dlp4tlHeAmUQ8" //微信美团配送配送能力不足推送
|
||||
WX_MTPS_DELIVERY_EXCEPTION_TEMPLATE_ID = "RkfOFHgR1N75L4-a6Gv0DljpCsVfOHhLm_vyXh8MR-w" //微信美团配送异常推送
|
||||
WX_BAD_COMMENT_PUSH_TEMPLATE_ID = "zMZH5Ek0k1OHlWnsDb98UaHEOlkJZYok2QOJUfwfJWs" //微信差评消息推送
|
||||
|
||||
WX_DADA_DELIVERY_GRABDONE_TEMPLATE_ID = "h4dkON6AgnHz1XmaksEUB_8Bcir4V8MSexUhC149pPE" //微信达达众包配送员接单推送
|
||||
WX_DADA_DELIVERY_DONE_TEMPLATE_ID = "YXdCrQAHZlcZX1htYUiarrLmtkmKAjp7rynjwObgODo" //微信达达众包配送员配送完成推送
|
||||
)
|
||||
|
||||
func GetWeixinOpenIDsFromStoreID(storeID int) (retVal []string) {
|
||||
db := orm.NewOrm()
|
||||
var lists []orm.ParamsList
|
||||
num, err := db.Raw(`
|
||||
SELECT openid
|
||||
FROM weixins t1
|
||||
JOIN
|
||||
(SELECT id
|
||||
FROM weixins
|
||||
WHERE jxstoreid = ? AND parentid = -1) t2 ON t2.id = t1.parentid
|
||||
UNION
|
||||
SELECT openid
|
||||
FROM weixins
|
||||
WHERE jxstoreid = ? AND parentid = -1
|
||||
`, storeID, storeID).ValuesList(&lists)
|
||||
if err != nil || num == 0 {
|
||||
globals.SugarLogger.Infof("can not find openid for store:%s, error:%v", storeID, err)
|
||||
return retVal
|
||||
}
|
||||
for _, v := range lists {
|
||||
retVal = append(retVal, v[0].(string))
|
||||
}
|
||||
return retVal
|
||||
}
|
||||
|
||||
func SendMsgToStore(storeID int, templateID, downloadURL string, data interface{}) (err error) {
|
||||
openIDs := GetWeixinOpenIDsFromStoreID(storeID)
|
||||
errCount := 0
|
||||
for _, openID := range openIDs {
|
||||
globals.SugarLogger.Debugf("send to:%s, templateID:%s, msg:%s", openID, templateID, string(utils.MustMarshal(data)))
|
||||
// todo
|
||||
// err2 := api.WeixinAPI.MessageTemplateSend(openID, templateID, downloadURL, nil, data)
|
||||
// if err2 != nil {
|
||||
// err = err2
|
||||
// errCount++
|
||||
// }
|
||||
}
|
||||
if errCount < len(openIDs) {
|
||||
err = nil // 只要成功一个都当成成功
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func NotifyNewOrder(order *model.GoodsOrder) (err error) {
|
||||
sb := new(strings.Builder)
|
||||
sb.WriteString("老板")
|
||||
sb.WriteString(order.ConsigneeName)
|
||||
sb.WriteString("购买了商品")
|
||||
sb.WriteString(order.Skus[0].SkuName)
|
||||
sb.WriteString("共")
|
||||
sb.WriteString(utils.Int2Str(order.Skus[0].Count))
|
||||
sb.WriteString("份(")
|
||||
sb.WriteString(jxutils.IntPrice2StandardString(order.Skus[0].SalePrice))
|
||||
sb.WriteString("元/份)等,共支付了")
|
||||
sb.WriteString(jxutils.IntPrice2StandardString(order.SalePrice))
|
||||
sb.WriteString("元")
|
||||
data := map[string]interface{}{
|
||||
"first": map[string]interface{}{
|
||||
"value": sb.String(),
|
||||
"color": WX_NEW_ORDER_TEMPLATE_COLOR,
|
||||
},
|
||||
"day": map[string]interface{}{
|
||||
"value": FormatDeliveryTime(order),
|
||||
"color": WX_NEW_ORDER_TEMPLATE_COLOR,
|
||||
},
|
||||
"orderId": map[string]interface{}{
|
||||
"value": order.VendorOrderID,
|
||||
"color": WX_NEW_ORDER_TEMPLATE_COLOR,
|
||||
},
|
||||
"orderType": map[string]interface{}{
|
||||
"value": fmt.Sprintf("%s第%d号订单", model.VendorChineseNames[order.VendorID], order.OrderSeq),
|
||||
"color": WX_NEW_ORDER_TEMPLATE_COLOR,
|
||||
},
|
||||
"customerName": map[string]interface{}{
|
||||
"value": order.ConsigneeName,
|
||||
"color": WX_NEW_ORDER_TEMPLATE_COLOR,
|
||||
},
|
||||
"customerPhone": map[string]interface{}{
|
||||
"value": order.ConsigneeMobile,
|
||||
"color": WX_NEW_ORDER_TEMPLATE_COLOR,
|
||||
},
|
||||
}
|
||||
storeID := jxutils.GetJxStoreIDFromOrder(order)
|
||||
return SendMsgToStore(storeID, fmt.Sprintf("%s%d", WX_TO_ORDER_PAGE_URL, storeID), WX_NEWORDER_TEMPLATE_ID, data)
|
||||
}
|
||||
|
||||
func NotifyWaybillStatus(bill *model.Waybill, order *model.GoodsOrder) error {
|
||||
var title string
|
||||
var templateID string
|
||||
switch bill.Status {
|
||||
case model.WaybillStatusAccepted:
|
||||
if bill.WaybillVendorID == model.VendorIDMTPS {
|
||||
templateID = WX_MTPS_DELIVERY_GRABDONE_TEMPLATE_ID
|
||||
} else if bill.WaybillVendorID == model.VendorIDDada {
|
||||
templateID = WX_DADA_DELIVERY_GRABDONE_TEMPLATE_ID
|
||||
}
|
||||
title = fmt.Sprintf("%s %s#订单长时间无人配送,我们已安排%s配送员%s电话号码%s负责配送。^_^", model.VendorChineseNames[bill.OrderVendorID], bill.VendorOrderID, model.VendorChineseNames[bill.WaybillVendorID], bill.CourierName, bill.CourierMobile)
|
||||
case model.WaybillStatusDelivered:
|
||||
if bill.WaybillVendorID == model.VendorIDMTPS {
|
||||
templateID = WX_MTPS_DELIVERY_DONE_TEMPLATE_ID
|
||||
} else if bill.WaybillVendorID == model.VendorIDDada {
|
||||
templateID = WX_DADA_DELIVERY_DONE_TEMPLATE_ID
|
||||
}
|
||||
title = fmt.Sprintf("%s 第%d号订单的配送完成", model.VendorChineseNames[bill.OrderVendorID], order.OrderSeq)
|
||||
}
|
||||
if title != "" {
|
||||
data := map[string]interface{}{
|
||||
"first": map[string]interface{}{
|
||||
"value": title,
|
||||
"color": WX_HIGHLEVEL_TEMPLATE_COLOR,
|
||||
},
|
||||
"keyword1": map[string]interface{}{
|
||||
"value": bill.VendorOrderID,
|
||||
"color": WX_NEW_ORDER_TEMPLATE_COLOR,
|
||||
},
|
||||
"keyword2": map[string]interface{}{
|
||||
"value": bill.CourierName,
|
||||
"color": WX_NEW_ORDER_TEMPLATE_COLOR,
|
||||
},
|
||||
"keyword3": map[string]interface{}{
|
||||
"value": bill.CourierMobile,
|
||||
"color": WX_NEW_ORDER_TEMPLATE_COLOR,
|
||||
},
|
||||
"remark": map[string]interface{}{
|
||||
"value": FormatDeliveryTime(order),
|
||||
"color": WX_NEW_ORDER_TEMPLATE_COLOR,
|
||||
},
|
||||
}
|
||||
return SendMsgToStore(jxutils.GetJxStoreIDFromOrder(order), templateID, "", data)
|
||||
} else {
|
||||
globals.SugarLogger.Infof("NotifyWaybillStatus wrong, bill:%v", bill)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func FormatDeliveryTime(order *model.GoodsOrder) string {
|
||||
var tmpTime time.Time
|
||||
if order.ExpectedDeliveredTime == utils.DefaultTimeValue {
|
||||
tmpTime = order.OrderCreatedAt.Add(1 * time.Hour)
|
||||
} else {
|
||||
tmpTime = order.ExpectedDeliveredTime
|
||||
}
|
||||
left := tmpTime.Sub(time.Now()) / time.Minute
|
||||
leftHours := left / 60
|
||||
leftMinutes := left % 60
|
||||
return fmt.Sprintf("请于%s前送达(剩余时间%d小时%d分钟", utils.Time2Str(tmpTime), leftHours, leftMinutes)
|
||||
}
|
||||
@@ -18,8 +18,17 @@ const (
|
||||
var (
|
||||
VendorNames = map[int]string{
|
||||
VendorIDJD: "JD",
|
||||
VendorIDELM: "ELEME",
|
||||
VendorIDMTWM: "MT",
|
||||
VendorIDELM: "ELEME",
|
||||
VendorIDDada: "Dada",
|
||||
VendorIDMTPS: "MTPS",
|
||||
}
|
||||
VendorChineseNames = map[int]string{
|
||||
VendorIDJD: "京东",
|
||||
VendorIDMTWM: "美团",
|
||||
VendorIDELM: "饿了么",
|
||||
VendorIDDada: "达达众包",
|
||||
VendorIDMTPS: "美团配送",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ const (
|
||||
defTime2Delivered = 1 * time.Hour // 正常订单都是1小时达
|
||||
defTime2Schedule3rdCarrier = 330 * time.Second // 京东要求5分钟后才能转自送,保险起见,设置为5分半钟
|
||||
time2Schedule3rdCarrierGap4OrderStatus = 3 * time.Minute // 京东要求是运单状态为待抢单且超时5分钟,但为了防止没有运单事件,所以就拣货完成事件开始算,添加3分钟
|
||||
defTime2AutoPickupMin = 25 * time.Minute
|
||||
time2AutoPickupGap = 5 * time.Minute
|
||||
defTime2AutoPickupMin = 10 * time.Minute
|
||||
time2AutoPickupGap = 2 * time.Minute
|
||||
)
|
||||
|
||||
type WatchOrderInfo struct {
|
||||
@@ -72,25 +72,37 @@ func (s *DefScheduler) OnOrderNew(order *model.GoodsOrder) (err error) {
|
||||
order: order,
|
||||
}
|
||||
s.orderMap.Store(jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID), watchInfo)
|
||||
s.resetTimer(model.OrderStatusNew, watchInfo, 0)
|
||||
s.resetTimer(watchInfo, model.OrderStatusNew, order.OrderCreatedAt, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *DefScheduler) OnOrderStatusChanged(status *model.OrderStatus) (err error) {
|
||||
globals.SugarLogger.Debugf("OnOrderStatusChanged, status:%v", status)
|
||||
if savedOrderInfo := s.loadWatchOrderFromMap(status.VendorOrderID, status.VendorID); savedOrderInfo != nil {
|
||||
if status.Status > model.OrderStatusUnknown && status.Status < model.OrderStatusEndBegin {
|
||||
if status.Status > model.OrderStatusUnknown {
|
||||
globals.SugarLogger.Debugf("OnOrderStatusChanged, status:%v", status)
|
||||
if savedOrderInfo := s.loadWatchOrderFromMap(status.VendorOrderID, status.VendorID); savedOrderInfo != nil {
|
||||
s.updateOrderByStatus(savedOrderInfo.order, status)
|
||||
gap := 0 * time.Second
|
||||
if status.Status == model.OrderStatusAccepted {
|
||||
gap = time.Duration(rand.Int63n(int64(time2AutoPickupGap)))
|
||||
} else if status.Status == model.OrderStatusFinishedPickup {
|
||||
gap = time2Schedule3rdCarrierGap4OrderStatus
|
||||
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)
|
||||
}
|
||||
} else {
|
||||
s.stopTimer(savedOrderInfo)
|
||||
s.orderMap.Delete(jxutils.GetUniversalOrderIDFromOrderStatus(status))
|
||||
}
|
||||
s.resetTimer(status.Status, savedOrderInfo, gap)
|
||||
} else {
|
||||
s.stopTimer(savedOrderInfo)
|
||||
s.orderMap.Delete(jxutils.GetUniversalOrderIDFromOrderStatus(status))
|
||||
err = scheduler.ErrCanNotFindOrder
|
||||
}
|
||||
}
|
||||
return err
|
||||
@@ -98,60 +110,65 @@ func (s *DefScheduler) OnOrderStatusChanged(status *model.OrderStatus) (err erro
|
||||
|
||||
// 以下是运单
|
||||
func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill) (err error) {
|
||||
globals.SugarLogger.Debugf("OnWaybillStatusChanged, bill:%v", bill)
|
||||
if savedOrderInfo := s.loadWatchOrderFromMap(bill.VendorOrderID, bill.OrderVendorID); savedOrderInfo != nil {
|
||||
s.addWaybill2Map(savedOrderInfo, bill) // 这样写的原因是因为调试时,程度从中途运行,没有接受到WaybillStatusNew事件
|
||||
if bill.Status == model.WaybillStatusNew {
|
||||
if bill.OrderVendorID == bill.WaybillVendorID {
|
||||
if savedOrderInfo.timerStatus == model.OrderStatusFinishedPickup {
|
||||
s.resetTimer(model.OrderStatusFinishedPickup, savedOrderInfo, 0)
|
||||
} else {
|
||||
globals.SugarLogger.Infof("OnWaybillStatusChanged met other timer, status:%d", savedOrderInfo.timerStatus)
|
||||
if bill.Status > model.WaybillStatusUnknown {
|
||||
globals.SugarLogger.Debugf("OnWaybillStatusChanged, bill:%v", bill)
|
||||
if savedOrderInfo := s.loadWatchOrderFromMap(bill.VendorOrderID, bill.OrderVendorID); savedOrderInfo != nil {
|
||||
s.addWaybill2Map(savedOrderInfo, bill) // 这样写的原因是因为调试时,程度从中途运行,没有接受到WaybillStatusNew事件
|
||||
if bill.Status == model.WaybillStatusNew {
|
||||
if bill.OrderVendorID == bill.WaybillVendorID {
|
||||
if savedOrderInfo.timerStatus == model.OrderStatusFinishedPickup { // 如果当前TIMER还是OrderStatusFinishedPickup(在OnOrderStatusChanged中设置的),则重置
|
||||
s.resetTimer(savedOrderInfo, model.OrderStatusFinishedPickup, bill.WaybillCreatedAt, 0)
|
||||
} else {
|
||||
globals.SugarLogger.Infof("OnWaybillStatusChanged met other timer, status:%d", savedOrderInfo.timerStatus)
|
||||
}
|
||||
}
|
||||
}
|
||||
if savedOrderInfo.order.WaybillVendorID != model.VendorIDUnknown {
|
||||
globals.SugarLogger.Infof("OnWaybillStatusChanged multiple waybill created, bill:%v", bill)
|
||||
if bill.WaybillVendorID != bill.WaybillVendorID {
|
||||
s.GetDeliveryPlatformFromVendorID(bill.WaybillVendorID).CancelWaybill(bill)
|
||||
if savedOrderInfo.order.WaybillVendorID != model.VendorIDUnknown {
|
||||
globals.SugarLogger.Infof("OnWaybillStatusChanged multiple waybill created, bill:%v", bill)
|
||||
if bill.WaybillVendorID != bill.WaybillVendorID {
|
||||
s.GetDeliveryPlatformFromVendorID(bill.WaybillVendorID).CancelWaybill(bill)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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
|
||||
s.CurOrderManager.UpdateWaybillVendorID(bill)
|
||||
savedOrderInfo.order.WaybillVendorID = bill.WaybillVendorID
|
||||
}
|
||||
case model.WaybillStatusCanceled, model.WaybillStatusFailed:
|
||||
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
|
||||
}
|
||||
case model.WaybillStatusDelivering:
|
||||
if savedOrderInfo.order.VendorID != bill.WaybillVendorID {
|
||||
s.GetPurchasePlatformFromVendorID(bill.OrderVendorID).SelfDeliverDelievering(savedOrderInfo.order)
|
||||
}
|
||||
case model.WaybillStatusDelivered:
|
||||
if savedOrderInfo.order.VendorID != bill.WaybillVendorID {
|
||||
s.GetPurchasePlatformFromVendorID(bill.OrderVendorID).SelfDeliverDelievered(savedOrderInfo.order)
|
||||
}
|
||||
s.removeWaybillFromMap(savedOrderInfo, bill)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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:
|
||||
s.createWaybillOn3rdProviders(savedOrderInfo.order, bill)
|
||||
if savedOrderInfo.order.WaybillVendorID == bill.WaybillVendorID {
|
||||
bill.WaybillVendorID = model.VendorIDUnknown
|
||||
s.CurOrderManager.UpdateWaybillVendorID(bill)
|
||||
savedOrderInfo.order.WaybillVendorID = bill.WaybillVendorID
|
||||
}
|
||||
case model.WaybillStatusCanceled, model.WaybillStatusFailed:
|
||||
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
|
||||
}
|
||||
case model.WaybillStatusDelivering:
|
||||
if savedOrderInfo.order.VendorID != bill.WaybillVendorID {
|
||||
s.GetPurchasePlatformFromVendorID(bill.OrderVendorID).SelfDeliverDelievering(savedOrderInfo.order)
|
||||
}
|
||||
case model.WaybillStatusDelivered:
|
||||
if savedOrderInfo.order.VendorID != bill.WaybillVendorID {
|
||||
s.GetPurchasePlatformFromVendorID(bill.OrderVendorID).SelfDeliverDelievered(savedOrderInfo.order)
|
||||
}
|
||||
s.removeWaybillFromMap(savedOrderInfo, bill)
|
||||
}
|
||||
err = scheduler.ErrCanNotFindOrder
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *DefScheduler) addWaybill2Map(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) {
|
||||
@@ -165,6 +182,15 @@ func (s *DefScheduler) addWaybill2Map(savedOrderInfo *WatchOrderInfo, bill *mode
|
||||
savedOrderInfo.waybills = append(savedOrderInfo.waybills, bill)
|
||||
}
|
||||
|
||||
func (s *DefScheduler) removeWaybillFromMap(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) {
|
||||
for k, v := range savedOrderInfo.waybills {
|
||||
if v.VendorWaybillID == bill.VendorWaybillID && v.WaybillVendorID == bill.WaybillVendorID {
|
||||
savedOrderInfo.waybills = append(savedOrderInfo.waybills[0:k], savedOrderInfo.waybills[k+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DefScheduler) createWaybillOn3rdProviders(order *model.GoodsOrder, excludeBill *model.Waybill) (err error) {
|
||||
globals.SugarLogger.Debugf("createWaybillOn3rdProviders, order:%v", order)
|
||||
successCount := 0
|
||||
@@ -224,26 +250,11 @@ func (s *DefScheduler) loadWatchOrderFromMap(vendorOrderID string, vendorID int)
|
||||
return realSavedInfo
|
||||
}
|
||||
|
||||
func (s *DefScheduler) removeWaybillFromMap(savedOrderInfo *WatchOrderInfo, bill *model.Waybill) {
|
||||
if savedOrderInfo == nil {
|
||||
savedOrderInfo = s.loadWatchOrderFromMap(bill.VendorOrderID, bill.OrderVendorID)
|
||||
}
|
||||
if savedOrderInfo != nil {
|
||||
for k, v := range savedOrderInfo.waybills {
|
||||
if v.VendorWaybillID == bill.VendorWaybillID && v.WaybillVendorID == bill.WaybillVendorID {
|
||||
savedOrderInfo.waybills = append(savedOrderInfo.waybills[0:k], savedOrderInfo.waybills[k+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DefScheduler) getLatestPickupTimeout(order *model.GoodsOrder, configTimeout time.Duration) (retVal time.Duration) {
|
||||
beginTime := order.StatusTime
|
||||
func (s *DefScheduler) getBeginTime4LatestPickup(order *model.GoodsOrder) (retVal time.Time) {
|
||||
if order.ExpectedDeliveredTime != utils.DefaultTimeValue {
|
||||
beginTime = order.ExpectedDeliveredTime.Add(-defTime2Delivered)
|
||||
return order.ExpectedDeliveredTime.Add(-defTime2Delivered)
|
||||
}
|
||||
return jxutils.GetRealTimeout(beginTime, configTimeout)
|
||||
return order.StatusTime
|
||||
}
|
||||
|
||||
func (s *DefScheduler) stopTimer(savedOrderInfo *WatchOrderInfo) {
|
||||
@@ -253,24 +264,17 @@ func (s *DefScheduler) stopTimer(savedOrderInfo *WatchOrderInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DefScheduler) resetTimer(status int, savedOrderInfo *WatchOrderInfo, gap time.Duration) {
|
||||
func (s *DefScheduler) resetTimer(savedOrderInfo *WatchOrderInfo, status int, beginTime time.Time, gap time.Duration) {
|
||||
globals.SugarLogger.Debugf("resetTimer status:%v, orderid:%v", status, savedOrderInfo.order.VendorOrderID)
|
||||
s.stopTimer(savedOrderInfo)
|
||||
config := s.mergeOrderStatusConfig(status, s.GetPurchasePlatformFromVendorID(savedOrderInfo.order.VendorID).GetStatusActionConfig(status))
|
||||
if config != nil && config.TimeoutAction != nil {
|
||||
var timeout time.Duration
|
||||
if status == model.OrderStatusNew {
|
||||
timeout = config.Timeout // 绝对值
|
||||
} else if status == model.OrderStatusAccepted {
|
||||
timeout = s.getLatestPickupTimeout(savedOrderInfo.order, config.Timeout)
|
||||
} else {
|
||||
timeout = jxutils.GetRealTimeout(savedOrderInfo.order.StatusTime, config.Timeout)
|
||||
}
|
||||
timeout += gap
|
||||
timeout := jxutils.GetRealTimeout(beginTime, config.Timeout) + gap
|
||||
globals.SugarLogger.Debugf("resetTimer timeout:%v, orderid:%v", timeout, savedOrderInfo.order.VendorOrderID)
|
||||
savedOrderInfo.timerStatus = status
|
||||
savedOrderInfo.timer = time.AfterFunc(timeout, func() {
|
||||
config.TimeoutAction(savedOrderInfo.order)
|
||||
savedOrderInfo.timerStatus = 0
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ var (
|
||||
var (
|
||||
ErrStatusIsNotOKForOperation = errors.New("当前状态操作无效")
|
||||
ErrCanNotCreateAtLeastOneWaybill = errors.New("一个运单都不能创建")
|
||||
ErrCanNotFindOrder = errors.New("不能找到订单(一般是由于事件错序)")
|
||||
ErrCanNotFindWaybill = errors.New("不能找到运单(一般是由于事件错序)")
|
||||
)
|
||||
|
||||
type StatusActionConfig struct {
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/astaxie/beego"
|
||||
|
||||
"github.com/astaxie/beego/orm"
|
||||
_ "github.com/go-sql-driver/mysql" // import your used driver
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
Reference in New Issue
Block a user