|
@@ -9,14 +9,17 @@ import (
|
|
|
"fmt"
|
|
|
"github.com/gin-gonic/gin"
|
|
|
"github.com/pkg/errors"
|
|
|
+ "sort"
|
|
|
+ "strconv"
|
|
|
+ "strings"
|
|
|
)
|
|
|
|
|
|
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"`
|
|
|
+ Gid string `form:"gid" binding:"required"`
|
|
|
+ //Pf []string `form:"pf" binding:""`
|
|
|
+ StartTime string `form:"startTime" binding:"required"`
|
|
|
+ EndTime string `form:"endTime" binding:"required"`
|
|
|
}{})
|
|
|
|
|
|
form.EndTime = form.EndTime + " 23:59:59"
|
|
@@ -34,31 +37,33 @@ func UserActionList(c *gin.Context) {
|
|
|
response.Fail(c, 1003, err.Error())
|
|
|
return
|
|
|
}
|
|
|
- //查询出时间段内的活跃用户,登录次数
|
|
|
- var userLogin []model.UserLogin
|
|
|
- query1 := global.App.DB.Table("user_login")
|
|
|
- if len(form.Pf) > 0 {
|
|
|
|
|
|
- query1 = query1.WhereIn("pf", form.Pf)
|
|
|
+ var optionIdList []int
|
|
|
+ for _, v := range actionList {
|
|
|
+ optionIdList = append(optionIdList, v.ID)
|
|
|
}
|
|
|
- err = query1.
|
|
|
- Where("gid", form.Gid).
|
|
|
- Where("loginTime", ">=", form.StartTime).
|
|
|
- Where("loginTime", "<=", form.EndTime).
|
|
|
- Select("userId", "loginTime").
|
|
|
- Scan(&userLogin).Error
|
|
|
+
|
|
|
+ //查询出有无选项
|
|
|
+ var optionIdList1 []int
|
|
|
+ err = global.App.DB.Table("game_action_option").
|
|
|
+ WhereIn("actionId", optionIdList).
|
|
|
+ Distinct("actionId").
|
|
|
+ Pluck("actionId", &optionIdList1).Error
|
|
|
if err != nil {
|
|
|
- response.Fail(c, 1001, err.Error())
|
|
|
+ response.Fail(c, 1003, err.Error())
|
|
|
return
|
|
|
}
|
|
|
+
|
|
|
+ //查出用户登录数据
|
|
|
+ userLogin, err := GetUserLogin(form.Gid, form.StartTime, form.EndTime)
|
|
|
userLoginCount := len(userLogin)
|
|
|
|
|
|
//查询出时间段内事件触发数量,以及触发人的ID
|
|
|
var userAction []model.UserAction
|
|
|
query2 := global.App.DB.Table("user_action")
|
|
|
- if len(form.Pf) > 0 {
|
|
|
- query2 = query2.WhereIn("pf", form.Pf)
|
|
|
- }
|
|
|
+ //if len(form.Pf) > 0 {
|
|
|
+ // query2 = query2.WhereIn("pf", form.Pf)
|
|
|
+ //}
|
|
|
err = query2.
|
|
|
Where("gid", form.Gid).
|
|
|
Where("createdAt", ">=", form.StartTime).
|
|
@@ -71,11 +76,14 @@ func UserActionList(c *gin.Context) {
|
|
|
}
|
|
|
//计算事件的触发总数和触发用户数
|
|
|
actionSumMap := make(map[string]int)
|
|
|
- actionUserSumMap := make(map[string][]int)
|
|
|
- //fmt.Println(userAction)
|
|
|
+ actionUserSumMap := make(map[string]map[int]bool)
|
|
|
+
|
|
|
for _, action := range userAction {
|
|
|
+ if actionUserSumMap[action.ActionId] == nil {
|
|
|
+ actionUserSumMap[action.ActionId] = make(map[int]bool)
|
|
|
+ }
|
|
|
actionSumMap[action.ActionId]++
|
|
|
- actionUserSumMap[action.ActionId] = append(actionUserSumMap[action.ActionId], action.UserId)
|
|
|
+ actionUserSumMap[action.ActionId][action.UserId] = true
|
|
|
}
|
|
|
|
|
|
//根据事件触发和活跃用户数量进行比对得出其他数据
|
|
@@ -96,16 +104,16 @@ func UserActionList(c *gin.Context) {
|
|
|
ActionUserCount int `json:"actionUserCount"`
|
|
|
ActiveUserRate float64 `json:"activeUserRate"`
|
|
|
LoginActiveRate float64 `json:"loginActiveRate"`
|
|
|
+ HaveOption bool `json:"haveOption"`
|
|
|
}
|
|
|
|
|
|
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)
|
|
|
+ ActiveUserRate = DivideWithPrecision(actionSumMap[v.ActionId], userLoginCount)
|
|
|
+ LoginActiveRate = DivideWithPrecision(len(actionUserSumMap[v.ActionId]), userLoginCount)
|
|
|
}
|
|
|
|
|
|
res = append(res, responses{
|
|
@@ -116,15 +124,166 @@ func UserActionList(c *gin.Context) {
|
|
|
ActionUserCount: len(actionUserSumMap[v.ActionId]),
|
|
|
ActiveUserRate: ActiveUserRate,
|
|
|
LoginActiveRate: LoginActiveRate,
|
|
|
+ HaveOption: utils.InArray(v.ID, optionIdList1),
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ response.Success(c, gin.H{
|
|
|
+ "data": res,
|
|
|
+ "count": len(res),
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+func GetUserLogin(Gid string, StartTime string, EndTime string) ([]model.UserLogin, error) {
|
|
|
+ //查询出时间段内的活跃用户,登录次数
|
|
|
+ var userLogin []model.UserLogin
|
|
|
+ query1 := global.App.DB.Table("user_login")
|
|
|
+ //if len(form.Pf) > 0 {
|
|
|
+ // query1 = query1.WhereIn("pf", form.Pf)
|
|
|
+ //}
|
|
|
+ err := query1.
|
|
|
+ Where("gid", Gid).
|
|
|
+ Where("loginTime", ">=", StartTime).
|
|
|
+ Where("loginTime", "<=", EndTime).
|
|
|
+ Select("userId", "loginTime").
|
|
|
+ Distinct("userId").
|
|
|
+ Scan(&userLogin).Error
|
|
|
+ if err != nil {
|
|
|
+ return userLogin, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return userLogin, nil
|
|
|
+}
|
|
|
+
|
|
|
+func UserActionOptionList(c *gin.Context) {
|
|
|
+ form := request.Check(c, &struct {
|
|
|
+ Gid string `form:"gid" binding:"required"`
|
|
|
+ ActionId string `form:"actionId" binding:"required"`
|
|
|
+ StartTime string `form:"startTime" binding:"required"`
|
|
|
+ EndTime string `form:"endTime" binding:"required"`
|
|
|
+ }{})
|
|
|
+
|
|
|
+ form.EndTime = form.EndTime + " 23:59:59"
|
|
|
+
|
|
|
+ //查出用户登录数据
|
|
|
+ userLogin, err := GetUserLogin(form.Gid, form.StartTime, form.EndTime)
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1003, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ userLoginCount := len(userLogin)
|
|
|
+ //查询出所有的事件选项
|
|
|
+ var actionOption []struct {
|
|
|
+ model.UserActionOption
|
|
|
+ UserId int `json:"userId" gorm:"not null;column:userId;"`
|
|
|
+ }
|
|
|
+
|
|
|
+ err = global.App.DB.Table("user_action_option").
|
|
|
+ LeftJoin("user_action", "user_action.id = user_action_option.UserActionId").
|
|
|
+ Where("user_action.actionId", form.ActionId).
|
|
|
+ Where("user_action.gid", form.Gid).
|
|
|
+ Where("user_action.createdAt", ">=", form.StartTime).
|
|
|
+ Where("user_action.createdAt", "<=", form.EndTime).
|
|
|
+ Select("user_action_option.*", "user_action.userId").
|
|
|
+ Scan(&actionOption).Error
|
|
|
+ if err != nil {
|
|
|
+ response.Fail(c, 1004, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //循环得出选项
|
|
|
+ optionList := make(map[string]int)
|
|
|
+ for _, v := range actionOption {
|
|
|
+ optionList[v.OptionId+"|"+v.Value]++
|
|
|
+ }
|
|
|
+
|
|
|
+ //根据人数进行比对
|
|
|
+ //计算事件的触发总数和触发用户数
|
|
|
+ actionSumMap := make(map[string]int)
|
|
|
+ actionUserSumMap := make(map[string]map[int]bool)
|
|
|
+
|
|
|
+ for _, action := range actionOption {
|
|
|
+ if actionUserSumMap[action.OptionId+"|"+action.Value] == nil {
|
|
|
+ actionUserSumMap[action.OptionId+"|"+action.Value] = make(map[int]bool)
|
|
|
+ }
|
|
|
+ actionSumMap[action.OptionId+"|"+action.Value]++
|
|
|
+ actionUserSumMap[action.OptionId+"|"+action.Value][action.UserId] = true
|
|
|
+ }
|
|
|
+
|
|
|
+ //根据事件触发和活跃用户数量进行比对得出其他数据
|
|
|
+ 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 {
|
|
|
+ Id int `json:"id"`
|
|
|
+ ActionId int `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
|
|
|
+
|
|
|
+ var optionName []model.GameActionOption
|
|
|
+ optionIdToName := make(map[string]string)
|
|
|
+ global.App.DB.Table("game_action_option").
|
|
|
+ LeftJoin("game_action", "game_action.id = game_action_option.actionId").
|
|
|
+ Where("gid", form.Gid).Scan(&optionName)
|
|
|
+ for _, v := range optionName {
|
|
|
+ optionIdToName[v.OptionId] = v.OptionName
|
|
|
+ }
|
|
|
+
|
|
|
+ for k, v := range optionList {
|
|
|
+ var ActiveUserRate float64
|
|
|
+ var LoginActiveRate float64
|
|
|
+ if userLoginCount > 0 {
|
|
|
+ ActiveUserRate = DivideWithPrecision(actionSumMap[k], userLoginCount)
|
|
|
+ LoginActiveRate = DivideWithPrecision(len(actionUserSumMap[k]), userLoginCount)
|
|
|
+ }
|
|
|
+
|
|
|
+ optionId := strings.Split(k, "|")[0]
|
|
|
+ value := strings.Split(k, "|")[1]
|
|
|
+ valueInt, _ := strconv.Atoi(value)
|
|
|
+
|
|
|
+ res = append(res, responses{
|
|
|
+ ActionId: valueInt,
|
|
|
+ ActionName: optionIdToName[optionId] + ":" + value,
|
|
|
+ ActionCount: v,
|
|
|
+ ActionUserCount: len(actionUserSumMap[k]),
|
|
|
+ ActiveUserRate: ActiveUserRate,
|
|
|
+ LoginActiveRate: LoginActiveRate,
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+ sort.Slice(res, func(i, j int) bool {
|
|
|
+ return res[i].ActionId < res[j].ActionId // 正序规则:i的Age小于j时返回true
|
|
|
+ })
|
|
|
+
|
|
|
response.Success(c, gin.H{
|
|
|
"data": res,
|
|
|
"count": len(res),
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+func DivideWithPrecision(a, b int) float64 {
|
|
|
+ if b == 0 {
|
|
|
+ panic("除数不能为零") // 实际项目中建议返回 error 类型
|
|
|
+ }
|
|
|
+ // 转换为浮点数再相除
|
|
|
+ result := float64(a) / float64(b)
|
|
|
+ // 格式化为三位小数并转换回 float64
|
|
|
+ formatted, _ := strconv.ParseFloat(fmt.Sprintf("%.3f", result), 64)
|
|
|
+ return formatted
|
|
|
+}
|
|
|
+
|
|
|
func UserActionDetail(c *gin.Context) {
|
|
|
form := request.Check(c, &struct {
|
|
|
Id int `form:"id" binding:"required"`
|