Skip to content

Commit

Permalink
Chore: 格式化代码还是按80列 & 更新TS调试配置
Browse files Browse the repository at this point in the history
Feat: 增加阿拉伯数字转中文数字函数
  • Loading branch information
Maorey committed Feb 19, 2020
1 parent 4859405 commit 8f4a901
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ indent_size = 2
end_of_line = lf
quote_type = single
indent_style = space
max_line_length = 100
max_line_length = 80
insert_final_newline = true
spaces_around_operators = true
trim_trailing_whitespace = true
Expand Down
5 changes: 3 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
"name": "file",
"cwd": "${workspaceFolder}",
"program": "${file}",
"preLaunchTask": "tsc: 监视 - .vscode/tsconfig.json", // cn
// "preLaunchTask": "tsc: watch - .vscode/tsconfig.json", // en
// .vscode 目录又不认识了???
"preLaunchTask": "tsc: 监视 - build/tsconfig.json", // cn
// "preLaunchTask": "tsc: watch - build/tsconfig.json", // en
"outFiles": [
"${workspaceFolder}/compile/**/*.js"
]
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"editor.tabSize": 2,
"editor.wordWrap": "on",
"editor.wordWrapColumn": 100,
"editor.wordWrapColumn": 80,
"editor.fontLigatures": true,
"editor.wrappingIndent": "indent",
"editor.detectIndentation": false,
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion package.json
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": [
Expand Down
104 changes: 104 additions & 0 deletions src/utils/numToCN.ts
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
}
)
}
74 changes: 74 additions & 0 deletions tests/unit/utils/numToCN.spec.ts
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(
'负一二三四五六七八九零九八七六五四三二一零'
)
})
})

0 comments on commit 8f4a901

Please sign in to comment.