2025-07-10 13:58:28 +08:00
package handlers
import (
2025-07-11 17:45:16 +08:00
"runtime"
"time"
2025-07-10 13:58:28 +08:00
2025-07-18 09:42:07 +08:00
"github.com/ctwj/urldb/db"
"github.com/ctwj/urldb/db/entity"
2025-07-23 12:31:45 +08:00
"github.com/ctwj/urldb/utils"
2025-07-10 13:58:28 +08:00
"github.com/gin-gonic/gin"
)
2025-07-11 17:45:16 +08:00
// GetStats 获取基础统计信息
2025-07-10 13:58:28 +08:00
func GetStats ( c * gin . Context ) {
2025-07-11 18:37:28 +08:00
// 设置响应头,启用缓存
c . Header ( "Cache-Control" , "public, max-age=60" ) // 1分钟缓存
2025-07-11 17:45:16 +08:00
// 获取数据库统计
var totalResources , totalCategories , totalTags , totalViews int64
db . DB . Model ( & entity . Resource { } ) . Count ( & totalResources )
db . DB . Model ( & entity . Category { } ) . Count ( & totalCategories )
db . DB . Model ( & entity . Tag { } ) . Count ( & totalTags )
db . DB . Model ( & entity . Resource { } ) . Select ( "COALESCE(SUM(view_count), 0)" ) . Scan ( & totalViews )
2025-07-10 13:58:28 +08:00
2025-10-19 08:56:11 +08:00
// 获取今日数据( 在UTC+8时区的0点开始统计)
now := utils . GetCurrentTime ( )
// 使用UTC+8时区的今天0点
loc , _ := time . LoadLocation ( "Asia/Shanghai" ) // UTC+8
startOfToday := time . Date ( now . Year ( ) , now . Month ( ) , now . Day ( ) , 0 , 0 , 0 , 0 , loc )
endOfToday := startOfToday . Add ( 24 * time . Hour )
2025-08-08 01:28:25 +08:00
2025-10-19 08:56:11 +08:00
// 今日新增资源数量( 从0点开始)
2025-08-08 01:28:25 +08:00
var todayResources int64
2025-10-19 08:56:11 +08:00
db . DB . Model ( & entity . Resource { } ) . Where ( "created_at >= ? AND created_at < ?" , startOfToday , endOfToday ) . Count ( & todayResources )
2025-08-08 01:28:25 +08:00
2025-10-19 08:56:11 +08:00
// 今日更新资源数量( 包括新增和修改, 从0点开始)
2025-08-11 01:34:07 +08:00
var todayUpdates int64
2025-10-19 08:56:11 +08:00
db . DB . Model ( & entity . Resource { } ) . Where ( "updated_at >= ? AND updated_at < ?" , startOfToday , endOfToday ) . Count ( & todayUpdates )
2025-08-11 01:34:07 +08:00
2025-08-08 01:28:25 +08:00
// 今日浏览量 - 使用访问记录表统计今日访问量
var todayViews int64
todayViews , err := repoManager . ResourceViewRepository . GetTodayViews ( )
if err != nil {
utils . Error ( "获取今日访问量失败: %v" , err )
todayViews = 0
}
2025-10-19 08:56:11 +08:00
// 今日搜索量( 从0点开始)
2025-08-08 01:28:25 +08:00
var todaySearches int64
2025-10-19 08:56:11 +08:00
db . DB . Model ( & entity . SearchStat { } ) . Where ( "date >= ? AND date < ?" , startOfToday . Format ( utils . TimeFormatDate ) , endOfToday . Format ( utils . TimeFormatDate ) ) . Count ( & todaySearches )
2025-08-08 01:28:25 +08:00
// 添加调试日志
utils . Info ( "统计数据 - 总资源: %d, 总分类: %d, 总标签: %d, 总浏览量: %d" ,
totalResources , totalCategories , totalTags , totalViews )
2025-08-11 01:34:07 +08:00
utils . Info ( "今日数据 - 新增资源: %d, 今日更新: %d, 今日浏览量: %d, 今日搜索: %d" ,
todayResources , todayUpdates , todayViews , todaySearches )
2025-07-20 11:00:17 +08:00
2025-07-11 17:45:16 +08:00
SuccessResponse ( c , gin . H {
"total_resources" : totalResources ,
"total_categories" : totalCategories ,
"total_tags" : totalTags ,
"total_views" : totalViews ,
2025-08-08 01:28:25 +08:00
"today_resources" : todayResources ,
2025-08-11 01:34:07 +08:00
"today_updates" : todayUpdates ,
2025-08-08 01:28:25 +08:00
"today_views" : todayViews ,
"today_searches" : todaySearches ,
2025-07-11 17:45:16 +08:00
} )
}
2025-07-10 13:58:28 +08:00
2025-07-11 17:45:16 +08:00
// GetPerformanceStats 获取性能监控信息
func GetPerformanceStats ( c * gin . Context ) {
var m runtime . MemStats
runtime . ReadMemStats ( & m )
2025-07-10 13:58:28 +08:00
2025-07-11 17:45:16 +08:00
// 获取数据库连接池状态
sqlDB , err := db . DB . DB ( )
var dbStats gin . H
if err == nil {
2025-07-23 12:31:45 +08:00
stats := sqlDB . Stats ( )
2025-07-11 17:45:16 +08:00
dbStats = gin . H {
2025-07-23 12:31:45 +08:00
"max_open_connections" : stats . MaxOpenConnections ,
"open_connections" : stats . OpenConnections ,
"in_use" : stats . InUse ,
"idle" : stats . Idle ,
"wait_count" : stats . WaitCount ,
"wait_duration" : stats . WaitDuration ,
2025-07-11 17:45:16 +08:00
}
2025-07-23 12:31:45 +08:00
// 添加调试日志
utils . Info ( "数据库连接池状态 - MaxOpen: %d, Open: %d, InUse: %d, Idle: %d" ,
stats . MaxOpenConnections , stats . OpenConnections , stats . InUse , stats . Idle )
2025-07-11 17:45:16 +08:00
} else {
dbStats = gin . H {
2025-07-23 12:31:45 +08:00
"error" : "无法获取数据库连接池状态: " + err . Error ( ) ,
2025-07-11 17:45:16 +08:00
}
2025-07-23 12:31:45 +08:00
utils . Error ( "获取数据库连接池状态失败: %v" , err )
2025-07-10 13:58:28 +08:00
}
2025-07-11 17:45:16 +08:00
SuccessResponse ( c , gin . H {
2025-07-29 14:00:01 +08:00
"timestamp" : utils . GetCurrentTime ( ) . Unix ( ) ,
2025-07-11 17:45:16 +08:00
"memory" : gin . H {
"alloc" : m . Alloc ,
"total_alloc" : m . TotalAlloc ,
"sys" : m . Sys ,
"num_gc" : m . NumGC ,
"heap_alloc" : m . HeapAlloc ,
"heap_sys" : m . HeapSys ,
"heap_idle" : m . HeapIdle ,
"heap_inuse" : m . HeapInuse ,
} ,
"goroutines" : runtime . NumGoroutine ( ) ,
"database" : dbStats ,
"system" : gin . H {
"cpu_count" : runtime . NumCPU ( ) ,
"go_version" : runtime . Version ( ) ,
} ,
} )
}
2025-07-10 13:58:28 +08:00
2025-07-11 17:45:16 +08:00
// GetSystemInfo 获取系统信息
func GetSystemInfo ( c * gin . Context ) {
SuccessResponse ( c , gin . H {
"uptime" : time . Since ( startTime ) . String ( ) ,
2025-08-11 01:34:07 +08:00
"start_time" : utils . FormatTime ( startTime , utils . TimeFormatDateTime ) ,
2025-07-27 08:06:55 +08:00
"version" : utils . Version ,
2025-07-11 17:45:16 +08:00
"environment" : gin . H {
"gin_mode" : gin . Mode ( ) ,
} ,
} )
2025-07-10 13:58:28 +08:00
}
2025-07-11 17:45:16 +08:00
2025-08-07 18:47:26 +08:00
// GetViewsTrend 获取访问量趋势数据
func GetViewsTrend ( c * gin . Context ) {
2025-08-08 01:28:25 +08:00
// 使用访问记录表获取最近7天的访问量数据
results , err := repoManager . ResourceViewRepository . GetViewsTrend ( 7 )
if err != nil {
utils . Error ( "获取访问量趋势数据失败: %v" , err )
// 如果获取失败,返回空数据
results = [ ] map [ string ] interface { } { }
2025-08-07 18:47:26 +08:00
}
// 添加调试日志
utils . Info ( "访问量趋势数据: %+v" , results )
for i , result := range results {
utils . Info ( "第%d天: 日期=%s, 访问量=%d" , i + 1 , result [ "date" ] , result [ "views" ] )
}
SuccessResponse ( c , results )
}
// GetSearchesTrend 获取搜索量趋势数据
func GetSearchesTrend ( c * gin . Context ) {
// 获取最近7天的搜索量数据
var results [ ] gin . H
// 生成最近7天的日期
for i := 6 ; i >= 0 ; i -- {
date := utils . GetCurrentTime ( ) . AddDate ( 0 , 0 , - i )
2025-08-11 01:34:07 +08:00
dateStr := date . Format ( utils . TimeFormatDate )
2025-08-07 18:47:26 +08:00
// 查询该日期的搜索量(从搜索统计表)
var searches int64
db . DB . Model ( & entity . SearchStat { } ) .
Where ( "DATE(date) = ?" , dateStr ) .
Count ( & searches )
2025-08-12 00:27:10 +08:00
// 如果没有搜索记录, 返回0
// 移除模拟数据生成逻辑,只返回真实数据
2025-08-07 18:47:26 +08:00
results = append ( results , gin . H {
"date" : dateStr ,
"searches" : searches ,
} )
}
// 添加调试日志
utils . Info ( "搜索量趋势数据: %+v" , results )
// 添加更详细的调试信息
for i , result := range results {
utils . Info ( "第%d天: 日期=%s, 搜索量=%d" , i + 1 , result [ "date" ] , result [ "searches" ] )
}
SuccessResponse ( c , results )
}
2025-07-11 17:45:16 +08:00
// 记录启动时间
2025-07-29 14:00:01 +08:00
var startTime = utils . GetCurrentTime ( )