Pārlūkot izejas kodu

Merge branch 'dev2.8.5' of http://192.168.3.207:10080/qmx/jy into dev2.8.5

wangshan 5 gadi atpakaļ
vecāks
revīzija
322d6cf99b

+ 77 - 0
src/jfw/modules/pushsubscribe/src/match/job/freeuser.go

@@ -0,0 +1,77 @@
+package job
+
+import (
+	. "public"
+	"strings"
+)
+
+//免费用户
+type FreeUser struct {
+	Users      map[*UserInfo]bool
+	Title_Pjob *Pjob
+}
+
+func NewFreeUser() *FreeUser {
+	return &FreeUser{
+		Users: map[*UserInfo]bool{},
+	}
+}
+func (f *FreeUser) Match(info *map[string]interface{}) *map[*UserInfo]*MatchUser {
+	title, _ := (*info)["title"].(string)
+	title = strings.ToUpper(title)
+	//订阅词
+	keys := f.Title_Pjob.InterestDfa.Analy(title)
+	//排除词
+	notkeys := f.Title_Pjob.NotInterestDfa.Analy(title)
+	users := f.GetFinalUser(keys, notkeys, f.Title_Pjob.Key_user, info)
+	return users
+}
+
+//获取最终的用户,排除词、信息范围、信息类型之后的
+//返回匹配上的用户和没有匹配到的用户
+func (f *FreeUser) GetFinalUser(keys, notkeys []string, key_user *map[string]*[]*UserInfo, info *map[string]interface{}) *map[*UserInfo]*MatchUser {
+	area, _ := (*info)["area"].(string)
+	toptype, _ := (*info)["toptype"].(string)
+	keyMap := map[string]bool{}
+	for _, v := range keys {
+		keyMap[v] = true
+	}
+	users := map[*UserInfo]*MatchUser{} //匹配到用户
+	//遍历所有用户
+	for k, us := range *key_user {
+		if !keyMap[k] { //该关键词没有匹配到的用户
+			continue
+		}
+		for _, u := range *us {
+			//获取该词下面所有的用户
+			//遍历我的排除词,如果存在的话,排除自己
+			isContinue := false
+			for _, notkey := range notkeys {
+				if u.Key_notkey[k][notkey] {
+					isContinue = true
+					break
+				}
+			}
+			if isContinue {
+				continue
+			}
+			//遍历我的信息范围,看该信息是不是在我的信息范围中
+			if len(u.O_jy.Area[k]) > 0 && !u.O_jy.Area[k][area] {
+				continue
+			}
+			//遍历我的信息类型,看该信息是不是在我的信息类型中
+			if len(u.O_jy.Infotype[k]) > 0 && !u.O_jy.Infotype[k][toptype] {
+				continue
+			}
+			matchUser := users[u]
+			if matchUser == nil {
+				matchUser = &MatchUser{
+					Keys: []string{},
+				}
+			}
+			matchUser.Keys = append(matchUser.Keys, k)
+			users[u] = matchUser
+		}
+	}
+	return &users
+}

+ 0 - 2
src/jfw/modules/pushsubscribe/src/match/job/job.go

@@ -2,7 +2,6 @@ package job
 
 import (
 	"match/config"
-	. "public"
 	"sync"
 )
 
@@ -30,7 +29,6 @@ type jobs struct {
 var Jobs = &jobs{
 	Match: &MatchJob{
 		datas:             &[]map[string]interface{}{},
-		users:             &map[string]*UserInfo{},
 		matchPool:         make(chan bool, config.SysConfig.MatchPoolSize),
 		eachInfoWaitGroup: &sync.WaitGroup{},
 		saveWaitGroup:     &sync.WaitGroup{},

+ 7 - 0
src/jfw/modules/pushsubscribe/src/match/job/matcher.go

@@ -0,0 +1,7 @@
+package job
+
+import . "public"
+
+type Matcher interface {
+	Match(info *map[string]interface{}) *map[*UserInfo]*MatchUser
+}

+ 215 - 221
src/jfw/modules/pushsubscribe/src/match/job/matchjob.go

@@ -23,7 +23,7 @@ import (
 )
 
 var (
-	SaveFields = []string{"_id", "area", "bidamount", "bidopentime", "budget", "buyer", "otitle", "projectname", "publishtime", "s_subscopeclass", "subtype", "title", "toptype", "type", "winner"}
+	SaveFields = []string{"_id", "area", "city", "bidamount", "bidopentime", "budget", "buyer", "buyerclass", "projectname", "publishtime", "s_subscopeclass", "subtype", "title", "toptype", "type", "winner"}
 	MailReg    = regexp.MustCompile(SysConfig.MailReg)
 )
 
@@ -53,12 +53,10 @@ func (p *Pjob) CreateDaf() {
 }
 
 type MatchUser struct {
-	User *UserInfo
 	Keys []string
 }
 type MatchJob struct {
 	datas             *[]map[string]interface{} //本次加载的数据
-	users             *map[string]*UserInfo     //所有用户
 	matchPool         chan bool
 	eachInfoWaitGroup *sync.WaitGroup
 	saveWaitGroup     *sync.WaitGroup
@@ -99,24 +97,12 @@ func (m *MatchJob) Execute() {
 	user_batch_index := 0
 	for {
 		user_batch_index++
-		user_batch_size := m.OnceUserBatch(user_batch_index)
+		user_batch_size, vipUser, freeUser := m.OnceUserBatch(user_batch_index)
 		if user_batch_size == 0 {
 			break
 		}
-		a_key_user := make(map[string]*[]*UserInfo)
-		a_notkey_user := make(map[string]*[]*UserInfo)
-		//开启智能订阅的用户
-		//s_key_user := make(map[string]*[]*UserInfo)
-		//s_notkey_user := make(map[string]*[]*UserInfo)
-		for _, v := range *m.users {
-			m.MakeKeyUser(v.Keys, v, &a_key_user)
-			m.MakeKeyUser(v.NotKeys, v, &a_notkey_user)
-			// if v.SmartSet == 1 {
-			// 	m.MakeKeyUser(v.Keys, v, &s_key_user)
-			// 	m.MakeKeyUser(v.NotKeys, v, &s_notkey_user)
-			// }
-		}
-		m.ToMatch(user_batch_index, a_key_user, a_notkey_user, nil, nil)
+		m.ToMatch(user_batch_index, vipUser)
+		m.ToMatch(user_batch_index, freeUser)
 		if user_batch_size < SysConfig.UserBatch {
 			break
 		}
@@ -127,35 +113,14 @@ func (m *MatchJob) Execute() {
 	TaskConfig.LastId = newId
 	TaskConfig.StartTime = util.FormatDateWithObj(&comeintime, util.Date_Full_Layout)
 	m.datas = &[]map[string]interface{}{}
-	m.users = &map[string]*UserInfo{}
 }
-func (m *MatchJob) ToMatch(batchIndex int, a_key_user, a_notkey_user, s_key_user, s_notkey_user map[string]*[]*UserInfo) {
+func (m *MatchJob) ToMatch(batchIndex int, matcher Matcher) {
 	logger.Info("开始匹配第", batchIndex, "批用户")
-	a_p := &Pjob{
-		Key_user:    &a_key_user,
-		Notkey_user: &a_notkey_user,
-	}
-	a_p.CreateDaf()
-	//
-	s_p := &Pjob{
-		Key_user:    &s_key_user,
-		Notkey_user: &s_notkey_user,
-	}
-	s_p.CreateDaf()
-	m.Save(a_p, s_p)
-	a_key_user = make(map[string]*[]*UserInfo)
-	a_notkey_user = make(map[string]*[]*UserInfo)
-	//开启智能订阅的用户
-	s_key_user = make(map[string]*[]*UserInfo)
-	s_notkey_user = make(map[string]*[]*UserInfo)
+	userMap := m.EachAllBidInfo(matcher)
 	logger.Info("第", batchIndex, "批用户匹配结束")
-}
-func (m *MatchJob) Save(a_p, s_p *Pjob) {
 	logger.Info("开始保存到pushmail_temp表")
-	userMap := m.EachAllBidInfo(a_p, s_p)
-	//加锁,保存数据和转移数据不能同时进行
 	index := 0
-	for openid, listInfos := range *userMap {
+	for user, listInfos := range *userMap {
 		var pushArray = make(SortList, 0)
 		for e := listInfos.Front(); e != nil; e = e.Next() {
 			matchInfo := *(e.Value.(*MatchInfo))
@@ -182,34 +147,32 @@ func (m *MatchJob) Save(a_p, s_p *Pjob) {
 				break
 			}
 		}
-		user := (*m.users)[openid]
 		m.saveBatch = append(m.saveBatch, map[string]interface{}{
-			"s_m_openid":   user.S_m_openid,
-			"a_m_openid":   user.A_m_openid,
-			"phone":        user.Phone,
-			"jpushid":      user.Jpushid,
-			"opushid":      user.Opushid,
-			"appphonetype": user.AppPhoneType,
-			"userid":       user.Id,
-			"ratemode":     user.RateMode,
-			"wxpush":       user.WxPush,
-			"apppush":      user.AppPush,
-			"mailpush":     user.MailPush,
-			"pchelperpush": user.PchelperPush,
-			//"smartset":      user.SmartSet,
-			"usertype": user.UserType,
-			"email":    user.Email,
-			//"dataexport":    user.DataExport,
+			"s_m_openid":    user.S_m_openid,
+			"a_m_openid":    user.A_m_openid,
+			"phone":         user.Phone,
+			"jpushid":       user.Jpushid,
+			"opushid":       user.Opushid,
+			"appphonetype":  user.AppPhoneType,
+			"userid":        user.Id,
+			"ratemode":      user.RateMode,
+			"wxpush":        user.WxPush,
+			"apppush":       user.AppPush,
+			"mailpush":      user.MailPush,
+			"pchelperpush":  user.PchelperPush,
+			"usertype":      user.UserType,
+			"email":         user.Email,
 			"list":          array,
 			"size":          size,
 			"subscribe":     user.Subscribe,
 			"applystatus":   user.ApplyStatus,
-			"words":         user.OriginalKeys,
+			"words":         user.Keys,
 			"modifydate":    user.ModifyDate,
 			"mergeorder":    user.MergeOrder,
 			"timestamp":     time.Now().Unix(),
 			"nickname":      user.NickName,
 			"firstpushtime": user.FirstPushTime,
+			"vipstatus":     user.VipStatus,
 		})
 		if len(m.saveBatch) == BulkSize {
 			mongodb.SaveBulk("pushspace_temp", m.saveBatch...)
@@ -289,9 +252,8 @@ func (m *MatchJob) LoadBidding(lastId, newId string, lastTime int64) bool {
 }
 
 //初始化用户缓存
-func (m *MatchJob) OnceUserBatch(user_batch_index int) int {
+func (m *MatchJob) OnceUserBatch(user_batch_index int) (int, *VipUser, *FreeUser) {
 	defer util.Catch()
-	m.users = &map[string]*UserInfo{}
 	//遍历用户
 	q := map[string]interface{}{
 		"i_appid": 2,
@@ -312,6 +274,8 @@ func (m *MatchJob) OnceUserBatch(user_batch_index int) int {
 	query := session.DB(DbName).C("user").Find(&q).Select(&map[string]interface{}{
 		"_id":             1,
 		"o_jy":            1,
+		"o_vipjy":         1,
+		"i_vipstatus":     1,
 		"s_m_openid":      1,
 		"a_m_openid":      1,
 		"s_phone":         1,
@@ -325,10 +289,19 @@ func (m *MatchJob) OnceUserBatch(user_batch_index int) int {
 		"a_mergeorder":    1,
 		"s_nickname":      1,
 		"l_firstpushtime": 1,
-		//"i_dataexport": 1,
-		//"i_smartset":1,
 	}).Iter()
 	n := 0
+	freeUser := NewFreeUser() //免费所有用户
+	vipUser := NewVipUser()   //vip所有用户
+	//vip标题匹配
+	vip_title_key_user := make(map[string]*[]*UserInfo)
+	vip_title_notkey_user := make(map[string]*[]*UserInfo)
+	//vip正文匹配
+	vip_detail_key_user := make(map[string]*[]*UserInfo)
+	vip_detail_notkey_user := make(map[string]*[]*UserInfo)
+	//免费用户
+	title_key_user := make(map[string]*[]*UserInfo)
+	title_notkey_user := make(map[string]*[]*UserInfo)
 	for temp := make(map[string]interface{}); query.Next(temp); {
 		s_m_openid := util.ObjToString(temp["s_m_openid"])
 		a_m_openid := util.ObjToString(temp["a_m_openid"])
@@ -352,7 +325,13 @@ func (m *MatchJob) OnceUserBatch(user_batch_index int) int {
 			}
 		}
 		applystatus := util.IntAll(temp["i_applystatus"])
-		o_msgset, _ := temp["o_jy"].(map[string]interface{})
+		vipStatus := util.IntAll(temp["i_vipstatus"])
+		var o_msgset map[string]interface{}
+		if !IsVipUser(vipStatus) {
+			o_msgset, _ = temp["o_jy"].(map[string]interface{})
+		} else {
+			o_msgset, _ = temp["o_vipjy"].(map[string]interface{})
+		}
 		wxpush, apppush, mailpush := mutil.ModeTransform(userType, o_msgset)
 		email := strings.TrimSpace(util.ObjToString(o_msgset["s_email"]))
 		if !MailReg.MatchString(email) {
@@ -361,78 +340,95 @@ func (m *MatchJob) OnceUserBatch(user_batch_index int) int {
 		if wxpush != 1 && apppush != 1 && mailpush != 1 {
 			continue
 		}
-		var allkeysTemp []elastic.KeyConfig
-		_bs, err := json.Marshal(o_msgset["a_key"])
-		if err == nil {
-			json.Unmarshal(_bs, &allkeysTemp)
-		}
-		allkeys := []elastic.KeyConfig{}
-		if len(allkeysTemp) > 0 {
-			//一个字或者配置文件中的词,不推送
-			for _, vs := range allkeysTemp {
-				isFilter := false
-				vskey := strings.Replace(strings.Join(vs.Keys, ""), " ", "", -1)
-				if len([]rune(vskey)) == 1 {
-					continue
-				}
-				for _, fv := range SysConfig.FilterWords {
-					if fv == vskey {
-						isFilter = true
-						break
-					}
-				}
-				if !isFilter {
-					allkeys = append(allkeys, vs)
+		userId := fmt.Sprintf("%x", string(temp["_id"].(bson.ObjectId)))
+		var allKeySet []*KeySet
+		var err error
+		if !IsVipUser(vipStatus) {
+			allKeySet, err = m.GetKeySet(o_msgset["a_key"])
+		} else {
+			vip_items, _ := o_msgset["a_items"].([]interface{})
+			for _, v := range vip_items {
+				vip_item, _ := v.(map[string]interface{})
+				var vip_keySet []*KeySet
+				vip_keySet, err = m.GetKeySet(vip_item["a_key"])
+				if err != nil {
+					break
 				}
+				allKeySet = append(allKeySet, vip_keySet...)
 			}
 		}
-		////////////////
-		if len(allkeys) == 0 {
+		if err != nil {
+			logger.Error("获取用户关键词错误!", userId, err)
 			continue
 		}
-		userId := fmt.Sprintf("%x", string(temp["_id"].(bson.ObjectId)))
-		//smartset := util.IntAll(temp["i_smartset"])
-		//dataExport := util.IntAll(temp["i_dataexport"])
 		rateMode := util.IntAllDef(o_msgset["i_ratemode"], 2)
-		logger.Info("第", user_batch_index, "批用户,userid", userId, "s_m_openid", s_m_openid, "a_m_openid", a_m_openid, "s_phone", s_phone, "jpushid", jpushid, "opushid", opushid, "applystatus", applystatus, "email", email, "rateMode", rateMode, "wxpush", wxpush, "apppush", apppush, "mailpush", mailpush)
+		logger.Info("第", user_batch_index, "批用户,userid", userId, "s_m_openid", s_m_openid, "a_m_openid", a_m_openid, "s_phone", s_phone, "jpushid", jpushid, "opushid", opushid, "applystatus", applystatus, "email", email, "rateMode", rateMode, "wxpush", wxpush, "apppush", apppush, "mailpush", mailpush, "vipstatus", vipStatus)
 		keys := []string{}                           //过滤后的关键词
 		notkeys := []string{}                        //排除词
 		key_notkey := map[string]map[string]bool{}   //关键词所对应的排除词
 		key_area := map[string]map[string]bool{}     //关键词所对应的信息范围
 		key_infotype := map[string]map[string]bool{} //关键词所对应的信息类型
-		for _, vs := range allkeys {
-			key := strings.Join(vs.Keys, "+")
+		originalKeys := []string{}                   //原始关键词
+		////////////////
+		for _, vs := range allKeySet {
+			var vs_keys []string
+			for _, vs_v := range [][]string{vs.Keys, vs.AppendKeys} {
+				for _, vs_vv := range vs_v {
+					vs_vv = strings.TrimSpace(vs_vv)
+					if vs_vv == "" {
+						continue
+					}
+					vs_keys = append(vs_keys, vs_vv)
+				}
+			}
+			if len(vs_keys) == 0 {
+				continue
+			}
+			key := strings.Join(vs_keys, "+")
+			originalKeys = append(originalKeys, key)
+			//一个字或者配置文件中的词,不推送
+			//if len([]rune(key)) == 1 {
+			//continue
+			//}
+			isFilter := false
+			for _, fv := range SysConfig.FilterWords {
+				if fv == key {
+					isFilter = true
+					break
+				}
+			}
+			if isFilter {
+				continue
+			}
 			keys = append(keys, key)
 			notkeys = append(notkeys, vs.NotKeys...)
 			//转大写
-			keyTemp := strings.ToUpper(key)
+			upperKey := strings.ToUpper(key)
 			//建立与排除词的对应关系
 			for _, notkey := range vs.NotKeys {
-				notkeyTemp := strings.ToUpper(notkey)
-				if key_notkey[keyTemp] == nil {
-					key_notkey[keyTemp] = map[string]bool{}
+				upperNotkey := strings.ToUpper(notkey)
+				if key_notkey[upperKey] == nil {
+					key_notkey[upperKey] = map[string]bool{}
 				}
-				key_notkey[keyTemp][notkeyTemp] = true
+				key_notkey[upperKey][upperNotkey] = true
 			}
 			//建立与信息范围的对应关系
 			for _, area := range vs.Areas {
-				if key_area[keyTemp] == nil {
-					key_area[keyTemp] = map[string]bool{}
+				if key_area[upperKey] == nil {
+					key_area[upperKey] = map[string]bool{}
 				}
-				key_area[keyTemp][area] = true
+				key_area[upperKey][area] = true
 			}
 			//建立与信息类型的对应关系
 			for _, infotype := range vs.InfoTypes {
-				if key_infotype[keyTemp] == nil {
-					key_infotype[keyTemp] = map[string]bool{}
+				if key_infotype[upperKey] == nil {
+					key_infotype[upperKey] = map[string]bool{}
 				}
-				key_infotype[keyTemp][infotype] = true
+				key_infotype[upperKey][infotype] = true
 			}
 		}
-		//
-		keysTemp := []string{} //原始关键词
-		for _, vs := range allkeysTemp {
-			keysTemp = append(keysTemp, strings.Join(vs.Keys, "+"))
+		if !IsVipUser(vipStatus) && len(originalKeys) == 0 {
+			continue
 		}
 		modifydate := ""
 		md, _ := o_msgset["l_modifydate"].(int64)
@@ -445,12 +441,8 @@ func (m *MatchJob) OnceUserBatch(user_batch_index int) int {
 		}
 		user := &UserInfo{
 			Id:           userId,
-			OriginalKeys: keysTemp,
-			Keys:         keys, //原始关键词
-			NotKeys:      notkeys,
+			Keys:         originalKeys,
 			Key_notkey:   key_notkey,
-			Key_area:     key_area,
-			Key_infotype: key_infotype,
 			WxPush:       wxpush,
 			AppPush:      apppush,
 			MailPush:     mailpush,
@@ -463,17 +455,81 @@ func (m *MatchJob) OnceUserBatch(user_batch_index int) int {
 			Opushid:      opushid,
 			UserType:     userType,
 			RateMode:     rateMode,
-			AllKeys:      allkeysTemp, //原始关键词
 			ModifyDate:   modifydate,
 			AppPhoneType: appPhoneType,
 			ApplyStatus:  applystatus,
 			Subscribe:    isPush,
+			MatchType:    util.IntAllDef(o_msgset["i_matchway"], 1),
 			MergeOrder:   temp["a_mergeorder"],
 			NickName:     util.ObjToString(temp["s_nickname"]),
-			//SmartSet:     smartset,
-			//DataExport:   dataExport,
+			VipStatus:    vipStatus,
+		}
+		/***************start*****************/
+		if !IsVipUser(vipStatus) {
+			user.O_jy = &O_jy{
+				Area:     key_area,
+				Infotype: key_infotype,
+			}
+			m.MakeKeyUser(keys, user, &title_key_user)
+			m.MakeKeyUser(notkeys, user, &title_notkey_user)
+		} else {
+			//vip付费-采购单位行业
+			vip_buyerclass, _ := o_msgset["a_buyerclass"].([]interface{})
+			if len(vip_buyerclass) == 0 {
+				vipUser.Add("", user, &vipUser.BuyerclassUsers)
+			} else {
+				for _, v := range vip_buyerclass {
+					s_v, _ := v.(string)
+					if s_v == "" {
+						continue
+					}
+					vipUser.Add(s_v, user, &vipUser.BuyerclassUsers)
+				}
+			}
+			//vip付费-区域
+			vip_area, _ := o_msgset["o_area"].(map[string]interface{})
+			if len(vip_area) == 0 {
+				vipUser.Add("", user, &vipUser.AreaUsers)
+			} else {
+				for k, v := range vip_area {
+					if k == "" {
+						continue
+					}
+					vs, _ := v.([]interface{})
+					if len(vs) == 0 {
+						vipUser.Add(k, user, &vipUser.AreaUsers)
+					} else {
+						for _, vv := range vs {
+							s_vv, _ := vv.(string)
+							if s_vv == "" {
+								continue
+							}
+							vipUser.Add(s_vv, user, &vipUser.CityUsers)
+						}
+					}
+				}
+			}
+			//vip付费-信息类型
+			vip_infotype, _ := o_msgset["a_infotype"].([]interface{})
+			if len(vip_infotype) == 0 {
+				vipUser.Add("", user, &vipUser.InfoTypeUsers)
+			} else {
+				for _, v := range vip_infotype {
+					s_v, _ := v.(string)
+					if s_v == "" {
+						continue
+					}
+					vipUser.Add(s_v, user, &vipUser.InfoTypeUsers)
+				}
+			}
+			m.MakeKeyUser(keys, user, &vip_title_key_user)
+			m.MakeKeyUser(notkeys, user, &vip_title_notkey_user)
+			if user.MatchType == 2 {
+				m.MakeKeyUser(keys, user, &vip_detail_key_user)
+				m.MakeKeyUser(notkeys, user, &vip_detail_notkey_user)
+			}
 		}
-		(*m.users)[user.Id] = user
+		/***************end*****************/
 		m.lastUserId = user.Id
 		temp = make(map[string]interface{})
 		n++
@@ -481,8 +537,38 @@ func (m *MatchJob) OnceUserBatch(user_batch_index int) int {
 			break
 		}
 	}
+	//
+	vip_title_pjob := &Pjob{
+		Key_user:    &vip_title_key_user,
+		Notkey_user: &vip_title_notkey_user,
+	}
+	vip_title_pjob.CreateDaf()
+	vip_detail_pjob := &Pjob{
+		Key_user:    &vip_detail_key_user,
+		Notkey_user: &vip_detail_notkey_user,
+	}
+	vip_detail_pjob.CreateDaf()
+	vipUser.Title_Pjob = vip_title_pjob
+	vipUser.Detail_Pjob = vip_detail_pjob
+	//
+	title_pjob := &Pjob{
+		Key_user:    &title_key_user,
+		Notkey_user: &title_notkey_user,
+	}
+	title_pjob.CreateDaf()
+	freeUser.Title_Pjob = title_pjob
 	logger.Info("第", user_batch_index, "批用户加载结束", n)
-	return n
+	return n, vipUser, freeUser
+}
+
+//得到用户的关键词
+func (m *MatchJob) GetKeySet(a_key interface{}) ([]*KeySet, error) {
+	var keySet []*KeySet
+	_bs, err := json.Marshal(a_key)
+	if err == nil {
+		err = json.Unmarshal(_bs, &keySet)
+	}
+	return keySet, err
 }
 
 //把用户挂在词下面
@@ -494,23 +580,20 @@ func (m *MatchJob) MakeKeyUser(keys []string, user *UserInfo, key_user *map[stri
 			continue
 		}
 		mp[v] = true
-		var arr *[]*UserInfo
-		if nil == (*key_user)[v] {
+		arr := (*key_user)[v]
+		if arr == nil {
 			arr = &[]*UserInfo{}
-			(*key_user)[v] = arr
-		} else {
-			arr = (*key_user)[v]
-			(*key_user)[v] = arr
 		}
 		*arr = append(*arr, user)
+		(*key_user)[v] = arr
 	}
 }
 
 //遍历数据并执行推送操作
-func (m *MatchJob) EachAllBidInfo(a_p *Pjob, s_p *Pjob) *map[string]*list.List {
+func (m *MatchJob) EachAllBidInfo(matcher Matcher) *map[*UserInfo]*list.List {
 	defer util.Catch()
 	logger.Info("开始遍历数据。。。")
-	userMap := &map[string]*list.List{}
+	userMap := map[*UserInfo]*list.List{}
 	var count int
 	for _, temp := range *m.datas {
 		m.matchPool <- true
@@ -521,39 +604,9 @@ func (m *MatchJob) EachAllBidInfo(a_p *Pjob, s_p *Pjob) *map[string]*list.List {
 				m.eachInfoWaitGroup.Done()
 				<-m.matchPool
 			}()
-			title := util.ObjToString(info["title"])
-			if title == "" {
-				return
-			}
-			titleTemp := strings.ToUpper(title)
-			area := util.ObjToString(info["area"])
-			toptype := util.ObjToString(info["toptype"])
-			//订阅词
-			keys := a_p.InterestDfa.Analy(titleTemp)
-			//排除词
-			notkeys := a_p.NotInterestDfa.Analy(titleTemp)
-			users := m.GetFinalUser(keys, notkeys, a_p.Key_user, area, toptype, true)
-			//开启智能匹配的用户,匹配projectscope
-			if s_p != nil {
-				projectscope := util.ObjToString(info["projectscope"])
-				if projectscope == "" {
-					projectscope = util.ObjToString(info["detail"])
-				}
-				if projectscope != "" {
-					projectscopeTemp := strings.ToUpper(projectscope)
-					keys = s_p.InterestDfa.Analy(projectscopeTemp)
-					notkeys = s_p.NotInterestDfa.Analy(projectscopeTemp)
-					s_users := m.GetFinalUser(keys, notkeys, s_p.Key_user, area, toptype, false)
-					for _, s_u := range *s_users {
-						if (*users)[s_u.User.Id] != nil {
-							continue
-						}
-						(*users)[s_u.User.Id] = s_u
-					}
-				}
-			}
+			users := matcher.Match(&info)
 			if len(*users) > 0 {
-				m.EachInfoToUser(users, &info, userMap)
+				m.EachInfoToUser(users, &info, &userMap)
 			}
 		}(temp)
 		if count%500 == 0 {
@@ -562,70 +615,11 @@ func (m *MatchJob) EachAllBidInfo(a_p *Pjob, s_p *Pjob) *map[string]*list.List {
 	}
 	m.eachInfoWaitGroup.Wait()
 	logger.Info("数据遍历完成!")
-	return userMap
-}
-
-//获取最终的用户,排除词、信息范围、信息类型之后的
-//返回匹配上的用户和没有匹配到的用户
-func (m *MatchJob) GetFinalUser(keys, notkeys []string, key_user *map[string]*[]*UserInfo, area, toptype string, flag bool) *map[string]*MatchUser {
-	keyMap := map[string]bool{}
-	for _, v := range keys {
-		keyMap[v] = true
-	}
-	y_users := map[string]*MatchUser{} //匹配到用户
-	//遍历所有用户
-	for k, us := range *key_user {
-		if !keyMap[k] { //改关键词没有匹配到的用户
-			continue
-		}
-		for _, u := range *us {
-			//获取该词下面所有的用户
-			//遍历我的排除词,如果存在的话,排除自己
-			isContinue := false
-			for _, notkey := range notkeys {
-				if u.Key_notkey[k][notkey] {
-					isContinue = true
-					break
-				}
-			}
-			if isContinue {
-				continue
-			}
-			//遍历我的信息范围,看该信息是不是在我的信息范围中
-			if len(u.Key_area[k]) > 0 && !u.Key_area[k][area] {
-				continue
-			}
-			//遍历我的信息类型,看该信息是不是在我的信息类型中
-			if len(u.Key_infotype[k]) > 0 && !u.Key_infotype[k][toptype] {
-				continue
-			}
-			matchUser := y_users[u.Id]
-			if matchUser == nil {
-				matchUser = &MatchUser{
-					User: u,
-					Keys: []string{},
-				}
-			}
-			matchUser.Keys = append(matchUser.Keys, k)
-			y_users[u.Id] = matchUser
-		}
-	}
-	//获取最终没有匹配到的用户,进行正文或者范围匹配
-	users := map[string]*MatchUser{}
-	for k, v := range *m.users {
-		if y_users[k] == nil {
-			continue
-		}
-		users[v.Id] = &MatchUser{
-			User: v,
-			Keys: y_users[k].Keys,
-		}
-	}
-	return &users
+	return &userMap
 }
 
 //遍历用户加入到此条信息上
-func (m *MatchJob) EachInfoToUser(users *map[string]*MatchUser, info *map[string]interface{}, userMap *map[string]*list.List) {
+func (m *MatchJob) EachInfoToUser(users *map[*UserInfo]*MatchUser, info *map[string]interface{}, userMap *map[*UserInfo]*list.List) {
 	defer m.userMapLock.Unlock()
 	m.userMapLock.Lock()
 	for k, v := range *users {

+ 131 - 0
src/jfw/modules/pushsubscribe/src/match/job/vipuser.go

@@ -0,0 +1,131 @@
+package job
+
+import (
+	. "public"
+	"strings"
+)
+
+//付费用户
+type VipUser struct {
+	Users           map[*UserInfo]bool
+	Title_Pjob      *Pjob
+	Detail_Pjob     *Pjob
+	BuyerclassUsers map[string]map[*UserInfo]bool
+	AreaUsers       map[string]map[*UserInfo]bool
+	CityUsers       map[string]map[*UserInfo]bool
+	InfoTypeUsers   map[string]map[*UserInfo]bool
+	MatchJob        *MatchJob
+}
+
+func (v *VipUser) Add(k string, u *UserInfo, m *map[string]map[*UserInfo]bool) {
+	mk := (*m)[k]
+	if mk == nil {
+		mk = map[*UserInfo]bool{}
+	}
+	mk[u] = true
+	(*m)[k] = mk
+}
+func NewVipUser() *VipUser {
+	return &VipUser{
+		Users:           map[*UserInfo]bool{},
+		BuyerclassUsers: map[string]map[*UserInfo]bool{},
+		AreaUsers:       map[string]map[*UserInfo]bool{},
+		CityUsers:       map[string]map[*UserInfo]bool{},
+		InfoTypeUsers:   map[string]map[*UserInfo]bool{},
+	}
+}
+
+func (v *VipUser) Match(info *map[string]interface{}) *map[*UserInfo]*MatchUser {
+	buyerclass, _ := (*info)["buyerclass"].(string)
+	area, _ := (*info)["area"].(string)
+	city, _ := (*info)["city"].(string)
+	toptype, _ := (*info)["toptype"].(string)
+	title, _ := (*info)["title"].(string)
+	title = strings.ToUpper(title)
+	//订阅词
+	keys := v.Title_Pjob.InterestDfa.Analy(title)
+	//排除词
+	notkeys := v.Title_Pjob.NotInterestDfa.Analy(title)
+	title_users := v.GetFinalUser(keys, notkeys, v.Title_Pjob.Key_user)
+	//开启智能匹配的用户,匹配projectscope
+	detail_users := &map[*UserInfo]*MatchUser{}
+	if v.Detail_Pjob != nil {
+		detail, _ := (*info)["projectscope"].(string)
+		if detail == "" {
+			detail, _ = (*info)["detail"].(string)
+		}
+		if detail != "" {
+			detail = strings.ToUpper(detail)
+			keys = v.Detail_Pjob.InterestDfa.Analy(detail)
+			notkeys = v.Detail_Pjob.NotInterestDfa.Analy(detail)
+			detail_users = v.GetFinalUser(keys, notkeys, v.Detail_Pjob.Key_user)
+			for d_k, d_u := range *detail_users {
+				if (*title_users)[d_k] != nil {
+					continue
+				}
+				(*title_users)[d_k] = d_u
+			}
+		}
+	}
+	users := map[*UserInfo]*MatchUser{}
+	for k, _ := range v.Users {
+		if (!v.BuyerclassUsers[""][k] && !v.BuyerclassUsers[buyerclass][k]) ||
+			(!v.AreaUsers[""][k] || !v.AreaUsers[area][k] || !v.AreaUsers[city][k]) ||
+			(!v.InfoTypeUsers[""][k] || !v.InfoTypeUsers[toptype][k]) {
+			continue
+		}
+		var matchUser *MatchUser
+		if len(k.OriginalKeys) > 0 {
+			matchUser = (*title_users)[k]
+			if matchUser == nil {
+				matchUser = (*detail_users)[k]
+			}
+			if matchUser == nil {
+				continue
+			}
+		} else {
+			matchUser = &MatchUser{}
+		}
+		users[k] = matchUser
+	}
+	return &users
+}
+
+//获取最终的用户,排除词、信息范围、信息类型之后的
+//返回匹配上的用户和没有匹配到的用户
+func (v *VipUser) GetFinalUser(keys, notkeys []string, key_user *map[string]*[]*UserInfo) *map[*UserInfo]*MatchUser {
+	keyMap := map[string]bool{}
+	for _, v := range keys {
+		keyMap[v] = true
+	}
+	users := map[*UserInfo]*MatchUser{} //匹配到用户
+	//遍历所有用户
+	for k, us := range *key_user {
+		if !keyMap[k] { //该关键词没有匹配到的用户
+			continue
+		}
+		for _, u := range *us {
+			//获取该词下面所有的用户
+			//遍历我的排除词,如果存在的话,排除自己
+			isContinue := false
+			for _, notkey := range notkeys {
+				if u.Key_notkey[k][notkey] {
+					isContinue = true
+					break
+				}
+			}
+			if isContinue {
+				continue
+			}
+			matchUser := users[u]
+			if matchUser == nil {
+				matchUser = &MatchUser{
+					Keys: []string{},
+				}
+			}
+			matchUser.Keys = append(matchUser.Keys, k)
+			users[u] = matchUser
+		}
+	}
+	return &users
+}

+ 47 - 27
src/jfw/modules/pushsubscribe/src/public/entity.go

@@ -2,52 +2,72 @@ package public
 
 import (
 	"qfw/util"
-	"qfw/util/elastic"
 )
 
 type UserInfo struct {
 	Id            string                     //mongoid
-	Province      string                     //省份
 	Key_notkey    map[string]map[string]bool //关键词-排除词
-	Key_area      map[string]map[string]bool //关键词-信息范围
-	Key_infotype  map[string]map[string]bool //关键词-信息类型
-	OriginalKeys  []string                   //用户兴趣
-	Keys          []string                   //用户兴趣
-	NotKeys       []string                   //用户不感兴趣
+	Keys          []string                   //用户原始关键词
 	S_m_openid    string                     //公众号openid
 	A_m_openid    string                     //app微信登录openid
 	Phone         string                     //app手机号登录
-	Jpushid       string
-	Opushid       string
-	InterestDate  int64
-	WxPush        int
-	AppPush       int
-	MailPush      int
-	PchelperPush  int
-	RateMode      int
-	Email         string
-	AllKeys       []elastic.KeyConfig
-	ModifyDate    string
-	AppPhoneType  string
-	ApplyStatus   int
-	Subscribe     int
-	UserType      int
-	MergeOrder    interface{}
-	NickName      string
-	FirstPushTime int64
-	//SmartSet      int //智能订阅 1开启 0关闭
-	//DataExport    int //是否导出数据 1开启 0关闭
+	Jpushid       string                     //极光推送id
+	Opushid       string                     //厂商推送id
+	WxPush        int                        //是否开启微信推送
+	AppPush       int                        //是否开启app推送
+	MailPush      int                        //是否开启邮箱推送
+	PchelperPush  int                        //是否pc助手推送
+	RateMode      int                        //推送时间
+	Email         string                     //邮箱
+	ModifyDate    string                     //修改时间
+	AppPhoneType  string                     //手机型号
+	ApplyStatus   int                        //是否申请打开订阅推送
+	Subscribe     int                        //是否关注
+	UserType      int                        //用户类型
+	MergeOrder    interface{}                //用户合并顺序
+	NickName      string                     //昵称
+	FirstPushTime int64                      //第一次推送时间
+	VipStatus     int                        // 1--试用 2--正式
+	MatchType     int                        //匹配方式 1-标题 2-正文
+	O_jy          *O_jy
 	//
 	//Active int
 	//Fail   *Fail //失败重试
 }
 
+type O_jy struct {
+	Area     map[string]map[string]bool //关键词-信息范围
+	Infotype map[string]map[string]bool //关键词-信息类型
+}
+
+//关键词
+type KeySet struct {
+	Keys       []string `json:"key"`       //关键词
+	NotKeys    []string `json:"notkey"`    //排除词
+	InfoTypes  []string `json:"infotype"`  //信息类型
+	Areas      []string `json:"area"`      //地区
+	AppendKeys []string `json:"appendkey"` //附加词
+}
+
 type Fail struct {
 	Wx    int
 	App   int
 	Email int
 }
 
+type Bidding struct {
+	Id              string
+	Area            string
+	City            string
+	Buyerclass      string
+	Publishtime     int64
+	S_subscopeclass []string
+	Subtype         string
+	Title           string
+	Toptype         string
+	Type            string
+}
+
 type SortList []*MatchInfo
 
 func (s SortList) Len() int {

+ 8 - 0
src/jfw/modules/pushsubscribe/src/public/util.go

@@ -0,0 +1,8 @@
+package public
+
+func IsVipUser(vipStatus int) bool {
+	if vipStatus == 1 || vipStatus == 2 {
+		return true
+	}
+	return false
+}

+ 2 - 1
src/jfw/modules/pushsubscribe/src/push/config.json

@@ -8,7 +8,7 @@
 		"size": 5,
 		"timeout": 20
 	},
-	"redisServers": "pushcache_2_a=192.168.3.128:5000,pushcache_2_b=192.168.3.128:5000",
+	"redisServers": "pushcache_2_a=192.168.3.128:5000,pushcache_2_b=192.168.3.128:5000,other=192.168.3.128:5000",
 	"mail_content": "<tr><td><num>%d</num></td><td><div class='tit'><a style='color: #000;text-decoration: none;' href='%s?mail' >%s</a></div></td><td style='float: right;' class='infos' ><span class='%s'>%s</span><span class='%s'>%s</span><span class='%s'>%s</span><span class='time'>%s</span></td></tr>",
 	"mail_html": "<body><style> *,body,html{margin:0;padding:0;font-family: tahoma, arial, 'Hiragino Sans GB', 'Microsoft YaHei', 宋体, sans-serif;font-size:16px; }#all{margin:0 auto;width:1024px;overflow:hidden;}.head{margin:5x;margin-top:20px;}.des{padding-bottom:15px;border-bottom:1px solid #e8ecee;color: #686868;}td a:hover {color: #fe7379;text-decoration: underline;} .tit{width:560px;overflow: hidden;    white-space: nowrap;text-overflow: ellipsis;}.area {background-color: #2cb7ca;border-radius: 3px;color: #fff;padding: 1px 2px;}.type {background-color: #ffba00;border-radius: 3px;color: #fff;padding: 1px 2px;margin-left:5px;}.industry {background-color: #25c78c;border-radius: 3px;color: #fff;padding: 1px 2px;margin-left:5px;}.infos span{display:inline-block;margin-left:5px;}td{padding-top:8px;padding-bottom:8px;height:20px;line-height:20px;}num{padding:0 5px 0 0; font-size:16px;color:#2cb7ca;font-weight:bolder;}.keys{color:blue;} </style><div id='all'><div class='head'><IMG width='100px' src=http://www.zhaobiao.info/images/swordfish/sf_01.png /></div><div class='head des'>根据您设置的关键词 :<span class='keys'>%s</span>,剑鱼标讯为您推送30天之内的信息。点击标题可查看详情信息</div><table cellpadding='0' cellspacing='0'>%s</table></div> </body>",
 	"mail_title": "您有新的%s信息-剑鱼标讯",
@@ -31,6 +31,7 @@
 		}
 	],
 	"maxPushSize": 50,
+	"vipOneDayMaxPushSize": 2000,
 	"mgoAddr": "192.168.3.128:27080",
 	"mgoSize": 10,
 	"testids": ["5d6e142a25ef871f08a72662"],

+ 1 - 0
src/jfw/modules/pushsubscribe/src/push/config/config.go

@@ -33,6 +33,7 @@ type sysConfig struct {
 	OncePushTime            string      `json:"oncePushTime"`
 	OtherPushTimes          []string    `json:"otherPushTimes"`
 	WxPollSize              int         `json:"wxPollSize"`
+	VipOneDayMaxPushSize    int64       `json:"vipOneDayMaxPushSize"`
 	AppPollSize             int         `json:"appPollSize"`
 	MailSleep               int         `json:"mailSleep"`
 	CassandraSleep          int         `json:"cassandraSleep"`

+ 14 - 20
src/jfw/modules/pushsubscribe/src/push/job/dopush.go

@@ -9,6 +9,7 @@ import (
 	"qfw/util"
 	"qfw/util/mail"
 	"qfw/util/mongodb"
+	"qfw/util/redis"
 	"strconv"
 	"strings"
 	"time"
@@ -57,8 +58,8 @@ func (d *doPush) Do(taskType int, isSave bool, wxPush, appPush, mailPush int, k
 	infos := []map[string]interface{}{}
 	publishTitle := map[string]bool{}
 	pushIds := []string{}
+	nowymd := util.NowFormat(util.Date_yyyyMMdd)
 	//邮件附件
-	//var fmdatas = []map[string]interface{}{}
 	for _, ks := range *sl {
 		k2 := *ks.Info
 		title := strings.Replace(k2["title"].(string), "\n", "", -1)
@@ -115,7 +116,7 @@ func (d *doPush) Do(taskType int, isSave bool, wxPush, appPush, mailPush int, k
 			dates := util.LongToDate(k2["publishtime"], false)
 			//标题替换
 			otitle := title
-			for _, kw := range k.OriginalKeys {
+			for _, kw := range k.Keys {
 				kws := strings.Split(kw, "+")
 				n := 0
 				otitle2 := otitle
@@ -137,23 +138,16 @@ func (d *doPush) Do(taskType int, isSave bool, wxPush, appPush, mailPush int, k
 				industryclass = ""
 			}
 			mailContent += fmt.Sprintf(SysConfig.Mail_content, i, url, otitle, classArea, area, classType, infotype, industryclass, industry, dates)
-			// if k.DataExport == 1 {
-			// 	//附件数据
-			// 	fmdatas = append(fmdatas, map[string]interface{}{
-			// 		"publishtime": k2["publishtime"],
-			// 		"subtype":     k2["subtype"],
-			// 		"buyer":       k2["buyer"],
-			// 		"projectname": k2["projectname"],
-			// 		"budget":      k2["budget"],
-			// 		"bidopentime": k2["bidopentime"],
-			// 		"winner":      k2["winner"],
-			// 		"bidamount":   k2["bidamount"],
-			// 	})
-			// }
 		}
-		if i >= SysConfig.MaxPushSize {
+		if IsVipUser(k.VipStatus) {
+			if redis.Incr("other", fmt.Sprintf("daycount_%s_%s", nowymd, k.Id)) >= SysConfig.VipOneDayMaxPushSize {
+				break
+			}
+		} else {
 			//限制最大信息条数
-			break
+			if i >= SysConfig.MaxPushSize {
+				break
+			}
 		}
 	}
 	if i == 0 {
@@ -170,7 +164,7 @@ func (d *doPush) Do(taskType int, isSave bool, wxPush, appPush, mailPush int, k
 	}
 	if taskType != 0 && isSave {
 		//推送记录id
-		pushId := putil.SaveSendInfo(k, pushIds, infos)
+		pushId := putil.SaveSendInfo(k, infos)
 		if pushId == "" {
 			logger.Info("推送任务", taskType, "保存到cassandra出错", k.Id)
 			return
@@ -215,7 +209,7 @@ func (d *doPush) Do(taskType int, isSave bool, wxPush, appPush, mailPush int, k
 				LastTip = fmt.Sprintf("...(共%d条)", i)
 			}
 			LastTipLen := len([]rune(LastTip))
-			wxTitleKeys := strings.Join(k.OriginalKeys, ";")
+			wxTitleKeys := strings.Join(k.Keys, ";")
 			if len([]rune(wxTitleKeys)) > 8 {
 				wxTitleKeys = string([]rune(wxTitleKeys)[:8]) + "..."
 			}
@@ -303,7 +297,7 @@ func (d *doPush) Do(taskType int, isSave bool, wxPush, appPush, mailPush int, k
 	//发送邮件
 	if mailPush == 1 {
 		logger.Info("推送任务", taskType, "开始邮箱推送", k.Id)
-		html := fmt.Sprintf(SysConfig.Mail_html, strings.Replace(strings.Join(k.OriginalKeys, ";"), "+", " ", -1), mailContent)
+		html := fmt.Sprintf(SysConfig.Mail_html, strings.Replace(strings.Join(k.Keys, ";"), "+", " ", -1), mailContent)
 		subject := fmt.Sprintf(SysConfig.Mail_title, "招标")
 		isPushOk := d.SendMail(k.Email, subject, html, nil)
 		if isPushOk {

+ 15 - 16
src/jfw/modules/pushsubscribe/src/push/job/pushjob.go

@@ -320,28 +320,27 @@ func (p *pushJob) Push() {
 				}()
 				words, _ := v["words"].([]interface{})
 				u := &UserInfo{
-					Id:           util.ObjToString(v["userid"]),
-					OriginalKeys: util.ObjArrToStringArr(words),
-					WxPush:       util.IntAll(v["wxpush"]),
-					AppPush:      util.IntAll(v["apppush"]),
-					MailPush:     util.IntAll(v["mailpush"]),
-					PchelperPush: util.IntAll(v["pchelperpush"]),
-					Email:        util.ObjToString(v["email"]),
-					S_m_openid:   util.ObjToString(v["s_m_openid"]),
-					A_m_openid:   util.ObjToString(v["a_m_openid"]),
-					Phone:        util.ObjToString(v["phone"]),
-					Jpushid:      util.ObjToString(v["jpushid"]),
-					Opushid:      util.ObjToString(v["opushid"]),
-					UserType:     util.IntAll(v["usertype"]),
-					RateMode:     util.IntAllDef(v["ratemode"], 1),
-					//SmartSet:      util.IntAllDef(v["smartset"], 1),
-					//DataExport:    util.IntAll(v["dataexport"]),
+					Id:            util.ObjToString(v["userid"]),
+					Keys:          util.ObjArrToStringArr(words),
+					WxPush:        util.IntAll(v["wxpush"]),
+					AppPush:       util.IntAll(v["apppush"]),
+					MailPush:      util.IntAll(v["mailpush"]),
+					PchelperPush:  util.IntAll(v["pchelperpush"]),
+					Email:         util.ObjToString(v["email"]),
+					S_m_openid:    util.ObjToString(v["s_m_openid"]),
+					A_m_openid:    util.ObjToString(v["a_m_openid"]),
+					Phone:         util.ObjToString(v["phone"]),
+					Jpushid:       util.ObjToString(v["jpushid"]),
+					Opushid:       util.ObjToString(v["opushid"]),
+					UserType:      util.IntAll(v["usertype"]),
+					RateMode:      util.IntAllDef(v["ratemode"], 1),
 					AppPhoneType:  util.ObjToString(v["appphonetype"]),
 					ApplyStatus:   util.IntAll(v["applystatus"]),
 					Subscribe:     util.IntAllDef(v["subscribe"], 1),
 					ModifyDate:    util.ObjToString(v["modifydate"]),
 					MergeOrder:    v["mergeorder"],
 					FirstPushTime: util.Int64All(v["firstpushtime"]),
+					VipStatus:     util.IntAll(v["vipstatus"]),
 				}
 				logger.Info("推送任务", p.taskType, "开始推送用户", "userType", u.UserType, "userId", u.Id, "s_m_openid", u.S_m_openid, "a_m_openid", u.A_m_openid, "phone", u.Phone, "subscribe", u.Subscribe, "applystatus", u.ApplyStatus, "jpushid", u.Jpushid, "opushid", u.Opushid, "phoneType", u.AppPhoneType, "rateMode", u.RateMode, "email", u.Email)
 				wxPush, appPush, mailPush := 0, 0, 0

+ 13 - 13
src/jfw/modules/pushsubscribe/src/push/job/repairjob.go

@@ -38,19 +38,19 @@ func (r *repairJob) Execute(param string) bool {
 				}()
 				words, _ := v["words"].([]interface{})
 				u := &public.UserInfo{
-					Id:           util.ObjToString(v["userid"]),
-					OriginalKeys: util.ObjArrToStringArr(words),
-					WxPush:       util.IntAll(v["wxpush"]),
-					AppPush:      util.IntAll(v["apppush"]),
-					MailPush:     util.IntAll(v["mailpush"]),
-					Email:        util.ObjToString(v["email"]),
-					S_m_openid:   util.ObjToString(v["s_m_openid"]),
-					A_m_openid:   util.ObjToString(v["a_m_openid"]),
-					Phone:        util.ObjToString(v["phone"]),
-					Jpushid:      util.ObjToString(v["jpushid"]),
-					Opushid:      util.ObjToString(v["opushid"]),
-					UserType:     util.IntAll(v["usertype"]),
-					RateMode:     util.IntAllDef(v["ratemode"], 1),
+					Id:         util.ObjToString(v["userid"]),
+					Keys:       util.ObjArrToStringArr(words),
+					WxPush:     util.IntAll(v["wxpush"]),
+					AppPush:    util.IntAll(v["apppush"]),
+					MailPush:   util.IntAll(v["mailpush"]),
+					Email:      util.ObjToString(v["email"]),
+					S_m_openid: util.ObjToString(v["s_m_openid"]),
+					A_m_openid: util.ObjToString(v["a_m_openid"]),
+					Phone:      util.ObjToString(v["phone"]),
+					Jpushid:    util.ObjToString(v["jpushid"]),
+					Opushid:    util.ObjToString(v["opushid"]),
+					UserType:   util.IntAll(v["usertype"]),
+					RateMode:   util.IntAllDef(v["ratemode"], 1),
 					//SmartSet:     util.IntAllDef(v["smartset"], 1),
 					//DataExport:   util.IntAll(v["dataexport"]),
 					AppPhoneType: util.ObjToString(v["appphonetype"]),

+ 18 - 8
src/jfw/modules/pushsubscribe/src/push/util/util.go

@@ -8,7 +8,6 @@ import (
 	"qfw/util"
 	"qfw/util/jy"
 	"sort"
-	"strings"
 	"time"
 	ca "ucbsutil/cassandra"
 
@@ -107,7 +106,7 @@ func ModeTransform(userType int, o_msgset map[string]interface{}) (int, int, int
 }
 
 //保存发送信息
-func SaveSendInfo(k *UserInfo, pushIds []string, infos []map[string]interface{}) string {
+func SaveSendInfo(k *UserInfo, infos []map[string]interface{}) string {
 	cassandraPoll <- true
 	defer func() {
 		<-cassandraPoll
@@ -123,13 +122,24 @@ func SaveSendInfo(k *UserInfo, pushIds []string, infos []map[string]interface{})
 		now = now.Add(time.Hour * time.Duration(h)).Add(time.Minute * time.Duration(m))
 	}
 	date := now.Unix()
-	wxpush := map[string]interface{}{
-		"dateymd":  now.Format(util.Date_yyyyMMdd),
-		"uid":      k.Id,
-		"date":     date,
-		"pushinfo": strings.Join(pushIds, ","),
+	dateymd := now.Format(util.Date_yyyyMMdd)
+	var saves []map[string]interface{}
+	for _, info := range infos {
+		wxpush := map[string]interface{}{
+			"dateymd":    dateymd,
+			"uid":        k.Id,
+			"date":       date,
+			"pushinfo":   fmt.Sprint(info["_id"]),
+			"keys":       k.Keys,
+			"area":       util.ObjToString(info["area"]),
+			"city":       util.ObjToString(info["city"]),
+			"buyerclass": util.ObjToString(info["buyerclass"]),
+		}
+		if ca.Save("jy_pushsubscribe", wxpush) {
+			saves = append(saves, info)
+		}
 	}
-	if ca.Save("jy_pushsubscribe", wxpush) {
+	if len(saves) > 0 {
 		updateRedis(date, k, infos)
 		return fmt.Sprint(date)
 	}