优化页面、修复BUG

This commit is contained in:
李琦
2026-06-24 16:50:04 +08:00
parent 88ba9be318
commit 3f653bc336
36 changed files with 1672 additions and 2401 deletions

View File

@@ -139,57 +139,63 @@ func GetPost(c *gin.Context) {
// 构建响应,包含内容
response := repositories.BuildPostResponse(post, true)
// 记录用户访问日志 (异步执行,不阻塞响应)
go func() {
// 添加 panic recover 保护
defer func() {
if r := recover(); r != nil {
log.Printf("Panic in user access log goroutine for post %d: %v", post.ID, r)
}
}()
visitorKey := utils.GetOrSetVisitorID(c)
// 获取客户端IP
ip := c.ClientIP()
var userID uint = 0
if uid, exists := c.Get("userID"); exists {
userID = uid.(uint)
}
// 获取归属地,使用 recover 保护
var location string
func() {
alreadyVisited, err := repositories.HasVisitedThisHour(post.ID, userID, visitorKey)
if err != nil {
log.Printf("Failed to check visit dedup for post %d: %v", post.ID, err)
}
if !alreadyVisited {
if err := repositories.IncrementReadCount(post.ID); err != nil {
log.Printf("Failed to increment read count for post %d: %v", post.ID, err)
} else {
response.ReadCount++
}
// 记录用户访问日志 (异步执行,不阻塞响应)
go func() {
defer func() {
if r := recover(); r != nil {
log.Printf("Panic in GetRegion for IP %s (post %d): %v", ip, post.ID, r)
location = "Unknown"
log.Printf("Panic in user access log goroutine for post %d: %v", post.ID, r)
}
}()
location = utils.GetRegion(ip)
ip := c.ClientIP()
var location string
func() {
defer func() {
if r := recover(); r != nil {
log.Printf("Panic in GetRegion for IP %s (post %d): %v", ip, post.ID, r)
location = "Unknown"
}
}()
location = utils.GetRegion(ip)
}()
if location == "" {
location = "Unknown"
}
logEntry := &models.UserAccessLog{
UserID: userID,
UserIP: ip,
UserLocation: location,
ArticleID: post.ID,
VisitorKey: visitorKey,
}
if err := repositories.CreateUserAccessLog(logEntry); err != nil {
log.Printf("Failed to create user access log for PostID=%d, IP=%s: %v", post.ID, ip, err)
}
}()
// 确保 location 不为空,如果为空则设置为 "Unknown"
if location == "" {
location = "Unknown"
}
// 记录调试信息
log.Printf("Creating user access log: PostID=%d, IP=%s, Location=%s", post.ID, ip, location)
// 获取用户ID (如果已登录)
var userID uint = 0
if uid, exists := c.Get("userID"); exists {
userID = uid.(uint)
}
logEntry := &models.UserAccessLog{
UserID: userID,
UserIP: ip,
UserLocation: location,
ArticleID: post.ID,
}
if err := repositories.CreateUserAccessLog(logEntry); err != nil {
log.Printf("Failed to create user access log for PostID=%d, IP=%s, Location=%s: %v", post.ID, ip, location, err)
} else {
log.Printf("Successfully created user access log: PostID=%d, IP=%s, Location=%s", post.ID, ip, location)
}
}()
}
utils.Success(c, response)
}
@@ -412,7 +418,62 @@ func AdminGetPostHistoryByVersion(c *gin.Context) {
return
}
utils.Success(c, repositories.BuildPostHistoryResponse(history))
utils.Success(c, repositories.BuildPostHistoryResponse(history, true))
}
// AdminGetPostHistoryDiff 对比两个历史版本
func AdminGetPostHistoryDiff(c *gin.Context) {
postIDStr := c.Param("id")
var postID uint
if _, err := fmt.Sscanf(postIDStr, "%d", &postID); err != nil {
utils.Error(c, 400, "Invalid post ID")
return
}
fromVersion, err := strconv.ParseUint(c.Query("from"), 10, 32)
if err != nil {
utils.Error(c, 400, "Invalid from version")
return
}
toVersion, err := strconv.ParseUint(c.Query("to"), 10, 32)
if err != nil {
utils.Error(c, 400, "Invalid to version")
return
}
diff, err := repositories.GetPostHistoryDiff(postID, uint(fromVersion), uint(toVersion))
if err != nil {
utils.Error(c, 404, err.Error())
return
}
utils.Success(c, diff)
}
// AdminRestorePostHistory 恢复指定历史版本
func AdminRestorePostHistory(c *gin.Context) {
postIDStr := c.Param("id")
var postID uint
if _, err := fmt.Sscanf(postIDStr, "%d", &postID); err != nil {
utils.Error(c, 400, "Invalid post ID")
return
}
versionStr := c.Param("version")
versionUint, err := strconv.ParseUint(versionStr, 10, 32)
if err != nil {
utils.Error(c, 400, "Invalid version")
return
}
userID, _ := c.Get("userID")
post, err := repositories.RestorePostFromHistory(postID, uint(versionUint), userID.(uint))
if err != nil {
utils.ServerError(c, err)
return
}
utils.Success(c, repositories.BuildPostResponse(post, true))
}
// GetPostsByTagID 根据标签ID获取文章

View File

@@ -47,6 +47,23 @@ func AdminDeleteSearchLog(c *gin.Context) {
utils.SuccessWithMsg(c, "Search log deleted successfully", nil)
}
// GetHotSearches 获取热门搜索关键词(公开)
func GetHotSearches(c *gin.Context) {
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
days, _ := strconv.Atoi(c.DefaultQuery("days", "30"))
keywords, err := repositories.GetHotKeywords(limit, days)
if err != nil {
utils.ServerError(c, err)
return
}
if keywords == nil {
keywords = []repositories.HotKeyword{}
}
utils.Success(c, keywords)
}
// LogSearch 记录搜索(异步,不阻塞)
func LogSearch(keyword, searchType, userIP, userLocation string) {
go func() {