Ver código fonte

Merge branch 'feature/v4.8.31' of https://jygit.jydev.jianyu360.cn/qmx/jy into dev/4.8.31_wmh

wenmenghao321 2 anos atrás
pai
commit
18f86fbe0a
89 arquivos alterados com 5424 adições e 1245 exclusões
  1. 3 0
      .vscode/settings.json
  2. 1 1
      config_formal/publicapply_172.17.148.50/bigmembermenu.json
  3. 1 1
      config_formal/publicapply_172.17.148.50/commonfunctions.json
  4. 1 1
      config_formal/publicapply_172.17.4.183/bigmembermenu.json
  5. 1 1
      config_formal/publicapply_172.17.4.183/commonfunctions.json
  6. 1 1
      src/jfw/front/classificationTag.go
  7. 2 2
      src/jfw/front/pcIndex.go
  8. 47 0
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/report_detail_month.css
  9. BIN
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/image/icon-infor-blue.png
  10. BIN
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/image/landpage_new/itemB_04.jpg
  11. BIN
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/image/landpage_new/itemB_04.png
  12. 2 1
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/chart_options.js
  13. 1 0
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/ent_portrait.js
  14. 1 1
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/main_root_data.js
  15. 22 2
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/report_analysis.js
  16. 1 1
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/report_analysis_history.js
  17. 295 37
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/report_detail_month.js
  18. 326 18
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/report_detail_week.js
  19. 1 0
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/unit_portrayal.js
  20. 0 0
      src/jfw/modules/app/src/web/templates/big-member/page_contrast.html
  21. 1 1
      src/jfw/modules/app/src/web/templates/big-member/page_landingPage.html
  22. 104 21
      src/jfw/modules/app/src/web/templates/big-member/page_report_analysis.html
  23. 1 1
      src/jfw/modules/app/src/web/templates/big-member/page_report_analysis_history.html
  24. 59 0
      src/jfw/modules/app/src/web/templates/big-member/page_report_analysis_pro_list.html
  25. 744 315
      src/jfw/modules/app/src/web/templates/big-member/page_report_detail_month.html
  26. 425 158
      src/jfw/modules/app/src/web/templates/big-member/page_report_detail_week.html
  27. 1 1
      src/jfw/modules/app/src/web/templates/weixin/historypush.html
  28. 3 1
      src/jfw/modules/bigmember/src/config.json
  29. 2 0
      src/jfw/modules/bigmember/src/config/config.go
  30. 4 4
      src/jfw/modules/bigmember/src/db.json
  31. 14 7
      src/jfw/modules/bigmember/src/entity/marketAnalysis/commonSearch.go
  32. 7 7
      src/jfw/modules/bigmember/src/entity/marketAnalysis/customizad_distribution.go
  33. 23 3
      src/jfw/modules/bigmember/src/entity/marketAnalysis/customized_analysis.go
  34. 108 15
      src/jfw/modules/bigmember/src/entity/marketAnalysis/marketAnalysisEntity.go
  35. 213 0
      src/jfw/modules/bigmember/src/entity/report.go
  36. 7 8
      src/jfw/modules/bigmember/src/go.mod
  37. 17 11
      src/jfw/modules/bigmember/src/go.sum
  38. 506 506
      src/jfw/modules/bigmember/src/service/analysis/forecastwinner.go
  39. 72 0
      src/jfw/modules/bigmember/src/service/report/marketAnalysis.go
  40. 66 11
      src/jfw/modules/bigmember/src/service/report/report.go
  41. 14 0
      src/jfw/modules/publicapply/src/ad/entity/struct.go
  42. 2 2
      src/jfw/modules/publicapply/src/ad/service/actions.go
  43. 1 1
      src/jfw/modules/publicapply/src/userbase/bigmembermenu.json
  44. 1 1
      src/jfw/modules/publicapply/src/userbase/commonfunctions.json
  45. 7 16
      src/jfw/tag/menu.go
  46. BIN
      src/web/staticres/big-member/image/landpage_new/itemB_04.jpg
  47. BIN
      src/web/staticres/big-member/image/landpage_new/itemB_04.png
  48. 1 1
      src/web/staticres/big-member/js/meauContact.js
  49. 1 0
      src/web/staticres/big-member/js/unit_portrayal.js
  50. 52 1
      src/web/staticres/common-module/collection/css/index.css
  51. BIN
      src/web/staticres/common-module/collection/image/bg/vip_ex_6.png
  52. BIN
      src/web/staticres/common-module/collection/image/buyer/07.png
  53. 66 10
      src/web/staticres/common-module/collection/js/area-city-mobile.js
  54. 78 1
      src/web/staticres/common-module/collection/js/area-mobile.js
  55. 49 2
      src/web/staticres/common-module/collection/js/cate-mobile.js
  56. 2 1
      src/web/staticres/common-module/collection/js/chart_options.js
  57. 1 0
      src/web/staticres/common-module/collection/js/ent_portrait.js
  58. 32 16
      src/web/staticres/common-module/collection/js/industry-mobile.js
  59. 73 5
      src/web/staticres/common-module/collection/js/keyword-mobile.js
  60. 23 0
      src/web/staticres/common-module/filter/css/filter_limit.css
  61. 89 0
      src/web/staticres/common-module/filter/css/project_cell.css
  62. 53 0
      src/web/staticres/common-module/filter/css/project_header.css
  63. BIN
      src/web/staticres/common-module/filter/image/right.png
  64. 599 0
      src/web/staticres/common-module/filter/js/filter_limit.js
  65. 141 0
      src/web/staticres/common-module/filter/js/project_cell.js
  66. 91 0
      src/web/staticres/common-module/filter/js/project_header.js
  67. 8 2
      src/web/staticres/common-module/perfect-info/js/perfect-info.js
  68. 90 0
      src/web/staticres/common-module/public/css/empty.css
  69. 46 0
      src/web/staticres/common-module/public/js/empty.js
  70. 103 0
      src/web/staticres/common-module/report-analysis/css/report_analysis.css
  71. BIN
      src/web/staticres/common-module/report-analysis/image/05.png
  72. BIN
      src/web/staticres/common-module/report-analysis/image/06.png
  73. BIN
      src/web/staticres/common-module/report-analysis/image/07.png
  74. BIN
      src/web/staticres/common-module/report-analysis/image/08.png
  75. BIN
      src/web/staticres/common-module/report-analysis/image/icon/icon-infor-blue.png
  76. 181 5
      src/web/staticres/common-module/report-analysis/js/report_analysis.js
  77. 1 1
      src/web/staticres/common-module/report-analysis/js/report_analysis_history.js
  78. 339 0
      src/web/staticres/common-module/report-analysis/js/report_analysis_pro_list.js
  79. 1 1
      src/web/templates/big-member/pc/page_index.html
  80. 0 0
      src/web/templates/big-member/wx/page_index.html
  81. 1 1
      src/web/templates/big-member/wx/page_landingPage.html
  82. 104 21
      src/web/templates/big-member/wx/page_report_analysis.html
  83. 1 1
      src/web/templates/big-member/wx/page_report_analysis_history.html
  84. 71 0
      src/web/templates/big-member/wx/page_report_analysis_pro_list.html
  85. 2 2
      src/web/templates/big-member/wx/page_report_detail_week.html
  86. 3 3
      src/web/templates/frontRouter/pc/serviceSystem/free/index.html
  87. 1 1
      src/web/templates/pc/brand/index.html
  88. 12 12
      src/web/templates/pc/supsearch.html
  89. 1 1
      src/web/templates/weixin/historypush.html

+ 3 - 0
.vscode/settings.json

@@ -0,0 +1,3 @@
+{
+  "git.ignoreLimitWarning": true
+}

+ 1 - 1
config_formal/publicapply_172.17.148.50/bigmembermenu.json

@@ -93,7 +93,7 @@
 				"isusable":false
 			},
 			{
-				   "name":"定制化分析报告",
+				   "name":"市场分析报告",
 				   "url":"/swordfish/page_big_pc/desktop/report_analysis",
 				   "isusable":false
 			}

+ 1 - 1
config_formal/publicapply_172.17.148.50/commonfunctions.json

@@ -136,7 +136,7 @@
 			}
 		},
 		{
-			   "name":"定制化分析报告",
+			   "name":"市场分析报告",
 			   "charge":true,
 			   "pc":{
 			      "url":"/swordfish/page_big_pc/desktop/report_analysis",

+ 1 - 1
config_formal/publicapply_172.17.4.183/bigmembermenu.json

@@ -93,7 +93,7 @@
 				"isusable":false
 			},
 			{
-				   "name":"定制化分析报告",
+				   "name":"市场分析报告",
 				   "url":"/swordfish/page_big_pc/desktop/report_analysis",
 				   "isusable":false
 			}

+ 1 - 1
config_formal/publicapply_172.17.4.183/commonfunctions.json

@@ -136,7 +136,7 @@
 			}
 		},
 		{
-			   "name":"定制化分析报告",
+			   "name":"市场分析报告",
 			   "charge":true,
 			   "pc":{
 			      "url":"/swordfish/page_big_pc/desktop/report_analysis",

+ 1 - 1
src/jfw/front/classificationTag.go

@@ -372,7 +372,7 @@ func NewIndexbids(session *httpsession.Session, r *http.Request) []map[string]in
 		_, total, _ := so.GetBidSearchList(true)
 		data.Count = total
 	*/
-	_, _, lists := bidsearch.GetPcBidSearchData("", "", "", "", "", "", "", "", "", "", "", "", "", 1, false, nil, bidSearch_field_1, "", false, false, "", 8, "")
+	_, _, lists := bidsearch.GetPcBidSearchData("", "", "", "", "", "", "", "", "", "", "", "", "", 1, false, nil, bidSearch_field_1, "", false, false, "", 10, "")
 	if lists != nil {
 		for _, v1 := range *lists {
 			v1["_id"] = encrypt.CommonEncodeArticle("content", v1["_id"].(string))

+ 2 - 2
src/jfw/front/pcIndex.go

@@ -30,8 +30,8 @@ const (
 type PcIndex struct {
 	*xweb.Action
 	newSordfish   xweb.Mapper `xweb:"/(old|)"`                  //剑鱼标讯pc首页
-	brandIndex    xweb.Mapper `xweb:"/brand/index"`             //品牌网站首页
-	brandIndexOld xweb.Mapper `xweb:"/brand/index_old"`         //品牌网站首页
+	brandIndex    xweb.Mapper `xweb:"/brand"`                   //品牌网站首页
+	brandIndexOld xweb.Mapper `xweb:"/brand/index"`             //品牌网站首页
 	productIndex  xweb.Mapper `xweb:"/product/index"`           //品牌网站首页
 	newSordfishC  xweb.Mapper `xweb:"/pcindex.html"`            //剑鱼标讯pc首页-统计
 	searchResult  xweb.Mapper `xweb:"/list/(\\w+)/(\\w+).html"` //剑鱼标讯分类 地区结果列表

+ 47 - 0
src/jfw/modules/app/src/web/staticres/jyapp/big-member/css/report_detail_month.css

@@ -124,6 +124,13 @@
     -webkit-transform: scaleY(0.5);
     transform: scaleY(0.5);
 }
+.current-list.current-list-new .item-double {
+  margin-top: .16rem;
+}
+.current-list.current-list-new .item-double .item-single {
+  flex-direction: inherit;
+  align-items: center;
+}
 .win-name{
     display: flex;
     align-items: center;
@@ -179,4 +186,44 @@
     font-size: .26rem;
     line-height: .4rem;
     color: #171826;
+}
+
+.project-detail-list{
+  margin-top: .16rem;
+  background: #fff;
+}
+
+.empty-container{
+  background-color: #fff;
+}
+ 
+.empty-main.tip-text {
+  color: #9B9CA3;
+  font-size: .26rem;
+}
+#report_week .van-tab--active, #report_month .van-tab--active {
+  color: #2ABED1;
+}
+#report_week .van-tabs__line, #report_month .van-tabs__line{
+  background: linear-gradient(270.04deg, #25BEEE 0.03%, #2ABED1 74.46%);;
+  width: .48rem;
+  border-radius: .02rem;
+}
+
+.ellipsis{
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.ellipsis-2{
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-line-clamp: 2;
+  -webkit-box-orient: vertical;
+  word-break: break-all;
+}
+
+.addlink{
+  text-decoration: underline;
 }

BIN
src/jfw/modules/app/src/web/staticres/jyapp/big-member/image/icon-infor-blue.png


BIN
src/jfw/modules/app/src/web/staticres/jyapp/big-member/image/landpage_new/itemB_04.jpg


BIN
src/jfw/modules/app/src/web/staticres/jyapp/big-member/image/landpage_new/itemB_04.png


+ 2 - 1
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/chart_options.js

@@ -729,6 +729,7 @@ var chartOptions = {
         },
     },
     deformPieChart:{
+        roseType: true,
         dataset: {
             source: []
         },
@@ -784,7 +785,7 @@ var chartOptions = {
             clockWise: false,
             startAngle: 60,
             center: ['50%', '50%'],
-            roseType: 'area',
+            ...(this.roseType ? {roseType: 'area'} : {}),
             encode: {
                 x:0,
                 y:1,

+ 1 - 0
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/ent_portrait.js

@@ -1247,6 +1247,7 @@ var vNode = {
       var normal = ['行业', '中标金额占比', '中标金额', '项目数量', '平均折扣率'];
       var newArr = that.arrTrans(5, arr);
       newArr.unshift(normal)
+      chartOptions.deformPieChart.roseType = false;
       chartOptions.deformPieChart.dataset.source = newArr;
       chartOptions.deformPieChart.tooltip.formatter = function (params) {
         var tip = '';

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

@@ -194,7 +194,7 @@ var staticData = [
                 dis_url:'javascript:;',
                 b_gray_icon:'icon-gray-dingzhi',
                 b_gold_icon:'icon-gold-dingzhi',
-                b_high:'定制化市场分析报告',
+                b_high:'市场分析报告',
                 b_content:'您可自定义时间范围,自动生成多维度市场分析报告。'
             },
             {

+ 22 - 2
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/report_analysis.js

@@ -25,7 +25,7 @@ var vm = new Vue({
     tabActiveName: 'analysis', // analysis/history
     tabList: [
       {
-        label: '定制化市场分析',
+        label: '市场分析报告',
         name: 'analysis'
       },
       {
@@ -1151,7 +1151,11 @@ var vm = new Vue({
         scaleData.rows.reverse()
         this.$set(this.sections.projectScatter, 'chartData', scaleData)
         if (this.sections.projectScatter.tableData.length) {
-          this.sections.projectScatter.dataAlready = true
+          setTimeout(() => {
+            this.sections.projectScatter.dataAlready = true
+          }, 100)
+        } else {
+          this.sections.projectScatter.dataAlready = false
         }
       }
     },
@@ -1298,6 +1302,8 @@ var vm = new Vue({
           }
         })
         tableDataCount.rows = scaleAreaCountTop3
+      } else {
+        tableDataCount.rows = []
       }
 
       const scaleAreaAmountTop3 = data.scaleAreaAmountTop
@@ -1323,13 +1329,19 @@ var vm = new Vue({
           }
         })
         tableDataAmount.rows = scaleAreaAmountTop3
+      } else {
+        tableDataAmount.rows = []
       }
 
       if (tableDataCount.rows.length) {
         this.$set(this.sections.areaScatter, 'projectCountTop3', tableDataCount.rows)
+      } else {
+        this.$set(this.sections.areaScatter, 'projectCountTop3', null)
       }
       if (tableDataAmount.rows.length) {
         this.$set(this.sections.areaScatter, 'projectAmountTop3', tableDataAmount.rows)
+      } else {
+        this.$set(this.sections.areaScatter, 'projectAmountTop3', null)
       }
     },
     sorUserTop3 (data) {
@@ -1366,6 +1378,8 @@ var vm = new Vue({
           }
         })
         tableDataCount.rows = countTop3
+      } else {
+        tableDataCount.rows = []
       }
 
       const amountTop3 = data.scaleBuyclassAmountTop
@@ -1391,13 +1405,19 @@ var vm = new Vue({
           }
         })
         tableDataAmount.rows = amountTop3
+      } else {
+        tableDataAmount.rows = []
       }
 
       if (tableDataCount.rows.length) {
         this.$set(this.sections.userScatter, 'projectCountTop3', tableDataCount.rows)
+      } else {
+        this.$set(this.sections.userScatter, 'projectCountTop3', null)
       }
       if (tableDataAmount.rows.length) {
         this.$set(this.sections.userScatter, 'projectAmountTop3', tableDataAmount.rows)
+      } else {
+        this.$set(this.sections.userScatter, 'projectAmountTop3', null)
       }
     },
     // 细分市场

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

@@ -9,7 +9,7 @@ var vm = new Vue({
     tabActiveName: 'history', // analysis/history
     tabList: [
       {
-        label: '定制化市场分析',
+        label: '市场分析报告',
         name: 'analysis'
       },
       {

+ 295 - 37
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/report_detail_month.js

@@ -3,11 +3,14 @@ var vNode = {
     el: '#report_month',
     components: {
       monthReportExample: monthReportExample,
+      filterComponent: filterComponent,
+      projectHeader: projectHeaderComponent,
+      projectCell: projectCellComponent,
+      empty: emptyComponent
     },
     data: {
-        scrollTop:0,
+        sessStorageKey: '$data-report_month',
         barChart: barChart,
-        keywords:'',
         keyTip: '',
         dateVal:'',
         settings1:{
@@ -121,7 +124,46 @@ var vNode = {
             renderer:'svg'
         },
         power: [],
-        bigStatus: 0
+        bigStatus: 0,
+        tabActive: '0',
+        projectInfo: {},
+        detailInfo: {},
+        vanlistParams: {
+          loading: false,
+          finished: false
+        },
+        listParams: {
+          sort: 0, // 项目明细排序方式
+          pageSize: 50,
+          pageNum: 1,
+          start: parseInt(utils.getParam('start')),
+          end: parseInt(utils.getParam('end'))
+        },
+        filters: {
+          selectKeysArr: [], // 关键词简单数组,用于恢复选择状态
+          keys: [], // 关键词详细数组,用于提交数据
+          area: {},
+          industry: [],
+          industryDetail: {},
+          buyerclass: [],
+          keywords:'',
+          keywordsList: [],
+        },
+        tabScrollTop: {
+          '0': 0,
+          '1': 0
+        },
+        // 备选项
+        initFilters: {
+          keys: [],
+          area: {},
+          industry: [],
+          industryDetail: {},
+          buyerclass: []
+        },
+        filterData: {},
+        stickyOffset: 0,
+        confirmSwitch: false
     },
     computed: {
         showCurMonthCount: function () {
@@ -143,7 +185,8 @@ var vNode = {
             return this.buyerTop.showAll ? this.buyerTop.list : this.buyerTop.list.slice(0,5)
         },
         showEntWinTop: function () {
-            return this.curMonthEntWin.showAll ? this.curMonthEntWin.list : this.curMonthEntWin.list.slice(0,3)
+            const num = this.detailInfo.isNewData ? 5 : 3
+            return this.curMonthEntWin.showAll ? this.curMonthEntWin.list : this.curMonthEntWin.list.slice(0,num)
         },
         showScaleWin: function () {
             return this.curMonthScaleWin.showAll ? this.curMonthScaleWin.list : this.curMonthScaleWin.list.slice(0,3)
@@ -152,6 +195,27 @@ var vNode = {
           return this.power.indexOf(10)  > -1 // power == 10
         },
     },
+    watch: {
+      tabActive (newVal) {
+        // 保存tab滚动高度
+        let beforetabname = ''
+        let aftertabname = 'tab_' + newVal
+        let beforetabnum = '0'
+        if(newVal === '1') {
+          beforetabname = 'tab_' + 0
+          beforetabnum = '0'
+        } else {
+          beforetabname = 'tab_' + 1
+          beforetabnum = '1'
+        }
+        var beforewrapper = document.querySelector('.' + beforetabname)
+        this.tabScrollTop[beforetabnum] = parseInt(beforewrapper.scrollTop) || this.tabScrollTop[beforetabnum]
+        setTimeout(() => {
+          var afterwrapper = document.querySelector('.' + aftertabname)
+          afterwrapper.scrollTop = this.tabScrollTop[newVal]
+        }, 100)
+      }
+    },
     created () {
         var startTime = new Date(parseInt(utils.getParam('start')*1000)).pattern('yyyy/MM/dd');
         var endTime = new Date(parseInt(utils.getParam('end')*1000)).pattern('yyyy/MM/dd')
@@ -159,50 +223,211 @@ var vNode = {
         this.getPowerInfo()
     },
     mounted() {
-        this.getAllChartsData();
-        if (this.$refs['chartRegCount']) {
-          this.$refs['chartRegCount'].echarts.resize()
-        }
-        setTimeout(() => {
-            this.reStoreState()
-        
-        }, 500);
-        utils.iosBackRefresh()
+      this.reStoreState()
+      this.getAllChartsData()
+      if (this.$refs['chartRegCount']) {
+        this.$refs['chartRegCount'].echarts.resize()
+      }
+      utils.iosBackRefresh()
+      const observer = new IntersectionObserver(this.handleIntersection, {
+        root: null, // 默认为浏览器视窗
+        threshold: 0, // 交叉比例,0为完全进入视窗
+      });
+      observer.observe(this.$refs.reportSource)
     },
     methods: {
-      saveScrollTop: function () {
-        var wrapper = document.querySelector('.j-container .j-main')
-        if (wrapper.scrollTop) {
-          this.scrollTop = parseInt(wrapper.scrollTop)
+      // tab切换
+      setTabChange (data) {
+        if(data === '1') {
+          this.confirmSwitch = true
+        }
+      },
+      handleIntersection(entries) {
+        entries.forEach((entry) => {
+          // 元素不可见
+          if (!entry.isIntersecting) {
+            this.calcStickyOffset()
+          }
+        })
+      },
+      // 点击项目
+      setLinkUrl (data) {
+        this.saveState()
+        if(data) {
+          const params = {
+            sid: (data.id || data.sourceinfoid)
+          }
+          sessionStorage.setItem('bigvip-fid', JSON.stringify(params))
+        }
+        location.href = '/jyapp/big/page/pro_follow_detail'
+      },
+      setBuyerLink (data) {
+        this.saveState()
+        location.href = '/jyapp/big/page/unit_portrayal?entName=' + data.buyer
+      },
+      setWinnerLink (id) {
+        this.saveState()
+        location.href = '/jyapp/big/page/ent_portrait?eId=' + id
+      },
+      // 设置排序方式
+      setsortType (data) {
+        this.listParams.pageNum = 0
+        this.listParams.sort = data
+        this.onListLoad()
+      },
+      showLoading: function () {
+        return this.$toast.loading({
+          duration: 0,
+          forbidClick: true,
+          message: 'loading...',
+        })
+      },
+      // 查询项目明细
+      confirm (data, str) {
+        this.filterData = data
+        const { area, buyerclass, industry, industryDetail, items, buyer, winner, selectKeysArr } = data
+        this.filters.area = area
+        this.filters.buyerclass = buyerclass
+        this.filters.industryDetail = industryDetail
+        this.filters.industry = industry
+        this.filters.keys = items
+        this.filters.selectKeysArr = selectKeysArr
+        this.filters.buyer = buyer
+        this.filters.winner = winner
+        const itemsArr = items.map((v) => {
+          return v.s_item
+        })
+        // data.industry = industryDetail
+        // delete data.industryDetail
+        // delete data.selectKeysArr
+        const params = {
+          ...this.listParams,
+          items: itemsArr,
+          area: area,
+          buyerclass: buyerclass,
+          industry: industryDetail,
+          buyer: buyer,
+          winner: winner
+        }
+        if(!str) {
+          this.resetListParams()
+        }
+        this.getProjectInfo(params)
+      },
+      resetListParams () {
+        this.listParams.pageNum = 1
+        this.projectInfo.list = []
+        this.projectInfo.total = 0
+      },
+      onListLoad: function () {
+        this.listParams.pageNum++
+        this.vanlistParams.loading = true
+        // 传noreload不需要重置页码
+        this.confirm(this.filterData, 'noreload')
+      },
+      getProjectInfo: function (params) {
+        var loading = null
+        if(this.listParams.pageNum === 1) {
+          loading = this.showLoading()
+        } else {
+          loading = null
         }
+        $.ajax({
+          type: 'POST',
+          url: '/bigmember/report/projectInfo',
+          data: JSON.stringify(params),
+          contentType: 'application/json',
+          success: function(res) {
+            if(loading) {
+              loading.clear()
+            }
+            this.vanlistParams.loading = false
+            if (res && res.error_code === 0 && res.data) {
+              const count = res.data.total > 5000 ? 5000 : res.data.total
+              if (this.listParams.pageNum === 1) {
+                this.projectInfo = res.data
+              } else {
+                this.projectInfo.list = this.projectInfo.list.concat(res.data.list)
+              }
+              const pageTotalNum = count / this.listParams.pageSize
+              const pageResidue = count % this.listParams.pageSize
+              if (pageResidue > 0) {
+                if (this.listParams.pageNum > pageTotalNum) {
+                  this.vanlistParams.finished = true
+                } else {
+                  this.vanlistParams.finished = false
+                }
+              } else {
+                if (this.listParams.pageNum >= pageTotalNum) {
+                  this.vanlistParams.finished = true
+                } else {
+                  this.vanlistParams.finished = false
+                }
+              }
+            } else {
+              this.$toast(res.error_msg)
+            }
+          }.bind(this)
+        })
+      },
+      calcStickyOffset: function () {
+        setTimeout(function () {
+          var headerHeight = $('.jy-app-header')[0].clientHeight
+          this.stickyOffset = headerHeight - 2
+        }.bind(this), 100)
+      },
+      // 保存页面状态
+      saveState: function () {
+        this.saveScrollTop()
         var $data = {
-          scrollTop: this.scrollTop, 
+          tabActive: this.tabActive,
+          listParams: this.listParams,
+          vanlistParams: this.vanlistParams,
+          filterData: this.filterData,
+          detailInfo: this.detailInfo,
+          projectInfo: this.projectInfo,
+          filters: this.filters,
+          tabScrollTop: this.tabScrollTop,
+          initFilters: this.initFilters
+        }
+        sessionStorage.setItem(this.sessStorageKey, JSON.stringify($data))
+      },
+      saveScrollTop: function () {
+        var wrapper = document.getElementById('report_month')
+        if (wrapper.scrollTop) {
+          this.tabScrollTop[this.tabActive] = parseInt(wrapper.scrollTop)
         }
-        sessionStorage.setItem('$data_month', JSON.stringify($data))
       },
       reStoreState: function () {
-        var $data = sessionStorage.getItem('$data_month')
+        var $data = sessionStorage.getItem(this.sessStorageKey)
         if ($data) {
           $data = JSON.parse($data)
-          this.scrollTop = $data.scrollTop
-        
+          Object.assign(this.listParams, $data.listParams)
+          Object.assign(this.vanlistParams, $data.vanlistParams)
+          Object.assign(this.filterData, $data.filterData)
+          Object.assign(this.detailInfo, $data.detailInfo)
+          this.setFilterData(this.detailInfo)
+          Object.assign(this.projectInfo, $data.projectInfo)
+          Object.assign(this.filters, $data.filters)
+          Object.assign(this.tabScrollTop, $data.tabScrollTop)
+          Object.assign(this.initFilters, $data.initFilters)
+          this.tabActive = $data.tabActive,
           setTimeout(function () {
             // 恢复滚动高度
-            this.setScrollTop(this.scrollTop)
-          }.bind(this), 0)
-  
-          sessionStorage.removeItem('$data_month')
-        } 
-  
+            this.setScrollTop(this.tabScrollTop[this.tabActive])
+          }.bind(this), 500)
+          sessionStorage.removeItem(this.sessStorageKey)
+          return $data
+        }
       },
       setScrollTop: function (scrollTop) {
         this.$nextTick(function () {
-          var wrapper = document.querySelector('.j-container .j-main')
+          var wrapper = document.getElementById('report_month')
           wrapper.scrollTop = scrollTop
         })
       },
         goTable (type) {
-          this.saveScrollTop()
+          this.saveState()
           if(type =='curMonthCountTop'){ // 本月项目数量采购行业排行榜
             window.location.href='/jyapp/big/page/report_table?source=curMonthCountTop&type='+utils.getParam("type")+'&start='+utils.getParam('start')+'&end='+utils.getParam('end')+'&header=本月项目数量采购行业排行榜'
             
@@ -215,6 +440,7 @@ var vNode = {
 
         },
         goCollect: function(source) {
+          this.saveState()
           location.href = '/jyapp/frontPage/bigmember/free/perfect_info?source=' + source
         },
         backPage: function () {
@@ -246,6 +472,9 @@ var vNode = {
                     case 'count':
                         v.parent = v.count / data[0].count*100 + "%";
                         break;
+                    case 'project_count':
+                      v.parent = v.project_count / data[0].project_count*100 + "%";
+                      break;
                     case 'scale':
                         v.bidamount = v.bidamount.fixed(2);
                         v.parent = v.bidamount / data[0].bidamount*100 + "%";
@@ -358,7 +587,7 @@ var vNode = {
             return Math.max.apply(null,arr);
         },
         // 数据部分
-        getAllChartsData: function(){
+        getAllChartsData: function(str){
             var that = this
             $.ajax({
                 type:'POST',
@@ -372,11 +601,8 @@ var vNode = {
                     // console.log(res)
                     if(res.error_code == 0 && res.data) {
                         // 关键词组
-                        if(res.data.item && res.data.item.length > 0 && res.data.item.toString() != '') {
-                            that.keywords = res.data.item.join('、')
-                        } else {
-                            that.keywords = '--'
-                        }
+                        that.detailInfo = res.data
+                        that.setFilterData(res.data)
                         // 项目数量 1
                         if (res.data.project_count && res.data.project_count.length > 0) {
                             var pCount = res.data.project_count;
@@ -539,7 +765,11 @@ var vNode = {
                         }
                         // 本月中标企业排行榜 14
                         if(res.data.winner && res.data.winner.length >0) {
-                            that.curMonthEntWin.list = res.data.winner;
+                            if(res.data.isNewData) {
+                              that.curMonthEntWin.list = that.formatterWinData(res.data.winner, 'project_count')
+                            } else {
+                              that.curMonthEntWin.list = res.data.winner;
+                            }
                             that.isShow.show_14 = true;
                         } else {
                             that.isShow.show_14 = false;
@@ -565,6 +795,34 @@ var vNode = {
                 }
             })
         },
+        setFilterData (res) {
+          var that = this
+          if(res.item && res.item.length > 0 && res.item.toString() != '') {
+              that.filters.keywords = res.item.join('、')
+              that.filters.keywordsList = res.item
+          } else {
+              that.filters.keywords = '--'
+              that.filters.selectKeysArr = []
+          }
+          // 地区
+          if (res.area) {
+            that.initFilters.area = res.area
+          } else {
+            that.initFilters.area = {}
+          }
+          // 采购单位类型
+          if(res.buyerClass) {
+            that.initFilters.buyerclass = res.buyerClass
+          } else {
+            that.initFilters.buyerclass = []
+          }
+          // 行业
+          if(res.industry) {
+            that.initFilters.industry = res.industry
+          } else {
+            that.initFilters.industry = []
+          }
+        },
         // 颜色值转换
         rgbToHex(val){  //RGB(A)颜色转换为HEX十六进制的颜色值
           var r, g, b, a,

+ 326 - 18
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/report_detail_week.js

@@ -1,9 +1,15 @@
 var vNode = {
     delimiters: ['${', '}'],
     el: '#report_week',
+    components: {
+      filterComponent: filterComponent,
+      projectHeader: projectHeaderComponent,
+      projectCell: projectCellComponent,
+      empty: emptyComponent
+    },
     data: {
+        sessStorageKey: "$data-report_week",
         barChart: barChart,
-        keywords: '',
         keyTip: '',
         dateVal: '',
         addCountSettings:{
@@ -46,23 +52,288 @@ var vNode = {
         showFollowEnt: true,
         initRendererSvg:{
             renderer:'svg'
-        }
+        },
+        tabActive: '0',
+        projectInfo: {},
+        detailInfo: {},
+        vanlistParams: {
+          loading: false,
+          finished: false
+        },
+        listParams: {
+          sort: 0, // 项目明细排序方式
+          pageSize: 50,
+          pageNum: 1,
+          start: parseInt(utils.getParam('start')),
+          end: parseInt(utils.getParam('end'))
+        },
+        filters: {
+          selectKeysArr: [], // 关键词简单数组,用于恢复选择状态
+          keys: [], // 关键词详细数组,用于提交数据
+          area: {},
+          industry: [],
+          industryDetail: {},
+          buyerclass: [],
+          keywords:'',
+          keywordsList: [],
+        },
+        tabScrollTop: {
+          '0': 0,
+          '1': 0
+        },
+        // 备选项
+        initFilters: {
+          keys: [],
+          area: {},
+          industry: [],
+          industryDetail: {},
+          buyerclass: []
+        },
+        filterData: {},
+        stickyOffset: 0,
+        confirmSwitch: false // 为true开始查询项目明细
     },
     computed: {
         amountWinArr: function () {
             return this.itemAmount.showAll ? this.itemAmount.list : this.itemAmount.list.slice(0,3)
         },
     },
+    watch: {
+      tabActive (newVal) {
+        // 保存tab滚动高度
+        let beforetabname = ''
+        let aftertabname = 'tab_' + newVal
+        let beforetabnum = '0'
+        if(newVal === '1') {
+          beforetabname = 'tab_' + 0
+          beforetabnum = '0'
+        } else {
+          beforetabname = 'tab_' + 1
+          beforetabnum = '1'
+        }
+        var beforewrapper = document.querySelector('.' + beforetabname)
+        this.tabScrollTop[beforetabnum] = parseInt(beforewrapper.scrollTop) || this.tabScrollTop[beforetabnum]
+        setTimeout(() => {
+          var afterwrapper = document.querySelector('.' + aftertabname)
+          afterwrapper.scrollTop = this.tabScrollTop[newVal]
+        }, 100)
+      }
+    },
     created () {
         var startTime = new Date(parseInt(utils.getParam('start')*1000)).pattern('yyyy/MM/dd');
         var endTime = new Date(parseInt(utils.getParam('end')*1000)).pattern('yyyy/MM/dd')
         this.dateVal = startTime + '-' + endTime;
     },
     mounted() {
-        this.getUserPower()
-        this.getAllChartsData()
+      const recover = this.reStoreState()
+      // if(!recover) {
+      // }
+      this.getUserPower()
+      this.getAllChartsData()
+      const observer = new IntersectionObserver(this.handleIntersection, {
+        root: null, // 默认为浏览器视窗
+        threshold: 0, // 交叉比例,0为完全进入视窗
+      });
+      observer.observe(this.$refs.reportSource)
     },
     methods: {
+      // tab切换
+      setTabChange (data) {
+        if(data === '1') {
+          this.confirmSwitch = true
+        }
+      },
+      // 保存页面状态
+      saveState: function () {
+        this.saveScrollTop()
+        var $data = {
+          tabActive: this.tabActive,
+          listParams: this.listParams,
+          vanlistParams: this.vanlistParams,
+          filterData: this.filterData,
+          detailInfo: this.detailInfo,
+          projectInfo: this.projectInfo,
+          filters: this.filters,
+          tabScrollTop: this.tabScrollTop,
+          initFilters: this.initFilters,
+          itemAmount: this.itemAmount
+        }
+        sessionStorage.setItem(this.sessStorageKey, JSON.stringify($data))
+      },
+      reStoreState: function () {
+        var $data = sessionStorage.getItem(this.sessStorageKey)
+        if ($data) {
+          $data = JSON.parse($data)
+          Object.assign(this.listParams, $data.listParams)
+          Object.assign(this.vanlistParams, $data.vanlistParams)
+          Object.assign(this.filterData, $data.filterData)
+          Object.assign(this.detailInfo, $data.detailInfo)
+          this.setFilterData(this.detailInfo)
+          Object.assign(this.projectInfo, $data.projectInfo)
+          Object.assign(this.filters, $data.filters)
+          Object.assign(this.tabScrollTop, $data.tabScrollTop)
+          Object.assign(this.initFilters, $data.initFilters)
+          Object.assign(this.itemAmount, $data.itemAmount)
+          // this.filters.industry = this.filters.industryDetail
+          this.tabActive = $data.tabActive
+
+          setTimeout(function () {
+            // 恢复滚动高度
+            this.setScrollTop(this.tabScrollTop[this.tabActive])
+          }.bind(this), 300)
+
+          sessionStorage.removeItem(this.sessStorageKey)
+        }
+
+        return $data
+      },
+      setScrollTop: function (scrollTop) {
+        this.$nextTick(function () {
+          var wrapper = document.getElementById('report_week')
+          wrapper.scrollTop = scrollTop
+        })
+      },
+      saveScrollTop: function () {
+        var wrapper = document.getElementById('report_week')
+        if (wrapper.scrollTop) {
+          this.tabScrollTop[this.tabActive] = parseInt(wrapper.scrollTop)
+        }
+      },
+      handleIntersection(entries) {
+        entries.forEach((entry) => {
+          // 元素不可见
+          if (!entry.isIntersecting) {
+            this.calcStickyOffset()
+          }
+        })
+      },
+      calcStickyOffset: function () {
+        setTimeout(function () {
+          var headerHeight = $('.jy-app-header')[0].clientHeight
+          this.stickyOffset = headerHeight - 2
+        }.bind(this), 100)
+      },
+      setLinkUrl (data) {
+        this.saveState()
+        if(data) {
+          const params = {
+            sid: data.sourceinfoid
+          }
+          sessionStorage.setItem('bigvip-fid', JSON.stringify(params))
+        }
+        location.href = '/jyapp/big/page/pro_follow_detail'
+      },
+      setBuyerLink (data) {
+        this.saveState()
+        location.href = '/jyapp/big/page/unit_portrayal?entName=' + data.buyer
+      },
+      setWinnerLink (id) {
+        if(id) {
+          this.saveState()
+          location.href = '/jyapp/big/page/ent_portrait?eId=' + id
+        }
+      },
+      // 设置排序方式
+      setsortType (data) {
+        this.listParams.pageNum = 0
+        this.listParams.sort = data
+        this.onListLoad()
+      },
+      showLoading: function () {
+        return this.$toast.loading({
+          duration: 0,
+          forbidClick: true,
+          message: 'loading...',
+        })
+      },
+      // 查询项目明细
+      confirm (data, str) {
+        this.filterData = data
+        const { area, buyerclass, industry, items, buyer, winner, industryDetail, selectKeysArr } = data
+        this.filters.area = area
+        this.filters.buyerclass = buyerclass
+        this.filters.industryDetail = industryDetail
+        this.filters.industry = industry
+        this.filters.keys = items
+        this.filters.selectKeysArr = selectKeysArr
+        this.filters.buyer = buyer
+        this.filters.winner = winner
+        const itemsArr = items.map((v) => {
+          return v.s_item
+        })
+        // data.industry = industryDetail
+        // delete data.industryDetail
+        // delete data.selectKeysArr
+        const params = {
+          ...this.listParams,
+          items: itemsArr,
+          area: area,
+          buyerclass: buyerclass,
+          industry: industryDetail,
+          buyer: buyer,
+          winner: winner
+        }
+        if(!str) {
+          this.resetListParams()
+        }
+        this.getProjectInfo(params)
+      },
+      resetListParams () {
+        this.listParams.pageNum = 1
+        this.projectInfo.list = []
+        this.projectInfo.total = 0
+      },
+      onListLoad: function () {
+        this.listParams.pageNum++
+        this.vanlistParams.loading = true
+        // 传noreload不需要重置页码
+        this.confirm(this.filterData, 'noreload')
+      },
+      getProjectInfo: function (params) {
+        var loading = null
+        if(this.listParams.pageNum === 1) {
+          loading = this.showLoading()
+        } else {
+          loading = null
+        }
+        $.ajax({
+          type: 'POST',
+          url: '/bigmember/report/projectInfo',
+          data: JSON.stringify(params),
+          contentType: 'application/json',
+          success: function(res) {
+            if(loading) {
+              loading.clear()
+            }
+            this.vanlistParams.loading = false
+            if (res && res.error_code === 0 && res.data) {
+              const count = res.data.total > 5000 ? 5000 : res.data.total
+              if (this.listParams.pageNum === 1) {
+                this.projectInfo = res.data
+              } else {
+                this.projectInfo.list = this.projectInfo.list.concat(res.data.list)
+              }
+              const pageTotalNum = count / this.listParams.pageSize
+              const pageResidue = count % this.listParams.pageSize
+              if (pageResidue > 0) {
+                if (this.listParams.pageNum > pageTotalNum) {
+                  this.vanlistParams.finished = true
+                } else {
+                  this.vanlistParams.finished = false
+                }
+              } else {
+                if (this.listParams.pageNum >= pageTotalNum) {
+                  this.vanlistParams.finished = true
+                } else {
+                  this.vanlistParams.finished = false
+                }
+              }
+            } else {
+              this.$toast(res.error_msg)
+            }
+          }.bind(this)
+        })
+      },
         formatterWinData: function(data) {
             data.forEach(function(v,i){
                 v.parent = v.count / data[0].count*100 + "%";
@@ -111,12 +382,9 @@ var vNode = {
                 },
                 success:function(res) {
                     // console.log(res)
-                    if(res.error_code == 0) {
-                        if(res.data.item && res.data.item.length > 0 && res.data.item.toString() != '') {
-                            that.keywords = res.data.item.join('、')
-                        } else {
-                            that.keywords = '--'
-                        }
+                    if(res.error_code == 0 && res.data) {
+                        that.detailInfo = res.data
+                        that.setFilterData(res.data)
                         // 本周新增招标项目数量
                         if(res.data.zhao_matchitem && res.data.zhao_matchitem.length > 0){
                             that.curWeekAddBirds = that.formatterWinData(res.data.zhao_matchitem)
@@ -173,13 +441,23 @@ var vNode = {
                         } else {
                             that.showScale = false
                         }
-                        // 项目金额排行榜
+                        // 本周项目规模排行榜TOP30
                         if(res.data.project_amount && res.data.project_amount.length > 0) {
-                            var data = res.data.project_amount;
-                            data.forEach(function(item,index){
-                                // 万元转换成亿
-                                item.budget = (item.budget/10000).fixed(2)
-                                item.bidamount = (item.bidamount/10000).fixed(2)
+                            res.data.project_amount.forEach(v => {
+                              if(v.winner) {
+                                if(v.winner.indexOf(',') !== -1) {
+                                  v.winner = v.winner.split(',')
+                                } else {
+                                  v.winner = [v.winner]
+                                }
+                              }
+                              if(v.id) {
+                                if(v.id.indexOf(',') !== -1) {
+                                  v.id = v.id.split(',')
+                                } else {
+                                  v.id = [v.id]
+                                }
+                              }
                             })
                             that.itemAmount.list = res.data.project_amount;
                         } else {
@@ -222,8 +500,38 @@ var vNode = {
                     console.log(err)
                 }
             })
-            
-            
+        },
+        // resetFilter () {
+        //   this.getAllChartsData('reset')
+        // },
+        setFilterData (data) {
+          var that = this
+          if(data.item && data.item.length > 0 && data.item.toString() != '') {
+              that.filters.keywords = data.item.join('、')
+              that.filters.keywordsList = data.item
+          } else {
+              that.filters.keywords = '--'
+              that.filters.selectKeysArr = []
+          }
+          // 地区
+          if (data.area) {
+            that.initFilters.area = data.area
+          } else {
+            that.initFilters.area = {}
+          }
+          // 采购单位类型
+          if(data.buyerClass) {
+            that.initFilters.buyerclass = data.buyerClass
+          } else {
+            that.initFilters.buyerclass = []
+          }
+          // 行业
+          if(data.industry) {
+            that.initFilters.industry = data.industry
+          } else {
+            that.initFilters.industry = []
+          }
+          this.$forceUpdate()
         },
         /* 以下为配置项部分 */
         // 本周新增招标项目数量

+ 1 - 0
src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/unit_portrayal.js

@@ -1395,6 +1395,7 @@ var vNode = {
       var normal = ['行业', '采购规模占比', '采购规模', '采购项目数量', '平均节支率'];
       var newArr = that.arrTrans(5, arr);
       newArr.unshift(normal)
+      chartOptions.deformPieChart.roseType = false;
       chartOptions.deformPieChart.dataset.source = newArr;
       chartOptions.deformPieChart.tooltip.formatter = function (params) {
         var tip = '';

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
src/jfw/modules/app/src/web/templates/big-member/page_contrast.html


+ 1 - 1
src/jfw/modules/app/src/web/templates/big-member/page_landingPage.html

@@ -136,7 +136,7 @@
           <img src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/image/landpage_new/itemB_03.jpg'>
         </div>
         <div style="font-size: 0;">
-          <img src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/image/landpage_new/itemB_04.jpg'>
+          <img src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/image/landpage_new/itemB_04.png'>
         </div>
         <div class="btn_buy" id="btn_buy" @click="exper_fun('sj', 1)"  style="background-color:#1A1A2A;"><img data-need-bind-phone src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/image/landpage_new/itemB_05.jpg' alt="" class="btn_buy_img" id="btn_buy_img"></div>
       </div>

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

@@ -3,13 +3,14 @@
 <head>
     <!--引入公共资源头部-->
     {{include "/big-member/meta.html"}}
-    <title>定制化市场分析报告</title>
+    <title>市场分析报告</title>
     <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/reset-css/5.0.1/reset.min.css />
     <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
     <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
     <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/css/index.css?v={{Msg "seo" "version"}}'/>
     <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/css/report_analysis.css?v={{Msg "seo" "version"}}1' />
     <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/css/index.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/css/project_header.css?v={{Msg "seo" "version"}}' />
     <style>
         /* fix: --- 弹窗组件不能显示底部问题  */
         .report-popup .j-main.unitTab {
@@ -126,7 +127,7 @@
                         <div class="height8" v-show="false"></div>
                         <section class="section bg-white dimension">
                             <div class="section-title"> - 分析维度 -</div>
-                            <van-sticky class="section-sticky" z-index="99999999" :offset-top="stickyOffset">
+                            <van-sticky class="section-sticky" z-index="2000" :offset-top="stickyOffset">
                                 <div class="section-content dimension-list bg-white">
                                     <div
                                         class="j-button j-button-item dimension-item"
@@ -145,7 +146,13 @@
                         </section>
                         <!-- 市场概况 -->
                         <section class="section bg-white market-overview" id="market" v-if="getStatus">
-                            <div class="section-title pd-16">市场概况</div>
+                            <div class="section-title add-pro-list-inlet pd-16">
+                              <span>市场概况</span>
+                              <div class="pro_list_inlet" @click="inProList">
+                                <img src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/icon/icon-infor-blue.png?v={{Msg "seo" "version"}}" alt="">
+                                <span>项目明细</span>
+                              </div>
+                            </div>
                             <div class="section-content market-overview-list">
                                 <div
                                     class="market-overview-item"
@@ -174,9 +181,15 @@
                         <div class="vip_component"
                           v-if="!getStatus"
                           style="height:8.84rem">
-                          <p class="example-title">市场概况</p>
+                          <div class="example-title add-pro-list-inlet">
+                            <span>市场概况</span>
+                            <div class="pro_list_inlet" @click="inProList">
+                              <img src="{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/icon/icon-infor-blue.png?v={{Msg "seo" "version"}}" alt="">
+                              <span>项目明细</span>
+                            </div>
+                          </div>
                           <div class="chart_com" style="background:url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/01-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
-                            <chart-example type="item_1" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/01.png?v={{Msg "seo" "version"}}'>
+                            <chart-example ref="chartExampleRef" type="item_1" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/01.png?v={{Msg "seo" "version"}}'>
                             </chart-example>
                           </div>
                         </div>
@@ -271,6 +284,62 @@
                                 <market-area-scatter :chart-data="sections.areaScatter.chartData"></market-area-scatter>
                             </div>
                         </div>
+                        <!-- 城市分布 -->
+                        <div class="section bg-white pd-16 city-scatter" v-if="sections.areaScatter.dataAlready && notOneAreaCityFilter && getStatus">
+                          <div class="section-title">城市分布</div>
+                          <div class="section-content">
+                            <!-- <market-area-scatter :chart-data="sections.areaScatter.chartData"></market-area-scatter> -->
+                            <div class="section-content-header">
+                              <div class="set-area-city" @click="setAreaCity">
+                                <span>${sections.areaScatter.selectArea.area}</span>
+                                <van-icon name="play"></van-icon>
+                              </div>
+                              <div class="set-sort-type">
+                                <project-header :sort-option="sortOptionContent" :sort-optiontitle="sortOptionTitle" :showtotal="false" @setsort="setsortType"></project-header>
+                              </div>
+                              <div class="set-unit">单位:${sections.areaScatter.sortType===0?'个':'万元'}</div>
+                            </div>
+                            <div class="progress-bar-container">
+                              <div class="progress-bar-item" v-for="(item,index) in showAreaCityBtn" :key="index">
+                                  <div class="item-label">
+                                      <span class="item-name">${item.city}</span>
+                                      <span class="item-count" v-if="sections.areaScatter.sortType===0">${item.total}个</span>
+                                      <span class="item-count" v-else>${showCountAmount(item)}万元</span>
+                                  </div>
+                                  <div class="item-progress">
+                                      <span class="item-progress-count blue-progress" :style="{width: item.parent}"></span>
+                                  </div>
+                              </div>
+                            </div>
+                            <div class="more" @click="sections.areaScatter.showAreaCityListBtn = false" v-if="sections.areaScatter.showAreaCityListBtn">
+                              <span>查看更多</span>
+                            </div>
+                          </div>
+                        </div>
+                        <van-popup
+                          v-model="sections.areaScatter.showAreaPopup"
+                          closeable
+                          round
+                          position="bottom"
+                          close-icon="clear"
+                          class="j-popup collection"
+                          :lazy-render="false"
+                          overlay-class="j-overlay"
+                          :style="{ height: '60%' }"
+                          get-container="body">
+                          <div class="j-container report-popup">
+                              <div class="popup-header header-title">请选择省份</div>
+                              <div class="j-main area-content">
+                                  <area-component
+                                      :multiple="false"
+                                      :newprovincelist="reportFilters.area"
+                                      :showcountry="false"
+                                      ref="areaSelector"
+                                      @cancel="cancelSelectArea"
+                                      @confirm="confirmSelectArea"></area-component>
+                              </div>
+                          </div>
+                        </van-popup>
                         <div class="section bg-white pd-16" v-if="sections.areaScatter.projectCountTop3 && getStatus">
                             <div class="section-title">项目数量TOP3地区的重点中标单位</div>
                             <div class="section-content">
@@ -365,31 +434,37 @@
                                 <line-chart-scatter :chart-data="sections.buyerclass.chartData"></line-chart-scatter>
                             </div>
                         </div>
-                        <div class="section bg-white pd-16" v-if="sections.buyerclass.projectCountTop3 && getStatus">
-                            <div class="section-title">项目数量TOP3采购单位及其重点合作中标单位</div>
+                        <div class="section bg-white pd-16" v-if="showBuyerBtn && getStatus">
+                            <div class="section-title">项目数量TOP30采购单位及其重点合作中标单位</div>
                             <div class="section-content">
-                                <market-top3-table :table-data="sections.buyerclass.projectCountTop3" type="count" @save="saveState"></market-top3-table>
+                                <market-top3-table :table-data="showBuyerBtn" type="count" @save="saveState"></market-top3-table>
+                                <div class="more" @click="sections.buyerclass.showCountAllBtn = false" v-if="sections.buyerclass.showCountAllBtn">
+                                  <span>查看更多</span>
+                                </div>
                             </div>
                         </div>
                         <div class="vip_component"
                           v-if="!getStatus"
                           style="height:10.8rem">
-                          <p class="example-title">项目数量TOP3采购单位及其重点合作中标单位</p>
+                          <p class="example-title">项目数量TOP30采购单位及其重点合作中标单位</p>
                           <div class="chart_com" style="background:url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/05-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
                             <chart-example type="item_5" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/05.png?v={{Msg "seo" "version"}}'>
                             </chart-example>
                           </div>
                         </div>
-                        <div class="section bg-white pd-16" v-if="sections.buyerclass.projectAmountTop3 && getStatus">
-                            <div class="section-title">采购金额TOP3采购单位及其重点合作中标单位</div>
+                        <div class="section bg-white pd-16" v-if="showAmoutBtn && getStatus">
+                            <div class="section-title">采购金额TOP30采购单位及其重点合作中标单位</div>
                             <div class="section-content">
-                                <market-top3-table :table-data="sections.buyerclass.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
+                                <market-top3-table :table-data="showAmoutBtn" type="amount" @save="saveState"></market-top3-table>
+                                <div class="more" @click="sections.buyerclass.showAmoutAllBtn = false" v-if="sections.buyerclass.showAmoutAllBtn">
+                                  <span>查看更多</span>
+                                </div>
                             </div>
                         </div>
                         <div class="vip_component"
                           v-if="!getStatus"
                           style="height:10.8rem">
-                          <p class="example-title">采购金额TOP3采购单位及其重点合作中标单位</p>
+                          <p class="example-title">采购金额TOP30采购单位及其重点合作中标单位</p>
                           <div class="chart_com" style="background:url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/06-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
                             <chart-example type="item_6" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/06.png?v={{Msg "seo" "version"}}'>
                             </chart-example>
@@ -402,31 +477,37 @@
                                 <line-chart-scatter :chart-data="sections.winner.chartData"></line-chart-scatter>
                             </div>
                         </div>
-                        <div class="section bg-white pd-16" v-if="sections.winner.projectCountTop3 && getStatus">
-                            <div class="section-title">项目数量TOP3中标单位及其重点合作采购单位</div>
+                        <div class="section bg-white pd-16" v-if="showWinnerCountBtn && getStatus">
+                            <div class="section-title">项目数量TOP30中标单位及其重点合作采购单位</div>
                             <div class="section-content">
-                                <market-top3-table :table-data="sections.winner.projectCountTop3" type="count" @save="saveState"></market-top3-table>
+                                <market-top3-table :table-data="showWinnerCountBtn" type="count" @save="saveState"></market-top3-table>
+                                <div class="more" @click="sections.winner.showCountAllBtn = false" v-if="sections.winner.showCountAllBtn">
+                                  <span>查看更多</span>
+                                </div>
                             </div>
                         </div>
                         <div class="vip_component"
                           v-if="!getStatus"
                           style="height:10.8rem">
-                          <p class="example-title">项目数量TOP3中标单位及其重点合作采购单位</p>
+                          <p class="example-title">项目数量TOP30中标单位及其重点合作采购单位</p>
                           <div class="chart_com" style="background:url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/07-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
                             <chart-example type="item_7" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/07.png?v={{Msg "seo" "version"}}'>
                             </chart-example>
                           </div>
                         </div>
-                        <div class="section bg-white pd-16" v-if="sections.winner.projectAmountTop3 && getStatus">
-                            <div class="section-title">中标金额TOP3中标单位及其重点合作采购单位</div>
+                        <div class="section bg-white pd-16" v-if="showWinnerAmoutBtn && getStatus">
+                            <div class="section-title">中标金额TOP30中标单位及其重点合作采购单位</div>
                             <div class="section-content">
-                                <market-top3-table :table-data="sections.winner.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
+                                <market-top3-table :table-data="showWinnerAmoutBtn" type="amount" @save="saveState"></market-top3-table>
+                                <div class="more" @click="sections.winner.showAmoutAllBtn = false" v-if="sections.winner.showAmoutAllBtn">
+                                  <span>查看更多</span>
+                                </div>
                             </div>
                         </div>
                         <div class="vip_component"
                           v-if="!getStatus"
                           style="height:10.8rem">
-                          <p class="example-title">中标金额TOP3中标单位及其重点合作采购单位</p>
+                          <p class="example-title">中标金额TOP30中标单位及其重点合作采购单位</p>
                           <div class="chart_com" style="background:url('{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/08-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
                             <chart-example type="item_8" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/08.png?v={{Msg "seo" "version"}}'>
                             </chart-example>
@@ -550,6 +631,7 @@
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/keyword-mobile.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/date-mobile.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/area-city-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/area-mobile.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/industry-mobile.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/cate-mobile.js?v={{Msg "seo" "version"}}'></script>
 <!-- components -->
@@ -562,6 +644,7 @@
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/marketUserScatter.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/marketSegment.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/lineChartScatter.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/js/project_header.js?v={{Msg "seo" "version"}}'></script>
 <!-- main.js -->
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/report_analysis.js?v={{Msg "seo" "version"}}13'></script>
 

+ 1 - 1
src/jfw/modules/app/src/web/templates/big-member/page_report_analysis_history.html

@@ -3,7 +3,7 @@
 <head>
     <!--引入公共资源头部-->
     {{include "/big-member/meta.html"}}
-    <title>定制化市场分析报告</title>
+    <title>市场分析报告</title>
     <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/reset-css/5.0.1/reset.min.css />
     <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
     <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />

+ 59 - 0
src/jfw/modules/app/src/web/templates/big-member/page_report_analysis_pro_list.html

@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <!--引入公共资源头部-->
+    {{include "/big-member/meta.html"}}
+    <title>市场分析报告项目明细</title>
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/reset-css/5.0.1/reset.min.css />
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/css/index.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/public/css/empty.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/css/filter_limit.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/css/project_cell.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/css/project_header.css?v={{Msg "seo" "version"}}' />
+</head>
+
+<body>
+<div class="j-container">
+    {{include "/big-member/header.html"}}
+    <div class="j-main" id="analysisList" v-cloak>
+      <filter-component :anyncdata="anyncData" :initfilters="initFilters" :switch="confirmSwitch" :show-tip="false" :show-select="false" :filtersdata="filters"  @confirm="confirm"></filter-component>
+      <div class="project-detail-list" v-if="Object.keys(projectInfo).length != 0 && projectInfo.list.length > 0">
+        <project-header :sort-optiontitle="sortOptiontitle" :sort-option="sortOption" :total="projectInfo.total"  @setsort="setsortType"></project-header>
+        <van-list
+          v-model:loading="vanlistParams.loading"
+          :finished="vanlistParams.finished"
+          :finished-text="projectInfo.total > 5000 ? '为您展示前5000条,可细化筛选条件查看更多信息': '没有更多了'"
+          @load="onListLoad"
+        >
+          <project-cell @set-winner-link="setWinnerLink" @set-buyer-link="setBuyerLink(item)" @set-link-url="setLinkUrl" :item="item" v-for="item in projectInfo.list" :key="item.id">
+            <div class="update-time">
+              <div class="update-time-label">
+                成交时间:
+              </div>
+              <div class="update-time-content">${item.dealTime?utils.dateFromNow(item.dealTime*1000):'--'}</div>
+            </div>
+          </project-cell>
+        </van-list>
+      </div>
+      <empty v-else>暂无数据</empty>
+    </div>
+</div>
+
+<script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js></script>
+<script src=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js></script>
+<script src=//cdn-common.jianyu360.com/cdn/lib/zepto/1.2.0/zepto.min.js></script>
+{{include "/big-member/commonjs.html"}}
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/public/js/china-map-data.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/keyword-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/area-city-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/industry-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/cate-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/js/filter_limit.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/js/project_cell.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/js/project_header.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/public/js/empty.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/report_analysis_pro_list.js?v={{Msg "seo" "version"}}'></script>
+</body>
+</html>

Diferenças do arquivo suprimidas por serem muito extensas
+ 744 - 315
src/jfw/modules/app/src/web/templates/big-member/page_report_detail_month.html


+ 425 - 158
src/jfw/modules/app/src/web/templates/big-member/page_report_detail_week.html

@@ -19,6 +19,11 @@
     <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
     <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/v-charts/1.19.0/style.min.css />
     <!--E-当前页面的css资源-->
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/css/index.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/css/filter_limit.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/css/project_header.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/css/project_cell.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/public/css/empty.css?v={{Msg "seo" "version"}}' />
     <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/css/report_detail_month.css?v={{Msg "seo" "version"}}' />
     <style>
         .emphasis-list{
@@ -42,6 +47,9 @@
             justify-content: space-between;
             align-items: baseline;
         }
+        .emphasis-p .addlink{
+          text-decoration: underline;
+        }
         .emphasis-p:not(:last-child){
             margin-bottom: .16rem;
         }
@@ -109,11 +117,11 @@
 <body>
 <div class="j-container">
     {{include "/big-member/header.html"}}
-    <div id="report_week" class="j-main" v-cloak>
+    <div id="report_week" :class="'tab_'+tabActive" class="j-main" v-cloak>
         <div class="report_title">
             <div class="keyword">
                 <span>订阅关键词${keyTip == 'free' ? '' : '组'}:</span>
-                <span>${keywords} </span>
+                <span>${filters.keywords} </span>
             </div>
             <van-cell-group>
                 <!-- <van-cell title-class="keyword" title="订阅关键词组:端点安全、网络安全、应用安全、数据安全、身份与访问管理、安全管理;"></van-cell> -->
@@ -124,13 +132,15 @@
                 </van-cell>
             </van-cell-group>
         </div>
-        <div class="report_source">
+        <div ref="reportSource" class="report_source">
             <p>数据来源:基于您当前订阅条件所关联的招投标公告数据;</p>
             <p>项目预算/项目规模:少量预算金额、中标金额未公开或为空的项目,在计算项目总预算、总规模时不参与统计;</p>
             <p>项目重复统计:一个招标项目可能同属于多个关键词组,故各关键词组的数据统计之和可能大于整体市场的统计。</p>
         </div>
-        <!-- 本周新增招标项目数量 -->
-        <div class="chart" v-if="showCurWeekAdd">
+        <!--  || !detailInfo.isNewData -->
+        <div v-if="utils.getParam('type')!='member' || !detailInfo.isNewData">
+          <!-- 本周新增招标项目数量 -->
+          <div class="chart" v-if="showCurWeekAdd">
             <div class="chart_title">本周新增招标项目数量</div>
             <div class="progress-bar-container">
                 <div class="progress-bar-item" v-for="(item,index) in curWeekAddBirds" :key="index">
@@ -144,179 +154,427 @@
                 </div>
             </div>
             <div class="mark-words" @click="goCollect('week_project_seek_count')">全面获取关注项目的新增数量,挖掘商机!<em class="mark-icon-right"></em></div>
+          </div>
+          <!-- 本周新增招标项目预算 -->
+          <div class="chart" v-if="showBudget">
+              <div class="chart_title">本周新增招标项目预算</div>
+              <div>
+                  <ve-histogram
+                      height="284px"
+                      :init-options="initRendererSvg"
+                      :data="addCountData"
+                      :after-config="addCountConfig"
+                      :settings="addCountSettings"
+                      :extend="barChart.chartExtend">
+                  </ve-histogram>
+              </div>
+              <div class="mark-words" @click="goCollect('week_project_seek_budget')">提前获取关注项目的市场动向,挖掘潜在客户!<em class="mark-icon-right"></em></div>
+          </div>
+          <!-- 本周新增开标项目数量 -->
+          <div class="chart" v-if="showCurWeekOpen">
+              <div class="chart_title">本周新增开标项目数量</div>
+              <div class="progress-bar-container">
+                  <div class="progress-bar-item" v-for="(item,index) in curWeekOpenBirds" :key="index">
+                      <div class="item-label">
+                          <span class="item-name">${item.item}</span>
+                          <span class="item-count">${item.count}个</span>
+                      </div>
+                      <div class="item-progress">
+                          <span class="item-progress-count" :class="index > 2 ? 'blue-progress' : 'yellow-progress'" :style="{width: item.parent}"></span>
+                      </div>
+                  </div>
+              </div>
+              <div class="mark-words" @click="goCollect('week_project_open_count')">获取新项目的全部开标统计,帮助企业寻找客户!<em class="mark-icon-right"></em></div>
+          </div>
+          <!-- 本周新增招标项目规模 -->
+          <div class="chart" v-if="showScale">
+              <div class="chart_title">本周新增开标项目规模</div>
+              <div>
+                  <ve-histogram
+                      height="284px"
+                      :init-options="initRendererSvg"
+                      :data="curWeekAddScaleData"
+                      :after-config="curWeekAddScaleConfig"
+                      :settings="curWeekAddScaleSettings"
+                      :extend="barChart.chartExtend">
+                  </ve-histogram>
+              </div>
+              <div class="mark-words" @click="goCollect('week_project_seek_bidamount')">全面获取关注项目的规模,分析市场容量,寻找客户!<em class="mark-icon-right"></em></div>
+          </div>
+          <!-- 项目金额排行榜 -->
+          <div class="chart" v-if="showItemAmount">
+              <div class="chart_title">项目金额排行榜</div>
+              <div>
+                  <div class="current-list" v-for="(item,index) in amountWinArr">
+                      <div class="win-name">
+                          <span v-if="index === 0" class="index first-index">${index + 1}</span>
+                          <span v-else-if="index === 1" class="index second-index">${index + 1}</span>
+                          <span v-else-if="index === 2" class="index third-index">${index + 1}</span>
+                          <span v-else class="index ">${index + 1}</span>
+                          <span class="title">${item.projectname || '--'}</span>
+                      </div>
+                      <div class="item-double">
+                          <div class="item-single">
+                              <span class="i-label">采购单位</span>
+                              <span class="i-value mosaic-text-for-check">${item.buyer || '--'}</span>
+                          </div>
+                      </div>
+                      <div class="item-double">
+                          <div class="item-single">
+                              <span class="i-label">中标单位</span>
+                              <span class="i-value mosaic-text-for-check">${item.winner || '--'}</span>
+                          </div>
+                      </div>
+                      <div class="item-double">
+                          <div class="item-single">
+                              <span class="i-label">预算金额(亿)</span>
+                              <span class="i-value mosaic-text-for-check">${item.budget || '--'}</span>
+                          </div>
+                          <div class="item-single">
+                              <span class="i-label">中标金额(亿)</span>
+                              <span class="i-value mosaic-text-for-check">${item.bidamount || '--'}</span>
+                          </div>
+                      </div>
+                  </div>
+              </div>
+              <div v-if="itemAmount.list.length > 5 && !itemAmount.showAll">
+                  <div class="more">
+                      <span @click="itemAmount.showAll = true">查看更多</span>
+                  </div>
+              </div>
+              <div class="mark-words" @click="goCollect('week_project_money_list')">提供你关注的top项目榜单,帮你分析市场动向!<em class="mark-icon-right"></em></div>
+          </div>
+          <!-- 下周开标提醒 -->
+          <div class="chart" v-if="showBidOpen">
+              <div class="chart_title">下周开标提醒</div>
+              <div class="emphasis">
+                  <div class="emphasis-list" v-for="item in bidOpenList">
+                      <p class="emphasis-p">
+                          <span class="e-l-label">开标时间</span>
+                          <span class="e-l-value">${item.bidopentime || '--'}</span>
+                      </p>
+                      <p class="emphasis-p">
+                          <span class="e-l-label">省市</span>
+                          <span class="e-l-value">${item.area || '--'} ${item.city}</span>
+                      </p>
+                      <p class="emphasis-p">
+                          <span class="e-l-label">项目名称</span>
+                          <span class="e-l-value mosaic-text-for-check">${item.projectname || '--'}</span>
+                      </p>
+                      <p class="emphasis-p">
+                          <span class="e-l-label">采购单位</span>
+                          <span class="e-l-value mosaic-text-for-check">${item.buyer || '--'}</span>
+                      </p>
+                      <p class="emphasis-p">
+                          <span class="e-l-label">项目预算(万)</span>
+                          <span class="e-l-value mosaic-text-for-check">${item.budget || '--'}</span>
+                      </p>
+                  </div>
+              </div>
+              <div class="mark-words" @click="goCollect('week_next_remind')">实时跟踪全部关注项目的开标详情,不遗漏商机!<em class="mark-icon-right"></em></div>
+          </div>
+          <!-- 重点关注项目 -->
+          <div class="chart" v-if="showFollowProject">
+              <div class="chart_title">重点关注项目</div>
+              <div class="emphasis">
+                  <div class="emphasis-list" v-for="fp in followProject">
+                      <p class="emphasis-p">
+                          <span class="e-l-label">项目名称</span>
+                          <span class="e-l-value">${fp.projectname || '--'}</span>
+                      </p>
+                      <p class="emphasis-p">
+                          <span class="e-l-label">项目状态</span>
+                          <span class="e-l-value">${fp.bidstatus || '--'}</span>
+                      </p>
+                      <p class="emphasis-p">
+                          <span class="e-l-label">采购单位</span>
+                          <span class="e-l-value">${fp.buyer || '--'}</span>
+                      </p>
+                      <p class="emphasis-p">
+                          <span class="e-l-label">项目预算(万)</span>
+                          <span class="e-l-value">${fp.budget || '--'}</span>
+                      </p>
+                  </div>
+              </div>
+              <div class="mark-words" @click="goCollect('week_important_project')">实时跟踪关注项目的最新动态,不遗漏任何商机!<em class="mark-icon-right"></em></div>
+          </div>
+          <!-- 重点关注企业 -->
+          <div class="chart" v-if="showFollowEnt">
+              <div class="chart_title">重点关注企业</div>
+              <div class="emphasis">
+                  <div class="emphasis-list" v-for="fi in followEnt">
+                      <p class="emphasis-p">
+                          <span class="e-l-label">企业名称</span>
+                          <span class="e-l-value">${fi.entname || '--'}</span>
+                      </p>
+                      <p class="emphasis-p">
+                          <span class="e-l-label">注册省市</span>
+                          <span class="e-l-value">${fi.area || '--'} ${fi.city}</span>
+                      </p>
+                      <p class="emphasis-p">
+                          <span class="e-l-label">中标项目</span>
+                          <span class="e-l-value">${fi.projectname || '--'}</span>
+                      </p>
+                      <p class="emphasis-p">
+                          <span class="e-l-label">中标日期</span>
+                          <span class="e-l-value">${fi.jgtime || '--'}</span>
+                      </p>
+                      <p class="emphasis-p">
+                          <span class="e-l-label">中标金额(万)</span>
+                          <span class="e-l-value">${fi.bidamount || '--'}</span>
+                      </p>
+                  </div>
+              </div>
+              <div class="mark-words" @click="goCollect('week_important_ent')">动态跟踪关注企业的最新中标项目,实时监控友商!<em class="mark-icon-right"></em></div>
+          </div>
         </div>
-        <!-- 本周新增招标项目预算 -->
-        <div class="chart" v-if="showBudget">
-            <div class="chart_title">本周新增招标项目预算</div>
-            <div>
-                <ve-histogram
-                    height="284px"
-                    :init-options="initRendererSvg"
-                    :data="addCountData"
-                    :after-config="addCountConfig"
-                    :settings="addCountSettings"
-                    :extend="barChart.chartExtend">
-                </ve-histogram>
-            </div>
-            <div class="mark-words" @click="goCollect('week_project_seek_budget')">提前获取关注项目的市场动向,挖掘潜在客户!<em class="mark-icon-right"></em></div>
-        </div>
-        <!-- 本周新增开标项目数量 -->
-        <div class="chart" v-if="showCurWeekOpen">
-            <div class="chart_title">本周新增开标项目数量</div>
-            <div class="progress-bar-container">
-                <div class="progress-bar-item" v-for="(item,index) in curWeekOpenBirds" :key="index">
-                    <div class="item-label">
-                        <span class="item-name">${item.item}</span>
-                        <span class="item-count">${item.count}个</span>
-                    </div>
-                    <div class="item-progress">
-                        <span class="item-progress-count" :class="index > 2 ? 'blue-progress' : 'yellow-progress'" :style="{width: item.parent}"></span>
+        <van-tabs v-else @change="setTabChange" v-model:active="tabActive" :offset-top="stickyOffset" sticky>
+          <van-tab name="0" title="本周分析">
+            <!-- 本周新增招标项目数量 -->
+            <div class="chart" v-if="showCurWeekAdd">
+                <div class="chart_title">本周新增招标项目数量</div>
+                <div class="progress-bar-container">
+                    <div class="progress-bar-item" v-for="(item,index) in curWeekAddBirds" :key="index">
+                        <div class="item-label">
+                            <span class="item-name">${item.item}</span>
+                            <span class="item-count">${item.count}个</span>
+                        </div>
+                        <div class="item-progress">
+                            <span class="item-progress-count" :class="index > 2 ? 'blue-progress' : 'yellow-progress'" :style="{width: item.parent}"></span>
+                        </div>
                     </div>
                 </div>
+                <div class="mark-words" @click="goCollect('week_project_seek_count')">全面获取关注项目的新增数量,挖掘商机!<em class="mark-icon-right"></em></div>
             </div>
-            <div class="mark-words" @click="goCollect('week_project_open_count')">获取新项目的全部开标统计,帮助企业寻找客户!<em class="mark-icon-right"></em></div>
-        </div>
-        <!-- 本周新增招标项目规模 -->
-        <div class="chart" v-if="showScale">
-            <div class="chart_title">本周新增开标项目规模</div>
-            <div>
-                <ve-histogram
-                    height="284px"
-                    :init-options="initRendererSvg"
-                    :data="curWeekAddScaleData"
-                    :after-config="curWeekAddScaleConfig"
-                    :settings="curWeekAddScaleSettings"
-                    :extend="barChart.chartExtend">
-                </ve-histogram>
+            <!-- 本周新增招标项目预算 -->
+            <div class="chart" v-if="showBudget">
+                <div class="chart_title">本周新增招标项目预算</div>
+                <div>
+                    <ve-histogram
+                        height="284px"
+                        :init-options="initRendererSvg"
+                        :data="addCountData"
+                        :after-config="addCountConfig"
+                        :settings="addCountSettings"
+                        :extend="barChart.chartExtend">
+                    </ve-histogram>
+                </div>
+                <div class="mark-words" @click="goCollect('week_project_seek_budget')">提前获取关注项目的市场动向,挖掘潜在客户!<em class="mark-icon-right"></em></div>
             </div>
-            <div class="mark-words" @click="goCollect('week_project_seek_bidamount')">全面获取关注项目的规模,分析市场容量,寻找客户!<em class="mark-icon-right"></em></div>
-        </div>
-        <!-- 项目金额排行榜 -->
-        <div class="chart" v-if="showItemAmount">
-            <div class="chart_title">项目金额排行榜</div>
-            <div>
-                <div class="current-list" v-for="(item,index) in amountWinArr">
-                    <div class="win-name">
-                        <span v-if="index === 0" class="index first-index">${index + 1}</span>
-                        <span v-else-if="index === 1" class="index second-index">${index + 1}</span>
-                        <span v-else-if="index === 2" class="index third-index">${index + 1}</span>
-                        <span v-else class="index ">${index + 1}</span>
-                        <span class="title">${item.projectname || '--'}</span>
-                    </div>
-                    <div class="item-double">
-                        <div class="item-single">
-                            <span class="i-label">采购单位</span>
-                            <span class="i-value mosaic-text-for-check">${item.buyer || '--'}</span>
+            <!-- 本周新增开标项目数量 -->
+            <div class="chart" v-if="showCurWeekOpen">
+                <div class="chart_title">本周新增开标项目数量</div>
+                <div class="progress-bar-container">
+                    <div class="progress-bar-item" v-for="(item,index) in curWeekOpenBirds" :key="index">
+                        <div class="item-label">
+                            <span class="item-name">${item.item}</span>
+                            <span class="item-count">${item.count}个</span>
                         </div>
-                    </div>
-                    <div class="item-double">
-                        <div class="item-single">
-                            <span class="i-label">中标单位</span>
-                            <span class="i-value mosaic-text-for-check">${item.winner || '--'}</span>
+                        <div class="item-progress">
+                            <span class="item-progress-count" :class="index > 2 ? 'blue-progress' : 'yellow-progress'" :style="{width: item.parent}"></span>
                         </div>
                     </div>
-                    <div class="item-double">
-                        <div class="item-single">
-                            <span class="i-label">预算金额(亿)</span>
-                            <span class="i-value mosaic-text-for-check">${item.budget || '--'}</span>
+                </div>
+                <div class="mark-words" @click="goCollect('week_project_open_count')">获取新项目的全部开标统计,帮助企业寻找客户!<em class="mark-icon-right"></em></div>
+            </div>
+            <!-- 本周新增招标项目规模 -->
+            <div class="chart" v-if="showScale">
+                <div class="chart_title">本周新增开标项目规模</div>
+                <div>
+                    <ve-histogram
+                        height="284px"
+                        :init-options="initRendererSvg"
+                        :data="curWeekAddScaleData"
+                        :after-config="curWeekAddScaleConfig"
+                        :settings="curWeekAddScaleSettings"
+                        :extend="barChart.chartExtend">
+                    </ve-histogram>
+                </div>
+                <div class="mark-words" @click="goCollect('week_project_seek_bidamount')">全面获取关注项目的规模,分析市场容量,寻找客户!<em class="mark-icon-right"></em></div>
+            </div>
+            <!-- 本周项目规模排行榜TOP30 -->
+            <div class="chart" v-if="showItemAmount">
+                <div class="chart_title">本周项目规模排行榜TOP30</div>
+                <div>
+                    <div class="project-cell current-list" v-for="(item,index) in amountWinArr">
+                        <div class="win-name" @click="setLinkUrl(item)">
+                            <span v-if="index === 0" class="index first-index">${index + 1}</span>
+                            <span v-else-if="index === 1" class="index second-index">${index + 1}</span>
+                            <span v-else-if="index === 2" class="index third-index">${index + 1}</span>
+                            <span v-else class="index ">${index + 1}</span>
+                            <span class="title ellipsis-2">${item.projectname || '--'}</span>
+                        </div>
+                        <div class="project-unit">
+                          <van-cell is-link @click="setBuyerLink(item)">
+                            <template #title>
+                              <div class="unit_title">
+                                <span>采购单位:</span>
+                                <span class="ellipsis buyerText">${item.buyer || '--' }</span>
+                                </div>
+                            </template>
+                            <template #label>
+                              <span>预算金额:</span>
+                              <span>${ item.budget || '--' }${ item.budget ? '万元' : ''}</span>
+                            </template>
+                          </van-cell>
+                        </div>
+                        <div class="project-unit">
+                          <van-cell :is-link="!!item.winner">
+                            <template #title>
+                              <div class="unit_title">
+                                <span>中标单位:</span>
+                                <span v-if="item.winner" :class="{'buyerText':item.winner && item.winner.length !== 0}">
+                                  <span style="margin-right: .08rem;" @click="setWinnerLink(item.id[i])" v-for="(w, i) in item.winner">${w}</span>
+                                </span>
+                                <span v-else>
+                                  ${'--'}
+                                </span>
+                              </div>
+                            </template>
+                            <template #label>
+                              <span>中标金额:</span>
+                              <span>${ item.bidamount || '--' }${ item.bidamount ? '万元' : ''}</span>
+                            </template>
+                          </van-cell>
                         </div>
-                        <div class="item-single">
-                            <span class="i-label">中标金额(亿)</span>
-                            <span class="i-value mosaic-text-for-check">${item.bidamount || '--'}</span>
+                        <!-- <div class="item-double">
+                            <div class="item-single" @click="setBuyerLink(item)">
+                                <span class="i-label">采购单位</span>
+                                <span class="i-value mosaic-text-for-check">${item.buyer || '--'}</span>
+                            </div>
                         </div>
+                        <div class="item-double">
+                            <div class="item-single" @click="setWinnerLink(item.id)">
+                                <span class="i-label">中标单位</span>
+                                <span class="i-value mosaic-text-for-check">${item.winner || '--'}</span>
+                            </div>
+                        </div>
+                        <div class="item-double">
+                            <div class="item-single">
+                                <span class="i-label">预算金额(万元)</span>
+                                <span class="i-value mosaic-text-for-check">${item.budget || '--'}</span>
+                            </div>
+                            <div class="item-single">
+                                <span class="i-label">中标金额(万元)</span>
+                                <span class="i-value mosaic-text-for-check">${item.bidamount || '--'}</span>
+                            </div>
+                        </div> -->
                     </div>
                 </div>
-            </div>
-            <div v-if="itemAmount.list.length > 5 && !itemAmount.showAll">
-                <div class="more">
-                    <span @click="itemAmount.showAll = true">查看更多</span>
+                <div v-if="itemAmount.list.length > 5 && !itemAmount.showAll">
+                    <div class="more">
+                        <span @click="itemAmount.showAll = true">查看更多</span>
+                    </div>
                 </div>
+                <div class="mark-words" @click="goCollect('week_project_money_list')">提供你关注的top项目榜单,帮你分析市场动向!<em class="mark-icon-right"></em></div>
             </div>
-            <div class="mark-words" @click="goCollect('week_project_money_list')">提供你关注的top项目榜单,帮你分析市场动向!<em class="mark-icon-right"></em></div>
-        </div>
-        <!-- 下周开标提醒 -->
-        <div class="chart" v-if="showBidOpen">
-            <div class="chart_title">下周开标提醒</div>
-            <div class="emphasis">
-                <div class="emphasis-list" v-for="item in bidOpenList">
-                    <p class="emphasis-p">
-                        <span class="e-l-label">开标时间</span>
-                        <span class="e-l-value">${item.bidopentime || '--'}</span>
-                    </p>
-                    <p class="emphasis-p">
-                        <span class="e-l-label">省市</span>
-                        <span class="e-l-value">${item.area || '--'} ${item.city}</span>
-                    </p>
-                    <p class="emphasis-p">
-                        <span class="e-l-label">项目名称</span>
-                        <span class="e-l-value mosaic-text-for-check">${item.projectname || '--'}</span>
-                    </p>
-                    <p class="emphasis-p">
-                        <span class="e-l-label">采购单位</span>
-                        <span class="e-l-value mosaic-text-for-check">${item.buyer || '--'}</span>
-                    </p>
-                    <p class="emphasis-p">
-                        <span class="e-l-label">项目预算(万)</span>
-                        <span class="e-l-value mosaic-text-for-check">${item.budget || '--'}</span>
-                    </p>
+            <!-- 下周开标提醒 -->
+            <div class="chart" v-if="showBidOpen">
+                <div class="chart_title">下周开标提醒</div>
+                <div class="emphasis">
+                    <div class="emphasis-list" v-for="item in bidOpenList">
+                        <p class="emphasis-p">
+                            <span class="e-l-label">开标时间</span>
+                            <span class="e-l-value">${item.bidopentime || '--'}</span>
+                        </p>
+                        <p class="emphasis-p">
+                            <span class="e-l-label">省市</span>
+                            <span class="e-l-value">${item.area || '--'} ${item.city}</span>
+                        </p>
+                        <p class="emphasis-p">
+                            <span class="e-l-label">项目名称</span>
+                            <span style="text-decoration: underline;" @click="setLinkUrl(item)" class="e-l-value mosaic-text-for-check">${item.projectname || '--'}</span>
+                        </p>
+                        <p class="emphasis-p">
+                            <span class="e-l-label">采购单位</span>
+                            <span style="text-decoration: underline;" @click="setBuyerLink(item)" class="e-l-value mosaic-text-for-check">${item.buyer || '--'}</span>
+                        </p>
+                        <p class="emphasis-p">
+                            <span class="e-l-label">项目预算(万)</span>
+                            <span class="e-l-value mosaic-text-for-check">${item.budget || '--'}</span>
+                        </p>
+                    </div>
                 </div>
+                <div class="mark-words" @click="goCollect('week_next_remind')">实时跟踪全部关注项目的开标详情,不遗漏商机!<em class="mark-icon-right"></em></div>
             </div>
-            <div class="mark-words" @click="goCollect('week_next_remind')">实时跟踪全部关注项目的开标详情,不遗漏商机!<em class="mark-icon-right"></em></div>
-        </div>
-        <!-- 重点关注项目 -->
-        <div class="chart" v-if="showFollowProject">
-            <div class="chart_title">重点关注项目</div>
-            <div class="emphasis">
-                <div class="emphasis-list" v-for="fp in followProject">
-                    <p class="emphasis-p">
-                        <span class="e-l-label">项目名称</span>
-                        <span class="e-l-value">${fp.projectname || '--'}</span>
-                    </p>
-                    <p class="emphasis-p">
-                        <span class="e-l-label">项目状态</span>
-                        <span class="e-l-value">${fp.bidstatus || '--'}</span>
-                    </p>
-                    <p class="emphasis-p">
-                        <span class="e-l-label">采购单位</span>
-                        <span class="e-l-value">${fp.buyer || '--'}</span>
-                    </p>
-                    <p class="emphasis-p">
-                        <span class="e-l-label">项目预算(万)</span>
-                        <span class="e-l-value">${fp.budget || '--'}</span>
-                    </p>
+            <!-- 重点关注项目 -->
+            <div class="chart" v-if="showFollowProject">
+                <div class="chart_title">重点关注项目</div>
+                <div class="emphasis">
+                    <div class="emphasis-list" v-for="fp in followProject">
+                        <p class="emphasis-p">
+                            <span class="e-l-label">项目名称</span>
+                            <span class="e-l-value">${fp.projectname || '--'}</span>
+                        </p>
+                        <p class="emphasis-p">
+                            <span class="e-l-label">项目状态</span>
+                            <span class="e-l-value">${fp.bidstatus || '--'}</span>
+                        </p>
+                        <p class="emphasis-p">
+                            <span class="e-l-label">采购单位</span>
+                            <span class="e-l-value">${fp.buyer || '--'}</span>
+                        </p>
+                        <p class="emphasis-p">
+                            <span class="e-l-label">项目预算(万)</span>
+                            <span class="e-l-value">${fp.budget || '--'}</span>
+                        </p>
+                    </div>
                 </div>
+                <div class="mark-words" @click="goCollect('week_important_project')">实时跟踪关注项目的最新动态,不遗漏任何商机!<em class="mark-icon-right"></em></div>
             </div>
-            <div class="mark-words" @click="goCollect('week_important_project')">实时跟踪关注项目的最新动态,不遗漏任何商机!<em class="mark-icon-right"></em></div>
-        </div>
-        <!-- 重点关注企业 -->
-        <div class="chart" v-if="showFollowEnt">
-            <div class="chart_title">重点关注企业</div>
-            <div class="emphasis">
-                <div class="emphasis-list" v-for="fi in followEnt">
-                    <p class="emphasis-p">
-                        <span class="e-l-label">企业名称</span>
-                        <span class="e-l-value">${fi.entname || '--'}</span>
-                    </p>
-                    <p class="emphasis-p">
-                        <span class="e-l-label">注册省市</span>
-                        <span class="e-l-value">${fi.area || '--'} ${fi.city}</span>
-                    </p>
-                    <p class="emphasis-p">
-                        <span class="e-l-label">中标项目</span>
-                        <span class="e-l-value">${fi.projectname || '--'}</span>
-                    </p>
-                    <p class="emphasis-p">
-                        <span class="e-l-label">中标日期</span>
-                        <span class="e-l-value">${fi.jgtime || '--'}</span>
-                    </p>
-                    <p class="emphasis-p">
-                        <span class="e-l-label">中标金额(万)</span>
-                        <span class="e-l-value">${fi.bidamount || '--'}</span>
-                    </p>
+            <!-- 已监控企业本周项目动态 -->
+            <div class="chart" v-if="showFollowEnt">
+                <div class="chart_title">已监控企业本周项目动态</div>
+                <div class="emphasis">
+                    <div class="emphasis-list" v-for="fi in followEnt">
+                        <p class="emphasis-p" @click="setWinnerLink(fi.id)">
+                            <span class="e-l-label">企业名称</span>
+                            <span class="e-l-value addlink">${fi.entname || '--'}</span>
+                        </p>
+                        <p class="emphasis-p">
+                            <span class="e-l-label">注册省市</span>
+                            <span class="e-l-value">${fi.area || '--'} ${fi.city}</span>
+                        </p>
+                        <p class="emphasis-p" @click="setLinkUrl(fi)">
+                            <span class="e-l-label">中标项目</span>
+                            <span class="e-l-value addlink">${fi.projectname || '--'}</span>
+                        </p>
+                        <p class="emphasis-p">
+                            <span class="e-l-label">中标日期</span>
+                            <span class="e-l-value">${fi.jgtime || '--'}</span>
+                        </p>
+                        <p class="emphasis-p">
+                            <span class="e-l-label">中标金额(万)</span>
+                            <span class="e-l-value">${fi.bidamount || '--'}</span>
+                        </p>
+                    </div>
                 </div>
+                <div class="mark-words" @click="goCollect('week_important_ent')">动态跟踪关注企业的最新中标项目,实时监控友商!<em class="mark-icon-right"></em></div>
             </div>
-            <div class="mark-words" @click="goCollect('week_important_ent')">动态跟踪关注企业的最新中标项目,实时监控友商!<em class="mark-icon-right"></em></div>
-        </div>
+          </van-tab>
+          <van-tab name="1" title="本周项目明细">
+            <filter-component :switch="confirmSwitch" :show-tip="false" :show-select="false" :filtersdata="filters" :initfilters="initFilters" :keyphraseslist="filters.keywordsList" keyformat="phrases" @confirm="confirm"></filter-component>
+            <div class="project-detail-list" v-if="Object.keys(projectInfo).length != 0 && projectInfo.list.length > 0">
+              <project-header :total="projectInfo.total" @setsort="setsortType"></project-header>
+              <van-list
+                v-model:loading="vanlistParams.loading"
+                :finished="vanlistParams.finished"
+                :finished-text="projectInfo.total > 5000 ? '为您展示前5000条,可细化筛选条件查看更多信息': '没有更多了'"
+                @load="onListLoad"
+              >
+                <project-cell @set-winner-link="setWinnerLink" @set-buyer-link="setBuyerLink(item)" @set-link-url="setLinkUrl" :item="item" v-for="item in projectInfo.list" :key="item.id">
+                  <div class="update-time">
+                    <div class="update-time-label">
+                      本周项目更新时间:
+                    </div>
+                    <div class="update-time-content">${item.lastTime?utils.dateFromNow(item.lastTime*1000):'--'}</div>
+                  </div>
+                </project-cell>
+              </van-list>
+            </div>
+            <empty v-else>暂无数据</empty>
+          </van-tab>
+        </van-tabs>
     </div>
 </div>
 
@@ -336,8 +594,17 @@
 <script src=//cdn-common.jianyu360.com/cdn/lib/v-charts/1.19.0/index.min.js></script>
 {{include "/big-member/commonjs.html"}}
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/echarts_option.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/public/js/china-map-data.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/keyword-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/area-city-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/industry-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/cate-mobile.js?v={{Msg "seo" "version"}}'></script>
 <!-- mock数据(与后端返回数据结构一致) 联调后可删除 -->
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/mock.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/js/filter_limit.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/js/project_header.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/filter/js/project_cell.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/public/js/empty.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/report_detail_week.js?v={{Msg "seo" "version"}}'></script>
 
 </body>

+ 1 - 1
src/jfw/modules/app/src/web/templates/weixin/historypush.html

@@ -297,7 +297,7 @@
         <!-- <div class="analysis-module"> -->
           <!-- 超前项目推荐 -->
           <!-- <recommend-com  ref="recommendRef"  @toggle="onToggleStatus"></recommend-com> -->
-          <!-- 定制化分析报告 -->
+          <!-- 市场分析报告 -->
           <!-- <div v-show="collapseStatus"> -->
             <!-- <CustomReport :chartData="chartData"></CustomReport> -->
           <!-- </div>

+ 3 - 1
src/jfw/modules/bigmember/src/config.json

@@ -181,5 +181,7 @@
     "listPage": "https://databi-web.jydev.jianyu360.com/nzj/app/nzj.app/nzj_claim.spg"
   },
   "contextOldVipLimit": 1664553600,
-  "potentialCount": 1000
+  "potentialCount": 1000,
+  "newDataTime": 1685606275,
+  "projectCount": 5000
 }

+ 2 - 0
src/jfw/modules/bigmember/src/config/config.go

@@ -67,6 +67,8 @@ type config struct {
 	} `json:"claim"`
 	ContextOldVipLimit int64 `json:"contextOldVipLimit"` //超级订阅部分用户:--- 超前项目权限
 	PotentialCount     int   `json:"potentialCount"`     //潜在客户 潜在竞争对手数据量
+	NewDataTime        int64 `json:"newDataTime"`        // 用于周边月报区分是否为新数据 、配置为p350发版的时间
+	ProjectCount       int   `json:"projectCount"`       //画像和报告项目明细最大数量
 }
 
 type CustomerInfo struct {

+ 4 - 4
src/jfw/modules/bigmember/src/db.json

@@ -36,11 +36,11 @@
   },
   "elasticsearch": {
     "main": {
-        "address": "http://192.168.3.206:9800,http://192.168.3.206:9801",
+        "address": "http://192.168.3.241:9205",
         "size": 30,
-		"version": "v7",
-		"userName": "",
-		"password": ""
+		    "version": "v7",
+		    "userName": "",
+		    "password": ""
     }
   },
   "redis": {

+ 14 - 7
src/jfw/modules/bigmember/src/entity/marketAnalysis/commonSearch.go

@@ -1,8 +1,8 @@
 package marketAnalysis
 
 import (
-	"fmt"
 	qutil "app.yhyue.com/moapp/jybase/common"
+	"fmt"
 	"strings"
 )
 
@@ -13,11 +13,11 @@ const (
 	query_bool_must     = `{"terms": {%s}}`
 )
 
-//GetCommonQuerySql 公共筛选
+// GetCommonQuerySql 公共筛选
 func (mae *MarketAnalysisEntity) GetCommonQuerySql() string {
 	var musts, bools []string
 	//时间
-	musts = append(musts, fmt.Sprintf(`{"range":{"firsttime":{"gte":%d,"lte":%d}}}`, mae.FormatParam.STime, mae.FormatParam.ETime))
+	musts = append(musts, fmt.Sprintf(`{"range":{"jgtime":{"gte":%d,"lte":%d}}}`, mae.FormatParam.STime, mae.FormatParam.ETime))
 	//地区
 	if len(mae.FormatParam.Area) > 0 || len(mae.FormatParam.City) > 0 {
 		var areaCity []string
@@ -45,16 +45,23 @@ func (mae *MarketAnalysisEntity) GetCommonQuerySql() string {
 			bools = append(bools, sql)
 		}
 	}
-
+	//中标企业
+	if mae.FormatParam.Winner != "" {
+		musts = append(musts, fmt.Sprintf(`{"term":{"s_winner":"%s"}}`, mae.FormatParam.Winner))
+	}
+	//采购单位
+	if mae.FormatParam.Buyer != "" {
+		musts = append(musts, fmt.Sprintf(`{"term":{"buyer":"%s"}}`, mae.FormatParam.Buyer))
+	}
 	return fmt.Sprintf(`{"query":{"bool":{"must":[%s],"should":[%s],"minimum_should_match": %d}}%s}`, strings.Join(musts, ","), strings.Join(bools, ","), qutil.If(len(bools) > 0, 1, 0).(int), "%s")
 }
 
-//GetCommonQuerySqlWithAggs 此方法用于聚合查询
+// GetCommonQuerySqlWithAggs 此方法用于聚合查询
 func (mae *MarketAnalysisEntity) GetCommonQuerySqlWithAggs() string {
 	return fmt.Sprintf(mae.GetCommonQuerySql(), `,"aggs":{%s},"size":0`)
 }
 
-//getGroupKeywordArr 模糊拆分为多个精准匹配
+// getGroupKeywordArr 模糊拆分为多个精准匹配
 func getGroupKeywordArr(res []viewKeyWord) (rData []viewKeyWord) {
 	for _, kw := range res {
 		if kw.MatchWay == 1 {
@@ -77,7 +84,7 @@ func getGroupKeywordArr(res []viewKeyWord) (rData []viewKeyWord) {
 	return
 }
 
-//getAllKeywordArr 获取所有匹配词
+// getAllKeywordArr 获取所有匹配词
 func getAllKeywordArr(res []keyWordGroup) (rData []viewKeyWord) {
 	for _, kwg := range res {
 		rData = append(rData, getGroupKeywordArr(kwg.A_Key)...)

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

@@ -17,31 +17,31 @@ import (
 
 const (
 	//市场分析聚合查询
-	aggs_market_analysis = `"%s": {"range": {"field": "firsttime","ranges": [%s]},"aggs":{"project_count": {"filter": {"match_all":{}}},"project_amount":{"sum":{"field":"sortprice"}},"project_avgMoney": {"filter": {"range": {"sortprice": {"gt": 0}}},"aggs": {"avg_amount": {"avg": {"field": "sortprice"}}}} ,"buyer_count":{"cardinality":{"field":"buyer"}},"winner_count":{"cardinality":{"field":"s_winner"}}}}`
+	aggs_market_analysis = `"%s": {"range": {"field": "jgtime","ranges": [%s]},"aggs":{"project_count": {"filter": {"match_all":{}}},"project_amount":{"sum":{"field":"sortprice"}},"project_avgMoney": {"filter": {"range": {"sortprice": {"gt": 0}}},"aggs": {"avg_amount": {"avg": {"field": "sortprice"}}}} ,"buyer_count":{"cardinality":{"field":"buyer"}},"winner_count":{"cardinality":{"field":"s_winner"}}}}`
 	//aggs_market_analysis = `"%s": {"range": {"field": "firsttime","ranges": [%s]},"aggs":{"project_count": {"filter": {"range": {"sortprice": {"gt": 0}}}},"project_amount":{"sum":{"field":"sortprice"}},"project_avgMoney": {"filter": {"range": {"sortprice": {"gt": 0}}},"aggs": {"avg_amount": {"avg": {"field": "sortprice"}}}},"buyer_count":{"filter": {"range": {"sortprice": {"gt": 0}}},"aggs": {"cardinality_buyer_count": {"cardinality": {"field": "buyer"}}}},"winner_count":{"filter": {"range": {"sortprice": {"gt": 0}}},"aggs": {"cardinality_winner_count": {"cardinality": {"field": "s_winner"}}}}}}`
 
 	//时间分布统计
-	project_time_distribution = `"%s": {"range": { "field": "firsttime","ranges": [%s]},"aggs":{ "scale_amount": {"sum": {"field": "sortprice"}}, "scale_total": {"filter": {"match_all":{}}}}}`
+	project_time_distribution = `"%s": {"range": { "field": "jgtime","ranges": [%s]},"aggs":{ "scale_amount": {"sum": {"field": "sortprice"}}, "scale_total": {"filter": {"match_all":{}}}}}`
 
 	//采购单位聚合查询
 	//buyer_procurement_scale = `"project_count":{"filter":{"match_all":{}}},"project_amount":{"sum":{"field":"sortprice"}},"buyer_count":{"filter": {"range": {"sortprice": {"gt": 0}}},"aggs": {"cardinality_buyer_count": {"cardinality": {"field": "buyer"}}}},"buyer_time_distribution": {"range": { "field": "sortprice","ranges": [%s]},"aggs":{"buyer_count": {"cardinality": {"field": "buyer"}}}},"buyer_amount_distribution": {"terms": {"field": "buyer"},"aggs": {"amount": {"sum": {"field": "sortprice"}}}}`
 	buyer_procurement_scale = `"project_amount":{"sum":{"field":"sortprice"}},"buyer_amount_distribution": {"terms": {"field": "buyer","order": [{"amount": "desc"}],"size":100000},"aggs": {"amount": {"sum": {"field": "sortprice"}}}}`
 
 	//采购单位top3(价格)buyer_sortprice
-	buyer_sortprice = `"buyer_amount_top3": {"terms": {"field": "buyer","order": [{"buyer_amount": "desc"}],"size": 3},"aggs": {"buyer_amount": {"sum": {"field": "sortprice"}},"s_winner_top": {"terms": {"field": "entidlist","exclude":["-"],"order": [{"buyer_winner_amount": "desc"}],"size": 3},"aggs": {"buyer_winner_amount": {"sum": {"field": "sortprice"}}}}}}`
+	buyer_sortprice = `"buyer_amount_top3": {"terms": {"field": "buyer","order": [{"buyer_amount": "desc"}],"size": 30},"aggs": {"buyer_amount": {"sum": {"field": "sortprice"}},"s_winner_top": {"terms": {"field": "entidlist","exclude":["-"],"order": [{"buyer_winner_amount": "desc"}],"size": 3},"aggs": {"buyer_winner_amount": {"sum": {"field": "sortprice"}}}}}}`
 	//采购单位top3(数量)
 	//buyer_count = `"buyer_count_top3": {"terms": {"field": "buyer","order": [{"buyer_count": "desc"}],"size": 3},"aggs": {"buyer_count": {"cardinality": {"field": "buyer"}},"s_winner_top": {"terms": {"field": "s_winner","order": [{"buyer_winner_count": "desc"}],"size": 3},"aggs": {"buyer_winner_count": {"cardinality": {"field": "s_winner"}}}}}}`
-	buyer_count = `"buyer_count_top3": {"terms": {"field": "buyer","order": [{"buyer_count": "desc"}],"size": 3},"aggs": {"buyer_count": {"filter":{"match_all":{}}},"s_winner_top": {"terms": {"field": "entidlist","exclude":["-"],"order": [{"buyer_winner_count": "desc"}],"size": 3},"aggs": { "buyer_winner_count": {"filter":{"match_all":{}}}}}}}`
+	buyer_count = `"buyer_count_top3": {"terms": {"field": "buyer","order": [{"buyer_count": "desc"}],"size": 30},"aggs": {"buyer_count": {"filter":{"match_all":{}}},"s_winner_top": {"terms": {"field": "entidlist","exclude":["-"],"order": [{"buyer_winner_count": "desc"}],"size": 3},"aggs": { "buyer_winner_count": {"filter":{"match_all":{}}}}}}}`
 
 	//中标单位
 	//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"},"aggs": {"amount": {"sum": {"field": "sortprice"}}}}`
 	winner_procurement_scale = `"winner_amount_distribution": {"terms": {"field": "entidlist","order": [{"amount": "desc"}],"size":100000},"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"}}}}}}`
+	winner_sortprice = `"winner_amount_top3": {"terms": {"field": "entidlist","exclude":["-"],"order": [{"s_winner_amount": "desc"}],"size": 30},"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"}}}}}}`
 	//中标单位(数量)
 	//winner_count = `"winner_count_top3": {"terms": {"field": "s_winner","order": [{"s_winner_count": "desc"}],"size": 3},"aggs": {"s_winner_count": {"cardinality": {"field": "s_winner"}},"buyer_top": {"terms": {"field": "buyer","order": [{"buyer_winner_count": "desc"}],"size": 3},"aggs": {"buyer_winner_count": {"cardinality": {"field": "buyer"}}}}}}`
-	winner_count = `"winner_count_top3": {"terms": {"field": "entidlist","exclude":["-"],"order": [{"s_winner_count": "desc"}],"size": 3},"aggs": {"s_winner_count": {"filter":{"match_all":{}}},"buyer_top": {"terms": {"field": "buyer","order": [{"buyer_winner_count": "desc"}],"size": 3},"aggs": {"buyer_winner_count": {"filter":{"match_all":{}}}}}}}`
+	winner_count = `"winner_count_top3": {"terms": {"field": "entidlist","exclude":["-"],"order": [{"s_winner_count": "desc"}],"size": 30},"aggs": {"s_winner_count": {"filter":{"match_all":{}}},"buyer_top": {"terms": {"field": "buyer","order": [{"buyer_winner_count": "desc"}],"size": 3},"aggs": {"buyer_winner_count": {"filter":{"match_all":{}}}}}}}`
 )
 
 var y_m_day = map[int]int{1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31}
@@ -313,7 +313,7 @@ func (mae *MarketAnalysisEntity) MarketTime() (map[string]interface{}, error) {
 
 	n_mae.FormatParam.STime = n_stime
 	finalSql := fmt.Sprintf(n_mae.GetCommonQuerySqlWithAggs(), strings.Join(sql, ","))
-	//log.Printf("final marketScaleRefineQuery sql: %s", finalSql)
+	log.Printf("final marketScaleRefineQuery sql: %s", finalSql)
 	rMap := make(map[string]interface{})
 	rMapData := make(map[string]interface{})
 	thisRow := marketTime{}

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

@@ -12,7 +12,7 @@ import (
 
 const (
 	query_aggs_sortprice       = `"sortprice_ranges": {"range":{"field":"sortprice","ranges":[%s]},"aggs":{"sum_sortprice":{"sum":{"field":"sortprice"}}}}`
-	aggs_area                  = `"area_distribution": {"terms": {"field": "area","size": 40},"aggs": {"area_amount": {"sum": {"field": "sortprice"}},"area_total": {"filter": {"match_all":{}}}}}`
+	aggs_area                  = `"area_distribution": {"terms": {"field": "area","size": 40},"aggs": {"area_amount": {"sum": {"field": "sortprice"}},"area_total": {"filter": {"match_all":{}}},"city_group": {"terms": {"field": "city","size": 40},"aggs": {"city_amount": {"sum": {"field": "sortprice"}}}}}}`
 	query_top10                = `,"sort": [{"sortprice": "desc"}],"from": 0,"size": 10`
 	aggs_area_amounttop3       = `"area_amount_top3":{"terms":{"field":"area","exclude":["全国"],"order":[{"area_amount":"desc"}],"size":3},"aggs":{"area_amount":{"sum":{"field":"sortprice"}},"winner_top":{"terms":{"field":"entidlist","exclude": ["-"],"order":[{"area_winner_amount":"desc"}],"size":3},"aggs":{"area_winner_amount":{"sum":{"field":"sortprice"}}}}}}`
 	aggs_area_counttop3        = `"area_count_top3":{"terms":{"field":"area","exclude":["全国"],"order":[{"area_count":"desc"}],"size":3},"aggs":{"area_count":{"filter":{"match_all":{}}},"winner_top":{"terms":{"field":"entidlist","exclude": ["-"],"order":[{"area_winner_count":"desc"}],"size":3},"aggs":{"area_winner_count":{"filter":{"match_all":{}}}}}}}`
@@ -53,6 +53,15 @@ type AreaCTop struct {
 			BuyclassAmount struct {
 				Value float64 `json:"value"`
 			} `json:"buyerclass_amount"`
+			CityGroup struct {
+				Buckets []struct {
+					City       string `json:"key"`
+					CityTotal  int64  `json:"doc_count"`
+					CityAmount struct {
+						Value float64 `json:"value"`
+					} `json:"city_amount"`
+				}
+			} `json:"city_group"`
 		}
 	} `json:"area_distribution"`
 	BuyerclassScale struct {
@@ -207,9 +216,9 @@ func (mae *MarketAnalysisEntity) AllData() (rMap map[string]interface{}, err err
 	area := mae.FormatParam.Area
 	city := mae.FormatParam.City
 	buyclass := mae.FormatParam.BuyerClass
-	aggs = append(aggs, aggs_all_c_m, fmt.Sprintf(query_aggs_sortprice, sortprice_str))
+	aggs = append(aggs, aggs_all_c_m, fmt.Sprintf(query_aggs_sortprice, sortprice_str), aggs_area)
 	if (len(area) + len(city)) != 1 {
-		aggs = append(aggs, aggs_area, aggs_area_amounttop3, aggs_area_counttop3)
+		aggs = append(aggs, aggs_area_amounttop3, aggs_area_counttop3)
 	}
 	if len(buyclass) != 1 {
 		aggs = append(aggs, aggs_buyerclass, aggs_buyerclass_other, aggs_buyerclass_amounttop3, aggs_buyerclass_counttop3)
@@ -409,6 +418,17 @@ func AreaDistribute(thisRow AreaCTop) (data []map[string]interface{}) {
 		rM["area"] = v.Area
 		rM["total"] = v.AreaTotal
 		rM["amount"] = v.AreaAmount.Value
+		var rmc []map[string]interface{}
+		if len(v.CityGroup.Buckets) > 0 {
+			for _, c := range v.CityGroup.Buckets {
+				rmc = append(rmc, map[string]interface{}{
+					"city":   c.City,
+					"total":  c.CityTotal,
+					"amount": c.CityAmount.Value,
+				})
+			}
+			rM["areaDetails"] = rmc
+		}
 		data = append(data, rM)
 	}
 	return

+ 108 - 15
src/jfw/modules/bigmember/src/entity/marketAnalysis/marketAnalysisEntity.go

@@ -1,18 +1,19 @@
 package marketAnalysis
 
 import (
-	"jy/src/jfw/modules/bigmember/src/config"
-	"jy/src/jfw/modules/bigmember/src/db"
-	"encoding/json"
-	"fmt"
-	"log"
-	"app.yhyue.com/moapp/jybase/mongodb"
 	qutil "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/encrypt"
 	elastic "app.yhyue.com/moapp/jybase/es"
+	"app.yhyue.com/moapp/jybase/mongodb"
 	"app.yhyue.com/moapp/jybase/redis"
+	"encoding/json"
+	"fmt"
+	"jy/src/jfw/modules/bigmember/src/config"
+	"jy/src/jfw/modules/bigmember/src/db"
+	"jy/src/jfw/modules/bigmember/src/util"
+	"log"
 	"strings"
 	"time"
-	"jy/src/jfw/modules/bigmember/src/util"
 )
 
 const (
@@ -38,7 +39,7 @@ func init() {
 	}
 }
 
-//AnalysisRequestParam 接口原请求参数
+// AnalysisRequestParam 接口原请求参数
 type AnalysisRequestParam struct {
 	KeysItemsStr   string //分析内容【字符串】结构和o_member_jy.a_items保持一致
 	RangeTime      string //时间【字符串】 时间戳开始-结束时间戳
@@ -46,6 +47,12 @@ type AnalysisRequestParam struct {
 	Area           string //省份【对象字符串】
 	Industry       string //行业【对象字符串】
 	BuyerClass     string //采购单位类型【字符串】多个采购单位类型用逗号拼接
+	Buyer          string //采购单位
+	Winner         string //中标单位
+	Sort           int    //排序:默认0:成交时间倒序;1:项目金额倒序
+	PageSize       int    //默认每页10条
+	PageNum        int    //默认当前第一页
+	IsDetail       bool   //是否是项目明细请求
 }
 
 type viewKeyWord struct {
@@ -55,20 +62,25 @@ type viewKeyWord struct {
 	MatchWay int      `json:"matchway"`  //匹配模式
 }
 
-//keyWordGroup 订阅词结构体
+// keyWordGroup 订阅词结构体
 type keyWordGroup struct {
 	A_Key      []viewKeyWord `json:"a_key"`
 	ItemName   string        `json:"s_item"`
 	UpdateTime int64         `json:"updatetime"`
 }
 
-//AnalysisRequestFormat 格式化后参数
+// AnalysisRequestFormat 格式化后参数
 type AnalysisRequestFormat struct {
 	KeysItems    []keyWordGroup
 	Area, City   []string //省份城市
 	STime, ETime int64    //开始结束时间
 	Industry     []string //行业
 	BuyerClass   []string //采购单位类型
+	Buyer        string   //采购单位
+	Winner       string   //中标单位
+	Sort         int      //排序:默认0:成交时间倒序;1:项目金额倒序
+	PageSize     int      //默认每页10条
+	PageNum      int      //默认当前第一页
 }
 
 type MarketAnalysisEntity struct {
@@ -76,9 +88,29 @@ type MarketAnalysisEntity struct {
 	BaseParam   AnalysisRequestParam
 	FormatParam AnalysisRequestFormat
 	UId, Pid    string
+	ProjectInfo projectInfo
 }
 
-//ForMatData 获取格式化请求参数
+type projectInfo struct {
+	Count int64
+	List  []ProjectList
+}
+
+type ProjectList struct {
+	Name       string   `json:"name"`       //项目名称
+	Id         string   `json:"id"`         //项目id
+	Area       string   `json:"area"`       //地区
+	DealTime   int64    `json:"dealTime"`   //成交时间
+	BidStatus  string   `json:"bidStatus"`  //项目类型
+	BuyerClass string   `json:"buyerClass"` //采购单位类型
+	Winner     []string `json:"winner"`     //中标单位
+	WinnerId   []string `json:"winnerId"`   //中标单位id
+	Buyer      string   `json:"buyer"`      //采购单位
+	BidAmount  float64  `json:"bidAmount"`  //中标金额
+	Budget     float64  `json:"budget"`     //预算
+}
+
+// ForMatData 获取格式化请求参数
 func (mae *MarketAnalysisEntity) ForMatData() error {
 	//格式化订阅词
 	if err := json.Unmarshal([]byte(mae.BaseParam.KeysItemsStr), &mae.FormatParam.KeysItems); err != nil {
@@ -134,10 +166,71 @@ func (mae *MarketAnalysisEntity) ForMatData() error {
 	if buyerClassStr := strings.TrimSpace(mae.BaseParam.BuyerClass); buyerClassStr != "" {
 		mae.FormatParam.BuyerClass = strings.Split(buyerClassStr, ",")
 	}
+	//中标企业
+	mae.FormatParam.Winner = mae.BaseParam.Winner
+	//采购单位
+	mae.FormatParam.Buyer = mae.BaseParam.Buyer
+	//排序
+	mae.FormatParam.Sort = qutil.If(mae.BaseParam.Sort != 0 && mae.BaseParam.Sort != 1, 0, mae.BaseParam.Sort).(int)
+	if mae.BaseParam.PageNum*mae.BaseParam.PageSize > config.Config.ProjectCount {
+		mae.BaseParam.PageNum = config.Config.ProjectCount / mae.BaseParam.PageSize
+	}
+	//当前页码
+	mae.FormatParam.PageNum = qutil.If(mae.BaseParam.PageNum < 1 || mae.BaseParam.PageNum > 1000, 1, mae.BaseParam.PageNum).(int)
+	//默认每页10条
+	mae.FormatParam.PageSize = qutil.If(mae.BaseParam.PageSize < 1 || mae.BaseParam.PageSize > 100, 50, mae.BaseParam.PageSize).(int)
+	return nil
+}
+
+// GetProjectInfoList 项目明细
+func (mae *MarketAnalysisEntity) GetProjectInfoList() error {
+	var (
+		queryDefault = `,"sort": [{%s}],"from": %d,"size": %d`
+		start        = (mae.FormatParam.PageNum - 1) * mae.FormatParam.PageSize
+		sort         = `"jgtime": "desc"`
+	)
+	if mae.FormatParam.Sort > 0 {
+		sort = `"bidamount": "desc","budget": "desc"`
+	}
+	countSql := fmt.Sprintf(mae.GetCommonQuerySql(), "")
+	queryDefault = fmt.Sprintf(queryDefault, sort, start, mae.FormatParam.PageSize)
+	finalSql := fmt.Sprintf(mae.GetCommonQuerySql(), queryDefault)
+	log.Println("finalSql:", finalSql)
+	count, hits := elastic.GetWithCount("projectset", "projectset", countSql, finalSql)
+	//hits, count := elastic.GetOA("projectset", "projectset", finalSql)
+	if count > 0 {
+		mae.ProjectInfo.Count = count
+		source := *hits
+		for _, v := range source {
+			var winnerIdArr []string
+			if qutil.ObjToString(v["s_winner"]) != "" && v["entidlist"] != nil {
+				idObjs, _ := v["entidlist"].([]interface{})
+				for _, v := range qutil.ObjArrToStringArr(idObjs) {
+					if v != "" && v != "-" {
+						v = encrypt.EncodeArticleId2ByCheck(v)
+					}
+					winnerIdArr = append(winnerIdArr, v)
+				}
+			}
+			mae.ProjectInfo.List = append(mae.ProjectInfo.List, ProjectList{
+				Name:       qutil.ObjToString(v["projectname"]),
+				Id:         encrypt.EncodeArticleId2ByCheck(qutil.ObjToString(v["id"])),
+				Area:       qutil.ObjToString(v["area"]),
+				DealTime:   qutil.Int64All(v["jgtime"]), //截止时间
+				BidStatus:  qutil.ObjToString(v["bidstatus"]),
+				BuyerClass: qutil.ObjToString(v["buyerclass"]),
+				Winner:     strings.Split(qutil.ObjToString(v["s_winner"]), ","),
+				WinnerId:   winnerIdArr,
+				Buyer:      qutil.ObjToString(v["buyer"]),
+				BidAmount:  qutil.Float64All(v["bidamount"]), //中标金额
+				Budget:     qutil.Float64All(v["budget"]),    //预算
+			})
+		}
+	}
 	return nil
 }
 
-//SaveAnalysisRecord 保存分析记录
+// SaveAnalysisRecord 保存分析记录
 func (mae *MarketAnalysisEntity) SaveAnalysisRecord() error {
 	mae.MgoRecordId = db.Mgo.Save(ReportHistoryTable, map[string]interface{}{
 		"s_keysItems":      mae.BaseParam.KeysItemsStr,
@@ -156,7 +249,7 @@ func (mae *MarketAnalysisEntity) SaveAnalysisRecord() error {
 	return nil
 }
 
-//GetAnalysisFromMgoDb 从数据库中获取分析记录
+// GetAnalysisFromMgoDb 从数据库中获取分析记录
 func (mae *MarketAnalysisEntity) GetAnalysisFromMgoDb() error {
 	if mae.MgoRecordId == "" {
 		return fmt.Errorf("缺少参数")
@@ -199,7 +292,7 @@ func (mae *MarketAnalysisEntity) removeEmptyRecord() {
 	//log.Println("删除空报告", queryMap)
 }
 
-//GetRecordList 获取分析记录
+// GetRecordList 获取分析记录
 func (mae *MarketAnalysisEntity) GetRecordList(pageNum, PageSize int) (total int, list []map[string]interface{}) {
 	queryMap := map[string]interface{}{
 		"i_del": map[string]interface{}{"$ne": 1},
@@ -248,7 +341,7 @@ func (mae *MarketAnalysisEntity) getQueryItem() (map[string]interface{}, error)
 	}, nil
 }
 
-//GetPartResult 分块儿获取报告内容
+// GetPartResult 分块儿获取报告内容
 func (mae *MarketAnalysisEntity) GetPartResult(flag int) (map[string]interface{}, error) {
 	defer qutil.Catch()
 	if flag == marketQueryItem { //返回查询内容

+ 213 - 0
src/jfw/modules/bigmember/src/entity/report.go

@@ -0,0 +1,213 @@
+package entity
+
+import (
+	"app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/encrypt"
+	"fmt"
+	"jy/src/jfw/modules/bigmember/src/db"
+	"strings"
+)
+
+const (
+	TableMemberReportProject = "member_report_project" // 大会员周报月报-项目明细表
+)
+
+type ReportProjectInfoParam struct {
+	Items      []string            `json:"items"`      // 订阅关键词组
+	Area       map[string][]string `json:"area"`       // 省份城市
+	Industry   map[string][]string `json:"industry"`   // 行业
+	BuyerClass []string            `json:"buyerClass"` // 采购单位类型
+	Buyer      string              `json:"buyer"`      // 采购单位
+	Winner     string              `json:"winner"`     // 中标单位
+	Sort       int                 `json:"sort"`       // 排序默认0:项目更新时间倒序;1:项目金额倒序
+	Start      int                 `json:"start"`      // 开始时间
+	End        int                 `json:"end"`        // 结束时间
+	PageSize   int                 `json:"pageSize"`   // 默认每页10条
+	PageNum    int                 `json:"pageNum"`    // 默认当前第一页
+}
+
+// GetReportProjectInfo 周报/月报查询项目明细
+func GetReportProjectInfo(param *ReportProjectInfoParam, positionId int64) (data []map[string]interface{}, total int64) {
+	data = []map[string]interface{}{}
+	// 处理查询条件
+	q := ""
+	values := []interface{}{positionId, param.Start, param.End} // 用于最后sql查询传的值
+	qstr := []string{}                                          // 用于后边拼接查询条件
+	if param.Items != nil && len(param.Items) > 0 {
+		tmpArr := []string{}
+		for i := 0; i < len(param.Items); i++ {
+			tmpArr = append(tmpArr, "find_in_set(?,items)")
+			values = append(values, param.Items[i])
+		} // 关键词组
+		qstr = append(qstr, fmt.Sprintf("(%s)", strings.Join(tmpArr, " or ")))
+	}
+	// 省份
+	if param.Area != nil && len(param.Area) > 0 {
+		area, city := []interface{}{}, []interface{}{} // 存值
+		areaS, cityS := []string{}, []string{}         // 存占位符
+		for k, v := range param.Area {
+			if len(v) == 0 { // 省份
+				area = append(area, k)
+				areaS = append(areaS, "?")
+			} else { // 城市
+				for i := 0; i < len(v); i++ {
+					city = append(city, v[i])
+					cityS = append(cityS, "?")
+				}
+			}
+		}
+		area_ := []string{}
+		if len(areaS) > 0 {
+			area_ = append(area_, fmt.Sprintf("area in (%s)", strings.Join(areaS, ","))) // 处理省份语句
+			values = append(values, area...)
+		}
+		if len(cityS) > 0 {
+			area_ = append(area_, fmt.Sprintf("city in (%s)", strings.Join(cityS, ","))) // 处理省份语句
+			values = append(values, city...)
+		}
+		qstr = append(qstr, fmt.Sprintf("(%s)", strings.Join(area_, " or ")))
+	}
+	//  行业
+	if param.Industry != nil && len(param.Industry) > 0 {
+		// 行业 {"水利水电":["水利工程","发电工程","航运工程","其他工程"]} sql中处理成 "水利水电_水利工程"
+		tmpArr := []string{}
+		for topIndustry, subList := range param.Industry {
+			for i := 0; i < len(subList); i++ {
+				tmpArr = append(tmpArr, "find_in_set(?,subscopeclass)")
+				values = append(values, fmt.Sprintf("%s_%s", topIndustry, subList[i]))
+			}
+		}
+		qstr = append(qstr, fmt.Sprintf("(%s)", strings.Join(tmpArr, " or ")))
+	}
+	// 采购单位类型
+	if param.BuyerClass != nil && len(param.BuyerClass) > 0 {
+		tmpArr := []string{}
+		for i := 0; i < len(param.BuyerClass); i++ {
+			tmpArr = append(tmpArr, "?")
+			values = append(values, param.BuyerClass[i])
+		}
+		qstr = append(qstr, fmt.Sprintf("buyerclass in (%s)", strings.Join(tmpArr, ",")))
+	}
+	// 采购单位
+	if param.Buyer != "" {
+		qstr = append(qstr, "buyer like ?")
+		values = append(values, fmt.Sprintf("%%%s%%", param.Buyer))
+	}
+	// 中标单位
+	if param.Winner != "" {
+		qstr = append(qstr, "winner like ?")
+		values = append(values, fmt.Sprintf("%%%s%%", param.Winner))
+	}
+	if len(qstr) > 0 {
+		q = " and "
+	}
+	q += strings.Join(qstr, " and ")
+	// 查询数量
+	CountQuery := fmt.Sprintf("select count(1) from %s where position_id=? and start_time>=? and end_time<=? %s ", TableMemberReportProject, q)
+	total = db.Base.CountBySql(CountQuery, values...)
+	if total == 0 {
+		return data, 0
+	}
+	orderby := "last_time desc,id desc"
+	if param.Sort == 1 {
+		orderby = " (if(bidamount >0,bidamount,budget)) desc,id desc"
+	}
+	query := fmt.Sprintf("select * from %s where position_id=? and start_time>=? and end_time<=? %s  order by  %s   limit %d,%d", TableMemberReportProject, q, orderby, (param.PageNum-1)*param.PageSize, param.PageSize)
+	rs := db.Base.SelectBySql(query, values...)
+	if rs != nil && len(*rs) > 0 {
+		data = *rs
+	}
+	return data, total
+}
+
+// ReportProjectInfoFormat 周报/月报 项目明细 格式化数据
+func ReportProjectInfoFormat(data []map[string]interface{}) []map[string]interface{} {
+	rs := []map[string]interface{}{}
+	for i := 0; i < len(data); i++ {
+		tmp := map[string]interface{}{}
+		tmpWinner := common.ObjToString(data[i]["winner"])
+		tmpWinnerId := common.ObjToString(data[i]["winner_id"])
+		// 中标id 加密
+		splitWinnerId := strings.Split(tmpWinnerId, ",")
+		winIdArr := []string{}
+		for j := 0; j < len(splitWinnerId); j++ {
+			if splitWinnerId[j] != "" {
+				splitWinnerId[j] = encrypt.EncodeArticleId2ByCheck(splitWinnerId[j])
+			}
+			winIdArr = append(winIdArr, splitWinnerId[j])
+		}
+		tmp["id"] = encrypt.EncodeArticleId2ByCheck(common.ObjToString(data[i]["source_infoid"]))
+		tmp["winnerId"] = winIdArr
+		tmp["winner"] = strings.Split(tmpWinner, ",")
+		tmp["name"] = common.ObjToString(data[i]["name"])
+		tmp["area"] = data[i]["area"]
+		tmp["bidStatus"] = data[i]["bidstatus"]
+		tmp["buyerClass"] = data[i]["buyerclass"]
+		tmp["bidAmount"] = data[i]["bidamount"]
+		tmp["budget"] = data[i]["budget"]
+		tmp["buyer"] = data[i]["buyer"]
+		tmp["lastTime"] = data[i]["last_time"]
+		rs = append(rs, tmp)
+	}
+	return rs
+}
+
+// ReportGetArea 周报月报获取当前订阅地区
+func ReportGetArea(positionId, start, end int64) map[string]interface{} {
+	q := "SELECT area,group_concat(distinct(city)) as city from " + TableMemberReportProject + " where position_id =? and start_time >=? and end_time<=? and area!='全国' group by area;"
+	rs := db.Base.SelectBySql(q, positionId, start, end)
+	areaMap := map[string]interface{}{}
+	if rs != nil && len(*rs) > 0 {
+		for i := 0; i < len(*rs); i++ {
+			area := common.ObjToString((*rs)[i]["area"])
+			if area == "" {
+				continue
+			}
+			city := []string{}
+			citySplitArr := strings.Split(common.ObjToString((*rs)[i]["city"]), ",")
+			for j := 0; j < len(citySplitArr); j++ {
+				if citySplitArr[j] != "" {
+					city = append(city, citySplitArr[j])
+				}
+			}
+			areaMap[area] = city
+		}
+	}
+	return areaMap
+}
+
+// ReportGetBuyerClass 周报月报获取当前采购单位类型
+func ReportGetBuyerClass(positionId, start, end int64) []string {
+	buyerClass := []string{}
+	q := "select distinct(buyerclass) from " + TableMemberReportProject + " where position_id =? and start_time >=? and end_time<=?  order by buyerclass "
+	rs := db.Base.SelectBySql(q, positionId, start, end)
+	if rs != nil && len(*rs) > 0 {
+		for i := 0; i < len(*rs); i++ {
+			buyerClass = append(buyerClass, common.ObjToString((*rs)[i]["buyerclass"]))
+		}
+	}
+	return buyerClass
+}
+
+// GetMainPositionId 根据用户id获取主账号的职位id
+func GetMainPositionId(mgoUserId string) (positionId int64) {
+	// 1. 查主账号的base_user_id
+	// 查主账号的id
+	rs, b := db.Mgo.FindById("user", mgoUserId, `{"s_member_mainid":1}`)
+	if !b || rs == nil || len(*rs) == 0 || (*rs)["s_member_mainid"] == nil {
+		return 0
+	}
+	mainMgoId := common.ObjToString((*rs)["s_member_mainid"])
+	// 2. 根据base_user_id 查 base_position  取到position_id
+	mainRs, b := db.Mgo.FindById("user", mainMgoId, `{"base_user_id":1}`)
+	if !b || mainRs == nil || len(*mainRs) == 0 || (*mainRs)["base_user_id"] == nil {
+		return 0
+	}
+	mainBaseUserId := common.IntAll((*mainRs)["base_user_id"])
+	q := "SELECT id FROM base_service.base_position where user_id=?"
+	baseRs := db.Base.SelectBySql(q, mainBaseUserId)
+	if baseRs != nil && len(*baseRs) > 0 {
+		positionId = common.Int64All((*baseRs)[0]["id"])
+	}
+	return
+}

+ 7 - 8
src/jfw/modules/bigmember/src/go.mod

@@ -3,14 +3,14 @@ module jy/src/jfw/modules/bigmember/src
 go 1.20
 
 require (
-	app.yhyue.com/moapp/jybase v0.0.0-20230511020847-9b0fbc33ff1c
+	app.yhyue.com/moapp/jybase v0.0.0-20230523020646-528a068dac39
 	app.yhyue.com/moapp/jylog v0.0.0-20230522075550-05d7230ca545
-	app.yhyue.com/moapp/jypkg v0.0.0-20230506115817-6f55523ae3f1
+	app.yhyue.com/moapp/jypkg v0.0.0-20230531014856-12e9a04b5c44
 	bp.jydev.jianyu360.cn/BaseService/userCenter v1.2.13
-	github.com/donnie4w/go-logger v0.0.0-20170827050443-4740c51383f4
-	github.com/gogf/gf/v2 v2.0.6
-	github.com/olivere/elastic/v7 v7.0.22
-	go.mongodb.org/mongo-driver v1.11.1
+	github.com/donnie4w/go-logger v0.0.0-20230316073421-36a48f87a69a
+	github.com/gogf/gf/v2 v2.4.2
+	github.com/olivere/elastic/v7 v7.0.32
+	go.mongodb.org/mongo-driver v1.11.6
 )
 
 require (
@@ -20,7 +20,7 @@ require (
 	bp.jydev.jianyu360.cn/BaseService/entManageApplication v0.0.0-20230214091519-89a98c01ab0e // indirect
 	bp.jydev.jianyu360.cn/BaseService/powerCheckCenter v0.0.0-20230222052351-9d6fad062447 // indirect
 	bp.jydev.jianyu360.cn/BaseService/resourceCenter v0.0.7 // indirect
-	github.com/BurntSushi/toml v0.4.1 // indirect
+	github.com/BurntSushi/toml v1.1.0 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/cenkalti/backoff/v4 v4.2.1 // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
@@ -57,7 +57,6 @@ require (
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/klauspost/compress v1.15.11 // indirect
-	github.com/longbridgeapp/sqlparser v0.3.1 // indirect
 	github.com/magiconair/properties v1.8.7 // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect
 	github.com/mattn/go-colorable v0.1.12 // indirect

+ 17 - 11
src/jfw/modules/bigmember/src/go.sum

@@ -5,12 +5,12 @@ app.yhyue.com/moapp/jyMarketing v0.0.2-0.20230304035551-21bb1eedf547/go.mod h1:J
 app.yhyue.com/moapp/jyPoints v1.1.1/go.mod h1:SvP8p5L3jGrejHiH2LXfgCg/NPlFiKBC5Yd0gsI12FU=
 app.yhyue.com/moapp/jybase v0.0.0-20220427020729-974c1a148186/go.mod h1:qNRA0sHuYqcLoYoP8irpaWnW9YsXixe6obBIkwaXpD0=
 app.yhyue.com/moapp/jybase v0.0.0-20230117032034-ad7c00ffe11a/go.mod h1:zB47XTeJvpcbtBRYgkQuxOICWNexiZfbUO+7aUf6mNs=
-app.yhyue.com/moapp/jybase v0.0.0-20230511020847-9b0fbc33ff1c h1:bYfxHP2uLcQlnsLuJSFHsvDpPTcEVqBgNOZ6E1B+Fl8=
-app.yhyue.com/moapp/jybase v0.0.0-20230511020847-9b0fbc33ff1c/go.mod h1:zB47XTeJvpcbtBRYgkQuxOICWNexiZfbUO+7aUf6mNs=
+app.yhyue.com/moapp/jybase v0.0.0-20230523020646-528a068dac39 h1:Cr68N8jdrNskP2fBhFhFGJhPlyt7H6o44fu8ob5nBVs=
+app.yhyue.com/moapp/jybase v0.0.0-20230523020646-528a068dac39/go.mod h1:zB47XTeJvpcbtBRYgkQuxOICWNexiZfbUO+7aUf6mNs=
 app.yhyue.com/moapp/jylog v0.0.0-20230522075550-05d7230ca545 h1:+Lak4m1zgsigQloOsvp8AJ+0XeX/+PGp9QP550xlbBQ=
 app.yhyue.com/moapp/jylog v0.0.0-20230522075550-05d7230ca545/go.mod h1:uFrsdUBFbETiJlEmr4PtJWPsZlUpPj2bHQRhryu6ggk=
-app.yhyue.com/moapp/jypkg v0.0.0-20230506115817-6f55523ae3f1 h1:d5VcH9qiJbFPypLNj42/d+bQ0webGqODZ1ALlBCWSso=
-app.yhyue.com/moapp/jypkg v0.0.0-20230506115817-6f55523ae3f1/go.mod h1:1QozRpU+mHTRhIYwrXemUt3sXSBWQRWZerqBwoHsBVM=
+app.yhyue.com/moapp/jypkg v0.0.0-20230531014856-12e9a04b5c44 h1:u7Y263EJvcCZDqJTwOfT+QkVQ6sJ/ZCBZxejEk8H9cI=
+app.yhyue.com/moapp/jypkg v0.0.0-20230531014856-12e9a04b5c44/go.mod h1:Ize93SJEPkBR0Tz8PM2KTJK3bpzlD/qp1JwJ4kdmlss=
 app.yhyue.com/moapp/message v0.0.0-20221223100203-6402e389d9ae h1:6rDDaz6yxvE8viTSzEBwKYOFWq14TMfuBivSazUZMz4=
 app.yhyue.com/moapp/message v0.0.0-20221223100203-6402e389d9ae/go.mod h1:b0zZHev3gmJao1Fo+2Z2KPVjsuLOJVvVxf+kCnu9WkA=
 bp.jydev.jianyu360.cn/BaseService/entManageApplication v0.0.0-20230214091519-89a98c01ab0e h1:h+VEI3o1qC0jeCzkFGTrLI4f27cfa/W/y+0sXokWMgE=
@@ -395,8 +395,9 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935
 github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
 github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
 github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
+github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/ClickHouse/clickhouse-go v1.4.3/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
 github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
@@ -495,8 +496,9 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
 github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
-github.com/donnie4w/go-logger v0.0.0-20170827050443-4740c51383f4 h1:T9PR91sjTtrA1HmZB4G+M7OLCelch0f6rIEY7Mm1T4U=
 github.com/donnie4w/go-logger v0.0.0-20170827050443-4740c51383f4/go.mod h1:L7S4x0R7vv3xoOhGuyAJyCO2MYzWOpccM4Isn8jIUgY=
+github.com/donnie4w/go-logger v0.0.0-20230316073421-36a48f87a69a h1:gXZfDEfrtcyyohaFVDBCVA7SjsAGJqr/aDQz26+4eDg=
+github.com/donnie4w/go-logger v0.0.0-20230316073421-36a48f87a69a/go.mod h1:/soYK7VeLIgdBS9B1+V+hZ2pffgKOyYSRHaBV+nj8xY=
 github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
 github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
@@ -534,6 +536,7 @@ github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
+github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
 github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
 github.com/fullstorydev/grpcurl v1.8.7/go.mod h1:pVtM4qe3CMoLaIzYS8uvTuDj2jVYmXqMUkZeijnXp/E=
@@ -587,7 +590,6 @@ github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ
 github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
-github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M=
 github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
 github.com/go-xorm/builder v0.3.4/go.mod h1:KxkQkNN1DpPKTedxXyTQcmH+rXfvk4LZ9SOOBoZBAxw=
 github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
@@ -620,8 +622,9 @@ github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
-github.com/gogf/gf/v2 v2.0.6 h1:2etb4FMpbQKWIJO+UjtIWrZUp01HUsFb6Po8pgizAWk=
 github.com/gogf/gf/v2 v2.0.6/go.mod h1:8uYzw7qNzuq8vrhVlWke1b1925FFqOJIgmyYW1sr/0M=
+github.com/gogf/gf/v2 v2.4.2 h1:31ekx+YKisG84/iEC2Ih6lB+g92+sB9R+VrfIbqfpac=
+github.com/gogf/gf/v2 v2.4.2/go.mod h1:tsbmtwcAl2chcYoq/fP9W2FZf06aw4i89X34nbSHo9Y=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
@@ -897,8 +900,8 @@ github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
-github.com/longbridgeapp/sqlparser v0.3.1 h1:iWOZWGIFgQrJRgobLXUNJdvqGRpbVXkyKUKUA5CNJBE=
 github.com/longbridgeapp/sqlparser v0.3.1/go.mod h1:GIHaUq8zvYyHLCLMJJykx1CdM6LHtkUih/QaJXySSx4=
+github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
 github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
 github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
 github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -969,8 +972,9 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N
 github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
 github.com/olivere/elastic v6.2.37+incompatible h1:UfSGJem5czY+x/LqxgeCBgjDn6St+z8OnsCuxwD3L0U=
 github.com/olivere/elastic v6.2.37+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8=
-github.com/olivere/elastic/v7 v7.0.22 h1:esBA6JJwvYgfms0EVlH7Z+9J4oQ/WUADF2y/nCNDw7s=
 github.com/olivere/elastic/v7 v7.0.22/go.mod h1:VDexNy9NjmtAkrjNoI7tImv7FR4tf5zUA3ickqu5Pc8=
+github.com/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E=
+github.com/olivere/elastic/v7 v7.0.32/go.mod h1:c7PVmLe3Fxq77PIfY/bZmxY/TAamBhCzZ8xDOE09a9k=
 github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -1195,8 +1199,9 @@ go.etcd.io/etcd/client/v3 v3.5.6/go.mod h1:f6GRinRMCsFVv9Ht42EyY7nfsVGwrNO0WEoS2
 go.mongodb.org/mongo-driver v1.5.0/go.mod h1:boiGPFqyBs5R0R5qf2ErokGRekMfwn+MqKaUyHs7wy0=
 go.mongodb.org/mongo-driver v1.9.0/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY=
 go.mongodb.org/mongo-driver v1.9.1/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY=
-go.mongodb.org/mongo-driver v1.11.1 h1:QP0znIRTuL0jf1oBQoAoM0C6ZJfBK4kx0Uumtv1A7w8=
 go.mongodb.org/mongo-driver v1.11.1/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8=
+go.mongodb.org/mongo-driver v1.11.6 h1:XM7G6PjiGAO5betLF13BIa5TlLUUE3uJ/2Ox3Lz1K+o=
+go.mongodb.org/mongo-driver v1.11.6/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY=
 go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
@@ -1234,6 +1239,7 @@ go.opentelemetry.io/otel/exporters/zipkin v1.15.1 h1:B6s/o48bx00ayJu7F+jIMJfhPTy
 go.opentelemetry.io/otel/exporters/zipkin v1.15.1/go.mod h1:EjjV7/YfYXG+khxCOfG6PPeRGoOmtcSusyW66qPqpRQ=
 go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM=
 go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs=
+go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU=
 go.opentelemetry.io/otel/sdk v1.8.0/go.mod h1:uPSfc+yfDH2StDM/Rm35WE8gXSNdvCg023J6HeGNO0c=
 go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE=
 go.opentelemetry.io/otel/sdk v1.15.1 h1:5FKR+skgpzvhPQHIEfcwMYjCBr14LWzs3uSqKiQzETI=

+ 506 - 506
src/jfw/modules/bigmember/src/service/analysis/forecastwinner.go

@@ -8,26 +8,26 @@
 package analysis
 
 import (
-	"encoding/json"
-	"errors"
-	"fmt"
-	. "jy/src/jfw/modules/bigmember/src/config"
-	"jy/src/jfw/modules/bigmember/src/db"
-	"jy/src/jfw/modules/bigmember/src/entity"
-	"jy/src/jfw/modules/bigmember/src/util"
-	"log"
-	"regexp"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
+    "encoding/json"
+    "errors"
+    "fmt"
+    . "jy/src/jfw/modules/bigmember/src/config"
+    "jy/src/jfw/modules/bigmember/src/db"
+    "jy/src/jfw/modules/bigmember/src/entity"
+    "jy/src/jfw/modules/bigmember/src/util"
+    "log"
+    "regexp"
+    "strconv"
+    "strings"
+    "sync"
+    "time"
 
-	. "app.yhyue.com/moapp/jybase/api"
-	qutil "app.yhyue.com/moapp/jybase/common"
-	"app.yhyue.com/moapp/jybase/encrypt"
-	elastic "app.yhyue.com/moapp/jybase/es"
-	. "app.yhyue.com/moapp/jybase/mongodb"
-	"app.yhyue.com/moapp/jybase/redis"
+    . "app.yhyue.com/moapp/jybase/api"
+    qutil "app.yhyue.com/moapp/jybase/common"
+    "app.yhyue.com/moapp/jybase/encrypt"
+    elastic "app.yhyue.com/moapp/jybase/es"
+    . "app.yhyue.com/moapp/jybase/mongodb"
+    "app.yhyue.com/moapp/jybase/redis"
 )
 
 var redis_forecast_status = "forecast_status_" //预测状态
@@ -36,526 +36,526 @@ var redis_forecast_date = "forecast_date_"     //预测时间
 var forecast_time = 300                        //超过五分钟 预测失败 清记录
 var reg = regexp.MustCompile("^[0-9]+.*$")
 
-//中标预测-项目信息当前是否已完成招标
+// 中标预测-项目信息当前是否已完成招标
 func (this *Analysis) BdInfoStatus() {
-	defer qutil.Catch()
-	userId := qutil.ObjToString(this.GetSession("userId"))
-	rData, errMsg := func() (interface{}, error) {
-		pid := this.GetString("pid") //项目信息id
-		sid := this.GetString("sid") //招标信息id
-		var pids, sids []string
-		var isBool = false
-		if pid != "" {
-			pids = encrypt.DecodeArticleId2ByCheck(pid)
-			isBool = true
-		}
-		if sid != "" {
-			sids = encrypt.DecodeArticleId2ByCheck(sid)
-			isBool = true
-		}
-		if !isBool {
-			return nil, errors.New("项目信息id或招标信息id不能同时为空")
-		}
-		//log.Println("pids:", pids, "--sids:", sids)
-		var res = entity.GetProInfoById(pids, sids)
-		if res == nil || len(res) == 0 {
-			return nil, errors.New("未查询到此项目")
-		}
-		bidstatus := qutil.ObjToString(res[0]["bidstatus"])
-		if strings.Contains(bidstatus, "中标") || strings.Contains(bidstatus, "成交") || strings.Contains(bidstatus, "废标") || strings.Contains(bidstatus, "流标") {
-			return 1, nil
-		}
-		return 0, nil
-	}()
-	if errMsg != nil {
-		log.Printf("%s   获取此项目状态出错-%s", userId, errMsg)
-	}
-	this.ServeJson(NewResult(rData, errMsg))
+    defer qutil.Catch()
+    userId := qutil.ObjToString(this.GetSession("userId"))
+    rData, errMsg := func() (interface{}, error) {
+        pid := this.GetString("pid") //项目信息id
+        sid := this.GetString("sid") //招标信息id
+        var pids, sids []string
+        var isBool = false
+        if pid != "" {
+            pids = encrypt.DecodeArticleId2ByCheck(pid)
+            isBool = true
+        }
+        if sid != "" {
+            sids = encrypt.DecodeArticleId2ByCheck(sid)
+            isBool = true
+        }
+        if !isBool {
+            return nil, errors.New("项目信息id或招标信息id不能同时为空")
+        }
+        //log.Println("pids:", pids, "--sids:", sids)
+        var res = entity.GetProInfoById(pids, sids)
+        if res == nil || len(res) == 0 {
+            return nil, errors.New("未查询到此项目")
+        }
+        bidstatus := qutil.ObjToString(res[0]["bidstatus"])
+        if strings.Contains(bidstatus, "中标") || strings.Contains(bidstatus, "成交") || strings.Contains(bidstatus, "废标") || strings.Contains(bidstatus, "流标") {
+            return 1, nil
+        }
+        return 0, nil
+    }()
+    if errMsg != nil {
+        log.Printf("%s   获取此项目状态出错-%s", userId, errMsg)
+    }
+    this.ServeJson(NewResult(rData, errMsg))
 }
 
-//中标预测超时处理
+// 中标预测超时处理
 func (this *Analysis) FWOvertime() {
-	defer qutil.Catch()
-	userId, _ := this.GetSession("userId").(string)
-	//中标信息预测结束
-	go ClearRedisInfo(userId)
+    defer qutil.Catch()
+    userId, _ := this.GetSession("userId").(string)
+    //中标信息预测结束
+    go ClearRedisInfo(userId)
 }
 
-//预测数据
+// 预测数据
 func (this *Analysis) FWData() {
-	defer qutil.Catch()
-	var regMap = Result{
-		Data:       []map[string]interface{}{},
-		Error_code: Error_code,
-		Error_msg:  "",
-	}
-	if this.Method() == METHOD {
-		userId, _ := this.GetSession("userId").(string)
-		//有正在预测的数据或已预测未查看的数据
-		success, id := isExistsFIng(userId)
-		status := 0
-		if success {
-			if success && id != "" {
-				status = 1 //success=true; id!=""  ---未查看的预测数据
-			} else if success && id == "" {
-				status = 2 //success=true; id=""  ---正在预测
-			}
-			var getRes map[string]interface{}
-			if redis.GetNewInterface("other", redis_forecast_status+userId, &getRes) != nil {
-				log.Println("redis 1获取预测参数有误-", userId)
-			}
-			regMap.Data = map[string]interface{}{
-				"status": status,
-				"id":     id,
-				"pname":  getRes["pname"],
-			}
-		} else {
-			if string(this.Body()) != "" {
-				//success=false; id=""  ---没有正在预测 也没有未查看的预测数据
-				//接受参数 调rpc 预测中标数据
-				getRes := new(util.ForecastS)
-				//接收参数
-				json.Unmarshal(this.Body(), &getRes)
-				if getRes.Type == "" && getRes.Id != "" {
-					//是否是子账号
-					var s_phone, _ = this.GetSession("s_phone").(string)
-					if s_phone == "" {
-						s_phone, _ = this.GetSession("s_m_phone").(string)
-					}
-					main_userId, phone, member_status := util.MainUserId(this.Session())
-					entity.UIL.Lock()
-					if entity.UIL.ForWLock[main_userId] == nil {
-						entity.UIL.ForWLock[main_userId] = &sync.Mutex{}
-					}
-					entity.UIL.Unlock()
-					entity.UIL.ForWLock[main_userId].Lock()
-					defer entity.UIL.ForWLock[main_userId].Unlock()
-					// log.Println(getRes.ServiceId, "----------", phone)
-					//判断是否有中标预测权限
-					var currentCount = 0
-					getRes.ServiceId = 15
-					ai, base64Key, currentCount := AnalysisPower("W", main_userId, getRes.Pname, getRes.Infoid, getRes.ServiceId)
-					// log.Println("ai:", ai)
-					if ai > 0 {
-						log.Println(main_userId, "---ai:", ai)
-						if ai == 2 {
-							// 订阅及搜索优化版本dev4.3.4调整为预测成功后才扣次数
-							// UpdatePower(main_userId, getRes.ServiceId) //更新sql库权限次数
-							redis.Put("newother", "jyPredictedDeduction_"+main_userId, base64Key, 3*24*60*60) //是否需要扣除次数 默认存3天
-						}
+    defer qutil.Catch()
+    var regMap = Result{
+        Data:       []map[string]interface{}{},
+        Error_code: Error_code,
+        Error_msg:  "",
+    }
+    if this.Method() == METHOD {
+        userId, _ := this.GetSession("userId").(string)
+        //有正在预测的数据或已预测未查看的数据
+        success, id := isExistsFIng(userId)
+        status := 0
+        if success {
+            if success && id != "" {
+                status = 1 //success=true; id!=""  ---未查看的预测数据
+            } else if success && id == "" {
+                status = 2 //success=true; id=""  ---正在预测
+            }
+            var getRes map[string]interface{}
+            if redis.GetNewInterface("other", redis_forecast_status+userId, &getRes) != nil {
+                log.Println("redis 1获取预测参数有误-", userId)
+            }
+            regMap.Data = map[string]interface{}{
+                "status": status,
+                "id":     id,
+                "pname":  getRes["pname"],
+            }
+        } else {
+            if string(this.Body()) != "" {
+                //success=false; id=""  ---没有正在预测 也没有未查看的预测数据
+                //接受参数 调rpc 预测中标数据
+                getRes := new(util.ForecastS)
+                //接收参数
+                json.Unmarshal(this.Body(), &getRes)
+                if getRes.Type == "" && getRes.Id != "" {
+                    //是否是子账号
+                    var s_phone, _ = this.GetSession("s_phone").(string)
+                    if s_phone == "" {
+                        s_phone, _ = this.GetSession("s_m_phone").(string)
+                    }
+                    main_userId, phone, member_status := util.MainUserId(this.Session())
+                    entity.UIL.Lock()
+                    if entity.UIL.ForWLock[main_userId] == nil {
+                        entity.UIL.ForWLock[main_userId] = &sync.Mutex{}
+                    }
+                    entity.UIL.Unlock()
+                    entity.UIL.ForWLock[main_userId].Lock()
+                    defer entity.UIL.ForWLock[main_userId].Unlock()
+                    // log.Println(getRes.ServiceId, "----------", phone)
+                    //判断是否有中标预测权限
+                    var currentCount = 0
+                    getRes.ServiceId = 15
+                    ai, base64Key, currentCount := AnalysisPower("W", main_userId, getRes.Pname, getRes.Infoid, getRes.ServiceId)
+                    // log.Println("ai:", ai)
+                    if ai > 0 {
+                        log.Println(main_userId, "---ai:", ai)
+                        if ai == 2 {
+                            // 订阅及搜索优化版本dev4.3.4调整为预测成功后才扣次数
+                            // UpdatePower(main_userId, getRes.ServiceId) //更新sql库权限次数
+                            redis.Put("newother", "jyPredictedDeduction_"+main_userId, base64Key, 3*24*60*60) //是否需要扣除次数 默认存3天
+                        }
 
-						//中标预测是否有缓存dev4.3.4-王山(项目名称+地区+城市+采购单位+标的物) 默认缓存保留一天
-						redisKeys := GetRedisBase64Key(getRes.Pname, getRes.Area, getRes.City, getRes.Buyer, getRes.BuyerContent)
-						if forecstId := redis.GetStr("newother", "jyPredicted_"+redisKeys); forecstId != "" {
-							if f_id := db.Mgo.Save(C_ForecastData, map[string]interface{}{
-								"userId":      userId,
-								"createtime":  time.Now().Unix(),
-								"status":      1, //预测完成待查看
-								"requestData": getRes,
-								"cacheId":     forecstId,
-								"upeatetime":  time.Now().Unix(),
-							}); f_id != "" {
-								regMap.Data = map[string]interface{}{
-									"status": 3, //缓存数据
-									"id":     util.EncodeId(forecstId),
-									"pname":  getRes.Pname,
-								}
-							} else {
-								regMap.Data = map[string]interface{}{
-									"status": -4, //缓存数据保存异常
-									"pname":  getRes.Pname,
-								}
-							}
-						} else {
-							// 项目信息加密key缓存5+分钟 - 预测成功后提供 项目加密key 把结果id存入redis缓存中时间默认一天
-							redis.Put("newother", "jyPredicted_five_"+main_userId, redisKeys, forecast_time+20)
-							getRes.RedisFKey = redis_forecast_res + userId
-							getRes.Id = util.DecodeId(getRes.Id)
-							if getRes.Infoid != "" {
-								getRes.Infoid = util.DecodeId(getRes.Infoid)
-							}
-							//中标预测数据处理ing
-							if util.JyForecastByRpc(getRes) {
-								//redis 存正在预测标识
-								redis.Put("other", redis_forecast_status+userId, getRes, -1)
-								//预测参数--保存mongodb中
-								f_id := db.Mgo.Save(C_ForecastData, map[string]interface{}{
-									"userId":      userId,
-									"createtime":  time.Now().Unix(),
-									"status":      -1, //预测完成待查看
-									"requestData": getRes,
-									"upeatetime":  time.Now().Unix(),
-								})
-								if f_id != "" {
-									redis.Put("other", redis_forecast_date+userId, f_id, forecast_time)
-								}
-								status = 2 //rpc 已接受参数 正在预测
-							} else {
-								status = -1
-								s_nickname, _ := this.GetSession("s_nickname").(string)
-								if s_nickname == "" {
-									s_nickname, _ = this.GetSession("app_name").(string)
-								}
-								go SaveFalseLogAndSendMail(userId, "rpc 接口调用出错", "", s_nickname, *getRes)
-							}
-							//保存中标预测记录
-							go SaveFWHistorys(status, userId, main_userId, base64Key, phone, currentCount, this.Request, getRes, ai)
-							regMap.Data = map[string]interface{}{
-								"status": status,
-								"pname":  getRes.Pname,
-							}
-						}
-					} else {
-						if member_status == 4 {
-							status = -3 //是否是试用用户
-						} else {
-							status = -2 //账号权限已经用完
-							if main_userId != userId {
-								status = -21 //子账号权限
-							}
-						}
-						regMap.Data = map[string]interface{}{
-							"status": status,
-							"pname":  getRes.Pname,
-						}
-					}
-				}
-			} else {
-				regMap.Error_code = Error_code_1002
-				regMap.Error_msg = Error_msg_1002
-			}
-		}
-	} else {
-		regMap.Error_code = Error_code_1005
-		regMap.Error_msg = Error_msg_1005
-	}
-	this.ServeJson(regMap)
+                        //中标预测是否有缓存dev4.3.4-王山(项目名称+地区+城市+采购单位+标的物) 默认缓存保留一天
+                        redisKeys := GetRedisBase64Key(getRes.Pname, getRes.Area, getRes.City, getRes.Buyer, getRes.BuyerContent)
+                        if forecstId := redis.GetStr("newother", "jyPredicted_"+redisKeys); forecstId != "" {
+                            if f_id := db.Mgo.Save(C_ForecastData, map[string]interface{}{
+                                "userId":      userId,
+                                "createtime":  time.Now().Unix(),
+                                "status":      1, //预测完成待查看
+                                "requestData": getRes,
+                                "cacheId":     forecstId,
+                                "upeatetime":  time.Now().Unix(),
+                            }); f_id != "" {
+                                regMap.Data = map[string]interface{}{
+                                    "status": 3, //缓存数据
+                                    "id":     util.EncodeId(forecstId),
+                                    "pname":  getRes.Pname,
+                                }
+                            } else {
+                                regMap.Data = map[string]interface{}{
+                                    "status": -4, //缓存数据保存异常
+                                    "pname":  getRes.Pname,
+                                }
+                            }
+                        } else {
+                            // 项目信息加密key缓存5+分钟 - 预测成功后提供 项目加密key 把结果id存入redis缓存中时间默认一天
+                            redis.Put("newother", "jyPredicted_five_"+main_userId, redisKeys, forecast_time+20)
+                            getRes.RedisFKey = redis_forecast_res + userId
+                            getRes.Id = util.DecodeId(getRes.Id)
+                            if getRes.Infoid != "" {
+                                getRes.Infoid = util.DecodeId(getRes.Infoid)
+                            }
+                            //中标预测数据处理ing
+                            if util.JyForecastByRpc(getRes) {
+                                //redis 存正在预测标识
+                                redis.Put("other", redis_forecast_status+userId, getRes, -1)
+                                //预测参数--保存mongodb中
+                                f_id := db.Mgo.Save(C_ForecastData, map[string]interface{}{
+                                    "userId":      userId,
+                                    "createtime":  time.Now().Unix(),
+                                    "status":      -1, //预测完成待查看
+                                    "requestData": getRes,
+                                    "upeatetime":  time.Now().Unix(),
+                                })
+                                if f_id != "" {
+                                    redis.Put("other", redis_forecast_date+userId, f_id, forecast_time)
+                                }
+                                status = 2 //rpc 已接受参数 正在预测
+                            } else {
+                                status = -1
+                                s_nickname, _ := this.GetSession("s_nickname").(string)
+                                if s_nickname == "" {
+                                    s_nickname, _ = this.GetSession("app_name").(string)
+                                }
+                                go SaveFalseLogAndSendMail(userId, "rpc 接口调用出错", "", s_nickname, *getRes)
+                            }
+                            //保存中标预测记录
+                            go SaveFWHistorys(status, userId, main_userId, base64Key, phone, currentCount, this.Request, getRes, ai)
+                            regMap.Data = map[string]interface{}{
+                                "status": status,
+                                "pname":  getRes.Pname,
+                            }
+                        }
+                    } else {
+                        if member_status == 4 {
+                            status = -3 //是否是试用用户
+                        } else {
+                            status = -2 //账号权限已经用完
+                            if main_userId != userId {
+                                status = -21 //子账号权限
+                            }
+                        }
+                        regMap.Data = map[string]interface{}{
+                            "status": status,
+                            "pname":  getRes.Pname,
+                        }
+                    }
+                }
+            } else {
+                regMap.Error_code = Error_code_1002
+                regMap.Error_msg = Error_msg_1002
+            }
+        }
+    } else {
+        regMap.Error_code = Error_code_1005
+        regMap.Error_msg = Error_msg_1005
+    }
+    this.ServeJson(regMap)
 }
 
-//是否有正在预测或已预测未查看的信息
+// 是否有正在预测或已预测未查看的信息
 func isExistsFIng(userId string) (success bool, id string) {
-	rfsExist, _ := redis.Exists("other", redis_forecast_status+userId)
-	rfrExist, _ := redis.Exists("other", redis_forecast_res+userId)
-	rfdExist, _ := redis.Exists("other", redis_forecast_date+userId)
-	// log.Println(rfsExist, "--------", rfrExist)
-	//五分钟之内 有预测数据 或正在预测。。。。
-	if rfdExist && (rfsExist || (rfsExist && rfrExist)) {
-		success = true
-	} else {
-		//有预测过但是没查看的信息
-		list, ok := db.Mgo.Find(C_ForecastData, map[string]interface{}{
-			"userId": userId,
-			"status": 0,
-		}, `{"createtime":-1}`, `{"requestData":1,"responseData":1}`, false, -1, -1)
-		if ok && list != nil && len(*list) > 0 {
-			r := qutil.ObjToMap((*list)[0])
-			id = util.EncodeId(BsonIdToSId((*r)["_id"]))
-			success = true
-		}
-	}
-	return
+    rfsExist, _ := redis.Exists("other", redis_forecast_status+userId)
+    rfrExist, _ := redis.Exists("other", redis_forecast_res+userId)
+    rfdExist, _ := redis.Exists("other", redis_forecast_date+userId)
+    // log.Println(rfsExist, "--------", rfrExist)
+    //五分钟之内 有预测数据 或正在预测。。。。
+    if rfdExist && (rfsExist || (rfsExist && rfrExist)) {
+        success = true
+    } else {
+        //有预测过但是没查看的信息
+        list, ok := db.Mgo.Find(C_ForecastData, map[string]interface{}{
+            "userId": userId,
+            "status": 0,
+        }, `{"createtime":-1}`, `{"requestData":1,"responseData":1}`, false, -1, -1)
+        if ok && list != nil && len(*list) > 0 {
+            r := qutil.ObjToMap((*list)[0])
+            id = util.EncodeId(BsonIdToSId((*r)["_id"]))
+            success = true
+        }
+    }
+    return
 }
 
 type EntInfo struct {
-	EntName     string  `json:"entName"`     //企业名称
-	Score       float64 `json:"score"`       //中标概率
-	Weight      float64 `json:"weight"`      //权重
-	DateStr     string  `json:"dateStr"`     //establish_date 成立日期
-	Phone       string  `json:"phone"`       //company_phone 联系方式
-	Area        string  `json:"area"`        //company_area 地区
-	City        string  `json:"city"`        //company_city 城市
-	Capital     float64 `json:"capital"`     //capital 注册资本
-	Employee_no string  `json:"employee_no"` //employee_no 员工人数
-	Id          string  `json:"id"`
+    EntName     string  `json:"entName"`     //企业名称
+    Score       float64 `json:"score"`       //中标概率
+    Weight      float64 `json:"weight"`      //权重
+    DateStr     string  `json:"dateStr"`     //establish_date 成立日期
+    Phone       string  `json:"phone"`       //company_phone 联系方式
+    Area        string  `json:"area"`        //company_area 地区
+    City        string  `json:"city"`        //company_city 城市
+    Capital     float64 `json:"capital"`     //capital 注册资本
+    Employee_no string  `json:"employee_no"` //employee_no 员工人数
+    Id          string  `json:"id"`
 }
 
-//前端每5秒查一次 预测是否完成
+// 前端每5秒查一次 预测是否完成
 func (this *Analysis) FWStatus() {
-	defer qutil.Catch()
-	var regMap = Result{
-		Data:       []map[string]interface{}{},
-		Error_code: Error_code,
-		Error_msg:  "",
-	}
-	if this.Method() == METHOD {
-		userId, _ := this.GetSession("userId").(string)
-		if userId != "" {
-			//父级userid
-			// userid := util.MainUserId(userId)
-			main_userId, _, _ := util.MainUserId(this.Session())
-			rfrExist, _ := redis.Exists("other", redis_forecast_res+userId)
-			f_id := redis.GetStr("other", redis_forecast_date+userId)
-			var isFFalse = 0  //是否预测失败
-			var falseMsg = "" //预测失败备注
-			// log.Println("---1--", rfrExist)
-			if rfrExist && f_id != "" {
-				var resp = []*EntInfo{}
-				f_res := redis.Get("other", redis_forecast_res+userId)
-				if f_res != nil && f_res.(string) != "" {
-					json.Unmarshal([]byte(f_res.(string)), &resp)
-					//获取数据为空
-					if resp != nil && len(resp) > 0 {
-						//rpc 返回预测数据只有企业名称和中标概率  还需要查询企业得成立日期 注册资本 员工人数 地区 城市 联系电话 企业信用库id
-						handleData := handleResp(resp)
-						//结果更新mongodb中
-						if db.Mgo.UpdateById(C_ForecastData, f_id, map[string]interface{}{
-							"$set": map[string]interface{}{
-								"status":       0,
-								"responseData": handleData,
-								"upeatetime":   time.Now().Unix(),
-							},
-						}) {
-							regMap.Data = map[string]interface{}{
-								"id":      util.EncodeId(f_id),
-								"success": true,
-							}
-							// 订阅及搜索优化版本dev4.3.4调整为预测成功后才扣次数
-							go func(userId, f_id string) {
-								main_userId, _, _ := util.MainUserId(this.Session())
-								if ok, _ := redis.Exists("newother", "jyPredictedDeduction_"+main_userId); ok {
-									//扣除次数
-									UpdatePower(main_userId, 15)
-									redis.Del("newother", "jyPredictedDeduction_"+main_userId)
-								}
-								// 预测项目信息  缓存 五分钟
-								redisKeys := redis.GetStr("newother", "jyPredicted_five_"+main_userId)
-								if redisKeys != "" {
-									//缓存默认一天
-									redis.Put("newother", "jyPredicted_"+redisKeys, f_id, qutil.IntAllDef(Config.ForecastTime, 86400))
-								}
-							}(userId, f_id)
-						} else {
-							isFFalse = 1
-							falseMsg = "中标预测二次更新状态出错"
-							log.Println(falseMsg, " :", f_id)
-						}
-					} else {
-						isFFalse = 2
-						falseMsg = "中标预测redis序列化数据出错" + f_res.(string)
-						log.Println(falseMsg, " :", f_id)
-					}
-				} else {
-					isFFalse = 3
-					falseMsg = "从redis获取预测数据出错" + f_res.(string)
-					log.Println(falseMsg, " :", f_id, f_res)
-				}
-				//保存请求日志
-				go func(f_id, userId, main_userId string, resp []*EntInfo) {
-					//log.Println("--resp--", resp)
-					var getRes map[string]interface{}
-					if redis.GetNewInterface("other", redis_forecast_status+userId, &getRes) != nil {
-						log.Println("redis 获取预测参数有误-", userId)
-					}
-					forecastLog(userId, main_userId, f_id, getRes, resp)
-				}(f_id, userId, main_userId, resp)
-			} else {
-				//预测中
-				rfdExist, _ := redis.Exists("other", redis_forecast_date+userId)
-				if rfdExist {
-					regMap.Data = map[string]interface{}{
-						"id":      "",
-						"success": true,
-					}
-				} else {
-					isFFalse = 4
-					falseMsg = "预测超时(五分钟)"
-					log.Println(falseMsg, " :", userId)
-				}
-			}
-			if isFFalse > 0 {
-				if rfrExist && f_id != "" {
-					go func() {
-						//发送失败邮件提醒
-						getRes := new(util.ForecastS)
-						if redis.GetNewInterface("other", redis_forecast_status+userId, &getRes) != nil {
-							log.Println("redis 1获取预测参数有误-", userId)
-						}
-						s_nickname, _ := this.GetSession("s_nickname").(string)
-						if s_nickname == "" {
-							s_nickname, _ = this.GetSession("app_name").(string)
-						}
-						SaveFalseLogAndSendMail(userId, falseMsg, f_id, s_nickname, *getRes)
-					}()
-				}
-				//预测失败 清除redis数据
-				ClearRedisInfo(userId)
-				regMap.Data = map[string]interface{}{
-					"id":      "",
-					"success": false,
-				}
-			}
-		} else {
-			regMap.Error_code = Error_code_1001
-			regMap.Error_msg = Error_msg_1001
-		}
-	} else {
-		regMap.Error_code = Error_code_1005
-		regMap.Error_msg = Error_msg_1005
-	}
-	this.ServeJson(regMap)
+    defer qutil.Catch()
+    var regMap = Result{
+        Data:       []map[string]interface{}{},
+        Error_code: Error_code,
+        Error_msg:  "",
+    }
+    if this.Method() == METHOD {
+        userId, _ := this.GetSession("userId").(string)
+        if userId != "" {
+            //父级userid
+            // userid := util.MainUserId(userId)
+            main_userId, _, _ := util.MainUserId(this.Session())
+            rfrExist, _ := redis.Exists("other", redis_forecast_res+userId)
+            f_id := redis.GetStr("other", redis_forecast_date+userId)
+            var isFFalse = 0  //是否预测失败
+            var falseMsg = "" //预测失败备注
+            // log.Println("---1--", rfrExist)
+            if rfrExist && f_id != "" {
+                var resp = []*EntInfo{}
+                f_res := redis.Get("other", redis_forecast_res+userId)
+                if f_res != nil && f_res.(string) != "" {
+                    json.Unmarshal([]byte(f_res.(string)), &resp)
+                    //获取数据为空
+                    if resp != nil && len(resp) > 0 {
+                        //rpc 返回预测数据只有企业名称和中标概率  还需要查询企业得成立日期 注册资本 员工人数 地区 城市 联系电话 企业信用库id
+                        handleData := handleResp(resp)
+                        //结果更新mongodb中
+                        if db.Mgo.UpdateById(C_ForecastData, f_id, map[string]interface{}{
+                            "$set": map[string]interface{}{
+                                "status":       0,
+                                "responseData": handleData,
+                                "upeatetime":   time.Now().Unix(),
+                            },
+                        }) {
+                            regMap.Data = map[string]interface{}{
+                                "id":      util.EncodeId(f_id),
+                                "success": true,
+                            }
+                            // 订阅及搜索优化版本dev4.3.4调整为预测成功后才扣次数
+                            go func(userId, f_id string) {
+                                main_userId, _, _ := util.MainUserId(this.Session())
+                                if ok, _ := redis.Exists("newother", "jyPredictedDeduction_"+main_userId); ok {
+                                    //扣除次数
+                                    UpdatePower(main_userId, 15)
+                                    redis.Del("newother", "jyPredictedDeduction_"+main_userId)
+                                }
+                                // 预测项目信息  缓存 五分钟
+                                redisKeys := redis.GetStr("newother", "jyPredicted_five_"+main_userId)
+                                if redisKeys != "" {
+                                    //缓存默认一天
+                                    redis.Put("newother", "jyPredicted_"+redisKeys, f_id, qutil.IntAllDef(Config.ForecastTime, 86400))
+                                }
+                            }(userId, f_id)
+                        } else {
+                            isFFalse = 1
+                            falseMsg = "中标预测更新异常"
+                            log.Println("中标预测二次更新状态出错", " :", f_id)
+                        }
+                    } else {
+                        isFFalse = 2
+                        falseMsg = "暂无预测结果"
+                        log.Println("中标预测redis序列化数据出错", " :", f_id, "---", f_res.(string))
+                    }
+                } else {
+                    isFFalse = 3
+                    falseMsg = "暂无预测结果-"
+                    log.Println("从redis获取预测数据出错", f_res.(string), " :", f_id, f_res)
+                }
+                //保存请求日志
+                go func(f_id, userId, main_userId string, resp []*EntInfo) {
+                    //log.Println("--resp--", resp)
+                    var getRes map[string]interface{}
+                    if redis.GetNewInterface("other", redis_forecast_status+userId, &getRes) != nil {
+                        log.Println("redis 获取预测参数有误-", userId)
+                    }
+                    forecastLog(userId, main_userId, f_id, getRes, resp)
+                }(f_id, userId, main_userId, resp)
+            } else {
+                //预测中
+                rfdExist, _ := redis.Exists("other", redis_forecast_date+userId)
+                if rfdExist {
+                    regMap.Data = map[string]interface{}{
+                        "id":      "",
+                        "success": true,
+                    }
+                } else {
+                    isFFalse = 4
+                    falseMsg = "预测超时(五分钟)"
+                    log.Println(falseMsg, " :", userId)
+                }
+            }
+            if isFFalse > 0 {
+                if rfrExist && f_id != "" {
+                    go func() {
+                        //发送失败邮件提醒
+                        getRes := new(util.ForecastS)
+                        if redis.GetNewInterface("other", redis_forecast_status+userId, &getRes) != nil {
+                            log.Println("redis 1获取预测参数有误-", userId)
+                        }
+                        s_nickname, _ := this.GetSession("s_nickname").(string)
+                        if s_nickname == "" {
+                            s_nickname, _ = this.GetSession("app_name").(string)
+                        }
+                        SaveFalseLogAndSendMail(userId, falseMsg, f_id, s_nickname, *getRes)
+                    }()
+                }
+                //预测失败 清除redis数据
+                ClearRedisInfo(userId)
+                regMap.Data = map[string]interface{}{
+                    "id":      "",
+                    "success": false,
+                }
+            }
+        } else {
+            regMap.Error_code = Error_code_1001
+            regMap.Error_msg = Error_msg_1001
+        }
+    } else {
+        regMap.Error_code = Error_code_1005
+        regMap.Error_msg = Error_msg_1005
+    }
+    this.ServeJson(regMap)
 
 }
 
-//查询中标企业名称【带曾用名检索】
+// 查询中标企业名称【带曾用名检索】
 const queryFullEntName = `{"query":{"function_score":{"query":{"multi_match":{"query":"%s","type":"phrase","fields":["name","history_name"]}},"field_value_factor":{"field":"company_type_int","modifier":"reciprocal","factor":2}}},"_source":["name","history_name","company_type_int","_id"],"size":%d}`
 
-//数据填充
+// 数据填充
 func handleResp(r []*EntInfo) []*EntInfo {
-	if len(r) > 0 {
-		for _, v := range r {
-			entInfo, _ := db.Mgo_Ent.FindOne(C_FW_qyxy, `{"company_name":"`+v.EntName+`"}`)
-			if entInfo == nil || (*entInfo)["_id"] == nil {
-				list := elastic.Get("qyxy", "qyxy", fmt.Sprintf(queryFullEntName, v.EntName, 1))
-				if list != nil && len(*list) > 0 {
-					entInfo = &(*list)[0]
-				}
-			}
-			if entInfo != nil {
-				if (*entInfo)["company_area"] != nil {
-					v.Area = qutil.ObjToString((*entInfo)["company_area"])
-				}
-				if (*entInfo)["company_city"] != nil {
-					v.City = qutil.ObjToString((*entInfo)["company_city"])
-				}
-				if (*entInfo)["company_phone"] != nil {
-					v.Phone = qutil.ObjToString((*entInfo)["company_phone"])
-				}
-				if (*entInfo)["establish_date"] != nil {
-					v.DateStr = qutil.ObjToString((*entInfo)["establish_date"])
-				}
-				if (*entInfo)["capital"] != nil {
-					v.Capital = qutil.Float64All((*entInfo)["capital"])
-				}
-				if (*entInfo)["_id"] != nil {
-					v.Id = qutil.ObjToString((*entInfo)["_id"])
-				}
-				if (*entInfo)["annual_reports"] != nil {
-					annual_reports := qutil.ObjArrToMapArr((*entInfo)["annual_reports"].([]interface{}))
-					if len(annual_reports) > 0 {
-						reportOne := annual_reports[0]
-						if reportOne["employee_no"] != nil && qutil.ObjToString(reportOne["employee_no"]) != "" {
-							employee_no := qutil.ObjToString(reportOne["employee_no"])
-							if reg.MatchString(employee_no) {
-								v.Employee_no = employee_no
-							}
-						}
-					}
-				}
-			}
-		}
-	}
-	return r
+    if len(r) > 0 {
+        for _, v := range r {
+            entInfo, _ := db.Mgo_Ent.FindOne(C_FW_qyxy, `{"company_name":"`+v.EntName+`"}`)
+            if entInfo == nil || (*entInfo)["_id"] == nil {
+                list := elastic.Get("qyxy", "qyxy", fmt.Sprintf(queryFullEntName, v.EntName, 1))
+                if list != nil && len(*list) > 0 {
+                    entInfo = &(*list)[0]
+                }
+            }
+            if entInfo != nil {
+                if (*entInfo)["company_area"] != nil {
+                    v.Area = qutil.ObjToString((*entInfo)["company_area"])
+                }
+                if (*entInfo)["company_city"] != nil {
+                    v.City = qutil.ObjToString((*entInfo)["company_city"])
+                }
+                if (*entInfo)["company_phone"] != nil {
+                    v.Phone = qutil.ObjToString((*entInfo)["company_phone"])
+                }
+                if (*entInfo)["establish_date"] != nil {
+                    v.DateStr = qutil.ObjToString((*entInfo)["establish_date"])
+                }
+                if (*entInfo)["capital"] != nil {
+                    v.Capital = qutil.Float64All((*entInfo)["capital"])
+                }
+                if (*entInfo)["_id"] != nil {
+                    v.Id = qutil.ObjToString((*entInfo)["_id"])
+                }
+                if (*entInfo)["annual_reports"] != nil {
+                    annual_reports := qutil.ObjArrToMapArr((*entInfo)["annual_reports"].([]interface{}))
+                    if len(annual_reports) > 0 {
+                        reportOne := annual_reports[0]
+                        if reportOne["employee_no"] != nil && qutil.ObjToString(reportOne["employee_no"]) != "" {
+                            employee_no := qutil.ObjToString(reportOne["employee_no"])
+                            if reg.MatchString(employee_no) {
+                                v.Employee_no = employee_no
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return r
 }
 
-//结果
+// 结果
 func (this *Analysis) FWResult() {
-	defer qutil.Catch()
-	var regMap = Result{
-		Data:       []map[string]interface{}{},
-		Error_code: Error_code,
-		Error_msg:  "",
-	}
-	if true || this.Method() == METHOD {
-		userId, _ := this.GetSession("userId").(string)
-		f_id := this.GetString("id")
-		// f_id = util.EncodeId(f_id)
-		if f_id != "" {
-			f_id = util.DecodeId(f_id)
-			res, ok := db.Mgo.FindById(C_ForecastData, f_id, `{"requestData":1,"responseData":1}`)
-			if ok {
-				if !db.Mgo.UpdateById(C_ForecastData, f_id, map[string]interface{}{
-					"$set": map[string]interface{}{"status": 1}, //中标预测信息已读
-				}) {
-					log.Println("中标预测信息已读修改报错:", userId, time.Now().Unix())
-				} else {
-					if res != nil {
-						delete((*res), "_id")
-						requestData := *qutil.ObjToMap((*res)["requestData"])
-						if requestData != nil && requestData["id"] != nil {
-							abstract := *elastic.GetById(P_INDEX, P_TYPE, requestData["id"].(string))
-							if len(abstract) > 0 {
-								requestData["agency"] = abstract[0]["agency"]
-								requestData["_area"] = abstract[0]["area"]
-								requestData["_city"] = abstract[0]["city"]
-								requestData["buyerperson"] = abstract[0]["buyerperson"]
-								requestData["buyertel"] = abstract[0]["buyertel"]
-							}
-							requestData["id"] = util.EncodeId(requestData["id"].(string))
-							requestData["infoid"] = util.EncodeId(requestData["infoid"].(string))
-						}
-						delete(requestData, "redisfkey")
-						//结果
-						responseData := qutil.ObjArrToMapArr((*res)["responseData"].([]interface{}))
-						if responseData != nil && len(responseData) > 0 {
-							for _, v := range responseData {
-								rdv := *qutil.ObjToMap(v)
-								entId := qutil.ObjToString(rdv["id"])
-								if rdv["id"] == nil || qutil.ObjToString(rdv["id"]) == "" {
-									entName := qutil.ObjToString(rdv["entname"])
-									entId = entity.GetEntIdByQYXY(entName)
-								}
-								rdv["entId"] = util.EncodeId(entId)
-							}
-						}
-					}
-					regMap.Data = res
-					go ClearRedisInfo(userId)
-				}
-			} else {
-				log.Println("forecast_find_err:")
-			}
-		} else {
-			regMap.Error_code = Error_code_1002
-			regMap.Error_msg = Error_msg_1002
-		}
-	} else {
-		regMap.Error_code = Error_code_1005
-		regMap.Error_msg = Error_msg_1005
-	}
-	this.ServeJson(regMap)
+    defer qutil.Catch()
+    var regMap = Result{
+        Data:       []map[string]interface{}{},
+        Error_code: Error_code,
+        Error_msg:  "",
+    }
+    if true || this.Method() == METHOD {
+        userId, _ := this.GetSession("userId").(string)
+        f_id := this.GetString("id")
+        // f_id = util.EncodeId(f_id)
+        if f_id != "" {
+            f_id = util.DecodeId(f_id)
+            res, ok := db.Mgo.FindById(C_ForecastData, f_id, `{"requestData":1,"responseData":1}`)
+            if ok {
+                if !db.Mgo.UpdateById(C_ForecastData, f_id, map[string]interface{}{
+                    "$set": map[string]interface{}{"status": 1}, //中标预测信息已读
+                }) {
+                    log.Println("中标预测信息已读修改报错:", userId, time.Now().Unix())
+                } else {
+                    if res != nil {
+                        delete((*res), "_id")
+                        requestData := *qutil.ObjToMap((*res)["requestData"])
+                        if requestData != nil && requestData["id"] != nil {
+                            abstract := *elastic.GetById(P_INDEX, P_TYPE, requestData["id"].(string))
+                            if len(abstract) > 0 {
+                                requestData["agency"] = abstract[0]["agency"]
+                                requestData["_area"] = abstract[0]["area"]
+                                requestData["_city"] = abstract[0]["city"]
+                                requestData["buyerperson"] = abstract[0]["buyerperson"]
+                                requestData["buyertel"] = abstract[0]["buyertel"]
+                            }
+                            requestData["id"] = util.EncodeId(requestData["id"].(string))
+                            requestData["infoid"] = util.EncodeId(requestData["infoid"].(string))
+                        }
+                        delete(requestData, "redisfkey")
+                        //结果
+                        responseData := qutil.ObjArrToMapArr((*res)["responseData"].([]interface{}))
+                        if responseData != nil && len(responseData) > 0 {
+                            for _, v := range responseData {
+                                rdv := *qutil.ObjToMap(v)
+                                entId := qutil.ObjToString(rdv["id"])
+                                if rdv["id"] == nil || qutil.ObjToString(rdv["id"]) == "" {
+                                    entName := qutil.ObjToString(rdv["entname"])
+                                    entId = entity.GetEntIdByQYXY(entName)
+                                }
+                                rdv["entId"] = util.EncodeId(entId)
+                            }
+                        }
+                    }
+                    regMap.Data = res
+                    go ClearRedisInfo(userId)
+                }
+            } else {
+                log.Println("forecast_find_err:")
+            }
+        } else {
+            regMap.Error_code = Error_code_1002
+            regMap.Error_msg = Error_msg_1002
+        }
+    } else {
+        regMap.Error_code = Error_code_1005
+        regMap.Error_msg = Error_msg_1005
+    }
+    this.ServeJson(regMap)
 }
 
-//预测结果日志
+// 预测结果日志
 func forecastLog(userId, userid, f_id string, getRes map[string]interface{}, resp []*EntInfo) {
-	id := db.Mgo.Save(C_ForecastLog, map[string]interface{}{
-		"userId":       userId,
-		"f_userId":     userid,
-		"createtime":   time.Now().Unix(),
-		"f_id":         f_id,
-		"requestData":  getRes,
-		"responseData": resp,
-	})
-	if id == "" {
-		log.Println("forecast-log-err:")
-	}
+    id := db.Mgo.Save(C_ForecastLog, map[string]interface{}{
+        "userId":       userId,
+        "f_userId":     userid,
+        "createtime":   time.Now().Unix(),
+        "f_id":         f_id,
+        "requestData":  getRes,
+        "responseData": resp,
+    })
+    if id == "" {
+        log.Println("forecast-log-err:")
+    }
 }
 
-//中标信息预测结束
+// 中标信息预测结束
 func ClearRedisInfo(userId string) {
-	redis.Del("other", redis_forecast_res+userId)
-	redis.Del("other", redis_forecast_status+userId)
-	redis.Del("other", redis_forecast_date+userId)
+    redis.Del("other", redis_forecast_res+userId)
+    redis.Del("other", redis_forecast_status+userId)
+    redis.Del("other", redis_forecast_date+userId)
 }
 
-//报错预测失败日志 并发送邮件
+// 报错预测失败日志 并发送邮件
 func SaveFalseLogAndSendMail(userId, msg, f_id, nickname string, res util.ForecastS) {
-	email := Config.WarnMailbox
-	if len(email) > 0 {
-		var resHtml = ``
-		var divH2 = "420px"
-		// log.Println("res:", res)
-		if len(res.BuyerContent) > 0 {
-			divH2 = "535px"
-			resHtml = `<p>中标预测内容:<div style="margin-left: 30px;font-size: 13px;"><p style="line-height: 12px;">项目名称:"` + res.Pname + `"</p><p style="line-height: 12px;">采购内容:"` + strings.Join(res.BuyerContent, ",") + `"</p><p style="line-height: 12px;">采购单位:"` + res.Buyer + `"</p><p style="line-height: 12px;">采购预算:"` + strconv.FormatFloat(res.Budget, 'f', -1, 64) + `"</p><p style="line-height: 12px;">区域:"` + res.Area + " " + res.City + `"</p></div></p>`
-		}
-		content := `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body style="margin: 0;padding: 0;"><div class="Email" id="Email" style="width: 100%%;height: 100%%;display: flex;flex-direction: column;align-items: center; background: #E5E5E5;"><div class="emailmain" style="width: 1200px;height: ` + divH2 + `;border-top: 8px solid #2CB7CA;border-radius: 8px; background: #fff; margin-top: 107px; padding: 0 40px;"><div class="emailmain_top" style="height: 88px;width: 100%%; border-bottom: 1px solid #F7F7F7; display: flex;justify-content: center;align-items: center;"><img src="https://www.jianyu360.com/images/swordfish/sf_01.png" alt="" style="width: 130px;"></div><div class="emailmain_bottom" style="display: flex;flex-direction: column; align-items: center;"><p class="emailmain_text" style="margin-top: 10px;width: 960px;font-size: 16px;line-height: 24px;color: #1D1D1D;">尊敬的管理员:<br>&nbsp;&nbsp;&nbsp;&nbsp;您好,中标预测失败信息如下:</p> <div class="download" style="margin-top: 0px;width: 100%%; height: 30px;justify-content: center;align-items: center;"><p>用户昵称:"` + nickname + `"</p><p>用户userid:"` + userId + `"</p><p>中标预测信息id:"` + f_id + `"</p><p>中标预测失败原因:"` + msg + `"</p>` + resHtml + `</div></div></div><p class="havapro"style="font-size: 14px;height: 24px;color: #686868;margin-top: 32px;">如有问题请<a href="mailto:bd@topnet.net.cn" class="click_here" id="click_here" style="color: #0987FF;cursor: pointer;text-decoration:none;">点击此处</a>,进行意见反馈</p></div></body></html>`
-		for _, v := range email {
-			if regexp.MustCompile("^\\d+$").MatchString(v) {
-				continue
-			}
-			if !util.SendRetryMail(Config.ReTry, v, Config.WarnMbTitle, content, "", nil, GmailAuth) {
-				log.Println("预测失败邮件发送失败")
-			}
-		}
-	}
+    email := Config.WarnMailbox
+    if len(email) > 0 {
+        var resHtml = ``
+        var divH2 = "420px"
+        // log.Println("res:", res)
+        if len(res.BuyerContent) > 0 {
+            divH2 = "535px"
+            resHtml = `<p>中标预测内容:<div style="margin-left: 30px;font-size: 13px;"><p style="line-height: 12px;">项目名称:"` + res.Pname + `"</p><p style="line-height: 12px;">采购内容:"` + strings.Join(res.BuyerContent, ",") + `"</p><p style="line-height: 12px;">采购单位:"` + res.Buyer + `"</p><p style="line-height: 12px;">采购预算:"` + strconv.FormatFloat(res.Budget, 'f', -1, 64) + `"</p><p style="line-height: 12px;">区域:"` + res.Area + " " + res.City + `"</p></div></p>`
+        }
+        content := `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body style="margin: 0;padding: 0;"><div class="Email" id="Email" style="width: 100%%;height: 100%%;display: flex;flex-direction: column;align-items: center; background: #E5E5E5;"><div class="emailmain" style="width: 1200px;height: ` + divH2 + `;border-top: 8px solid #2CB7CA;border-radius: 8px; background: #fff; margin-top: 107px; padding: 0 40px;"><div class="emailmain_top" style="height: 88px;width: 100%%; border-bottom: 1px solid #F7F7F7; display: flex;justify-content: center;align-items: center;"><img src="https://www.jianyu360.com/images/swordfish/sf_01.png" alt="" style="width: 130px;"></div><div class="emailmain_bottom" style="display: flex;flex-direction: column; align-items: center;"><p class="emailmain_text" style="margin-top: 10px;width: 960px;font-size: 16px;line-height: 24px;color: #1D1D1D;">尊敬的管理员:<br>&nbsp;&nbsp;&nbsp;&nbsp;您好,中标预测失败信息如下:</p> <div class="download" style="margin-top: 0px;width: 100%%; height: 30px;justify-content: center;align-items: center;"><p>用户昵称:"` + nickname + `"</p><p>用户userid:"` + userId + `"</p><p>中标预测信息id:"` + f_id + `"</p><p>中标预测失败原因:"` + msg + `"</p>` + resHtml + `</div></div></div><p class="havapro"style="font-size: 14px;height: 24px;color: #686868;margin-top: 32px;">如有问题请<a href="mailto:bd@topnet.net.cn" class="click_here" id="click_here" style="color: #0987FF;cursor: pointer;text-decoration:none;">点击此处</a>,进行意见反馈</p></div></body></html>`
+        for _, v := range email {
+            if regexp.MustCompile("^\\d+$").MatchString(v) {
+                continue
+            }
+            if !util.SendRetryMail(Config.ReTry, v, Config.WarnMbTitle, content, "", nil, GmailAuth) {
+                log.Println("预测失败邮件发送失败")
+            }
+        }
+    }
 }

+ 72 - 0
src/jfw/modules/bigmember/src/service/report/marketAnalysis.go

@@ -22,6 +22,78 @@ type MarketAnalysis struct {
 	getAnalysisResult xweb.Mapper `xweb:"/marketAnalysis/getAnalysisResult"` //获取分析报告结果(根据记录id查询报告结果)
 	analysisHistory   xweb.Mapper `xweb:"/marketAnalysis/analysisHistory"`   //市场分析报告历史记录
 	analysisKeyWord   xweb.Mapper `xweb:"/marketAnalysis/analysisKeyWord"`   //市场分析报告订阅词
+	projectInfo       xweb.Mapper `xweb:"/marketAnalysis/projectInfo"`       //项目明细
+}
+
+// 项目明细
+func (this *MarketAnalysis) ProjectInfo() {
+	userId := qutil.ObjToString(this.GetSession("userId"))
+	rData, errMsg := func() (interface{}, error) {
+		pid, powerErr := checkPower(this.Session())
+		if powerErr != nil {
+			return nil, powerErr
+		}
+		var (
+			sort, _     = this.GetInteger("sort")
+			pageSize, _ = this.GetInteger("pageSize")
+			pageNum, _  = this.GetInteger("pageNum")
+			rid         = util.DecodeId(this.GetString("rid"))
+		)
+		if rid == "" {
+			return nil, fmt.Errorf("参数异常")
+		}
+		log.Println("-----:", this.GetString("keysItems"))
+		//接受参数
+		bParam := marketAnalysis.AnalysisRequestParam{
+			KeysItemsStr:   this.GetString("keysItems"),      //分析内容【字符串】结构和o_member_jy.a_items保持一致
+			RangeTime:      this.GetString("rangeTime"),      //时间【字符串】 时间戳开始-结束时间戳
+			RangeTimeExtra: this.GetString("rangeTimeExtra"), //时间【字符串】 时间戳开始-结束时间戳
+			Area:           this.GetString("area"),           //省份【字符串】多个省份用逗号拼接
+			Industry:       this.GetString("industry"),       //行业【字符串】多个行业用逗号拼接
+			BuyerClass:     this.GetString("buyerclass"),     //采购单位类型【字符串】多个采购单位类型用逗号拼接
+			Buyer:          this.GetString("buyer"),          //采购单位
+			Winner:         this.GetString("winner"),         //中标单位
+			Sort:           sort,                             //排序
+			PageSize:       pageSize,                         //每页数据量
+			PageNum:        pageNum,                          //当前页码
+			IsDetail:       true,                             //是否是项目明细请求
+		}
+		mae := &marketAnalysis.MarketAnalysisEntity{MgoRecordId: rid, BaseParam: bParam, UId: userId, Pid: pid}
+		//参数验证 --:回显字段keysItems、area、industry、buyerclass
+		if bParam.KeysItemsStr == "" || bParam.Area == "" || bParam.Industry == "" || bParam.BuyerClass == "" {
+			//原查询条件
+			maePrimary := &marketAnalysis.MarketAnalysisEntity{MgoRecordId: rid, UId: userId, Pid: pid}
+			if err := maePrimary.GetAnalysisFromMgoDb(); err == nil {
+				if bParam.KeysItemsStr == "" || len([]rune(bParam.KeysItemsStr)) < 3 { //分析内容【字符串】结构和o_member_jy.a_items保持一致
+					mae.BaseParam.KeysItemsStr = maePrimary.BaseParam.KeysItemsStr
+				}
+				if bParam.Area == "" || len([]rune(bParam.Area)) < 3 { //省份【字符串】多个省份用逗号拼接
+					mae.BaseParam.Area = maePrimary.BaseParam.Area
+				}
+				if bParam.Industry == "" || len([]rune(bParam.Industry)) < 3 { //行业【字符串】多个行业用逗号拼接
+					mae.BaseParam.Industry = maePrimary.BaseParam.Industry
+				}
+				if bParam.BuyerClass == "" || len([]rune(bParam.BuyerClass)) < 3 { //采购单位类型【字符串】多个采购单位类型用逗号拼接
+					mae.BaseParam.BuyerClass = maePrimary.BaseParam.BuyerClass
+				}
+			}
+		}
+		if err := mae.ForMatData(); err != nil {
+			return nil, err
+		}
+		//项目明细
+		if err := mae.GetProjectInfoList(); err != nil {
+			return nil, err
+		}
+		return map[string]interface{}{
+			"total": mae.ProjectInfo.Count,
+			"list":  mae.ProjectInfo.List,
+		}, nil
+	}()
+	if errMsg != nil {
+		log.Printf("%s MarketAnalysis DoAnalysis Error:%s\n", userId, errMsg.Error())
+	}
+	this.ServeJson(NewResult(rData, errMsg))
 }
 
 // checkPower 权限校验

+ 66 - 11
src/jfw/modules/bigmember/src/service/report/report.go

@@ -1,9 +1,11 @@
 package report
 
 import (
+	"encoding/json"
 	"fmt"
 	"jy/src/jfw/modules/bigmember/src/config"
 	. "jy/src/jfw/modules/bigmember/src/db"
+	"jy/src/jfw/modules/bigmember/src/entity"
 	"sort"
 	"strings"
 	"time"
@@ -25,6 +27,8 @@ type Report struct {
 	tipover     xweb.Mapper `xweb:"/report/tipover"`
 	openpushmsg xweb.Mapper `xweb:"/report/openpushmsg"`
 	starttime   xweb.Mapper `xweb:"/report/starttime"`
+	projectInfo xweb.Mapper `xweb:"/report/projectInfo"` // 周边月报项目明细
+
 }
 
 type BarChart struct {
@@ -170,12 +174,67 @@ func (r *Report) Detail() {
 			"unread": 0,
 		},
 	}, false, true)
+	isNewData := true
+	if end < config.Config.NewDataTime {
+		isNewData = false
+	}
+	positionId := qutil.Int64All(r.GetSession("positionId"))
+	mainPositionId := entity.GetMainPositionId(qutil.ObjToString(r.GetSession("mgoUserId")))
+	if mainPositionId != int64(0) {
+		positionId = mainPositionId
+	}
+	// 省份
+	m["area"] = entity.ReportGetArea(positionId, start, end)
+	// 采购单位类型
+	m["buyerClass"] = entity.ReportGetBuyerClass(positionId, start, end)
+	m["isNewData"] = isNewData
+	r.ServeJson(Result{
+		Data: m,
+	})
+}
+
+// ProjectInfo 项目明细
+func (r *Report) ProjectInfo() {
+	//参数接收
+	body := xweb.FilterXSS(string(r.Body()))
+	param := entity.ReportProjectInfoParam{}
+	//接收参数
+	err := json.Unmarshal([]byte(body), &param)
+	if err != nil {
+		R.InvalidReqParam(r.ResponseWriter, r.Request)
+		return
+	}
+	start := param.Start
+	end := param.End
+	if end-start == 518400 { //周
+	} else if 518400 < end-start && end-start <= 2592000 { //月
+	} else {
+		R.InvalidReqParam(r.ResponseWriter, r.Request, "start", "end")
+		return
+	}
+	if param.PageNum*param.PageSize > config.Config.ProjectCount {
+		param.PageNum = config.Config.ProjectCount / param.PageSize
+	}
+	//当前页码
+	param.PageNum = qutil.If(param.PageNum < 1 || param.PageNum > 1000, 1, param.PageNum).(int)
+	//默认每页10条
+	param.PageSize = qutil.If(param.PageSize < 1 || param.PageSize > 100, 50, param.PageSize).(int)
+	// 取positionId
+	positionId := qutil.Int64All(r.GetSession("positionId"))
+	mainPositionId := entity.GetMainPositionId(qutil.ObjToString(r.GetSession("mgoUserId")))
+	if mainPositionId != int64(0) {
+		positionId = mainPositionId
+	}
+	m := map[string]interface{}{}
+	list, total := entity.GetReportProjectInfo(&param, positionId)
+	m["list"] = entity.ReportProjectInfoFormat(list)
+	m["total"] = total
 	r.ServeJson(Result{
 		Data: m,
 	})
 }
 
-//周报
+// 周报
 func weekResult(qk string, qv interface{}, start, end int64, coll, coll_winner string) M {
 	prevWeekStartDate := start - 7*oneday
 	list, ok := Mgo.Find(coll, map[string]interface{}{
@@ -219,7 +278,7 @@ func weekResult(qk string, qv interface{}, start, end int64, coll, coll_winner s
 	return result
 }
 
-//月报
+// 月报
 func monthResult(userId, qk string, qv interface{}, start, end int64, coll, coll_winner string) M {
 	result := M{}
 	//最近6个月
@@ -233,7 +292,7 @@ func monthResult(userId, qk string, qv interface{}, start, end int64, coll, coll
 		"enddate": map[string]interface{}{
 			"$lte": end,
 		},
-	}, `{"startdate":1}`, `{"startdate":1,"item":1,"project_matchitem_count":1,"project_matchitem_bidamount":1,"project_count":1,"project_bidamount_count":1,"project_area_count":1,"project_area_bidamount":1,"project_buyerclass_count":1,"project_buyerclass_bidamount":1,"project_buyerclass_average_bidamount":1,"winner_area":1,"buyer":1,"winner":1,"project_bidamount":1}`, false, -1, -1)
+	}, `{"startdate":1}`, `{"startdate":1,"item":1,"project_matchitem_count":1,"project_matchitem_bidamount":1,"project_count":1,"project_bidamount_count":1,"project_area_count":1,"project_area_bidamount":1,"project_buyerclass_count":1,"project_buyerclass_bidamount":1,"project_buyerclass_average_bidamount":1,"winner_area":1,"buyer":1,"winner":1,"project_bidamount":1,"winner_capital_array":1,"winner_project":1}`, false, -1, -1)
 	if ok && sixDatas != nil {
 		project_count := &BarCharts{
 			Keys: map[int64]bool{},
@@ -273,7 +332,7 @@ func monthResult(userId, qk string, qv interface{}, start, end int64, coll, coll
 				//本月项目规模排行榜
 				result["project_bidamount"] = v["project_bidamount"]
 				//
-				result["winner_capital"] = v["winner_capital"]
+				result["winner_capital"] = v["winner_capital_array"]
 				//本月中标企业中标项目数量分布
 				result["winner_project"] = v["winner_project"]
 			}
@@ -371,7 +430,7 @@ func monthResult(userId, qk string, qv interface{}, start, end int64, coll, coll
 	return result
 }
 
-//处理关键词分组环比增长率
+// 处理关键词分组环比增长率
 func matchitemGrowthRateHandle(earliest, curr map[string]interface{}, key1, key2 string) []interface{} {
 	e, _ := earliest[key1].([]interface{})
 	c, _ := curr[key1].([]interface{})
@@ -387,7 +446,7 @@ func matchitemGrowthRateHandle(earliest, curr map[string]interface{}, key1, key2
 	return c
 }
 
-//获取企业注册资本范围
+// 获取企业注册资本范围
 func getEntCapitalScopt(capital float64) string {
 	if 0 <= capital && capital < 100 {
 		return "0-100万"
@@ -412,7 +471,6 @@ func getEntCapitalScopt(capital float64) string {
 	}
 }
 
-//
 func formatMonths(start, end int64, bcs *BarCharts, pv interface{}) *BarCharts {
 	if len(bcs.List) == 0 {
 		return bcs
@@ -441,7 +499,7 @@ func formatMonths(start, end int64, bcs *BarCharts, pv interface{}) *BarCharts {
 	return bcs
 }
 
-//环比增长率
+// 环比增长率
 func getGrowthRate(v1, v2 float64) float64 {
 	if v2 == 0 {
 		return 0
@@ -449,7 +507,6 @@ func getGrowthRate(v1, v2 float64) float64 {
 	return qutil.RetainDecimal((v1-v2)/v2*100, 2)
 }
 
-//
 func (r *Report) Tip() {
 	_, qk, qv := getQuery(r.Session())
 	if qk == "" || qv == nil {
@@ -553,7 +610,6 @@ func (r *Report) Starttime() {
 	})
 }
 
-//
 func getColl(referer, t string) (string, string) {
 	if t == "free" || strings.Contains(referer, "t=wx_experience") || strings.Contains(referer, "t=app_experience") {
 		return pushspace_experience_member_statistic, pushspace_experience_member_statistic_winner
@@ -571,7 +627,6 @@ func isFree(userId string, positionType int64, session *httpsession.Session) boo
 	return false
 }
 
-//
 func getQuery(sess *httpsession.Session) (string, string, interface{}) {
 	sessMap := sess.GetMultiple()
 	userId := qutil.ObjToString(sessMap["userId"])

+ 14 - 0
src/jfw/modules/publicapply/src/ad/entity/struct.go

@@ -71,3 +71,17 @@ func Handle(data []interface{}, host string) []AdInfo {
 	}
 	return res
 }
+
+// 获取当天剩余时间
+var (
+	timeOut int64 = 24 * 60 * 60
+)
+
+func GetLastTime() int64 {
+	t := time.Now()
+	midnight := time.Date(t.Year(), t.Month(), t.Day()+1, 0, 0, 0, 0, t.Location())
+	if midnight.After(t) {
+		return midnight.Unix() - t.Unix()
+	}
+	return timeOut
+}

+ 2 - 2
src/jfw/modules/publicapply/src/ad/service/actions.go

@@ -12,7 +12,7 @@ import (
 	"app.yhyue.com/moapp/jybase/go-xweb/xweb"
 )
 
-//JyAdvertisement 剑鱼广告位
+// JyAdvertisement 剑鱼广告位
 type JyAdvertisement struct {
 	*xweb.Action
 	getJyAdList xweb.Mapper `xweb:"/free/getJyAdList"` //获取剑鱼广告位
@@ -38,7 +38,7 @@ func (a *JyAdvertisement) GetJyAdList() {
 					if ok && res != nil && (*res)["a_son"] != nil {
 						son := (*res)["a_son"].([]interface{})
 						if len(son) > 0 {
-							redis.PutCKV("other", "ad_"+sCode, son)
+							redis.Put("other", "ad_"+sCode, son, int(entity.GetLastTime()))
 						}
 						adInfo = entity.Handle(son, a.Request.Host)
 					}

+ 1 - 1
src/jfw/modules/publicapply/src/userbase/bigmembermenu.json

@@ -98,7 +98,7 @@
 				"isusable":false
 			},
 			{
-				"name":"定制化分析报告",
+				"name":"市场分析报告",
 				"url":"/swordfish/page_big_pc/desktop/report_analysis",
 				"isusable":false
 			}

+ 1 - 1
src/jfw/modules/publicapply/src/userbase/commonfunctions.json

@@ -162,7 +162,7 @@
 			}
 		},
 		{
-			"name":"定制化分析报告",
+			"name":"市场分析报告",
 			"charge":true,
 			"pc":{
 				"url":"/swordfish/page_big_pc/desktop/report_analysis",

+ 7 - 16
src/jfw/tag/menu.go

@@ -61,23 +61,15 @@ func AllMenuCache() (cache *MenuCache) {
 	}
 	cache.BottomLinkMap, cache.TopMenuMap = map[int][]*TopMenuItem{}, map[int][]*TopMenuItem{}
 	for _, menu := range cache.AllMenu {
-		if len(menu.TopMenu) == 0 {
-			//默认主站展示
-			cache.TopMenuMap[mainSite] = append(cache.TopMenuMap[mainSite], menu)
-		} else {
-			for _, value := range menu.TopMenu {
-				cache.TopMenuMap[value] = append(cache.TopMenuMap[value], menu)
-			}
+
+		for _, value := range menu.TopMenu {
+			cache.TopMenuMap[value] = append(cache.TopMenuMap[value], menu)
 		}
 
-		if len(menu.BottomLink) == 0 {
-			//默认主站底部展示
-			cache.BottomLinkMap[mainSite] = append(cache.BottomLinkMap[mainSite], menu)
-		} else {
-			for _, value := range menu.BottomLink {
-				cache.BottomLinkMap[value] = append(cache.BottomLinkMap[value], menu)
-			}
+		for _, value := range menu.BottomLink {
+			cache.BottomLinkMap[value] = append(cache.BottomLinkMap[value], menu)
 		}
+
 	}
 
 	redis.Put("other", cacheKey, cache, -1)
@@ -89,7 +81,7 @@ func (mc *MenuCache) GetSite(url string, isTopMenu bool) int {
 	//配置文件
 	if url == "/" {
 		return mainSite
-	} else if url == "/brand/index" {
+	} else if url == "/brand" {
 		return brandFlag
 	}
 
@@ -102,7 +94,6 @@ func (mc *MenuCache) GetSite(url string, isTopMenu bool) int {
 			} else {
 				sites = item.BottomLink
 			}
-
 			break
 		}
 		for _, c := range item.Child {

BIN
src/web/staticres/big-member/image/landpage_new/itemB_04.jpg


BIN
src/web/staticres/big-member/image/landpage_new/itemB_04.png


+ 1 - 1
src/web/staticres/big-member/js/meauContact.js

@@ -439,7 +439,7 @@ var SCFX = [
         ]
       },
       {
-        two:"定制化市场分析报告",
+        two:"市场分析报告",
         three:[
           {
             threein:"可自定义分析条件,包含:分析内容、时间、地区、行业和采购单位类型。",

+ 1 - 0
src/web/staticres/big-member/js/unit_portrayal.js

@@ -1355,6 +1355,7 @@ var vNode = {
             var normal =['行业','采购规模占比','采购规模', '采购项目数量','平均节支率'];
             var newArr = that.arrTrans(5,arr);
             newArr.unshift(normal)
+            chartOptions.deformPieChart.roseType = false;
             chartOptions.deformPieChart.dataset.source = newArr;
             chartOptions.deformPieChart.tooltip.formatter = function(params){
                 var tip = '';

+ 52 - 1
src/web/staticres/common-module/collection/css/index.css

@@ -118,6 +118,7 @@
 
 .j-popup.collection .unitTab {
     height: 100%;
+    flex: 1;
 }
 
 .collection {
@@ -708,11 +709,11 @@
     flex-basis: auto !important;
     width: 2.5rem;
     min-height: .8rem;
-    height: .8rem;
     background: #f5f6f7;
     border: 0;
     padding: 0;
     color: inherit;
+    word-break: break-all;
 }
 
 .unitType .van-tabs__nav--complete {
@@ -842,6 +843,9 @@
 .select-area-box .van-index-bar__sidebar {
     top: 40%;
 }
+.area-content .select-area-box .van-index-bar__sidebar{
+  top: 65%;
+}
 
 .select-area-box .fix-bottom {
     box-sizing: border-box;
@@ -1493,3 +1497,50 @@
   margin-left: 0.08rem;
 
 }
+
+.filters-title {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: .32rem .32rem .12rem;
+  color: #171826;
+  line-height: .52rem;
+  font-size: .36rem;
+  font-weight: 400;
+}
+
+.j-popup .keys-popup .popup-header {
+  /* padding-top: .24rem;
+  padding-bottom: .24rem; */
+  display: flex;
+  flex-direction: column;
+  align-items: flex-start;
+  justify-content: center;
+  height: 1.28rem;
+  padding: 0 .32rem;
+}
+
+.keys-popup .header-top {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+.keys-popup .header-title {
+  margin-right: .2rem;
+}
+.keys-popup .header-action {
+  padding: 0 .32rem;
+  font-size: .26rem;
+  line-height: .42rem;
+  color: #2ABDD1;
+  background: rgba(42, 189, 209, 0.1);
+  border-radius: .24rem;
+  border: 1px solid #2ABDD1;
+}
+
+.keys-popup .header-bottom {
+  margin-top: .1rem;
+  color: #2ABDD1;
+  font-size: .22rem;
+  line-height: .26rem;
+}

BIN
src/web/staticres/common-module/collection/image/bg/vip_ex_6.png


BIN
src/web/staticres/common-module/collection/image/buyer/07.png


+ 66 - 10
src/web/staticres/common-module/collection/js/area-city-mobile.js

@@ -64,6 +64,11 @@ var areaCityMobileComponent = {
       default: function () {
         return {}
       }
+    },
+    // 是否设置全选时传空
+    issetallempty: {
+      type: Boolean,
+      default: false
     }
   },
   data:function () {
@@ -109,9 +114,31 @@ var areaCityMobileComponent = {
   },
   methods: {
     // 整理原始数据
-    getData: function () {
+    getData: function (newData) {
       var provinceListMapExp = this.provinceListMapExp
-
+      // 从父组件传进来的地区
+      if (newData && JSON.stringify(newData) !== '{}') {
+        let newProList = []
+        Object.keys(provinceListMapExp).forEach((v, i) => {
+          provinceListMapExp[v].forEach(m => {
+            Object.keys(newData).forEach(n => {
+              if (m == n) {
+                newProList.push({
+                  [v]: [n]
+                })
+              }
+            })
+          })
+        })
+        // 合并并去重数组中的元素
+        const result = newProList.reduce((acc, cur) => {
+          Object.keys(cur).forEach(key => {
+            acc[key] = Array.from(new Set([...(acc[key] || []), ...cur[key]]))
+          })
+          return acc
+        }, {})
+        provinceListMapExp = result
+      }
       // 整理数据得到indexListMap(),同时获得indexList
       const provinceListMap = {}
       const indexList = []
@@ -126,7 +153,7 @@ var areaCityMobileComponent = {
           }
 
           if (pName !== '全国') {
-            const cities = this.getCitiesFromJSONMap(pName)
+            let cities = this.getCitiesFromJSONMap(pName)
             // console.log(pName, cities)
             // 筛选掉直辖市和特别行政区(台湾省也不不需要展开)
             if (cities.ProRemark === '省份' || cities.ProRemark === '自治区') {
@@ -135,10 +162,22 @@ var areaCityMobileComponent = {
               } else {
                 cities.city.forEach(c => {
                   // 将市区重组成一个新的对象
-                  return provinceExp.children.push({
-                    name: c.name,
-                    type: false
-                  })
+                  if(newData && JSON.stringify(newData) !== '{}') {
+                    const apiArea = newData[pName]
+                    apiArea.forEach(v => {
+                      if (v == c.name) {
+                        return provinceExp.children.push({
+                          name: c.name,
+                          type: false
+                        })
+                      }
+                    })
+                  } else {
+                    return provinceExp.children.push({
+                      name: c.name,
+                      type: false
+                    })
+                  }
                 })
               }
             } else {
@@ -183,13 +222,18 @@ var areaCityMobileComponent = {
       // 设置全国(此处为全部未选中)
       if (!data || Object.keys(data).length === 0) {
         this.allStateChange(false)
-        this.setCountryState(true)
+        if(this.tablist[0].name === '全国') {
+          this.setCountryState(true)
+        } else {
+          this.setCountryState(false)
+        }
       } else {
         for (var key in data) {
           if (data[key].length === 0) {
             // 当前全省
             for (var i = 0; i < this.tablist.length; i++) {
               if (this.tablist[i].name === key) {
+                this.tablist[i].type = true
                 this.tablist[i].children.forEach(function (item) {
                   item.type = true
                 })
@@ -211,7 +255,9 @@ var areaCityMobileComponent = {
           }
           
         }
-        this.setCountryState(false)
+        if(this.tablist[0].name === '全国') {
+          this.setCountryState(false)
+        }
       }
     },
     // 获取当前选中状态
@@ -265,9 +311,9 @@ var areaCityMobileComponent = {
       if (item.name === '全国') {
         this.setState()
       } else {
-        this.setCountryState(false)
         // 子项跟随全选状态
         item.type = !item.type
+        // this.setCountryState(item.type)
         item.children.forEach(function (city) {
           city.type = item.type
         })
@@ -316,6 +362,16 @@ var areaCityMobileComponent = {
         data: state.state,
         count: state.count
       }
+      if(this.issetallempty) {
+        let hasFalseValue = false
+        if(this.tablist.length > 0) {
+          hasFalseValue = this.tablist.some(item => !item.type);
+        }
+        if(!hasFalseValue) {
+          params.data = {}
+          params.count = 0
+        }
+      }
       this.$emit('confirm', params)
       return params
     },

+ 78 - 1
src/web/staticres/common-module/collection/js/area-mobile.js

@@ -36,6 +36,26 @@ var areaComponent = {
         return []
       }
     },
+    // 新的省份数据,用于替换原始数组
+    newprovincelist: {
+      type: Object,
+      default () {
+        return {
+          // 安徽: ['合肥', '蚌埠'],
+          // 广州: ['广东', '揭阳']
+        }
+      }
+    },
+    // 是否展示全国按钮
+    showcountry: {
+      type: Boolean,
+      default: true
+    },
+    // 是否显示直辖市
+    showzxs: {
+      type: Boolean,
+      default: true
+    },
     initarealist: {
       type: Object,
       default: function () {
@@ -88,6 +108,14 @@ var areaComponent = {
         }
       },
       immediate: true
+    },
+    'newprovincelist' :{
+      handler(newval) {
+        if(Object.keys(newval) != 0) {
+          this.arrangeListMap(this.provinceListMap)
+        }
+      },
+      immediate: true
     }
   },
   created () {
@@ -99,11 +127,45 @@ var areaComponent = {
   methods: {
     // 整理数据得到indexListMap,同时获得indexList
     arrangeListMap: function (provinceListMap) {
+      if(Object.keys(this.newprovincelist).length > 0) {
+        let newProList = []
+        Object.keys(provinceListMap).forEach((v, i) => {
+          provinceListMap[v].forEach(m => {
+            Object.keys(this.newprovincelist).forEach(n => {
+              if (m == n) {
+                newProList.push({
+                  [v]: [n]
+                })
+              }
+            })
+          })
+        })
+        // 合并并去重数组中的元素
+        const result = newProList.reduce((acc, cur) => {
+          Object.keys(cur).forEach(key => {
+            acc[key] = Array.from(new Set([...(acc[key] || []), ...cur[key]]))
+          })
+          return acc
+        }, {})
+        provinceListMap = result
+      }
+      // 是否展示直辖市
+      if (!this.showzxs) {
+        provinceListMap = this.deleteZXSData(provinceListMap)
+      }
+      // 是否展示全国按钮
+      if(!this.showcountry) {
+        delete provinceListMap['#']
+      }
       this.indexList = []
       this.indexListMap = {}
 
       for (var key in provinceListMap) {
-        this.indexList.push(key)
+        if(provinceListMap[key].length == 0 && !this.showzxs) {
+          // this.indexList.push(key)
+        } else {
+          this.indexList.push(key)
+        }
         this.indexListMap[key] = provinceListMap[key].map(function (item) {
           return {
             name: item,
@@ -112,6 +174,19 @@ var areaComponent = {
         })
       }
     },
+    // 删除直辖市
+    deleteZXSData: function (data) {
+      for (var key in data) {
+        data[key].forEach((v, i) => {
+          chinaMapJSON.forEach(item => {
+            if (item.name.indexOf(v) !== -1 && (item.ProRemark === '直辖市' || item.ProRemark === '特别行政区')) {
+              data[key].splice(i, 1)
+            }
+          })
+        })
+      }
+      return data
+    },
     // 回显数据
     setState: function (data) {
       let optionArr = []
@@ -120,6 +195,7 @@ var areaComponent = {
       } else {
         optionArr = this.selectarealist
       }
+      const _this = this
       for (var key in this.indexListMap) {
         this.indexListMap[key].forEach(function (item) {
             item.selected = false
@@ -127,6 +203,7 @@ var areaComponent = {
               if(item.name == sum) {
                 item.selected = true
               }
+              _this.$forceUpdate()
             })
         })
       }

+ 49 - 2
src/web/staticres/common-module/collection/js/cate-mobile.js

@@ -79,6 +79,10 @@ var cateComponent = {
       default: function () {
         return []
       }
+    },
+    isAll: {
+      type: Boolean,
+      default: false
     }
   },
   template: cateComponentTemplate,
@@ -91,7 +95,7 @@ var cateComponent = {
     }
   },
   created () {
-    this.getData()
+    this.setNewSelect()
     this.setState()
     this.getbBtnClick()
   },
@@ -119,9 +123,14 @@ var cateComponent = {
       }
     },
     // 获取数据
-    getData: function(){
+    getData: function(data){
       const _this = this
       let maxarr = []
+      if(data) {
+        _this.tablist = data
+      } else {
+        _this.tablist = cateSimpleList
+      }
       _this.tablist.forEach(function(item,index) {
         let minarr = []
         let keyname = Object.keys(item)[0]
@@ -141,6 +150,35 @@ var cateComponent = {
       })
       _this.tablist = maxarr
     },
+    // 设置新的备选项
+    setNewSelect (buyerClass) {
+      if(!buyerClass) {
+        this.getData()
+      } else {
+        var allValues = [];
+        for (var i = 0; i < cateSimpleList.length; i++) {
+          var obj = cateSimpleList[i];
+          for (var key in obj) {
+            allValues = allValues.concat(obj[key]);
+          }
+        }
+
+        var result = [];
+        for (var i = 0; i < allValues.length; i++) {
+          var value = allValues[i];
+          if (buyerClass.indexOf(value) !== -1) {
+            result.push(value);
+          }
+        }
+
+        var output = [{
+          '党政机关事业单位': result.filter(value => cateSimpleList[0]['党政机关事业单位'].includes(value))
+        }, {
+          '企业': result.filter(value => cateSimpleList[1]['企业'].includes(value))
+        }]
+        this.getData(output)
+      }
+    },
     // 总全选
     checkBoxAll:function() {
       if(this.checkedAll){
@@ -263,6 +301,15 @@ var cateComponent = {
         data: cateArr,
         t: t
       }
+      if(this.isAll) {
+        if(this.checkedAll) {
+          params = {
+            name: 'cateItem',
+            data: [],
+            t: t
+          }
+        }
+      }
       this.$emit('confirm', params)
       return params
     }

+ 2 - 1
src/web/staticres/common-module/collection/js/chart_options.js

@@ -729,6 +729,7 @@ var chartOptions = {
         },
     },
     deformPieChart:{
+        roseType: true,
         dataset: {
             source: []
         },
@@ -784,7 +785,7 @@ var chartOptions = {
             clockWise: false,
             startAngle: 60,
             center: ['50%', '50%'],
-            roseType: 'area',
+            ...(this.roseType ? {roseType: 'area'} : {}),
             encode: {
                 x:0,
                 y:1,

+ 1 - 0
src/web/staticres/common-module/collection/js/ent_portrait.js

@@ -1229,6 +1229,7 @@ var vNode = {
       var normal = ['行业', '中标金额占比', '中标金额', '项目数量', '平均折扣率'];
       var newArr = that.arrTrans(5, arr);
       newArr.unshift(normal)
+      chartOptions.deformPieChart.roseType = false;
       chartOptions.deformPieChart.dataset.source = newArr;
       chartOptions.deformPieChart.tooltip.formatter = function (params) {
         var tip = '';

+ 32 - 16
src/web/staticres/common-module/collection/js/industry-mobile.js

@@ -74,6 +74,10 @@ var industryComponent = {
     'onlyshowsome': {
       type: Boolean,
       default: false
+    },
+    isAll: {
+      type: Boolean,
+      default: false
     }
   },
   template: industryComponentTemplate,
@@ -90,7 +94,7 @@ var industryComponent = {
       return 1
     }
   },
-  created () {
+  mounted () {
     this.getIndustryData()
     this.getbBtnClick()
   },
@@ -244,24 +248,26 @@ var industryComponent = {
         })
         this.canClick = bool
       } else {
-        indArr.forEach(function(sum) {
-          // newindArr.push(sum.split('_')[1])
-          newindArr.push({
-            key:sum.split('_')[0],
-            value:sum.split('_')[1]
+        if(JSON.stringify(indArr) !== "{}") {
+          indArr.forEach(function(sum) {
+            // newindArr.push(sum.split('_')[1])
+            newindArr.push({
+              key:sum.split('_')[0],
+              value:sum.split('_')[1]
+            })
           })
-        })
-        // console.log(newindArr)
-        this.tablist.forEach(function(item){
-          item[Object.keys(item)[0]].forEach(function(data) {
-            newindArr.forEach(function(sum) {
-              if(data.name == sum.value && Object.keys(item)[0] == sum.key) {
-                data.type = true
-                bool = false
-              }
+          // console.log(newindArr)
+          this.tablist.forEach(function(item){
+            item[Object.keys(item)[0]].forEach(function(data) {
+              newindArr.forEach(function(sum) {
+                if(data.name == sum.value && Object.keys(item)[0] == sum.key) {
+                  data.type = true
+                  bool = false
+                }
+              })
             })
           })
-        })
+        }
         this.canClick = bool
       }
       // this.checkSelectedAll()
@@ -424,6 +430,16 @@ var industryComponent = {
         detail: this.getSelected(),
         t: t
       }
+      if(this.isAll) {
+        if(this.checkedAll) {
+          params = {
+            name: 'industryItem',
+            data: [],
+            detail: {},
+            t: t
+          }
+        }
+      }
       this.$emit('confirm', params)
       return params
     }

+ 73 - 5
src/web/staticres/common-module/collection/js/keyword-mobile.js

@@ -46,7 +46,7 @@ var keywordComponentTemplate = `<div class="j-container">
             @click="toggleCheck(iitem, item)"
           >
             <template #title v-if="useKeyCard">
-              <span class="j-tag" :class="iitem.matchway == 1 ? 'tag-orange' : 'tag-green'">{{ iitem.matchway == 1 ? '模糊' : '精准' }}</span>
+              <span class="j-tag" v-if="keyformat=='all'" :class="iitem.matchway == 1 ? 'tag-orange' : 'tag-green'">{{ iitem.matchway == 1 ? '模糊' : '精准' }}</span>
               <span class="custom-title">{{ iitem.text || iitem.name }}</span>
             </template>
             <template #label v-if="useKeyCard && (iitem.notkey && iitem.notkey.length)">
@@ -73,6 +73,28 @@ var keywordComponentTemplate = `<div class="j-container">
 var keywordComponent = {
   name: 'keyword-mobile',
   props: {
+    // phrases: 只显示关键词组,all:显示所有关键词
+    keyformat: {
+      type: String,
+      default: 'all'
+    },
+    keyphraseslist: {
+      type: Array,
+      default: [
+        // "智慧社区",
+        // "智慧园区",
+        // "智慧城市",
+        // "智慧楼宇",
+        // "数字乡村",
+        // "智慧工地",
+        // "智慧生活"
+      ]
+    },
+    // 如果选择全部传空
+    isAll: {
+      type: Boolean,
+      default: false
+    },
     useKeyCard: {
       type: Boolean,
       default: false
@@ -136,12 +158,30 @@ var keywordComponent = {
           } else {
             _this.isvip = true
           }
-          _this.$nextTick(
-            _this.getData()
-          )
+          console.log(_this.keyphraseslist)
+          if (_this.keyphraseslist.length > 0) {
+            _this.tablist = _this.initKeyList(_this.keyphraseslist)
+          } else {
+            _this.$nextTick(
+              _this.getData()
+            )
+          }
         }
       })
     },
+    initKeyList (arr) {
+      const result = arr.map(item => ({
+        [item]: [
+          {
+            name: item,
+            text: item,
+            type: false
+          }
+        ],
+        type: false
+      }))
+      return result
+    },
     // 获取关键词数据
     getData: function(){
       const _this = this
@@ -304,6 +344,10 @@ var keywordComponent = {
               _this.setState()
             }
           }
+          if (_this.keyformat == 'phrases') {
+            // 只显示关键词组
+            _this.setInitList(_this.tablist)
+          }
           _this.checkNoKey()
         },
         error: function(err){
@@ -311,10 +355,24 @@ var keywordComponent = {
         }
       })
     },
-    setState: function() {
+    setInitList: function(arr) {
+      arr.forEach((v) => {
+        const ownKey = {
+          name: Object.keys(v)[0],
+          text: Object.keys(v)[0],
+          type: false
+        }
+        v[Object.keys(v)[0]] = []
+        v[Object.keys(v)[0]].push(ownKey)
+      })
+    },
+    setState: function(data) {
       var _this = this
       let bool = true
       let keyArr = this.selectkeywordlist
+      if(data) {
+        keyArr = data
+      }
       this.tablist.forEach(function(item) {
         item[Object.keys(item)[0]].forEach(function(data) {
           if (keyArr.indexOf(data.text) !== -1) {
@@ -495,6 +553,16 @@ var keywordComponent = {
         detail: detailArr,
         t: t
       }
+      if(this.isAll) {
+        if(this.checkedAll) {
+          params = {
+            name: 'keywordItem',
+            data: [],
+            detail: [],
+            t: t
+          }
+        }
+      }
       this.$emit('confirm', params)
     },
     checkNoKey () {

+ 23 - 0
src/web/staticres/common-module/filter/css/filter_limit.css

@@ -0,0 +1,23 @@
+.search-filters .filters-title, .search-filters .filters-title{
+  background-color: #fff;
+}
+
+.search-filters .van-collapse-item__content{
+  padding: 0;
+}
+.search-filters .van-collapse-item__title .van-cell__title{
+  font-size: .36rem;
+  color: #171826;
+}
+.search-filters .no-show-select .van-cell__value{
+  color: #2ABED1;
+}
+
+.search-filters .van-collapse-item__content .van-cell .van-cell__title{
+  font-size: .32rem;
+  color: #171826;
+}
+
+.search-filters .van-collapse-item__content .van-cell .van-cell__value {
+  font-size: .28rem;
+}

+ 89 - 0
src/web/staticres/common-module/filter/css/project_cell.css

@@ -0,0 +1,89 @@
+.project-cell{
+  padding: .32rem;
+}
+.ellipsis{
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.ellipsis-2{
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-line-clamp: 2;
+  -webkit-box-orient: vertical;
+  word-break: break-all;
+}
+.project-cell .project-cell-title{
+  width: 100%;
+  font-size: 16px;
+  line-height: 24px;
+  color: #171826;
+}
+.project-cell .project-cell-tags{
+  display: flex;
+  align-items: center;
+  margin: .2rem 0 .08rem;
+}
+.project-cell .project-cell-tags>span {
+  margin-right: .08rem;
+  padding: .02rem .16rem;
+  background: #F7F9FA;
+  border: 0.01rem solid rgba(0, 0, 0, 0.05);
+  border-radius: .08rem;
+  line-height: .36rem;
+  font-size: .24rem;
+  color: #5F5E64;
+}
+.project-cell .project-unit{
+  margin: .16rem 0;
+}
+.project-cell .project-unit .van-cell{
+  height: auto;
+  padding: .16rem;
+  background: linear-gradient(180deg, rgba(108, 218, 237, 0.2) 0%, rgba(255, 255, 255, 0) 100%);
+  border-radius: .12rem;
+}
+.project-cell .project-unit .van-cell .van-cell__title{
+  display: flex;
+  flex-direction: column;
+}
+.project-cell .project-unit .van-cell .van-cell__title .unit_title{
+  display: flex;
+}
+.project-cell .project-unit .van-cell .van-cell__title .unit_title>span:first-child{
+  font-size: .24rem;
+  color: #9B9CA3;
+}
+.project-cell .project-unit .van-cell .van-cell__title .unit_title>span:last-child{
+  display: block;
+  width: 4.6rem;
+  font-size: .26rem;
+  color: #171826;
+}
+.project-cell .project-unit .van-cell .van-cell__title .unit_title .winnerText, .project-cell .project-unit .van-cell .van-cell__title .unit_title .buyerText{
+  text-decoration: underline;
+}
+.van-cell__label{
+  display: flex;
+  align-items: center;
+}
+.van-cell__label>span:first-child {
+  color: #9B9CA3;
+}
+.van-cell__label>span:last-child {
+  color: #171826;
+}
+.project-cell .project-update-time .update-time{
+  display: flex;
+  align-items: center;
+  padding-left: .16rem;
+}
+.project-cell .project-update-time .update-time-label{
+  color: #9B9CA3;
+  font-size: .24rem;
+}
+.update-time-content{
+  color: #171826;
+  font-size: .2rem;
+}

+ 53 - 0
src/web/staticres/common-module/filter/css/project_header.css

@@ -0,0 +1,53 @@
+.project-detail-list {
+  background: #fff;
+}
+.project-detail-title{
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 0 .32rem;
+  height: .88rem;
+}
+.project-detail-title .p-d-t-left{
+  font-size: .28rem;
+  color: #5F5E64;
+}
+.project-detail-title .p-d-t-right {
+  display: flex;
+  align-items: center;
+  padding-right: .22rem;
+}
+.p-d-t-right .sort-label{
+  font-size: .28rem;
+  color: #9B9CA3;
+}
+
+.sort-type-title{
+  font-size: .28rem;
+  color: #5F5E64;
+}
+.sort-type-title .van-icon{
+  transform: rotate(90deg);
+  color: #C0C4CC;
+}
+.select_sort .van-cell{
+  padding: 0 .32rem;
+  height: .88rem;
+}
+.select_sort .van-cell.van-dropdown-item__option{
+  font-size: .28rem;
+  color: #5F5E64;
+}
+.select_sort .van-cell.activeColor{
+  color: #2ABED1;
+}
+.select_sort .van-cell .select_active{
+  width: .48rem;
+  height: .48rem;
+}
+
+.van-list__finished-text{
+  background: #F0F0F0;
+  color: #686868;
+}
+

BIN
src/web/staticres/common-module/filter/image/right.png


+ 599 - 0
src/web/staticres/common-module/filter/js/filter_limit.js

@@ -0,0 +1,599 @@
+var filterTemp = `
+<div class="search-filters">
+  <van-collapse v-model="activeNames">
+    <van-collapse-item :title="title" name="1">
+      <div class="j-main">
+        <van-cell-group class="filters-list">
+            <van-cell center :class="{'no-show-select': colorEdit.keys}"  v-if="filterAction.keyModule.isShow" :title="filterAction.keyModule.label" is-link value-class="ellipsis" :value="resolveSelected('keys')" @click="clickCell('keys')"></van-cell>
+            <van-cell center :class="{'no-show-select': colorEdit.area}" v-if="filterAction.areaModule.isShow" :title="filterAction.areaModule.label" is-link value-class="ellipsis" :value="resolveSelected('area')" @click="clickCell('area')"></van-cell>
+            <van-cell center :class="{'no-show-select': colorEdit.buyerclass}" v-if="filterAction.buyerModule.isShow" :title="filterAction.buyerModule.label" value-class="ellipsis" is-link :value="resolveSelected('buyerclass')" @click="clickCell('buyerclass')"></van-cell>
+            <van-cell center :class="{'no-show-select': colorEdit.industry}" v-if="filterAction.industryModule.isShow" :title="filterAction.industryModule.label" is-link value-class="ellipsis" :value="resolveSelected('industry')" @click="clickCell('industry')"></van-cell>
+            <van-field type="textarea" rows="1" autosize v-model="filters.winnerUnit" label="中标单位" placeholder="请输入中标单位"></van-field>
+            <van-field type="textarea" rows="1" autosize v-model="filters.buyerUnit" label="采购单位" placeholder="请输入采购单位"></van-field>
+        </van-cell-group>
+      </div>
+      <div class="j-footer j-button-group">
+          <button class="j-button-cancel" @click="resetAllFilters">{{cancelText}}</button>
+          <button class="j-button-confirm" @click="startAnalysis">{{confirmText}}</button>
+      </div>
+    </van-collapse-item>
+  </van-collapse>
+  <van-popup
+  v-model="filterDialogShow.keys"
+  closeable
+  round
+  position="bottom"
+  close-icon="clear"
+  class="j-popup collection"
+  overlay-class="j-overlay"
+  :lazy-render="false"
+  :style="{ height: '60%' }"
+  get-container="body">
+  <div class="j-container keys-popup">
+      <div class="popup-header">
+          <div class="header-top">
+              <div class="header-title">选择分析内容</div>
+              <div v-if="showTip" class="header-action" @click="toSubManageButtonClick">订阅管理</div>
+          </div>
+          <div v-if="showTip" class="header-bottom">注:如需新增分析内容,请完善您的订阅关键词</div>
+      </div>
+      <div class="j-main">
+          <keyword-component
+              ref="keywordSelector"
+              protype="bigmember"
+              :is-all="setAll.keysAll"
+              :keyphraseslist="keyphraseslist"
+              :keyformat="keyformat"
+              :use-key-card="true"
+              @nokeys="showSetKeyTip"
+              @cancel="cancel($event, 'keys')"
+              @confirm="confirm($event, 'keys')"
+              :selectkeywordlist="filters.selectKeysArr"></keyword-component>
+      </div>
+  </div>
+</van-popup>
+<van-popup
+  v-model="filterDialogShow.area"
+  closeable
+  round
+  position="bottom"
+  close-icon="clear"
+  :lazy-render="false"
+  class="j-popup collection"
+  overlay-class="j-overlay"
+  :style="{ height: '60%' }"
+  get-container="body">
+  <div class="j-container report-popup">
+      <div class="popup-header header-title">选择区域</div>
+      <div class="j-main">
+          <area-city-mobile
+              :issetallempty="true"
+              :is-all="setAll.areaAll"
+              ref="areaCitySelector"
+              @cancel="cancel($event, 'area')"
+              @confirm="confirm($event, 'area')"></area-city-mobile>
+      </div>
+  </div>
+</van-popup>
+<van-popup
+  v-model="filterDialogShow.industry"
+  closeable
+  round
+  position="bottom"
+  close-icon="clear"
+  class="j-popup collection"
+  overlay-class="j-overlay"
+  :lazy-render="false"
+  :style="{ height: '60%' }"
+  get-container="body">
+  <div class="j-container report-popup">
+      <div class="popup-header header-title">选择行业</div>
+      <div class="j-main">
+          <industry-component
+              ref="industrySelector"
+              :is-all="setAll.industryAll"
+              :selectindustrylist="filters.industry"
+              @cancel="cancel($event, 'industry')"
+              @confirm="confirm($event, 'industry')"></industry-component>
+      </div>
+  </div>
+</van-popup>
+<van-popup
+  v-model="filterDialogShow.buyerclass"
+  closeable
+  round
+  position="bottom"
+  close-icon="clear"
+  class="j-popup collection"
+  :lazy-render="false"
+  overlay-class="j-overlay"
+  :style="{ height: '60%' }"
+  get-container="body">
+  <div class="j-container report-popup">
+      <div class="popup-header header-title">选择采购单位类型</div>
+      <div class="j-main">
+          <cate-component
+              ref="buyerclassSelector"
+              :is-all="setAll.buyerAll"
+              :selectcatelist="filters.buyerclass"
+              @cancel="cancel($event, 'buyerclass')"
+              @confirm="confirm($event, 'buyerclass')"></cate-component>
+      </div>
+  </div>
+</van-popup>
+</div>
+`
+
+var filterComponent = {
+  
+  name: 'filter-limit',
+  template: filterTemp,
+  components: {
+    keywordComponent: keywordComponent,
+    areaCityMobile: areaCityMobileComponent,
+    industryComponent: industryComponent,
+    cateComponent: cateComponent
+  },
+  props: {
+    switch: {
+      type: Boolean,
+      default: false
+    },
+    // phrases: 只显示关键词组,all:显示所有关键词
+    keyformat: {
+      type: String,
+      default: 'all'
+    },
+    // 关键词组列表
+    keyphraseslist: {
+      type: Array,
+      default: []
+    },
+    // 区域列表
+    arealist: {
+      type: Object,
+      default: {
+        // "四川": [
+        //   "成都市"
+        // ],
+        // "广东": [
+        //   "深圳市"
+        // ]
+      }
+    },
+    title: {
+      type: String,
+      default: '筛选条件'
+    },
+    cancelText: {
+      type: String,
+      default: '重置'
+    },
+    confirmText: {
+      type: String,
+      default: '确定'
+    },
+    showTip: {
+      type: Boolean,
+      default: true
+    },
+    showSelect: {
+      type: Boolean,
+      default: true
+    },
+    // 筛选条件回显
+    filtersdata: {
+      type: Object,
+      default () {
+        return {
+          // selectKeysArr: [], // 关键词简单数组,用于恢复选择状态
+          // keys: [], // 关键词详细数组,用于提交数据
+          // area: {},
+          // industry: [],
+          // industryDetail: {},
+          // buyerclass: [],
+          // rangeTime: {
+          //   start: '',
+          //   end: '',
+          //   exact: 'sinceYearBeforeLast',
+          // }
+        }
+      }
+    },
+    initfilters: {
+      type: Object,
+      default () {
+        return {
+          keys: [],
+          area: {},
+          industry: [],
+          industryDetail: {},
+          buyerclass: []
+        }
+      },
+    },
+    filterAction: {
+      type: Object,
+      default () {
+        return {
+          keyModule: {
+            label: '关键词组',
+            isShow: true
+          },
+          areaModule: {
+            label: '项目地区',
+            isShow: true
+          },
+          buyerModule: {
+            label: '采购单位类型',
+            isShow: true
+          },
+          industryModule: {
+            label: '行业',
+            isShow: true
+          },
+          winnerModule: {
+            label: '中标单位',
+            isShow: true
+          },
+          buyerUnit: {
+            label: '采购单位',
+            isShow: true
+          }
+        }
+      }
+    },
+    anyncdata: {
+      type: Boolean,
+      default: false
+    }
+  },
+  watch: {
+    anyncdata: {
+      handler (newval) {
+        if(newval) {
+          this.$refs.areaCitySelector.getData(this.initfilters.area)
+          if(this.initfilters.buyerclass.length > 0) {
+            this.$refs.buyerclassSelector.setNewSelect(this.initfilters.buyerclass)
+          } else {
+            this.$refs.buyerclassSelector.setNewSelect()
+          }
+        }
+      },
+      immediate: true
+    },
+    filtersdata: {
+      handler (newval) {
+        Object.assign(this.filters, newval)
+      },
+      immediate: true,
+      deep: true
+    },
+    switch: {
+      handler (newval) {
+        if(newval) {
+          setTimeout(() => {
+            this.startAnalysis()
+          }, 200)
+        }
+      },
+      immediate: true
+    },
+    'filters.industry': {
+      handler (newVal) {
+        if (newVal && newVal !== '{}') {
+          var industry = []
+          for (var key in this.filters.industryDetail) {
+            this.filters.industryDetail[key].forEach(function (item) {
+              industry.push(key + '_' + item)
+            })
+          }
+          newVal = industry
+        }
+      },
+      immediate: true
+    }
+  },
+  data () {
+    return {
+      filters: {
+        selectKeysArr: [], // 关键词简单数组,用于恢复选择状态
+        keys: [], // 关键词详细数组,用于提交数据
+        area: {},
+        industry: [],
+        industryDetail: {},
+        buyerclass: [],
+        buyerUnit: '',
+        winnerUnit: '',
+        rangeTime: {
+          start: '',
+          end: '',
+          exact: 'sinceYearBeforeLast',
+        },
+      },
+      filterDialogShow: {
+        keys: false,
+        area: false,
+        industry: false,
+        buyerclass: false,
+        rangeTime: false
+      },
+      activeNames: ['0'],
+      colorEdit: {
+        keys: false,
+        area: false,
+        industry: false,
+        buyerclass: false
+      },
+      setAll: {
+        keysAll: true,
+        areaAll: true,
+        buyerAll: true,
+        industryAll: true,
+      }
+    }
+  },
+  mounted () {
+    // if (Object.keys(this.arealist).length > 0) {
+    //   this.$refs.areaCitySelector.getData(this.arealist)
+    // }
+    try {
+      this.$refs.areaCitySelector.getData(this.initfilters.area)
+      if(this.initfilters.buyerclass.length > 0) {
+        this.$refs.buyerclassSelector.setNewSelect(this.initfilters.buyerclass)
+      } else {
+        this.$refs.buyerclassSelector.setNewSelect()
+      }
+    } catch (error) {
+      
+    }
+  },
+  methods: {
+    cancel: function (e, key) {
+      var dialog = this.filterDialogShow
+      this.resetFilter(key)
+      this.colorEdit[key] = false
+      dialog[key] = false
+    },
+    confirm: function (e, key) {
+      var dialog = this.filterDialogShow
+      var filters = this.filters
+      if (key === 'keys') {
+        filters.keys = e.detail
+        filters.selectKeysArr = e.data
+        this.anyncdata = false
+      } else if (key === 'area') {
+        filters.area = e.data
+      } else if (key === 'industry') {
+        filters.industry = e.data
+        filters.industryDetail = e.detail
+      } else if (key === 'buyerclass') {
+        filters.buyerclass = e.data
+        console.log(e.data)
+      } 
+      this.colorEdit[key] = true
+      dialog[key] = false
+    },
+    showLoading: function () {
+      return this.$toast.loading({
+        duration: 0,
+        forbidClick: true,
+        message: 'loading...',
+      })
+    },
+    setKeyTip: function () {
+      this.showDialog({
+        title: '',
+        message: '分析内容为您订阅的关键词组,您<br />当前尚未订阅,请前往完善',
+        className: 'j-confirm-dialog text-center',
+        showConfirmButton: true,
+        showCancelButton: true,
+        confirmButtonText: '订阅管理',
+        confirmButtonColor: '#2abed1'
+      }).then(() => {
+        if (this.isSubCount) {
+          // 提示联系管理员
+          this.showToast('请联系管理员完善订阅的关键词')
+          // this.showDialog({
+          //   title: '',
+          //   message: '请联系管理员完善订阅的关键词',
+          //   className: 'j-confirm-dialog text-center',
+          //   showConfirmButton: true,
+          //   showCancelButton: false,
+          //   confirmButtonText: '我知道了',
+          //   confirmButtonColor: '#2abed1'
+          // })
+        } else {
+          this.toSubManage()
+        }
+      })
+    },
+    clickCell: function (key) {
+      var _this = this
+      console.log(_this.$refs)
+      var dialog = this.filterDialogShow
+      if (key === 'keys') {
+        if (this.notSetKey) {
+          return this.setKeyTip()
+        }
+        if(this.filters.selectKeysArr && this.filters.selectKeysArr.length > 0) {
+          _this.$refs.keywordSelector.setState(this.filters.selectKeysArr.join(','))
+        }
+      } else if (key === 'area') {
+        setTimeout(function () {
+          _this.$refs.areaCitySelector.setState(_this.filters.area)
+        }, 200)
+      } else if (key === 'buyerclass') {
+        setTimeout(function () {
+          _this.$refs.buyerclassSelector.setState()
+        }, 200)
+      }  else if (key === 'industry') {
+        setTimeout(function () {
+          _this.$refs.industrySelector.setState()
+        }, 200)
+      }
+      dialog[key] = true
+    },
+    resolveSelected: function (type) {
+      var filters = this.filters
+      var prefix = '已选:'
+      var text = ''
+      if (type === 'keys') {
+        if (this.notSetKey) return '请设置'
+        text = this.resolveSelectKeysText(filters.keys)
+      } else if (type === 'area') {
+        text = this.resolveSelectAreaText(filters.area)
+      } else if (type === 'industry') {
+        text = this.resolveSelectIndustryText(filters.industryDetail)
+      } else if (type === 'buyerclass') {
+        text = this.resolveSelectBuyerclassText(filters.buyerclass)
+      }
+      if ((text != '全部' && text != '全国') && !this.showSelect) {
+        this.colorEdit[type] = true
+        return text
+      } else {
+        return prefix + text
+      }
+    },
+    resolveSelectKeysText: function (keys) {
+      if (Array.isArray(keys)) {
+        if (keys.length === 0) {
+          return '全部'
+        } else {
+          var count = 0
+          var arr = []
+          keys.forEach(function (classify) {
+            if (Array.isArray(classify.a_key) && classify.a_key.length) {
+              count += classify.a_key.length
+              classify.a_key.forEach(function (item) {
+                arr.push(item.key.join(' '))
+              })
+            }
+          })
+          if (count <= 0) {
+            return '全部'
+          } else {
+            return arr.join(',')
+          }
+        }
+      } else {
+        return '全部'
+      }
+    },
+    resolveSelectAreaText: function (area) {
+      if (!area || Object.keys(area).length === 0) return '全国'
+      var areaArr = []
+      var cityArr = []
+      for (var key in area) {
+        if (area[key].length === 0) {
+          areaArr.push(key)
+        } else {
+          cityArr = cityArr.concat(area[key])
+        }
+      }
+      return areaArr.concat(cityArr).join(',')
+    },
+    resolveSelectIndustryText: function (industry) {
+      if (!industry || Object.keys(industry).length === 0) return '全部'
+      var keyArr = []
+      var valueArr = []
+      for (var key in industry) {
+        if (industry[key].length === 0) {
+          keyArr.push(key)
+        } else {
+          valueArr = valueArr.concat(industry[key])
+        }
+      }
+      return keyArr.concat(valueArr).join(',')
+    },
+    resolveSelectBuyerclassText: function (buyerclass) {
+      if (!Array.isArray(buyerclass)) return '全部'
+      if (buyerclass.length === 0) return '全部'
+      return buyerclass.join(',')
+    },
+    resetAllFilters: function () {
+      this.resetFilter('all')
+    },
+    getSelectedKeys () {
+      const keys = this.filters.keys
+      if (Array.isArray(keys) && keys.length) {
+        return keys
+      } else {
+        if (this.setAll.keysAll) {
+          return []
+        } else {
+          if(this.$refs.keywordSelector) {
+            var allKeys = this.$refs.keywordSelector.keywordGroupList
+            return allKeys
+          } else {
+            return []
+          }
+        }
+      }
+    },
+    startAnalysis: function () {
+      // this.dateTimeSelectorConfirm()
+
+      const query = {
+        items: this.getSelectedKeys(),
+        selectKeysArr: this.filters.selectKeysArr,
+        area: this.filters.area,
+        industry: this.filters.industry,
+        industryDetail: this.filters.industryDetail,
+        buyerclass: this.filters.buyerclass,
+        winner: this.filters.winnerUnit,
+        buyer: this.filters.buyerUnit
+      }
+      this.$emit('confirm', query)
+    },
+    // 重置
+    resetFilter: function (type) {
+      var filters = this.filters
+      if (type === 'keys') {
+        filters.keys = []
+        filters.selectKeysArr = []
+        try {
+          this.$refs.keywordSelector.resetAllNoSelect()
+        } catch (error) {}
+      } else if (type === 'area') {
+        filters.area = {}
+      } else if (type === 'industry') {
+        filters.industry = []
+        filters.industryDetail = {}
+      } else if (type === 'buyerclass') {
+        filters.buyerclass = []
+      } else if (type === 'buyerUnit') {
+        this.filters.buyerUnit = ''
+      } else if (type === 'winnerUnit') {
+        this.filters.winnerUnit = ''
+      } else {
+        this.resetFilter('keys')
+        this.resetFilter('area')
+        this.resetFilter('industry')
+        this.resetFilter('buyerclass')
+        this.resetFilter('buyerUnit')
+        this.resetFilter('winnerUnit')
+      }
+    },
+    toSubManageButtonClick: function () {
+      if (this.isSubCount) {
+        this.showToast('请联系管理员完善订阅的关键词')
+      } else {
+        this.toSubManage()
+      }
+    },
+    toSubManage: function () {
+      location.href = '/jyapp/vipsubscribe/toSetKeyWordPage?vSwitch=m'
+    },
+    showToast: function (message) {
+      return this.$toast({
+        duration: 1500,
+        forbidClick: true,
+        message: message,
+      })
+    },
+    showSetKeyTip: function () {
+      this.notSetKey = true
+    },
+  }
+}

+ 141 - 0
src/web/staticres/common-module/filter/js/project_cell.js

@@ -0,0 +1,141 @@
+var projectCellTemp = `
+<div class="project-cell">
+  <div @click="setLinkUrl(item)" class="project-cell-title ellipsis-2">
+    {{ item.name }}
+  </div>
+  <div class="project-cell-tags">
+    <span v-if="item.area">{{ item.area }}</span>
+    <span v-if="item.bidStatus && item.bidStatus!=='其它'">{{ item.bidStatus }}</span>
+    <span v-if="item.buyerClass && item.buyerClass!=='其它'">{{ item.buyerClass }}</span>
+    <span v-if="item.budget||item.bidAmount">{{ setBidAmount || setBudget }}</span>
+  </div>
+  <div class="project-unit">
+    <van-cell :is-link="getBuyer" @click="setBuyerLink(item)">
+      <template #title>
+        <div class="unit_title">
+          <span>采购单位:</span>
+          <span class="ellipsis" :class="{buyerText:getBuyer}">{{ item.buyer || '--' }}</span>
+          </div>
+      </template>
+      <template #label>
+        <span>预算金额:</span>
+        <span>{{ setBudget || '--' }}</span>
+      </template>
+    </van-cell>
+  </div>
+  <div class="project-unit">
+    <van-cell :is-link="getWinnerID" @click="setWinnerLink($event, item)">
+      <template #title>
+        <div class="unit_title">
+          <span>中标单位:</span>
+          <span v-html="setWinner"></span>
+        </div>
+      </template>
+      <template #label>
+        <span>中标金额:</span>
+        <span>{{ setBidAmount || '--' }}</span>
+      </template>
+    </van-cell>
+  </div>
+  <div class="project-update-time">
+    <slot></slot>
+  </div>
+</div>
+`
+
+var projectCellComponent = {
+  
+  name: 'project-cell',
+  template: projectCellTemp,
+  props: {
+    item: {
+      type: Object,
+      default: {}
+    }
+  },
+  computed: {
+    getWinnerID () {
+      if(this.item.winnerId) {
+        this.item.winnerId.filter(function(str) {
+          return str.trim() !== ""
+        })
+        if (this.item.winnerId.length > 0) {
+          return true
+        } else {
+          return false
+        }
+      } else {
+        return false
+      }
+    },
+    getBuyer () {
+      if(this.item.buyer) {
+        return true
+      } else {
+        return false
+      }
+    },
+    setBidAmount () {
+      if (this.item.bidAmount >= 10000) {
+        return this.item.bidAmount ? utils.moneyUnit(this.item.bidAmount, 'transfer', '万元') : ''
+      } else {
+        return this.item.bidAmount ? utils.moneyUnit(this.item.bidAmount) : ''
+      }
+    },
+    setBudget () {
+      if(this.item.budget >= 10000) {
+        return this.item.budget ? utils.moneyUnit(this.item.budget, 'transfer', '万元') : ''
+      } else {
+        return this.item.budget ? utils.moneyUnit(this.item.budget) : ''
+      }
+    },
+    setWinner () {
+      if (this.item.winner) {
+        this.item.winner.forEach((v, i) => {
+          if(v == '') {
+            this.item.winner.splice(i, 1)
+          }
+        })
+        // this.item.winner = this.item.winner.filter(str => str.trim() !== '')
+        if(this.item.winnerId) {
+          this.item.winnerId = this.item.winnerId.filter(str => str.trim() !== '')
+        }
+        if (this.item.winner.length > 0) {
+          this.item.winner.map((v, i) => {
+            this.item.winner[i] = `<span class="winnerText" winnerId="${this.item.winnerId ? this.item.winnerId[i] : ''}">${v}</span>`
+          })
+        } else {
+          return '--'
+        }
+        return this.item.winner.join('、')
+      } else {
+        return '--'
+      }
+    }
+  },
+  data () {
+    return {
+    }
+  },
+  methods: {
+    // 点击项目名称跳转到项目详情页
+    setLinkUrl (item) {
+      const params = {
+        sid: item.id
+      }
+      sessionStorage.setItem('bigvip-fid', JSON.stringify(params))
+      this.$emit('set-link-url')
+    },
+    // 点击采购单位到采购单位画像
+    setBuyerLink (item) {
+      this.$emit('set-buyer-link')
+    },
+    // 点击中标单位到企业画像
+    setWinnerLink (e, item) {
+      const winnerId = $(e.target).attr('winnerid')
+      if(winnerId) {
+        this.$emit('set-winner-link', winnerId)
+      }
+    }
+  }
+}

+ 91 - 0
src/web/staticres/common-module/filter/js/project_header.js

@@ -0,0 +1,91 @@
+var projectHeaderTemp = `
+<div class="project-detail-title">
+  <div class="p-d-t-left" v-if="showtotal">
+    共<span style="color:#2ABED1"> {{ total }} </span>个项目
+  </div>
+  <div class="p-d-t-right">
+    <span class="sort-label" v-if="showtotal">排序:</span>
+    <div class="sort-type-title" @click="setSortType">
+      <span>{{ sortTitle }}</span>
+      <van-icon name="play"></van-icon>
+    </div>
+  </div>
+  <van-popup
+    v-model="showSortPopup"
+    closeable
+    round
+    position="bottom"
+    close-icon="clear"
+    class="j-popup collection select_sort"
+    :lazy-render="false"
+    overlay-class="j-overlay"
+    get-container="body">
+    <div class="j-container report-popup">
+        <div class="popup-header header-title">请选择排序</div>
+        <div class="j-main">
+          <van-cell center :class="{'activeColor': item.active}" @click="setSortRules(item)" :title="item.text" v-for="(item, index) in sortOption" :key="index">
+            <template #right-icon>
+              <img v-if="item.active" class="select_active" src="/common-module/filter/image/right.png" alt="">
+            </template>
+          </van-cell>
+        </div>
+    </div>
+  </van-popup>
+</div>
+`
+
+var projectHeaderComponent = {
+  name: 'project-detail-title',
+  template: projectHeaderTemp,
+  props: {
+    total: {
+      type: String,
+      default: ''
+    },
+    showtotal: {
+      type: Boolean,
+      default: true
+    },
+    sortOptiontitle: {
+      type: String,
+      default: '项目更新时间由晚到早'
+    },
+    sortOption: {
+      type: Array,
+      default () {
+        return [
+          { text: '项目更新时间由晚到早', value: 0, active: true },
+          { text: '项目金额由大到小', value: 1, active: false }
+        ]
+      }
+    }
+  },
+  data () {
+    return {
+      showSortPopup: false,
+      sortTitle: this.sortOptiontitle
+    }
+  },
+  methods: {
+    setSortType () {
+      this.sortOption.forEach(v => {
+        v.active = false
+        if(v.text === this.sortTitle) {
+          v.active = true
+        }
+      })
+      this.showSortPopup = true
+    },
+    // 选择排序方式
+    setSortRules: function (data) {
+      this.sortOption.forEach(option => {
+        option.active = false
+      })
+      data.active = true
+      this.sortTitle = data.text
+      this.$emit('setsort', data.value)
+      // 关闭菜单
+      this.showSortPopup = false
+    },
+  }
+}

+ 8 - 2
src/web/staticres/common-module/perfect-info/js/perfect-info.js

@@ -42,7 +42,9 @@ var titleMap = {
   wx_subscribe_cqxm: '欢迎体验剑鱼大会员',
   wx_search_cqxm: '欢迎体验剑鱼大会员',
   wx_subscribe_dzhfxbg: '欢迎体验剑鱼大会员',
-  wx_search_dzhfxbg: '欢迎体验剑鱼大会员'
+  wx_search_dzhfxbg: '欢迎体验剑鱼大会员',
+  app_analysis_ProjectDetails: '欢迎体验剑鱼大会员',
+  wx_analysis_ProjectDetails: '欢迎体验剑鱼大会员',
 }
 
 // tip
@@ -131,7 +133,9 @@ var tipMap = {
   wx_subscribe_cqxm: '请完善个人信息,我们将尽快与您联系,体验超前项目推荐服务!',
   wx_search_cqxm: '请完善个人信息,我们将尽快与您联系,体验超前项目推荐服务!',
   wx_subscribe_dzhfxbg: '请完善个人信息,我们将尽快与您联系,为您量身定制报告,做市场复盘数据支持。',
-  wx_search_dzhfxbg: '请完善个人信息,我们将尽快与您联系,为您量身定制报告,做市场复盘数据支持。'
+  wx_search_dzhfxbg: '请完善个人信息,我们将尽快与您联系,为您量身定制报告,做市场复盘数据支持。',
+  wx_analysis_ProjectDetails: '请完善个人信息,我们将尽快与您联系,为您量身定制报告,做市场复盘数据支持。',
+  app_analysis_ProjectDetails: '请完善个人信息,我们将尽快与您联系,为您量身定制报告,做市场复盘数据支持。'
 }
 
 var vNode = {
@@ -344,6 +348,8 @@ var vNode = {
         case 'h5_search_dzhfxbg':
         case 'wx_subscribe_cqxm':
         case 'wx_search_cqxm':
+        case 'app_analysis_ProjectDetails':
+        case 'wx_analysis_ProjectDetails':
         case 'wx_subscribe_dzhfxbg':
         case 'wx_search_dzhfxbg': {
           hideLabel()

+ 90 - 0
src/web/staticres/common-module/public/css/empty.css

@@ -0,0 +1,90 @@
+.empty-container {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  flex: 1;
+  min-height: 6.4rem;
+  padding: 16px;
+  box-sizing: border-box;
+  background: #fff;
+}
+
+.empty-container .empty-content-position {
+  display: flex;
+  align-items: center;
+  flex-direction: column;
+  justify-content: center;
+  margin-top: 0;
+}
+
+.empty-container .empty-main {
+  display: flex;
+  align-items: center;
+  flex-direction: column;
+  justify-content: center;
+  text-align: center;
+}
+
+.empty-container .max-width70 {
+  width: 70%;
+}
+
+.empty-container .max-width80 {
+  width: 80%;
+}
+
+.empty-container .tip-text {
+  color: #5f5e64;
+  font-size: 14px;
+  line-height: 20px;
+  text-align: center;
+}
+
+.empty-container .tip-sub-text {
+  color: #9b9ca3;
+  font-size: 13px;
+  line-height: 20px;
+  margin-top: 6px;
+  text-align: center;
+}
+
+.empty-container .image {
+  width: 200px;
+  height: 200px;
+}
+
+.empty-container .image.empty-box {
+  margin-top: unset;
+  width: 160px;
+  height: 160px;
+}
+
+.empty-container .fixed-position {
+  margin-top: -50px;
+}
+
+.empty-container .empty-back {
+  background: url(../image/jy-back.png) no-repeat;
+  background-size: contain;
+}
+
+.empty-container .empty-cry {
+  background: url(../image/jy-cry.png) no-repeat;
+  background-size: contain;
+}
+
+.empty-container .empty-chagrin {
+  background: url(../image/jy-chagrin.png) no-repeat;
+  background-size: contain;
+}
+
+.empty-container .empty-sleep {
+  background: url(../image/jy-sleep.png) no-repeat;
+  background-size: contain;
+}
+
+.empty-container .empty-smile {
+  background: url(../image/jy-smile.png) no-repeat;
+  background-size: contain;
+}

+ 46 - 0
src/web/staticres/common-module/public/js/empty.js

@@ -0,0 +1,46 @@
+var emptyTemp = `
+<div class="empty-container">
+  <div class="empty-content-position">
+    <div class="image" :class="stateClass"></div>
+    <div class="empty-main tip-text">
+      <slot name="default"></slot>
+    </div>
+  </div>
+</div>
+`
+
+var emptyComponent = {
+  name: 'empty-container',
+  template: emptyTemp,
+  props: {
+    /**
+     * 图标名称 back [back cry chagrin sleep smile box]
+     */
+    state: {
+      type: String,
+      default: 'back'
+    }
+  },
+  computed: {
+    stateClass () {
+      const imgType = this.typeSrc[this.state]
+      const classArr = [imgType]
+      if (!window.utils.$envs.inH5) {
+        classArr.push('fixed-position')
+      }
+      return classArr
+    }
+  },
+  data () {
+    return {
+      typeSrc: {
+        back: 'empty-back',
+        cry: 'empty-cry',
+        chagrin: 'empty-chagrin',
+        sleep: 'empty-sleep',
+        smile: 'empty-smile',
+        box: 'empty-box'
+      }
+    }
+  }
+}

+ 103 - 0
src/web/staticres/common-module/report-analysis/css/report_analysis.css

@@ -332,6 +332,81 @@
 .search-result .dimension .section-content {
   padding: .28rem 0;
 }
+
+.section-content .progress-bar-container {
+  background-color: #fff;
+  padding: 0 0 .32rem;
+}
+
+.section-content .progress-bar-item {
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  /* height: 1.04rem; */
+  margin-top: .28rem;
+}
+
+.section-content .progress-bar-item .item-label {
+  display: flex;
+  justify-content: space-between;
+}
+
+.section-content .progress-bar-item .item-label .item-name {
+  font-size: .26rem;
+  line-height:.4rem;
+  color: #5F5E64;
+  flex: 1;
+}
+
+.section-content .progress-bar-item .item-label .item-count {
+  font-size: .26rem;
+  color: #171826;
+  line-height:.4rem;
+}
+
+.section-content .progress-bar-item .item-progress {
+  position: relative;
+  height: .2rem;
+  background-color: #EDEFF2;
+  border-radius: 0 .28rem .28rem 0;
+  overflow: hidden;
+  margin-top: .14rem;
+}
+
+.section-content .progress-bar-item .item-progress-count {
+  position: absolute;
+  top: 0;
+  left: 0;
+  height: 100%;
+  border-radius: 0 .28rem .28rem 0;
+}
+.section-content .yellow-progress{
+  background: linear-gradient(to right,#FAE7CA, #F1D090);
+}
+.section-content .blue-progress{
+  background: linear-gradient(to right,#8DE0EB, #2ABED1);
+}
+.section-content .section-content-header{
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  height: .88rem;
+}
+.set-area-city{
+  font-size: .28rem;
+  color: #5F5E64;
+}
+.set-area-city .van-icon{
+  transform: rotate(90deg);
+  color: #C0C4CC;
+}
+.set-sort-type{
+
+}
+.set-unit{
+  font-size: .18rem;
+  color: #9B9CA3;
+}
 .van-sticky--fixed {
   display: flex;
   align-items: center;
@@ -380,6 +455,7 @@
   margin: 0!important;
   padding-left: .08rem!important;
   padding-right: .08rem!important;
+  overflow-x: scroll;
 }
 .market-overview-item {
   display: flex;
@@ -582,3 +658,30 @@
   transform: translateX(-50%);
   background-color: #2ABDD1;
 }
+.add-pro-list-inlet {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+.add-pro-list-inlet .pro_list_inlet{
+  display: flex;
+  align-items: center;
+  font-size: .28rem;
+  color: #2ABDD1;
+  font-weight: 400;
+}
+.pro_list_inlet>img{
+  width: .32rem;
+  height: .32rem;
+  margin-right: .08rem;
+}
+
+.more{
+  padding: .2rem 0 .36rem;
+  text-align: center;
+  color: #2ABED1;
+  font-size: .28rem;
+  line-height: .4rem;
+}
+
+

BIN
src/web/staticres/common-module/report-analysis/image/05.png


BIN
src/web/staticres/common-module/report-analysis/image/06.png


BIN
src/web/staticres/common-module/report-analysis/image/07.png


BIN
src/web/staticres/common-module/report-analysis/image/08.png


BIN
src/web/staticres/common-module/report-analysis/image/icon/icon-infor-blue.png


+ 181 - 5
src/web/staticres/common-module/report-analysis/js/report_analysis.js

@@ -7,10 +7,12 @@ var vm = new Vue({
   components: {
     keywordComponent: keywordComponent,
     areaCityMobile: areaCityMobileComponent,
+    areaComponent: areaComponent,
     industryComponent: industryComponent,
     cateComponent: cateComponent,
     dateComponent: dateComponent,
     chartExample: chartExample,
+    projectHeader: projectHeaderComponent,
     // 图表
     projectScatter: projectScatter,
     marketTimeScatter: marketTimeScatter,
@@ -25,7 +27,7 @@ var vm = new Vue({
     tabActiveName: 'analysis', // analysis/history
     tabList: [
       {
-        label: '定制化市场分析',
+        label: '市场分析报告',
         name: 'analysis'
       },
       {
@@ -201,6 +203,13 @@ var vm = new Vue({
       areaScatter: {
         dataAlready: false,
         chartData: null,
+        // 地区信息接口返回的原始数据
+        originAreaData: [],
+        showAreaPopup: false,
+        setCityList: [],
+        selectArea: {},
+        sortType: 0,
+        showAreaCityListBtn: false,
         // 项目数量Top3
         projectCountTop3: null,
         // 项目金额Top3
@@ -218,16 +227,20 @@ var vm = new Vue({
         chartData: null,
         // 项目数量Top3
         projectCountTop3: null,
+        showCountAllBtn: false,
         // 项目金额Top3
-        projectAmountTop3: null
+        projectAmountTop3: null,
+        showAmoutAllBtn: false
       },
       winner: {
         dataAlready: false,
         chartData: null,
         // 项目数量Top3
         projectCountTop3: null,
+        showCountAllBtn: false,
         // 项目金额Top3
-        projectAmountTop3: null
+        projectAmountTop3: null,
+        showAmoutAllBtn: false
       }
     },
     empty: {
@@ -238,9 +251,29 @@ var vm = new Vue({
     notSetKey: false, // 未设置关键词
     isSubCount: false, // 是否子账号
     powerInfo: {},
-    isWeixin: false
+    isWeixin: false,
+    sortOptionTitle: '项目数量由大到小排序',
+    sortOptionContent: [
+      { text: '项目数量由大到小排序', value: 0, active: true },
+      { text: '项目金额由大到小排序', value: 1, active: false }
+    ]
   },
   computed: {
+    showBuyerBtn: function () {
+      return this.sections.buyerclass.showCountAllBtn ? this.sections.buyerclass.projectCountTop3.slice(0, 3) : this.sections.buyerclass.projectCountTop3
+    },
+    showAmoutBtn: function () {
+      return this.sections.buyerclass.showAmoutAllBtn ? this.sections.buyerclass.projectAmountTop3.slice(0, 3) : this.sections.buyerclass.projectAmountTop3
+    },
+    showWinnerCountBtn: function () {
+      return this.sections.winner.showCountAllBtn ? this.sections.winner.projectCountTop3.slice(0, 3) : this.sections.winner.projectCountTop3
+    },
+    showWinnerAmoutBtn: function () {
+      return this.sections.winner.showAmoutAllBtn ? this.sections.winner.projectAmountTop3.slice(0, 3) : this.sections.winner.projectAmountTop3
+    },
+    showAreaCityBtn: function () {
+      return this.sections.areaScatter.showAreaCityListBtn ? this.sections.areaScatter.setCityList.slice(0, 5) : this.sections.areaScatter.setCityList
+    },
     getStatus: function () {
       if (JSON.stringify(this.powerInfo) !== '{}') {
         return this.powerInfo.power.indexOf(10) !== -1
@@ -260,6 +293,15 @@ var vm = new Vue({
       var showArea = area && (Object.keys(area).length > 1 || Object.keys(area).length === 0)
       return showArea
     },
+    notOneAreaCityFilter () {
+      var area = this.reportFilters.area
+      if (!this.notOneAreaFilter) {
+        var showCity = area && (area[Object.keys(area)].length >=2 || area[Object.keys(area)].length === 0)
+        return showCity
+      } else {
+        return this.notOneAreaFilter
+      }
+    },
     emptyShow () {
       return !this.rid && this.analysis.loaded
     },
@@ -331,13 +373,81 @@ var vm = new Vue({
     utils.iosBackRefresh()
   },
   methods: {
+    // 设置排序方式
+    setsortType (data) {
+      this.sections.areaScatter.sortType = data
+      const type = data===0 ? 'total' : 'amount'
+      // const list = this.setCitySort(this.sections.areaScatter.setCityList, type)
+      let newArr = []
+      if(data === 0) {
+        newArr = this.sections.areaScatter.setCityList.sort((a, b) => b.total - a.total)
+      } else {
+        newArr = this.sections.areaScatter.setCityList.sort((a, b) => b.amount - a.amount)
+      }
+      this.sections.areaScatter.setCityList = this.formatterWinData(newArr, type)
+      this.sortOptionTitle = this.sortOptionContent[data].text
+      this.sections.areaScatter.setCityList = newArr
+    },
+    cancelSelectArea () {
+      this.sections.areaScatter.showAreaPopup = false
+    },
+    // 城市排序
+    setCitySort (list, type) {
+      return list.sort((a, b) => {
+        a[type] - b[type]
+      })
+    },
+    // 选择省份展示城市分布(单选)
+    confirmSelectArea (data) {
+      console.log(data)
+      if(this.sections.areaScatter.originAreaData.length > 0) {
+        this.sections.areaScatter.originAreaData.forEach(item => {
+          if(item.area == data.data[0]) {
+            this.sections.areaScatter.selectArea = item
+            const areaSort = this.sections.areaScatter.sortType === 0 ? 'total' : 'amount'
+            let newArr = []
+            if(this.sections.areaScatter.sortType === 0) {
+              newArr = item.areaDetails.sort((a, b) => b.total - a.total)
+            } else {
+              newArr = item.areaDetails.sort((a, b) => b.amount - a.amount)
+            }
+            this.sections.areaScatter.setCityList = this.formatterWinData(newArr, areaSort)
+            this.sections.areaScatter.setCityList = this.sections.areaScatter.setCityList.sort((a, b) => b[areaSort] - a[areaSort])
+            if(this.sections.areaScatter.setCityList.length > 5) {
+              this.sections.areaScatter.showAreaCityListBtn = true
+            } else {
+              this.sections.areaScatter.showAreaCityListBtn = false
+            }
+          }
+        })
+      }
+      this.sections.areaScatter.showAreaPopup = false
+    },
+    showCountAmount (data) {
+      return (data.amount / 10000).toFixed(2)
+    },
+    inProList () {
+      this.saveState()
+      if(utils.$envs.inWX){
+        if(!this.getStatus) {
+          location.href = '/weixin/frontPage/bigmember/free/perfect_info?source=wx_analysis_ProjectDetails'
+        } else {
+          window.location.href='/big/wx/page/report_analysis_pro_list?id=' + this.rid
+        }
+       } else {
+        if(!this.getStatus) {
+          location.href = '/jyapp/frontPage/bigmember/free/perfect_info?source=app_analysis_ProjectDetails'
+        } else {
+          window.location.href='/jyapp/big/page/report_analysis_pro_list?id=' + this.rid
+        }
+       }
+    },
     gotable () {
       this.saveState()
        if(utils.$envs.inWX){
         window.location.href='/big/wx/page/report_table?source=analysis'+'&flag=3'+'&rid='+this.rid+'&header=客户类型分布详情'
        } else {
         window.location.href='/jyapp/big/page/report_table?source=analysis'+'&flag=3'+'&rid='+this.rid+'&header=客户类型分布详情'
-
        }
 
     },
@@ -872,7 +982,10 @@ var vm = new Vue({
         // 项目规模分布
         this.sortProjectScatter(data.projectScale)
         // 地区规模分布
+        this.sections.areaScatter.originAreaData = data.area_infos
         this.sortAreaScatter(data.area_infos)
+        // 城市分布
+        this.sortAreaCityScatter(data.area_infos)
         // 客户分布
         if(data.customer_scale){
           if(data.customer_scale.length!=0){
@@ -1280,6 +1393,46 @@ var vm = new Vue({
         this.sections.areaScatter.dataAlready = true
       }
     },
+    setAreaCity () {
+      this.sections.areaScatter.showAreaPopup = true
+      const selectAreaArr = [this.sections.areaScatter.selectArea.area]
+      this.$refs.areaSelector.setState(selectAreaArr)
+    },
+    // 城市分布
+    sortAreaCityScatter (areacitylist) {
+      const list = areacitylist
+      const ZXS = ['北京', '天津', '上海', '重庆', '台湾', '澳门', '香港']
+      const result  = list.reduce((max, item) => {
+        const isMaxZXS = ZXS.includes(max.area)
+        const isZXS = ZXS.includes(item.area);
+        const isMaxTotal = item.total > max.total;
+        const isNotZXSMaxTotal = (isMaxTotal && !isZXS) || isMaxZXS;
+        return isNotZXSMaxTotal ? item : max
+      })
+      if (result.areaDetails.length > 5) {
+        this.sections.areaScatter.showAreaCityListBtn = true
+      } else {
+        this.sections.areaScatter.showAreaCityListBtn = false
+      }
+      this.sections.areaScatter.setCityList = this.formatterWinData(result.areaDetails, 'total')
+      this.sections.areaScatter.selectArea = result
+    },
+    // 格式化进度条图表数据
+    formatterWinData: function(data,type) {
+      data.forEach(function(v,i){
+          // v.bidamount = (v.bidamount / 10000).fixed(2);
+          // v.average = (v.average / 10000).fixed(2);
+          switch (type) {
+            case 'total':
+              v.parent = v.total / data[0].total*100 + "%";
+              break;
+            case 'amount':
+              v.parent = v.amount / data[0].amount*100 + "%";
+              break;
+          }
+      })
+      return data;
+  },
     // 客户分布
     sortUserScatter (userList) {
       if (Array.isArray(userList)) {
@@ -1295,6 +1448,9 @@ var vm = new Vue({
     sortAreaUserTop3 (data) {
       if (data.scaleAreaCountTop || data.scaleAreaAmountTop) {
         this.sorAreaTop3(data)
+      } else {
+        this.sections.areaScatter.projectCountTop3 = null
+        this.sections.areaScatter.projectAmountTop3 = null
       }
       if (data.scaleBuyclassCountTop || data.scaleBuyclassAmountTop) {
         this.sorUserTop3(data)
@@ -1649,9 +1805,19 @@ var vm = new Vue({
         dataAmount.rows = amountTop3
       }
       if (dataCount.rows.length) {
+        if (dataCount.rows.length > 3) {
+          this.sections.buyerclass.showCountAllBtn = true
+        } else {
+          this.sections.buyerclass.showCountAllBtn = false
+        }
         this.$set(this.sections.buyerclass, 'projectCountTop3', dataCount.rows)
       }
       if (dataAmount.rows.length) {
+        if (dataAmount.rows.length > 3) {
+          this.sections.buyerclass.showAmoutAllBtn = true
+        } else {
+          this.sections.buyerclass.showAmoutAllBtn = false
+        }
         this.$set(this.sections.buyerclass, 'projectAmountTop3', dataAmount.rows)
       }
     },
@@ -1758,9 +1924,19 @@ var vm = new Vue({
       }
 
       if (dataCount.rows.length) {
+        if (dataCount.rows.length > 3) {
+          this.sections.winner.showCountAllBtn = true
+        } else {
+          this.sections.winner.showCountAllBtn = false
+        }
         this.$set(this.sections.winner, 'projectCountTop3', dataCount.rows)
       }
       if (dataAmount.rows.length) {
+        if (dataAmount.rows.length > 3) {
+          this.sections.winner.showAmoutAllBtn = true
+        } else {
+          this.sections.winner.showAmoutAllBtn = false
+        }
         this.$set(this.sections.winner, 'projectAmountTop3', dataAmount.rows)
       }
     },

+ 1 - 1
src/web/staticres/common-module/report-analysis/js/report_analysis_history.js

@@ -9,7 +9,7 @@ var vm = new Vue({
     tabActiveName: 'history', // analysis/history
     tabList: [
       {
-        label: '定制化市场分析',
+        label: '市场分析报告',
         name: 'analysis'
       },
       {

+ 339 - 0
src/web/staticres/common-module/report-analysis/js/report_analysis_pro_list.js

@@ -0,0 +1,339 @@
+var vm = new Vue({
+  delimiters: ['${', '}'],
+  el: '#analysisList',
+  components: {
+    filterComponent: filterComponent,
+    projectHeader: projectHeaderComponent,
+    projectCell: projectCellComponent,
+    empty: emptyComponent
+  },
+  data: {
+    sessStorageKey: '$data-report_analysis_pro_list',
+    vanlistParams: {
+      loading: false,
+      finished: false,
+      scrollTop: 0
+    },
+    filters: {
+      selectKeysArr: [], // 关键词简单数组,用于恢复选择状态
+      keys: [], // 关键词详细数组,用于提交数据
+      area: {},
+      industry: {},
+      industryDetail: {},
+      buyerclass: [],
+      rangeTime: {
+        start: '',
+        end: '',
+      },
+      rangeTimeExtra: 'sinceYearBeforeLast',
+    },
+    initFilters: {
+      keys: [],
+      area: {},
+      industry: [],
+      industryDetail: {},
+      buyerclass: []
+    },
+    listParams: {
+      sort: 0, // 项目明细排序方式
+      pageSize: 10,
+      pageNum: 1
+    },
+    sortOptiontitle: '成交时间由晚到早',
+    sortOption: [
+      { text: '成交时间由晚到早', value: 0, active: true },
+      { text: '项目金额由大到小', value: 1, active: false }
+    ],
+    filterData: {},
+    projectInfo: {},
+    confirmSwitch: false,
+    anyncData: false // 获取筛选条件结束后置为true,传到filter-limit组件设置筛选条件初始值
+  },
+  computed: {
+  },
+  created: function () {
+    const recover = this.reStoreState()
+    if (!recover) {
+      this.getFilterData()
+    }
+  },
+  mounted: function () {
+    utils.iosBackRefresh()
+  },
+  methods: {
+    // 保存页面状态
+    saveState: function () {
+      this.saveScrollTop()
+      var $data = {
+        filters: this.filters,
+        listParams: this.listParams,
+        filterData: this.filterData,
+        projectInfo: this.projectInfo,
+        vanlistParams: this.vanlistParams,
+        initFilters: this.initFilters
+      }
+      sessionStorage.setItem(this.sessStorageKey, JSON.stringify($data))
+    },
+    // 恢复页面数据
+    reStoreState: function () {
+      var $data = sessionStorage.getItem(this.sessStorageKey)
+      if ($data) {
+        $data = JSON.parse($data)
+        Object.assign(this.filters, $data.filters)
+        Object.assign(this.listParams, $data.listParams)
+        Object.assign(this.filterData, $data.filterData)
+        Object.assign(this.projectInfo, $data.projectInfo)
+        Object.assign(this.vanlistParams, $data.vanlistParams)
+        Object.assign(this.initFilters, $data.initFilters)
+        this.sortOptiontitle = this.sortOption[this.filterData.sort].text
+        setTimeout(function () {
+          // 恢复滚动高度
+          this.setScrollTop(this.vanlistParams.scrollTop)
+        }.bind(this), 0)
+
+        sessionStorage.removeItem(this.sessStorageKey)
+      }
+
+      return $data
+    },
+    setScrollTop: function (scrollTop) {
+      this.$nextTick(function () {
+        var wrapper = document.getElementById('analysisList')
+        wrapper.scrollTop = scrollTop
+      })
+    },
+    saveScrollTop: function () {
+      var wrapper = document.getElementById('analysisList')
+      if (wrapper.scrollTop) {
+        this.vanlistParams.scrollTop = parseInt(wrapper.scrollTop)
+      }
+    },
+    // 获取筛选条件并回显
+    getFilterData () {
+      $.ajax({
+        type:'POST',
+        url: '/bigmember/marketAnalysis/getAnalysisResult',
+        data: {
+          rid: utils.getParam('id'),
+          flag: 0
+        },
+        success: function(res) {
+          if (res.error_code === 0) {
+            this.sortReportFilters(res.data)
+            this.confirmSwitch = true
+            this.anyncData = true
+          } else {
+            this.$toast(res.error_msg)
+          }
+        }.bind(this)
+      })
+    },
+    // 整理数据,并赋值给filters
+    sortReportFilters (data) {
+      if (data.keysItems && data.keysItems !== '[]') {
+        // this.filters.keys = JSON.parse(data.keysItems)
+        this.initFilters.keys = JSON.parse(data.keysItems)
+        // var keyArr = []
+        // this.filters.keys.forEach(function (classify) {
+        //   if(Array.isArray(classify.a_key)) {
+        //     classify.a_key.forEach(function (item) {
+        //       keyArr.push(item.key.join(' '))
+        //     })
+        //   }
+        // })
+        // this.initFilters.keys = keyArr
+      }
+      if(data.s_rangeTimeExtra) {
+        this.filters.rangeTimeExtra = data.s_rangeTimeExtra
+      }
+      if (data.rangeTime) {
+        var arr = data.rangeTime.split('-')
+        this.filters.rangeTime.start = arr[0] * 1000
+        this.filters.rangeTime.end = arr[1] * 1000
+        if (data.s_rangeTimeExtra === 'exact') {
+          var date = new Date(this.filters.rangeTime.end)
+          var timeString = date.pattern('yyyy/MM/dd')
+          this.filters.rangeTime.end = new Date(timeString).getTime()
+        }
+      }
+      if (data.area && data.area !== '{}') {
+        this.initFilters.area = JSON.parse(data.area)
+      } else {
+        this.initFilters.area = {}
+      }
+      if (data.industry && data.industry !== '{}') {
+        this.$set(this.filters, 'industryDetail', JSON.parse(data.industry))
+        var industry = []
+        for (var key in this.filters.industryDetail) {
+          this.filters.industryDetail[key].forEach(function (item) {
+            industry.push(key + '_' + item)
+          })
+        }
+        this.filters.industry = industry
+      }
+      if (data.buyerclass) {
+        this.initFilters.buyerclass = data.buyerclass.split(',')
+      }
+    },
+    // 点击项目
+    setLinkUrl () {
+      this.saveState()
+      if (utils.$envs.inWX) {
+        location.href = '/big/wx/page/pro_follow_detail'
+      } else {
+        location.href = '/jyapp/big/page/pro_follow_detail'
+      }
+    },
+    setBuyerLink (data) {
+      this.saveState()
+      if (utils.$envs.inWX) {
+        location.href = '/big/wx/page/unit_portrayal?entName=' + data.buyer
+      } else {
+        location.href = '/jyapp/big/page/unit_portrayal?entName=' + data.buyer
+      }
+    },
+    setWinnerLink (id) {
+      this.saveState()
+      if (utils.$envs.inWX) {
+        location.href = '/weixin/frontPage/collection/sess/ent_portrait?eId=' + id
+      } else {
+        location.href = '/jyapp/big/page/ent_portrait?eId=' + id
+      }
+    },
+    // 设置排序方式
+    setsortType (data) {
+      this.filterData.pageNum = 0
+      this.filterData.sort = data
+      this.onListLoad()
+    },
+    onListLoad: function () {
+      this.filterData.pageNum++
+      this.getProjectInfo(this.filterData)
+    },
+    // 查询项目明细
+    confirm (data) {
+      const { items, area, industry, industryDetail, buyerclass, buyer, winner, selectKeysArr } = data
+      this.filters.keys = items
+      this.filters.selectKeysArr = selectKeysArr
+      this.filters.area = area
+      this.filters.industryDetail = industryDetail
+      this.filters.industry = industry
+      this.filters.buyerclass = buyerclass
+      this.filters.buyer = buyer
+      this.filters.winner = winner
+      let strBuyerClass = ''
+      if(buyerclass.length > 0) {
+        strBuyerClass = buyerclass.join(',')
+      }
+      data.industry = industryDetail
+      delete data.industryDetail
+      delete data.selectKeysArr
+      const params = {
+        ...this.listParams,
+        rid: utils.getParam('id'),
+        keysItems: JSON.stringify(items),
+        area: JSON.stringify(area),
+        industry: JSON.stringify(data.industry),
+        buyerclass: strBuyerClass,
+        buyer: buyer,
+        winner: winner,
+        rangeTime: parseInt(this.filters.rangeTime.start / 1000)+'-'+parseInt(this.filters.rangeTime.end / 1000),
+        rangeTimeExtra: this.filters.rangeTimeExtra
+      }
+      if(this.confirmSwitch) {
+        params.keysItems = JSON.stringify(this.initFilters.keys)
+        this.confirmSwitch = !this.confirmSwitch
+      }
+      if (params.keysItems === '[]') {
+        params.keysItems = ''
+      }
+      this.filterData = params
+      this.getProjectInfo(params)
+    },
+    getProjectInfo: function (params) {
+      var loading = null
+      if(params.pageNum === 1) {
+        loading = this.showLoading()
+      } else {
+        loading = null
+      }
+      this.vanlistParams.loading = true
+      $.ajax({
+        type: 'POST',
+        url: '/bigmember/marketAnalysis/projectInfo',
+        data: params,
+        // contentType: 'application/json',
+        success: function(res) {
+          if(loading) {
+            loading.clear()
+          }
+          if (res && res.error_code === 0 && res.data) {
+            if (!res.data.list) {
+              this.projectInfo.list = []
+              this.$forceUpdate()
+              if(loading) {
+                loading.clear()
+              }
+              return
+            }
+            if (params.pageNum === 1) {
+              this.projectInfo = res.data
+            } else {
+              this.projectInfo.list = this.projectInfo.list.concat(res.data.list)
+            }
+            this.vanlistParams.loading = false
+            const count = res.data.total > 5000 ? 5000 : res.data.total
+            const pageTotalNum = count / this.listParams.pageSize
+            const pageResidue = count % this.listParams.pageSize
+            if (pageResidue > 0) {
+              if (params.pageNum > pageTotalNum) {
+                this.vanlistParams.finished = true
+              } else {
+                this.vanlistParams.finished = false
+              }
+            } else {
+              if (params.pageNum >= pageTotalNum) {
+                this.vanlistParams.finished = true
+              } else {
+                this.vanlistParams.finished = false
+              }
+            }
+          } else {
+            this.projectInfo.list = []
+            this.vanlistParams.loading = false
+            this.$toast(res.error_msg)
+          }
+        }.bind(this)
+      })
+    },
+    showLoading: function () {
+      return this.$toast.loading({
+        duration: 0,
+        forbidClick: true,
+        message: 'loading...',
+      })
+    },
+    showToast: function (message) {
+      return this.$toast({
+        duration: 1500,
+        forbidClick: true,
+        message: message,
+      })
+    },
+    showDialog: function (conf) {
+      var defaultConf = {
+        title: '提示',
+        message: 'message',
+        className: 'j-confirm-dialog',
+        showConfirmButton: true,
+        showCancelButton: true,
+        confirmButtonText: '确定',
+        confirmButtonColor: '#2abed1'
+      }
+      if (conf) {
+        Object.assign(defaultConf, conf)
+      }
+      return this.$dialog.confirm(defaultConf)
+    }
+  }
+})

+ 1 - 1
src/web/templates/big-member/pc/page_index.html

@@ -565,7 +565,7 @@
                     <div class="icon-sprites" data-index="9"></div>
                     <h5>市场分析</h5>
                     <p>
-                        提供周报/月报/定制化报告分析,辅助做市场洞察。
+                        提供周报/月报/市场分析报告,辅助做市场洞察。
                     </p>
                     <div class="subpage-button sm gold">了解更多</div>
                 </div>

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
src/web/templates/big-member/wx/page_index.html


+ 1 - 1
src/web/templates/big-member/wx/page_landingPage.html

@@ -134,7 +134,7 @@
                     <img src='{{Msg "seo" "cdn"}}/big-member/image/landpage_new/itemB_03.jpg'>
                 </div>
                 <div>
-                    <img src='{{Msg "seo" "cdn"}}/big-member/image/landpage_new/itemB_04.jpg'>
+                    <img src='{{Msg "seo" "cdn"}}/big-member/image/landpage_new/itemB_04.png'>
                 </div>
                 <div class="btn_buy" id="btn_buy" @click="exper_fun('sj', 1)"  style="background-color:#1A1A2A;margin-top: -0.01rem; ">
                     <img data-need-bind-phone src='{{Msg "seo" "cdn"}}/big-member/image/landpage_new/itemB_05.jpg' alt="" class="btn_buy_img" id="btn_buy_img" >

+ 104 - 21
src/web/templates/big-member/wx/page_report_analysis.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="zh-CN" style="font-size: 50px;">
 <head>
-    <title>定制化市场分析报告 </title>
+    <title>市场分析报告 </title>
     <meta charset="UTF-8">
     <meta name="viewport"
         content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
@@ -20,6 +20,7 @@
     <link rel="stylesheet" href='{{Msg "seo" "cdn"}}/big-member/weixin/css/public.css?v={{Msg "seo" "version"}}'>
     <link rel="stylesheet" href='{{Msg "seo" "cdn"}}/big-member/weixin/css/j-icons.css?v={{Msg "seo" "version"}}'>
     <link rel="stylesheet" href='{{Msg "seo" "cdn"}}/common-module/collection/css/index.css?v={{Msg "seo" "version"}}'/>
+    <link rel="stylesheet" href='{{Msg "seo" "cdn"}}/common-module/filter/css/project_header.css?v={{Msg "seo" "version"}}' />
     <link rel="stylesheet" href='{{Msg "seo" "cdn"}}/common-module/report-analysis/css/report_analysis.css?v={{Msg "seo" "version"}}' />
     <style>
       /* fix: --- 弹窗组件不能显示底部问题  */
@@ -134,7 +135,7 @@
                       <div class="height8" v-show="false"></div>
                       <section class="section bg-white dimension">
                           <div class="section-title"> - 分析维度 -</div>
-                          <van-sticky class="section-sticky" z-index="99999999" :offset-top="stickyOffset">
+                          <van-sticky class="section-sticky" z-index="2000" :offset-top="stickyOffset">
                               <div class="section-content dimension-list bg-white">
                                   <div
                                       class="j-button j-button-item dimension-item"
@@ -153,7 +154,13 @@
                       </section>
                       <!-- 市场概况 -->
                       <section class="section bg-white market-overview" id="market" v-if="getStatus">
-                          <div class="section-title pd-16">市场概况</div>
+                          <div class="section-title add-pro-list-inlet pd-16">
+                            <span>市场概况</span>
+                            <div class="pro_list_inlet" @click="inProList">
+                              <img src="/common-module/report-analysis/image/icon/icon-infor-blue.png?v={{Msg "seo" "version"}}" alt="">
+                              <span>项目明细</span>
+                            </div>
+                          </div>
                           <div class="section-content market-overview-list">
                               <div
                                   class="market-overview-item"
@@ -182,9 +189,15 @@
                       <div class="vip_component"
                         v-if="!getStatus"
                         style="height:8.84rem">
-                        <p class="example-title">市场概况</p>
+                        <div class="example-title add-pro-list-inlet">
+                          <span>市场概况</span>
+                          <div class="pro_list_inlet" @click="inProList">
+                            <img src="/common-module/report-analysis/image/icon/icon-infor-blue.png?v={{Msg "seo" "version"}}" alt="">
+                            <span>项目明细</span>
+                          </div>
+                        </div>
                         <div class="chart_com" style="background:url('/common-module/report-analysis/image/01-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
-                          <chart-example type="item_1" imgurl='{{Msg "seo" "cdn"}}/common-module/report-analysis/image/01.png?v={{Msg "seo" "version"}}'>
+                          <chart-example ref="chartExampleRef" type="item_1" imgurl='{{Msg "seo" "cdn"}}/common-module/report-analysis/image/01.png?v={{Msg "seo" "version"}}'>
                           </chart-example>
                         </div>
                       </div>
@@ -279,6 +292,62 @@
                               <market-area-scatter :chart-data="sections.areaScatter.chartData"></market-area-scatter>
                           </div>
                       </div>
+                      <!-- 城市分布 -->
+                      <div class="section bg-white pd-16 city-scatter" v-if="sections.areaScatter.dataAlready && notOneAreaCityFilter && getStatus">
+                        <div class="section-title">城市分布</div>
+                        <div class="section-content">
+                          <!-- <market-area-scatter :chart-data="sections.areaScatter.chartData"></market-area-scatter> -->
+                          <div class="section-content-header">
+                            <div class="set-area-city" @click="setAreaCity">
+                              <span>${sections.areaScatter.selectArea.area}</span>
+                              <van-icon name="play"></van-icon>
+                            </div>
+                            <div class="set-sort-type">
+                              <project-header :sort-option="sortOptionContent" :sort-optiontitle="sortOptionTitle" :showtotal="false" @setsort="setsortType"></project-header>
+                            </div>
+                            <div class="set-unit">单位:${sections.areaScatter.sortType===0?'个':'万元'}</div>
+                          </div>
+                          <div class="progress-bar-container">
+                            <div class="progress-bar-item" v-for="(item,index) in showAreaCityBtn" :key="index">
+                                <div class="item-label">
+                                    <span class="item-name">${item.city}</span>
+                                    <span class="item-count" v-if="sections.areaScatter.sortType===0">${item.total}个</span>
+                                    <span class="item-count" v-else>${showCountAmount(item)}万元</span>
+                                </div>
+                                <div class="item-progress">
+                                    <span class="item-progress-count blue-progress" :style="{width: item.parent}"></span>
+                                </div>
+                            </div>
+                          </div>
+                          <div class="more" @click="sections.areaScatter.showAreaCityListBtn = false" v-if="sections.areaScatter.showAreaCityListBtn">
+                            <span>查看更多</span>
+                          </div>
+                        </div>
+                      </div>
+                      <van-popup
+                        v-model="sections.areaScatter.showAreaPopup"
+                        closeable
+                        round
+                        position="bottom"
+                        close-icon="clear"
+                        class="j-popup collection"
+                        :lazy-render="false"
+                        overlay-class="j-overlay"
+                        :style="{ height: '60%' }"
+                        get-container="body">
+                        <div class="j-container report-popup">
+                            <div class="popup-header header-title">请选择省份</div>
+                            <div class="j-main area-content">
+                                <area-component
+                                    :newprovincelist="reportFilters.area"
+                                    :showcountry="false"
+                                    :multiple="false"
+                                    ref="areaSelector"
+                                    @cancel="cancelSelectArea"
+                                    @confirm="confirmSelectArea"></area-component>
+                            </div>
+                        </div>
+                      </van-popup>
                       <div class="section bg-white pd-16" v-if="sections.areaScatter.projectCountTop3 && getStatus">
                           <div class="section-title">项目数量TOP3地区的重点中标单位</div>
                           <div class="section-content">
@@ -373,31 +442,37 @@
                               <line-chart-scatter :chart-data="sections.buyerclass.chartData"></line-chart-scatter>
                           </div>
                       </div>
-                      <div class="section bg-white pd-16" v-if="sections.buyerclass.projectCountTop3 && getStatus">
-                          <div class="section-title">项目数量TOP3采购单位及其重点合作中标单位</div>
+                      <div class="section bg-white pd-16" v-if="showBuyerBtn && getStatus">
+                          <div class="section-title">项目数量TOP30采购单位及其重点合作中标单位</div>
                           <div class="section-content">
-                              <market-top3-table :table-data="sections.buyerclass.projectCountTop3" type="count" @save="saveState"></market-top3-table>
+                              <market-top3-table :table-data="showBuyerBtn" type="count" @save="saveState"></market-top3-table>
+                              <div class="more" @click="sections.buyerclass.showCountAllBtn = false" v-if="sections.buyerclass.showCountAllBtn">
+                                <span>查看更多</span>
+                              </div>
                           </div>
                       </div>
                       <div class="vip_component"
                         v-if="!getStatus"
                         style="height:10.8rem">
-                        <p class="example-title">项目数量TOP3采购单位及其重点合作中标单位</p>
+                        <p class="example-title">项目数量TOP30采购单位及其重点合作中标单位</p>
                         <div class="chart_com" style="background:url('/common-module/report-analysis/image/05-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
                           <chart-example type="item_5" imgurl='{{Msg "seo" "cdn"}}/common-module/report-analysis/image/05.png?v={{Msg "seo" "version"}}'>
                           </chart-example>
                         </div>
                       </div>
-                      <div class="section bg-white pd-16" v-if="sections.buyerclass.projectAmountTop3 && getStatus">
-                          <div class="section-title">采购金额TOP3采购单位及其重点合作中标单位</div>
+                      <div class="section bg-white pd-16" v-if="showAmoutBtn && getStatus">
+                          <div class="section-title">采购金额TOP30采购单位及其重点合作中标单位</div>
                           <div class="section-content">
-                              <market-top3-table :table-data="sections.buyerclass.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
+                              <market-top3-table :table-data="showAmoutBtn" type="amount" @save="saveState"></market-top3-table>
+                              <div class="more" @click="sections.buyerclass.showAmoutAllBtn = false" v-if="sections.buyerclass.showAmoutAllBtn">
+                                <span>查看更多</span>
+                              </div>
                           </div>
                       </div>
                       <div class="vip_component"
                         v-if="!getStatus"
                         style="height:10.8rem">
-                        <p class="example-title">采购金额TOP3采购单位及其重点合作中标单位</p>
+                        <p class="example-title">采购金额TOP30采购单位及其重点合作中标单位</p>
                         <div class="chart_com" style="background:url('/common-module/report-analysis/image/06-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
                           <chart-example type="item_6" imgurl='{{Msg "seo" "cdn"}}/common-module/report-analysis/image/06.png?v={{Msg "seo" "version"}}'>
                           </chart-example>
@@ -410,31 +485,37 @@
                               <line-chart-scatter :chart-data="sections.winner.chartData"></line-chart-scatter>
                           </div>
                       </div>
-                      <div class="section bg-white pd-16" v-if="sections.winner.projectCountTop3 && getStatus">
-                          <div class="section-title">项目数量TOP3中标单位及其重点合作采购单位</div>
+                      <div class="section bg-white pd-16" v-if="showWinnerCountBtn && getStatus">
+                          <div class="section-title">项目数量TOP30中标单位及其重点合作采购单位</div>
                           <div class="section-content">
-                              <market-top3-table :table-data="sections.winner.projectCountTop3" type="count" @save="saveState"></market-top3-table>
+                              <market-top3-table :table-data="showWinnerCountBtn" type="count" @save="saveState"></market-top3-table>
+                              <div class="more" @click="sections.winner.showCountAllBtn = false" v-if="sections.winner.showCountAllBtn">
+                                <span>查看更多</span>
+                              </div>
                           </div>
                       </div>
                       <div class="vip_component"
                         v-if="!getStatus"
                         style="height:10.8rem">
-                        <p class="example-title">项目数量TOP3中标单位及其重点合作采购单位</p>
+                        <p class="example-title">项目数量TOP30中标单位及其重点合作采购单位</p>
                         <div class="chart_com" style="background:url('/common-module/report-analysis/image/07-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
                           <chart-example type="item_7" imgurl='{{Msg "seo" "cdn"}}/common-module/report-analysis/image/07.png?v={{Msg "seo" "version"}}'>
                           </chart-example>
                         </div>
                       </div>
-                      <div class="section bg-white pd-16" v-if="sections.winner.projectAmountTop3 && getStatus">
-                          <div class="section-title">中标金额TOP3中标单位及其重点合作采购单位</div>
+                      <div class="section bg-white pd-16" v-if="showWinnerAmoutBtn && getStatus">
+                          <div class="section-title">中标金额TOP30中标单位及其重点合作采购单位</div>
                           <div class="section-content">
-                              <market-top3-table :table-data="sections.winner.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
+                              <market-top3-table :table-data="showWinnerAmoutBtn" type="amount" @save="saveState"></market-top3-table>
+                              <div class="more" @click="sections.winner.showAmoutAllBtn = false" v-if="sections.winner.showAmoutAllBtn">
+                                <span>查看更多</span>
+                              </div>
                           </div>
                       </div>
                       <div class="vip_component"
                         v-if="!getStatus"
                         style="height:10.8rem">
-                        <p class="example-title">中标金额TOP3中标单位及其重点合作采购单位</p>
+                        <p class="example-title">中标金额TOP30中标单位及其重点合作采购单位</p>
                         <div class="chart_com" style="background:url('/common-module/report-analysis/image/08-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
                           <chart-example type="item_8" imgurl='{{Msg "seo" "cdn"}}/common-module/report-analysis/image/08.png?v={{Msg "seo" "version"}}'>
                           </chart-example>
@@ -558,6 +639,7 @@
 <script src='{{Msg "seo" "cdn"}}/common-module/collection/js/keyword-mobile.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Msg "seo" "cdn"}}/common-module/collection/js/date-mobile.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Msg "seo" "cdn"}}/common-module/collection/js/area-city-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/collection/js/area-mobile.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Msg "seo" "cdn"}}/common-module/collection/js/industry-mobile.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Msg "seo" "cdn"}}/common-module/collection/js/cate-mobile.js?v={{Msg "seo" "version"}}'></script>
 
@@ -571,6 +653,7 @@
 <script src='{{Msg "seo" "cdn"}}/common-module/report-analysis/js/components/marketUserScatter.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Msg "seo" "cdn"}}/common-module/report-analysis/js/components/marketSegment.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Msg "seo" "cdn"}}/common-module/report-analysis/js/components/lineChartScatter.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/filter/js/project_header.js?v={{Msg "seo" "version"}}'></script>
 <script src='{{Msg "seo" "cdn"}}/common-module/report-analysis/js/report_analysis.js?v={{Msg "seo" "version"}}'></script>
 {{include "/common/baiducc.html"}}
 </body>

+ 1 - 1
src/web/templates/big-member/wx/page_report_analysis_history.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="zh-CN" style="font-size: 50px;">
 <head>
-    <title>定制化市场分析报告 </title>
+    <title>市场分析报告 </title>
     <meta charset="UTF-8">
     <meta name="viewport"
         content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />

+ 71 - 0
src/web/templates/big-member/wx/page_report_analysis_pro_list.html

@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html lang="zh-CN" style="font-size: 50px;">
+<head>
+    <title>市场分析报告项目明细 </title>
+    <meta charset="UTF-8">
+    <meta name="viewport"
+        content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+    <meta name="apple-mobile-web-app-capable" content="yes">
+    <meta name="format-detection" content="telephone=yes"/>
+    <meta name="apple-mobile-web-app-status-bar-style" content="black">
+    <meta http-equiv="X-UA-Compatible" content="ie=edge">
+    <meta http-equiv="X-UA-Compatible" content="ie=edge">
+    <script src="/big-member/js/rem.js"></script>
+    <!--S-当前页面的css资源-->
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/reset-css/5.0.1/reset.min.css />
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/index.css />
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/v-charts/1.19.0/style.min.css />
+    <!--E-当前页面的css资源-->
+    <link rel="stylesheet" href='{{Msg "seo" "cdn"}}/big-member/weixin/css/public.css?v={{Msg "seo" "version"}}'>
+    <link rel="stylesheet" href='{{Msg "seo" "cdn"}}/big-member/weixin/css/j-icons.css?v={{Msg "seo" "version"}}'>
+    <link rel="stylesheet" href=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/icon/local.css />
+    <link rel="stylesheet" href='{{Msg "seo" "cdn"}}/common-module/collection/css/index.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Msg "seo" "cdn"}}/common-module/public/css/empty.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Msg "seo" "cdn"}}/common-module/filter/css/filter_limit.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Msg "seo" "cdn"}}/common-module/filter/css/project_cell.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Msg "seo" "cdn"}}/common-module/filter/css/project_header.css?v={{Msg "seo" "version"}}' />
+</head>
+<body>
+  <div class="j-container">
+    <div class="j-main" id="analysisList" v-cloak>
+      <filter-component :anyncdata="anyncData" :initfilters="initFilters" :show-tip="false" :switch="confirmSwitch" :show-select="false" :filtersdata="filters"  @confirm="confirm"></filter-component>
+      <div class="project-detail-list" v-if="Object.keys(projectInfo).length != 0 && projectInfo.list.length > 0">
+        <project-header :sort-optiontitle="sortOptiontitle" :sort-option="sortOption" :total="projectInfo.total"  @setsort="setsortType"></project-header>
+        <van-list
+          v-model:loading="vanlistParams.loading"
+          :finished="vanlistParams.finished"
+          :finished-text="projectInfo.total > 5000 ? '为您展示前5000条,可细化筛选条件查看更多信息': '没有更多了'"
+          @load="onListLoad"
+        >
+          <project-cell @set-winner-link="setWinnerLink" @set-buyer-link="setBuyerLink(item)" @set-link-url="setLinkUrl" :item="item" v-for="item in projectInfo.list" :key="item.id">
+            <div class="update-time">
+              <div class="update-time-label">
+                成交时间:
+              </div>
+              <div class="update-time-content">${item.dealTime?utils.dateFromNow(item.dealTime*1000):'--'}</div>
+            </div>
+          </project-cell>
+        </van-list>
+      </div>
+      <empty v-else>暂无数据</empty>
+    </div>
+</div>
+<script src=//cdn-common.jianyu360.com/cdn/lib/vue/2.6.11/vue.min.js></script>
+<script src=//cdn-common.jianyu360.com/cdn/lib/vant/2.12.24/lib/vant.min.js></script>
+<script src=//cdn-common.jianyu360.com/cdn/lib/zepto/1.2.0/zepto.min.js></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/public/js/utils.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/public/js/china-map-data.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/collection/js/keyword-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/collection/js/area-city-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/collection/js/industry-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/collection/js/cate-mobile.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/filter/js/filter_limit.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/filter/js/project_cell.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/filter/js/project_header.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/public/js/empty.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/report-analysis/js/report_analysis_pro_list.js?v={{Msg "seo" "version"}}'></script>
+
+{{include "/common/baiducc.html"}}
+</body>
+</html>

+ 2 - 2
src/web/templates/big-member/wx/page_report_detail_week.html

@@ -190,9 +190,9 @@
             </div>
             <div class="mark-words" @click="goCollect('week_project_seek_bidamount')">全面获取关注项目的规模,分析市场容量,寻找客户!<em class="mark-icon-right"></em></div>
         </div>
-        <!-- 项目金额排行榜 -->
+        <!-- 本周项目规模排行榜TOP30 -->
         <div class="chart" v-if="showItemAmount">
-            <div class="chart_title">项目金额排行榜</div>
+            <div class="chart_title">本周项目规模排行榜TOP30</div>
             <div>
                 <div class="current-list" v-for="(item,index) in amountWinArr">
                     <div class="win-name">

+ 3 - 3
src/web/templates/frontRouter/pc/serviceSystem/free/index.html

@@ -1929,7 +1929,7 @@
                                             订阅高级版项目周报/月报,实时掌握关注项目趋势
                                         </p>
                                         <p class="text">
-                                            月新增招标和开标的项目数量、项目预算、项目规模统计,以及关注企业中标项目明细,开标项目提醒、规模TOP10采购行业;中标企业区域、资本分布统计;采购单位、中标企业排行等。
+                                            本周/月新增招标和开标的项目数量、项目预算、项目规模统计,以及关注企业中标项目明细,开标项目提醒、采购行业排名;中标企业区域、资本分布统计;采购单位、中标企业排行等。
                                         </p>
                                     </div>
                                     <div class="table_content_sortcell"><i class="free"></i></div>
@@ -1941,7 +1941,7 @@
                                 <div class="table_content_r_item cell_wite">
                                     <div class="table_content_longcell">
                                         <p class="tit">
-                                            定制化市场分析报告,精准分析客户、竞对、市场
+                                            市场分析报告,精准分析客户、竞对、市场
                                         </p>
                                         <p class="text">
                                             自定义分析范围(分析内容、区域、行业、采购单位类型、时间),对市场规模、采购单位、中标单位进行分析,包含细分业务市场的项目数量、金额分布情况、以及各细分业务市场的重点中标单位中标数量明细等。
@@ -1968,7 +1968,7 @@
                                             按需导出数据,分析市场、挖掘商机线索
                                         </p>
                                         <p class="text">
-                                            本周/字段明细:省份、城市、公告标题、公告类别、公告内容、发布时间、公告地址、剑鱼标讯地址、项目名称、项目范围、预算金额、中标金额、开标日期、采购单位、采购单位信息(采购单位联系人、采购单位联系电话、招标代理机构)、中标单位信息(中标单位、中标单位联系人、中标单位联系电话)(来源:招标公告网站)、中标单位信息(中标单位联系人、中标单位联系电话、电子邮箱)(来源:国家企业公示网站)。
+                                            字段明细:省份、城市、公告标题、公告类别、公告内容、发布时间、公告地址、剑鱼标讯地址、项目名称、项目范围、预算金额、中标金额、开标日期、采购单位、采购单位信息(采购单位联系人、采购单位联系电话、招标代理机构)、中标单位信息(中标单位、中标单位联系人、中标单位联系电话)(来源:招标公告网站)、中标单位信息(中标单位联系人、中标单位联系电话、电子邮箱)(来源:国家企业公示网站)。
                                         </p>
                                     </div>
                                     <div class="table_content_sortcell"><i class="free"></i></div>

+ 1 - 1
src/web/templates/pc/brand/index.html

@@ -67,7 +67,7 @@
 
   <!-- 核心产品区域 -->
   <div class="jy-index-product CfadeInUp">
-    <h3 class="module-title">核心产品</h3>
+    <h3 class="module-title">剑鱼赋能招投标全场景决策</h3>
     <div class="w1200 product-container">
       <div class="main-product">
         <div class="product-item main-product-item svip-product" data-href="/front/subscribe.html">

+ 12 - 12
src/web/templates/pc/supsearch.html

@@ -1172,7 +1172,7 @@
         <i class="icon-arrow"></i>
       </div>
     </div>
-    <!-- 超前项目推荐&&定制化分析报告 -->
+    <!-- 超前项目推荐&&市场分析报告 -->
     <div id="jyChartCom" class="w">
       <div class="advanced-pro-rec" v-show="advancedInfo.show">
         <div class="p-lr-32">
@@ -1187,8 +1187,8 @@
               </div>
             </div>
             <div class="c-a-r-option">
-              <div v-if="nowModuleName === '定制化分析报告'" class="c-view-report c-view-common" @click="goToReport">查看完整报告</div>
-              <div class="c-view-interest c-view-common" @click="onClickInterested(nowModuleName === '定制化分析报告' ? 'B' : 'A')">感兴趣点我</div>
+              <div v-if="nowModuleName === '市场分析报告'" class="c-view-report c-view-common" @click="goToReport">查看完整报告</div>
+              <div class="c-view-interest c-view-common" @click="onClickInterested(nowModuleName === '市场分析报告' ? 'B' : 'A')">感兴趣点我</div>
               <div class="c-up-or-down" @click="toggleAdvancedContent()">
                 <el-button type="text">
                   ${ advancedInfo.showContent ? '收起' : '展开'}
@@ -1217,12 +1217,12 @@
                 </div>
               </div>
             </div>
-            <!-- 定制化分析报告 -->
-            <!-- 定制化分析报告 -->
+            <!-- 市场分析报告 -->
+            <!-- 市场分析报告 -->
             <div class="custom-analysis-report">
               <div class="c-a-r-top" v-if="nowModuleName === '超前项目推荐'">
                 <div class="c-a-r-title">
-                  <div class="r-title-text">定制化分析报告</div>
+                  <div class="r-title-text">市场分析报告</div>
                   <div class="r-title-tip">
                     量身定制个性化报告,分析市场竞争格局,为企业找准市场机会!
                   </div>
@@ -2591,8 +2591,8 @@ function checkTagDisabled () {
               title: '超前项目推荐',
               desc: '提前推送超前项目,优先对接项目负责人'
             },
-            定制化分析报告: {
-              title: '定制化分析报告',
+            市场分析报告: {
+              title: '市场分析报告',
               desc: '量身定制个性化报告,分析市场竞争格局,为企业找准市场机会!'
             }
           },
@@ -2619,7 +2619,7 @@ function checkTagDisabled () {
         if (this.advancedInfo.briefList.length || this.advancedInfo.projectList.length) {
           return '超前项目推荐'
         } else {
-          return '定制化分析报告'
+          return '市场分析报告'
         }
       },
       // 保存显示排除词
@@ -2638,7 +2638,7 @@ function checkTagDisabled () {
           return true
         }
       },
-      // 是否展示定制化分析报告模块
+      // 是否展示市场分析报告模块
       getShowChart () {
         return Object.keys(this.chartCustomData).length
       },
@@ -2793,7 +2793,7 @@ function checkTagDisabled () {
       getInterested () {
         vm.isNeedSubmit('pc_search_dzhfxbg')
       },
-      // 定制化分析报告&&超前项目推荐数据请求
+      // 市场分析报告&&超前项目推荐数据请求
       getCustomReportData () {
         $('#customerChart').hide()
         $('#winnerChart').hide()
@@ -2818,7 +2818,7 @@ function checkTagDisabled () {
                   })
                   _this.advancedInfo.projectList = res.data.ahead.projectTop2 || []
                 }
-                //定制化分析报告
+                //市场分析报告
                 _this.chartCustomData = res.data.custom || {}
                 if (_this.advancedInfo.briefList.length || _this.advancedInfo.projectList.length || Object.keys(_this.chartCustomData).length) {
                   _this.advancedInfo.show = true

+ 1 - 1
src/web/templates/weixin/historypush.html

@@ -305,7 +305,7 @@
     <!-- <div class="analysis-module"> -->
       <!-- 超前项目推荐 -->
       <!-- <recommend-com  ref="recommendRef"  @toggle="onToggleStatus"></recommend-com> -->
-      <!-- 定制化分析报告 -->
+      <!-- 市场分析报告 -->
       <!-- <div v-show="collapseStatus"> -->
         <!-- <CustomReport :chartData="chartData"></CustomReport> -->
       <!-- </div>

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff