namespace Service.AgentFramework; /// /// 账单分类查询工具集 /// public interface ITransactionQueryTools { /// /// 查询待分类的账单记录 /// Task QueryUnclassifiedRecordsAsync(long[] transactionIds); /// /// 按关键词查询已分类的相似记录(带评分) /// Task> QueryClassifiedByKeywordsAsync( List keywords, double minMatchRate = 0.4, int limit = 10); /// /// 批量查询账单是否已存在(按导入编号) /// Task> BatchCheckExistsByImportNoAsync( string[] importNos, string source); /// /// 获取所有分类信息 /// Task GetCategoryInfoAsync(); /// /// 更新账单分类信息 /// Task UpdateTransactionClassifyAsync( long transactionId, string classify, TransactionType type); } /// /// 账单分类查询工具实现 /// public class TransactionQueryTools( ITransactionRecordRepository transactionRepository, ITransactionCategoryRepository categoryRepository, ILogger logger ) : ITransactionQueryTools { public async Task QueryUnclassifiedRecordsAsync(long[] transactionIds) { logger.LogInformation("查询待分类记录,ID 数量: {Count}", transactionIds.Length); var records = await transactionRepository.GetByIdsAsync(transactionIds); var unclassified = records .Where(x => string.IsNullOrEmpty(x.Classify)) .ToArray(); logger.LogInformation("找到 {Count} 条待分类记录", unclassified.Length); return unclassified; } public async Task> QueryClassifiedByKeywordsAsync( List keywords, double minMatchRate = 0.4, int limit = 10) { logger.LogInformation("按关键词查询相似记录,关键词: {Keywords}", string.Join(", ", keywords)); var result = await transactionRepository.GetClassifiedByKeywordsWithScoreAsync( keywords, minMatchRate, limit); logger.LogInformation("找到 {Count} 条相似记录,相关度分数: {Scores}", result.Count, string.Join(", ", result.Select(x => $"{x.record.Reason}({x.relevanceScore:F2})"))); return result; } public async Task> BatchCheckExistsByImportNoAsync( string[] importNos, string source) { logger.LogInformation("批量检查导入编号是否存在,数量: {Count},来源: {Source}", importNos.Length, source); var result = new Dictionary(); // 分批查询以提高效率 const int batchSize = 100; for (int i = 0; i < importNos.Length; i += batchSize) { var batch = importNos.Skip(i).Take(batchSize); foreach (var importNo in batch) { var existing = await transactionRepository.ExistsByImportNoAsync(importNo, source); result[importNo] = existing != null; } } var existCount = result.Values.Count(v => v); logger.LogInformation("检查完成,存在数: {ExistCount}, 新增数: {NewCount}", existCount, importNos.Length - existCount); return result; } public async Task GetCategoryInfoAsync() { logger.LogInformation("获取分类信息"); var categories = await categoryRepository.GetAllAsync(); var sb = new StringBuilder(); sb.AppendLine("可用分类列表:"); foreach (var cat in categories) { sb.AppendLine($"- {cat.Name}"); } return sb.ToString(); } public async Task UpdateTransactionClassifyAsync( long transactionId, string classify, TransactionType type) { logger.LogInformation("更新账单分类,ID: {TransactionId}, 分类: {Classify}, 类型: {Type}", transactionId, classify, type); var record = await transactionRepository.GetByIdAsync(transactionId); if (record == null) { logger.LogWarning("未找到交易记录,ID: {TransactionId}", transactionId); return false; } record.Classify = classify; record.Type = type; var result = await transactionRepository.UpdateAsync(record); logger.LogInformation("账单分类更新结果: {Success}", result); return result; } }