瀏覽代碼

Merge branch 'dev4.6.2.15' of http://192.168.3.207:8080/qmx/jy into dev4.6.2.15

yangfeng 3 年之前
父節點
當前提交
b346d79621

+ 7 - 1
config_formal/big_member_1_172.17.145.180/config.json

@@ -64,5 +64,11 @@
     "mainWebDomain": "https://www.jianyu360.cn",
     "createPdfServer": "http://10.170.187.34:8081/api/to-pdf/%s?delay=300&dir=%s&url=https://www.jianyu360.cn/swordfish/frontPage/report/free/report?pid=%s",
     "pdfDataApiWhiteList": ["123.56.103.12","1.192.61.183","1.192.61.146"],
-    "pdfServerPoor" : 5
+    "pdfServerPoor" : 5,
+    "marketAnalysisPool": {
+	  "limit": 5,
+	  "timeOut": 20,
+	  "projectNumLimit": 600000
+	}
+
 }

+ 1 - 1
config_formal/big_member_1_172.17.145.180/time.txt

@@ -1,2 +1,2 @@
 #上次修改时间,比当前修改时间小就行
-2021-12-30 16:15:12
+2022-1-14 9:00:00

+ 7 - 1
config_formal/bigmember_172.17.145.180/config.json

@@ -64,5 +64,11 @@
     "mainWebDomain": "https://www.jianyu360.cn",
     "createPdfServer": "http://172.17.145.176:8079/api/to-pdf/%s?delay=300&dir=%s&url=https://www.jianyu360.cn/swordfish/frontPage/report/free/report?pid=%s",
     "pdfDataApiWhiteList": ["123.56.103.12","1.192.61.183","1.192.61.146","39.107.83.53"],
-    "pdfServerPoor" : 5
+    "pdfServerPoor" : 5,
+    "marketAnalysisPool": {
+	  "limit": 3,
+	  "timeOut": 20,
+          "projectNumLimit": 600000
+	}
+
 }

+ 5 - 0
config_formal/publicapply_172.17.148.50/bigmembermenu.json

@@ -91,6 +91,11 @@
 				"name":"月报",
 				"url":"/swordfish/page_big_pc/bigvip_subreport_month",
 				"isusable":false
+			},
+			{
+				   "name":"定制化分析报告",
+				   "url":"/swordfish/page_big_pc/desktop/report_analysis",
+				   "isusable":false
 			}
 		]
 	},

+ 8 - 0
config_formal/publicapply_172.17.148.50/commonfunctions.json

@@ -135,6 +135,14 @@
 				"img":"/commonFunctions/pc_subreport_week.png"
 			}
 		},
+		{
+			   "name":"定制化分析报告",
+			   "charge":true,
+			   "pc":{
+			      "url":"/swordfish/page_big_pc/desktop/report_analysis",
+			      "img":"/commonFunctions/analysis_report.png"
+			   }
+		},
 		{
 			"name":"月报",
 			"charge":true,

+ 1 - 1
config_formal/publicapply_172.17.148.50/time.txt

@@ -1,2 +1,2 @@
 #上次修改时间,比当前修改时间小就行
-2021-12-30 16:15:12
+2022-1-14 9:00:00

+ 14 - 0
src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/report_analysis.css

@@ -75,6 +75,9 @@
 }
 
 /* j-tag */
+.j-tag {
+  white-space: nowrap;
+}
 .j-tag.tag-orange {
   color: #FF9F3F;
   background-color: rgba(255, 159, 63, 0.1);
@@ -326,7 +329,15 @@
 .search-result .dimension .section-title {
   font-size: .28rem;
   line-height: .28rem;
+  padding: .32rem;
+  padding-bottom: 0;
+  text-align: center;
+}
+.search-result .dimension .section-tip-text {
+  padding-bottom: .32rem;
 }
+
+
 .search-result .dimension-list {
   display: flex;
   align-items: center;
@@ -449,6 +460,7 @@
   display: flex;
   align-items: center;
   justify-content: space-between;
+  width: 100%;
 }
 .project-top-item .p-t-i-hd-r .project-actions {
   display: flex;
@@ -473,6 +485,8 @@
   font-size: .28rem;
   color: #1D1D1D;
   line-height: .48rem;
+  max-width: 4rem;
+  flex: 1;
 }
 .project-top-item .p-t-i-hd-r .project-tags {
   display: flex;

+ 37 - 33
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/components/marketTimeScatter.js

@@ -27,21 +27,21 @@ var marketTimeScatter = {
         return {
           columns: ['日期', '项目规模', '环比增长率(%)'],
           rows: [
-            {
-              日期: '6月',
-              项目规模: 0,
-              '环比增长率(%)': -33
-            },
-            {
-              日期: '7月',
-              项目规模: 736325,
-              '环比增长率(%)': 0
-            },
-            {
-              日期: '8月',
-              项目规模: 73145,
-              '环比增长率(%)': 20
-            }
+            // {
+            //   日期: '6月',
+            //   项目规模: 0,
+            //   '环比增长率(%)': -33
+            // },
+            // {
+            //   日期: '7月',
+            //   项目规模: 736325,
+            //   '环比增长率(%)': 0
+            // },
+            // {
+            //   日期: '8月',
+            //   项目规模: 73145,
+            //   '环比增长率(%)': 20
+            // }
           ]
         }
       }
@@ -185,25 +185,29 @@ var marketTimeScatter = {
       options.xAxis[0].axisLabel.interval = 'auto'
 
       options.yAxis[1].axisLabel.show = true
-      // 设置时间轴
-      Object.assign(options, {
-        // grid解决dataZoom文字被隐藏的问题
-        // https://github.com/apache/echarts/issues/11601
-        grid: {
-          left: '5%',
-          right: '10%'
-        },
-        dataZoom: {
-          show: true, // 显示滚动条
-          realtime: true, // 拖动时,是否实时更新系列的视图
-          type: 'slider',
-          height: 20,
-          bottom: 0,
-          textStyle: {
-            fontSize: 10
+
+      if (this.chartData.rows.length > 8) {
+        // 设置时间轴
+        Object.assign(options, {
+          // grid解决dataZoom文字被隐藏的问题
+          // https://github.com/apache/echarts/issues/11601
+          grid: {
+            left: '5%',
+            right: '13%'
+          },
+          dataZoom: {
+            show: true, // 显示滚动条
+            realtime: true, // 拖动时,是否实时更新系列的视图
+            type: 'slider',
+            height: 20,
+            bottom: 0,
+            textStyle: {
+              fontSize: 10
+            }
           }
-        }
-      })
+        })
+      }
+
       options.legend.bottom = 30
       options.legend.data = [
         { icon: 'rect', name: this.chartData.columns[1] },

+ 1 - 1
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/components/marketTop3Table.js

@@ -15,7 +15,7 @@ var marketTop3TableTemplate = `
           }"></div>
         <div class="p-t-i-hd-r">
           <div class="p-t-i-hd-r-top">
-            <div class="project-name" v-text="item.name" :class="{ disabled: !item.id }" @click="toPortrait(item.id, item.type)"></div>
+            <div class="project-name ellipsis" v-text="item.name" :class="{ disabled: !item.id }" @click="toPortrait(item.id, item.type)"></div>
             <div class="project-actions" v-show="item.children.length" :class="{ 'icon-reverse': item.childrenShow }" @click="changeChildrenShow(item)">
               <div v-text="item.actionText"></div>
               <van-icon name="arrow-down"></van-icon>

+ 33 - 30
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/report_analysis.js

@@ -340,11 +340,16 @@ var vm = new Vue({
       return this.$dialog.confirm(defaultConf)
     },
     calcOffsetTop: function () {
+      var sticky = $('.van-sticky')
+      var stickyHeight = 0
+      if (sticky.length) {
+        stickyHeight = sticky[0].clientHeight
+      }
       this.dimensionList.forEach(function (item) {
         var anchor = $('.' + item.anchor)
         var offsetTop = 0
         if (anchor.length) {
-          offsetTop = parseInt(anchor.offset().top)
+          offsetTop = parseInt(anchor[0].offsetTop - stickyHeight)
         }
         item.top = offsetTop
       })
@@ -359,7 +364,7 @@ var vm = new Vue({
       // 2. 具体逻辑
       $scrollDOM.on('scroll', this.checkScrollTopButtonShow)
       setTimeout(function () {
-        // 5s后绑定(尽可能保证top能够被计算完)
+        // 2s后绑定(尽可能保证top能够被计算完)
         $scrollDOM.on('scroll', this.checkAnchorItemActive)
       }.bind(this), 2000)
 
@@ -370,13 +375,13 @@ var vm = new Vue({
     checkAnchorItemActive: function () {
       var $scrollDOM = $('.j-container.search-result > .j-main')
       var anchorTopList = this.anchorTopList
-      var scrollTop = $scrollDOM.scrollTop()
+      var scrollTop = parseInt($scrollDOM.scrollTop()) + 3 // (误差校正)
       var i = 0
-      if (scrollTop > anchorTopList[1] && scrollTop <= anchorTopList[2]) {
+      if (scrollTop >= anchorTopList[1] && scrollTop < anchorTopList[2]) {
         i = 1
-      } else if (scrollTop >= anchorTopList[2]) {
+      } else if (scrollTop > anchorTopList[2]) {
         i = 2
-      } else {
+      } else if (scrollTop < anchorTopList[1]) {
         i = 0
       }
       this.activeDimension = this.dimensionList[i].id
@@ -574,7 +579,7 @@ var vm = new Vue({
       var _this = this
       var dialog = this.filterDialogShow
       if (key === 'keys') {
-        if (this.notSetKey && this.isSubCount) {
+        if (this.notSetKey) {
           return this.setKeyTip()
         }
       } else if (key === 'area') {
@@ -1236,7 +1241,7 @@ var vm = new Vue({
       if (Array.isArray(scaleAreaCountTop3)) {
         scaleAreaCountTop3.forEach((item, index) => {
           item.name = item.name
-          item.subInfo1 = `项目数量:${item.area_count}个`
+          item.subInfo1 = item.area_count ? `项目数量:${item.area_count}个` : ''
           item.subInfo2 = item.area_scale ? `全国占比:${utils.formatMoney(item.area_scale * 100, undefined, true)}%` : ''
           item.actionText = `中标单位 TOP3`
           item.childrenShow = true
@@ -1261,7 +1266,7 @@ var vm = new Vue({
       if (Array.isArray(scaleAreaAmountTop3)) {
         scaleAreaAmountTop3.forEach((item, index) => {
           item.name = item.name
-          item.subInfo1 = `中标金额:${utils.formatMoney(item.area_amount / 10000, undefined, true)}万元`
+          item.subInfo1 = item.area_amount ? `中标金额:${utils.formatMoney(item.area_amount / 10000, undefined, true)}万元` : ''
           item.subInfo2 = item.area_scale ? `全国占比:${utils.formatMoney(item.area_scale * 100, undefined, true)}%` : ''
           item.actionText = `中标单位 TOP3`
           item.childrenShow = true
@@ -1303,7 +1308,7 @@ var vm = new Vue({
       if (Array.isArray(countTop3)) {
         countTop3.forEach((item, index) => {
           item.name = item.name
-          item.subInfo1 = `项目数量:${item.buyclass_count}个`
+          item.subInfo1 = item.buyclass_count ? `项目数量:${item.buyclass_count}个` : ''
           item.subInfo2 = item.buyclass_scale ? `全部占比:${utils.formatMoney(item.buyclass_scale * 100, undefined, true)}%` : ''
           item.actionText = `中标单位 TOP3`
           item.childrenShow = true
@@ -1329,7 +1334,7 @@ var vm = new Vue({
       if (Array.isArray(amountTop3)) {
         amountTop3.forEach((item, index) => {
           item.name = item.name
-          item.subInfo1 = `项目金额:${utils.formatMoney(item.buyclass_amount / 10000, undefined, true)}万元`
+          item.subInfo1 = item.buyclass_amount ? `项目金额:${utils.formatMoney(item.buyclass_amount / 10000, undefined, true)}万元` : ''
           item.subInfo2 = item.buyclass_scale ? `全部占比:${utils.formatMoney(item.buyclass_scale * 100, undefined, true)}%` : 0
           item.actionText = `中标单位 TOP3`
           item.childrenShow = true
@@ -1404,11 +1409,11 @@ var vm = new Vue({
     },
     sortRefineTop3 (data) {
       const tableDataCount = {
-        columns: ['序号', '细分市场:项目数量(个),占比', '前3中标单位:中标数量(个)'], // ,该细分市场占比
+        columns: ['序号', '细分市场:项目数量(个)', '前3中标单位:中标数量(个)'], // ,占比,该细分市场占比
         rows: []
       }
       const tableDataAmount = {
-        columns: ['序号', '细分市场:项目金额(万元),占比', '前3中标单位:中标金额(万元)'], // ,该细分市场占比
+        columns: ['序号', '细分市场:项目金额(万元)', '前3中标单位:中标金额(万元)'], // ,占比,该细分市场占比
         rows: []
       }
 
@@ -1416,13 +1421,13 @@ var vm = new Vue({
       if (Array.isArray(countTop3)) {
         countTop3.forEach((item, index) => {
           item.name = item.name
-          item.subInfo1 = `项目数量:${item.total}个`
-          item.subInfo2 = item.prop ? `全部占比:${utils.formatMoney(item.prop * 100, undefined, true)}%` : 0
+          item.subInfo1 = item.value ? `项目数量:${item.value}个` : ''
+          // item.subInfo2 = item.prop ? `全部占比:${utils.formatMoney(item.prop * 100, undefined, true)}%` : 0
           item.actionText = `中标单位 TOP3`
           item.childrenShow = true
           item.children = []
-          if (Array.isArray(item.totalTop)) {
-            item.totalTop.forEach((w, i) => {
+          if (Array.isArray(item.topList)) {
+            item.topList.forEach((w, i) => {
               const row = {
                 name: w.name,
                 id: w.id,
@@ -1441,13 +1446,13 @@ var vm = new Vue({
       if (Array.isArray(amountTop3)) {
         amountTop3.forEach((item, index) => {
           item.name = item.name
-          item.subInfo1 = `项目金额:${utils.formatMoney(item.amount / 10000, undefined, true)}万元`
-          item.subInfo2 = item.prop ? `全部占比:${utils.formatMoney(item.prop * 100, undefined, true)}%` : 0
+          item.subInfo1 = item.value ? `项目金额:${utils.formatMoney(item.value / 10000, undefined, true)}万元` : ''
+          // item.subInfo2 = item.prop ? `全部占比:${utils.formatMoney(item.prop * 100, undefined, true)}%` : 0
           item.actionText = `中标单位 TOP3`
           item.childrenShow = true
           item.children = []
-          if (Array.isArray(item.amountTop)) {
-            item.amountTop.forEach((w, i) => {
+          if (Array.isArray(item.topList)) {
+            item.topList.forEach((w, i) => {
               const row = {
                 name: w.name,
                 id: w.id,
@@ -1523,7 +1528,7 @@ var vm = new Vue({
           item.name = item.name
           item.type = 'buyer'
           item.id = item.name
-          item.subInfo1 = `项目数量:${item.number}个`
+          item.subInfo1 = item.number ? `项目数量:${item.number}个` : ''
           // item.subInfo2 = item.accounted ? `全部占比:${utils.formatMoney(item.accounted * 100, undefined, true)}%` : ''
           item.actionText = `中标单位 TOP3`
           item.childrenShow = true
@@ -1550,7 +1555,7 @@ var vm = new Vue({
           item.name = item.name
           item.type = 'buyer'
           item.id = item.name
-          item.subInfo1 = `采购金额:${utils.formatMoney(item.amount / 10000, undefined, true)}万元`
+          item.subInfo1 = item.amount ? `采购金额:${utils.formatMoney(item.amount / 10000, undefined, true)}万元` : ''
           // item.subInfo2 = item.accounted ? `全部占比:${utils.formatMoney(item.accounted * 100, undefined, true)}%` : ''
           item.actionText = `中标单位 TOP3`
           item.childrenShow = true
@@ -1631,7 +1636,7 @@ var vm = new Vue({
           item.name = item.name
           item.type = 'winner'
           item.id = item.id
-          item.subInfo1 = `中标数量:${item.number}个`
+          item.subInfo1 = item.number ? `中标数量:${item.number}个` : ''
           // item.subInfo2 = item.accounted ? `全部占比:${utils.formatMoney(item.accounted * 100, undefined, true)}%` : ''
           item.actionText = `采购单位 TOP3`
           item.childrenShow = true
@@ -1658,7 +1663,7 @@ var vm = new Vue({
           item.name = item.name
           item.type = 'winner'
           item.id = item.id
-          item.subInfo1 = `中标金额:${utils.formatMoney(item.amount / 10000, undefined, true)}万元`
+          item.subInfo1 = item.amount ? `中标金额:${utils.formatMoney(item.amount / 10000, undefined, true)}万元` : ''
           // item.subInfo2 = item.accounted ? `全部占比:${utils.formatMoney(item.accounted * 100, undefined, true)}%` : ''
           item.actionText = `采购单位 TOP3`
           item.childrenShow = true
@@ -1706,12 +1711,10 @@ var vm = new Vue({
     anchorTo (item) {
       if (!item.top) return
       var offsetTop = item.top || 0
-      var headerHeight = $('.jy-app-header')[0].clientHeight
-      var tabHeight = $('#analysis .van-tabs')[0].clientHeight
-      var stickyHeight = $('.dimension-list')[0].clientHeight
-      var sTop = offsetTop - headerHeight - tabHeight - stickyHeight
       this.activeDimension = item.id
-      $('.search-result > .j-main').animate({ scrollTop: sTop })
+      this.$nextTick(function () {
+        $('.search-result > .j-main')[0].scrollTop = offsetTop
+      })
     },
     showSetKeyTip: function () {
       this.notSetKey = true

+ 4 - 4
src/jfw/modules/app/src/web/templates/big-member/page_report_analysis.html

@@ -78,7 +78,7 @@
                             <van-cell center title="分析条件" is-link @click="filtersPageShow = true; rid = ''"></van-cell>
                         </van-cell-group>
                         <div class="height8" v-show="false"></div>
-                        <section class="section bg-white pd-16 dimension">
+                        <section class="section bg-white dimension">
                             <div class="section-title"> - 分析维度 -</div>
                             <van-sticky class="section-sticky" z-index="99999999" :offset-top="stickyOffset">
                                 <div class="section-content dimension-list bg-white">
@@ -98,7 +98,7 @@
                             </div>
                         </section>
                         <!-- 市场概况 -->
-                        <section class="section bg-white market-overview">
+                        <section class="section bg-white market-overview" id="market">
                             <div class="section-title pd-16">市场概况</div>
                             <div class="section-content market-overview-list">
                                 <div
@@ -265,7 +265,7 @@
                             </div>
                         </div>
                         <!-- 采购规模分布 -->
-                        <div class="section bg-white pd-16 buyerclass-scatter" v-if="sections.buyerclass.dataAlready">
+                        <div class="section bg-white pd-16 buyerclass-scatter" id="buyer" v-if="sections.buyerclass.dataAlready">
                             <div class="section-title">采购规模分布</div>
                             <div class="section-content">
                                 <line-chart-scatter :chart-data="sections.buyerclass.chartData"></line-chart-scatter>
@@ -284,7 +284,7 @@
                             </div>
                         </div>
                         <!-- 采购规模分布 -->
-                        <div class="section bg-white pd-16 winner-scatter" v-if="sections.winner.dataAlready">
+                        <div class="section bg-white pd-16 winner-scatter" id="winner" v-if="sections.winner.dataAlready">
                             <div class="section-title">中标规模分布</div>
                             <div class="section-content">
                                 <line-chart-scatter :chart-data="sections.winner.chartData"></line-chart-scatter>

+ 43 - 32
src/jfw/modules/bigmember/src/entity/marketAnalysis/customizad_distribution.go

@@ -32,7 +32,7 @@ const (
 
 	//中标单位
 	//winner_procurement_scale = `"winner_count":{"filter": {"range": {"sortprice": {"gt": 0}}},"aggs": {"cardinality_winner_count": {"cardinality": {"field": "s_winner"}}}},"winner_time_distribution": {"range": { "field": "sortprice","ranges": [%s]},"aggs":{"s_winner_count": {"cardinality": {"field": "s_winner"}}}},"winner_amount_distribution": {"terms": {"field": "s_winner","size": 0},"aggs": {"amount": {"sum": {"field": "sortprice"}}}}`
-	winner_procurement_scale = `"winner_amount_distribution": {"terms": {"field": "s_winner","size": 0},"aggs": {"amount": {"sum": {"field": "sortprice"}}}}`
+	winner_procurement_scale = `"winner_amount_distribution": {"terms": {"field": "entidlist","size": 0},"aggs": {"amount": {"sum": {"field": "sortprice"}}}}`
 
 	//中标单位top3(价格)
 	winner_sortprice = `"winner_amount_top3": {"terms": {"field": "entidlist","exclude":["-"],"order": [{"s_winner_amount": "desc"}],"size": 3},"aggs": {"s_winner_amount": {"sum": {"field": "sortprice"}},"buyer_top": {"terms": {"field": "buyer","order": [{"buyer_winner_amount": "desc"}],"size": 3},"aggs": {"buyer_winner_amount": {"sum": {"field": "sortprice"}}}}}}`
@@ -386,62 +386,51 @@ func (mae *MarketAnalysisEntity) TimeData(_b bool, thisRow []Buckets) map[string
 }
 
 func amountDistribution(v float64, data map[string]*distributionTrend) {
+	if v <= 0 {
+		return
+	}
 	if v < 100000 {
 		if data["<10万"] == nil {
 			data["<10万"] = new(distributionTrend)
 		}
 		data["<10万"].Amount += v
-		if v != 0 {
-			data["<10万"].Count++
-		}
-	} else if v <= 500000 {
+		data["<10万"].Count++
+	} else if v < 500000 {
 		if data["10万-50万"] == nil {
 			data["10万-50万"] = new(distributionTrend)
 		}
 		data["10万-50万"].Amount += v
-		if v != 0 {
-			data["10万-50万"].Count++
-		}
-	} else if v <= 1000000 {
+		data["10万-50万"].Count++
+	} else if v < 1000000 {
 		if data["50万-100万"] == nil {
 			data["50万-100万"] = new(distributionTrend)
 		}
 		data["50万-100万"].Amount += v
-		if v != 0 {
-			data["50万-100万"].Count++
-		}
-	} else if v <= 1000000*5 {
+		data["50万-100万"].Count++
+	} else if v < 1000000*5 {
 		if data["100万-500万"] == nil {
 			data["100万-500万"] = new(distributionTrend)
 		}
 		data["100万-500万"].Amount += v
-		if v != 0 {
-			data["100万-500万"].Count++
-		}
-	} else if v <= 1000000*10 {
+		data["100万-500万"].Count++
+	} else if v < 1000000*10 {
 		if data["500万-1000万"] == nil {
 			data["500万-1000万"] = new(distributionTrend)
 		}
 		data["500万-1000万"].Amount += v
-		if v != 0 {
-			data["500万-1000万"].Count++
-		}
-	} else if v <= 100000000 {
+		data["500万-1000万"].Count++
+	} else if v < 100000000 {
 		if data["1000万-1亿"] == nil {
 			data["1000万-1亿"] = new(distributionTrend)
 		}
 		data["1000万-1亿"].Amount += v
-		if v != 0 {
-			data["1000万-1亿"].Count++
-		}
-	} else if v > 100000000 {
+		data["1000万-1亿"].Count++
+	} else if v >= 100000000 {
 		if data["≥1亿"] == nil {
 			data["≥1亿"] = new(distributionTrend)
 		}
 		data["≥1亿"].Amount += v
-		if v != 0 {
-			data["≥1亿"].Count++
-		}
+		data["≥1亿"].Count++
 	}
 
 }
@@ -683,6 +672,7 @@ func BuyerAnalysis(thisBuyerRow BuyerWinnerRow, rMap map[string]interface{}) {
 	for _, v := range buyerA {
 		count_b = count_b + v.Count
 	}
+
 	for _, v := range Analysis {
 		var data buyer
 		data.Name = v
@@ -707,6 +697,19 @@ func BuyerAnalysis(thisBuyerRow BuyerWinnerRow, rMap map[string]interface{}) {
 		Number int64       `json:"number"`
 		//Accounted interface{} `json:"accounted"`
 	}
+	var winnerKeys []string
+	for _, v := range thisBuyerRow.BuyerCountTop3.Buckets {
+		for _, v1 := range v.SWinnerTop.Buckets {
+			winnerKeys = append(winnerKeys, v1.Key)
+		}
+	}
+	for _, v := range thisBuyerRow.BuyerAmountTop3.Buckets {
+		for _, v1 := range v.SWinnerTop.Buckets {
+			winnerKeys = append(winnerKeys, v1.Key)
+		}
+	}
+
+	winnerName := GetEntNameByIds(winnerKeys)
 	//采购单位-项目数量TOP3
 	countMap := []interface{}{}
 	for _, v := range thisBuyerRow.BuyerCountTop3.Buckets {
@@ -720,7 +723,7 @@ func BuyerAnalysis(thisBuyerRow BuyerWinnerRow, rMap map[string]interface{}) {
 		for _, v1 := range v.SWinnerTop.Buckets {
 			var _dd number_project
 			_dd.Number = v1.BuyerWinnerAmount.Value
-			_dd.Name = IdToWinner(v1.Key)
+			_dd.Name = winnerName[v1.Key]
 			_dd.Id = util.EncodeId(v1.Key)
 
 			/*if _d.Number != 0 {
@@ -764,7 +767,7 @@ func BuyerAnalysis(thisBuyerRow BuyerWinnerRow, rMap map[string]interface{}) {
 			}
 			var _dd amount_project
 			_dd.Amount = v1.BuyerWinnerAmount.Value
-			_dd.Name = IdToWinner(v1.Key)
+			_dd.Name = winnerName[v1.Key]
 			_dd.Id = util.EncodeId(v1.Key)
 			/*	if _d.Amount != 0 {
 				_dd.Accounted = v1.BuyerWinnerAmount.Value / _d.Amount
@@ -821,13 +824,21 @@ func WinningAnalysis(thisWinnerRow BuyerWinnerRow, rMap map[string]interface{})
 		Number int64  `json:"number"`
 		//Accounted interface{} `json:"accounted"`
 	}
+	var winnerKeys []string
+	for _, v := range thisWinnerRow.WinnerCountTop3.SWinnerCount {
+		winnerKeys = append(winnerKeys, v.Key)
+	}
+	for _, v := range thisWinnerRow.WinnerAmountTop3.SWinnerAmount {
+		winnerKeys = append(winnerKeys, v.Key)
+	}
 
+	winnerName := GetEntNameByIds(winnerKeys)
 	//中标单位-项目数量TOP3
 	countMap := []interface{}{}
 	for _, v := range thisWinnerRow.WinnerCountTop3.SWinnerCount {
 		var _d number_projects
 		_d.Number = v.BuyerCount.Value
-		_d.Name = IdToWinner(v.Key)
+		_d.Name = winnerName[v.Key]
 		_d.Id = util.EncodeId(v.Key)
 		/*if thisWinnerRow.ProjectCount.Value != 0 {
 			_d.Accounted = float64(v.BuyerCount.Value) / float64(thisWinnerRow.ProjectCount.Value)
@@ -867,7 +878,7 @@ func WinningAnalysis(thisWinnerRow BuyerWinnerRow, rMap map[string]interface{})
 		}
 		var _d amount_projects
 		_d.Amount = v.SWinnerAmount.Value
-		_d.Name = IdToWinner(v.Key)
+		_d.Name = winnerName[v.Key]
 		_d.Id = util.EncodeId(v.Key)
 		/*if thisWinnerRow.ProjectAmount.Value != 0 {
 			_d.Accounted = v.SWinnerAmount.Value / thisWinnerRow.ProjectAmount.Value

+ 10 - 3
src/jfw/modules/bigmember/src/entity/marketAnalysis/customized_analysis.go

@@ -19,13 +19,16 @@ const (
 	aggs_buyerclass_counttop3  = `"buyerclass_count_top3":{"terms":{"field":"buyerclass","exclude":["其它",""],"order":[{"buyerclass_count":"desc"}],"size":3},"aggs":{"buyerclass_count":{"filter":{}},"bidcount_top":{"terms":{"field":"entidlist","exclude": ["-"],"order":[{"buyer_winner_count":"desc"}],"size":3},"aggs":{"buyer_winner_count":{"filter":{}}}}}}`
 	aggs_buyerclass_amounttop3 = `"buyerclass_amount_top3":{"terms":{"field":"buyerclass","exclude":["其它",""],"order":[{"buyerclass_amount":"desc"}],"size":3},"aggs":{"buyerclass_amount":{"sum":{"field":"sortprice"}},"winner_top":{"terms":{"field":"entidlist","exclude": ["-"],"order":[{"buyer_winner_amount":"desc"}],"size":3},"aggs":{"buyer_winner_amount":{"sum":{"field":"sortprice"}}}}}}`
 	sortprice_str              = `{"key":"<10万","from":0.0000000000001,"to":100000},{"key":"10万-50万","from":100000,"to":500000},{"key":"50万-100万","from":500000,"to":1000000},{"key":"100万-500万","from":1000000,"to":5000000},{"key":"500万-1000万","from":5000000,"to":10000000},{"key":"1000万-1亿","from":10000000,"to":100000000},{"key":"≥1亿","from":100000000}`
-	aggs_all_c_m               = `"project_count": {"filter": {}},"project_amount": {"sum": {"field": "sortprice"}}`
+	aggs_all_c_m               = `"project_count": {"filter": {}},"project_count_not0": {"filter": {"range": {"sortprice": {"gt": 0}}}},"project_amount": {"sum": {"field": "sortprice"}}`
 	query_id                   = `{"query": {"bool": {"must": [{"term": {"entidlist": "%s"}}]}},"size": 1}`
 	query_idto                 = `{"query": {"bool": {"must": [{"terms": {"qyxy.id": [%s]}}],"should": []}},"from": 0,"size": 36}`
 )
 
 type AreaCTop struct {
-	Total  int64 `json:"doc_count"`
+	Total     int64 `json:"doc_count"`
+	CountNot0 struct {
+		Count int64 `json:"doc_count"`
+	} `json:"project_count_not0"`
 	Amount struct {
 		Value float64 `json:"value"`
 	} `json:"project_amount"`
@@ -242,6 +245,10 @@ func (mae *MarketAnalysisEntity) AllData() (rMap map[string]interface{}, err err
 			if json.Unmarshal(bArr, &thisRow) != nil {
 				continue
 			}
+		} else if name == "project_count_not0" {
+			if json.Unmarshal(bArr, &thisRow.CountNot0) != nil {
+				continue
+			}
 		} else if name == "sortprice_ranges" {
 			if json.Unmarshal(bArr, &thisRow.SortpriceRanges) != nil {
 				continue
@@ -288,7 +295,7 @@ func (mae *MarketAnalysisEntity) AllData() (rMap map[string]interface{}, err err
 //项目规模分布
 func ProjectScale(thisRow AreaCTop) (data []interface{}) {
 	ammount := thisRow.Amount.Value
-	total := thisRow.Total
+	total := thisRow.CountNot0.Count
 	buckets := thisRow.SortpriceRanges.Buckets
 	type Scale struct {
 		Name      string

+ 20 - 0
src/jfw/modules/bigmember/src/entity/marketAnalysis/marketAnalysisEntity.go

@@ -8,6 +8,7 @@ import (
 	"log"
 	"mongodb"
 	qutil "qfw/util"
+	"qfw/util/elastic"
 	"qfw/util/redis"
 	"strings"
 	"time"
@@ -300,3 +301,22 @@ func (mae *MarketAnalysisEntity) GetPartResult(flag int) (map[string]interface{}
 	}
 	return rData, err
 }
+
+func GetEntNameByIds(ids []string) (returnMap map[string]string) {
+	returnMap = map[string]string{}
+	if len(ids) == 0 {
+		return
+	}
+	list := elastic.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
+}

+ 92 - 85
src/jfw/modules/bigmember/src/entity/marketAnalysis/scaleRefineQuery.go

@@ -19,9 +19,14 @@ const (
 )
 
 type scaleRefineData struct {
-	Data   []*scaleRefineRow
-	Total  simpleTotal
-	Amount simpleSum
+	Data       []*scaleRefineRow
+	Total      simpleTotal
+	Amount     simpleSum
+	IdSwitch   map[string]string
+	ReturnData struct {
+		Overall             []map[string]interface{}
+		TotalTop, AmountTop []*returnItem
+	}
 }
 
 type simpleTotal struct {
@@ -39,18 +44,16 @@ type scaleRefineRow struct {
 	AmountProp     float64   `json:"amount_prop"`
 	WinnerTotalTop struct {
 		Buckets []*struct {
-			EntId   string       `json:"key"`
-			TopMsg  topMsgStruct `json:"topMsg"`
-			EntName string       `json:"entName"`
-			Total   int64        `json:"doc_count"`
-			Prop    float64      `json:"prop"`
+			EntId   string  `json:"key"`
+			EntName string  `json:"entName"`
+			Total   int64   `json:"doc_count"`
+			Prop    float64 `json:"prop"`
 		} `json:"buckets"`
 	} `json:"winner_total_top"`
 	WinnerAmountTop struct {
 		Buckets []*struct {
-			EntId   string       `json:"key"`
-			EntName string       `json:"entName"`
-			TopMsg  topMsgStruct `json:"topMsg"`
+			EntId   string `json:"key"`
+			EntName string `json:"entName"`
 			Amount  struct {
 				Value float64 `json:"value"`
 			} `json:"refine_winner_amount"`
@@ -61,43 +64,18 @@ type scaleRefineRow struct {
 	UpdateTime int64  `json:"updateTime"`
 }
 
-type topMsgStruct struct {
-	Hits struct {
-		Total    int     `json:"total"`
-		MaxScore float64 `json:"max_score"`
-		Hits     []struct {
-			Source struct {
-				EntIdList  []string `json:"entidlist"`
-				WinnerName string   `json:"s_winner"`
-			} `json:"_source"`
-		} `json:"hits"`
-	} `json:"hits"`
+type returnItem struct {
+	Name    string      `json:"name"`
+	Value   interface{} `json:"value"`
+	Prop    interface{} `json:"prop"`
+	TopList []*entValue `json:"topList"`
 }
 
-//getReallyName 根据企业id或企业名称
-func (tms topMsgStruct) getReallyName(entId string) string {
-	for _, rs := range tms.Hits.Hits {
-		//仅只有一个中标企业
-		if len(rs.Source.EntIdList) == 1 {
-			if rs.Source.EntIdList[0] == entId {
-				return rs.Source.WinnerName
-			}
-		} else { //多个中标企业,根据顺序返回对应名称
-			flag := -1
-			for index, tId := range rs.Source.EntIdList {
-				if tId == entId {
-					flag = index
-					break
-				}
-			}
-			if flag > -1 {
-				if names := strings.Split(rs.Source.WinnerName, ","); len(names)-1 >= flag {
-					return names[flag]
-				}
-			}
-		}
-	}
-	return ""
+type entValue struct {
+	Id    string      `json:"id"`
+	Name  string      `json:"name"`
+	Value interface{} `json:"value"`
+	Prop  interface{} `json:"prop"`
 }
 
 //marketScaleRefineQuery 细化聚合
@@ -116,18 +94,18 @@ func (mae *MarketAnalysisEntity) marketScaleRefineQuery() (rMap map[string]inter
 			}
 		}
 		if len(bools) > 0 {
-			aggsGroup = append(aggsGroup, fmt.Sprintf(`"%s":{"filter":{"query":{"bool":{"should":[%s],"minimum_should_match": 1}}},"aggs":{"project_count":{"filter":{}},"project_amount":{"sum":{"field":"sortprice"}},"winner_total_top":{"terms":{"field":"entidlist","order":[{"refine_winner_total":"desc"}],"size":%d},"aggs":{"refine_winner_total":{"filter":{}},"topMsg":{"top_hits":{"_source":{"includes":["entidlist","s_winner"]},"size":1}}}},"winner_amount_top":{"terms":{"field":"entidlist","order":[{"refine_winner_amount":"desc"}],"size":%d},"aggs":{"refine_winner_amount":{"sum":{"field":"sortprice"}},"topMsg":{"top_hits":{"_source":{"includes":["entidlist","s_winner"]},"size":1}}}}}}`, group.ItemName, strings.Join(bools, ","), topWinnerLimit, topWinnerLimit))
+			aggsGroup = append(aggsGroup, fmt.Sprintf(`"%s":{"filter":{"query":{"bool":{"should":[%s],"minimum_should_match": 1}}},"aggs":{"project_count":{"filter":{}},"project_amount":{"sum":{"field":"sortprice"}},"winner_total_top":{"terms":{"field":"entidlist","exclude":["-"],"order":[{"refine_winner_total":"desc"}],"size":%d},"aggs":{"refine_winner_total":{"filter":{}}}},"winner_amount_top":{"terms":{"field":"entidlist","exclude":["-"],"order":[{"refine_winner_amount":"desc"}],"size":%d},"aggs":{"refine_winner_amount":{"sum":{"field":"sortprice"}}}}}}`, group.ItemName, strings.Join(bools, ","), topWinnerLimit, topWinnerLimit))
 		}
 		itemDataMap[group.ItemName] = group.UpdateTime
 	}
 	finalSql := fmt.Sprintf(mae.GetCommonQuerySqlWithAggs(), strings.Join(aggsGroup, ","))
-	//log.Println("finalSql", finalSql)
+	//fmt.Println("finalSql-----4", finalSql)
 	rMap = map[string]interface{}{}
 	res, _ := util.GetAggs("projectset", "projectset", finalSql)
 	if res == nil || len(res) == 0 {
 		return
 	}
-	scale := scaleRefineData{}
+	scale := scaleRefineData{IdSwitch: map[string]string{}}
 	for name, object := range res {
 		bArr, err := object.MarshalJSON()
 		if len(bArr) == 0 || err != nil {
@@ -154,13 +132,37 @@ func (mae *MarketAnalysisEntity) marketScaleRefineQuery() (rMap map[string]inter
 		thisRow.UpdateTime = itemDataMap[name]
 		scale.Data = append(scale.Data, &thisRow)
 	}
-	//计算占比
-	scale.formatData()
+	scale.formatData() //获取所需数据
+	scale.doIdSwitch() //补充企业名称
+	return map[string]interface{}{
+		"scaleRefineAll":       scale.ReturnData.Overall,
+		"scaleRefineTotalTop":  scale.ReturnData.TotalTop,
+		"scaleRefineAmountTop": scale.ReturnData.AmountTop,
+	}, nil
+}
 
-	rMap["scaleRefineAll"] = scale.sortBy(totalAndAmount).getFormatTop(-1, totalAndAmount)
-	rMap["scaleRefineTotalTop"] = scale.sortBy(onlyTotal).getFormatTop(topItemLimit, onlyTotal)
-	rMap["scaleRefineAmountTop"] = scale.sortBy(onlyAmount).getFormatTop(topItemLimit, onlyAmount)
-	return
+//doIdSwitch 补充企业名称
+func (srd *scaleRefineData) doIdSwitch() {
+	if len(srd.IdSwitch) == 0 {
+		return
+	}
+	var ids []string
+	for id, _ := range srd.IdSwitch {
+		ids = append(ids, id)
+	}
+	srd.IdSwitch = GetEntNameByIds(ids)
+	for _, v := range srd.ReturnData.TotalTop {
+		for _, vv := range v.TopList {
+			vv.Name, _ = srd.IdSwitch[vv.Id]
+			vv.Id = util.EncodeId(vv.Id)
+		}
+	}
+	for _, v := range srd.ReturnData.AmountTop {
+		for _, vv := range v.TopList {
+			vv.Name, _ = srd.IdSwitch[vv.Id]
+			vv.Id = util.EncodeId(vv.Id)
+		}
+	}
 }
 
 //formatData 计算百分比&获取企业对应名称
@@ -171,62 +173,67 @@ func (srd *scaleRefineData) formatData() {
 
 		for _, vv := range v.WinnerTotalTop.Buckets {
 			vv.Prop = float64(vv.Total) / float64(v.Total)
-			vv.EntName = vv.TopMsg.getReallyName(vv.EntId)
 		}
 		for _, vv := range v.WinnerAmountTop.Buckets {
 			vv.Prop = vv.Amount.Value / v.Amount.Value
-			vv.EntName = vv.TopMsg.getReallyName(vv.EntId)
 		}
 	}
+	srd.ReturnData.Overall = srd.sortBy(totalAndAmount).getOverallData()
+	srd.ReturnData.AmountTop = srd.sortBy(onlyAmount).getFormatTop(topItemLimit, onlyAmount)
+	srd.ReturnData.TotalTop = srd.sortBy(onlyTotal).getFormatTop(topItemLimit, onlyTotal)
+}
+
+//getOverallData 获取分类总览数据
+func (srd *scaleRefineData) getOverallData() (rData []map[string]interface{}) {
+	for _, Value := range srd.Data {
+		rData = append(rData, map[string]interface{}{
+			"name":   Value.ItemName,
+			"total":  Value.Total,
+			"amount": Value.Amount.Value,
+		})
+	}
+	return
 }
 
 //getArrayFormatTop 获取前n个数据,并格式化
 //limit 获取前x条
-//flag 1仅返回数量统计 2仅返回金额统计 3返回数量和金额统计,但不返回各项Top数据
-func (srd *scaleRefineData) getFormatTop(limit, flag int) (rData []map[string]interface{}) {
+//flag 1仅返回数量统计 2仅返回金额统计
+func (srd *scaleRefineData) getFormatTop(limit, flag int) (rData []*returnItem) {
 	for index, Value := range srd.Data {
 		if index >= limit && limit > -1 {
 			return
 		}
-		thisRow := map[string]interface{}{
-			"name": Value.ItemName,
+		thisRow := &returnItem{
+			Name: Value.ItemName,
 		}
 		if flag == 1 || flag == 3 { //返回数量相关数据
-			thisRow["total"] = Value.Total
+			thisRow.Value = Value.Total
 			if flag != 3 {
-				topArr := []map[string]interface{}{}
 				for _, v := range Value.WinnerTotalTop.Buckets {
-					if len(v.EntId) <= 1 || len(v.EntName) <= 1 { //数据库过滤id为-,及未关联到企业名称的数据
-						continue
-					}
-					topArr = append(topArr, map[string]interface{}{
-						"id":    util.EncodeId(v.EntId),
-						"name":  v.EntName,
-						"value": v.Total,
-						"prop":  v.Prop,
+					thisRow.TopList = append(thisRow.TopList, &entValue{
+						Id:    v.EntId,
+						Name:  v.EntName,
+						Value: v.Total,
+						Prop:  v.Prop,
 					})
+					srd.IdSwitch[v.EntId] = ""
 				}
-				thisRow["prop"] = Value.TotalProp
-				thisRow["totalTop"] = topArr
+				thisRow.Prop = Value.TotalProp
 			}
 		}
 		if flag == 2 || flag == 3 { //返回金额相关数据
-			thisRow["amount"] = Value.Amount.Value
+			thisRow.Value = Value.Amount.Value
 			if flag != 3 {
-				topArr := []map[string]interface{}{}
 				for _, v := range Value.WinnerAmountTop.Buckets {
-					if len(v.EntId) <= 1 || len(v.EntName) <= 1 { //数据库过滤id为-,及未关联到企业名称的数据
-						continue
-					}
-					topArr = append(topArr, map[string]interface{}{
-						"id":    util.EncodeId(v.EntId),
-						"name":  v.EntName,
-						"value": v.Amount.Value,
-						"prop":  v.Prop,
+					thisRow.TopList = append(thisRow.TopList, &entValue{
+						Id:    v.EntId,
+						Name:  v.EntName,
+						Value: v.Amount.Value,
+						Prop:  v.Prop,
 					})
+					srd.IdSwitch[v.EntId] = ""
 				}
-				thisRow["prop"] = Value.AmountProp
-				thisRow["amountTop"] = topArr
+				thisRow.Prop = Value.TotalProp
 			}
 		}
 		rData = append(rData, thisRow)