|
@@ -1,606 +1,607 @@
|
|
|
package entity
|
|
|
|
|
|
-import (
|
|
|
- "config"
|
|
|
- "encoding/json"
|
|
|
- "errors"
|
|
|
- "fmt"
|
|
|
- "log"
|
|
|
- "math"
|
|
|
- qutil "qfw/util"
|
|
|
- "qfw/util/elastic"
|
|
|
- "qfw/util/jy"
|
|
|
- "strconv"
|
|
|
- "strings"
|
|
|
- "sync"
|
|
|
- "time"
|
|
|
- "util"
|
|
|
-
|
|
|
- "go.mongodb.org/mongo-driver/bson"
|
|
|
-)
|
|
|
-
|
|
|
-/*筛选条件--关键词*/
|
|
|
-type KeyWord struct {
|
|
|
- Keyword string `json:"keyword"` //关键词
|
|
|
- Appended []string `json:"appended"` //附加词
|
|
|
- Exclude []string `json:"exclude"` //排除词
|
|
|
-}
|
|
|
-
|
|
|
-/*筛选条件*/
|
|
|
-type SieveCondition struct {
|
|
|
- Id string `json:"id"`
|
|
|
- PublishTime string `json:"publishtime"` //发布时间
|
|
|
- Area []string `json:"area"` //地区-省份
|
|
|
- City []string `json:"city"` //地区-城市
|
|
|
- Region []string `json:"region"` //地区-省份+城市
|
|
|
- Industry []string `json:"industry"` //行业
|
|
|
- Keyword []KeyWord `json:"keywords"` //关键词
|
|
|
- Buyer []string `json:"buyer"` //招标单位(采购单位)
|
|
|
- Buyerclass []string `json:"buyerclass"` //采购单位类型
|
|
|
- Winner []string `json:"winner"` //中标单位
|
|
|
- ComeInTime int64 `json:"comeintime"` //入库时间(秒)
|
|
|
- OpenId string `json:"openid"` //用户openid
|
|
|
- MinPrice string `json:"minprice"` //金额——最少
|
|
|
- MaxPrice string `json:"maxprice"` //金额——最多
|
|
|
- SelectType string `json:"selectType"` //筛选(正文 or 标题)
|
|
|
- Subtype string `json:"subtype"` //信息类型
|
|
|
- Comeinfrom string `json:"comeinfrom"` //查询来源
|
|
|
- DisWord string `json:"disWord"` //分销系统 口令
|
|
|
-}
|
|
|
-
|
|
|
-//VIP订单
|
|
|
-type VipFilter struct {
|
|
|
- Area map[string]interface{} `json:"area"` //地区
|
|
|
- Industry []string `json:"industry"` //
|
|
|
- Cyclecount int `json:"cyclecount"`
|
|
|
- Cycleunit int `json:"cycleunit"`
|
|
|
- Ordertype int `json:"ordertype"`
|
|
|
- Addarea map[string]interface{} `json:"addarea"` //新增地区
|
|
|
- Addindustry []string `json:"addindustry"` //新增行业
|
|
|
- Addareacount map[string]interface{} `json:"addareacount"` //新增地区数量
|
|
|
- Addbuyerclasscount int `json:"addbuyerclasscount"` //新增地区数量
|
|
|
- Buyset map[string]interface{} `json:buyset`
|
|
|
- NewBuyset map[string]interface{} `json:newBuyset` //逻辑重写后的判断条件
|
|
|
-}
|
|
|
-
|
|
|
-const (
|
|
|
- INDEX = "bidding"
|
|
|
- TYPE = "bidding"
|
|
|
- bidSearch_sort = `{"publishtime":-1}`
|
|
|
-)
|
|
|
-
|
|
|
-var onceSearchCount = 500
|
|
|
-var ExportTable string = "export_search"
|
|
|
-var searchPool = make(chan bool, 8)
|
|
|
-
|
|
|
-//获取数据导出查询语句
|
|
|
-func getDataExportSql(scd *SieveCondition) string {
|
|
|
- multi_match := `{"multi_match": {"query": %s,"type": "phrase", "fields": [%s]}}`
|
|
|
- query := `{"query":{"bool":{"must":[%s],"should":[%s],"minimum_should_match": %d}}}`
|
|
|
- query_bool_should := `{"bool":{"should":[%s],"minimum_should_match": 1}}`
|
|
|
- query_price := `{"bool":{"must":[{"range":{"bidamount":{%s}}}]}},{"bool":{"must":[{"range":{"budget":{%s}}}],"must_not":[{"range":{"bidamount":{"gte":-1}}}]}}`
|
|
|
- query_bool_must := `{"terms":{"%s":[%s]}}`
|
|
|
- query_bool_must_and := `{"bool":{"must":[%s]%s}}`
|
|
|
- gte := `"gte": %s`
|
|
|
- lte := `"lte": %s`
|
|
|
-
|
|
|
- bools := []string{}
|
|
|
- musts := []string{fmt.Sprintf(`{"range":{"comeintime":{"lt":%d}}}`, scd.ComeInTime)}
|
|
|
- //省份
|
|
|
- areaCity := []string{}
|
|
|
- if len(scd.Area) > 0 {
|
|
|
- areaquery := `{"terms":{"area":[`
|
|
|
- for k, v := range scd.Area {
|
|
|
- if k > 0 {
|
|
|
- areaquery += `,`
|
|
|
- }
|
|
|
- areaquery += `"` + v + `"`
|
|
|
- }
|
|
|
- areaquery += `]}}`
|
|
|
- areaCity = append(areaCity, areaquery)
|
|
|
- }
|
|
|
- //城市
|
|
|
- if len(scd.City) > 0 {
|
|
|
- areaquery := `{"terms":{"city":[`
|
|
|
- for k, v := range scd.City {
|
|
|
- if k > 0 {
|
|
|
- areaquery += `,`
|
|
|
- }
|
|
|
- areaquery += `"` + v + `"`
|
|
|
- }
|
|
|
- areaquery += `]}}`
|
|
|
- areaCity = append(areaCity, areaquery)
|
|
|
- }
|
|
|
- if len(areaCity) > 0 {
|
|
|
- musts = append(musts, fmt.Sprintf(query_bool_should, strings.Join(areaCity, ",")))
|
|
|
- }
|
|
|
- //检索日期
|
|
|
-
|
|
|
- starttime := ""
|
|
|
- now := time.Unix(scd.ComeInTime, 0)
|
|
|
- endtime := fmt.Sprintf("%d", now.Unix())
|
|
|
- if scd.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 scd.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 scd.PublishTime == "thisyear" { //去年
|
|
|
- starttime = fmt.Sprint(time.Date(now.Year()-1, 1, 1, 0, 0, 0, 0, time.Local).Unix())
|
|
|
- endtime = fmt.Sprint(time.Date(now.Year()-1, 12, 31, 23, 59, 59, 0, time.Local).Unix())
|
|
|
- } else if strings.Contains(scd.PublishTime, "_") { //设置检索日期
|
|
|
- starttime = strings.Split(scd.PublishTime, "_")[0]
|
|
|
- endTime_tmp := now
|
|
|
- if etime := strings.Split(scd.PublishTime, "_")[1]; etime != "" {
|
|
|
- etTime := time.Unix(qutil.Int64All(etime), 0)
|
|
|
- endTime_tmp = time.Date(etTime.Year(), etTime.Month(), etTime.Day()+1, 0, 0, 0, 0, time.Local)
|
|
|
- }
|
|
|
- //结束时间必须小于筛选时间
|
|
|
- if endTime_tmp.After(now) {
|
|
|
- endTime_tmp = now
|
|
|
- }
|
|
|
- endtime = fmt.Sprintf("%d", endTime_tmp.Unix())
|
|
|
- }
|
|
|
- timequery := `{"range":{"publishtime":{`
|
|
|
- if starttime != "" {
|
|
|
- timequery += `"gte":` + starttime
|
|
|
- }
|
|
|
- if starttime != "" && endtime != "" {
|
|
|
- timequery += `,`
|
|
|
- }
|
|
|
- if endtime != "" {
|
|
|
- timequery += `"lt":` + endtime
|
|
|
- }
|
|
|
- timequery += `}}}`
|
|
|
- musts = append(musts, timequery)
|
|
|
-
|
|
|
- if scd.Subtype != "" {
|
|
|
- subquery := `{"terms":{"subtype":[`
|
|
|
- for k, v := range strings.Split(scd.Subtype, ",") {
|
|
|
- if k > 0 {
|
|
|
- subquery += `,`
|
|
|
- }
|
|
|
- subquery += `"` + v + `"`
|
|
|
- }
|
|
|
- subquery += `]}}`
|
|
|
- musts = append(musts, subquery)
|
|
|
- }
|
|
|
- if len(scd.Industry) > 0 {
|
|
|
- musts = append(musts, fmt.Sprintf(query_bool_must, "s_subscopeclass", `"`+strings.Join(scd.Industry, `","`)+`"`))
|
|
|
- }
|
|
|
- if len(scd.Buyer) > 0 {
|
|
|
- musts = append(musts, fmt.Sprintf(query_bool_must, "buyer", `"`+strings.Join(scd.Buyer, `","`)+`"`))
|
|
|
- }
|
|
|
- if len(scd.Buyerclass) > 0 {
|
|
|
- musts = append(musts, fmt.Sprintf(query_bool_must, "buyerclass", `"`+strings.Join(scd.Buyerclass, `","`)+`"`))
|
|
|
- }
|
|
|
- if len(scd.Winner) > 0 {
|
|
|
- musts = append(musts, fmt.Sprintf(query_bool_must, "s_winner", `"`+strings.Join(scd.Winner, `","`)+`"`))
|
|
|
- }
|
|
|
- _minPrice := ""
|
|
|
- _maxPrice := ""
|
|
|
- if scd.MinPrice != "" || scd.MaxPrice != "" {
|
|
|
- sq := ``
|
|
|
- if scd.MinPrice != "" {
|
|
|
- min, _ := strconv.ParseFloat(scd.MinPrice, 64)
|
|
|
- _minPrice = fmt.Sprintf("%.0f", min*10000)
|
|
|
- if _minPrice == "0" {
|
|
|
- _minPrice = ""
|
|
|
- }
|
|
|
- }
|
|
|
- if scd.MaxPrice != "" {
|
|
|
- max, _ := strconv.ParseFloat(scd.MaxPrice, 64)
|
|
|
- _maxPrice = fmt.Sprintf("%.0f", max*10000)
|
|
|
- if _maxPrice == "0" {
|
|
|
- _maxPrice = ""
|
|
|
- }
|
|
|
- }
|
|
|
- if _minPrice != "" {
|
|
|
- sq += fmt.Sprintf(gte, _minPrice)
|
|
|
- }
|
|
|
- if _minPrice != "" && _maxPrice != "" {
|
|
|
- sq += `,`
|
|
|
- }
|
|
|
- if _maxPrice != "" {
|
|
|
- sq += fmt.Sprintf(lte, _maxPrice)
|
|
|
- }
|
|
|
- if _minPrice != "" || _maxPrice != "" {
|
|
|
- query_price := fmt.Sprintf(query_bool_should, fmt.Sprintf(query_price, sq, sq))
|
|
|
- musts = append(musts, query_price)
|
|
|
- }
|
|
|
- }
|
|
|
- boolsNum := 0
|
|
|
- //should
|
|
|
- if len(scd.Keyword) > 0 {
|
|
|
- boolsNum = 1
|
|
|
- if scd.SelectType == "" || scd.SelectType == "all" {
|
|
|
- scd.SelectType = "detail\", \"title"
|
|
|
- }
|
|
|
- multi_match = fmt.Sprintf(multi_match, "%s", "\""+scd.SelectType+"\"")
|
|
|
-
|
|
|
- if scd.Comeinfrom == "supersearchPage" {
|
|
|
- var keywordArr []string
|
|
|
- if strings.Contains(scd.Keyword[0].Keyword, "+") {
|
|
|
- keywordArr = strings.Split(scd.Keyword[0].Keyword, "+")
|
|
|
- } else if strings.Contains(scd.Keyword[0].Keyword, " ") {
|
|
|
- keywordArr = strings.Split(scd.Keyword[0].Keyword, " ")
|
|
|
- }
|
|
|
- if len(keywordArr) > 1 {
|
|
|
- KeyWordSearch := KeyWord{}
|
|
|
- for _, v := range keywordArr {
|
|
|
- KeyWordSearch.Appended = append(KeyWordSearch.Appended, v)
|
|
|
- }
|
|
|
- scd.Keyword = []KeyWord{KeyWordSearch}
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- for _, v := range scd.Keyword {
|
|
|
- shoulds := []string{}
|
|
|
- must_not := []string{}
|
|
|
- //附加词
|
|
|
- if v.Keyword != "" {
|
|
|
- shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+v.Keyword+"\""))
|
|
|
- }
|
|
|
-
|
|
|
- for _, vv := range v.Appended {
|
|
|
- shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+vv+"\""))
|
|
|
- }
|
|
|
-
|
|
|
- //排除词
|
|
|
- for _, vv := range v.Exclude {
|
|
|
- must_not = append(must_not, fmt.Sprintf(multi_match, "\""+vv+"\""))
|
|
|
- }
|
|
|
-
|
|
|
- //添加
|
|
|
- if len(shoulds) > 0 {
|
|
|
- notStr := ""
|
|
|
- if len(must_not) > 0 {
|
|
|
- notStr = fmt.Sprintf(`,"must_not":[%s]`, strings.Join(must_not, ","))
|
|
|
- }
|
|
|
- bools = append(bools, fmt.Sprintf(query_bool_must_and, strings.Join(shoulds, ","), notStr))
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- qstr := fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(bools, ","), boolsNum)
|
|
|
- return qstr
|
|
|
-}
|
|
|
-
|
|
|
-func GetSqlObjFromId(_id string) *SieveCondition {
|
|
|
- var (
|
|
|
- query *map[string]interface{}
|
|
|
- ok bool
|
|
|
- )
|
|
|
- if query, ok = util.MQFW.FindById(ExportTable, _id, nil); !ok {
|
|
|
- return nil
|
|
|
- }
|
|
|
- return &SieveCondition{
|
|
|
- Id: _id,
|
|
|
- Keyword: getKeyWordArrFromDbResult((*query)["keywords"]),
|
|
|
- Industry: getStringArrFromDbResult((*query)["industry"]),
|
|
|
- MinPrice: qutil.ObjToString((*query)["minprice"]),
|
|
|
- MaxPrice: qutil.ObjToString((*query)["maxprice"]),
|
|
|
- Subtype: qutil.ObjToString((*query)["subtype"]),
|
|
|
- Area: getStringArrFromDbResult((*query)["area"]),
|
|
|
- City: getStringArrFromDbResult((*query)["city"]),
|
|
|
- SelectType: qutil.ObjToString((*query)["selectType"]),
|
|
|
- PublishTime: qutil.ObjToString((*query)["publishtime"]),
|
|
|
- Buyer: getStringArrFromDbResult((*query)["buyer"]),
|
|
|
- Buyerclass: getStringArrFromDbResult((*query)["buyerclass"]),
|
|
|
- Winner: getStringArrFromDbResult((*query)["winner"]),
|
|
|
- ComeInTime: qutil.Int64All((*query)["comeintime"]),
|
|
|
- Comeinfrom: qutil.ObjToString((*query)["comeinfrom"]),
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//合并map数据,去重
|
|
|
-func delRepeatMapArr(res *[]map[string]interface{}, res2 *[]map[string]interface{}) *[]map[string]interface{} {
|
|
|
- if res != nil {
|
|
|
- for _, v := range *res {
|
|
|
- for n, m := range *res2 {
|
|
|
- if qutil.ObjToString(v["_id"]) == qutil.ObjToString(m["_id"]) {
|
|
|
- *res2 = append((*res2)[0:n], (*res2)[n+1:]...)
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- *res = append(*res, *res2...)
|
|
|
- } else {
|
|
|
- res = res2
|
|
|
- }
|
|
|
- return res
|
|
|
-}
|
|
|
-
|
|
|
-//查询条件是否为空
|
|
|
-func isNullSearch(scd *SieveCondition) (isNull bool) {
|
|
|
- if scd.PublishTime == "" && len(scd.Area) == 0 && len(scd.Industry) == 0 && len(scd.Keyword) == 0 && len(scd.Buyer) == 0 && len(scd.Winner) == 0 && scd.MinPrice == "" && scd.MaxPrice == "" && scd.Subtype == "" && len(scd.City) == 0 {
|
|
|
- isNull = true
|
|
|
- }
|
|
|
- return isNull
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * 数据导出 查询结果
|
|
|
- * _id 数据库查询条件记录id
|
|
|
- * dataType 1-普通字段 2-高级字段
|
|
|
- * webdomain 三级页域名
|
|
|
- * count 返回数量 (-1:预览数据查询)
|
|
|
- */
|
|
|
-var EntTable = "winner_enterprise"
|
|
|
-
|
|
|
-func GetDataExportSearchResult(id string, dataType string, checkCount int) (*[]map[string]interface{}, error) {
|
|
|
- defer qutil.Catch()
|
|
|
- var res []map[string]interface{}
|
|
|
- //获取查询语句
|
|
|
- scd := GetSqlObjFromId(id)
|
|
|
- if scd == nil {
|
|
|
- return nil, errors.New("GetDataExportSearchResult-获取查询条件")
|
|
|
- }
|
|
|
- qstr := getDataExportSql(scd)
|
|
|
- log.Printf("GetDataExportSearchResult-%s-sql:%s\n", scd.Id, qstr)
|
|
|
- //数据导出数据查询
|
|
|
- if checkCount > onceSearchCount { //分批次查询
|
|
|
- batchNum := qutil.IntAll(math.Ceil(float64(checkCount) / float64(onceSearchCount)))
|
|
|
- var searchWaitGroup = &sync.WaitGroup{}
|
|
|
- var lock sync.Mutex
|
|
|
- for n := 0; n < batchNum; n++ {
|
|
|
- searchWaitGroup.Add(1)
|
|
|
- searchPool <- true
|
|
|
- go func(start int) {
|
|
|
- defer func() {
|
|
|
- searchWaitGroup.Done()
|
|
|
- <-searchPool
|
|
|
- }()
|
|
|
- checkNum, checkOk := onceSearchCount, false
|
|
|
- if start == (batchNum - 1) {
|
|
|
- if checkCount%onceSearchCount != 0 {
|
|
|
- checkNum = checkCount % onceSearchCount
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- var tmp *[]map[string]interface{}
|
|
|
- for i := 0; i < 3; i++ {
|
|
|
- tmp = doSearch(qstr, start*onceSearchCount, onceSearchCount, dataType)
|
|
|
- if tmp != nil && (len(*tmp) == checkNum) { //校验数据量是否够
|
|
|
- checkOk = true
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- if tmp == nil {
|
|
|
- log.Printf("GetDataExportSearchResult-%s-第%d页数据查询结果为空\n", scd.Id, start+1)
|
|
|
- return
|
|
|
- }
|
|
|
- if checkOk {
|
|
|
- log.Printf("GetDataExportSearchResult-%s-第%d页数据加载完成,共%d条\n", scd.Id, start+1, len(*tmp))
|
|
|
- } else {
|
|
|
- log.Printf("GetDataExportSearchResult-%s-第%d页数据加载异常,共%d条,预期%d条\n", scd.Id, start+1, len(*tmp), checkNum)
|
|
|
- }
|
|
|
- lock.Lock()
|
|
|
- res = append(res, *tmp...)
|
|
|
- lock.Unlock()
|
|
|
- }(n)
|
|
|
- }
|
|
|
- searchWaitGroup.Wait()
|
|
|
- log.Printf("GetDataExportSearchResult-%s-分批次加载数据总量为%d\n", scd.Id, len(res))
|
|
|
- } else {
|
|
|
- tmp := doSearch(qstr, 0, checkCount, dataType)
|
|
|
- if tmp == nil || len(*tmp) == 0 {
|
|
|
- log.Printf("GetDataExportSearchResult-%s-一次性加载数据异常\n", scd.Id)
|
|
|
- } else {
|
|
|
- res = *tmp
|
|
|
- log.Printf("GetDataExportSearchResult-%s-一次性加载数据总量为%d\n", scd.Id, len(res))
|
|
|
- }
|
|
|
- }
|
|
|
- //超级搜索一致的检索(防止数据导出和超级搜索数据量不一致)
|
|
|
- if scd.Comeinfrom == "supersearchPage" && (len(scd.Keyword) != 0 || len(scd.Industry) != 0) {
|
|
|
- if len(scd.Keyword) != 0 {
|
|
|
- num := len(res)
|
|
|
- searchTextSize := 0
|
|
|
- if len(scd.Keyword) > 0 {
|
|
|
- searchTextSize = len([]rune(scd.Keyword[0].Keyword))
|
|
|
- }
|
|
|
- if searchTextSize > 3 && num < 50 {
|
|
|
- secondKWS := jy.HttpEs(scd.Keyword[0].Keyword, "ik_smart", config.Config.Elasticsearch)
|
|
|
- scd.Keyword[0].Keyword = secondKWS
|
|
|
- scd.SelectType = "title"
|
|
|
- qstr = getDataExportSql(scd)
|
|
|
- log.Printf("GetDataExportSearchResult-%s-分词查询-sql:%s\n", scd.Id, qstr)
|
|
|
- res2 := doSearch(qstr, 0, 100, "")
|
|
|
- res = *delRepeatMapArr(&res, res2)
|
|
|
- if len(res) > 100 {
|
|
|
- res = res[:100]
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- //校验数量
|
|
|
- if checkCount != len(res) {
|
|
|
- return nil, fmt.Errorf("GetDataExportSearchResult-%s-数据总量校验异常,期望:%d,实际:%d", scd.Id, checkCount, len(res))
|
|
|
- //发邮件
|
|
|
- }
|
|
|
-
|
|
|
- var EntArr = []string{}
|
|
|
- for _, v := range res {
|
|
|
- //高级字段查询且winner不为空
|
|
|
- if v["s_winner"] != nil && v["s_winner"] != "" && dataType == "2" {
|
|
|
- EntArr = append(EntArr, v["s_winner"].(string))
|
|
|
- }
|
|
|
- }
|
|
|
- res = *FormatExportData(&res, config.Config.WebDomain, dataType, EntArr)
|
|
|
- return &res, nil
|
|
|
-}
|
|
|
-
|
|
|
-//数据导出-查询结果数量
|
|
|
-func GetDataExportSearchCountUseId(id string) (count int) {
|
|
|
- scd := GetSqlObjFromId(id) //用户筛选条件
|
|
|
- qstr := getDataExportSql(scd)
|
|
|
- if isNullSearch(scd) {
|
|
|
- return config.ExConf.MsgMaxCount
|
|
|
- }
|
|
|
- log.Printf("GetDataExportSearchCountUseId-%s-sql:%s\n", scd.Id, qstr)
|
|
|
- count = int(elastic.Count(INDEX, TYPE, qstr))
|
|
|
- //超级搜索一致的检索(防止数据导出和超级搜索数据量不一致)
|
|
|
- if scd.Comeinfrom == "supersearchPage" && (len(scd.Keyword) != 0 || len(scd.Industry) != 0) {
|
|
|
- if len(scd.Keyword) != 0 {
|
|
|
- searchTextSize := 0
|
|
|
- if len(scd.Keyword) > 0 {
|
|
|
- searchTextSize = len([]rune(scd.Keyword[0].Keyword))
|
|
|
- }
|
|
|
- if searchTextSize > 3 && count < 50 {
|
|
|
- var res *[]map[string]interface{}
|
|
|
- if count > 0 {
|
|
|
- res = doSearch(qstr, 0, count, "")
|
|
|
- }
|
|
|
- secondKWS := jy.HttpEs(scd.Keyword[0].Keyword, "ik_smart", config.Config.Elasticsearch)
|
|
|
- scd.Keyword[0].Keyword = secondKWS
|
|
|
- scd.SelectType = "title"
|
|
|
- qstr = getDataExportSql(scd)
|
|
|
- res2 := doSearch(qstr, 0, 100, "")
|
|
|
- result := len(*delRepeatMapArr(res, res2))
|
|
|
- if result > 100 {
|
|
|
- result = 100
|
|
|
- }
|
|
|
- log.Printf("GetDataExportSearchCountUseId-%s-count:%d-分词-sql:%s\n", scd.Id, result, qstr)
|
|
|
- return result
|
|
|
- }
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
- log.Printf("GetDataExportSearchCountUseId-%s-count:%d\n", scd.Id, count)
|
|
|
- return
|
|
|
-}
|
|
|
-
|
|
|
-func FormatExportData(data *[]map[string]interface{}, webdomain string, dataType string, EntArr []string) *[]map[string]interface{} {
|
|
|
- //格式化输出
|
|
|
- for _, v := range *data {
|
|
|
- //有中标企业 且 高级字段查询
|
|
|
- if len(EntArr) > 0 && dataType == "2" {
|
|
|
- //查询企业公示 法人 公司电话 公司邮箱地址
|
|
|
- query := bson.M{"company_name": bson.M{"$in": EntArr}} //
|
|
|
- if entData, ok := util.MQFWENT.Find(EntTable, query, nil, `{"company_name":1,"company_email":1,"legal_person":1,"company_phone":1}`, false, -1, -1); ok {
|
|
|
- if entData != nil && *entData != nil && len(*entData) > 0 {
|
|
|
- for _, ev := range *entData {
|
|
|
- if v["s_winner"] == ev["company_name"] {
|
|
|
- legal_person := ""
|
|
|
- if ev["legal_person"] != nil {
|
|
|
- legal_person = ev["legal_person"].(string)
|
|
|
- }
|
|
|
- company_phone := ""
|
|
|
- if ev["company_phone"] != nil {
|
|
|
- company_phone = ev["company_phone"].(string)
|
|
|
- }
|
|
|
- company_email := ""
|
|
|
- if ev["company_email"] != nil && ev["company_email"] != "无" {
|
|
|
- company_email = ev["company_email"].(string)
|
|
|
- }
|
|
|
- v["legal_person"] = legal_person
|
|
|
- v["company_phone"] = company_phone
|
|
|
- v["company_email"] = company_email
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- //====================字段补漏=========================
|
|
|
- if v["toptype"] == "结果" && dataType == "2" && !(v["agency"] != nil && v["budget"] != nil && v["buyerperson"] != nil && v["buyertel"] != nil) {
|
|
|
- r := elastic.Get("projectset", "projectset", fmt.Sprintf(`{"query":{"term":{"list.infoid":"%s"}},"_source": ["list"]}`, v["_id"]))
|
|
|
- if len(*r) > 0 {
|
|
|
- MsgList := (*r)[0]["list"]
|
|
|
- if MsgList != nil {
|
|
|
- list := qutil.ObjArrToMapArr(MsgList.([]interface{}))
|
|
|
- for _, vv := range list {
|
|
|
- if vv["subtype"] == "招标" {
|
|
|
- if v["agency"] == nil && vv["agency"] != nil {
|
|
|
- v["agency"] = vv["agency"]
|
|
|
- }
|
|
|
- if v["budget"] == nil && vv["budget"] != nil {
|
|
|
- v["budget"] = vv["budget"]
|
|
|
- }
|
|
|
- if v["buyerperson"] == nil && vv["buyerperson"] != nil {
|
|
|
- v["buyerperson"] = vv["buyerperson"]
|
|
|
- }
|
|
|
- if v["buyertel"] == nil && vv["buyertel"] != nil {
|
|
|
- v["buyertel"] = vv["buyertel"]
|
|
|
- }
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if v["area"] == "A" {
|
|
|
- v["area"] = "全国"
|
|
|
- }
|
|
|
- if v["bidamount"] != nil {
|
|
|
- v["bidamount"] = formatFloat(qutil.Float64All(v["bidamount"]))
|
|
|
- }
|
|
|
- if v["budget"] != nil {
|
|
|
- v["budget"] = formatFloat(qutil.Float64All(v["budget"]))
|
|
|
- }
|
|
|
- if v["publishtime"] != nil {
|
|
|
- date := v["publishtime"]
|
|
|
- v["publishtime"] = qutil.FormatDateWithObj(&date, qutil.Date_Short_Layout)
|
|
|
- }
|
|
|
- if v["bidopentime"] != nil {
|
|
|
- date := v["bidopentime"]
|
|
|
- v["bidopentime"] = qutil.FormatDateWithObj(&date, qutil.Date_Short_Layout)
|
|
|
- }
|
|
|
- if v["_id"] != nil {
|
|
|
- v["url"] = webdomain + "/article/content/" + qutil.CommonEncodeArticle("content", v["_id"].(string)) + ".html"
|
|
|
- }
|
|
|
- if v["currency"] == "" || v["currency"] == nil {
|
|
|
- v["currency"] = "人民币"
|
|
|
- }
|
|
|
- if v["subtype"] == nil && v["toptype"] != nil {
|
|
|
- v["subtype"] = v["toptype"]
|
|
|
- }
|
|
|
- }
|
|
|
- return data
|
|
|
-}
|
|
|
-
|
|
|
-//保留到0.01分
|
|
|
-func formatFloat(value float64) string {
|
|
|
- str := strings.TrimRight(fmt.Sprintf("%.7f", value*10000/100000000), "0")
|
|
|
- if str[len(str)-1:] == "." {
|
|
|
- return str[:len(str)-1]
|
|
|
- }
|
|
|
- return str
|
|
|
-}
|
|
|
-
|
|
|
-func doSearch(sql string, start, count int, dataType string) *[]map[string]interface{} {
|
|
|
- if sql != "" {
|
|
|
- //筛选字段
|
|
|
- if dataType != "" {
|
|
|
- dataexport_field := `"_id","title","detail","area","city","publishtime","projectname","buyer","s_winner","bidamount","subtype","toptype"`
|
|
|
- if dataType == "2" {
|
|
|
- dataexport_field += `,"href","projectcode","buyerperson","buyertel","budget","bidopentime","agency","projectscope","winnerperson","winnertel"`
|
|
|
- }
|
|
|
- sql = sql[:len(sql)-1] + `,"_source":[` + dataexport_field + "]}"
|
|
|
- }
|
|
|
- //分页排序
|
|
|
- sql = sql[:len(sql)-1] + `,"sort": {"publishtime":"desc"},"from":` + strconv.Itoa(start) + `,"size":` + strconv.Itoa(count) + "}"
|
|
|
- }
|
|
|
- return elastic.Get(INDEX, TYPE, sql)
|
|
|
-}
|
|
|
-
|
|
|
-func getKeyWordArrFromDbResult(k interface{}) (arr []KeyWord) {
|
|
|
- if k == nil {
|
|
|
- return
|
|
|
- }
|
|
|
- kArr := k.([]interface{})
|
|
|
- for _, v := range kArr {
|
|
|
- kw := KeyWord{}
|
|
|
- b, e := json.Marshal(v)
|
|
|
- if e != nil {
|
|
|
- log.Println(e.Error())
|
|
|
- }
|
|
|
- json.Unmarshal(b, &kw)
|
|
|
- arr = append(arr, kw)
|
|
|
- }
|
|
|
- return
|
|
|
-}
|
|
|
-
|
|
|
-func getStringArrFromDbResult(c interface{}) (arr []string) {
|
|
|
- if c != nil {
|
|
|
- cArr := c.([]interface{})
|
|
|
- arr = qutil.ObjArrToStringArr(cArr)
|
|
|
- }
|
|
|
- return
|
|
|
-}
|
|
|
+//
|
|
|
+//import (
|
|
|
+// "config"
|
|
|
+// "encoding/json"
|
|
|
+// "errors"
|
|
|
+// "fmt"
|
|
|
+// "log"
|
|
|
+// "math"
|
|
|
+// qutil "qfw/util"
|
|
|
+// "qfw/util/elastic"
|
|
|
+// "qfw/util/jy"
|
|
|
+// "strconv"
|
|
|
+// "strings"
|
|
|
+// "sync"
|
|
|
+// "time"
|
|
|
+// "util"
|
|
|
+//
|
|
|
+// "go.mongodb.org/mongo-driver/bson"
|
|
|
+//)
|
|
|
+//
|
|
|
+///*筛选条件--关键词*/
|
|
|
+//type KeyWord struct {
|
|
|
+// Keyword string `json:"keyword"` //关键词
|
|
|
+// Appended []string `json:"appended"` //附加词
|
|
|
+// Exclude []string `json:"exclude"` //排除词
|
|
|
+//}
|
|
|
+//
|
|
|
+///*筛选条件*/
|
|
|
+//type SieveCondition struct {
|
|
|
+// Id string `json:"id"`
|
|
|
+// PublishTime string `json:"publishtime"` //发布时间
|
|
|
+// Area []string `json:"area"` //地区-省份
|
|
|
+// City []string `json:"city"` //地区-城市
|
|
|
+// Region []string `json:"region"` //地区-省份+城市
|
|
|
+// Industry []string `json:"industry"` //行业
|
|
|
+// Keyword []KeyWord `json:"keywords"` //关键词
|
|
|
+// Buyer []string `json:"buyer"` //招标单位(采购单位)
|
|
|
+// Buyerclass []string `json:"buyerclass"` //采购单位类型
|
|
|
+// Winner []string `json:"winner"` //中标单位
|
|
|
+// ComeInTime int64 `json:"comeintime"` //入库时间(秒)
|
|
|
+// OpenId string `json:"openid"` //用户openid
|
|
|
+// MinPrice string `json:"minprice"` //金额——最少
|
|
|
+// MaxPrice string `json:"maxprice"` //金额——最多
|
|
|
+// SelectType string `json:"selectType"` //筛选(正文 or 标题)
|
|
|
+// Subtype string `json:"subtype"` //信息类型
|
|
|
+// Comeinfrom string `json:"comeinfrom"` //查询来源
|
|
|
+// DisWord string `json:"disWord"` //分销系统 口令
|
|
|
+//}
|
|
|
+//
|
|
|
+////VIP订单
|
|
|
+//type VipFilter struct {
|
|
|
+// Area map[string]interface{} `json:"area"` //地区
|
|
|
+// Industry []string `json:"industry"` //
|
|
|
+// Cyclecount int `json:"cyclecount"`
|
|
|
+// Cycleunit int `json:"cycleunit"`
|
|
|
+// Ordertype int `json:"ordertype"`
|
|
|
+// Addarea map[string]interface{} `json:"addarea"` //新增地区
|
|
|
+// Addindustry []string `json:"addindustry"` //新增行业
|
|
|
+// Addareacount map[string]interface{} `json:"addareacount"` //新增地区数量
|
|
|
+// Addbuyerclasscount int `json:"addbuyerclasscount"` //新增地区数量
|
|
|
+// Buyset map[string]interface{} `json:buyset`
|
|
|
+// NewBuyset map[string]interface{} `json:newBuyset` //逻辑重写后的判断条件
|
|
|
+//}
|
|
|
+//
|
|
|
+//const (
|
|
|
+// INDEX = "bidding"
|
|
|
+// TYPE = "bidding"
|
|
|
+// bidSearch_sort = `{"publishtime":-1}`
|
|
|
+//)
|
|
|
+//
|
|
|
+//var onceSearchCount = 500
|
|
|
+//var ExportTable string = "export_search"
|
|
|
+//var searchPool = make(chan bool, 8)
|
|
|
+//
|
|
|
+////获取数据导出查询语句
|
|
|
+//func getDataExportSql(scd *SieveCondition) string {
|
|
|
+// multi_match := `{"multi_match": {"query": %s,"type": "phrase", "fields": [%s]}}`
|
|
|
+// query := `{"query":{"bool":{"must":[%s],"should":[%s],"minimum_should_match": %d}}}`
|
|
|
+// query_bool_should := `{"bool":{"should":[%s],"minimum_should_match": 1}}`
|
|
|
+// query_price := `{"bool":{"must":[{"range":{"bidamount":{%s}}}]}},{"bool":{"must":[{"range":{"budget":{%s}}}],"must_not":[{"range":{"bidamount":{"gte":-1}}}]}}`
|
|
|
+// query_bool_must := `{"terms":{"%s":[%s]}}`
|
|
|
+// query_bool_must_and := `{"bool":{"must":[%s]%s}}`
|
|
|
+// gte := `"gte": %s`
|
|
|
+// lte := `"lte": %s`
|
|
|
+//
|
|
|
+// bools := []string{}
|
|
|
+// musts := []string{fmt.Sprintf(`{"range":{"comeintime":{"lt":%d}}}`, scd.ComeInTime)}
|
|
|
+// //省份
|
|
|
+// areaCity := []string{}
|
|
|
+// if len(scd.Area) > 0 {
|
|
|
+// areaquery := `{"terms":{"area":[`
|
|
|
+// for k, v := range scd.Area {
|
|
|
+// if k > 0 {
|
|
|
+// areaquery += `,`
|
|
|
+// }
|
|
|
+// areaquery += `"` + v + `"`
|
|
|
+// }
|
|
|
+// areaquery += `]}}`
|
|
|
+// areaCity = append(areaCity, areaquery)
|
|
|
+// }
|
|
|
+// //城市
|
|
|
+// if len(scd.City) > 0 {
|
|
|
+// areaquery := `{"terms":{"city":[`
|
|
|
+// for k, v := range scd.City {
|
|
|
+// if k > 0 {
|
|
|
+// areaquery += `,`
|
|
|
+// }
|
|
|
+// areaquery += `"` + v + `"`
|
|
|
+// }
|
|
|
+// areaquery += `]}}`
|
|
|
+// areaCity = append(areaCity, areaquery)
|
|
|
+// }
|
|
|
+// if len(areaCity) > 0 {
|
|
|
+// musts = append(musts, fmt.Sprintf(query_bool_should, strings.Join(areaCity, ",")))
|
|
|
+// }
|
|
|
+// //检索日期
|
|
|
+//
|
|
|
+// starttime := ""
|
|
|
+// now := time.Unix(scd.ComeInTime, 0)
|
|
|
+// endtime := fmt.Sprintf("%d", now.Unix())
|
|
|
+// if scd.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 scd.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 scd.PublishTime == "thisyear" { //去年
|
|
|
+// starttime = fmt.Sprint(time.Date(now.Year()-1, 1, 1, 0, 0, 0, 0, time.Local).Unix())
|
|
|
+// endtime = fmt.Sprint(time.Date(now.Year()-1, 12, 31, 23, 59, 59, 0, time.Local).Unix())
|
|
|
+// } else if strings.Contains(scd.PublishTime, "_") { //设置检索日期
|
|
|
+// starttime = strings.Split(scd.PublishTime, "_")[0]
|
|
|
+// endTime_tmp := now
|
|
|
+// if etime := strings.Split(scd.PublishTime, "_")[1]; etime != "" {
|
|
|
+// etTime := time.Unix(qutil.Int64All(etime), 0)
|
|
|
+// endTime_tmp = time.Date(etTime.Year(), etTime.Month(), etTime.Day()+1, 0, 0, 0, 0, time.Local)
|
|
|
+// }
|
|
|
+// //结束时间必须小于筛选时间
|
|
|
+// if endTime_tmp.After(now) {
|
|
|
+// endTime_tmp = now
|
|
|
+// }
|
|
|
+// endtime = fmt.Sprintf("%d", endTime_tmp.Unix())
|
|
|
+// }
|
|
|
+// timequery := `{"range":{"publishtime":{`
|
|
|
+// if starttime != "" {
|
|
|
+// timequery += `"gte":` + starttime
|
|
|
+// }
|
|
|
+// if starttime != "" && endtime != "" {
|
|
|
+// timequery += `,`
|
|
|
+// }
|
|
|
+// if endtime != "" {
|
|
|
+// timequery += `"lt":` + endtime
|
|
|
+// }
|
|
|
+// timequery += `}}}`
|
|
|
+// musts = append(musts, timequery)
|
|
|
+//
|
|
|
+// if scd.Subtype != "" {
|
|
|
+// subquery := `{"terms":{"subtype":[`
|
|
|
+// for k, v := range strings.Split(scd.Subtype, ",") {
|
|
|
+// if k > 0 {
|
|
|
+// subquery += `,`
|
|
|
+// }
|
|
|
+// subquery += `"` + v + `"`
|
|
|
+// }
|
|
|
+// subquery += `]}}`
|
|
|
+// musts = append(musts, subquery)
|
|
|
+// }
|
|
|
+// if len(scd.Industry) > 0 {
|
|
|
+// musts = append(musts, fmt.Sprintf(query_bool_must, "s_subscopeclass", `"`+strings.Join(scd.Industry, `","`)+`"`))
|
|
|
+// }
|
|
|
+// if len(scd.Buyer) > 0 {
|
|
|
+// musts = append(musts, fmt.Sprintf(query_bool_must, "buyer", `"`+strings.Join(scd.Buyer, `","`)+`"`))
|
|
|
+// }
|
|
|
+// if len(scd.Buyerclass) > 0 {
|
|
|
+// musts = append(musts, fmt.Sprintf(query_bool_must, "buyerclass", `"`+strings.Join(scd.Buyerclass, `","`)+`"`))
|
|
|
+// }
|
|
|
+// if len(scd.Winner) > 0 {
|
|
|
+// musts = append(musts, fmt.Sprintf(query_bool_must, "s_winner", `"`+strings.Join(scd.Winner, `","`)+`"`))
|
|
|
+// }
|
|
|
+// _minPrice := ""
|
|
|
+// _maxPrice := ""
|
|
|
+// if scd.MinPrice != "" || scd.MaxPrice != "" {
|
|
|
+// sq := ``
|
|
|
+// if scd.MinPrice != "" {
|
|
|
+// min, _ := strconv.ParseFloat(scd.MinPrice, 64)
|
|
|
+// _minPrice = fmt.Sprintf("%.0f", min*10000)
|
|
|
+// if _minPrice == "0" {
|
|
|
+// _minPrice = ""
|
|
|
+// }
|
|
|
+// }
|
|
|
+// if scd.MaxPrice != "" {
|
|
|
+// max, _ := strconv.ParseFloat(scd.MaxPrice, 64)
|
|
|
+// _maxPrice = fmt.Sprintf("%.0f", max*10000)
|
|
|
+// if _maxPrice == "0" {
|
|
|
+// _maxPrice = ""
|
|
|
+// }
|
|
|
+// }
|
|
|
+// if _minPrice != "" {
|
|
|
+// sq += fmt.Sprintf(gte, _minPrice)
|
|
|
+// }
|
|
|
+// if _minPrice != "" && _maxPrice != "" {
|
|
|
+// sq += `,`
|
|
|
+// }
|
|
|
+// if _maxPrice != "" {
|
|
|
+// sq += fmt.Sprintf(lte, _maxPrice)
|
|
|
+// }
|
|
|
+// if _minPrice != "" || _maxPrice != "" {
|
|
|
+// query_price := fmt.Sprintf(query_bool_should, fmt.Sprintf(query_price, sq, sq))
|
|
|
+// musts = append(musts, query_price)
|
|
|
+// }
|
|
|
+// }
|
|
|
+// boolsNum := 0
|
|
|
+// //should
|
|
|
+// if len(scd.Keyword) > 0 {
|
|
|
+// boolsNum = 1
|
|
|
+// if scd.SelectType == "" || scd.SelectType == "all" {
|
|
|
+// scd.SelectType = "detail\", \"title"
|
|
|
+// }
|
|
|
+// multi_match = fmt.Sprintf(multi_match, "%s", "\""+scd.SelectType+"\"")
|
|
|
+//
|
|
|
+// if scd.Comeinfrom == "supersearchPage" {
|
|
|
+// var keywordArr []string
|
|
|
+// if strings.Contains(scd.Keyword[0].Keyword, "+") {
|
|
|
+// keywordArr = strings.Split(scd.Keyword[0].Keyword, "+")
|
|
|
+// } else if strings.Contains(scd.Keyword[0].Keyword, " ") {
|
|
|
+// keywordArr = strings.Split(scd.Keyword[0].Keyword, " ")
|
|
|
+// }
|
|
|
+// if len(keywordArr) > 1 {
|
|
|
+// KeyWordSearch := KeyWord{}
|
|
|
+// for _, v := range keywordArr {
|
|
|
+// KeyWordSearch.Appended = append(KeyWordSearch.Appended, v)
|
|
|
+// }
|
|
|
+// scd.Keyword = []KeyWord{KeyWordSearch}
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// for _, v := range scd.Keyword {
|
|
|
+// shoulds := []string{}
|
|
|
+// must_not := []string{}
|
|
|
+// //附加词
|
|
|
+// if v.Keyword != "" {
|
|
|
+// shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+v.Keyword+"\""))
|
|
|
+// }
|
|
|
+//
|
|
|
+// for _, vv := range v.Appended {
|
|
|
+// shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+vv+"\""))
|
|
|
+// }
|
|
|
+//
|
|
|
+// //排除词
|
|
|
+// for _, vv := range v.Exclude {
|
|
|
+// must_not = append(must_not, fmt.Sprintf(multi_match, "\""+vv+"\""))
|
|
|
+// }
|
|
|
+//
|
|
|
+// //添加
|
|
|
+// if len(shoulds) > 0 {
|
|
|
+// notStr := ""
|
|
|
+// if len(must_not) > 0 {
|
|
|
+// notStr = fmt.Sprintf(`,"must_not":[%s]`, strings.Join(must_not, ","))
|
|
|
+// }
|
|
|
+// bools = append(bools, fmt.Sprintf(query_bool_must_and, strings.Join(shoulds, ","), notStr))
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// qstr := fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(bools, ","), boolsNum)
|
|
|
+// return qstr
|
|
|
+//}
|
|
|
+//
|
|
|
+//func GetSqlObjFromId(_id string) *SieveCondition {
|
|
|
+// var (
|
|
|
+// query *map[string]interface{}
|
|
|
+// ok bool
|
|
|
+// )
|
|
|
+// if query, ok = util.MQFW.FindById(ExportTable, _id, nil); !ok {
|
|
|
+// return nil
|
|
|
+// }
|
|
|
+// return &SieveCondition{
|
|
|
+// Id: _id,
|
|
|
+// Keyword: getKeyWordArrFromDbResult((*query)["keywords"]),
|
|
|
+// Industry: getStringArrFromDbResult((*query)["industry"]),
|
|
|
+// MinPrice: qutil.ObjToString((*query)["minprice"]),
|
|
|
+// MaxPrice: qutil.ObjToString((*query)["maxprice"]),
|
|
|
+// Subtype: qutil.ObjToString((*query)["subtype"]),
|
|
|
+// Area: getStringArrFromDbResult((*query)["area"]),
|
|
|
+// City: getStringArrFromDbResult((*query)["city"]),
|
|
|
+// SelectType: qutil.ObjToString((*query)["selectType"]),
|
|
|
+// PublishTime: qutil.ObjToString((*query)["publishtime"]),
|
|
|
+// Buyer: getStringArrFromDbResult((*query)["buyer"]),
|
|
|
+// Buyerclass: getStringArrFromDbResult((*query)["buyerclass"]),
|
|
|
+// Winner: getStringArrFromDbResult((*query)["winner"]),
|
|
|
+// ComeInTime: qutil.Int64All((*query)["comeintime"]),
|
|
|
+// Comeinfrom: qutil.ObjToString((*query)["comeinfrom"]),
|
|
|
+// }
|
|
|
+//}
|
|
|
+//
|
|
|
+////合并map数据,去重
|
|
|
+//func delRepeatMapArr(res *[]map[string]interface{}, res2 *[]map[string]interface{}) *[]map[string]interface{} {
|
|
|
+// if res != nil {
|
|
|
+// for _, v := range *res {
|
|
|
+// for n, m := range *res2 {
|
|
|
+// if qutil.ObjToString(v["_id"]) == qutil.ObjToString(m["_id"]) {
|
|
|
+// *res2 = append((*res2)[0:n], (*res2)[n+1:]...)
|
|
|
+// break
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// *res = append(*res, *res2...)
|
|
|
+// } else {
|
|
|
+// res = res2
|
|
|
+// }
|
|
|
+// return res
|
|
|
+//}
|
|
|
+//
|
|
|
+////查询条件是否为空
|
|
|
+//func isNullSearch(scd *SieveCondition) (isNull bool) {
|
|
|
+// if scd.PublishTime == "" && len(scd.Area) == 0 && len(scd.Industry) == 0 && len(scd.Keyword) == 0 && len(scd.Buyer) == 0 && len(scd.Winner) == 0 && scd.MinPrice == "" && scd.MaxPrice == "" && scd.Subtype == "" && len(scd.City) == 0 {
|
|
|
+// isNull = true
|
|
|
+// }
|
|
|
+// return isNull
|
|
|
+//}
|
|
|
+//
|
|
|
+///*
|
|
|
+// * 数据导出 查询结果
|
|
|
+// * _id 数据库查询条件记录id
|
|
|
+// * dataType 1-普通字段 2-高级字段
|
|
|
+// * webdomain 三级页域名
|
|
|
+// * count 返回数量 (-1:预览数据查询)
|
|
|
+// */
|
|
|
+//var EntTable = "winner_enterprise"
|
|
|
+//
|
|
|
+//func GetDataExportSearchResult(id string, dataType string, checkCount int) (*[]map[string]interface{}, error) {
|
|
|
+// defer qutil.Catch()
|
|
|
+// var res []map[string]interface{}
|
|
|
+// //获取查询语句
|
|
|
+// scd := GetSqlObjFromId(id)
|
|
|
+// if scd == nil {
|
|
|
+// return nil, errors.New("GetDataExportSearchResult-获取查询条件")
|
|
|
+// }
|
|
|
+// qstr := getDataExportSql(scd)
|
|
|
+// log.Printf("GetDataExportSearchResult-%s-sql:%s\n", scd.Id, qstr)
|
|
|
+// //数据导出数据查询
|
|
|
+// if checkCount > onceSearchCount { //分批次查询
|
|
|
+// batchNum := qutil.IntAll(math.Ceil(float64(checkCount) / float64(onceSearchCount)))
|
|
|
+// var searchWaitGroup = &sync.WaitGroup{}
|
|
|
+// var lock sync.Mutex
|
|
|
+// for n := 0; n < batchNum; n++ {
|
|
|
+// searchWaitGroup.Add(1)
|
|
|
+// searchPool <- true
|
|
|
+// go func(start int) {
|
|
|
+// defer func() {
|
|
|
+// searchWaitGroup.Done()
|
|
|
+// <-searchPool
|
|
|
+// }()
|
|
|
+// checkNum, checkOk := onceSearchCount, false
|
|
|
+// if start == (batchNum - 1) {
|
|
|
+// if checkCount%onceSearchCount != 0 {
|
|
|
+// checkNum = checkCount % onceSearchCount
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// var tmp *[]map[string]interface{}
|
|
|
+// for i := 0; i < 3; i++ {
|
|
|
+// tmp = doSearch(qstr, start*onceSearchCount, onceSearchCount, dataType)
|
|
|
+// if tmp != nil && (len(*tmp) == checkNum) { //校验数据量是否够
|
|
|
+// checkOk = true
|
|
|
+// break
|
|
|
+// }
|
|
|
+// }
|
|
|
+// if tmp == nil {
|
|
|
+// log.Printf("GetDataExportSearchResult-%s-第%d页数据查询结果为空\n", scd.Id, start+1)
|
|
|
+// return
|
|
|
+// }
|
|
|
+// if checkOk {
|
|
|
+// log.Printf("GetDataExportSearchResult-%s-第%d页数据加载完成,共%d条\n", scd.Id, start+1, len(*tmp))
|
|
|
+// } else {
|
|
|
+// log.Printf("GetDataExportSearchResult-%s-第%d页数据加载异常,共%d条,预期%d条\n", scd.Id, start+1, len(*tmp), checkNum)
|
|
|
+// }
|
|
|
+// lock.Lock()
|
|
|
+// res = append(res, *tmp...)
|
|
|
+// lock.Unlock()
|
|
|
+// }(n)
|
|
|
+// }
|
|
|
+// searchWaitGroup.Wait()
|
|
|
+// log.Printf("GetDataExportSearchResult-%s-分批次加载数据总量为%d\n", scd.Id, len(res))
|
|
|
+// } else {
|
|
|
+// tmp := doSearch(qstr, 0, checkCount, dataType)
|
|
|
+// if tmp == nil || len(*tmp) == 0 {
|
|
|
+// log.Printf("GetDataExportSearchResult-%s-一次性加载数据异常\n", scd.Id)
|
|
|
+// } else {
|
|
|
+// res = *tmp
|
|
|
+// log.Printf("GetDataExportSearchResult-%s-一次性加载数据总量为%d\n", scd.Id, len(res))
|
|
|
+// }
|
|
|
+// }
|
|
|
+// //超级搜索一致的检索(防止数据导出和超级搜索数据量不一致)
|
|
|
+// if scd.Comeinfrom == "supersearchPage" && (len(scd.Keyword) != 0 || len(scd.Industry) != 0) {
|
|
|
+// if len(scd.Keyword) != 0 {
|
|
|
+// num := len(res)
|
|
|
+// searchTextSize := 0
|
|
|
+// if len(scd.Keyword) > 0 {
|
|
|
+// searchTextSize = len([]rune(scd.Keyword[0].Keyword))
|
|
|
+// }
|
|
|
+// if searchTextSize > 3 && num < 50 {
|
|
|
+// secondKWS := jy.HttpEs(scd.Keyword[0].Keyword, "ik_smart", config.Config.Elasticsearch)
|
|
|
+// scd.Keyword[0].Keyword = secondKWS
|
|
|
+// scd.SelectType = "title"
|
|
|
+// qstr = getDataExportSql(scd)
|
|
|
+// log.Printf("GetDataExportSearchResult-%s-分词查询-sql:%s\n", scd.Id, qstr)
|
|
|
+// res2 := doSearch(qstr, 0, 100, "")
|
|
|
+// res = *delRepeatMapArr(&res, res2)
|
|
|
+// if len(res) > 100 {
|
|
|
+// res = res[:100]
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// //校验数量
|
|
|
+// if checkCount != len(res) {
|
|
|
+// return nil, fmt.Errorf("GetDataExportSearchResult-%s-数据总量校验异常,期望:%d,实际:%d", scd.Id, checkCount, len(res))
|
|
|
+// //发邮件
|
|
|
+// }
|
|
|
+//
|
|
|
+// var EntArr = []string{}
|
|
|
+// for _, v := range res {
|
|
|
+// //高级字段查询且winner不为空
|
|
|
+// if v["s_winner"] != nil && v["s_winner"] != "" && dataType == "2" {
|
|
|
+// EntArr = append(EntArr, v["s_winner"].(string))
|
|
|
+// }
|
|
|
+// }
|
|
|
+// res = *FormatExportData(&res, config.Config.WebDomain, dataType, EntArr)
|
|
|
+// return &res, nil
|
|
|
+//}
|
|
|
+//
|
|
|
+////数据导出-查询结果数量
|
|
|
+//func GetDataExportSearchCountUseId(id string) (count int) {
|
|
|
+// scd := GetSqlObjFromId(id) //用户筛选条件
|
|
|
+// qstr := getDataExportSql(scd)
|
|
|
+// if isNullSearch(scd) {
|
|
|
+// return config.ExConf.MsgMaxCount
|
|
|
+// }
|
|
|
+// log.Printf("GetDataExportSearchCountUseId-%s-sql:%s\n", scd.Id, qstr)
|
|
|
+// count = int(elastic.Count(INDEX, TYPE, qstr))
|
|
|
+// //超级搜索一致的检索(防止数据导出和超级搜索数据量不一致)
|
|
|
+// if scd.Comeinfrom == "supersearchPage" && (len(scd.Keyword) != 0 || len(scd.Industry) != 0) {
|
|
|
+// if len(scd.Keyword) != 0 {
|
|
|
+// searchTextSize := 0
|
|
|
+// if len(scd.Keyword) > 0 {
|
|
|
+// searchTextSize = len([]rune(scd.Keyword[0].Keyword))
|
|
|
+// }
|
|
|
+// if searchTextSize > 3 && count < 50 {
|
|
|
+// var res *[]map[string]interface{}
|
|
|
+// if count > 0 {
|
|
|
+// res = doSearch(qstr, 0, count, "")
|
|
|
+// }
|
|
|
+// secondKWS := jy.HttpEs(scd.Keyword[0].Keyword, "ik_smart", config.Config.Elasticsearch)
|
|
|
+// scd.Keyword[0].Keyword = secondKWS
|
|
|
+// scd.SelectType = "title"
|
|
|
+// qstr = getDataExportSql(scd)
|
|
|
+// res2 := doSearch(qstr, 0, 100, "")
|
|
|
+// result := len(*delRepeatMapArr(res, res2))
|
|
|
+// if result > 100 {
|
|
|
+// result = 100
|
|
|
+// }
|
|
|
+// log.Printf("GetDataExportSearchCountUseId-%s-count:%d-分词-sql:%s\n", scd.Id, result, qstr)
|
|
|
+// return result
|
|
|
+// }
|
|
|
+// return
|
|
|
+// }
|
|
|
+// }
|
|
|
+// log.Printf("GetDataExportSearchCountUseId-%s-count:%d\n", scd.Id, count)
|
|
|
+// return
|
|
|
+//}
|
|
|
+//
|
|
|
+//func FormatExportData(data *[]map[string]interface{}, webdomain string, dataType string, EntArr []string) *[]map[string]interface{} {
|
|
|
+// //格式化输出
|
|
|
+// for _, v := range *data {
|
|
|
+// //有中标企业 且 高级字段查询
|
|
|
+// if len(EntArr) > 0 && dataType == "2" {
|
|
|
+// //查询企业公示 法人 公司电话 公司邮箱地址
|
|
|
+// query := bson.M{"company_name": bson.M{"$in": EntArr}} //
|
|
|
+// if entData, ok := util.MQFWENT.Find(EntTable, query, nil, `{"company_name":1,"company_email":1,"legal_person":1,"company_phone":1}`, false, -1, -1); ok {
|
|
|
+// if entData != nil && *entData != nil && len(*entData) > 0 {
|
|
|
+// for _, ev := range *entData {
|
|
|
+// if v["s_winner"] == ev["company_name"] {
|
|
|
+// legal_person := ""
|
|
|
+// if ev["legal_person"] != nil {
|
|
|
+// legal_person = ev["legal_person"].(string)
|
|
|
+// }
|
|
|
+// company_phone := ""
|
|
|
+// if ev["company_phone"] != nil {
|
|
|
+// company_phone = ev["company_phone"].(string)
|
|
|
+// }
|
|
|
+// company_email := ""
|
|
|
+// if ev["company_email"] != nil && ev["company_email"] != "无" {
|
|
|
+// company_email = ev["company_email"].(string)
|
|
|
+// }
|
|
|
+// v["legal_person"] = legal_person
|
|
|
+// v["company_phone"] = company_phone
|
|
|
+// v["company_email"] = company_email
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// //====================字段补漏=========================
|
|
|
+// if v["toptype"] == "结果" && dataType == "2" && !(v["agency"] != nil && v["budget"] != nil && v["buyerperson"] != nil && v["buyertel"] != nil) {
|
|
|
+// r := elastic.Get("projectset", "projectset", fmt.Sprintf(`{"query":{"term":{"list.infoid":"%s"}},"_source": ["list"]}`, v["_id"]))
|
|
|
+// if len(*r) > 0 {
|
|
|
+// MsgList := (*r)[0]["list"]
|
|
|
+// if MsgList != nil {
|
|
|
+// list := qutil.ObjArrToMapArr(MsgList.([]interface{}))
|
|
|
+// for _, vv := range list {
|
|
|
+// if vv["subtype"] == "招标" {
|
|
|
+// if v["agency"] == nil && vv["agency"] != nil {
|
|
|
+// v["agency"] = vv["agency"]
|
|
|
+// }
|
|
|
+// if v["budget"] == nil && vv["budget"] != nil {
|
|
|
+// v["budget"] = vv["budget"]
|
|
|
+// }
|
|
|
+// if v["buyerperson"] == nil && vv["buyerperson"] != nil {
|
|
|
+// v["buyerperson"] = vv["buyerperson"]
|
|
|
+// }
|
|
|
+// if v["buyertel"] == nil && vv["buyertel"] != nil {
|
|
|
+// v["buyertel"] = vv["buyertel"]
|
|
|
+// }
|
|
|
+// break
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// if v["area"] == "A" {
|
|
|
+// v["area"] = "全国"
|
|
|
+// }
|
|
|
+// if v["bidamount"] != nil {
|
|
|
+// v["bidamount"] = formatFloat(qutil.Float64All(v["bidamount"]))
|
|
|
+// }
|
|
|
+// if v["budget"] != nil {
|
|
|
+// v["budget"] = formatFloat(qutil.Float64All(v["budget"]))
|
|
|
+// }
|
|
|
+// if v["publishtime"] != nil {
|
|
|
+// date := v["publishtime"]
|
|
|
+// v["publishtime"] = qutil.FormatDateWithObj(&date, qutil.Date_Short_Layout)
|
|
|
+// }
|
|
|
+// if v["bidopentime"] != nil {
|
|
|
+// date := v["bidopentime"]
|
|
|
+// v["bidopentime"] = qutil.FormatDateWithObj(&date, qutil.Date_Short_Layout)
|
|
|
+// }
|
|
|
+// if v["_id"] != nil {
|
|
|
+// v["url"] = webdomain + "/article/content/" + qutil.CommonEncodeArticle("content", v["_id"].(string)) + ".html"
|
|
|
+// }
|
|
|
+// if v["currency"] == "" || v["currency"] == nil {
|
|
|
+// v["currency"] = "人民币"
|
|
|
+// }
|
|
|
+// if v["subtype"] == nil && v["toptype"] != nil {
|
|
|
+// v["subtype"] = v["toptype"]
|
|
|
+// }
|
|
|
+// }
|
|
|
+// return data
|
|
|
+//}
|
|
|
+//
|
|
|
+////保留到0.01分
|
|
|
+//func formatFloat(value float64) string {
|
|
|
+// str := strings.TrimRight(fmt.Sprintf("%.7f", value*10000/100000000), "0")
|
|
|
+// if str[len(str)-1:] == "." {
|
|
|
+// return str[:len(str)-1]
|
|
|
+// }
|
|
|
+// return str
|
|
|
+//}
|
|
|
+//
|
|
|
+//func doSearch(sql string, start, count int, dataType string) *[]map[string]interface{} {
|
|
|
+// if sql != "" {
|
|
|
+// //筛选字段
|
|
|
+// if dataType != "" {
|
|
|
+// dataexport_field := `"_id","title","detail","area","city","publishtime","projectname","buyer","s_winner","bidamount","subtype","toptype"`
|
|
|
+// if dataType == "2" {
|
|
|
+// dataexport_field += `,"href","projectcode","buyerperson","buyertel","budget","bidopentime","agency","projectscope","winnerperson","winnertel"`
|
|
|
+// }
|
|
|
+// sql = sql[:len(sql)-1] + `,"_source":[` + dataexport_field + "]}"
|
|
|
+// }
|
|
|
+// //分页排序
|
|
|
+// sql = sql[:len(sql)-1] + `,"sort": {"publishtime":"desc"},"from":` + strconv.Itoa(start) + `,"size":` + strconv.Itoa(count) + "}"
|
|
|
+// }
|
|
|
+// return elastic.Get(INDEX, TYPE, sql)
|
|
|
+//}
|
|
|
+//
|
|
|
+//func getKeyWordArrFromDbResult(k interface{}) (arr []KeyWord) {
|
|
|
+// if k == nil {
|
|
|
+// return
|
|
|
+// }
|
|
|
+// kArr := k.([]interface{})
|
|
|
+// for _, v := range kArr {
|
|
|
+// kw := KeyWord{}
|
|
|
+// b, e := json.Marshal(v)
|
|
|
+// if e != nil {
|
|
|
+// log.Println(e.Error())
|
|
|
+// }
|
|
|
+// json.Unmarshal(b, &kw)
|
|
|
+// arr = append(arr, kw)
|
|
|
+// }
|
|
|
+// return
|
|
|
+//}
|
|
|
+//
|
|
|
+//func getStringArrFromDbResult(c interface{}) (arr []string) {
|
|
|
+// if c != nil {
|
|
|
+// cArr := c.([]interface{})
|
|
|
+// arr = qutil.ObjArrToStringArr(cArr)
|
|
|
+// }
|
|
|
+// return
|
|
|
+//}
|