package domain import ( "database/sql/driver" "encoding/json" "time" ) // SocialAccount models a persisted OAuth binding. type SocialAccount struct { ID int64 `gorm:"primaryKey;autoIncrement" json:"id"` UserID int64 `gorm:"index;not null" json:"user_id"` Provider string `gorm:"type:varchar(50);not null" json:"provider"` OpenID string `gorm:"type:varchar(100);not null" json:"open_id"` UnionID string `gorm:"type:varchar(100)" json:"union_id,omitempty"` Nickname string `gorm:"type:varchar(100)" json:"nickname"` Avatar string `gorm:"type:varchar(500)" json:"avatar"` Gender string `gorm:"type:varchar(10)" json:"gender,omitempty"` Email string `gorm:"type:varchar(100)" json:"email,omitempty"` Phone string `gorm:"type:varchar(20)" json:"phone,omitempty"` Extra ExtraData `gorm:"type:text" json:"extra,omitempty"` Status SocialAccountStatus `gorm:"default:1" json:"status"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } func (SocialAccount) TableName() string { return "user_social_accounts" } type SocialAccountStatus int const ( SocialAccountStatusActive SocialAccountStatus = 1 SocialAccountStatusInactive SocialAccountStatus = 0 SocialAccountStatusDisabled SocialAccountStatus = 2 ) type ExtraData map[string]interface{} func (e ExtraData) Value() (driver.Value, error) { if e == nil { return nil, nil } return json.Marshal(e) } func (e *ExtraData) Scan(value interface{}) error { if value == nil { *e = nil return nil } bytes, ok := value.([]byte) if !ok { return nil } return json.Unmarshal(bytes, e) } type SocialAccountInfo struct { ID int64 `json:"id"` Provider string `json:"provider"` Nickname string `json:"nickname"` Avatar string `json:"avatar"` Status SocialAccountStatus `json:"status"` CreatedAt time.Time `json:"created_at"` } func (s *SocialAccount) ToInfo() *SocialAccountInfo { return &SocialAccountInfo{ ID: s.ID, Provider: s.Provider, Nickname: s.Nickname, Avatar: s.Avatar, Status: s.Status, CreatedAt: s.CreatedAt, } }