feat(mining-admin-web): 前端实现区域代码到中文名称转换
系统账户列表现在显示中文省市名称(如"广州市公司")而不是区域代码(如"440100账户") - 新增 region-codes.ts 包含完整的省市行政区划代码映射 - 修改 accounts-table.tsx 使用 getRegionDisplayName() 转换名称 - 修改 account-card.tsx 使用区域代码映射 - 修改账户详情页使用区域代码映射显示标题 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
71151eaabf
commit
cb9831f2fc
|
|
@ -39,6 +39,7 @@ import {
|
|||
} from '@/features/system-accounts';
|
||||
import { ContributionRecordsTable } from '@/features/system-accounts/components';
|
||||
import { getAccountDisplayInfo } from '@/types/system-account';
|
||||
import { getRegionDisplayName } from '@/lib/constants/region-codes';
|
||||
import { formatDecimal } from '@/lib/utils/format';
|
||||
|
||||
const TRANSACTION_TYPE_LABELS: Record<string, { label: string; color: string }> = {
|
||||
|
|
@ -106,7 +107,10 @@ export default function SystemAccountDetailPage() {
|
|||
? Math.ceil(transactions.total / pageSize)
|
||||
: 0;
|
||||
|
||||
const accountTitle = currentAccount?.name || displayInfo.label;
|
||||
// 使用前端区域代码映射获取显示名称
|
||||
const accountTitle = currentAccount?.regionCode
|
||||
? getRegionDisplayName(currentAccount.regionCode, currentAccount.accountType)
|
||||
: (currentAccount?.name || displayInfo.label);
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { formatDecimal } from '@/lib/utils/format';
|
||||
import { getAccountDisplayInfo, type SystemAccount } from '@/types/system-account';
|
||||
import { getRegionDisplayName } from '@/lib/constants/region-codes';
|
||||
import { Coins, Flame, ShoppingCart, Building2, Wallet, Landmark, Box } from 'lucide-react';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
|
||||
|
|
@ -26,7 +27,11 @@ export function AccountCard({ account }: AccountCardProps) {
|
|||
|
||||
// Use contributionBalance if available (synced), otherwise totalContribution (local)
|
||||
const balance = account.contributionBalance || account.totalContribution || '0';
|
||||
const displayName = account.name || displayInfo.label;
|
||||
|
||||
// 使用前端区域代码映射获取显示名称
|
||||
const displayName = account.regionCode
|
||||
? getRegionDisplayName(account.regionCode, account.accountType)
|
||||
: (account.name || displayInfo.label);
|
||||
|
||||
return (
|
||||
<Card className="hover:shadow-md transition-shadow">
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import { Skeleton } from '@/components/ui/skeleton';
|
|||
import { Button } from '@/components/ui/button';
|
||||
import { formatDecimal } from '@/lib/utils/format';
|
||||
import { getAccountDisplayInfo, type SystemAccount } from '@/types/system-account';
|
||||
import { getRegionDisplayName } from '@/lib/constants/region-codes';
|
||||
import { formatDistanceToNow } from 'date-fns';
|
||||
import { zhCN } from 'date-fns/locale';
|
||||
import { FileText } from 'lucide-react';
|
||||
|
|
@ -95,8 +96,13 @@ export function AccountsTable({
|
|||
const contribution = account.contributionBalance || account.totalContribution || '0';
|
||||
const totalMined = account.totalMined || '0';
|
||||
|
||||
// 使用前端区域代码映射获取显示名称
|
||||
const displayName = account.regionCode
|
||||
? getRegionDisplayName(account.regionCode, account.accountType)
|
||||
: (account.name || displayInfo.label);
|
||||
|
||||
return (
|
||||
<TableRow key={account.accountType}>
|
||||
<TableRow key={account.accountType + (account.regionCode || '')}>
|
||||
<TableCell>
|
||||
<div className="flex items-center gap-2">
|
||||
<span
|
||||
|
|
@ -104,11 +110,12 @@ export function AccountsTable({
|
|||
/>
|
||||
<code className="text-xs bg-muted px-1.5 py-0.5 rounded">
|
||||
{account.accountType}
|
||||
{account.regionCode && `_${account.regionCode}`}
|
||||
</code>
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
{account.name || displayInfo.label}
|
||||
{displayName}
|
||||
</TableCell>
|
||||
<TableCell className="text-right font-mono">
|
||||
{formatDecimal(contribution, 8)}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,283 @@
|
|||
/**
|
||||
* 中国行政区划代码映射
|
||||
* 用于将区域代码转换为中文省市名称
|
||||
*/
|
||||
|
||||
/**
|
||||
* 省份区域代码到名称的映射
|
||||
*/
|
||||
export const PROVINCE_CODE_NAMES: Record<string, string> = {
|
||||
// 2位代码格式
|
||||
'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': '澳门特别行政区',
|
||||
// 6位代码格式(带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 const CITY_CODE_NAMES: Record<string, string> = {
|
||||
// 北京市
|
||||
'110100': '北京市',
|
||||
// 天津市
|
||||
'120100': '天津市',
|
||||
// 河北省
|
||||
'130100': '石家庄市', '130200': '唐山市', '130300': '秦皇岛市', '130400': '邯郸市',
|
||||
'130500': '邢台市', '130600': '保定市', '130700': '张家口市', '130800': '承德市',
|
||||
'130900': '沧州市', '131000': '廊坊市', '131100': '衡水市',
|
||||
// 山西省
|
||||
'140100': '太原市', '140200': '大同市', '140300': '阳泉市', '140400': '长治市',
|
||||
'140500': '晋城市', '140600': '朔州市', '140700': '晋中市', '140800': '运城市',
|
||||
'140900': '忻州市', '141000': '临汾市', '141100': '吕梁市',
|
||||
// 内蒙古自治区
|
||||
'150100': '呼和浩特市', '150200': '包头市', '150300': '乌海市', '150400': '赤峰市',
|
||||
'150500': '通辽市', '150600': '鄂尔多斯市', '150700': '呼伦贝尔市', '150800': '巴彦淖尔市',
|
||||
'150900': '乌兰察布市',
|
||||
// 辽宁省
|
||||
'210100': '沈阳市', '210200': '大连市', '210300': '鞍山市', '210400': '抚顺市',
|
||||
'210500': '本溪市', '210600': '丹东市', '210700': '锦州市', '210800': '营口市',
|
||||
'210900': '阜新市', '211000': '辽阳市', '211100': '盘锦市', '211200': '铁岭市',
|
||||
'211300': '朝阳市', '211400': '葫芦岛市',
|
||||
// 吉林省
|
||||
'220100': '长春市', '220200': '吉林市', '220300': '四平市', '220400': '辽源市',
|
||||
'220500': '通化市', '220600': '白山市', '220700': '松原市', '220800': '白城市',
|
||||
// 黑龙江省
|
||||
'230100': '哈尔滨市', '230200': '齐齐哈尔市', '230300': '鸡西市', '230400': '鹤岗市',
|
||||
'230500': '双鸭山市', '230600': '大庆市', '230700': '伊春市', '230800': '佳木斯市',
|
||||
'230900': '七台河市', '231000': '牡丹江市', '231100': '黑河市', '231200': '绥化市',
|
||||
// 上海市
|
||||
'310100': '上海市',
|
||||
// 江苏省
|
||||
'320100': '南京市', '320200': '无锡市', '320300': '徐州市', '320400': '常州市',
|
||||
'320500': '苏州市', '320600': '南通市', '320700': '连云港市', '320800': '淮安市',
|
||||
'320900': '盐城市', '321000': '扬州市', '321100': '镇江市', '321200': '泰州市',
|
||||
'321300': '宿迁市',
|
||||
// 浙江省
|
||||
'330100': '杭州市', '330200': '宁波市', '330300': '温州市', '330400': '嘉兴市',
|
||||
'330500': '湖州市', '330600': '绍兴市', '330700': '金华市', '330800': '衢州市',
|
||||
'330900': '舟山市', '331000': '台州市', '331100': '丽水市',
|
||||
// 安徽省
|
||||
'340100': '合肥市', '340200': '芜湖市', '340300': '蚌埠市', '340400': '淮南市',
|
||||
'340500': '马鞍山市', '340600': '淮北市', '340700': '铜陵市', '340800': '安庆市',
|
||||
'341000': '黄山市', '341100': '滁州市', '341200': '阜阳市', '341300': '宿州市',
|
||||
'341500': '六安市', '341600': '亳州市', '341700': '池州市', '341800': '宣城市',
|
||||
// 福建省
|
||||
'350100': '福州市', '350200': '厦门市', '350300': '莆田市', '350400': '三明市',
|
||||
'350500': '泉州市', '350600': '漳州市', '350700': '南平市', '350800': '龙岩市',
|
||||
'350900': '宁德市',
|
||||
// 江西省
|
||||
'360100': '南昌市', '360200': '景德镇市', '360300': '萍乡市', '360400': '九江市',
|
||||
'360500': '新余市', '360600': '鹰潭市', '360700': '赣州市', '360800': '吉安市',
|
||||
'360900': '宜春市', '361000': '抚州市', '361100': '上饶市',
|
||||
// 山东省
|
||||
'370100': '济南市', '370200': '青岛市', '370300': '淄博市', '370400': '枣庄市',
|
||||
'370500': '东营市', '370600': '烟台市', '370700': '潍坊市', '370800': '济宁市',
|
||||
'370900': '泰安市', '371000': '威海市', '371100': '日照市', '371300': '临沂市',
|
||||
'371400': '德州市', '371500': '聊城市', '371600': '滨州市', '371700': '菏泽市',
|
||||
// 河南省
|
||||
'410100': '郑州市', '410200': '开封市', '410300': '洛阳市', '410400': '平顶山市',
|
||||
'410500': '安阳市', '410600': '鹤壁市', '410700': '新乡市', '410800': '焦作市',
|
||||
'410900': '濮阳市', '411000': '许昌市', '411100': '漯河市', '411200': '三门峡市',
|
||||
'411300': '南阳市', '411400': '商丘市', '411500': '信阳市', '411600': '周口市',
|
||||
'411700': '驻马店市',
|
||||
// 湖北省
|
||||
'420100': '武汉市', '420200': '黄石市', '420300': '十堰市', '420500': '宜昌市',
|
||||
'420600': '襄阳市', '420700': '鄂州市', '420800': '荆门市', '420900': '孝感市',
|
||||
'421000': '荆州市', '421100': '黄冈市', '421200': '咸宁市', '421300': '随州市',
|
||||
// 湖南省
|
||||
'430100': '长沙市', '430200': '株洲市', '430300': '湘潭市', '430400': '衡阳市',
|
||||
'430500': '邵阳市', '430600': '岳阳市', '430700': '常德市', '430800': '张家界市',
|
||||
'430900': '益阳市', '431000': '郴州市', '431100': '永州市', '431200': '怀化市',
|
||||
'431300': '娄底市',
|
||||
// 广东省
|
||||
'440100': '广州市', '440200': '韶关市', '440300': '深圳市', '440400': '珠海市',
|
||||
'440500': '汕头市', '440600': '佛山市', '440700': '江门市', '440800': '湛江市',
|
||||
'440900': '茂名市', '441200': '肇庆市', '441300': '惠州市', '441400': '梅州市',
|
||||
'441500': '汕尾市', '441600': '河源市', '441700': '阳江市', '441800': '清远市',
|
||||
'441900': '东莞市', '442000': '中山市', '445100': '潮州市', '445200': '揭阳市',
|
||||
'445300': '云浮市',
|
||||
// 广西壮族自治区
|
||||
'450100': '南宁市', '450200': '柳州市', '450300': '桂林市', '450400': '梧州市',
|
||||
'450500': '北海市', '450600': '防城港市', '450700': '钦州市', '450800': '贵港市',
|
||||
'450900': '玉林市', '451000': '百色市', '451100': '贺州市', '451200': '河池市',
|
||||
'451300': '来宾市', '451400': '崇左市',
|
||||
// 海南省
|
||||
'460100': '海口市', '460200': '三亚市', '460300': '三沙市', '460400': '儋州市',
|
||||
// 重庆市
|
||||
'500100': '重庆市',
|
||||
// 四川省
|
||||
'510100': '成都市', '510300': '自贡市', '510400': '攀枝花市', '510500': '泸州市',
|
||||
'510600': '德阳市', '510700': '绵阳市', '510800': '广元市', '510900': '遂宁市',
|
||||
'511000': '内江市', '511100': '乐山市', '511300': '南充市', '511400': '眉山市',
|
||||
'511500': '宜宾市', '511600': '广安市', '511700': '达州市', '511800': '雅安市',
|
||||
'511900': '巴中市', '512000': '资阳市',
|
||||
// 贵州省
|
||||
'520100': '贵阳市', '520200': '六盘水市', '520300': '遵义市', '520400': '安顺市',
|
||||
'520500': '毕节市', '520600': '铜仁市',
|
||||
// 云南省
|
||||
'530100': '昆明市', '530300': '曲靖市', '530400': '玉溪市', '530500': '保山市',
|
||||
'530600': '昭通市', '530700': '丽江市', '530800': '普洱市', '530900': '临沧市',
|
||||
// 西藏自治区
|
||||
'540100': '拉萨市', '540200': '日喀则市', '540300': '昌都市', '540400': '林芝市',
|
||||
'540500': '山南市', '540600': '那曲市',
|
||||
// 陕西省
|
||||
'610100': '西安市', '610200': '铜川市', '610300': '宝鸡市', '610400': '咸阳市',
|
||||
'610500': '渭南市', '610600': '延安市', '610700': '汉中市', '610800': '榆林市',
|
||||
'610900': '安康市', '611000': '商洛市',
|
||||
// 甘肃省
|
||||
'620100': '兰州市', '620200': '嘉峪关市', '620300': '金昌市', '620400': '白银市',
|
||||
'620500': '天水市', '620600': '武威市', '620700': '张掖市', '620800': '平凉市',
|
||||
'620900': '酒泉市', '621000': '庆阳市', '621100': '定西市', '621200': '陇南市',
|
||||
// 青海省
|
||||
'630100': '西宁市', '630200': '海东市',
|
||||
// 宁夏回族自治区
|
||||
'640100': '银川市', '640200': '石嘴山市', '640300': '吴忠市', '640400': '固原市',
|
||||
'640500': '中卫市',
|
||||
// 新疆维吾尔自治区
|
||||
'650100': '乌鲁木齐市', '650200': '克拉玛依市', '650400': '吐鲁番市', '650500': '哈密市',
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据区域代码获取省份名称
|
||||
*/
|
||||
export function getProvinceName(regionCode: string): string | null {
|
||||
// 直接查找
|
||||
if (PROVINCE_CODE_NAMES[regionCode]) {
|
||||
return PROVINCE_CODE_NAMES[regionCode];
|
||||
}
|
||||
// 尝试用前2位查找
|
||||
if (regionCode.length >= 2) {
|
||||
const prefix = regionCode.substring(0, 2);
|
||||
return PROVINCE_CODE_NAMES[prefix] || null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据区域代码获取城市名称
|
||||
*/
|
||||
export function getCityName(regionCode: string): string | null {
|
||||
return CITY_CODE_NAMES[regionCode] || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据区域代码获取显示名称
|
||||
* @param regionCode 区域代码(6位)
|
||||
* @param accountType 账户类型(PROVINCE 或 CITY)
|
||||
* @returns 格式化后的显示名称,如 "广州市公司" 或 "广东省公司"
|
||||
*/
|
||||
export function getRegionDisplayName(
|
||||
regionCode: string | null | undefined,
|
||||
accountType?: string
|
||||
): string {
|
||||
if (!regionCode) {
|
||||
return accountType === 'PROVINCE' ? '省公司账户' :
|
||||
accountType === 'CITY' ? '市公司账户' : '系统账户';
|
||||
}
|
||||
|
||||
// 尝试获取城市名称
|
||||
const cityName = getCityName(regionCode);
|
||||
if (cityName) {
|
||||
// 去掉"市"后缀再加"市公司"
|
||||
const shortName = cityName.replace(/市$/, '');
|
||||
return `${shortName}市公司`;
|
||||
}
|
||||
|
||||
// 尝试获取省份名称
|
||||
const provinceName = getProvinceName(regionCode);
|
||||
if (provinceName) {
|
||||
// 简化省份名称
|
||||
const shortName = provinceName
|
||||
.replace(/省$/, '')
|
||||
.replace(/市$/, '')
|
||||
.replace(/自治区$/, '')
|
||||
.replace(/特别行政区$/, '')
|
||||
.replace(/壮族/, '')
|
||||
.replace(/回族/, '')
|
||||
.replace(/维吾尔/, '');
|
||||
return `${shortName}省公司`;
|
||||
}
|
||||
|
||||
// 无法识别时返回原始代码
|
||||
return `${regionCode}账户`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是省级代码(后4位为0000)
|
||||
*/
|
||||
export function isProvinceCode(regionCode: string): boolean {
|
||||
return regionCode.length === 6 && regionCode.endsWith('0000');
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是市级代码(后2位为00,但不是省级)
|
||||
*/
|
||||
export function isCityCode(regionCode: string): boolean {
|
||||
return regionCode.length === 6 && regionCode.endsWith('00') && !regionCode.endsWith('0000');
|
||||
}
|
||||
Loading…
Reference in New Issue