123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 |
- package service
- import (
- "app.yhyue.com/moapp/jybase/encrypt"
- "context"
- "fmt"
- "github.com/gogf/gf/v2/container/gvar"
- "github.com/gogf/gf/v2/database/gdb"
- "github.com/gogf/gf/v2/frame/g"
- "github.com/gogf/gf/v2/util/gconv"
- "jyseo/internal/consts"
- "jyseo/utility"
- "strings"
- )
- type (
- SeoBiddingQuery struct {
- keys string
- area string
- city string
- district string
- topType string
- subType string
- topClass string
- subClass string
- SIGN int
- Other map[string]interface{}
- }
- InfoList struct {
- Id string
- Title string
- Url string
- Area string
- Industry string
- Subtype string
- Price string
- Site string
- Detail string
- Keyword string
- FileExists bool
- PublishTime int64
- ExpandMap map[string]interface{}
- }
- ListResp struct {
- Total int
- List []*InfoList
- }
- )
- func NewBiddingQuery() *SeoBiddingQuery {
- return &SeoBiddingQuery{}
- }
- // EquipArea 装备地区查询
- func (query *SeoBiddingQuery) EquipArea(areaNode *AreaNode) *SeoBiddingQuery {
- if areaNode != nil {
- switch areaNode.Type {
- case 1, 3:
- query.area = areaNode.Name
- case 2:
- query.city = areaNode.Name
- case 4:
- // 区县会重名,所以带上上级名字
- if areaNode.PNode != nil {
- if areaNode.PNode.Type == 3 {
- query.area = areaNode.PNode.Name
- } else {
- query.city = areaNode.PNode.Name
- }
- }
- query.district = areaNode.Name
- }
- }
- return query
- }
- func (query *SeoBiddingQuery) EquipSType(sTypeNode *STypeNode) *SeoBiddingQuery {
- if sTypeNode.PNode != nil {
- query.subType = sTypeNode.Name
- } else {
- query.topType = sTypeNode.Name
- }
- return query
- }
- func (query *SeoBiddingQuery) EquipSIGN(sign int) *SeoBiddingQuery {
- if sign > 0 {
- query.SIGN = sign
- }
- return query
- }
- func (query *SeoBiddingQuery) EquipKeyWord(keyword string) *SeoBiddingQuery {
- query.keys = keyword
- return query
- }
- func (query *SeoBiddingQuery) EquipIndustry(topClass, subClass string) *SeoBiddingQuery {
- if topClass != "" {
- query.topClass = topClass
- }
- if subClass != "" {
- query.subClass = subClass
- }
- return query
- }
- func (query *SeoBiddingQuery) EquipOtherMap(m map[string]interface{}) *SeoBiddingQuery {
- if m != nil && len(m) > 0 {
- query.Other = m
- }
- return query
- }
- // defaultDataFormat 默认格式化数据
- func (query *SeoBiddingQuery) defaultDataFormat(data []map[string]interface{}) (bList []*InfoList) {
- if len(data) > 0 {
- titleReduction := map[string]bool{}
- for _, v := range data {
- bl := &InfoList{
- Id: gconv.String(v["bid_id"]),
- Title: gconv.String(v["title"]),
- 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"]),
- Detail: gconv.String(v["desc"]),
- Keyword: gconv.String(v["keyword"]),
- }
- //重复标题加数字后缀
- if titleReduction[bl.Title] {
- continue
- }
- titleReduction[bl.Title] = true
- bl.PublishTime = gconv.Int64(v["publish_time"])
- if gconv.String(v["area"]) == "剑鱼信息发布平台" {
- bl.Site = "用户发布"
- }
- if industry := gconv.String(v["industry"]); industry != "" {
- bl.Industry = industry
- }
- if isValidFile, _ := v["isValidFile"].(bool); isValidFile {
- bl.FileExists = true
- }
- if budget := gconv.Float64(v["budget"]); budget > 0 {
- bl.Price = utility.ConversionMoney(v["budget"])
- } else if bidamount := gconv.Float64(v["bidamount"]); bidamount > 0 {
- bl.Price = utility.ConversionMoney(v["bidamount"])
- }
- bList = append(bList, bl)
- }
- }
- return
- }
- // getBidListCacheKey 获取列表缓存
- func (query *SeoBiddingQuery) getDataPageListCacheKey(pageNum, pageSize, maxTotal int, flag string) string {
- return fmt.Sprintf("JySeoBidDataPageList_%s_%d_%d_%d_%s_%s_%s_%s_%s_%s_%s_%s_%d", flag, pageNum, pageSize, maxTotal, query.keys, query.area, query.city, query.district, query.topType, query.subType, query.topClass, query.subClass, query.SIGN)
- }
- // GetDataPageList 翻页列表页查询
- // 一次性查询全部信息,生成每页cache
- func (query *SeoBiddingQuery) GetDataPageList(ctx context.Context, pageNum, pageSize, maxTotal int, flag string, getData func(context.Context, int, *SeoBiddingQuery) []map[string]interface{}, formatFunc ...func([]map[string]interface{}) []*InfoList) (res *ListResp, err error) {
- var vars *gvar.Var
- res = &ListResp{}
- if pageSize == 0 {
- pageSize = consts.SettingPageSize
- }
- vars, err = g.Redis().Get(ctx, query.getDataPageListCacheKey(pageNum, pageSize, maxTotal, flag))
- if err != nil || vars.IsNil() {
- //并发限制
- if ok := JySeoQueryListLimit.Limit(); !ok {
- err = fmt.Errorf("请求超时")
- return
- }
- defer JySeoQueryListLimit.Reset()
- data := getData(ctx, maxTotal, query)
- formatExec := query.defaultDataFormat
- if len(formatFunc) > 0 && formatFunc[0] != nil {
- formatExec = formatFunc[0]
- }
- formatData := formatExec(data)
- count := len(formatData)
- if count > maxTotal {
- count = maxTotal
- }
- if data != nil && len(data) > 0 {
- totalPage := count / pageSize
- if count%pageSize != 0 {
- totalPage++
- }
- for i := 1; i <= gconv.Int(totalPage); i++ {
- start, end := (i-1)*pageSize, (i)*pageSize
- if end > count {
- end = count
- }
- pageTmp := &ListResp{
- Total: totalPage,
- List: formatData[start:end],
- }
- if i == pageNum {
- res = pageTmp
- }
- fmt.Println(query.getDataPageListCacheKey(i, pageSize, maxTotal, flag), consts.GetListCacheTime(ctx, flag))
- if err := g.Redis().SetEX(ctx, query.getDataPageListCacheKey(i, pageSize, maxTotal, flag), pageTmp, consts.GetListCacheTime(ctx, flag)); err != nil {
- g.Log().Errorf(ctx, "第%d页数据 存储redis err:%v", err)
- }
- }
- }
- } else {
- err = vars.Struct(res)
- }
- return
- }
- // getTabDataCacheKey 获取列表缓存
- func (query *SeoBiddingQuery) getOnceDataCacheKey(total int, flag string) string {
- return fmt.Sprintf("JySeoBidDataOnceList_%s_%d_%s_%s_%s_%s_%s_%s_%s_%s_%d_%v", flag, total, query.keys, query.area, query.city, query.district, query.topType, query.subType, query.topClass, query.subClass, query.SIGN, query.Other)
- }
- // GetOnceData 获取数据
- func (query *SeoBiddingQuery) GetOnceData(ctx context.Context, total int, flag string, getData func(context.Context, int, *SeoBiddingQuery) []map[string]interface{}, formatFunc ...func([]map[string]interface{}) []*InfoList) (res []*InfoList, err error) {
- var vars *gvar.Var
- cacheKey := query.getOnceDataCacheKey(total, flag)
- vars, err = g.Redis().Get(ctx, cacheKey)
- if err != nil || vars.IsNil() {
- //并发限制
- if ok := JySeoQueryTabLimit.Limit(); !ok {
- err = fmt.Errorf("请求超时")
- return
- }
- defer JySeoQueryTabLimit.Reset()
- data := getData(ctx, total*2, query)
- if data != nil && len(data) > 0 {
- formatExec := query.defaultDataFormat
- if len(formatFunc) > 0 && formatFunc[0] != nil {
- formatExec = formatFunc[0]
- }
- res = formatExec(data)
- }
- if len(res) > total {
- res = res[:total]
- }
- fmt.Println(cacheKey, consts.GetListCacheTime(ctx, flag))
- if err := g.Redis().SetEX(ctx, cacheKey, res, consts.GetListCacheTime(ctx, flag)); err != nil {
- g.Log().Errorf(ctx, "GetOnceData 存储redis err:%v", err)
- }
- } else {
- err = vars.Struct(&res)
- }
- return
- }
- func FillingBiddingBaseFields(ctx context.Context, res []map[string]interface{}, filterNj ...bool) []map[string]interface{} {
- bidIdStrings := make([]string, 0, len(res))
- for _, m := range res {
- if bidId := gconv.String(m["bid_id"]); bidId != "" {
- bidIdStrings = append(bidIdStrings, bidId)
- }
- }
- var bidRes gdb.Result
- if len(filterNj) > 0 { //没有过滤拟建项目和采购意向,需要查询过滤
- bidRes, _ = g.DB().Query(ctx, fmt.Sprintf(`SELECT * FROM new_bidList WHERE toptype !='拟建' AND toptype !='采购意向' AND bid_id IN ('%s')`, strings.Join(bidIdStrings, "','")))
- } else { //已经过滤了拟建项目和采购意向
- bidRes, _ = g.DB().Query(ctx, fmt.Sprintf(`SELECT * FROM new_bidList WHERE bid_id IN ('%s')`, strings.Join(bidIdStrings, "','")))
- }
- if bidRes.IsEmpty() {
- return nil
- }
- bidMap := map[string]map[string]interface{}{}
- for _, m := range bidRes.List() {
- if bidIdStr := gconv.String(m["bid_id"]); bidIdStr != "" {
- bidMap[bidIdStr] = m
- }
- }
- var finalArr []map[string]interface{}
- for i := 0; i < len(res); i++ {
- if tBid := gconv.String(res[i]["bid_id"]); tBid != "" && bidMap[tBid] != nil && len(bidMap[tBid]) > 0 {
- for k, v := range bidMap[tBid] {
- res[i][k] = v
- }
- finalArr = append(finalArr, res[i])
- }
- }
- return finalArr
- }
- func FillingEsBiddingBaseFields(res []map[string]interface{}, key string) []map[string]interface{} {
- bidMap := map[string]map[string]interface{}{}
- for _, m := range res {
- if bidIdStr := gconv.String(m["_id"]); bidIdStr != "" {
- mv := make(map[string]interface{})
- mv["keyword"] = key
- if len([]rune(gconv.String(m["detail"]))) > 100 {
- mv["desc"] = string([]rune(gconv.String(m["detail"]))[:100])
- } else {
- mv["desc"] = gconv.String(m["detail"])
- }
- mv["bid_id"] = bidIdStr
- mv["title"] = gconv.String(m["title"])
- mv["area"] = gconv.String(m["area"])
- mv["city"] = gconv.String(m["city"])
- mv["district"] = gconv.String(m["district"])
- mv["toptype"] = gconv.String(m["toptype"])
- mv["subtype"] = gconv.String(m["subtype"])
- mv["industry"] = ""
- if subs := gconv.String(m["s_subscopeclass"]); subs != "" {
- classArr := strings.Split(strings.Split(subs, ",")[0], "_")
- if len(classArr) == 2 {
- mv["industry"] = classArr[0]
- }
- }
- mv["bidamount"] = gconv.Float64(m["bidamount"])
- mv["budget"] = gconv.Float64(m["budget"])
- mv["size"] = gconv.String(m["size"])
- mv["isValidFile"] = gconv.Bool(m["isValidFile"])
- mv["publish_time"] = gconv.Int64(m["publishtime"])
- bidMap[bidIdStr] = mv
- }
- }
- var finalArr []map[string]interface{}
- for i := 0; i < len(res); i++ {
- if tBid := gconv.String(res[i]["_id"]); tBid != "" && bidMap[tBid] != nil && len(bidMap[tBid]) > 0 {
- for k, v := range bidMap[tBid] {
- res[i][k] = v
- }
- finalArr = append(finalArr, res[i])
- }
- }
- return finalArr
- }
- func GetEsQuery(maxTotal int, query *SeoBiddingQuery) string {
- var musts []string
- qu := `{"query": {"bool": {"must": [%s],
- "must_not": [{"terms": {"toptype": ["拟建","采购意向"]}}]}},
- "_source": [
- "title",
- "publishtime",
- "_id",
- "area",
- "city",
- "district",
- "toptype",
- "subtype",
- "s_subscopeclass",
- "bidamount",
- "budget",
- "site",
- "detail",
- "isValidFile"
- ],
- "sort": {
- "publishtime": "desc"
- },
- "from": 0,
- "size": %d
- }`
- if query.keys != "" {
- musts = append(musts, fmt.Sprintf(`{"multi_match": {"query": "%s","minimum_should_match": "%s","fields": ["title"]}}`, query.keys, consts.KeyWordEsMatchingDegree))
- }
- if query.district != "" {
- musts = append(musts, fmt.Sprintf(`{"term": {"district": "%s" }}`, query.district))
- }
- if query.city != "" {
- musts = append(musts, fmt.Sprintf(`{"term": {"city": "%s" }}`, query.city))
- }
- if query.area != "" {
- musts = append(musts, fmt.Sprintf(`{"term": {"area": "%s" }}`, query.area))
- }
- if query.topType != "" {
- if val, _ := consts.TopTypeMap[query.topType]; val != "" {
- musts = append(musts, fmt.Sprintf(`{"term": {"topType": "%s" }}`, val))
- } else {
- musts = append(musts, fmt.Sprintf(`{"term": {"topType": "%s" }}`, query.topType))
- }
- }
- if query.topClass != "" {
- musts = append(musts, fmt.Sprintf(`{"term": {"s_topscopeclass": "%s" }}`, query.topClass))
- }
- if query.subClass != "" && query.topClass != "" {
- musts = append(musts, fmt.Sprintf(`{"term": {"s_subscopeclass": "%s" }}`, fmt.Sprintf("%s_%s", query.topClass, query.subClass)))
- }
- return fmt.Sprintf(qu, strings.Join(musts, ","), maxTotal)
- }
|