CustomerAddress.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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. // TODO @puhui999:address 换成 area 会更合适哈,
  28. defineOptions({ name: 'CustomerAddress' })
  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: item.areaName // TODO @puhui999:这里最好注释下原因哈
  105. .replace('维吾尔自治区', '')
  106. .replace('壮族自治区', '')
  107. .replace('回族自治区', '')
  108. .replace('自治区', '')
  109. .replace('省', '')
  110. }
  111. })
  112. builderLeftMap()
  113. builderRightMap()
  114. loading.value = false
  115. }
  116. defineExpose({ loadData })
  117. // TODO @puhui999:builder 改成 build 更合理哈
  118. const builderLeftMap = () => {
  119. let min = 0
  120. let max = 0
  121. echartsOption.series![0].data = areaStatisticsList.value.map((item) => {
  122. min = Math.min(min, item.customerCount || 0)
  123. max = Math.max(max, item.customerCount || 0)
  124. return { ...item, name: item.areaName, value: item.customerCount || 0 }
  125. })
  126. echartsOption.visualMap!['min'] = min
  127. echartsOption.visualMap!['max'] = max
  128. }
  129. const builderRightMap = () => {
  130. let min = 0
  131. let max = 0
  132. echartsOption2.series![0].data = areaStatisticsList.value.map((item) => {
  133. min = Math.min(min, item.dealCount || 0)
  134. max = Math.max(max, item.dealCount || 0)
  135. return { ...item, name: item.areaName, value: item.dealCount || 0 }
  136. })
  137. echartsOption2.visualMap!['min'] = min
  138. echartsOption2.visualMap!['max'] = max
  139. }
  140. /** 初始化 */
  141. onMounted(() => {
  142. loadData()
  143. })
  144. </script>