|  | @@ -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;
 |