2026-07-17 16:55:22 +08:00

103 lines
2.8 KiB
Go

package mysql
import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"math"
"strings"
mysqlDriver "github.com/go-sql-driver/mysql"
"hyapp/pkg/appcode"
"hyapp/pkg/xerr"
)
func contextWithCommandApp(ctx context.Context, value string) context.Context {
if strings.TrimSpace(value) == "" {
return appcode.WithContext(ctx, appcode.FromContext(ctx))
}
return appcode.WithContext(ctx, value)
}
func normalizedEntryAppCode(ctx context.Context, value string) string {
if strings.TrimSpace(value) == "" {
return appcode.FromContext(ctx)
}
return appcode.Normalize(value)
}
func checkedMul(unit int64, count int64) (int64, error) {
if unit < 0 || count <= 0 {
return 0, xerr.New(xerr.InvalidArgument, "amount is invalid")
}
if unit != 0 && count > math.MaxInt64/unit {
return 0, xerr.New(xerr.InvalidArgument, "amount overflow")
}
return unit * count, nil
}
func checkedAdd(left int64, right int64) (int64, error) {
if right < 0 || left > math.MaxInt64-right {
return 0, xerr.New(xerr.CoinSellerStockAmountInvalid, "coin amount overflow")
}
return left + right, nil
}
func checkedAddDelta(left int64, right int64) (int64, error) {
if (right > 0 && left > math.MaxInt64-right) || (right < 0 && left < math.MinInt64-right) {
return 0, xerr.New(xerr.CoinSellerStockAmountInvalid, "coin amount overflow")
}
return left + right, nil
}
func stableHash(value string) string {
sum := sha256.Sum256([]byte(value))
return hex.EncodeToString(sum[:])
}
// boundedDerivedCommandID 为内部子动作保留可读前缀,同时保证最终键不超过所有
// command_id VARCHAR(128) 的共同边界。正常短键保持历史值,极长客户端键才稳定收敛为哈希。
func boundedDerivedCommandID(prefix string, commandID string) string {
commandID = strings.TrimSpace(commandID)
derived := prefix + commandID
if len(derived) <= 128 {
return derived
}
return prefix + stableHash(commandID)
}
func mustJSON(value any) string {
body, err := json.Marshal(value)
if err != nil {
return "{}"
}
return string(body)
}
func transactionID(appCode string, commandID string) string {
return "wtx_" + stableHash(appcode.Normalize(appCode)+"|"+commandID)
}
func coinSellerStockID(appCode string, commandID string) string {
return "cstock_" + stableHash(appcode.Normalize(appCode)+"|"+commandID)
}
func billingReceiptID(appCode string, commandID string) string {
return "bill_" + stableHash(appcode.Normalize(appCode)+"|"+commandID)
}
func eventID(transactionID string, eventType string, userID int64, assetType string) string {
return "wev_" + stableHash(fmt.Sprintf("%s|%s|%d|%s", transactionID, eventType, userID, assetType))
}
func isMySQLDuplicateError(err error) bool {
var mysqlErr *mysqlDriver.MySQLError
return errors.As(err, &mysqlErr) && mysqlErr.Number == 1062
}