123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- /**
- * 金额转换
- * @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
- })
- }
|