rwadurian/backend/services/mining-service/src/api/controllers/admin.controller.ts

174 lines
5.5 KiB
TypeScript

import { Controller, Get, Post, HttpException, HttpStatus } from '@nestjs/common';
import { ApiTags, ApiOperation } from '@nestjs/swagger';
import { ConfigService } from '@nestjs/config';
import { PrismaService } from '../../infrastructure/persistence/prisma/prisma.service';
import { NetworkSyncService } from '../../application/services/network-sync.service';
import { Public } from '../../shared/guards/jwt-auth.guard';
@ApiTags('Admin')
@Controller('admin')
export class AdminController {
constructor(
private readonly prisma: PrismaService,
private readonly networkSyncService: NetworkSyncService,
private readonly configService: ConfigService,
) {}
@Get('accounts/sync')
@Public()
@ApiOperation({ summary: '获取所有挖矿账户用于同步' })
async getAllAccountsForSync() {
const accounts = await this.prisma.miningAccount.findMany({
select: {
accountSequence: true,
totalMined: true,
availableBalance: true,
frozenBalance: true,
totalContribution: true,
createdAt: true,
updatedAt: true,
},
});
return {
accounts: accounts.map((acc) => ({
accountSequence: acc.accountSequence,
totalMined: acc.totalMined.toString(),
availableBalance: acc.availableBalance.toString(),
frozenBalance: acc.frozenBalance.toString(),
totalContribution: acc.totalContribution.toString(),
createdAt: acc.createdAt,
updatedAt: acc.updatedAt,
})),
total: accounts.length,
};
}
@Get('status')
@Public()
@ApiOperation({ summary: '获取挖矿系统状态' })
async getStatus() {
const config = await this.prisma.miningConfig.findFirst();
const accountCount = await this.prisma.miningAccount.count();
// 用户有效算力
const userContribution = await this.prisma.miningAccount.aggregate({
_sum: { totalContribution: true },
});
// 系统账户算力
const systemContribution = await this.prisma.systemMiningAccount.aggregate({
_sum: { totalContribution: true },
});
// 待解锁算力
const pendingContribution = await this.prisma.pendingContributionMining.aggregate({
_sum: { amount: true },
where: { isExpired: false },
});
return {
initialized: !!config,
isActive: config?.isActive || false,
activatedAt: config?.activatedAt,
currentEra: config?.currentEra || 0,
remainingDistribution: config?.remainingDistribution?.toString() || '0',
secondDistribution: config?.secondDistribution?.toString() || '0',
accountCount,
// 用户有效算力
totalContribution: userContribution._sum.totalContribution?.toString() || '0',
// 全网理论算力(从 contribution-service 同步)
networkTotalContribution: config?.networkTotalContribution?.toString() || '0',
totalTreeCount: config?.totalTreeCount || 0,
contributionPerTree: config?.contributionPerTree?.toString() || '22617',
networkLastSyncedAt: config?.networkLastSyncedAt,
// 系统账户算力
systemContribution: systemContribution._sum.totalContribution?.toString() || '0',
// 待解锁算力
pendingContribution: pendingContribution._sum.amount?.toString() || '0',
};
}
@Post('activate')
@Public()
@ApiOperation({ summary: '激活挖矿系统' })
async activate() {
const config = await this.prisma.miningConfig.findFirst();
if (!config) {
throw new HttpException('挖矿系统未初始化,请先运行 seed 脚本', HttpStatus.BAD_REQUEST);
}
if (config.isActive) {
return { success: true, message: '挖矿系统已经处于激活状态' };
}
await this.prisma.miningConfig.update({
where: { id: config.id },
data: {
isActive: true,
activatedAt: new Date(),
},
});
return { success: true, message: '挖矿系统已激活' };
}
@Post('deactivate')
@Public()
@ApiOperation({ summary: '停用挖矿系统' })
async deactivate() {
const config = await this.prisma.miningConfig.findFirst();
if (!config) {
throw new HttpException('挖矿系统未初始化', HttpStatus.BAD_REQUEST);
}
if (!config.isActive) {
return { success: true, message: '挖矿系统已经处于停用状态' };
}
await this.prisma.miningConfig.update({
where: { id: config.id },
data: {
isActive: false,
},
});
return { success: true, message: '挖矿系统已停用' };
}
@Post('sync-network')
@Public()
@ApiOperation({ summary: '从 contribution-service 同步全网数据(系统账户、全网进度)' })
async syncNetwork() {
const contributionServiceUrl = this.configService.get<string>(
'CONTRIBUTION_SERVICE_URL',
'http://localhost:3020',
);
return this.networkSyncService.syncFromContributionService(contributionServiceUrl);
}
@Get('system-accounts')
@Public()
@ApiOperation({ summary: '获取系统账户挖矿状态' })
async getSystemAccounts() {
const accounts = await this.prisma.systemMiningAccount.findMany({
orderBy: { accountType: 'asc' },
});
return {
accounts: accounts.map((acc) => ({
accountType: acc.accountType,
name: acc.name,
totalMined: acc.totalMined.toString(),
availableBalance: acc.availableBalance.toString(),
totalContribution: acc.totalContribution.toString(),
lastSyncedAt: acc.lastSyncedAt,
})),
total: accounts.length,
};
}
}