flipped-aurora/gin-vue-admin · error

用户名已注册

Error message

用户名已注册

What it means

Register in UserService throws "用户名已注册" when a First() query on username does NOT return gorm.ErrRecordNotFound, i.e. a user with that username already exists. It prevents duplicate accounts before hashing the password and creating the record.

Source

Thrown at server/service/system/sys_user.go:33

	"github.com/flipped-aurora/gin-vue-admin/server/utils/logger"
	"github.com/google/uuid"
	"gorm.io/gorm"
)

//@author: [piexlmax](https://github.com/piexlmax)
//@function: Register
//@description: 用户注册
//@param: u model.SysUser
//@return: userInter system.SysUser, err error

type UserService struct{}

var UserServiceApp = new(UserService)

func (userService *UserService) Register(ctx context.Context, u system.SysUser) (userInter system.SysUser, err error) {
	var user system.SysUser
	if !errors.Is(global.GVA_DB.WithContext(ctx).Where("username = ?", u.Username).First(&user).Error, gorm.ErrRecordNotFound) { // 判断用户名是否注册
		return userInter, errors.New("用户名已注册")
	}
	// 否则 附加uuid 密码hash加密 注册
	cfg := (&SecurityConfigService{}).Current(ctx)
	u.MustChangePassword = cfg.ForceNewUserChangePassword
	u.Password = utils.BcryptHash(u.Password)
	u.UUID = uuid.New()
	now := time.Now()
	u.PasswordUpdatedAt = &now
	err = global.GVA_DB.WithContext(ctx).Create(&u).Error
	return u, err
}

//@author: [piexlmax](https://github.com/piexlmax)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: Login
//@description: 用户登录
//@param: u *model.SysUser
//@return: err error, userInter *model.SysUser

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Choose a different username or instruct the user to log in instead of registering.
  2. Check the user table (including soft-deleted rows) for the conflicting name and clean up if appropriate.
  3. Trim/normalize the username client-side before submitting.
  4. Add a unique constraint on username as a backstop against registration races.

Example fix

// before
u.Username = rawForm.Username // " alice " vs existing "alice"

// after
u.Username = strings.TrimSpace(rawForm.Username)
if err := svc.Register(ctx, u); err != nil && strings.Contains(err.Error(), "用户名已注册") {
    return fmt.Errorf("该用户名已被占用,请直接登录或更换用户名")
}
Defensive patterns

Strategy: try-catch

Validate before calling

var existing system.SysUser
if err := db.Where("username = ?", username).First(&existing).Error; err == nil {
    return errors.New("username already taken; choose another or log in")
}

Try / catch

user, err := userService.Register(ctx, u)
if err != nil {
    if strings.Contains(err.Error(), "用户名已注册") {
        http.Error(w, "username already registered", http.StatusConflict)
        return
    }
    http.Error(w, err.Error(), http.StatusInternalServerError)
}

Prevention

When it happens

Trigger: Calling the register API with a username already present in sys_user; double-submitting a registration form; a soft-deleted user row still matching the unique username (if not excluded by GORM soft-delete).

Common situations: Users re-registering with an existing name; concurrent race where two requests pass the check nearly simultaneously; test fixtures leaving a user with the same name in the DB; username case/whitespace differences not normalized.

Related errors


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/e72e2ef196b20786. Report an issue: GitHub.