You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

287 lines
9.7 KiB

  1. package v1
  2. import (
  3. "gin-vue-admin/global"
  4. "gin-vue-admin/middleware"
  5. "gin-vue-admin/model"
  6. "gin-vue-admin/model/request"
  7. "gin-vue-admin/model/response"
  8. "gin-vue-admin/service"
  9. "gin-vue-admin/utils"
  10. "time"
  11. "github.com/dgrijalva/jwt-go"
  12. "github.com/gin-gonic/gin"
  13. "github.com/go-redis/redis"
  14. "go.uber.org/zap"
  15. )
  16. // @Tags Base
  17. // @Summary 用户登录
  18. // @Produce application/json
  19. // @Param data body request.Login true "用户名, 密码, 验证码"
  20. // @Success 200 {string} string "{"success":true,"data":{},"msg":"登陆成功"}"
  21. // @Router /base/login [post]
  22. func Login(c *gin.Context) {
  23. var L request.Login
  24. _ = c.ShouldBindJSON(&L)
  25. if err := utils.Verify(L, utils.LoginVerify); err != nil {
  26. response.FailWithMessage(err.Error(), c)
  27. return
  28. }
  29. if store.Verify(L.CaptchaId, L.Captcha, true) {
  30. U := &model.SysUser{Username: L.Username, Password: L.Password}
  31. if err, user := service.Login(U); err != nil {
  32. global.GVA_LOG.Error("登陆失败! 用户名不存在或者密码错误!", zap.Any("err", err))
  33. response.FailWithMessage("用户名不存在或者密码错误", c)
  34. } else {
  35. tokenNext(c, *user)
  36. }
  37. } else {
  38. response.FailWithMessage("验证码错误", c)
  39. }
  40. }
  41. // 登录以后签发jwt
  42. func tokenNext(c *gin.Context, user model.SysUser) {
  43. j := &middleware.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名
  44. claims := request.CustomClaims{
  45. UUID: user.UUID,
  46. ID: user.ID,
  47. NickName: user.NickName,
  48. Username: user.Username,
  49. AuthorityId: user.AuthorityId,
  50. BufferTime: global.GVA_CONFIG.JWT.BufferTime, // 缓冲时间1天 缓冲时间内会获得新的token刷新令牌 此时一个用户会存在两个有效令牌 但是前端只留一个 另一个会丢失
  51. StandardClaims: jwt.StandardClaims{
  52. NotBefore: time.Now().Unix() - 1000, // 签名生效时间
  53. ExpiresAt: time.Now().Unix() + global.GVA_CONFIG.JWT.ExpiresTime, // 过期时间 7天 配置文件
  54. Issuer: "qmPlus", // 签名的发行者
  55. },
  56. }
  57. token, err := j.CreateToken(claims)
  58. if err != nil {
  59. global.GVA_LOG.Error("获取token失败!", zap.Any("err", err))
  60. response.FailWithMessage("获取token失败", c)
  61. return
  62. }
  63. if !global.GVA_CONFIG.System.UseMultipoint {
  64. response.OkWithDetailed(response.LoginResponse{
  65. User: user,
  66. Token: token,
  67. ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
  68. }, "登录成功", c)
  69. return
  70. }
  71. if err, jwtStr := service.GetRedisJWT(user.Username); err == redis.Nil {
  72. if err := service.SetRedisJWT(token, user.Username); err != nil {
  73. global.GVA_LOG.Error("设置登录状态失败!", zap.Any("err", err))
  74. response.FailWithMessage("设置登录状态失败", c)
  75. return
  76. }
  77. response.OkWithDetailed(response.LoginResponse{
  78. User: user,
  79. Token: token,
  80. ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
  81. }, "登录成功", c)
  82. } else if err != nil {
  83. global.GVA_LOG.Error("设置登录状态失败!", zap.Any("err", err))
  84. response.FailWithMessage("设置登录状态失败", c)
  85. } else {
  86. var blackJWT model.JwtBlacklist
  87. blackJWT.Jwt = jwtStr
  88. if err := service.JsonInBlacklist(blackJWT); err != nil {
  89. response.FailWithMessage("jwt作废失败", c)
  90. return
  91. }
  92. if err := service.SetRedisJWT(token, user.Username); err != nil {
  93. response.FailWithMessage("设置登录状态失败", c)
  94. return
  95. }
  96. response.OkWithDetailed(response.LoginResponse{
  97. User: user,
  98. Token: token,
  99. ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
  100. }, "登录成功", c)
  101. }
  102. }
  103. // @Tags SysUser
  104. // @Summary 用户注册账号
  105. // @Produce application/json
  106. // @Param data body model.SysUser true "用户名, 昵称, 密码, 角色ID"
  107. // @Success 200 {string} string "{"success":true,"data":{},"msg":"注册成功"}"
  108. // @Router /user/register [post]
  109. func Register(c *gin.Context) {
  110. var R request.Register
  111. _ = c.ShouldBindJSON(&R)
  112. if err := utils.Verify(R, utils.RegisterVerify); err != nil {
  113. response.FailWithMessage(err.Error(), c)
  114. return
  115. }
  116. user := &model.SysUser{Username: R.Username, NickName: R.NickName, Password: R.Password, HeaderImg: R.HeaderImg, AuthorityId: R.AuthorityId}
  117. err, userReturn := service.Register(*user)
  118. if err != nil {
  119. global.GVA_LOG.Error("注册失败!", zap.Any("err", err))
  120. response.FailWithDetailed(response.SysUserResponse{User: userReturn}, "注册失败", c)
  121. } else {
  122. response.OkWithDetailed(response.SysUserResponse{User: userReturn}, "注册成功", c)
  123. }
  124. }
  125. // @Tags SysUser
  126. // @Summary 用户修改密码
  127. // @Security ApiKeyAuth
  128. // @Produce application/json
  129. // @Param data body request.ChangePasswordStruct true "用户名, 原密码, 新密码"
  130. // @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
  131. // @Router /user/changePassword [put]
  132. func ChangePassword(c *gin.Context) {
  133. var user request.ChangePasswordStruct
  134. _ = c.ShouldBindJSON(&user)
  135. if err := utils.Verify(user, utils.ChangePasswordVerify); err != nil {
  136. response.FailWithMessage(err.Error(), c)
  137. return
  138. }
  139. U := &model.SysUser{Username: user.Username, Password: user.Password}
  140. if err, _ := service.ChangePassword(U, user.NewPassword); err != nil {
  141. global.GVA_LOG.Error("修改失败!", zap.Any("err", err))
  142. response.FailWithMessage("修改失败,原密码与当前账户不符", c)
  143. } else {
  144. response.OkWithMessage("修改成功", c)
  145. }
  146. }
  147. // @Tags SysUser
  148. // @Summary 分页获取用户列表
  149. // @Security ApiKeyAuth
  150. // @accept application/json
  151. // @Produce application/json
  152. // @Param data body request.PageInfo true "页码, 每页大小"
  153. // @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
  154. // @Router /user/getUserList [post]
  155. func GetUserList(c *gin.Context) {
  156. var pageInfo request.PageInfo
  157. _ = c.ShouldBindJSON(&pageInfo)
  158. if err := utils.Verify(pageInfo, utils.PageInfoVerify); err != nil {
  159. response.FailWithMessage(err.Error(), c)
  160. return
  161. }
  162. if err, list, total := service.GetUserInfoList(pageInfo); err != nil {
  163. global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
  164. response.FailWithMessage("获取失败", c)
  165. } else {
  166. response.OkWithDetailed(response.PageResult{
  167. List: list,
  168. Total: total,
  169. Page: pageInfo.Page,
  170. PageSize: pageInfo.PageSize,
  171. }, "获取成功", c)
  172. }
  173. }
  174. // @Tags SysUser
  175. // @Summary 设置用户权限
  176. // @Security ApiKeyAuth
  177. // @accept application/json
  178. // @Produce application/json
  179. // @Param data body request.SetUserAuth true "用户UUID, 角色ID"
  180. // @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
  181. // @Router /user/setUserAuthority [post]
  182. func SetUserAuthority(c *gin.Context) {
  183. var sua request.SetUserAuth
  184. _ = c.ShouldBindJSON(&sua)
  185. if UserVerifyErr := utils.Verify(sua, utils.SetUserAuthorityVerify); UserVerifyErr != nil {
  186. response.FailWithMessage(UserVerifyErr.Error(), c)
  187. return
  188. }
  189. if err := service.SetUserAuthority(sua.UUID, sua.AuthorityId); err != nil {
  190. global.GVA_LOG.Error("修改失败!", zap.Any("err", err))
  191. response.FailWithMessage("修改失败", c)
  192. } else {
  193. response.OkWithMessage("修改成功", c)
  194. }
  195. }
  196. // @Tags SysUser
  197. // @Summary 删除用户
  198. // @Security ApiKeyAuth
  199. // @accept application/json
  200. // @Produce application/json
  201. // @Param data body request.GetById true "用户ID"
  202. // @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
  203. // @Router /user/deleteUser [delete]
  204. func DeleteUser(c *gin.Context) {
  205. var reqId request.GetById
  206. _ = c.ShouldBindJSON(&reqId)
  207. if err := utils.Verify(reqId, utils.IdVerify); err != nil {
  208. response.FailWithMessage(err.Error(), c)
  209. return
  210. }
  211. jwtId := getUserID(c)
  212. if jwtId == uint(reqId.ID) {
  213. response.FailWithMessage("删除失败, 自杀失败", c)
  214. return
  215. }
  216. if err := service.DeleteUser(reqId.ID); err != nil {
  217. global.GVA_LOG.Error("删除失败!", zap.Any("err", err))
  218. response.FailWithMessage("删除失败", c)
  219. } else {
  220. response.OkWithMessage("删除成功", c)
  221. }
  222. }
  223. // @Tags SysUser
  224. // @Summary 设置用户信息
  225. // @Security ApiKeyAuth
  226. // @accept application/json
  227. // @Produce application/json
  228. // @Param data body model.SysUser true "ID, 用户名, 昵称, 头像链接"
  229. // @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}"
  230. // @Router /user/setUserInfo [put]
  231. func SetUserInfo(c *gin.Context) {
  232. var user model.SysUser
  233. _ = c.ShouldBindJSON(&user)
  234. if err := utils.Verify(user, utils.IdVerify); err != nil {
  235. response.FailWithMessage(err.Error(), c)
  236. return
  237. }
  238. if err, ReqUser := service.SetUserInfo(user); err != nil {
  239. global.GVA_LOG.Error("设置失败!", zap.Any("err", err))
  240. response.FailWithMessage("设置失败", c)
  241. } else {
  242. response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "设置成功", c)
  243. }
  244. }
  245. // 从Gin的Context中获取从jwt解析出来的用户ID
  246. func getUserID(c *gin.Context) uint {
  247. if claims, exists := c.Get("claims"); !exists {
  248. global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户ID失败, 请检查路由是否使用jwt中间件!")
  249. return 0
  250. } else {
  251. waitUse := claims.(*request.CustomClaims)
  252. return waitUse.ID
  253. }
  254. }
  255. // 从Gin的Context中获取从jwt解析出来的用户UUID
  256. func getUserUuid(c *gin.Context) string {
  257. if claims, exists := c.Get("claims"); !exists {
  258. global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!")
  259. return ""
  260. } else {
  261. waitUse := claims.(*request.CustomClaims)
  262. return waitUse.UUID.String()
  263. }
  264. }
  265. // 从Gin的Context中获取从jwt解析出来的用户角色id
  266. func getUserAuthorityId(c *gin.Context) string {
  267. if claims, exists := c.Get("claims"); !exists {
  268. global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!")
  269. return ""
  270. } else {
  271. waitUse := claims.(*request.CustomClaims)
  272. return waitUse.AuthorityId
  273. }
  274. }