PortraitCustomerArea.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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. defineOptions({ name: 'PortraitCustomerArea' })
  28. const props = defineProps<{ queryParams: any }>() // 搜索参数
  29. // 注册地图
  30. echarts?.registerMap('china', china as any)
  31. const loading = ref(false) // 加载中
  32. const areaStatisticsList = ref<CrmStatisticCustomerAreaRespVO[]>([]) // 列表的数据
  33. /** 地图配置(全部客户) */
  34. const echartsOption = reactive<EChartsOption>({
  35. title: {
  36. text: '全部客户',
  37. left: 'center'
  38. },
  39. tooltip: {
  40. trigger: 'item',
  41. showDelay: 0,
  42. transitionDuration: 0.2
  43. },
  44. visualMap: {
  45. text: ['高', '低'],
  46. realtime: false,
  47. calculable: true,
  48. top: 'middle',
  49. inRange: {
  50. color: ['#fff', '#3b82f6']
  51. }
  52. },
  53. series: [
  54. {
  55. name: '客户地域分布',
  56. type: 'map',
  57. map: 'china',
  58. roam: false,
  59. selectedMode: false,
  60. data: []
  61. }
  62. ]
  63. }) as EChartsOption
  64. /** 地图配置(成交客户) */
  65. const echartsOption2 = reactive<EChartsOption>({
  66. title: {
  67. text: '成交客户',
  68. left: 'center'
  69. },
  70. tooltip: {
  71. trigger: 'item',
  72. showDelay: 0,
  73. transitionDuration: 0.2
  74. },
  75. visualMap: {
  76. text: ['高', '低'],
  77. realtime: false,
  78. calculable: true,
  79. top: 'middle',
  80. inRange: {
  81. color: ['#fff', '#3b82f6']
  82. }
  83. },
  84. series: [
  85. {
  86. name: '客户地域分布',
  87. type: 'map',
  88. map: 'china',
  89. roam: false,
  90. selectedMode: false,
  91. data: []
  92. }
  93. ]
  94. }) as EChartsOption
  95. /** 获取统计数据 */
  96. const loadData = async () => {
  97. // 1. 加载统计数据
  98. loading.value = true
  99. const areaList = await StatisticsPortraitApi.getCustomerArea(props.queryParams)
  100. areaStatisticsList.value = areaList.map((item: CrmStatisticCustomerAreaRespVO) => {
  101. return {
  102. ...item,
  103. areaName: item.areaName // TODO @puhui999:这里最好注释下原因哈, 🤣 我从 mall copy 过来的
  104. // .replace('维吾尔自治区', '')
  105. // .replace('壮族自治区', '')
  106. // .replace('回族自治区', '')
  107. // .replace('自治区', '')
  108. // .replace('省', '')
  109. }
  110. })
  111. buildLeftMap()
  112. buildRightMap()
  113. loading.value = false
  114. }
  115. defineExpose({ loadData })
  116. const buildLeftMap = () => {
  117. let min = 0
  118. let max = 0
  119. echartsOption.series![0].data = areaStatisticsList.value.map((item) => {
  120. min = Math.min(min, item.customerCount || 0)
  121. max = Math.max(max, item.customerCount || 0)
  122. return { ...item, name: item.areaName, value: item.customerCount || 0 }
  123. })
  124. echartsOption.visualMap!['min'] = min
  125. echartsOption.visualMap!['max'] = max
  126. }
  127. const buildRightMap = () => {
  128. let min = 0
  129. let max = 0
  130. echartsOption2.series![0].data = areaStatisticsList.value.map((item) => {
  131. min = Math.min(min, item.dealCount || 0)
  132. max = Math.max(max, item.dealCount || 0)
  133. return { ...item, name: item.areaName, value: item.dealCount || 0 }
  134. })
  135. echartsOption2.visualMap!['min'] = min
  136. echartsOption2.visualMap!['max'] = max
  137. }
  138. /** 初始化 */
  139. onMounted(() => {
  140. loadData()
  141. })
  142. </script>