admin/src/Oms.Application/Services/Kb/KbCategoryService.cs
zzh 7e442180cd fix: avoid SqlSugar invalid SQL from null/HasValue KB filters
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-04 16:53:09 +08:00

112 lines
3.4 KiB
C#

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;
/// <summary>
/// 知识库分类管理。
/// </summary>
[ApiExplorerSettings(GroupName = "OMS-Kb")]
public class KbCategoryService : ApplicationService
{
private IKbCategoryRepository CategoryRepository =>
LazyServiceProvider.GetRequiredService<IKbCategoryRepository>();
private IKbArticleRepository ArticleRepository =>
LazyServiceProvider.GetRequiredService<IKbArticleRepository>();
[HttpGet("/kb/admin/category/list")]
public async Task<OmsItemsResult<KbCategoryOutput>> AdminListAsync([FromQuery] bool? enabledOnly = null)
{
Expression<Func<KbCategory, bool>> predicate = ExpressionPredicate.True<KbCategory>();
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<KbCategoryOutput>
{
Items = ordered.Select(Map).ToList()
};
}
[HttpPost("/kb/admin/category/save")]
public async Task<KbCategoryOutput> 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
};
}