feat(ops): ECR-007 行为分析与 ECR-008 内容运营后台
ci / h5 (push) Canceled after 0s
ci / api (push) Canceled after 0s
ci / ess-docs (push) Canceled after 0s

落地埋点 ingest/数据看板、首页宫格 CMS 与测评上下架;含账号引导、问答流式与免责声明去重,以及 review P1 审计同事务修复。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-07 02:26:16 +08:00
co-authored by Cursor
parent 7e9023f0a8
commit 7ab9add5dd
132 changed files with 8276 additions and 491 deletions
+35
View File
@@ -34,12 +34,47 @@ func (h *ReportHandler) Register(rg *gin.RouterGroup) {
rg.POST("/reports/synastry", h.CreateSynastry)
rg.POST("/reports/rhythm", h.CreateRhythm)
rg.GET("/reports", h.List)
rg.GET("/reports/latest", h.GetLatest)
rg.GET("/reports/:id", h.Get)
rg.GET("/membership/me", h.GetMembership)
rg.POST("/orders", h.CreateOrder)
rg.POST("/orders/:id/pay-mock", h.PayMock)
}
// GetLatest handles GET /reports/latest?profile_id=&type=&peer_profile_id=.
func (h *ReportHandler) GetLatest(c *gin.Context) {
userID, ok := middleware.UserIDFromContext(c)
if !ok {
response.Fail(c, http.StatusUnauthorized, 40100, "unauthorized")
return
}
pid, err := uuid.Parse(c.Query("profile_id"))
if err != nil {
response.Fail(c, http.StatusBadRequest, 10000, "profile_id required")
return
}
typ := c.Query("type")
if typ == "" {
response.Fail(c, http.StatusBadRequest, 10000, "type required")
return
}
var peer *uuid.UUID
if ps := c.Query("peer_profile_id"); ps != "" {
id, err := uuid.Parse(ps)
if err != nil {
response.Fail(c, http.StatusBadRequest, 10000, "invalid peer_profile_id")
return
}
peer = &id
}
rep, err := h.Svc.GetLatest(c.Request.Context(), userID, pid, typ, peer)
if err != nil {
response.Fail(c, http.StatusNotFound, 40402, err.Error())
return
}
response.OK(c, rep)
}
// CreatePortrait handles POST /reports/portrait.
func (h *ReportHandler) CreatePortrait(c *gin.Context) {
userID, ok := middleware.UserIDFromContext(c)