rwadurian/frontend/admin-web/src/app/(dashboard)/users/[id]/page.tsx

804 lines
37 KiB
TypeScript

'use client';
import { useState, useCallback } from 'react';
import { useParams, useRouter } from 'next/navigation';
import Image from 'next/image';
import Link from 'next/link';
import { Button, toast } from '@/components/common';
import { PageContainer } from '@/components/layout';
import { cn } from '@/utils/helpers';
import { formatNumber, formatRanking } from '@/utils/formatters';
import {
useUserFullDetail,
useReferralTree,
usePlantingLedger,
useWalletLedger,
useAuthorizationDetail,
} from '@/hooks/useUserDetailPage';
import type {
ReferralNode,
PlantingLedgerItem,
WalletLedgerItem,
WALLET_ENTRY_TYPE_LABELS,
ASSET_TYPE_LABELS,
PLANTING_STATUS_LABELS,
AUTHORIZATION_ROLE_LABELS,
AUTHORIZATION_STATUS_LABELS,
ASSESSMENT_RESULT_LABELS,
} from '@/types/userDetail.types';
import styles from './user-detail.module.scss';
// Tab 类型
type TabType = 'referral' | 'planting' | 'wallet' | 'authorization';
const tabs: { key: TabType; label: string }[] = [
{ key: 'referral', label: '推荐关系' },
{ key: 'planting', label: '认种信息' },
{ key: 'wallet', label: '钱包信息' },
{ key: 'authorization', label: '授权信息' },
];
// 流水类型标签
const entryTypeLabels: Record<string, string> = {
DEPOSIT: '充值',
DEPOSIT_USDT: 'USDT充值',
DEPOSIT_BNB: 'BNB充值',
WITHDRAW: '提现',
WITHDRAW_FROZEN: '提现冻结',
WITHDRAW_CONFIRMED: '提现确认',
WITHDRAW_CANCELLED: '提现取消',
PLANTING_PAYMENT: '认种支付',
PLANTING_FROZEN: '认种冻结',
PLANTING_DEDUCT: '认种扣款',
REWARD_PENDING: '收益待领取',
REWARD_SETTLED: '收益结算',
REWARD_EXPIRED: '收益过期',
TRANSFER_OUT: '转出',
TRANSFER_IN: '转入',
INTERNAL_TRANSFER: '内部转账',
ADMIN_ADJUSTMENT: '管理员调整',
SYSTEM_DEDUCT: '系统扣款',
FEE: '手续费',
};
const assetTypeLabels: Record<string, string> = {
USDT: '绿积分',
DST: 'DST',
BNB: 'BNB',
OG: 'OG',
RWAD: 'RWAD',
HASHPOWER: '算力',
};
const plantingStatusLabels: Record<string, string> = {
CREATED: '已创建',
PAID: '已支付',
FUND_ALLOCATED: '资金已分配',
MINING_ENABLED: '已开始挖矿',
CANCELLED: '已取消',
EXPIRED: '已过期',
};
const roleTypeLabels: Record<string, string> = {
COMMUNITY_PARTNER: '社区合伙人',
PROVINCE_COMPANY: '省公司',
CITY_COMPANY: '市公司',
AUTH_PROVINCE_COMPANY: '授权省公司',
AUTH_CITY_COMPANY: '授权市公司',
};
const authStatusLabels: Record<string, string> = {
PENDING: '待授权',
AUTHORIZED: '已授权',
REVOKED: '已撤销',
EXPIRED: '已过期',
};
const assessmentResultLabels: Record<string, string> = {
NOT_ASSESSED: '未考核',
PASSED: '通过',
FAILED: '未通过',
BYPASSED: '豁免',
};
/**
* 用户详情页面
*/
export default function UserDetailPage() {
const params = useParams();
const router = useRouter();
const accountSequence = params.id as string;
const [activeTab, setActiveTab] = useState<TabType>('referral');
const [treeRootUser, setTreeRootUser] = useState<string>(accountSequence);
const [plantingPage, setPlantingPage] = useState(1);
const [walletPage, setWalletPage] = useState(1);
// 获取用户完整信息
const { data: userDetail, isLoading: detailLoading, error: detailError } = useUserFullDetail(accountSequence);
// 获取推荐关系树(以当前选中的用户为根)
const { data: referralTree, isLoading: treeLoading } = useReferralTree(treeRootUser, 'both', 1);
// 获取认种分类账
const { data: plantingData, isLoading: plantingLoading } = usePlantingLedger(accountSequence, {
page: plantingPage,
pageSize: 10,
});
// 获取钱包分类账
const { data: walletData, isLoading: walletLoading } = useWalletLedger(accountSequence, {
page: walletPage,
pageSize: 10,
});
// 获取授权信息
const { data: authData, isLoading: authLoading } = useAuthorizationDetail(accountSequence);
// 切换推荐关系树的根节点
const handleTreeNodeClick = useCallback((node: ReferralNode) => {
setTreeRootUser(node.accountSequence);
}, []);
// 返回列表
const handleBack = useCallback(() => {
router.push('/users');
}, [router]);
// 格式化日期
const formatDate = (dateStr: string | null) => {
if (!dateStr) return '-';
return new Date(dateStr).toLocaleString('zh-CN');
};
// 格式化金额
const formatAmount = (amount: string | null) => {
if (!amount) return '-';
const num = parseFloat(amount);
return num.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 8 });
};
if (detailLoading) {
return (
<PageContainer title="用户详情">
<div className={styles.loading}>...</div>
</PageContainer>
);
}
if (detailError || !userDetail) {
return (
<PageContainer title="用户详情">
<div className={styles.error}>
<p>: {(detailError as Error)?.message || '用户不存在'}</p>
<Button onClick={handleBack}></Button>
</div>
</PageContainer>
);
}
return (
<PageContainer title={`用户详情 - ${userDetail.accountSequence}`}>
<div className={styles.userDetail}>
{/* 返回按钮 */}
<div className={styles.userDetail__backBar}>
<button className={styles.userDetail__backBtn} onClick={handleBack}>
<span className={styles.userDetail__backIcon}></span>
</button>
</div>
{/* 用户基本信息卡片 */}
<div className={styles.userDetail__basicCard}>
<div className={styles.userDetail__basicHeader}>
<div
className={styles.userDetail__avatar}
style={{ backgroundImage: `url(${userDetail.avatar || '/images/Data@2x.png'})` }}
>
<div
className={cn(
styles.userDetail__status,
userDetail.isOnline ? styles['userDetail__status--online'] : styles['userDetail__status--offline']
)}
/>
</div>
<div className={styles.userDetail__basicInfo}>
<h1 className={styles.userDetail__nickname}>
{userDetail.nickname || '未设置昵称'}
<span className={cn(
styles.userDetail__statusBadge,
styles[`userDetail__statusBadge--${userDetail.status}`]
)}>
{userDetail.status === 'active' ? '正常' : userDetail.status === 'frozen' ? '冻结' : '停用'}
</span>
</h1>
<div className={styles.userDetail__basicMeta}>
<span>: <strong>{userDetail.accountSequence}</strong></span>
<span>: {userDetail.phoneNumberMasked || '未绑定'}</span>
<span>KYC: {userDetail.kycStatus}</span>
</div>
<div className={styles.userDetail__basicMeta}>
<span>: {formatDate(userDetail.registeredAt)}</span>
<span>: {formatDate(userDetail.lastActiveAt)}</span>
</div>
</div>
</div>
{/* 统计卡片 */}
<div className={styles.userDetail__statsGrid}>
<div className={styles.userDetail__statCard}>
<span className={styles.userDetail__statLabel}></span>
<span className={styles.userDetail__statValue}>{formatNumber(userDetail.personalAdoptions)}</span>
</div>
<div className={styles.userDetail__statCard}>
<span className={styles.userDetail__statLabel}></span>
<span className={styles.userDetail__statValue}>{formatNumber(userDetail.teamAdoptions)}</span>
</div>
<div className={styles.userDetail__statCard}>
<span className={styles.userDetail__statLabel}></span>
<span className={styles.userDetail__statValue}>{formatNumber(userDetail.teamAddresses)}</span>
</div>
<div className={styles.userDetail__statCard}>
<span className={styles.userDetail__statLabel}></span>
<span className={cn(
styles.userDetail__statValue,
userDetail.ranking && userDetail.ranking <= 10 && styles['userDetail__statValue--gold']
)}>
{userDetail.ranking ? formatRanking(userDetail.ranking) : '-'}
</span>
</div>
<div className={styles.userDetail__statCard}>
<span className={styles.userDetail__statLabel}></span>
<span className={styles.userDetail__statValue}>
{formatNumber(userDetail.referralInfo.directReferralCount)}
</span>
</div>
<div className={styles.userDetail__statCard}>
<span className={styles.userDetail__statLabel}></span>
<span className={styles.userDetail__statValue}>
{formatNumber(userDetail.referralInfo.activeDirectCount)}
</span>
</div>
</div>
{/* 推荐人信息 */}
{userDetail.referralInfo.referrerSequence && (
<div className={styles.userDetail__referrerInfo}>
<span className={styles.userDetail__referrerLabel}>:</span>
<Link
href={`/users/${userDetail.referralInfo.referrerSequence}`}
className={styles.userDetail__referrerLink}
>
{userDetail.referralInfo.referrerSequence}
{userDetail.referralInfo.referrerNickname && ` (${userDetail.referralInfo.referrerNickname})`}
</Link>
<span className={styles.userDetail__referrerMeta}>
: {userDetail.referralInfo.usedReferralCode || '-'}
</span>
<span className={styles.userDetail__referrerMeta}>
: {userDetail.referralInfo.depth}
</span>
</div>
)}
</div>
{/* Tab 切换 */}
<div className={styles.userDetail__tabs}>
{tabs.map((tab) => (
<button
key={tab.key}
className={cn(
styles.userDetail__tab,
activeTab === tab.key && styles['userDetail__tab--active']
)}
onClick={() => setActiveTab(tab.key)}
>
{tab.label}
</button>
))}
</div>
{/* Tab 内容 */}
<div className={styles.userDetail__tabContent}>
{/* 推荐关系 Tab */}
{activeTab === 'referral' && (
<div className={styles.referralTab}>
<div className={styles.referralTab__header}>
<h3></h3>
{treeRootUser !== accountSequence && (
<Button
variant="outline"
size="sm"
onClick={() => setTreeRootUser(accountSequence)}
>
</Button>
)}
</div>
{treeLoading ? (
<div className={styles.referralTab__loading}>...</div>
) : referralTree ? (
<div className={styles.referralTree}>
{/* 向上的推荐人链 */}
{referralTree.ancestors.length > 0 && (
<div className={styles.referralTree__ancestors}>
<div className={styles.referralTree__label}> ()</div>
<div className={styles.referralTree__nodeList}>
{referralTree.ancestors.map((ancestor, index) => (
<div key={ancestor.accountSequence} className={styles.referralTree__nodeWrapper}>
<button
className={styles.referralTree__node}
onClick={() => handleTreeNodeClick(ancestor)}
>
<span className={styles.referralTree__nodeSeq}>{ancestor.accountSequence}</span>
<span className={styles.referralTree__nodeNickname}>
{ancestor.nickname || '未设置'}
</span>
<span className={styles.referralTree__nodeAdoptions}>
: {formatNumber(ancestor.personalAdoptions)}
</span>
</button>
{index < referralTree.ancestors.length - 1 && (
<div className={styles.referralTree__connector}></div>
)}
</div>
))}
</div>
<div className={styles.referralTree__connector}></div>
</div>
)}
{/* 当前用户 */}
<div className={styles.referralTree__current}>
<div
className={cn(
styles.referralTree__node,
styles['referralTree__node--current'],
referralTree.currentUser.accountSequence === accountSequence &&
styles['referralTree__node--highlight']
)}
>
<span className={styles.referralTree__nodeSeq}>
{referralTree.currentUser.accountSequence}
</span>
<span className={styles.referralTree__nodeNickname}>
{referralTree.currentUser.nickname || '未设置'}
</span>
<span className={styles.referralTree__nodeAdoptions}>
: {formatNumber(referralTree.currentUser.personalAdoptions)}
</span>
<span className={styles.referralTree__nodeCount}>
: {formatNumber(referralTree.currentUser.directReferralCount)}
</span>
</div>
</div>
{/* 直推用户 */}
{referralTree.directReferrals.length > 0 && (
<div className={styles.referralTree__directReferrals}>
<div className={styles.referralTree__connector}></div>
<div className={styles.referralTree__label}>
({referralTree.directReferrals.length})
</div>
<div className={styles.referralTree__nodeGrid}>
{referralTree.directReferrals.map((referral) => (
<button
key={referral.accountSequence}
className={styles.referralTree__node}
onClick={() => handleTreeNodeClick(referral)}
>
<span className={styles.referralTree__nodeSeq}>{referral.accountSequence}</span>
<span className={styles.referralTree__nodeNickname}>
{referral.nickname || '未设置'}
</span>
<span className={styles.referralTree__nodeAdoptions}>
: {formatNumber(referral.personalAdoptions)}
</span>
{referral.directReferralCount > 0 && (
<span className={styles.referralTree__nodeCount}>
: {formatNumber(referral.directReferralCount)}
</span>
)}
</button>
))}
</div>
</div>
)}
{referralTree.directReferrals.length === 0 && referralTree.ancestors.length === 0 && (
<div className={styles.referralTree__empty}></div>
)}
</div>
) : (
<div className={styles.referralTab__empty}></div>
)}
</div>
)}
{/* 认种信息 Tab */}
{activeTab === 'planting' && (
<div className={styles.plantingTab}>
{plantingLoading ? (
<div className={styles.plantingTab__loading}>...</div>
) : plantingData ? (
<>
{/* 认种汇总 */}
<div className={styles.plantingTab__summary}>
<h3></h3>
<div className={styles.plantingTab__summaryGrid}>
<div className={styles.plantingTab__summaryItem}>
<span className={styles.plantingTab__summaryLabel}></span>
<span className={styles.plantingTab__summaryValue}>
{formatNumber(plantingData.summary.totalOrders)}
</span>
</div>
<div className={styles.plantingTab__summaryItem}>
<span className={styles.plantingTab__summaryLabel}></span>
<span className={styles.plantingTab__summaryValue}>
{formatNumber(plantingData.summary.totalTreeCount)}
</span>
</div>
<div className={styles.plantingTab__summaryItem}>
<span className={styles.plantingTab__summaryLabel}> (绿)</span>
<span className={styles.plantingTab__summaryValue}>
{formatAmount(plantingData.summary.totalAmount)}
</span>
</div>
<div className={styles.plantingTab__summaryItem}>
<span className={styles.plantingTab__summaryLabel}></span>
<span className={styles.plantingTab__summaryValue}>
{formatNumber(plantingData.summary.effectiveTreeCount)}
</span>
</div>
<div className={styles.plantingTab__summaryItem}>
<span className={styles.plantingTab__summaryLabel}></span>
<span className={styles.plantingTab__summaryValue}>
{formatDate(plantingData.summary.firstPlantingAt)}
</span>
</div>
<div className={styles.plantingTab__summaryItem}>
<span className={styles.plantingTab__summaryLabel}></span>
<span className={styles.plantingTab__summaryValue}>
{formatDate(plantingData.summary.lastPlantingAt)}
</span>
</div>
</div>
</div>
{/* 认种分类账 */}
<div className={styles.plantingTab__ledger}>
<h3></h3>
<div className={styles.ledgerTable}>
<div className={styles.ledgerTable__header}>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
</div>
{plantingData.items.length === 0 ? (
<div className={styles.ledgerTable__empty}></div>
) : (
plantingData.items.map((item) => (
<div key={item.orderId} className={styles.ledgerTable__row}>
<div className={styles.ledgerTable__cell}>{item.orderNo}</div>
<div className={styles.ledgerTable__cell}>{formatNumber(item.treeCount)}</div>
<div className={styles.ledgerTable__cell}>{formatAmount(item.totalAmount)}</div>
<div className={styles.ledgerTable__cell}>
<span className={cn(
styles.ledgerTable__status,
styles[`ledgerTable__status--${item.status.toLowerCase()}`]
)}>
{plantingStatusLabels[item.status] || item.status}
</span>
</div>
<div className={styles.ledgerTable__cell}>
{item.selectedProvince || '-'} / {item.selectedCity || '-'}
</div>
<div className={styles.ledgerTable__cell}>{formatDate(item.createdAt)}</div>
<div className={styles.ledgerTable__cell}>{formatDate(item.paidAt)}</div>
</div>
))
)}
</div>
{/* 分页 */}
{plantingData.totalPages > 1 && (
<div className={styles.pagination}>
<button
disabled={plantingPage === 1}
onClick={() => setPlantingPage((p) => p - 1)}
>
</button>
<span> {plantingPage} / {plantingData.totalPages} </span>
<button
disabled={plantingPage === plantingData.totalPages}
onClick={() => setPlantingPage((p) => p + 1)}
>
</button>
</div>
)}
</div>
</>
) : (
<div className={styles.plantingTab__empty}></div>
)}
</div>
)}
{/* 钱包信息 Tab */}
{activeTab === 'wallet' && (
<div className={styles.walletTab}>
{walletLoading ? (
<div className={styles.walletTab__loading}>...</div>
) : walletData ? (
<>
{/* 钱包汇总 */}
<div className={styles.walletTab__summary}>
<h3></h3>
<div className={styles.walletTab__summaryGrid}>
<div className={styles.walletTab__summaryItem}>
<span className={styles.walletTab__summaryLabel}>绿 </span>
<span className={styles.walletTab__summaryValue}>
{formatAmount(walletData.summary.usdtAvailable)}
</span>
</div>
<div className={styles.walletTab__summaryItem}>
<span className={styles.walletTab__summaryLabel}>绿 </span>
<span className={styles.walletTab__summaryValue}>
{formatAmount(walletData.summary.usdtFrozen)}
</span>
</div>
<div className={styles.walletTab__summaryItem}>
<span className={styles.walletTab__summaryLabel}>DST </span>
<span className={styles.walletTab__summaryValue}>
{formatAmount(walletData.summary.dstAvailable)}
</span>
</div>
<div className={styles.walletTab__summaryItem}>
<span className={styles.walletTab__summaryLabel}></span>
<span className={styles.walletTab__summaryValue}>
{formatAmount(walletData.summary.hashpower)}
</span>
</div>
<div className={styles.walletTab__summaryItem}>
<span className={styles.walletTab__summaryLabel}></span>
<span className={styles.walletTab__summaryValue}>
{formatAmount(walletData.summary.pendingUsdt)}
</span>
</div>
<div className={styles.walletTab__summaryItem}>
<span className={styles.walletTab__summaryLabel}></span>
<span className={styles.walletTab__summaryValue}>
{formatAmount(walletData.summary.settleableUsdt)}
</span>
</div>
<div className={styles.walletTab__summaryItem}>
<span className={styles.walletTab__summaryLabel}></span>
<span className={styles.walletTab__summaryValue}>
{formatAmount(walletData.summary.settledTotalUsdt)}
</span>
</div>
<div className={styles.walletTab__summaryItem}>
<span className={styles.walletTab__summaryLabel}></span>
<span className={styles.walletTab__summaryValue}>
{formatAmount(walletData.summary.expiredTotalUsdt)}
</span>
</div>
</div>
</div>
{/* 钱包分类账 */}
<div className={styles.walletTab__ledger}>
<h3></h3>
<div className={styles.ledgerTable}>
<div className={styles.ledgerTable__header}>
<div className={styles.ledgerTable__cell}>ID</div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
</div>
{walletData.items.length === 0 ? (
<div className={styles.ledgerTable__empty}></div>
) : (
walletData.items.map((item) => (
<div key={item.entryId} className={styles.ledgerTable__row}>
<div className={styles.ledgerTable__cell}>{item.entryId}</div>
<div className={styles.ledgerTable__cell}>
{entryTypeLabels[item.entryType] || item.entryType}
</div>
<div className={styles.ledgerTable__cell}>
{assetTypeLabels[item.assetType] || item.assetType}
</div>
<div className={cn(
styles.ledgerTable__cell,
parseFloat(item.amount) >= 0
? styles['ledgerTable__cell--positive']
: styles['ledgerTable__cell--negative']
)}>
{parseFloat(item.amount) >= 0 ? '+' : ''}{formatAmount(item.amount)}
</div>
<div className={styles.ledgerTable__cell}>
{formatAmount(item.balanceAfter)}
</div>
<div className={styles.ledgerTable__cell}>
{item.refOrderId || item.refTxHash || '-'}
</div>
<div className={styles.ledgerTable__cell}>{formatDate(item.createdAt)}</div>
</div>
))
)}
</div>
{/* 分页 */}
{walletData.totalPages > 1 && (
<div className={styles.pagination}>
<button
disabled={walletPage === 1}
onClick={() => setWalletPage((p) => p - 1)}
>
</button>
<span> {walletPage} / {walletData.totalPages} </span>
<button
disabled={walletPage === walletData.totalPages}
onClick={() => setWalletPage((p) => p + 1)}
>
</button>
</div>
)}
</div>
</>
) : (
<div className={styles.walletTab__empty}></div>
)}
</div>
)}
{/* 授权信息 Tab */}
{activeTab === 'authorization' && (
<div className={styles.authTab}>
{authLoading ? (
<div className={styles.authTab__loading}>...</div>
) : authData ? (
<>
{/* 授权角色列表 */}
<div className={styles.authTab__roles}>
<h3></h3>
{authData.roles.length === 0 ? (
<div className={styles.authTab__empty}></div>
) : (
<div className={styles.authTab__roleGrid}>
{authData.roles.map((role) => (
<div key={role.id} className={styles.authTab__roleCard}>
<div className={styles.authTab__roleHeader}>
<span className={styles.authTab__roleType}>
{roleTypeLabels[role.roleType] || role.roleType}
</span>
<span className={cn(
styles.authTab__roleStatus,
styles[`authTab__roleStatus--${role.status.toLowerCase()}`]
)}>
{authStatusLabels[role.status] || role.status}
</span>
</div>
<div className={styles.authTab__roleInfo}>
<p><strong>:</strong> {role.regionName} ({role.regionCode})</p>
<p><strong>:</strong> {role.displayTitle}</p>
<p>
<strong>:</strong>
{role.benefitActive ? (
<span className={styles.authTab__benefitActive}></span>
) : (
<span className={styles.authTab__benefitInactive}></span>
)}
</p>
<p><strong>:</strong> {formatNumber(role.initialTargetTreeCount)} </p>
<p><strong>:</strong> {role.monthlyTargetType}</p>
<p><strong>:</strong> {formatDate(role.authorizedAt)}</p>
</div>
</div>
))}
</div>
)}
</div>
{/* 月度考核记录 */}
<div className={styles.authTab__assessments}>
<h3></h3>
{authData.assessments.length === 0 ? (
<div className={styles.authTab__empty}></div>
) : (
<div className={styles.ledgerTable}>
<div className={styles.ledgerTable__header}>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}>/</div>
<div className={styles.ledgerTable__cell}>/</div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
</div>
{authData.assessments.map((assessment) => (
<div key={assessment.id} className={styles.ledgerTable__row}>
<div className={styles.ledgerTable__cell}>{assessment.assessmentMonth}</div>
<div className={styles.ledgerTable__cell}>
{roleTypeLabels[assessment.roleType] || assessment.roleType}
</div>
<div className={styles.ledgerTable__cell}>
{formatNumber(assessment.monthlyCompleted)} / {formatNumber(assessment.monthlyTarget)}
</div>
<div className={styles.ledgerTable__cell}>
{formatNumber(assessment.cumulativeCompleted)} / {formatNumber(assessment.cumulativeTarget)}
</div>
<div className={styles.ledgerTable__cell}>
<span className={cn(
styles.ledgerTable__result,
styles[`ledgerTable__result--${assessment.result.toLowerCase()}`]
)}>
{assessmentResultLabels[assessment.result] || assessment.result}
</span>
</div>
<div className={styles.ledgerTable__cell}>
{assessment.rankingInRegion || '-'}
{assessment.isFirstPlace && ' 🥇'}
</div>
</div>
))}
</div>
)}
</div>
{/* 系统账户流水(如果有) */}
{authData.systemAccountLedger.length > 0 && (
<div className={styles.authTab__systemLedger}>
<h3></h3>
<div className={styles.ledgerTable}>
<div className={styles.ledgerTable__header}>
<div className={styles.ledgerTable__cell}>ID</div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
<div className={styles.ledgerTable__cell}></div>
</div>
{authData.systemAccountLedger.map((ledger) => (
<div key={ledger.ledgerId} className={styles.ledgerTable__row}>
<div className={styles.ledgerTable__cell}>{ledger.ledgerId}</div>
<div className={styles.ledgerTable__cell}>{ledger.accountType}</div>
<div className={styles.ledgerTable__cell}>{ledger.entryType}</div>
<div className={cn(
styles.ledgerTable__cell,
parseFloat(ledger.amount) >= 0
? styles['ledgerTable__cell--positive']
: styles['ledgerTable__cell--negative']
)}>
{parseFloat(ledger.amount) >= 0 ? '+' : ''}{formatAmount(ledger.amount)}
</div>
<div className={styles.ledgerTable__cell}>{formatAmount(ledger.balanceAfter)}</div>
<div className={styles.ledgerTable__cell}>{formatDate(ledger.createdAt)}</div>
</div>
))}
</div>
</div>
)}
</>
) : (
<div className={styles.authTab__empty}></div>
)}
</div>
)}
</div>
</div>
</PageContainer>
);
}