222 lines
8.8 KiB
Go
222 lines
8.8 KiB
Go
package delivery
|
||
|
||
import (
|
||
"fmt"
|
||
"git.rosy.net.cn/baseapi/platformapi/mtpsapi"
|
||
"math"
|
||
"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/business/model/dao"
|
||
"git.rosy.net.cn/jx-callback/business/partner"
|
||
"git.rosy.net.cn/jx-callback/globals"
|
||
)
|
||
|
||
const (
|
||
warningDistance = 10 // 公里
|
||
warningWeight = 50 * 1000 // 克
|
||
// maxDiffFee2Mtps = 200 // 与美团配送最多差价
|
||
// maxAddFee = 200 // 最大增加费用,单位为分,超过不发三方配送了
|
||
defMaxDeliveryFee = 10000 // 创建运单最高价
|
||
alarmFee = 1500 // 配送费报警阈值
|
||
)
|
||
|
||
func CallCreateWaybillPolicy(deliveryFee, maxDeliveryFee int64, order *model.GoodsOrder, waybillVendorID int) (err error) {
|
||
if maxDeliveryFee <= 0 || maxDeliveryFee > defMaxDeliveryFee {
|
||
maxDeliveryFee = defMaxDeliveryFee
|
||
}
|
||
if deliveryFee > maxDeliveryFee {
|
||
errStr := fmt.Sprintf("超最高限价, 所需运费:%s, 最高限价:%s", jxutils.IntPrice2StandardCurrencyString(deliveryFee), jxutils.IntPrice2StandardCurrencyString(maxDeliveryFee))
|
||
err = fmt.Errorf(errStr)
|
||
globals.SugarLogger.Debugf("CallCreateWaybillPolicy orderID:%s, 平台:%s运单,创建出错:%s", order.VendorOrderID, model.VendorChineseNames[waybillVendorID], errStr)
|
||
}
|
||
return err
|
||
}
|
||
|
||
func CalculateDeliveryFee(db *dao.DaoDB, jxStoreID int, hint string, consigneeLng, consigneeLat, coordinateType, weight int, billTime time.Time) (deliveryFee, addFee int64, err error) {
|
||
globals.SugarLogger.Debugf("CalculateOrderDeliveryFee orderID:%s", hint)
|
||
if db == nil {
|
||
db = dao.GetDB()
|
||
}
|
||
var lng, lat float64
|
||
priceInfo := &struct {
|
||
CityPrice int64
|
||
DistrictPrice int64
|
||
Lng int
|
||
Lat int
|
||
}{}
|
||
if err = dao.GetRow(db, priceInfo, `
|
||
SELECT
|
||
t2.mtps_price city_price, t2.mtps_price district_price, t1.lng, t1.lat
|
||
FROM store t1
|
||
LEFT JOIN place t2 ON t2.level = 2 AND t2.code = t1.city_code
|
||
LEFT JOIN place t3 ON t3.level = 3 AND t2.code = t1.district_code
|
||
WHERE t1.id = ? AND t1.deleted_at = ?
|
||
`, jxStoreID, utils.DefaultTimeValue); err != nil {
|
||
return 0, 0, err
|
||
}
|
||
lng = jxutils.IntCoordinate2Standard(priceInfo.Lng)
|
||
lat = jxutils.IntCoordinate2Standard(priceInfo.Lat)
|
||
if deliveryFee = priceInfo.DistrictPrice; deliveryFee == 0 {
|
||
deliveryFee = priceInfo.CityPrice
|
||
}
|
||
if deliveryFee == 0 {
|
||
// globals.SugarLogger.Warnf("CalculateOrderDeliveryFee 查不到美团配送价格 orderID:%s", hint)
|
||
deliveryFee = 650
|
||
}
|
||
if lng == 0 || lat == 0 {
|
||
globals.SugarLogger.Infof("[运营]计算订单配送费orderID:%s,门店:%d没有坐标信息", hint, jxStoreID)
|
||
return 0, 0, fmt.Errorf("找不到门店:%d的坐标", jxStoreID)
|
||
}
|
||
lng2, lat2, _ := jxutils.IntCoordinate2MarsStandard(consigneeLng, consigneeLat, coordinateType)
|
||
|
||
var distanceAddFee, weightAddFee, timeAddFee int64
|
||
|
||
// 距离加价
|
||
distance := jxutils.WalkingDistance(lng, lat, lng2, lat2)
|
||
if distance > warningDistance {
|
||
//globals.SugarLogger.Infof("[运营]计算订单配送费orderID:%s,距离%.3fkm太远,请检查门店坐标信息", hint, distance)
|
||
}
|
||
distanceAddFee = int64(jxutils.CalcStageValue([][]float64{
|
||
[]float64{
|
||
7,
|
||
300,
|
||
},
|
||
[]float64{
|
||
5,
|
||
200,
|
||
},
|
||
[]float64{
|
||
3,
|
||
100,
|
||
},
|
||
}, distance))
|
||
|
||
// 重量加价
|
||
if weight > warningWeight {
|
||
//globals.SugarLogger.Infof("[运营]计算订单配送费orderID:%s,重量:%dg太重,请检查商品属性", hint, weight)
|
||
}
|
||
weightAddFee = int64(jxutils.CalcStageValue([][]float64{
|
||
[]float64{
|
||
20,
|
||
200,
|
||
},
|
||
[]float64{
|
||
10,
|
||
100,
|
||
},
|
||
[]float64{
|
||
5,
|
||
50,
|
||
},
|
||
}, float64(weight)/1000))
|
||
|
||
// 其它加价
|
||
hour, min, sec := billTime.Clock()
|
||
totalSeconds := hour*3600 + min*60 + sec
|
||
// 午高峰加价
|
||
if totalSeconds >= 11*3600 && totalSeconds <= 14*3600 { // 11:00 -- 14:00
|
||
timeAddFee = jxutils.StandardPrice2Int(2)
|
||
} else if totalSeconds >= 21*3600 || totalSeconds <= 6*3600 { // 21:00 -- 06:00 夜间加价
|
||
timeAddFee = jxutils.StandardPrice2Int(3)
|
||
}
|
||
addFee = distanceAddFee + weightAddFee + timeAddFee
|
||
globals.SugarLogger.Debugf("CalculateOrderDeliveryFee orderID:%s, deliveryFee:%d addFee:%d, distance:%.3fkm distanceAddFee:%d, weight:%dg weightAddFee:%d, time:%s timeAddFee:%d",
|
||
hint, deliveryFee, addFee, distance, distanceAddFee, weight, weightAddFee, utils.Time2TimeStr(billTime), timeAddFee)
|
||
return deliveryFee + addFee, addFee, nil
|
||
}
|
||
|
||
func CalculateOrderDeliveryFee(order *model.GoodsOrder, billTime time.Time, db *dao.DaoDB) (deliveryFee, addFee int64, err error) {
|
||
return CalculateDeliveryFee(db, jxutils.GetSaleStoreIDFromOrder(order), order.VendorOrderID, order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType, order.Weight, billTime)
|
||
}
|
||
|
||
func CalculateBillDeliveryFee(bill *model.Waybill) (deliveryFee, addFee int64) {
|
||
order, err := partner.CurOrderManager.LoadOrder(bill.VendorOrderID, bill.OrderVendorID)
|
||
if err != nil {
|
||
return 0, 0
|
||
}
|
||
deliveryFee, addFee, _ = CalculateOrderDeliveryFee(order, bill.StatusTime, nil)
|
||
return deliveryFee, addFee
|
||
}
|
||
|
||
// 日志提示检查订单运费
|
||
func OnWaybillCreated(waybill *model.Waybill) {
|
||
deliveryFee := int64(math.Max(float64(waybill.DesiredFee), float64(waybill.ActualFee)))
|
||
if deliveryFee > alarmFee {
|
||
globals.SugarLogger.Infof("[运营]%s订单, orderID:%s, 成功创建%s运单:%s, 配送费:%s太高(大于%s),请知悉!", model.VendorChineseNames[waybill.OrderVendorID], waybill.VendorOrderID,
|
||
model.VendorChineseNames[waybill.WaybillVendorID], waybill.VendorWaybillID, jxutils.IntPrice2StandardCurrencyString(deliveryFee), jxutils.IntPrice2StandardCurrencyString(alarmFee))
|
||
}
|
||
}
|
||
|
||
// 订单骑手信息推送:将获取到的三方配送订单,且订单状态为配送中的订单,将配送人员的信息返回给订单方
|
||
// 该方法为定时任务,没五分钟推送一次订单消息,订单状态发生变化时
|
||
//配送状态code,如下提供配送状态枚举值,
|
||
//以及各配送状态对应在C端(用户端)和B端(商家PC端)后台展示的配送状态信息。
|
||
//未同步配送状态时(C端:商家已接单;B端:待发配送)
|
||
//0-配送单发往配送(C端:商家已接单;B端:待骑手接单)
|
||
//1-已创建配送包裹(C端:商家已接单;B端:待骑手接单)
|
||
//5-已分配骑手(C端:商家已接单;B端:已分配骑手)
|
||
//10-骑手已接单(C端:骑手正在赶往商家;B端:待骑手取货)
|
||
//15-骑手已到店(C端:骑手到店取货中;B端:骑手已到店)
|
||
//20-骑手已取货(C端:商品配送中/骑手正在送货;B端:骑手已取货)
|
||
//40-骑手已送达(C端:商品已送达;B端:骑手已送达)
|
||
//100-配送单已取消(C端:商家已接单;B端:配送已取消)
|
||
//注:若同步配送状态为“配送单已取消”,接口仍支持继续同步配送状态。 说明:商家如未上传此信息,则平台默认值为20(现已要求必传)。
|
||
func GetOrderRiderInfoToPlatform(orderId string) {
|
||
params := make(map[string]interface{}, 0)
|
||
params["brandID"] = 0
|
||
params["statuss"] = 20
|
||
params["isDateFinish"] = false
|
||
params["isIncludeFake"] = true
|
||
params["mustInvoice"] = false
|
||
params["adjustCount"] = 0
|
||
params["waybillVendorIDs"] = `[101,102,103]`
|
||
if orderId != "" { // 订单id会忽略其他参数
|
||
params["keyword"] = orderId
|
||
}
|
||
//params["offset"] = 0
|
||
//params["pageSize"] = 10000
|
||
// 查询三天内一万条数据
|
||
orders, _, err := dao.GetOrders(dao.GetDB(), nil, false, true, time.Now().Add(-24*3*time.Hour).Format("2006-01-02"), time.Now().Format("2006-01-02"), false, nil, false, "", params, 0, 10000)
|
||
if err != nil {
|
||
globals.SugarLogger.Errorf("GetOrder err :%v", err)
|
||
return
|
||
}
|
||
|
||
for _, v := range orders {
|
||
var riderInfo *mtpsapi.RiderInfo
|
||
if handlerInfo := partner.GetDeliveryPlatformFromVendorID(v.WaybillVendorID); handlerInfo != nil {
|
||
riderInfo, err = handlerInfo.Handler.GetRiderInfo(v.VendorOrderID, utils.Str2Int64(v.VendorWaybillId2Waybill), v.VendorWaybillID)
|
||
if err != nil {
|
||
globals.SugarLogger.Errorf("Get Order waybill rider info err :%v", err)
|
||
continue
|
||
}
|
||
}
|
||
|
||
// 目前只推送美团骑手信息
|
||
switch v.VendorID {
|
||
case model.VendorIDMTWM: // 美团发单
|
||
paramsMap := utils.Struct2Map(riderInfo, "", true)
|
||
if handler := partner.GetPurchaseOrderHandlerFromVendorID(v.VendorID); handler != nil {
|
||
if err := handler.GetOrderRider(v.VendorOrgCode, v.VendorOrderID, paramsMap); err != nil {
|
||
globals.SugarLogger.Errorf("Error pushing meituan rider information :%v", err)
|
||
}
|
||
}
|
||
case model.VendorIDELM: // 饿了么
|
||
case model.VendorIDEBAI: // 饿百发单
|
||
|
||
case model.VendorIDJD: // 京东发单
|
||
case model.VendorIDGD: // 美团发单
|
||
case model.VendorIDYB: // 银豹发单
|
||
case model.VendorIDJDShop: // 京东商城
|
||
case model.VendorIDWSC: // 微盟微商城
|
||
default:
|
||
globals.SugarLogger.Errorf("Order source error, non system order")
|
||
return
|
||
}
|
||
}
|
||
return
|
||
}
|