有时我们需要把几个账本合并到一个账本中,这样就可以在一个账本中查看所有的交易记录。那么,在本片文章中我们就来一起实现这个功能。
一、需求分析
用户需要能够将多个账本中的交易记录合并到一个目标账本中,以便在统一的视图下管理和查看所有交易数据。用户首先选择一个目标账本作为合并的目的地,然后选择一个或多个源账本,系统将源账本中的所有交易记录复制到目标账本中。
在这里我们暂时不考虑合并后可能出现的重复交易记录问题,因为这个功能属于一个较为复杂的功能,因此我们会把这个功能放在进阶的阶段去讲解具体怎么实现。
二、功能设计
我们现在已经了解了需求,接下来我们来设计一下这个功能。这个功能很简单,只需要一个接口,一个方法就可以实现。
我们在 AccountBookController 中添加一个新的接口 MergeAccountBooks,该方法接受一个目标账本 ID 和一个源账本 ID 列表,代码如下:
csharp
///<summary>
///账本合并
///</summary>
///<param name="request">账本合并请求</param>
[HttpPost("merge")]
public ActionResult<bool> MergeAccountBooks([FromBody] AccountBookMergeRequest request)
{
_accountBookServer.Merge(request);
return Ok();
}
接下来我们需要定义 AccountBookMergeRequest 类来封装请求参数:
csharp
namespace SP.FinanceService.Models.Request
{
/// <summary>
/// 账本合并请求模型
/// </summary>
public class AccountBookMergeRequest
{
/// <summary>
/// 目标账本ID
/// </summary>
public long TargetAccountBookId { get; set; }
/// <summary>
/// 源账本ID列表
/// </summary>
public List<long> SourceAccountBookIds { get; set; } = new();
}
}
接下来我们在 IAccountBookServer 中新增 Merge 方法,并在 AccountBookServerImpl 类中实现该方法:
csharp
// IAccountBookServer.cs
/// <summary>
/// 合并账本
/// </summary>
/// <param name="request"></param>
void Merge(AccountBookMergeRequest request);
// AccountBookServerImpl.cs
/// <summary>
/// 合并账本
/// </summary>
/// <param name="request"></param>
/// <exception cref="NotImplementedException"></exception>
public void Merge(AccountBookMergeRequest request)
{
// 目标账本是否存在
bool targetExist = Exist(request.TargetAccountBookId);
if (targetExist)
{
throw new NotFoundException($"账本不存在,ID: {request.TargetAccountBookId}");
}
// 来源账本是否存在
List<long> sourceIds = request.SourceAccountBookIds;
List<long> notExistIds = BatchQuery(sourceIds);
if (notExistIds.Any())
{
throw new NotFoundException($"以下账本不存在,ID: {string.Join(", ", notExistIds)}");
}
// 迁移账本下的记录
// 规则:源账本的记录迁移到目标账本下,修改账本ID为目标账本ID
var accountingServer = _serviceProvider.GetRequiredService<IAccountingServer>();
accountingServer.MigrateAccountBook(request.TargetAccountBookId, sourceIds);
}
在上面的代码中,我们首先检查目标账本是否存在,如果不存在则抛出异常。接着检查源账本是否存在,如果有不存在的账本也抛出异常。最后,我们调用 IAccountingServer 的 MigrateAccountBook 方法来迁移源账本下的记录到目标账本下。
在合并前,系统需要通过 Exist 方法确认目标账本存在,若不存在则立即抛出 NotFoundException 异常,中断合并流程。随后使用 BatchQuery 方法对所有源账本进行批量查询,返回不存在的账本ID列表。这种方式比逐个验证更高效,特别是在源账本数量较多时。
核心的记录迁移操作通过 MigrateAccountBook 方法实现,将源账本中的所有交易记录转移到目标账本,其本质是更新这些记录的 AccountBookId 字段为目标账本ID,从而实现记录的归集。在实现此方法时,应当使用数据库事务确保整个迁移过程的原子性,避免数据不一致。对于大量交易记录的迁移场景,应使用批量更新操作而非逐条更新,以提高性能并减少数据库压力。
三、总结
这篇文章我们介绍了如何实现账本合并功能。通过设计一个简单的接口和方法,我们可以将多个账本中的交易记录合并到一个目标账本中,方便用户统一管理和查看所有交易数据。在实际应用中,还可以根据需求进一步完善该功能,例如处理重复交易记录等问题。