数字:过滤、转中文、转千位符...

747 阅读2分钟

由于项目经常使用到数字类型转换过滤,个人封装了数字类型过滤器与转换,提高团队的开发效率。

number.js:https://pgyqx.oss-…


/**
 * 千位符 toThousands
 * num  字符串或者数字 *必传
 * fixed 保留位数 0整数 >=1小数位数  *不必填
 */
export function toThousands(num, fixed, check = true) {
  try {
    let text = ''
    if (check) {
      text = num ? parseFloat(String(num).replace(/,/g, '')) : 0.00
      if (isNaN(text)) {
        throw new Error(`数据异常:${num}`)
      }
      text = Number(fixed) > 0 ? text.toFixed(Number(fixed)) : (Number(fixed) === 0) ? Math.round(text) : text.toString()
    } else {
      text = String(num)
    }
    return text.replace(text.indexOf('.') < 0 ? /(\d)(?=(\d{3})+$)/g : /(\d)(?=(\d{3})+\.)/g, function($0, $1) {
      return $1 + ','
    })
  } catch (e) {
    console.error(e || `千位符转换失败:${num}`)
    return num
  }
}

/**
 * 数字转中文
 */
export function toChinese(num) {
  try {
    if (!/^(0|\-*[1-9]\d*)(\.\d+)?$/.test(num)) throw new Error(`数据异常:${num}`)
    const fuhao = (num.toString().indexOf('-') === 0 ? '负' : '')
    let unit = '千百拾万千百拾亿千百拾万千百拾元角分'
    let str = ''
    let n = num + '00'
    if (fuhao === '负') {
      n = n.substring(1, n.length)
    }
    if (String(num).replace('-', '') === '0') {
      return '零元'
    }
    const p = n.indexOf('.')
    if (p >= 0) {
      n = n.substring(0, p) + n.substr(p + 1, 2)
    }
    unit = unit.substr(unit.length - n.length)
    for (const i in n) {
      str += '零壹贰叁肆伍陆柒捌玖'.charAt(n.charAt(i)) + unit.charAt(i)
    }
    return fuhao + str.replace(/零(千|百|拾|角)/g, '零').replace(/(零)+/g, '零').replace(/零(万|亿|元)/g, '$1').replace(/(亿)万|壹(拾)/g, '$1$2').replace(/^元零?|零分/g, '').replace(/元$/g, '元整')
  } catch (e) {
    console.error(e || `转换中文失败:${num}`)
    return num
  }
}

/**
 * 数字类型过滤器
 * val  值
 * obj 过滤方式
 */

export function setIntFilter(val, obj = {}) {
  try {
    const initData = Object.assign({
      min: -999999999999, // 最小值
      max: 99999999, // 最大值 到千亿
      fixed: -1, // 保留位数  -1不限制 0>=其他保留的位数
      default: '', // 默认值
      fixedSup: false, // 保留小数位数大于0时开启 小数位数不足是否补 0
      toThousands: false, // 是否转换千位符
      toChinese: false, //  转中文
      prefix: '', // 内容添加前缀
      suffix: '', // 内容添加后缀
      empty: '', // 数据为空时显示
      simplify: false, // 数字简化展示
      simplifyData: {
        0: { suffix: '' },
        10000: { suffix: '万' },
        100000000: { suffix: '亿' }
      },
      math: '' // round:保留小数四舍五入    ceil:保留小数向上取值   floor:保留小数向下取值 *使用时候请注意ceil与floor的使用与特性 Math.ceil(8.540*Math.pow(10,2))/Math.pow(10,2)
    }, obj)
    let simplifySuffix = ''
    let value = !isNaN(parseFloat(String(val).replace(/,/g, ''))) ? parseFloat(String(val).replace(/,/g, '')) : (!isNaN(parseFloat(String(initData.default).replace(/,/g, ''))) ? parseFloat(String(initData.default).replace(/,/g, '')) : '')
    const roundFun = function(value, n, type) {
      if (type === 'ceil') {
        const returnValue = Math.ceil(value * Math.pow(10, n)) / Math.pow(10, n)
        return initData.fixedSup && n ? returnValue.toFixed(n) : returnValue
      } else if (type === 'floor') {
        const returnValue = Math.floor(value * Math.pow(10, n)) / Math.pow(10, n)
        return initData.fixedSup && n ? returnValue.toFixed(n) : returnValue
      } else {
        const returnValue = Math.round(value * Math.pow(10, n)) / Math.pow(10, n)
        return initData.fixedSup && n ? returnValue.toFixed(n) : returnValue
      }
    }
    if (typeof (value) === 'number') {
      /**
       * 初始值过滤判断
       */
      if (initData.min > value) {
        value = initData.min
      } else if (initData.max < value) {
        value = initData.max
      }
      /**
       * 简化展示
       */
      if (initData.simplify && initData.simplifyData) {
        let item = {}
        for (const num in initData.simplifyData) {
          if (num && value >= num) {
            item = initData.simplifyData[num]
            item.num = num
          }
        }
        simplifySuffix = item.suffix || ''
        value = value / item.num
      }
      /**
       * 保留位数转换
       */
      if (initData.fixed >= 0) {
        value = roundFun(value, initData.fixed, initData.math)
      }
      /**
       * 简化展示后缀
       */
      if (simplifySuffix) {
        value += simplifySuffix
      }
      /**
       * 转换千位符 else 转中文
       */
      if (initData.toThousands && String(value) && !initData.simplify) {
        value = toThousands(value, initData.fixed, false)
      } else if (initData.toChinese && String(value) && !initData.simplify) {
        value = toChinese(value)
      }
      /**
       * 新增前缀、后缀
       */
      if (String(value) && (initData.prefix || initData.suffix)) {
        value = `${initData.prefix}${value}${initData.suffix}`
      } else if (initData.empty && !String(value)) {
        value = initData.empty
      }
    }
    return value || initData.empty
  } catch (e) {
    console.error(e || `数字类型过滤失败:${val}`)
    return val
  }
}

setIntFilter配置参数

    {
      min: -999999999999, // 最小值
      max: 99999999, // 最大值 到千亿
      fixed: -1, // 保留位数  -1不限制 0>=其他保留的位数
      default: '', // 默认值
      fixedSup: false, // 保留小数位数大于0时开启 小数位数不足是否补 0
      toThousands: false, // 是否转换千位符
      toChinese: false, //  转中文
      prefix: '', // 内容添加前缀
      suffix: '', // 内容添加后缀
      empty: '', // 数据为空时显示
      simplify: false, // 数字简化展示
      simplifyData: {
        0: { suffix: '' },
        10000: { suffix: '万' },
        100000000: { suffix: '亿' }
      },
      math: '' // round:保留小数四舍五入    ceil:保留小数向上取值   floor:保留小数向下取值 *使用时候请注意ceil与floor的使用与特性 Math.ceil(8.540*Math.pow(10,2))/Math.pow(10,2)
    }

vue项目在main.js: prototype全局引入

/** * 封装 - 数字过滤器 */
import * as numbers from '@/utils/number'
Object.keys(numbers).forEach(key => {  Vue.prototype[key] = numbers[key]})

使用例子:

{{ setIntFilter('123abddf') }}
this.setIntFilter('123abddf')
==》 123

{{ setIntFilter('12345678', {toThousands: true, suffix: '元'}) }}
this.setIntFilter('12345678', {toThousands: true, suffix: '元'})
==》 12,345,678元{{ setIntFilter('12345678', {toChinese: true}) }}

this.setIntFilter('12345678', {toChinese: true})
==》壹千贰百叁拾肆万伍千陆百柒拾捌元整

具体使用请查看setIntFilter参数

vue项目在main.js: filter全局引入

import * as filters from '@/utils/number'
Object.keys(filters).forEach(key => {  Vue.filter(key, filters[key])})

使用例子:

{{ '12345678' | toThousands }}
==》 12,345,678

{{ '12345678' | toChinese }}
==》 壹千贰百叁拾肆万伍千陆百柒拾捌元整

{{ '12345678' | setIntFilter({toThousands: true, suffix: '元'}) }}
==》 12,345,678元

{{ 'aaaaaa' | setIntFilter() }}
==》 ''

{{ 'aaaaaa' | setIntFilter({empty: '-'}) }}
==》 -

{{ '12345678' | setIntFilter({fixed: 2, fixedSup: true}) }}
==》 12345678.00

具体使用请查看setIntFilter参数