package tao_vegetable import ( "bytes" "fmt" "git.rosy.net.cn/baseapi/platformapi/mtwmapi" "git.rosy.net.cn/baseapi/platformapi/tao_vegetable" request1475 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability1475/request" domain585 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability585/domain" request585 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability585/request" "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability587/domain" "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability587/request" domain589 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability589/domain" request589 "git.rosy.net.cn/baseapi/platformapi/tao_vegetable/sdk/ability589/request" "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/model/dao" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/business/partner/putils" "git.rosy.net.cn/jx-callback/globals" "image/jpeg" "io/ioutil" "net/http" "regexp" "strings" "time" ) const ( updateTypeStock = iota updateTypeStatus updateTypePrice ) var ( sensitiveWordRegexp = regexp.MustCompile(`包含敏感词:(\[.*\])`) ) func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) { switch funcID { case partner.FuncUpdateStoreSkusStock, partner.FuncUpdateStoreSkusStatus, partner.FuncUpdateStoreSkusPrice: batchSize = 20 case partner.FuncDeleteStoreSkus: batchSize = 20 case partner.FuncCreateStoreSkus: batchSize = 20 // 可考虑用批量操作 case partner.FuncUpdateStoreSkus: batchSize = 20 // mtwmapi.MaxStoreSkuBatchSize case partner.FuncGetStoreSkusFullInfo: batchSize = 20 case partner.FuncCreateActs: batchSize = 20 case partner.FuncCancelActs: batchSize = 20 } return batchSize } func getStoreVendorOrgCode(storeID int) (vendorOrgCode string) { if storeMap, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDTaoVegetable, ""); storeMap != nil { return storeMap.VendorOrgCode } return vendorOrgCode } func getStoreVendorOrgCodeByVendorStoreID(vendorStoreID string) (vendorOrgCode string) { if storeMap, _ := dao.GetStoreDetailForDD(dao.GetDB(), 0, model.VendorIDTaoVegetable, vendorStoreID, ""); storeMap != nil { return storeMap.VendorOrgCode } return vendorOrgCode } // 门店分类 func (p *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) { remoteCats, err := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).GetStoreAllCategory() if err == nil { cats = convertVendorCatList(remoteCats) } return cats, err } func convertVendorCatList(remoteCats []*tao_vegetable.CategoryInfo) (cats []*partner.BareCategoryInfo) { for _, rCat := range remoteCats { cat := &partner.BareCategoryInfo{ VendorCatID: rCat.Code, Name: rCat.Name, Seq: rCat.Status, Children: convertVendorCatList(rCat.ChildCategorys), } if len(rCat.ChildCategorys) == 0 { cat.Level = 1 } else { cat.Level = 2 } if cat.VendorCatID == "" { cat.VendorCatID = rCat.Name } cats = append(cats, cat) } return cats } func (p *PurchaseHandler) IsErrCategoryExist(err error) (isExist bool) { return tao_vegetable.IsErrCategoryExist(err) } func (p *PurchaseHandler) IsErrCategoryNotExist(err error) (isNotExist bool) { return tao_vegetable.IsErrCategoryNotExist(err) } func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { api := getAPI(storeCat.VendorOrgCode, storeID, vendorStoreID) // 修改分类 if model.IsSyncStatusUpdate(storeCat.CatSyncStatus) { err := api.UpdateStoreCategoryInfo(&request.AlibabaWdkSkuCategoryUpdateRequest{Param: &domain.AlibabaWdkSkuCategoryUpdateCategoryDo{ Code: utils.String2Pointer(utils.Int2Str(storeCat.StoreCatID)), Name: &storeCat.StoreCatName, }}) if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 && p.IsErrCategoryNotExist(err) && storeCat.StoreCatName != "" { // 修改分类名,但分类不存在 storeCat.CatSyncStatus |= model.SyncFlagNewMask createCategory := &request.AlibabaWdkSkuCategoryAddRequest{Param: &domain.AlibabaWdkSkuCategoryAddCategoryDo{ Code: utils.String2Pointer(utils.Int2Str(storeCat.ID)), Name: &storeCat.Name, Leaf: utils.Bool2Point(false), }} if storeCat.ParentID != model.NO { createCategory.Param.ParentCode = utils.String2Pointer(utils.Int2Str(storeCat.ParentID)) createCategory.Param.Leaf = utils.Bool2Point(true) } skuCode, err := api.AddStoreCategoryInfo(createCategory) if err != nil { return err } storeCat.VendorCatID = skuCode } } // 创建分类 if model.IsSyncStatusNeedCreate(storeCat.CatSyncStatus) { createCategoryParam := &request.AlibabaWdkSkuCategoryAddRequest{Param: &domain.AlibabaWdkSkuCategoryAddCategoryDo{ Code: utils.String2Pointer(utils.Int2Str(storeCat.ID)), Name: &storeCat.Name, Leaf: utils.Bool2Point(false), }} if storeCat.ParentID != model.NO { createCategoryParam.Param.ParentCode = utils.String2Pointer(utils.Int2Str(storeCat.ParentID)) createCategoryParam.Param.Leaf = utils.Bool2Point(true) } skuCode, err := api.AddStoreCategoryInfo(createCategoryParam) globals.SugarLogger.Debugf("IsSyncStatusNeedCreate AddStoreCategoryInfo : skucode : %s ,%v", utils.Format4Output(skuCode, false), err) if err != nil { return err } storeCat.VendorCatID = skuCode } return err } func (p *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { return p.CreateStoreCategory(ctx, storeID, vendorStoreID, storeCat) } func (p *PurchaseHandler) DeleteStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, vendorCatID string, level int) (err error) { // 668594 正式服印象汇 668469 测试服芬姐(淘宝所有门店公用分类) , 模板门店才能删除 if storeID != 668594 && storeID != 668469 { return nil } api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID) // 只能删除叶子结点 // 看看这个level是不是代表子节点,感觉不是 category, err := api.GetStoreCategoryInfo(vendorCatID) if err != nil { return err } // 删除的是父节点,删除父节点下的所有子节点在删除父节点 if len(category.ChildCategorys) != 0 { for _, v := range category.ChildCategorys { err2 := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).DeleteStoreCategoryInfo(&request.AlibabaWdkSkuCategoryDeleteRequest{Param: &domain.AlibabaWdkSkuCategoryDeleteCategoryDo{Code: &v.Code}}) if err2 != nil && strings.Contains(err2.Error(), "类目已有子类目,不能被删除") { p.DeleteStoreCategory(ctx, storeID, vendorStoreID, v.Code, 0) } } } return getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).DeleteStoreCategoryInfo(&request.AlibabaWdkSkuCategoryDeleteRequest{Param: &domain.AlibabaWdkSkuCategoryDeleteCategoryDo{Code: &vendorCatID}}) } func (p *PurchaseHandler) IsErrSkuExist(err error) (isExist bool) { return false } func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) { return mtwmapi.IsErrSkuNotExist(err) } func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { failedList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, false) return failedList, err } func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { failedList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, true) return failedList, err } // 对于多门店平台来说,storeSkuList中只有SkuID与VendorSkuID有意义 func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo, isCreate bool) (failedList []*partner.StoreSkuInfoWithErr, err error) { var syncType string if isCreate { syncType = "创建商品" } else { syncType = "更新商品" } api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID) if isCreate { failedList, err = createTaoVegetable(ctx, api, storeSkuList, vendorStoreID, storeID, syncType) } else { failedList, err = UpdateTaoVegetable(api, storeSkuList, vendorStoreID, storeID, syncType) } return failedList, err } // UpdateTaoVegetable 修改淘鲜达商品 func UpdateTaoVegetable(api *tao_vegetable.API, storeSkuList []*dao.StoreSkuSyncInfo, vendorStoreID string, storeID int, syncType string) (failedList []*partner.StoreSkuInfoWithErr, err error) { param := &request585.AlibabaWdkSkuUpdateRequest{} updateSkuList := make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0) for _, v := range storeSkuList { price := utils.String2Pointer(utils.Float64ToStr(float64(v.VendorPrice) / float64(100))) updateSku := domain585.AlibabaWdkSkuUpdateSkuDo{ OuCode: utils.String2Pointer(vendorStoreID), SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)), SkuName: utils.String2Pointer(checkNameLength(v.SkuName, v.Weight, v.Unit)), SkuPrice: price, // 优先使用skuPrice 靠后SalePrice CategoryCode: utils.String2Pointer(utils.Int2Str(v.CategoryID)), MerchantCatCode: utils.String2Pointer(v.VendorCatID), // 优先使用 靠后 category_code CleanSkuMemberPrice: utils.Int64ToPointer(model.YES), SubTitle: utils.String2Pointer("小时达"), } if v.MinOrderCount <= model.YES { updateSku.PurchaseQuantity = utils.Int64ToPointer(model.YES) // 起购单位 } else { updateSku.PurchaseQuantity = utils.Int64ToPointer(int64(v.MinOrderCount)) // 起购单位 } // 修改暂时不修改图片,保持效率 updateSku.SkuPicUrls = uploadImg(api, v.SkuID, model.VendorIDTaoVegetable, []string{v.Img, v.Img2, v.Img3, v.Img4, v.Img5, v.DescImg}) if updateSku.SkuPicUrls == nil { continue } updateSkuList = append(updateSkuList, updateSku) } param.ParamList = &updateSkuList result, err := api.UpdateStoreSku(param) if err != nil { globals.SugarLogger.Debugf("UpdateStoreSku Tao Vegetable err : %s", err.Error()) } // 记录失败的同步数据 createFailedList, _ := SelectStoreSkuListByFoodList(storeSkuList, *result, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], syncType) failedList = append(failedList, createFailedList...) return failedList, err } // createTaoVegetable 创建淘鲜达商品 func createTaoVegetable(ctx *jxcontext.Context, api *tao_vegetable.API, storeSkuList []*dao.StoreSkuSyncInfo, vendorStoreID string, storeID int, syncType string) (failedList []*partner.StoreSkuInfoWithErr, err error) { createPram := &request585.AlibabaWdkSkuAddRequest{} param := make([]domain585.AlibabaWdkSkuAddSkuDo, 0, 0) vendorSkuIdMap := make(map[string]string, 0) for _, storeSku := range storeSkuList { price := utils.String2Pointer(utils.Float64ToStr(utils.Int64ToFloat64(storeSku.VendorPrice) / utils.Int64ToFloat64(100))) sku := domain585.AlibabaWdkSkuAddSkuDo{ Barcodes: utils.String2Pointer(utils.Int2Str(storeSku.SkuID)), BrandName: utils.String2Pointer(tao_vegetable.CreateSkuBrandName), OuCode: utils.String2Pointer(vendorStoreID), //InventoryUnit: utils.String2Pointer(storeSku.Unit), InventoryUnit: utils.String2Pointer("份"), ProducerPlace: utils.String2Pointer(tao_vegetable.CreateSkuProducerPlace), SkuCode: utils.String2Pointer(utils.Int2Str(storeSku.SkuID)), StorageType: utils.Int64ToPointer(tao_vegetable.CreateSkuStorageType), SuggestedPrice: price, Weight: utils.String2Pointer(utils.Int2Str(storeSku.Weight)), ShelfLife: utils.Int64ToPointer(tao_vegetable.CreateShelfLife), NetContent: utils.String2Pointer(utils.Int2Str(storeSku.Weight)), SaleUnit: utils.String2Pointer("份"), LifeStatus: utils.String2Pointer(tao_vegetable.CreateSkuLeafStatus), SaleSpec: utils.String2Pointer(fmt.Sprintf("%d %s*1%s", storeSku.Weight, "g", storeSku.Unit)), StepQuantity: utils.Int64ToPointer(model.YES), // 每次购买至少增加一个购买单位 OnlineSaleFlag: utils.Int64ToPointer(tao_vegetable.CreateOnlineSaleFlag), // 门店控制是否可见 SubTitle: utils.String2Pointer("小时达"), SubTitle1: utils.String2Pointer("一小时速达"), //DeliveryUnit: utils.String2Pointer(storeSku.Unit), DeliveryUnit: utils.String2Pointer("份"), DeliverySpec: utils.String2Pointer(utils.Int2Str(model.YES)), Storage: utils.String2Pointer(tao_vegetable.CreateStorage), PickFloatRate: utils.String2Pointer(utils.Int2Str(model.NO)), // ? 0 ForbidReceiveDays: utils.Int64ToPointer(tao_vegetable.CreateShelfLife), // ? 7 ForbidSalesDays: utils.Int64ToPointer(model.NO), // ? 0 OverloadRate: utils.String2Pointer(utils.Int2Str(model.NO)), // ? 0 WarnDays: utils.Int64ToPointer(model.NO), // ? 0 FixedFlag: utils.Int64ToPointer(model.NO), // ? 0 PurchaseSpec: utils.String2Pointer(utils.Int2Str(model.YES)), // ? 1 PurchaseUnit: utils.String2Pointer("份"), // ? 同上 LabelStyleType: utils.String2Pointer(tao_vegetable.CreateLabelStyleType), // 库存单位 ItemTypeNew: utils.Int64ToPointer(tao_vegetable.CreateItemTypeNewVegetable), SkuPrice: price, // 优先使用skuPrice 靠后SalePrice Period: utils.Int64ToPointer(tao_vegetable.CreateShelfLife), // 优先使用period 靠后shelf_life FragileFlag: utils.Int64ToPointer(model.YES), DeliveryStorage: utils.String2Pointer(tao_vegetable.CreateItemDeliveryStorage), TemporaryFlag: utils.Int64ToPointer(model.NO), IsOnline: utils.Int64ToPointer(tao_vegetable.CreateIsOnline), MerchantCatCode: utils.String2Pointer(storeSku.VendorCatID), // 优先使用 靠后 category_code RichText: utils.String2Pointer(storeSku.Name), AllowAppSale: utils.Int64ToPointer(tao_vegetable.IsAllowAppSale), } // 赠品专区 if storeSku.VendorCatID == "175" { sku.MerchantCatCode = utils.String2Pointer("1751") } sku.SkuPicUrls = uploadImg(api, storeSku.SkuID, model.VendorIDTaoVegetable, []string{storeSku.Img, storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5, storeSku.DescImg}) if sku.SkuPicUrls == nil { continue } sku.SkuName = utils.String2Pointer(checkNameLength(storeSku.Name, storeSku.Weight, storeSku.Unit)) if storeSku.MinOrderCount <= model.YES { sku.PurchaseQuantity = utils.Int64ToPointer(model.YES) // 起购单位 } else { sku.PurchaseQuantity = utils.Int64ToPointer(int64(storeSku.MinOrderCount)) // 起购单位 } sku.WeightFlag = utils.Int64ToPointer(tao_vegetable.CreateSkuWeightFlagNo) sku.AvgWeight = utils.String2Pointer("1") // (重量) sku.PreMinusWeight = utils.String2Pointer("1") // 每个购买单位重量,预扣重量 sku.SkuSuppliers = &[]domain585.AlibabaWdkSkuAddSkuSupplierDo{ domain585.AlibabaWdkSkuAddSkuSupplierDo{ ReturnFlag: utils.Int64ToPointer(model.NO), Minimum: utils.String2Pointer(utils.Int2Str(model.YES)), }, } sku.ChannelProps = &[]domain585.AlibabaWdkSkuAddChannelProp{ domain585.AlibabaWdkSkuAddChannelProp{ ChannelType: utils.String2Pointer(tao_vegetable.CreateChannelType), Props: &[]domain585.AlibabaWdkSkuAddPropField{ domain585.AlibabaWdkSkuAddPropField{ Value: utils.String2Pointer(utils.Int2Str(model.YES)), Key: utils.String2Pointer(tao_vegetable.CreateChannelTypeKey), }, }, }, } param = append(param, sku) } createPram.ParamList = ¶m result, err := api.AddStoreSku(createPram) if err != nil { globals.SugarLogger.Debugf("创建淘鲜达商品异常:%s", err.Error()) } //ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "2452A93EEB9111EC9B06525400E86DC0", fmt.Sprintf("定时创建商品[门店id:%d],出入商品个数[%d]", storeID, len(storeSkuList)), utils.Format4Output(result, false)) // 记录失败的同步数据 failedList2, vendorSkuIdMap2 := SelectStoreSkuListByFoodList(storeSkuList, *result, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], syncType) failedList = append(failedList, failedList2...) for k, v := range vendorSkuIdMap2 { vendorSkuIdMap[k] = v } var successSku = make([]int, 0, len(vendorSkuIdMap)) for _, v := range storeSkuList { if k, ok := vendorSkuIdMap[utils.Int2Str(v.SkuID)]; ok { v.VendorSkuID = k successSku = append(successSku, v.SkuID) } else { v.VendorSkuID = "0" v.SkuSyncStatus = 59 } } failedListStock := updateStoreSkusStockByCreate(ctx, api, storeID, vendorStoreID, successSku) failedList = append(failedList, failedListStock...) return failedList, nil } func checkNameLength(name string, weight int, uint string) string { lastName := "" if !strings.Contains(name, uint) { name = fmt.Sprintf("%s %d/%s", name, weight, uint) } if strings.Contains(name, "其它") { name = strings.ReplaceAll(name, "其它", "") } if strings.Contains(name, "其她") { name = strings.ReplaceAll(name, "其她", "") } if strings.Contains(name, "其他") { name = strings.ReplaceAll(name, "其他", "") } if len(name) <= tao_vegetable.NameMaxLength { return name } lastName = name if strings.Contains(name, "(") { startIndex := strings.Index(name, "(") endIndex := strings.Index(name, ")") lastName = name[0:startIndex] + name[endIndex+1:] if len(lastName) <= tao_vegetable.NameMaxLength { return lastName } } if strings.Contains(lastName, "(") { startIndex := strings.Index(lastName, "(") endIndex := strings.Index(lastName, ")") lastName = lastName[0:startIndex] + " " + lastName[endIndex+3:] if len(lastName) <= tao_vegetable.NameMaxLength { return lastName } } if strings.Contains(lastName, "[") { startIndex := strings.Index(lastName, "[") endIndex := strings.Index(lastName, "]") lastName = lastName[0:startIndex] + lastName[endIndex+1:] if len(lastName) <= tao_vegetable.NameMaxLength { return lastName } } if strings.Contains(lastName, "【") { startIndex := strings.Index(lastName, "【") endIndex := strings.Index(lastName, "】") lastName = lastName[0:startIndex] + " " + lastName[endIndex+3:] if len(lastName) <= tao_vegetable.NameMaxLength { return lastName } } return lastName[0:60] } // 图片压缩,大于3M func decodeImg(data []byte) []byte { if float64(len(data))/float64(1024)/float64(1024) > float64(3) { jpgimg, err := jpeg.Decode(strings.NewReader(string(data))) // 文件解码成图像对象 if err != nil { return nil } var buf bytes.Buffer err = jpeg.Encode(&buf, jpgimg, &jpeg.Options{Quality: 30}) if err != nil { return nil } return buf.Bytes() } return data } func uploadImg(api *tao_vegetable.API, skuId, vendorId int, imgs []string) *string { vendorImg, _ := dao.GetVendorImg(skuId, vendorId) result := make([]string, 0, 0) taoImgs := &model.TaoSkuImg{} isCreate := false if vendorImg == nil || (vendorImg.Img == "" && vendorImg.Img2 == "" && vendorImg.Img3 == "" && vendorImg.Img4 == "" && vendorImg.Img5 == "" && vendorImg.DescImg == "") { isCreate = true for i := 0; i < len(imgs); i++ { if imgs[i] == "" { continue } inputTitle := strings.LastIndex(imgs[i], "/") title := strings.LastIndex(imgs[i], ".") resp, err := http.Get(imgs[i]) if err != nil { continue } body, _ := ioutil.ReadAll(resp.Body) // 图片失效 if strings.Contains(string(body), "Document not found") || len(body) == 0 { continue } // 检查图片大小 body = decodeImg(body) newImg, _ := api.UploadImg(&request1475.AlibabaWdkPictureUploadRequest{ PictureCategoryId: utils.Int64ToPointer(0), Img: &body, ImgInputTitle: utils.String2Pointer(imgs[i][inputTitle:]), Title: utils.String2Pointer(imgs[i][inputTitle:title]), }) if newImg != "" { result = append(result, newImg) switch i { case 0: taoImgs.Img = newImg case 1: taoImgs.Img2 = newImg case 2: taoImgs.Img3 = newImg case 3: taoImgs.Img4 = newImg case 4: taoImgs.Img5 = newImg case 5: taoImgs.DescImg = newImg } } } } else { if vendorImg.Img != "" { result = append(result, vendorImg.Img) } if vendorImg.Img2 != "" { result = append(result, vendorImg.Img2) } if vendorImg.Img3 != "" { result = append(result, vendorImg.Img3) } if vendorImg.Img4 != "" { result = append(result, vendorImg.Img4) } if vendorImg.Img5 != "" { result = append(result, vendorImg.Img5) } if vendorImg.DescImg != "" { result = append(result, vendorImg.DescImg) } } if isCreate { taoImgs.SkuID = skuId taoImgs.VendorID = vendorId dao.CreateEntity(dao.GetDB(), taoImgs) } // 商品图片最多五张 if len(result) > 5 { return utils.String2Pointer(strings.Join(result[1:], ",")) } return utils.String2Pointer(strings.Join(result, ",")) } // DeleteStoreSkus 暂无删除API,使用下架接口 func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { param := &request585.AlibabaWdkSkuUpdateRequest{} updateSkuList := make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0) api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID) for _, v := range storeSkuList { updateSku := domain585.AlibabaWdkSkuUpdateSkuDo{ OuCode: utils.String2Pointer(vendorStoreID), SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)), OnlineSaleFlag: utils.Int64ToPointer(tao_vegetable.CreateOfflineSaleFlag), } updateSkuList = append(updateSkuList, updateSku) } param.ParamList = &updateSkuList result, err := api.UpdateStoreSku(param) if err != nil { globals.SugarLogger.Debugf("UpdateStoreSku Tao Vegetable err : %s", err.Error()) } // 记录失败的同步数据 createFailedList, _ := SelectStoreSkuListByFoodList(storeSkuList, *result, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], "删除商品(暂无接口,下架处理)") failedList = append(failedList, createFailedList...) return failedList, err } // UpdateStoreSkusStatus 批量更新商品上下架状态 func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) { param := &request585.AlibabaWdkSkuUpdateRequest{} updateSkuList := make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0) api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID) onlineStatus := skuStatusJX2Tao(status) for _, v := range storeSkuList { updateSku := domain585.AlibabaWdkSkuUpdateSkuDo{ OuCode: utils.String2Pointer(vendorStoreID), SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)), OnlineSaleFlag: utils.Int64ToPointer(onlineStatus), SubTitle: utils.String2Pointer("小时达"), AllowAppSale: utils.Int64ToPointer(onlineStatus), //CleanSkuMemberPrice: utils.Int64ToPointer(model.YES), } updateSkuList = append(updateSkuList, updateSku) } param.ParamList = &updateSkuList result, err := api.UpdateStoreSku(param) if err != nil { globals.SugarLogger.Debugf("UpdateStoreSku Tao Vegetable err : %s", err.Error()) } // 记录失败的同步数据 createFailedList, _ := SelectStoreSkuListByFoodList(storeSkuList, *result, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], "批量更新商品上下架") failedList = append(failedList, createFailedList...) return failedList, err } func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { param := &request585.AlibabaWdkSkuUpdateRequest{} updateSkuList := make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0) api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID) for _, v := range storeSkuList { price := utils.String2Pointer(fmt.Sprintf("%.2f", float64(v.VendorPrice)/float64(100))) updateSku := domain585.AlibabaWdkSkuUpdateSkuDo{ OuCode: utils.String2Pointer(vendorStoreID), SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)), SkuPrice: price, CleanSkuMemberPrice: utils.Int64ToPointer(model.YES), SubTitle: utils.String2Pointer("小时达"), } // 临时更新上传图片错误的,或图片上传失败的商品 updateSku.SkuPicUrls = uploadImg(api, v.SkuID, model.VendorIDTaoVegetable, nil) updateSkuList = append(updateSkuList, updateSku) } param.ParamList = &updateSkuList result, err := api.UpdateStoreSku(param) if err != nil { globals.SugarLogger.Debugf("UpdateStoreSku Tao Vegetable err : %s", err.Error()) } // 记录失败的同步数据 createFailedList, _ := SelectStoreSkuListByFoodList(storeSkuList, *result, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], "修改商品价格") failedList = append(failedList, createFailedList...) return failedList, err } // updateStoreSkusStockByCreate 创建时更新库存数量 func updateStoreSkusStockByCreate(ctx *jxcontext.Context, api *tao_vegetable.API, storeID int, vendorStoreID string, storeSkuList []int) (failedList []*partner.StoreSkuInfoWithErr) { param := request589.AlibabaWdkStockPublishRequest{} batchStockPublishDto := &domain589.AlibabaWdkStockPublishBatchStockPublishDto{ UpdateType: utils.Int64ToPointer(tao_vegetable.UpdateTypeStoke), BillNo: utils.String2Pointer(utils.Int64ToStr(time.Now().UnixNano())), BillType: utils.Int64ToPointer(tao_vegetable.UpdateTypeStokeBillType), PublishSource: utils.String2Pointer(vendorStoreID), ShopCode: utils.String2Pointer(vendorStoreID), Operator: utils.String2Pointer(ctx.GetUserName()), StockPublishDtos: nil, } stockPublishDtos := make([]domain589.AlibabaWdkStockPublishStockPublishDto, 0, 0) for _, v := range storeSkuList { stockPublishDtos = append(stockPublishDtos, domain589.AlibabaWdkStockPublishStockPublishDto{ SkuCode: utils.String2Pointer(utils.Int2Str(v)), Quantity: utils.String2Pointer("9999"), OrderNo: utils.String2Pointer(fmt.Sprintf("%s_%d_%d", vendorStoreID, time.Now().UnixNano(), 84671)), OrderType: utils.String2Pointer("10006800"), // 这个不太确定 }) //if (index+model.YES)%tao_vegetable.MAXHandleCount == model.NO || (index+1) == len(storeSkuList) { // batchStockPublishDto.StockPublishDtos = &stockPublishDtos // param.BatchStockPublishDto = batchStockPublishDto // if err := api.StoreSkuStock(¶m); err != nil { // failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], "更新库存错误")...) // } // stockPublishDtos = make([]domain589.AlibabaWdkStockPublishStockPublishDto, 0, 0) // param.BatchStockPublishDto = nil //} } batchStockPublishDto.StockPublishDtos = &stockPublishDtos param.BatchStockPublishDto = batchStockPublishDto if err := api.StoreSkuStock(¶m); err != nil { globals.SugarLogger.Debugf("Updat stock err := %s", err.Error()) //failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], "更新库存错误")...) } return failedList } // UpdateStoreSkusStock 操作更新库存数量 func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID) param := request589.AlibabaWdkStockPublishRequest{} batchStockPublishDto := &domain589.AlibabaWdkStockPublishBatchStockPublishDto{ UpdateType: utils.Int64ToPointer(tao_vegetable.UpdateTypeStoke), BillNo: utils.String2Pointer(utils.Int64ToStr(time.Now().UnixNano())), BillType: utils.Int64ToPointer(tao_vegetable.UpdateTypeStokeBillType), PublishSource: utils.String2Pointer(vendorStoreID), ShopCode: utils.String2Pointer(vendorStoreID), Operator: utils.String2Pointer(ctx.GetUserName()), StockPublishDtos: nil, } stockPublishDtos := make([]domain589.AlibabaWdkStockPublishStockPublishDto, 0, 0) for _, v := range storeSkuList { stockPublishDtos = append(stockPublishDtos, domain589.AlibabaWdkStockPublishStockPublishDto{ SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)), Quantity: utils.String2Pointer(utils.Int2Str(v.Stock)), OrderNo: utils.String2Pointer(fmt.Sprintf("%s_%d_%d", vendorStoreID, time.Now().UnixNano(), 84671)), OrderType: utils.String2Pointer("10006800"), // 这个不太确定 }) //if (index+model.YES)%tao_vegetable.MAXHandleCount == model.NO || (index+1) == len(storeSkuList) { // batchStockPublishDto.StockPublishDtos = &stockPublishDtos // param.BatchStockPublishDto = batchStockPublishDto // if err = api.StoreSkuStock(¶m); err != nil { // failedList = append(failedList, putils.GetErrMsg2FailedSingleList(v, err, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], "更新库存错误")...) // } // stockPublishDtos = make([]domain589.AlibabaWdkStockPublishStockPublishDto, 0, 0) // param.BatchStockPublishDto = nil //} } batchStockPublishDto.StockPublishDtos = &stockPublishDtos param.BatchStockPublishDto = batchStockPublishDto if err = api.StoreSkuStock(¶m); err != nil { failedList = append(failedList, putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], "更新库存错误")...) } return failedList, err } func taoSkuStatus2Jx(taoSkuStatus int) (jxSkuStatus int) { if taoSkuStatus == tao_vegetable.CreateIsOnline { jxSkuStatus = model.SkuStatusNormal } else { jxSkuStatus = model.SkuStatusDontSale } return jxSkuStatus } // GetStoreSkusFullInfo 获取淘鲜达平台商品,由于参数商品id必填作为参数,storeSkuList不能为空,且skuCode最大长度为20 func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (skuNameList []*partner.SkuNameInfo, err error) { if len(storeSkuList) == model.NO { return nil, fmt.Errorf("淘鲜达获取门店商品需要参数商品id") } var storeSkuMap map[string]*partner.StoreSkuInfo api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID) if storeSkuList != nil { storeSkuMap = putils.StoreSkuList2MapByVendorSkuID(storeSkuList) } skuCodeList := make([]string, 0, len(storeSkuList)) for _, v := range storeSkuList { skuCodeList = append(skuCodeList, utils.Int2Str(v.SkuID)) } forCount := len(storeSkuList) / tao_vegetable.MAXHandleCount maxIndex := len(storeSkuList) % tao_vegetable.MAXHandleCount if maxIndex != model.NO { forCount += model.YES } for i := 1; i <= forCount; i++ { // todo 待优化获取速度 data := &request585.AlibabaWdkSkuQueryRequest{ Param: &domain585.AlibabaWdkSkuQuerySkuQueryDo{ OuCode: &vendorStoreID, }, } if forCount == i { data.Param.SetSkuCodes(skuCodeList[(i-1)*tao_vegetable.MAXHandleCount : len(skuCodeList)]) } else { data.Param.SetSkuCodes(skuCodeList[(i-1)*tao_vegetable.MAXHandleCount : i*tao_vegetable.MAXHandleCount]) } result, err := api.QueryStoreSKu(data) if err != nil { return nil, err } if storeSkuMap == nil { skuNameList = append(skuNameList, vendorSkuList2Jx(result)...) } else { for _, v := range *result { if storeSkuMap[*v.Model.SkuCode] != nil { if skuName := vendorSku2Jx(v.Model); skuName != nil { skuNameList = append(skuNameList, skuName) } } } } } return skuNameList, err } // vendorSku2Jx 淘鲜达商品解析到京西 func vendorSku2Jx(appFood *domain585.AlibabaWdkSkuQuerySkuDo) (skuName *partner.SkuNameInfo) { if &appFood == nil { return nil } prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(*appFood.SkuName) weight := int(utils.Str2Int64WithDefault(*appFood.Weight, 0)) if weight <= 0 { weight = jxutils.FormatSkuWeight(specQuality, specUnit) } skuID := int(utils.Str2Int64WithDefault(*appFood.SkuCode, 0)) skuName = &partner.SkuNameInfo{ NameID: int(utils.Str2Int64WithDefault(*appFood.SkuCode, 0)), VendorNameID: *appFood.ProducerName, UPC: *appFood.Barcodes, Prefix: prefix, Name: name, Unit: unit, Status: taoSkuStatus2Jx(int(*appFood.OnlineSaleFlag)), SkuList: []*partner.SkuInfo{ &partner.SkuInfo{ StoreSkuInfo: partner.StoreSkuInfo{ VendorSkuID: utils.Int2Str(skuID), SkuID: skuID, IsSpecialty: 0, // 是否为力荐商品(淘宝没返回) Stock: partner.UnlimitedStoreSkuStock, // 淘宝没返回 VendorPrice: jxutils.StandardPrice2Int(utils.Str2Float64WithDefault(*appFood.SalePrice, 0) * (utils.Str2Float64WithDefault(*appFood.Weight, 0) / float64(1000))), Status: taoSkuStatus2Jx(int(*appFood.OnlineSaleFlag)), }, SkuName: *appFood.SkuName, Comment: comment, SpecQuality: float64(specQuality), SpecUnit: specUnit, Weight: weight, }, }, PictureList: utils.Interface2StringList(*appFood.SkuPicUrls), } if appFood.CategoryCode != nil { skuName.VendorCatIDList = []string{} } return skuName } func vendorSkuList2Jx(appFoodList *[]domain585.AlibabaWdkSkuQueryApiResult) (skuNameList []*partner.SkuNameInfo) { for _, appFood := range *appFoodList { if skuName := vendorSku2Jx(appFood.Model); skuName != nil { skuNameList = append(skuNameList, skuName) } } return skuNameList } func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp { return sensitiveWordRegexp } // SelectStoreSkuListByFoodList 淘宝批量返回 func SelectStoreSkuListByFoodList(storeSkuList interface{}, foodList []tao_vegetable.VegetableResultList, storeID int, vendorName, syncType string) (selectedStoreSkuList []*partner.StoreSkuInfoWithErr, successMap map[string]string) { foodMap := make(map[string]string, len(foodList)) successMap = make(map[string]string) if len(foodList) > 0 { for _, v := range foodList { if v.ProductID != "" { successMap[v.SkuID] = v.ProductID } else { foodMap[v.SkuID] = v.ErrMsg } } if storeSkuLists, ok := storeSkuList.([]*partner.StoreSkuInfo); ok { for _, v := range storeSkuLists { if foodMap[utils.Int2Str(v.SkuID)] != "" { foodFailed := &partner.StoreSkuInfoWithErr{ StoreSkuInfo: v, ErrMsg: foodMap[utils.Int2Str(v.SkuID)], StoreID: storeID, VendoreName: vendorName, SyncType: syncType, } selectedStoreSkuList = append(selectedStoreSkuList, foodFailed) } } } if storeSkuLists, ok := storeSkuList.([]*dao.StoreSkuSyncInfo); ok { for _, v := range storeSkuLists { if foodMap[utils.Int2Str(v.SkuID)] != "" { storeSkuInfo := &partner.StoreSkuInfo{ SkuID: v.SkuID, VendorSkuID: v.VendorSkuID, NameID: v.NameID, VendorNameID: v.VendorNameID, VendorPrice: v.VendorPrice, Status: v.Status, } foodFailed := &partner.StoreSkuInfoWithErr{ StoreSkuInfo: storeSkuInfo, ErrMsg: foodMap[utils.Int2Str(v.SkuID)], StoreID: storeID, VendoreName: vendorName, SyncType: syncType, } selectedStoreSkuList = append(selectedStoreSkuList, foodFailed) } } } } return selectedStoreSkuList, successMap } func (p *PurchaseHandler) CreateStoreSkusAct(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { actStoreSkuList := putils.StoreSku2ActStoreSku(model.SyncFlagNewMask, vendorStoreID, storeSkuList) failedList, err = createOneShopAct(putils.GetFixDirectDownAct(vendorOrgCode, storeID, 0), vendorStoreID, actStoreSkuList) storeSkuMap := putils.StoreSkuList2MapBySkuID(storeSkuList) for _, v := range actStoreSkuList { storeSkuMap[v.SkuID].VendorActID = v.VendorActID } if len(failedList) > 0 { err = nil } return failedList, err } func (p *PurchaseHandler) CancelActs(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { return cancelOneShopAct(putils.GetFixDirectDownAct(vendorOrgCode, storeID, 0), vendorStoreID, putils.StoreSku2ActStoreSku(model.SyncFlagDeletedMask, vendorStoreID, storeSkuList)) } // UpdateStoreSkusSpecTag 更新限购 func (p *PurchaseHandler) UpdateStoreSkusSpecTag(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (err error) { var errList = make([]string, 0, 0) param := &request585.AlibabaWdkSkuUpdateRequest{} updateSkuList := make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0) api := getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID) for _, v := range storeSkuList { updateSku := domain585.AlibabaWdkSkuUpdateSkuDo{ OuCode: utils.String2Pointer(vendorStoreID), SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)), } if v.IsSpecialty <= model.YES { updateSku.PurchaseQuantity = utils.Int64ToPointer(model.YES) } else { updateSku.PurchaseQuantity = utils.Int64ToPointer(int64(v.IsSpecialty)) } updateSkuList = append(updateSkuList, updateSku) } param.ParamList = &updateSkuList result, err := api.UpdateStoreSku(param) if err != nil { globals.SugarLogger.Debugf("UpdateStoreSku Tao Vegetable err : %s", err.Error()) } // 记录失败的同步数据 for _, v := range *result { if v.ErrMsg != "" { errList = append(errList, v.ErrMsg) } } return fmt.Errorf("%s", strings.Join(errList, ",")) } func (p *PurchaseHandler) GetSkuCategoryIdByName(vendorOrgCode, skuName string) (vendorCategoryId string, err error) { return "", err }