package models import ( "strings" "time" ) type UserRecord struct { Account string `json:"account"` PasswordHash string `json:"passwordHash"` Username string `json:"username"` Email string `json:"email"` Level int `json:"level"` SproutCoins int `json:"sproutCoins"` LastCheckInDate string `json:"lastCheckInDate,omitempty"` LastCheckInAt string `json:"lastCheckInAt,omitempty"` LastVisitDate string `json:"lastVisitDate,omitempty"` LastVisitAt string `json:"lastVisitAt,omitempty"` LastVisitIP string `json:"lastVisitIp,omitempty"` LastVisitDisplayLocation string `json:"lastVisitDisplayLocation,omitempty"` CheckInTimes []string `json:"checkInTimes,omitempty"` VisitTimes []string `json:"visitTimes,omitempty"` SecondaryEmails []string `json:"secondaryEmails,omitempty"` Phone string `json:"phone,omitempty"` AvatarURL string `json:"avatarUrl,omitempty"` WebsiteURL string `json:"websiteUrl,omitempty"` Bio string `json:"bio,omitempty"` CreatedAt string `json:"createdAt"` UpdatedAt string `json:"updatedAt"` Banned bool `json:"banned"` BanReason string `json:"banReason,omitempty"` BannedAt string `json:"bannedAt,omitempty"` AuthClients []AuthClientEntry `json:"authClients,omitempty"` } type UserPublic struct { Account string `json:"account"` Username string `json:"username"` Email string `json:"email"` Level int `json:"level"` SproutCoins int `json:"sproutCoins"` LastCheckInDate string `json:"lastCheckInDate,omitempty"` LastCheckInAt string `json:"lastCheckInAt,omitempty"` LastVisitDate string `json:"lastVisitDate,omitempty"` CheckInDays int `json:"checkInDays"` CheckInStreak int `json:"checkInStreak"` LastVisitAt string `json:"lastVisitAt,omitempty"` LastVisitIP string `json:"lastVisitIp,omitempty"` LastVisitDisplayLocation string `json:"lastVisitDisplayLocation,omitempty"` VisitDays int `json:"visitDays"` VisitStreak int `json:"visitStreak"` SecondaryEmails []string `json:"secondaryEmails,omitempty"` Phone string `json:"phone,omitempty"` AvatarURL string `json:"avatarUrl,omitempty"` WebsiteURL string `json:"websiteUrl,omitempty"` Bio string `json:"bio,omitempty"` CreatedAt string `json:"createdAt"` UpdatedAt string `json:"updatedAt"` Banned bool `json:"banned,omitempty"` BanReason string `json:"banReason,omitempty"` BannedAt string `json:"bannedAt,omitempty"` AuthClients []AuthClientEntry `json:"authClients,omitempty"` } func (u UserRecord) Public() UserPublic { checkInDays, checkInStreak, lastCheckInAt := ActivitySummary(u.CheckInTimes, u.LastCheckInDate) visitDays, visitStreak, lastVisitAt := ActivitySummary(u.VisitTimes, u.LastVisitDate) if strings.TrimSpace(u.LastCheckInAt) != "" { lastCheckInAt = u.LastCheckInAt } if strings.TrimSpace(u.LastVisitAt) != "" { lastVisitAt = u.LastVisitAt } return UserPublic{ Account: u.Account, Username: u.Username, Email: u.Email, Level: u.Level, SproutCoins: u.SproutCoins, LastCheckInDate: u.LastCheckInDate, LastCheckInAt: lastCheckInAt, LastVisitDate: u.LastVisitDate, CheckInDays: checkInDays, CheckInStreak: checkInStreak, LastVisitAt: lastVisitAt, VisitDays: visitDays, VisitStreak: visitStreak, SecondaryEmails: u.SecondaryEmails, Phone: u.Phone, AvatarURL: u.AvatarURL, WebsiteURL: u.WebsiteURL, Bio: u.Bio, CreatedAt: u.CreatedAt, UpdatedAt: u.UpdatedAt, } } // PublicProfile 在 Public 基础上附带最近访问 IP / 展示用地理位置,仅供「用户公开主页」接口使用。 func (u UserRecord) PublicProfile() UserPublic { p := u.Public() p.LastVisitIP = strings.TrimSpace(u.LastVisitIP) p.LastVisitDisplayLocation = strings.TrimSpace(u.LastVisitDisplayLocation) return p } // OwnerPublic 包含仅本人/管理员可见的字段(如最近访问 IP),勿用于公开资料接口。 func (u UserRecord) OwnerPublic() UserPublic { p := u.Public() p.LastVisitIP = strings.TrimSpace(u.LastVisitIP) p.LastVisitDisplayLocation = strings.TrimSpace(u.LastVisitDisplayLocation) p.Banned = u.Banned p.BanReason = strings.TrimSpace(u.BanReason) p.BannedAt = strings.TrimSpace(u.BannedAt) if len(u.AuthClients) > 0 { p.AuthClients = append([]AuthClientEntry(nil), u.AuthClients...) } return p } type UserShowcase struct { Account string `json:"account"` Username string `json:"username"` Level int `json:"level"` SproutCoins int `json:"sproutCoins"` AvatarURL string `json:"avatarUrl,omitempty"` WebsiteURL string `json:"websiteUrl,omitempty"` Bio string `json:"bio,omitempty"` } func (u UserRecord) Showcase() UserShowcase { return UserShowcase{ Account: u.Account, Username: u.Username, Level: u.Level, SproutCoins: u.SproutCoins, AvatarURL: u.AvatarURL, WebsiteURL: u.WebsiteURL, Bio: u.Bio, } } func NowISO() string { return time.Now().Format(time.RFC3339) }