Files
honoka-chan/internal/model/user/userpref.go
T
YumeMichi 947da92a66 webui: Add user birthday settings
- Store birth month and day in user_pref with default 10/18
- Migrate existing user_pref rows to fill missing birthday fields
- Expose birthday editing in the webui profile page
- Replace hardcoded birthday values in user info, top info, and product list responses
- Fix birthday month/day field alignment in the profile form

Signed-off-by: Sean Du <do4suki@gmail.com>
2026-06-05 05:48:36 +08:00

164 lines
4.1 KiB
Go

package usermodel
import (
"strconv"
"strings"
"time"
)
const CurrentUserPrefProfileVersion = 2
const (
DefaultAutoUserName = "音乃木坂学生"
DefaultAutoUserDesc = "你好。"
DefaultUserLevel = 1028
DefaultUserExp = 1089696
DefaultUserNextExp = 1207185
DefaultUserGameCoin = 112124104
DefaultUserSnsCoin = 10000
DefaultUserEnergyMax = 417
DefaultUserOverMaxEnergy = 0
DefaultBirthMonth = 10
DefaultBirthDay = 18
)
type UserPref struct {
ID int `xorm:"id pk autoincr"`
UserID int `xorm:"user_id"`
AwardID int `xorm:"award_id"`
BackgroundID int `xorm:"background_id"`
UnitOwningUserID int `xorm:"unit_owning_user_id"`
UserName string `xorm:"user_name"`
UserLevel int `xorm:"user_level"`
UserDesc string `xorm:"user_desc"`
InviteCode string `xorm:"invite_code"`
UserExp int `xorm:"user_exp"`
NextExp int `xorm:"next_exp"`
GameCoin int `xorm:"game_coin"`
SnsCoin int `xorm:"sns_coin"`
EnergyMax int `xorm:"energy_max"`
OverMaxEnergy int `xorm:"over_max_energy"`
BirthMonth int `xorm:"birth_month"`
BirthDay int `xorm:"birth_day"`
ProfileVersion int `xorm:"profile_version"`
UpdateTime int64 `xorm:"update_time"`
}
func (u *UserPref) ApplyProfileDefaults() {
if u.UserLevel <= 0 {
u.UserLevel = DefaultUserLevel
}
if strings.TrimSpace(u.InviteCode) == "" && u.UserID > 0 {
u.InviteCode = strconv.Itoa(u.UserID)
}
if u.UserExp < 0 || u.UserExp == 0 {
u.UserExp = DefaultUserExp
}
if u.NextExp < 0 || u.NextExp == 0 {
u.NextExp = DefaultUserNextExp
}
if u.GameCoin < 0 || u.GameCoin == 0 {
u.GameCoin = DefaultUserGameCoin
}
if u.SnsCoin < 0 || u.SnsCoin == 0 {
u.SnsCoin = DefaultUserSnsCoin
}
if u.EnergyMax <= 0 {
u.EnergyMax = DefaultUserEnergyMax
}
if u.OverMaxEnergy < 0 {
u.OverMaxEnergy = DefaultUserOverMaxEnergy
}
if !IsValidBirthDate(u.BirthMonth, u.BirthDay) {
u.BirthMonth = DefaultBirthMonth
u.BirthDay = DefaultBirthDay
}
u.ProfileVersion = CurrentUserPrefProfileVersion
}
func (u *UserPref) ResetProfileDefaults() {
u.UserName = DefaultAutoUserName
u.UserDesc = DefaultAutoUserDesc
u.UserLevel = DefaultUserLevel
u.UserExp = DefaultUserExp
u.NextExp = DefaultUserNextExp
u.GameCoin = DefaultUserGameCoin
u.SnsCoin = DefaultUserSnsCoin
u.EnergyMax = DefaultUserEnergyMax
u.OverMaxEnergy = DefaultUserOverMaxEnergy
u.BirthMonth = DefaultBirthMonth
u.BirthDay = DefaultBirthDay
if u.UserID > 0 {
u.InviteCode = strconv.Itoa(u.UserID)
}
u.ProfileVersion = CurrentUserPrefProfileVersion
}
func (u UserPref) NeedsProfileMigration() bool {
return u.ProfileVersion < CurrentUserPrefProfileVersion
}
func (u UserPref) EffectiveEnergyMax() int {
if u.EnergyMax > 0 {
return u.EnergyMax
}
return DefaultUserEnergyMax
}
func (u UserPref) EffectiveCurrentEnergy() int {
if u.OverMaxEnergy > 0 {
return u.OverMaxEnergy
}
return u.EffectiveEnergyMax()
}
func (u UserPref) EffectiveBirthMonth() int {
if IsValidBirthDate(u.BirthMonth, u.BirthDay) {
return u.BirthMonth
}
return DefaultBirthMonth
}
func (u UserPref) EffectiveBirthDay() int {
if IsValidBirthDate(u.BirthMonth, u.BirthDay) {
return u.BirthDay
}
return DefaultBirthDay
}
func (u UserPref) HasBirthDate() bool {
return IsValidBirthDate(u.BirthMonth, u.BirthDay)
}
func (u UserPref) IsBirthdayToday(now time.Time) bool {
return int(now.Month()) == u.EffectiveBirthMonth() && now.Day() == u.EffectiveBirthDay()
}
func IsValidBirthDate(month, day int) bool {
if month < 1 || month > 12 || day < 1 {
return false
}
maxDay := time.Date(2000, time.Month(month)+1, 0, 0, 0, 0, 0, time.UTC).Day()
return day <= maxDay
}
func UserPrefProfileColumns() []string {
return []string{
"user_level",
"invite_code",
"user_exp",
"next_exp",
"game_coin",
"sns_coin",
"energy_max",
"over_max_energy",
"birth_month",
"birth_day",
"profile_version",
}
}
func (UserPref) TableName() string {
return "user_pref"
}