123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- package job
- import (
- uuid2 "app.yhyue.com/moapp/jybase/go-xweb/uuid"
- "context"
- "github.com/gogf/gf/v2/frame/g"
- "github.com/gogf/gf/v2/util/gconv"
- "github.com/gogf/gf/v2/util/gutil"
- "github.com/pkg/errors"
- "regexp"
- "strings"
- "time"
- "workTasks/common/match"
- "workTasks/urlStatic/clickIterSource"
- )
- type (
- UserId string
- UUid string
- MatchObj struct {
- urlMapping map[string][]*matchItem
- result map[UUid]map[UserId]int64 //统计计算次数
- uuidCodeMapping map[UUid]string
- matchObj *match.TrieNode
- }
- matchItem struct {
- UUid UUid
- Name string
- Code string
- Rule map[string]interface{}
- }
- dbStruct struct {
- UserId string `json:"userId"`
- Code string `json:"code"`
- Num int64 `json:"num"`
- Date time.Time `json:"date"`
- }
- )
- var re = regexp.MustCompile(`\[[^\]]*\]`)
- func NewMatchObj(ctx context.Context) *MatchObj {
- var (
- urlMapping = map[string][]*matchItem{}
- treeMatch = &match.TrieNode{}
- uuidCodeMapping = map[UUid]string{}
- result = map[UUid]map[UserId]int64{}
- )
- for _, mObj := range g.Cfg().MustGet(ctx, "match").Maps() {
- var (
- name = gconv.String(mObj["name"])
- code = gconv.String(mObj["code"])
- rule = gconv.Map(mObj["rule"])
- urlArr []string
- newMatchItem []*matchItem
- )
- for _, s := range gconv.Strings(rule["url"]) {
- urlArr = append(urlArr, s)
- }
- arr := re.FindAllStringSubmatch(code, -1)
- if len(arr) > 0 {
- for _, str := range arr {
- var (
- rep = str[0]
- key = rep[1 : len(rep)-1]
- repVal = gconv.Strings(rule[key])
- )
- for _, val := range repVal {
- ruleItem := gconv.Map(gutil.Copy(rule))
- ruleItem[key] = val
- var (
- uuid = UUid(uuid2.New())
- finalCode = strings.ReplaceAll(code, rep, val)
- )
- uuidCodeMapping[uuid] = finalCode
- newMatchItem = append(newMatchItem, &matchItem{
- UUid: uuid,
- Name: name,
- Code: strings.ReplaceAll(code, rep, val),
- Rule: ruleItem,
- })
- }
- }
- } else {
- uuid := UUid(uuid2.New())
- uuidCodeMapping[uuid] = code
- newMatchItem = append(newMatchItem, &matchItem{
- UUid: uuid,
- Name: name,
- Code: code,
- Rule: rule,
- })
- }
- if len(urlArr) > 0 {
- for _, uStr := range gconv.Strings(rule["url"]) {
- if uStr != "" {
- treeMatch.Insert(uStr)
- }
- urlMapping[uStr] = newMatchItem
- }
- } else {
- urlMapping[""] = newMatchItem
- }
- }
- for uid, _ := range uuidCodeMapping {
- result[uid] = make(map[UserId]int64)
- }
- return &MatchObj{
- matchObj: treeMatch,
- urlMapping: urlMapping,
- result: result,
- uuidCodeMapping: uuidCodeMapping,
- }
- }
- func (o *MatchObj) Match(ctx context.Context, start, end time.Time) error {
- rows, err := clickIterSource.Ch_analysis.Query(ctx, "SELECT date,url,user_id,mini_program_code,action_id,breaker_name,page_id FROM dwd_f_personnel_behavior WHERE user_id!='' AND date>=? and date<? ", start.Format(time.DateTime), end.Format(time.DateTime))
- if err != nil {
- return errors.Wrap(err, "加载日志数据异常")
- }
- defer rows.Close()
- for rows.Next() {
- var (
- date time.Time
- user_id, url, mini_program_code, action_id, breaker_name, page_id string
- )
- if err := rows.Scan(
- &date, &url, &user_id, &mini_program_code, &action_id, &breaker_name, &page_id,
- ); err != nil {
- g.Log().Errorf(ctx, "字段映射异常 %v", err)
- }
- for _, str := range append(o.matchObj.FindWords(url), "") {
- for _, item := range o.urlMapping[str] {
- var isValid = func() bool {
- for key, val := range item.Rule {
- if key == "url" {
- continue
- }
- switch key {
- case "mini_program_code":
- if !hasPrefix(mini_program_code, val) {
- return false
- }
- case "action_id":
- if !compareValue(action_id, val) {
- return false
- }
- case "breaker_name":
- if !compareValue(breaker_name, val) {
- return false
- }
- case "page_id":
- if !compareValue(page_id, val) {
- return false
- }
- }
- }
- return true
- }()
- if isValid {
- if _, ok := o.result[item.UUid][UserId(user_id)]; ok {
- o.result[item.UUid][UserId(user_id)]++
- } else {
- o.result[item.UUid][UserId(user_id)] = 1
- }
- }
- }
- }
- }
- return nil
- }
- func compareValue(val string, setting interface{}) bool {
- if v, ok := setting.(string); ok {
- return v == val
- } else if v, ok := setting.([]string); ok {
- for _, s := range v {
- if s == val {
- return true
- }
- }
- }
- return false
- }
- func hasPrefix(val string, setting interface{}) bool {
- if v, ok := setting.(string); ok {
- return strings.HasPrefix(val, v)
- } else if v, ok := setting.([]string); ok {
- for _, s := range v {
- return strings.HasPrefix(val, s)
- }
- }
- return false
- }
- func (o *MatchObj) Save(ctx context.Context, data time.Time) error {
- var (
- r []*dbStruct
- total int
- )
- for uuid, mData := range o.result {
- for userId, num := range mData {
- r = append(r, &dbStruct{
- UserId: string(userId),
- Code: o.uuidCodeMapping[uuid],
- Num: num,
- Date: data,
- })
- }
- if len(r) >= 2000 {
- var t = r
- if _, err := g.DB().Save(ctx, "dwd_d_visit", t, 500); err != nil {
- g.Log().Errorf(ctx, "save errr %v", err)
- }
- total += 500
- r = []*dbStruct{}
- }
- }
- if len(r) > 0 {
- if _, err := g.DB().Save(ctx, "dwd_d_visit", r, 500); err != nil {
- g.Log().Errorf(ctx, "save errr %v", err)
- }
- total += len(r)
- }
- if total > 0 {
- g.Log().Infof(ctx, "任务[%s] 共%d条数据", data, total)
- }
- return nil
- }
|