hn-hlw-service/utils/validator.js
2026-07-27 11:28:33 +08:00

182 lines
4.5 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

function isMobile(val) {
// 正则表达式验证手机号
const reg = /^1[3-9]\d{9}$/;
return reg.test(val);
}
function verifyString(str, label, min = 0, max = 100) {
if (typeof str === 'number') {
str = str.toString()
}
if (str === undefined || str === null) {
str = ''
}
if (typeof str === 'string' && str.trim().length >= min && str.trim().length < max) {
return [true, str.trim()];
}
if (typeof str !== 'string' && min === 0) {
return [true, ''];
}
if (typeof str !== 'string') {
return [false, `${label}格式不正确`];
}
if (str.trim().length === 0 && min > 0) {
return [false, `${label}不能为空`];
}
if (min > 0 && str.trim().length < min) {
return [false, `${label}不能少于${min}个字符`];
}
return [false, `${label}不能超过${max}个字符`]
}
function verifyNumber(value, label, len = 0, min, max, minEq = false, maxEq = false) {
// 1. 检查 value 是否为字符串或数字类型
if (typeof value !== 'string' && typeof value !== 'number') {
return [false, `${label}无效`];
}
// 2. 如果是字符串类型,尝试转为数字
if (typeof value === 'string') {
// 去除前后空格
value = value.trim();
// 空字符串或非数字字符串直接返回 false
if (value === '' || isNaN(value)) {
return [false, `${label}无效`];
}
value = Number(value);
}
// 3. 检查是否为有效数字(排除 NaN 和 Infinity
if (typeof value !== 'number' || !isFinite(value)) {
return [false, `${label}无效`];
}
// 4. 检查小数位数是否 <= len
const decimalPart = String(value).split('.')[1];
if (decimalPart && decimalPart.length > len) {
return len === 0 ? [false, `${label}只能输入整数`] : [false, `${label}最多输入${len}位小数`];
}
if (typeof min === 'number' && minEq && value < min) {
return [false, `${label}不能小于${min}`];
}
if (typeof min === 'number' && !minEq && value <= min) {
return [false, `${label}应该大于${min}`];
}
if (typeof max === 'number' && maxEq && value > max) {
return [false, `${label}不能大于${max}`];
}
if (typeof max === 'number' && !maxEq && value >= max) {
return [false, `${label}应该小于${max}`];
}
return [true, value];
}
function verifyListItem(val, list, required, label, defaultValue = '') {
const isEmpty =
val === undefined ||
val === null ||
(typeof val === 'string' && val.trim() === '');
if (isEmpty && !required) {
return [true, defaultValue]
}
if (list.includes(val)) {
return [true, val]
}
return [false, `${label}无效`]
}
const idTransfer = (sId) => {
if (sId.length === 15) {
const arrInt = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2],
arrCh = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"];
let nTemp = 0;
sId = sId.substr(0, 6) + "19" + sId.substr(6, sId.length - 6);
for (let i = 0; i < 17; i++) {
nTemp += Number(sId.substr(i, 1)) * arrInt[i];
}
sId += arrCh[nTemp % 11];
}
return sId;
};
function isChinaId(s) {
const sId = idTransfer(s),
aCity = {
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: "澳门",
91: "国外 ",
};
if (!/^\d{17}(\d|x)$/i.test(sId)) {
return false;
}
if (!aCity[parseInt(sId.substr(0, 2), 10)]) {
return false
}
if (sId.length == 18) {
//∑(ai×Wi)(mod 11)
//加权因子
const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
//校验位
const parity = [1, 0, "X", 9, 8, 7, 6, 5, 4, 3, 2];
let sum = 0;
let ai = 0;
let wi = 0;
for (let i = 0; i < 17; i++) {
ai = Number(sId[i]);
wi = factor[i];
sum += ai * wi;
}
const last = parity[sum % 11];
if (last != sId[17].toUpperCase()) {
return false;
}
}
return true
}
module.exports = {
verifyString,
verifyNumber,
verifyListItem,
isMobile,
isChinaId
}