feat(admin-web): 系统账户显示正式名称并保留编码

- 添加 SYSTEM_ACCOUNT_NAMES 映射:S0000000001-S0000000006 映射到正式名称
- 添加 PROVINCE_CODE_NAMES 映射:中国省份行政区划代码映射
- 添加 getAccountDisplayName 函数:统一显示格式 "名称 (编码)"
- FixedAccountsSection: 固定账户显示为 "总部账户 (S0000000001)" 格式
- RegionAccountsSection: 区域账户合并显示名称和编码
- LedgerAccountCard: 分类账卡片显示完整账户信息
- FeeAccountSection: 手续费归集账户显示正式名称
- RewardTypeSummarySection: 收益明细显示账户正式名称
- OfflineSettlementSection: 面对面结算明细显示账户正式名称

回滚方式:恢复 imports,删除映射常量和 getAccountDisplayName 函数

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-01-06 21:29:14 -08:00
parent ce1d342269
commit 2d9d6ceed7
2 changed files with 146 additions and 23 deletions

View File

@ -26,7 +26,7 @@ import type {
OfflineSettlementEntriesResponse,
OfflineSettlementEntryDTO,
} from '@/types';
import { ENTRY_TYPE_LABELS, ACCOUNT_TYPE_LABELS, FEE_TYPE_LABELS, REWARD_RIGHT_TYPE_LABELS, REWARD_STATUS_LABELS, FEE_COLLECTION_TYPE_LABELS } from '@/types';
import { ENTRY_TYPE_LABELS, ACCOUNT_TYPE_LABELS, FEE_TYPE_LABELS, REWARD_RIGHT_TYPE_LABELS, REWARD_STATUS_LABELS, FEE_COLLECTION_TYPE_LABELS, getAccountDisplayName, SYSTEM_ACCOUNT_NAMES, PROVINCE_CODE_NAMES } from '@/types';
import styles from './SystemAccountsTab.module.scss';
/**
@ -296,23 +296,23 @@ export default function SystemAccountsTab() {
* [2026-01-05] USDT改为绿积分
*/
function FixedAccountsSection({ data }: { data: SystemAccountReportResponse['fixedAccounts'] }) {
// [2026-01-07] 更新:使用 SYSTEM_ACCOUNT_NAMES 映射获取正式名称
const accounts = [
{ key: 'costAccount', label: '总部储备', sequence: 'S0000000001', data: data.costAccount },
{ key: 'operationAccount', label: '运营账户1', sequence: 'S0000000002', data: data.operationAccount },
{ key: 'hqCommunity', label: '运营账户2', sequence: 'S0000000003', data: data.hqCommunity },
{ key: 'rwadPoolPending', label: '积分股池', sequence: 'S0000000004', data: data.rwadPoolPending },
{ key: 'platformFee', label: '平台手续费', sequence: 'S0000000005', data: data.platformFee },
{ key: 'costAccount', sequence: 'S0000000001', data: data.costAccount },
{ key: 'operationAccount', sequence: 'S0000000002', data: data.operationAccount },
{ key: 'hqCommunity', sequence: 'S0000000003', data: data.hqCommunity },
{ key: 'rwadPoolPending', sequence: 'S0000000004', data: data.rwadPoolPending },
{ key: 'platformFee', sequence: 'S0000000005', data: data.platformFee },
];
return (
<div className={styles.section}>
<h3 className={styles.sectionTitle}></h3>
<div className={styles.cardGrid}>
{accounts.map(({ key, label, sequence, data: accountData }) => (
{accounts.map(({ key, sequence, data: accountData }) => (
<div key={key} className={styles.accountCard}>
<div className={styles.cardHeader}>
<span className={styles.accountLabel}>{label}</span>
<span className={styles.accountSequence}>{sequence}</span>
<span className={styles.accountLabel}>{getAccountDisplayName(sequence)}</span>
</div>
<div className={styles.cardBody}>
<div className={styles.statRow}>
@ -374,8 +374,7 @@ function RegionAccountsSection({ data, type }: { data: RegionAccountsSummary; ty
<table className={styles.table}>
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th> (绿)</th>
<th> (绿)</th>
<th></th>
@ -384,8 +383,8 @@ function RegionAccountsSection({ data, type }: { data: RegionAccountsSummary; ty
<tbody>
{data.accounts.map((account) => (
<tr key={account.id}>
<td>{account.regionCode || '-'}</td>
<td>{account.regionName || '-'}</td>
{/* [2026-01-07] 更新:合并显示区域名称和编码 */}
<td>{account.regionName ? `${account.regionName} (${account.regionCode})` : account.regionCode || '-'}</td>
<td>{formatAmount(account.usdtBalance)}</td>
<td>{formatAmount(account.totalReceived)}</td>
<td>
@ -519,7 +518,8 @@ function OfflineSettlementSection({ data }: { data: SystemAccountReportResponse[
<tbody>
{entriesData.entries.map((entry) => (
<tr key={entry.id}>
<td>{entry.accountSequence}</td>
{/* [2026-01-07] 更新:使用 getAccountDisplayName 显示账户名称和编码 */}
<td>{getAccountDisplayName(entry.accountSequence)}</td>
<td>{formatAmount(entry.amount)}</td>
<td>{entry.memo || '-'}</td>
<td>{new Date(entry.createdAt).toLocaleString('zh-CN')}</td>
@ -704,14 +704,15 @@ function LedgerSection({
</div>
{/* 固定系统账户分类账 */}
{/* [2026-01-07] 更新:使用 getAccountDisplayName 显示账户名称和编码 */}
{data.fixedAccountsLedger && data.fixedAccountsLedger.length > 0 && (
<div className={styles.ledgerGroup}>
<h4 className={styles.subTitle}></h4>
{data.fixedAccountsLedger.map((account) => (
<LedgerAccountCard
key={account.accountSequence}
title={getAccountTypeLabel(account.accountType)}
subtitle={account.accountSequence}
title={getAccountDisplayName(account.accountSequence)}
subtitle=""
ledger={account.ledger}
total={account.total}
expanded={expandedAccounts.has(account.accountSequence)}
@ -729,8 +730,8 @@ function LedgerSection({
{data.provinceAccountsLedger.map((account) => (
<LedgerAccountCard
key={account.accountSequence}
title={account.regionName || account.regionCode}
subtitle={account.accountSequence}
title={account.regionName ? `${account.regionName} (${account.accountSequence})` : getAccountDisplayName(account.accountSequence)}
subtitle=""
ledger={account.ledger}
total={account.total}
expanded={expandedAccounts.has(account.accountSequence)}
@ -748,8 +749,8 @@ function LedgerSection({
{data.cityAccountsLedger.map((account) => (
<LedgerAccountCard
key={account.accountSequence}
title={account.regionName || account.regionCode}
subtitle={account.accountSequence}
title={account.regionName ? `${account.regionName} (${account.accountSequence})` : getAccountDisplayName(account.accountSequence)}
subtitle=""
ledger={account.ledger}
total={account.total}
expanded={expandedAccounts.has(account.accountSequence)}
@ -807,7 +808,8 @@ function LedgerAccountCard({
<div className={styles.ledgerCardHeader} onClick={onToggle}>
<div className={styles.ledgerCardTitle}>
<span className={styles.accountName}>{title}</span>
<span className={styles.accountSequence}>{subtitle}</span>
{/* [2026-01-07] 更新subtitle 为空时不显示 */}
{subtitle && <span className={styles.accountSequence}>{subtitle}</span>}
</div>
<div className={styles.ledgerCardInfo}>
<span className={styles.ledgerCount}>{total} </span>
@ -957,9 +959,10 @@ function FeeAccountSection({
</div>
{/* 账户信息 */}
{/* [2026-01-07] 更新:使用 getAccountDisplayName 显示账户名称和编码 */}
<div className={styles.accountInfo}>
<span className={styles.accountLabel}>: </span>
<span className={styles.accountValue}>{data.accountSequence}</span>
<span className={styles.accountValue}>{getAccountDisplayName(data.accountSequence)}</span>
</div>
{/* 汇总卡片 */}
@ -1323,7 +1326,8 @@ function RewardTypeSummarySection({
{detailsData.entries.map((entry) => (
<tr key={entry.id}>
<td>{new Date(entry.createdAt).toLocaleString('zh-CN')}</td>
<td>{entry.accountSequence}</td>
{/* [2026-01-07] 更新:使用 getAccountDisplayName 显示账户名称和编码 */}
<td>{getAccountDisplayName(entry.accountSequence)}</td>
<td className={styles.orderId}>{entry.sourceOrderId}</td>
<td>{formatAmount(entry.usdtAmount)}</td>
<td>

View File

@ -380,3 +380,122 @@ export const FEE_COLLECTION_TYPE_LABELS: Record<string, string> = {
FIAT_WITHDRAWAL_FEE: '法币提现手续费',
UNKNOWN: '未知类型',
};
// [2026-01-07] 新增:系统账户名称映射
/**
*
*/
export const SYSTEM_ACCOUNT_NAMES: Record<string, string> = {
'S0000000001': '总部账户',
'S0000000002': '成本账户',
'S0000000003': '运营账户',
'S0000000004': 'RWAD底池',
'S0000000005': '分享权益池',
'S0000000006': '手续费归集',
};
// [2026-01-07] 新增:省份行政区划代码映射
/**
*
*/
export const PROVINCE_CODE_NAMES: Record<string, string> = {
'11': '北京市',
'12': '天津市',
'13': '河北省',
'14': '山西省',
'15': '内蒙古自治区',
'21': '辽宁省',
'22': '吉林省',
'23': '黑龙江省',
'31': '上海市',
'32': '江苏省',
'33': '浙江省',
'34': '安徽省',
'35': '福建省',
'36': '江西省',
'37': '山东省',
'41': '河南省',
'42': '湖北省',
'43': '湖南省',
'44': '广东省',
'45': '广西壮族自治区',
'46': '海南省',
'50': '重庆市',
'51': '四川省',
'52': '贵州省',
'53': '云南省',
'54': '西藏自治区',
'61': '陕西省',
'62': '甘肃省',
'63': '青海省',
'64': '宁夏回族自治区',
'65': '新疆维吾尔自治区',
'71': '台湾省',
'81': '香港特别行政区',
'82': '澳门特别行政区',
// 带0000后缀的格式某些系统可能使用
'110000': '北京市',
'120000': '天津市',
'130000': '河北省',
'140000': '山西省',
'150000': '内蒙古自治区',
'210000': '辽宁省',
'220000': '吉林省',
'230000': '黑龙江省',
'310000': '上海市',
'320000': '江苏省',
'330000': '浙江省',
'340000': '安徽省',
'350000': '福建省',
'360000': '江西省',
'370000': '山东省',
'410000': '河南省',
'420000': '湖北省',
'430000': '湖南省',
'440000': '广东省',
'450000': '广西壮族自治区',
'460000': '海南省',
'500000': '重庆市',
'510000': '四川省',
'520000': '贵州省',
'530000': '云南省',
'540000': '西藏自治区',
'610000': '陕西省',
'620000': '甘肃省',
'630000': '青海省',
'640000': '宁夏回族自治区',
'650000': '新疆维吾尔自治区',
'710000': '台湾省',
'810000': '香港特别行政区',
'820000': '澳门特别行政区',
};
/**
*
* ()
*/
export function getAccountDisplayName(accountSequence: string): string {
// 检查是否是系统账户
if (SYSTEM_ACCOUNT_NAMES[accountSequence]) {
return `${SYSTEM_ACCOUNT_NAMES[accountSequence]} (${accountSequence})`;
}
// 检查是否是7位数字的区域账户
if (/^\d{7}$/.test(accountSequence)) {
const provinceCode = accountSequence.substring(0, 2);
const cityPart = accountSequence.substring(2, 4);
const provinceName = PROVINCE_CODE_NAMES[provinceCode];
if (provinceName) {
// 判断是省级还是市级账户
if (cityPart === '00') {
// 省级账户
return `${provinceName}(省级)(${accountSequence})`;
} else {
// 市级账户 - 显示省份简称 + 市级代码
const shortProvinceName = provinceName.replace(/省|市|自治区|特别行政区|壮族|回族|维吾尔/g, '');
return `${shortProvinceName}${cityPart}市 (${accountSequence})`;
}
}
}
return accountSequence;
}