|
@@ -1,10 +1,13 @@
|
|
|
package v1
|
|
|
|
|
|
import (
|
|
|
+ "bufio"
|
|
|
"context"
|
|
|
"designs/app/common/request"
|
|
|
"designs/app/common/response"
|
|
|
+ "designs/config"
|
|
|
"designs/global"
|
|
|
+ "designs/model"
|
|
|
"designs/service"
|
|
|
"designs/utils"
|
|
|
"encoding/json"
|
|
@@ -14,6 +17,8 @@ import (
|
|
|
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
|
|
"math"
|
|
|
"math/big"
|
|
|
+ "os"
|
|
|
+ "path/filepath"
|
|
|
"strconv"
|
|
|
"strings"
|
|
|
"time"
|
|
@@ -26,6 +31,7 @@ func Summary(c *gin.Context) {
|
|
|
Pf string `form:"pf" json:"pf" binding:"required"`
|
|
|
}{})
|
|
|
|
|
|
+ start := time.Now()
|
|
|
//查询用户总数
|
|
|
var userCount int64
|
|
|
err := global.App.DB.Table("user").
|
|
@@ -36,7 +42,7 @@ func Summary(c *gin.Context) {
|
|
|
response.Fail(c, 1001, err.Error())
|
|
|
return
|
|
|
}
|
|
|
-
|
|
|
+ fmt.Println(time.Since(start))
|
|
|
//查询近七日活跃总数
|
|
|
now := time.Now()
|
|
|
sevenDayAgo := now.AddDate(0, 0, -7)
|
|
@@ -54,6 +60,7 @@ func Summary(c *gin.Context) {
|
|
|
response.Fail(c, 1001, err.Error())
|
|
|
return
|
|
|
}
|
|
|
+ fmt.Println(time.Since(start))
|
|
|
|
|
|
var activeUserCount30 int64
|
|
|
err = global.App.DB.Table("user_login").
|
|
@@ -67,6 +74,7 @@ func Summary(c *gin.Context) {
|
|
|
response.Fail(c, 1001, err.Error())
|
|
|
return
|
|
|
}
|
|
|
+ fmt.Println(time.Since(start))
|
|
|
|
|
|
//从redis中读取缓存
|
|
|
var avgTimeString string
|
|
@@ -243,6 +251,7 @@ func UserTrendsOverview(c *gin.Context) {
|
|
|
EndTime string `form:"endTime" json:"endTime" binding:"required"`
|
|
|
}{})
|
|
|
|
|
|
+ start := time.Now()
|
|
|
//查询用户新增
|
|
|
var registerCount int64
|
|
|
err := global.App.DB.Table("user").
|
|
@@ -255,19 +264,20 @@ func UserTrendsOverview(c *gin.Context) {
|
|
|
response.Fail(c, 1001, err.Error())
|
|
|
return
|
|
|
}
|
|
|
-
|
|
|
+ fmt.Println(time.Since(start))
|
|
|
//查询活跃设备
|
|
|
var activeCount int64
|
|
|
- err = global.App.DB.Table("user_online").
|
|
|
- Where("gid", form.Gid).
|
|
|
- Where("pf", form.Pf).
|
|
|
- Where("logTime", ">=", form.StartTime).
|
|
|
- Where("logTime", "<=", form.EndTime).
|
|
|
- Distinct("userId").Count(&activeCount).Error
|
|
|
- if err != nil {
|
|
|
- response.Fail(c, 1001, err.Error())
|
|
|
- return
|
|
|
+ //sql := "SELECT COUNT(DISTINCT(`userId`)) FROM `user_online` USE INDEX(date) WHERE gid = ? AND pf = ? AND date >= ? AND date <= ?"
|
|
|
+ //err = global.App.DB.Raw(sql, form.Gid, form.Pf, strings.Replace(form.StartTime, "-", "", 5), strings.Replace(form.EndTime, "-", "", 5)).Count(&activeCount).Error
|
|
|
+
|
|
|
+ UserLoginBydDay := utils.GetTimeDayDate(form.StartTime, form.EndTime) //用户分别是在哪天注册的
|
|
|
+ var activeLog [][]int
|
|
|
+ //逐天读取每天活跃的用户数据
|
|
|
+ for k := range UserLoginBydDay {
|
|
|
+ activeLog = append(activeLog, service.GetLocalActiveLog(form.Gid, form.Pf, k))
|
|
|
}
|
|
|
+ activeLogCount := utils.UnionOfSubArrays(activeLog)
|
|
|
+ activeCount = int64(len(activeLogCount))
|
|
|
|
|
|
//查询启动次数
|
|
|
var loginCount int64
|
|
@@ -281,6 +291,7 @@ func UserTrendsOverview(c *gin.Context) {
|
|
|
response.Fail(c, 1001, err.Error())
|
|
|
return
|
|
|
}
|
|
|
+ fmt.Println(time.Since(start))
|
|
|
//查询平均启动时长
|
|
|
//查询活跃用户月趋势图
|
|
|
_, _, activeTime, err := service.GetActiveMouthDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
@@ -408,36 +419,45 @@ func DataTradesDetail(c *gin.Context) {
|
|
|
}
|
|
|
var data = make(map[string]dayData)
|
|
|
|
|
|
+ start := time.Now()
|
|
|
//查询新增设备趋势图
|
|
|
NewUser, _, _, err := service.GetRegisterDayDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
if err != nil {
|
|
|
response.Fail(c, 1001, err.Error())
|
|
|
return
|
|
|
}
|
|
|
+ fmt.Println(time.Since(start))
|
|
|
//查询活跃用户趋势图
|
|
|
ActiveUser, _, _, err := service.GetActiveDayDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
if err != nil {
|
|
|
response.Fail(c, 1001, err.Error())
|
|
|
return
|
|
|
}
|
|
|
+ fmt.Println(time.Since(start))
|
|
|
+
|
|
|
//查询活跃用户周趋势图
|
|
|
ActiveUserWeek, _, _, err := service.GetActiveWeekDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
if err != nil {
|
|
|
response.Fail(c, 1001, err.Error())
|
|
|
return
|
|
|
}
|
|
|
+ fmt.Println(time.Since(start))
|
|
|
+
|
|
|
//查询活跃用户月趋势图
|
|
|
ActiveUserMouth, _, _, err := service.GetActiveMouthDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
if err != nil {
|
|
|
response.Fail(c, 1001, err.Error())
|
|
|
return
|
|
|
}
|
|
|
+ fmt.Println(time.Since(start))
|
|
|
+
|
|
|
//查询启动次数
|
|
|
ActiveStart, _, _, err := service.GetActiveMouthDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
if err != nil {
|
|
|
response.Fail(c, 1001, err.Error())
|
|
|
return
|
|
|
}
|
|
|
+ fmt.Println(time.Since(start))
|
|
|
|
|
|
//查询平均启动时间
|
|
|
AvgTime, _, _, err := service.UserOnlineSummaryByDay(form.Gid, form.Pf, form.StartTime, form.EndTime)
|
|
@@ -462,6 +482,18 @@ func DataTradesDetail(c *gin.Context) {
|
|
|
|
|
|
}
|
|
|
|
|
|
+func OnlineToFile(c *gin.Context) {
|
|
|
+ service.OnlineToFile()
|
|
|
+
|
|
|
+ //now := time.Now()
|
|
|
+ //for i := 1; i <= 60; i++ {
|
|
|
+ // lastDay := now.AddDate(0, 0, -i).Format("20060102")
|
|
|
+ // crons.AdsDataSummary(lastDay)
|
|
|
+ //}
|
|
|
+
|
|
|
+ response.Success(c, gin.H{})
|
|
|
+}
|
|
|
+
|
|
|
func RemainDataBydDay(c *gin.Context) {
|
|
|
form := request.Check(c, &struct {
|
|
|
Gid string `form:"gid" json:"gid" binding:"required"`
|
|
@@ -471,7 +503,13 @@ func RemainDataBydDay(c *gin.Context) {
|
|
|
Type int `form:"type" json:"type" binding:"required"`
|
|
|
}{})
|
|
|
|
|
|
- data, err := service.RemainDataBydDay(form.Type, form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
+ //data, err := service.RemainDataBydDay(form.Type, form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
+ //if err != nil {
|
|
|
+ // response.Fail(c, 1001, err.Error())
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+
|
|
|
+ data, err := service.RemainDataBydDayNew(form.Type, form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
if err != nil {
|
|
|
response.Fail(c, 1001, err.Error())
|
|
|
return
|
|
@@ -1092,8 +1130,8 @@ func SetGameCondition(c *gin.Context) {
|
|
|
func GameConditionList(c *gin.Context) {
|
|
|
form := request.Check(c, &struct {
|
|
|
Gid string `form:"gid" json:"gid" binding:"required"`
|
|
|
- Pid int64 `form:"pid" json:"pid" binding:""`
|
|
|
- Aid int64 `form:"aid" json:"aid" binding:""`
|
|
|
+ Pid string `form:"pid" json:"pid" binding:""`
|
|
|
+ Aid string `form:"aid" json:"aid" binding:""`
|
|
|
Type string `form:"type" json:"type" binding:""`
|
|
|
Offset int `form:"offset" json:"offset" binding:""`
|
|
|
Limit int `form:"limit" json:"limit" binding:"required"`
|
|
@@ -1105,10 +1143,10 @@ func GameConditionList(c *gin.Context) {
|
|
|
if form.Type != "" {
|
|
|
filter["type"] = form.Type
|
|
|
}
|
|
|
- if form.Pid != 0 {
|
|
|
+ if form.Pid != "" {
|
|
|
filter["pid"] = form.Pid
|
|
|
}
|
|
|
- if form.Aid != 0 {
|
|
|
+ if form.Aid != "" {
|
|
|
filter["aid"] = form.Aid
|
|
|
}
|
|
|
|
|
@@ -1393,3 +1431,132 @@ func BehaviorListCake(c *gin.Context) {
|
|
|
})
|
|
|
|
|
|
}
|
|
|
+
|
|
|
+func SplitOnlineData(c *gin.Context) {
|
|
|
+
|
|
|
+ //只保留最近30天的数据
|
|
|
+ now := time.Now()
|
|
|
+ for i := 0; i <= 29; i++ {
|
|
|
+ date := now.AddDate(0, 0, -i).Format("2006-01-02")
|
|
|
+ date1 := now.AddDate(0, 0, -i).Format("20060102")
|
|
|
+
|
|
|
+ var dir string
|
|
|
+ if config.Get("app.local") == "local" {
|
|
|
+ //url = "mongodb://localhost:27017"
|
|
|
+ dir = "storage"
|
|
|
+ } else {
|
|
|
+ dir = "/www/wwwroot/chunhao_receive/storage"
|
|
|
+ }
|
|
|
+
|
|
|
+ //读取对应的文件夹
|
|
|
+ dirPath := filepath.Join(dir, date)
|
|
|
+ dateDir, _ := os.ReadDir(dirPath)
|
|
|
+ fmt.Println(dateDir, date)
|
|
|
+
|
|
|
+ for _, v := range dateDir {
|
|
|
+ var onlineData []model.UserOnlineSplit
|
|
|
+
|
|
|
+ fileName := v.Name()
|
|
|
+
|
|
|
+ fileNameSplit := strings.Split(fileName, "_")
|
|
|
+
|
|
|
+ if len(fileNameSplit) < 2 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ last := fileNameSplit[len(fileNameSplit)-1]
|
|
|
+ pf := last[:len(last)-4]
|
|
|
+
|
|
|
+ gid := strings.TrimRight(fileName, "_"+last)
|
|
|
+
|
|
|
+ fmt.Println("fileName:", fileName)
|
|
|
+ fmt.Println("gid:", gid)
|
|
|
+ fmt.Println("last:", last)
|
|
|
+
|
|
|
+ //err1 := DropTable(gid, date1)
|
|
|
+ //fmt.Println(err1)
|
|
|
+ //continue
|
|
|
+
|
|
|
+ filePath := filepath.Join(dirPath, fileName)
|
|
|
+ file, _ := os.Open(filePath)
|
|
|
+
|
|
|
+ // 创建 Scanner 对象
|
|
|
+ scanner := bufio.NewScanner(file)
|
|
|
+ // 逐行读取文件内容
|
|
|
+ lineNumber := 1
|
|
|
+ for scanner.Scan() {
|
|
|
+ line := scanner.Text() // 获取当前行内容
|
|
|
+ lineNumber++
|
|
|
+ lineData := strings.Split(line, ",")
|
|
|
+
|
|
|
+ userId, _ := strconv.Atoi(lineData[0])
|
|
|
+ types, _ := strconv.Atoi(lineData[1])
|
|
|
+
|
|
|
+ loc, _ := time.LoadLocation("Asia/Shanghai")
|
|
|
+ LogTime, _ := time.ParseInLocation("2006-01-02 15:04:05", lineData[2], loc)
|
|
|
+
|
|
|
+ //fmt.Println(LogTime, lineData[2])
|
|
|
+ onlineData = append(onlineData, model.UserOnlineSplit{
|
|
|
+ Pf: pf,
|
|
|
+ UserId: userId,
|
|
|
+ Type: types,
|
|
|
+ LogTime: LogTime,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ file.Close() // 确保函数结束时关闭文件
|
|
|
+
|
|
|
+ //数据存入mysql
|
|
|
+ err := InsertOnlineSpilt(gid, date1, onlineData)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("插入数据库错误", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ fmt.Println(date, "数据归档数据库完成,耗时:", time.Since(now))
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func InsertOnlineSpilt(gid string, date string, online []model.UserOnlineSplit) error {
|
|
|
+
|
|
|
+ //先根据date ,gid ,判定存哪个表
|
|
|
+ tableName := "user_online" + "_" + date + "_" + gid
|
|
|
+
|
|
|
+ err := global.App.DB.Exec(`
|
|
|
+ CREATE TABLE IF NOT EXISTS ` + tableName + ` (
|
|
|
+ id int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
|
|
|
+ pf varchar(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '登录路径',
|
|
|
+ userId int NOT NULL COMMENT '用户ID',
|
|
|
+ type tinyint NOT NULL COMMENT '1:在线 2.下线',
|
|
|
+ logTime timestamp NULL DEFAULT NULL COMMENT '时间',
|
|
|
+ PRIMARY KEY (id) USING BTREE,
|
|
|
+ KEY pf (pf)
|
|
|
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
|
|
+ `).Error
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("创建数据库失败", tableName, err.Error())
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ err = global.App.DB.Table(tableName).CreateInBatches(&online, 1000).Error
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func DropTable(gid string, date string) error {
|
|
|
+
|
|
|
+ //先根据date ,gid ,判定存哪个表
|
|
|
+ tableName := "user_online" + "_" + date + "_" + gid
|
|
|
+
|
|
|
+ sql := "DROP TABLE IF EXISTS " + tableName
|
|
|
+ err := global.App.DB.Exec(sql).Error
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("创建数据库失败", tableName, err.Error())
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|