1241 lines
51 KiB
C#
1241 lines
51 KiB
C#
using Atomx.Admin.Client.Models;
|
||
using Atomx.Admin.Services;
|
||
using Atomx.Common.Entities;
|
||
using Atomx.Common.Enums;
|
||
using Atomx.Common.Models;
|
||
using Atomx.Data;
|
||
using Atomx.Data.Services;
|
||
using Atomx.Utils.Extension;
|
||
using Atomx.Utils.Json;
|
||
using FluentValidation;
|
||
using Mapster;
|
||
using MapsterMapper;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.Extensions.Localization;
|
||
|
||
namespace Atomx.Admin.Controllers
|
||
{
|
||
[Route("api/[controller]")]
|
||
[ApiController]
|
||
public class ProductController : ControllerBase
|
||
{
|
||
readonly ILogger<ProductController> _logger;
|
||
readonly IIdentityService _identityService;
|
||
readonly IIdCreatorService _idCreator;
|
||
readonly IMapper _mapper;
|
||
readonly DataContext _dbContext;
|
||
readonly IValidator<ProductModel> _validator;
|
||
readonly IStringLocalizer<ProductController> _localizer;
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="logger"></param>
|
||
/// <param name="identityService"></param>
|
||
/// <param name="idCreator"></param>
|
||
/// <param name="adminService"></param>
|
||
/// <param name="mapper"></param>
|
||
public ProductController(ILogger<ProductController> logger, IIdentityService identityService, IIdCreatorService idCreator, IMapper mapper, DataContext dataContext,
|
||
IValidator<ProductModel> validator, IStringLocalizer<ProductController> localizer )
|
||
{
|
||
_logger = logger;
|
||
_identityService = identityService;
|
||
_idCreator = idCreator;
|
||
_mapper = mapper;
|
||
_dbContext = dataContext;
|
||
_validator = validator;
|
||
_localizer = localizer;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询接口
|
||
/// </summary>
|
||
/// <param name="search"></param>
|
||
/// <param name="page"></param>
|
||
/// <param name="size"></param>
|
||
/// <returns></returns>
|
||
[HttpPost("search")]
|
||
|
||
public IActionResult Search(ProductSearch search, int page, int size = 20)
|
||
{
|
||
var result = new ApiResult<PagingList<Product>>();
|
||
try
|
||
{
|
||
var pager = new PagingList<Product>() { Size = size, Index = page < 1 ? 1 : page };
|
||
|
||
var query = from p in _dbContext.Products
|
||
select p;
|
||
|
||
pager.Count = query.Count();
|
||
|
||
pager.Items = query.OrderByDescending(p => p.Id).Skip((pager.Index - 1) * size).Take(size).ToList();
|
||
result = result.IsSuccess(pager);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result = result.IsFail(ex.Message);
|
||
_logger.LogError(ex.Message);
|
||
}
|
||
return new JsonResult(result);
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 查询接口
|
||
/// </summary>
|
||
/// <param name="search"></param>
|
||
/// <param name="page"></param>
|
||
/// <param name="size"></param>
|
||
/// <returns></returns>
|
||
[HttpPost("stock/search")]
|
||
|
||
public IActionResult StockUnitSearch(ProductStockUnitSearch search, int page, int size = 20)
|
||
{
|
||
var result = new ApiResult<PagingList<ProductStockUnitModel>>();
|
||
try
|
||
{
|
||
List<MiniProductModel> products = new();
|
||
|
||
if (search.Type == 1)
|
||
{
|
||
if (string.IsNullOrEmpty(search.Key))
|
||
{
|
||
var productQuery = from p in _dbContext.Products
|
||
where p.Status == 1 && p.Title.Contains(search.Key)
|
||
select new MiniProductModel
|
||
{
|
||
Id = p.Id,
|
||
Title = p.Title,
|
||
Image = p.Image
|
||
};
|
||
products = productQuery.Take(100).ToList();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (search.Key.ToLong() > 0)
|
||
{
|
||
var productQuery = from p in _dbContext.Products
|
||
where p.Status == 1 && p.Id == search.Key.ToLong()
|
||
select new MiniProductModel
|
||
{
|
||
Id = p.Id,
|
||
Title = p.Title,
|
||
Image = p.Image
|
||
};
|
||
products = productQuery.Take(100).ToList();
|
||
}
|
||
}
|
||
|
||
var productIds = products.Select(p => p.Id).ToList();
|
||
var pager = new PagingList<ProductStockUnitModel>() { Size = size, Index = page < 1 ? 1 : page };
|
||
|
||
var query = from p in _dbContext.ProductAttributeCombinations
|
||
select p;
|
||
|
||
if (products.Any())
|
||
{
|
||
query = from p in query
|
||
where productIds.Contains(p.ProductId)
|
||
select p;
|
||
}
|
||
|
||
if (search.Weight > 0)
|
||
{
|
||
query = query.Where(p => p.Weight == search.Weight);
|
||
}
|
||
|
||
pager.Count = query.Count();
|
||
|
||
var list = query.OrderByDescending(p => p.UpdateTime).Skip((pager.Index - 1) * size).Take(size).ToList();
|
||
|
||
List<ProductStockUnitModel> stockUnits = new();
|
||
foreach (var item in list)
|
||
{
|
||
var data = _mapper.Map<ProductStockUnitModel>(item);
|
||
if (products.Any())
|
||
{
|
||
var product = products.SingleOrDefault(p => p.Id == item.ProductId);
|
||
if (product != null)
|
||
{
|
||
data.Title = product.Title;
|
||
data.Image = product.Image;
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
var product = _dbContext.Products.SingleOrDefault(p => p.Id == item.ProductId);
|
||
if (product != null)
|
||
{
|
||
data.Title = product.Title;
|
||
data.Image = product.Image;
|
||
}
|
||
}
|
||
if (!string.IsNullOrEmpty(data.AttributesJson))
|
||
{
|
||
data.Sku = data.AttributesJson.FromJson<List<ProductSkuModel>>();
|
||
foreach (var sku in data.Sku)
|
||
{
|
||
if (sku.Weight > 0)
|
||
{
|
||
data.WeightUnit = sku.WeightUnit;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
stockUnits.Add(data);
|
||
}
|
||
|
||
pager.Items = stockUnits;
|
||
result = result.IsSuccess(pager);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result = result.IsFail(ex.Message);
|
||
_logger.LogError(ex.Message);
|
||
}
|
||
return new JsonResult(result);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据id获取数据
|
||
/// </summary>
|
||
/// <param name="id"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("{id:long}")]
|
||
public IActionResult Get(long id)
|
||
{
|
||
var result = new ApiResult<Product>();
|
||
try
|
||
{
|
||
var data = _dbContext.Products.Where(p => p.Id == id).SingleOrDefault();
|
||
result = result.IsSuccess(data);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result = result.IsFail(ex.Message);
|
||
_logger.LogError(ex.Message);
|
||
}
|
||
return new JsonResult(result);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取商品详情
|
||
/// </summary>
|
||
/// <param name="id"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("detail/{id:long}")]
|
||
public IActionResult Detail(long id)
|
||
{
|
||
var result = new ApiResult<ProductModel>();
|
||
var product = _dbContext.Products.SingleOrDefault(p => p.Id == id);
|
||
if (product == null)
|
||
{
|
||
return new JsonResult(result);
|
||
}
|
||
var attributeCombinations = _dbContext.ProductAttributeCombinations.Where(p => p.ProductId == id).ToList();
|
||
var attributeRelations = _dbContext.ProductAttributeRelations.Where(p => p.ProductId == id).ToList();
|
||
var attributeValues = _dbContext.ProductAttributeValues.Where(p => p.ProductId == id).ToList();
|
||
|
||
|
||
var productAttributeCombinationList = new List<ProductAttributeCombinationModel>();
|
||
foreach (var item in attributeCombinations)
|
||
{
|
||
var attribute = item.AttributesJson.FromJson<List<ProductSkuModel>>();
|
||
var sku = new ProductAttributeCombinationModel()
|
||
{
|
||
Enabled = item.Enabled,
|
||
Id = item.Id,
|
||
MarketPrice = item.MarketPrice,
|
||
Price = item.Price,
|
||
ProductId = item.ProductId,
|
||
SalesQuantity = item.SalesQuantity,
|
||
SkuNumber = item.SkuNumber,
|
||
SkuAttributes = attribute,
|
||
StockQuantity = item.StockQuantity,
|
||
Weight = item.Weight,
|
||
WeightUnit = item.WeightUnit,
|
||
ManufacturerId = item.ManufacturerId,
|
||
ProcessCharge = item.ProcessCharge,
|
||
ProcessCost = item.ProcessCost,
|
||
Surcharge = item.Surcharge,
|
||
SurchargeCost = item.SurchargeCost
|
||
};
|
||
productAttributeCombinationList.Add(sku);
|
||
}
|
||
|
||
var productSaleAttributes = new List<ProductSaleAttributeModel>();
|
||
int index = 0;
|
||
long skuPhotoAttributeId = 0;
|
||
foreach (var item in attributeRelations)
|
||
{
|
||
var values = (from p in attributeValues
|
||
where p.ProductAttributeRelationId == item.Id
|
||
select new ProductAttributeValueModel()
|
||
{
|
||
Id = p.Id,
|
||
Image = p.Image,
|
||
Name = p.Name,
|
||
OptionId = p.OptionId,
|
||
DisplayOrder = p.DisplayOrder,
|
||
IsAddWeight = p.IsAddWeight,
|
||
IsEdit = false,
|
||
ProductAttributeRelationId = p.ProductAttributeRelationId,
|
||
ProductId = p.ProductId,
|
||
Weight = p.Weight.RemoveTrailingZeros().ToDecimal(),
|
||
WeightUnit = p.WeightUnit
|
||
}).ToList();
|
||
if (item.Image)
|
||
{
|
||
skuPhotoAttributeId = item.AttributeId;
|
||
}
|
||
var attributeTree = _dbContext.ProductAttributes.SingleOrDefault(p => p.Id == item.AttributeId);
|
||
|
||
var saleAttribute = new ProductSaleAttributeModel()
|
||
{
|
||
Id = item.Id,
|
||
AttributeId = item.AttributeId,
|
||
Name = attributeTree?.Name ?? "",
|
||
Image = item.Image,
|
||
AddAttribute = false,
|
||
DisplayOrder = index,
|
||
InputText = string.Empty,
|
||
SelectOption = string.Empty,
|
||
ProductAttributeValues = values,
|
||
ControlType = attributeTree?.ControlType ?? 0,
|
||
IsRequired = attributeTree?.IsRequired ?? false,
|
||
WeightIsRequired = attributeTree?.WeightIsRequired ?? false,
|
||
};
|
||
productSaleAttributes.Add(saleAttribute);
|
||
index++;
|
||
}
|
||
|
||
var data = _mapper.Map<ProductModel>(product);
|
||
|
||
|
||
data.ProductAttributeCombinations = productAttributeCombinationList;
|
||
data.ProductSaleAttributes = productSaleAttributes;
|
||
|
||
|
||
//if (!string.IsNullOrEmpty(product.Photos))
|
||
//{
|
||
// var photos = product.Photos.FromJson<ProductPhotosModel>();
|
||
// if (photos != null)
|
||
// {
|
||
// data.ProductPhotos = photos;
|
||
// }
|
||
//}
|
||
//data.SkuPhotoAttributeId = skuPhotoAttributeId;
|
||
|
||
result = result.IsSuccess(data);
|
||
|
||
return new JsonResult(result);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 新增数据
|
||
/// </summary>
|
||
/// <param name="model"></param>
|
||
/// <returns></returns>
|
||
[HttpPost("add")]
|
||
public IActionResult Add(ProductModel model)
|
||
{
|
||
|
||
var result = new ApiResult<string>();
|
||
var validation = _validator.Validate(model);
|
||
if (!validation.IsValid)
|
||
{
|
||
var message = validation.Errors.FirstOrDefault()?.ErrorMessage ?? string.Empty;
|
||
result = result.IsFail(message, null);
|
||
return new JsonResult(result);
|
||
}
|
||
|
||
try
|
||
{
|
||
model.Id = _idCreator.CreateId();
|
||
var product = _mapper.Map<Product>(model);
|
||
product.CreateTime = DateTime.UtcNow;
|
||
|
||
var productAttributeRelations = new List<ProductAttributeRelation>();
|
||
var productSalesAttributeValues = new List<ProductAttributeValue>();
|
||
var productAttributeCombinations = new List<ProductAttributeCombination>();
|
||
var productInventories = new List<ProductInventory>();
|
||
var productInventroryLogs = new List<ProductInventoryLog>();
|
||
|
||
foreach (var item in model.ProductSaleAttributes)
|
||
{
|
||
var attributeRelated = new ProductAttributeRelation()
|
||
{
|
||
AttributeId = item.AttributeId,
|
||
DisplayOrder = 0,
|
||
ProductId = product.Id,
|
||
Image = item.Image,
|
||
Id = _idCreator.CreateId()
|
||
};
|
||
|
||
foreach (var value in item.ProductAttributeValues)
|
||
{
|
||
//处理销售属性值
|
||
var data = productSalesAttributeValues.SingleOrDefault(p => p.OptionId == value.OptionId && p.Name == value.Name && p.Weight == value.Weight);
|
||
if (data == null)
|
||
{
|
||
var attributeValue = new ProductAttributeValue()
|
||
{
|
||
ProductAttributeRelationId = attributeRelated.Id,
|
||
DisplayOrder = value.DisplayOrder,
|
||
Id = _idCreator.CreateId(),
|
||
Name = value.Name,
|
||
OptionId = value.OptionId,
|
||
ProductId = product.Id,
|
||
Image = value.Image,
|
||
WeightUnit = value.WeightUnit,
|
||
Weight = value.Weight.RemoveTrailingZeros().ToDecimal(),
|
||
IsAddWeight = value.IsAddWeight
|
||
};
|
||
if (!string.IsNullOrEmpty(value.Image))
|
||
{
|
||
attributeRelated.Image = true;
|
||
}
|
||
|
||
foreach (var sku in model.ProductAttributeCombinations)
|
||
{
|
||
var skuAttribute = sku.SkuAttributes.SingleOrDefault(p => p.ValueName == attributeValue.Name && p.Weight == attributeValue.Weight);
|
||
if (skuAttribute != null)
|
||
{
|
||
skuAttribute.ValueId = attributeValue.Id;
|
||
}
|
||
}
|
||
|
||
productSalesAttributeValues.Add(attributeValue);
|
||
}
|
||
}
|
||
productAttributeRelations.Add(attributeRelated);
|
||
}
|
||
|
||
foreach (var item in model.ProductAttributeCombinations)
|
||
{
|
||
var data = _mapper.Map<ProductAttributeCombination>(item);
|
||
data.AttributesJson = item.SkuAttributes.ToJson();
|
||
data.Id = _idCreator.CreateId();
|
||
data.ProductId = product.Id;
|
||
data.UpdateTime = DateTime.UtcNow;
|
||
|
||
productAttributeCombinations.Add(data);
|
||
}
|
||
|
||
if (productAttributeCombinations.Count > 0)
|
||
{
|
||
var skuPrices = new List<ProductSKUPricesModel>();
|
||
foreach (var item in productAttributeCombinations)
|
||
{
|
||
var prices = new ProductSKUPricesModel()
|
||
{
|
||
Id = item.Id,
|
||
MarketPrice = item.MarketPrice,
|
||
Price = item.Price,
|
||
};
|
||
skuPrices.Add(prices);
|
||
|
||
if (item.StockQuantity > 0)
|
||
{
|
||
var inventory = new ProductInventory()
|
||
{
|
||
CorporationId = item.CorporationId,
|
||
StockQuantity = item.StockQuantity,
|
||
CreateTime = DateTime.UtcNow,
|
||
Id = _idCreator.CreateId(),
|
||
ProductAttributeCombinationId = item.Id,
|
||
ProductId = item.ProductId,
|
||
WarehouseId = 0
|
||
};
|
||
productInventories.Add(inventory);
|
||
var inventorylog = new ProductInventoryLog()
|
||
{
|
||
WarehouseId = 0,
|
||
ProductId = item.ProductId,
|
||
ProductAttributeCombinationId = item.Id,
|
||
Id = _idCreator.CreateId(),
|
||
AfterStock = item.StockQuantity,
|
||
BeforeStock = 0,
|
||
ChangeAmount = item.StockQuantity,
|
||
CorporationId = item.CorporationId,
|
||
CreateTime = DateTime.UtcNow,
|
||
ManufacturerId = item.ManufacturerId,
|
||
Note = string.Empty,
|
||
Operator = _identityService.GetUserId(),
|
||
OrderId = 0,
|
||
StoreId = 0,
|
||
Type = (int)ProductInventoryChangeType.Initial,
|
||
Weight = item.Weight.RemoveTrailingZeros().ToDecimal()
|
||
};
|
||
productInventroryLogs.Add(inventorylog);
|
||
}
|
||
}
|
||
var stockQuantity = productAttributeCombinations.Where(p => !p.Enabled).Sum(p => p.StockQuantity);
|
||
|
||
product.SkuPrices = skuPrices.ToJson();
|
||
product.StockQuantity = stockQuantity;
|
||
}
|
||
|
||
|
||
|
||
|
||
using (var transaction = _dbContext.Database.BeginTransaction())
|
||
{
|
||
try
|
||
{
|
||
_dbContext.Products.Add(product);
|
||
if (productAttributeRelations.Count() > 0)
|
||
{
|
||
_dbContext.ProductAttributeRelations.AddRange(productAttributeRelations);
|
||
}
|
||
if (productSalesAttributeValues.Count() > 0)
|
||
{
|
||
_dbContext.ProductAttributeValues.AddRange(productSalesAttributeValues);
|
||
}
|
||
if (productAttributeCombinations.Count() > 0)
|
||
{
|
||
_dbContext.ProductAttributeCombinations.AddRange(productAttributeCombinations);
|
||
}
|
||
if (productInventories.Count() > 0)
|
||
{
|
||
_dbContext.ProductInventories.AddRange(productInventories);
|
||
}
|
||
if (productInventroryLogs.Count() > 0)
|
||
{
|
||
_dbContext.ProductInventoryLogs.AddRange(productInventroryLogs);
|
||
}
|
||
|
||
int count = _dbContext.SaveChanges();
|
||
transaction.Commit();
|
||
result = result.IsSuccess(count.ToString());
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
transaction.Rollback();
|
||
result.Success = false;
|
||
result.Message = ex.Message;
|
||
return new JsonResult(result);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result = result.IsFail(ex.Message);
|
||
_logger.LogError(ex.Message);
|
||
}
|
||
return new JsonResult(result);
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 编辑数据
|
||
/// </summary>
|
||
/// <param name="model"></param>
|
||
/// <returns></returns>
|
||
[HttpPost("edit")]
|
||
public IActionResult Edit(ProductModel model)
|
||
{
|
||
Console.WriteLine("编辑");
|
||
Console.WriteLine(model.ToJson());
|
||
|
||
var result = new ApiResult<string>();
|
||
var validation = _validator.Validate(model);
|
||
if (!validation.IsValid)
|
||
{
|
||
var message = validation.Errors.FirstOrDefault()?.ErrorMessage ?? string.Empty;
|
||
result = result.IsFail(message, null);
|
||
return new JsonResult(result);
|
||
}
|
||
|
||
var product = _dbContext.Products.SingleOrDefault(p => p.Id == model.Id);
|
||
|
||
if (product == null)
|
||
{
|
||
result.Message = "参数错误,产品数据不存在";
|
||
return new JsonResult(result);
|
||
}
|
||
|
||
model.Adapt(product);
|
||
|
||
var productAttributeRelations = new List<ProductAttributeRelation>();
|
||
var productProductAttributeValues = new List<ProductAttributeValue>();
|
||
var productAttributeCombination = new List<ProductAttributeCombination>();
|
||
var originalProductAttributeRelasions = _dbContext.ProductAttributeRelations.Where(p => p.ProductId == model.Id).ToList();
|
||
|
||
foreach (var item in model.ProductSaleAttributes)
|
||
{
|
||
var attributeRelation = originalProductAttributeRelasions.SingleOrDefault(p => p.AttributeId == item.AttributeId);
|
||
if (attributeRelation == null)
|
||
{
|
||
attributeRelation = new ProductAttributeRelation()
|
||
{
|
||
AttributeId = item.AttributeId,
|
||
DisplayOrder = 0,
|
||
ProductId = product.Id,
|
||
Image = item.Image,
|
||
Id = _idCreator.CreateId()
|
||
};
|
||
}
|
||
|
||
foreach (var value in item.ProductAttributeValues)
|
||
{
|
||
//更新属性值信息
|
||
|
||
var data = productProductAttributeValues.FirstOrDefault(p => p.OptionId == value.OptionId && p.Name == value.Name && p.Weight == value.Weight);
|
||
if (data == null)
|
||
{
|
||
var attributeValue = new ProductAttributeValue()
|
||
{
|
||
ProductAttributeRelationId = attributeRelation.Id,
|
||
DisplayOrder = value.DisplayOrder,
|
||
Id = value.Id,
|
||
Name = value.Name,
|
||
OptionId = value.OptionId,
|
||
ProductId = product.Id,
|
||
Image = value.Image,
|
||
Weight = value.Weight.RemoveTrailingZeros().ToDecimal(),
|
||
IsAddWeight = value.IsAddWeight,
|
||
WeightUnit = value.WeightUnit
|
||
};
|
||
if (attributeValue.Id == 0)
|
||
{
|
||
attributeValue.Id = _idCreator.CreateId();
|
||
}
|
||
if (!string.IsNullOrEmpty(value.Image))
|
||
{
|
||
attributeRelation.Image = true;
|
||
}
|
||
else
|
||
{
|
||
attributeRelation.Image = false;
|
||
}
|
||
productProductAttributeValues.Add(attributeValue);
|
||
|
||
foreach (var sku in model.ProductAttributeCombinations)
|
||
{
|
||
var skuAttribute = sku.SkuAttributes.SingleOrDefault(p => p.ValueName == attributeValue.Name && p.Weight == attributeValue.Weight);
|
||
if (skuAttribute != null)
|
||
{
|
||
skuAttribute.ValueId = attributeValue.Id;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
productAttributeRelations.Add(attributeRelation);
|
||
}
|
||
|
||
foreach (var item in model.ProductAttributeCombinations)
|
||
{
|
||
//处理产品SKU组合信息
|
||
var data = _mapper.Map<ProductAttributeCombination>(item);
|
||
data.AttributesJson = item.SkuAttributes.ToJson();
|
||
if (data.Id == 0)
|
||
{
|
||
data.Id = _idCreator.CreateId();
|
||
data.ProductId = product.Id;
|
||
}
|
||
productAttributeCombination.Add(data);
|
||
}
|
||
|
||
|
||
var originalProductAttributeValues = _dbContext.ProductAttributeValues.Where(p => p.ProductId == model.Id).ToList();
|
||
var originalProductAttributeCombinations = _dbContext.ProductAttributeCombinations.Where(p => p.ProductId == model.Id).ToList();
|
||
|
||
|
||
var removeProductAttributeRelations = new List<ProductAttributeRelation>();
|
||
var removeProductAttributeValues = new List<ProductAttributeValue>();
|
||
var removeProductAttributeCombinations = new List<ProductAttributeCombination>();
|
||
|
||
|
||
//处理产品属性
|
||
foreach (var item in originalProductAttributeRelasions)
|
||
{
|
||
var data = productAttributeRelations.SingleOrDefault(p => p.Id == item.Id);
|
||
if (data == null)
|
||
{
|
||
removeProductAttributeRelations.Add(item);
|
||
}
|
||
}
|
||
|
||
//处理产品属性值
|
||
foreach (var item in originalProductAttributeValues)
|
||
{
|
||
var data = productProductAttributeValues.SingleOrDefault(p => p.Id == item.Id);
|
||
if (data == null)
|
||
{
|
||
removeProductAttributeValues.Add(item);
|
||
}
|
||
}
|
||
|
||
//处理SKU组合信息
|
||
foreach (var item in originalProductAttributeCombinations)
|
||
{
|
||
var data = productAttributeCombination.SingleOrDefault(p => p.Id == item.Id);
|
||
if (data == null)
|
||
{
|
||
removeProductAttributeCombinations.Add(item);
|
||
}
|
||
}
|
||
|
||
|
||
if (productAttributeCombination.Count > 0)
|
||
{
|
||
var skuPrices = new List<ProductSKUPricesModel>();
|
||
foreach (var item in productAttributeCombination)
|
||
{
|
||
var prices = new ProductSKUPricesModel()
|
||
{
|
||
Id = item.Id,
|
||
MarketPrice = item.MarketPrice,
|
||
Price = item.Price
|
||
};
|
||
skuPrices.Add(prices);
|
||
}
|
||
var stockQuantity = productAttributeCombination.Where(p => !p.Enabled).Sum(p => p.StockQuantity);
|
||
product.SkuPrices = skuPrices.ToJson();
|
||
product.StockQuantity = stockQuantity;
|
||
}
|
||
|
||
|
||
|
||
using (var transaction = _dbContext.Database.BeginTransaction())
|
||
{
|
||
try
|
||
{
|
||
_dbContext.Products.Update(product);
|
||
|
||
foreach (var item in productAttributeRelations)
|
||
{
|
||
var data = originalProductAttributeRelasions.SingleOrDefault(p => p.Id == item.Id);
|
||
if (data == null)
|
||
{
|
||
_dbContext.ProductAttributeRelations.Add(item);
|
||
}
|
||
else
|
||
{
|
||
data.Image = item.Image;
|
||
data.DisplayOrder = item.DisplayOrder;
|
||
_dbContext.ProductAttributeRelations.Update(data);
|
||
}
|
||
}
|
||
|
||
if (removeProductAttributeRelations.Count > 0)
|
||
{
|
||
_dbContext.ProductAttributeRelations.RemoveRange(removeProductAttributeRelations);
|
||
}
|
||
|
||
foreach (var item in productProductAttributeValues)
|
||
{
|
||
var data = originalProductAttributeValues.SingleOrDefault(p => p.Id == item.Id);
|
||
if (data == null)
|
||
{
|
||
_dbContext.ProductAttributeValues.Add(item);
|
||
}
|
||
else
|
||
{
|
||
data.Image = item.Image;
|
||
data.Name = item.Name;
|
||
data.Weight = item.Weight;
|
||
data.DisplayOrder = item.DisplayOrder;
|
||
_dbContext.ProductAttributeValues.Update(data);
|
||
}
|
||
}
|
||
|
||
if (removeProductAttributeValues.Count > 0)
|
||
{
|
||
_dbContext.RemoveRange(removeProductAttributeValues);
|
||
}
|
||
|
||
foreach (var item in productAttributeCombination)
|
||
{
|
||
var data = originalProductAttributeCombinations.SingleOrDefault(p => p.Id == item.Id);
|
||
if (data == null)
|
||
{
|
||
_dbContext.ProductAttributeCombinations.Add(item);
|
||
}
|
||
else
|
||
{
|
||
data.Enabled = item.Enabled;
|
||
data.MarketPrice = item.MarketPrice;
|
||
data.Price = item.Price;
|
||
data.AttributesJson = item.AttributesJson;
|
||
data.SalesQuantity = item.SalesQuantity;
|
||
data.SkuNumber = item.SkuNumber;
|
||
data.StockQuantity = item.StockQuantity;
|
||
data.UpdateTime = DateTime.UtcNow;
|
||
data.Weight = item.Weight;
|
||
|
||
|
||
_dbContext.ProductAttributeCombinations.Update(data);
|
||
}
|
||
}
|
||
|
||
if (removeProductAttributeCombinations.Count > 0)
|
||
{
|
||
_dbContext.RemoveRange(removeProductAttributeCombinations);
|
||
}
|
||
|
||
_dbContext.SaveChanges();
|
||
transaction.Commit();
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
transaction.Rollback();
|
||
result.Success = false;
|
||
result.Message = ex.Message;
|
||
return new JsonResult(result);
|
||
}
|
||
|
||
}
|
||
//await _cacheService.GetProductDetails(model.Id, true);
|
||
|
||
return new JsonResult(result);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除指定ID的数据
|
||
/// </summary>
|
||
/// <param name="id"></param>
|
||
/// <returns></returns>
|
||
[HttpPost("delete/{id:long}")]
|
||
public IActionResult Delete(long id)
|
||
{
|
||
var result = new ApiResult<string>();
|
||
|
||
Console.WriteLine($"{id} deleted");
|
||
#region
|
||
var skuCombinations = _dbContext.ProductAttributeCombinations.Where(p => p.ProductId == id).ToList();
|
||
var saleAttribute = _dbContext.ProductAttributeRelations.Where(p => p.ProductId == id).ToList();
|
||
var saleAttributeValues = _dbContext.ProductAttributeValues.Where(p => p.ProductId == id).ToList();
|
||
var product = _dbContext.Products.SingleOrDefault(p => p.Id == id);
|
||
var localiztion = _dbContext.LocalizedProperties.Where(p => p.EntityId == id).ToList();
|
||
|
||
var attributeRelate = _dbContext.ProductAttributeRelations.Where(p => p.ProductId == id).ToList();
|
||
|
||
List<long> attributeIds = new List<long>();
|
||
List<long> attributeValueIds = new List<long>();
|
||
if (attributeRelate != null && attributeRelate.Count > 0)
|
||
{
|
||
attributeIds = attributeRelate.Select(p => p.AttributeId).ToList();
|
||
}
|
||
if (saleAttributeValues != null && saleAttributeValues.Count > 0)
|
||
{
|
||
attributeValueIds = saleAttributeValues.Select(p => p.OptionId).ToList();
|
||
}
|
||
|
||
var skuAttributes = _dbContext.ProductAttributes.Where(p => attributeIds.Contains(p.Id)).ToList();
|
||
var skuAttributeValues = _dbContext.ProductAttributeOptions.Where(p => attributeValueIds.Contains(p.Id)).ToList();
|
||
|
||
using (var transaction = _dbContext.Database.BeginTransaction())
|
||
{
|
||
try
|
||
{
|
||
foreach (var item in skuAttributes)
|
||
{
|
||
item.Count = item.Count - 1;
|
||
}
|
||
foreach (var item in skuAttributeValues)
|
||
{
|
||
item.Count = item.Count - 1;
|
||
}
|
||
if (skuCombinations != null)
|
||
{
|
||
_dbContext.RemoveRange(skuCombinations);
|
||
}
|
||
if (saleAttributeValues != null)
|
||
{
|
||
_dbContext.RemoveRange(saleAttributeValues);
|
||
}
|
||
if (saleAttribute != null)
|
||
{
|
||
_dbContext.RemoveRange(saleAttribute);
|
||
}
|
||
if (product != null)
|
||
{
|
||
_dbContext.Remove(product);
|
||
}
|
||
if (skuAttributes != null)
|
||
{
|
||
_dbContext.UpdateRange(skuAttributes);
|
||
}
|
||
if (skuAttributeValues != null)
|
||
{
|
||
_dbContext.UpdateRange(skuAttributeValues);
|
||
}
|
||
if (localiztion.Any())
|
||
{
|
||
_dbContext.RemoveRange(localiztion);
|
||
}
|
||
|
||
var count = _dbContext.SaveChanges();
|
||
|
||
transaction.Commit();
|
||
|
||
//_cacheService.RemoveProduct(id);
|
||
result = result.IsSuccess(count.ToString());
|
||
return new JsonResult(result);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
transaction.Rollback();
|
||
result = result.IsFail(ex.Message);
|
||
return new JsonResult(result);
|
||
}
|
||
}
|
||
#endregion
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取商品的规格信息
|
||
/// </summary>
|
||
/// <param name="id"></param>
|
||
/// <returns></returns>
|
||
[HttpPost("attributes/{id:long}")]
|
||
public IActionResult GetAttributes(long id)
|
||
{
|
||
var result = new ApiResult<List<ProductStockAttributeModel>>();
|
||
|
||
var data = new List<ProductStockAttributeModel>();
|
||
|
||
var relations = _dbContext.ProductAttributeRelations.Where(p => p.ProductId == id).ToList();
|
||
List<long> attributeIds = relations.Select(p => p.AttributeId).ToList();
|
||
var attributes = _dbContext.ProductAttributes.Where(p => attributeIds.Contains(p.Id)).ToList();
|
||
var attributeValues = _dbContext.ProductAttributeValues.Where(p => p.ProductId == id).ToList();
|
||
|
||
foreach (var attribute in attributes)
|
||
{
|
||
var saleAttribute = _mapper.Map<ProductStockAttributeModel>(attribute);
|
||
saleAttribute.AttributeId = attribute.Id;
|
||
var relationIds = relations.Where(p => p.AttributeId == attribute.Id).Select(p => p.Id).ToList();
|
||
var values = attributeValues.Where(p => relationIds.Contains(p.ProductAttributeRelationId)).ToList();
|
||
|
||
saleAttribute.ProductAttributeValues = _mapper.Map<List<ProductAttributeValueModel>>(values);
|
||
data.Add(saleAttribute);
|
||
}
|
||
|
||
result = result.IsSuccess(data);
|
||
|
||
return new JsonResult(result);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加库存
|
||
/// </summary>
|
||
/// <param name="model"></param>
|
||
/// <returns></returns>
|
||
[HttpPost("stock/add")]
|
||
public IActionResult AddStock(ProductAddStockModel model)
|
||
{
|
||
var result = new ApiResult<string>();
|
||
var product = _dbContext.Products.SingleOrDefault(p => p.Id == model.ProductId);
|
||
if (product == null)
|
||
{
|
||
result = result.IsFail("参数错误,产品数据不存在");
|
||
return new JsonResult(result);
|
||
}
|
||
_logger.LogInformation(model.ToJson());
|
||
Console.WriteLine(model.ToJson());
|
||
ProductAttributeCombination productAttributeCombination = null;
|
||
List<ProductAttributeValue> productAttributeValueList = new List<ProductAttributeValue>();
|
||
List<ProductSkuModel> productSkus = new List<ProductSkuModel>();
|
||
List<ProductAttributeRelation> productAttributeRelations = _dbContext.ProductAttributeRelations.Where(p => p.ProductId == product.Id).ToList();
|
||
ProductSkuModel? weightModel = null;
|
||
if (model.AddAttribute)
|
||
{
|
||
foreach (var item in model.ProductStockAttributes)
|
||
{
|
||
var relation = productAttributeRelations.SingleOrDefault(p => p.AttributeId == item.AttributeId);
|
||
var attributeValue = new ProductAttributeValue()
|
||
{
|
||
Id = _idCreator.CreateId(),
|
||
Name = item.AttributeValue.Name,
|
||
OptionId = item.AttributeValue.OptionId,
|
||
ProductAttributeRelationId = relation.Id,
|
||
ProductId = model.ProductId,
|
||
Image = item.AttributeValue.Image,
|
||
Weight = item.AttributeValue.Weight,
|
||
WeightUnit = item.AttributeValue.WeightUnit,
|
||
IsAddWeight = item.AttributeValue.IsAddWeight
|
||
};
|
||
|
||
productAttributeValueList.Add(attributeValue);
|
||
var sku = new ProductSkuModel() { AttributeId = item.AttributeId, AttributeName = item.Name, ValueId = attributeValue.Id, ValueName = attributeValue.Name, Weight = attributeValue.Weight.RemoveTrailingZeros().ToDecimal(), WeightUnit = attributeValue.WeightUnit };
|
||
if (sku.Weight > 0)
|
||
{
|
||
weightModel = sku;
|
||
}
|
||
productSkus.Add(sku);
|
||
|
||
}
|
||
|
||
productAttributeCombination = new ProductAttributeCombination()
|
||
{
|
||
Id = _idCreator.CreateId(),
|
||
ProductId = model.ProductId,
|
||
AttributesJson = productSkus.ToJson(),
|
||
Enabled = true,
|
||
MarketPrice = model.ProductAttributeCombination.MarketPrice,
|
||
Price = model.ProductAttributeCombination.Price,
|
||
SalesQuantity = 0,
|
||
SkuNumber = model.ProductAttributeCombination.SkuNumber,
|
||
StockQuantity = model.AddStockQuantity,
|
||
Weight = weightModel?.Weight.RemoveTrailingZeros().ToDecimal() ?? 0,
|
||
WeightUnit = weightModel?.WeightUnit ?? 0,
|
||
ManufacturerId = model.ProductAttributeCombination.ManufacturerId,
|
||
ProcessCharge = model.ProductAttributeCombination.ProcessCharge,
|
||
ProcessCost = model.ProductAttributeCombination.ProcessCost,
|
||
Surcharge = model.ProductAttributeCombination.Surcharge,
|
||
SurchargeCost = model.ProductAttributeCombination.SurchargeCost,
|
||
CorporationId = model.CorporationId,
|
||
UpdateTime = DateTime.UtcNow
|
||
};
|
||
|
||
|
||
var productWarehouseInventory = new ProductInventory()
|
||
{
|
||
Id = _idCreator.CreateId(),
|
||
ProductId = model.ProductId,
|
||
ProductAttributeCombinationId = productAttributeCombination.Id,
|
||
WarehouseId = model.WarehouseId.ToLong(),
|
||
StockQuantity = model.AddStockQuantity,
|
||
CorporationId = model.CorporationId,
|
||
CreateTime = DateTime.UtcNow,
|
||
UpdateTime = DateTime.UtcNow
|
||
};
|
||
|
||
product.StockQuantity += model.AddStockQuantity;
|
||
|
||
using (var transaction = _dbContext.Database.BeginTransaction())
|
||
{
|
||
try
|
||
{
|
||
_dbContext.ProductAttributeValues.AddRange(productAttributeValueList);
|
||
_dbContext.ProductInventories.Add(productWarehouseInventory);
|
||
_dbContext.ProductAttributeCombinations.Add(productAttributeCombination);
|
||
_dbContext.Products.Update(product);
|
||
_dbContext.SaveChanges();
|
||
transaction.Commit();
|
||
result.Success = true;
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
transaction.Rollback();
|
||
result.Success = false;
|
||
result.Message = ex.Message;
|
||
return new JsonResult(result);
|
||
}
|
||
|
||
}
|
||
}
|
||
else
|
||
{
|
||
foreach (var item in model.ProductStockAttributes)
|
||
{
|
||
var value = item.ProductAttributeValues.Where(p => p.Id == item.AttributeValue.OptionId).SingleOrDefault();
|
||
var attributeValue = new ProductAttributeValue()
|
||
{
|
||
Id = _idCreator.CreateId(),
|
||
Name = value.Name,
|
||
OptionId = item.AttributeValue.OptionId,
|
||
ProductAttributeRelationId = item.AttributeValue.ProductAttributeRelationId,
|
||
ProductId = model.ProductId,
|
||
Image = item.AttributeValue.Image,
|
||
Weight = value.Weight,
|
||
WeightUnit = item.WeightUnit,
|
||
IsAddWeight = item.AttributeValue.IsAddWeight
|
||
};
|
||
productSkus.Add(new() { AttributeId = item.AttributeId, AttributeName = item.Name, ValueId = item.AttributeValue.OptionId, ValueName = value.Name, Weight = value.Weight.RemoveTrailingZeros().ToDecimal(), WeightUnit = item.WeightUnit });
|
||
}
|
||
var json = productSkus.ToJson();
|
||
Console.WriteLine($"json: {json}");
|
||
productAttributeCombination = _dbContext.ProductAttributeCombinations.SingleOrDefault(p => p.ProductId == model.ProductId && p.AttributesJson == json);
|
||
bool addNewSku = false;
|
||
if (productAttributeCombination == null)
|
||
{
|
||
result = result.IsFail("参数错误,产品SKU数据不存在");
|
||
return new JsonResult(result);
|
||
}
|
||
else
|
||
{
|
||
productAttributeCombination.StockQuantity += model.AddStockQuantity;
|
||
productAttributeCombination.UpdateTime = DateTime.UtcNow;
|
||
}
|
||
|
||
var productWarehouseInventory = _dbContext.ProductInventories.SingleOrDefault(p => p.ProductId == model.ProductId && p.ProductAttributeCombinationId == model.Id && p.WarehouseId == model.WarehouseId.ToLong());
|
||
bool newWarehouseInventory = false;
|
||
if (productWarehouseInventory == null)
|
||
{
|
||
productWarehouseInventory = new ProductInventory()
|
||
{
|
||
Id = _idCreator.CreateId(),
|
||
ProductId = model.ProductId,
|
||
ProductAttributeCombinationId = model.Id,
|
||
WarehouseId = model.WarehouseId.ToLong(),
|
||
StockQuantity = model.AddStockQuantity,
|
||
CorporationId = model.CorporationId,
|
||
CreateTime = DateTime.UtcNow,
|
||
UpdateTime = DateTime.UtcNow
|
||
};
|
||
newWarehouseInventory = true;
|
||
}
|
||
else
|
||
{
|
||
productWarehouseInventory.StockQuantity += model.AddStockQuantity;
|
||
}
|
||
product.StockQuantity += model.AddStockQuantity;
|
||
|
||
using (var transaction = _dbContext.Database.BeginTransaction())
|
||
{
|
||
try
|
||
{
|
||
if (newWarehouseInventory)
|
||
{
|
||
_dbContext.ProductInventories.Add(productWarehouseInventory);
|
||
}
|
||
else
|
||
{
|
||
_dbContext.ProductInventories.Update(productWarehouseInventory);
|
||
}
|
||
|
||
if (addNewSku)
|
||
{
|
||
_dbContext.ProductAttributeCombinations.Add(productAttributeCombination);
|
||
}
|
||
else
|
||
{
|
||
_dbContext.ProductAttributeCombinations.Update(productAttributeCombination);
|
||
}
|
||
|
||
_dbContext.Products.Update(product);
|
||
_dbContext.SaveChanges();
|
||
transaction.Commit();
|
||
result.Success = true;
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
transaction.Rollback();
|
||
result.Success = false;
|
||
result.Message = ex.Message;
|
||
return new JsonResult(result);
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
return new JsonResult(result);
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加库存
|
||
/// </summary>
|
||
/// <param name="model"></param>
|
||
/// <returns></returns>
|
||
[HttpPost("skustock/add")]
|
||
public IActionResult AddSkuStock(ProductStockModel model)
|
||
{
|
||
var result = new ApiResult<string>();
|
||
|
||
var productSku = _dbContext.ProductAttributeCombinations.SingleOrDefault(p => p.Id == model.Id && p.ProductId == model.ProductId);
|
||
if (productSku == null)
|
||
{
|
||
result = result.IsFail("参数错误,产品SKU数据不存在");
|
||
return new JsonResult(result);
|
||
}
|
||
var product = _dbContext.Products.SingleOrDefault(p => p.Id == model.ProductId);
|
||
if (product == null)
|
||
{
|
||
result = result.IsFail("参数错误,产品数据不存在");
|
||
return new JsonResult(result);
|
||
}
|
||
var productWarehouseInventory = _dbContext.ProductInventories.SingleOrDefault(p => p.ProductId == model.ProductId && p.ProductAttributeCombinationId == model.Id && p.WarehouseId == model.WarehouseId);
|
||
bool newWarehouseInventory = false;
|
||
if (productWarehouseInventory == null)
|
||
{
|
||
productWarehouseInventory = new ProductInventory()
|
||
{
|
||
Id = _idCreator.CreateId(),
|
||
ProductId = model.ProductId,
|
||
ProductAttributeCombinationId = model.Id,
|
||
WarehouseId = model.WarehouseId,
|
||
StockQuantity = model.AddStockQuantity,
|
||
CorporationId = model.CorporationId,
|
||
CreateTime = DateTime.UtcNow,
|
||
UpdateTime = DateTime.UtcNow
|
||
};
|
||
newWarehouseInventory = true;
|
||
|
||
|
||
}
|
||
else
|
||
{
|
||
productWarehouseInventory.StockQuantity += model.AddStockQuantity;
|
||
}
|
||
productSku.StockQuantity += model.AddStockQuantity;
|
||
productSku.UpdateTime = DateTime.UtcNow;
|
||
product.StockQuantity += model.AddStockQuantity;
|
||
product.UpdateTime = DateTime.UtcNow;
|
||
|
||
using (var transaction = _dbContext.Database.BeginTransaction())
|
||
{
|
||
try
|
||
{
|
||
if (newWarehouseInventory)
|
||
{
|
||
_dbContext.ProductInventories.Add(productWarehouseInventory);
|
||
}
|
||
else
|
||
{
|
||
_dbContext.ProductInventories.Update(productWarehouseInventory);
|
||
}
|
||
_dbContext.Products.Update(product);
|
||
_dbContext.ProductAttributeCombinations.Update(productSku);
|
||
_dbContext.SaveChanges();
|
||
transaction.Commit();
|
||
result.Success = true;
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
transaction.Rollback();
|
||
result.Success = false;
|
||
result.Message = ex.Message;
|
||
return new JsonResult(result);
|
||
}
|
||
|
||
}
|
||
|
||
return new JsonResult(result);
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
public class MiniProductModel
|
||
{
|
||
/// <summary>
|
||
/// 产品ID
|
||
/// </summary>
|
||
public long Id { get; set; }
|
||
|
||
/// <summary>
|
||
/// 产品名称
|
||
/// </summary>
|
||
public string Title { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 封面图片
|
||
/// </summary>
|
||
public string? Image { get; set; } = string.Empty;
|
||
} |