From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目
---
src/views/crm/statistics/customer/components/CustomerConversionStat.vue | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 170 insertions(+), 0 deletions(-)
diff --git a/src/views/crm/statistics/customer/components/CustomerConversionStat.vue b/src/views/crm/statistics/customer/components/CustomerConversionStat.vue
new file mode 100644
index 0000000..4f5c50c
--- /dev/null
+++ b/src/views/crm/statistics/customer/components/CustomerConversionStat.vue
@@ -0,0 +1,170 @@
+<!-- 瀹㈡埛杞寲鐜囧垎鏋� -->
+<template>
+ <!-- Echarts鍥� -->
+ <el-card shadow="never">
+ <el-skeleton :loading="loading" animated>
+ <Echart :height="500" :options="echartsOption" />
+ </el-skeleton>
+ </el-card>
+
+ <!-- 缁熻鍒楄〃 -->
+ <el-card shadow="never" class="mt-16px">
+ <el-table v-loading="loading" :data="list">
+ <el-table-column label="搴忓彿" align="center" type="index" width="80" fixed="left" />
+ <el-table-column
+ label="瀹㈡埛鍚嶇О"
+ align="center"
+ prop="customerName"
+ min-width="200"
+ fixed="left"
+ />
+ <el-table-column label="鍚堝悓鍚嶇О" align="center" prop="contractName" min-width="200" />
+ <el-table-column
+ label="鍚堝悓鎬婚噾棰�"
+ align="center"
+ prop="totalPrice"
+ min-width="200"
+ :formatter="erpPriceTableColumnFormatter"
+ />
+ <el-table-column
+ label="鍥炴閲戦"
+ align="center"
+ prop="receivablePrice"
+ min-width="200"
+ :formatter="erpPriceTableColumnFormatter"
+ />
+ <el-table-column align="center" label="瀹㈡埛鏉ユ簮" prop="source" width="100">
+ <template #default="scope">
+ <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="scope.row.source" />
+ </template>
+ </el-table-column>
+ <el-table-column align="center" label="瀹㈡埛琛屼笟" prop="industryId" width="100">
+ <template #default="scope">
+ <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_INDUSTRY" :value="scope.row.industryId" />
+ </template>
+ </el-table-column>
+ <el-table-column label="璐熻矗浜�" align="center" prop="ownerUserName" min-width="200" />
+ <el-table-column label="鍒涘缓浜�" align="center" prop="creatorUserName" min-width="200" />
+ <el-table-column
+ label="鍒涘缓鏃堕棿"
+ align="center"
+ prop="createTime"
+ :formatter="dateFormatter"
+ min-width="200"
+ />
+ <el-table-column
+ label="涓嬪崟鏃ユ湡"
+ align="center"
+ prop="orderDate"
+ :formatter="dateFormatter"
+ min-width="200"
+ fixed="right"
+ />
+ </el-table>
+ </el-card>
+</template>
+<script setup lang="ts">
+import {
+ StatisticsCustomerApi,
+ CrmStatisticsCustomerSummaryByDateRespVO
+} from '@/api/crm/statistics/customer'
+import { EChartsOption } from 'echarts'
+import { dateFormatter } from '@/utils/formatTime'
+import { erpPriceTableColumnFormatter } from '@/utils'
+import { DICT_TYPE } from '@/utils/dict'
+
+defineOptions({ name: 'CustomerConversionStat' })
+
+const props = defineProps<{ queryParams: any }>() // 鎼滅储鍙傛暟
+
+const loading = ref(false) // 鍔犺浇涓�
+const list = ref<CrmStatisticsCustomerSummaryByDateRespVO[]>([]) // 鍒楄〃鐨勬暟鎹�
+
+/** 鏌辩姸鍥鹃厤缃細绾靛悜 */
+const echartsOption = reactive<EChartsOption>({
+ grid: {
+ left: 20,
+ right: 40, // 璁� X 杞村彸渚ф樉绀哄畬鏁�
+ bottom: 20,
+ containLabel: true
+ },
+ legend: {},
+ series: [
+ {
+ name: '瀹㈡埛杞寲鐜�',
+ type: 'line',
+ data: []
+ }
+ ],
+ toolbox: {
+ feature: {
+ dataZoom: {
+ xAxisIndex: false // 鏁版嵁鍖哄煙缂╂斁锛歒 杞翠笉缂╂斁
+ },
+ brush: {
+ type: ['lineX', 'clear'] // 鍖哄煙缂╂斁鎸夐挳銆佽繕鍘熸寜閽�
+ },
+ saveAsImage: { show: true, name: '瀹㈡埛杞寲鐜囧垎鏋�' } // 淇濆瓨涓哄浘鐗�
+ }
+ },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ type: 'shadow'
+ }
+ },
+ yAxis: {
+ type: 'value',
+ name: '杞寲鐜�(%)'
+ },
+ xAxis: {
+ type: 'category',
+ name: '鏃ユ湡',
+ data: []
+ }
+}) as EChartsOption
+
+/** 鑾峰彇鏁版嵁骞跺~鍏呭浘琛� */
+const fetchAndFill = async () => {
+ // 1. 鍔犺浇缁熻鏁版嵁
+ const customerCount = await StatisticsCustomerApi.getCustomerSummaryByDate(props.queryParams)
+ const contractSummary = await StatisticsCustomerApi.getContractSummary(props.queryParams)
+ // 2.1 鏇存柊 Echarts 鏁版嵁
+ if (echartsOption.xAxis && echartsOption.xAxis['data']) {
+ echartsOption.xAxis['data'] = customerCount.map(
+ (s: CrmStatisticsCustomerSummaryByDateRespVO) => s.time
+ )
+ }
+ if (echartsOption.series && echartsOption.series[0] && echartsOption.series[0]['data']) {
+ echartsOption.series[0]['data'] = customerCount.map(
+ (item: CrmStatisticsCustomerSummaryByDateRespVO) => {
+ return {
+ name: item.time,
+ value: item.customerCreateCount
+ ? ((item.customerDealCount / item.customerCreateCount) * 100).toFixed(2)
+ : 0
+ }
+ }
+ )
+ }
+ // 2.2 鏇存柊鍒楄〃鏁版嵁
+ list.value = contractSummary
+}
+
+/** 鑾峰彇缁熻鏁版嵁 */
+const loadData = async () => {
+ loading.value = true
+ try {
+ await fetchAndFill()
+ } finally {
+ loading.value = false
+ }
+}
+
+defineExpose({ loadData })
+
+/** 鍒濆鍖� */
+onMounted(() => {
+ loadData()
+})
+</script>
--
Gitblit v1.8.0