|
@@ -16,6 +16,12 @@
|
|
|
v-model="searchKey"
|
|
|
style="margin-bottom: 8px; max-width: 100%"
|
|
|
/>
|
|
|
+ <a-alert
|
|
|
+ v-if="originTreeData.some((v) => v.disabled)"
|
|
|
+ type="warning"
|
|
|
+ closable
|
|
|
+ >{{ $t('previewList.tip3') }}</a-alert
|
|
|
+ >
|
|
|
<a-spin v-if="loading" />
|
|
|
<a-tree v-else block-node :data="treeData" @select="onSelect">
|
|
|
<template #icon>
|
|
@@ -129,33 +135,33 @@
|
|
|
class="video-box-tip"
|
|
|
><span>{{ t('previewList.wxh') }}</span></div
|
|
|
>
|
|
|
- <div class="video-tools">
|
|
|
- <!-- 截图 -->
|
|
|
- <a-tooltip :content="$t('previewList.jt')">
|
|
|
- <a-button
|
|
|
- v-if="activeObj[i].isCloseBtn"
|
|
|
- type="text"
|
|
|
- size="mini"
|
|
|
- >
|
|
|
- <template #icon>
|
|
|
- <Icon
|
|
|
- icon="ri:screenshot-2-line"
|
|
|
- width="24"
|
|
|
- height="24"
|
|
|
- />
|
|
|
- </template>
|
|
|
- </a-button>
|
|
|
- </a-tooltip>
|
|
|
- <!-- 录像 -->
|
|
|
- <a-tooltip :content="$t('previewList.lx')">
|
|
|
+ <canvas
|
|
|
+ v-if="activeObj[i].isReset"
|
|
|
+ :id="'video-canvas-' + i"
|
|
|
+ :style="{
|
|
|
+ transform: `rotateZ(${rotateZ}deg)`,
|
|
|
+ }"
|
|
|
+ ></canvas>
|
|
|
+ <div
|
|
|
+ v-if="activeObj[i].isShowTools"
|
|
|
+ class="video-tools"
|
|
|
+ >
|
|
|
+ <!-- 截图 录像 -->
|
|
|
+ <a-tooltip
|
|
|
+ v-for="tool in activeObj[i].tools"
|
|
|
+ :key="tool.type"
|
|
|
+ :content="tool.title"
|
|
|
+ >
|
|
|
<a-button
|
|
|
- v-if="activeObj[i].isCloseBtn"
|
|
|
type="text"
|
|
|
size="mini"
|
|
|
+ @click="toolsClick(tool, activeObj[i])"
|
|
|
>
|
|
|
<template #icon>
|
|
|
<Icon
|
|
|
- icon="bx:video-recording"
|
|
|
+ :icon="tool.icon"
|
|
|
+ :color="tool.color"
|
|
|
+ :class="[tool.iconClass]"
|
|
|
width="24"
|
|
|
height="24"
|
|
|
/>
|
|
@@ -165,7 +171,6 @@
|
|
|
<!-- 关闭 -->
|
|
|
<a-tooltip :content="$t('previewList.close')">
|
|
|
<a-button
|
|
|
- v-if="activeObj[i].isCloseBtn"
|
|
|
type="text"
|
|
|
size="mini"
|
|
|
@click="handleClose(i)"
|
|
@@ -180,15 +185,6 @@
|
|
|
</a-button>
|
|
|
</a-tooltip>
|
|
|
</div>
|
|
|
-
|
|
|
- <canvas
|
|
|
- v-if="activeObj[i].isReset"
|
|
|
- :id="'video-canvas-' + i"
|
|
|
- :style="{
|
|
|
- width: '100%',
|
|
|
- transform: `rotateZ(${rotateZ}deg)`,
|
|
|
- }"
|
|
|
- ></canvas>
|
|
|
</div>
|
|
|
</a-grid-item>
|
|
|
</a-grid>
|
|
@@ -221,33 +217,30 @@
|
|
|
class="video-box-tip"
|
|
|
><span>{{ t('previewList.wxh') }}</span></div
|
|
|
>
|
|
|
- <div class="video-tools">
|
|
|
- <!-- 截图 -->
|
|
|
- <a-tooltip :content="$t('previewList.jt')">
|
|
|
- <a-button
|
|
|
- v-if="activeObj[i].isCloseBtn"
|
|
|
- type="text"
|
|
|
- size="mini"
|
|
|
- >
|
|
|
- <template #icon>
|
|
|
- <Icon
|
|
|
- icon="ri:screenshot-2-line"
|
|
|
- width="24"
|
|
|
- height="24"
|
|
|
- />
|
|
|
- </template>
|
|
|
- </a-button>
|
|
|
- </a-tooltip>
|
|
|
- <!-- 录像 -->
|
|
|
- <a-tooltip :content="$t('previewList.lx')">
|
|
|
+ <canvas
|
|
|
+ v-if="activeObj[i].isReset"
|
|
|
+ :id="'video-canvas-' + i"
|
|
|
+ ></canvas>
|
|
|
+ <div
|
|
|
+ v-if="activeObj[i].isShowTools"
|
|
|
+ class="video-tools"
|
|
|
+ >
|
|
|
+ <!-- 截图 录像 -->
|
|
|
+ <a-tooltip
|
|
|
+ v-for="tool in activeObj[i].tools"
|
|
|
+ :key="tool.type"
|
|
|
+ :content="tool.title"
|
|
|
+ >
|
|
|
<a-button
|
|
|
- v-if="activeObj[i].isCloseBtn"
|
|
|
type="text"
|
|
|
size="mini"
|
|
|
+ @click="toolsClick(tool, activeObj[i])"
|
|
|
>
|
|
|
<template #icon>
|
|
|
<Icon
|
|
|
- icon="bx:video-recording"
|
|
|
+ :icon="tool.icon"
|
|
|
+ :color="tool.color"
|
|
|
+ :class="[tool.iconClass]"
|
|
|
width="24"
|
|
|
height="24"
|
|
|
/>
|
|
@@ -257,7 +250,6 @@
|
|
|
<!-- 关闭 -->
|
|
|
<a-tooltip :content="$t('previewList.close')">
|
|
|
<a-button
|
|
|
- v-if="activeObj[i].isCloseBtn"
|
|
|
type="text"
|
|
|
size="mini"
|
|
|
@click="handleClose(i)"
|
|
@@ -272,12 +264,6 @@
|
|
|
</a-button>
|
|
|
</a-tooltip>
|
|
|
</div>
|
|
|
-
|
|
|
- <canvas
|
|
|
- v-if="activeObj[i].isReset"
|
|
|
- :id="'video-canvas-' + i"
|
|
|
- style="width: 100%"
|
|
|
- ></canvas>
|
|
|
</div>
|
|
|
</a-grid-item>
|
|
|
</a-grid>
|
|
@@ -289,15 +275,23 @@
|
|
|
:scroll="{ y: 100 }"
|
|
|
:pagination="false"
|
|
|
:bordered="{ cell: true }"
|
|
|
+ :loading="alarmLoading"
|
|
|
size="small"
|
|
|
style="height: 100%"
|
|
|
>
|
|
|
<template #columns>
|
|
|
<a-table-column
|
|
|
:title="t('previewList.bjlx')"
|
|
|
+ :ellipsis="true"
|
|
|
+ :tooltip="true"
|
|
|
data-index="type"
|
|
|
>
|
|
|
</a-table-column>
|
|
|
+ <a-table-column
|
|
|
+ :title="t('previewList.bjsj')"
|
|
|
+ data-index="timeN"
|
|
|
+ :width="180"
|
|
|
+ ></a-table-column>
|
|
|
<a-table-column
|
|
|
:title="t('previewList.status')"
|
|
|
data-index="status"
|
|
@@ -343,10 +337,14 @@
|
|
|
type="text"
|
|
|
size="mini"
|
|
|
@click="
|
|
|
- $modal.info({
|
|
|
- title: '提示',
|
|
|
- content: record.type,
|
|
|
- })
|
|
|
+ () => (
|
|
|
+ (record.isRead = true),
|
|
|
+ $modal.info({
|
|
|
+ title: '提示',
|
|
|
+ draggable: true,
|
|
|
+ content: record.type,
|
|
|
+ })
|
|
|
+ )
|
|
|
"
|
|
|
>{{ t('previewList.ck') }}</a-button
|
|
|
>
|
|
@@ -412,7 +410,6 @@
|
|
|
computed,
|
|
|
watch,
|
|
|
nextTick,
|
|
|
- reactive,
|
|
|
defineAsyncComponent,
|
|
|
onUnmounted,
|
|
|
} from 'vue';
|
|
@@ -421,6 +418,7 @@
|
|
|
import { getCropFullInfo } from '@/api/system';
|
|
|
import { Message } from '@arco-design/web-vue';
|
|
|
import { useDebounceFn } from '@vueuse/core';
|
|
|
+ import dayjs from 'dayjs';
|
|
|
|
|
|
const resizeArr: any[] = [];
|
|
|
const { loading, setLoading } = useLoading(true);
|
|
@@ -464,6 +462,42 @@
|
|
|
}[]
|
|
|
>([]);
|
|
|
|
|
|
+ // const tools = ref([
|
|
|
+ // {
|
|
|
+ // icon: 'ri:screenshot-2-line',
|
|
|
+ // title: t('previewList.jt'),
|
|
|
+ // type: 'jt',
|
|
|
+ // color: '#8ac5ff',
|
|
|
+ // iconClass: '',
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // icon: 'bx:video-recording',
|
|
|
+ // title: t('previewList.lx'),
|
|
|
+ // type: 'lx',
|
|
|
+ // color: '#8ac5ff',
|
|
|
+ // iconClass: '',
|
|
|
+ // },
|
|
|
+ // ]);
|
|
|
+ const state = ref(false);
|
|
|
+ const toolsClick = (tool: any, ao: any) => {
|
|
|
+ switch (tool.type) {
|
|
|
+ case 'lx':
|
|
|
+ state.value = !state.value;
|
|
|
+ tool.icon = state.value ? 'fad:armrecording' : 'bx:video-recording';
|
|
|
+ tool.color = state.value ? 'red' : '#8ac5ff';
|
|
|
+ tool.iconClass = state.value ? '.fade-open' : '';
|
|
|
+ ao.workerObj.WebSocketWork.postMessage({
|
|
|
+ type: 'lx',
|
|
|
+ lx: state.value,
|
|
|
+ });
|
|
|
+ break;
|
|
|
+ case 'jt':
|
|
|
+ ao.workerObj.worker.postMessage({ type: 'jt' });
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ };
|
|
|
const gridCount = computed<number>(() => {
|
|
|
let result = 4;
|
|
|
switch (radioActive.value) {
|
|
@@ -533,42 +567,13 @@
|
|
|
width: 150,
|
|
|
},
|
|
|
];
|
|
|
- const alarmData = reactive([
|
|
|
- {
|
|
|
- type: '行人闯入',
|
|
|
- status: 0,
|
|
|
- isRead: false,
|
|
|
- },
|
|
|
- {
|
|
|
- type: '行人闯入',
|
|
|
- status: 0,
|
|
|
- isRead: false,
|
|
|
- },
|
|
|
- {
|
|
|
- type: '行人闯入',
|
|
|
- status: 0,
|
|
|
- isRead: true,
|
|
|
- },
|
|
|
- {
|
|
|
- type: '行人闯入',
|
|
|
- status: 0,
|
|
|
- isRead: false,
|
|
|
- },
|
|
|
- {
|
|
|
- type: '行人闯入',
|
|
|
- status: 0,
|
|
|
- isRead: false,
|
|
|
- },
|
|
|
- {
|
|
|
- type: '行人闯入',
|
|
|
- status: 0,
|
|
|
- isRead: false,
|
|
|
- },
|
|
|
- {
|
|
|
- type: '行人闯入',
|
|
|
- status: 1,
|
|
|
- isRead: true,
|
|
|
- },
|
|
|
+ const alarmLoading = ref(false);
|
|
|
+ const alarmData = ref<{ [key: string]: number | string | boolean }[]>([
|
|
|
+ // {
|
|
|
+ // type: '行人闯入',
|
|
|
+ // status: 0,
|
|
|
+ // isRead: false,
|
|
|
+ // },
|
|
|
]);
|
|
|
|
|
|
const searchKey = ref<string>('');
|
|
@@ -607,6 +612,7 @@
|
|
|
title: item.alias,
|
|
|
port: item.port,
|
|
|
status: item.status,
|
|
|
+ disabled: !item.id,
|
|
|
}));
|
|
|
} catch (err) {
|
|
|
// you can report use errorHandler or other
|
|
@@ -690,13 +696,10 @@
|
|
|
`#video-canvas-${screenActive.value}`
|
|
|
);
|
|
|
resizeArr.push(vc);
|
|
|
- if (vc.offsetWidth > vc.parentNode.offsetWidth) {
|
|
|
- vc.style.width = '100%';
|
|
|
- vc.style.height = 'auto';
|
|
|
- } else {
|
|
|
- vc.style.height = '100%';
|
|
|
- vc.style.width = 'auto';
|
|
|
- }
|
|
|
+ vc.style.height = `${vc.parentNode.offsetHeight}px`;
|
|
|
+ vc.style.width = 'auto';
|
|
|
+ // eslint-disable-next-line no-use-before-define
|
|
|
+ resize();
|
|
|
}, 50);
|
|
|
}
|
|
|
);
|
|
@@ -710,10 +713,10 @@
|
|
|
};
|
|
|
|
|
|
const handleMouseEnter = (v: number) => {
|
|
|
- activeObj.value[v].isCloseBtn = true;
|
|
|
+ activeObj.value[v].isShowTools = true;
|
|
|
};
|
|
|
const handleMouseLeave = (v: number) => {
|
|
|
- activeObj.value[v].isCloseBtn = false;
|
|
|
+ activeObj.value[v].isShowTools = false;
|
|
|
};
|
|
|
|
|
|
const handleRadioChange = (
|
|
@@ -762,6 +765,46 @@
|
|
|
// toggle();
|
|
|
};
|
|
|
|
|
|
+ let eventSource: EventSource;
|
|
|
+ const alarmSSE = () => {
|
|
|
+ alarmLoading.value = true;
|
|
|
+ eventSource = new EventSource(`${app.ip}/rpc/AiSSE?Topic=All`);
|
|
|
+ eventSource.addEventListener(
|
|
|
+ 'open',
|
|
|
+ () => {
|
|
|
+ alarmData.value = [];
|
|
|
+ alarmLoading.value = false;
|
|
|
+ },
|
|
|
+ false
|
|
|
+ );
|
|
|
+ eventSource.addEventListener(
|
|
|
+ 'message',
|
|
|
+ (e) => {
|
|
|
+ const data = JSON.parse(e.data);
|
|
|
+ alarmData.value.unshift({
|
|
|
+ type: data.AlgorithmName,
|
|
|
+ status: 0,
|
|
|
+ isRead: false,
|
|
|
+ timeN: dayjs(+`${data.time}`.padEnd(13, '0')).format(
|
|
|
+ 'YYYY-MM-DD HH:mm:ss'
|
|
|
+ ),
|
|
|
+ ...data,
|
|
|
+ });
|
|
|
+ },
|
|
|
+ false
|
|
|
+ );
|
|
|
+ eventSource.addEventListener(
|
|
|
+ 'error',
|
|
|
+ () => {
|
|
|
+ Message.warning({
|
|
|
+ content: t('previewList.tip2'),
|
|
|
+ duration: 5 * 1000,
|
|
|
+ });
|
|
|
+ },
|
|
|
+ false
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
watch(
|
|
|
radioActive,
|
|
|
(newV) => {
|
|
@@ -773,8 +816,24 @@
|
|
|
loading: false,
|
|
|
isSignal: false,
|
|
|
workerObj: null,
|
|
|
- isCloseBtn: false,
|
|
|
- isReset: false,
|
|
|
+ isShowTools: false,
|
|
|
+ isReset: true,
|
|
|
+ tools: ref([
|
|
|
+ {
|
|
|
+ icon: 'ri:screenshot-2-line',
|
|
|
+ title: t('previewList.jt'),
|
|
|
+ type: 'jt',
|
|
|
+ color: '#8ac5ff',
|
|
|
+ iconClass: '',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ icon: 'bx:video-recording',
|
|
|
+ title: t('previewList.lx'),
|
|
|
+ type: 'lx',
|
|
|
+ color: '#8ac5ff',
|
|
|
+ iconClass: '',
|
|
|
+ },
|
|
|
+ ]),
|
|
|
});
|
|
|
}
|
|
|
},
|
|
@@ -783,15 +842,34 @@
|
|
|
|
|
|
const resize = useDebounceFn(() => {
|
|
|
resizeArr.forEach((vc) => {
|
|
|
- if (vc.offsetWidth > vc.parentNode.offsetWidth) {
|
|
|
- vc.style.width = '100%';
|
|
|
- vc.style.height = 'auto';
|
|
|
- } else {
|
|
|
+ const splitScreenBox = document.querySelector('.split-screen-box');
|
|
|
+ if (
|
|
|
+ splitScreenBox &&
|
|
|
+ vc.offsetHeight + 2 >= (splitScreenBox as HTMLElement).offsetHeight + 2
|
|
|
+ ) {
|
|
|
vc.style.height = '100%';
|
|
|
vc.style.width = 'auto';
|
|
|
+ } else {
|
|
|
+ vc.style.width = '100%';
|
|
|
+ vc.style.height = 'auto';
|
|
|
}
|
|
|
});
|
|
|
- }, 200);
|
|
|
+ }, 100);
|
|
|
+ // onMounted
|
|
|
+ watch(
|
|
|
+ comName,
|
|
|
+ (newV) => {
|
|
|
+ if (newV === 'index') {
|
|
|
+ alarmSSE();
|
|
|
+ } else {
|
|
|
+ eventSource.close();
|
|
|
+ // for (let i = 0; i < radioActive.value; i + 1) {
|
|
|
+ handleClose(screenActive.value);
|
|
|
+ // }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ { immediate: true }
|
|
|
+ );
|
|
|
window.addEventListener('resize', resize);
|
|
|
onUnmounted(() => {
|
|
|
window.removeEventListener('resize', resize);
|
|
@@ -822,7 +900,7 @@
|
|
|
height: 100%;
|
|
|
position: relative;
|
|
|
.screen-active {
|
|
|
- border: 2px solid red;
|
|
|
+ border: 1px solid red;
|
|
|
}
|
|
|
.arco-divider {
|
|
|
position: absolute;
|
|
@@ -837,7 +915,14 @@
|
|
|
flex-flow: column;
|
|
|
gap: 15px;
|
|
|
.alarm-box {
|
|
|
+ flex: 1;
|
|
|
min-height: 100px;
|
|
|
+ max-height: 100px;
|
|
|
+ :deep(.arco-table) {
|
|
|
+ .arco-table-scroll-y > .arco-scrollbar {
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
.split-screen-box {
|
|
@@ -867,6 +952,7 @@
|
|
|
justify-content: center;
|
|
|
align-items: center;
|
|
|
background-color: #000;
|
|
|
+ overflow: hidden;
|
|
|
.arco-spin {
|
|
|
position: absolute;
|
|
|
}
|