|
|
@@ -0,0 +1,811 @@
|
|
|
+<template>
|
|
|
+ <div style="padding: 10px 15px">
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="6" style="padding-right: 10px">
|
|
|
+ <el-card class="box-card">
|
|
|
+ <template #header>
|
|
|
+ <div class="card-header">
|
|
|
+ <span>设备区域</span>
|
|
|
+ <div style="display: none">
|
|
|
+ <el-button type="primary">
|
|
|
+ 添加
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <div class="tree">
|
|
|
+ <LayTree :data="data" :tail-node-icon="false" :onlyIconControl="true" v-model:selectedKey="selectedKey"
|
|
|
+ @node-click="handleClick">
|
|
|
+ <template #title="{ data }">
|
|
|
+ <div style="display: flex;align-items: center;">
|
|
|
+ <el-icon v-if="(data.id + '').indexOf('device') != -1">
|
|
|
+ <Cpu />
|
|
|
+ </el-icon> {{ data.name }}</div>
|
|
|
+ </template>
|
|
|
+ </LayTree>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="18">
|
|
|
+ <el-card class="box-card">
|
|
|
+ <div style="display: flex; flex-direction: row; justify-content: space-between">
|
|
|
+ <div style="display: flex; flex-direction: row;">
|
|
|
+ <div style="
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ align-items: center;
|
|
|
+ ">
|
|
|
+ <div style="font-size: 12px; width: 100px;">传感器编号:</div>
|
|
|
+ <el-input v-model="searchform.id" placeholder="请输入"></el-input>
|
|
|
+ </div>
|
|
|
+ <div style="
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ align-items: center;
|
|
|
+ ">
|
|
|
+ <div style="font-size: 12px; width: 80px;margin-right: 10px;text-align: right;">描述:</div>
|
|
|
+ <el-input v-model="searchform.desc" placeholder="请输入"></el-input>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <el-button type="primary" plain @click="initdata">重置</el-button>
|
|
|
+ <el-button type="primary" @click="getalldata">搜索</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <el-card class="box-card" style="margin-top: 10px;">
|
|
|
+ <template #header>
|
|
|
+ <div class="card-header">
|
|
|
+ <span>传感器台账</span>
|
|
|
+ <div style="display: none">
|
|
|
+ <el-button type="primary" @click="handleImport">导入</el-button>
|
|
|
+ <el-button type="primary" @click="goadd">添加</el-button>
|
|
|
+ <el-button type="danger" @click="deleteall">批量删除</el-button>
|
|
|
+ <el-button type="primary" plain @click="ziduanshow = true">显示字段</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="24" style="padding-left: 10px">
|
|
|
+ <el-table :data="devicetabledata" ref="tableref" :border="true">
|
|
|
+ <el-table-column type="selection" width="55" />
|
|
|
+ <el-table-column v-for="item in cloumdata.filter(i => i.visible)" :prop="item.prop"
|
|
|
+ :label="item.label"></el-table-column>
|
|
|
+ <el-table-column label="协议">
|
|
|
+ <template #default="scope">
|
|
|
+ <div>
|
|
|
+ {{ getProtocalTypeName(scope.row) }}
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作">
|
|
|
+ <template #default="scope">
|
|
|
+ <div>
|
|
|
+ <el-button link @click="lookdata(scope.row)">
|
|
|
+ <el-tooltip effect="dark" content="查看数据">
|
|
|
+ <el-icon>
|
|
|
+ <PieChart />
|
|
|
+ </el-icon>
|
|
|
+ </el-tooltip>
|
|
|
+ </el-button>
|
|
|
+
|
|
|
+ <el-button link @click="goedit(scope.row)" style="display:none">
|
|
|
+ <el-tooltip effect="dark" content="编辑">
|
|
|
+ <el-icon>
|
|
|
+ <Edit />
|
|
|
+ </el-icon>
|
|
|
+ </el-tooltip>
|
|
|
+ </el-button>
|
|
|
+ <el-button link @click="cdbd(scope.row)" style="display:none">
|
|
|
+ <el-tooltip effect="dark" content="测点绑定">
|
|
|
+ <el-icon>
|
|
|
+ <VideoPlay />
|
|
|
+ </el-icon>
|
|
|
+ </el-tooltip>
|
|
|
+ </el-button>
|
|
|
+ <el-popconfirm title="确定删除该传感器?" @confirm="deleterow(scope.row)" >
|
|
|
+ <template #reference>
|
|
|
+ <el-button link style="display:none"><el-tooltip effect="dark" content="删除"><el-icon>
|
|
|
+ <Delete />
|
|
|
+ </el-icon></el-tooltip></el-button>
|
|
|
+ </template>
|
|
|
+ </el-popconfirm>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="24" style="margin-top: 10px;">
|
|
|
+ <el-pagination style="float: right;" small background layout="prev, pager, next" :total="pagedata.total"
|
|
|
+ :page-size="pagedata.pageSize" :current-page="pagedata.pageNum" @current-change="onchangepage"
|
|
|
+ class="mt-4" />
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+
|
|
|
+ <el-dialog title="测点配置" v-model="cdbdshow">
|
|
|
+
|
|
|
+ <div style="display: flex; flex-direction: row; justify-content: space-between">
|
|
|
+ <div style="display: flex; flex-direction: row;">
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <el-button type="primary" plain @click="addrow">新增</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-table :data="pointdata" style="margin-top: 15px" height="400px">
|
|
|
+ <el-table-column label="变量名" prop="name">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-input v-model="scope.row.name">
|
|
|
+ </el-input>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="名称" prop="label">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-input v-model="scope.row.label">
|
|
|
+ </el-input>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="单位" prop="unitId">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-popover placement="right" :width="400" trigger="click">
|
|
|
+ <template #reference>
|
|
|
+ <el-button plain>{{ `${scope.row.unit}(${scope.row.unitType})` }}</el-button>
|
|
|
+ </template>
|
|
|
+ <el-table :data="allUnit" height="500"
|
|
|
+ @cellClick="(row1) => { scope.row.unit = row1.unitName; scope.row.unitType = row1.unitSymbol; }">
|
|
|
+ <el-table-column property="unitName" label="单位名称" />
|
|
|
+ <el-table-column property="unitSymbol" label="单位符号" />
|
|
|
+ <el-table-column property="unitType" label="分类" />
|
|
|
+ </el-table>
|
|
|
+ </el-popover>
|
|
|
+
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="描述" prop="desc">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-input v-model="scope.row.desc">
|
|
|
+ </el-input>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="点表配置" prop="dataPointId">
|
|
|
+ <template #default="scope">
|
|
|
+ <span v-if="currentsensor.protocalType == 3">无需配置</span>
|
|
|
+ <div v-if="currentsensor.protocalType != 3">
|
|
|
+ <el-popover placement="right" :width="400" trigger="click">
|
|
|
+ <template #reference>
|
|
|
+ <el-button plain>{{ `${(currentdatapointlist.find(i => (i.id + "") == scope.row.dataPointId) ??
|
|
|
+ { name: '失效' }).name}` }}</el-button>
|
|
|
+ </template>
|
|
|
+ <el-table :data="currentdatapointlist" @cellClick="(row1) => { scope.row.dataPointId = row1.id; }">
|
|
|
+ <el-table-column property="name" label="点位名称" />
|
|
|
+ <el-table-column property="valueType" label="变量类型" />
|
|
|
+ <el-table-column property="addr" label="地址" />
|
|
|
+ </el-table>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+
|
|
|
+
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-popconfirm title="确定删除该测点?" @confirm="deldatapoint(scope.$index)">
|
|
|
+ <template #reference>
|
|
|
+ <el-button link><el-tooltip effect="dark" content="删除"><el-icon>
|
|
|
+ <Delete />
|
|
|
+ </el-icon></el-tooltip></el-button>
|
|
|
+ </template>
|
|
|
+ </el-popconfirm>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button @click="cdbdshow = false;"> 取消 </el-button>
|
|
|
+ <el-button type="primary" @click="dosave"> 保存 </el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <el-dialog title="字段显示" v-model="ziduanshow" width="50%" @close="ziduanshow = false">
|
|
|
+ <div style="display: flex;flex-wrap: wrap;align-content: center;justify-content: center;align-items: center;">
|
|
|
+ <el-checkbox v-for="item in cloumdata" v-model="item.visible" :label="item.label" size="large" />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <el-dialog title="测点数据查看" v-model="datashow" width="50%" @close="datashow = false">
|
|
|
+ <div>
|
|
|
+ <!-- 显示测点实时数据-->
|
|
|
+ <el-table @cellClick="doshowhistory" :data="JSON.parse(currentsensor.datapoints)" style="margin-top: 15px"
|
|
|
+ height="250px">
|
|
|
+ <el-table-column label="变量名" prop="name">
|
|
|
+ <template #default="scope">
|
|
|
+ <span>{{ scope.row.name }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="名称" prop="name">
|
|
|
+ <template #default="scope">
|
|
|
+ <span>{{ scope.row.label }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="数值" prop="name">
|
|
|
+ <template #default="scope">
|
|
|
+ <span>{{showdata(scope.row.name,scope.row.unitType)
|
|
|
+
|
|
|
+ }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="单位" prop="name">
|
|
|
+ <template #default="scope">
|
|
|
+ <span>{{ scope.row.unitType }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="时间" prop="name">
|
|
|
+ <template #default="scope">
|
|
|
+ <span>{{
|
|
|
+ (useWSStore().getMessage()[currentsensor.id]) ?
|
|
|
+ (useWSStore().getMessage()[currentsensor.id][scope.row.name]?.time) : '-'
|
|
|
+ }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ <div style="position: relative;">
|
|
|
+ <div style="margin-top: 10px" v-if="currentname != ''">变量 {{ currentname }} 数值曲线</div>
|
|
|
+
|
|
|
+ <div style="position: absolute;right:10px;top:10px">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="value1"
|
|
|
+ style="z-index: 10000;"
|
|
|
+ type="datetimerange"
|
|
|
+ :shortcuts="shortcuts"
|
|
|
+ range-separator="到"
|
|
|
+ start-placeholder="开始时间"
|
|
|
+ end-placeholder="结束时间"
|
|
|
+ @change="doshowhistory"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <!-- 显示历史数据 折线图-->
|
|
|
+ <div ref="chartlinediv" style="height: 250px" v-loading="isloading"></div>
|
|
|
+
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
|
|
|
+ <el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
|
|
|
+ :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading"
|
|
|
+ :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag
|
|
|
+ :data="{deviceId:uploadParams}">
|
|
|
+ <el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
|
|
+ <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
|
|
+ <template #tip>
|
|
|
+ <div class="el-upload__tip text-center">
|
|
|
+ <span>仅允许导入xls、xlsx格式文件。</span>
|
|
|
+ <!-- <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;"
|
|
|
+ @click="importTemplate">下载模板</el-link> -->
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-upload>
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button type="primary" @click="submitFileForm">确 定</el-button>
|
|
|
+ <el-button @click="upload.open = false">取 消</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { getToken } from "@/utils/auth";
|
|
|
+// import { ElMessage } from 'element-plus'
|
|
|
+import { onMounted, ref, watch, watchEffect } from "vue";
|
|
|
+import { LayTree } from "@layui/layui-vue";
|
|
|
+import "@layui/layui-vue/lib/index.css";
|
|
|
+import { useRoute, useRouter } from "vue-router";
|
|
|
+import { listEquipmentOrganizational } from "@/api/data/equipmentOrganizational"
|
|
|
+import { listEquipmentSbook } from "@/api/data/equipmentSbook"
|
|
|
+import { listSensor, delSensor, addSensor, updateSensor, listSensorData, listSensorRecordData } from "@/api/data/sensor"
|
|
|
+import { listDatapoint } from "@/api/data/datapoint";
|
|
|
+import { listUnit } from "@/api/data/unit";
|
|
|
+import useWSStore from "@/store/modules/websocket"
|
|
|
+import * as echarts from 'echarts';
|
|
|
+
|
|
|
+
|
|
|
+import { ElMessage, ElMessageBox } from "element-plus";
|
|
|
+import moment from "moment";
|
|
|
+
|
|
|
+const { proxy } = getCurrentInstance();
|
|
|
+const { protocal_type, sensor_type, sensor_status } = proxy.useDict("protocal_type", "sensor_type", "sensor_status");
|
|
|
+const pointdata = ref([]);
|
|
|
+
|
|
|
+const route = useRoute();
|
|
|
+const router = useRouter();
|
|
|
+const ziduanshow = ref(false);
|
|
|
+
|
|
|
+
|
|
|
+const showdata = (name, un) => {
|
|
|
+
|
|
|
+ let value = "-";
|
|
|
+ try {
|
|
|
+ value = useWSStore().getMessage()[currentsensor.value.id][name].value
|
|
|
+ if (un == "~") {
|
|
|
+ return moment(value*1000).format("yyyy-MM-DD HH:mm:ss");
|
|
|
+ }
|
|
|
+ value = value ? parseFloat(value)+"" : '-';
|
|
|
+ }catch(e) {
|
|
|
+ }
|
|
|
+ return value;
|
|
|
+}
|
|
|
+
|
|
|
+const tableref = ref(null);
|
|
|
+const value1 = ref([
|
|
|
+ moment().subtract(1,'days'),
|
|
|
+ moment(),
|
|
|
+])
|
|
|
+const shortcuts = [
|
|
|
+ {
|
|
|
+ text: '1天',
|
|
|
+ value: () => {
|
|
|
+ const end = moment()
|
|
|
+ const start = moment().subtract(1, 'days');
|
|
|
+ return [start, end]
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ text: '3天',
|
|
|
+ value: () => {
|
|
|
+ const end = moment()
|
|
|
+ const start = moment().subtract(3, 'days');
|
|
|
+ return [start, end]
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ text: '1周',
|
|
|
+ value: () => {
|
|
|
+ const end = moment()
|
|
|
+ const start = moment().subtract(7, 'days');
|
|
|
+ return [start, end]
|
|
|
+ },
|
|
|
+ },
|
|
|
+]
|
|
|
+
|
|
|
+const uploadParams = ref();
|
|
|
+
|
|
|
+const cloumdata = ref([
|
|
|
+ { label: '传感器编号', prop: 'id', visible: true },
|
|
|
+ { label: '传感器名称', prop: 'name', visible: true },
|
|
|
+ { label: '描述', prop: 'sensorDesc', visible: true },
|
|
|
+ { label: '状态', prop: 'statusname', visible: true },
|
|
|
+ { label: '类型', prop: 'sensorType', visible: true },
|
|
|
+])
|
|
|
+
|
|
|
+/*** 用户导入参数 */
|
|
|
+const upload = reactive({
|
|
|
+ // 是否显示弹出层(用户导入)
|
|
|
+ open: false,
|
|
|
+ // 弹出层标题(用户导入)
|
|
|
+ title: "",
|
|
|
+ // 是否禁用上传
|
|
|
+ isUploading: false,
|
|
|
+ // 是否更新已经存在的用户数据
|
|
|
+ updateSupport: 0,
|
|
|
+ // 设置上传的请求头部
|
|
|
+ headers: { Authorization: "Bearer " + getToken() },
|
|
|
+ // 上传的地址
|
|
|
+ url: import.meta.env.VITE_APP_BASE_API + "/data/sensor/invoke"
|
|
|
+});
|
|
|
+
|
|
|
+
|
|
|
+const onchangepage = (page) => {
|
|
|
+ pagedata.value.pageNum = page;
|
|
|
+ getalldata();
|
|
|
+}
|
|
|
+const pagedata = ref({
|
|
|
+ total: 0,
|
|
|
+ pageSize: 10,
|
|
|
+ pageNum: 1
|
|
|
+});
|
|
|
+
|
|
|
+const allUnit = ref([])
|
|
|
+
|
|
|
+const deleterow = (item) => {
|
|
|
+ delSensor(item.id).then((res) => {
|
|
|
+ ElMessage.success("删除成功");
|
|
|
+ getalldata();
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const deleteall = () => {
|
|
|
+ let selected = tableref.value.getSelectionRows();
|
|
|
+ if (selected.length == 0) {
|
|
|
+ ElMessage.warning("请选择要删除的行");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (selected.length > 0) {
|
|
|
+ ElMessageBox.confirm(
|
|
|
+ `是否删除${selected.length}条数据`,
|
|
|
+ "警告", {
|
|
|
+ confirmButtonText: "确认",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: 'warning',
|
|
|
+ }
|
|
|
+ ).then(() => {
|
|
|
+
|
|
|
+ delSensor(selected.map(i => i.id).join(",")).then((res) => {
|
|
|
+ ElMessage.success("删除成功");
|
|
|
+ getalldata();
|
|
|
+ })
|
|
|
+
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/** 导入按钮操作 */
|
|
|
+const handleImport = () => {
|
|
|
+ const getdeviceid = (node) => {
|
|
|
+ if (node.children) {
|
|
|
+ return node.children.map(item => {
|
|
|
+ return getdeviceid(item);
|
|
|
+ }).join(",")
|
|
|
+ } else {
|
|
|
+ if ((node.id + "").indexOf("device") > -1) {
|
|
|
+ return node.id;
|
|
|
+ } else {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (currentnode.value != null) {
|
|
|
+ let deviceids = getdeviceid(currentnode.value).split(",").filter(i => i != "").join(",");
|
|
|
+ console.log(deviceids.split(',').length == 1)
|
|
|
+ if (deviceids != null && deviceids.split(',').length == 1) {
|
|
|
+ uploadParams.value = deviceids.replaceAll("device_", '');
|
|
|
+ console.log(uploadParams.value)
|
|
|
+ upload.title = "传感器导入";
|
|
|
+ upload.open = true;
|
|
|
+ } else {
|
|
|
+ ElMessage({
|
|
|
+ message: '请选择传感器所属设备',
|
|
|
+ type: 'warning',
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ ElMessage({
|
|
|
+ message: '请选择传感器所属设备',
|
|
|
+ type: 'warning',
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+function submitFileForm() {
|
|
|
+ proxy.$refs["uploadRef"].submit();
|
|
|
+ upload.open = false;
|
|
|
+};
|
|
|
+
|
|
|
+const initdata = () => {
|
|
|
+ searchform.value.id = '';
|
|
|
+ searchform.value.desc = '';
|
|
|
+ pagedata.value = {
|
|
|
+ total: 0,
|
|
|
+ pageSize: 10,
|
|
|
+ pageNum: 1
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const goadd = () => {
|
|
|
+ router.push("/device/sensordash/add?type=0")
|
|
|
+}
|
|
|
+
|
|
|
+const goedit = (item) => {
|
|
|
+ localStorage.setItem("currentsensor", JSON.stringify(item))
|
|
|
+ router.push("/device/sensordash/add?type=1")
|
|
|
+}
|
|
|
+
|
|
|
+const getProtocalTypeName = (item) => {
|
|
|
+ for (var index in protocal_type.value) {
|
|
|
+ if (protocal_type.value[index].value == item.protocalType) {
|
|
|
+ return protocal_type.value[index].label
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+const currentnode = ref(null);
|
|
|
+const getalldata = () => {
|
|
|
+ const getdeviceid = (node) => {
|
|
|
+ if (node.children) {
|
|
|
+ return node.children.map(item => {
|
|
|
+ return getdeviceid(item);
|
|
|
+ }).join(",")
|
|
|
+ } else {
|
|
|
+ if ((node.id + "").indexOf("device") > -1) {
|
|
|
+ return node.id;
|
|
|
+ } else {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ let deviceids = getdeviceid(currentnode.value).split(",").filter(i => i != "").join(",");
|
|
|
+ console.log(deviceids)
|
|
|
+ if (deviceids != "") {
|
|
|
+ deviceids = deviceids.replaceAll("device_", "")
|
|
|
+ listSensor({ ...pagedata.value, params: { deviceids: deviceids, ...searchform.value }}).then(res => {
|
|
|
+ const { rows, total, page, size } = res;
|
|
|
+ pagedata.value = { total: total, pageNum: page, pageSize: 10 };
|
|
|
+ console.log(rows);
|
|
|
+ devicetabledata.value = rows.map(item => {
|
|
|
+ try {
|
|
|
+ var statusname = sensor_status.value.find(i => i.value == item.status).label;
|
|
|
+ item["statusname"] = statusname;
|
|
|
+ } catch (e) {
|
|
|
+
|
|
|
+ }
|
|
|
+ return item;
|
|
|
+ });
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ pagedata.value = { total: 0, pageNum: 1, pageSize: 10 };
|
|
|
+ devicetabledata.value = [];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const handleClick = (node) => {
|
|
|
+ //循环获取子的id
|
|
|
+ currentnode.value = node;
|
|
|
+ getalldata();
|
|
|
+};
|
|
|
+const selectedKey = ref(4);
|
|
|
+const data = ref([]);
|
|
|
+
|
|
|
+
|
|
|
+const getTreedata = () => {
|
|
|
+ listEquipmentOrganizational({ pageSize: 10000 }).then(res => {
|
|
|
+ const { rows, total, page, size } = res;
|
|
|
+ let rows1 = rows.map(item => {
|
|
|
+ if(item.name=="仿岩质潮间带生态修复实施安全保障工程"){
|
|
|
+ item.name="水上水下一体化监控"
|
|
|
+ }
|
|
|
+ if(item.name=="红树林-盐沼生态海岸线生态修复实施安全保障支撑工程"){
|
|
|
+ item.name="岸基环境生态全自动监控"
|
|
|
+ }
|
|
|
+ if(item.name=="海洋防文减文预警工程"){
|
|
|
+ item.name="防灾减灾预警监控"
|
|
|
+ }
|
|
|
+ if(item.name=="入海污染物自动监管工程"){
|
|
|
+ item.name="入海污染物监控"
|
|
|
+ }
|
|
|
+ return item;
|
|
|
+ })
|
|
|
+ //获取设备数据
|
|
|
+ listEquipmentSbook({ page: 1, pageSize: 100000 }).then(res1 => {
|
|
|
+ res1.rows.forEach(item => {
|
|
|
+ item["parentId"] = item.equipmentTreeId;
|
|
|
+ item["id"] = "device_" + item.id;
|
|
|
+ rows1.push(item);
|
|
|
+ data.value = proxy.handleTree(rows1, "id", "parentId");
|
|
|
+ })
|
|
|
+ })
|
|
|
+ })
|
|
|
+}
|
|
|
+getTreedata();
|
|
|
+
|
|
|
+
|
|
|
+const devicetabledata = ref([]);
|
|
|
+const searchform = ref({
|
|
|
+ id: "",
|
|
|
+ desc: ""
|
|
|
+});
|
|
|
+
|
|
|
+const currentdatapointlist = ref([]);
|
|
|
+const cdbdshow = ref(false);
|
|
|
+const currentsensor = ref(null);
|
|
|
+const cdbd = (item) => {
|
|
|
+ cdbdshow.value = true;
|
|
|
+ listDatapoint({ sensorId: item.id }).then(res => {
|
|
|
+ const { rows, total, page, size } = res;
|
|
|
+ currentdatapointlist.value = rows;
|
|
|
+ currentsensor.value = item;
|
|
|
+ try {
|
|
|
+ pointdata.value = JSON.parse(item.datapoints);
|
|
|
+ } catch (e) {}
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+}
|
|
|
+const realtimedata = ref({})
|
|
|
+const datashow = ref(false);
|
|
|
+const lookdata = (item) => {
|
|
|
+ //弹窗
|
|
|
+ datashow.value = true;
|
|
|
+ currentsensor.value = item;
|
|
|
+ listSensorData({ page: 1, pageSize: 10000, id: item.id }).then(res => {
|
|
|
+ const { rows, total, page, size } = res;
|
|
|
+ if (rows.length > 0) {
|
|
|
+ if (rows[0].recordData) {
|
|
|
+ let data = JSON.parse(rows[0].recordData);
|
|
|
+ useWSStore().setMessagetype1(rows[0].tblSensor.id, data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+ //直接接mqtt 数据
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+const deldatapoint = (index) => {
|
|
|
+ pointdata.value.splice(index, 1)
|
|
|
+}
|
|
|
+
|
|
|
+const addrow = () => {
|
|
|
+ if (!pointdata.value) { pointdata.value = []; }
|
|
|
+ pointdata.value.push({
|
|
|
+ name: "",
|
|
|
+ unit: "",
|
|
|
+ unitType: "0",
|
|
|
+ desc: "",
|
|
|
+ label: "",
|
|
|
+ dataPointId: null
|
|
|
+ })
|
|
|
+}
|
|
|
+onMounted(() => {
|
|
|
+ listUnit({}).then(res => {
|
|
|
+ allUnit.value = res.data;
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
+const dosave = () => {
|
|
|
+ let data = JSON.stringify(pointdata.value.filter(i => i.name !== ""));
|
|
|
+ currentsensor.value.datapoints = data;
|
|
|
+ updateSensor(currentsensor.value).then(res => {
|
|
|
+ ElMessage.success("保存成功");
|
|
|
+ cdbdshow.value = false;
|
|
|
+ getalldata();
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const historytabledata = ref([]);
|
|
|
+const chartlinediv = ref(null)
|
|
|
+const currentname = ref("")
|
|
|
+const isloading = ref(false);
|
|
|
+watchEffect(() => {
|
|
|
+ if (currentsensor.value && useWSStore().getMessage()[currentsensor.value.id] && useWSStore().getMessage()[currentsensor.value.id][currentname.value]) {
|
|
|
+ let data = useWSStore().getMessage()[currentsensor.value.id][currentname.value];
|
|
|
+ var isadd = false;
|
|
|
+ historytabledata.value.forEach(i => {
|
|
|
+ if (moment(data.time).utc() - moment(i[0]).utc() > 10) {
|
|
|
+ isadd = true;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ if (isadd) {
|
|
|
+ historytabledata.value.splice(0, 0, [moment(data.time).valueOf(), data.value])
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ if (historytabledata.value.length > 0) {
|
|
|
+ const usedmemoryInstance = echarts.init(chartlinediv.value, "macarons");
|
|
|
+ usedmemoryInstance.setOption({
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ position: function(pt) {
|
|
|
+ return [pt[0], '10%'];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'time',
|
|
|
+ splitLine: {
|
|
|
+ show: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'value',
|
|
|
+ },
|
|
|
+ dataZoom: [{
|
|
|
+ type: 'inside',
|
|
|
+ start: 80,
|
|
|
+ end: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ start: 0,
|
|
|
+ end: 20
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ series: [{
|
|
|
+ name: currentname.value,
|
|
|
+ data: historytabledata.value,
|
|
|
+ showSymbol: false,
|
|
|
+ type: 'line',
|
|
|
+ connectNulls: false,
|
|
|
+ // lineStyle: {
|
|
|
+ // curveness: 0 // 设置曲率为0,使线条不弯曲,即首尾不相连
|
|
|
+ // },
|
|
|
+ areaStyle: {},
|
|
|
+ smooth: true
|
|
|
+ }]
|
|
|
+ });
|
|
|
+ console.error(historytabledata.value)
|
|
|
+ window.addEventListener("resize", () => {
|
|
|
+ usedmemoryInstance.resize()
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ if (chartlinediv.value) {
|
|
|
+ chartlinediv.value.innerHTML = "无数据";
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+})
|
|
|
+const doshowhistory = (row) => {
|
|
|
+ if (row != undefined && row != null && row.name!=undefined) {
|
|
|
+ currentname.value = row.name;
|
|
|
+ } else {
|
|
|
+ if (currentname.value == undefined || currentname.value == "" || currentname.value == null) {
|
|
|
+ ElMessage.warning("请选择监测点")
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ isloading.value = true;
|
|
|
+// debugger
|
|
|
+
|
|
|
+ //获取历史数据
|
|
|
+ listSensorRecordData({ sensorId: currentsensor.value.id, pointName: currentname.value, pageNum: 1, pageSize: 10000, orderByColumn: "createTime", isAsc: "desc", params: { name: currentname.value, starttime: moment(value1.value[0]).format("YYYY-MM-DD HH:mm:ss"), endtime:moment(value1.value[1]).format("YYYY-MM-DD HH:mm:ss")} }).then(res => {
|
|
|
+ const { rows, total, page, size } = res;
|
|
|
+ isloading.value = false;
|
|
|
+ historytabledata.value = rows.map(i => {
|
|
|
+ return [moment(i.createTime).valueOf(), i.pointValue]
|
|
|
+ });
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const inportSensor = () => {
|
|
|
+
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+.layui-tree .layui-this .layui-tree-txt {
|
|
|
+ color: #038de0 !important;
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.card-header {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+.tree {
|
|
|
+ *,
|
|
|
+ *:before,
|
|
|
+ *:after {
|
|
|
+ box-sizing: content-box !important;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|