wangshan před 2 roky
rodič
revize
95a2301300

+ 6 - 6
jyBXCore/api/bxcore.api

@@ -10,14 +10,14 @@ info (
 type (
 	searchReq {
 		UserType        string `path:"userType,optional"`
-		AppId           string `header:"appId,optional"`
-		UserId          string `header:"userId,optional"`
-		Phone           string `header:"phone,optional"`
-		NewUserId       string `header:"newUserId,optional"`
+		AppId           string `header:"appId"`
+		UserId          string `header:"userId"`
+		Phone           string `header:"phone"`
+		NewUserId       string `header:"newUserId"`
 		EntId           int64  `header:"entId,optional"`
 		EntUserId       int64  `header:"entUserId,optional"`
-		PageNum         int64  `json:"pageNum"`
-		PageSize        int64  `json:"pageSize"`
+		PageNum         int64  `json:"pageNum,optional"`
+		PageSize        int64  `json:"pageSize,optional"`
 		Province        string `json:"province,optional"`
 		City            string `json:"city,optional"`
 		Subtype         string `json:"subtype,optional"`

+ 6 - 6
jyBXCore/api/internal/types/types.go

@@ -3,14 +3,14 @@ package types
 
 type SearchReq struct {
 	UserType        string `path:"userType,optional"`
-	AppId           string `header:"appId,optional"`
-	UserId          string `header:"userId,optional"`
-	Phone           string `header:"phone,optional"`
-	NewUserId       string `header:"newUserId,optional"`
+	AppId           string `header:"appId"`
+	UserId          string `header:"userId"`
+	Phone           string `header:"phone"`
+	NewUserId       string `header:"newUserId"`
 	EntId           int64  `header:"entId,optional"`
 	EntUserId       int64  `header:"entUserId,optional"`
-	PageNum         int64  `json:"pageNum"`
-	PageSize        int64  `json:"pageSize"`
+	PageNum         int64  `json:"pageNum,optional"`
+	PageSize        int64  `json:"pageSize,optional"`
 	Province        string `json:"province,optional"`
 	City            string `json:"city,optional"`
 	Subtype         string `json:"subtype,optional"`

+ 1 - 2
jyBXCore/go.mod

@@ -3,10 +3,9 @@ module jyBXCore
 go 1.16
 
 require (
-	app.yhyue.com/moapp/jybase v0.0.0-20220829123944-ed6966c3fcb3
+	app.yhyue.com/moapp/jybase v0.0.0-20230113085802-8e2760635a23
 	bp.jydev.jianyu360.cn/BaseService/gateway v1.3.4
 	github.com/go-sql-driver/mysql v1.6.0
-	github.com/golang/protobuf v1.5.2
 	github.com/zeromicro/go-zero v1.4.0
 	google.golang.org/grpc v1.49.0
 	google.golang.org/protobuf v1.28.1

+ 4 - 2
jyBXCore/go.sum

@@ -4,8 +4,8 @@ app.yhyue.com/moapp/jybase v0.0.0-20220415064050-37ce64b3e2d4/go.mod h1:qNRA0sHu
 app.yhyue.com/moapp/jybase v0.0.0-20220418104200-46c3fff161c7/go.mod h1:qNRA0sHuYqcLoYoP8irpaWnW9YsXixe6obBIkwaXpD0=
 app.yhyue.com/moapp/jybase v0.0.0-20220420032112-668025915ee4/go.mod h1:qNRA0sHuYqcLoYoP8irpaWnW9YsXixe6obBIkwaXpD0=
 app.yhyue.com/moapp/jybase v0.0.0-20220421060131-a1001013ba46/go.mod h1:qNRA0sHuYqcLoYoP8irpaWnW9YsXixe6obBIkwaXpD0=
-app.yhyue.com/moapp/jybase v0.0.0-20220829123944-ed6966c3fcb3 h1:yKOLZmtjWansB6QvwMbeqXDdm4kq3ALc92aqVzyCgu4=
-app.yhyue.com/moapp/jybase v0.0.0-20220829123944-ed6966c3fcb3/go.mod h1:HelrO6tcD9TcKb/HOP2BLbzppyDz2kpQSFhPMQTUgbQ=
+app.yhyue.com/moapp/jybase v0.0.0-20230113085802-8e2760635a23 h1:ttr6iVvpY7vLmiZlDyRPyFpP+tHWXnzQDbfRtcG3Vw8=
+app.yhyue.com/moapp/jybase v0.0.0-20230113085802-8e2760635a23/go.mod h1:zB47XTeJvpcbtBRYgkQuxOICWNexiZfbUO+7aUf6mNs=
 bp.jydev.jianyu360.cn/BP/jynsq v0.0.0-20220222052708-ebc43af90698/go.mod h1:ojo/AUH9Yr1wzarEjOaNMkj1Cet/9r8IgLyba64Z52E=
 bp.jydev.jianyu360.cn/BaseService/gateway v0.0.0-20220419090715-88ddb32961be/go.mod h1:Yj4oabIGItuMoF0BXYLz2XAnF581kxgXBrvlUtIJrkI=
 bp.jydev.jianyu360.cn/BaseService/gateway v1.3.4 h1:zl5eZrKDBENVVBUiPpzyQQ0/SBdGUmZS3thXycSEO1g=
@@ -270,6 +270,8 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws=
+github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=

+ 61 - 117
jyBXCore/rpc/entity/search.go

@@ -1,152 +1,96 @@
 package entity
 
 import (
-	MC "app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/redis"
+	"encoding/json"
 	"fmt"
 	"github.com/zeromicro/go-zero/core/logx"
 	"jyBXCore/rpc/bxcore"
+	IC "jyBXCore/rpc/init"
+	"jyBXCore/rpc/service"
 	"jyBXCore/rpc/util"
 	"strings"
 )
 
-type KeyWordsSearch struct {
-	AppId           string ` json:"appId,omitempty"`          //剑鱼默认10000
-	UserId          string `json:"userId,omitempty"`          //用户id
-	Phone           string ` json:"phone,omitempty"`          //手机号
-	NewUserId       string `json:"newUserId,omitempty"`       //base_user_id 新用户id
-	EntId           int64  `json:"entId,omitempty"`           //企业id 没有企业 企业id=0
-	EntUserId       int64  `json:"entUserId,omitempty"`       //企业用户id  当前企业下的员工id 没有企业默认0
-	PageNum         int64  `json:"pageNum,omitempty"`         //当前页码
-	PageSize        int64  `json:"pageSize,omitempty"`        //每页数量
-	Province        string `json:"province,omitempty"`        //省份
-	City            string `json:"city,omitempty"`            //城市
-	Subtype         string `json:"subtype,omitempty"`         //信息类型-二级
-	TopType         string `json:"topType,omitempty"`         //信息类型-一级分类
-	PublishTime     string `json:"publishTime,omitempty"`     //发布时间
-	SelectType      string `json:"selectType,omitempty"`      //搜索范围:标题;正文等
-	Price           string `json:"price,omitempty"`           //价格
-	Industry        string `json:"industry,omitempty"`        //行业
-	BuyerClass      string `json:"buyerClass,omitempty"`      //采购单位类型
-	BuyerTel        string `json:"buyerTel,omitempty"`        //采购单位联系方式
-	WinnerTel       string `json:"winnerTel,omitempty"`       //中标单位联系方式
-	FileExists      string `json:"fileExists,omitempty"`      //是否有附件
-	SearchGroup     int64  `json:"searchGroup,omitempty"`     //搜索分组:默认0:全部;1:招标采购公告;2:超前项目
-	SearchMode      int64  `json:"searchMode,omitempty"`      //搜索模式:0:精准搜索;1:模糊搜索
-	WordsMode       int64  `json:"wordsMode,omitempty"`       //搜索关键词模式;默认0:包含所有,1:包含任意
-	KeyWords        string `json:"keyWords,omitempty"`        //关键词:多个空格隔开(主)
-	AdditionalWords string `json:"additionalWords,omitempty"` //关键词:附加关键词(副:五组,每组最多15个字符)
-	ExclusionWords  string `json:"exclusionWords,omitempty"`  //关键词:排除词(副:五组,每组最多15个字符)
-	UserType        string `json:"userType,omitempty"`        //用户状态 fType:免费用户;pType:付费用户;vType:超级订阅用户;mType:大会员用户;eType:商机管理用户
-	Platform        string `json:"platform,omitempty"`        //请求平台
-}
+var (
+	SearchCacheKey   = "searchDataCache_%s_%d"
+	SearchCacheCount = "searchCountCache_%s"
+)
 
-func NewKeyWordsSearch(in *bxcore.SearchReq) *KeyWordsSearch {
-	return &KeyWordsSearch{
-		AppId:           in.AppId,
-		UserId:          in.UserId,
-		Phone:           in.Phone,
-		NewUserId:       in.NewUserId,
-		EntId:           in.EntId,
-		EntUserId:       in.EntUserId,
-		PageNum:         in.PageNum,
-		PageSize:        in.PageSize,
-		Province:        in.Province,
-		City:            in.City,
-		Subtype:         in.Subtype,
-		TopType:         in.TopType,
-		PublishTime:     in.PublishTime,
-		SelectType:      in.SelectType,
-		Price:           in.Price,
-		Industry:        in.Industry,
-		BuyerClass:      in.BuyerClass,
-		BuyerTel:        in.BuyerTel,
-		WinnerTel:       in.WinnerTel,
-		FileExists:      in.FileExists,
-		SearchGroup:     in.SearchGroup,
-		SearchMode:      in.SearchMode,
-		WordsMode:       in.WordsMode,
-		KeyWords:        in.KeyWords,
-		AdditionalWords: in.AdditionalWords,
-		ExclusionWords:  in.ExclusionWords,
-		UserType:        in.UserType,
-		Platform:        in.Platform,
-	}
+type KeyWordsSearch struct{}
+
+func NewKeyWordsSearch() *KeyWordsSearch {
+	return &KeyWordsSearch{}
 }
 
 // IsEmptySearch  是否是空搜索,如果是空搜索查缓存数据
-func (kws *KeyWordsSearch) IsEmptySearch() bool {
+func (kws *KeyWordsSearch) IsEmptySearch(in *bxcore.SearchReq) bool {
 	//有主关键词 或 选择了行业,都不是空搜索
-	if kws.KeyWords != "" || kws.Industry != "" {
+	if in.KeyWords != "" || in.Industry != "" {
 		return false
 	}
 	return true
 }
 
 // GetBidListByCache  查询缓存数据
-func (kws *KeyWordsSearch) GetBidListByCache() (list []*bxcore.SearchList, count int64) {
-	//缓存数据: kws.Platform-平台;kws.PageNum-当前页
-	redisDataKey := fmt.Sprintf(util.SearchCacheKey, kws.Platform, kws.PageNum)
-	sCache, err := redis.GetNewBytes(util.RedisName, redisDataKey)
-	if err == nil {
-		redisCountKey := fmt.Sprintf("PC_SearchCountCache_%s", kws.Platform)
-		count = int64(redis.GetInt(util.RedisName, redisCountKey))
-		if sCache != nil && len(*sCache) > 0 {
-			err = json.Unmarshal(*sCache, &list)
-			if err != nil {
-				//return &bxcore.SearchResp{
-				//	ErrCode: -1,
-				//	ErrMsg:  "缓存数据序列化异常:" + err.Error(),
-				//}, nil
-			}
-		} else {
-			pcstime := IC.C.PCSTime * 60 * 60
-			//缓存数据
-			_in := &bxcore.SearchReq{
-				PageNum:  kws.PageNum,
-				PageSize: kws.PageSize,
-			}
-			count, list = util.SearchCahcheData(_in)
-			limitCount := int64(util.SearchPageSize * util.SearchMaxPageNum)
-			if count > limitCount {
-				count = limitCount
-			}
-			if len(list) > 0 {
-				redis.Put(util.RedisName, redisCountKey, count, pcstime)
-				b, err := json.Marshal(list)
+func (kws *KeyWordsSearch) GetBidListByCache(in *bxcore.SearchReq) (list []*bxcore.SearchList, count int64) {
+	//缓存数据 最大量是500条  十页数据
+	list, count = func(in *bxcore.SearchReq) (list []*bxcore.SearchList, count int64) {
+		//缓存数据: kws.Platform-平台;kws.PageNum-当前页
+		redisDataKey := fmt.Sprintf(SearchCacheKey, in.Platform, in.PageNum)
+		//缓存数据总量 - 当前平台
+		redisCountKey := fmt.Sprintf(SearchCacheCount, in.Platform)
+		sCache, err := redis.GetNewBytes(util.RedisName, redisDataKey)
+		if err == nil {
+			count = int64(redis.GetInt(util.RedisName, redisCountKey))
+			if sCache != nil && len(*sCache) > 0 {
+				err = json.Unmarshal(*sCache, &list)
 				if err == nil {
-					redis.PutBytes(util.RedisName, redisDataKey, &b, pcstime)
-				} else {
-					//return &bxcore.SearchResp{
-					//	ErrCode: -1,
-					//	ErrMsg:  "缓存数据 转化异常:" + err.Error(),
-					//}, nil
+					return
 				}
 			}
 		}
-		//是否收藏
-		util.MakeCollection(kws.UserId, list)
-		res.TotalPage = MC.If(kws.PageNum == 1, (count+int64(util.SearchPageSize)-1)/int64(util.SearchPageSize), res.TotalPage).(int64)
-		res.Count = count
-		res.List = list
-	} else {
-		//return &bxcore.SearchResp{
-		//	ErrCode: -1,
-		//	ErrMsg:  "查询redis缓存异常:" + err.Error(),
-		//}, nil
-	}
+		//无缓存数据 或 缓存数据查询异常
+		//查库>存redis缓存
+		//缓存时间
+		pcstime := IC.C.PCSTime * 60 * 60
+		//缓存数据 默认查询分组 searchGroup = 1 ,
+		//不查超前信息--招标信息类型为拟建和采购意向的信息
+		in.SearchGroup = 1
+		in.TopType = IC.C.DefaultTopTypes[in.SearchGroup]
+		//缓存数据
+		count, list = service.SearchCacheData(in)
+		limitCount := int64(util.SearchPageSize * util.SearchMaxPageNum)
+		if count > limitCount {
+			count = limitCount
+		}
+		if len(list) > 0 {
+			redis.Put(util.RedisName, redisCountKey, count, pcstime)
+			b, err := json.Marshal(list)
+			if err == nil {
+				redis.PutBytes(util.RedisName, redisDataKey, &b, pcstime)
+			} else {
+				logx.Info("默认搜索查询结果保存redis缓存异常")
+			}
+		} else {
+			logx.Info("默认搜索 暂无数据")
+		}
+		return
+	}(in)
+	//是否收藏
+	util.MakeCollection(in.UserId, list)
 	return
 }
 
 //保存历史记录
-func (kws *KeyWordsSearch) SaveKeyWordsToHistory() {
-	if kws.KeyWords != "" {
+func (kws *KeyWordsSearch) SaveKeyWordsToHistory(in *bxcore.SearchReq) {
+	if in.KeyWords != "" {
 		//历史记录
-		history := redis.GetStr("other", "s_"+kws.UserId)
-		keys := util.SearchHistory(history, kws.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_"+kws.UserId, strings.Join(keys, ","), -1); !b {
-				logx.Info("保存搜索记录异常,用户id:", kws.UserId)
+			if b := redis.Put("other", "s_"+in.UserId, strings.Join(keys, ","), -1); !b {
+				logx.Info("保存搜索记录异常,用户id:", in.UserId)
 			}
 		}
 	}

+ 9 - 2
jyBXCore/rpc/etc/bxcore.yaml

@@ -31,5 +31,12 @@ PaySearchLimit:
   WordSize: 7
   PageNum: 1
   PageSize: 20
-KeywordsLimit: 35
-DefaultBidInfoNum: 超过1.8亿
+KeywordsLimit: 35 #主搜索框 关键词长度限制
+DefaultBidInfo: #默认搜索
+  NumMsg: 超过1.8亿 #数据量提示
+  PageNum: 10 #总页数
+  Count: 600 #查询数据量
+DefaultTopTypes:
+  - 拟建,采购意向,招标预告,招标公告,招标结果,招标信用信息
+  - 招标预告,招标公告,招标结果,招标信用信息
+  - 拟建,采购意向

+ 7 - 2
jyBXCore/rpc/internal/config/config.go

@@ -34,8 +34,13 @@ type Config struct {
 		PageNum  int64
 		PageSize int64
 	}
-	KeywordsLimit     int
-	DefaultBidInfoNum string
+	KeywordsLimit  int
+	DefaultBidInfo struct {
+		NumMsg  string
+		PageNum int
+		Count   int
+	}
+	DefaultTopTypes []string
 }
 
 type Db struct {

+ 123 - 126
jyBXCore/rpc/internal/logic/getsearchlistlogic.go

@@ -3,11 +3,8 @@ package logic
 import (
 	MC "app.yhyue.com/moapp/jybase/common"
 	"context"
-	"fmt"
 	"jyBXCore/rpc/entity"
 	IC "jyBXCore/rpc/init"
-	"jyBXCore/rpc/util"
-	"strings"
 	"time"
 
 	"jyBXCore/rpc/internal/svc"
@@ -44,13 +41,13 @@ func (l *GetSearchListLogic) GetSearchList(in *bxcore.SearchReq) (*bxcore.Search
 		Count:          0,
 		List:           []*bxcore.SearchList{},
 		InterceptLimit: int64(MC.IntAllDef(IC.C.KeywordsLimit, 35)),
-		NumberMsg:      IC.C.DefaultBidInfoNum,
+		NumberMsg:      IC.C.DefaultBidInfo.NumMsg,
 	}
 	//初始化搜索对象
-	ks := entity.NewKeyWordsSearch(in)
+	ks := entity.NewKeyWordsSearch()
 	//判断是否是空搜索,如果是空搜索,查缓存数据
-	if ks.IsEmptySearch() {
-		res.List, res.Count = ks.GetBidListByCache()
+	if ks.IsEmptySearch(in) {
+		res.List, res.Count = ks.GetBidListByCache(in)
 		return &bxcore.SearchResp{
 			Data:    res,
 			ErrMsg:  "",
@@ -58,127 +55,127 @@ func (l *GetSearchListLogic) GetSearchList(in *bxcore.SearchReq) (*bxcore.Search
 		}, nil
 	}
 	//更新关键词搜索历史记录
-	go ks.SaveKeyWordsToHistory()
-	//判断搜索是否有查询条件
-	//判断用户身份
+	go ks.SaveKeyWordsToHistory(in)
+	////判断搜索是否有查询条件
+	////判断用户身份
 	t := time.Now()
+	////
+	//if in.SelectType == "" {
+	//	in.SelectType = "title,content"
+	//}
+	//in.Industry = strings.TrimSpace(in.Industry)
+	//userInfo := util.GetVipState(IC.MainMysql, IC.Mgo, in.UserId)
+	////付费用户
+	//if in.UserType != "fType" && !userInfo.IsPayedUser() {
+	//	return &bxcore.SearchResp{
+	//		ErrCode: -1,
+	//		ErrMsg:  "无权限",
+	//	}, nil
+	//}
+	//if in.UserType == "fType" {
+	//	in.BuyerClass = ""
+	//	in.BuyerTel = ""
+	//	in.WinnerTel = ""
+	//	in.ExclusionWords = ""
+	//	in.City = ""
+	//}
+	//in.KeyWords = strings.TrimSpace(in.KeyWords)
+	////搜索范围
+	//queryItems := userInfo.GetQueryItems(in.SelectType, IC.C.BidSearchOldUserLimit)
+	//in.SelectType = strings.Join(queryItems, ",")
+	////b_word, s_word := "", ""
+	//res.IsLimit = 1
+	////以后可能会出现 关键词 C++ 等带+的关键词
+	//if in.KeyWords != "" {
+	//	res.InterceptKeywords, res.InterceptWord, in.KeyWords = util.InterceptSearchKW(in.KeyWords, MC.IntAllDef(IC.C.KeywordsLimit, 35), len(in.Industry) == 0)
+	//}
+	////查询数据
+	//if in.KeyWords != "" || in.Industry != "" {
+	//	//查询数据
+	//	searchLimit := util.IsSearchLimit(strings.Split(in.SelectType, ","))
+	//	//全文检索限制
+	//	if searchLimit {
+	//		res.IsLimit = util.IsLimited(in.UserId, in.UserType != "fType")
+	//		if res.IsLimit == 1 { //没有被限制
+	//			defer util.Limit()
+	//		}
+	//	}
+	//	//无限制
+	//	if res.IsLimit == 1 {
+	//		var count int64
+	//		var list = []*bxcore.SearchList{}
+	//		//付费用户搜索优化
+	//		publishTime := in.PublishTime
+	//		t1 := time.Now()
+	//		if b := util.IsOptimize(IC.C, in); b {
+	//			count, list = util.GetBidSearchData(in)
+	//			count += 1 //避免刚好50条 无法加载下一页数据
+	//		}
+	//		logx.Info("1查询耗时", time.Since(t1))
+	//		t2 := time.Now()
+	//		//分词后 第二页数据请求 先获取全部数据 再切割
+	//		if in.SplitKeywords != "" && strings.Contains(in.SplitKeywords, "+&&&") && in.PageNum == 2 {
+	//			in.KeyWords = strings.ReplaceAll(in.KeyWords, "+&&&", "")
+	//			in.PageNum = 1
+	//		}
+	//		//不够配置条 走原始查询
+	//		if count < IC.C.PaySearchLimit.PageSize {
+	//			in.PublishTime = publishTime
+	//			count, list = util.GetBidSearchData(in)
+	//		}
+	//		logx.Info("2查询耗时:", time.Since(t2))
+	//		res.KeyWords = in.KeyWords
+	//		//二次搜索- 一次搜索结果少于一页数据;关键词长度大于三;第一,二页请求;搜索范围包括title;四个条件
+	//		if len([]rune(in.KeyWords)) > 3 && int(count) < util.SearchPageSize && in.PageNum < 3 && strings.Contains(in.SelectType, "title") {
+	//			if iksk := util.HttpEs(in.KeyWords, "ik_smart", IC.DB.Es.Addr); iksk != "" {
+	//				t3 := time.Now()
+	//				iksk_temp := in.KeyWords
+	//				in.KeyWords = iksk
+	//				in.SelectType = "title"
+	//				//最多查两页数据
+	//				in.PageSize = 2 * in.PageSize
+	//				_, secondList := util.GetBidSearchData(in)
+	//				//数据合并 去重 排序
+	//				list = util.DelRepeatSearchData(list, secondList)
+	//				count = int64(len(list))
+	//				switch {
+	//				case count > util.SearchPageSize:
+	//					count = MC.If(count > int64(util.SearchPageSize*2), int64(util.SearchPageSize*2), count).(int64)
+	//					list = list[:util.SearchPageSize]
+	//					if in.SplitKeywords != "" {
+	//						list = list[util.SearchPageSize:count]
+	//					}
+	//				case count <= util.SearchPageSize:
+	//					list = list[:count]
+	//				}
+	//				var kbool = map[string]bool{}
+	//				var karr = []string{}
+	//				for _, v := range strings.Split(fmt.Sprintf("%s+%s", iksk_temp, iksk), "+") {
+	//					if kbool[v] {
+	//						continue
+	//					}
+	//					karr = append(karr, v)
+	//					kbool[v] = true
+	//				}
+	//				//+&&& 作为二次搜索第二页数据请求的标识(临时处理)
+	//				res.KeyWords = strings.Join(karr, "+") + "+&&&"
+	//				logx.Info("3查询耗时:", time.Since(t3))
+	//			}
+	//		}
+	//		limitCount := MC.If(in.UserType != "fType", int64(util.SearchPageSize*util.SearchMaxPageNum_PAYED), int64(util.SearchPageSize*util.SearchMaxPageNum)).(int64)
+	//		if count > limitCount {
+	//			count = limitCount
+	//		}
+	//		//是否收藏
+	//		//util.MakeCollection(in.UserId, list)
+	//		res.TotalPage = MC.If(in.PageNum == 1, (count+int64(util.SearchPageSize)-1)/int64(util.SearchPageSize), res.TotalPage).(int64)
+	//		res.Count = count
+	//		res.List = list
+	//	}
+	//	logx.Info("关键词 -0- 查询耗时:", time.Since(t).Seconds())
+	//} else if in.Platform == "PC" {
 	//
-	if in.SelectType == "" {
-		in.SelectType = "title,content"
-	}
-	in.Industry = strings.TrimSpace(in.Industry)
-	userInfo := util.GetVipState(IC.MainMysql, IC.Mgo, in.UserId)
-	//付费用户
-	if in.UserType != "fType" && !userInfo.IsPayedUser() {
-		return &bxcore.SearchResp{
-			ErrCode: -1,
-			ErrMsg:  "无权限",
-		}, nil
-	}
-	if in.UserType == "fType" {
-		in.BuyerClass = ""
-		in.BuyerTel = ""
-		in.WinnerTel = ""
-		in.ExclusionWords = ""
-		in.City = ""
-	}
-	in.KeyWords = strings.TrimSpace(in.KeyWords)
-	//搜索范围
-	queryItems := userInfo.GetQueryItems(in.SelectType, IC.C.BidSearchOldUserLimit)
-	in.SelectType = strings.Join(queryItems, ",")
-	//b_word, s_word := "", ""
-	res.IsLimit = 1
-	//以后可能会出现 关键词 C++ 等带+的关键词
-	if in.KeyWords != "" {
-		res.InterceptKeywords, res.InterceptWord, in.KeyWords = util.InterceptSearchKW(in.KeyWords, MC.IntAllDef(IC.C.KeywordsLimit, 35), len(in.Industry) == 0)
-	}
-	//查询数据
-	if in.KeyWords != "" || in.Industry != "" {
-		//查询数据
-		searchLimit := util.IsSearchLimit(strings.Split(in.SelectType, ","))
-		//全文检索限制
-		if searchLimit {
-			res.IsLimit = util.IsLimited(in.UserId, in.UserType != "fType")
-			if res.IsLimit == 1 { //没有被限制
-				defer util.Limit()
-			}
-		}
-		//无限制
-		if res.IsLimit == 1 {
-			var count int64
-			var list = []*bxcore.SearchList{}
-			//付费用户搜索优化
-			publishTime := in.PublishTime
-			t1 := time.Now()
-			if b := util.IsOptimize(IC.C, in); b {
-				count, list = util.GetBidSearchData(in)
-				count += 1 //避免刚好50条 无法加载下一页数据
-			}
-			logx.Info("1查询耗时", time.Since(t1))
-			t2 := time.Now()
-			//分词后 第二页数据请求 先获取全部数据 再切割
-			if in.SplitKeywords != "" && strings.Contains(in.SplitKeywords, "+&&&") && in.PageNum == 2 {
-				in.KeyWords = strings.ReplaceAll(in.KeyWords, "+&&&", "")
-				in.PageNum = 1
-			}
-			//不够配置条 走原始查询
-			if count < IC.C.PaySearchLimit.PageSize {
-				in.PublishTime = publishTime
-				count, list = util.GetBidSearchData(in)
-			}
-			logx.Info("2查询耗时:", time.Since(t2))
-			res.KeyWords = in.KeyWords
-			//二次搜索- 一次搜索结果少于一页数据;关键词长度大于三;第一,二页请求;搜索范围包括title;四个条件
-			if len([]rune(in.KeyWords)) > 3 && int(count) < util.SearchPageSize && in.PageNum < 3 && strings.Contains(in.SelectType, "title") {
-				if iksk := util.HttpEs(in.KeyWords, "ik_smart", IC.DB.Es.Addr); iksk != "" {
-					t3 := time.Now()
-					iksk_temp := in.KeyWords
-					in.KeyWords = iksk
-					in.SelectType = "title"
-					//最多查两页数据
-					in.PageSize = 2 * in.PageSize
-					_, secondList := util.GetBidSearchData(in)
-					//数据合并 去重 排序
-					list = util.DelRepeatSearchData(list, secondList)
-					count = int64(len(list))
-					switch {
-					case count > util.SearchPageSize:
-						count = MC.If(count > int64(util.SearchPageSize*2), int64(util.SearchPageSize*2), count).(int64)
-						list = list[:util.SearchPageSize]
-						if in.SplitKeywords != "" {
-							list = list[util.SearchPageSize:count]
-						}
-					case count <= util.SearchPageSize:
-						list = list[:count]
-					}
-					var kbool = map[string]bool{}
-					var karr = []string{}
-					for _, v := range strings.Split(fmt.Sprintf("%s+%s", iksk_temp, iksk), "+") {
-						if kbool[v] {
-							continue
-						}
-						karr = append(karr, v)
-						kbool[v] = true
-					}
-					//+&&& 作为二次搜索第二页数据请求的标识(临时处理)
-					res.KeyWords = strings.Join(karr, "+") + "+&&&"
-					logx.Info("3查询耗时:", time.Since(t3))
-				}
-			}
-			limitCount := MC.If(in.UserType != "fType", int64(util.SearchPageSize*util.SearchMaxPageNum_PAYED), int64(util.SearchPageSize*util.SearchMaxPageNum)).(int64)
-			if count > limitCount {
-				count = limitCount
-			}
-			//是否收藏
-			//util.MakeCollection(in.UserId, list)
-			res.TotalPage = MC.If(in.PageNum == 1, (count+int64(util.SearchPageSize)-1)/int64(util.SearchPageSize), res.TotalPage).(int64)
-			res.Count = count
-			res.List = list
-		}
-		logx.Info("关键词 -0- 查询耗时:", time.Since(t).Seconds())
-	} else if in.Platform == "PC" {
-
-	}
+	//}
 	logx.Info("关键词 -全部- 查询耗时:", time.Since(t).Seconds())
 	return &bxcore.SearchResp{
 		Data:    res,

+ 2 - 0
jyBXCore/rpc/model/es/es.go

@@ -10,6 +10,8 @@ import (
 const (
 	highlightStr = `"%s": {"fragment_size": %d,"number_of_fragments": 1}`
 	HL           = `"highlight": {"pre_tags": [""],"post_tags": [""],"fields": {%s}}`
+	INDEX        = "bidding"
+	TYPE         = "bidding"
 )
 
 var SR = strings.Replace

+ 289 - 0
jyBXCore/rpc/model/es/search.go

@@ -0,0 +1,289 @@
+package es
+
+import (
+	MC "app.yhyue.com/moapp/jybase/common"
+	elastic "app.yhyue.com/moapp/jybase/esv1"
+	"fmt"
+	"github.com/zeromicro/go-zero/core/logx"
+	"jyBXCore/rpc/bxcore"
+	IC "jyBXCore/rpc/init"
+	"strconv"
+	"strings"
+)
+
+// GetSearchCacheData  查询es bidding 获取数据
+func GetSearchCacheData(industrys, query string) (count int64, list []*bxcore.SearchList) {
+	repl, repc := elastic.GetAllByNgramNew(INDEX, TYPE, query, DefaultFields, bidSearch_sort, bidSearch_field, 0, IC.C.DefaultBidInfo.Count, 0, false)
+	if repl != nil && *repl != nil && len(*repl) > 0 {
+		//util.BidListConvert(industrys, repl)
+		//list = util.SearchListFormart(repl, false)
+	}
+	if repc > 0 {
+		count = repc
+	}
+	return
+}
+
+//
+func GetSearchQuery(in *bxcore.SearchReq, mustquery string) (qstr string) {
+	multi_match := `{"multi_match": {"query": "%s","type": "phrase", "fields": [%s]}}`
+	query := `{"query":{"bool":{"must":[%s],"must_not":[%s]}}}`
+	//query := `{"query": {"function_score": {"query": {"bool": {"must": [%s],"must_not": [%s]}},"field_value_factor": {"field": "dataweight","modifier": "ln1p","missing": 0}}}}`
+
+	query_bool_should := `{"bool":{"should":[%s],"minimum_should_match": 1}}`
+	query_bools_must := `{"bool":{"must":[{"range":{"bidamount":{%s}}}]}},{"bool":{"must":[{"range":{"budget":{%s}}}],"must_not":[{"range":{"bidamount":{"gte":-1}}}]}}`
+	query_bool_must := `{"bool":{"must":[{"terms":{"s_subscopeclass":[%s]}}]}}`
+	query_bool_must_term := `{"bool": {"must": [{ "term": {"isValidFile": %d }}]}}`
+	query_missing := `{"constant_score":{"filter":{"missing":{"field":"%s"}}}}`
+	gte := `"gte": %s`
+	lte := `"lte": %s`
+	musts, must_not := []string{}, []string{}
+	if mustquery != "" {
+		musts = append(musts, mustquery)
+	}
+	//搜索范围是否只有附件
+	//搜索范围只选择附件,是否有附件条件无效;
+	var isFileSearch bool = in.SelectType == "filetext"
+	selectTypeArr := strings.Split(in.SelectType, ",")
+	var findfields string
+	if selectTypeArr == nil || len(selectTypeArr) == 0 {
+		findfields = `"title"`
+	} else {
+		findfields = fmt.Sprintf(`"%s"`, strings.Join(selectTypeArr, "\",\""))
+	}
+	//此时关键词中间有+进行隔离
+	if in.KeyWords != "" {
+		shoulds := []string{}
+		var switchBool = strings.Contains(findfields, "detail") && strings.Contains(findfields, "title") && IC.C.SearchTypeSwitch
+		keyword_multi_match := fmt.Sprintf(multi_match, "%s", findfields)
+		for _, v := range strings.Split(in.KeyWords, "+") {
+			if elastic.ReplaceYH(v) == "" {
+				continue
+			}
+			if len([]rune(elastic.ReplaceYH(v))) == 1 {
+				//单个字  搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail  搜索的时候加上标题
+				if DetailFileORTitle(findfields) {
+					keyword_multi_match = fmt.Sprintf(multi_match, "%s", findfields+`,"title"`)
+				}
+			} else {
+				//标题 全文搜索 搜索类型开关打开 默认搜索全文;(全文包含标题)(单字排除)
+				if switchBool && len([]rune(elastic.ReplaceYH(v))) > 1 {
+					if strings.Contains(findfields, `"title",`) {
+						findfields = strings.Replace(findfields, `"title",`, ``, -1)
+					} else if strings.Contains(findfields, `,"title"`) {
+						findfields = strings.Replace(findfields, `,"title"`, ``, -1)
+					}
+					keyword_multi_match = fmt.Sprintf(multi_match, "%s", findfields)
+				}
+			}
+			shoulds = append(shoulds, fmt.Sprintf(keyword_multi_match, elastic.ReplaceYH(v)))
+		}
+		musts = append(musts, fmt.Sprintf(elastic.NgramMust, strings.Join(shoulds, ",")))
+	}
+	if in.Industry != "" {
+		industrys := strings.Split(in.Industry, ",")
+		musts = append(musts, fmt.Sprintf(query_bool_must, `"`+strings.Join(industrys, `","`)+`"`))
+	}
+	//价格
+	if in.Price != "" && len(strings.Split(in.Price, "-")) > 1 {
+		minprice, maxprice := strings.Split(in.Price, "-")[0], strings.Split(in.Price, "-")[1]
+		if minprice != "" || maxprice != "" {
+			sq := ``
+			if minprice != "" {
+				min, _ := strconv.ParseFloat(minprice, 64)
+				minprice = fmt.Sprintf("%.0f", min*10000)
+				if minprice == "0" {
+					minprice = ""
+				}
+			}
+			if maxprice != "" {
+				max, _ := strconv.ParseFloat(maxprice, 64)
+				maxprice = fmt.Sprintf("%.0f", max*10000)
+				if maxprice == "0" {
+					maxprice = ""
+				}
+			}
+			if minprice != "" {
+				sq += fmt.Sprintf(gte, minprice)
+			}
+			if minprice != "" && maxprice != "" {
+				sq += `,`
+			}
+			if maxprice != "" {
+				sq += fmt.Sprintf(lte, maxprice)
+			}
+			if minprice != "" || maxprice != "" {
+				query_price := fmt.Sprintf(query_bool_should, fmt.Sprintf(query_bools_must, sq, sq))
+				musts = append(musts, query_price)
+			}
+		}
+	}
+	hasBuyerTel := in.BuyerTel
+	if hasBuyerTel != "" {
+		if hasBuyerTel == "y" {
+			must_not = append(must_not, fmt.Sprintf(query_missing, "buyertel"))
+		} else {
+			musts = append(musts, fmt.Sprintf(query_missing, "buyertel"))
+		}
+	}
+	hasWinnerTel := in.WinnerTel
+	if hasWinnerTel != "" {
+		if hasWinnerTel == "y" {
+			must_not = append(must_not, fmt.Sprintf(query_missing, "winnertel"))
+		} else {
+			musts = append(musts, fmt.Sprintf(query_missing, "winnertel"))
+		}
+	}
+	//排除词
+	notkey := in.ExclusionWords
+	if notkey = strings.TrimSpace(notkey); notkey != "" {
+		notkey_multi_match := fmt.Sprintf(multi_match, "%s", findfields)
+		notkey_must_not := []string{}
+		for _, v := range strings.Split(notkey, " ") {
+			v = strings.TrimSpace(v)
+			if v == "" {
+				continue
+			}
+			if len([]rune(elastic.ReplaceYH(v))) == 1 {
+				//单个字 搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail  搜索的时候加上标题
+				if DetailFileORTitle(findfields) {
+					notkey_multi_match = fmt.Sprintf(multi_match, "%s", findfields+`,"title"`)
+				}
+			}
+			notkey_must_not = append(notkey_must_not, fmt.Sprintf(notkey_multi_match, elastic.ReplaceYH(v)))
+		}
+		must_not = append(must_not, fmt.Sprintf(query_bool_should, strings.Join(notkey_must_not, ",")))
+	}
+	//
+	fileExists := in.FileExists
+	if !isFileSearch && fileExists != "" {
+		if fileExists == "1" { //有附件
+			must_not = append(must_not, fmt.Sprintf(query_missing, "isValidFile"))
+			musts = append(musts, fmt.Sprintf(query_bool_must_term, 1))
+		} else if fileExists == "-1" { //无附件
+			musts = append(musts, fmt.Sprintf(query_missing, "isValidFile"))
+		}
+	}
+	qstr = fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(must_not, ","))
+	logx.Info("qstr:", qstr)
+	return
+}
+
+//
+func GetBidSearchQuery(in *bxcore.SearchReq) string {
+	query := ``
+	//省份
+	area := in.Province
+	if area != "" {
+		query += `{"terms":{"area":[`
+		for k, v := range strings.Split(area, ",") {
+			if k > 0 {
+				query += `,`
+			}
+			query += `"` + v + `"`
+		}
+		query += `]}}`
+	}
+	//
+	city := in.City
+	if city != "" {
+		if len(query) > 0 {
+			query += ","
+		}
+		query += `{"terms":{"city":[`
+		for k, v := range strings.Split(city, ",") {
+			if k > 0 {
+				query += `,`
+			}
+			query += `"` + v + `"`
+		}
+		query += `]}}`
+	}
+	if query != "" {
+		query = fmt.Sprintf(query_bool_should, query)
+	}
+	//发布时间
+	publishtime := in.PublishTime
+	if publishtime != "" && len(strings.Split(publishtime, "-")) > 1 {
+		if len(query) > 0 {
+			query += ","
+		}
+		starttime := strings.Split(publishtime, "-")[0]
+		endtime := strings.Split(publishtime, "-")[1]
+		query += `{"range":{"publishtime":{`
+		if starttime != "" {
+			query += `"gte":` + starttime
+		}
+		if starttime != "" && endtime != "" {
+			query += `,`
+		}
+		if endtime != "" {
+			query += `"lt":` + endtime
+		}
+		query += `}}}`
+	}
+	//信息类型-二级
+	subtype := in.Subtype
+	toptype := MC.If(in.TopType != "", strings.Split(in.TopType, ","), []string{}).([]string)
+	alltype := ``
+	//二级分类
+	if subtype != "" {
+		var typeInt = 0
+		alltype += `{"terms":{"subtype":[`
+		for k, v := range strings.Split(subtype, ",") {
+			if ttype := MC.If(topTypeMap[v] != "" && in.TopType == "", topTypeMap[v], "").(string); ttype != "" {
+				toptype = append(toptype, ttype)
+				typeInt += 1
+				continue
+			}
+			if k > typeInt {
+				alltype += `,`
+			}
+			alltype += `"` + v + `"`
+		}
+		alltype += `]}}`
+	}
+	//信息类型  一级分类
+	logx.Info("toptype:", toptype)
+	if len(toptype) > 0 {
+		if alltype != "" {
+			alltype += ","
+		}
+		alltype += `{"terms":{"toptype":[`
+		for k, v := range toptype {
+			if k > 0 {
+				alltype += `,`
+			}
+			alltype += `"` + v + `"`
+		}
+		alltype += `]}}`
+	}
+
+	if alltype != "" {
+		if query != "" {
+			query += ","
+		}
+		query += fmt.Sprintf(query_bool_should, alltype)
+	}
+	//采购单位类型
+	buyerclass := in.BuyerClass
+	if buyerclass != "" {
+		if len(query) > 0 {
+			query += ","
+		}
+		query += `{"terms":{"buyerclass":[`
+		for k, v := range strings.Split(buyerclass, ",") {
+			if k > 0 {
+				query += `,`
+			}
+			query += `"` + v + `"`
+		}
+		query += `]}}`
+	}
+	return query
+}
+
+//包含正文或 附件 不包含标题
+func DetailFileORTitle(findfields string) bool {
+	return (strings.Contains(findfields, `"detail"`) || strings.Contains(findfields, `"filetext"`)) && !strings.Contains(findfields, `"title"`)
+}

+ 9 - 276
jyBXCore/rpc/model/es/searchQuery.go

@@ -1,15 +1,5 @@
 package es
 
-import (
-	MC "app.yhyue.com/moapp/jybase/common"
-	elastic "app.yhyue.com/moapp/jybase/esv1"
-	"fmt"
-	"jyBXCore/rpc/entity"
-	"strconv"
-	"strings"
-	"time"
-)
-
 const (
 	queryByIds        = `{"query":{"bool":{"must":[{"terms":{"_id":[%s]}}]}}}`
 	multiMatch        = `{"multi_match": {"query": %s,"type": "phrase", "fields": [%s]}}`
@@ -23,9 +13,17 @@ const (
 	gte               = `"gte": %s`
 	lte               = `"lte": %s`
 	queryPublishTime  = `{"range":{"publishtime":{%s}}}`
+
+	query_bool_should = `{"bool":{"should":[%s],"minimum_should_match": 1}}`
+	bidSearch_sort    = `{"dataweight":-1,"publishtime":-1}`
+	bidSearch_field_1 = `"_id","title","publishtime","dataweight","toptype","subtype","type","area","city","s_subscopeclass","bidamount","budget","buyerclass","spidercode","site"` //,"filetext"
+	bidSearch_field   = bidSearch_field_1 + `,"bidopentime","winner","buyer","projectname","projectcode","projectinfo"`
+
+	DefaultFields = `"title"` //最新招标信息
 )
 
-var topType = map[string]string{
+//
+var topTypeMap = map[string]string{
 	"招标预告":   "预告",
 	"招标公告":   "招标",
 	"招标结果":   "结果",
@@ -33,268 +31,3 @@ var topType = map[string]string{
 	"拟建项目":   "拟建",
 	"采购意向":   "采购意向",
 }
-
-type SearchQuery struct{}
-
-func (s *SearchQuery) BiddingSearchQuery(bsp *entity.BiddingSearchParams) (qstr string) {
-	if len(bsp.SelectIds) > 0 {
-		return fmt.Sprintf(queryByIds, `"`+strings.Join(bsp.SelectIds, `","`)+`"`)
-	}
-
-	var bools []string
-	var musts = []string{fmt.Sprintf(`{"range":{"comeintime":{"lt":%d}}}`, bsp.ComeInTime)}
-	var mustNot []string
-	//地区
-	var area []string
-	//省份
-	if len(bsp.Province) > 0 {
-		areaquery := `{"terms":{"area":[`
-		for k, v := range bsp.Province {
-			if k > 0 {
-				areaquery += `,`
-			}
-			areaquery += `"` + v + `"`
-		}
-		areaquery += `]}}`
-		area = append(area, areaquery)
-	}
-	//城市
-	if len(bsp.City) > 0 {
-		areaquery := `{"terms":{"city":[`
-		for k, v := range bsp.City {
-			if k > 0 {
-				areaquery += `,`
-			}
-			areaquery += `"` + v + `"`
-		}
-		areaquery += `]}}`
-		area = append(area, areaquery)
-	}
-	if len(area) > 0 {
-		musts = append(musts, fmt.Sprintf(queryBoolShould, strings.Join(area, ",")))
-	}
-	//检索日期
-	//发布时间
-	startTime := ""
-	now := time.Unix(bsp.ComeInTime, 0)
-	endTime := fmt.Sprintf("%d", now.Unix())
-	if strings.Contains(bsp.PublishTime, "_") { //设置检索日期
-		timeQuery := ``
-		startTime = strings.Split(bsp.PublishTime, "_")[0]
-		endTimeTmp := now
-		if etime := strings.Split(bsp.PublishTime, "_")[1]; etime != "" {
-			etTime := time.Unix(MC.Int64All(etime), 0)
-			endTimeTmp = time.Date(etTime.Year(), etTime.Month(), etTime.Day()+1, 0, 0, 0, 0, time.Local)
-		}
-		//结束时间必须小于筛选时间
-		if endTimeTmp.After(now) {
-			endTimeTmp = now
-		}
-		endTime = fmt.Sprintf("%d", endTimeTmp.Unix())
-		if startTime != "" {
-			timeQuery += fmt.Sprintf(gte, startTime)
-		}
-		if startTime != "" && endTime != "" {
-			timeQuery += `,`
-		}
-		if endTime != "" {
-			timeQuery += fmt.Sprintf(lte, endTime)
-		}
-		musts = append(musts, fmt.Sprintf(queryPublishTime, timeQuery))
-	}
-	//信息类型 toptype 一级;subtype 二级;
-	if bsp.Subtype != "" || bsp.Toptype != "" {
-		var subQuery string
-		var topTypes = strings.Split(bsp.Toptype, ",")
-		var subTypes = strings.Split(bsp.Subtype, ",")
-		for _, v := range strings.Split(bsp.Subtype, ",") {
-			if v1, ok := topType[v]; ok {
-				topTypes = append(topTypes, fmt.Sprintf(`"%s"`, v1))
-			} else {
-				subTypes = append(subTypes, fmt.Sprintf(`"%s"`, v))
-			}
-		}
-		if len(subTypes) > 0 && len(topTypes) > 0 {
-			subQuery = fmt.Sprintf(`{"bool": {"should": [{"terms": {"subtype": [%s]}},{"terms": {"toptype": [%s]}}]}}`, strings.Join(subTypes, ","), strings.Join(topTypes, ","))
-		} else if len(subTypes) > 0 {
-			subQuery = fmt.Sprintf(`{"terms":{"subtype":[%s]}}`, strings.Join(subTypes, ","))
-		} else if len(topTypes) > 0 {
-			subQuery = fmt.Sprintf(`{"terms":{"toptype":[%s]}}`, strings.Join(topTypes, ","))
-		}
-		musts = append(musts, subQuery)
-	}
-	//行业
-	if len(bsp.Industry) > 0 {
-		musts = append(musts, fmt.Sprintf(queryBoolMust, "s_subscopeclass", `"`+strings.Join(bsp.Industry, `","`)+`"`))
-	}
-	//采购单位
-	if len(bsp.Buyer) > 0 {
-		musts = append(musts, fmt.Sprintf(queryBoolMust, "buyer", `"`+strings.Join(bsp.Buyer, `","`)+`"`))
-	}
-	//采购单位类型
-	if len(bsp.BuyerClass) > 0 {
-		musts = append(musts, fmt.Sprintf(queryBoolMust, "buyerclass", `"`+strings.Join(bsp.BuyerClass, `","`)+`"`))
-	}
-	//中标单位
-	if len(bsp.Winner) > 0 {
-		musts = append(musts, fmt.Sprintf(queryBoolMust, "s_winner", `"`+strings.Join(bsp.Winner, `","`)+`"`))
-	}
-	//价格区间
-	if bsp.MinPrice != "" || bsp.MaxPrice != "" {
-		_minPrice := ""
-		_maxPrice := ""
-		sq := ``
-		if bsp.MinPrice != "" {
-			min, _ := strconv.ParseFloat(bsp.MinPrice, 64)
-			_minPrice = fmt.Sprintf("%.0f", min*10000)
-			if _minPrice == "0" {
-				_minPrice = ""
-			}
-		}
-		if bsp.MaxPrice != "" {
-			max, _ := strconv.ParseFloat(bsp.MaxPrice, 64)
-			_maxPrice = fmt.Sprintf("%.0f", max*10000)
-			if _maxPrice == "0" {
-				_maxPrice = ""
-			}
-		}
-		if _minPrice != "" {
-			sq += fmt.Sprintf(gte, _minPrice)
-		}
-		if _minPrice != "" && _maxPrice != "" {
-			sq += `,`
-		}
-		if _maxPrice != "" {
-			sq += fmt.Sprintf(lte, _maxPrice)
-		}
-		if _minPrice != "" || _maxPrice != "" {
-			musts = append(musts, fmt.Sprintf(queryBoolShould, fmt.Sprintf(queryPrice, sq, sq)))
-		}
-	}
-	boolsNum := 0
-	selectType := bsp.SelectType
-	//关键词
-	if len(bsp.Keyword) > 0 {
-		boolsNum = 1
-		queryItem := ""
-		if selectType == "" {
-			queryItem = "title"
-		} else if selectType == "all" {
-			queryItem = "detail\", \"title"
-		} else {
-			//搜索开关打开  包含标题和正文  只匹配正文
-			if bsp.SearchTypeSwitch && s.DetailANDTitle(selectType) {
-				if strings.Contains(selectType, "title,") {
-					selectType = strings.Replace(selectType, "title,", "", -1)
-				} else if strings.Contains(selectType, ",title") {
-					selectType = strings.Replace(selectType, ",title", "", -1)
-				}
-			}
-			queryItem = strings.ReplaceAll(selectType, ",", "\",\"")
-		}
-		multiMatchNew := fmt.Sprintf(multiMatch, "%s", "\""+queryItem+"\"")
-		for _, v := range bsp.Keyword {
-			var should []string
-			var mustNot []string
-			if v.Keyword != "" {
-				if strings.Contains(v.Keyword, "+") {
-					for _, vk := range strings.Split(v.Keyword, "+") {
-						//单个字 搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail 搜索的时候加上标题
-						if bsp.ComeInFrom == "supersearchPage" && s.DetailFileORTitle(selectType) && len([]rune(elastic.ReplaceYH(vk))) == 1 {
-							queryItem = strings.ReplaceAll(selectType+",title", ",", "\",\"")
-							shouldKeys := fmt.Sprintf(multiMatch, "\""+vk+"\"", "\""+queryItem+"\"")
-							should = append(should, shouldKeys)
-						} else {
-							should = append(should, fmt.Sprintf(multiMatchNew, "\""+vk+"\""))
-						}
-					}
-				} else if strings.Contains(v.Keyword, " ") {
-					for _, vk := range strings.Split(v.Keyword, " ") {
-						//单个字 搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail 搜索的时候加上标题
-						if bsp.ComeInFrom == "supersearchPage" && s.DetailFileORTitle(selectType) && len([]rune(elastic.ReplaceYH(vk))) == 1 {
-							queryItem = strings.ReplaceAll(selectType+",title", ",", "\",\"")
-							shouldKeys := fmt.Sprintf(multiMatch, "\""+vk+"\"", "\""+queryItem+"\"")
-							should = append(should, shouldKeys)
-						} else {
-							should = append(should, fmt.Sprintf(multiMatchNew, "\""+vk+"\""))
-						}
-					}
-				} else {
-					//单个字 搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail 搜索的时候加上标题
-					if bsp.ComeInFrom == "supersearchPage" && s.DetailFileORTitle(selectType) && len([]rune(elastic.ReplaceYH(v.Keyword))) == 1 {
-						queryItem = strings.ReplaceAll(selectType+",title", ",", "\",\"")
-						shouldKeys := fmt.Sprintf(multiMatch, "\""+v.Keyword+"\"", "\""+queryItem+"\"")
-						should = append(should, shouldKeys)
-					} else {
-						should = append(should, fmt.Sprintf(multiMatchNew, "\""+v.Keyword+"\""))
-					}
-				}
-			}
-
-			//附加词
-			for _, vv := range v.Appended {
-				should = append(should, fmt.Sprintf(multiMatchNew, "\""+vv+"\""))
-			}
-
-			//排除词
-			for _, vv := range v.Exclude {
-				//单个字 搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail 搜索的时候加上标题
-				if bsp.ComeInFrom == "supersearchPage" && s.DetailFileORTitle(selectType) && len([]rune(elastic.ReplaceYH(vv))) == 1 {
-					queryItem = strings.ReplaceAll(selectType+",title", ",", "\",\"")
-					shouldKeys := fmt.Sprintf(multiMatch, "\""+vv+"\"", "\""+queryItem+"\"")
-					should = append(should, shouldKeys)
-				} else {
-					mustNot = append(mustNot, fmt.Sprintf(multiMatchNew, "\""+vv+"\""))
-				}
-			}
-
-			//添加
-			if len(should) > 0 {
-				notStr := ""
-				if len(mustNot) > 0 {
-					notStr = fmt.Sprintf(`,"must_not":[%s]`, strings.Join(mustNot, ","))
-				}
-				bools = append(bools, fmt.Sprintf(queryBoolMustAnd, strings.Join(should, ","), notStr))
-			}
-		}
-	}
-	//采购单位联系方式
-	if bsp.HasBuyerTel != "" {
-		if bsp.HasBuyerTel == "y" {
-			mustNot = append(mustNot, fmt.Sprintf(queryMissing, "buyertel"))
-		} else {
-			musts = append(musts, fmt.Sprintf(queryMissing, "buyertel"))
-		}
-	}
-	//中标企业联系方式
-	if bsp.HasWinnerTel != "" {
-		if bsp.HasWinnerTel == "y" {
-			mustNot = append(mustNot, fmt.Sprintf(queryMissing, "winnertel"))
-		} else {
-			musts = append(musts, fmt.Sprintf(queryMissing, "winnertel"))
-		}
-	}
-	//搜索范围是否只有附件
-	//搜索范围只选择附件,是否有附件条件无效;
-	var isFileSearch = strings.ReplaceAll(selectType, ",", "\",\"") == "filetext"
-	if !isFileSearch && bsp.FileExists != "" {
-		if bsp.FileExists == "1" { //有附件
-			mustNot = append(mustNot, fmt.Sprintf(queryMissing, "isValidFile"))
-			musts = append(musts, fmt.Sprintf(queryBoolMustTerm, 1))
-		} else if bsp.FileExists == "-1" { //无附件
-			musts = append(musts, fmt.Sprintf(queryMissing, "isValidFile"))
-		}
-	}
-	qstr = fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(mustNot, ","), strings.Join(bools, ","), boolsNum)
-	return
-}
-
-// DetailFileORTitle 包含正文或 附件 不包含标题
-func (s *SearchQuery) DetailFileORTitle(findFields string) bool {
-	return (strings.Contains(findFields, "detail") || strings.Contains(findFields, "filetext")) && !strings.Contains(findFields, "title")
-}
-
-// DetailANDTitle 包含正文包含标题
-func (s *SearchQuery) DetailANDTitle(findFields string) bool {
-	return strings.Contains(findFields, "detail") && strings.Contains(findFields, "title")
-}

+ 10 - 0
jyBXCore/rpc/service/search.go

@@ -1 +1,11 @@
 package service
+
+import (
+	"jyBXCore/rpc/bxcore"
+	"jyBXCore/rpc/model/es"
+)
+
+// SearchCacheData  默认查询缓存数据
+func SearchCacheData(in *bxcore.SearchReq) (count int64, list []*bxcore.SearchList) {
+	return es.GetSearchCacheData(in.Industry, es.GetSearchQuery(in, es.GetBidSearchQuery(in)))
+}

+ 26 - 20
jyBXCore/rpc/util/search.go

@@ -24,33 +24,39 @@ import (
 )
 
 var (
-	ClearHtml      = regexp.MustCompile("<[^>]*>")
-	MatchSpace     = regexp.MustCompile("\\s+")
-	filterReg_3    = regexp.MustCompile("(项目|公告|公示)$")
-	filterReg_2    = regexp.MustCompile("^[)\\)>》】\\]}}〕,,;;::'\"“”。.\\??、/+=\\_—*&……\\^%$¥@!!`~·(\\(<《【\\[{{〔]+$")
-	filterReg_1    = regexp.MustCompile("^([0-9]{1,3}|[零一二三四五六七八九十]{1,2}|联系人?|电话|地址|编号|采购|政府采购|成交|更正|招标|中标|变更|结果)$")
-	filterReg      = regexp.MustCompile("^[的人号时元万公告项目地址电话邮编日期联系招标中结果成交项目项目采购采购项目政府采购公告更正公告]+$")
-	PhoneReg       = regexp.MustCompile("^[1][3-9][0-9]{9}$")
-	EmailPattern   = regexp.MustCompile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$")
-	SearchCacheKey = "searchDataCache_%s_%d"
+	ClearHtml    = regexp.MustCompile("<[^>]*>")
+	MatchSpace   = regexp.MustCompile("\\s+")
+	filterReg_3  = regexp.MustCompile("(项目|公告|公示)$")
+	filterReg_2  = regexp.MustCompile("^[)\\)>》】\\]}}〕,,;;::'\"“”。.\\??、/+=\\_—*&……\\^%$¥@!!`~·(\\(<《【\\[{{〔]+$")
+	filterReg_1  = regexp.MustCompile("^([0-9]{1,3}|[零一二三四五六七八九十]{1,2}|联系人?|电话|地址|编号|采购|政府采购|成交|更正|招标|中标|变更|结果)$")
+	filterReg    = regexp.MustCompile("^[的人号时元万公告项目地址电话邮编日期联系招标中结果成交项目项目采购采购项目政府采购公告更正公告]+$")
+	PhoneReg     = regexp.MustCompile("^[1][3-9][0-9]{9}$")
+	EmailPattern = regexp.MustCompile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$")
 )
 
-func SearchHistory(history, searchvalue string) (arrs []string) {
-	if searchvalue != "" {
+// SearchHistory 格式化 关键词搜索历史记录
+func SearchHistory(history, searchValue, additionalWords string) (arrs []string) {
+	if searchValue != "" {
+		var searchKeys = []string{searchValue}
+		if additionalWords != "" {
+			searchKeys = append(searchKeys, strings.Split(additionalWords, ",")...)
+		}
 		arrs = strings.Split(history, ",")
 		//新增历史记录
 		if history == "" {
 			arrs = make([]string, 0)
 		}
-		for k, v := range arrs {
-			if v == strings.TrimSpace(searchvalue) {
-				arrs = append(arrs[:k], arrs[k+1:]...)
-				break
+		for _, sv := range searchKeys {
+			for k, v := range arrs {
+				if v == strings.TrimSpace(sv) {
+					arrs = append(arrs[:k], arrs[k+1:]...)
+					break
+				}
 			}
 		}
-		arrs = append(arrs, searchvalue)
+		arrs = append(arrs, searchValue)
 		if len(arrs) > 10 {
-			arrs = arrs[1:11]
+			arrs = arrs[len(searchKeys) : len(searchKeys)+10]
 		}
 	}
 	return arrs
@@ -210,7 +216,7 @@ func GetBidSearchData(in *bxcore.SearchReq) (count int64, list []*bxcore.SearchL
 		count, repl = biddingSearch.GetAllByNgramWithCount()
 		if repl != nil && *repl != nil && len(*repl) > 0 {
 			BidListConvert(in.Industry, repl)
-			list = searchListFormart(repl, true)
+			list = SearchListFormart(repl, true)
 		}
 		logx.Info("关键词 -1- 查询耗时:", time.Since(t).Seconds())
 		MakeCollection(in.UserId, list)
@@ -595,14 +601,14 @@ func SearchCahcheData(in *bxcore.SearchReq) (count int64, list []*bxcore.SearchL
 		repl := elastic.GetAllByNgram(INDEX, TYPE, qstr, findfields, bidSearch_sort, bidSearch_field, int(in.PageNum), int(in.PageSize), 0, false)
 		if repl != nil && *repl != nil && len(*repl) > 0 {
 			BidListConvert(in.Industry, repl)
-			list = searchListFormart(repl, false)
+			list = SearchListFormart(repl, false)
 		}
 	}
 	return
 }
 
 //格式化数据
-func searchListFormart(repl *[]map[string]interface{}, b bool) (list []*bxcore.SearchList) {
+func SearchListFormart(repl *[]map[string]interface{}, b bool) (list []*bxcore.SearchList) {
 	for _, v := range *repl {
 		var searchList = &bxcore.SearchList{}
 		if b {