Files
web_template/internal/handler/access_log.go
2026-09-09 02:39:57 +08:00

108 lines
2.5 KiB
Go

package handler
import (
"strconv"
"gotest/internal/model"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
// AccessLogHandler 访问日志处理器
type AccessLogHandler struct {
db *gorm.DB
}
// NewAccessLogHandler 创建访问日志处理器
func NewAccessLogHandler(db *gorm.DB) *AccessLogHandler {
return &AccessLogHandler{db: db}
}
// ListLogs 获取访问日志列表 GET /api/v1/admin/access-logs
func (h *AccessLogHandler) ListLogs(c *gin.Context) {
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
ip := c.Query("ip")
path := c.Query("path")
if page < 1 {
page = 1
}
if pageSize < 1 || pageSize > 100 {
pageSize = 20
}
offset := (page - 1) * pageSize
query := h.db.Model(&model.AccessLog{})
if ip != "" {
query = query.Where("ip LIKE ?", "%"+ip+"%")
}
if path != "" {
query = query.Where("path LIKE ?", "%"+path+"%")
}
var total int64
query.Count(&total)
var logs []model.AccessLog
if err := query.Order("id DESC").Offset(offset).Limit(pageSize).Find(&logs).Error; err != nil {
FailInternal(c, "查询失败: "+err.Error())
return
}
Success(c, gin.H{
"list": logs,
"total": total,
"page": page,
"page_size": pageSize,
})
}
// GetStats 获取访问统计 GET /api/v1/admin/access-logs/stats
func (h *AccessLogHandler) GetStats(c *gin.Context) {
var totalVisits int64
h.db.Model(&model.AccessLog{}).Count(&totalVisits)
var todayVisits int64
h.db.Model(&model.AccessLog{}).Where("created_at >= date('now')").Count(&todayVisits)
var uniqueIPs int64
h.db.Model(&model.AccessLog{}).Distinct("ip").Count(&uniqueIPs)
// 最近 24 小时每小时访问量
type hourlyCount struct {
Hour string `json:"hour"`
Count int64 `json:"count"`
}
var hourly []hourlyCount
h.db.Model(&model.AccessLog{}).
Select("strftime('%Y-%m-%d %H:00', created_at) as hour, count(*) as count").
Where("created_at >= datetime('now', '-24 hours')").
Group("hour").
Order("hour ASC").
Scan(&hourly)
// 最近 10 条日志
var recent []model.AccessLog
h.db.Order("id DESC").Limit(10).Find(&recent)
Success(c, gin.H{
"total_visits": totalVisits,
"today_visits": todayVisits,
"unique_ips": uniqueIPs,
"hourly": hourly,
"recent": recent,
})
}
// DeleteLogs 清空访问日志 DELETE /api/v1/admin/access-logs
func (h *AccessLogHandler) DeleteLogs(c *gin.Context) {
if err := h.db.Where("1 = 1").Delete(&model.AccessLog{}).Error; err != nil {
FailInternal(c, "清空失败: "+err.Error())
return
}
SuccessMsg(c, "清空成功")
}