feat(mining-admin): 重构算力构成展示,添加解锁状态
- 后端添加 unlockedBonusTiers 字段同步 - 前端算力构成卡片展示层级解锁(L1-15)和团队奖励解锁(3档)状态 - 移除无用的系统运营/省级/市级字段 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
4ca4fc9135
commit
180e5ad057
|
|
@ -0,0 +1,2 @@
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "synced_contribution_accounts" ADD COLUMN "unlockedBonusTiers" INTEGER NOT NULL DEFAULT 0;
|
||||||
|
|
@ -191,6 +191,7 @@ model SyncedContributionAccount {
|
||||||
hasAdopted Boolean @default(false)
|
hasAdopted Boolean @default(false)
|
||||||
directReferralCount Int @default(0)
|
directReferralCount Int @default(0)
|
||||||
unlockedLevelDepth Int @default(0)
|
unlockedLevelDepth Int @default(0)
|
||||||
|
unlockedBonusTiers Int @default(0)
|
||||||
syncedAt DateTime @default(now())
|
syncedAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,7 @@ export class InitializationService {
|
||||||
hasAdopted: account.hasAdopted || false,
|
hasAdopted: account.hasAdopted || false,
|
||||||
directReferralCount: account.directReferralAdoptedCount || 0,
|
directReferralCount: account.directReferralAdoptedCount || 0,
|
||||||
unlockedLevelDepth: account.unlockedLevelDepth || 0,
|
unlockedLevelDepth: account.unlockedLevelDepth || 0,
|
||||||
|
unlockedBonusTiers: account.unlockedBonusTiers || 0,
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
personalContribution: account.personalContribution,
|
personalContribution: account.personalContribution,
|
||||||
|
|
@ -184,6 +185,7 @@ export class InitializationService {
|
||||||
hasAdopted: account.hasAdopted,
|
hasAdopted: account.hasAdopted,
|
||||||
directReferralCount: account.directReferralAdoptedCount,
|
directReferralCount: account.directReferralAdoptedCount,
|
||||||
unlockedLevelDepth: account.unlockedLevelDepth,
|
unlockedLevelDepth: account.unlockedLevelDepth,
|
||||||
|
unlockedBonusTiers: account.unlockedBonusTiers,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
syncedCount++;
|
syncedCount++;
|
||||||
|
|
|
||||||
|
|
@ -325,6 +325,9 @@ export class UsersService {
|
||||||
totalContribution: '0',
|
totalContribution: '0',
|
||||||
effectiveContribution: '0',
|
effectiveContribution: '0',
|
||||||
hasAdopted: false,
|
hasAdopted: false,
|
||||||
|
directReferralCount: 0,
|
||||||
|
unlockedLevelDepth: 0,
|
||||||
|
unlockedBonusTiers: 0,
|
||||||
},
|
},
|
||||||
records: [],
|
records: [],
|
||||||
pagination: { page, pageSize, total: 0, totalPages: 0 },
|
pagination: { page, pageSize, total: 0, totalPages: 0 },
|
||||||
|
|
@ -342,6 +345,7 @@ export class UsersService {
|
||||||
hasAdopted: contribution.hasAdopted,
|
hasAdopted: contribution.hasAdopted,
|
||||||
directReferralCount: contribution.directReferralCount,
|
directReferralCount: contribution.directReferralCount,
|
||||||
unlockedLevelDepth: contribution.unlockedLevelDepth,
|
unlockedLevelDepth: contribution.unlockedLevelDepth,
|
||||||
|
unlockedBonusTiers: contribution.unlockedBonusTiers,
|
||||||
},
|
},
|
||||||
// 详细流水需要从 contribution-service 获取
|
// 详细流水需要从 contribution-service 获取
|
||||||
records: [],
|
records: [],
|
||||||
|
|
@ -883,6 +887,7 @@ export class UsersService {
|
||||||
hasAdopted: user.contributionAccount.hasAdopted,
|
hasAdopted: user.contributionAccount.hasAdopted,
|
||||||
directReferralCount: user.contributionAccount.directReferralCount,
|
directReferralCount: user.contributionAccount.directReferralCount,
|
||||||
unlockedLevelDepth: user.contributionAccount.unlockedLevelDepth,
|
unlockedLevelDepth: user.contributionAccount.unlockedLevelDepth,
|
||||||
|
unlockedBonusTiers: user.contributionAccount.unlockedBonusTiers,
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
mining: user.miningAccount
|
mining: user.miningAccount
|
||||||
|
|
|
||||||
|
|
@ -447,6 +447,7 @@ export class CdcSyncService implements OnModuleInit {
|
||||||
hasAdopted: payload.hasAdopted || false,
|
hasAdopted: payload.hasAdopted || false,
|
||||||
directReferralCount: payload.directReferralAdoptedCount || 0,
|
directReferralCount: payload.directReferralAdoptedCount || 0,
|
||||||
unlockedLevelDepth: payload.unlockedLevelDepth || 0,
|
unlockedLevelDepth: payload.unlockedLevelDepth || 0,
|
||||||
|
unlockedBonusTiers: payload.unlockedBonusTiers || 0,
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
personalContribution: payload.personalContribution,
|
personalContribution: payload.personalContribution,
|
||||||
|
|
@ -457,6 +458,7 @@ export class CdcSyncService implements OnModuleInit {
|
||||||
hasAdopted: payload.hasAdopted,
|
hasAdopted: payload.hasAdopted,
|
||||||
directReferralCount: payload.directReferralAdoptedCount,
|
directReferralCount: payload.directReferralAdoptedCount,
|
||||||
unlockedLevelDepth: payload.unlockedLevelDepth,
|
unlockedLevelDepth: payload.unlockedLevelDepth,
|
||||||
|
unlockedBonusTiers: payload.unlockedBonusTiers,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -496,6 +498,7 @@ export class CdcSyncService implements OnModuleInit {
|
||||||
hasAdopted: true, // 有算力计算说明已认种
|
hasAdopted: true, // 有算力计算说明已认种
|
||||||
directReferralCount: 0,
|
directReferralCount: 0,
|
||||||
unlockedLevelDepth: 0,
|
unlockedLevelDepth: 0,
|
||||||
|
unlockedBonusTiers: 0,
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
// 增量更新个人算力
|
// 增量更新个人算力
|
||||||
|
|
|
||||||
|
|
@ -175,35 +175,120 @@ export default function UserDetailPage() {
|
||||||
算力构成
|
算力构成
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-3">
|
<CardContent className="space-y-4">
|
||||||
<div className="flex justify-between">
|
{/* 个人算力 */}
|
||||||
<span className="text-sm text-muted-foreground">个人算力</span>
|
<div className="flex justify-between items-center">
|
||||||
<span className="font-mono">{formatDecimal(user?.contributions?.personal, 4)}</span>
|
<span className="text-sm text-muted-foreground">个人算力 (70%)</span>
|
||||||
|
<span className="font-mono font-medium">{formatDecimal(user?.contributions?.personal, 4)}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between">
|
|
||||||
<span className="text-sm text-muted-foreground">系统运营</span>
|
{/* 层级算力 */}
|
||||||
<span className="font-mono">{formatDecimal(user?.contributions?.systemOperation, 4)}</span>
|
<div className="space-y-2">
|
||||||
|
<div className="flex justify-between items-center">
|
||||||
|
<span className="text-sm text-muted-foreground">层级算力 (7.5%)</span>
|
||||||
|
<span className="font-mono font-medium">{formatDecimal(user?.contributions?.teamLevel, 4)}</span>
|
||||||
|
</div>
|
||||||
|
<div className="pl-3 space-y-1 text-xs">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
{(user?.contributions?.unlockedLevelDepth ?? 0) >= 5 ? (
|
||||||
|
<span className="text-green-600">✓</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-muted-foreground">✗</span>
|
||||||
|
)}
|
||||||
|
<span className={`${(user?.contributions?.unlockedLevelDepth ?? 0) >= 5 ? 'text-foreground' : 'text-muted-foreground'}`}>
|
||||||
|
L1-L5 {(user?.contributions?.unlockedLevelDepth ?? 0) >= 5 ? '已解锁' : '未解锁'}
|
||||||
|
</span>
|
||||||
|
<span className="text-muted-foreground">(直推≥1人认种)</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
{(user?.contributions?.unlockedLevelDepth ?? 0) >= 10 ? (
|
||||||
|
<span className="text-green-600">✓</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-muted-foreground">✗</span>
|
||||||
|
)}
|
||||||
|
<span className={`${(user?.contributions?.unlockedLevelDepth ?? 0) >= 10 ? 'text-foreground' : 'text-muted-foreground'}`}>
|
||||||
|
L6-L10 {(user?.contributions?.unlockedLevelDepth ?? 0) >= 10 ? '已解锁' : '未解锁'}
|
||||||
|
</span>
|
||||||
|
<span className="text-muted-foreground">(直推≥3人认种)</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
{(user?.contributions?.unlockedLevelDepth ?? 0) >= 15 ? (
|
||||||
|
<span className="text-green-600">✓</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-muted-foreground">✗</span>
|
||||||
|
)}
|
||||||
|
<span className={`${(user?.contributions?.unlockedLevelDepth ?? 0) >= 15 ? 'text-foreground' : 'text-muted-foreground'}`}>
|
||||||
|
L11-L15 {(user?.contributions?.unlockedLevelDepth ?? 0) >= 15 ? '已解锁' : '未解锁'}
|
||||||
|
</span>
|
||||||
|
<span className="text-muted-foreground">(直推≥5人认种)</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between">
|
|
||||||
<span className="text-sm text-muted-foreground">系统省级</span>
|
{/* 团队奖励 */}
|
||||||
<span className="font-mono">{formatDecimal(user?.contributions?.systemProvince, 4)}</span>
|
<div className="space-y-2">
|
||||||
</div>
|
<div className="flex justify-between items-center">
|
||||||
<div className="flex justify-between">
|
<span className="text-sm text-muted-foreground">团队奖励 (7.5%)</span>
|
||||||
<span className="text-sm text-muted-foreground">系统市级</span>
|
<span className="font-mono font-medium">{formatDecimal(user?.contributions?.teamBonus, 4)}</span>
|
||||||
<span className="font-mono">{formatDecimal(user?.contributions?.systemCity, 4)}</span>
|
</div>
|
||||||
</div>
|
<div className="pl-3 space-y-1 text-xs">
|
||||||
<div className="flex justify-between">
|
<div className="flex items-center gap-2">
|
||||||
<span className="text-sm text-muted-foreground">团队层级</span>
|
{(user?.contributions?.unlockedBonusTiers ?? 0) >= 1 ? (
|
||||||
<span className="font-mono">{formatDecimal(user?.contributions?.teamLevel, 4)}</span>
|
<span className="text-green-600">✓</span>
|
||||||
</div>
|
) : (
|
||||||
<div className="flex justify-between">
|
<span className="text-muted-foreground">✗</span>
|
||||||
<span className="text-sm text-muted-foreground">团队奖励</span>
|
)}
|
||||||
<span className="font-mono">{formatDecimal(user?.contributions?.teamBonus, 4)}</span>
|
<span className={`${(user?.contributions?.unlockedBonusTiers ?? 0) >= 1 ? 'text-foreground' : 'text-muted-foreground'}`}>
|
||||||
|
第1档 2.5% {(user?.contributions?.unlockedBonusTiers ?? 0) >= 1 ? '已解锁' : '未解锁'}
|
||||||
|
</span>
|
||||||
|
<span className="text-muted-foreground">(自己认种)</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
{(user?.contributions?.unlockedBonusTiers ?? 0) >= 2 ? (
|
||||||
|
<span className="text-green-600">✓</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-muted-foreground">✗</span>
|
||||||
|
)}
|
||||||
|
<span className={`${(user?.contributions?.unlockedBonusTiers ?? 0) >= 2 ? 'text-foreground' : 'text-muted-foreground'}`}>
|
||||||
|
第2档 2.5% {(user?.contributions?.unlockedBonusTiers ?? 0) >= 2 ? '已解锁' : '未解锁'}
|
||||||
|
</span>
|
||||||
|
<span className="text-muted-foreground">(直推≥2人认种)</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
{(user?.contributions?.unlockedBonusTiers ?? 0) >= 3 ? (
|
||||||
|
<span className="text-green-600">✓</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-muted-foreground">✗</span>
|
||||||
|
)}
|
||||||
|
<span className={`${(user?.contributions?.unlockedBonusTiers ?? 0) >= 3 ? 'text-foreground' : 'text-muted-foreground'}`}>
|
||||||
|
第3档 2.5% {(user?.contributions?.unlockedBonusTiers ?? 0) >= 3 ? '已解锁' : '未解锁'}
|
||||||
|
</span>
|
||||||
|
<span className="text-muted-foreground">(直推≥4人认种)</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* 有效算力 */}
|
||||||
<div className="flex justify-between pt-3 border-t font-medium">
|
<div className="flex justify-between pt-3 border-t font-medium">
|
||||||
<span>有效算力 (贡献值)</span>
|
<span>有效算力 (贡献值)</span>
|
||||||
<span className="font-mono text-primary text-lg">{formatDecimal(user?.effectiveContribution, 4)}</span>
|
<span className="font-mono text-primary text-lg">{formatDecimal(user?.effectiveContribution, 4)}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* 解锁状态汇总 */}
|
||||||
|
<div className="pt-2 border-t text-xs text-muted-foreground">
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<span>直推认种人数</span>
|
||||||
|
<span className="font-mono">{user?.contributions?.directReferralCount ?? 0} 人</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<span>层级解锁深度</span>
|
||||||
|
<span className="font-mono">{user?.contributions?.unlockedLevelDepth ?? 0} / 15 级</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<span>奖励解锁档位</span>
|
||||||
|
<span className="font-mono">{user?.contributions?.unlockedBonusTiers ?? 0} / 3 档</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -54,15 +54,17 @@ function transformUserDetail(backendUser: any): UserDetail {
|
||||||
// 认种数据
|
// 认种数据
|
||||||
personalAdoptions: backendUser.adoption?.personalAdoptionCount || 0,
|
personalAdoptions: backendUser.adoption?.personalAdoptionCount || 0,
|
||||||
teamAdoptions: backendUser.adoption?.teamAdoptions || 0,
|
teamAdoptions: backendUser.adoption?.teamAdoptions || 0,
|
||||||
// 算力明细
|
// 算力明细及解锁状态
|
||||||
contributions: {
|
contributions: {
|
||||||
personal: backendUser.contribution?.personalContribution || '0',
|
personal: backendUser.contribution?.personalContribution || '0',
|
||||||
systemOperation: '0',
|
|
||||||
systemProvince: '0',
|
|
||||||
systemCity: '0',
|
|
||||||
teamLevel: backendUser.contribution?.teamLevelContribution || '0',
|
teamLevel: backendUser.contribution?.teamLevelContribution || '0',
|
||||||
teamBonus: backendUser.contribution?.teamBonusContribution || '0',
|
teamBonus: backendUser.contribution?.teamBonusContribution || '0',
|
||||||
total: backendUser.contribution?.totalContribution || '0',
|
total: backendUser.contribution?.totalContribution || '0',
|
||||||
|
// 解锁状态
|
||||||
|
hasAdopted: backendUser.contribution?.hasAdopted || false,
|
||||||
|
directReferralCount: backendUser.contribution?.directReferralCount || 0,
|
||||||
|
unlockedLevelDepth: backendUser.contribution?.unlockedLevelDepth || 0,
|
||||||
|
unlockedBonusTiers: backendUser.contribution?.unlockedBonusTiers || 0,
|
||||||
},
|
},
|
||||||
kycStatus: backendUser.kycStatus,
|
kycStatus: backendUser.kycStatus,
|
||||||
registeredAt: backendUser.createdAt,
|
registeredAt: backendUser.createdAt,
|
||||||
|
|
|
||||||
|
|
@ -53,12 +53,14 @@ export interface UserDetail extends UserOverview {
|
||||||
|
|
||||||
export interface ContributionBreakdown {
|
export interface ContributionBreakdown {
|
||||||
personal: string;
|
personal: string;
|
||||||
systemOperation: string;
|
|
||||||
systemProvince: string;
|
|
||||||
systemCity: string;
|
|
||||||
teamLevel: string;
|
teamLevel: string;
|
||||||
teamBonus: string;
|
teamBonus: string;
|
||||||
total: string;
|
total: string;
|
||||||
|
// 解锁状态
|
||||||
|
hasAdopted: boolean;
|
||||||
|
directReferralCount: number;
|
||||||
|
unlockedLevelDepth: number; // 0, 5, 10, 15
|
||||||
|
unlockedBonusTiers: number; // 0, 1, 2, 3
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ContributionRecord {
|
export interface ContributionRecord {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue