package jdshop import ( "regexp" "strings" "git.rosy.net.cn/baseapi/platformapi/jdshopapi" "git.rosy.net.cn/jx-callback/globals/api" "git.rosy.net.cn/baseapi/platformapi/yinbaoapi" "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" ) 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 && vendorStoreID == model.JdShopMainVendorStoreID { for _, v := range storeSkuList { //判断京东商城上是否有这个商品了,如果有就是添加规格而不是创建商品 name := filterSensitiveWord(v.Name) result, err := api.JdShopAPI.SearchWare4Valid(name) if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") return failedList, err } if result.TotalItem > 0 && len(result.Data) > 0 { for _, vv := range v.StoreSkuSyncInfoJds { v.JdsWareID = result.Data[0].WareID vv.JdsWareID = result.Data[0].WareID updateSkusParam, err := buildUpdateSkusParam(v, vv, true) if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") return failedList, err } vendorSkuID, err := api.JdShopAPI.UpdateSkus(updateSkusParam) if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") return failedList, err } vv.VendorSkuID = vendorSkuID } } else { createSkuParamWare, createSkuParamSkus, err := buildCreateWareParam(v) if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") return failedList, err } createSkuResult, err := api.JdShopAPI.CreateWare(createSkuParamWare, createSkuParamSkus) if err != nil { failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") return failedList, err } var paramAttrs = make(map[string]*jdshopapi.CreateSkuParamSkus) var resultAttrs = make(map[string]int64) 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)]) } } } } } 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 { for _, v := range storeSkuList { name := filterSensitiveWord(v.Name) updateWareParam := &jdshopapi.UpdateWareParam{ WareID: v.JdsWareID, Title: name, VenderID: jdshopapi.VenderID, PromiseID: jdshopapi.JdsPromiseID, } var desc string if v.DescImg != "" { pic3, err2 := uploadImg2(v.DescImg, name, "desc") err = err2 desc = `



` } updateWareParam.Introduction = desc updateWareParam.MobileDesc = desc if v.Img != "" { pic1, err2 := uploadImg2(v.Img, name, "1") err = err2 err = api.JdShopAPI.ImageUpdate(v.JdsWareID, 1, pic1) if v.Img2 != "" { pic2, err2 := uploadImg2(v.Img2, name, "2") err = err2 err = api.JdShopAPI.ImageUpdate(v.JdsWareID, 2, pic2) } else { err = api.JdShopAPI.ImageUpdate(v.JdsWareID, 2, pic1) } } err = api.JdShopAPI.UpdateWare(updateWareParam) 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 } vendorSkuID, err := api.JdShopAPI.UpdateSkus(updateSkusParam) vv.VendorSkuID = vendorSkuID } } 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 { err = api.JdShopAPI.DeleteSku(utils.Str2Int64(v.VendorSkuID)) // err = api.JdShopAPI.UpOrDown(utils.Str2Int64(v.VendorSkuID2), 2) // if err == nil { // err = api.JdShopAPI.DeleteWare(utils.Str2Int(v.VendorSkuID2)) // } } if err != nil { 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) { return skuNameList, 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 status == model.SkuStatusNormal { stock = 9999 } if vendorStoreID == model.JdShopMainVendorStoreID { err = api.JdShopAPI.UpdateSkuStock(utils.Str2Int(v.VendorSkuID), stock) } else { err = api.JdShopAPI.UpdateSkuSiteStock(utils.Str2Int(v.VendorSkuID), stock, utils.Str2Int(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 && vendorStoreID == model.JdShopMainVendorStoreID { for _, v := range storeSkuList { err = api.JdShopAPI.UpdateSkuJdPrice(utils.Str2Int(v.VendorSkuID), jxutils.IntPrice2Standard(v.VendorPrice)) } if err != nil { 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 { } 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 { err = updateOrCreateCategories(storeCat, true) result, err := api.JdShopAPI.FindShopCategories() if err != nil { return err } for _, v := range result { if v.Name == storeCat.Name { storeCat.VendorCatID = utils.Int64ToStr(v.CID) } } } return err } func (p *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { if globals.EnableJdShopWrite && vendorStoreID == model.JdShopMainVendorStoreID { err = updateOrCreateCategories(storeCat, false) } 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) { return false } func ybSkuStatus2Jx(ybStatus int) (jxSkuStatus int) { if ybStatus == yinbaoapi.SkuStatusEnable { jxSkuStatus = model.SkuStatusNormal } else if ybStatus == yinbaoapi.SkuStatusDisabled { jxSkuStatus = model.SkuStatusDontSale } else if ybStatus == yinbaoapi.SkuStatusDeleted { jxSkuStatus = model.SkuStatusDeleted } return jxSkuStatus } func vendorSku2Jx(result *yinbaoapi.QueryProductByBarcodeResult, resultp []*yinbaoapi.QueryProductImagesByBarcodeResult) (skuName *partner.SkuNameInfo) { var picList []string if result == nil { globals.SugarLogger.Warnf("vendorSku2Jx, strange result:%s", utils.Format4Output(result, true)) return nil } if len(resultp) > 0 { if resultp[0].ImageURL != "" { // for _, v := range resultp.Productimages { picList = append(picList, resultp[0].ImageURL) // } } } prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(result.Name) skuName = &partner.SkuNameInfo{ Prefix: prefix, Name: name, Unit: unit, YbBarCode: result.Barcode, SkuList: []*partner.SkuInfo{ &partner.SkuInfo{ StoreSkuInfo: partner.StoreSkuInfo{ VendorSkuID: utils.Int64ToStr(result.UID), Stock: int(utils.Float64TwoInt64(result.Stock)), VendorPrice: jxutils.StandardPrice2Int(result.SellPrice), Status: ybSkuStatus2Jx(result.Enable), }, SkuName: result.Name, Comment: comment, SpecQuality: float64(specQuality), SpecUnit: specUnit, Weight: int(utils.Float64TwoInt64(float64(specQuality))), }, }, PictureList: picList, } return skuName } func updateOrCreateCategories(storeCat *dao.SkuStoreCatInfo, isCreate bool) (err error) { var createShopCategoryParams []*jdshopapi.CreateShopCategoryParam result, err := api.JdShopAPI.FindShopCategories() if err != nil { return 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 } } } err = api.JdShopAPI.CreateShopCategory(createShopCategoryParams) return err } func buildCreateWareParam(storeSku *dao.StoreSkuSyncInfo) (createSkuParamWare *jdshopapi.CreateSkuParamWare, createSkuParamSkus []*jdshopapi.CreateSkuParamSkus, err error) { var ( images []*jdshopapi.CreateSkuParamImages // desc string ) name := filterSensitiveWord(storeSku.Name) createSkuParamWare = &jdshopapi.CreateSkuParamWare{ Title: name, ShopCategorys: []int{utils.Str2Int(storeSku.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, } //上传京东图片 //规则,有两张就传两张,没有就重复传一张 pic1, err := uploadImg(storeSku.Img, name, "1") 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") err = err2 img2.ImgURL = pic2 } images = append(images, img1) images = append(images, img2) createSkuParamWare.Images = images //商品详情拼接 var desc string if storeSku.DescImg != "" { pic3, err2 := uploadImg(storeSku.DescImg, name, "desc") err = err2 desc = `



` } else { desc = `



` } createSkuParamWare.MobileDesc = desc createSkuParamWare.Introduction = desc //设置商品属性值 var ( attrIDs = make(map[string]int) //贮存方式,净含量,保质期IDs zctjValueID int64 //贮存条件冷藏0-4的id gcjkValueID int64 //国产,进口的id attrsProp []*jdshopapi.CreateSkuParamAttrs ) attrs, err := api.JdShopAPI.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 } } values, _, err := api.JdShopAPI.FindValuesByAttrId(attrIDs["贮存条件"]) for _, v := range values { if v.Name == "冷藏 0-4℃" { zctjValueID = v.ID } } if attrIDs["国产/进口"] != 0 { values2, _, err2 := api.JdShopAPI.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) } 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 feature := &jdshopapi.CreateSkuParamFeatures{ Key: "is7ToReturn", //不支持7天无理由退货 Value: "0", } features = append(features, feature) createSkuParamWare.Features = features //组合sku var vendorPrice int64 = 0 for _, v := range storeSku.StoreSkuSyncInfoJds { var ( ggValueID int64 //规格的属性id attrsPropSku []*jdshopapi.CreateSkuParamAttrs ) valuesSku, maxNo, _ := api.JdShopAPI.FindValuesByAttrId(attrIDs["规格"]) specQuality := utils.Float64ToStr(float64(v.SpecQuality)) + v.SpecUnit for _, v := range valuesSku { if v.Name == specQuality { ggValueID = v.ID } } if ggValueID == 0 { //说明没有建这个规格,要建上 catID, _ := api.JdShopAPI.SaveVenderAttrValue(specQuality, attrIDs["规格"], int(storeSku.VendorVendorCatID), maxNo+1) ggValueID = catID } attrSku := &jdshopapi.CreateSkuParamAttrs{ AttrID: utils.Int2Str(attrIDs["规格"]), AttrValues: []string{utils.Int64ToStr(ggValueID)}, } attrsPropSku = append(attrsPropSku, attrSku) 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 createSkuParamSkus = append(createSkuParamSkus, sku) if v.VendorPrice > vendorPrice { vendorPrice = v.VendorPrice } if v.Status == model.SkuStatusNormal { sku.StockNum = 9999 } else { sku.StockNum = 0 } } createSkuParamWare.MarketPrice = jxutils.IntPrice2Standard(vendorPrice) return createSkuParamWare, createSkuParamSkus, err } //京东商城上传图片,若平台上已经有了这个图就直接拿来用了 func uploadImg(img, name, index string) (imgURL string, err error) { result, err := api.JdShopAPI.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 := api.JdShopAPI.UploadPicture(data, 0, name+index) if err != nil { return imgURL, err } imgURL = uploadResult.PictureURL } return imgURL, err } func uploadImg2(img, name, index string) (imgURL string, err error) { data, _, err := jxutils.DownloadFileByURL(img) if err != nil { return imgURL, err } uploadResult, err := api.JdShopAPI.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, err error) { updateSkusParam = &jdshopapi.UpdateSkusParam{ WareID: storeSku.JdsWareID, } attrIDs := make(map[string]int) attrs, err := api.JdShopAPI.FindAttrs(int(storeSku.VendorVendorCatID)) for _, v := range attrs { if v.Name == "规格" { attrIDs[v.Name] = v.ID } } var ( ggValueID int64 //规格的属性id attrsPropSku []*jdshopapi.CreateSkuParamAttrs skus []*jdshopapi.UpdateSkusParamSkus ) valuesSku, maxNo, _ := api.JdShopAPI.FindValuesByAttrId(attrIDs["规格"]) specQuality := utils.Float64ToStr(float64(v.SpecQuality)) + v.SpecUnit for _, v := range valuesSku { if v.Name == specQuality { ggValueID = v.ID } } if ggValueID == 0 { //说明没有建这个规格,要建上 catID, _ := api.JdShopAPI.SaveVenderAttrValue(specQuality, attrIDs["规格"], int(storeSku.VendorVendorCatID), maxNo+1) ggValueID = catID } attrSku := &jdshopapi.CreateSkuParamAttrs{ AttrID: utils.Int2Str(attrIDs["规格"]), AttrValues: []string{utils.Int64ToStr(ggValueID)}, } attrsPropSku = append(attrsPropSku, attrSku) 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), } sku.SaleAttrs = attrsPropSku if v.Status == model.SkuStatusNormal { sku.StockNum = "9999" } else { sku.StockNum = "0" } if !isCreate { result, err2 := api.JdShopAPI.FindSkuById(utils.Str2Int64(v.VendorSkuID)) err = err2 if specQuality != result.SaleAttrs[0].AttrValueAlias[0] { api.JdShopAPI.DeleteSku(utils.Str2Int64(v.VendorSkuID)) } } skus = append(skus, sku) updateSkusParam.Skus = skus return updateSkusParam, err }