|
@@ -0,0 +1,359 @@
|
|
|
|
+<script setup name="loseAnalysis">
|
|
|
|
+import searchCop from "./components/search.vue";
|
|
|
|
+import tableCop from "./components/table.vue";
|
|
|
|
+import excelCop from "@/components/excel.vue";
|
|
|
|
+import treeCop from "@/components/tree.vue";
|
|
|
|
+import {
|
|
|
|
+ getWindLosePower,
|
|
|
|
+ getPrepareTree,
|
|
|
|
+} from "@/api/powerGenerating/index.js";
|
|
|
|
+import barLineChartCop from "./components/barLineChart.vue";
|
|
|
|
+import { ElMessage } from "element-plus";
|
|
|
|
+import { onMounted, ref, onActivated } from "vue";
|
|
|
|
+
|
|
|
|
+/**table 开始 */
|
|
|
|
+const tableShowId = ref("");
|
|
|
|
+const tableName = ref("损失电量分析");
|
|
|
|
+const tableColumn = ref([]);
|
|
|
|
+const tableLoading = ref(false);
|
|
|
|
+const tableData = ref([]);
|
|
|
|
+const funSummary = ({ columns, data }) => {
|
|
|
|
+ const sums = [];
|
|
|
|
+ columns.forEach((column, index) => {
|
|
|
|
+ if (index === 0) {
|
|
|
|
+ sums[index] = "合计";
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ const values = data.map((item) => Number(item[column.property]));
|
|
|
|
+ if (!values.every((value) => Number.isNaN(value))) {
|
|
|
|
+ sums[index] = values.reduce((prev, curr) => {
|
|
|
|
+ const value = Number(curr);
|
|
|
|
+ if (!Number.isNaN(value)) {
|
|
|
|
+ return Number((prev + curr).toFixed(2));
|
|
|
|
+ } else {
|
|
|
|
+ return Number(prev.toFixed(2));
|
|
|
|
+ }
|
|
|
|
+ }, 0);
|
|
|
|
+ } else {
|
|
|
|
+ sums[index] = "--";
|
|
|
|
+ }
|
|
|
|
+ if (["speed", "fnlly"].includes(column.property)) {
|
|
|
|
+ if (!Number.isNaN(sums[index])) {
|
|
|
|
+ sums[index] = Number((sums[index] / data.length).toFixed(2));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ return sums;
|
|
|
|
+};
|
|
|
|
+const funSubmit = async () => {
|
|
|
|
+ if (!excelCheckIds.value.length) {
|
|
|
|
+ ElMessage.error("请勾选要展现的项");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ tableLoading.value = true;
|
|
|
|
+ tableData.value = [];
|
|
|
|
+ tableShowId.value = "";
|
|
|
|
+ barData.value = {
|
|
|
|
+ area: [],
|
|
|
|
+ legend: [],
|
|
|
|
+ data: [],
|
|
|
|
+ };
|
|
|
|
+ lineData.value = [];
|
|
|
|
+ const res = await getWindLosePower({
|
|
|
|
+ ids: excelCheckIds.value.join(),
|
|
|
|
+ });
|
|
|
|
+ if (res.code !== 200 || !res.data.title) {
|
|
|
|
+ tableLoading.value = false;
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ ElMessage.success(res.msg);
|
|
|
|
+ tableColumn.value = res.data.title.map((o) => {
|
|
|
|
+ return {
|
|
|
|
+ prop: o.key,
|
|
|
|
+ label: o.des,
|
|
|
|
+ width: o.des === "时间" ? 100 : 80,
|
|
|
|
+ };
|
|
|
|
+ });
|
|
|
|
+ tableData.value = res.data.data;
|
|
|
|
+
|
|
|
|
+ const name = [],
|
|
|
|
+ data = [],
|
|
|
|
+ llfdl = [],
|
|
|
|
+ legend = [
|
|
|
|
+ "实际电量",
|
|
|
|
+ "计划检修损失",
|
|
|
|
+ "非计划检修损失",
|
|
|
|
+ "限电损失",
|
|
|
|
+ "受累损失",
|
|
|
|
+ "性能损失",
|
|
|
|
+ ],
|
|
|
|
+ data2 = []; //项目列表
|
|
|
|
+ // if (params.station) {
|
|
|
|
+ // let arr = [];
|
|
|
|
+ // let hj = res.data.data.pop();
|
|
|
|
+ // res.data.data.forEach((ele, index) => {
|
|
|
|
+ // arr[ele.id.split('_')[1] - 1] = ele
|
|
|
|
+ // })
|
|
|
|
+ // arr.push(hj);
|
|
|
|
+ // res.data.data = arr;
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ res.data.data.forEach((item, index) => {
|
|
|
|
+ name.push(item.name);
|
|
|
|
+ data.push([item.sjfdl, item.jhjx, item.fjhjx, item.xd, item.sl, item.xn]);
|
|
|
|
+ llfdl.push(item.llfdl);
|
|
|
|
+ data2.push({
|
|
|
|
+ index: index + 1,
|
|
|
|
+ name: item.name,
|
|
|
|
+ llfdl: item.llfdl,
|
|
|
|
+ sjfdl: item.sjfdl,
|
|
|
|
+ speed: item.speed,
|
|
|
|
+ fjhjx: item.fjhjx,
|
|
|
|
+ jhjx: item.jhjx,
|
|
|
|
+ sl: item.sl,
|
|
|
|
+ xd: item.xd,
|
|
|
|
+ xn: item.xn,
|
|
|
|
+ fnlly: item.fnlly,
|
|
|
|
+ is_light: false,
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ if (data.length > 0) {
|
|
|
|
+ let arr1 = [];
|
|
|
|
+ const length = data[0].length;
|
|
|
|
+ for (var i = 0; i < length; i++) {
|
|
|
|
+ let arr2 = [];
|
|
|
|
+ data.forEach((ele) => {
|
|
|
|
+ arr2.push(ele[i]);
|
|
|
|
+ });
|
|
|
|
+ arr1.push(arr2);
|
|
|
|
+ }
|
|
|
|
+ lineData.value = llfdl;
|
|
|
|
+ barData.value = {
|
|
|
|
+ area: name,
|
|
|
|
+ legend: legend,
|
|
|
|
+ data: arr1,
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ tableLoading.value = false;
|
|
|
|
+ tableShowId.value = "1";
|
|
|
|
+ activeTab.value = "2";
|
|
|
|
+};
|
|
|
|
+/**barlineChart 开始 */
|
|
|
|
+const barData = ref({
|
|
|
|
+ area: [],
|
|
|
|
+ legend: [],
|
|
|
|
+ data: [],
|
|
|
|
+});
|
|
|
|
+const lineData = ref([]);
|
|
|
|
+const barColor = [
|
|
|
|
+ "#4b55ae",
|
|
|
|
+ "#e17e23",
|
|
|
|
+ "#ba3237",
|
|
|
|
+ "#c531c7",
|
|
|
|
+ "rgb(63,177,227)",
|
|
|
|
+ "#05bb4c",
|
|
|
|
+];
|
|
|
|
+
|
|
|
|
+/**tabs */
|
|
|
|
+const activeTab = ref("1");
|
|
|
|
+/**excel 开始 */
|
|
|
|
+const excelCheckboxShow = ref(false);
|
|
|
|
+const excelType = ref("");
|
|
|
|
+const treeCopRef = ref(); //treeCop ref
|
|
|
|
+const excelCheckIds = ref([]);
|
|
|
|
+const excelList = ref([]);
|
|
|
|
+const funExcelChange = async (obj) => {
|
|
|
|
+ //点击excel项时
|
|
|
|
+ return false;
|
|
|
|
+};
|
|
|
|
+const funExcelCheckChange = ({ checkArr, data }) => {
|
|
|
|
+ //bug
|
|
|
|
+ excelCheckIds.value = checkArr;
|
|
|
|
+ funSubmit();
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/**prepare tree 开始 */
|
|
|
|
+const treeData = ref([]);
|
|
|
|
+const actTreeNode = ref(null); //当前激活的treeNode
|
|
|
|
+const funRepeatMap = (arr) => {
|
|
|
|
+ return arr.map((o) => {
|
|
|
|
+ if (o.children) {
|
|
|
|
+ const findIndex = o.children.findIndex((p) => !!p.type);
|
|
|
|
+ if (findIndex !== -1) {
|
|
|
|
+ o.childs = o.children;
|
|
|
|
+ o.children = [];
|
|
|
|
+ if (!actTreeNode.value) {
|
|
|
|
+ //判断当且仅有process获取tree时 赋值
|
|
|
|
+ actTreeNode.value = o;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return {
|
|
|
|
+ ...o,
|
|
|
|
+ children: o.children ? funRepeatMap(o.children) : [],
|
|
|
|
+ };
|
|
|
|
+ });
|
|
|
|
+};
|
|
|
|
+const funGetTree = async () => {
|
|
|
|
+ actTreeNode.value = null;
|
|
|
|
+ const res = await getPrepareTree();
|
|
|
|
+ treeData.value = funRepeatMap(res.data);
|
|
|
|
+ excelList.value = [];
|
|
|
|
+ if (actTreeNode.value) {
|
|
|
|
+ funCurrentChange({ current: actTreeNode.value, currentNode: null });
|
|
|
|
+ if (treeCopRef.value) {
|
|
|
|
+ treeCopRef.value.setCheckedKeys([actTreeNode.value.id]);
|
|
|
|
+ excelCheckIds.value = actTreeNode.value.childs.map((o) => o.id);
|
|
|
|
+ funSubmit();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+const funCurrentChange = ({ current, currentNode }) => {
|
|
|
|
+ excelCheckboxShow.value = true;
|
|
|
|
+ if (current.childs) {
|
|
|
|
+ excelList.value = current.childs.map((o) => {
|
|
|
|
+ return {
|
|
|
|
+ id: o.id,
|
|
|
|
+ interval: o.interval,
|
|
|
|
+ path: o.path,
|
|
|
|
+ prepareid: o.prepareid,
|
|
|
|
+ station: o.station,
|
|
|
|
+ time: o.time,
|
|
|
|
+ type: o.type,
|
|
|
|
+ windturbine: o.windturbine,
|
|
|
|
+ name: o.path.substring(
|
|
|
|
+ o.path.indexOf(o.station + "_") + (o.station + "_").length
|
|
|
|
+ ),
|
|
|
|
+ };
|
|
|
|
+ });
|
|
|
|
+ } else {
|
|
|
|
+ excelList.value = [];
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+const funTreeCheckChange = ({
|
|
|
|
+ current,
|
|
|
|
+ checkedNodes,
|
|
|
|
+ checkedKeys,
|
|
|
|
+ halfCheckedNodes,
|
|
|
|
+ halfCheckedKeys,
|
|
|
|
+}) => {
|
|
|
|
+ //tree change -> excel change
|
|
|
|
+ funCurrentChange({ current, currentNode: "" });
|
|
|
|
+ const checkIds = [];
|
|
|
|
+ if (checkedNodes.length) {
|
|
|
|
+ for (const node of checkedNodes) {
|
|
|
|
+ if (node.childs && node.childs.length) {
|
|
|
|
+ for (const child of node.childs) {
|
|
|
|
+ checkIds.push(child.id);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ excelCheckIds.value = checkIds;
|
|
|
|
+ funSubmit();
|
|
|
|
+};
|
|
|
|
+/**created */
|
|
|
|
+funGetTree();
|
|
|
|
+/**activated */
|
|
|
|
+onActivated(() => {
|
|
|
|
+ funGetTree();
|
|
|
|
+});
|
|
|
|
+</script>
|
|
|
|
+<template>
|
|
|
|
+ <div class="container-wrapper">
|
|
|
|
+ <div class="power-data-wrapper card-shadow wrapper">
|
|
|
|
+ <div class="card-title">数据展示</div>
|
|
|
|
+ <div class="data-wrapper">
|
|
|
|
+ <tree-cop
|
|
|
|
+ ref="treeCopRef"
|
|
|
|
+ :data="treeData"
|
|
|
|
+ @checkChange="funTreeCheckChange"
|
|
|
|
+ :show-checkbox="true"
|
|
|
|
+ @currentChange="funCurrentChange"
|
|
|
|
+ @refresh="funGetTree"
|
|
|
|
+ />
|
|
|
|
+ <excel-cop
|
|
|
|
+ :checkIds="excelCheckIds"
|
|
|
|
+ :showCheckbox="excelCheckboxShow"
|
|
|
|
+ :data="excelList"
|
|
|
|
+ @excelChange="funExcelChange"
|
|
|
|
+ @checkChange="funExcelCheckChange"
|
|
|
|
+ />
|
|
|
|
+ <div class="data-table-wrapper card-shadow">
|
|
|
|
+ <el-tabs v-model="activeTab">
|
|
|
|
+ <el-tab-pane label="表格数据" name="1"> </el-tab-pane>
|
|
|
|
+ <el-tab-pane label="图表展示" name="2"> </el-tab-pane>
|
|
|
|
+ <table-cop
|
|
|
|
+ v-show="activeTab === '1'"
|
|
|
|
+ :data="tableData"
|
|
|
|
+ :showShadow="false"
|
|
|
|
+ :showSummary="true"
|
|
|
|
+ :summaryMethod="funSummary"
|
|
|
|
+ :column="tableColumn"
|
|
|
|
+ :loading="tableLoading"
|
|
|
|
+ :tableId="tableShowId"
|
|
|
|
+ :tableName="tableName"
|
|
|
|
+ />
|
|
|
|
+ <div v-show="activeTab === '2'" class="data-chart-wrapper">
|
|
|
|
+ <bar-line-chart-cop
|
|
|
|
+ v-show="lineData.length"
|
|
|
|
+ width="100%"
|
|
|
|
+ height="100%"
|
|
|
|
+ :bardata="barData"
|
|
|
|
+ :lineData="lineData"
|
|
|
|
+ :color="barColor"
|
|
|
|
+ lineName="理论发电量"
|
|
|
|
+ ></bar-line-chart-cop>
|
|
|
|
+ <el-empty
|
|
|
|
+ v-show="!lineData.length"
|
|
|
|
+ description="请选择条件"
|
|
|
|
+ ></el-empty>
|
|
|
|
+ </div>
|
|
|
|
+ </el-tabs>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+<style lang="less" scoped>
|
|
|
|
+.power-data-wrapper {
|
|
|
|
+ height: 100%;
|
|
|
|
+ margin-top: 0;
|
|
|
|
+}
|
|
|
|
+.data-table-wrapper {
|
|
|
|
+ width: calc(62% - 40px) !important;
|
|
|
|
+}
|
|
|
|
+.el-tabs ::v-deep {
|
|
|
|
+ height: 100%;
|
|
|
|
+ .el-tabs__item {
|
|
|
|
+ color: #b3b3b3;
|
|
|
|
+ padding: 0 20px;
|
|
|
|
+ }
|
|
|
|
+ .el-tabs__nav-wrap::after {
|
|
|
|
+ background-color: #14221f;
|
|
|
|
+ }
|
|
|
|
+ .el-tabs__active-bar {
|
|
|
|
+ background-color: #05bb4c;
|
|
|
|
+ }
|
|
|
|
+ .el-tabs__item.is-top:last-child {
|
|
|
|
+ padding: 0;
|
|
|
|
+ padding-left: 5px;
|
|
|
|
+ }
|
|
|
|
+ .el-tabs__item.is-active,
|
|
|
|
+ .el-tabs__item:hover {
|
|
|
|
+ color: #05bb4c;
|
|
|
|
+ }
|
|
|
|
+ .el-tabs__content {
|
|
|
|
+ height: calc(100% - 45px);
|
|
|
|
+ .table-wrapper {
|
|
|
|
+ width: 100%;
|
|
|
|
+ }
|
|
|
|
+ .data-chart-wrapper {
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</style>
|