likes
comments
collection
share

列表金额字段字段转中文大写悬浮展示

作者站长头像
站长
· 阅读数 26

金额转中文大写需求:

  1. 列表中涉及存在的金额字段,鼠标悬浮的时候要展示对应的大写金额
  2. 要考虑千分符问题
  3. 要考虑后面2位小数问题
  4. 要考虑金额为0元的问题
  5. 要考虑金额为整数的问题

不要问我为什么大写金额不直接让后端转了后直接返回来,这样的需求多了去了,后端可以实现前端也可以实现,懂的都懂,我这里只是把实现方式分享一下,具体的方案:以各位大佬的公司需求以及前后端任务划分为准。

页面效果:

列表金额字段字段转中文大写悬浮展示

列表金额字段字段转中文大写悬浮展示

列表金额字段字段转中文大写悬浮展示

代码展示:

//数字金额转中文大写
export function numToCapital(n) {
  // 定义需要用到的数组
  const fraction = ['角', '分'] //小数部分的单位
  const digit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'] //数字与汉字的对应关系
  const unit = [
    ['元', '万', '亿'], //整数部分的单位
    ['', '拾', '佰', '仟'] //数字位与汉字的对应关系
  ]
  let delThousands = n.replace(/,/g, '') //去除千分符
  let num = Math.abs(delThousands) //获取数字的绝对值
  let s = '' //最终输出的字符串
  //循环处理小数部分
  fraction.forEach((item, index) => {
    s += (digit[Math.floor(num * 10 * Math.pow(10, index)) % 10] + item).replace(/零./, '') //将小数部分转换为汉字,并去掉“零”
  })
  s = s || '整' //如果没有小数则加上“整”
  num = Math.floor(num) //向下取整,确保为整数
  //循环处理整数部分
  for (let i = 0; i < unit[0].length && num > 0; i++) {
    let p = ''
    for (let j = 0; j < unit[1].length && num > 0; j++) {
      p = digit[num % 10] + unit[1][j] + p //将数字位转换为汉字,并和单位拼接
      num = Math.floor(num / 10) //每次去掉最后一位数字
    }
    s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s //去掉连续的“零”,将整数部分和单位拼接
  }
  return (n < 0 ? '负' : '') + s.replace(/^整$/, '零元整') //如果是负数,则加上“负”,如果是整数,则加上“零元整”
}

如果后端返回数据没有携带千分符,可以不去处理。

列表中鼠标悬浮显示效果是使用了element-ui的el-popover实现,当初自己也在网上找个其它方式去实现,但是会有缺陷,例如悬浮效果样式不好控制,而且悬浮的时候无法截图,截图会自动悬浮失效。

结合插槽去使用,上代码

<template #cost="scope">
    <el-popover trigger="hover" placement="top">
       <p>{{ numToCapital(scope.row.cost) }}</p>
         <div slot="reference" class="name-wrapper">
            {{ scope.row.cost }}
          </div>
    </el-popover>
</template>

2023-5-15更新一下,修复一个bug 上面的图三中转换后的大写金额细看会有个问题,中间的零佰会十分拗口,不符合我们的口语化.....

问题在于:处理整数部分,从低位往高位依次处理。首先处理个位数1,对应的汉字为“壹”,加上单位“元”得到“壹元”;然后处理十位数2,对应的汉字为“贰”,加上数字位对应的汉字“拾”得到“贰拾”,将其拼接到已有的字符串后面得到“贰拾壹元”;接着处理百位数0,由于百位数为0,所以不需要加上数字位对应的汉字,直接跳过;然后处理千位数5,对应的汉字为“伍”,加上数字位对应的汉字“仟”得到“伍仟”,将其拼接到已有的字符串后面得到“伍仟贰百叁拾伍元”;最后处理万位数6,对应的汉字为“陆”,加上单位“万”得到“陆万”,将其拼接到已有的字符串后面得到“陆万伍仟贰百叁拾伍元”。

修复方案: p = digit[num % 10] + unit[1][j] + p //将数字位转换为汉字,并和单位拼接

改为

if (num % 10 !== 0 || p.match(/零$/)) { p = digit[num % 10] + unit[1][j] + p //将数字位转换为汉字,并和单位拼接 } else { p = '零' + p }