提交
This commit is contained in:
1 parent
771f010a39
commit
ee4abd361e
102 files changed
+8021
-4094
No files matched your search
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* 金额格式化工具模块
|
||||
* 提供千分位分隔、输入清洗、展示格式化、数值解析等功能
|
||||
*/
|
||||
|
||||
/** 字符串分段拼接千分位,禁止使用前瞻正则 */
|
||||
export function addThousandSeparators(intStr: string): string {
|
||||
if (!intStr) return ''
|
||||
const isNegative = intStr.startsWith('-')
|
||||
const absStr = isNegative ? intStr.slice(1) : intStr
|
||||
const parts: string[] = []
|
||||
const len = absStr.length
|
||||
for (let i = len; i > 0; i -= 3) {
|
||||
const start = Math.max(0, i - 3)
|
||||
parts.unshift(absStr.slice(start, i))
|
||||
}
|
||||
const result = parts.join(',')
|
||||
return isNegative ? `-${result}` : result
|
||||
}
|
||||
|
||||
/** 输入清洗:去逗号、仅保留数字与一个点、截断小数位 */
|
||||
export function sanitizeMoneyInput(value: string, precision = 2): string {
|
||||
if (!value) return ''
|
||||
// 去逗号
|
||||
let cleaned = value.replace(/,/g, '')
|
||||
// 去非数字非点字符
|
||||
cleaned = cleaned.replace(/[^0-9.]/g, '')
|
||||
// 只保留第一个小数点
|
||||
const dotIndex = cleaned.indexOf('.')
|
||||
if (dotIndex !== -1) {
|
||||
const intPart = cleaned.slice(0, dotIndex + 1)
|
||||
const decPart = cleaned.slice(dotIndex + 1).replace(/\./g, '')
|
||||
cleaned = intPart + decPart
|
||||
}
|
||||
// 截断小数到 precision 位
|
||||
if (dotIndex !== -1) {
|
||||
const dotIdx = cleaned.indexOf('.')
|
||||
const intPart = cleaned.slice(0, dotIdx + 1)
|
||||
let decPart = cleaned.slice(dotIdx + 1)
|
||||
if (decPart.length > precision) {
|
||||
decPart = decPart.slice(0, precision)
|
||||
}
|
||||
cleaned = intPart + decPart
|
||||
}
|
||||
return cleaned
|
||||
}
|
||||
|
||||
/** 展示:整数部分千分位 + 最多 precision 位小数 */
|
||||
export function formatMoneyDisplay(
|
||||
value: string | number | null | undefined,
|
||||
precision = 2
|
||||
): string {
|
||||
if (value === null || value === undefined || value === '') return '0.00'
|
||||
const num = typeof value === 'string' ? parseFloat(value) : value
|
||||
if (isNaN(num)) return '0.00'
|
||||
const isNegative = num < 0
|
||||
const absNum = Math.abs(num)
|
||||
const fixed = absNum.toFixed(precision)
|
||||
const [intStr, decStr] = fixed.split('.')
|
||||
const formatted = addThousandSeparators(intStr)
|
||||
const result = `${formatted}.${decStr}`
|
||||
return isNegative ? `-${result}` : result
|
||||
}
|
||||
|
||||
/** 提交:number | null;空串 / 仅 '.' → null */
|
||||
export function parseMoneyToNumber(value: string, precision = 2): number | null {
|
||||
const sanitized = sanitizeMoneyInput(value, precision)
|
||||
if (!sanitized || sanitized === '.') return null
|
||||
const num = Number(sanitized)
|
||||
if (isNaN(num)) return null
|
||||
const factor = Math.pow(10, precision)
|
||||
return Math.round(num * factor) / factor
|
||||
}
|
||||
Reference in new issue
Block a user