admin_user.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. package service
  2. import (
  3. "gadmin/config"
  4. "gadmin/internal/admin/consts"
  5. "gadmin/internal/admin/forms"
  6. "gadmin/internal/gorm/model"
  7. "gadmin/utility/serializer"
  8. "time"
  9. "golang.org/x/crypto/bcrypt"
  10. )
  11. // User 管理员服务
  12. var User = NewsUser()
  13. type LoginStats struct {
  14. FailNum int
  15. BanTs int64
  16. }
  17. type sUser struct {
  18. BanIps map[string]*LoginStats
  19. }
  20. func NewsUser() *sUser {
  21. user := new(sUser)
  22. user.BanIps = make(map[string]*LoginStats)
  23. return user
  24. }
  25. // 一次登录,清空错误次数
  26. func (s *sUser) AddSucessNum(ip string) {
  27. delete(s.BanIps, ip)
  28. }
  29. // 增加错误登录次数,超过10次,不再进行密码验证
  30. func (s *sUser) AddFailNum(ip string) {
  31. stats, ok := s.BanIps[ip]
  32. if !ok {
  33. stats = new(LoginStats)
  34. s.BanIps[ip] = stats
  35. }
  36. if stats.BanTs > 0 {
  37. return
  38. }
  39. if stats.FailNum > 10 {
  40. curTs := time.Now().Unix()
  41. stats.BanTs = curTs
  42. // 清理错误登录
  43. for k, v := range s.BanIps {
  44. if v.BanTs+24*60*60 < curTs {
  45. delete(s.BanIps, k)
  46. }
  47. }
  48. return
  49. }
  50. stats.FailNum += 1
  51. }
  52. // 检查是否允许登录
  53. func (s *sUser) CheckLoginAllow(ip string) bool {
  54. stats, ok := s.BanIps[ip]
  55. if !ok {
  56. return true
  57. }
  58. cur := time.Now().Unix()
  59. if stats.BanTs+1*60*60 > cur {
  60. return false
  61. }
  62. stats.BanTs = 0
  63. stats.FailNum = 0
  64. return true
  65. }
  66. // GetUser 用ID获取用户
  67. func (s *sUser) GetUser(ID interface{}) (u *model.AdminUser, err error) {
  68. result := config.DB.First(&u, ID)
  69. return u, result.Error
  70. }
  71. // SetPassword 设置密码
  72. func (s *sUser) SetPassword(password string) (string, error) {
  73. bytes, err := bcrypt.GenerateFromPassword([]byte(password), consts.PassWordCost)
  74. if err != nil {
  75. return "", err
  76. }
  77. return string(bytes), nil
  78. }
  79. // CheckPassword 校验密码
  80. func (s *sUser) CheckPasswordRight(passwordDigest, password string) bool {
  81. err := bcrypt.CompareHashAndPassword([]byte(passwordDigest), []byte(password))
  82. return err == nil
  83. }
  84. //func (s *sUser) Login(req forms.UserLoginReq, ip string) serializer.Response {
  85. // var (
  86. // u model.AdminUser
  87. // )
  88. // if ok := s.CheckLoginAllow(ip); !ok {
  89. // return serializer.ParamErr("账号已被禁止登录", nil)
  90. // }
  91. //
  92. // if err := config.AdminDB.Where("user_name = ?", req.UserName).First(&u).Error; err != nil {
  93. // s.AddFailNum(ip)
  94. // logrus.Warnf("sUser %v Login req error %v.", req.UserName, ip)
  95. // return serializer.ParamErr("账号错误或不存在,请检查", nil)
  96. // }
  97. // //p, _ := s.SetPassword(req.Password)
  98. // //fmt.Println("pass:", p)
  99. //
  100. // if u.Status != 1 {
  101. // return serializer.ParamErr("账号已被禁用", nil)
  102. // }
  103. //
  104. // if s.CheckPasswordRight(u.PasswordDigest, req.Password) == false {
  105. // s.AddFailNum(ip)
  106. // logrus.Warnf("sUser %v Login req error. ip: %v.", req.UserName, ip)
  107. // return serializer.ParamErr("密码不正确,如忘记了密码请联系管理员!", nil)
  108. // }
  109. // s.AddSucessNum(ip)
  110. //
  111. // //if os.Getenv("GIN_MODE") == "release" && u.UserName == "mojun" {
  112. // // return serializer.ParamErr("该账号只允许在测试服登录!", nil)
  113. // //}
  114. //
  115. // t := token.GenerateTokenUsingUUID()
  116. //
  117. // // 记录登录token
  118. // key := config.GetUserTokenKey(u.ID)
  119. // config.TokenRedis.HSet(key, t, time.Now().Unix())
  120. // config.TokenRedis.Expire(key, config.TokenExpireTime)
  121. //
  122. // tokenKey := config.GetTokenKey(t)
  123. // user := &token.UserClaims{
  124. // ID: u.ID,
  125. // UserName: u.UserName,
  126. // RoleId: int64(u.RoleID),
  127. // Avatar: u.Avatar,
  128. // Nickname: u.Nickname,
  129. // AccessToken: t,
  130. // }
  131. // userStr, err := jsoniter.MarshalToString(user)
  132. // if err != nil {
  133. // return serializer.Err(1, "", err)
  134. // }
  135. // config.TokenRedis.Set(tokenKey, userStr, config.TokenExpireTime)
  136. //
  137. // return serializer.Suc(forms.UserLoginRes{
  138. // ID: u.ID,
  139. // UserName: u.UserName,
  140. // Nickname: u.Nickname,
  141. // Status: u.Status,
  142. // Avatar: u.Avatar,
  143. // Token: base64.URLEncoding.EncodeToString([]byte(t)),
  144. // })
  145. //
  146. // //t, err := token.GenerateToken(&token.UserClaims{
  147. // // ID: u.ID,
  148. // // UserName: u.UserName,
  149. // // RoleId: int64(u.RoleID),
  150. // // Avatar: u.Avatar,
  151. // // Nickname: u.Nickname,
  152. // //})
  153. // //if err != nil {
  154. // // return serializer.ParamErr(err.Error(), nil)
  155. // //}
  156. // //return serializer.Suc(forms.UserLoginRes{
  157. // // ID: u.ID,
  158. // // UserName: u.UserName,
  159. // // Nickname: u.Nickname,
  160. // // Status: u.Status,
  161. // // Avatar: u.Avatar,
  162. // // Token: t,
  163. // //})
  164. //}
  165. func (s *sUser) Register(req forms.UserRegisterReq) serializer.Response {
  166. user := model.AdminUser{
  167. Nickname: req.Nickname,
  168. UserName: req.UserName,
  169. Status: consts.StatusNormal,
  170. }
  171. count := int64(0)
  172. config.DB.Model(&model.AdminUser{}).Where("nickname = ?", req.Nickname).Count(&count)
  173. if count > 0 {
  174. return serializer.Response{
  175. Code: 40001,
  176. Msg: "昵称被占用",
  177. }
  178. }
  179. config.DB.Model(&model.AdminUser{}).Where("user_name = ?", req.UserName).Count(&count)
  180. if count > 0 {
  181. return serializer.Response{
  182. Code: 40001,
  183. Msg: "用户名已经注册",
  184. }
  185. }
  186. // 加密密码
  187. password, err := s.SetPassword(req.Password)
  188. if err != nil {
  189. return serializer.Err(
  190. consts.CodeEncryptError,
  191. "密码加密失败",
  192. err,
  193. )
  194. }
  195. user.PasswordDigest = password
  196. if err = config.DB.Create(&user).Error; err != nil {
  197. return serializer.ParamErr("注册失败", err)
  198. }
  199. user.PasswordDigest = ""
  200. return serializer.Suc(user)
  201. }
  202. //func (s *sUser) List(ctx *gin.Context, req forms.AdminUserListReq) serializer.Response {
  203. // var (
  204. // q = query.Use(config.AdminDB).AdminUser
  205. // r = query.Use(config.AdminDB).AdminRole
  206. // m = q.WithContext(ctx)
  207. // offset int64 = 0
  208. // models forms.UserAccountListRes
  209. // lists []*forms.AdminUserListModel
  210. // )
  211. //
  212. // m = m.Order(q.ID.Desc())
  213. //
  214. // req.Page, req.PerPage, offset = forms.CalculatePage(req.Page, req.PerPage)
  215. //
  216. // count, err := m.Count()
  217. // if err != nil {
  218. // return serializer.Err(consts.CodeParamErr, "查询出错 count", err)
  219. // }
  220. //
  221. // if count > 0 {
  222. // if err = m.Limit(int(req.PerPage)).Offset(int(offset)).Scan(&lists); err != nil {
  223. // return serializer.Err(consts.CodeParamErr, "查询出错 lists", err)
  224. // }
  225. // }
  226. //
  227. // for _, v := range lists {
  228. // role, err := r.WithContext(ctx).Where(r.ID.Eq(v.RoleID)).First()
  229. // v.RoleName = "未绑定角色"
  230. // if role != nil && err == nil {
  231. // v.RoleName = role.Name
  232. // }
  233. // }
  234. //
  235. // models.List = lists
  236. // models.Page = req.Page
  237. // models.PerPage = req.PerPage
  238. // models.PageCount = (count + req.PerPage - 1) / req.PerPage
  239. //
  240. // return serializer.Suc(models)
  241. //}
  242. //func (s *sUser) Edit(ctx *gin.Context, req forms.AdminUserEditReq) serializer.Response {
  243. // q := query.Use(config.AdminDB).AdminUser
  244. //
  245. // logrus.Warnf("sUser Edit req:%+v", req)
  246. //
  247. // if req.RoleID <= 0 {
  248. // return serializer.ParamErr("角色不能为空", nil)
  249. // }
  250. //
  251. // if req.UserName == "" {
  252. // return serializer.ParamErr("用户名不能为空", nil)
  253. // }
  254. //
  255. // // 修改
  256. // if req.ID > 0 {
  257. // update := &model.AdminUser{
  258. // UserName: req.UserName,
  259. // RoleID: int32(req.RoleID),
  260. // Nickname: req.Nickname,
  261. // Status: req.Status,
  262. // UpdatedAt: time.Now(),
  263. // }
  264. // _, err := q.WithContext(ctx).Where(q.ID.Eq(req.ID)).Updates(update)
  265. // if err != nil {
  266. // return serializer.Err(consts.CodeParamErr, "更新出错", err)
  267. // }
  268. // // 维护redis token
  269. // config.TokenRedis.Del(config.GetUserTokenKey(req.ID))
  270. // return serializer.Suc(nil)
  271. // }
  272. //
  273. // if req.Password == "" {
  274. // return serializer.ParamErr("密码不能为空", nil)
  275. // }
  276. //
  277. // // 加密密码
  278. // password, err := s.SetPassword(req.Password)
  279. // if err != nil {
  280. // return serializer.Err(
  281. // consts.CodeEncryptError,
  282. // "密码加密失败",
  283. // err,
  284. // )
  285. // }
  286. //
  287. // // 新增
  288. // create := &model.AdminUser{
  289. // UserName: req.UserName,
  290. // RoleID: int32(req.RoleID),
  291. // Nickname: req.Nickname,
  292. // PasswordDigest: password,
  293. // Status: req.Status,
  294. // UpdatedAt: time.Now(),
  295. // CreatedAt: time.Now(),
  296. // }
  297. //
  298. // if err = query.Use(config.AdminDB).AdminUser.WithContext(ctx).Create(create); err != nil {
  299. // return serializer.DBErr(err.Error(), err)
  300. // }
  301. //
  302. // return serializer.Suc(nil)
  303. //}
  304. //func (s *sUser) ResetPassword(ctx *gin.Context, req forms.AdminUserResetPasswordReq) serializer.Response {
  305. // q := query.Use(config.AdminDB).AdminUser
  306. //
  307. // logrus.Warnf("sUser ResetPassword req:%+v", req)
  308. //
  309. // if req.ID <= 0 {
  310. // return serializer.ParamErr("用于ID不能为空", nil)
  311. // }
  312. //
  313. // if req.Password == "" {
  314. // return serializer.ParamErr("密码不能为空", nil)
  315. // }
  316. //
  317. // // 加密密码
  318. // password, err := s.SetPassword(req.Password)
  319. // if err != nil {
  320. // return serializer.Err(
  321. // consts.CodeEncryptError,
  322. // "密码加密失败",
  323. // err,
  324. // )
  325. // }
  326. // update := &model.AdminUser{
  327. // PasswordDigest: password,
  328. // UpdatedAt: time.Now(),
  329. // }
  330. //
  331. // _, err = q.WithContext(ctx).Where(q.ID.Eq(req.ID)).Updates(update)
  332. // if err != nil {
  333. // return serializer.Err(consts.CodeParamErr, "更新出错", err)
  334. // }
  335. // // 维护redis token
  336. // config.TokenRedis.Del(config.GetUserTokenKey(req.ID))
  337. // return serializer.Suc(nil)
  338. //}
  339. //func (s *sUser) UpdatePassword(ctx *gin.Context, req forms.AdminUserUpdatePasswordReq) serializer.Response {
  340. // q := query.Use(config.AdminDB).AdminUser
  341. //
  342. // logrus.Warnf("sUser UpdatePassword req:%+v", req)
  343. //
  344. // userId := token.GetUID(ctx)
  345. // if userId <= 0 {
  346. // return serializer.ParamErr("用户信息获取失败", nil)
  347. // }
  348. //
  349. // models, err := q.WithContext(ctx).Where(q.ID.Eq(userId)).First()
  350. // if err != nil {
  351. // return serializer.ParamErr(err.Error(), err)
  352. // }
  353. //
  354. // if models == nil {
  355. // return serializer.ParamErr("用户不存在", nil)
  356. // }
  357. //
  358. // if !s.CheckPasswordRight(models.PasswordDigest, req.OldPassword) {
  359. // return serializer.ParamErr("老密码不正确", nil)
  360. // }
  361. //
  362. // // 加密密码
  363. // password, err := s.SetPassword(req.NewPassword)
  364. // if err != nil {
  365. // return serializer.Err(
  366. // consts.CodeEncryptError,
  367. // "密码加密失败",
  368. // err,
  369. // )
  370. // }
  371. // update := &model.AdminUser{
  372. // PasswordDigest: password,
  373. // UpdatedAt: time.Now(),
  374. // }
  375. //
  376. // _, err = q.WithContext(ctx).Where(q.ID.Eq(userId)).Updates(update)
  377. // if err != nil {
  378. // return serializer.Err(consts.CodeParamErr, "更新出错", err)
  379. // }
  380. //
  381. // // 修改token状态
  382. // config.TokenRedis.Del(config.GetUserTokenKey(userId))
  383. //
  384. // return serializer.Suc(nil)
  385. //}
  386. //func (s *sUser) GetUserInfo(c *gin.Context) (*model.AdminUser, error) {
  387. // q := query.Use(config.AdminDB).AdminUser
  388. //
  389. // userId := token.GetUID(c)
  390. // if userId <= 0 {
  391. // c.JSON(200, serializer.Err(consts.CodeNoPermission, "用户信息获取失败", nil))
  392. // c.Abort()
  393. // }
  394. //
  395. // return q.WithContext(c).Where(q.ID.Eq(userId)).First()
  396. //}
  397. //func (s *sUser) GetUserRoleId(c *gin.Context) int64 {
  398. // info, err := s.GetUserInfo(c)
  399. // if err != nil {
  400. // return 0
  401. // }
  402. //
  403. // if info == nil {
  404. // return 0
  405. // }
  406. //
  407. // return int64(info.RoleID)
  408. //}
  409. //func (s *sUser) GetUserByUnionID(unionID string) (*model.AdminUser, error) {
  410. // q := query.Use(config.AdminDB).AdminUser
  411. // return q.Where(q.FeishuUnionID.Eq(unionID)).First()
  412. //}