113 lines
3.0 KiB
Go

package registerreward
import (
"context"
"fmt"
"strconv"
"strings"
"time"
"github.com/redis/go-redis/v9"
)
// parseRegisterRewardEvent 把 Redis Stream 消息解析成统一事件对象。
func parseRegisterRewardEvent(message redis.XMessage) (registerRewardEvent, error) {
eventID := strings.TrimSpace(toRegisterRewardString(message.Values["eventId"]))
if eventID == "" {
return registerRewardEvent{}, fmt.Errorf("eventId is required")
}
sysOrigin := strings.ToUpper(strings.TrimSpace(toRegisterRewardString(message.Values["sysOrigin"])))
if sysOrigin == "" {
return registerRewardEvent{}, fmt.Errorf("sysOrigin is required")
}
userID, err := toRegisterRewardInt64(message.Values["userId"])
if err != nil {
return registerRewardEvent{}, fmt.Errorf("invalid userId: %w", err)
}
if userID <= 0 {
return registerRewardEvent{}, fmt.Errorf("invalid userId")
}
countryID, _ := toRegisterRewardInt64(message.Values["countryId"])
return registerRewardEvent{
EventID: eventID,
SysOrigin: sysOrigin,
UserID: userID,
CountryID: countryID,
}, nil
}
// toRegisterRewardString 把 Stream 字段安全转换成字符串。
func toRegisterRewardString(value any) string {
switch typed := value.(type) {
case nil:
return ""
case string:
return typed
case []byte:
return string(typed)
default:
return fmt.Sprint(typed)
}
}
// toRegisterRewardInt64 把 Stream 字段安全转换成 int64。
func toRegisterRewardInt64(value any) (int64, error) {
switch typed := value.(type) {
case nil:
return 0, fmt.Errorf("value is nil")
case int64:
return typed, nil
case int32:
return int64(typed), nil
case int:
return int64(typed), nil
case uint64:
return int64(typed), nil
case float64:
return int64(typed), nil
case string:
return strconv.ParseInt(strings.TrimSpace(typed), 10, 64)
case []byte:
return strconv.ParseInt(strings.TrimSpace(string(typed)), 10, 64)
default:
return strconv.ParseInt(strings.TrimSpace(fmt.Sprint(typed)), 10, 64)
}
}
// isRegisterRewardTerminalStatus 判断该日志状态是否已经终态。
func isRegisterRewardTerminalStatus(status string) bool {
switch strings.ToUpper(strings.TrimSpace(status)) {
case registerRewardStatusSuccess, registerRewardStatusSkipped:
return true
default:
return false
}
}
// isRegisterRewardNoGroupErr 判断是否是消费者组不存在错误。
func isRegisterRewardNoGroupErr(err error) bool {
if err == nil {
return false
}
return strings.Contains(strings.ToUpper(err.Error()), "NOGROUP")
}
// truncateRegisterRewardMessage 截断错误信息,避免超出数据库字段长度。
func truncateRegisterRewardMessage(message string) string {
message = strings.TrimSpace(message)
if len(message) <= 255 {
return message
}
return message[:255]
}
// sleepWithContext 支持被上下文中断的休眠。
func sleepWithContext(ctx context.Context, duration time.Duration) {
timer := time.NewTimer(duration)
defer timer.Stop()
select {
case <-ctx.Done():
case <-timer.C:
}
}