|
@@ -0,0 +1,120 @@
|
|
|
|
+/**
|
|
|
|
+ * 金额转换
|
|
|
|
+ * @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)
|
|
|
|
+}
|