package service import ( "gadmin/config" "gadmin/internal/admin/consts" "gadmin/internal/admin/forms" "gadmin/internal/gorm/model" "gadmin/utility/serializer" "time" "golang.org/x/crypto/bcrypt" ) // User 管理员服务 var User = NewsUser() type LoginStats struct { FailNum int BanTs int64 } type sUser struct { BanIps map[string]*LoginStats } func NewsUser() *sUser { user := new(sUser) user.BanIps = make(map[string]*LoginStats) return user } // 一次登录,清空错误次数 func (s *sUser) AddSucessNum(ip string) { delete(s.BanIps, ip) } // 增加错误登录次数,超过10次,不再进行密码验证 func (s *sUser) AddFailNum(ip string) { stats, ok := s.BanIps[ip] if !ok { stats = new(LoginStats) s.BanIps[ip] = stats } if stats.BanTs > 0 { return } if stats.FailNum > 10 { curTs := time.Now().Unix() stats.BanTs = curTs // 清理错误登录 for k, v := range s.BanIps { if v.BanTs+24*60*60 < curTs { delete(s.BanIps, k) } } return } stats.FailNum += 1 } // 检查是否允许登录 func (s *sUser) CheckLoginAllow(ip string) bool { stats, ok := s.BanIps[ip] if !ok { return true } cur := time.Now().Unix() if stats.BanTs+1*60*60 > cur { return false } stats.BanTs = 0 stats.FailNum = 0 return true } // GetUser 用ID获取用户 func (s *sUser) GetUser(ID interface{}) (u *model.AdminUser, err error) { result := config.DB.First(&u, ID) return u, result.Error } // SetPassword 设置密码 func (s *sUser) SetPassword(password string) (string, error) { bytes, err := bcrypt.GenerateFromPassword([]byte(password), consts.PassWordCost) if err != nil { return "", err } return string(bytes), nil } // CheckPassword 校验密码 func (s *sUser) CheckPasswordRight(passwordDigest, password string) bool { err := bcrypt.CompareHashAndPassword([]byte(passwordDigest), []byte(password)) return err == nil } //func (s *sUser) Login(req forms.UserLoginReq, ip string) serializer.Response { // var ( // u model.AdminUser // ) // if ok := s.CheckLoginAllow(ip); !ok { // return serializer.ParamErr("账号已被禁止登录", nil) // } // // if err := config.AdminDB.Where("user_name = ?", req.UserName).First(&u).Error; err != nil { // s.AddFailNum(ip) // logrus.Warnf("sUser %v Login req error %v.", req.UserName, ip) // return serializer.ParamErr("账号错误或不存在,请检查", nil) // } // //p, _ := s.SetPassword(req.Password) // //fmt.Println("pass:", p) // // if u.Status != 1 { // return serializer.ParamErr("账号已被禁用", nil) // } // // if s.CheckPasswordRight(u.PasswordDigest, req.Password) == false { // s.AddFailNum(ip) // logrus.Warnf("sUser %v Login req error. ip: %v.", req.UserName, ip) // return serializer.ParamErr("密码不正确,如忘记了密码请联系管理员!", nil) // } // s.AddSucessNum(ip) // // //if os.Getenv("GIN_MODE") == "release" && u.UserName == "mojun" { // // return serializer.ParamErr("该账号只允许在测试服登录!", nil) // //} // // t := token.GenerateTokenUsingUUID() // // // 记录登录token // key := config.GetUserTokenKey(u.ID) // config.TokenRedis.HSet(key, t, time.Now().Unix()) // config.TokenRedis.Expire(key, config.TokenExpireTime) // // tokenKey := config.GetTokenKey(t) // user := &token.UserClaims{ // ID: u.ID, // UserName: u.UserName, // RoleId: int64(u.RoleID), // Avatar: u.Avatar, // Nickname: u.Nickname, // AccessToken: t, // } // userStr, err := jsoniter.MarshalToString(user) // if err != nil { // return serializer.Err(1, "", err) // } // config.TokenRedis.Set(tokenKey, userStr, config.TokenExpireTime) // // return serializer.Suc(forms.UserLoginRes{ // ID: u.ID, // UserName: u.UserName, // Nickname: u.Nickname, // Status: u.Status, // Avatar: u.Avatar, // Token: base64.URLEncoding.EncodeToString([]byte(t)), // }) // // //t, err := token.GenerateToken(&token.UserClaims{ // // ID: u.ID, // // UserName: u.UserName, // // RoleId: int64(u.RoleID), // // Avatar: u.Avatar, // // Nickname: u.Nickname, // //}) // //if err != nil { // // return serializer.ParamErr(err.Error(), nil) // //} // //return serializer.Suc(forms.UserLoginRes{ // // ID: u.ID, // // UserName: u.UserName, // // Nickname: u.Nickname, // // Status: u.Status, // // Avatar: u.Avatar, // // Token: t, // //}) //} func (s *sUser) Register(req forms.UserRegisterReq) serializer.Response { user := model.AdminUser{ Nickname: req.Nickname, UserName: req.UserName, Status: consts.StatusNormal, } count := int64(0) config.DB.Model(&model.AdminUser{}).Where("nickname = ?", req.Nickname).Count(&count) if count > 0 { return serializer.Response{ Code: 40001, Msg: "昵称被占用", } } config.DB.Model(&model.AdminUser{}).Where("user_name = ?", req.UserName).Count(&count) if count > 0 { return serializer.Response{ Code: 40001, Msg: "用户名已经注册", } } // 加密密码 password, err := s.SetPassword(req.Password) if err != nil { return serializer.Err( consts.CodeEncryptError, "密码加密失败", err, ) } user.PasswordDigest = password if err = config.DB.Create(&user).Error; err != nil { return serializer.ParamErr("注册失败", err) } user.PasswordDigest = "" return serializer.Suc(user) } //func (s *sUser) List(ctx *gin.Context, req forms.AdminUserListReq) serializer.Response { // var ( // q = query.Use(config.AdminDB).AdminUser // r = query.Use(config.AdminDB).AdminRole // m = q.WithContext(ctx) // offset int64 = 0 // models forms.UserAccountListRes // lists []*forms.AdminUserListModel // ) // // m = m.Order(q.ID.Desc()) // // req.Page, req.PerPage, offset = forms.CalculatePage(req.Page, req.PerPage) // // count, err := m.Count() // if err != nil { // return serializer.Err(consts.CodeParamErr, "查询出错 count", err) // } // // if count > 0 { // if err = m.Limit(int(req.PerPage)).Offset(int(offset)).Scan(&lists); err != nil { // return serializer.Err(consts.CodeParamErr, "查询出错 lists", err) // } // } // // for _, v := range lists { // role, err := r.WithContext(ctx).Where(r.ID.Eq(v.RoleID)).First() // v.RoleName = "未绑定角色" // if role != nil && err == nil { // v.RoleName = role.Name // } // } // // models.List = lists // models.Page = req.Page // models.PerPage = req.PerPage // models.PageCount = (count + req.PerPage - 1) / req.PerPage // // return serializer.Suc(models) //} //func (s *sUser) Edit(ctx *gin.Context, req forms.AdminUserEditReq) serializer.Response { // q := query.Use(config.AdminDB).AdminUser // // logrus.Warnf("sUser Edit req:%+v", req) // // if req.RoleID <= 0 { // return serializer.ParamErr("角色不能为空", nil) // } // // if req.UserName == "" { // return serializer.ParamErr("用户名不能为空", nil) // } // // // 修改 // if req.ID > 0 { // update := &model.AdminUser{ // UserName: req.UserName, // RoleID: int32(req.RoleID), // Nickname: req.Nickname, // Status: req.Status, // UpdatedAt: time.Now(), // } // _, err := q.WithContext(ctx).Where(q.ID.Eq(req.ID)).Updates(update) // if err != nil { // return serializer.Err(consts.CodeParamErr, "更新出错", err) // } // // 维护redis token // config.TokenRedis.Del(config.GetUserTokenKey(req.ID)) // return serializer.Suc(nil) // } // // if req.Password == "" { // return serializer.ParamErr("密码不能为空", nil) // } // // // 加密密码 // password, err := s.SetPassword(req.Password) // if err != nil { // return serializer.Err( // consts.CodeEncryptError, // "密码加密失败", // err, // ) // } // // // 新增 // create := &model.AdminUser{ // UserName: req.UserName, // RoleID: int32(req.RoleID), // Nickname: req.Nickname, // PasswordDigest: password, // Status: req.Status, // UpdatedAt: time.Now(), // CreatedAt: time.Now(), // } // // if err = query.Use(config.AdminDB).AdminUser.WithContext(ctx).Create(create); err != nil { // return serializer.DBErr(err.Error(), err) // } // // return serializer.Suc(nil) //} //func (s *sUser) ResetPassword(ctx *gin.Context, req forms.AdminUserResetPasswordReq) serializer.Response { // q := query.Use(config.AdminDB).AdminUser // // logrus.Warnf("sUser ResetPassword req:%+v", req) // // if req.ID <= 0 { // return serializer.ParamErr("用于ID不能为空", nil) // } // // if req.Password == "" { // return serializer.ParamErr("密码不能为空", nil) // } // // // 加密密码 // password, err := s.SetPassword(req.Password) // if err != nil { // return serializer.Err( // consts.CodeEncryptError, // "密码加密失败", // err, // ) // } // update := &model.AdminUser{ // PasswordDigest: password, // UpdatedAt: time.Now(), // } // // _, err = q.WithContext(ctx).Where(q.ID.Eq(req.ID)).Updates(update) // if err != nil { // return serializer.Err(consts.CodeParamErr, "更新出错", err) // } // // 维护redis token // config.TokenRedis.Del(config.GetUserTokenKey(req.ID)) // return serializer.Suc(nil) //} //func (s *sUser) UpdatePassword(ctx *gin.Context, req forms.AdminUserUpdatePasswordReq) serializer.Response { // q := query.Use(config.AdminDB).AdminUser // // logrus.Warnf("sUser UpdatePassword req:%+v", req) // // userId := token.GetUID(ctx) // if userId <= 0 { // return serializer.ParamErr("用户信息获取失败", nil) // } // // models, err := q.WithContext(ctx).Where(q.ID.Eq(userId)).First() // if err != nil { // return serializer.ParamErr(err.Error(), err) // } // // if models == nil { // return serializer.ParamErr("用户不存在", nil) // } // // if !s.CheckPasswordRight(models.PasswordDigest, req.OldPassword) { // return serializer.ParamErr("老密码不正确", nil) // } // // // 加密密码 // password, err := s.SetPassword(req.NewPassword) // if err != nil { // return serializer.Err( // consts.CodeEncryptError, // "密码加密失败", // err, // ) // } // update := &model.AdminUser{ // PasswordDigest: password, // UpdatedAt: time.Now(), // } // // _, err = q.WithContext(ctx).Where(q.ID.Eq(userId)).Updates(update) // if err != nil { // return serializer.Err(consts.CodeParamErr, "更新出错", err) // } // // // 修改token状态 // config.TokenRedis.Del(config.GetUserTokenKey(userId)) // // return serializer.Suc(nil) //} //func (s *sUser) GetUserInfo(c *gin.Context) (*model.AdminUser, error) { // q := query.Use(config.AdminDB).AdminUser // // userId := token.GetUID(c) // if userId <= 0 { // c.JSON(200, serializer.Err(consts.CodeNoPermission, "用户信息获取失败", nil)) // c.Abort() // } // // return q.WithContext(c).Where(q.ID.Eq(userId)).First() //} //func (s *sUser) GetUserRoleId(c *gin.Context) int64 { // info, err := s.GetUserInfo(c) // if err != nil { // return 0 // } // // if info == nil { // return 0 // } // // return int64(info.RoleID) //} //func (s *sUser) GetUserByUnionID(unionID string) (*model.AdminUser, error) { // q := query.Use(config.AdminDB).AdminUser // return q.Where(q.FeishuUnionID.Eq(unionID)).First() //}