|
@@ -5,30 +5,42 @@
|
|
|
<div class="product_summary">
|
|
<div class="product_summary">
|
|
|
<div class="summary_title">跟进产品总数 {{ followUpProductSummary.total }}</div>
|
|
<div class="summary_title">跟进产品总数 {{ followUpProductSummary.total }}</div>
|
|
|
<div class="summary_tags">
|
|
<div class="summary_tags">
|
|
|
- <span v-for="(item,index) in followUpProductSummary.differentStatusNum" :key="index"> {{item.name}} {{item.num}}</span>
|
|
|
|
|
|
|
+ <span v-for="(item,index) in followUpProductSummary.differentStatusNum" :key="item.productId"> {{item.productName}} {{item.count}}</span>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="product_list">
|
|
<div class="product_list">
|
|
|
-
|
|
|
|
|
- <template v-for="(item,index) in productsStatus" :key="item.id" >
|
|
|
|
|
|
|
+ <template v-for="(item,index) in productsFollowStatistic" :key="item.productId" >
|
|
|
<div class="list_item">
|
|
<div class="list_item">
|
|
|
- <div class="item_title">{{item.name}}</div>
|
|
|
|
|
- <div class="item_info">跟进状态:{{item.followupStatus}}</div>
|
|
|
|
|
- <div class="item_info">联系人:{{item.concactPeople}}</div>
|
|
|
|
|
- <div class="item_info">上次跟进时间:{{item.lastFollowupTime}}</div>
|
|
|
|
|
- <div class="item_info">跟进次数:{{item.followupTimes}}</div>
|
|
|
|
|
|
|
+ <div class="item_title">{{item.productName}}</div>
|
|
|
|
|
+ <div class="item_info">跟进状态:{{item.followName}}</div>
|
|
|
|
|
+ <div class="item_info">联系人:{{item.customerPersonName}}</div>
|
|
|
|
|
+ <div class="item_info">跟进次数:{{item.count}}</div>
|
|
|
|
|
+ <div class="item_info">上次跟进时间:{{item.lastFollowTime}}</div>
|
|
|
</div>
|
|
</div>
|
|
|
- <div v-if="index !== (productsStatus?.length - 1)" class="page_solid_line" />
|
|
|
|
|
|
|
+ <div v-if="index !== (productsFollowStatistic?.length - 1)" class="page_solid_line" />
|
|
|
</template>
|
|
</template>
|
|
|
-
|
|
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<!-- 中间:搜索与 我的跟进 -->
|
|
<!-- 中间:搜索与 我的跟进 -->
|
|
|
<div class="center_panel">
|
|
<div class="center_panel">
|
|
|
<div class="page_content hide_scrollbar">
|
|
<div class="page_content hide_scrollbar">
|
|
|
- <SearchBlock :searchList="ongoingFollowSearchList"></SearchBlock>
|
|
|
|
|
|
|
+ <SearchBlock :searchList="ongoingFollowSearchList" @searchChange="HandleSearchChange">
|
|
|
|
|
+ <template #rowItem-time>
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-if="searchParams.time=='custom'"
|
|
|
|
|
+ style="flex-grow: 0;height: 28px;"
|
|
|
|
|
+ v-model="searchParams.startAndEndTime"
|
|
|
|
|
+ @change="(val)=>HandleSearchChange({startAndEndTime:val},'startAndEndTime')"
|
|
|
|
|
+ start-placeholder="开始时间"
|
|
|
|
|
+ end-placeholder="结束时间"
|
|
|
|
|
+ type="datetimerange"
|
|
|
|
|
+ range-separator="至"
|
|
|
|
|
+ size="default"
|
|
|
|
|
+ />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </SearchBlock>
|
|
|
<FollowCard v-if="finalRenderData?.length > 0" style="margin-top: 16px;" :cardList="finalRenderData">
|
|
<FollowCard v-if="finalRenderData?.length > 0" style="margin-top: 16px;" :cardList="finalRenderData">
|
|
|
<template #operation="{row}">
|
|
<template #operation="{row}">
|
|
|
<div style="" class="table_row_option">
|
|
<div style="" class="table_row_option">
|
|
@@ -44,31 +56,31 @@
|
|
|
|
|
|
|
|
<Pagination :currentPage="currentPage"
|
|
<Pagination :currentPage="currentPage"
|
|
|
:pageSize="pageSize" :totalNum="totalNum"
|
|
:pageSize="pageSize" :totalNum="totalNum"
|
|
|
- @paginationChange="handlePaginationChange" />
|
|
|
|
|
|
|
+ @paginationChange="HandlePaginationChange" />
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<!-- 右侧:待办与统计 -->
|
|
<!-- 右侧:待办与统计 -->
|
|
|
<div class="right_panel">
|
|
<div class="right_panel">
|
|
|
<div class="pending_appointments">
|
|
<div class="pending_appointments">
|
|
|
- <div class="panel_header">预约待办 (6项)</div>
|
|
|
|
|
|
|
+ <div class="panel_header">{{'预约待办 ('+ pendingAppointmentList?.length +'项)'}}</div>
|
|
|
<ul class="task_list hide_scrollbar">
|
|
<ul class="task_list hide_scrollbar">
|
|
|
<template v-if="pendingAppointmentList?.length > 0">
|
|
<template v-if="pendingAppointmentList?.length > 0">
|
|
|
<li v-for="cardItm in pendingAppointmentList" :key="cardItm.id" class="todo_card">
|
|
<li v-for="cardItm in pendingAppointmentList" :key="cardItm.id" class="todo_card">
|
|
|
<div class="card_top">
|
|
<div class="card_top">
|
|
|
- <span class="time">{{cardItm.createTime}}</span>
|
|
|
|
|
|
|
+ <span class="time">{{cardItm.createdAt}}</span>
|
|
|
<span class="title one_line_ellipsis">{{cardItm.productName}}</span>
|
|
<span class="title one_line_ellipsis">{{cardItm.productName}}</span>
|
|
|
<div class="table_row_option">
|
|
<div class="table_row_option">
|
|
|
<span class="button_editor"@click="OpenFollowlFormDialog(cardItm)">详情</span>
|
|
<span class="button_editor"@click="OpenFollowlFormDialog(cardItm)">详情</span>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="card_tags">
|
|
<div class="card_tags">
|
|
|
- <span class="task_type">{{cardItm.taskType}}</span>
|
|
|
|
|
- <span class="follow_status">{{cardItm.followStatus}}</span>
|
|
|
|
|
|
|
+ <span v-if="[0,1].includes(cardItm.orderType)" class="task_type">{{cardItm.orderType ===0 ? '预约' : '待办' }}</span>
|
|
|
|
|
+ <span class="follow_status">{{cardItm.followName}}</span>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="card_info">
|
|
<div class="card_info">
|
|
|
- <span>跟进人:{{ cardItm.followPeople }}</span>
|
|
|
|
|
- <span>联系人:{{ cardItm.concactPeople }}</span>
|
|
|
|
|
- <span>职务:{{ cardItm.position }}</span>
|
|
|
|
|
|
|
+ <span>跟进人:{{ cardItm.claimUserName }}</span>
|
|
|
|
|
+ <span>联系人:{{ cardItm.customerPersonName }}</span>
|
|
|
|
|
+ <span>职务:{{ cardItm.positionName }}</span>
|
|
|
</div>
|
|
</div>
|
|
|
<div :title="cardItm.followContent" class="card_content two_line_ellipsis">
|
|
<div :title="cardItm.followContent" class="card_content two_line_ellipsis">
|
|
|
跟进内容:{{cardItm.followContent}}
|
|
跟进内容:{{cardItm.followContent}}
|
|
@@ -94,24 +106,24 @@
|
|
|
</div>
|
|
</div>
|
|
|
<div class="stat_numbers">
|
|
<div class="stat_numbers">
|
|
|
<div class="num_item">
|
|
<div class="num_item">
|
|
|
- <div class="num">{{historyFollowData.hsitoryProductNum}}</div>
|
|
|
|
|
|
|
+ <div class="num">{{historyFollowData.historyProductCount}}</div>
|
|
|
<div class="label">历史产品</div>
|
|
<div class="label">历史产品</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="vertical_solid"></div>
|
|
<div class="vertical_solid"></div>
|
|
|
<div class="num_item">
|
|
<div class="num_item">
|
|
|
- <div class="num">{{historyFollowData.historyPeopleNum}}</div>
|
|
|
|
|
|
|
+ <div class="num">{{historyFollowData.historyPersonCount}}</div>
|
|
|
<div class="label">历史人员</div>
|
|
<div class="label">历史人员</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="vertical_solid"></div>
|
|
<div class="vertical_solid"></div>
|
|
|
|
|
|
|
|
<div class="num_item">
|
|
<div class="num_item">
|
|
|
- <div class="num">{{historyFollowData.followTimes}}</div>
|
|
|
|
|
|
|
+ <div class="num">{{historyFollowData.historyFollowCount}}</div>
|
|
|
<div class="label">跟进次数</div>
|
|
<div class="label">跟进次数</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="vertical_solid"></div>
|
|
<div class="vertical_solid"></div>
|
|
|
|
|
|
|
|
<div class="num_item">
|
|
<div class="num_item">
|
|
|
- <div class="num">{{historyFollowData.winnerCaseTimes}}</div>
|
|
|
|
|
|
|
+ <div class="num">{{historyFollowData.successCount}}</div>
|
|
|
<div class="label">赢单次数</div>
|
|
<div class="label">赢单次数</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -152,217 +164,270 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
-import { ref,computed } from 'vue';
|
|
|
|
|
|
|
+import { ref,computed, onMounted,watch } from 'vue';
|
|
|
|
|
+import {useRoute} from 'vue-router'
|
|
|
|
|
+
|
|
|
import SearchBlock from '@/baseComponents/SearchBlock.vue';
|
|
import SearchBlock from '@/baseComponents/SearchBlock.vue';
|
|
|
import { ongoingFollowSearchList,historyFollowSearchList } from './searchBlock';
|
|
import { ongoingFollowSearchList,historyFollowSearchList } from './searchBlock';
|
|
|
import FollowCard from '@/components/FollowCard.vue';
|
|
import FollowCard from '@/components/FollowCard.vue';
|
|
|
-
|
|
|
|
|
import Pagination from '@/baseComponents/Pagination.vue';
|
|
import Pagination from '@/baseComponents/Pagination.vue';
|
|
|
import FollowFormDialog from '../components/FollowFormDialog/index.vue'
|
|
import FollowFormDialog from '../components/FollowFormDialog/index.vue'
|
|
|
-
|
|
|
|
|
import PreviewDialog from '@/baseComponents/PreviewDialog.vue';
|
|
import PreviewDialog from '@/baseComponents/PreviewDialog.vue';
|
|
|
|
|
|
|
|
-// 跟进产品总览
|
|
|
|
|
-const followUpProductSummary = ref({
|
|
|
|
|
- total:6,
|
|
|
|
|
- differentStatusNum:[
|
|
|
|
|
- {
|
|
|
|
|
- name:'线索建立',
|
|
|
|
|
- num:2
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- name:'方案演示',
|
|
|
|
|
- num:1
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- name:'试用测试',
|
|
|
|
|
- num:1
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- name:'赢单',
|
|
|
|
|
- num:1
|
|
|
|
|
- },
|
|
|
|
|
- ]
|
|
|
|
|
-})
|
|
|
|
|
|
|
+import {getOverviewDetailApi} from '@/api/myCustomer'
|
|
|
|
|
+import {
|
|
|
|
|
+ getTodayRange,
|
|
|
|
|
+ getYesterdayRange,
|
|
|
|
|
+ getRecentDaysRange,
|
|
|
|
|
+ getRecentWeeksRange,
|
|
|
|
|
+ getRecentMonthsRange,
|
|
|
|
|
+ formatTime
|
|
|
|
|
+} from '@/utils/timeRangeGet'
|
|
|
|
|
+
|
|
|
|
|
+interface ProductFollowRecord {
|
|
|
|
|
+ productId: string; // 产品ID
|
|
|
|
|
+ productName: string; // 产品名称
|
|
|
|
|
+ count?: number; // 数量
|
|
|
|
|
+ followName: string; // 跟进名称
|
|
|
|
|
+ customerPersonName: string; // 客户人员名称
|
|
|
|
|
+ lastFollowTime: string | number; // 最后跟进时间
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
|
|
|
-interface ProductStatusItm {
|
|
|
|
|
|
|
+interface pendingAppointmentItm {
|
|
|
id:string,
|
|
id:string,
|
|
|
- name:string,
|
|
|
|
|
- followupStatus:string,
|
|
|
|
|
- concactPeople:string,
|
|
|
|
|
- lastFollowupTime:string,
|
|
|
|
|
- followupTimes:string
|
|
|
|
|
|
|
+ createdAt:string,
|
|
|
|
|
+ productName:string,
|
|
|
|
|
+ orderType:number,
|
|
|
|
|
+ followName:string,
|
|
|
|
|
+ claimUserName:string,
|
|
|
|
|
+ customerPersonName:string,
|
|
|
|
|
+ positionName:string,
|
|
|
|
|
+ followContent:string,
|
|
|
}
|
|
}
|
|
|
-const productsStatus = ref<ProductStatusItm[]>([
|
|
|
|
|
- {
|
|
|
|
|
- id:'1',
|
|
|
|
|
- name: '大数据精准教学',
|
|
|
|
|
- followupStatus: '试用测试',
|
|
|
|
|
- concactPeople: '张三(校长)',
|
|
|
|
|
- lastFollowupTime: '26-08-12 8:00',
|
|
|
|
|
- followupTimes: '6次',
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id:'2',
|
|
|
|
|
- name: '智能判分系统',
|
|
|
|
|
- followupStatus: '试用测试',
|
|
|
|
|
- concactPeople: '张三(校长)',
|
|
|
|
|
- lastFollowupTime: '26-08-12 8:00',
|
|
|
|
|
- followupTimes: '6次',
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id:'3',
|
|
|
|
|
- name: '材料采集系统',
|
|
|
|
|
- followupStatus: '试用测试',
|
|
|
|
|
- concactPeople: '张三(校长)',
|
|
|
|
|
- lastFollowupTime: '26-08-12 8:00',
|
|
|
|
|
- followupTimes: '6次',
|
|
|
|
|
- },
|
|
|
|
|
-]);
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
-// 进行中的跟进记录
|
|
|
|
|
-const ongoingFollowRecord = ref([
|
|
|
|
|
- {
|
|
|
|
|
- id:'1',
|
|
|
|
|
- followUpTime: '26-02-19 19:00',
|
|
|
|
|
- schoolName: '北京师达学校',
|
|
|
|
|
- followUpProduct: '大数据精准教学',
|
|
|
|
|
- followUpStatus: '赢单',
|
|
|
|
|
- audditStatus:'审核中',
|
|
|
|
|
- followUpUser: '张三',
|
|
|
|
|
- contactPerson: '严谨',
|
|
|
|
|
- jobTitle: '校长',
|
|
|
|
|
- followUpContent: '跟进文案跟进文案跟进文案跟进文案跟进文案北京市东城区葱店西街56号跟进文案跟进文案跟进文案跟进文案跟进文'
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id:'2',
|
|
|
|
|
- followUpTime: '26-02-19 19:00',
|
|
|
|
|
- schoolName: '北京师达学校',
|
|
|
|
|
- followUpProduct: '大数据精准教学',
|
|
|
|
|
- followUpStatus: '方案演示',
|
|
|
|
|
- taskType:'预约',
|
|
|
|
|
- followUpUser: '张三',
|
|
|
|
|
- contactPerson: '严谨',
|
|
|
|
|
- jobTitle: '校长',
|
|
|
|
|
- followUpContent: '跟进文案跟进文案跟进文案跟进文案跟进文案北京市东城区葱店西街56号跟进文案跟进文案跟进文案跟进文案跟进文案北京\n文案跟进文案跟进文案北京市东城区葱店西街56号跟进文案跟进文案跟进文案跟进文案跟进文案北京市东城区葱店西街56号'
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id:'3',
|
|
|
|
|
- followUpTime: '26-02-19 19:00',
|
|
|
|
|
- schoolName: '北京师达学校',
|
|
|
|
|
- followUpProduct: '大数据精准教学',
|
|
|
|
|
- followUpStatus: '试用测试',
|
|
|
|
|
- taskType:'待办',
|
|
|
|
|
- followUpUser: '张三',
|
|
|
|
|
- contactPerson: '严谨',
|
|
|
|
|
- jobTitle: '校长',
|
|
|
|
|
- followUpContent: '跟进文案跟进文案跟进文案跟进文案跟进文案北京市东城区葱店西街56号跟进文案跟进文案跟进文案跟进文案跟进文案北京\n文案跟进文案跟进文案北京市东城区葱店西街56号跟进文案跟进文案跟进文案跟进文案跟进文案北京市东城区葱店西街56号'
|
|
|
|
|
|
|
+const props = defineProps({
|
|
|
|
|
+ followReloadFlag:{
|
|
|
|
|
+ type:Number,
|
|
|
}
|
|
}
|
|
|
-])
|
|
|
|
|
-const finalRenderData = computed(()=>{
|
|
|
|
|
- return ongoingFollowRecord.value.map(item=>{
|
|
|
|
|
-
|
|
|
|
|
- let headerTags = []
|
|
|
|
|
- if(item.followUpStatus){
|
|
|
|
|
- headerTags.push(item.followUpStatus)
|
|
|
|
|
- }
|
|
|
|
|
- if(item.audditStatus){
|
|
|
|
|
- headerTags.push(item.audditStatus)
|
|
|
|
|
- }
|
|
|
|
|
- return {
|
|
|
|
|
- headerTitleList:[
|
|
|
|
|
- item.followUpTime,
|
|
|
|
|
- item.schoolName,
|
|
|
|
|
- item.followUpProduct
|
|
|
|
|
- ],
|
|
|
|
|
- headerTags,
|
|
|
|
|
- middleDesc:[
|
|
|
|
|
- `跟进人:${item.followUpUser}`,
|
|
|
|
|
- `联系人:${item.contactPerson}`,
|
|
|
|
|
- `职务:${item.jobTitle}`
|
|
|
|
|
- ],
|
|
|
|
|
- taskType:item.taskType,
|
|
|
|
|
- bottomDesc:`跟进内容:${item.followUpContent}`
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
})
|
|
})
|
|
|
|
|
+const route = useRoute()
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 1. 左侧数据展示
|
|
|
|
|
+ */
|
|
|
|
|
+// 左侧——跟进产品总览
|
|
|
|
|
+const followUpProductSummary = ref({
|
|
|
|
|
+ total:0,
|
|
|
|
|
+ differentStatusNum:[ ]
|
|
|
|
|
+})
|
|
|
|
|
+//左侧——跟进产品——统计分析
|
|
|
|
|
+const productsFollowStatistic = ref<ProductFollowRecord[]>([]);
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 中间数展示
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+// 中间——当前客户跟进记录列表展示 及有关筛选操作
|
|
|
|
|
+const finalRenderData = ref([])
|
|
|
const currentPage = ref(1)
|
|
const currentPage = ref(1)
|
|
|
const pageSize = ref(20)
|
|
const pageSize = ref(20)
|
|
|
const totalNum = ref(0)
|
|
const totalNum = ref(0)
|
|
|
-const handlePaginationChange = (params)=>{
|
|
|
|
|
|
|
+const HandlePaginationChange = async (params)=>{
|
|
|
const {type,val} = params
|
|
const {type,val} = params
|
|
|
if(type == 'currentPage'){
|
|
if(type == 'currentPage'){
|
|
|
currentPage.value = val
|
|
currentPage.value = val
|
|
|
}else if(type == 'pageSize'){
|
|
}else if(type == 'pageSize'){
|
|
|
pageSize.value = val
|
|
pageSize.value = val
|
|
|
}
|
|
}
|
|
|
|
|
+ await GetOverviewDetail()
|
|
|
}
|
|
}
|
|
|
|
|
+// 查看总览数据
|
|
|
|
|
+const GetOverviewDetail = async ()=>{
|
|
|
|
|
+ let rangeTime = {
|
|
|
|
|
+ startTime: '',
|
|
|
|
|
+ endTime: ''
|
|
|
|
|
+ }
|
|
|
|
|
+ switch(searchParams.value.time){
|
|
|
|
|
+ case 'today':
|
|
|
|
|
+ rangeTime = getTodayRange()
|
|
|
|
|
+ break
|
|
|
|
|
+ case 'yesterday':
|
|
|
|
|
+ rangeTime = getYesterdayRange()
|
|
|
|
|
+ break
|
|
|
|
|
+ case 'last3days':
|
|
|
|
|
+ rangeTime = getRecentDaysRange(3)
|
|
|
|
|
+ break
|
|
|
|
|
+ case 'last1week':
|
|
|
|
|
+ rangeTime = getRecentWeeksRange(1)
|
|
|
|
|
+ break
|
|
|
|
|
+ case 'last1month':
|
|
|
|
|
+ rangeTime = getRecentMonthsRange(1)
|
|
|
|
|
+ break
|
|
|
|
|
+ case 'custom':
|
|
|
|
|
+ rangeTime = {
|
|
|
|
|
+ startTime:formatTime(searchParams.value.startAndEndTime?.[0]) ,
|
|
|
|
|
+ endTime: formatTime(searchParams.value.startAndEndTime?.[1]),
|
|
|
|
|
+ }
|
|
|
|
|
+ break
|
|
|
|
|
+ }
|
|
|
|
|
+ let params = {
|
|
|
|
|
+ startDatetime: rangeTime.startTime,
|
|
|
|
|
+ endDatetime: rangeTime.endTime,
|
|
|
|
|
+ customerId: route.query.id,
|
|
|
|
|
+ positionId: searchParams.value.position == 'all' ? '' : searchParams.value.position,
|
|
|
|
|
+ productId: searchParams.value.product == 'all' ? '' : searchParams.value.product,
|
|
|
|
|
+ followId: searchParams.value.followStatus == 'all' ? '' : searchParams.value.followStatus,
|
|
|
|
|
+ // userId: '',
|
|
|
|
|
+ pageNum: currentPage.value,
|
|
|
|
|
+ pageSize: pageSize.value,
|
|
|
|
|
+ }
|
|
|
|
|
+ let res = await getOverviewDetailApi(params)
|
|
|
|
|
+ if(res.code == 200){
|
|
|
|
|
+ const {selectData,dataPageList,productCount,
|
|
|
|
|
+ productOverviewData,productData,
|
|
|
|
|
+ followOverViewData,orderData
|
|
|
|
|
+ } = res.data
|
|
|
|
|
+
|
|
|
|
|
+ // 跟进产品总览 ——左
|
|
|
|
|
+ followUpProductSummary.value = {
|
|
|
|
|
+ total:productCount,
|
|
|
|
|
+ differentStatusNum:productOverviewData || []
|
|
|
|
|
+ }
|
|
|
|
|
+ // 跟进产品-各自分析 ——左
|
|
|
|
|
+ productsFollowStatistic.value = productData || []
|
|
|
|
|
+ // 历史跟进统计 —— 右
|
|
|
|
|
+ historyFollowData.value = followOverViewData
|
|
|
|
|
+ //预约待办展示 —— 右
|
|
|
|
|
+ pendingAppointmentList.value = orderData || []
|
|
|
|
|
+ // 中间 正在进行中的跟进记录 —— 中
|
|
|
|
|
+ totalNum.value = dataPageList.total
|
|
|
|
|
+ finalRenderData.value = dataPageList?.records?.map(item=>{
|
|
|
|
|
+ let headerTags = []
|
|
|
|
|
+ if(item.followName){
|
|
|
|
|
+ headerTags.push(item.followName)
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-// 预约待办项
|
|
|
|
|
-interface pendingAppointmentItm {
|
|
|
|
|
- id:string,
|
|
|
|
|
- createTime:string,
|
|
|
|
|
- productName:string,
|
|
|
|
|
- taskType:string,
|
|
|
|
|
- followStatus:string,
|
|
|
|
|
- followPeople:string,
|
|
|
|
|
- concactPeople:string,
|
|
|
|
|
- position:string,
|
|
|
|
|
- followContent:string,
|
|
|
|
|
|
|
+ // 审核状态:0-待审核,1-已通过,2-已驳回
|
|
|
|
|
+ if(item.auditStatus || item.auditStatus === 0){
|
|
|
|
|
+ headerTags.push(item.auditStatus === 0 ? '待审核' : (item.auditStatus === 1 ? '已通过' : '已驳回') )
|
|
|
|
|
+ }
|
|
|
|
|
+ return {
|
|
|
|
|
+ headerTitleList:[
|
|
|
|
|
+ item.claimDatetime,
|
|
|
|
|
+ item.customerName,
|
|
|
|
|
+ item.productName
|
|
|
|
|
+ ],
|
|
|
|
|
+ headerTags,
|
|
|
|
|
+ middleDesc:[
|
|
|
|
|
+ `跟进人:${item.claimUserName}`,
|
|
|
|
|
+ `联系人:${item.customerPersonName}`,
|
|
|
|
|
+ `职务:${item.positionName}`
|
|
|
|
|
+ ],
|
|
|
|
|
+ taskType:[0,1].includes(item.orderType) ? (item.orderType === 0 ? '预约' : '待办') : '',
|
|
|
|
|
+ bottomDesc:`跟进内容:${item.followContent}`
|
|
|
|
|
+ }
|
|
|
|
|
+ }) || []
|
|
|
|
|
+ const {
|
|
|
|
|
+ followData,
|
|
|
|
|
+ positionData,
|
|
|
|
|
+ productData:productList
|
|
|
|
|
+ } = selectData || {}
|
|
|
|
|
+
|
|
|
|
|
+ let productOption = productList?.map(item=>{
|
|
|
|
|
+ return {
|
|
|
|
|
+ label:item.name,
|
|
|
|
|
+ value:item.id
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ let followStatusOption = followData.map(item=>{
|
|
|
|
|
+ return {
|
|
|
|
|
+ label:item.name,
|
|
|
|
|
+ value:item.id
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ let positionOption = positionData.map(item=>{
|
|
|
|
|
+ return {
|
|
|
|
|
+ label:item.name,
|
|
|
|
|
+ value:item.id
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ ongoingFollowSearchList.value = ongoingFollowSearchList.value.map(item=>{
|
|
|
|
|
+ switch(item.key){
|
|
|
|
|
+ case 'product':
|
|
|
|
|
+ item.options = [
|
|
|
|
|
+ { label: '全部', value: 'all' },
|
|
|
|
|
+ ...productOption,
|
|
|
|
|
+ ]
|
|
|
|
|
+ item.defaultValue = searchParams.value.product
|
|
|
|
|
+ break
|
|
|
|
|
+ case 'followStatus':
|
|
|
|
|
+ item.options = [
|
|
|
|
|
+ { label: '全部', value: 'all' },
|
|
|
|
|
+ ...followStatusOption,
|
|
|
|
|
+ ]
|
|
|
|
|
+ item.defaultValue = searchParams.value.followStatus
|
|
|
|
|
+ break
|
|
|
|
|
+ case 'position':
|
|
|
|
|
+ item.options = [
|
|
|
|
|
+ { label: '全部', value: 'all' },
|
|
|
|
|
+ ...positionOption
|
|
|
|
|
+ ]
|
|
|
|
|
+ item.defaultValue = searchParams.value.position
|
|
|
|
|
+ break
|
|
|
|
|
+ default:
|
|
|
|
|
+ item.defaultValue = searchParams.value[item.key]
|
|
|
|
|
+ break
|
|
|
|
|
+ }
|
|
|
|
|
+ return item
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+// 筛选条件
|
|
|
|
|
+const searchParams = ref({
|
|
|
|
|
+ time:'all',
|
|
|
|
|
+ product:'all',
|
|
|
|
|
+ followStatus:'all',
|
|
|
|
|
+ position:'all',
|
|
|
|
|
+ startAndEndTime:[],
|
|
|
|
|
+})
|
|
|
|
|
+const HandleSearchChange = async (params,key)=>{
|
|
|
|
|
+ searchParams.value = {
|
|
|
|
|
+ ...searchParams.value,
|
|
|
|
|
+ ...params
|
|
|
|
|
+ }
|
|
|
|
|
+ if(key == 'time' && params.time !== 'custom' ){
|
|
|
|
|
+ searchParams.value.startAndEndTime = []
|
|
|
|
|
+ }
|
|
|
|
|
+ await GetOverviewDetail()
|
|
|
}
|
|
}
|
|
|
-const pendingAppointmentList = ref<pendingAppointmentItm[]>([
|
|
|
|
|
- {
|
|
|
|
|
- id:'1',
|
|
|
|
|
- createTime: '26-02-19 16:00',
|
|
|
|
|
- productName: '大数据精准教学...',
|
|
|
|
|
- taskType: '预约',
|
|
|
|
|
- followStatus: '方案演示',
|
|
|
|
|
- followPeople: '张三',
|
|
|
|
|
- concactPeople: '严谨',
|
|
|
|
|
- position: '校长',
|
|
|
|
|
- followContent: '跟进文案跟进文案跟进文案跟进文案跟进文案北京市东城区葱店西街56号跟进文案跟进文案跟进xxxx...',
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id:'2',
|
|
|
|
|
- createTime: '26-02-19 16:00',
|
|
|
|
|
- productName: '大数据精准教学',
|
|
|
|
|
- taskType: '待办',
|
|
|
|
|
- followStatus: '试用测试',
|
|
|
|
|
- followPeople: '张三',
|
|
|
|
|
- concactPeople: '严谨',
|
|
|
|
|
- position: '校长',
|
|
|
|
|
- followContent: '跟进文案跟进文案跟进文案跟进文案跟进文案北京市东城区葱店西街56号跟进文案跟进文案跟进xxxxx...',
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id:'3',
|
|
|
|
|
- createTime: '26-02-19 16:00',
|
|
|
|
|
- productName: '大数据精准教学',
|
|
|
|
|
- taskType: '待办',
|
|
|
|
|
- followStatus: '试用测试',
|
|
|
|
|
- followPeople: '张三',
|
|
|
|
|
- concactPeople: '严谨',
|
|
|
|
|
- position: '校长',
|
|
|
|
|
- followContent: '跟进文案跟进文案跟进文案跟进文案跟进文案北京市东城区葱店西街56号跟进文案跟进文案跟进...',
|
|
|
|
|
- },
|
|
|
|
|
-])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-// 历史跟进 数据总览
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * 3. 右侧数据展示
|
|
|
|
|
+ */
|
|
|
|
|
+// 右侧 —— 预约待办数据
|
|
|
|
|
+const pendingAppointmentList = ref<pendingAppointmentItm[]>([])
|
|
|
|
|
+
|
|
|
|
|
+// 右侧—— 历史跟进 数据总览
|
|
|
const historyFollowData = ref({
|
|
const historyFollowData = ref({
|
|
|
- hsitoryProductNum:10,
|
|
|
|
|
- historyPeopleNum:2,
|
|
|
|
|
- followTimes:8,
|
|
|
|
|
- winnerCaseTimes:8,
|
|
|
|
|
|
|
+ historyProductCount:0,
|
|
|
|
|
+ historyPersonCount:0,
|
|
|
|
|
+ historyFollowCount:0,
|
|
|
|
|
+ successCount:0,
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * 4.
|
|
|
|
|
+ */
|
|
|
/** 跟进弹窗详情(查看)有关数据及操作 */
|
|
/** 跟进弹窗详情(查看)有关数据及操作 */
|
|
|
const followVisible = ref(false)
|
|
const followVisible = ref(false)
|
|
|
const followDefaultFormData = ref({})
|
|
const followDefaultFormData = ref({})
|
|
|
const OpenFollowlFormDialog = (row)=>{
|
|
const OpenFollowlFormDialog = (row)=>{
|
|
|
followVisible.value = true
|
|
followVisible.value = true
|
|
|
followDefaultFormData.value = {
|
|
followDefaultFormData.value = {
|
|
|
|
|
+ ...row,
|
|
|
// school:customerBaseMsg.value.schoolName,
|
|
// school:customerBaseMsg.value.schoolName,
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -445,6 +510,15 @@ const historyCurrentPage = ref(1)
|
|
|
const historyPageSize = ref(10)
|
|
const historyPageSize = ref(10)
|
|
|
const historyTotalNum = ref(0)
|
|
const historyTotalNum = ref(0)
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+watch(()=>props.followReloadFlag,async (newVal)=>{
|
|
|
|
|
+ await GetOverviewDetail()
|
|
|
|
|
+})
|
|
|
|
|
+onMounted( async ()=>{
|
|
|
|
|
+ await GetOverviewDetail()
|
|
|
|
|
+})
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|