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();
}