Files
EmailBill/Repository/TransactionCategoryRepository.cs
孙诚 4526cc6396
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 8s
Docker Build & Deploy / Deploy to Production (push) Successful in 7s
first commot
2025-12-25 11:20:56 +08:00

175 lines
5.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace Repository;
/// <summary>
/// 交易分类仓储接口
/// </summary>
public interface ITransactionCategoryRepository : IBaseRepository<TransactionCategory>
{
/// <summary>
/// 根据类型获取所有顶级分类Level=2即类型下的分类
/// </summary>
Task<List<TransactionCategory>> GetTopLevelCategoriesByTypeAsync(TransactionType type);
/// <summary>
/// 根据父分类ID获取子分类
/// </summary>
Task<List<TransactionCategory>> GetChildCategoriesAsync(long parentId);
/// <summary>
/// 获取完整的分类树(按类型)
/// </summary>
Task<List<TransactionCategoryTreeDto>> GetCategoryTreeAsync(TransactionType? type = null);
/// <summary>
/// 根据名称和父ID查找分类防止重复
/// </summary>
Task<TransactionCategory?> GetByNameAndParentAsync(string name, long parentId, TransactionType type);
/// <summary>
/// 检查分类是否被使用
/// </summary>
Task<bool> IsCategoryInUseAsync(long categoryId);
}
/// <summary>
/// 交易分类仓储实现
/// </summary>
public class TransactionCategoryRepository(IFreeSql freeSql) : BaseRepository<TransactionCategory>(freeSql), ITransactionCategoryRepository
{
/// <summary>
/// 根据类型获取所有顶级分类Level=2
/// </summary>
public async Task<List<TransactionCategory>> GetTopLevelCategoriesByTypeAsync(TransactionType type)
{
return await FreeSql.Select<TransactionCategory>()
.Where(c => c.Type == type && c.Level == 2 && c.IsEnabled)
.OrderBy(c => c.SortOrder)
.OrderBy(c => c.Name)
.ToListAsync();
}
/// <summary>
/// 根据父分类ID获取子分类
/// </summary>
public async Task<List<TransactionCategory>> GetChildCategoriesAsync(long parentId)
{
return await FreeSql.Select<TransactionCategory>()
.Where(c => c.ParentId == parentId && c.IsEnabled)
.OrderBy(c => c.SortOrder)
.OrderBy(c => c.Name)
.ToListAsync();
}
/// <summary>
/// 获取完整的分类树
/// </summary>
public async Task<List<TransactionCategoryTreeDto>> GetCategoryTreeAsync(TransactionType? type = null)
{
var query = FreeSql.Select<TransactionCategory>()
.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<TransactionCategoryTreeDto>();
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;
}
/// <summary>
/// 递归构建子分类树
/// </summary>
private List<TransactionCategoryTreeDto> BuildChildrenTree(long parentId, List<TransactionCategory> allCategories)
{
var children = allCategories.Where(c => c.ParentId == parentId).ToList();
var result = new List<TransactionCategoryTreeDto>();
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;
}
/// <summary>
/// 根据名称和父ID查找分类
/// </summary>
public async Task<TransactionCategory?> GetByNameAndParentAsync(string name, long parentId, TransactionType type)
{
return await FreeSql.Select<TransactionCategory>()
.Where(c => c.Name == name && c.ParentId == parentId && c.Type == type)
.FirstAsync();
}
/// <summary>
/// 检查分类是否被使用
/// </summary>
public async Task<bool> IsCategoryInUseAsync(long categoryId)
{
// 检查是否有交易记录使用此分类
var category = await GetByIdAsync(categoryId);
if (category == null) return false;
// 根据层级检查不同的字段
var count = category.Level switch
{
2 => await FreeSql.Select<TransactionRecord>()
.Where(r => r.Classify == category.Name && r.Type == category.Type)
.CountAsync(),
3 => await FreeSql.Select<TransactionRecord>()
.Where(r => r.SubClassify == category.Name && r.Type == category.Type)
.CountAsync(),
_ => 0
};
return count > 0;
}
}
/// <summary>
/// 分类树DTO
/// </summary>
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<TransactionCategoryTreeDto> Children { get; set; } = new();
}