package jd import ( "fmt" "regexp" "strings" "time" "git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg" "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" "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/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.OrderStatusWaitOutStore: model.OrderStatusAccepted, jdapi.StatusIDWaitOutStore: model.OrderStatusAccepted, jdapi.OrderStatusFinishedPickup: model.OrderStatusFinishedPickup, jdapi.OrderStatusDelivering: model.OrderStatusDelivering, jdapi.OrderStatusDelivered: model.OrderStatusFinished, jdapi.OrderStatusFinished: model.OrderStatusFinished, // todo 这个状态不是真正都完成的意思? jdapi.OrderStatusCanceled: model.OrderStatusCanceled, jdapi.OrderStatusAdjust: model.OrderStatusAdjust, jdapi.OrderStatusUserApplyCancel: model.OrderStatusApplyCancel, jdapi.OrderStatusLocked: model.OrderStatusLocked, jdapi.OrderStatusUnlocked: model.OrderStatusUnlocked, jdapi.OrderStatusVenderAgreeCancel: model.OrderStatusVendorAgreeCancel, jdapi.OrderStatusVenderRejectCancel: model.OrderStatusVendorRejectCancel, jdapi.CallbackMsgOrderAddTips: model.OrderStatusWaybillTipChanged, } deliveryTypeMap = map[int]string{ jdapi.CarrierNoCrowdSourcing: model.OrderDeliveryTypePlatform, jdapi.CarrierNoSelfDelivery: model.OrderDeliveryTypeStoreSelf, jdapi.CarrierNoSelfTake: model.OrderDeliveryTypeSelfTake, } selfTakeCodeReg = regexp.MustCompile(`等待用户凭提货码(\d+)于`) afsMsgMap = map[string]bool{ jdapi.CallbackMsgNewApplyAfterSaleBill: true, jdapi.CallbackMsgUpdateApplyAfterSaleBill: true, jdapi.CallbackMsgNewAfterSaleBill: true, jdapi.CallbackMsgAfterSaleBillStatus: true, } ) func (c *PurchaseHandler) OnOrderMsg(vendorOrgCode string, msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { jxutils.CallMsgHandler(func() { retVal = c.onOrderMsg(vendorOrgCode, msg) }, jxutils.ComposeUniversalOrderID(msg.BillID, model.VendorIDJD)) return retVal } func (c *PurchaseHandler) updateOrderFinancialInfo(a *jdapi.API, orderID string) (err error) { order := &model.GoodsOrder{ VendorOrderID: orderID, VendorID: model.VendorIDJD, } orderSettlement, err := a.OrderShoudSettlementService2(orderID) if err == nil { if orderSettlement != nil { updateOrderBySettleMent(order, orderSettlement) globals.SugarLogger.Debugf("updateOrderBySettleMent: %v , %v", order.NewEarningPrice, order.TotalShopMoney) err = partner.CurOrderManager.UpdateOrderFields(order, []string{ /*"WaybillTipMoney", */ "TotalShopMoney", "PmSubsidyMoney", "NewEarningPrice"}) } } return err } func (c *PurchaseHandler) onOrderMsg(vendorOrgCode string, msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { a := getAPI(vendorOrgCode) if afsMsgMap[msg.MsgURL] { retVal = c.OnAfsOrderMsg(a, msg) } else { status := c.callbackMsg2Status(msg) if jdapi.StatusIDNewOrder == msg.StatusID { status.Status = model.OrderStatusNew // 因为京东将事件32000与状态32000混用,事件32000可能是新订单,也可能是已接单,统一当成新订单处理 } if partner.CurOrderManager.GetStatusDuplicatedCount(status) > 0 { return nil } if msg.MsgURL == jdapi.CallbackMsgOrderAccounting { retVal = c.OnFinancialMsg(msg) retVal = jdapi.Err2CallbackResponse(c.updateOrderFinancialInfo(a, msg.BillID), status.VendorStatus) } else { // 新订单事件,与订单状态有点冲突 if jdapi.StatusIDNewOrder == msg.StatusID { retVal = c.onOrderNew(a, msg, status) } else if jdapi.OrderStatusAdjust == msg.StatusID { retVal = c.onOrderAdjust(a, msg, status) } else { if msg.StatusID == jdapi.OrderStatusAddComment || msg.StatusID == jdapi.OrderStatusModifyComment { utils.CallFuncAsync(func() { c.onOrderComment2(a, msg) }) } // if msg.StatusID == jdapi.OrderStatusVenderAgreeCancel { // order := &model.GoodsOrder{ // VendorOrgCode: vendorOrgCode, // VendorOrderID: msg.BillID, // } // err2 := c.PickupGoods(order, false, jxcontext.AdminCtx.GetUserName()) // if err2 != nil { // globals.SugarLogger.Warnf("京东取消拣货:%v", err2) // } // } err := partner.CurOrderManager.OnOrderStatusChanged(vendorOrgCode, status) retVal = jdapi.Err2CallbackResponse(err, status.VendorStatus) } } } return retVal } func (c *PurchaseHandler) OnOrderInfoChangeMsg(vendorOrgCode string, msg *jdapi.CallbackOrderInfoChangeMsg) (retVal *jdapi.CallbackResponse) { jxutils.CallMsgHandler(func() { retVal = c.onOrderInfoChangeMsg(vendorOrgCode, msg) }, jxutils.ComposeUniversalOrderID(msg.BillID, model.VendorIDJD)) return retVal } func (c *PurchaseHandler) onOrderInfoChangeMsg(vendorOrgCode string, msg *jdapi.CallbackOrderInfoChangeMsg) (retVal *jdapi.CallbackResponse) { db := dao.GetDB() order, err := dao.GetSimpleOrder(db, msg.BillID) if err == nil { globals.SugarLogger.Debugf("onOrderInfoChangeMsg msg:%v", utils.Format4Output(msg, false)) if msg.BuyerFullAddress != "" { order.ConsigneeAddress = msg.BuyerFullAddress } if msg.BuyerFullName != "" { order.ConsigneeName = msg.BuyerFullName } if msg.BuyerMobile != "" { order.ConsigneeMobile = msg.BuyerMobile } if msg.BuyerLat != "" { order.ConsigneeLat = jxutils.StandardCoordinate2Int(utils.Str2Float64(msg.BuyerLat)) } if msg.BuyerLng != "" { order.ConsigneeLng = jxutils.StandardCoordinate2Int(utils.Str2Float64(msg.BuyerLng)) } if msg.OrderBuyerRemark != "" { order.BuyerComment = msg.OrderBuyerRemark } _, err = dao.UpdateEntity(db, order, "ConsigneeAddress", "ConsigneeName", "ConsigneeMobile", "ConsigneeLat", "ConsigneeLng", "BuyerComment") weixinmsg.NotifyOrderChanged(order) } return jdapi.SuccessResponse } func updateOrderBySettleMent(order *model.GoodsOrder, orderSettlement *jdapi.OrderSettlementInfo) { if orderSettlement != nil { order.TotalShopMoney = orderSettlement.SettlementAmount order.PmSubsidyMoney = orderSettlement.PlatOrderGoodsDiscountMoney + orderSettlement.PlatSkuGoodsDiscountMoney if order.TotalShopMoney > 0 { if jxutils.GetSaleStoreIDFromOrder(order) != 0 { storeDetail, err := partner.CurOrderManager.LoadStoreDetail(jxutils.GetSaleStoreIDFromOrder(order), order.VendorID) if storeDetail != nil && err == nil { jxutils.RefreshOrderEarningPrice2(order, storeDetail.PayPercentage) } } else { order2, err := partner.CurOrderManager.LoadOrder(order.VendorOrderID, order.VendorID) if order2 != nil && err == nil { storeDetail, err := partner.CurOrderManager.LoadStoreDetail(jxutils.GetSaleStoreIDFromOrder(order2), order.VendorID) if storeDetail != nil && err == nil { jxutils.RefreshOrderEarningPrice2(order, storeDetail.PayPercentage) } } } } else { order.NewEarningPrice = order.EarningPrice } } } func (c *PurchaseHandler) getOrder(a *jdapi.API, orderID string) (order *model.GoodsOrder, orderMap map[string]interface{}, err error) { globals.SugarLogger.Debugf("jd getOrder orderID:%s", orderID) var ( realMobile string orderSettlement *jdapi.OrderSettlementInfo ) task := tasksch.NewParallelTask("jd getOrder", tasksch.NewParallelConfig().SetIsContinueWhenError(true), jxcontext.AdminCtx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { taskIndex := batchItemList[0].(int) switch taskIndex { case 0: orderMap, err = a.QuerySingleOrder(orderID) if err == nil { order = c.Map2Order(orderMap) realMobile, _ = a.GetRealMobile4Order(orderID, order.VendorStoreID) if realMobile != "" { order.ConsigneeMobile2 = jxutils.FormalizeMobile(realMobile) } } case 1: orderSettlement, _ = a.OrderShoudSettlementService2(orderID) } return nil, err }, []int{0, 1}) task.Run() _, err = task.GetResult(0) if order != nil && orderSettlement != nil { updateOrderBySettleMent(order, orderSettlement) err = partner.CurOrderManager.UpdateOrderFields(order, []string{"NewEarningPrice"}) } return order, orderMap, err } func (c *PurchaseHandler) GetOrder(vendorOrgCode, orderID string) (order *model.GoodsOrder, err error) { order, _, err = c.getOrder(getAPI(vendorOrgCode), orderID) return order, err } func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) { order, err := getAPI(vendorOrgCode).QuerySingleOrder2(vendorOrderID) if err == nil { status = getStatusFromVendorStatus(utils.Int2Str(order.OrderStatus)) } return status, err } func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { return Map2Order(orderData) } func Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { result := orderData orderID := utils.Int64ToStr(utils.MustInterface2Int64(result["orderId"])) globals.SugarLogger.Debugf("jd Map2Order orderID:%s", 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"]), VendorUserID: utils.Interface2String(result["buyerPin"]), ConsigneeName: utils.Interface2String(result["buyerFullName"]), ConsigneeMobile: jxutils.FormalizeMobile(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)), OrderCreatedAt: utils.Str2Time(result[statusTimeField].(string)), // OrderFinishedAt: utils.Str2Time(result["orderStatusTime"].(string)), OriginalData: string(utils.MustMarshal(result)), ActualPayPrice: utils.MustInterface2Int64(result["orderBuyerPayableMoney"]), BaseFreightMoney: utils.Interface2Int64WithDefault(result["orderBaseFreightMoney"], 0), DistanceFreightMoney: utils.Interface2Int64WithDefault(result["merchantPaymentDistanceFreightMoney"], 0), DeliveryType: deliveryTypeMap[int(utils.Str2Int64WithDefault(utils.Interface2String(result["deliveryCarrierNo"]), 0))], VendorOrgCode: utils.Interface2String(result["orgCode"]), } if orderInvoice, ok := result["orderInvoice"].(map[string]interface{}); ok && orderInvoice != nil { order.InvoiceTitle = utils.Interface2String(orderInvoice["invoiceTitle"]) order.InvoiceTaxerID = utils.Interface2String(orderInvoice["invoiceDutyNo"]) order.InvoiceEmail = utils.Interface2String(orderInvoice["invoiceMail"]) } order.Status = 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"].([]interface{}) for _, v := range discounts { discount := v.(map[string]interface{}) order.DiscountMoney += utils.Interface2Int64WithDefault(discount["discountPrice"], 0) } 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"]))), VendorPrice: utils.MustInterface2Int64(product["skuStorePrice"]), SalePrice: utils.MustInterface2Int64(product["skuJdPrice"]), } if jdPromotionType := int(utils.MustInterface2Int64(product["promotionType"])); jdPromotionType != 0 && jdPromotionType != jdapi.PromotionTypeNormal { sku.StoreSubName = utils.Int2Str(jdPromotionType) } 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) } jxutils.RefreshOrderSkuRelated(order) return order } // func (c *PurchaseHandler) onOrderNew(a *jdapi.API, msg *jdapi.CallbackOrderMsg, orderStatus *model.OrderStatus) (response *jdapi.CallbackResponse) { globals.SugarLogger.Debugf("onOrderNew orderID:%s", msg.BillID) order, orderMap, err := c.getOrder(a, msg.BillID) if err == nil { globals.SugarLogger.Debugf("onOrderNew2 orderID:%s", msg.BillID) if err = partner.CurOrderManager.OnOrderNew(order, orderStatus); err == nil { utils.CallFuncAsync(func() { c.OnOrderDetail(a, orderMap, partner.CreatedPeration) }) } } return jdapi.Err2CallbackResponse(err, "jd onOrderNew") } func (c *PurchaseHandler) onOrderAdjust(a *jdapi.API, msg *jdapi.CallbackOrderMsg, orderStatus *model.OrderStatus) *jdapi.CallbackResponse { order, orderMap, err := c.getOrder(a, msg.BillID) if err == nil { err = partner.CurOrderManager.OnOrderAdjust(order, orderStatus) if err == nil { utils.CallFuncAsync(func() { c.OnOrderDetail(a, orderMap, partner.UpdatedPeration) }) } } 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, StatusTime: utils.Str2Time(msg.Timestamp), Remark: msg.Remark, } if msg.MsgURL == jdapi.CallbackMsgOrderAddTips { orderStatus.VendorStatus = jdapi.CallbackMsgOrderAddTips } orderStatus.Status = getStatusFromVendorStatus(orderStatus.VendorStatus) return orderStatus } func (c *PurchaseHandler) postFakeMsg(vendorOrgCode, vendorOrderID, vendorStatus string) { msg := &jdapi.CallbackOrderMsg{ CallbackMsg: &jdapi.CallbackMsg{ AppKey: getAPI(vendorOrgCode).GetAppKey(), }, BillID: vendorOrderID, StatusID: vendorStatus, Timestamp: utils.Time2Str(time.Now()), } utils.CallFuncAsync(func() { OnOrderMsg(msg) }) } // IPurchasePlatformHandler func 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) { globals.SugarLogger.Debugf("jd AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt) if globals.EnableJdStoreWrite { err = getAPI(order.VendorOrgCode).OrderAcceptOperate(order.VendorOrderID, isAcceptIt, userName) if isAcceptIt && err == nil { c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.StatusIDWaitOutStore) } } else { if isAcceptIt { c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.StatusIDWaitOutStore) } else { c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.OrderStatusCanceled) } } return err } func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { globals.SugarLogger.Debugf("jd PickupGoods orderID:%s, isSelfDelivery:%t", order.VendorOrderID, isSelfDelivery) if !isSelfDelivery && globals.EnableJdStoreWrite { _, err = getAPI(order.VendorOrgCode).OrderJDZBDelivery(order.VendorOrderID, userName) } else { c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.OrderStatusFinishedPickup) } if err == nil { orderSettlement, _ := getAPI(order.VendorOrgCode).OrderShoudSettlementService2(order.VendorOrderID) updateOrderBySettleMent(order, orderSettlement) globals.SugarLogger.Debugf("jd PickupGoods, %v", order.NewEarningPrice) err = partner.CurOrderManager.UpdateOrderFields(order, []string{"NewEarningPrice"}) } return err } func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) { if globals.EnableJdStoreWrite { err = getAPI(order.VendorOrgCode).ReceiveFailedAudit(order.VendorOrderID, isAcceptIt, ctx.GetUserName(), "") } return err } func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 拣货失败后再次招唤平台配送 if globals.EnableJdStoreWrite { err = getAPI(order.VendorOrgCode).UrgeDispatching(order.VendorOrderID, ctx.GetUserName()) } return err } func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 投递失败后确认收到退货 if globals.EnableJdStoreWrite { err = getAPI(order.VendorOrgCode).ConfirmReceiveGoods(order.VendorOrderID) } return err } func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) { globals.SugarLogger.Debugf("jd Swtich2SelfDeliver orderID:%s", order.VendorOrderID) if globals.EnableJdStoreWrite { _, err = getAPI(order.VendorOrgCode).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.VendorOrgCode, 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) { globals.SugarLogger.Debugf("jd Swtich2SelfDelivered orderID:%s", order.VendorOrderID) if globals.EnableJdStoreWrite { _, err = getAPI(order.VendorOrgCode).DeliveryEndOrder(order.VendorOrderID, userName) } return err } func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { globals.SugarLogger.Debugf("jd SelfDeliverDelivering orderID:%s", order.VendorOrderID) if globals.EnableJdStoreWrite { _, err = getAPI(order.VendorOrgCode).OrderSerllerDelivery(order.VendorOrderID, userName) } return err } // 京东送达接口都是一样的 func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) { globals.SugarLogger.Debugf("jd SelfDeliverDelivered orderID:%s", order.VendorOrderID) if globals.EnableJdStoreWrite { err = c.Swtich2SelfDelivered(order, userName) } return err } func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) { mobile, err = getAPI(order.VendorOrgCode).GetRealMobile4Order(order.VendorOrderID, order.VendorStoreID) return mobile, err } func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) { if globals.EnableJdStoreWrite { err = getAPI(order.VendorOrgCode).OrderCancelOperate(order.VendorOrderID, isAgree, ctx.GetUserName(), reason) } return err } func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { if globals.EnableJdStoreWrite { err1 := c.Swtich2SelfDeliver(order, ctx.GetUserName()) if err = getAPI(order.VendorOrgCode).CancelAndRefund(order.VendorOrderID, ctx.GetUserName(), reason); err != nil { if err1 != nil { err = fmt.Errorf("取消订单失败,京东取消订单是要先转为自送再处理,转自送失败:%v", err1) } } } return err } func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) { order = jxutils.RemoveSkuFromOrder(order, removedSkuList) var oaosAdjustDTOList []*jdapi.OAOSAdjustDTO dtoMap := make(map[int]*jdapi.OAOSAdjustDTO) for _, sku := range order.Skus { skuID := jxutils.GetSkuIDFromOrderSku(sku) if dtoMap[skuID] == nil { dtoMap[skuID] = &jdapi.OAOSAdjustDTO{ OutSkuID: utils.Int2Str(skuID), SkuCount: sku.Count, } oaosAdjustDTOList = append(oaosAdjustDTOList, dtoMap[skuID]) } else { dtoMap[skuID].SkuCount += sku.Count } } if globals.EnableJdStoreWrite { err = getAPI(order.VendorOrgCode).AdjustOrder(order.VendorOrderID, ctx.GetUserName(), reason, oaosAdjustDTOList) } return err } func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) { if utils.IsTimeZero(queryDate) { return nil, fmt.Errorf("queryDate必须指定") } fromDate := utils.Time2Date(queryDate) toDate := fromDate.Add(24*time.Hour - 1) queryParam := &jdapi.OrderQueryParam{ OrderPurchaseTimeBegin: utils.Time2Str(fromDate), OrderPurchaseTimeEnd: utils.Time2Str(toDate), PageNo: jdapi.AllPage, } if vendorStoreID != "" { queryParam.DeliveryStationNo = vendorStoreID } orderList, _, err := getAPI(vendorOrgCode).OrderQuery2(queryParam) if err == nil { vendorOrderIDs = make([]string, len(orderList)) for k, v := range orderList { vendorOrderIDs[k] = utils.Int64ToStr(v.OrderID) } } return vendorOrderIDs, err } func (c *PurchaseHandler) GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error) { orderInfo, err := getAPI(vendorOrgCode).QuerySingleOrder2(vendorOrderID) if err == nil { tipFee = int64(orderInfo.Tips) } return tipFee, err } func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error) { curTipFee, err := c.GetWaybillTip(ctx, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2) if err == nil { if tipFee2Add := tipFee - curTipFee; tipFee2Add > 0 { if globals.EnableJdStoreWrite { err = getAPI(vendorOrgCode).OrderAddTips(vendorOrderID, int(tipFee2Add), ctx.GetUserName()) } } } return err } func (c *PurchaseHandler) GetSelfTakeCode(ctx *jxcontext.Context, order *model.GoodsOrder) (selfTakeCode string, err error) { orderTrackList, err := getAPI(order.VendorOrgCode).GetByOrderNoForOaos(order.VendorOrderID) if err == nil { for _, v := range orderTrackList { if v.TagCode == 180 { searchResult := selfTakeCodeReg.FindStringSubmatch(v.MsgContent) if searchResult != nil && len(searchResult[1]) > 0 { selfTakeCode = searchResult[1] } break } } } return selfTakeCode, err } func (c *PurchaseHandler) ConfirmSelfTake(ctx *jxcontext.Context, order *model.GoodsOrder, selfTakeCode string) (err error) { if globals.EnableJdStoreWrite { err = getAPI(order.VendorOrgCode).CheckSelfPickCode(selfTakeCode, order.VendorOrderID, ctx.GetUserName()) } return err }