|
@@ -2,28 +2,22 @@ package service
|
|
|
|
|
|
import (
|
|
|
"app.yhyue.com/moapp/jybase/encrypt"
|
|
|
- elastic "app.yhyue.com/moapp/jybase/es"
|
|
|
"context"
|
|
|
"fmt"
|
|
|
"github.com/gogf/gf/v2/container/gvar"
|
|
|
"github.com/gogf/gf/v2/frame/g"
|
|
|
"github.com/gogf/gf/v2/util/gconv"
|
|
|
"jyseo/utility"
|
|
|
- "strings"
|
|
|
- "time"
|
|
|
)
|
|
|
|
|
|
type (
|
|
|
SeoBiddingQuery struct {
|
|
|
+ keys string
|
|
|
area string
|
|
|
city string
|
|
|
district string
|
|
|
topType string
|
|
|
subType string
|
|
|
- industry string
|
|
|
- keys string
|
|
|
- isBuyer bool
|
|
|
- isWinner bool
|
|
|
}
|
|
|
InfoList struct {
|
|
|
Title string
|
|
@@ -31,25 +25,19 @@ type (
|
|
|
Area string
|
|
|
Industry string
|
|
|
Subtype string
|
|
|
- FileExists bool
|
|
|
- Site string //来自用户发版
|
|
|
Price string
|
|
|
PublishTime int64
|
|
|
- BuyerClass string //采购单位类型
|
|
|
- LegalPerson string //企业法人
|
|
|
- State string //中标企业状态
|
|
|
- Address string //地址
|
|
|
}
|
|
|
|
|
|
ListResp struct {
|
|
|
- Total int64
|
|
|
+ Total int
|
|
|
List []*InfoList
|
|
|
}
|
|
|
)
|
|
|
|
|
|
var (
|
|
|
- SettingPageSize = g.Cfg().MustGet(context.Background(), "listPageSetting.pageSize").Int64()
|
|
|
- SettingListTotal = g.Cfg().MustGet(context.Background(), "listPageSetting.maxTotal").Int64()
|
|
|
+ SettingPageSize = g.Cfg().MustGet(context.Background(), "listPageSetting.pageSize").Int()
|
|
|
+ SettingMaxBidSize = g.Cfg().MustGet(context.Background(), "listPageSetting.maxBidSize").Int()
|
|
|
SettingBidCacheTime = g.Cfg().MustGet(context.Background(), "listPageSetting.cacheTime").Int64()
|
|
|
topTypeMap = map[string]string{
|
|
|
"招标预告": "预告",
|
|
@@ -59,14 +47,6 @@ var (
|
|
|
}
|
|
|
)
|
|
|
|
|
|
-const (
|
|
|
- field = `"_id","title","publishtime","toptype","subtype","area","s_subscopeclass","buyerclass","budget","bidamount","isValidFile","spidercode","site"`
|
|
|
- querySql = `{"query":{"bool":{"filter":[%s],"should": [%s],"minimum_should_match": %d}},"_source":[%s],"sort":[{"publishtime":"desc"}],"size":%d}`
|
|
|
- keywords = `{"multi_match": {"query": "%s","type": "phrase", "fields": ["title","purchasing"]}}`
|
|
|
- filterBool = `{"bool":{"must":[%s],"should":[%s],"minimum_should_match": %d}}`
|
|
|
- filterRange = `{"range":{"publishtime":{"gte":%d,"lte":%d}}}`
|
|
|
-)
|
|
|
-
|
|
|
func NewBiddingQuery() *SeoBiddingQuery {
|
|
|
return &SeoBiddingQuery{}
|
|
|
}
|
|
@@ -94,48 +74,39 @@ func (query *SeoBiddingQuery) EquipSType(sTypeNode *STypeNode) *SeoBiddingQuery
|
|
|
return query
|
|
|
}
|
|
|
|
|
|
-func (query *SeoBiddingQuery) getSearchSql(total int64) string {
|
|
|
- var filterMusts, filterShould, should, filter []string
|
|
|
- now := time.Now()
|
|
|
- filter = append(filter, fmt.Sprintf(filterRange, now.AddDate(-5, 0, 0).Unix(), now.Unix())) //发版前 改成最近一年
|
|
|
- // 地区
|
|
|
+func (query *SeoBiddingQuery) getResult(ctx context.Context, total int) (int, []map[string]interface{}) {
|
|
|
+ var sql string
|
|
|
+ var values []interface{}
|
|
|
+
|
|
|
if query.district != "" {
|
|
|
- filterShould = append(filterShould, fmt.Sprintf(`{"term":{"district":"%s"}}`, query.district))
|
|
|
+ sql += " AND district=? "
|
|
|
+ values = append(values, query.district)
|
|
|
} else if query.city != "" {
|
|
|
- filterShould = append(filterShould, fmt.Sprintf(`{"term":{"city":"%s"}}`, query.city))
|
|
|
+ sql += " AND city=? "
|
|
|
+ values = append(values, query.city)
|
|
|
} else if query.area != "" {
|
|
|
- filterShould = append(filterShould, fmt.Sprintf(`{"term":{"area":"%s"}}`, query.area))
|
|
|
+ sql += " AND area=? "
|
|
|
+ values = append(values, query.area)
|
|
|
}
|
|
|
|
|
|
if query.topType != "" {
|
|
|
if val, _ := topTypeMap[query.topType]; val != "" {
|
|
|
- filterMusts = append(filterMusts, fmt.Sprintf(`{"term":{"toptype":"%s"}}`, val))
|
|
|
+ sql += " AND toptype=? "
|
|
|
+ values = append(values, val)
|
|
|
} else {
|
|
|
- filterMusts = append(filterMusts, fmt.Sprintf(`{"term":{"toptype":"%s"}}`, query.topType))
|
|
|
+ sql += " AND toptype=? "
|
|
|
+ values = append(values, query.topType)
|
|
|
}
|
|
|
} else if query.subType != "" {
|
|
|
- filterMusts = append(filterMusts, fmt.Sprintf(`{"term":{"subtype":"%s"}}`, query.subType))
|
|
|
- }
|
|
|
- //行业
|
|
|
- if query.industry != "" {
|
|
|
- filterMusts = append(filterMusts, fmt.Sprintf(`{"terms":{"s_subscopeclass":["%s"]}}`, query.industry))
|
|
|
- }
|
|
|
- if len(filterMusts) > 0 || len(filterShould) > 0 {
|
|
|
- shouldMatch := 0
|
|
|
- if len(filterShould) > 0 {
|
|
|
- shouldMatch = 1
|
|
|
- }
|
|
|
- filter = append(filter, fmt.Sprintf(filterBool, strings.Join(filterMusts, ","), strings.Join(filterShould, ","), shouldMatch))
|
|
|
+ sql += " AND subtype=? "
|
|
|
+ values = append(values, query.subType)
|
|
|
}
|
|
|
- //标的物
|
|
|
- if query.keys != "" {
|
|
|
- should = append(should, fmt.Sprintf(keywords, query.keys))
|
|
|
+ values = append(values, total)
|
|
|
+ res, err := g.DB("clickHouse").Query(ctx, "SELECT * FROM bidMsg WHERE 1=1 "+sql+" ORDER BY publish_time DESC limit 0,?", values...)
|
|
|
+ if err != nil {
|
|
|
+ return -1, nil
|
|
|
}
|
|
|
- queryShouldMatch := 0
|
|
|
- if len(should) > 0 {
|
|
|
- queryShouldMatch = 1
|
|
|
- }
|
|
|
- return fmt.Sprintf(querySql, strings.Join(filter, ","), strings.Join(should, ","), queryShouldMatch, field, total)
|
|
|
+ return res.Len(), res.List()
|
|
|
}
|
|
|
|
|
|
func (query *SeoBiddingQuery) dataFormat(data []map[string]interface{}) (bList []*InfoList) {
|
|
@@ -143,23 +114,19 @@ func (query *SeoBiddingQuery) dataFormat(data []map[string]interface{}) (bList [
|
|
|
for _, v := range data {
|
|
|
bl := &InfoList{
|
|
|
Title: gconv.String(v["title"]),
|
|
|
- Url: fmt.Sprintf("/nologin/content/%s.html", encrypt.CommonEncodeArticle("content", gconv.String(v["_id"]))),
|
|
|
+ Url: fmt.Sprintf("/nologin/content/%s.html", encrypt.CommonEncodeArticle("content", gconv.String(v["bid_id"]))),
|
|
|
Area: gconv.String(v["area"]),
|
|
|
Subtype: gconv.String(v["subtype"]),
|
|
|
}
|
|
|
- if gconv.String(v["site"]) == "剑鱼信息发布平台" {
|
|
|
- bl.Site = "用户发布"
|
|
|
- }
|
|
|
- bl.PublishTime = gconv.Int64(v["publishtime"])
|
|
|
- if subs := gconv.String(v["s_subscopeclass"]); subs != "" {
|
|
|
- bl.Industry = strings.Split(strings.Split(subs, ",")[0], "_")[0]
|
|
|
- }
|
|
|
- if isValidFile, _ := v["isValidFile"].(bool); isValidFile {
|
|
|
- bl.FileExists = true
|
|
|
+ bl.PublishTime = gconv.Int64(v["publish_time"])
|
|
|
+
|
|
|
+ if industry := gconv.String(v["industry"]); industry != "" {
|
|
|
+ bl.Industry = industry
|
|
|
}
|
|
|
- if v["budget"] != nil {
|
|
|
+
|
|
|
+ if budget := gconv.Float64(v["budget"]); budget > 0 {
|
|
|
bl.Price = utility.ConversionMoney(v["budget"])
|
|
|
- } else if v["bidamount"] != nil {
|
|
|
+ } else if bidamount := gconv.Float64(v["bidamount"]); bidamount > 0 {
|
|
|
bl.Price = utility.ConversionMoney(v["bidamount"])
|
|
|
}
|
|
|
bList = append(bList, bl)
|
|
@@ -170,7 +137,7 @@ func (query *SeoBiddingQuery) dataFormat(data []map[string]interface{}) (bList [
|
|
|
|
|
|
// getBidListCacheKey 获取列表缓存
|
|
|
func (query *SeoBiddingQuery) getBidListCacheKey(pageNum int) string {
|
|
|
- return fmt.Sprintf("JySeoListCache_%d_%d_%s_%s_%s_%s", SettingPageSize, pageNum, query.area, query.city, query.topType, query.subType)
|
|
|
+ return fmt.Sprintf("JySeoListCache_%d_%d_%s_%s_%s_%s_%s", SettingPageSize, pageNum, query.keys, query.area, query.city, query.topType, query.subType)
|
|
|
}
|
|
|
|
|
|
// GetBidListList 列表页查询
|
|
@@ -186,20 +153,19 @@ func (query *SeoBiddingQuery) GetBidListList(ctx context.Context, pageNum int) (
|
|
|
return
|
|
|
}
|
|
|
defer JySeoQueryListLimit.Reset()
|
|
|
- // 查询全量
|
|
|
- sql := query.getSearchSql(SettingListTotal)
|
|
|
+
|
|
|
//g.Log().Info(ctx, sql)
|
|
|
- count, data := elastic.GetWithCount("bidding", "bidding", "", sql)
|
|
|
- if count > SettingListTotal {
|
|
|
- count = SettingListTotal
|
|
|
+ count, data := query.getResult(ctx, SettingMaxBidSize)
|
|
|
+ if count > SettingMaxBidSize {
|
|
|
+ count = SettingMaxBidSize
|
|
|
}
|
|
|
- if data != nil && len(*data) > 0 && gconv.Int(count) == len(*data) {
|
|
|
- totalPage, formatData := count/SettingPageSize, query.dataFormat(*data)
|
|
|
+ if data != nil && len(data) > 0 && gconv.Int(count) == len(data) {
|
|
|
+ totalPage, formatData := count/SettingPageSize, query.dataFormat(data)
|
|
|
if count%SettingPageSize != 0 {
|
|
|
totalPage++
|
|
|
}
|
|
|
for i := 1; i <= gconv.Int(totalPage); i++ {
|
|
|
- start, end := gconv.Int64(i-1)*SettingPageSize, gconv.Int64(i)*SettingPageSize
|
|
|
+ start, end := (i-1)*SettingPageSize, (i)*SettingPageSize
|
|
|
if end > count {
|
|
|
end = count
|
|
|
}
|
|
@@ -222,12 +188,12 @@ func (query *SeoBiddingQuery) GetBidListList(ctx context.Context, pageNum int) (
|
|
|
}
|
|
|
|
|
|
// getTabDataCacheKey 获取列表缓存
|
|
|
-func (query *SeoBiddingQuery) getTabDataCacheKey(total int64) string {
|
|
|
+func (query *SeoBiddingQuery) getTabDataCacheKey(total int) string {
|
|
|
return fmt.Sprintf("JySeoTabData_%d_%s_%s_%s_%s", total, query.area, query.city, query.topType, query.subType)
|
|
|
}
|
|
|
|
|
|
// GetTabData 面包屑数据
|
|
|
-func (query *SeoBiddingQuery) GetTabData(ctx context.Context, total int64) (res []*InfoList, err error) {
|
|
|
+func (query *SeoBiddingQuery) GetTabData(ctx context.Context, total int) (res []*InfoList, err error) {
|
|
|
var vars *gvar.Var
|
|
|
cacheKey := query.getTabDataCacheKey(total)
|
|
|
vars, err = g.Redis().Get(ctx, cacheKey)
|
|
@@ -238,9 +204,10 @@ func (query *SeoBiddingQuery) GetTabData(ctx context.Context, total int64) (res
|
|
|
return
|
|
|
}
|
|
|
defer JySeoQueryTabLimit.Reset()
|
|
|
- data := elastic.Get("bidding", "bidding", query.getSearchSql(total))
|
|
|
- if data != nil && len(*data) > 0 {
|
|
|
- res = query.dataFormat(*data)
|
|
|
+
|
|
|
+ _, data := query.getResult(ctx, total)
|
|
|
+ if data != nil && len(data) > 0 {
|
|
|
+ res = query.dataFormat(data)
|
|
|
}
|
|
|
if err := g.Redis().SetEX(ctx, cacheKey, res, SettingBidCacheTime); err != nil {
|
|
|
g.Log().Errorf(ctx, "GetTabData 存储redis err:%v", err)
|