Skip to content

Commit 33153b3

Browse files
committed
feat: [yuanFormat] 增加 options.prefix 和 options.space
1 parent c882655 commit 33153b3

File tree

2 files changed

+97
-3
lines changed

2 files changed

+97
-3
lines changed

packages/core/src/yuanFormat.test.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,72 @@ describe('yuanFormat', () => {
4646
expect(yuanFormat(-1000000, { unit: 'yuan' })).toMatchInlineSnapshot(`"-1,000,000.00"`)
4747
expect(yuanFormat(-9432432.34, { unit: 'yuan'})).toMatchInlineSnapshot(`"-9,432,432.34"`)
4848
})
49+
50+
describe('prefix option', () => {
51+
it('should work with prefix: true (¥)', () => {
52+
expect(yuanFormat(100, { prefix: true })).toBe('¥1.00')
53+
expect(yuanFormat(100000, { prefix: true })).toBe('¥1,000.00')
54+
expect(yuanFormat(100, { prefix: true, unit: 'yuan' })).toBe('¥100.00')
55+
expect(yuanFormat(-100, { prefix: true })).toBe('¥-1.00')
56+
})
57+
58+
it('should work with custom prefix string', () => {
59+
expect(yuanFormat(100, { prefix: '$' })).toBe('$1.00')
60+
expect(yuanFormat(100000, { prefix: 'USD' })).toBe('USD1,000.00')
61+
expect(yuanFormat(100, { prefix: '€', unit: 'yuan' })).toBe('€100.00')
62+
expect(yuanFormat(-100, { prefix: 'RMB' })).toBe('RMB-1.00')
63+
})
64+
65+
it('should work without prefix (undefined)', () => {
66+
expect(yuanFormat(100)).toBe('1.00')
67+
expect(yuanFormat(100, { prefix: undefined })).toBe('1.00')
68+
expect(yuanFormat(100000)).toBe('1,000.00')
69+
})
70+
})
71+
72+
describe('space option', () => {
73+
it('should add space between prefix and amount when space: true', () => {
74+
expect(yuanFormat(100, { prefix: true, space: true })).toBe('¥ 1.00')
75+
expect(yuanFormat(100000, { prefix: true, space: true })).toBe('¥ 1,000.00')
76+
expect(yuanFormat(100, { prefix: '$', space: true })).toBe('$ 1.00')
77+
expect(yuanFormat(100, { prefix: 'USD', space: true })).toBe('USD 1.00')
78+
expect(yuanFormat(-100, { prefix: true, space: true })).toBe('¥ -1.00')
79+
})
80+
81+
it('should not add space when space: false or undefined', () => {
82+
expect(yuanFormat(100, { prefix: true, space: false })).toBe('¥1.00')
83+
expect(yuanFormat(100, { prefix: true })).toBe('¥1.00')
84+
expect(yuanFormat(100, { prefix: '$', space: false })).toBe('$1.00')
85+
expect(yuanFormat(100, { prefix: '$' })).toBe('$1.00')
86+
})
87+
88+
it('should ignore space option when prefix is undefined', () => {
89+
expect(yuanFormat(100, { space: true })).toBe('1.00')
90+
expect(yuanFormat(100, { prefix: undefined, space: true })).toBe('1.00')
91+
})
92+
})
93+
94+
describe('combined prefix and space options', () => {
95+
it('should work with all combinations', () => {
96+
// prefix: true, space: true
97+
expect(yuanFormat(12345, { prefix: true, space: true })).toBe('¥ 123.45')
98+
// prefix: string, space: true
99+
expect(yuanFormat(12345, { prefix: 'CNY', space: true })).toBe('CNY 123.45')
100+
// prefix: true, space: false
101+
expect(yuanFormat(12345, { prefix: true, space: false })).toBe('¥123.45')
102+
// prefix: string, space: false
103+
expect(yuanFormat(12345, { prefix: 'CNY', space: false })).toBe('CNY123.45')
104+
// with unit: yuan
105+
expect(yuanFormat(123.45, { prefix: true, space: true, unit: 'yuan' })).toBe('¥ 123.45')
106+
expect(yuanFormat(123456.78, { prefix: 'USD', space: true, unit: 'yuan' })).toBe('USD 123,456.78')
107+
})
108+
})
109+
110+
describe('error cases with prefix and space', () => {
111+
it('should return "-" when input is invalid even with prefix/space options', () => {
112+
expect(yuanFormat(null as any, { prefix: true, space: true })).toBe('-')
113+
expect(yuanFormat('abc' as any, { prefix: '$', space: true })).toBe('-')
114+
expect(yuanFormat(Number.NaN, { prefix: true })).toBe('-')
115+
})
116+
})
49117
})

packages/core/src/yuanFormat.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,55 @@ interface Options {
88
* @default 'fen'
99
*/
1010
unit?: 'fen' | 'yuan'
11+
/**
12+
* 前缀,如果是 true 则使用 ¥,或者使用传入的字符
13+
* @default undefined
14+
*/
15+
prefix?: string | true
16+
/**
17+
* 是否在前缀 prefix 和数值之间添加空格
18+
* @default undefined
19+
*/
20+
space?: boolean
1121
}
1222

1323
/**
1424
* 金额格式化¥ 分转元(如果单位是分),并保留两位小数,最后添加千位分隔符
1525
* @param num 金额
16-
* @param options (单位默认是 分),
26+
* @param options 格式化选项
27+
* @param options.unit 单位,分或元,如果单位是分,则会将金额转换为元,默认为 'fen'
28+
* @param options.prefix 前缀,如果是 true 则使用 ¥,或者使用传入的字符串,默认为 undefined
29+
* @param options.space 是否在前缀和数值之间添加空格,默认为 false
1730
* @returns 格式化后的金额, 如果输入不是数字,则返回 '-'
1831
* @example
1932
* ```ts
2033
* yuanFormat(100) // '1.00'
2134
* yuanFormat(100, { unit: 'yuan' }) // '100.00'
35+
* yuanFormat(100, { prefix: true }) // '¥1.00'
36+
* yuanFormat(100, { prefix: '$' }) // '$1.00'
37+
* yuanFormat(100, { prefix: true, space: true }) // '¥ 1.00'
38+
* yuanFormat(100000, { prefix: 'USD', space: true }) // 'USD 1,000.00'
2239
* yuanFormat('not number') // '-'
2340
* ```
2441
*/
2542
export function yuanFormat(num?: number, options?: Options): string | '-' {
2643
try {
2744
if (!isNumber(num) || Number.isNaN(num))
2845
return '-'
29-
const { unit = 'fen' } = options ?? {}
46+
const { unit = 'fen', prefix, space } = options ?? {}
3047
const yuan = unit === 'fen' ? fenToYuan(num) : num
3148
if (yuan === null || yuan === undefined)
3249
return '-'
33-
return yuan.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
50+
51+
const formattedAmount = yuan.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
52+
53+
if (!prefix)
54+
return formattedAmount
55+
56+
const prefixStr = prefix === true ? '¥' : prefix
57+
const spacing = space ? ' ' : ''
58+
59+
return `${prefixStr}${spacing}${formattedAmount}`
3460
}
3561
catch (err) {
3662
console.error(err)

0 commit comments

Comments
 (0)