From e0eb7341961b1c247fde966297a2be20b010add0 Mon Sep 17 00:00:00 2001 From: hailin Date: Wed, 21 Jan 2026 02:56:58 -0800 Subject: [PATCH] =?UTF-8?q?fix(contribution):=20=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E9=A2=86=E5=8F=96=E5=A5=96=E5=8A=B1=E6=97=B6=E4=BB=8E=20HEADQU?= =?UTF-8?q?ARTERS=20=E5=87=8F=E5=B0=91=E7=AE=97=E5=8A=9B=E5=B9=B6=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=98=8E=E7=BB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 subtractContribution 方法减少系统账户算力 - 添加 deleteContributionRecordsByAdoption 方法删除明细记录 - 在 BonusClaimService 中领取奖励时同步更新 HEADQUARTERS --- .../services/bonus-claim.service.ts | 35 ++++++++++++- .../repositories/system-account.repository.ts | 50 +++++++++++++++++++ 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/backend/services/contribution-service/src/application/services/bonus-claim.service.ts b/backend/services/contribution-service/src/application/services/bonus-claim.service.ts index 856f536e..7f812898 100644 --- a/backend/services/contribution-service/src/application/services/bonus-claim.service.ts +++ b/backend/services/contribution-service/src/application/services/bonus-claim.service.ts @@ -2,13 +2,14 @@ import { Injectable, Logger } from '@nestjs/common'; import { UnallocatedContributionRepository, UnallocatedContribution } from '../../infrastructure/persistence/repositories/unallocated-contribution.repository'; import { ContributionAccountRepository } from '../../infrastructure/persistence/repositories/contribution-account.repository'; import { ContributionRecordRepository } from '../../infrastructure/persistence/repositories/contribution-record.repository'; +import { SystemAccountRepository } from '../../infrastructure/persistence/repositories/system-account.repository'; import { OutboxRepository } from '../../infrastructure/persistence/repositories/outbox.repository'; import { UnitOfWork } from '../../infrastructure/persistence/unit-of-work/unit-of-work'; import { ContributionRecordAggregate } from '../../domain/aggregates/contribution-record.aggregate'; import { ContributionSourceType } from '../../domain/aggregates/contribution-account.aggregate'; import { ContributionAmount } from '../../domain/value-objects/contribution-amount.vo'; import { DistributionRate } from '../../domain/value-objects/distribution-rate.vo'; -import { ContributionRecordSyncedEvent } from '../../domain/events'; +import { ContributionRecordSyncedEvent, SystemAccountSyncedEvent } from '../../domain/events'; /** * 奖励补发服务 @@ -22,6 +23,7 @@ export class BonusClaimService { private readonly unallocatedContributionRepository: UnallocatedContributionRepository, private readonly contributionAccountRepository: ContributionAccountRepository, private readonly contributionRecordRepository: ContributionRecordRepository, + private readonly systemAccountRepository: SystemAccountRepository, private readonly outboxRepository: OutboxRepository, private readonly unitOfWork: UnitOfWork, ) {} @@ -135,7 +137,36 @@ export class BonusClaimService { const pendingIds = pendingRecords.map((r) => r.id); await this.unallocatedContributionRepository.claimBonusRecords(pendingIds, accountSequence); - // 6. 发布事件到 Kafka(通过 Outbox) + // 6. 从 HEADQUARTERS 减少算力并删除明细记录 + await this.systemAccountRepository.subtractContribution('HEADQUARTERS', null, totalAmount); + for (const pending of pendingRecords) { + await this.systemAccountRepository.deleteContributionRecordsByAdoption( + 'HEADQUARTERS', + null, + pending.sourceAdoptionId, + pending.sourceAccountSequence, + ); + } + + // 7. 发布 HEADQUARTERS 账户更新事件 + const headquartersAccount = await this.systemAccountRepository.findByTypeAndRegion('HEADQUARTERS', null); + if (headquartersAccount) { + const hqEvent = new SystemAccountSyncedEvent( + 'HEADQUARTERS', + null, + headquartersAccount.name, + headquartersAccount.contributionBalance.value.toString(), + headquartersAccount.createdAt, + ); + await this.outboxRepository.save({ + aggregateType: SystemAccountSyncedEvent.AGGREGATE_TYPE, + aggregateId: 'HEADQUARTERS', + eventType: SystemAccountSyncedEvent.EVENT_TYPE, + payload: hqEvent.toPayload(), + }); + } + + // 8. 发布事件到 Kafka(通过 Outbox) await this.publishBonusClaimEvents(accountSequence, savedRecords, pendingRecords); this.logger.log( diff --git a/backend/services/contribution-service/src/infrastructure/persistence/repositories/system-account.repository.ts b/backend/services/contribution-service/src/infrastructure/persistence/repositories/system-account.repository.ts index 23a2eee1..05382b47 100644 --- a/backend/services/contribution-service/src/infrastructure/persistence/repositories/system-account.repository.ts +++ b/backend/services/contribution-service/src/infrastructure/persistence/repositories/system-account.repository.ts @@ -165,6 +165,56 @@ export class SystemAccountRepository { return `${regionCode}账户`; } + /** + * 减少系统账户算力 + */ + async subtractContribution( + accountType: SystemAccountType, + regionCode: string | null, + amount: ContributionAmount, + ): Promise { + const existing = await this.client.systemAccount.findFirst({ + where: { + accountType, + regionCode: regionCode === null ? { equals: null } : regionCode, + }, + }); + + if (existing) { + await this.client.systemAccount.update({ + where: { id: existing.id }, + data: { + contributionBalance: { decrement: amount.value }, + }, + }); + } + } + + /** + * 删除指定来源认种的明细记录 + */ + async deleteContributionRecordsByAdoption( + accountType: SystemAccountType, + regionCode: string | null, + sourceAdoptionId: bigint, + sourceAccountSequence: string, + ): Promise { + const systemAccount = await this.findByTypeAndRegion(accountType, regionCode); + if (!systemAccount) { + return 0; + } + + const result = await this.client.systemContributionRecord.deleteMany({ + where: { + systemAccountId: systemAccount.id, + sourceAdoptionId, + sourceAccountSequence, + }, + }); + + return result.count; + } + async saveContributionRecord(record: { accountType: SystemAccountType; regionCode: string | null;