using System.Linq.Expressions; using Fake.Application; using Fake.Domain.Exceptions; using Microsoft.AspNetCore.Mvc; using Oms.Application.Dtos.Kb; using Oms.Application.Dtos.Shared; using Oms.Application.Shared; using Oms.Domain.KbAggregate.Entities; using Oms.Domain.KbAggregate.Repositories; namespace Oms.Application.Services.Kb; /// /// 知识库分类管理。 /// [ApiExplorerSettings(GroupName = "OMS-Kb")] public class KbCategoryService : ApplicationService { private IKbCategoryRepository CategoryRepository => LazyServiceProvider.GetRequiredService(); private IKbArticleRepository ArticleRepository => LazyServiceProvider.GetRequiredService(); [HttpGet("/kb/admin/category/list")] public async Task> AdminListAsync([FromQuery] bool? enabledOnly = null) { Expression> predicate = ExpressionPredicate.True(); if (enabledOnly is bool enabled) { predicate = ExpressionPredicate.AndAlso(predicate, x => x.Enabled == enabled); } var items = await CategoryRepository.GetListAsync(predicate); var ordered = items.OrderBy(x => x.SortOrder).ThenBy(x => x.Id).ToList(); return new OmsItemsResult { Items = ordered.Select(Map).ToList() }; } [HttpPost("/kb/admin/category/save")] public async Task SaveAsync(KbCategorySaveInput input) { var code = input.Code.Trim(); var name = input.Name.Trim(); if (string.IsNullOrWhiteSpace(code) || string.IsNullOrWhiteSpace(name)) { throw new BusinessException("分类编码 / 名称不能为空"); } KbCategory? entity = null; if (input.Id is > 0) { entity = await CategoryRepository.FirstOrDefaultAsync(x => x.Id == input.Id.Value); if (entity == null) { throw new BusinessException("分类不存在"); } } if (await CategoryRepository.ExistsCodeAsync(code, entity?.Id)) { throw new BusinessException($"分类编码已存在:{code}"); } entity ??= new KbCategory(); entity.Code = code; entity.Name = name; entity.SortOrder = input.SortOrder; entity.Enabled = input.Enabled; if (entity.Id > 0) { await CategoryRepository.UpdateAsync(entity); } else { await CategoryRepository.InsertAsync(entity); } return Map(entity); } [HttpPost("/kb/admin/category/delete")] public async Task DeleteAsync(KbCategoryDeleteInput input) { var entity = await CategoryRepository.FirstOrDefaultAsync(x => x.Id == input.Id); if (entity == null) { throw new BusinessException("分类不存在"); } var articleCount = await ArticleRepository.CountByCategoryIdAsync(entity.Id); if (articleCount > 0) { throw new BusinessException($"该分类下仍有 {articleCount} 篇文章,无法删除"); } await CategoryRepository.DeleteAsync(entity); } private static KbCategoryOutput Map(KbCategory x) => new() { Id = x.Id, Code = x.Code, Name = x.Name, SortOrder = x.SortOrder, Enabled = x.Enabled }; }