From 40869ef00f48eb5c0eb53be709d0fd3256e7c5b3 Mon Sep 17 00:00:00 2001 From: hailin Date: Thu, 15 Jan 2026 05:55:52 -0800 Subject: [PATCH] =?UTF-8?q?feat:=20split=20share=20pool=20into=20A=20(100?= =?UTF-8?q?=E4=BA=BF)=20and=20B=20(200=E4=B8=87)=20accounts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backend changes: - mining-wallet-service: Split SHARE_POOL into SHARE_POOL_A (100亿, for burning) and SHARE_POOL_B (200万, for mining distribution) - Add /pool-accounts/share-pool-balance API endpoint to get total balance - Update pool initialization logic and seed data - Fix Kong routing for mining-wallet-service (strip_path: true) - Fix Kong routing for trading-service (strip_path: true) Constant updates (100.02亿 = 10,002,000,000): - mining-service: TOTAL_SHARES - trading-service: TOTAL_SHARES, trading config defaults - trading-service seed: initial green points = 5760 Frontend changes: - Add sharePoolBalanceProvider to fetch pool balance from mining-wallet-service - Update contribution page to display real-time share pool balance (A + B) Co-Authored-By: Claude Opus 4.5 --- backend/api-gateway/kong.yml | 7 +- .../mining-service/prisma/schema.prisma | 2 +- .../services/mining-service/prisma/seed.ts | 2 +- .../services/mining-calculator.service.ts | 4 +- .../prisma/schema.prisma | 3 +- .../mining-wallet-service/prisma/seed.ts | 21 +++-- .../controllers/pool-account.controller.ts | 25 ++++-- .../services/pool-account.service.ts | 80 +++++++++++++++---- .../trading-service/prisma/schema.prisma | 4 +- .../services/trading-service/prisma/seed.ts | 10 +-- .../services/trading-calculator.service.ts | 4 +- .../repositories/trading-config.repository.ts | 2 +- .../lib/core/network/api_endpoints.dart | 3 + .../pages/contribution/contribution_page.dart | 22 +++-- .../providers/contribution_providers.dart | 37 +++++++++ 15 files changed, 170 insertions(+), 56 deletions(-) diff --git a/backend/api-gateway/kong.yml b/backend/api-gateway/kong.yml index 868b38b1..778b3f16 100644 --- a/backend/api-gateway/kong.yml +++ b/backend/api-gateway/kong.yml @@ -357,18 +357,19 @@ services: # --------------------------------------------------------------------------- # Mining Wallet Service 2.0 - 挖矿钱包服务 + # 前端路径: /api/v2/mining-wallet/... -> 后端路径: /api/v2/... # --------------------------------------------------------------------------- - name: mining-wallet-service - url: http://192.168.1.111:3025 + url: http://192.168.1.111:3025/api/v2 routes: - name: mining-wallet-api paths: - /api/v2/mining-wallet - strip_path: false + strip_path: true - name: mining-wallet-health paths: - /api/v2/mining-wallet/health - strip_path: false + strip_path: true # ============================================================================= # Plugins - 全局插件配置 diff --git a/backend/services/mining-service/prisma/schema.prisma b/backend/services/mining-service/prisma/schema.prisma index a3de13a5..b3d4117b 100644 --- a/backend/services/mining-service/prisma/schema.prisma +++ b/backend/services/mining-service/prisma/schema.prisma @@ -12,7 +12,7 @@ datasource db { // 挖矿全局配置 model MiningConfig { id String @id @default(uuid()) - totalShares Decimal @db.Decimal(30, 8) // 总积分股数量 (100.02B) + totalShares Decimal @db.Decimal(30, 8) // 总积分股数量 (100.02亿) distributionPool Decimal @db.Decimal(30, 8) // 分配池 (200M) remainingDistribution Decimal @db.Decimal(30, 8) // 剩余可分配 halvingPeriodYears Int @default(2) // 减半周期(年) diff --git a/backend/services/mining-service/prisma/seed.ts b/backend/services/mining-service/prisma/seed.ts index ccf3896b..115ac2f4 100644 --- a/backend/services/mining-service/prisma/seed.ts +++ b/backend/services/mining-service/prisma/seed.ts @@ -19,7 +19,7 @@ async function main() { const now = new Date(); // 常量 - const TOTAL_SHARES = new Decimal('100020000000'); // 100.02B + const TOTAL_SHARES = new Decimal('10002000000'); // 100.02亿 const DISTRIBUTION_POOL = new Decimal('2000000'); // 200万 const ERA1_DISTRIBUTION = new Decimal('1000000'); // 100万(第一个两年) const BURN_TARGET = new Decimal('10000000000'); // 100亿 diff --git a/backend/services/mining-service/src/domain/services/mining-calculator.service.ts b/backend/services/mining-service/src/domain/services/mining-calculator.service.ts index 7c39eb87..b6b64881 100644 --- a/backend/services/mining-service/src/domain/services/mining-calculator.service.ts +++ b/backend/services/mining-service/src/domain/services/mining-calculator.service.ts @@ -6,8 +6,8 @@ import { Price } from '../value-objects/price.vo'; * 挖矿计算领域服务 */ export class MiningCalculatorService { - // 总积分股数量: 100.02B - static readonly TOTAL_SHARES = new ShareAmount('100020000000'); + // 总积分股数量: 100.02亿 (SHARE_POOL_A: 100亿 + SHARE_POOL_B: 200万) + static readonly TOTAL_SHARES = new ShareAmount('10002000000'); // 初始分配池: 200M static readonly INITIAL_DISTRIBUTION_POOL = new ShareAmount('200000000'); diff --git a/backend/services/mining-wallet-service/prisma/schema.prisma b/backend/services/mining-wallet-service/prisma/schema.prisma index 99a5bcd1..1f85ea69 100644 --- a/backend/services/mining-wallet-service/prisma/schema.prisma +++ b/backend/services/mining-wallet-service/prisma/schema.prisma @@ -27,7 +27,8 @@ enum SystemAccountType { // 池账户类型 enum PoolAccountType { - SHARE_POOL // 积分股池 - 总股池 + SHARE_POOL_A // 积分股池A - 初始100亿 + SHARE_POOL_B // 积分股池B - 初始200万 BLACK_HOLE_POOL // 黑洞积分股池 - 销毁池 CIRCULATION_POOL // 流通积分股池 - 交易流通池 } diff --git a/backend/services/mining-wallet-service/prisma/seed.ts b/backend/services/mining-wallet-service/prisma/seed.ts index 77674e60..6a810962 100644 --- a/backend/services/mining-wallet-service/prisma/seed.ts +++ b/backend/services/mining-wallet-service/prisma/seed.ts @@ -62,19 +62,28 @@ async function main() { } } - // 2. 初始化池账户(积分股池、黑洞池、流通池) + // 2. 初始化池账户(积分股池A/B、黑洞池、流通池) + // 积分股池A: 100亿 (10,000,000,000) - 用于销毁 + // 积分股池B: 200万 (2,000,000) - 用于挖矿分配 + // 总计: 100.02亿 (10,002,000,000) const poolAccounts = [ { - poolType: 'SHARE_POOL', - name: '积分股池', - balance: new Decimal('100000000'), // 1亿初始发行量 - description: '挖矿奖励的来源池,总发行量', + poolType: 'SHARE_POOL_A', + name: '积分股池A', + balance: new Decimal('10000000000'), // 100亿初始发行量 + description: '销毁池来源,初始100亿', + }, + { + poolType: 'SHARE_POOL_B', + name: '积分股池B', + balance: new Decimal('2000000'), // 200万初始发行量 + description: '挖矿分配池,初始200万', }, { poolType: 'BLACK_HOLE_POOL', name: '黑洞池', balance: new Decimal('0'), - targetBurn: new Decimal('50000000'), // 目标销毁5000万 + targetBurn: new Decimal('10000000000'), // 目标销毁100亿 description: '销毁的积分股,用于减少流通量', }, { diff --git a/backend/services/mining-wallet-service/src/api/controllers/pool-account.controller.ts b/backend/services/mining-wallet-service/src/api/controllers/pool-account.controller.ts index 0d85005b..e9aea8c8 100644 --- a/backend/services/mining-wallet-service/src/api/controllers/pool-account.controller.ts +++ b/backend/services/mining-wallet-service/src/api/controllers/pool-account.controller.ts @@ -6,7 +6,8 @@ import { PoolAccountType, TransactionType } from '@prisma/client'; import Decimal from 'decimal.js'; class InitializePoolsDto { - sharePool: { name: string; initialBalance?: string }; + sharePoolA: { name: string; initialBalance?: string }; + sharePoolB: { name: string; initialBalance?: string }; blackHolePool: { name: string; targetBurn: string }; circulationPool: { name: string; initialBalance?: string }; } @@ -78,10 +79,16 @@ export class PoolAccountController { @ApiResponse({ status: 201, description: '池账户初始化成功' }) async initialize(@Body() dto: InitializePoolsDto) { return this.poolAccountService.initializePools({ - sharePool: { - name: dto.sharePool.name, - initialBalance: dto.sharePool.initialBalance - ? new Decimal(dto.sharePool.initialBalance) + sharePoolA: { + name: dto.sharePoolA.name, + initialBalance: dto.sharePoolA.initialBalance + ? new Decimal(dto.sharePoolA.initialBalance) + : undefined, + }, + sharePoolB: { + name: dto.sharePoolB.name, + initialBalance: dto.sharePoolB.initialBalance + ? new Decimal(dto.sharePoolB.initialBalance) : undefined, }, blackHolePool: { @@ -97,6 +104,14 @@ export class PoolAccountController { }); } + @Get('share-pool-balance') + @Public() + @ApiOperation({ summary: '获取积分股池总余量' }) + @ApiResponse({ status: 200, description: '积分股池A+B的总余量' }) + async getSharePoolTotalBalance() { + return this.poolAccountService.getSharePoolTotalBalance(); + } + @Post('burn') @AdminOnly() @ApiOperation({ summary: '销毁到黑洞池' }) diff --git a/backend/services/mining-wallet-service/src/application/services/pool-account.service.ts b/backend/services/mining-wallet-service/src/application/services/pool-account.service.ts index 152c4270..fe3507c7 100644 --- a/backend/services/mining-wallet-service/src/application/services/pool-account.service.ts +++ b/backend/services/mining-wallet-service/src/application/services/pool-account.service.ts @@ -6,7 +6,11 @@ import Decimal from 'decimal.js'; import { DomainException } from '../../shared/filters/domain-exception.filter'; export interface InitializePoolsInput { - sharePool: { + sharePoolA: { + name: string; + initialBalance?: Decimal; + }; + sharePoolB: { name: string; initialBalance?: Decimal; }; @@ -30,27 +34,45 @@ export class PoolAccountService { ) {} /** - * 初始化三大池账户 + * 初始化四大池账户 */ async initializePools(input: InitializePoolsInput): Promise { const pools: PoolAccount[] = []; - // 积分股池 - const sharePool = await this.poolAccountRepo.create({ - poolType: 'SHARE_POOL', - name: input.sharePool.name, + // 积分股池A - 初始100亿 + const sharePoolA = await this.poolAccountRepo.create({ + poolType: 'SHARE_POOL_A', + name: input.sharePoolA.name, }); - pools.push(sharePool); + pools.push(sharePoolA); - // 如果有初始余额,注入资金 - if (input.sharePool.initialBalance?.greaterThan(0)) { + if (input.sharePoolA.initialBalance?.greaterThan(0)) { await this.poolAccountRepo.updateBalanceWithTransaction( - 'SHARE_POOL', - input.sharePool.initialBalance, + 'SHARE_POOL_A', + input.sharePoolA.initialBalance, { transactionType: 'INITIAL_INJECT', counterpartyType: 'EXTERNAL', - memo: `初始注入, 数量${input.sharePool.initialBalance.toFixed(8)}`, + memo: `初始注入积分股池A, 数量${input.sharePoolA.initialBalance.toFixed(8)}`, + }, + ); + } + + // 积分股池B - 初始200万 + const sharePoolB = await this.poolAccountRepo.create({ + poolType: 'SHARE_POOL_B', + name: input.sharePoolB.name, + }); + pools.push(sharePoolB); + + if (input.sharePoolB.initialBalance?.greaterThan(0)) { + await this.poolAccountRepo.updateBalanceWithTransaction( + 'SHARE_POOL_B', + input.sharePoolB.initialBalance, + { + transactionType: 'INITIAL_INJECT', + counterpartyType: 'EXTERNAL', + memo: `初始注入积分股池B, 数量${input.sharePoolB.initialBalance.toFixed(8)}`, }, ); } @@ -93,7 +115,8 @@ export class PoolAccountService { type: p.poolType, name: p.name, })), - sharePoolInitialBalance: input.sharePool.initialBalance?.toString() || '0', + sharePoolAInitialBalance: input.sharePoolA.initialBalance?.toString() || '0', + sharePoolBInitialBalance: input.sharePoolB.initialBalance?.toString() || '0', blackHoleTargetBurn: input.blackHolePool.targetBurn.toString(), circulationPoolInitialBalance: input.circulationPool.initialBalance?.toString() || '0', initializedAt: new Date().toISOString(), @@ -106,6 +129,7 @@ export class PoolAccountService { /** * 从积分股池分配(挖矿分配) + * 挖矿只从 SHARE_POOL_B (200万) 分配 */ async distributeMiningReward( toAccountSeq: string, @@ -117,10 +141,12 @@ export class PoolAccountService { referenceId?: string; }, ): Promise { + const sourcePool: PoolAccountType = 'SHARE_POOL_B'; + const memo = `挖矿分配给用户[${toAccountSeq}], 算力占比${miningInfo.contributionRatio.mul(100).toFixed(4)}%, 分钟${miningInfo.miningMinute.toISOString()}`; await this.poolAccountRepo.updateBalanceWithTransaction( - 'SHARE_POOL', + sourcePool, amount.negated(), { transactionType: 'MINING_DISTRIBUTE', @@ -139,7 +165,7 @@ export class PoolAccountService { await this.outboxRepo.create({ aggregateType: 'PoolAccount', - aggregateId: 'SHARE_POOL', + aggregateId: sourcePool, eventType: 'MINING_DISTRIBUTED', payload: { toAccountSeq, @@ -151,6 +177,30 @@ export class PoolAccountService { }); } + /** + * 获取积分股池总余量 (SHARE_POOL_A + SHARE_POOL_B) + */ + async getSharePoolTotalBalance(): Promise<{ + poolA: string; + poolB: string; + total: string; + }> { + const [poolA, poolB] = await Promise.all([ + this.poolAccountRepo.findByType('SHARE_POOL_A'), + this.poolAccountRepo.findByType('SHARE_POOL_B'), + ]); + + const balanceA = poolA ? new Decimal(poolA.balance.toString()) : new Decimal(0); + const balanceB = poolB ? new Decimal(poolB.balance.toString()) : new Decimal(0); + const total = balanceA.plus(balanceB); + + return { + poolA: balanceA.toFixed(8), + poolB: balanceB.toFixed(8), + total: total.toFixed(8), + }; + } + /** * 用户划入流通池(准备卖出) */ diff --git a/backend/services/trading-service/prisma/schema.prisma b/backend/services/trading-service/prisma/schema.prisma index 66961125..d8c6ec48 100644 --- a/backend/services/trading-service/prisma/schema.prisma +++ b/backend/services/trading-service/prisma/schema.prisma @@ -12,8 +12,8 @@ datasource db { // 交易全局配置 model TradingConfig { id String @id @default(uuid()) - // 总积分股数量: 100.02B - totalShares Decimal @default(100020000000) @map("total_shares") @db.Decimal(30, 8) + // 总积分股数量: 100.02亿 + totalShares Decimal @default(10002000000) @map("total_shares") @db.Decimal(30, 8) // 目标销毁量: 100亿 (4年销毁完) burnTarget Decimal @default(10000000000) @map("burn_target") @db.Decimal(30, 8) // 销毁周期: 4年 (分钟数) 365*4*1440 = 2102400 diff --git a/backend/services/trading-service/prisma/seed.ts b/backend/services/trading-service/prisma/seed.ts index 3a3a8861..e925a554 100644 --- a/backend/services/trading-service/prisma/seed.ts +++ b/backend/services/trading-service/prisma/seed.ts @@ -66,7 +66,7 @@ async function main() { if (!existingConfig) { await prisma.tradingConfig.create({ data: { - totalShares: new Decimal('100020000000'), // 100.02B 总积分股 + totalShares: new Decimal('10002000000'), // 100.02亿 总积分股 burnTarget: new Decimal('10000000000'), // 100亿目标销毁量 burnPeriodMinutes: 2102400, // 4年 = 365*4*1440 分钟 minuteBurnRate: new Decimal('4756.468797564687'), // 每分钟销毁率 @@ -93,17 +93,17 @@ async function main() { console.log('Black hole account already exists'); } - // 4. 初始化积分股池 + // 4. 初始化积分股池(绿积分池) const existingSharePool = await prisma.sharePool.findFirst(); if (!existingSharePool) { await prisma.sharePool.create({ data: { - greenPoints: new Decimal(0), // 初始绿积分为 0 - totalInflow: new Decimal(0), + greenPoints: new Decimal(5760), // 初始绿积分为 5760 + totalInflow: new Decimal(5760), totalOutflow: new Decimal(0), }, }); - console.log('Created share pool'); + console.log('Created share pool with initial green points: 5760'); } else { console.log('Share pool already exists'); } diff --git a/backend/services/trading-service/src/domain/services/trading-calculator.service.ts b/backend/services/trading-service/src/domain/services/trading-calculator.service.ts index 2cfed8eb..48f94520 100644 --- a/backend/services/trading-service/src/domain/services/trading-calculator.service.ts +++ b/backend/services/trading-service/src/domain/services/trading-calculator.service.ts @@ -14,8 +14,8 @@ import { Money } from '../value-objects/money.vo'; * 7. 资产每秒增长量 = 用户每天分配的积分股 ÷ 24 ÷ 60 ÷ 60 */ export class TradingCalculatorService { - // 总积分股数量: 100.02B - static readonly TOTAL_SHARES = new Decimal('100020000000'); + // 总积分股数量: 100.02亿 (SHARE_POOL_A: 100亿 + SHARE_POOL_B: 200万) + static readonly TOTAL_SHARES = new Decimal('10002000000'); // 目标销毁量: 100亿 (4年销毁完) static readonly BURN_TARGET = new Decimal('10000000000'); diff --git a/backend/services/trading-service/src/infrastructure/persistence/repositories/trading-config.repository.ts b/backend/services/trading-service/src/infrastructure/persistence/repositories/trading-config.repository.ts index bca35a70..6791f8ba 100644 --- a/backend/services/trading-service/src/infrastructure/persistence/repositories/trading-config.repository.ts +++ b/backend/services/trading-service/src/infrastructure/persistence/repositories/trading-config.repository.ts @@ -35,7 +35,7 @@ export class TradingConfigRepository { const record = await this.prisma.tradingConfig.create({ data: { - totalShares: new Decimal('100020000000'), + totalShares: new Decimal('10002000000'), // 100.02亿 burnTarget: new Decimal('10000000000'), burnPeriodMinutes: 2102400, // 365 * 4 * 1440 minuteBurnRate: new Decimal('4756.468797564687'), diff --git a/frontend/mining-app/lib/core/network/api_endpoints.dart b/frontend/mining-app/lib/core/network/api_endpoints.dart index 34a68cbf..88984bcd 100644 --- a/frontend/mining-app/lib/core/network/api_endpoints.dart +++ b/frontend/mining-app/lib/core/network/api_endpoints.dart @@ -59,4 +59,7 @@ class ApiEndpoints { // Planting Ledger (Kong路由: /api/v2/contribution) static String plantingLedger(String accountSequence) => '/api/v2/contribution/accounts/$accountSequence/planting-ledger'; + + // Mining Wallet Service 2.0 (Kong路由: /api/v2/mining-wallet) + static const String sharePoolBalance = '/api/v2/mining-wallet/pool-accounts/share-pool-balance'; } 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 8692a9b7..f92a2d10 100644 --- a/frontend/mining-app/lib/presentation/pages/contribution/contribution_page.dart +++ b/frontend/mining-app/lib/presentation/pages/contribution/contribution_page.dart @@ -5,10 +5,8 @@ import '../../../core/constants/app_colors.dart'; import '../../../core/router/routes.dart'; import '../../../core/utils/format_utils.dart'; import '../../../domain/entities/contribution.dart'; -import '../../../domain/entities/market_overview.dart'; import '../../providers/user_providers.dart'; import '../../providers/contribution_providers.dart'; -import '../../providers/trading_providers.dart'; import '../../widgets/shimmer_loading.dart'; class ContributionPage extends ConsumerWidget { @@ -30,8 +28,8 @@ class ContributionPage extends ConsumerWidget { // 获取预估收益 final estimatedEarnings = ref.watch(estimatedEarningsProvider(accountSequence)); final statsAsync = ref.watch(contributionStatsProvider); - // 获取市场概览(积分股池余量) - final marketAsync = ref.watch(marketOverviewProvider); + // 获取积分股池余量 + final sharePoolAsync = ref.watch(sharePoolBalanceProvider); // Extract loading state and data from AsyncValue final isLoading = contributionAsync.isLoading; @@ -39,8 +37,8 @@ class ContributionPage extends ConsumerWidget { final hasError = contributionAsync.hasError; final error = contributionAsync.error; final isStatsLoading = statsAsync.isLoading; - final isMarketLoading = marketAsync.isLoading; - final market = marketAsync.valueOrNull; + final isSharePoolLoading = sharePoolAsync.isLoading; + final sharePoolBalance = sharePoolAsync.valueOrNull; return Scaffold( backgroundColor: const Color(0xFFF5F5F5), @@ -50,7 +48,7 @@ class ContributionPage extends ConsumerWidget { onRefresh: () async { ref.invalidate(contributionProvider(accountSequence)); ref.invalidate(contributionStatsProvider); - ref.invalidate(marketOverviewProvider); + ref.invalidate(sharePoolBalanceProvider); }, child: hasError && contribution == null ? Center( @@ -78,7 +76,7 @@ class ContributionPage extends ConsumerWidget { sliver: SliverList( delegate: SliverChildListDelegate([ // 总贡献值卡片 - _buildTotalContributionCard(ref, contribution, isLoading, market, isMarketLoading), + _buildTotalContributionCard(ref, contribution, isLoading, sharePoolBalance, isSharePoolLoading), const SizedBox(height: 16), // 三栏统计 _buildThreeColumnStats(ref, contribution, isLoading), @@ -167,8 +165,8 @@ class ContributionPage extends ConsumerWidget { WidgetRef ref, Contribution? contribution, bool isLoading, - MarketOverview? market, - bool isMarketLoading, + SharePoolBalance? sharePoolBalance, + bool isSharePoolLoading, ) { final total = contribution?.totalContribution ?? '0'; final hideAmounts = ref.watch(hideAmountsProvider); @@ -220,13 +218,13 @@ class ContributionPage extends ConsumerWidget { '积分股池实时余量: ', style: TextStyle(fontSize: 12, color: _grayText.withOpacity(0.9)), ), - isMarketLoading + isSharePoolLoading ? const ShimmerText( placeholder: '----', style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: _orange), ) : Text( - hideAmounts ? '******' : formatAmount(market?.greenPoints ?? '0'), + hideAmounts ? '******' : formatAmount(sharePoolBalance?.total ?? '0'), style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: _orange), ), ], diff --git a/frontend/mining-app/lib/presentation/providers/contribution_providers.dart b/frontend/mining-app/lib/presentation/providers/contribution_providers.dart index 57e8e29c..4fedc972 100644 --- a/frontend/mining-app/lib/presentation/providers/contribution_providers.dart +++ b/frontend/mining-app/lib/presentation/providers/contribution_providers.dart @@ -6,6 +6,8 @@ import '../../domain/entities/contribution_stats.dart'; import '../../domain/usecases/contribution/get_user_contribution.dart'; import '../../domain/repositories/contribution_repository.dart'; import '../../core/di/injection.dart'; +import '../../core/network/api_client.dart'; +import '../../core/network/api_endpoints.dart'; final getUserContributionUseCaseProvider = Provider((ref) { return getIt(); @@ -176,3 +178,38 @@ final estimatedEarningsProvider = Provider.family((re /// 控制是否隐藏金额显示的状态 final hideAmountsProvider = StateProvider((ref) => false); + +/// 积分股池余量数据类 +class SharePoolBalance { + final String poolA; + final String poolB; + final String total; + + const SharePoolBalance({ + required this.poolA, + required this.poolB, + required this.total, + }); + + factory SharePoolBalance.fromJson(Map json) { + return SharePoolBalance( + poolA: json['poolA'] ?? '0', + poolB: json['poolB'] ?? '0', + total: json['total'] ?? '0', + ); + } + + static const zero = SharePoolBalance(poolA: '0', poolB: '0', total: '0'); +} + +/// 积分股池总余量 Provider +final sharePoolBalanceProvider = FutureProvider((ref) async { + final client = getIt(); + + try { + final response = await client.get(ApiEndpoints.sharePoolBalance); + return SharePoolBalance.fromJson(response.data as Map); + } catch (e) { + return SharePoolBalance.zero; + } +});