PortraitCustomerArea.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <!-- 客户城市分布 -->
  2. <template>
  3. <!-- Echarts图 -->
  4. <el-card shadow="never">
  5. <el-row :gutter="20">
  6. <el-col :span="12">
  7. <el-skeleton :loading="loading" animated>
  8. <Echart :height="500" :options="echartsOption" />
  9. </el-skeleton>
  10. </el-col>
  11. <el-col :span="12">
  12. <el-skeleton :loading="loading" animated>
  13. <Echart :height="500" :options="echartsOption2" />
  14. </el-skeleton>
  15. </el-col>
  16. </el-row>
  17. </el-card>
  18. </template>
  19. <script lang="ts" setup>
  20. import { EChartsOption } from 'echarts'
  21. import china from '@/assets/map/json/china.json'
  22. import echarts from '@/plugins/echarts'
  23. import {
  24. CrmStatisticCustomerAreaRespVO,
  25. StatisticsPortraitApi
  26. } from '@/api/crm/statistics/portrait'
  27. import { areaReplace } from '@/utils'
  28. defineOptions({ name: 'PortraitCustomerArea' })
  29. const props = defineProps<{ queryParams: any }>() // 搜索参数
  30. // 注册地图
  31. echarts?.registerMap('china', china as any)
  32. const loading = ref(false) // 加载中
  33. const areaStatisticsList = ref<CrmStatisticCustomerAreaRespVO[]>([]) // 列表的数据
  34. /** 地图配置(全部客户) */
  35. const echartsOption = reactive<EChartsOption>({
  36. title: {
  37. text: '全部客户',
  38. left: 'center'
  39. },
  40. tooltip: {
  41. trigger: 'item',
  42. showDelay: 0,
  43. transitionDuration: 0.2
  44. },
  45. visualMap: {
  46. text: ['高', '低'],
  47. realtime: false,
  48. calculable: true,
  49. top: 'middle',
  50. inRange: {
  51. color: ['#fff', '#3b82f6']
  52. }
  53. },
  54. series: [
  55. {
  56. name: '客户地域分布',
  57. type: 'map',
  58. map: 'china',
  59. roam: false,
  60. selectedMode: false,
  61. data: []
  62. }
  63. ]
  64. }) as EChartsOption
  65. /** 地图配置(成交客户) */
  66. const echartsOption2 = reactive<EChartsOption>({
  67. title: {
  68. text: '成交客户',
  69. left: 'center'
  70. },
  71. tooltip: {
  72. trigger: 'item',
  73. showDelay: 0,
  74. transitionDuration: 0.2
  75. },
  76. visualMap: {
  77. text: ['高', '低'],
  78. realtime: false,
  79. calculable: true,
  80. top: 'middle',
  81. inRange: {
  82. color: ['#fff', '#3b82f6']
  83. }
  84. },
  85. series: [
  86. {
  87. name: '客户地域分布',
  88. type: 'map',
  89. map: 'china',
  90. roam: false,
  91. selectedMode: false,
  92. data: []
  93. }
  94. ]
  95. }) as EChartsOption
  96. /** 获取统计数据 */
  97. const loadData = async () => {
  98. // 1. 加载统计数据
  99. loading.value = true
  100. const areaList = await StatisticsPortraitApi.getCustomerArea(props.queryParams)
  101. areaStatisticsList.value = areaList.map((item: CrmStatisticCustomerAreaRespVO) => {
  102. return {
  103. ...item,
  104. areaName: areaReplace(item.areaName)
  105. }
  106. })
  107. buildLeftMap()
  108. buildRightMap()
  109. loading.value = false
  110. }
  111. defineExpose({ loadData })
  112. const buildLeftMap = () => {
  113. let min = 0
  114. let max = 0
  115. echartsOption.series![0].data = areaStatisticsList.value.map((item) => {
  116. min = Math.min(min, item.customerCount || 0)
  117. max = Math.max(max, item.customerCount || 0)
  118. return { ...item, name: item.areaName, value: item.customerCount || 0 }
  119. })
  120. echartsOption.visualMap!['min'] = min
  121. echartsOption.visualMap!['max'] = max
  122. }
  123. const buildRightMap = () => {
  124. let min = 0
  125. let max = 0
  126. echartsOption2.series![0].data = areaStatisticsList.value.map((item) => {
  127. min = Math.min(min, item.dealCount || 0)
  128. max = Math.max(max, item.dealCount || 0)
  129. return { ...item, name: item.areaName, value: item.dealCount || 0 }
  130. })
  131. echartsOption2.visualMap!['min'] = min
  132. echartsOption2.visualMap!['max'] = max
  133. }
  134. /** 初始化 */
  135. onMounted(() => {
  136. loadData()
  137. })
  138. </script>