ContractPricePerformance.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <!-- 客户总量统计 -->
  2. <template>
  3. <!-- Echarts图 -->
  4. <el-card shadow="never">
  5. <el-skeleton :loading="loading" animated>
  6. <Echart :height="500" :options="echartsOption" />
  7. </el-skeleton>
  8. </el-card>
  9. <!-- 统计列表 TODO @scholar:统计列表的展示不对 -->
  10. <el-card shadow="never" class="mt-16px">
  11. <el-table v-loading="loading" :data="tableData">
  12. <el-table-column
  13. v-for="item in columnsData"
  14. :key="item.prop"
  15. :label="item.label"
  16. :prop="item.prop"
  17. align="center"
  18. >
  19. <template #default="scope">
  20. {{ scope.row[item.prop] }}
  21. </template>
  22. </el-table-column>
  23. </el-table>
  24. </el-card>
  25. </template>
  26. <script setup lang="ts">
  27. import { EChartsOption } from 'echarts'
  28. import {
  29. StatisticsPerformanceApi,
  30. StatisticsPerformanceRespVO
  31. } from '@/api/crm/statistics/performance'
  32. defineOptions({ name: 'ContractPricePerformance' })
  33. const props = defineProps<{ queryParams: any }>() // 搜索参数
  34. const loading = ref(false) // 加载中
  35. const list = ref<StatisticsPerformanceRespVO[]>([]) // 列表的数据
  36. /** 柱状图配置:纵向 */
  37. const echartsOption = reactive<EChartsOption>({
  38. grid: {
  39. left: 20,
  40. right: 20,
  41. bottom: 20,
  42. containLabel: true
  43. },
  44. legend: {},
  45. series: [
  46. {
  47. name: '当月合同金额(元)',
  48. type: 'line',
  49. data: []
  50. },
  51. {
  52. name: '上月合同金额(元)',
  53. type: 'line',
  54. data: []
  55. },
  56. {
  57. name: '去年同月合同金额(元)',
  58. type: 'line',
  59. data: []
  60. },
  61. {
  62. name: '同比增长率(%)',
  63. type: 'line',
  64. yAxisIndex: 1,
  65. data: []
  66. },
  67. {
  68. name: '环比增长率(%)',
  69. type: 'line',
  70. yAxisIndex: 1,
  71. data: []
  72. }
  73. ],
  74. toolbox: {
  75. feature: {
  76. dataZoom: {
  77. xAxisIndex: false // 数据区域缩放:Y 轴不缩放
  78. },
  79. brush: {
  80. type: ['lineX', 'clear'] // 区域缩放按钮、还原按钮
  81. },
  82. saveAsImage: { show: true, name: '客户总量分析' } // 保存为图片
  83. }
  84. },
  85. tooltip: {
  86. trigger: 'axis',
  87. axisPointer: {
  88. type: 'shadow'
  89. }
  90. },
  91. yAxis: [
  92. {
  93. type: 'value',
  94. name: '金额(元)',
  95. axisTick: {
  96. show: false
  97. },
  98. axisLabel: {
  99. color: '#BDBDBD',
  100. formatter: '{value}'
  101. },
  102. /** 坐标轴轴线相关设置 */
  103. axisLine: {
  104. lineStyle: {
  105. color: '#BDBDBD'
  106. }
  107. },
  108. splitLine: {
  109. show: true,
  110. lineStyle: {
  111. color: '#e6e6e6'
  112. }
  113. }
  114. },
  115. {
  116. type: 'value',
  117. name: '',
  118. axisTick: {
  119. alignWithLabel: true,
  120. lineStyle: {
  121. width: 0
  122. }
  123. },
  124. axisLabel: {
  125. color: '#BDBDBD',
  126. formatter: '{value}%'
  127. },
  128. /** 坐标轴轴线相关设置 */
  129. axisLine: {
  130. lineStyle: {
  131. color: '#BDBDBD'
  132. }
  133. },
  134. splitLine: {
  135. show: true,
  136. lineStyle: {
  137. color: '#e6e6e6'
  138. }
  139. }
  140. }
  141. ],
  142. xAxis: {
  143. type: 'category',
  144. name: '日期',
  145. data: []
  146. }
  147. }) as EChartsOption
  148. /** 获取统计数据 */
  149. const loadData = async () => {
  150. // 1. 加载统计数据
  151. loading.value = true
  152. const performanceList = await StatisticsPerformanceApi.getContractPricePerformance(
  153. props.queryParams
  154. )
  155. // 2.1 更新 Echarts 数据
  156. if (echartsOption.xAxis && echartsOption.xAxis['data']) {
  157. echartsOption.xAxis['data'] = performanceList.map((s: StatisticsPerformanceRespVO) => s.time)
  158. }
  159. if (echartsOption.series && echartsOption.series[0] && echartsOption.series[0]['data']) {
  160. echartsOption.series[0]['data'] = performanceList.map(
  161. (s: StatisticsPerformanceRespVO) => s.currentMonthCount
  162. )
  163. }
  164. if (echartsOption.series && echartsOption.series[1] && echartsOption.series[1]['data']) {
  165. echartsOption.series[1]['data'] = performanceList.map(
  166. (s: StatisticsPerformanceRespVO) => s.lastMonthCount
  167. )
  168. echartsOption.series[3]['data'] = performanceList.map((s: StatisticsPerformanceRespVO) =>
  169. s.lastMonthCount !== 0 ? ((s.currentMonthCount / s.lastMonthCount) * 100).toFixed(2) : 'NULL'
  170. )
  171. }
  172. if (echartsOption.series && echartsOption.series[2] && echartsOption.series[2]['data']) {
  173. echartsOption.series[2]['data'] = performanceList.map(
  174. (s: StatisticsPerformanceRespVO) => s.lastYearCount
  175. )
  176. echartsOption.series[4]['data'] = performanceList.map((s: StatisticsPerformanceRespVO) =>
  177. s.lastYearCount !== 0 ? ((s.currentMonthCount / s.lastYearCount) * 100).toFixed(2) : 'NULL'
  178. )
  179. }
  180. // 2.2 更新列表数据
  181. list.value = performanceList
  182. loading.value = false
  183. }
  184. // 初始化数据
  185. const columnsData = reactive([])
  186. const tableData = reactive([
  187. { title: '当月合同金额统计(元)' },
  188. { title: '上月合同金额统计(元)' },
  189. { title: '去年当月合同金额统计(元)' },
  190. { title: '同比增长率(%)' },
  191. { title: '环比增长率(%)' }
  192. ])
  193. // 定义 init 方法
  194. const init = () => {
  195. const columnObj = { label: '日期', prop: 'title' }
  196. columnsData.push(columnObj)
  197. list.value.forEach((item, index) => {
  198. const columnObj = { label: item.time, prop: 'prop' + index }
  199. columnsData.push(columnObj)
  200. tableData[0]['prop' + index] = item.currentMonthCount
  201. tableData[1]['prop' + index] = item.lastMonthCount
  202. tableData[2]['prop' + index] = item.lastYearCount
  203. tableData[3]['prop' + index] =
  204. item.lastYearCount !== 0 ? (item.currentMonthCount / item.lastYearCount).toFixed(2) : 'NULL'
  205. tableData[4]['prop' + index] =
  206. item.lastMonthCount !== 0 ? (item.currentMonthCount / item.lastMonthCount).toFixed(2) : 'NULL'
  207. })
  208. }
  209. defineExpose({ loadData })
  210. /** 初始化 */
  211. onMounted(async () => {
  212. await loadData()
  213. init()
  214. })
  215. </script>