package web import ( "net/http" "strings" "github.com/gin-gonic/gin" ) // attachTrackerPage 按响应状态和路径注入 pageKey / pageName(handler 可显式覆盖)。 // 所有 HTML 页面都必须得到明确页面信息,避免埋点落入 unknown / 未知页面。 func attachTrackerPage(c *gin.Context, code int, data gin.H) { if data == nil { return } key, name := trackerPageFromRequest(c.Request.URL.Path, code) if code >= http.StatusBadRequest { data["pageKey"] = key data["pageName"] = name return } existingKey, _ := data["pageKey"].(string) existingName, _ := data["pageName"].(string) existingKey = strings.TrimSpace(existingKey) existingName = strings.TrimSpace(existingName) if existingKey == "" || existingKey == "unknown" { data["pageKey"] = key } if existingName == "" || existingName == "未知页面" { data["pageName"] = name } } func trackerPageFromRequest(path string, code int) (pageKey, pageName string) { if code >= http.StatusInternalServerError { return "server_error", "服务异常页面" } if code >= http.StatusBadRequest { return "not_found", "404页面" } return trackerPageFromPath(path) } func trackerPageFromPath(path string) (pageKey, pageName string) { p := strings.TrimSpace(path) if p == "" || p == "/" { return "home", "首页" } // 去掉尾部斜杠,便于精确匹配 p = strings.TrimSuffix(p, "/") switch { case trackerPathHasPrefix(p, "/list"): return "list", "短剧列表" case trackerPathHasPrefix(p, "/series"): return "series", "AI成人剧集" case trackerPathHasPrefix(p, "/tag"), trackerPathHasPrefix(p, "/tag-list"): return "tag_list", "标签详情" case trackerPathHasPrefix(p, "/rank"): return "rank", "排行榜" case trackerPathHasPrefix(p, "/today-update"): return "today_update", "今日更新" case trackerPathHasPrefix(p, "/category"): return "category_detail", "分类详情" case trackerTopicIndexPath(p): return "theme_index", "专题列表" case trackerPathHasPrefix(p, "/topic"), trackerPathHasPrefix(p, "/more"): return "topic", "专题详情" case trackerPathHasPrefix(p, "/download-app"): return "download_app", "下载APP" case trackerPathHasPrefix(p, "/application"): return "application", "应用推荐" case trackerPathHasPrefix(p, "/home-road"): return "home_road", "回家的路" case trackerPathHasPrefix(p, "/detail"): return "detail", "短剧详情" case trackerPathHasPrefix(p, "/play"): return "play", "播放页" case trackerPathHasPrefix(p, "/login"): return "login", "登录" case trackerPathHasPrefix(p, "/register"): return "register", "注册" case trackerPathHasPrefix(p, "/user-center"): return "user_center", "个人中心" case trackerPathHasPrefix(p, "/deposit"): return "deposit", "充值中心" case trackerPathHasPrefix(p, "/collect"): return "collect", "我的收藏" case trackerPathHasPrefix(p, "/history"): return "history", "观看历史" case trackerPathHasPrefix(p, "/setting"): return "setting", "设置" case trackerPathHasPrefix(p, "/edit-profile"): return "edit_profile", "编辑资料" case trackerPathHasPrefix(p, "/edit-password"): return "edit_password", "修改密码" case trackerPathHasPrefix(p, "/search"): return "search", "搜索结果页" case trackerPathHasPrefix(p, "/about-us"): return "about_us", "关于我们" case trackerPathHasPrefix(p, "/user-agreement"): return "user_agreement", "用户协议" case trackerPathHasPrefix(p, "/privacy-policy"): return "privacy_policy", "隐私政策" case trackerPathHasPrefix(p, "/help-center"): return "help_center", "帮助中心" case trackerPathHasPrefix(p, "/richtext"): return "rich_text", "富文本页" case trackerPathHasPrefix(p, "/feedback"): return "feedback", "问题反馈" case trackerPathHasPrefix(p, "/nav"), trackerPathHasPrefix(p, "/dh"): return "nav", "官方导航" default: return "internal_other", "站内其他页面" } } func trackerPathHasPrefix(path, base string) bool { return path == base || strings.HasPrefix(path, base+"/") } func trackerTopicIndexPath(path string) bool { if path == "/topic" || path == "/more" { return true } return strings.HasPrefix(path, "/topic/page/") || strings.HasPrefix(path, "/more/page/") }