package sfps import ( "encoding/json" "errors" "fmt" "io/ioutil" "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) } if maxDeliveryFee == model.NO { if order.EarningType != model.EarningTypePoints { fee, err := d.GetWaybillFee(order) if err != nil { return nil, err } if fee.DeliveryFee >= model.DefMaxDeliveryFee { return nil, fmt.Errorf("顺丰超最高限价, 所需运费:%s, 最高限价:%s", jxutils.IntPrice2StandardCurrencyString(fee.DeliveryFee), jxutils.IntPrice2StandardCurrencyString(model.DefMaxDeliveryFee)) } } } 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) deliveryFeeInfo.RefAddFee = utils.Float64TwoInt64(price) 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) //判断是否是果园 if goodsOrder == nil && beego.BConfig.RunMode != "jxgy" { 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) } } //获取实时订单信息 sfOrder, err := api.SfPsAPI.GetOrderStatus(order.VendorWaybillID) if err != nil { return sfps2.Err2CallbackResponse(err) } if order.CourierMobile == "" { order.CourierName = sfOrder.RiderName } if order.CourierName == "" { order.CourierMobile = sfOrder.RiderPhone } sfTotalPrice := utils.Float64TwoInt(sfOrder.TotalPrice) sfActualPrice := utils.Float64TwoInt64(sfOrder.RealPayMoney) 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, model.VendorIDEBAI, model.VendorIDJD: 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 ) b, _ := json.Marshal(msg) switch urlIndex { case sfps2.UrlIndexRiderException: request, err = http.NewRequest(http.MethodPost, "http://callback-jxgy.jxc4.com/SFPS/SfAbnormal", strings.NewReader(string(b))) default: //fullUrl := utils.GenerateGetURL("http://callback-jxgy.jxc4.com/SFPS/SfOrder", "", map[string]interface{}{"sign": sign}) //request, err = http.NewRequest(http.MethodPost, fullUrl, strings.NewReader(string(b))) request, err = http.NewRequest(http.MethodPost, "http://callback-jxgy.jxc4.com/SFPS/SfOrder", strings.NewReader(string(b))) } if err != nil { globals.SugarLogger.Debugf("pushCallbackToGy req err=%v", err) return } request.Header.Set("Content-Type", "application/json; charset=UTF-8") resp, err := client.Do(request) ioutil.ReadAll(resp.Body) } 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("%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 } //签名 //b, _ := json.Marshal(retVal) //sign := api.SfPsAPI.SignParam(b) //retVal["sign"] = sign return retVal } // 辅助函数 //获取订单来源标识符 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 } }