提交: 项目管理 新版本 安全监控模块下 功能代码

This commit is contained in:
23688nl 2022-09-01 16:51:30 +08:00
parent 84a66a1473
commit 62367c5544
14 changed files with 2711 additions and 106 deletions

View File

@ -35,3 +35,85 @@ export function statProject(query) {
params: query params: query
}); });
} }
// 查询 全部报警图表
export function projectAlarmEcharts(query) {
return request({
url: "/iot/project/monitor/allAlarmChart",
method: "get",
params: query
});
}
// 查询 全部报警表格
export function projectAlarmTable(query) {
return request({
url: "/iot/project/monitor/allAlarmList",
method: "get",
params: query
});
}
// 查询 报警 图表
export function projectAlarmRecordEcharts(query) {
return request({
url: "/iot/project/monitor/alarmChart",
method: "get",
params: query
});
}
// 查询 报警 表格
export function projectAlarmRecordTable(query) {
return request({
url: "/iot/project/monitor/alarmList",
method: "get",
params: query
});
}
// 查询 异常 列表
export function projectAbnormalRecordTable(query) {
return request({
url: "/iot/project/monitor/abnormalList",
method: "get",
params: query
});
}
// 查询 分合闸 警示
export function projectWarningRecordTable(query) {
return request({
url: "/iot/project/monitor/deviceOutList",
method: "get",
params: query
});
}
// 查询 异常 导出
export function projectAbnormalRecordExport(query) {
return request({
url: "/iot/project/monitor/abnormalExport",
method: "get",
params: query
});
}
// 查询 分合闸 导出
export function projectWarningRecordExport(query) {
return request({
url: "/iot/project/monitor/deviceOutExport",
method: "get",
params: query
});
}
// 查询 能源 列表
export function projectEneElectricityTable(query) {
return request({
url: "/iot/project/monitor/deviceOutList",
method: "get",
params: query
});
}

View File

@ -96,7 +96,6 @@ export default {
// //
markerClick(e) { markerClick(e) {
// console.log(""); // console.log("");
debugger;
if (!this.infoWindow) { if (!this.infoWindow) {
this.createInfoWindowO(); this.createInfoWindowO();
} }

View File

@ -262,3 +262,39 @@ export const downloadFile = (data, fileName) => {
navigator.msSaveBlob(blob, fileName); navigator.msSaveBlob(blob, fileName);
} }
} }
/**
* 查询两个时间之间 相差具体 小时 分钟
* @param {*} $begin_time 开始时间
* @param {*} $end_time 结束时间
* @returns
*/
export const timeDiff = ($begin_time, $end_time ) => {
$begin_time = $begin_time ? $begin_time : parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s}');
$end_time = $end_time ? $end_time : parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s}');
var starttime = new Date($begin_time).getTime() / 1000;
var endTime = new Date($end_time).getTime() / 1000;
//计算天数
var $timediff = 0;
if (starttime < endTime) {
$timediff = endTime - starttime
} else {
$timediff = starttime - endTime
}
var $days = parseInt($timediff / 86400);
//计算小时数
var $remain = $timediff % 86400;
var $hours = parseInt($remain / 3600);
//计算分钟数
var $remain = $remain % 3600;
var $mins = parseInt($remain / 60);
//计算秒数
var $secs = $remain % 60;
// $days=>天
// $hours=>时
// $mins=>分
// $secs=>秒
var $res = [$days,$hours,$mins,$secs]
return $res
}

View File

@ -0,0 +1,41 @@
<template>
<div class="token-timing">
<span>{{ title }}</span>
</div>
</template>
<script >
import { timeDiff } from "@/utils/hciot";
export default {
name: "ETiming",
data() {
return {
title: "",
};
},
props: {
startTime: {
type: String,
},
endTime: {
type: String,
},
},
created() {
this.init();
},
methods: {
init() {
let startTime = new Date(this.startTime).getTime();
let endTime = new Date(this.endTime).getTime();
let timeArr = timeDiff(startTime, endTime);
let titleText = `${timeArr[0] > 0 ? timeArr[0] + "天" : ""} ${
timeArr[1] > 0 ? timeArr[1] + "时" : ""
} ${timeArr[2] > 0 ? timeArr[2] + "分" : ""} ${
timeArr[3] > 0 ? timeArr[3] + "秒" : ""
} `;
this.title = titleText;
},
},
};
</script>

View File

@ -0,0 +1,418 @@
<template>
<div class="e-project-alarm-manage">
<div class="e-alarm-heard">
<div style="width: 200px">
<el-radio-group v-model="queryParams.typeCode" size="small">
<el-radio-button label="A">用电报警</el-radio-button>
<el-radio-button label="B">用电预警</el-radio-button>
</el-radio-group>
</div>
<div class="heard-query">
<div
@click="
() => {
queryParams.timeType = 'day';
}
"
:class="
queryParams.timeType === 'day'
? 'data-type data-type-selected'
: 'data-type'
"
>
</div>
<div
@click="
() => {
queryParams.timeType = 'month';
}
"
:class="
queryParams.timeType === 'month'
? 'data-type data-type-selected'
: 'data-type'
"
class="data-type"
>
</div>
<div class="other-query">
<span>日期</span>
<el-date-picker
v-if="queryParams.timeType === 'day'"
v-model="time"
type="date"
style="width: 150px"
placeholder="选择日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd 00:00:00"
:clearable="false"
>
</el-date-picker>
<el-date-picker
v-model="time"
v-if="queryParams.timeType === 'month'"
type="month"
style="width: 150px"
format="yyyy-MM"
value-format="yyyy-MM-01 00:00:00"
:clearable="false"
placeholder="选择月"
>
</el-date-picker>
<el-input
style="width: 150px"
v-model="queryParams.deviceId"
placeholder="输入设备号"
></el-input>
<el-button type="primary" @click="handleQuery" size="small"
>查询</el-button
>
</div>
<div class="other-print">
<i class="el-icon-printer"></i>
</div>
</div>
</div>
<div class="e-alarm-echarts">
<e-echarts-bar
ref="echartsLineTrend"
:styles="echartsOption.styles"
:colorList="echartsOption.colorList"
:eId="echartsOption.eId"
:option="resultOption"
></e-echarts-bar>
</div>
<div class="e-alarm-table">
<el-table v-loading="tableLoading" :data="tableList" :height="total > 0 ? '230px': '270px'">
<el-table-column
label="设备名称"
width="120px"
align="left"
prop="deviceName"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.deviceName">
{{ scope.row.deviceName }}
</span>
</template>
</el-table-column>
<el-table-column
label="设备号"
align="center"
width="150px"
prop="deviceId"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.deviceId">
{{ scope.row.deviceId }}
</span>
</template>
</el-table-column>
<el-table-column
label="事件ID"
align="left"
width="150"
prop="recordId"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.recordId">
{{ scope.row.recordId }}
</span>
</template>
</el-table-column>
<el-table-column label="地址" align="left" prop="projectAddress">
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.address">
{{ scope.row.address }}
</span>
</template>
</el-table-column>
<el-table-column
label="线路"
width="60px"
align="center"
prop="lineType"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.lineType == '0' ">
{{ scope.row.lineType == '0' ? '总路' : '支路'}}
</span>
</template>
</el-table-column>
<el-table-column
label="报警类型"
width="100px"
align="center"
prop="typeName"
/>
<el-table-column
label="报警时间"
align="center"
width="100"
prop="alarmTime"
/>
<el-table-column
label="进度"
width="80px"
align="left"
prop="deviceName"
>
<template slot-scope="scope">
<span v-if="scope.row.processStatus === 'UNPROCESS'" style="color: #FF2F60;">未开始</span>
<span v-else-if="scope.row.processStatus === 'PROCESSED'" style="color: #25F094;">已处理</span>
<span v-else style="color: #25F094;">处理中</span>
</template>
</el-table-column>
<el-table-column
label="耗时"
width="150px"
align="center"
prop="deviceName"
>
<template slot-scope="scope">
<e-timing
:startTime="scope.row.alarmTime"
:endTime="scope.row.processTime || parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s}')"
></e-timing>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="pageParams.pageNum"
:limit.sync="pageParams.pageSize"
@pagination="getProjectAlarmTable"
/>
</div>
</div>
</template>
<script>
import EEchartsBar from "@/components/Echarts/EEchartsBar";
import { projectAlarmEcharts, projectAlarmTable } from "@/api/iot/project_new";
import ETiming from './ETiming'
export default {
name: "ProjectAlarmManage",
components: {
EEchartsBar,
ETiming
},
props: {
projectInfo: {
type: Object,
require: true,
},
sourceId: {
type: [Number, String],
require: true,
},
tempType: {
type: String,
require: true
}
},
data() {
return {
templateType: "A", // A: BE
time: "",
queryParams: {
typeCode: "A",
timeType: "day",
time: "",
deviceId: "",
},
pageParams: {
pageNum: 1,
pageSize: 10
},
echartsOption: {
styles: "width: 100%; height: 100%;",
colorList: ["#1890FF", "#EE6666", "#FFCC00"],
eId: "projectAlaramEchartsBar",
},
resultOption: {
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
xAxis: [
{
type: "category",
data: [],
axisTick: {
alignWithLabel: true,
},
},
],
yAxis: [
{
type: "value",
},
],
series: [
{
name: "",
type: "bar",
barWidth: "60%",
data: [],
},
],
},
tableList: [],
tableLoading: false,
total: 0,
};
},
watch: {
sourceId(val) {
this.init()
}
},
created() {
this.init();
},
methods: {
handleQuery() {
this.pageParams.pageNum = 1;
this.time =
this.queryParams.timeType === "day"
? this.parseTime(new Date(this.time), "{y}-{m}-{d} 00:00:00")
: this.parseTime(new Date(this.time), "{y}-{m}-01 00:00:00");
this.getProjectAlarmEcharts();
this.getProjectAlarmTable();
},
//
handleEachartsBarData(list, axisKey, seriesKey) {
var xAxisData = [],
seriesData = [];
if (list && list.length > 0) {
list.forEach((v) => {
xAxisData.push(v[axisKey]);
seriesData.push(v[seriesKey]);
});
}
return { xAxisData: xAxisData, seriesData: seriesData };
},
getProjectAlarmEcharts() {
this.resultOption.xAxis[0].data = [];
this.resultOption.series[0].data = [];
projectAlarmEcharts(
Object.assign(this.queryParams, {
projectId: this.sourceId,
time: this.time,
})
).then((res) => {
let result = this.handleEachartsBarData(
res.data,
"typeName",
"alarmCount"
);
this.resultOption.xAxis[0].data = result["xAxisData"];
this.resultOption.series[0].data = result["seriesData"];
this.$forceUpdate();
});
},
//
getProjectAlarmTable() {
this.tableLoading = true;
projectAlarmTable(
Object.assign(this.queryParams, {
projectId: this.sourceId,
time: this.time,
}, this.pageParams)
).then((res) => {
this.tableList = res.rows;
this.total = res.total;
this.tableLoading = false;
this.$forceUpdate();
});
},
init() {
this.time =
this.queryParams.timeType === "day"
? this.parseTime(new Date(), "{y}-{m}-{d} 00:00:00")
: this.parseTime(new Date(), "{y}-{m}-01 00:00:00");
},
},
};
</script>
<style lang="scss">
.e-project-alarm-manage {
width: 100%;
height: 100%;
display: flex;
flex-wrap: wrap;
.e-alarm-heard {
width: 100%;
height: 40px;
display: flex;
justify-content: space-between;
align-items: center;
.heard-query {
width: 50%;
height: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
.data-type {
width: 32px;
height: 32px;
background: #f4f5f7;
border-radius: 50%;
font-size: 14px;
font-family: Source Han Sans CN;
font-weight: 300;
color: #6b778c;
display: flex;
justify-content: center;
align-items: center;
margin: 0 5px;
cursor: default;
}
.data-type-selected {
background: #1890ff;
color: #f4f5f7;
}
.other-query {
display: flex;
width: 420px;
justify-content: space-evenly;
align-items: center;
}
.other-print {
font-size: 20px;
}
.other-print:hover {
color: #1890ff;
}
}
}
.e-alarm-echarts {
width: 100%;
height: 300px;
}
.e-alarm-table {
height: 280px;
width: 100%;
padding-top: 10px;
}
.pagination-container {
margin-top: 5px;
height: 35px;
}
}
</style>

View File

@ -24,16 +24,33 @@
</span> </span>
</div> </div>
<div class="right-operate"> <div class="right-operate">
<div class="operate-refresh" @click="handleRefresh"> <div class="operate-refresh" @click="handleRefresh">刷新</div>
刷新 <div
</div> :class="
<div :class="tableSelectList && tableSelectList.length > 0 ? 'operate-onekey-on' : 'operate-onekey-on but-disable'" @click="handleChildStatus('true')"> tableSelectList && tableSelectList.length > 0
? 'operate-onekey-on'
: 'operate-onekey-on but-disable'
"
@click="handleChildStatus('true')"
>
一键合闸 一键合闸
</div> </div>
<div :class="tableSelectList && tableSelectList.length > 0 ? 'operate-onekey-on' : 'operate-onekey-on but-disable'" @click="handleChildStatus('false')"> <div
:class="
tableSelectList && tableSelectList.length > 0
? 'operate-onekey-on'
: 'operate-onekey-on but-disable'
"
@click="handleChildStatus('false')"
>
一键分闸 一键分闸
</div> </div>
<el-select v-model="queryParams.prodKey" style="margin-left: 5xp; width: 130px;" placeholder="请选择项目类型" size="small"> <el-select
v-model="queryParams.prodKey"
style="margin-left: 5xp; width: 130px"
placeholder="请选择项目类型"
size="small"
>
<el-option <el-option
v-for="dict in projectModelList" v-for="dict in projectModelList"
:key="dict.prodKey" :key="dict.prodKey"
@ -42,7 +59,6 @@
@change="getTableFilterList" @change="getTableFilterList"
></el-option> ></el-option>
</el-select> </el-select>
</div> </div>
</div> </div>
<div class="device-children-center"> <div class="device-children-center">
@ -52,7 +68,12 @@
:tableTotal="deviceTotal" :tableTotal="deviceTotal"
:queryParams="queryParams" :queryParams="queryParams"
:tableList="tableList" :tableList="tableList"
:filterList="[...defaultFilterList, ...filterList]" :filterList="[
...defaultFilterList,
...filterList,
...status,
...operate,
]"
:isIndex="true" :isIndex="true"
:tableHeight="tableList.length > 0 ? '470px' : '495px'" :tableHeight="tableList.length > 0 ? '470px' : '495px'"
:isSelect="true" :isSelect="true"
@ -60,18 +81,52 @@
@tableSelectionChange="handleTableChange" @tableSelectionChange="handleTableChange"
@handleQuery="handleQuery" @handleQuery="handleQuery"
> >
<template v-slot:operate="operate"> <template v-slot:operate="scope">
<div> <div class="children-device-operate">
<span>{{ operate }}</span> <span
@click="handleOpening(scope.row)"
:class="
scope.row.switch === 0 || scope.row.switch === undefined
? 'span-disable'
: ''
"
>
<i class="iconfont iconfenzha"></i>
分闸
</span>
<span
@click="handleSwitchOn(scope.row)"
:class="scope.row.switch === 1 ? 'span-disable' : ''"
>
<i class="iconfont iconhezha"></i>
合闸
</span>
</div> </div>
</template> </template>
<template v-slot:deviceState="scope">
<span
:class="
scope.row.deviceState === 'ONLINE'
? 'children-device-online'
: 'children-device-offline'
"
>
{{ scope.row.deviceState === "ONLINE" ? "已通" : "已断" }}
</span>
</template>
</e-dynamic-table> </e-dynamic-table>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import EDynamicTable from "./EDynamicTable"; import EDynamicTable from "./EDynamicTable";
import { listProjectDevice, listProjectModel, listProjectTableFilter } from '@/api/iot/project_new' import {
listProjectDevice,
listProjectModel,
listProjectTableFilter,
} from "@/api/iot/project_new";
import { setSwitchControl } from "@/api/iot/device"; import { setSwitchControl } from "@/api/iot/device";
import { webSocketProjectGatewayUrl } from "@/config/env"; import { webSocketProjectGatewayUrl } from "@/config/env";
export default { export default {
@ -107,7 +162,7 @@ export default {
label: "线路名称", label: "线路名称",
align: "center", align: "center",
prop: "deviceName", prop: "deviceName",
width: "150px" width: "150px",
}, },
{ {
label: "型号", label: "型号",
@ -118,9 +173,17 @@ export default {
], ],
filterList: [], filterList: [],
status: {
label: "状态",
align: "center",
prop: "deviceState",
width: "120px",
slot: true,
slotName: "deviceState",
},
operate: { operate: {
label: "操作", label: "操作",
align: "left", align: "center",
prop: "operate", prop: "operate",
width: "200px", width: "200px",
slot: true, slot: true,
@ -131,12 +194,12 @@ export default {
stompClient: null, stompClient: null,
socket_flag: true, socket_flag: true,
timeout_flag: null, timeout_flag: null,
deviceTotal: 0 deviceTotal: 0,
}; };
}, },
created() { created() {
this.tableLoading = true this.tableLoading = true;
this.getProjectModelList() this.getProjectModelList();
}, },
methods: { methods: {
handleLinkToHome() { handleLinkToHome() {
@ -146,69 +209,87 @@ export default {
handleTableFilter(list) { handleTableFilter(list) {
var resultList = []; var resultList = [];
if (list && list.length > 0) { if (list && list.length > 0) {
list.forEach(v => { list.forEach((v) => {
resultList.push({ resultList.push({
label: v['unitName'] ? `${v['name']}(${v['unitName']})` : v['name'], label: v["unitName"] ? `${v["name"]}(${v["unitName"]})` : v["name"],
align: "center", align: "center",
prop: v['key'], prop: v["key"],
width: list.length > 5 ? '200px' : '', width: list.length > 5 ? "200px" : "",
}) });
}); });
}; }
return resultList; return resultList;
}, },
// //
getProjectModelList() { getProjectModelList() {
listProjectModel({ listProjectModel({
projectId: this.sourceId, projectId: this.sourceId,
deviceTags: this.deviceType || '', deviceTags: this.deviceType || "",
pid: this.gatewayDevice.deviceId || '' pid: this.gatewayDevice.deviceId || "",
}).then(res => { }).then((res) => {
this.projectModelList = res.data this.projectModelList = res.data;
if (this.projectModelList && this.projectModelList.length > 0) { if (this.projectModelList && this.projectModelList.length > 0) {
this.queryParams.prodKey = this.projectModelList[0]['prodKey'] this.queryParams.prodKey = this.projectModelList[0]["prodKey"];
this.getTableFilterList() this.getTableFilterList();
}; }
}) });
}, },
// //
getTableFilterList() { getTableFilterList() {
this.filterList = [] this.filterList = [];
this.getChildrenDeviceList() this.getChildrenDeviceList();
listProjectTableFilter({ listProjectTableFilter({
prodKey: this.queryParams.prodKey prodKey: this.queryParams.prodKey,
}).then(res => { }).then((res) => {
this.filterList = this.handleTableFilter(res.data) this.filterList = this.handleTableFilter(res.data);
this.$forceUpdate() this.$forceUpdate();
this.tableLoading = false this.tableLoading = false;
}) });
}, },
// --- // ---
getChildrenDeviceList() { getChildrenDeviceList() {
this.tableList = [] this.tableList = [];
listProjectDevice(Object.assign({ listProjectDevice(
projectId: this.sourceId || '', Object.assign(
deviceTags: this.deviceType || '', {
pid: this.gatewayDevice.deviceId || '' projectId: this.sourceId || "",
}, this.queryParams)).then(res => { deviceTags: this.deviceType || "",
this.tableList = res.rows pid: this.gatewayDevice.deviceId || "",
this.deviceTotal = res.total },
this.queryParams
)
).then((res) => {
this.tableList = res.rows;
this.deviceTotal = res.total;
if (this.stompClient) { if (this.stompClient) {
this.closeSocket() this.closeSocket();
} }
this.connection() this.connection();
}) });
}, },
// //
handleTableChange(e) { handleTableChange(e) {
if (e && e.length > 0) { if (e && e.length > 0) {
this.tableSelectList = e.map(v => v['deviceId']) this.tableSelectList = e.map((v) => v["deviceId"]);
} else { } else {
this.tableSelectList = [] this.tableSelectList = [];
}
},
handleOpening(row) {
if (row.switch === 1) {
this.handleSendSwitchDirect("false", row.deviceId);
}
},
handleSwitchOn(row) {
if (row.switch !== 1) {
this.handleSendSwitchDirect("true", row.deviceId);
} }
}, },
// 线
handleChildStatus(type) { handleChildStatus(type) {
this.handleSendSwitchDirect(type, this.tableSelectList.toString());
},
// 线
handleSendSwitchDirect(type, ids) {
this.$prompt("请输入登录密码", "提示", { this.$prompt("请输入登录密码", "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
@ -220,22 +301,22 @@ export default {
data: { data: {
cmd: "set_switch", cmd: "set_switch",
params: { params: {
switch: 1 switch: 1,
}, },
}, },
deviceId: '', deviceId: "",
verifyKey: value, verifyKey: value,
}; };
switch(type) { switch (type) {
case 'true': case "true":
params.data.params.switch = 1; params.data.params.switch = 1;
params.deviceId = this.tableSelectList.toString(); params.deviceId = ids;
break; break;
case 'false': case "false":
params.data.params.switch = 0; params.data.params.switch = 0;
params.deviceId = this.tableSelectList.toString(); params.deviceId = ids;
break; break;
} }
@ -246,23 +327,23 @@ export default {
}, },
handleRefresh() { handleRefresh() {
this.queryParams.pageNum = 1; this.queryParams.pageNum = 1;
this.getChildrenDeviceList() this.getChildrenDeviceList();
}, },
// //
handleQuery(e) { handleQuery(e) {
this.queryParams = Object.assign(this.queryParams, e) this.queryParams = Object.assign(this.queryParams, e);
this.getChildrenDeviceList() this.getChildrenDeviceList();
}, },
// socket // socket
handleDeviceInfo(param) { handleDeviceInfo(param) {
if (this.tableList && this.tableList.length > 0) { if (this.tableList && this.tableList.length > 0) {
this.tableList = this.tableList.map(v => { this.tableList = this.tableList.map((v) => {
if (v['deviceId'] === param['deviceId']) { if (v["deviceId"] === param["deviceId"]) {
return Object.assign(v, param) return Object.assign(v, param);
} else { } else {
return v return v;
} }
}) });
} }
}, },
// ws // ws
@ -276,9 +357,9 @@ export default {
if (!this.tableList || this.length <= 0) { if (!this.tableList || this.length <= 0) {
return; return;
} }
let deviceIds = this.tableList.map(v => v['deviceId']) let deviceIds = this.tableList.map((v) => v["deviceId"]);
this.stompClient = new WebSocket( this.stompClient = new WebSocket(
`${webSocketProjectGatewayUrl}/${this.getGuid()}/${ deviceIds.toString() }` `${webSocketProjectGatewayUrl}/${this.getGuid()}/${deviceIds.toString()}`
); );
this.stompClient.onmessage = this.socket_message; this.stompClient.onmessage = this.socket_message;
this.stompClient.onclose = this.socket_onclose; this.stompClient.onclose = this.socket_onclose;
@ -287,8 +368,8 @@ export default {
console.log("wsljcg:=", evt); console.log("wsljcg:=", evt);
const data = JSON.parse(evt.data); const data = JSON.parse(evt.data);
// this.actualEnergyCensus = data.params || {}; // this.actualEnergyCensus = data.params || {};
console.log('socket-message:', data) console.log("socket-message:", data);
this.handleDeviceInfo(data) this.handleDeviceInfo(data);
this.$forceUpdate(); this.$forceUpdate();
}, },
socket_onclose(e) { socket_onclose(e) {
@ -311,18 +392,19 @@ export default {
clearTimeout(this.timeout_flag); clearTimeout(this.timeout_flag);
}, },
getGuid() { getGuid() {
return "xxxxxxx_xxxxx_4xxx_yxxx_xxxxxxxxxxxx".replace(/[xy]/g, function( return "xxxxxxx_xxxxx_4xxx_yxxx_xxxxxxxxxxxx".replace(
c /[xy]/g,
) { function (c) {
var r = (Math.random() * 16) | 0, var r = (Math.random() * 16) | 0,
v = c == "x" ? r : (r & 0x3) | 0x8; v = c == "x" ? r : (r & 0x3) | 0x8;
return v.toString(16); return v.toString(16);
}); }
);
}, },
}, },
destroyed() { destroyed() {
this.closeSocket() this.closeSocket();
} },
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
@ -416,7 +498,7 @@ export default {
.operate-refresh { .operate-refresh {
width: 60px; width: 60px;
height: 30px; height: 30px;
background: #F4F5F7; background: #f4f5f7;
border-radius: 5px; border-radius: 5px;
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -426,7 +508,7 @@ export default {
.operate-onekey-on { .operate-onekey-on {
width: 75px; width: 75px;
height: 30px; height: 30px;
background: #F4F5F7; background: #f4f5f7;
border-radius: 5px; border-radius: 5px;
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -436,10 +518,48 @@ export default {
color: #344567; color: #344567;
} }
.but-disable { .but-disable {
color: #6B778C; color: #6b778c;
opacity: 0.5; opacity: 0.5;
} }
} }
} }
.device-children-center {
.children-device-operate {
display: flex;
justify-content: space-evenly;
align-items: baseline;
cursor: default;
> span {
display: block;
width: 50px;
text-align: center;
font-size: 13px;
font-family: Source Han Sans CN;
font-weight: 300;
color: #1890ff;
align-items: center;
> i {
font-size: 16px;
margin-right: 1px;
}
}
.span-disable {
color: #6b778c;
opacity: 0.5;
}
}
.children-device-online {
font-size: 13px;
font-family: Source Han Sans CN;
font-weight: 400;
color: #009003;
}
.children-device-offline {
font-size: 13px;
font-family: Source Han Sans CN;
font-weight: 400;
color: #ff0000;
}
}
} }
</style> </style>

View File

@ -103,7 +103,7 @@
<div class="object-device-body"> <div class="object-device-body">
<div class="card-body-info"> <div class="card-body-info">
<div class="card-body-left"> <div class="card-body-left">
<img :src="devItem['deviceImage'] ? devItem['deviceImage'] : '/images/devcie_default.png'" /> <img :src="devItem['deviceImage'] ? getIotFileUrl(devItem['deviceImage']) : '/images/devcie_default.png'" />
</div> </div>
<div class="card-body-right"> <div class="card-body-right">
<span :title="devItem.deviceId">{{ devItem.deviceId }}</span> <span :title="devItem.deviceId">{{ devItem.deviceId }}</span>
@ -136,6 +136,7 @@ import ESimpleCard from "@/components/Cards/index";
import EDeviceChildren from './EDeviceChildren' import EDeviceChildren from './EDeviceChildren'
import { webSocketProjectGatewayUrl } from "@/config/env"; import { webSocketProjectGatewayUrl } from "@/config/env";
import { listProjectDevice, listProjectModel } from '@/api/iot/project_new' import { listProjectDevice, listProjectModel } from '@/api/iot/project_new'
import { getIotFileUrl } from "@/utils/hciot"
export default { export default {
name: "EDeviceTable", name: "EDeviceTable",
components: { components: {
@ -238,6 +239,7 @@ export default {
this.initHTML() this.initHTML()
}, },
methods: { methods: {
getIotFileUrl,
// init html // init html
initHTML() { initHTML() {
this.getGatewayList(); this.getGatewayList();

View File

@ -1,14 +1,60 @@
<template> <template>
<div class="e-nav-menu"> <div class="e-nav-menu">
<div <div
:class="value === item[props['key']] ? 'nav-menu-item menu-selected' : 'nav-menu-item'" :class="
v-for="(item) in activeList" value === item[props['key']]
? 'nav-menu-item menu-selected'
: 'nav-menu-item'
"
v-for="item in activeList"
:key="item[props['key']]" :key="item[props['key']]"
:style="{
flexWrap:
item[props['children']] && item[props['children']].length > 0
? 'wrap'
: '',
height:
developList.indexOf(item[props['key']]) >= 0 &&
item[props['children']] &&
item[props['children']].length > 0
? 'auto'
: ''
}"
@click="handleClick(item)" @click="handleClick(item)"
> >
<svg-icon slot="prefix" icon-class="A_yuanjiaodian" class="icon-left" /> <svg-icon slot="prefix" icon-class="A_yuanjiaodian" class="icon-left" />
<div class="nav-item-title">{{ item[props["label"]] }}</div> <div class="nav-item-title">{{ item[props["label"]] }}</div>
<i class="el-icon-arrow-right icon-right"></i> <i class="el-icon-arrow-right icon-right"></i>
<div
style="height: 100%; width: 100%;"
v-if="
developList.indexOf(item[props['key']]) >= 0 &&
item[props['children']] &&
item[props['children']].length > 0
"
>
<div
:class="
value === childItem[props['key']]
? 'nav-menu-item nav-menu-children menu-selected'
: 'nav-menu-item nav-menu-children'
"
v-show="
developList.indexOf(item[props['key']]) >= 0 &&
item[props['children']] &&
item[props['children']].length > 0
"
v-for="childItem in item[props['children']]"
:key="childItem[props['key']]"
@click.stop="handleClick(childItem)"
>
<i
class="icon iconfont icontongxun icon-left"
style="margin-right: 5px"
></i>
<div class="nav-item-title">{{ childItem[props["label"]] }}</div>
</div>
</div>
</div> </div>
</div> </div>
</template> </template>
@ -19,8 +65,8 @@ export default {
value: { value: {
type: [String, Number], type: [String, Number],
default: () => { default: () => {
return 0 return 0;
} },
}, },
props: { props: {
type: Object, type: Object,
@ -28,6 +74,7 @@ export default {
return { return {
label: "label", label: "label",
key: "key", key: "key",
children: "children",
}; };
}, },
}, },
@ -37,21 +84,58 @@ export default {
return [ return [
{ {
label: "项目管理", label: "项目管理",
key: "projectOt" key: "projectOt",
}, },
{ {
label: "设备管理", label: "设备管理",
key: "projectOt" key: "projectOt",
}, },
]; ];
}, },
}, },
singleDevelop: {
type: Boolean,
default: () => {
return true;
},
},
defaultDevelop: {
type: Array,
default: () => {
return [];
},
},
},
data() {
return {
developList: [],
};
},
created() {
this.developList = this.defaultDevelop;
}, },
methods: { methods: {
handleClick(row) { handleClick(row) {
this.$emit('input', row[this.props['key']]); if (
} !row[this.props["children"]] ||
} row[this.props["children"]].length <= 0
) {
this.$emit("input", row);
} else {
if (this.developList.indexOf(row[this.props["key"]]) >= 0) {
this.developList = this.developList.filter((v) => {
v !== row[this.props["key"]];
});
} else {
//
if (this.singleDevelop) {
this.developList = [];
}
this.developList.push(row[this.props["key"]]);
}
}
},
},
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@ -59,7 +143,7 @@ export default {
width: 150px; width: 150px;
height: 100%; height: 100%;
padding-top: 15px; padding-top: 15px;
border-right: 1px solid #E8E8E8; border-right: 1px solid #e8e8e8;
.nav-menu-item { .nav-menu-item {
width: 100%; width: 100%;
height: 32px; height: 32px;
@ -68,23 +152,34 @@ export default {
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 0 10px; padding: 0 10px;
cursor: default;
.nav-item-title { .nav-item-title {
font-size: 14px; font-size: 14px;
font-family: 'Source Han Sans CN'; font-family: "Source Han Sans CN";
font-weight: 300; font-weight: 400;
color: #344567; color: #344567;
color: #626262;
height: 32px;
display: flex;
align-items: center;
} }
.icon-left { .icon-left {
font-size: 18px; font-size: 16px;
color: #9da3af;
} }
.icon-right { .icon-right {
font-size: 18px font-size: 18px;
} }
} }
.nav-menu-children {
padding-left: 35px;
padding-left: 17px;
justify-content: flex-start;
}
.menu-selected { .menu-selected {
background: #F4F5F7; background: #f4f5f7;
.nav-item-title { .nav-item-title {
color: #1890FF; color: #1890ff;
} }
} }
} }

View File

@ -0,0 +1,344 @@
<template>
<div class="e-project-electricity">
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
label-width="68px"
>
<el-form-item label="空间:" prop="parentId">
<treeselect
style="width: 200px"
v-model="queryParams.parentId"
:options="querySpaceOptions"
:normalizer="normalizer"
placeholder="请选择空间"
/>
</el-form-item>
<el-form-item label="时间:" prop="queryTime">
<el-date-picker
v-model="queryTime"
type="datetimerange"
:clearable="false"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
>
</el-date-picker>
</el-form-item>
<el-form-item label="设备号:" prop="deviceId">
<el-input
style="width: 150px"
v-model="queryParams.deviceId"
placeholder="输入设备号"
></el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
icon="el-icon-search"
@click="handleQuery"
>搜索</el-button
>
</el-form-item>
</el-form>
<div class="debuff-table">
<el-table
v-loading="tableLoading"
:data="tableList"
:height="total > 0 ? '520px' : '560px'"
>
<el-table-column
label="设备名称"
align="left"
width="180px"
prop="deviceName"
></el-table-column>
<el-table-column
label="设备号"
align="left"
width="180px"
prop="deviceId"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.deviceId">
{{ scope.row.deviceId }}
</span>
</template>
</el-table-column>
<el-table-column label="地点" align="left" prop="address">
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.address">
{{ scope.row.address }}
</span>
</template>
</el-table-column>
<el-table-column label="本月电量" align="center" width="100" prop="address">
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.address">
{{ scope.row.address || 0 }}
</span>
</template>
</el-table-column>
<el-table-column label="上月电量" align="center" width="100" prop="address">
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.address">
{{ scope.row.address || 0 }}
</span>
</template>
</el-table-column>
<el-table-column label="对比" align="center" width="100" prop="address">
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.address">
{{ scope.row.address || 0 }}
</span>
</template>
</el-table-column>
<el-table-column label="联系人" align="center" width="100" prop="name">
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.name">
{{ scope.row.name}}
</span>
</template>
</el-table-column>
<el-table-column label="联系电话" align="center" width="120" prop="phone">
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.phone">
{{ scope.row.phone}}
</span>
</template>
</el-table-column>
<el-table-column label="状态" align="center" width="100" prop="status">
<template slot-scope="scope">
<div class="e-table-dev-status">
<span>{{ scope.row.deviceStatus == '0' ? '启用':'禁用' }}</span>
<el-divider direction="vertical"></el-divider>
<span class="c-success" v-if="scope.row.deviceState === 'ONLINE'">在线</span>
<span class="c-danger" v-else-if="scope.row.deviceState === 'OFFLINE'">离线</span>
<span class="c-warning" v-else-if="scope.row.deviceState === 'OUTLINE'">脱线</span>
<span class="c-info" v-else-if="scope.row.deviceState === 'UNACTIVE'">未激活</span>
</div>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
width="100"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-search"
@click="handleLinkDevDetails(scope.row)"
>详情</el-button>
</template>
</el-table-column>
</el-table>
<pagination
style="margin-top: 5px; height: 35px"
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</div>
</template>
<script>
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { projectEneElectricityTable } from "@/api/iot/project_new";
import { listSpace } from "@/api/iot/space";
export default {
name: "EElectricity",
props: {
projectInfo: {
type: Object,
require: true,
},
sourceId: {
type: [Number, String],
require: true,
},
tempType: {
type: String,
require: true,
},
},
components: {
Treeselect,
},
data() {
return {
queryParams: {
parentId: null,
deviceId: '',
},
queryTime: [],
querySpaceOptions: [],
tableList: [],
tableLoading: false,
total: 2
};
},
watch: {
sourceId(val) {
if (val !== null && val !== undefined) {
this.init();
}
},
},
created() {
this.init()
},
methods: {
init() {
this.queryTime = [
this.parseTime(new Date(), "{y}-{m}-{d} 00:00:00"),
this.parseTime(new Date(), "{y}-{m}-{d} {h}:{i}:{s}"),
];
this.getSpaceList();
this.handleQuery();
},
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
handleLinkDevDetails(row) {
var deviceUrl =
this.$store.getters.tenantId === 0
? "/device/device"
: "/device_tenant/device_tenant";
this.$router.push({ path: deviceUrl, query: { 'deviceId': row.deviceId, 'tempType': 'details' } })
},
/** 转换项目空间数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.spaceId,
label: node.spaceName,
children: node.children
};
},
/** 查询项目空间拉树结构 */
getSpaceList() {
let param = {
projectId: this.sourceId,
};
listSpace(param).then((response) => {
this.querySpaceOptions = [];
const data = { spaceId: 0, spaceName: "顶级节点", children: [] };
data.children = this.handleTree(response.data, "spaceId", "parentId");
this.querySpaceOptions.push(data);
});
},
//
getList() {
console.log('query-', Object.assign(this.queryParams, {
projectId: this.sourceId,
startTime: this.parseTime(
new Date(this.queryTime[0]),
"{y}-{m}-{d} {h}:{i}:{s}"
),
endTime: this.parseTime(
new Date(this.queryTime[1]),
"{y}-{m}-{d} {h}:{i}:{s}"
)
}))
this.tableList = [
{
name: '林电工',
deviceId: '123456789764',
deviceName: 'HC-3456789764',
address: '西外环中路18栋18楼101#',
phone: '15860888888',
deviceState: 'ONLINE',
deviceStatus: '0'
},
{
name: '林电工',
deviceId: '123456789764',
deviceName: 'HC-3456789764',
address: '西外环中路18栋18楼101#',
phone: '15860888888',
deviceState: 'ONLINE',
deviceStatus: '0'
}
]
// projectAbnormalRecordTable(
// Object.assign(this.queryParams, {
// projectId: this.sourceId,
// startTime: this.parseTime(
// new Date(this.queryTime[0]),
// "{y}-{m}-{d} {h}:{i}:{s}"
// ),
// endTime: this.parseTime(
// new Date(this.queryTime[1]),
// "{y}-{m}-{d} {h}:{i}:{s}"
// ),
// typeCode: this.tempType,
// })
// ).then((res) => {
// this.tableList = res.rows;
// this.total = res.total;
// });
},
},
};
</script>
<style lang="scss">
.e-project-electricity {
.electricity-query {
width: 100%;
height: 40px;
justify-content: start;
align-items: center;
display: flex;
margin-bottom: 10px;
}
.e-table-dev-status {
width: 100%;
height: 25px;
display: flex;
justify-content: center;
align-items: center;
> span {
font-size: 13px;
font-family: Source Han Sans CN;
font-weight: 300;
color: #6B778C;
line-height: 50px;
}
.c-success {
color: #00C805;
}
.c-warning {
color: #e6a23c;
}
.c-danger {
color: #f56c6c;
}
.c-info {
color: #909399;
}
}
}
</style>

View File

@ -0,0 +1,256 @@
<template>
<div class="e-project-debuff">
<div class="debuff-query">
<el-date-picker
v-model="queryTime"
style="margin: 0 10px"
type="datetimerange"
:clearable="false"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
>
</el-date-picker>
<el-input
style="width: 150px; margin: 0 10px 0 0"
v-model="queryParams.deviceId"
placeholder="输入设备号"
></el-input>
<el-button
type="primary"
style="margin: 0 10px 0 0"
@click="queryGetList"
size="small"
>查询</el-button
>
<el-dropdown>
<el-button size="small">
导出<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="handleExport('nowPage')"
>导出当前页</el-dropdown-item
>
<el-dropdown-item @click.native="handleExport('all')">导出全部</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<div class="debuff-table">
<el-table
v-loading="tableLoading"
:data="tableList"
:height="total > 0 ? '530px' : '570px'"
>
<el-table-column
label="事件ID"
width="200px"
align="left"
prop="recordId"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.recordId">
{{ scope.row.recordId }}
</span>
</template>
</el-table-column>
<el-table-column label="地点" align="left" prop="address">
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.address">
{{ scope.row.address }}
</span>
</template>
</el-table-column>
<el-table-column
label="设备号"
align="left"
width="180px"
prop="deviceId"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.deviceId">
{{ scope.row.deviceId }}
</span>
</template>
</el-table-column>
<el-table-column
label="线路"
width="80px"
align="center"
prop="lineType"
>
<template slot-scope="scope">
<span class="lay-table-textarea">
{{ scope.row.lineType == '0' ? "总路" : "支路" }}
</span>
</template>
</el-table-column>
<el-table-column
label="检查的规则"
width="180px"
align="center"
prop="typeName"
/>
<el-table-column
label="异常的描述"
align="left"
width="200px"
prop="alarmContent"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.alarmContent">
{{ scope.row.alarmContent }}
</span>
</template>
</el-table-column>
<el-table-column
label="联系人"
width="180px"
align="center"
prop="contacts"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.name">
{{ scope.row.name }} {{ scope.row.phone }}
</span>
</template>
</el-table-column>
</el-table>
<pagination
style="margin-top: 5px; height: 35px"
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</div>
</template>
<script>
import {
projectAbnormalRecordTable,
projectAbnormalRecordExport,
} from "@/api/iot/project_new";
import { downloadFile } from '@/utils/hciot'
export default {
name: "EDebuff",
props: {
projectInfo: {
type: Object,
require: true,
},
sourceId: {
type: [Number, String],
require: true,
},
tempType: {
type: String,
require: true,
},
},
watch: {
sourceId(val) {
if (val !== null && val !== undefined) {
this.queryGetList();
}
},
},
data() {
return {
queryParams: {
deviceId: "",
pageNum: 1,
pageSize: 10,
},
tableLoading: false,
tableList: [],
queryTime: [],
total: 0,
};
},
created() {
this.queryTime = [
this.parseTime(new Date(), "{y}-{m}-{d} 00:00:00"),
this.parseTime(new Date(), "{y}-{m}-{d} {h}:{i}:{s}"),
];
this.queryGetList();
},
methods: {
queryGetList() {
this.queryParams.pageNum = 1;
this.getList();
},
getList() {
projectAbnormalRecordTable(
Object.assign(this.queryParams, {
projectId: this.sourceId,
startTime: this.parseTime(
new Date(this.queryTime[0]),
"{y}-{m}-{d} {h}:{i}:{s}"
),
endTime: this.parseTime(
new Date(this.queryTime[1]),
"{y}-{m}-{d} {h}:{i}:{s}"
),
typeCode: this.tempType,
})
).then((res) => {
this.tableList = res.rows;
this.total = res.total;
});
},
/** 导出按钮操作 */
handleExport(type) {
let queryParams = {};
queryParams = JSON.parse(JSON.stringify(this.queryParams));
if (type === 'all') {
queryParams.pageNum = undefined;
queryParams.pageSize = undefined;
};
queryParams = Object.assign(queryParams, {
projectId: this.sourceId,
typeCode: this.tempType,
startTime: this.parseTime(
new Date(this.queryTime[0]),
"{y}-{m}-{d} {h}:{i}:{s}"
),
endTime: this.parseTime(
new Date(this.queryTime[1]),
"{y}-{m}-{d} {h}:{i}:{s}"
)
});
this.$confirm("是否确认导出所有项目数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(function () {
return projectAbnormalRecordExport(queryParams);
})
.then((response) => {
this.download(response.msg);
});
},
},
};
</script>
<style lang="scss">
.e-project-debuff {
.debuff-query {
width: 100%;
height: 40px;
justify-content: flex-end;
align-items: center;
display: flex;
margin-bottom: 10px;
}
}
</style>

View File

@ -0,0 +1,232 @@
<template>
<div class="e-device-switch-warning">
<div class="warning-query">
<el-date-picker
v-model="queryTime"
style="margin: 0 10px"
type="datetimerange"
:clearable="false"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
>
</el-date-picker>
<el-input
style="width: 150px; margin: 0 10px 0 0"
v-model="queryParams.deviceId"
placeholder="输入设备号"
></el-input>
<el-button
type="primary"
style="margin: 0 10px 0 0"
@click="queryGetList"
size="small"
>查询</el-button
>
<el-dropdown>
<el-button size="small">
导出<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>导出当前页</el-dropdown-item>
<el-dropdown-item>导出全部</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<div class="debuff-table">
<el-table
v-loading="tableLoading"
:data="tableList"
:height="total > 0 ? '530px' : '570px'"
>
<el-table-column
label="事件ID"
width="200px"
align="left"
prop="recordId"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.recordId">
{{ scope.row.recordId }}
</span>
</template>
</el-table-column>
<el-table-column label="地点" align="left" prop="address">
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.address">
{{ scope.row.address }}
</span>
</template>
</el-table-column>
<el-table-column
label="设备号"
align="left"
width="180px"
prop="deviceId"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.deviceId">
{{ scope.row.deviceId }}
</span>
</template>
</el-table-column>
<el-table-column
label="线路"
width="80px"
align="center"
prop="lineType"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.lineType == '0' ">
{{ scope.row.lineType == '0' ? "总路" : "支路" }}
</span>
</template>
</el-table-column>
<el-table-column
label="警示类型"
width="180px"
align="center"
prop="typeName"
/>
<el-table-column
label="警示事件"
width="180px"
align="center"
prop="alarmContent"
/>
</el-table>
<pagination
style="margin-top: 5px; height: 35px"
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
</div>
</template>
<script>
import { projectWarningRecordTable, projectWarningRecordExport } from "@/api/iot/project_new";
export default {
name: "EDeviceSwitchWarning",
props: {
projectInfo: {
type: Object,
require: true,
},
sourceId: {
type: [Number, String],
require: true,
},
tempType: {
type: String,
require: true,
},
},
watch: {
sourceId(val) {
if (val !== null && val !== undefined) {
this.queryGetList();
}
},
},
data() {
return {
queryParams: {
time: "",
deviceId: "",
pageNum: 1,
pageSize: 10,
},
tableLoading: false,
tableList: [],
queryTime: [],
total: 0
};
},
created() {
this.queryTime = [
this.parseTime(new Date(), "{y}-{m}-{d} 00:00:00"),
this.parseTime(new Date(), "{y}-{m}-{d} {h}:{i}:{s}"),
];
this.queryGetList();
},
methods: {
queryGetList() {
this.queryParams.pageNum = 1;
this.getList();
},
getList() {
projectWarningRecordTable(
Object.assign(this.queryParams, {
projectId: this.sourceId,
startTime: this.parseTime(
new Date(this.queryTime[0]),
"{y}-{m}-{d} {h}:{i}:{s}"
),
endTime: this.parseTime(
new Date(this.queryTime[1]),
"{y}-{m}-{d} {h}:{i}:{s}"
),
typeCode: this.tempType,
})
).then((res) => {
this.tableList = res.rows;
this.total = res.total;
});
},
/** 导出按钮操作 */
handleExport(type) {
let queryParams = {};
queryParams = JSON.parse(JSON.stringify(this.queryParams));
if (type === 'all') {
queryParams.pageNum = undefined;
queryParams.pageSize = undefined;
};
queryParams = Object.assign(queryParams, {
projectId: this.sourceId,
typeCode: this.tempType,
startTime: this.parseTime(
new Date(this.queryTime[0]),
"{y}-{m}-{d} {h}:{i}:{s}"
),
endTime: this.parseTime(
new Date(this.queryTime[1]),
"{y}-{m}-{d} {h}:{i}:{s}"
)
});
this.$confirm("是否确认导出所有项目数据项?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(function () {
return projectWarningRecordExport(queryParams);
})
.then((response) => {
this.download(response.msg);
});
},
},
};
</script>
<style lang="scss">
.e-device-switch-warning {
.warning-query {
width: 100%;
height: 40px;
justify-content: flex-end;
align-items: center;
display: flex;
margin-bottom: 10px;
}
}
</style>

View File

@ -0,0 +1,438 @@
<template>
<div class="e-leakage-current">
<div class="e-alarm-heard">
<div class="heard-query">
<div
@click="
() => {
queryParams.timeType = 'day';
}
"
:class="
queryParams.timeType === 'day'
? 'data-type data-type-selected'
: 'data-type'
"
>
</div>
<div
@click="
() => {
queryParams.timeType = 'month';
}
"
:class="
queryParams.timeType === 'month'
? 'data-type data-type-selected'
: 'data-type'
"
class="data-type"
>
</div>
<div class="other-query">
<span>日期</span>
<el-date-picker
v-if="queryParams.timeType === 'day'"
v-model="time"
type="date"
style="width: 150px"
placeholder="选择日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd 00:00:00"
:clearable="false"
>
</el-date-picker>
<el-date-picker
v-model="time"
v-if="queryParams.timeType === 'month'"
type="month"
style="width: 150px"
format="yyyy-MM"
value-format="yyyy-MM-01 00:00:00"
:clearable="false"
placeholder="选择月"
>
</el-date-picker>
<el-input
style="width: 150px"
v-model="queryParams.deviceId"
placeholder="输入设备号"
></el-input>
<el-button type="primary" @click="init" size="small">查询</el-button>
</div>
<!-- <div class="other-print">
<i class="el-icon-printer"></i>
</div> -->
</div>
</div>
<div class="e-alarm-echarts">
<e-echarts-line
ref="echartsLineTrend"
:styles="echartsOption.styles"
:colorList="echartsOption.colorList"
:eId="echartsOption.eId"
:option="resultOption"
></e-echarts-line>
</div>
<div class="e-alarm-table">
<el-table
v-loading="tableLoading"
:data="tableList"
:height="total > 0 ? '230px' : '270px'"
>
<el-table-column
label="设备名称"
width="200px"
align="left"
prop="deviceName"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.deviceName">
{{ scope.row.deviceName }}
</span>
</template>
</el-table-column>
<el-table-column
label="设备号"
align="left"
width="200px"
prop="deviceId"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.deviceId">
{{ scope.row.deviceId }}
</span>
</template>
</el-table-column>
<el-table-column
label="线路"
width="80px"
align="center"
prop="lineType"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.lineType == '0' ">
{{ scope.row.lineType ? "总路" : "支路" }}
</span>
</template>
</el-table-column>
<el-table-column label="地点" align="left" prop="projectAddress">
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.address">
{{ scope.row.address }}
</span>
</template>
</el-table-column>
<el-table-column
label="漏电流(单位:毫安)"
width="150px"
align="center"
prop="typeName"
/>
<el-table-column
label="操作"
align="center"
width="150"
prop="alarmTime"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
@click="handleDetails(scope.row)"
>
<i class="iocnfont icontubiao-zhuzhuangtu"></i>
历史趋势</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="pageParams.pageNum"
:limit.sync="pageParams.pageSize"
@pagination="getDeviceRecordTable"
/>
</div>
</div>
</template>
<script>
import EEchartsLine from "@/components/Echarts/EEchartsLine";
import * as echarts from "echarts";
export default {
name: "ELeakageCurrent",
props: {
projectInfo: {
type: Object,
require: true,
},
sourceId: {
type: [Number, String],
require: true,
},
tempType: {
type: String,
require: true,
},
},
components: {
EEchartsLine
},
data() {
return {
time: "",
queryParams: {
timeType: "day",
time: "",
deviceId: "",
},
pageParams: {
pageNum: 1,
pageSize: 10,
},
echartsOption: {
styles: "width: 100%; height: 100%;",
colorList: ["#EE6666", "#FFCC00"],
eId: "trendEchartsLine",
},
title: "24小时报警情况",
typeName: "alarm",
resultOption: {
color: ["#EE6666", "#FFC900"],
title: {
text: "",
show: false,
},
tooltip: {
trigger: "axis",
},
legend: {
top: 5,
right: 5,
data: ["预警", "报警"],
textStyle: {
color: "#344567",
fontSize: 14,
fontWeight: 400,
},
},
grid: {
left: "20",
right: "20",
bottom: "5",
top: 30,
containLabel: true,
},
xAxis: {
type: "category",
boundaryGap: false,
show: true,
data: [],
splitLine: {
show: false,
},
axisLabel: {
show: true,
textStyle: {
color: "#fff",
},
},
},
yAxis: {
type: "value",
splitLine: {
show: false,
},
axisLabel: {
show: true,
textStyle: {
color: "#fff",
},
},
},
series: [
{
name: "--",
type: "line",
smooth: false,
symbolSize: 2,
markPoint: {
symbolSize: 35,
data: [
{ type: "max", name: "Max" },
{ type: "min", name: "Min" },
],
},
label: {
show: false,
formatter: function (params) {
return echarts.format.formatTime("yyyy-MM-dd", params.value);
},
backgroundColor: "#7581BD",
},
data: [],
},
],
},
total: 0,
tableList: [],
tableLoading: false,
};
},
created() {
this.init();
},
watch: {
sourceId(val) {
if (val !== null && val !== undefined) {
this.init();
}
},
},
methods: {
init() {
this.time =
this.queryParams.timeType === "day"
? this.parseTime(new Date(), "{y}-{m}-{d} 00:00:00")
: this.parseTime(new Date(), "{y}-{m}-01 00:00:00");
this.getDeviceRecordEcharts();
this.getDeviceRecordTable();
},
//
getDeviceRecordEcharts() {
// projectAlarmRecordEcharts(
// Object.assign(this.queryParams, {
// projectId: this.sourceId,
// time: this.time,
// typeCodes: this.tempType,
// })
// ).then((res) => {
// this.resultOption.xAxis.data = res.data["name"];
// this.resultOption.legend.data = Object.keys(res.data).filter(v => { v !== 'name' })
// var list = Object.keys(res.data).map((v) => {
// if (v !== "name") {
// return {
// name: v,
// type: "line",
// smooth: false,
// symbolSize: 2,
// markPoint: {
// symbolSize: 35,
// data: [
// { type: "max", name: "Max" },
// { type: "min", name: "Min" },
// ],
// },
// label: {
// show: false,
// formatter: function (params) {
// return echarts.format.formatTime("yyyy-MM-dd", params.value);
// },
// backgroundColor: "#7581BD",
// },
// data: res.data[v],
// };
// }
// });
// this.resultOption.series = [...list];
// this.updateEcharts();
// });
},
//
getDeviceRecordTable() {
this.tableLoading = true;
this.tableLoading = false;
// projectAlarmRecordTable(
// Object.assign(this.queryParams, {
// projectId: this.sourceId,
// time: this.time,
// typeCodes: this.tempType,
// })
// ).then((res) => {
// this.tableList = res.rows;
// this.tableLoading = false;
// this.total = res.total;
// });
},
//
updateEcharts() {
this.$refs.echartsLineTrend.updateEchart();
},
},
};
</script>
<style lang="scss">
.e-leakage-current {
width: 100%;
height: 100%;
display: flex;
flex-wrap: wrap;
.e-alarm-heard {
width: 100%;
height: 40px;
display: flex;
justify-content: flex-end;
align-items: center;
.heard-query {
width: 50%;
height: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
.data-type {
width: 32px;
height: 32px;
background: #f4f5f7;
border-radius: 50%;
font-size: 14px;
font-family: Source Han Sans CN;
font-weight: 300;
color: #6b778c;
display: flex;
justify-content: center;
align-items: center;
margin: 0 5px;
cursor: default;
}
.data-type-selected {
background: #1890ff;
color: #f4f5f7;
}
.other-query {
display: flex;
width: 420px;
justify-content: space-evenly;
align-items: center;
}
.other-print {
font-size: 20px;
}
.other-print:hover {
color: #1890ff;
}
}
}
.e-alarm-echarts {
width: 100%;
height: 300px;
}
.e-alarm-table {
height: 280px;
width: 100%;
padding-top: 10px;
}
.pagination-container {
margin-top: 5px;
height: 35px;
}
}
</style>

View File

@ -0,0 +1,448 @@
<template>
<div class="e-object-safety-template">
<div class="e-alarm-heard">
<div class="heard-query">
<div
@click="
() => {
queryParams.timeType = 'day';
}
"
:class="
queryParams.timeType === 'day'
? 'data-type data-type-selected'
: 'data-type'
"
>
</div>
<div
@click="
() => {
queryParams.timeType = 'month';
}
"
:class="
queryParams.timeType === 'month'
? 'data-type data-type-selected'
: 'data-type'
"
class="data-type"
>
</div>
<div class="other-query">
<span>日期</span>
<el-date-picker
v-if="queryParams.timeType === 'day'"
v-model="time"
type="date"
style="width: 150px"
placeholder="选择日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd 00:00:00"
:clearable="false"
>
</el-date-picker>
<el-date-picker
v-model="time"
v-if="queryParams.timeType === 'month'"
type="month"
style="width: 150px"
format="yyyy-MM"
value-format="yyyy-MM-01 00:00:00"
:clearable="false"
placeholder="选择月"
>
</el-date-picker>
<el-input
style="width: 150px"
v-model="queryParams.deviceId"
placeholder="输入设备号"
></el-input>
<el-button type="primary" @click="handleQuery" size="small">查询</el-button>
</div>
<!-- <div class="other-print">
<i class="el-icon-printer"></i>
</div> -->
</div>
</div>
<div class="e-alarm-echarts">
<e-echarts-line
ref="echartsLineTrend"
:styles="echartsOption.styles"
:colorList="echartsOption.colorList"
:eId="echartsOption.eId"
:option="resultOption"
></e-echarts-line>
</div>
<div class="e-alarm-table">
<el-table
v-loading="tableLoading"
:data="tableList"
:height="total > 0 ? '230px' : '270px'"
>
<el-table-column
label="设备名称"
width="200px"
align="left"
prop="deviceName"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.deviceName">
{{ scope.row.deviceName }}
</span>
</template>
</el-table-column>
<el-table-column
label="设备号"
align="left"
width="200px"
prop="deviceId"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.deviceId">
{{ scope.row.deviceId }}
</span>
</template>
</el-table-column>
<el-table-column
label="线路"
width="60px"
align="center"
prop="lineType"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.lineType == '0' ">
{{ scope.row.lineType == '0' ? "总路" : "支路" }}
</span>
</template>
</el-table-column>
<el-table-column label="地点" align="left" prop="projectAddress">
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.address">
{{ scope.row.address }}
</span>
</template>
</el-table-column>
<el-table-column
label="事件ID"
align="left"
width="200"
prop="recordId"
>
<template slot-scope="scope">
<span class="lay-table-textarea" :title="scope.row.recordId">
{{ scope.row.recordId }}
</span>
</template>
</el-table-column>
<el-table-column
label="事件类型"
width="120px"
align="center"
prop="typeName"
/>
<el-table-column
label="事件时间"
align="center"
width="160"
prop="alarmTime"
/>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="pageParams.pageNum"
:limit.sync="pageParams.pageSize"
@pagination="getDeviceRecordTable"
/>
</div>
</div>
</template>
<script>
import EEchartsLine from "@/components/Echarts/EEchartsLine";
import * as echarts from "echarts";
import {
projectAlarmRecordEcharts,
projectAlarmRecordTable,
} from "@/api/iot/project_new";
export default {
name: "ESafetyTemplate",
props: {
projectInfo: {
type: Object,
require: true,
},
sourceId: {
type: [Number, String],
require: true,
},
tempType: {
type: String,
require: true,
},
},
components: { EEchartsLine },
data() {
return {
time: "",
queryParams: {
timeType: "day",
time: "",
deviceId: "",
},
pageParams: {
pageNum: 1,
pageSize: 10,
},
echartsOption: {
styles: "width: 100%; height: calc(100% - 35px);",
colorList: ["#1890FF", "#EE6666", "#FFCC00"],
eId: "safetytTemplateIdx",
},
title: "24小时报警情况",
typeName: "alarm",
resultOption: {
color: ["#1890FF", "#EE6666", "#FFCC00"],
title: {
text: "24小时报警情况",
show: false,
},
tooltip: {
trigger: "axis",
},
legend: {
bottom: 0,
data: [],
// icon: "circle",
textStyle: {
color: "#38486a",
fontSize: 12,
fontWeight: 400,
},
},
grid: {
left: "20",
right: "20",
bottom: "35",
top: 30,
containLabel: true,
},
xAxis: {
type: "category",
boundaryGap: false,
show: true,
data: [],
splitLine: {
show: false,
},
axisLabel: {
show: true,
textStyle: {
color: "#606266",
},
},
},
yAxis: {
type: "value",
splitLine: {
show: false,
},
axisLabel: {
show: true,
textStyle: {
color: "#606266",
},
},
},
series: [],
},
total: 0,
tableList: [],
tableLoading: false,
};
},
watch: {
sourceId(val) {
if (val !== null && val !== undefined) {
this.init();
}
},
tempType(val) {
if (val) {
this.init();
}
}
},
mounted() {},
created() {
this.init();
},
methods: {
init() {
this.time =
this.queryParams.timeType === "day"
? this.parseTime(new Date(), "{y}-{m}-{d} 00:00:00")
: this.parseTime(new Date(), "{y}-{m}-01 00:00:00");
this.handleQuery()
},
handleQuery() {
this.pageParams.pageNum = 1;
this.time =
this.queryParams.timeType === "day"
? this.parseTime(new Date(this.time), "{y}-{m}-{d} 00:00:00")
: this.parseTime(new Date(this.time), "{y}-{m}-01 00:00:00");
this.getDeviceRecordEcharts();
this.getDeviceRecordTable();
},
//
getDeviceRecordEcharts() {
let qeuryParams = JSON.parse(JSON.stringify(this.queryParams));
projectAlarmRecordEcharts(
Object.assign(qeuryParams, {
projectId: this.sourceId,
time: this.time,
typeCodes: this.tempType,
})
).then((res) => {
this.resultOption.series = [];
this.resultOption.xAxis.data = [...res.data["name"]];
let keys = Object.keys(res.data);
this.resultOption.legend.data = keys.filter((v) => {
if (v !== "name") {
return v;
}
});
var list = keys.map((v) => {
if (v !== "name") {
return {
name: v,
type: "line",
smooth: false,
symbolSize: 2,
markPoint: {
symbolSize: 35,
data: [
{ type: "max", name: "Max" },
{ type: "min", name: "Min" },
],
},
label: {
show: false,
formatter: function (params) {
return echarts.format.formatTime("yyyy-MM-dd", params.value);
},
backgroundColor: "#7581BD",
},
data: res.data[v],
};
}
});
this.resultOption.series = list.filter(
(v) => v !== undefined && v !== null
);
console.log(this.resultOption);
this.updateEcharts();
});
},
//
getDeviceRecordTable() {
this.tableLoading = true;
let qeuryParams = JSON.parse(JSON.stringify(this.queryParams));
projectAlarmRecordTable(
Object.assign(
qeuryParams,
{
projectId: this.sourceId,
time: this.time,
typeCode: this.tempType,
},
this.pageParams
)
).then((res) => {
this.tableList = res.rows;
this.tableLoading = false;
this.total = res.total;
});
},
//
updateEcharts() {
this.$refs.echartsLineTrend.updateEchart();
},
},
};
</script>
<style lang="scss">
.e-object-safety-template {
width: 100%;
height: 100%;
display: flex;
flex-wrap: wrap;
.e-alarm-heard {
width: 100%;
height: 40px;
display: flex;
justify-content: flex-end;
align-items: center;
.heard-query {
width: 50%;
height: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
.data-type {
width: 32px;
height: 32px;
background: #f4f5f7;
border-radius: 50%;
font-size: 14px;
font-family: Source Han Sans CN;
font-weight: 300;
color: #6b778c;
display: flex;
justify-content: center;
align-items: center;
margin: 0 5px;
cursor: default;
}
.data-type-selected {
background: #1890ff;
color: #f4f5f7;
}
.other-query {
display: flex;
width: 420px;
justify-content: space-evenly;
align-items: center;
}
.other-print {
font-size: 20px;
}
.other-print:hover {
color: #1890ff;
}
}
}
.e-alarm-echarts {
width: 100%;
height: 300px;
}
.e-alarm-table {
height: 280px;
width: 100%;
padding-top: 10px;
}
.pagination-container {
margin-top: 5px;
height: 35px;
}
}
</style>

View File

@ -57,11 +57,12 @@
</div> </div>
<div class="container-main"> <div class="container-main">
<e-nav-menu <e-nav-menu
v-model="activeName" v-model="activeType"
:activeList="activeList" :activeList="activeList"
@input=" @input="
(data) => { (data) => {
activeName = data; activeName = data['template'];
activeType = data['key'];
} }
" "
/> />
@ -71,6 +72,7 @@
:projectInfo="infoData" :projectInfo="infoData"
:projectTypeOptions="projectTypeOptions" :projectTypeOptions="projectTypeOptions"
:sourceId="stateSourceId" :sourceId="stateSourceId"
:tempType="activeType"
></component> ></component>
</div> </div>
</div> </div>
@ -112,6 +114,12 @@ import ETypeCensus from "./ETypeCensus";
import ETrendCensus from "./ETrendCensus"; import ETrendCensus from "./ETrendCensus";
import EObjectContainer from "./EObjectContainer"; import EObjectContainer from "./EObjectContainer";
import EDeviceManage from "./DeviceManage/index"; import EDeviceManage from "./DeviceManage/index";
import EAlarmManage from './AlarmManage/index'
import ESafetyTemplate from './SafetyTemplate/index'
import ELeakageCurrent from './SafetyTemplate/ELeakageCurrent'
import EDebuff from './SafetyTemplate/EDebuff'
import EDeviceSwitchWarning from './SafetyTemplate/EDeviceSwitchWarning'
import EElectricity from './EnergyManage/EElectricity'
export default { export default {
name: "projectDetailV2", name: "projectDetailV2",
@ -127,6 +135,12 @@ export default {
ETrendCensus, ETrendCensus,
EObjectContainer, EObjectContainer,
EDeviceManage, EDeviceManage,
EAlarmManage,
ESafetyTemplate,
ELeakageCurrent,
EDebuff,
EDeviceSwitchWarning,
EElectricity
}, },
props: { props: {
sourceId: { sourceId: {
@ -139,14 +153,94 @@ export default {
stateSourceId: null, stateSourceId: null,
resultInfo: {}, resultInfo: {},
activeName: "EObjectContainer", activeName: "EObjectContainer",
activeType: 'EObjectContainer',
activeList: [ activeList: [
{ {
label: "项目信息", label: "项目信息",
key: "EObjectContainer", key: "EObjectContainer",
template: "EObjectContainer",
}, },
{ {
label: "设备管理", label: "设备管理",
key: "EDeviceManage", key: "EDeviceManage",
template: "EDeviceManage",
},
{
label: "安全监管",
key: "safety",
children: [ //
{
label: "全部报警",
key: "EAlarmManage",
template: "EAlarmManage",
},
{
label: "漏电流",
key: "ELeakageCurrent",
template: "ELeakageCurrent",
},
{
label: "温度",
key: "A006,A007,A008,A009,B004,B005,B006,B007",
template: 'ESafetyTemplate'
},
{
label: "漏电报警",
key: "A002,B002",
template: "ESafetyTemplate",
},
{
label: "漏保自检",
key: "A002,B004",
template: "ESafetyTemplate",
},
{
label: "短路报警",
key: "A001,B004",
template: "ESafetyTemplate",
},
{
label: "过欠压",
key: "A005,A004,B000,B001",
template: "ESafetyTemplate",
},
{
label: "过流过载",
key: "A003,B003",
template: "ESafetyTemplate",
},
{
label: "电弧报警",
key: "A003,B003",
template: "ESafetyTemplate",
},
{
label: "三相报警",
key: "A003,B003",
template: "ESafetyTemplate",
},
{
label: "异常状态",
key: "A010",
template: "EDebuff",
},
{
label: "分合闸警示",
key: "A011",
template: "EDeviceSwitchWarning",
},
]
},
{
label: "综合管理",
key: "energy",
children: [
{
label: "电量",
key: "electricity",
template: "EElectricity",
},
],
}, },
], ],
projectTypeOptions: [], projectTypeOptions: [],