Files
mengyastore/mengyastore-backend-go/internal/handlers/public.go
2026-05-16 19:03:36 +08:00

81 lines
2.4 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 handlers
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
"mengyastore-backend/internal/models"
"mengyastore-backend/internal/storage"
)
type PublicHandler struct {
store *storage.ProductStore
}
func NewPublicHandler(store *storage.ProductStore) *PublicHandler {
return &PublicHandler{store: store}
}
// ListProducts 上架商品列表(公开字段,不含卡密与管理信息)。
// @Summary 获取上架商品列表
// @Description 返回当前处于「上架」状态的商品集合,仅包含前台展示所需字段(不含卡密、管理字段等)。无需登录。
// @Tags 公开
// @Produce json
// @Success 200 {object} SwaggerProductListBody
// @Failure 500 {object} SwaggerErrorBody
// @Router /api/products [get]
func (h *PublicHandler) ListProducts(c *gin.Context) {
items, err := h.store.ListActive()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"data": sanitizeForPublic(items)})
}
// RecordProductView 记录商品浏览(去重策略由服务端指纹决定)。
// @Summary 记录商品浏览次数
// @Description 对指定商品增加浏览计数;是否计入由服务端对访客指纹去重策略决定,用于热门统计。路径参数为商品 ID。
// @Tags 公开
// @Produce json
// @Param id path string true "商品ID路径"
// @Success 200 {object} SwaggerProductViewWrap
// @Failure 404 {object} SwaggerErrorBody
// @Router /api/products/{id}/view [post]
func (h *PublicHandler) RecordProductView(c *gin.Context) {
id := c.Param("id")
fingerprint := buildViewerFingerprint(c)
product, counted, err := h.store.IncrementView(id, fingerprint)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"data": gin.H{
"id": product.ID,
"viewCount": product.ViewCount,
"counted": counted,
},
})
}
func buildViewerFingerprint(c *gin.Context) string {
clientIP := strings.TrimSpace(c.ClientIP())
userAgent := strings.TrimSpace(c.GetHeader("User-Agent"))
language := strings.TrimSpace(c.GetHeader("Accept-Language"))
return clientIP + "|" + userAgent + "|" + language
}
func sanitizeForPublic(items []models.Product) []models.Product {
out := make([]models.Product, len(items))
for i, item := range items {
item.Codes = nil
item.FixedContent = ""
out[i] = item
}
return out
}