2025-07-10 21:14:17 +08:00
|
|
|
|
package handlers
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"net/http"
|
|
|
|
|
|
"strconv"
|
|
|
|
|
|
|
2025-07-17 14:08:52 +08:00
|
|
|
|
"github.com/ctwj/panResManage/db/converter"
|
|
|
|
|
|
"github.com/ctwj/panResManage/db/dto"
|
2025-07-10 21:14:17 +08:00
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// RecordSearch 记录搜索
|
|
|
|
|
|
func RecordSearch(c *gin.Context) {
|
|
|
|
|
|
var req dto.SearchStatRequest
|
|
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
2025-07-11 17:45:16 +08:00
|
|
|
|
ErrorResponse(c, err.Error(), http.StatusBadRequest)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取客户端IP和User-Agent
|
|
|
|
|
|
ip := c.ClientIP()
|
|
|
|
|
|
userAgent := c.GetHeader("User-Agent")
|
|
|
|
|
|
|
|
|
|
|
|
// 记录搜索
|
|
|
|
|
|
err := repoManager.SearchStatRepository.RecordSearch(req.Keyword, ip, userAgent)
|
|
|
|
|
|
if err != nil {
|
2025-07-11 17:45:16 +08:00
|
|
|
|
ErrorResponse(c, "记录搜索失败", http.StatusInternalServerError)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-11 17:45:16 +08:00
|
|
|
|
SuccessResponse(c, gin.H{"message": "搜索记录成功"})
|
2025-07-10 21:14:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-11 17:45:16 +08:00
|
|
|
|
// GetSearchStats 获取搜索统计(使用全局repoManager)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
func GetSearchStats(c *gin.Context) {
|
2025-07-11 17:45:16 +08:00
|
|
|
|
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
|
|
|
|
|
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
2025-07-10 21:14:17 +08:00
|
|
|
|
|
2025-07-11 17:45:16 +08:00
|
|
|
|
stats, total, err := repoManager.SearchStatRepository.FindWithPagination(page, pageSize)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
if err != nil {
|
2025-07-11 17:45:16 +08:00
|
|
|
|
ErrorResponse(c, "获取搜索统计失败", http.StatusInternalServerError)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-11 17:45:16 +08:00
|
|
|
|
response := converter.ToSearchStatResponseList(stats)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
|
2025-07-11 17:45:16 +08:00
|
|
|
|
SuccessResponse(c, gin.H{
|
|
|
|
|
|
"data": response,
|
|
|
|
|
|
"total": int(total),
|
|
|
|
|
|
})
|
2025-07-10 21:14:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-11 17:45:16 +08:00
|
|
|
|
// GetHotKeywords 获取热门关键词(使用全局repoManager)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
func GetHotKeywords(c *gin.Context) {
|
|
|
|
|
|
daysStr := c.DefaultQuery("days", "30")
|
|
|
|
|
|
limitStr := c.DefaultQuery("limit", "10")
|
|
|
|
|
|
|
|
|
|
|
|
days, err := strconv.Atoi(daysStr)
|
|
|
|
|
|
if err != nil {
|
2025-07-11 17:45:16 +08:00
|
|
|
|
ErrorResponse(c, "无效的天数参数", http.StatusBadRequest)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
limit, err := strconv.Atoi(limitStr)
|
|
|
|
|
|
if err != nil {
|
2025-07-11 17:45:16 +08:00
|
|
|
|
ErrorResponse(c, "无效的限制参数", http.StatusBadRequest)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
keywords, err := repoManager.SearchStatRepository.GetHotKeywords(days, limit)
|
|
|
|
|
|
if err != nil {
|
2025-07-11 17:45:16 +08:00
|
|
|
|
ErrorResponse(c, "获取热门关键词失败", http.StatusInternalServerError)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
response := converter.ToHotKeywordResponseList(keywords)
|
2025-07-11 17:45:16 +08:00
|
|
|
|
SuccessResponse(c, response)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-11 17:45:16 +08:00
|
|
|
|
// GetDailyStats 获取每日统计(使用全局repoManager)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
func GetDailyStats(c *gin.Context) {
|
|
|
|
|
|
daysStr := c.DefaultQuery("days", "30")
|
|
|
|
|
|
|
|
|
|
|
|
days, err := strconv.Atoi(daysStr)
|
|
|
|
|
|
if err != nil {
|
2025-07-11 17:45:16 +08:00
|
|
|
|
ErrorResponse(c, "无效的天数参数", http.StatusBadRequest)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
stats, err := repoManager.SearchStatRepository.GetDailyStats(days)
|
|
|
|
|
|
if err != nil {
|
2025-07-11 17:45:16 +08:00
|
|
|
|
ErrorResponse(c, "获取每日统计失败", http.StatusInternalServerError)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
response := converter.ToDailySearchStatResponseList(stats)
|
2025-07-11 17:45:16 +08:00
|
|
|
|
SuccessResponse(c, response)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-11 17:45:16 +08:00
|
|
|
|
// GetSearchTrend 获取搜索趋势(使用全局repoManager)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
func GetSearchTrend(c *gin.Context) {
|
|
|
|
|
|
daysStr := c.DefaultQuery("days", "30")
|
|
|
|
|
|
|
|
|
|
|
|
days, err := strconv.Atoi(daysStr)
|
|
|
|
|
|
if err != nil {
|
2025-07-11 17:45:16 +08:00
|
|
|
|
ErrorResponse(c, "无效的天数参数", http.StatusBadRequest)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
trend, err := repoManager.SearchStatRepository.GetSearchTrend(days)
|
|
|
|
|
|
if err != nil {
|
2025-07-11 17:45:16 +08:00
|
|
|
|
ErrorResponse(c, "获取搜索趋势失败", http.StatusInternalServerError)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
response := converter.ToDailySearchStatResponseList(trend)
|
2025-07-11 17:45:16 +08:00
|
|
|
|
SuccessResponse(c, response)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-11 17:45:16 +08:00
|
|
|
|
// GetKeywordTrend 获取关键词趋势(使用全局repoManager)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
func GetKeywordTrend(c *gin.Context) {
|
|
|
|
|
|
keyword := c.Param("keyword")
|
|
|
|
|
|
if keyword == "" {
|
2025-07-11 17:45:16 +08:00
|
|
|
|
ErrorResponse(c, "关键词不能为空", http.StatusBadRequest)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
daysStr := c.DefaultQuery("days", "30")
|
|
|
|
|
|
days, err := strconv.Atoi(daysStr)
|
|
|
|
|
|
if err != nil {
|
2025-07-11 17:45:16 +08:00
|
|
|
|
ErrorResponse(c, "无效的天数参数", http.StatusBadRequest)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
trend, err := repoManager.SearchStatRepository.GetKeywordTrend(keyword, days)
|
|
|
|
|
|
if err != nil {
|
2025-07-11 17:45:16 +08:00
|
|
|
|
ErrorResponse(c, "获取关键词趋势失败", http.StatusInternalServerError)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
response := converter.ToDailySearchStatResponseList(trend)
|
2025-07-11 17:45:16 +08:00
|
|
|
|
SuccessResponse(c, response)
|
2025-07-10 21:14:17 +08:00
|
|
|
|
}
|