cfofpp 5 kuukautta sitten
vanhempi
commit
0e8f39e2b2

+ 276 - 42
src/views/home/components/TargetSituation/index.vue

@@ -1,22 +1,70 @@
 <template>
   <div class="w-full h-full">
-    <div class="c-title">目标完成情况</div>
+    <div class="c-title flex justify-between">
+      <span>目标完成情况</span>
+      <div>
+        <el-select
+          size="mini"
+          style="width: 70px; margin-right: 10px"
+          v-model="queryParams.type"
+          @change="dateTypeChange"
+          placeholder="请选择时间纬度"
+        >
+          <el-option label="年" value="reportYear"></el-option>
+          <el-option label="月" value="reportDate"></el-option>
+        </el-select>
+
+        <el-date-picker
+          style="width: 120px"
+          size="mini"
+          v-model="queryParams.reportYear"
+          type="year"
+          format="yyyy"
+          value-format="yyyy"
+          placeholder="选择年"
+          :clearable="false"
+          @change="getList"
+        >
+        </el-date-picker>
+        <el-select
+          size="mini"
+          style="width: 100px; margin-left: 10px"
+          v-model="zdlx"
+          @change="dateLxChange"
+          placeholder="请选择"
+        >
+          <el-option
+            v-for="(ite, i) in yearTypeList"
+            :key="i"
+            :label="ite.label"
+            :value="ite.key"
+          ></el-option>
+        </el-select>
+      </div>
+    </div>
     <div
+      v-if="queryParams.type == 'reportYear'"
       ref="barChart"
       id="barChart"
       :style="{ height: height, width: width }"
     ></div>
+    <div
+      v-else
+      ref="stopTargetLineRef"
+      id="stopTimeMonth"
+      :style="{ height: height, width: width }"
+    ></div>
   </div>
 </template>
 
 <script>
+import moment from "moment/moment";
 import * as echarts from "echarts";
+import TargetLine from "../monthLine.vue";
+import { stopActualList } from "@/api/powerdistribution/power-outage-control";
 export default {
+  components: { TargetLine },
   props: {
-    chartOptions: {
-      type: Object,
-      default: () => {},
-    },
     width: {
       type: String,
       default: "100%",
@@ -26,19 +74,73 @@ export default {
       default: "200px",
     },
   },
+  data() {
+    return {
+      // 查询参数
+      queryParams: {
+        type: "reportYear",
+        pageNum: 1,
+        pageSize: 10,
+        reportDate: null,
+        reportYear: moment(new Date()).format("yyyy"),
+      },
+      zdlx: 1,
+      dataList: [],
+      loading: false,
+      yearTypeList: [
+        {
+          label: "总目标",
+          key: 1,
+          value: { 0: "stopTimeTotal", 1: "stopTotalActual" },
+          value2: { 0: "stopTimeMonth", 1: "stopMonth" },
+        },
+        {
+          label: "计划停电目标",
+          key: 2,
+          value: { 0: "planStopTimeTotal", 1: "planStopTotalActual" },
+          value2: { 0: "planStopTimeMonth", 1: "planStopMonth" },
+        },
+        {
+          label: "故障停电目标",
+          key: 3,
+          value: { 0: "errorStopTimeTotal", 1: "errorStopTotalActual" },
+          value2: { 0: "errorStopTimeMonth", 1: "errorStopMonth" },
+        },
+      ],
+    };
+  },
   mounted() {
-    this.initEcharts();
+    this.getList();
   },
-  watch: {
-    chartOptions: {
-      handler(newVal, oldVal) {
+  methods: {
+    dateTypeChange(e) {
+      this.queryParams.type = e;
+      this.dataList = [];
+      this.getList();
+    },
+    dateLxChange(e) {
+      this.zdlx = e;
+      if (this.queryParams.type == "reportYear") {
         this.initEcharts();
-      },
-      // 这里的deep是深度监听,因为我们传递过来的是一个对象
-      deep: true,
+      } else {
+        this.initEcharts2();
+      }
+    },
+    /** 查询列表 */
+    getList() {
+      this.loading = true;
+      stopActualList(this.queryParams).then((response) => {
+        this.dataList = response.rows.filter(
+          (ite) => ite.companyName != "总计"
+        );
+        this.loading = false;
+        if (this.queryParams.type == "reportYear") {
+          this.initEcharts();
+        } else {
+          this.initEcharts2();
+        }
+      });
     },
-  },
-  methods: {
     initEcharts() {
       let myChart = echarts.getInstanceByDom(
         document.getElementById("barChart")
@@ -46,51 +148,183 @@ export default {
       if (myChart == null) {
         myChart = echarts.init(document.getElementById("barChart"));
       }
-
+      const zdlx = this.yearTypeList.find((ite) => ite.key == this.zdlx).value;
+      const yAxisData = this.dataList.map((ite) => ite.companyName);
+      const targetData = this.dataList.map((ite) => ite[zdlx[0]] || 0);
+      const actualData = this.dataList.map((ite) => ite[zdlx[1]] || 0);
       // 指定图表的配置项和数据
       var option = {
         tooltip: {
-          trigger: "item",
+          trigger: "axis",
+          axisPointer: {
+            type: "shadow",
+          },
+          formatter: function (params) {
+            // params 是一个数组,数组中包含每个系列的数据信息
+            let result = "";
+            params.forEach(function (item) {
+              // item 是每一个系列的数据
+              const seriesName = item.seriesName; // 系列名称
+              const value = item.value; // 数据值
+              const marker = item.marker; // 标志图形
+              result += `${marker}${seriesName}: ${value}<br/>`;
+            });
+            const zxl = Number(params[1].value) / Number(params[0].value);
+            result += `${params[0].marker}执行率: ${zxl.toFixed(2) * 100}%`;
+            return result;
+          },
+        },
+        textStyle: {
+          color: "#fff",
+        },
+        legend: {
+          textStyle: {
+            color: "#fff",
+          },
+        },
+        grid: {
+          left: "2%", //图表距离容器左侧多少距离
+          right: "2%", //图表距离容器右侧侧多少距离
+          bottom: "5%", //图表距离容器上面多少距离
+          top: "8%", //图表距离容器下面多少距离
+          containLabel: true,
         },
         xAxis: {
-          // type: "category",
           type: "value",
-          data: this.chartOptions.xData,
-          axisLine: {
-            lineStyle: {
-              color: "#fff", // 设置 y 轴线的颜色为红色
-            },
-          },
+          boundaryGap: [0, 0.01],
         },
         yAxis: {
-          // type: "value",
           type: "category",
-          data: [
-            "作业机构1",
-            "作业机构2",
-            "作业机构3",
-            "作业机构4",
-            "作业机构5",
-          ],
-          axisLine: {
-            lineStyle: {
-              color: "#fff", // 设置 y 轴线的颜色为红色
-            },
-          },
+          data: yAxisData,
         },
         series: [
           {
-            data: this.chartOptions.data,
+            name: "目标值",
             type: "bar",
-            // showBackground: true,
-            backgroundStyle: {
-              color: "rgba(180, 180, 180, 0.2)",
-            },
+            data: targetData,
+          },
+          {
+            name: "实际值",
+            type: "bar",
+            data: actualData,
           },
         ],
       };
       // 使用刚指定的配置项和数据显示图表。
-      myChart.setOption(option);
+      myChart.clear();
+      myChart.setOption(option, true);
+      window.addEventListener("resize", () => {
+        myChart.resize();
+      });
+    },
+    initEcharts2() {
+      let legend = [];
+      let series = [];
+      const zdlx = this.yearTypeList.find((ite) => ite.key == this.zdlx).value2;
+      this.dataList.forEach((e, i) => {
+        legend.push(e.companyName);
+        series.push(
+          {
+            name: `${e.companyName}目标值`,
+            type: "line",
+            stack: "Total",
+            data: Array(12)
+              .fill(0)
+              .map((ite, i) => {
+                return (
+                  e[`${zdlx[0]}${i + 1 < 10 ? "0" + (i + 1) : i + 1}`] || 0
+                );
+              }),
+          },
+          {
+            name: `${e.companyName}实际值`,
+            type: "line",
+            stack: "Total",
+            data: Array(12)
+              .fill(0)
+              .map((ite, i) => {
+                return (
+                  e[`${zdlx[1]}${i + 1 < 10 ? "0" + (i + 1) : i + 1}Actual`] ||
+                  0
+                );
+              }),
+          }
+        );
+      });
+      let myChart = echarts.getInstanceByDom(
+        document.getElementById("stopTimeMonth")
+      );
+      if (myChart == null) {
+        myChart = echarts.init(document.getElementById("stopTimeMonth"));
+      }
+      // 指定图表的配置项和数据
+      var option = {
+        tooltip: {
+          trigger: "axis",
+          formatter: function (params) {
+            // params 是一个数组,数组中包含每个系列的数据信息
+            let result = "";
+            params.forEach(function (item, i) {
+              // item 是每一个系列的数据
+              const seriesName = item.seriesName; // 系列名称
+              const value = item.value; // 数据值
+              const marker = item.marker; // 标志图形
+              result += `${marker}${seriesName}: ${value}<br/>`;
+              if (i % 2 == 0) {
+                const zxl = Number(params[1].value) / Number(params[0].value);
+                result += `${params[0].marker}执行率: ${
+                  zxl.toFixed(2) * 100
+                }%<br/>`;
+              }
+            });
+
+            return result;
+          },
+          // width: 320, // 设置tooltip宽度
+          // position: function (point) {
+          //   // 自定义提示框位置
+          //   return {
+          //     left: point[0] + 0,
+          //     top: point[1] - 10,
+          //   };
+          // },
+        },
+        textStyle: {
+          color: "#fff",
+        },
+
+        legend: {
+          data: legend,
+          type: "scroll",
+          top: "8%",
+          textStyle: {
+            color: "#fff",
+          },
+        },
+        grid: {
+          left: "1%",
+          right: "3%",
+          bottom: "2%",
+          containLabel: true,
+        },
+        xAxis: {
+          type: "category",
+          boundaryGap: false,
+          data: Array(12)
+            .fill(0)
+            .map((it, i) => `${i + 1}月`),
+        },
+        yAxis: {
+          type: "value",
+        },
+        series: series,
+      };
+      // 使用刚指定的配置项和数据显示图表。
+      myChart.clear();
+      myChart.setOption(option, true);
+      setTimeout(() => {
+        myChart.resize();
+      }, 100);
       window.addEventListener("resize", () => {
         myChart.resize();
       });

+ 118 - 0
src/views/home/components/monthLine.vue

@@ -0,0 +1,118 @@
+<template>
+  <div ref="barChart" :id="id" :style="{ height: height, width: width }"></div>
+</template>
+
+<script>
+import * as echarts from "echarts";
+export default {
+  props: {
+    chartOptions: {
+      type: Object,
+      default: () => {},
+    },
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "200px",
+    },
+    id: {
+      type: String,
+      default: "barChart",
+    },
+  },
+  mounted() {
+    // this.initEcharts();
+  },
+  watch: {
+    chartOptions: {
+      handler(newVal, oldVal) {
+        this.initEcharts();
+      },
+      // 这里的deep是深度监听,因为我们传递过来的是一个对象
+      deep: true,
+    },
+  },
+  methods: {
+    initEcharts(data, title) {
+      let legend = [];
+      let series = [];
+      (data || []).forEach((e, i) => {
+        legend.push(e.companyName);
+        series.push(
+          {
+            name: `${e.companyName}目标值`,
+            type: "line",
+            stack: "Total",
+            data: Array(12)
+              .fill(0)
+              .map((it, ii) => {
+                return e[`${this.id}${ii < 10 ? "0" + (ii + 1) : ii + 1}`] || 0;
+              }),
+          },
+          {
+            name: `${e.companyName}实际值`,
+            type: "line",
+            stack: "Total",
+            data: Array(12)
+              .fill(0)
+              .map((it, ii) => {
+                return e[`${this.id}${ii < 10 ? "0" + (ii + 1) : ii + 1}`] || 0;
+              }),
+          }
+        );
+      });
+      let myChart = echarts.getInstanceByDom(document.getElementById(this.id));
+      if (myChart == null) {
+        myChart = echarts.init(document.getElementById(this.id));
+      }
+      // 指定图表的配置项和数据
+      var option = {
+        tooltip: {
+          trigger: "axis",
+        },
+        textStyle: {
+          color: "#fff",
+        },
+        legend: {
+          data: legend,
+          type: "scroll",
+          top: "8%",
+          textStyle: {
+            color: "#fff",
+          },
+        },
+        grid: {
+          left: "1%",
+          right: "3%",
+          bottom: "0%",
+          containLabel: true,
+        },
+        xAxis: {
+          type: "category",
+          boundaryGap: false,
+          data: Array(12)
+            .fill(0)
+            .map((it, i) => `${i + 1}月`),
+        },
+        yAxis: {
+          type: "value",
+        },
+        series: series,
+      };
+      // 使用刚指定的配置项和数据显示图表。
+      myChart.setOption(option, true);
+      setTimeout(() => {
+        myChart.resize();
+      }, 100);
+      window.addEventListener("resize", () => {
+        myChart.resize();
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 1 - 11
src/views/home/index.vue

@@ -29,17 +29,7 @@
           </div>
         </el-card>
         <el-card class="h-60 mt-10">
-          <TargetSituation
-            v-if="chartOptions2.data && chartOptions2.data.length > 0"
-            :chartOptions="chartOptions2"
-            height="100%"
-          ></TargetSituation>
-          <div
-            style="text-align: center; color: #fff; line-height: 400px"
-            v-else
-          >
-            暂无数据
-          </div>
+          <TargetSituation height="100%"></TargetSituation>
         </el-card>
       </el-col>
     </el-row>