package entity import ( MC "app.yhyue.com/moapp/jybase/common" "app.yhyue.com/moapp/jybase/redis" "app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy" "encoding/json" "fmt" IC "jyBXCore/rpc/init" "jyBXCore/rpc/service" "jyBXCore/rpc/type/bxcore" "jyBXCore/rpc/util" "log" "strconv" "strings" "time" ) var ( SearchCacheKey = "searchDataCache_%d_%s_%s_%s" SearchCacheCount = "searchCountCache_%d_%s_%s_%s" ) type KeyWordsSearch struct{} func NewKeyWordsSearch() *KeyWordsSearch { return &KeyWordsSearch{} } // IsEmptySearch 是否是空搜索,如果是空搜索查缓存数据 func (kws *KeyWordsSearch) IsEmptySearch(in *bxcore.SearchReq) bool { //有主关键词 或 选择了行业,都不是空搜索 if strings.TrimSpace(in.KeyWords) != "" || strings.TrimSpace(in.Industry) != "" || strings.TrimSpace(in.AdditionalWords) != "" { return false } //所有的未登录空搜索 缓存都最多查500条数据 return true } // GetBidSearchListByCache 查询缓存数据 // 未登录用户默认搜索和关键词搜索改成500条和免费用户保持一致--需求调整P260来自产品经理杨蘭20220116 func (kws *KeyWordsSearch) GetBidSearchListByCache(in *bxcore.SearchReq) (list []*bxcore.SearchList, count, total int64) { //缓存数据 最大量是5000条 100页数据 l, c := func(in *bxcore.SearchReq) (list []*bxcore.SearchList, count int64) { //缓存数据总量 - 当前平台 redisCountKey := fmt.Sprintf(SearchCacheCount, in.SearchGroup, MC.If(in.IsPay, "v", "f").(string), MC.If(in.BidField != "", in.BidField, "n").(string), in.Platform) count = int64(redis.GetInt(util.RedisNameNew, redisCountKey)) //缓存数据: SearchGroup-全部;招标信息;超前项目信息;kws.PageNum-当前页 免费用户 or 付费用户 redisDataKey := fmt.Sprintf(SearchCacheKey, in.SearchGroup, MC.If(in.IsPay, "v", "f").(string), MC.If(in.BidField != "", in.BidField, "n").(string), in.Platform) sCache, err := redis.GetNewBytes(util.RedisNameNew, redisDataKey) log.Println("-------------------------redisDataKey--------------------------------:", redisDataKey) if err == nil { if sCache != nil && len(*sCache) > 0 { err = json.Unmarshal(*sCache, &list) if err == nil { return } else { log.Println("缓存序列化异常") } } } //无缓存数据 或 缓存数据查询异常 //查库>存redis缓存 //查询缓存数据 参数初始化 kws.DefaultSearchParamsAuto(in) //缓存数据 count, list = service.GetBidSearchData(in, true) if len(list) > 0 { redis.Put(util.RedisNameNew, redisCountKey, count, MC.If(IC.C.DefaultSearchCacheTime > 0, IC.C.DefaultSearchCacheTime*60*60, 24*60*60).(int)) b, err := json.Marshal(list) if err == nil { redis.PutBytes(util.RedisNameNew, redisDataKey, &b, MC.If(IC.C.DefaultSearchCacheTime > 0, IC.C.DefaultSearchCacheTime*60*60, 24*60*60).(int)) } else { log.Println("默认搜索查询结果保存redis缓存异常") } } else { log.Println("默认搜索 暂无数据") } return }(in) if len(l) > 0 { total = c limitCount := int64(util.SearchPageSize * MC.If(in.IsPay, util.SearchMaxPageNum_PAYED, util.SearchMaxPageNum).(int)) count = c if count > limitCount { count = limitCount } list = l[(in.PageNum-1)*in.PageSize : in.PageNum*in.PageSize] //是否收藏 util.MakeCollection(in.UserId, list) } return } // DefaultSearchParamsAuto 缓存查询条件初始化 func (kws *KeyWordsSearch) DefaultSearchParamsAuto(in *bxcore.SearchReq) { in.TopType = "" in.City = "" in.Industry = "" in.FileExists = "" in.WinnerTel = "" in.BuyerTel = "" in.BuyerClass = "" in.Price = "" in.SelectType = "title" in.Province = "" } // SaveKeyWordsToHistory 保存历史记录 func (kws *KeyWordsSearch) SaveKeyWordsToHistory(in *bxcore.SearchReq) { if in.KeyWords != "" { //历史记录 history := redis.GetStr("other", "s_"+in.UserId) keys := util.SearchHistory(history, in.KeyWords, in.AdditionalWords) if len(keys) > 0 { if b := redis.Put("other", "s_"+in.UserId, strings.Join(keys, ","), -1); !b { log.Println("保存搜索记录异常,用户id:", in.UserId) } } } } // GetSearchKeyWordsQueryStr 关键词和附加词处理 获取关键词查询条件;是否进行分词查询 func (kws *KeyWordsSearch) GetSearchKeyWordsQueryStr(in *bxcore.SearchReq) (searchWords []string) { // in.SearchMode 搜索模式:0:精准搜索;1:模糊搜索 // 精准搜索:不分词,完全匹配;(中间带空格的关键词组自动分词) // 模糊搜索:对用户输入的单个关键词进行分词处理,但必须都存在; //主关键词词组 if in.KeyWords != "" { if in.SearchMode == 1 { if ikWords := util.HttpEs(in.KeyWords, "ik_smart", IC.DB.Es.Addr); ikWords != "" { in.KeyWords = jy.KeywordsProcessing(ikWords, IC.C.JYKeyMark) } } searchWords = append(searchWords, in.KeyWords) } //多组附加词,每组间,号隔开。每组内如果关键词中间有空格,自动分词 if in.AdditionalWords != "" { if in.SearchMode == 1 { var ( addWords []string ) for _, awv := range strings.Split(in.AdditionalWords, ",") { if strings.TrimSpace(awv) != "" { if ikWords := util.HttpEs(awv, "ik_smart", IC.DB.Es.Addr); ikWords != "" { addWords = append(addWords, jy.KeywordsProcessing(ikWords, IC.C.JYKeyMark)) } } } if len(addWords) > 0 { in.AdditionalWords = strings.Join(addWords, ",") } } searchWords = append(searchWords, strings.Split(in.AdditionalWords, ",")...) } return } // SearchParamsHandle 搜索条件 处理 func (kws *KeyWordsSearch) SearchParamsHandle(in *bxcore.SearchReq) []string { baseUserId, _ := strconv.ParseInt(in.NewUserId, 10, 64) accountId, _ := strconv.ParseInt(in.AccountId, 10, 64) positionType, _ := strconv.ParseInt(in.PositionType, 10, 64) positionId, _ := strconv.ParseInt(in.PositionId, 10, 64) //判断用户身份 userInfo := IC.Middleground.PowerCheckCenter.Check(in.AppId, in.MgoUserId, baseUserId, accountId, in.EntId, positionType, positionId) //是否是付费用户 in.IsPay = !userInfo.Free.IsFree //默认搜索范围 if in.SelectType == "" { in.SelectType = "title,content" } queryItems := util.GetQueryItems(in.SelectType, IC.C.BidSearchOldUserLimit, userInfo.Free.Registedate, in.IsPay) in.SelectType = strings.Join(queryItems, ",") // in.SearchGroup 搜索分组 搜索分组:默认0:全部;1:招标采购公告;2:超前项目 // 详情页判断是否能使用超前项目 老版超级订阅、大会员、商机管理有权限 if in.SearchGroup < 0 || in.SearchGroup > 2 { in.SearchGroup = 1 } //信息类型 if in.Subtype == "" && in.TopType == "" { //(免费用户和新版超级订阅用户 有搜索权限,但是没有查看权限)免费用户与未登录用户支持 拟建,采购意向搜索 if in.SearchGroup > 0 && len(IC.C.DefaultTopTypes) >= int(in.SearchGroup) { in.Subtype = IC.C.DefaultTopTypes[in.SearchGroup-1] } } // in.SearchMode 搜索模式 搜索模式:0:精准搜索;1:模糊搜索 // 精准搜索:不分词,完全匹配;(中间带空格的关键词组自动分词) // 模糊搜索:对用户输入的单个关键词进行分词处理,但必须都存在; if in.SearchMode < 0 || in.SearchMode > 1 { in.SearchMode = 0 } // in.WordsMode 搜索关键词模式;默认0:包含所有,1:包含任意 if in.WordsMode < 0 || in.WordsMode > 1 { in.WordsMode = 0 } //查询时间publishTime if in.PublishTime == "" { //付费用户最新5年;免费用户||未登录用户最新1年 in.PublishTime = fmt.Sprintf("%d-%d", time.Now().AddDate(-1, 0, 0).Unix(), time.Now().Unix()) if in.IsPay { in.PublishTime = fmt.Sprintf("%d-%d", time.Now().AddDate(-5, 0, 0).Unix(), time.Now().Unix()) } } //默认每页数据量 if in.PageSize <= 0 { in.PageSize = 50 } //第一页 if in.PageNum <= 0 { in.PageNum = 1 } count := MC.If(in.IsPay, IC.C.DefaultBidInfo.PayCount, IC.C.DefaultBidInfo.Count).(int) if in.PageNum > int64(count)/in.PageSize { in.PageNum = -1 in.PageSize = -1 } //行业格式化 if in.Industry != "" { in.Industry = strings.TrimSpace(in.Industry) } //免费用户:高级筛选 采购单位类型、采购单位联系方式、中标企业联系方式、排除词、城市 if userInfo.Free.IsFree { in.BuyerClass = "" in.BuyerTel = "" in.WinnerTel = "" in.ExclusionWords = "" in.City = "" in.ExclusionWords = "" } //判断是否有关键词 if in.KeyWords != "" { //关键词处理 in.KeyWords = strings.TrimSpace(in.KeyWords) in.InterceptKeyWords, in.InterceptOtherWords, in.KeyWords = util.InterceptSearchKW(in.KeyWords, MC.IntAllDef(IC.C.KeywordsLimit, 35), true) // len(in.Industry) == 0 } //附加词 每组附加词不能超过15个字符 if in.AdditionalWords != "" { var additionalWords []string for _, ak := range strings.Split(in.AdditionalWords, ",") { if len([]rune(ak)) > 15 { additionalWords = append(additionalWords, string([]rune(ak)[:15])) } else { additionalWords = append(additionalWords, ak) } } in.AdditionalWords = strings.Join(additionalWords, ",") //分组不变 } //更新关键词搜索历史记录 go kws.SaveKeyWordsToHistory(in) //排除词 每组排除词不能超过15个字符 if in.ExclusionWords != "" { var exclusionWords []string for _, ak := range strings.Split(in.ExclusionWords, ",") { if len([]rune(ak)) > 15 { exclusionWords = append(exclusionWords, string([]rune(ak)[:15])) } else { exclusionWords = append(exclusionWords, ak) } } in.ExclusionWords = strings.Join(exclusionWords, IC.C.JYKeyMark) //util.MatchSpace.ReplaceAllString(in.ExclusionWords, IC.C.JYKeyMark) } return kws.GetSearchKeyWordsQueryStr(in) //格式化关键词 } // GetBidSearchList 非空搜索 查询 func (kws *KeyWordsSearch) GetBidSearchList(in *bxcore.SearchReq) (count, total int64, list []*bxcore.SearchList) { //排除异常in.PageNum参数 count, list = service.GetBidSearchData(in, false) util.MakeCollection(in.UserId, list) total = count //返回数据总量提示信息 limitCount := MC.If(in.IsPay, int64(util.SearchPageSize*util.SearchMaxPageNum_PAYED), int64(util.SearchPageSize*util.SearchMaxPageNum)).(int64) if count > limitCount { count = limitCount //付费用户count 最多5000条,100页数据,每页50条;免费用户count 最多500条,10页数据,每页50条。 } return } // 聚合搜索 func (kws *KeyWordsSearch) PolymerizeSearch(in *bxcore.PolymerizeSearchReq) *bxcore.SearchReturn { data := &bxcore.SearchReturn{} //powerCheck := IC.Middleground.PowerCheckCenter.Check(in.AppId, in.UserId, in.NewUserId, in.AccountId, in.EntId, in.PositionType, in.PositionId) //企业搜索 now1 := time.Now().Unix() entList := &bxcore.SearchMap{} entList.Data, entList.Count = service.EntSearch(in.SearchCode) data.EntList = entList now2 := time.Now().Unix() //采购单位搜搜索 procureList := &bxcore.SearchMap{} procureList.Data, procureList.Count = service.ProcureSearch(in.SearchCode) data.ProcureList = procureList now3 := time.Now().Unix() log.Println("企业查询耗时", now2-now1) log.Println("采购单位搜搜索", now3-now2) /*if in.AccountId > 0 { //菜单搜索 data.MenuList = service.MenuSearch(in) //标讯搜索 now4 := time.Now().Unix() subscribeList := &bxcore.SearchMap{} subscribeList.Data = service.SubscribeSearch(in.SearchCode, powerCheck) data.SubscribeList = subscribeList now4 := time.Now().Unix() log.Println("菜单搜索", now4-now3) }*/ return data }