Browse Source

订阅中心

kobe6258 3 months ago
parent
commit
a271419a98

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

@@ -42,6 +42,7 @@ const (
 	RangeByConditionWithDocIds = "range_by_condition_with_doc_ids"
 
 	RangeWithDocIds = "range_with_doc_ids"
+	LimitByScore    = "limit_by_score"
 )
 
 func GetInstance() *ESClient {
@@ -170,6 +171,7 @@ type ESQueryRequest struct {
 	DocIds         []string
 	Max            interface{}
 	Min            interface{}
+	MinScore       float64
 }
 
 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,
 	}
 }
-
+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 {
 	req.RangeColumn = column
 	req.Max = to
@@ -400,6 +409,34 @@ func (req *ESQueryRequest) parseJsonQuery() (queryMap map[string]interface{}) {
 			},
 		}
 		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:
 		queryMap = map[string]interface{}{}
 		return

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

@@ -13,11 +13,12 @@ type PageResult struct {
 	Data interface{}
 }
 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 {

+ 51 - 21
controllers/product/product_controller.go

@@ -7,6 +7,7 @@ import (
 	"eta/eta_mini_ht_api/controllers"
 	productService "eta/eta_mini_ht_api/service/product"
 	"eta/eta_mini_ht_api/service/user"
+	"sync/atomic"
 )
 
 var (
@@ -86,26 +87,61 @@ func (p *ProductController) RelatePackage(productId int) {
 	})
 }
 
-// ProductSearch  获取商品信息
-// @Summary 获取商品信息
-// @Description 获取商品信息
+// ProductSearch  搜索产品
+// @Summary 搜索产品
+// @Description 搜索产品
 // @Success 200 {object} controllers.BaseResponse
 // @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) {
 		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 permissionWeightMap map[int]*atomic.Int32
 		pageRes := page.Page{
 			Current:  p.PageInfo.Current,
 			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 {
 			p.PageInfo.LatestId = pageRes.LatestId
 			p.PageInfo.Total = pageRes.Total
@@ -114,16 +150,10 @@ func (p *ProductController) ProductSearch(productType, key string, isSignal bool
 			pageRes.Total = p.PageInfo.Total
 		}
 		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
 	})
 }

+ 45 - 2
domian/media/media_service.go

@@ -10,6 +10,7 @@ import (
 	configDomain "eta/eta_mini_ht_api/domian/config"
 	reportService "eta/eta_mini_ht_api/domian/report"
 	"eta/eta_mini_ht_api/models"
+	configDao "eta/eta_mini_ht_api/models/config"
 	"eta/eta_mini_ht_api/models/image"
 	mediaDao "eta/eta_mini_ht_api/models/media"
 	productDao "eta/eta_mini_ht_api/models/merchant"
@@ -62,9 +63,10 @@ type MediaDTO struct {
 	IsPackage             bool     `json:"isPackage"`
 	RiskLevel             string   `json:"riskLevel"`
 	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
 	var docIds []string
 	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.PublishedTime = media.PublishedTime[:10]
 		media.MediaTitle = media.Highlight[0]
-		reports = append(reports, media)
+		medias = append(medias, media)
 	}
 	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.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) {
 	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"
 	logger "eta/eta_mini_ht_api/common/component/log"
 	"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"
 	"github.com/shopspring/decimal"
 	"gorm.io/gorm"
+	"strings"
+	"sync/atomic"
 	"time"
 )
 
@@ -117,9 +121,57 @@ func GetProductPageByProductType(productIds []int, info page.PageInfo) (dtoList
 		logger.Error("获取商品列表失败[productIds:%v,pageInfo:%v],err:%v", productIds, info, err)
 		return
 	}
-	for _, product := range productList {
-		productDTO := convertToDTO(product)
+	for _, productInfo := range productList {
+		productDTO := convertToDTO(productInfo)
 		dtoList = append(dtoList, productDTO)
 	}
 	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"
 	userService "eta/eta_mini_ht_api/domian/user"
 	"eta/eta_mini_ht_api/models"
+	configDao "eta/eta_mini_ht_api/models/config"
 	permissionDao "eta/eta_mini_ht_api/models/config"
 	"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"`
 	ProductId        int             `json:"productId"`
 	IsPackage        bool            `json:"isPackage"`
+	Score            float64         `json:"score"`
 }
 
 type Detail struct {
@@ -955,3 +957,50 @@ func CountByDocId(key string, sorts []string, docIds []string) (request *es.ESQu
 	req := new(es.ESQueryRequest)
 	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
 	return
 }
+
+type PermissionWeight struct {
+	PermissionId int
+	Weight       int
+}

+ 8 - 0
models/media/media.go

@@ -4,6 +4,7 @@ import (
 	"errors"
 	logger "eta/eta_mini_ht_api/common/component/log"
 	"eta/eta_mini_ht_api/models"
+	"eta/eta_mini_ht_api/models/config"
 	"eta/eta_mini_ht_api/models/report"
 	"gorm.io/gorm"
 	"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
 	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 (
 	"errors"
 	"eta/eta_mini_ht_api/models"
+	"fmt"
 	"github.com/shopspring/decimal"
-	"gorm.io/gorm"
+	"sort"
+	"sync/atomic"
 	"time"
 )
 
@@ -48,13 +50,6 @@ func (MerchantProduct) TableName() string {
 	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) {
 	db := models.Main()
 	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
 	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"
 	silce_utils "eta/eta_mini_ht_api/common/utils/silce"
 	"eta/eta_mini_ht_api/models"
+	permissionDao "eta/eta_mini_ht_api/models/config"
 	"fmt"
 	"gorm.io/gorm"
 	"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
 	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`,
             AllowHTTPMethods: []string{"get"},
             MethodParams: param.Make(
-				param.New("productType"),
 				param.New("key"),
 				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
 }
+
+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/utils/page"
 	permissionService "eta/eta_mini_ht_api/domian/config"
+	mediaDomain "eta/eta_mini_ht_api/domian/media"
 	merchantService "eta/eta_mini_ht_api/domian/merchant"
 	reportDomain "eta/eta_mini_ht_api/domian/report"
 	"eta/eta_mini_ht_api/domian/user"
@@ -16,7 +17,9 @@ import (
 	"eta/eta_mini_ht_api/service/order"
 	reportService "eta/eta_mini_ht_api/service/report"
 	"fmt"
+	"sort"
 	"sync"
+	"sync/atomic"
 	"time"
 )
 
@@ -110,7 +113,6 @@ func GetProductRiskLevel(product merchantService.MerchantProductDTO) (riskLevel,
 				}
 			}
 			_, permissionNames = reportService.GetReportPermissionNames(report.OrgId, report.Source)
-			//permissionNames = strings.Join(permissionNamesList, ",")
 		}
 	default:
 		logger.Warn("不支持的产品类型[%s]", product.Type)
@@ -322,13 +324,11 @@ func ProductList(productIds []int, templateUserId int, info page.PageInfo) (dtoL
 	}
 	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
-	merchantProductList, err = merchantService.GetProductListByProductType(productType)
 	var sourceIds []int
 	var maxId int
 	for _, product := range merchantProductList {
@@ -347,6 +347,106 @@ func ProductSearch(productType string, key string, templateUserId int, pageInfo
 	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
 }
+
+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) {
 	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)
 }
+
+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
+}