|
@@ -0,0 +1,300 @@
|
|
|
|
|
+package v1
|
|
|
|
|
+
|
|
|
|
|
+import (
|
|
|
|
|
+ "designs/app/common/request"
|
|
|
|
|
+ "designs/app/common/response"
|
|
|
|
|
+ "designs/global"
|
|
|
|
|
+ "designs/model"
|
|
|
|
|
+ "designs/utils"
|
|
|
|
|
+ "fmt"
|
|
|
|
|
+ "github.com/gin-gonic/gin"
|
|
|
|
|
+ "github.com/pkg/errors"
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+func UserActionList(c *gin.Context) {
|
|
|
|
|
+ form := request.Check(c, &struct {
|
|
|
|
|
+ Gid string `form:"gid" binding:"required"`
|
|
|
|
|
+ Pf string `form:"pf" binding:""`
|
|
|
|
|
+ StartTime string `form:"startTime" binding:"required"`
|
|
|
|
|
+ EndTime string `form:"endTime" binding:"required"`
|
|
|
|
|
+ }{})
|
|
|
|
|
+
|
|
|
|
|
+ //查询出所有的事件
|
|
|
|
|
+ var actionList []model.GameAction
|
|
|
|
|
+ err := global.App.DB.Table("game_action").
|
|
|
|
|
+ Where("gid", form.Gid).
|
|
|
|
|
+ Select("id", "actionId", "actionName").
|
|
|
|
|
+ Order("id desc").Scan(&actionList).Error
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ response.Fail(c, 1003, err.Error())
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ //查询出时间段内的活跃用户,登录次数
|
|
|
|
|
+ var userLogin []model.UserLogin
|
|
|
|
|
+ err = global.App.DB.Table("user_login").
|
|
|
|
|
+ Where("gid", form.Gid).
|
|
|
|
|
+ Where("loginTime", ">=", form.StartTime).
|
|
|
|
|
+ Where("loginTime", "<=", form.EndTime).
|
|
|
|
|
+ Select("userId", "loginTime").
|
|
|
|
|
+ Scan(&userLogin).Error
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ userLoginCount := len(userLogin)
|
|
|
|
|
+
|
|
|
|
|
+ //查询出时间段内事件触发数量,以及触发人的ID
|
|
|
|
|
+ var userAction []model.UserAction
|
|
|
|
|
+ err = global.App.DB.Table("user_action").
|
|
|
|
|
+ Where("gid", form.Gid).
|
|
|
|
|
+ Where("createdAt", ">=", form.StartTime).
|
|
|
|
|
+ Where("createdAt", "<=", form.EndTime).
|
|
|
|
|
+ Select("id", "actionId", "userId", "createdAt").
|
|
|
|
|
+ Scan(&userAction).Error
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ response.Fail(c, 1002, err.Error())
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ //计算事件的触发总数和触发用户数
|
|
|
|
|
+ actionSumMap := make(map[string]int)
|
|
|
|
|
+ actionUserSumMap := make(map[string][]int)
|
|
|
|
|
+ for _, action := range userAction {
|
|
|
|
|
+ actionSumMap[action.ActionId]++
|
|
|
|
|
+ actionUserSumMap[action.ActionId] = append(actionUserSumMap[action.ActionId], action.UserId)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //根据事件触发和活跃用户数量进行比对得出其他数据
|
|
|
|
|
+ activeUser := make(map[int]bool)
|
|
|
|
|
+ var activeUserSlice []int
|
|
|
|
|
+ for _, users := range userLogin {
|
|
|
|
|
+ activeUser[users.UserId] = true
|
|
|
|
|
+ }
|
|
|
|
|
+ for k := range activeUser {
|
|
|
|
|
+ activeUserSlice = append(activeUserSlice, k)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ type responses struct {
|
|
|
|
|
+ ActionId string `json:"actionId"`
|
|
|
|
|
+ ActionName string `json:"actionName"`
|
|
|
|
|
+ ActionCount int `json:"actionCount"`
|
|
|
|
|
+ ActionUserCount int `json:"actionUserCount"`
|
|
|
|
|
+ ActiveUserRate float64 `json:"activeUserRate"`
|
|
|
|
|
+ LoginActiveRate float64 `json:"loginActiveRate"`
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var res []responses
|
|
|
|
|
+
|
|
|
|
|
+ for _, v := range actionList {
|
|
|
|
|
+ var ActiveUserRate float64
|
|
|
|
|
+ var LoginActiveRate float64
|
|
|
|
|
+ if userLoginCount > 0 {
|
|
|
|
|
+ ActiveUserRate = float64(actionSumMap[v.ActionId] / userLoginCount)
|
|
|
|
|
+ LoginActiveRate = float64(len(actionUserSumMap[v.ActionId]) / userLoginCount)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ res = append(res, responses{
|
|
|
|
|
+ ActionId: v.ActionId,
|
|
|
|
|
+ ActionName: v.ActionName,
|
|
|
|
|
+ ActionCount: actionSumMap[v.ActionId],
|
|
|
|
|
+ ActionUserCount: len(actionUserSumMap[v.ActionId]),
|
|
|
|
|
+ ActiveUserRate: ActiveUserRate,
|
|
|
|
|
+ LoginActiveRate: LoginActiveRate,
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ response.Success(c, gin.H{
|
|
|
|
|
+ "data": res,
|
|
|
|
|
+ "count": len(res),
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func UserActionDetail(c *gin.Context) {
|
|
|
|
|
+ form := request.Check(c, &struct {
|
|
|
|
|
+ Id int `form:"id" binding:"required"`
|
|
|
|
|
+ StartTime string `form:"startTime" binding:"required"`
|
|
|
|
|
+ EndTime string `form:"endTime" binding:"required"`
|
|
|
|
|
+ }{})
|
|
|
|
|
+
|
|
|
|
|
+ //查询启动次数
|
|
|
|
|
+ var action model.GameAction
|
|
|
|
|
+ err := global.App.DB.Table("game_action").
|
|
|
|
|
+ Where("id", form.Id).Find(&action).Error
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ var userAction []struct {
|
|
|
|
|
+ UserId int `json:"userId" gorm:"not null;column:userId;"`
|
|
|
|
|
+ CreatedAt string `json:"createdAt" gorm:"not null;column:createdAt;"`
|
|
|
|
|
+ }
|
|
|
|
|
+ err = global.App.DB.Table("user_action").
|
|
|
|
|
+ Where("gid", action.Gid).
|
|
|
|
|
+ Where("actionId", action.ActionId).
|
|
|
|
|
+ Select("userId", "DATE_FORMAT(createdAt, '%Y-%m-%d') as createdAt").
|
|
|
|
|
+ Scan(&userAction).Error
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ response.Fail(c, 1002, err.Error())
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //查询出时间段内的活跃用户,登录次数
|
|
|
|
|
+ var userLogin []struct {
|
|
|
|
|
+ UserId int `json:"userId" gorm:"not null;column:userId;"`
|
|
|
|
|
+ CreatedAt string `json:"createdAt" gorm:"not null;column:createdAt;"`
|
|
|
|
|
+ }
|
|
|
|
|
+ err = global.App.DB.Table("user_login").
|
|
|
|
|
+ Where("gid", action.Gid).
|
|
|
|
|
+ Where("loginTime", ">=", form.StartTime).
|
|
|
|
|
+ Where("loginTime", "<=", form.EndTime).
|
|
|
|
|
+ Select("userId", "DATE_FORMAT(loginTime, '%Y-%m-%d') as createdAt").
|
|
|
|
|
+ Scan(&userLogin).Error
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ //userLoginCount := len(userLogin)
|
|
|
|
|
+
|
|
|
|
|
+ activeCount := make(map[string]int)
|
|
|
|
|
+ activeCountUser := make(map[string]map[int]bool)
|
|
|
|
|
+
|
|
|
|
|
+ //根据日期进行分组
|
|
|
|
|
+ for _, v := range userAction {
|
|
|
|
|
+ activeCount[v.CreatedAt]++
|
|
|
|
|
+
|
|
|
|
|
+ if activeCountUser[v.CreatedAt] == nil {
|
|
|
|
|
+ activeCountUser[v.CreatedAt] = make(map[int]bool)
|
|
|
|
|
+ }
|
|
|
|
|
+ activeCountUser[v.CreatedAt][v.UserId] = true
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ days := utils.GetTimeDayDateFormat(form.StartTime, form.EndTime)
|
|
|
|
|
+
|
|
|
|
|
+ type responses struct {
|
|
|
|
|
+ Date string `json:"date"`
|
|
|
|
|
+ ActiveCount int `json:"activeCount"`
|
|
|
|
|
+ ActiveUserCount int `json:"activeUserCount"`
|
|
|
|
|
+ ActiveCountRate float64 `json:"activeCountRate"`
|
|
|
|
|
+ ActiveCountUser float64 `json:"activeCountUser"`
|
|
|
|
|
+ }
|
|
|
|
|
+ var res []responses
|
|
|
|
|
+ //输出格式
|
|
|
|
|
+ for _, v := range days {
|
|
|
|
|
+ res = append(res, responses{
|
|
|
|
|
+ Date: v,
|
|
|
|
|
+ ActiveCount: activeCount[v],
|
|
|
|
|
+ ActiveUserCount: len(activeCountUser[v]),
|
|
|
|
|
+ ActiveCountRate: float64(activeCount[v] / 1),
|
|
|
|
|
+ ActiveCountUser: float64(len(activeCountUser[v]) / 1),
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ response.Success(c, gin.H{
|
|
|
|
|
+ "data": res,
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func UserActionDetailDistribution(c *gin.Context) {
|
|
|
|
|
+ form := request.Check(c, &struct {
|
|
|
|
|
+ Id int `form:"id" binding:"required"`
|
|
|
|
|
+ StartTime string `form:"startTime" binding:"required"`
|
|
|
|
|
+ EndTime string `form:"endTime" binding:"required"`
|
|
|
|
|
+ Type int `form:"type" binding:"required"`
|
|
|
|
|
+ }{})
|
|
|
|
|
+
|
|
|
|
|
+ var action model.GameAction
|
|
|
|
|
+ err := global.App.DB.Table("game_action").
|
|
|
|
|
+ Where("id", form.Id).Find(&action).Error
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ response.Fail(c, 1001, err.Error())
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ res := make(map[string]interface{})
|
|
|
|
|
+ if form.Type == 1 {
|
|
|
|
|
+ var userAction []struct {
|
|
|
|
|
+ UserId int `json:"userId" gorm:"not null;column:userId;"`
|
|
|
|
|
+ CreatedAt string `json:"createdAt" gorm:"not null;column:createdAt;"`
|
|
|
|
|
+ }
|
|
|
|
|
+ err = global.App.DB.Table("user_action").
|
|
|
|
|
+ Where("gid", action.Gid).
|
|
|
|
|
+ Where("actionId", action.ActionId).
|
|
|
|
|
+ Select("userId", "DATE_FORMAT(createdAt, '%Y-%m-%d') as createdAt").
|
|
|
|
|
+ Scan(&userAction).Error
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ response.Fail(c, 1002, err.Error())
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ activeCount := make(map[string]int)
|
|
|
|
|
+ for _, v := range userAction {
|
|
|
|
|
+ activeCount[v.CreatedAt]++
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ days := utils.GetTimeDayDateFormat(form.StartTime, form.EndTime)
|
|
|
|
|
+ for _, v := range days {
|
|
|
|
|
+ res[v] = activeCount[v]
|
|
|
|
|
+ }
|
|
|
|
|
+ fmt.Print(len(userAction) / len(days))
|
|
|
|
|
+
|
|
|
|
|
+ response.Success(c, gin.H{"data": res, "avg": fmt.Sprintf("%.2f", float64(len(userAction))/float64(len(days)))})
|
|
|
|
|
+ } else if form.Type == 2 {
|
|
|
|
|
+ var userAction []struct {
|
|
|
|
|
+ UserId int `json:"userId" gorm:"not null;column:userId;"`
|
|
|
|
|
+ CreatedAt string `json:"createdAt" gorm:"not null;column:createdAt;"`
|
|
|
|
|
+ }
|
|
|
|
|
+ err = global.App.DB.Table("user_action").
|
|
|
|
|
+ Where("gid", action.Gid).
|
|
|
|
|
+ Where("actionId", action.ActionId).
|
|
|
|
|
+ Select("userId", "DATE_FORMAT(createdAt, '%Y-%m-%d') as createdAt").
|
|
|
|
|
+ Scan(&userAction).Error
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ response.Fail(c, 1002, err.Error())
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ activeCount := make(map[string]map[int]bool)
|
|
|
|
|
+ for _, v := range userAction {
|
|
|
|
|
+ if activeCount[v.CreatedAt] == nil {
|
|
|
|
|
+ activeCount[v.CreatedAt] = make(map[int]bool)
|
|
|
|
|
+ }
|
|
|
|
|
+ activeCount[v.CreatedAt][v.UserId] = true
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ days := utils.GetTimeDayDateFormat(form.StartTime, form.EndTime)
|
|
|
|
|
+ for _, v := range days {
|
|
|
|
|
+ res[v] = len(activeCount[v])
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ response.Success(c, gin.H{"data": res, "avg": fmt.Sprintf("%.2f", float64(len(userAction))/float64(len(days)))})
|
|
|
|
|
+ } else if form.Type == 3 {
|
|
|
|
|
+ var userAction []struct {
|
|
|
|
|
+ UserId int `json:"userId" gorm:"not null;column:userId;"`
|
|
|
|
|
+ CreatedAt string `json:"createdAt" gorm:"not null;column:createdAt;"`
|
|
|
|
|
+ }
|
|
|
|
|
+ err = global.App.DB.Table("user_action").
|
|
|
|
|
+ Where("gid", action.Gid).
|
|
|
|
|
+ Where("actionId", action.ActionId).
|
|
|
|
|
+ Select("userId", "DATE_FORMAT(createdAt, '%Y-%m-%d') as createdAt").
|
|
|
|
|
+ Scan(&userAction).Error
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ response.Fail(c, 1002, err.Error())
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ activeCount := make(map[string]map[int]bool)
|
|
|
|
|
+ for _, v := range userAction {
|
|
|
|
|
+ if activeCount[v.CreatedAt] == nil {
|
|
|
|
|
+ activeCount[v.CreatedAt] = make(map[int]bool)
|
|
|
|
|
+ }
|
|
|
|
|
+ activeCount[v.CreatedAt][v.UserId] = true
|
|
|
|
|
+ }
|
|
|
|
|
+ //查询活跃用户
|
|
|
|
|
+
|
|
|
|
|
+ } else if form.Type == 4 {
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ response.Fail(c, 1003, errors.New("type 错误"))
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+}
|