代码提交
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
<!-- 谐波放大表格详情 -->
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:close-on-click-modal="false"
|
||||
title="详情"
|
||||
draggable
|
||||
width="1000px"
|
||||
@close="handleCloseDialog"
|
||||
style="height: 600px"
|
||||
>
|
||||
<MyEChart :options="[]" />
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from "vue";
|
||||
import MyEChart from "@/components/echarts/MyEchart.vue";
|
||||
|
||||
const visible = ref(false);
|
||||
const options = ref<any>(null);
|
||||
|
||||
const open = () => {
|
||||
visible.value = true;
|
||||
}
|
||||
|
||||
const handleCloseDialog = () => {
|
||||
visible.value = false;
|
||||
options.value = null;
|
||||
};
|
||||
|
||||
// const showCharts = (row: any, valueType: number, name: string) => {
|
||||
// getHistoryLineData({
|
||||
// lineId: row.lineId,
|
||||
// number: row.number,
|
||||
// phaseType: row.phaseType,
|
||||
// searchTime: row.timeId,
|
||||
// targetCode: row.targetCode,
|
||||
// valueType,
|
||||
// }).then((res) => {
|
||||
// options.value = {
|
||||
// title: {
|
||||
// text:
|
||||
// row.subName +
|
||||
// " " +
|
||||
// row.lineName +
|
||||
// " " +
|
||||
// row.targetName +
|
||||
// " " +
|
||||
// row.phaseType +
|
||||
// "相" +
|
||||
// name,
|
||||
// },
|
||||
// legend: {
|
||||
// show: false,
|
||||
// },
|
||||
// xAxis: {
|
||||
// type: "category",
|
||||
// name: "时间",
|
||||
// data: res.data[0]?.value.map((item: any[]) => item[0]),
|
||||
// },
|
||||
// yAxis: {
|
||||
// name: "%",
|
||||
// type: "value",
|
||||
// },
|
||||
// series: [
|
||||
// {
|
||||
// name: name,
|
||||
// data: res.data[0]?.value.map((item: any[]) => item[1]),
|
||||
// type: "line",
|
||||
// },
|
||||
// ],
|
||||
// options: {
|
||||
// grid: {
|
||||
// top: "50px",
|
||||
// left: "40px",
|
||||
// right: "60px",
|
||||
// bottom: "10px",
|
||||
// containLabel: true,
|
||||
// },
|
||||
// dataZoom: null,
|
||||
// },
|
||||
// };
|
||||
// });
|
||||
// };
|
||||
defineExpose({
|
||||
open,
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
title="责任度计算"
|
||||
draggable
|
||||
width="1700px"
|
||||
style="height: 875px"
|
||||
@close="handleClose"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div class="currentPosition">
|
||||
当前位置:{{ alias || "" }}
|
||||
</div>
|
||||
<el-tabs v-model="activeName" class="demo-tabs">
|
||||
<el-tab-pane label="系统" name="1">
|
||||
<system @setTitle="setTitle" v-if="activeName == '1'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="配网" name="2">
|
||||
<distributionNetwork @setTitle="setTitle" v-if="activeName == '2'" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, reactive } from "vue";
|
||||
import distributionNetwork from "./distributionNetwork.vue";
|
||||
import system from "./system.vue";
|
||||
|
||||
const visible = ref(false);
|
||||
const alias = ref("");
|
||||
|
||||
const activeName = ref("1");
|
||||
|
||||
const openDialog = () => {
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
onMounted(() => {});
|
||||
const setTitle = (title: string) => {
|
||||
alias.value = title;
|
||||
};
|
||||
const emit = defineEmits(["showCalculation", "close-dialog"]); // 打开弹窗
|
||||
|
||||
const handleClose = () => {
|
||||
visible.value = false;
|
||||
// 通知父组件显示收集界面
|
||||
emit("showCalculation", false);
|
||||
emit("close-dialog"); // 关闭弹窗
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@/assets/scss/index.scss";
|
||||
|
||||
.currentPosition {
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
right: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
z-index: 10;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,337 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:close-on-click-modal="false"
|
||||
title="用采数据管理"
|
||||
draggable
|
||||
>
|
||||
<el-form label-width="auto" :model="form" inline class="formBox">
|
||||
<el-form-item label="关键字">
|
||||
<el-input
|
||||
v-model="form.searchValue"
|
||||
placeholder="关键字查询"
|
||||
clearable
|
||||
style="width: 180px"
|
||||
size="small"
|
||||
/>
|
||||
</el-form-item>
|
||||
<div class="mt5">
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Search"
|
||||
size="small"
|
||||
@click="getTableData"
|
||||
>查询</el-button
|
||||
>
|
||||
<el-button type="primary" :icon="Plus" size="small" @click="uploadFile"
|
||||
>新增</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Download"
|
||||
@click="exportTable"
|
||||
size="small"
|
||||
>导出
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
<div class="tableBox">
|
||||
<el-table
|
||||
:scrollbar-always-on="true"
|
||||
:data="tableData"
|
||||
height="400px"
|
||||
size="small"
|
||||
:header-cell-style="{ textAlign: 'center' }"
|
||||
v-loading="loading1"
|
||||
element-loading-background="#343849c7"
|
||||
border
|
||||
>
|
||||
<el-table-column prop="name" align="center" label="表名" />
|
||||
<el-table-column
|
||||
prop="startTime"
|
||||
align="center"
|
||||
label="起始时间"
|
||||
width="150"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="endTime"
|
||||
align="center"
|
||||
label="截止时间"
|
||||
width="150"
|
||||
/>
|
||||
<el-table-column prop="updateTime" align="center" label="更新时间" />
|
||||
<el-table-column fixed="right" align="center" label="操作" width="140">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
size="small"
|
||||
v-if="row.integrity == 1"
|
||||
@click="handleClick(row)"
|
||||
>完整性详情</el-button
|
||||
>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
size="small"
|
||||
@click.stop="handleDelete(row)"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-pagination
|
||||
size="small"
|
||||
style="margin-top: 10px"
|
||||
:currentPage="form.pageNum"
|
||||
:page-size="form.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100, 200]"
|
||||
background
|
||||
:layout="'sizes,total, ->, prev, pager, next, jumper'"
|
||||
:total="total"
|
||||
@size-change="onTableSizeChange"
|
||||
@current-change="onTableCurrentChange"
|
||||
></el-pagination>
|
||||
</el-dialog>
|
||||
<!-- 详情 -->
|
||||
<completenessDetails ref="completenessDetailsRef" @close="close" />
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
draggable
|
||||
title="上传数据"
|
||||
width="500"
|
||||
:close-on-click-modal="false"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<el-upload
|
||||
ref="upload"
|
||||
action=""
|
||||
v-model:file-list="fileList"
|
||||
accept=".xlsx,.xls"
|
||||
:auto-upload="false"
|
||||
:on-change="choose"
|
||||
:limit="2"
|
||||
>
|
||||
<el-button type="primary" :icon="Upload" size="small">上传文件</el-button>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<el-button @click="handleClose" size="small">取消</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="submitupload"
|
||||
:loading="loading"
|
||||
size="small"
|
||||
>确认</el-button
|
||||
>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, reactive } from "vue";
|
||||
import completenessDetails from "./completenessDetails.vue";
|
||||
import type { UploadInstance } from "element-plus";
|
||||
import { Search, Plus, Upload, Download } from "@element-plus/icons-vue";
|
||||
import { useStore } from "vuex";
|
||||
import * as XLSX from "xlsx";
|
||||
|
||||
import {
|
||||
userDataList,
|
||||
uploadUserData,
|
||||
deleteUserDataByIds,
|
||||
} from "@/api/manage_wx";
|
||||
const store = useStore();
|
||||
const visible = ref(false);
|
||||
const openDialog = () => {
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
const form = reactive({
|
||||
searchValue: "",
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
});
|
||||
const total = ref(0); // 假设总条数为100
|
||||
const tableData = ref([]);
|
||||
|
||||
const completenessDetailsRef = ref();
|
||||
const dialogVisible = ref(false);
|
||||
const upload = ref<UploadInstance>();
|
||||
const fileList = ref([]);
|
||||
const loading = ref(false);
|
||||
const loading1 = ref(false);
|
||||
|
||||
// 关闭上传弹框
|
||||
const handleClose = () => {
|
||||
fileList.value = [];
|
||||
dialogVisible.value = false;
|
||||
visible.value = true;
|
||||
getTableData();
|
||||
};
|
||||
// 详情关闭弹框
|
||||
const close = () => {
|
||||
visible.value = true;
|
||||
};
|
||||
// 新增
|
||||
const uploadFile = () => {
|
||||
dialogVisible.value = true;
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
// 上传
|
||||
const choose = (e: any) => {
|
||||
upload.value!.clearFiles();
|
||||
setTimeout(() => {
|
||||
if (e.name.includes(".xls")) {
|
||||
fileList.value = [e];
|
||||
} else {
|
||||
ElMessage.warning("请上传Excel文件!");
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
// 上传
|
||||
const submitupload = async () => {
|
||||
if (fileList.value.length == 0) {
|
||||
ElMessage.warning("请上传文件!");
|
||||
return;
|
||||
}
|
||||
ElMessage.info("上传中,请稍等...");
|
||||
const formData = new FormData();
|
||||
formData.append("file", fileList.value[0].raw);
|
||||
loading.value = true;
|
||||
uploadUserData(formData)
|
||||
.then((res) => {
|
||||
ElMessage.success("上传成功");
|
||||
loading.value = false;
|
||||
handleClose();
|
||||
// tableStore.index();
|
||||
})
|
||||
.catch((err) => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
// provide("tableStore", tableStore);
|
||||
// tableStore.table.params.searchValue = "";
|
||||
|
||||
const onTableSizeChange = (size: number) => {
|
||||
form.pageSize = size;
|
||||
// 重新加载数据
|
||||
getTableData();
|
||||
};
|
||||
const onTableCurrentChange = (page: number) => {
|
||||
form.pageNum = page;
|
||||
// 重新加载数据
|
||||
getTableData();
|
||||
};
|
||||
|
||||
const getTableData = async () => {
|
||||
loading1.value = true;
|
||||
// form.deptId = store.state.deptId;
|
||||
const res: any = await userDataList(form);
|
||||
|
||||
if (res.code == "A0000") {
|
||||
tableData.value = res.data.records;
|
||||
|
||||
total.value = res.data.total;
|
||||
}
|
||||
loading1.value = false;
|
||||
};
|
||||
|
||||
// 完整性详情
|
||||
const handleClick = (row) => {
|
||||
visible.value = false;
|
||||
completenessDetailsRef.value.open(row);
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDelete = (row) => {
|
||||
ElMessageBox.confirm("确定删除?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(() => {
|
||||
deleteUserDataByIds([row.id]).then(() => {
|
||||
ElMessage.success("删除成功");
|
||||
getTableData();
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "info",
|
||||
message: "删除取消",
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 导出
|
||||
const exportTable = async () => {
|
||||
let columnExpor: any = [
|
||||
[
|
||||
"表名",
|
||||
"起始时间",
|
||||
"截止时间",
|
||||
"更新时间",
|
||||
],
|
||||
];
|
||||
|
||||
let list = [];
|
||||
|
||||
await userDataList({
|
||||
...form,
|
||||
pageNum: 1,
|
||||
pageSize: total.value,
|
||||
}).then((res) => {
|
||||
let data = res.data.records.map((item) => {
|
||||
return [
|
||||
item.name,
|
||||
item.startTime,
|
||||
item.endTime,
|
||||
item.updateTime,
|
||||
];
|
||||
});
|
||||
list = [...columnExpor, ...data];
|
||||
// 创建工作表
|
||||
const worksheet = XLSX.utils.aoa_to_sheet(list);
|
||||
|
||||
worksheet["!cols"] = list.map((col) => ({ wch: 20 }));
|
||||
|
||||
// 创建工作簿
|
||||
const workbook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, "用采数据管理");
|
||||
|
||||
// 写出文件
|
||||
XLSX.writeFile(workbook, "用采数据管理" + ".xlsx");
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getTableData();
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use "@/assets/scss/index.scss";
|
||||
.tableBox {
|
||||
padding: 0px !important;
|
||||
}
|
||||
.formBox {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
:deep(.el-upload-list__item-name) {
|
||||
color: #fff;
|
||||
}
|
||||
:deep(.el-upload-list__item:hover) {
|
||||
.el-upload-list__item-name {
|
||||
color: #909399;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<!--暂降 -->
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
draggable
|
||||
v-model="machineVisible"
|
||||
title="完整性不足详情"
|
||||
:before-close="handleClose"
|
||||
width="1000px"
|
||||
>
|
||||
<div class="formBox">
|
||||
<el-form label-width="70px" :model="form" inline>
|
||||
<el-form-item label="关键字">
|
||||
<el-input
|
||||
style="width: 150px"
|
||||
v-model="form.searchValue"
|
||||
placeholder="关键字查询"
|
||||
clearable
|
||||
size="small"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Search"
|
||||
size="small"
|
||||
@click="getTableData"
|
||||
>查询</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Download"
|
||||
@click="exportTable"
|
||||
size="small"
|
||||
>导出
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tableBox">
|
||||
<el-table
|
||||
:scrollbar-always-on="true"
|
||||
:data="tableData"
|
||||
height="400px"
|
||||
size="small"
|
||||
:header-cell-style="{ textAlign: 'center' }"
|
||||
v-loading="loading"
|
||||
element-loading-background="#343849c7"
|
||||
border
|
||||
>
|
||||
<el-table-column prop="userNo" align="center" label="户号" />
|
||||
<el-table-column prop="userName" align="center" label="用户名" />
|
||||
<el-table-column
|
||||
prop="lineNo"
|
||||
align="center"
|
||||
label="测量点局号"
|
||||
width="180"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="updateTime"
|
||||
align="center"
|
||||
label="日期"
|
||||
width="180"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="integrity"
|
||||
align="center"
|
||||
label="完整性(%)"
|
||||
width="130"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
{{ Math.floor(row.integrity * 10000) / 100 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-pagination
|
||||
size="small"
|
||||
style="margin-top: 10px"
|
||||
:currentPage="form.pageNum"
|
||||
:page-size="form.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100, 200]"
|
||||
background
|
||||
:layout="'sizes,total, ->, prev, pager, next, jumper'"
|
||||
:total="total"
|
||||
@size-change="onTableSizeChange"
|
||||
@current-change="onTableCurrentChange"
|
||||
></el-pagination>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, inject, onMounted } from "vue";
|
||||
import { Search, Download } from "@element-plus/icons-vue";
|
||||
import { userDataIntegrityList } from "@/api/manage_wx";
|
||||
import { useStore } from "vuex";
|
||||
import * as XLSX from "xlsx";
|
||||
const emits = defineEmits(["close"]);
|
||||
const store = useStore();
|
||||
const machineVisible = ref(false);
|
||||
const form = reactive({
|
||||
searchValue: "",
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
userDataId: "",
|
||||
});
|
||||
const loading = ref(false);
|
||||
const total = ref(0); // 假设总条数为100
|
||||
const tableData = ref([]);
|
||||
//form表单校验规则
|
||||
const open = (row) => {
|
||||
machineVisible.value = true;
|
||||
form.searchValue = "";
|
||||
form.pageNum = 1;
|
||||
form.pageSize = 20;
|
||||
form.userDataId = row.id;
|
||||
|
||||
getTableData();
|
||||
};
|
||||
const onTableSizeChange = (size: number) => {
|
||||
form.pageSize = size;
|
||||
getTableData();
|
||||
};
|
||||
const onTableCurrentChange = (page: number) => {
|
||||
form.pageNum = page;
|
||||
getTableData();
|
||||
};
|
||||
|
||||
const getTableData = async () => {
|
||||
loading.value = true;
|
||||
const res: any = await userDataIntegrityList(form);
|
||||
|
||||
if (res.code == "A0000") {
|
||||
tableData.value = res.data.records;
|
||||
total.value = res.data.total;
|
||||
}
|
||||
loading.value = false;
|
||||
};
|
||||
const handleClose = () => {
|
||||
machineVisible.value = false;
|
||||
emits("close");
|
||||
};
|
||||
|
||||
// 导出
|
||||
const exportTable = async () => {
|
||||
let columnExpor: any = [
|
||||
["户号", "用户名", "测量点局号", "日期", "完整性(%)"],
|
||||
];
|
||||
|
||||
let list = [];
|
||||
|
||||
await userDataIntegrityList({
|
||||
...form,
|
||||
pageNum: 1,
|
||||
pageSize: total.value,
|
||||
}).then((res) => {
|
||||
let data = res.data.records.map((item) => {
|
||||
return [
|
||||
item.userNo,
|
||||
item.userName,
|
||||
item.lineNo,
|
||||
item.updateTime,
|
||||
Math.floor(item.integrity * 10000) / 100,
|
||||
];
|
||||
});
|
||||
list = [...columnExpor, ...data];
|
||||
// 创建工作表
|
||||
const worksheet = XLSX.utils.aoa_to_sheet(list);
|
||||
|
||||
worksheet["!cols"] = list.map((col) => ({ wch: 20 }));
|
||||
|
||||
// 创建工作簿
|
||||
const workbook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, "完整性不足详情");
|
||||
|
||||
// 写出文件
|
||||
XLSX.writeFile(workbook, "完整性不足详情" + ".xlsx");
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {});
|
||||
|
||||
defineExpose({ open });
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@use "@/assets/scss/index.scss";
|
||||
|
||||
.tableBox {
|
||||
padding: 0px !important;
|
||||
}
|
||||
|
||||
.formBox {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,262 @@
|
||||
<template>
|
||||
<!--暂降 -->
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
draggable
|
||||
v-model="machineVisible"
|
||||
title="暂降事件"
|
||||
width="1200px"
|
||||
>
|
||||
<div class="tableBox">
|
||||
<div style="display: flex;justify-content: flex-end;">
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Download"
|
||||
@click="exportTable"
|
||||
size="small"
|
||||
>导出
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
:scrollbar-always-on="true"
|
||||
:data="tableData"
|
||||
height="443px"
|
||||
size="small"
|
||||
v-loading="loading"
|
||||
element-loading-background="#343849c7"
|
||||
:header-cell-style="{ textAlign: 'center' }"
|
||||
border
|
||||
style="margin-top: 13px;"
|
||||
>
|
||||
<!-- <el-table-column type="index" align="center" label="序号" width="70" /> -->
|
||||
<el-table-column label="序号" align="center" type="index" width="70">
|
||||
<template #default="scope">
|
||||
<span>{{
|
||||
(form.pageNum - 1) * form.pageSize + scope.$index + 1
|
||||
}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="startTime"
|
||||
align="center"
|
||||
label="发生时间"
|
||||
show-overflow-tooltip
|
||||
width="160"
|
||||
/>
|
||||
<el-table-column prop="stationName" align="center" label="变电站" />
|
||||
<el-table-column prop="lineName" align="center" label="监测点" />
|
||||
<el-table-column
|
||||
prop="objName"
|
||||
label="用户"
|
||||
align="center"
|
||||
show-overflow-tooltip
|
||||
>
|
||||
<template v-slot="scope">
|
||||
<span>{{ scope.row.objName ? scope.row.objName : "/" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="eventType"
|
||||
align="center"
|
||||
label="触发类型"
|
||||
width="80"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="featureAmplitude"
|
||||
align="center"
|
||||
label="残余电压(%)"
|
||||
width="100"
|
||||
>
|
||||
<template v-slot="scope">
|
||||
<span>{{ (scope.row.featureAmplitude * 100).toFixed(2) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="duration"
|
||||
align="center"
|
||||
label="持续时间(S)"
|
||||
width="100"
|
||||
/>
|
||||
<el-table-column fixed="right" label="操作" width="80" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
size="small"
|
||||
@click.stop="trendCharts(scope.row)"
|
||||
>波形</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-pagination
|
||||
size="small"
|
||||
style="margin-top: 10px"
|
||||
:currentPage="form.pageNum"
|
||||
:page-size="form.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100, 200]"
|
||||
background
|
||||
:layout="'sizes,total, ->, prev, pager, next, jumper'"
|
||||
:total="total"
|
||||
@size-change="onTableSizeChange"
|
||||
@current-change="onTableCurrentChange"
|
||||
></el-pagination>
|
||||
</el-dialog>
|
||||
<!-- 波形图 -->
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
draggable
|
||||
v-model="trendVisible"
|
||||
v-if="trendVisible"
|
||||
title="波形"
|
||||
width="70%"
|
||||
@close="handleCloseTrend"
|
||||
>
|
||||
<waveForm ref="waveFormRef" />
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, inject } from "vue";
|
||||
import { eventListByLineId } from "@/api/manage_wx";
|
||||
import waveForm from "@/components/BX/waveForm.vue";
|
||||
import * as XLSX from "xlsx";
|
||||
import { Download } from "@element-plus/icons-vue";
|
||||
|
||||
const machineVisible = ref(false);
|
||||
const form = reactive({
|
||||
lineId: "",
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
searchBeginTime: "",
|
||||
searchEndTime: "",
|
||||
});
|
||||
const total = ref(0); // 假设总条数为100
|
||||
const loading = ref(false);
|
||||
const tableData = ref([]);
|
||||
import { useStore } from "vuex";
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const trendVisible = ref(false);
|
||||
|
||||
const waveFormRef = ref();
|
||||
//点击波形图
|
||||
const trendCharts = (row: any) => {
|
||||
row.eventdetail_index = row.eventId;
|
||||
machineVisible.value = false;
|
||||
trendVisible.value = true;
|
||||
setTimeout(() => {
|
||||
waveFormRef.value?.open({
|
||||
...row,
|
||||
bdname: row.stationName,
|
||||
pointname: row.lineName,
|
||||
timeid: row.startTime,
|
||||
eventvalue: row.featureAmplitude,
|
||||
persisttime: row.duration,
|
||||
});
|
||||
}, 500);
|
||||
};
|
||||
|
||||
// 关闭波形图
|
||||
const handleCloseTrend = () => {
|
||||
trendVisible.value = false;
|
||||
machineVisible.value = true;
|
||||
};
|
||||
const open = async (id: any) => {
|
||||
form.pageNum = 1;
|
||||
form.pageSize = 20;
|
||||
form.lineId = id;
|
||||
machineVisible.value = true;
|
||||
await init();
|
||||
};
|
||||
|
||||
const init = async () => {
|
||||
loading.value = true;
|
||||
eventListByLineId({
|
||||
lineId: form.lineId,
|
||||
searchBeginTime: store.state.timeValue[0],
|
||||
searchEndTime: store.state.timeValue[1],
|
||||
}).then((res) => {
|
||||
tableData.value = res.data.records;
|
||||
total.value = res.data.total;
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const onTableSizeChange = (size: number) => {
|
||||
form.pageSize = size;
|
||||
init();
|
||||
};
|
||||
const onTableCurrentChange = (page: number) => {
|
||||
form.pageNum = page;
|
||||
init();
|
||||
};
|
||||
|
||||
// 暂降溯源导出
|
||||
const exportTable = async () => {
|
||||
let columnExpor: any = [
|
||||
[
|
||||
"发生时间",
|
||||
"变电站",
|
||||
"监测点",
|
||||
"用户",
|
||||
"触发类型",
|
||||
"残余电压(%)",
|
||||
"持续时间(S)",
|
||||
],
|
||||
];
|
||||
|
||||
let list = [];
|
||||
|
||||
await eventListByLineId({
|
||||
lineId: form.lineId,
|
||||
searchBeginTime: store.state.timeValue[0],
|
||||
searchEndTime: store.state.timeValue[1],
|
||||
pageNum: 1,
|
||||
pageSize: total.value,
|
||||
}).then((res) => {
|
||||
let data = res.data.records.map((item) => {
|
||||
return [
|
||||
item.startTime,
|
||||
item.stationName,
|
||||
item.lineName,
|
||||
item.objName,
|
||||
item.eventType,
|
||||
(item.featureAmplitude * 100).toFixed(2),
|
||||
item.duration,
|
||||
];
|
||||
});
|
||||
list = [...columnExpor, ...data];
|
||||
// 创建工作表
|
||||
const worksheet = XLSX.utils.aoa_to_sheet(list);
|
||||
|
||||
worksheet["!cols"] = list.map((col) => ({ wch: 20 }));
|
||||
|
||||
// 创建工作簿
|
||||
const workbook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, "暂降事件");
|
||||
|
||||
// 写出文件
|
||||
XLSX.writeFile(workbook, "暂降事件" + ".xlsx");
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ open });
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@use "@/assets/scss/index.scss";
|
||||
.tableBox {
|
||||
padding: 0px !important;
|
||||
}
|
||||
.formBox {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.formLeft {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,558 @@
|
||||
<template>
|
||||
<!--暂降 -->
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
draggable
|
||||
v-model="machineVisible"
|
||||
title="暂降事件"
|
||||
width="1000px"
|
||||
>
|
||||
<div class="tableBox">
|
||||
<el-form
|
||||
:inline="true"
|
||||
style="display: flex; justify-content: space-between"
|
||||
>
|
||||
<el-form-item label="关键字筛选">
|
||||
<el-input
|
||||
clearable
|
||||
style="width: 150px"
|
||||
v-model="searchValue"
|
||||
size="small"
|
||||
placeholder="电站、测点、用户信息"
|
||||
></el-input>
|
||||
<el-popover placement="bottom" :width="550" trigger="click">
|
||||
<template #reference>
|
||||
<el-button
|
||||
size="small"
|
||||
:icon="DArrowRight"
|
||||
type="primary"
|
||||
style="margin-left: 10px"
|
||||
>更多</el-button
|
||||
>
|
||||
</template>
|
||||
|
||||
<el-form label-width="auto">
|
||||
<!-- <el-form-item label="关键字筛选">
|
||||
<el-input
|
||||
clearable
|
||||
style="width: 150px"
|
||||
v-model="searchValue"
|
||||
size="small"
|
||||
placeholder="电站、测点、用户信息"
|
||||
></el-input>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="运维单位">
|
||||
<el-tree-select
|
||||
v-model="deptsIndex"
|
||||
:data="deptsList"
|
||||
:render-after-expand="false"
|
||||
clearable
|
||||
size="small"
|
||||
style="width: 150px"
|
||||
:props="{
|
||||
value: 'id',
|
||||
label: 'name',
|
||||
children: 'children',
|
||||
}"
|
||||
/>
|
||||
<!-- <el-select
|
||||
v-model="deptsIndex"
|
||||
placeholder="请选择运维单位"
|
||||
clearable
|
||||
size="small"
|
||||
:teleported="false"
|
||||
style="width: 150px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in deptsList"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
:key="item.id"
|
||||
></el-option>
|
||||
</el-select> -->
|
||||
</el-form-item>
|
||||
<el-form-item label="触发类型">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
:teleported="false"
|
||||
v-model="eventForm.eventType"
|
||||
placeholder="请选择触发类型"
|
||||
style="width: 150px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in eventTypeList"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
:key="item.id"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="残余电压百分比">
|
||||
<el-input-number
|
||||
v-model="eventForm.eventValueMin"
|
||||
:min="0"
|
||||
style="width: 150px"
|
||||
size="small"
|
||||
:max="100"
|
||||
:precision="1"
|
||||
:step="1"
|
||||
@change="
|
||||
(e) => (e == null ? (eventForm.eventValueMin = 1) : null)
|
||||
"
|
||||
><template #suffix>
|
||||
<span>%</span>
|
||||
</template></el-input-number
|
||||
>
|
||||
<span> < 残余电压 < </span>
|
||||
|
||||
<el-input-number
|
||||
v-model="eventForm.eventValueMax"
|
||||
:min="0"
|
||||
style="width: 150px"
|
||||
size="small"
|
||||
:max="100"
|
||||
:precision="1"
|
||||
:step="1"
|
||||
@change="
|
||||
(e) => (e == null ? (eventForm.eventValueMax = 1) : null)
|
||||
"
|
||||
><template #suffix>
|
||||
<span>%</span>
|
||||
</template></el-input-number
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item label="暂降持续事时间">
|
||||
<el-input-number
|
||||
v-model="eventForm.eventDurationMin"
|
||||
:min="0"
|
||||
style="width: 150px"
|
||||
size="small"
|
||||
:max="1000000"
|
||||
:precision="1"
|
||||
:step="1"
|
||||
@change="
|
||||
(e) => (e == null ? (eventForm.eventDurationMin = 1) : null)
|
||||
"
|
||||
><template #suffix>
|
||||
<span>ms</span>
|
||||
</template></el-input-number
|
||||
>
|
||||
<span> < 持续时间 < </span>
|
||||
|
||||
<el-input-number
|
||||
v-model="eventForm.eventDurationMax"
|
||||
:min="0"
|
||||
style="width: 150px"
|
||||
size="small"
|
||||
:max="1000000"
|
||||
:precision="1"
|
||||
:step="1"
|
||||
@change="
|
||||
(e) => (e == null ? (eventForm.eventDurationMax = 1) : null)
|
||||
"
|
||||
><template #suffix>
|
||||
<span>ms</span>
|
||||
</template></el-input-number
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-popover>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item style="margin-right: -10px">
|
||||
<el-button size="small" :icon="Search" type="primary" @click="init()"
|
||||
>查询</el-button
|
||||
>
|
||||
<el-button size="small" :icon="RefreshLeft" @click="clearInit()"
|
||||
>重置</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Download"
|
||||
@click="exportTable"
|
||||
size="small"
|
||||
style="margin-right: 10px"
|
||||
>导出
|
||||
</el-button>
|
||||
<el-button
|
||||
style="margin-right: 10px"
|
||||
v-if="displayValue == 1"
|
||||
size="small"
|
||||
:icon="HelpFilled"
|
||||
type="primary"
|
||||
@click="handleAggregation"
|
||||
>溯源</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- <div style="float: right; margin-bottom: 9px" v-if="displayValue == 1">
|
||||
<el-button
|
||||
size="small"
|
||||
:icon="HelpFilled"
|
||||
type="primary"
|
||||
@click="handleAggregation"
|
||||
>聚合</el-button
|
||||
>
|
||||
</div> -->
|
||||
<el-table
|
||||
:scrollbar-always-on="true"
|
||||
:data="tableData"
|
||||
height="443px"
|
||||
size="small"
|
||||
v-loading="loading"
|
||||
element-loading-background="#343849c7"
|
||||
:header-cell-style="{ textAlign: 'center' }"
|
||||
border
|
||||
>
|
||||
<!-- <el-table-column type="index" align="center" label="序号" width="70" /> -->
|
||||
<el-table-column label="序号" align="center" type="index" width="70">
|
||||
<template #default="scope">
|
||||
<span>{{
|
||||
(form.pageNum - 1) * form.pageSize + scope.$index + 1
|
||||
}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="startTime"
|
||||
align="center"
|
||||
label="发生时间"
|
||||
show-overflow-tooltip
|
||||
width="160"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="stationName"
|
||||
align="center"
|
||||
label="变电站"
|
||||
width="120"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="lineName"
|
||||
align="center"
|
||||
label="监测点"
|
||||
width="120"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="objName"
|
||||
label="用户"
|
||||
align="center"
|
||||
show-overflow-tooltip
|
||||
>
|
||||
<template v-slot="scope">
|
||||
<span>{{ scope.row.objName ? scope.row.objName : "/" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="eventType"
|
||||
align="center"
|
||||
label="触发类型"
|
||||
width="90"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="featureAmplitude"
|
||||
align="center"
|
||||
label="残余电压(%)"
|
||||
width="90"
|
||||
>
|
||||
<template v-slot="scope">
|
||||
<span>{{ (scope.row.featureAmplitude * 100).toFixed(2) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="duration"
|
||||
align="center"
|
||||
label="持续时间(S)"
|
||||
width="90"
|
||||
/>
|
||||
<el-table-column fixed="right" label="操作" width="80" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
size="small"
|
||||
@click.stop="trendCharts(scope.row)"
|
||||
>波形</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-pagination
|
||||
size="small"
|
||||
style="margin-top: 10px"
|
||||
:currentPage="form.pageNum"
|
||||
:page-size="form.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100, 200]"
|
||||
background
|
||||
:layout="'sizes,total, ->, prev, pager, next, jumper'"
|
||||
:total="total"
|
||||
@size-change="onTableSizeChange"
|
||||
@current-change="onTableCurrentChange"
|
||||
></el-pagination>
|
||||
</el-dialog>
|
||||
<!-- 波形图 -->
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
draggable
|
||||
v-model="trendVisible"
|
||||
v-if="trendVisible"
|
||||
title="波形"
|
||||
width="70%"
|
||||
@close="handleCloseTrend"
|
||||
>
|
||||
<waveForm ref="waveFormRef" />
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, inject, onMounted, watch } from "vue";
|
||||
import {
|
||||
getEventList,
|
||||
processEvents,
|
||||
loginDeptTree,
|
||||
getDicDataByTypeCode,
|
||||
} from "@/api/manage_wx";
|
||||
import { HelpFilled } from "@element-plus/icons-vue";
|
||||
import waveForm from "@/components/BX/waveForm.vue";
|
||||
import {
|
||||
DArrowRight,
|
||||
Search,
|
||||
RefreshLeft,
|
||||
Download,
|
||||
} from "@element-plus/icons-vue";
|
||||
import * as XLSX from "xlsx";
|
||||
|
||||
// 定义 emit
|
||||
const emit = defineEmits(["aggregation-success"]);
|
||||
|
||||
const machineVisible = ref(false);
|
||||
const form = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
});
|
||||
const total = ref(0); // 假设总条数为100
|
||||
const loading = ref(false);
|
||||
const tableData = ref([]);
|
||||
import { useStore } from "vuex";
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const displayValue = ref();
|
||||
|
||||
const trendVisible = ref(false);
|
||||
|
||||
const waveFormRef = ref();
|
||||
|
||||
const open = async (val) => {
|
||||
displayValue.value = val;
|
||||
machineVisible.value = true;
|
||||
await init();
|
||||
};
|
||||
|
||||
// 查询
|
||||
const searchValue = ref("");
|
||||
const deptsIndex = ref("");
|
||||
const deptsList = ref([]); //部门列表
|
||||
const eventTypeList = ref([]); //触发类型
|
||||
const eventForm: any = reactive({
|
||||
eventValueMin: null,
|
||||
eventValueMax: null,
|
||||
eventDurationMin: null,
|
||||
eventDurationMax: null,
|
||||
eventType: null,
|
||||
});
|
||||
|
||||
const clearInit = async () => {
|
||||
searchValue.value = "";
|
||||
eventForm.eventValueMin = null;
|
||||
eventForm.eventValueMax = null;
|
||||
eventForm.eventDurationMin = null;
|
||||
eventForm.eventDurationMax = null;
|
||||
eventForm.eventType = null;
|
||||
deptsIndex.value = null;
|
||||
|
||||
await init();
|
||||
};
|
||||
|
||||
// 部门
|
||||
const initDept = () => {
|
||||
loginDeptTree({
|
||||
deptIndex: store.state.deptId,
|
||||
}).then((res: any) => {
|
||||
deptsList.value = res.data;
|
||||
});
|
||||
};
|
||||
|
||||
// 触发类型
|
||||
const dicDataByTypeCode = () => {
|
||||
getDicDataByTypeCode({
|
||||
dictTypeCode: "Event_Statis",
|
||||
}).then((res: any) => {
|
||||
eventTypeList.value = res.data;
|
||||
});
|
||||
};
|
||||
|
||||
const init = async () => {
|
||||
loading.value = true;
|
||||
getEventList({
|
||||
deptId: store.state.deptId,
|
||||
searchBeginTime: store.state.timeValue[0],
|
||||
searchEndTime: store.state.timeValue[1],
|
||||
pageNum: form.pageNum,
|
||||
pageSize: form.pageSize,
|
||||
searchValue: searchValue.value,
|
||||
...eventForm,
|
||||
eventValueMin:
|
||||
eventForm.eventValueMin == null ? null : eventForm.eventValueMin / 100,
|
||||
eventValueMax:
|
||||
eventForm.eventValueMax == null ? null : eventForm.eventValueMax / 100,
|
||||
}).then((res) => {
|
||||
tableData.value = res.data.records;
|
||||
total.value = res.data.total;
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const handleAggregation = (row: any) => {
|
||||
machineVisible.value = false;
|
||||
ElMessageBox.confirm(
|
||||
`是否确认对当前用户部门${store.state.timeValue[0]}至${store.state.timeValue[1]}之间的暂降事件进行溯源?`,
|
||||
"提示",
|
||||
{
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
processEvents({
|
||||
deptId: store.state.deptId,
|
||||
searchBeginTime: store.state.timeValue[0],
|
||||
searchEndTime: store.state.timeValue[1],
|
||||
}).then((res: any) => {
|
||||
if (res.code == "A0000") {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: res.message,
|
||||
});
|
||||
// 通知父组件执行 initialAggregation
|
||||
emit("aggregation-success");
|
||||
} else {
|
||||
ElMessage({
|
||||
type: "warning",
|
||||
message: res.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch((error) => {});
|
||||
};
|
||||
|
||||
//点击波形图
|
||||
const trendCharts = (row: any) => {
|
||||
row.eventdetail_index = row.eventId;
|
||||
machineVisible.value = false;
|
||||
trendVisible.value = true;
|
||||
setTimeout(() => {
|
||||
waveFormRef.value?.open({
|
||||
...row,
|
||||
bdname: row.stationName,
|
||||
pointname: row.lineName,
|
||||
timeid: row.startTime,
|
||||
eventvalue: row.featureAmplitude,
|
||||
persisttime: row.duration,
|
||||
});
|
||||
}, 500);
|
||||
};
|
||||
|
||||
// 关闭波形图
|
||||
const handleCloseTrend = () => {
|
||||
trendVisible.value = false;
|
||||
machineVisible.value = true;
|
||||
};
|
||||
|
||||
const onTableSizeChange = (size: number) => {
|
||||
form.pageSize = size;
|
||||
init();
|
||||
};
|
||||
const onTableCurrentChange = (page: number) => {
|
||||
form.pageNum = page;
|
||||
init();
|
||||
};
|
||||
|
||||
// 暂降溯源导出
|
||||
const exportTable = async () => {
|
||||
let columnExpor: any = [
|
||||
[
|
||||
"发生时间",
|
||||
"变电站",
|
||||
"监测点",
|
||||
"用户",
|
||||
"触发类型",
|
||||
"残余电压(%)",
|
||||
"持续时间(S)",
|
||||
],
|
||||
];
|
||||
|
||||
let list = [];
|
||||
|
||||
await getEventList({
|
||||
deptId: store.state.deptId,
|
||||
searchBeginTime: store.state.timeValue[0],
|
||||
searchEndTime: store.state.timeValue[1],
|
||||
searchValue: searchValue.value,
|
||||
...eventForm,
|
||||
eventValueMin:
|
||||
eventForm.eventValueMin == null ? null : eventForm.eventValueMin / 100,
|
||||
eventValueMax:
|
||||
eventForm.eventValueMax == null ? null : eventForm.eventValueMax / 100,
|
||||
pageNum: 1,
|
||||
pageSize: total.value,
|
||||
}).then((res) => {
|
||||
let data = res.data.records.map((item) => {
|
||||
return [
|
||||
item.startTime,
|
||||
item.stationName,
|
||||
item.lineName,
|
||||
item.objName,
|
||||
item.eventType,
|
||||
(item.featureAmplitude * 100).toFixed(2),
|
||||
item.duration,
|
||||
];
|
||||
});
|
||||
list = [...columnExpor, ...data];
|
||||
// 创建工作表
|
||||
const worksheet = XLSX.utils.aoa_to_sheet(list);
|
||||
|
||||
worksheet["!cols"] = list.map((col) => ({ wch: 20 }));
|
||||
|
||||
// 创建工作簿
|
||||
const workbook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, "暂降事件");
|
||||
|
||||
// 写出文件
|
||||
XLSX.writeFile(workbook, "暂降事件" + ".xlsx");
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
initDept();
|
||||
dicDataByTypeCode();
|
||||
});
|
||||
defineExpose({ open });
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@use "@/assets/scss/index.scss";
|
||||
.tableBox {
|
||||
padding: 0px !important;
|
||||
}
|
||||
.formBox {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.formLeft {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,701 @@
|
||||
<template>
|
||||
<!-- 配网计算 -->
|
||||
<splitpanes style="height: 100%" class="default-theme" id="navigation-splitpanes">
|
||||
<pane :size="20">
|
||||
<PointTree :showSelect="false" @node-click="handleNodeClick" @init="handleNodeClick"></PointTree>
|
||||
</pane>
|
||||
|
||||
<pane style="background-color: rgba(44, 46, 60, 0.1)" :size="100 - size">
|
||||
|
||||
<el-form :model="form" inline label-width="auto">
|
||||
<el-form-item label="谐波类型">
|
||||
<el-radio-group v-model="form.type">
|
||||
<el-radio-button label="谐波电压" size="small" value="1" />
|
||||
<el-radio-button label="谐波电流" size="small" value="0" />
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="谐波次数">
|
||||
<el-select v-model="form.index" filterable multiple :multiple-limit="5" collapse-tags collapse-tags-tooltip
|
||||
clearable placeholder="请选择次数" style="width: 200px" size="small">
|
||||
<el-option v-for="item in 49" :key="item" :label="item + 1 + '次'" :value="item + 1"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="负荷数据">
|
||||
<el-select v-model="form.loadDataId" clearable filterable placeholder="请选择负荷数据" style="width: 200px"
|
||||
size="small">
|
||||
<el-option v-for="item in loadDataOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<!-- <el-button type="primary" icon="el-icon-Plus" @click="push('/admin/division/aListOfLoadData')">
|
||||
新增
|
||||
</el-button> -->
|
||||
<el-button type="primary" :icon="Select" @click="submit" size="small">确定</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-tabs v-model="activeName" v-if="showTabs" style="height: 740px">
|
||||
<el-tab-pane v-for="(item, index) in tabList" :key="item" :label="item.label" :name="index"
|
||||
style="height: 100%">
|
||||
<div>
|
||||
<div>
|
||||
<span style="color: #fff">时间范围</span>
|
||||
<el-date-picker v-model="item.time" class="mr10 ml10" type="daterange" start-placeholder="起始时间"
|
||||
end-placeholder="结束时间" format="YYYY-MM-DD" date-format="YYYY-MM-DD" time-format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD" :disabled-date="handleDisabledDate" size="small" />
|
||||
<el-button type="primary" :icon="CaretRight" @click="execute(item, index)" size="small">
|
||||
执行
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="item.showEcahr == 1" class="harmonicButton">
|
||||
<el-form :inline="true" v-model="item.form">
|
||||
<el-form-item label="限值" v-if="item.showDynamic">
|
||||
<el-input v-model="item.form.limit" placeholder="请选择限值" disabled style="width: 200px" size="small">
|
||||
<template #append>
|
||||
<el-button :icon="Edit" :class="[code == 0 ? 'frontBox' : '']" @click="setCode(0)" size="small" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间点一" v-if="item.showDynamic">
|
||||
<el-input v-model="item.form.time1" placeholder="请选择时间点一" disabled style="width: 200px" size="small">
|
||||
<template #append>
|
||||
<el-button :icon="Edit" :class="[code == 1 ? 'frontBox' : '']" @click="setCode(1)" size="small" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间点二" v-if="item.showDynamic">
|
||||
<el-input v-model="item.form.time2" placeholder="请选择时间点二" disabled style="width: 200px" size="small">
|
||||
<template #append>
|
||||
<el-button :icon="Edit" :class="[code == 2 ? 'frontBox' : '']" @click="setCode(2)" size="small" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-button type="primary" :icon="Document" @click="generateFn" v-if="!item.showDynamic" size="small">
|
||||
生成动态谐波责任数据
|
||||
</el-button>
|
||||
<el-button type="primary" :icon="Document" v-else @click="generateMetrics" size="small">
|
||||
生成谐波责任指标
|
||||
</el-button>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="box" v-loading="loading" element-loading-background="#343849c7">
|
||||
<MyEChart :options="item.options" v-if="item.showEcahr == 1" @group="group" />
|
||||
<el-empty description="时间范围内无谐波数据" v-if="item.showEcahr == 2" />
|
||||
</div>
|
||||
<!-- 生成动态谐波责任数据 -->
|
||||
<div class="box boxTab" v-loading="loading1" element-loading-background="#343849c7">
|
||||
<MyEChart :options="item.dynamicOptions" style="flex: 1" v-if="item.showDynamic" />
|
||||
<div style="width: 500px" v-if="item.showDynamic" class="tableBox">
|
||||
<el-table :scrollbar-always-on="true" ref="tableRef" :data="item.dynamicData" height="280px"
|
||||
size="small" :header-cell-style="{ textAlign: 'center' }" border>
|
||||
<el-table-column prop="customerName" align="center" label="用户名(用户号)" />
|
||||
<el-table-column prop="responsibilityData" align="center" label="责任数据(%)" width="120">
|
||||
<template #default="scope">
|
||||
{{
|
||||
Math.floor(scope.row.responsibilityData * 10000) /
|
||||
10000
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</pane>
|
||||
</splitpanes>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, reactive } from "vue";
|
||||
import "splitpanes/dist/splitpanes.css";
|
||||
import { Splitpanes, Pane } from "splitpanes";
|
||||
import PointTree from "@/components/tree/pointTree.vue";
|
||||
import { Edit, Right } from "@element-plus/icons-vue";
|
||||
import MyEChart from "@/components/echarts/MyEchart.vue";
|
||||
import { timeFormat } from "@/utils/common";
|
||||
import { yMethod } from "@/utils/echartMethod";
|
||||
import { Select, CaretRight, Document } from "@element-plus/icons-vue";
|
||||
import {
|
||||
userDataList,
|
||||
getHistoryHarmData,
|
||||
getDynamicData,
|
||||
getResponsibilityData,
|
||||
} from "@/api/manage_wx";
|
||||
const emit = defineEmits(["setTitle"]); // 打开弹窗
|
||||
const visible = ref(false);
|
||||
const size = ref(0);
|
||||
const dotList: any = ref({});
|
||||
const form: any = reactive({
|
||||
type: "1",
|
||||
index: [],
|
||||
loadDataId: "",
|
||||
});
|
||||
|
||||
const loadDataOptions: any = ref([]);
|
||||
const code = ref(3);
|
||||
const xAxisData = ref([]);
|
||||
const loading = ref(false);
|
||||
const loading1 = ref(false);
|
||||
const tabList: any = ref([]);
|
||||
const activeName = ref(0);
|
||||
const xValue = ref("");
|
||||
const showTabs = ref(false);
|
||||
|
||||
// 设置时间
|
||||
const timeFrame = ref(["", ""]);
|
||||
|
||||
const openDialog = () => {
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
const handleNodeClick = (data: any) => {
|
||||
if (data.level == 6) {
|
||||
dotList.value = data;
|
||||
setTimeout(() => {
|
||||
emit("setTitle", data.alias);
|
||||
}, 0)
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// 处理日期禁用逻辑
|
||||
const handleDisabledDate = (date) => {
|
||||
// 定义时间边界
|
||||
const startLimit = new Date(timeFrame.value[0]).getTime() - 86400000; //向前推1天
|
||||
const endLimit = new Date(timeFrame.value[1]).setHours(23, 59, 59, 999);
|
||||
|
||||
// 如果日期不存在(选择今天时可能出现),不禁用
|
||||
if (!date) return false;
|
||||
|
||||
// 禁用 2025-08-01 之前和 2025-08-31 之后的日期
|
||||
return date.getTime() < startLimit || date.getTime() > endLimit;
|
||||
};
|
||||
// 这是按钮变色
|
||||
const setCode = (num: number) => {
|
||||
if (code.value == num) {
|
||||
return (code.value = 3);
|
||||
}
|
||||
code.value = num;
|
||||
};
|
||||
|
||||
// 确定
|
||||
const submit = () => {
|
||||
if (form.loadDataId == "") {
|
||||
return ElMessage.warning("请选择负荷数据");
|
||||
}
|
||||
if (form.index.length == 0) {
|
||||
return ElMessage.warning("请选择谐波次数");
|
||||
}
|
||||
|
||||
if (form.index.length == 0) {
|
||||
showTabs.value = false;
|
||||
} else {
|
||||
let timeList = loadDataOptions.value.filter(
|
||||
(item: any) => item.id == form.loadDataId
|
||||
)[0];
|
||||
showTabs.value = true;
|
||||
let list = JSON.parse(JSON.stringify(form.index)).sort((a, b) => a - b);
|
||||
tabList.value = [];
|
||||
list.forEach((item: any) => {
|
||||
tabList.value.push({
|
||||
label: item + "次谐波",
|
||||
key: item,
|
||||
time: [timeList.startTime, timeList.endTime],
|
||||
showExecute: false,
|
||||
form: {
|
||||
limit: "",
|
||||
time1: "",
|
||||
time2: "",
|
||||
},
|
||||
showEcahr: 3, //1显示echart 2显示无数据 3什么都没有
|
||||
options: {},
|
||||
dynamicOptions: {}, //动态echarts
|
||||
dynamicList: {}, //动态echarts
|
||||
showDynamic: false, //动态执行展示
|
||||
});
|
||||
timeFrame.value = [timeList.startTime, timeList.endTime];
|
||||
});
|
||||
code.value = 3;
|
||||
activeName.value = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// 执行
|
||||
const execute = async (item: any, index: number) => {
|
||||
tabList.value[activeName.value].showDynamic = false;
|
||||
loading.value = true;
|
||||
await getHistoryHarmData({
|
||||
searchBeginTime: item.time[0],
|
||||
searchEndTime: item.time[1],
|
||||
type: form.type,
|
||||
time: item.key,
|
||||
lineId: dotList.value.id,
|
||||
})
|
||||
.then((res: any) => {
|
||||
if (res.code == "A0000") {
|
||||
let [min, max] = yMethod(
|
||||
res.data.historyData.map((item: any) => item.value + 0.1)
|
||||
);
|
||||
xAxisData.value = res.data.historyData.map((item: any) => item.time);
|
||||
tabList.value[index].options = {
|
||||
title: {
|
||||
text: "",
|
||||
},
|
||||
xAxis: {
|
||||
type: "time",
|
||||
name: "时间",
|
||||
axisLabel: {
|
||||
formatter: {
|
||||
day: "{MM}-{dd}",
|
||||
month: "{MM}",
|
||||
year: "{yyyy}",
|
||||
},
|
||||
},
|
||||
// 刻度线样式
|
||||
axisTick: {
|
||||
lineStyle: {
|
||||
color: "#fff", // 刻度线白色
|
||||
},
|
||||
},
|
||||
|
||||
// 轴线样式
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "#fff", // 轴线白色
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
formatter(params: any) {
|
||||
xValue.value = params[0].value[0];
|
||||
let str = params[0].value[0] + "<br/>";
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
str =
|
||||
str +
|
||||
params[i].marker +
|
||||
params[i].seriesName +
|
||||
":" +
|
||||
params[i].value[1] +
|
||||
"<br/>";
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
top: 30,
|
||||
right: 50,
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
yAxis: {
|
||||
name: form.type == 1 ? "%" : "A",
|
||||
min: min,
|
||||
max: max,
|
||||
},
|
||||
toolbox: {
|
||||
show: false,
|
||||
},
|
||||
|
||||
series: [
|
||||
{
|
||||
name: item.key + (form.type == 1 ? "次谐波电压" : "次谐波电流"),
|
||||
data: res.data.historyData.map((item: any) => [
|
||||
item.time,
|
||||
Math.floor(item.value * 10000) / 10000,
|
||||
]),
|
||||
type: "line",
|
||||
symbol: "none",
|
||||
|
||||
markLine: {
|
||||
symbol: "none", // 去除箭头
|
||||
label: {
|
||||
show: false, // 隐藏标签
|
||||
},
|
||||
data: [
|
||||
{
|
||||
yAxis: "",
|
||||
},
|
||||
{
|
||||
xAxis: "",
|
||||
},
|
||||
{
|
||||
xAxis: "",
|
||||
},
|
||||
],
|
||||
// 样式配置
|
||||
lineStyle: {
|
||||
color: "red",
|
||||
type: "dashed", // 虚线
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
tabList.value[index].showEcahr = 1; //显示echart
|
||||
} else {
|
||||
ElMessage.warning(res.message);
|
||||
tabList.value[index].showEcahr = 2;
|
||||
}
|
||||
loading.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
tabList.value[index].showEcahr = 2;
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
const resDataId = ref("");
|
||||
// 生成动态谐波责任数据
|
||||
const generateFn = async () => {
|
||||
loading1.value = true;
|
||||
await getDynamicData({
|
||||
lineId: dotList.value.id,
|
||||
searchBeginTime: tabList.value[activeName.value].time[0],
|
||||
searchEndTime: tabList.value[activeName.value].time[1],
|
||||
time: tabList.value[activeName.value].key,
|
||||
type: form.type,
|
||||
userDataId: form.loadDataId,
|
||||
})
|
||||
.then((res: any) => {
|
||||
if (res.code == "A0000") {
|
||||
resDataId.value = res.data.responsibilityDataIndex;
|
||||
tabList.value[activeName.value].dynamicData = res.data.responsibilities;
|
||||
let [min, max] = yMethod(
|
||||
res.data.datas.map((item: any) => item.valueDatas).flat()
|
||||
);
|
||||
let series: any[] = [];
|
||||
let time: any[] = res.data.timeDatas.map((item: any) =>
|
||||
timeFormat(item)
|
||||
);
|
||||
res.data.datas.forEach((item: any) => {
|
||||
series.push({
|
||||
name: item.customerName,
|
||||
data: item.valueDatas.map((k: any, i: number) => [
|
||||
time[i],
|
||||
Math.floor(k * 10000) / 10000,
|
||||
]),
|
||||
type: "line",
|
||||
symbol: "none",
|
||||
});
|
||||
});
|
||||
|
||||
tabList.value[activeName.value].dynamicOptions = {
|
||||
title: {
|
||||
text: "",
|
||||
},
|
||||
xAxis: {
|
||||
type: "time",
|
||||
name: "时间",
|
||||
axisLabel: {
|
||||
formatter: {
|
||||
day: "{MM}-{dd}",
|
||||
month: "{MM}",
|
||||
year: "{yyyy}",
|
||||
},
|
||||
},
|
||||
// 刻度线样式
|
||||
axisTick: {
|
||||
lineStyle: {
|
||||
color: "#fff", // 刻度线白色
|
||||
},
|
||||
},
|
||||
|
||||
// 轴线样式
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "#fff", // 轴线白色
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
formatter(params: any) {
|
||||
let str = params[0].value[0] + "<br/>";
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
str =
|
||||
str +
|
||||
params[i].marker +
|
||||
params[i].seriesName +
|
||||
":" +
|
||||
params[i].value[1] +
|
||||
"<br/>";
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
top: 30,
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
yAxis: {
|
||||
name: form.type == 1 ? "%" : "A",
|
||||
min: min,
|
||||
max: max,
|
||||
},
|
||||
toolbox: {
|
||||
show: false,
|
||||
},
|
||||
|
||||
options: {
|
||||
series: series,
|
||||
},
|
||||
};
|
||||
|
||||
tabList.value[activeName.value].showDynamic = true;
|
||||
} else {
|
||||
ElMessage.warning(res.message);
|
||||
}
|
||||
loading1.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading1.value = false;
|
||||
});
|
||||
loading1.value = false;
|
||||
};
|
||||
|
||||
// 生成指标
|
||||
const generateMetrics = async () => {
|
||||
if (tabList.value[activeName.value].form.limit == "")
|
||||
return ElMessage.warning("请选择限值!");
|
||||
if (tabList.value[activeName.value].form.time1 == "")
|
||||
return ElMessage.warning("请选择时间一!");
|
||||
if (tabList.value[activeName.value].form.time2 == "")
|
||||
return ElMessage.warning("请选择时间二!");
|
||||
loading1.value = true;
|
||||
await getResponsibilityData({
|
||||
limitEndTime: tabList.value[activeName.value].form.time2,
|
||||
limitStartTime: tabList.value[activeName.value].form.time1,
|
||||
limitValue: tabList.value[activeName.value].form.limit,
|
||||
resDataId: resDataId.value,
|
||||
time: tabList.value[activeName.value].key,
|
||||
type: form.type,
|
||||
})
|
||||
.then((res: any) => {
|
||||
tabList.value[activeName.value].dynamicData = res.data.responsibilities;
|
||||
let [min, max] = yMethod(
|
||||
res.data.datas.map((item: any) => item.valueDatas).flat()
|
||||
);
|
||||
let series: any[] = [];
|
||||
let time: any[] = res.data.timeDatas.map((item: any) => timeFormat(item));
|
||||
res.data.datas.forEach((item: any) => {
|
||||
series.push({
|
||||
name: item.customerName,
|
||||
data: item.valueDatas.map((k: any, i: number) => [
|
||||
time[i],
|
||||
Math.floor(k * 10000) / 10000,
|
||||
]),
|
||||
type: "line",
|
||||
smooth: true,
|
||||
symbol: "none",
|
||||
});
|
||||
});
|
||||
|
||||
tabList.value[activeName.value].dynamicOptions = {
|
||||
title: {
|
||||
text: "",
|
||||
},
|
||||
xAxis: {
|
||||
type: "time",
|
||||
name: "时间",
|
||||
axisLabel: {
|
||||
formatter: {
|
||||
day: "{MM}-{dd}",
|
||||
month: "{MM}",
|
||||
year: "{yyyy}",
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
formatter(params: any) {
|
||||
let str = params[0].value[0] + "<br/>";
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
str =
|
||||
str +
|
||||
params[i].marker +
|
||||
params[i].seriesName +
|
||||
":" +
|
||||
params[i].value[1] +
|
||||
"<br/>";
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
top: 30,
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
yAxis: {
|
||||
name: form.type == 1 ? "%" : "A",
|
||||
min: min,
|
||||
max: max,
|
||||
},
|
||||
toolbox: {
|
||||
show: false,
|
||||
},
|
||||
|
||||
options: {
|
||||
series: series,
|
||||
},
|
||||
};
|
||||
|
||||
tabList.value[activeName.value].showDynamic = true;
|
||||
})
|
||||
.catch(() => {
|
||||
loading1.value = false;
|
||||
});
|
||||
loading1.value = false;
|
||||
};
|
||||
// 监听echart点击
|
||||
const group = (chart: any, myChartDom: any) => {
|
||||
myChartDom.addEventListener("click", function (event: any) {
|
||||
// 获取点击位置相对于图表容器的坐标
|
||||
const rect = myChartDom.getBoundingClientRect();
|
||||
const x = event.clientX - rect.left;
|
||||
const y = event.clientY - rect.top;
|
||||
const pointInPixel = [x, y];
|
||||
// 转换为逻辑坐标(相对于图表坐标系)
|
||||
const pointInGrid = chart.convertFromPixel({ gridIndex: 0 }, pointInPixel);
|
||||
// 计算X轴和Y轴的对应数据
|
||||
|
||||
// 处理X轴数据(分类轴)
|
||||
|
||||
// 处理Y轴数据(数值轴)
|
||||
let yValue = pointInGrid[1].toFixed(4);
|
||||
// xValue = timeFormat(pointInGrid[0].toFixed(0) - 0)
|
||||
if (code.value == 0) {
|
||||
tabList.value[activeName.value].form.limit = yValue;
|
||||
tabList.value[activeName.value].options.series[0].markLine.data[0].yAxis =
|
||||
yValue;
|
||||
chart.setOption(tabList.value[activeName.value].options);
|
||||
} else if (code.value == 1) {
|
||||
tabList.value[activeName.value].form.time1 = xValue.value;
|
||||
tabList.value[activeName.value].options.series[0].markLine.data[1].xAxis =
|
||||
xValue.value;
|
||||
chart.setOption(tabList.value[activeName.value].options);
|
||||
} else if (code.value == 2) {
|
||||
tabList.value[activeName.value].form.time2 = xValue.value;
|
||||
tabList.value[activeName.value].options.series[0].markLine.data[2].xAxis =
|
||||
xValue.value;
|
||||
chart.setOption(tabList.value[activeName.value].options);
|
||||
}
|
||||
// 控制台输出详细信息
|
||||
// console.log('点击事件详情:', {
|
||||
// X轴数据: xValue,
|
||||
// Y轴数据: yValue
|
||||
// })
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
const dom = document.getElementById("navigation-splitpanes");
|
||||
if (dom) {
|
||||
size.value = Math.round((180 / dom.offsetHeight) * 100);
|
||||
}
|
||||
userDataList({
|
||||
pageNum: 1,
|
||||
pageSize: 10000,
|
||||
searchValue: "",
|
||||
}).then((res: any) => {
|
||||
console.log(res.data);
|
||||
loadDataOptions.value = res.data.records;
|
||||
});
|
||||
|
||||
if (!dotList.value || !dotList.value.alias) {
|
||||
dotList.value = { alias: "请选择监测点位" };
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@/assets/scss/index.scss";
|
||||
|
||||
.box {
|
||||
// height: calc((100vh - 190px) / 2);
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.boxTab {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.harmonicButton {
|
||||
height: 42px;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__content) {
|
||||
height: calc(100vh - 265px);
|
||||
}
|
||||
|
||||
:deep(.el-input-group__append, .el-input-group__prepend) {
|
||||
background-color: #ffffff00;
|
||||
padding: 0 17px;
|
||||
}
|
||||
|
||||
:deep(.frontBox) {
|
||||
background-color: var(--el-color-primary) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
::v-deep(.el-tabs__item) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep(.el-tabs__item.is-active) {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
::v-deep(.el-tabs__nav-wrap::after) {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
::v-deep(.el-tabs__active-bar) {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
::v-deep(.splitpanes__splitter) {
|
||||
background-color: rgba(44, 46, 60, 0.1) !important;
|
||||
|
||||
&:before {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
&:after {
|
||||
background-color: #fffFFF80 !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep(.el-form-item) {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.currentPosition {
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
right: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,255 @@
|
||||
<template>
|
||||
<!--谐波放大事件 -->
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
draggable
|
||||
v-model="machineVisible"
|
||||
:title="title"
|
||||
width="1200px"
|
||||
>
|
||||
<div class="tableBox">
|
||||
<div style="display: flex; justify-content: flex-end">
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Download"
|
||||
@click="exportTable"
|
||||
size="small"
|
||||
>导出
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
:scrollbar-always-on="true"
|
||||
:data="tableData"
|
||||
height="443px"
|
||||
size="small"
|
||||
v-loading="loading"
|
||||
element-loading-background="#343849c7"
|
||||
:header-cell-style="{ textAlign: 'center' }"
|
||||
border
|
||||
style="margin-top: 13px"
|
||||
>
|
||||
<el-table-column label="序号" align="center" type="index" width="70">
|
||||
<template #default="scope">
|
||||
<span>{{
|
||||
(form.pageNum - 1) * form.pageSize + scope.$index + 1
|
||||
}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="monitorName"
|
||||
align="center"
|
||||
label="监测点名称"
|
||||
width="120"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="objName"
|
||||
align="center"
|
||||
label="用户"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="startTime"
|
||||
align="center"
|
||||
label="开始时间"
|
||||
width="140"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="endTime"
|
||||
align="center"
|
||||
label="结束时间"
|
||||
width="140"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="harmonicCount"
|
||||
align="center"
|
||||
label="次数"
|
||||
width="60"
|
||||
/>
|
||||
<el-table-column prop="phase" align="center" label="相别" width="60" />
|
||||
<el-table-column
|
||||
prop="duration"
|
||||
align="center"
|
||||
label="持续时间(min)"
|
||||
width="100"
|
||||
>
|
||||
<template #default="scope">
|
||||
{{ scope.row.duration / 60 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="vavgValue"
|
||||
align="center"
|
||||
label="电压标准值"
|
||||
width="80"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="iavgValue"
|
||||
align="center"
|
||||
label="电流标准值"
|
||||
width="80"
|
||||
>
|
||||
<template #default="scope">
|
||||
{{ Math.floor(scope.row.iavgValue * 100) / 100 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="upScheme"
|
||||
align="center"
|
||||
label="处理措施"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column prop="address" align="center" label="操作" width="60">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
link
|
||||
@click="arendChart(scope.row)"
|
||||
>趋势图</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-pagination
|
||||
size="small"
|
||||
style="margin-top: 10px"
|
||||
:currentPage="form.pageNum"
|
||||
:page-size="form.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100, 200]"
|
||||
background
|
||||
:layout="'sizes,total, ->, prev, pager, next, jumper'"
|
||||
:total="total"
|
||||
@size-change="onTableSizeChange"
|
||||
@current-change="onTableCurrentChange"
|
||||
></el-pagination>
|
||||
</el-dialog>
|
||||
<TrendChart ref="trendChartRef" @close="machineVisible = true"></TrendChart>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, inject, nextTick } from "vue";
|
||||
import { getDetail } from "@/api/manage_wx";
|
||||
import TrendChart from "./trendChart.vue";
|
||||
import { Download } from "@element-plus/icons-vue";
|
||||
import * as XLSX from "xlsx";
|
||||
|
||||
const machineVisible = ref(false);
|
||||
const title = ref("谐波放大事件");
|
||||
const form = reactive({
|
||||
searchBeginTime: "",
|
||||
lineId: "",
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
});
|
||||
const total = ref(0); // 假设总条数为100
|
||||
const tableData = ref([]);
|
||||
const loading = ref(false);
|
||||
const trendChartRef = ref();
|
||||
//form表单校验规则
|
||||
const open = (text: string, time?: any, lineId?: any) => {
|
||||
machineVisible.value = true;
|
||||
form.lineId = lineId;
|
||||
form.searchBeginTime = time;
|
||||
nextTick(() => {
|
||||
getTableData();
|
||||
});
|
||||
};
|
||||
const onTableSizeChange = (size: number) => {
|
||||
form.pageSize = size;
|
||||
getTableData();
|
||||
};
|
||||
const onTableCurrentChange = (page: number) => {
|
||||
form.pageNum = page;
|
||||
getTableData();
|
||||
};
|
||||
|
||||
const getTableData = async () => {
|
||||
loading.value = true;
|
||||
const res: any = await getDetail(form);
|
||||
|
||||
if (res.code == "A0000") {
|
||||
tableData.value = res.data.records;
|
||||
total.value = res.data.total;
|
||||
}
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
// 趋势图
|
||||
const arendChart = (row: any) => {
|
||||
trendChartRef.value.open(row);
|
||||
machineVisible.value = false;
|
||||
};
|
||||
|
||||
// 导出
|
||||
const exportTable = async () => {
|
||||
let columnExpor: any = [
|
||||
[
|
||||
"监测点名称",
|
||||
"用户",
|
||||
"开始时间",
|
||||
"结束时间",
|
||||
"次数",
|
||||
"相别",
|
||||
"持续时间(min)",
|
||||
"电压标准值",
|
||||
"电流标准值",
|
||||
],
|
||||
];
|
||||
|
||||
let list = [];
|
||||
|
||||
await getDetail({
|
||||
...form,
|
||||
pageNum: 1,
|
||||
pageSize: total.value,
|
||||
}).then((res) => {
|
||||
let data = res.data.records.map((item) => {
|
||||
return [
|
||||
item.monitorName,
|
||||
item.objName,
|
||||
item.startTime,
|
||||
item.endTime,
|
||||
item.harmonicCount,
|
||||
item.phase,
|
||||
item.duration / 60,
|
||||
item.vavgValue,
|
||||
Math.floor(item.iavgValue * 100) / 100,
|
||||
];
|
||||
});
|
||||
list = [...columnExpor, ...data];
|
||||
// 创建工作表
|
||||
const worksheet = XLSX.utils.aoa_to_sheet(list);
|
||||
|
||||
worksheet["!cols"] = list.map((col) => ({ wch: 20 }));
|
||||
|
||||
// 创建工作簿
|
||||
const workbook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, "谐波放大事件");
|
||||
|
||||
// 写出文件
|
||||
XLSX.writeFile(workbook, "谐波放大事件" + ".xlsx");
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ open });
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@use "@/assets/scss/index.scss";
|
||||
|
||||
.tableBox {
|
||||
padding: 0px !important;
|
||||
}
|
||||
|
||||
.formBox {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.formLeft {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
1384
src/views/SagTraceResult_WX/components/eventStatistics/index.vue
Normal file
1384
src/views/SagTraceResult_WX/components/eventStatistics/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,667 @@
|
||||
<template>
|
||||
<!-- 配网计算 -->
|
||||
<splitpanes style="height: 100%" class="default-theme" id="navigation-splitpanes">
|
||||
<pane :size="20">
|
||||
<SystemTree :showSelect="false" @node-click="handleNodeClick" @init="handleNodeClick"></SystemTree>
|
||||
</pane>
|
||||
|
||||
<pane style="background-color: rgba(44, 46, 60, 0.1)" :size="100 - size">
|
||||
|
||||
<el-form :model="form" inline label-width="auto">
|
||||
<el-form-item label="谐波类型">
|
||||
<el-radio-group v-model="form.type">
|
||||
<el-radio-button label="谐波电压" size="small" value="1" />
|
||||
<el-radio-button label="谐波电流" size="small" value="0" />
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="谐波次数">
|
||||
<el-select v-model="form.index" filterable multiple :multiple-limit="5" collapse-tags
|
||||
collapse-tags-tooltip clearable placeholder="请选择次数" style="width: 200px" size="small">
|
||||
<el-option v-for="item in 49" :key="item" :label="item + 1 + '次'" :value="item + 1"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<!-- <el-button type="primary" icon="el-icon-Plus" @click="push('/admin/division/aListOfLoadData')">
|
||||
新增
|
||||
</el-button> -->
|
||||
<el-button type="primary" :icon="Select" @click="submit" size="small">确定</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-tabs v-model="activeName" v-if="showTabs" style="height: 740px">
|
||||
<el-tab-pane v-for="(item, index) in tabList" :key="item" :label="item.label" :name="index"
|
||||
style="height: 100%">
|
||||
<div>
|
||||
<div>
|
||||
<span style="color: #fff">时间范围</span>
|
||||
<el-date-picker v-model="item.time" class="mr10 ml10" type="daterange"
|
||||
start-placeholder="起始时间" end-placeholder="结束时间" format="YYYY-MM-DD"
|
||||
date-format="YYYY-MM-DD" time-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
|
||||
:disabled-date="handleDisabledDate" size="small" />
|
||||
<el-button type="primary" :icon="CaretRight" @click="execute(item, index)" size="small">
|
||||
执行
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="item.showEcahr == 1" class="harmonicButton">
|
||||
<el-form :inline="true" v-model="item.form">
|
||||
<el-form-item label="限值" v-if="item.showDynamic">
|
||||
<el-input v-model="item.form.limit" placeholder="请选择限值" disabled
|
||||
style="width: 200px" size="small">
|
||||
<template #append>
|
||||
<el-button :icon="Edit" :class="[code == 0 ? 'frontBox' : '']"
|
||||
@click="setCode(0)" size="small" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间点一" v-if="item.showDynamic">
|
||||
<el-input v-model="item.form.time1" placeholder="请选择时间点一" disabled
|
||||
style="width: 200px" size="small">
|
||||
<template #append>
|
||||
<el-button :icon="Edit" :class="[code == 1 ? 'frontBox' : '']"
|
||||
@click="setCode(1)" size="small" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间点二" v-if="item.showDynamic">
|
||||
<el-input v-model="item.form.time2" placeholder="请选择时间点二" disabled
|
||||
style="width: 200px" size="small">
|
||||
<template #append>
|
||||
<el-button :icon="Edit" :class="[code == 2 ? 'frontBox' : '']"
|
||||
@click="setCode(2)" size="small" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-button type="primary" :icon="Document" @click="generateFn" v-if="!item.showDynamic"
|
||||
size="small">
|
||||
生成动态谐波责任数据
|
||||
</el-button>
|
||||
<el-button type="primary" :icon="Document" v-else @click="generateMetrics" size="small">
|
||||
生成谐波责任指标
|
||||
</el-button>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="box" v-loading="loading" element-loading-background="#343849c7">
|
||||
<MyEChart :options="item.options" v-if="item.showEcahr == 1" @group="group" />
|
||||
<el-empty description="时间范围内无谐波数据" v-if="item.showEcahr == 2" />
|
||||
</div>
|
||||
<!-- 生成动态谐波责任数据 -->
|
||||
<div class="box boxTab" v-loading="loading1" element-loading-background="#343849c7">
|
||||
<MyEChart :options="item.dynamicOptions" style="flex: 1" v-if="item.showDynamic" />
|
||||
<div style="width: 500px" v-if="item.showDynamic" class="tableBox">
|
||||
<el-table :scrollbar-always-on="true" ref="tableRef" :data="item.dynamicData"
|
||||
height="280px" size="small" :header-cell-style="{ textAlign: 'center' }" border>
|
||||
<el-table-column prop="customerName" align="center" label="用户名(用户号)" />
|
||||
<el-table-column prop="responsibilityData" align="center" label="责任数据(%)"
|
||||
width="120">
|
||||
<template #default="scope">
|
||||
{{
|
||||
Math.floor(scope.row.responsibilityData * 10000) /
|
||||
10000
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</pane>
|
||||
</splitpanes>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, reactive } from "vue";
|
||||
import "splitpanes/dist/splitpanes.css";
|
||||
import { Splitpanes, Pane } from "splitpanes";
|
||||
import SystemTree from "@/components/tree/systemTree.vue";
|
||||
import { Edit, Right } from "@element-plus/icons-vue";
|
||||
import MyEChart from "@/components/echarts/MyEchart.vue";
|
||||
import { timeFormat } from "@/utils/common";
|
||||
import { yMethod } from "@/utils/echartMethod";
|
||||
import { Select, CaretRight, Document } from "@element-plus/icons-vue";
|
||||
import {
|
||||
getHistoryHarmData,
|
||||
getDynamicData,
|
||||
getResponsibilityData,
|
||||
} from "@/api/manage_wx";
|
||||
const visible = ref(false);
|
||||
const size = ref(0);
|
||||
const dotList: any = ref({});
|
||||
const form: any = reactive({
|
||||
type: "1",
|
||||
index: [],
|
||||
});
|
||||
|
||||
const code = ref(3);
|
||||
const xAxisData = ref([]);
|
||||
const loading = ref(false);
|
||||
const loading1 = ref(false);
|
||||
const tabList: any = ref([]);
|
||||
const activeName = ref(0);
|
||||
const xValue = ref("");
|
||||
const showTabs = ref(false);
|
||||
|
||||
// 设置时间
|
||||
const timeFrame = ref(["", ""]);
|
||||
|
||||
const openDialog = () => {
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
const handleNodeClick = (data: any) => {
|
||||
if (data.level == 6) {
|
||||
dotList.value = data;
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// 处理日期禁用逻辑
|
||||
const handleDisabledDate = (date) => {
|
||||
return date.getTime() > Date.now();
|
||||
};
|
||||
// 这是按钮变色
|
||||
const setCode = (num: number) => {
|
||||
if (code.value == num) {
|
||||
return (code.value = 3);
|
||||
}
|
||||
code.value = num;
|
||||
};
|
||||
|
||||
// 确定
|
||||
const submit = () => {
|
||||
|
||||
if (form.index.length == 0) {
|
||||
return ElMessage.warning("请选择谐波次数");
|
||||
}
|
||||
|
||||
if (form.index.length == 0) {
|
||||
showTabs.value = false;
|
||||
} else {
|
||||
|
||||
showTabs.value = true;
|
||||
let list = JSON.parse(JSON.stringify(form.index)).sort((a, b) => a - b);
|
||||
tabList.value = [];
|
||||
list.forEach((item: any) => {
|
||||
tabList.value.push({
|
||||
label: item + "次谐波",
|
||||
key: item,
|
||||
showExecute: false,
|
||||
form: {
|
||||
limit: "",
|
||||
time1: "",
|
||||
time2: "",
|
||||
},
|
||||
showEcahr: 3, //1显示echart 2显示无数据 3什么都没有
|
||||
options: {},
|
||||
dynamicOptions: {}, //动态echarts
|
||||
dynamicList: {}, //动态echarts
|
||||
showDynamic: false, //动态执行展示
|
||||
});
|
||||
});
|
||||
code.value = 3;
|
||||
activeName.value = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// 执行
|
||||
const execute = async (item: any, index: number) => {
|
||||
tabList.value[activeName.value].showDynamic = false;
|
||||
loading.value = true;
|
||||
await getHistoryHarmData({
|
||||
searchBeginTime: item.time[0],
|
||||
searchEndTime: item.time[1],
|
||||
type: form.type,
|
||||
time: item.key,
|
||||
lineId: dotList.value.id,
|
||||
})
|
||||
.then((res: any) => {
|
||||
if (res.code == "A0000") {
|
||||
let [min, max] = yMethod(
|
||||
res.data.historyData.map((item: any) => item.value + 0.1)
|
||||
);
|
||||
xAxisData.value = res.data.historyData.map((item: any) => item.time);
|
||||
tabList.value[index].options = {
|
||||
title: {
|
||||
text: "",
|
||||
},
|
||||
xAxis: {
|
||||
type: "time",
|
||||
name: "时间",
|
||||
axisLabel: {
|
||||
formatter: {
|
||||
day: "{MM}-{dd}",
|
||||
month: "{MM}",
|
||||
year: "{yyyy}",
|
||||
},
|
||||
},
|
||||
// 刻度线样式
|
||||
axisTick: {
|
||||
lineStyle: {
|
||||
color: "#fff", // 刻度线白色
|
||||
},
|
||||
},
|
||||
|
||||
// 轴线样式
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "#fff", // 轴线白色
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
formatter(params: any) {
|
||||
xValue.value = params[0].value[0];
|
||||
let str = params[0].value[0] + "<br/>";
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
str =
|
||||
str +
|
||||
params[i].marker +
|
||||
params[i].seriesName +
|
||||
":" +
|
||||
params[i].value[1] +
|
||||
"<br/>";
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
top: 30,
|
||||
right: 50,
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
yAxis: {
|
||||
name: form.type == 1 ? "%" : "A",
|
||||
min: min,
|
||||
max: max,
|
||||
},
|
||||
toolbox: {
|
||||
show: false,
|
||||
},
|
||||
|
||||
series: [
|
||||
{
|
||||
name: item.key + (form.type == 1 ? "次谐波电压" : "次谐波电流"),
|
||||
data: res.data.historyData.map((item: any) => [
|
||||
item.time,
|
||||
Math.floor(item.value * 10000) / 10000,
|
||||
]),
|
||||
type: "line",
|
||||
symbol: "none",
|
||||
markLine: {
|
||||
symbol: "none", // 去除箭头
|
||||
label: {
|
||||
show: false, // 隐藏标签
|
||||
},
|
||||
data: [
|
||||
{
|
||||
yAxis: "",
|
||||
},
|
||||
{
|
||||
xAxis: "",
|
||||
},
|
||||
{
|
||||
xAxis: "",
|
||||
},
|
||||
],
|
||||
// 样式配置
|
||||
lineStyle: {
|
||||
color: "red",
|
||||
type: "dashed", // 虚线
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
tabList.value[index].showEcahr = 1; //显示echart
|
||||
} else {
|
||||
ElMessage.warning(res.message);
|
||||
tabList.value[index].showEcahr = 2;
|
||||
}
|
||||
loading.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
tabList.value[index].showEcahr = 2;
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
const resDataId = ref("");
|
||||
// 生成动态谐波责任数据
|
||||
const generateFn = async () => {
|
||||
loading1.value = true;
|
||||
await getDynamicData({
|
||||
lineId: dotList.value.id,
|
||||
searchBeginTime: tabList.value[activeName.value].time[0],
|
||||
searchEndTime: tabList.value[activeName.value].time[1],
|
||||
time: tabList.value[activeName.value].key,
|
||||
type: form.type,
|
||||
})
|
||||
.then((res: any) => {
|
||||
if (res.code == "A0000") {
|
||||
resDataId.value = res.data.responsibilityDataIndex;
|
||||
tabList.value[activeName.value].dynamicData = res.data.responsibilities;
|
||||
let [min, max] = yMethod(
|
||||
res.data.datas.map((item: any) => item.valueDatas).flat()
|
||||
);
|
||||
let series: any[] = [];
|
||||
let time: any[] = res.data.timeDatas.map((item: any) =>
|
||||
timeFormat(item)
|
||||
);
|
||||
res.data.datas.forEach((item: any) => {
|
||||
series.push({
|
||||
name: item.customerName,
|
||||
data: item.valueDatas.map((k: any, i: number) => [
|
||||
time[i],
|
||||
Math.floor(k * 10000) / 10000,
|
||||
]),
|
||||
type: "line",
|
||||
smooth: true,
|
||||
symbol: "none",
|
||||
});
|
||||
});
|
||||
|
||||
tabList.value[activeName.value].dynamicOptions = {
|
||||
title: {
|
||||
text: "",
|
||||
},
|
||||
xAxis: {
|
||||
type: "time",
|
||||
name: "时间",
|
||||
axisLabel: {
|
||||
formatter: {
|
||||
day: "{MM}-{dd}",
|
||||
month: "{MM}",
|
||||
year: "{yyyy}",
|
||||
},
|
||||
},
|
||||
// 刻度线样式
|
||||
axisTick: {
|
||||
lineStyle: {
|
||||
color: "#fff", // 刻度线白色
|
||||
},
|
||||
},
|
||||
|
||||
// 轴线样式
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "#fff", // 轴线白色
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
formatter(params: any) {
|
||||
let str = params[0].value[0] + "<br/>";
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
str =
|
||||
str +
|
||||
params[i].marker +
|
||||
params[i].seriesName +
|
||||
":" +
|
||||
params[i].value[1] +
|
||||
"<br/>";
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
top: 30,
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
yAxis: {
|
||||
name: form.type == 1 ? "%" : "A",
|
||||
min: min,
|
||||
max: max,
|
||||
},
|
||||
toolbox: {
|
||||
show: false,
|
||||
},
|
||||
|
||||
options: {
|
||||
series: series,
|
||||
},
|
||||
};
|
||||
|
||||
tabList.value[activeName.value].showDynamic = true;
|
||||
} else {
|
||||
ElMessage.warning(res.message);
|
||||
}
|
||||
loading1.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading1.value = false;
|
||||
});
|
||||
loading1.value = false;
|
||||
};
|
||||
|
||||
// 生成指标
|
||||
const generateMetrics = async () => {
|
||||
if (tabList.value[activeName.value].form.limit == "")
|
||||
return ElMessage.warning("请选择限值!");
|
||||
if (tabList.value[activeName.value].form.time1 == "")
|
||||
return ElMessage.warning("请选择时间一!");
|
||||
if (tabList.value[activeName.value].form.time2 == "")
|
||||
return ElMessage.warning("请选择时间二!");
|
||||
loading1.value = true;
|
||||
await getResponsibilityData({
|
||||
limitEndTime: tabList.value[activeName.value].form.time2,
|
||||
limitStartTime: tabList.value[activeName.value].form.time1,
|
||||
limitValue: tabList.value[activeName.value].form.limit,
|
||||
resDataId: resDataId.value,
|
||||
time: tabList.value[activeName.value].key,
|
||||
type: form.type,
|
||||
})
|
||||
.then((res: any) => {
|
||||
tabList.value[activeName.value].dynamicData = res.data.responsibilities;
|
||||
let [min, max] = yMethod(
|
||||
res.data.datas.map((item: any) => item.valueDatas).flat()
|
||||
);
|
||||
let series: any[] = [];
|
||||
let time: any[] = res.data.timeDatas.map((item: any) => timeFormat(item));
|
||||
res.data.datas.forEach((item: any) => {
|
||||
series.push({
|
||||
name: item.customerName,
|
||||
data: item.valueDatas.map((k: any, i: number) => [
|
||||
time[i],
|
||||
Math.floor(k * 10000) / 10000,
|
||||
]),
|
||||
type: "line",
|
||||
symbol: "none",
|
||||
});
|
||||
});
|
||||
|
||||
tabList.value[activeName.value].dynamicOptions = {
|
||||
title: {
|
||||
text: "",
|
||||
},
|
||||
xAxis: {
|
||||
type: "time",
|
||||
name: "时间",
|
||||
axisLabel: {
|
||||
formatter: {
|
||||
day: "{MM}-{dd}",
|
||||
month: "{MM}",
|
||||
year: "{yyyy}",
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
formatter(params: any) {
|
||||
let str = params[0].value[0] + "<br/>";
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
str =
|
||||
str +
|
||||
params[i].marker +
|
||||
params[i].seriesName +
|
||||
":" +
|
||||
params[i].value[1] +
|
||||
"<br/>";
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
top: 30,
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
yAxis: {
|
||||
name: form.type == 1 ? "%" : "A",
|
||||
min: min,
|
||||
max: max,
|
||||
},
|
||||
toolbox: {
|
||||
show: false,
|
||||
},
|
||||
|
||||
options: {
|
||||
series: series,
|
||||
},
|
||||
};
|
||||
|
||||
tabList.value[activeName.value].showDynamic = true;
|
||||
})
|
||||
.catch(() => {
|
||||
loading1.value = false;
|
||||
});
|
||||
loading1.value = false;
|
||||
};
|
||||
// 监听echart点击
|
||||
const group = (chart: any, myChartDom: any) => {
|
||||
myChartDom.addEventListener("click", function (event: any) {
|
||||
// 获取点击位置相对于图表容器的坐标
|
||||
const rect = myChartDom.getBoundingClientRect();
|
||||
const x = event.clientX - rect.left;
|
||||
const y = event.clientY - rect.top;
|
||||
const pointInPixel = [x, y];
|
||||
// 转换为逻辑坐标(相对于图表坐标系)
|
||||
const pointInGrid = chart.convertFromPixel({ gridIndex: 0 }, pointInPixel);
|
||||
// 计算X轴和Y轴的对应数据
|
||||
|
||||
// 处理X轴数据(分类轴)
|
||||
|
||||
// 处理Y轴数据(数值轴)
|
||||
let yValue = pointInGrid[1].toFixed(4);
|
||||
// xValue = timeFormat(pointInGrid[0].toFixed(0) - 0)
|
||||
if (code.value == 0) {
|
||||
tabList.value[activeName.value].form.limit = yValue;
|
||||
tabList.value[activeName.value].options.series[0].markLine.data[0].yAxis =
|
||||
yValue;
|
||||
chart.setOption(tabList.value[activeName.value].options);
|
||||
} else if (code.value == 1) {
|
||||
tabList.value[activeName.value].form.time1 = xValue.value;
|
||||
tabList.value[activeName.value].options.series[0].markLine.data[1].xAxis =
|
||||
xValue.value;
|
||||
chart.setOption(tabList.value[activeName.value].options);
|
||||
} else if (code.value == 2) {
|
||||
tabList.value[activeName.value].form.time2 = xValue.value;
|
||||
tabList.value[activeName.value].options.series[0].markLine.data[2].xAxis =
|
||||
xValue.value;
|
||||
chart.setOption(tabList.value[activeName.value].options);
|
||||
}
|
||||
// 控制台输出详细信息
|
||||
// console.log('点击事件详情:', {
|
||||
// X轴数据: xValue,
|
||||
// Y轴数据: yValue
|
||||
// })
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
const dom = document.getElementById("navigation-splitpanes");
|
||||
if (dom) {
|
||||
size.value = Math.round((180 / dom.offsetHeight) * 100);
|
||||
}
|
||||
|
||||
|
||||
if (!dotList.value || !dotList.value.alias) {
|
||||
dotList.value = { alias: "请选择监测点位" };
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@/assets/scss/index.scss";
|
||||
|
||||
.box {
|
||||
// height: calc((100vh - 190px) / 2);
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.boxTab {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.harmonicButton {
|
||||
height: 42px;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__content) {
|
||||
height: calc(100vh - 265px);
|
||||
}
|
||||
|
||||
:deep(.el-input-group__append, .el-input-group__prepend) {
|
||||
background-color: #ffffff00;
|
||||
padding: 0 17px;
|
||||
}
|
||||
|
||||
:deep(.frontBox) {
|
||||
background-color: var(--el-color-primary) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
::v-deep(.el-tabs__item) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep(.el-tabs__item.is-active) {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
::v-deep(.el-tabs__nav-wrap::after) {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
::v-deep(.el-tabs__active-bar) {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
::v-deep(.splitpanes__splitter) {
|
||||
background-color: rgba(44, 46, 60, 0.1) !important;
|
||||
|
||||
&:before {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
&:after {
|
||||
background-color: #fffFFF80 !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep(.el-form-item) {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,982 @@
|
||||
<template>
|
||||
<!-- 配网计算 -->
|
||||
<splitpanes
|
||||
style="height: 100%"
|
||||
class="default-theme"
|
||||
id="navigation-splitpanes"
|
||||
>
|
||||
<pane :size="20">
|
||||
<PointTree
|
||||
:showSelect="false"
|
||||
@node-click="handleNodeClick"
|
||||
@init="handleNodeClick"
|
||||
></PointTree>
|
||||
</pane>
|
||||
|
||||
<pane style="background-color: rgba(44, 46, 60, 0.1)" :size="100 - size">
|
||||
<el-form :model="form" inline label-width="auto">
|
||||
<el-form-item label="用采用户">
|
||||
<el-tree-select
|
||||
v-model="form.userList"
|
||||
:data="dataTree"
|
||||
multiple
|
||||
filterable
|
||||
show-checkbox
|
||||
ref="treeRef"
|
||||
:props="defaultProps"
|
||||
node-key="id"
|
||||
size="small"
|
||||
popper-class="tree-select-popper"
|
||||
:popper-append-to-body="false"
|
||||
:default-expanded-keys="expandedKeys"
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
clearable
|
||||
class="wide-tree-select"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="谐波类型">
|
||||
<el-radio-group v-model="form.type">
|
||||
<el-radio-button label="谐波电压" size="small" value="1" />
|
||||
<el-radio-button label="谐波电流" size="small" value="0" />
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="谐波次数">
|
||||
<el-select
|
||||
v-model="form.index"
|
||||
filterable
|
||||
multiple
|
||||
:multiple-limit="5"
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
clearable
|
||||
placeholder="请选择次数"
|
||||
style="width: 200px"
|
||||
size="small"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in 49"
|
||||
:key="item"
|
||||
:label="item + 1 + '次'"
|
||||
:value="item + 1"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="负荷数据">
|
||||
<el-select v-model="form.loadDataId" clearable filterable placeholder="请选择负荷数据" style="width: 200px"
|
||||
size="small">
|
||||
<el-option v-for="item in loadDataOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item> -->
|
||||
<el-form-item>
|
||||
<!-- <el-button type="primary" icon="el-icon-Plus" @click="push('/admin/division/aListOfLoadData')">
|
||||
新增
|
||||
</el-button> -->
|
||||
<el-button type="primary" :icon="Select" @click="submit" size="small"
|
||||
>确定</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-tabs v-model="activeName" v-if="showTabs" style="height: 740px">
|
||||
<el-tab-pane
|
||||
v-for="(item, index) in tabList"
|
||||
:key="item"
|
||||
:label="item.label"
|
||||
:name="index"
|
||||
style="height: 100%"
|
||||
>
|
||||
<div>
|
||||
<div>
|
||||
<span style="color: #fff">时间范围</span>
|
||||
<el-date-picker
|
||||
v-model="item.time"
|
||||
class="mr10 ml10"
|
||||
type="daterange"
|
||||
start-placeholder="起始时间"
|
||||
end-placeholder="结束时间"
|
||||
format="YYYY-MM-DD"
|
||||
date-format="YYYY-MM-DD"
|
||||
time-format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
:disabled-date="handleDisabledDate"
|
||||
size="small"
|
||||
/>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="CaretRight"
|
||||
@click="execute(item, index)"
|
||||
size="small"
|
||||
>
|
||||
执行
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="item.showEcahr == 1" class="harmonicButton">
|
||||
<el-form :inline="true" v-model="item.form">
|
||||
<el-form-item label="限值" v-if="item.showDynamic">
|
||||
<el-input
|
||||
v-model="item.form.limit"
|
||||
placeholder="请选择限值"
|
||||
disabled
|
||||
style="width: 200px"
|
||||
size="small"
|
||||
>
|
||||
<template #append>
|
||||
<el-button
|
||||
:icon="Edit"
|
||||
:class="[code == 0 ? 'frontBox' : '']"
|
||||
@click="setCode(0)"
|
||||
size="small"
|
||||
/>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间点一" v-if="item.showDynamic">
|
||||
<el-input
|
||||
v-model="item.form.time1"
|
||||
placeholder="请选择时间点一"
|
||||
disabled
|
||||
style="width: 200px"
|
||||
size="small"
|
||||
>
|
||||
<template #append>
|
||||
<el-button
|
||||
:icon="Edit"
|
||||
:class="[code == 1 ? 'frontBox' : '']"
|
||||
@click="setCode(1)"
|
||||
size="small"
|
||||
/>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间点二" v-if="item.showDynamic">
|
||||
<el-input
|
||||
v-model="item.form.time2"
|
||||
placeholder="请选择时间点二"
|
||||
disabled
|
||||
style="width: 200px"
|
||||
size="small"
|
||||
>
|
||||
<template #append>
|
||||
<el-button
|
||||
:icon="Edit"
|
||||
:class="[code == 2 ? 'frontBox' : '']"
|
||||
@click="setCode(2)"
|
||||
size="small"
|
||||
/>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Document"
|
||||
@click="generateFn"
|
||||
v-if="!item.showDynamic"
|
||||
size="small"
|
||||
>
|
||||
生成动态谐波责任数据
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Document"
|
||||
v-else
|
||||
@click="generateMetrics"
|
||||
size="small"
|
||||
>
|
||||
生成谐波责任指标
|
||||
</el-button>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="box"
|
||||
v-loading="loading"
|
||||
element-loading-background="#343849c7"
|
||||
>
|
||||
<MyEChart
|
||||
:options="item.options"
|
||||
v-if="item.showEcahr == 1"
|
||||
@group="group"
|
||||
/>
|
||||
<el-empty
|
||||
description="时间范围内无谐波数据"
|
||||
v-if="item.showEcahr == 2"
|
||||
/>
|
||||
</div>
|
||||
<!-- 生成动态谐波责任数据 -->
|
||||
<div
|
||||
class="box boxTab"
|
||||
v-loading="loading1"
|
||||
element-loading-background="#343849c7"
|
||||
>
|
||||
<MyEChart
|
||||
:options="item.dynamicOptions"
|
||||
style="flex: 1"
|
||||
v-if="item.showDynamic"
|
||||
/>
|
||||
<div
|
||||
style="width: 500px"
|
||||
v-if="item.showDynamic"
|
||||
class="tableBox"
|
||||
>
|
||||
<el-table
|
||||
:scrollbar-always-on="true"
|
||||
ref="tableRef"
|
||||
:data="item.dynamicData"
|
||||
height="280px"
|
||||
size="small"
|
||||
:header-cell-style="{ textAlign: 'center' }"
|
||||
border
|
||||
>
|
||||
<el-table-column
|
||||
prop="customerName"
|
||||
align="center"
|
||||
label="用户名(用户号)"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="responsibilityData"
|
||||
align="center"
|
||||
label="责任数据(%)"
|
||||
width="120"
|
||||
>
|
||||
<template #default="scope">
|
||||
{{
|
||||
Math.floor(scope.row.responsibilityData * 10000) / 10000
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</pane>
|
||||
</splitpanes>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, reactive, watch } from "vue";
|
||||
import "splitpanes/dist/splitpanes.css";
|
||||
import { Splitpanes, Pane } from "splitpanes";
|
||||
import PointTree from "@/components/tree/pointTree.vue";
|
||||
import { Edit, Right } from "@element-plus/icons-vue";
|
||||
import MyEChart from "@/components/echarts/MyEchart.vue";
|
||||
import { timeFormat } from "@/utils/common";
|
||||
import { yMethod } from "@/utils/echartMethod";
|
||||
import { Select, CaretRight, Document } from "@element-plus/icons-vue";
|
||||
import {
|
||||
userDataList,
|
||||
getHistoryHarmData,
|
||||
getDynamicData,
|
||||
getResponsibilityData,
|
||||
getTerminalTreeForFive,
|
||||
} from "@/api/manage_wx";
|
||||
import { useStore } from "vuex";
|
||||
|
||||
const store = useStore();
|
||||
const emit = defineEmits(["setTitle", "init"]); // 打开弹窗
|
||||
const visible = ref(false);
|
||||
const size = ref(0);
|
||||
const dotList: any = ref({});
|
||||
const form: any = reactive({
|
||||
type: "1",
|
||||
index: [],
|
||||
userList: [],
|
||||
});
|
||||
|
||||
const loadDataOptions: any = ref([]);
|
||||
const code = ref(3);
|
||||
const xAxisData = ref([]);
|
||||
const loading = ref(false);
|
||||
const loading1 = ref(false);
|
||||
const tabList: any = ref([]);
|
||||
const activeName = ref(0);
|
||||
const xValue = ref("");
|
||||
const showTabs = ref(false);
|
||||
|
||||
// 设置时间
|
||||
const timeFrame = ref(["", ""]);
|
||||
|
||||
const openDialog = () => {
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
// 添加已选择的节点ID列表
|
||||
const selectedNodeIds = ref<string[]>([]);
|
||||
|
||||
const handleNodeClick = (data: any) => {
|
||||
if (data.level == 6) {
|
||||
dotList.value = data;
|
||||
setTimeout(() => {
|
||||
emit("setTitle", data.alias);
|
||||
}, 0);
|
||||
// 保存选择的节点ID
|
||||
if (data.id) {
|
||||
selectedNodeIds.value = [data.id];
|
||||
}
|
||||
// 如果右侧已经选择了这个节点,则从右侧选择中移除
|
||||
const selectedUserIdIndex = form.userList.indexOf(data.id);
|
||||
if (selectedUserIdIndex > -1) {
|
||||
// 创建新数组以触发视图更新
|
||||
form.userList = form.userList.filter((id: string) => id !== data.id);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 添加一个方法来更新树节点的禁用状态
|
||||
const updateTreeDataDisabledState = () => {
|
||||
if (!dataTree.value || dataTree.value.length === 0) return;
|
||||
|
||||
const disableNodes = (nodes: any[]) => {
|
||||
if (!nodes || nodes.length === 0) return;
|
||||
|
||||
nodes.forEach((node) => {
|
||||
// 如果节点ID在已选择列表中,则禁用
|
||||
if (selectedNodeIds.value.includes(node.id)) {
|
||||
node.disabled = true;
|
||||
} else {
|
||||
// 如果之前被禁用但现在不在选择列表中,则启用
|
||||
if (node.hasOwnProperty("disabled")) {
|
||||
node.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 递归处理子节点
|
||||
if (node.children && node.children.length > 0) {
|
||||
disableNodes(node.children);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
disableNodes(dataTree.value);
|
||||
};
|
||||
|
||||
// 监听 selectedNodeIds 的变化,更新树节点状态
|
||||
watch(
|
||||
selectedNodeIds,
|
||||
() => {
|
||||
updateTreeDataDisabledState();
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// 处理日期禁用逻辑
|
||||
const handleDisabledDate = (date) => {
|
||||
// 定义时间边界
|
||||
const startLimit = new Date(timeFrame.value[0]).getTime() - 86400000; //向前推1天
|
||||
const endLimit = new Date(timeFrame.value[1]).setHours(23, 59, 59, 999);
|
||||
|
||||
// 如果日期不存在(选择今天时可能出现),不禁用
|
||||
if (!date) return false;
|
||||
|
||||
// 禁用 2025-08-01 之前和 2025-08-31 之后的日期
|
||||
return date.getTime() < startLimit || date.getTime() > endLimit;
|
||||
};
|
||||
// 这是按钮变色
|
||||
const setCode = (num: number) => {
|
||||
if (code.value == num) {
|
||||
return (code.value = 3);
|
||||
}
|
||||
code.value = num;
|
||||
};
|
||||
|
||||
// 确定
|
||||
const submit = () => {
|
||||
if (form.index.length == 0) {
|
||||
return ElMessage.warning("请选择谐波次数");
|
||||
}
|
||||
|
||||
if (form.index.length == 0) {
|
||||
showTabs.value = false;
|
||||
} else {
|
||||
showTabs.value = true;
|
||||
let list = JSON.parse(JSON.stringify(form.index)).sort((a, b) => a - b);
|
||||
tabList.value = [];
|
||||
list.forEach((item: any) => {
|
||||
tabList.value.push({
|
||||
label: item + "次谐波",
|
||||
key: item,
|
||||
showExecute: false,
|
||||
form: {
|
||||
limit: "",
|
||||
time1: "",
|
||||
time2: "",
|
||||
},
|
||||
showEcahr: 3, //1显示echart 2显示无数据 3什么都没有
|
||||
options: {},
|
||||
dynamicOptions: {}, //动态echarts
|
||||
dynamicList: {}, //动态echarts
|
||||
showDynamic: false, //动态执行展示
|
||||
});
|
||||
});
|
||||
code.value = 3;
|
||||
activeName.value = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// 执行
|
||||
const execute = async (item: any, index: number) => {
|
||||
if (item.time == undefined) {
|
||||
return ElMessage.warning("请选择时间范围");
|
||||
}
|
||||
tabList.value[activeName.value].showDynamic = false;
|
||||
loading.value = true;
|
||||
await getHistoryHarmData({
|
||||
searchBeginTime: item.time[0],
|
||||
searchEndTime: item.time[1],
|
||||
type: form.type,
|
||||
time: item.key,
|
||||
lineId: dotList.value.id,
|
||||
})
|
||||
.then((res: any) => {
|
||||
if (res.code == "A0000") {
|
||||
let [min, max] = yMethod(
|
||||
res.data.historyData.map((item: any) => item.value + 0.1)
|
||||
);
|
||||
xAxisData.value = res.data.historyData.map((item: any) => item.time);
|
||||
tabList.value[index].options = {
|
||||
title: {
|
||||
text: "",
|
||||
},
|
||||
xAxis: {
|
||||
type: "time",
|
||||
name: "时间",
|
||||
axisLabel: {
|
||||
formatter: {
|
||||
day: "{MM}-{dd}",
|
||||
month: "{MM}",
|
||||
year: "{yyyy}",
|
||||
},
|
||||
},
|
||||
// 刻度线样式
|
||||
axisTick: {
|
||||
lineStyle: {
|
||||
color: "#fff", // 刻度线白色
|
||||
},
|
||||
},
|
||||
|
||||
// 轴线样式
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "#fff", // 轴线白色
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
formatter(params: any) {
|
||||
xValue.value = params[0].value[0];
|
||||
let str = params[0].value[0] + "<br/>";
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
str =
|
||||
str +
|
||||
params[i].marker +
|
||||
params[i].seriesName +
|
||||
":" +
|
||||
params[i].value[1] +
|
||||
"<br/>";
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
top: 30,
|
||||
right: 50,
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
yAxis: {
|
||||
name: form.type == 1 ? "%" : "A",
|
||||
min: min,
|
||||
max: max,
|
||||
},
|
||||
toolbox: {
|
||||
show: false,
|
||||
},
|
||||
|
||||
series: [
|
||||
{
|
||||
name: item.key + (form.type == 1 ? "次谐波电压" : "次谐波电流"),
|
||||
data: res.data.historyData.map((item: any) => [
|
||||
item.time,
|
||||
Math.floor(item.value * 10000) / 10000,
|
||||
]),
|
||||
type: "line",
|
||||
symbol: "none",
|
||||
|
||||
markLine: {
|
||||
symbol: "none", // 去除箭头
|
||||
label: {
|
||||
show: false, // 隐藏标签
|
||||
},
|
||||
data: [
|
||||
{
|
||||
yAxis: "",
|
||||
},
|
||||
{
|
||||
xAxis: "",
|
||||
},
|
||||
{
|
||||
xAxis: "",
|
||||
},
|
||||
],
|
||||
// 样式配置
|
||||
lineStyle: {
|
||||
color: "red",
|
||||
type: "dashed", // 虚线
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
tabList.value[index].showEcahr = 1; //显示echart
|
||||
} else {
|
||||
ElMessage.warning(res.message);
|
||||
tabList.value[index].showEcahr = 2;
|
||||
}
|
||||
loading.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
tabList.value[index].showEcahr = 2;
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
const resDataId = ref("");
|
||||
// 生成动态谐波责任数据
|
||||
const generateFn = async () => {
|
||||
if (form.userList.length == 0) {
|
||||
return ElMessage.warning("请选择用采用户");
|
||||
}
|
||||
loading1.value = true;
|
||||
await getDynamicData({
|
||||
userDataId: "123",
|
||||
lineId: dotList.value.id,
|
||||
searchBeginTime: tabList.value[activeName.value].time[0],
|
||||
searchEndTime: tabList.value[activeName.value].time[1],
|
||||
time: tabList.value[activeName.value].key,
|
||||
type: form.type,
|
||||
userList: form.userList,
|
||||
systemType: 1,
|
||||
})
|
||||
.then((res: any) => {
|
||||
if (res.code == "A0000") {
|
||||
resDataId.value = res.data.responsibilityDataIndex;
|
||||
tabList.value[activeName.value].dynamicData = res.data.responsibilities;
|
||||
let [min, max] = yMethod(
|
||||
res.data.datas.map((item: any) => item.valueDatas).flat()
|
||||
);
|
||||
let series: any[] = [];
|
||||
let time: any[] = res.data.timeDatas.map((item: any) =>
|
||||
timeFormat(item)
|
||||
);
|
||||
res.data.datas.forEach((item: any) => {
|
||||
series.push({
|
||||
name: item.customerName,
|
||||
data: item.valueDatas.map((k: any, i: number) => [
|
||||
time[i],
|
||||
Math.floor(k * 10000) / 10000,
|
||||
]),
|
||||
type: "line",
|
||||
symbol: "none",
|
||||
});
|
||||
});
|
||||
|
||||
tabList.value[activeName.value].dynamicOptions = {
|
||||
title: {
|
||||
text: "",
|
||||
},
|
||||
xAxis: {
|
||||
type: "time",
|
||||
name: "时间",
|
||||
axisLabel: {
|
||||
formatter: {
|
||||
day: "{MM}-{dd}",
|
||||
month: "{MM}",
|
||||
year: "{yyyy}",
|
||||
},
|
||||
},
|
||||
// 刻度线样式
|
||||
axisTick: {
|
||||
lineStyle: {
|
||||
color: "#fff", // 刻度线白色
|
||||
},
|
||||
},
|
||||
|
||||
// 轴线样式
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "#fff", // 轴线白色
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
formatter(params: any) {
|
||||
let str = params[0].value[0] + "<br/>";
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
str =
|
||||
str +
|
||||
params[i].marker +
|
||||
params[i].seriesName +
|
||||
":" +
|
||||
params[i].value[1] +
|
||||
"<br/>";
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
top: 30,
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
yAxis: {
|
||||
name: form.type == 1 ? "%" : "A",
|
||||
min: min,
|
||||
max: max,
|
||||
},
|
||||
toolbox: {
|
||||
show: false,
|
||||
},
|
||||
|
||||
options: {
|
||||
series: series,
|
||||
},
|
||||
};
|
||||
|
||||
tabList.value[activeName.value].showDynamic = true;
|
||||
} else {
|
||||
ElMessage.warning(res.message);
|
||||
}
|
||||
loading1.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading1.value = false;
|
||||
});
|
||||
loading1.value = false;
|
||||
};
|
||||
|
||||
// 生成指标
|
||||
const generateMetrics = async () => {
|
||||
if (tabList.value[activeName.value].form.limit == "")
|
||||
return ElMessage.warning("请选择限值!");
|
||||
if (tabList.value[activeName.value].form.time1 == "")
|
||||
return ElMessage.warning("请选择时间一!");
|
||||
if (tabList.value[activeName.value].form.time2 == "")
|
||||
return ElMessage.warning("请选择时间二!");
|
||||
loading1.value = true;
|
||||
await getResponsibilityData({
|
||||
limitEndTime: tabList.value[activeName.value].form.time2,
|
||||
limitStartTime: tabList.value[activeName.value].form.time1,
|
||||
limitValue: tabList.value[activeName.value].form.limit,
|
||||
resDataId: resDataId.value,
|
||||
time: tabList.value[activeName.value].key,
|
||||
type: form.type,
|
||||
})
|
||||
.then((res: any) => {
|
||||
tabList.value[activeName.value].dynamicData = res.data.responsibilities;
|
||||
let [min, max] = yMethod(
|
||||
res.data.datas.map((item: any) => item.valueDatas).flat()
|
||||
);
|
||||
let series: any[] = [];
|
||||
let time: any[] = res.data.timeDatas.map((item: any) => timeFormat(item));
|
||||
res.data.datas.forEach((item: any) => {
|
||||
series.push({
|
||||
name: item.customerName,
|
||||
data: item.valueDatas.map((k: any, i: number) => [
|
||||
time[i],
|
||||
Math.floor(k * 10000) / 10000,
|
||||
]),
|
||||
type: "line",
|
||||
smooth: true,
|
||||
symbol: "none",
|
||||
});
|
||||
});
|
||||
|
||||
tabList.value[activeName.value].dynamicOptions = {
|
||||
title: {
|
||||
text: "",
|
||||
},
|
||||
xAxis: {
|
||||
type: "time",
|
||||
name: "时间",
|
||||
axisLabel: {
|
||||
formatter: {
|
||||
day: "{MM}-{dd}",
|
||||
month: "{MM}",
|
||||
year: "{yyyy}",
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
formatter(params: any) {
|
||||
let str = params[0].value[0] + "<br/>";
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
str =
|
||||
str +
|
||||
params[i].marker +
|
||||
params[i].seriesName +
|
||||
":" +
|
||||
params[i].value[1] +
|
||||
"<br/>";
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
top: 30,
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
yAxis: {
|
||||
name: form.type == 1 ? "%" : "A",
|
||||
min: min,
|
||||
max: max,
|
||||
},
|
||||
toolbox: {
|
||||
show: false,
|
||||
},
|
||||
|
||||
options: {
|
||||
series: series,
|
||||
},
|
||||
};
|
||||
|
||||
tabList.value[activeName.value].showDynamic = true;
|
||||
})
|
||||
.catch(() => {
|
||||
loading1.value = false;
|
||||
});
|
||||
loading1.value = false;
|
||||
};
|
||||
// 监听echart点击
|
||||
const group = (chart: any, myChartDom: any) => {
|
||||
myChartDom.addEventListener("click", function (event: any) {
|
||||
// 获取点击位置相对于图表容器的坐标
|
||||
const rect = myChartDom.getBoundingClientRect();
|
||||
const x = event.clientX - rect.left;
|
||||
const y = event.clientY - rect.top;
|
||||
const pointInPixel = [x, y];
|
||||
// 转换为逻辑坐标(相对于图表坐标系)
|
||||
const pointInGrid = chart.convertFromPixel({ gridIndex: 0 }, pointInPixel);
|
||||
// 计算X轴和Y轴的对应数据
|
||||
|
||||
// 处理X轴数据(分类轴)
|
||||
|
||||
// 处理Y轴数据(数值轴)
|
||||
let yValue = pointInGrid[1].toFixed(4);
|
||||
// xValue = timeFormat(pointInGrid[0].toFixed(0) - 0)
|
||||
if (code.value == 0) {
|
||||
tabList.value[activeName.value].form.limit = yValue;
|
||||
tabList.value[activeName.value].options.series[0].markLine.data[0].yAxis =
|
||||
yValue;
|
||||
chart.setOption(tabList.value[activeName.value].options);
|
||||
} else if (code.value == 1) {
|
||||
tabList.value[activeName.value].form.time1 = xValue.value;
|
||||
tabList.value[activeName.value].options.series[0].markLine.data[1].xAxis =
|
||||
xValue.value;
|
||||
chart.setOption(tabList.value[activeName.value].options);
|
||||
} else if (code.value == 2) {
|
||||
tabList.value[activeName.value].form.time2 = xValue.value;
|
||||
tabList.value[activeName.value].options.series[0].markLine.data[2].xAxis =
|
||||
xValue.value;
|
||||
chart.setOption(tabList.value[activeName.value].options);
|
||||
}
|
||||
// 控制台输出详细信息
|
||||
// console.log('点击事件详情:', {
|
||||
// X轴数据: xValue,
|
||||
// Y轴数据: yValue
|
||||
// })
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
const dom = document.getElementById("navigation-splitpanes");
|
||||
if (dom) {
|
||||
size.value = Math.round((180 / dom.offsetHeight) * 100);
|
||||
}
|
||||
userDataList({
|
||||
pageNum: 1,
|
||||
pageSize: 10000,
|
||||
searchValue: "",
|
||||
}).then((res: any) => {
|
||||
console.log(res.data);
|
||||
loadDataOptions.value = res.data.records;
|
||||
});
|
||||
|
||||
if (!dotList.value || !dotList.value.alias) {
|
||||
dotList.value = { alias: "请选择监测点位" };
|
||||
}
|
||||
});
|
||||
|
||||
const formData = ref({
|
||||
deptIndex: store.state.deptId,
|
||||
});
|
||||
|
||||
const dataTree = ref([]);
|
||||
const expandedKeys = ref([]);
|
||||
|
||||
const defaultProps = {
|
||||
label: "name",
|
||||
value: "id",
|
||||
disabled: "disabled",
|
||||
};
|
||||
|
||||
const treeRef = ref();
|
||||
|
||||
const loadData = () => {
|
||||
let form = JSON.parse(JSON.stringify(formData.value));
|
||||
getTerminalTreeForFive(form).then((res) => {
|
||||
console.log(res);
|
||||
|
||||
res.data = [
|
||||
{
|
||||
name: "电网拓扑",
|
||||
level: -1,
|
||||
id: 0,
|
||||
children: res.data,
|
||||
},
|
||||
];
|
||||
|
||||
// 查找第一层级的最后一个子节点
|
||||
const firstLevelChildren = res.data[0].children;
|
||||
if (firstLevelChildren && firstLevelChildren.length > 0) {
|
||||
let flag = true;
|
||||
|
||||
// 设置节点别名
|
||||
res.data.forEach((item: any) => {
|
||||
item.children.forEach((item2: any) => {
|
||||
item2.children.forEach((item3: any) => {
|
||||
item3.children.forEach((item4: any) => {
|
||||
item4.children.forEach((item5: any) => {
|
||||
if (item5.level == 7) {
|
||||
item5.children.forEach((item6: any) => {
|
||||
item6.disabled = false;
|
||||
item6.alias = `${item.name}>${item2.name}>${item3.name}>${item4.name}>${item5.name}>${item6.name}`;
|
||||
});
|
||||
} else {
|
||||
if (flag) {
|
||||
expandedKeys.value = [item5.id];
|
||||
treeRef.value.setCurrentKey(item5.id);
|
||||
emit("init", item5);
|
||||
flag = false;
|
||||
}
|
||||
item5.disabled = false;
|
||||
item5.alias = `${item.name}>${item2.name}>${item3.name}>${item4.name}>${item5.name}`;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
dataTree.value = res.data;
|
||||
|
||||
// 更新禁用状态
|
||||
updateTreeDataDisabledState();
|
||||
});
|
||||
};
|
||||
|
||||
loadData();
|
||||
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@/assets/scss/index.scss";
|
||||
|
||||
.box {
|
||||
// height: calc((100vh - 190px) / 2);
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.boxTab {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.harmonicButton {
|
||||
height: 42px;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__content) {
|
||||
height: calc(100vh - 265px);
|
||||
}
|
||||
|
||||
:deep(.el-input-group__append, .el-input-group__prepend) {
|
||||
background-color: #ffffff00;
|
||||
padding: 0 17px;
|
||||
}
|
||||
|
||||
:deep(.frontBox) {
|
||||
background-color: var(--el-color-primary) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
::v-deep(.el-tabs__item) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep(.el-tabs__item.is-active) {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
::v-deep(.el-tabs__nav-wrap::after) {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
::v-deep(.el-tabs__active-bar) {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
::v-deep(.splitpanes__splitter) {
|
||||
background-color: rgba(44, 46, 60, 0.1) !important;
|
||||
|
||||
&:before {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
&:after {
|
||||
background-color: #ffffff80 !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep(.el-form-item) {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.currentPosition {
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
right: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
// 树选择器下拉面板样式
|
||||
::v-deep(.tree-select-popper) {
|
||||
.el-select-dropdown__wrap {
|
||||
width: 400px; /* 设置你想要的宽度 */
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep(.el-tag__content){
|
||||
max-width: 90px;
|
||||
}
|
||||
|
||||
/* 树选择器本身的宽度控制 */
|
||||
::v-deep(.wide-tree-select) {
|
||||
width: 200px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,230 @@
|
||||
<!-- 详情 -->
|
||||
<template>
|
||||
<el-dialog v-model="visible" :close-on-click-modal="false" title="详情" draggable width="1600px"
|
||||
@close="handleCloseDialog" style="height: 800px">
|
||||
<div class="default-main">
|
||||
<div class="title_1">
|
||||
<span class="monitoring-point">
|
||||
{{ props.detailsQuery.name || "" }}</span>
|
||||
</div>
|
||||
|
||||
<el-tabs v-model="activeName" @tab-change="generateFn">
|
||||
<el-tab-pane v-for="(item, index) in tabList" :key="index" :label="item.name + '次谐波'" style="height: 100%"
|
||||
:name="index" v-loading="loading">
|
||||
<div style="height: 680px; overflow-y: auto">
|
||||
<div class="box mb10" v-for="(value, i) in item.dynamicOptions" :key="i">
|
||||
<div class="boxTab">
|
||||
<MyEChart :options="item.dynamicOptions[i]" style="flex: 1" :style="{
|
||||
height: `calc((680px) / ${item.list.length == 0
|
||||
? 1
|
||||
: item.list.length > 1
|
||||
? 2
|
||||
: item.list.length
|
||||
} - 21px)`,
|
||||
}" />
|
||||
<div style="width: 500px" class="tableBox">
|
||||
<el-table ref="tableRef" :data="item.list[i]" size="small" :height="`calc((600px) / ${item.list.length == 0
|
||||
? 1
|
||||
: item.list.length > 1
|
||||
? 2
|
||||
: item.list.length
|
||||
} - 21px)`" :header-cell-style="{ textAlign: 'center' }" border>
|
||||
<el-table-column prop="customerName" align="center" label="用户名(用户号)" />
|
||||
<el-table-column prop="responsibilityData" align="center" label="责任数据(%)" width="120">
|
||||
<template #default="scope">
|
||||
{{
|
||||
Math.floor(scope.row.responsibilityData * 10000) / 10000
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-divider />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, nextTick } from "vue";
|
||||
import MyEChart from "@/components/echarts/MyEchart.vue";
|
||||
import { timeFormat } from "@/utils/common";
|
||||
import { yMethod } from "@/utils/echartMethod";
|
||||
import { displayHistoryData } from "@/api/manage_wx";
|
||||
|
||||
const props = defineProps<{
|
||||
detailsQuery?: any; // 根据实际类型调整
|
||||
}>();
|
||||
|
||||
// const height = mainHeight(155);
|
||||
const activeName = ref(0);
|
||||
const tabList: any = ref([]);
|
||||
|
||||
const visible: any = ref(false);
|
||||
|
||||
const loading: any = ref(false);
|
||||
const init = () => {
|
||||
let data =
|
||||
(Array.isArray(props.detailsQuery.time)
|
||||
? props.detailsQuery.time[0]
|
||||
: props.detailsQuery.time
|
||||
)?.split(",") ?? [];
|
||||
tabList.value = [];
|
||||
data.forEach((item: any) => {
|
||||
tabList.value.push({
|
||||
name: item,
|
||||
dynamicOptions: [],
|
||||
list: [],
|
||||
});
|
||||
});
|
||||
activeName.value = 0;
|
||||
generateFn(0);
|
||||
};
|
||||
|
||||
// 生成动态谐波责任数据
|
||||
const generateFn = async (e: any) => {
|
||||
if (tabList.value[e].dynamicOptions.length != 0) return;
|
||||
|
||||
loading.value = true;
|
||||
await displayHistoryData({
|
||||
id: props.detailsQuery.id,
|
||||
time: tabList.value[e].name,
|
||||
})
|
||||
.then((res: any) => {
|
||||
res.data.forEach((item: any) => {
|
||||
tabList.value[e].list.push(item.responsibilities);
|
||||
|
||||
let [min, max] = yMethod(
|
||||
item.datas.map((k: any) => k.valueDatas).flat()
|
||||
);
|
||||
let series: any[] = [];
|
||||
let time: any[] = item.timeDatas.map((k: any) => timeFormat(k));
|
||||
item.datas.forEach((k: any) => {
|
||||
series.push({
|
||||
name: k.customerName,
|
||||
data: k.valueDatas.map((k: any, i: number) => [
|
||||
time[i],
|
||||
Math.floor(k * 10000) / 10000,
|
||||
]),
|
||||
type: "line",
|
||||
symbol: "none",
|
||||
smooth: true,
|
||||
});
|
||||
});
|
||||
tabList.value[e].dynamicOptions.push({
|
||||
title: {
|
||||
text: `时间:${item.limitSTime} 至${item.limitETime} 限值:${item.limitValue}`,
|
||||
},
|
||||
xAxis: {
|
||||
type: "time",
|
||||
name: "时间",
|
||||
axisLabel: {
|
||||
formatter: {
|
||||
day: "{MM}-{dd}",
|
||||
month: "{MM}",
|
||||
year: "{yyyy}",
|
||||
},
|
||||
},
|
||||
// 刻度线样式
|
||||
axisTick: {
|
||||
lineStyle: {
|
||||
color: "#fff", // 刻度线白色
|
||||
},
|
||||
},
|
||||
|
||||
// 轴线样式
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "#fff", // 轴线白色
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
formatter(params: any) {
|
||||
let str = params[0].value[0] + "<br/>";
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
str =
|
||||
str +
|
||||
params[i].marker +
|
||||
params[i].seriesName +
|
||||
":" +
|
||||
params[i].value[1] +
|
||||
"<br/>";
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
top: 30,
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
yAxis: {
|
||||
min: min,
|
||||
max: max,
|
||||
},
|
||||
toolbox: {
|
||||
show: false,
|
||||
},
|
||||
|
||||
options: {
|
||||
series: series,
|
||||
},
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
const openDialog = () => {
|
||||
visible.value = true;
|
||||
if (props.detailsQuery) {
|
||||
nextTick(() => {
|
||||
init();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleCloseDialog = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
// onMounted(() => {
|
||||
// init();
|
||||
// });
|
||||
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@use "@/assets/scss/index.scss";
|
||||
|
||||
.title_1 {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 65px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.monitoring-point {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.boxTab {
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,653 @@
|
||||
<!-- 谐波放大表格详情 -->
|
||||
<template>
|
||||
<el-dialog v-model="visible" :close-on-click-modal="false" title="趋势图" draggable width="70%"
|
||||
@close="handleCloseDialog">
|
||||
<el-radio-group v-model="condition" size="small" @change="init">
|
||||
<el-radio-button label="谐波电压" value="42" />
|
||||
<el-radio-button label="谐波电流" value="43" />
|
||||
|
||||
</el-radio-group>
|
||||
<MyEChart v-loading="loading" element-loading-background="rgba(122, 122, 122, 0.8)" :options="list[0]?.option"
|
||||
:style="`height:670px`" />
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from "vue";
|
||||
import MyEChart from "@/components/echarts/MyEchart.vue";
|
||||
import { getHistoryResult } from "@/api/manage_wx/index";
|
||||
import { yMethod } from "@/utils/echartMethod";
|
||||
|
||||
const emit = defineEmits(["close"]);
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
const options = ref<any>(null);
|
||||
const list = ref<any>([]);
|
||||
const traceability = ref<any>([]);
|
||||
const rowData: any = ref({});
|
||||
const condition: any = ref('42');
|
||||
|
||||
const open = async (row: any) => {
|
||||
rowData.value = row;
|
||||
condition.value = '42';
|
||||
visible.value = true;
|
||||
init()
|
||||
};
|
||||
const init = async () => {
|
||||
list.value = [];
|
||||
|
||||
loading.value = true;
|
||||
await getHistoryResult({
|
||||
lineId: [rowData.value.monitorId],
|
||||
searchBeginTime: rowData.value.startTime,
|
||||
searchEndTime: rowData.value.endTime,
|
||||
valueType: 4,
|
||||
harmonic: rowData.value.harmonicCount,
|
||||
ptType: 0,
|
||||
condition: [condition.value],
|
||||
}).then((res) => {
|
||||
shujuchuli(res);
|
||||
});
|
||||
}
|
||||
const shujuchuli = (res: any) => {
|
||||
list.value = [];
|
||||
let shujuData = res.data;
|
||||
shujuData.forEach((item: any, i: number) => {
|
||||
//判断是否存在暂降点
|
||||
|
||||
if (item.eventDetail == null) {
|
||||
let [min, max] = yMethod([item.minValue, item.maxValue, condition.value == '42' ? rowData.value.vavgValue : rowData.value.vavgValue.iavgValue]
|
||||
|
||||
);
|
||||
//判断是否有限值(有上下限)
|
||||
if (item.topLimit !== 0 && item.lowerLimit !== 0) {
|
||||
item.phaiscType.push("上限");
|
||||
item.phaiscType.push("下限");
|
||||
if (item.minValue !== null && item.maxValue !== null) {
|
||||
//最小值等于下限值
|
||||
//图列为A,B,C,上限,下限
|
||||
if (item.phaiscType.length == 5) {
|
||||
let avalue = [];
|
||||
let bvalue = [];
|
||||
let cvalue = [];
|
||||
let topLimit = [];
|
||||
let lowerLimit = [];
|
||||
item.maxValue = item.topLimit;
|
||||
item.minValue = item.lowerLimit;
|
||||
//判断数据是否存在
|
||||
if (item.value !== null) {
|
||||
for (let j = 0; j < item.value.length; j++) {
|
||||
//判断存在缺失值a
|
||||
if (item.value[j][1] != undefined) {
|
||||
avalue.push([item.value[j][0], item.value[j][1].toFixed(3)]);
|
||||
} else {
|
||||
avalue.push([]);
|
||||
}
|
||||
//判断存在缺失值b
|
||||
if (item.value[j][2] != undefined) {
|
||||
bvalue.push([item.value[j][0], item.value[j][2].toFixed(3)]);
|
||||
} else {
|
||||
bvalue.push([]);
|
||||
}
|
||||
//判断存在缺失值c
|
||||
if (item.value[j][3] != undefined) {
|
||||
cvalue.push([item.value[j][0], item.value[j][3].toFixed(3)]);
|
||||
} else {
|
||||
cvalue.push([]);
|
||||
}
|
||||
//上下限值
|
||||
topLimit.push([item.value[j][0], item.topLimit.toFixed(3)]);
|
||||
lowerLimit.push([item.value[j][0], item.lowerLimit.toFixed(3)]);
|
||||
}
|
||||
//数据为空
|
||||
} else {
|
||||
avalue = [];
|
||||
bvalue = [];
|
||||
cvalue = [];
|
||||
}
|
||||
let shuju = {
|
||||
id: "qushifenx" + i,
|
||||
title: item.lineName + "--" + item.targetName,
|
||||
targetName: item.targetName,
|
||||
legend: item.phaiscType,
|
||||
valueName: item.unit[0],
|
||||
maxValue: max,
|
||||
minValue: min,
|
||||
avalue: avalue,
|
||||
bvalue: bvalue,
|
||||
cvalue: cvalue,
|
||||
topLimit: topLimit,
|
||||
lowerLimit: lowerLimit,
|
||||
};
|
||||
list.value.push(shuju);
|
||||
}
|
||||
//图列为频率等,上限,下限
|
||||
if (item.phaiscType.length == 3) {
|
||||
let gvalue = [];
|
||||
let topLimit = [];
|
||||
let lowerLimit = [];
|
||||
item.maxValue = item.topLimit;
|
||||
item.minValue = item.lowerLimit;
|
||||
//判断数据是否存在
|
||||
if (item.value !== null) {
|
||||
for (let j = 0; j < item.value.length; j++) {
|
||||
//判断存在缺失值a
|
||||
if (item.value[j][1] != undefined) {
|
||||
gvalue.push([item.value[j][0], item.value[j][1].toFixed(3)]);
|
||||
} else {
|
||||
gvalue.push([]);
|
||||
}
|
||||
//上下限值
|
||||
topLimit.push([item.value[j][0], item.topLimit.toFixed(3)]);
|
||||
lowerLimit.push([item.value[j][0], item.lowerLimit.toFixed(3)]);
|
||||
}
|
||||
//数据为空
|
||||
} else {
|
||||
gvalue = [];
|
||||
}
|
||||
let shuju = {
|
||||
id: "qushifenx" + i,
|
||||
title: item.lineName + "--" + item.targetName,
|
||||
targetName: item.targetName,
|
||||
legend: item.phaiscType,
|
||||
valueName: item.unit[0],
|
||||
maxValue: max,
|
||||
minValue: min,
|
||||
gvalue: gvalue,
|
||||
topLimit: topLimit,
|
||||
lowerLimit: lowerLimit,
|
||||
chufa: [],
|
||||
};
|
||||
list.value.push(shuju);
|
||||
}
|
||||
} else {
|
||||
let shuju = {
|
||||
id: "qushifenx" + i,
|
||||
title: item.lineName + "--" + item.targetName,
|
||||
targetName: item.targetName,
|
||||
legend: item.phaiscType,
|
||||
valueName: item.unit[0],
|
||||
minValue: null,
|
||||
avalue: [],
|
||||
bvalue: [],
|
||||
cvalue: [],
|
||||
topLimit: [],
|
||||
lowerLimit: [],
|
||||
chufa: [],
|
||||
};
|
||||
list.value.push(shuju);
|
||||
}
|
||||
}
|
||||
//有上限值
|
||||
if (item.topLimit !== 0 && item.lowerLimit == 0) {
|
||||
item.phaiscType.push("上限");
|
||||
if (item.minValue !== null) {
|
||||
//最小值等于下限值
|
||||
//图列为A,B,C,上限
|
||||
if (item.phaiscType.length == 4) {
|
||||
let avalue = [];
|
||||
let bvalue = [];
|
||||
let cvalue = [];
|
||||
let topLimit = [];
|
||||
item.maxValue = item.topLimit;
|
||||
// item.minValue=item.lowerLimit
|
||||
//判断数据是否存在
|
||||
if (item.value !== null) {
|
||||
for (let j = 0; j < item.value.length; j++) {
|
||||
//判断存在缺失值a
|
||||
if (item.value[j][1] != undefined) {
|
||||
avalue.push([item.value[j][0], item.value[j][1].toFixed(3)]);
|
||||
} else {
|
||||
avalue.push([]);
|
||||
}
|
||||
//判断存在缺失值b
|
||||
if (item.value[j][2] != undefined) {
|
||||
bvalue.push([item.value[j][0], item.value[j][2].toFixed(3)]);
|
||||
} else {
|
||||
bvalue.push([]);
|
||||
}
|
||||
//判断存在缺失值c
|
||||
if (item.value[j][3] != undefined) {
|
||||
cvalue.push([item.value[j][0], item.value[j][3].toFixed(3)]);
|
||||
} else {
|
||||
cvalue.push([]);
|
||||
}
|
||||
//上限值
|
||||
topLimit.push([item.value[j][0], item.topLimit.toFixed(3)]);
|
||||
}
|
||||
//数据为空
|
||||
} else {
|
||||
avalue = [];
|
||||
bvalue = [];
|
||||
cvalue = [];
|
||||
}
|
||||
let shuju = {
|
||||
id: "qushifenx" + i,
|
||||
title: item.lineName + "--" + item.targetName,
|
||||
targetName: item.targetName,
|
||||
legend: item.phaiscType,
|
||||
valueName: item.unit[0],
|
||||
maxValue: max,
|
||||
minValue: min,
|
||||
avalue: avalue,
|
||||
bvalue: bvalue,
|
||||
cvalue: cvalue,
|
||||
topLimit: topLimit,
|
||||
};
|
||||
list.value.push(shuju);
|
||||
}
|
||||
//图列为频率等,上限
|
||||
if (item.phaiscType.length == 2) {
|
||||
let gvalue = [];
|
||||
let topLimit = [];
|
||||
item.maxValue = item.topLimit;
|
||||
// item.minValue=item.lowerLimit
|
||||
//判断数据是否存在
|
||||
if (item.value !== null) {
|
||||
for (let j = 0; j < item.value.length; j++) {
|
||||
//判断存在缺失值a
|
||||
if (item.value[j][1] != undefined) {
|
||||
gvalue.push([item.value[j][0], item.value[j][1].toFixed(3)]);
|
||||
} else {
|
||||
gvalue.push([]);
|
||||
}
|
||||
//上限值
|
||||
topLimit.push([item.value[j][0], item.topLimit.toFixed(3)]);
|
||||
}
|
||||
//数据为空
|
||||
} else {
|
||||
gvalue = [];
|
||||
}
|
||||
let shuju = {
|
||||
id: "qushifenx" + i,
|
||||
title: item.lineName + "--" + item.targetName,
|
||||
targetName: item.targetName,
|
||||
legend: item.phaiscType,
|
||||
valueName: item.unit[0],
|
||||
minValue: min,
|
||||
maxValue: max,
|
||||
gvalue: gvalue,
|
||||
topLimit: topLimit,
|
||||
};
|
||||
list.value.push(shuju);
|
||||
}
|
||||
} else {
|
||||
let shuju = {
|
||||
id: "qushifenx" + i,
|
||||
title: item.lineName + "--" + item.targetName,
|
||||
targetName: item.targetName,
|
||||
legend: item.phaiscType,
|
||||
valueName: item.unit[0],
|
||||
minValue: null,
|
||||
avalue: [],
|
||||
bvalue: [],
|
||||
cvalue: [],
|
||||
topLimit: [],
|
||||
lowerLimit: [],
|
||||
chufa: [],
|
||||
};
|
||||
list.value.push(shuju);
|
||||
}
|
||||
}
|
||||
|
||||
//无限值
|
||||
if (item.topLimit == 0 && item.lowerLimit == 0) {
|
||||
if (item.minValue !== null) {
|
||||
//最小值等于下限值
|
||||
//图列为A,B,C
|
||||
if (item.phaiscType.length == 3) {
|
||||
let avalue = [];
|
||||
let bvalue = [];
|
||||
let cvalue = [];
|
||||
//判断数据是否存在
|
||||
if (item.value !== null) {
|
||||
for (let j = 0; j < item.value.length; j++) {
|
||||
//判断存在缺失值a
|
||||
if (item.value[j][1] != undefined) {
|
||||
avalue.push([item.value[j][0], item.value[j][1].toFixed(3)]);
|
||||
} else {
|
||||
avalue.push([]);
|
||||
}
|
||||
//判断存在缺失值b
|
||||
if (item.value[j][2] != undefined) {
|
||||
bvalue.push([item.value[j][0], item.value[j][2].toFixed(3)]);
|
||||
} else {
|
||||
bvalue.push([]);
|
||||
}
|
||||
//判断存在缺失值c
|
||||
if (item.value[j][3] != undefined) {
|
||||
cvalue.push([item.value[j][0], item.value[j][3].toFixed(3)]);
|
||||
} else {
|
||||
cvalue.push([]);
|
||||
}
|
||||
}
|
||||
//数据为空
|
||||
} else {
|
||||
avalue = [];
|
||||
bvalue = [];
|
||||
cvalue = [];
|
||||
}
|
||||
|
||||
let shuju = {
|
||||
id: "qushifenx" + i,
|
||||
title: item.lineName + "--" + item.targetName,
|
||||
targetName: item.targetName,
|
||||
legend: item.phaiscType,
|
||||
valueName: item.unit[0],
|
||||
minValue: min,
|
||||
maxValue: max,
|
||||
avalue: avalue,
|
||||
bvalue: bvalue,
|
||||
cvalue: cvalue,
|
||||
};
|
||||
list.value.push(shuju);
|
||||
}
|
||||
//图列为频率等
|
||||
if (item.phaiscType.length == 1) {
|
||||
let gvalue = [];
|
||||
//判断数据是否存在
|
||||
if (item.value !== null) {
|
||||
for (let j = 0; j < item.value.length; j++) {
|
||||
//判断存在缺失值a
|
||||
if (item.value[j][1] != undefined) {
|
||||
gvalue.push([item.value[j][0], item.value[j][1].toFixed(3)]);
|
||||
} else {
|
||||
gvalue.push([]);
|
||||
}
|
||||
}
|
||||
//数据为空
|
||||
} else {
|
||||
gvalue = [];
|
||||
}
|
||||
let shuju = {
|
||||
id: "qushifenx" + i,
|
||||
title: item.lineName + "--" + item.targetName,
|
||||
targetName: item.targetName,
|
||||
legend: item.phaiscType,
|
||||
valueName: item.unit[0],
|
||||
minValue: min,
|
||||
maxValue: max,
|
||||
gvalue: gvalue,
|
||||
};
|
||||
list.value.push(shuju);
|
||||
}
|
||||
} else {
|
||||
let shuju = {
|
||||
id: "qushifenx" + i,
|
||||
title: item.lineName + "--" + item.targetName,
|
||||
targetName: item.targetName,
|
||||
legend: item.phaiscType,
|
||||
valueName: item.unit[0],
|
||||
minValue: null,
|
||||
avalue: [],
|
||||
bvalue: [],
|
||||
cvalue: [],
|
||||
topLimit: [],
|
||||
lowerLimit: [],
|
||||
chufa: [],
|
||||
};
|
||||
list.value.push(shuju);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
rendering();
|
||||
};
|
||||
const rendering = () => {
|
||||
list.value.forEach((item: any) => {
|
||||
let opitonserise: any[] = [];
|
||||
item.legend.forEach((item2: any) => {
|
||||
if (
|
||||
item.avalue !== undefined &&
|
||||
(item2 == "A相" || item2 == "AB相" || item2 == "零序电压")
|
||||
) {
|
||||
let data = {
|
||||
name: item2,
|
||||
symbol: "none",
|
||||
symbolSize: 5,
|
||||
type: "line",
|
||||
smooth: true,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: "#DAA520",
|
||||
},
|
||||
},
|
||||
|
||||
data: item.avalue,
|
||||
};
|
||||
opitonserise.push(data);
|
||||
} else if (
|
||||
item.bvalue !== undefined &&
|
||||
(item2 == "B相" || item2 == "BC相" || item2 == "正序电压")
|
||||
) {
|
||||
let data = {
|
||||
name: item2,
|
||||
symbol: "none",
|
||||
symbolSize: 5,
|
||||
type: "line",
|
||||
smooth: true,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: "#2E8B57",
|
||||
},
|
||||
},
|
||||
|
||||
data: item.bvalue,
|
||||
};
|
||||
opitonserise.push(data);
|
||||
} else if (
|
||||
item.cvalue !== undefined &&
|
||||
(item2 == "C相" || item2 == "CA相" || item2 == "负序电压")
|
||||
) {
|
||||
let data = {
|
||||
name: item2,
|
||||
symbol: "none",
|
||||
symbolSize: 5,
|
||||
type: "line",
|
||||
smooth: true,
|
||||
barWidth: 22,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: "#A52a2a",
|
||||
},
|
||||
},
|
||||
data: item.cvalue,
|
||||
};
|
||||
opitonserise.push(data);
|
||||
}
|
||||
});
|
||||
if (item.valueName == undefined) {
|
||||
item.valueName = "无";
|
||||
}
|
||||
opitonserise[0].markLine = {
|
||||
itemStyle: {
|
||||
normal: {
|
||||
lineStyle: {
|
||||
type: "dashed", //dotted、solid
|
||||
color: "#FF33FF",
|
||||
width: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
label: {
|
||||
normal: {
|
||||
color: "#fff",
|
||||
formatter: function (params) {
|
||||
return `标准值`;
|
||||
},
|
||||
},
|
||||
},
|
||||
data: [
|
||||
{
|
||||
name: "标准值",
|
||||
yAxis: condition.value == '42' ? rowData.value.vavgValue : rowData.value.iavgValue,
|
||||
},
|
||||
],
|
||||
};
|
||||
// console.log("🚀 ~ rendering ~ row.value:", rowData.value);
|
||||
|
||||
// console.log("🚀 ~ rendering ~ opitonserise:", opitonserise);
|
||||
item.serise = opitonserise;
|
||||
});
|
||||
|
||||
getEcharts();
|
||||
};
|
||||
const getEcharts = () => {
|
||||
list.value.forEach((item: any, i: number) => {
|
||||
console.log("🚀 ~ getEcharts ~ item:", item)
|
||||
item.option = {
|
||||
backgroundColor: "#fff",
|
||||
title: {
|
||||
left: "center",
|
||||
text: item.title,
|
||||
},
|
||||
tooltip: {
|
||||
top: "10px",
|
||||
trigger: "axis",
|
||||
borderColor: "grey",
|
||||
style: {
|
||||
color: "#fff",
|
||||
fontSize: "15px",
|
||||
padding: 10,
|
||||
},
|
||||
formatter: function (params) {
|
||||
// console.log(params)
|
||||
let tips = "";
|
||||
tips += "时刻:" + params[0].data[0] + "</br/>";
|
||||
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
if (params[i].seriesName != "暂降触发点") {
|
||||
tips +=
|
||||
params[i].marker +
|
||||
params[i].seriesName +
|
||||
":" +
|
||||
(params[i].value[1] - 0).toFixed(2) +
|
||||
"<br/>";
|
||||
}
|
||||
}
|
||||
return tips;
|
||||
},
|
||||
// axisPointer: {
|
||||
// type: "cross",
|
||||
// label: {
|
||||
// color: "#fff",
|
||||
// fontSize: 16,
|
||||
// },
|
||||
// },
|
||||
textStyle: {
|
||||
color: "#fff",
|
||||
fontStyle: "normal",
|
||||
opacity: 0.35,
|
||||
fontSize: 14,
|
||||
},
|
||||
backgroundColor: "rgba(0,0,0,0.55)",
|
||||
borderWidth: 0,
|
||||
},
|
||||
|
||||
legend: {
|
||||
right: 50,
|
||||
top: 25,
|
||||
verticalAlign: "top",
|
||||
enabled: true,
|
||||
itemDistance: 5,
|
||||
textStyle: {
|
||||
fontSize: "0.6rem",
|
||||
color: "#fff",
|
||||
rich: {
|
||||
a: {
|
||||
verticalAlign: "middle",
|
||||
},
|
||||
},
|
||||
|
||||
padding: [0, 0, 0, 0], //[上、右、下、左]
|
||||
},
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: "time",
|
||||
axisLine: {
|
||||
show: true,
|
||||
onZero: false,
|
||||
lineStyle: {
|
||||
color: "#fff",
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
fontFamily: "dinproRegular",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
toolbox: {
|
||||
show: false,
|
||||
feature: {
|
||||
dataZoom: {
|
||||
// bottom: '10px',
|
||||
yAxisIndex: "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: "value",
|
||||
min: item.minValue,
|
||||
max: item.maxValue,
|
||||
name: item.valueName,
|
||||
|
||||
|
||||
axisLine: {
|
||||
show: true,
|
||||
onZero: false, //-----------重点
|
||||
lineStyle: {
|
||||
color: "#fff",
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
// 使用深浅的间隔色
|
||||
type: "dashed",
|
||||
opacity: 0.5,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
series: item.serise,
|
||||
};
|
||||
let aValues = [];
|
||||
let bValues = [];
|
||||
let CValues = [];
|
||||
let ZValues = [];
|
||||
|
||||
if (
|
||||
traceability.value.length > 0 &&
|
||||
traceability.value[0].value != null &&
|
||||
traceability.value[0].value.length > 0
|
||||
) {
|
||||
for (let i = 0; i < traceability.value[0].value.length; i++) {
|
||||
let T = traceability.value[0].value[i][0];
|
||||
let A = traceability.value[0].value[i][1];
|
||||
let B = traceability.value[0].value[i][2];
|
||||
let C = traceability.value[0].value[i][3];
|
||||
let Z = A + B + C;
|
||||
aValues.push([T, A > 0 ? 1 : A == 0 ? 0 : -1]);
|
||||
bValues.push([T, B > 0 ? 1 : B == 0 ? 0 : -1]);
|
||||
CValues.push([T, C > 0 ? 1 : C == 0 ? 0 : -1]);
|
||||
ZValues.push([T, Z > 0 ? 1 : Z == 0 ? 0 : -1]);
|
||||
}
|
||||
}
|
||||
});
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
const handleCloseDialog = () => {
|
||||
visible.value = false;
|
||||
options.value = null;
|
||||
emit("close");
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user