ContractPricePerformance.vue 5.9 KB

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