package tao_vegetable import ( "fmt" "io/ioutil" "net/http" "regexp" "strings" "time" "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" ) 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 = mtwmapi.MaxStoreSkuBatchSize case partner.FuncDeleteStoreSkus: batchSize = mtwmapi.MaxBatchDeleteSize case partner.FuncCreateStoreSkus: batchSize = 1 // 可考虑用批量操作 case partner.FuncUpdateStoreSkus: batchSize = 1 // mtwmapi.MaxStoreSkuBatchSize case partner.FuncGetStoreSkusFullInfo: batchSize = 1 case partner.FuncCreateActs: batchSize = mtwmapi.MaxRetailDiscountCreateBatchSize case partner.FuncCancelActs: batchSize = mtwmapi.MaxRetailDiscountDeleteBatchSize } 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) globals.SugarLogger.Debugf("CreateStoreCategory===== := %s%s%d", vendorStoreID, storeCat.VendorOrgCode, storeID) // 修改分类 if model.IsSyncStatusUpdate(storeCat.CatSyncStatus) { err := api.UpdateStoreCategoryInfo(&request.AlibabaWdkSkuCategoryUpdateRequest{Param: &domain.AlibabaWdkSkuCategoryUpdateCategoryDo{ Code: utils.String2Pointer(utils.Int2Str(storeCat.StoreCatID)), Name: &storeCat.StoreCatName, }}) globals.SugarLogger.Debugf("CreateStoreCategory=====err := %v", err) 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.StoreCatID)), Name: &storeCat.StoreCatName, Leaf: utils.Bool2Point(false), }} if storeCat.ParentID != model.NO { createCategory.Param.ParentCode = utils.String2Pointer(storeCat.ParentVendorCatID) createCategory.Param.Leaf = utils.Bool2Point(true) } skuCode, err := api.AddStoreCategoryInfo(createCategory) globals.SugarLogger.Debugf("AddStoreCategoryInfo=====err := %v", err) 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.StoreCatID)), Name: &storeCat.StoreCatName, Leaf: utils.Bool2Point(false), }} if storeCat.ParentID != model.NO { createCategoryParam.Param.ParentCode = utils.String2Pointer(storeCat.ParentVendorCatID) 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) { 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) globals.SugarLogger.Debugf("UpdateStoreSkus=====err := %v", err) globals.SugarLogger.Debugf("UpdateStoreSkus=====err := %v", failedList) 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) globals.SugarLogger.Debugf("CreateStoreSkus=====err := %v", err) globals.SugarLogger.Debugf("CreateStoreSkus=====err := %v", failedList) 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(api, storeSkuList, vendorStoreID, storeID, syncType) globals.SugarLogger.Debugf("创建淘鲜达商品异常:%v", err) } else { failedList, err = UpdateTaoVegetable(api, storeSkuList, vendorStoreID, storeID, syncType) globals.SugarLogger.Debugf("更新淘鲜达商品异常:%v", err) } globals.SugarLogger.Debugf("createOrUpdateStoreSkus=====err := %v", err) globals.SugarLogger.Debugf("createOrUpdateStoreSkus=====err := %v", failedList) 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) totalCount := len(storeSkuList) for index, v := range storeSkuList { updateSku := domain585.AlibabaWdkSkuUpdateSkuDo{ OuCode: utils.String2Pointer(vendorStoreID), SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)), SkuName: utils.String2Pointer(v.SkuName), MemberPrice: utils.String2Pointer(utils.Float64ToStr(float64(v.UnitPrice) / float64(100))), SkuPrice: utils.String2Pointer(utils.Float64ToStr(float64(v.UnitPrice) / float64(100))), // 优先使用skuPrice 靠后SalePrice CategoryCode: utils.String2Pointer(utils.Int2Str(v.CategoryID)), MerchantCatCode: utils.String2Pointer(v.VendorCatID), // 优先使用 靠后 category_code } if v.MinOrderCount <= model.YES { updateSku.PurchaseQuantity = utils.Int64ToPointer(model.YES) // 起购单位 } else { updateSku.PurchaseQuantity = utils.Int64ToPointer(int64(v.MinOrderCount)) // 起购单位 } updateSku.SkuPicUrls = uploadImg(api, []string{v.ImgOrigin, v.Img, v.Img2, v.Img3, v.Img4, v.Img5, v.DescImg}) updateSkuList = append(updateSkuList, updateSku) if (index+model.YES)%tao_vegetable.MAXHandleCount == model.NO || index+model.YES == totalCount { 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...) // 记录同步成功的数据 param.ParamList = nil updateSkuList = make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0) } } globals.SugarLogger.Debugf("UpdateTaoVegetable=====err := %v", err) globals.SugarLogger.Debugf("UpdateTaoVegetable=====err := %v", failedList) return failedList, err } // createTaoVegetable 创建淘鲜达商品 func createTaoVegetable(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) totalCount := len(storeSkuList) vendorSkuIdMap := make(map[string]string, 0) for index, storeSku := range storeSkuList { 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)), SkuName: utils.String2Pointer(storeSku.SkuName), StorageType: utils.Int64ToPointer(tao_vegetable.CreateSkuStorageType), SuggestedPrice: utils.String2Pointer(utils.Float64ToStr(utils.Int64ToFloat64(storeSku.UnitPrice) / utils.Int64ToFloat64(100))), Weight: utils.String2Pointer(utils.Float32ToStr(storeSku.SpecQuality)), ShelfLife: utils.Int64ToPointer(tao_vegetable.CreateShelfLife), NetContent: utils.String2Pointer(utils.Float32ToStr(storeSku.SpecQuality)), SaleUnit: utils.String2Pointer("份"), LifeStatus: utils.String2Pointer(tao_vegetable.CreateSkuLeafStatus), SaleSpec: utils.String2Pointer(fmt.Sprintf("%.2f*1%s", storeSku.SpecQuality, storeSku.Unit)), StepQuantity: utils.Int64ToPointer(model.YES), // 每次购买至少增加一个购买单位 SubTitle: utils.String2Pointer("同城包邮"), SubTitle1: utils.String2Pointer("一小时速达"), OnlineSaleFlag: utils.Int64ToPointer(tao_vegetable.CreateOnlineSaleFlag), // 门店控制是否可见 //DeliveryUnit: utils.String2Pointer(storeSku.Unit), DeliveryUnit: utils.String2Pointer("份"), DeliverySpec: utils.String2Pointer(utils.Int2Str(model.YES)), MemberPrice: utils.String2Pointer(utils.Float64ToStr(float64(storeSku.UnitPrice) / float64(100))), 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(storeSku.Unit), // ? 同上 PurchaseUnit: utils.String2Pointer("份"), // ? 同上 LabelStyleType: utils.String2Pointer(tao_vegetable.CreateLabelStyleType), // 库存单位 ItemTypeNew: utils.Int64ToPointer(tao_vegetable.CreateItemTypeNewVegetable), SkuPrice: utils.String2Pointer(utils.Float64ToStr(float64(storeSku.UnitPrice) / float64(100))), // 优先使用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 } sku.SkuPicUrls = uploadImg(api, []string{storeSku.ImgOrigin, storeSku.Img, storeSku.Img2, storeSku.Img3, storeSku.Img4, storeSku.Img5, storeSku.DescImg}) 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") // 每个购买单位重量,预扣重量 //if storeSku.Upc == "" { // //sku.WeightFlag = utils.Int64ToPointer(tao_vegetable.CreateSkuWeightFlagYes) // if storeSku.SpecUnit == "g" || storeSku.SpecUnit == "ml" || storeSku.SpecUnit == "G" || storeSku.SpecUnit == "ML" { // sku.PreMinusWeight = utils.String2Pointer(utils.Float64ToStr(float64(storeSku.SpecQuality) / float64(1000))) // 一个售卖单位按多少库存单位扣款(钱) // //sku.AvgWeight = utils.String2Pointer(utils.Float64ToStr(float64(storeSku.SpecQuality) / float64(1000))) // (重量) // } // if storeSku.SpecUnit == "kg" || storeSku.SpecUnit == "l" || storeSku.SpecUnit == "KG" || storeSku.SpecUnit == "L" { // sku.PreMinusWeight = utils.String2Pointer(utils.Float64ToStr(float64(storeSku.SpecQuality))) // 每个购买单位重量,预扣重量 // //sku.AvgWeight = utils.String2Pointer(utils.Float64ToStr(float64(storeSku.SpecQuality) / float64(1000))) // (重量) // } //} else { // //sku.WeightFlag = utils.Int64ToPointer(tao_vegetable.CreateSkuWeightFlagNo) // 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) if (index+model.YES)%tao_vegetable.MAXHandleCount == model.NO || index+model.YES == totalCount { createPram.ParamList = ¶m result, err := api.AddStoreSku(createPram) globals.SugarLogger.Debugf("创建淘鲜达商品异常 result :%s", utils.Format4Output(result, false)) if err != nil { globals.SugarLogger.Debugf("创建淘鲜达商品异常:%s", err.Error()) } // 记录失败的同步数据 failedList, vendorSkuIdMap = SelectStoreSkuListByFoodList(storeSkuList, *result, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], syncType) createPram.ParamList = nil param = make([]domain585.AlibabaWdkSkuAddSkuDo, 0, 0) } } globals.SugarLogger.Debugf("vendorSkuIdMap=====err := %v", utils.Format4Output(vendorSkuIdMap, false)) for _, v := range storeSkuList { if k, ok := vendorSkuIdMap[utils.Int2Str(v.SkuID)]; ok { v.VendorSkuID = k } } globals.SugarLogger.Debugf("storeSkuList=====err := %s", utils.Format4Output(storeSkuList, false)) globals.SugarLogger.Debugf("createTaoVegetable=====err := %v", err) globals.SugarLogger.Debugf("createTaoVegetable=====err := %v", failedList) return failedList, nil } func uploadImg(api *tao_vegetable.API, imgs []string) *string { result := make([]string, 0, 0) for _, v := range imgs { if v == "" { continue } inputTitle := strings.LastIndex(v, "/") title := strings.LastIndex(v, ".") resp, err := http.Get(v) if err != nil { continue } body, _ := ioutil.ReadAll(resp.Body) if newImg, _ := api.UploadImg(&request1475.AlibabaWdkPictureUploadRequest{ PictureCategoryId: utils.Int64ToPointer(0), Img: &body, ImgInputTitle: utils.String2Pointer(v[inputTitle:]), Title: utils.String2Pointer(v[inputTitle:title]), }); newImg != "" { result = append(result, newImg) } } 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 index, 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) if (index+model.YES)%tao_vegetable.MAXHandleCount == model.NO || (index+1) == len(storeSkuList) { 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...) param.ParamList = nil updateSkuList = make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0) } } globals.SugarLogger.Debugf("DeleteStoreSkus=====err := %v", err) globals.SugarLogger.Debugf("DeleteStoreSkus=====err := %v", failedList) return failedList, err //param := &request.AlibabaAxChannelSkuStatusUpdateRequest{ChannelSkuUpdateStatusReq: &domain.AlibabaAxChannelSkuStatusUpdateChannelSkuUpdateStatusReq{ // StoreId: utils.String2Pointer(vendorStoreID), // ChannelCode: utils.String2Pointer(tao_vegetable.TaoVegetableChannelCode), // OnlineSaleFlag: utils.Int64ToPointer(tao_vegetable.CreateIsOnline), //}} //var updateOffShelf = make([]tao_vegetable.VegetableResultList, 0, len(storeSkuList)) //for _, v := range storeSkuList { // param.ChannelSkuUpdateStatusReq.SkuCode = utils.String2Pointer(utils.Int2Str(v.SkuID)) // // StoreSkuUpdateOffShelf 这个接口暂时有问题使用更新接口上下架 // if err = getAPI(getStoreVendorOrgCode(storeID), storeID, vendorStoreID).StoreSkuUpdateOffShelf(param); err != nil { // updateOffShelf = append(updateOffShelf, tao_vegetable.VegetableResultList{ // ProductID: v.VendorSkuID, // SkuID: utils.Int2Str(v.SkuID), // ErrMsg: err.Error(), // }) // } //} //failedList, _ = SelectStoreSkuListByFoodList(storeSkuList, updateOffShelf, storeID, model.VendorChineseNames[model.VendorIDTaoVegetable], "批量删除商品(暂时下架,无删除接口)") //if len(failedList) > 0 { // err = nil //} //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 index, v := range storeSkuList { updateSku := domain585.AlibabaWdkSkuUpdateSkuDo{ OuCode: utils.String2Pointer(vendorStoreID), SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)), OnlineSaleFlag: utils.Int64ToPointer(onlineStatus), } updateSkuList = append(updateSkuList, updateSku) if (index+model.YES)%tao_vegetable.MAXHandleCount == model.NO || (index+1) == len(storeSkuList) { 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...) param.ParamList = nil updateSkuList = make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0) } } globals.SugarLogger.Debugf("UpdateStoreSkusStatus=====err := %v", err) globals.SugarLogger.Debugf("UpdateStoreSkusStatus=====err := %v", failedList) 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 index, v := range storeSkuList { updateSku := domain585.AlibabaWdkSkuUpdateSkuDo{ OuCode: utils.String2Pointer(vendorStoreID), SkuCode: utils.String2Pointer(utils.Int2Str(v.SkuID)), SkuPrice: utils.String2Pointer(fmt.Sprintf("%.2f", (float64(1000)/float64(v.SpecQuality))*(float64(v.JxUnitPrice)/float64(100)))), CleanSkuMemberPrice: utils.Int64ToPointer(model.YES), SuggestedPrice: utils.String2Pointer(fmt.Sprintf("%.2f", (float64(1000)/float64(v.SpecQuality))*(float64(v.JxUnitPrice)/float64(100)))), } updateSkuList = append(updateSkuList, updateSku) if (index+model.YES)%tao_vegetable.MAXHandleCount == model.NO || (index+1) == len(storeSkuList) { 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...) param.ParamList = nil updateSkuList = make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0) } } globals.SugarLogger.Debugf("UpdateStoreSkusPrice=====err := %v", err) globals.SugarLogger.Debugf("UpdateStoreSkusPrice=====err := %v", failedList) return failedList, err } 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 index, 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 } } globals.SugarLogger.Debugf("UpdateStoreSkusStock=====err := %v", err) globals.SugarLogger.Debugf("UpdateStoreSkusStock=====err := %v", failedList) 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 { foodMap[v.SkuID] = v.ErrMsg if v.ProductID != "" { successMap[v.SkuID] = v.ProductID } } if storeSkuLists, ok := storeSkuList.([]*partner.StoreSkuInfo); ok { for _, v := range storeSkuLists { if foodMap[v.VendorSkuID] != "" { foodFailed := &partner.StoreSkuInfoWithErr{ StoreSkuInfo: v, ErrMsg: foodMap[v.VendorSkuID], StoreID: storeID, VendoreName: vendorName, SyncType: syncType, } selectedStoreSkuList = append(selectedStoreSkuList, foodFailed) } } } if storeSkuLists, ok := storeSkuList.([]*dao.StoreSkuSyncInfo); ok { for _, v := range storeSkuLists { if foodMap[v.VendorSkuID] != "" { 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[v.VendorSkuID], 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 index, 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) if (index+model.YES)%tao_vegetable.MAXHandleCount == model.NO || (index+1) == len(storeSkuList) { 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) } } param.ParamList = nil updateSkuList = make([]domain585.AlibabaWdkSkuUpdateSkuDo, 0, 0) } } return fmt.Errorf("%s", strings.Join(errList, ",")) } func (p *PurchaseHandler) GetSkuCategoryIdByName(vendorOrgCode, skuName string) (vendorCategoryId string, err error) { return "", err }