Răsfoiți Sursa

feat:修改

wangchuanjin 1 an în urmă
părinte
comite
320c5da899

Fișier diff suprimat deoarece este prea mare
+ 0 - 0
subrecommend/README.md


+ 3 - 3
subrecommend/config.json

@@ -7,10 +7,10 @@
 	"matchDuration":60,
 	"matchDuration":60,
 	"freeMaxSize":10,
 	"freeMaxSize":10,
 	"payMaxSize":10,
 	"payMaxSize":10,
-	"userBatch":10,
+	"userBatch":5000,
 	"loadUserPoolSize":5,
 	"loadUserPoolSize":5,
 	"recomRul":"http://192.168.3.109:16699",
 	"recomRul":"http://192.168.3.109:16699",
 	"similarity": 0.5,
 	"similarity": 0.5,
-	"searchLimitDay":5,
-	"browseLimitDay":5
+	"searchLimitDay":15,
+	"browseLimitDay":15
 }
 }

+ 1 - 7
subrecommend/go.mod

@@ -4,12 +4,9 @@ go 1.20
 
 
 require (
 require (
 	app.yhyue.com/moapp/jybase v0.0.0-20240226084952-7e7b38ef8a66
 	app.yhyue.com/moapp/jybase v0.0.0-20240226084952-7e7b38ef8a66
-	bp.jydev.jianyu360.cn/BaseService/pushpkg v0.0.0-20240318095734-2ea90e3c94b7
+	bp.jydev.jianyu360.cn/BaseService/pushpkg v0.0.0-20240319084225-7516d93a6302
 	github.com/ClickHouse/clickhouse-go/v2 v2.2.0
 	github.com/ClickHouse/clickhouse-go/v2 v2.2.0
 	pushentniche v0.0.0-00010101000000-000000000000
 	pushentniche v0.0.0-00010101000000-000000000000
-	pushmember v0.0.0-00010101000000-000000000000
-	pushsubscribe v0.0.0-00010101000000-000000000000
-	pushsupersub v0.0.0-00010101000000-000000000000
 )
 )
 
 
 replace (
 replace (
@@ -20,7 +17,6 @@ replace (
 )
 )
 
 
 require (
 require (
-	app.yhyue.com/moapp/esv1 v0.0.0-20220414031211-3da4123e648d // indirect
 	bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.0 // indirect
 	bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.0 // indirect
 	bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.17 // indirect
 	bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.17 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
@@ -65,8 +61,6 @@ require (
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
 	github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
-	github.com/olivere/elastic v6.2.37+incompatible // indirect
-	github.com/olivere/elastic/v7 v7.0.22 // indirect
 	github.com/openzipkin/zipkin-go v0.4.1 // indirect
 	github.com/openzipkin/zipkin-go v0.4.1 // indirect
 	github.com/paulmach/orb v0.7.1 // indirect
 	github.com/paulmach/orb v0.7.1 // indirect
 	github.com/pelletier/go-toml/v2 v2.0.7 // indirect
 	github.com/pelletier/go-toml/v2 v2.0.7 // indirect

+ 2 - 6
subrecommend/go.sum

@@ -1,9 +1,8 @@
-app.yhyue.com/moapp/esv1 v0.0.0-20220414031211-3da4123e648d h1:WPsYuuptAd3UEgN+jPzpnsDe/OvcshDUUtOTZPYGSJ8=
 app.yhyue.com/moapp/esv1 v0.0.0-20220414031211-3da4123e648d/go.mod h1:91/lSD/hS+ckMVP3WdidRzDhC60lLMdyce9QHy0cSMA=
 app.yhyue.com/moapp/esv1 v0.0.0-20220414031211-3da4123e648d/go.mod h1:91/lSD/hS+ckMVP3WdidRzDhC60lLMdyce9QHy0cSMA=
 app.yhyue.com/moapp/jybase v0.0.0-20240226084952-7e7b38ef8a66 h1:kCRYqzclN4dtGuGC89ID2w5lGrJgqZC8bNL8mRR+tiU=
 app.yhyue.com/moapp/jybase v0.0.0-20240226084952-7e7b38ef8a66 h1:kCRYqzclN4dtGuGC89ID2w5lGrJgqZC8bNL8mRR+tiU=
 app.yhyue.com/moapp/jybase v0.0.0-20240226084952-7e7b38ef8a66/go.mod h1:XHNATN6tsJKHdCB0DbUtFdPPHXexTUFyB3RlO+lUUoM=
 app.yhyue.com/moapp/jybase v0.0.0-20240226084952-7e7b38ef8a66/go.mod h1:XHNATN6tsJKHdCB0DbUtFdPPHXexTUFyB3RlO+lUUoM=
-bp.jydev.jianyu360.cn/BaseService/pushpkg v0.0.0-20240318095734-2ea90e3c94b7 h1:dtWjTFgCXvpYbVMv9TsvBWlkw9g0rpM4zu8fIcIkIpE=
-bp.jydev.jianyu360.cn/BaseService/pushpkg v0.0.0-20240318095734-2ea90e3c94b7/go.mod h1:ECcF3i8XJ9J6vZ9ZK0gyxHqMRm9UBtgQAdWD2Tw7vvA=
+bp.jydev.jianyu360.cn/BaseService/pushpkg v0.0.0-20240319084225-7516d93a6302 h1:CT0UatwS06M44BJZfVRkmJt+G7xqO7rF4T7OsL4XBHk=
+bp.jydev.jianyu360.cn/BaseService/pushpkg v0.0.0-20240319084225-7516d93a6302/go.mod h1:ECcF3i8XJ9J6vZ9ZK0gyxHqMRm9UBtgQAdWD2Tw7vvA=
 bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.0 h1:60fFbyRAnn5vrnsPk99pVB2aJVin6nDIkNnmekdpFso=
 bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.0 h1:60fFbyRAnn5vrnsPk99pVB2aJVin6nDIkNnmekdpFso=
 bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.0/go.mod h1:rRiGzKG4F/fmkNxXQCxrkxNWc8yf1SmW8qWCKfGIQSM=
 bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.1.0/go.mod h1:rRiGzKG4F/fmkNxXQCxrkxNWc8yf1SmW8qWCKfGIQSM=
 bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.17 h1:QHjAuAYPJjml8e19ytWxgKAboo9+f6aQUH/s1UUEfrA=
 bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.17 h1:QHjAuAYPJjml8e19ytWxgKAboo9+f6aQUH/s1UUEfrA=
@@ -117,7 +116,6 @@ github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
 github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
 github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
 github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
 github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
 github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
 github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
-github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
 github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
 github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
 github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
 github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
@@ -315,9 +313,7 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
 github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
-github.com/olivere/elastic v6.2.37+incompatible h1:UfSGJem5czY+x/LqxgeCBgjDn6St+z8OnsCuxwD3L0U=
 github.com/olivere/elastic v6.2.37+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8=
 github.com/olivere/elastic v6.2.37+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8=
-github.com/olivere/elastic/v7 v7.0.22 h1:esBA6JJwvYgfms0EVlH7Z+9J4oQ/WUADF2y/nCNDw7s=
 github.com/olivere/elastic/v7 v7.0.22/go.mod h1:VDexNy9NjmtAkrjNoI7tImv7FR4tf5zUA3ickqu5Pc8=
 github.com/olivere/elastic/v7 v7.0.22/go.mod h1:VDexNy9NjmtAkrjNoI7tImv7FR4tf5zUA3ickqu5Pc8=
 github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
 github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
 github.com/onsi/ginkgo/v2 v2.7.0 h1:/XxtEV3I3Eif/HobnVx9YmJgk8ENdRsuUmM+fLCFNow=
 github.com/onsi/ginkgo/v2 v2.7.0 h1:/XxtEV3I3Eif/HobnVx9YmJgk8ENdRsuUmM+fLCFNow=

+ 2 - 7
subrecommend/job/matchjob.go

@@ -37,13 +37,8 @@ func (m *MatchJob) Execute() {
 		*datas = append(*datas, v)
 		*datas = append(*datas, v)
 	}
 	}
 	logger.Info("加载bidding数据", len(*datasTemp), "条", "没有autoid的", len(*datasTemp)-len(*datas), "条")
 	logger.Info("加载bidding数据", len(*datasTemp), "条", "没有autoid的", len(*datasTemp)-len(*datas), "条")
-	m.Start(&PersonMatch{Datas: datas})
-	m.Start(&EntMatch{Datas: datas})
+	(&PersonMatch{Datas: datas}).Start()
+	(&EntMatch{Datas: datas}).Start()
 	TaskConfig.Pici = endTime
 	TaskConfig.Pici = endTime
 	logger.Info("推荐数据任务结束。。。", TaskConfig.Pici)
 	logger.Info("推荐数据任务结束。。。", TaskConfig.Pici)
 }
 }
-
-//
-func (m *MatchJob) Start(matcher OtherMatcher) {
-	matcher.Start()
-}

+ 233 - 72
subrecommend/matcher/ent.go

@@ -2,12 +2,10 @@ package matcher
 
 
 import (
 import (
 	"fmt"
 	"fmt"
-	"pushentniche/match/job"
 	. "pushentniche/public"
 	. "pushentniche/public"
 	. "subrecommend/config"
 	. "subrecommend/config"
 	. "subrecommend/db"
 	. "subrecommend/db"
 	. "subrecommend/util"
 	. "subrecommend/util"
-	"sync"
 
 
 	util "app.yhyue.com/moapp/jybase/common"
 	util "app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/logger"
 	"app.yhyue.com/moapp/jybase/logger"
@@ -16,17 +14,21 @@ import (
 )
 )
 
 
 type EntMatch struct {
 type EntMatch struct {
-	Datas    *[]map[string]interface{}
-	matchJob *job.MatchJob
+	Datas *[]map[string]interface{}
 }
 }
 
 
 func (e *EntMatch) Start() {
 func (e *EntMatch) Start() {
 	defer util.Catch()
 	defer util.Catch()
-	_, userEpu, _, _ := LoadEntProductUsers(Tidb, Config.TestUserIds)
-	e.matchJob = &job.MatchJob{
-		UserEpu: userEpu,
-	}
 	InitEnt(Tidb, Mgo, DbConf.Mongodb.Main.DbName, Config.TestQuery)
 	InitEnt(Tidb, Mgo, DbConf.Mongodb.Main.DbName, Config.TestQuery)
+	searchfors, browses := map[string][]*Searchfor{}, map[string][]*Browse{}
+	userIdArea := map[int]string{}
+	for k, _ := range EntUsers {
+		ks := fmt.Sprint(k)
+		searchfor, browse, area := LoadBehavior(ks)
+		searchfors[ks] = searchfor
+		browses[ks] = browse
+		userIdArea[k] = area
+	}
 	allSubSet := mr.NewPayUser()
 	allSubSet := mr.NewPayUser()
 	//标题匹配
 	//标题匹配
 	title_key := make(map[string]*[]*UserInfo)
 	title_key := make(map[string]*[]*UserInfo)
@@ -42,58 +44,23 @@ func (e *EntMatch) Start() {
 		Key_user:    &detail_key,
 		Key_user:    &detail_key,
 		Notkey_user: &detail_notkey,
 		Notkey_user: &detail_notkey,
 	}
 	}
-	e.matchJob.LoadMySubSet(allSubSet, title_pjob, detail_pjob, ChangeUserObj)
+	e.LoadMySubSet(allSubSet, title_pjob, detail_pjob, userIdArea)
 	//
 	//
 	title_pjob.CreateDaf()
 	title_pjob.CreateDaf()
 	detail_pjob.CreateDaf()
 	detail_pjob.CreateDaf()
 	allSubSet.Title_KeyDfa = title_pjob
 	allSubSet.Title_KeyDfa = title_pjob
 	allSubSet.Detail_KeyDfa = detail_pjob
 	allSubSet.Detail_KeyDfa = detail_pjob
 	//
 	//
-	e.ToMatch(allSubSet)
-	ClearEnt()
-	e.matchJob.UserEpu = nil
-}
-
-//
-func (e *EntMatch) ToMatch(matcher mr.Matcher) {
 	logger.Info("开始匹配订阅规则。。。")
 	logger.Info("开始匹配订阅规则。。。")
-	entRuleMap, _ := matcher.Match(Config.MatchPoolSize, e.Datas)
+	entRuleMap, _ := allSubSet.Match(Config.MatchPoolSize, e.Datas)
 	newEntRuleMap := map[*UserInfo]*SortList{}
 	newEntRuleMap := map[*UserInfo]*SortList{}
 	userIdMap := map[int]*UserInfo{}
 	userIdMap := map[int]*UserInfo{}
 	for k, v := range *entRuleMap {
 	for k, v := range *entRuleMap {
-		if k.Entniche.IsDis == 1 {
-			delete(*entRuleMap, k)
-			if dus := GetDisUser(k.Entniche); dus != nil {
-				for duk, _ := range dus {
-					nk := &UserInfo{
-						Id:           fmt.Sprint(duk),
-						VipStatus:    1,
-						MemberStatus: 1,
-						NicheStatus:  1,
-						Entniche: &Entniche{
-							UserId: duk,
-						},
-					}
-					if userIdMap[duk] == nil {
-						userIdMap[duk] = nk
-					}
-					if newEntRuleMap[userIdMap[duk]] == nil {
-						newEntRuleMap[userIdMap[duk]] = v
-					} else {
-						newEntRuleMap[userIdMap[duk]] = MergeSortList(newEntRuleMap[userIdMap[duk]], v, getMaxSize(userIdMap[duk]))
-					}
-				}
-			}
-		} else if k.Entniche.UserId > 0 {
-			k.Id = fmt.Sprint(k.Entniche.UserId)
-			if userIdMap[k.Entniche.UserId] == nil {
-				userIdMap[k.Entniche.UserId] = k
-			}
-			if newEntRuleMap[userIdMap[k.Entniche.UserId]] == nil {
-				newEntRuleMap[userIdMap[k.Entniche.UserId]] = v
-			} else {
-				newEntRuleMap[userIdMap[k.Entniche.UserId]] = MergeSortList(newEntRuleMap[userIdMap[k.Entniche.UserId]], v, getMaxSize(userIdMap[k.Entniche.UserId]))
-			}
+		if userIdMap[k.Entniche.UserId] == nil {
+			userIdMap[k.Entniche.UserId] = k
+			newEntRuleMap[k] = v
+		} else {
+			newEntRuleMap[userIdMap[k.Entniche.UserId]] = MergeSortList(newEntRuleMap[userIdMap[k.Entniche.UserId]], v, -1)
 		}
 		}
 	}
 	}
 	allUsers := map[*UserInfo]bool{}
 	allUsers := map[*UserInfo]bool{}
@@ -105,29 +72,223 @@ func (e *EntMatch) ToMatch(matcher mr.Matcher) {
 			},
 			},
 		}] = true
 		}] = true
 	}
 	}
-	(&MatchOther{IsEnt: true, UserMap: &newEntRuleMap, AllUsers: allUsers, Datas: e.Datas}).Match()
+	(&MatchOther{UserMap: &newEntRuleMap, AllUsers: allUsers, Searchfors: searchfors, Browses: browses, Datas: e.Datas}).Match()
 	logger.Info("订阅规则匹配结束。。。")
 	logger.Info("订阅规则匹配结束。。。")
-	logger.Info("开始保存。。。")
-	index := 0
-	savePool := make(chan bool, Config.SavePoolSize)
-	saveWaitGroup := &sync.WaitGroup{}
-	//lock := &sync.Mutex{}
-	for k, v := range *entRuleMap {
-		savePool <- true
-		saveWaitGroup.Add(1)
-		go func(user *UserInfo, infos *SortList) {
-			defer util.Catch()
-			defer func() {
-				<-savePool
-				saveWaitGroup.Done()
-			}()
-			Save(user, infos)
-		}(k, v)
-		index++
-		if index%500 == 0 {
-			logger.Info("保存", index)
+	Save(1, &newEntRuleMap)
+	ClearEnt()
+}
+
+//我的订阅设置
+func (e *EntMatch) LoadMySubSet(allSubSet *mr.PayUser, title_pjob, detail_pjob *KeyDfa, userIdArea map[int]string) {
+	defer util.Catch()
+	sess := Mgo.GetMgoConn()
+	defer Mgo.DestoryMongoConn(sess)
+	query := map[string]interface{}{}
+	if len(Config.TestQuery) > 0 {
+		query = Config.TestQuery
+	}
+	logger.Info("我的订阅设置", query)
+	it := sess.DB(DbConf.Mongodb.Main.DbName).C(Entniche_rule).Find(query).Select(map[string]interface{}{
+		"i_entid":    1,
+		"i_deptid":   1,
+		"i_userid":   1,
+		"o_entniche": 1,
+		"i_type":     1,
+	}).Iter()
+	for temp := make(map[string]interface{}); it.Next(&temp); {
+		entId := util.IntAll(temp["i_entid"])
+		deptId := util.IntAll(temp["i_deptid"])
+		userId := util.IntAll(temp["i_userid"])
+		if entId == 0 || (deptId != 0 && userId != 0) {
+			continue
+		}
+		var entName string
+		if Ents[entId] != nil {
+			entName = Ents[entId].Name
+		} else {
+			logger.Info("没有找到该企业,过滤掉", entId)
+			continue
+		}
+		user := &UserInfo{
+			Entniche: &Entniche{
+				EntId:   entId,
+				EntName: entName,
+				DeptId:  deptId,
+				UserId:  userId,
+				IsNew:   1,
+			},
+		}
+		subSetType := util.IntAllDef(temp["i_type"], -1)
+		if deptId != 0 {
+			if EntDepts[deptId] == nil {
+				logger.Info("没有找到该部门,过滤掉", entName, entId, deptId)
+				continue
+			} else if Ents[entId] == nil || Ents[entId].Model != 1 || Ents[entId].DeptSubscribe != 1 || EntDepts[deptId].Subdis != 1 || EntDepts[deptId].Nodiff != 0 {
+				logger.Info("不符合部门自己订阅,过滤掉", entName, entId, deptId)
+				continue
+			}
+		} else if userId != 0 {
+			if EntUsers[userId] == nil {
+				logger.Info("没有找到该用户,过滤掉", entName, entId, userId)
+				continue
+			}
+			if subSetType == 0 {
+				if EntUsers[userId].Power == 0 {
+					logger.Info("没有商机管理权限,过滤掉", entName, entId, userId)
+					continue
+				}
+				user.NicheStatus = 1
+			} else if subSetType == 1 {
+				if MgoEntUsers[userId] == nil || (MgoEntUsers[userId].VipStatus <= 0 && MgoEntUsers[userId].MemberStatus <= 0) {
+					logger.Info("不是超级订阅/大会员,过滤掉", entName, entId, userId)
+					continue
+				}
+				user.MemberStatus = MgoEntUsers[userId].MemberStatus
+				user.VipStatus = MgoEntUsers[userId].VipStatus
+			} else if subSetType == 2 {
+				if (MgoEntUsers[userId] != nil && (MgoEntUsers[userId].VipStatus > 0 || MgoEntUsers[userId].MemberStatus > 0)) || EntUsers[userId].Power == 1 {
+					logger.Info("不是免费订阅,过滤掉", entName, entId, userId)
+					continue
+				}
+			} else {
+				continue
+			}
+			user.Phone = EntUsers[userId].Phone
+			user.Entniche.Mail = EntUsers[userId].Mail
+		}
+		if !ChangeUserObj(temp, subSetType, userIdArea[userId]) {
+			continue
+		}
+		subSet, _ := temp["o_entniche"].(map[string]interface{})
+		user.GetSubSet(subSetType == 2, fmt.Sprint(userId), subSet)
+		user.Entniche.IsNew = Ents[entId].IsNew
+		if deptId == 0 {
+			if EntUserDept[userId] != nil {
+				user.Entniche.DeptId = EntUserDept[userId].DeptId
+			} else {
+				user.Entniche.DeptId = EntTopDept[entId]
+			}
+		}
+		if userId != 0 { //个人订阅
+			if MgoEntUsers[userId] != nil {
+				user.PushSet = MgoEntUsers[userId].PushSet
+			} else {
+				user.GetPushSet(map[string]interface{}{})
+			}
+			if subSetType == 2 {
+				user.PushSet.SubSet.RateMode = 0
+			}
+			e.InitSubSet(allSubSet, user, title_pjob, detail_pjob)
+			allSubSet.Users[user] = true
+		} else { //企业/部门订阅
+			user.PushSet = &PushSet{
+				SubSet: &PushSetChild{
+					WxPush:   util.IntAllDef(subSet["i_wxpush"], 1),
+					AppPush:  util.IntAllDef(subSet["i_apppush"], 1),
+					MailPush: util.IntAll(subSet["i_mailpush"]),
+					RateMode: util.IntAllDef(subSet["i_ratemode"], 2),
+				},
+			}
+			user.PushSet.Reset()
+			itemMap := map[string]interface{}{}
+			items, _ := subSet["a_items"].([]interface{})
+			for _, v := range items {
+				item, _ := v.(map[string]interface{})
+				if item == nil {
+					continue
+				}
+				item_name, _ := item["s_item"].(string)
+				if item_name == "" {
+					continue
+				}
+				itemMap[item_name] = item
+			}
+			var diss []*EntDistribute
+			if deptId == 0 {
+				diss = EntDis[entId]
+			} else {
+				diss = EntDeptDis[deptId]
+			}
+			if diss == nil || len(diss) == 0 {
+				logger.Info("该订阅规则没有分发规则,过滤掉", entId, deptId)
+				continue
+			}
+			for _, dis := range diss {
+				child_items := []interface{}{}
+				for _, item_name := range dis.Items {
+					if itemMap[item_name] == nil {
+						continue
+					}
+					child_items = append(child_items, itemMap[item_name])
+				}
+				child_subSet := map[string]interface{}{}
+				if len(dis.Buyerclass) > 0 {
+					child_subSet["a_buyerclass"] = dis.Buyerclass
+				}
+				if len(dis.Area) > 0 {
+					child_subSet["o_area"] = dis.Area
+				}
+				if len(dis.District) > 0 {
+					child_subSet["o_district"] = dis.District
+				}
+				if len(child_items) > 0 {
+					child_subSet["a_items"] = child_items
+				}
+				if len(user.SubSet.Subtype) > 0 {
+					child_subSet["a_infotype"] = user.SubSet.Subtype
+				}
+				if len(child_subSet) == 0 {
+					continue
+				}
+				if dus := GetDisUser(&Entniche{
+					EntId:       user.Entniche.EntId,
+					EntName:     user.Entniche.EntName,
+					DeptId:      user.Entniche.DeptId,
+					DisId:       dis.Id,
+					IsDis:       1,
+					IsNew:       user.Entniche.IsNew,
+					PowerSource: user.Entniche.PowerSource,
+					ProductType: user.Entniche.ProductType,
+				}); dus != nil {
+					for duk, _ := range dus {
+						child_user := &UserInfo{
+							Id:           fmt.Sprint(duk),
+							VipStatus:    1,
+							MemberStatus: 1,
+							NicheStatus:  1,
+							Phone:        user.Phone,
+							Entniche: &Entniche{
+								UserId: duk,
+							},
+						}
+						if child_subSet["o_area"] == nil && userIdArea[duk] != "" {
+							child_subSet["o_area"] = map[string]interface{}{
+								userIdArea[duk]: map[string]interface{}{},
+							}
+						}
+						child_user.GetSubSet(false, dis.Id, child_subSet)
+						child_user.SubSet.MatchWay = user.SubSet.MatchWay
+						child_user.SubSet.MaxPushSize = user.SubSet.MaxPushSize
+						child_user.SubSet.MaxMailSize = user.SubSet.MaxMailSize
+						child_user.PushSet = user.PushSet
+						e.InitSubSet(allSubSet, child_user, title_pjob, detail_pjob)
+						allSubSet.Users[child_user] = true
+					}
+				}
+			}
 		}
 		}
+		logger.Info("加载我的订阅设置", "entId", entId, "entName", entName, "userId", userId, "wxPush", user.PushSet.SubSet.WxPush, "appPush", user.PushSet.SubSet.AppPush, "mailPush", user.PushSet.SubSet.MailPush, "rateMode", user.PushSet.SubSet.RateMode, "matchWay", user.SubSet.MatchWay)
+		temp = make(map[string]interface{})
+	}
+}
+func (e *EntMatch) InitSubSet(allSubSet *mr.PayUser, user *UserInfo, title_pjob, detail_pjob *KeyDfa) {
+	user.AddBuyerclass(&allSubSet.BuyerclassUsers)
+	user.AddAreaCityDistrict(&allSubSet.AreaUsers, &allSubSet.CityUsers, &allSubSet.DistrictUsers)
+	user.AddSubtype(&allSubSet.SubtypeUsers)
+	user.MakeKeyUser(user.SubSet.Keys, title_pjob.Key_user)
+	user.MakeKeyUser(user.SubSet.Notkeys, title_pjob.Notkey_user)
+	if user.SubSet.MatchWay == 2 {
+		user.MakeKeyUser(user.SubSet.Keys, detail_pjob.Key_user)
+		user.MakeKeyUser(user.SubSet.Notkeys, detail_pjob.Notkey_user)
 	}
 	}
-	saveWaitGroup.Wait()
-	logger.Info("保存结束。。。", index)
 }
 }

+ 147 - 141
subrecommend/matcher/matcher.go

@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"encoding/json"
 	"fmt"
 	"fmt"
 	"sort"
 	"sort"
+	"strings"
 	. "subrecommend/config"
 	. "subrecommend/config"
 	. "subrecommend/db"
 	. "subrecommend/db"
 	"sync"
 	"sync"
@@ -16,9 +17,6 @@ import (
 	. "bp.jydev.jianyu360.cn/BaseService/pushpkg/p"
 	. "bp.jydev.jianyu360.cn/BaseService/pushpkg/p"
 )
 )
 
 
-type OtherMatcher interface {
-	Start()
-}
 type Searchfor struct {
 type Searchfor struct {
 	WinnerTel  int      //0:不限 1:有中标单位联系方式
 	WinnerTel  int      //0:不限 1:有中标单位联系方式
 	SelectType string   //搜索范围 detail,title,filetext,purchasing,projectname.pname,buyer.mbuyer
 	SelectType string   //搜索范围 detail,title,filetext,purchasing,projectname.pname,buyer.mbuyer
@@ -44,100 +42,89 @@ type Browse struct {
 }
 }
 
 
 type MatchOther struct {
 type MatchOther struct {
-	IsEnt    bool
-	UserMap  *map[*UserInfo]*SortList
-	AllUsers map[*UserInfo]bool
-	Datas    *[]map[string]interface{}
+	UserMap    *map[*UserInfo]*SortList
+	AllUsers   map[*UserInfo]bool
+	Searchfors map[string][]*Searchfor
+	Browses    map[string][]*Browse
+	Datas      *[]map[string]interface{}
 }
 }
 
 
 func (m *MatchOther) Match() {
 func (m *MatchOther) Match() {
 	m.MatchSearchfor()
 	m.MatchSearchfor()
+	m.MatchBrowse()
+}
+
+//
+func LoadBehavior(userId string) ([]*Searchfor, []*Browse, string) {
+	rules := Clickhouse.SelectBySql(`select browse,searchfor from jianyu.sub_recommend_rule where userid=? order by update_time desc limit 1`, userId)
+	if rules == nil || len(*rules) == 0 {
+		return nil, nil, ""
+	}
+	searchfor, _ := (*rules)[0]["searchfor"].(string)
+	browse, _ := (*rules)[0]["browse"].(string)
+	if searchfor == "" && browse == "" {
+		return nil, nil, ""
+	}
+	var searchfors []*Searchfor
+	if searchfor != "" {
+		if err := json.Unmarshal([]byte(searchfor), &searchfors); err != nil {
+			logger.Error(userId, err)
+		}
+	}
+	var browses []*Browse
+	if browse != "" {
+		if err := json.Unmarshal([]byte(browse), &browses); err != nil {
+			logger.Error(userId, err)
+		}
+	}
+	area := ""
+	if browses != nil && len(browses) > 0 {
+		area = browses[0].Area
+	}
+	return searchfors, browses, area
 }
 }
 
 
 //
 //
 func (m *MatchOther) MatchSearchfor() {
 func (m *MatchOther) MatchSearchfor() {
 	onceUserMap := []*UserInfo{}
 	onceUserMap := []*UserInfo{}
-	browseCache := map[string][]*Browse{}
-	pool := make(chan bool, Config.LoadUserPoolSize)
-	wait := &sync.WaitGroup{}
-	lock := &sync.Mutex{}
-	for k, _ := range m.AllUsers {
-		pool <- true
-		wait.Add(1)
-		go func(ui *UserInfo) {
-			defer Catch()
-			defer func() {
-				<-pool
-				wait.Done()
-			}()
-			if (*m.UserMap)[k] != nil && len(*(*m.UserMap)[k]) >= getMaxSize(ui) {
-				return
-			}
-			rules := Clickhouse.SelectBySql(`select browse,searchfor from jianyu.sub_recommend_rule where userid=? order by update_time desc limit 1`, ui.Id)
-			if rules == nil || len(*rules) == 0 {
-				return
-			}
-			searchfor, _ := (*rules)[0]["searchfor"].(string)
-			browse, _ := (*rules)[0]["browse"].(string)
-			if searchfor == "" && browse == "" {
-				return
-			}
-			var searchfors []*Searchfor
-			if searchfor != "" {
-				if err := json.Unmarshal([]byte(searchfor), &searchfors); err != nil {
-					logger.Info(ui.Id, err)
-				}
-			}
-			var browses []*Browse
-			if browse != "" {
-				if err := json.Unmarshal([]byte(browse), &browses); err != nil {
-					logger.Info(ui.Id, err)
-				}
-			}
-			if (searchfors == nil || len(searchfors) == 0) && (browses == nil || len(browses) == 0) {
-				return
-			}
-			if browses != nil && len(browses) > 0 {
-				browseCache[ui.Id] = browses
-			}
-			keys := []string{}
-			for _, vv := range searchfors {
-				datetime, err := time.ParseInLocation(Date_Full_Layout, vv.Datetime, time.Local)
-				if err != nil {
-					logger.Info(ui.Id, err)
-					continue
-				}
-				if datetime.Before(time.Now().AddDate(0, 0, -Config.SearchLimitDay)) {
-					continue
-				}
-				keys = append(keys, vv.Keys...)
+	for ui, _ := range m.AllUsers {
+		if (*m.UserMap)[ui] != nil && len(*(*m.UserMap)[ui]) >= getMaxSize(ui) {
+			continue
+		} else if m.Searchfors[ui.Id] == nil {
+			continue
+		}
+		keys := []string{}
+		for _, vv := range m.Searchfors[ui.Id] {
+			datetime, err := time.ParseInLocation(Date_Full_Layout, vv.Datetime, time.Local)
+			if err != nil {
+				logger.Info(ui.Id, err)
+				continue
 			}
 			}
-			lock.Lock()
-			defer lock.Unlock()
-			if cnss := m.CreateNewUserInfo(ui, "", keys); cnss != nil {
-				onceUserMap = append(onceUserMap, cnss)
+			if datetime.Before(time.Now().AddDate(0, 0, -Config.SearchLimitDay)) {
+				continue
 			}
 			}
-		}(k)
+			keys = append(keys, vv.Keys...)
+		}
+		if cnss := m.CreateNewUserInfo(ui, keys); cnss != nil {
+			onceUserMap = append(onceUserMap, cnss)
+		}
 	}
 	}
-	wait.Wait()
 	if len(onceUserMap) > 0 {
 	if len(onceUserMap) > 0 {
 		m.OnceBatchMatch(onceUserMap, "searchfor")
 		m.OnceBatchMatch(onceUserMap, "searchfor")
 	}
 	}
-	m.MatchBrowse(browseCache)
 }
 }
 
 
 //
 //
-func (m *MatchOther) MatchBrowse(browseCache map[string][]*Browse) {
+func (m *MatchOther) MatchBrowse() {
 	onceUserMap := []*UserInfo{}
 	onceUserMap := []*UserInfo{}
 	for ui, _ := range m.AllUsers {
 	for ui, _ := range m.AllUsers {
 		if (*m.UserMap)[ui] != nil && len(*(*m.UserMap)[ui]) >= getMaxSize(ui) {
 		if (*m.UserMap)[ui] != nil && len(*(*m.UserMap)[ui]) >= getMaxSize(ui) {
 			continue
 			continue
-		} else if browseCache[ui.Id] == nil {
+		} else if m.Browses[ui.Id] == nil {
 			continue
 			continue
 		}
 		}
 		keys := []string{}
 		keys := []string{}
-		area := ""
-		for _, vv := range browseCache[ui.Id] {
+		for _, vv := range m.Browses[ui.Id] {
 			datetime, err := time.ParseInLocation(Date_Full_Layout, vv.Datetime, time.Local)
 			datetime, err := time.ParseInLocation(Date_Full_Layout, vv.Datetime, time.Local)
 			if err != nil {
 			if err != nil {
 				logger.Info(ui.Id, err)
 				logger.Info(ui.Id, err)
@@ -146,12 +133,9 @@ func (m *MatchOther) MatchBrowse(browseCache map[string][]*Browse) {
 			if datetime.Before(time.Now().AddDate(0, 0, -Config.BrowseLimitDay)) {
 			if datetime.Before(time.Now().AddDate(0, 0, -Config.BrowseLimitDay)) {
 				continue
 				continue
 			}
 			}
-			if len(keys) == 0 {
-				area = vv.Area
-			}
 			keys = append(keys, vv.Classify)
 			keys = append(keys, vv.Classify)
 		}
 		}
-		if cnss := m.CreateNewUserInfo(ui, area, keys); cnss != nil {
+		if cnss := m.CreateNewUserInfo(ui, keys); cnss != nil {
 			onceUserMap = append(onceUserMap, cnss)
 			onceUserMap = append(onceUserMap, cnss)
 		}
 		}
 	}
 	}
@@ -161,7 +145,7 @@ func (m *MatchOther) MatchBrowse(browseCache map[string][]*Browse) {
 }
 }
 
 
 //
 //
-func (m *MatchOther) CreateNewUserInfo(ui *UserInfo, area string, keys []string) *UserInfo {
+func (m *MatchOther) CreateNewUserInfo(ui *UserInfo, keys []string) *UserInfo {
 	if len(keys) == 0 {
 	if len(keys) == 0 {
 		return nil
 		return nil
 	}
 	}
@@ -172,20 +156,14 @@ func (m *MatchOther) CreateNewUserInfo(ui *UserInfo, area string, keys []string)
 			Keys:         keys,
 			Keys:         keys,
 			OriginalKeys: keys,
 			OriginalKeys: keys,
 		},
 		},
-		Extend: &UserInfoExtend{
-			Object: map[string]interface{}{
-				"area": area,
-			},
-		},
+		Extend:   ui.Extend,
+		Entniche: ui.Entniche,
 	}
 	}
 	if ui.SubSet != nil {
 	if ui.SubSet != nil {
 		userInfo.SubSet.Area = ui.SubSet.Area
 		userInfo.SubSet.Area = ui.SubSet.Area
 		userInfo.SubSet.Areas = ui.SubSet.Areas
 		userInfo.SubSet.Areas = ui.SubSet.Areas
 		userInfo.SubSet.District = ui.SubSet.District
 		userInfo.SubSet.District = ui.SubSet.District
 	}
 	}
-	if ui.Entniche != nil {
-		userInfo.Entniche = ui.Entniche
-	}
 	return userInfo
 	return userInfo
 }
 }
 
 
@@ -252,65 +230,93 @@ func (m *MatchOther) MergeInfos(userMap *map[*UserInfo]*SortList) {
 }
 }
 
 
 //
 //
-func Save(ui *UserInfo, infos *SortList) {
-	// for _, vv := range *infos {
-	// 	logger.Info(userId, "-----", vv.Info["title"], vv.Keys)
-	// }
-	area := ""
-	if ui.Extend != nil && ui.Extend.Object != nil {
-		area, _ = ui.Extend.Object["area"].(string)
-	}
-	maxSize := getMaxSize(ui)
-	subCount, searchforCount, browseCount := 0, 0, 0
-	sort.Sort(infos)
-	matchLen := len(*infos)
-	if len(*infos) > maxSize {
-		*infos = (*infos)[:maxSize]
-	}
-	ids := []int{}
-	for _, v := range *infos {
-		ids = append(ids, IntAll(v.Info["autoid"]))
-		if len(v.MatchWays) == 0 {
-		} else if len(v.MatchWays) > 0 && v.MatchWays[0] == "searchfor" {
-			searchforCount++
-		} else if len(v.MatchWays) > 0 && v.MatchWays[0] == "browse" {
-			browseCount++
-		} else {
-			subCount++
-		}
-	}
-	logger.Info(ui.Id, "匹配上", matchLen, "条", "保存", len(*infos), "条", "订阅", subCount, "搜索", searchforCount, "浏览", browseCount)
-	if len(ids) == 0 {
-		return
-	}
-	nowFormat := NowFormat(Date_Full_Layout)
-	datas := Clickhouse.SelectBySql(`select bitmapToArray(infoids) as infoids from jianyu.sub_recommend_list where userid=? order by update_time desc limit 1`, ui.Id)
-	if datas == nil {
-		logger.Error(ui.Id, "查询clickhouse失败")
-		return
-	}
-	if len(*datas) == 0 {
-		Clickhouse.InsertBySql(`INSERT INTO jianyu.sub_recommend_list (userid, infoids, area, update_time) values ('` + ui.Id + `',bitmapBuild([` + toUInt64(ids) + `]),'` + area + `','` + nowFormat + `')`)
-	} else {
-		infoids, _ := (*datas)[0]["infoids"].([]uint64)
-		intIds := []int{}
-		allInfoIds := map[int]bool{}
-		for _, v := range infoids {
-			intIds = append(intIds, int(v))
-			allInfoIds[int(v)] = true
-		}
-		for _, v := range ids {
-			if allInfoIds[v] {
-				continue
+func Save(batchIndex int, userMap *map[*UserInfo]*SortList) {
+	logger.Info("第", batchIndex, "批开始保存。。。")
+	index := 0
+	//
+	savePool := make(chan bool, Config.SavePoolSize)
+	saveWaitGroup := &sync.WaitGroup{}
+	for k, v := range *userMap {
+		savePool <- true
+		saveWaitGroup.Add(1)
+		go func(ui *UserInfo, infos *SortList) {
+			defer Catch()
+			defer func() {
+				<-savePool
+				saveWaitGroup.Done()
+			}()
+			// for _, vv := range *infos {
+			// 	logger.Info(userId, "-----", vv.Info["title"], vv.Keys)
+			// }
+			area := ""
+			if ui.SubSet != nil {
+				area = strings.Join(ui.SubSet.Areas, " ")
+				if len([]rune(area)) > 20 {
+					area = string([]rune(area)[:20]) + "..."
+				}
 			}
 			}
-			intIds = append(intIds, v)
-		}
-		if len(intIds) > maxSize {
-			intIds = intIds[len(intIds)-maxSize:]
+			if area == "" {
+				area = "全国"
+			}
+			maxSize := getMaxSize(ui)
+			subCount, searchforCount, browseCount := 0, 0, 0
+			sort.Sort(infos)
+			matchLen := len(*infos)
+			if len(*infos) > maxSize {
+				*infos = (*infos)[:maxSize]
+			}
+			ids := []int{}
+			for _, v := range *infos {
+				ids = append(ids, IntAll(v.Info["autoid"]))
+				if len(v.MatchWays) == 0 {
+				} else if len(v.MatchWays) > 0 && v.MatchWays[0] == "searchfor" {
+					searchforCount++
+				} else if len(v.MatchWays) > 0 && v.MatchWays[0] == "browse" {
+					browseCount++
+				} else {
+					subCount++
+				}
+			}
+			logger.Info(ui.Id, "匹配上", matchLen, "条", "保存", len(*infos), "条", "订阅", subCount, "搜索", searchforCount, "浏览", browseCount)
+			if len(ids) == 0 {
+				return
+			}
+			nowFormat := NowFormat(Date_Full_Layout)
+			datas := Clickhouse.SelectBySql(`select bitmapToArray(infoids) as infoids from jianyu.sub_recommend_list where userid=? order by update_time desc limit 1`, ui.Id)
+			if datas == nil {
+				logger.Error(ui.Id, "查询clickhouse失败")
+				return
+			}
+			if len(*datas) == 0 {
+				Clickhouse.InsertBySql(`INSERT INTO jianyu.sub_recommend_list (userid, infoids, area, update_time) values ('` + ui.Id + `',bitmapBuild([` + toUInt64(ids) + `]),'` + area + `','` + nowFormat + `')`)
+			} else {
+				infoids, _ := (*datas)[0]["infoids"].([]uint64)
+				intIds := []int{}
+				allInfoIds := map[int]bool{}
+				for _, v := range infoids {
+					intIds = append(intIds, int(v))
+					allInfoIds[int(v)] = true
+				}
+				for _, v := range ids {
+					if allInfoIds[v] {
+						continue
+					}
+					intIds = append(intIds, v)
+				}
+				if len(intIds) > maxSize {
+					intIds = intIds[len(intIds)-maxSize:]
+				}
+				text := `ALTER TABLE jianyu.sub_recommend_list update area='` + area + `',infoids=bitmapBuild([` + toUInt64(intIds) + `]),update_time='` + nowFormat + `' where userid='` + ui.Id + `'`
+				Clickhouse.UpdateOrDeleteBySql(text)
+			}
+		}(k, v)
+		index++
+		if index%500 == 0 {
+			logger.Info("保存:", index)
 		}
 		}
-		text := `ALTER TABLE jianyu.sub_recommend_list update area='` + area + `',infoids=bitmapBuild([` + toUInt64(intIds) + `]),update_time='` + nowFormat + `' where userid='` + ui.Id + `'`
-		Clickhouse.UpdateOrDeleteBySql(text)
 	}
 	}
+	saveWaitGroup.Wait()
+	logger.Info("第", batchIndex, "批保存。。。", index)
 }
 }
 
 
 //
 //

+ 177 - 67
subrecommend/matcher/person.go

@@ -1,9 +1,6 @@
 package matcher
 package matcher
 
 
 import (
 import (
-	mrjob "pushmember/match/job"
-	sejob "pushsubscribe/match/job"
-	sbjob "pushsupersub/match/job"
 	. "subrecommend/config"
 	. "subrecommend/config"
 	. "subrecommend/db"
 	. "subrecommend/db"
 	. "subrecommend/util"
 	. "subrecommend/util"
@@ -11,103 +8,216 @@ import (
 
 
 	util "app.yhyue.com/moapp/jybase/common"
 	util "app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/logger"
 	"app.yhyue.com/moapp/jybase/logger"
+	. "app.yhyue.com/moapp/jybase/mongodb"
 	mr "bp.jydev.jianyu360.cn/BaseService/pushpkg/matcher"
 	mr "bp.jydev.jianyu360.cn/BaseService/pushpkg/matcher"
 	. "bp.jydev.jianyu360.cn/BaseService/pushpkg/p"
 	. "bp.jydev.jianyu360.cn/BaseService/pushpkg/p"
 )
 )
 
 
-type MatchPay interface {
-	OnceUserBatch(batchIndex int, lastUserId *string, fn func(obj map[string]interface{}, tp int) bool) (int, *mr.PayUser)
-}
-
 type PersonMatch struct {
 type PersonMatch struct {
 	Datas *[]map[string]interface{}
 	Datas *[]map[string]interface{}
 }
 }
 
 
 //定时任务,匹配数据,存库
 //定时任务,匹配数据,存库
 func (p *PersonMatch) Start() {
 func (p *PersonMatch) Start() {
-	p.ToMatchFree()
-	p.ToMatchPay(&mrjob.MatchJob{})
-	p.ToMatchPay(&sbjob.MatchJob{})
-}
-func (p *PersonMatch) ToMatchFree() {
-	logger.Info("开始匹配免费用户数据任务。。。")
+	logger.Info("开始匹配个人用户数据任务。。。")
 	lastUserId := ""
 	lastUserId := ""
 	batchIndex := 0
 	batchIndex := 0
 	for {
 	for {
 		batchIndex++
 		batchIndex++
-		batchSize, freeUser := (&sejob.MatchJob{}).OnceUserBatch(batchIndex, &lastUserId, ChangeUserObj)
+		batchSize, freeUser, payUser, searchfors, browses := p.OnceUserBatch(batchIndex, &lastUserId)
 		if batchSize == 0 {
 		if batchSize == 0 {
 			break
 			break
 		}
 		}
-		p.ToMatch(batchIndex, freeUser, len(freeUser.Users) > 0, freeUser.AllUsers)
-		if batchSize < Config.UserBatch {
-			break
+		logger.Info("开始匹配第", batchIndex, "批用户。。。")
+		userMap := &map[*UserInfo]*SortList{}
+		if len(freeUser.Users) > 0 {
+			userMap, _ = freeUser.Match(Config.MatchPoolSize, p.Datas)
 		}
 		}
-	}
-	logger.Info("匹配免费用户数据任务结束。。。")
-}
-
-func (p *PersonMatch) ToMatchPay(mp MatchPay) {
-	logger.Info("开始匹配付费用户数据任务。。。")
-	lastUserId := ""
-	batchIndex := 0
-	for {
-		batchIndex++
-		batchSize, payUser := mp.OnceUserBatch(batchIndex, &lastUserId, ChangeUserObj)
-		if batchSize == 0 {
-			break
+		if len(payUser.Users) > 0 {
+			userIdMap := map[string]*UserInfo{}
+			payUserMap, _ := payUser.Match(Config.MatchPoolSize, p.Datas)
+			for k, v := range *payUserMap {
+				if userIdMap[k.Id] == nil {
+					userIdMap[k.Id] = k
+					(*userMap)[k] = v
+				} else {
+					(*userMap)[userIdMap[k.Id]] = MergeSortList((*payUserMap)[userIdMap[k.Id]], v, -1)
+				}
+			}
+			allUserMap := map[string]bool{}
+			for k, v := range payUser.Users {
+				if allUserMap[k.Id] {
+					continue
+				}
+				allUserMap[k.Id] = true
+				freeUser.Users[k] = v
+			}
 		}
 		}
-		p.ToMatch(batchIndex, payUser, len(payUser.Users) > 0, payUser.AllUsers)
+		(&MatchOther{UserMap: userMap, AllUsers: freeUser.Users, Searchfors: searchfors, Browses: browses, Datas: p.Datas}).Match()
+		logger.Info("第", batchIndex, "批用户匹配结束。。。")
+		Save(batchIndex, userMap)
 		if batchSize < Config.UserBatch {
 		if batchSize < Config.UserBatch {
 			break
 			break
 		}
 		}
 	}
 	}
-	logger.Info("匹配付费用户数据任务结束。。。")
+	logger.Info("匹配个人用户数据任务结束。。。")
 }
 }
 
 
-func (p *PersonMatch) ToMatch(batchIndex int, matcher mr.Matcher, isMatch bool, allUsers map[*UserInfo]bool) {
-	logger.Info("开始匹配第", batchIndex, "批用户。。。")
-	userMap := &map[*UserInfo]*SortList{}
-	if isMatch {
-		userMap, _ = matcher.Match(Config.MatchPoolSize, p.Datas)
+//
+func (p *PersonMatch) OnceUserBatch(batchIndex int, lastUserId *string) (int, *mr.FreeUser, *mr.PayUser, map[string][]*Searchfor, map[string][]*Browse) {
+	defer util.Catch()
+	q := map[string]interface{}{
+		"i_appid": 2,
+	}
+	_idq := map[string]interface{}{}
+	if len(Config.TestIds) > 0 {
+		_idq["$in"] = ToObjectIds(Config.TestIds)
 	}
 	}
-	(&MatchOther{IsEnt: false, UserMap: userMap, AllUsers: allUsers, Datas: p.Datas}).Match()
-	logger.Info("第", batchIndex, "批用户匹配结束。。。")
-	logger.Info("第", batchIndex, "批开始保存。。。")
-	index := 0
+	if *lastUserId != "" {
+		_idq["$gt"] = StringTOBsonId(*lastUserId)
+	}
+	if len(_idq) > 0 {
+		q["_id"] = _idq
+	}
+	logger.Info("开始加载第", batchIndex, "批用户", q)
+	session := Mgo.GetMgoConn()
+	defer Mgo.DestoryMongoConn(session)
+	query := session.DB(DbConf.Mongodb.Main.DbName).C(Mgo_User).Find(&q).Select(UserCollFields).Sort("_id").Iter()
+	n := 0
+	searchfors, browses := map[string][]*Searchfor{}, map[string][]*Browse{}
+	freeUser, payUser := mr.NewFreeUser(), mr.NewPayUser() //所有用户
+	//标题匹配
+	free_title_key_user := make(map[string]*[]*UserInfo)
+	free_title_notkey_user := make(map[string]*[]*UserInfo)
+	pay_title_key_user := make(map[string]*[]*UserInfo)
+	pay_title_notkey_user := make(map[string]*[]*UserInfo)
+	//正文匹配
+	pay_detail_key_user := make(map[string]*[]*UserInfo)
+	pay_detail_notkey_user := make(map[string]*[]*UserInfo)
 	//
 	//
-	savePool := make(chan bool, Config.SavePoolSize)
-	saveWaitGroup := &sync.WaitGroup{}
-	for k, v := range *userMap {
-		savePool <- true
-		saveWaitGroup.Add(1)
-		go func(user *UserInfo, infos *SortList) {
-			defer util.Catch()
+	loadUserPool := make(chan bool, Config.LoadUserPoolSize)
+	loadUserWaitGroup := &sync.WaitGroup{}
+	lock := &sync.Mutex{}
+	for userTemp := make(map[string]interface{}); query.Next(&userTemp); {
+		loadUserPool <- true
+		loadUserWaitGroup.Add(1)
+		go func(temp map[string]interface{}) {
 			defer func() {
 			defer func() {
-				<-savePool
-				saveWaitGroup.Done()
+				<-loadUserPool
+				loadUserWaitGroup.Done()
 			}()
 			}()
-			users := []*UserInfo{user}
-			uiSons := []*UserInfo{}
-			if user.MemberStatus > 0 && user.IsMainAccount {
-				for _, son := range *MySonAccounts(Mgo, Mgo_User, user.Id, UserCollFields) {
-					son_user := NewUserInfo(son, 3)
-					if son_user == nil {
-						continue
+			userId := BsonIdToSId(temp["_id"])
+			lock.Lock()
+			searchfor, browse, area := LoadBehavior(userId)
+			searchfors[userId] = searchfor
+			browses[userId] = browse
+			lock.Unlock()
+			users := []*UserInfo{}
+			memberStatus := util.IntAll(temp["i_member_status"])
+			vipStatus := util.IntAll(temp["i_vip_status"])
+			if memberStatus <= 0 && vipStatus <= 0 {
+				if ChangeUserObj(temp, -1, area) {
+					users = append(users, NewUserInfo(temp, 1))
+				}
+			}
+			if vipStatus > 0 {
+				if ChangeUserObj(temp, -2, area) {
+					users = append(users, NewUserInfo(temp, 2))
+				}
+			}
+			if memberStatus > 0 {
+				obj, _ := temp["o_member_jy"].(map[string]interface{})
+				areaIsNil := obj["o_area"] == nil
+				isChange := ChangeUserObj(temp, -3, area)
+				ui := NewUserInfo(temp, 3)
+				if ui.SonAccountStatus == 1 {
+					logger.Info("子账号,不进行匹配,过滤掉!", ui.Id)
+					return
+				}
+				if isChange {
+					users = append(users, ui)
+				}
+				if ui.IsMainAccount {
+					for _, son := range *MySonAccounts(Mgo, Mgo_User, ui.Id, UserCollFields) {
+						if son_user := NewUserInfo(son, 3); son_user != nil {
+							lock.Lock()
+							son_searchfor, son_browse, son_area := LoadBehavior(son_user.Id)
+							searchfors[son_user.Id] = son_searchfor
+							browses[son_user.Id] = son_browse
+							lock.Unlock()
+							son_obj, _ := temp["o_member_jy"].(map[string]interface{})
+							if areaIsNil && son_area != "" {
+								son_obj["o_area"] = map[string]interface{}{
+									area: map[string]interface{}{},
+								}
+							}
+							son_user.GetSubSet(false, ui.Id, son_obj)
+							users = append(users, ui)
+						}
 					}
 					}
-					uiSons = append(uiSons, son_user)
 				}
 				}
 			}
 			}
-			users = append(users, uiSons...)
-			for _, u := range users {
-				Save(u, infos)
+			if len(users) == 0 {
+				return
+			}
+			logger.Info("第", batchIndex, "批用户,userid", userId, "memberStatus", memberStatus, "vipStatus", vipStatus)
+			/***************start*****************/
+			lock.Lock()
+			defer lock.Unlock()
+			for _, user := range users {
+				if user.MemberStatus > 0 || user.VipStatus > 0 {
+					user.AddBuyerclass(&payUser.BuyerclassUsers)
+					user.AddAreaCityDistrict(&payUser.AreaUsers, &payUser.CityUsers, &payUser.DistrictUsers)
+					user.AddSubtype(&payUser.SubtypeUsers)
+					user.MakeKeyUser(user.SubSet.Keys, &pay_title_key_user)
+					user.MakeKeyUser(user.SubSet.Notkeys, &pay_title_notkey_user)
+					if user.SubSet.MatchWay == 2 {
+						user.MakeKeyUser(user.SubSet.Keys, &pay_detail_key_user)
+						user.MakeKeyUser(user.SubSet.Notkeys, &pay_detail_notkey_user)
+					}
+					payUser.Users[user] = true
+				} else {
+					if user.SubSet.IsUpgrade {
+						//区域
+						user.AddArea(&freeUser.AreaUsers)
+						//信息类型
+						user.AddSubtype(&freeUser.SubtypeUsers)
+					}
+					user.MakeKeyUser(user.SubSet.Keys, &free_title_key_user)
+					user.MakeKeyUser(user.SubSet.Notkeys, &free_title_notkey_user)
+					freeUser.Users[user] = true
+				}
 			}
 			}
-		}(k, v)
-		index++
-		if index%500 == 0 {
-			logger.Info("保存:", index)
+			/***************end*****************/
+		}(userTemp)
+		*lastUserId = BsonIdToSId(userTemp["_id"])
+		userTemp = make(map[string]interface{})
+		n++
+		if n == Config.UserBatch {
+			break
 		}
 		}
 	}
 	}
-	saveWaitGroup.Wait()
-	logger.Info("第", batchIndex, "批保存。。。", index)
+	loadUserWaitGroup.Wait()
+	//
+	pay_title_pjob := &KeyDfa{
+		Key_user:    &pay_title_key_user,
+		Notkey_user: &pay_title_notkey_user,
+	}
+	pay_title_pjob.CreateDaf()
+	pay_detail_pjob := &KeyDfa{
+		Key_user:    &pay_detail_key_user,
+		Notkey_user: &pay_detail_notkey_user,
+	}
+	pay_detail_pjob.CreateDaf()
+	payUser.Title_KeyDfa = pay_title_pjob
+	payUser.Detail_KeyDfa = pay_detail_pjob
+	//
+	free_title_pjob := &KeyDfa{
+		Key_user:    &free_title_key_user,
+		Notkey_user: &free_title_notkey_user,
+	}
+	free_title_pjob.CreateDaf()
+	freeUser.Title_KeyDfa = free_title_pjob
+	logger.Info("第", batchIndex, "批用户加载结束", n)
+	return n, freeUser, payUser, searchfors, browses
 }
 }

+ 23 - 1
subrecommend/util/util.go

@@ -15,7 +15,7 @@ import (
 )
 )
 
 
 //tp 0:企业-商机管理 2:企业-超级订阅/大会员 3:企业-免费 -1:个人-免费 -2:个人-超级订阅 -3:个人-大会员
 //tp 0:企业-商机管理 2:企业-超级订阅/大会员 3:企业-免费 -1:个人-免费 -2:个人-超级订阅 -3:个人-大会员
-func ChangeUserObj(userObj map[string]interface{}, tp int) bool {
+func ChangeUserObj(userObj map[string]interface{}, tp int, area string) bool {
 	subSetKey := ""
 	subSetKey := ""
 	if tp > 0 {
 	if tp > 0 {
 		subSetKey = "o_entniche"
 		subSetKey = "o_entniche"
@@ -33,6 +33,23 @@ func ChangeUserObj(userObj map[string]interface{}, tp int) bool {
 		if len(new_a_key) == 0 {
 		if len(new_a_key) == 0 {
 			return false
 			return false
 		}
 		}
+		if area != "" {
+			for _, v := range new_a_key {
+				if v["area"] == nil {
+					v["area"] = []interface{}{area}
+				}
+			}
+			if obj["o_area"] == nil {
+				obj["o_area"] = map[string]interface{}{
+					area: map[string]interface{}{},
+				}
+			}
+			if obj["o_area_p"] == nil {
+				obj["o_area_p"] = map[string]interface{}{
+					area: map[string]interface{}{},
+				}
+			}
+		}
 		obj["a_key"] = new_a_key
 		obj["a_key"] = new_a_key
 	} else {
 	} else {
 		new_a_items := []interface{}{}
 		new_a_items := []interface{}{}
@@ -49,6 +66,11 @@ func ChangeUserObj(userObj map[string]interface{}, tp int) bool {
 			return false
 			return false
 		}
 		}
 		obj["a_items"] = new_a_items
 		obj["a_items"] = new_a_items
+		if area != "" && obj["o_area"] == nil {
+			obj["o_area"] = map[string]interface{}{
+				area: map[string]interface{}{},
+			}
+		}
 	}
 	}
 	userObj[subSetKey] = obj
 	userObj[subSetKey] = obj
 	return true
 	return true

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff