-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: 增加阿拉伯数字转中文数字函数
- Loading branch information
Showing
7 changed files
with
184 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
{ | ||
"name": "vue-tpl", | ||
"author": "毛瑞 <[email protected]>", | ||
"version": "1.2.1", | ||
"version": "1.2.2", | ||
"private": false, | ||
"license": "MIT", | ||
"keywords": [ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/** 阿拉伯数字转中文数字(最高支持描述万万亿) | ||
* @param {string|number} number 阿拉伯数字 | ||
* @param {number} unit 1: 不需要单位 2: 不需要单位并且保留开头的0 | ||
* | ||
* @returns {string} 中文数字 | ||
*/ | ||
export default function numToCN(number: string | number, noUnit?: 1 | 2) { | ||
if (!number && number !== 0) { | ||
return '' | ||
} | ||
|
||
const POINT = '点' | ||
const NUM = '零一二三四五六七八九' | ||
const UNIT = '十百千万十百千亿十百千万十百千' | ||
const SIGN = { '+': '正', '-': '负' } | ||
const LEN_UNIT = 15 // UNIT.length | ||
const ZERO = '零' // NUM[0] | ||
const UNIT_MAX = '亿' // 最大单位 | ||
const TRIPLE = '万' // 溢出单位 一二万万亿 | ||
const TRIPLE_POS = 11 // 万的最后位置 十万亿 | ||
const TRIM_BEFORE = /^零*[十百千万亿]*/ // 去开头的0和单位 | ||
return String(number).replace( | ||
/([+-])?(\d+)(\.\d+)?/g, | ||
(match, sign: '+' | '-', integer: string, decimal: string) => { | ||
let result = '' | ||
|
||
let index | ||
// 小数部分(保留末尾0) | ||
if (decimal) { | ||
index = decimal.length | ||
while (--index) { | ||
result = NUM[decimal[index] as any] + result | ||
} | ||
result = POINT + result | ||
} | ||
|
||
let char | ||
let unit | ||
let pos | ||
let indexUnit = -1 // [-1, LEN_UNIT) | ||
index = integer.length | ||
// 整数部分 | ||
while (index--) { | ||
char = NUM[integer[index] as any] | ||
if (!noUnit) { | ||
if (indexUnit < LEN_UNIT) { | ||
// 未超过最大可描述数值 | ||
unit = UNIT[indexUnit++] || '' | ||
if (ZERO === char) { | ||
char = result[0] | ||
switch (char) { | ||
case (pos = UNIT.indexOf(char)) >= 0 && char: | ||
// 替换上大的单位 | ||
if (indexUnit > TRIPLE_POS && char === UNIT_MAX) { | ||
// 万亿 | ||
char = unit | ||
} else if ((pos as any) < UNIT.indexOf(unit)) { | ||
char = unit | ||
result = result.substring(1) | ||
} else { | ||
char = '' | ||
} | ||
break | ||
|
||
default: | ||
// ZERO POINT falsy ... | ||
char = NUM.indexOf(char) > 0 ? unit + ZERO : unit | ||
} | ||
} else if (unit) { | ||
;(pos = UNIT.indexOf(result[0])) >= 0 && | ||
pos < UNIT.indexOf(unit) && | ||
(result = result.substring(1)) | ||
char += unit | ||
} | ||
} else if (indexUnit === LEN_UNIT) { | ||
indexUnit++ // 使只执行一次 | ||
result = TRIPLE + result | ||
} | ||
} | ||
|
||
result = char + result | ||
} | ||
|
||
char = result[0] // 兼职首字 | ||
if (!char || char === POINT) { | ||
// 补零 0/0.1 | ||
result = ZERO + result | ||
} else if (char === NUM[1] && result[1] === UNIT[0]) { | ||
// 一十* => 十* | ||
result = result.substring(1) | ||
} else if (noUnit !== 2 && (char === ZERO || UNIT.indexOf(char) >= 0)) { | ||
// 去零及单位开头的 | ||
ZERO === | ||
(result = | ||
result.replace( | ||
TRIM_BEFORE, | ||
noUnit || indexUnit > LEN_UNIT ? '' : ZERO | ||
) || ZERO) && (sign = 0 as any) | ||
} | ||
// 加正负号 | ||
return (SIGN[sign] || '') + result | ||
} | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/** 阿拉伯数字转中文数字 | ||
*/ | ||
import numToCN from '@/utils/numToCN' | ||
describe('@/utils/numToCN: 阿拉伯数字和中文转换', () => { | ||
it('numToCN: 阿拉伯数字转中文数字', () => { | ||
expect(numToCN('')).toBe('') | ||
|
||
expect(numToCN(0)).toBe('零') | ||
expect(numToCN('00')).toBe('零') | ||
expect(numToCN('+000000')).toBe('零') | ||
expect(numToCN('-0000000000')).toBe('零') | ||
expect(numToCN('00000000000000000')).toBe('零') | ||
|
||
expect(numToCN(-0.1)).toBe('负零点一') | ||
expect(numToCN(0.01)).toBe('零点零一') | ||
expect(numToCN('0.01230')).toBe('零点零一二三零') | ||
expect(numToCN('-00000.01200')).toBe('负零点零一二零零') | ||
|
||
expect(numToCN(2)).toBe('二') | ||
expect(numToCN('+2')).toBe('正二') | ||
expect(numToCN(-2)).toBe('负二') | ||
expect(numToCN('+ 2')).toBe('+ 二') | ||
expect(numToCN('- 2')).toBe('- 二') | ||
|
||
expect(numToCN('测试')).toBe('测试') | ||
expect(numToCN('测试2')).toBe('测试二') | ||
expect(numToCN('测试2和测试-2')).toBe('测试二和测试负二') | ||
|
||
expect(numToCN(10)).toBe('十') | ||
expect(numToCN(12)).toBe('十二') | ||
|
||
expect(numToCN(100)).toBe('一百') | ||
expect(numToCN(120)).toBe('一百二十') | ||
expect(numToCN(103)).toBe('一百零三') | ||
|
||
expect(numToCN(1000)).toBe('一千') | ||
expect(numToCN(1004)).toBe('一千零四') | ||
expect(numToCN(1030)).toBe('一千零三十') | ||
expect(numToCN(1200)).toBe('一千二百') | ||
|
||
expect(numToCN(10000)).toBe('一万') | ||
expect(numToCN(10005)).toBe('一万零五') | ||
expect(numToCN(10040)).toBe('一万零四十') | ||
expect(numToCN(10045)).toBe('一万零四十五') | ||
expect(numToCN(10300)).toBe('一万零三百') | ||
expect(numToCN(10305)).toBe('一万零三百零五') | ||
expect(numToCN(10340)).toBe('一万零三百四十') | ||
expect(numToCN(10345)).toBe('一万零三百四十五') | ||
expect(numToCN(12000)).toBe('一万二千') | ||
expect(numToCN(12005)).toBe('一万二千零五') | ||
expect(numToCN(12040)).toBe('一万二千零四十') | ||
expect(numToCN(12045)).toBe('一万二千零四十五') | ||
expect(numToCN(12300)).toBe('一万二千三百') | ||
expect(numToCN(12305)).toBe('一万二千三百零五') | ||
expect(numToCN(12340)).toBe('一万二千三百四十') | ||
expect(numToCN(12345)).toBe('一万二千三百四十五') | ||
|
||
expect(numToCN(100006)).toBe('十万零六') | ||
expect(numToCN(1004067)).toBe('一百万零四千零六十七') | ||
expect(numToCN(1014067)).toBe('一百零一万四千零六十七') | ||
expect(numToCN(123456789000000)).toBe( | ||
'一百二十三万四千五百六十七亿八千九百万' | ||
) | ||
expect(numToCN('012345678909876543210')).toBe( | ||
'一二三四万五千六百七十八万九千零九十八亿七千六百五十四万三千二百一十' | ||
) | ||
|
||
expect(numToCN('012345.67890', 1)).toBe('一二三四五点六七八九零') | ||
expect(numToCN('012345.67890', 2)).toBe('零一二三四五点六七八九零') | ||
expect(numToCN('-012345678909876543210', 1)).toBe( | ||
'负一二三四五六七八九零九八七六五四三二一零' | ||
) | ||
}) | ||
}) |