ecpm.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. package crons
  2. import (
  3. "context"
  4. "designs/global"
  5. "designs/service"
  6. "encoding/json"
  7. "github.com/pkg/errors"
  8. "net/http"
  9. "net/url"
  10. "strconv"
  11. "time"
  12. )
  13. func SetEcpm() {
  14. gid := "linkup"
  15. err := Ecpm(gid)
  16. if err != nil {
  17. global.App.Log.Error("Ecpm error", err)
  18. }
  19. global.App.Log.Info("ser Ecpm success")
  20. }
  21. func GetAccessToken(gid string, ttAppid string, ttSecret string) (string, error) {
  22. tokenKey := gid + "||" + "ttToken"
  23. AccessToken := global.App.Redis.Get(context.Background(), tokenKey).Val()
  24. if AccessToken == "" {
  25. reportDat := map[string]string{
  26. "appid": ttAppid,
  27. "secret": ttSecret,
  28. "grant_type": "client_credential",
  29. }
  30. //请求接口获取token
  31. content, err := service.CurlPost("https://minigame.zijieapi.com/mgplatform/api/apps/v2/token", reportDat, nil)
  32. if err != nil {
  33. return "", err
  34. }
  35. var resp struct {
  36. Data struct {
  37. AccessToken string `json:"access_token"`
  38. ExpiresIn int `json:"expires_in"`
  39. ExpiresAt int `json:"expiresAt"`
  40. } `json:"data"`
  41. ErrTips string `json:"err_tips"`
  42. ErrNo int `json:"err_no"`
  43. }
  44. str2oErr := json.Unmarshal([]byte(content), &resp)
  45. if str2oErr != nil {
  46. return "", err
  47. }
  48. if resp.ErrNo != 0 {
  49. return "", errors.New(resp.ErrTips)
  50. }
  51. AccessToken = resp.Data.AccessToken
  52. global.App.Redis.Set(context.Background(), tokenKey, AccessToken, time.Second*30)
  53. }
  54. return AccessToken, nil
  55. }
  56. type UserJoinSeeAds struct {
  57. ID int `json:"id" gorm:"not null;"`
  58. Pf string `json:"pf" gorm:"not null;"`
  59. Gid string `json:"gid" gorm:"not null;"`
  60. UserId int `json:"userId" gorm:"not null;column:userId;"`
  61. OpenId string `json:"openId" gorm:"not null;column:openId;"`
  62. Date string `json:"date" gorm:"not null;"`
  63. CreatedAt time.Time `json:"createdAt" gorm:"column:createdAt;"`
  64. StartTime time.Time `json:"startTime" gorm:"column:startTime;"`
  65. AdsId string `json:"adsId" gorm:"not null;column:adsId;"`
  66. AdsType string `json:"adsType" gorm:"not null;column:adsType;"`
  67. AdsScene string `json:"adsScene" gorm:"not null;column:adsScene;"`
  68. AdsState int `json:"adsState" gorm:"not null;column:adsState;"`
  69. }
  70. func Ecpm(gid string) error {
  71. res, _ := global.App.Redis.HGetAll(context.Background(), "gid:"+gid).Result()
  72. //获取和存储accessToken
  73. accessToken, err := GetAccessToken(gid, res["ttAppid"], res["ttSecret"])
  74. if err != nil {
  75. return err
  76. }
  77. //请求获取结果
  78. dateHour := time.Now().AddDate(0, 0, 0).Format("2006-01-02")
  79. ecpmRes, err := GetEcpm(res["ttAppid"], accessToken, dateHour)
  80. if err != nil {
  81. return err
  82. }
  83. //查询出当日的所有数据
  84. var userSeeAds []UserJoinSeeAds
  85. err = global.App.DB.Table("user_see_ads").
  86. LeftJoin("user", "user.userId = user_see_ads.userId and user.gid = user_see_ads.gid").
  87. Where("user_see_ads.createdAt", ">=", dateHour).
  88. Select("user_see_ads.*", "user.openId").
  89. Where("user_see_ads.gid", gid).
  90. Where("user_see_ads.pf", "tt").
  91. Order("user_see_ads.createdAt asc").
  92. Scan(&userSeeAds).Error
  93. if err != nil {
  94. return err
  95. }
  96. //按照openId 分组
  97. userSeeAdsMap := make(map[string][]UserJoinSeeAds)
  98. for _, userSeeAd := range userSeeAds {
  99. userSeeAdsMap[userSeeAd.OpenId] = append(userSeeAdsMap[userSeeAd.OpenId], userSeeAd)
  100. }
  101. ecpmMap := make(map[string][]EcpmItem)
  102. for _, record := range ecpmRes.Data.Records {
  103. ecpmMap[record.OpenId] = append(ecpmMap[record.OpenId], record)
  104. }
  105. for k, item := range ecpmMap {
  106. //跳过数据对不上的
  107. if len(userSeeAdsMap[k]) == 0 {
  108. continue
  109. }
  110. gid := userSeeAdsMap[k][0].Gid
  111. pf := userSeeAdsMap[k][0].Pf
  112. openId := userSeeAdsMap[k][0].OpenId
  113. userId := userSeeAdsMap[k][0].UserId
  114. for key, v := range item {
  115. ecpmData := struct {
  116. Id int `json:"id" gorm:"not null;"`
  117. }{}
  118. global.App.DB.Table("ecpm_data").Where("ecmpId", v.Id).Select("id").First(&ecpmData)
  119. if ecpmData.Id == 0 {
  120. err = global.App.DB.Table("ecpm_data").Create(map[string]interface{}{
  121. "gid": gid,
  122. "pf": pf,
  123. "openId": openId,
  124. "cost": v.Cost,
  125. "userId": userId,
  126. "ecmpId": v.Id,
  127. "createdAt": v.EventTime,
  128. }).Error
  129. if err != nil {
  130. return err
  131. }
  132. }
  133. //关联到看广告表中
  134. if key < len(userSeeAdsMap[k]) {
  135. err = global.App.DB.Table("user_see_ads").Where("id", userSeeAdsMap[k][key].ID).Update("cost", v.Cost).Error
  136. if err != nil {
  137. global.App.Log.Error("id:"+strconv.Itoa(userSeeAdsMap[k][key].ID)+"user_see_ads update cost err:", err.Error())
  138. return err
  139. }
  140. }
  141. }
  142. }
  143. return nil
  144. }
  145. type EcpmItem struct {
  146. Aid string `json:"aid"`
  147. Cost int `json:"cost"`
  148. Did string `json:"did"`
  149. EventName string `json:"event_name"`
  150. EventTime string `json:"event_time"`
  151. OpenId string `json:"open_id"`
  152. Id int `json:"id"`
  153. }
  154. type Result struct {
  155. ErrMsg string `json:"err_msg"`
  156. ErrNo int `json:"err_no"`
  157. LogId string `json:"log_id"`
  158. Data struct {
  159. Total int `json:"total"`
  160. Records []EcpmItem `json:"records"`
  161. } `json:"data"`
  162. }
  163. // GetEcpm 获取用户的ecpm值,用于巨量引擎下小游戏的关键行为转化指标
  164. func GetEcpm(appId string, accessToken string, dateHour string) (*Result, error) {
  165. pageNo := 0
  166. pageSize := 100
  167. var resData Result
  168. header := http.Header{
  169. "Content-type": []string{"application/json"},
  170. }
  171. for {
  172. pageNo++
  173. params := url.Values{
  174. "access_token": {accessToken},
  175. "mp_id": {appId},
  176. "date_hour": {dateHour},
  177. "page_no": {strconv.Itoa(pageNo)},
  178. "page_size": {strconv.Itoa(pageSize)},
  179. }
  180. res, err := service.CurlGet("https://minigame.zijieapi.com/mgplatform/api/apps/data/get_ecpm", params, header)
  181. if err != nil {
  182. return nil, err
  183. }
  184. var resp Result
  185. err = json.Unmarshal([]byte(res), &resp)
  186. if err != nil {
  187. return nil, err
  188. }
  189. resData.Data.Records = append(resData.Data.Records, resp.Data.Records...)
  190. resData.Data.Total = resp.Data.Total
  191. //当获取到所有数据的时候,停止获取数据
  192. if pageNo*pageSize >= resp.Data.Total {
  193. break
  194. }
  195. }
  196. return &resData, nil
  197. }