Y_ANXI преди 2 години
родител
ревизия
b928341ce2

+ 1 - 1
ruoyi-system/src/main/java/com/ruoyi/system/core/deviceEntity/RollerShutter.java

@@ -39,7 +39,7 @@ public class RollerShutter implements ProductEntity {
             method.invoke(this, defProtocol, clientExecute, device); // 执行该方法
         } catch (NoSuchMethodException e) {
             // 找不到对应方法时,执行commonPut方法
-            commonPut(defProtocol, clientExecute, device);
+            commonInfo(defProtocol, clientExecute, device);
         } catch (IllegalAccessException | InvocationTargetException e) {
             throw new RuntimeException("Failed to invoke the method", e);
         }

+ 44 - 0
ruoyi-vue3/src/api/system/command.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询设备命令列表
+export function listCommand(query) {
+  return request({
+    url: '/system/command/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询设备命令详细
+export function getCommand(commandId) {
+  return request({
+    url: '/system/command/' + commandId,
+    method: 'get'
+  })
+}
+
+// 新增设备命令
+export function addCommand(data) {
+  return request({
+    url: '/system/command',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改设备命令
+export function updateCommand(data) {
+  return request({
+    url: '/system/command',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除设备命令
+export function delCommand(commandId) {
+  return request({
+    url: '/system/command/' + commandId,
+    method: 'delete'
+  })
+}

+ 52 - 0
ruoyi-vue3/src/api/system/device.js

@@ -0,0 +1,52 @@
+import request from '@/utils/request'
+
+// 查询设备列表
+export function listDevice(query) {
+  return request({
+    url: '/system/device/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询设备详细
+export function getDevice(deviceId) {
+  return request({
+    url: '/system/device/' + deviceId,
+    method: 'get'
+  })
+}
+
+// 新增设备
+export function addDevice(data) {
+  return request({
+    url: '/system/device',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改设备
+export function updateDevice(data) {
+  return request({
+    url: '/system/device',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除设备
+export function delDevice(deviceId) {
+  return request({
+    url: '/system/device/' + deviceId,
+    method: 'delete'
+  })
+}
+
+export function getDeviceLogs(params){
+  return request({
+    url: '/system/device/findLogs',
+    method: 'get',
+    params
+  })
+}

+ 270 - 0
ruoyi-vue3/src/views/system/command/index.vue

@@ -0,0 +1,270 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="模式" prop="mode">
+        <el-input v-model="queryParams.mode" placeholder="请输入模式" clearable @keyup.enter="handleQuery" />
+      </el-form-item>
+      <el-form-item label="时长" prop="duration">
+        <el-input v-model="queryParams.duration" placeholder="请输入时长" clearable @keyup.enter="handleQuery" />
+      </el-form-item>
+      <el-form-item label="订阅命令" prop="subscribe">
+        <el-input v-model="queryParams.subscribe" placeholder="请输入订阅命令" clearable @keyup.enter="handleQuery" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:command:add']">新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate"
+          v-hasPermi="['system:command:edit']">修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete"
+          v-hasPermi="['system:command:remove']">删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="warning" plain icon="Download" @click="handleExport"
+          v-hasPermi="['system:command:export']">导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="commandList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="命令" align="center" prop="command" />
+      <el-table-column label="模式" align="center" prop="mode" />
+      <el-table-column label="时长" align="center" prop="duration" />
+      <el-table-column label="订阅命令" align="center" prop="subscribe" />
+      <el-table-column label="设备类型" align="center" prop="deviceType" />
+      <el-table-column label="排序" align="center" prop="sort" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button type="text" icon="Edit" @click="handleUpdate(scope.row)"
+            v-hasPermi="['system:command:edit']">修改</el-button>
+          <el-button type="text" icon="Delete" @click="handleDelete(scope.row)"
+            v-hasPermi="['system:command:remove']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
+      @pagination="getList" />
+
+    <!-- 添加或修改设备命令对话框 -->
+    <el-dialog :title="title" v-model="open" width="1200px" append-to-body>
+      <el-form ref="commandRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="命令实体" prop="command">
+          <el-input v-model="form.command" placeholder="请输入命令实体" />
+        </el-form-item>
+        <el-form-item label="模式" prop="mode">
+          <el-select v-model="form.mode" class="m-2" placeholder="Select">
+            <el-option v-for="item in dicst['command_mode']" :key="item.dictValue" :label="item.dictLabel"
+              :value="item.dictValue" />
+          </el-select>
+          <!-- <el-input v-model="form.mode" placeholder="请输入模式" /> -->
+        </el-form-item>
+        <el-form-item label="设备类型" prop="deviceType">
+
+          <el-select v-model="form.deviceType" class="m-2" placeholder="Select">
+            <el-option v-for="item in dicst['device_type']" :key="item.dictValue" :label="item.dictLabel"
+              :value="item.dictValue" />
+          </el-select>
+
+
+          <!-- <el-input v-model="form.deviceType" placeholder="设备类型" /> -->
+        </el-form-item>
+        <el-form-item label="时长" prop="duration">
+          <el-input v-model="form.duration" placeholder="请输入时长" />
+        </el-form-item>
+        <el-form-item label="订阅命令" prop="subscribe">
+          <el-input v-model="form.subscribe" placeholder="请输入订阅命令" />
+        </el-form-item>
+        <el-form-item label="命令描述" prop="remark">
+          <el-input v-model="form.remark" placeholder="请输入命令描述" />
+          <!-- <editor v-model="form.remark" :min-height="192" /> -->
+        </el-form-item>
+        <el-form-item label="排序" prop="sort">
+          <el-input v-model="form.sort" placeholder="请输入排序" />
+        </el-form-item>
+
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="Command">
+import { listCommand, getCommand, delCommand, addCommand, updateCommand } from "@/api/system/command";
+import { getDicts } from "@/api/system/dict/data";
+
+const { proxy } = getCurrentInstance();
+
+const commandList = ref([]);
+const open = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const title = ref("");
+const dicst = ref({})
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    command: null,
+    mode: null,
+    duration: null,
+    subscribe: null,
+    deviceType: null,
+    sort: null
+  },
+  rules: {
+  }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+/** 查询设备命令列表 */
+function getList() {
+  loading.value = true;
+  listCommand(queryParams.value).then(response => {
+    commandList.value = response.rows;
+    total.value = response.total;
+    loading.value = false;
+  });
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false;
+  reset();
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    commandId: null,
+    command: null,
+    mode: null,
+    duration: null,
+    subscribe: null,
+    remark: null,
+    deviceType: null,
+    sort: null
+  };
+  proxy.resetForm("commandRef");
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+  proxy.resetForm("queryRef");
+  handleQuery();
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.commandId);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+  reset();
+  open.value = true;
+  title.value = "添加设备命令";
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+  reset();
+  const commandId = row.commandId || ids.value
+  getCommand(commandId).then(response => {
+    form.value = response.data;
+    open.value = true;
+    title.value = "修改设备命令";
+  });
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["commandRef"].validate(valid => {
+    if (valid) {
+      if (form.value.commandId != null) {
+        updateCommand(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功");
+          open.value = false;
+          getList();
+        });
+      } else {
+        addCommand(form.value).then(response => {
+          proxy.$modal.msgSuccess("新增成功");
+          open.value = false;
+          getList();
+        });
+      }
+    }
+  });
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+  const commandIds = row.commandId || ids.value;
+  proxy.$modal.confirm('是否确认删除设备命令编号为"' + commandIds + '"的数据项?').then(function () {
+    return delCommand(commandIds);
+  }).then(() => {
+    getList();
+    proxy.$modal.msgSuccess("删除成功");
+  }).catch(() => { });
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('system/command/export', {
+    ...queryParams.value
+  }, `command_${new Date().getTime()}.xlsx`)
+}
+
+const findDists = () => {
+  let dictTypes = ['command_mode', 'device_type']
+  let array = []
+  for (const item of dictTypes) {
+    array.push(getDicts(item))
+  }
+  Promise.all(array).then(res => {
+    for (let i = 0; i < dictTypes.length; i++) {
+      dicst.value[dictTypes[i]] = res[i].data
+    }
+    let booleanDist = [{
+      dictValue: true,
+      dictLabel: '是'
+    }, {
+      dictValue: false,
+      dictLabel: '否'
+    }]
+    dicst.value['booleanDist'] = booleanDist
+  })
+}
+findDists();
+getList();
+</script>

+ 36 - 0
ruoyi-vue3/src/views/system/device/deviceDebugConsole.vue

@@ -0,0 +1,36 @@
+<template>
+    <div class="container">
+        <div class="debugEdit">
+            <VAceEditor class="edit_box" v-model:value="content" v-bind="attr" :lang="lang" theme="tomorrow"
+                :readonly="readonly" ref="aces" :class="{ 'border': hasBorder }" :options="{
+                    fontSize: 14,
+                    tabSize: 2,
+                    showPrintMargin: false,
+                    highlightActiveLine: highlightActiveLine,
+                    showLineNumbers: showLineNumbers,
+                    showGutter: showGutter
+                }" />
+
+            <div class="deviceMsg">
+
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { VAceEditor } from 'vue3-ace-editor';
+
+const content = ref(null)
+
+const jsonDataChange = (value) => {
+    // console.log(content.value)
+}
+
+const editorInit = (value) => {
+    console.log(value)
+}
+
+</script>
+
+<style></style>

+ 74 - 0
ruoyi-vue3/src/views/system/device/deviceLog.vue

@@ -0,0 +1,74 @@
+<template>
+    <div>
+        <el-table :data="tableData" style="width: 100%" :row-class-name="tableRowClassName">
+            <el-table-column prop="ts" label="响应时间">
+            </el-table-column>
+            <el-table-column prop="reportTime" label="上报时间">
+            </el-table-column>
+            <el-table-column prop="logMessage" label="命令">
+            </el-table-column>
+            <el-table-column prop="reply" label="响应">
+            </el-table-column>
+            <el-table-column prop="status" label="状态">
+                <template #default="scope">
+                    {{scope.row.status=='OK'?'成功':'失败'}}
+                </template>
+            </el-table-column>
+        </el-table>
+
+        <el-pagination style="margin-bottom: 20px;margin-top: 20px;" @current-change="paginationChange" background layout="pager" :total="total" />
+    </div>
+</template>
+
+<style>
+.el-table .warning-row {
+    background: red;
+    color: #FFF;
+}
+
+.el-table .success-row {
+    background: #f0f9eb;
+}
+</style>
+
+<script setup>
+import { getDeviceLogs } from '@/api/system/device'
+
+const tableData = ref([])
+const total = ref(0)
+
+const params = ref({
+    pageSize: 10,
+    pageNum: 1
+})
+
+const props = defineProps({
+  deviceNo :String
+});
+
+params.type = props.type
+
+const tableRowClassName = ({
+    row,
+    rowIndex,
+}) => {
+    if (row.status == 'ERROR') {
+        return 'warning-row'
+    }
+    return 'success-row'
+}
+
+const findDeviceLogs = () => {
+    params.value.deviceNo = props.deviceNo
+    getDeviceLogs(params.value).then(res => {
+        tableData.value = res.rows
+        total.value = res.total
+    })
+}
+
+const paginationChange=(current)=>{
+    params.value.pageNum = current
+    findDeviceLogs()
+}
+findDeviceLogs()
+</script>

+ 351 - 0
ruoyi-vue3/src/views/system/device/index.vue

@@ -0,0 +1,351 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="设备名称" prop="deviceName">
+        <el-input v-model="queryParams.deviceName" placeholder="请输入设备名称" clearable @keyup.enter="handleQuery" />
+      </el-form-item>
+      <el-form-item label="设备编号" prop="deviceNo">
+        <el-input v-model="queryParams.deviceNo" placeholder="请输入设备编号" clearable @keyup.enter="handleQuery" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:device:add']">新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate"
+          v-hasPermi="['system:device:edit']">修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete"
+          v-hasPermi="['system:device:remove']">删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="warning" plain icon="Download" @click="handleExport"
+          v-hasPermi="['system:device:export']">导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="deviceList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="设备编号" align="center" prop="deviceNo" />
+      <el-table-column label="设备类型" align="center" prop="deviceType" />
+      <el-table-column label="设备名称" align="center" prop="deviceName" />
+      <el-table-column label="连接类型" align="center" prop="connectionType" />
+      <el-table-column label="设备状态" align="center" prop="status">
+        <template #default="scope">
+          {{ scope.row.status == 'ONLINE' ? '在线' : '离线' }}
+        </template>
+      </el-table-column>
+      <el-table-column label="客户端设备" align="center" prop="client">
+        <template #default="scope">
+          {{ clientFilter(scope.row.client) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="ip" align="center" prop="ip" />
+      <el-table-column label="端口" align="center" prop="port" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button type="text" icon="Edit" @click="handleUpdate(scope.row)"
+            v-hasPermi="['system:device:edit']">修改</el-button>
+          <el-button type="text" icon="Edit" @click="showLogs(scope.row)"
+            v-hasPermi="['system:device:list']">查看日志</el-button>
+          <el-button type="text" icon="Edit" @click="debug(scope.row)"
+            v-hasPermi="['system:device:list']">设备调试</el-button>
+          <el-button type="text" icon="Delete" @click="handleDelete(scope.row)"
+            v-hasPermi="['system:device:remove']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <el-dialog title="设备日志" v-model="showLogDialog" width="1200px">
+
+      <el-tabs v-model="activeName" @tab-click="handleClick">
+        <DeviceLog :deviceNo="currentDeviceNo"></DeviceLog>
+      </el-tabs>
+
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="showLogDialog = false">取 消</el-button>
+        <el-button type="primary" @click="showLogDialog = false">确 定</el-button>
+      </span>
+    </el-dialog>
+
+    <el-dialog title="设备调试" v-model="debugDialog" width="1200px">
+      <DebugConsole :deviceNo="currentDeviceNo"></DebugConsole>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="debugDialog = false">取 消</el-button>
+        <el-button type="primary" @click="debugDialog = false">确 定</el-button>
+      </span>
+    </el-dialog>
+
+
+    <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
+      @pagination="getList" />
+    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
+      <el-form ref="deviceRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="设备编号" prop="deviceNo">
+          <el-input v-model="form.deviceNo" placeholder="请输入设备编号" />
+        </el-form-item>
+        <el-form-item label="设备名称" prop="deviceName">
+          <el-input v-model="form.deviceName" placeholder="请输入设备名称" />
+        </el-form-item>
+        <el-form-item label="客户端" prop="client">
+          <el-select v-model="form.client" class="m-2" placeholder="Select">
+            <el-option v-for="item in dicst['booleanDist']" :key="item.dictValue" :label="item.dictLabel"
+              :value="item.dictValue" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="ip" prop="ip">
+          <el-input v-model="form.ip" placeholder="请输入ip" />
+        </el-form-item>
+        <el-form-item label="端口" prop="port">
+          <el-input v-model="form.port" placeholder="请输入端口" />
+        </el-form-item>
+        <el-form-item label="连接类型" prop="connectionType">
+          <el-select v-model="form.connectionType" class="m-2" placeholder="Select">
+            <el-option v-for="item in dicst['connection_type']" :key="item.dictValue" :label="item.dictLabel"
+              :value="item.dictValue" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="主题" prop="topic" v-if="form.connectionType == 'MQTT'">
+          <el-input v-model="form.topic" placeholder="请输入主题" />
+        </el-form-item>
+        <el-form-item label="心跳指令" prop="heartbeat">
+          <el-input v-model="form.heartbeat" placeholder="请输入主题" />
+        </el-form-item>
+        <el-form-item label="开启心跳" prop="openHeartbeat">
+          <el-select v-model="form.openHeartbeat" class="m-2" placeholder="Select">
+            <el-option v-for="item in dicst['booleanDist']" :key="item.dictValue" :label="item.dictLabel"
+              :value="item.dictValue" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="开启设备" prop="enable">
+          <el-select v-model="form.enable" class="m-2" placeholder="Select">
+            <el-option v-for="item in dicst['booleanDist']" :key="item.dictValue" :label="item.dictLabel"
+              :value="item.dictValue" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="设备类型" prop="deviceType">
+          <el-select v-model="form.deviceType" class="m-2" placeholder="Select">
+            <el-option v-for="item in dicst['device_type']" :key="item.dictValue" :label="item.dictLabel"
+              :value="item.dictValue" />
+          </el-select>
+        </el-form-item>
+
+      </el-form>
+
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+
+  </div>
+</template>
+
+<script setup name="Device">
+import { listDevice, getDevice, delDevice, addDevice, updateDevice } from "@/api/system/device";
+import { getDicts } from "@/api/system/dict/data";
+import DeviceLog from "./deviceLog.vue";
+import DebugConsole from "./deviceDebugConsole.vue";
+
+const { proxy } = getCurrentInstance();
+const showLogDialog = ref(false);
+const deviceList = ref([]);
+const open = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref([]);
+const single = ref(true);
+const multiple = ref(true);
+const debugDialog = ref(false)
+const total = ref(0);
+const title = ref("");
+const dicst = ref({})
+const currentDeviceNo = ref('')
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    deviceName: null,
+    status: null,
+    client: null,
+    ip: null,
+    port: null,
+    connectionType: null,
+    deviceType: null,
+    deviceNo: null
+  },
+  rules: {
+  }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+/** 查询设备列表 */
+function getList() {
+  loading.value = true;
+  listDevice(queryParams.value).then(response => {
+    deviceList.value = response.rows;
+    total.value = response.total;
+    loading.value = false;
+  });
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false;
+  reset();
+}
+
+const clientFilter = (value) => {
+  for (const item of dicst.value['booleanDist']) {
+    if (item.dictValue == value) {
+      return item.dictLabel
+    }
+  }
+}
+
+
+// 表单重置
+function reset() {
+  form.value = {
+    deviceId: null,
+    deviceName: null,
+    status: "0",
+    client: null,
+    ip: null,
+    port: null,
+    connectionType: null,
+    deviceType: null,
+    deviceNo: null,
+    topic: null,
+    heartbeat: null,
+    openHeartbeat: null,
+    enable: null
+  };
+  proxy.resetForm("deviceRef");
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+  proxy.resetForm("queryRef");
+  handleQuery();
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.deviceId);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+  reset();
+  open.value = true;
+  title.value = "添加设备";
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+  reset();
+  const deviceId = row.deviceId || ids.value
+  getDevice(deviceId).then(response => {
+    form.value = response.data;
+    open.value = true;
+    title.value = "修改设备";
+  });
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["deviceRef"].validate(valid => {
+    if (valid) {
+      if (form.value.deviceId != null) {
+        updateDevice(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功");
+          open.value = false;
+          getList();
+        });
+      } else {
+        addDevice(form.value).then(response => {
+          proxy.$modal.msgSuccess("新增成功");
+          open.value = false;
+          getList();
+        });
+      }
+    }
+  });
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+  const deviceIds = row.deviceId || ids.value;
+  proxy.$modal.confirm('是否确认删除设备编号为"' + deviceIds + '"的数据项?').then(function () {
+    return delDevice(deviceIds);
+  }).then(() => {
+    getList();
+    proxy.$modal.msgSuccess("删除成功");
+  }).catch(() => { });
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('system/device/export', {
+    ...queryParams.value
+  }, `device_${new Date().getTime()}.xlsx`)
+}
+
+
+const findDists = () => {
+  let dictTypes = ['connection_type', 'device_type']
+  let array = []
+  for (const item of dictTypes) {
+    array.push(getDicts(item))
+  }
+  Promise.all(array).then(res => {
+    for (let i = 0; i < dictTypes.length; i++) {
+      dicst.value[dictTypes[i]] = res[i].data
+    }
+    dicst.value['booleanDist'] = [{
+      dictValue: true,
+      dictLabel: '是'
+    }, {
+      dictValue: false,
+      dictLabel: '否'
+    }]
+
+    getList();
+
+  })
+}
+
+const showLogs = (row) => {
+  showLogDialog.value = true
+  currentDeviceNo.value = row.deviceNo
+}
+
+const debug =(row)=>{
+  debugDialog.value = true
+  currentDeviceNo.value = row.deviceNo
+}
+
+findDists();
+
+</script>