|
@@ -0,0 +1,551 @@
|
|
|
+<template>
|
|
|
+ <el-card>
|
|
|
+ <el-space wrap>
|
|
|
+ <div class="search-input">
|
|
|
+ <span class="lable">类型:</span>
|
|
|
+ <el-select
|
|
|
+ v-model="state.typeVal"
|
|
|
+ clearable
|
|
|
+ size="mini"
|
|
|
+ style="width: 100px"
|
|
|
+ placeholder="全部"
|
|
|
+ popper-class="select"
|
|
|
+ @change="
|
|
|
+ () => {
|
|
|
+ getStationList();
|
|
|
+ typechange();
|
|
|
+ }
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in state.typeList"
|
|
|
+ :key="item.value"
|
|
|
+ :value="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div class="search-input" v-if="!isStation">
|
|
|
+ <span class="lable">{{
|
|
|
+ state.isshowwindturbineName ? "场站:" : "升压站:"
|
|
|
+ }}</span>
|
|
|
+ <el-select
|
|
|
+ v-model="state.stationId"
|
|
|
+ clearable
|
|
|
+ size="mini"
|
|
|
+ placeholder="全部"
|
|
|
+ popper-class="select"
|
|
|
+ @change="getWindturbineList"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in stationList"
|
|
|
+ :key="item.id"
|
|
|
+ :value="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ ></el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div class="search-input" v-if="state.isshowwindturbineName">
|
|
|
+ <span class="lable">机组:</span>
|
|
|
+ <el-select
|
|
|
+ v-model="state.windturbineId"
|
|
|
+ clearable
|
|
|
+ size="mini"
|
|
|
+ placeholder="全部"
|
|
|
+ popper-class="select"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in state.windturbineList"
|
|
|
+ :key="item.id"
|
|
|
+ :value="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div class="search-input" v-if="state.isshowwindturbineName">
|
|
|
+ <span class="lable">型号:</span>
|
|
|
+ <el-select
|
|
|
+ v-model="state.modelId"
|
|
|
+ clearable
|
|
|
+ size="mini"
|
|
|
+ placeholder="全部"
|
|
|
+ popper-class="select"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in modelList"
|
|
|
+ :key="item.id"
|
|
|
+ :value="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div class="search-input" v-if="state.isshowwindturbineName">
|
|
|
+ <span class="lable">部件:</span>
|
|
|
+ <el-select
|
|
|
+ v-model="state.components"
|
|
|
+ clearable
|
|
|
+ size="mini"
|
|
|
+ placeholder="全部"
|
|
|
+ popper-class="select"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in componentList"
|
|
|
+ :key="item.id"
|
|
|
+ :value="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div class="search-input">
|
|
|
+ <span class="lable">描述:</span>
|
|
|
+ <el-input
|
|
|
+ v-model="state.description"
|
|
|
+ style="width: 100px"
|
|
|
+ size="mini"
|
|
|
+ ></el-input>
|
|
|
+ </div>
|
|
|
+ <div class="search-input">
|
|
|
+ <span class="lable">日期:</span>
|
|
|
+ <el-date-picker
|
|
|
+ v-model="state.dateTime"
|
|
|
+ size="mini"
|
|
|
+ type="datetimerange"
|
|
|
+ range-separator="-"
|
|
|
+ format="YYYY-MM-DD HH:mm:ss"
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
+ start-placeholder="开始"
|
|
|
+ end-placeholder="结束"
|
|
|
+ >
|
|
|
+ </el-date-picker>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-button type="primary" size="mini" @click="getAlarmHistoryt"
|
|
|
+ >查询</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ size="mini"
|
|
|
+ type="primary"
|
|
|
+ @click="export2Excel"
|
|
|
+ :disabled="state.tableData?.length == 0 ? true : false"
|
|
|
+ >
|
|
|
+ 导出</el-button
|
|
|
+ >
|
|
|
+ </el-space>
|
|
|
+ </el-card>
|
|
|
+ <div class="table-wrapper">
|
|
|
+ <el-table
|
|
|
+ :data="state.tableData"
|
|
|
+ height="calc(100% - 35px - 10px)"
|
|
|
+ style="width: 100%"
|
|
|
+ border
|
|
|
+ stripe
|
|
|
+ >
|
|
|
+ <template v-if="state.isshowwindturbineName">
|
|
|
+ <el-table-column
|
|
|
+ v-for="item in state.tableHeader"
|
|
|
+ :label="item.title"
|
|
|
+ :prop="item.code"
|
|
|
+ :key="item.code"
|
|
|
+ :width="item.width || ''"
|
|
|
+ show-overflow-tooltip
|
|
|
+ header-align="center"
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ <p :style="item.style && item.style(item)">
|
|
|
+ <span v-if="item.code == 'rank'">
|
|
|
+ {{ tableFilter(scope.row.rank) }}
|
|
|
+ </span>
|
|
|
+ <span v-else-if="item.code == 'alarmtype'">
|
|
|
+ {{ tableFilter(scope.row.alarmtype) }}
|
|
|
+ </span>
|
|
|
+ <span v-else-if="item.code == 'ts'">
|
|
|
+ {{ formatTime(scope.row.ts) }}
|
|
|
+ </span>
|
|
|
+ <span v-else>
|
|
|
+ {{ scope.row[item.code] }}
|
|
|
+ </span>
|
|
|
+ </p>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <el-table-column
|
|
|
+ v-for="item in state.tableHeader1"
|
|
|
+ :label="item.title"
|
|
|
+ :prop="item.code"
|
|
|
+ :key="item.code"
|
|
|
+ :width="item.width || ''"
|
|
|
+ show-overflow-tooltip
|
|
|
+ header-align="center"
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ <p :style="item.style && item.style(item)">
|
|
|
+ <span v-if="item.code == 'rank'">
|
|
|
+ {{ tableFilter(scope.row.rank) }}
|
|
|
+ </span>
|
|
|
+ <span v-else-if="item.code == 'alarmtype'">
|
|
|
+ {{ tableFilter(scope.row.alarmtype) }}
|
|
|
+ </span>
|
|
|
+ <span v-else-if="item.code == 'ts'">
|
|
|
+ {{ formatTime(scope.row.ts) }}
|
|
|
+ </span>
|
|
|
+ <span v-else>
|
|
|
+ {{ scope.row[item.code] }}
|
|
|
+ </span>
|
|
|
+ </p>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </template>
|
|
|
+ </el-table>
|
|
|
+ <div class="pagination-wrapper">
|
|
|
+ <el-pagination
|
|
|
+ background
|
|
|
+ layout="total, prev, pager, next"
|
|
|
+ hide-on-single-page
|
|
|
+ :current-page="query.page"
|
|
|
+ :page-size="query.limit"
|
|
|
+ :total="query.pageTotal"
|
|
|
+ @current-change="handlePageChange"
|
|
|
+ ></el-pagination>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { watch, reactive, nextTick, computed, onMounted, ref } from "vue";
|
|
|
+import { useRouter, useRoute } from "vue-router";
|
|
|
+import dayjs from "dayjs";
|
|
|
+import {
|
|
|
+ alarm_history,
|
|
|
+ new_alarm_history,
|
|
|
+ fetchWindturbineList,
|
|
|
+ fetchModel,
|
|
|
+ fetchRelatePartAndAlarmType,
|
|
|
+ getWpList,
|
|
|
+} from "/@/api/api.js";
|
|
|
+import { ElMessage } from "element-plus";
|
|
|
+import { initWebSocket } from "/@/websocket/indextest";
|
|
|
+import { outExportExcel } from "/@/utils/exportExcel"; //引入文件
|
|
|
+import { useStore } from "vuex";
|
|
|
+
|
|
|
+const store = useStore();
|
|
|
+const isStation = computed(() => store.getters.isStation);
|
|
|
+const route = useRoute();
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ state.dateTime = [
|
|
|
+ dayjs().startOf("day").format("YYYY-MM-DD HH:mm:ss"),
|
|
|
+ dayjs().format("YYYY-MM-DD HH:mm:ss"),
|
|
|
+ ];
|
|
|
+ state.deviceId = route.params.deviceId || "";
|
|
|
+ state.alarmId = route.params.alarmId || "";
|
|
|
+ getStationList();
|
|
|
+ getequipmentmodel_list();
|
|
|
+ getfetchRelatePart();
|
|
|
+});
|
|
|
+// 机型
|
|
|
+const getequipmentmodel_list = async () => {
|
|
|
+ const { data } = await fetchModel();
|
|
|
+ state.modelListAll = data;
|
|
|
+};
|
|
|
+//所属部件
|
|
|
+const getfetchRelatePart = async () => {
|
|
|
+ const { data } = await fetchRelatePartAndAlarmType();
|
|
|
+ state.fetchListAll = data;
|
|
|
+};
|
|
|
+
|
|
|
+const getColumnStyle = (columnItem) => {
|
|
|
+ let style = "color:";
|
|
|
+ if (columnItem.endts) {
|
|
|
+ style += "var(--el-color-success)";
|
|
|
+ } else {
|
|
|
+ style += "var(--el-color-danger)";
|
|
|
+ }
|
|
|
+ return style;
|
|
|
+};
|
|
|
+
|
|
|
+const state = reactive({
|
|
|
+ typeList: [
|
|
|
+ {
|
|
|
+ label: "升压站",
|
|
|
+ value: "booststation",
|
|
|
+ },
|
|
|
+ // {
|
|
|
+ // label: "自定义",
|
|
|
+ // value: "custom",
|
|
|
+ // },
|
|
|
+ {
|
|
|
+ label: "风机",
|
|
|
+ value: "windturbine",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "光伏",
|
|
|
+ value: "inverter",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ c: "windturbine",
|
|
|
+ stationId: "",
|
|
|
+ alarmId: "",
|
|
|
+ typeVal: "windturbine",
|
|
|
+ windturbineList: [],
|
|
|
+ windturbineId: "",
|
|
|
+ modelListAll: {},
|
|
|
+ fetchListAll: {},
|
|
|
+ modelId: "", //型号
|
|
|
+ components: "", //部件
|
|
|
+ description: "", //描述
|
|
|
+ dateTime: [],
|
|
|
+ startDate: null,
|
|
|
+ endDate: null,
|
|
|
+ tableData: [],
|
|
|
+ isshowwindturbineName: true,
|
|
|
+ tableHeader: [
|
|
|
+ { title: "时间", code: "ts", width: "150" },
|
|
|
+ { title: "场站", code: "stationname", width: "150" },
|
|
|
+ { title: "机组", code: "devicename", width: "150" },
|
|
|
+ { title: "故障编码", code: "nemCode", width: "100" },
|
|
|
+ { title: "故障原因", code: "faultCause" },
|
|
|
+ { title: "故障解决方法", code: "resolvent" },
|
|
|
+ { title: "报警信息", code: "description", width: "180" },
|
|
|
+ { title: "级别", code: "rank", width: "80" },
|
|
|
+ { title: "类型", code: "alarmType", width: "80" },
|
|
|
+ {
|
|
|
+ title: "状态",
|
|
|
+ code: "isCloseName",
|
|
|
+ width: "80",
|
|
|
+ style: getColumnStyle,
|
|
|
+ width: 100,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ tableHeader1: [
|
|
|
+ { title: "时间", code: "ts", width: "150" },
|
|
|
+ { title: "升压站", code: "stationname", width: "150" },
|
|
|
+ { title: "报警信息", code: "description" },
|
|
|
+ { title: "级别", code: "rank", width: "80" },
|
|
|
+ { title: "类型", code: "alarmType", width: "80" },
|
|
|
+ {
|
|
|
+ title: "状态",
|
|
|
+ code: "isCloseName",
|
|
|
+ style: getColumnStyle,
|
|
|
+ width: 100,
|
|
|
+ width: "80",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+});
|
|
|
+// 场站列表/升压站列表
|
|
|
+const stationList = ref([]);
|
|
|
+
|
|
|
+const getStationList = async () => {
|
|
|
+ const { data } = await getWpList(state.typeVal);
|
|
|
+ stationList.value = data;
|
|
|
+};
|
|
|
+
|
|
|
+watch(
|
|
|
+ () => stationList,
|
|
|
+ (val, old) => {
|
|
|
+ val?.value?.length &&
|
|
|
+ nextTick(async () => {
|
|
|
+ state.stationId = val.value[0]?.id;
|
|
|
+ await getWindturbineList();
|
|
|
+ await getAlarmHistoryt();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ {
|
|
|
+ deep: true,
|
|
|
+ immediate: true,
|
|
|
+ }
|
|
|
+);
|
|
|
+watch(
|
|
|
+ () => route,
|
|
|
+ (val, old) => {
|
|
|
+ state.deviceId = route.params.deviceId || "";
|
|
|
+ state.alarmId = route.params.alarmId || "";
|
|
|
+ nextTick(async () => {
|
|
|
+ if (route.params.deviceId && route.params.alarmId) {
|
|
|
+ await getAlarmHistoryt();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ {
|
|
|
+ deep: true,
|
|
|
+ immediate: true,
|
|
|
+ }
|
|
|
+);
|
|
|
+//型号列表
|
|
|
+const modelList = computed(() => {
|
|
|
+ if (state.typeVal == "windturbine") {
|
|
|
+ if (state.stationId == "") {
|
|
|
+ return [];
|
|
|
+ } else {
|
|
|
+ state.modelId = state.modelListAll[state.stationId]?.[0]?.id || "";
|
|
|
+ return state.modelListAll[state.stationId];
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+});
|
|
|
+//部件列表
|
|
|
+const componentList = computed(() => {
|
|
|
+ if (state.typeVal == "windturbine") {
|
|
|
+ if (state.stationId == "") {
|
|
|
+ return [];
|
|
|
+ } else {
|
|
|
+ if (state.stationId.includes("FDC")) {
|
|
|
+ return state.fetchListAll?.fjbj;
|
|
|
+ } else {
|
|
|
+ return state.fetchListAll?.gfbj;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+});
|
|
|
+//get 风机
|
|
|
+const getWindturbineList = async () => {
|
|
|
+ state.windturbineList = [];
|
|
|
+ state.windturbineId = "";
|
|
|
+ const { data } = await fetchWindturbineList(state.stationId);
|
|
|
+ state.windturbineList = data;
|
|
|
+};
|
|
|
+const query = reactive({
|
|
|
+ page: 1,
|
|
|
+ limit: 17,
|
|
|
+ pageTotal: null,
|
|
|
+});
|
|
|
+
|
|
|
+// 获取历史记录表
|
|
|
+const getAlarmHistoryt = async () => {
|
|
|
+ if (route.params.deviceId && route.params.alarmId) {
|
|
|
+ state.stationId = "";
|
|
|
+ }
|
|
|
+ let params = {
|
|
|
+ pageNum: query.page,
|
|
|
+ pageSize: query.limit,
|
|
|
+ alarmId: state.alarmId,
|
|
|
+ alarmType: "custom",
|
|
|
+ deviceType: state.typeVal,
|
|
|
+ stationid: state.stationId,
|
|
|
+ deviceid:
|
|
|
+ state.deviceId ||
|
|
|
+ (state.typeVal == "booststation" ? "" : state.windturbineId),
|
|
|
+ modelId: state.typeVal == "booststation" ? "" : state.modelId,
|
|
|
+ components: state.components,
|
|
|
+ description: state.description,
|
|
|
+ begin: state.dateTime[0],
|
|
|
+ end: state.dateTime[1],
|
|
|
+ };
|
|
|
+ const { data } = await alarm_history(params);
|
|
|
+ query.pageTotal = data?.total;
|
|
|
+ data?.ls?.forEach((ele) => {
|
|
|
+ ele.isCloseName = ele.endts ? "已解除" : "未解除";
|
|
|
+ });
|
|
|
+ state.tableData = data?.ls;
|
|
|
+};
|
|
|
+//报警类型变化
|
|
|
+const typechange = () => {
|
|
|
+ state.isshowwindturbineName = state.typeVal == "booststation" ? false : true;
|
|
|
+};
|
|
|
+
|
|
|
+// 批量导出
|
|
|
+const export2Excel = async () => {
|
|
|
+ let params = {
|
|
|
+ pageNum: query.page,
|
|
|
+ pageSize: query.pageTotal,
|
|
|
+ alarmType: state.typeVal,
|
|
|
+ stationid: state.stationId,
|
|
|
+ deviceid: state.typeVal == "booststation" ? "" : state.windturbineId,
|
|
|
+ modelId: state.modelId,
|
|
|
+ components: state.components,
|
|
|
+ description: state.description,
|
|
|
+ begin: state.dateTime[0],
|
|
|
+ end: state.dateTime[1],
|
|
|
+ };
|
|
|
+
|
|
|
+ if (state.dateTime[1] - state.dateTime[0] > 6 * 24 * 60 * 60 * 1000) {
|
|
|
+ this.$message({
|
|
|
+ message: "导出时间范围不能大于7天",
|
|
|
+ type: "warning",
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ let tableHeader = [];
|
|
|
+ let tableKey = [];
|
|
|
+ const { data } = await alarm_history(params);
|
|
|
+ if (state.isshowwindturbineName) {
|
|
|
+ tableHeader = state.tableHeader.map((item) => item.title);
|
|
|
+ tableKey = state.tableHeader.map((item) => item.code);
|
|
|
+ } else {
|
|
|
+ tableHeader = state.tableHeader1.map((item) => item.title);
|
|
|
+ tableKey = state.tableHeader1.map((item) => item.code);
|
|
|
+ }
|
|
|
+ const stationName = stationList.value.find((ele) => {
|
|
|
+ return ele.id === state.stationId;
|
|
|
+ }).name;
|
|
|
+ const fileName = `${stationName} ${state.dateTime[0]} ~ ${state.dateTime[1]} 数据表`;
|
|
|
+
|
|
|
+ outExportExcel(
|
|
|
+ tableHeader,
|
|
|
+ tableKey,
|
|
|
+ data.ls.map((item) => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ ts: formatTime(item.ts),
|
|
|
+ rank: tableFilter(item.rank),
|
|
|
+ alarmtype: tableFilter(item.alarmtype),
|
|
|
+ };
|
|
|
+ }),
|
|
|
+ fileName
|
|
|
+ );
|
|
|
+ ElMessage.success(`导出成功!`);
|
|
|
+ }
|
|
|
+};
|
|
|
+// 分页导航
|
|
|
+const handlePageChange = (val) => {
|
|
|
+ query.page = val;
|
|
|
+ getAlarmHistoryt();
|
|
|
+};
|
|
|
+// 时间格式化
|
|
|
+const formatTime = (val) => {
|
|
|
+ return dayjs(val).format("YYYY-MM-DD HH:mm:ss");
|
|
|
+};
|
|
|
+// 格式化
|
|
|
+const obj = {
|
|
|
+ 1: "低级",
|
|
|
+ 2: "中低级",
|
|
|
+ 3: "中级",
|
|
|
+ 4: "中高级",
|
|
|
+ 5: "高级",
|
|
|
+ booststation: "升压站",
|
|
|
+ custom: "自定义",
|
|
|
+ windturbine: "风机",
|
|
|
+};
|
|
|
+const messageTypeObj = {
|
|
|
+ 1: "触发",
|
|
|
+ 3: "解除",
|
|
|
+};
|
|
|
+const tableFilter = (val) => {
|
|
|
+ return obj[val];
|
|
|
+};
|
|
|
+const messageTypeFilter = (val) => {
|
|
|
+ return messageTypeObj[val];
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.table-wrapper {
|
|
|
+ height: calc(100% - 70px - 50px);
|
|
|
+ background-color: #fff;
|
|
|
+ margin-top: 10px;
|
|
|
+ padding: 20px;
|
|
|
+ .pagination-wrapper :deep {
|
|
|
+ text-align: right;
|
|
|
+ margin-top: 10px;
|
|
|
+ .el-icon {
|
|
|
+ width: unset;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|