123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- <!-- 销售漏斗分析 -->
- <template>
- <!-- Echarts图 -->
- <el-card shadow="never">
- <el-row>
- <el-col :span="24">
- <el-button-group class="mb-10px">
- <el-button type="primary" @click="handleActive(true)">客户视角</el-button>
- <el-button type="primary" @click="handleActive(false)">动态视角</el-button>
- </el-button-group>
- <el-skeleton :loading="loading" animated>
- <Echart :height="500" :options="echartsOption" />
- </el-skeleton>
- </el-col>
- </el-row>
- </el-card>
- <!-- 统计列表 -->
- <el-card class="mt-16px" shadow="never">
- <el-table v-loading="loading" :data="list">
- <el-table-column align="center" label="序号" type="index" width="80" />
- <el-table-column align="center" label="阶段" prop="endStatus" width="200">
- <template #default="scope">
- <dict-tag :type="DICT_TYPE.CRM_BUSINESS_END_STATUS_TYPE" :value="scope.row.endStatus" />
- </template>
- </el-table-column>
- <el-table-column align="center" label="商机数" min-width="200" prop="businessCount" />
- <el-table-column align="center" label="商机总金额(元)" min-width="200" prop="totalPrice" />
- </el-table>
- </el-card>
- </template>
- <script lang="ts" setup>
- import { CrmStatisticFunnelRespVO, StatisticFunnelApi } from '@/api/crm/statistics/funnel'
- import { EChartsOption } from 'echarts'
- import { DICT_TYPE } from '@/utils/dict'
- import echarts from '@/plugins/echarts'
- import { FunnelChart } from 'echarts/charts'
- defineOptions({ name: 'FunnelBusiness' })
- const props = defineProps<{ queryParams: any }>() // 搜索参数
- const active = ref(true)
- const loading = ref(false) // 加载中
- const list = ref<CrmStatisticFunnelRespVO[]>([]) // 列表的数据
- /** 销售漏斗 */
- echarts?.use([FunnelChart])
- const echartsOption = reactive<EChartsOption>({
- title: {
- text: '销售漏斗'
- },
- tooltip: {
- trigger: 'item',
- formatter: '{a} <br/>{b}'
- },
- toolbox: {
- feature: {
- dataView: { readOnly: false },
- restore: {},
- saveAsImage: {}
- }
- },
- legend: {
- data: ['客户', '商机', '赢单']
- },
- series: [
- {
- name: '销售漏斗',
- type: 'funnel',
- left: '10%',
- top: 60,
- bottom: 60,
- width: '80%',
- min: 0,
- max: 100,
- minSize: '0%',
- maxSize: '100%',
- sort: 'descending',
- gap: 2,
- label: {
- show: true,
- position: 'inside'
- },
- labelLine: {
- length: 10,
- lineStyle: {
- width: 1,
- type: 'solid'
- }
- },
- itemStyle: {
- borderColor: '#fff',
- borderWidth: 1
- },
- emphasis: {
- label: {
- fontSize: 20
- }
- },
- data: [
- { value: 60, name: '客户-0个' },
- { value: 40, name: '商机-0个' },
- { value: 20, name: '赢单-0个' }
- ]
- }
- ]
- }) as EChartsOption
- const handleActive = async (val: boolean) => {
- active.value = val
- await loadData()
- }
- /** 获取统计数据 */
- const loadData = async () => {
- loading.value = true
- // 1. 加载漏斗数据
- const data = (await StatisticFunnelApi.getFunnelSummary(
- props.queryParams
- )) as CrmStatisticFunnelRespVO
- // 2.1 更新 Echarts 数据
- if (
- !!data &&
- echartsOption.series &&
- echartsOption.series[0] &&
- echartsOption.series[0]['data']
- ) {
- // tips:写死 value 值是为了保持漏斗顺序不变
- const list: { value: number; name: string }[] = []
- if (active.value) {
- list.push({ value: 60, name: `客户-${data.customerCount || 0}个` })
- list.push({ value: 40, name: `商机-${data.businessCount || 0}个` })
- list.push({ value: 20, name: `赢单-${data.businessWinCount || 0}个` })
- } else {
- list.push({ value: data.customerCount || 0, name: `客户-${data.customerCount || 0}个` })
- list.push({ value: data.businessCount || 0, name: `商机-${data.businessCount || 0}个` })
- list.push({ value: data.businessWinCount || 0, name: `赢单-${data.businessWinCount || 0}个` })
- }
- echartsOption.series[0]['data'] = list
- }
- // 2.2 获取商机结束状态统计
- list.value = await StatisticFunnelApi.getBusinessSummaryByEndStatus(props.queryParams)
- loading.value = false
- }
- defineExpose({ loadData })
- /** 初始化 */
- onMounted(() => {
- loadData()
- })
- </script>
|