/// <summary> /// 更新图片 /// </summary> /// <param name="input"></param> /// <param name="product"></param> private static void CreateOrUpdateProductPictures(CreateOrUpdateProductInput input, Product product) { //删除不存在的图片 var existItemIds = input.Pictures.Select(i => i.Id); var itemsId2Remove = product.Pictures.Where(i => !existItemIds.Contains(i.PictureId)).ToList(); foreach (var item in itemsId2Remove) { product.Pictures.Remove(item); } //添加或更新图片 var displayOrder = 0; foreach (var itemInput in input.Pictures) { var item = product.Pictures.FirstOrDefault(x => x.PictureId == itemInput.Id); if (item != null) { item.DisplayOrder = ++displayOrder; } else { product.Pictures.Add(new ProductPicture() { PictureId = itemInput.Id, DisplayOrder = ++displayOrder }); } } }
/// <summary> /// 更新分类 /// </summary> /// <param name="input"></param> /// <param name="product"></param> private static void CreateOrUpdateCategories(CreateOrUpdateProductInput input, Product product) { //删除不存在的分类 var existItemIds = input.Categories.Select(i => i.Id); var itemsId2Remove = product.Categories.Where(i => !existItemIds.Contains(i.CategoryId)).ToList(); foreach (var item in itemsId2Remove) { product.Categories.Remove(item); } //添加或更新分类 foreach (var itemInput in input.Categories) { var item = product.Categories.FirstOrDefault(x => x.CategoryId == itemInput.Id); if (item != null) { continue; } else { product.Categories.Add(new ProductCategory() { CategoryId = itemInput.Id, }); } } }
public async Task <long> CreateOrUpdateProduct(CreateOrUpdateProductInput input) { long value; if (!input.Product.Id.HasValue) { long num = await this._productRepository.InsertAndGetIdAsync(input.Product.MapTo <Product>()); value = num; } else { value = input.Product.Id.Value; await this._productRepository.UpdateAsync(input.Product.MapTo <Product>()); } if (input.Product.ProductOptions.Any <ProductOption>()) { foreach (ProductOption productOption in input.Product.ProductOptions) { if (productOption.Name.IsNullOrEmpty() && productOption.Comment.IsNullOrEmpty() && productOption.Value.IsNullOrEmpty()) { continue; } productOption.ProductId = value; await this._productOptionRepository.InsertOrUpdateAsync(productOption); } } return(value); }
/// <summary> /// 创建或更新属性组合 /// </summary> /// <param name="input"></param> /// <param name="product"></param> /// <returns></returns> private async Task CreateOrUpdateAttributeCombination(CreateOrUpdateProductInput input, Product product) { if (input.Id == null || input.Id == 0) { product.AttributeCombinations = new Collection <ProductAttributeCombination>(); } else { var existItemIds = input.AttributeCombinations.Select(i => i.Id); var itemsId2Remove = product.AttributeCombinations.Where(i => !existItemIds.Contains(i.Id)).ToList(); //删除不存在的属性 foreach (var item in itemsId2Remove) { item.IsDeleted = true; product.AttributeCombinations.Remove(item); } } var displayOrder = 0; foreach (var combinDto in input.AttributeCombinations) { // sku去重 if (combinDto.Sku.IsNullOrWhiteSpace()) { await IsCombinSkuExisted(input, combinDto); } ProductAttributeCombination combin = null; var attributesJson = JsonConvert.SerializeObject(combinDto.Attributes .GetAttributesJson(product, _productAttributeManager, true)); if (input.Id != 0) { combin = product.AttributeCombinations.FirstOrDefault(c => c.Id == combinDto.Id || c.AttributesJson == attributesJson); } if (combin == null) { combin = new ProductAttributeCombination(); } combin.AttributesJson = attributesJson; combin.Sku = combinDto.Sku; combin.ThirdPartySku = combinDto.ThirdPartySku; combin.OverriddenPrice = combinDto.OverriddenPrice; combin.OverriddenGoodCost = combinDto.OverriddenGoodCost; combin.StockQuantity = combinDto.StockQuantity; combin.DisplayOrder = displayOrder; if (combin.Id == 0) { product.AttributeCombinations.Add(combin); } } }
/// <summary> /// 添加或者修改Product的公共方法 /// </summary> /// <param name="input"></param> /// <returns></returns> public async Task CreateOrUpdateProduct(CreateOrUpdateProductInput input) { if (input.Product.Id.HasValue) { await UpdateProductAsync(input.Product); } else { await CreateProductAsync(input.Product); } }
public async Task SaveProductAsync(CreateOrUpdateProductInput input) { if (input.ProductEditDto.Id.HasValue) { await UpdateProductAsync(input.ProductEditDto); } else { await CreateProductAsync(input.ProductEditDto); } }
/// <summary> /// 创建或者更新属性 /// </summary> /// <param name="input"></param> /// <param name="product"></param> /// <returns></returns> private async Task CreateOrUpdateProductAttributes(CreateOrUpdateProductInput input, Product product) { if (product.Id == 0) { product.Attributes = new Collection <ProductAttributeMapping>(); } else { var existItemIds = input.Attributes.Select(i => i.Id).ToList(); var itemsId2Remove = product.Attributes.Where(i => !existItemIds.Contains(i.ProductAttributeId)).ToList(); //删除不存在的属性 foreach (var item in itemsId2Remove) { item.IsDeleted = true; product.Attributes.Remove(item); } } //添加或更新属性 int displayOrder = 0; foreach (var attributeDto in input.Attributes) { ProductAttributeMapping attributeMapping = null; if (product.Id != 0) { attributeMapping = product.Attributes.FirstOrDefault(a => a.ProductAttributeId == attributeDto.Id); } if (attributeMapping == null) { // 属性关联 attributeMapping = new ProductAttributeMapping() { ProductAttributeId = attributeDto.Id, DisplayOrder = ++displayOrder, Values = new Collection <ProductAttributeValue>() }; product.Attributes.Add(attributeMapping); } else { attributeMapping.DisplayOrder = ++displayOrder; } //添加或更新属性值 await CreateOrUpdateProductAttributeValues(attributeMapping, attributeDto); } }
public async Task <EntityDto <long> > CreateOrUpdateProduct(CreateOrUpdateProductInput input) { if (input.Id.HasValue && input.Id.Value > 0) { await UpdateProductAsync(input); return(new EntityDto <long>() { Id = input.Id.Value }); } else { return(await CreateProductAsync(input)); } }
protected virtual async Task <EntityDto <long> > CreateProductAsync(CreateOrUpdateProductInput input) { var product = ObjectMapper.Map <Product>(input); if (input.Categories != null) { product.Categories = input.Categories.Select(i => { return(new ProductCategory() { CategoryId = i.Id, }); }).ToList(); } if (input.Pictures != null) { int displayOrder = 0; product.Pictures = input.Pictures.Select(i => { return(new ProductPicture() { PictureId = i.Id, DisplayOrder = ++displayOrder, ProductId = input.Id ?? 0, }); }).ToList(); } await CreateOrUpdateProductAttributes(input, product); await _productManager.CreateAsync(product); await CreateOrUpdateAttributeCombination(input, product); await _productManager.UpdateWithRelateAttributeAsync(product); await CurrentUnitOfWork.SaveChangesAsync(); return(new EntityDto <long>() { Id = product.Id }); }
protected virtual async Task UpdateProductAsync(CreateOrUpdateProductInput input) { var product = await _productManager.FindByIdAsync(input.Id.Value); await _productManager.ProductRepository.EnsureCollectionLoadedAsync(product, t => t.Categories); await _productManager.ProductRepository.EnsureCollectionLoadedAsync(product, t => t.Pictures); await _productManager.ProductRepository.EnsureCollectionLoadedAsync(product, t => t.Attributes); await _productManager.ProductRepository.EnsureCollectionLoadedAsync(product, t => t.AttributeCombinations); // 更新基础属性 product.Name = input.Name; product.ShortDescription = input.ShortDescription; product.Price = input.Price; product.GoodCost = input.GoodCost; product.Sku = input.Sku; product.ThirdPartySku = input.ThirdPartySku; product.StockQuantity = input.StockQuantity; product.Height = input.Height; product.Weight = input.Weight; product.Width = input.Width; product.Length = input.Length; product.NotifyQuantityBelow = input.NotifyQuantityBelow; product.FullDescription = input.FullDescription; CreateOrUpdateProductPictures(input, product); await CreateOrUpdateProductAttributes(input, product); // 执行保存 await _productManager.UpdateAsync(product); await CurrentUnitOfWork.SaveChangesAsync(); await CreateOrUpdateAttributeCombination(input, product); await _productManager.UpdateWithRelateAttributeAsync(product); }
/// <summary> /// Sku 是否已存在 /// </summary> /// <param name="input"></param> /// <param name="combinDto"></param> /// <returns></returns> private async Task IsCombinSkuExisted(CreateOrUpdateProductInput input, AttributeCombinationDto combinDto) { // sku重复性判断 var existedCombin = await _productAttributeManager.FindCombinationBySkuAsync(combinDto.Sku); if (existedCombin != null && combinDto.Sku == existedCombin.Sku) { // 重复sku是否在同一个商品中 if (existedCombin.ProductId != input.Id) { throw new UserFriendlyException($"Sku : {combinDto.Sku} 已存在"); } // 已存在的sku是否发生改变 var existedCombinDto = input.AttributeCombinations .FirstOrDefault(a => a.Id == existedCombin.Id); if (existedCombinDto.Sku == existedCombin.Sku) { throw new UserFriendlyException($"Sku : {combinDto.Sku} 已存在"); } } }
/// <summary> /// 商品信息同步 /// </summary> /// <returns></returns> public async Task ProductSync() { string reqURL = "http://commerce.vapps.com.cn/catalog/CategoryProductJsons?categoryId=0&PageSize=1000"; var httpClient = new HttpClient(); CacheControlHeaderValue cacheControl = new CacheControlHeaderValue(); cacheControl.NoCache = true; cacheControl.NoStore = true; httpClient.DefaultRequestHeaders.CacheControl = cacheControl; try { var response = await httpClient.GetAsync(new Uri(reqURL)); var jsonResultString = await response.Content.ReadAsStringAsync(); JObject products = ((JObject)JToken.Parse(jsonResultString)["data"]); //return value; var productList = products["Data"].ToList().OrderBy(p => p["Id"]); foreach (JObject productJson in productList) { var productDetailResponse = await httpClient.GetAsync(new Uri($"http://commerce.vapps.com.cn/product/ProductDetailJson?productId={productJson["Id"]}")); var productDetailJsonResultString = await productDetailResponse.Content.ReadAsStringAsync(); JObject productsDetail = (JObject)JToken.Parse(productDetailJsonResultString)["data"]; var sku = productsDetail["Sku"].ToString(); var product = await _productManager.FindBySkuAsync(sku); if (product != null) { continue; } var productDto = new CreateOrUpdateProductInput() { Name = productsDetail["Name"].ToString(), Price = Decimal.Parse(productsDetail["ProductPrice"]["PriceValue"].ToString()), GoodCost = Decimal.Parse(productsDetail["ProductPrice"]["Cost"].ToString()), //Height = Decimal.Parse(productsDetail["Height"].ToString().IsNullOrWhiteSpace() ? "0" : productsDetail["Height"].ToString()), //Weight = Decimal.Parse(productsDetail["Weight"].ToString().IsNullOrWhiteSpace() ? "0" : productsDetail["Weight"].ToString()), //Width = Decimal.Parse(productsDetail["Width"].ToString().IsNullOrWhiteSpace() ? "0" : productsDetail["Width"].ToString()), //Length = Decimal.Parse(productsDetail["Length"].ToString().IsNullOrWhiteSpace() ? "0" : productsDetail["Length"].ToString()), Sku = sku, StockQuantity = 0, ShortDescription = productsDetail["ShortDescription"].ToString(), }; // 同步分类 var categoryJsons = productsDetail["Breadcrumb"]["CategoryBreadcrumb"]; if (!categoryJsons.IsNullOrEmpty()) { foreach (JObject categoryJson in categoryJsons.ToList()) { var categoryName = categoryJson["Name"].ToString(); var category = await _categoryManager.FindByNameAsync(categoryName); if (category == null) { category = new Category() { Name = categoryName, } } ; if (category.Id == 0) { await _categoryManager.CreateAsync(category); await CurrentUnitOfWork.SaveChangesAsync(); } productDto.Categories.Add(new ProductCategoryDto() { Id = category.Id }); } } // 图片 var defaultPictureUrl = ((JObject)productsDetail["DefaultPictureModel"])["FullSizeImageUrl"].ToString(); if (!defaultPictureUrl.IsNullOrWhiteSpace()) { var picture = await _pictureManager.FetchPictureAsync(defaultPictureUrl, (long)DefaultGroups.ProductPicture); productDto.Pictures.Add(new ProductPictureDto() { Id = picture.Id, }); } //商品属性 var attributeJsons = productsDetail["ProductAttributes"]; if (!attributeJsons.IsNullOrEmpty()) { foreach (JObject attributeJson in attributeJsons.ToList()) { var attributeName = attributeJson["Name"].ToString(); // 属性值 var attributeValueJsons = attributeJson["Values"]; if (attributeValueJsons.IsNullOrEmpty()) { continue; } var attribute = await _productAttributeManager.FindByNameAsync(attributeName); if (attribute == null) { attribute = new ProductAttribute() { Name = attributeName, }; await _productAttributeManager.CreateAsync(attribute); await CurrentUnitOfWork.SaveChangesAsync(); } var attributeDto = new ProductAttributeDto() { Id = attribute.Id, Name = attributeJson["Id"].ToString() }; // 属性值 foreach (JObject attributeValueJson in attributeValueJsons.ToList()) { var attributeValueName = attributeValueJson["Name"].ToString(); var pAttributeValue = await _productAttributeManager.FindPredefinedValueByNameAsync(attribute.Id, attributeValueName); if (pAttributeValue == null) { pAttributeValue = new PredefinedProductAttributeValue() { Name = attributeValueName, ProductAttributeId = attribute.Id, }; await _productAttributeManager.CreateOrUpdatePredefinedValueAsync(pAttributeValue); await CurrentUnitOfWork.SaveChangesAsync(); } attributeDto.Values.Add(new ProductAttributeValueDto() { Id = pAttributeValue.Id, Name = attributeValueJson["Id"].ToString(), PictureUrl = attributeValueJson["CostAdjustment"].ToString(), }); } productDto.Attributes.Add(attributeDto); } } // 属性组合 if (!productDto.Attributes.IsNullOrEmpty()) { for (int index = 0; index < productDto.Attributes[0].Values.Count; index++) { var deserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace }; var attribute = JsonConvert.DeserializeObject <ProductAttributeDto>(JsonConvert.SerializeObject(productDto.Attributes[0]), deserializeSettings); attribute.Values = new List <ProductAttributeValueDto>(); attribute.Values.Add(productDto.Attributes[0].Values[index]); //var combin = new AttributeCombinationDto(); //combin.Attributes.Add(attribute); if (productDto.Attributes.Count() >= 2) { for (int i = 0; i < productDto.Attributes[1].Values.Count; i++) { var attribute1 = JsonConvert.DeserializeObject <ProductAttributeDto>(JsonConvert.SerializeObject(productDto.Attributes[1]), deserializeSettings); attribute1.Values = new List <ProductAttributeValueDto>(); attribute1.Values.Add(productDto.Attributes[1].Values[i]); if (productDto.Attributes.Count() >= 3) { for (int j = 0; j < productDto.Attributes[2].Values.Count; j++) { var attribute2 = JsonConvert.DeserializeObject <ProductAttributeDto>(JsonConvert.SerializeObject(productDto.Attributes[2]), deserializeSettings); attribute2.Values = new List <ProductAttributeValueDto>(); attribute2.Values.Add(productDto.Attributes[2].Values[j]); var combin = new AttributeCombinationDto(); combin.Attributes.Add(attribute); combin.Attributes.Add(attribute1); combin.Attributes.Add(attribute2); productDto.AttributeCombinations.Add(combin); } } else { var combin = new AttributeCombinationDto(); combin.Attributes.Add(attribute); combin.Attributes.Add(attribute1); productDto.AttributeCombinations.Add(combin); } } } else { var combin = new AttributeCombinationDto(); combin.Attributes.Add(attribute); productDto.AttributeCombinations.Add(combin); } } } string combinURL = "http://commerce.vapps.com.cn/product/GetStockByDropAndDropJson"; foreach (var combin in productDto.AttributeCombinations) { var para = combin.Attributes.Select(c => { return(new { ProductAttrbuteId = Convert.ToInt32(c.Name), ProductAttrbuteValueId = Convert.ToInt32(c.Values[0].Name) }); }).ToList(); var data = new { productId = Convert.ToInt32(productsDetail["Id"].ToString()), paramDictionary = para }; HttpContent content = new StringContent(JsonConvert.SerializeObject(data)); content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); var combinResponse = await httpClient.PostAsync(new Uri(combinURL), content); var combinJsonResultString = await combinResponse.Content.ReadAsStringAsync(); if (combinJsonResultString.IsNullOrWhiteSpace()) { continue; } JObject combinDetail = ((JObject)JToken.Parse(combinJsonResultString)); combin.Sku = combinDetail["Sku"].ToString(); if (!combin.Attributes[0].Values[0].PictureUrl.IsNullOrWhiteSpace()) { combin.OverriddenGoodCost = decimal.Parse(combin.Attributes[0].Values[0].PictureUrl); } } await CreateOrUpdateProduct(productDto); } } catch (Exception ex) { } finally { httpClient.Dispose(); } }