namespace Repository; /// /// 交易分类仓储接口 /// public interface ITransactionCategoryRepository : IBaseRepository { /// /// 根据类型获取所有顶级分类(Level=2,即类型下的分类) /// Task> GetTopLevelCategoriesByTypeAsync(TransactionType type); /// /// 根据父分类ID获取子分类 /// Task> GetChildCategoriesAsync(long parentId); /// /// 获取完整的分类树(按类型) /// Task> GetCategoryTreeAsync(TransactionType? type = null); /// /// 根据名称和父ID查找分类(防止重复) /// Task GetByNameAndParentAsync(string name, long parentId, TransactionType type); /// /// 检查分类是否被使用 /// Task IsCategoryInUseAsync(long categoryId); } /// /// 交易分类仓储实现 /// public class TransactionCategoryRepository(IFreeSql freeSql) : BaseRepository(freeSql), ITransactionCategoryRepository { /// /// 根据类型获取所有顶级分类(Level=2) /// public async Task> GetTopLevelCategoriesByTypeAsync(TransactionType type) { return await FreeSql.Select() .Where(c => c.Type == type && c.Level == 2 && c.IsEnabled) .OrderBy(c => c.SortOrder) .OrderBy(c => c.Name) .ToListAsync(); } /// /// 根据父分类ID获取子分类 /// public async Task> GetChildCategoriesAsync(long parentId) { return await FreeSql.Select() .Where(c => c.ParentId == parentId && c.IsEnabled) .OrderBy(c => c.SortOrder) .OrderBy(c => c.Name) .ToListAsync(); } /// /// 获取完整的分类树 /// public async Task> GetCategoryTreeAsync(TransactionType? type = null) { var query = FreeSql.Select() .Where(c => c.IsEnabled); if (type.HasValue) { query = query.Where(c => c.Type == type.Value); } var allCategories = await query .OrderBy(c => c.Type) .OrderBy(c => c.SortOrder) .OrderBy(c => c.Name) .ToListAsync(); // 构建树形结构(Level 2为根节点,即各个分类) var result = new List(); var level2Categories = allCategories.Where(c => c.Level == 2).ToList(); foreach (var category in level2Categories) { var treeNode = new TransactionCategoryTreeDto { Id = category.Id, Name = category.Name, Type = category.Type, Level = category.Level, Icon = category.Icon, Children = BuildChildrenTree(category.Id, allCategories) }; result.Add(treeNode); } return result; } /// /// 递归构建子分类树 /// private List BuildChildrenTree(long parentId, List allCategories) { var children = allCategories.Where(c => c.ParentId == parentId).ToList(); var result = new List(); foreach (var child in children) { var treeNode = new TransactionCategoryTreeDto { Id = child.Id, Name = child.Name, Type = child.Type, Level = child.Level, Icon = child.Icon, Children = BuildChildrenTree(child.Id, allCategories) }; result.Add(treeNode); } return result; } /// /// 根据名称和父ID查找分类 /// public async Task GetByNameAndParentAsync(string name, long parentId, TransactionType type) { return await FreeSql.Select() .Where(c => c.Name == name && c.ParentId == parentId && c.Type == type) .FirstAsync(); } /// /// 检查分类是否被使用 /// public async Task IsCategoryInUseAsync(long categoryId) { // 检查是否有交易记录使用此分类 var category = await GetByIdAsync(categoryId); if (category == null) return false; // 根据层级检查不同的字段 var count = category.Level switch { 2 => await FreeSql.Select() .Where(r => r.Classify == category.Name && r.Type == category.Type) .CountAsync(), 3 => await FreeSql.Select() .Where(r => r.SubClassify == category.Name && r.Type == category.Type) .CountAsync(), _ => 0 }; return count > 0; } } /// /// 分类树DTO /// public class TransactionCategoryTreeDto { public long Id { get; set; } public string Name { get; set; } = string.Empty; public TransactionType Type { get; set; } public int Level { get; set; } public string? Icon { get; set; } public List Children { get; set; } = new(); }