731 lines
26 KiB
Go
731 lines
26 KiB
Go
package sfps
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"net/http"
|
||
"strings"
|
||
"time"
|
||
|
||
beego "github.com/astaxie/beego/server/web"
|
||
|
||
tao "git.rosy.net.cn/baseapi/platformapi/tao_vegetable"
|
||
"git.rosy.net.cn/jx-callback/business/partner/purchase/tao_vegetable"
|
||
|
||
"git.rosy.net.cn/jx-callback/globals"
|
||
|
||
"git.rosy.net.cn/jx-callback/business/partner/delivery"
|
||
|
||
"git.rosy.net.cn/jx-callback/business/jxutils"
|
||
|
||
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
|
||
"git.rosy.net.cn/jx-callback/globals/api"
|
||
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||
"git.rosy.net.cn/jx-callback/business/partner"
|
||
|
||
"git.rosy.net.cn/baseapi/platformapi/sfps2"
|
||
"git.rosy.net.cn/jx-callback/business/model"
|
||
)
|
||
|
||
type DeliveryHandler struct {
|
||
}
|
||
|
||
var (
|
||
curDeliveryHandler *DeliveryHandler
|
||
)
|
||
|
||
func init() {
|
||
if api.SfPsAPI != nil {
|
||
curDeliveryHandler = new(DeliveryHandler)
|
||
partner.RegisterDeliveryPlatform(curDeliveryHandler, true)
|
||
}
|
||
}
|
||
|
||
func (d DeliveryHandler) GetVendorID() int {
|
||
return model.VendorIDSFPS
|
||
}
|
||
|
||
func (d DeliveryHandler) CreateStore(ctx *jxcontext.Context, storeDetail *dao.StoreDetail2) (vendorStoreID string, status int, err error) {
|
||
return "", 0, fmt.Errorf("顺丰派送暂不支持此操作")
|
||
}
|
||
|
||
func (d DeliveryHandler) GetStore(ctx *jxcontext.Context, storeID int, vendorStoreID string) (storeDetail *dao.StoreDetail2, err error) {
|
||
store, err := dao.GetStoreDetail(dao.GetDB(), utils.Str2Int(vendorStoreID), model.VendorIDSFPS, "")
|
||
if err == nil {
|
||
storeDetail = &dao.StoreDetail2{
|
||
Store: model.Store{
|
||
Name: store.Name,
|
||
Tel1: store.Tel1,
|
||
Address: store.Address,
|
||
Lat: store.Lat,
|
||
Lng: store.Lng,
|
||
},
|
||
VendorID: model.VendorIDSFPS,
|
||
VendorStoreID: utils.Int2Str(storeID),
|
||
CourierStatus: model.StoreStatusOpened,
|
||
}
|
||
}
|
||
return storeDetail, err
|
||
}
|
||
|
||
func (d DeliveryHandler) IsErrStoreNotExist(err error) bool {
|
||
return false
|
||
}
|
||
|
||
func (d DeliveryHandler) IsErrStoreExist(err error) bool {
|
||
return false
|
||
}
|
||
|
||
func (d DeliveryHandler) CreateWaybill(order *model.GoodsOrder, maxDeliveryFee int64) (bill *model.Waybill, err error) {
|
||
vendorOrgCode, err := dao.GetVendorOrgCode(dao.GetDB(), model.VendorIDSFPS, "", model.VendorOrgTypeDelivery)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
if len(vendorOrgCode) > 0 && vendorOrgCode[0].IsOpen == model.YES {
|
||
return nil, fmt.Errorf("此平台配送已被系统关闭,暂不发配送 [%v]", vendorOrgCode[0].Comment)
|
||
}
|
||
|
||
store, err := dao.GetStoreDetail(dao.GetDB(), getReallyStoreID(order.StoreID, order.JxStoreID), 0, "")
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
var (
|
||
weight int
|
||
flag = false
|
||
productDetail []*sfps2.ProductDetail
|
||
param = &sfps2.CreateOrderReq{}
|
||
)
|
||
if order.Weight >= 49500 || order.Weight <= model.NO {
|
||
weight = 49500
|
||
} else {
|
||
weight = order.Weight
|
||
}
|
||
param = &sfps2.CreateOrderReq{
|
||
//ShopId: sfps2.SFShopStoreID,
|
||
ShopOrderId: order.VendorOrderID,
|
||
OrderSource: GetVendorSource(order.VendorID),
|
||
OrderTime: order.CreatedAt.Unix(),
|
||
ShopType: sfps2.OrderTypeSF,
|
||
LbsType: sfps2.LbsTypeGD,
|
||
RiderPickMethod: sfps2.RiderPickUpMethodSTU,
|
||
Receive: &sfps2.ReceiveAddress{
|
||
UserName: order.ConsigneeName,
|
||
UserPhone: order.ConsigneeMobile,
|
||
UserAddress: order.ConsigneeAddress,
|
||
UserLat: utils.Float64ToStr(jxutils.IntCoordinate2Standard(order.ConsigneeLat)),
|
||
UserLng: utils.Float64ToStr(jxutils.IntCoordinate2Standard(order.ConsigneeLng)),
|
||
},
|
||
Shop: &sfps2.SfShopInfo{
|
||
ShopName: order.StoreName,
|
||
ShopPhone: store.Tel1,
|
||
ShopAddress: store.Address,
|
||
ShopLat: utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lat)),
|
||
ShopLng: utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lng)),
|
||
},
|
||
OrderDetail: &sfps2.OrderDetail{
|
||
TotalPrice: order.ActualPayPrice,
|
||
ProductType: sfps2.ProductTypeFresh,
|
||
WeightGram: int64(weight),
|
||
ProductNum: int64(order.GoodsCount),
|
||
ProductTypeNum: int64(order.SkuCount),
|
||
},
|
||
}
|
||
// 城市维度获取顺丰门店id
|
||
if len(store.CityName) > 0 {
|
||
for k, v := range sfps2.SFCityStoreIDs {
|
||
//globals.SugarLogger.Debugf("sfps GetWaybillFee store.CityName==%s,k=%s", store.CityName, k)
|
||
if strings.Contains(store.CityName, k) || store.CityName == k {
|
||
param.ShopId = v
|
||
flag = true
|
||
}
|
||
}
|
||
}
|
||
if flag == false || len(store.CityName) == 0 {
|
||
flag = true //todo sf测试用
|
||
//return nil, errors.New("此城市暂时不在,顺丰配送业务范围")
|
||
}
|
||
if len(order.Skus) != model.NO {
|
||
for _, v := range order.Skus {
|
||
productDetail = append(productDetail, &sfps2.ProductDetail{
|
||
ProductName: v.SkuName,
|
||
ProductNum: int64(v.Count),
|
||
})
|
||
}
|
||
} else {
|
||
productDetail = append(productDetail, &sfps2.ProductDetail{
|
||
ProductName: "本地暂无商品储存信息",
|
||
ProductNum: int64(model.YES),
|
||
})
|
||
}
|
||
param.OrderDetail.ProductDetail = productDetail
|
||
|
||
sfOrderID, sfBillID, sfTotalPrice, sfReallyPrice, err := api.SfPsAPI.CreateOrder(param)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// 系统加价
|
||
desiredFee := utils.Float64TwoInt(sfTotalPrice) + utils.WayBillDeliveryMarkUp
|
||
// 运营加价
|
||
desiredFee += store.FreightMarkup
|
||
bill = &model.Waybill{
|
||
VendorOrderID: order.VendorOrderID,
|
||
OrderVendorID: order.VendorID,
|
||
VendorWaybillID: sfOrderID,
|
||
VendorWaybillID2: sfBillID,
|
||
WaybillVendorID: model.VendorIDSFPS,
|
||
DesiredFee: int64(desiredFee),
|
||
ActualFee: utils.Float64TwoInt64(sfReallyPrice),
|
||
}
|
||
delivery.OnWaybillCreated(bill)
|
||
//todo 模拟新运单回调
|
||
if _, err = partner.CurOrderManager.LoadWaybill(sfOrderID, model.VendorIDSFPS); fmt.Sprintf("%s", err) == "找不到相应运单" {
|
||
//忽略找不到运单错误
|
||
err = nil
|
||
resp := OnWaybillMsg(sfps2.UrlIndexRiderStatus, sfps2.RiderStatus{
|
||
ShopId: utils.Str2Float64(sfps2.SFShopStoreID),
|
||
SFOrderID: sfOrderID,
|
||
ShopOrderID: order.VendorOrderID,
|
||
UrlIndex: sfps2.UrlIndexRiderStatus,
|
||
OperatorName: "",
|
||
OperatorPhone: "",
|
||
RiderLng: 0,
|
||
RiderLat: 0,
|
||
OrderStatus: sfps2.OrderStatusNewOrder,
|
||
StatusDesc: sfps2.OrderStatusNewOrderDesc,
|
||
SFUCode: "",
|
||
PushTime: int(time.Now().Unix()),
|
||
})
|
||
if resp.ErrorCode != sfps2.SuccessCode {
|
||
err = fmt.Errorf("%v,%s", err, resp.ErrorMsg)
|
||
}
|
||
}
|
||
return bill, err
|
||
}
|
||
|
||
func (d DeliveryHandler) CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) {
|
||
money := int64(0)
|
||
deductionFee, err := api.SfPsAPI.PreCancelOrder(bill.VendorWaybillID)
|
||
if deductionFee == 0 || err != nil {
|
||
money = 0
|
||
} else {
|
||
money = utils.Float64TwoInt64(deductionFee)
|
||
}
|
||
globals.SugarLogger.Debugf("CancelWaybill money=%d", money)
|
||
if err = api.SfPsAPI.CancelOrder(bill.VendorWaybillID); err != nil {
|
||
return err
|
||
}
|
||
bill.Status = model.WaybillStatusCanceled
|
||
bill.Remark = cancelReason
|
||
bill.DesiredFee = money //取消成功才赋值违约金
|
||
bill.ActualFee = money
|
||
globals.SugarLogger.Debugf("CancelWaybill bill=%s", utils.Format4Output(bill, false))
|
||
|
||
partner.CurOrderManager.OnWaybillStatusChanged(bill)
|
||
return nil
|
||
}
|
||
|
||
func (d DeliveryHandler) GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *partner.WaybillFeeInfo, err error) {
|
||
var (
|
||
weight int
|
||
flag = false
|
||
//param = &sfps2.PreCreateOrderReq{}
|
||
)
|
||
|
||
// 默认重量
|
||
if order.Weight >= 49500 || order.Weight <= 0 {
|
||
weight = 49500
|
||
} else {
|
||
weight = order.Weight
|
||
}
|
||
|
||
store, err := dao.GetStoreDetail(dao.GetDB(), getReallyStoreID(order.StoreID, order.JxStoreID), 0, "")
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
param := &sfps2.PreCreateOrderReq{
|
||
//ShopId: sfps2.SFShopStoreID,
|
||
UserLng: utils.Float64ToStr(jxutils.IntCoordinate2Standard(order.ConsigneeLng)),
|
||
UserLat: utils.Float64ToStr(jxutils.IntCoordinate2Standard(order.ConsigneeLat)),
|
||
UserAddress: order.ConsigneeAddress,
|
||
Weight: int64(weight),
|
||
ProductType: sfps2.ProductTypeFresh,
|
||
ShopType: sfps2.OrderTypeSF,
|
||
LbsType: sfps2.LbsTypeGD,
|
||
RiderPickMethod: sfps2.RiderPickUpMethodSTU,
|
||
Shop: &sfps2.SfShopInfo{
|
||
ShopName: order.StoreName,
|
||
ShopPhone: store.Tel1,
|
||
ShopAddress: store.Address,
|
||
ShopLat: utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lat)),
|
||
ShopLng: utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lng)),
|
||
},
|
||
}
|
||
// 城市维度获取顺丰门店id
|
||
if len(store.CityName) > 0 {
|
||
for k, v := range sfps2.SFCityStoreIDs {
|
||
//globals.SugarLogger.Debugf("sfps GetWaybillFee store.CityName==%s,k=%s", store.CityName, k)
|
||
if strings.Contains(store.CityName, k) || store.CityName == k {
|
||
param.ShopId = v
|
||
flag = true
|
||
}
|
||
}
|
||
}
|
||
if flag == false || len(store.CityName) == 0 {
|
||
flag = true //todo sf测试用
|
||
//return nil, errors.New("此城市暂时不在,顺丰配送业务范围")
|
||
}
|
||
deliveryFeeInfo = &partner.WaybillFeeInfo{}
|
||
price, err := api.SfPsAPI.PreCreateOrder(param)
|
||
deliveryFeeInfo.DeliveryFee = utils.Float64TwoInt64(price)
|
||
globals.SugarLogger.Debugf("GetWaybillFee deliveryFeeInfo.DeliveryFee=%d", deliveryFeeInfo.DeliveryFee)
|
||
return deliveryFeeInfo, err
|
||
}
|
||
|
||
func (d DeliveryHandler) ComplaintRider(bill *model.Waybill, resonID int, resonContent string) (err error) {
|
||
return fmt.Errorf("顺丰暂未实现投诉")
|
||
}
|
||
|
||
// GetDeliverLiquidatedDamages 获取取消运单违约金
|
||
func (d DeliveryHandler) GetDeliverLiquidatedDamages(orderId string, deliverId string) (money int64, err error) {
|
||
waybill, err := dao.GetWaybills(dao.GetDB(), orderId, []int64{model.VendorIDSFPS})
|
||
if len(waybill) == 0 || err != nil {
|
||
return 0, err
|
||
}
|
||
deductionFee, err := api.SfPsAPI.PreCancelOrder(waybill[0].VendorWaybillID)
|
||
if deductionFee == 0 || err != nil {
|
||
return 0, err
|
||
}
|
||
money = utils.Float64TwoInt64(deductionFee)
|
||
return money, nil
|
||
}
|
||
|
||
func (d DeliveryHandler) GetRiderInfo(orderId string, deliveryId int64, mtPeisongId string) (rider *utils.RiderInfo, err error) {
|
||
order, err := dao.GetWaybills(dao.GetDB(), orderId, []int64{model.VendorIDSFPS})
|
||
if len(order) == 0 || err != nil {
|
||
return nil, errors.New("顺丰 订单id无效,请检查")
|
||
}
|
||
//获取顺丰运单详情
|
||
sfOrder, err := api.SfPsAPI.GetOrderStatus(order[0].VendorWaybillID)
|
||
//获取顺丰骑手实时位置
|
||
sfRider, err := api.SfPsAPI.GetRiderLatestPosition(sfOrder.OrderID)
|
||
if sfRider == nil {
|
||
return nil, errors.New("顺丰派送暂无骑手信息")
|
||
}
|
||
result := &utils.RiderInfo{
|
||
OrderId: orderId,
|
||
ThirdCarrierOrderId: sfOrder.OrderID,
|
||
CourierName: sfOrder.RiderName,
|
||
CourierPhone: sfOrder.RiderPhone,
|
||
LogisticsProviderCode: utils.SFPSCode,
|
||
LogisticsStatus: utils.Float64TwoInt(sfOrder.OrderStatus), // 默认正在配送中
|
||
Latitude: sfRider.RiderLat,
|
||
Longitude: sfRider.RiderLng,
|
||
}
|
||
|
||
switch sfOrder.OrderStatus {
|
||
case sfps2.OrderStatusNewOrder:
|
||
result.LogisticsStatus = model.WaybillStatusNew
|
||
result.LogisticsContext = model.RiderWaitRider
|
||
case sfps2.OrderStatusTakeOrder:
|
||
result.LogisticsStatus = model.WaybillStatusCourierAssigned
|
||
result.LogisticsContext = model.RiderGetOrder
|
||
case sfps2.OrderStatusArrivedStore:
|
||
result.LogisticsStatus = model.WaybillStatusCourierArrived
|
||
result.LogisticsContext = model.RiderToStore
|
||
case sfps2.OrderStatusRiderArriving:
|
||
result.LogisticsStatus = model.WaybillStatusDelivering
|
||
result.LogisticsContext = model.RiderGetOrderDelivering
|
||
case sfps2.OrderStatusFinished:
|
||
result.LogisticsStatus = model.WaybillStatusDelivered
|
||
result.LogisticsContext = model.RiderGetOrderDelivered
|
||
case sfps2.OrderStatusOrderCancel:
|
||
result.LogisticsStatus = model.WaybillStatusCanceled
|
||
result.LogisticsContext = model.RiderGetOrderCanceled
|
||
case sfps2.OrderStatusError:
|
||
result.LogisticsStatus = model.WaybillStatusDeliverFailed
|
||
result.LogisticsContext = model.RiderGetOrderDeliverFailed
|
||
default:
|
||
result.LogisticsStatus = 0
|
||
result.LogisticsContext = model.RiderGetOrderDeliverOther
|
||
}
|
||
return result, nil
|
||
}
|
||
|
||
func (c *DeliveryHandler) GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error) {
|
||
return api.SfPsAPI.QueryTipFee(vendorWaybillID)
|
||
}
|
||
|
||
func (c *DeliveryHandler) GetRidderPosition(ctx *jxcontext.Context, vendorOrgCode, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (lng, lat float64, err error) {
|
||
if rider, err := api.SfPsAPI.GetRiderLatestPosition(vendorWaybillID); err == nil && len(rider.RiderLng) > 0 && len(rider.RiderLat) > 0 {
|
||
lng = utils.Str2Float64(rider.RiderLng)
|
||
lat = utils.Str2Float64(rider.RiderLat)
|
||
return lng, lat, nil
|
||
}
|
||
return 0, 0, err
|
||
}
|
||
|
||
func (c *DeliveryHandler) UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error) {
|
||
return api.SfPsAPI.AddTipFee(vendorWaybillID, tipFee)
|
||
}
|
||
|
||
// OnWaybillMsg 配送状态更改回调
|
||
func OnWaybillMsg(urlIndex string, msg interface{}) (resp *sfps2.CallbackResponse) {
|
||
|
||
order, goodsOrder := GetWaybillByStatus(urlIndex, msg)
|
||
//判断是否是果园
|
||
globals.SugarLogger.Debugf("sfsfsf goodsOrder=%s runMode=%s", utils.Format4Output(goodsOrder, false), beego.BConfig.RunMode)
|
||
if goodsOrder == nil && beego.BConfig.RunMode != "jxgy" {
|
||
globals.SugarLogger.Debugf("sfsfsf 我在这里")
|
||
pushCallbackToGy(urlIndex, msg)
|
||
return sfps2.SuccessResponse
|
||
}
|
||
//多次取消回调只取第一次
|
||
tempStatus := utils.Str2Int(order.VendorStatus)
|
||
if tempStatus == sfps2.OrderStatusOrderCancel || tempStatus == sfps2.OrderStatusRiderCancel {
|
||
bill, err := partner.CurOrderManager.LoadWaybill(order.VendorWaybillID, model.VendorIDSFPS)
|
||
if err != nil {
|
||
return sfps2.Err2CallbackResponse(err)
|
||
}
|
||
if bill.Status == model.OrderStatusCanceled {
|
||
return sfps2.Err2CallbackResponse(nil)
|
||
}
|
||
}
|
||
//获取实时订单信息
|
||
var temp = api.SfPsAPI
|
||
globals.SugarLogger.Debugf("sfsfsf sfApi=%s", utils.Format4Output(temp, false))
|
||
|
||
sfOrder, err := api.SfPsAPI.GetOrderStatus(order.VendorWaybillID)
|
||
if err != nil {
|
||
globals.SugarLogger.Debugf("SFPS OnWaybillMsg GetOrderStatus err=%v", err)
|
||
return sfps2.Err2CallbackResponse(err)
|
||
}
|
||
globals.SugarLogger.Debugf("SFPS OnWaybillMsg sfOrder=%s", utils.Format4Output(sfOrder, false))
|
||
if order.CourierMobile == "" {
|
||
order.CourierName = sfOrder.RiderName
|
||
}
|
||
if order.CourierName == "" {
|
||
order.CourierMobile = sfOrder.RiderPhone
|
||
}
|
||
|
||
sfTotalPrice := utils.Float64TwoInt(sfOrder.TotalPrice)
|
||
sfActualPrice := utils.Float64TwoInt64(sfOrder.RealPayMoney)
|
||
globals.SugarLogger.Debugf("SFPS OnWaybillMsg,sfTotalPrice=%d,sfActualPrice=%d", sfTotalPrice, sfActualPrice)
|
||
|
||
store, _ := dao.GetStoreDetail(dao.GetDB(), goodsOrder.JxStoreID, goodsOrder.VendorID, goodsOrder.VendorOrgCode)
|
||
sfTotalPrice += store.FreightMarkup
|
||
|
||
orderStatus := utils.Str2Int64(order.VendorStatus)
|
||
switch orderStatus {
|
||
case sfps2.OrderStatusNewOrder: //1:订单创建
|
||
order.DesiredFee = int64(sfTotalPrice)
|
||
order.ActualFee = sfActualPrice
|
||
order.Status = model.WaybillStatusNew //5 带调度
|
||
case sfps2.OrderStatusTakeOrder: //10:配送员接单
|
||
order.DesiredFee = int64(sfTotalPrice)
|
||
order.Status = model.WaybillStatusCourierAssigned //12
|
||
order.Remark = order.CourierName + "," + order.CourierMobile
|
||
case sfps2.OrderStatusArrivedStore:
|
||
order.DesiredFee = int64(sfTotalPrice)
|
||
order.Status = model.WaybillStatusCourierArrived
|
||
case sfps2.OrderStatusRiderArriving:
|
||
order.DesiredFee = int64(sfTotalPrice)
|
||
order.Status = model.WaybillStatusDelivering
|
||
case sfps2.OrderStatusFinished:
|
||
order.DesiredFee = int64(sfTotalPrice)
|
||
order.Status = model.WaybillStatusDelivered
|
||
case sfps2.OrderStatusOrderCancel, sfps2.OrderStatusRiderCancel:
|
||
order.Status = model.WaybillStatusCanceled
|
||
case sfps2.OrderStatusError:
|
||
order.Status = model.WaybillStatusDeliverFailed // 22
|
||
default:
|
||
globals.SugarLogger.Warnf("onWaybillMsg unknown msg:%v", msg)
|
||
}
|
||
|
||
if err := partner.CurOrderManager.OnWaybillStatusChanged(order); err != nil {
|
||
return sfps2.Err2CallbackResponse(err)
|
||
}
|
||
|
||
switch order.OrderVendorID {
|
||
case model.VendorIDDD:
|
||
Lng, Lat, _ := partner.GetRidderPositionGetter(order.WaybillVendorID).GetRidderPosition(nil, order.VendorOrderID, order.VendorOrderID, order.VendorWaybillID, order.VendorWaybillID2)
|
||
tiktokStatusPush(order, orderStatus, utils.Float64ToStr(Lng), utils.Float64ToStr(Lat), goodsOrder.VendorOrgCode)
|
||
case model.VendorIDTaoVegetable, model.VendorIDMTWM:
|
||
delivery.GetOrderRiderInfoToPlatform(order.VendorOrderID, order.Status) // 骑手位置更新
|
||
if goodsOrder.VendorID == model.VendorIDTaoVegetable && orderStatus == sfps2.OrderStatusTakeOrder {
|
||
tao_vegetable.PushDelivererChangeInfo(goodsOrder, order, tao.TaoDeliveryTypeSF)
|
||
}
|
||
}
|
||
return sfps2.Err2CallbackResponse(nil)
|
||
}
|
||
|
||
//转发到果园
|
||
func pushCallbackToGy(urlIndex string, msg interface{}) {
|
||
var (
|
||
err error
|
||
client = http.Client{}
|
||
request *http.Request
|
||
param = make(map[string]interface{})
|
||
)
|
||
param = changeToRaw(urlIndex, msg)
|
||
globals.SugarLogger.Debugf("sfsfsf pushCallbackToGy param=%s", utils.Format4Output(param, false))
|
||
switch urlIndex {
|
||
case sfps2.UrlIndexRiderException:
|
||
request, err = http.NewRequest(http.MethodPost, "http://callback-jxgy.jxc4.com/SFPS/SfAbnormal", strings.NewReader(utils.Map2URLValues(param).Encode()))
|
||
default:
|
||
request, err = http.NewRequest(http.MethodPost, "http://callback-jxgy.jxc4.com/SFPS/SfOrder", strings.NewReader(utils.Map2URLValues(param).Encode()))
|
||
}
|
||
if err != nil {
|
||
globals.SugarLogger.Debugf("sfsfsf pushCallbackToGy err=%v", err)
|
||
return
|
||
}
|
||
request.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
|
||
client.Do(request)
|
||
|
||
}
|
||
|
||
func tiktokStatusPush(order *model.Waybill, orderStatus int64, lng, lat, vendorOrgCode string) {
|
||
result := &utils.RiderInfo{
|
||
OrderId: order.VendorOrderID,
|
||
ThirdCarrierOrderId: order.VendorWaybillID,
|
||
CourierName: order.CourierName,
|
||
CourierPhone: order.CourierMobile,
|
||
LogisticsProviderCode: utils.SFPSCode,
|
||
LogisticsStatus: order.Status,
|
||
OpCode: "",
|
||
Latitude: lat,
|
||
Longitude: lng,
|
||
}
|
||
switch orderStatus {
|
||
case sfps2.OrderStatusNewOrder:
|
||
result.LogisticsStatus = model.WaybillStatusNew
|
||
result.LogisticsContext = model.RiderWaitRider
|
||
case sfps2.OrderStatusTakeOrder:
|
||
result.LogisticsStatus = model.WaybillStatusCourierAssigned // 分配骑手
|
||
result.LogisticsContext = model.RiderWaitGetGoods
|
||
case sfps2.OrderStatusRiderArriving:
|
||
result.LogisticsStatus = model.WaybillStatusDelivering
|
||
result.LogisticsContext = model.RiderGetOrderDelivering
|
||
case sfps2.OrderStatusFinished:
|
||
result.LogisticsStatus = model.WaybillStatusDelivered
|
||
result.LogisticsContext = model.RiderGetOrderDelivered
|
||
case sfps2.OrderStatusOrderCancel, sfps2.OrderStatusRiderCancel:
|
||
result.LogisticsStatus = model.WaybillStatusCanceled
|
||
result.LogisticsContext = model.RiderGetOrderCanceled
|
||
case sfps2.OrderStatusError:
|
||
result.LogisticsStatus = model.WaybillStatusDeliverFailed
|
||
result.LogisticsContext = model.RiderGetOrderDeliverFailed
|
||
case sfps2.OrderStatusArrivedStore:
|
||
result.LogisticsStatus = model.WaybillStatusCourierArrived
|
||
result.LogisticsContext = model.RiderToStore
|
||
default:
|
||
result.LogisticsStatus = 0
|
||
result.LogisticsContext = model.RiderGetOrderDeliverOther
|
||
}
|
||
delivery.PullTiktokRiderInfo(result, vendorOrgCode)
|
||
}
|
||
|
||
// OnWaybillExceptSF 异常报备
|
||
func OnWaybillExceptSF(msg *sfps2.RiderException) (retVal *sfps2.CallbackResponse) {
|
||
jxutils.CallMsgHandler(func() {
|
||
order := &model.Waybill{
|
||
VendorWaybillID: msg.SFOrderID,
|
||
VendorWaybillID2: utils.Int2Str(msg.ExID),
|
||
WaybillVendorID: model.VendorIDSFPS,
|
||
CourierName: msg.OperatorName,
|
||
CourierMobile: "",
|
||
Status: model.WaybillStatusUnknown, // todo 这里要再确定一下是否只要收到订单异常消息就只简单当成一个消息
|
||
VendorStatus: utils.Float64ToStr(msg.OrderStatus),
|
||
StatusTime: utils.Timestamp2Time(int64(msg.PushTime)),
|
||
}
|
||
order.VendorOrderID, order.OrderVendorID = jxutils.SplitUniversalOrderID(msg.ShopOrderID)
|
||
retVal = sfps2.Err2CallbackResponse(partner.CurOrderManager.OnWaybillStatusChanged(order))
|
||
}, jxutils.ComposeUniversalOrderID(msg.ShopOrderID, model.VendorIDSFPS))
|
||
return retVal
|
||
}
|
||
|
||
// GetWaybillByStatus 根据orderStatus 获取waybill和goodsOrder结构
|
||
func GetWaybillByStatus(urlIndex string, msg interface{}) (waybill *model.Waybill, good2 *model.GoodsOrder) {
|
||
globals.SugarLogger.Debugf("GetWaybillByStatus msg=%s", utils.Format4Output(msg, false))
|
||
|
||
waybill = getWaybillByStatus(urlIndex, msg)
|
||
//获取系统订单
|
||
var good *model.GoodsOrder
|
||
sql := `SELECT * FROM goods_order WHERE vendor_order_id = ? ORDER BY order_created_at DESC LIMIT 1 OFFSET 0`
|
||
sqlParams := []interface{}{waybill.VendorOrderID}
|
||
err := dao.GetRow(dao.GetDB(), &good, sql, sqlParams)
|
||
|
||
if err != nil || good == nil || good.VendorOrderID == "" {
|
||
waybill.OrderVendorID = 0
|
||
} else {
|
||
waybill.OrderVendorID = good.VendorID
|
||
waybill.VendorOrderID = good.VendorOrderID
|
||
}
|
||
return waybill, good
|
||
}
|
||
|
||
//转换顺丰回调信息
|
||
func getWaybillByStatus(urlIndex string, msg interface{}) (waybill *model.Waybill) {
|
||
waybill = &model.Waybill{}
|
||
switch urlIndex {
|
||
case sfps2.UrlIndexRiderStatus:
|
||
retVal := msg.(sfps2.RiderStatus)
|
||
waybill = &model.Waybill{
|
||
VendorWaybillID: retVal.SFOrderID,
|
||
WaybillVendorID: model.VendorIDSFPS,
|
||
VendorOrderID: retVal.ShopOrderID,
|
||
CourierName: retVal.OperatorName,
|
||
CourierMobile: retVal.OperatorPhone,
|
||
VendorStatus: utils.Float64ToStr(retVal.OrderStatus),
|
||
StatusTime: utils.Timestamp2Time(int64(retVal.PushTime)),
|
||
Remark: retVal.StatusDesc,
|
||
}
|
||
if retVal.PushTime == 0 {
|
||
waybill.StatusTime = time.Now()
|
||
}
|
||
case sfps2.UrlIndexRiderRecall:
|
||
retVal := msg.(sfps2.RiderRecall)
|
||
waybill = &model.Waybill{
|
||
VendorWaybillID: retVal.SFOrderID,
|
||
WaybillVendorID: model.VendorIDSFPS,
|
||
VendorOrderID: retVal.ShopOrderID,
|
||
VendorStatus: utils.Float64ToStr(retVal.OrderStatus),
|
||
StatusTime: utils.Timestamp2Time(int64(retVal.PushTime)),
|
||
Remark: retVal.StatusDesc,
|
||
}
|
||
if retVal.PushTime == 0 {
|
||
waybill.StatusTime = time.Now()
|
||
}
|
||
case sfps2.UrlIndexOrderComplete:
|
||
retVal := msg.(sfps2.OrderComplete)
|
||
waybill = &model.Waybill{
|
||
VendorWaybillID: retVal.SfOrderID,
|
||
WaybillVendorID: model.VendorIDSFPS,
|
||
VendorOrderID: retVal.ShopOrderID,
|
||
CourierName: retVal.OperatorName,
|
||
VendorStatus: utils.Float64ToStr(retVal.OrderStatus),
|
||
StatusTime: utils.Timestamp2Time(int64(retVal.PushTime)),
|
||
Remark: retVal.StatusDesc,
|
||
}
|
||
if retVal.PushTime == 0 {
|
||
waybill.StatusTime = time.Now()
|
||
}
|
||
case sfps2.UrlIndexSFCancel:
|
||
retVal := msg.(sfps2.SFCancel)
|
||
waybill = &model.Waybill{
|
||
VendorWaybillID: retVal.SFOrderID,
|
||
WaybillVendorID: model.VendorIDSFPS,
|
||
VendorOrderID: retVal.ShopOrderID,
|
||
CourierName: retVal.OperatorName,
|
||
VendorStatus: utils.Float64ToStr(retVal.OrderStatus),
|
||
StatusTime: utils.Timestamp2Time(int64(retVal.PushTime)),
|
||
Remark: retVal.StatusDesc,
|
||
}
|
||
if retVal.PushTime == 0 {
|
||
waybill.StatusTime = time.Now()
|
||
}
|
||
default:
|
||
return nil
|
||
}
|
||
return waybill
|
||
}
|
||
|
||
//转换原始数据 转发果园
|
||
func changeToRaw(urlIndex string, msg interface{}) (retVal map[string]interface{}) {
|
||
retVal = make(map[string]interface{})
|
||
globals.SugarLogger.Debugf("changeToRaw urlIndex=%s, msg=%s", urlIndex, utils.Format4Output(msg, false))
|
||
switch urlIndex {
|
||
case sfps2.UrlIndexRiderStatus:
|
||
temp := msg.(sfps2.RiderStatus)
|
||
retVal["shop_id"] = temp.ShopId
|
||
retVal["sf_order_id"] = temp.SFOrderID
|
||
retVal["shop_order_id"] = temp.ShopOrderID
|
||
retVal["url_index"] = temp.UrlIndex
|
||
retVal["operator_name"] = temp.OperatorName
|
||
retVal["operator_phone"] = temp.OperatorPhone
|
||
retVal["rider_lng"] = temp.RiderLng
|
||
retVal["rider_lat"] = temp.RiderLat
|
||
retVal["order_status"] = temp.OrderStatus
|
||
retVal["status_desc"] = temp.StatusDesc
|
||
retVal["sf_ucode"] = temp.SFUCode
|
||
retVal["push_time"] = temp.PushTime
|
||
case sfps2.UrlIndexRiderRecall:
|
||
temp := msg.(sfps2.RiderRecall)
|
||
retVal["order_status"] = temp.OrderStatus
|
||
retVal["push_time"] = temp.PushTime
|
||
retVal["sf_order_id"] = temp.SFOrderID
|
||
retVal["shop_id"] = temp.ShopId
|
||
retVal["shop_order_id"] = temp.ShopOrderID
|
||
retVal["url_index"] = temp.UrlIndex
|
||
retVal["status_desc"] = temp.StatusDesc
|
||
case sfps2.UrlIndexOrderComplete:
|
||
temp := msg.(sfps2.OrderComplete)
|
||
retVal["operator_name"] = temp.OperatorName
|
||
retVal["operator_phone"] = temp.OperatorPhone
|
||
retVal["order_status"] = temp.OrderStatus
|
||
retVal["push_time"] = temp.PushTime
|
||
retVal["receiRpt_type"] = temp.ReceiRptType
|
||
retVal["rider_lat"] = temp.RiderLat
|
||
retVal["rider_lng"] = temp.RiderLng
|
||
retVal["sf_order_id"] = temp.SfOrderID
|
||
retVal["sf_ucode"] = temp.SfUcode
|
||
retVal["shop_id"] = temp.ShopId
|
||
retVal["shop_order_id"] = temp.ShopOrderID
|
||
retVal["status_desc"] = temp.StatusDesc
|
||
retVal["url_index"] = temp.UrlIndex
|
||
case sfps2.UrlIndexSFCancel:
|
||
temp := msg.(sfps2.SFCancel)
|
||
retVal["cancel_reason"] = temp.CancelReason
|
||
retVal["cancel_code"] = temp.CancelCode
|
||
retVal["operator_name"] = temp.OperatorName
|
||
retVal["operator_phone"] = temp.OperatorPhone
|
||
retVal["order_status"] = temp.OrderStatus
|
||
retVal["push_time"] = temp.PushTime
|
||
retVal["rider_lat"] = temp.RiderLat
|
||
retVal["rider_lng"] = temp.RiderLng
|
||
retVal["sf_order_id"] = temp.SFOrderID
|
||
retVal["sf_ucode"] = temp.SFUCode
|
||
retVal["shop_id"] = temp.ShopId
|
||
retVal["shop_order_id"] = temp.ShopOrderID
|
||
retVal["url_index"] = temp.UrlIndex
|
||
retVal["status_desc"] = temp.StatusDesc
|
||
}
|
||
return retVal
|
||
}
|
||
|
||
// GetVendorSource 辅助函数
|
||
//获取订单来源标识符
|
||
func GetVendorSource(vendorID int) (source string) {
|
||
switch vendorID {
|
||
case model.VendorIDMTWM:
|
||
source = sfps2.OrderSourceMt
|
||
case model.VendorIDELM:
|
||
source = sfps2.OrderSourceELM
|
||
case model.VendorIDEBAI:
|
||
source = sfps2.OrderSourceEBAI
|
||
case model.VendorIDDD:
|
||
source = "抖音"
|
||
case model.VendorIDJD:
|
||
source = "京东"
|
||
case model.VendorIDJX:
|
||
source = "京西"
|
||
default:
|
||
source = "其他"
|
||
}
|
||
return source
|
||
}
|
||
|
||
func getReallyStoreID(storeID, jxStoreID int) int {
|
||
if storeID == 0 && jxStoreID == 0 {
|
||
return 0
|
||
}
|
||
if storeID == 0 {
|
||
return jxStoreID
|
||
} else {
|
||
return storeID
|
||
}
|
||
}
|