package data import ( "time" "github.com/google/uuid" "gorm.io/gorm" "gorm.io/gorm/clause" ) type User struct { Id uint `json:"id" gorm:"primarykey;autoincrement"` UUID uuid.UUID `json:"uuid" gorm:"type:uuid;uniqueindex;not null"` UserId uuid.UUID `json:"user_id" gorm:"type:uuid;uniqueindex;not null"` Email string `json:"email" gorm:"type:varchar(255);uniqueindex;not null"` Type string `json:"type" gorm:"type:varchar(32);index;not null"` Nickname string `json:"nickname"` Subtitle string `json:"subtitle"` Avatar string `json:"avatar"` Checkin time.Time `json:"checkin" gorm:"index"` PermissionLevel uint `json:"permission_level" gorm:"default:10;not null"` } func (self *User) GetByEmail(email string) error { if err := Database.Where("email = ?", email).First(&self).Error; err != nil { return err } return nil } func (self *User) GetByUserId(userId uuid.UUID) error { if err := Database.Where("user_id = ?", userId).First(&self).Error; err != nil { return err } return nil } func (self *User) UpdateCheckin(userId uuid.UUID, time time.Time) error { return Database.Transaction(func(tx *gorm.DB) error { if err := tx. Clauses(clause.Locking{Strength: "UPDATE"}). Where("user_id = ?", userId). First(self).Error; err != nil { return err // if error then rollback } self.Checkin = time if err := tx.Save(self).Error; err != nil { return err // rollback } return nil // commit }) } func (self *User) Create() error { return Database.Transaction(func(tx *gorm.DB) error { if self.UUID == uuid.Nil { self.UUID = uuid.New() } if self.UserId == uuid.Nil { self.UserId = uuid.New() } if err := tx.Create(self).Error; err != nil { return err } return nil }) } type UserUpdateInput struct { Email *string Nickname *string Subtitle *string Avatar *string Type *string } func (self *User) UpdateByUserID(userID uuid.UUID, in *UserUpdateInput) error { return Database.Transaction(func(tx *gorm.DB) error { if err := tx. Where("user_id = ?", userID). First(self).Error; err != nil { return err } updates := map[string]any{} if in.Email != nil { updates["email"] = *in.Email } if in.Nickname != nil { updates["nickname"] = *in.Nickname } if in.Subtitle != nil { updates["subtitle"] = *in.Subtitle } if in.Avatar != nil { updates["avatar"] = *in.Avatar } if in.Type != nil { updates["type"] = *in.Type } if len(updates) == 0 { return nil } return tx.Model(self).Updates(updates).Error }) }