Bläddra i källkod

feat:字段限制

wangshan 1 år sedan
förälder
incheckning
b7f0d1ae30
1 ändrade filer med 1138 tillägg och 1128 borttagningar
  1. 1138 1128
      src/jfw/front/searchOptimize.go

+ 1138 - 1128
src/jfw/front/searchOptimize.go

@@ -1,1208 +1,1218 @@
 package front
 
 import (
-    "encoding/json"
-    "fmt"
-    "github.com/gogf/gf/v2/util/gconv"
-    "jy/src/jfw/config"
-    "jy/src/jfw/jyutil"
-    "log"
-    "net/http"
-    "strconv"
-    "strings"
-    "time"
+	"encoding/json"
+	"fmt"
+	"github.com/gogf/gf/v2/util/gconv"
+	"jy/src/jfw/config"
+	"jy/src/jfw/jyutil"
+	"log"
+	"net/http"
+	"strconv"
+	"strings"
+	"time"
 
-    util "app.yhyue.com/moapp/jybase/common"
-    "app.yhyue.com/moapp/jybase/encrypt"
-    elastic "app.yhyue.com/moapp/jybase/es"
-    "app.yhyue.com/moapp/jybase/redis"
-    "app.yhyue.com/moapp/jypkg/common/src/qfw/util/bidsearch"
-    "app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
-    pc "app.yhyue.com/moapp/jypkg/public"
+	util "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/encrypt"
+	elastic "app.yhyue.com/moapp/jybase/es"
+	"app.yhyue.com/moapp/jybase/redis"
+	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/bidsearch"
+	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
+	pc "app.yhyue.com/moapp/jypkg/public"
 )
 
 const (
-    multiMatch              = `{"multi_match": {"query": "%s","type": "phrase", "fields": [%s]}}`
-    query                   = `{"query":{"bool":{"filter":[%s],"must_not":[%s]}}}`
-    queryBoolShould         = `{"bool":{"should":[%s],"minimum_should_match": 1}}`
-    queryBoolMustBoolShould = `{"bool":{"must":[{"range":{"bidamount":{%s}}}]}},{"bool":{"must":[{"range":{"budget":{%s}}}],"must_not":[{"range":{"bidamount":{"gte":-1}}}]}}`
-    queryBoolMust           = `{"bool":{"must":[{"terms":{"s_subscopeclass":[%s]}}]}}`
-    queryBoolMustA          = `{"bool":{"must":[{"terms":{"%s":[%s]}}]}}`
-    queryBoolMustTerm       = `{"bool": {"must": [{ "term": {"isValidFile": %t }}]}}`
-    queryExists             = `{"constant_score":{"filter":{"exists":{"field":"%s"}}}}`
-    gte                     = `"gte": %s`
-    lte                     = `"lte": %s`
-    HighlightStr            = `"%s": {"fragment_size": %d,"number_of_fragments": 1}`
-    HL                      = `"highlight": {"pre_tags": [""],"post_tags": [""],"fields": {%s}}`
-    BidSearchSort           = `{"dataweight":-1,"publishtime":-1}`
-    queryBoolMustTermDomain = `{"bool": {"must": [{ "term": {"bid_field": "%s" }}]}}` // 领域化数据类型
+	multiMatch              = `{"multi_match": {"query": "%s","type": "phrase", "fields": [%s]}}`
+	query                   = `{"query":{"bool":{"filter":[%s],"must_not":[%s]}}}`
+	queryBoolShould         = `{"bool":{"should":[%s],"minimum_should_match": 1}}`
+	queryBoolMustBoolShould = `{"bool":{"must":[{"range":{"bidamount":{%s}}}]}},{"bool":{"must":[{"range":{"budget":{%s}}}],"must_not":[{"range":{"bidamount":{"gte":-1}}}]}}`
+	queryBoolMust           = `{"bool":{"must":[{"terms":{"s_subscopeclass":[%s]}}]}}`
+	queryBoolMustA          = `{"bool":{"must":[{"terms":{"%s":[%s]}}]}}`
+	queryBoolMustTerm       = `{"bool": {"must": [{ "term": {"isValidFile": %t }}]}}`
+	queryExists             = `{"constant_score":{"filter":{"exists":{"field":"%s"}}}}`
+	gte                     = `"gte": %s`
+	lte                     = `"lte": %s`
+	HighlightStr            = `"%s": {"fragment_size": %d,"number_of_fragments": 1}`
+	HL                      = `"highlight": {"pre_tags": [""],"post_tags": [""],"fields": {%s}}`
+	BidSearchSort           = `{"dataweight":-1,"publishtime":-1}`
+	queryBoolMustTermDomain = `{"bool": {"must": [{ "term": {"bid_field": "%s" }}]}}` // 领域化数据类型
 )
 
 var (
-    SR              = strings.Replace
-    DefaultTopTypes = []string{
-        "招标预告,招标公告,招标结果,招标信用信息",
-        "拟建,采购意向",
-    }
-    SearchCacheKey   = "searchDataCache_%d_%s_%s"
-    SearchCacheCount = "searchCountCache_%d_%s_%s"
-    RedisNameNew     = "newother"
+	SR              = strings.Replace
+	DefaultTopTypes = []string{
+		"招标预告,招标公告,招标结果,招标信用信息",
+		"拟建,采购意向",
+	}
+	SearchCacheKey   = "searchDataCache_%d_%s_%s"
+	SearchCacheCount = "searchCountCache_%d_%s_%s"
+	RedisNameNew     = "newother"
 )
 
 type SearchOptimize struct {
-    AppId               string        `json:"appId,omitempty"`               //剑鱼默认10000
-    UserId              string        `json:"userId,omitempty"`              //用户id
-    Phone               string        `json:"phone,omitempty"`               //手机号
-    NewUserId           int64         `json:"newUserId,omitempty"`           //base_user_id 新用户id
-    EntId               int64         `json:"entId,omitempty"`               //企业id 没有企业 企业id=0
-    EntUserId           int64         `json:"entUserId,omitempty"`           //企业用户id  当前企业下的员工id 没有企业默认0
-    PageNum             int           `json:"pageNum,omitempty"`             //当前页码
-    PageSize            int           `json:"pageSize,omitempty"`            //每页数量
-    Province            string        `json:"province,omitempty"`            //省份
-    City                string        `json:"city,omitempty"`                //城市
-    Subtype             string        `json:"subtype,omitempty"`             //信息类型-二级
-    TopType             string        `json:"topTypeMap,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         int           `json:"searchGroup,omitempty"`         //搜索分组:默认0:全部;1:招标采购公告;2:超前项目
-    SearchMode          int           `json:"searchMode,omitempty"`          //搜索模式:0:精准搜索;1:模糊搜索
-    WordsMode           int           `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"`            //请求平台
-    IsPay               bool          `json:"isPay,omitempty"`               //是否是付费用户
-    InterceptKeyWords   string        `json:"interceptKeyWords,omitempty"`   //关键词截取后的关键词;
-    InterceptOtherWords string        `json:"interceptOtherWords,omitempty"` //关键词截取后 后面三个字
-    BidField            string        `json:"bidField,omitempty"`            //领域化数据
-    SearchTypeSwitch    bool          `json:"searchTypeSwitch,omitempty"`    //标题+全文搜索 搜索类型开关打开 默认搜索全文;(全文包含标题)(单字排除)
-    IsOldVip            bool          `json:"isOldVip"`                      //超级订阅老用户 超前项目权限
-    VipStatus           int           `json:"vipStatus"`
-    BigMemberStatus     int           `json:"bigMemberStatus"`
-    EntStatus           int           `json:"entStatus"`
-    HeightKeys          string        `json:"heightKeys"`     //需要高亮的关键词
-    R                   *http.Request `json:"r"`              //http.request
-    District            string        `json:"district"`       //需要高亮的关键词
-    PropertyForm        string        `json:"propertyForm"`   //物业业态
-    ExpireTime          string        `json:"expireTime"`     //到期时间
-    Subinformation      string        `json:"subinformation"` //业务类型
-    Period              string        `json:"period"`         //合同周期
-    Changehand          int           `json:"changehand"`     // 换手率
-    Scale               string        `json:"scale"`          //价格区间
-    Isfile              int           `json:"isfile"`         //有无附件
-    Buyer               string        `json:"buyer"`          //采购单位
-    Winner              string        `json:"winner"`         //中标企业
-    Agency              string        `json:"agency"`         //代理机构
+	AppId               string        `json:"appId,omitempty"`               //剑鱼默认10000
+	UserId              string        `json:"userId,omitempty"`              //用户id
+	Phone               string        `json:"phone,omitempty"`               //手机号
+	NewUserId           int64         `json:"newUserId,omitempty"`           //base_user_id 新用户id
+	EntId               int64         `json:"entId,omitempty"`               //企业id 没有企业 企业id=0
+	EntUserId           int64         `json:"entUserId,omitempty"`           //企业用户id  当前企业下的员工id 没有企业默认0
+	PageNum             int           `json:"pageNum,omitempty"`             //当前页码
+	PageSize            int           `json:"pageSize,omitempty"`            //每页数量
+	Province            string        `json:"province,omitempty"`            //省份
+	City                string        `json:"city,omitempty"`                //城市
+	Subtype             string        `json:"subtype,omitempty"`             //信息类型-二级
+	TopType             string        `json:"topTypeMap,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         int           `json:"searchGroup,omitempty"`         //搜索分组:默认0:全部;1:招标采购公告;2:超前项目
+	SearchMode          int           `json:"searchMode,omitempty"`          //搜索模式:0:精准搜索;1:模糊搜索
+	WordsMode           int           `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"`            //请求平台
+	IsPay               bool          `json:"isPay,omitempty"`               //是否是付费用户
+	InterceptKeyWords   string        `json:"interceptKeyWords,omitempty"`   //关键词截取后的关键词;
+	InterceptOtherWords string        `json:"interceptOtherWords,omitempty"` //关键词截取后 后面三个字
+	BidField            string        `json:"bidField,omitempty"`            //领域化数据
+	SearchTypeSwitch    bool          `json:"searchTypeSwitch,omitempty"`    //标题+全文搜索 搜索类型开关打开 默认搜索全文;(全文包含标题)(单字排除)
+	IsOldVip            bool          `json:"isOldVip"`                      //超级订阅老用户 超前项目权限
+	VipStatus           int           `json:"vipStatus"`
+	BigMemberStatus     int           `json:"bigMemberStatus"`
+	EntStatus           int           `json:"entStatus"`
+	HeightKeys          string        `json:"heightKeys"`     //需要高亮的关键词
+	R                   *http.Request `json:"r"`              //http.request
+	District            string        `json:"district"`       //需要高亮的关键词
+	PropertyForm        string        `json:"propertyForm"`   //物业业态
+	ExpireTime          string        `json:"expireTime"`     //到期时间
+	Subinformation      string        `json:"subinformation"` //业务类型
+	Period              string        `json:"period"`         //合同周期
+	Changehand          int           `json:"changehand"`     // 换手率
+	Scale               string        `json:"scale"`          //价格区间
+	Isfile              int           `json:"isfile"`         //有无附件
+	Buyer               string        `json:"buyer"`          //采购单位
+	Winner              string        `json:"winner"`         //中标企业
+	Agency              string        `json:"agency"`         //代理机构
 
 }
 
 // NewSearchOptimize  初始化
 func NewSearchOptimize(userId, phone, province, city, district, subtype, topType, publishTime, selectType, price, industry, buyerClass, buyerTel, winnerTel, fileExists, keyWords, additionalWords, exclusionWords, platform, territorialization, expireTime, propertyForm, subinformation string,
-    pageNum, pageSize, searchGroup, searchMode, wordsMode int, period, scale string, changehand, isfile int,
-    userInfo jy.VipState, searchTypeSwitch bool, r *http.Request, accountId, entAccountId, entId, entUserId int64, buyer, winner, agency string) *SearchOptimize {
-    IsPay := userInfo.IsPayedUser()
-    if territorialization == "BIProperty" {
-        res := config.Middleground.ResourceCenter.Haspowers(accountId, entAccountId, entId, entUserId)
-        for _, pCode := range res.Powers {
-            if pCode == "bi_yx_wyzb" {
-                IsPay = true
-            }
-        }
-    }
-    var so = &SearchOptimize{
-        AppId:            "10000",
-        UserId:           userId,
-        Phone:            phone,
-        PageNum:          pageNum,
-        PageSize:         pageSize,
-        Province:         province,
-        City:             city,
-        Subtype:          subtype,
-        TopType:          topType,
-        PublishTime:      publishTime,
-        SelectType:       selectType,
-        Price:            price,
-        Industry:         industry,
-        BuyerClass:       buyerClass,
-        BuyerTel:         buyerTel,
-        WinnerTel:        winnerTel,
-        FileExists:       fileExists,
-        SearchGroup:      searchGroup,
-        SearchMode:       searchMode,
-        WordsMode:        wordsMode,
-        KeyWords:         keyWords,
-        AdditionalWords:  additionalWords,
-        ExclusionWords:   exclusionWords,
-        Platform:         platform,
-        IsPay:            IsPay,
-        BidField:         territorialization,
-        SearchTypeSwitch: searchTypeSwitch,
-        IsOldVip:         userInfo.VipState > 0 && userInfo.RegisterData < util.Int64All(config.Sysconfig["contextOldVipLimit"]),
-        VipStatus:        userInfo.VipState,
-        BigMemberStatus:  userInfo.BigMember,
-        EntStatus:        userInfo.EntMember,
-        R:                r,
-        District:         district,
-        PropertyForm:     propertyForm,
-        ExpireTime:       expireTime,
-        Subinformation:   subinformation,
-        Period:           period,
-        Changehand:       changehand,
-        Scale:            scale,
-        Isfile:           isfile,
-        Buyer:            buyer,
-        Winner:           winner,
-        Agency:           agency,
-    }
-    so.SearchParamsHandle()
-    return so
+	pageNum, pageSize, searchGroup, searchMode, wordsMode int, period, scale string, changehand, isfile int,
+	userInfo jy.VipState, searchTypeSwitch bool, r *http.Request, accountId, entAccountId, entId, entUserId int64, buyer, winner, agency string) *SearchOptimize {
+	IsPay := userInfo.IsPayedUser()
+	if territorialization == "BIProperty" {
+		res := config.Middleground.ResourceCenter.Haspowers(accountId, entAccountId, entId, entUserId)
+		for _, pCode := range res.Powers {
+			if pCode == "bi_yx_wyzb" {
+				IsPay = true
+			}
+		}
+	}
+	var so = &SearchOptimize{
+		AppId:            "10000",
+		UserId:           userId,
+		Phone:            phone,
+		PageNum:          pageNum,
+		PageSize:         pageSize,
+		Province:         province,
+		City:             city,
+		Subtype:          subtype,
+		TopType:          topType,
+		PublishTime:      publishTime,
+		SelectType:       selectType,
+		Price:            price,
+		Industry:         industry,
+		BuyerClass:       buyerClass,
+		BuyerTel:         buyerTel,
+		WinnerTel:        winnerTel,
+		FileExists:       fileExists,
+		SearchGroup:      searchGroup,
+		SearchMode:       searchMode,
+		WordsMode:        wordsMode,
+		KeyWords:         keyWords,
+		AdditionalWords:  additionalWords,
+		ExclusionWords:   exclusionWords,
+		Platform:         platform,
+		IsPay:            IsPay,
+		BidField:         territorialization,
+		SearchTypeSwitch: searchTypeSwitch,
+		IsOldVip:         userInfo.VipState > 0 && userInfo.RegisterData < util.Int64All(config.Sysconfig["contextOldVipLimit"]),
+		VipStatus:        userInfo.VipState,
+		BigMemberStatus:  userInfo.BigMember,
+		EntStatus:        userInfo.EntMember,
+		R:                r,
+		District:         district,
+		PropertyForm:     propertyForm,
+		ExpireTime:       expireTime,
+		Subinformation:   subinformation,
+		Period:           period,
+		Changehand:       changehand,
+		Scale:            scale,
+		Isfile:           isfile,
+		Buyer:            buyer,
+		Winner:           winner,
+		Agency:           agency,
+	}
+	so.SearchParamsHandle()
+	return so
 }
 
 // DefaultSearchParamsAuto 缓存查询条件初始化
 func (so *SearchOptimize) DefaultSearchParamsAuto() {
-    so.TopType = ""
-    so.City = ""
-    so.Industry = ""
-    so.FileExists = ""
-    so.WinnerTel = ""
-    so.BuyerTel = ""
-    so.BuyerClass = ""
-    so.Price = ""
-    so.SelectType = "title"
-    so.Province = ""
-    so.KeyWords = ""
-    so.AdditionalWords = ""
-    so.ExclusionWords = ""
+	so.TopType = ""
+	so.City = ""
+	so.Industry = ""
+	so.FileExists = ""
+	so.WinnerTel = ""
+	so.BuyerTel = ""
+	so.BuyerClass = ""
+	so.Price = ""
+	so.SelectType = "title"
+	so.Province = ""
+	so.KeyWords = ""
+	so.AdditionalWords = ""
+	so.ExclusionWords = ""
 }
 
 // SearchParamsHandle 搜索条件 处理
 func (so *SearchOptimize) SearchParamsHandle() {
-    // so.SearchGroup 搜索分组 搜索分组:默认0:全部;1:招标采购公告;2:超前项目
-    if so.SearchGroup < 0 || so.SearchGroup > 2 {
-        so.SearchGroup = 1
-    }
-    //信息类型
-    if so.Subtype == "" && so.TopType == "" && so.BidField != "BIProperty" {
-        // 所有用户都可以搜索,判断是否能使用超前项目  老版超级订阅、大会员、商机管理有权限
-        if so.SearchGroup > 0 && len(DefaultTopTypes) >= so.SearchGroup {
-            so.Subtype = DefaultTopTypes[so.SearchGroup-1]
-        }
-    }
-    // so.SearchMode 搜索模式 搜索模式:0:精准搜索;1:模糊搜索
-    // 精准搜索:不分词,完全匹配;(中间带空格的关键词组自动分词)
-    // 模糊搜索:对用户输入的单个关键词进行分词处理,但必须都存在;
-    if so.SearchMode < 0 {
-        so.SearchMode = 0
-    }
-    // so.WordsMode 搜索关键词模式;默认0:包含所有,1:包含任意
-    if so.WordsMode < 0 {
-        so.WordsMode = 0
-    }
-    //查询时间publishTime
-    if so.PublishTime == "" {
-        //so.UserId == ""||免费用户最新1年 未登录用户默认最近一年的数据
-        so.PublishTime = fmt.Sprintf("%d_%d", time.Now().AddDate(-1, 0, 0).Unix(), time.Now().Unix())
-        //付费用户最新5年
-        if so.IsPay {
-            so.PublishTime = fmt.Sprintf("%d_%d", time.Now().AddDate(-5, 0, 0).Unix(), time.Now().Unix())
-        }
-    }
-    //默认每页数据量
-    if so.PageSize <= 0 {
-        so.PageSize = 50
-    }
-    //第一页
-    if so.PageNum <= 0 {
-        so.PageNum = 1
-    }
-    userCount := util.If(so.IsPay, bidsearch.SearchMaxPageCount_PAYED, bidsearch.SearchMaxPageCount_PC).(int)
-    if so.PageNum > userCount/so.PageSize {
-        so.PageNum = -1
-        so.PageSize = -1
-    }
-    //行业格式化
-    if so.Industry != "" {
-        so.Industry = strings.TrimSpace(so.Industry)
-    }
-    //默认搜索范围
-    if so.SelectType == "" {
-        so.SelectType = "title,detail"
-    }
-    //免费用户:高级筛选 采购单位类型、采购单位联系方式、中标企业联系方式、排除词、城市
-    if !so.IsPay {
-        so.BuyerClass = ""
-        so.BuyerTel = ""
-        so.WinnerTel = ""
-        so.ExclusionWords = ""
-        so.City = ""
-        //so.SearchGroup = util.If(so.SearchGroup > 1, 1, so.SearchGroup).(int) //搜索分组:默认0:全部;1:招标采购公告;2:超前项目
-        so.ExclusionWords = "" //排除词
-    }
-    //判断是否有关键词
-    if so.KeyWords != "" {
-        //关键词处理
-        so.KeyWords = strings.TrimSpace(so.KeyWords)
-    }
-    //附加词 每组附加词不能超过15个字符
-    if so.AdditionalWords != "" {
-        var additionalWords []string
-        for _, ak := range strings.Split(so.AdditionalWords, ",") {
-            if len([]rune(ak)) > 15 {
-                additionalWords = append(additionalWords, string([]rune(ak)[:15]))
-            } else {
-                additionalWords = append(additionalWords, ak)
-            }
-        }
-        so.AdditionalWords = strings.Join(additionalWords, ",")
-    }
-    //合并 关键词 & 附加词
-    so.HeightKeys = so.GetSearchKeyWordsQueryStr()
-    //排除词  每组排除词不能超过15个字符
-    if so.ExclusionWords != "" {
-        var exclusionWords []string
-        for _, ak := range strings.Split(so.ExclusionWords, ",") {
-            if len([]rune(ak)) > 15 {
-                exclusionWords = append(exclusionWords, string([]rune(ak)[:15]))
-            } else {
-                exclusionWords = append(exclusionWords, ak)
-            }
-        }
-        so.ExclusionWords = strings.Join(exclusionWords, " ")
-    }
+	// so.SearchGroup 搜索分组 搜索分组:默认0:全部;1:招标采购公告;2:超前项目
+	if so.SearchGroup < 0 || so.SearchGroup > 2 {
+		so.SearchGroup = 1
+	}
+	//信息类型
+	if so.Subtype == "" && so.TopType == "" && so.BidField != "BIProperty" {
+		// 所有用户都可以搜索,判断是否能使用超前项目  老版超级订阅、大会员、商机管理有权限
+		if so.SearchGroup > 0 && len(DefaultTopTypes) >= so.SearchGroup {
+			so.Subtype = DefaultTopTypes[so.SearchGroup-1]
+		}
+	}
+	// so.SearchMode 搜索模式 搜索模式:0:精准搜索;1:模糊搜索
+	// 精准搜索:不分词,完全匹配;(中间带空格的关键词组自动分词)
+	// 模糊搜索:对用户输入的单个关键词进行分词处理,但必须都存在;
+	if so.SearchMode < 0 {
+		so.SearchMode = 0
+	}
+	// so.WordsMode 搜索关键词模式;默认0:包含所有,1:包含任意
+	if so.WordsMode < 0 {
+		so.WordsMode = 0
+	}
+	//查询时间publishTime
+	if so.PublishTime == "" {
+		//so.UserId == ""||免费用户最新1年 未登录用户默认最近一年的数据
+		so.PublishTime = fmt.Sprintf("%d_%d", time.Now().AddDate(-1, 0, 0).Unix(), time.Now().Unix())
+		//付费用户最新5年
+		if so.IsPay {
+			so.PublishTime = fmt.Sprintf("%d_%d", time.Now().AddDate(-5, 0, 0).Unix(), time.Now().Unix())
+		}
+	}
+	//默认每页数据量
+	if so.PageSize <= 0 {
+		so.PageSize = 50
+	}
+	//第一页
+	if so.PageNum <= 0 {
+		so.PageNum = 1
+	}
+	userCount := util.If(so.IsPay, bidsearch.SearchMaxPageCount_PAYED, bidsearch.SearchMaxPageCount_PC).(int)
+	if so.PageNum > userCount/so.PageSize {
+		so.PageNum = -1
+		so.PageSize = -1
+	}
+	//行业格式化
+	if so.Industry != "" {
+		so.Industry = strings.TrimSpace(so.Industry)
+	}
+	//默认搜索范围
+	if so.SelectType == "" {
+		so.SelectType = "title,detail"
+	}
+	//免费用户:高级筛选 采购单位类型、采购单位联系方式、中标企业联系方式、排除词、城市
+	if !so.IsPay {
+		so.BuyerClass = ""
+		so.BuyerTel = ""
+		so.WinnerTel = ""
+		so.ExclusionWords = ""
+		so.City = ""
+		//so.SearchGroup = util.If(so.SearchGroup > 1, 1, so.SearchGroup).(int) //搜索分组:默认0:全部;1:招标采购公告;2:超前项目
+		so.ExclusionWords = "" //排除词
+	}
+	//判断是否有关键词
+	if so.KeyWords != "" {
+		//关键词处理
+		so.KeyWords = strings.TrimSpace(so.KeyWords)
+	}
+	//附加词 每组附加词不能超过15个字符
+	if so.AdditionalWords != "" {
+		var additionalWords []string
+		for _, ak := range strings.Split(so.AdditionalWords, ",") {
+			if len([]rune(ak)) > 15 {
+				additionalWords = append(additionalWords, string([]rune(ak)[:15]))
+			} else {
+				additionalWords = append(additionalWords, ak)
+			}
+		}
+		so.AdditionalWords = strings.Join(additionalWords, ",")
+	}
+	//合并 关键词 & 附加词
+	so.HeightKeys = so.GetSearchKeyWordsQueryStr()
+	//排除词  每组排除词不能超过15个字符
+	if so.ExclusionWords != "" {
+		var exclusionWords []string
+		for _, ak := range strings.Split(so.ExclusionWords, ",") {
+			if len([]rune(ak)) > 15 {
+				exclusionWords = append(exclusionWords, string([]rune(ak)[:15]))
+			} else {
+				exclusionWords = append(exclusionWords, ak)
+			}
+		}
+		so.ExclusionWords = strings.Join(exclusionWords, " ")
+	}
 }
 
 // GetSearchKeyWordsQueryStr 关键词处理 获取关键词查询条件
 func (so *SearchOptimize) GetSearchKeyWordsQueryStr() string {
-    // in.SearchMode 搜索模式:0:精准搜索;1:模糊搜索
-    // 精准搜索:不分词,完全匹配;(中间带空格的关键词组自动分词)
-    // 模糊搜索:对用户输入的单个关键词进行分词处理,但必须都存在;
-    var (
-        searchWords []string
-    )
-    //主关键词词组
-    if so.KeyWords != "" {
-        if so.SearchMode == 1 {
-            if ikWords := jy.HttpEs(so.KeyWords, "ik_smart", pc.DbConf.Elasticsearch.Main.Address); ikWords != "" {
-                so.KeyWords = jy.KeywordsProcessing(strings.ReplaceAll(ikWords, "+", " "), " ")
-            }
-        }
-        searchWords = append(searchWords, so.KeyWords)
-    }
-    //多组附加词,每组间,号隔开。每组内如果关键词中间有空格,自动分词
-    if so.AdditionalWords != "" {
-        if so.SearchMode == 1 {
-            var (
-                addWords []string
-            )
-            for _, awv := range strings.Split(so.AdditionalWords, ",") {
-                if ikWords := jy.HttpEs(awv, "ik_smart", pc.DbConf.Elasticsearch.Main.Address); ikWords != "" {
-                    addWords = append(addWords, jy.KeywordsProcessing(strings.ReplaceAll(ikWords, "+", " "), " "))
-                }
-            }
-            if len(addWords) > 0 {
-                so.AdditionalWords = strings.Join(addWords, ",")
-            }
-        }
-        searchWords = append(searchWords, strings.Split(so.AdditionalWords, ",")...)
-    }
-    return strings.Join(searchWords, " ")
+	// in.SearchMode 搜索模式:0:精准搜索;1:模糊搜索
+	// 精准搜索:不分词,完全匹配;(中间带空格的关键词组自动分词)
+	// 模糊搜索:对用户输入的单个关键词进行分词处理,但必须都存在;
+	var (
+		searchWords []string
+	)
+	//主关键词词组
+	if so.KeyWords != "" {
+		if so.SearchMode == 1 {
+			if ikWords := jy.HttpEs(so.KeyWords, "ik_smart", pc.DbConf.Elasticsearch.Main.Address); ikWords != "" {
+				so.KeyWords = jy.KeywordsProcessing(strings.ReplaceAll(ikWords, "+", " "), " ")
+			}
+		}
+		searchWords = append(searchWords, so.KeyWords)
+	}
+	//多组附加词,每组间,号隔开。每组内如果关键词中间有空格,自动分词
+	if so.AdditionalWords != "" {
+		if so.SearchMode == 1 {
+			var (
+				addWords []string
+			)
+			for _, awv := range strings.Split(so.AdditionalWords, ",") {
+				if ikWords := jy.HttpEs(awv, "ik_smart", pc.DbConf.Elasticsearch.Main.Address); ikWords != "" {
+					addWords = append(addWords, jy.KeywordsProcessing(strings.ReplaceAll(ikWords, "+", " "), " "))
+				}
+			}
+			if len(addWords) > 0 {
+				so.AdditionalWords = strings.Join(addWords, ",")
+			}
+		}
+		searchWords = append(searchWords, strings.Split(so.AdditionalWords, ",")...)
+	}
+	return strings.Join(searchWords, " ")
 }
 
 // GetBidSearchList 搜索 查询
 func (so *SearchOptimize) GetBidSearchList(isCache bool) (count, total int64, list []*map[string]interface{}) {
-    var start = (so.PageNum - 1) * so.PageSize
-    if start >= 0 {
-        t := time.Now()
-        fields := util.If(so.IsPay, BidSearchFieldOfVip, BidSearchFieldBase).(string)
-        esIndex := util.If(so.UserId == "", INDEXOther, INDEX).(string)
-        esType := util.If(so.UserId == "", TYPEOther, TYPE).(string)
-        Fields := ""
-        switch so.BidField {
-        case "BIProperty":
-            Fields = BidSearchFieldProperty
-        case "":
-            Fields = fields
-        default:
-            Fields = BidSearchDomainField
-        }
-        biddingSearch := SearchByES{
-            Index:      esIndex,
-            IType:      esType,
-            Query:      so.GetSearchQuery(so.GetBidSearchQuery()),
-            FindFields: util.If(isCache, "title", "detail").(string),
-            Order:      BidSearchSort,
-            Fields:     Fields, //BidField ===医疗领域化数据
-            Start:      util.If(isCache, 0, start).(int),
-            Limit:      util.If(isCache, util.If(so.IsPay, bidsearch.SearchMaxPageCount_PAYED, bidsearch.SearchMaxPageCount_PC).(int), so.PageSize).(int), //缓存数据: 付费或未登录用户一次性5000条,100页数据;免费用户一次性500条,10页数据;实时数据:每页50条数据请求
-            Count:      util.If(strings.Contains(so.SelectType, "detail"), 115, 0).(int),                                                                  //高亮正文数量
-            HighLight:  util.If(strings.Contains(so.SelectType, "detail"), true, false).(bool),                                                            //是否高亮正文
-            State: func(userId string, isPay bool) (state int) {
-                state = 1
-                if userId != "" {
-                    state = 2
-                    if isPay {
-                        state = 3
-                    }
-                }
-                return
-            }(so.UserId, so.IsPay),
-        }
-        var repl *[]map[string]interface{}
-        total, repl = biddingSearch.GetAllByNgramWithCount()
-        if repl != nil && *repl != nil && len(*repl) > 0 {
-            //格式化查询结果
-            list = SearchListFormat(so.Industry, so.Subinformation, so.PropertyForm, *repl, strings.Contains(so.SelectType, "detail"), so.BidField)
-            count = util.If(so.IsPay, int64(bidsearch.SearchMaxPageCount_PAYED), int64(bidsearch.SearchMaxPageCount_PC)).(int64)
-            //数据如果>最大数据结果量 total==count,否则count = 付费:5000;免费:500;
-            count = util.If(count > total, total, count).(int64)
-        } else {
-            log.Println("查询数据异常")
-        }
-        //保存搜索日志
-        so.SaveSearchLogs(count)
-        log.Println("关键词 -1- 查询耗时:", time.Since(t).Seconds())
-    }
-    return
+	var start = (so.PageNum - 1) * so.PageSize
+	if start >= 0 {
+		t := time.Now()
+		fields := util.If(so.IsPay, BidSearchFieldOfVip, BidSearchFieldBase).(string)
+		esIndex := util.If(so.UserId == "", INDEXOther, INDEX).(string)
+		esType := util.If(so.UserId == "", TYPEOther, TYPE).(string)
+		Fields := ""
+		switch so.BidField {
+		case "BIProperty":
+			Fields = BidSearchFieldProperty
+		case "":
+			Fields = fields
+		default:
+			Fields = BidSearchDomainField
+		}
+		biddingSearch := SearchByES{
+			Index:      esIndex,
+			IType:      esType,
+			Query:      so.GetSearchQuery(so.GetBidSearchQuery()),
+			FindFields: util.If(isCache, "title", "detail").(string),
+			Order:      BidSearchSort,
+			Fields:     Fields, //BidField ===医疗领域化数据
+			Start:      util.If(isCache, 0, start).(int),
+			Limit:      util.If(isCache, util.If(so.IsPay, bidsearch.SearchMaxPageCount_PAYED, bidsearch.SearchMaxPageCount_PC).(int), so.PageSize).(int), //缓存数据: 付费或未登录用户一次性5000条,100页数据;免费用户一次性500条,10页数据;实时数据:每页50条数据请求
+			Count:      util.If(strings.Contains(so.SelectType, "detail"), 115, 0).(int),                                                                  //高亮正文数量
+			HighLight:  util.If(strings.Contains(so.SelectType, "detail"), true, false).(bool),                                                            //是否高亮正文
+			State: func(userId string, isPay bool) (state int) {
+				state = 1
+				if userId != "" {
+					state = 2
+					if isPay {
+						state = 3
+					}
+				}
+				return
+			}(so.UserId, so.IsPay),
+		}
+		var repl *[]map[string]interface{}
+		total, repl = biddingSearch.GetAllByNgramWithCount()
+		if repl != nil && *repl != nil && len(*repl) > 0 {
+			//格式化查询结果
+			list = SearchListFormat(so.Industry, so.Subinformation, so.PropertyForm, *repl, strings.Contains(so.SelectType, "detail"), so.BidField)
+			count = util.If(so.IsPay, int64(bidsearch.SearchMaxPageCount_PAYED), int64(bidsearch.SearchMaxPageCount_PC)).(int64)
+			//数据如果>最大数据结果量 total==count,否则count = 付费:5000;免费:500;
+			count = util.If(count > total, total, count).(int64)
+		} else {
+			log.Println("查询数据异常")
+		}
+		//保存搜索日志
+		so.SaveSearchLogs(count)
+		log.Println("关键词 -1- 查询耗时:", time.Since(t).Seconds())
+	}
+	return
 }
 
 // SaveSearchLogs 搜索日志
 func (so *SearchOptimize) SaveSearchLogs(count int64) {
-    data := map[string]interface{}{
-        "ip":                util.GetIp(so.R),
-        "count":             count,
-        "s_userid":          so.UserId,
-        "platform":          "pc",
-        "source":            "超级搜索",
-        "createtime":        time.Now().Unix(),
-        "userAgent":         so.R.Header.Get("User-Agent"),
-        "pagenum":           so.PageNum,
-        "pagesize":          so.PageSize,
-        "search_area":       so.Province,
-        "search_city":       so.City,
-        "search_subType":    so.Subtype,
-        "search_topType":    so.TopType,
-        "search_selectType": so.SelectType,
-        "search_price":      so.Price,
-        "search_industry":   so.Industry,
-        "search_buyerClass": so.BuyerClass,
-        "search_buyerTel":   so.BuyerTel,
-        "search_winnerTel":  so.WinnerTel,
-        "fileExists":        so.FileExists,
-        "searchGroup": func(searchGroup int) string {
-            switch searchGroup {
-            case 1:
-                return "招标采购公告"
-            case 2:
-                return "超前项目"
-            }
-            return ""
-        }(so.SearchGroup),                                                 //搜索分组:默认0:全部;1:招标采购公告;2:超前项目
-        "searchMode":         util.If(so.SearchMode == 1, "模糊搜索", "精准搜索"), //搜索模式:0:精准搜索;1:模糊搜索
-        "wordsMode":          util.If(so.WordsMode == 1, "包含任意", "包含所有"),  //搜索关键词模式;默认0:包含所有,1:包含任意
-        "search_word":        so.KeyWords,
-        "additionalWords":    so.AdditionalWords,
-        "exclusionWords":     so.ExclusionWords,
-        "search_publishtime": so.PublishTime,
-        "bid_field":          util.If(bidField != "", bidField, nil),
-    }
-    go pc.Mgo_Log.Save("jy_search_log", data)
+	data := map[string]interface{}{
+		"ip":                util.GetIp(so.R),
+		"count":             count,
+		"s_userid":          so.UserId,
+		"platform":          "pc",
+		"source":            "超级搜索",
+		"createtime":        time.Now().Unix(),
+		"userAgent":         so.R.Header.Get("User-Agent"),
+		"pagenum":           so.PageNum,
+		"pagesize":          so.PageSize,
+		"search_area":       so.Province,
+		"search_city":       so.City,
+		"search_subType":    so.Subtype,
+		"search_topType":    so.TopType,
+		"search_selectType": so.SelectType,
+		"search_price":      so.Price,
+		"search_industry":   so.Industry,
+		"search_buyerClass": so.BuyerClass,
+		"search_buyerTel":   so.BuyerTel,
+		"search_winnerTel":  so.WinnerTel,
+		"fileExists":        so.FileExists,
+		"searchGroup": func(searchGroup int) string {
+			switch searchGroup {
+			case 1:
+				return "招标采购公告"
+			case 2:
+				return "超前项目"
+			}
+			return ""
+		}(so.SearchGroup), //搜索分组:默认0:全部;1:招标采购公告;2:超前项目
+		"searchMode":         util.If(so.SearchMode == 1, "模糊搜索", "精准搜索"), //搜索模式:0:精准搜索;1:模糊搜索
+		"wordsMode":          util.If(so.WordsMode == 1, "包含任意", "包含所有"),  //搜索关键词模式;默认0:包含所有,1:包含任意
+		"search_word":        so.KeyWords,
+		"additionalWords":    so.AdditionalWords,
+		"exclusionWords":     so.ExclusionWords,
+		"search_publishtime": so.PublishTime,
+		"bid_field":          util.If(bidField != "", bidField, nil),
+	}
+	go pc.Mgo_Log.Save("jy_search_log", data)
 }
 
 // GetSearchQuery  整理关键词等查询条件
 func (so *SearchOptimize) GetSearchQuery(mustQuery string) (qstr string) {
-    var (
-        musts, mustNot, wordsMusts, wordsShould []string
-        findFields                              string
-        //搜索范围是否只有附件
-        //搜索范围只选择附件,是否有附件条件无效;
-        isFileSearch  = so.SelectType == "filetext"
-        selectTypeArr = strings.Split(so.SelectType, ",")
-        isLogin       = so.UserId != ""
-    )
-    if mustQuery != "" {
-        musts = append(musts, mustQuery)
-    }
-    if selectTypeArr == nil || len(selectTypeArr) == 0 {
-        findFields = `"title"`
-    } else {
-        findFields = fmt.Sprintf(`"%s"`, strings.Join(selectTypeArr, "\",\""))
-    }
-    switchBool := strings.Contains(findFields, "detail") && strings.Contains(findFields, "title") && so.SearchTypeSwitch
+	var (
+		musts, mustNot, wordsMusts, wordsShould []string
+		findFields                              string
+		//搜索范围是否只有附件
+		//搜索范围只选择附件,是否有附件条件无效;
+		isFileSearch  = so.SelectType == "filetext"
+		selectTypeArr = strings.Split(so.SelectType, ",")
+		isLogin       = so.UserId != ""
+	)
+	if mustQuery != "" {
+		musts = append(musts, mustQuery)
+	}
+	if selectTypeArr == nil || len(selectTypeArr) == 0 {
+		findFields = `"title"`
+	} else {
+		findFields = fmt.Sprintf(`"%s"`, strings.Join(selectTypeArr, "\",\""))
+	}
+	switchBool := strings.Contains(findFields, "detail") && strings.Contains(findFields, "title") && so.SearchTypeSwitch
 
-    //采购单位
-    if so.Buyer != "" {
-        musts = append(musts, GetMatchArrSql("buyer.mbuyer", strings.Split(so.Buyer, ",")...))
-    }
-    //中标单位
-    if so.Winner != "" {
-        musts = append(musts, GetMatchArrSql("s_winner.mwinner", strings.Split(so.Winner, ",")...))
-    }
-    //代理机构
-    if so.Agency != "" {
-        musts = append(musts, GetMatchArrSql("agency.magency", strings.Split(so.Agency, ",")...))
-    }
-    //此时关键词中间有+进行隔离
-    if so.KeyWords != "" {
-        var (
-            keyWordsMusts []string
-        )
-        for _, v := range strings.Split(so.KeyWords, " ") {
-            if elastic.ReplaceYH(v) == "" {
-                continue
-            }
-            //单个字  搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail  搜索的时候加上标题
-            if len([]rune(elastic.ReplaceYH(v))) == 1 && bidsearch.DetailFileORTitle(findFields) {
-                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)
-                }
-            }
-            keyWordsMusts = append(keyWordsMusts, fmt.Sprintf(fmt.Sprintf(multiMatch, "%s", findFields), elastic.ReplaceYH(v)))
-        }
-        //搜索关键词模式;默认0:包含所有,1:包含任意
-        if so.WordsMode == 1 {
-            wordsShould = append(wordsShould, fmt.Sprintf(elastic.NgramMust, strings.Join(keyWordsMusts, ",")))
-        } else {
-            wordsMusts = append(wordsMusts, keyWordsMusts...)
-        }
-    }
-    //附加词
-    if so.AdditionalWords != "" {
-        //多组附加词,每组间,号隔开。每组内如果关键词中间有空格,自动分词
-        var (
-            addWordsMusts []string
-        )
-        for _, aws := range strings.Split(so.AdditionalWords, ",") {
-            var (
-                addWordsMust []string
-            )
-            for _, v := range strings.Split(aws, " ") {
-                if elastic.ReplaceYH(v) == "" {
-                    continue
-                }
-                //单个字  搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail  搜索的时候加上标题
-                //detail 正文不支持单字查询
-                if len([]rune(elastic.ReplaceYH(v))) == 1 && bidsearch.DetailFileORTitle(findFields) {
-                    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)
-                    }
-                }
-                addWordsMust = append(addWordsMust, fmt.Sprintf(fmt.Sprintf(multiMatch, "%s", findFields), elastic.ReplaceYH(v)))
-                addWordsMusts = append(addWordsMusts, addWordsMust...)
-                if so.WordsMode == 0 {
-                    wordsMusts = append(wordsMusts, addWordsMust...)
-                }
-                addWordsMust = []string{}
-            }
-            //搜索关键词模式;默认0:包含所有,1:包含任意
-            if so.WordsMode == 1 {
-                wordsShould = append(wordsShould, fmt.Sprintf(elastic.NgramMust, strings.Join(addWordsMusts, ",")))
-                addWordsMusts = []string{}
-            }
-        }
-    }
-    //搜索关键词模式;默认0:包含所有,1:包含任意
-    //包含任意一组
-    if len(wordsShould) > 0 {
-        musts = append(musts, fmt.Sprintf(queryBoolShould, strings.Join(wordsShould, ",")))
-    } else if len(wordsMusts) > 0 {
-        musts = append(musts, fmt.Sprintf(elastic.NgramMust, strings.Join(wordsMusts, ",")))
-    }
-    //排除词
-    if notKey := strings.TrimSpace(so.ExclusionWords); notKey != "" {
-        notKeyMultiMatch := fmt.Sprintf(multiMatch, "%s", findFields)
-        var notKeyMustNot []string
-        //多组排除词
-        for _, nks := range strings.Split(notKey, ",") {
-            //单组排除词 空格分割
-            for _, v := range strings.Split(nks, " ") {
-                v = strings.TrimSpace(v)
-                if v == "" {
-                    continue
-                }
-                if len([]rune(elastic.ReplaceYH(v))) == 1 {
-                    //单个字 搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail  搜索的时候加上标题
-                    if bidsearch.DetailFileORTitle(findFields) {
-                        notKeyMultiMatch = fmt.Sprintf(multiMatch, "%s", findFields+`,"title"`)
-                    }
-                }
-                notKeyMustNot = append(notKeyMustNot, fmt.Sprintf(notKeyMultiMatch, elastic.ReplaceYH(v)))
-            }
-        }
-        mustNot = append(mustNot, fmt.Sprintf(queryBoolShould, strings.Join(notKeyMustNot, ",")))
-    }
-    //行业
-    if so.Industry != "" && isLogin {
-        musts = append(musts, fmt.Sprintf(queryBoolMust, `"`+strings.ReplaceAll(so.Industry, ",", `","`)+`"`))
-    }
-    if so.BidField == "BIProperty" {
-        musts = append(musts, fmt.Sprintf(queryBoolMustA, "tag_topinformation", `"情报_物业"`))
-    }
-    //物业业态
-    if so.PropertyForm != "" && isLogin {
-        arr := []string{}
-        for _, v := range strings.Split(so.PropertyForm, ",") {
-            arr = append(arr, fmt.Sprintf(`"%s"`, v))
-        }
-        musts = append(musts, fmt.Sprintf(queryBoolShould, fmt.Sprintf(`{"terms":{"tag_set.wuye.property_form":[%s]}}`, strings.Join(arr, ","))))
-        //musts = append(musts, fmt.Sprintf(queryBoolShould, "property_form", `"`+strings.ReplaceAll(so.PropertyForm, ", ", `", "`)+`"`))
-    }
-    //业务类型
-    if so.Subinformation != "" && isLogin {
-        arr := []string{}
-        for _, v := range strings.Split(so.Subinformation, ",") {
-            arr = append(arr, fmt.Sprintf(`"%s"`, v))
-        }
-        musts = append(musts, fmt.Sprintf(queryBoolShould, fmt.Sprintf(`{"terms":{"tag_subinformation":[%s]}}`, strings.Join(arr, ","))))
-    }
-    //价格区间
-    if so.Scale != "" && isLogin {
-        arr := []string{}
-        for _, v := range strings.Split(so.Scale, ",") {
-            arr = append(arr, fmt.Sprintf(`"%s"`, v))
-        }
-        musts = append(musts, fmt.Sprintf(queryBoolShould, fmt.Sprintf(`{"terms":{"tag_set.wuye.scale":[%s]}}`, strings.Join(arr, ","))))
-    }
-    //合同周期
-    if so.Period != "" && isLogin {
-        arr := []string{}
-        for _, v := range strings.Split(so.Period, ",") {
-            arr = append(arr, fmt.Sprintf(`"%s"`, v))
-        }
-        musts = append(musts, fmt.Sprintf(queryBoolShould, fmt.Sprintf(`{"terms":{"tag_set.wuye.period":[%s]}}`, strings.Join(arr, ","))))
-    }
-    //换手率
-    if so.Changehand != 0 && isLogin {
-        if so.Changehand > 0 {
-            //存在
-            musts = append(musts, `{"range":{"tag_set.wuye.changehand":{"gt":0.3}}}`)
-        }
-    }
-    if so.Isfile != 0 && isLogin {
-        if so.Isfile > 0 {
-            //存在
-            musts = append(musts, fmt.Sprintf(queryBoolMustA, "tag_set.wuye.isfile", `"63"`))
-        } else {
-            //不存在
-            mustNot = append(mustNot, fmt.Sprintf(queryExists, "tag_set.wuye.isfile"))
-        }
-    }
-    //价格
-    if so.Price != "" && len(strings.Split(so.Price, "-")) > 1 && isLogin {
-        minPrice, maxPrice := strings.Split(so.Price, "-")[0], strings.Split(so.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 != "" {
-                musts = append(musts, fmt.Sprintf(queryBoolShould, fmt.Sprintf(queryBoolMustBoolShould, sq, sq)))
-            }
-        }
-    }
-    //采购单位联系方式
-    hasBuyerTel := so.BuyerTel
-    if hasBuyerTel != "" && isLogin {
-        if hasBuyerTel == "y" {
-            musts = append(musts, fmt.Sprintf(queryExists, "buyertel"))
-        } else {
-            mustNot = append(mustNot, fmt.Sprintf(queryExists, "buyertel"))
-        }
-    }
-    //中标企业联系方式
-    hasWinnerTel := so.WinnerTel
-    if hasWinnerTel != "" && isLogin {
-        if hasWinnerTel == "y" {
-            musts = append(musts, fmt.Sprintf(queryExists, "winnertel"))
-        } else {
-            mustNot = append(mustNot, fmt.Sprintf(queryExists, "winnertel"))
-        }
-    }
-    //附件
-    fileExists := so.FileExists
+	//采购单位
+	if so.Buyer != "" {
+		musts = append(musts, GetMatchArrSql("buyer.mbuyer", strings.Split(so.Buyer, ",")...))
+	}
+	//中标单位
+	if so.Winner != "" {
+		musts = append(musts, GetMatchArrSql("s_winner.mwinner", strings.Split(so.Winner, ",")...))
+	}
+	//代理机构
+	if so.Agency != "" {
+		musts = append(musts, GetMatchArrSql("agency.magency", strings.Split(so.Agency, ",")...))
+	}
+	//此时关键词中间有+进行隔离
+	if so.KeyWords != "" {
+		var (
+			keyWordsMusts []string
+		)
+		for _, v := range strings.Split(so.KeyWords, " ") {
+			if elastic.ReplaceYH(v) == "" {
+				continue
+			}
+			//单个字  搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail  搜索的时候加上标题
+			if len([]rune(elastic.ReplaceYH(v))) == 1 && bidsearch.DetailFileORTitle(findFields) {
+				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)
+				}
+			}
+			keyWordsMusts = append(keyWordsMusts, fmt.Sprintf(fmt.Sprintf(multiMatch, "%s", findFields), elastic.ReplaceYH(v)))
+		}
+		//搜索关键词模式;默认0:包含所有,1:包含任意
+		if so.WordsMode == 1 {
+			wordsShould = append(wordsShould, fmt.Sprintf(elastic.NgramMust, strings.Join(keyWordsMusts, ",")))
+		} else {
+			wordsMusts = append(wordsMusts, keyWordsMusts...)
+		}
+	}
+	//附加词
+	if so.AdditionalWords != "" {
+		//多组附加词,每组间,号隔开。每组内如果关键词中间有空格,自动分词
+		var (
+			addWordsMusts []string
+		)
+		for _, aws := range strings.Split(so.AdditionalWords, ",") {
+			var (
+				addWordsMust []string
+			)
+			for _, v := range strings.Split(aws, " ") {
+				if elastic.ReplaceYH(v) == "" {
+					continue
+				}
+				//单个字  搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail  搜索的时候加上标题
+				//detail 正文不支持单字查询
+				if len([]rune(elastic.ReplaceYH(v))) == 1 && bidsearch.DetailFileORTitle(findFields) {
+					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)
+					}
+				}
+				addWordsMust = append(addWordsMust, fmt.Sprintf(fmt.Sprintf(multiMatch, "%s", findFields), elastic.ReplaceYH(v)))
+				addWordsMusts = append(addWordsMusts, addWordsMust...)
+				if so.WordsMode == 0 {
+					wordsMusts = append(wordsMusts, addWordsMust...)
+				}
+				addWordsMust = []string{}
+			}
+			//搜索关键词模式;默认0:包含所有,1:包含任意
+			if so.WordsMode == 1 {
+				wordsShould = append(wordsShould, fmt.Sprintf(elastic.NgramMust, strings.Join(addWordsMusts, ",")))
+				addWordsMusts = []string{}
+			}
+		}
+	}
+	//搜索关键词模式;默认0:包含所有,1:包含任意
+	//包含任意一组
+	if len(wordsShould) > 0 {
+		musts = append(musts, fmt.Sprintf(queryBoolShould, strings.Join(wordsShould, ",")))
+	} else if len(wordsMusts) > 0 {
+		musts = append(musts, fmt.Sprintf(elastic.NgramMust, strings.Join(wordsMusts, ",")))
+	}
+	//排除词
+	if notKey := strings.TrimSpace(so.ExclusionWords); notKey != "" {
+		notKeyMultiMatch := fmt.Sprintf(multiMatch, "%s", findFields)
+		var notKeyMustNot []string
+		//多组排除词
+		for _, nks := range strings.Split(notKey, ",") {
+			//单组排除词 空格分割
+			for _, v := range strings.Split(nks, " ") {
+				v = strings.TrimSpace(v)
+				if v == "" {
+					continue
+				}
+				if len([]rune(elastic.ReplaceYH(v))) == 1 {
+					//单个字 搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail  搜索的时候加上标题
+					if bidsearch.DetailFileORTitle(findFields) {
+						notKeyMultiMatch = fmt.Sprintf(multiMatch, "%s", findFields+`,"title"`)
+					}
+				}
+				notKeyMustNot = append(notKeyMustNot, fmt.Sprintf(notKeyMultiMatch, elastic.ReplaceYH(v)))
+			}
+		}
+		mustNot = append(mustNot, fmt.Sprintf(queryBoolShould, strings.Join(notKeyMustNot, ",")))
+	}
+	//行业
+	if so.Industry != "" && isLogin {
+		musts = append(musts, fmt.Sprintf(queryBoolMust, `"`+strings.ReplaceAll(so.Industry, ",", `","`)+`"`))
+	}
+	if so.BidField == "BIProperty" {
+		musts = append(musts, fmt.Sprintf(queryBoolMustA, "tag_topinformation", `"情报_物业"`))
+	}
+	//物业业态
+	if so.PropertyForm != "" && isLogin {
+		arr := []string{}
+		for _, v := range strings.Split(so.PropertyForm, ",") {
+			arr = append(arr, fmt.Sprintf(`"%s"`, v))
+		}
+		musts = append(musts, fmt.Sprintf(queryBoolShould, fmt.Sprintf(`{"terms":{"tag_set.wuye.property_form":[%s]}}`, strings.Join(arr, ","))))
+		//musts = append(musts, fmt.Sprintf(queryBoolShould, "property_form", `"`+strings.ReplaceAll(so.PropertyForm, ", ", `", "`)+`"`))
+	}
+	//业务类型
+	if so.Subinformation != "" && isLogin {
+		arr := []string{}
+		for _, v := range strings.Split(so.Subinformation, ",") {
+			arr = append(arr, fmt.Sprintf(`"%s"`, v))
+		}
+		musts = append(musts, fmt.Sprintf(queryBoolShould, fmt.Sprintf(`{"terms":{"tag_subinformation":[%s]}}`, strings.Join(arr, ","))))
+	}
+	//价格区间
+	if so.Scale != "" && isLogin {
+		arr := []string{}
+		for _, v := range strings.Split(so.Scale, ",") {
+			arr = append(arr, fmt.Sprintf(`"%s"`, v))
+		}
+		musts = append(musts, fmt.Sprintf(queryBoolShould, fmt.Sprintf(`{"terms":{"tag_set.wuye.scale":[%s]}}`, strings.Join(arr, ","))))
+	}
+	//合同周期
+	if so.Period != "" && isLogin {
+		arr := []string{}
+		for _, v := range strings.Split(so.Period, ",") {
+			arr = append(arr, fmt.Sprintf(`"%s"`, v))
+		}
+		musts = append(musts, fmt.Sprintf(queryBoolShould, fmt.Sprintf(`{"terms":{"tag_set.wuye.period":[%s]}}`, strings.Join(arr, ","))))
+	}
+	//换手率
+	if so.Changehand != 0 && isLogin {
+		if so.Changehand > 0 {
+			//存在
+			musts = append(musts, `{"range":{"tag_set.wuye.changehand":{"gt":0.3}}}`)
+		}
+	}
+	if so.Isfile != 0 && isLogin {
+		if so.Isfile > 0 {
+			//存在
+			musts = append(musts, fmt.Sprintf(queryBoolMustA, "tag_set.wuye.isfile", `"63"`))
+		} else {
+			//不存在
+			mustNot = append(mustNot, fmt.Sprintf(queryExists, "tag_set.wuye.isfile"))
+		}
+	}
+	//价格
+	if so.Price != "" && len(strings.Split(so.Price, "-")) > 1 && isLogin {
+		minPrice, maxPrice := strings.Split(so.Price, "-")[0], strings.Split(so.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 != "" {
+				musts = append(musts, fmt.Sprintf(queryBoolShould, fmt.Sprintf(queryBoolMustBoolShould, sq, sq)))
+			}
+		}
+	}
+	//采购单位联系方式
+	hasBuyerTel := so.BuyerTel
+	if hasBuyerTel != "" && isLogin {
+		if hasBuyerTel == "y" {
+			musts = append(musts, fmt.Sprintf(queryExists, "buyertel"))
+		} else {
+			mustNot = append(mustNot, fmt.Sprintf(queryExists, "buyertel"))
+		}
+	}
+	//中标企业联系方式
+	hasWinnerTel := so.WinnerTel
+	if hasWinnerTel != "" && isLogin {
+		if hasWinnerTel == "y" {
+			musts = append(musts, fmt.Sprintf(queryExists, "winnertel"))
+		} else {
+			mustNot = append(mustNot, fmt.Sprintf(queryExists, "winnertel"))
+		}
+	}
+	//附件
+	fileExists := so.FileExists
 
-    if !isFileSearch && fileExists != "" && isLogin {
-        if so.BidField == "BIProperty" {
-            //物业
-            if fileExists == "1" {
-                //存在
-                musts = append(musts, fmt.Sprintf(queryBoolMustA, "tag_set.wuye.isfile", `"63"`))
-            } else if fileExists == "-1" {
-                //不存在
-                mustNot = append(mustNot, fmt.Sprintf(queryExists, "tag_set.wuye.isfile"))
-            }
-        } else {
-            if fileExists == "1" { //有附件
-                musts = append(musts, fmt.Sprintf(queryBoolMustTerm, true))
-            } else if fileExists == "-1" { //无附件
-                mustNot = append(mustNot, fmt.Sprintf(queryBoolMustTerm, true))
-            }
-        }
-    }
-    // 如果是领域化数据则需要加标签
-    if so.BidField != "" && so.BidField != "BIProperty" {
-        musts = append(musts, fmt.Sprintf(queryBoolMustTermDomain, so.BidField))
-    }
-    qstr = fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(mustNot, ","))
-    log.Println("qstr:", qstr)
-    return
+	if !isFileSearch && fileExists != "" && isLogin {
+		if so.BidField == "BIProperty" {
+			//物业
+			if fileExists == "1" {
+				//存在
+				musts = append(musts, fmt.Sprintf(queryBoolMustA, "tag_set.wuye.isfile", `"63"`))
+			} else if fileExists == "-1" {
+				//不存在
+				mustNot = append(mustNot, fmt.Sprintf(queryExists, "tag_set.wuye.isfile"))
+			}
+		} else {
+			if fileExists == "1" { //有附件
+				musts = append(musts, fmt.Sprintf(queryBoolMustTerm, true))
+			} else if fileExists == "-1" { //无附件
+				mustNot = append(mustNot, fmt.Sprintf(queryBoolMustTerm, true))
+			}
+		}
+	}
+	// 如果是领域化数据则需要加标签
+	if so.BidField != "" && so.BidField != "BIProperty" {
+		musts = append(musts, fmt.Sprintf(queryBoolMustTermDomain, so.BidField))
+	}
+	qstr = fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(mustNot, ","))
+	log.Println("qstr:", qstr)
+	return
 }
 
 // GetBidSearchQuery  整理地区、城市、发布时间、信息类型、采购单位类型 查询条件
 func (so *SearchOptimize) GetBidSearchQuery() string {
-    query := ``
-    //省份
-    area := so.Province
-    isLogin := so.UserId != ""
-    if area != "" && isLogin {
-        query += `{"terms":{"area":[`
-        for k, v := range strings.Split(area, ",") {
-            if k > 0 {
-                query += `,`
-            }
-            query += `"` + v + `"`
-        }
-        query += `]}}`
-    }
-    //市
-    city := so.City
-    if city != "" && isLogin {
-        if len(query) > 0 {
-            query += ","
-        }
-        query += `{"terms":{"city":[`
-        for k, v := range strings.Split(city, ",") {
-            if k > 0 {
-                query += `,`
-            }
-            query += `"` + v + `"`
-        }
-        query += `]}}`
-    }
-    //区域处理
-    district := so.District
-    if district != "" && isLogin {
-        if len(query) > 0 {
-            query += ","
-        }
-        for k, v := range strings.Split(district, ",") {
-            if k > 0 {
-                query += `,`
-            }
-            cityName := strings.Split(v, "_")[0]
-            districtName := strings.Split(v, "_")[1]
-            query_bool_must_and_district := `{"bool":{"must":[{"terms":{"city":["%s"]}},{"terms":{"district":["%s"]}}]}}`
-            query += fmt.Sprintf(query_bool_must_and_district, cityName, districtName)
-        }
+	query := ``
+	//省份
+	area := so.Province
+	isLogin := so.UserId != ""
+	if area != "" && isLogin {
+		query += `{"terms":{"area":[`
+		for k, v := range strings.Split(area, ",") {
+			if k > 0 {
+				query += `,`
+			}
+			query += `"` + v + `"`
+		}
+		query += `]}}`
+	}
+	//市
+	city := so.City
+	if city != "" && isLogin {
+		if len(query) > 0 {
+			query += ","
+		}
+		query += `{"terms":{"city":[`
+		for k, v := range strings.Split(city, ",") {
+			if k > 0 {
+				query += `,`
+			}
+			query += `"` + v + `"`
+		}
+		query += `]}}`
+	}
+	//区域处理
+	district := so.District
+	if district != "" && isLogin {
+		if len(query) > 0 {
+			query += ","
+		}
+		for k, v := range strings.Split(district, ",") {
+			if k > 0 {
+				query += `,`
+			}
+			cityName := strings.Split(v, "_")[0]
+			districtName := strings.Split(v, "_")[1]
+			query_bool_must_and_district := `{"bool":{"must":[{"terms":{"city":["%s"]}},{"terms":{"district":["%s"]}}]}}`
+			query += fmt.Sprintf(query_bool_must_and_district, cityName, districtName)
+		}
 
-    }
-    if query != "" {
-        query = fmt.Sprintf(queryBoolShould, query)
-    }
-    //发布时间
-    publishTime := so.PublishTime
-    if publishTime != "" {
-        if len(query) > 0 {
-            query += ","
-        }
-        startTime, endTime := "", ""
-        now := time.Now()
-        if publishTime == "lately-7" { //最近7天
-            startTime = fmt.Sprint(time.Date(now.Year(), now.Month(), now.Day()-7, 0, 0, 0, 0, time.Local).Unix())
-        } else if publishTime == "lately-30" { //最近30天
-            startTime = fmt.Sprint(time.Date(now.Year(), now.Month(), now.Day()-30, 0, 0, 0, 0, time.Local).Unix())
-        } else if publishTime == "thisyear" { //最近一年
-            startTime = fmt.Sprint(time.Date(now.Year()-1, now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, time.Local).Unix())
-            endTime = fmt.Sprint(now.Unix())
-        } else if publishTime == "threeyear" { //最近三年
-            startTime = fmt.Sprint(time.Date(now.Year()-3, now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, time.Local).Unix())
-            endTime = fmt.Sprint(now.Unix())
-        } else if publishTime == "fiveyear" { //最近五年
-            startTime = fmt.Sprint(time.Date(now.Year()-5, now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, time.Local).Unix())
-            endTime = fmt.Sprint(now.Unix())
-        } else if len(strings.Split(publishTime, "_")) > 1 {
-            startTime = strings.Split(publishTime, "_")[0]
-            endTime = strings.Split(publishTime, "_")[1]
-            etTime := time.Now()
-            if endTime != "" {
-                et, _ := strconv.ParseInt(endTime, 0, 64)
-                etTime = time.Unix(et, 0)
-            }
-            endTime = fmt.Sprint(time.Date(etTime.Year(), etTime.Month(), etTime.Day()+1, 0, 0, 0, 0, time.Local).Unix())
-        }
-        query += `{"range":{"publishtime":{`
-        if startTime != "" {
-            query += `"gte":` + startTime
-        }
-        if startTime != "" && endTime != "" {
-            query += `,`
-        }
-        if endTime != "" {
-            query += `"lt":` + endTime
-        }
-        query += `}}}`
-    }
-    if so.ExpireTime != "" {
-        if len(query) > 0 {
-            query += ","
-        }
-        startTime, endTime := "", ""
-        now := time.Now()
-        if so.ExpireTime == "1" { //本月到期
-            startTime = fmt.Sprint(now.Unix())
-            first := time.Date(now.Year(), now.Month()+1, 1, 0, 0, 0, 0, time.Local)
-            endTime = fmt.Sprint(first.AddDate(0, 0, 0).Unix())
-            /* endTime = fmt.Sprint(time.Date(now.Year(), now.Month()+1, 1, 0, 0, 0, 0, time.Local).Unix())*/
-        } else if so.ExpireTime == "1-3" { //1-3个月到期
-            startTime = fmt.Sprint(time.Date(now.Year(), now.Month()+1, now.Day(), 0, 0, 0, 0, time.Local).Unix())
-            endTime = fmt.Sprint(time.Date(now.Year(), now.Month()+3, now.Day(), 0, 0, 0, 0, time.Local).Unix())
-        } else if so.ExpireTime == "3-6" { //3-6个月到期
-            startTime = fmt.Sprint(time.Date(now.Year(), now.Month()+3, now.Day(), 0, 0, 0, 0, time.Local).Unix())
-            endTime = fmt.Sprint(time.Date(now.Year(), now.Month()+6, now.Day(), 0, 0, 0, 0, time.Local).Unix())
-        } else if so.ExpireTime == "6-12" { //6-12个月到期
-            startTime = fmt.Sprint(time.Date(now.Year(), now.Month()+6, now.Day(), 0, 0, 0, 0, time.Local).Unix())
-            endTime = fmt.Sprint(time.Date(now.Year(), now.Month()+12, now.Day(), 0, 0, 0, 0, time.Local).Unix())
-        } else if so.ExpireTime == "12" { //12个月以后
-            startTime = fmt.Sprint(time.Date(now.Year(), now.Month()+12, now.Day(), 0, 0, 0, 0, time.Local).Unix())
-        } else if len(strings.Split(so.ExpireTime, "_")) > 1 {
-            startTime = strings.Split(so.ExpireTime, "_")[0]
-            endTime = strings.Split(so.ExpireTime, "_")[1]
-            etTime := time.Now()
-            if endTime != "" {
-                et, _ := strconv.ParseInt(endTime, 0, 64)
-                etTime = time.Unix(et, 0)
-            }
-            endTime = fmt.Sprint(time.Date(etTime.Year(), etTime.Month(), etTime.Day()+1, 0, 0, 0, 0, time.Local).Unix())
-        }
-        query += `{"range":{"expiredate":{`
-        if startTime != "" {
-            query += `"gte":` + startTime
-        }
-        if startTime != "" && endTime != "" {
-            query += `,`
-        }
-        if endTime != "" {
-            query += `"lt":` + endTime
-        }
-        query += `}}}`
-    }
-    //信息类型-二级
-    subtype := so.Subtype
-    topType := util.If(so.TopType != "", strings.Split(so.TopType, ","), []string{}).([]string)
-    allType := ``
-    //二级分类
-    if subtype != "" {
-        var typeInt = 0
-        allType += `{"terms":{"subtype":[`
-        for k, v := range strings.Split(subtype, ",") {
-            if tType := util.If(topTypeMap[v] != "" && so.TopType == "", topTypeMap[v], "").(string); tType != "" {
-                topType = append(topType, tType)
-                typeInt += 1
-                continue
-            }
-            if k > typeInt {
-                allType += `,`
-            }
-            allType += `"` + v + `"`
-        }
-        allType += `]}}`
-        //subtype里都是一级信息类型
-        if typeInt == len(strings.Split(subtype, ",")) {
-            allType = ``
-        }
-    }
-    //信息类型  一级分类
-    log.Println("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 query != "" {
+		query = fmt.Sprintf(queryBoolShould, query)
+	}
+	//发布时间
+	publishTime := so.PublishTime
+	if publishTime != "" {
+		if len(query) > 0 {
+			query += ","
+		}
+		startTime, endTime := "", ""
+		now := time.Now()
+		if publishTime == "lately-7" { //最近7天
+			startTime = fmt.Sprint(time.Date(now.Year(), now.Month(), now.Day()-7, 0, 0, 0, 0, time.Local).Unix())
+		} else if publishTime == "lately-30" { //最近30天
+			startTime = fmt.Sprint(time.Date(now.Year(), now.Month(), now.Day()-30, 0, 0, 0, 0, time.Local).Unix())
+		} else if publishTime == "thisyear" { //最近一年
+			startTime = fmt.Sprint(time.Date(now.Year()-1, now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, time.Local).Unix())
+			endTime = fmt.Sprint(now.Unix())
+		} else if publishTime == "threeyear" { //最近三年
+			startTime = fmt.Sprint(time.Date(now.Year()-3, now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, time.Local).Unix())
+			endTime = fmt.Sprint(now.Unix())
+		} else if publishTime == "fiveyear" { //最近五年
+			startTime = fmt.Sprint(time.Date(now.Year()-5, now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, time.Local).Unix())
+			endTime = fmt.Sprint(now.Unix())
+		} else if len(strings.Split(publishTime, "_")) > 1 {
+			startTime = strings.Split(publishTime, "_")[0]
+			endTime = strings.Split(publishTime, "_")[1]
+			etTime := time.Now()
+			if endTime != "" {
+				et, _ := strconv.ParseInt(endTime, 0, 64)
+				etTime = time.Unix(et, 0)
+			}
+			endTime = fmt.Sprint(time.Date(etTime.Year(), etTime.Month(), etTime.Day()+1, 0, 0, 0, 0, time.Local).Unix())
+		}
+		query += `{"range":{"publishtime":{`
+		if startTime != "" {
+			query += `"gte":` + startTime
+		}
+		if startTime != "" && endTime != "" {
+			query += `,`
+		}
+		if endTime != "" {
+			query += `"lt":` + endTime
+		}
+		query += `}}}`
+	}
+	if so.ExpireTime != "" {
+		if len(query) > 0 {
+			query += ","
+		}
+		startTime, endTime := "", ""
+		now := time.Now()
+		if so.ExpireTime == "1" { //本月到期
+			startTime = fmt.Sprint(now.Unix())
+			first := time.Date(now.Year(), now.Month()+1, 1, 0, 0, 0, 0, time.Local)
+			endTime = fmt.Sprint(first.AddDate(0, 0, 0).Unix())
+			/* endTime = fmt.Sprint(time.Date(now.Year(), now.Month()+1, 1, 0, 0, 0, 0, time.Local).Unix())*/
+		} else if so.ExpireTime == "1-3" { //1-3个月到期
+			startTime = fmt.Sprint(time.Date(now.Year(), now.Month()+1, now.Day(), 0, 0, 0, 0, time.Local).Unix())
+			endTime = fmt.Sprint(time.Date(now.Year(), now.Month()+3, now.Day(), 0, 0, 0, 0, time.Local).Unix())
+		} else if so.ExpireTime == "3-6" { //3-6个月到期
+			startTime = fmt.Sprint(time.Date(now.Year(), now.Month()+3, now.Day(), 0, 0, 0, 0, time.Local).Unix())
+			endTime = fmt.Sprint(time.Date(now.Year(), now.Month()+6, now.Day(), 0, 0, 0, 0, time.Local).Unix())
+		} else if so.ExpireTime == "6-12" { //6-12个月到期
+			startTime = fmt.Sprint(time.Date(now.Year(), now.Month()+6, now.Day(), 0, 0, 0, 0, time.Local).Unix())
+			endTime = fmt.Sprint(time.Date(now.Year(), now.Month()+12, now.Day(), 0, 0, 0, 0, time.Local).Unix())
+		} else if so.ExpireTime == "12" { //12个月以后
+			startTime = fmt.Sprint(time.Date(now.Year(), now.Month()+12, now.Day(), 0, 0, 0, 0, time.Local).Unix())
+		} else if len(strings.Split(so.ExpireTime, "_")) > 1 {
+			startTime = strings.Split(so.ExpireTime, "_")[0]
+			endTime = strings.Split(so.ExpireTime, "_")[1]
+			etTime := time.Now()
+			if endTime != "" {
+				et, _ := strconv.ParseInt(endTime, 0, 64)
+				etTime = time.Unix(et, 0)
+			}
+			endTime = fmt.Sprint(time.Date(etTime.Year(), etTime.Month(), etTime.Day()+1, 0, 0, 0, 0, time.Local).Unix())
+		}
+		query += `{"range":{"expiredate":{`
+		if startTime != "" {
+			query += `"gte":` + startTime
+		}
+		if startTime != "" && endTime != "" {
+			query += `,`
+		}
+		if endTime != "" {
+			query += `"lt":` + endTime
+		}
+		query += `}}}`
+	}
+	//信息类型-二级
+	subtype := so.Subtype
+	topType := util.If(so.TopType != "", strings.Split(so.TopType, ","), []string{}).([]string)
+	allType := ``
+	//二级分类
+	if subtype != "" {
+		var typeInt = 0
+		allType += `{"terms":{"subtype":[`
+		for k, v := range strings.Split(subtype, ",") {
+			if tType := util.If(topTypeMap[v] != "" && so.TopType == "", topTypeMap[v], "").(string); tType != "" {
+				topType = append(topType, tType)
+				typeInt += 1
+				continue
+			}
+			if k > typeInt {
+				allType += `,`
+			}
+			allType += `"` + v + `"`
+		}
+		allType += `]}}`
+		//subtype里都是一级信息类型
+		if typeInt == len(strings.Split(subtype, ",")) {
+			allType = ``
+		}
+	}
+	//信息类型  一级分类
+	log.Println("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(queryBoolShould, allType)
-    }
-    //采购单位类型
-    if so.BuyerClass != "" && isLogin {
-        if len(query) > 0 {
-            query += ","
-        }
-        query += `{"terms":{"buyerclass":[`
-        for k, v := range strings.Split(so.BuyerClass, ",") {
-            if k > 0 {
-                query += `,`
-            }
-            query += `"` + v + `"`
-        }
-        query += `]}}`
-    }
-    return query
+	if allType != "" {
+		if query != "" {
+			query += ","
+		}
+		query += fmt.Sprintf(queryBoolShould, allType)
+	}
+	//采购单位类型
+	if so.BuyerClass != "" && isLogin {
+		if len(query) > 0 {
+			query += ","
+		}
+		query += `{"terms":{"buyerclass":[`
+		for k, v := range strings.Split(so.BuyerClass, ",") {
+			if k > 0 {
+				query += `,`
+			}
+			query += `"` + v + `"`
+		}
+		query += `]}}`
+	}
+	return query
 }
 
 // GetBidSearchListByCache   查询缓存数据
 // 未登录用户默认搜索和关键词搜索改成500条和免费用户保持一致--需求调整P260来自产品经理杨蘭20220116
 func (so *SearchOptimize) GetBidSearchListByCache() (list []*map[string]interface{}, count, total int64) {
-    //缓存数据 最大量是5000条  100页数据
-    l, c, t := func(so *SearchOptimize) (list []*map[string]interface{}, count, total int64) {
-        //缓存数据总量 - 当前平台
-        var keyDistinction string
-        if so.UserId == "" { //遗留问题 在p311处理
-            keyDistinction = "n"
-        } else {
-            keyDistinction = util.If(so.IsPay, "v", "f").(string)
-        }
-        redisCountKey := fmt.Sprintf(SearchCacheCount, so.SearchGroup, keyDistinction, util.If(so.BidField != "", so.BidField, "n").(string))
-        total = int64(redis.GetInt(RedisNameNew, redisCountKey))
-        //缓存数据: kws.SearchGroup-全部,招标信息,超前信息;kws.PageNum-当前页 免费用户 or 付费用户,BidField:领域化产品
-        redisDataKey := fmt.Sprintf(SearchCacheKey, so.SearchGroup, keyDistinction, util.If(so.BidField != "", so.BidField, "n").(string))
-        log.Println("-------redisDataKey:------", redisDataKey)
-        sCache, err := redis.GetNewBytes(RedisNameNew, redisDataKey)
-        if err == nil {
-            if sCache != nil && len(*sCache) > 0 {
-                err = json.Unmarshal(*sCache, &list)
-                if err == nil {
-                    //数据如果>最大数据结果量 total==count,否则count = 付费:5000;免费:500;
-                    count = util.If(so.IsPay, int64(bidsearch.SearchMaxPageCount_PAYED), int64(bidsearch.SearchMaxPageCount_PC)).(int64)
-                    count = util.If(count > total, total, count).(int64)
-                    return
-                }
-            }
-        }
-        //无缓存数据 或 缓存数据查询异常
-        //查库>存redis缓存
-        //查询缓存数据 参数初始化
-        so.DefaultSearchParamsAuto()
-        //缓存数据
-        count, total, list = so.GetBidSearchList(true)
-        if len(list) > 0 {
-            redis.Put(RedisNameNew, redisCountKey, total, 10*60)
-            b, err := json.Marshal(list)
-            if err == nil {
-                if err = redis.PutBytes(RedisNameNew, redisDataKey, &b, 10*60); err != nil {
-                    log.Println("默认搜索查询结果保存redis缓存异常")
-                }
-            } else {
-                log.Println("默认搜索查询数量保存redis缓存异常")
-            }
-        } else {
-            log.Println("默认搜索 暂无数据")
-        }
-        return
-    }(so)
-    if len(l) > 0 {
-        total = t
-        count = c
-        if len(l) < so.PageNum*so.PageSize {
-            list = l[(so.PageNum-1)*so.PageSize:]
-        } else {
-            list = l[(so.PageNum-1)*so.PageSize : so.PageNum*so.PageSize]
-        }
-    }
-    return
+	//缓存数据 最大量是5000条  100页数据
+	l, c, t := func(so *SearchOptimize) (list []*map[string]interface{}, count, total int64) {
+		//缓存数据总量 - 当前平台
+		var keyDistinction string
+		if so.UserId == "" { //遗留问题 在p311处理
+			keyDistinction = "n"
+		} else {
+			keyDistinction = util.If(so.IsPay, "v", "f").(string)
+		}
+		redisCountKey := fmt.Sprintf(SearchCacheCount, so.SearchGroup, keyDistinction, util.If(so.BidField != "", so.BidField, "n").(string))
+		total = int64(redis.GetInt(RedisNameNew, redisCountKey))
+		//缓存数据: kws.SearchGroup-全部,招标信息,超前信息;kws.PageNum-当前页 免费用户 or 付费用户,BidField:领域化产品
+		redisDataKey := fmt.Sprintf(SearchCacheKey, so.SearchGroup, keyDistinction, util.If(so.BidField != "", so.BidField, "n").(string))
+		log.Println("-------redisDataKey:------", redisDataKey)
+		sCache, err := redis.GetNewBytes(RedisNameNew, redisDataKey)
+		if err == nil {
+			if sCache != nil && len(*sCache) > 0 {
+				err = json.Unmarshal(*sCache, &list)
+				if err == nil {
+					//数据如果>最大数据结果量 total==count,否则count = 付费:5000;免费:500;
+					count = util.If(so.IsPay, int64(bidsearch.SearchMaxPageCount_PAYED), int64(bidsearch.SearchMaxPageCount_PC)).(int64)
+					count = util.If(count > total, total, count).(int64)
+					return
+				}
+			}
+		}
+		//无缓存数据 或 缓存数据查询异常
+		//查库>存redis缓存
+		//查询缓存数据 参数初始化
+		so.DefaultSearchParamsAuto()
+		//缓存数据
+		count, total, list = so.GetBidSearchList(true)
+		if len(list) > 0 {
+			redis.Put(RedisNameNew, redisCountKey, total, 10*60)
+			b, err := json.Marshal(list)
+			if err == nil {
+				if err = redis.PutBytes(RedisNameNew, redisDataKey, &b, 10*60); err != nil {
+					log.Println("默认搜索查询结果保存redis缓存异常")
+				}
+			} else {
+				log.Println("默认搜索查询数量保存redis缓存异常")
+			}
+		} else {
+			log.Println("默认搜索 暂无数据")
+		}
+		return
+	}(so)
+	if len(l) > 0 {
+		total = t
+		count = c
+		if len(l) < so.PageNum*so.PageSize {
+			list = l[(so.PageNum-1)*so.PageSize:]
+		} else {
+			list = l[(so.PageNum-1)*so.PageSize : so.PageNum*so.PageSize]
+		}
+	}
+	return
 }
 
 // SearchByES  es搜索
 type SearchByES struct {
-    Index      string
-    IType      string
-    Query      string
-    FindFields string
-    Order      string
-    Fields     string
-    Start      int
-    Limit      int
-    Count      int
-    HighLight  bool
-    State      int //1:noLogin;2:free;3:pay
+	Index      string
+	IType      string
+	Query      string
+	FindFields string
+	Order      string
+	Fields     string
+	Start      int
+	Limit      int
+	Count      int
+	HighLight  bool
+	State      int //1:noLogin;2:free;3:pay
 }
 
 // GetAllByNgramWithCount  获取es查询结果及总数量
 func (e *SearchByES) GetAllByNgramWithCount() (int64, *[]map[string]interface{}) {
-    var (
-        jyES = jyutil.GetES(e.State)
-    )
-    if jyES.EsIndex != "" {
-        e.Index = jyES.EsIndex
-        e.IType = jyES.EsType
-    }
-    if e.Query != "" {
-        queryStr := e.Query
-        if e.HighLight {
-            var ws []string
-            for _, w := range strings.Split(e.FindFields, ",") {
-                ws = append(ws, fmt.Sprintf(HighlightStr, w, e.Count))
-            }
-            queryStr = queryStr[:len(queryStr)-1] + `,` + fmt.Sprintf(HL, strings.Join(ws, ",")) + `}`
-        }
-        if len(e.Fields) > 0 {
-            queryStr = queryStr[:len(queryStr)-1] + `,"_source":[` + e.Fields + "]}"
-        }
-        if len(e.Order) > 0 {
-            queryStr = queryStr[:len(queryStr)-1] + `,"sort":[` + SR(SR(SR(SR(e.Order, ",", "},{", -1), " ", "", -1), ":-1", `:"desc"`, -1), ":1", `:"asc"`, -1) + `]}`
-        }
-        if e.Start > -1 {
-            queryStr = queryStr[:len(queryStr)-1] + `,"from":` + strconv.Itoa(e.Start) + `,"size":` + strconv.Itoa(e.Limit) + "}"
-        }
-        log.Println(e.Index, e.IType, "--queryStr:", queryStr)
-        //if e.IsLogin {
-        //	return elastic.GetWithCount(e.Index, e.IType, e.Query, queryStr)
-        //} else {
-        //	return pc.Other.GetWithCount(e.Index, e.IType, e.Query, queryStr)
-        //}
-        return jyES.Es.GetWithCount(e.Index, e.IType, e.Query, queryStr)
-    } else {
-        return 0, nil
-    }
+	var (
+		jyES = jyutil.GetES(e.State)
+	)
+	if jyES.EsIndex != "" {
+		e.Index = jyES.EsIndex
+		e.IType = jyES.EsType
+	}
+	if e.Query != "" {
+		queryStr := e.Query
+		if e.HighLight {
+			var ws []string
+			for _, w := range strings.Split(e.FindFields, ",") {
+				ws = append(ws, fmt.Sprintf(HighlightStr, w, e.Count))
+			}
+			queryStr = queryStr[:len(queryStr)-1] + `,` + fmt.Sprintf(HL, strings.Join(ws, ",")) + `}`
+		}
+		if len(e.Fields) > 0 {
+			queryStr = queryStr[:len(queryStr)-1] + `,"_source":[` + e.Fields + "]}"
+		}
+		if len(e.Order) > 0 {
+			queryStr = queryStr[:len(queryStr)-1] + `,"sort":[` + SR(SR(SR(SR(e.Order, ",", "},{", -1), " ", "", -1), ":-1", `:"desc"`, -1), ":1", `:"asc"`, -1) + `]}`
+		}
+		if e.Start > -1 {
+			queryStr = queryStr[:len(queryStr)-1] + `,"from":` + strconv.Itoa(e.Start) + `,"size":` + strconv.Itoa(e.Limit) + "}"
+		}
+		log.Println(e.Index, e.IType, "--queryStr:", queryStr)
+		//if e.IsLogin {
+		//	return elastic.GetWithCount(e.Index, e.IType, e.Query, queryStr)
+		//} else {
+		//	return pc.Other.GetWithCount(e.Index, e.IType, e.Query, queryStr)
+		//}
+		return jyES.Es.GetWithCount(e.Index, e.IType, e.Query, queryStr)
+	} else {
+		return 0, nil
+	}
 }
 
 // SearchListFormat  格式化数据
 func SearchListFormat(industry, subinformation, propertyForm string, repl []map[string]interface{}, b bool, bidField string) (list []*map[string]interface{}) {
-    for _, v := range repl {
-        //正文
-        if b {
-            //正文匹配检索关键词
-            highlight, _ := v["highlight"].(map[string][]string)
-            detail := ""
-            for _, val := range highlight["detail"] {
-                detail += jy.ClearHtml.ReplaceAllString(val, "")
-            }
-            v["detail"] = detail
-        }
-        v["_id"] = encrypt.EncodeArticleId2ByCheck(util.ObjToString(v["_id"]))                                     //加密信息id
-        v["s_subscopeclass"] = IndustryFormat(industry, strings.Trim(util.ObjToString(v["s_subscopeclass"]), ",")) //行业
-        v["industry"] = v["s_subscopeclass"]                                                                       //行业
-        if budget, ok := v["budget"].(float64); ok && budget > 0 {                                                 //预算
-            v["budget"] = int64(budget)
-        }
-        if bidAmount, ok := v["bidamount"].(float64); ok && bidAmount > 0 { //中标金额
-            v["bidamount"] = int64(bidAmount)
-        }
-        //附件
-        if isValidFile, _ := v["isValidFile"].(bool); isValidFile {
-            delete(v, "isValidFile")
-            v["fileExists"] = true
-        }
-        //地区链接、
-        area := util.ObjToString(v["area"])
-        //信息类型链接
-        finalType, _ := v["subtype"].(string)
-        if finalType == "" {
-            finalType = util.ObjToString(v["toptype"])
-        }
-        if finalType == "" {
-            finalType = util.ObjToString(v["type"])
-            if finalType == "bid" {
-                finalType = "中标"
-            } else if finalType == "tender" {
-                finalType = "招标"
-            } else {
-                finalType = ""
-            }
-        }
-        //行业链接、
-        subScopeClass := industry
-        if subScopeClass == "" {
-            subScopeClass = util.ObjToString(v["s_subscopeclass"])
-            if subScopeClass != "" {
-                if strings.Contains(subScopeClass, "它") {
-                    subScopeClass = strings.Replace(subScopeClass, "它", "他", -1)
-                }
-                subScopeClass = strings.Split(subScopeClass, ",")[0]
-            }
-        }
-        //stypeadd :信息类型链接
-        //areaadd:地址链接;
-        //indadd:行业链接
-        v["stypeadd"], v["areaadd"], v["indadd"] = classify(finalType, area, subScopeClass)
-        winnerList := util.ObjToString(v["s_winner"]) //中标企业名称集合
-        if winnerList != "" && len(strings.Split(winnerList, ",")) > 0 {
-            var winnerInfo []*WinnerInfo
-            for wk, wv := range strings.Split(winnerList, ",") {
-                var (
-                    winnerId = ""
-                )
-                if v["entidlist"] != nil {
-                    if entIdList := util.ObjArrToStringArr(v["entidlist"].([]interface{})); len(entIdList) > wk { //中标企业id集合
-                        winnerId = entIdList[wk]
-                    }
-                }
-                winnerInfo = append(winnerInfo, &WinnerInfo{
-                    Winner:       wv,                                                                                                            //中标企业 需要单独处理
-                    WinnerTel:    util.ObjToString(v["winnertel"]),                                                                              //中标企业联系电话
-                    WinnerPerson: util.ObjToString(v["winnerperson"]),                                                                           //中标企业联系人
-                    WinnerId:     util.If(winnerId != "" && len([]rune(winnerId)) > 12, encrypt.EncodeArticleId2ByCheck(winnerId), "").(string), //中标企业加密id  存在winnerId 异常的情况
-                })
-            }
-            v["winnerInfo"] = winnerInfo
+	for _, v := range repl {
+		//正文
+		if b {
+			//正文匹配检索关键词
+			highlight, _ := v["highlight"].(map[string][]string)
+			detail := ""
+			for _, val := range highlight["detail"] {
+				detail += jy.ClearHtml.ReplaceAllString(val, "")
+			}
+			v["detail"] = detail
+		}
+		v["_id"] = encrypt.EncodeArticleId2ByCheck(util.ObjToString(v["_id"]))                                     //加密信息id
+		v["s_subscopeclass"] = IndustryFormat(industry, strings.Trim(util.ObjToString(v["s_subscopeclass"]), ",")) //行业
+		v["industry"] = v["s_subscopeclass"]                                                                       //行业
+		if budget, ok := v["budget"].(float64); ok && budget > 0 {                                                 //预算
+			v["budget"] = int64(budget)
+		}
+		if bidAmount, ok := v["bidamount"].(float64); ok && bidAmount > 0 { //中标金额
+			v["bidamount"] = int64(bidAmount)
+		}
+		//附件
+		if isValidFile, _ := v["isValidFile"].(bool); isValidFile {
+			delete(v, "isValidFile")
+			v["fileExists"] = true
+		}
+		//地区链接、
+		area := util.ObjToString(v["area"])
+		//信息类型链接
+		finalType, _ := v["subtype"].(string)
+		if finalType == "" {
+			finalType = util.ObjToString(v["toptype"])
+		}
+		if finalType == "" {
+			finalType = util.ObjToString(v["type"])
+			if finalType == "bid" {
+				finalType = "中标"
+			} else if finalType == "tender" {
+				finalType = "招标"
+			} else {
+				finalType = ""
+			}
+		}
+		//行业链接、
+		subScopeClass := industry
+		if subScopeClass == "" {
+			subScopeClass = util.ObjToString(v["s_subscopeclass"])
+			if subScopeClass != "" {
+				if strings.Contains(subScopeClass, "它") {
+					subScopeClass = strings.Replace(subScopeClass, "它", "他", -1)
+				}
+				subScopeClass = strings.Split(subScopeClass, ",")[0]
+			}
+		}
+		//stypeadd :信息类型链接
+		//areaadd:地址链接;
+		//indadd:行业链接
+		v["stypeadd"], v["areaadd"], v["indadd"] = classify(finalType, area, subScopeClass)
+		winnerList := util.ObjToString(v["s_winner"]) //中标企业名称集合
+		if winnerList != "" && len(strings.Split(winnerList, ",")) > 0 {
+			var winnerInfo []*WinnerInfo
+			for wk, wv := range strings.Split(winnerList, ",") {
+				var (
+					winnerId = ""
+				)
+				if v["entidlist"] != nil {
+					if entIdList := util.ObjArrToStringArr(v["entidlist"].([]interface{})); len(entIdList) > wk { //中标企业id集合
+						winnerId = entIdList[wk]
+					}
+				}
+				winnerInfo = append(winnerInfo, &WinnerInfo{
+					Winner:       wv,                                                                                                            //中标企业 需要单独处理
+					WinnerTel:    util.ObjToString(v["winnertel"]),                                                                              //中标企业联系电话
+					WinnerPerson: util.ObjToString(v["winnerperson"]),                                                                           //中标企业联系人
+					WinnerId:     util.If(winnerId != "" && len([]rune(winnerId)) > 12, encrypt.EncodeArticleId2ByCheck(winnerId), "").(string), //中标企业加密id  存在winnerId 异常的情况
+				})
+			}
+			v["winnerInfo"] = winnerInfo
 
-        }
-        if bidField == "BIProperty" {
-            v["fileExists"] = false
-            //物业数据处理
-            subinformationArr := gconv.SliceStr(v["tag_subinformation"])
-            if len(subinformationArr) > 0 {
-                if len(subinformation) > 0 {
-                    fool := false
-                    for _, s1 := range subinformationArr {
-                        for _, s2 := range strings.Split(subinformation, ",") {
-                            if s2 == s1 {
-                                v["tag_subinformation"] = strings.Split(s1, "_")[1]
-                                fool = true
-                                break
-                            }
-                        }
-                        if fool {
-                            break
-                        }
-                    }
-                } else {
-                    v["tag_subinformation"] = strings.Split(subinformationArr[0], "_")[1]
-                }
-            }
-            //是否有附件
-            tag := gconv.Map(v["tag_set"])
-            if tag != nil {
-                wuye := gconv.Map(tag["wuye"])
-                if tag != nil {
-                    isFile := gconv.Int64(wuye["isfile"])
-                    propertyFormStr := gconv.String(wuye["property_form"])
-                    if isFile == 63 {
-                        v["fileExists"] = true
-                    }
-                    if propertyFormStr != "" {
-                        if propertyForm != "" {
-                            fool := false
-                            for _, s1 := range strings.Split(propertyFormStr, ",") {
-                                for _, s2 := range strings.Split(propertyForm, ",") {
-                                    if s2 == s1 {
-                                        v["property_form"] = s2
-                                        fool = true
-                                        break
-                                    }
-                                }
-                                if fool {
-                                    break
-                                }
-                            }
-                        } else {
-                            v["property_form"] = strings.Split(propertyFormStr, ",")[0]
-                        }
-                    }
-                }
-            }
-            delete(v, "tag_set")
-        }
-        tmp := v
-        list = append(list, &tmp)
-    }
-    return
+		}
+		if bidField == "BIProperty" {
+			v["fileExists"] = false
+			//物业数据处理
+			subinformationArr := gconv.SliceStr(v["tag_subinformation"])
+			if len(subinformationArr) > 0 {
+				if len(subinformation) > 0 {
+					fool := false
+					for _, s1 := range subinformationArr {
+						for _, s2 := range strings.Split(subinformation, ",") {
+							if s2 == s1 {
+								v["tag_subinformation"] = strings.Split(s1, "_")[1]
+								fool = true
+								break
+							}
+						}
+						if fool {
+							break
+						}
+					}
+				} else {
+					v["tag_subinformation"] = strings.Split(subinformationArr[0], "_")[1]
+				}
+			}
+			//是否有附件
+			tag := gconv.Map(v["tag_set"])
+			if tag != nil {
+				wuye := gconv.Map(tag["wuye"])
+				if tag != nil {
+					isFile := gconv.Int64(wuye["isfile"])
+					propertyFormStr := gconv.String(wuye["property_form"])
+					if isFile == 63 {
+						v["fileExists"] = true
+					}
+					if propertyFormStr != "" {
+						if propertyForm != "" {
+							fool := false
+							for _, s1 := range strings.Split(propertyFormStr, ",") {
+								for _, s2 := range strings.Split(propertyForm, ",") {
+									if s2 == s1 {
+										v["property_form"] = s2
+										fool = true
+										break
+									}
+								}
+								if fool {
+									break
+								}
+							}
+						} else {
+							v["property_form"] = strings.Split(propertyFormStr, ",")[0]
+						}
+					}
+				}
+			}
+			delete(v, "tag_set")
+		}
+		tmp := v
+		list = append(list, &tmp)
+	}
+	return
 }
 
 // WinnerInfo 中标企业信息
 type WinnerInfo struct {
-    Winner       string `json:"winner,omitempty"`
-    WinnerTel    string `json:"winnerTel,omitempty"`
-    WinnerPerson string `json:"winnerPerson,omitempty"`
-    WinnerId     string `json:"winnerId,omitempty"`
+	Winner       string `json:"winner,omitempty"`
+	WinnerTel    string `json:"winnerTel,omitempty"`
+	WinnerPerson string `json:"winnerPerson,omitempty"`
+	WinnerId     string `json:"winnerId,omitempty"`
 }
 
 // IndustryFormat 行业处理
 func IndustryFormat(industry, subScopeClass string) (newIndustry string) {
-    commonSubstring := func(v string) (value string) {
-        bcs := strings.Split(v, "_")
-        if len(bcs) == 1 {
-            value = bcs[0]
-        } else if len(bcs) == 2 {
-            value = bcs[0]
-            if strings.TrimSpace(value) == "" {
-                value = bcs[0]
-            }
-        }
-        return
-    }
-    bct := strings.Split(subScopeClass, ",")
-    if bct == nil || len(bct) == 0 {
-        return
-    }
-    //搜索条件中没有行业的话,取查询结果中第一个行业
-    if industry == "" {
-        newIndustry = commonSubstring(bct[0])
-    } else { //搜索条件中有行业的话,取行业中和搜索条件相对应的第一个
-        industryArr := strings.Split(industry, ",")
-    L:
-        for _, bc := range bct {
-            for _, is := range industryArr {
-                if bc == is {
-                    newIndustry = strings.TrimSpace(commonSubstring(bc))
-                    break L
-                }
-            }
-        }
-    }
-    return
+	commonSubstring := func(v string) (value string) {
+		bcs := strings.Split(v, "_")
+		if len(bcs) == 1 {
+			value = bcs[0]
+		} else if len(bcs) == 2 {
+			value = bcs[0]
+			if strings.TrimSpace(value) == "" {
+				value = bcs[0]
+			}
+		}
+		return
+	}
+	bct := strings.Split(subScopeClass, ",")
+	if bct == nil || len(bct) == 0 {
+		return
+	}
+	//搜索条件中没有行业的话,取查询结果中第一个行业
+	if industry == "" {
+		newIndustry = commonSubstring(bct[0])
+	} else { //搜索条件中有行业的话,取行业中和搜索条件相对应的第一个
+		industryArr := strings.Split(industry, ",")
+	L:
+		for _, bc := range bct {
+			for _, is := range industryArr {
+				if bc == is {
+					newIndustry = strings.TrimSpace(commonSubstring(bc))
+					break L
+				}
+			}
+		}
+	}
+	return
 }
 
-//采购单位、中标企业、代理机构
+// 采购单位、中标企业、代理机构
 var GetMatchArrSql = func(field string, val ...string) (sql string) {
-    if len(val) == 0 {
-        return
-    }
-    var arr []string
-    for _, s := range val {
-        if s == "" {
-            continue
-        }
-        arr = append(arr, fmt.Sprintf(`{"match_phrase": {"%s": "%s"}}`, field, s))
-    }
-    if len(arr) == 0 {
-        return ""
-    }
-    return fmt.Sprintf(`{"bool": {"should": [%s],"minimum_should_match": 1}}`, strings.Join(arr, ","))
+	if len(val) == 0 {
+		return
+	}
+	var (
+		arr []string
+		i   int
+	)
+	for _, s := range val {
+		if s == "" {
+			continue
+		}
+		if len([]rune(s)) > 30 {
+			s = string([]rune(s)[:30])
+		}
+		i++
+		arr = append(arr, fmt.Sprintf(`{"match_phrase": {"%s": "%s"}}`, field, s))
+		if i > 4 {
+			break
+		}
+	}
+	if len(arr) == 0 {
+		return ""
+	}
+	return fmt.Sprintf(`{"bool": {"should": [%s],"minimum_should_match": 1}}`, strings.Join(arr, ","))
 }