sys_user_online.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * @desc:用户在线状态处理
  3. * @company:云南奇讯科技有限公司
  4. * @Author: yixiaohu<yxh669@qq.com>
  5. * @Date: 2023/1/10 14:50
  6. */
  7. package sysUserOnline
  8. import (
  9. "context"
  10. "github.com/gogf/gf/v2/frame/g"
  11. "github.com/gogf/gf/v2/os/grpool"
  12. "github.com/gogf/gf/v2/os/gtime"
  13. "github.com/mssola/user_agent"
  14. "github.com/tiger1103/gfast/v3/api/v1/common"
  15. "github.com/tiger1103/gfast/v3/api/v1/system"
  16. "github.com/tiger1103/gfast/v3/internal/app/system/consts"
  17. "github.com/tiger1103/gfast/v3/internal/app/system/dao"
  18. "github.com/tiger1103/gfast/v3/internal/app/system/model"
  19. "github.com/tiger1103/gfast/v3/internal/app/system/model/do"
  20. "github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
  21. "github.com/tiger1103/gfast/v3/internal/app/system/service"
  22. "github.com/tiger1103/gfast/v3/library/liberr"
  23. )
  24. func init() {
  25. service.RegisterSysUserOnline(New())
  26. }
  27. func New() *sSysUserOnline {
  28. return &sSysUserOnline{
  29. Pool: grpool.New(100),
  30. }
  31. }
  32. type sSysUserOnline struct {
  33. Pool *grpool.Pool
  34. }
  35. func (s *sSysUserOnline) Invoke(ctx context.Context, params *model.SysUserOnlineParams) {
  36. s.Pool.Add(ctx, func(ctx context.Context) {
  37. //写入数据
  38. s.SaveOnline(ctx, params)
  39. })
  40. }
  41. // SaveOnline 保存用户在线状态
  42. func (s *sSysUserOnline) SaveOnline(ctx context.Context, params *model.SysUserOnlineParams) {
  43. err := g.Try(ctx, func(ctx context.Context) {
  44. ua := user_agent.New(params.UserAgent)
  45. browser, _ := ua.Browser()
  46. os := ua.OS()
  47. var (
  48. info *entity.SysUserOnline
  49. data = &do.SysUserOnline{
  50. Uuid: params.Uuid,
  51. Token: params.Token,
  52. CreateTime: gtime.Now(),
  53. UserName: params.Username,
  54. Ip: params.Ip,
  55. Explorer: browser,
  56. Os: os,
  57. }
  58. )
  59. //查询是否已存在当前用户
  60. err := dao.SysUserOnline.Ctx(ctx).Fields(dao.SysUserOnline.Columns().Id).
  61. Where(dao.SysUserOnline.Columns().Token, data.Token).
  62. Scan(&info)
  63. liberr.ErrIsNil(ctx, err)
  64. //若已存在则更新
  65. if info != nil {
  66. _, err = dao.SysUserOnline.Ctx(ctx).
  67. Where(dao.SysUserOnline.Columns().Id, info.Id).
  68. FieldsEx(dao.SysUserOnline.Columns().Id).Update(data)
  69. liberr.ErrIsNil(ctx, err)
  70. } else { //否则新增
  71. _, err = dao.SysUserOnline.Ctx(ctx).
  72. FieldsEx(dao.SysUserOnline.Columns().Id).Insert(data)
  73. liberr.ErrIsNil(ctx, err)
  74. }
  75. })
  76. if err != nil {
  77. g.Log().Error(ctx, err)
  78. }
  79. }
  80. // CheckUserOnline 检查在线用户
  81. func (s *sSysUserOnline) CheckUserOnline(ctx context.Context) {
  82. param := &system.SysUserOnlineSearchReq{
  83. PageReq: common.PageReq{
  84. PageNum: 1,
  85. PageSize: 50,
  86. },
  87. }
  88. var total int
  89. for {
  90. var (
  91. res *system.SysUserOnlineSearchRes
  92. err error
  93. )
  94. res, err = s.GetOnlineListPage(ctx, param, true)
  95. if err != nil {
  96. g.Log().Error(ctx, err)
  97. break
  98. }
  99. if res.List == nil {
  100. break
  101. }
  102. for _, v := range res.List {
  103. if b := s.UserIsOnline(ctx, v.Token); !b {
  104. s.DeleteOnlineByToken(ctx, v.Token)
  105. }
  106. }
  107. if param.PageNum*param.PageSize >= total {
  108. break
  109. }
  110. param.PageNum++
  111. }
  112. }
  113. // GetOnlineListPage 搜素在线用户列表
  114. func (s *sSysUserOnline) GetOnlineListPage(ctx context.Context, req *system.SysUserOnlineSearchReq, hasToken ...bool) (res *system.SysUserOnlineSearchRes, err error) {
  115. if req.PageNum == 0 {
  116. req.PageNum = 1
  117. }
  118. if req.PageSize == 0 {
  119. req.PageSize = consts.PageSize
  120. }
  121. model := dao.SysUserOnline.Ctx(ctx)
  122. if req.Ip != "" {
  123. model = model.Where("ip like ?", "%"+req.Ip+"%")
  124. }
  125. if req.Username != "" {
  126. model = model.Where("user_name like ?", "%"+req.Username+"%")
  127. }
  128. res = new(system.SysUserOnlineSearchRes)
  129. err = g.Try(ctx, func(ctx context.Context) {
  130. res.Total, err = model.Count()
  131. liberr.ErrIsNil(ctx, err, "获取总行数失败")
  132. if len(hasToken) == 0 || !hasToken[0] {
  133. model = model.FieldsEx("token")
  134. }
  135. err = model.Page(req.PageNum, req.PageSize).Order("create_time DESC").Scan(&res.List)
  136. liberr.ErrIsNil(ctx, err, "获取数据失败")
  137. })
  138. return
  139. }
  140. func (s *sSysUserOnline) UserIsOnline(ctx context.Context, token string) bool {
  141. err := g.Try(ctx, func(ctx context.Context) {
  142. _, _, err := service.GfToken().GetTokenData(ctx, token)
  143. liberr.ErrIsNil(ctx, err)
  144. })
  145. return err == nil
  146. }
  147. func (s *sSysUserOnline) DeleteOnlineByToken(ctx context.Context, token string) (err error) {
  148. _, err = dao.SysUserOnline.Ctx(ctx).Delete(dao.SysUserOnline.Columns().Token, token)
  149. return
  150. }
  151. func (s *sSysUserOnline) ForceLogout(ctx context.Context, ids []int) (err error) {
  152. err = g.Try(ctx, func(ctx context.Context) {
  153. var onlineList []*entity.SysUserOnline
  154. onlineList, err = s.GetInfosByIds(ctx, ids)
  155. liberr.ErrIsNil(ctx, err)
  156. _, err = dao.SysUserOnline.Ctx(ctx).Where(dao.SysUserOnline.Columns().Id+" in(?)", ids).Delete()
  157. liberr.ErrIsNil(ctx, err)
  158. for _, v := range onlineList {
  159. err = service.GfToken().RemoveToken(ctx, v.Token)
  160. liberr.ErrIsNil(ctx, err)
  161. }
  162. })
  163. return
  164. }
  165. func (s *sSysUserOnline) GetInfosByIds(ctx context.Context, ids []int) (onlineList []*entity.SysUserOnline, err error) {
  166. err = dao.SysUserOnline.Ctx(ctx).Where(dao.SysUserOnline.Columns().Id+" in(?)", ids).Scan(&onlineList)
  167. return
  168. }