刘洋 1 жил өмнө
parent
commit
8a271b24df

+ 7 - 0
src/api/report.js

@@ -141,6 +141,13 @@ export const projectStageAnalysis = (params) =>
     params,
   });
 
+//项目燃尽图
+export const projectProcessAnalysis = (params) =>
+  request({
+    url: '/api/sop/schedule/projectProgress',
+    params,
+  });
+
 // -----------------------------------设备保障监控-----------------------------------------
 export const deviceStatusAnalysis = (params) =>
   request({

+ 45 - 0
src/utils/chart.js

@@ -589,3 +589,48 @@ export const createPercentBarOption = (
     extend
   );
 };
+
+export const createLineOption = ({ sData = [], xData = [] }, extend = {}) => {
+  return mergeParams(
+    {
+      grid: {
+        top: 50,
+        bottom: 15,
+        left: 30,
+        right: 30,
+        containLabel: true,
+      },
+      legend: {
+        top: 10,
+        itemWidth: 10,
+        data: sData.map((item) => item.name),
+      },
+      tooltip: {
+        trigger: 'axis',
+      },
+      xAxis: {
+        axisLine: { show: false },
+        axisTick: { show: false },
+        splitLine: { show: false },
+        axisLabel: {
+          align: 'right',
+        },
+        data: xData,
+      },
+      yAxis: [
+        {
+          type: 'value',
+        },
+      ],
+      series: sData.map((item, index) => ({
+        name: item.name,
+        type: 'line',
+        itemStyle: {
+          color: colorList[index],
+        },
+        data: item.data,
+      })),
+    },
+    {}
+  );
+};

+ 37 - 0
src/views/report/dispatch-analysis/custom-type-drill-dialog.vue

@@ -0,0 +1,37 @@
+<template>
+  <my-dialog
+    :visible="visible"
+    :header="`客户类型`"
+    :width="1000"
+    :closeOnOverlayClick="false"
+    @close="emit('update:visible', false)"
+  >
+    <SearchForm :fields="fields" :params="params"> </SearchForm>
+  </my-dialog>
+</template>
+<script setup name="CustomTypeDrillDialog">
+import { ref, computed, reactive, watch } from 'vue';
+import { CUSTOMER_TYPE } from '@/config/constants';
+import { dictToOptionList } from '@/utils/tool';
+const props = defineProps({
+  visible: Boolean,
+  data: Object,
+});
+const emit = defineEmits(['close']);
+const fields = ref([
+  {
+    prop: 'type',
+    label: '客户类型',
+    type: 'select',
+    labelWidth: 70,
+    colSpan: 6,
+    options: dictToOptionList(CUSTOMER_TYPE),
+  },
+]);
+const params = reactive({
+  type: '',
+});
+watch(props.visible, () => {
+  params.type = '';
+});
+</script>

+ 8 - 0
src/views/report/dispatch-analysis/index.vue

@@ -97,6 +97,10 @@
         </div>
       </div>
     </div>
+    <CustomTypeDrillDialog
+      v-model:visible="showCustomTypeDrill"
+      :footer="false"
+    ></CustomTypeDrillDialog>
   </div>
 </template>
 
@@ -106,6 +110,7 @@ import ChinaPointChart from '@/components/common/china-point-chart/index.vue';
 import TableLoop from '@/components/common/table-loop/index.vue';
 import { CUSTOMER_TYPE } from '@/config/constants';
 import { useRequest } from 'vue-request';
+import CustomTypeDrillDialog from './custom-type-drill-dialog.vue';
 import {
   createBarOption,
   createRingPieOption,
@@ -118,6 +123,9 @@ import {
   supplierDispatchAnalysis,
   dispatchStatisticsAnalysis,
 } from '@/api/report';
+
+const showCustomTypeDrill = ref(true);
+
 const curTimeRange = ref([]);
 const timeParams = computed(() => {
   return {

+ 49 - 5
src/views/report/project-analysis/index.vue

@@ -41,7 +41,14 @@
           </div>
         </div>
         <div class="row2">
-          <div class="card"></div>
+          <div class="card">
+            <div class="title">
+              <span class="label">项目燃尽图</span>
+            </div>
+            <div class="chart-wrap">
+              <my-chart :options="options4"></my-chart>
+            </div>
+          </div>
         </div>
       </div>
     </div>
@@ -51,8 +58,16 @@
 <script setup name="ProjectAnalysis">
 import { ref, computed, onMounted, watch } from 'vue';
 import { useRequest } from 'vue-request';
-import { createCakePieOption, createPercentBarOption } from '@/utils/chart';
-import { serviceServiceList, projectStageAnalysis } from '@/api/report';
+import {
+  createCakePieOption,
+  createPercentBarOption,
+  createLineOption,
+} from '@/utils/chart';
+import {
+  serviceServiceList,
+  projectStageAnalysis,
+  projectProcessAnalysis,
+} from '@/api/report';
 const curTimeRange = ref([]);
 const timeParams = computed(() => {
   return {
@@ -85,10 +100,39 @@ const {
   loading: loading3,
   run: run3,
 } = useRequest(projectStageAnalysis);
+const {
+  data: result4,
+  loading: loading4,
+  run: run4,
+} = useRequest(projectProcessAnalysis);
+const options4 = computed(() => {
+  let actual = result4?.actual || [];
+  let plan = result4?.plan || [];
+  let xData = Array.from(
+    new Set([
+      ...actual.filter((item) => item.datetime),
+      ...plan.filter((item) => item.datetime),
+    ])
+  );
+  xData.sort();
+  let data1 = actual.map((item) => {
+    return xData.includes(item.datetime) ? item.count : 0;
+  });
+  let data2 = plan.map((item) => {
+    return xData.includes(item.datetime) ? item.count : 0;
+  });
+  let sData = [
+    { name: '实际', data: data1 },
+    { name: '计划', data: data2 },
+  ];
+  return createLineOption({ xData, sData });
+});
+
 watch(serviceId, (serviceId) => {
   run1({ serviceId, group: 'REGION' });
   run2({ serviceId, group: 'POPULATION' });
   run3({ serviceId, group: 'SUPPLIER' });
+  run4({ serviceId });
 });
 const options1 = computed(() => {
   let res = result1.value || {};
@@ -153,7 +197,7 @@ const options3 = computed(() => {
       min-height: 600px;
       min-width: 1000px;
       .row1 {
-        height: calc((100% - 16px) / 2);
+        height: calc(60% - 16px);
         .card {
           width: calc((100% - 30px) / 3);
           height: 100%;
@@ -164,7 +208,7 @@ const options3 = computed(() => {
       }
       .row2 {
         margin-top: 15px;
-        height: calc((100% - 16px) / 2);
+        height: 40%;
         .card {
           height: 100%;
         }