test.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. package v1
  2. import (
  3. "context"
  4. "designs/app/common/request"
  5. "designs/config"
  6. "designs/crons"
  7. "designs/global"
  8. "designs/model"
  9. "designs/response"
  10. "designs/service"
  11. "fmt"
  12. "github.com/gin-gonic/gin"
  13. "go.mongodb.org/mongo-driver/v2/bson"
  14. "gorm.io/gorm/clause"
  15. "os"
  16. "strconv"
  17. "time"
  18. )
  19. type logData struct {
  20. LogTime time.Time `json:"logTime" gorm:"column:logTime;"`
  21. Type int `json:"Type"`
  22. }
  23. func calculateUserOnlineTime(logData []logData) int64 {
  24. var lastLog int64
  25. var isStart bool
  26. var onlineTimeTotal int64
  27. for k, v := range logData {
  28. logTime := v.LogTime.Unix()
  29. //如果跟上一次的记录隔的时间超过6分钟,就认为是之前断线了,属于无效数据
  30. if k > 0 && logData[k-1].LogTime.Unix()+60*6 < logTime {
  31. isStart = false
  32. continue
  33. }
  34. if v.Type == 1 && isStart == false {
  35. isStart = true
  36. lastLog = v.LogTime.Unix()
  37. continue
  38. }
  39. if v.Type == 1 && isStart == true {
  40. //logTime := v.LogTime.Unix()
  41. onlineTimeTotal = onlineTimeTotal + (logTime - lastLog)
  42. lastLog = logTime
  43. //如果下一次的心跳,间隔时间大于6分钟了,就可以认为,这次就算是结束了
  44. if k+1 == len(logData) || logData[k+1].LogTime.Unix() > logTime+60*6 {
  45. isStart = false
  46. }
  47. continue
  48. }
  49. if v.Type == 2 && isStart == true {
  50. //logTime := v.LogTime.Unix()
  51. onlineTimeTotal = onlineTimeTotal + (logTime - lastLog)
  52. isStart = false
  53. continue
  54. }
  55. }
  56. return onlineTimeTotal
  57. }
  58. func SetUserBehaviorBak(c *gin.Context) {
  59. //读取出来user数据
  60. var users []model.User
  61. global.App.DB.Table("user").
  62. Where("pf", "=", "tt").
  63. Where("gid", "=", "linkup").
  64. Where("createdAt", ">=", "2024-11-12").
  65. Where("createdAt", "<=", "2024-11-13").Scan(&users)
  66. collection := global.App.MongoDB.Database("chunhao").Collection("adRelated")
  67. for _, user := range users {
  68. //查询出reids中的openId
  69. userIdKeys := fmt.Sprintf("%s:%s:%s:%v", user.Gid, user.Pf, config.Get("app.user_table_id"), strconv.Itoa(user.UserId))
  70. userIdData, _ := global.App.Redis.HGetAll(context.Background(), userIdKeys).Result()
  71. openId := userIdData["openId"]
  72. //openId = strconv.Itoa(user.UserId)
  73. //查询出在线时长数据
  74. var LogData []logData
  75. global.App.DB.Table("user_online").
  76. Where("pf", user.Pf).
  77. Where("gid", user.Gid).
  78. Where("userId", user.UserId).Scan(&LogData)
  79. duration := calculateUserOnlineTime(LogData)
  80. //查询出看广告数据
  81. var req_count int64
  82. var exp_count int64
  83. global.App.DB.Table("user_see_ads").
  84. Where("pf", user.Pf).
  85. Where("gid", user.Gid).
  86. Where("userId", user.UserId).Count(&req_count)
  87. global.App.DB.Table("user_see_ads").
  88. Where("pf", user.Pf).
  89. Where("gid", user.Gid).
  90. Where("adState", 2).
  91. Where("userId", user.UserId).Count(&exp_count)
  92. //查询出启动次数
  93. var start_num int64
  94. global.App.DB.Table("user_login").
  95. Where("pf", user.Pf).
  96. Where("gid", user.Gid).
  97. Where("userId", user.UserId).Count(&start_num)
  98. //存入mongo
  99. adData := struct {
  100. Id string `bson:"_id" json:"_id"`
  101. UserId string `bson:"userId" json:"userId"`
  102. Aid int64 `json:"aid" bson:"aid"` //广告的推广计划id,即广告ID,广告平台配置落地页参数
  103. Cid string `json:"cid" bson:"cid"` //openid的用户点击aid广告进入游戏时的唯一标识,广告平台提供
  104. Pid int64 `json:"pid" bson:"pid"` //广告的项目id(仅巨量引擎存在,腾讯广告时不存在该值),广告平台配置落地页参数
  105. CreateTime int64 `bson:"create_time"` //当前计划的创建时间
  106. StartNum int `bson:"startNum" json:"startNum"` //启动次数
  107. Revenue float32 `bson:"revenue" json:"revenue"` //当日预估收益
  108. Duration int64 `bson:"duration" json:"duration"` //当日在线时长
  109. ReqCount int `bson:"req_count" json:"req_count"` //当日的激励视频广告请求次数
  110. ExpCount int `bson:"exp_count" json:"exp_count"` //当日的激励视频广告曝光次数
  111. }{
  112. UserId: user.Gid + "|" + user.Pf + "|" + openId,
  113. Id: user.Gid + "|" + user.Pf + "|" + openId + "|" + "7436301890621997000",
  114. Aid: 7436301890621997000,
  115. Pid: 0,
  116. Cid: "",
  117. Duration: duration,
  118. StartNum: int(start_num),
  119. Revenue: 0,
  120. ReqCount: int(req_count),
  121. ExpCount: int(exp_count),
  122. CreateTime: user.CreatedAt.Unix(),
  123. }
  124. collection.InsertOne(context.Background(), adData)
  125. fmt.Println(user.Gid+"|"+user.Pf+"|"+openId, "数据写入完成\n")
  126. }
  127. }
  128. func DeleteUserBehaviorBak(c *gin.Context) {
  129. collection := global.App.MongoDB.Database("chunhao").Collection("userBehavior")
  130. filter := bson.M{"create_time": bson.M{"$gt": 1}}
  131. collection.DeleteMany(context.Background(), filter)
  132. response.Success(c, gin.H{})
  133. }
  134. func GetUserNickName(c *gin.Context) {
  135. //读取user表
  136. var count int64
  137. err := global.App.DB.Table("user").Count(&count).Error
  138. if err != nil {
  139. response.Fail(c, 1001, err.Error())
  140. return
  141. }
  142. var i int64
  143. for i = 1; i <= count; i++ {
  144. var user model.User
  145. err = global.App.DB.Table("user").Where("id", i).Find(&user).Error
  146. if err != nil {
  147. response.Fail(c, 1001, err.Error())
  148. return
  149. }
  150. if user.Pf == "web" {
  151. //web跳过
  152. continue
  153. }
  154. userKey := user.Gid + ":" + user.Pf + ":" + config.Get("app.user_table_key") + user.OpenId
  155. userData, err := global.App.Redis.HGetAll(context.Background(), userKey).Result()
  156. if err != nil {
  157. global.App.Log.Error("GetUserData err")
  158. response.Fail(c, 1003, "GetUserData err"+err.Error())
  159. return
  160. }
  161. if userData["head"] != "" {
  162. //有意义的数据
  163. //data := struct {
  164. // ID int `json:"id" gorm:"not null;"`
  165. // Head string `json:"head" gorm:"not null;"`
  166. // NickName string `json:"nickName" gorm:"not null;column:nickName;"`
  167. //}{
  168. // Head: userData["head"],
  169. // NickName: userData["nickName"],
  170. //}
  171. //err = global.App.DB.Table("nickname").Create(&data).Error
  172. //if err != nil {
  173. // response.Fail(c, 1003, "nickname err"+err.Error())
  174. // return
  175. //}
  176. }
  177. }
  178. response.Success(c, gin.H{})
  179. }
  180. // 定义一个函数来执行任务
  181. func WriteDBDataToFile(c *gin.Context) {
  182. // 打开文件准备写入
  183. file, err := os.Create("./nickname.txt")
  184. if err != nil {
  185. response.Fail(c, 1001, fmt.Errorf("无法创建文件: %v", err))
  186. }
  187. defer file.Close()
  188. // 查询数据库
  189. var data []struct {
  190. ID int `json:"id" gorm:"not null;"`
  191. Head string `json:"head" gorm:"not null;"`
  192. NickName string `json:"nickName" gorm:"not null;column:nickName;"`
  193. }
  194. global.App.DB.Table("nickname").Scan(&data)
  195. // 写入列名到文件(可选)
  196. for _, v := range data {
  197. fmt.Println(v)
  198. fmt.Fprintf(file, "%s\t%s\n", v.NickName, v.Head)
  199. }
  200. response.Success(c, gin.H{})
  201. }
  202. // 对打点数据进行汇算
  203. func ActionDataSummary(c *gin.Context) {
  204. service.SeeAdsSummary("20250706")
  205. return
  206. now := time.Now()
  207. for i := 1; i <= 30; i++ {
  208. lastDay := now.AddDate(0, 0, -i).Format("20060102")
  209. service.SeeAdsSummary(lastDay)
  210. fmt.Println("用时", time.Since(now))
  211. }
  212. response.Success(c, gin.H{})
  213. }
  214. func CopyGameConfig(c *gin.Context) {
  215. form := request.Check(c, &struct {
  216. Gid string `json:"gid" binding:""`
  217. }{})
  218. form.Gid = "snake"
  219. ////查询出所有的Key
  220. //redisKey := "config_game:snake:" + "*"
  221. //
  222. //fmt.Println(redisKey)
  223. //val, err := global.App.Redis.Keys(context.Background(), redisKey).Result()
  224. //if err != nil {
  225. // response.Fail(c, 1001, err.Error())
  226. // return
  227. //}
  228. //
  229. //for _, key := range val {
  230. // data, _ := global.App.Redis.Get(context.Background(), key).Result()
  231. //
  232. // global.App.DB.Table("snake").Create(&map[string]interface{}{
  233. // "key": key,
  234. // "data": data,
  235. // })
  236. //}
  237. type aaa struct {
  238. Key string `json:"key"`
  239. Data string `json:"data"`
  240. }
  241. var data []aaa
  242. global.App.DB.Table("snake").Scan(&data)
  243. for _, v := range data {
  244. err := global.App.Redis.Set(context.Background(), v.Key, v.Data, 0).Err()
  245. if err != nil {
  246. response.Fail(c, 1001, err.Error())
  247. return
  248. }
  249. }
  250. response.Success(c, gin.H{"data": data})
  251. }
  252. func BehaviorTimeSummary(c *gin.Context) {
  253. //先查出所有gid
  254. ActiveGid := service.GetActiveGid()
  255. //现在直接汇总所有的数据(直到前一天的)
  256. now := time.Now()
  257. end := now.AddDate(0, 0, -1)
  258. start, _ := time.Parse("2006-01-02 15:04:05", "2025-05-17 15:04:05")
  259. crons.BehaviorSummary("wx", ActiveGid, start, end)
  260. global.App.Log.Info("重新汇总用户在线时长数据完成")
  261. response.Success(c, gin.H{})
  262. }
  263. func BehaviorSummary(c *gin.Context) {
  264. //先查出所有gid
  265. ActiveGid := service.GetActiveGid()
  266. //now := time.Now().AddDate(0, 0, -1)
  267. //start := now.AddDate(0, 0, -45)
  268. pf := "wx"
  269. //循环一下,查出userId 跟相关的在线数据
  270. for _, gid := range ActiveGid {
  271. start1 := time.Now()
  272. fmt.Println("处理数据开始,gid :", gid)
  273. ////查询 30天内的在线数据
  274. //
  275. //SummaryData, err := service.UserOnlineSummary(gid, pf, "", start.Format("2006-01-02 15:04:05"), now.Format("2006-01-02 15:04:05"))
  276. //if err != nil {
  277. // response.Fail(c, 1001, err.Error())
  278. // return
  279. //}
  280. //aaa, _ := json.Marshal(SummaryData)
  281. //global.App.Log.Error(string(aaa))
  282. //
  283. //return
  284. fmt.Println("查询在线数据完成:", time.Since(start1))
  285. //查询用户的登录次数
  286. var loginData []struct {
  287. UserId int `json:"userId" gorm:"not null;column:userId;"`
  288. LoginCount int `json:"loginCount" gorm:"not null;column:loginCount;"`
  289. }
  290. loginDataMap := make(map[int]int)
  291. err := global.App.DB.Table("user_login").
  292. Where("gid", gid).
  293. Where("pf", pf).
  294. Group("userId").
  295. Select("count(*) as loginCount", "userId").
  296. Scan(&loginData).Error
  297. if err != nil {
  298. response.Fail(c, 1002, err.Error())
  299. return
  300. }
  301. for _, login := range loginData {
  302. loginDataMap[login.UserId] = login.LoginCount
  303. }
  304. fmt.Println("查询登录数据完成:", time.Since(start1))
  305. //查询用户的看广告次数,广告看完次数
  306. var seeAdsData []struct {
  307. UserId int `json:"userId" gorm:"not null;column:userId;"`
  308. SeeAdsCount int `json:"seeAdsCount" gorm:"not null;column:seeAdsCount;"`
  309. State2Count int `json:"state2Count" gorm:"not null;column:state2Count;"`
  310. }
  311. seeAdsDataMap := make(map[int]int)
  312. seeAdsDataMap2 := make(map[int]int)
  313. err = global.App.DB.Table("user_see_ads").
  314. Where("gid", gid).
  315. Where("pf", pf).
  316. Group("userId").
  317. Select("count(*) as seeAdsCount", "SUM(CASE WHEN adsState = 2 THEN 1 ELSE 0 END) AS state2Count", "userId").
  318. Scan(&seeAdsData).Error
  319. if err != nil {
  320. response.Fail(c, 1003, err.Error())
  321. return
  322. }
  323. for _, ads := range seeAdsData {
  324. seeAdsDataMap[ads.UserId] = ads.SeeAdsCount
  325. seeAdsDataMap2[ads.UserId] = ads.State2Count
  326. }
  327. fmt.Println("查询广告数据完成:", time.Since(start1))
  328. //格式化,存入数据库
  329. var userIdList []model.User
  330. err = global.App.DB.Table("user").Where("gid", gid).
  331. Select("id", "userId").
  332. Where("pf", pf).Scan(&userIdList).Error
  333. if err != nil {
  334. response.Fail(c, 1004, err.Error())
  335. return
  336. }
  337. //fmt.Println(len(userIdList))
  338. userBehavior := make(map[int]model.UserBehavior)
  339. for _, users := range userIdList {
  340. userBehavior[users.UserId] = model.UserBehavior{
  341. ID: users.ID,
  342. //Duration: int(SummaryData[users.UserId]),
  343. StartNum: loginDataMap[users.UserId],
  344. AdCount: seeAdsDataMap[users.UserId],
  345. AdExpCount: seeAdsDataMap2[users.UserId],
  346. }
  347. }
  348. var userBehaviorList []model.UserBehavior
  349. for _, Behavior := range userBehavior {
  350. userBehaviorList = append(userBehaviorList, Behavior)
  351. }
  352. err = global.App.DB.Table("user_behavior").Clauses(clause.OnConflict{
  353. Columns: []clause.Column{{Name: "id"}}, // 冲突列(主键)
  354. DoUpdates: clause.AssignmentColumns([]string{"startNum", "adCount", "adExpCount"}), // 需要更新的列
  355. }).CreateInBatches(&userBehaviorList, 1000).Error
  356. if err != nil {
  357. //global.App.Log.Error(userBehavior)
  358. response.Fail(c, 1005, err.Error())
  359. return
  360. }
  361. fmt.Println("存入汇总完成:", time.Since(start1))
  362. }
  363. }
  364. func TestClickHouse(c *gin.Context) {
  365. //sql := "CREATE TABLE IF NOT EXISTS example_table (pf FixedString(10), gid FixedString(20), userId Int64) ENGINE = MergeTree() ORDER BY (pf, gid, userId);"
  366. //err := global.App.Clickhouse.Exec(sql).Error
  367. now := time.Now()
  368. //for i := 100; i >= 0; i-- {
  369. // global.App.Clickhouse.Table("example_table").Create(map[string]interface{}{
  370. // "gid": "aaa",
  371. // "pf": "wx",
  372. // "userId": 1001,
  373. // })
  374. //
  375. // fmt.Println(time.Since(now))
  376. //
  377. //}
  378. type ssss struct {
  379. UserId int `json:"userId" gorm:"not null;column:userId;"`
  380. Gid string `json:"gid" gorm:"not null;column:gid;"`
  381. Pf string `json:"pf" gorm:"not null;column:pf;"`
  382. }
  383. var insert []ssss
  384. for i := 100; i >= 0; i-- {
  385. insert = append(insert, ssss{
  386. UserId: 1001,
  387. Gid: "aaa",
  388. Pf: "wx",
  389. })
  390. }
  391. global.App.Clickhouse.Table("example_table").CreateInBatches(&insert, 1000)
  392. fmt.Println(time.Since(now))
  393. //var res []struct {
  394. // UserId int `json:"userId" gorm:"not null;column:userId;"`
  395. // Gid string `json:"gid" gorm:"not null;column:gid;"`
  396. // Pf string `json:"pf" gorm:"not null;column:pf;"`
  397. //}
  398. //global.App.Clickhouse.Table("example_table").Scan(&res)
  399. //
  400. //response.Success(c, gin.H{
  401. // "res": res,
  402. //})
  403. }
  404. func TestLevel(c *gin.Context) {
  405. //block := [][]string{
  406. // {
  407. // "*0", "*0",
  408. // },
  409. // {
  410. // "e0", "e0", "f0", "f0",
  411. // },
  412. // {
  413. // "*0", "*0",
  414. // },
  415. //}
  416. ////随机移动
  417. }
  418. func move() {
  419. }
  420. func check() {
  421. }