From 46f85b13b077ae2db5a5f12167a171e19543862c Mon Sep 17 00:00:00 2001 From: hailin Date: Tue, 3 Feb 2026 02:00:59 -0800 Subject: [PATCH] =?UTF-8?q?fix(pool-account):=20=E4=BF=AE=E5=A4=8D=20seed.?= =?UTF-8?q?ts=20=E8=A6=86=E7=9B=96=E6=B1=A0=E4=BD=99=E9=A2=9D=20+=20?= =?UTF-8?q?=E6=BF=80=E6=B4=BB=E6=8C=96=E7=9F=BF=E5=89=8D=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E6=B1=A0=E4=BD=99=E9=A2=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. seed.ts upsert 的 update 子句移除 balance/targetBurn/remainingBurn, 避免重新部署时将已有池余额清零(导致 BurnConsumer 和 MiningDistributionConsumer 因余额不足崩溃) 2. activateMining 激活前检查 SHARE_POOL_A/B 余额,任一为0则阻止激活 并返回 400 错误提示先通过区块链充值 Co-Authored-By: Claude Opus 4.5 --- .../src/api/controllers/config.controller.ts | 27 +++++++++++++++++++ .../mining-wallet-service/prisma/seed.ts | 6 ++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/backend/services/mining-admin-service/src/api/controllers/config.controller.ts b/backend/services/mining-admin-service/src/api/controllers/config.controller.ts index 1e5e3079..37a3d42b 100644 --- a/backend/services/mining-admin-service/src/api/controllers/config.controller.ts +++ b/backend/services/mining-admin-service/src/api/controllers/config.controller.ts @@ -152,6 +152,32 @@ export class ConfigController { @ApiOperation({ summary: '激活挖矿' }) async activateMining(@Req() req: any) { const miningServiceUrl = this.appConfigService.get('MINING_SERVICE_URL', 'http://localhost:3021'); + const walletServiceUrl = this.appConfigService.get('MINING_WALLET_SERVICE_URL', 'http://localhost:3025'); + + // 安全检查:池账户余额不能为0 + try { + const [poolARes, poolBRes] = await Promise.all([ + fetch(`${walletServiceUrl}/api/v2/pool-accounts/SHARE_POOL_A`), + fetch(`${walletServiceUrl}/api/v2/pool-accounts/SHARE_POOL_B`), + ]); + if (poolARes.ok && poolBRes.ok) { + const poolA = await poolARes.json(); + const poolB = await poolBRes.json(); + const balA = parseFloat(poolA?.data?.balance ?? poolA?.balance ?? '0'); + const balB = parseFloat(poolB?.data?.balance ?? poolB?.balance ?? '0'); + if (balA <= 0 || balB <= 0) { + const msg = `池账户余额不足,无法激活挖矿。积分股池A余额: ${balA},积分股池B余额: ${balB}。请先通过区块链充值。`; + this.logger.warn(msg); + throw new BadRequestException(msg); + } + } else { + this.logger.warn('无法获取池账户余额,跳过安全检查'); + } + } catch (error) { + if (error instanceof BadRequestException) throw error; + this.logger.warn('池账户余额检查失败,跳过安全检查', error); + } + try { const response = await fetch(`${miningServiceUrl}/api/v2/mining/admin/activate`, { method: 'POST', @@ -163,6 +189,7 @@ export class ConfigController { this.logger.log(`Mining activated by admin ${req.admin?.id}`); return result; } catch (error) { + if (error instanceof BadRequestException) throw error; this.logger.error('Failed to activate mining', error); return { success: false, message: 'Failed to activate mining' }; } diff --git a/backend/services/mining-wallet-service/prisma/seed.ts b/backend/services/mining-wallet-service/prisma/seed.ts index 9f0f5c12..c6d22f8c 100644 --- a/backend/services/mining-wallet-service/prisma/seed.ts +++ b/backend/services/mining-wallet-service/prisma/seed.ts @@ -66,7 +66,7 @@ async function main() { // 积分股池A: 100亿 (10,000,000,000) - 用于销毁 // 积分股池B: 200万 (2,000,000) - 用于挖矿分配 // 总计: 100.02亿 (10,002,000,000) - // 直接 upsert 覆盖,不检查是否存在 + // upsert: 已存在时只更新元数据(name/description),不覆盖余额等运营数据 const poolAccounts = [ { poolType: 'SHARE_POOL_A', @@ -99,10 +99,8 @@ async function main() { const created = await prisma.poolAccount.upsert({ where: { poolType: pool.poolType as any }, update: { + // 仅更新元数据,绝不覆盖 balance/targetBurn/remainingBurn name: pool.name, - balance: pool.balance, - targetBurn: pool.targetBurn, - remainingBurn: pool.targetBurn, description: pool.description, isActive: true, },