diff --git a/internal/apps/oauth/utils.go b/internal/apps/oauth/utils.go index 592ff0c..eaf4463 100644 --- a/internal/apps/oauth/utils.go +++ b/internal/apps/oauth/utils.go @@ -28,12 +28,15 @@ import ( "context" "encoding/json" "errors" + "fmt" + "io" + "time" + + "github.com/google/uuid" "github.com/hibiken/asynq" "github.com/linux-do/cdk/internal/logger" "github.com/linux-do/cdk/internal/task" "github.com/linux-do/cdk/internal/task/schedule" - "io" - "time" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" @@ -112,7 +115,7 @@ func doOAuth(ctx context.Context, code string) (*User, error) { // save to db var user User - tx := db.DB(ctx).Where("id = ?", userInfo.Id).First(&user) + tx := db.DB(ctx).Where("username = ?", userInfo.Username).First(&user) if tx.Error != nil { // create user if errors.Is(tx.Error, gorm.ErrRecordNotFound) { @@ -130,7 +133,6 @@ func doOAuth(ctx context.Context, code string) (*User, error) { span.SetStatus(codes.Error, tx.Error.Error()) return nil, tx.Error } - // 为新注册用户下发计算徽章分数的任务 payload, _ := json.Marshal(map[string]interface{}{ "user_id": user.ID, }) @@ -146,22 +148,60 @@ func doOAuth(ctx context.Context, code string) (*User, error) { return nil, tx.Error } } else { - if !user.IsActive { - err = errors.New(BannedAccount) - span.SetStatus(codes.Error, err.Error()) - return nil, err - } - // update user - user.Username = userInfo.Username - user.Nickname = userInfo.Name - user.AvatarUrl = userInfo.AvatarUrl - user.IsActive = userInfo.Active - user.TrustLevel = userInfo.TrustLevel - user.LastLoginAt = time.Now() - tx = db.DB(ctx).Save(&user) - if tx.Error != nil { - span.SetStatus(codes.Error, tx.Error.Error()) - return nil, tx.Error + if user.ID != userInfo.Id { + err = db.DB(ctx).Transaction(func(tx *gorm.DB) error { + oldUsername := fmt.Sprintf("%s已注销: %s", user.Username, uuid.NewString()) + if errUpdate := tx.Model(&user).Updates(map[string]interface{}{ + "username": oldUsername, + "is_active": false, + }).Error; errUpdate != nil { + return errUpdate + } + // create user + user = User{ + ID: userInfo.Id, + Username: userInfo.Username, + Nickname: userInfo.Name, + AvatarUrl: userInfo.AvatarUrl, + IsActive: userInfo.Active, + TrustLevel: userInfo.TrustLevel, + LastLoginAt: time.Now(), + } + if errCreate := tx.Create(&user).Error; errCreate != nil { + return errCreate + } + return nil + }) + if err != nil { + span.SetStatus(codes.Error, err.Error()) + return nil, err + } + payload, _ := json.Marshal(map[string]interface{}{ + "user_id": user.ID, + }) + if _, errTask := schedule.AsynqClient.Enqueue(asynq.NewTask(task.UpdateSingleUserBadgeScoreTask, payload)); errTask != nil { + logger.ErrorF(ctx, "下发用户[%s]徽章分数计算任务失败: %v", user.Username, errTask) + } else { + logger.InfoF(ctx, "下发用户[%s]徽章分数计算任务成功", user.Username) + } + } else { + if !user.IsActive { + err = errors.New(BannedAccount) + span.SetStatus(codes.Error, err.Error()) + return nil, err + } + // update user + user.Username = userInfo.Username + user.Nickname = userInfo.Name + user.AvatarUrl = userInfo.AvatarUrl + user.IsActive = userInfo.Active + user.TrustLevel = userInfo.TrustLevel + user.LastLoginAt = time.Now() + tx = db.DB(ctx).Save(&user) + if tx.Error != nil { + span.SetStatus(codes.Error, tx.Error.Error()) + return nil, tx.Error + } } } return &user, nil