package model import ( "database/sql/driver" "time" ) // RuleJSON 存储 JSON 数组/对象的列(user_rules 的 trigger_conditions 等) type RuleJSON []byte // MarshalJSON 原样输出 JSON,避免 encoding/json 将 []byte 编成 base64 导致前端把 triggerConditions 当字符串而 .map 崩溃 func (r RuleJSON) MarshalJSON() ([]byte, error) { if len(r) == 0 { return []byte("null"), nil } out := make([]byte, len(r)) copy(out, r) return out, nil } // UnmarshalJSON 接收请求体中的原始 JSON(对象/数组) func (r *RuleJSON) UnmarshalJSON(data []byte) error { if r == nil { return nil } if len(data) == 0 || string(data) == "null" { *r = nil return nil } *r = append((*r)[0:0], data...) return nil } func (r RuleJSON) Value() (driver.Value, error) { return []byte(r), nil } func (r *RuleJSON) Scan(value interface{}) error { if value == nil { *r = nil return nil } b, ok := value.([]byte) if !ok { return nil } *r = append((*r)[0:0], b...) return nil } // UserRule 用户旅程触达规则(结构化触发条件 + 推送动作,由管理端配置) type UserRule struct { ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` Title string `gorm:"column:title;size:200;not null" json:"title"` Description string `gorm:"column:description;type:text" json:"description"` Trigger string `gorm:"column:trigger;size:100" json:"trigger"` TriggerConditions RuleJSON `gorm:"column:trigger_conditions;type:json" json:"triggerConditions,omitempty"` ActionType string `gorm:"column:action_type;size:50;default:'popup'" json:"actionType,omitempty"` ActionConfig RuleJSON `gorm:"column:action_config;type:json" json:"actionConfig,omitempty"` Sort int `gorm:"column:sort;default:0" json:"sort"` Enabled bool `gorm:"column:enabled;default:true" json:"enabled"` CreatedAt time.Time `gorm:"column:created_at" json:"createdAt"` UpdatedAt time.Time `gorm:"column:updated_at" json:"updatedAt"` } func (UserRule) TableName() string { return "user_rules" }