diff --git a/business/bidding/logistics_Loading.go b/business/bidding/logistics_Loading.go index 69c65832e..d1b435dd1 100644 --- a/business/bidding/logistics_Loading.go +++ b/business/bidding/logistics_Loading.go @@ -1,12 +1,19 @@ package bidding import ( + "encoding/json" + "fmt" "git.rosy.net.cn/baseapi/platformapi/ali_logistics_query" + "git.rosy.net.cn/baseapi/platformapi/dingdingapi" + "git.rosy.net.cn/baseapi/platformapi/tonglianpayapi" + "git.rosy.net.cn/baseapi/platformapi/weixinapi" "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" "time" ) @@ -37,6 +44,22 @@ func LoadingLogistics(paramLogistic []*model.UpdateMaterialLogistic) []error { errList = append(errList, err) continue } + + payList, _ := dao.GetOrderPayList(db, goodsOrder.VendorOrderID, goodsOrder.VendorID) + for _, pl := range payList { + if pl.OriginalData != "" { + originalData := &tonglianpayapi.CallBackResult{} + json.Unmarshal([]byte(pl.OriginalData), originalData) + if err = api.WeixinMiniAPI.SNSDeliveryGoodsOrder(&weixinapi.DeliveryOrder{ + TransactionId: originalData.ChnlTrxID, + ReceivedTime: time.Now().Unix(), + }); err != nil { + ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "2452A93EEB9111EC9B06525400E86DC0", "微信物料送达推送", fmt.Sprintf("物料商城下单,送达错误:%s,请注意查看,err:%s", goodsOrder.VendorOrderID, err.Error())) + } + + } + } + } } diff --git a/business/jxstore/cms/system_store_sku.go b/business/jxstore/cms/system_store_sku.go index edbf149e6..40cc2c7d4 100644 --- a/business/jxstore/cms/system_store_sku.go +++ b/business/jxstore/cms/system_store_sku.go @@ -571,29 +571,29 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS if copyMap[storeSku.AppFoodCode] == nil || copyMap[storeSku.AppFoodCode].MainSkuId == "" { param := &product_addV2_request.ProductAddV2Param{ Name: utils.LimitUTF8StringLen(storeSku.Name, 90), - PayType: tiktok_api.TiktokPayType1, + PayType: utils.Int64ToPointer(tiktok_api.TiktokPayType1), ReduceType: tiktok_api.SkuReduceTypePayMakeOrder, - DeliveryDelayDay: tiktok_api.DeliveryDelayDayToDay, - PresellType: tiktok_api.SendGoodsTypeNow, - Supply7dayReturn: 0, // 是否支持7天无理由,0不支持,1支持,2支持(拆封后不支持) + DeliveryDelayDay: utils.Int64ToPointer(tiktok_api.DeliveryDelayDayToDay), + PresellType: utils.Int64ToPointer(tiktok_api.SendGoodsTypeNow), + Supply7dayReturn: utils.Int64ToPointer(0), // 是否支持7天无理由,0不支持,1支持,2支持(拆封后不支持) Mobile: toStoreDetail.Tel1, Commit: true, //Specs: "重量|" + utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit, - NeedRechargeMode: false, + NeedRechargeMode: nil, SellChannel: []int64{0}, - StartSaleType: 0, - PickupMethod: "0", - OuterProductId: storeSku.AppFoodCode, // 本地skuId为外部商品id + StartSaleType: utils.Int64ToPointer(0), + PickupMethod: utils.String2Pointer("0"), + OuterProductId: utils.String2Pointer(storeSku.AppFoodCode), // 本地skuId为外部商品id } specs := "重量|" specsList := make([]string, 0, 0) upc := "" for _, sl := range storeSku.SkuList { specsList = append(specsList, strings.Split(sl.Spec, "*")[0]) - param.Weight = utils.Str2Float64(sl.Weight) + param.Weight = utils.Float64ToPointer(utils.Str2Float64(sl.Weight)) upc = sl.Upc } - param.Specs = specs + strings.Join(specsList, ",") + param.Specs = utils.String2Pointer(specs + strings.Join(specsList, ",")) // 获取上传图,商品轮播图 imgs := make([]tiktok_api.Imgs, 0, 0) for spk, spl := range storeSku.PictureList { @@ -631,7 +631,7 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS continue } if strings.Contains(til, "white_") { - param.WhiteBackGroundPicUrl = v.ByteUrl + param.WhiteBackGroundPicUrl = utils.String2Pointer(v.ByteUrl) } picList = append(picList, v.ByteUrl) } @@ -641,7 +641,7 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS if len(param.Pic) != 0 { var vendorCategoryId int64 = 0 // 根据图片推导分类 - picList = append(picList, param.WhiteBackGroundPicUrl, param.Description) + picList = append(picList, *param.WhiteBackGroundPicUrl, param.Description) vendorCategoryId, _ = toApi.GetRecommendCategory(picList) // 根据名字推导分类 if vendorCategoryId == 0 { @@ -660,16 +660,16 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS // 是否支持七天无理由 isAfterSale, rule := toApi.GetProductUpdateRule(param.CategoryLeafId) if isAfterSale { - param.AfterSaleService = map[string]string{"supply_day_return_selector": fmt.Sprintf("%s", rule)} + param.AfterSaleService = &map[string]string{"supply_day_return_selector": fmt.Sprintf("%s", rule)} } // weight_unit 目前抖音只支持g和kg两种 - param.WeightUnit = tiktok_api.WeightUint_G + param.WeightUnit = utils.Int64ToPointer(tiktok_api.WeightUint_G) // spec_prices //param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, 0, storeSku) skuSize := make([]*tiktok_api.SpecDetailList, 0, 0) - name1 := strings.Split(strings.Split(param.Specs, "|")[1], ",") + name1 := strings.Split(strings.Split(*param.Specs, "|")[1], ",") for _, sl := range storeSku.SkuList { for i := 0; i < len(name1); i++ { if name1[i] == strings.Split(sl.Spec, "*")[0] { @@ -693,16 +693,16 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS } } data, _ := json.Marshal(skuSize) - param.SpecPrices = string(data) + param.SpecPrices = utils.String2Pointer(string(data)) // 获取商品的属性 //param.ProductFormatNew, param.StandardBrandId, err = MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId) if upc == "" { - param.StandardBrandId = 596120136 + param.StandardBrandId = utils.Int64ToPointer(596120136) } else { brandName, err := tiktok_store.GetBrandByBrandName(upc) if err != nil { - param.StandardBrandId = 596120136 + param.StandardBrandId = utils.Int64ToPointer(596120136) } else { if strings.Contains(brandName, "/") || strings.Contains(brandName, "(") || strings.Contains(brandName, "(") { brandName = strings.Split(brandName, "/")[0] @@ -715,14 +715,14 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS } standardBrandId, err := toApi.GetSkuBrand(param.CategoryLeafId, brandName) if err != nil { - param.StandardBrandId = 596120136 + param.StandardBrandId = utils.Int64ToPointer(596120136) } else { - param.StandardBrandId = standardBrandId + param.StandardBrandId = &standardBrandId } } } - if param.StandardBrandId == 0 { - param.StandardBrandId = 596120136 + if param.StandardBrandId == utils.Int64ToPointer(0) { + param.StandardBrandId = utils.Int64ToPointer(596120136) } categoryList, err := toApi.GetCatePropertyV2(param.CategoryLeafId) if err != nil { @@ -753,11 +753,11 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS } } - param.ProductFormatNew = utils.Format4Output(categoryMap, false) + param.ProductFormatNew = utils.String2Pointer(utils.Format4Output(categoryMap, false)) //param.ProductFormatNew, err = MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId) if StoreTemp[toStoreDetail.VendorStoreID] != "" { idList := strings.Split(StoreTemp[toStoreDetail.VendorStoreID], "_") - param.FreightId, param.SaleLimitId = utils.Str2Int64(idList[0]), utils.Str2Int64(idList[1]) + param.FreightId, param.SaleLimitId = utils.Str2Int64(idList[0]), utils.Int64ToPointer(utils.Str2Int64(idList[1])) } else { // 运费模板 param.FreightId, err = tiktok_store.GetDeliveryTemp(toApi, toStoreDetail.VendorStoreID, toStoreDetail) @@ -769,7 +769,7 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS return errList, nil } // 获取门店限售模板 - param.SaleLimitId, err = tiktok_store.CreateSaleTemp(utils.Str2Int64(toStoreDetail.VendorStoreID), toApi) + saleLimitId, err := tiktok_store.CreateSaleTemp(utils.Str2Int64(toStoreDetail.VendorStoreID), toApi) if err != nil { errList = append(errList, &mtwmapi.AppFoodResult{ AppFoodCode: storeSku.AppFoodCode, @@ -777,6 +777,7 @@ func BatchInitSkuMT2TT(ctx *jxcontext.Context, fromSku []*mtwmapi.AppFood, fromS }) return errList, nil } + param.SaleLimitId = &saleLimitId StoreTemp[toStoreDetail.VendorStoreID] = fmt.Sprintf("%d_%d", param.FreightId, param.SaleLimitId) } diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index c9e06ebe3..beaecbee2 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -2109,7 +2109,7 @@ type StoreOrderRank struct { func GetOrderStatusList(vendorOrderId string, orderType, vendorId int) (orderStatus []*model.OrderStatus, err error) { sql := ` SELECT * FROM order_status WHERE ref_vendor_order_id = ? AND vendor_id = ? AND order_type = ? ORDER BY status_time asc ` param := []interface{}{vendorOrderId, vendorId, orderType} - if err = GetRows(GetDB(), &orderStatus, sql, param); err != nil { + if err = GetRows(GetDB(), &orderStatus, sql, param...); err != nil { return nil, err } return orderStatus, nil diff --git a/business/partner/printer/feie/feie.go b/business/partner/printer/feie/feie.go index 92f38c9ba..c3eb4d284 100644 --- a/business/partner/printer/feie/feie.go +++ b/business/partner/printer/feie/feie.go @@ -285,8 +285,7 @@ func (c *PrinterHandler) getOrderContentBigMiddle(order *model.GoodsOrder, store ` } - orderFmt += `%s
-` + getCode + + orderFmt += getCode + `客户: %s
电话: %s
地址: %s
@@ -304,7 +303,7 @@ func (c *PrinterHandler) getOrderContentBigMiddle(order *model.GoodsOrder, store utils.Time2Str(order.OrderCreatedAt), utils.Time2Str(expectedDeliveryTime), order.VendorOrderID, - order.VendorOrderID, + //order.VendorOrderID, order.ConsigneeName, order.ConsigneeMobile, order.ConsigneeAddress, diff --git a/business/partner/purchase/jx/localjx/tonglianpay.go b/business/partner/purchase/jx/localjx/tonglianpay.go index a2a50143e..af8881238 100644 --- a/business/partner/purchase/jx/localjx/tonglianpay.go +++ b/business/partner/purchase/jx/localjx/tonglianpay.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "git.rosy.net.cn/baseapi/platformapi/dingdingapi" + "git.rosy.net.cn/baseapi/platformapi/weixinapi" "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" "git.rosy.net.cn/jx-callback/business/partner" "strings" @@ -156,6 +157,42 @@ func onTLpayFinished(call *tonglianpayapi.CallBackResult) (err error) { } //weixinmsg.SendUserMessage(jxcontext.AdminCtx, "商户购买物料信息推送", fmt.Sprintf("门店%s:%d,在物料商城下单了:%s,请注意查看", store.Name, store.ID, order.VendorOrderID), userID, true, true) } + authList, _ := dao.GetUserBindAuthInfo(db, order.UserID, 0, nil, "", "", []string{api.WeixinMiniAppID2}) + if authList != nil && len(authList) != 0 { + param := &weixinapi.SNSSendOrderParameter{ + OrderKey: struct { + OrderNumberType int `json:"order_number_type"` + TransactionId string `json:"transaction_id"` + Mchid string `json:"mchid"` + OutTradeNo string `json:"out_trade_no"` + }{ + OrderNumberType: 2, + TransactionId: call.ChnlTrxID, + }, + LogisticsType: 1, + DeliveryMode: 1, + IsAllDelivered: false, + ShippingList: append([]weixinapi.ShippingList{}, weixinapi.ShippingList{ + TrackingNo: order.VendorOrderID, + ExpressCompany: "YD", + ItemDesc: "背心袋", + Contact: struct { + ConsignorContact string `json:"consignor_contact"` + ReceiverContact string `json:"receiver_contact"` + }{}, + }), + UploadTime: time.Now().Format(time.RFC3339), + Payer: struct { + Openid string `json:"openid"` + }{ + Openid: authList[0].AuthID, + }, + } + if err = api.WeixinMiniAPI.SNSSendGoodsOrder(param); err != nil { + ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "2452A93EEB9111EC9B06525400E86DC0", "物料发货推送", fmt.Sprintf("物料商城下单,发货错误:%s,请注意查看,err:%s", order.VendorOrderID, err.Error())) + } + } + } } } else { diff --git a/business/partner/purchase/tiktok_store/dy.go b/business/partner/purchase/tiktok_store/dy.go index 17f2c05f6..d75e46009 100644 --- a/business/partner/purchase/tiktok_store/dy.go +++ b/business/partner/purchase/tiktok_store/dy.go @@ -44,7 +44,7 @@ func (c *PurchaseHandler) GetVendorID() int { } func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) { - cats, err := getAPI("68023619", 0, "").GetShopCategory(0) + cats, err := getAPI("260477060", 0, "").GetShopCategory(0) if err != nil { return nil, err } diff --git a/business/partner/purchase/tiktok_store/store_sku2_utils.go b/business/partner/purchase/tiktok_store/store_sku2_utils.go index 2e08e8404..4701dbcbf 100644 --- a/business/partner/purchase/tiktok_store/store_sku2_utils.go +++ b/business/partner/purchase/tiktok_store/store_sku2_utils.go @@ -142,13 +142,7 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI } // 根据本地商品id获取线上商品是否存在,存在则只创建子商品 // 获取本地存储映射关系,获取本地主商品id是否存在 - //var mainProductId int64 = 0 - //var mainOrderDetail *product_detail_response.ProductDetailData localThing, _ := dao.GetThingToTiktokMapList(db, model.VendorIDDD, int64(storeSku.SkuID), storeDetail.VendorOrgCode) - //if len(localThing) != 0 && localThing[0].VendorThingID != "" { - // mainProductId = utils.Str2Int64(localThing[0].VendorThingID) - //} - if len(localThing) == 0 { param, failedList2 := makeMainProductSku(db, api, storeSku, storeDetail, storeID, vendorStoreID, syncType) if len(failedList2) != 0 { @@ -179,7 +173,6 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI } tiktokResult.Sku = specPrices } else { - //storeSku.SkuSyncStatus = model.SyncFlagNewMask // 只创建主品,子品都没做 storeSku.SkuSyncStatus = 2 // 后续不在做定时任务更新 storeSku.VendorSonSkuID = "此商品已经创建抖音主商品了" failedList = putils.GetErrMsg2FailedSingleList(storeSku, errCreate, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) @@ -207,7 +200,6 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI attrId = append(attrId, utils.Int64ToStr(v.SkuId)) } - //mainProductId = tiktokResult.ProductId storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID) storeSku.SkuSyncStatus = model.SyncFlagNewMask // 只创建主品,子品都没做 storeSku.VendorMainId = utils.Int64ToStr(tiktokResult.ProductId) @@ -240,12 +232,9 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI for _, v := range tiktokResult.Sku { attrId = append(attrId, utils.Int64ToStr(v.SkuId)) } - //mainProductId = tiktokResult.ProductId - //storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID) storeSku.SkuSyncStatus = model.SyncFlagNewMask // 只创建主品,子品都没做 storeSku.VendorMainId = utils.Int64ToStr(tiktokResult.ProductId) 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) case model.ThingTypeSyncing: if time.Now().Unix()-localThing[0].CreatedAt.Unix() > 300 { @@ -349,21 +338,21 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI // 更新主商品,在同步到子门店,考虑审核时间 param := &product_editV2_request.ProductEditV2Param{ - Name: utils.LimitUTF8StringLen(storeSku.SkuName, 90), - PayType: tiktokShop.TiktokPayType1, - ReduceType: tiktokShop.SkuReduceTypePayMakeOrder, - Weight: utils.Int2Float64(storeSku.Weight), - DeliveryDelayDay: tiktokShop.DeliveryDelayDayToDay, - PresellType: tiktokShop.SendGoodsTypeNow, - Mobile: storeDetail.Tel1, + Name: utils.String2Pointer(utils.LimitUTF8StringLen(storeSku.SkuName, 90)), + PayType: utils.Int64ToPointer(tiktokShop.TiktokPayType1), + ReduceType: utils.Int64ToPointer(tiktokShop.SkuReduceTypePayMakeOrder), + Weight: utils.Float64ToPointer(utils.Int2Float64(storeSku.Weight)), + DeliveryDelayDay: utils.Int64ToPointer(tiktokShop.DeliveryDelayDayToDay), + PresellType: utils.Int64ToPointer(tiktokShop.SendGoodsTypeNow), + Mobile: utils.String2Pointer(storeDetail.Tel1), Commit: true, - Specs: "重量|" + utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit, - NeedRechargeMode: false, + Specs: utils.String2Pointer("总净重|" + utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit), + NeedRechargeMode: nil, SellChannel: []int64{0}, - StartSaleType: 0, - PickupMethod: "0", + StartSaleType: utils.Int64ToPointer(0), + PickupMethod: utils.String2Pointer("0"), } - param.Name = checkNameLenght(param.Name) + param.Name = utils.String2Pointer(checkNameLength(*param.Name)) // 暂时只考虑修改白底图,提高效率.其余图片不做修改 img, descImg, whiteImg, err := GetTiktokImgList(api, utils.Int2Str(storeSku.StoreID), storeSku.SkuID, storeSku.DescImg, storeSku.Img, []string{storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5}) @@ -371,31 +360,40 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) continue } - param.Pic = img - param.Description = descImg - param.WhiteBackGroundPicUrl = whiteImg - param.WeightUnit = tiktokShop.WeightUint_G + param.Pic = utils.String2Pointer(img) + param.Description = utils.String2Pointer(descImg) + param.WhiteBackGroundPicUrl = utils.String2Pointer(whiteImg) + param.WeightUnit = utils.Int64ToPointer(tiktokShop.WeightUint_G) // 部分商品没有所属的分类,直接跳过! - if storeSku.SkuVendorMapCatID != "" { - param.CategoryLeafId = utils.Str2Int64(storeSku.SkuVendorMapCatID) - } else if len(param.Pic) != 0 { // 自动推导分类id - var vendorCategoryId int64 = 0 - // 根据图片推导分类 - vendorCategoryId, _ = api.GetRecommendCategory(strings.Split(img, "|")) - if vendorCategoryId == 0 { - vendorCategoryId, _ = api.GetRecommendCategoryByName(storeSku.SkuName) + // 老的类目长度小于十 + var vendorCategoryId int64 = 0 + var isUpdate bool = false + if storeSku.SkuVendorMapCatID == "" { + if vendorCategoryId, _ = api.GetRecommendCategory(strings.Split(img, "|")); vendorCategoryId == 0 { // 根据图片推导分类 + vendorCategoryId, _ = api.GetRecommendCategoryByName(storeSku.SkuName) // 根据名字推导分类 } - if vendorCategoryId == 0 || err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSku, errors.New("当前商品本地未设置抖音分类/抖音推荐分类查询错误:"+err.Error()), storeID, model.VendorChineseNames[model.VendorIDDD], syncType) + isUpdate = true + } else if len(storeSku.SkuVendorMapCatID) < 10 { + // 用老的分类ID换取新的分类ID + newCategoryMap, err := api.BatchGetChannelCategoryMapping([]int64{utils.Str2Int64(storeSku.SkuVendorMapCatID)}) + if err != nil { + failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) continue } - param.CategoryLeafId = vendorCategoryId + vendorCategoryId = newCategoryMap[storeSku.VendorVendorCatID] + isUpdate = true + } else { + vendorCategoryId = utils.Str2Int64(storeSku.SkuVendorMapCatID) } + if isUpdate { + dao.ExecuteSQL(db, `UPDATE sku_vendor_category_map SET vendor_category_id = ? WHERE name_id = ? AND vendor_id = ? `, []interface{}{utils.Int64ToStr(vendorCategoryId), storeSku.NameID, model.VendorIDDD}) + } + param.CategoryLeafId = utils.Int64ToPointer(vendorCategoryId) - isAfterSale, rule := api.GetProductUpdateRule(param.CategoryLeafId) + isAfterSale, rule := api.GetProductUpdateRule(*param.CategoryLeafId) if isAfterSale { - param.AfterSaleService = map[string]string{"supply_day_return_selector": fmt.Sprintf("%s", rule)} + param.AfterSaleService = &map[string]string{"supply_day_return_selector": fmt.Sprintf("%s", rule)} } // 获取主商品id var mainIdInt int64 @@ -426,37 +424,39 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI //} // 获取商品的属性 - if storeSku.TiktokAttribute == "" || storeSku.TiktokAttribute == "{}" || storeSku.UpcTiktokBrandId == "" { - param.ProductFormatNew, param.StandardBrandId, err = MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId) + if storeSku.TiktokAttribute != "" && storeSku.TiktokAttribute != "{}" && storeSku.UpcTiktokBrandId != "" { + param.ProductFormatNew = utils.String2Pointer(storeSku.TiktokAttribute) + } else { + productFormatNew, standardBrandId, err := MakeProductFormatNew(api, int64(storeSku.NameID), *param.CategoryLeafId, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId) if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) + failedList = putils.GetErrMsg2FailedSingleList(storeSku, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) continue } - } else { - param.ProductFormatNew = storeSku.TiktokAttribute + param.ProductFormatNew = utils.String2Pointer(productFormatNew) + param.StandardBrandId = utils.Int64ToPointer(standardBrandId) } + // 获取品牌 - if param.StandardBrandId == 0 { - param.StandardBrandId, _ = getTiktokBrandId(api, db, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId, param.CategoryLeafId) - } - if param.StandardBrandId == 0 { - param.StandardBrandId = 596120136 // 无品牌 + if param.StandardBrandId == utils.Int64ToPointer(model.NO) { + standardBrandId, _ := getTiktokBrandId(api, db, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId, *param.CategoryLeafId) + if standardBrandId != 0 { + param.StandardBrandId = utils.Int64ToPointer(standardBrandId) + } else { + param.StandardBrandId = utils.Int64ToPointer(596120136) + } } // 修改商品 param.ProductId = mainIdInt - //param.MainProductId = mainIdInt - //param.FreightId, _ = api.GetStoreBindTemp(utils.Str2Int64(vendorStoreID)) - param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, mainIdInt, storeSku) + param.SpecPrices = utils.String2Pointer(GetSpecPrices(*param.Specs, vendorStoreID, mainIdInt, storeSku)) err = api.EditStoreCommodity(param) if err != nil && !strings.Contains(err.Error(), "您上传的商品主图存在重复") { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) //storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID) - } /* else { - // todo 暂时关闭之后解开 + } else { skuId, _ := upDateChildrenPriceStockLaunch(api, storeSku, utils.Str2Int64(storeSku.VendorSkuID), vendorStoreID, syncType) storeSku.VendorSonSkuID = utils.Int64ToStr(skuId) // 品库修改 售卖状态待同步 价格待同步 - }*/ + } //storeSku.SkuSyncStatus = model.SyncFlagStoreSkuModifiedMask // 品库修改 售卖状态待同步 价格待同步 storeSku.SkuSyncStatus = 0 // 品库修改 售卖状态待同步 价格待同步 } @@ -468,21 +468,22 @@ func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeI 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, + PayType: utils.Int64ToPointer(tiktokShop.TiktokPayType1), ReduceType: tiktokShop.SkuReduceTypePayMakeOrder, - Weight: utils.Int2Float64(storeSku.Weight), - DeliveryDelayDay: tiktokShop.DeliveryDelayDayToDay, - PresellType: tiktokShop.SendGoodsTypeNow, + Weight: utils.Float64ToPointer(utils.Int2Float64(storeSku.Weight)), + DeliveryDelayDay: utils.Int64ToPointer(tiktokShop.DeliveryDelayDayToDay), + PresellType: utils.Int64ToPointer(tiktokShop.SendGoodsTypeNow), Mobile: storeDetail.Tel1, Commit: true, - Specs: "重量|" + utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit, - NeedRechargeMode: false, + Specs: utils.String2Pointer("总净重|" + utils.Float64ToStr(float64(storeSku.SpecQuality)) + storeSku.SpecUnit), + NeedRechargeMode: nil, SellChannel: []int64{0}, - StartSaleType: 0, - PickupMethod: "0", - OuterProductId: utils.Int2Str(storeSku.SkuID), // 本地skuId为外部商品id + StartSaleType: utils.Int64ToPointer(0), + PickupMethod: utils.String2Pointer("0"), + OuterProductId: utils.String2Pointer(utils.Int2Str(storeSku.SkuID)), // 本地skuId为外部商品id + ProductType: 0, } - param.Name = checkNameLenght(param.Name) + param.Name = checkNameLength(param.Name) // 获取上传图,商品轮播图 img, detailImg, whiteImg, err := GetTiktokImgList(api, utils.Int2Str(storeSku.StoreID), storeSku.SkuID, storeSku.DescImg, storeSku.Img, []string{storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5}) @@ -492,23 +493,32 @@ func makeMainProductSku(db *dao.DaoDB, api *tiktokShop.API, storeSku *dao.StoreS } param.Pic = img param.Description = detailImg - param.WhiteBackGroundPicUrl = whiteImg + param.WhiteBackGroundPicUrl = utils.String2Pointer(whiteImg) - // 部分商品没有所属的分类,直接跳过! - if storeSku.SkuVendorMapCatID != "" { - param.CategoryLeafId = utils.Str2Int64(storeSku.SkuVendorMapCatID) - } else if len(param.Pic) != 0 { // 自动推导分类id - var vendorCategoryId int64 = 0 - vendorCategoryId, _ = api.GetRecommendCategory(strings.Split(img, "|")) // 根据图片推导分类 - if vendorCategoryId == 0 { + // 老的类目长度小于十 + var vendorCategoryId int64 = 0 + var isUpdate bool = false + if storeSku.SkuVendorMapCatID == "" { + if vendorCategoryId, _ = api.GetRecommendCategory(strings.Split(img, "|")); vendorCategoryId == 0 { // 根据图片推导分类 vendorCategoryId, _ = api.GetRecommendCategoryByName(storeSku.SkuName) // 根据名字推导分类 } - if vendorCategoryId == 0 || err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSku, errors.New("当前商品本地未设置抖音分类/抖音推荐分类查询错误"), storeID, model.VendorChineseNames[model.VendorIDDD], syncType) - return + isUpdate = true + } else if len(storeSku.SkuVendorMapCatID) < 10 { + // 用老的分类ID换取新的分类ID + newCategoryMap, err := api.BatchGetChannelCategoryMapping([]int64{utils.Str2Int64(storeSku.SkuVendorMapCatID)}) + if err != nil { + return nil, putils.GetErrMsg2FailedSingleList(storeSku, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) } - param.CategoryLeafId = vendorCategoryId + vendorCategoryId = newCategoryMap[storeSku.VendorVendorCatID] + isUpdate = true + } else { + vendorCategoryId = utils.Str2Int64(storeSku.SkuVendorMapCatID) } + if isUpdate { + dao.ExecuteSQL(db, `UPDATE sku_vendor_category_map SET vendor_category_id = ? WHERE name_id = ? AND vendor_id = ? `, []interface{}{utils.Int64ToStr(vendorCategoryId), storeSku.NameID, model.VendorIDDD}) + } + param.CategoryLeafId = vendorCategoryId + // 这个情况是原有商品不存在和推荐查询不到类目id是,使用京西类目和抖音类目的绑定关系 // 但是不太实用,导致商品类目错误被暂停营业等 //if storeSku.VendorVendorCatID != 0 && param.CategoryLeafId == 0 { @@ -517,37 +527,43 @@ func makeMainProductSku(db *dao.DaoDB, api *tiktokShop.API, storeSku *dao.StoreS isAfterSale, rule := api.GetProductUpdateRule(param.CategoryLeafId) if isAfterSale { - param.AfterSaleService = map[string]string{"supply_day_return_selector": fmt.Sprintf("%s", rule)} + param.AfterSaleService = &map[string]string{"supply_day_return_selector": fmt.Sprintf("%s", rule)} } // weight_unit 目前抖音只支持g和kg两种 - param.WeightUnit = tiktokShop.WeightUint_G + param.WeightUnit = utils.Int64ToPointer(tiktokShop.WeightUint_G) // spec_prices - param.SpecPrices = GetSpecPrices(param.Specs, vendorStoreID, 0, storeSku) + param.SpecPrices = utils.String2Pointer(GetSpecPrices(*param.Specs, vendorStoreID, 0, storeSku)) // 获取商品的属性 if storeSku.TiktokAttribute != "" && storeSku.TiktokAttribute != "{}" && storeSku.UpcTiktokBrandId != "" { - param.ProductFormatNew = storeSku.TiktokAttribute + param.ProductFormatNew = utils.String2Pointer(storeSku.TiktokAttribute) } else { - param.ProductFormatNew, param.StandardBrandId, err = MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId) - //param.ProductFormatNew, err = MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId) + productFormatNew, standardBrandId, err := MakeProductFormatNew(api, int64(storeSku.NameID), param.CategoryLeafId, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId) if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSku, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) return } + param.ProductFormatNew = utils.String2Pointer(productFormatNew) + param.StandardBrandId = utils.Int64ToPointer(standardBrandId) } - if param.StandardBrandId == 0 { - param.StandardBrandId, _ = getTiktokBrandId(api, db, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId, param.CategoryLeafId) + if param.StandardBrandId == utils.Int64ToPointer(model.NO) { + standardBrandId, _ := getTiktokBrandId(api, db, storeSku.Upc, storeSku.UpcBrandName, storeSku.UpcTiktokBrandId, param.CategoryLeafId) + if standardBrandId != 0 { + param.StandardBrandId = utils.Int64ToPointer(standardBrandId) + } else { + param.StandardBrandId = utils.Int64ToPointer(596120136) + } } - if param.StandardBrandId == 0 { - param.StandardBrandId = 596120136 - } - param.FreightId, param.SaleLimitId, err = getFreightIdAndSaleLimitId(api, db, storeDetail, vendorStoreID) + + freightId, saleLimitId, err := getFreightIdAndSaleLimitId(api, db, storeDetail, vendorStoreID) if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSku, err, storeID, model.VendorChineseNames[model.VendorIDDD], syncType) return } + param.FreightId = freightId + param.SaleLimitId = utils.Int64ToPointer(saleLimitId) return } @@ -632,7 +648,7 @@ func loadMainProductId(api *tiktokShop.API, storeSku *dao.StoreSkuSyncInfo, main return mainOrderDetailProductId } -func checkNameLenght(name string) string { +func checkNameLength(name string) string { var chinesLen int // 中文 var punctZh int // 中文标点 var punctEn int // 英文标点 @@ -952,6 +968,47 @@ func GetProductFormatNew(categoryLeftId int64, vendorOrgCode string) (*product_g //return string(productFormatNew), nil } +type VendorCategoryId struct { + VendorCategoryID string `orm:"column(vendor_category_id)" json:"vendorCategoryID"` +} + +func BatchGetChannelCategoryMapping() error { + var db = dao.GetDB() + sql := ` SELECT vendor_category_id FROM sku_vendor_category_map WHERE vendor_id = 14 GROUP BY vendor_category_id` + data := make([]*VendorCategoryId, 0, 0) + if err := dao.GetRows(db, &data, sql, nil); err != nil { + return err + } + + count := len(data) / 50 + if len(data)%50 != 0 { + count = count + 1 + } + + categoryList := make([]int64, 0, len(data)) + for _, v := range data { + if len(v.VendorCategoryID) < 10 { + categoryList = append(categoryList, utils.Str2Int64(v.VendorCategoryID)) + } + } + api := getAPI("260477060", 0, "") + for i := 1; i <= count; i++ { + cats := make(map[int64]int64, 50) + if i == count { + cats, _ = api.BatchGetChannelCategoryMapping(categoryList[(i-1)*50:]) + } else { + cats, _ = api.BatchGetChannelCategoryMapping(categoryList[(i-1)*50 : i*50]) + } + + for k, c := range cats { + sql2 := ` UPDATE sku_vendor_category_map SET vendor_category_id = ? WHERE vendor_category_id = ?` + param := []interface{}{utils.Int64ToStr(c), utils.Int64ToStr(k)} + dao.ExecuteSQL(db, sql2, param...) + } + } + return nil +} + // GetTiktokImgList 获取抖音图片链接 whiteImg 白底图,有的商品可能没有白底图随便用一张(创建商品专用,更新商品只考虑更新白底图,不然太慢了) func GetTiktokImgList(api *tiktokShop.API, storeId string, skuId int, detailImg, whiteImg string, img []string) (string, string, string, error) { detailTiktok := "" @@ -1051,49 +1108,6 @@ func GetTiktokImgList(api *tiktokShop.API, storeId string, skuId int, detailImg, return strings.Join(tiktokImg, "|"), detailTiktok, whiteTiktok, nil } -// GetWhiteImg 更新专用暂时只考虑更新白底图 -//func GetWhiteImg(api *tiktokShop.API, skuId int, storeId, whiteImg string) (string, error) { -// //每个图片都上传太慢了 -// tiktokImgLocal, err := dao.GetVendorImg(skuId, model.VendorIDDD) -// if err == nil && tiktokImgLocal != nil && tiktokImgLocal.Img != "" { -// return tiktokImgLocal.Img, nil -// } -// -// imgs := make([]tiktokShop.Imgs, 0, 0) -// if whiteImg == "" { -// return "", fmt.Errorf("商品白底图不能为空") -// } -// -// imgs = append(imgs, tiktokShop.Imgs{ -// Name: "white_" + storeId + "_" + whiteImg[21:54], -// Url: whiteImg, -// }) -// -// tiktokImgList, err := api.BatchUploadImages(imgs) -// if err != nil { -// return "", err -// } -// if len(tiktokImgList) == model.NO { -// return "", fmt.Errorf("白底图片上传失败") -// } -// -// whiteTiktok := "" -// var tiktokImg []string -// for k, v := range tiktokImgList { -// if strings.Contains(k, "white_") { -// whiteTiktok = v.ByteUrl -// continue -// } -// tiktokImg = append(tiktokImg, v.ByteUrl) -// } -// -// if whiteTiktok == "" { -// whiteTiktok = tiktokImg[0] -// } -// -// return whiteTiktok, nil -//} - func MakeProductFormatNew(api *tiktokShop.API, skuNameId int64, categoryLeafId int64, upcCode, upcBrandName, upcTiktokBrandId string) (string, int64, error) { db := dao.GetDB() categoryList, err := api.GetCatePropertyV2(categoryLeafId) diff --git a/controllers/cms_sku.go b/controllers/cms_sku.go index 3d9d5c683..c5229c8ef 100644 --- a/controllers/cms_sku.go +++ b/controllers/cms_sku.go @@ -847,6 +847,19 @@ func (c *SkuController) GetTiktokCategoryValue() { }) } +// @Title 更新最新的分类树 +// @Description 更新最新的分类树 +// @Param token header string true "认证token" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /BatchGetChannelCategoryMapping [get] +func (c *SkuController) BatchGetChannelCategoryMapping() { + c.callGetTiktokCategoryValue(func(params *tSkuGetTiktokCategoryValueParams) (interface{}, string, error) { + err := tiktok_store.BatchGetChannelCategoryMapping() + return nil, "", err + }) +} + // @Title 根据美团分类id获取平台扩展规则 // @Description 根据美团分类id获取平台扩展规则 // @Param token header string true "认证token" diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index a4ef5fba8..241543922 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -2112,6 +2112,16 @@ func init() { Filters: nil, Params: nil}) + // 更新最新的抖音分类树 + web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"] = append(web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"], + web.ControllerComments{ + Method: "BatchGetChannelCategoryMapping", + Router: `/BatchGetChannelCategoryMapping`, + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"] = append(web.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:SkuController"], web.ControllerComments{ Method: "GetMTCategoryAttrList",