From e12b5b26d6dbe1fe7d2e26ec0cbbf51f78aa20e4 Mon Sep 17 00:00:00 2001 From: yokowu <18836617@qq.com> Date: Thu, 24 Jul 2025 21:31:56 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=94=A8=E6=88=B7=E9=94=81=E5=AE=9A?= =?UTF-8?q?=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/domain/user.go | 2 +- backend/errcode/errcode.go | 1 + backend/errcode/locale.zh.toml | 3 +++ backend/internal/user/repo/user.go | 28 +++++++++++++++++--------- backend/internal/user/usecase/user.go | 29 +++++++++++++++++++++++---- 5 files changed, 48 insertions(+), 15 deletions(-) diff --git a/backend/domain/user.go b/backend/domain/user.go index e1f01b6..3940568 100644 --- a/backend/domain/user.go +++ b/backend/domain/user.go @@ -36,7 +36,7 @@ type UserUsecase interface { type UserRepo interface { List(ctx context.Context, page *web.Pagination) ([]*db.User, *db.PageInfo, error) - Update(ctx context.Context, id string, fn func(*db.User, *db.UserUpdateOne) error) (*db.User, error) + Update(ctx context.Context, id string, fn func(*db.Tx, *db.User, *db.UserUpdateOne) error) (*db.User, error) Delete(ctx context.Context, id string) error InitAdmin(ctx context.Context, username, password string) error CreateUser(ctx context.Context, user *db.User) (*db.User, error) diff --git a/backend/errcode/errcode.go b/backend/errcode/errcode.go index 9d168b7..ad72689 100644 --- a/backend/errcode/errcode.go +++ b/backend/errcode/errcode.go @@ -12,6 +12,7 @@ var LocalFS embed.FS var ( ErrPermission = web.NewBadRequestErr("err-permission") ErrUserNotFound = web.NewBadRequestErr("err-user-not-found") + ErrUserLock = web.NewBadRequestErr("err-user-lock") ErrPassword = web.NewBadRequestErr("err-password") ErrInviteCodeInvalid = web.NewBadRequestErr("err-invite-code-invalid") ErrEmailInvalid = web.NewBadRequestErr("err-email-invalid") diff --git a/backend/errcode/locale.zh.toml b/backend/errcode/locale.zh.toml index 536e37b..6dab11d 100644 --- a/backend/errcode/locale.zh.toml +++ b/backend/errcode/locale.zh.toml @@ -4,6 +4,9 @@ other = "无权操作" [err-user-not-found] other = "用户不存在" +[err-user-lock] +other = "用户已锁定" + [err-password] other = "密码错误" diff --git a/backend/internal/user/repo/user.go b/backend/internal/user/repo/user.go index 2d91ba0..03b515c 100644 --- a/backend/internal/user/repo/user.go +++ b/backend/internal/user/repo/user.go @@ -74,12 +74,14 @@ func (r *UserRepo) AdminByName(ctx context.Context, username string) (*db.Admin, } func (r *UserRepo) GetByName(ctx context.Context, username string) (*db.User, error) { - return r.db.User.Query().Where( - user.Or( - user.Username(username), - user.Email(username), - ), - ).Only(ctx) + return r.db.User.Query(). + Where( + user.Or( + user.Username(username), + user.Email(username), + ), + ). + Only(ctx) } func (r *UserRepo) ValidateInviteCode(ctx context.Context, code string) (*db.InviteCode, error) { @@ -167,12 +169,12 @@ func (r *UserRepo) CreateInviteCode(ctx context.Context, userID string, code str } func (r *UserRepo) AdminList(ctx context.Context, page *web.Pagination) ([]*db.Admin, *db.PageInfo, error) { - q := r.db.Admin.Query() + q := r.db.Admin.Query().Order(admin.ByCreatedAt(sql.OrderDesc())) return q.Page(ctx, page.Page, page.Size) } func (r *UserRepo) List(ctx context.Context, page *web.Pagination) ([]*db.User, *db.PageInfo, error) { - q := r.db.User.Query() + q := r.db.User.Query().Order(user.ByCreatedAt(sql.OrderDesc())) return q.Page(ctx, page.Page, page.Size) } @@ -241,7 +243,7 @@ func (r *UserRepo) UpdateSetting(ctx context.Context, fn func(*db.Setting, *db.S return res, err } -func (r *UserRepo) Update(ctx context.Context, id string, fn func(*db.User, *db.UserUpdateOne) error) (*db.User, error) { +func (r *UserRepo) Update(ctx context.Context, id string, fn func(*db.Tx, *db.User, *db.UserUpdateOne) error) (*db.User, error) { uid, err := uuid.Parse(id) if err != nil { return nil, err @@ -254,7 +256,7 @@ func (r *UserRepo) Update(ctx context.Context, id string, fn func(*db.User, *db. return err } up := tx.User.UpdateOneID(u.ID) - if err = fn(u, up); err != nil { + if err = fn(tx, u, up); err != nil { return err } return up.Exec(ctx) @@ -372,6 +374,9 @@ func (r *UserRepo) OAuthLogin(ctx context.Context, platform consts.UserPlatform, if err != nil { return nil, errcode.ErrNotInvited.Wrap(err) } + if ui.Edges.User.Status != consts.UserStatusActive { + return nil, errcode.ErrUserLock + } if ui.AvatarURL != req.AvatarURL { if err = entx.WithTx(ctx, r.db, func(tx *db.Tx) error { return r.updateAvatar(ctx, tx, ui, req.AvatarURL) @@ -409,6 +414,9 @@ func (r *UserRepo) SignUpOrIn(ctx context.Context, platform consts.UserPlatform, First(ctx) if err == nil { u = ui.Edges.User + if u.Status != consts.UserStatusActive { + return errcode.ErrUserLock + } if ui.AvatarURL != req.AvatarURL { if err = r.updateAvatar(ctx, tx, ui, req.AvatarURL); err != nil { return err diff --git a/backend/internal/user/usecase/user.go b/backend/internal/user/usecase/user.go index 69b5c4d..12035e7 100644 --- a/backend/internal/user/usecase/user.go +++ b/backend/internal/user/usecase/user.go @@ -19,6 +19,7 @@ import ( "github.com/chaitin/MonkeyCode/backend/config" "github.com/chaitin/MonkeyCode/backend/consts" "github.com/chaitin/MonkeyCode/backend/db" + "github.com/chaitin/MonkeyCode/backend/db/apikey" "github.com/chaitin/MonkeyCode/backend/domain" "github.com/chaitin/MonkeyCode/backend/ent/types" "github.com/chaitin/MonkeyCode/backend/errcode" @@ -206,6 +207,9 @@ func (u *UserUsecase) Login(ctx context.Context, req *domain.LoginReq) (*domain. if err != nil { return nil, errcode.ErrUserNotFound.Wrap(err) } + if user.Status != consts.UserStatusActive { + return nil, errcode.ErrUserLock + } if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password)); err != nil { return nil, errcode.ErrPassword.Wrap(err) } @@ -394,17 +398,34 @@ func (u *UserUsecase) UpdateSetting(ctx context.Context, req *domain.UpdateSetti return cvt.From(s, &domain.Setting{}), nil } +func (u *UserUsecase) cleanApiKey(ctx context.Context, tx *db.Tx, user *db.User) error { + if apikey, err := tx.ApiKey.Query().Where(apikey.UserID(user.ID)).First(ctx); err == nil { + if err := tx.ApiKey.DeleteOneID(apikey.ID).Exec(ctx); err != nil { + return err + } + rkey := "sk-" + apikey.Key + return u.redis.Del(ctx, rkey).Err() + + } + return nil +} + func (u *UserUsecase) Update(ctx context.Context, req *domain.UpdateUserReq) (*domain.User, error) { - user, err := u.repo.Update(ctx, req.ID, func(_ *db.User, u *db.UserUpdateOne) error { + user, err := u.repo.Update(ctx, req.ID, func(tx *db.Tx, old *db.User, up *db.UserUpdateOne) error { if req.Status != nil { - u.SetStatus(*req.Status) + if *req.Status == consts.UserStatusLocked { + if err := u.cleanApiKey(ctx, tx, old); err != nil { + return err + } + } + up.SetStatus(*req.Status) } if req.Password != nil { hash, err := bcrypt.GenerateFromPassword([]byte(*req.Password), bcrypt.DefaultCost) if err != nil { return err } - u.SetPassword(string(hash)) + up.SetPassword(string(hash)) } return nil }) @@ -613,7 +634,7 @@ func (u *UserUsecase) WithOAuthCallback(ctx context.Context, req *domain.OAuthCa } func (u *UserUsecase) ProfileUpdate(ctx context.Context, req *domain.ProfileUpdateReq) (*domain.User, error) { - user, err := u.repo.Update(ctx, req.UID, func(old *db.User, uuo *db.UserUpdateOne) error { + user, err := u.repo.Update(ctx, req.UID, func(_ *db.Tx, old *db.User, uuo *db.UserUpdateOne) error { if req.Avatar != nil { uuo.SetAvatarURL(*req.Avatar) }