瀏覽代碼

联系人数据新增关联线索、关联项目、关联客户情况统计,联系人跟进情况统计

qymljy 4 月之前
父節點
當前提交
392a415ffb

+ 2 - 0
src/HDrpManagement/contactData/components/btnSelectInfo.vue

@@ -49,6 +49,8 @@ export default {
         const now = new Date();
         const monthStartDate = new Date(now.getFullYear(), now.getMonth());
         this.dateData = [monthStartDate,monthStartDate]
+      }else if (data == '全部'){
+        this.dateData = []
       }
       this.$emit('btnClick',data)
     },

+ 1 - 1
src/HDrpManagement/contactData/components/contactsAddAnalysis.vue

@@ -18,7 +18,7 @@
               :end-placeholder="$t('结束月份')">
           </el-date-picker>
         </div>
-        <fullScreen class="inline-16"  domId="contactsAddAnalysisFull" @onFull="onFull" @backFull="backFull"  ></fullScreen>
+<!--        <fullScreen class="inline-16"  domId="contactsAddAnalysisFull" @onFull="onFull" @backFull="backFull"  ></fullScreen>-->
       </template>
       <template slot="content">
         <div :style="{height:heightDiv}">

+ 1 - 1
src/HDrpManagement/contactData/components/contactsFollowAnalysis.vue

@@ -18,7 +18,7 @@
               :end-placeholder="$t('结束月份')">
           </el-date-picker>
         </div>
-        <fullScreen class="inline-16"  domId="contactsFollowAnalysisFull" @onFull="onFull" @backFull="backFull"  ></fullScreen>
+<!--        <fullScreen class="inline-16"  domId="contactsFollowAnalysisFull" @onFull="onFull" @backFull="backFull"  ></fullScreen>-->
       </template>
       <template slot="content">
         <div :style="{height:heightDiv}">

+ 247 - 0
src/HDrpManagement/contactData/components/statisticsOfClues.vue

@@ -0,0 +1,247 @@
+<template>
+  <div>
+    <dataTemPlate ref="dataTemPlateRef" :isTitle="true" title="联系人关联线索情况统计" @list="listData" id="statisticsOfCluesFull">
+      <template slot="operation">
+        <btnSelect ref="btnSelectRef" @btnClick="btnClick" class="inline-16"  :btnTitle="['全部','本年']" dateType="本年"></btnSelect>
+<!--        <fullScreen class="inline-16"  domId="statisticsOfCustomerFull" @onFull="onFull" @backFull="backFull"  ></fullScreen>-->
+      </template>
+      <template slot="content">
+        <div style="display: flex;justify-content: space-between" :style="{height:heightDiv}">
+          <div ref="statisticsOfCluesChart" :style="{height: heightChart}"></div>
+          <div style="width: 70%"  :style="{height: heightDiv}">
+            <tableDetail :layout="tablecols" :data="tableList" :opwidth="200" :custom="true" fixed-name="operation" :height="heightTable">
+              <template v-slot:customcol="scope">
+                <div v-if="scope.column.columnname === 'tag'">
+                  <div v-if="scope.column.data.tag">
+                    <div v-if="scope.column.data.tag.length > 0">
+                      <el-tag v-for="item in scope.column.data.tag" :key="item.index" :type="item === '支持者'?'warning':item === '反对者'?'danger':''" size="mini" style="margin:0 5px 0 0">
+                        {{$t(item)}}
+                      </el-tag>
+                    </div>
+                    <div v-else>--</div>
+                  </div>
+                  <div v-else>--</div>
+                </div>
+                <div v-else>{{scope.column.data[scope.column.columnname]||scope.column.columnname === 'operation' ? scope.column.data[scope.column.columnname] : '--'}}</div>
+              </template>
+              <template v-slot:opreation="scope">
+                <drawerTemp class="inline-16" v-if="detailPath" :data="scope.data" :detailPath="detailPath" :idName="idName"  :disabled="isFull"
+                            :listqueryid="listqueryid" :total="total" :overview="true"></drawerTemp>
+              </template>
+            </tableDetail>
+            <div style="margin-top:10px;text-align:right">
+              <el-pagination
+                  background
+                  small
+                  @size-change="handleSizeChange"
+                  @current-change="handleCurrentChange"
+                  :current-page="currentPage"
+                  :page-size="paramTable.content.pageSize"
+                  layout="total, prev, pager, next, jumper"
+                  :total="total">
+              </el-pagination>
+            </div>
+          </div>
+        </div>
+      </template>
+    </dataTemPlate>
+  </div>
+</template>
+
+<script>
+import dataTemPlate from '@/components/dataTemplate/index'
+import btnSelect from "./btnSelectInfo"
+import {Pie} from "@antv/g2plot";
+import fullScreen from "@/views/salesData/components/fullScreen";
+export default {
+  name: "statisticsOfClues",
+  components:{dataTemPlate,btnSelect,fullScreen,
+    drawerTemp:() =>  import('@/components/normal-basic-layout/drawerDetail/index')},
+  data() {
+    return {
+      detailPath:{
+        path:'/contactDataDetail'
+      },
+      idName:'sys_phonebookid',
+      isFull:false,
+      listqueryid:'',
+      paramChart:{
+        "id": 2025073115102102,
+        "content": {
+          "type": 1,
+          "dataid": 58,
+          "dateType": "本年",
+          "where": {
+            "begdate": "",
+            "enddate": "",
+            "isleave": "1"
+          }
+        },
+      },
+      paramTable:{
+        "id": 2025073115102902,
+        "content": {
+          "type": 1,
+          "dataid": 58,
+          "pageSize": 20,
+          "pageNumber": 1,
+          "dateType": "本年",
+          "where": {
+            "begdate": "",
+            "enddate": "",
+            "isleave": "1",
+            "isorderclue": ""
+          }
+        },
+      },
+      tablecols:[],
+      tableList:[],
+      total:0,
+      currentPage:0,
+      chartList:[],
+      chartCluesMap:null,
+      typesData:[],
+      heightChart:'100%',
+      heightDiv:'400px',
+      heightTable:'360px'
+    }
+  },
+  methods:{
+    listData(dataid,type,isleave,state,init){
+      this.paramChart.content.dataid = dataid
+      this.paramTable.content.dataid = dataid
+      this.paramChart.content.type = type
+      this.paramTable.content.type = type
+      this.paramChart.content.where.isleave = isleave
+      this.paramTable.content.where.isleave = isleave
+      this.chartData(init,state)
+      this.tableData()
+    },
+    async chartData(init,state){
+      const res = await this.$api.requested(this.paramChart)
+      this.chartList = res.data
+      if (init) {
+        this.chartCluesMap = new Pie(this.$refs.statisticsOfCluesChart, {
+          appendPadding: 10,
+          data:this.chartList,
+          angleField: 'ratio',
+          colorField: 'key',
+          radius: 1,
+          innerRadius: 0.64,
+          label:{
+            formatter: (datum) => `${datum.ratio}%`
+          },
+          tooltip:{
+            formatter: (datum) => {
+              return { name: datum.key, value: datum.ratio + '%' };
+            },
+          },
+          statistic: {
+            title: {
+              offsetY: -4,
+              style: {
+                fontSize:'16px'
+              },
+              content:this.$t('线索总数')
+            },
+            content: {
+              offsetY: 4,
+              style: {
+                whiteSpace: 'pre-wrap',
+                overflow: 'hidden',
+                textOverflow: 'ellipsis',
+                fontSize:'16px'
+              },
+              customHtml: (container, view, datum, data) => {
+                const text = data[0].totalqty
+                return text
+              },
+            },
+          },
+          legend: {
+            position:'bottom'
+          },
+          // 添加 中心统计文本 交互
+          interactions: [{ type: 'element-single-selected' },{ type: 'element-active' }],
+        });
+        this.chartCluesMap.on('element:click',(v) => {
+          if (v.data.data.key != this.paramTable.content.where.isorderclue) {
+            this.paramTable.content.pageNumber = 1
+            this.paramTable.content.where.isorderclue = v.data.data.key
+            this.tableData()
+          } else {
+            this.paramTable.content.pageNumber = 1
+            this.paramTable.content.where.isorderclue = ''
+            this.tableData()
+          }
+        })
+        this.chartCluesMap.render();
+      } else {
+        this.chartCluesMap.changeData(this.chartList)
+      }
+    },
+    async tableData(){
+      const res = await this.$api.requested(this.paramTable)
+      this.tableList = res.data
+      this.total = res.total
+      this.currentPage = res.pageNumber
+      this.listqueryid = res.listqueryid
+    },
+    btnClick(dateType,dateData){
+      this.paramTable.content.pageNumber = 1
+      if (dateType){
+        this.paramChart.content.dateType = dateType
+        this.paramTable.content.dateType = dateType
+      }else {
+        this.paramTable.content.where.begdate = dateData[0]
+        this.paramTable.content.where.enddate = dateData[1]
+        this.paramChart.content.where.begdate = dateData[0]
+        this.paramChart.content.where.enddate = dateData[1]
+      }
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    handleSizeChange(val) {
+      // console.log(`每页 ${val} 条`);
+      this.paramTable.content.pageSize = val
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    handleCurrentChange(val) {
+      // console.log(`当前页: ${val}`);
+      this.paramTable.content.pageNumber = val
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    selectChange(){
+      this.paramChart.content.where.type = this.paramTable.content.where.type
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    async queryType(){
+      if (this.typesData.length == 0){
+        const res = await this.$store.dispatch("optiontypeselect", "customertypemx")
+        this.typesData = res.data
+      }
+    },
+    /*全屏*/
+    onFull(){
+      this.heightChart = this.windowWidth > 1136 ? 'calc(100vh - 70px)':'calc(100vh - 123px)'
+      this.heightDiv = this.windowWidth > 1136 ? 'calc(100vh - 70px)':'calc(100vh - 123px)'
+      this.heightTable = this.windowWidth > 1136 ? 'calc(100vh - 100px)':'calc(100vh - 153px)'
+      this.isFull = true
+    },
+    /*退出全屏*/
+    backFull(val){
+      this.heightChart = '100%'
+      this.heightDiv = '400px'
+      this.heightTable = '360px'
+      this.isFull = false
+      this.$emit('backFull',val)
+    }
+  },
+  created() {
+    this.tablecols = this.tool.tabelCol(this.$route.name).contactsTable.tablecols
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 271 - 0
src/HDrpManagement/contactData/components/statisticsOfCustomer.vue

@@ -0,0 +1,271 @@
+<template>
+  <div>
+    <dataTemPlate ref="dataTemPlateRef" :isTitle="true" title="联系人关联客户情况统计" @list="listData" id="statisticsOfCustomerFull">
+      <template slot="operation">
+        <div class="mt-10 inline-16">
+          <label class="search__label">{{ $t("客户类型") }}:</label>
+          <el-select
+              class="inline-16"
+              v-model="paramTable.content.where.type"
+              size="small"
+              :placeholder="$t('请选择')"
+              @focus="queryType"
+              @change="selectChange"
+              clearable
+          >
+            <el-option
+                v-for="item in typesData"
+                :key="item.value"
+                :label="$t(item.value)"
+                :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </div>
+        <btnSelect ref="btnSelectRef" @btnClick="btnClick" class="inline-16"  :btnTitle="['全部','本年']" dateType="本年"></btnSelect>
+<!--        <fullScreen class="inline-16"  domId="statisticsOfCustomerFull" @onFull="onFull" @backFull="backFull"  ></fullScreen>-->
+      </template>
+      <template slot="content">
+        <div style="display: flex;justify-content: space-between" :style="{height:heightDiv}">
+          <div ref="statisticsOfCustomerChart" :style="{height: heightChart}"></div>
+          <div style="width: 70%"  :style="{height: heightDiv}">
+            <tableDetail :layout="tablecols" :data="tableList" :opwidth="200" :custom="true" fixed-name="operation" :height="heightTable">
+              <template v-slot:customcol="scope">
+                <div v-if="scope.column.columnname === 'tag'">
+                  <div v-if="scope.column.data.tag">
+                    <div v-if="scope.column.data.tag.length > 0">
+                      <el-tag v-for="item in scope.column.data.tag" :key="item.index" :type="item === '支持者'?'warning':item === '反对者'?'danger':''" size="mini" style="margin:0 5px 0 0">
+                        {{$t(item)}}
+                      </el-tag>
+                    </div>
+                    <div v-else>--</div>
+                  </div>
+                  <div v-else>--</div>
+                </div>
+                <div v-else>{{scope.column.data[scope.column.columnname]||scope.column.columnname === 'operation' ? scope.column.data[scope.column.columnname] : '--'}}</div>
+              </template>
+              <template v-slot:opreation="scope">
+                <drawerTemp class="inline-16" v-if="detailPath" :data="scope.data" :detailPath="detailPath" :idName="idName"  :disabled="isFull"
+                            :listqueryid="listqueryid" :total="total" :overview="true"></drawerTemp>
+              </template>
+            </tableDetail>
+            <div style="margin-top:10px;text-align:right">
+              <el-pagination
+                  background
+                  small
+                  @size-change="handleSizeChange"
+                  @current-change="handleCurrentChange"
+                  :current-page="currentPage"
+                  :page-size="paramTable.content.pageSize"
+                  layout="total, prev, pager, next, jumper"
+                  :total="total">
+              </el-pagination>
+            </div>
+          </div>
+        </div>
+      </template>
+    </dataTemPlate>
+  </div>
+</template>
+
+<script>
+import dataTemPlate from '@/components/dataTemplate/index'
+import btnSelect from "./btnSelectInfo"
+import {Pie} from "@antv/g2plot";
+import fullScreen from "@/views/salesData/components/fullScreen";
+export default {
+  name: "statisticsOfCustomer",
+  components:{dataTemPlate,btnSelect,fullScreen,
+    drawerTemp:() =>  import('@/components/normal-basic-layout/drawerDetail/index')},
+  data() {
+    return {
+      detailPath:{
+        path:'/contactDataDetail'
+      },
+      idName:'sys_phonebookid',
+      isFull:false,
+      listqueryid:'',
+      paramChart:{
+        "id": 2025080114334802,
+        "content": {
+          "type": 1,
+          "dataid": 58,
+          "dateType": "本年",
+          "where": {
+            "begdate": "",
+            "enddate": "",
+            "isleave": "1",
+            "type": ""
+          }
+        },
+      },
+      paramTable:{
+        "id": 2025080114335402,
+        "content": {
+          "type": 1,
+          "dataid": 58,
+          "pageSize": 20,
+          "pageNumber": 1,
+          "dateType": "本年",
+          "where": {
+            "begdate": "",
+            "enddate": "",
+            "isleave": "1",
+            "iscustomers": "",
+            "type": ""
+          }
+        },
+      },
+      tablecols:[],
+      tableList:[],
+      total:0,
+      currentPage:0,
+      chartList:[],
+      chartMap:null,
+      typesData:[],
+      heightChart:'100%',
+      heightDiv:'400px',
+      heightTable:'360px'
+    }
+  },
+  methods:{
+    listData(dataid,type,isleave,state,init){
+      console.log(dataid,'dataid')
+      console.log(type,'type')
+      this.paramChart.content.dataid = dataid
+      this.paramTable.content.dataid = dataid
+      this.paramChart.content.type = type
+      this.paramTable.content.type = type
+      this.paramChart.content.where.isleave = isleave
+      this.paramTable.content.where.isleave = isleave
+      this.chartData(init,state)
+      this.tableData()
+    },
+    async chartData(init,state){
+      const res = await this.$api.requested(this.paramChart)
+      this.chartList = res.data
+      if (init) {
+        this.chartMap = new Pie(this.$refs.statisticsOfCustomerChart, {
+          appendPadding: 10,
+          data:this.chartList,
+          angleField: 'ratio',
+          colorField: 'key',
+          radius: 1,
+          innerRadius: 0.64,
+          label:{
+            formatter: (datum) => `${datum.ratio}%`
+          },
+          tooltip:{
+            formatter: (datum) => {
+              return { name: datum.key, value: datum.ratio + '%' };
+            },
+          },
+          statistic: {
+            title: {
+              offsetY: -4,
+              style: {
+                fontSize:'16px'
+              },
+              content:this.$t('客户总数')
+            },
+            content: {
+              offsetY: 4,
+              style: {
+                whiteSpace: 'pre-wrap',
+                overflow: 'hidden',
+                textOverflow: 'ellipsis',
+                fontSize:'16px'
+              },
+              customHtml: (container, view, datum, data) => {
+                const text = data[0].totalqty
+                return text
+              },
+            },
+          },
+          legend: {
+            position:'bottom'
+          },
+          // 添加 中心统计文本 交互
+          interactions: [{ type: 'element-single-selected' },{ type: 'element-active' }],
+        });
+        this.chartMap.on('element:click',(v) => {
+          if (v.data.data.key != this.paramTable.content.where.iscustomers) {
+            this.paramTable.content.pageNumber = 1
+            this.paramTable.content.where.iscustomers = v.data.data.key
+            this.tableData()
+          } else {
+            this.paramTable.content.pageNumber = 1
+            this.paramTable.content.where.iscustomers = ''
+            this.tableData()
+          }
+        })
+        this.chartMap.render();
+      } else {
+        this.chartMap.changeData(this.chartList)
+      }
+    },
+    async tableData(){
+      const res = await this.$api.requested(this.paramTable)
+      this.tableList = res.data
+      this.total = res.total
+      this.currentPage = res.pageNumber
+      this.listqueryid = res.listqueryid
+    },
+    btnClick(dateType,dateData){
+      this.paramTable.content.pageNumber = 1
+      if (dateType){
+        this.paramChart.content.dateType = dateType
+        this.paramTable.content.dateType = dateType
+      }else {
+        this.paramTable.content.where.begdate = dateData[0]
+        this.paramTable.content.where.enddate = dateData[1]
+        this.paramChart.content.where.begdate = dateData[0]
+        this.paramChart.content.where.enddate = dateData[1]
+      }
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    handleSizeChange(val) {
+      // console.log(`每页 ${val} 条`);
+      this.paramTable.content.pageSize = val
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    handleCurrentChange(val) {
+      // console.log(`当前页: ${val}`);
+      this.paramTable.content.pageNumber = val
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    selectChange(){
+      this.paramChart.content.where.type = this.paramTable.content.where.type
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    async queryType(){
+      if (this.typesData.length == 0){
+        const res = await this.$store.dispatch("optiontypeselect", "customertypemx")
+        this.typesData = res.data
+      }
+    },
+    /*全屏*/
+    onFull(){
+      this.heightChart = this.windowWidth > 1136 ? 'calc(100vh - 70px)':'calc(100vh - 123px)'
+      this.heightDiv = this.windowWidth > 1136 ? 'calc(100vh - 70px)':'calc(100vh - 123px)'
+      this.heightTable = this.windowWidth > 1136 ? 'calc(100vh - 100px)':'calc(100vh - 153px)'
+      this.isFull = true
+    },
+    /*退出全屏*/
+    backFull(val){
+      this.heightChart = '100%'
+      this.heightDiv = '400px'
+      this.heightTable = '360px'
+      this.isFull = false
+      this.$emit('backFull',val)
+    }
+  },
+  created() {
+    this.tablecols = this.tool.tabelCol(this.$route.name).contactsTable.tablecols
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 243 - 0
src/HDrpManagement/contactData/components/statisticsOfFollow.vue

@@ -0,0 +1,243 @@
+<template>
+  <div>
+    <dataTemPlate ref="dataTemPlateRef" :isTitle="true" title="联系人跟进线索情况统计" @list="listData" id="statisticsOfFollowFull">
+      <template slot="operation">
+        <btnSelect ref="btnSelectRef" @btnClick="btnClick" class="inline-16"  :btnTitle="['全部','本年']" dateType="本年"></btnSelect>
+        <!--        <fullScreen class="inline-16"  domId="statisticsOfCustomerFull" @onFull="onFull" @backFull="backFull"  ></fullScreen>-->
+      </template>
+      <template slot="content">
+        <div style="display: flex;justify-content: space-between" :style="{height:heightDiv}">
+          <div ref="statisticsOfFollowChart" :style="{height: heightChart}"></div>
+          <div style="width: 70%"  :style="{height: heightDiv}">
+            <tableDetail :layout="tablecols" :data="tableList" :opwidth="200" :custom="true" fixed-name="operation" :height="heightTable">
+              <template v-slot:customcol="scope">
+                <div v-if="scope.column.columnname === 'tag'">
+                  <div v-if="scope.column.data.tag">
+                    <div v-if="scope.column.data.tag.length > 0">
+                      <el-tag v-for="item in scope.column.data.tag" :key="item.index" :type="item === '支持者'?'warning':item === '反对者'?'danger':''" size="mini" style="margin:0 5px 0 0">
+                        {{$t(item)}}
+                      </el-tag>
+                    </div>
+                    <div v-else>--</div>
+                  </div>
+                  <div v-else>--</div>
+                </div>
+                <div v-else>{{scope.column.data[scope.column.columnname]||scope.column.columnname === 'operation' ? scope.column.data[scope.column.columnname] : '--'}}</div>
+              </template>
+              <template v-slot:opreation="scope">
+                <drawerTemp class="inline-16" v-if="detailPath" :data="scope.data" :detailPath="detailPath" :idName="idName"  :disabled="isFull"
+                            :listqueryid="listqueryid" :total="total" :overview="true"></drawerTemp>
+              </template>
+            </tableDetail>
+            <div style="margin-top:10px;text-align:right">
+              <el-pagination
+                  background
+                  small
+                  @size-change="handleSizeChange"
+                  @current-change="handleCurrentChange"
+                  :current-page="currentPage"
+                  :page-size="paramTable.content.pageSize"
+                  layout="total, prev, pager, next, jumper"
+                  :total="total">
+              </el-pagination>
+            </div>
+          </div>
+        </div>
+      </template>
+    </dataTemPlate>
+  </div>
+</template>
+
+<script>
+import dataTemPlate from '@/components/dataTemplate/index'
+import btnSelect from "./btnSelectInfo"
+import {Pie} from "@antv/g2plot";
+import fullScreen from "@/views/salesData/components/fullScreen";
+export default {
+  name: "statisticsOfFollow",
+  components:{dataTemPlate,btnSelect,fullScreen,
+    drawerTemp:() =>  import('@/components/normal-basic-layout/drawerDetail/index')},
+  data() {
+    return {
+      detailPath:{
+        path:'/contactDataDetail'
+      },
+      idName:'sys_phonebookid',
+      isFull:false,
+      listqueryid:'',
+      paramChart:{
+        "id": 2025072814054402,
+        "content": {
+          "type": 1,
+          "dataid": 58,
+          "username": JSON.parse(sessionStorage.getItem('active_account')).name,
+          "dateType": "本年",
+          "where": {
+            "begdate": "",
+            "enddate": "",
+            "isleave": "1",
+          }
+        },
+      },
+      paramTable:{
+        "id": 2025072814055602,
+        "content": {
+          "type": 1,
+          "dataid": 58,
+          "pageSize": 20,
+          "pageNumber": 1,
+          "dateType": "本年",
+          "username": JSON.parse(sessionStorage.getItem('active_account')).name,
+          "where": {
+            "begdate": "",
+            "enddate": "",
+            "isleave": "1",
+            "isfollowup": "",
+          }
+        },
+      },
+      tablecols:[],
+      tableList:[],
+      total:0,
+      currentPage:0,
+      chartList:[],
+      chartMap:null,
+      typesData:[],
+      heightChart:'100%',
+      heightDiv:'400px',
+      heightTable:'360px'
+    }
+  },
+  methods:{
+    listData(dataid,type,isleave,state,init){
+      this.paramChart.content.dataid = dataid
+      this.paramTable.content.dataid = dataid
+      this.paramChart.content.type = type
+      this.paramTable.content.type = type
+      this.paramChart.content.where.isleave = isleave
+      this.paramTable.content.where.isleave = isleave
+      this.chartData(init,state)
+      this.tableData()
+    },
+    async chartData(init,state){
+      const res = await this.$api.requested(this.paramChart)
+      this.chartList = res.data
+      if (init) {
+        this.chartMap = new Pie(this.$refs.statisticsOfFollowChart, {
+          appendPadding: 10,
+          data:this.chartList,
+          angleField: 'ratio',
+          colorField: 'key',
+          radius: 1,
+          innerRadius: 0.64,
+          label:{
+            formatter: (datum) => `${datum.ratio}%`
+          },
+          tooltip:{
+            formatter: (datum) => {
+              return { name: datum.key, value: datum.ratio + '%' };
+            },
+          },
+          statistic: {
+            title: {
+              offsetY: -4,
+              style: {
+                fontSize:'16px'
+              },
+              content:this.$t('跟进总数')
+            },
+            content: {
+              offsetY: 4,
+              style: {
+                whiteSpace: 'pre-wrap',
+                overflow: 'hidden',
+                textOverflow: 'ellipsis',
+                fontSize:'16px'
+              },
+              customHtml: (container, view, datum, data) => {
+                const text = data[0].totalqty
+                return text
+              },
+            },
+          },
+          legend: {
+            position:'bottom'
+          },
+          // 添加 中心统计文本 交互
+          interactions: [{ type: 'element-single-selected' },{ type: 'element-active' }],
+        });
+        this.chartMap.on('element:click',(v) => {
+          if (v.data.data.key != this.paramTable.content.where.isfollowup) {
+            this.paramTable.content.pageNumber = 1
+            this.paramTable.content.where.isfollowup = v.data.data.key
+            this.tableData()
+          } else {
+            this.paramTable.content.pageNumber = 1
+            this.paramTable.content.where.isfollowup = ''
+            this.tableData()
+          }
+        })
+        this.chartMap.render();
+      } else {
+        this.chartMap.changeData(this.chartList)
+      }
+    },
+    async tableData(){
+      const res = await this.$api.requested(this.paramTable)
+      this.tableList = res.data
+      this.total = res.total
+      this.currentPage = res.pageNumber
+      this.listqueryid = res.listqueryid
+    },
+    btnClick(dateType,dateData){
+      this.paramTable.content.pageNumber = 1
+      if (dateType){
+        this.paramChart.content.dateType = dateType
+        this.paramTable.content.dateType = dateType
+      }else {
+        this.paramTable.content.where.begdate = dateData[0]
+        this.paramTable.content.where.enddate = dateData[1]
+        this.paramChart.content.where.begdate = dateData[0]
+        this.paramChart.content.where.enddate = dateData[1]
+      }
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    handleSizeChange(val) {
+      // console.log(`每页 ${val} 条`);
+      this.paramTable.content.pageSize = val
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    handleCurrentChange(val) {
+      // console.log(`当前页: ${val}`);
+      this.paramTable.content.pageNumber = val
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    selectChange(){
+      this.paramChart.content.where.type = this.paramTable.content.where.type
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    /*全屏*/
+    onFull(){
+      this.heightChart = this.windowWidth > 1136 ? 'calc(100vh - 70px)':'calc(100vh - 123px)'
+      this.heightDiv = this.windowWidth > 1136 ? 'calc(100vh - 70px)':'calc(100vh - 123px)'
+      this.heightTable = this.windowWidth > 1136 ? 'calc(100vh - 100px)':'calc(100vh - 153px)'
+      this.isFull = true
+    },
+    /*退出全屏*/
+    backFull(val){
+      this.heightChart = '100%'
+      this.heightDiv = '400px'
+      this.heightTable = '360px'
+      this.isFull = false
+      this.$emit('backFull',val)
+    }
+  },
+  created() {
+    this.tablecols = this.tool.tabelCol(this.$route.name).contactsTable.tablecols
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 302 - 0
src/HDrpManagement/contactData/components/statisticsOfProject.vue

@@ -0,0 +1,302 @@
+<template>
+  <div>
+    <dataTemPlate ref="dataTemPlateRef" :isTitle="true" title="联系人关联项目情况统计" @list="listData" id="statisticsOfProjectFull">
+      <template slot="operation">
+        <div class="mt-10 inline-16">
+          <label class="search__label">{{ $t("项目类型") }}:</label>
+          <el-select
+              class="inline-16"
+              v-model="paramTable.content.where.projecttype"
+              size="small"
+              :placeholder="$t('请选择')"
+              @focus="queryType"
+              @change="selectChange"
+              clearable
+          >
+            <el-option
+                v-for="item in typesData"
+                :key="item.value"
+                :label="$t(item.value)"
+                :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </div>
+        <div class="mt-10 inline-16">
+          <label  class="search__label">{{$t(`项目状态`)}}:</label>
+          <el-select class="inline-24" v-model="paramTable.content.where.status" :placeholder="$t(`请选择项目状态`)" @change="selectChange" size="small" multiple  clearable>
+            <el-option
+                v-for="item in statusTab"
+                :key="item.value"
+                :label="$t(item.label)"
+                :value="item.value">
+            </el-option>
+          </el-select>
+        </div>
+        <btnSelect ref="btnSelectRef" @btnClick="btnClick" class="inline-16"  :btnTitle="['全部','本年']" dateType="本年"></btnSelect>
+<!--        <fullScreen class="inline-16"  domId="statisticsOfCustomerFull" @onFull="onFull" @backFull="backFull"  ></fullScreen>-->
+      </template>
+      <template slot="content">
+        <div style="display: flex;justify-content: space-between" :style="{height:heightDiv}">
+          <div ref="statisticsOfProjectChart" :style="{height: heightChart}"></div>
+          <div style="width: 70%"  :style="{height: heightDiv}">
+            <tableDetail :layout="tablecols" :data="tableList" :opwidth="200" :custom="true" fixed-name="operation" :height="heightTable">
+              <template v-slot:customcol="scope">
+                <div v-if="scope.column.columnname === 'tag'">
+                  <div v-if="scope.column.data.tag">
+                    <div v-if="scope.column.data.tag.length > 0">
+                      <el-tag v-for="item in scope.column.data.tag" :key="item.index" :type="item === '支持者'?'warning':item === '反对者'?'danger':''" size="mini" style="margin:0 5px 0 0">
+                        {{$t(item)}}
+                      </el-tag>
+                    </div>
+                    <div v-else>--</div>
+                  </div>
+                  <div v-else>--</div>
+                </div>
+                <div v-else>{{scope.column.data[scope.column.columnname]||scope.column.columnname === 'operation' ? scope.column.data[scope.column.columnname] : '--'}}</div>
+              </template>
+              <template v-slot:opreation="scope">
+                <drawerTemp class="inline-16" v-if="detailPath" :data="scope.data" :detailPath="detailPath" :idName="idName"  :disabled="isFull"
+                            :listqueryid="listqueryid" :total="total" :overview="true"></drawerTemp>
+              </template>
+            </tableDetail>
+            <div style="margin-top:10px;text-align:right">
+              <el-pagination
+                  background
+                  small
+                  @size-change="handleSizeChange"
+                  @current-change="handleCurrentChange"
+                  :current-page="currentPage"
+                  :page-size="paramTable.content.pageSize"
+                  layout="total, prev, pager, next, jumper"
+                  :total="total">
+              </el-pagination>
+            </div>
+          </div>
+        </div>
+      </template>
+    </dataTemPlate>
+  </div>
+</template>
+
+<script>
+import dataTemPlate from '@/components/dataTemplate/index'
+import btnSelect from "./btnSelectInfo"
+import {Pie} from "@antv/g2plot";
+import fullScreen from "@/views/salesData/components/fullScreen";
+export default {
+  name: "statisticsOfProject",
+  components:{dataTemPlate,btnSelect,fullScreen,
+    drawerTemp:() =>  import('@/components/normal-basic-layout/drawerDetail/index')},
+  data() {
+    return {
+      detailPath:{
+        path:'/contactDataDetail'
+      },
+      idName:'sys_phonebookid',
+      isFull:false,
+      listqueryid:'',
+      paramChart:{
+        "id": 2025080114335902,
+        "content": {
+          "type": 1,
+          "dataid": 58,
+          "dateType": "本年",
+          "where": {
+            "begdate": "",
+            "enddate": "",
+            "isleave": "1",
+            "projecttype":"",
+            "status": []
+          }
+        },
+      },
+      paramTable:{
+        "id": 2025080114340402,
+        "content": {
+          "type": 1,
+          "dataid": 58,
+          "pageSize": 10,
+          "pageNumber": 1,
+          "dateType": "本年",
+          "where": {
+            "begdate": "",
+            "enddate": "",
+            "isleave": "1",
+            "isprojects": "",
+            "projecttype":"",
+            "status": []
+          }
+        },
+      },
+      tablecols:[],
+      tableList:[],
+      total:0,
+      currentPage:0,
+      chartList:[],
+      chartMap:null,
+      typesData:[],
+      heightChart:'100%',
+      heightDiv:'400px',
+      heightTable:'360px',
+      statusTab:[
+        {
+          value:"跟进中",
+          label:"跟进中"
+        },
+        {
+          value:"已成交",
+          label:"已成交"
+        },
+        {
+          value:"已失败",
+          label:"已失败"
+        },
+        {
+          value:"已结案",
+          label:"已结案"
+        }
+      ],
+    }
+  },
+  methods:{
+    listData(dataid,type,isleave,state,init){
+      this.paramChart.content.dataid = dataid
+      this.paramTable.content.dataid = dataid
+      this.paramChart.content.type = type
+      this.paramTable.content.type = type
+      this.paramChart.content.where.isleave = isleave
+      this.paramTable.content.where.isleave = isleave
+      // this.paramTable.content.where.status = this.paramTable.content.where.status?this.paramTable.content.where.status:[]
+      // this.paramChart.content.where.status = this.paramChart.content.where.status?this.paramChart.content.where.status:[]
+      this.chartData(init,state)
+      this.tableData()
+    },
+    async chartData(init,state){
+      const res = await this.$api.requested(this.paramChart)
+      this.chartList = res.data
+      if (init) {
+        this.chartMap = new Pie(this.$refs.statisticsOfProjectChart, {
+          appendPadding: 10,
+          data:this.chartList,
+          angleField: 'ratio',
+          colorField: 'key',
+          radius: 1,
+          innerRadius: 0.64,
+          label:{
+            formatter: (datum) => `${datum.ratio}%`
+          },
+          tooltip:{
+            formatter: (datum) => {
+              return { name: datum.key, value: datum.ratio + '%' };
+            },
+          },
+          statistic: {
+            title: {
+              offsetY: -4,
+              style: {
+                fontSize:'16px'
+              },
+              content:this.$t('项目总数')
+            },
+            content: {
+              offsetY: 4,
+              style: {
+                whiteSpace: 'pre-wrap',
+                overflow: 'hidden',
+                textOverflow: 'ellipsis',
+                fontSize:'16px'
+              },
+              customHtml: (container, view, datum, data) => {
+                const text = data[0].totalqty
+                return text
+              },
+            },
+          },
+          legend: {
+            position:'bottom'
+          },
+          // 添加 中心统计文本 交互
+          interactions: [{ type: 'element-single-selected' },{ type: 'element-active' }],
+        });
+        this.chartMap.on('element:click',(v) => {
+          if (v.data.data.key != this.paramTable.content.where.isprojects) {
+            this.paramTable.content.pageNumber = 1
+            this.paramTable.content.where.isprojects = v.data.data.key
+            this.tableData()
+          } else {
+            this.paramTable.content.pageNumber = 1
+            this.paramTable.content.where.isprojects = ''
+            this.tableData()
+          }
+        })
+        this.chartMap.render();
+      } else {
+        this.chartMap.changeData(this.chartList)
+      }
+    },
+    async tableData(){
+      const res = await this.$api.requested(this.paramTable)
+      this.tableList = res.data
+      this.total = res.total
+      this.currentPage = res.pageNumber
+      this.listqueryid = res.listqueryid
+    },
+    btnClick(dateType,dateData){
+      this.paramTable.content.pageNumber = 1
+      if (dateType){
+        this.paramChart.content.dateType = dateType
+        this.paramTable.content.dateType = dateType
+      }else {
+        this.paramTable.content.where.begdate = dateData[0]
+        this.paramTable.content.where.enddate = dateData[1]
+        this.paramChart.content.where.begdate = dateData[0]
+        this.paramChart.content.where.enddate = dateData[1]
+      }
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    handleSizeChange(val) {
+      // console.log(`每页 ${val} 条`);
+      this.paramTable.content.pageSize = val
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    handleCurrentChange(val) {
+      // console.log(`当前页: ${val}`);
+      this.paramTable.content.pageNumber = val
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    selectChange(){
+      this.paramChart.content.dateType = this.paramTable.content.where.type
+      this.listData(this.paramChart.content.dataid,this.paramChart.content.type,this.paramChart.content.where.isleave)
+    },
+    async queryType(){
+      if (this.typesData.length == 0){
+        const res = await this.$store.dispatch("optiontypeselect", "projecttype")
+        this.typesData = res.data
+      }
+    },
+    /*全屏*/
+    onFull(){
+      this.heightChart = this.windowWidth > 1136 ? 'calc(100vh - 70px)':'calc(100vh - 123px)'
+      this.heightDiv = this.windowWidth > 1136 ? 'calc(100vh - 70px)':'calc(100vh - 123px)'
+      this.heightTable = this.windowWidth > 1136 ? 'calc(100vh - 100px)':'calc(100vh - 153px)'
+      this.isFull = true
+    },
+    /*退出全屏*/
+    backFull(val){
+      this.heightChart = '100%'
+      this.heightDiv = '400px'
+      this.heightTable = '360px'
+      this.isFull = false
+      this.$emit('backFull',val)
+    }
+  },
+  created() {
+    this.tablecols = this.tool.tabelCol(this.$route.name).contactsTable.tablecols
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 45 - 1
src/HDrpManagement/contactData/index.vue

@@ -12,6 +12,7 @@
               <btnSelect :btn-title="['全部','本年','本季','本月','上月','去年']" :date-type="dateType" @btnClick="btnClick"></btnSelect>
             </div>
           </div>
+          <!--  数据概况        -->
           <dataBoard title="联系人数据概况" :mainData="maninInfo" heightNew="145px" @goDetail="goDetail"></dataBoard>
           <dataDetail ref="detailRef" :param="paramDetail" :person="person" :departmentid="depment" :layout="tablecols" :title="detailTitle" :titleHeader="titleHeader" height="calc(100vh - 225px)" tableType="联系人数据概况">
             <template slot="custom">
@@ -160,9 +161,21 @@
               </div>
             </template>
           </dataDetail>
+          <!--  联系人销售贡献度排行        -->
           <salesContribution class="mt-10" ref="salesContributionRef"></salesContribution>
+          <!--  近12月联系人新增分析        -->
           <contactsAddAnalysis class="mt-10" ref="contactsAddAnalysisRef"></contactsAddAnalysis>
+          <!--  联系人关联线索情况统计       -->
+          <statisticsOfClues class="mt-10" ref="statisticsOfCluesRef"></statisticsOfClues>
+          <!--  联系人关联客户情况统计       -->
+          <statisticsOfCustomer class="mt-10" ref="statisticsOfCustomerRef"></statisticsOfCustomer>
+          <!--  联系人关联项目情况统计       -->
+          <statisticsOfProject class="mt-10" ref="statisticsOfProjectRef"></statisticsOfProject>
+          <!--  联系人跟进情况统计       -->
+          <statisticsOfFollow class="mt-10" ref="statisticsOfFollowRef"></statisticsOfFollow>
+          <!--  近12月联系人跟进分析        -->
           <contactsFollowAnalysis class="mt-10" ref="contactsFollowAnalysisRef"></contactsFollowAnalysis>
+          <!--          -->
         </div>
       </template>
     </normal-layout>
@@ -178,9 +191,14 @@ import salesContribution from './components/salesContribution'
 import depStatus from './components/depStatus'
 import contactsAddAnalysis from './components/contactsAddAnalysis'
 import contactsFollowAnalysis from './components/contactsFollowAnalysis'
+import statisticsOfClues from './components/statisticsOfClues'
+import statisticsOfCustomer from './components/statisticsOfCustomer'
+import statisticsOfProject from './components/statisticsOfProject'
+import statisticsOfFollow from './components/statisticsOfFollow'
 export default {
   name: "index",
-  components:{normalLayout,btnSelect,dataBoard,dataDetail,salesContribution,depStatus,contactsAddAnalysis,contactsFollowAnalysis},
+  components:{normalLayout,btnSelect,dataBoard,dataDetail,salesContribution,depStatus,contactsAddAnalysis,contactsFollowAnalysis,statisticsOfClues,statisticsOfCustomer,statisticsOfProject,
+    statisticsOfFollow},
   data(){
     return {
       scrollData:'',
@@ -333,6 +351,10 @@ export default {
       this.$refs.salesContributionRef.$refs.depStatusProRef.deplist = this.deplist
       this.$refs.contactsAddAnalysisRef.$refs.dataTemPlateRef.$refs.depStatusRef.deplist = this.deplist
       this.$refs.contactsFollowAnalysisRef.$refs.dataTemPlateRef.$refs.depStatusRef.deplist = this.deplist
+      this.$refs.statisticsOfCluesRef.$refs.dataTemPlateRef.$refs.depStatusRef.deplist = this.deplist
+      this.$refs.statisticsOfCustomerRef.$refs.dataTemPlateRef.$refs.depStatusRef.deplist = this.deplist
+      this.$refs.statisticsOfProjectRef.$refs.dataTemPlateRef.$refs.depStatusRef.deplist = this.deplist
+      this.$refs.statisticsOfFollowRef.$refs.dataTemPlateRef.$refs.depStatusRef.deplist = this.deplist
 
       this.personnelList = res.data.hr
       this.$refs.allDepRef.personnelList = this.personnelList
@@ -340,6 +362,10 @@ export default {
       this.$refs.salesContributionRef.$refs.depStatusProRef.personnelList = this.personnelList
       this.$refs.contactsAddAnalysisRef.$refs.dataTemPlateRef.$refs.depStatusRef.personnelList = this.personnelList
       this.$refs.contactsFollowAnalysisRef.$refs.dataTemPlateRef.$refs.depStatusRef.personnelList = this.personnelList
+      this.$refs.statisticsOfCluesRef.$refs.dataTemPlateRef.$refs.depStatusRef.personnelList = this.personnelList
+      this.$refs.statisticsOfCustomerRef.$refs.dataTemPlateRef.$refs.depStatusRef.personnelList = this.personnelList
+      this.$refs.statisticsOfProjectRef.$refs.dataTemPlateRef.$refs.depStatusRef.personnelList = this.personnelList
+      this.$refs.statisticsOfFollowRef.$refs.dataTemPlateRef.$refs.depStatusRef.personnelList = this.personnelList
 
       this.depment = ''
       this.$refs.allDepRef.depment = this.depment
@@ -347,6 +373,10 @@ export default {
       this.$refs.salesContributionRef.$refs.depStatusProRef.depment = this.depment
       this.$refs.contactsAddAnalysisRef.$refs.dataTemPlateRef.$refs.depStatusRef.depment = this.depment
       this.$refs.contactsFollowAnalysisRef.$refs.dataTemPlateRef.$refs.depStatusRef.depment = this.depment
+      this.$refs.statisticsOfCluesRef.$refs.dataTemPlateRef.$refs.depStatusRef.depment = this.depment
+      this.$refs.statisticsOfCustomerRef.$refs.dataTemPlateRef.$refs.depStatusRef.depment = this.depment
+      this.$refs.statisticsOfProjectRef.$refs.dataTemPlateRef.$refs.depStatusRef.depment = this.depment
+      this.$refs.statisticsOfFollowRef.$refs.dataTemPlateRef.$refs.depStatusRef.depment = this.depment
 
       this.person = JSON.parse(window.sessionStorage.getItem('active_account')).name
       this.$refs.allDepRef.person = this.person
@@ -354,6 +384,10 @@ export default {
       this.$refs.salesContributionRef.$refs.depStatusProRef.person = this.person
       this.$refs.contactsAddAnalysisRef.$refs.dataTemPlateRef.$refs.depStatusRef.person = this.person
       this.$refs.contactsFollowAnalysisRef.$refs.dataTemPlateRef.$refs.depStatusRef.person = this.person
+      this.$refs.statisticsOfCluesRef.$refs.dataTemPlateRef.$refs.depStatusRef.person = this.person
+      this.$refs.statisticsOfCustomerRef.$refs.dataTemPlateRef.$refs.depStatusRef.person = this.person
+      this.$refs.statisticsOfProjectRef.$refs.dataTemPlateRef.$refs.depStatusRef.person = this.person
+      this.$refs.statisticsOfFollowRef.$refs.dataTemPlateRef.$refs.depStatusRef.person = this.person
 
       const userid = JSON.parse(sessionStorage.getItem('active_account')).userid
       this.otherMethod(userid)
@@ -469,6 +503,11 @@ export default {
       this.$refs.salesContributionRef.listData(dataid,0,1)
       this.$refs.contactsAddAnalysisRef.listData(0,dataid,1,null,true)
       this.$refs.contactsFollowAnalysisRef.listData(0,dataid,1,null,true)
+      this.$refs.statisticsOfCluesRef.paramTable.content.pageNumber = 1
+      this.$refs.statisticsOfCluesRef.listData(dataid,0,1,null,true)
+      this.$refs.statisticsOfCustomerRef.listData(dataid,0,1,null,true)
+      this.$refs.statisticsOfProjectRef.listData(dataid,0,1,null,true)
+      this.$refs.statisticsOfFollowRef.listData(dataid,0,1,null,true)
     },
     /*其他页面再次调用*/
     otherModel(dataid,type,isleave,state){
@@ -485,6 +524,11 @@ export default {
       this.$refs.salesContributionRef.listData(dataid,type,isleave,state)
       this.$refs.contactsAddAnalysisRef.listData(0,dataid,1,state,null)
       this.$refs.contactsFollowAnalysisRef.listData(0,dataid,1,state,null)
+      this.$refs.statisticsOfCluesRef.paramTable.content.pageNumber = 1
+      this.$refs.statisticsOfCluesRef.listData(dataid,0,1,state,null)
+      this.$refs.statisticsOfCustomerRef.listData(dataid,0,1,state,null)
+      this.$refs.statisticsOfProjectRef.listData(dataid,0,1,state,null)
+      this.$refs.statisticsOfFollowRef.listData(dataid,0,1,state,null)
     },
     /*联系人数据概况*/
     async queryMainData(dataid,dateType){

+ 1 - 1
src/components/dataTemplate/index.vue

@@ -28,7 +28,7 @@ export default {
   components:{depStatus},
   methods:{
     listData(dataid,type,isleave,state){
-      this.$emit('list',type,dataid,isleave,state)
+      this.$emit('list',dataid,type,isleave,state)
     }
   }
 }

+ 1 - 0
src/components/normal-basic-layout/drawerDetail/index.vue

@@ -17,6 +17,7 @@ export default {
   },
   methods:{
     onShow () {
+      console.log(this.data,'data')
       let key = ''
       if (this.idName instanceof Array) {
         key = this.idName[1]

+ 11 - 0
src/router/HDrpManagement.js

@@ -1203,6 +1203,17 @@ const HDrpManagement = [
       keeproute: true,
     },
     component: () => import(/* webpackChunkName: "about" */ '@/HDrpManagement/contactData/index'),
+    children:[
+      {
+        path: '/contactDataDetail',
+        name: 'contactData',
+        meta: {
+          title: '联系人数据详情',
+          ast_nav:false
+        },
+        component: () => import(/* webpackChunkName: "about" */ '@/HManagement/addressList/addressBook/detail/index')
+      },
+    ]
   },
   {
     path: '/salerpriceData',