<!-- isc单路 --> <script lang="ts" setup name="ResourceList"> import type { Ref } from 'vue' import { getCurrentInstance, nextTick, reactive, ref } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import dayjs from 'dayjs' import { videoTree } from '@/api/ycjg/aqbb' import { log } from '@/utils/log' import { getPreviewUrl } from '@/utils/hik' const router = useRouter() const treeRef = ref(null) as any const filterText = ref('') const data = ref([]) const defaultProps = ref({ children: 'children', label: 'name', isDisabled: 'disabled', }) const title = ref('') const { proxy } = getCurrentInstance() as any const width = ref(0) const height = ref(0) const loading = ref(false) const src = ref(['', '', '', '']) const player = ref(null) as any const leafLoading = ref(false) const currentLeafId = ref('') const resize = () => { const divPlugin = document.getElementById('home') width.value = divPlugin!.clientWidth - 40 height.value = divPlugin!.clientHeight - 30 if (player.value !== null) { player.value!.JS_Resize() } } let videoClickCount = 0 function createPlayer() { player.value = new window.JSPlugin({ szId: 'player', szBasePath: './', iMaxSplit: 1, iCurrentSplit: 2, openDebug: true, bSupporDoubleClickFull: false, iWidth: width.value, iHeight: height.value, oStyle: { borderSelect: '#FFCC00', }, }) // 事件回调绑定 player.value.JS_SetWindowControlCallback({ windowEventSelect(iWndIndex: any) { // 插件选中窗口回调 console.log('windowSelect callback: ', iWndIndex) const now = new Date().getTime() if (now - videoClickCount < 300) { // 双击事件的判断,300毫秒内重复点击 page(iWndIndex) } videoClickCount = now }, pluginErrorHandler(iWndIndex: any, iErrorCode: any, oError: any) { // 插件错误回调 console.log('pluginError callback: ', iWndIndex, iErrorCode, oError) }, windowEventOver(iWndIndex: any) { // 鼠标移过回调 // console.log(iWndIndex); }, windowEventOut(iWndIndex: any) { // 鼠标移出回调 // console.log(iWndIndex); }, windowEventUp(iWndIndex: any) { // 鼠标mouseup事件回调 // console.log(iWndIndex); }, windowFullCcreenChange(bFull: any) { // 全屏切换回调 console.log('fullScreen callback: ', bFull) }, firstFrameDisplay(iWndIndex: any, iWidth: any, iHeight: any) { // 首帧显示回调 console.log('firstFrame loaded callback: ', iWndIndex, iWidth, iHeight) }, performanceLack() { // 性能不足回调 console.log('performanceLack callback: ') }, }) } function filterNode(value: any, data: { name: string | any[] }) { if (value === '' || value === null) { return true } return data.name.includes(value) } let treeClickCount = 0 let currentIndex = 0 const currentCameras = [{}, {}, {}, {}] as any async function handleNodeClick(data: any, node: any, self: any) { if (data.device.deviceStatusName === '离线') { ElMessage.warning(`设备 ${data.device.monitorName} 离线`) return false } const now = new Date().getTime() if (now - treeClickCount < 300) { // 双击事件的判断,300毫秒内重复点击 console.log('Double click on:', data) if (data.device === '') { // 点击父亲 return } leafLoading.value = true currentLeafId.value = data.device.id getPreviewUrl(data.device.cameraIndexCode).then((res) => { const playUrl = res currentIndex = 0 leafLoading.value = false console.log('获取ISC流playUrl:', playUrl) log('实时监控预览', `${data.name}-${dayjs().format('YYYY-MM-DD HH:mm:ss')}`) player.value!.JS_Play(playUrl, { playURL: playUrl, mode: 0 }, currentIndex).then( () => { console.log('realplay success') }, (e: any) => { ElMessage.warning('预览失败!'); console.error(e) }, ) src.value[currentIndex] = playUrl as string currentCameras[currentIndex] = data title.value = data.device.monitorName.replace('-', ' - ') currentIndex++ }).catch(() => { leafLoading.value = false }) } treeClickCount = now } function page(index: any) { if (src.value[index] !== '') { router.push({ path: '/ssjk/control', query: { id: currentCameras[index].id, }, }) } } const unwatch = watch(filterText, (newVal) => { treeRef.value!.filter(newVal) }) onBeforeUnmount(() => { unwatch() window.removeEventListener('resize', resize) }) function solveData(data: any) { data.forEach((item: any) => { if (item.device) { item.name = `${item.name} (${item.device.deviceStatusName})` console.log('修改后的name', item.name) } if (item.children && item.children.length) { solveData(item.children) } }) return data } onMounted(() => { videoTree().then((response) => { if (response.code === 200) { data.value = response.data } }) setTimeout(() => { window.addEventListener('resize', resize) resize() createPlayer() }, 200) }) </script> <template> <app-container style="height: calc(100vh - 110px)"> <div style="display: flex;height: 100%"> <el-card class="left"> <el-input v-model="filterText" placeholder="设备名称过滤" style="margin-bottom: 10px;" /> <el-tree ref="treeRef" class="filter-tree" style="width: 100%;height: 100%" :data="data" :filter-node-method="filterNode" node-key="id" :default-expand-all="true" :props="defaultProps" @node-click="handleNodeClick" > <template #default="{ node, data }"> <span style="display: flex;align-items: center;"> <el-icon class="loading-rotate" style="margin-right: 5px" v-if="data.device.id === currentLeafId && leafLoading"> <svg-icon name="icon-loading" /> </el-icon> <el-icon v-if="data.device.deviceStatusName === '在线'" style="margin-right: 5px"> <svg-icon name="icon-online" /> </el-icon> <el-icon v-if="data.device.deviceStatusName === '离线'" style="margin-right: 5px"> <svg-icon name="icon-offline" /> </el-icon> <el-tooltip class="box-item" effect="dark" :content="node.label" placement="right" > <template #content> <span>{{ node.label }}</span> <span v-if="data.device.deviceTypeName">({{ data.device.deviceTypeName }})</span> </template> <span v-if="data.device.deviceTypeName" :style="{ 'color': data.device.deviceStatusName === '在线' ? '#0e932e' : '#606266', 'font-weight': data.device.deviceStatusName === '在线' ? 600 : 500 }">{{ node.label }}</span> <span v-else>{{ node.label }}</span> </el-tooltip> <el-icon v-if="data.device.deviceType === '0'" style="margin-left: 5px"> <svg-icon name="icon-qiang" :color="data.device.deviceStatusName === '在线' ? '#0e932e' : '#979797'"/> </el-icon> <el-icon v-if="data.device.deviceType === '1' || data.device.deviceType === '2'" style="margin-left: 5px;"> <svg-icon name="icon-ball" :color="data.device.deviceStatusName === '在线' ? '#0e932e' : '#979797'" /> </el-icon> <el-icon v-if="data.device.deviceType === '3'" style="margin-left: 5px;"> <svg-icon name="icon-ball" :color="data.device.deviceStatusName === '在线' ? '#0e932e' : '#979797'" /> </el-icon> <el-icon v-if="data.device.deviceType === '4'" style="margin-left: 5px;"> <svg-icon name="icon-ytqiang" :color="data.device.deviceStatusName === '在线' ? '#0e932e' : '#979797'" /> </el-icon> </span> </template> </el-tree> </el-card> <div id="home" class="right"> <div id="player" :style="`width:${width}px;height:${height}px;`" style="margin: 30px 0 0 0"/> <div class="title"> {{ title }} </div> </div> </div> </app-container> </template> <style lang="scss" scoped> .title { position: absolute; z-index: 1000; font-size: 16px; letter-spacing: 1px; cursor: pointer; background: linear-gradient(180deg, #71b5ff, #4384ff); color: white; font-weight: bold; line-height: 30px; width: calc(100% - 371px) !important; height: 30px; top: 10px; border-radius: 15px 15px 0 0 ; padding-left: 6px; } .left { width: 300px; height: 100%; padding: 10px; overflow-y: scroll; } .right { flex: 1; margin-left: 10px; // padding-top: 30px; } </style>