|
@@ -0,0 +1,464 @@
|
|
|
+package v1
|
|
|
+
|
|
|
+import (
|
|
|
+ "designs/app/common/request"
|
|
|
+ "designs/app/common/response"
|
|
|
+ "designs/global"
|
|
|
+ "designs/service"
|
|
|
+ "designs/utils"
|
|
|
+ "github.com/gin-gonic/gin"
|
|
|
+ "math"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+// 总览
|
|
|
+func Summary(c *gin.Context) {
|
|
|
+ form := request.Check(c, &struct {
|
|
|
+ Gid string `form:"gid" json:"gid" binding:"required"`
|
|
|
+ Pf string `form:"pf" json:"pf" binding:"required"`
|
|
|
+ }{})
|
|
|
+
|
|
|
+ //查询用户总数
|
|
|
+ var userCount int64
|
|
|
+ err := global.App.DB.Table("user").
|
|
|
+ Where("gid", form.Gid).
|
|
|
+ Where("pf", form.Pf).
|
|
|
+ Count(&userCount).Error
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //查询近七日活跃总数
|
|
|
+ now := time.Now()
|
|
|
+ sevenDayAgo := now.AddDate(0, 0, -7)
|
|
|
+ thirtyDayAgo := now.AddDate(0, 0, -30)
|
|
|
+
|
|
|
+ var activeUserCount7 int64
|
|
|
+ err = global.App.DB.Table("user_login").
|
|
|
+ Where("gid", form.Gid).
|
|
|
+ Where("pf", form.Pf).
|
|
|
+ Where("loginTime", ">=", sevenDayAgo).
|
|
|
+ Where("loginTime", "<=", now).
|
|
|
+ Distinct("userId").
|
|
|
+ Count(&activeUserCount7).Error
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ var activeUserCount30 int64
|
|
|
+ err = global.App.DB.Table("user_login").
|
|
|
+ Where("gid", form.Gid).
|
|
|
+ Where("pf", form.Pf).
|
|
|
+ Where("loginTime", ">=", thirtyDayAgo).
|
|
|
+ Where("loginTime", "<=", now).
|
|
|
+ Distinct("userId").
|
|
|
+ Count(&activeUserCount30).Error
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //查询 近7日单设备日均使用时长
|
|
|
+ res, err := service.UserOnlineSummary(form.Gid, form.Pf, "", sevenDayAgo.Format("2006-01-02 15:04:05"), now.Format("2006-01-02 15:04:05"))
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var avgTime int
|
|
|
+ for _, v := range res {
|
|
|
+ avgTime = avgTime + int(v)
|
|
|
+ }
|
|
|
+ var avgTimeString string
|
|
|
+ if avgTime != 0 {
|
|
|
+ avgTime = int(math.Round(float64(avgTime / len(res))))
|
|
|
+ avgTimeString = utils.TimeStampToMDS(avgTime)
|
|
|
+ } else {
|
|
|
+ avgTimeString = "00.00"
|
|
|
+ }
|
|
|
+
|
|
|
+ response.Success(c, gin.H{
|
|
|
+ "data": map[string]interface{}{
|
|
|
+ "userCount": userCount,
|
|
|
+ "activeUserCount7": activeUserCount7,
|
|
|
+ "activeUserCount30": activeUserCount30,
|
|
|
+ "activeUserCount7Time": avgTimeString,
|
|
|
+ },
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 时段分布
|
|
|
+func TimeDistributionData(c *gin.Context) {
|
|
|
+ form := request.Check(c, &struct {
|
|
|
+ Gid string `form:"gid" json:"gid" binding:"required"`
|
|
|
+ Pf string `form:"pf" json:"pf" binding:"required"`
|
|
|
+ Type int `form:"type" json:"type" binding:"required"`
|
|
|
+ }{})
|
|
|
+
|
|
|
+ var data interface{}
|
|
|
+ if form.Type == 1 {
|
|
|
+ //新增用户
|
|
|
+ todayTimeDistribution, yesterdayTimeDistribution, yesterdayCount, todayCount, yesterdayThisTimeCount, err := service.GetRegisterTimeDistribution(form.Pf, form.Gid)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ data = map[string]interface{}{
|
|
|
+ "today": todayTimeDistribution,
|
|
|
+ "yesterday": yesterdayTimeDistribution,
|
|
|
+ "yesterdayCount": yesterdayCount,
|
|
|
+ "yesterdayThisTimeCount": yesterdayThisTimeCount,
|
|
|
+ "todayCount": todayCount,
|
|
|
+ }
|
|
|
+ } else if form.Type == 2 {
|
|
|
+ //活跃设备
|
|
|
+ todayTimeDistribution, yesterdayTimeDistribution, yesterdayCount, todayCount, yesterdayThisTimeCount, err := service.GetActiveTimeDistribution(form.Pf, form.Gid)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ data = map[string]interface{}{
|
|
|
+ "today": todayTimeDistribution,
|
|
|
+ "yesterday": yesterdayTimeDistribution,
|
|
|
+ "yesterdayCount": yesterdayCount,
|
|
|
+ "yesterdayThisTimeCount": yesterdayThisTimeCount,
|
|
|
+ "todayCount": todayCount,
|
|
|
+ }
|
|
|
+ } else if form.Type == 3 {
|
|
|
+ //启动次数
|
|
|
+ todayTimeDistribution, yesterdayTimeDistribution, yesterdayCount, todayCount, yesterdayThisTimeCount, err := service.GetActiveTimeDistribution(form.Pf, form.Gid)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ data = map[string]interface{}{
|
|
|
+ "today": todayTimeDistribution,
|
|
|
+ "yesterday": yesterdayTimeDistribution,
|
|
|
+ "yesterdayCount": yesterdayCount,
|
|
|
+ "yesterdayThisTimeCount": yesterdayThisTimeCount,
|
|
|
+ "todayCount": todayCount,
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ response.Fail(c, 1003, "type错误")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ response.Success(c, gin.H{
|
|
|
+ "data": data,
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 30日趋势
|
|
|
+func MouthDistributionData(c *gin.Context) {
|
|
|
+ form := request.Check(c, &struct {
|
|
|
+ Gid string `form:"gid" json:"gid" binding:"required"`
|
|
|
+ Pf string `form:"pf" json:"pf" binding:"required"`
|
|
|
+ Type int `form:"type" json:"type" binding:"required"`
|
|
|
+ }{})
|
|
|
+ now := time.Now()
|
|
|
+ EndTime := now.Format("2006-01-02")
|
|
|
+ StartTime := now.AddDate(0, 0, -29).Format("2006-01-02")
|
|
|
+
|
|
|
+ data := make(map[string]interface{})
|
|
|
+ if form.Type == 1 {
|
|
|
+ //查询新增设备趋势图
|
|
|
+ TimeDistribution, count, avg, err := service.GetRegisterDayDistribution(form.Pf, form.Gid, StartTime, EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ data["timeDistribution"] = TimeDistribution
|
|
|
+ data["count"] = count
|
|
|
+ data["avg"] = avg
|
|
|
+
|
|
|
+ } else if form.Type == 2 {
|
|
|
+ //查询活跃用户趋势图
|
|
|
+ TimeDistribution, count, avg, err := service.GetActiveDayDistribution(form.Pf, form.Gid, StartTime, EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ data["timeDistribution"] = TimeDistribution
|
|
|
+ data["count"] = count
|
|
|
+ data["avg"] = avg
|
|
|
+ } else if form.Type == 3 {
|
|
|
+ //查询启动次数
|
|
|
+ TimeDistribution, count, avg, err := service.GetActiveMouthDistribution(form.Pf, form.Gid, StartTime, EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ data["timeDistribution"] = TimeDistribution
|
|
|
+ data["count"] = count
|
|
|
+ data["avg"] = avg
|
|
|
+
|
|
|
+ } else if form.Type == 4 {
|
|
|
+ //查询单用户使用时长
|
|
|
+ TimeDistribution, count, avg, err := service.GetActiveMouthDistribution(form.Pf, form.Gid, StartTime, EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ data["timeDistribution"] = TimeDistribution
|
|
|
+ data["count"] = count
|
|
|
+ data["avg"] = avg
|
|
|
+ } else if form.Type == 5 {
|
|
|
+ //查询用户留存率
|
|
|
+ //todo
|
|
|
+
|
|
|
+ } else {
|
|
|
+ response.Fail(c, 1003, "type错误")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ response.Success(c, gin.H{
|
|
|
+ "data": data,
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 用户趋势 总览
|
|
|
+func UserTrendsOverview(c *gin.Context) {
|
|
|
+ form := request.Check(c, &struct {
|
|
|
+ Gid string `form:"gid" json:"gid" binding:"required"`
|
|
|
+ Pf string `form:"pf" json:"pf" binding:"required"`
|
|
|
+ StartTime string `form:"startTime" json:"startTime" binding:"required"`
|
|
|
+ EndTime string `form:"endTime" json:"endTime" binding:"required"`
|
|
|
+ }{})
|
|
|
+
|
|
|
+ //查询用户新增
|
|
|
+ var registerCount int64
|
|
|
+ err := global.App.DB.Table("user").
|
|
|
+ Where("gid", form.Gid).
|
|
|
+ Where("pf", form.Pf).
|
|
|
+ Where("createdAt", ">=", form.StartTime).
|
|
|
+ Where("createdAt", "<=", form.EndTime).
|
|
|
+ Count(®isterCount).Error
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //查询活跃设备
|
|
|
+ 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
|
|
|
+ }
|
|
|
+
|
|
|
+ //查询启动次数
|
|
|
+ var loginCount int64
|
|
|
+ err = global.App.DB.Table("user_login").
|
|
|
+ Where("gid", form.Gid).
|
|
|
+ Where("pf", form.Pf).
|
|
|
+ Where("loginTime", ">=", form.StartTime).
|
|
|
+ Where("loginTime", "<=", form.EndTime).
|
|
|
+ Count(&loginCount).Error
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //查询平均启动时长
|
|
|
+ //查询活跃用户月趋势图
|
|
|
+ _, _, activeTime, err := service.GetActiveMouthDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //查询 DAU/MAU
|
|
|
+ //todo 查询方式需要更新
|
|
|
+ dauMau := 0.3
|
|
|
+
|
|
|
+ response.Success(c, gin.H{
|
|
|
+ "data": map[string]interface{}{
|
|
|
+ "registerCount": registerCount,
|
|
|
+ "activeCount": activeCount,
|
|
|
+ "loginCount": loginCount,
|
|
|
+ "activeTime": activeTime,
|
|
|
+ "dauMau": dauMau,
|
|
|
+ },
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 数据趋势
|
|
|
+func DataTrades(c *gin.Context) {
|
|
|
+ form := request.Check(c, &struct {
|
|
|
+ Gid string `form:"gid" json:"gid" binding:"required"`
|
|
|
+ Pf string `form:"pf" json:"pf" binding:"required"`
|
|
|
+ StartTime string `form:"startTime" json:"startTime" binding:"required"`
|
|
|
+ EndTime string `form:"endTime" json:"endTime" binding:"required"`
|
|
|
+ Type int `form:"type" json:"type" binding:"required"`
|
|
|
+ }{})
|
|
|
+ data := make(map[string]interface{})
|
|
|
+ if form.Type == 1 {
|
|
|
+ //查询新增设备趋势图
|
|
|
+ TimeDistribution, count, avg, err := service.GetRegisterDayDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ data["imeDistribution"] = TimeDistribution
|
|
|
+ data["count"] = count
|
|
|
+ data["avg"] = avg
|
|
|
+ } else if form.Type == 2 {
|
|
|
+ //查询活跃用户趋势图
|
|
|
+ TimeDistribution, count, avg, err := service.GetActiveDayDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ data["imeDistribution"] = TimeDistribution
|
|
|
+ data["count"] = count
|
|
|
+ data["avg"] = avg
|
|
|
+ } else if form.Type == 3 {
|
|
|
+ //查询活跃用户周趋势图
|
|
|
+ TimeDistribution, count, avg, err := service.GetActiveWeekDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ data["imeDistribution"] = TimeDistribution
|
|
|
+ data["count"] = count
|
|
|
+ data["avg"] = avg
|
|
|
+
|
|
|
+ } else if form.Type == 4 {
|
|
|
+ //查询活跃用户月趋势图
|
|
|
+ TimeDistribution, count, avg, err := service.GetActiveMouthDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ data["imeDistribution"] = TimeDistribution
|
|
|
+ data["count"] = count
|
|
|
+ data["avg"] = avg
|
|
|
+ } else if form.Type == 5 {
|
|
|
+ //查询启动次数
|
|
|
+ TimeDistribution, count, avg, err := service.GetActiveMouthDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ data["imeDistribution"] = TimeDistribution
|
|
|
+ data["count"] = count
|
|
|
+ data["avg"] = avg
|
|
|
+ } else if form.Type == 6 {
|
|
|
+ //查询平均启动时间
|
|
|
+ TimeDistribution, count, avg, err := service.UserOnlineSummaryByDay(form.Gid, form.Pf, form.StartTime, form.EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ data["imeDistribution"] = TimeDistribution
|
|
|
+ data["count"] = count
|
|
|
+ data["avg"] = avg
|
|
|
+
|
|
|
+ } else {
|
|
|
+ response.Fail(c, 1003, "type 错误")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ response.Success(c, gin.H{
|
|
|
+ "data": data,
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 数据趋势的整合
|
|
|
+func DataTradesDetail(c *gin.Context) {
|
|
|
+ form := request.Check(c, &struct {
|
|
|
+ Gid string `form:"gid" json:"gid" binding:"required"`
|
|
|
+ Pf string `form:"pf" json:"pf" binding:"required"`
|
|
|
+ StartTime string `form:"startTime" json:"startTime" binding:"required"`
|
|
|
+ EndTime string `form:"endTime" json:"endTime" binding:"required"`
|
|
|
+ }{})
|
|
|
+
|
|
|
+ type dayData struct {
|
|
|
+ NewUser int `json:"newUser"`
|
|
|
+ ActiveUser int `json:"activeUser"`
|
|
|
+ ActiveUserWeek int `json:"activeUserWeek"`
|
|
|
+ ActiveUserMouth int `json:"activeUserMouth"`
|
|
|
+ ActiveStart int `json:"activeStart"`
|
|
|
+ AvgTime int `json:"avgTime"`
|
|
|
+ }
|
|
|
+ var data = make(map[string]dayData)
|
|
|
+ //查询新增设备趋势图
|
|
|
+ NewUser, _, _, err := service.GetRegisterDayDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //查询活跃用户趋势图
|
|
|
+ ActiveUser, _, _, err := service.GetActiveDayDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //查询活跃用户周趋势图
|
|
|
+ ActiveUserWeek, _, _, err := service.GetActiveWeekDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //查询活跃用户月趋势图
|
|
|
+ ActiveUserMouth, _, _, err := service.GetActiveMouthDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //查询启动次数
|
|
|
+ ActiveStart, _, _, err := service.GetActiveMouthDistribution(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //查询平均启动时间
|
|
|
+ AvgTime, _, _, err := service.UserOnlineSummaryByDay(form.Gid, form.Pf, form.StartTime, form.EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ for k := range AvgTime {
|
|
|
+ data[k] = dayData{
|
|
|
+ NewUser: NewUser[k],
|
|
|
+ ActiveUser: ActiveUser[k],
|
|
|
+ ActiveUserWeek: ActiveUserWeek[k],
|
|
|
+ ActiveUserMouth: ActiveUserMouth[k],
|
|
|
+ ActiveStart: ActiveStart[k],
|
|
|
+ AvgTime: AvgTime[k],
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ response.Success(c, gin.H{
|
|
|
+ "data": data,
|
|
|
+ })
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+func RemainDataBydDay(c *gin.Context) {
|
|
|
+ form := request.Check(c, &struct {
|
|
|
+ Gid string `form:"gid" json:"gid" binding:"required"`
|
|
|
+ Pf string `form:"pf" json:"pf" binding:"required"`
|
|
|
+ StartTime string `form:"startTime" json:"startTime" binding:"required"`
|
|
|
+ EndTime string `form:"endTime" json:"endTime" binding:"required"`
|
|
|
+ }{})
|
|
|
+
|
|
|
+ data, err := service.RemainDataBydDay(form.Pf, form.Gid, form.StartTime, form.EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ response.Success(c, gin.H{
|
|
|
+ "data": data,
|
|
|
+ })
|
|
|
+}
|