Files
Veyra/internal/model/money.go
T
Blizzard 92329ddce2
Checks / verify (push) Failing after 9m52s
feat: 完成模拟交易闭环、App 与 A 股行情接入
统一单入口 Go 工程与前端依赖目录,增加后台供应商配置、候选审核、计划预算、成交冲正、持仓复盘和站内通知。接入策略版本、Python 回测、可配置 A 股公开行情及 zap 文件轮转日志,补充迁移、契约与验证。
2026-10-08 22:58:52 +08:00

45 lines
1.0 KiB
Go

package model
import (
"fmt"
"regexp"
"strconv"
"strings"
"git.sundynix.cn/Blizzard/Veyra/internal/apperror"
)
var moneyPattern = regexp.MustCompile(`^(0|[1-9][0-9]{0,9})(\.[0-9]{1,2})?$`)
// ParseMoney converts decimal text into exact cents, rejecting rounding and exponents.
func ParseMoney(value string) (int64, error) {
if !moneyPattern.MatchString(value) {
return 0, apperror.ErrInvalidInput
}
whole, fraction, _ := strings.Cut(value, ".")
units, err := strconv.ParseInt(whole, 10, 64)
if err != nil {
return 0, apperror.ErrInvalidInput
}
fraction += strings.Repeat("0", 2-len(fraction))
cents, err := strconv.ParseInt(fraction, 10, 64)
if err != nil {
return 0, apperror.ErrInvalidInput
}
amount := units*100 + cents
if amount > 100000000000 {
return 0, apperror.ErrInvalidInput
}
return amount, nil
}
func FormatMoney(minor int64) string {
sign := ""
absolute := uint64(minor)
if minor < 0 {
sign = "-"
absolute = uint64(-(minor + 1)) + 1
}
return fmt.Sprintf("%s%d.%02d", sign, absolute/100, absolute%100)
}