package user import ( "context" "server/internal/dao" "server/internal/model" "server/internal/model/do" "server/internal/model/entity" "server/internal/service" "server/utility/ecode" "server/utility/encrypt" "server/utility/jwt" "strings" "github.com/gogf/gf/v2/database/gdb" ) type sUser struct{} func New() service.IUser { return &sUser{} } func init() { service.RegisterUser(New()) } func (s *sUser) Login(ctx context.Context, in *model.UserLoginIn) (out *model.UserLoginOut, err error) { user, err := dao.Users.Ctx(ctx).Where(do.Users{Email: in.Email}).One() if err != nil { return nil, ecode.Fail.Sub("database_query_failed") } if user == nil { return nil, ecode.Auth // 账户名或密码不正确 } var entityUser entity.Users if err = user.Struct(&entityUser); err != nil { return nil, ecode.Fail.Sub("data_conversion_failed") } if !encrypt.ComparePassword(entityUser.PasswordHash, in.Password) { return nil, ecode.Password // 密码不正确 } // 判断是否为作者 author, _ := dao.Authors.Ctx(ctx).Where(do.Authors{UserId: entityUser.Id, Status: 1}).One() role := "user" if author != nil && !author.IsEmpty() { role = "author" } token, err := jwt.GenerateToken(&jwt.TokenIn{UserId: entityUser.Id, Role: role}) if err != nil { return nil, ecode.Fail.Sub("token_generation_failed") } return &model.UserLoginOut{Token: token}, nil } func (s *sUser) Register(ctx context.Context, in *model.UserRegisterIn) (out *model.UserRegisterOut, err error) { if in.Password != in.Password2 { return nil, ecode.Password.Sub("password_mismatch") } exist, err := dao.Users.Ctx(ctx).Where(do.Users{Email: in.Email}).Count() if err != nil { return nil, ecode.Fail.Sub("database_query_failed") } if exist > 0 { return nil, ecode.EmailExist // 该邮箱已被注册 } hash, err := encrypt.EncryptPassword(in.Password) if err != nil { return nil, ecode.Fail.Sub("password_encryption_failed") } _, err = dao.Users.Ctx(ctx).Data(do.Users{ Email: in.Email, PasswordHash: hash, Username: strings.Split(in.Email, "@")[0], }).Insert() if err != nil { return nil, ecode.Fail.Sub("registration_failed") } return &model.UserRegisterOut{Success: true}, nil } func (s *sUser) Info(ctx context.Context, in *model.UserInfoIn) (out *model.UserInfoOut, err error) { user, err := dao.Users.Ctx(ctx).Where(do.Users{Id: in.UserId}).One() if err != nil { return nil, ecode.Fail.Sub("database_query_failed") } if user == nil { return nil, ecode.Auth.Sub("user_not_found") } var entityUser entity.Users if err = user.Struct(&entityUser); err != nil { return nil, ecode.Fail.Sub("data_conversion_failed") } return &model.UserInfoOut{ UserId: entityUser.Id, Username: entityUser.Username, Email: entityUser.Email, Avatar: entityUser.Avatar, Points: entityUser.Points, // 如有积分表可补充 }, nil } func (s *sUser) Delete(ctx context.Context, in *model.UserDeleteIn) (out *model.UserDeleteOut, err error) { // 查询用户信息 user, err := dao.Users.Ctx(ctx).Where(do.Users{Id: in.UserId}).One() if err != nil { return nil, ecode.Fail.Sub("database_query_failed") } if user == nil { return nil, ecode.Auth.Sub("user_not_found") } var entityUser entity.Users if err = user.Struct(&entityUser); err != nil { return nil, ecode.Fail.Sub("data_conversion_failed") } // 验证密码 if !encrypt.ComparePassword(entityUser.PasswordHash, in.Password) { return nil, ecode.Password.Sub("password_incorrect") } // 开启事务,删除用户及相关数据 err = dao.Users.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { // 1. 删除用户阅读记录 _, err := dao.UserReadRecords.Ctx(ctx).TX(tx). Where(dao.UserReadRecords.Columns().UserId, in.UserId). Delete() if err != nil { return ecode.Fail.Sub("read_record_delete_failed") } // 2. 删除用户阅读历史 _, err = dao.UserReadHistory.Ctx(ctx).TX(tx). Where(dao.UserReadHistory.Columns().UserId, in.UserId). Delete() if err != nil { return ecode.Fail.Sub("history_delete_failed") } // 3. 删除用户书架 _, err = dao.Bookshelves.Ctx(ctx).TX(tx). Where(dao.Bookshelves.Columns().UserId, in.UserId). Delete() if err != nil { return ecode.Fail.Sub("bookshelf_delete_failed") } // 4. 删除用户关注作者记录 _, err = dao.UserFollowAuthors.Ctx(ctx).TX(tx). Where(dao.UserFollowAuthors.Columns().UserId, in.UserId). Delete() if err != nil { return ecode.Fail.Sub("follow_author_delete_failed") } // 5. 删除用户评分记录 _, err = dao.BookRatings.Ctx(ctx).TX(tx). Where(dao.BookRatings.Columns().UserId, in.UserId). Delete() if err != nil { return ecode.Fail.Sub("rating_delete_failed") } // 6. 删除用户章节购买记录 _, err = dao.UserChapterPurchases.Ctx(ctx).TX(tx). Where(dao.UserChapterPurchases.Columns().UserId, in.UserId). Delete() if err != nil { return ecode.Fail.Sub("purchase_delete_failed") } // 7. 删除用户积分日志 _, err = dao.UserPointsLogs.Ctx(ctx).TX(tx). Where(dao.UserPointsLogs.Columns().UserId, in.UserId). Delete() if err != nil { return ecode.Fail.Sub("points_log_delete_failed") } // 8. 删除用户反馈 _, err = dao.Feedbacks.Ctx(ctx).TX(tx). Where(dao.Feedbacks.Columns().UserId, in.UserId). Delete() if err != nil { return ecode.Fail.Sub("feedback_delete_failed") } // 9. 删除作者信息(如果用户是作者) _, err = dao.Authors.Ctx(ctx).TX(tx). Where(dao.Authors.Columns().UserId, in.UserId). Delete() if err != nil { return ecode.Fail.Sub("author_delete_failed") } // 10. 最后删除用户(软删除) _, err = dao.Users.Ctx(ctx).TX(tx).Where(do.Users{Id: in.UserId}).Delete() if err != nil { return ecode.Fail.Sub("user_delete_failed") } return nil }) if err != nil { return nil, err } return &model.UserDeleteOut{Success: true}, nil } func (s *sUser) Code(ctx context.Context, in *model.UserCodeIn) (out *model.UserCodeOut, err error) { exist, err := dao.Users.Ctx(ctx).Where(do.Users{Email: in.Email}).Exist() if err != nil { return nil, ecode.Fail.Sub("database_query_failed") } if !exist { return nil, ecode.Params.Sub("email_not_found") } return &model.UserCodeOut{Success: true}, nil } func (s *sUser) EditPass(ctx context.Context, in *model.UserEditPassIn) (out *model.UserEditPassOut, err error) { exist, err := dao.Users.Ctx(ctx).Where(do.Users{Email: in.Email}).Exist() if err != nil { return nil, ecode.Fail.Sub("database_query_failed") } if !exist { return nil, ecode.Params.Sub("email_not_found") } if in.Sign != "123456" { return nil, ecode.Params.Sub("sign_error") } if in.Password != in.Password2 { return nil, ecode.Password.Sub("password_mismatch") } hash, err := encrypt.EncryptPassword(in.Password) if err != nil { return nil, ecode.Fail.Sub("password_encryption_failed") } _, err = dao.Users.Ctx(ctx).Where(do.Users{Email: in.Email}).Data(do.Users{PasswordHash: hash}).Update() if err != nil { return nil, ecode.Fail.Sub("password_update_failed") } return &model.UserEditPassOut{ Success: true, }, nil }