206 lines
5.5 KiB
Go
206 lines
5.5 KiB
Go
package analysis
|
|
|
|
import (
|
|
"database/sql"
|
|
"github.com/1340691923/xwl_bi/engine/logs"
|
|
|
|
"fmt"
|
|
"github.com/1340691923/xwl_bi/engine/db"
|
|
"github.com/1340691923/xwl_bi/platform-basic-libs/my_error"
|
|
"github.com/1340691923/xwl_bi/platform-basic-libs/request"
|
|
"github.com/1340691923/xwl_bi/platform-basic-libs/service/analysis/utils"
|
|
jsoniter "github.com/json-iterator/go"
|
|
"strconv"
|
|
)
|
|
|
|
type Funnel struct {
|
|
sql string
|
|
args []interface{}
|
|
req request.FunnelReqData
|
|
}
|
|
|
|
func (this *Funnel) GetExecSql() (SQL string, allArgs []interface{}, err error) {
|
|
|
|
startTime := this.req.Date[0] + " 00:00:00"
|
|
endTime := this.req.Date[1] + " 23:59:59"
|
|
|
|
windowSql := ""
|
|
|
|
for _, zhibiao := range this.req.ZhibiaoArr {
|
|
windowSql = windowSql + ","
|
|
|
|
windowSql = windowSql + fmt.Sprintf(" xwl_part_event = '%v' ", zhibiao.EventName)
|
|
|
|
if len(zhibiao.Relation.Filts) > 0 {
|
|
windowSql = windowSql + " and "
|
|
sql, args, _, err := utils.GetWhereSql(zhibiao.Relation)
|
|
|
|
if err != nil {
|
|
return SQL, allArgs, err
|
|
}
|
|
|
|
allArgs = append(allArgs, args...)
|
|
|
|
windowSql = windowSql + sql
|
|
}
|
|
}
|
|
|
|
var userFilterSql string
|
|
var userFilterArgs []interface{}
|
|
|
|
if len(this.req.WhereFilterByUser.Filts) > 0 {
|
|
var colArr []string
|
|
var sql string
|
|
sql, userFilterArgs, colArr, err = utils.GetWhereSql(this.req.WhereFilterByUser)
|
|
if err != nil {
|
|
return SQL, allArgs, err
|
|
}
|
|
userFilterSql = `and xwl_distinct_id in ( select xwl_distinct_id from ` + utils.GetUserTableView(this.req.Appid, colArr) + ` where ` + sql + ")"
|
|
}
|
|
|
|
whereFilterSql, whereFilterArgs, _, err := utils.GetWhereSql(this.req.WhereFilter)
|
|
|
|
whereFilterSql = whereFilterSql + this.sql
|
|
|
|
allArgs = append(allArgs, whereFilterArgs...)
|
|
|
|
allArgs = append(allArgs, this.args...)
|
|
|
|
allArgs = append(allArgs, userFilterArgs...)
|
|
|
|
if err != nil {
|
|
logs.Logger.Sugar().Errorf("req.WhereFilter", this.req.WhereFilter)
|
|
return
|
|
}
|
|
|
|
SQL = `SELECT '总体' as groupkey,level_index,count(1) as count,groupUniqArray(xwl_distinct_id) as ui FROM
|
|
(
|
|
SELECT xwl_distinct_id,
|
|
arrayWithConstant(windowFunnel_level, 1) levels,
|
|
arrayJoin(arrayEnumerate( levels )) level_index
|
|
FROM (
|
|
SELECT
|
|
xwl_distinct_id,
|
|
windowFunnel(` + strconv.Itoa(this.req.WindowTime) + `)(
|
|
xwl_part_date
|
|
` + windowSql + `
|
|
) AS windowFunnel_level
|
|
FROM xwl_event` + strconv.Itoa(this.req.Appid) + `
|
|
WHERE xwl_part_date >= toDateTime('` + startTime + `') and xwl_part_date <= toDateTime('` + endTime + `') and ` + whereFilterSql + ` ` + userFilterSql + `
|
|
GROUP BY xwl_distinct_id
|
|
)
|
|
)
|
|
group by level_index
|
|
ORDER BY level_index limit 1000
|
|
`
|
|
|
|
if len(this.req.GroupBy) > 0 {
|
|
groupSql := `SELECT toString(groupkey) as groupkey,level_index,count(1) as count ,groupUniqArray(xwl_distinct_id) as ui FROM
|
|
(
|
|
SELECT xwl_distinct_id, groupkey,
|
|
arrayWithConstant(windowFunnel_level, 1) levels,
|
|
arrayJoin(arrayEnumerate( levels )) level_index
|
|
FROM (
|
|
SELECT
|
|
xwl_distinct_id, ` + this.req.GroupBy[0] + ` groupkey,
|
|
windowFunnel(` + strconv.Itoa(this.req.WindowTime) + `)(
|
|
xwl_part_date
|
|
` + windowSql + `
|
|
) AS windowFunnel_level
|
|
FROM xwl_event` + strconv.Itoa(this.req.Appid) + `
|
|
WHERE xwl_part_date >= toDateTime('` + startTime + `') and xwl_part_date <= toDateTime('` + endTime + `') and ` + whereFilterSql + ` ` + userFilterSql + `
|
|
|
|
GROUP BY xwl_distinct_id,groupkey
|
|
)
|
|
)
|
|
group by groupkey,level_index
|
|
ORDER BY groupkey,level_index limit 1000
|
|
`
|
|
SQL = fmt.Sprintf("%s UNION ALL %s", SQL, groupSql)
|
|
allArgs = append(allArgs, allArgs...)
|
|
}
|
|
|
|
return SQL, allArgs, err
|
|
}
|
|
|
|
type FunnelRes struct {
|
|
LevelIndex int `json:"level_index" db:"level_index"`
|
|
Count int `json:"count" db:"count"`
|
|
UI []string `json:"ui" db:"ui"`
|
|
}
|
|
|
|
type FunnelGroupRes struct {
|
|
Groupkey sql.NullString `json:"groupkey" db:"groupkey"`
|
|
LevelIndex int `json:"level_index" db:"level_index"`
|
|
UI []string `json:"ui" db:"ui"`
|
|
Count int `json:"count" db:"count"`
|
|
}
|
|
|
|
func (this *Funnel) GetList() (interface{}, error) {
|
|
|
|
sql, args, err := this.GetExecSql()
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
logs.Logger.Sugar().Infof("SQL", sql, args)
|
|
|
|
var funnelGroupResList []FunnelGroupRes
|
|
|
|
if err := db.ClickHouseSqlx.Select(&funnelGroupResList, sql, args...); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
groupData := map[string][]FunnelRes{}
|
|
|
|
for _, v := range funnelGroupResList {
|
|
if _, ok := groupData[v.Groupkey.String]; !ok {
|
|
groupData[v.Groupkey.String] = []FunnelRes{}
|
|
}
|
|
groupData[v.Groupkey.String] = append(groupData[v.Groupkey.String], FunnelRes{
|
|
LevelIndex: v.LevelIndex,
|
|
Count: v.Count,
|
|
UI: v.UI,
|
|
})
|
|
}
|
|
|
|
return map[string]interface{}{"groupData": groupData}, nil
|
|
}
|
|
|
|
func NewFunnel(reqData []byte) (Ianalysis, error) {
|
|
obj := &Funnel{}
|
|
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
|
err := json.Unmarshal(reqData, &obj.req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(obj.req.Date) < 2 {
|
|
return nil, my_error.NewBusiness(ERROR_TABLE, TimeError)
|
|
}
|
|
if len(obj.req.ZhibiaoArr) > 30 {
|
|
return nil, my_error.NewBusiness(ERROR_TABLE, ZhiBiaoNumError)
|
|
}
|
|
var T int
|
|
switch obj.req.WindowTimeFormat {
|
|
case "天":
|
|
T = 60 * 60 * 24
|
|
case "小时":
|
|
T = 60 * 60
|
|
case "分钟":
|
|
T = 60
|
|
case "秒":
|
|
T = 1
|
|
default:
|
|
return nil, my_error.NewBusiness(ERROR_TABLE, TimeError)
|
|
}
|
|
obj.req.WindowTime = obj.req.WindowTime * T
|
|
obj.sql, obj.args, err = utils.GetUserGroupSqlAndArgs(obj.req.UserGroup, obj.req.Appid)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return obj, nil
|
|
}
|