sfps
This commit is contained in:
@@ -109,10 +109,10 @@ func GetOrderRiderInfoToPlatform(orderId string, wayBillStatus int) {
|
||||
|
||||
riderInfo := &mtpsapi.RiderInfo{}
|
||||
if handlerInfo := partner.GetDeliveryPlatformFromVendorID(v.WaybillVendorID); handlerInfo != nil {
|
||||
if v.WaybillVendorID == model.VendorIDDada || v.WaybillVendorID == model.VendorIDFengNiao || v.WaybillVendorID == model.VendorIDUUPT {
|
||||
if v.WaybillVendorID == model.VendorIDDada || v.WaybillVendorID == model.VendorIDFengNiao || v.WaybillVendorID == model.VendorIDUUPT || v.WaybillVendorID == model.VendorIDSFPS {
|
||||
riderInfo, err = handlerInfo.Handler.GetRiderInfo(v.VendorOrderID, 0, v.VendorWaybillID)
|
||||
if err != nil {
|
||||
globals.SugarLogger.Debug("Get Order waybill rider info err FN/DADA/DYPS :%v", err)
|
||||
globals.SugarLogger.Debug("Get Order waybill rider info err FN/DADA/SFPS :%v", err)
|
||||
}
|
||||
} else if v.WaybillVendorID == model.VendorIDMTPS {
|
||||
if v.VendorWaybillID != "" {
|
||||
|
||||
401
business/partner/delivery/sfps/waybill.go
Normal file
401
business/partner/delivery/sfps/waybill.go
Normal file
@@ -0,0 +1,401 @@
|
||||
package sfps
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"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/baseapi/platformapi/mtpsapi"
|
||||
"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
|
||||
productDetail []*sfps2.ProductDetail
|
||||
)
|
||||
if order.Weight >= 49500 {
|
||||
weight = 49500
|
||||
} else {
|
||||
weight = order.Weight
|
||||
}
|
||||
|
||||
param := &sfps2.CreateOrderReq{
|
||||
ShopId: sfps2.SFShopStoreID,
|
||||
ShopOrderId: order.VendorOrderID,
|
||||
OrderSource: GetVendorSource(order.VendorID),
|
||||
OrderTime: order.CreatedAt.Unix(),
|
||||
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),
|
||||
},
|
||||
}
|
||||
|
||||
for _, v := range order.Skus {
|
||||
productDetail = append(productDetail, &sfps2.ProductDetail{
|
||||
ProductName: v.SkuName,
|
||||
ProductNum: int64(v.Count),
|
||||
})
|
||||
}
|
||||
param.OrderDetail.ProductDetail = productDetail
|
||||
|
||||
sfOrderID, sfBillID, sfTotalPrice, err := api.SfPsAPI.CreateOrder(param)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bill = &model.Waybill{
|
||||
VendorOrderID: order.VendorOrderID,
|
||||
OrderVendorID: order.VendorID,
|
||||
VendorWaybillID: sfOrderID,
|
||||
VendorWaybillID2: sfBillID,
|
||||
WaybillVendorID: model.VendorIDFengNiao,
|
||||
DesiredFee: int64(sfTotalPrice),
|
||||
}
|
||||
delivery.OnWaybillCreated(bill)
|
||||
return bill, err
|
||||
}
|
||||
|
||||
func (d DeliveryHandler) CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) {
|
||||
if err = api.SfPsAPI.CancelOrder(bill.VendorWaybillID); err != nil {
|
||||
return err
|
||||
}
|
||||
bill.Status = model.WaybillStatusCanceled
|
||||
bill.Remark = cancelReason
|
||||
partner.CurOrderManager.OnWaybillStatusChanged(bill)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d DeliveryHandler) GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *partner.WaybillFeeInfo, err error) {
|
||||
var (
|
||||
weight int
|
||||
//productDetail []*sfps2.ProductDetail
|
||||
)
|
||||
if order.Weight >= 49500 {
|
||||
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,
|
||||
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)),
|
||||
},
|
||||
}
|
||||
deliveryFeeInfo = &partner.WaybillFeeInfo{}
|
||||
price, err := api.SfPsAPI.PreCreateOrder(param)
|
||||
deliveryFeeInfo.DeliveryFee = jxutils.StandardPrice2Int(price)
|
||||
return deliveryFeeInfo, err
|
||||
}
|
||||
|
||||
func (d DeliveryHandler) ComplaintRider(bill *model.Waybill, resonID int, resonContent string) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d DeliveryHandler) GetRiderInfo(orderId string, deliveryId int64, mtPeisongId string) (rider *mtpsapi.RiderInfo, err error) {
|
||||
order, err := dao.GetWaybills(dao.GetDB(), orderId)
|
||||
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)
|
||||
|
||||
result := &mtpsapi.RiderInfo{
|
||||
OrderId: orderId,
|
||||
ThirdCarrierOrderId: sfOrder.OrderID,
|
||||
CourierName: sfOrder.RiderName,
|
||||
CourierPhone: sfOrder.RiderPhone,
|
||||
LogisticsProviderCode: mtpsapi.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
|
||||
}
|
||||
|
||||
// OnWaybillMsg 配送状态更改回调
|
||||
func OnWaybillMsg(msg *sfps2.RiderStatus) (resp *sfps2.CallbackResponse) {
|
||||
|
||||
order := &model.Waybill{
|
||||
VendorWaybillID: msg.SFOrderID,
|
||||
WaybillVendorID: model.VendorIDSFPS,
|
||||
VendorOrderID: msg.ShopOrderID,
|
||||
CourierName: msg.OperatorName,
|
||||
CourierMobile: msg.OperatorPhone,
|
||||
VendorStatus: utils.Int2Str(msg.OrderStatus),
|
||||
StatusTime: utils.Timestamp2Time(int64(msg.PushTime)),
|
||||
Remark: msg.StatusDesc,
|
||||
}
|
||||
if msg.PushTime == 0 {
|
||||
order.StatusTime = time.Now()
|
||||
}
|
||||
//获取实时订单信息
|
||||
sfOrder, err := api.SfPsAPI.GetOrderStatus(msg.SFOrderID)
|
||||
if err != nil {
|
||||
return sfps2.Err2CallbackResponse(err)
|
||||
}
|
||||
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{}{msg.ShopOrderID}
|
||||
dao.GetRow(dao.GetDB(), &good, sql, sqlParams)
|
||||
order.OrderVendorID = good.VendorID
|
||||
|
||||
orderStatus := utils.Str2Int64(order.VendorStatus)
|
||||
switch orderStatus {
|
||||
case sfps2.OrderStatusNewOrder: //1:订单创建
|
||||
order.DesiredFee = jxutils.StandardPrice2Int(sfOrder.TotalPrice)
|
||||
order.Status = model.WaybillStatusNew //5 带调度
|
||||
case sfps2.OrderStatusTakeOrder: //10:配送员接单
|
||||
order.DesiredFee = jxutils.StandardPrice2Int(sfOrder.TotalPrice)
|
||||
order.Status = model.WaybillStatusCourierAssigned //12
|
||||
order.Remark = order.CourierName + "," + order.CourierMobile
|
||||
case sfps2.OrderStatusArrivedStore:
|
||||
order.DesiredFee = jxutils.StandardPrice2Int(sfOrder.TotalPrice)
|
||||
order.Status = model.WaybillStatusCourierArrived
|
||||
case sfps2.OrderStatusRiderArriving:
|
||||
order.DesiredFee = jxutils.StandardPrice2Int(sfOrder.TotalPrice)
|
||||
order.Status = model.WaybillStatusDelivering
|
||||
case sfps2.OrderStatusFinished:
|
||||
order.DesiredFee = jxutils.StandardPrice2Int(sfOrder.TotalPrice)
|
||||
order.Status = model.WaybillStatusDelivered
|
||||
case sfps2.OrderStatusOrderCancel:
|
||||
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)
|
||||
}
|
||||
|
||||
if order.OrderVendorID == model.VendorIDDD {
|
||||
result := &mtpsapi.RiderInfo{
|
||||
OrderId: order.VendorOrderID,
|
||||
ThirdCarrierOrderId: order.VendorOrderID,
|
||||
CourierName: order.CourierName,
|
||||
CourierPhone: order.CourierMobile,
|
||||
LogisticsProviderCode: "10002",
|
||||
LogisticsStatus: order.Status,
|
||||
OpCode: "",
|
||||
}
|
||||
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:
|
||||
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)
|
||||
}
|
||||
|
||||
defer delivery.GetOrderRiderInfoToPlatform(order.VendorOrderID, order.Status) // 骑手位置更新
|
||||
return sfps2.Err2CallbackResponse(nil)
|
||||
}
|
||||
|
||||
// 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.Int2Str(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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
@@ -320,11 +320,8 @@ func OnWaybillMsg(req *uuptapi.WaybillCallbackParam) (resp *uuptapi.CallbackResp
|
||||
case uuptapi.StateArrivedStore:
|
||||
param.Status = model.WaybillStatusCourierArrived
|
||||
param.DesiredFee = reallyPrice
|
||||
case uuptapi.StatePickUp:
|
||||
param.Status = model.WaybillStatusUuPickUp
|
||||
param.DesiredFee = reallyPrice
|
||||
case uuptapi.StateArrivedDestination:
|
||||
param.Status = model.WaybillStatusUuArrivedDestination
|
||||
case uuptapi.StatePickUp, uuptapi.StateArrivedDestination:
|
||||
param.Status = model.WaybillStatusDelivering
|
||||
param.DesiredFee = reallyPrice
|
||||
case uuptapi.StateReceiverGetGoods:
|
||||
param.Status = model.WaybillStatusDelivered
|
||||
@@ -358,12 +355,9 @@ func OnWaybillMsg(req *uuptapi.WaybillCallbackParam) (resp *uuptapi.CallbackResp
|
||||
case uuptapi.StateArrivedStore: //骑手到店
|
||||
result.LogisticsStatus = model.WaybillStatusCourierArrived
|
||||
result.LogisticsContext = model.RiderToStore
|
||||
case uuptapi.StatePickUp: //已取件
|
||||
result.LogisticsStatus = model.WaybillStatusUuPickUp
|
||||
case uuptapi.StatePickUp, uuptapi.StateArrivedDestination: //已取件
|
||||
result.LogisticsStatus = model.WaybillStatusDelivering
|
||||
result.LogisticsContext = model.RiderPickUp
|
||||
case uuptapi.StateArrivedDestination: //到达取件人地址处
|
||||
result.LogisticsStatus = model.WaybillStatusUuArrivedDestination
|
||||
result.LogisticsContext = model.RiderArrivedDestination
|
||||
case uuptapi.StateReceiverGetGoods: //取件人收货
|
||||
result.LogisticsStatus = model.WaybillStatusDelivered
|
||||
result.LogisticsContext = model.RiderGetOrderDelivered
|
||||
|
||||
Reference in New Issue
Block a user