diff --git a/.gitignore b/.gitignore index 816a49125..054440af3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ debug .DS_Store *.log *.bak +OFF/ \ No newline at end of file diff --git a/business/controller/dada/waybill.go b/business/controller/dada/waybill.go index ea240bb7b..d354dd699 100644 --- a/business/controller/dada/waybill.go +++ b/business/controller/dada/waybill.go @@ -29,6 +29,9 @@ func (c *WaybillController) onWaybillMsg(msg *dadaapi.CallbackMsg) (retVal *dada order := c.callbackMsg2Waybill(msg) switch msg.OrderStatus { case dadaapi.OrderStatusWaitingForAccept: + if result, err := api.DadaAPI.QueryOrderInfo(msg.OrderID); err == nil { + order.DesiredFee = controller.StandardPrice2Int(utils.Interface2FloatWithDefault(result["deliveryFee"], 0.0)) + } order.Status = model.WaybillStatusNew case dadaapi.OrderStatusAccepted: order.Status = model.WaybillStatusAccepted diff --git a/business/controller/elm/waybill.go b/business/controller/elm/waybill.go index 1ea7f3c7a..a27b60fed 100644 --- a/business/controller/elm/waybill.go +++ b/business/controller/elm/waybill.go @@ -8,6 +8,7 @@ import ( "git.rosy.net.cn/jx-callback/business/controller" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/globals/api" ) type WaybillController struct { @@ -23,6 +24,10 @@ func (c *WaybillController) OnWaybillStatusMsg(msg *elmapi.CallbackWaybillStatus func (c *WaybillController) onWaybillStatusMsg(msg *elmapi.CallbackWaybillStatusMsg) (retVal *elmapi.CallbackResponse) { order := c.callbackMsg2Waybill(msg) if msg.MsgType == elmapi.MsgTypeWaybillWait4DeliveryVendor { + if result, err := api.ElmAPI.GetOrder(msg.OrderID); err == nil { + order.DesiredFee = controller.StandardPrice2Int(utils.Interface2FloatWithDefault(result["deliverFee"], 0.0) + + utils.Interface2FloatWithDefault(result["vipDeliveryFeeDiscount"], 0.0)) + } order.Status = model.WaybillStatusNew } else if msg.MsgType == elmapi.MsgTypeWaybillPickingUp { order.Status = model.WaybillStatusAccepted diff --git a/business/controller/jd/waybill.go b/business/controller/jd/waybill.go index b7d8007c7..fa8beb6a3 100644 --- a/business/controller/jd/waybill.go +++ b/business/controller/jd/waybill.go @@ -6,6 +6,7 @@ import ( "git.rosy.net.cn/jx-callback/business/controller" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/globals/api" ) type WaybillController struct { @@ -22,6 +23,11 @@ func (c *WaybillController) onWaybillMsg(msg *jdapi.CallbackDeliveryStatusMsg) ( order := c.callbackMsg2Waybill(msg) switch msg.DeliveryStatus { case jdapi.DeliveryStatusWait4Grap: + if result, err := api.JdAPI.QuerySingleOrder(msg.OrderID); err == nil { + order.DesiredFee = utils.Interface2Int64WithDefault(result["orderFreightMoney"], 0) + + utils.Interface2Int64WithDefault(result["merchantPaymentDistanceFreightMoney"], 0) + + utils.Interface2Int64WithDefault(result["tips"], 0) + } order.Status = model.WaybillStatusNew case jdapi.DeliveryStatusAccepted: order.Status = model.WaybillStatusAccepted diff --git a/business/controller/mtps/waybill.go b/business/controller/mtps/waybill.go index 0ba99d9c4..656f6fc17 100644 --- a/business/controller/mtps/waybill.go +++ b/business/controller/mtps/waybill.go @@ -1,6 +1,8 @@ package mtps import ( + "math" + "git.rosy.net.cn/baseapi/platformapi/mtpsapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/controller" @@ -49,6 +51,7 @@ func (c *WaybillController) onWaybillMsg(msg *mtpsapi.CallbackOrderMsg) (retVal order := c.callbackMsg2Waybill(msg) switch msg.Status { case mtpsapi.OrderStatusWaitingForSchedule: + order.DesiredFee = c.calculateDeliveryFee(order) order.Status = model.WaybillStatusNew case mtpsapi.OrderStatusAccepted: order.Status = model.WaybillStatusAccepted @@ -79,6 +82,53 @@ func (c *WaybillController) callbackMsg2Waybill(msg *mtpsapi.CallbackOrderMsg) ( return retVal } +func (c *WaybillController) calculateDeliveryFee(bill *model.Waybill) (retVal int64) { + order, err := controller.OrderManager.LoadOrder(bill.VendorOrderID, bill.OrderVendorID) + if err != nil { + return 0 + } + + var lists []orm.ParamsList + db := orm.NewOrm() + JxStoreID := jxutils.GetJxStoreIDFromOrder(order) + num, err := db.Raw(` + SELECT t2.price, t2.lng, t2.lat + FROM jxstore t1 + JOIN mtpsdeliveryprice t2 ON t2.citycode = t1.area + WHERE t1.storeid = ? + `, JxStoreID).ValuesList(&lists) + + var delieveryFee int64 + if err == nil && num == 1 { + delieveryFee = utils.Str2Int64(lists[0][0].(string)) + } else { + globals.SugarLogger.Warnf("calculateDeliveryFee can not cal delivery fee for orderid:%s", order.VendorOrderID) + return 0 + } + + lng := utils.Str2Float64(lists[0][1].(string)) + lat := utils.Str2Float64(lists[0][2].(string)) + lng2, lat2, _ := controller.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType) + + distance := jxutils.EarthDistance(lat, lng, lat2, lng2) * 1.4 + if distance < 3 { + } else if distance < 5 { + delieveryFee += controller.StandardPrice2Int(math.Ceil(distance - 3)) + } else { + delieveryFee += controller.StandardPrice2Int(2 + 2*math.Ceil(distance-5)) + } + + if order.Weight < 5*1000 { + } else if order.Weight < 10*1000 { + delieveryFee += controller.StandardPrice2Int(0.5 * float64(order.Weight/1000-5)) + } else if order.Weight < 20*1000 { + delieveryFee += controller.StandardPrice2Int(2.5 + 1*float64(order.Weight/1000-10)) + } else { + delieveryFee += controller.StandardPrice2Int(2.5 + 10 + 2*float64(order.Weight/1000-20)) + } + return delieveryFee +} + // DeliveryPlatformHandler func (c *WaybillController) CreateWaybill(order *model.GoodsOrder) (err error) { globals.SugarLogger.Infof("CreateWaybill bill:%v", order) diff --git a/business/jxutils/jxutils.go b/business/jxutils/jxutils.go index 67cc5d051..6cc646955 100644 --- a/business/jxutils/jxutils.go +++ b/business/jxutils/jxutils.go @@ -1,6 +1,8 @@ package jxutils import ( + "fmt" + "math" "math/rand" "strings" "sync" @@ -8,7 +10,6 @@ import ( "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/globals" ) const ( @@ -55,7 +56,8 @@ func SplitUniversalOrderID(universalOrderID string) (orderID string, vendorID in } else if orderIDLen == len("3022716176275221584") { vendorID = model.VendorIDELM } else { - globals.SugarLogger.Errorf("unkown order type:%v", universalOrderID) + // globals.SugarLogger.Errorf("unkown order type:%v", universalOrderID) + panic(fmt.Sprintf("unkown order type:%v", universalOrderID)) vendorID = model.VendorIDUnknown } orderID = universalOrderID @@ -87,3 +89,15 @@ func GetRealTimeout(beginTime time.Time, timeout time.Duration) time.Duration { } return retVal } + +func EarthDistance(lat1, lng1, lat2, lng2 float64) float64 { + radius := 6378.137 + rad := math.Pi / 180.0 + lat1 = lat1 * rad + lng1 = lng1 * rad + lat2 = lat2 * rad + lng2 = lng2 * rad + theta := lng2 - lng1 + dist := math.Acos(math.Sin(lat1)*math.Sin(lat2) + math.Cos(lat1)*math.Cos(lat2)*math.Cos(theta)) + return dist * radius +} diff --git a/business/jxutils/jxutils_test.go b/business/jxutils/jxutils_test.go new file mode 100644 index 000000000..46fe309a0 --- /dev/null +++ b/business/jxutils/jxutils_test.go @@ -0,0 +1,13 @@ +package jxutils + +import ( + "fmt" + "testing" +) + +func TestEarthDistance(t *testing.T) { + lat1, lng1 := 32.060255, 118.796877 + lat2, lng2 := 39.904211, 116.407395 + distance := EarthDistance(lat1, lng1, lat2, lng2) + fmt.Print(distance) +} diff --git a/business/scheduler/defsch/defsch.go b/business/scheduler/defsch/defsch.go index 4b9457e53..ae9e0843b 100644 --- a/business/scheduler/defsch/defsch.go +++ b/business/scheduler/defsch/defsch.go @@ -23,9 +23,10 @@ const ( ) type WatchOrderInfo struct { - order *model.GoodsOrder // order里的信息是保持更新的 - waybills []*model.Waybill // 这个waybills里的状态信息是不真实的,只使用id相关的信息 - timer *time.Timer + order *model.GoodsOrder // order里的信息是保持更新的 + waybills []*model.Waybill // 这个waybills里的状态信息是不真实的,只使用id相关的信息 + timerStatus int + timer *time.Timer } // 重要:此调度器要求同一定单的处理逻辑必须是序列化了的,不然会有并发问题 @@ -99,12 +100,17 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill) (err error) { globals.SugarLogger.Debugf("OnWaybillStatusChanged, bill:%v", bill) savedOrderInfo := s.loadWatchOrderFromMap(bill.VendorOrderID, bill.OrderVendorID) if bill.Status == model.WaybillStatusNew { - if savedOrderInfo.order.WaybillVendorID == model.VendorIDUnknown { - s.resetTimer(model.OrderStatusFinishedPickup, savedOrderInfo, 0) + 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) + } err = s.addWaybill2Map(savedOrderInfo, bill) - } else { + } + if savedOrderInfo.order.WaybillVendorID != model.VendorIDUnknown { globals.SugarLogger.Infof("OnWaybillStatusChanged multiple waybill created, bill:%v", bill) - if bill.WaybillVendorID != bill.OrderVendorID { + if bill.WaybillVendorID != bill.WaybillVendorID { s.GetDeliveryPlatformFromVendorID(bill.WaybillVendorID).CancelWaybill(bill) } } @@ -263,12 +269,15 @@ func (s *DefScheduler) resetTimer(status int, savedOrderInfo *WatchOrderInfo, ga config := s.mergeOrderStatusConfig(status, s.GetPurchasePlatformFromVendorID(savedOrderInfo.order.VendorID).GetStatusActionConfig(status)) if config != nil && config.TimeoutAction != nil { var timeout time.Duration - if status == model.OrderStatusAccepted { + 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) } globals.SugarLogger.Debugf("resetTimer timeout:%v, orderid:%v", timeout, savedOrderInfo.order.VendorOrderID) + savedOrderInfo.timerStatus = status savedOrderInfo.timer = time.AfterFunc(timeout+gap, func() { config.TimeoutAction(savedOrderInfo.order) })