package v1 import ( "aps_crm/conf" "aps_crm/constvar" "aps_crm/model" "aps_crm/model/request" "aps_crm/model/response" "aps_crm/pkg/contextx" "aps_crm/pkg/ecode" "aps_crm/pkg/encrypt" "aps_crm/pkg/logx" "aps_crm/pkg/snowflake" "aps_crm/utils" "fmt" "github.com/gin-gonic/gin" "github.com/go-redis/redis/v8" "github.com/mojocn/base64Captcha" ) // 当开启多服务器部署时,替换下面的配置,使用redis共享存储验证码 // var store = captcha.NewDefaultRedisStore() var store = base64Captcha.DefaultMemStore // Login // // @Tags Base // @Summary 用户登录 // @Produce application/json // @Param object body request.Login true "查询参数" // @Success 200 {object} contextx.Response{data=response.LoginResponse} "成功" // @Router /api/base/login [post] func (slf *BaseApi) Login(c *gin.Context) { var params request.Login ctx, ok := contextx.NewContext(c, ¶ms) if !ok { return } // 判断验证码是否开启 key := c.ClientIP() //openCaptcha := conf.Conf.Captcha.OpenCaptcha // 是否开启防暴次数 //openCaptchaTimeOut := conf.Conf.Captcha.OpenCaptchaTimeOut // 缓存超时时间 //v, ok := constvar.BlackCache.Get(key) //if !ok { // constvar.BlackCache.Set(key, 1, time.Second*time.Duration(openCaptchaTimeOut)) //} //var oc = openCaptcha == 0 || convertx.InterfaceToInt(v) > openCaptcha // 0 表示每次登录都需要验证码 或者当前次数已超过防暴次数 //if !oc || store.Verify(params.CaptchaId, params.Captcha, true) { u := &model.User{Username: params.Username, Password: params.Password} user, errCode := userService.Login(u) if errCode != ecode.OK { logx.Errorf("登陆失败! 用户名不存在或者密码错误! errCode:%v", errCode) // 验证码次数+1 _ = constvar.BlackCache.Increment(key, 1) ctx.Fail(errCode) return } // 赋值菜单ID列表 //user.MenuIds, _ = menuService.GetUserMenuIds(user.UUID, user.UserType) slf.TokenNext(ctx, *user) return //} // 验证码次数+1 //_ = constvar.BlackCache.Increment(key, 1) //ctx.Fail(ecode.CaptchaErr) } // TokenNext 登录以后签发jwt func (slf *BaseApi) TokenNext(ctx *contextx.Context, user model.User) { logx.Infof("TokenNext user:%+v", user) j := &utils.JWT{SigningKey: []byte(conf.Conf.JWT.SigningKey)} // 唯一签名 claims := j.CreateClaims(request.BaseClaims{ UserId: user.UUID, Username: user.Username, UserType: user.UserType, AuthorityId: user.AuthorityId, }) token, err := j.CreateToken(claims) if err != nil { logx.Errorf("创建token失败! err:%v", err) ctx.Fail(ecode.CreateTokenErr) return } if !conf.Conf.System.UseMultipoint { // 不允许多点登录 ctx.OkWithDetailed(response.LoginResponse{ User: user, Token: token, //ExpiresAt: claims.StandardClaims.ExpiresAt * 1000, }) return } if jwtStr, err := jwtService.GetRedisJWT(user.Username); err == redis.Nil { // redis无JWT数据 if err := jwtService.SetRedisJWT(token, user.Username); err != nil { logx.Errorf("设置登录状态失败! err:%v", err) ctx.Fail(ecode.RedisErr) return } ctx.OkWithDetailed(response.LoginResponse{ User: user, Token: token, //ExpiresAt: claims.StandardClaims.ExpiresAt * 1000, }) } else if err != nil { // redis获取JWT报错 logx.Errorf("设置登录状态失败! err:%v", err) ctx.Fail(ecode.RedisErr) } else { // 成功获取redis的JWT,旧的作废 var blackJWT model.JwtBlacklist blackJWT.Jwt = jwtStr if err := jwtService.JsonInBlacklist(blackJWT); err != nil { ctx.Fail(ecode.DBErr) return } if err := jwtService.SetRedisJWT(token, user.Username); err != nil { ctx.Fail(ecode.RedisErr) return } ctx.OkWithDetailed(response.LoginResponse{ User: user, Token: token, //ExpiresAt: claims.StandardClaims.ExpiresAt * 1000, }) } } // Register // // @Tags User // @Summary 注册账号 // @Produce application/json // @Param object body request.Register true "查询参数" // @Success 200 {object} contextx.Response{data=response.UserResponse} "成功" // @Router /api/user/register [post] func (slf *BaseApi) Register(c *gin.Context) { var params request.Register ctx, ok := contextx.NewContext(c, ¶ms) if !ok { return } userInfo := utils.GetUserInfo(c) if len(userInfo.UserId) <= 0 { ctx.Fail(ecode.UnknownErr) return } if len(params.Username) == 0 || len(params.Password) == 0 || len(params.NickName) == 0 || params.AuthorityId == 0 || len(params.RePassword) == 0 || params.DepartmentId == 0 { ctx.Fail(ecode.ParamsErr) return } var userId = fmt.Sprintf("u%v", snowflake.GenerateId()) var passWord = encrypt.BcryptHash(params.Password) var userType constvar.UserType user := &model.User{UUID: userId, Username: params.Username, UserType: userType, NickName: params.NickName, Password: passWord, HeaderImg: params.HeaderImg, Phone: params.Phone, Email: params.Email, DepartmentId: params.DepartmentId, AuthorityId: params.AuthorityId} userReturn, errCode := userService.Register(user) if errCode != ecode.OK { ctx.Fail(errCode) return } //if user.UserType == constvar.UserTypePrimary { // 主账户创建对应的数据库用户和排程数据库 // err := model.NewMysql().CreateDatabase(user.Username) // if err != nil { // ctx.Fail(ecode.CreateDatabaseErr) // return // } // // defaultPwd := fmt.Sprintf("%v@Basic2023", user.Username) // err = model.NewMysql().CreateUser(user.Username, defaultPwd, user.Username) // if err != nil { // ctx.Fail(ecode.CreateDatabaseUserErr) // return // } //} ctx.OkWithDetailed(response.UserResponse{User: *userReturn}) } // ChangePassword // // @Tags User // @Summary 用户修改密码 // @Produce application/json // @Param object body request.ChangePasswordReq true "查询参数" // @Success 200 {object} contextx.Response{} "成功" // @Router /api/user/changePassword [post] func (slf *BaseApi) ChangePassword(c *gin.Context) { var params request.ChangePasswordReq ctx, ok := contextx.NewContext(c, ¶ms) if !ok { return } u := &model.User{UUID: utils.GetUserID(c), Password: params.Password} _, errCode := userService.ChangePassword(u, params.NewPassword) if errCode != ecode.OK { ctx.Fail(errCode) return } ctx.Ok() } // GetUserList // // @Tags User // @Summary 分页获取用户列表(不传分页参数,获取全部) // @Produce application/json // @Param object body request.GetUserList true "查询参数" // @Success 200 {object} contextx.Response{data=response.PageResult} "成功" // @Router /api/user/getUserList [post] func (slf *BaseApi) GetUserList(c *gin.Context) { var params request.GetUserList ctx, ok := contextx.NewContext(c, ¶ms) if !ok { return } userInfo := utils.GetUserInfo(c) if len(userInfo.UserId) <= 0 || len(userInfo.ParentId) == 0 { ctx.Fail(ecode.UnknownErr) return } ctx.OkWithDetailed(response.PageResult{ Page: params.Page, PageSize: params.PageSize, }) } // DeleteUser // // @Tags User // @Summary 删除用户 // @Produce application/json // @Param object body request.DeleteUserReq true "查询参数" // @Success 200 {object} contextx.Response{} "成功" // @Router /api/user/deleteUser [delete] func (slf *BaseApi) DeleteUser(c *gin.Context) { var params request.DeleteUserReq ctx, ok := contextx.NewContext(c, ¶ms) if !ok { return } if len(params.UserId) <= 0 { ctx.Fail(ecode.ParamsErr) return } userInfo := utils.GetUserInfo(c) if userInfo.UserType != constvar.UserTypePrimary || userInfo.UserId == params.UserId { ctx.Fail(ecode.NoPowerErr) return } err := userService.DeleteUser(params.UserId) if err != nil { logx.Errorf("删除失败! err:%v", err) ctx.Fail(ecode.DBErr) return } ctx.Ok() } // SetUserInfo // // @Tags User // @Summary 设置用户信息 // @Produce application/json // @Param object body request.ChangeUserInfo true "查询参数" // @Success 200 {object} contextx.Response{} "成功" // @Router /api/user/setUserInfo [post] func (slf *BaseApi) SetUserInfo(c *gin.Context) { var params request.ChangeUserInfo ctx, ok := contextx.NewContext(c, ¶ms) if !ok { return } err := userService.SetUserInfo(model.User{ UUID: params.ID, NickName: params.NickName, HeaderImg: params.HeaderImg, Phone: params.Phone, Email: params.Email, Pos: params.Pos, }) if err != nil { logx.Errorf("设置失败! err:%v", err) ctx.Fail(ecode.DBErr) return } ctx.Ok() } // SetSelfInfo // // @Tags User // @Summary 设置用户信息 // @Produce application/json // @Param object body request.ChangeUserInfo true "查询参数" // @Success 200 {object} contextx.Response{} "成功" // @Router /api/user/setSelfInfo [post] func (slf *BaseApi) SetSelfInfo(c *gin.Context) { var params request.ChangeUserInfo ctx, ok := contextx.NewContext(c, ¶ms) if !ok { return } params.ID = utils.GetUserID(c) err := userService.SetUserInfo(model.User{ UUID: params.ID, NickName: params.NickName, HeaderImg: params.HeaderImg, Phone: params.Phone, Email: params.Email, Pos: params.Pos, }) if err != nil { logx.Errorf("设置失败! err:%v", err) ctx.Fail(ecode.DBErr) return } ctx.Ok() } // GetUserInfo // // @Tags User // @Summary 获取自身信息 // @Produce application/json // @Success 200 {object} contextx.Response{} "成功" // @Router /api/user/getUserInfo [post] func (slf *BaseApi) GetUserInfo(c *gin.Context) { ctx, ok := contextx.NewContext(c, nil) if !ok { return } id := utils.GetUserID(c) ReqUser, err := userService.GetUserInfo(id) if err != nil { logx.Errorf("获取失败! err:%v", err) ctx.Fail(ecode.DBErr) return } ctx.OkWithDetailed(response.UserResponse{ User: *ReqUser, }) } // ResetPassword // // @Tags User // @Summary 重置用户密码 // @Produce application/json // @Param object body model.User true "查询参数" // @Success 200 {object} contextx.Response{} "成功" // @Router /api/user/resetPassword [post] func (slf *BaseApi) ResetPassword(c *gin.Context) { var params model.User ctx, ok := contextx.NewContext(c, ¶ms) if !ok { return } err := userService.ResetPassword(params.UUID) if err != nil { logx.Errorf("重置失败! err:%v", err) ctx.Fail(ecode.DBErr) return } ctx.Ok() }