金额大写

使用

对数字进行中文大写转化

// utils.js 文件中
export const number2Chinese = (number, type, prefix) => {})

// vue 文件中
{{number2Chinese(-1000012.111)}}
-----
import { number2Chinese } from '../common/utils.js'
data(){
  return{
      number2Chinese
  }
}

参数说明

第一个参数 number 值为需要转化为大写的数字

第二个参数 type 值为'upper'繁体或者'lower'简体 表示转化出来的数字是简体(一)还是繁体(壹) ,默认upper繁体

第三个参数 prefix 值为字符串 表示负数时,这个符号转化为什么 默认是'负',有些或许是负一百万,欠一百万

源码

/**
 * @description 数字转中文数码
 *
 * @param {Number|String}   num     数字
 * @param {String}          type    文本类型,lower|upper,默认upper
 * @param {String}          prefix  文本类型,替换负号的字符,默认'负'
 *
 * @example number2Chinese(100000000) => "壹亿元整"
 */

export const number2Chinese = (number, type = "upper", prefix = "负") => {
    // 配置
    const confs = {
        lower: {
            num: ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"],
            unit: ["", "十", "百", "千", "万"],
            level: ["", "万", "亿"]
        },
        upper: {
            num: ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"],
            unit: ["", "拾", "佰", "仟"],
            level: ["", "万", "亿"]
        },
        decimal: {
            unit: ["分", "角"]
        },
        maxNumber: 999999999999.99
    };

    // 过滤不合法参数
    if (Number(number) > confs.maxNumber || isNaN(number)) return
      let negative = ''
      if (Number(number) < 0) {
        number = Math.abs(number)
        negative = prefix
      }
    const conf = confs[type];
    const numbers = String(Number(number).toFixed(3)).split(".");
    const integer = numbers[0].split("");
    const decimal = Number(numbers[1]) === 0 ? [] : numbers[1].split("").slice(0,2);
    // 小数直接截取2位  不进行舍入处理

    // 四位分级
    const levels = integer.reverse().reduce((pre, item, idx) => {
        let level = pre[0] && pre[0].length < 4 ? pre[0] : [];
        let value = item === "0" ? conf.num[item] : conf.num[item] + conf.unit[idx % 4];
        level.unshift(value);
        if (level.length === 1) {
            pre.unshift(level);
        } else {
            pre[0] = level;
        }
        return pre;
    }, []);

    // 整数部分
    const _integer = levels.reduce((pre, item, idx) => {
        let _level = conf.level[levels.length - idx - 1];
        let _item = item.join("").replace(/(零)\1+/g, "$1"); // 连续多个零字的部分设置为单个零字

        // 如果这一级只有一个零字,则去掉这级
        if (_item === "零") {
            _item = "";
            _level = "";
            // 否则如果末尾为零字,则去掉这个零字
        } else if (_item[_item.length - 1] === "零") {
            _item = _item.slice(0, _item.length - 1);
        }

        return pre + _item + _level;
    }, "");

    // 小数部分
    let _decimal = decimal.map((item, idx) => {
            const unit = confs.decimal.unit;
            const _unit = item !== "0" ? unit[unit.length - idx - 1] : "";
            return `${conf.num[item]}${_unit}`;
        }).join("");

    // 如果是整数,则补个整字
    return `${negative}${_integer}元` + (_decimal || "整");
}

知识

toFixed 并不是我们直接截取两位小数、也不是四舍五入。toFixed(1) 返回 '1.00',所以通过保留三位小数然后截取前两位及整数部分

function() {
  // 返回新的字符串
  str.substring(0, str.length - 1)
  str.slice(0, str.length - 1)
  // 返回新的数组
  arr.slice(0, arr.length - 1)
}

数组的reduce方法的使用,其实和数组的map等是一样的使用,map每次返回一个元素 ,最终由返回元素一个新数组,而reduce 每次返回的元素都被reduce自己拿去使用了。

map((current, index, arr)=> {
  //map 三个参数 current当前元素 index当前元素下标,arr数组本身
})

reduce((pre, current, index, arr)=> {
  //pre 上一次返会的值 current当前元素 index当前元素下标,arr数组本身
  // initValue 第一次是没有上一次的,这时候把初始值initValue赋给pre
},initValue)

参考:https://juejin.cn/post/6844904039461683207#comment

posted @ 2021-10-31 13:41  雨天。我  阅读(110)  评论(0编辑  收藏  举报