|
|
@@ -39,25 +39,26 @@
|
|
|
</el-row>
|
|
|
</el-card>
|
|
|
<el-card shadow="hover" :style="{ marginTop: '10px', height: '60px' }">
|
|
|
- <el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
|
|
+ <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="40px">
|
|
|
<el-form-item label="名称" prop="name">
|
|
|
- <el-input v-model="queryParams.name" placeholder="请输入设备名称" clearable @keyup.enter="handleQuery" />
|
|
|
+ <el-input v-model="queryParams.name" style="width: 150px" placeholder="请输入设备名称" clearable @keyup.enter="handleQuery" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="SN" prop="serialNumber">
|
|
|
- <el-input v-model="queryParams.serialNumber" placeholder="请输入设备SN" clearable @keyup.enter="handleQuery" />
|
|
|
+ <el-input v-model="queryParams.serialNumber" style="width: 150px" placeholder="请输入设备SN" clearable @keyup.enter="handleQuery" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="MAC" prop="mac">
|
|
|
- <el-input v-model="queryParams.mac" placeholder="请输入设备MAC" clearable @keyup.enter="handleQuery" />
|
|
|
+ <el-input v-model="queryParams.mac" style="width: 150px" placeholder="请输入设备MAC" 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-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['smsb:device:add']">设备添加 </el-button>
|
|
|
- <el-button type="success" plain icon="VideoPlay" :disabled="single" @click="startMonitor()">回采画面 </el-button>
|
|
|
- <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['smsb:device:remove']"
|
|
|
+ <el-button v-hasPermi="['smsb:device:add']" type="primary" plain icon="Plus" @click="handleAdd">设备添加 </el-button>
|
|
|
+ <el-button type="warning" plain icon="Picture" :disabled="single" @click="screenShot()">回采画面 </el-button>
|
|
|
+ <el-button type="success" plain icon="VideoPlay" :disabled="single" @click="startMonitor()">回调视频 </el-button>
|
|
|
+ <el-button v-hasPermi="['smsb:device:remove']" type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
|
|
|
>删除
|
|
|
</el-button>
|
|
|
- <el-button type="info" plain icon="Position" :disabled="single" @click="handleInfo()" v-hasPermi="['smsb:device:query']">
|
|
|
+ <el-button v-hasPermi="['smsb:device:query']" type="info" plain icon="Position" :disabled="single" @click="handleInfo()">
|
|
|
详情
|
|
|
</el-button>
|
|
|
</el-form-item>
|
|
|
@@ -101,19 +102,19 @@
|
|
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120">
|
|
|
<template #default="scope">
|
|
|
<el-tooltip content="修改" placement="top">
|
|
|
- <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['smsb:device:edit']"></el-button>
|
|
|
+ <el-button v-hasPermi="['smsb:device:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
|
|
|
</el-tooltip>
|
|
|
<el-tooltip content="删除" placement="top">
|
|
|
- <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['smsb:device:remove']"></el-button>
|
|
|
+ <el-button v-hasPermi="['smsb:device:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
|
|
|
</el-tooltip>
|
|
|
</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" />
|
|
|
+ <pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
|
|
</el-card>
|
|
|
<!-- 添加或修改设备对话框 -->
|
|
|
- <el-dialog :title="dialog.title" v-model="dialog.visible" width="850px" append-to-body>
|
|
|
+ <el-dialog v-model="dialog.visible" :title="dialog.title" width="850px" append-to-body>
|
|
|
<el-form ref="deviceFormRef" :model="form" :rules="rules" label-width="78px">
|
|
|
<el-row>
|
|
|
<el-col :span="12">
|
|
|
@@ -189,7 +190,7 @@
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
<!--设备详情弹窗-->
|
|
|
- <el-dialog :title="viewDialog.title" v-model="viewDialog.visible" width="1000px" append-to-body>
|
|
|
+ <el-dialog v-model="viewDialog.visible" :title="viewDialog.title" width="1000px" append-to-body>
|
|
|
<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClickTab">
|
|
|
<el-tab-pane label="状态检测" name="info">
|
|
|
<div>
|
|
|
@@ -217,7 +218,7 @@
|
|
|
</el-tab-pane>
|
|
|
<el-tab-pane label="报警信息" name="alarm">
|
|
|
<el-table v-loading="loading" :data="alarmList" row-key="id">
|
|
|
- <el-table-column label="主键ID" align="left" prop="id" v-if="true" />
|
|
|
+ <el-table-column v-if="true" label="主键ID" align="left" prop="id" />
|
|
|
<el-table-column label="设备名称" align="left" prop="deviceName" :show-overflow-tooltip="true" />
|
|
|
<el-table-column label="告警等级" align="center" prop="errorLevel" width="100">
|
|
|
<template #default="scope">
|
|
|
@@ -233,9 +234,9 @@
|
|
|
</el-table>
|
|
|
<pagination
|
|
|
v-show="alarmTotal > 0"
|
|
|
- :total="alarmTotal"
|
|
|
v-model:page="dialogQueryParams.pageNum"
|
|
|
v-model:limit="dialogQueryParams.pageSize"
|
|
|
+ :total="alarmTotal"
|
|
|
@pagination="getAlarmList"
|
|
|
/>
|
|
|
</el-tab-pane>
|
|
|
@@ -246,7 +247,7 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
- <el-dialog :title="watchDialog.title" v-model="watchDialog.visible" width="900px" append-to-body @closed="onDialogClosed">
|
|
|
+ <el-dialog v-model="watchDialog.visible" :title="watchDialog.title" width="900px" append-to-body @closed="onDialogClosed">
|
|
|
<div v-if="watchDialog.visible" style="width: 100%; height: 500px">
|
|
|
<video ref="flvPlayerRef" style="width: 100%; height: 100%" controls></video>
|
|
|
</div>
|
|
|
@@ -256,6 +257,12 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
+ <el-dialog v-model="shotDialog.visible" :title="shotDialog.title" width="900px" append-to-body @closed="onDialogClosed">
|
|
|
+ <div style="text-align: center">
|
|
|
+ <!-- <image-preview :src="screenshotImageUrl" style="width: 40px; height: 40px; cursor: pointer" />-->
|
|
|
+ <el-image v-loading="screenshotLoading" :src="screenshotImageUrl" style="width: 600px; height: 600px" />
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
@@ -273,7 +280,8 @@ import {
|
|
|
startStream,
|
|
|
deviceStatistics,
|
|
|
getDeviceRunInfo,
|
|
|
- stopStream
|
|
|
+ stopStream,
|
|
|
+ getDeviceScreenshot
|
|
|
} from '@/api/smsb/device/device';
|
|
|
import { DeviceVO, DeviceQuery, DeviceForm, DeviceStatisticsVo } from '@/api/smsb/device/device_type';
|
|
|
import { ProductVO } from '@/api/smsb/device/product_types';
|
|
|
@@ -286,7 +294,11 @@ import flvjs from 'flv.js';
|
|
|
import { DeviceRunInfoVO } from '@/api/smsb/device/device_run_type';
|
|
|
import { DeviceErrorRecordQuery, DeviceErrorRecordVO } from '@/api/smsb/device/errorRecord_type';
|
|
|
import { listDeviceErrorRecord } from '@/api/smsb/device/errorRecord';
|
|
|
+import { storeToRefs } from 'pinia';
|
|
|
+import useScreenshotStore from '@/store/modules/screenshot';
|
|
|
|
|
|
+const screenshotStore = storeToRefs(useScreenshotStore());
|
|
|
+const screenshotImageUrl = ref<string>();
|
|
|
const alarmList = ref<DeviceErrorRecordVO[]>([]);
|
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
const { sys_device_online, smsb_yes_no, smsb_device_error_level, smsb_device_error_type } = toRefs<any>(
|
|
|
@@ -298,6 +310,7 @@ const productList = ref<ProductVO[]>([]);
|
|
|
const manufacturerList = ref<DeviceManufacturerVO[]>([]);
|
|
|
const buttonLoading = ref(false);
|
|
|
const loading = ref(true);
|
|
|
+const screenshotLoading = ref(true);
|
|
|
const showSearch = ref(true);
|
|
|
const ids = ref<Array<string | number>>([]);
|
|
|
const single = ref(true);
|
|
|
@@ -342,6 +355,10 @@ const watchDialog = reactive<DialogOption>({
|
|
|
visible: false,
|
|
|
title: ''
|
|
|
});
|
|
|
+const shotDialog = reactive<DialogOption>({
|
|
|
+ visible: false,
|
|
|
+ title: ''
|
|
|
+});
|
|
|
const activeName = ref('info');
|
|
|
|
|
|
const initFormData: DeviceForm = {
|
|
|
@@ -456,8 +473,8 @@ const cancel = () => {
|
|
|
viewDialog.visible = false;
|
|
|
watchDialog.visible = false;
|
|
|
// 关闭播放器
|
|
|
- if (flvPlayer) {
|
|
|
- flvPlayer.destroy();
|
|
|
+ if (flvPlayer.value) {
|
|
|
+ flvPlayer.value.destroy();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
@@ -577,6 +594,32 @@ const handleControl = async (type: string) => {
|
|
|
proxy?.$modal.msgSuccess(resMsg);
|
|
|
}
|
|
|
};
|
|
|
+let intervalId = null;
|
|
|
+const screenShot = async (row?: DeviceVO) => {
|
|
|
+ const deviceId = row?.id || ids.value[0];
|
|
|
+ shotDialog.title = '回传画面';
|
|
|
+ shotDialog.visible = true;
|
|
|
+ const res = await getDeviceScreenshot(deviceId);
|
|
|
+
|
|
|
+ intervalId = setInterval(getScreenshot, 1000);
|
|
|
+};
|
|
|
+const getScreenshot = async () => {
|
|
|
+ screenshotImageUrl.value = screenshotStore.state.value.imageUrl;
|
|
|
+ console.log('device.vue screenshotImageUrl.value = ' + screenshotImageUrl.value);
|
|
|
+ if (screenshotImageUrl.value !== null) {
|
|
|
+ clearInterval(intervalId);
|
|
|
+ screenshotLoading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+// 对话框关闭时清理
|
|
|
+const onDialogClosed = () => {
|
|
|
+ destroyPlayer();
|
|
|
+ screenshotImageUrl.value = null;
|
|
|
+ screenshotStore.state.value.imageUrl = null;
|
|
|
+ screenshotLoading.value = true;
|
|
|
+ // 清除定时器
|
|
|
+ clearInterval(intervalId);
|
|
|
+};
|
|
|
|
|
|
const startMonitor = async (row?: DeviceVO) => {
|
|
|
try {
|
|
|
@@ -625,10 +668,7 @@ const destroyPlayer = () => {
|
|
|
flvPlayer.value = null;
|
|
|
}
|
|
|
};
|
|
|
-// 对话框关闭时清理
|
|
|
-const onDialogClosed = () => {
|
|
|
- destroyPlayer();
|
|
|
-};
|
|
|
+
|
|
|
const stopMonitor = async () => {
|
|
|
const res = await stopStream(streamDeviceId.value);
|
|
|
watchDialog.visible = false;
|