xingzai 2 лет назад
Родитель
Сommit
b7bef83b00
13 измененных файлов с 1356 добавлено и 3 удалено
  1. 243 0
      controllers/search.go
  2. 3 0
      go.mod
  3. 29 0
      go.sum
  4. 28 0
      models/article.go
  5. 2 3
      models/config.go
  6. 75 0
      models/industry_map.go
  7. 59 0
      models/search.go
  8. 18 0
      routers/commentsRouter.go
  9. 6 0
      routers/router.go
  10. 240 0
      services/elastic.go
  11. 620 0
      services/industry_map.go
  12. 6 0
      utils/config.go
  13. 27 0
      utils/elastic.go

+ 243 - 0
controllers/search.go

@@ -0,0 +1,243 @@
+package controllers
+
+import (
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"hongze/hongze_clpt/models"
+	"hongze/hongze_clpt/services"
+	"hongze/hongze_clpt/utils"
+	"strings"
+)
+
+type SearchController struct {
+	BaseAuthController
+}
+
+type BaseSearchController struct {
+	BaseCommonController
+}
+
+type MobileSearchController struct {
+	BaseAuthMobileController
+}
+
+// @Title 搜索接口
+// @Description 搜索接口
+// @Param   PageSize   query   int  false       "每页数据条数"
+// @Param   CurrentIndex   query   int  false       "当前页页码,从1开始"
+// @Param   KeyWord   query   string  true       "搜索关键词"
+// @Param   OrderColumn   query   int  false       "排序字段 ,Comprehensive综合 ,Matching匹配度 ,PublishDate 发布时间 "
+// @Param   ListType   query   int  false       "列表类型,1最新/全部,2 纪要 ,3图表 默认1"
+// @Success 200 {object} models.SearchItem
+// @router /list [get]
+func (this *MobileSearchController) ListHomeArtAndChart() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	listType, _ := this.GetInt("ListType")
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+
+	if listType == 0 {
+		listType = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+	keyWord := this.GetString("KeyWord")
+	orderColumn := this.GetString("OrderColumn")
+	if keyWord == "" {
+		br.Msg = "请输入搜索词"
+		br.ErrMsg = "请输入搜索词"
+		return
+	}
+	user := this.User
+	if user == nil {
+		br.Msg = "请重新登录"
+		br.Ret = 408
+		return
+	}
+
+	//研选的五张图片
+	detailResearch, errConfig := models.GetConfigByCode("category_research_img_url")
+	if errConfig != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据研选分类图片失败,Err:" + errConfig.Error()
+		return
+	}
+	researchList := strings.Split(detailResearch.ConfigValue, "{|}")
+	//对应分类的所图片
+	detailCategoryUrl, errConfig := models.GetConfigByCode("category_map_img_url")
+	if errConfig != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "行业配置信息失败,Err:" + errConfig.Error()
+		return
+	}
+	categoryUrlList := strings.Split(detailCategoryUrl.ConfigValue, "{|}")
+	mapCategoryUrl := make(map[string]string)
+	var categoryId string
+	var imgUrlChart string
+	for _, v := range categoryUrlList {
+		vslice := strings.Split(v, "_")
+		categoryId = vslice[0]
+		imgUrlChart = vslice[len(vslice)-1]
+		mapCategoryUrl[categoryId] = imgUrlChart
+	}
+	if orderColumn == "" {
+		orderColumn = "Matching"
+	}
+	indexName := utils.IndexName
+	pageSize = 20
+	var chartTotal int
+	resp := new(models.SearchResp)
+	//page := paging.GetPaging(currentIndex, pageSize, total)
+	var chartList []*models.HomeChartListResp
+	var err error
+	var condition string
+	var pars []interface{}
+	if listType == 1 || listType == 3 {
+		if listType == 1 {
+			pageSize = 100
+		}
+		if currentIndex <= 2 {
+			condition = ` AND title LIKE '%` + keyWord + `%'`
+			chartList, err = models.GetChartList(condition, pars, startSize, pageSize)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
+				return
+			}
+			chartTotal, err = models.GetChartCount(condition, pars)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.Msg = "获取帖子总数失败,Err:" + err.Error()
+				return
+			}
+		}
+	}
+	for k, v := range chartList {
+		chartList[k].IsNeedJump = true
+		chartList[k].Source = 2
+		if v.PtagName != "" {
+			chartList[k].CtagNamePc = v.PtagName
+		}
+		if v.CtagName != "" {
+			chartList[k].CtagNamePc += "," + v.CtagName
+		}
+		if v.PtagNameTwo != "" {
+			chartList[k].CtagNamePc += "," + v.PtagNameTwo
+		}
+		if v.CtagNameTwo != "" {
+			chartList[k].CtagNamePc += "," + v.CtagNameTwo
+		}
+	}
+	if len(chartList) == 0 {
+		chartList = make([]*models.HomeChartListResp, 0)
+	}
+	resp.ChartList = chartList
+	var result []*models.SearchItem
+	var total int64
+	if listType == 1 || listType == 2 {
+		if orderColumn == "PublishDate" {
+			tmpResult, tmpTotal, tmpErr := services.EsMultiMatchFunctionScoreQueryTimeSort(indexName, keyWord, startSize, 100, user.UserId)
+			result = tmpResult
+			total = tmpTotal
+			err = tmpErr
+		} else {
+			tmpResult, tmpTotal, tmpErr := services.EsMultiMatchFunctionScoreQuerySort(indexName, keyWord, startSize, pageSize, user.UserId, orderColumn)
+			result = tmpResult
+			total = tmpTotal
+			err = tmpErr
+		}
+		if err != nil {
+			br.Msg = "检索失败"
+			br.ErrMsg = "检索失败,Err:" + err.Error()
+			return
+		}
+		if len(result) == 0 {
+			result = make([]*models.SearchItem, 0)
+		}
+
+		for k, v := range result {
+			//如果是研选系列的任意取五张图片的中的一张
+			if v.CategoryId == "0" {
+				knum := v.ArticleId % 5
+				result[k].ImgUrlPc = researchList[knum]
+			} else {
+				result[k].ImgUrlPc = mapCategoryUrl[v.CategoryId]
+			}
+			result[k].Source = 1
+		}
+	}
+	// ListType   query   int  true       "列表类型,1最新/全部,2 纪要 ,3图表 默认1"
+	//记录用户搜索关键词
+	//var source int
+	//if listType == 1 {
+	//	source = 3
+	//} else if listType == 2 {
+	//	source = 1
+	//} else {
+	//	source = 2
+	//}
+	//go services.AddSearchKeyWord(user, keyWord, source)
+
+	if chartTotal > int(total) {
+		total = int64(chartTotal)
+	}
+	if listType == 1 {
+		total = total + int64(chartTotal)
+	}
+	page := paging.GetPaging(currentIndex, pageSize, int(total))
+	resp.Paging = page
+	resp.List = result
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 获取搜索推荐词
+// @Description 获取搜索推荐词
+// @Success 200 {object} models.ConfigResp
+// @router /keyWord [get]
+func (this *BaseSearchController) BrowseHistoryList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	resp := new(models.ConfigResp)
+	hotSearch, err := models.GetHotSearch()
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	slicehotSearch := strings.Split(hotSearch, ",")
+	for _, v := range slicehotSearch {
+		item := new(models.KeyWord)
+		item.KeyWord = v
+		resp.ListRecommend = append(resp.ListRecommend, item)
+	}
+	hotList, err := models.GetSearchKeyWordTop()
+	if err != nil {
+		br.Msg = "获取信息失败"
+		br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
+		return
+	}
+	for _, v := range hotList {
+		item := new(models.KeyWord)
+		item.KeyWord = v.KeyWord
+		resp.ListHot = append(resp.ListHot, item)
+	}
+	br.Msg = "获取成功!"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+}

+ 3 - 0
go.mod

@@ -5,10 +5,13 @@ go 1.16
 require (
 	github.com/PuerkitoBio/goquery v1.8.0 // indirect
 	github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible
+	github.com/andybalholm/cascadia v1.3.1 // indirect
 	github.com/beego/beego/v2 v2.0.5
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/go-sql-driver/mysql v1.6.0
 	github.com/medivhzhan/weapp/v2 v2.5.0 // indirect
+	github.com/olivere/elastic/v7 v7.0.32 // indirect
 	github.com/rdlucklib/rdluck_tools v1.0.3
+	golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
 )

+ 29 - 0
go.sum

@@ -62,6 +62,7 @@ github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6l
 github.com/astaxie/beego v1.12.3/go.mod h1:p3qIm0Ryx7zeBHLljmd7omloyca1s4yu1a8kM1FkpIA=
 github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
 github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/aws/aws-sdk-go v1.43.21/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
 github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
 github.com/beego/beego/v2 v2.0.5 h1:fa2TBWfKGDs35Ck9an9SVnpS0zM8sRTXlW8rFjpeYlE=
 github.com/beego/beego/v2 v2.0.5/go.mod h1:CH2/JIaB4ceGYVQlYqTAFft4pVk/ol1ZkakUrUvAyns=
@@ -130,6 +131,7 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
 github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
 github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@@ -168,6 +170,7 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er
 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
@@ -204,8 +207,10 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
 github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
 github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -261,7 +266,11 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
 github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
+github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
 github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -292,6 +301,8 @@ github.com/lib/pq v1.10.5/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
 github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
 github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
+github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
+github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
 github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
@@ -332,6 +343,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
 github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
 github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
 github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
+github.com/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E=
+github.com/olivere/elastic/v7 v7.0.32/go.mod h1:c7PVmLe3Fxq77PIfY/bZmxY/TAamBhCzZ8xDOE09a9k=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -420,7 +433,10 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
+github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/smartystreets/gunit v1.4.2/go.mod h1:ZjM1ozSIMJlAz/ay4SG8PeKF00ckUp+zMHZXV9/bvak=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
 github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
 github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
@@ -436,6 +452,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
@@ -467,9 +484,12 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
+go.opentelemetry.io/otel v1.5.0/go.mod h1:Jm/m+rNp/z0eqJc74H7LPwQ3G87qkU/AnnAydAjSAHk=
 go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM=
 go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.8.0/go.mod h1:ztncjvKpotSUQq7rlgPibGt8kZfSI3/jI8EO7JjuY2c=
 go.opentelemetry.io/otel/sdk v1.8.0/go.mod h1:uPSfc+yfDH2StDM/Rm35WE8gXSNdvCg023J6HeGNO0c=
+go.opentelemetry.io/otel/trace v1.5.0/go.mod h1:sq55kfhjXYr1zVSyexg0w1mpa03AYXR5eyTkB9NPPdE=
 go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4=
 go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
@@ -559,12 +579,15 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
 golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 h1:/6y1LfuqNuQdHAm0jjtPtgRcxIxjVZgm5OTu8/QhZvk=
 golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
+golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -631,9 +654,12 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -642,6 +668,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -774,6 +802,7 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
 google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
 google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
+google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
 google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=

+ 28 - 0
models/article.go

@@ -144,3 +144,31 @@ func GetArticleCollectionList(condition string, userId int) (items []*ArticleCol
 type ArticleCollectionLIstResp struct {
 	List []*ArticleCollectionResp
 }
+
+type CygxArticleEs struct {
+	Id               int    `orm:"column(id);pk"`
+	ArticleId        int    `description:"文章id"`
+	Title            string `description:"标题"`
+	TitleEn          string `description:"英文标题 "`
+	UpdateFrequency  string `description:"更新周期"`
+	CreateDate       string `description:"创建时间"`
+	PublishDate      string `description:"发布时间"`
+	Body             string `description:"内容"`
+	BodyText         string `description:"内容"`
+	Abstract         string `description:"摘要"`
+	CategoryName     string `description:"一级分类"`
+	SubCategoryName  string `description:"二级分类"`
+	PublishStatus    int    `description:"发布状态"`
+	CategoryId       string `description:"分类id"`
+	ExpertBackground string `description:"专家背景"`
+	ExpertNumber     string `description:"专家编号"`
+	InterviewDate    string `description:"访谈日期"`
+	Department       string `description:"作者"`
+	ArticleIdMd5     string `description:"ID,md5值"`
+	IsClass          int    `description:"是否归类,1是,0否"`
+	IsSummary        bool   `description:"是否是纪要库,1是,0否"`
+	IsReport         bool   `description:"是否属于报告,1是,0否"`
+	ReportType       int    `description:"报告类型,1行业报告,2产业报告,0无"`
+	FileLink         string `description:"下载预览链接"`
+	MatchTypeName    string `description:"匹配类型"`
+}

+ 2 - 3
models/config.go

@@ -32,9 +32,8 @@ func UpdateConfigByCode(configValue, countryCode string) (err error) {
 }
 
 type ConfigResp struct {
-	Item    *CygxConfig
-	List    []*KeyWord `description:"图表搜索推荐"`
-	ListHot []*KeyWord `description:"热搜关键词"`
+	ListRecommend []*KeyWord `description:"图表搜索推荐"`
+	ListHot       []*KeyWord `description:"热搜关键词"`
 }
 
 //获取是否展示限免标签

+ 75 - 0
models/industry_map.go

@@ -0,0 +1,75 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type CygxIndustryMap struct {
+	IndustryMapId   int `orm:"column(industry_map_id);pk" description:"行业图谱id"`
+	IndustryMapName string
+	ParentId        int
+	CreateTime      time.Time
+}
+
+func GetCygxIndustryMapByName(industryName string) (item *CygxIndustryMap, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_industry_map WHERE industry_map_name=? ORDER BY parent_id ASC LIMIT 1 `
+	err = o.Raw(sql, industryName).QueryRow(&item)
+	return
+}
+
+func GetCygxIndustryMapAll() (items []*CygxIndustryMapItems, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_industry_map WHERE parent_id<>0`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+type CygxIndustryMapItems struct {
+	IndustryMapId   int `orm:"column(industry_map_id);" description:"行业图谱id"`
+	IndustryMapName string
+	ParentId        int
+	Level           int
+	Children        []*CygxIndustryMapItems
+}
+
+func GetCygxIndustryMapByParentId(parentId int) (items []*CygxIndustryMapItems, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_industry_map WHERE parent_id=?`
+	_, err = o.Raw(sql, parentId).QueryRows(&items)
+	return
+}
+
+func GetCygxIndustryMapByLevel(level int) (items []*CygxIndustryMapItems, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_industry_map WHERE level=?`
+	_, err = o.Raw(sql, level).QueryRows(&items)
+	return
+}
+
+//根据名称模糊匹配获取一条数据
+func GetFirstCygxIndustryItemByName(industryName string) (items *CygxIndustryMapItems, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_industry_map WHERE industry_map_name like '%` + industryName + `%' order by industry_map_id asc`
+	err = o.Raw(sql).QueryRow(&items)
+	return
+}
+
+//根据名称模糊匹配获取一条数据
+func GetFirstCygxIndustryListByName(industryName string) (list []*CygxIndustryMapItems, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_industry_map WHERE industry_map_name like '%` + industryName + `%' order by level,industry_map_id asc`
+	_, err = o.Raw(sql).QueryRows(&list)
+	return
+}
+
+//根据名称模糊匹配获取一条数据
+func FixLevelData(industryMapId int, level int) (list []*CygxIndustryMapItems, err error) {
+	o := orm.NewOrm()
+	sql := ` UPDATE cygx_industry_map set level = ? WHERE industry_map_id = ?`
+	_, err = o.Raw(sql, level, industryMapId).QueryRows(&list)
+	return
+}
+
+//func

+ 59 - 0
models/search.go

@@ -0,0 +1,59 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"time"
+)
+
+type SearchItem struct {
+	ArticleId        int      `description:"文章id"`
+	Body             []string `description:"搜索结果"`
+	Title            string   `description:"标题"`
+	PublishDate      string   `description:"发布时间"`
+	ExpertBackground string   `description:"专家背景"`
+	ImgUrlPc         string   `description:"图片链接"`
+	CategoryId       string   `description:"文章分类"`
+	Source           int      `description:"来源  1:文章, 2:图表"`
+}
+
+type CategoryItem struct {
+	CategoryName string
+}
+
+func GetCategoryByCompanyId(companyId int) (items []*CategoryItem, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT b.chart_permission_id,d.category_name FROM company_product AS a
+			INNER JOIN company_report_permission AS b ON a.company_id=b.company_id AND a.product_id=b.product_id
+			INNER JOIN cygx_permission_mapping AS d ON b.chart_permission_id=d.chart_permission_id
+			WHERE a.product_id=2
+			AND a.company_id=?`
+	_, err = o.Raw(sql, companyId).QueryRows(&items)
+	return
+}
+
+type SearchResp struct {
+	Paging    *paging.PagingItem
+	List      []*SearchItem
+	ChartList []*HomeChartListResp `description:"图表列表"`
+}
+
+type CygxSearchKeyWord struct {
+	Id          int `orm:"column(id);" description:"id"`
+	KeyWord     string
+	UserId      int
+	CreateTime  time.Time
+	Mobile      string `description:"手机号"`
+	Email       string `description:"邮箱"`
+	CompanyId   int    `description:"公司id"`
+	CompanyName string `description:"公司名称"`
+	RealName    string `description:"用户实际名称"`
+}
+
+//获取用户搜索词汇频率较高的词
+func GetSearchKeyWordTop() (items []*CygxSearchKeyWord, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT key_word, COUNT(*) AS num FROM cygx_search_key_word GROUP BY key_word ORDER BY num DESC LIMIT 8 `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}

+ 18 - 0
routers/commentsRouter.go

@@ -61,6 +61,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hongze_clpt/controllers:BaseSearchController"] = append(beego.GlobalControllerRouter["hongze/hongze_clpt/controllers:BaseSearchController"],
+        beego.ControllerComments{
+            Method: "BrowseHistoryList",
+            Router: `/keyWord`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hongze_clpt/controllers:ChartPermissionController"] = append(beego.GlobalControllerRouter["hongze/hongze_clpt/controllers:ChartPermissionController"],
         beego.ControllerComments{
             Method: "Detail",
@@ -79,6 +88,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hongze_clpt/controllers:MobileSearchController"] = append(beego.GlobalControllerRouter["hongze/hongze_clpt/controllers:MobileSearchController"],
+        beego.ControllerComments{
+            Method: "ListHomeArtAndChart",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hongze_clpt/controllers:UserCommonController"] = append(beego.GlobalControllerRouter["hongze/hongze_clpt/controllers:UserCommonController"],
         beego.ControllerComments{
             Method: "Login",

+ 6 - 0
routers/router.go

@@ -56,6 +56,12 @@ func init() {
 				&controllers.ArticleController{},
 			),
 		),
+		web.NSNamespace("/search",
+			web.NSInclude(
+				&controllers.MobileSearchController{},
+				&controllers.BaseSearchController{},
+			),
+		),
 	)
 	web.AddNamespace(ns)
 }

+ 240 - 0
services/elastic.go

@@ -0,0 +1,240 @@
+package services
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"github.com/olivere/elastic/v7"
+	"hongze/hongze_clpt/models"
+	"hongze/hongze_clpt/utils"
+	"strconv"
+)
+
+//func NewClient() (client *elastic.Client, err error) {
+//	//errorlog := log.New(os.Stdout, "APP", log.LstdFlags)
+//	//file := ""
+//	//if utils.RunMode == "release" {
+//	//	//file = `/data/rdlucklog/hongze_cygx/eslog.log`
+//	//	file = `./rdlucklog/eslog.log`
+//	//} else {
+//	//	file = `./rdlucklog/eslog.log`
+//	//}
+//	//logFile, _ := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766)
+//	//client, err = elastic.NewClient(
+//	//	elastic.SetURL(ES_URL),
+//	//	elastic.SetBasicAuth(ES_USERNAME, ES_PASSWORD),
+//	//	elastic.SetTraceLog(log.New(logFile, "ES-TRACE: ", 0)),
+//	//	elastic.SetSniff(false), elastic.SetErrorLog(errorlog))
+//	client, err = elastic.NewClient(
+//		elastic.SetURL(ES_URL),
+//		elastic.SetBasicAuth(ES_USERNAME, ES_PASSWORD),
+//		elastic.SetSniff(false))
+//	return
+//}
+
+func RemoveDuplicatesAndEmpty(a []string) (ret []string) {
+	a_len := len(a)
+	for i := 0; i < a_len; i++ {
+		if (i > 0 && a[i-1] == a[i]) || len(a[i]) == 0 {
+			continue
+		}
+		ret = append(ret, a[i])
+	}
+	return
+}
+
+func GetArrSum(intArr []int) (sum int) {
+	for _, val := range intArr {
+		//累计求和
+		sum += val
+	}
+	return
+}
+
+func EsMultiMatchFunctionScoreQuerySort(indexName, keyWord string, startSize, pageSize, userId int, orderColumn string) (result []*models.SearchItem, total int64, err error) {
+	client := utils.Client
+	keyWordArr, err := GetIndustryMapNameSliceV3(keyWord)
+	keyWordArr = RemoveDuplicatesAndEmpty(keyWordArr)
+	//artidArr := make([]elastic.Query, 0)
+	//matchArr := make([]elastic.Query, 0)
+	n := 0
+	keyWordLen := len(keyWordArr)
+	if keyWordLen <= 0 {
+		keyWordArr = append(keyWordArr, keyWord)
+		keyWordLen = len(keyWordArr)
+	}
+
+	// @Param   OrderColumn   query   int  true       "排序字段 ,Comprehensive综合 ,Matching匹配度 ,PublishDate 发布时间 "
+	utils.FileLog.Info("SearchKeyWord:%s, userId:%s", keyWordArr, strconv.Itoa(userId))
+	//keyWordWeight := GetWeight(keyWordLen)
+	for _, v := range keyWordArr {
+		if v != "" {
+			matchArr := make([]elastic.Query, 0)
+			boolquery := elastic.NewBoolQuery()
+			bodyFunctionQuery := elastic.NewFunctionScoreQuery()
+			bodyFunctionQuery2 := elastic.NewFunctionScoreQuery()
+			bodyFunctionQuery3 := elastic.NewFunctionScoreQuery()
+
+			//multiMatch := elastic.NewMultiMatchQuery(v, "Title", "BodyText").Analyzer("ik_smart")
+			multiMatch := elastic.NewMultiMatchQuery(v, "Title").Analyzer("ik_smart").Boost(100)
+			bodyFunctionQuery.Query(multiMatch)
+			matchArr = append(matchArr, bodyFunctionQuery)
+
+			multiMatch = elastic.NewMultiMatchQuery(v, "BodyText").Analyzer("ik_smart").Boost(1)
+			bodyFunctionQuery2.Query(multiMatch)
+			matchArr = append(matchArr, bodyFunctionQuery2)
+
+			//multiMatch = elastic.NewMultiMatchQuery(1, "IsSummary")
+			bodyFunctionQuery3.Query(multiMatch)
+			matchArr = append(matchArr, bodyFunctionQuery3)
+
+			boolquery.Should(matchArr...)
+
+			//multiMatch = elastic.NewMultiMatchQuery(v, "BodyText").Analyzer("ik_smart")
+			//bodyFunctionQuery.Query(multiMatch)
+			//matchArr = append(matchArr, bodyFunctionQuery)
+			//boolquery.Should(matchArr...)
+
+			highlight := elastic.NewHighlight()
+			highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
+			highlight = highlight.Fields(elastic.NewHighlighterField("Title"), elastic.NewHighlighterField("BodyText"))
+			request := client.Search(indexName).Highlight(highlight).Sort("PublishDate", false).From(0).Size(pageSize).Query(boolquery)
+			if orderColumn == "Matching" {
+				request = client.Search(indexName).Highlight(highlight).From(0).Size(pageSize).Query(boolquery)
+			}
+			searchByMatch, err := request.Do(context.Background())
+			if err != nil {
+				return nil, 0, err
+			}
+			if searchByMatch != nil {
+				if searchByMatch.Hits != nil {
+					for _, v := range searchByMatch.Hits.Hits {
+						var isAppend bool
+						articleJson, err := v.Source.MarshalJSON()
+						if err != nil {
+							return nil, 0, err
+						}
+						article := new(models.CygxArticleEs)
+						err = json.Unmarshal(articleJson, &article)
+						if err != nil {
+							return nil, 0, err
+						}
+						searchItem := new(models.SearchItem)
+						searchItem.ArticleId, _ = strconv.Atoi(v.Id)
+						if len(v.Highlight["BodyText"]) > 0 {
+							searchItem.Body = v.Highlight["BodyText"]
+						} else {
+							bodyRune := []rune(article.BodyText)
+							bodyRuneLen := len(bodyRune)
+							if bodyRuneLen > 100 {
+								bodyRuneLen = 100
+							}
+							body := string(bodyRune[:bodyRuneLen])
+							searchItem.Body = []string{body}
+						}
+						var title string
+						if len(v.Highlight["Title"]) > 0 {
+							title = v.Highlight["Title"][0]
+						} else {
+							title = article.Title
+						}
+						searchItem.Title = title
+						searchItem.PublishDate = article.PublishDate
+						searchItem.ExpertBackground = article.ExpertBackground
+						searchItem.CategoryId = article.CategoryId
+						for _, v_result := range result {
+							if v_result.ArticleId == searchItem.ArticleId {
+								isAppend = true
+							}
+						}
+						if !isAppend {
+							result = append(result, searchItem)
+						}
+					}
+				}
+				//total += searchByMatch.Hits.TotalHits.Value
+			}
+		}
+		n++
+	}
+	total = int64(len(result))
+	return
+}
+
+func EsMultiMatchFunctionScoreQueryTimeSort(indexName, keyWord string, startSize, pageSize, userId int) (result []*models.SearchItem, total int64, err error) {
+	client := utils.Client
+	keyWordArr, err := GetIndustryMapNameSliceV2(keyWord)
+
+	keyWordArr = RemoveDuplicatesAndEmpty(keyWordArr)
+	boolquery := elastic.NewBoolQuery()
+	matchArr := make([]elastic.Query, 0)
+	//matchArr2 := make([]elastic.Query, 0)
+
+	n := 0
+	keyWordLen := len(keyWordArr)
+	if keyWordLen <= 0 {
+		keyWordArr = append(keyWordArr, keyWord)
+		keyWordLen = len(keyWordArr)
+	}
+	utils.FileLog.Info("SearchKeyWord:%s, userId:%s", keyWordArr, strconv.Itoa(userId))
+	for _, v := range keyWordArr {
+		if v != "" {
+			multiMatch := elastic.NewMultiMatchQuery(v, "Title", "BodyText")
+			bodyFunctionQuery := elastic.NewFunctionScoreQuery()
+			bodyFunctionQuery.Query(multiMatch)
+			matchArr = append(matchArr, bodyFunctionQuery)
+		}
+		n++
+	}
+	boolquery.Should(matchArr...)
+	highlight := elastic.NewHighlight()
+	highlight = highlight.Fields(elastic.NewHighlighterField("Title"), elastic.NewHighlighterField("BodyText"))
+	highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
+	request := client.Search(indexName).Highlight(highlight).Sort("PublishDate", false).Size(pageSize).Query(boolquery)
+	searchByMatch, err := request.Do(context.Background())
+	if searchByMatch != nil {
+		matchResult, _ := json.Marshal(searchByMatch)
+		utils.FileLog.Info("%s", string(matchResult))
+		fmt.Println(len(searchByMatch.Hits.Hits))
+		if searchByMatch.Hits != nil {
+			for _, v := range searchByMatch.Hits.Hits {
+				articleJson, err := v.Source.MarshalJSON()
+				utils.FileLog.Info("%s", string(articleJson))
+				if err != nil {
+					return nil, 0, err
+				}
+				article := new(models.CygxArticleEs)
+				err = json.Unmarshal(articleJson, &article)
+				if err != nil {
+					return nil, 0, err
+				}
+				searchItem := new(models.SearchItem)
+				searchItem.ArticleId, _ = strconv.Atoi(v.Id)
+				if len(v.Highlight["BodyText"]) > 0 {
+					searchItem.Body = v.Highlight["BodyText"]
+				} else {
+					bodyRune := []rune(article.BodyText)
+					bodyRuneLen := len(bodyRune)
+					if bodyRuneLen > 100 {
+						bodyRuneLen = 100
+					}
+					body := string(bodyRune[:bodyRuneLen])
+					searchItem.Body = []string{body}
+				}
+				var title string
+				if len(v.Highlight["Title"]) > 0 {
+					title = v.Highlight["Title"][0]
+				} else {
+					title = article.Title
+				}
+				searchItem.Title = title
+				searchItem.PublishDate = article.PublishDate
+				searchItem.ExpertBackground = article.ExpertBackground
+				searchItem.CategoryId = article.CategoryId
+				result = append(result, searchItem)
+			}
+		}
+		total = searchByMatch.Hits.TotalHits.Value
+	}
+	return
+}

+ 620 - 0
services/industry_map.go

@@ -0,0 +1,620 @@
+package services
+
+import (
+	"fmt"
+	"hongze/hongze_clpt/models"
+	"math/rand"
+	"reflect"
+	"sort"
+	"time"
+)
+
+func MakeTree(allNode []*models.CygxIndustryMapItems, node *models.CygxIndustryMapItems) {
+	childs, _ := haveChild(allNode, node) //判断节点是否有子节点并返回
+	if len(childs) > 0 {
+		node.Children = append(node.Children, childs[0:]...) //添加子节点
+		for _, v := range childs {                           //查询子节点的子节点,并添加到子节点
+			_, has := haveChild(allNode, v)
+			if has {
+				MakeTree(allNode, v) //递归添加节点
+			}
+		}
+	}
+}
+
+func haveChild(allNode []*models.CygxIndustryMapItems, node *models.CygxIndustryMapItems) (childs []*models.CygxIndustryMapItems, yes bool) {
+	for _, v := range allNode {
+		if v.ParentId == node.IndustryMapId {
+			childs = append(childs, v)
+		}
+	}
+	if len(childs) > 0 {
+		yes = true
+	}
+	return
+}
+
+func GetIndustryMap() {
+	list, err := models.GetCygxIndustryMapByParentId(0)
+	if err != nil {
+		return
+	}
+	rootNode := list[0]
+	allNodes, err := models.GetCygxIndustryMapAll()
+	if err != nil {
+		return
+	}
+	MakeTree(allNodes, rootNode)
+}
+
+func GetIndustryTree() (rootNode *models.CygxIndustryMapItems, err error) {
+	//fmt.Println("start")
+	list, err := models.GetCygxIndustryMapByParentId(0)
+	if err != nil {
+		return
+	}
+	rootNode = list[0]
+	allNodes, err := models.GetCygxIndustryMapAll()
+	if err != nil {
+		return
+	}
+	MakeTree(allNodes, rootNode)
+	//resultJson,err:=json.Marshal(rootNode)
+	//fmt.Println("Err:",err)
+	//fmt.Println("allNodes:",string(resultJson))
+	//utils.FileLog.Info("allNodes:%s",string(resultJson))
+	//fmt.Println("end")
+	return
+}
+
+//获取对应的层级map
+func getMap(tree *models.CygxIndustryMapItems, item *models.CygxIndustryMapItems, hasIdMap map[int]string, otherChildMapSlice map[int][]*models.CygxIndustryMapItems) {
+	//深度
+	depth := 1
+
+	//获取下级
+	childTree := getChildTree(tree, item)
+	depth = childTreeToSlice(childTree, hasIdMap, depth, otherChildMapSlice)
+
+	//获取上级
+	var tmpParentSlice []*models.CygxIndustryMapItems
+	tmpParentSlice, _ = parentTreeToSlice(tree, item, 0, tmpParentSlice, hasIdMap)
+	//移除第一个最上级的行业(根节点)
+	tmpParentSlice = append(tmpParentSlice[:0], tmpParentSlice[1:len(tmpParentSlice)]...)
+	//切片反转
+	tmpParentSlice = reverse(tmpParentSlice)
+	for _, v := range tmpParentSlice {
+		depth++
+		if _, ok := hasIdMap[v.IndustryMapId]; ok == false {
+			otherChildMapSlice[depth] = append(otherChildMapSlice[depth], v)
+		}
+	}
+
+	//获取同级
+	//fmt.Println("===============")
+	depth = siblingTreeToSlice(tree, item, hasIdMap, depth, otherChildMapSlice)
+
+	//上级的同级~
+	/*for _,parentSlice := range tmpParentSlice{
+		depth = siblingTreeToSlice(tree,parentSlice,hasIdMap,depth,otherChildMapSlice)
+	}*/
+	return
+}
+
+//获取行业图谱切片
+func GetIndustryMapNameSlice(industryName string) (nameSlice []string, err error) {
+	nameSlice = append(nameSlice, industryName)
+	tree, err := GetIndustryTree()
+	if err != nil {
+		return
+	}
+	//已经存在的行业id的map集合
+	hasIdMap := make(map[int]string)
+	itemList, err := models.GetFirstCygxIndustryListByName(industryName)
+	if err != nil {
+		return
+	}
+	//找不到对应的数据
+	if len(itemList) <= 0 {
+		return
+	}
+
+	industryMapList := make(map[int][]*models.CygxIndustryMapItems)
+	for _, item := range itemList {
+		industryMapList[item.Level] = append(industryMapList[item.Level], item)
+	}
+
+	//将查出来的根节点数据的key取出来,放在切片中,并对该切片做正序排列
+	var sortIndustryList []int
+	for k, _ := range industryMapList {
+		sortIndustryList = append(sortIndustryList, k)
+	}
+	sort.Ints(sortIndustryList)
+
+	//最底层节点的数据集合
+	list := industryMapList[sortIndustryList[0]]
+
+	otherChildMapSlice := map[int][]*models.CygxIndustryMapItems{}
+	for _, item := range list {
+		hasIdMap[item.IndustryMapId] = ""
+		//将自己的节点给加进去
+		otherChildMapSlice[0] = append(otherChildMapSlice[0], item)
+		getMap(tree, item, hasIdMap, otherChildMapSlice)
+	}
+	var tmpSlice []*models.CygxIndustryMapItems
+
+	//将其他规律数据的key取出来,放在切片中,并对该切片做正序排列
+	var sortList []int
+	for k, _ := range otherChildMapSlice {
+		sortList = append(sortList, k)
+	}
+	sort.Ints(sortList)
+
+	//遍历该切片,根据下标key获取对应的数据,并插入到主数据中
+	for _, v := range sortList {
+		tmpChildSlice := otherChildMapSlice[v]
+		randSlice(tmpChildSlice)
+		tmpSlice = append(tmpSlice, tmpChildSlice...)
+		//fmt.Println(k,"=====")
+		//for _,tmpV := range otherChildMapSlice[v]{
+		//	fmt.Println(tmpV.IndustryMapName)
+		//}
+	}
+	//名字切片
+	for _, v := range tmpSlice {
+		//fmt.Println("k===",k,"=======v=======",v)
+		nameSlice = append(nameSlice, v.IndustryMapName)
+	}
+
+	//fmt.Println(nameSlice)
+	//fmt.Println(strings.Join(nameSlice,","))
+	//utils.FileLog.Info("allNodes:%s",strings.Join(nameSlice,","))
+	return
+}
+
+//切片反转
+func reverse(s []*models.CygxIndustryMapItems) []*models.CygxIndustryMapItems {
+	for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
+		s[i], s[j] = s[j], s[i]
+	}
+	return s
+}
+
+//获取当前节点的树
+func getChildTree(rootNode *models.CygxIndustryMapItems, nowNode *models.CygxIndustryMapItems) (returnNode *models.CygxIndustryMapItems) {
+	if rootNode.IndustryMapId == nowNode.IndustryMapId {
+		returnNode = rootNode
+		return
+	}
+	if rootNode.Children != nil {
+		for _, v := range rootNode.Children {
+			if v.IndustryMapId == nowNode.IndustryMapId {
+				returnNode = v
+			} else {
+				returnNode = getChildTree(v, nowNode)
+			}
+			if returnNode != nil {
+				return
+			}
+		}
+	}
+	return
+}
+
+//获取子树V2,与上一个子树规律不一样,因为上级
+func childTreeToSlice(rootNode *models.CygxIndustryMapItems, hasIdMap map[int]string, depth int, otherChildMapSlice map[int][]*models.CygxIndustryMapItems) (maxDepth int) {
+	if rootNode.Children != nil {
+		depth++
+		maxDepth = depth
+		for _, v := range rootNode.Children {
+			//判断是否已经录入,如果已经录入,那么不处理
+			if _, ok := hasIdMap[v.IndustryMapId]; ok == false {
+				otherChildMapSlice[depth] = append(otherChildMapSlice[depth], v)
+			}
+		}
+
+		for _, v := range rootNode.Children {
+			//判断是否已经录入,如果已经录入,那么不处理
+			if _, ok := hasIdMap[v.IndustryMapId]; ok == false {
+				hasIdMap[v.IndustryMapId] = ""
+				returnDepth := childTreeToSlice(v, hasIdMap, depth, otherChildMapSlice)
+				if returnDepth > maxDepth {
+					maxDepth = returnDepth
+				}
+			}
+		}
+	}
+	return maxDepth
+}
+
+//获取兄弟级树
+func siblingTreeToSlice(rootNode *models.CygxIndustryMapItems, nowNode *models.CygxIndustryMapItems, hasIdMap map[int]string, depth int, otherChildMapSlice map[int][]*models.CygxIndustryMapItems) (maxDepth int) {
+	if rootNode.Children != nil {
+		depth++
+		maxDepth = depth
+		for _, v := range rootNode.Children {
+			//如果父级id一致的情况下,那么代表这是兄弟节点或者是自己了
+			if v.ParentId == nowNode.ParentId {
+				//判断是否已经录入,如果已经录入,那么不处理
+				if _, ok := hasIdMap[v.IndustryMapId]; ok == false {
+					otherChildMapSlice[depth] = append(otherChildMapSlice[depth], v)
+					returnDepth := childTreeToSlice(v, hasIdMap, depth, otherChildMapSlice)
+					if returnDepth > maxDepth {
+						maxDepth = returnDepth
+					}
+				}
+			} else {
+				returnDepth := siblingTreeToSlice(v, nowNode, hasIdMap, depth, otherChildMapSlice)
+				if returnDepth > maxDepth {
+					maxDepth = returnDepth
+				}
+			}
+		}
+
+		for _, v := range rootNode.Children {
+			if v.ParentId == nowNode.ParentId {
+				if _, ok := hasIdMap[v.IndustryMapId]; ok == false {
+					hasIdMap[v.IndustryMapId] = ""
+				}
+
+			}
+		}
+	}
+	return
+}
+
+//获取上级树
+func parentTreeToSlice(rootNode *models.CygxIndustryMapItems, nowNode *models.CygxIndustryMapItems, depth int, tmpReturnSlice []*models.CygxIndustryMapItems, hasIdMap map[int]string) (returnSlice []*models.CygxIndustryMapItems, ok bool) {
+	if depth != 0 {
+		returnSlice = tmpReturnSlice
+	}
+	depth++
+	returnSlice = append(returnSlice, rootNode)
+	//if _,ok := hasIdMap[rootNode.IndustryMapId];ok==false{
+	//	hasIdMap[rootNode.IndustryMapId] = ""
+	//}
+	if rootNode.Children != nil {
+		for _, v := range rootNode.Children {
+			if v.ParentId == nowNode.ParentId {
+				ok = true
+				return
+			}
+			returnSlice, ok = parentTreeToSlice(v, nowNode, depth, returnSlice, hasIdMap)
+			//如果返回的匹配完成,那么不进入下一次循环,直接返回
+			if ok {
+				return
+			}
+
+			//一次循环结束后,如果没有匹配上,那么移除临时切片中的数据
+			returnSlice = append(returnSlice[:0], returnSlice[0:depth]...)
+		}
+	}
+
+	return
+}
+
+//切片乱序
+func randSlice(slice []*models.CygxIndustryMapItems) {
+	rv := reflect.ValueOf(slice)
+	if rv.Type().Kind() != reflect.Slice {
+		return
+	}
+
+	length := rv.Len()
+	if length < 2 {
+		return
+	}
+
+	swap := reflect.Swapper(slice)
+	rand.Seed(time.Now().Unix())
+	for i := length - 1; i >= 0; i-- {
+		j := rand.Intn(length)
+		swap(i, j)
+	}
+	return
+}
+
+//获取行业图谱切片(v2版本,调整时间:2021-03-19 18:02:07)
+func GetIndustryMapNameSliceV2(industryName string) (nameSlice []string, err error) {
+	nameSlice = append(nameSlice, industryName)
+	tree, err := GetIndustryTree()
+	if err != nil {
+		fmt.Println("获取树失败")
+		return
+	}
+
+	//fmt.Println(tree)
+
+	//已经存在的行业id的map集合
+	hasIdMap := make(map[int]string)
+	itemList, err := models.GetFirstCygxIndustryListByName(industryName)
+	if err != nil {
+		fmt.Println("获取数据失败,", err)
+		return
+	}
+	//找不到对应的数据
+	if len(itemList) <= 0 {
+		return
+	}
+
+	industryMapList := make(map[int][]*models.CygxIndustryMapItems)
+	//TODO  这里好像有问题,如果传入行业的话,上面再没有是否只是找到第一个节点判断,那么就会异常抛出
+	for _, item := range itemList {
+		industryMapList[item.Level] = append(industryMapList[item.Level], item)
+	}
+
+	//将查出来的根节点数据的key取出来,放在切片中,并对该切片做正序排列
+	var sortIndustryList []int
+	for k, _ := range industryMapList {
+		sortIndustryList = append(sortIndustryList, k)
+	}
+	sort.Ints(sortIndustryList)
+
+	//最底层节点的数据集合
+	list := industryMapList[sortIndustryList[0]]
+
+	//如果该数据正好是第一层节点数据,那么需要额外判断下
+	if list[0].ParentId <= 2 {
+		//如果存在第二级,那么就使用该层级
+		if len(sortIndustryList) > 1 {
+			list = industryMapList[sortIndustryList[1]]
+		}
+	}
+	//fmt.Println(list)
+	//return
+
+	otherChildMapSlice := map[int][]*models.CygxIndustryMapItems{}
+
+	//多个节点时,额外处理
+	if len(list) > 1 {
+		for _, item := range list {
+			hasIdMap[item.IndustryMapId] = ""
+			//将自己的节点给加进去
+			otherChildMapSlice[0] = append(otherChildMapSlice[0], item)
+
+			//获取上级
+			var tmpParentSlice []*models.CygxIndustryMapItems
+			tmpParentSlice, _ = parentTreeToSlice(tree, item, 0, tmpParentSlice, hasIdMap)
+			//父节点
+			parentItem := tmpParentSlice[len(tmpParentSlice)-1]
+			if _, ok := hasIdMap[parentItem.IndustryMapId]; ok == false {
+				hasIdMap[parentItem.IndustryMapId] = ""
+				otherChildMapSlice[1] = append(otherChildMapSlice[1], parentItem)
+			}
+		}
+	} else {
+		//匹配到单个节点
+		item := list[0]
+		hasIdMap[item.IndustryMapId] = ""
+		//将自己的节点给加进去
+		otherChildMapSlice[0] = append(otherChildMapSlice[0], item)
+		childTree := getChildTree(tree, item)
+
+		//如果是命中到最后一层节点
+		if len(childTree.Children) == 0 {
+			//获取上级
+			var tmpParentSlice []*models.CygxIndustryMapItems
+			tmpParentSlice, _ = parentTreeToSlice(tree, item, 0, tmpParentSlice, hasIdMap)
+			//父节点
+			parentItem := tmpParentSlice[len(tmpParentSlice)-1]
+
+			if _, ok := hasIdMap[parentItem.IndustryMapId]; ok == false {
+				hasIdMap[parentItem.IndustryMapId] = ""
+				otherChildMapSlice[1] = append(otherChildMapSlice[1], parentItem)
+			}
+
+			//兄弟节点
+			siblingTreeToSliceV2(parentItem, item, hasIdMap, 2, otherChildMapSlice)
+		} else {
+			//如果不是命中到最后一层节点
+			otherChildMapSlice[1] = append(otherChildMapSlice[1], childTree.Children...)
+		}
+	}
+
+	//return
+	var tmpSlice []*models.CygxIndustryMapItems
+
+	//将其他规律数据的key取出来,放在切片中,并对该切片做正序排列
+	var sortList []int
+	for k, _ := range otherChildMapSlice {
+		sortList = append(sortList, k)
+	}
+	sort.Ints(sortList)
+
+	//遍历该切片,根据下标key获取对应的数据,并插入到主数据中
+	for _, v := range sortList {
+		tmpChildSlice := otherChildMapSlice[v]
+		randSlice(tmpChildSlice)
+		tmpSlice = append(tmpSlice, tmpChildSlice...)
+		//fmt.Println(k,"=====")
+		//for _,tmpV := range otherChildMapSlice[v]{
+		//	fmt.Println(tmpV.IndustryMapName)
+		//}
+	}
+	//名字切片
+	for _, v := range tmpSlice {
+		//fmt.Println("k===",k,"=======v=======",v)
+		nameSlice = append(nameSlice, v.IndustryMapName)
+	}
+
+	//fmt.Println(nameSlice)
+	//fmt.Println(strings.Join(nameSlice,","))
+	//utils.FileLog.Info("allNodes:%s",strings.Join(nameSlice,","))
+	return
+}
+
+//获取行业图谱切片(v3版本,调整时间:2021-04-20 17:23:31,不乱序)
+func GetIndustryMapNameSliceV3(industryName string) (nameSlice []string, err error) {
+	nameSlice = append(nameSlice, industryName)
+	tree, err := GetIndustryTree()
+	if err != nil {
+		fmt.Println("获取树失败")
+		return
+	}
+
+	//fmt.Println(tree)
+
+	//已经存在的行业id的map集合
+	hasIdMap := make(map[int]string)
+	itemList, err := models.GetFirstCygxIndustryListByName(industryName)
+	if err != nil {
+		fmt.Println("获取数据失败,", err)
+		return
+	}
+	//找不到对应的数据
+	if len(itemList) <= 0 {
+		return
+	}
+
+	industryMapList := make(map[int][]*models.CygxIndustryMapItems)
+	//TODO  这里好像有问题,如果传入行业的话,上面再没有是否只是找到第一个节点判断,那么就会异常抛出
+	for _, item := range itemList {
+		industryMapList[item.Level] = append(industryMapList[item.Level], item)
+	}
+
+	//将查出来的根节点数据的key取出来,放在切片中,并对该切片做正序排列
+	var sortIndustryList []int
+	for k, _ := range industryMapList {
+		sortIndustryList = append(sortIndustryList, k)
+	}
+	sort.Ints(sortIndustryList)
+
+	//最底层节点的数据集合
+	list := industryMapList[sortIndustryList[0]]
+
+	//如果该数据正好是第一层节点数据,那么需要额外判断下
+	if list[0].ParentId <= 2 {
+		//如果存在第二级,那么就使用该层级
+		if len(sortIndustryList) > 1 {
+			list = industryMapList[sortIndustryList[1]]
+		}
+	}
+	//fmt.Println(list)
+	//return
+
+	otherChildMapSlice := map[int][]*models.CygxIndustryMapItems{}
+
+	//多个节点时,额外处理
+	if len(list) > 1 {
+		for _, item := range list {
+			hasIdMap[item.IndustryMapId] = ""
+			//将自己的节点给加进去
+			otherChildMapSlice[0] = append(otherChildMapSlice[0], item)
+
+			//获取上级
+			var tmpParentSlice []*models.CygxIndustryMapItems
+			tmpParentSlice, _ = parentTreeToSlice(tree, item, 0, tmpParentSlice, hasIdMap)
+			//父节点
+			parentItem := tmpParentSlice[len(tmpParentSlice)-1]
+			if _, ok := hasIdMap[parentItem.IndustryMapId]; ok == false {
+				hasIdMap[parentItem.IndustryMapId] = ""
+				otherChildMapSlice[1] = append(otherChildMapSlice[1], parentItem)
+			}
+		}
+	} else {
+		//匹配到单个节点
+		item := list[0]
+		hasIdMap[item.IndustryMapId] = ""
+		//将自己的节点给加进去
+		otherChildMapSlice[0] = append(otherChildMapSlice[0], item)
+		childTree := getChildTree(tree, item)
+
+		//如果是命中到最后一层节点
+		if len(childTree.Children) == 0 {
+			//获取上级
+			var tmpParentSlice []*models.CygxIndustryMapItems
+			tmpParentSlice, _ = parentTreeToSlice(tree, item, 0, tmpParentSlice, hasIdMap)
+			//父节点
+			parentItem := tmpParentSlice[len(tmpParentSlice)-1]
+
+			if _, ok := hasIdMap[parentItem.IndustryMapId]; ok == false {
+				hasIdMap[parentItem.IndustryMapId] = ""
+				otherChildMapSlice[1] = append(otherChildMapSlice[1], parentItem)
+			}
+
+			//兄弟节点
+			siblingTreeToSliceV2(parentItem, item, hasIdMap, 2, otherChildMapSlice)
+		} else {
+			//如果不是命中到最后一层节点
+			otherChildMapSlice[1] = append(otherChildMapSlice[1], childTree.Children...)
+		}
+	}
+
+	//return
+	var tmpSlice []*models.CygxIndustryMapItems
+
+	//将其他规律数据的key取出来,放在切片中,并对该切片做正序排列
+	var sortList []int
+	for k, _ := range otherChildMapSlice {
+		sortList = append(sortList, k)
+	}
+	sort.Ints(sortList)
+
+	//遍历该切片,根据下标key获取对应的数据,并插入到主数据中
+	for _, v := range sortList {
+		tmpChildSlice := otherChildMapSlice[v]
+		//randSlice(tmpChildSlice)
+		tmpSlice = append(tmpSlice, tmpChildSlice...)
+		//fmt.Println(k,"=====")
+		//for _,tmpV := range otherChildMapSlice[v]{
+		//	fmt.Println(tmpV.IndustryMapName)
+		//}
+	}
+	//名字切片
+	for _, v := range tmpSlice {
+		//fmt.Println("k===",k,"=======v=======",v)
+		nameSlice = append(nameSlice, v.IndustryMapName)
+	}
+
+	//fmt.Println(nameSlice)
+	//fmt.Println(strings.Join(nameSlice,","))
+	//utils.FileLog.Info("allNodes:%s",strings.Join(nameSlice,","))
+	return
+}
+
+//获取兄弟级树
+func siblingTreeToSliceV2(rootNode *models.CygxIndustryMapItems, nowNode *models.CygxIndustryMapItems, hasIdMap map[int]string, depth int, otherChildMapSlice map[int][]*models.CygxIndustryMapItems) (maxDepth int) {
+	if rootNode.Children != nil {
+		depth++
+		maxDepth = depth
+		for _, v := range rootNode.Children {
+			//如果父级id一致的情况下,那么代表这是兄弟节点或者是自己了
+			if v.ParentId == nowNode.ParentId {
+				//判断是否已经录入,如果已经录入,那么不处理
+				if _, ok := hasIdMap[v.IndustryMapId]; ok == false {
+					otherChildMapSlice[depth] = append(otherChildMapSlice[depth], v)
+					hasIdMap[v.IndustryMapId] = ""
+				}
+			} else {
+				returnDepth := siblingTreeToSliceV2(v, nowNode, hasIdMap, depth, otherChildMapSlice)
+				if returnDepth > maxDepth {
+					maxDepth = returnDepth
+				}
+			}
+		}
+	}
+	return
+}
+
+//region数据修复
+func FixData() {
+	tree, err := GetIndustryTree()
+	if err != nil {
+	}
+	models.FixLevelData(tree.IndustryMapId, 1)
+	fixData(tree, 1)
+	return
+}
+
+func fixData(item *models.CygxIndustryMapItems, depth int) {
+	depth++
+	if item.Children == nil {
+		return
+	}
+	for _, v := range item.Children {
+		models.FixLevelData(v.IndustryMapId, depth)
+		fixData(v, depth)
+	}
+}
+
+//endregion

+ 6 - 0
utils/config.go

@@ -31,6 +31,8 @@ var (
 	WxMsgTemplateIdApply          string //申请待处理
 	WxMsgTemplateIdAskMsgMobile   string //手机号用户【XXX】发送模板消息
 	WxMsgTemplateIdAskMsgXzs      string //手机号用户【XXX】发送模板消息模板ID(小助手)
+
+	IndexName string
 )
 
 func init() {
@@ -78,6 +80,8 @@ func init() {
 		WxMsgTemplateIdApply = "PaoDanHGlt1kFw5q-4_ipJSwO3FyZpxSSNg4rwB7YCk"
 		WxMsgTemplateIdAskMsgMobile = "15557270714,17634786714,18767183922,17516315016"
 		WxMsgTemplateIdAskMsgXzs = "IpS-yuNNQc8osCoy20jPHNkvBUyKRL1NGn7c0G9xmQA" //手机号用户【XXX】发送模板消息模板ID(小助手)
+
+		IndexName = "cygx_article_v0718"
 	} else {
 		WxPublicAppId = "wx9b5d7291e581233a"                                          //弘则投研公众号 开发者ID(AppID)
 		WxPublicAppSecret = "f4d52e34021eee262dce9682b31f8861"                        //弘则投研公众号秘钥
@@ -86,6 +90,8 @@ func init() {
 		WxMsgTemplateIdApply = "qfNuops-sKrfIkbA7U97A7gSrX03mUpoEpJksRUdloo"
 		WxMsgTemplateIdAskMsgMobile = "15557270714,17634786714,18767183922,17516315016"
 		WxMsgTemplateIdAskMsgXzs = "qfNuops-sKrfIkbA7U97A7gSrX03mUpoEpJksRUdloo" //手机号用户【XXX】发送模板消息模板ID(小助手)
+
+		IndexName = "cygx_article_v1"
 	}
 	HeadimgurlDefault = "https://hongze.oss-cn-shanghai.aliyuncs.com/static/images/202202/20220225/XFBBOUmDC5AXkfxnHiuqKpPtoofH.png"
 }

+ 27 - 0
utils/elastic.go

@@ -0,0 +1,27 @@
+package utils
+
+import (
+	"github.com/olivere/elastic/v7"
+	"time"
+)
+
+var Client *elastic.Client
+
+const (
+	ES_URL      = "http://es-cn-nif227b580019rgw6.public.elasticsearch.aliyuncs.com:9200" //<1>
+	ES_USERNAME = "elastic"                                                               //<2>
+	ES_PASSWORD = "hongze@2021"                                                           //<3>
+)
+
+func init() {
+	client, err := elastic.NewClient(
+		elastic.SetURL(ES_URL),
+		elastic.SetBasicAuth(ES_USERNAME, ES_PASSWORD),
+		elastic.SetSniff(false))
+	Client = client
+	if err != nil {
+		go SendAlarmMsg("ElasticSearch连接失败", 2)
+		go SendEmail("ElasticSearch连接失败"+time.Now().Format("2006-01-02 15:04:05"), err.Error(), EmailSendToUsers)
+	}
+	return
+}