package validator import ( "context" ) // contextKey 上下文键类型 type contextKey string const ( // 验证组 contextKeyGroups contextKey = "validator:groups" // 验证策略 contextKeyStrategy contextKey = "validator:strategy" // 语言 contextKeyLanguage contextKey = "validator:language" // 用户角色 contextKeyRoles contextKey = "validator:roles" // 是否管理员 contextKeyIsAdmin contextKey = "validator:is_admin" ) // ValidationContext 验证上下文 type ValidationContext struct { // 激活的验证组 Groups []string // 验证策略 Strategy *ValidationStrategy // 语言偏好 Language string // 用户角色 Roles []string // 是否管理员 IsAdmin bool // 自定义元数据 Metadata map[string]interface{} } // ValidationStrategy 验证策略 type ValidationStrategy struct { // 验证模式 Mode ValidationMode // 是否快速失败(遇到第一个错误就停止) FailFast bool // 是否收集警告 CollectWarnings bool // 最大错误数(超过后停止验证) MaxErrors int // 是否启用缓存 EnableCache bool } // ValidationMode 验证模式 type ValidationMode int const ( // 验证所有规则 ValidationModeAll ValidationMode = iota // 仅验证必填项 ValidationModeRequiredOnly // 仅验证修改的字段 ValidationModeChangedOnly // 自定义(根据组选择) ValidationModeCustom ) // NewContext 创建验证上下文 func NewContext() *ValidationContext { return &ValidationContext{ Groups: make([]string, 0), Metadata: make(map[string]interface{}), Strategy: DefaultStrategy(), } } // DefaultStrategy 默认验证策略 func DefaultStrategy() *ValidationStrategy { return &ValidationStrategy{ Mode: ValidationModeAll, FailFast: false, CollectWarnings: true, MaxErrors: 100, EnableCache: true, } } // WithGroups 设置验证组到上下文 func WithGroups(ctx context.Context, groups ...string) context.Context { return context.WithValue(ctx, contextKeyGroups, groups) } // GetGroups 从上下文获取验证组 func GetGroups(ctx context.Context) []string { if groups, ok := ctx.Value(contextKeyGroups).([]string); ok { return groups } return nil } // WithStrategy 设置验证策略到上下文 func WithStrategy(ctx context.Context, strategy *ValidationStrategy) context.Context { return context.WithValue(ctx, contextKeyStrategy, strategy) } // GetStrategy 从上下文获取验证策略 func GetStrategy(ctx context.Context) *ValidationStrategy { if strategy, ok := ctx.Value(contextKeyStrategy).(*ValidationStrategy); ok { return strategy } return DefaultStrategy() } // WithLanguage 设置语言到上下文 func WithLanguage(ctx context.Context, lang string) context.Context { return context.WithValue(ctx, contextKeyLanguage, lang) } // GetLanguage 从上下文获取语言 func GetLanguage(ctx context.Context) string { if lang, ok := ctx.Value(contextKeyLanguage).(string); ok { return lang } return "zh-CN" // 默认中文 } // WithRoles 设置用户角色到上下文 func WithRoles(ctx context.Context, roles ...string) context.Context { return context.WithValue(ctx, contextKeyRoles, roles) } // GetRoles 从上下文获取用户角色 func GetRoles(ctx context.Context) []string { if roles, ok := ctx.Value(contextKeyRoles).([]string); ok { return roles } return nil } // WithAdmin 设置管理员标志到上下文 func WithAdmin(ctx context.Context, isAdmin bool) context.Context { return context.WithValue(ctx, contextKeyIsAdmin, isAdmin) } // IsAdmin 从上下文判断是否管理员 func IsAdmin(ctx context.Context) bool { if isAdmin, ok := ctx.Value(contextKeyIsAdmin).(bool); ok { return isAdmin } return false } // FromContext 从上下文创建 ValidationContext func FromContext(ctx context.Context) *ValidationContext { vc := NewContext() vc.Groups = GetGroups(ctx) vc.Strategy = GetStrategy(ctx) vc.Language = GetLanguage(ctx) vc.Roles = GetRoles(ctx) vc.IsAdmin = IsAdmin(ctx) return vc } // HasGroup 检查是否包含指定组 func (vc *ValidationContext) HasGroup(group string) bool { if len(vc.Groups) == 0 { // 没有指定组时,默认验证所有规则 return true } for _, g := range vc.Groups { if g == group { return true } } return false } // HasAnyGroup 检查是否包含任一指定组 func (vc *ValidationContext) HasAnyGroup(groups []string) bool { if len(vc.Groups) == 0 { return true } if len(groups) == 0 { return true } for _, g := range groups { if vc.HasGroup(g) { return true } } return false } // ShouldFailFast 是否应该快速失败 func (vc *ValidationContext) ShouldFailFast() bool { return vc.Strategy != nil && vc.Strategy.FailFast } // ShouldCollectWarnings 是否应该收集警告 func (vc *ValidationContext) ShouldCollectWarnings() bool { return vc.Strategy == nil || vc.Strategy.CollectWarnings } // MaxErrorsReached 是否达到最大错误数 func (vc *ValidationContext) MaxErrorsReached(errorCount int) bool { if vc.Strategy == nil { return false } return vc.Strategy.MaxErrors > 0 && errorCount >= vc.Strategy.MaxErrors }