package jdshop import ( "fmt" "math" "regexp" "strings" "time" "git.rosy.net.cn/baseapi/platformapi/jdshopapi" "git.rosy.net.cn/jx-callback/globals/api" "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 ( deleteErr1 = "已经删除的不能直接下架" deleteErr2 = "SKU" deleteErr3 = "已删除" ) var ( sensitiveWordRegexp = regexp.MustCompile(`商品名称中含有敏感词(\[.*\])`) ) func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { if globals.EnableJdShopWrite { if vendorStoreID == model.JdShopMainVendorStoreID { for _, v := range storeSkuList { //判断京东商城上是否有这个商品了,如果有就是添加规格而不是创建商品 //如果是京东商城2,是下架的商品,弄上架 ,先改为有下架的不管,重新建 name := filterSensitiveWord(v.Name) flag := false //flag2 := false //var wareStatusUpdateWareID string result, err := getAPI(v.VendorOrgCode).SearchWare4Valid(name, 1, 100) // 搜索有效商品 if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") return failedList, err } for _, v := range result.Data { if v.Title == name { flag = true //下架 if v.WareStatus == 2 || v.WareStatus == 1028 { flag = false //wareStatusUpdateWareID = utils.Int64ToStr(v.WareID) } break } } //if flag2 { // err = getAPI(v.VendorOrgCode).WareDoUpdate("op", wareStatusUpdateWareID) //} //result.TotalItem > 0 && len(result.Data) > 0 && if flag { //jds2 wareSaveParam := &jdshopapi.WareSaveParam{ WareID: result.Data[0].WareID, Title: v.Name, CategoryID: int(v.VendorVendorCatID), VenderID: jdshopapi.VendorID2, Length: 200, Wide: 100, Height: 100, Weight: "1", BrandID: jdshopapi.BrandIdNO, ShopCategorys: []int{utils.Str2Int(v.VendorCatID)}, PromiseID: -1, MultiCateProps: []interface{}{}, PropsSet: []interface{}{}, SaleAttrs: []interface{}{}, WareStatus: 8, } var wareSaveSkus []*jdshopapi.WareSaveSkus //先把已有的规格放进去 // if v.VendorOrgCode == "2" { wareResult, _ := getAPI(v.VendorOrgCode).FindWareById(wareSaveParam.WareID) // 获取单个商品详情 if wareResult != nil { for _, v := range wareResult.Images { wareSaveParam.ImageMap.Num0000000000 = append(wareSaveParam.ImageMap.Num0000000000, &jdshopapi.CreateSkuParamImages{ ColorID: v.ColorID, ImgURL: v.ImgURL, ImgIndex: v.ImgIndex, }) } } skus, _, _ := getAPI(v.VendorOrgCode).SearchSkuList2([]int{int(wareSaveParam.WareID)}) // 获取改商品的sku信息 if len(skus) > 0 { for _, vv := range skus { sku := &jdshopapi.WareSaveSkus{ SkuID: vv.SkuID, JdPrice: utils.Float64ToStr(vv.JdPrice), StockNum: vv.StockNum, Props: []*jdshopapi.WareSaveSkusProp{ &jdshopapi.WareSaveSkusProp{ AttrID: utils.Str2Int(vv.SaleAttrs[0].AttrID), AttrValues: utils.Str2Int64(vv.SaleAttrs[0].AttrValues[0]), AttrValueAlias: vv.SaleAttrs[0].AttrValueAlias[0], }, }, OuterID: vv.OuterID, } wareSaveSkus = append(wareSaveSkus, sku) } } // } for _, vv := range v.StoreSkuSyncInfoJds { v.JdsWareID = result.Data[0].WareID vv.JdsWareID = result.Data[0].WareID _, wareSaveSku, err := buildUpdateSkusParam(v, vv, true) wareSaveSkus = append(wareSaveSkus, wareSaveSku) if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") return failedList, err } // if v.VendorOrgCode == "1" { // vendorSkuID, err := getAPI(v.VendorOrgCode).UpdateSkus(updateSkusParam) // if strings.Contains(err.Error(), "cookie可能过期了") { // err = nil // } // if err != nil { // failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") // return failedList, err // } // vv.VendorSkuID = vendorSkuID // } else { wareSaveParam.Skus = wareSaveSkus if wareResult, err2 := getAPI(v.VendorOrgCode).WareSave(wareSaveParam); err2 == nil { for _, vvv := range wareResult { if vvv.OuterID == wareSaveSku.OuterID { vv.VendorSkuID = utils.Int64ToStr(vvv.SkuID) break } } //创建商品后要上架,改价,库存,门店关注商品等 if err = getAPI(v.VendorOrgCode).WareDoUpdate("up", utils.Int64ToStr(wareSaveParam.WareID)); err == nil { err = getAPI(v.VendorOrgCode).StoreSkuBindStore(true, []string{vv.VendorSkuID}, nil) } } // } } } else { _, _, wareSaveParam, err := buildCreateWareParam(v) if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") return failedList, err } var ( wareID int64 resultAttrs = make(map[string]int64) ) // if v.VendorOrgCode == "1" { // createSkuResult, err2 := getAPI(v.VendorOrgCode).CreateWare(createSkuParamWare, createSkuParamSkus) // err = err2 // if strings.Contains(err.Error(), "cookie可能过期了") { // err = nil // } // wareID = createSkuResult.WareID // var paramAttrs = make(map[string]*jdshopapi.CreateSkuParamSkus) // for _, vv := range createSkuParamSkus { // for _, vvv := range vv.SaleAttrs { // paramAttrs[vvv.AttrValues[0]] = vv // } // } // for _, vv1 := range createSkuResult.Skus { // for _, vvv1 := range vv1.SaleAttrs { // if paramAttrs[vvv1.AttrValues[0]] != nil { // resultAttrs[paramAttrs[vvv1.AttrValues[0]].OuterID] = vv1.SkuID // } // } // } // for _, vv2 := range v.StoreSkuSyncInfoJds { // vv2.JdsWareID = createSkuResult.WareID // if resultAttrs[utils.Int2Str(vv2.SkuID)] != 0 { // vv2.VendorSkuID = utils.Int64ToStr(resultAttrs[utils.Int2Str(vv2.SkuID)]) // } // } // } else { var createSkuResult []*jdshopapi.WareSaveResult //for i := 0; i < 10; i++ { createSkuResult, err = getAPI(v.VendorOrgCode).WareSave(wareSaveParam) //if len(createSkuResult) > 0 { // break //} //time.Sleep(time.Second) //} wareID = createSkuResult[0].WareID var paramAttrs = make(map[string]*jdshopapi.WareSaveSkus) for _, vv := range wareSaveParam.Skus { for _, vvv := range vv.Props { paramAttrs[vvv.AttrValueAlias] = vv } } for _, vv1 := range createSkuResult { for _, vvv1 := range vv1.Props { if paramAttrs[vvv1.AttrValueAlias] != nil { resultAttrs[paramAttrs[vvv1.AttrValueAlias].OuterID] = vv1.SkuID } } } for _, vv2 := range v.StoreSkuSyncInfoJds { vv2.JdsWareID = createSkuResult[0].WareID if resultAttrs[utils.Int2Str(vv2.SkuID)] != 0 { vv2.VendorSkuID = utils.Int64ToStr(resultAttrs[utils.Int2Str(vv2.SkuID)]) } } //创建商品后要上架,改价,库存,门店关注商品等 if err = getAPI(v.VendorOrgCode).WareDoUpdate("up", utils.Int64ToStr(wareID)); err == nil { for _, vv2 := range v.StoreSkuSyncInfoJds { if resultAttrs[utils.Int2Str(vv2.SkuID)] != 0 { err = getAPI(v.VendorOrgCode).StoreSkuBindStore(true, []string{utils.Int64ToStr(resultAttrs[utils.Int2Str(vv2.SkuID)])}, nil) } } } // } if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") return failedList, err } else { //追加商品透图 imageURL := "" img := v.Img if img != "" { suffix := img[strings.LastIndex(img, "."):] if suffix != ".png" { if resBinary, _, _ := jxutils.DownloadFileByURL(img + model.SkuNameImgToPng); err == nil { downloadURL, _ := jxutils.UploadExportContent(resBinary, utils.Int64ToStr(time.Now().Unix())) imageURL, _ = uploadImg(downloadURL, name, "tou", v.VendorOrgCode) } } else { imageURL, _ = uploadImg(img, name, "tou", v.VendorOrgCode) } } if v.VendorOrgCode == "1" { api.JdShopAPI.TransparentImageAdd(wareID, imageURL) } } } if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") return failedList, err } } } else { //如果是普通店关注商品 for _, v := range storeSkuList { for _, vv := range v.StoreSkuSyncInfoJds { // if vv.VendorOrgCode == "2" { storeSkus, _ := dao.GetStoresSkusInfo(dao.GetDB(), []int{model.JdShopMainStoreID}, []int{vv.SkuID}) if len(storeSkus) > 0 { for _, storeSku := range storeSkus { if storeSku.JdsID != 0 { status := vv.Status stock := vv.Stock price := vv.VendorPrice if status == model.StoreSkuBindStatusNormal { err = getAPI(vv.VendorOrgCode).StoreWareDoUpdate(status, storeSku.JdsID, vendorStoreID) if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") return failedList, err } } if stock != 0 { err = getAPI(vv.VendorOrgCode).StoreUpdateStock(stock, storeSku.JdsID, vendorStoreID) if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") return failedList, err } } err = getAPI(v.VendorOrgCode).StoreUpdatePrice(utils.Float64ToStr(jxutils.IntPrice2Standard(int64(price))), storeSku.JdsID, vendorStoreID) } } if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") return failedList, err } } } // } } } } return failedList, err } func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { if globals.EnableJdShopWrite && vendorStoreID == model.JdShopMainVendorStoreID { if vendorStoreID == model.JdShopMainVendorStoreID { for _, v := range storeSkuList { name := filterSensitiveWord(v.Name) updateWareParam := &jdshopapi.UpdateWareParam{ WareID: v.JdsWareID, Title: name, VenderID: jdshopapi.VenderID, // PromiseID: jdshopapi.JdsPromiseID, ShopCategorys: []int{utils.Str2Int(v.VendorCatID)}, JdPrice: jxutils.IntPrice2Standard(v.UnitPrice), } if v.VendorVendorCatID != jdshopapi.JdsOtherMeatCatID { updateWareParam.PromiseID = jdshopapi.JdsPromiseID } var desc string if v.DescImg != "" { pic3, err2 := uploadImg2(v.DescImg, name, "desc", v.VendorOrgCode) err = err2 desc = `



` } else { desc = `



` } updateWareParam.Introduction = desc updateWareParam.MobileDesc = desc img := "" if v.ImgMix != "" { img = v.ImgMix } else { img = v.Img } if img != "" { pic1, err2 := uploadImg2(img, name, "1", v.VendorOrgCode) err = err2 err = getAPI(v.VendorOrgCode).ImageUpdate(v.JdsWareID, 1, pic1) if v.Img2 != "" { pic2, err2 := uploadImg2(v.Img2, name, "2", v.VendorOrgCode) err = err2 err = getAPI(v.VendorOrgCode).ImageUpdate(v.JdsWareID, 2, pic2) } else { err = getAPI(v.VendorOrgCode).ImageUpdate(v.JdsWareID, 2, pic1) } err = getAPI(v.VendorOrgCode).ImageUpdate(v.JdsWareID, 3, pic1) } var features = []*jdshopapi.CreateSkuParamFeatures{ &jdshopapi.CreateSkuParamFeatures{ Key: "is7ToReturn", //不支持7天无理由退货 Value: "0", }, &jdshopapi.CreateSkuParamFeatures{ Key: "tssp", //支持自提 Value: "", }, // &jdshopapi.CreateSkuParamFeatures{ // Key: "fdms", //分单? // Value: "1", // }, } updateWareParam.Features = features err = getAPI(v.VendorOrgCode).UpdateWare(updateWareParam) if err == nil { //追加商品透图 imageURL := "" img := v.Img if img != "" { suffix := img[strings.LastIndex(img, "."):] if suffix != ".png" { if resBinary, _, err := jxutils.DownloadFileByURL(img + model.SkuNameImgToPng); err == nil { downloadURL, err2 := jxutils.UploadExportContent(resBinary, utils.Int64ToStr(time.Now().Unix())) err = err2 imageURL, err = uploadImg(downloadURL, name, "tou", v.VendorOrgCode) } } else { imageURL, err = uploadImg(img, name, "tou", v.VendorOrgCode) } } if v.VendorOrgCode == "1" { api.JdShopAPI.TransparentImageAdd(v.JdsWareID, imageURL) } } for _, vv := range v.StoreSkuSyncInfoJds { updateSkusParam, _, err := buildUpdateSkusParam(v, vv, false) if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "更新商品基础信息") return failedList, err } _, err = getAPI(v.VendorOrgCode).UpdateSkus(updateSkusParam) } } } else { for _, v := range storeSkuList { var wareSaveSkus []*jdshopapi.WareSaveSkus name := filterSensitiveWord(v.Name) //jds2 wareSaveParam := &jdshopapi.WareSaveParam{ WareID: v.JdsWareID, Title: name, CategoryID: int(v.VendorVendorCatID), VenderID: jdshopapi.VendorID2, Length: 100, Wide: 100, Height: 100, Weight: utils.Int2Str(v.Weight), BrandID: jdshopapi.BrandIdNO, ShopCategorys: []int{utils.Str2Int(v.VendorCatID)}, PromiseID: -1, MultiCateProps: []interface{}{}, PropsSet: []interface{}{}, SaleAttrs: []interface{}{}, } var desc string if v.DescImg != "" { pic3, err2 := uploadImg2(v.DescImg, name, "desc", v.VendorOrgCode) err = err2 desc = `



` } else { desc = `



` } wareSaveParam.Notes = desc //上传京东图片 //规则,有两张就传两张,没有就重复传一张 pic1, _ := uploadImg(v.Img, name, "1", v.VendorOrgCode) img1 := &jdshopapi.CreateSkuParamImages{ ColorID: "0000000000", ImgIndex: 1, ImgURL: pic1, } img2 := &jdshopapi.CreateSkuParamImages{ ColorID: "0000000000", ImgIndex: 2, } if v.Img2 == "" { img2.ImgURL = pic1 } else { pic2, err2 := uploadImg(v.Img, name, "2", v.VendorOrgCode) err = err2 img2.ImgURL = pic2 } img3 := &jdshopapi.CreateSkuParamImages{ ColorID: "0000000000", ImgIndex: 3, ImgURL: pic1, } //jds2图片 wareSaveParam.ImageMap.Num0000000000 = append(wareSaveParam.ImageMap.Num0000000000, img1, img2, img3) for _, vv := range v.StoreSkuSyncInfoJds { _, wareSaveSku, err2 := buildUpdateSkusParam(v, vv, true) err = err2 wareSaveSku.SkuID = utils.Str2Int64(vv.VendorSkuID) wareSaveSkus = append(wareSaveSkus, wareSaveSku) } getAPI("2").WareSave(wareSaveParam) } } if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "更新商品基础信息") } } return failedList, err } func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { if globals.EnableJdShopWrite && vendorStoreID == model.JdShopMainVendorStoreID { for _, v := range storeSkuList { if v.IsDeletedBySku { err = getAPI(v.VendorOrgCode).DeleteSku(utils.Str2Int64(v.VendorSkuID)) } else { if v.VendorOrgCode == "1" { err = getAPI(v.VendorOrgCode).UpOrDown(utils.Str2Int64(v.VendorSkuID2), 2) if err == nil { err = getAPI(v.VendorOrgCode).DeleteWare(utils.Str2Int(v.VendorSkuID2)) } } else { err = getAPI(v.VendorOrgCode).WareDoUpdate("down", v.VendorSkuID2) } } if err != nil { failedList = append(failedList, putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "删除商品")...) } } } return failedList, err } func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (skuNameList []*partner.SkuNameInfo, err error) { var ( pageNo = 1 pageSize = 20 ) if result, totalCount, err := api.JdShopAPI.StoreProductSearch(pageNo, pageSize, []string{vendorStoreID}); err == nil && result != nil { for ; pageNo <= totalCount/pageSize+1; pageNo++ { result2, _, err := api.JdShopAPI.StoreProductSearch(pageNo, pageSize, []string{vendorStoreID}) if err == nil { for _, v := range result2 { if skuName := vendorSku2Jx2(v); skuName != nil { skuNameList = append(skuNameList, skuName) } } } } } // _, totalCount, err := api.JdShopAPI.SearchSkuList(pageNo, pageSize) // for ; pageNo <= totalCount/pageSize+1; pageNo++ { // result, _, err := api.JdShopAPI.SearchSkuList(pageNo, pageSize) // if err == nil { // for _, v := range result { // if skuName := vendorSku2Jx(v); skuName != nil { // skuNameList = append(skuNameList, skuName) // } // } // } // } return skuNameList, err } func getMainStoreVendorSkuID(mainStoreID int, skuID int) (vendorSkuID int64, err error) { var ( db = dao.GetDB() ) storeSkus, err := dao.GetStoresSkusInfo(db, []int{mainStoreID}, []int{skuID}) if len(storeSkus) > 0 { vendorSkuID = storeSkus[0].JdsID } return vendorSkuID, err } func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) { if globals.EnableJdShopWrite { // var stock = 0 for _, v := range storeSkuList { // if storeID == model.JdShopMainStoreID { // if status == model.SkuStatusNormal { // stock = 9999 // } // if v.JdsStockSwitch == model.NO { // stock = 0 // } // err = getAPI(v.VendorOrgCode).UpdateSkuStock(utils.Str2Int(v.VendorSkuID), stock) // } else { // if v.VendorOrgCode == "1" { // storeSkus, err2 := dao.GetStoresSkusInfo(dao.GetDB(), []int{model.JdShopMainStoreID}, []int{v.SkuID}) // err = err2 // if len(storeSkus) > 0 { // if storeSkus[0].JdsID != 0 && vendorStoreID != "" { // if storeSkus[0].Status == model.SkuStatusNormal { // stock = 9999 // } // err = getAPI(v.VendorOrgCode).UpdateSkuSiteStock(storeSkus[0].JdsID, stock, utils.Str2Int(vendorStoreID)) // } // } // } else { if vendorSkuID, err := getMainStoreVendorSkuID(model.JdShopMainStoreID, v.SkuID); err == nil && vendorSkuID != 0 { err = getAPI(v.VendorOrgCode).StoreWareDoUpdate(status, vendorSkuID, vendorStoreID) } // } // } } if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "修改商品库存") } } return failedList, err } func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { if globals.EnableJdShopWrite { for _, v := range storeSkuList { // if storeID == model.JdShopMainStoreID { // err = getAPI(v.VendorOrgCode).UpdateSkuJdPrice(utils.Str2Int(v.VendorSkuID), jxutils.IntPrice2Standard(v.VendorPrice)) // } else if storeID == model.JdShopMainStoreID2 { // //修改京东商城商品库价格 // } else { // if v.VendorOrgCode == "1" { // // null // } else { if vendorSkuID, err := getMainStoreVendorSkuID(model.JdShopMainStoreID, v.SkuID); err == nil && vendorSkuID != 0 { err = getAPI(v.VendorOrgCode).StoreUpdatePrice(utils.Float64ToStr(jxutils.IntPrice2Standard(v.VendorPrice)), vendorSkuID, vendorStoreID) } // } // } if err != nil { failedList = append(failedList, putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "修改商品价格")...) } } } return failedList, err } func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { if globals.EnableJdShopWrite { for _, v := range storeSkuList { // if storeID == model.JdShopMainStoreID { // } else if storeID == model.JdShopMainStoreID2 { // } else { // if v.VendorOrgCode == "1" { // } else { if vendorSkuID, err := getMainStoreVendorSkuID(model.JdShopMainStoreID, v.SkuID); err == nil && vendorSkuID != 0 { err = getAPI(v.VendorOrgCode).StoreUpdateStock(v.Stock, vendorSkuID, vendorStoreID) } // } // } } if err != nil { failedList = append(failedList, putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "修改商品库存")...) } } return failedList, err } func (p *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) { result, err := api.JdShopAPI.FindShopCategories() for _, v := range result { var cat = &partner.BareCategoryInfo{ VendorCatID: utils.Int64ToStr(v.CID), Name: v.Name, } if v.ParentCID == 0 { cat.Level = 1 } else { cat.Level = 2 } cats = append(cats, cat) } return cats, err } func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { if globals.EnableJdShopWrite && vendorStoreID == model.JdShopMainVendorStoreID { status, err2 := updateOrCreateCategories(storeCat, true) err = err2 if status == -1 { return fmt.Errorf("京东商城店内分类创建失败!") } if err != nil { return err } time.Sleep(time.Second * 2) // flag := false // for { result, err := getAPI(storeCat.VendorOrgCode).FindShopCategories() if err != nil { return err } for _, v := range result { if v.Name == storeCat.Name { storeCat.VendorCatID = utils.Int64ToStr(v.CID) // flag = true break } } if storeCat.VendorCatID == "" { return fmt.Errorf("京东商城店内分类创建可能失败了!storeID: %v", storeID) } // if flag { // break // } // } } return err } func (p *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { if globals.EnableJdShopWrite && vendorStoreID == model.JdShopMainVendorStoreID { status, err2 := updateOrCreateCategories(storeCat, false) err = err2 if status == -1 { return fmt.Errorf("京东商城店内分类更新失败!") } } return err } func (p *PurchaseHandler) DeleteStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, vendorCatID string, level int) (err error) { if globals.EnableJdShopWrite && vendorStoreID == model.JdShopMainVendorStoreID { _, err = api.JdShopAPI.DeleteShopCategory(utils.Str2Int64(vendorCatID)) } return err } func (p *PurchaseHandler) IsErrSkuExist(err error) (isExist bool) { return false } func (p *PurchaseHandler) IsErrCategoryExist(err error) (isExist bool) { return false } func (p *PurchaseHandler) IsErrCategoryNotExist(err error) (isNotExist bool) { return false } func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) { return 1 } func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp { return sensitiveWordRegexp } func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) { if strings.Contains(err.Error(), deleteErr1) || (strings.Contains(err.Error(), deleteErr2) && strings.Contains(err.Error(), deleteErr3)) { return true } return false } func vendorSku2Jx(result *jdshopapi.SearchSkuListResult) (skuName *partner.SkuNameInfo) { if result == nil { return nil } skuName = &partner.SkuNameInfo{ VendorNameID: utils.Int64ToStr(result.WareID), SkuList: []*partner.SkuInfo{ &partner.SkuInfo{ StoreSkuInfo: partner.StoreSkuInfo{ SkuID: utils.Str2Int(result.OuterID), VendorSkuID: utils.Int64ToStr(result.SkuID), VendorNameID: utils.Int64ToStr(result.WareID), Stock: result.StockNum, VendorPrice: utils.Float64TwoInt64(result.JdPrice * 100), }, Comment: result.SaleAttrs[0].AttrValueAlias[0], }, }, } return skuName } func vendorSku2Jx2(result *jdshopapi.StoreProductSearchResult) (skuName *partner.SkuNameInfo) { if result == nil { return nil } skuName = &partner.SkuNameInfo{ Name: result.SkuName, SkuList: []*partner.SkuInfo{ &partner.SkuInfo{ StoreSkuInfo: partner.StoreSkuInfo{ VendorSkuID: utils.Int64ToStr(result.SkuID), Stock: result.StockNum, VendorPrice: jxutils.StandardPrice2Int(result.StorePrice), }, }, }, Status: result.Status, } return skuName } func updateOrCreateCategories(storeCat *dao.SkuStoreCatInfo, isCreate bool) (status int64, err error) { var createShopCategoryParams []*jdshopapi.CreateShopCategoryParam result, err := getAPI(storeCat.VendorOrgCode).FindShopCategories() if err != nil { return -1, err } for _, v := range result { createShopCategoryParam := &jdshopapi.CreateShopCategoryParam{ HomeShow: "0", ID: utils.Int64ToStr(v.CID), Open: "", OrderNo: utils.Int2Str(v.OrderNo), ParentID: utils.Int64ToStr(v.ParentCID), Title: v.Name, Type: jdshopapi.UpdateCatType, } createShopCategoryParams = append(createShopCategoryParams, createShopCategoryParam) } createShopCategoryParam2 := &jdshopapi.CreateShopCategoryParam{ HomeShow: "0", Open: "", OrderNo: utils.Int2Str(storeCat.Seq), ParentID: storeCat.ParentVendorCatID, Title: storeCat.Name, } if isCreate { createShopCategoryParam2.Type = jdshopapi.CreateCatType createShopCategoryParam2.ID = "1" createShopCategoryParams = append(createShopCategoryParams, createShopCategoryParam2) } else { for _, v := range createShopCategoryParams { if v.ID == storeCat.VendorCatID { v.Title = createShopCategoryParam2.Title v.OrderNo = createShopCategoryParam2.OrderNo } } } status, err = getAPI(storeCat.VendorOrgCode).CreateShopCategory(createShopCategoryParams) return status, err } func buildCreateWareParam(storeSku *dao.StoreSkuSyncInfo) (createSkuParamWare *jdshopapi.CreateSkuParamWare, createSkuParamSkus []*jdshopapi.CreateSkuParamSkus, wareSaveParam *jdshopapi.WareSaveParam, err error) { var ( images []*jdshopapi.CreateSkuParamImages vendorCatID int ) if storeSku.VendorCatID == "0" { resultCat, _ := getAPI(storeSku.VendorOrgCode).FindShopCategories() for _, v := range resultCat { if v.Name == storeSku.CategoryName { vendorCatID = int(v.CID) break } } } else { vendorCatID = utils.Str2Int(storeSku.VendorCatID) } name := filterSensitiveWord(storeSku.Name) wareSaveParam = &jdshopapi.WareSaveParam{ WareID: 0, Title: name, CategoryID: int(storeSku.VendorVendorCatID), LastCategoryID: int(storeSku.VendorVendorCatID), VenderID: jdshopapi.VendorID2, Length: 200, Wide: 100, Height: 100, Weight: "1", BrandID: jdshopapi.BrandIdNO, WareStatus: 8, //上架待审核,没用,建好了都要再上架一次 ShopCategorys: []int{vendorCatID}, PromiseID: 0, MultiCateProps: []interface{}{}, PropsSet: []interface{}{}, SaleAttrs: []interface{}{}, TransparentImageAudit: []interface{}{}, OptionType: 1, AvailableFeatures: []interface{}{}, CharacteristicService: []interface{}{}, ExtendFeatures: []interface{}{}, TempID: "10569615110055200", //必须要这个东西,不知道是啥 } createSkuParamWare = &jdshopapi.CreateSkuParamWare{ Title: name, ShopCategorys: []int{vendorCatID}, CategoryID: int(storeSku.VendorVendorCatID), BrandID: jdshopapi.JxBrandId, // TransportID: jdshopapi.TransportID, WareStatus: 8, //上架待审核 OuterID: utils.Int2Str(storeSku.NameID), // VenderID: jdshopapi.VenderID, Length: 100, Width: 100, Height: 100, Weight: 0.5, JdPrice: jxutils.IntPrice2Standard(storeSku.UnitPrice), // MarketPrice: jxutils.IntPrice2Standard(storeSku.UnitPrice), // PromiseID: jdshopapi.JdsPromiseID, } if storeSku.VendorOrgCode == "1" { createSkuParamWare.VenderID = jdshopapi.VenderID } if storeSku.VendorVendorCatID != jdshopapi.JdsOtherMeatCatID { createSkuParamWare.PromiseID = jdshopapi.JdsPromiseID } if storeSku.VendorVendorCatID == jdshopapi.JdsBeefCatID { createSkuParamWare.MultiCategoryID = jdshopapi.JdsBeefLastCatID } //上传京东图片 //规则,有两张就传两张,没有就重复传一张 pic1, err := uploadImg(storeSku.Img, name, "1", storeSku.VendorOrgCode) img1 := &jdshopapi.CreateSkuParamImages{ ColorID: "0000000000", ImgIndex: 1, ImgURL: pic1, } img2 := &jdshopapi.CreateSkuParamImages{ ColorID: "0000000000", ImgIndex: 2, } if storeSku.Img2 == "" { img2.ImgURL = pic1 } else { pic2, err2 := uploadImg(storeSku.Img, name, "2", storeSku.VendorOrgCode) err = err2 img2.ImgURL = pic2 } img3 := &jdshopapi.CreateSkuParamImages{ ColorID: "0000000000", ImgIndex: 3, ImgURL: pic1, } images = append(images, img1) images = append(images, img2) images = append(images, img3) createSkuParamWare.Images = images //jds2图片 // img4 := img1 // img4.ImgZoneID = "0000000000" // img5 := img2 // img5.ImgZoneID = "0000000000" // img6 := img3 // img6.ImgZoneID = "0000000000" wareSaveParam.ImageMap.Num0000000000 = append(wareSaveParam.ImageMap.Num0000000000, img1, img2, img3) //商品详情拼接 var desc string if storeSku.DescImg != "" { pic3, err2 := uploadImg(storeSku.DescImg, name, "desc", storeSku.VendorOrgCode) err = err2 desc = `



` } else { desc = `



` } createSkuParamWare.MobileDesc = desc createSkuParamWare.Introduction = desc wareSaveParam.Notes = desc //设置商品属性值 var ( attrIDs = make(map[string]int) //贮存方式,净含量,保质期IDs zctjValueID int64 //贮存条件冷藏0-4的id gcjkValueID int64 //国产,进口的id lbValueID int64 //类别的ID bcztValueID int64 //保存状态ID rmsjValueID int64 //热卖时间ID attrsProp []*jdshopapi.CreateSkuParamAttrs ) attrs, err := getAPI(storeSku.VendorOrgCode).FindAttrs(int(storeSku.VendorVendorCatID)) for _, v := range attrs { if v.Name == "保质期" { attrIDs[v.Name] = v.ID } else if v.Name == "贮存条件" { attrIDs[v.Name] = v.ID } else if v.Name == "净含量" { attrIDs[v.Name] = v.ID } else if v.Name == "规格" { attrIDs[v.Name] = v.ID } else if v.Name == "国产/进口" { attrIDs[v.Name] = v.ID } else if v.Name == "类别" { attrIDs[v.Name] = v.ID } else if v.Name == "保存状态" { attrIDs[v.Name] = v.ID } else if v.Name == "热卖时间" { attrIDs[v.Name] = v.ID } } values, _, err := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(attrIDs["贮存条件"]) for _, v := range values { if v.Name == "冷藏 0-4℃" { zctjValueID = v.ID } } if attrIDs["国产/进口"] != 0 { values2, _, err2 := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(attrIDs["国产/进口"]) err = err2 for _, v := range values2 { if v.Name == "国产" { gcjkValueID = v.ID } } attrgcjk := &jdshopapi.CreateSkuParamAttrs{ AttrID: utils.Int2Str(attrIDs["国产/进口"]), AttrValues: []string{utils.Int64ToStr(gcjkValueID)}, } attrsProp = append(attrsProp, attrgcjk) } if attrIDs["保存状态"] != 0 { values2, _, err2 := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(attrIDs["保存状态"]) err = err2 for _, v := range values2 { if v.Name == "冷藏" || v.Name == "活鲜" { bcztValueID = v.ID } } attrbczt := &jdshopapi.CreateSkuParamAttrs{ AttrID: utils.Int2Str(attrIDs["保存状态"]), AttrValues: []string{utils.Int64ToStr(bcztValueID)}, } attrsProp = append(attrsProp, attrbczt) } if attrIDs["热卖时间"] != 0 { values2, _, err2 := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(attrIDs["热卖时间"]) err = err2 for _, v := range values2 { if v.Name == "12月" { rmsjValueID = v.ID } } attrrmsj := &jdshopapi.CreateSkuParamAttrs{ AttrID: utils.Int2Str(attrIDs["热卖时间"]), AttrValues: []string{utils.Int64ToStr(rmsjValueID)}, } attrsProp = append(attrsProp, attrrmsj) } //牛肉创建不一样 if storeSku.VendorVendorCatID == jdshopapi.JdsBeefCatID { var exValueID int64 values2, _, err2 := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(150390) err = err2 for _, v := range values2 { if v.Name == "其它" { exValueID = v.ID } } attrex := &jdshopapi.CreateSkuParamAttrs{ AttrID: utils.Int2Str(150390), AttrValues: []string{utils.Int64ToStr(exValueID)}, } attrsProp = append(attrsProp, attrex) wareSaveParam.LastCategoryID = 17902 } attrZctj := &jdshopapi.CreateSkuParamAttrs{ AttrID: utils.Int2Str(attrIDs["贮存条件"]), AttrValues: []string{utils.Int64ToStr(zctjValueID)}, } attrJhl := &jdshopapi.CreateSkuParamAttrs{ AttrID: utils.Int2Str(attrIDs["净含量"]), AttrValues: []string{"0.5"}, } attrBzq := &jdshopapi.CreateSkuParamAttrs{ AttrID: utils.Int2Str(attrIDs["保质期"]), AttrValues: []string{"5"}, } attrsProp = append(attrsProp, attrZctj) attrsProp = append(attrsProp, attrJhl) attrsProp = append(attrsProp, attrBzq) createSkuParamWare.MultiCateProps = attrsProp var features = []*jdshopapi.CreateSkuParamFeatures{ &jdshopapi.CreateSkuParamFeatures{ Key: "is7ToReturn", //不支持7天无理由退货 Value: "0", }, // &jdshopapi.CreateSkuParamFeatures{ // Key: "tssp", //支持自提 // Value: "", // }, // &jdshopapi.CreateSkuParamFeatures{ // Key: "fdms", //分单? // Value: "1", // }, } createSkuParamWare.Features = features //组合sku var ( vendorPrice int64 = 0 wareSaveSkus []*jdshopapi.WareSaveSkus ) for _, v := range storeSku.StoreSkuSyncInfoJds { var ( ggValueID int64 //规格的属性id ggValueName string //规格的属性名 attrsPropSku []*jdshopapi.CreateSkuParamAttrs attrsPropSku2 []*jdshopapi.WareSaveSkusProp //jds2 multiPropSku []*jdshopapi.CreateSkuParamAttrs specQuality string ) valuesSku, maxNo, _ := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(attrIDs["规格"]) if v.SpecUnit == model.SpecUnitNames[1] || v.SpecUnit == model.SpecUnitNames[2] { specQuality = strings.TrimRight(fmt.Sprintf("%.2f", float64(v.SpecQuality)), "0.") + v.SpecUnit } else { specQuality = utils.Float64ToStr(float64(v.SpecQuality)) + v.SpecUnit } if v.Comment != "" { specQuality = v.Comment } for _, v := range valuesSku { if v.Name == specQuality { ggValueID = v.ID ggValueName = v.Name } } if ggValueID == 0 { //说明没有建这个规格,要建上 catID, _ := getAPI(storeSku.VendorOrgCode).SaveVenderAttrValue(specQuality, attrIDs["规格"], int(storeSku.VendorVendorCatID), maxNo+1) ggValueID = catID ggValueName = specQuality } //jds1 attrSku := &jdshopapi.CreateSkuParamAttrs{ AttrID: utils.Int2Str(attrIDs["规格"]), AttrValues: []string{utils.Int64ToStr(ggValueID)}, } attrsPropSku = append(attrsPropSku, attrSku) //jds2 attrSku2 := &jdshopapi.WareSaveSkusProp{ AttrID: attrIDs["规格"], AttrValues: ggValueID, AttrValueAlias: ggValueName, } attrsPropSku2 = append(attrsPropSku2, attrSku2) //jds1 sku := &jdshopapi.CreateSkuParamSkus{ JdPrice: jxutils.IntPrice2Standard(v.VendorPrice), // StockNum: 9999, Type: "com.jd.pop.ware.ic.api.domain.sku", Type2: "com.jd.pop.ware.ic.api.domain.Sku", OuterID: utils.Int2Str(v.SkuID), } sku.SaleAttrs = attrsPropSku //jds2 sku2 := &jdshopapi.WareSaveSkus{ JdPrice: utils.Float64ToStr(jxutils.IntPrice2Standard(v.VendorPrice)), OuterID: utils.Int2Str(v.SkuID), } sku2.Props = attrsPropSku2 if attrIDs["类别"] != 0 { values2, _, err2 := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(attrIDs["类别"]) err = err2 lbValueID = values2[len(values2)-1].ID attrlb := &jdshopapi.CreateSkuParamAttrs{ AttrID: utils.Int2Str(attrIDs["类别"]), AttrValues: []string{utils.Int64ToStr(lbValueID)}, } multiPropSku = append(multiPropSku, attrlb) } sku.MultiCateProps = multiPropSku createSkuParamSkus = append(createSkuParamSkus, sku) if v.VendorPrice > vendorPrice { vendorPrice = v.VendorPrice } if v.Status == model.SkuStatusNormal { sku.StockNum = 9999 sku2.StockNum = 9999 } else { sku.StockNum = 0 sku2.StockNum = 0 } wareSaveSkus = append(wareSaveSkus, sku2) } //市场价固定500 createSkuParamWare.MarketPrice = 500 wareSaveParam.Skus = wareSaveSkus return createSkuParamWare, createSkuParamSkus, wareSaveParam, err } //京东商城上传图片,若平台上已经有了这个图就直接拿来用了 func uploadImg(img, name, index, vendorOrgCode string) (imgURL string, err error) { result, err := getAPI(vendorOrgCode).QueryPicture(name + index) if len(result) > 0 { imgURL = result[0].PictureURL } else { data, _, err := jxutils.DownloadFileByURL(img) if err != nil { return imgURL, err } uploadResult, err := getAPI(vendorOrgCode).UploadPicture(data, 0, name+index) if err != nil { return imgURL, err } imgURL = uploadResult.PictureURL } return imgURL, err } func uploadImg2(img, name, index, vendorOrgCode string) (imgURL string, err error) { data, _, err := jxutils.DownloadFileByURL(img) if err != nil { return imgURL, err } uploadResult, err := getAPI(vendorOrgCode).UploadPicture(data, 0, name+index) if err != nil { return imgURL, err } imgURL = uploadResult.PictureURL return imgURL, err } func filterSensitiveWord(name string) (result string) { for _, v := range jdshopapi.SensitiveWordMap { if strings.Contains(name, v) { return strings.ReplaceAll(name, v, "") } } return name } func buildUpdateSkusParam(storeSku *dao.StoreSkuSyncInfo, v *dao.StoreSkuSyncInfo, isCreate bool) (updateSkusParam *jdshopapi.UpdateSkusParam, wareSku *jdshopapi.WareSaveSkus, err error) { var ( ggValueID int64 //规格的属性id ggValueName string //规格名 attrsPropSku []*jdshopapi.CreateSkuParamAttrs attrsPropSku2 []*jdshopapi.WareSaveSkusProp skus []*jdshopapi.UpdateSkusParamSkus multiPropSku []*jdshopapi.CreateSkuParamAttrs specQuality string ) updateSkusParam = &jdshopapi.UpdateSkusParam{ WareID: storeSku.JdsWareID, } sku := &jdshopapi.UpdateSkusParamSkus{ WareID: storeSku.JdsWareID, JdPrice: jxutils.IntPrice2Standard(v.VendorPrice), Type: "com.jd.pop.ware.ic.api.domain.sku", Type2: "com.jd.pop.ware.ic.api.domain.Sku", OuterID: utils.Int2Str(v.SkuID), } //jds2 wareSku = &jdshopapi.WareSaveSkus{ JdPrice: utils.Float64ToStr(jxutils.IntPrice2Standard(v.VendorPrice)), OuterID: utils.Int2Str(v.SkuID), } //库存设置 if v.StoreSkuStatus == model.SkuStatusNormal { sku.StockNum = "9999" wareSku.StockNum = 9999 } else { sku.StockNum = "0" wareSku.StockNum = 0 } //规格类别设置 attrIDs := make(map[string]int) attrs, err := getAPI(storeSku.VendorOrgCode).FindAttrs(int(storeSku.VendorVendorCatID)) for _, v := range attrs { if v.Name == "规格" { attrIDs[v.Name] = v.ID } else if v.Name == "类别" { attrIDs[v.Name] = v.ID } } if attrIDs["类别"] != 0 { values2, _, err2 := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(attrIDs["类别"]) err = err2 lbValueID := values2[len(values2)-1].ID attrlb := &jdshopapi.CreateSkuParamAttrs{ AttrID: utils.Int2Str(attrIDs["类别"]), AttrValues: []string{utils.Int64ToStr(lbValueID)}, } multiPropSku = append(multiPropSku, attrlb) } sku.MultiCateProps = multiPropSku if v.SpecUnit == model.SpecUnitNames[1] || v.SpecUnit == model.SpecUnitNames[2] { if math.Mod(float64(v.SpecQuality), 10) != 0 { specQuality = strings.TrimRight(fmt.Sprintf("%.2f", float64(v.SpecQuality)), "0.") + v.SpecUnit } else { specQuality = utils.Float64ToStr(float64(v.SpecQuality)) + v.SpecUnit } } else { specQuality = utils.Float64ToStr(float64(v.SpecQuality)) + v.SpecUnit } valuesSku, maxNo, _ := getAPI(storeSku.VendorOrgCode).FindValuesByAttrId(attrIDs["规格"]) if isCreate { for _, vv := range valuesSku { if vv.Name == specQuality { ggValueID = vv.ID ggValueName = vv.Name break } } if ggValueID == 0 { //说明没有建这个规格,要建上 catID, _ := getAPI(storeSku.VendorOrgCode).SaveVenderAttrValue(specQuality, attrIDs["规格"], int(storeSku.VendorVendorCatID), maxNo+1) ggValueID = catID ggValueName = specQuality } attrSku := &jdshopapi.CreateSkuParamAttrs{ AttrID: utils.Int2Str(attrIDs["规格"]), AttrValues: []string{utils.Int64ToStr(ggValueID)}, } attrsPropSku = append(attrsPropSku, attrSku) sku.SaleAttrs = attrsPropSku //jds2 attrSku2 := &jdshopapi.WareSaveSkusProp{ AttrID: attrIDs["规格"], AttrValues: ggValueID, AttrValueAlias: ggValueName, } attrsPropSku2 = append(attrsPropSku2, attrSku2) wareSku.Props = attrsPropSku2 } else { vendorSku, err2 := getAPI(storeSku.VendorOrgCode).FindSkuById(utils.Str2Int64(v.VendorSkuID)) err = err2 vendorAttrValue := vendorSku.SaleAttrs[0].AttrValueAlias[0] if v.Comment != "" { specQuality = v.Comment } if v.Comment != vendorAttrValue { err = getAPI(storeSku.VendorOrgCode).UpdateWareSaleAttrvalueAlias(&jdshopapi.UpdateWareSaleAttrvalueAliasParam{ WareID: v.JdsWareID, Props: []*jdshopapi.CreateSkuParamAttrs2{ &jdshopapi.CreateSkuParamAttrs2{ AttrID: vendorSku.SaleAttrs[0].AttrID, AttrValues: []string{vendorSku.SaleAttrs[0].AttrValues[0]}, AttrValueAlias: []string{specQuality}, Type: "com.jd.pop.ware.ic.api.domain.prop", Type2: "com.jd.pop.ware.ic.api.domain.Prop", }, }, }) sku.SkuID = utils.Str2Int64(v.VendorSkuID) } attrSku := &jdshopapi.CreateSkuParamAttrs{ AttrID: vendorSku.SaleAttrs[0].AttrID, AttrValues: []string{vendorSku.SaleAttrs[0].AttrValues[0]}, } attrsPropSku = append(attrsPropSku, attrSku) sku.SaleAttrs = attrsPropSku } skus = append(skus, sku) updateSkusParam.Skus = skus return updateSkusParam, wareSku, err }