✨
This commit is contained in:
202
StopShopping.Services/Implementions/CategoryService.cs
Normal file
202
StopShopping.Services/Implementions/CategoryService.cs
Normal file
@@ -0,0 +1,202 @@
|
||||
using System.Data.Common;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StopShopping.EF;
|
||||
using StopShopping.Services.Models.Req;
|
||||
using StopShopping.Services.Models.Resp;
|
||||
|
||||
namespace StopShopping.Services.Implementions;
|
||||
|
||||
public class CategoryService : ICategoryService
|
||||
{
|
||||
public CategoryService(
|
||||
IFileService fileService,
|
||||
StopShoppingContext dbContext,
|
||||
ILogger<CategoryService> logger
|
||||
)
|
||||
{
|
||||
_fileService = fileService;
|
||||
_dbContext = dbContext;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
private readonly IFileService _fileService;
|
||||
private readonly StopShoppingContext _dbContext;
|
||||
private readonly ILogger<CategoryService> _logger;
|
||||
|
||||
public async Task<ApiResponse> DeleteCategoryAsync(CategoryIdParams model)
|
||||
{
|
||||
var category = await _dbContext.Categories
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(c => c.Id == model.CategoryId && !c.Deleted);
|
||||
if (null == category)
|
||||
return ApiResponse.Failed("此分类已不存在,请刷新重试");
|
||||
|
||||
var anyProduct = await _dbContext.Products
|
||||
.AsNoTracking()
|
||||
.AnyAsync(p =>
|
||||
_dbContext.Categories
|
||||
.AsNoTracking()
|
||||
.Where(c => c.Path.StartsWith(category.Path) && !c.Deleted)
|
||||
.Select(c => c.Id)
|
||||
.Contains(p.CategoryId));
|
||||
if (anyProduct)
|
||||
return ApiResponse.Failed("分类下已有商品,不允许删除");
|
||||
|
||||
await _dbContext.Categories
|
||||
.Where(c => c.Path.StartsWith(category.Path) && !c.Deleted)
|
||||
.ExecuteDeleteAsync();
|
||||
|
||||
return ApiResponse.Succed();
|
||||
}
|
||||
|
||||
public async Task<ApiResponse<Category>> EditCategoryAsync(EditCategoryParams model)
|
||||
{
|
||||
EF.Models.Category category;
|
||||
|
||||
using var trans = await _dbContext.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
short level = 1, order = 1;
|
||||
string path = string.Empty;
|
||||
|
||||
var parent = await _dbContext.Categories
|
||||
.FirstOrDefaultAsync(c => c.Id == model.ParentId);
|
||||
if (null != parent)
|
||||
level = (short)(parent.Level + 1);
|
||||
|
||||
if (model.Id > 0)
|
||||
{
|
||||
category = await _dbContext.Categories
|
||||
.FirstAsync(c => c.Id == model.Id && !c.Deleted);
|
||||
if (null == category)
|
||||
return new ApiResponse<Category>().Failed("此分类已不存在");
|
||||
|
||||
path = category.Path;
|
||||
order = category.Order;
|
||||
}
|
||||
else
|
||||
{
|
||||
category = new EF.Models.Category();
|
||||
await _dbContext.Categories.AddAsync(category);
|
||||
|
||||
order = await _dbContext.Categories
|
||||
.Where(c => c.ParentId == model.ParentId)
|
||||
.Select(c => c.Order)
|
||||
.DefaultIfEmpty()
|
||||
.MaxAsync();
|
||||
}
|
||||
|
||||
category.Level = level;
|
||||
if (!string.IsNullOrWhiteSpace(model.Logo))
|
||||
category.Logo = model.Logo;
|
||||
category.Name = model.Name;
|
||||
category.Order = order;
|
||||
category.ParentId = model.ParentId;
|
||||
category.Path = path;
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
if (!(model.Id > 0))
|
||||
{
|
||||
category.Path = BuildPath(parent?.Path ?? "", category.Id);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
await trans.CommitAsync();
|
||||
|
||||
var categoryResult = Cast(category);
|
||||
|
||||
return new ApiResponse<Category>(categoryResult);
|
||||
}
|
||||
catch (DbException e)
|
||||
{
|
||||
await trans.RollbackAsync();
|
||||
_logger.LogError(e, "新增/修改分类失败");
|
||||
return new ApiResponse<Category>().Failed("数据库操作失败,请刷新重试");
|
||||
}
|
||||
}
|
||||
|
||||
public ApiResponse<List<Category>> GetCategoriesTree()
|
||||
{
|
||||
var qry = _dbContext.Categories
|
||||
.AsNoTracking()
|
||||
.Where(c => !c.Deleted)
|
||||
.OrderBy(c => c.ParentId)
|
||||
.ThenBy(c => c.Order)
|
||||
.AsEnumerable();
|
||||
|
||||
var result = new ApiResponse<List<Category>>(ToTree(qry));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<ApiResponse> ResortCategoryAsync(ResortCategoryParams model)
|
||||
{
|
||||
var curr = await _dbContext.Categories
|
||||
.FirstOrDefaultAsync(c => c.Id == model.Id && !c.Deleted);
|
||||
if (null == curr)
|
||||
return ApiResponse.Failed("此分类已不存在,请刷新重试");
|
||||
|
||||
var target = await _dbContext.Categories
|
||||
.FirstOrDefaultAsync(c => c.Order == model.TargetOrder && !c.Deleted);
|
||||
if (null == target)
|
||||
return ApiResponse.Failed("目标位置分类已不存在,请刷新重试");
|
||||
|
||||
target.Order = curr.Order;
|
||||
curr.Order = model.TargetOrder;
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return ApiResponse.Succed();
|
||||
}
|
||||
|
||||
#region private methods
|
||||
|
||||
private List<Category> ToTree(IEnumerable<EF.Models.Category> models)
|
||||
{
|
||||
Dictionary<int, Category> idDicts = [];
|
||||
List<Category> categories = [];
|
||||
|
||||
foreach (var model in models)
|
||||
{
|
||||
Category node = Cast(model);
|
||||
node.Children = [];
|
||||
idDicts.Add(node.Id, node);
|
||||
}
|
||||
|
||||
foreach (var d in idDicts)
|
||||
{
|
||||
if (d.Value.ParentId > 0)
|
||||
idDicts[d.Value.ParentId].Children.Add(d.Value);
|
||||
else
|
||||
categories.Add(d.Value);
|
||||
}
|
||||
|
||||
return categories;
|
||||
}
|
||||
|
||||
private Category Cast(EF.Models.Category model)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Id = model.Id,
|
||||
LogoUrl = string.IsNullOrWhiteSpace(model.Logo)
|
||||
? ""
|
||||
: _fileService.GetFileUrl(Models.UploadScences.Category, model.Logo),
|
||||
Name = model.Name,
|
||||
Order = model.Order,
|
||||
ParentId = model.ParentId,
|
||||
Children = []
|
||||
};
|
||||
}
|
||||
|
||||
private string BuildPath(string prefix, params int[] ids)
|
||||
{
|
||||
return string.Format("{0}/{1}/",
|
||||
prefix.TrimEnd('/')
|
||||
, string.Join('/', ids));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user