Browse Source

添加金额转中文大写的函数

yjp 2 weeks ago
parent
commit
d15181923c
1 changed files with 116 additions and 1 deletions
  1. 116 1
      money/money.go

+ 116 - 1
money/money.go

@@ -1,6 +1,10 @@
 package money
 package money
 
 
-import "github.com/shopspring/decimal"
+import (
+	"strings"
+
+	"github.com/shopspring/decimal"
+)
 
 
 func Yuan2Fen(price float64) int64 {
 func Yuan2Fen(price float64) int64 {
 	return decimal.NewFromFloat(price).Mul(decimal.New(1, 2)).IntPart()
 	return decimal.NewFromFloat(price).Mul(decimal.New(1, 2)).IntPart()
@@ -12,3 +16,114 @@ func Fen2Yuan(price uint64) float64 {
 	result, _ := decimal.NewFromInt(int64(price)).DivRound(d, 2).Float64()
 	result, _ := decimal.NewFromInt(int64(price)).DivRound(d, 2).Float64()
 	return result
 	return result
 }
 }
+
+var (
+	numUpper = []string{"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"}
+	unitInt  = []string{"", "拾", "佰", "仟"}   // 个、十、百、千
+	unitSec  = []string{"", "万", "亿", "万亿"} // 万级单位
+	unitDec  = []string{"角", "分"}             // 小数单位
+)
+
+func AmountToChinese(amount float64) string {
+	if amount == 0 {
+		return "零元整"
+	}
+
+	// 处理负数
+	prefix := ""
+	if amount < 0 {
+		prefix = "负"
+		amount = -amount
+	}
+
+	// 转成整数(分)
+	n := int64(amount*100 + 0.5)
+
+	intPart := n / 100 // 整数部分
+	decPart := n % 100 // 小数部分
+
+	result := prefix + integerToChinese(intPart)
+
+	// 小数部分处理
+	if decPart == 0 {
+		return result + "元整"
+	}
+
+	result += "元"
+
+	jiao := decPart / 10
+	fen := decPart % 10
+
+	if jiao > 0 {
+		result += numUpper[jiao] + unitDec[0] // 角
+	} else if fen > 0 {
+		result += "零" // 无角有分,如 0.05 → “零”
+	}
+
+	if fen > 0 {
+		result += numUpper[fen] + unitDec[1] // 分
+	} else {
+		result += "整" // 无分,加“整”
+	}
+
+	return result
+}
+
+// 整数金额转大写
+func integerToChinese(num int64) string {
+	if num == 0 {
+		return "零"
+	}
+
+	var res string
+	secIdx := 0 // 万、亿、万亿
+
+	for num > 0 {
+		section := num % 10000
+		if section != 0 {
+			sectionStr := sectionToChinese(section)
+			if secIdx > 0 {
+				sectionStr += unitSec[secIdx]
+			}
+			res = sectionStr + res
+		} else {
+			if !strings.HasPrefix(res, "零") {
+				res = "零" + res
+			}
+		}
+		num /= 10000
+		secIdx++
+	}
+
+	// 清理多余“零”
+	res = strings.TrimLeft(res, "零")
+	for strings.Contains(res, "零零") {
+		res = strings.ReplaceAll(res, "零零", "零")
+	}
+	res = strings.TrimRight(res, "零")
+
+	return res
+}
+
+// 每个 4 位小节(0~9999)
+func sectionToChinese(section int64) string {
+	var str string
+	unitPos := 0
+	zeroFlag := false
+
+	for section > 0 {
+		digit := section % 10
+		if digit == 0 {
+			if !zeroFlag && len(str) > 0 {
+				str = "零" + str
+			}
+			zeroFlag = true
+		} else {
+			str = numUpper[digit] + unitInt[unitPos] + str
+			zeroFlag = false
+		}
+		unitPos++
+		section /= 10
+	}
+	return str
+}