🎨 新增用户登录日志记录
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
common "git.echol.cn/loser/lckt/model/common/request"
|
||||
user2 "git.echol.cn/loser/lckt/model/user"
|
||||
"gorm.io/gorm"
|
||||
"strconv"
|
||||
"time"
|
||||
@@ -67,6 +68,24 @@ func (*AppUserApi) Login(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 添加登录日志
|
||||
loginLog := user2.LoginLog{
|
||||
UserId: user.ID,
|
||||
UserName: user.NickName,
|
||||
Phone: user.Phone,
|
||||
Ip: ctx.ClientIP(),
|
||||
Address: utils.GetIPAdcode(ctx.ClientIP()),
|
||||
Device: ctx.Request.Header.Get("sec-ch-ua-platform"),
|
||||
UserAgent: ctx.Request.UserAgent(),
|
||||
Mode: "微信登录",
|
||||
LoginTime: time.Now().Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
|
||||
err = global.GVA_DB.Create(&loginLog).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("添加登录日志失败!", zap.Error(err))
|
||||
}
|
||||
|
||||
if _, err = global.GVA_REDIS.Get(ctx, strconv.Itoa(int(user.ID))).Result(); errors.Is(err, redis.Nil) {
|
||||
// 此处过期时间等于jwt过期时间
|
||||
dr, err := utils.ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)
|
||||
@@ -132,6 +151,24 @@ func (*AppUserApi) WechatLogin(ctx *gin.Context) {
|
||||
}
|
||||
user_jwt.SetToken(ctx, token, int(claims.RegisteredClaims.ExpiresAt.Unix()-time.Now().Unix()))
|
||||
|
||||
// 添加登录日志
|
||||
loginLog := user2.LoginLog{
|
||||
UserId: user.ID,
|
||||
UserName: user.NickName,
|
||||
Phone: user.Phone,
|
||||
Ip: ctx.ClientIP(),
|
||||
Address: utils.GetIPAdcode(ctx.ClientIP()),
|
||||
Device: ctx.Request.Header.Get("sec-ch-ua-platform"),
|
||||
UserAgent: ctx.Request.UserAgent(),
|
||||
Mode: "微信登录",
|
||||
LoginTime: time.Now().Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
|
||||
err = global.GVA_DB.Create(&loginLog).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("添加登录日志失败!", zap.Error(err))
|
||||
}
|
||||
|
||||
r.OkWithDetailed(gin.H{
|
||||
"User": user,
|
||||
"Token": token,
|
||||
|
@@ -171,3 +171,28 @@ func (a *UserApi) UpdateTeacherApplyStatus(context *gin.Context) {
|
||||
}
|
||||
r.OkWithMessage("更新教师申请状态成功", context)
|
||||
}
|
||||
|
||||
// GetLoginLog 获取用户登录日志
|
||||
func (a *UserApi) GetLoginLog(context *gin.Context) {
|
||||
var p request.GetUserListReq
|
||||
if err := context.ShouldBind(&p); err != nil {
|
||||
global.GVA_LOG.Error("参数错误,获取登录日志失败", zap.Error(err))
|
||||
r.FailWithMessage("参数错误,获取登录日志失败", context)
|
||||
return
|
||||
}
|
||||
|
||||
logs, total, err := userService.GetLoginLog(p)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取登录日志失败", zap.Error(err))
|
||||
r.FailWithMessage("获取登录日志失败", context)
|
||||
return
|
||||
}
|
||||
|
||||
r.OkWithDetailed(
|
||||
r.PageResult{
|
||||
List: logs,
|
||||
Total: total,
|
||||
Page: p.Page,
|
||||
PageSize: p.PageSize,
|
||||
}, "获取登录日志成功", context)
|
||||
}
|
||||
|
@@ -83,6 +83,7 @@ func RegisterTables() {
|
||||
app.Follow{},
|
||||
app.TeacherVip{},
|
||||
app.UserTeacherVip{},
|
||||
user.LoginLog{},
|
||||
)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("register table failed", zap.Error(err))
|
||||
|
22
model/user/login_log.go
Normal file
22
model/user/login_log.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package user
|
||||
|
||||
import "git.echol.cn/loser/lckt/global"
|
||||
|
||||
type LoginLog struct {
|
||||
global.GVA_MODEL
|
||||
UserId uint `json:"user_id" gorm:"comment:用户ID;index"`
|
||||
UserName string `json:"user_name" gorm:"comment:用户登录名"`
|
||||
Phone string `json:"phone" gorm:"comment:用户手机号"`
|
||||
Ip string `json:"ip" gorm:"comment:登录IP"`
|
||||
Address string `json:"address" gorm:"comment:登录地址"`
|
||||
UserAgent string `json:"user_agent" gorm:"comment:用户代理"`
|
||||
// 登录设备
|
||||
Device string `json:"device" gorm:"comment:登录设备"`
|
||||
// 登录方式
|
||||
Mode string `json:"mode" gorm:"comment:登录方式"`
|
||||
LoginTime string `json:"login_time" gorm:"comment:登录时间"`
|
||||
}
|
||||
|
||||
func (LoginLog) TableName() string {
|
||||
return "user_login_log"
|
||||
}
|
@@ -43,6 +43,7 @@ type BindPhoneReq struct {
|
||||
|
||||
type GetUserListReq struct {
|
||||
request.PageInfo
|
||||
UserId uint `json:"user_id" form:"user_id"`
|
||||
Type int `json:"type" form:"type"`
|
||||
UserLabel string `json:"user_label" form:"user_label" `
|
||||
Status int `json:"status" form:"status"`
|
||||
|
@@ -20,5 +20,6 @@ func (s *UserRouter) InitUserRouter(Router *gin.RouterGroup, PublicRouter *gin.R
|
||||
userRouter.GET("/teachers", userApi.GetTeachers) // 获取教师列表
|
||||
userRouter.GET("/teacherApplyList", userApi.GetTeacherApplyList) // 获取教师申请列表
|
||||
userRouter.PUT("/teacherApply/status", userApi.UpdateTeacherApplyStatus) // 更新教师申请状态
|
||||
userRouter.GET("/login/log", userApi.GetLoginLog) // 获取用户登录日志
|
||||
}
|
||||
}
|
||||
|
@@ -248,3 +248,27 @@ func (u *UserService) SetUserVip(p request.SetUserVipReq) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UserService) GetLoginLog(p request.GetUserListReq) (list []user.LoginLog, total int64, err error) {
|
||||
limit := p.PageSize
|
||||
offset := (p.Page - 1) * p.PageSize
|
||||
db := global.GVA_DB.Model(&user.LoginLog{})
|
||||
|
||||
if p.UserId != 0 {
|
||||
db = db.Where("user_id = ?", p.UserId)
|
||||
}
|
||||
if p.Name != "" {
|
||||
db = db.Where("user_name LIKE ?", "%"+p.Name+"%")
|
||||
}
|
||||
err = db.Count(&total).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询登录日志总数失败", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
err = db.Limit(limit).Offset(offset).Order("created_at desc").Find(&list).Error
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("查询登录日志列表失败", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
29
utils/ip.go
Normal file
29
utils/ip.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ipAdcodeResp struct {
|
||||
Adcode struct {
|
||||
O string `json:"o"`
|
||||
} `json:"adcode"`
|
||||
}
|
||||
|
||||
func GetIPAdcode(ip string) string {
|
||||
url := fmt.Sprintf("https://api.vore.top/api/IPdata?ip=%s", ip)
|
||||
client := &http.Client{Timeout: 5 * time.Second}
|
||||
resp, err := client.Get(url)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
var result ipAdcodeResp
|
||||
if err = json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
return ""
|
||||
}
|
||||
return result.Adcode.O
|
||||
}
|
Reference in New Issue
Block a user