Ver código fonte

Merge branch 'dev/v1.0.4_dx' of jianyu/jyseo into feature/v1.0.4

duxin 1 ano atrás
pai
commit
a66900cb18
6 arquivos alterados com 266 adições e 7 exclusões
  1. 4 2
      go.mod
  2. 6 4
      go.sum
  3. 6 0
      manifest/config/config.yaml
  4. 219 0
      utility/anonymousPortrait.go
  5. 16 1
      utility/db.go
  6. 15 0
      utility/util.go

+ 4 - 2
go.mod

@@ -5,9 +5,9 @@ go 1.19
 require (
 	app.yhyue.com/moapp/jybase v0.0.0-20230727083622-4dfc804ea6cf
 	github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.5.2
-	github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.2
+	github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.4
 	github.com/gogf/gf/contrib/nosql/redis/v2 v2.5.2
-	github.com/gogf/gf/v2 v2.5.2
+	github.com/gogf/gf/v2 v2.5.4
 )
 
 require (
@@ -19,11 +19,13 @@ require (
 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 	github.com/fatih/color v1.15.0 // indirect
 	github.com/fsnotify/fsnotify v1.6.0 // indirect
+	github.com/garyburd/redigo v1.6.2 // indirect
 	github.com/go-logr/logr v1.2.4 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
 	github.com/go-sql-driver/mysql v1.7.1 // indirect
 	github.com/go-stack/stack v1.8.0 // indirect
 	github.com/golang/snappy v0.0.4 // indirect
+	github.com/gomodule/redigo v1.8.9 // indirect
 	github.com/google/uuid v1.3.0 // indirect
 	github.com/gorilla/websocket v1.5.0 // indirect
 	github.com/grokify/html-strip-tags-go v0.0.1 // indirect

+ 6 - 4
go.sum

@@ -131,6 +131,7 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
+github.com/garyburd/redigo v1.6.2 h1:yE/pwKCrbLpLpQICzYTeZ7JsTA/C53wFTJHaEtRqniM=
 github.com/garyburd/redigo v1.6.2/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
@@ -169,12 +170,12 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg78
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.5.2 h1:QwHoniewNRrQVcRE47yzpVG2l9kfqn+W9VSL91nkaxo=
 github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.5.2/go.mod h1:ihKUdWof54li5HwlW2H9qYqIxoJn0KAs1WvD8Ve9dHk=
-github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.2 h1:tFQP3/4Ivsx9ZkXXbHPIGn+TCiEW+0pQ2elwsafACNM=
-github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.2/go.mod h1:k9TrNZlYVBPNPYeqJ2uac0aqcJh75CHk7mWNYpRmrk4=
+github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.4 h1:xAmYQZEDBDoce/q5s7UTibYHHW0DSTApfmXVC/i0/zI=
+github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.4/go.mod h1:lEgzJw5PLBOEJ4gZHgs1GwsbjyBLBttN2sN63rYRNhk=
 github.com/gogf/gf/contrib/nosql/redis/v2 v2.5.2 h1:JzRIXB5J6vvnJGJmh7RfT8ntjXsn2jYXJf1+Q6oFe+A=
 github.com/gogf/gf/contrib/nosql/redis/v2 v2.5.2/go.mod h1:vLNtPgfInF5cXlcjLhVZxijIXD30+IiVjN6hP9sjjhY=
-github.com/gogf/gf/v2 v2.5.2 h1:fACJE7DJH6iTGHGhgiNY1uuZIZtr2IqQkJ52E+wBnt8=
-github.com/gogf/gf/v2 v2.5.2/go.mod h1:7yf5qp0BznfsYx7Sw49m3mQvBsHpwAjJk3Q9ZnKoUEc=
+github.com/gogf/gf/v2 v2.5.4 h1:UBCSw8mInkHmEqL0E1LYc6QhSpaNFY/wHcFrTI/rzTk=
+github.com/gogf/gf/v2 v2.5.4/go.mod h1:7yf5qp0BznfsYx7Sw49m3mQvBsHpwAjJk3Q9ZnKoUEc=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
 github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
@@ -210,6 +211,7 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws=
 github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=

+ 6 - 0
manifest/config/config.yaml

@@ -35,6 +35,12 @@ elasticsearch:
   "userName": ""
   "password": ""
 
+entMongodb:
+  address: "192.168.3.206:27080"
+  size: 5
+  dbName: "qfw"
+  replSet: ""
+
 redis:
   default: # 配置seo的redis
     address: 127.0.0.1:6379

+ 219 - 0
utility/anonymousPortrait.go

@@ -0,0 +1,219 @@
+package utility
+
+import (
+	"app.yhyue.com/moapp/jybase/common"
+	elastic "app.yhyue.com/moapp/jybase/es"
+	"app.yhyue.com/moapp/jybase/redis"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"math/rand"
+	"strings"
+	"time"
+)
+
+// PortraitScreen 画像筛选
+type PortraitScreen struct {
+	Ent        string //企业id
+	Match      string //检索词 50个字符
+	MatchRange string //搜索范围 项目名称/项目标的物、招标代理机构、采购单位、中标单位
+	ExactMatch bool   //匹配方式 true精确匹配、false模糊匹配
+	Area       string //省份
+	ScopeClass string //行业
+	BuyerClass string //采购单位类型
+	TimeRange  string //信息发布时间 以年为单位,逗号分隔、结束时间不得超过当前时间
+	HasPower   bool   //是否有相应权限
+	//数据导出回显
+	PareStartTime, PareEndTime int64 //筛选时间戳
+	ShowMatch                  string
+	KeyWordArr                 []string
+	UserLevel                  int //用户身份 3:未登录;2:免费;1:付费
+}
+
+// PortraitProjectScreen 动态翻页
+type PortraitProjectScreen struct {
+	Ent      string //企业id
+	PageNum  int    //页码
+	PageSize int    //每页数量
+}
+
+const (
+	NewMustSearch             = `{"query":{"bool":{"must":[%s]}}%s}`
+	biddingIndex, biddingType = "bidding", "bidding"
+)
+
+// 未登录用户动态信息
+func (pwp *PortraitProjectScreen) FreeBuyerNews(name string, isWinner bool) ([]map[string]interface{}, int64, error) {
+	if pwp.Ent == "" {
+		return nil, 0, errors.New("参数错误")
+	}
+	pwp.PageNum = common.If(pwp.PageNum == 0, 1, pwp.PageNum).(int)     //默认第一页
+	pwp.PageSize = common.If(pwp.PageSize == 0, 10, pwp.PageSize).(int) //默认每页10条
+
+	redisKey := fmt.Sprintf("free_portrait_list_%s", pwp.Ent)
+	var data []map[string]interface{}
+	if rBytes, err := redis.GetBytes("other", redisKey); err == nil && len(*rBytes) != 0 {
+		_ = json.Unmarshal(*rBytes, &data)
+	} else {
+		list := elastic.Get(biddingIndex, biddingIndex, PareSelect(name, isWinner))
+		if list != nil && len(*list) > 0 {
+			data = *list
+			go func() {
+				redis.Put("other", redisKey, data, int(redisTime()))
+			}()
+		}
+	}
+	total := int64(len(data))
+	if len(data) > 0 {
+		start := (pwp.PageNum - 1) * pwp.PageSize
+		// 对数据切片进行裁剪
+		if start < 0 {
+			start = 0
+		}
+		if start >= len(data) {
+			data = []map[string]interface{}{}
+		} else {
+			end := start + pwp.PageSize
+			if end > len(data) {
+				end = len(data)
+			}
+			data = data[start:end]
+		}
+	}
+	return data, total, nil
+}
+
+// PareSelect sql
+func PareSelect(name string, isWinner bool) string {
+	sYear := 2018
+	//返回默认时间
+	sTimeStamp := time.Date(sYear, 1, 1, 0, 0, 0, 0, time.Local)
+	var (
+		mustQueryArr []string
+		fields       string
+	)
+	if isWinner {
+		fields = `"_id","projectname","bidamount","budget","title","publishtime","subtype","toptype","area","bidopentime","buyer"`
+		mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"term":{"entidlist":"%s"}}`, name))
+		mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"range":{"publishtime":{"gte":"%d","lte":"%d"}}}`, sTimeStamp.Unix(), time.Now().Unix()))
+	} else {
+		fields = `"bidstatus","_id","title","subtype","projectname","publishtime","area","bidamount","budget","bidopentime","s_winner","entidlist"`
+		mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"term":{"buyer":"%s"}}`, name))
+		mustQueryArr = append(mustQueryArr, fmt.Sprintf(`{"range":{"publishtime":{"gte":"%d","lte":"%d"}}}`, sTimeStamp.Unix(), time.Now().Unix()))
+	}
+	return fmt.Sprintf(NewMustSearch, strings.Join(mustQueryArr, ","), fmt.Sprintf(`,"_source":[%s],"sort":{%s},"from":0,"size":30`, fields, `"publishtime":"desc","id":"desc"`))
+}
+
+func redisTime() float64 {
+	currentTime := time.Now()
+
+	currentWeekday := currentTime.Weekday()
+	daysUntilMonday := time.Monday - currentWeekday
+	if daysUntilMonday < 0 {
+		daysUntilMonday += 7
+	}
+	nextMonday := currentTime.AddDate(0, 0, int(daysUntilMonday))
+
+	nextMondayMidnight := time.Date(nextMonday.Year(), nextMonday.Month(), nextMonday.Day(), 0, 0, 0, 0, nextMonday.Location())
+
+	return nextMondayMidnight.Sub(currentTime).Seconds()
+}
+
+func RelevanceData(name string, isWinner bool) []map[string]interface{} {
+	if name == "" {
+		return nil
+	}
+	redisKey := fmt.Sprintf("portrait_relevance_%v_%s", isWinner, name)
+	var data []map[string]interface{}
+	if rBytes, err := redis.GetBytes("other", redisKey); err == nil && len(*rBytes) != 0 {
+		_ = json.Unmarshal(*rBytes, &data)
+	} else {
+		querySql := `{"query": {"bool": {"must": [%s]}},"_source":["buyer","s_winner","entidlist"],"size": 200}`
+		var mustSql string
+		if isWinner {
+			mustSql = fmt.Sprintf(`{"terms": {"entidlist": ["%s"]}},{"exists": {"field": "buyer"}}`, name)
+		} else {
+			mustSql = fmt.Sprintf(`{"match": {"buyer": "%s"}},{"exists": {"field": "s_winner"}},{"exists": {"field": "entidlist"}}`, name)
+		}
+		getData := elastic.Get(biddingIndex, biddingType, fmt.Sprintf(querySql, mustSql))
+		if getData != nil && len(*getData) > 0 {
+			if !isWinner { //采购关联企业 校验正确性
+				entMap := make(map[string]string)
+				for _, v := range *getData {
+					s_winner := common.InterfaceToStr(v["s_winner"])
+					entidlist, _ := v["entidlist"].([]interface{})
+					winners := strings.Split(s_winner, ",")
+					if s_winner == "" || entidlist == nil || len(winners) != len(entidlist) {
+						continue
+					}
+					//中标企业去重
+					for k, v1 := range winners {
+						entMap[v1] = EncodeId(common.InterfaceToStr(entidlist[k]))
+					}
+				}
+				for entname, entid := range entMap {
+					data = append(data, map[string]interface{}{"s_winner": entname, "entidlist": []string{entid}})
+				}
+			} else {
+				data = *getData
+			}
+
+			go func() {
+				redis.Put("other", redisKey, data, 24*3600)
+			}()
+		}
+	}
+	var start int
+	if len(data) > 10 { //大于10 随机取10个
+		rand.Seed(time.Now().UnixNano())
+		start = rand.Intn(len(data) - 10)
+		data = data[start : start+10]
+	}
+	return data
+}
+
+// name 名称 province 省份 isWinner 来源是否中标企业画像 false 来源企业画像
+func RecommendedData(name, province string, isWinner bool) []map[string]interface{} {
+	var data []map[string]interface{}
+	if name != "" && province != "" && province != "其他" {
+		redisKey := fmt.Sprintf("portrait_recommended_%v_%s", isWinner, province)
+		if rBytes, err := redis.GetBytes("other", redisKey); err == nil && len(*rBytes) != 0 {
+			_ = json.Unmarshal(*rBytes, &data)
+		} else {
+			if isWinner {
+				winnerData, _ := Mgo_Ent.Find("qyxy_std", map[string]interface{}{"company_area": province, "name": map[string]interface{}{"$ne": name}},
+					"", `{"company_area": 1,"_id": 1,"company_name": 1,}`, true, 0, 200)
+				if winnerData != nil && len(*winnerData) > 0 {
+					for _, v := range *winnerData {
+						v["id"] = EncodeId(common.InterfaceToStr(v["_id"]))
+						delete(v, "_id")
+					}
+					data = *winnerData
+				}
+			} else {
+				qsl := `{"query": {"bool": {"must": [{"term": {"province": "%s"}}],"must_not": [{"term": {"name": "%s"}}]}},"_source":["buyer_name"],"size": 200}`
+				buyerData := elastic.Get("buyer", "buyer", fmt.Sprintf(qsl, province, name))
+				if buyerData != nil {
+					data = *buyerData
+				}
+			}
+			if len(data) > 0 {
+				go func() {
+					redis.Put("other", redisKey, data, 24*3600)
+				}()
+			}
+		}
+		var start int
+		if len(data) > 10 { //大于10 随机取10个
+			rand.Seed(time.Now().UnixNano())
+			start = rand.Intn(len(data) - 10)
+			data = data[start : start+10]
+		}
+	}
+
+	//TODO 无数据从运行数据从取
+	if len(data) == 0 {
+
+	}
+	return data
+}

+ 16 - 1
utility/db.go

@@ -29,9 +29,10 @@ type (
 )
 
 var (
-	mongdbConf  mgoConf
 	elasticConf esConf
+	mongdbConf  mgoConf
 	Mgo         m.MongodbSim
+	Mgo_Ent     m.MongodbSim
 )
 
 func init() {
@@ -49,6 +50,20 @@ func init() {
 	}
 	Mgo.InitPool()
 	g.Log().Info(context.Background(), "初始化 mongodb 完成")
+	if err := g.Cfg().MustGet(context.Background(), "entMongodb").Struct(&mongdbConf); err != nil {
+		panic(err)
+	}
+
+	Mgo_Ent = m.MongodbSim{
+		MongodbAddr: mongdbConf.Address,
+		Size:        mongdbConf.Size,
+		DbName:      mongdbConf.DbName,
+		UserName:    mongdbConf.UserName,
+		Password:    mongdbConf.Password,
+		ReplSet:     mongdbConf.ReplSet,
+	}
+	Mgo_Ent.InitPool()
+	g.Log().Info(context.Background(), "初始化 mongodb 完成")
 
 	if err := g.Cfg().MustGet(initCtx, "elasticsearch").Struct(&elasticConf); err != nil {
 		panic(err)

+ 15 - 0
utility/util.go

@@ -1,6 +1,7 @@
 package utility
 
 import (
+	"app.yhyue.com/moapp/jybase/encrypt"
 	"fmt"
 	"github.com/gogf/gf/v2/util/gconv"
 	"reflect"
@@ -53,3 +54,17 @@ func GetCommonRenderPatch(path, value string) string {
 	}
 	return fmt.Sprintf("pc/%s", value)
 }
+
+func EncodeId(sid string) string {
+	if sid == "" || sid == "-" { //不存在的id为-
+		return ""
+	}
+	return encrypt.EncodeArticleId2ByCheck(sid)
+}
+
+func DecodeId(eid string) string {
+	if eid == "" {
+		return ""
+	}
+	return encrypt.DecodeArticleId2ByCheck(eid)[0]
+}