|
|
@@ -290,13 +290,111 @@ function desensitizeContent(content, type = 1) {
|
|
|
|
|
|
// 2 - 手机号脱敏
|
|
|
case 2: {
|
|
|
- // 手机号基本校验:11位数字,以1开头
|
|
|
- const phoneReg = /^1\d{10}$/;
|
|
|
- if (!phoneReg.test(trimContent) || trimContent.length !== 11) {
|
|
|
- return content; // 不符合手机号格式返回原内容
|
|
|
- }
|
|
|
- // 保留前3位和后4位,中间4位用*代替
|
|
|
- return trimContent.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
|
|
|
+ // 定义不同区号的手机号脱敏规则映射表
|
|
|
+ const phoneDesensitizeRules = {
|
|
|
+ // 中国及港澳台
|
|
|
+ '+86': [3, 4, '+86', 11], // 中国大陆:11位,前3后4(138****8000)
|
|
|
+ '+852': [2, 4, '+852', 8], // 中国香港:8位,前2后4(12****78)
|
|
|
+ '+853': [2, 4, '+853', 8], // 中国澳门:8位,前2后4(12****78)
|
|
|
+ '+886': [3, 4, '+886', 10], // 中国台湾:10位,前3后4(098****7890)
|
|
|
+
|
|
|
+ // 亚洲
|
|
|
+ '+81': [3, 4, '+81', 11], // 日本:11位,前3后4(090****1234)
|
|
|
+ '+82': [3, 4, '+82', 11], // 韩国:11位,前3后4(010****1234)
|
|
|
+ '+65': [2, 4, '+65', 8], // 新加坡:8位,前2后4(61****78)
|
|
|
+ '+60': [3, 4, '+60', 10], // 马来西亚:10位,前3后4(012****7890)
|
|
|
+ '+91': [3, 4, '+91', 10], // 印度:10位,前3后4(987****6543)
|
|
|
+ '+66': [3, 4, '+66', 10], // 泰国:10位,前3后4(081****1234)
|
|
|
+ '+84': [3, 4, '+84', 10], // 越南:10位,前3后4(091****1234)
|
|
|
+ '+92': [3, 4, '+92', 11], // 巴基斯坦:11位,前3后4(0300****1234)
|
|
|
+ '+94': [3, 4, '+94', 10], // 斯里兰卡:10位,前3后4(771****1234)
|
|
|
+ '+880': [3, 4, '+880', 11], // 孟加拉国:11位,前3后4(0171****1234)
|
|
|
+ '+62': [3, 4, '+62', 12], // 印度尼西亚:12位,前3后4(0812****1234)
|
|
|
+ '+966': [3, 4, '+966', 9], // 沙特阿拉伯:9位,前3后4(500****123)
|
|
|
+ '+971': [2, 4, '+971', 9], // 阿联酋:9位,前2后4(50****1234)
|
|
|
+ '+965': [2, 4, '+965', 8], // 科威特:8位,前2后4(50****123)
|
|
|
+ '+974': [2, 4, '+974', 8], // 卡塔尔:8位,前2后4(50****123)
|
|
|
+ '+95': [2, 4, '+95', 9], // 缅甸:9位,前2后4(90****1234)
|
|
|
+ '+855': [3, 4, '+855', 9], // 柬埔寨:9位,前3后4(012****123)
|
|
|
+
|
|
|
+ // 北美洲
|
|
|
+ '+1': [3, 4, '+1', 10], // 美国/加拿大:10位,前3后4(123****7890)
|
|
|
+ '+52': [3, 4, '+52', 10], // 墨西哥:10位,前3后4(123****7890)
|
|
|
+
|
|
|
+ // 欧洲
|
|
|
+ '+44': [3, 4, '+44', 11], // 英国:11位,前3后4(791****1234)
|
|
|
+ '+33': [3, 4, '+33', 10], // 法国:10位,前3后4(601****1234)
|
|
|
+ '+49': [3, 4, '+49', 11], // 德国:11位,前3后4(151****12345)
|
|
|
+ '+34': [2, 4, '+34', 9], // 西班牙:9位,前2后4(60****1234)
|
|
|
+ '+39': [3, 4, '+39', 10], // 意大利:10位,前3后4(333****1234)
|
|
|
+ '+32': [2, 4, '+32', 9], // 比利时:9位,前2后4(47****1234)
|
|
|
+ '+31': [2, 4, '+31', 9], // 荷兰:9位,前2后4(61****1234)
|
|
|
+ '+46': [3, 4, '+46', 10], // 瑞典:10位,前3后4(701****1234)
|
|
|
+ '+41': [2, 4, '+41', 9], // 瑞士:9位,前2后4(79****1234)
|
|
|
+ '+358': [2, 4, '+358', 9], // 芬兰:9位,前2后4(40****1234)
|
|
|
+ '+45': [2, 4, '+45', 8], // 丹麦:8位,前2后4(12****78)
|
|
|
+ '+30': [3, 4, '+30', 10], // 希腊:10位,前3后4(690****1234)
|
|
|
+ '+36': [2, 4, '+36', 9], // 匈牙利:9位,前2后4(30****1234)
|
|
|
+ '+359': [2, 4, '+359', 9], // 保加利亚:9位,前2后4(88****1234)
|
|
|
+ '+380': [3, 4, '+380', 10], // 乌克兰:10位,前3后4(067****1234)
|
|
|
+ '+7': [3, 4, '+7', 11], // 俄罗斯/哈萨克斯坦:11位,前3后4(916****12345)
|
|
|
+ '+381': [3, 4, '+381', 10], // 塞尔维亚:10位,前3后4(630****1234)
|
|
|
+
|
|
|
+ // 大洋洲
|
|
|
+ '+61': [3, 4, '+61', 9], // 澳大利亚:9位,前3后4(400****123)
|
|
|
+ '+64': [3, 4, '+64', 9], // 新西兰:9位,前3后4(210****123)
|
|
|
+
|
|
|
+ // 非洲
|
|
|
+ '+27': [3, 4, '+27', 10], // 南非:10位,前3后4(082****1234)
|
|
|
+ '+234': [3, 4, '+234', 11], // 尼日利亚:11位,前3后4(080****12345)
|
|
|
+ '+254': [2, 4, '+254', 9], // 肯尼亚:9位,前2后4(70****1234)
|
|
|
+ '+20': [3, 4, '+20', 10], // 埃及:10位,前3后4(010****1234)
|
|
|
+
|
|
|
+ // 南美洲
|
|
|
+ '+55': [3, 4, '+55', 11], // 巴西:11位,前3后4(119****12345)
|
|
|
+ '+54': [3, 4, '+54', 10], // 阿根廷:10位,前3后4(112****1234)
|
|
|
+ '+57': [3, 4, '+57', 10], // 哥伦比亚:10位,前3后4(300****1234)
|
|
|
+ };
|
|
|
+
|
|
|
+ // 步骤1:解析手机号(区分带区号/不带区号)
|
|
|
+ let areaCode = '+86'; // 默认中国大陆区号
|
|
|
+ let purePhone = trimContent;
|
|
|
+
|
|
|
+ // 匹配是否包含国际区号(+开头,1-3位数字)
|
|
|
+ const areaCodeMatch = trimContent.match(/^(\+\d{1,3})(\d+)$/);
|
|
|
+ if (areaCodeMatch) {
|
|
|
+ areaCode = areaCodeMatch[1]; // 提取区号(如+86)
|
|
|
+ purePhone = areaCodeMatch[2]; // 提取纯手机号(不含区号)
|
|
|
+ } else {
|
|
|
+ // 无区号时,默认按+86处理,且要求是11位数字
|
|
|
+ if (!/^\d{11}$/.test(trimContent)) {
|
|
|
+ return content; // 无区号且不是11位数字,返回原内容
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 步骤2:获取当前区号的脱敏规则,无规则则用默认逻辑
|
|
|
+ const rule = phoneDesensitizeRules[areaCode] || [3, 4, areaCode, purePhone.length];
|
|
|
+ const [keepPrefix, keepSuffix, code, phoneLen] = rule;
|
|
|
+
|
|
|
+ // 步骤3:校验手机号格式(位数匹配)
|
|
|
+ if (purePhone.length !== phoneLen) {
|
|
|
+ return content; // 位数不匹配,返回原内容
|
|
|
+ }
|
|
|
+
|
|
|
+ // 步骤4:执行脱敏逻辑
|
|
|
+ // 计算需要隐藏的位数
|
|
|
+ const hideLength = purePhone.length - keepPrefix - keepSuffix;
|
|
|
+ if (hideLength <= 0) {
|
|
|
+ return content; // 无隐藏位数,返回原内容
|
|
|
+ }
|
|
|
+ // 拼接脱敏后的手机号
|
|
|
+ const prefix = purePhone.substring(0, keepPrefix);
|
|
|
+ const suffix = purePhone.substring(purePhone.length - keepSuffix);
|
|
|
+ const hidden = '*'.repeat(hideLength);
|
|
|
+ const desensitizedPhone = `${prefix}${hidden}${suffix}`;
|
|
|
+
|
|
|
+ // 步骤5:返回带区号的脱敏结果(如果有区号)
|
|
|
+ return areaCodeMatch ? `${code}${desensitizedPhone}` : desensitizedPhone;
|
|
|
}
|
|
|
|
|
|
// 3 - 姓名脱敏
|