diff --git a/backend/services/contribution-service/src/application/services/contribution-calculation.service.ts b/backend/services/contribution-service/src/application/services/contribution-calculation.service.ts index 40049533..889b314e 100644 --- a/backend/services/contribution-service/src/application/services/contribution-calculation.service.ts +++ b/backend/services/contribution-service/src/application/services/contribution-calculation.service.ts @@ -285,8 +285,6 @@ export class ContributionCalculationService { (sum, u) => sum.add(u.amount), new ContributionAmount(0), ); - // 确保 HEADQUARTERS 账户存在 - await this.systemAccountRepository.ensureSystemAccountsExist(); await this.systemAccountRepository.addContribution('HEADQUARTERS', totalUnallocatedAmount); // 发布 HEADQUARTERS 账户同步事件 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 c35fbcb4..5517459b 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 @@ -81,9 +81,21 @@ export class SystemAccountRepository { accountType: SystemAccountType, amount: ContributionAmount, ): Promise { - await this.client.systemAccount.update({ + const accountNames: Record = { + OPERATION: '运营账户', + PROVINCE: '省公司账户', + CITY: '市公司账户', + HEADQUARTERS: '总部账户', + }; + + await this.client.systemAccount.upsert({ where: { accountType }, - data: { + create: { + accountType, + name: accountNames[accountType], + contributionBalance: amount.value, + }, + update: { contributionBalance: { increment: amount.value }, }, }); diff --git a/frontend/mining-app/lib/presentation/pages/contribution/contribution_page.dart b/frontend/mining-app/lib/presentation/pages/contribution/contribution_page.dart index c1c5a0aa..20a1bf23 100644 --- a/frontend/mining-app/lib/presentation/pages/contribution/contribution_page.dart +++ b/frontend/mining-app/lib/presentation/pages/contribution/contribution_page.dart @@ -21,9 +21,8 @@ class ContributionPage extends ConsumerWidget { final user = ref.watch(userNotifierProvider); final accountSequence = user.accountSequence ?? ''; final contributionAsync = ref.watch(contributionProvider(accountSequence)); - // 获取预估收益 + // 获取预估收益(基于用户每秒收益计算) final estimatedEarnings = ref.watch(estimatedEarningsProvider(accountSequence)); - final statsAsync = ref.watch(contributionStatsProvider); // 获取积分股池余量 final sharePoolAsync = ref.watch(sharePoolBalanceProvider); @@ -32,7 +31,6 @@ class ContributionPage extends ConsumerWidget { final contribution = contributionAsync.valueOrNull; final hasError = contributionAsync.hasError; final error = contributionAsync.error; - final isStatsLoading = statsAsync.isLoading; final isSharePoolLoading = sharePoolAsync.isLoading; final sharePoolBalance = sharePoolAsync.valueOrNull; @@ -43,7 +41,6 @@ class ContributionPage extends ConsumerWidget { child: RefreshIndicator( onRefresh: () async { ref.invalidate(contributionProvider(accountSequence)); - ref.invalidate(contributionStatsProvider); ref.invalidate(sharePoolBalanceProvider); }, child: hasError && contribution == null @@ -78,7 +75,7 @@ class ContributionPage extends ConsumerWidget { _buildThreeColumnStats(context, ref, contribution, isLoading), const SizedBox(height: 16), // 今日预估收益 - _buildTodayEstimateCard(context, ref, estimatedEarnings, isLoading || isStatsLoading), + _buildTodayEstimateCard(context, ref, estimatedEarnings, isLoading), const SizedBox(height: 16), // 贡献值明细(三类汇总) _buildContributionDetailCard(context, ref, contribution, isLoading), diff --git a/frontend/mining-app/lib/presentation/providers/contribution_providers.dart b/frontend/mining-app/lib/presentation/providers/contribution_providers.dart index 4fedc972..b947ec86 100644 --- a/frontend/mining-app/lib/presentation/providers/contribution_providers.dart +++ b/frontend/mining-app/lib/presentation/providers/contribution_providers.dart @@ -8,6 +8,7 @@ import '../../domain/repositories/contribution_repository.dart'; import '../../core/di/injection.dart'; import '../../core/network/api_client.dart'; import '../../core/network/api_endpoints.dart'; +import 'mining_providers.dart'; final getUserContributionUseCaseProvider = Provider((ref) { return getIt(); @@ -118,8 +119,7 @@ final contributionStatsProvider = FutureProvider((ref) async }); /// 计算用户今日预估收益 -/// 公式: (用户贡献值 / 全网总贡献值) × 每日发放量 -/// 每日发放量 = 每秒发放量 × 86400 +/// 公式: 用户每秒收益 × 60分钟 × 60秒 × 24小时 class EstimatedEarnings { final String dailyShares; final String perSecondShares; @@ -138,40 +138,27 @@ class EstimatedEarnings { ); } -/// 每日发放总量配置(积分股) -/// 第1纪元: 100M / (2年 × 365天) ≈ 136,986 积分股/天 -const double dailyAllocationTotal = 136986.0; - final estimatedEarningsProvider = Provider.family((ref, accountSequence) { - final contributionAsync = ref.watch(contributionProvider(accountSequence)); - final statsAsync = ref.watch(contributionStatsProvider); + // 从 mining-service 获取用户每秒收益 + final shareAccountAsync = ref.watch(shareAccountProvider(accountSequence)); + final shareAccount = shareAccountAsync.valueOrNull; - final contribution = contributionAsync.valueOrNull; - final stats = statsAsync.valueOrNull; - - if (contribution == null || stats == null) { + if (shareAccount == null) { return EstimatedEarnings.zero; } - final userContribution = double.tryParse(contribution.totalContribution) ?? 0; - final totalContribution = double.tryParse(stats.totalContribution) ?? 0; + final perSecondEarning = double.tryParse(shareAccount.perSecondEarning) ?? 0; - if (totalContribution <= 0 || userContribution <= 0) { + if (perSecondEarning <= 0) { return EstimatedEarnings.zero; } - // 用户占比 - final ratio = userContribution / totalContribution; - - // 每日预估 - final dailyShares = ratio * dailyAllocationTotal; - - // 每秒预估 - final perSecondShares = dailyShares / 86400; + // 每日预估 = 每秒收益 × 86400(60×60×24) + final dailyShares = perSecondEarning * 86400; return EstimatedEarnings( dailyShares: dailyShares.toStringAsFixed(4), - perSecondShares: perSecondShares.toStringAsFixed(8), + perSecondShares: perSecondEarning.toStringAsFixed(8), isValid: true, ); });