Skip to content

Commit 55856be

Browse files
YunaiVgitee-org
authored andcommitted
!394 feat: CRM/数据统计/员工客户分析 初稿
Merge pull request !394 from dhb52/dev
2 parents a6e29c5 + 470c507 commit 55856be

File tree

7 files changed

+917
-0
lines changed

7 files changed

+917
-0
lines changed

src/api/crm/statistics/customer.ts

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import request from '@/config/axios'
2+
3+
export interface CrmStatisticsCustomerSummaryByDateRespVO {
4+
time: string
5+
customerCreateCount: number
6+
customerDealCount: number
7+
}
8+
9+
export interface CrmStatisticsCustomerSummaryByUserRespVO {
10+
ownerUserName: string
11+
customerCreateCount: number
12+
customerDealCount: number
13+
contractPrice: number
14+
receivablePrice: number
15+
}
16+
17+
export interface CrmStatisticsFollowupSummaryByDateRespVO {
18+
time: string
19+
followupRecordCount: number
20+
followupCustomerCount: number
21+
}
22+
23+
export interface CrmStatisticsFollowupSummaryByUserRespVO {
24+
ownerUserName: string
25+
followupRecordCount: number
26+
followupCustomerCount: number
27+
}
28+
29+
export interface CrmStatisticsFollowupSummaryByTypeRespVO {
30+
followupType: string
31+
followupRecordCount: number
32+
}
33+
34+
export interface CrmStatisticsCustomerContractSummaryRespVO {
35+
customerName: string
36+
contractName: string
37+
totalPrice: number
38+
receivablePrice: number
39+
customerType: string
40+
customerSource: string
41+
ownerUserName: string
42+
creatorUserName: string
43+
createTime: Date
44+
orderDate: Date
45+
}
46+
47+
export interface CrmStatisticsCustomerDealCycleByDateRespVO {
48+
time: string
49+
customerDealCycle: number
50+
}
51+
52+
export interface CrmStatisticsCustomerDealCycleByUserRespVO {
53+
ownerUserName: string
54+
customerDealCycle: number
55+
customerDealCount: number
56+
}
57+
58+
// 客户分析 API
59+
export const StatisticsCustomerApi = {
60+
// 1.1 客户总量分析(按日期)
61+
getCustomerSummaryByDate: (params: any) => {
62+
return request.get({
63+
url: '/crm/statistics-customer/get-customer-summary-by-date',
64+
params
65+
})
66+
},
67+
// 1.2 客户总量分析(按用户)
68+
getCustomerSummaryByUser: (params: any) => {
69+
return request.get({
70+
url: '/crm/statistics-customer/get-customer-summary-by-user',
71+
params
72+
})
73+
},
74+
// 2.1 客户跟进次数分析(按日期)
75+
getFollowupSummaryByDate: (params: any) => {
76+
return request.get({
77+
url: '/crm/statistics-customer/get-followup-summary-by-date',
78+
params
79+
})
80+
},
81+
// 2.2 客户跟进次数分析(按用户)
82+
getFollowupSummaryByUser: (params: any) => {
83+
return request.get({
84+
url: '/crm/statistics-customer/get-followup-summary-by-user',
85+
params
86+
})
87+
},
88+
// 3.1 获取客户跟进方式统计数
89+
getFollowupSummaryByType: (params: any) => {
90+
return request.get({
91+
url: '/crm/statistics-customer/get-followup-summary-by-type',
92+
params
93+
})
94+
},
95+
// 4.1 合同摘要信息(客户转化率页面)
96+
getContractSummary: (params: any) => {
97+
return request.get({
98+
url: '/crm/statistics-customer/get-contract-summary',
99+
params
100+
})
101+
},
102+
// 5.1 获取客户成交周期(按日期)
103+
getCustomerDealCycleByDate: (params: any) => {
104+
return request.get({
105+
url: '/crm/statistics-customer/get-customer-deal-cycle-by-date',
106+
params
107+
})
108+
},
109+
// 5.2 获取客户成交周期(按用户)
110+
getCustomerDealCycleByUser: (params: any) => {
111+
return request.get({
112+
url: '/crm/statistics-customer/get-customer-deal-cycle-by-user',
113+
params
114+
})
115+
}
116+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<!-- 客户转化率分析 -->
2+
<template>
3+
<!-- Echarts图 -->
4+
<el-card shadow="never">
5+
<el-skeleton :loading="loading" animated>
6+
<Echart :height="500" :options="echartsOption" />
7+
</el-skeleton>
8+
</el-card>
9+
10+
<!-- 统计列表 -->
11+
<el-card shadow="never" class="mt-16px">
12+
<el-table v-loading="loading" :data="list">
13+
<el-table-column label="序号" align="center" type="index" width="80" />
14+
<el-table-column label="客户名称" align="center" prop="customerName" min-width="200" />
15+
<el-table-column label="合同名称" align="center" prop="contractName" min-width="200" />
16+
<el-table-column label="合同总金额" align="center" prop="totalPrice" min-width="200" />
17+
<el-table-column label="回款金额" align="center" prop="receivablePrice" min-width="200" />
18+
<el-table-column label="负责人" align="center" prop="ownerUserName" min-width="200" />
19+
<el-table-column label="创建人" align="center" prop="creatorUserName" min-width="200" />
20+
<el-table-column
21+
label="创建时间"
22+
align="center"
23+
prop="createTime"
24+
:formatter="dateFormatter"
25+
min-width="200"
26+
/>
27+
<el-table-column
28+
label="下单日期"
29+
align="center"
30+
prop="orderDate"
31+
:formatter="dateFormatter2"
32+
min-width="200"
33+
/>
34+
</el-table>
35+
</el-card>
36+
</template>
37+
<script setup lang="ts">
38+
import {
39+
StatisticsCustomerApi,
40+
CrmStatisticsCustomerSummaryByDateRespVO
41+
} from '@/api/crm/statistics/customer'
42+
import { EChartsOption } from 'echarts'
43+
import { round } from 'lodash-es'
44+
import { dateFormatter, dateFormatter2 } from '@/utils/formatTime'
45+
46+
defineOptions({ name: 'CustomerConversionStat' })
47+
const props = defineProps<{ queryParams: any }>() // 搜索参数
48+
49+
const loading = ref(false) // 加载中
50+
const list = ref<CrmStatisticsCustomerSummaryByDateRespVO[]>([]) // 列表的数据
51+
52+
/** 柱状图配置:纵向 */
53+
const echartsOption = reactive<EChartsOption>({
54+
grid: {
55+
left: 20,
56+
right: 20,
57+
bottom: 20,
58+
containLabel: true
59+
},
60+
legend: {},
61+
series: [
62+
{
63+
name: '客户转化率',
64+
type: 'line',
65+
data: []
66+
}
67+
],
68+
toolbox: {
69+
feature: {
70+
dataZoom: {
71+
xAxisIndex: false // 数据区域缩放:Y 轴不缩放
72+
},
73+
brush: {
74+
type: ['lineX', 'clear'] // 区域缩放按钮、还原按钮
75+
},
76+
saveAsImage: { show: true, name: '客户转化率分析' } // 保存为图片
77+
}
78+
},
79+
tooltip: {
80+
trigger: 'axis',
81+
axisPointer: {
82+
type: 'shadow'
83+
}
84+
},
85+
yAxis: {
86+
type: 'value',
87+
name: '转化率(%)'
88+
},
89+
xAxis: {
90+
type: 'category',
91+
name: '日期',
92+
data: []
93+
}
94+
}) as EChartsOption
95+
96+
/** 获取统计数据 */
97+
const loadData = async () => {
98+
// 1. 加载统计数据
99+
loading.value = true
100+
const customerCount = await StatisticsCustomerApi.getCustomerSummaryByDate(props.queryParams)
101+
const contractSummary = await StatisticsCustomerApi.getContractSummary(props.queryParams)
102+
// 2.1 更新 Echarts 数据
103+
if (echartsOption.xAxis && echartsOption.xAxis['data']) {
104+
echartsOption.xAxis['data'] = customerCount.map(
105+
(s: CrmStatisticsCustomerSummaryByDateRespVO) => s.time
106+
)
107+
}
108+
if (echartsOption.series && echartsOption.series[0] && echartsOption.series[0]['data']) {
109+
echartsOption.series[0]['data'] = customerCount.map(
110+
(item: CrmStatisticsCustomerSummaryByDateRespVO) => {
111+
return {
112+
name: item.time,
113+
value: item.customerCreateCount
114+
? round((item.customerDealCount / item.customerCreateCount) * 100, 2)
115+
: 0
116+
}
117+
}
118+
)
119+
}
120+
// 2.2 更新列表数据
121+
list.value = contractSummary
122+
loading.value = false
123+
}
124+
defineExpose({ loadData })
125+
126+
/** 初始化 */
127+
onMounted(() => {
128+
loadData()
129+
})
130+
</script>
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<!-- 成交周期分析 -->
2+
<template>
3+
<!-- Echarts图 -->
4+
<el-card shadow="never">
5+
<el-skeleton :loading="loading" animated>
6+
<Echart :height="500" :options="echartsOption" />
7+
</el-skeleton>
8+
</el-card>
9+
10+
<!-- 统计列表 -->
11+
<el-card shadow="never" class="mt-16px">
12+
<el-table v-loading="loading" :data="list">
13+
<el-table-column label="序号" align="center" type="index" width="80" />
14+
<el-table-column label="日期" align="center" prop="ownerUserName" min-width="200" />
15+
<el-table-column
16+
label="成交周期(天)"
17+
align="center"
18+
prop="customerDealCycle"
19+
min-width="200"
20+
/>
21+
<el-table-column label="成交客户数" align="center" prop="customerDealCount" min-width="200" />
22+
</el-table>
23+
</el-card>
24+
</template>
25+
<script setup lang="ts">
26+
import {
27+
StatisticsCustomerApi,
28+
CrmStatisticsCustomerDealCycleByDateRespVO,
29+
CrmStatisticsCustomerSummaryByDateRespVO,
30+
} from '@/api/crm/statistics/customer'
31+
import { EChartsOption } from 'echarts'
32+
33+
defineOptions({ name: 'CustomerDealCycle' })
34+
const props = defineProps<{ queryParams: any }>() // 搜索参数
35+
36+
const loading = ref(false) // 加载中
37+
const list = ref<CrmStatisticsCustomerDealCycleByDateRespVO[]>([]) // 列表的数据
38+
39+
/** 柱状图配置:纵向 */
40+
const echartsOption = reactive<EChartsOption>({
41+
grid: {
42+
left: 20,
43+
right: 20,
44+
bottom: 20,
45+
containLabel: true
46+
},
47+
legend: {},
48+
series: [
49+
{
50+
name: '成交周期(天)',
51+
type: 'bar',
52+
data: []
53+
},
54+
{
55+
name: '成交客户数',
56+
type: 'bar',
57+
data: []
58+
}
59+
],
60+
toolbox: {
61+
feature: {
62+
dataZoom: {
63+
xAxisIndex: false // 数据区域缩放:Y 轴不缩放
64+
},
65+
brush: {
66+
type: ['lineX', 'clear'] // 区域缩放按钮、还原按钮
67+
},
68+
saveAsImage: { show: true, name: '成交周期分析' } // 保存为图片
69+
}
70+
},
71+
tooltip: {
72+
trigger: 'axis',
73+
axisPointer: {
74+
type: 'shadow'
75+
}
76+
},
77+
yAxis: {
78+
type: 'value',
79+
name: '数量(个)'
80+
},
81+
xAxis: {
82+
type: 'category',
83+
name: '日期',
84+
data: []
85+
}
86+
}) as EChartsOption
87+
88+
/** 获取统计数据 */
89+
const loadData = async () => {
90+
// 1. 加载统计数据
91+
loading.value = true
92+
const customerDealCycleByDate = await StatisticsCustomerApi.getCustomerDealCycleByDate(
93+
props.queryParams
94+
)
95+
const customerSummaryByDate = await StatisticsCustomerApi.getCustomerSummaryByDate(
96+
props.queryParams
97+
)
98+
const customerDealCycleByUser = await StatisticsCustomerApi.getCustomerDealCycleByUser(
99+
props.queryParams
100+
)
101+
// 2.1 更新 Echarts 数据
102+
if (echartsOption.xAxis && echartsOption.xAxis['data']) {
103+
echartsOption.xAxis['data'] = customerDealCycleByDate.map(
104+
(s: CrmStatisticsCustomerDealCycleByDateRespVO) => s.time
105+
)
106+
}
107+
if (echartsOption.series && echartsOption.series[0] && echartsOption.series[0]['data']) {
108+
echartsOption.series[0]['data'] = customerDealCycleByDate.map(
109+
(s: CrmStatisticsCustomerDealCycleByDateRespVO) => s.customerDealCycle
110+
)
111+
}
112+
if (echartsOption.series && echartsOption.series[1] && echartsOption.series[1]['data']) {
113+
echartsOption.series[1]['data'] = customerSummaryByDate.map(
114+
(s: CrmStatisticsCustomerSummaryByDateRespVO) => s.customerDealCount
115+
)
116+
}
117+
// 2.2 更新列表数据
118+
list.value = customerDealCycleByUser
119+
loading.value = false
120+
}
121+
defineExpose({ loadData })
122+
123+
/** 初始化 */
124+
onMounted(() => {
125+
loadData()
126+
})
127+
</script>

0 commit comments

Comments
 (0)