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/portrait/components/PortraitCustomerIndustry.vue |  198 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 198 insertions(+), 0 deletions(-)

diff --git a/src/views/crm/statistics/portrait/components/PortraitCustomerIndustry.vue b/src/views/crm/statistics/portrait/components/PortraitCustomerIndustry.vue
new file mode 100644
index 0000000..d426993
--- /dev/null
+++ b/src/views/crm/statistics/portrait/components/PortraitCustomerIndustry.vue
@@ -0,0 +1,198 @@
+<!-- 瀹㈡埛琛屼笟鍒嗘瀽 -->
+<template>
+  <!-- Echarts鍥� -->
+  <el-card shadow="never">
+    <el-row :gutter="20">
+      <el-col :span="12">
+        <el-skeleton :loading="loading" animated>
+          <Echart :height="500" :options="echartsOption" />
+        </el-skeleton>
+      </el-col>
+      <el-col :span="12">
+        <el-skeleton :loading="loading" animated>
+          <Echart :height="500" :options="echartsOption2" />
+        </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="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 align="center" label="瀹㈡埛涓暟" min-width="200" prop="customerCount" />
+      <el-table-column align="center" label="鎴愪氦涓暟" min-width="200" prop="dealCount" />
+      <el-table-column align="center" label="琛屼笟鍗犳瘮(%)" min-width="200" prop="industryPortion" />
+      <el-table-column align="center" label="鎴愪氦鍗犳瘮(%)" min-width="200" prop="dealPortion" />
+    </el-table>
+  </el-card>
+</template>
+<script lang="ts" setup>
+import {
+  CrmStatisticCustomerIndustryRespVO,
+  StatisticsPortraitApi
+} from '@/api/crm/statistics/portrait'
+import { EChartsOption } from 'echarts'
+import { DICT_TYPE, getDictLabel } from '@/utils/dict'
+import { erpCalculatePercentage, getSumValue } from '@/utils'
+import { isEmpty } from '@/utils/is'
+
+defineOptions({ name: 'PortraitCustomerIndustry' })
+const props = defineProps<{ queryParams: any }>() // 鎼滅储鍙傛暟
+
+const loading = ref(false) // 鍔犺浇涓�
+const list = ref<CrmStatisticCustomerIndustryRespVO[]>([]) // 鍒楄〃鐨勬暟鎹�
+
+/** 楗煎浘閰嶇疆锛堝叏閮ㄥ鎴凤級 */
+const echartsOption = reactive<EChartsOption>({
+  title: {
+    text: '鍏ㄩ儴瀹㈡埛',
+    left: 'center'
+  },
+  tooltip: {
+    trigger: 'item'
+  },
+  legend: {
+    orient: 'vertical',
+    left: 'left'
+  },
+  toolbox: {
+    feature: {
+      saveAsImage: { show: true, name: '鍏ㄩ儴瀹㈡埛' } // 淇濆瓨涓哄浘鐗�
+    }
+  },
+  series: [
+    {
+      name: '鍏ㄩ儴瀹㈡埛',
+      type: 'pie',
+      radius: ['40%', '70%'],
+      avoidLabelOverlap: false,
+      itemStyle: {
+        borderRadius: 10,
+        borderColor: '#fff',
+        borderWidth: 2
+      },
+      label: {
+        show: false,
+        position: 'center'
+      },
+      emphasis: {
+        label: {
+          show: true,
+          fontSize: 40,
+          fontWeight: 'bold'
+        }
+      },
+      labelLine: {
+        show: false
+      },
+      data: []
+    }
+  ]
+}) as EChartsOption
+
+/** 楗煎浘閰嶇疆锛堟垚浜ゅ鎴凤級 */
+const echartsOption2 = reactive<EChartsOption>({
+  title: {
+    text: '鎴愪氦瀹㈡埛',
+    left: 'center'
+  },
+  tooltip: {
+    trigger: 'item'
+  },
+  legend: {
+    orient: 'vertical',
+    left: 'left'
+  },
+  toolbox: {
+    feature: {
+      saveAsImage: { show: true, name: '鎴愪氦瀹㈡埛' } // 淇濆瓨涓哄浘鐗�
+    }
+  },
+  series: [
+    {
+      name: '鎴愪氦瀹㈡埛',
+      type: 'pie',
+      radius: ['40%', '70%'],
+      avoidLabelOverlap: false,
+      itemStyle: {
+        borderRadius: 10,
+        borderColor: '#fff',
+        borderWidth: 2
+      },
+      label: {
+        show: false,
+        position: 'center'
+      },
+      emphasis: {
+        label: {
+          show: true,
+          fontSize: 40,
+          fontWeight: 'bold'
+        }
+      },
+      labelLine: {
+        show: false
+      },
+      data: []
+    }
+  ]
+}) as EChartsOption
+
+/** 鑾峰彇缁熻鏁版嵁 */
+const loadData = async () => {
+  // 1. 鍔犺浇缁熻鏁版嵁
+  loading.value = true
+  const industryList = await StatisticsPortraitApi.getCustomerIndustry(props.queryParams)
+  // 2.1 鏇存柊 Echarts 鏁版嵁
+  if (echartsOption.series && echartsOption.series[0] && echartsOption.series[0]['data']) {
+    echartsOption.series[0]['data'] = industryList.map((r: CrmStatisticCustomerIndustryRespVO) => {
+      return {
+        name: getDictLabel(DICT_TYPE.CRM_CUSTOMER_INDUSTRY, r.industryId),
+        value: r.customerCount
+      }
+    })
+  }
+  // 2.2 鏇存柊 Echarts2 鏁版嵁
+  if (echartsOption2.series && echartsOption2.series[0] && echartsOption2.series[0]['data']) {
+    echartsOption2.series[0]['data'] = industryList.map((r: CrmStatisticCustomerIndustryRespVO) => {
+      return {
+        name: getDictLabel(DICT_TYPE.CRM_CUSTOMER_INDUSTRY, r.industryId),
+        value: r.dealCount
+      }
+    })
+  }
+  // 3. 璁$畻姣斾緥
+  calculateProportion(industryList)
+  list.value = industryList
+  loading.value = false
+}
+defineExpose({ loadData })
+
+/** 璁$畻姣斾緥 */
+const calculateProportion = (sourceList: CrmStatisticCustomerIndustryRespVO[]) => {
+  if (isEmpty(sourceList)) {
+    return
+  }
+  // 杩欓噷绫诲瀷涓㈠け浜嗘墍浠ラ噸鏂版悶涓彉閲�
+  const list = sourceList as unknown as CrmStatisticCustomerIndustryRespVO[]
+  const sumCustomerCount = getSumValue(list.map((item) => item.customerCount))
+  const sumDealCount = getSumValue(list.map((item) => item.dealCount))
+  list.forEach((item) => {
+    item.industryPortion =
+      item.customerCount === 0 ? 0 : erpCalculatePercentage(item.customerCount, sumCustomerCount)
+    item.dealPortion =
+      item.dealCount === 0 ? 0 : erpCalculatePercentage(item.dealCount, sumDealCount)
+  })
+}
+
+/** 鍒濆鍖� */
+onMounted(() => {
+  loadData()
+})
+</script>

--
Gitblit v1.8.0