Browse Source

feat:字段限制

wangshan 1 year ago
parent
commit
b7f0d1ae30
1 changed files with 1138 additions and 1128 deletions
  1. 1138 1128
      src/jfw/front/searchOptimize.go

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

@@ -1,1208 +1,1218 @@
 package front
 package front
 
 
 import (
 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 (
 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 (
 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 {
 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  初始化
 // 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,
 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 缓存查询条件初始化
 // DefaultSearchParamsAuto 缓存查询条件初始化
 func (so *SearchOptimize) 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 搜索条件 处理
 // SearchParamsHandle 搜索条件 处理
 func (so *SearchOptimize) 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 关键词处理 获取关键词查询条件
 // GetSearchKeyWordsQueryStr 关键词处理 获取关键词查询条件
 func (so *SearchOptimize) GetSearchKeyWordsQueryStr() string {
 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 搜索 查询
 // GetBidSearchList 搜索 查询
 func (so *SearchOptimize) GetBidSearchList(isCache bool) (count, total int64, list []*map[string]interface{}) {
 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 搜索日志
 // SaveSearchLogs 搜索日志
 func (so *SearchOptimize) SaveSearchLogs(count int64) {
 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  整理关键词等查询条件
 // GetSearchQuery  整理关键词等查询条件
 func (so *SearchOptimize) GetSearchQuery(mustQuery string) (qstr string) {
 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  整理地区、城市、发布时间、信息类型、采购单位类型 查询条件
 // GetBidSearchQuery  整理地区、城市、发布时间、信息类型、采购单位类型 查询条件
 func (so *SearchOptimize) GetBidSearchQuery() string {
 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   查询缓存数据
 // GetBidSearchListByCache   查询缓存数据
 // 未登录用户默认搜索和关键词搜索改成500条和免费用户保持一致--需求调整P260来自产品经理杨蘭20220116
 // 未登录用户默认搜索和关键词搜索改成500条和免费用户保持一致--需求调整P260来自产品经理杨蘭20220116
 func (so *SearchOptimize) GetBidSearchListByCache() (list []*map[string]interface{}, count, total int64) {
 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搜索
 // SearchByES  es搜索
 type SearchByES struct {
 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查询结果及总数量
 // GetAllByNgramWithCount  获取es查询结果及总数量
 func (e *SearchByES) GetAllByNgramWithCount() (int64, *[]map[string]interface{}) {
 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  格式化数据
 // SearchListFormat  格式化数据
 func SearchListFormat(industry, subinformation, propertyForm string, repl []map[string]interface{}, b bool, bidField string) (list []*map[string]interface{}) {
 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 中标企业信息
 // WinnerInfo 中标企业信息
 type WinnerInfo struct {
 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 行业处理
 // IndustryFormat 行业处理
 func IndustryFormat(industry, subScopeClass string) (newIndustry string) {
 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) {
 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, ","))
 }
 }