kobe6258 3 mesi fa
parent
commit
a271419a98

+ 38 - 1
common/component/es/es.go

@@ -42,6 +42,7 @@ const (
 	RangeByConditionWithDocIds = "range_by_condition_with_doc_ids"
 	RangeByConditionWithDocIds = "range_by_condition_with_doc_ids"
 
 
 	RangeWithDocIds = "range_with_doc_ids"
 	RangeWithDocIds = "range_with_doc_ids"
+	LimitByScore    = "limit_by_score"
 )
 )
 
 
 func GetInstance() *ESClient {
 func GetInstance() *ESClient {
@@ -170,6 +171,7 @@ type ESQueryRequest struct {
 	DocIds         []string
 	DocIds         []string
 	Max            interface{}
 	Max            interface{}
 	Min            interface{}
 	Min            interface{}
+	MinScore       float64
 }
 }
 
 
 func (req *ESQueryRequest) CreateESQueryRequest(index string, column string, key string, from int, size int, sorts []string, searchType SearchType) *ESQueryRequest {
 func (req *ESQueryRequest) CreateESQueryRequest(index string, column string, key string, from int, size int, sorts []string, searchType SearchType) *ESQueryRequest {
@@ -183,7 +185,14 @@ func (req *ESQueryRequest) CreateESQueryRequest(index string, column string, key
 		Sorts:     sorts,
 		Sorts:     sorts,
 	}
 	}
 }
 }
-
+func (req *ESQueryRequest) Limit(limit int) *ESQueryRequest {
+	req.Size = limit
+	return req
+}
+func (req *ESQueryRequest) WithScore(score float64) *ESQueryRequest {
+	req.MinScore = score
+	return req
+}
 func (req *ESQueryRequest) Range(from int64, to int64, column string) *ESQueryRequest {
 func (req *ESQueryRequest) Range(from int64, to int64, column string) *ESQueryRequest {
 	req.RangeColumn = column
 	req.RangeColumn = column
 	req.Max = to
 	req.Max = to
@@ -400,6 +409,34 @@ func (req *ESQueryRequest) parseJsonQuery() (queryMap map[string]interface{}) {
 			},
 			},
 		}
 		}
 		return
 		return
+	case LimitByScore:
+		queryMap = map[string]interface{}{
+			"query": map[string]interface{}{
+				"match": map[string]interface{}{
+					req.Column: req.Key,
+				},
+			},
+			"highlight": map[string]interface{}{
+				"fields": map[string]interface{}{
+					req.Column: map[string]interface{}{},
+				},
+				"pre_tags":  []string{"<span style='color:#0078E8'>"},
+				"post_tags": []string{"</span>"},
+			},
+			"post_filter": map[string]interface{}{
+				"bool": map[string]interface{}{
+					"must": []map[string]interface{}{
+						{
+							"terms": map[string]interface{}{
+								"_id": req.DocIds,
+							},
+						},
+					},
+				},
+			},
+			"min_score": req.MinScore,
+		}
+		return
 	default:
 	default:
 		queryMap = map[string]interface{}{}
 		queryMap = map[string]interface{}{}
 		return
 		return

+ 6 - 5
common/utils/page/page_utils.go

@@ -13,11 +13,12 @@ type PageResult struct {
 	Data interface{}
 	Data interface{}
 }
 }
 type Page struct {
 type Page struct {
-	LatestId  int64 `json:"latestId,omitempty"`
-	Current   int   `json:"current"`
-	PageSize  int   `json:"pageSize"`
-	Total     int64 `json:"total"`
-	TotalPage int   `json:"totalPage"`
+	LatestId  int64  `json:"latestId,omitempty"`
+	Current   int    `json:"current"`
+	PageSize  int    `json:"pageSize"`
+	Total     int64  `json:"total"`
+	Range     string `json:"range"`
+	TotalPage int    `json:"totalPage"`
 }
 }
 
 
 func StartIndex(page, pagesize int) int {
 func StartIndex(page, pagesize int) int {

+ 51 - 21
controllers/product/product_controller.go

@@ -7,6 +7,7 @@ import (
 	"eta/eta_mini_ht_api/controllers"
 	"eta/eta_mini_ht_api/controllers"
 	productService "eta/eta_mini_ht_api/service/product"
 	productService "eta/eta_mini_ht_api/service/product"
 	"eta/eta_mini_ht_api/service/user"
 	"eta/eta_mini_ht_api/service/user"
+	"sync/atomic"
 )
 )
 
 
 var (
 var (
@@ -86,26 +87,61 @@ func (p *ProductController) RelatePackage(productId int) {
 	})
 	})
 }
 }
 
 
-// ProductSearch  获取商品信息
-// @Summary 获取商品信息
-// @Description 获取商品信息
+// ProductSearch  搜索产品
+// @Summary 搜索产品
+// @Description 搜索产品
 // @Success 200 {object} controllers.BaseResponse
 // @Success 200 {object} controllers.BaseResponse
 // @router /productSearch [get]
 // @router /productSearch [get]
-func (p *ProductController) ProductSearch(productType, key string, isSignal bool) {
+func (p *ProductController) ProductSearch(key string, isSignal bool) {
 	controllers.Wrap(&p.BaseController, func() (result *controllers.WrapData, err error) {
 	controllers.Wrap(&p.BaseController, func() (result *controllers.WrapData, err error) {
 		result = p.InitWrapData("搜索产品信息失败")
 		result = p.InitWrapData("搜索产品信息失败")
-		//userInfo := p.Data["user"].(user.User)
-		if !productMap[productType] {
-			err = exception.New(exception.ProductTypeError)
-			p.FailedResult("搜索产品信息失败", result)
-			return
-		}
+		userInfo := p.Data["user"].(user.User)
 		var productList []productService.ProductDTO
 		var productList []productService.ProductDTO
+		var permissionWeightMap map[int]*atomic.Int32
 		pageRes := page.Page{
 		pageRes := page.Page{
 			Current:  p.PageInfo.Current,
 			Current:  p.PageInfo.Current,
 			PageSize: p.PageInfo.PageSize,
 			PageSize: p.PageInfo.PageSize,
 		}
 		}
-		//pageRes.Total, pageRes.LatestId = productService.RangeProductList(isSignal)
+		productIdMap, err := productService.RangeProductList()
+		if err != nil {
+			logger.Error("搜索产品信息失败")
+			err = exception.NewWithException(exception.GetProductListFailed, err.Error())
+			return
+		}
+		productPage := new(page.PageResult)
+		if isSignal {
+			if len(productIdMap["report"]) == 0 && len(productIdMap["audio"]) == 0 && len(productIdMap["video"]) == 0 {
+				logger.Info("没有相关的产品类型产品")
+				productPage.Page = pageRes
+				p.SuccessResult("搜索产品信息成功", productPage, result)
+				return
+			}
+		} else {
+			if len(productIdMap["package"]) == 0 {
+				logger.Info("没有相关的产品类型产品")
+				productPage.Page = pageRes
+				p.SuccessResult("搜索产品信息成功", productList, result)
+				return
+			}
+		}
+		//搜索出相关的报告和音视频
+		productSearchList, searchErr := productService.SearchRelateProduct(key, productIdMap)
+		if searchErr != nil {
+			logger.Error("搜索报告产品失败")
+			return
+		}
+		if len(productSearchList) == 0 {
+			logger.Info("没有相关的产品类型产品")
+			productPage.Page = pageRes
+			p.SuccessResult("搜索产品信息成功", productList, result)
+			return
+		}
+		if isSignal {
+			pageRes.Total = int64(len(productSearchList))
+			pageRes.LatestId = productService.LatestId()
+		} else {
+			pageRes.Total, pageRes.LatestId, permissionWeightMap = productService.CountSearchPackageList(productSearchList)
+		}
 		if p.PageInfo.LatestId == 0 {
 		if p.PageInfo.LatestId == 0 {
 			p.PageInfo.LatestId = pageRes.LatestId
 			p.PageInfo.LatestId = pageRes.LatestId
 			p.PageInfo.Total = pageRes.Total
 			p.PageInfo.Total = pageRes.Total
@@ -114,16 +150,10 @@ func (p *ProductController) ProductSearch(productType, key string, isSignal bool
 			pageRes.Total = p.PageInfo.Total
 			pageRes.Total = p.PageInfo.Total
 		}
 		}
 		pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize)
 		pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize)
-		//if isSignal {
-		//	productList, err = productService.ProductSearch(key, userInfo.Id, p.PageInfo)
-		//} else {
-		//	productList, err = productService.PackageSearch(key, userInfo.Id)
-		//}
-		if err != nil {
-			p.FailedResult("搜索产品信息失败", result)
-			return
-		}
-		p.SuccessResult("搜索产品信息成功", productList, result)
+		productList, err = productService.ProductListBySort(isSignal, productSearchList, permissionWeightMap, userInfo.Id, p.PageInfo)
+		productPage.Data = productSearchList
+		productPage.Page = pageRes
+		p.SuccessResult("搜索产品信息成功", productPage, result)
 		return
 		return
 	})
 	})
 }
 }

+ 45 - 2
domian/media/media_service.go

@@ -10,6 +10,7 @@ import (
 	configDomain "eta/eta_mini_ht_api/domian/config"
 	configDomain "eta/eta_mini_ht_api/domian/config"
 	reportService "eta/eta_mini_ht_api/domian/report"
 	reportService "eta/eta_mini_ht_api/domian/report"
 	"eta/eta_mini_ht_api/models"
 	"eta/eta_mini_ht_api/models"
+	configDao "eta/eta_mini_ht_api/models/config"
 	"eta/eta_mini_ht_api/models/image"
 	"eta/eta_mini_ht_api/models/image"
 	mediaDao "eta/eta_mini_ht_api/models/media"
 	mediaDao "eta/eta_mini_ht_api/models/media"
 	productDao "eta/eta_mini_ht_api/models/merchant"
 	productDao "eta/eta_mini_ht_api/models/merchant"
@@ -62,9 +63,10 @@ type MediaDTO struct {
 	IsPackage             bool     `json:"isPackage"`
 	IsPackage             bool     `json:"isPackage"`
 	RiskLevel             string   `json:"riskLevel"`
 	RiskLevel             string   `json:"riskLevel"`
 	ProductId             int      `json:"productId"`
 	ProductId             int      `json:"productId"`
+	Score                 float64  `json:"score"`
 }
 }
 
 
-func SearchMediaList(_ string, key string, mediaIds []int, from int, size int, max int64) (reports []MediaDTO, err error) {
+func SearchMediaList(_ string, key string, mediaIds []int, from int, size int, max int64) (medias []MediaDTO, err error) {
 	//同步es
 	//同步es
 	var docIds []string
 	var docIds []string
 	for _, id := range mediaIds {
 	for _, id := range mediaIds {
@@ -89,7 +91,7 @@ func SearchMediaList(_ string, key string, mediaIds []int, from int, size int, m
 		media.Highlight = content[ESColumn]
 		media.Highlight = content[ESColumn]
 		media.PublishedTime = media.PublishedTime[:10]
 		media.PublishedTime = media.PublishedTime[:10]
 		media.MediaTitle = media.Highlight[0]
 		media.MediaTitle = media.Highlight[0]
-		reports = append(reports, media)
+		medias = append(medias, media)
 	}
 	}
 	return
 	return
 }
 }
@@ -332,6 +334,47 @@ func matchRangeWithDocIds(key string, from int, to int, max int64, sorts []strin
 	//return req.CreateESQueryRequest(htConfig.GetMediaIndex(), ESColumn, key, from, to, sorts, es.RangeByCondition).Range(0, max, ESRangeColumn).ByCondition(column, value)
 	//return req.CreateESQueryRequest(htConfig.GetMediaIndex(), ESColumn, key, from, to, sorts, es.RangeByCondition).Range(0, max, ESRangeColumn).ByCondition(column, value)
 	return req.CreateESQueryRequest(htConfig.GetMediaIndex(), ESColumn, key, from, to, sorts, es.Range).Range(0, max, ESRangeColumn).WithDocs(docIds)
 	return req.CreateESQueryRequest(htConfig.GetMediaIndex(), ESColumn, key, from, to, sorts, es.Range).Range(0, max, ESRangeColumn).WithDocs(docIds)
 }
 }
+func matchLimitByScore(key string, limit int, score float64, docIds []string) (request *es.ESQueryRequest) {
+	req := new(es.ESQueryRequest)
+	return req.CreateESQueryRequest(htConfig.GetMediaIndex(), ESColumn, key, 0, limit, sortField, es.LimitByScore).WithScore(score).WithDocs(docIds)
+}
 func GetImageSrc(id int) (src string, err error) {
 func GetImageSrc(id int) (src string, err error) {
 	return image.GetImageSrc(id)
 	return image.GetImageSrc(id)
 }
 }
+
+func SearchMediaProduct(key string, limit int, score float64, docIds []int) (medias []MediaDTO, err error) {
+	var docStrIds []string
+	for _, docId := range docIds {
+		docStrIds = append(docStrIds, strconv.Itoa(docId))
+	}
+	request := matchLimitByScore(key, limit, score, docStrIds)
+	re, err := elastic().Search(request)
+	if err != nil {
+		logger.Error("es搜索异常:%v", err)
+	}
+	hits := elastic().GetSource(re.Hits)
+	if len(hits) == 0 {
+		medias = []MediaDTO{}
+		return
+	}
+	for _, hit := range hits {
+		var content map[string][]string
+		err = json.Unmarshal(hit.Highlight, &content)
+		media := MediaDTO{}
+		err = json.Unmarshal(hit.Source, &media)
+		if err != nil {
+			logger.Error("解析研报数据失败:%v", err)
+			continue
+		}
+		media.Score = hit.Score
+		media.Highlight = content[ESColumn]
+		media.PublishedTime = media.PublishedTime[:10]
+		media.MediaTitle = media.Highlight[0]
+		medias = append(medias, media)
+	}
+	return
+}
+
+func CountPermissionWeight(ids []int) (list []configDao.PermissionWeight, err error) {
+	return mediaDao.CountPermissionWeight(ids)
+}

+ 54 - 2
domian/merchant/merchant_product.go

@@ -4,9 +4,13 @@ import (
 	"errors"
 	"errors"
 	logger "eta/eta_mini_ht_api/common/component/log"
 	logger "eta/eta_mini_ht_api/common/component/log"
 	"eta/eta_mini_ht_api/common/utils/page"
 	"eta/eta_mini_ht_api/common/utils/page"
+	stringUtils "eta/eta_mini_ht_api/common/utils/string"
+	reportDomain "eta/eta_mini_ht_api/domian/report"
 	merchantDao "eta/eta_mini_ht_api/models/merchant"
 	merchantDao "eta/eta_mini_ht_api/models/merchant"
 	"github.com/shopspring/decimal"
 	"github.com/shopspring/decimal"
 	"gorm.io/gorm"
 	"gorm.io/gorm"
+	"strings"
+	"sync/atomic"
 	"time"
 	"time"
 )
 )
 
 
@@ -117,9 +121,57 @@ func GetProductPageByProductType(productIds []int, info page.PageInfo) (dtoList
 		logger.Error("获取商品列表失败[productIds:%v,pageInfo:%v],err:%v", productIds, info, err)
 		logger.Error("获取商品列表失败[productIds:%v,pageInfo:%v],err:%v", productIds, info, err)
 		return
 		return
 	}
 	}
-	for _, product := range productList {
-		productDTO := convertToDTO(product)
+	for _, productInfo := range productList {
+		productDTO := convertToDTO(productInfo)
 		dtoList = append(dtoList, productDTO)
 		dtoList = append(dtoList, productDTO)
 	}
 	}
 	return
 	return
 }
 }
+
+func GetProductByProductType() (productIdMap map[string][]int, err error) {
+	productMap, err := merchantDao.GetProductByProductType()
+	if err != nil {
+		logger.Error("根据类型分类获取商品ID失败,err:%v", err)
+		return
+	}
+	productIdMap = make(map[string][]int, len(productMap))
+	for productType, productIds := range productMap {
+		idStr := strings.Split(productIds, ",")
+		productIdMap[productType], _ = stringUtils.StringToIntSlice(idStr)
+	}
+	return
+}
+
+func LatestId() (latestId int64) {
+
+	return merchantDao.LatestId()
+}
+
+func ProductListBySort(isSignal bool, list []reportDomain.ProductSearchDTO, weightMap map[int]*atomic.Int32, info page.PageInfo) (productDTOS []MerchantProductDTO, err error) {
+	offset := page.StartIndex(info.Current, info.PageSize)
+	var productList []merchantDao.MerchantProduct
+	if isSignal {
+		var searchList []merchantDao.ProductDTO
+		for _, product := range list {
+			searchList = append(searchList, merchantDao.ProductDTO{
+				SourceId:   product.SourceId,
+				SourceType: product.SourceType,
+				Score:      product.Score,
+			})
+		}
+		productList, err = merchantDao.ProductListBySort(searchList, info.LatestId, offset, info.PageSize)
+		if err != nil {
+			return
+		}
+
+	} else {
+		productList, err = merchantDao.PackageListBySort(weightMap, info.LatestId, offset, info.PageSize)
+		if err != nil {
+			return
+		}
+	}
+	for _, productInfo := range productList {
+		productDTOS = append(productDTOS, convertToDTO(productInfo))
+	}
+	return
+}

+ 49 - 0
domian/report/report_service.go

@@ -12,6 +12,7 @@ import (
 	analystService "eta/eta_mini_ht_api/domian/financial_analyst"
 	analystService "eta/eta_mini_ht_api/domian/financial_analyst"
 	userService "eta/eta_mini_ht_api/domian/user"
 	userService "eta/eta_mini_ht_api/domian/user"
 	"eta/eta_mini_ht_api/models"
 	"eta/eta_mini_ht_api/models"
+	configDao "eta/eta_mini_ht_api/models/config"
 	permissionDao "eta/eta_mini_ht_api/models/config"
 	permissionDao "eta/eta_mini_ht_api/models/config"
 	"eta/eta_mini_ht_api/models/eta"
 	"eta/eta_mini_ht_api/models/eta"
 	etaDao "eta/eta_mini_ht_api/models/eta"
 	etaDao "eta/eta_mini_ht_api/models/eta"
@@ -84,6 +85,7 @@ type ReportDTO struct {
 	Price            string          `json:"price"`
 	Price            string          `json:"price"`
 	ProductId        int             `json:"productId"`
 	ProductId        int             `json:"productId"`
 	IsPackage        bool            `json:"isPackage"`
 	IsPackage        bool            `json:"isPackage"`
+	Score            float64         `json:"score"`
 }
 }
 
 
 type Detail struct {
 type Detail struct {
@@ -955,3 +957,50 @@ func CountByDocId(key string, sorts []string, docIds []string) (request *es.ESQu
 	req := new(es.ESQueryRequest)
 	req := new(es.ESQueryRequest)
 	return req.CreateESQueryRequest(htConfig.GetReportIndex(), ESColumn, key, 0, 1, sorts, es.CountWithDocIds).WithDocs(docIds)
 	return req.CreateESQueryRequest(htConfig.GetReportIndex(), ESColumn, key, 0, 1, sorts, es.CountWithDocIds).WithDocs(docIds)
 }
 }
+func matchLimitByScore(key string, limit int, score float64, docIds []string) (request *es.ESQueryRequest) {
+	req := new(es.ESQueryRequest)
+	return req.CreateESQueryRequest(htConfig.GetReportIndex(), ESColumn, key, 0, limit, sortField, es.LimitByScore).WithScore(score).WithDocs(docIds)
+}
+func SearchReportProduct(key string, limit int, score float64, docIds []int) (reports []ReportDTO, err error) {
+	var docStrIds []string
+	for _, id := range docIds {
+		docStrIds = append(docStrIds, strconv.Itoa(id))
+	}
+	request := matchLimitByScore(key, limit, score, docStrIds)
+	re, err := elastic().Search(request)
+	if err != nil {
+		logger.Error("es搜索异常:%v", err)
+	}
+	hits := elastic().GetSource(re.Hits)
+	if len(hits) == 0 {
+		reports = []ReportDTO{}
+		return
+	}
+	for _, hit := range hits {
+		var content map[string][]string
+		err = json.Unmarshal(hit.Highlight, &content)
+		report := ReportDTO{}
+		err = json.Unmarshal(hit.Source, &report)
+		if err != nil {
+			logger.Error("解析研报数据失败:%v", err)
+			continue
+		}
+		report.Score = hit.Score
+		report.Highlight = content[ESColumn]
+		report.Title = report.Highlight[0]
+		report.PublishedTime = report.PublishedTime[:10]
+		reports = append(reports, report)
+	}
+	return
+}
+
+type ProductSearchDTO struct {
+	HighLight  string
+	SourceId   int
+	SourceType string
+	Score      float64
+}
+
+func CountPermissionWeight(ids []int) (list []configDao.PermissionWeight, err error) {
+	return reportDao.CountPermissionWeight(ids)
+}

+ 5 - 0
models/config/permission.go

@@ -110,3 +110,8 @@ func PermissionsByPermissionId(permissionId int) (permission Permission, err err
 	err = db.Model(&Permission{}).Select(Columns).Where("permission_id  =? ", permissionId).First(&permission).Error
 	err = db.Model(&Permission{}).Select(Columns).Where("permission_id  =? ", permissionId).First(&permission).Error
 	return
 	return
 }
 }
+
+type PermissionWeight struct {
+	PermissionId int
+	Weight       int
+}

+ 8 - 0
models/media/media.go

@@ -4,6 +4,7 @@ import (
 	"errors"
 	"errors"
 	logger "eta/eta_mini_ht_api/common/component/log"
 	logger "eta/eta_mini_ht_api/common/component/log"
 	"eta/eta_mini_ht_api/models"
 	"eta/eta_mini_ht_api/models"
+	"eta/eta_mini_ht_api/models/config"
 	"eta/eta_mini_ht_api/models/report"
 	"eta/eta_mini_ht_api/models/report"
 	"gorm.io/gorm"
 	"gorm.io/gorm"
 	"time"
 	"time"
@@ -133,3 +134,10 @@ func GetMediaById(mediaType string, mediaId int) (media Media, err error) {
 	err = db.Select(DetailColumns).Where("id =? and media_type=? and deleted =?", mediaId, mediaType, false).First(&media).Error
 	err = db.Select(DetailColumns).Where("id =? and media_type=? and deleted =?", mediaId, mediaType, false).First(&media).Error
 	return
 	return
 }
 }
+
+func CountPermissionWeight(ids []int) (list []config.PermissionWeight, err error) {
+	db := models.Main()
+	sql := `select permission_id,count(*) num from(select mpm.permission_id from  media m LEFT JOIN (select permission_id,media_id from media_permission_mappings where deleted=0) mpm on mpm.media_id=m.id where m.id in (?)) a GROUP BY a.permission_id`
+	err = db.Raw(sql, ids).Find(&list).Error
+	return
+}

+ 90 - 8
models/merchant/merchant_product.go

@@ -3,8 +3,10 @@ package merchant
 import (
 import (
 	"errors"
 	"errors"
 	"eta/eta_mini_ht_api/models"
 	"eta/eta_mini_ht_api/models"
+	"fmt"
 	"github.com/shopspring/decimal"
 	"github.com/shopspring/decimal"
-	"gorm.io/gorm"
+	"sort"
+	"sync/atomic"
 	"time"
 	"time"
 )
 )
 
 
@@ -48,13 +50,6 @@ func (MerchantProduct) TableName() string {
 	return "merchant_products"
 	return "merchant_products"
 }
 }
 
 
-func (m *MerchantProduct) BeforeCreate(_ *gorm.DB) (err error) {
-	m.CreatedTime = time.Now()
-	m.Deleted = false
-	m.SaleStatus = OffSale
-	return
-}
-
 func GetMerchantProductById(id int) (product MerchantProduct, err error) {
 func GetMerchantProductById(id int) (product MerchantProduct, err error) {
 	db := models.Main()
 	db := models.Main()
 	err = db.Select(detailColumns).Where("id = ? and deleted =?", id, false).First(&product).Error
 	err = db.Select(detailColumns).Where("id = ? and deleted =?", id, false).First(&product).Error
@@ -144,3 +139,90 @@ func CountProductList(isSignal bool) (total, latestId int64, ids []int) {
 	_ = db.Select("id").Where(" ? and deleted =? order by id desc ", condition, Package, false).Scan(&ids).Error
 	_ = db.Select("id").Where(" ? and deleted =? order by id desc ", condition, Package, false).Scan(&ids).Error
 	return
 	return
 }
 }
+
+type MerchantProductIdMap struct {
+	Type      string
+	ProductId string
+}
+
+func GetProductByProductType() (productIds map[string]string, err error) {
+	db := models.Main()
+	var productIdMap []MerchantProductIdMap
+	sql := `SELECT type,GROUP_CONCAT(source_id ORDER BY source_id SEPARATOR ',') as source_id FROM merchant_products GROUP BY type`
+	err = db.Raw(sql).Find(&productIdMap).Error
+	productIds = make(map[string]string, len(productIdMap))
+	for _, v := range productIdMap {
+		productIds[v.Type] = v.ProductId
+	}
+	return
+}
+
+func generateSignalPdSql(idMap map[string][]int) (condition string, pars []interface{}) {
+	for k, v := range idMap {
+		if condition == "" {
+			condition = "(" + fmt.Sprintf("(type =? and source_id in ?)")
+		} else {
+			condition = condition + fmt.Sprintf(" or (type =? and source_id in ?)")
+		}
+		pars = append(pars, k, v)
+	}
+	condition = condition + ")"
+	return
+}
+
+func LatestId() (latestId int64) {
+	db := models.Main()
+	_ = db.Select("max(id)").Where("deleted=?", false).Scan(&latestId).Error
+	return
+}
+
+type ProductDTO struct {
+	SourceId   int
+	SourceType string
+	Score      float64
+}
+
+func ProductListBySort(list []ProductDTO, id int64, offset int, size int) (productList []MerchantProduct, err error) {
+	var productMap map[string][]int
+	sort.Slice(list, func(i, j int) bool {
+		return list[i].Score > list[j].Score
+	})
+	var idSort []int
+	for _, v := range list {
+		idSort = append(idSort, v.SourceId)
+	}
+	for _, v := range list {
+		ids := productMap[v.SourceType]
+		ids = append(ids, v.SourceId)
+		productMap[v.SourceType] = ids
+	}
+	sql, pars := generateSignalPdSql(productMap)
+	db := models.Main()
+	err = db.Select(detailColumns).Where(fmt.Sprintf("id <= ? and deleted =? and  %s order by Field(id,?) desc limit ?,? ", sql), id, false, pars, idSort, offset, size).Find(&productList).Error
+	return
+}
+
+type packageStruct struct {
+	SourceId int
+	Weight   int32
+}
+
+func PackageListBySort(weightMap map[int]*atomic.Int32, id int64, offset int, size int) (productList []MerchantProduct, err error) {
+	var packageList []packageStruct
+	for k, v := range weightMap {
+		packageList = append(packageList, packageStruct{
+			SourceId: k,
+			Weight:   v.Load(),
+		})
+	}
+	sort.Slice(packageList, func(i, j int) bool {
+		return packageList[i].Weight > packageList[j].Weight
+	})
+	var idSort []int
+	for _, v := range packageList {
+		idSort = append(idSort, v.SourceId)
+	}
+	db := models.Main()
+	err = db.Select(detailColumns).Where("id <= ?  and type =? and deleted =? and source_id in ? order by Field(id,?) desc limit ?,? ", id, Package, false, idSort, offset, size).Find(&productList).Error
+	return
+}

+ 11 - 0
models/report/report.go

@@ -6,6 +6,7 @@ import (
 	"eta/eta_mini_ht_api/common/utils/date"
 	"eta/eta_mini_ht_api/common/utils/date"
 	silce_utils "eta/eta_mini_ht_api/common/utils/silce"
 	silce_utils "eta/eta_mini_ht_api/common/utils/silce"
 	"eta/eta_mini_ht_api/models"
 	"eta/eta_mini_ht_api/models"
+	permissionDao "eta/eta_mini_ht_api/models/config"
 	"fmt"
 	"fmt"
 	"gorm.io/gorm"
 	"gorm.io/gorm"
 	"gorm.io/gorm/clause"
 	"gorm.io/gorm/clause"
@@ -396,3 +397,13 @@ func GetReportClassifyById(id int) (classifyId int, err error) {
 		Where("orgId =? and source ='ETA' ", id).Scan(&classifyId).Error
 		Where("orgId =? and source ='ETA' ", id).Scan(&classifyId).Error
 	return
 	return
 }
 }
+
+func CountPermissionWeight(ids []int) (list []permissionDao.PermissionWeight, err error) {
+	db := models.Main()
+	sql := `select a.permission_id,count(*) from 
+(select p.permission_id from reports r LEFT JOIN(SELECT *from permissions) p on p.name=r.plate_name where r.id in (?) and r.source='HT'
+UNION ALL
+select cpm.permission_id from reports  r LEFT JOIN (SELECT classify_id,permission_id FROM permission_classify_mapping) cpm on cpm.classify_id=r.classify_id  where r.id in (?) and r.source='ETA') a GROUP BY a.permission_id`
+	err = db.Raw(sql, ids, ids).Find(&list).Error
+	return
+}

+ 0 - 1
routers/commentsRouter.go

@@ -161,7 +161,6 @@ func init() {
             Router: `/productSearch`,
             Router: `/productSearch`,
             AllowHTTPMethods: []string{"get"},
             AllowHTTPMethods: []string{"get"},
             MethodParams: param.Make(
             MethodParams: param.Make(
-				param.New("productType"),
 				param.New("key"),
 				param.New("key"),
 				param.New("isSignal"),
 				param.New("isSignal"),
 			),
 			),

+ 19 - 0
service/media/media_service.go

@@ -422,3 +422,22 @@ func SearchMediaList(mediaType string, key string, mediaIds []int, pageInfo page
 	}
 	}
 	return
 	return
 }
 }
+
+func SearchMediaProduct(key string, docIds []int) (list []mediaService.MediaDTO, err error) {
+	list, err = mediaService.SearchMediaProduct(key, 100, 0, docIds)
+	if err != nil {
+		err = exception.New(exception.SearchReportPageFailed)
+	}
+	return
+}
+
+func CountPermissionWeight(ids []int) (permissionMap map[int]int) {
+	list, err := mediaService.CountPermissionWeight(ids)
+	if err != nil {
+		return
+	}
+	for _, permission := range list {
+		permissionMap[permission.PermissionId] = permission.Weight
+	}
+	return
+}

+ 108 - 8
service/product/product_service.go

@@ -5,6 +5,7 @@ import (
 	"eta/eta_mini_ht_api/common/exception"
 	"eta/eta_mini_ht_api/common/exception"
 	"eta/eta_mini_ht_api/common/utils/page"
 	"eta/eta_mini_ht_api/common/utils/page"
 	permissionService "eta/eta_mini_ht_api/domian/config"
 	permissionService "eta/eta_mini_ht_api/domian/config"
+	mediaDomain "eta/eta_mini_ht_api/domian/media"
 	merchantService "eta/eta_mini_ht_api/domian/merchant"
 	merchantService "eta/eta_mini_ht_api/domian/merchant"
 	reportDomain "eta/eta_mini_ht_api/domian/report"
 	reportDomain "eta/eta_mini_ht_api/domian/report"
 	"eta/eta_mini_ht_api/domian/user"
 	"eta/eta_mini_ht_api/domian/user"
@@ -16,7 +17,9 @@ import (
 	"eta/eta_mini_ht_api/service/order"
 	"eta/eta_mini_ht_api/service/order"
 	reportService "eta/eta_mini_ht_api/service/report"
 	reportService "eta/eta_mini_ht_api/service/report"
 	"fmt"
 	"fmt"
+	"sort"
 	"sync"
 	"sync"
+	"sync/atomic"
 	"time"
 	"time"
 )
 )
 
 
@@ -110,7 +113,6 @@ func GetProductRiskLevel(product merchantService.MerchantProductDTO) (riskLevel,
 				}
 				}
 			}
 			}
 			_, permissionNames = reportService.GetReportPermissionNames(report.OrgId, report.Source)
 			_, permissionNames = reportService.GetReportPermissionNames(report.OrgId, report.Source)
-			//permissionNames = strings.Join(permissionNamesList, ",")
 		}
 		}
 	default:
 	default:
 		logger.Warn("不支持的产品类型[%s]", product.Type)
 		logger.Warn("不支持的产品类型[%s]", product.Type)
@@ -322,13 +324,11 @@ func ProductList(productIds []int, templateUserId int, info page.PageInfo) (dtoL
 	}
 	}
 	return
 	return
 }
 }
-func RangeProductList(isSignal bool) (total, latestId int64, ids []int) {
-	//return merchantService.CountProductListByProductType(isSignal)
-	return 0, 0, nil
+func RangeProductList() (productIdMap map[string][]int, err error) {
+	return merchantService.GetProductByProductType()
 }
 }
-func ProductSearch(productType string, key string, templateUserId int, pageInfo page.PageInfo) (list []ProductDTO, err error) {
+func ProductSearch(key string, templateUserId int, pageInfo page.PageInfo) (list []ProductDTO, err error) {
 	var merchantProductList []merchantService.MerchantProductDTO
 	var merchantProductList []merchantService.MerchantProductDTO
-	merchantProductList, err = merchantService.GetProductListByProductType(productType)
 	var sourceIds []int
 	var sourceIds []int
 	var maxId int
 	var maxId int
 	for _, product := range merchantProductList {
 	for _, product := range merchantProductList {
@@ -347,6 +347,106 @@ func ProductSearch(productType string, key string, templateUserId int, pageInfo
 	return
 	return
 }
 }
 
 
-func PackageSearch(key string, templateUserId int) (list []ProductDTO, err error) {
-	return nil, nil
+func convertReportToSearchDTO(report reportDomain.ReportDTO) (dto reportDomain.ProductSearchDTO) {
+	return reportDomain.ProductSearchDTO{
+		HighLight:  report.Highlight[0],
+		SourceId:   report.ReportID,
+		SourceType: "report",
+		Score:      report.Score,
+	}
+}
+func convertMediaToSearchDTO(media mediaDomain.MediaDTO) (dto reportDomain.ProductSearchDTO) {
+	return reportDomain.ProductSearchDTO{
+		HighLight:  media.Highlight[0],
+		SourceId:   media.MediaId,
+		SourceType: media.MediaType,
+		Score:      media.Score,
+	}
+}
+func SearchRelateProduct(key string, productIdMap map[string][]int) (list []reportDomain.ProductSearchDTO, err error) {
+	var wg sync.WaitGroup
+	wg.Add(2)
+	go func() {
+		defer wg.Done()
+		docIds := productIdMap["report"]
+		reports, reportErr := reportService.SearchReportProduct(key, docIds)
+		if reportErr != nil {
+			logger.Error("搜索相关报告失败:%v,key:%s", reportErr, key)
+			return
+		}
+		for _, report := range reports {
+			list = append(list, convertReportToSearchDTO(report))
+		}
+	}()
+	go func() {
+		defer wg.Done()
+		docIds := append(productIdMap["audio"], productIdMap["video"]...)
+		medias, mediaErr := mediaService.SearchMediaProduct(key, docIds)
+		if mediaErr != nil {
+			logger.Error("搜索相关媒体失败:%v,key:%s", mediaErr, key)
+			return
+		}
+		for _, mediaInfo := range medias {
+			list = append(list, convertMediaToSearchDTO(mediaInfo))
+		}
+		list = append(list, reportDomain.ProductSearchDTO{
+			HighLight:  "",
+			SourceId:   165,
+			SourceType: "audio",
+			Score:      12.31,
+		})
+	}()
+	wg.Wait()
+	sort.Slice(list, func(i, j int) bool {
+		return list[i].Score > list[j].Score
+	})
+	return
+}
+
+func LatestId() (latestId int64) {
+	return merchantService.LatestId()
+}
+
+func CountSearchPackageList(list []reportDomain.ProductSearchDTO) (total, latestId int64, permissionTotalMap map[int]*atomic.Int32) {
+	var productIdMap map[string][]int
+	for _, product := range list {
+		ids := productIdMap[product.SourceType]
+		ids = append(ids, product.SourceId)
+		productIdMap[product.SourceType] = ids
+	}
+	var wg sync.WaitGroup
+	wg.Add(len(productIdMap))
+	for key, ids := range productIdMap {
+		go func(k string, ids []int) {
+			var permissionMap map[int]int
+			switch k {
+			case "report":
+				permissionMap = reportService.CountPermissionWeight(ids)
+			case "audio", "video":
+				permissionMap = mediaService.CountPermissionWeight(ids)
+			}
+			for permissionId, weight := range permissionMap {
+				permissionTotalMap[permissionId].Add(int32(weight))
+			}
+		}(key, ids)
+	}
+	wg.Wait()
+	total = int64(len(permissionTotalMap))
+	latestId = merchantService.LatestId()
+	return
+}
+
+func ProductListBySort(isSignal bool, list []reportDomain.ProductSearchDTO, weightMap map[int]*atomic.Int32, id int, info page.PageInfo) (resultList []ProductDTO, err error) {
+	var pdDTOS []merchantService.MerchantProductDTO
+	pdDTOS, err = merchantService.ProductListBySort(isSignal, list, weightMap, info)
+	var wg sync.WaitGroup
+	wg.Add(len(pdDTOS))
+	for _, pd := range pdDTOS {
+		go func(pd merchantService.MerchantProductDTO) {
+			productDTO := convertToProductDTO(pd)
+			productDTO.RiskLevel, productDTO.SourceTile, productDTO.Abstract, productDTO.CoverUrl, productDTO.Src, productDTO.PermissionNames, _, err = GetProductRiskLevel(pd)
+		}(pd)
+	}
+	wg.Wait()
+	return
 }
 }

+ 19 - 0
service/report/report_service.go

@@ -263,6 +263,14 @@ func SearchReportList(key string, Ids []int, pageInfo page.PageInfo, isLogin boo
 	}
 	}
 	return
 	return
 }
 }
+
+func SearchReportProduct(key string, docIds []int) (list []reportService.ReportDTO, err error) {
+	list, err = reportService.SearchReportProduct(key, 100, 0, docIds)
+	if err != nil {
+		err = exception.New(exception.SearchReportPageFailed)
+	}
+	return
+}
 func RangeSearchByAnalyst(analystName string, userId int) (total int64, latestId int64, ids []int) {
 func RangeSearchByAnalyst(analystName string, userId int) (total int64, latestId int64, ids []int) {
 	return getCountByAnalyst(nil, true, userId, analystName)
 	return getCountByAnalyst(nil, true, userId, analystName)
 }
 }
@@ -698,3 +706,14 @@ func getCountByAnalyst(permissionIds []int, isLogin bool, userId int, analystNam
 	}
 	}
 	return reportService.GetTotalPageCountByAnalyst(analystName, filterPermissionIds, riskLevel)
 	return reportService.GetTotalPageCountByAnalyst(analystName, filterPermissionIds, riskLevel)
 }
 }
+
+func CountPermissionWeight(ids []int) (permissionMap map[int]int) {
+	list, err := reportService.CountPermissionWeight(ids)
+	if err != nil {
+		return
+	}
+	for _, item := range list {
+		permissionMap[item.PermissionId] = item.Weight
+	}
+	return
+}