重构
This commit is contained in:
78
packages/shared/src/phone-countries.js
Normal file
78
packages/shared/src/phone-countries.js
Normal file
@@ -0,0 +1,78 @@
|
||||
import { normalizeLocale } from './api-errors';
|
||||
import dialCodesJson from './phone-dial-codes.json';
|
||||
/** 平台开放注册/短信的国家(ISO 3166-1 alpha-2),顺序即下拉展示顺序 */
|
||||
export const ALLOWED_PHONE_ISO = ['MY', 'SG', 'IN', 'AU', 'TH', 'VN', 'BD', 'TW'];
|
||||
const ALLOWED_SET = new Set(ALLOWED_PHONE_ISO);
|
||||
const ZH_LABELS = {
|
||||
MY: '马来西亚',
|
||||
SG: '新加坡',
|
||||
IN: '印度',
|
||||
AU: '澳洲',
|
||||
TH: '泰国',
|
||||
VN: '越南',
|
||||
BD: '孟加拉国',
|
||||
TW: '台湾',
|
||||
};
|
||||
const allCountries = dialCodesJson;
|
||||
/** 开放国家列表(从 ITU 全量数据中筛选) */
|
||||
export const PHONE_COUNTRIES = ALLOWED_PHONE_ISO.map((iso) => {
|
||||
const found = allCountries.find((c) => c.iso === iso);
|
||||
if (!found) {
|
||||
throw new Error(`Missing phone country data for ISO: ${iso}`);
|
||||
}
|
||||
return found;
|
||||
});
|
||||
const DIAL_SET = new Set(PHONE_COUNTRIES.map((c) => c.dial));
|
||||
export function isSupportedPhoneDial(dial) {
|
||||
return DIAL_SET.has(dial.replace(/\D/g, ''));
|
||||
}
|
||||
export function isAllowedPhoneIso(iso) {
|
||||
return ALLOWED_SET.has(iso.toUpperCase());
|
||||
}
|
||||
export function defaultPhoneDialForLocale(localeInput) {
|
||||
return findPhoneCountryByIso(defaultPhoneIsoForLocale(localeInput))?.dial ?? '60';
|
||||
}
|
||||
export function defaultPhoneIsoForLocale(localeInput) {
|
||||
const locale = normalizeLocale(localeInput);
|
||||
if (locale === 'zh-CN')
|
||||
return 'TW';
|
||||
if (locale === 'ms-MY')
|
||||
return 'MY';
|
||||
return 'SG';
|
||||
}
|
||||
export function getPhoneDialFromIso(iso) {
|
||||
return findPhoneCountryByIso(iso)?.dial ?? '';
|
||||
}
|
||||
export function getPhoneCountryLabel(country, localeInput) {
|
||||
const locale = normalizeLocale(localeInput);
|
||||
if (locale === 'zh-CN' && isAllowedPhoneIso(country.iso)) {
|
||||
return ZH_LABELS[country.iso];
|
||||
}
|
||||
if (locale === 'zh-CN') {
|
||||
return country.nameLocal || country.nameEn;
|
||||
}
|
||||
return country.nameEn;
|
||||
}
|
||||
export function findPhoneCountryByDial(dial) {
|
||||
const normalized = dial.replace(/\D/g, '');
|
||||
return PHONE_COUNTRIES.find((c) => c.dial === normalized);
|
||||
}
|
||||
export function findPhoneCountryByIso(iso) {
|
||||
const upper = iso.toUpperCase();
|
||||
if (!isAllowedPhoneIso(upper))
|
||||
return undefined;
|
||||
return PHONE_COUNTRIES.find((c) => c.iso === upper);
|
||||
}
|
||||
export function searchPhoneCountries(query, localeInput) {
|
||||
const q = query.trim().toLowerCase();
|
||||
if (!q)
|
||||
return PHONE_COUNTRIES;
|
||||
return PHONE_COUNTRIES.filter((country) => {
|
||||
const label = getPhoneCountryLabel(country, localeInput).toLowerCase();
|
||||
return (country.iso.toLowerCase().includes(q)
|
||||
|| country.dial.includes(q.replace(/^\+/, ''))
|
||||
|| country.nameEn.toLowerCase().includes(q)
|
||||
|| label.includes(q)
|
||||
|| `+${country.dial}`.includes(q));
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user