admin_user.go 11 KB

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