Files
YouduWiki/backend/handler/share/stat.go
2026-05-21 19:52:45 +08:00

103 lines
2.6 KiB
Go

package share
import (
"net/url"
"time"
"github.com/labstack/echo/v4"
"github.com/mileusna/useragent"
"github.com/chaitin/panda-wiki/domain"
"github.com/chaitin/panda-wiki/handler"
"github.com/chaitin/panda-wiki/log"
"github.com/chaitin/panda-wiki/usecase"
)
type ShareStatHandler struct {
*handler.BaseHandler
useCase *usecase.StatUseCase
logger *log.Logger
}
func NewShareStatHandler(baseHandler *handler.BaseHandler, echo *echo.Echo, useCase *usecase.StatUseCase, logger *log.Logger) *ShareStatHandler {
h := &ShareStatHandler{
BaseHandler: baseHandler,
useCase: useCase,
logger: logger.WithModule("handler.share.stat"),
}
group := echo.Group("/share/v1/stat")
group.POST("/page", h.RecordPage, h.ShareAuthMiddleware.Authorize)
return h
}
// RecordPage record page
//
// @Summary RecordPage
// @Description RecordPage
// @Tags share_stat
// @Accept json
// @Produce json
// @Param request body domain.StatPageReq true "request"
// @Success 200 {object} domain.Response
// @Router /share/v1/stat/page [post]
func (h *ShareStatHandler) RecordPage(c echo.Context) error {
req := &domain.StatPageReq{}
if err := c.Bind(req); err != nil {
return h.NewResponseWithError(c, "bind request body failed", err)
}
if err := c.Validate(req); err != nil {
return h.NewResponseWithError(c, "validate request body failed", err)
}
kbID := c.Request().Header.Get("X-KB-ID")
// get user info --> no enterprise is nil
var userIDValue uint
userID := c.Get("user_id")
if userID != nil { // can find userinfo from auth
userIDValue = userID.(uint)
}
ua := c.Request().UserAgent()
userAgent := useragent.Parse(ua)
browserName := userAgent.Name
browserOS := userAgent.OS
referer := c.Request().Referer()
refererHost := ""
if referer != "" {
refererURL, err := url.Parse(referer)
if err == nil {
refererHost = refererURL.Host
}
}
sessionID := ""
sessionIDCookie, err := c.Request().Cookie("x-pw-session-id")
if err != nil {
sessionID = c.Request().Header.Get("x-pw-session-id")
} else {
sessionID = sessionIDCookie.Value
}
if sessionID == "" {
return h.NewResponseWithError(c, "session id not found", err)
}
ip := c.RealIP()
stat := &domain.StatPage{
KBID: kbID,
UserID: userIDValue,
NodeID: req.NodeID,
Scene: req.Scene,
SessionID: sessionID,
IP: ip,
UA: ua,
BrowserName: browserName,
BrowserOS: browserOS,
Referer: referer,
RefererHost: refererHost,
CreatedAt: time.Now(),
}
if err := h.useCase.RecordPage(c.Request().Context(), stat); err != nil {
return h.NewResponseWithError(c, "record page failed", err)
}
return h.NewResponseWithData(c, nil)
}