diff --git a/data/user.go b/data/user.go index d0c084d..46d6a0d 100644 --- a/data/user.go +++ b/data/user.go @@ -4,18 +4,21 @@ 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"` + 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:0;not null"` } func (self *User) GetByEmail(email string) error { @@ -32,11 +35,80 @@ func (self *User) GetByUserId(userId uuid.UUID) error { return nil } -func (self *User) SetCheckinState(userId uuid.UUID, time time.Time) error { - if err := Database.Where("user_id = ?", userId).First(&self).Error; err != nil { - return err - } - self.Checkin = time - Database.Save(&self) - 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 + }) } diff --git a/service/checkin/checkin.go b/service/checkin/checkin.go index 207e927..e7d7c35 100644 --- a/service/checkin/checkin.go +++ b/service/checkin/checkin.go @@ -18,7 +18,7 @@ func Checkin(ctx *gin.Context) { }) return } - data.SetCheckinState(userId.(uuid.UUID), time.Now()) + data.UpdateCheckin(userId.(uuid.UUID), time.Now()) ctx.JSON(http.StatusOK, gin.H{ "status": "success", }) diff --git a/service/user/userinfo.go b/service/user/userinfo.go index e5ef147..9a810fd 100644 --- a/service/user/userinfo.go +++ b/service/user/userinfo.go @@ -29,12 +29,13 @@ func UserInfo(c *gin.Context) { checkinTime = data.Checkin } c.JSON(http.StatusOK, gin.H{ - "user_id": data.UserId, - "email": data.Email, - "type": data.Type, - "nickname": data.Nickname, - "subtitle": data.Subtitle, - "avatar": data.Avatar, - "checkin": checkinTime, + "user_id": data.UserId, + "email": data.Email, + "type": data.Type, + "nickname": data.Nickname, + "subtitle": data.Subtitle, + "avatar": data.Avatar, + "checkin": checkinTime, + "permission_level": data.PermissionLevel, }) }