package controller import ( "context" "errors" "gitea.youtukeji.com.cn/xiabin/douyin-openapi/cache" "gitea.youtukeji.com.cn/xiabin/youtu_ecpm/api/gin/service" "gitea.youtukeji.com.cn/xiabin/youtu_ecpm/dao/model" "gitea.youtukeji.com.cn/xiabin/youtu_ecpm/dao/query" "gitea.youtukeji.com.cn/xiabin/youtu_ecpm/pkg/douyinapi" "github.com/gin-gonic/gin" "go.uber.org/zap" "net/http" "time" ) type DouyinOpenApiController struct { *Controller logger *zap.Logger douyinCli *douyinapi.DouYinOpenApiClient appUser *service.AppUserInfo appAccount *service.AppAccount } // NewDouyinOpenApiController 实例化控制器 // logger: 日志 // q: 数据库 // 将数据库中的数据存储到内存中 func NewDouyinOpenApiController(logger *zap.Logger, q *query.Query) *DouyinOpenApiController { // 创建抖音客户端 douyinCli := douyinapi.NewDouYinOpenApiClient() // 获取数据库中的数据 ctx := context.Background() var result []struct { AppID string `gorm:"column:app_id;type:char(20);not null;index:app_id,priority:1" json:"app_id"` Secret string `gorm:"column:secret;type:char(40);not null" json:"secret"` EcpmValue uint32 `gorm:"column:ecpm_value;type:int unsigned;not null;comment:值" json:"ecpm_value"` // 值 EcpmView uint32 `gorm:"column:ecpm_view;type:int unsigned;not null;comment:浏览次数" json:"ecpm_view"` // 浏览次数 } account := q.AppAccount cfg := q.DouyinEcpmConfig //获取抖音配置 err := account.WithContext(ctx). Select( account.AppID, account.Secret, cfg.EcpmValue, cfg.EcpmView, ).Where(account.Type.Eq(0)). LeftJoin(cfg, cfg.AppAccountID.EqCol(account.ID)). Scan(&result) if err != nil { logger.Sugar().Error("获取数据失败", err) } // 将数据库中的数据存储到内存中 for _, v := range result { douyinCli.NewAndStoreDouYinOpenApi(v.AppID, v.Secret, v.EcpmValue, v.EcpmView, cache.NewMemory()) } return &DouyinOpenApiController{ logger: logger, douyinCli: douyinCli, appUser: service.NewAppUserInfo(q), appAccount: service.NewAppAccount(q), } } // GetEcpm 获取ECPM,返回true或false func (ctl *DouyinOpenApiController) GetEcpm(c *gin.Context) { var req struct { AppId string `json:"app_id" form:"app_id"` UserId uint64 `json:"user_id" form:"user_id"` } if err := c.ShouldBind(&req); err != nil { c.JSON(http.StatusOK, false) return } userInfo, err := ctl.appUser.GetUserById(c, req.UserId) if err != nil { ctl.logger.Error(err.Error()) c.JSON(http.StatusOK, false) } if userInfo == nil { c.JSON(http.StatusOK, false) return } res, err := ctl.douyinCli.GetEcpmData(req.AppId, userInfo.Openid, time.Now().Format(time.DateOnly)) if err != nil { ctl.logger.Sugar().Error("获取ecpm失败", err) c.JSON(http.StatusOK, false) return } ecpm, err := ctl.douyinCli.GetEcpm(res) if err != nil { ctl.logger.Sugar().Error("计算ecpm失败", err) c.JSON(http.StatusOK, false) return } // 打印日志 ctl.logger.Sugar().Info("ECPM:", zap.Float64("ecpm", ecpm)) // 判断是否满足ECPM值和浏览数 var result bool if ecpm > float64(ctl.douyinCli.GetEcpmValue(req.AppId)) && len(res) > int(ctl.douyinCli.GetEcpmViewCount(req.AppId)) { result = true } else { result = false } // 返回结果 c.JSON(http.StatusOK, result) } // Code2OpenId 获取openId func (ctl *DouyinOpenApiController) Code2OpenId(c *gin.Context) { code := c.Query("code") anonymousOpenid := c.Query("anonymous_openid") appId := c.Query("app_id") douyinCli, err := ctl.douyinCli.GetDouYinOpenApi(appId) if err != nil { ctl.logger.Sugar().Error("获取小程序登录地址失败", err) ctl.ResponseErr(c, err) return } res, err := douyinCli.Api.Code2Session(code, anonymousOpenid) if err != nil { ctl.logger.Sugar().Error("获取小程序登录地址失败", err) ctl.ResponseErr(c, err) return } if res.Errcode != 0 { ctl.logger.Sugar().Errorf("Code2Session 错误,res : %+v", res) ctl.ResponseErr(c, errors.New(res.Errmsg)) return } accountId, err := ctl.appAccount.GetAppAccountIdByAppId(c, appId) if err != nil { ctl.ResponseErr(c, err) return } aui := &model.AppUserInfo{ AppAccountID: accountId, Openid: res.Openid, Unionid: res.Unionid, AnonymousOpenid: res.AnonymousOpenid, } err = ctl.appUser.SaveUserInfoByRes(c, aui) if err != nil { ctl.ResponseErr(c, err) return } c.JSON(http.StatusOK, gin.H{"userId": aui.ID}) }