suerprisePlus
2024-07-08 6f393bea8db5898684b573b8bebc64890fcc9183
src/views/iot/device/device-edit.vue
@@ -1,125 +1,154 @@
<template>
  <el-card style="margin: 6px; padding-bottom: 100px">
  <el-card style="margin: 6px;width:calc(100% - 12px); height: calc(100% - 12px);position:absolute; ">
    <el-tabs v-model="activeName" tab-position="left" @tab-click="tabChange" style="padding: 10px; min-height: 400px">
      <el-tab-pane name="basic">
        <span slot="label">* 基本信息</span>
        <el-form ref="form" :model="form" :rules="rules" label-width="100px">
          <el-row :gutter="100">
            <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8">
              <el-form-item label="设备名称" prop="deviceName">
                <el-input v-model="form.deviceName" placeholder="请输入设备名称">
                  <el-button slot="append" @click="openSummaryDialog" v-if="form.deviceId != 0">摘要</el-button>
                </el-input>
              </el-form-item>
              <el-form-item label="" prop="productName">
                <template slot="label">
                  <span style="color: red">*</span>
                  所属产品
                </template>
                <el-input readonly v-model="form.productName" placeholder="请选择产品" :disabled="form.status != 1">
                  <el-button slot="append" @click="selectProduct()" :disabled="form.status != 1">选择</el-button>
                </el-input>
              </el-form-item>
              <el-form-item label="" prop="serialNumber">
                <template slot="label">
                  <span style="color: red">*</span>
                  设备编号
                </template>
                <el-input v-model="form.serialNumber" placeholder="请输入设备编号" :disabled="form.status !== 1" maxlength="32">
                  <el-button slot="append" @click="generateNum" :loading="genDisabled"
                    :disabled="form.status !== 1">生成</el-button>
                </el-input>
              </el-form-item>
              <el-form-item v-if="openServerTip">
                <template>
                  <el-alert type="info" show-icon description="当前选择TCP协议,设备编号生成为HEX格式"></el-alert>
                </template>
              </el-form-item>
              <el-form-item v-if="openTip">
                <template>
                  <el-alert type="success" show-icon description="当前选择的产品属于modbus协议,将在网关设备创建后根据采集点模板生成子设备"></el-alert>
                </template>
              </el-form-item>
              <el-form-item label="固件版本" prop="firmwareVersion">
                <el-input v-model="form.firmwareVersion" placeholder="请输入固件版本" type="number" step="0.1"
                  :disabled="form.status != 1 || form.deviceType === 3">
                  <template slot="prepend">Version</template>
                </el-input>
              </el-form-item>
              <el-form-item label="模拟设备" prop="isSimulate">
                <el-switch v-model="form.isSimulate" active-text="" inactive-text="" :active-value="1" :inactive-value="0"
                  :disabled="form.deviceType === 3"></el-switch>
              </el-form-item>
              <el-form-item label="设备影子" prop="isShadow">
                <el-switch v-model="form.isShadow" active-text="" inactive-text="" :active-value="1" :inactive-value="0"
                  :disabled="form.deviceType === 3"></el-switch>
              </el-form-item>
              <el-form-item label="禁用设备" prop="deviceStatus">
                <el-switch v-model="deviceStatus" active-text="" inactive-text=""
                           :disabled="form.status === 1 || form.deviceType === 3" :active-value="1" :inactive-value="0"
                           active-color="#F56C6C"></el-switch>
              </el-form-item>
              <el-form-item label="备注信息" prop="remark">
                <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" rows="1" />
              </el-form-item>
            </el-col>
            <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8">
              <el-form-item label="定位方式" prop="locationWay">
                <el-select v-model="form.locationWay" placeholder="请选择设备状态" clearable size="small" style="width: 100%"
                  :disabled="form.deviceType === 3">
                  <el-option v-for="dict in dict.type.iot_location_way" :key="dict.value" :label="dict.label"
                    :value="Number(dict.value)" />
                </el-select>
              </el-form-item>
              <el-form-item label="设备经度" prop="longitude">
                <el-input v-model="form.longitude" placeholder="请输入设备经度" type="number" :disabled="form.locationWay != 3">
                  <el-link slot="append" :underline="false" href="https://api.map.baidu.com/lbsapi/getpoint/index.html"
                    target="_blank" :disabled="form.locationWay != 3">坐标拾取</el-link>
                </el-input>
              </el-form-item>
              <el-form-item label="设备纬度" prop="latitude">
                <el-input v-model="form.latitude" placeholder="请输入设备纬度" type="number" :disabled="form.locationWay != 3">
                  <el-link slot="append" :underline="false" href="https://api.map.baidu.com/lbsapi/getpoint/index.html"
                    target="_blank" :disabled="form.locationWay != 3">坐标拾取</el-link>
                </el-input>
              </el-form-item>
              <el-form-item label="所在地址" prop="networkAddress">
                <el-input v-model="form.networkAddress" placeholder="请输入设备所在地址" :disabled="form.locationWay != 3" />
              </el-form-item>
              <el-form-item label="入网地址" prop="networkIp">
                <el-input v-model="form.networkIp" placeholder="设备入网IP" disabled />
              </el-form-item>
              <el-form-item label="激活时间" prop="activeTime">
                <el-date-picker clearable v-model="form.activeTime" type="date" value-format="yyyy-MM-dd"
                  placeholder="设备激活时间" disabled style="width: 100%"></el-date-picker>
              </el-form-item>
              <el-form-item label="设备信号" prop="rssi">
                <el-input v-model="form.rssi" placeholder="设备信号强度" disabled />
              </el-form-item>
              <el-form-item label="其他信息" prop="remark" v-if="form.deviceId != 0">
                <dict-tag :options="dict.type.iot_device_status" :value="form.status"
                  style="display: inline-block; margin-right: 8px" />
                <el-button size="small" @click="handleViewMqtt()">认证信息</el-button>
                <el-button size="small" @click="openCodeDialog()">二维码</el-button>
              </el-form-item>
            </el-col>
            <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8" v-if="form.deviceId != 0">
              <div
                style="border: 1px solid #dfe4ed; border-radius: 5px; padding: 5px; text-align: center; line-height: 400px">
                <div id="map" style="height: 435px; width: 100%">地图展示区域,新增后显示</div>
              </div>
            </el-col>
          </el-row>
        </el-form>
        <el-form label-width="100px" style="margin-top: 50px">
          <el-form-item style="text-align: center; margin-left: -100px; margin-top: 10px">
            <el-button type="primary" @click="submitForm" v-hasPermi="['iot:device:edit']" v-show="form.deviceId != 0">修
              改</el-button>
            <el-button type="primary" @click="submitForm" v-hasPermi="['iot:device:add']" v-show="form.deviceId == 0">新
              增</el-button>
          </el-form-item>
        </el-form>
        <div style="width:100%;    display:flex">
          <div class="leftCount">
            <el-form ref="form" :model="form" :rules="rules" label-width="100px">
              <el-row :gutter="100">
                <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
                  <el-form-item label="设备名称" prop="deviceName">
                    <el-input v-model="form.deviceName" placeholder="请输入设备名称">
                      <el-button slot="append" @click="openSummaryDialog" v-if="form.deviceId != 0">摘要</el-button>
                    </el-input>
                  </el-form-item>
                  <el-form-item label="" prop="productName">
                    <template slot="label">
                      <span style="color: red">*</span>
                      所属产品
                    </template>
                    <el-input readonly v-model="form.productName" placeholder="请选择产品" :disabled="form.status != 1">
                      <el-button slot="append" @click="selectProduct()" :disabled="form.status != 1">选择</el-button>
                    </el-input>
                  </el-form-item>
                  <el-form-item label="" prop="serialNumber">
                    <template slot="label">
                      <span style="color: red">*</span>
                      设备编号
                    </template>
                    <el-input v-model="form.serialNumber" placeholder="请输入设备编号" :disabled="form.status !== 1"
                      maxlength="32">
                      <el-button slot="append" @click="generateNum" :loading="genDisabled"
                        :disabled="form.status !== 1">生成</el-button>
                    </el-input>
                  </el-form-item>
                  <el-form-item v-if="openServerTip">
                    <template>
                      <el-alert type="info" show-icon description="当前选择TCP协议,设备编号生成为HEX格式"></el-alert>
                    </template>
                  </el-form-item>
                  <el-form-item v-if="openTip">
                    <template>
                      <el-alert type="success" show-icon
                        description="当前选择的产品属于modbus协议,将在网关设备创建后根据采集点模板生成子设备"></el-alert>
                    </template>
                  </el-form-item>
                  <el-form-item label="固件版本" prop="firmwareVersion">
                    <el-input v-model="form.firmwareVersion" placeholder="请输入固件版本" type="number" step="0.1"
                      :disabled="form.status != 1 || form.deviceType === 3">
                      <template slot="prepend">Version</template>
                    </el-input>
                  </el-form-item>
                  <el-form-item label="模拟设备" prop="isSimulate">
                    <el-switch v-model="form.isSimulate" active-text="" inactive-text="" :active-value="1"
                      :inactive-value="0" :disabled="form.deviceType === 3"></el-switch>
                  </el-form-item>
                  <el-form-item label="设备影子" prop="isShadow">
                    <el-switch v-model="form.isShadow" active-text="" inactive-text="" :active-value="1"
                      :inactive-value="0" :disabled="form.deviceType === 3"></el-switch>
                  </el-form-item>
                  <el-form-item label="禁用设备" prop="deviceStatus">
                    <el-switch v-model="deviceStatus" active-text="" inactive-text=""
                      :disabled="form.status === 1 || form.deviceType === 3" :active-value="1" :inactive-value="0"
                      active-color="#F56C6C"></el-switch>
                  </el-form-item>
                  <el-form-item label="备注信息" prop="remark">
                    <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" rows="1" />
                  </el-form-item>
                </el-col>
                <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
                  <el-form-item label="定位方式" prop="locationWay">
                    <el-select v-model="form.locationWay" placeholder="请选择设备状态" clearable size="small"
                      style="width: 100%" :disabled="form.deviceType === 3">
                      <el-option v-for="dict in dict.type.iot_location_way" :key="dict.value" :label="dict.label"
                        :value="Number(dict.value)" />
                    </el-select>
                  </el-form-item>
                  <el-form-item label="设备经度" prop="longitude">
                    <el-input v-model="form.longitude" placeholder="请输入设备经度" type="number"
                      :disabled="form.locationWay != 3">
                      <el-link slot="append" :underline="false"
                        href="https://api.map.baidu.com/lbsapi/getpoint/index.html" target="_blank"
                        :disabled="form.locationWay != 3">坐标拾取</el-link>
                    </el-input>
                  </el-form-item>
                  <el-form-item label="设备纬度" prop="latitude">
                    <el-input v-model="form.latitude" placeholder="请输入设备纬度" type="number"
                      :disabled="form.locationWay != 3">
                      <el-link slot="append" :underline="false"
                        href="https://api.map.baidu.com/lbsapi/getpoint/index.html" target="_blank"
                        :disabled="form.locationWay != 3">坐标拾取</el-link>
                    </el-input>
                  </el-form-item>
                  <el-form-item label="所在地址" prop="networkAddress">
                    <el-input v-model="form.networkAddress" placeholder="请输入设备所在地址" :disabled="form.locationWay != 3" />
                  </el-form-item>
                  <el-form-item label="入网地址" prop="networkIp">
                    <el-input v-model="form.networkIp" placeholder="设备入网IP" disabled />
                  </el-form-item>
                  <el-form-item label="激活时间" prop="activeTime">
                    <el-date-picker clearable v-model="form.activeTime" type="date" value-format="yyyy-MM-dd"
                      placeholder="设备激活时间" disabled
                      style="width: 100%"></el-date-picker>http://localhost:82/iot/template
                  </el-form-item>
                  <el-form-item label="设备信号" prop="rssi">
                    <el-input v-model="form.rssi" placeholder="设备信号强度" disabled />
                  </el-form-item>
                  <el-form-item label="设备模型" prop="modeUrl">
                    <el-select placeholder="请选择设备模型" v-model="modeUrl" @change="changeSelect" size="small"
                      style="width: 100%">
                      <el-option v-for="(item, index) in modelOption" :key="item.id" :label="item.name"
                        :value="item.id">
                      </el-option>
                    </el-select>
                  </el-form-item>
                  <el-form-item label="其他信息" prop="remark" v-if="form.deviceId != 0">
                    <dict-tag :options="dict.type.iot_device_status" :value="form.status"
                      style="display: inline-block; margin-right: 8px" />
                    <el-button size="small" @click="handleViewMqtt()">认证信息</el-button>
                    <el-button size="small" @click="openCodeDialog()">二维码</el-button>
                  </el-form-item>
                </el-col>
                <!-- <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8" v-if="form.deviceId != 0">
            </el-col>   -->
              </el-row>
            </el-form>
            <el-form label-width="100px" style="margin-top: 50px">
              <el-form-item style="text-align: center; margin-left: -100px; margin-top: 10px">
                <el-button type="primary" @click="submitForm" v-hasPermi="['iot:device:edit']"
                  v-show="form.deviceId != 0">修
                  改</el-button>
                <el-button type="primary" @click="submitForm" v-hasPermi="['iot:device:add']"
                  v-show="form.deviceId == 0">新
                  增</el-button>
              </el-form-item>
            </el-form>
          </div>
          <div class="rightCount">
            <div class="contebtBoder">
              <div id="map" style="height:100%; width: 100%">地图展示区域,新增后显示</div>
            </div>
            <div   class="contebtBoder" style="margin-top: 20px;">
              <three-js :someData="someData"></three-js>
            </div>
          </div>
        </div>
        <!-- 选择产品 -->
        <product-list ref="productList" :productId="form.productId" @productEvent="getProductData($event)" />
@@ -127,27 +156,27 @@
      <el-tab-pane name="runningStatus" v-if="form.deviceType !== 3 && !isSubDev">
        <span slot="label">运行状态</span>
        <running-status ref="runningStatus" :device="form" @statusEvent="getDeviceStatusData($event)"/>
        <running-status ref="runningStatus" :device="form" @statusEvent="getDeviceStatusData($event)" />
      </el-tab-pane>
      <el-tab-pane name="runningStatus" v-if="isSubDev">
        <span slot="label"><span style="color:red;">¥ </span>运行状态</span>
        <business ref="business"/>
        <business ref="business" />
      </el-tab-pane>
      <el-tab-pane name="sipChannel" :disabled="form.deviceId === 0" v-if="form.deviceType === 3">
        <span slot="label"><span style="color:red;">¥ </span>设备通道</span>
        <business ref="business"/>
        <business ref="business" />
      </el-tab-pane>
      <el-tab-pane :disabled="form.deviceId === 0" v-if="form.deviceType === 3" name="sipPlayer">
        <span slot="label"><span style="color:red;">¥ </span>设备直播</span>
        <business ref="business"/>
        <business ref="business" />
      </el-tab-pane>
      <el-tab-pane :disabled="form.deviceId === 0" v-if="form.deviceType === 3" name="sipVideo">
        <span slot="label"><span style="color:red;">¥ </span>直播录像</span>
        <business ref="business"/>
        <business ref="business" />
      </el-tab-pane>
      <el-tab-pane name="deviceTimer" :disabled="form.deviceId === 0"
@@ -172,7 +201,7 @@
        <device-func ref="deviceFuncLog" :device="form" />
      </el-tab-pane>
      <el-tab-pane name="deviceMonitor" :disabled="form.deviceId == 0 "
      <el-tab-pane name="deviceMonitor" :disabled="form.deviceId == 0"
        v-if="form.deviceType !== 3 && hasShrarePerm('monitor')">
        <span slot="label">实时监测</span>
        <device-monitor ref="deviceMonitor" :device="form" />
@@ -263,10 +292,15 @@
import business from "@/views/iot/business/index.vue";
import vueQr from 'vue-qr';
import { loadBMap } from '@/utils/map.js';
import { deviceSynchronization, getDevice, addDevice, updateDevice, generatorDeviceNum, listDevice, getMqttConnect } from '@/api/iot/device';
import {
  deviceSynchronization, getDevice, addDevice, updateDevice,
  generatorDeviceNum, listDevice, getMqttConnect, modelSelectPublishes,
  setModelInsertModel, setModelSelectModelByPage
} from '@/api/iot/device';
import { getDeviceRunningStatus } from '@/api/iot/device';
import { cacheJsonThingsModel } from '@/api/iot/model';
import { getDeviceTemp } from '@/api/iot/temp';
import threeJs from '../../threeJs/index.vue'
export default {
  name: 'DeviceEdit',
@@ -283,6 +317,7 @@
    deviceTimer,
    JsonViewer,
    vueQr,
    threeJs
  },
  watch: {
    activeName(val) {
@@ -343,7 +378,9 @@
        serialNumber: '',
        deviceType: 1,
        isSimulate: 0,
      },
      modeUrl: null,
      //mqtt参数查看
      listQuery: {
        clientId: 0,
@@ -389,9 +426,12 @@
        ],
      },
      isMediaDevice: false,
      modelOption: [],
      someData: null, showModelLayer: false,
    };
  },
  created() {
    this.getListSource();
    let activeName = this.$route.query.activeName;
    if (activeName != null && activeName != '') {
      this.activeName = activeName;
@@ -416,6 +456,28 @@
    this.mqttUnSubscribe(this.form);
  },
  methods: {
    // Js
    changeSelect() {
      this.$forceUpdate() // 强制刷新
    },
    getListSource() {
      modelSelectPublishes({
        name: '',
        type: ''
      }).then((response) => {
        if (response.code == 200) {
          if (response.data) {
            this.modelOption = response.data;
          } else {
            this.modelOption = [];
          }
        } else {
          this.$message('模型数据列表获取失败。');
        }
      })
    },
    /* 连接Mqtt消息服务器 */
    async connectMqtt() {
      if (this.$mqttTool.client == null) {
@@ -522,7 +584,7 @@
        // 获取监测统计数据
        if (panel.name === 'deviceStastic' && !this.isSubDev) {
          this.$refs.deviceStatistic.getListHistory();
        } else if (panel.name === 'deviceTimer'&& !this.isSubDev) {
        } else if (panel.name === 'deviceTimer' && !this.isSubDev) {
          this.$refs.deviceTimer.getList();
        }
      });
@@ -545,6 +607,7 @@
    },
    /**获取设备详情*/
    getDevice(deviceId) {
      getDevice(deviceId).then(async (response) => {
        // 分享设备获取用户权限
        response.data.userPerms = [];
@@ -764,34 +827,58 @@
      this.$refs['form'].validate((valid) => {
        if (valid) {
          if (this.form.deviceId != 0) {
            updateDevice(this.form).then((response) => {
              if (response.data == 0) {
                this.$modal.alertError(response.msg);
              } else {
                this.$modal.alertSuccess('修改成功');
                this.form = JSON.parse(JSON.stringify(this.form));
                this.loadMap();
              }
            });
            this.setEditDevice();
          } else {
            addDevice(this.form).then(async (response) => {
              // 获取设备状态
              await this.getDeviceStatusWitchThingsModel(response);
              if (this.form.deviceId == null || this.form.deviceId == 0) {
                this.$modal.alertError('设备编号已经存在,添加设备失败');
              } else {
                if (this.form.status == 2) {
                  this.deviceStatus = 1;
                }
                this.$modal.alertSuccess('添加设备成功');
                this.loadMap();
              }
            });
            this.setAddDevice();
          }
        }
      });
    },
    setAddDevice() {
      const modeUrl = this.modeUrl;
      const modeName = this.form.deviceName;
      addDevice(this.form).then(async (response) => {
        // 获取设备状态
        await this.getDeviceStatusWitchThingsModel(response);
        if (this.form.deviceId == null || this.form.deviceId == 0) {
          this.$modal.alertError('设备编号已经存在,添加设备失败');
        } else {
          if (this.form.status == 2) {
            this.deviceStatus = 1;
          }
          if (modeUrl && response.data.deviceId) {
            this.setAddmodelToDevice(modeName, modeUrl, response.data.deviceId);
          }
          this.$modal.alertSuccess('添加设备成功');
          this.loadMap();
        }
      });
    },
    setEditDevice() {
      updateDevice(this.form).then((response) => {
        if (response.data == 0) {
          this.$modal.alertError(response.msg);
        } else {
          this.$modal.alertSuccess('修改成功');
          this.form = JSON.parse(JSON.stringify(this.form));
          this.loadMap();
        }
      });
    },
    setAddmodelToDevice(modeName, layerId, deviceId) {
      setModelInsertModel({
        "deviceid": deviceId,
        "layerid": layerId,
        "name": modeName
      }).then(response => {
      })
    },
    /** 获取设备状态和物模型 **/
    async getDeviceStatusWitchThingsModel(response) {
      // 获取缓存物模型
@@ -809,6 +896,9 @@
      // 格式化物模型,拆分出监测值,数组添加前缀
      this.formatThingsModel(response.data);
      this.form = response.data;
      // 解析设备摘要
      if (this.form.summary != null && this.form.summary != '') {
        this.summary = JSON.parse(this.form.summary);
@@ -819,6 +909,38 @@
      //Mqtt订阅
      this.connectMqtt();
      this.mqttSubscribe(this.form);
      this.$nextTick(() => {
        this.getModelURL(response.data.deviceId)
      })
    },
    getModelURL(res) {
      setModelSelectModelByPage({
        deviceid: res,
        pageIndex: 1,
        pageSize: 10
      }).then(response => {
        if (response.code != 200 || response.data.length <= 0) return
        const id = response.data[0].layerid;
        this.modeUrl = id
        if (this.modeUrl) {
          const obj = this.modelOption.filter(item => {
            if (item.id == id) {
              return item
            }
          })
          if (obj.length > 0) {
            this.showModelLayer = true;
            this.$nextTick(()=>{
              this.someData = obj[0].url
            })
          }
        }
      })
    },
    /**选择产品 */
    selectProduct() {
@@ -930,3 +1052,26 @@
  },
};
</script>
<style lang="scss" scoped>
.leftCount {
  flex: 1
}
.rightCount {
  width: 30%;
  height: 100%;
  padding-left: 20px;
  .contebtBoder {
    border: 1px solid #dfe4ed;
    border-radius: 5px;
    padding: 5px;
    text-align: center;
    line-height: 400px;
    height: 390px;
    position: relative;
  }
}
</style>