|
@@ -9,6 +9,7 @@ import (
|
|
|
"leadGeneration/public"
|
|
|
"leadGeneration/vars"
|
|
|
"log"
|
|
|
+ "sort"
|
|
|
"sync"
|
|
|
"time"
|
|
|
)
|
|
@@ -17,6 +18,7 @@ import (
|
|
|
type AheadManager struct {
|
|
|
Conf vars.AheadConfig
|
|
|
UserGroup map[string]int
|
|
|
+ BatchFlag string
|
|
|
sync.RWMutex
|
|
|
}
|
|
|
|
|
@@ -49,10 +51,6 @@ func (this *AheadManager) GetData(userId, keyWords string, isNew bool) map[strin
|
|
|
}
|
|
|
//查询数据
|
|
|
rDate := search.AdvancedProject(userId, keyWords)
|
|
|
- //if err != nil {
|
|
|
- // log.Printf("[ERROR]AheadManager %s %s GetData Error %v\n", userId, keyWords, err)
|
|
|
- // return nil
|
|
|
- //}
|
|
|
//累计请求计数
|
|
|
if rDate != nil && len(rDate) > 0 {
|
|
|
if num := redis.Incr(AheadCacheDb, cacheKey); num == 1 {
|
|
@@ -62,6 +60,17 @@ func (this *AheadManager) GetData(userId, keyWords string, isNew bool) map[strin
|
|
|
return rDate
|
|
|
}
|
|
|
|
|
|
+// Click 用户点击
|
|
|
+func (this *AheadManager) Click(userId string) bool {
|
|
|
+ this.Lock()
|
|
|
+ defer this.Unlock()
|
|
|
+ if v, ok := this.UserGroup[userId]; ok {
|
|
|
+ this.UserGroup[userId] = v
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
//CheckGroupUser 校验用户是否有资格展示
|
|
|
func (this *AheadManager) checkGroupUser(userId string) (exists bool) {
|
|
|
this.RLock()
|
|
@@ -87,38 +96,134 @@ func (this *AheadManager) UpdateUserGroupJob() {
|
|
|
if this.Conf.Prop <= 0 {
|
|
|
return
|
|
|
}
|
|
|
+ log.Printf("[MANAGER-INFO]AheadManager UserGroup Change Start\n")
|
|
|
+ this.BatchFlag = getWeekBatchName(time.Now())
|
|
|
|
|
|
- //查询上批次活跃用户
|
|
|
newMap := map[string]int{}
|
|
|
- var userArr []string
|
|
|
- //测试账户
|
|
|
- if len(vars.Config.TestUid) > 0 {
|
|
|
- for _, uid := range vars.Config.TestUid {
|
|
|
- newMap[uid] = 0
|
|
|
- }
|
|
|
- } else {
|
|
|
- //查询月活用户
|
|
|
- userArr = activeUsers.GetWeekActiveFreeUsers()
|
|
|
- }
|
|
|
- this.Lock()
|
|
|
- defer this.Unlock()
|
|
|
- //if len(this.UserGroup) != 0 {
|
|
|
- // for uId, num := range this.UserGroup {
|
|
|
- // if num > this.Conf.SaveClickTimes {
|
|
|
- // newMap[uId] = 0
|
|
|
- // }
|
|
|
- // }
|
|
|
- //}
|
|
|
//新圈用户
|
|
|
- for _, uId := range userArr {
|
|
|
+ for _, uId := range this.getUserGroup() {
|
|
|
newMap[uId] = 0
|
|
|
}
|
|
|
+ this.Lock()
|
|
|
+ defer this.Unlock()
|
|
|
this.UserGroup = newMap
|
|
|
+ log.Printf("[MANAGER-INFO]AheadManager UserGroup Changed Finish Total is %d \n", len(this.UserGroup))
|
|
|
+}
|
|
|
+
|
|
|
+//getUserGroup 取用户
|
|
|
+func (this *AheadManager) getUserGroup() (userIds []string) {
|
|
|
+ //当前批次是否已有数据
|
|
|
+ rData := public.UserAnalyseDb.SelectBySql("SELECT user_mongoid AS uid FROM user_leadGeneration_group WHERE group_type = 0 AND group_name=?", this.BatchFlag)
|
|
|
+ if rData != nil || len(*rData) == 0 {
|
|
|
+ log.Printf("[MANAGER-INFO]AheadManager getUserGroup from Db Total is %d \n", len(*rData))
|
|
|
+ userIds = make([]string, 0, len(*rData))
|
|
|
+ for _, m := range *rData {
|
|
|
+ if uId, _ := m["uid"].(string); uId != "" {
|
|
|
+ userIds = append(userIds, uId)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //无数据则重新生成用户群组数据
|
|
|
+ if len(userIds) == 0 {
|
|
|
+ log.Printf("[MANAGER-INFO]AheadManager getUserGroup createNewGroup start\n")
|
|
|
+ var (
|
|
|
+ wg sync.WaitGroup
|
|
|
+ newActiveGroup, lastActiveGroup, testUserGroup []string
|
|
|
+ )
|
|
|
+ wg.Add(3)
|
|
|
+
|
|
|
+ //新活跃用户
|
|
|
+ go func() {
|
|
|
+ defer wg.Done()
|
|
|
+ newActiveGroup = this.sortUserByBatchAndGetFinal(activeUsers.GetWeekActiveFreeUsers())
|
|
|
+ activeUsers.SaveBatchGroup(newActiveGroup, 0, this.BatchFlag, "newActive")
|
|
|
+ }()
|
|
|
|
|
|
- log.Printf("AheadManager NewGroup %v\n", newMap)
|
|
|
+ //测试用户群组
|
|
|
+ go func() {
|
|
|
+ defer wg.Done()
|
|
|
+ if len(vars.Config.TestUid) > 0 {
|
|
|
+ for _, uid := range vars.Config.TestUid {
|
|
|
+ testUserGroup = append(testUserGroup, uid)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ activeUsers.SaveBatchGroup(testUserGroup, 0, this.BatchFlag, "testUser")
|
|
|
+ }()
|
|
|
|
|
|
+ //查询上批次活跃用户(点击量满足用户)
|
|
|
+ go func() {
|
|
|
+ defer wg.Done()
|
|
|
+ this.RLock()
|
|
|
+ defer this.RUnlock()
|
|
|
+ for uId, clickNum := range this.UserGroup {
|
|
|
+ if clickNum > this.Conf.SaveClickTimes {
|
|
|
+ lastActiveGroup = append(lastActiveGroup, uId)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ activeUsers.SaveBatchGroup(lastActiveGroup, 0, this.BatchFlag, "oldActive")
|
|
|
+ }()
|
|
|
+ wg.Wait()
|
|
|
+ userIds = make([]string, 0, len(newActiveGroup)+len(lastActiveGroup)+len(testUserGroup))
|
|
|
+ userIds = append(userIds, newActiveGroup...)
|
|
|
+ userIds = append(userIds, lastActiveGroup...)
|
|
|
+ userIds = append(userIds, testUserGroup...)
|
|
|
+
|
|
|
+ log.Printf("[MANAGER-INFO]AheadManager getUserGroup createNewGroup Total %d \n New:%d Old:%d Test:%d \n",
|
|
|
+ len(userIds), len(newActiveGroup), len(lastActiveGroup), len(testUserGroup))
|
|
|
+ }
|
|
|
+ return
|
|
|
}
|
|
|
|
|
|
-func sortUserByBatchAndGetFinal() {
|
|
|
+// sortUserByBatchAndGetFinal 根据百分比取用户,优先级【没有参与>参与时间早的>参与时间晚的】
|
|
|
+func (this *AheadManager) sortUserByBatchAndGetFinal(userIds []string) (rData []string) {
|
|
|
+ log.Printf("[MANAGER-INFO]AheadManager sortUserByBatchAndGetFinal Begin\n")
|
|
|
+ total := int(this.Conf.Prop * float64(len(userIds)))
|
|
|
+ //查询历史分组情况
|
|
|
+ gData := public.UserAnalyseDb.SelectBySql("SELECT * FROM ( SELECT user_mongoid AS uid, MAX( UNIX_TIMESTAMP(create_time) ) AS gTime FROM user_leadGeneration_group WHERE group_type = 0 GROUP BY user_mongoid ) AS groupData ORDER BY gTime ASC")
|
|
|
+ log.Printf("[MANAGER-INFO]AheadManager sortUserByBatchAndGetFinal Search Finished\n")
|
|
|
+ // 无记录直接返回数组前final_count个用户id
|
|
|
+ if gData == nil || len(*gData) == 0 {
|
|
|
+ return userIds[:total]
|
|
|
+ }
|
|
|
+ sortMap := map[string]int64{}
|
|
|
+ for _, m := range *gData {
|
|
|
+ if uId, _ := m["uid"].(string); uId != "" {
|
|
|
+ num, _ := m["gTime"].(int64)
|
|
|
+ sortMap[uId] = num
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.Printf("[MANAGER-INFO]AheadManager sortUserByBatchAndGetFinal Sort Begin\n")
|
|
|
+ // 有记录进行排序筛选
|
|
|
+ sort.Slice(userIds, func(i, j int) bool {
|
|
|
+ iNum, _ := sortMap[userIds[i]]
|
|
|
+ jNum, _ := sortMap[userIds[j]]
|
|
|
+ if iNum < jNum {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ return false
|
|
|
+ })
|
|
|
+ log.Printf("[MANAGER-INFO]AheadManager sortUserByBatchAndGetFinal Finished\n")
|
|
|
+ return userIds[:total]
|
|
|
+}
|
|
|
+
|
|
|
+//getWeekBatchName 返回周批次标识
|
|
|
+//return Example 2022Y73W
|
|
|
+func getWeekBatchName(t time.Time) string {
|
|
|
+ yearDay := t.YearDay()
|
|
|
+ yearFirstDay := t.AddDate(0, 0, -yearDay+1)
|
|
|
+ firstDayInWeek := int(yearFirstDay.Weekday())
|
|
|
+
|
|
|
+ //今年第一周有几天
|
|
|
+ firstWeekDays := 1
|
|
|
+ if firstDayInWeek != 0 {
|
|
|
+ firstWeekDays = 7 - firstDayInWeek + 1
|
|
|
+ }
|
|
|
+ var week int
|
|
|
+ if yearDay <= firstWeekDays {
|
|
|
+ week = 1
|
|
|
+ } else {
|
|
|
+ week = (yearDay-firstWeekDays)/7 + 2
|
|
|
+ }
|
|
|
|
|
|
+ return fmt.Sprintf("%dY%02dW", t.Year(), week)
|
|
|
}
|