const uppercaseDigits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'] as const const positionUnits = ['', '拾', '佰', '仟'] as const const sectionUnits = ['', '万', '亿', '兆', '京'] as const export function formatChineseUppercaseAmount(value: string) { const normalizedValue = value.trim().replaceAll(',', '') const matchedValue = /^([+-]?)(\d+)(?:\.(\d*))?$/.exec(normalizedValue) if (!matchedValue) return '' const negative = matchedValue[1] === '-' const decimal = matchedValue[3] || '' let integer = BigInt(matchedValue[2] || '0') let fenValue = BigInt(decimal.slice(0, 2).padEnd(2, '0')) if ((decimal[2] || '0') >= '5') fenValue += 1n if (fenValue >= 100n) { integer += fenValue / 100n fenValue %= 100n } if (integer === 0n && fenValue === 0n) return '零元整' const uppercaseInteger = formatUppercaseInteger(integer.toString()) if (integer > 0n && !uppercaseInteger) return '金额超出转换范围' const jiao = Number(fenValue / 10n) const fen = Number(fenValue % 10n) let result = uppercaseInteger ? `${uppercaseInteger}元` : '' if (jiao === 0 && fen === 0) { result = `${result || '零元'}整` } else { if (jiao > 0) { result += `${uppercaseDigits[jiao] || ''}角` } else if (result && fen > 0) { result += '零' } if (fen > 0) result += `${uppercaseDigits[fen] || ''}分` } return negative ? `负${result}` : result } function formatUppercaseInteger(value: string) { if (value === '0') return '' const sections: string[] = [] for (let end = value.length; end > 0; end -= 4) { sections.push(value.slice(Math.max(0, end - 4), end)) } if (sections.length > sectionUnits.length) return '' let result = '' let needsZero = false for (let index = sections.length - 1; index >= 0; index -= 1) { const section = sections[index] || '' const sectionValue = Number(section) if (sectionValue === 0) { if (result) needsZero = true continue } if (result && (needsZero || sectionValue < 1000)) result += '零' const sectionUnit = sectionUnits[index] if (sectionUnit === undefined) return '' result += `${formatFourDigitSection(section)}${sectionUnit}` needsZero = false } return result } function formatFourDigitSection(value: string) { let result = '' let needsZero = false for (let index = 0; index < value.length; index += 1) { const digit = Number(value.charAt(index)) if (digit === 0) { if (result) needsZero = true continue } if (needsZero) { result += '零' needsZero = false } const digitText = uppercaseDigits[digit] || '' const positionUnit = positionUnits[value.length - index - 1] || '' result += `${digitText}${positionUnit}` } return result }