ソースを参照

fix:新增P271潜客圈进需求

zhangsiya 1 年間 前
コミット
1b82b3b47a

+ 612 - 0
apps/bigmember_pc/src/views/search/bidding/components/recommend-card.vue

@@ -0,0 +1,612 @@
+<script setup>
+import { getCurrentInstance, watch} from 'vue'
+import MarketUserScatter from '@/views/analysisReport/components/MarketUserScatter'
+import BuyerScaleScatter from '@/views/analysisReport/components/BuyerScaleScatter'
+import { SearchBidModel } from '../model'
+const {
+  recommendCardCircleModel
+} = SearchBidModel
+
+const that = getCurrentInstance().proxy
+
+const {
+  toggleAdvancedContent,
+  advancedInfo,
+  onClickInterested,
+  goToContent,
+  getProjectTitle,
+  goToReport,
+  getShowChart,
+  getNotModuleDataStatus,
+  getNowInfo,
+  nowModuleName,
+  chartCustomData,
+  showModuleChart,
+  chart,
+  test
+} = recommendCardCircleModel
+</script>
+
+<template>
+  <!-- 超前项目推荐&&市场分析报告 -->
+  <div id="jyChartCom">
+    <div class="advanced-pro-rec" v-show="advancedInfo.show">
+      <div class="p-lr-32">
+        <div class="c-a-r-top">
+          <div class="c-a-r-title">
+            <div class="r-title-text">{{ getNowInfo.title }}</div>
+            <div class="r-title-tip">
+                  <span
+                    v-if="advancedInfo.showContent || getNotModuleDataStatus"
+                  >{{ getNowInfo.desc }}</span
+                  >
+              <span
+                v-else
+                class="total-item"
+                v-for="(item, index) in advancedInfo.briefList"
+                :key="index"
+              >
+                    {{ item.key }}:<span class="highlight-text"
+              ><em>{{ item.value }}</em
+              >条</span
+              >
+                  </span>
+            </div>
+          </div>
+          <div class="c-a-r-option">
+            <div
+              v-if="nowModuleName === '市场分析报告'"
+              class="c-view-report c-view-common"
+              @click="goToReport"
+            >
+              查看完整报告
+            </div>
+            <div
+              class="c-view-interest c-view-common"
+              @click="
+                    onClickInterested(
+                      nowModuleName === '市场分析报告' ? 'B' : 'A'
+                    )
+                  "
+            >
+              感兴趣点我
+            </div>
+            <div class="c-up-or-down" @click="toggleAdvancedContent()">
+              <el-button type="text">
+                {{ advancedInfo.showContent ? '收起' : '展开' }}
+                <i
+                  class="el-icon--right"
+                  :class="
+                        'el-icon-arrow-' +
+                        (advancedInfo.showContent ? 'up' : 'down')
+                      "
+                ></i>
+              </el-button>
+            </div>
+          </div>
+        </div>
+      </div>
+      <el-collapse-transition>
+
+        <div v-show="advancedInfo.showContent">
+          <!-- 超前项目 -->
+          <div
+            class="project-module"
+            v-if="nowModuleName === '超前项目推荐'"
+            :class="{ 'remove-bl': !getShowChart }"
+          >
+            <div class="project-item">
+              <div class="left-tag total-color">累计发布</div>
+              <div>
+                    <span
+                      class="total-item"
+                      v-for="(item, index) in advancedInfo.briefList"
+                      :key="index"
+                    >
+                      {{ item.key }}:<span class="highlight-text"
+                    ><em>{{ item.value }}</em
+                    >条</span
+                    >
+                    </span>
+              </div>
+            </div>
+            <div class="project-item">
+              <div class="left-tag new-color">最新项目</div>
+              <div class="new-group">
+                    <span
+                      class="ellipsis new-item"
+                      @click="goToContent(item)"
+                      v-for="(item, index) in advancedInfo.projectList"
+                      :key="index"
+                      v-html="getProjectTitle(item)"
+                    ></span>
+              </div>
+            </div>
+          </div>
+          <!-- 市场分析报告 -->
+          <div class="custom-report" v-if="getShowChart">
+            <div class="c-a-r-top" v-if="nowModuleName === '超前项目推荐'">
+              <div class="c-a-r-title">
+                <div class="r-title-text">市场分析报告</div>
+                <div class="r-title-tip">
+                  量身定制个性化报告,分析市场竞争格局,为企业找准市场机会!
+                </div>
+              </div>
+              <div class="c-a-r-option">
+                <div
+                  class="c-view-report c-view-common"
+                  @click="goToReport"
+                >
+                  查看完整报告
+                </div>
+                <div
+                  class="c-view-interest c-view-common"
+                  @click="onClickInterested('B')"
+                >
+                  感兴趣点我
+                </div>
+              </div>
+            </div>
+            <div class="c-a-r-chart">
+              <div
+                class="chart-common"
+                id="customerChart"
+                v-show="showModuleChart !== 'customer_scale'"
+              >
+                <div class="chart-title">客户分布:</div>
+                <div class="c-c-content">
+                  <!-- <div id="chartTreeMap"></div> -->
+                  <MarketUserScatter
+                    min-height="min-height: 211px"
+                    top="-8px"
+                    :key="chart.treeMapKey"
+                    ref="treeMap"
+                    :chartData="chart.treeMapData"
+                  />
+                </div>
+              </div>
+              <div
+                class="chart-common"
+                id="winnerChart"
+                v-show="showModuleChart !== 'winner_time_distribution'"
+              >
+                <div class="chart-title">中标规模分布:</div>
+                <div class="c-c-content chart-line">
+                  <!-- <div id="chartLineChart"></div> -->
+                  <BuyerScaleScatter
+                    :key="chart.winnerLineKey"
+                    height="211px"
+                    :chartData="chart.winnerLineData"
+                  />
+                </div>
+              </div>
+              <div
+                class="chart-common"
+                id="buyerChart"
+                v-show="showModuleChart !== 'buyer_time_distribution'"
+              >
+                <div class="chart-title">采购规模分布:</div>
+                <div class="c-c-content chart-line">
+                  <!-- <div id="chartLineChartBuyer"></div> -->
+                  <BuyerScaleScatter
+                    :key="chart.buyLineKey"
+                    height="211px"
+                    :chartData="chart.buyLineData"
+                  />
+                </div>
+              </div>
+            </div>
+          </div>
+          <!-- <custom-report :show-title="nowModuleName === '超前项目推荐'" @onReport="goToReport" @onInterest="onClickInterested('B')" v-if="getShowChart" :chartCustomData="chartCustomData"></custom-report> -->
+        </div>
+      </el-collapse-transition>
+    </div>
+    <el-dialog
+      custom-class="advanced-dialog"
+      :visible.sync="advancedInfo.showDialog"
+    >
+      <img
+        class="advanced-dialog--head"
+        src="@/assets/images/advanced/dialog-head.png"
+        alt="剑鱼标讯"
+      />
+      <img
+        class="advanced-dialog--qrcode"
+        src="@/assets/images/advanced/dialog-qrcode.png"
+        alt="扫码联系客服"
+      />
+      <div class="advanced-dialog--info">
+        <h4>扫码联系客服</h4>
+        <h4>{{ advancedInfo.dialogContent }}</h4>
+        <p>专业招投标大数据服务平台丨国家信息中心大数据战略合作商</p>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+#jyChartCom {
+  background: #fff;
+  border-radius: 8px;
+
+  .advanced-pro-rec {
+    margin-top: 16px;
+    margin-bottom: 16px;
+
+    .custom-report {
+      padding: 0 16px 0 32px;
+    }
+
+    // 超前项目模块
+    $total-color: #2abed1;
+    $new-color: #ff9f40;
+
+    .total-item {
+      line-height: 24px;
+
+      em {
+        font-weight: 700;
+        font-size: 20px;
+      }
+
+      & + .total-item {
+        margin-left: 72px;
+      }
+    }
+
+    .project-module {
+      font-weight: 400;
+      font-size: 14px;
+      line-height: 22px;
+      color: #1d1d1d;
+      padding: 24px 32px;
+      border-bottom: 1px solid #ececec;
+
+      &.remove-bl {
+        border-bottom-color: transparent;
+      }
+
+      .left-tag {
+        flex-shrink: 0;
+        display: inline-block;
+        font-size: 14px;
+        line-height: 24px;
+        color: #ffffff;
+        padding: 0 9px;
+        border-radius: 0 12px 12px 0;
+        margin-right: 24px;
+
+        &.total-color {
+          background: $total-color;
+        }
+
+        &.new-color {
+          background: $new-color;
+        }
+      }
+
+      .project-item {
+        width: 100%;
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+
+        & + .project-item {
+          margin-top: 18px;
+        }
+      }
+
+      .new-group {
+        display: flex;
+        flex-direction: row;
+        width: 100%;
+      }
+
+      .new-item {
+        cursor: pointer;
+        font-size: 16px;
+        line-height: 24px;
+        max-width: calc(50% - 72px);
+
+        & + .new-item {
+          margin-left: 36px;
+        }
+
+        &::before {
+          content: '';
+          display: inline-block;
+          vertical-align: middle;
+          width: 7px;
+          height: 7px;
+          border-radius: 50%;
+          margin-right: 8px;
+          background: $new-color;
+        }
+      }
+    }
+
+    .p-lr-32 {
+      padding: 0 16px 0 32px;
+    }
+
+    .c-a-r-top {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      height: 60px;
+      border-bottom: 1px dashed #e0e0e0;
+
+      .c-a-r-title {
+        display: flex;
+        align-items: center;
+        height: 100%;
+        line-height: 21px;
+        font-family: 'Microsoft YaHei';
+        font-style: normal;
+        font-weight: 400;
+      }
+
+      .r-title-text {
+        display: flex;
+        align-items: center;
+        width: fit-content;
+        height: 95%;
+        margin-top: 5px;
+        color: #2cb7ca;
+        font-size: 16px;
+        border-bottom: 2px solid #2cb7ca;
+      }
+
+      .r-title-tip {
+        margin-top: 5px;
+        margin-left: 32px;
+        color: #686868;
+        font-size: 14px;
+      }
+    }
+
+    .c-a-r-option {
+      display: flex;
+      align-items: center;
+    }
+
+    .c-view-common {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      padding: 0 17px;
+      height: 30px;
+      font-family: 'Microsoft YaHei';
+      font-style: normal;
+      font-weight: 400;
+      font-size: 14px;
+      line-height: 22px;
+      border-radius: 4px;
+      cursor: pointer;
+    }
+
+    .c-view-report {
+      border: 1px solid #2abed1;
+      color: #2abed1;
+    }
+
+    .chart-common {
+      /* width: 590px; */
+      height: 280px;
+    }
+
+    .c-c-content {
+      width: 383px;
+      height: 211px;
+    }
+
+    .c-c-content.chart-line {
+      width: 558px;
+    }
+
+    .c-up-or-down {
+      margin-left: 32px;
+
+      .el-icon--right {
+        margin-left: 2px;
+      }
+
+      .el-button--text {
+        padding: 0;
+        font-weight: 400;
+        font-size: 14px;
+        line-height: 19px;
+        color: #686868;
+      }
+    }
+
+    .c-view-interest {
+      margin-left: 36px;
+      background: #2abed1;
+      color: #fff;
+      border: 1px solid #2abdd1;
+    }
+
+    .c-a-r-chart {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-top: 16px;
+    }
+
+    .chart-title {
+      padding: 16px 0 12px 0;
+      font-family: 'Microsoft YaHei';
+      font-style: normal;
+      font-weight: 400;
+      font-size: 16px;
+      line-height: 24px;
+      color: #1d1d1d;
+    }
+  }
+}
+.custom-report {
+  padding: 0 32px;
+
+  .c-a-r-top {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    height: 60px;
+    border-bottom: 1px dashed #e0e0e0;
+
+    .c-a-r-title {
+      display: flex;
+      align-items: center;
+      height: 100%;
+      line-height: 21px;
+      font-family: 'Microsoft YaHei';
+      font-style: normal;
+      font-weight: 400;
+    }
+
+    .r-title-text {
+      display: flex;
+      align-items: center;
+      width: fit-content;
+      height: 95%;
+      margin-top: 5px;
+      color: #2cb7ca;
+      font-size: 16px;
+      border-bottom: 2px solid #2cb7ca;
+    }
+
+    .r-title-tip {
+      margin-top: 5px;
+      margin-left: 32px;
+      color: #686868;
+      font-size: 14px;
+    }
+  }
+
+  .c-a-r-option {
+    display: flex;
+    align-items: center;
+  }
+
+  .c-view-common {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    padding: 0 17px;
+    height: 30px;
+    font-family: 'Microsoft YaHei';
+    font-style: normal;
+    font-weight: 400;
+    font-size: 14px;
+    line-height: 22px;
+    border-radius: 4px;
+    cursor: pointer;
+  }
+
+  .c-view-report {
+    border: 1px solid #2abed1;
+    color: #2abed1;
+  }
+
+  .chart-common {
+    /* width: 590px; */
+    height: 280px;
+  }
+
+  .c-c-content {
+    width: 383px;
+    height: 211px;
+  }
+
+  .c-c-content.chart-line {
+    width: 558px;
+  }
+
+  .c-view-interest {
+    margin-left: 36px;
+    background: #2abed1;
+    color: #fff;
+    border: 1px solid #2abdd1;
+  }
+
+  .c-a-r-chart {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-top: 16px;
+  }
+
+  .chart-title {
+    padding: 16px 0 12px 0;
+    font-family: 'Microsoft YaHei';
+    font-style: normal;
+    font-weight: 400;
+    font-size: 16px;
+    line-height: 24px;
+    color: #1d1d1d;
+  }
+}
+::v-deep {
+  .advanced-dialog {
+    width: 370px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    border-radius: 8px;
+
+    .el-dialog__body {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+    }
+
+    .el-dialog__close {
+      font-size: 20px;
+      font-weight: bold;
+      color: #2abdd1;
+      cursor: pointer;
+    }
+
+    .el-dialog__header,
+    .el-dialog__body {
+      padding: 0;
+    }
+
+    &--head {
+      margin-top: -58px;
+      max-width: 100%;
+    }
+
+    &--qrcode {
+      margin-top: 26px;
+      margin-bottom: 22px;
+      width: 154px;
+      height: 154px;
+    }
+
+    &--info {
+      padding: 24px 20px;
+      padding-top: 0;
+
+      h4 {
+        font-weight: 400;
+        font-size: 16px;
+        line-height: 24px;
+        text-align: center;
+        color: #1d1d1d;
+      }
+
+      p {
+        margin-top: 16px;
+        font-weight: 400;
+        font-size: 12px;
+        line-height: 18px;
+        text-align: center;
+        color: #999999;
+      }
+    }
+  }
+}
+</style>
+

+ 4 - 0
apps/bigmember_pc/src/views/search/bidding/index.vue

@@ -13,6 +13,7 @@ import ExportTip from '@/views/portrayal/components/DataExportTip.vue'
 import powerPerson from '@/components/subscribe-manager/powerPerson.vue'
 import BidrenewalDialog from '@/views/BidrenewalDialog/index.vue'
 import Empty from '@/components/common/Empty.vue'
+import recommendCard from '@/views/search/bidding/components/recommend-card.vue'
 // 导入业务模型
 import { useSearchBidModel, SearchBidModel } from './model/index'
 import { getMsgDistributor } from '@/api/modules/'
@@ -107,6 +108,9 @@ const articleRef = ref({
       <search-filter-header></search-filter-header>
       <search-bid-filter></search-bid-filter>
     </div>
+    <div >
+      <recommend-card></recommend-card>
+    </div>
     <div class='search-bidding-list-container'>
       <search-list
         class="b-rd-8px"

+ 30 - 4
apps/bigmember_pc/src/views/search/bidding/model/base.js

@@ -37,7 +37,8 @@ import { dataEmployActionsModel } from './modules/data-employ-actions'
 import { dataAddActionsModel } from './modules/data-add-actions'
 // 进行搜索前业务判断
 import { beforeSearchModel } from './modules/before-search'
-
+// 潜在客户引流--市场分析报告&&超前项目推荐数据请求
+import { recommendCardModel } from './modules/recommend-card'
 
 export default function () {
   const that = getCurrentInstance().proxy
@@ -77,7 +78,7 @@ export default function () {
 
   // 是否在工作台内
   // 本地调试,可改为工作台内isInApp = ref(true),  isInWeb = ref(false) 提交记得改回!
-  const isInApp = ref(InContainer.inApp)
+  const isInApp = ref(true) ||  ref(InContainer.inApp)
   const isInWeb = ref(InContainer.inWeb)
 
   // 是否是渠道商
@@ -663,6 +664,12 @@ export default function () {
         saveFilterToLocal()
       }
     }
+
+    //P271需求--潜客圈进引流需求
+    if(!advancedInfo.show && !getShowChart.value && inputKeywordsState.value.input) {
+      getCustomReportData({ keywords:  inputKeywordsState.value.input })
+    }
+
     // Ajax请求
     return doRunQuery(getParams(params)).then((res) => {
       afterQueryAjax(res)
@@ -764,6 +771,14 @@ export default function () {
     return originParams
   }
 
+// P271需求,潜客圈进,展示超前项目or分析报告引流
+  const recommendCardCircleModel = recommendCardModel({ that })
+  const {
+    getShowChart,
+    advancedInfo,
+    getCustomReportData,
+  } = recommendCardCircleModel
+
   /******开通超级订阅弹窗start**********/
 
   // 开通超级订阅弹窗配置
@@ -1361,13 +1376,18 @@ export default function () {
   // 切换模糊搜索
   const toggleBlurModeTip = computed( () => {
     const isBlurMode = Number(inputKeywordsState.value.searchMode) === 1
+    let canShow = isBlurMode ? false : toggleSearchBlurData.show
+    if(listState.loading) {
+      canShow = false
+    }
     const result = {
-      show: isBlurMode ? false : toggleSearchBlurData.show,
+      show: canShow,
       count: toggleSearchBlurData.count
     }
     return result
   })
 
+  // 页面初始化
   function initPage () {
     // 恢复以前选过的tab
     restoreListTabActive()
@@ -1377,6 +1397,11 @@ export default function () {
       if(!inBIPropertyIframe) {
         getLastFilter()
       }
+
+      //  P271潜客圈进--客户引流请求
+      if(inputKeywordsState.value.input) {
+        getCustomReportData({ keywords: inputKeywordsState.value.input})
+      }
     })
 
   }
@@ -1449,6 +1474,7 @@ export default function () {
     onFreeTaste,
     getLastFilter,
     toggleBlurModeTip,
-    doToggleSearchBlurMode
+    doToggleSearchBlurMode,
+    recommendCardCircleModel
   }
 }

+ 305 - 0
apps/bigmember_pc/src/views/search/bidding/model/modules/recommend-card.js

@@ -0,0 +1,305 @@
+import { reactive, ref, toRefs, computed } from 'vue'
+import { leadGetDate, ajaxSetLeadGetDateRecord } from '@/api/modules/'
+import {
+  dateFormatter,
+  openSelfLink,
+  replaceKeyword,
+  formatPrice,
+} from '@/utils/'
+import { tryCallHooks } from '@jianyu/easy-inject-qiankun'
+import { difference } from 'lodash'
+
+
+export function recommendCardModel (modelConfig) {
+  const { that } = modelConfig
+
+  const advancedInfo = reactive( {
+    show: false,
+    showContent: false,
+    showDialog: false,
+    dialogContent: '体验超前项目推荐服务!',
+    moduleInfo: {
+      超前项目推荐: {
+        title: '超前项目推荐',
+        desc: '提前推送超前项目,优先对接项目负责人'
+      },
+      市场分析报告: {
+        title: '市场分析报告',
+        desc: '量身定制个性化报告,分析市场竞争格局,为企业找准市场机会!'
+      }
+    },
+    briefList: [],
+    projectList: []
+  })
+
+  const chartCustomData = ref({})
+
+  const chart = reactive( {
+      treeMapKey: 1,
+      treeMapData: [],
+      buyLineKey: 1,
+      buyLineData: {},
+      winnerLineKey: 1,
+      winnerLineData: {}
+  })
+
+  const nowModuleName = computed(() => {
+    if (
+      advancedInfo.briefList.length ||
+      advancedInfo.projectList.length
+    ) {
+      return '超前项目推荐'
+    } else {
+      return '市场分析报告'
+    }
+  })
+  // 获取当前模块展示文本信息
+  const getNowInfo = computed(() => {
+    return advancedInfo.moduleInfo[nowModuleName.value]
+  })
+
+  // 获取当前模块缩小后是否有数据展示
+  const getNotModuleDataStatus = computed(() => {
+    if (nowModuleName.value === '超前项目推荐') {
+      return !advancedInfo.briefList.length
+    } else {
+      return true
+    }
+  })
+
+  // 是否展示市场分析报告模块
+  const getShowChart = computed(() => {
+    return Object.keys(chartCustomData.value).length > 0
+  })
+  // 当前第一位展示内容标识
+  const showModuleChart = computed(() => {
+    const chartKeyArr = Object.keys(chartCustomData.value)
+    const fieldText = getRandomArrayElements(chartKeyArr, 2)
+    const noShowFiled = difference(chartKeyArr, fieldText)
+    return noShowFiled[0]
+  })
+  // 市场分析报告&&超前项目推荐数据请求
+  function getCustomReportData(conf) {
+    const { keywords } = conf
+    const params = {
+      dType: 0,
+      keyWords: keywords
+    }
+    leadGetDate(params).then(res => {
+      const { error_code: code = 0, data } =  res
+      if (code === 0 && data && Object.keys(data).length > 0) {
+        advancedInfo.briefList = (data?.ahead?.subTypeCount || []).map(
+          (v) => {
+            v.value = v.doc_count
+            return v
+          }
+        )
+
+        advancedInfo.projectList = data?.ahead?.projectTop2 || []
+
+        chartCustomData.value = data.custom || {}
+
+        if (
+          advancedInfo.briefList.length ||
+          advancedInfo.projectList.length ||
+          Object.keys(chartCustomData.value).length
+        ) {
+
+          advancedInfo.show = true
+          advancedInfo.showContent = false
+
+          setTimeout(() => {
+            advancedInfo.showContent = true
+            setChartData(data.custom)
+          }, 1000)
+        }
+      }
+    })
+  }
+  // 市场分析报告图表
+  function setChartData(newval) {
+    const chartKeyArr = Object.keys(newval)
+    chartKeyArr.forEach((item) => {
+      if (item === 'customer_scale') {
+        const data = newval.customer_scale.map((item) => {
+          return {
+            ...item,
+            name: item.buyclass,
+            value: item.total,
+            amount: formatPrice(item.amount / 10000)
+          }
+        })
+        chart.treeMapData = data
+        chart.treeMapKey = new Date().getTime()
+      } else if (item === 'winner_time_distribution') {
+        const data = {
+          columns: ['采购规模分布', '采购总金额占比', '采购单位总数占比'],
+          rows: []
+        }
+        let total = 0
+        const chartLIst = newval.winner_time_distribution
+        if (Array.isArray(chartLIst)) {
+          const field = {
+            [data.columns[0]]: 'key',
+            [data.columns[1]]: 'total_amount',
+            [data.columns[2]]: 'total_number'
+          }
+          chartLIst.forEach((item) => {
+            const row = {}
+            data.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]]
+              }
+            })
+            data.rows.push(row)
+          })
+        }
+        if (total) {
+          data.rows.reverse()
+          chart.buyLineData = data
+          chart.buyLineKey = new Date().getTime()
+        }
+      } else if (item === 'buyer_time_distribution') {
+        const data = {
+          columns: ['中标规模分布', '中标总金额占比', '中标单位总数占比'],
+          rows: []
+        }
+        let total = 0
+        const buyerclassList = newval.buyer_time_distribution
+        if (Array.isArray(buyerclassList)) {
+          const field = {
+            [data.columns[0]]: 'key',
+            [data.columns[1]]: 'total_amount',
+            [data.columns[2]]: 'total_number'
+          }
+          buyerclassList.forEach((item) => {
+            const row = {}
+            data.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]]
+              }
+            })
+            data.rows.push(row)
+          })
+        }
+        if (total) {
+          data.rows.reverse()
+          chart.winnerLineData = data
+          chart.winnerLineKey = new Date().getTime()
+        }
+      }
+    })
+  }
+
+  // 收起或打开 展示超前项目、模块
+  function toggleAdvancedContent(type) {
+    if (typeof type !== 'boolean') {
+      type = !advancedInfo.showContent
+    }
+    advancedInfo.showContent = type
+  }
+  // 展示弹窗
+  function showAdvancedDialog(title = '体验超前项目推荐服务!') {
+    advancedInfo.dialogContent = title
+    advancedInfo.showDialog = true
+  }
+
+  // 点击感兴趣
+  function onClickInterested(type) {
+    const title = type === 'A' ? '体验超前项目推荐服务!' : '为您量身定制个性化报告!'
+    showAdvancedDialog(title)
+    try {
+      ajaxSetLeadGetDateRecord({ type })
+    } catch (e) {
+      console.warn(e)
+    }
+  }
+  // 查看完整报告
+  async function goToReport() {
+    try {
+      await ajaxSetLeadGetDateRecord({ type: 'B' })
+    } catch (e) {
+      console.warn(e)
+    }
+    tryCallHooks({
+      fn: () => {
+        that.$BRACE.methods.open({
+          route: {
+            link: '/desktop/report_analysis',
+            appName: 'big',
+            appType: 'qiankun'
+          }
+        })
+      },
+      spareFn: () => {
+        window.open(
+          '/swordfish/page_big_pc/desktop/report_analysis?tab=analysis'
+        )
+      }
+    })
+  }
+  // 查看项目详情
+  function goToContent(item) {
+    try {
+      ajaxSetLeadGetDateRecord({ type: 'A' })
+    } catch (e) {
+      console.warn(e)
+    }
+    let goURL = '/article/content/' + item._id + '.html'
+    if (Array.isArray(item.keyWord)) {
+      goURL += '?kds=' + encodeURIComponent(item.keyWord.join('+'))
+    }
+    window.open(goURL)
+  }
+  // 匹配高亮文本信息
+  function getProjectTitle({ title, keyWord }) {
+    return replaceKeyword(title, keyWord, [
+      '<span class="highlight-text">',
+      '</span>'
+    ])
+  }
+  // /* 随机获取数组中的数据*/
+  function getRandomArrayElements(arr, count) {
+    const shuffled = arr.slice(0)
+    let i = arr.length
+    const min = i - count
+    let temp
+    let index
+    while (i-- > min) {
+      index = Math.floor((i + 1) * Math.random())
+      temp = shuffled[index]
+      shuffled[index] = shuffled[i]
+      shuffled[i] = temp
+    }
+    return shuffled.slice(min)
+  }
+
+  return {
+    getCustomReportData,
+    toggleAdvancedContent,
+    advancedInfo,
+    onClickInterested,
+    goToContent,
+    getProjectTitle,
+    goToReport,
+    getShowChart,
+    getNotModuleDataStatus,
+    getNowInfo,
+    nowModuleName,
+    chartCustomData,
+    showModuleChart,
+    chart
+  }
+}