import dayjs from 'dayjs'; import customParseFormat from 'dayjs/plugin/customParseFormat'; dayjs.extend(customParseFormat); // 注册插件 import { BigNumber } from "bignumber.js"; /** * 过滤输入,只允许数字和最多两位小数 * @param {string} value - 输入框当前值 * @param {boolean} isIntegerOnly - 是否只允许正整数(无小数点),开启时最小值为1,或为传入的值 * @returns {string} 过滤后的合法值 */ export function filterNumberInput(value, isIntegerOnly = false) { // 第一步就过滤所有非数字和非小数点的字符(包括字母) let filtered = value.replace(/[^\d.]/g, ""); // 整数模式处理 if (isIntegerOnly !== false) { // 移除所有小数点 filtered = filtered.replace(/\./g, ""); // 处理前导零 filtered = filtered.replace(/^0+(\d)/, "$1") || filtered; // 空值处理(允许临时删除) if (filtered === "") { return ""; } // 最小值限制 if (filtered === isIntegerOnly || parseInt(filtered, 10) < isIntegerOnly) { return isIntegerOnly; } return filtered; } // 小数模式处理 const parts = filtered.split("."); if (parts.length > 1) { filtered = parts[0] + "." + (parts[1].substring(0, 2) || ""); } // 处理前导零 if (filtered.startsWith("0") && filtered.length > 1 && !filtered.startsWith("0.")) { filtered = filtered.replace(/^0+(\d)/, "$1"); } return filtered; } /** * 时间格式互转:HH:mm → HH:mm:ss;HH:mm:ss → HH:mm * @param {string} timeStr - 输入的时间字符串 * @returns {string} 转换后的时间字符串 */ export const convertTimeFormat = (timeStr) => { if (!timeStr) return '00:00'; // 正则判断格式 const isHms = /^\d{1,2}:\d{2}:\d{2}$/.test(timeStr); // HH:mm:ss const isHm = /^\d{1,2}:\d{2}$/.test(timeStr); // HH:mm if (isHm) { // HH:mm → 解析后格式化为 HH:mm:ss return dayjs(timeStr, 'HH:mm').format('HH:mm:ss'); } if (isHms) { // HH:mm:ss → 解析后格式化为 HH:mm return dayjs(timeStr, 'HH:mm:ss').format('HH:mm'); } // 非法格式兜底 return '00:00'; }; /** * 判断目标值是否包含指定字符串 * @param {string|number|array} target - 目标值(字符串/数字/数组) * @param {string} searchStr - 要查找的子字符串 * @param {object} [options] - 可选配置 * @param {boolean} [options.ignoreCase=false] - 是否忽略大小写 * @param {boolean} [options.allowEmpty=false] - 当 searchStr 为空时,是否返回 true(默认 false) * @returns {boolean} 是否包含指定字符串 */ export function includesString(target, searchStr, options = {}) { // 解构配置,设置默认值 const { ignoreCase = false, allowEmpty = false } = options; // 1. 处理 searchStr 为空的情况 if (searchStr === '' || searchStr === null || searchStr === undefined) { return allowEmpty; } // 2. 统一将目标值转为字符串(兼容数字/数组等) let targetStr = ''; if (typeof target === 'string') { targetStr = target; } else if (typeof target === 'number') { targetStr = String(target); } else if (Array.isArray(target)) { // 数组:拼接为字符串(也可改为 "数组中某一项包含",根据需求调整) targetStr = target.join(','); } else { // 其他类型(对象/布尔等):转为字符串或返回 false targetStr = String(target); } // 3. 处理大小写忽略 const processedTarget = ignoreCase ? targetStr.toLowerCase() : targetStr; const processedSearch = ignoreCase ? searchStr.toLowerCase() : searchStr; // 4. 执行包含判断 return processedTarget.includes(processedSearch); } /** * 乘法计算并格式化结果 * @param {string|number} num1 - 第一个乘数 * @param {string|number} num2 - 第二个乘数 * @returns {string} 保留两位小数的结果(不四舍五入,补零) */ export const multiplyAndFormat = (num1, num2) => { try { // 转换为BigNumber(使用字符串构造避免精度问题) const bigNum1 = new BigNumber(num1.toString()); const bigNum2 = new BigNumber(num2.toString()); // 1. 乘法计算 const product = bigNum1.multipliedBy(bigNum2); // 2. 截断到两位小数(不四舍五入) const truncated = product.decimalPlaces(2, BigNumber.ROUND_DOWN); // 3. 格式化保留两位小数(补零) return truncated.toFixed(2); } catch (error) { console.error('计算错误:', error); return '0.00'; // 出错时返回默认值 } };