|
|
@@ -1,6 +1,10 @@
|
|
|
package money
|
|
|
|
|
|
-import "github.com/shopspring/decimal"
|
|
|
+import (
|
|
|
+ "strings"
|
|
|
+
|
|
|
+ "github.com/shopspring/decimal"
|
|
|
+)
|
|
|
|
|
|
func Yuan2Fen(price float64) int64 {
|
|
|
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()
|
|
|
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
|
|
|
+}
|