1340691923@qq.com ebbf4120bf 第一次提交
2022-01-26 16:40:50 +08:00

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
}