Files
cashier_app/utils/index.js
2025-12-25 15:38:00 +08:00

146 lines
4.4 KiB
JavaScript
Raw 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.
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:ssHH: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'; // 出错时返回默认值
}
};