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/funnel/components/BusinessSummary.vue |  259 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 259 insertions(+), 0 deletions(-)

diff --git a/src/views/crm/statistics/funnel/components/BusinessSummary.vue b/src/views/crm/statistics/funnel/components/BusinessSummary.vue
new file mode 100644
index 0000000..942a712
--- /dev/null
+++ b/src/views/crm/statistics/funnel/components/BusinessSummary.vue
@@ -0,0 +1,259 @@
+<!-- 瀹㈡埛鎬婚噺缁熻 -->
+<template>
+  <!-- Echarts鍥� -->
+  <el-card shadow="never">
+    <el-skeleton :loading="loading" animated>
+      <Echart :height="500" :options="echartsOption" />
+    </el-skeleton>
+  </el-card>
+
+  <!-- 缁熻鍒楄〃 -->
+  <el-card class="mt-16px" shadow="never">
+    <el-table v-loading="loading" :data="list">
+      <el-table-column align="center" fixed="left" label="搴忓彿" type="index" width="80" />
+      <el-table-column align="center" fixed="left" label="鍟嗘満鍚嶇О" prop="name" width="160">
+        <template #default="scope">
+          <el-link :underline="false" type="primary" @click="openDetail(scope.row.id)">
+            {{ scope.row.name }}
+          </el-link>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" fixed="left" label="瀹㈡埛鍚嶇О" prop="customerName" width="120">
+        <template #default="scope">
+          <el-link
+            :underline="false"
+            type="primary"
+            @click="openCustomerDetail(scope.row.customerId)"
+          >
+            {{ scope.row.customerName }}
+          </el-link>
+        </template>
+      </el-table-column>
+      <el-table-column
+        :formatter="erpPriceTableColumnFormatter"
+        align="center"
+        label="鍟嗘満閲戦锛堝厓锛�"
+        prop="totalPrice"
+        width="140"
+      />
+      <el-table-column
+        :formatter="dateFormatter"
+        align="center"
+        label="棰勮鎴愪氦鏃ユ湡"
+        prop="dealTime"
+        width="180px"
+      />
+      <el-table-column align="center" label="澶囨敞" prop="remark" width="200" />
+      <el-table-column
+        :formatter="dateFormatter"
+        align="center"
+        label="涓嬫鑱旂郴鏃堕棿"
+        prop="contactNextTime"
+        width="180px"
+      />
+      <el-table-column align="center" label="璐熻矗浜�" prop="ownerUserName" width="100px" />
+      <el-table-column align="center" label="鎵�灞為儴闂�" prop="ownerUserDeptName" width="100px" />
+      <el-table-column
+        :formatter="dateFormatter"
+        align="center"
+        label="鏈�鍚庤窡杩涙椂闂�"
+        prop="contactLastTime"
+        width="180px"
+      />
+      <el-table-column
+        :formatter="dateFormatter"
+        align="center"
+        label="鏇存柊鏃堕棿"
+        prop="updateTime"
+        width="180px"
+      />
+      <el-table-column
+        :formatter="dateFormatter"
+        align="center"
+        label="鍒涘缓鏃堕棿"
+        prop="createTime"
+        width="180px"
+      />
+      <el-table-column align="center" label="鍒涘缓浜�" prop="creatorName" width="100px" />
+      <el-table-column
+        align="center"
+        fixed="right"
+        label="鍟嗘満鐘舵�佺粍"
+        prop="statusTypeName"
+        width="140"
+      />
+      <el-table-column
+        align="center"
+        fixed="right"
+        label="鍟嗘満闃舵"
+        prop="statusName"
+        width="120"
+      />
+    </el-table>
+    <!-- 鍒嗛〉 -->
+    <Pagination
+      v-model:limit="queryParams0.pageSize"
+      v-model:page="queryParams0.pageNo"
+      :total="total"
+      @pagination="getList"
+    />
+  </el-card>
+</template>
+<script lang="ts" setup>
+import {
+  CrmStatisticsBusinessSummaryByDateRespVO,
+  StatisticFunnelApi
+} from '@/api/crm/statistics/funnel'
+import { EChartsOption } from 'echarts'
+import { erpPriceTableColumnFormatter } from '@/utils'
+import { dateFormatter } from '@/utils/formatTime'
+
+defineOptions({ name: 'BusinessSummary' })
+
+const props = defineProps<{ queryParams: any }>() // 鎼滅储鍙傛暟
+const queryParams0 = reactive({
+  pageNo: 1,
+  pageSize: 10
+})
+const loading = ref(false) // 鍔犺浇涓�
+const list = ref([]) // 鍒楄〃鐨勬暟鎹�
+const total = ref(0)
+/** 灏嗕紶杩涙潵鐨勫�艰祴鍊肩粰 queryParams0 */
+watch(
+  () => props.queryParams,
+  (data) => {
+    if (!data) {
+      return
+    }
+    const newObj = { ...queryParams0, ...data }
+    Object.assign(queryParams0, newObj)
+  },
+  {
+    immediate: true
+  }
+)
+/** 鏌辩姸鍥鹃厤缃細绾靛悜 */
+const echartsOption = reactive<EChartsOption>({
+  grid: {
+    left: 30,
+    right: 30, // 璁� X 杞村彸渚ф樉绀哄畬鏁�
+    bottom: 20,
+    containLabel: true
+  },
+  legend: {},
+  series: [
+    {
+      name: '鏂板鍟嗘満鏁伴噺',
+      type: 'bar',
+      yAxisIndex: 0,
+      data: []
+    },
+    {
+      name: '鏂板鍟嗘満閲戦',
+      type: 'bar',
+      yAxisIndex: 1,
+      data: []
+    }
+  ],
+  toolbox: {
+    feature: {
+      dataZoom: {
+        xAxisIndex: false // 鏁版嵁鍖哄煙缂╂斁锛歒 杞翠笉缂╂斁
+      },
+      brush: {
+        type: ['lineX', 'clear'] // 鍖哄煙缂╂斁鎸夐挳銆佽繕鍘熸寜閽�
+      },
+      saveAsImage: { show: true, name: '鏂板鍟嗘満鍒嗘瀽' } // 淇濆瓨涓哄浘鐗�
+    }
+  },
+  tooltip: {
+    trigger: 'axis',
+    axisPointer: {
+      type: 'shadow'
+    }
+  },
+  yAxis: [
+    {
+      type: 'value',
+      name: '鏂板鍟嗘満鏁伴噺',
+      min: 0,
+      minInterval: 1 // 鏄剧ず鏁存暟鍒诲害
+    },
+    {
+      type: 'value',
+      name: '鏂板鍟嗘満閲戦',
+      min: 0,
+      minInterval: 1, // 鏄剧ず鏁存暟鍒诲害
+      splitLine: {
+        lineStyle: {
+          type: 'dotted', // 鍙充晶缃戞牸绾胯櫄鍖�, 鍑忓皯娣蜂贡
+          opacity: 0.7
+        }
+      }
+    }
+  ],
+  xAxis: {
+    type: 'category',
+    name: '鏃ユ湡',
+    data: []
+  }
+}) as EChartsOption
+
+/** 鑾峰彇鏁版嵁骞跺~鍏呭浘琛� */
+const fetchAndFill = async () => {
+  // 1. 鍔犺浇缁熻鏁版嵁
+  const businessSummaryByDate = await StatisticFunnelApi.getBusinessSummaryByDate(props.queryParams)
+  // 2.1 鏇存柊 Echarts 鏁版嵁
+  if (echartsOption.xAxis && echartsOption.xAxis['data']) {
+    echartsOption.xAxis['data'] = businessSummaryByDate.map(
+      (s: CrmStatisticsBusinessSummaryByDateRespVO) => s.time
+    )
+  }
+  if (echartsOption.series && echartsOption.series[0] && echartsOption.series[0]['data']) {
+    echartsOption.series[0]['data'] = businessSummaryByDate.map(
+      (s: CrmStatisticsBusinessSummaryByDateRespVO) => s.businessCreateCount
+    )
+  }
+  if (echartsOption.series && echartsOption.series[1] && echartsOption.series[1]['data']) {
+    echartsOption.series[1]['data'] = businessSummaryByDate.map(
+      (s: CrmStatisticsBusinessSummaryByDateRespVO) => s.totalPrice
+    )
+  }
+
+  // 2.2 鏇存柊鍒楄〃鏁版嵁
+  await getList()
+}
+/** 鑾峰彇鍟嗘満鍒楄〃 */
+const getList = async () => {
+  const data = await StatisticFunnelApi.getBusinessPageByDate(props.queryParams)
+  list.value = data.list
+  total.value = data.total
+}
+/** 鎵撳紑瀹㈡埛璇︽儏 */
+const { push } = useRouter()
+const openDetail = (id: number) => {
+  push({ name: 'CrmBusinessDetail', params: { id } })
+}
+
+/** 鎵撳紑瀹㈡埛璇︽儏 */
+const openCustomerDetail = (id: number) => {
+  push({ name: 'CrmCustomerDetail', params: { id } })
+}
+
+/** 鑾峰彇缁熻鏁版嵁 */
+const loadData = async () => {
+  loading.value = true
+  try {
+    await fetchAndFill()
+  } finally {
+    loading.value = false
+  }
+}
+
+defineExpose({ loadData })
+
+/** 鍒濆鍖� */
+onMounted(() => {
+  loadData()
+})
+</script>

--
Gitblit v1.8.0