79 lines
2.7 KiB
JavaScript
79 lines
2.7 KiB
JavaScript
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));
|
||
});
|
||
}
|