瀏覽代碼

feat:移动端添加遮罩、微信定制化分析报告开发

tsz 2 年之前
父節點
當前提交
abef5e2fca
共有 36 個文件被更改,包括 5982 次插入29 次删除
  1. 9 1
      src/jfw/modules/app/src/web/staticres/jyapp/big-member/js/report_analysis.js
  2. 149 25
      src/jfw/modules/app/src/web/templates/big-member/page_report_analysis.html
  3. 2 2
      src/jfw/modules/app/src/web/templates/big-member/page_report_analysis_history.html
  4. 1 1
      src/web/staticres/common-module/collection/css/index.css
  5. 324 0
      src/web/staticres/common-module/collection/js/analysis-report-example.js
  6. 581 0
      src/web/staticres/common-module/report-analysis/css/report_analysis.css
  7. 二進制
      src/web/staticres/common-module/report-analysis/image/01-bg.png
  8. 二進制
      src/web/staticres/common-module/report-analysis/image/01.png
  9. 二進制
      src/web/staticres/common-module/report-analysis/image/02-bg.png
  10. 二進制
      src/web/staticres/common-module/report-analysis/image/02.png
  11. 二進制
      src/web/staticres/common-module/report-analysis/image/03-bg.png
  12. 二進制
      src/web/staticres/common-module/report-analysis/image/03.png
  13. 二進制
      src/web/staticres/common-module/report-analysis/image/04-1-bg.png
  14. 二進制
      src/web/staticres/common-module/report-analysis/image/04-1.png
  15. 二進制
      src/web/staticres/common-module/report-analysis/image/04-2-bg.png
  16. 二進制
      src/web/staticres/common-module/report-analysis/image/04-2.png
  17. 二進制
      src/web/staticres/common-module/report-analysis/image/05-bg.png
  18. 二進制
      src/web/staticres/common-module/report-analysis/image/05.png
  19. 二進制
      src/web/staticres/common-module/report-analysis/image/06-bg.png
  20. 二進制
      src/web/staticres/common-module/report-analysis/image/06.png
  21. 二進制
      src/web/staticres/common-module/report-analysis/image/07-bg.png
  22. 二進制
      src/web/staticres/common-module/report-analysis/image/07.png
  23. 二進制
      src/web/staticres/common-module/report-analysis/image/08-bg.png
  24. 二進制
      src/web/staticres/common-module/report-analysis/image/08.png
  25. 185 0
      src/web/staticres/common-module/report-analysis/js/components/lineChartScatter.js
  26. 120 0
      src/web/staticres/common-module/report-analysis/js/components/marketAreaScatter.js
  27. 237 0
      src/web/staticres/common-module/report-analysis/js/components/marketSegment.js
  28. 241 0
      src/web/staticres/common-module/report-analysis/js/components/marketTimeScatter.js
  29. 105 0
      src/web/staticres/common-module/report-analysis/js/components/marketTop3Table.js
  30. 161 0
      src/web/staticres/common-module/report-analysis/js/components/marketUserScatter.js
  31. 198 0
      src/web/staticres/common-module/report-analysis/js/components/projectScatter.js
  32. 1006 0
      src/web/staticres/common-module/report-analysis/js/echarts_option.js
  33. 1817 0
      src/web/staticres/common-module/report-analysis/js/report_analysis.js
  34. 222 0
      src/web/staticres/common-module/report-analysis/js/report_analysis_history.js
  35. 566 0
      src/web/templates/big-member/wx/page_report_analysis.html
  36. 58 0
      src/web/templates/big-member/wx/page_report_analysis_history.html

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

@@ -10,6 +10,7 @@ var vm = new Vue({
     industryComponent: industryComponent,
     cateComponent: cateComponent,
     dateComponent: dateComponent,
+    chartExample: chartExample,
     // 图表
     projectScatter: projectScatter,
     marketTimeScatter: marketTimeScatter,
@@ -235,9 +236,15 @@ var vm = new Vue({
     },
     stickyOffset: 0,
     notSetKey: false, // 未设置关键词
-    isSubCount: false // 是否子账号
+    isSubCount: false, // 是否子账号
+    powerInfo: {}
   },
   computed: {
+    getStatus: function () {
+      if (JSON.stringify(this.powerInfo) !== '{}') {
+        return this.powerInfo.power.indexOf(10) === -1
+      }
+    },
     anchorTopList: function () {
       var arr = []
       this.dimensionList.forEach(function (item) {
@@ -445,6 +452,7 @@ var vm = new Vue({
         type:'POST',
         url:'/bigmember/use/isAdd',
         success:function(res) {
+          _this.powerInfo = res.data
           if (res.data && res.data.isSubCount){
             _this.isSubCount = true
           }

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

@@ -8,7 +8,8 @@
     <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}}/jyapp/big-member/css/report_analysis.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"}}' />
+    <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/css/index.css?v={{Msg "seo" "version"}}' />
     <style>
         /* fix: --- 弹窗组件不能显示底部问题  */
         .report-popup .j-main.unitTab {
@@ -17,6 +18,47 @@
         .collection .unitTab {
             flex: 1;
         }
+        .example-title{
+        padding: .32rem .32rem .12rem;
+        font-size: .36rem;
+        line-height: .52rem;
+        color: #171826;
+        font-weight: bold;
+        background-color: #fcfcfd;
+      }
+      .vip_openDialog{
+        margin-top: 0.92rem 0 .6rem;
+        width: 6.06rem;
+        background: url(/big-member/image/openVip.png) no-repeat;
+        background-size: 100% 100%;
+        box-sizing: border-box;
+      }
+      .vip_openDialog .goBtn{
+        margin-bottom: .48rem;
+      }
+      .vip_extend{
+        padding: .16rem 0 0;
+        line-height: .4rem;
+        color: #171826;
+      }
+      .vip_component {
+        margin-top: .16rem;
+        flex-direction: column;
+      }
+
+      .vip_component .example-title {
+        width: 100%;
+        height: .96rem;
+        background: #fcfcfd;
+        font-size: .36rem;
+      }
+      .vip_component .chart_com{
+        width: 100%;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        height: inherit;
+      }
         /* fix: --- end */
     </style>
 </head>
@@ -102,7 +144,7 @@
                             </div>
                         </section>
                         <!-- 市场概况 -->
-                        <section class="section bg-white market-overview" id="market">
+                        <section class="section bg-white market-overview" id="market" v-if="getStatus">
                             <div class="section-title pd-16">市场概况</div>
                             <div class="section-content market-overview-list">
                                 <div
@@ -129,15 +171,24 @@
                                 环比:统计学术语,是表示连续2个统计周期(比如连<br />续两月)内的量的变化比。
                             </div>
                         </section>
+                        <div class="vip_component"
+                          v-if="!getStatus"
+                          style="height:8.84rem">
+                          <p class="example-title">市场概况</p>
+                          <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='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/01.png?v={{Msg "seo" "version"}}'>
+                            </chart-example>
+                          </div>
+                        </div>
                         <!-- 项目规模分布 -->
-                        <section class="section bg-white pd-16 project-scatter" v-if="sections.projectScatter.dataAlready">
+                        <section class="section bg-white pd-16 project-scatter" v-if="sections.projectScatter.dataAlready && getStatus">
                             <div class="section-title">项目规模分布</div>
                             <div class="section-content">
                                 <project-scatter :chart-data="sections.projectScatter.chartData"></project-scatter>
                             </div>
                         </section>
                         <!-- 项目规模TOP10 -->
-                        <section class="section bg-white pd-16 project-scatter" v-if="sections.projectScatter.tableData.length">
+                        <section class="section bg-white pd-16 project-scatter" v-if="sections.projectScatter.tableData.length && getStatus">
                             <div class="section-title">项目规模TOP10</div>
                             <div class="section-content project-top-list">
                                 <div
@@ -178,6 +229,15 @@
                                 </div>
                             </div>
                         </section>
+                        <div class="vip_component"
+                          v-if="!getStatus"
+                          style="height:11.38rem">
+                          <p class="example-title">项目规模分布</p>
+                          <div class="chart_com" style="background:url('/common-module/report-analysis/image/02-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
+                            <chart-example type="item_2" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/02.png?v={{Msg "seo" "version"}}'>
+                            </chart-example>
+                          </div>
+                        </div>
                         <!-- 时间分布 -->
                         <section class="section bg-white pd-16 time-scatter" v-if="sections.timeScatter.dataAlready">
                             <div class="section-header">
@@ -205,24 +265,33 @@
                             </div>
                         </section>
                         <!-- 地区分布 -->
-                        <div class="section bg-white pd-16 area-scatter" v-if="sections.areaScatter.dataAlready && notOneAreaFilter">
+                        <div class="section bg-white pd-16 area-scatter" v-if="sections.areaScatter.dataAlready && notOneAreaFilter && getStatus">
                             <div class="section-title">地区分布</div>
                             <div class="section-content">
                                 <market-area-scatter :chart-data="sections.areaScatter.chartData"></market-area-scatter>
                             </div>
                         </div>
-                        <div class="section bg-white pd-16" v-if="sections.areaScatter.projectCountTop3">
+                        <div class="section bg-white pd-16" v-if="sections.areaScatter.projectCountTop3 && getStatus">
                             <div class="section-title">项目数量TOP3地区的重点中标单位</div>
                             <div class="section-content">
                                 <market-top3-table :table-data="sections.areaScatter.projectCountTop3" type="count" @save="saveState"></market-top3-table>
                             </div>
                         </div>
-                        <div class="section bg-white pd-16" v-if="sections.areaScatter.projectAmountTop3">
+                        <div class="section bg-white pd-16" v-if="sections.areaScatter.projectAmountTop3 && getStatus">
                             <div class="section-title">项目金额TOP3地区的重点中标单位</div>
                             <div class="section-content">
                                 <market-top3-table :table-data="sections.areaScatter.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
                             </div>
                         </div>
+                        <div class="vip_component"
+                          v-if="!getStatus"
+                          style="height:13.08rem">
+                          <p class="example-title">地区分布</p>
+                          <div class="chart_com" style="background:url('/common-module/report-analysis/image/03-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
+                            <chart-example type="item_3" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/03.png?v={{Msg "seo" "version"}}'>
+                            </chart-example>
+                          </div>
+                        </div>
                         <!-- 客户分布 -->
                         <div class="section bg-white pd-16 user-scatter" v-if="sections.userScatter.list.length">
                             <div class="section-title">客户分布</div>
@@ -243,31 +312,49 @@
                             </div>
                         </div>
                         <!-- 细分市场 - 项目数量 -->
-                        <div class="section bg-white pd-16 market-refine" v-if="sections.market.refine.dataAlready">
+                        <div class="section bg-white pd-16 market-refine" v-if="sections.market.refine.dataAlready && getStatus">
                             <div class="section-title">细分市场 - 项目数量</div>
                             <div class="section-content">
                                 <market-segment :chart-data="sections.market.refine.projectCountData" type="count"></market-segment>
                             </div>
                         </div>
-                        <div class="section bg-white pd-16" v-if="sections.market.refine.projectCountTop3">
+                        <div class="section bg-white pd-16" v-if="sections.market.refine.projectCountTop3 && getStatus">
                             <div class="section-title">细分市场的重点中标单位-项目数量</div>
                             <div class="section-content">
                                 <market-top3-table :table-data="sections.market.refine.projectCountTop3" type="count" @save="saveState"></market-top3-table>
                             </div>
                         </div>
+                        <div class="vip_component"
+                          v-if="!getStatus"
+                          style="height:10.8rem">
+                          <p class="example-title">细分市场 - 项目数量</p>
+                          <div class="chart_com" style="background:url('/common-module/report-analysis/image/04-1-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
+                            <chart-example type="item_4_1" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/04-1.png?v={{Msg "seo" "version"}}'>
+                            </chart-example>
+                          </div>
+                        </div>
                         <!-- 细分市场 - 项目金额 -->
-                        <div class="section bg-white pd-16 market-refine" v-if="sections.market.refine.dataAlready">
+                        <div class="section bg-white pd-16 market-refine" v-if="sections.market.refine.dataAlready && getStatus">
                             <div class="section-title">细分市场 - 项目金额</div>
                             <div class="section-content">
                                 <market-segment :chart-data="sections.market.refine.projectAmountData" type="amount"></market-segment>
                             </div>
                         </div>
-                        <div class="section bg-white pd-16" v-if="sections.market.refine.projectAmountTop3">
+                        <div class="section bg-white pd-16" v-if="sections.market.refine.projectAmountTop3 && getStatus">
                             <div class="section-title">细分市场的重点中标单位-项目金额</div>
                             <div class="section-content">
                                 <market-top3-table :table-data="sections.market.refine.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
                             </div>
                         </div>
+                        <div class="vip_component"
+                          v-if="!getStatus"
+                          style="height:10.8rem">
+                          <p class="example-title">细分市场 - 项目金额</p>
+                          <div class="chart_com" style="background:url('/common-module/report-analysis/image/04-2-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
+                            <chart-example type="item_4_2" imgurl='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/04-2.png?v={{Msg "seo" "version"}}'>
+                            </chart-example>
+                          </div>
+                        </div>
                         <!-- 采购规模分布 -->
                         <div class="section bg-white pd-16 buyerclass-scatter" id="buyer" v-if="sections.buyerclass.dataAlready">
                             <div class="section-title">采购规模分布</div>
@@ -275,37 +362,73 @@
                                 <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">
+                        <div class="section bg-white pd-16" v-if="sections.buyerclass.projectCountTop3 && getStatus">
                             <div class="section-title">项目数量TOP3采购单位及其重点合作中标单位</div>
                             <div class="section-content">
                                 <market-top3-table :table-data="sections.buyerclass.projectCountTop3" type="count" @save="saveState"></market-top3-table>
                             </div>
                         </div>
-                        <div class="section bg-white pd-16" v-if="sections.buyerclass.projectAmountTop3">
+                        <div class="vip_component"
+                          v-if="!getStatus"
+                          style="height:10.8rem">
+                          <p class="example-title">项目数量TOP3</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='{{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-content">
                                 <market-top3-table :table-data="sections.buyerclass.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
                             </div>
                         </div>
-                        <!-- 采购规模分布 -->
+                        <div class="vip_component"
+                          v-if="!getStatus"
+                          style="height:10.8rem">
+                          <p class="example-title">项目金额TOP3</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='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/06.png?v={{Msg "seo" "version"}}'>
+                            </chart-example>
+                          </div>
+                        </div>
+                        <!-- 中标规模分布 -->
                         <div class="section bg-white pd-16 winner-scatter" id="winner" v-if="sections.winner.dataAlready">
                             <div class="section-title">中标规模分布</div>
                             <div class="section-content">
                                 <line-chart-scatter :chart-data="sections.winner.chartData"></line-chart-scatter>
                             </div>
                         </div>
-                        <div class="section bg-white pd-16" v-if="sections.winner.projectCountTop3">
+                        <div class="section bg-white pd-16" v-if="sections.winner.projectCountTop3 && getStatus">
                             <div class="section-title">项目数量TOP3中标单位及其重点合作采购单位</div>
                             <div class="section-content">
                                 <market-top3-table :table-data="sections.winner.projectCountTop3" type="count" @save="saveState"></market-top3-table>
                             </div>
                         </div>
-                        <div class="section bg-white pd-16" v-if="sections.winner.projectAmountTop3">
+                        <div class="vip_component"
+                          v-if="!getStatus"
+                          style="height:10.8rem">
+                          <p class="example-title">项目数量TOP3</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='{{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-content">
                                 <market-top3-table :table-data="sections.winner.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
                             </div>
                         </div>
+                        <div class="vip_component"
+                          v-if="!getStatus"
+                          style="height:10.8rem">
+                          <p class="example-title">项目金额TOP3</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='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/image/08.png?v={{Msg "seo" "version"}}'>
+                            </chart-example>
+                          </div>
+                        </div>
                     </div>
                     <div class="fixed-bottom-right clickable scroll-to-top" style="display: none;">
                         <van-icon name="arrow-up"></van-icon>
@@ -427,16 +550,17 @@
 <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 -->
-<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}}/jyapp/big-member/js/components/projectScatter.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/components/marketTimeScatter.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/components/marketAreaScatter.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/components/marketTop3Table.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/components/marketUserScatter.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/components/marketSegment.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/components/lineChartScatter.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/echarts_option.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/collection/js/analysis-report-example.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/projectScatter.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/marketTimeScatter.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/marketAreaScatter.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/components/marketTop3Table.js?v={{Msg "seo" "version"}}'></script>
+<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>
 <!-- main.js -->
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/report_analysis.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/report_analysis.js?v={{Msg "seo" "version"}}'></script>
 
 </body>
 </html>

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

@@ -7,7 +7,7 @@
     <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}}/jyapp/big-member/css/report_analysis.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"}}' />
     <link rel="stylesheet" href='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/diy-report/css/report-list.css?v={{Msg "seo" "version"}}' />
 </head>
 
@@ -43,7 +43,7 @@
 {{include "/big-member/commonjs.html"}}
 
 <script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/diy-report/js/report-list.js?v={{Msg "seo" "version"}}'></script>
-<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/jyapp/big-member/js/report_analysis_history.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Cdns .Host "seo" "cdn"|SafeUrl}}/common-module/report-analysis/js/report_analysis_history.js?v={{Msg "seo" "version"}}'></script>
 
 </body>
 </html>

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

@@ -1001,10 +1001,10 @@
     display: flex;
     justify-content: center;
     align-items: center;
+    margin-top: .48rem;
 }
 
 .vip_openDialog .openBtn .goBtn {
-    margin-top: .48rem;
     width: 4.78rem;
     height: 100%;
     background: #2cb7ca;

+ 324 - 0
src/web/staticres/common-module/collection/js/analysis-report-example.js

@@ -0,0 +1,324 @@
+var vipDialog = `
+<div class="vip_openDialog">
+  <div class="vip_content">
+    <div class="vip_content_div">
+      <img class="vip_img" :src="imgurl" />
+      <span class="vip_example">示例</span>
+    </div>
+  </div>
+  <div class="vip_head">
+      <span style="display:none;">{{getTextMap.titleText}}</span>
+      <span class="vip_extend"><span>{{getTextMap.headText.top}}</span><br/>{{getTextMap.headText.bot}}</span>
+  </div>
+  <div class="openBtn">
+      <button class="goBtn" @click="goOpen(getTextMap.headText.top,getTextMap.headText.bot, getTextMap.source)">{{getTextMap.btnText}}</button>
+  </div>
+</div>
+`
+
+var chartExample = {
+  name: 'chart-example',
+  template: vipDialog,
+  props: {
+    'imgurl': {
+      type: String,
+      default: function() {
+        return ''
+      }
+    },
+    "type": {
+      type: String,
+      default: function () {
+        return ''
+      }
+    },
+    "power": {
+      type: Array,
+      default: function () {
+        return []
+      }
+    },
+    "status": {
+      type: Number,
+      default: function () {
+        return 0
+      }
+    },
+    "userinfo": {
+      type: Object,
+      default: function () {
+        return {}
+      }
+    },
+    "useage": {
+      type: Object,
+      default: function () {
+        return {}
+      }
+    },
+  },
+  data: function() {
+    return {
+      titleText: '开通大会员',
+      btnText: '免费体验',
+      headText: {
+        top: '通过实时监控项目的招标、中标、合同等',
+        bot: '信息,全面挖掘更多潜在商机!'
+      }
+    }
+  },
+  computed: {
+    getTextMap () {
+      var textMap = {
+        titleText: '开通大会员',
+        btnText: '去开通',
+        headText: {
+          top: '通过实时监控项目的招标、中标、合同等',
+          bot: '信息,全面挖掘更多潜在商机!'
+        },
+        source: ''
+      }
+      // if (this.power.indexOf(5) < 0 && this.status > 0) {
+      //   textMap.btnText = '联系客服'
+      // }
+      switch (this.type) {
+          // 市场概况
+        case 'item_1': {
+          textMap.headText.top = '通过招标大数据综合分析项目体量,'
+          textMap.headText.bot = '采购单位和中标单位数量,全面掌握市场趋势'
+          textMap.source = 'buyer_portrait_contacts_freeuser'
+          break
+        }
+          // 项目规模分布
+        case 'item_2': {
+          textMap.headText.top = '从项目总金额、项目总数等多维度分析'
+          textMap.headText.bot = '了解市场需求状况,全面挖掘更多潜在商机'
+          textMap.source = 'buyer_portrait_yearData_freeuser'
+          break
+        }
+          // 地区分布
+        case 'item_3': {
+          textMap.headText.top = '根据项目数量、中标金额统计市场热度高的区域'
+          textMap.headText.bot = '为企业市场战略布局提供可靠的数据支持'
+          textMap.source = 'buyer_portrait_monthData_freeuser'
+          break
+        }
+          // 细分市场
+        case 'item_4_1': {
+          textMap.headText.top = '通过市场细分,企业可以综合选择适合的目标市场'
+          textMap.headText.bot = '有利于挖掘市场机会,开拓新市场'
+          textMap.source = 'buyer_portrait_moneyRange_freeuser'
+          break
+        }
+        case 'item_4_2': {
+          textMap.headText.top = '通过市场细分,企业可以综合选择适合的目标市场'
+          textMap.headText.bot = '有利于挖掘市场机会,开拓新市场'
+          textMap.source = 'buyer_portrait_moneyRange_freeuser'
+          break
+        }
+          // 采购单位项目数量TOP3
+        case 'item_5': {
+          textMap.headText.top = '直观了解优质采购单位名单'
+          textMap.headText.bot = '分析采购单位与供应商关系远近,辅助市场决策'
+          textMap.source = 'buyer_portrait_bidtypeData_freeuser'
+          break
+        }
+          // 采购单位项目金额TOP3
+        case 'item_6': {
+          textMap.headText.top = '透过采购单位项目采购金额排名'
+          textMap.headText.bot = '重点合作单位采购占比,帮助供应商挖掘市场机会'
+          textMap.source = 'buyer_portrait_rate_freeuser'
+          break
+        }
+          // 中标单位项目数量TOP3
+        case 'item_7': {
+          textMap.headText.top = '综合分析中标企业及合作采购单位'
+          textMap.headText.bot = '洞悉行业的市场竞争格局和市场份额'
+          textMap.source = 'buyer_portrait_top12_freeuser'
+          break
+        }
+          // 中标单位项目金额TOP3
+        case 'item_8': {
+          textMap.headText.top = '洞察行业的中标市场情况、分析业务关系'
+          textMap.headText.bot = '为企业找准市场机会,制定市场策略提供数据分析'
+          textMap.source = 'buyer_portrait_topShow_freeuser'
+          break
+        }
+      }
+      return textMap
+    },
+    // 遮罩按钮对应文案
+    shadeBottomBtnText () {
+      let btnText = ''
+      var info = this.userinfo
+      var usage = this.useage
+      // 【立即解锁】:未体验过采购单位画像的免费用户,点击进行“欢迎体验采购单位全景分析”留资
+      // 【去开通】:已体验过1次采购单位画像的免费用户,点击进入超级订阅购买页
+      // 【前往升级】:超级订阅老版用户+购买了非全国采购单位画像余额为0的超级订阅新版用户,点击进入超级订阅升级页
+      // 【联系客服】:购买了全国采购单位画像余额为0的超级订阅新版用户+无采购单位画像权限的大会员客户;点击调起智齿在线客服
+      if (info.isFree) {
+        if (info.freeBuyerPort === 0) {
+          btnText = '立即解锁'
+        } else {
+          btnText = '去开通'
+        }
+      } else {
+        // 老超级订阅用户
+        var oldVip = info.vipStatus > 0 && !info.viper
+        // 新超级订阅用户
+        var newVip = info.vipStatus > 0 && info.viper
+        // 大会员用户
+        var member = this.status > 0
+        // 新超级订阅用户买的非全国 余额为0
+        var noAllProvinNoCounts = newVip && usage.provin !== -1 && usage.surplus <= 0
+        // 超级订阅新用户 购买的全国 余额为0
+        var allProvinNoCounts = newVip && usage.provin === -1 && usage.surplus <= 0
+        // 无权限的大会员用户
+        var noAuthMember = member && this.power.indexOf(5) === -1
+        // 纯商机管理用户
+        var entniche = info.entniche && !oldVip && !newVip && !member
+        // 超级订阅用户采购单位画像查看次数为0遮罩按钮显示'立即充值'
+        if (oldVip || noAllProvinNoCounts) {
+          if(oldVip) {
+            btnText = '前往升级'
+          } else {
+            btnText = '立即充值'
+          }
+        } else if (allProvinNoCounts || noAuthMember || entniche) {
+          if(allProvinNoCounts) {
+            btnText = '立即充值'
+          } else {
+            btnText = '联系客服'
+          }
+        }
+      }
+      return btnText
+    }
+  },
+  methods: {
+    linkFn: function(id, source) {
+      var u = this.useage
+      const textinit = `
+      <div><span class="on">升级超级订阅:</span><span>适合需要订阅更多省份、查看更多采购单位画像及企业画像的用户。</span></div><div style="margin-top:20px"><span class="on">充值画像包:</span><span>适合仅需要查看更多采购单位画像用户。</span></div>
+      `
+      var isWeixin = utils.isWeiXinBrowser
+      if(!isWeixin) {
+        if (this.getTextMap.btnText == '立即解锁') {
+          // 留资
+          location.href = '/jyapp/frontPage/bigmember/free/perfect_info?source=' + source
+        } else if (this.getTextMap.btnText == '联系客服') {
+          // try {
+          //   JyObj.callPhone('400-108-6670');
+          // } catch (error) {
+          //   console.log(error)
+          // }
+          location.href = '/jyapp/free/customer' // 客服
+        } else if (this.getTextMap.btnText == '去开通') {
+          // location.href = '/jyapp/vipsubscribe/vipsubscribe_new'
+          location.href = '/jy_mobile/common/order/create/svip?type=buy'
+        } else if (this.getTextMap.btnText == '前往升级') {
+          //跳转清除旧套餐缓存,防止计算价格出错
+          sessionStorage.removeItem('vipSub_oldBuySet')
+          // location.href = '/jyapp/vipsubscribe/upgradePage'
+          location.href = '/jy_mobile/common/order/create/svip?type=upgrade'
+        } else if (this.getTextMap.btnText == '立即充值') {
+          // 选择充值方式
+          // 判断是否购买全国,全国直接跳转到到充值页面, 非全国显示弹窗
+          if(u.provin == -1) {
+            location.href = '/jy_mobile/common/order/create/areapack?type=1'
+          } else {
+            this.$dialog.confirm({
+              title: '请选择充值方式',
+              message: textinit,
+              overlayClass: 'showSelectDialog',
+              width: 303,
+              className: 'pro-log select-recharge',
+              messageAlign: 'left',
+              confirmButtonColor: '#2ABED1',
+              confirmButtonText: '充值画像包',
+              cancelButtonText: '升级超级订阅',
+              closeOnClickOverlay: true,
+              showCancelButton: true
+            }).then(function () {
+              location.href = '/jy_mobile/common/order/create/buyerpack?type=1'
+            }).catch(function (e) {
+              if(e == 'cancel') {
+                //跳转清除旧套餐缓存,防止计算价格出错
+                sessionStorage.removeItem('vipSub_oldBuySet')
+                // location.href = '/jyapp/vipsubscribe/upgradePage'
+                location.href = '/jy_mobile/common/order/create/svip?type=upgrade'
+              }
+            })
+          }
+        }
+      } else {
+        if (this.getTextMap.btnText == '立即解锁') {
+          // 留资
+          location.href = '/weixin/frontPage/bigmember/free/perfect_info?source=' + source
+        } else if (this.getTextMap.btnText == '联系客服') {
+          // location.href = 'tel:400-108-6670'
+          location.href = '/big/wx/page/customer'
+        } else if (this.getTextMap.btnText == '去开通') {
+          // location.href = '/front/vipsubscribe/vipsubscribe_new'
+          location.href = '/jy_mobile/common/order/create/svip?type=buy'
+        } else if (this.getTextMap.btnText == '前往升级') {
+          // location.href = '/front/vipsubscribe/upgradePage'
+          location.href = '/jy_mobile/common/order/create/svip?type=upgrade'
+        } else if (this.getTextMap.btnText == '立即充值') {
+          // 判断是否购买全国,全国直接跳转到到充值页面, 非全国显示弹窗
+          if(u.provin == -1) {
+            location.href = '/jy_mobile/common/order/create/areapack?type=1'
+          }  else {
+            this.$dialog.confirm({
+              title: '请选择充值方式',
+              message: textinit,
+              overlayClass: 'showSelectDialog',
+              width: 303,
+              className: 'pro-log select-recharge',
+              messageAlign: 'left',
+              confirmButtonColor: '#2ABED1',
+              confirmButtonText: '充值画像包',
+              cancelButtonText: '升级超级订阅',
+              closeOnClickOverlay: true,
+              showCancelButton: true
+            }).then(function () {
+              location.href = '/jy_mobile/common/order/create/buyerpack?type=1'
+            }).catch(function (e) {
+              if(e == 'cancel') {
+                // location.href = '/front/vipsubscribe/upgradePage'
+                location.href = '/jy_mobile/common/order/create/svip?type=upgrade'
+              }
+            })
+          }
+        }
+      }
+    },
+    goOpen: function(top, bot, source) {
+      console.log(this.$parent.encryptId)
+      var params = {
+        mold: 'isCBBT',
+        id: this.$parent.encryptId,
+        introduce: top + bot
+      }
+      var _this = this
+      console.log(_this.getTextMap.btnText)
+      if (_this.getTextMap.btnText == '立即解锁') {
+        $.ajax({
+          type: 'POST',
+          url: '/publicapply/drainage/buyerunit',
+          contentType: "application/json",
+          data: JSON.stringify(params),
+          success: function (res) {
+            _this.linkFn(_this.$parent.encryptId, source)
+          },
+          error: function (error) {
+            console.log(error)
+            _this.linkFn(_this.$parent.encryptId, source)
+          }
+        })
+      } else {
+        _this.linkFn(_this.$parent.encryptId)
+      }
+    }
+  }
+}

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

@@ -0,0 +1,581 @@
+.order-list-container .van-tabs__wrap {
+  height: .96rem;
+}
+.order-list-container .van-tabs__line {
+  bottom: .36rem;
+}
+.order-list-container .van-tab__pane {
+  height: 100%;
+}
+.order-list-container .van-tabs__content {
+  flex: 1;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
+.order-list-container .van-tabs {
+  width: 100%;
+}
+.order-list-container .van-tab {
+  font-size: .32rem;
+  line-height: .4rem;
+}
+
+/* vant-reset */
+.van-dialog {
+  width: 6rem;
+  border-radius: .16rem;
+}
+.van-dialog__header {
+  font-weight: 700;
+  font-size: 18px;
+  line-height: 26px;
+  color: #171826;
+}
+.van-dialog__content {
+  padding: .16rem .6rem;
+}
+.van-dialog__message {
+  padding-left: 0;
+  padding-right: 0;
+  font-size: .3rem;
+  line-height: .44rem;
+  color: #5F5E64;
+}
+.van-dialog .van-button {
+  font-size: 18px;
+  line-height: 26px;
+}
+
+.van-dialog  .van-button--default {
+  color: #171826;
+}
+
+.van-toast {
+  max-width: 4.2rem;
+  line-height: 1.6;
+}
+
+/* vant-custom */
+.j-confirm-dialog {
+  border-radius: 8px;
+}
+.j-confirm-dialog .van-dialog__message {
+  font-size: .32rem;
+  color: #171826;
+  line-height: .48rem;
+  text-align: left;
+}
+.j-confirm-dialog.text-center .van-dialog__message {
+  text-align: center;
+}
+.j-confirm-dialog .van-button {
+  font-size: .36rem;
+  color: #171826;
+  line-height: .52rem;
+}
+
+/* j-tag */
+.j-tag {
+  white-space: nowrap;
+}
+.j-tag.tag-orange {
+  color: #FF9F3F;
+  background-color: rgba(255, 159, 63, 0.1);
+  border-color: rgba(255, 159, 63, 0.1);
+}
+.j-tag.tag-blue {
+  color: #05A6F3;
+  background-color: rgba(5, 166, 243, 0.1);
+  border-color: rgba(5, 166, 243, 0.1);
+}
+.j-tag.tag-plain {
+  color: #5E5E64;
+  background-color: #F7F9F9;
+  border-color: rgba(0, 0, 0, 0.05);
+}
+
+/* empty */
+.empty-container {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  flex: 1;
+  height: 80%;
+  padding: .32rem;
+  box-sizing: border-box;
+  background-color: rgba(245, 244, 249, 1);
+}
+.empty-container {
+  min-height: 7rem;
+}
+.empty-main,
+.empty-content-position {
+  display: flex;
+  align-items: center;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.empty-content-position {
+  margin-top: -1rem;
+}
+
+.empty-container .tip-text {
+  margin-top: .2rem;
+  color: #5F5E64;
+  font-size: .28rem;
+  line-height: .4rem;
+  text-align: center;
+}
+
+.empty-container .tip-sub-text {
+  color: #9B9CA3;
+  font-size: .26rem;
+  line-height: .4rem;
+  margin-top: .12rem;
+  text-align: center;
+}
+
+.empty-container .image {
+  width: 4rem;
+  height: 4rem;
+}
+.empty-container .image > img {
+  width: 100%;
+  height: 100%;
+}
+
+/* common-css */
+.j-container .van-tabs__wrap {
+  height: 0.96rem;
+}
+.van-tab {
+  font-size: .32rem;
+  line-height: .4rem;
+}
+
+/* analysis-page */
+.pd-16 {
+  padding: .32rem;
+}
+.pd-lr16 {
+  padding: 0 .32rem;
+}
+.height8 {
+  height: .16rem;
+  width: 100%;
+  color: transparent;
+  background-color: transparent;
+}
+
+.filters-title {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: .24rem .32rem;
+  color: #161826;
+  line-height: .6rem;
+  font-size: .4rem;
+  font-weight: 700;
+}
+.filters-list {
+  margin-bottom: .16rem;
+  border-top: 1px solid transparent;
+}
+.filters-list .van-cell {
+  height: 1.08rem;
+}
+.date-cell .cell-title,
+.filters-list .van-cell__title {
+  color: #161826;
+  line-height: .48rem;
+  font-size: .28rem;
+}
+.keys-popup .popup-header {
+  padding-top: .24rem;
+  padding-bottom: .24rem;
+  height: auto;
+  flex-direction: column;
+  align-items: flex-start;
+}
+.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;
+}
+
+.date-cell {
+  padding: 10px 0;
+}
+.date-cell .cell-title {
+  padding: 0 16px;
+}
+
+.filters-list .collection .dateTags .customTime {
+  display: none;
+}
+.filters-list .collection .dateTags .timeTag {
+  flex-wrap: wrap;
+}
+.collection .dateTags {
+  height: unset;
+}
+.collection .timePicker.clickactive {
+  background-color: #fff;
+}
+.collection .timePicker.clickactive::after {
+  content: unset;
+}
+.collection .timePicker.clickactive .van-cell.van-field {
+  border-color: #2abed1;
+}
+.collection .timeTag .area-card-item {
+  width: unset;
+  height: unset;
+  padding: 0 .16rem;
+}
+.date-cell > .j-container > .j-footer {
+  display: none;
+}
+
+.search-result {
+  position: relative;
+}
+.search-result .filters-list .van-cell__title {
+  color: #161826;
+  font-size: .4rem;
+}
+.search-result .section:not(:first-of-type) {
+  position: relative;
+  margin-top: .16rem;
+}
+.search-result .section-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+.search-result .section .section-title {
+  color: #161826;
+  line-height: .52rem;
+  font-size: .36rem;
+}
+.search-result .section:not(:first-of-type) .section-content {
+  margin: .16rem 0;
+  padding: .12rem 0;
+}
+
+.fixed-bottom-right {
+  position: absolute;
+  bottom: 15%;
+  right: .32rem;
+}
+.scroll-to-top {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: .8rem;
+  height: .8rem;
+  font-size: .4rem;
+  border-radius: 50%;
+  background-color: #fff;
+  box-shadow: rgb(54,147,79,20%) 0 0 30px 5px;
+}
+
+.section-sticky {
+  width: 100%;
+}
+.van-sticky {
+  padding: 0 .32rem;
+  width: 100%;
+  background-color: #fff;
+}
+
+.section .section-tip-text {
+  font-size: .22rem;
+  line-height: .3rem;
+  color: #9B9BA3;
+  text-align: center;
+}
+
+.search-result .dimension {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  width: 100%;
+  min-height: 2.5rem;
+}
+
+.search-result .dimension .section-content {
+  padding: .28rem 0;
+}
+.van-sticky--fixed {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  min-height: 1.32rem;
+  background-color: #fff;
+}
+.van-sticky--fixed .dimension-list {
+  padding: 0!important;
+}
+.search-result .dimension > div {
+  width: 100%;
+}
+.search-result .dimension .section-title {
+  font-size: .28rem;
+  line-height: .28rem;
+  padding: .32rem;
+  padding-bottom: 0;
+  text-align: center;
+}
+.search-result .dimension .section-tip-text {
+  padding-bottom: .32rem;
+}
+
+
+.search-result .dimension-list {
+  display: flex;
+  align-items: center;
+  width: 100%;
+}
+.search-result .dimension-item {
+  display: flex;
+  flex: 1;
+  font-size: .28rem;
+  line-height: .4rem;
+}
+.search-result .dimension-item:not(:last-of-type) {
+  margin-right: .32rem;
+}
+.search-result .dimension-item::after {
+  content: unset;
+}
+
+.market-overview-list {
+  display: flex;
+  margin: 0!important;
+  padding-left: .08rem!important;
+  padding-right: .08rem!important;
+}
+.market-overview-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: space-between;
+  flex: 1;
+  padding: 0 .08rem;
+}
+.market-overview-item:not(:last-of-type) {
+  border-right: 1px solid #F2F2F2;
+}
+
+.m-overview-name {
+  margin-bottom: .08rem;
+  white-space: nowrap;
+}
+.m-overview-name,
+.m-overview-unit,
+.m-overview-type {
+  font-size: .22rem;
+  line-height: .28rem;
+  color: #5E5E64;
+  text-align: center;
+}
+.m-overview-count {
+  margin: .12rem 0;
+}
+.m-overview-ratio {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-top: .08rem;
+  height: .32rem;
+  padding: 0 .08rem;
+  border-radius: .2rem;
+}
+.m-overview-ratio.red {
+  color: #FA483C;
+  background-color: #FFEDEC;
+}
+.m-overview-ratio.green {
+  color: #04B15E;
+  background-color: #EAF8E5;
+}
+.m-overview-ratio .icon-reverse {
+  transform: rotate(180deg);
+}
+
+/* 表格首页索引 */
+.table-index-rect {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin: 0 auto;
+  width: .4rem;
+  height: .4rem;
+  color: #fff;
+  font-size: .28rem;
+  border-radius: 3px;
+  background-color: #C0C4CC;
+}
+.table-index-rect.red {
+  background-color: #FF3A20;
+}
+.table-index-rect.orange {
+  background-color: #FF9F3F;
+}
+.table-index-rect.soft-orange {
+  background-color: #EED08C;
+}
+
+/* TOP10 */
+.project-top-item {
+  padding: .32rem 0;
+}
+.project-top-item:first-of-type {
+  padding-top: .16rem;
+}
+.project-top-item:last-of-type {
+  padding-bottom: .16rem;
+}
+.project-top-item:not(:last-of-type) {
+  border-bottom: 1px solid rgba(0, 0, 0, 0.03);
+}
+.project-top-item .p-t-i-hd {
+  display: flex;
+  justify-content: space-between;
+}
+.project-top-item .p-t-i-hd .p-t-i-hd-r {
+  display: flex;
+  flex-direction: column;
+  flex: 1;
+  margin-left: .16rem;
+}
+.project-top-item .p-t-i-hd .p-t-i-hd-r-top {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  width: 100%;
+}
+.project-top-item .p-t-i-hd-r .project-actions {
+  display: flex;
+  align-items: center;
+  color: #2ABDD1;
+  line-height: .36rem;
+  font-size: .24rem;
+  white-space: nowrap;
+}
+.project-top-item .p-t-i-hd-r .project-actions .van-icon {
+  margin-left: .12rem;
+}
+.project-top-item .p-t-i-hd-r .project-actions.icon-reverse .van-icon {
+  transform: rotate(180deg);
+}
+.project-top-item .p-t-i-hd-r .project-info {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+.market-top3-table .project-name {
+  max-width: 4rem;
+}
+.project-top-item .p-t-i-hd-r .project-name {
+  font-size: .28rem;
+  color: #1D1D1D;
+  line-height: .48rem;
+  flex: 1;
+}
+.project-top-item .p-t-i-hd-r .project-tags {
+  display: flex;
+  align-items: center;
+}
+.project-top-item .p-t-i-hd-r .project-right {
+  color: #5E5E64;
+}
+.project-top-item .j-tag {
+  margin-right: .08rem;
+}
+.project-top-item .p-t-i-ft {
+  margin-top: .24rem;
+  padding: .16rem;
+  background: linear-gradient(180deg, rgba(108, 217, 236, 0.3) 0%, rgba(255, 255, 255, 0) 100%);
+  border-radius: 6px;
+}
+.project-top-item .p-t-i-ft .p-t-i-ft-top {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+.project-top-item .p-t-i-ft .p-t-i-ft-bottom {
+  display: flex;
+  align-items: center;
+  font-size: .24rem;
+  color: #5E5E64;
+  line-height: .36rem;
+}
+.project-top-item .p-t-i-ft .p-t-i-ft-sub {
+  margin-right: .24rem;
+}
+.project-top-item .p-t-i-ft .p-t-i-ft-title {
+  font-size: .26rem;
+  color: #161826;
+  line-height: .36rem;
+}
+.project-top-item .p-t-i-ft .p-t-i-ft-winner {
+  font-size: .24rem;
+  color: #5E5E64;
+  line-height: .36rem;
+}
+.project-top-item .p-t-i-ft.disabled,
+.project-top-item .p-t-i-hd-r .project-name.disabled,
+.project-top-item .p-t-i-ft .p-t-i-ft-winner.disabled {
+  color: #a2a2a2;
+  cursor: not-allowed;
+}
+
+/* time scatter */
+.time-scatter .section-actions {
+  display: flex;
+  align-items: center;
+}
+.time-scatter .action-button {
+  position: relative;
+  margin-left: .36rem;
+  font-size: .26rem;
+  color: #5E5E64;
+  line-height: .28rem;
+}
+.time-scatter .action-button.active {
+  color: #2ABDD1;
+}
+.time-scatter .action-button.active::after {
+  content: '';
+  position: absolute;
+  bottom: -8px;
+  left: 50%;
+  width: 80%;
+  height: .04rem;
+  transform: translateX(-50%);
+  background-color: #2ABDD1;
+}

二進制
src/web/staticres/common-module/report-analysis/image/01-bg.png


二進制
src/web/staticres/common-module/report-analysis/image/01.png


二進制
src/web/staticres/common-module/report-analysis/image/02-bg.png


二進制
src/web/staticres/common-module/report-analysis/image/02.png


二進制
src/web/staticres/common-module/report-analysis/image/03-bg.png


二進制
src/web/staticres/common-module/report-analysis/image/03.png


二進制
src/web/staticres/common-module/report-analysis/image/04-1-bg.png


二進制
src/web/staticres/common-module/report-analysis/image/04-1.png


二進制
src/web/staticres/common-module/report-analysis/image/04-2-bg.png


二進制
src/web/staticres/common-module/report-analysis/image/04-2.png


二進制
src/web/staticres/common-module/report-analysis/image/05-bg.png


二進制
src/web/staticres/common-module/report-analysis/image/05.png


二進制
src/web/staticres/common-module/report-analysis/image/06-bg.png


二進制
src/web/staticres/common-module/report-analysis/image/06.png


二進制
src/web/staticres/common-module/report-analysis/image/07-bg.png


二進制
src/web/staticres/common-module/report-analysis/image/07.png


二進制
src/web/staticres/common-module/report-analysis/image/08-bg.png


二進制
src/web/staticres/common-module/report-analysis/image/08.png


+ 185 - 0
src/web/staticres/common-module/report-analysis/js/components/lineChartScatter.js

@@ -0,0 +1,185 @@
+var lineChartScatterTemplate = `
+<ve-line :data="chartData" :height="options.height" :after-config="options.config" :extend="defaultOption"></ve-line>
+`
+
+var lineChartScatter = {
+  name: 'line-chart-scatter',
+  template: lineChartScatterTemplate,
+  props: {
+    chartData: {
+      type: Object,
+      default () {
+        return {
+          columns: ['金额区间', '采购总金额占比', '采购单位数量占比'],
+          rows: [
+            // {
+            //   金额区间: '>=1亿',
+            //   采购总金额占比: 2,
+            //   采购单位数量占比: 222
+            // },
+            // {
+            //   金额区间: '1000万-1亿',
+            //   采购总金额占比: 322,
+            //   采购单位数量占比: 2222
+            // },
+            // {
+            //   金额区间: '500万-1000万',
+            //   采购总金额占比: 1,
+            //   采购单位数量占比: 111
+            // }
+          ]
+        }
+      }
+    },
+  },
+  data:function () {
+    return {
+      options: {
+        height: '326px',
+        config: this.configOptions
+      },
+      defaultOption: {
+        color: ['#05A6F3', '#FF9F40'],
+        xAxis: {
+          axisLabel: {
+            textStyle: {
+              color: '#626262',
+              fontSize: 10
+            },
+            formatter: this.xAxisFormatter,
+            interval: 0
+          }
+        },
+        grid: {
+          top: 10,
+          left: 12,
+          right: 12
+        },
+        yAxis: {
+          splitLine: {
+            lineStyle: {
+              type: 'dashed',
+              width: 0.5
+            }
+          },
+          nameGap: 15,
+          nameTextStyle: {
+            fontSize: 12,
+            align: 'left',
+            color: '#9B9CA3',
+            padding: [0, 0, 0, -30]
+          },
+          axisLabel: {
+            margin: 2,
+            fontSize: 12,
+            color: '#5F5E64',
+            interval: 'auto',
+            formatter: p => p + '%'
+          }
+        },
+        legend: {
+          orient: 'horizontal',
+          icon: 'circle',
+          bottom: 10,
+          itemWidth: 8,
+          itemHeight: 8,
+          itemGap: 40,
+          textStyle: {
+            color: '#5F5E64',
+            fontSize: 12
+          }
+        },
+        series: {
+          type: 'line',
+          showSymbol: false,
+          smooth: false,
+          symbol: 'circle',
+          symbolSize: 3,
+          itemStyle: {
+            borderColor: '#fff',
+            borderWidth: 1
+          }
+        },
+        tooltip: {
+          backgroundColor: '#fff',
+          confine: true,
+          axisPointer: {
+            type: 'line',
+            lineStyle: {
+              width: 2,
+              color: '#FA483C'
+            },
+            z: 3
+          },
+          textStyle: {
+            color: '#171826',
+            fontSize: 12
+          },
+          padding: [7, 12],
+          extraCssText: 'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08)',
+          borderWidth: 2,
+          borderColor: '#F5F6F7'
+        },
+        lineStyle: {
+          width: 0.5
+        }
+      }
+    }
+  },
+  computed: {},
+  created () {},
+  methods: {
+    xAxisFormatter (params) {
+      var arr = params.split('-')
+      if (arr.length === 2) {
+        return arr.join('\n-')
+      } else {
+        return params
+      }
+    },
+    configOptions (options) {
+      // 面积颜色-渐变
+      Object.assign(options.series[0], {
+        areaStyle: {
+          normal: {
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              {
+                offset: 0,
+                color: 'rgba(42, 190, 209, 0.5)'
+              },
+              {
+                offset: 1,
+                color: 'rgba(42, 190, 209, 0)'
+              }
+            ], false)
+          }
+        }
+      })
+      Object.assign(options.series[1], {
+        areaStyle: {
+          normal: {
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              {
+                offset: 0,
+                color: 'rgba(255, 159, 63, 0.5)'
+              },
+              {
+                offset: 1,
+                color: 'rgba(255, 159, 63, 0)'
+              }
+            ], false)
+          }
+        }
+      })
+      options.tooltip.formatter = params => {
+        let tip = `<div style="padding-top:2px;color:#9B9CA3;">${params[0].name}</div>`
+        for (let i = 0; i < params.length; i++) {
+          params[i].marker = '<span style="display:inline-block;margin-right:5px;border-radius:8px;width:8px;height:8px;background-color:' + params[i].color + ';"></span>'
+          tip += params[i].marker + params[i].seriesName + ':' + params[i].value[1].toString().replace(/,/, '') + '%' + '<br/>'
+        }
+        return tip
+      }
+      return options
+    }
+  }
+}

+ 120 - 0
src/web/staticres/common-module/report-analysis/js/components/marketAreaScatter.js

@@ -0,0 +1,120 @@
+var marketAreaScatterTemplate = `
+  <div class="market-area-scatter-chart">
+    <ve-map
+      :height="options.height"
+      :init-options="initRendererSvg"
+      :after-config="options.config"
+      :data="getMapDatas"
+      :settings="defaultSettings"
+      :extend="defaultOptions">
+    </ve-map>
+  </div>
+`
+var marketAreaScatter = {
+  name: 'market-area-scatter',
+  template: marketAreaScatterTemplate,
+  props: {
+    chartData: {
+      type: Object,
+      default () {
+        return {
+          columns: ['项目所在地', '项目数量', '中标金额'],
+          rows: [
+            // {
+            //   项目所在地: '河南',
+            //   项目数量: 2,
+            //   中标金额: 2222
+            // },
+            // {
+            //   项目所在地: '北京',
+            //   项目数量: 22,
+            //   中标金额: 565666
+            // },
+            // {
+            //   项目所在地: '浙江',
+            //   项目数量: 22,
+            //   中标金额: 765666
+            // }
+          ]
+        }
+      }
+    },
+  },
+  data:function () {
+    return {
+      options: {
+        height: '400px',
+        colors: ['#05a6f3'],
+        config: this.configArea
+      },
+      initRendererSvg: {
+        renderer: 'svg'
+      },
+      // 引用/jyapp/big-member/js/echarts_option.js中配置文件
+      defaultSettings: mapSettings.chartSettings,
+      defaultOptions: mapSettings.chartExtend
+    }
+  },
+  computed: {
+    getMapDatas () {
+      return {
+        columns: this.chartData.columns,
+        rows: this.chartData.rows.map(function (v) {
+          return Object.assign({}, v, {
+            name: mapSettings.completionMapName(v.name),
+            _name: v.name
+          })
+        })
+      }
+    }
+  },
+  created () {},
+  methods: {
+    extend (chart) {
+      chart.setOption({
+        series: [{
+          type: 'bar',
+          barWidth: 20
+        }, {
+          type: 'line',
+          smooth: false,
+          symbol: 'none'
+        }]
+      })
+    },
+    configArea (options) {
+      const arr = this.getMapDatas.rows || []
+      const maxNum = Math.max.apply(Math, arr.map((o) => { return o['项目数量'] }))
+      options.visualMap.min = 1
+      options.visualMap.max = maxNum < 100 ? 100 : maxNum
+      options.graphic[0].children[0].style.text = '项目数量(个)'
+      options.graphic[options.graphic.length - 1].children[0].style.text = maxNum > 100 ? maxNum : 100
+      options.graphic[options.graphic.length - 1].children[1].style.text = 1
+      options.tooltip.formatter = params => {
+        const obj = {}
+        let tip = ''
+        arr.forEach((v) => {
+          if (v['项目所在地'] === params.name) {
+            for (const key in v) {
+              obj[key] = v[key]
+            }
+          }
+        })
+        if (Object.keys(obj).length > 0) {
+          const regArea = '<span style="color: #999">' + obj['项目所在地'] + '</span></br>'
+          const count = '<span>项目数量:' + obj['项目数量'] + '个</span></br>'
+          const scale = '<span>项目金额:' + obj['项目金额'] + '万元</span></br>'
+          tip = regArea + count + scale
+        } else {
+          tip = ''
+        }
+        return tip
+      }
+      options.series[0].aspectScale = 0.75
+      options.series[0].layoutCenter = ['50%', '50%']
+      options.series[0].zoom = 0.8
+      options.series[0].layoutSize = 400
+      return options
+    }
+  }
+}

+ 237 - 0
src/web/staticres/common-module/report-analysis/js/components/marketSegment.js

@@ -0,0 +1,237 @@
+var marketSegmentTemplate = `
+<ve-histogram
+  :id="id"
+  :height="options.height"
+  :width="options.width ? options.width : null"
+  :colors="options.colors"
+  :data="chartData"
+  :settings="options.settings"
+  :after-config="options.config"
+  :after-set-option="extend"
+  :extend="defaultOptions"
+></ve-histogram>
+`
+
+var marketSegment = {
+  name: 'market-segment',
+  template: marketSegmentTemplate,
+  props: {
+    id: String,
+    type: {
+      type: String,
+      default: 'count' // count/amount
+    },
+    chartData: {
+      type: Object,
+      default () {
+        return {
+          columns: ['行业', '项目金额'],
+          rows: [
+            // {
+            //   行业: '6月2',
+            //   项目金额: 2
+            // },
+            // {
+            //   行业: '6月3',
+            //   项目金额: 3
+            // },
+            // {
+            //   行业: '6月4',
+            //   项目金额: 4
+            // },
+            // {
+            //   行业: '6月4',
+            //   项目金额: 0
+            // },
+            // {
+            //   行业: '6月5',
+            //   项目金额: 5
+            // }
+          ]
+        }
+      }
+    },
+  },
+  data: function () {
+    const color = this.type === 'count' ? '#05A6F3' : '#FF9F3F'
+    return {
+      options: {
+        height: '320px',
+        colors: [color],
+        config: this.config(this.type)
+      },
+      defaultOptions: {
+        grid: {
+          top: 20
+        },
+        xAxis: {
+          axisLabel: {
+            margin: 10,
+            interval: 0, // 强制显示x轴所有刻度
+            fontSize: 10
+          },
+          nameLocation: 'start',
+          nameTextStyle: {
+            fontSize: 12,
+            align: 'left',
+            padding: [70, 0, 0, 50],
+            color: '#9B9CA3'
+          }
+        },
+        yAxis (item) {
+          item[0].splitLine = {
+            lineStyle: {
+              type: 'dashed',
+              width: 0.5
+            }
+          }
+          item[0].axisLabel = {
+            margin: 2,
+            fontSize: 12
+          }
+          item[1].splitLine = {
+            show: false
+          }
+          item[1].axisLabel = {
+            show: false,
+            fontSize: 12
+          }
+          item[0].axisLabel.formatter = (value, index) => {
+            return value.toString().replace(/,/, '')
+          }
+          item[1].axisLabel.formatter = (value, index) => {
+            return value.toString().replace(/,/, '')
+          }
+          return item
+        },
+        tooltip: {
+          trigger: 'axis',
+          confine: true,
+          backgroundColor: '#fff',
+          axisPointer: {
+            type: 'shadow',
+            shadowStyle: {
+              color: 'rgba(42, 190, 209,0.1)'
+            },
+            z: 3
+          },
+          textStyle: {
+            color: '#171826',
+            fontSize: 12
+          },
+          padding: [7, 12],
+          extraCssText: 'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08);transform: translate3d(0,0,0)'
+        },
+        legend: {
+          orient: 'horizontal',
+          icon: 'circle',
+          bottom: 0,
+          align: 'left',
+          itemWidth: 8,
+          itemHeight: 8,
+          itemGap: 20,
+          textStyle: {
+            fontSize: 12,
+            rich: {
+              a: {
+                fontSize: 16,
+                verticalAlign: 'top',
+                align: 'center',
+                padding: [0, 15, 28, 0]
+              },
+              b: {
+                fontSize: 14,
+                align: 'center',
+                padding: [0, 15, 0, 0],
+                lineHeight: 25
+              }
+            }
+          },
+          formatter: (name) => {
+            if (name === '企业数量') {
+              name = name + '(个)'
+            }
+            return name
+          }
+        }
+      }
+    }
+  },
+  computed: {},
+  created () {
+    // console.log(this.chartData)
+  },
+  methods: {
+    extend (chart) {
+      chart.setOption({
+        series: [{
+          type: 'bar',
+          barMaxWidth: 40
+        }, {
+          type: 'line',
+          smooth: false,
+          symbol: 'none'
+        }]
+      })
+    },
+    config (type) {
+      return options => {
+        const suffix = type === 'count' ? '个' : '万元'
+        options.xAxis[0].axisLabel.rotate = 60
+        options.xAxis[0].axisLabel.formatter = name => {
+          if (name && name.length > 4) {
+            return `${name.slice(0, 4)}...`
+          } else {
+            return name
+          }
+        }
+
+        if (this.chartData.rows.length > 8) {
+          // 设置时间轴
+          Object.assign(options, {
+            // grid解决dataZoom文字被隐藏的问题
+            // https://github.com/apache/echarts/issues/11601
+            grid: {
+              left: '5%',
+              right: '13%'
+            },
+            dataZoom: {
+              show: true, // 显示滚动条
+              realtime: true, // 拖动时,是否实时更新系列的视图
+              type: 'slider',
+              height: 20,
+              bottom: 0,
+              textStyle: {
+                fontSize: 10
+              }
+            }
+          })
+        }
+
+        options.legend.bottom = 30
+        options.legend.formatter = name => {
+          return `${name}(${suffix})`
+        }
+
+        options.legend.data = [
+          { icon: 'rect', name: this.chartData.columns[1] }
+        ]
+
+        options.tooltip.axisPointer.shadowStyle.color = 'rgba(5,166,243,0.1)'
+        options.tooltip.formatter = params => {
+          let tip = `<div style="padding-top:2px;color:#9B9CA3;">${params[0].name}</div>`
+          for (let i = 0; i < params.length; i++) {
+            if (params[i].value === undefined) {
+              params[i].value = 0
+            }
+            if (i === 0) {
+              tip = tip + params[i].marker + params[i].seriesName + ':' + params[i].value + suffix + '<br/>'
+            }
+          }
+          return tip
+        }
+        return options
+      }
+    }
+  }
+}

+ 241 - 0
src/web/staticres/common-module/report-analysis/js/components/marketTimeScatter.js

@@ -0,0 +1,241 @@
+var marketTimeScatterTemplate = `
+  <div class="market-time-scatter">
+    <ve-histogram
+      id="bar-line-histogram-chart"
+      :init-options="initRendererSvg"
+      :height="options.height"
+      :width="options.width ? options.width : null"
+      :colors="options.colors"
+      :data="chartData"
+      :settings="options.settings"
+      :after-config="options.config"
+      :after-set-option="extend"
+      :extend="defaultOptions"
+      >
+    </ve-histogram>
+  </div>
+`
+
+
+var marketTimeScatter = {
+  name: 'market-time-scatter',
+  template: marketTimeScatterTemplate,
+  props: {
+    chartData: {
+      type: Object,
+      default () {
+        return {
+          columns: ['日期', '项目规模', '环比增长率(%)'],
+          rows: [
+            // {
+            //   日期: '6月',
+            //   项目规模: 0,
+            //   '环比增长率(%)': -33
+            // },
+            // {
+            //   日期: '7月',
+            //   项目规模: 736325,
+            //   '环比增长率(%)': 0
+            // },
+            // {
+            //   日期: '8月',
+            //   项目规模: 73145,
+            //   '环比增长率(%)': 20
+            // }
+          ]
+        }
+      }
+    },
+    width: String,
+    // 柱状图颜色
+    barChartColor: {
+      type: String,
+      default: '#05A6F3'
+    }
+  },
+  data:function () {
+    return {
+      initRendererSvg: {
+        renderer: 'svg'
+      },
+      options: {
+        height: '320px',
+        width: this.width,
+        colors: [this.barChartColor, '#FF3A20'],
+        settings: {
+          showLine: [this.chartData.columns[2]],
+          axisSite: { right: [this.chartData.columns[2]] }
+        },
+        config: this.newTimeConfig
+      },
+      defaultOptions: {
+        grid: {
+          top: 20
+        },
+        xAxis: {
+          axisLabel: {
+            margin: 10,
+            interval: 0, // 强制显示x轴所有刻度
+            fontSize: 10
+          },
+          nameLocation: 'start',
+          nameTextStyle: {
+            fontSize: 12,
+            align: 'left',
+            padding: [70, 0, 0, 50],
+            color: '#9B9CA3'
+          }
+        },
+        yAxis (item) {
+          item[0].splitLine = {
+            lineStyle: {
+              type: 'dashed',
+              width: 0.5
+            }
+          }
+          item[0].axisLabel = {
+            margin: 2,
+            fontSize: 12
+          }
+          item[1].splitLine = {
+            show: false
+          }
+          item[1].axisLabel = {
+            show: false,
+            fontSize: 12
+          }
+          item[0].axisLabel.formatter = (value, index) => {
+            return value.toString().replace(/,/, '')
+          }
+          item[1].axisLabel.formatter = (value, index) => {
+            return value.toString().replace(/,/, '')
+          }
+          return item
+        },
+        tooltip: {
+          trigger: 'axis',
+          confine: true,
+          backgroundColor: '#fff',
+          axisPointer: {
+            type: 'shadow',
+            shadowStyle: {
+              color: 'rgba(42, 190, 209,0.1)'
+            },
+            z: 3
+          },
+          textStyle: {
+            color: '#171826',
+            fontSize: 12
+          },
+          padding: [7, 12],
+          extraCssText: 'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08);transform: translate3d(0,0,0)'
+        },
+        legend: {
+          orient: 'horizontal',
+          icon: 'circle',
+          bottom: 0,
+          align: 'left',
+          itemWidth: 8,
+          itemHeight: 8,
+          itemGap: 20,
+          textStyle: {
+            fontSize: 12,
+            rich: {
+              a: {
+                fontSize: 16,
+                verticalAlign: 'top',
+                align: 'center',
+                padding: [0, 15, 28, 0]
+              },
+              b: {
+                fontSize: 14,
+                align: 'center',
+                padding: [0, 15, 0, 0],
+                lineHeight: 25
+              }
+            }
+          },
+          formatter: (name) => {
+            if (name === '企业数量') {
+              name = name + '(个)'
+            }
+            return name
+          }
+        }
+      }
+    }
+  },
+  computed: {},
+  created () {},
+  methods: {
+    extend (chart) {
+      chart.setOption({
+        series: [{
+          type: 'bar',
+          barMaxWidth: 40
+        }, {
+          type: 'line',
+          smooth: false,
+          symbol: 'none'
+        }]
+      })
+    },
+    newTimeConfig (options) {
+      options.xAxis[0].axisLabel.rotate = 60
+      options.xAxis[0].axisLabel.interval = 'auto'
+
+      options.yAxis[1].axisLabel.show = true
+
+      if (this.chartData.rows.length > 8) {
+        // 设置时间轴
+        Object.assign(options, {
+          // grid解决dataZoom文字被隐藏的问题
+          // https://github.com/apache/echarts/issues/11601
+          grid: {
+            left: '5%',
+            right: '13%'
+          },
+          dataZoom: {
+            show: true, // 显示滚动条
+            realtime: true, // 拖动时,是否实时更新系列的视图
+            type: 'slider',
+            height: 20,
+            bottom: 0,
+            textStyle: {
+              fontSize: 10
+            }
+          }
+        })
+      }
+
+      options.legend.bottom = 30
+      options.legend.data = [
+        { icon: 'rect', name: this.chartData.columns[1] },
+        { icon: 'line', name: this.chartData.columns[2] }
+      ]
+
+      options.tooltip.axisPointer.shadowStyle.color = 'rgba(5,166,243,0.1)'
+      options.tooltip.formatter = params => {
+        let tip = '' 
+        for (let i = 0; i < params.length; i++) {
+          if (params[i].value === undefined || params[i].value === '') {
+            params[i].value = 0
+          }
+          if (params[i].seriesName.indexOf('环比') === -1) {
+            var match = params[i].seriesName.match(/((.*))$/g)
+            var unit = ''
+            if (Array.isArray(match)) {
+              unit = match.join('').replace(/[()]/g, '')
+            }
+            tip = tip + params[i].marker + params[i].seriesName.replace(`(${unit})`, '') + ':' + params[i].value + unit + '<br/>'
+          } else {
+            tip = tip + params[i].marker + params[i].seriesName + ':' + params[i].value + '%' + '<br/>'
+          }
+        }
+        tip += `<div style="padding-top:2px;color:#9B9CA3;text-align:center">- ${params[0].name} -</div>`
+        return tip
+      }
+      return options
+    }
+  }
+}

+ 105 - 0
src/web/staticres/common-module/report-analysis/js/components/marketTop3Table.js

@@ -0,0 +1,105 @@
+var marketTop3TableTemplate = `
+  <div class="market-top3-table">
+    <div
+      class="project-top-item"
+      v-for="(item, index) in tableData"
+      :key="index">
+      <div class="p-t-i-hd">
+        <div
+          class="p-t-i-hd-l table-index-rect"
+          v-text="index + 1"
+          :class="{
+              red: index === 0,
+              orange: index === 1,
+              'soft-orange': index === 2
+          }"></div>
+        <div class="p-t-i-hd-r">
+          <div class="p-t-i-hd-r-top">
+            <div class="project-name ellipsis" v-text="item.name" :class="{ disabled: !item.id }" @click="toPortrait(item.id, item.type)"></div>
+            <div class="project-actions" v-show="item.children.length" :class="{ 'icon-reverse': item.childrenShow }" @click="changeChildrenShow(item)">
+              <div v-text="item.actionText"></div>
+              <van-icon name="arrow-down"></van-icon>
+            </div>
+          </div>
+          <div class="project-info">
+            <div class="project-tags">
+              <div class="j-tag" :class="{ 'tag-blue': type === 'count', 'tag-orange': type === 'amount' }" v-text="item.subInfo1" v-if="item.subInfo1"></div>
+              <div class="j-tag tag-plain" v-text="item.subInfo2" v-if="item.subInfo2"></div>
+            </div>
+            <div class="project-right"></div>
+          </div>
+        </div>
+      </div>
+      <div
+        class="p-t-i-ft"
+        :class="{ disabled: !child.id }"
+        v-for="(child, i) in item.children"
+        :key="i"
+        @click="toPortrait(child.id, child.type)"
+        v-show="item.childrenShow">
+        <div class="p-t-i-ft-title" v-text="child.name"></div>
+        <div class="p-t-i-ft-bottom">
+          <div class="p-t-i-ft-sub" v-text="child.subInfo1" v-if="child.subInfo1"></div>
+          <div class="p-t-i-ft-sub" v-text="child.subInfo2" v-if="child.subInfo2"></div>
+        </div>
+      </div>
+    </div>
+  </div>
+`
+
+var marketTop3Table = {
+  name: 'market-top3-table',
+  template: marketTop3TableTemplate,
+  props: {
+    type: {
+      type: String,
+      default: 'count' // count/amount
+    },
+    tableData: {
+      type: Array,
+      default () {
+        return [
+          // {
+          //   name: 'xxxx',
+          //   subInfo1: 'xx',
+          //   subInfo2: 'xxx',
+          //   actionText: 'actionText',
+          //   childrenShow: true,
+          //   children: [
+          //     {
+          //       name: 'w1',
+          //       subInfo1: 'xx',
+          //       subInfo2: 'xx',
+          //     },
+          //     {
+          //       name: 'w2',
+          //       subInfo1: 'xx',
+          //       subInfo2: 'xx',
+          //     }
+          //   ]
+          // }
+        ]
+      }
+    },
+  },
+  data:function () {
+    return {}
+  },
+  computed: {},
+  created () {},
+  methods: {
+    toPortrait (id, type) {
+      console.log(...arguments)
+      if (!type || !id) return
+      this.$emit('save')
+      if (type === 'winner') {
+        location.href = `./ent_portrait?eId=${id}`
+      } else if (type === 'buyer') {
+        location.href = `./unit_portrayal?entName=${id}`
+      }
+    },
+    changeChildrenShow (item) {
+      item.childrenShow = !item.childrenShow
+    }
+  }
+}

+ 161 - 0
src/web/staticres/common-module/report-analysis/js/components/marketUserScatter.js

@@ -0,0 +1,161 @@
+var marketUserScatterTemplate = `<div class="rect-tree-map-chart" style="width: 100%;min-height: 400px"></div>`
+
+var marketUserScatter = {
+  name: 'market-user-scatter',
+  template: marketUserScatterTemplate,
+  props: {
+    chartData: {
+      type: Array,
+      default () {
+        return [
+          // {
+          //   name: 'a',
+          //   value: 222,
+          //   amount: '22'
+          // },
+          // {
+          //   name: 'b',
+          //   value: 122,
+          //   amount: '22'
+          // },
+          // {
+          //   name: 'b',
+          //   value: 22,
+          //   amount: '22'
+          // },
+          // {
+          //   name: 'd',
+          //   value: 2,
+          //   amount: '22'
+          // },
+        ]
+      }
+    },
+  },
+  data:function () {
+    return {
+      myChart: null,
+      height: '500px',
+      options: {
+        title: {
+          subtext: '单位:个、万元',
+          left: '0',
+          textStyle: {
+            color: '#000',
+            fontWeight: 'normal'
+          }
+        },
+        tooltip: {
+          formatter: this.tooltipFormatter
+        }
+      },
+      defaultOptions: {
+        legend: {
+          show: true,
+          selectedMode: 'single',
+          data: [],
+          bottom: 0,
+          itemGap: 5
+        },
+        tooltip: {
+          backgroundColor: '#fff',
+          confine: true,
+          textStyle: {
+            color: '#171826',
+            fontSize: 12
+          },
+          padding: [7, 12],
+          extraCssText: 'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08)',
+          borderWidth: 2,
+          borderColor: '#F5F6F7'
+        },
+        series: [
+          {
+            type: 'treemap',
+            width: '100%',
+            // height: '85%',
+            // top: '15%',
+            roam: false, // 是否开启拖拽漫游(移动和缩放)
+            nodeClick: false, // 点击节点后的行为,false无反应
+            breadcrumb: {
+              show: false
+            },
+            label: { // 描述了每个矩形中,文本标签的样式。
+              normal: {
+                show: true,
+                position: ['10%', '40%']
+              }
+            },
+            itemStyle: {
+              normal: {
+                show: true,
+                textStyle: {
+                  color: '#fff',
+                  fontSize: 16
+                },
+                borderWidth: 1,
+                borderColor: '#fff'
+              },
+              emphasis: {
+                label: {
+                  show: true
+                }
+              }
+            },
+            data: [
+              // {
+              //   name: 'xxx',
+              //   value: 122
+              // },
+              // {
+              //   name: 'yyy',
+              //   value: 122
+              // }
+            ]
+          }
+        ]
+      }
+    }
+  },
+  computed: {},
+  mounted () {
+    this.updateChartView()
+  },
+  methods: {
+    updateChartView () {
+      this.myChart = echarts.init(this.$el, 'light', { renderer: 'canvas' })
+      if (!this.myChart) return
+      this.mergeOptions()
+      this.myChart.setOption(this.defaultOptions)
+      window.addEventListener('resize', () => {
+        // this.myChart.resize()
+      })
+    },
+    mergeOptions () {
+      // 设置数据
+      this.defaultOptions.series[0].data = this.chartData
+      // 设置图例?
+      this.defaultOptions.legend.data = this.chartData.map(item => {
+        return item.name
+      })
+
+      _.merge(this.defaultOptions, this.options)
+    },
+    tooltipFormatter (params) {
+      const item = params.data
+      let tip = `<span style="display:inline-block;margin-right:5px;border-radius:8px;width:8px;height:8px;background-color:${params.color};"></span>${params.name}<br />`
+      if (item && item.value) {
+        tip += `<div>项目数量:${item.value}个<div>`
+      }
+      if (item && item.amount) {
+        tip += `<div>项目金额:${item.amount}万元<div>`
+      }
+      return tip
+    }
+  },
+  beforeDestroy () {
+    if (this.myChart) {
+      this.myChart.dispose()
+    }
+  }
+}

+ 198 - 0
src/web/staticres/common-module/report-analysis/js/components/projectScatter.js

@@ -0,0 +1,198 @@
+var projectScatterTemplate = `
+  <div class="project-scatter-chart" v-if="chartData.rows.length">
+    <ve-histogram
+      id="simple-histogram-chart"
+      :init-options="initRendererSvg"
+      :colors="options.colors"
+      :width="options.width"
+      :height="options.height"
+      :data="chartData"
+      :settings="options.settings"
+      :after-config="options.config"
+      :after-set-option="extend"
+      :extend="defaultOptions"
+      >
+    </ve-histogram>
+  </div>
+`
+
+
+var projectScatter = {
+  name: 'project-scatter',
+  template: projectScatterTemplate,
+  props: {
+    chartData: {
+      type: Object,
+      default () {
+        return {
+          columns: ['项目规模', '项目总金额占比', '项目总数占比'],
+          rows: [
+            // {
+            //   项目规模: '≥1亿',
+            //   项目总金额占比: 20,
+            //   项目总数占比: 10
+            // },
+            // {
+            //   项目规模: '1000万-1亿',
+            //   项目总金额占比: 50,
+            //   项目总数占比: 40
+            // },
+            // {
+            //   项目规模: '500万-1000万',
+            //   项目总金额占比: 20,
+            //   项目总数占比: 30
+            // },
+            // {
+            //   项目规模: '100万-500万',
+            //   项目总金额占比: 20,
+            //   项目总数占比: 30
+            // }
+          ]
+        }
+      }
+    },
+  },
+  data:function () {
+    return {
+      initRendererSvg: {
+        renderer: 'svg'
+      },
+      options: {
+        colors: ['#FF9F3F', '#05A5F2'],
+        width: '100%',
+        height: '300px',
+        settings: {}
+      },
+      defaultOptions: {
+        grid: {
+          top: 20
+        },
+        xAxis: {
+          axisLabel: {
+            margin: 10,
+            interval: 0, // 强制显示x轴所有刻度
+            fontSize: 10,
+            formatter: this.xAxisFormatter
+          },
+          nameLocation: 'start',
+          nameTextStyle: {
+            fontSize: 12,
+            align: 'left',
+            padding: [70, 0, 0, 50],
+            color: '#9B9CA3'
+          }
+        },
+        yAxis (item) {
+          Object.assign(item[0], {
+            splitLine: {
+              lineStyle: {
+                type: 'dashed',
+                width: 0.5
+              }
+            },
+            axisLabel: {
+              margin: 2,
+              fontSize: 12,
+              formatter: (value, index) => value.toString().replace(/,/, '') + '%'
+            }
+          })
+
+          Object.assign(item[1], {
+            splitLine: {
+              show: false
+            },
+            axisLabel: {
+              show: false,
+              fontSize: 12,
+              formatter: (value, index) => value.toString().replace(/,/, '')
+            }
+          })
+          return item
+        },
+        tooltip: {
+          trigger: 'axis',
+          confine: true,
+          backgroundColor: '#fff',
+          axisPointer: {
+            type: 'shadow',
+            shadowStyle: {
+              color: 'rgba(42, 190, 209,0.1)'
+            },
+            z: 3
+          },
+          textStyle: {
+            color: '#171826',
+            fontSize: 12
+          },
+          padding: [7, 12],
+          extraCssText: 'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08);transform: translate3d(0,0,0)',
+          formatter: this.tooltipFormatter
+        },
+        legend: {
+          orient: 'horizontal',
+          icon: 'rect',
+          bottom: 20,
+          align: 'left',
+          itemGap: 20,
+          textStyle: {
+            fontSize: 12,
+            rich: {
+              a: {
+                fontSize: 16,
+                verticalAlign: 'top',
+                align: 'center',
+                padding: [0, 15, 28, 0]
+              },
+              b: {
+                fontSize: 14,
+                align: 'center',
+                padding: [0, 15, 0, 0],
+                lineHeight: 25
+              }
+            }
+          },
+          formatter: name => name
+        }
+      }
+    }
+  },
+  computed: {},
+  created () {},
+  methods: {
+    extend (chart) {
+      chart.setOption({
+        series: [
+          {
+            type: 'bar'
+          },
+          {
+            type: 'bar'
+          }
+        ]
+      })
+    },
+    tooltipFormatter (params) {
+      let tip = ''
+      for (let i = 0; i < params.length; i++) {
+        if (params[i].value === undefined || params[i].value === '') {
+          params[i].value = 0
+        }
+        if (i === 0) {
+          tip = tip + params[i].marker + params[i].seriesName + ':' + params[i].value + '%<br/>'
+        } else if (i === 1) {
+          tip = tip + params[i].marker + params[i].seriesName + ':' + params[i].value + '%<br/>'
+        }
+      }
+      tip +=`<div style="padding-top:2px;color:#9B9CA3;text-align:center">- ${params[0].name} -</div>`
+      return tip
+    },
+    xAxisFormatter (params) {
+      var arr = params.split('-')
+      if (arr.length === 2) {
+        return arr.join('\n-')
+      } else {
+        return params
+      }
+    }
+  }
+}

+ 1006 - 0
src/web/staticres/common-module/report-analysis/js/echarts_option.js

@@ -0,0 +1,1006 @@
+// 中国地图配置项
+function completionMapName (name) {
+  return name
+  // const beforeMaps = {
+  //   '新疆': '新疆维吾尔自治区',
+  //   '西藏': '西藏自治区',
+  //   '宁夏': '宁夏回族自治区',
+  //   '广西': '广西壮族自治区',
+  //   '内蒙古': '内蒙古自治区',
+  //   '香港': '香港特别行政区',
+  //   '澳门': '澳门特别行政区',
+  //   '重庆': '重庆市',
+  //   '上海': '上海市',
+  //   '天津': '天津市',
+  //   '北京': '北京市'
+  // }
+  // if (beforeMaps[name]) {
+  //   return beforeMaps[name]
+  // } else {
+  //   return name
+  // }
+}
+
+var mapSettings = {
+    completionMapName: completionMapName,
+    chartSettings:{
+        positionJsonLink: "/jyapp/big-member/js/china-n.json?v=908",
+        beforeRegisterMapOnce (map) {
+            return map
+        },
+        beforeRegisterMap (map) {
+            return map
+        },
+        label:{
+            show:true,
+            fontSize:7
+        },
+        selectedMode:false, // 去掉省份小圆点
+        itemStyle:{
+            normal:{
+                borderColor:'#F06326',
+                areaColor: '#FFFFFF'
+            }
+        },
+        // zoom:0.95, // 缩放比例
+    },
+    chartExtend: {
+        tooltip: {
+            confine: true,
+            backgroundColor:'#fff',
+            axisPointer: {            // 坐标轴指示器,坐标轴触发有效
+                type: 'shadow',        // 默认为直线,可选为:'line' | 'shadow'
+                shadowStyle:{
+                    color:'rgba(5,166,243,0.1)'
+                },
+                z: 3
+            },
+            textStyle:{
+                color:'#171826',
+                fontSize:12
+            },
+            padding:[8,12],
+            extraCssText:'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08)',
+            formatter:function(params,ticket, callback){
+                if(params.data == null){
+                    return params.name+':0'
+                }else{
+                    return params.name+':'+ params.value
+                }
+            }
+        },
+        grid:{
+            height: '280px',
+            containLabel: true
+        },
+        legend:{ // 隐藏图标上方小方块及文字
+            selectedMode: false,
+            textStyle:{
+                color:'transparent'
+            },
+            itemWidth:0,
+            itemHeight:0,
+        },
+        silent:false, // 禁用鼠标点击、滑过事件
+        series: {
+            showLegendSymbol:false,
+            selectedMode:false,
+        },
+        graphic:[
+            {
+                type:'group',
+                bottom: 54,
+                children:[
+                {
+                    type: 'text',
+                    z: 100,
+                    left: 'left',
+                    top: 'middle',
+                    style: {
+                        fill: '#333',
+                        text:'市场分布数量',
+                        font: '10px Microsoft YaHei'
+                    }
+                }]
+            },
+            {
+                type: 'rect',
+                z: 101,
+                left: 0,
+                bottom: 34,
+                shape: {
+                    width: 84,
+                    height: 14
+                },
+                style: {
+                    stroke: '#FB483D',
+                    fill: 'transparent',
+                    lineWidth: 0.5
+                }
+            },
+            rectGroup(0,'#F06326'),
+            rectGroup(14,'#F48A5D'),
+            rectGroup(28,'#FFB366'),
+            rectGroup(42,'#FFCF9F'),
+            rectGroup(56,'#FFE7CF'),
+            rectGroup(70,'#FFF4EB'),
+            {
+                type:'group',
+                width: 84,
+                bottom: 20,
+                children:[
+                {
+                    type: 'text',
+                    z: 100,
+                    left: 'left',
+                    top: 'middle',
+                    style: {
+                        fill: '#333',
+                        text:'100',
+                        font: '10px Microsoft YaHei'
+                    }
+                },
+                {
+                    type: 'text',
+                    z: 100,
+                    left: 'right',
+                    top: 'middle',
+                    style: {
+                        fill: '#333',
+                        text:'0',
+                        font: '10px Microsoft YaHei'
+                    }
+                }]
+            }
+        ],
+        visualMap: {
+            show:false,
+            inRange:{                             //定义 在选中范围中 的视觉元素
+                color: ['#FFF4EB','#FFE7CF', '#FFCF9F','#FFB366','#F48A5D', '#F06326'],
+            },
+            outOfRange:{
+                color: ['#F06326'],
+            },
+        },
+    },
+    chart: null
+}
+// 月报本月项目规模分布
+var mapSettings2 = {
+    completionMapName: completionMapName,
+    chartSettings:{
+        positionJsonLink: "/jyapp/big-member/js/china-n.json?v=908",
+        beforeRegisterMapOnce (map) {
+            return map
+        },
+        beforeRegisterMap (map) {
+            return map
+        },
+        label:{
+            show:true,
+            fontSize:7
+        },
+        selectedMode:false,
+        itemStyle:{
+            normal:{
+                borderColor:'#F06326',
+                areaColor: '#FFFFFF'
+            }
+        },
+    },
+    chartExtend: {
+        tooltip: {
+            confine: true,
+            backgroundColor:'#fff',
+            axisPointer: {
+                type: 'shadow',
+                shadowStyle:{
+                    color:'rgba(5,166,243,0.1)'
+                },
+                z: 3
+            },
+            textStyle:{
+                color:'#171826',
+                fontSize:12
+            },
+            padding:[8,12],
+            extraCssText:'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08)',
+            formatter:function(params,ticket, callback){
+                if(params.data == null){
+                    return params.name + ':0'
+                }else{
+                    return params.name + ':'+ params.value
+                }
+            }
+        },
+        grid:{
+            height: '280px',
+            containLabel: true
+        },
+        legend:{
+            selectedMode: false,
+            textStyle:{
+                color:'transparent'
+            },
+            itemWidth:0,
+            itemHeight:0,
+        },
+        silent:false,
+        series: {
+            showLegendSymbol:false,
+            selectedMode:false,
+        },
+        graphic:[
+            {
+                type:'group',
+                bottom: 54,
+                children:[
+                {
+                    type: 'text',
+                    z: 100,
+                    left: 'left',
+                    top: 'middle',
+                    style: {
+                        fill: '#333',
+                        text:'单位:万元',
+                        font: '10px Microsoft YaHei'
+                    }
+                }]
+            },
+            {
+                type: 'rect',
+                z: 101,
+                left: 0,
+                bottom: 34,
+                shape: {
+                    width: 84,
+                    height: 14
+                },
+                style: {
+                    stroke: '#FB483D',
+                    fill: 'transparent',
+                    lineWidth: 0.5
+                }
+            },
+            rectGroup(0,'#F06326'),
+            rectGroup(14,'#F48A5D'),
+            rectGroup(28,'#FFB366'),
+            rectGroup(42,'#FFCF9F'),
+            rectGroup(56,'#FFE7CF'),
+            rectGroup(70,'#FFF4EB'),
+            {
+                type:'group',
+                width: 84,
+                bottom: 20,
+                children:[
+                {
+                    type: 'text',
+                    z: 100,
+                    left: 'left',
+                    top: 'middle',
+                    style: {
+                        fill: '#333',
+                        text:'100',
+                        font: '10px Microsoft YaHei'
+                    }
+                },
+                {
+                    type: 'text',
+                    z: 100,
+                    left: 'right',
+                    top: 'middle',
+                    style: {
+                        fill: '#333',
+                        text:'0',
+                        font: '10px Microsoft YaHei'
+                    }
+                }]
+            }
+        ],
+        visualMap: {
+            show:false,
+            inRange:{
+                color: ['#FFF4EB','#FFE7CF', '#FFCF9F','#FFB366','#F48A5D', '#F06326'],
+            },
+            outOfRange:{
+                color: ['#F06326'],
+            },
+        },
+    },
+    chart: null
+}
+// 月报本月中标企业注册地分布
+var mapSettings3 = {
+    completionMapName: completionMapName,
+    chartSettings:{
+        positionJsonLink: "/jyapp/big-member/js/china-n.json?v=908",
+        beforeRegisterMapOnce (map) {
+            return map
+        },
+        beforeRegisterMap (map) {
+            return map
+        },
+        label:{
+            show:true,
+            fontSize:7
+        },
+        selectedMode:false,
+        itemStyle:{
+            normal:{
+                borderColor:'#F06326',
+                areaColor: '#FFFFFF'
+            }
+        },
+    },
+    chartExtend: {
+        tooltip: {
+            confine: true,
+            backgroundColor:'#fff',
+            axisPointer: {
+                type: 'shadow',
+                shadowStyle:{
+                    color:'rgba(5,166,243,0.1)'
+                },
+                z: 3
+            },
+            textStyle:{
+                color:'#171826',
+                fontSize:12
+            },
+            padding:[8,12],
+            extraCssText:'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08)',
+            formatter:function(params,ticket, callback){
+                if(params.data == null){
+                    return params.name + ':0'
+                }else{
+                    return params.name + ':'+ params.value
+                }
+            }
+        },
+        grid:{
+            height: '280px',
+            containLabel: true
+        },
+        legend:{
+            selectedMode: false,
+            textStyle:{
+                color:'transparent'
+            },
+            itemWidth:0,
+            itemHeight:0,
+        },
+        silent:false,
+        series: {
+            showLegendSymbol:false,
+            selectedMode:false,
+        },
+        graphic:[
+            {
+                type:'group',
+                bottom: 54,
+                children:[
+                {
+                    type: 'text',
+                    z: 100,
+                    left: 'left',
+                    top: 'middle',
+                    style: {
+                        fill: '#333',
+                        text:'单位:个',
+                        font: '10px Microsoft YaHei'
+                    }
+                }]
+            },
+            {
+                type: 'rect',
+                z: 101,
+                left: 0,
+                bottom: 34,
+                shape: {
+                    width: 84,
+                    height: 14
+                },
+                style: {
+                    stroke: '#FB483D',
+                    fill: 'transparent',
+                    lineWidth: 0.5
+                }
+            },
+            rectGroup(0,'#F06326'),
+            rectGroup(14,'#F48A5D'),
+            rectGroup(28,'#FFB366'),
+            rectGroup(42,'#FFCF9F'),
+            rectGroup(56,'#FFE7CF'),
+            rectGroup(70,'#FFF4EB'),
+            {
+                type:'group',
+                width: 84,
+                bottom: 20,
+                children:[
+                {
+                    type: 'text',
+                    z: 100,
+                    left: 'left',
+                    top: 'middle',
+                    style: {
+                        fill: '#333',
+                        text:'100',
+                        font: '10px Microsoft YaHei'
+                    }
+                },
+                {
+                    type: 'text',
+                    z: 100,
+                    left: 'right',
+                    top: 'middle',
+                    style: {
+                        fill: '#333',
+                        text:'0',
+                        font: '10px Microsoft YaHei'
+                    }
+                }]
+            }
+        ],
+        visualMap: {
+            show:false,
+            inRange:{
+                color: ['#FFF4EB','#FFE7CF', '#FFCF9F','#FFB366','#F48A5D', '#F06326'],
+            },
+            outOfRange:{
+                color: ['#F06326'],
+            },
+        },
+    },
+    chart: null
+}
+// 中国地图例graphic配置函数
+function rectGroup(left,color) {
+    return {
+        type: 'rect',
+        z: 100,
+        left: left,
+        bottom: 34,
+        shape: {
+            width: 14,
+            height: 14
+        },
+        style: {
+            fill: color
+        }
+    }
+}
+//  投标决策分析页面:预算分布、中标金额、折扣率分布三个图表配置项(只配置相同部分,不同部分在页面里单独配置)
+var barChart = {
+    chartSettings: {},
+    chartExtend:{
+        grid:{
+            left:4,
+            x:0,
+            y:20,
+            x2:0,
+            bottom:20
+        },
+        xAxis:{
+            axisLabel:{
+                interval: 0, // 强制显示x轴所有刻度
+                fontSize: 10
+            }
+        },
+        yAxis(item){
+            item[0].splitLine = {
+                lineStyle:{
+                    type: 'dashed',  // y轴背景虚线
+                    width: 0.5
+                }
+            }
+            item[0].axisLabel = {
+                margin:2,
+                fontSize: 10
+            }
+            item[1].splitLine = {
+                show:false
+            }
+            item[1].axisLabel = {
+                show:false,
+                fontSize: 10
+            }
+            return item;
+        },
+        tooltip: {
+            trigger: 'axis',
+            confine: true,
+            backgroundColor:'#fff',
+            axisPointer: {
+                type: 'shadow',
+                shadowStyle: {},
+                z: 3
+            },
+            textStyle:{
+                color:'#171826',
+                fontSize:12
+            },
+            padding:[7,12],
+            extraCssText:'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08);transform: translate3d(0,0,0)',
+            formatter:function(params){
+                //移除重复的数据
+                for (var i = 0; i < params.length; i++) {
+                    for (var j = params.length - 1; j > i; j--) {
+                        if (params[j].data == params[i].data) {
+                            params.splice(j, 1);
+                            break;
+                        }
+                    }
+                }
+                var tip = '';
+                for (var i = 0; i < params.length; i++) {
+                    if( i == 0) {
+                        tip = params[i].value == 0 ? '' : tip + params[i].seriesName + ':' + params[i].value + '个' + '<br/>';
+                    }else if(i == 1){
+                        if (params[i].value != 0 || params[i].value != '0.00') {
+                            if (params[i].seriesName === '平均折扣率') {
+                                tip = tip + params[i].seriesName + ':' + params[i].value + '%' + '<br/>';
+                            } else {
+                                tip = tip + params[i].seriesName + ':' + params[i].value + '万元' + '<br/>';
+                            }
+                        } else {
+                            tip = tip
+                        }
+
+                    }
+                }
+                return tip;
+            }
+        },
+        legend: {
+            show:false,
+            orient: 'horizontal',
+            icon:'circle',
+            bottom:20,
+            align:'left',
+            itemWidth: 8,
+            itemHeight: 8,
+            itemGap:20,
+            textStyle:{
+                fontSize:11,
+                rich:{
+                    a:{
+                        fontSize:16,
+                        verticalAlign:'top',
+                        align:'center',
+                        padding:[0,15,28,0]
+                    },
+                    b:{
+                        fontSize:14,
+                        align:'center',
+                        padding:[0,15,0,0],
+                        lineHeight:25
+                    }
+                }
+            },
+            formatter: function (name) {
+                var wnYuan = ['金额', '项目金额', '项目规划', '项目总预算', '项目总规模']
+                var ge = ['数量', '项目数量']
+                if (wnYuan.indexOf(name) !== -1) {
+                    name += '(万元)'
+                } else if (ge.indexOf(name) !== -1) {
+                    name += '(个)'
+                }
+                return name;
+            },
+        },
+        series: {
+            barWidth: 20,
+            smooth:false,
+            symbol:'none',
+            lineStyle: {
+                width: 0,
+                color: 'rgba(0, 0, 0, 0)' // 线的颜色是透明的
+            },
+        },
+
+    },
+}
+
+// 平均折扣率配置
+var multiBarChart = {
+    chartSettings: {
+        showLine: ['平均折扣率'],
+    },
+    chartExtend:{
+        grid:{
+            x:12,
+            y:20,
+            x2:12,
+        },
+        yAxis: {
+            splitLine: {
+                show: true,
+                lineStyle: {
+                    type: 'dashed',  // y轴背景虚线
+                    width: 0.5
+                }
+            },
+            axisLabel:{
+                fontSize:10
+            },
+        },
+        xAxis: {
+            axisLabel:{
+                fontSize:10
+            }
+        },
+        tooltip: {
+            trigger: 'axis',
+            confine: true,
+            backgroundColor:'#fff',
+            axisPointer: {
+                type: 'shadow',
+                shadowStyle:{
+                    color:'rgba(5,166,243,0.1)'
+                }
+            },
+            textStyle:{
+                color:'#171826',
+                fontSize:12
+            },
+            padding: [8,12],
+            extraCssText:'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08)',
+            formatter: function(params){
+                var tip = '';
+                for (var i = 0; i < params.length; i++) {
+                    if( i< 4) {
+                        tip = tip + params[i].marker + params[i].seriesName + ':' + params[i].value + '<br/>';
+                    }else {
+                        tip = tip + params[i].marker + params[i].seriesName + ':' + params[i].value + '%' + '<br/>';
+                    }
+                }
+                tip += '<div style="padding-top:2px;text-align:center;color:#9B9CA3;">' + ' - ' + params[0].name.substring(0,params[0].name.lastIndexOf('年')) + ' - ' + '</div>'
+                return tip;
+            },
+        },
+        legend: {
+            orient: 'horizontal',
+            bottom:20,
+            icon:'circle',
+            itemWidth: 8,
+            itemHeight: 8,
+            padding:[0,6],
+            data:['日期', '0~5%', '5~10%','10~30%','30~100%','平均折扣率'],
+            textStyle:{
+                fontSize:11
+            }
+        },
+        series: {
+            smooth:false,
+        },
+        color:['#05A6F3','#0BD991','#FF9F40','#8E6DF2','#F1D090']
+    },
+}
+
+var mBarChart = {
+    dataEmpty: true,
+    chartSettings: {},
+    chartExtend:{
+        grid:{
+            x:14,
+            y:20,
+            x2:14
+        },
+        tooltip: {
+            trigger: 'axis',
+            confine: true,
+            backgroundColor:'#fff',
+            axisPointer: {
+                type: 'shadow',
+                shadowStyle:{
+                    color:'rgba(5,166,243,0.1)'
+                }
+            },
+            textStyle:{
+                color:'#171826',
+                fontSize:12
+            },
+            padding:[8,12],
+            extraCssText:'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08)',
+            z: 3
+        },
+        legend: {
+            orient: 'horizontal',
+            icon:'circle',
+            bottom:10,
+            left: 'center',
+            itemWidth: 8,
+            itemHeight: 8,
+            itemGap:10,
+            textStyle:{
+                fontSize:11
+            }
+        },
+        yAxis: {
+            splitLine: {
+                show: true,
+                lineStyle: {
+                    type: 'dashed',
+                    width: 0.5,
+                    color:'rgba(0, 0, 0, 0.08)'
+                }
+            },
+            axisLabel:{
+                fontSize:10
+            },
+        },
+        xAxis: {
+            axisLabel:{
+                fontSize:10
+            }
+        },
+        series: {
+            barWidth: 20,
+            type:'bar'
+        },
+        color:['#9C72F4','#6B78E8','#05A6F3','#2ABED1','#0BD991','#C0C4CC','#B8D4F9','#444A7A','#F1D090','#B8D4F9','#C09BFC','#104EA3','#21CED2','#FFB901','#7BBFE5','#82E9D6','#62B8FF','#7E56EE','#B3E3E7','#8591FF','#96C3D8','#3774E8','#CDCEFE','#6BBEF4','#6E55B4','#2B82FE','#FF9A01','#01C290','#BAE1A8','#EB97D8']
+    },
+}
+
+
+// 月报 (本月项目规模)
+var barChart2 = {
+    chartExtend:{
+        grid:{
+            left:4,
+            x:0,
+            y:20,
+            x2:12,
+        },
+        xAxis: {
+            axisLabel:{
+                fontSize:10
+            }
+        },
+        yAxis(item){
+            var maxCountList = vNode.data.curMonthScaleData.rows.map(v =>{
+                return v['项目规模']
+            })
+            var maxPriceList = vNode.data.curMonthScaleData.rows.map(v =>{
+                return v['环比增长率(%)-右纵轴']
+            })
+            var maxCount = Math.ceil(Math.max.apply(null,maxCountList)).toString();
+            var maxPrice = Math.ceil(Math.max.apply(null,maxPriceList)).toString();
+            var minRight = Math.ceil(Math.min.apply(null,maxPriceList)).toString();
+            maxCount = Math.ceil(maxCount / (Math.pow(10,maxCount.length -1))) * Math.pow(10,maxCount.length -1);
+            maxPrice = Math.ceil(maxPrice / (Math.pow(10,maxPrice.length -1))) * Math.pow(10,maxPrice.length -1);
+            if(minRight.indexOf('-') > -1) {
+                minRight = '-'  + Math.ceil(minRight.replace('-','') / (Math.pow(10,minRight.replace('-','').length -1))) * Math.pow(10,minRight.replace('-','').length -1)
+            } else {
+                minRight = 0;
+            }
+            item[0].min = 0;
+            item[1].min = minRight;
+            item[0].max = maxCount;
+            item[0].interval = Math.ceil(maxCount / 5);
+            item[1].max = maxPrice;
+            item[1].interval = Math.ceil((maxPrice - minRight) / 5);
+            item[0].splitLine = {
+                lineStyle:{
+                    type: 'dashed',
+                    width: 0.5
+                }
+            }
+            item[1].splitLine = {
+                show:false,
+                lineStyle:{
+                    type: 'dashed',
+                    width: 0.5
+                }
+            },
+            item[1].axisLabel = {
+                show: true,
+                fontSize: 10
+            },
+            item[0].axisLabel = {
+                margin:2,
+                fontSize: 10,
+                formatter: function(value, index){
+                    return value.toString().replace(/,/,'');
+                }
+            }
+            return item;
+        },
+        tooltip: {
+            trigger: 'axis',
+            confine: true,
+            backgroundColor:'#fff',
+            axisPointer: {
+                type: 'shadow',
+                shadowStyle:{
+                    color:'rgba(5,166,243,0.1)'
+                }
+            },
+            textStyle:{
+                color:'#171826',
+                fontSize:12
+            },
+            padding:[7,12],
+            extraCssText:'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08)',
+            formatter:function(params){
+                return formatterTip(params)
+            }
+        },
+        legend: {
+            show: true,
+            orient: 'horizontal',
+            icon:'circle',
+            bottom:20,
+            align:'left',
+            itemWidth: 8,
+            itemHeight: 8,
+            itemGap:20,
+            textStyle:{
+                fontSize:11,
+                rich:{
+                    a:{
+                        fontSize:16,
+                        verticalAlign:'top',
+                        align:'center',
+                        padding:[0,15,28,0]
+                    },
+                    b:{
+                        fontSize:14,
+                        align:'center',
+                        padding:[0,15,0,0],
+                        lineHeight:25
+                    }
+                }
+            },
+            formatter: function (name) {
+                if(name == '项目规模') {
+                    name = name + '(万元)'
+                }
+                return name;
+            },
+            data:["项目规模","环比增长率(%)-右纵轴"],
+        },
+        series: {
+            barWidth: 20,
+            smooth:false,
+        },
+        color:['#05A6F3', '#FF9F40']
+    },
+}
+// 月报 (本月中标企业中标项目数量分布)
+var barChart3 = {
+    chartExtend:{
+        grid:{
+            x:8,
+            y:20,
+            x2:12,
+        },
+        xAxis: {
+            axisLabel: {
+                fontSize: 10,
+                formatter: function (val) {
+                    return val + '个';
+                }
+            }
+        },
+        yAxis(item){
+            var maxCountList = vNode.data.curWinEntCountData.rows.map(v =>{
+                return v['企业数量']
+            })
+            var maxPriceList = vNode.data.curWinEntCountData.rows.map(v =>{
+                return v['累计占比(%)-右纵轴']
+            })
+            var maxCount = Math.ceil(Math.max.apply(null,maxCountList)).toString();
+            var maxPrice = Math.ceil(Math.max.apply(null,maxPriceList)).toString();
+            maxCount = Math.ceil(maxCount / (Math.pow(10,maxCount.length -1))) * Math.pow(10,maxCount.length -1);
+            maxPrice = Math.ceil(maxPrice / (Math.pow(10,maxPrice.length -1))) * Math.pow(10,maxPrice.length -1);
+            item[0].min = 0;
+            item[1].min = 0;
+            item[0].max = maxCount;
+            item[0].interval = Math.ceil(maxCount / 5);
+            item[1].max = maxPrice;
+            item[1].interval = Math.ceil((maxPrice - 0) / 5);
+            item[0].splitLine = {
+                lineStyle:{
+                    type: 'dashed',
+                    width: 0.5
+                }
+            }
+            item[1].splitLine = {
+                show:false,
+                lineStyle:{
+                    type: 'dashed',
+                    width: 0.5
+                }
+            },
+            item[1].axisLabel = {
+                show: true,
+                fontSize: 10
+            },
+            item[0].axisLabel = {
+                margin:2,
+                fontSize: 10,
+                formatter: function(value, index){
+                    return value.toString().replace(/,/,'');
+                }
+            }
+            return item;
+        },
+        tooltip: {
+            trigger: 'axis',
+            confine: true,
+            backgroundColor:'#fff',
+            axisPointer: {
+                type: 'shadow',
+                shadowStyle:{
+                    color:'rgba(5,166,243,0.1)'
+                }
+            },
+            textStyle:{
+                color:'#171826',
+                fontSize:12
+            },
+            padding:[7,12],
+            extraCssText:'box-shadow: 0px 4px 16px rgba(8, 31, 38, 0.08)',
+            formatter:function(params){
+                return formatterTip(params)
+            }
+        },
+        legend: {
+            show: true,
+            orient: 'horizontal',
+            icon:'circle',
+            bottom:20,
+            align:'left',
+            itemWidth: 8,
+            itemHeight: 8,
+            itemGap:20,
+            textStyle:{
+                fontSize:11,
+                rich:{
+                    a:{
+                        fontSize:16,
+                        verticalAlign:'top',
+                        align:'center',
+                        padding:[0,15,28,0]
+                    },
+                    b:{
+                        fontSize:14,
+                        align:'center',
+                        padding:[0,15,0,0],
+                        lineHeight:25
+                    }
+                }
+            },
+            formatter: function (name) {
+                if(name == '企业数量') {
+                    name = name + '(个)'
+                }
+                return name;
+            },
+            data:["企业数量","累计占比(%)-右纵轴"],
+        },
+        series: {
+            barWidth: 20,
+            smooth:false
+        },
+        color:['#05A6F3', '#FF9F40']
+    },
+}
+// 修改tooltip展示效果函数
+function formatterTip(params) {
+    var tip = '';
+    for (var i = 0; i < params.length; i++) {//这里是自己定义样式, params[i].marker 表示是否显示左边的那个小圆圈
+        params[i].value == undefined ? params[i].value = 0 : params[i].value;
+        params[i].marker = '<span style="display:inline-block;margin-right:5px;border-radius:8px;width:8px;height:8px;background-color:' +  params[i].color + '"></span>';
+        if( params[i].seriesName === '项目数量' || params[i].seriesName === '企业数量') {
+            tip = tip + params[i].marker + params[i].seriesName + ':' + params[i].value + '个' + '<br/>';
+        }else if(params[i].seriesName === '环比增长率(%)-右纵轴' || params[i].seriesName === '累计占比(%)-右纵轴'){
+            tip = tip + params[i].marker + params[i].seriesName + ':' + params[i].value + '%' + '<br/>';
+        } else {
+            tip = tip + params[i].marker + params[i].seriesName + ':' + params[i].value + '万元' + '<br/>';
+        }
+    }
+    tip += '<div style="padding-top:2px;text-align:center;color:#9B9CA3;">' + ' - ' + params[0].name + ' - ' + '</div>'
+    return tip;
+}

+ 1817 - 0
src/web/staticres/common-module/report-analysis/js/report_analysis.js

@@ -0,0 +1,1817 @@
+function dateFormatter (date, pattern) {
+  return new Date(date).pattern(pattern)
+}
+var vm = new Vue({
+  delimiters: ['${', '}'],
+  el: '#analysis',
+  components: {
+    keywordComponent: keywordComponent,
+    areaCityMobile: areaCityMobileComponent,
+    industryComponent: industryComponent,
+    cateComponent: cateComponent,
+    dateComponent: dateComponent,
+    chartExample: chartExample,
+    // 图表
+    projectScatter: projectScatter,
+    marketTimeScatter: marketTimeScatter,
+    marketAreaScatter: marketAreaScatter,
+    marketTop3Table: marketTop3Table,
+    marketUserScatter: marketUserScatter,
+    marketSegment: marketSegment,
+    lineChartScatter: lineChartScatter,
+  },
+  data: {
+    sessStorageKey: '$data-report_analysis',
+    tabActiveName: 'analysis', // analysis/history
+    tabList: [
+      {
+        label: '定制化市场分析',
+        name: 'analysis'
+      },
+      {
+        label: '历史报告',
+        name: 'history'
+      }
+    ],
+    tabConf: {
+      titleActiveColor: '#2ABED1',
+      titleInactiveColor: '#5F5E64',
+      lineWidth: '24',
+      color: '#2ABED1'
+    },
+    timeOptions: [
+      {
+        name: '近3个月',
+        value: 'lately90',
+        selected: false
+      },
+      {
+        name: '近半年',
+        value: 'lately180',
+        selected: false
+      },
+      {
+        name: '今年全年',
+        value: 'thisYear',
+        selected: false
+      },
+      {
+        name: '去年至今',
+        value: 'sinceLastYear',
+        selected: false
+      },
+      {
+        name: '前年至今',
+        value: 'sinceYearBeforeLast',
+        selected: false
+      }
+    ],
+    scrollTop: 0,
+    filtersPageShow: true,
+    filters: {
+      selectKeysArr: [], // 关键词简单数组,用于恢复选择状态
+      keys: [], // 关键词详细数组,用于提交数据
+      area: {},
+      industry: [],
+      industryDetail: {},
+      buyerclass: [],
+      rangeTime: {
+        start: '',
+        end: '',
+        exact: 'sinceYearBeforeLast',
+      },
+    },
+    filterDialogShow: {
+      keys: false,
+      area: false,
+      industry: false,
+      buyerclass: false,
+      rangeTime: false
+    },
+    // 分析结果页面数据
+    activeDimension: 'market',
+    dimensionList: [
+      {
+        id: 'market',
+        name: '市场规模',
+        top: 0,
+        anchor: 'market-overview'
+      },
+      {
+        id: 'buyer',
+        name: '采购单位',
+        top: 0,
+        anchor: 'buyerclass-scatter'
+      },
+      {
+        id: 'bidder',
+        name: '中标单位',
+        top: 0,
+        anchor: 'winner-scatter'
+      },
+    ],
+    analysis: { // 开始分析请求的loaed和loading
+      loaded: false,
+      loading: false
+    },
+    rid: '', // reportId
+    reportFilters: {
+      keys: [],
+      selectTime: '',
+      selectTimeExtra: '',
+      area: {},
+      industry: {},
+      buyerclass: []
+    },
+    sections: {
+      market: {
+        overview: [],
+        refine: {
+          dataAlready: false,
+          projectCountData: null,
+          projectAmountData: null,
+          // 项目数量Top3
+          projectCountTop3: null,
+          // 项目金额Top3
+          projectAmountTop3: null
+        }
+      },
+      projectScatter: {
+        dataAlready: false,
+        chartData: null,
+        tableData: [
+          // {
+          //   projectname: 'xxxx',
+          //   area: 'xx',
+          //   city: 'xxx',
+          //   sortprice: 'zzz',
+          //   jgtime: 'zzzz',
+          //   winner_s: [
+          //     {
+          //       name: 'w1',
+          //       id: '33'
+          //     },
+          //     {
+          //       name: 'w2',
+          //       id: '33'
+          //     }
+          //   ]
+          // },
+          // {
+          //   projectname: 'xxxx',
+          //   area: 'xx',
+          //   city: 'xxx',
+          //   sortprice: 'zzz',
+          //   jgtime: 'zzzz',
+          //   winner_s: [
+          //     {
+          //       name: 'w1',
+          //       id: '33'
+          //     },
+          //     {
+          //       name: 'w2',
+          //       id: '33'
+          //     }
+          //   ]
+          // }
+        ]
+      },
+      timeScatter: {
+        dataAlready: false, // 数据准备好之后才能开始渲染
+        activeAction: 'month',
+        actionList: [
+          {
+            label: '月度数据',
+            value: 'month'
+          },
+          {
+            label: '年度数据',
+            value: 'year'
+          }
+        ],
+        month: {
+          count: {},
+          amount: {}
+        },
+        year: {
+          count: {},
+          amount: {}
+        }
+      },
+      areaScatter: {
+        dataAlready: false,
+        chartData: null,
+        // 项目数量Top3
+        projectCountTop3: null,
+        // 项目金额Top3
+        projectAmountTop3: null
+      },
+      userScatter: {
+        list: [],
+        // 项目数量Top3
+        projectCountTop3: null,
+        // 项目金额Top3
+        projectAmountTop3: null
+      },
+      buyerclass: {
+        dataAlready: false,
+        chartData: null,
+        // 项目数量Top3
+        projectCountTop3: null,
+        // 项目金额Top3
+        projectAmountTop3: null
+      },
+      winner: {
+        dataAlready: false,
+        chartData: null,
+        // 项目数量Top3
+        projectCountTop3: null,
+        // 项目金额Top3
+        projectAmountTop3: null
+      }
+    },
+    empty: {
+      defaultMsg: '对不起,没有匹配到相关信息<br />请修改您的分析条件',
+      msg: ''
+    },
+    stickyOffset: 0,
+    notSetKey: false, // 未设置关键词
+    isSubCount: false, // 是否子账号
+    powerInfo: {}
+  },
+  computed: {
+    getStatus: function () {
+      if (JSON.stringify(this.powerInfo) !== '{}') {
+        return this.powerInfo.power.indexOf(10) !== -1
+      }
+    },
+    anchorTopList: function () {
+      var arr = []
+      this.dimensionList.forEach(function (item) {
+        arr.push(item.top)
+      })
+      return arr
+    },
+    // 报告详情筛选条件只有一个省份
+    // 此时不显示地区分布chart
+    notOneAreaFilter () {
+      var area = this.reportFilters.area
+      var showArea = area && (Object.keys(area).length > 1 || Object.keys(area).length === 0)
+      return showArea
+    },
+    emptyShow () {
+      return !this.rid && this.analysis.loaded
+    },
+    tabActive: function () {
+      var _this = this
+      var active = {}
+      this.tabList.some(function (item) {
+        var findThis = item.name === _this.tabActiveName
+        if (findThis)  {
+          active = item
+          return findThis
+        }
+      })
+      return active
+    },
+    buyerclassSectionShow () {
+      const winnerState = this.sections.buyerclass
+      return winnerState.dataAlready && winnerState.projectCountTop3 && winnerState.projectAmountTop3
+    },
+    winnerSectionShow () {
+      const winnerState = this.sections.winner
+      return winnerState.dataAlready && winnerState.projectCountTop3 && winnerState.projectAmountTop3
+    },
+    overviewRateTotal: function () {
+      var total = 0
+      this.sections.market.overview.forEach(function (item) {
+        if (item.ringRatio !== undefined && item.ringRatio !== null) {
+          total += item.ringRatio
+        }
+      })
+      return total
+    }
+  },
+  watch: {
+    filtersPageShow (newVal) {
+      if (!newVal) {
+        var isWeixin = utils.isWeiXinBrowser
+        if (!isWeixin) {
+          this.calcStickyOffset()
+        }
+      }
+    }
+  },
+  created () {
+    this.calcLastTimeText()
+    this.getPower()
+    var id = utils.getParam('id')
+    if (id) {
+      this.rid = decodeURIComponent(id)
+      this.filtersPageShow = false
+    }
+  },
+  mounted: function () {
+    setTimeout(() => {
+      var restored = this.reStoreState()
+      if (!restored) {
+        if (this.rid) {
+          this.getReportResult()
+        }
+      } else {
+        this.$nextTick(this.calcOffsetTop)
+        if (utils.isIos) {
+          setTimeout(this.calcOffsetTop, 1000)
+        }
+      }
+    }, 0)
+    this.addEventListeners()
+    utils.iosBackRefresh()
+  },
+  methods: {
+    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)
+    },
+    calcOffsetTop: function () {
+      var sticky = $('.van-sticky')
+      var stickyHeight = 0
+      if (sticky.length) {
+        stickyHeight = sticky[0].clientHeight
+      }
+      this.dimensionList.forEach(function (item) {
+        var anchor = $('.' + item.anchor)
+        var offsetTop = 0
+        if (anchor.length) {
+          offsetTop = parseInt(anchor[0].offsetTop - stickyHeight)
+        }
+        item.top = offsetTop
+      })
+    },
+    addEventListeners: function () {
+      this.scrollToTop()
+    },
+    scrollToTop: function () {
+      var $scrollDOM = $('.j-container.search-result > .j-main')
+      // 1. 检查当前高度是否满足显示快速滚动到顶部
+      this.checkScrollTopButtonShow()
+      // 2. 具体逻辑
+      $scrollDOM.on('scroll', this.checkScrollTopButtonShow)
+      setTimeout(function () {
+        // 2s后绑定(尽可能保证top能够被计算完)
+        $scrollDOM.on('scroll', this.checkAnchorItemActive)
+      }.bind(this), 2000)
+
+      $('.scroll-to-top').on('click', function () {
+        $scrollDOM.animate({ scrollTop: 0 })
+      })
+    },
+    checkAnchorItemActive: function () {
+      var $scrollDOM = $('.j-container.search-result > .j-main')
+      var anchorTopList = this.anchorTopList
+      var scrollTop = parseInt($scrollDOM.scrollTop()) + 3 // (误差校正)
+      var i = 0
+      if (scrollTop >= anchorTopList[1] && scrollTop < anchorTopList[2]) {
+        i = 1
+      } else if (scrollTop > anchorTopList[2]) {
+        i = 2
+      } else if (scrollTop < anchorTopList[1]) {
+        i = 0
+      }
+      this.activeDimension = this.dimensionList[i].id
+    },
+    checkScrollTopButtonShow: function () {
+      var showButtonHeight = 300
+      var $scrollDOM = $('.j-container.search-result > .j-main')
+      var button = $('.scroll-to-top')
+      var scrollTop = $scrollDOM.scrollTop()
+      if (scrollTop > showButtonHeight) {
+        button.show()
+      } else {
+        button.hide()
+      }
+    },
+    calcStickyOffset: function () {
+      setTimeout(function () {
+        var headerHeight = $('.jy-app-header')[0].clientHeight
+        var tabHeight = $('.analysis-tab')[0].clientHeight
+        this.stickyOffset = headerHeight + tabHeight - 5
+      }.bind(this), 1000)
+    },
+    setScrollTop: function (scrollTop) {
+      this.$nextTick(function () {
+        var wrapper = document.querySelector('.j-container.search-result > .j-main')
+        wrapper.scrollTop = scrollTop
+      })
+    },
+    saveScrollTop: function () {
+      var wrapper = document.querySelector('.j-container.search-result > .j-main')
+      if (wrapper.scrollTop) {
+        this.scrollTop = parseInt(wrapper.scrollTop)
+      }
+    },
+    beforeTabChange: function (name) {
+      if (name !== this.tabActiveName) {
+        this.goToAnalysisHistory()
+      }
+      return false
+    },
+    goToAnalysisHistory: function () {
+      location.href = './report_analysis_history'
+    },
+    formatSelectTime (value) {
+      if (!value) return '-'
+      const timeArr = value.split('-')
+      return `${dateFormatter(timeArr[0] * 1000, 'yyyy/MM/dd')}-${dateFormatter(timeArr[1] * 1000, 'yyyy/MM/dd')}`
+    },
+    getPower:function () {
+      var _this = this
+      $.ajax({
+        type:'POST',
+        url:'/bigmember/use/isAdd',
+        success:function(res) {
+          _this.powerInfo = res.data
+          if (res.data && res.data.isSubCount){
+            _this.isSubCount = true
+          }
+        }
+      })
+    },
+    init: function () {
+      // 初始化页面数据
+      this.initDateTimeSelector('sinceYearBeforeLast')
+    },
+    // 时间选择器选中状态
+    initDateTimeSelector: function (exact) {
+      if (exact === 'exact') {
+        this.$refs.dateSelector.setState(this.filters.rangeTime)
+      } else {
+        this.$refs.dateSelector.setTimeSelectListState(exact)
+        this.$refs.dateSelector.dateStyle = false
+      }
+    },
+    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)
+      }
+      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(',')
+    },
+    calcLastTimeText: function () {
+      const renameList = [
+        'thisYear', // 今年全年
+        'sinceLastYear', // 去年至今
+        'sinceYearBeforeLast' // 前年至今
+      ]
+      const thisYear = new Date().getFullYear()
+      this.timeOptions.forEach(item => {
+        if (renameList.indexOf(item.value) !== -1) {
+          if (item.value === renameList[0]) {
+            item.name = `${thisYear}年全年`
+          } else if (item.value === renameList[1]) {
+            item.name = `${thisYear - 1}年至今`
+          } else if (item.value === renameList[2]) {
+            item.name = `${thisYear - 2}年至今`
+          }
+        }
+      })
+    },
+    // 重置
+    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 === 'date') {
+        this.filters.rangeTime.start = ''
+        this.filters.rangeTime.edd = ''
+        this.filters.rangeTime.exact = 'sinceYearBeforeLast'
+        this.initDateTimeSelector(this.filters.rangeTime.exact)
+      } else {
+        this.resetFilter('keys')
+        this.resetFilter('area')
+        this.resetFilter('industry')
+        this.resetFilter('buyerclass')
+        this.resetFilter('date')
+      }
+    },
+    clickCell: function (key) {
+      var _this = this
+      var dialog = this.filterDialogShow
+      if (key === 'keys') {
+        if (this.notSetKey) {
+          return this.setKeyTip()
+        }
+      } else if (key === 'area') {
+        setTimeout(function () {
+          _this.$refs.areaCitySelector.setState(_this.filters.area)
+        }, 0)
+      } else if (key === 'buyerclass') {
+        setTimeout(function () {
+          _this.$refs.buyerclassSelector.setState()
+        }, 0)
+      }  else if (key === 'industry') {
+        setTimeout(function () {
+          _this.$refs.industrySelector.setState()
+        }, 0)
+      }
+      dialog[key] = true
+    },
+    cancel: function (e, key) {
+      var dialog = this.filterDialogShow
+      this.resetFilter(key)
+      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
+      } 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)
+      } 
+      dialog[key] = false
+    },
+    dateTimeSelectorConfirm () {
+      var result = this.$refs.dateSelector.getState()
+      this.filters.rangeTime.start = result.start
+      this.filters.rangeTime.end = result.end
+      this.filters.rangeTime.exact = result.exact
+    },
+    resetAllFilters: function () {
+      this.analysis.loaded = false
+      this.resetFilter('all')
+    },
+    getReportResult () {
+      this.sendRequest()
+    },
+    getSelectedKeys () {
+      const keys = this.filters.keys
+      if (Array.isArray(keys) && keys.length) {
+        return JSON.stringify(keys)
+      } else {
+        var allKeys = this.$refs.keywordSelector.keywordGroupList
+        return JSON.stringify(allKeys)
+      }
+    },
+    startAnalysis: function () {
+      this.dateTimeSelectorConfirm()
+
+      const query = {
+        keysItems: this.getSelectedKeys(),
+        rangeTime: `${parseInt(this.filters.rangeTime.start / 1000)}-${parseInt(this.filters.rangeTime.end / 1000)}`,
+        rangeTimeExtra: this.filters.rangeTime.exact,
+        area: JSON.stringify(this.filters.area),
+        industry: JSON.stringify(this.filters.industryDetail),
+        buyerclass: this.filters.buyerclass.join(',')
+      }
+
+      this.analysis.loaded = false
+      this.analysis.loading = true
+      this.showLoading()
+
+      $.ajax({
+        type: 'POST',
+        url: '/bigmember/marketAnalysis/doAnalysis',
+        data: query,
+        success: function (res) {
+          if (res && res.error_code === 0 && res.data) {
+            this.rid = res.data
+            this.analysis.loaded = true
+            // location.replace('./report_analysis?id=' + res.data)
+            this.rid = res.data
+            history.replaceState({}, null, '?id=' + this.rid)
+            this.getReportResult()
+          } else {
+            this.$toast(res.error_msg)
+          }
+        }.bind(this),
+        complete: function () {
+          this.analysis.loading = false
+        }.bind(this)
+      })
+    },
+    // 保存页面状态
+    saveState: function () {
+      this.saveScrollTop()
+      this.dateTimeSelectorConfirm()
+      var $data = {
+        analysis: this.analysis,
+        filters: this.filters,
+        scrollTop: this.scrollTop,
+        filtersPageShow: this.filtersPageShow,
+        reportFilters: this.reportFilters,
+        sections: this.sections,
+        isSubCount: this.isSubCount
+      }
+      sessionStorage.setItem(this.sessStorageKey, JSON.stringify($data))
+    },
+    reStoreState: function () {
+      var $data = sessionStorage.getItem(this.sessStorageKey)
+      if ($data) {
+        $data = JSON.parse($data)
+
+        this.isSubCount = $data.isSubCount
+        this.scrollTop = $data.scrollTop
+        this.filtersPageShow = $data.filtersPageShow
+        Object.assign(this.analysis, $data.analysis)
+        this.$set(this, 'filters', $data.filters)
+        this.$set(this, 'reportFilters', $data.reportFilters)
+        this.$set(this, 'sections', $data.sections)
+
+        setTimeout(function () {
+          // 恢复滚动高度
+          this.setScrollTop(this.scrollTop)
+          this.initDateTimeSelector(this.filters.rangeTime.exact)
+        }.bind(this), 0)
+
+        sessionStorage.removeItem(this.sessStorageKey)
+      } else {
+        this.init()
+      }
+
+      return $data
+    },
+    onEmpty (info) {
+      if (this.loading) {
+        this.loading.clear()
+      }
+      this.filtersPageShow = true
+      this.analysis.loaded = true
+      this.rid = ''
+      if (info && info.msg) {
+        this.empty.msg = info.msg
+      } else {
+        this.empty.msg = this.empty.defaultMsg
+      }
+    },
+    sendRequest () {
+      let _this = this
+      // 先请求概况(1),判断报告是否为空
+      const query = {
+        rid: this.rid,
+        flag: 1
+      }
+      if (!query.rid) {
+        return
+      }
+      this.loading = this.showLoading()
+      $.ajax({
+        type: 'POST',
+        async: false,
+        url: '/bigmember/marketAnalysis/getAnalysisResult',
+        data: query,
+        success: function(res) {
+          if (res && res.error_code === 0 && res.data) {
+            var empty = _this.formatterData(query.flag, res.data)
+            if (empty) {
+              return _this.onEmpty()
+            }
+          } else {
+            if (res.error_msg.indexOf('项目数量超出上限') === -1) {
+              return _this.onEmpty()
+            } else {
+              return _this.onEmpty({ msg: '当前分析条件涉及项目数量已超过最大限制,请修改分析条件进行精确分析' })
+            }
+          }
+        }
+      }).responseJSON
+
+
+      this.filtersPageShow = false
+
+      const flagArr = [
+        0, // 筛选条件
+        // 1, // 市场概括与时间分布
+        2, // 项目规模Top10
+        3, // 项目规模分布/地区规模分布/客户分布/地区分布及客户分布&Top3(table+chart)
+        4, // 细分市场
+        5 // 采购单位/中标单位&Top3(table+chart)
+      ]
+
+      flagArr.forEach(this.getReport)
+
+      if (this.loading) {
+        this.loading.clear()
+      }
+    },
+    getReport (flag) {
+      const query = {
+        rid: this.rid,
+        flag
+      }
+      if (!query.rid) {
+        return
+      }
+      
+      $.ajax({
+        type: 'POST',
+        url: '/bigmember/marketAnalysis/getAnalysisResult',
+        data: query,
+        success: function (res) {
+          if (res && res.error_code === 0 && res.data) {
+            this.formatterData(flag, res.data)
+          } else {
+            this.$toast('请求失败')
+          }
+        }.bind(this)
+      })
+    },
+    formatterData (flag, data) {
+      if (flag === 0) {
+        this.sortReportFilters(data)
+      } else if (flag === 1) {
+        // 市场概况
+        const totalCount = this.sortMarketOverview(data.market_profile)
+        if (!totalCount) {
+          return true
+        }
+        // 时间分布
+        this.sortTimeScatter(data)
+      } else if (flag === 2) {
+        // 项目规模Top10
+        this.sortProjectTop10(data.ProjectTop10)
+      } else if (flag === 3) {
+        // 项目规模分布/地区规模分布/客户分布/地区分布及客户分布&Top3(table+chart)
+        // 项目规模分布
+        this.sortProjectScatter(data.projectScale)
+        // 地区规模分布
+        this.sortAreaScatter(data.area_infos)
+        // 客户分布
+        this.sortUserScatter(data.customer_scale)
+        // 地区分布及客户分布Top3
+        this.sortAreaUserTop3(data)
+      } else if (flag === 4) {
+        // 细分市场
+        this.sortMarketRefineData(data)
+      } else if (flag === 5) {
+        // 采购单位/中标单位&Top3(table+chart)
+        this.sortBuyerclassData(data)
+        // 中标单位分析
+        this.sortWinnerData(data)
+      }
+
+      this.$nextTick(this.calcOffsetTop)
+    },
+    formatSelectTime (value) {
+      if (!value) return '-'
+      const timeArr = value.split('-')
+      return `${dateFormatter(timeArr[0] * 1000, 'yyyy/MM/dd')}-${dateFormatter(timeArr[1] * 1000, 'yyyy/MM/dd')}`
+    },
+    // 整理数据,并赋值给filters
+    sortReportFilters (data) {
+      if (data.keysItems && data.keysItems !== '[]') {
+        this.reportFilters.keys = JSON.parse(data.keysItems)
+        this.filters.keys = this.reportFilters.keys
+        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.filters.selectKeysArr = keyArr
+      }
+
+      // if (data.s_rangeTimeExtra) {
+      //   this.reportFilters.selectTimeExtra = data.s_rangeTimeExtra
+      //   this.filters.rangeTime.exact = this.reportFilters.selectTimeExtra
+      // } else {
+      //   this.filters.rangeTime.exact = 'exact'
+      // }
+      this.filters.rangeTime.exact = 'exact'
+      if (data.rangeTime) {
+        this.reportFilters.selectTime = data.rangeTime
+        var arr = data.rangeTime.split('-')
+        this.filters.rangeTime.start = arr[0] * 1000
+        this.filters.rangeTime.end = arr[1] * 1000
+        if (this.filters.rangeTime.exact === 'exact') {
+          var date = new Date(this.filters.rangeTime.end)
+          var timeString = date.pattern('yyyy/MM/dd')
+          this.filters.rangeTime.end = new Date(timeString).getTime()
+        }
+      }
+      
+      this.$refs.dateSelector.setState(this.filters.rangeTime)
+      if (data.area && data.area !== '{}') {
+        this.reportFilters.area = JSON.parse(data.area)
+        this.filters.area = this.reportFilters.area
+      }
+      if (data.industry && data.industry !== '{}') {
+        this.reportFilters.industry = JSON.parse(data.industry)
+        this.$set(this.filters, 'industryDetail', this.reportFilters.industry)
+        var industry = []
+        for (var key in this.reportFilters.industry) {
+          this.reportFilters.industry[key].forEach(function (item) {
+            industry.push(key + '_' + item)
+          })
+        }
+        this.filters.industry = industry
+      }
+      if (data.buyerclass) {
+        this.reportFilters.buyerclass = data.buyerclass.split(',')
+        this.filters.buyerclass = this.reportFilters.buyerclass
+      }
+    },
+    // 市场概况
+    sortMarketOverview (profile) {
+      if (!profile) return
+      const list = [
+        {
+          label: '项目总数',
+          unit: '个',
+          count: 0,
+          ringRatio: 0
+        },
+        {
+          label: '项目总金额',
+          unit: '万元',
+          count: 0,
+          ringRatio: 0
+        },
+        {
+          label: '项目平均金额',
+          unit: '万元',
+          count: 10.04,
+          ringRatio: 0
+        },
+        {
+          label: '中标单位数',
+          unit: '家',
+          count: 10628,
+          ringRatio: 0
+        },
+        {
+          label: '采购单位数',
+          unit: '家',
+          count: 16215,
+          ringRatio: 0
+        }
+      ]
+
+      // 项目总数
+      list[0].count = profile.project_count ? profile.project_count : 0
+      list[0].ringRatio = profile.project_count_ratio ? (profile.project_count_ratio * 100).toFixed(2) : 0
+      // 项目总金额
+      const projectTotalMoney = this.moneyUnit(profile.projctamout ? profile.projctamout : 0)
+      list[1].count = projectTotalMoney.count || 0
+      list[1].unit = projectTotalMoney.unit || '万元'
+
+      list[1].ringRatio = profile.projctamount_ratio ? (profile.projctamount_ratio * 100).toFixed(2) : 0
+      // 项目平均金额
+      const projectAvgMoney = this.moneyUnit(profile.projectavgmoney ? profile.projectavgmoney : 0)
+      list[2].count = projectAvgMoney.count || 0
+      list[2].unit = projectAvgMoney.unit || '万元'
+      list[2].ringRatio = profile.projectavgmoney_ratio ? (profile.projectavgmoney_ratio * 100).toFixed(2) : 0
+      // 中标单位数
+      list[3].count = profile.winnercount ? profile.winnercount : 0
+      list[3].ringRatio = profile.winnercount_ratio ? (profile.winnercount_ratio * 100).toFixed(2) : 0
+      // 采购单位数
+      list[4].count = profile.buyercount ? profile.buyercount : 0
+      list[4].ringRatio = profile.winnercount_ratio ? (profile.winnercount_ratio * 100).toFixed(2) : 0
+
+      var totalCount = list.reduce((total, item) => item.count + total, 0)
+
+      if (totalCount) {
+        this.sections.market.overview = list
+      }
+
+      return totalCount
+    },
+    // 时间分布
+    sortTimeScatter (data) {
+      const hasDataM = this.sortTimeScatterData('month', data.month_distribution)
+      const hasDataY = this.sortTimeScatterData('year', data.year_distribution)
+
+      const hasData = hasDataM && hasDataY
+      this.sections.timeScatter.dataAlready = hasData
+    },
+    sortTimeScatterData (type, data) {
+      // columns: ['日期', '项目规模', '环比增长率(%)'],
+      // rows: [
+      //   {
+      //     日期: '6月',
+      //     项目规模: 0,
+      //     '环比增长率(%)': -99
+      //   },
+      //   {
+      //     日期: '7月',
+      //     项目规模: 736325,
+      //     '环比增长率(%)': 0
+      //   },
+      // ]
+
+      if (!data) return
+
+      // 项目数量
+      const mDCount = {
+        columns: ['日期', '项目数量(个)', '项目数量环比'],
+        rows: []
+      }
+      let mDCountTotal = 0
+      if (Array.isArray(data.project_count)) {
+        const field = {
+          [mDCount.columns[0]]: 'minth',
+          [mDCount.columns[1]]: 'value',
+          [mDCount.columns[2]]: 'ratio'
+        }
+        data.project_count.forEach(item => {
+          const row = {}
+          mDCount.columns.forEach(column => {
+            var value = item[field[column]]
+            if (value) {
+              if (field[column] === 'ratio') {
+                row[column] = utils.formatMoney(value * 100, undefined, true) - 0
+              } else {
+                row[column] = value
+              }
+            } else {
+              row[column] = null
+            }
+
+            if (typeof value === 'number') {
+              mDCountTotal += value
+            }
+          })
+          mDCount.rows.push(row)
+        })
+      }
+
+      if (mDCountTotal || isNaN(mDCountTotal)) {
+        this.$set(this.sections.timeScatter[type], 'count', mDCount)
+      }
+
+      // 项目规模
+      const mDAmount = {
+        columns: ['日期', '项目金额(万元)', '项目金额环比'],
+        rows: []
+      }
+      let mDAmuntTotal = 0
+      if (Array.isArray(data.project_amount)) {
+        const field = {
+          [mDAmount.columns[0]]: 'minth',
+          [mDAmount.columns[1]]: 'value',
+          [mDAmount.columns[2]]: 'ratio'
+        }
+        data.project_amount.forEach(item => {
+          const row = {}
+          mDAmount.columns.forEach(column => {
+            const value = item[field[column]]
+            if (value) {
+              if (field[column] === 'value') {
+                row[column] = utils.formatMoney(value / 10000, undefined, true) - 0
+              } else if (field[column] === 'ratio') {
+                row[column] = utils.formatMoney(value * 100, undefined, true)
+              } else {
+                row[column] = value
+              }
+            } else {
+              row[column] = null
+            }
+
+            if (typeof value === 'number') {
+              mDAmuntTotal += value
+            }
+          })
+          mDAmount.rows.push(row)
+        })
+      }
+
+      if (mDAmuntTotal || !isNaN(mDAmuntTotal)) {
+        this.$set(this.sections.timeScatter[type], 'amount', mDAmount)
+      }
+
+      const r = !!(mDCountTotal + mDAmuntTotal)
+      const hasOneNaN = isNaN(mDCountTotal) || isNaN(mDAmuntTotal)
+      return hasOneNaN || r
+    },
+    // 项目规模分布
+    sortProjectScatter (data) {
+      // const chartData = {
+      //   columns: ['项目规模', '项目总金额占比', '项目总数占比'],
+      //   rows: [
+      //     {
+      //       项目规模: '≥1亿',
+      //       项目总金额占比: 20,
+      //       项目总数占比: 10
+      //     },
+      //     {
+      //       项目规模: '1000万-1亿',
+      //       项目总金额占比: 50,
+      //       项目总数占比: 40
+      //     },
+      //     {
+      //       项目规模: '500万-1000万',
+      //       项目总金额占比: 20,
+      //       项目总数占比: 30
+      //     },
+      //     {
+      //       项目规模: '100万-500万',
+      //       项目总金额占比: 20,
+      //       项目总数占比: 30
+      //     }
+      //   ]
+      // }
+
+      const scaleList = data
+      const scaleData = {
+        columns: ['项目规模', '项目总金额占比', '项目总数占比'],
+        rows: []
+      }
+      let total = 0
+
+      if (scaleList && Array.isArray(scaleList)) {
+        const field = {
+          [scaleData.columns[0]]: 'Name',
+          [scaleData.columns[1]]: 'Persent_c',
+          [scaleData.columns[2]]: 'Persent_a'
+        }
+        scaleList.forEach(item => {
+          const row = {}
+          scaleData.columns.forEach(column => {
+            if (field[column] === 'Persent_c' || field[column] === 'Persent_a') {
+              row[column] = (item[field[column]] * 100).toFixed(2)
+              total += (item[field[column]] - 0)
+            } else {
+              row[column] = item[field[column]]
+            }
+          })
+          scaleData.rows.push(row)
+        })
+      }
+
+      if (total) {
+        scaleData.rows.reverse()
+        this.$set(this.sections.projectScatter, 'chartData', scaleData)
+        if (this.sections.projectScatter.tableData.length) {
+          this.sections.projectScatter.dataAlready = true
+        }
+      }
+    },
+    // 项目规模Top10
+    sortProjectTop10 (top10List) {
+      if (!Array.isArray(top10List)) return
+
+      this.sections.projectScatter.tableData = top10List.map(top => {
+        let winners = top.winner_s ? top.winner_s.join(',') : ''
+        if (!winners) {
+          winners = []
+        } else {
+          winners = top.winner_s
+        }
+
+        winners = winners.map((item, index) => {
+          return {
+            name: item,
+            id: Array.isArray(top.eidlist) ? top.eidlist[index] : null
+          }
+        })
+
+        top.area = top.area ? top.area : ''
+        top.city = top.city ? top.city : ''
+        top.sortprice = top.sortprice ? utils.formatMoney(top.sortprice / 10000, undefined, true) : ''
+        top.jgtime = top.jgtime ? dateFormatter(top.jgtime * 1000, 'yyyy-MM-dd') : ''
+        top.winner_s = winners
+
+        return top
+      })
+
+      if (this.sections.projectScatter.chartData) {
+        this.sections.projectScatter.dataAlready = true
+      }
+    },
+    // 地区规模分布
+    sortAreaScatter (areaList) {
+      // const chartData = {
+      //   columns: ['项目所在地', '项目数量', '项目金额'],
+      //   rows: [
+      //     {
+      //       项目所在地: '河南',
+      //       项目数量: 2,
+      //       项目金额: 2222
+      //     },
+      //     {
+      //       项目所在地: '北京',
+      //       项目数量: 22,
+      //       项目金额: 565666
+      //     },
+      //     {
+      //       项目所在地: '浙江',
+      //       项目数量: 22,
+      //       项目金额: 765666
+      //     }
+      //   ]
+      // }
+
+      const areaChartData = {
+        columns: ['项目所在地', '项目数量'],
+        sColumns: ['项目金额'],
+        rows: []
+      }
+      let total = 0
+
+      if (areaList && Array.isArray(areaList)) {
+        const field = {
+          [areaChartData.columns[0]]: 'area',
+          [areaChartData.columns[1]]: 'total',
+          [areaChartData.sColumns[0]]: 'amount'
+        }
+        areaList.forEach(item => {
+          const row = {}
+          areaChartData.columns.concat(areaChartData.sColumns).forEach(column => {
+            if (field[column] === 'amount') {
+              row[column] = utils.formatMoney(item[field[column]] / 10000, undefined, true) - 0
+            } else {
+              row[column] = item[field[column]]
+            }
+
+            if (field[column] === 'amount' || field[column] === 'total') {
+              total += (item[field[column]] - 0)
+            }
+          })
+          areaChartData.rows.push(row)
+        })
+      }
+
+      if (total) {
+        this.$set(this.sections.areaScatter, 'chartData', areaChartData)
+        this.sections.areaScatter.dataAlready = true
+      }
+    },
+    // 客户分布
+    sortUserScatter (userList) {
+      if (Array.isArray(userList)) {
+        this.sections.userScatter.list = userList.map(item => {
+          item.name = item.buyclass
+          item.value = item.total
+          item.amount = utils.formatMoney(item.amount / 10000, undefined, true)
+          return item
+        })
+      }
+    },
+    // 地区分布及客户分布Top3
+    sortAreaUserTop3 (data) {
+      if (data.scaleAreaCountTop || data.scaleAreaAmountTop) {
+        this.sorAreaTop3(data)
+      }
+      if (data.scaleBuyclassCountTop || data.scaleBuyclassAmountTop) {
+        this.sorUserTop3(data)
+      }
+    },
+    sorAreaTop3 (data) {
+      const tableDataCount = {
+        columns: ['序号', '地区:项目数量(个),占比', '前3中标单位:中标数量(个)'], // ,该地区占比
+        rows: []
+      }
+      const tableDataAmount = {
+        columns: ['序号', '地区:项目金额(万元),占比', '前3中标单位:中标金额(万元)'], // ,该地区占比
+        rows: []
+      }
+
+      const scaleAreaCountTop3 = data.scaleAreaCountTop
+      if (Array.isArray(scaleAreaCountTop3)) {
+        scaleAreaCountTop3.forEach((item, index) => {
+          item.name = item.name
+          item.subInfo1 = item.area_count ? `项目数量:${item.area_count}个` : ''
+          item.subInfo2 = item.area_scale ? `全国占比:${utils.formatMoney(item.area_scale * 100, undefined, true)}%` : ''
+          item.actionText = `中标单位 TOP3`
+          item.childrenShow = true
+          item.children = []
+          if (Array.isArray(item.winner)) {
+            item.winner.forEach((w, i) => {
+              const row = {
+                name: w.winner,
+                id: w.id,
+                type: 'winner',
+                subInfo1: w.winner_total ? `中标个数:${w.winner_total}个` : '',
+                // subInfo2: w.total_scale ? `地区占比:${utils.formatMoney(w.total_scale * 100, undefined, true)}%` : 0
+              }
+              item.children.push(row)
+            })
+          }
+        })
+        tableDataCount.rows = scaleAreaCountTop3
+      }
+
+      const scaleAreaAmountTop3 = data.scaleAreaAmountTop
+      if (Array.isArray(scaleAreaAmountTop3)) {
+        scaleAreaAmountTop3.forEach((item, index) => {
+          item.name = item.name
+          item.subInfo1 = item.area_amount ? `中标金额:${utils.formatMoney(item.area_amount / 10000, undefined, true)}万元` : ''
+          item.subInfo2 = item.area_scale ? `全国占比:${utils.formatMoney(item.area_scale * 100, undefined, true)}%` : ''
+          item.actionText = `中标单位 TOP3`
+          item.childrenShow = true
+          item.children = []
+          if (Array.isArray(item.winner)) {
+            item.winner.forEach((w, i) => {
+              const row = {
+                name: w.winner,
+                id: w.id,
+                type: 'winner',
+                subInfo1: w.winner_amount ? `中标金额:${utils.formatMoney(w.winner_amount / 10000, undefined, true)}万元` : '',
+                // subInfo2: w.amount_scale ? `地区占比:${utils.formatMoney(w.amount_scale * 100, undefined, true)}%` : ''
+              }
+              item.children.push(row)
+            })
+          }
+        })
+        tableDataAmount.rows = scaleAreaAmountTop3
+      }
+
+      if (tableDataCount.rows.length) {
+        this.$set(this.sections.areaScatter, 'projectCountTop3', tableDataCount.rows)
+      }
+      if (tableDataAmount.rows.length) {
+        this.$set(this.sections.areaScatter, 'projectAmountTop3', tableDataAmount.rows)
+      }
+    },
+    sorUserTop3 (data) {
+      const tableDataCount = {
+        columns: ['序号', '客户类型:项目数量(个),占比', '前3中标单位:中标数量(个)'], // ,该客户类型占比
+        rows: []
+      }
+      const tableDataAmount = {
+        columns: ['序号', '客户类型:项目金额(万元),占比', '前3中标单位:中标金额(万元)'], // ,该客户类型占比
+        rows: []
+      }
+
+      const countTop3 = data.scaleBuyclassCountTop
+      if (Array.isArray(countTop3)) {
+        countTop3.forEach((item, index) => {
+          item.name = item.name
+          item.subInfo1 = item.buyclass_count ? `项目数量:${item.buyclass_count}个` : ''
+          item.subInfo2 = item.buyclass_scale ? `全部占比:${utils.formatMoney(item.buyclass_scale * 100, undefined, true)}%` : ''
+          item.actionText = `中标单位 TOP3`
+          item.childrenShow = true
+          item.children = []
+
+          if (Array.isArray(item.winner)) {
+            item.winner.forEach((w, i) => {
+              const row = {
+                name: w.winner,
+                id: w.id,
+                type: 'winner',
+                subInfo1: w.winner_total ? `中标个数:${w.winner_total}个` : '',
+                // subInfo2: w.total_scale ? `该行业占比:${utils.formatMoney(w.total_scale * 100, undefined, true)}%` : ''
+              }
+              item.children.push(row)
+            })
+          }
+        })
+        tableDataCount.rows = countTop3
+      }
+
+      const amountTop3 = data.scaleBuyclassAmountTop
+      if (Array.isArray(amountTop3)) {
+        amountTop3.forEach((item, index) => {
+          item.name = item.name
+          item.subInfo1 = item.buyclass_amount ? `项目金额:${utils.formatMoney(item.buyclass_amount / 10000, undefined, true)}万元` : ''
+          item.subInfo2 = item.buyclass_scale ? `全部占比:${utils.formatMoney(item.buyclass_scale * 100, undefined, true)}%` : 0
+          item.actionText = `中标单位 TOP3`
+          item.childrenShow = true
+          item.children = []
+          if (Array.isArray(item.winner)) {
+            item.winner.forEach((w, i) => {
+              const row = {
+                name: w.winner,
+                id: w.id,
+                type: 'winner',
+                subInfo1: w.winner_amount ? `中标金额:${utils.formatMoney(w.winner_amount / 10000, undefined, true)}万元` : '',
+                // subInfo2: w.amount_scale ? `该行业占比:${utils.formatMoney(w.amount_scale * 100, undefined, true)}%` : ''
+              }
+              item.children.push(row)
+            })
+          }
+        })
+        tableDataAmount.rows = amountTop3
+      }
+
+      if (tableDataCount.rows.length) {
+        this.$set(this.sections.userScatter, 'projectCountTop3', tableDataCount.rows)
+      }
+      if (tableDataAmount.rows.length) {
+        this.$set(this.sections.userScatter, 'projectAmountTop3', tableDataAmount.rows)
+      }
+    },
+    // 细分市场
+    sortMarketRefineData (data) {
+      const refineCount = {
+        columns: ['行业', '项目数量'],
+        rows: []
+      }
+      const refineAmount = {
+        columns: ['行业', '项目金额'],
+        rows: []
+      }
+      let total = 0
+      const refineAll = data.scaleRefineAll
+      if (Array.isArray(refineAll)) {
+        const field = {
+          行业: 'name',
+          项目数量: 'total',
+          项目金额: 'amount'
+        }
+        refineAll.forEach(item => {
+          const row = {}
+          for (const key in field) {
+            if (field[key] === 'amount') {
+              row[key] = utils.formatMoney(item[field[key]] / 10000, undefined, true)
+            } else {
+              row[key] = item[field[key]]
+            }
+
+            if (field[key] === 'total' || field[key] === 'amount') {
+              total += (item[field[key]] - 0)
+            }
+          }
+          refineCount.rows.push(row)
+          refineAmount.rows.push(row)
+        })
+      }
+
+      if (total) {
+        this.$set(this.sections.market.refine, 'projectCountData', refineCount)
+        this.$set(this.sections.market.refine, 'projectAmountData', refineAmount)
+
+        this.sections.market.refine.dataAlready = true
+      }
+      
+      this.sortRefineTop3(data)
+    },
+    sortRefineTop3 (data) {
+      const tableDataCount = {
+        columns: ['序号', '细分市场:项目数量(个)', '前3中标单位:中标数量(个)'], // ,占比,该细分市场占比
+        rows: []
+      }
+      const tableDataAmount = {
+        columns: ['序号', '细分市场:项目金额(万元)', '前3中标单位:中标金额(万元)'], // ,占比,该细分市场占比
+        rows: []
+      }
+
+      const countTop3 = data.scaleRefineTotalTop
+      if (Array.isArray(countTop3)) {
+        countTop3.forEach((item, index) => {
+          item.name = item.name
+          item.subInfo1 = item.value ? `项目数量:${item.value}个` : ''
+          // item.subInfo2 = item.prop ? `全部占比:${utils.formatMoney(item.prop * 100, undefined, true)}%` : 0
+          item.actionText = `中标单位 TOP3`
+          item.childrenShow = true
+          item.children = []
+          if (Array.isArray(item.topList)) {
+            item.topList.forEach((w, i) => {
+              const row = {
+                name: w.name,
+                id: w.id,
+                type: 'winner',
+                subInfo1: w.value ? `中标个数:${w.value}个` : '',
+                // subInfo2: w.prop ? `该细分市场占比:${utils.formatMoney(w.prop * 100, undefined, true)}%` : ''
+              }
+              item.children.push(row)
+            })
+          }
+        })
+        tableDataCount.rows = countTop3
+      }
+
+      const amountTop3 = data.scaleRefineAmountTop
+      if (Array.isArray(amountTop3)) {
+        amountTop3.forEach((item, index) => {
+          item.name = item.name
+          item.subInfo1 = item.value ? `项目金额:${utils.formatMoney(item.value / 10000, undefined, true)}万元` : ''
+          // item.subInfo2 = item.prop ? `全部占比:${utils.formatMoney(item.prop * 100, undefined, true)}%` : 0
+          item.actionText = `中标单位 TOP3`
+          item.childrenShow = true
+          item.children = []
+          if (Array.isArray(item.topList)) {
+            item.topList.forEach((w, i) => {
+              const row = {
+                name: w.name,
+                id: w.id,
+                type: 'winner',
+                subInfo1: w.value ? `中标金额:${utils.formatMoney(w.value / 10000, undefined, true)}万元` : '',
+                // subInfo2: w.prop ? `该细分市场占比:${utils.formatMoney(w.prop * 100, undefined, true)}%`: ''
+              }
+              item.children.push(row)
+            })
+          }
+        })
+        tableDataAmount.rows = amountTop3
+      }
+
+      if (tableDataCount.rows.length) {
+        this.$set(this.sections.market.refine, 'projectCountTop3', tableDataCount.rows)
+      }
+      if (tableDataAmount.rows.length) {
+        this.$set(this.sections.market.refine, 'projectAmountTop3', tableDataAmount.rows)
+      }
+    },
+    // 采购单位
+    sortBuyerclassData (data) {
+      const buyerclassChartData = {
+        columns: ['金额区间', '采购总金额占比', '采购单位数量占比'],
+        rows: []
+      }
+      let total = 0
+
+      const buyerclassList = data.buyer_time_distribution
+      if (Array.isArray(buyerclassList)) {
+        const field = {
+          [buyerclassChartData.columns[0]]: 'key',
+          [buyerclassChartData.columns[1]]: 'total_amount',
+          [buyerclassChartData.columns[2]]: 'total_number'
+        }
+        buyerclassList.forEach(item => {
+          const row = {}
+          buyerclassChartData.columns.forEach(column => {
+            if (field[column] === 'total_amount' || field[column] === 'total_number') {
+              row[column] = (item[field[column]] * 100).toFixed(2)
+              total += (item[field[column]] - 0)
+            } else {
+              row[column] = item[field[column]]
+            }
+          })
+          buyerclassChartData.rows.push(row)
+        })
+      }
+
+      if (total) {
+        buyerclassChartData.rows.reverse()
+        this.$set(this.sections.buyerclass, 'chartData', buyerclassChartData)
+
+        this.sections.buyerclass.dataAlready = true
+      }
+      
+      this.sortBuyerclassTableData(data)
+    },
+    sortBuyerclassTableData (data) {
+      const dataCount = {
+        columns: ['序号', '采购单位:采购数量(个)', '前3中标单位:中标数量(个)'], //,占比 |  ,占该采购单位
+        rows: []
+      }
+      const dataAmount = {
+        columns: ['序号', '采购单位:采购金额(万元)', '前3中标单位:中标金额(万元)'], //,占比 |  ,占该采购单位
+        rows: []
+      }
+
+      const countTop3 = data.buyer_count_top3
+      if (Array.isArray(countTop3)) {
+        countTop3.forEach((item, index) => {
+          item.name = item.name
+          item.type = 'buyer'
+          item.id = item.name
+          item.subInfo1 = item.number ? `项目数量:${item.number}个` : ''
+          // item.subInfo2 = item.accounted ? `全部占比:${utils.formatMoney(item.accounted * 100, undefined, true)}%` : ''
+          item.actionText = `中标单位 TOP3`
+          item.childrenShow = true
+          item.children = []
+          if (Array.isArray(item.winnertop3)) {
+            item.winnertop3.forEach((w, i) => {
+              const row = {
+                name: w.name,
+                id: w.id,
+                type: 'winner',
+                subInfo1: w.number ? `中标个数:${w.number}个` : '',
+                // subInfo2: w.accounted ? `占该采购单位:${utils.formatMoney(w.accounted * 100, undefined, true)}%` : ''
+              }
+              item.children.push(row)
+            })
+          }
+        })
+        dataCount.rows = countTop3
+      }
+
+      const amountTop3 = data.buyer_amount_top3
+      if (Array.isArray(amountTop3)) {
+        amountTop3.forEach((item, index) => {
+          item.name = item.name
+          item.type = 'buyer'
+          item.id = item.name
+          item.subInfo1 = item.amount ? `采购金额:${utils.formatMoney(item.amount / 10000, undefined, true)}万元` : ''
+          // item.subInfo2 = item.accounted ? `全部占比:${utils.formatMoney(item.accounted * 100, undefined, true)}%` : ''
+          item.actionText = `中标单位 TOP3`
+          item.childrenShow = true
+          item.children = []
+          if (Array.isArray(item.winnertop3)) {
+            item.winnertop3.forEach((w, i) => {
+              const row = {
+                name: w.name,
+                id: w.id,
+                type: 'winner',
+                subInfo1: w.amount ? `中标金额:${utils.formatMoney(w.amount / 10000, undefined, true)}万元` : '',
+                // subInfo2: w.accounted ? `该行业占比:${utils.formatMoney(w.accounted * 100, undefined, true)}%` : ''
+              }
+              item.children.push(row)
+            })
+          }
+        })
+        dataAmount.rows = amountTop3
+      }
+      if (dataCount.rows.length) {
+        this.$set(this.sections.buyerclass, 'projectCountTop3', dataCount.rows)
+      }
+      if (dataAmount.rows.length) {
+        this.$set(this.sections.buyerclass, 'projectAmountTop3', dataAmount.rows)
+      }
+    },
+    // 中标单位
+    sortWinnerData (data) {
+      const chartData = {
+        columns: ['金额区间', '中标总金额占比', '中标单位数量占比'],
+        rows: []
+      }
+      let total = 0
+
+      const chartLIst = data.winner_time_distribution
+      if (Array.isArray(chartLIst)) {
+        const field = {
+          [chartData.columns[0]]: 'key',
+          [chartData.columns[1]]: 'total_amount',
+          [chartData.columns[2]]: 'total_number'
+        }
+        chartLIst.forEach(item => {
+          const row = {}
+          chartData.columns.forEach(column => {
+            if (field[column] === 'total_amount' || field[column] === 'total_number') {
+              row[column] = (item[field[column]] * 100).toFixed(2)
+              total += (item[field[column]] - 0)
+            } else {
+              row[column] = item[field[column]]
+            }
+          })
+          chartData.rows.push(row)
+        })
+      }
+
+      if (total) {
+        chartData.rows.reverse()
+        this.$set(this.sections.winner, 'chartData', chartData)
+
+        this.sections.winner.dataAlready = true
+      }
+
+      this.sortWinnerTableData(data)
+    },
+    sortWinnerTableData (data) {
+      const dataCount = {
+        columns: ['序号', '中标单位:中标数量(个)', '前3采购单位:采购数量(个)'], // ,占比 | ,占该中标单位
+        rows: []
+      }
+      const dataAmount = {
+        columns: ['序号', '中标单位:中标金额(万元),占比', '前3采购单位:采购金额(万元),占该中标单位'], // ,占比 | ,占该中标单位
+        rows: []
+      }
+
+      const countTop3 = data.winner_count_top3
+      if (Array.isArray(countTop3)) {
+        countTop3.forEach((item, index) => {
+          item.name = item.name
+          item.type = 'winner'
+          item.id = item.id
+          item.subInfo1 = item.number ? `中标数量:${item.number}个` : ''
+          // item.subInfo2 = item.accounted ? `全部占比:${utils.formatMoney(item.accounted * 100, undefined, true)}%` : ''
+          item.actionText = `采购单位 TOP3`
+          item.childrenShow = true
+          item.children = []
+          if (Array.isArray(item.buyertop3)) {
+            item.buyertop3.forEach((w, i) => {
+              const row = {
+                name: w.name,
+                id: w.name,
+                type: 'buyer',
+                subInfo1: w.number ? `采购数量:${w.number}个` : '',
+                // subInfo2: w.accounted ? `占该中标单位:${utils.formatMoney(w.accounted * 100, undefined, true)}%` : ''
+              }
+              item.children.push(row)
+            })
+          }
+        })
+        dataCount.rows = countTop3
+      }
+
+      const amountTop3 = data.winner_amount_top3
+      if (Array.isArray(amountTop3)) {
+        amountTop3.forEach((item, index) => {
+          item.name = item.name
+          item.type = 'winner'
+          item.id = item.id
+          item.subInfo1 = item.amount ? `中标金额:${utils.formatMoney(item.amount / 10000, undefined, true)}万元` : ''
+          // item.subInfo2 = item.accounted ? `全部占比:${utils.formatMoney(item.accounted * 100, undefined, true)}%` : ''
+          item.actionText = `采购单位 TOP3`
+          item.childrenShow = true
+          item.children = []
+          if (Array.isArray(item.buyertop3)) {
+            item.buyertop3.forEach((w, i) => {
+              const row = {
+                name: w.name,
+                id: w.name,
+                type: 'buyer',
+                subInfo1: w.amount ? `采购金额:${utils.formatMoney(w.amount / 10000, undefined, true)}万元` : '',
+                // subInfo2: w.accounted ? `占该中标单位:${utils.formatMoney(w.accounted * 100, undefined, true)}%` : ''
+              }
+              item.children.push(row)
+            })
+          }
+        })
+        dataAmount.rows = amountTop3
+      }
+
+      if (dataCount.rows.length) {
+        this.$set(this.sections.winner, 'projectCountTop3', dataCount.rows)
+      }
+      if (dataAmount.rows.length) {
+        this.$set(this.sections.winner, 'projectAmountTop3', dataAmount.rows)
+      }
+    },
+    toAnalysisPage: function () {
+      this.rid = ''
+      this.analysis.loaded = false
+      this.filtersPageShow = true
+    },
+    moneyUnit (num, type, lv) {
+      const m = utils.moneyUnit(num, type, lv)
+      let unit = String(m).match(/[\u4e00-\u9fa5]/g)
+      if (unit && Array.isArray(unit)) {
+        unit = unit.join('')
+      } else {
+        unit = ''
+      }
+      let count = ''
+      if (unit) {
+        count = m.replace(unit, '') - 0
+      }
+      return {
+        unit,
+        count
+      }
+    },
+    anchorTo (item) {
+      if (!item.top) return
+      var offsetTop = item.top || 0
+      this.activeDimension = item.id
+      this.$nextTick(function () {
+        $('.search-result > .j-main')[0].scrollTop = offsetTop
+      })
+    },
+    showSetKeyTip: function () {
+      this.notSetKey = true
+    },
+    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()
+        }
+      })
+    },
+    toSubManageButtonClick: function () {
+      if (this.isSubCount) {
+        this.showToast('请联系管理员完善订阅的关键词')
+      } else {
+        this.toSubManage()
+      }
+    },
+    toSubManage: function () {
+      location.href = '/jyapp/vipsubscribe/toSetKeyWordPage?vSwitch=m'
+    },
+    toArticleContent (item) {
+      this.saveState()
+      location.href = `/jyapp/article/content/${item._id}.html`
+    },
+    toPortrait (id, type) {
+      if (!type || !id) return
+      this.saveState()
+      if (type === 'winner') {
+        location.href = `./ent_portrait?eId=${id}`
+      } else if (type === 'buyer') {
+        location.href = `./unit_portrayal?entName=${id}`
+      }
+    }
+  }
+})

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

@@ -0,0 +1,222 @@
+var vm = new Vue({
+  delimiters: ['${', '}'],
+  el: '#analysis',
+  components: {
+    reportListMobileComponent: reportListMobileComponent
+  },
+  data: {
+    sessStorageKey: '$data-report_analysis_history',
+    tabActiveName: 'history', // analysis/history
+    tabList: [
+      {
+        label: '定制化市场分析',
+        name: 'analysis'
+      },
+      {
+        label: '历史报告',
+        name: 'history'
+      }
+    ],
+    tabConf: {
+      titleActiveColor: '#2ABED1',
+      titleInactiveColor: '#5F5E64',
+      lineWidth: '24',
+      color: '#2ABED1'
+    },
+    historyPageState: {
+      scrollTop: 0,
+      listState: {
+        refreshing: false,
+        loaded: false,
+        loading: false,
+        finished: false,
+        pageNum: 1,
+        pageSize: 10,
+        offset: 100,
+        list: []
+      }
+    }
+  },
+  computed: {
+    tabActive: function () {
+      var _this = this
+      var active = {}
+      this.tabList.some(function (item) {
+        var findThis = item.name === _this.tabActiveName
+        if (findThis)  {
+          active = item
+          return findThis
+        }
+      })
+      return active
+    }
+  },
+  created: function () {},
+  mounted: function () {
+    this.reStoreState()
+    utils.iosBackRefresh()
+  },
+  methods: {
+    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)
+    },
+    setScrollTop: function (scrollTop) {
+      this.$nextTick(function () {
+        var wrapper = document.querySelector('.van-tabs__content')
+        wrapper.scrollTop = scrollTop
+      })
+    },
+    saveScrollTop: function () {
+      var wrapper = document.querySelector('.van-tabs__content')
+      if (wrapper.scrollTop) {
+        this.historyPageState.listState.scrollTop = parseInt(wrapper.scrollTop)
+      }
+    },
+    beforeTabChange: function (name) {
+      if (name !== this.tabActiveName) {
+        this.saveState()
+        this.goToAnalysis()
+      }
+      return false
+    },
+    goToAnalysis: function (id) {
+      var href = './report_analysis'
+      if (id) {
+        href += ('?id=' + id)
+      }
+      location.replace(href)
+    },
+    // 重置列表数据
+    resetHistoryState: function () {
+      var rState = {
+        refreshing: false,
+        loaded: false,
+        loading: false,
+        finished: false,
+        pageNum: 1,
+        pageSize: 10,
+        list: []
+      }
+
+      this.historyPageState.scrollTop = 0
+      Object.assign(this.historyPageState.listState, rState)
+    },
+    // 加载历史记录数据
+    onHistoryListLoad: function () {
+      var _this = this
+      var t = this.historyPageState.listState
+      var query = {
+        pageNum: t.pageNum,
+        pageSize: t.pageSize
+      }
+
+      t.loading = true
+
+      $.ajax({
+        type: 'POST',
+        url: '/bigmember/marketAnalysis/analysisHistory?t=' + Date.now(),
+        data: query,
+        success: function (res) {
+          if (res) {
+            // 判断是否为刷新
+            if (t.refreshing) {
+              t.list = []
+              t.refreshing = false
+            }
+
+            // 列表赋值
+            var list = res.res
+            if (Array.isArray(list)) {
+              _this.preSortList(list)
+              t.list = t.list.concat(list)
+            }
+
+            // 加载状态结束
+            t.loaded = true
+            t.loading = false
+
+            // 翻页
+            if (res.hasNextPage) {
+              t.pageNum++
+            } else {
+              t.finished = true
+            }
+          } else {
+            t.loaded = true
+            t.loading = false
+            t.finished = true
+            _this.$toast('请求失败')
+          }
+        },
+        error: function (error) {
+          console.log(error)
+        }
+      })
+    },
+    // 刷新历史记录数据
+    onHistoryListRefresh: function () {
+      var t = this.historyPageState.listState
+      // 重置数据
+      t.pageNum = 1
+      // 解除加载完成状态
+      t.finished = false
+      // 重新加载数据
+      // 将 loading 设置为 true,表示处于加载状态
+      t.loading = true
+      // 请求数据
+      this.onHistoryListLoad()
+    },
+    // 保存页面状态
+    saveState: function () {
+      this.saveScrollTop()
+      var $data = {
+        historyPageState: this.historyPageState
+      }
+      sessionStorage.setItem(this.sessStorageKey, JSON.stringify($data))
+    },
+    reStoreState: function () {
+      var $data = sessionStorage.getItem(this.sessStorageKey)
+      if ($data) {
+        $data = JSON.parse($data)
+        Object.assign(this.historyPageState, $data.historyPageState)
+
+        if (this.tabActiveName === 'history') {
+          setTimeout(function () {
+            // 恢复滚动高度
+            this.setScrollTop(this.historyPageState.scrollTop)
+          }.bind(this), 0)
+        }
+
+        sessionStorage.removeItem(this.sessStorageKey)
+      }
+
+      return $data
+    }
+  }
+})

+ 566 - 0
src/web/templates/big-member/wx/page_report_analysis.html

@@ -0,0 +1,566 @@
+<!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='{{Msg "seo" "cdn"}}/common-module/collection/css/index.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>
+      .example-title{
+        padding: .32rem .32rem .12rem;
+        font-size: .36rem;
+        line-height: .52rem;
+        color: #171826;
+        font-weight: bold;
+        background-color: #fcfcfd;
+      }
+      .vip_openDialog{
+        margin-top: 0.92rem 0 .6rem;
+        width: 6.06rem;
+        background: url(/big-member/image/openVip.png) no-repeat;
+        background-size: 100% 100%;
+        box-sizing: border-box;
+      }
+      .vip_openDialog .goBtn{
+        margin-bottom: .48rem;
+      }
+      .vip_extend{
+        padding: .16rem 0 0;
+        line-height: .4rem;
+        color: #171826;
+      }
+      .vip_component {
+        margin-top: .16rem;
+        flex-direction: column;
+      }
+
+      .vip_component .example-title {
+        width: 100%;
+        height: .96rem;
+        background: #fcfcfd;
+        font-size: .36rem;
+      }
+      .vip_component .chart_com{
+        width: 100%;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        height: inherit;
+      }
+    </style>
+</head>
+<body>
+  <div class="j-container">
+    <div class="j-main" id="analysis" v-cloak>
+      <div class="j-container">
+          <van-tabs
+              class="analysis-tab"
+              :title-active-color="tabConf.titleActiveColor"
+              :title-inactive-color="tabConf.titleInactiveColor"
+              :line-width="tabConf.lineWidth"
+              :color="tabConf.color"
+              :before-change="beforeTabChange"
+              v-model="tabActiveName">
+              <van-tab
+                  v-for="(tab, index) in tabList"
+                  :key="index"
+                  :title="tab.label"
+                  :name="tab.name"></van-tab>
+          </van-tabs>
+          <section v-show="tabActiveName === 'analysis'" class="j-main analysis-content">
+              <div class="j-container search-filters bg-white" v-show="filtersPageShow && !rid">
+                  <div class="j-main">
+                      <div class="height8">height8</div>
+                      <div class="filters-title pd-lr16">
+                          <span>分析条件</span>
+                      </div>
+                      <van-cell-group class="filters-list">
+                          <van-cell center title="分析内容" is-link value-class="ellipsis" :value="resolveSelected('keys')" @click="clickCell('keys')"></van-cell>
+                          <van-cell center title="区域" is-link value-class="ellipsis" :value="resolveSelected('area')" @click="clickCell('area')"></van-cell>
+                          <van-cell center title="行业" is-link value-class="ellipsis" :value="resolveSelected('industry')" @click="clickCell('industry')"></van-cell>
+                          <van-cell center title="采购单位类型" value-class="ellipsis" is-link :value="resolveSelected('buyerclass')" @click="clickCell('buyerclass')"></van-cell>
+                          <div class="date-cell collection">
+                              <div class="cell-title">时间</div>
+                              <date-component
+                                  ref="dateSelector"
+                                  popup-container="body"
+                                  :diy="true"
+                                  :times="timeOptions"></date-component>
+                          </div>
+                      </van-cell-group>
+                      <div class="empty-container analysis-empty" v-show="emptyShow">
+                          <div class="empty-content-position">
+                              <div class="image">
+                                  <img src='/common-module/public/image/jy-sleep.png'>
+                              </div>
+                              <div class="empty-main tip-text" v-html="empty.msg"></div>
+                          </div>
+                      </div>
+                  </div>
+                  <div class="j-footer j-button-group">
+                      <button class="j-button-cancel" @click="resetAllFilters">重置</button>
+                      <button class="j-button-confirm" @click="startAnalysis">开始分析</button>
+                  </div>
+              </div>
+              <div class="j-container search-result" v-show="!filtersPageShow && rid">
+                  <div class="j-main">
+                      <div class="height8">height8</div>
+                      <van-cell-group class="filters-list">
+                          <van-cell center title="分析条件" is-link @click="toAnalysisPage"></van-cell>
+                      </van-cell-group>
+                      <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">
+                              <div class="section-content dimension-list bg-white">
+                                  <div
+                                      class="j-button j-button-item dimension-item"
+                                      v-for="(item, index) in dimensionList"
+                                      :key="index"
+                                      v-text="item.name"
+                                      :class="{ active: item.id === activeDimension }"
+                                      @click="anchorTo(item)"
+                                  ></div>
+                              </div>
+                          </van-sticky>
+                          <div class="section-footer section-tip-text">
+                              <span>数据统计范围:</span>
+                              <span v-text="formatSelectTime(reportFilters.selectTime)"></span>
+                          </div>
+                      </section>
+                      <!-- 市场概况 -->
+                      <section class="section bg-white market-overview" id="market" v-if="getStatus">
+                          <div class="section-title pd-16">市场概况</div>
+                          <div class="section-content market-overview-list">
+                              <div
+                                  class="market-overview-item"
+                                  v-for="(item, index) in sections.market.overview"
+                                  :key="index">
+                                  <span class="m-overview-name">${ item.label }</span>
+                                  <span class="m-overview-unit">(${ item.unit })</span>
+                                  <span class="m-overview-count">${ item.count }</span>
+                                  <span class="m-overview-type" v-if="item.ringRatio">环比</span>
+                                  <span
+                                      class="m-overview-ratio"
+                                      v-show="overviewRateTotal"
+                                      :class="{
+                                          red: item.ringRatio > 0,
+                                          green: item.ringRatio < 0
+                                      }">
+                                      <van-icon name="down" :class="{ 'icon-reverse': item.ringRatio >= 0 }" v-if="item.ringRatio"></van-icon>
+                                      <span>${ item.ringRatio ? (Math.abs(item.ringRatio) + '%') : '-' }</span>
+                                  </span>
+                              </div>
+                          </div>
+                          <div class="section-footer section-tip-text pd-16">
+                              环比:统计学术语,是表示连续2个统计周期(比如连<br />续两月)内的量的变化比。
+                          </div>
+                      </section>
+                      <div class="vip_component"
+                        v-if="!getStatus"
+                        style="height:8.84rem">
+                        <p class="example-title">市场概况</p>
+                        <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>
+                        </div>
+                      </div>
+                      <!-- 项目规模分布 -->
+                      <section class="section bg-white pd-16 project-scatter" v-if="sections.projectScatter.dataAlready && getStatus">
+                          <div class="section-title">项目规模分布</div>
+                          <div class="section-content">
+                              <project-scatter :chart-data="sections.projectScatter.chartData"></project-scatter>
+                          </div>
+                      </section>
+                      <!-- 项目规模TOP10 -->
+                      <section class="section bg-white pd-16 project-scatter" v-if="sections.projectScatter.tableData.length && getStatus">
+                          <div class="section-title">项目规模TOP10</div>
+                          <div class="section-content project-top-list">
+                              <div
+                                  class="project-top-item"
+                                  v-for="(item, index) in sections.projectScatter.tableData"
+                                  :key="index">
+                                  <div class="p-t-i-hd">
+                                      <div
+                                          class="p-t-i-hd-l table-index-rect"
+                                          :class="{
+                                              red: index === 0,
+                                              orange: index === 1,
+                                              'soft-orange': index === 2
+                                          }">
+                                          ${ index + 1 }</div>
+                                      <div class="p-t-i-hd-r" @click="toArticleContent(item)">
+                                          <div class="project-name">${ item.projectname }</div>
+                                          <div class="project-info">
+                                              <div class="project-tags">
+                                                  <div class="j-tag tag-orange" v-if="item.sortprice">项目金额:${ item.sortprice }万元</div>
+                                                  <div class="j-tag tag-plain" v-if="item.area">${ item.area }</div>
+                                                  <div class="j-tag tag-plain" v-if="item.city">${ item.city }</div>
+                                              </div>
+                                              <div class="project-right">${ item.jgtime }</div>
+                                          </div>
+                                      </div>
+                                  </div>
+                                  <div class="p-t-i-ft" v-if="item.winner_s.length">
+                                      <div class="p-t-i-ft-title">中标单位</div>
+                                      <div
+                                          class="p-t-i-ft-winner"
+                                          :class="{ disabled: !winner.id }"
+                                          v-for="(winner, i) in item.winner_s"
+                                          :key="index"
+                                          v-text="winner.name"
+                                          @click="toPortrait(winner.id, 'winner')"></div>
+                                  </div>
+                              </div>
+                          </div>
+                      </section>
+                      <div class="vip_component"
+                        v-if="!getStatus"
+                        style="height:11.38rem">
+                        <p class="example-title">项目规模分布</p>
+                        <div class="chart_com" style="background:url('/common-module/report-analysis/image/02-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
+                          <chart-example type="item_2" imgurl='{{Msg "seo" "cdn"}}/common-module/report-analysis/image/02.png?v={{Msg "seo" "version"}}'>
+                          </chart-example>
+                        </div>
+                      </div>
+                      <!-- 时间分布 -->
+                      <section class="section bg-white pd-16 time-scatter" v-if="sections.timeScatter.dataAlready">
+                          <div class="section-header">
+                              <div class="section-title">时间分布</div>
+                              <div class="section-actions">
+                                  <div
+                                      class="action-button"
+                                      :class="{ active: sections.timeScatter.activeAction == 'month' }"
+                                      @click="sections.timeScatter.activeAction = 'month'">
+                                      月度数据</div>
+                                  <div
+                                      class="action-button"
+                                      :class="{ active: sections.timeScatter.activeAction == 'year' }"
+                                      @click="sections.timeScatter.activeAction = 'year'">
+                                      年度数据</div>
+                              </div>
+                          </div>
+                          <div class="section-content">
+                              <div class="sub-section-content">
+                                  <market-time-scatter width="100%" :chart-data="sections.timeScatter[sections.timeScatter.activeAction].count"></market-time-scatter>
+                              </div>
+                              <div class="sub-section-content">
+                                  <market-time-scatter width="100%" :chart-data="sections.timeScatter[sections.timeScatter.activeAction].amount"></market-time-scatter>
+                              </div>
+                          </div>
+                      </section>
+                      <!-- 地区分布 -->
+                      <div class="section bg-white pd-16 area-scatter" v-if="sections.areaScatter.dataAlready && notOneAreaFilter && getStatus">
+                          <div class="section-title">地区分布</div>
+                          <div class="section-content">
+                              <market-area-scatter :chart-data="sections.areaScatter.chartData"></market-area-scatter>
+                          </div>
+                      </div>
+                      <div class="section bg-white pd-16" v-if="sections.areaScatter.projectCountTop3 && getStatus">
+                          <div class="section-title">项目数量TOP3地区的重点中标单位</div>
+                          <div class="section-content">
+                              <market-top3-table :table-data="sections.areaScatter.projectCountTop3" type="count" @save="saveState"></market-top3-table>
+                          </div>
+                      </div>
+                      <div class="section bg-white pd-16" v-if="sections.areaScatter.projectAmountTop3 && getStatus">
+                          <div class="section-title">项目金额TOP3地区的重点中标单位</div>
+                          <div class="section-content">
+                              <market-top3-table :table-data="sections.areaScatter.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
+                          </div>
+                      </div>
+                      <div class="vip_component"
+                        v-if="!getStatus"
+                        style="height:13.08rem">
+                        <p class="example-title">地区分布</p>
+                        <div class="chart_com" style="background:url('/common-module/report-analysis/image/03-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
+                          <chart-example type="item_3" imgurl='{{Msg "seo" "cdn"}}/common-module/report-analysis/image/03.png?v={{Msg "seo" "version"}}'>
+                          </chart-example>
+                        </div>
+                      </div>
+                      <!-- 客户分布 -->
+                      <div class="section bg-white pd-16 user-scatter" v-if="sections.userScatter.list.length">
+                          <div class="section-title">客户分布</div>
+                          <div class="section-content">
+                              <market-user-scatter :chart-data="sections.userScatter.list"></market-user-scatter>
+                          </div>
+                      </div>
+                      <div class="section bg-white pd-16" v-if="sections.userScatter.projectCountTop3">
+                          <div class="section-title">项目数量TOP3客户类型的重点中标单位</div>
+                          <div class="section-content">
+                              <market-top3-table :table-data="sections.userScatter.projectCountTop3" type="count" @save="saveState"></market-top3-table>
+                          </div>
+                      </div>
+                      <div class="section bg-white pd-16" v-if="sections.userScatter.projectAmountTop3">
+                          <div class="section-title">项目金额TOP3客户类型的重点中标单位</div>
+                          <div class="section-content">
+                              <market-top3-table :table-data="sections.userScatter.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
+                          </div>
+                      </div>
+                      <!-- 细分市场 - 项目数量 -->
+                      <div class="section bg-white pd-16 market-refine" v-if="sections.market.refine.dataAlready && getStatus">
+                          <div class="section-title">细分市场 - 项目数量</div>
+                          <div class="section-content">
+                              <market-segment :chart-data="sections.market.refine.projectCountData" type="count"></market-segment>
+                          </div>
+                      </div>
+                      <div class="section bg-white pd-16" v-if="sections.market.refine.projectCountTop3 && getStatus">
+                          <div class="section-title">细分市场的重点中标单位-项目数量</div>
+                          <div class="section-content">
+                              <market-top3-table :table-data="sections.market.refine.projectCountTop3" type="count" @save="saveState"></market-top3-table>
+                          </div>
+                      </div>
+                      <div class="vip_component"
+                        v-if="!getStatus"
+                        style="height:10.8rem">
+                        <p class="example-title">细分市场 - 项目数量</p>
+                        <div class="chart_com" style="background:url('/common-module/report-analysis/image/04-1-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
+                          <chart-example type="item_4_1" imgurl='{{Msg "seo" "cdn"}}/common-module/report-analysis/image/04-1.png?v={{Msg "seo" "version"}}'>
+                          </chart-example>
+                        </div>
+                      </div>
+                      <!-- 细分市场 - 项目金额 -->
+                      <div class="section bg-white pd-16 market-refine" v-if="sections.market.refine.dataAlready && getStatus">
+                          <div class="section-title">细分市场 - 项目金额</div>
+                          <div class="section-content">
+                              <market-segment :chart-data="sections.market.refine.projectAmountData" type="amount"></market-segment>
+                          </div>
+                      </div>
+                      <div class="section bg-white pd-16" v-if="sections.market.refine.projectAmountTop3 && getStatus">
+                          <div class="section-title">细分市场的重点中标单位-项目金额</div>
+                          <div class="section-content">
+                              <market-top3-table :table-data="sections.market.refine.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
+                          </div>
+                      </div>
+                      <div class="vip_component"
+                        v-if="!getStatus"
+                        style="height:10.8rem">
+                        <p class="example-title">细分市场 - 项目金额</p>
+                        <div class="chart_com" style="background:url('/common-module/report-analysis/image/04-2-bg.png?v={{Msg "seo" "version"}}') no-repeat;background-size:100% 100%">
+                          <chart-example type="item_4_2" imgurl='{{Msg "seo" "cdn"}}/common-module/report-analysis/image/04-2.png?v={{Msg "seo" "version"}}'>
+                          </chart-example>
+                        </div>
+                      </div>
+                      <!-- 采购规模分布 -->
+                      <div class="section bg-white pd-16 buyerclass-scatter" id="buyer" v-if="sections.buyerclass.dataAlready">
+                          <div class="section-title">采购规模分布</div>
+                          <div class="section-content">
+                              <line-chart-scatter :chart-data="sections.buyerclass.chartData"></line-chart-scatter>
+                          </div>
+                      </div>
+                      <div class="section bg-white pd-16" v-if="sections.buyerclass.projectCountTop3 && getStatus">
+                          <div class="section-title">项目数量TOP3采购单位及其重点合作中标单位</div>
+                          <div class="section-content">
+                              <market-top3-table :table-data="sections.buyerclass.projectCountTop3" type="count" @save="saveState"></market-top3-table>
+                          </div>
+                      </div>
+                      <div class="vip_component"
+                        v-if="!getStatus"
+                        style="height:10.8rem">
+                        <p class="example-title">项目数量TOP3采购单位及其重点合作中标单位</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-content">
+                              <market-top3-table :table-data="sections.buyerclass.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
+                          </div>
+                      </div>
+                      <div class="vip_component"
+                        v-if="!getStatus"
+                        style="height:10.8rem">
+                        <p class="example-title">采购金额TOP3采购单位及其重点合作中标单位</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>
+                        </div>
+                      </div>
+                      <!-- 中标规模分布 -->
+                      <div class="section bg-white pd-16 winner-scatter" id="winner" v-if="sections.winner.dataAlready">
+                          <div class="section-title">中标规模分布</div>
+                          <div class="section-content">
+                              <line-chart-scatter :chart-data="sections.winner.chartData"></line-chart-scatter>
+                          </div>
+                      </div>
+                      <div class="section bg-white pd-16" v-if="sections.winner.projectCountTop3 && getStatus">
+                          <div class="section-title">项目数量TOP3中标单位及其重点合作采购单位</div>
+                          <div class="section-content">
+                              <market-top3-table :table-data="sections.winner.projectCountTop3" type="count" @save="saveState"></market-top3-table>
+                          </div>
+                      </div>
+                      <div class="vip_component"
+                        v-if="!getStatus"
+                        style="height:10.8rem">
+                        <p class="example-title">项目数量TOP3中标单位及其重点合作采购单位</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-content">
+                              <market-top3-table :table-data="sections.winner.projectAmountTop3" type="amount" @save="saveState"></market-top3-table>
+                          </div>
+                      </div>
+                      <div class="vip_component"
+                        v-if="!getStatus"
+                        style="height:10.8rem">
+                        <p class="example-title">中标金额TOP3中标单位及其重点合作采购单位</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>
+                        </div>
+                      </div>
+                  </div>
+                  <div class="fixed-bottom-right clickable scroll-to-top" style="display: none;">
+                      <van-icon name="arrow-up"></van-icon>
+                  </div>
+              </div>
+          </section>
+      </div>
+      <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 class="header-action" @click="toSubManageButtonClick">订阅管理</div>
+                  </div>
+                  <div class="header-bottom">注:如需新增分析内容,请完善您的订阅关键词</div>
+              </div>
+              <div class="j-main">
+                  <keyword-component
+                      ref="keywordSelector"
+                      protype="bigmember"
+                      :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
+                      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"
+                      :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"
+                      :selectcatelist="filters.buyerclass"
+                      @cancel="cancel($event, 'buyerclass')"
+                      @confirm="confirm($event, 'buyerclass')"></cate-component>
+              </div>
+          </div>
+      </van-popup>
+  </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=//cdn-common.jianyu360.com/cdn/lib/lodash/4.17.21/lodash.min.js></script>
+<script src=//cdn-common.jianyu360.com/cdn/lib/echarts/4.8.0/echarts.min.js></script>
+<script src=//cdn-common.jianyu360.com/cdn/lib/v-charts/1.19.0/index.min.js></script>
+<script src='{{Msg "seo" "cdn"}}/big-member/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/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/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"}}/big-member/js/echarts_option.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/report-analysis/js/echarts_option.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/collection/js/analysis-report-example.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/report-analysis/js/components/projectScatter.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/report-analysis/js/components/marketTimeScatter.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/report-analysis/js/components/marketAreaScatter.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/report-analysis/js/components/marketTop3Table.js?v={{Msg "seo" "version"}}'></script>
+<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/report-analysis/js/report_analysis.js?v={{Msg "seo" "version"}}'></script>
+{{include "/common/baiducc.html"}}
+</body>
+</html>

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

@@ -0,0 +1,58 @@
+<!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='{{Msg "seo" "cdn"}}/common-module/report-analysis/css/report_analysis.css?v={{Msg "seo" "version"}}' />
+    <link rel="stylesheet" href='{{Msg "seo" "cdn"}}/common-module/diy-report/css/report-list.css?v={{Msg "seo" "version"}}' />
+</head>
+<body>
+  <div class="j-container">
+    <div class="j-main" id="analysis" v-cloak>
+      <div class="j-container">
+          <van-tabs
+              :title-active-color="tabConf.titleActiveColor"
+              :title-inactive-color="tabConf.titleInactiveColor"
+              :line-width="tabConf.lineWidth"
+              :color="tabConf.color"
+              :before-change="beforeTabChange"
+              v-model="tabActiveName">
+              <van-tab
+                  v-for="(tab, index) in tabList"
+                  :key="index"
+                  :title="tab.label"
+                  :name="tab.name"></van-tab>
+          </van-tabs>
+          <section v-show="tabActiveName === 'analysis'" class="j-main analysis-content"></section>
+          <section v-show="tabActiveName === 'history'" class="j-main history-content">
+              <report-list-mobile-component ref="list" @go-report="goToAnalysis"></report-list-mobile-component>
+          </section>
+      </div>
+  </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"}}/big-member/js/utils.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/diy-report/js/report-list.js?v={{Msg "seo" "version"}}'></script>
+<script src='{{Msg "seo" "cdn"}}/common-module/report-analysis/js/report_analysis_history.js?v={{Msg "seo" "version"}}'></script>
+
+{{include "/common/baiducc.html"}}
+</body>
+</html>