重构存款预算
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Failing after 44s
Docker Build & Deploy / Deploy to Production (push) Has been skipped
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 3s
Docker Build & Deploy / WeChat Notification (push) Successful in 2s
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Failing after 44s
Docker Build & Deploy / Deploy to Production (push) Has been skipped
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 3s
Docker Build & Deploy / WeChat Notification (push) Successful in 2s
This commit is contained in:
@@ -217,6 +217,8 @@ public interface ITransactionRecordRepository : IBaseRepository<TransactionRecor
|
||||
/// <param name="type">交易类型</param>
|
||||
/// <returns>影响行数</returns>
|
||||
Task<int> UpdateCategoryNameAsync(string oldName, string newName, TransactionType type);
|
||||
|
||||
Task<Dictionary<(string, TransactionType), decimal>> GetAmountGroupByClassifyAsync(DateTime startTime, DateTime endTime);
|
||||
}
|
||||
|
||||
public class TransactionRecordRepository(IFreeSql freeSql) : BaseRepository<TransactionRecord>(freeSql), ITransactionRecordRepository
|
||||
@@ -276,7 +278,7 @@ public class TransactionRecordRepository(IFreeSql freeSql) : BaseRepository<Tran
|
||||
var dateEnd = dateStart.AddMonths(1);
|
||||
query = query.Where(t => t.OccurredAt >= dateStart && t.OccurredAt < dateEnd);
|
||||
}
|
||||
|
||||
|
||||
// 按日期范围筛选
|
||||
query = query.WhereIf(startDate.HasValue, t => t.OccurredAt >= startDate!.Value)
|
||||
.WhereIf(endDate.HasValue, t => t.OccurredAt <= endDate!.Value);
|
||||
@@ -379,7 +381,7 @@ public class TransactionRecordRepository(IFreeSql freeSql) : BaseRepository<Tran
|
||||
var expense = g.Where(t => t.Type == TransactionType.Expense).Sum(t => Math.Abs(t.Amount));
|
||||
|
||||
var saving = 0m;
|
||||
if(!string.IsNullOrEmpty(savingClassify))
|
||||
if (!string.IsNullOrEmpty(savingClassify))
|
||||
{
|
||||
saving = g.Where(t => savingClassify.Split(',').Contains(t.Classify)).Sum(t => Math.Abs(t.Amount));
|
||||
}
|
||||
@@ -649,19 +651,19 @@ public class TransactionRecordRepository(IFreeSql freeSql) : BaseRepository<Tran
|
||||
|
||||
// 计算每个候选账单的相关度分数
|
||||
var scoredResults = candidates
|
||||
.Select(record =>
|
||||
.Select(record =>
|
||||
{
|
||||
var matchedCount = keywords.Count(keyword => record.Reason.Contains(keyword, StringComparison.OrdinalIgnoreCase));
|
||||
var matchRate = (double)matchedCount / keywords.Count;
|
||||
|
||||
|
||||
// 额外加分:完全匹配整个摘要(相似度更高)
|
||||
var exactMatchBonus = keywords.Any(k => record.Reason.Equals(k, StringComparison.OrdinalIgnoreCase)) ? 0.2 : 0.0;
|
||||
|
||||
|
||||
// 长度相似度加分:长度越接近,相关度越高
|
||||
var avgKeywordLength = keywords.Average(k => k.Length);
|
||||
var lengthSimilarity = 1.0 - Math.Min(1.0, Math.Abs(record.Reason.Length - avgKeywordLength) / Math.Max(record.Reason.Length, avgKeywordLength));
|
||||
var lengthBonus = lengthSimilarity * 0.1;
|
||||
|
||||
|
||||
var score = matchRate + exactMatchBonus + lengthBonus;
|
||||
return (record, score);
|
||||
})
|
||||
@@ -695,9 +697,9 @@ public class TransactionRecordRepository(IFreeSql freeSql) : BaseRepository<Tran
|
||||
.Where(t => Math.Abs(t.Amount) >= minAmount && Math.Abs(t.Amount) <= maxAmount)
|
||||
.Take(50)
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
return list.OrderBy(t => Math.Abs(Math.Abs(t.Amount) - absAmount))
|
||||
.ThenBy(x=> Math.Abs((x.OccurredAt - currentRecord.OccurredAt).TotalSeconds))
|
||||
.ThenBy(x => Math.Abs((x.OccurredAt - currentRecord.OccurredAt).TotalSeconds))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
@@ -757,6 +759,21 @@ public class TransactionRecordRepository(IFreeSql freeSql) : BaseRepository<Tran
|
||||
.GroupBy(t => t.OccurredAt.Date)
|
||||
.ToDictionary(g => g.Key, g => g.Sum(x => Math.Abs(x.Amount)));
|
||||
}
|
||||
|
||||
public async Task<Dictionary<(string, TransactionType), decimal>> GetAmountGroupByClassifyAsync(DateTime startTime, DateTime endTime)
|
||||
{
|
||||
var result = await FreeSql.Select<TransactionRecord>()
|
||||
.Where(t => t.OccurredAt >= startTime && t.OccurredAt < endTime)
|
||||
.GroupBy(t => new { t.Classify, t.Type })
|
||||
.ToListAsync(g => new
|
||||
{
|
||||
g.Key.Classify,
|
||||
g.Key.Type,
|
||||
TotalAmount = g.Sum(g.Value.Amount - g.Value.RefundAmount)
|
||||
});
|
||||
|
||||
return result.ToDictionary(x => (x.Classify, x.Type), x => x.TotalAmount);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user