feat: 完成"登录日志"和"操作日志"接口

This commit is contained in:
geeknonerd
2023-01-08 15:42:13 +08:00
parent cd958ce718
commit 3ccbe3f9d2
7 changed files with 214 additions and 21 deletions

View File

@@ -4,6 +4,7 @@ import (
"github.com/gin-gonic/gin"
"likeadmin/core"
"likeadmin/core/response"
"likeadmin/middleware"
"likeadmin/util"
"strings"
)
@@ -12,8 +13,8 @@ var MonitorGroup = core.Group("/monitor")
func init() {
group := MonitorGroup
group.AddGET("/cache", cache)
group.AddGET("/server", server)
group.AddGET("/cache", cache, middleware.RecordLog("缓存监控"))
group.AddGET("/server", server, middleware.RecordLog("服务监控"))
}
//cache 缓存监控

View File

@@ -38,6 +38,8 @@ func init() {
group.AddPOST("/menu/add", menuAdd)
group.AddPOST("/menu/edit", menuEdit)
group.AddPOST("/menu/del", menuDel)
group.AddGET("/log/operate", logOperate)
group.AddGET("/log/login", logLogin)
}
//login 登录系统
@@ -202,3 +204,21 @@ func menuDel(c *gin.Context) {
system.SystemAuthMenuService.Del(delReq.ID)
response.Ok(c)
}
//logOperate 操作日志
func logOperate(c *gin.Context) {
var page request.PageReq
var logReq req.SystemLogOperateReq
util.VerifyUtil.VerifyQuery(c, &page)
util.VerifyUtil.VerifyQuery(c, &logReq)
response.OkWithData(c, system.SystemLogsServer.Operate(page, logReq))
}
//logLogin 登录日志
func logLogin(c *gin.Context) {
var page request.PageReq
var logReq req.SystemLogLoginReq
util.VerifyUtil.VerifyQuery(c, &page)
util.VerifyUtil.VerifyQuery(c, &logReq)
response.OkWithData(c, system.SystemLogsServer.Login(page, logReq))
}

View File

@@ -1,5 +1,9 @@
package req
import (
"time"
)
//SystemLoginReq 系统登录参数
type SystemLoginReq struct {
Username string `json:"username" binding:"required,min=2,max=20"` // 账号
@@ -143,3 +147,23 @@ type SystemAuthMenuEditReq struct {
type SystemAuthMenuDelReq struct {
ID uint `form:"id" binding:"required,gt=0"` // 主键
}
//SystemLogOperateReq 操作日志列表参数
type SystemLogOperateReq struct {
Title string `form:"title"` // 操作标题
Username string `form:"username"` // 用户账号
Ip string `form:"ip"` // 请求IP
Type string `form:"type" binding:"omitempty,oneof=GET POST PUT"` // 请求类型: GET/POST/PUT
Status int `form:"status" binding:"omitempty,oneof=1 2"` // 执行状态: [1=成功, 2=失败]
Url string `form:"url"` // 请求地址
StartTime time.Time `form:"startTime" time_format:"2006-01-02"` // 开始时间
EndTime time.Time `form:"endTime" time_format:"2006-01-02"` // 结束时间
}
//SystemLogLoginReq 登录日志列表参数
type SystemLogLoginReq struct {
Username string `form:"username"` // 登录账号
Status int `form:"status" binding:"omitempty,oneof=1 2"` // 执行状态: [1=成功, 2=失败]
StartTime time.Time `form:"startTime" time_format:"2006-01-02"` // 开始时间
EndTime time.Time `form:"endTime" time_format:"2006-01-02"` // 结束时间
}

View File

@@ -94,3 +94,33 @@ type SystemAuthMenuResp struct {
UpdateTime core.TsTime `json:"updateTime" structs:"updateTime"` // 更新时间
Children []SystemAuthMenuResp `json:"children,omitempty" structs:"children"` // 子集
}
//SystemLogOperateResp 操作日志返回信息
type SystemLogOperateResp struct {
ID uint `json:"id" structs:"id"` // 主键
Username string `json:"username" structs:"username"` // 用户账号
Nickname string `json:"nickname" structs:"nickname"` // 用户昵称
Type string `json:"type" structs:"type"` // 请求类型: GET/POST/PUT
Title string `json:"title" structs:"title"` // 操作标题
Method string `json:"method" structs:"method"` // 请求方式
Ip string `json:"ip" structs:"ip"` // 请求IP
Url string `json:"url" structs:"url"` // 请求地址
Args string `json:"args" structs:"args"` // 请求参数
Error string `json:"error" structs:"error"` // 错误信息
Status int `json:"status" structs:"status"` // 执行状态: [1=成功, 2=失败]
TaskTime string `json:"taskTime" structs:"taskTime"` // 执行耗时
StartTime core.TsTime `json:"startTime" structs:"startTime"` // 开始时间
EndTime core.TsTime `json:"endTime" structs:"endTime"` // 结束时间
CreateTime core.TsTime `json:"createTime" structs:"createTime"` // 创建时间
}
//SystemLogLoginResp 登录日志返回信息
type SystemLogLoginResp struct {
ID uint `json:"id" structs:"id"` // 主键
Username string `json:"username" structs:"username"` // 登录账号
Ip string `json:"ip" structs:"ip"` // 来源IP
Os string `json:"os" structs:"os"` // 操作系统
Browser string `json:"browser" structs:"browser"` // 浏览器
Status int `json:"status" structs:"status"` // 操作状态: [1=成功, 2=失败]
CreateTime core.TsTime `json:"createTime" structs:"createTime"` // 创建时间
}

View File

@@ -0,0 +1,116 @@
package system
import (
"fmt"
"likeadmin/admin/schemas/req"
"likeadmin/admin/schemas/resp"
"likeadmin/core"
"likeadmin/core/request"
"likeadmin/core/response"
"likeadmin/model/system"
)
var SystemLogsServer = systemLogsServer{}
//systemAuthMenuService 系统日志服务实现类
type systemLogsServer struct{}
//Operate 系统操作日志
func (logSrv systemLogsServer) Operate(page request.PageReq, logReq req.SystemLogOperateReq) response.PageResp {
// 分页信息
var res response.PageResp
response.Copy(&res, page)
limit := page.PageSize
offset := page.PageSize * (page.PageNo - 1)
// 查询
logTbName := core.DBTableName(&system.SystemLogOperate{})
adminTbName := core.DBTableName(&system.SystemAuthAdmin{})
logModel := core.DB.Table(logTbName + " AS log").Joins(
fmt.Sprintf("LEFT JOIN %s AS admin ON log.admin_id = admin.id", adminTbName)).Select(
"log.*, admin.username, admin.nickname")
// 条件
if logReq.Title != "" {
logModel = logModel.Where("title like ?", "%"+logReq.Title+"%")
}
if logReq.Username != "" {
logModel = logModel.Where("username like ?", "%"+logReq.Username+"%")
}
if logReq.Ip != "" {
logModel = logModel.Where("ip like ?", "%"+logReq.Ip+"%")
}
if logReq.Type != "" {
logModel = logModel.Where("type = ?", logReq.Type)
}
if logReq.Status > 0 {
logModel = logModel.Where("status = ?", logReq.Status)
}
if logReq.Url != "" {
logModel = logModel.Where("url = ?", logReq.Url)
}
if !logReq.StartTime.IsZero() {
logModel = logModel.Where("log.create_time >= ?", logReq.StartTime.Unix())
}
if !logReq.EndTime.IsZero() {
logModel = logModel.Where("log.create_time <= ?", logReq.EndTime.Unix())
}
// 总数
var count int64
if err := logModel.Count(&count).Error; err != nil {
core.Logger.Errorf("Operate Count err: err=[%+v]", err)
panic(response.SystemError)
}
// 数据
var logResp []resp.SystemLogOperateResp
if err := logModel.Limit(limit).Offset(offset).Order("id desc").Find(&logResp).Error; err != nil {
core.Logger.Errorf("Operate Find err: err=[%+v]", err)
panic(response.SystemError)
}
return response.PageResp{
PageNo: page.PageNo,
PageSize: page.PageSize,
Count: count,
Lists: logResp,
}
}
//Login 系统登录日志
func (logSrv systemLogsServer) Login(page request.PageReq, logReq req.SystemLogLoginReq) response.PageResp {
// 分页信息
var res response.PageResp
response.Copy(&res, page)
limit := page.PageSize
offset := page.PageSize * (page.PageNo - 1)
// 查询
logModel := core.DB.Model(&system.SystemLogLogin{})
// 条件
if logReq.Username != "" {
logModel = logModel.Where("username like ?", "%"+logReq.Username+"%")
}
if logReq.Status > 0 {
logModel = logModel.Where("status = ?", logReq.Status)
}
if !logReq.StartTime.IsZero() {
logModel = logModel.Where("create_time >= ?", logReq.StartTime.Unix())
}
if !logReq.EndTime.IsZero() {
logModel = logModel.Where("create_time <= ?", logReq.EndTime.Unix())
}
// 总数
var count int64
if err := logModel.Count(&count).Error; err != nil {
core.Logger.Errorf("Login Count err: err=[%+v]", err)
panic(response.SystemError)
}
// 数据
var logResp []resp.SystemLogLoginResp
if err := logModel.Limit(limit).Offset(offset).Order("id desc").Find(&logResp).Error; err != nil {
core.Logger.Errorf("Login Find err: err=[%+v]", err)
panic(response.SystemError)
}
return response.PageResp{
PageNo: page.PageNo,
PageSize: page.PageSize,
Count: count,
Lists: logResp,
}
}

View File

@@ -18,7 +18,9 @@ func initMysql() *gorm.DB {
// 日志配置
slowThreshold := time.Second
ignoreRecordNotFoundError := true
logLevel := logger.Warn
if config.Config.GinMode == "debug" {
logLevel = logger.Info
slowThreshold = 200 * time.Millisecond
ignoreRecordNotFoundError = false
}
@@ -26,7 +28,7 @@ func initMysql() *gorm.DB {
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer日志输出的目标前缀和日志包含的内容——译者注
logger.Config{
SlowThreshold: slowThreshold, // 慢 SQL 阈值
LogLevel: logger.Warn, // 日志级别
LogLevel: logLevel, // 日志级别
IgnoreRecordNotFoundError: ignoreRecordNotFoundError, // 忽略ErrRecordNotFound记录未找到错误
Colorful: true, // 彩色打印
},

View File

@@ -8,27 +8,27 @@ import (
const DateFormat = "2006-01-02"
const TimeFormat = "2006-01-02 15:04:05"
//TsDate 自定义日期格式
type TsDate int64
//TsTime 自定义时间格式
type TsTime int64
func (tsd *TsDate) UnmarshalJSON(bs []byte) error {
var date string
err := json.Unmarshal(bs, &date)
if err != nil {
return err
}
tt, _ := time.ParseInLocation(DateFormat, date, time.Local)
*tsd = TsDate(tt.Unix())
return nil
}
func (tsd TsDate) MarshalJSON() ([]byte, error) {
tt := time.Unix(int64(tsd), 0).Format(DateFormat)
return json.Marshal(tt)
}
////TsDate 自定义日期格式
//type TsDate int64
//
//func (tsd *TsDate) UnmarshalJSON(bs []byte) error {
// var date string
// err := json.Unmarshal(bs, &date)
// if err != nil {
// return err
// }
// tt, _ := time.ParseInLocation(DateFormat, date, time.Local)
// *tsd = TsDate(tt.Unix())
// return nil
//}
//
//func (tsd TsDate) MarshalJSON() ([]byte, error) {
// tt := time.Unix(int64(tsd), 0).Format(DateFormat)
// return json.Marshal(tt)
//}
func (tst *TsTime) UnmarshalJSON(bs []byte) error {
var date string