소스 검색

Merge branch 'orangeUrgent' into testToMerge

qymljy 8 달 전
부모
커밋
ca5b2ed69e
29개의 변경된 파일3866개의 추가작업 그리고 53개의 파일을 삭제
  1. 137 0
      src/HDrpManagement/contactData/components/allRank.vue
  2. 73 0
      src/HDrpManagement/contactData/components/btnSelectInfo.vue
  3. 165 0
      src/HDrpManagement/contactData/components/contactsAddAnalysis.vue
  4. 165 0
      src/HDrpManagement/contactData/components/contactsFollowAnalysis.vue
  5. 159 0
      src/HDrpManagement/contactData/components/depStatus.vue
  6. 191 0
      src/HDrpManagement/contactData/components/salesContribution.vue
  7. 248 0
      src/HDrpManagement/contactData/components/statisticsOfClues.vue
  8. 252 0
      src/HDrpManagement/contactData/components/statisticsOfCustomer.vue
  9. 244 0
      src/HDrpManagement/contactData/components/statisticsOfFollow.vue
  10. 273 0
      src/HDrpManagement/contactData/components/statisticsOfProject.vue
  11. 231 0
      src/HDrpManagement/contactData/components/statisticsOfUnFollow.vue
  12. 799 0
      src/HDrpManagement/contactData/index.vue
  13. 3 0
      src/HDrpManagement/contactProfile/modules/detail.vue
  14. 24 3
      src/HDrpManagement/dataanalysis/index.vue
  15. 16 16
      src/HDrpManagement/dataanalysis/modules/assignmentData.vue
  16. 314 0
      src/HDrpManagement/dataanalysis/modules/contact.vue
  17. 1 1
      src/HManagement/addressList/addressBook/index.vue
  18. 1 1
      src/HManagement/serviceDataScreen/components/profileTemplate.vue
  19. 45 2
      src/HManagement/serviceDataScreen/modules/dataProfile.vue
  20. 79 26
      src/HManagement/serviceDataScreen/modules/jobData.vue
  21. 1 0
      src/HManagement/serviceDataScreen/modules/salesPanel.vue
  22. 72 0
      src/components/dataBoard/index.vue
  23. 159 0
      src/components/dataTemplate/depStatus.vue
  24. 69 0
      src/components/dataTemplate/index.vue
  25. 0 2
      src/components/export_file/index5.vue
  26. 1 0
      src/components/normal-basic-layout/drawerDetail/index.vue
  27. 21 0
      src/router/HDrpManagement.js
  28. 122 1
      src/template/dataDetail/index.vue
  29. 1 1
      vue.config.js

+ 137 - 0
src/HDrpManagement/contactData/components/allRank.vue

@@ -0,0 +1,137 @@
+<template>
+  <div>
+    <el-button type="primary" size="small" @click="allClick">{{$t(btnTitle)}} ></el-button>
+    <el-drawer
+        :title="$t(allTitle)"
+        :visible.sync="drawerShow"
+        size="90%"
+        direction="rtl"
+        append-to-body
+        :show-close="false"
+        @close="onCLose"
+    >
+      <div class="drawer__panel" style="margin-bottom: 0!important;">
+        <depStatus class="inline-16 mt-10" ref="depStatusRef" @depData="queryList" @personData="queryList" @leaveData="queryList" :disabled="true"></depStatus>
+        <el-date-picker
+            style="margin-right: 10px"
+            @change="onChange"
+            v-model="dateData"
+            size="small"
+            type="monthrange"
+            format="yyyy-MM"
+            value-format="yyyy-MM"
+            :range-separator="$t('至')"
+            :start-placeholder="$t(`开始月份`)"
+            :end-placeholder="$t(`结束月份`)">
+        </el-date-picker>
+        <el-input style="width:200px;" :placeholder="$t('搜索')" :suffix-icon="param.content.where.condition?param.content.where.condition.length > 0?'':'':'el-icon-search'" v-model="param.content.where.condition" @keyup.native.enter="listData(param.content.pageNumber = 1)" @clear="listData(param.content.pageNumber = 1)" size="small" class="input-with-select inline-16 layout_search__panel" clearable>
+        </el-input>
+        <div class="mt-10 inline-15">
+          <exportFile :param="param" :columns="tablecols" :fileName="allTitle" :dataid="param.content.dataid"></exportFile>
+        </div>
+        <tableDetail :layout="tablecols" :data="list" :opwidth="200" :custom="true" height="calc(100vh - 210px)">
+          <template v-slot:customcol="scope">
+            <div v-if="scope.column.columnname === 'amount'">
+              {{tool.formatAmount(scope.column.data[scope.column.columnname],2,'¥')}}
+            </div>
+            <div v-else>{{scope.column.data[scope.column.columnname]||scope.column.columnname ==='operation'?scope.column.data[scope.column.columnname] : '--'}}</div>
+          </template>
+        </tableDetail>
+        <div  class="container normal-panel" style="text-align:right">
+          <el-pagination
+              background
+              @size-change="handleSizeChange"
+              @current-change="handleCurrentChange"
+              :current-page="currentPage"
+              :page-sizes="[20, 50, 100, 200]"
+              :page-size="100"
+              layout="total,sizes, prev, pager, next, jumper"
+              :total="total">
+          </el-pagination>
+        </div>
+      </div>
+    </el-drawer>
+  </div>
+</template>
+
+<script>
+import depStatus from './depStatus'
+import exportFile from '@/components/export_file/index'
+export default {
+  name: "allRank",
+  props:['btnTitle','allTitle','tablecols'],
+  components:{depStatus,exportFile},
+  data(){
+    return {
+      drawerShow:false,
+      list:[],
+      currentPage:0,
+      total:0,
+      param:{
+        "id": 2025072410065502,
+        "content": {
+          "type": 1,
+          "dataid": 54,
+          "dateType": "本年",
+          "where": {
+            "begdate": "",
+            "enddate": "",
+            "condition": "",
+            "isleave": ""
+          },
+          "pageSize": 100,
+          "pageNumber": 1
+        },
+      },
+      dateData:[]
+    }
+  },
+  methods:{
+    allClick(){
+      this.$emit('allClick')
+    },
+    queryList(id,type,isleave,state){
+      this.param.content.dataid = id
+      this.param.content.type = type
+      this.param.content.where.isleave = isleave
+      this.listData()
+    },
+    async listData(){
+      const res = await this.$api.requested(this.param)
+      this.list = res.data
+      this.total = res.total
+      this.currentPage = res.pageNumber
+    },
+    handleSizeChange(val) {
+      // console.log(`每页 ${val} 条`);
+      this.param.content.pageSize = val
+      this.listData()
+    },
+    handleCurrentChange(val) {
+      // console.log(`当前页: ${val}`);
+      this.param.content.pageNumber = val
+      this.listData()
+    },
+    onCLose(){
+      this.param.content.where.condtion = ''
+      this.drawerShow = false
+    },
+    onChange(){
+      if (this.dateData){
+        this.param.content.dataType = ""
+        this.param.content.where.begindate = this.dateData[0]
+        this.param.content.where.enddate = this.dateData[1]
+        this.listData()
+      }else {
+        this.param.content.where.begindate = ""
+        this.param.content.where.enddate = ""
+        this.listData()
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

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

@@ -0,0 +1,73 @@
+<template>
+  <div>
+    <el-button-group>
+      <el-button v-for="item in btnTitle" :key="item.index" :type="item === dataTypeNow ?'primary':''" size="small" @click="btnClick(item)">{{$t(item)}}</el-button>
+    </el-button-group>
+    <el-date-picker
+        style="margin-left: 10px"
+        v-model="dateData"
+        @change="onChange"
+        size="small"
+        format="yyyy-MM"
+        value-format="yyyy-MM"
+        type="monthrange"
+        :range-separator="$t('至')"
+        :start-placeholder="$t(`开始月份`)"
+        :end-placeholder="$t(`结束月份`)">
+    </el-date-picker>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "btnSelectInfo",
+  props:{
+    btnTitle: Array,
+    dateType:String
+  },
+  data(){
+    return {
+      dateData:[],
+      dataTypeNow:'本年'
+    }
+  },
+  methods:{
+    btnClick(data){
+      this.dataTypeNow = data
+      if (data == '本年'){
+        let year = new Date().getFullYear()
+        let begdate = year + '-01'
+        let enddate = year + '-12'
+        this.dateData = [begdate,enddate]
+      }else if (data == '本季'){
+        const now = new Date();
+        const quarterStartMonth = Math.floor(now.getMonth() / 3) * 3;
+        const quarterStartDate = new Date(now.getFullYear(), quarterStartMonth);
+        const quarterEndDate = new Date(now.getFullYear(), quarterStartMonth + 3);
+        this.dateData = [quarterStartDate,quarterEndDate]
+      }else if (data == '本月'){
+        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)
+    },
+    onChange(){
+      if (this.dateData){
+        this.dataTypeNow = ''
+      }
+      this.$emit('btnClick',this.dataTypeNow,this.dateData)
+    }
+  },
+  mounted() {
+    this.dataTypeNow = this.dateType
+    this.btnClick(this.dateType)
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 165 - 0
src/HDrpManagement/contactData/components/contactsAddAnalysis.vue

@@ -0,0 +1,165 @@
+<template>
+  <div>
+    <dataTemPlate ref="dataTemPlateRef" :isTitle="true" title="近12月联系人新增分析" @list="listData" id="contactsAddAnalysisFull">
+      <template slot="operation">
+        <div class="mt-10 inline-15">
+          <span class="search__label inline-16">{{$t('分析日期')}}:</span>
+          <el-date-picker
+              v-model="enddate"
+              :append-to-body="!isFull"
+              type="date"
+              :clearable="false"
+              @change="changeDate"
+              format="yyyy-MM-dd"
+              value-format="yyyy-MM-dd"
+              size="small"
+              :range-separator="$t('至')"
+              :start-placeholder="$t('开始月份')"
+              :end-placeholder="$t('结束月份')">
+          </el-date-picker>
+        </div>
+<!--        <fullScreen class="inline-16"  domId="contactsAddAnalysisFull" @onFull="onFull" @backFull="backFull"  ></fullScreen>-->
+      </template>
+      <template slot="content">
+        <div :style="{height:heightDiv}">
+          <div ref="contactsAddAnalysisChart" :style="{height: heightChart}"></div>
+        </div>
+      </template>
+    </dataTemPlate>
+  </div>
+</template>
+
+<script>
+import dataTemPlate from '@/components/dataTemplate/index'
+import depStatus from './depStatus'
+import {DualAxes} from "@antv/g2plot";
+import fullScreen from "@/views/salesData/components/fullScreen";
+export default {
+  name: "contactsAddAnalysis",
+  components:{dataTemPlate,depStatus,fullScreen},
+  data(){
+    return {
+      param:{
+        "id": 2025072510194302,
+        "content": {
+          "type": 1,
+          "dataid": 58,
+          "enddate": "",
+          "where": {
+            "isleave": ""
+          }
+        },
+      },
+      list:[],
+      heightChart:'100%',
+      uvBillData:[],
+      dualAxes:null,
+      enddate:new Date().getFullYear() + '-' +  (new Date().getMonth() + 1) + '-' + new Date().getDate(),
+      isFull:false,
+      heightDiv:'360px'
+    }
+  },
+  methods:{
+    async listData(id,type,isleave,state,init){
+      this.param.content.type = type
+      this.param.content.dataid = id
+      this.param.content.where.isleave = isleave
+      const res = await this.$api.requested(this.param)
+      let lastYear = []
+      let nowYear = []
+      let k=0
+      for (var i=0;i<res.data.histogram.length;i++){
+        if (res.data.histogram[i].type === '去年同期新增'){
+          lastYear[k]=res.data.histogram[i]
+          k++
+        }
+      }
+      let x=0
+      for (var i=0;i<res.data.histogram.length;i++){
+        if (res.data.histogram[i].type === '本期新增'){
+          nowYear[x]=res.data.histogram[i]
+          x++
+        }
+      }
+      this.uvBillData = lastYear.concat(nowYear)
+      this.uvBillData = this.uvBillData.map(item=>{
+        return {
+          date: item.date,
+          type:this.$t(item.type),
+          value: item.value
+        }
+      })
+      /*res.data.lineChart.forEach(item => item[`同比增长率`] = item.value)*/
+      this.transformData = res.data.lineChart
+      this.transformData = this.transformData.map(item=>{
+        return {
+          date: item.date,
+          type:this.$t(item.type),
+          value: Math.round((item.value * 100) * 100) / 100
+        }
+      })
+      if (init) {
+        this.dualAxes = new DualAxes(this.$refs.contactsAddAnalysisChart, {
+          data: [this.uvBillData,this.transformData],
+          xField: 'date',
+          yField: ['value', 'value'],
+          geometryOptions: [
+            {
+              geometry: 'column',
+              isGroup: true,
+              seriesField: 'type',
+              color:['#62daab','#6395fa'],
+              label:{
+                position:top
+              }
+            },
+            {
+              geometry: 'line',
+              lineStyle: {
+                lineWidth: 2,
+              },
+              seriesField: 'type',
+              color: '#F6903D',
+              smooth: true,
+              label:{
+                formatter: (datum) =>{
+                  return  datum.value + '%'
+                }
+              }
+            },
+          ],
+          tooltip: {
+            formatter: (datum) => {
+              return { name: datum.type, value: datum.type == this.$t('同比增长率')? datum.value + '%' : datum.value };
+            },
+          },
+        });
+        this.dualAxes.render()
+      } else {
+        this.dualAxes.changeData([this.uvBillData,this.transformData])
+      }
+    },
+    changeDate(){
+      this.param.content.enddate = this.enddate
+      this.listData(this.param.content.dataid,this.param.content.type,this.param.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.isFull = true
+    },
+    /*退出全屏*/
+    backFull(val){
+      this.heightChart = '100%'
+      this.heightDiv = '360px'
+      this.isFull = false
+      this.$emit('backFull',val)
+    }
+  },
+}
+</script>
+
+<style scoped>
+
+</style>

+ 165 - 0
src/HDrpManagement/contactData/components/contactsFollowAnalysis.vue

@@ -0,0 +1,165 @@
+<template>
+  <div>
+    <dataTemPlate ref="dataTemPlateRef" :isTitle="true" title="近12月联系人跟进分析" @list="listData" id="contactsFollowAnalysisFull">
+      <template slot="operation">
+        <div class="mt-10 inline-15">
+          <span class="search__label inline-16">{{$t('分析日期')}}:</span>
+          <el-date-picker
+              v-model="enddate"
+              :append-to-body="!isFull"
+              type="date"
+              :clearable="false"
+              @change="changeDate"
+              format="yyyy-MM-dd"
+              value-format="yyyy-MM-dd"
+              size="small"
+              :range-separator="$t('至')"
+              :start-placeholder="$t('开始月份')"
+              :end-placeholder="$t('结束月份')">
+          </el-date-picker>
+        </div>
+<!--        <fullScreen class="inline-16"  domId="contactsFollowAnalysisFull" @onFull="onFull" @backFull="backFull"  ></fullScreen>-->
+      </template>
+      <template slot="content">
+        <div :style="{height:heightDiv}">
+          <div ref="contactsFollowAnalysisChart" :style="{height: heightChart}"></div>
+        </div>
+      </template>
+    </dataTemPlate>
+  </div>
+</template>
+
+<script>
+import dataTemPlate from '@/components/dataTemplate/index'
+import depStatus from './depStatus'
+import {DualAxes} from "@antv/g2plot";
+import fullScreen from "@/views/salesData/components/fullScreen";
+export default {
+  name: "contactsFollowAnalysis",
+  components:{dataTemPlate,depStatus,fullScreen},
+  data(){
+    return {
+      param:{
+        "id": 2025072510195202,
+        "content": {
+          "type": 1,
+          "dataid": 58,
+          "enddate": "",
+          "where": {
+            "isleave": ""
+          }
+        },
+      },
+      list:[],
+      heightChart:'100%',
+      uvBillData:[],
+      dualAxes:null,
+      enddate:new Date().getFullYear() + '-' +  (new Date().getMonth() + 1) + '-' + new Date().getDate(),
+      isFull:false,
+      heightDiv:'360px'
+    }
+  },
+  methods:{
+    async listData(id,type,isleave,state,init){
+      this.param.content.type = type
+      this.param.content.dataid = id
+      this.param.content.where.isleave = isleave
+      const res = await this.$api.requested(this.param)
+      let lastYear = []
+      let nowYear = []
+      let k=0
+      for (var i=0;i<res.data.histogram.length;i++){
+        if (res.data.histogram[i].key === '去年同期跟进'){
+          lastYear[k]=res.data.histogram[i]
+          k++
+        }
+      }
+      let x=0
+      for (var i=0;i<res.data.histogram.length;i++){
+        if (res.data.histogram[i].key === '本期跟进'){
+          nowYear[x]=res.data.histogram[i]
+          x++
+        }
+      }
+      this.uvBillData = lastYear.concat(nowYear)
+      this.uvBillData = this.uvBillData.map(item=>{
+        return {
+          date: item.date,
+          key:this.$t(item.key),
+          value: item.value
+        }
+      })
+      /*res.data.lineChart.forEach(item => item[`同比增长率`] = item.value)*/
+      this.transformData = res.data.lineChart
+      this.transformData = this.transformData.map(item=>{
+        return {
+          date: item.date,
+          key:this.$t(item.key),
+          value: Math.round((item.value * 100) * 100) / 100
+        }
+      })
+      if (init) {
+        this.dualAxes = new DualAxes(this.$refs.contactsFollowAnalysisChart, {
+          data: [this.uvBillData,this.transformData],
+          xField: 'date',
+          yField: ['value', 'value'],
+          geometryOptions: [
+            {
+              geometry: 'column',
+              isGroup: true,
+              seriesField: 'key',
+              color:['#62daab','#6395fa'],
+              label:{
+                position:top
+              }
+            },
+            {
+              geometry: 'line',
+              lineStyle: {
+                lineWidth: 2,
+              },
+              seriesField: 'key',
+              color: '#F6903D',
+              smooth: true,
+              label:{
+                formatter: (datum) =>{
+                  return  datum.value + '%'
+                }
+              }
+            },
+          ],
+          tooltip: {
+            formatter: (datum) => {
+              return { name: datum.key, value: datum.key == this.$t('同比增长率')? datum.value + '%' : datum.value };
+            },
+          },
+        });
+        this.dualAxes.render()
+      } else {
+        this.dualAxes.changeData([this.uvBillData,this.transformData])
+      }
+    },
+    changeDate(){
+      this.param.content.enddate = this.enddate
+      this.listData(this.param.content.dataid,this.param.content.type,this.param.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.isFull = true
+    },
+    /*退出全屏*/
+    backFull(val){
+      this.heightChart = '100%'
+      this.heightDiv = '360px'
+      this.isFull = false
+      this.$emit('backFull',val)
+    }
+  },
+}
+</script>
+
+<style scoped>
+
+</style>

+ 159 - 0
src/HDrpManagement/contactData/components/depStatus.vue

@@ -0,0 +1,159 @@
+<template>
+  <div>
+    <div class="inline-16">
+      <label  class="search__label" >{{$t('部门')}}:</label>
+      <el-cascader class="inline-16" placement="bottom" ref="selectdep" size="small" v-model="depment" :options="deplist" :props="{emitPath:true,expandTrigger:'hover',checkStrictly:true,label:'label',value:'departmentid',children:'children'}"  @change="selectDep" clearable :disabled="disabled"></el-cascader>
+    </div>
+    <div class="inline-16">
+      <label  class="search__label" >{{$t('业务员')}}:</label>
+      <el-select v-model="person" filterable :placeholder="$t('请选择')" size="small" clearable @change="selectPerson" :disabled="disabled">
+        <el-option
+            v-for="item in personnelList"
+            :key="item.index"
+            :label="$t(item.name)"
+            :value="item.userid">
+        </el-option>
+      </el-select>
+    </div>
+    <div class="mt-10 inline-16" v-if="isLeaveShow != false">
+      <p class="search__label">{{$t('状态')}}:</p>
+      <el-select v-model="isleave" clearable style="margin-right:10px" size="small" :placeholder="$t('请选择状态')" @change="leaveChange" :disabled="disabled">
+        <el-option :label="$t('在职')" value="1"></el-option>
+        <el-option :label="$t('离职')" value="2"></el-option>
+      </el-select>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "depStatus",
+  props:['isLeaveShow','disabled'],
+  data(){
+    return {
+      depment:'',
+      person:'',
+      isleave:'1',
+      deplist:[],
+      personnelList:[],
+      depmentParam:{
+        "id": 20230620102004,
+        "content": {
+          "isleave":1
+        }
+      },
+    }
+  },
+  methods:{
+    /*部门人员列表*/
+    async departmentrtment() {
+      const res = await this.$api.requested(this.depmentParam)
+      this.deplist = this.createMenu(res.data.dep)
+      this.personnelList = res.data.hr
+      this.depment = ''
+      this.person = JSON.parse(window.sessionStorage.getItem('active_account')).name
+      const userid = JSON.parse(sessionStorage.getItem('active_account')).userid
+    },
+    /*部门结构处理*/
+    createMenu (array) {
+      var that = this
+      let arr = []
+      function convertToElementTree(node) {
+        // 新节点
+        if (node.subdep.length === 0){
+          var elNode = {
+            label: node["depname"],
+            parentid:node['parentid'],
+            parentname:node['parentname'],
+            departmentid:node["departmentid"],
+            value:node["departmentid"],
+            remarks:node["remarks"],
+            isused:node["isused"],
+            changedate:node['changedate'],
+            changeby:node['changeby'],
+            createdate:node['createdate'],
+            createby:node['createby'],
+            depno:node['depno'],
+            disabled:that.pageOnlyRead,
+          }
+        }else {
+          var elNode = {
+            label: node["depname"],
+            parentid:node['parentid'],
+            parentname:node['parentname'],
+            departmentid:node["departmentid"],
+            value:node["departmentid"],
+            remarks:node["remarks"],
+            isused:node["isused"],
+            changedate:node['changedate'],
+            changeby:node['changeby'],
+            createdate:node['createdate'],
+            createby:node['createby'],
+            depno:node['depno'],
+            disabled:that.pageOnlyRead,
+            children: []
+          }
+        }
+        if (node.subdep && node.subdep.length > 0) {
+          // 如果存在子节点
+          for (var index = 0; index < node.subdep.length; index++) {
+            // 遍历子节点, 把每个子节点看做一颗独立的树, 传入递归构造子树, 并把结果放回到新node的children中
+            elNode.children.push(convertToElementTree(node.subdep[index]));
+          }
+        }
+        return elNode;
+      }
+      array.forEach((element) => {
+        arr.push(convertToElementTree(element))
+      });
+      return arr
+    },
+    /*选择部门*/
+    selectDep(val) {
+      console.log(val,'val2222')
+      if (val.length === 0){
+        const userid = JSON.parse(sessionStorage.getItem('active_account')).userid
+        console.log(JSON.parse(sessionStorage.getItem('active_account')).userid)
+        this.person = JSON.parse(window.sessionStorage.getItem('active_account')).name
+        this.$emit(`depData`,userid,'0')
+      }else {
+        this.person = ''
+        this.departmentid = val[val.length -1]
+        this.$emit(`depData`,this.departmentid,'1',this.isleave)
+      }
+    },
+    /*选择人员*/
+    selectPerson(val){
+      this.depment = ''
+      this.departmentid = ''
+      this.dataid = val
+      this.$emit(`personData`,val,'0',this.isleave)
+    },
+    /*选择在职状态*/
+    leaveChange(){
+      this.person = ''
+      const type = this.depment?'1':'0'
+      const dataid = type == 0?-1:this.departmentid
+      this.$emit(`leaveData`,dataid,type,this.isleave,'状态')
+      this.personData()
+    },
+    /*获取新的业务员列表*/
+    async personData(){
+      let param = {
+        id: 20230620102004,
+        content: {
+          isleave:this.isleave
+        },
+      }
+      const res = await this.$api.requested(param)
+      this.personnelList = res.data.hr
+    },
+  },
+  mounted() {
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 191 - 0
src/HDrpManagement/contactData/components/salesContribution.vue

@@ -0,0 +1,191 @@
+<template>
+  <div>
+    <dataTemPlate>
+      <template slot="content">
+        <el-tabs v-model="activeName" @tab-click="handleClick">
+          <el-tab-pane :label="$t(`联系人关联客户销售TOP10`)" name="关联客户">
+            <depStatus class="inline-16" ref="depStatusCusRef" @depData="listData" @personData="listData" @leaveData="listData" ></depStatus>
+            <btnSelect ref="btnSelectCusRef" @btnClick="btnClick" class="inline-16"  :btnTitle="['本年','本季','本月']" dateType="本年"></btnSelect>
+            <allRank @allClick="allClick" ref="allRankCusRef" class="inline-16" btnTitle="全部排名" allTitle="联系人关联客户销售贡献度排行" :tablecols="tool.tabelCol(this.$route.name).associatedCustomers.tablecols"></allRank>
+            <tableDetail :layout="tablecols" :data="list" :opwidth="200" :custom="true" >
+              <template v-slot:customcol="scope">
+                <div v-if="scope.column.columnname === 'amount'">
+                  {{tool.formatAmount(scope.column.data[scope.column.columnname],2,'¥')}}
+                </div>
+                <div v-else>{{scope.column.data[scope.column.columnname]||scope.column.columnname ==='operation'?scope.column.data[scope.column.columnname] : '--'}}</div>
+              </template>
+            </tableDetail>
+          </el-tab-pane>
+          <el-tab-pane :label="$t(`联系人关联项目销售TOP10`)" name="关联项目">
+            <depStatus @btnClick="handleClick" class="inline-16"  ref="depStatusProRef" @depData="listData" @personData="listData" @leaveData="listData"></depStatus>
+            <btnSelect ref="btnSelectProRef" @btnClick="btnClick" class="inline-16" :btnTitle="['本年','本季','本月']" dateType="本年"></btnSelect>
+            <allRank @allClick="allClick" ref="allRankProRef"  class="inline-16" btnTitle="全部排名" allTitle="联系人关联项目销售贡献度排行" :tablecols="tool.tabelCol(this.$route.name).associatedProject.tablecols"></allRank>
+            <tableDetail :layout="tablecols" :data="list" :opwidth="200" :custom="true">
+              <template v-slot:customcol="scope">
+                <div v-if="scope.column.columnname === 'amount'">
+                  {{tool.formatAmount(scope.column.data[scope.column.columnname],2,'¥')}}
+                </div>
+                <div v-else>{{scope.column.data[scope.column.columnname]||scope.column.columnname ==='operation'?scope.column.data[scope.column.columnname] : '--'}}</div>
+              </template>
+            </tableDetail>
+          </el-tab-pane>
+        </el-tabs>
+      </template>
+    </dataTemPlate>
+  </div>
+</template>
+
+<script>
+import dataTemPlate from '@/components/dataTemplate/index'
+import depStatus from './depStatus'
+import btnSelect from "./btnSelectInfo"
+import allRank from './allRank'
+export default {
+  name: "salesContribution",
+  components:{dataTemPlate,depStatus,btnSelect,allRank},
+  data(){
+    return {
+      activeName: '关联客户',
+      /*获取关联客户数据*/
+      paramCus:{
+        "id": 2025072410065502,
+        "content": {
+          "type": 1,
+          "dataid": 54,
+          "dateType": "本年",
+          "where": {
+            "begdate": "",
+            "enddate": "",
+            "condition": "",
+            "isleave": ""
+          },
+          "pageSize": 10,
+          "pageNumber": 1
+        },
+      },
+      /*获取关联项目数据*/
+      paramPro:{
+        "id": 2025072410070302,
+        "content": {
+          "type": 1,
+          "dataid": 54,
+          "dateType": "本年",
+          "where": {
+            "begdate": "",
+            "enddate": "",
+            "condition": "",
+            "isleave": ""
+          },
+          "pageSize": 10,
+          "pageNumber": 1
+        },
+      },
+      list:[],
+      tablecols:[],
+      currentPage:0,
+      total:0,
+      drawerShow:false,
+      allTitle:'关联客户'
+    }
+  },
+  methods:{
+    queryList(id,type,isleave,state){
+      if (this.activeName == '关联客户') {
+        this.paramCus.content.pageNumber = 1
+      }else if (this.activeName == '关联项目'){
+        this.paramPro.content.pageNumber = 1
+      }
+      this.listData(id,type,isleave,state)
+    },
+    async listData(id,type,isleave,state){
+      console.log(this.paramCus,'paramCus')
+      if (this.activeName == '关联客户') {
+        this.paramCus.content.pageNumber = 1
+        this.paramCus.content.pageSize = 10
+        this.paramCus.content.dataid = id
+        this.paramCus.content.type = type
+        this.paramCus.content.where.isleave = isleave
+      }else if (this.activeName == '关联项目'){
+        this.paramPro.content.pageNumber = 1
+        this.paramPro.content.pageSize = 10
+        this.paramPro.content.dataid = id
+        this.paramPro.content.type = type
+        this.paramPro.content.where.isleave = isleave
+      }
+      const res = await this.$api.requested(this.activeName == '关联客户'?this.paramCus:this.paramPro)
+      this.list = res.data
+      this.total = res.total
+      this.currentPage = res.pageNumber
+    },
+    handleClick(tab, event) {
+      if (this.activeName == '关联客户'){
+        this.tablecols = this.tool.tabelCol(this.$route.name).associatedCustomers.tablecols
+        this.listData(this.paramCus.content.dataid,this.paramCus.content.type,this.paramCus.content.where.isleave)
+      }else {
+        this.tablecols = this.tool.tabelCol(this.$route.name).associatedProject.tablecols
+        this.listData(this.paramPro.content.dataid,this.paramPro.content.type,this.paramPro.content.where.isleave)
+      }
+    },
+    btnClick(dateType,dateData){
+      if (this.activeName == '关联客户'){
+        if (dateType){
+          this.paramCus.content.dateType = dateType
+        }else {
+          this.paramCus.content.dateType = ''
+          this.paramCus.content.where.begdate = dateData[0]
+          this.paramCus.content.where.enddate = dateData[1]
+        }
+        this.listData(this.paramCus.content.dataid,this.paramCus.content.type,this.paramCus.content.where.isleave)
+      }else {
+        if (dateType){
+          this.paramPro.content.dateType = dateType
+        }else {
+          this.paramPro.content.dateType = ''
+          this.paramPro.content.where.begdate = dateData[0]
+          this.paramPro.content.where.enddate = dateData[1]
+        }
+        this.listData(this.paramPro.content.dataid,this.paramPro.content.type,this.paramPro.content.where.isleave)
+      }
+    },
+    allClick(){
+      if (this.activeName == '关联客户'){
+        this.$refs.allRankCusRef.drawerShow = true
+        this.$nextTick(()=>{
+          this.$refs.allRankCusRef.$refs.depStatusRef.deplist = this.$refs.depStatusCusRef.deplist
+          this.$refs.allRankCusRef.$refs.depStatusRef.personnelList = this.$refs.depStatusCusRef.personnelList
+          this.$refs.allRankCusRef.$refs.depStatusRef.depment = this.$refs.depStatusCusRef.depment
+          this.$refs.allRankCusRef.$refs.depStatusRef.person = this.$refs.depStatusCusRef.person
+          this.$refs.allRankCusRef.$refs.depStatusRef.isleave = this.$refs.depStatusCusRef.isleave
+          this.$refs.allRankCusRef.param = this.paramCus
+          this.$refs.allRankCusRef.param.content.pageSize = 100
+          this.$refs.allRankCusRef.dateData = this.$refs.btnSelectCusRef.dateData
+          this.$refs.allRankCusRef.listData()
+        })
+      }else {
+        this.$refs.allRankProRef.drawerShow = true
+        this.$nextTick(()=>{
+          this.$refs.allRankProRef.$refs.depStatusRef.deplist = this.$refs.depStatusProRef.deplist
+          this.$refs.allRankProRef.$refs.depStatusRef.personnelList = this.$refs.depStatusProRef.personnelList
+          this.$refs.allRankProRef.$refs.depStatusRef.depment = this.$refs.depStatusProRef.depment
+          this.$refs.allRankProRef.$refs.depStatusRef.person = this.$refs.depStatusProRef.person
+          this.$refs.allRankProRef.$refs.depStatusRef.isleave = this.$refs.depStatusProRef.isleave
+          this.$refs.allRankProRef.param = this.paramPro
+          this.$refs.allRankProRef.param.content.pageSize = 100
+          this.$refs.allRankProRef.dateData = this.$refs.btnSelectProRef.dateData
+          this.$refs.allRankProRef.listData()
+        })
+      }
+    },
+    onCLose(){
+      this.drawerShow = false
+    }
+  },
+  created() {
+    this.tablecols = this.tool.tabelCol(this.$route.name).associatedCustomers.tablecols
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

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

@@ -0,0 +1,248 @@
+<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="{height: heightDiv,width:windowWidth > 1646 ? '70%' : '50%'}">
+            <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",
+  props:['windowWidth'],
+  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>

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

@@ -0,0 +1,252 @@
+<template>
+  <div>
+    <dataTemPlate ref="dataTemPlateRef" :isTitle="true" title="联系人关联客户情况统计" @list="listData" id="statisticsOfCustomerFull">
+      <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="statisticsOfCustomerChart" :style="{height: heightChart}"></div>
+          <div  :style="{height: heightDiv,width:windowWidth > 1646 ? '70%' : '50%'}">
+            <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",
+  props:['windowWidth'],
+  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>

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

@@ -0,0 +1,244 @@
+<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="{height: heightDiv,width:windowWidth > 1646 ? '70%' : '50%'}">
+            <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",
+  props:['windowWidth'],
+  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>

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

@@ -0,0 +1,273 @@
+<template>
+  <div>
+    <dataTemPlate ref="dataTemPlateRef" :isTitle="true" title="联系人关联项目情况统计" @list="listData" id="statisticsOfProjectFull">
+      <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="statisticsOfProjectChart" :style="{height: heightChart}"></div>
+          <div  :style="{height: heightDiv,width:windowWidth > 1646 ? '70%' : '50%'}">
+            <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",
+  props:['windowWidth'],
+  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.where.projecttype = this.paramTable.content.where.projecttype
+      this.paramChart.content.where.status = this.paramTable.content.where.status
+      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>

+ 231 - 0
src/HDrpManagement/contactData/components/statisticsOfUnFollow.vue

@@ -0,0 +1,231 @@
+<template>
+  <div>
+    <dataTemPlate ref="dataTemPlateRef" :isTitle="true" title="联系人未跟进天数分析" @list="listData" id="statisticsOfUnFollowFull" :isFull="isFull">
+      <template slot="operation">
+        <div class="mt-10 inline-16">
+          <span class="search__label inline-16">{{$t('分析日期')}}:</span>
+          <el-date-picker
+              v-model="paramTable.content.enddate"
+              :append-to-body="!isFull"
+              type="date"
+              :clearable="false"
+              @change="changeDate"
+              format="yyyy-MM-dd"
+              value-format="yyyy-MM-dd"
+              size="small"
+              :placeholder="$t(`选择日期`)">
+          </el-date-picker>
+        </div>
+        <exportFile class="inline-16" :param="paramTable" :columns="tablecols" :dataid="paramChart.content.dataid" fileName="联系人未跟进天数分析"></exportFile>
+        <fullScreen class="inline-16"  domId="statisticsOfUnFollowFull" @onFull="onFull" @backFull="backFull"  ></fullScreen>
+      </template>
+      <template slot="content">
+        <div :style="{height:heightDiv}">
+          <div ref="statisticsOfUnFollowChart" :style="{height: heightChart}"></div>
+          <div :style="{height: heightChart}" style="margin-top: 20px">
+            <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 {Column, Pie} from "@antv/g2plot";
+import fullScreen from "@/views/salesData/components/fullScreen";
+import exportFile from '@/components/export_file/index5'
+export default {
+  name: "statisticsOfUnFollow",
+  components:{dataTemPlate,btnSelect,fullScreen,exportFile,
+    drawerTemp:() =>  import('@/components/normal-basic-layout/drawerDetail/index')},
+  data() {
+    return {
+      detailPath:{
+        path:'/contactDataDetail'
+      },
+      idName:'sys_phonebookid',
+      isFull:false,
+      listqueryid:'',
+      paramChart:{
+        "id": 2025073111015902,
+        "content": {
+          "type": 1,
+          "dataid": 58,
+          "enddate": new Date().getFullYear() + '-' +  (new Date().getMonth() + 1) + '-' + new Date().getDate(),
+          "dataType": "",
+          "where": {
+            "isleave": "1"
+          },
+        },
+      },
+      paramTable:{
+        "id": 2025073111020602,
+        "content": {
+          "type": 1,
+          "dataid": 58,
+          "enddate": new Date().getFullYear() + '-' +  (new Date().getMonth() + 1) + '-' + new Date().getDate(),
+          "pageSize": 20,
+          "pageNumber": 1,
+          "where": {
+            "dateType": "",
+            "isleave": "1"
+          }
+        },
+      },
+      tablecols:[],
+      tableList:[],
+      total:0,
+      currentPage:0,
+      chartList:[],
+      chartMap:null,
+      typesData:[],
+      heightChart:'50%',
+      heightDiv:'830px',
+      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 Column(this.$refs.statisticsOfUnFollowChart, {
+          data:this.chartList,
+          xField: 'datetype',
+          yField: 'value',
+          seriesField: 'key',
+          // 添加 中心统计文本 交互
+          interactions: [{ type: 'element-single-selected' },{ type: 'element-active' }],
+          label: {
+            position:top
+          },
+        });
+        this.chartMap.on('element:click',(v) => {
+          // const states = this.chartColumn.getStates()
+          // this.paramTable.content.where.dateType = states.length === 0 ? '':v.data.data.key
+          // this.paramTable.content.pageNumber = 1
+          // this.tableData()
+          if (v.data.data.datetype != this.paramTable.content.where.dateType) {
+            this.paramTable.content.pageNumber = 1
+            this.paramTable.content.where.dateType = v.data.data.datetype
+            this.tableData()
+          } else {
+            this.paramTable.content.pageNumber = 1
+            this.paramTable.content.where.dateType = ''
+            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)
+    },
+    changeDate(){
+      this.paramTable.content.where.dateType = ''
+      this.paramChart.content.enddate = this.paramTable.content.enddate
+      this.listData(this.paramTable.content.dataid,this.paramTable.content.type,this.paramTable.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(50vh - 130px)':'calc(50vh - 130px)'
+      // this.heightTable = '300px'
+      this.isFull = true
+    },
+    /*退出全屏*/
+    backFull(val){
+      // this.heightChart = '100%'
+      this.heightDiv = '830px'
+      this.heightTable = '360px'
+      this.isFull = false
+      this.$emit('backFull',val)
+    }
+  },
+  created() {
+    this.tablecols = this.tool.tabelCol(this.$route.name).contactsUnfollowTable.tablecols
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 799 - 0
src/HDrpManagement/contactData/index.vue

@@ -0,0 +1,799 @@
+<template>
+  <div style="background: #f8f8f8;">
+    <normal-layout>
+      <template #refresh>
+        <el-button size="mini" type="text" style="margin-right: 15px;color: #3874f6;font-size: 14px" @click="toTop">{{ $t('返回顶部') }}</el-button>
+      </template>
+      <template #content>
+        <div style="overflow: auto;height: calc(100vh - 220px)" ref="rollRef" @scroll="handleScroll">
+          <div style="display: flex;justify-content: space-between;margin: 10px 24px 20px 24px;">
+            <depStatus ref="allDepRef" @depData="depData" @personData="depData" @leaveData="depData"></depStatus>
+            <div>
+              <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">
+              <div class="mt-10 inline-16">
+                <p class="search__label">{{$t('状态')}}:</p>
+                <el-select v-model="isleave" clearable style="margin-right:10px" size="small" :placeholder="$t('请选择状态')" @change="leaveChange" disabled>
+                  <el-option :label="$t('在职')" value="1"></el-option>
+                  <el-option :label="$t('离职')" value="2"></el-option>
+                </el-select>
+              </div>
+              <div class="inline-16 mt-10" v-if="titleHeader == '关联客户数'">
+                <label class="search__label">{{ $t("客户类型") }}:</label>
+                <el-select
+                    class="inline-16"
+                    v-model="paramDetail.content.where.type"
+                    size="small"
+                    :placeholder="$t('请选择')"
+                    @change="selectChange"
+                    clearable
+                >
+                  <el-option
+                      v-for="item in option.typeData"
+                      :key="item.value"
+                      :label="$t(item.value)"
+                      :value="item.value"
+                  >
+                  </el-option>
+                </el-select>
+              </div>
+              <div class="mt-10 inline-16" v-if="titleHeader == '关联客户数'">
+                <label class="search__label">{{ $t("合作状态") }}:</label>
+                <el-select
+                    class="inline-16"
+                    v-model="paramDetail.content.where.status"
+                    size="small"
+                    :placeholder="$t('请选择')"
+                    @change="selectChange"
+                    clearable
+                >
+                  <el-option
+                      v-for="item in option.status"
+                      :key="item.value"
+                      :label="$t(item.value)"
+                      :value="item.value"
+                  >
+                  </el-option>
+                </el-select>
+              </div>
+              <div class="mt-10 inline-16" v-if="titleHeader == '关联客户数'">
+                <label class="search__label">{{ $t("成交状态") }}:</label>
+                <el-select
+                    class="inline-16"
+                    v-model="paramDetail.content.where.tradingstatus"
+                    size="small"
+                    :placeholder="$t('请选择')"
+                    @change="selectChange"
+                    clearable
+                >
+                  <el-option
+                      v-for="item in option.tradingstatus"
+                      :key="item.value"
+                      :label="$t(item.value)"
+                      :value="item.value"
+                  >
+                  </el-option>
+                </el-select>
+              </div>
+              <div class="mt-10 inline-16" v-if="titleHeader == '关联项目数'">
+                <label  class="search__label">{{$t(`项目阶段`)}}:</label>
+                <el-select class="inline-16" v-model="paramDetail.content.where.stagename" :placeholder="$t(`请选择项目阶段`)" @change="selectChange" size="small" clearable>
+                  <el-option
+                      v-for="item in option.stageList"
+                      :key="item.stagename"
+                      :label="$t(item.stagename)"
+                      :value="item.stagename">
+                  </el-option>
+                </el-select>
+              </div>
+              <div class="mt-10 inline-16" v-if="titleHeader == '关联项目数'">
+                <label  class="search__label">{{$t(`报备进度`)}}:</label>
+                <el-select class="inline-16" v-model="paramDetail.content.where.reportstatus" :placeholder="$t(`请选择报备进度`)" @change="selectChange" size="small" clearable>
+                  <el-option
+                      v-for="item in option.reportstatus"
+                      :key="item.value"
+                      :label="$t(item.label)"
+                      :value="item.value">
+                  </el-option>
+                </el-select>
+              </div>
+              <div class="mt-10 inline-16" v-if="titleHeader == '关联项目数'">
+                <label  class="search__label">{{$t(`项目类型`)}}:</label>
+                <el-select class="inline-16" v-model="paramDetail.content.where.projecttype" :placeholder="$t('请选择项目类型')" @change="selectChange" size="small" clearable>
+                  <el-option
+                      v-for="item in projectType"
+                      :key="item.value"
+                      :label="$t(item.value)"
+                      :value="item.value">
+                    <span style="float: left">{{ $t(item.value) }}</span>
+                    <span style="float: right; color: #8492a6; font-size: 12px">{{ item.remarks?$t(item.remarks):$t('暂无描述') }}</span>
+                  </el-option>
+                </el-select>
+              </div>
+              <div class="mt-10 inline-16" v-if="titleHeader == '关联项目数' || titleHeader == '关联客户成交金额'">
+                <label  class="search__label">{{$t('领域')}}:</label>
+                <el-select class="inline-16" v-model="paramDetail.content.where.tradefield" :placeholder="$t('请选择领域')" @change="selectChange" size="small" clearable>
+                  <el-option
+                      v-for="item in tradefieldSelect"
+                      :key="item.value"
+                      :label="$t(item.value)"
+                      :value="item.value">
+                    <span style="float: left">{{ $t(item.value) }}</span>
+                    <span style="float: right; color: #8492a6; font-size: 12px">{{ item.remarks?$t(item.remarks):$t('暂无描述') }}</span>
+                  </el-option>
+                </el-select>
+              </div>
+              <div class="inline-16 mt-10" v-if="titleHeader == '联系人总数' || titleHeader == '关联项目数' || titleHeader == '关联客户数'">
+                <span class="search__label">{{$t('标签')}}:</span>
+                <el-select  v-model="tags" :placeholder="$t('请选择标签')" size="small" @change="selectChange" clearable @clear="selectChange" filterable class="inline-16" multiple>
+                  <el-option
+                      v-for="item in tagList"
+                      :key="item.index"
+                      :label="$t(item.tag)"
+                      :value="item.tag"
+                      :disabled="hasDisabledTag(item)">
+                  </el-option>
+                </el-select>
+              </div>
+              <div class="mt-10 inline-16" v-if="titleHeader == '关联项目数'">
+                <label  class="search__label">{{$t(`项目状态`)}}:</label>
+                <el-select class="inline-24" v-model="paramDetail.content.where.status" :placeholder="$t(`请选择项目状态`)" @change="selectChange" size="small" clearable>
+                  <el-option
+                      v-for="item in option.statusTab"
+                      :key="item.value"
+                      :label="$t(item.label)"
+                      :value="item.value">
+                  </el-option>
+                </el-select>
+              </div>
+              <div class="inline-16" v-if="titleHeader == '联系人总数'">
+                <label class="search__label">{{ $t('关联') }}:</label>
+                <el-select  v-model="paramDetail.content.where.contactstype" :placeholder="$t('请选择关联')" size="small" @change="selectChange" clearable @clear="selectChange" class="inline-16">
+                  <el-option :label="$t(`关联线索`)" value="关联线索"></el-option>
+                  <el-option :label="$t(`关联客户`)" value="关联客户"></el-option>
+                  <el-option :label="$t(`关联项目`)" value="关联项目"></el-option>
+                </el-select>
+              </div>
+            </template>
+          </dataDetail>
+          <!--  联系人销售贡献度排行        -->
+          <salesContribution class="mt-10" ref="salesContributionRef"></salesContribution>
+          <!--  近12月联系人新增分析        -->
+          <contactsAddAnalysis class="mt-10" ref="contactsAddAnalysisRef"></contactsAddAnalysis>
+          <!--  联系人关联线索情况统计       -->
+          <statisticsOfClues class="mt-10" ref="statisticsOfCluesRef" :windowWidth="windowWidth"></statisticsOfClues>
+          <!--  联系人关联客户情况统计       -->
+          <statisticsOfCustomer class="mt-10" ref="statisticsOfCustomerRef" :windowWidth="windowWidth"></statisticsOfCustomer>
+          <!--  联系人关联项目情况统计       -->
+          <statisticsOfProject class="mt-10" ref="statisticsOfProjectRef" :windowWidth="windowWidth"></statisticsOfProject>
+          <!--  联系人跟进情况统计       -->
+          <statisticsOfFollow class="mt-10" ref="statisticsOfFollowRef" :windowWidth="windowWidth"></statisticsOfFollow>
+          <!--  近12月联系人跟进分析        -->
+          <contactsFollowAnalysis class="mt-10" ref="contactsFollowAnalysisRef"></contactsFollowAnalysis>
+          <!--  联系人未跟进天数分析        -->
+          <statisticsOfUnFollow class="mt-10" ref="statisticsOfUnFollowRef"></statisticsOfUnFollow>
+        </div>
+      </template>
+    </normal-layout>
+  </div>
+</template>
+
+<script>
+import normalLayout from '@/components/normal-basic-layout/normalNew'
+import btnSelect from "@/components/btn_select/btnSelect";
+import dataBoard from '@/components/dataBoard/index'
+import dataDetail from '@/template/dataDetail/index'
+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'
+import statisticsOfUnFollow from './components/statisticsOfUnFollow'
+export default {
+  name: "index",
+  components:{normalLayout,btnSelect,dataBoard,dataDetail,salesContribution,depStatus,contactsAddAnalysis,contactsFollowAnalysis,statisticsOfClues,statisticsOfCustomer,statisticsOfProject,
+    statisticsOfFollow,statisticsOfUnFollow},
+  data(){
+    return {
+      scrollData:'',
+      depment:'',
+      person:'',
+      isleave:'1',
+      deplist:[],
+      personnelList:[],
+      depmentParam:{
+        "id": 20230620102004,
+        "content": {
+          "isleave":1
+        }
+      },
+      dateType:'本年',
+      windowWidth: document.documentElement.clientWidth,  //实时屏幕宽度
+      userName:JSON.parse(window.sessionStorage.getItem('active_account')).name,
+      mainData:'',
+      paramMain:{
+        "id": 2025072114302202,
+        "content": {
+          "type": 1,
+          "dataid": 58,
+          "dateType": "全部",
+          "where": {
+            "isleave": "1"
+          }
+        },
+      },
+      maninInfo:'',
+      paramDetail:{
+        "id": 2025072213574102,
+        "content": {
+          "type": 1,
+          "dataid": 58,
+          "dateType": "本年",
+          "pageNumber":1,
+          "pageSize":100,
+          "where": {
+            "isleave": "",
+            "condition": "",
+            "tag": [],
+            "contactstype": "", //关联线索,关联客户,关联项目
+            "type":"",
+            "status":"",
+            "tradingstatus":"",
+            "stagename":'',
+            "projecttype":'',
+            "tradefield":'',
+            "reportstatus":''
+          }
+        },
+      },
+      tablecols:'',
+      detailTitle:'',
+      tagList:[],
+      tags:[],
+      titleHeader:'',
+      projectType:[],
+      tradefieldSelect:[],
+      option: {
+        typeData: [],
+        customerClassification: [],
+        customerGrade: [],
+        industryData: [],
+        tagData: [],
+        stageList:[],
+        status: [
+          {
+            value: "潜在",
+          },
+          {
+            value: "合作中",
+          },
+          {
+            value: "暂缓",
+          },
+          {
+            value: "已终止",
+          },
+        ],
+        tradingstatus: [
+          {
+            value: "未成交",
+          },
+          {
+            value: "已成交",
+          },
+          {
+            value: "多次成交",
+          },
+        ],
+        reportstatus:[
+          {
+            value:"未报备",
+            label:"未报备"
+          },
+          {
+            value:"报备中",
+            label:"报备中"
+          },
+          {
+            value:"已报备",
+            label:"已报备"
+          },
+        ],
+        statusTab:[
+          {
+            value:"跟进中",
+            label:"跟进中"
+          },
+          {
+            value:"已成交",
+            label:"已成交"
+          },
+          {
+            value:"已失败",
+            label:"已失败"
+          },
+          {
+            value:"已结案",
+            label:"已结案"
+          }
+        ],
+      },
+    }
+  },
+  watch: {
+    windowWidth (val) {
+      console.log("实时屏幕宽度:",val );
+    }
+  },
+  methods:{
+    /*返回顶部*/
+    toTop(){
+      this.$refs.rollRef.scrollTop = 0
+    },
+
+    /*滚动条*/
+    handleScroll(){
+      this.scrollData = this.$refs.rollRef.scrollTop
+    },
+
+    /*部门人员列表*/
+    async departmentrtment() {
+      const res = await this.$api.requested(this.depmentParam)
+      this.deplist = this.createMenu(res.data.dep)
+      this.$refs.allDepRef.deplist = this.deplist
+      this.$refs.salesContributionRef.$refs.depStatusCusRef.deplist = this.deplist
+      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.$refs.statisticsOfUnFollowRef.$refs.dataTemPlateRef.$refs.depStatusRef.deplist = this.deplist
+
+      this.personnelList = res.data.hr
+      this.$refs.allDepRef.personnelList = this.personnelList
+      this.$refs.salesContributionRef.$refs.depStatusCusRef.personnelList = this.personnelList
+      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.$refs.statisticsOfUnFollowRef.$refs.dataTemPlateRef.$refs.depStatusRef.personnelList = this.personnelList
+
+      this.depment = ''
+      this.$refs.allDepRef.depment = this.depment
+      this.$refs.salesContributionRef.$refs.depStatusCusRef.depment = this.depment
+      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.$refs.statisticsOfUnFollowRef.$refs.dataTemPlateRef.$refs.depStatusRef.depment = this.depment
+
+      this.person = JSON.parse(window.sessionStorage.getItem('active_account')).name
+      this.$refs.allDepRef.person = this.person
+      this.$refs.salesContributionRef.$refs.depStatusCusRef.person = this.person
+      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
+      this.$refs.statisticsOfUnFollowRef.$refs.dataTemPlateRef.$refs.depStatusRef.person = this.person
+
+      const userid = JSON.parse(sessionStorage.getItem('active_account')).userid
+      this.otherMethod(userid)
+    },
+    /*部门结构处理*/
+    createMenu (array) {
+      var that = this
+      let arr = []
+      function convertToElementTree(node) {
+        // 新节点
+        if (node.subdep.length === 0){
+          var elNode = {
+            label: node["depname"],
+            parentid:node['parentid'],
+            parentname:node['parentname'],
+            departmentid:node["departmentid"],
+            value:node["departmentid"],
+            remarks:node["remarks"],
+            isused:node["isused"],
+            changedate:node['changedate'],
+            changeby:node['changeby'],
+            createdate:node['createdate'],
+            createby:node['createby'],
+            depno:node['depno'],
+            disabled:that.pageOnlyRead,
+          }
+        }else {
+          var elNode = {
+            label: node["depname"],
+            parentid:node['parentid'],
+            parentname:node['parentname'],
+            departmentid:node["departmentid"],
+            value:node["departmentid"],
+            remarks:node["remarks"],
+            isused:node["isused"],
+            changedate:node['changedate'],
+            changeby:node['changeby'],
+            createdate:node['createdate'],
+            createby:node['createby'],
+            depno:node['depno'],
+            disabled:that.pageOnlyRead,
+            children: []
+          }
+        }
+        if (node.subdep && node.subdep.length > 0) {
+          // 如果存在子节点
+          for (var index = 0; index < node.subdep.length; index++) {
+            // 遍历子节点, 把每个子节点看做一颗独立的树, 传入递归构造子树, 并把结果放回到新node的children中
+            elNode.children.push(convertToElementTree(node.subdep[index]));
+          }
+        }
+        return elNode;
+      }
+      array.forEach((element) => {
+        arr.push(convertToElementTree(element))
+      });
+      return arr
+    },
+    /*选择部门*/
+    selectDep(val) {
+      if (val.length === 0){
+        const userid = JSON.parse(sessionStorage.getItem('active_account')).userid
+        this.otherModel(userid,'0')
+      }else {
+        this.person = ''
+        this.departmentid = val[val.length -1]
+        this.otherModel(this.departmentid,'1',this.isleave)
+      }
+    },
+    /*选择人员*/
+    selectPerson(val){
+      this.depment = ''
+      this.departmentid = ''
+      this.dataid = val
+      this.otherModel(val,'0',this.isleave)
+    },
+    /*选择在职状态*/
+    leaveChange(){
+      this.person = ''
+      const type = this.depment?'1':'0'
+      const dataid = type == 0?-1:this.departmentid
+      this.otherModel(dataid,type,this.isleave,'状态')
+      this.personData()
+    },
+    /*获取新的业务员列表*/
+    async personData(){
+      let param = {
+        id: 20230620102004,
+        content: {
+          isleave:this.isleave
+        },
+      }
+      const res = await this.$api.requested(param)
+      this.personnelList = res.data.hr
+    },
+    /*切换时间*/
+    btnClick(data){
+      this.dateType = data
+      this.queryMainData(this.paramMain.content.dataid,data)
+    },
+    /*选择部门*/
+    depData(id,type,isleave,state){
+      this.otherModel(id,type,isleave,state)
+    },
+    /*其他页面首次调用*/
+    otherMethod(dataid){
+      const userName = JSON.parse(sessionStorage.getItem('active_account')).name
+      /*联系人数据概况*/
+      this.paramMain.content.type = '0'
+      this.queryMainData(dataid,this.dateType)
+      this.$refs.salesContributionRef.paramCus.content.dateType = '本年'
+      this.$refs.salesContributionRef.paramPro.content.dateType = '本年'
+      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)
+      this.$refs.statisticsOfUnFollowRef.listData(dataid,0,1,null,true)
+    },
+    /*其他页面再次调用*/
+    otherModel(dataid,type,isleave,state){
+      this.paramMain.content.type = type
+      this.paramMain.content.where.isleave = isleave
+      this.paramMain.content.dataid = dataid
+      this.person = state == '状态' ? '' : type == 0  ? dataid : ''
+      this.depment = type == 0 ? '' : dataid
+      this.isleave = isleave
+      this.queryMainData(dataid,this.dateType)
+
+      /*联系人销售贡献度排行*/
+      this.$refs.salesContributionRef.$refs.depStatusProRef.person = state == '状态' ? '' : type == 0  ? dataid : ''
+      this.$refs.salesContributionRef.$refs.depStatusCusRef.person = state == '状态' ? '' : type == 0 ? dataid : ''
+      this.$refs.salesContributionRef.$refs.depStatusCusRef.depment = type == 0 ? '' : dataid
+      this.$refs.salesContributionRef.$refs.depStatusProRef.depment = type == 0 ? '' : dataid
+      this.$refs.salesContributionRef.$refs.depStatusProRef.isleave = isleave
+
+      this.$refs.salesContributionRef.$refs.depStatusCusRef.isleave = isleave
+      this.$refs.salesContributionRef.listData(dataid,type,isleave,state)
+
+      /*近12月联系人新增分析*/
+      this.$refs.contactsAddAnalysisRef.$refs.dataTemPlateRef.$refs.depStatusRef.person = state == '状态' ? '' : type == 0  ? dataid : ''
+      this.$refs.contactsAddAnalysisRef.$refs.dataTemPlateRef.$refs.depStatusRef.depment = type == 0 ? '' : dataid
+      this.$refs.contactsAddAnalysisRef.$refs.dataTemPlateRef.$refs.depStatusRef.isleave = isleave
+      this.$refs.contactsAddAnalysisRef.listData(dataid,type,1,state,null)
+
+      /*联系人关联线索情况统计*/
+      this.$refs.statisticsOfCluesRef.$refs.dataTemPlateRef.$refs.depStatusRef.person = state == '状态' ? '' : type == 0  ? dataid : ''
+      this.$refs.statisticsOfCluesRef.$refs.dataTemPlateRef.$refs.depStatusRef.depment = type == 0 ? '' : dataid
+      this.$refs.statisticsOfCluesRef.$refs.dataTemPlateRef.$refs.depStatusRef.isleave = isleave
+      this.$refs.statisticsOfCluesRef.paramTable.content.pageNumber = 1
+      this.$refs.statisticsOfCluesRef.listData(dataid,type,1,state,null)
+
+      /*联系人关联客户情况统计*/
+      this.$refs.statisticsOfCustomerRef.$refs.dataTemPlateRef.$refs.depStatusRef.person = state == '状态' ? '' : type == 0  ? dataid : ''
+      this.$refs.statisticsOfCustomerRef.$refs.dataTemPlateRef.$refs.depStatusRef.depment = type == 0 ? '' : dataid
+      this.$refs.statisticsOfCustomerRef.$refs.dataTemPlateRef.$refs.depStatusRef.isleave = isleave
+      this.$refs.statisticsOfCustomerRef.paramTable.content.pageNumber = 1
+      this.$refs.statisticsOfCustomerRef.listData(dataid,type,1,state,null)
+
+      /*联系人关联项目情况统计*/
+      this.$refs.statisticsOfProjectRef.$refs.dataTemPlateRef.$refs.depStatusRef.person = state == '状态' ? '' : type == 0  ? dataid : ''
+      this.$refs.statisticsOfProjectRef.$refs.dataTemPlateRef.$refs.depStatusRef.depment = type == 0 ? '' : dataid
+      this.$refs.statisticsOfProjectRef.$refs.dataTemPlateRef.$refs.depStatusRef.isleave = isleave
+      this.$refs.statisticsOfProjectRef.paramTable.content.pageNumber = 1
+      this.$refs.statisticsOfProjectRef.listData(dataid,type,1,state,null)
+
+      /*联系人跟进情况统计*/
+      this.$refs.statisticsOfFollowRef.$refs.dataTemPlateRef.$refs.depStatusRef.person = state == '状态' ? '' : type == 0  ? dataid : ''
+      this.$refs.statisticsOfFollowRef.$refs.dataTemPlateRef.$refs.depStatusRef.depment = type == 0 ? '' : dataid
+      this.$refs.statisticsOfFollowRef.$refs.dataTemPlateRef.$refs.depStatusRef.isleave = isleave
+      this.$refs.statisticsOfFollowRef.paramTable.content.pageNumber = 1
+      this.$refs.statisticsOfFollowRef.listData(dataid,type,1,state,null)
+
+      /*近12月联系人跟进分析*/
+      this.$refs.contactsFollowAnalysisRef.$refs.dataTemPlateRef.$refs.depStatusRef.person = state == '状态' ? '' : type == 0  ? dataid : ''
+      this.$refs.contactsFollowAnalysisRef.$refs.dataTemPlateRef.$refs.depStatusRef.depment = type == 0 ? '' : dataid
+      this.$refs.contactsFollowAnalysisRef.$refs.dataTemPlateRef.$refs.depStatusRef.isleave = isleave
+      this.$refs.contactsFollowAnalysisRef.listData(dataid,type,1,state,null)
+
+      /*联系人未跟进天数分析*/
+      this.$refs.statisticsOfUnFollowRef.$refs.dataTemPlateRef.$refs.depStatusRef.person = state == '状态' ? '' : type == 0  ? dataid : ''
+      this.$refs.statisticsOfUnFollowRef.$refs.dataTemPlateRef.$refs.depStatusRef.depment = type == 0 ? '' : dataid
+      this.$refs.statisticsOfUnFollowRef.$refs.dataTemPlateRef.$refs.depStatusRef.isleave = isleave
+      this.$refs.statisticsOfUnFollowRef.paramTable.content.pageNumber = 1
+      this.$refs.statisticsOfUnFollowRef.listData(dataid,type,1,state,null)
+    },
+    /*联系人数据概况*/
+    async queryMainData(dataid,dateType){
+      this.paramMain.content.dataid = dataid
+      this.paramMain.content.dateType = dateType
+      const res = await this.$api.requested(this.paramMain)
+      if (res.code == 0){
+        this.tool.showMessage(res,()=>{})
+      }else {
+        this.mainData = res.data
+        this.changeDataStructure()
+      }
+    },
+    changeDataStructure(){
+      let that = this
+      this.maninInfo = [
+        {
+          label:'联系人总数',
+          value:this.tool.qtyShow(this.mainData.count_phonebook),
+          isTooltip:true,
+          tooltip:'统计跟进联系人总数量。'
+        },
+        {
+          label:'联系人跟进次数',
+          value:this.tool.qtyShow(this.mainData.count_follow),
+          isTooltip:true,
+          tooltip:'统计在【联系人】应用,跟进联系人次数。'
+        },
+        {
+          label:'关联客户数',
+          value:this.tool.qtyShow(this.mainData.count_customer),
+          isTooltip:true,
+          tooltip:'统计联系人关联的客户数量。'
+        },
+        {
+          label:'关联项目数',
+          value:this.tool.qtyShow(this.mainData.count_project),
+          isTooltip:true,
+          tooltip:'统计联系人关联的项目数量。'
+        },
+        {
+          label:'关联客户成交金额',
+          // value:this.tool.formatAmount(this.mainData.amount_customer,2,'¥'),
+          value:this.mainData.amount_customer < 10000 ? this.tool.formatAmount(this.mainData.amount_customer,2,'¥'):
+              this.tool.formatAmount(this.tool.unitConversion(this.mainData.amount_customer,10000),2,'¥'),
+          isTooltip:true,
+          isTitle:this.mainData.amount_customer < 10000?false:true,
+          tooltip:'统计联系人关联的客户标准、特殊订单下单金额。'
+        },
+        {
+          label:'关联项目成交金额',
+          value:this.mainData.amount_project < 10000 ? this.tool.formatAmount(this.mainData.amount_project,2,'¥'):
+                this.tool.formatAmount(this.tool.unitConversion(this.mainData.amount_project,10000),2,'¥'),
+          isTooltip:true,
+          isTitle:this.mainData.amount_project < 10000?false:true,
+          tooltip:'统计联系人关联的项目订单下单金额。'
+        }
+      ]
+    },
+    goDetail(data){
+      this.titleHeader = data
+      if (data == '联系人总数'){
+        this.paramDetail.id =2025072213574102
+        this.tablecols = this.tool.tabelCol(this.$route.name).contactsTotalTable.tablecols
+        this.getTagList()
+      }else if (data == '联系人跟进次数'){
+        this.paramDetail.id = 2025072213575402
+        this.tablecols = this.tool.tabelCol(this.$route.name).contactsFollowTable.tablecols
+      }else if (data == '关联客户数'){
+        this.paramDetail.id = 2025072213580402
+        this.tablecols = this.tool.tabelCol(this.$route.name).associatedCustomersTable.tablecols
+        this.getSelectData()
+        this.getTagList()
+      }else if (data == '关联项目数'){
+        this.paramDetail.id = 2025072213581302
+        this.tablecols = this.tool.tabelCol(this.$route.name).associatedProjectsTable.tablecols
+        this.stageData()
+        this.getSelectData()
+        this.getTagList()
+      }else if (data == '关联客户成交金额'){
+        this.paramDetail.id = 2025072213582002
+        this.tablecols = this.tool.tabelCol(this.$route.name).associatedAmountTable.tablecols
+        this.getSelectData()
+      }else if (data == '关联项目成交金额'){
+        this.paramDetail.id = 2025072213582602
+        this.tablecols = this.tool.tabelCol(this.$route.name).associatedAmountTable.tablecols
+        this.getSelectData()
+      }
+      this.detailTitle = this.$t(this.dateType) + '_' + this.$t(data)
+      this.paramDetail.content.dataid = this.paramMain.content.dataid
+      this.paramDetail.content.type = this.paramMain.content.type
+      this.paramDetail.content.dateType = this.paramMain.content.dateType
+      this.paramDetail.content.where.isleave = this.paramMain.content.where.isleave
+      this.$refs.detailRef.onShow()
+    },
+    /*获取联系人标签*/
+    async getTagList () {
+      if (this.titleHeader == '联系人总数'){
+        let res = await this.$api.requested({
+          "id": 20220929085401,
+          "content": {
+            "ownertable":"sys_phonebook",
+            "ownerid":102
+          }
+        })
+        this.tagList = res.data.option
+      }else if (this.titleHeader == '关联客户数'){
+        const res = await this.$api.requested({
+          id: 20221013104401,
+          content: {
+            isExport: 1,
+            pageNumber: 1,
+            pageSize: 100,
+            sys_systemtagid: 2,
+            where: {
+              condition: "",
+            },
+          },
+        });
+        this.tagList = this.unique(res.data)
+      }else if (this.titleHeader == '关联项目数'){
+        const res = await this.$api.requested({
+          "id":20221013104401,
+          "content":{
+            "isExport":1,
+            "pageNumber":1,
+            "pageSize":100,
+            "sys_systemtagid":1,
+            "where":{
+              "condition":""
+            }
+          }
+        })
+        this.tagList = this.unique(res.data)
+      }
+    },
+    /*去重*/
+    unique(arr) {
+      const res = new Map();
+      return arr.filter((arr) => !res.has(arr.tag) && res.set(arr.tag, 1));
+    },
+    selectChange(){
+      this.paramDetail.content.where.tag = this.tags
+      this.$refs.detailRef.listData()
+    },
+    hasDisabledTag (item) {
+      let arr = []
+      let arr2 = []
+      arr = this.tagList.filter(item=>{
+        return this.tags.includes(item.tag)
+      })
+      arr.forEach(e=>{
+        arr2 = arr2.concat(e.mutextag)
+      })
+      arr2 = this.tags.length === 0?[]:arr2
+      let _isSame = arr2.some(tag=>item.tag === tag)
+      return _isSame
+    },
+    clearSearchValue () {
+      this.$store.dispatch('clearSearchValue')
+      this.$refs.detailRef.listData(this.paramDetail.content.pageNumber = 1)
+    },
+    /*获取自定义选项数据*/
+    async getSelectData(){
+      if (this.titleHeader == '关联客户数'){
+        const res = await this.$store.dispatch("optiontypeselect", "customertypemx")
+        this.option.typeData = res.data
+      }else if (this.titleHeader == '关联项目数'){
+        const res = await this.$store.dispatch("optiontypeselect", "projecttype")
+        this.projectType = res.data
+        const res1 = await this.$store.dispatch("optiontypeselect", "tradefield")
+        this.tradefieldSelect = res1.data
+      }else {
+        const res1 = await this.$store.dispatch("optiontypeselect", "tradefield")
+        this.tradefieldSelect = res1.data
+      }
+    },
+    /*获取阶段*/
+    async stageData(){
+      const res = await this.$api.requested({
+        "id": 20221128143604,
+        "content": {
+          "pageNumber": 1,
+          "pageSize": 99,
+          "where": {
+            "condition": "",
+            "allprojecttype":"",
+            "projecttype":""
+          }
+        }
+      })
+      this.option.stageList = res.data
+    },
+  },
+  mounted() {
+    this.departmentrtment()
+
+    var that = this;
+    // <!--把window.onresize事件挂在到mounted函数上-->
+    window.onresize = () => {
+      return (() => {
+        window.fullWidth = document.documentElement.clientWidth;
+        that.windowWidth = window.fullWidth; // 宽
+      })()
+    };
+  },
+  created() {
+    // this.tablecols = this.tool.tabelCol(this.$route.name).contactsTotalTable.tablecols
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 3 - 0
src/HDrpManagement/contactProfile/modules/detail.vue

@@ -225,6 +225,9 @@
               >
                 <template v-slot:custom="scope">
                   <div v-if="scope.data.columnname === 'followname'"></div>
+                  <div v-else-if="scope.data.columnname == 'ordercluename'">
+                    {{scope.data.data[scope.data.columnname].length > 0 ? scope.data.data[scope.data.columnname] : '--'}}
+                  </div>
                   <div
                     v-else
                     style="

+ 24 - 3
src/HDrpManagement/dataanalysis/index.vue

@@ -47,6 +47,9 @@
               <el-tab-pane :label="$t(`客户`)" name="客户">
                 <customer ref="customer" :param="tableParam" :isDep="isDep" :dataid="dataid" :isPerson="isPerson"></customer>
               </el-tab-pane>
+              <el-tab-pane :label="$t(`联系人`)" name="联系人">
+                <contact ref="contact" :param="tableParam" :isDep="isDep" :dataid="dataid" :isPerson="isPerson"></contact>
+              </el-tab-pane>
               <el-tab-pane :label="$t(`项目商机`)" name="项目商机">
                 <project ref="project" :param="tableParam" :isDep="isDep" :dataid="dataid" :isPerson="isPerson"></project>
               </el-tab-pane>
@@ -72,6 +75,7 @@ import customer from './modules/customer'
 import project from './modules/project'
 import documents from './modules/documents'
 import normalLayout from '@/components/normal-basic-layout/normalData'
+import contact from './modules/contact'
 export default {
   name: "index",
   data(){
@@ -112,7 +116,7 @@ export default {
         "content": {
           "pageNumber": 1,
           "pageSize": 10,
-          "dataType":"",//1 线索新增列表 2 线索更新列表 3 线索跟进列表4 客户新增列表 5 客户更新列表 6 客户跟进列表 7 项目新增列表8 项目更新列表 9 项目跟进列表 10 报价单列表 11 合同列表
+          "dataType":"",//1 线索新增列表 2 线索更新列表 3 线索跟进列表4 客户新增列表 5 客户更新列表 6 客户跟进列表 7 项目新增列表8 项目更新列表 9 项目跟进列表 10 报价单列表 11 合同列表 12 联系人新增 13 联系人更进 14 联系人更新
           "type":'',//0 按人搜素 1 按部门搜索
           "dataid":"",// 人员id或部门id
           "dateType":'',
@@ -126,7 +130,7 @@ export default {
     }
   },
   components:{
-    assignmentData,salesData,performanceData,clue,customer,project,documents,normalLayout
+    assignmentData,salesData,performanceData,clue,customer,project,documents,normalLayout,contact
   },
   methods:{
     async departmentrtment() {
@@ -284,6 +288,10 @@ export default {
       }else if (this.tabName === '作业单据'){
         this.$refs.documents.queryQuotation()
         this.$refs.documents.queryContract()
+      }else if (this.tabName === '联系人'){
+        this.$refs.contact.queryAdd()
+        this.$refs.contact.queryUpdate()
+        this.$refs.contact.queryFollow()
       }
     },
     clickFull(type,time,val){
@@ -329,8 +337,21 @@ export default {
         this.$refs.project.$refs.quickFow.select = time
         this.$refs.project.$refs.quickFow.selectData(val)
         this.$refs.project.$refs.fowFullRef.enterFullscreen()
+      }else if (type == '新增联系人'){
+        this.tabName = '联系人'
+        this.$refs.contact.disabled = true
+        this.$refs.contact.selectAdd = time
+        this.$refs.contact.$refs.quickAdd.select = time
+        this.$refs.contact.$refs.quickAdd.selectData(val)
+        this.$refs.contact.$refs.addFullRef.enterFullscreen()
+      }else if (type == '联系人跟进'){
+        this.tabName = '联系人'
+        this.$refs.contact.disabled = true
+        this.$refs.contact.selectFow = time
+        this.$refs.contact.$refs.quickFow.select = time
+        this.$refs.contact.$refs.quickFow.selectData(val)
+        this.$refs.contact.$refs.fowFullRef.enterFullscreen()
       }
-
     }
 
   },

+ 16 - 16
src/HDrpManagement/dataanalysis/modules/assignmentData.vue

@@ -36,14 +36,14 @@
                   <div class="title-font" style="color: #16BDFF">{{list.bzkhgj}}</div>
                 </div>
               </el-col>
-              <el-col :span="3" >
-                <div>
+              <el-col :span="3" class="titleHover">
+                <div @click="onClick('新增联系人','周',2)">
                   <div>{{$t(`新增联系人`)}}</div>
                   <div class="title-font" style="color: #F09E00">{{list.bzlxxz}}</div>
                 </div>
               </el-col>
-              <el-col :span="3" >
-                <div>
+              <el-col :span="3" class="titleHover">
+                <div @click="onClick('联系人跟进','周',2)">
                   <div>{{$t(`联系人跟进`)}}</div>
                   <div class="title-font" style="color: #FF7602">{{list.bzlxgj}}</div>
                 </div>
@@ -99,14 +99,14 @@
                   <div class="title-font" style="color: #16BDFF">{{list.bykhgj}}</div>
                 </div>
               </el-col>
-              <el-col :span="3" >
-                <div>
+              <el-col :span="3" class="titleHover">
+                <div @click="onClick('新增联系人','月',3)">
                   <div>{{$t(`新增联系人`)}}</div>
                   <div class="title-font" style="color: #F09E00">{{list.bylxxz}}</div>
                 </div>
               </el-col>
-              <el-col :span="3" >
-                <div>
+              <el-col :span="3" class="titleHover">
+                <div @click="onClick('联系人跟进','月',3)">
                   <div>{{$t(`联系人跟进`)}}</div>
                   <div class="title-font" style="color: #FF7602">{{list.bylxgj}}</div>
                 </div>
@@ -162,14 +162,14 @@
                   <div class="title-font" style="color: #16BDFF">{{list.sykhgj}}</div>
                 </div>
               </el-col>
-              <el-col :span="3">
-                <div>
+              <el-col :span="3" class="titleHover">
+                <div @click="onClick('新增联系人','上月',5)">
                   <div>{{$t(`新增联系人`)}}</div>
                   <div class="title-font" style="color: #F09E00">{{list.sylxxz}}</div>
                 </div>
               </el-col>
-              <el-col :span="3" >
-                <div>
+              <el-col :span="3" class="titleHover">
+                <div @click="onClick('联系人跟进','上月',5)">
                   <div>{{$t(`联系人跟进`)}}</div>
                   <div class="title-font" style="color: #FF7602">{{list.sylxgj}}</div>
                 </div>
@@ -225,14 +225,14 @@
                   <div class="title-font" style="color: #16BDFF">{{list.bnkhgj}}</div>
                 </div>
               </el-col>
-              <el-col :span="3" >
-                <div>
+              <el-col :span="3" class="titleHover">
+                <div @click="onClick('新增联系人','年',4)">
                   <div>{{$t(`新增联系人`)}}</div>
                   <div class="title-font" style="color: #F09E00">{{list.bnlxxz}}</div>
                 </div>
               </el-col>
-              <el-col :span="3" >
-                <div>
+              <el-col :span="3" class="titleHover">
+                <div @click="onClick('联系人跟进','年',4)">
                   <div>{{$t(`联系人跟进`)}}</div>
                   <div class="title-font" style="color: #FF7602">{{list.bnlxgj}}</div>
                 </div>

+ 314 - 0
src/HDrpManagement/dataanalysis/modules/contact.vue

@@ -0,0 +1,314 @@
+<template>
+  <div>
+    <el-scrollbar>
+      <div style="margin: auto;">
+        <div id="contactAddFull" style="background: #FFFFFF" :style="{padding:isFull ?'16px':0}">
+          <div style="display: flex;justify-content: space-between">
+            <div>
+              <span style="font-size: 16px;color: #333">{{$t(`新增联系人`)}}</span>
+            </div>
+            <div>
+              <quickDate class="inline-16" ref="quickAdd" @selectQuick="selectQuickAdd" :disabled="disabled"></quickDate>
+              <fullScreen ref="addFullRef" class="inline-16" domId="contactAddFull" @onFull="onFull('新增')" @backFull="backFull('新增')"></fullScreen>
+            </div>
+          </div>
+          <tableLayout style="margin-top: 10px" :layout="tablecolsAdd" :data="listAdd" :opwidth="200" :width="true" :custom="true" :height="isFull ?'calc(100vh - 150px)':tableHeight">
+            <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>
+              <p v-else>{{scope.column.data[scope.column.columnname]?$t(scope.column.data[scope.column.columnname]):'--'}}</p>
+            </template>
+          </tableLayout>
+          <div class="container normal-panel" style="text-align:right">
+            <el-pagination
+                background
+                @size-change="handleSizeChangeAdd"
+                @current-change="handleCurrentChangeAdd"
+                :current-page="currentPageAdd"
+                :page-sizes="isFull ?[100,150, 200, 250]:[10,20, 50, 100, 200]"
+                :page-size="isFull ?100:10"
+                layout="total,sizes, prev, pager, next, jumper"
+                :total="totalAdd">
+            </el-pagination>
+          </div>
+        </div>
+        <div id="contactUpdFull" style="background: #FFFFFF" :style="{padding:isFull ?'16px':0}">
+          <div style="display: flex;justify-content: space-between">
+            <div>
+              <span style="font-size: 16px;color: #333">{{$t(`更新联系人`)}}</span>
+            </div>
+            <div>
+              <quickDate class="inline-16"  ref="quickUpd" @selectQuick="selectQuickUpd"></quickDate>
+              <fullScreen ref="updFullRef" class="inline-16" domId="contactUpdFull" @onFull="onFull('更新')" @backFull="backFull('更新')"></fullScreen>
+            </div>
+          </div>
+          <tableLayout style="margin-top: 10px" :layout="tablecolsUpdate" :data="listUpdate" :opwidth="200" :custom="true" :height="isFull ?'calc(100vh - 150px)':tableHeight">
+            <template v-slot:customcol="scope">
+              <p>{{scope.column.data[scope.column.columnname]?$t(scope.column.data[scope.column.columnname]):'--'}}</p>
+            </template>
+          </tableLayout>
+          <div class="container normal-panel" style="text-align:right">
+            <el-pagination
+                background
+                @size-change="handleSizeChangeUpdate"
+                @current-change="handleCurrentChangeUpdate"
+                :current-page="currentPageUpdate"
+                :page-sizes="isFull ?[100,150, 200, 250]:[10,20, 50, 100, 200]"
+                :page-size="isFull ?100:10"
+                layout="total,sizes, prev, pager, next, jumper"
+                :total="totalUpdate">
+            </el-pagination>
+          </div>
+        </div>
+        <div id="contactFowFull" style="background: #FFFFFF" :style="{padding:isFull ?'16px':0}">
+          <div style="display: flex;justify-content: space-between">
+            <div>
+              <span style="font-size: 16px;color: #333">{{$t(`跟进联系人`)}}</span>
+            </div>
+            <div>
+              <quickDate class="inline-16" ref="quickFow" @selectQuick="selectQuickFow" :disabled="disabled"></quickDate>
+              <fullScreen ref="fowFullRef" class="inline-16" domId="contactFowFull" @onFull="onFull('跟进')" @backFull="backFull('跟进')"></fullScreen>
+            </div>
+          </div>
+          <tableLayout style="margin-top: 10px" :layout="tablecolsFollow" :data="listFollow" :opwidth="200" :custom="true" :height="isFull ?'calc(100vh - 150px)':tableHeight">
+            <template v-slot:customcol="scope">
+              <p v-if="scope.column.columnname === 'followname'">
+              <span v-if="scope.column.data.followname.length > 0">
+                <span v-for="(item,index) in scope.column.data.followname">
+                <span v-if="index === scope.column.data.followname.length -1">
+                  {{$t(item)}}
+                </span>
+                <span v-else>
+                  {{item + ','}}
+                </span>
+              </span>
+              </span>
+                <span v-else>--</span>
+              </p>
+              <p v-else>{{scope.column.data[scope.column.columnname]?$t(scope.column.data[scope.column.columnname]):'--'}}</p>
+            </template>
+          </tableLayout>
+          <div class="container normal-panel" style="text-align:right">
+            <el-pagination
+                background
+                @size-change="handleSizeChangeFollow"
+                @current-change="handleCurrentChangeFollow"
+                :current-page="currentPageFollow"
+                :page-sizes="isFull ?[100,150, 200, 250]:[10,20, 50, 100, 200]"
+                :page-size="isFull ?100:10"
+                layout="total,sizes, prev, pager, next, jumper"
+                :total="totalFollow">
+            </el-pagination>
+          </div>
+        </div>
+      </div>
+    </el-scrollbar>
+  </div>
+</template>
+
+<script>
+import quickDate from "@/HDrpManagement/dataanalysis/components/quickDate";
+import tableLayout from '@/components/table/index9'
+import fullScreen from "@/views/salesData/components/fullScreen";
+export default {
+  name: "contact",
+  props:['param','isDep','dataid','isPerson'],
+  components:{quickDate,tableLayout,fullScreen},
+  data() {
+    return {
+      listAdd:[],
+      tablecolsAdd:[],
+      listUpdate:[],
+      tablecolsUpdate:[],
+      tableHeight:'',
+      currentPageAdd:0,
+      totalAdd:0,
+      currentPageUpdate:0,
+      totalUpdate:0,
+      listFollow:[],
+      tablecolsFollow:[],
+      currentPageFollow:0,
+      totalFollow:0,
+      begindate:'',
+      enddate:'',
+      selectAdd:'月',
+      selectUpd:'月',
+      selectFow:'月',
+      sort:[
+        {
+          reversed : 0,
+          sorted: 1,
+          sortid: 207,
+          sortname: "新增,更新排序"
+        },
+        {
+          reversed : 0,
+          sorted: 1,
+          sortid: 208,
+          sortname: "跟进排序"
+        }
+      ],
+      isFull:false,
+      disabled:false
+    }
+  },
+  methods:{
+    async queryAdd(type){
+      this.$refs.quickAdd.select = type?type:this.selectAdd
+      this.param.content.dataType = 12
+      this.param.content.where.begindate = this.selectAdd ? '' :this.begindate
+      this.param.content.where.enddate = this.selectAdd ? '' : this.enddate
+      this.param.content.dateType = type?type:this.selectAdd
+      this.param.content.dataid = this.dataid
+      this.param.content.type = this.isDep?1:0
+      this.param.content.sort = [this.sort[0]]
+      const res = await this.$api.requested(this.param)
+      this.listAdd = res.data
+      this.currentPageAdd = res.pageNumber
+      this.totalAdd = res.total
+    },
+    handleSizeChangeAdd(val) {
+      // console.log(`每页 ${val} 条`);
+      this.param.content.pageSize = val
+      this.queryAdd()
+    },
+    handleCurrentChangeAdd(val) {
+      // console.log(`当前页: ${val}`);
+      this.param.content.pageNumber = val
+      this.queryAdd()
+    },
+    async queryUpdate(type){
+      this.$refs.quickUpd.select = type?type:this.selectUpd
+      this.param.content.dataType = 14
+      this.param.content.where.begindate = this.selectUpd ? '' :this.begindate
+      this.param.content.where.enddate = this.selectUpd ? '' : this.enddate
+      this.param.content.dateType = type?type:this.selectUpd
+      this.param.content.dataid = this.dataid
+      this.param.content.type = this.isDep?1:0
+      this.param.content.sort = [this.sort[0]]
+      const res = await this.$api.requested(this.param)
+      this.listUpdate = res.data
+      this.currentPageUpdate = res.pageNumber
+      this.totalUpdate = res.total
+    },
+    handleSizeChangeUpdate(val) {
+      // console.log(`每页 ${val} 条`);
+      this.param.content.pageSize = val
+      this.queryUpdate()
+    },
+    handleCurrentChangeUpdate(val) {
+      // console.log(`当前页: ${val}`);
+      this.param.content.pageNumber = val
+      this.queryUpdate()
+    },
+    async queryFollow(type){
+      this.$refs.quickFow.select = type?type:this.selectFow
+      this.param.content.dataType = 13
+      this.param.content.where.begindate = this.selectFow ? '' :this.begindate
+      this.param.content.where.enddate = this.selectFow ? '' : this.enddate
+      this.param.content.dateType = type?type:this.selectFow
+      this.param.content.dataid = this.dataid
+      this.param.content.type = this.isDep?1:0
+      this.param.content.sort = [this.sort[1]]
+      const res = await this.$api.requested(this.param)
+      this.listFollow = res.data
+      this.currentPageFollow = res.pageNumber
+      this.totalFollow = res.total
+    },
+    handleSizeChangeFollow(val) {
+      // console.log(`每页 ${val} 条`);
+      this.param.content.pageSize = val
+      this.queryFollow()
+    },
+    handleCurrentChangeFollow(val) {
+      // console.log(`当前页: ${val}`);
+      this.param.content.pageNumber = val
+      this.queryFollow()
+    },
+    /*日期筛选*/
+    selectQuickAdd(begindate,enddate,select){
+      this.begindate = begindate
+      this.enddate = enddate
+      this.selectAdd = select
+      this.param.content.pageNumber = 1
+      this.queryAdd()
+    },
+    selectQuickUpd(begindate,enddate,select){
+      this.begindate = begindate
+      this.enddate = enddate
+      this.selectUpd = select
+      this.param.content.pageNumber = 1
+      this.queryUpdate()
+    },
+    selectQuickFow(begindate,enddate,select){
+      this.begindate = begindate
+      this.enddate = enddate
+      this.selectFow = select
+      this.param.content.pageNumber = 1
+      this.queryFollow()
+    },
+    onFull(type){
+      if (type == '新增'){
+        this.param.content.dataType = 12
+        this.param.content.pageNumber = 1
+        this.param.content.pageSize = 100
+        this.queryAdd()
+        this.isFull = true
+      }else if (type == '更新'){
+        this.param.content.dataType = 14
+        this.param.content.pageNumber = 1
+        this.param.content.pageSize = 100
+        this.queryUpdate()
+        this.isFull = true
+      }else if (type == '跟进'){
+        this.param.content.dataType = 13
+        this.param.content.pageNumber = 1
+        this.param.content.pageSize = 100
+        this.queryFollow()
+        this.isFull = true
+      }
+    },
+    backFull(type){
+      if (type == '新增'){
+        this.param.content.dataType = 12
+        this.param.content.pageNumber = 1
+        this.param.content.pageSize = 10
+        this.queryAdd()
+        this.disabled = false
+        this.isFull = false
+      }else if (type == '更新'){
+        this.param.content.dataType = 14
+        this.param.content.pageNumber = 1
+        this.param.content.pageSize = 10
+        this.queryUpdate()
+        this.isFull = false
+      }else if (type == '跟进'){
+        this.param.content.dataType = 13
+        this.param.content.pageNumber = 1
+        this.param.content.pageSize = 10
+        this.queryFollow()
+        this.disabled = false
+        this.isFull = false
+      }
+    }
+  },
+  created() {
+    this.tablecolsAdd = this.tool.tabelCol(this.$route.name).contactAdd.tablecols
+    this.tablecolsUpdate = this.tool.tabelCol(this.$route.name).contactUpdate.tablecols
+    this.tablecolsFollow = this.tool.tabelCol(this.$route.name).contactFollow.tablecols
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 1 - 1
src/HManagement/addressList/addressBook/index.vue

@@ -38,7 +38,7 @@
         </div>
         <div class="inline-16">
           <label class="search__label">{{ $t('关联') }}:</label>
-          <el-select  v-model="contactstype" :placeholder="$t('请选择标签')" size="small" @change="selectChange" clearable @clear="selectChange" class="inline-16">
+          <el-select  v-model="contactstype" :placeholder="$t('请选择关联')" size="small" @change="selectChange" clearable @clear="selectChange" class="inline-16">
             <el-option :label="$t(`关联客户`)" value="关联客户"></el-option>
             <el-option :label="$t(`关联项目`)" value="关联项目"></el-option>
           </el-select>

+ 1 - 1
src/HManagement/serviceDataScreen/components/profileTemplate.vue

@@ -22,7 +22,7 @@
               </template>
               <div slot="reference">
                 <div class="value-style">
-              <span v-if="item.title == '报价总金额' || item.title == '客户报价金额' || item.title == '项目报价金额'">
+              <span v-if="item.title == '报价总金额' || item.title == '客户报价金额' || item.title == '项目报价金额' || item.title == '关联客户成交金额' || item.title == '关联项目成交金额'">
                 <span v-if="item.value > 10000" >
                   {{tool.formatAmount(tool.unitConversion(item.value,10000),2)}}<span style="font-size: 0.729vw">{{$t('万元')}}</span>
                 </span>

+ 45 - 2
src/HManagement/serviceDataScreen/modules/dataProfile.vue

@@ -1,8 +1,8 @@
 <template>
   <div>
     <borderTemplate borderBox="width: 31.250vw;height: 32.813vw;" title="数据概况" detailTitle="查看详情" @dialog="$emit('dialog')"
-                    :systemappid="typeSelect == '线索'?'278':typeSelect == '客户'?'276':typeSelect == '项目'?'275':'277'"
-                    :push_path="typeSelect == '线索'?'/clueData':typeSelect == '客户'?'/customerData':typeSelect == '项目'?'/projectData':'/salesData'">
+                    :systemappid="typeSelect == '线索'?'278':typeSelect == '客户'?'276':typeSelect == '项目'?'275':typeSelect == '联系人'?'313':'277'"
+                    :push_path="typeSelect == '线索'?'/clueData':typeSelect == '客户'?'/customerData':typeSelect == '项目'?'/projectData':typeSelect == '联系人'?'/contactData':'/salesData'">
       <template slot="content">
         <div class="justify-content">
           <div class="justify-content-left">
@@ -14,6 +14,10 @@
               <el-button type="primary" v-if="typeSelect == '客户'" class="btn-select" @click="typeChange('客户')">{{$t(`客户`)}}</el-button>
               <el-button type="text" class="btn-unSelect" v-else @click="typeChange('客户')">{{$t(`客户`)}}</el-button>
             </div>
+            <div class="box-border" v-if="siteid == 'HY'">
+              <el-button type="primary" v-if="typeSelect == '联系人'" class="btn-select" @click="typeChange('联系人')">{{$t(`联系人`)}}</el-button>
+              <el-button type="text" class="btn-unSelect" v-else @click="typeChange('联系人')">{{$t(`联系人`)}}</el-button>
+            </div>
             <div class="box-border">
               <el-button type="primary" v-if="typeSelect == '项目'" class="btn-select" @click="typeChange('项目')">{{$t(`项目`)}}</el-button>
               <el-button type="text" class="btn-unSelect" v-else @click="typeChange('项目')">{{$t(`项目`)}}</el-button>
@@ -29,6 +33,7 @@
               <el-option :label="$t('本年')" value="本年"></el-option>
               <el-option :label="$t('本季')" value="本季"></el-option>
               <el-option :label="$t('本月')" value="本月"></el-option>
+              <el-option :label="$t('上月')" value="上月"></el-option>
               <el-option :label="$t('去年')" value="去年"></el-option>
             </el-select>
           </div>
@@ -100,6 +105,7 @@ export default {
       list:'',
       dataProfile:[],
       profileType:[],
+      siteid:JSON.parse(sessionStorage.getItem('active_account')).siteid
     }
   },
   methods:{
@@ -112,6 +118,8 @@ export default {
         this.param.id = 20231018110404
       }else if (this.typeSelect == '报价'){
         this.param.id = 20231011201004
+      }else if (this.typeSelect == '联系人'){
+        this.param.id = 2025072114302202
       }
       const res = await this.$api.requested(this.param)
       this.list = res.data
@@ -328,6 +336,39 @@ export default {
             tips:'统计到当前查询时间为止的项目报价金额(审核状态)'
           },
         ]
+      }else if (val == '联系人') {
+        this.dataProfile = [
+          {
+            title:'联系人总数',
+            value:this.list.count_phonebook,
+            tips:'统计跟进联系人总数量'
+          },
+          {
+            title:'联系人跟进次数',
+            value:this.list.count_follow,
+            tips:'统计在【联系人】应用,跟进联系人次数。'
+          },
+          {
+            title:'关联客户数',
+            value:this.list.count_customer,
+            tips:'统计联系人关联的客户数量。'
+          },
+          {
+            title:'关联项目数',
+            value:this.list.count_project,
+            tips:'统计联系人关联的项目数量。'
+          },
+          {
+            title:'关联客户成交金额',
+            value:this.list.amount_customer,
+            tips:'统计联系人关联的客户标准、特殊订单下单金额。'
+          },
+          {
+            title:'关联项目成交金额',
+            value:this.list.amount_project,
+            tips:'统计联系人关联的项目订单下单金额。'
+          },
+        ]
       }
     },
     typeChange(val){
@@ -339,6 +380,8 @@ export default {
         this.typeSelect = '项目'
       }else if (val == '报价'){
         this.typeSelect = '报价'
+      }else if (val == '联系人'){
+        this.typeSelect = '联系人'
       }
       this.listData()
     },

+ 79 - 26
src/HManagement/serviceDataScreen/modules/jobData.vue

@@ -6,36 +6,49 @@
           <el-select v-model="dateType"   size="small"  @change="dateTypeChange" :popper-append-to-body="false">
             <el-option :label="$t('本周')" value="本周"></el-option>
             <el-option :label="$t('本月')" value="本月"></el-option>
+            <el-option :label="$t('上月')" value="上月"></el-option>
             <el-option :label="$t('本年')" value="本年"></el-option>
           </el-select>
         </div>
         <div class="box-style">
-          <div class="justify-content-style-set">
-            <div>
-              <div class="data-font">{{list.xsxz}}</div>
-              <div class="title">{{$t(`新增线索`)}}</div>
+          <div class="box-border">
+            <div class="justify-content-style-set">
+              <div>
+                <div class="data-font">{{list.xsxz}}</div>
+                <div class="title">{{$t(`新增线索`)}}</div>
+              </div>
+              <div class="magin-10">
+                <div class="data-font">{{list.xmxz}}</div>
+                <div class="title">{{$t(`新增项目`)}}</div>
+              </div>
+              <div class="magin-10">
+                <div class="data-font">{{list.lxxz}}</div>
+                <div class="title">{{$t(`新增联系人`)}}</div>
+              </div>
             </div>
-            <div>
-              <div class="data-font">{{list.xmxz}}</div>
-              <div class="title">{{$t(`新增项目`)}}</div>
+            <div class="justify-content-style-set">
+              <div>
+                <div class="data-font">{{list.khxz}}</div>
+                <div class="title">{{$t(`新增客户`)}}</div>
+              </div>
+              <div class="magin-10">
+                <div class="data-font">{{list.khgj}}</div>
+                <div class="title">{{$t(`客户跟进`)}}</div>
+              </div>
+              <div class="magin-10">
+                <div class="data-font">{{list.xsgj}}</div>
+                <div class="title">{{$t(`跟进线索`)}}</div>
+              </div>
             </div>
-            <div>
-              <div class="data-font">{{list.khxz}}</div>
-              <div class="title">{{$t(`新增客户`)}}</div>
-            </div>
-          </div>
-          <div class="justify-content-style-set">
-            <div>
-              <div class="data-font">{{list.khgj}}</div>
-              <div class="title">{{$t(`客户跟进`)}}</div>
-            </div>
-            <div>
-              <div class="data-font">{{list.xsgj}}</div>
-              <div class="title">{{$t(`跟进线索`)}}</div>
-            </div>
-            <div>
-              <div class="data-font">{{list.xmgj}}</div>
-              <div class="title">{{$t(`项目跟进`)}}</div>
+            <div class="justify-content-style-set">
+              <div>
+                <div class="data-font">{{list.lxgj}}</div>
+                <div class="title">{{$t(`联系人跟进`)}}</div>
+              </div>
+              <div style="margin-left: 0.52vw">
+                <div class="data-font">{{list.xmgj}}</div>
+                <div class="title">{{$t(`项目跟进`)}}</div>
+              </div>
             </div>
           </div>
         </div>
@@ -69,7 +82,9 @@ export default {
         xmgj:'',
         xmxz:'',
         xsgj:'',
-        xsxz:'5'
+        xsxz:'',
+        lxgj:'',
+        lxxz:'',
       },
       listNew:""
     }
@@ -78,6 +93,7 @@ export default {
     async listData(){
       const res = await this.$api.requested(this.param)
       this.listNew = res.data
+      console.log(this.listNew,'数据1111222')
       this.dateTypeChange()
     },
     dateTypeChange(){
@@ -88,6 +104,8 @@ export default {
         this.list.xmgj = this.listNew.byxmgj
         this.list.xsgj = this.listNew.byxsgj
         this.list.xsxz = this.listNew.byxsxz
+        this.list.lxgj = this.listNew.bylxgj
+        this.list.lxxz = this.listNew.bylxxz
       }else if (this.dateType == '本周') {
         this.list.khgj = this.listNew.bzkhgj
         this.list.khxz = this.listNew.bzkhxz
@@ -95,6 +113,8 @@ export default {
         this.list.xmgj = this.listNew.bzxmgj
         this.list.xsgj = this.listNew.bzxsgj
         this.list.xsxz = this.listNew.bzxsxz
+        this.list.lxgj = this.listNew.bzlxgj
+        this.list.lxxz = this.listNew.bzlxxz
       }else if (this.dateType == '本年') {
         this.list.khgj = this.listNew.bnkhgj
         this.list.khxz = this.listNew.bnkhxz
@@ -102,6 +122,17 @@ export default {
         this.list.xmgj = this.listNew.bnxmgj
         this.list.xsgj = this.listNew.bnxsgj
         this.list.xsxz = this.listNew.bnxsxz
+        this.list.lxgj = this.listNew.bnlxgj
+        this.list.lxxz = this.listNew.bnlxxz
+      }else if (this.dateType == '上月'){
+        this.list.khgj = this.listNew.sykhgj
+        this.list.khxz = this.listNew.sykhxz
+        this.list.xmxz = this.listNew.syxmxz
+        this.list.xmgj = this.listNew.syxmgj
+        this.list.xsgj = this.listNew.syxsgj
+        this.list.xsxz = this.listNew.syxsxz
+        this.list.lxgj = this.listNew.sylxgj
+        this.list.lxxz = this.listNew.sylxxz
       }
     },
     detailClick(){
@@ -121,6 +152,25 @@ export default {
   border: 0.052vw solid #CFDCE5;
   margin-top: 0.642vw;
 }
+.box-border{
+  margin: 0vw 0 0.605vw 0vw;
+  max-width: 13.021vw;
+  max-height: 6.058vw;
+  overflow: auto;
+}
+.box-border::-webkit-scrollbar {
+  width: 0.313vw;
+  height: 0.313vw;
+  background-color: transparent;
+}
+.box-border::-webkit-scrollbar-track {
+  background-color: transparent;
+  background-color: rgb(15, 43, 87);
+}
+.box-border::-webkit-scrollbar-thumb {
+  border-radius: 0.156vw;
+  background-image: linear-gradient(135deg, #c0c7cc, #c0c7cc);
+}
 .box-style .data-font{
   font-family: Microsoft YaHei, Microsoft YaHei;
   font-weight: bold;
@@ -142,7 +192,10 @@ export default {
 }
 .justify-content-style-set{
   display: flex;
-  justify-content: space-between;
+  justify-content:left;
   padding: 0.225vw 1.042vw 0 1.042vw;
 }
+.magin-10{
+  margin-left: 1.182vw;
+}
 </style>

+ 1 - 0
src/HManagement/serviceDataScreen/modules/salesPanel.vue

@@ -27,6 +27,7 @@
               <el-option :label="$t('本年')" value="本年"></el-option>
               <el-option :label="$t('本季')" value="本季"></el-option>
               <el-option :label="$t('本月')" value="本月"></el-option>
+              <el-option :label="$t('上月')" value="上月"></el-option>
             </el-select>
           </div>
         </div>

+ 72 - 0
src/components/dataBoard/index.vue

@@ -0,0 +1,72 @@
+<template>
+  <div>
+    <div class="div-box-new-margin">
+      <div class="div-box-new" :style="{height:heightNew}">
+        <div style="font-size: 16px;color: #333333;margin-bottom: 20px">
+<!--          <div class="div-line div-line-right"></div>-->
+          {{$t(title)}}
+        </div>
+        <div class="div-border-new" :style="{height:heightNew}">
+          <div class="item div-click" v-for="item in mainData" @click="detailClick(item.label)">
+            <p class="title" v-if="item.isTitle">
+              {{item.value}}
+              <span style="font-size: 14px">{{$t('万')}}</span>
+            </p>
+            <p class="title" v-else>{{item.value}}</p>
+            <span class="content-font-new">{{$t(item.label)}}</span>
+            <el-tooltip placement="top" v-if="item.isTooltip">
+              <div slot="content">{{$t(item.tooltip)}}</div>
+              <img style="vertical-align: middle" width="14px" height="14px" src="../../assets/icons/prompt_icon.svg" >
+            </el-tooltip>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "index",
+  props:['title','mainData','heightNew'],
+  methods:{
+    detailClick(title){
+      this.$emit('goDetail',title)
+    }
+  }
+}
+</script>
+
+<style scoped>
+.div-box-new{
+  margin-top: 16px;
+  width: 100%;
+  /* height: 210px;*/
+  border-radius: 2px;
+  border: 1px solid #e9e9e9;
+  background-color: #ffffff;
+  box-sizing: border-box;
+  box-shadow: -1px -1px 5px 0px rgba(0, 0, 0, 0.2);
+  padding: 16px
+}
+.div-border-new{
+  /*margin:0 30px 0 30px;*/
+  height: 150px
+}
+.div-border-new .item{
+  height: 33%;
+  width: 16.6%;
+  float: left;
+}
+.div-border-new .item .title{
+  font-size: 26px
+}
+.div-border-new .item .content-font-new{
+  font-size: 14px;
+  margin-right: 10px;
+  color: #000000A6;
+}
+.div-click:hover{
+  color: #3874f6 !important;
+}
+</style>

+ 159 - 0
src/components/dataTemplate/depStatus.vue

@@ -0,0 +1,159 @@
+<template>
+  <div>
+    <div class="inline-16">
+      <label  class="search__label" >{{$t('部门')}}:</label>
+      <el-cascader :append-to-body="!isFull" class="inline-16" placement="bottom" ref="selectdep" size="small" v-model="depment" :options="deplist" :props="{emitPath:true,expandTrigger:'hover',checkStrictly:true,label:'label',value:'departmentid',children:'children'}"  @change="selectDep" clearable></el-cascader>
+    </div>
+    <div class="inline-16">
+      <label  class="search__label" >{{$t('业务员')}}:</label>
+      <el-select v-model="person" filterable :placeholder="$t('请选择')" size="small" clearable @change="selectPerson" :popper-append-to-body="!isFull">
+        <el-option
+            v-for="item in personnelList"
+            :key="item.index"
+            :label="$t(item.name)"
+            :value="item.userid">
+        </el-option>
+      </el-select>
+    </div>
+    <div class="mt-10 inline-16" v-if="isLeaveShow != false">
+      <p class="search__label">{{$t('状态')}}:</p>
+      <el-select v-model="isleave" clearable style="margin-right:10px" size="small" :placeholder="$t('请选择状态')" @change="leaveChange" :popper-append-to-body="!isFull">
+        <el-option :label="$t('在职')" value="1"></el-option>
+        <el-option :label="$t('离职')" value="2"></el-option>
+      </el-select>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "depStatus",
+  props:['isLeaveShow','isFull'],
+  data(){
+    return {
+      depment:'',
+      person:'',
+      isleave:'1',
+      deplist:[],
+      personnelList:[],
+      depmentParam:{
+        "id": 20230620102004,
+        "content": {
+          "isleave":1
+        }
+      },
+    }
+  },
+  methods:{
+    /*部门人员列表*/
+    async departmentrtment() {
+      const res = await this.$api.requested(this.depmentParam)
+      this.deplist = this.createMenu(res.data.dep)
+      this.personnelList = res.data.hr
+      this.depment = ''
+      this.person = JSON.parse(window.sessionStorage.getItem('active_account')).name
+      const userid = JSON.parse(sessionStorage.getItem('active_account')).userid
+    },
+    /*部门结构处理*/
+    createMenu (array) {
+      var that = this
+      let arr = []
+      function convertToElementTree(node) {
+        // 新节点
+        if (node.subdep.length === 0){
+          var elNode = {
+            label: node["depname"],
+            parentid:node['parentid'],
+            parentname:node['parentname'],
+            departmentid:node["departmentid"],
+            value:node["departmentid"],
+            remarks:node["remarks"],
+            isused:node["isused"],
+            changedate:node['changedate'],
+            changeby:node['changeby'],
+            createdate:node['createdate'],
+            createby:node['createby'],
+            depno:node['depno'],
+            disabled:that.pageOnlyRead,
+          }
+        }else {
+          var elNode = {
+            label: node["depname"],
+            parentid:node['parentid'],
+            parentname:node['parentname'],
+            departmentid:node["departmentid"],
+            value:node["departmentid"],
+            remarks:node["remarks"],
+            isused:node["isused"],
+            changedate:node['changedate'],
+            changeby:node['changeby'],
+            createdate:node['createdate'],
+            createby:node['createby'],
+            depno:node['depno'],
+            disabled:that.pageOnlyRead,
+            children: []
+          }
+        }
+        if (node.subdep && node.subdep.length > 0) {
+          // 如果存在子节点
+          for (var index = 0; index < node.subdep.length; index++) {
+            // 遍历子节点, 把每个子节点看做一颗独立的树, 传入递归构造子树, 并把结果放回到新node的children中
+            elNode.children.push(convertToElementTree(node.subdep[index]));
+          }
+        }
+        return elNode;
+      }
+      array.forEach((element) => {
+        arr.push(convertToElementTree(element))
+      });
+      return arr
+    },
+    /*选择部门*/
+    selectDep(val) {
+      console.log(val,'val2222')
+      if (val.length === 0){
+        const userid = JSON.parse(sessionStorage.getItem('active_account')).userid
+        console.log(JSON.parse(sessionStorage.getItem('active_account')).userid)
+        this.person = JSON.parse(window.sessionStorage.getItem('active_account')).name
+        this.$emit(`depData`,userid,'0')
+      }else {
+        this.person = ''
+        this.departmentid = val[val.length -1]
+        this.$emit(`depData`,this.departmentid,'1',this.isleave)
+      }
+    },
+    /*选择人员*/
+    selectPerson(val){
+      this.depment = ''
+      this.departmentid = ''
+      this.dataid = val
+      this.$emit(`personData`,val,'0',this.isleave)
+    },
+    /*选择在职状态*/
+    leaveChange(){
+      this.person = ''
+      const type = this.depment?'1':'0'
+      const dataid = type == 0?-1:this.departmentid
+      this.$emit(`leaveData`,dataid,type,this.isleave,'状态')
+      this.personData()
+    },
+    /*获取新的业务员列表*/
+    async personData(){
+      let param = {
+        id: 20230620102004,
+        content: {
+          isleave:this.isleave
+        },
+      }
+      const res = await this.$api.requested(param)
+      this.personnelList = res.data.hr
+    },
+  },
+  mounted() {
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 69 - 0
src/components/dataTemplate/index.vue

@@ -0,0 +1,69 @@
+<template>
+  <div>
+    <div class="div-box-new-margin">
+      <div class="div-box-new" :style="{height:heightNew}">
+        <div style="display: flex;justify-content: space-between" v-if="isTitle">
+          <div style="font-size: 16px;color: #333333;margin-bottom: 20px;width: 200px">
+            <div class="div-line div-line-right"></div>
+            <div style="padding-top: -10px">{{$t(title)}}</div>
+          </div>
+          <div>
+            <depStatus class="inline-16" ref="depStatusRef" @depData="listData" @personData="listData" @leaveData="listData" :isFull="isFull"></depStatus>
+            <slot name="operation"></slot>
+          </div>
+        </div>
+        <div>
+          <slot name="content"></slot>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import depStatus from './depStatus'
+export default {
+  name: "index",
+  props:['heightNew','title','isTitle','titleWidth','isFull'],
+  components:{depStatus},
+  methods:{
+    listData(dataid,type,isleave,state){
+      this.$emit('list',dataid,type,isleave,state)
+    }
+  }
+}
+</script>
+
+<style scoped>
+.div-box-new{
+  margin-top: 16px;
+  width: 100%;
+  /* height: 210px;*/
+  border-radius: 2px;
+  border: 1px solid #e9e9e9;
+  background-color: #ffffff;
+  box-sizing: border-box;
+  box-shadow: -1px -1px 5px 0px rgba(0, 0, 0, 0.2);
+  padding: 16px
+}
+.div-border-new{
+  /*margin:0 30px 0 30px;*/
+  height: 150px
+}
+.div-border-new .item{
+  height: 33%;
+  width: 16.6%;
+  float: left;
+}
+.div-border-new .item .title{
+  font-size: 26px
+}
+.div-border-new .item .content-font-new{
+  font-size: 14px;
+  margin-right: 10px;
+  color: #000000A6;
+}
+.div-click:hover{
+  color: #3874f6 !important;
+}
+</style>

+ 0 - 2
src/components/export_file/index5.vue

@@ -15,8 +15,6 @@ export default {
   methods: {
     async exportData() {
       let rs = [];
-
-      console.log(this.columns, "columnswww");
       this.columnsData = JSON.parse(JSON.stringify(this.columns));
       if (this.columnsData) {
         this.columns.filter((p) => {

+ 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]

+ 21 - 0
src/router/HDrpManagement.js

@@ -1194,6 +1194,27 @@ const HDrpManagement = [
       },
     ]
   },
+  {
+    path: '/contactData',
+    name: 'contactData',
+    meta: {
+      title: '联系人数据',
+      ast_nav: true,
+      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',
     name: 'salerpriceData',

+ 122 - 1
src/template/dataDetail/index.vue

@@ -37,6 +37,126 @@
                 {{ scope.column.data[[scope.column.columnname]] || scope.column.columnname === 'operation' ? scope.column.data[[scope.column.columnname]] : '--' }}
               </div>
             </div>
+            <div v-else-if="tableType == '联系人数据概况'">
+              <div v-if="titleHeader == '联系人总数' || titleHeader == '联系人跟进次数'">
+                <div v-if="scope.column.columnname === 'tag'">
+                  <div v-if="scope.column.data.sys_tag">
+                    <div v-for="item in scope.column.data.sys_tag" :key="item.index"  style="float: left;margin-left: 5px;margin-bottom: 5px">
+                      <el-tag  color="#3874F6" size="mini" type="primary" effect="dark">
+                        <span>{{$t(item)}}</span>
+                      </el-tag>
+                    </div>
+                    <div v-for="item in scope.column.data.tag" :key="item.index"  style="float: left;margin-left: 5px;margin-bottom: 5px">
+                      <el-tag color="#FA8C16" size="mini" type="warning" effect="dark">
+                        <span>{{$t(item)}}</span>
+                      </el-tag>
+                    </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>
+              </div>
+              <div v-else-if="titleHeader == '关联客户数'">
+                <div v-if="scope.column.columnname === 'tag'">
+                  <div v-if="scope.column.data.sys_tag">
+                    <div v-for="item in scope.column.data.sys_tag" :key="item.index"  style="float: left;margin-left: 5px;margin-bottom: 5px">
+                      <el-tag  color="#3874F6" size="mini" type="primary" effect="dark">
+                        <span>{{$t(item)}}</span>
+                      </el-tag>
+                    </div>
+                    <div v-for="item in scope.column.data.tag" :key="item.index"  style="float: left;margin-left: 5px;margin-bottom: 5px">
+                      <el-tag color="#FA8C16" size="mini" type="warning" effect="dark">
+                        <span>{{$t(item)}}</span>
+                      </el-tag>
+                    </div>
+                  </div>
+                </div>
+                <div v-else-if="scope.column.columnname === 'leader'">
+                  <span>{{scope.column.data['leader'][0]?scope.column.data['leader'][0].name:'--'}}</span>
+                </div>
+                <div v-else-if="scope.column.columnname === 'depname'">
+                  <span>{{scope.column.data['leader'][0]?scope.column.data['leader'][0].depname:'--'}}</span>
+                </div>
+                <div v-else-if="scope.column.columnname === 'tradingstatus'">
+                  <span
+                      :style="tool.getStatusColor(scope.column.data[[scope.column.columnname]])"
+                  >{{
+                      $t(scope.column.data[[scope.column.columnname]])
+                    }}</span
+                  >
+                </div>
+                <div v-else-if="scope.column.columnname === 'status'">
+                  <span
+                      :style="tool.getStatusColor(scope.column.data[[scope.column.columnname]])"
+                  >{{
+                      $t(scope.column.data[[scope.column.columnname]])
+                    }}</span
+                  >
+                </div>
+                <div v-else>
+                  {{ scope.column.data[[scope.column.columnname]] || scope.column.columnname === 'operation' ? scope.column.data[[scope.column.columnname]] : '--' }}
+                </div>
+              </div>
+              <div v-else-if="titleHeader == '关联项目数'">
+                <div v-if="scope.column.columnname === 'status'">
+                  <span :style="scope.column.data[[scope.column.columnname]] == '跟进中'?'color:#3874f6':tool.getStatusColor(scope.column.data[[scope.column.columnname]])">{{$t(scope.column.data[[scope.column.columnname]])}}</span>
+                </div>
+                <div v-else-if="scope.column.columnname === 'reportstatus'">
+                  <span :style="tool.getStatusColor(scope.column.data[[scope.column.columnname]])">{{$t(scope.column.data[[scope.column.columnname]])}}</span>
+                </div>
+                <div v-else-if="scope.column.columnname === 'tag'">
+                  <div v-if="scope.column.data.sys_tag">
+                    <div v-for="item in scope.column.data.sys_tag" :key="item.index"  style="float: left;margin-left: 5px;margin-bottom: 5px">
+                      <el-tag  color="#3874F6" size="mini" type="primary" effect="dark">
+                        <span>{{$t(item)}}</span>
+                      </el-tag>
+                    </div>
+                    <div v-for="item in scope.column.data.tag" :key="item.index"  style="float: left;margin-left: 5px;margin-bottom: 5px">
+                      <el-tag color="#FA8C16" size="mini" type="warning" effect="dark">
+                        <span>{{$t(item)}}</span>
+                      </el-tag>
+                    </div>
+                  </div>
+                </div>
+                <div v-else-if="scope.column.columnname === 'leader'">
+                  <span>{{scope.column.data['leader'][0]?scope.column.data['leader'][0].name:'--'}}</span>
+                </div>
+                <div v-else-if="scope.column.columnname === 'depname'">
+                  <span>{{scope.column.data['leader'][0]?scope.column.data['leader'][0].depname:'--'}}</span>
+                </div>
+                <div v-else-if="scope.column.columnname == 'dealamount'">
+                  <span>{{scope.column.data[[scope.column.columnname]] ?tool.formatAmount(scope.column.data[[scope.column.columnname]],2,'¥'):'--'}}</span>
+                </div>
+                <div v-else-if="scope.column.columnname == 'signamount_due'">
+                  <span>{{scope.column.data[[scope.column.columnname]] ?tool.formatAmount(scope.column.data[[scope.column.columnname]],2,'¥'):'--'}}</span>
+                </div>
+                <div v-else-if="scope.column.columnname == 'scale'">
+                  <span>{{scope.column.data[[scope.column.columnname]]?$t(scope.column.data[[scope.column.columnname]]) + $t(scope.column.data.unitname):'--'}}</span>
+                </div>
+                <div v-else-if="scope.column.columnname == 'address'">
+                  <span>{{scope.column.data.address || scope.column.data.province?scope.column.data.province+scope.column.data.city+scope.column.data.county+scope.column.data.address:'--'}}</span>
+                </div>
+                <div v-else>
+                  {{ scope.column.data[[scope.column.columnname]] || scope.column.columnname === 'operation' ? scope.column.data[[scope.column.columnname]] : '--' }}
+                </div>
+              </div>
+              <div v-else-if="titleHeader == '关联客户成交金额' || titleHeader == '关联项目成交金额'">
+                <div v-if="scope.column.columnname === 'nominalpressure'">
+                  {{tool.nominalPressureSet(scope.column.data.nominalpressure)}}
+                </div>
+                <div v-else-if="scope.column.columnname == 'qty' || scope.column.columnname == 'undeliqty' || scope.column.columnname == 'bookedqty' || scope.column.columnname == 'returnqty'"  >
+                  {{tool.qtyShow(scope.column.data[[scope.column.columnname]])}}
+                </div>
+                <div v-else-if="scope.column.columnname == 'defaultprice' || scope.column.columnname == 'defaultamount' || scope.column.columnname == 'price' || scope.column.columnname == 'amount' || scope.column.columnname == 'returnamount'"  >
+                  {{tool.formatAmount(scope.column.data[[scope.column.columnname]],2,'¥')}}
+                </div>
+                <div v-else>
+                  {{ scope.column.data[[scope.column.columnname]] || scope.column.columnname === 'operation' ? scope.column.data[[scope.column.columnname]] : '--' }}
+                </div>
+              </div>
+            </div>
             <div v-else>
               <div v-if="scope.column.columnname === 'tag'">
                 <div v-if="scope.column.data.sys_tag">
@@ -124,7 +244,7 @@
 <script>
 export default {
   name: "index",
-  props:["title","layout","param","person","departmentid","isleave","height",'tableType'],
+  props:["title","layout","param","person","departmentid","isleave","height",'tableType','titleHeader'],
   data(){
     return {
       dialogFormVisible:false,
@@ -171,6 +291,7 @@ export default {
       this.listData(this.param.content.pageNumber = 1)
     },
     onClose(){
+      this.param.content.where.condition = ''
       this.dialogFormVisible = false
     },
     async departmentrtment() {

+ 1 - 1
vue.config.js

@@ -9,7 +9,7 @@ module.exports = {
         'Access-Control-Allow-Origin': '*',
       },
       open: true,
-      // host: '192.168.4.170',
+      // host: '192.168.3.146',
       host: 'localhost',
       port: 8000,
       proxy: {