Prechádzať zdrojové kódy

feat:数据模块核算

wangshan 1 rok pred
rodič
commit
50eedb8eb7

+ 19 - 2
internal/consts/consts.go

@@ -1,11 +1,28 @@
 package consts
 
+const (
+	JudgmentPrev0  = iota //地区分布-省份
+	JudgmentPrev1         //地区分布-城市
+	JudgmentPrev2         //客户分布
+	JudgmentPrev3         //项目数量TOP3客户类型的重点中标单位
+	JudgmentPrev4         //项目规模分布-金额分布
+	JudgmentPrev5         //项目数量-项目金额---TOP3地区的重点中标单位
+	JudgmentPrev6         //订阅分类|重点中标单位-项目数量|重点中标单位-项目金额
+	JudgmentPrev7         //采购单位--TOP30
+	JudgmentPrev8         //采购规模分布-金额分布
+	JudgmentPrev9         //中标单位--TOP30
+	JudgmentPrev10        //中标规模分布-金额分布
+	Top3           = 3
+	Top10          = 10
+	Top30          = 30
+)
+
 var (
 	//项目规模分布
 	ProjectScale = []struct {
 		Key  string
-		From int
-		To   int
+		From float64
+		To   float64
 	}{
 		{
 			"<10万",

+ 21 - 0
internal/dao/internal/analyzeTask.go

@@ -11,6 +11,7 @@ import (
 	"github.com/gogf/gf/v2/frame/g"
 	"github.com/gogf/gf/v2/os/gctx"
 	es "github.com/olivere/elastic/v7"
+	"strings"
 )
 
 type AnalyzeTask struct {
@@ -128,3 +129,23 @@ func (a *AnalyzeTask) GetEsSql() string {
 	query := fmt.Sprintf(`{"query":{"bool":{"must":[{"range":{"jgtime":{"gte":%d,"lte":%d}}},{"terms":{"bidstatus":["中标","成交","合同","单一"]}}]}},"sort": [{"jgtime": "desc"}],"from": 0,"size": %d}`, a.StartTime, a.EndTime, g.Cfg().MustGet(gctx.New(), "es.countLimit").Int())
 	return query
 }
+
+// 企业信息
+func GetEntNameByIds(ids []string) (returnMap map[string]string) {
+	returnMap = map[string]string{}
+	if len(ids) == 0 {
+		return
+	}
+	list := do.Es.Get("qyxy", "qyxy", fmt.Sprintf(`{"query":{"bool":{"must":[{"terms":{"_id":["%s"]}}]}},"_source":["_id","company_name"],"size":%d}`, strings.Join(ids, `","`), len(ids)))
+	if list == nil || len(*list) == 0 {
+		return
+	}
+	for _, item := range *list {
+		id, _ := item["_id"].(string)
+		name, _ := item["company_name"].(string)
+		if id != "" && name != "" {
+			returnMap[id] = name
+		}
+	}
+	return
+}

+ 795 - 62
internal/dao/internal/userTask.go

@@ -1,15 +1,19 @@
 package internal
 
 import (
+	"analyze/internal/consts"
 	"analyze/internal/model/entity"
 	"analyze/utility"
 	"app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/encrypt"
 	"bp.jydev.jianyu360.cn/BaseService/pushpkg/dfa"
 	"encoding/json"
 	"fmt"
 	"github.com/gogf/gf/v2/frame/g"
 	"github.com/gogf/gf/v2/os/gctx"
+	"sort"
 	"strings"
+	"sync"
 	"sync/atomic"
 	"time"
 )
@@ -31,6 +35,9 @@ type UserTask struct {
 	Result               *CalculateResult             //结果集
 	MonthDistributionKey []entity.DateSpan            //月度分配key
 	YearDistributionKey  []entity.DateSpan            //年度分配key
+	JudgmentMap          map[string]bool              //地区分布|城市分布|客户 项目规模  地区top3|订阅分类|一个就行
+	CalculateChan        chan bool
+	CalculateWG          sync.WaitGroup
 }
 
 type CalculateResult struct {
@@ -48,6 +55,7 @@ func NewUserInfo() *UserTask {
 		AnalysisParam: entity.AnalyzeParameters{},
 		Ticker:        time.NewTicker(time.Duration(10000) * time.Second),
 		Result:        &CalculateResult{},
+		JudgmentMap:   make(map[string]bool),
 	}
 }
 
@@ -144,6 +152,31 @@ func (ut *UserTask) IndustryMatch(industry string) (b bool) {
 	return
 }
 
+// 关键词匹配--分类
+func (ut *UserTask) KeysMatchByKeysItems(matchObject string, keysItems entity.KeyWordGroup) (b bool) {
+	var (
+		dfaKey = dfa.DFA{}
+	)
+	//purchasing|projectname
+	//订阅词分组
+	for _, viewKeyWord := range utility.GetGroupKeywordArr(keysItems.A_Key) {
+		var (
+			keys = viewKeyWord.Keyword
+		)
+		//关键词 和 附加词
+		if len(viewKeyWord.Appended) > 0 {
+			keys = append(keys, viewKeyWord.Appended...)
+		}
+		dfaKey.AddWord(common.If(len(keys) > 0, strings.Join(keys, "+"), strings.Join(keys, "")).(string))
+		//关键词 附加词
+		if rk := dfaKey.Analy(matchObject); len(rk) != 0 {
+			b = true
+			break
+		}
+	}
+	return
+}
+
 // 关键词
 func (ut *UserTask) KeysMatch(matchObject string) (b bool) {
 	var (
@@ -177,84 +210,784 @@ func (ut *UserTask) KeysMatch(matchObject string) (b bool) {
 }
 
 // Calculate 模块计算逻辑
-func (ut *UserTask) Calculate(project *entity.ProjectInfo) {
+func (ut *UserTask) Calculate(pt *entity.ProjectInfo) {
 	//市场概况+时间分布
 	scale := ut.Result.Scale
-	//项目信息结果时间在原始查询条件范围内
-	if utility.DateIsIn(ut.StartTime, ut.EndTime, project.JgTime, 0) {
-		if project.Buyer != "" {
-			scale.MarketProfile.Buyercount += 1
+	var scaleFunc = func() {
+		//项目信息结果时间在原始查询条件范围内
+		if utility.DateIsIn(ut.StartTime, ut.EndTime, pt.JgTime, 0) {
+			if pt.Buyer != "" {
+				scale.MarketProfile.Buyercount += 1
+			}
+			scale.MarketProfile.ProjectCount += 1
+			if pt.Winners != "" {
+				scale.MarketProfile.Winnercount += len(strings.Split(pt.Winners, ","))
+			}
+			scale.MarketProfile.Projctamout += pt.Sortprice
+			scale.MarketProfile.Projectavgmoney = utility.Sequential(scale.MarketProfile.Projctamout, float64(scale.MarketProfile.ProjectCount)) //项目平均金额(万)
+		}
+		//是否需要进行环比
+		if ut.IsRatio {
+			scale.ProjectInfoAll.ProjectCount += 1
+			scale.ProjectInfoAll.Projctamout += pt.Sortprice
+			if pt.Buyer != "" {
+				scale.ProjectInfoAll.Buyercount += 1
+			}
+			if pt.Winners != "" {
+				scale.ProjectInfoAll.Winnercount += len(strings.Split(pt.Winners, ","))
+			}
+			//项目平均金额(万)
+			scale.ProjectInfoAll.Projectavgmoney = utility.Sequential(scale.ProjectInfoAll.Projctamout, float64(scale.ProjectInfoAll.ProjectCount))
+			//采购单位项目数量环比
+			scale.MarketProfile.BuyercountRatio = utility.Sequential(float64(scale.MarketProfile.Buyercount), float64(scale.ProjectInfoAll.Buyercount))
+			//项目金额环比
+			scale.MarketProfile.ProjctamountRatio = utility.Sequential(scale.MarketProfile.Projctamout, scale.ProjectInfoAll.Projctamout)
+			//项目数量环比
+			scale.MarketProfile.ProjectCountRatio = utility.Sequential(float64(scale.MarketProfile.ProjectCount), float64(scale.ProjectInfoAll.ProjectCount))
+			//项目平均金额环比
+			scale.MarketProfile.ProjectavgmoneyRatio = utility.Sequential(scale.MarketProfile.Projectavgmoney, float64(scale.ProjectInfoAll.Projectavgmoney))
+			//采购单位环比
+			scale.MarketProfile.BuyercountRatio = utility.Sequential(float64(scale.MarketProfile.Buyercount), float64(scale.ProjectInfoAll.Buyercount))
+		}
+		//月度分配
+		if len(ut.MonthDistributionKey) > 0 {
+			for mdk, mdv := range ut.MonthDistributionKey {
+				eDAmount := entity.Distribution{} //金额
+				eDCount := entity.Distribution{}  //项目数量
+				eDAmount.Minth = mdv.Key
+				eDCount.Minth = mdv.Key
+				if utility.DateIsIn(mdv.From, mdv.To, pt.JgTime, 0) {
+					eDAmount.Value += pt.Sortprice
+					eDCount.Value += 1
+					if ut.IsRatio && mdk > 0 {
+						//计算环比
+						eDAmount.Ratio = utility.Sequential(eDAmount.Value, scale.MonthDistribution.ProjectAmount[mdk-1].Value)
+						eDCount.Ratio = utility.Sequential(eDCount.Value, scale.MonthDistribution.ProjectCount[mdk-1].Value)
+					}
+				}
+				scale.MonthDistribution.ProjectAmount = append(scale.MonthDistribution.ProjectAmount, eDAmount)
+				scale.MonthDistribution.ProjectCount = append(scale.MonthDistribution.ProjectCount, eDCount)
+			}
 		}
-		scale.MarketProfile.ProjectCount += 1
-		if project.Winners != "" {
-			scale.MarketProfile.Winnercount += len(strings.Split(project.Winners, ","))
+		//月度分配
+		if len(ut.YearDistributionKey) > 0 {
+			for ydk, ydv := range ut.YearDistributionKey {
+				eDAmount := entity.Distribution{} //金额
+				eDCount := entity.Distribution{}  //项目数量
+				eDAmount.Minth = ydv.Key
+				eDCount.Minth = ydv.Key
+				if utility.DateIsIn(ydv.From, ydv.To, pt.JgTime, 0) {
+					eDAmount.Value += pt.Sortprice
+					eDCount.Value += 1
+					if ut.IsRatio && ydk > 0 {
+						//计算环比
+						eDAmount.Ratio = utility.Sequential(eDAmount.Value, scale.YearDistribution.ProjectAmount[ydk-1].Value)
+						eDCount.Ratio = utility.Sequential(eDCount.Value, scale.YearDistribution.ProjectCount[ydk-1].Value)
+					}
+				}
+				scale.YearDistribution.ProjectAmount = append(scale.YearDistribution.ProjectAmount, eDAmount)
+				scale.YearDistribution.ProjectCount = append(scale.YearDistribution.ProjectCount, eDCount)
+			}
 		}
-		scale.MarketProfile.Projctamout += project.Sortprice
-		scale.MarketProfile.Projectavgmoney = utility.Sequential(scale.MarketProfile.Projctamout, float64(scale.MarketProfile.ProjectCount)) //项目平均金额(万)
 	}
-	//是否需要进行环比
-	if ut.IsRatio {
-		scale.ProjectInfoAll.ProjectCount += 1
-		scale.ProjectInfoAll.Projctamout += project.Sortprice
-		if project.Buyer != "" {
-			scale.ProjectInfoAll.Buyercount += 1
+	scaleFunc()
+	//项目规模TOP10 集合
+	topProject := ut.Result.TopProject
+	var topProjectFunc = func() {
+		if utility.DateIsIn(ut.StartTime, ut.EndTime, pt.JgTime, 0) && pt.Sortprice > 0 {
+			var (
+				entIdList = pt.Entidlist
+			)
+			if len(pt.Entidlist) > 0 {
+				for _, entId := range pt.Entidlist {
+					entIdList = append(entIdList, utility.EncodeId(entId))
+				}
+			}
+			topProject.ProjectTop10 = append(topProject.ProjectTop10, entity.ProjectTop{
+				Id:          common.If(pt.SourceInfoId != "", utility.EncodeId(pt.SourceInfoId), "").(string),
+				Area:        pt.Area,
+				City:        pt.City,
+				Eidlist:     entIdList,
+				Jgtime:      pt.JgTime,
+				Projectname: pt.ProjectName,
+				Sortprice:   pt.Sortprice,
+				WinnerS:     strings.Split(pt.Winners, ","),
+			})
 		}
-		if project.Winners != "" {
-			scale.ProjectInfoAll.Winnercount += len(strings.Split(project.Winners, ","))
+		if len(topProject.ProjectTop10) > 1 {
+			sort.Slice(topProject.ProjectTop10, func(i, j int) bool {
+				return topProject.ProjectTop10[i].Sortprice > topProject.ProjectTop10[j].Sortprice // 根据 price 字段进行倒序排序
+			})
+			if len(topProject.ProjectTop10) > consts.Top10 {
+				topProject.ProjectTop10 = topProject.ProjectTop10[:consts.Top10]
+			}
 		}
-		//项目平均金额(万)
-		scale.ProjectInfoAll.Projectavgmoney = utility.Sequential(scale.ProjectInfoAll.Projctamout, float64(scale.ProjectInfoAll.ProjectCount))
-		//采购单位项目数量环比
-		scale.MarketProfile.BuyercountRatio = utility.Sequential(float64(scale.MarketProfile.Buyercount), float64(scale.ProjectInfoAll.Buyercount))
-		//项目金额环比
-		scale.MarketProfile.ProjctamountRatio = utility.Sequential(scale.MarketProfile.Projctamout, scale.ProjectInfoAll.Projctamout)
-		//项目数量环比
-		scale.MarketProfile.ProjectCountRatio = utility.Sequential(float64(scale.MarketProfile.ProjectCount), float64(scale.ProjectInfoAll.ProjectCount))
-		//项目平均金额环比
-		scale.MarketProfile.ProjectavgmoneyRatio = utility.Sequential(scale.MarketProfile.Projectavgmoney, float64(scale.ProjectInfoAll.Projectavgmoney))
-		//采购单位环比
-		scale.MarketProfile.BuyercountRatio = utility.Sequential(float64(scale.MarketProfile.Buyercount), float64(scale.ProjectInfoAll.Buyercount))
 	}
-	//月度分配
-	if len(ut.MonthDistributionKey) > 0 {
-		for mdk, mdv := range ut.MonthDistributionKey {
-			eDAmount := entity.Distribution{} //金额
-			eDCount := entity.Distribution{}  //项目数量
-			eDAmount.Minth = mdv.Key
-			eDCount.Minth = mdv.Key
-			if utility.DateIsIn(mdv.From, mdv.To, project.JgTime, 0) {
-				eDAmount.Value += project.Sortprice
-				eDCount.Value += 1
-				if ut.IsRatio && mdk > 0 {
-					//计算环比
-					eDAmount.Ratio = utility.Sequential(eDAmount.Value, scale.MonthDistribution.ProjectAmount[mdk-1].Value)
-					eDCount.Ratio = utility.Sequential(eDCount.Value, scale.MonthDistribution.ProjectCount[mdk-1].Value)
+	topProjectFunc()
+	///* 项目规模 地区分布 客户分布 地区客户top3*/
+	pad := ut.Result.ProjectAllData
+	var projectAllFunc = func() {
+		//地区分布
+		var areaInfoFunc = func() {
+			areaInfoKey := utility.GetJudgmentPrevKey(consts.JudgmentPrev1, pt.Area)
+			cityInfoKey := utility.GetJudgmentPrevKey(consts.JudgmentPrev1, fmt.Sprintf("%s_%s", pt.Area, pt.City))
+			if !ut.JudgmentMap[areaInfoKey] {
+				ut.JudgmentMap[areaInfoKey] = true
+				ut.JudgmentMap[cityInfoKey] = true
+				pad.AreaInfos = append(pad.AreaInfos, &entity.AreaInfosS{
+					Amount: pt.Sortprice,
+					Area:   pt.Area,
+					AreaDetails: []*entity.AreaDetailsS{
+						{
+							Amount: pt.Sortprice,
+							City:   pt.City,
+							Total:  1,
+						},
+					},
+					Total: 1,
+				})
+			} else {
+				for _, ai := range pad.AreaInfos {
+					if ai.Area == pt.Area {
+						if !ut.JudgmentMap[cityInfoKey] {
+							ut.JudgmentMap[cityInfoKey] = true
+							ai.AreaDetails = append(ai.AreaDetails, &entity.AreaDetailsS{
+								Amount: pt.Sortprice,
+								City:   pt.City,
+								Total:  1,
+							})
+						} else {
+							for _, ci := range ai.AreaDetails {
+								if ci.City == pt.City {
+									ci.Amount += pt.Sortprice
+									ci.Total += 1
+								}
+							}
+						}
+						break
+					}
 				}
 			}
-			scale.MonthDistribution.ProjectAmount = append(scale.MonthDistribution.ProjectAmount, eDAmount)
-			scale.MonthDistribution.ProjectCount = append(scale.MonthDistribution.ProjectCount, eDCount)
 		}
+		areaInfoFunc()
+		//客户分布
+		var customerScaleFunc = func() {
+			bc := pt.BuyerClass
+			//客户分布
+			if bc != "" {
+				customerKey := utility.GetJudgmentPrevKey(consts.JudgmentPrev2, bc)
+				if bc == "其它" {
+					//客户分布(其它)
+					if !ut.JudgmentMap[customerKey] {
+						ut.JudgmentMap[customerKey] = true
+						//客户分布 其它
+						pad.CustomerScaleOther = &entity.CustomerScaleS{
+							Amount:   pt.Sortprice,
+							Buyclass: bc,
+							Total:    1,
+						}
+					} else {
+						pad.CustomerScaleOther.Amount += pt.Sortprice
+						pad.CustomerScaleOther.Total += 1
+					}
+				} else {
+					//客户分布
+					if !ut.JudgmentMap[customerKey] {
+						ut.JudgmentMap[customerKey] = true
+						pad.CustomerScale = append(pad.CustomerScale, &entity.CustomerScaleS{
+							Amount:   pt.Sortprice,
+							Buyclass: bc,
+							Total:    1,
+						})
+					} else {
+						for _, csm := range pad.CustomerScale {
+							if csm.Buyclass == bc {
+								csm.Amount += pt.Sortprice
+								csm.Total += 1
+							}
+						}
+					}
+				}
+				top3Key := utility.GetJudgmentPrevKey(consts.JudgmentPrev3, fmt.Sprintf("%s_top3", bc))
+				if !ut.JudgmentMap[top3Key] {
+					ut.JudgmentMap[top3Key] = true
+					//项目数量TOP3客户类型的重点中标单位
+					pad.ScaleBuyclassCountTop = append(pad.ScaleBuyclassCountTop, &entity.ScaleBuyclassCountTopS{
+						BuyclassCount: 1,
+						BuyclassScale: utility.Formula(1, float64(scale.MarketProfile.ProjectCount)),
+						Name:          bc,
+						Winner:        utility.GetWinnerInfoOfCount(pt),
+					})
+					//项目金额TOP3客户类型的重点中标单位
+					pad.ScaleBuyclassAmountTop = append(pad.ScaleBuyclassAmountTop, &entity.ScaleBuyclassAmountTopS{
+						BuyclassAmount: pt.Sortprice,
+						BuyclassScale:  utility.Formula(pt.Sortprice, float64(scale.MarketProfile.ProjectCount)),
+						Name:           bc,
+						Winner:         utility.GetWinnerInfoOfAmount(pt),
+					})
+				} else {
+					//项目数量TOP3客户类型的重点中标单位
+					for _, sbct := range pad.ScaleBuyclassCountTop {
+						if sbct.Name == bc {
+							sbct.BuyclassCount += 1
+							sbct.BuyclassScale = utility.Formula(float64(sbct.BuyclassCount), float64(scale.MarketProfile.ProjectCount))
+							if len(sbct.Winner) > 0 {
+								var wnMap = map[string]int{}
+								for wi, wn := range sbct.Winner {
+									wnMap[wn.Winner] = wi + 1
+								}
+								for wk, wd := range strings.Split(pt.Winners, ",") {
+									if wnMap[wd] > 0 {
+										sbct.Winner[wnMap[wd]-1].WinnerTotal += 1
+									} else {
+										sbct.Winner = append(sbct.Winner, &entity.WinnerTotal{
+											Id:          common.If(len(pt.Entidlist) > wk, encrypt.EncodeArticleId2ByCheck(pt.Entidlist[wk]), "").(string),
+											Winner:      wd,
+											WinnerTotal: 1,
+										})
+									}
+								}
+							} else {
+								sbct.Winner = utility.GetWinnerInfoOfCount(pt)
+							}
+							if len(sbct.Winner) > 1 {
+								sort.Slice(sbct.Winner, func(i, j int) bool {
+									return sbct.Winner[i].WinnerTotal > sbct.Winner[j].WinnerTotal
+								})
+								if len(sbct.Winner) > consts.Top3 {
+									sbct.Winner = sbct.Winner[:consts.Top3]
+								}
+							}
+						}
+					}
+					if len(pad.ScaleBuyclassCountTop) > 1 {
+						sort.Slice(pad.ScaleBuyclassCountTop, func(i, j int) bool {
+							return pad.ScaleBuyclassCountTop[i].BuyclassCount > pad.ScaleBuyclassCountTop[j].BuyclassCount
+						})
+						if len(pad.ScaleBuyclassCountTop) > consts.Top3 {
+							pad.ScaleBuyclassCountTop = pad.ScaleBuyclassCountTop[:consts.Top3]
+						}
+					}
+					//项目金额TOP3客户类型的重点中标单位
+					for _, sbat := range pad.ScaleBuyclassAmountTop {
+						if sbat.Name == bc {
+							sbat.BuyclassAmount += pt.Sortprice
+							sbat.BuyclassScale = utility.Formula(sbat.BuyclassAmount, float64(scale.MarketProfile.ProjectCount))
+							if len(sbat.Winner) > 0 {
+								var wnMap = map[string]int{}
+								for wi, wn := range sbat.Winner {
+									wnMap[wn.Winner] = wi + 1
+								}
+								for wk, wd := range strings.Split(pt.Winners, ",") {
+									if wnMap[wd] > 0 {
+										sbat.Winner[wnMap[wd]-1].WinnerAmount += pt.Sortprice
+									} else {
+										sbat.Winner = append(sbat.Winner, &entity.WinnerAmount{
+											Id:           common.If(len(pt.Entidlist) > wk, encrypt.EncodeArticleId2ByCheck(pt.Entidlist[wk]), "").(string),
+											Winner:       wd,
+											WinnerAmount: pt.Sortprice,
+										})
+									}
+								}
+							} else {
+								sbat.Winner = utility.GetWinnerInfoOfAmount(pt)
+							}
+							if len(sbat.Winner) > 1 {
+								sort.Slice(sbat.Winner, func(i, j int) bool {
+									return sbat.Winner[i].WinnerAmount > sbat.Winner[j].WinnerAmount
+								})
+								if len(sbat.Winner) > consts.Top3 {
+									sbat.Winner = sbat.Winner[:consts.Top3]
+								}
+							}
+						}
+					}
+					if len(pad.ScaleBuyclassCountTop) > 1 {
+						sort.Slice(pad.ScaleBuyclassCountTop, func(i, j int) bool {
+							return pad.ScaleBuyclassCountTop[i].BuyclassCount > pad.ScaleBuyclassCountTop[j].BuyclassCount
+						})
+						if len(pad.ScaleBuyclassCountTop) > consts.Top3 {
+							pad.ScaleBuyclassCountTop = pad.ScaleBuyclassCountTop[:consts.Top3]
+						}
+					}
+				}
+			}
+		}
+		customerScaleFunc()
+		//项目规模分布
+		var ProjectScaleFunc = func() {
+			var psk = ""
+			for _, cp := range consts.ProjectScale {
+				if cp.From < pt.Sortprice && common.If(cp.To > 0, cp.To > pt.Sortprice, true).(bool) {
+					psk = cp.Key
+				}
+			}
+			scaleKey := utility.GetJudgmentPrevKey(consts.JudgmentPrev4, psk)
+			if !ut.JudgmentMap[scaleKey] {
+				ut.JudgmentMap[scaleKey] = true
+				pad.ProjectScale = append(pad.ProjectScale, &entity.ProjectScaleS{
+					Name:     psk,
+					Count:    1,
+					Amount:   pt.Sortprice,
+					PersentA: utility.Formula(1, float64(scale.MarketProfile.ProjectCount)),
+					PersentC: utility.Formula(pt.Sortprice, scale.MarketProfile.Projctamout),
+				})
+			} else {
+				for _, ps := range pad.ProjectScale {
+					if ps.Name == psk {
+						ps.Count += 1
+						ps.Amount += pt.Sortprice
+						ps.PersentC = utility.Formula(ps.Amount, scale.MarketProfile.Projctamout)
+						ps.PersentA = utility.Formula(float64(ps.Count), float64(scale.MarketProfile.ProjectCount))
+						break
+					}
+				}
+			}
+		}
+		ProjectScaleFunc()
+		//项目金额TOP3地区的重点中标单位
+		var scaleAreaAmountAndCountTopFunc = func() {
+			//项目金额---TOP3地区的重点中标单位
+			//项目数量---TOP3地区的重点中标单位
+			saaactKey := utility.GetJudgmentPrevKey(consts.JudgmentPrev5, pt.Area)
+			if !ut.JudgmentMap[saaactKey] {
+				ut.JudgmentMap[saaactKey] = true
+				//项目金额---TOP3地区的重点中标单位
+				pad.ScaleAreaAmountTop = append(pad.ScaleAreaAmountTop, &entity.ScaleAreaAmountTopS{
+					AreaAmount: pt.Sortprice,
+					AreaScale:  utility.Formula(pt.Sortprice, scale.MarketProfile.Projctamout),
+					Name:       pt.Area,
+					Winner:     utility.GetWinnerInfoOfAmount(pt),
+				})
+				//项目数量---TOP3地区的重点中标单位
+				pad.ScaleAreaCountTop = append(pad.ScaleAreaCountTop, &entity.ScaleAreaCountTopS{
+					AreaCount: 1,
+					AreaScale: utility.Formula(1, scale.MarketProfile.Projctamout),
+					Name:      pt.Area,
+					Winner:    utility.GetWinnerInfoOfCount(pt),
+				})
+			} else {
+				//项目金额---TOP3地区的重点中标单位
+				for _, saat := range pad.ScaleAreaAmountTop {
+					if saat.Name == pt.Area {
+						saat.AreaAmount += pt.Sortprice
+						saat.AreaScale = utility.Formula(saat.AreaAmount, scale.MarketProfile.Projctamout)
+						if len(saat.Winner) > 0 {
+							var wnMap = map[string]int{}
+							for wi, wn := range saat.Winner {
+								wnMap[wn.Winner] = wi + 1
+							}
+							for wk, wd := range strings.Split(pt.Winners, ",") {
+								if wnMap[wd] > 0 {
+									saat.Winner[wnMap[wd]-1].WinnerAmount += pt.Sortprice
+								} else {
+									saat.Winner = append(saat.Winner, &entity.WinnerAmount{
+										Id:           common.If(len(pt.Entidlist) > wk, encrypt.EncodeArticleId2ByCheck(pt.Entidlist[wk]), "").(string),
+										Winner:       wd,
+										WinnerAmount: pt.Sortprice,
+									})
+								}
+							}
+						} else {
+							saat.Winner = utility.GetWinnerInfoOfAmount(pt)
+						}
+						if len(saat.Winner) > 1 {
+							sort.Slice(saat.Winner, func(i, j int) bool {
+								return saat.Winner[i].WinnerAmount > saat.Winner[j].WinnerAmount
+							})
+							if len(saat.Winner) > consts.Top3 {
+								saat.Winner = saat.Winner[:consts.Top3]
+							}
+						}
+					}
+				}
+				if len(pad.ScaleAreaAmountTop) > 1 {
+					sort.Slice(pad.ScaleAreaAmountTop, func(i, j int) bool {
+						return pad.ScaleAreaAmountTop[i].AreaAmount > pad.ScaleAreaAmountTop[j].AreaAmount
+					})
+					if len(pad.ScaleAreaAmountTop) > consts.Top3 {
+						pad.ScaleAreaAmountTop = pad.ScaleAreaAmountTop[:consts.Top3]
+					}
+				}
+				//项目数量---TOP3地区的重点中标单位
+				for _, sact := range pad.ScaleAreaCountTop {
+					if sact.Name == pt.Area {
+						sact.AreaCount += 1
+						sact.AreaScale = utility.Formula(float64(sact.AreaCount), scale.MarketProfile.Projctamout)
+						if len(sact.Winner) > 0 {
+							var wnMap = map[string]int{}
+							for wi, wn := range sact.Winner {
+								wnMap[wn.Winner] = wi + 1
+							}
+							for wk, wd := range strings.Split(pt.Winners, ",") {
+								if wnMap[wd] > 0 {
+									sact.Winner[wnMap[wd]-1].WinnerTotal += 1
+								} else {
+									sact.Winner = append(sact.Winner, &entity.WinnerTotal{
+										Id:          common.If(len(pt.Entidlist) > wk, encrypt.EncodeArticleId2ByCheck(pt.Entidlist[wk]), "").(string),
+										Winner:      wd,
+										WinnerTotal: 1,
+									})
+								}
+							}
+						} else {
+							sact.Winner = utility.GetWinnerInfoOfCount(pt)
+						}
+						if len(sact.Winner) > 1 {
+							sort.Slice(sact.Winner, func(i, j int) bool {
+								return sact.Winner[i].WinnerTotal > sact.Winner[j].WinnerTotal
+							})
+							if len(sact.Winner) > consts.Top3 {
+								sact.Winner = sact.Winner[:consts.Top3]
+							}
+						}
+					}
+				}
+				if len(pad.ScaleAreaCountTop) > 1 {
+					sort.Slice(pad.ScaleAreaCountTop, func(i, j int) bool {
+						return pad.ScaleAreaCountTop[i].AreaCount > pad.ScaleAreaCountTop[j].AreaCount
+					})
+					if len(pad.ScaleAreaCountTop) > consts.Top3 {
+						pad.ScaleAreaCountTop = pad.ScaleAreaCountTop[:consts.Top3]
+					}
+				}
+			}
+		}
+		scaleAreaAmountAndCountTopFunc()
+		//
+	}
+	projectAllFunc()
+	//细化市场
+	sr := ut.Result.ScaleRefine
+	var scaleRefineFunc = func() {
+		//订阅分类|重点中标单位-项目数量|重点中标单位-项目金额
+		var scaleRefineAllAndAmountAndTotalFunc = func() {
+			for _, keysItems := range ut.FormatParam.KeysItems {
+				if ut.KeysMatchByKeysItems(pt.ProjectName, keysItems) {
+					itemName := keysItems.ItemName
+					itemNameKey := utility.GetJudgmentPrevKey(consts.JudgmentPrev6, itemName)
+					if !ut.JudgmentMap[itemNameKey] {
+						ut.JudgmentMap[itemNameKey] = true
+						//订阅分类
+						sr.ScaleRefineAll = append(sr.ScaleRefineAll, &entity.ScaleRefineAllS{
+							Amount: pt.Sortprice,
+							Name:   itemName,
+							Total:  1,
+						})
+						//重点中标单位-项目数量
+						sr.ScaleRefineTotalTop = append(sr.ScaleRefineTotalTop, &entity.ScaleRefineTotalTopS{
+							Name:    itemName,
+							Value:   1,
+							Prop:    utility.Formula(1, float64(scale.MarketProfile.ProjectCount)),
+							TopList: utility.GetWinnerInfoTopList(pt, 1, float64(scale.MarketProfile.ProjectCount)),
+						})
+						//重点中标单位-金额
+						sr.ScaleRefineAmountTop = append(sr.ScaleRefineAmountTop, &entity.ScaleRefineAmountTopS{
+							Name:    itemName,
+							Value:   pt.Sortprice,
+							Prop:    utility.Formula(pt.Sortprice, scale.MarketProfile.Projctamout),
+							TopList: utility.GetWinnerInfoTopList(pt, pt.Sortprice, scale.MarketProfile.Projctamout),
+						})
+					} else {
+						//订阅分类
+						for _, sra := range sr.ScaleRefineAll {
+							if sra.Name == itemName {
+								sra.Total += 1
+								sra.Amount += pt.Sortprice
+							}
+						}
+						//重点中标单位-项目数量
+						for _, srtt := range sr.ScaleRefineTotalTop {
+							if srtt.Name == itemName {
+								srtt.Value += 1
+								srtt.Prop = utility.Formula(float64(srtt.Value), float64(scale.MarketProfile.ProjectCount))
+								if len(srtt.TopList) > 0 {
+									var wnMap = map[string]int{}
+									for wi, wn := range srtt.TopList {
+										wnMap[wn.Name] = wi + 1
+									}
+									for wk, wd := range strings.Split(pt.Winners, ",") {
+										if wnMap[wd] > 0 {
+											srtt.TopList[wnMap[wd]-1].Value += 1
+											srtt.TopList[wnMap[wd]-1].Prop = utility.Formula(srtt.TopList[wnMap[wd]-1].Value, float64(scale.MarketProfile.ProjectCount))
+										} else {
+											srtt.TopList = append(srtt.TopList, &entity.TopListS{
+												Id:    common.If(len(pt.Entidlist) > wk, encrypt.EncodeArticleId2ByCheck(pt.Entidlist[wk]), "").(string),
+												Name:  wd,
+												Value: 1,
+												Prop:  utility.Formula(1, float64(scale.MarketProfile.ProjectCount)),
+											})
+										}
+									}
+								} else {
+									srtt.TopList = utility.GetWinnerInfoTopList(pt, 1, float64(scale.MarketProfile.ProjectCount))
+								}
+								if len(srtt.TopList) > 1 {
+									sort.Slice(srtt.TopList, func(i, j int) bool {
+										return srtt.TopList[i].Value > srtt.TopList[j].Value
+									})
+									if len(srtt.TopList) > consts.Top3 {
+										srtt.TopList = srtt.TopList[:consts.Top3]
+									}
+								}
+							}
+						}
+						//重点中标单位-金额
+						for _, srat := range sr.ScaleRefineAmountTop {
+							if srat.Name == itemName {
+								srat.Value += pt.Sortprice
+								srat.Prop = utility.Formula(srat.Value, float64(scale.MarketProfile.ProjectCount))
+								if len(srat.TopList) > 0 {
+									var wnMap = map[string]int{}
+									for wi, wn := range srat.TopList {
+										wnMap[wn.Name] = wi + 1
+									}
+									for wk, wd := range strings.Split(pt.Winners, ",") {
+										if wnMap[wd] > 0 {
+											srat.TopList[wnMap[wd]-1].Value += pt.Sortprice
+											srat.TopList[wnMap[wd]-1].Prop = utility.Formula(srat.TopList[wnMap[wd]-1].Value, float64(scale.MarketProfile.ProjectCount))
+										} else {
+											srat.TopList = append(srat.TopList, &entity.TopListS{
+												Id:    common.If(len(pt.Entidlist) > wk, encrypt.EncodeArticleId2ByCheck(pt.Entidlist[wk]), "").(string),
+												Name:  wd,
+												Value: pt.Sortprice,
+												Prop:  utility.Formula(pt.Sortprice, float64(scale.MarketProfile.ProjectCount)),
+											})
+										}
+									}
+								} else {
+									srat.TopList = utility.GetWinnerInfoTopList(pt, pt.Sortprice, float64(scale.MarketProfile.ProjectCount))
+								}
+								if len(srat.TopList) > 1 {
+									sort.Slice(srat.TopList, func(i, j int) bool {
+										return srat.TopList[i].Value > srat.TopList[j].Value
+									})
+									//sort 排序 剪切有问题 待处理--------------------------------------- 在这里进行切片处理,会把有效数据误删
+									if len(srat.TopList) > consts.Top3 {
+										srat.TopList = srat.TopList[:consts.Top3]
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+		scaleRefineAllAndAmountAndTotalFunc()
 	}
-	//月度分配
-	if len(ut.YearDistributionKey) > 0 {
-		for ydk, ydv := range ut.YearDistributionKey {
-			eDAmount := entity.Distribution{} //金额
-			eDCount := entity.Distribution{}  //项目数量
-			eDAmount.Minth = ydv.Key
-			eDCount.Minth = ydv.Key
-			if utility.DateIsIn(ydv.From, ydv.To, project.JgTime, 0) {
-				eDAmount.Value += project.Sortprice
-				eDCount.Value += 1
-				if ut.IsRatio && ydk > 0 {
-					//计算环比
-					eDAmount.Ratio = utility.Sequential(eDAmount.Value, scale.YearDistribution.ProjectAmount[ydk-1].Value)
-					eDCount.Ratio = utility.Sequential(eDCount.Value, scale.YearDistribution.ProjectCount[ydk-1].Value)
+	scaleRefineFunc()
+	///* 市场-采购单位&&中标企业*/
+	baw := ut.Result.BuyerAndWinner
+	var buyerAndWinnerFunc = func() {
+		//采购单位
+		var buyerAmountAndTotalTop30 = func() {
+			baaattKey := utility.GetJudgmentPrevKey(consts.JudgmentPrev7, pt.Buyer)
+			if !ut.JudgmentMap[baaattKey] {
+				ut.JudgmentMap[baaattKey] = true
+				//项目数量TOP30采购单位及其重点合作中标单位
+				baw.BuyerCountTop3 = append(baw.BuyerCountTop3, &entity.BuyerCountTop3S{
+					Name:       pt.Buyer,
+					Number:     1,
+					Winnertop3: utility.GetWinnerInfoOfBuyerCount(pt),
+				})
+				//采购金额TOP30采购单位及其重点合作中标单位
+				baw.BuyerAmountTop3 = append(baw.BuyerAmountTop3, &entity.BuyerAmountTop3S{
+					Name:       pt.Buyer,
+					Amount:     pt.Sortprice,
+					Winnertop3: utility.GetWinnerInfoOfBuyerAmount(pt),
+				})
+			} else {
+				//项目数量TOP30采购单位及其重点合作中标单位
+				for _, bct := range baw.BuyerCountTop3 {
+					if bct.Name == pt.Buyer {
+						bct.Number += 1
+						if len(bct.Winnertop3) == 0 {
+							bct.Winnertop3 = utility.GetWinnerInfoOfBuyerCount(pt)
+						} else {
+							var wnMap = map[string]int{}
+							for wi, wn := range bct.Winnertop3 {
+								wnMap[wn.Name] = wi + 1
+							}
+							for wk, wd := range strings.Split(pt.Winners, ",") {
+								if wnMap[wd] > 0 {
+									bct.Winnertop3[wnMap[wd]-1].Number += 1
+								} else {
+									bct.Winnertop3 = append(bct.Winnertop3, &entity.Winnertop3Number{
+										Id:     common.If(len(pt.Entidlist) > wk, encrypt.EncodeArticleId2ByCheck(pt.Entidlist[wk]), "").(string),
+										Name:   wd,
+										Number: 1,
+									})
+								}
+							}
+						}
+						break
+					}
+				}
+				//采购金额TOP30采购单位及其重点合作中标单位
+				for _, bat := range baw.BuyerAmountTop3 {
+					if bat.Name == pt.Buyer {
+						bat.Amount += pt.Sortprice
+						if len(bat.Winnertop3) == 0 {
+							bat.Winnertop3 = utility.GetWinnerInfoOfBuyerAmount(pt)
+						} else {
+							var wnMap = map[string]int{}
+							for wi, wn := range bat.Winnertop3 {
+								wnMap[wn.Name] = wi + 1
+							}
+							for wk, wd := range strings.Split(pt.Winners, ",") {
+								if wnMap[wd] > 0 {
+									bat.Winnertop3[wnMap[wd]-1].Amount += pt.Sortprice
+								} else {
+									bat.Winnertop3 = append(bat.Winnertop3, &entity.Winnertop3Amount{
+										Id:     common.If(len(pt.Entidlist) > wk, encrypt.EncodeArticleId2ByCheck(pt.Entidlist[wk]), "").(string),
+										Name:   wd,
+										Amount: pt.Sortprice,
+									})
+								}
+							}
+						}
+						break
+					}
+				}
+			}
+			//采购规模分布
+			var psk = ""
+			for _, cp := range consts.ProjectScale {
+				if cp.From < pt.Sortprice && common.If(cp.To > 0, cp.To > pt.Sortprice, true).(bool) {
+					psk = cp.Key
+				}
+			}
+			scaleKey := utility.GetJudgmentPrevKey(consts.JudgmentPrev8, psk)
+			if !ut.JudgmentMap[scaleKey] {
+				ut.JudgmentMap[scaleKey] = true
+				baw.BuyerTimeDistribution = append(baw.BuyerTimeDistribution, &entity.BuyerAndWinnerTimeDistributionS{
+					Key:         psk,
+					Amount:      pt.Sortprice,
+					Number:      1,
+					TotalAmount: utility.Formula(pt.Sortprice, scale.MarketProfile.Projctamout),
+					TotalNumber: utility.Formula(1, float64(scale.MarketProfile.ProjectCount)),
+				})
+			} else {
+				for _, ps := range baw.BuyerTimeDistribution {
+					if ps.Key == psk {
+						ps.Number += 1
+						ps.Amount += pt.Sortprice
+						ps.TotalAmount = utility.Formula(ps.Amount, scale.MarketProfile.Projctamout)
+						ps.TotalNumber = utility.Formula(ps.Number, float64(scale.MarketProfile.ProjectCount))
+						break
+					}
+				}
+			}
+		}
+		if pt.Buyer != "" {
+			buyerAmountAndTotalTop30()
+		}
+		//中标单位
+		var winnerAmountAndTotalTop30 = func() {
+			for _, winner := range strings.Split(pt.Winners, ",") {
+				waaattKey := utility.GetJudgmentPrevKey(consts.JudgmentPrev9, winner)
+				if !ut.JudgmentMap[waaattKey] {
+					ut.JudgmentMap[waaattKey] = true
+					//项目数量TOP30中标单位及其重点合作采购单位
+					baw.WinnerCountTop3 = append(baw.WinnerCountTop3, &entity.WinnerCountTop3S{
+						Name:      winner,
+						Number:    1,
+						Buyertop3: utility.GetWinnerInfoOfWinnerCount(pt),
+					})
+					//中标金额TOP30中标单位及其重点合作采购单位
+					baw.WinnerAmountTop3 = append(baw.WinnerAmountTop3, &entity.WinnerAmountTop3S{
+						Name:      winner,
+						Amount:    pt.Sortprice,
+						Buyertop3: utility.GetWinnerInfoOfWinnerAmount(pt),
+					})
+				} else {
+					//项目数量TOP30中标单位及其重点合作采购单位
+					for _, wct := range baw.WinnerCountTop3 {
+						if wct.Name == winner {
+							wct.Number += 1
+							if len(wct.Buyertop3) == 0 {
+								wct.Buyertop3 = utility.GetWinnerInfoOfWinnerCount(pt)
+							} else {
+								var wnMap = map[string]int{}
+								for wi, wn := range wct.Buyertop3 {
+									if wn.Name == pt.Buyer {
+										wnMap[wn.Name] = wi + 1
+										break
+									}
+								}
+								if wnMap[pt.Buyer] > 0 {
+									wct.Buyertop3[wnMap[pt.Buyer]-1].Number += 1
+								} else {
+									wct.Buyertop3 = append(wct.Buyertop3, &entity.Buyertop3Number{
+										Name:   pt.Buyer,
+										Number: 1,
+									})
+								}
+							}
+							break
+						}
+					}
+					//中标金额TOP30中标单位及其重点合作采购单位
+					for _, wat := range baw.WinnerAmountTop3 {
+						if wat.Name == pt.Buyer {
+							wat.Amount += pt.Sortprice
+							if len(wat.Buyertop3) == 0 {
+								wat.Buyertop3 = utility.GetWinnerInfoOfWinnerAmount(pt)
+							} else {
+								var wnMap = map[string]int{}
+								for wi, wn := range wat.Buyertop3 {
+									if wn.Name == pt.Buyer {
+										wnMap[wn.Name] = wi + 1
+									}
+								}
+								if wnMap[pt.Buyer] > 0 {
+									wat.Buyertop3[wnMap[pt.Buyer]-1].Amount += pt.Sortprice
+								} else {
+									wat.Buyertop3 = append(wat.Buyertop3, &entity.Buyertop3Amount{
+										Name:   pt.Buyer,
+										Amount: pt.Sortprice,
+									})
+								}
+							}
+							break
+						}
+					}
+				}
+			}
+			//中标规模分布
+			var psk = ""
+			for _, cp := range consts.ProjectScale {
+				if cp.From < pt.Sortprice && common.If(cp.To > 0, cp.To > pt.Sortprice, true).(bool) {
+					psk = cp.Key
 				}
 			}
-			scale.YearDistribution.ProjectAmount = append(scale.YearDistribution.ProjectAmount, eDAmount)
-			scale.YearDistribution.ProjectCount = append(scale.YearDistribution.ProjectCount, eDCount)
+			scaleKey := utility.GetJudgmentPrevKey(consts.JudgmentPrev10, psk)
+			if !ut.JudgmentMap[scaleKey] {
+				ut.JudgmentMap[scaleKey] = true
+				baw.WinnerTimeDistribution = append(baw.WinnerTimeDistribution, &entity.BuyerAndWinnerTimeDistributionS{
+					Key:         psk,
+					Amount:      pt.Sortprice,
+					Number:      1,
+					TotalAmount: utility.Formula(pt.Sortprice, scale.MarketProfile.Projctamout),
+					TotalNumber: utility.Formula(1, float64(scale.MarketProfile.ProjectCount)),
+				})
+			} else {
+				for _, ps := range baw.WinnerTimeDistribution {
+					if ps.Key == psk {
+						ps.Number += 1
+						ps.Amount += pt.Sortprice
+						ps.TotalAmount = utility.Formula(ps.Amount, scale.MarketProfile.Projctamout)
+						ps.TotalNumber = utility.Formula(ps.Number, float64(scale.MarketProfile.ProjectCount))
+						break
+					}
+				}
+			}
+		}
+		if pt.Winners != "" {
+			winnerAmountAndTotalTop30()
 		}
 	}
+	buyerAndWinnerFunc()
 }
 
 // ResultSave  结果保存

+ 7 - 6
internal/model/entity/project.go

@@ -25,10 +25,11 @@ type ProjectInfo struct {
 		Title      string  `json:"title"`
 		Toptype    string  `json:"toptype"`
 	}
-	ProjectName string  `json:"projectname"`     //项目名称 字段:projectname
-	Purchasing  string  `json:"purchasing"`      //标的物 字段:purchasing
-	Industry    string  `json:"s_subscopeclass"` //行业 字段:subscopeclass
-	Winners     string  `json:"s_winner"`        //
-	Sortprice   float64 `json:"sortprice"`       //优先是中标金额>其次是预算
-	Winner      string  `json:"winner"`          //中标企业
+	ProjectName  string  `json:"projectname"`     //项目名称 字段:projectname
+	Purchasing   string  `json:"purchasing"`      //标的物 字段:purchasing
+	Industry     string  `json:"s_subscopeclass"` //行业 字段:subscopeclass
+	Winners      string  `json:"s_winner"`        //
+	Sortprice    float64 `json:"sortprice"`       //优先是中标金额>其次是预算
+	SourceInfoId string  `json:"sourceinfoid"`    //招标信息id
+	Winner       string  `json:"winner"`          //中标企业
 }

+ 67 - 70
internal/model/entity/result.go

@@ -50,7 +50,7 @@ type ProjectTop struct {
 	Area        string   `json:"area"`        //省份
 	City        string   `json:"city"`        //城市
 	Eidlist     []string `json:"eidlist"`     //中标企业id集合
-	Jgtime      int      `json:"jgtime"`      //结果时间
+	Jgtime      int64    `json:"jgtime"`      //结果时间
 	Projectname string   `json:"projectname"` //项目名称
 	Sortprice   float64  `json:"sortprice"`   //中标金额 > 预算
 	WinnerS     []string `json:"winner_s"`    //中标企业名称集合
@@ -70,10 +70,10 @@ type AreaDetailsS struct {
 
 // 地区分布
 type AreaInfosS struct {
-	Amount      float64        `json:"amount"`      //总金额
-	Area        string         `json:"area"`        //省份
-	AreaDetails []AreaDetailsS `json:"areaDetails"` //城市项目分布详情
-	Total       int            `json:"total"`       //省份项目总数
+	Amount      float64         `json:"amount"`      //总金额
+	Area        string          `json:"area"`        //省份
+	AreaDetails []*AreaDetailsS `json:"areaDetails"` //城市项目分布详情
+	Total       int             `json:"total"`       //省份项目总数
 }
 
 // 客户分布
@@ -88,6 +88,8 @@ type ProjectScaleS struct {
 	Name     string  `json:"Name"`      //项目规模名称
 	PersentC float64 `json:"Persent_c"` //项目总金额占比
 	PersentA float64 `json:"Persent_a"` //项目总数占比
+	Count    int     `json:"count"`     //项目总数--del--
+	Amount   float64 `json:"amount"`    //总金额--del--
 }
 
 // 中标单位信息-金额
@@ -99,10 +101,10 @@ type WinnerAmount struct {
 
 // 项目金额TOP3地区的重点中标单位
 type ScaleAreaAmountTopS struct {
-	AreaAmount float64        `json:"area_amount"` //地区总金额
-	AreaScale  float64        `json:"area_scale"`  //地区环比
-	Name       string         `json:"name"`        //省份
-	Winner     []WinnerAmount `json:"winner"`      //中标单位信息
+	AreaAmount float64         `json:"area_amount"` //地区总金额
+	AreaScale  float64         `json:"area_scale"`  //地区环比
+	Name       string          `json:"name"`        //省份
+	Winner     []*WinnerAmount `json:"winner"`      //中标单位信息
 }
 
 // 中标单位信息-项目数量
@@ -114,44 +116,44 @@ type WinnerTotal struct {
 
 // 项目数量TOP3地区的重点中标单位
 type ScaleAreaCountTopS struct {
-	AreaCount int           `json:"area_count"` //项目数量
-	AreaScale float64       `json:"area_scale"` //项目数量占比
-	Name      string        `json:"name"`       //城市
-	Winner    []WinnerTotal `json:"winner"`     //中标企业集合
+	AreaCount int            `json:"area_count"` //项目数量
+	AreaScale float64        `json:"area_scale"` //项目数量占比
+	Name      string         `json:"name"`       //城市
+	Winner    []*WinnerTotal `json:"winner"`     //中标企业集合
 }
 
 // 项目金额TOP3客户类型的重点中标单位
 type ScaleBuyclassAmountTopS struct {
-	BuyclassAmount float64        `json:"buyclass_amount"` //采购单位类型总金额
-	BuyclassScale  float64        `json:"buyclass_scale"`  //采购单位类型金额占比
-	Name           string         `json:"name"`            //采购单位类型名称
-	Winner         []WinnerAmount `json:"winner"`          //中标企业集合
+	BuyclassAmount float64         `json:"buyclass_amount"` //采购单位类型总金额
+	BuyclassScale  float64         `json:"buyclass_scale"`  //采购单位类型金额占比
+	Name           string          `json:"name"`            //采购单位类型名称
+	Winner         []*WinnerAmount `json:"winner"`          //中标企业集合
 }
 
 // 项目数量TOP3客户类型的重点中标单位
 type ScaleBuyclassCountTopS struct {
-	BuyclassCount int           `json:"buyclass_count"` //采购单位项目数量
-	BuyclassScale float64       `json:"buyclass_scale"` //采购单位数量环比
-	Name          string        `json:"name"`           //采购单位名称
-	Winner        []WinnerTotal `json:"winner"`         //中标企业集合
+	BuyclassCount int            `json:"buyclass_count"` //采购单位项目数量
+	BuyclassScale float64        `json:"buyclass_scale"` //采购单位数量环比
+	Name          string         `json:"name"`           //采购单位名称
+	Winner        []*WinnerTotal `json:"winner"`         //中标企业集合
 }
 type MarketProjectAllData struct {
 	//地区分布
-	AreaInfos []AreaInfosS `json:"area_infos"`
+	AreaInfos []*AreaInfosS `json:"area_infos"`
 	//客户分布
-	CustomerScale []CustomerScaleS `json:"customer_scale"`
+	CustomerScale []*CustomerScaleS `json:"customer_scale"`
 	//客户分布(其它)
-	CustomerScaleOther CustomerScaleS `json:"customer_scale_other"`
+	CustomerScaleOther *CustomerScaleS `json:"customer_scale_other"`
 	//项目规模分布
-	ProjectScale []ProjectScaleS `json:"projectScale"`
+	ProjectScale []*ProjectScaleS `json:"projectScale"`
 	//项目金额TOP3地区的重点中标单位
-	ScaleAreaAmountTop []ScaleAreaAmountTopS `json:"scaleAreaAmountTop"`
+	ScaleAreaAmountTop []*ScaleAreaAmountTopS `json:"scaleAreaAmountTop"`
 	//项目数量TOP3地区的重点中标单位
-	ScaleAreaCountTop []ScaleAreaCountTopS `json:"scaleAreaCountTop"`
+	ScaleAreaCountTop []*ScaleAreaCountTopS `json:"scaleAreaCountTop"`
 	//项目金额TOP3客户类型的重点中标单位
-	ScaleBuyclassAmountTop []ScaleBuyclassAmountTopS `json:"scaleBuyclassAmountTop"`
+	ScaleBuyclassAmountTop []*ScaleBuyclassAmountTopS `json:"scaleBuyclassAmountTop"`
 	//项目数量TOP3客户类型的重点中标单位
-	ScaleBuyclassCountTop []ScaleBuyclassCountTopS `json:"scaleBuyclassCountTop"`
+	ScaleBuyclassCountTop []*ScaleBuyclassCountTopS `json:"scaleBuyclassCountTop"`
 }
 
 /*细化市场*/
@@ -172,28 +174,28 @@ type TopListS struct {
 
 // 细分市场的重点中标单位-项目金额
 type ScaleRefineAmountTopS struct {
-	Name    string     `json:"name"`    //分类名称
-	Value   float64    `json:"value"`   //金额总数
-	Prop    int        `json:"prop"`    //分类金额百分比
-	TopList []TopListS `json:"topList"` //中标企业集合 金额排序前三个
+	Name    string      `json:"name"`    //分类名称
+	Value   float64     `json:"value"`   //金额总数
+	Prop    float64     `json:"prop"`    //分类金额百分比
+	TopList []*TopListS `json:"topList"` //中标企业集合 金额排序前三个
 }
 
 // 细分市场的重点中标单位-项目数量
 type ScaleRefineTotalTopS struct {
-	Name    string     `json:"name"`    //分类名称
-	Value   int        `json:"value"`   //项目数量
-	Prop    int        `json:"prop"`    //项目数量占比
-	TopList []TopListS `json:"topList"` //中标企业集合 项目数量排序前三个
+	Name    string      `json:"name"`    //分类名称
+	Value   int         `json:"value"`   //项目数量
+	Prop    float64     `json:"prop"`    //项目数量占比
+	TopList []*TopListS `json:"topList"` //中标企业集合 项目数量排序前三个
 }
 
 // 细化市场
 type MarketScaleRefine struct {
 	//订阅分类
-	ScaleRefineAll []ScaleRefineAllS `json:"scaleRefineAll"`
+	ScaleRefineAll []*ScaleRefineAllS `json:"scaleRefineAll"`
 	//细分市场的重点中标单位-项目金额
-	ScaleRefineAmountTop []ScaleRefineAmountTopS `json:"scaleRefineAmountTop"`
+	ScaleRefineAmountTop []*ScaleRefineAmountTopS `json:"scaleRefineAmountTop"`
 	//细分市场的重点中标单位-项目数量
-	ScaleRefineTotalTop []ScaleRefineTotalTopS `json:"scaleRefineTotalTop"`
+	ScaleRefineTotalTop []*ScaleRefineTotalTopS `json:"scaleRefineTotalTop"`
 }
 
 /* 市场-采购单位&&中标企业*/
@@ -206,9 +208,9 @@ type Winnertop3Amount struct {
 
 // 采购金额TOP30采购单位及其重点合作中标单位
 type BuyerAmountTop3S struct {
-	Name       string             `json:"name"`       //采购单位名称
-	Amount     float64            `json:"amount"`     //采购单位金额
-	Winnertop3 []Winnertop3Amount `json:"winnertop3"` //合作 中标企业 金额 前三
+	Name       string              `json:"name"`       //采购单位名称
+	Amount     float64             `json:"amount"`     //采购单位金额
+	Winnertop3 []*Winnertop3Amount `json:"winnertop3"` //合作 中标企业 金额 前三
 }
 type Winnertop3Number struct {
 	Id     string `json:"id"`     //中标企业id
@@ -217,15 +219,17 @@ type Winnertop3Number struct {
 }
 
 // 项目数量TOP30采购单位及其重点合作中标单位
-type BuyerCountTop3S []struct {
-	Name       string             `json:"name"`       //采购单位名称
-	Number     int                `json:"number"`     //采购单位项目数量
-	Winnertop3 []Winnertop3Number `json:"winnertop3"` //合作中标企业结婚  项目数量 倒叙 前三
+type BuyerCountTop3S struct {
+	Name       string              `json:"name"`       //采购单位名称
+	Number     int                 `json:"number"`     //采购单位项目数量
+	Winnertop3 []*Winnertop3Number `json:"winnertop3"` //合作中标企业结婚  项目数量 倒叙 前三
 }
 
-// 采购规模分布
-type BuyerTimeDistributionS struct {
+// 采购规模分布|中标规模分布
+type BuyerAndWinnerTimeDistributionS struct {
 	Key         string  `json:"key"`          //采购规模名称 (金额分隔
+	Amount      float64 `json:"amount"`       //------del----
+	Number      float64 `json:"number"`       //------del-------
 	TotalAmount float64 `json:"total_amount"` //总金额
 	TotalNumber float64 `json:"total_number"` //总项目数量
 }
@@ -238,10 +242,10 @@ type Buyertop3Amount struct {
 
 // 中标金额TOP30中标单位及其重点合作采购单位
 type WinnerAmountTop3S struct {
-	Id        string            `json:"id"`        //中标企业id
-	Name      string            `json:"name"`      //中标企业名称
-	Amount    float64           `json:"amount"`    //中标金额
-	Buyertop3 []Buyertop3Amount `json:"buyertop3"` //合作采购单位 中标金额排序 前三
+	Id        string             `json:"id"`        //中标企业id
+	Name      string             `json:"name"`      //中标企业名称
+	Amount    float64            `json:"amount"`    //中标金额
+	Buyertop3 []*Buyertop3Amount `json:"buyertop3"` //合作采购单位 中标金额排序 前三
 }
 
 // 合作采购单位 项目数量 前三
@@ -252,30 +256,23 @@ type Buyertop3Number struct {
 
 // 项目数量TOP30中标单位及其重点合作采购单位
 type WinnerCountTop3S struct {
-	Id        string            `json:"id"`        //中标企业id
-	Name      string            `json:"name"`      //中标企业名称
-	Number    int               `json:"number"`    //项目数量
-	Buyertop3 []Buyertop3Number `json:"buyertop3"` //合作采购单位 前三
-}
-
-// 中标规模分布
-type WinnerTimeDistributionS struct {
-	Key         string  `json:"key"`          //中标规模分布 key (金额分隔
-	TotalAmount float64 `json:"total_amount"` //总金额
-	TotalNumber float64 `json:"total_number"` //项目总数量
+	Id        string             `json:"id"`        //中标企业id
+	Name      string             `json:"name"`      //中标企业名称
+	Number    int                `json:"number"`    //项目数量
+	Buyertop3 []*Buyertop3Number `json:"buyertop3"` //合作采购单位 前三
 }
 
 type MarketBuyerAndWinner struct {
 	//采购金额TOP30采购单位及其重点合作中标单位
-	BuyerAmountTop3 []BuyerAmountTop3S `json:"buyer_amount_top3"`
+	BuyerAmountTop3 []*BuyerAmountTop3S `json:"buyer_amount_top3"`
 	//项目数量TOP30采购单位及其重点合作中标单位
-	BuyerCountTop3 []BuyerCountTop3S `json:"buyer_count_top3"`
+	BuyerCountTop3 []*BuyerCountTop3S `json:"buyer_count_top3"`
 	//采购规模分布
-	BuyerTimeDistribution []BuyerTimeDistributionS `json:"buyer_time_distribution"`
+	BuyerTimeDistribution []*BuyerAndWinnerTimeDistributionS `json:"buyer_time_distribution"`
 	//中标金额TOP30中标单位及其重点合作采购单位
-	WinnerAmountTop3 []WinnerAmountTop3S `json:"winner_amount_top3"`
+	WinnerAmountTop3 []*WinnerAmountTop3S `json:"winner_amount_top3"`
 	//项目数量TOP30中标单位及其重点合作采购单位
-	WinnerCountTop3 []WinnerCountTop3S `json:"winner_count_top3"`
+	WinnerCountTop3 []*WinnerCountTop3S `json:"winner_count_top3"`
 	//中标规模分布
-	WinnerTimeDistribution []WinnerTimeDistributionS `json:"winner_time_distribution"`
+	WinnerTimeDistribution []*BuyerAndWinnerTimeDistributionS `json:"winner_time_distribution"`
 }

+ 116 - 3
utility/userTask.go

@@ -2,8 +2,11 @@ package utility
 
 import (
 	"analyze/internal/model/entity"
+	"app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/encrypt"
 	"fmt"
 	"math"
+	"strings"
 	"time"
 )
 
@@ -140,13 +143,13 @@ func getYearRange(t time.Time, isStart bool) time.Time {
 // GetAllKeywordArr  获取所有匹配词
 func GetAllKeywordArr(res []entity.KeyWordGroup) (rData []entity.ViewKeyWord) {
 	for _, kwg := range res {
-		rData = append(rData, getGroupKeywordArr(kwg.A_Key)...)
+		rData = append(rData, GetGroupKeywordArr(kwg.A_Key)...)
 	}
 	return
 }
 
-// getGroupKeywordArr 模糊拆分为多个精准匹配
-func getGroupKeywordArr(res []entity.ViewKeyWord) (rData []entity.ViewKeyWord) {
+// GetGroupKeywordArr 模糊拆分为多个精准匹配
+func GetGroupKeywordArr(res []entity.ViewKeyWord) (rData []entity.ViewKeyWord) {
 	for _, kw := range res {
 		if kw.MatchWay == 1 {
 			for _, kk := range kw.Keyword {
@@ -174,3 +177,113 @@ func DateIsIn(from, to, n, m int64) bool {
 	}
 	return to > n && from < n
 }
+
+func EncodeId(sid string) string {
+	if sid == "" || sid == "-" { //不存在的id为-
+		return ""
+	}
+	return encrypt.EncodeArticleId2ByCheck(sid)
+}
+
+// 项目金额---TOP3地区的重点中标单位
+func GetWinnerInfoOfAmount(pt *entity.ProjectInfo) []*entity.WinnerAmount {
+	var winnerAmount []*entity.WinnerAmount
+	if pt.Winners != "" {
+		for k, w := range strings.Split(pt.Winners, ",") {
+			winnerAmount = append(winnerAmount, &entity.WinnerAmount{
+				Id:           common.If(len(pt.Entidlist) > k, encrypt.EncodeArticleId2ByCheck(pt.Entidlist[k]), "").(string),
+				Winner:       w,
+				WinnerAmount: pt.Sortprice,
+			})
+		}
+	}
+	return winnerAmount
+}
+
+// 项目数量---TOP3地区的重点中标单位
+func GetWinnerInfoOfCount(pt *entity.ProjectInfo) []*entity.WinnerTotal {
+	var winnerCount []*entity.WinnerTotal
+	if pt.Winners != "" {
+		for k, w := range strings.Split(pt.Winners, ",") {
+			winnerCount = append(winnerCount, &entity.WinnerTotal{
+				Id:          common.If(len(pt.Entidlist) > k, encrypt.EncodeArticleId2ByCheck(pt.Entidlist[k]), "").(string),
+				Winner:      w,
+				WinnerTotal: 1,
+			})
+		}
+	}
+	return winnerCount
+}
+
+// 细化市场重点中标单位-项目数量|金额
+func GetWinnerInfoTopList(pt *entity.ProjectInfo, value, total float64) []*entity.TopListS {
+	var winnerTotal []*entity.TopListS
+	if pt.Winners != "" {
+		for k, w := range strings.Split(pt.Winners, ",") {
+			winnerTotal = append(winnerTotal, &entity.TopListS{
+				Id:    common.If(len(pt.Entidlist) > k, encrypt.EncodeArticleId2ByCheck(pt.Entidlist[k]), "").(string),
+				Name:  w,
+				Value: value,
+				Prop:  Formula(value, total),
+			})
+		}
+	}
+	return winnerTotal
+}
+
+// 市场-采购单位&&中标企业---采购金额TOP30采购单位及其重点合作中标单位
+func GetWinnerInfoOfBuyerCount(pt *entity.ProjectInfo) []*entity.Winnertop3Number {
+	var winnertop3Number []*entity.Winnertop3Number
+	if pt.Winners != "" {
+		for k, w := range strings.Split(pt.Winners, ",") {
+			winnertop3Number = append(winnertop3Number, &entity.Winnertop3Number{
+				Id:     common.If(len(pt.Entidlist) > k, encrypt.EncodeArticleId2ByCheck(pt.Entidlist[k]), "").(string),
+				Name:   w,
+				Number: 1,
+			})
+		}
+	}
+	return winnertop3Number
+}
+
+// 市场-采购单位&&中标企业---采购金额TOP30采购单位及其重点合作中标单位
+func GetWinnerInfoOfBuyerAmount(pt *entity.ProjectInfo) []*entity.Winnertop3Amount {
+	var winnertop3Amount []*entity.Winnertop3Amount
+	if pt.Winners != "" {
+		for k, w := range strings.Split(pt.Winners, ",") {
+			winnertop3Amount = append(winnertop3Amount, &entity.Winnertop3Amount{
+				Id:     common.If(len(pt.Entidlist) > k, encrypt.EncodeArticleId2ByCheck(pt.Entidlist[k]), "").(string),
+				Name:   w,
+				Amount: pt.Sortprice,
+			})
+		}
+	}
+	return winnertop3Amount
+}
+
+// 市场-采购单位&&中标企业---采购金额TOP30采购单位及其重点合作中标单位
+func GetWinnerInfoOfWinnerCount(pt *entity.ProjectInfo) []*entity.Buyertop3Number {
+	var buyertop3Number []*entity.Buyertop3Number
+	if pt.Buyer != "" {
+		buyertop3Number = append(buyertop3Number, &entity.Buyertop3Number{
+			Name:   pt.Buyer,
+			Number: 1,
+		})
+	}
+	return buyertop3Number
+}
+
+// 市场-采购单位&&中标企业---采购金额TOP30采购单位及其重点合作中标单位
+func GetWinnerInfoOfWinnerAmount(pt *entity.ProjectInfo) []*entity.Buyertop3Amount {
+	var buyertop3Amount []*entity.Buyertop3Amount
+	if pt.Buyer != "" {
+		buyertop3Amount = append(buyertop3Amount, &entity.Buyertop3Amount{
+			Name:   pt.Buyer,
+			Amount: pt.Sortprice,
+		})
+	}
+	return buyertop3Amount
+}
+func GetJudgmentPrevKey(first int, next string) (key string) {
+	return fmt.Sprintf("%d-%s", first, next)
+}

+ 9 - 0
utility/utility.go

@@ -19,3 +19,12 @@ func Sequential(now, old float64) float64 {
 	}
 	return (now - old) / old
 }
+
+// 计算公式
+func Formula(current, total float64) (result float64) {
+	if total == 0 {
+		return 0
+	}
+	result = current / total
+	return
+}