package jd import ( "strings" "time" "git.rosy.net.cn/baseapi/platformapi/autonavi" "git.rosy.net.cn/baseapi/platformapi/jdapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals/api" ) var ( VendorStatus2StatusMap = map[string]int{ jdapi.OrderStatusPurchased: model.OrderStatusNew, jdapi.OrderStatusNew: model.OrderStatusNew, jdapi.OrderStatusAdjust: model.OrderStatusNew, jdapi.OrderStatusWaitOutStore: model.OrderStatusAccepted, jdapi.OrderStatusFinishedPickup: model.OrderStatusFinishedPickup, jdapi.OrderStatusDelivering: model.OrderStatusDelivering, jdapi.OrderStatusDelivered: model.OrderStatusDelivered, jdapi.OrderStatusFinished: model.OrderStatusFinished, jdapi.OrderStatusCanceled: model.OrderStatusCanceled, jdapi.OrderStatusUserApplyCancel: model.OrderStatusApplyCancel, jdapi.OrderStatusLocked: model.OrderStatusLocked, jdapi.OrderStatusUnlocked: model.OrderStatusUnlocked, } ) func (c *PurchaseHandler) OnOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { jxutils.CallMsgHandler(func() { retVal = c.onOrderMsg(msg) }, jxutils.ComposeUniversalOrderID(msg.BillID, model.VendorIDJD)) return retVal } func (c *PurchaseHandler) onOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { if jdapi.OrderStatusNew == msg.StatusID { retVal = c.onOrderNew(msg) } else if jdapi.OrderStatusAdjust == msg.StatusID { retVal = c.onOrderAdjust(msg) } else { status := c.callbackMsg2Status(msg) if msg.StatusID == jdapi.OrderStatusAddComment || msg.StatusID == jdapi.OrderStatusModifyComment { utils.CallFuncAsync(func() { c.onOrderComment2(msg) }) } err := partner.CurOrderManager.OnOrderStatusChanged(status) // if globals.HandleLegacyJxOrder && err == nil { // c.legacyJdOrderStatusChanged(status) // } retVal = jdapi.Err2CallbackResponse(err, status.VendorStatus) } return retVal } func (c *PurchaseHandler) GetOrder(orderID string) (order *model.GoodsOrder, err error) { globals.SugarLogger.Debugf("jd GetOrder orderID:%s", orderID) var ( result map[string]interface{} result2 string err2 error ) task := tasksch.NewParallelTask("jd GetOrder", nil, model.AdminName, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, errInner error) { taskIndex := batchItemList[0].(int) switch taskIndex { case 0: result, err = api.JdAPI.QuerySingleOrder(orderID) case 1: result2, err2 = api.JdAPI.GetRealMobile4Order(orderID) } return nil, nil }, []int{0, 1}) task.Run() task.GetResult(0) if err == nil { order = c.Map2Order(result) if err2 == nil { order.ConsigneeMobile2 = result2 } else { // globals.SugarLogger.Warnf("jd GetOrder orderID:%s, GetRealMobile4Order failed with error:%v", orderID, err2) } } return order, err } func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { result := orderData orderID := utils.Int64ToStr(utils.MustInterface2Int64(result["orderId"])) const defaultStatusTimeField = "orderPurchaseTime" statusTimeField := defaultStatusTimeField if result[statusTimeField] == nil { // 814560888003021 orderPurchaseTime为空 statusTimeField = "orderStartTime" } order = &model.GoodsOrder{ VendorOrderID: orderID, VendorID: model.VendorIDJD, VendorStoreID: utils.Interface2String(result["produceStationNo"]), StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(result["produceStationNoIsv"]), 0)), StoreName: utils.Interface2String(result["produceStationName"]), ConsigneeName: utils.Interface2String(result["buyerFullName"]), ConsigneeMobile: utils.Interface2String(result["buyerMobile"]), ConsigneeAddress: utils.Interface2String(result["buyerFullAddress"]), CoordinateType: model.CoordinateTypeMars, BuyerComment: utils.TrimBlankChar(utils.Interface2String(result["orderBuyerRemark"])), ExpectedDeliveredTime: utils.Str2TimeWithDefault(utils.Interface2String(result["orderPreEndDeliveryTime"]), utils.DefaultTimeValue), PickDeadline: utils.Str2TimeWithDefault(utils.Interface2String(result["pickDeadline"]), utils.DefaultTimeValue), // 813951615000022 pickDeadline为空 VendorStatus: utils.Int64ToStr(utils.MustInterface2Int64(result["orderStatus"])), OrderSeq: int(utils.MustInterface2Int64(result["orderNum"])), StatusTime: utils.Str2Time(result[statusTimeField].(string)), OriginalData: string(utils.MustMarshal(result)), ActualPayPrice: utils.MustInterface2Int64(result["orderBuyerPayableMoney"]), Skus: []*model.OrderSku{}, } order.Status = c.GetStatusFromVendorStatus(order.VendorStatus) businessTage := utils.Interface2String(result["businessTag"]) if strings.Index(businessTage, "dj_aging_immediately") >= 0 { order.BusinessType = model.BusinessTypeImmediate } else { order.BusinessType = model.BusinessTypeDingshida } coordinateType := utils.Interface2Int64WithDefault(result["buyerCoordType"], 1) originalLng := utils.MustInterface2Float64(result["buyerLng"]) originalLat := utils.MustInterface2Float64(result["buyerLat"]) if coordinateType == 1 { lng, lat, err2 := api.AutonaviAPI.CoordinateConvert(originalLng, originalLat, autonavi.CoordSysGPS) if err2 == nil { originalLng = lng originalLat = lat } else { // 如果没有转成功,保留原始数据 order.CoordinateType = model.CoordinateTypeGPS } } order.ConsigneeLng = jxutils.StandardCoordinate2Int(originalLng) order.ConsigneeLat = jxutils.StandardCoordinate2Int(originalLat) // discounts := result["discount"].(map[string]interface{}) for _, product2 := range result["product"].([]interface{}) { product := product2.(map[string]interface{}) sku := &model.OrderSku{ VendorOrderID: orderID, VendorID: model.VendorIDJD, Count: int(utils.MustInterface2Int64(product["skuCount"])), SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(product["skuIdIsv"]), 0)), VendorSkuID: utils.Int64ToStr(utils.MustInterface2Int64(product["skuId"])), SkuName: product["skuName"].(string), Weight: jxutils.FloatWeight2Int(float32(utils.MustInterface2Float64(product["skuWeight"]))), SalePrice: utils.MustInterface2Int64(product["skuJdPrice"]), PromotionType: int(utils.MustInterface2Int64(product["promotionType"])), } if skuCostumeProperty, ok := product["skuCostumeProperty"]; ok { sku.SkuName += skuCostumeProperty.(string) } if isGift, ok := product["isGift"].(bool); ok && isGift { sku.SkuType = 1 } order.Skus = append(order.Skus, sku) order.SkuCount++ order.GoodsCount += sku.Count order.SalePrice += sku.SalePrice * int64(sku.Count) order.Weight += sku.Weight * sku.Count } setOrederDetailFee(result, order) return order } func setOrederDetailFee(result map[string]interface{}, order *model.GoodsOrder) { order.BoxFee = utils.Interface2Int64WithDefault(result["packagingMoney"], 0) order.PlatformFeeRate = model.JdPlatformFeeRate order.BillStoreFreightFee = utils.Interface2Int64WithDefault(result["merchantPaymentDistanceFreightMoney"], 0) + utils.Interface2Int64WithDefault(result["tips"], 0) } // func (c *PurchaseHandler) onOrderNew(msg *jdapi.CallbackOrderMsg) (response *jdapi.CallbackResponse) { order, err := c.GetOrder(msg.BillID) if err == nil { err = partner.CurOrderManager.OnOrderNew(order, msg.StatusID) // if err == nil { // c.legacyWriteJdOrder(order, false) // } } return jdapi.Err2CallbackResponse(err, "jd onOrderNew") } func (c *PurchaseHandler) onOrderAdjust(msg *jdapi.CallbackOrderMsg) *jdapi.CallbackResponse { order, err := c.GetOrder(msg.BillID) if err == nil { err = partner.CurOrderManager.OnOrderAdjust(order, msg.StatusID) // if globals.HandleLegacyJxOrder && err == nil { // c.legacyWriteJdOrder(order, true) // } } return jdapi.Err2CallbackResponse(err, "jd onOrderAdjust") } func (c *PurchaseHandler) callbackMsg2Status(msg *jdapi.CallbackOrderMsg) *model.OrderStatus { orderStatus := &model.OrderStatus{ VendorOrderID: msg.BillID, VendorID: model.VendorIDJD, OrderType: model.OrderTypeOrder, RefVendorOrderID: msg.BillID, RefVendorID: model.VendorIDJD, VendorStatus: msg.StatusID, Status: c.GetStatusFromVendorStatus(msg.StatusID), StatusTime: utils.Str2Time(msg.Timestamp), Remark: msg.Remark, } return orderStatus } // IPurchasePlatformHandler func (c *PurchaseHandler) GetStatusFromVendorStatus(vendorStatus string) int { if status, ok := VendorStatus2StatusMap[vendorStatus]; ok { return status } return model.OrderStatusUnknown } func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { return api.JdAPI.OrderAcceptOperate(order.VendorOrderID, isAcceptIt, userName) } func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, userName string) (err error) { _, err = api.JdAPI.OrderJDZBDelivery(order.VendorOrderID, userName) return err } func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) { _, err = api.JdAPI.ModifySellerDelivery(order.VendorOrderID, userName) if err != nil { if errWithCode, ok := err.(*utils.ErrorWithCode); ok && errWithCode.Level() == 1 { globals.SugarLogger.Infof("Swtich2SelfDeliver failed with error:%v try get current status", err) if order2, err2 := c.GetOrder(order.VendorOrderID); err2 == nil { var mapData map[string]interface{} if err2 = utils.UnmarshalUseNumber([]byte(order2.OriginalData), &mapData); err2 == nil { if utils.Interface2String(mapData["deliveryCarrierNo"]) == "2938" { // 当前已经是自送状态了 err = nil } } } } } return err } func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) { _, err = api.JdAPI.DeliveryEndOrder(order.VendorOrderID, userName) return err } func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { _, err = api.JdAPI.OrderSerllerDelivery(order.VendorOrderID, userName) return err } // 京东送达接口都是一样的 func (c *PurchaseHandler) SelfDeliverDelievered(order *model.GoodsOrder, userName string) (err error) { return c.Swtich2SelfDelivered(order, userName) } func (c *PurchaseHandler) RefreshRealMobile(ctx *jxcontext.Context, fromTime, toTime time.Time, isAsync, isContinueWhenError bool) (hint string, err error) { return hint, err }