index.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // @ts-nocheck
  2. import { isString } from "../isString";
  3. import { isNumber } from "../isNumber";
  4. /**
  5. * 将金额转换为中文大写形式
  6. * @param {number | string} amount - 需要转换的金额,可以是数字或字符串
  7. * @returns {string} 转换后的中文大写金额
  8. */
  9. function capitalizedAmount(amount : number) : string
  10. function capitalizedAmount(amount : string) : string
  11. function capitalizedAmount(amount : any | null) : string {
  12. try {
  13. let _amountStr :string;
  14. let _amountNum :number = 0;
  15. // 如果输入是字符串,先将其转换为数字,并去除逗号
  16. if (typeof amount == 'string') {
  17. _amountNum = parseFloat((amount as string).replace(/,/g, ''));
  18. }
  19. if(isNumber(amount)) {
  20. _amountNum = amount as number
  21. }
  22. // 判断输入是否为有效的金额 || isNaN(amount)
  23. if (amount == null) throw new Error('不是有效的金额!');
  24. let result = '';
  25. // 处理负数情况
  26. if (_amountNum < 0) {
  27. result = '欠';
  28. _amountNum = Math.abs(_amountNum);
  29. }
  30. // 金额不能超过千亿以上
  31. if (_amountNum >= 10e11) throw new Error('计算金额过大!');
  32. // 保留两位小数并转换为字符串
  33. _amountStr = _amountNum.toFixed(2);
  34. // 定义数字、单位和小数单位的映射
  35. const digits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
  36. const units = ['', '拾', '佰', '仟'];
  37. const bigUnits = ['', '万', '亿'];
  38. const decimalUnits = ['角', '分'];
  39. // 分离整数部分和小数部分
  40. const amountArray = _amountStr.split('.');
  41. let integerPart = amountArray[0]; // string| number[]
  42. const decimalPart = amountArray[1];
  43. // 处理整数部分
  44. if (integerPart != '0') {
  45. let _integerPart = integerPart.split('').map((item):number => parseInt(item));
  46. // 将整数部分按四位一级进行分组
  47. const levels = _integerPart.reverse().reduce((prev:string[][], item, index):string[][] => {
  48. // const level = prev?.[0]?.length < 4 ? prev[0] : [];
  49. const level = prev.length > 0 && prev[0].length < 4 ? prev[0]: []
  50. const value = item == 0 ? digits[item] : digits[item] + units[index % 4];
  51. level.unshift(value);
  52. if (level.length == 1) {
  53. prev.unshift(level);
  54. } else {
  55. prev[0] = level;
  56. }
  57. return prev;
  58. }, [] as string[][]);
  59. // 将分组后的整数部分转换为中文大写形式
  60. result += levels.reduce((prev, item, index):string => {
  61. let _level = bigUnits[levels.length - index - 1];
  62. let _item = item.join('').replace(/(零)\1+/g, '$1');
  63. if (_item == '零') {
  64. _level = '';
  65. _item = '';
  66. } else if (_item.endsWith('零')) {
  67. _item = _item.slice(0, _item.length - 1);
  68. }
  69. return prev + _item + _level;
  70. }, '');
  71. } else {
  72. result += '零';
  73. }
  74. // 添加元
  75. result += '元';
  76. // 处理小数部分
  77. if (decimalPart != '00') {
  78. if (result == '零元') result = '';
  79. for (let i = 0; i < decimalPart.length; i++) {
  80. const digit = parseInt(decimalPart.charAt(i));
  81. if (digit != 0) {
  82. result += digits[digit] + decimalUnits[i];
  83. }
  84. }
  85. } else {
  86. result += '整';
  87. }
  88. return result;
  89. } catch (error : Error) {
  90. return error.message;
  91. }
  92. };