2023-09-26 16:23:44 +08:00

191 lines
5.3 KiB
Go

/*
* @desc:用户在线状态处理
* @company:云南奇讯科技有限公司
* @Author: yixiaohu<yxh669@qq.com>
* @Date: 2023/1/10 14:50
*/
package sysUserOnline
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/grpool"
"github.com/gogf/gf/v2/os/gtime"
"github.com/mssola/user_agent"
"github.com/tiger1103/gfast/v3/api/v1/common"
"github.com/tiger1103/gfast/v3/api/v1/system"
comModel "github.com/tiger1103/gfast/v3/internal/app/common/model"
"github.com/tiger1103/gfast/v3/internal/app/system/consts"
"github.com/tiger1103/gfast/v3/internal/app/system/dao"
"github.com/tiger1103/gfast/v3/internal/app/system/model"
"github.com/tiger1103/gfast/v3/internal/app/system/model/do"
"github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
"github.com/tiger1103/gfast/v3/internal/app/system/service"
"github.com/tiger1103/gfast/v3/library/liberr"
)
func init() {
service.RegisterSysUserOnline(New())
}
func New() service.ISysUserOnline {
return &sSysUserOnline{
Pool: grpool.New(100),
}
}
type sSysUserOnline struct {
Pool *grpool.Pool
}
func (s *sSysUserOnline) Invoke(ctx context.Context, params *model.SysUserOnlineParams) {
s.Pool.Add(ctx, func(ctx context.Context) {
//写入数据
s.SaveOnline(ctx, params)
})
}
// SaveOnline 保存用户在线状态
func (s *sSysUserOnline) SaveOnline(ctx context.Context, params *model.SysUserOnlineParams) {
err := g.Try(ctx, func(ctx context.Context) {
ua := user_agent.New(params.UserAgent)
browser, _ := ua.Browser()
os := ua.OS()
var (
info *entity.SysUserOnline
data = &do.SysUserOnline{
Uuid: params.Uuid,
Token: params.Token,
CreateTime: gtime.Now(),
UserName: params.Username,
Ip: params.Ip,
Explorer: browser,
Os: os,
}
)
//查询是否已存在当前用户
err := dao.SysUserOnline.Ctx(ctx).Fields(dao.SysUserOnline.Columns().Id).
Where(dao.SysUserOnline.Columns().Token, data.Token).
Scan(&info)
liberr.ErrIsNil(ctx, err)
//若已存在则更新
if info != nil {
_, err = dao.SysUserOnline.Ctx(ctx).
Where(dao.SysUserOnline.Columns().Id, info.Id).
FieldsEx(dao.SysUserOnline.Columns().Id).Update(data)
liberr.ErrIsNil(ctx, err)
} else { //否则新增
_, err = dao.SysUserOnline.Ctx(ctx).
FieldsEx(dao.SysUserOnline.Columns().Id).Insert(data)
liberr.ErrIsNil(ctx, err)
}
})
if err != nil {
g.Log().Error(ctx, err)
}
}
// CheckUserOnline 检查在线用户
func (s *sSysUserOnline) CheckUserOnline(ctx context.Context) {
param := &system.SysUserOnlineSearchReq{
PageReq: common.PageReq{
PageReq: comModel.PageReq{
PageNum: 1,
PageSize: 50,
},
},
}
for {
var (
res *system.SysUserOnlineSearchRes
err error
)
res, err = s.GetOnlineListPage(ctx, param, true)
if err != nil {
g.Log().Error(ctx, err)
break
}
if res.List == nil {
break
}
for _, v := range res.List {
if b := s.UserIsOnline(ctx, v.Token); !b {
err = s.DeleteOnlineByToken(ctx, v.Token)
if err != nil {
g.Log().Error(ctx, err)
}
}
}
param.PageNum++
}
service.SysJobLog().Add(ctx, &do.SysJobLog{
TargetName: "checkUserOnline",
CreatedAt: gtime.Now(),
Result: "在线用户定时更新,执行成功",
})
}
// GetOnlineListPage 搜素在线用户列表
func (s *sSysUserOnline) GetOnlineListPage(ctx context.Context, req *system.SysUserOnlineSearchReq, hasToken ...bool) (res *system.SysUserOnlineSearchRes, err error) {
if req.PageNum == 0 {
req.PageNum = 1
}
if req.PageSize == 0 {
req.PageSize = consts.PageSize
}
model := dao.SysUserOnline.Ctx(ctx)
if req.Ip != "" {
model = model.Where("ip like ?", "%"+req.Ip+"%")
}
if req.Username != "" {
model = model.Where("user_name like ?", "%"+req.Username+"%")
}
res = new(system.SysUserOnlineSearchRes)
err = g.Try(ctx, func(ctx context.Context) {
res.Total, err = model.Count()
liberr.ErrIsNil(ctx, err, "获取总行数失败")
if len(hasToken) == 0 || !hasToken[0] {
model = model.FieldsEx("token")
}
err = model.Page(req.PageNum, req.PageSize).Order("create_time DESC").Scan(&res.List)
liberr.ErrIsNil(ctx, err, "获取数据失败")
})
return
}
func (s *sSysUserOnline) UserIsOnline(ctx context.Context, token string) bool {
err := g.Try(ctx, func(ctx context.Context) {
_, _, err := service.GfToken().GetTokenData(ctx, token)
liberr.ErrIsNil(ctx, err)
})
return err == nil
}
func (s *sSysUserOnline) DeleteOnlineByToken(ctx context.Context, token string) (err error) {
_, err = dao.SysUserOnline.Ctx(ctx).Delete(dao.SysUserOnline.Columns().Token, token)
return
}
func (s *sSysUserOnline) ForceLogout(ctx context.Context, ids []int) (err error) {
err = g.Try(ctx, func(ctx context.Context) {
var onlineList []*entity.SysUserOnline
onlineList, err = s.GetInfosByIds(ctx, ids)
liberr.ErrIsNil(ctx, err)
_, err = dao.SysUserOnline.Ctx(ctx).Where(dao.SysUserOnline.Columns().Id+" in(?)", ids).Delete()
liberr.ErrIsNil(ctx, err)
for _, v := range onlineList {
err = service.GfToken().RemoveToken(ctx, v.Token)
liberr.ErrIsNil(ctx, err)
}
})
return
}
func (s *sSysUserOnline) GetInfosByIds(ctx context.Context, ids []int) (onlineList []*entity.SysUserOnline, err error) {
err = dao.SysUserOnline.Ctx(ctx).Where(dao.SysUserOnline.Columns().Id+" in(?)", ids).Scan(&onlineList)
return
}