|
@@ -1,24 +1,24 @@
|
|
|
<template>
|
|
|
<div class="page bg page-full">
|
|
|
<div class="content">
|
|
|
- <div class="cont_box" style="align-items: center;">
|
|
|
+ <div class="cont_box" style="align-items: center">
|
|
|
<div class="title">设备:{{ detail.name }}</div>
|
|
|
- <el-tag v-if="areaData.status === 0" type="info" style="margin-left: 20px;">未启用</el-tag>
|
|
|
- <el-tag v-else-if="areaData.status === 1" type="danger" style="margin-left: 20px;">离线</el-tag>
|
|
|
- <el-tag v-else-if="areaData.status === 2" type="success" style="margin-left: 20px;">在线</el-tag>
|
|
|
+ <el-tag v-if="areaData.status === 0" type="info" style="margin-left: 20px">未启用</el-tag>
|
|
|
+ <el-tag v-else-if="areaData.status === 1" type="danger" style="margin-left: 20px">离线</el-tag>
|
|
|
+ <el-tag v-else-if="areaData.status === 2" type="success" style="margin-left: 20px">在线</el-tag>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="content-box page-full-part page-full">
|
|
|
<el-tabs v-model="activeName" @tab-click="handleClick">
|
|
|
<el-tab-pane label="运行状态" name="3">
|
|
|
- <div style=" display: flex;flex-wrap: wrap;">
|
|
|
+ <div style="display: flex; flex-wrap: wrap">
|
|
|
<div class="ant-card">
|
|
|
<div class="ant-card-body">
|
|
|
<div class="cardflex">
|
|
|
<div>设备状态</div>
|
|
|
- <div @click="getrunData()" style="cursor: pointer;">
|
|
|
- <el-icon style="font-size: 18px;">
|
|
|
+ <div @click="getrunData()" style="cursor: pointer">
|
|
|
+ <el-icon style="font-size: 18px">
|
|
|
<ele-Refresh />
|
|
|
</el-icon>
|
|
|
</div>
|
|
@@ -28,8 +28,8 @@
|
|
|
<div class="statusname" v-if="areaData.status == 1">离线</div>
|
|
|
<div class="statusname" v-if="areaData.status == 2">在线</div>
|
|
|
<div class="cardflex comtest">
|
|
|
- <div> 数据时间</div>
|
|
|
- <div>{{ areaData.lastOnlineTime || '未启用' }}</div>
|
|
|
+ <div>数据时间</div>
|
|
|
+ <div>{{ areaData.lastOnlineTime || "未启用" }}</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -38,28 +38,26 @@
|
|
|
<div class="ant-card-body">
|
|
|
<div class="cardflex">
|
|
|
<div>{{ item.name }}</div>
|
|
|
- <div style="cursor: pointer;">
|
|
|
- <el-icon style="font-size: 18px;" @click="getrunData()">
|
|
|
+ <div style="cursor: pointer">
|
|
|
+ <el-icon style="font-size: 18px" @click="getrunData()">
|
|
|
<ele-Refresh />
|
|
|
</el-icon>
|
|
|
- <el-icon style="font-size: 18px;margin-left: 10px;" @click="onOpenListDetail(item)">
|
|
|
+ <el-icon style="font-size: 18px; margin-left: 10px" @click="onOpenListDetail(item)">
|
|
|
<ele-Expand />
|
|
|
</el-icon>
|
|
|
- <el-icon style="font-size: 18px;margin-left: 10px;" @click="onOpenChartDetail(item)">
|
|
|
+ <el-icon style="font-size: 18px; margin-left: 10px" @click="onOpenChartDetail(item)">
|
|
|
<ele-DataLine />
|
|
|
</el-icon>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="statusname" v-if="item.type != 'object'">
|
|
|
-
|
|
|
{{ getValueText(item.key, item.value) }}
|
|
|
<!-- {{ item.value }}{{ item.unit }} -->
|
|
|
-
|
|
|
</div>
|
|
|
<div v-else>
|
|
|
<div class="oblist" v-for="(vare, name) in item.value">
|
|
|
- <div> {{ getStatusText(name, vare) }}</div>
|
|
|
+ <div>{{ getStatusText(name, vare) }}</div>
|
|
|
<!-- <div class="name">{{ name }}:</div>
|
|
|
<div class="name">{{ vare }}</div> -->
|
|
|
</div>
|
|
@@ -89,14 +87,13 @@
|
|
|
<copy :text="prodetail.key"></copy>
|
|
|
</el-descriptions-item>
|
|
|
<el-descriptions-item label="产品名称">
|
|
|
- <router-link :to="'/iotmanager/device/product/detail/' + prodetail.key" class="link-type">{{
|
|
|
- detail.productName }} </router-link>
|
|
|
+ <router-link :to="'/iotmanager/device/product/detail/' + prodetail.key" class="link-type">{{ detail.productName }} </router-link>
|
|
|
</el-descriptions-item>
|
|
|
<el-descriptions-item label="链接协议">{{ prodetail.transportProtocol }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="设备类型">{{ prodetail.deviceType }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="固件版本">{{ detail.version }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="注册时间">{{ detail.registryTime }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="最后上线时间">{{ detail.lastOnlineTime || '' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="最后上线时间">{{ detail.lastOnlineTime || "" }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="详细地址">{{ detail.address }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="说明">{{ detail.desc }}</el-descriptions-item>
|
|
|
<el-descriptions-item :label="item.name" v-for="(item, index) in detail.tags" :key="index">{{ item.value }}</el-descriptions-item>
|
|
@@ -109,13 +106,14 @@
|
|
|
</div>
|
|
|
</el-descriptions-item> -->
|
|
|
</el-descriptions>
|
|
|
- <div class="flex" style="margin-top: 20px;">
|
|
|
- <el-input type="number" style="width: 380px;margin-right: 20px;" v-model.number="detail.onlineTimeout">
|
|
|
+ <div class="flex" style="margin-top: 20px">
|
|
|
+ <el-input type="number" style="width: 380px; margin-right: 20px" v-model.number="detail.onlineTimeout">
|
|
|
<template #prepend>设备超时时间</template>
|
|
|
<template #append>秒</template>
|
|
|
</el-input>
|
|
|
<el-button type="primary" @click="onlineTimeoutUpdate">
|
|
|
- <el-icon style="font-size: 18px;"><ele-Refresh /></el-icon>更新</el-button>
|
|
|
+ <el-icon style="font-size: 18px"><ele-Refresh /></el-icon>更新</el-button
|
|
|
+ >
|
|
|
</div>
|
|
|
</el-tab-pane>
|
|
|
<el-tab-pane label="物模型" name="2">
|
|
@@ -219,7 +217,6 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
-
|
|
|
<el-table style="width: 100%" :data="tableData.data" v-loading="tableLoading" v-if="activetab == 'tab'">
|
|
|
<el-table-column label="属性标识" align="center" prop="key" />
|
|
|
<el-table-column label="属性名称" prop="name" show-overflow-tooltip />
|
|
@@ -292,7 +289,7 @@
|
|
|
</el-tab-pane>
|
|
|
<el-tab-pane label="Topic列表" name="topic">
|
|
|
SagooMqtt协议 ,涉及的topic如下:
|
|
|
- <el-table style="width: 100%;margin-top: 20px;" :data="topicData" border>
|
|
|
+ <el-table style="width: 100%; margin-top: 20px" :data="topicData" border>
|
|
|
<el-table-column label="描述" prop="info" width="250" />
|
|
|
<el-table-column label="类型" prop="type" width="80" align="center" />
|
|
|
<el-table-column label="Topic类" prop="url">
|
|
@@ -341,7 +338,6 @@
|
|
|
</el-table>
|
|
|
<pagination v-show="deviceTableData.total > 0" :total="deviceTableData.total" v-model:page="deviceTableData.param.pageNum" v-model:limit="deviceTableData.param.pageSize" @pagination="getDeviceTableData" />
|
|
|
</div>
|
|
|
-
|
|
|
</el-tab-pane>
|
|
|
<el-tab-pane label="设备档案" name="7" v-if="deviceAssetData">
|
|
|
<el-form label-width="110px">
|
|
@@ -399,27 +395,27 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
<script lang="ts">
|
|
|
-import { toRefs, reactive, onMounted, ref, defineComponent, nextTick, onUnmounted } from 'vue';
|
|
|
-import { ElMessageBox, ElMessage, FormInstance } from 'element-plus';
|
|
|
-import functionCom from './component/function.vue';
|
|
|
-import 'vue3-json-viewer/dist/index.css';
|
|
|
-import EditDic from './component/edit.vue';
|
|
|
-import EditAttr from '../product/component/editAttr.vue';
|
|
|
-import EditFun from '../product/component/editFun.vue';
|
|
|
-import EditEvent from '../product/component/editEvent.vue';
|
|
|
-import EditTab from '../product/component/editTab.vue';
|
|
|
-import devantd from '/@/components/devantd/index.vue';
|
|
|
-import ListDic from './component/list.vue';
|
|
|
-import ChartDic from './component/chart.vue';
|
|
|
-import SubDevice from './component/subDevice.vue';
|
|
|
-import setAttr from './component/setAttr.vue';
|
|
|
-import SubDeviceMutipleBind from './component/subDeviceMutipleBind.vue';
|
|
|
-import api from '/@/api/device';
|
|
|
-import datahub from '/@/api/datahub';
|
|
|
+import { toRefs, reactive, onMounted, ref, defineComponent, nextTick, onUnmounted } from "vue";
|
|
|
+import { ElMessageBox, ElMessage, FormInstance } from "element-plus";
|
|
|
+import functionCom from "./component/function.vue";
|
|
|
+import "vue3-json-viewer/dist/index.css";
|
|
|
+import EditDic from "./component/edit.vue";
|
|
|
+import EditAttr from "../product/component/editAttr.vue";
|
|
|
+import EditFun from "../product/component/editFun.vue";
|
|
|
+import EditEvent from "../product/component/editEvent.vue";
|
|
|
+import EditTab from "../product/component/editTab.vue";
|
|
|
+import devantd from "/@/components/devantd/index.vue";
|
|
|
+import ListDic from "./component/list.vue";
|
|
|
+import ChartDic from "./component/chart.vue";
|
|
|
+import SubDevice from "./component/subDevice.vue";
|
|
|
+import setAttr from "./component/setAttr.vue";
|
|
|
+import SubDeviceMutipleBind from "./component/subDeviceMutipleBind.vue";
|
|
|
+import api from "/@/api/device";
|
|
|
+import datahub from "/@/api/datahub";
|
|
|
import FromData from "/@/views/iot/property/dossier/component/from.vue";
|
|
|
import EditAssetRef from "/@/views/iot/property/dossier/edit.vue";
|
|
|
|
|
|
-import { useRoute } from 'vue-router';
|
|
|
+import { useRoute } from "vue-router";
|
|
|
|
|
|
interface TableDataState {
|
|
|
isShowDialog: boolean;
|
|
@@ -442,14 +438,16 @@ interface TableDataState {
|
|
|
data: [];
|
|
|
total: number;
|
|
|
loading: boolean;
|
|
|
- param: {
|
|
|
- pageNum: number;
|
|
|
- pageSize: number;
|
|
|
- name: string;
|
|
|
- deviceType: string;
|
|
|
- status: string;
|
|
|
- dateRange: string[];
|
|
|
- } | any;
|
|
|
+ param:
|
|
|
+ | {
|
|
|
+ pageNum: number;
|
|
|
+ pageSize: number;
|
|
|
+ name: string;
|
|
|
+ deviceType: string;
|
|
|
+ status: string;
|
|
|
+ dateRange: string[];
|
|
|
+ }
|
|
|
+ | any;
|
|
|
};
|
|
|
logtableData: {
|
|
|
data: [];
|
|
@@ -459,24 +457,23 @@ interface TableDataState {
|
|
|
};
|
|
|
}
|
|
|
export default defineComponent({
|
|
|
- name: 'deviceEditPro',
|
|
|
+ name: "deviceEditPro",
|
|
|
components: { EditAssetRef, FromData, SubDeviceMutipleBind, SubDevice, EditDic, EditAttr, EditFun, EditEvent, EditTab, devantd, ListDic, functionCom, setAttr, ChartDic },
|
|
|
|
|
|
props: {
|
|
|
- deviceKey: String
|
|
|
+ deviceKey: String,
|
|
|
},
|
|
|
setup(props, context) {
|
|
|
+ let timer: any;
|
|
|
|
|
|
- let timer: any
|
|
|
-
|
|
|
- onUnmounted(() => clearInterval(timer))
|
|
|
+ onUnmounted(() => clearInterval(timer));
|
|
|
|
|
|
const logqueryRef = ref();
|
|
|
|
|
|
- const topicData = ref<any[]>([])
|
|
|
+ const topicData = ref<any[]>([]);
|
|
|
|
|
|
// 属性列表,查询保留小数位使用
|
|
|
- const propertyMap = new Map()
|
|
|
+ const propertyMap = new Map();
|
|
|
|
|
|
const array_list = ref([]);
|
|
|
const tableLoading = ref(false);
|
|
@@ -498,18 +495,18 @@ export default defineComponent({
|
|
|
const state = reactive<TableDataState>({
|
|
|
certificate: [],
|
|
|
phone: [],
|
|
|
- intro: '',
|
|
|
+ intro: "",
|
|
|
deviceKeyList: [],
|
|
|
areaData: [],
|
|
|
isShowDialog: false,
|
|
|
dialogVisible: false,
|
|
|
logTypeData: [],
|
|
|
- jsonData: '',
|
|
|
- activeName: '3', // 分类数据
|
|
|
- activetab: 'attr', // 分类数据
|
|
|
+ jsonData: "",
|
|
|
+ activeName: "3", // 分类数据
|
|
|
+ activetab: "attr", // 分类数据
|
|
|
detail: {},
|
|
|
prodetail: [],
|
|
|
- productKey: '',
|
|
|
+ productKey: "",
|
|
|
developer_status: 0,
|
|
|
deviceTableData: {
|
|
|
data: [],
|
|
@@ -517,7 +514,7 @@ export default defineComponent({
|
|
|
loading: false,
|
|
|
param: {
|
|
|
pageNum: 1,
|
|
|
- gatewayKey: '',
|
|
|
+ gatewayKey: "",
|
|
|
pageSize: 20,
|
|
|
dateRange: [],
|
|
|
},
|
|
@@ -528,9 +525,9 @@ export default defineComponent({
|
|
|
loading: false,
|
|
|
param: {
|
|
|
pageNum: 1,
|
|
|
- productKey: '',
|
|
|
+ productKey: "",
|
|
|
pageSize: 20,
|
|
|
- status: '',
|
|
|
+ status: "",
|
|
|
dateRange: [],
|
|
|
},
|
|
|
},
|
|
@@ -540,21 +537,21 @@ export default defineComponent({
|
|
|
loading: false,
|
|
|
param: {
|
|
|
pageNum: 1,
|
|
|
- productKey: '',
|
|
|
+ productKey: "",
|
|
|
pageSize: 20,
|
|
|
- status: '',
|
|
|
+ status: "",
|
|
|
dateRange: [],
|
|
|
},
|
|
|
},
|
|
|
});
|
|
|
|
|
|
onMounted(() => {
|
|
|
- initData()
|
|
|
+ initData();
|
|
|
});
|
|
|
|
|
|
function initData() {
|
|
|
// 如果是嵌入的就是子设备,看子设备详情,否则看页面参数
|
|
|
- const deviceKey = props.deviceKey || route.params?.id
|
|
|
+ const deviceKey = props.deviceKey || route.params?.id;
|
|
|
api.instance.detail(deviceKey).then((res: any) => {
|
|
|
state.detail = res.data;
|
|
|
state.developer_status = res.data.status;
|
|
@@ -564,10 +561,10 @@ export default defineComponent({
|
|
|
state.prodetail = res.data;
|
|
|
});
|
|
|
|
|
|
- const { phone, certificate, intro } = JSON.parse(res.data.extensionInfo || '{}')
|
|
|
+ const { phone, certificate, intro } = JSON.parse(res.data.extensionInfo || "{}");
|
|
|
state.phone = phone || [];
|
|
|
state.certificate = certificate || [];
|
|
|
- state.intro = intro
|
|
|
+ state.intro = intro;
|
|
|
|
|
|
//加载全部属性
|
|
|
datahub.node.getpropertyList({ productKey: state.detail.productKey }).then((re: any) => {
|
|
@@ -575,52 +572,53 @@ export default defineComponent({
|
|
|
re.forEach((item: any) => propertyMap.set(item.key, item?.valueType));
|
|
|
});
|
|
|
|
|
|
-
|
|
|
- const deviceType = res.data?.product?.deviceType
|
|
|
-
|
|
|
- topicData.value = deviceType === '网关' ? [
|
|
|
- {
|
|
|
- url: `/sys/${res.data.productKey}/${deviceKey}/thing/event/property/pack/post`,
|
|
|
- info: '网关批量上传事件和属性(网关发起)',
|
|
|
- type: '请求',
|
|
|
- },
|
|
|
- {
|
|
|
- url: `/sys/${res.data.productKey}/${deviceKey}/thing/event/property/pack/post_reply`,
|
|
|
- info: '网关批量上传事件和属性(网关发起)',
|
|
|
- type: '响应',
|
|
|
- }
|
|
|
- ] : [
|
|
|
-
|
|
|
- {
|
|
|
- url: `/sys/${res.data.productKey}/${deviceKey}/thing/event/property/post`,
|
|
|
- info: '设备上报属性(设备端发起)',
|
|
|
- type: '请求',
|
|
|
- },
|
|
|
- {
|
|
|
- url: `/sys/${res.data.productKey}/${deviceKey}/thing/event/property/post_reply`,
|
|
|
- info: '设备上报属性(设备端发起)',
|
|
|
- type: '响应',
|
|
|
- },
|
|
|
- {
|
|
|
- url: `/sys/${res.data.productKey}/${deviceKey}/thing/event/${'${eventIdentifier}'}/post`,
|
|
|
- info: '设备上报事件(设备端发起)',
|
|
|
- type: '请求',
|
|
|
- },
|
|
|
- {
|
|
|
- url: `/sys/${res.data.productKey}/${deviceKey}/thing/event/${'${eventIdentifier}'}/post_reply`,
|
|
|
- info: '设备上报事件(设备端发起)',
|
|
|
- type: '响应',
|
|
|
- }
|
|
|
- ]
|
|
|
+ const deviceType = res.data?.product?.deviceType;
|
|
|
+
|
|
|
+ topicData.value =
|
|
|
+ deviceType === "网关"
|
|
|
+ ? [
|
|
|
+ {
|
|
|
+ url: `/sys/${res.data.productKey}/${deviceKey}/thing/event/property/pack/post`,
|
|
|
+ info: "网关批量上传事件和属性(网关发起)",
|
|
|
+ type: "请求",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ url: `/sys/${res.data.productKey}/${deviceKey}/thing/event/property/pack/post_reply`,
|
|
|
+ info: "网关批量上传事件和属性(网关发起)",
|
|
|
+ type: "响应",
|
|
|
+ },
|
|
|
+ ]
|
|
|
+ : [
|
|
|
+ {
|
|
|
+ url: `/sys/${res.data.productKey}/${deviceKey}/thing/event/property/post`,
|
|
|
+ info: "设备上报属性(设备端发起)",
|
|
|
+ type: "请求",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ url: `/sys/${res.data.productKey}/${deviceKey}/thing/event/property/post_reply`,
|
|
|
+ info: "设备上报属性(设备端发起)",
|
|
|
+ type: "响应",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ url: `/sys/${res.data.productKey}/${deviceKey}/thing/event/${"${eventIdentifier}"}/post`,
|
|
|
+ info: "设备上报事件(设备端发起)",
|
|
|
+ type: "请求",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ url: `/sys/${res.data.productKey}/${deviceKey}/thing/event/${"${eventIdentifier}"}/post_reply`,
|
|
|
+ info: "设备上报事件(设备端发起)",
|
|
|
+ type: "响应",
|
|
|
+ },
|
|
|
+ ];
|
|
|
|
|
|
// 加载对应设备档案 (企业版功能)
|
|
|
- sessionStorage.isEnterprise && getDeviceAssetMetadata()
|
|
|
+ sessionStorage.isEnterprise && getDeviceAssetMetadata();
|
|
|
|
|
|
getrunData();
|
|
|
|
|
|
- timer = setInterval(getrunData, 3000)
|
|
|
+ timer = setInterval(getrunData, 3000);
|
|
|
|
|
|
- getDeviceTableData()
|
|
|
+ getDeviceTableData();
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -634,56 +632,58 @@ export default defineComponent({
|
|
|
const newArray = (resde?.data || []).map((obj: any) => {
|
|
|
const { name, value, ...rest } = obj;
|
|
|
const newObj = { name, value, ...rest };
|
|
|
- newObj[name] = value ? value : '';
|
|
|
+ newObj[name] = value ? value : "";
|
|
|
return newObj;
|
|
|
});
|
|
|
- dataList.value = newArray
|
|
|
+ dataList.value = newArray;
|
|
|
|
|
|
for (const item of dataList.value) {
|
|
|
item.pattern = false;
|
|
|
- if (item.types == 'input' || item.types == 'textarea') {
|
|
|
+ if (item.types == "input" || item.types == "textarea") {
|
|
|
if (urlRegex.test(item.value)) {
|
|
|
item.pattern = true;
|
|
|
}
|
|
|
}
|
|
|
// 根据属性返回键获取对应档案对应的内容
|
|
|
- deviceAssetMetadata.value[item.name] = item.value ? item.value : ''
|
|
|
+ deviceAssetMetadata.value[item.name] = item.value ? item.value : "";
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
- }
|
|
|
+ };
|
|
|
|
|
|
const mutipleUnbind = () => {
|
|
|
- let msg = '是否进行批量解绑?';
|
|
|
+ let msg = "是否进行批量解绑?";
|
|
|
if (state.deviceKeyList.length === 0) {
|
|
|
- ElMessage.error('请选择要批量解绑的数据。');
|
|
|
+ ElMessage.error("请选择要批量解绑的数据。");
|
|
|
return;
|
|
|
}
|
|
|
- ElMessageBox.confirm(msg, '提示', {
|
|
|
- confirmButtonText: '确认',
|
|
|
- cancelButtonText: '取消',
|
|
|
- type: 'warning',
|
|
|
+ ElMessageBox.confirm(msg, "提示", {
|
|
|
+ confirmButtonText: "确认",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning",
|
|
|
})
|
|
|
.then(() => {
|
|
|
- api.device.mutipleUnbind({
|
|
|
- "gatewayKey": state.deviceTableData.param.gatewayKey,
|
|
|
- "subKeys": state.deviceKeyList
|
|
|
- }).then(() => {
|
|
|
- ElMessage.success('解绑成功');
|
|
|
- // typeList();
|
|
|
- getDeviceTableData();
|
|
|
- });
|
|
|
+ api.device
|
|
|
+ .mutipleUnbind({
|
|
|
+ gatewayKey: state.deviceTableData.param.gatewayKey,
|
|
|
+ subKeys: state.deviceKeyList,
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ ElMessage.success("解绑成功");
|
|
|
+ // typeList();
|
|
|
+ getDeviceTableData();
|
|
|
+ });
|
|
|
})
|
|
|
- .catch(() => { });
|
|
|
- }
|
|
|
+ .catch(() => {});
|
|
|
+ };
|
|
|
|
|
|
const getDeviceTableData = () => {
|
|
|
- state.deviceTableData.data = []
|
|
|
+ state.deviceTableData.data = [];
|
|
|
state.deviceTableData.param.gatewayKey = state.detail.key;
|
|
|
api.device.getList(state.deviceTableData.param).then((res: any) => {
|
|
|
state.deviceTableData.data = res.list;
|
|
|
state.deviceTableData.total = res.Total;
|
|
|
- })
|
|
|
+ });
|
|
|
};
|
|
|
|
|
|
// 多选框选中数据
|
|
@@ -693,23 +693,21 @@ export default defineComponent({
|
|
|
|
|
|
// 打开修改产品弹窗
|
|
|
const onOpenDetail = (row: any) => {
|
|
|
- subDeviceRef.value.openDialog(row)
|
|
|
+ subDeviceRef.value.openDialog(row);
|
|
|
};
|
|
|
|
|
|
-
|
|
|
// 删除子设备
|
|
|
const deleteSubDevice = (row: any) => {
|
|
|
- ElMessageBox.confirm(`此操作将永久删除该子设备:${row.name}, 是否继续?`, '提示', {
|
|
|
- confirmButtonText: '删除',
|
|
|
- cancelButtonText: '取消',
|
|
|
- type: 'warning',
|
|
|
+ ElMessageBox.confirm(`此操作将永久删除该子设备:${row.name}, 是否继续?`, "提示", {
|
|
|
+ confirmButtonText: "删除",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning",
|
|
|
}).then(() => {
|
|
|
api.product.deleteSubDevice(row.id).then(() => {
|
|
|
- ElMessage.success('删除成功');
|
|
|
+ ElMessage.success("删除成功");
|
|
|
getDeviceTableData();
|
|
|
});
|
|
|
});
|
|
|
-
|
|
|
};
|
|
|
|
|
|
const onLogDetail = (row: any) => {
|
|
@@ -721,7 +719,6 @@ export default defineComponent({
|
|
|
mutipleBindRef.value.openDialog(state.deviceTableData.param.gatewayKey);
|
|
|
};
|
|
|
|
|
|
-
|
|
|
//编辑属性
|
|
|
const onEditAttr = (row: any) => {
|
|
|
editAttrRef.value.openDialog(row, state.productKey);
|
|
@@ -768,7 +765,7 @@ export default defineComponent({
|
|
|
|
|
|
//查看日志图形
|
|
|
const onOpenChartDetail = (row: any) => {
|
|
|
- chartDicRef.value.openDialog(row, state.detail.key);
|
|
|
+ chartDicRef.value.openDialog(row, state.detail.key, state.productKey);
|
|
|
};
|
|
|
|
|
|
// 打开修改产品弹窗
|
|
@@ -778,7 +775,7 @@ export default defineComponent({
|
|
|
|
|
|
// 打开修改设备档案弹窗
|
|
|
const onOpenEditAsset = () => {
|
|
|
- editAssetRef.value.open(deviceAssetData.value, state.detail.product)
|
|
|
+ editAssetRef.value.open(deviceAssetData.value, state.detail.product);
|
|
|
};
|
|
|
|
|
|
// 删除产品
|
|
@@ -786,109 +783,121 @@ export default defineComponent({
|
|
|
let msg = `此操作将永久删除该数据,是否继续?`;
|
|
|
|
|
|
if (key.length === 0) {
|
|
|
- ElMessage.error('请选择要删除的数据。');
|
|
|
+ ElMessage.error("请选择要删除的数据。");
|
|
|
return;
|
|
|
}
|
|
|
- ElMessageBox.confirm(msg, '提示', {
|
|
|
- confirmButtonText: '确认',
|
|
|
- cancelButtonText: '取消',
|
|
|
- type: 'warning',
|
|
|
+ ElMessageBox.confirm(msg, "提示", {
|
|
|
+ confirmButtonText: "确认",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning",
|
|
|
})
|
|
|
.then(() => {
|
|
|
- if (type == 'attr') {
|
|
|
+ if (type == "attr") {
|
|
|
api.model.propertydel(state.productKey, key).then(() => {
|
|
|
- ElMessage.success('删除成功');
|
|
|
+ ElMessage.success("删除成功");
|
|
|
getproperty();
|
|
|
});
|
|
|
}
|
|
|
- if (type == 'fun') {
|
|
|
+ if (type == "fun") {
|
|
|
api.model.functiondel(state.productKey, key).then(() => {
|
|
|
- ElMessage.success('删除成功');
|
|
|
+ ElMessage.success("删除成功");
|
|
|
getfunction();
|
|
|
});
|
|
|
}
|
|
|
- if (type == 'event') {
|
|
|
+ if (type == "event") {
|
|
|
api.model.eventdel(state.productKey, key).then(() => {
|
|
|
- ElMessage.success('删除成功');
|
|
|
+ ElMessage.success("删除成功");
|
|
|
getevent();
|
|
|
});
|
|
|
}
|
|
|
- if (type == 'tab') {
|
|
|
+ if (type == "tab") {
|
|
|
api.model.tagdel(state.productKey, key).then(() => {
|
|
|
- ElMessage.success('删除成功');
|
|
|
+ ElMessage.success("删除成功");
|
|
|
gettab();
|
|
|
});
|
|
|
}
|
|
|
})
|
|
|
- .catch(() => { });
|
|
|
+ .catch(() => {});
|
|
|
};
|
|
|
|
|
|
//根据不同类型获取列表
|
|
|
const getList = () => {
|
|
|
switch (state.activetab) {
|
|
|
- case 'attr':
|
|
|
+ case "attr":
|
|
|
getproperty();
|
|
|
break;
|
|
|
- case 'fun':
|
|
|
+ case "fun":
|
|
|
getfunction();
|
|
|
break;
|
|
|
- case 'event':
|
|
|
+ case "event":
|
|
|
getevent();
|
|
|
break;
|
|
|
- case 'tab':
|
|
|
+ case "tab":
|
|
|
gettab();
|
|
|
break;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const getproperty = () => {
|
|
|
- state.tableData.data = []
|
|
|
- tableLoading.value = true
|
|
|
- api.model.property(state.tableData.param).then((res: any) => {
|
|
|
- state.tableData.data = res.Data;
|
|
|
- state.tableData.total = res.Total;
|
|
|
- }).finally(() => tableLoading.value = false)
|
|
|
+ state.tableData.data = [];
|
|
|
+ tableLoading.value = true;
|
|
|
+ api.model
|
|
|
+ .property(state.tableData.param)
|
|
|
+ .then((res: any) => {
|
|
|
+ state.tableData.data = res.Data;
|
|
|
+ state.tableData.total = res.Total;
|
|
|
+ })
|
|
|
+ .finally(() => (tableLoading.value = false));
|
|
|
};
|
|
|
|
|
|
const getfunction = () => {
|
|
|
- state.tableData.data = []
|
|
|
- tableLoading.value = true
|
|
|
- api.model.function(state.tableData.param).then((res: any) => {
|
|
|
- state.tableData.data = res.Data;
|
|
|
- state.tableData.total = res.Total;
|
|
|
- }).finally(() => tableLoading.value = false)
|
|
|
+ state.tableData.data = [];
|
|
|
+ tableLoading.value = true;
|
|
|
+ api.model
|
|
|
+ .function(state.tableData.param)
|
|
|
+ .then((res: any) => {
|
|
|
+ state.tableData.data = res.Data;
|
|
|
+ state.tableData.total = res.Total;
|
|
|
+ })
|
|
|
+ .finally(() => (tableLoading.value = false));
|
|
|
};
|
|
|
const getevent = () => {
|
|
|
- state.tableData.data = []
|
|
|
- tableLoading.value = true
|
|
|
- api.model.event(state.tableData.param).then((res: any) => {
|
|
|
- state.tableData.data = res.Data;
|
|
|
- state.tableData.total = res.Total;
|
|
|
- }).finally(() => tableLoading.value = false)
|
|
|
+ state.tableData.data = [];
|
|
|
+ tableLoading.value = true;
|
|
|
+ api.model
|
|
|
+ .event(state.tableData.param)
|
|
|
+ .then((res: any) => {
|
|
|
+ state.tableData.data = res.Data;
|
|
|
+ state.tableData.total = res.Total;
|
|
|
+ })
|
|
|
+ .finally(() => (tableLoading.value = false));
|
|
|
};
|
|
|
|
|
|
const gettab = () => {
|
|
|
- state.tableData.data = []
|
|
|
- tableLoading.value = true
|
|
|
- api.model.tag(state.tableData.param).then((res: any) => {
|
|
|
- state.tableData.data = res.Data;
|
|
|
- state.tableData.total = res.Total;
|
|
|
- }).finally(() => tableLoading.value = false)
|
|
|
+ state.tableData.data = [];
|
|
|
+ tableLoading.value = true;
|
|
|
+ api.model
|
|
|
+ .tag(state.tableData.param)
|
|
|
+ .then((res: any) => {
|
|
|
+ state.tableData.data = res.Data;
|
|
|
+ state.tableData.total = res.Total;
|
|
|
+ })
|
|
|
+ .finally(() => (tableLoading.value = false));
|
|
|
};
|
|
|
|
|
|
const wuhandleClick = (tab: any) => {
|
|
|
state.activetab = tab.props.name;
|
|
|
switch (tab.props.name) {
|
|
|
- case 'attr':
|
|
|
+ case "attr":
|
|
|
getproperty();
|
|
|
break;
|
|
|
- case 'fun':
|
|
|
+ case "fun":
|
|
|
getfunction();
|
|
|
break;
|
|
|
- case 'event':
|
|
|
+ case "event":
|
|
|
getevent();
|
|
|
break;
|
|
|
- case 'tab':
|
|
|
+ case "tab":
|
|
|
gettab();
|
|
|
break;
|
|
|
}
|
|
@@ -909,22 +918,22 @@ export default defineComponent({
|
|
|
};
|
|
|
|
|
|
const getValueText = (key: String, value: String) => {
|
|
|
- const item = propertyMap.get(key)
|
|
|
+ const item = propertyMap.get(key);
|
|
|
|
|
|
- if (!item) return value
|
|
|
+ if (!item) return value;
|
|
|
|
|
|
if (item.type === "enum") {
|
|
|
const option = item.elements.find((element: any) => element.value === value);
|
|
|
if (option) {
|
|
|
return option.text;
|
|
|
}
|
|
|
- } else if (['float', 'double'].includes(item?.type) && item?.decimals) {
|
|
|
+ } else if (["float", "double"].includes(item?.type) && item?.decimals) {
|
|
|
// 根据属性确定保留小数位数
|
|
|
- return Number(value).toFixed(item.decimals)
|
|
|
+ return Number(value).toFixed(item.decimals);
|
|
|
} else {
|
|
|
return value;
|
|
|
}
|
|
|
- }
|
|
|
+ };
|
|
|
const getStatusText = (name: any, value: string) => {
|
|
|
let data = array_list.value as any;
|
|
|
for (let i = 0; i < data.length; i++) {
|
|
@@ -952,25 +961,22 @@ export default defineComponent({
|
|
|
return `${field.name}: ${element.text}`;
|
|
|
}
|
|
|
} else {
|
|
|
-
|
|
|
return `${field.name}: ${value}`;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return name + ':' + value;
|
|
|
- }
|
|
|
+ return name + ":" + value;
|
|
|
+ };
|
|
|
|
|
|
const getrunData = () => {
|
|
|
-
|
|
|
api.instance.getrun_status({ deviceKey: state.detail.key }).then((res: any) => {
|
|
|
- state.areaData = res
|
|
|
+ state.areaData = res;
|
|
|
let properties = state.areaData.properties || [];
|
|
|
|
|
|
var temp = new Array();
|
|
|
|
|
|
properties.forEach(function (item: any, index: number) {
|
|
|
-
|
|
|
let datalist = item.list || [];
|
|
|
temp[index] = [];
|
|
|
var temps = new Array();
|
|
@@ -980,17 +986,16 @@ export default defineComponent({
|
|
|
temps.push(a);
|
|
|
}
|
|
|
});
|
|
|
- if (item.type == 'object') {
|
|
|
+ if (item.type == "object") {
|
|
|
item.value = JSON.parse(item.value);
|
|
|
}
|
|
|
|
|
|
- temp[index]['name'] = item.name
|
|
|
- temp[index]['key'] = item.key
|
|
|
- temp[index]['type'] = item.type
|
|
|
- temp[index]['unit'] = item.unit
|
|
|
- temp[index]['value'] = item.value
|
|
|
- temp[index]['list'] = temps
|
|
|
-
|
|
|
+ temp[index]["name"] = item.name;
|
|
|
+ temp[index]["key"] = item.key;
|
|
|
+ temp[index]["type"] = item.type;
|
|
|
+ temp[index]["unit"] = item.unit;
|
|
|
+ temp[index]["value"] = item.value;
|
|
|
+ temp[index]["list"] = temps;
|
|
|
});
|
|
|
state.areaData.properties = temp;
|
|
|
});
|
|
@@ -1019,25 +1024,25 @@ export default defineComponent({
|
|
|
const CkOption = () => {
|
|
|
if (state.developer_status == 2) {
|
|
|
api.instance.devoffline({ id: state.detail.id }).then((res: any) => {
|
|
|
- ElMessage.success('操作成功');
|
|
|
+ ElMessage.success("操作成功");
|
|
|
state.developer_status = 1;
|
|
|
});
|
|
|
} else {
|
|
|
api.instance.devonline({ id: state.detail.id }).then((res: any) => {
|
|
|
- ElMessage.success('操作成功');
|
|
|
+ ElMessage.success("操作成功");
|
|
|
state.developer_status = 2;
|
|
|
});
|
|
|
}
|
|
|
};
|
|
|
const onlineTimeoutUpdate = () => {
|
|
|
- if (!state.detail.onlineTimeout) return ElMessage('请先输入设备超时时间')
|
|
|
+ if (!state.detail.onlineTimeout) return ElMessage("请先输入设备超时时间");
|
|
|
api.device.updateOnlineTimeout({ deviceKey: state.detail.key, onlineTimeout: state.detail.onlineTimeout }).then(() => {
|
|
|
- ElMessage.success('设置成功')
|
|
|
- })
|
|
|
- }
|
|
|
+ ElMessage.success("设置成功");
|
|
|
+ });
|
|
|
+ };
|
|
|
const setAttr = (row: any) => {
|
|
|
- setAttrRef.value.show(row)
|
|
|
- }
|
|
|
+ setAttrRef.value.show(row);
|
|
|
+ };
|
|
|
|
|
|
return {
|
|
|
topicData,
|
|
@@ -1101,35 +1106,35 @@ export default defineComponent({
|
|
|
});
|
|
|
</script>
|
|
|
<style scoped lang="scss">
|
|
|
-.capsule-wrapper{
|
|
|
+.capsule-wrapper {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- .capsule{
|
|
|
+ .capsule {
|
|
|
display: flex;
|
|
|
flex-direction: row;
|
|
|
align-items: center;
|
|
|
border: 1px solid var(--el-color-primary);
|
|
|
border-radius: 20px;
|
|
|
font-size: 12px;
|
|
|
- .label{
|
|
|
- height: 24px;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- border-top-left-radius: 20px;
|
|
|
- border-bottom-left-radius: 20px;
|
|
|
- background-color: var(--el-color-primary);
|
|
|
- padding: 0px 10px;
|
|
|
- text-indent: 2px;
|
|
|
- color: var(--el-color-white) !important;
|
|
|
+ .label {
|
|
|
+ height: 24px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ border-top-left-radius: 20px;
|
|
|
+ border-bottom-left-radius: 20px;
|
|
|
+ background-color: var(--el-color-primary);
|
|
|
+ padding: 0px 10px;
|
|
|
+ text-indent: 2px;
|
|
|
+ color: var(--el-color-white) !important;
|
|
|
}
|
|
|
- .value{
|
|
|
- height: 24px;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- border-top-right-radius: 20px;
|
|
|
- border-bottom-right-radius: 20px;
|
|
|
- text-indent: -2px;
|
|
|
- padding: 0px 10px;
|
|
|
+ .value {
|
|
|
+ height: 24px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ border-top-right-radius: 20px;
|
|
|
+ border-bottom-right-radius: 20px;
|
|
|
+ text-indent: -2px;
|
|
|
+ padding: 0px 10px;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -1196,7 +1201,6 @@ export default defineComponent({
|
|
|
display: flex;
|
|
|
padding: 10px;
|
|
|
justify-content: space-between;
|
|
|
-
|
|
|
}
|
|
|
|
|
|
.content-box .pro-box .protitle {
|
|
@@ -1251,7 +1255,7 @@ tr {
|
|
|
|
|
|
line-height: 1.5;
|
|
|
list-style: none;
|
|
|
- font-feature-settings: 'tnum';
|
|
|
+ font-feature-settings: "tnum";
|
|
|
position: relative;
|
|
|
border-radius: 2px;
|
|
|
transition: all 0.3s;
|