UNPKG

ph-utils

Version:

js 开发工具集,前后端都可以使用(commonjs和es module)

240 lines (239 loc) 7.92 kB
/** * node 和 web 通用的工具类 */ /** 包含字母+数字的随机数字符 */ const RANDOM_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; /** 只包含字母的随机数字符 */ const NUMBER_RANDOM_CHARTS = "0123456789"; /** * 验证参数是否为空 * @param str 待验证的参数 * @param ignoreWhitespace 如果是字符串是否忽略空格(包括空白字符串以及[\r\t\n]之类的制表符),默认为true */ export function isBlank(str, ignoreWhitespace = true) { if (str == null) { return true; } return ((ignoreWhitespace && typeof str === "string" ? str.trim().length : str.length) === 0); } /** * 屏蔽手机号,中间部分用 * 展示 * @param mobile 待屏蔽的手机号 * @returns 屏蔽后的手机号,例如:123 **** 1234 */ export function shieldMobile(mobile) { const x1 = Math.floor(mobile.length / 2); const x2 = Math.ceil(x1 / 2); const shields = [" "]; for (let i = 0; i < x1 - 1; i++) { shields.push("*"); } shields.push(" "); return (mobile.substring(0, x2) + shields.join("") + mobile.substring(x2 + x1 - 1)); } /** * 验证参数是否是数字 * @param str 待验证的字符串 * @param numericParam 通过参数标记是否包含小数、正数 * @param numericParam.isPositive 是否是正数, 默认: false * @param numericParam.isFloat 是否是小数, 默认: true * @returns true 是数字, false 不是数字 */ export function isNumeric(str, numericParam) { numericParam = { isPositive: false, isFloat: true, ...numericParam }; const symbol = numericParam.isPositive ? "[+]?" : "[+-]?"; const main = numericParam.isFloat ? "([0-9]*[.])?[0-9]+" : "[0-9]+"; return new RegExp("^" + symbol + main + "$").test(str); } /** * 验证参数是否是Boolean 类型 * @param str 待验证的字符串 * @returns */ export function isBoolean(str) { return ["true", "false"].indexOf(str) >= 0; } export function random(opts) { if (typeof opts === "object" && opts.min != null && opts.max != null) { const randomNum = Math.random(); /* 生成两个数字之间的随机数(number) */ const end = opts.hasEnd ? 1 : 0; const resRandom = randomNum * (opts.max - opts.min + end) + opts.min; return opts.isInteger !== false ? Math.floor(resRandom) : resRandom; } else { if (typeof opts === "object" && opts.length == null) { throw new Error("random_length_cannot_null"); } let len = typeof opts === "object" ? opts.length : opts; /* 生成指定长度的随机数 */ let chars = RANDOM_CHARS; if (typeof opts === "object" && opts.hasLetter === false) { chars = NUMBER_RANDOM_CHARTS; } const resRandom = Array.from({ length: len }, () => chars.charAt(random({ min: 0, max: chars.length - 1, hasEnd: true }))).join(""); if (typeof opts === "object" && opts.firstIsZero === false && resRandom.indexOf("0") === 0) { return random(opts); } else { return resRandom; } } } /** * 带有错误名称标记的错误类型 */ export class BaseError extends Error { constructor() { if (arguments.length === 1) { super(arguments[0]); this.name = "BaseError"; } else { super(arguments[1]); this.name = arguments[0]; } } } /** * 将金额数字格式化为金额格式显示并且会保留两位小数[去除多余的位数,不是四舍五入,而是直接舍去] 1234523432.23 => 123,123,123.23 * @param {number} number 待转换的金额数字 * @return string */ export function formatMoney(number) { if (typeof Intl.NumberFormat !== "undefined") { const formatter = new Intl.NumberFormat("zh-CN", { style: "decimal", maximumFractionDigits: 2, }); return formatter.format(number); } else { number = number || 0; const negative = ""; const base = String(parseInt(number, 10)); // 获取数字整数部分 const mod = base.length > 3 ? base.length % 3 : 0; /* * 利用 正则前瞻 (?=) 将3位数字后面还紧跟一位数字的三位数字替换为 数字, 的形式 */ const numberStr = String(number); const usePrecision = numberStr.indexOf("."); let dotStr = usePrecision > 0 ? numberStr.slice(usePrecision + 1) : "00"; dotStr = dotStr.length > 2 ? dotStr.slice(0, 2) : dotStr; return (negative + (mod ? base.slice(0, mod) + "," : "") + base.slice(mod).replace(/(\d{3})(?=\d)/g, "$1,") + "." + dotStr); } } /** * 将风格由大写风格转换为下划线风格: HelloWorld -> hello-world * @param name 命名, 例如: HelloWorld * @param connector 连接符, 默认为: _ */ export function snakeCaseStyle(name, connector = "-") { return name.replace(/([A-Z])/g, (match, p1, offset) => (offset > 0 ? connector : "") + match.toLowerCase()); } /** * 对数字进行四舍五入处理 * @param num 需要进行四舍五入的数字 * @param precision 精度,默认为2,即保留小数点后两位 * @param roundType 舍入类型,默认为0,提供三种取值: * 0: 标准四舍五入 * 1: 向上取整 * 2: 向下取整 * @returns 返回经过指定方式舍入后的数字 */ export function round(num, precision = 2, roundType = 0) { // 计算精度因子,用于后续四舍五入计算 const factor = Math.pow(10, precision); switch (roundType) { case 0: // 标准四舍五入 return Math.round(num * factor) / factor; case 1: // 向上取整 return Math.ceil(num * factor) / factor; case 2: // 向下取整 return Math.floor(num * factor) / factor; default: // 如果传入的roundType不是预期的值,则直接返回原始数字 return num; } } /** * 反转字符串 */ export function reverseStr(str) { return str.split("").reverse().join(""); } function getObjKeyValue(data, key) { if (data == null) return null; return data[key]; } /** * 嵌套的 json 指定 key 数据 * @param data JSON格式数据 * @param keys 待获取的数据 key, 可以通过 [.] 获取嵌套数据, 例如: a.b.c * @returns */ export function getJSONValue(data, keystr) { if (data == null) return null; const keys = keystr.split("."); let res = data; for (const key of keys) { res = getObjKeyValue(res, key); if (res == null) break; } return res; } /** * 数据格式化主要用于数据类型转换 * @param data 待转换数据类型的数据 * @param config 转换配置 * @returns */ export function formatData(data, config) { const cfg = { numberFields: [], stringFields: [], formatter: {}, ...config, }; const res = {}; for (const key in data) { let value = getJSONValue(data, key); let formater; if (key in cfg.formatter) { formater = cfg.formatter[key]; } if (cfg.numberFields.includes(key)) { formater = "number"; } if (cfg.stringFields.includes(key)) { formater = "string"; } if (formater != null) { if (typeof formater == "function") { value = formater(value); } else if (formater == "number") { value = Number(value); } else if (formater == "string") { value = String(value); } } res[key] = value; } return res; }