Files
InfoGenie/infogenie-backend-go/internal/handler/feature_card_clicks.go
2026-04-01 22:03:57 +08:00

96 lines
2.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package handler
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
"infogenie-backend/internal/database"
"infogenie-backend/internal/model"
)
var featureCardSections = map[string]struct{}{
"60sapi": {},
"smallgame": {},
"toolbox": {},
"aimodel": {},
}
func normalizeFeatureSection(s string) (string, bool) {
key := strings.ToLower(strings.TrimSpace(s))
if key == "" {
return "", false
}
if _, ok := featureCardSections[key]; !ok {
return "", false
}
return key, true
}
func sanitizeFeatureItemID(raw string) (string, bool) {
id := strings.TrimSpace(raw)
if id == "" || len(id) > 128 {
return "", false
}
return id, true
}
// GetFeatureCardClicks 公开:按板块返回各功能 id 的点击次数(未出现过的 id 前端视为 0
func (h *SiteConfigHandler) GetFeatureCardClicks(c *gin.Context) {
section, ok := normalizeFeatureSection(c.Query("section"))
if !ok {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid_section"})
return
}
var rows []model.SiteFeatureCardClick
if err := database.DB.Where("section = ?", section).Find(&rows).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "db_error"})
return
}
counts := make(map[string]uint64, len(rows))
for _, r := range rows {
counts[r.ItemID] = r.ClickCount
}
c.JSON(http.StatusOK, gin.H{"section": section, "counts": counts})
}
type postFeatureCardClickBody struct {
Section string `json:"section"`
ItemID string `json:"item_id"`
}
// PostFeatureCardClickIncrement 公开:记录一次卡片点击并返回最新计数
func (h *SiteConfigHandler) PostFeatureCardClickIncrement(c *gin.Context) {
var body postFeatureCardClickBody
if err := c.ShouldBindJSON(&body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid_json"})
return
}
section, ok := normalizeFeatureSection(body.Section)
if !ok {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid_section"})
return
}
itemID, ok := sanitizeFeatureItemID(body.ItemID)
if !ok {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid_item_id"})
return
}
const q = `INSERT INTO site_feature_card_clicks (section, item_id, click_count, updated_at)
VALUES (?, ?, 1, NOW())
ON DUPLICATE KEY UPDATE click_count = click_count + 1, updated_at = NOW()`
if err := database.DB.Exec(q, section, itemID).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "db_error"})
return
}
var row model.SiteFeatureCardClick
if err := database.DB.Where("section = ? AND item_id = ?", section, itemID).First(&row).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "db_error"})
return
}
c.JSON(http.StatusOK, gin.H{"section": section, "item_id": itemID, "count": row.ClickCount})
}