/** * 金额转换 * @param money 金额 * @param config * @param config.type 类型 full | number | unit * @param config.level 初始单位索引 * @param config.levelArr 单位数组 ['元', '万', '亿', '万亿'] * @param config.unit 计算单位 10000 * @param config.digit 精度,保留小数位数 2 * @param config.degrade 指定单位索引时,所需精度不够是否降级单位 false * @returns {*|string|string|number} */ function recursiveCalculationMoney(money, config = {}, start = false) { const { type, level, levelArr, unit, digit, degrade } = Object.assign( { type: 'full', level: 0, levelArr: ['元', '万元', '亿元', '万亿元'], digit: 2, degrade: false, unit: 10000 }, config ) // 提取纯数字 let computMoney = String(money).match(/^\d+(\.\d+)?/g) || [0] computMoney = Number(computMoney[0]) // 是否指定单位索引 const lockUnit = start && level > 0 // 判断是否需要递归单位 if (!lockUnit) { const canNext = computMoney / Math.pow(unit, level + 1) >= 1 && level + 1 < levelArr.length if (canNext) { return recursiveCalculationMoney(computMoney, { type, level: level + 1, levelArr, digit, degrade, unit }) } } // 浮点数精度 const digitNumber = Math.pow(10, digit) // 指定单位索引时,如不满足精度要求,是否需要降级单位处理 let computLevel = level const needDegrade = degrade && computMoney * digitNumber < Math.pow(unit, level) if (lockUnit && needDegrade) { computLevel-- } // 计算金额 const addPowMoney = Math.floor( Number( ((computMoney / Math.pow(unit, computLevel)) * digitNumber).toPrecision( 12 ) ) ) const resetPowMoney = Number((addPowMoney / digitNumber).toPrecision(12)) computMoney = resetPowMoney // 返回结果 switch (type) { case 'full': { if (computMoney === 0) { return '' } else { return computMoney + levelArr[computLevel] } } case 'unit': { return levelArr[computLevel] } case 'number': { return computMoney } } } /** * 金额转换 * @param money 金额 * @param config * @param config.type 类型 full | number | unit * @param config.level 初始单位索引 * @param config.levelArr 单位数组 ['元', '万元', '亿元', '万亿元'] * @param config.unit 计算单位 10000 * @param config.digit 精度,保留小数位数 2 * @param config.degrade 指定单位索引时,所需精度不够是否降级单位 false * @returns {*|string|string|number} */ export function formatMoney(money, config = {}) { if (config.level === 1 && !config.degrade) { // 万元单位, 并且不单位降级, 则小于100元的金额会被舍弃, 造成显示空白 // 此处逻辑: 单位固定万元,不降级. 金额<10000, 展示元为单位 if (money && money > 0 && money < 10000) { return `${money}元` } else { return recursiveCalculationMoney(money, config, true) } } else { return recursiveCalculationMoney(money, config, true) } } /** * 金额浮点问题修复 * @param number * @returns {number} */ export function formatNumber(number) { return Number(number.toFixed(12)) } // 元转分 export function yuan2Fen(v) { return formatNumber((v * 10000) / 100) } // 金额3位逗号分隔 ------------> /** * @param s 要格式化的数字(四舍五入) * @param n 保留几位小数(不传或者传-1 --> 如果为整数,则不保留小数。如果为浮点数,则保留两位小数) * @param comma 是否小数点前每3位添加逗号 */ export function splitMoney(s = 0, n = -1, comma = false) { n = n === -1 ? 0 : n if (n > 20 || n < -1) { n = 2 } s = Number(s) return s.toLocaleString('zh-CN', { style: 'decimal', useGrouping: comma, minimumFractionDigits: n, maximumFractionDigits: n }) }