diff --git a/business/jxcallback/scheduler/defsch/defsch.go b/business/jxcallback/scheduler/defsch/defsch.go index 8bea09133..c9c197a38 100644 --- a/business/jxcallback/scheduler/defsch/defsch.go +++ b/business/jxcallback/scheduler/defsch/defsch.go @@ -596,6 +596,21 @@ func (s *DefScheduler) OnWaybillStatusChanged(bill *model.Waybill, isPending boo // s.addWaybill2Map(savedOrderInfo, bill) // updateBillsInfo中会添加 globals.SugarLogger.Debugf("OnWaybillStatusChanged bill not exist! orderID:%s, bill:%v", bill.VendorOrderID, bill) } + // 美团订单会存在:用户直接申请退款,不推送取消消息!导致三方配送未取消! + if order.Status >= model.OrderStatusCanceled { + s.removeWaybillFromMap(savedOrderInfo, bill.WaybillVendorID) + if s.isBillCandidate(order, bill) { + s.resetTimer(savedOrderInfo, bill, isPending) + if !isPending { + s.updateOrderByBill(order, nil, true) + } + } else if model.IsOrderHaveWaybill(order) { + s.ProxyCancelWaybill(order, bill, partner.CancelWaybillReasonNotAcceptIntime, partner.CancelWaybillReasonStrNotAcceptIntime) + if !isPending { + globals.SugarLogger.Warnf("OnWaybillStatusChanged AcceptCanceled orderID:%s got multiple bill:%v, order details:%v", order.VendorOrderID, bill, order) + } + } + } switch bill.Status { case model.WaybillStatusAccepted, model.WaybillStatusCourierAssigned, model.WaybillStatusCourierArrived, model.WaybillStatusDelivering: s.resetTimer(savedOrderInfo, bill, isPending) diff --git a/business/partner/purchase/tiktok_store/store_sku2_utils.go b/business/partner/purchase/tiktok_store/store_sku2_utils.go index d182af693..ca217194c 100644 --- a/business/partner/purchase/tiktok_store/store_sku2_utils.go +++ b/business/partner/purchase/tiktok_store/store_sku2_utils.go @@ -136,80 +136,6 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI if storeSku.StoreSkuStatus != 1 { // 未可售的商品不参与修改 continue } - param := &product_addV2_request.ProductAddV2Param{ - Name: utils.LimitUTF8StringLen(storeSku.SkuName, 90), - PayType: tiktokShop.TiktokPayType1, - ReduceType: tiktokShop.SkuReduceTypePayMakeOrder, - Weight: utils.Int2Float64(storeSku.Weight), - DeliveryDelayDay: tiktokShop.DeliveryDelayDayToDay, - PresellType: tiktokShop.SendGoodsTypeNow, - Supply7dayReturn: 0, // 是否支持7天无理由,0不支持,1支持,2支持(拆封后不支持) - Mobile: storeDetail.Tel1, - Commit: true, - Specs: "重量|" + utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit, - NeedRechargeMode: false, - SellChannel: []int64{0}, - StartSaleType: 0, - PickupMethod: "0", - OuterProductId: utils.Int2Str(storeSku.SkuID), // 本地skuId为外部商品id - } - param.Name = checkNameLenght(param.Name) - - // 获取上传图,商品轮播图 - img, detailImg, err := GetTiktokImgList(api, utils.Int2Str(storeSku.StoreID), storeDetail.VendorOrgCode, storeSku.DescImg, storeSku.ImgOrigin, storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) - continue - } - param.Pic = img - param.Description = detailImg - - // 部分商品没有所属的分类,直接跳过! - if storeSku.SkuVendorMapCatID != "" { - param.CategoryLeafId = utils.Str2Int64(storeSku.SkuVendorMapCatID) - } else if len(param.Pic) != 0 { // 自动推导分类id - param.CategoryLeafId, err = api.GetRecommendCategory(strings.Split(img, "|")) - if param.CategoryLeafId == 0 || err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSku, errors.New("当前商品本地未设置抖音分类/抖音推荐分类查询错误:"+err.Error()), storeID, model.VendorChineseNames[model.VendorIDDD], syncType) - continue - } - } - // 这个情况是原有商品不存在和推荐查询不到类目id是,使用京西类目和抖音类目的绑定关系 - // 但是不太实用,导致商品类目错误被暂停营业等 - //if storeSku.VendorVendorCatID != 0 && param.CategoryLeafId == 0 { - // param.CategoryLeafId = storeSku.VendorVendorCatID - //} - - // 是否支持七天无理由 - if api.GetProductUpdateRule(param.CategoryLeafId) { - param.Supply7dayReturn = 1 - } else { - param.Supply7dayReturn = 0 - } - - // weight_unit 目前抖音只支持g和kg两种 - param.WeightUnit = tiktokShop.WeightUint_G - - // spec_prices - param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, 0, storeSku) - // 获取商品的属性 - if storeSku.TiktokAttribute != "" && storeSku.TiktokAttribute != "{}" { - param.ProductFormatNew = storeSku.TiktokAttribute - } else if storeSku.VendorSkuAttrId != "" && storeSku.VendorSkuAttrId != "{}" { - param.ProductFormatNew = storeSku.TiktokAttribute - } else { - param.ProductFormatNew, err = MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSku, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) - continue - } - } - param.StandardBrandId = 789194134 // 默认品牌京西菜市 596120136 - param.FreightId, param.SaleLimitId, err = getFreightIdAndSaleLimitId(api, db, storeDetail, vendorStoreID) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSku, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) - continue - } // 根据本地商品id获取线上商品是否存在,存在则只创建子商品 // 获取本地存储映射关系,获取本地主商品id是否存在 @@ -222,6 +148,11 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI if len(localThing) == 0 { //if mainProductId == 0 { + param, failedList2 := makeMainProductSku(db, api, storeSku, storeDetail, storeID, vendorStoreID, syncType) + if len(failedList2) != 0 { + failedList = append(failedList, failedList2...) + continue + } tiktokResult, err := api.CreateStoreCommodity(param) // 创建主商品,同步主商品 if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSku, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) @@ -240,35 +171,6 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI storeSku.VendorSkuAttrId = strings.Join(attrId, ",") // 属性id skuID storeSku.VendorSonSkuID = utils.Int2Str(storeSku.SkuID) // 还没同步子商品 failedList = putils.GetErrMsg2FailedSingleList(storeSku, errors.New("只创建了主商品,没创建子商品"), storeID, model.VendorChineseNames[model.VendorIDDD], syncType) - //} else { - // // 本地不存在,线上存在.直接创建子商品保存本地同步记录 - // var childrenProductId int64 = 0 - // dao.CreateThingMap(int64(storeSku.SkuID), utils.Int64ToStr(mainProductId), storeDetail.VendorOrgCode, "线上存在本地不存在", model.ThingTypeSku, 0) - // - // childrenProductId, err = api.CreateSubProduct(mainProductId, utils.Str2Int64(vendorStoreID)) - // if err != nil { - // failedList = putils.GetErrMsg2FailedSingleList(storeSku, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) - // continue - // } - // - // storeSku.VendorMainId = utils.Int64ToStr(mainProductId) - // var attrId []string - // for _, v := range mainOrderDetail.SpecPrices { - // attrId = append(attrId, utils.Int64ToStr(v.SkuId)) - // } - // storeSku.VendorSkuAttrId = strings.Join(attrId, ",") // 属性id skuID - // if childrenProductId > 0 { - // storeSku.VendorSonSkuID = utils.Int64ToStr(childrenProductId) // (属性id skuID方案一)(自商品的商品id方案二) - // storeSku.SkuSyncStatus = 0 - // storeSku.VendorSkuID = utils.Int64ToStr(childrenProductId) // 子商品主id - // upDateChildrenPriceStockLaunch(api, storeSku, childrenProductId, vendorStoreID, syncType) - // } else { - // storeSku.VendorSonSkuID = utils.Int2Str(storeSku.SkuID) // (属性id skuID方案一)(自商品的商品id方案二) - // storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID) // 子商品主id - // storeSku.SkuSyncStatus = model.SyncFlagNewMask - // failedList = putils.GetErrMsg2FailedSingleList(storeSku, errors.New("主商品创建了,子商品为创建"), storeID, model.VendorChineseNames[model.VendorIDDD], syncType) - // } - //} } else { // 主商品存在,直接同步子商品 childrenProductId, err := api.CreateSubProduct(utils.Str2Int64(localThing[0].VendorThingID), utils.Str2Int64(vendorStoreID)) @@ -277,6 +179,11 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI mainOrderDetail = loadMainProductId(api, storeSku, localThing[0].VendorThingID) if mainOrderDetail.CheckStatus == tiktokShop.SkuCheckStatusProhibit || mainOrderDetail.CheckStatus == tiktokShop.SkuCheckStatusNotPass { // 更新主商品,在同步到子门店,考虑审核时间 + param, failedList2 := makeMainProductSku(db, api, storeSku, storeDetail, storeID, vendorStoreID, syncType) + if len(failedList2) != 0 { + failedList = append(failedList, failedList2...) + continue + } updateParam := &product_editV2_request.ProductEditV2Param{ PayType: tiktokShop.TiktokPayType1, ReduceType: tiktokShop.SkuReduceTypePayMakeOrder, @@ -295,8 +202,8 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI Name: param.Name, ProductFormatNew: param.ProductFormatNew, } - updateParam.Pic = img - updateParam.Description = detailImg + updateParam.Pic = param.Pic + updateParam.Description = param.Description updateParam.WeightUnit = tiktokShop.WeightUint_G updateParam.StandardBrandId = param.StandardBrandId // 默认品牌京西菜市 updateParam.ProductId = mainOrderDetail.ProductId @@ -420,6 +327,84 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI return failedList, err } +func makeMainProductSku(db *dao.DaoDB, api *tiktokShop.API, storeSku *dao.StoreSkuSyncInfo, storeDetail *dao.StoreDetail, storeID int, vendorStoreID, syncType string) (param *product_addV2_request.ProductAddV2Param, failedList []*partner.StoreSkuInfoWithErr) { + param = &product_addV2_request.ProductAddV2Param{ + Name: utils.LimitUTF8StringLen(storeSku.SkuName, 90), + PayType: tiktokShop.TiktokPayType1, + ReduceType: tiktokShop.SkuReduceTypePayMakeOrder, + Weight: utils.Int2Float64(storeSku.Weight), + DeliveryDelayDay: tiktokShop.DeliveryDelayDayToDay, + PresellType: tiktokShop.SendGoodsTypeNow, + Supply7dayReturn: 0, // 是否支持7天无理由,0不支持,1支持,2支持(拆封后不支持) + Mobile: storeDetail.Tel1, + Commit: true, + Specs: "重量|" + utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit, + NeedRechargeMode: false, + SellChannel: []int64{0}, + StartSaleType: 0, + PickupMethod: "0", + OuterProductId: utils.Int2Str(storeSku.SkuID), // 本地skuId为外部商品id + } + param.Name = checkNameLenght(param.Name) + + // 获取上传图,商品轮播图 + img, detailImg, err := GetTiktokImgList(api, utils.Int2Str(storeSku.StoreID), storeDetail.VendorOrgCode, storeSku.DescImg, storeSku.ImgOrigin, storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5) + if err != nil { + failedList = putils.GetErrMsg2FailedSingleList(storeSku, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) + return + } + param.Pic = img + param.Description = detailImg + + // 部分商品没有所属的分类,直接跳过! + if storeSku.SkuVendorMapCatID != "" { + param.CategoryLeafId = utils.Str2Int64(storeSku.SkuVendorMapCatID) + } else if len(param.Pic) != 0 { // 自动推导分类id + param.CategoryLeafId, err = api.GetRecommendCategory(strings.Split(img, "|")) + if param.CategoryLeafId == 0 || err != nil { + failedList = putils.GetErrMsg2FailedSingleList(storeSku, errors.New("当前商品本地未设置抖音分类/抖音推荐分类查询错误:"+err.Error()), storeID, model.VendorChineseNames[model.VendorIDDD], syncType) + return + } + } + // 这个情况是原有商品不存在和推荐查询不到类目id是,使用京西类目和抖音类目的绑定关系 + // 但是不太实用,导致商品类目错误被暂停营业等 + //if storeSku.VendorVendorCatID != 0 && param.CategoryLeafId == 0 { + // param.CategoryLeafId = storeSku.VendorVendorCatID + //} + + // 是否支持七天无理由 + if api.GetProductUpdateRule(param.CategoryLeafId) { + param.Supply7dayReturn = 1 + } else { + param.Supply7dayReturn = 0 + } + + // weight_unit 目前抖音只支持g和kg两种 + param.WeightUnit = tiktokShop.WeightUint_G + + // spec_prices + param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, 0, storeSku) + // 获取商品的属性 + if storeSku.TiktokAttribute != "" && storeSku.TiktokAttribute != "{}" { + param.ProductFormatNew = storeSku.TiktokAttribute + } else if storeSku.VendorSkuAttrId != "" && storeSku.VendorSkuAttrId != "{}" { + param.ProductFormatNew = storeSku.TiktokAttribute + } else { + param.ProductFormatNew, err = MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId) + if err != nil { + failedList = putils.GetErrMsg2FailedSingleList(storeSku, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) + return + } + } + param.StandardBrandId = 789194134 // 默认品牌京西菜市 596120136 + param.FreightId, param.SaleLimitId, err = getFreightIdAndSaleLimitId(api, db, storeDetail, vendorStoreID) + if err != nil { + failedList = putils.GetErrMsg2FailedSingleList(storeSku, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) + return + } + return +} + func loadMainProductId(api *tiktokShop.API, storeSku *dao.StoreSkuSyncInfo, mainProductId string) *product_detail_response.ProductDetailData { // 这有可能获取的值主商品也有可能是子商品,我们需要的是主商品id和状态 mainOrderDetailProductId, err := api.GetSkuDetail(mainProductId, "")