From 4a21a5d3935dec0efd375db39c6e11bc6cc86a83 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 29 Oct 2026 16:23:44 +0800 Subject: [PATCH] =?UTF-8?q?feat(adcenter):=20=E6=96=B0=E5=A2=9E=20POST=20/?= =?UTF-8?q?api/app/ads/click=20=E5=B9=BF=E5=91=8A=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E4=B8=8A=E6=8A=A5=E5=88=B0=E5=B9=BF=E5=91=8A=E4=B8=AD=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - handler 绑定 proto.AdsClickInfo{appId, adsId, location} - 走 ${versionUrl}/api/stat/advitise/v2/click - appId<=0 时回落到默认 advertiseAppId=12 Co-Authored-By: Claude Opus 4.7 --- app/api/adsapi/click.go | 31 +++++++++++ app/router/ads.go | 11 ++++ app/router/gin.go | 1 + app/service/configser/advertise_click.go | 66 ++++++++++++++++++++++++ 4 files changed, 109 insertions(+) create mode 100644 app/api/adsapi/click.go create mode 100644 app/router/ads.go create mode 100644 app/service/configser/advertise_click.go diff --git a/app/api/adsapi/click.go b/app/api/adsapi/click.go new file mode 100644 index 0000000..f673027 --- /dev/null +++ b/app/api/adsapi/click.go @@ -0,0 +1,31 @@ +package adsapi + +import ( + "strconv" + + "videoweb/app/api/proto" + "videoweb/app/service/configser" + "videoweb/pub/common" + "videoweb/pub/common/srvdef" + + "github.com/gin-gonic/gin" +) + +// Click 广告点击上报 +// @Tags 广告 +// @Summary 广告点击上报 +// @Description 用户点击广告时异步上报到广告中心。请求可带 appId 覆盖默认,缺省时按本站 appId 上报。 +// @Accept json +// @Produce json +// @Param param body proto.AdsClickInfo true "参数" +// @Success 200 {string} json +// @Router /api/app/ads/click [POST] +func Click(c *gin.Context) { + var req proto.AdsClickInfo + if err := c.ShouldBindJSON(&req); err != nil { + common.ServerJSON(c, srvdef.ErrParamError, err.Error()) + return + } + configser.AsyncAdvertiseClick(strconv.FormatInt(req.AdsId, 10), int32(req.AppId)) + common.ServerJSON(c, srvdef.Success, nil) +} diff --git a/app/router/ads.go b/app/router/ads.go new file mode 100644 index 0000000..9d132a0 --- /dev/null +++ b/app/router/ads.go @@ -0,0 +1,11 @@ +package router + +import ( + "videoweb/app/api/adsapi" + + "github.com/gin-gonic/gin" +) + +func adsRouter(r *gin.Engine) { + r.POST("/api/app/ads/click", adsapi.Click) +} diff --git a/app/router/gin.go b/app/router/gin.go index b4fa19d..323762b 100644 --- a/app/router/gin.go +++ b/app/router/gin.go @@ -122,6 +122,7 @@ func registeRouter(r *gin.Engine) { translationRouter(r) navigationRouter(r) statcenterRouter(r) + adsRouter(r) r.GET("/notpage", templatecache.WithCache(time.Minute*1), home.PageNotFound) } diff --git a/app/service/configser/advertise_click.go b/app/service/configser/advertise_click.go new file mode 100644 index 0000000..ab070ac --- /dev/null +++ b/app/service/configser/advertise_click.go @@ -0,0 +1,66 @@ +package configser + +import ( + "encoding/json" + "fmt" + "net/http" + "strconv" + "strings" + + "videoweb/app/appg" + "videoweb/pub/common/godef" + "videoweb/pub/common/httputil" + "videoweb/pub/common/log" +) + +type advertiseClickReq struct { + Id int64 `json:"id"` + AppId int32 `json:"appId"` +} + +type advertiseClickResp struct { + Code int64 `json:"code"` +} + +// resolveAdvertiseAppId 请求带了 AppId 用请求的,否则回落到默认 advertiseAppId +func resolveAdvertiseAppId(reqAppId int32) int32 { + if reqAppId > 0 { + return reqAppId + } + return advertiseAppId +} + +// AdvertiseClickCenter 同步上报单条广告点击到广告中心。 +// appId<=0 时回落到默认 advertiseAppId。 +func AdvertiseClickCenter(advertiseId int64, appId int32) error { + versionUrl := strings.TrimRight(strings.TrimSpace(appg.Conf.VersionUrl), "/") + if versionUrl == "" { + return fmt.Errorf("versionUrl 未配置") + } + url := versionUrl + "/api/stat/advitise/v2/click" + body, _ := json.Marshal(advertiseClickReq{Id: advertiseId, AppId: resolveAdvertiseAppId(appId)}) + var resp advertiseClickResp + code, err := httputil.Client().POSTJsonWithJResp(&resp, url, map[string]string{"Content-Type": "application/json"}, body) + if err != nil { + log.Error("AdvertiseClickCenter POST fail", log.Any("url", url), log.Any("id", advertiseId), log.E(err)) + return err + } + if code != http.StatusOK { + log.Error("AdvertiseClickCenter response status", log.Any("code", code), log.Any("id", advertiseId)) + return fmt.Errorf("response status %d", code) + } + return nil +} + +// AsyncAdvertiseClick 异步上报广告点击,非数字 id 忽略。 +// appId<=0 时回落到默认 advertiseAppId。 +func AsyncAdvertiseClick(id string, appId int32) { + advertiseId, err := strconv.ParseInt(strings.TrimSpace(id), 10, 64) + if err != nil { + log.Warn("AsyncAdvertiseClick invalid id", log.Any("id", id)) + return + } + godef.Go(func() { + _ = AdvertiseClickCenter(advertiseId, appId) + }) +}