2025-10-20 13:41:00 +08:00
|
|
|
|
<template>
|
2025-10-21 16:01:33 +08:00
|
|
|
|
<div class="default-main" :style="{ padding: prop.height ? '0px !important' : '10px' }">
|
2025-10-21 14:56:27 +08:00
|
|
|
|
<!-- 实时数据 -->
|
2025-12-10 10:30:32 +08:00
|
|
|
|
<!-- 实时数据 走驾驶舱-->
|
2025-10-21 14:56:27 +08:00
|
|
|
|
<!-- 添加加载事件监听 -->
|
2025-12-10 10:30:32 +08:00
|
|
|
|
<div class="dataBox" :style="{ height: prop.height ? prop.height : pageHeight.height }">
|
2026-06-08 18:34:49 +08:00
|
|
|
|
<div class="iframe-container" :style="{
|
|
|
|
|
|
boxShadow: `var(--el-box-shadow-light)`
|
|
|
|
|
|
}" style="position: relative">
|
|
|
|
|
|
<iframe v-if="bindId" :key="bindId" :src="iframeSrc" width="100%" height="100%" frameborder="0"
|
|
|
|
|
|
scrolling="no" id="iframeLeft" @load="onIframeLoad"></iframe>
|
2026-01-04 14:55:31 +08:00
|
|
|
|
<el-empty v-else description="暂无绑定页面" style="height: 100%" />
|
2025-10-21 14:56:27 +08:00
|
|
|
|
</div>
|
2025-12-20 23:44:46 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="bottom-container">
|
2026-06-08 18:34:49 +08:00
|
|
|
|
<el-button type="primary" :icon="show ? 'el-icon-ArrowDownBold' : 'el-icon-ArrowUpBold'"
|
|
|
|
|
|
@click="show = !show" style="width: 100%" v-if="bindId">
|
2025-12-20 23:44:46 +08:00
|
|
|
|
事件列表
|
|
|
|
|
|
</el-button>
|
2026-06-08 18:34:49 +08:00
|
|
|
|
<!-- <el-button class="bindBut" type="primary" icon="el-icon-Sort" @click="bindClick">绑定</el-button> -->
|
|
|
|
|
|
|
|
|
|
|
|
<el-icon class="bindBut">
|
|
|
|
|
|
<Sort style="width: 30px;height: 30px;" color="#fff" @click="bindClick" />
|
|
|
|
|
|
</el-icon>
|
2025-12-20 23:44:46 +08:00
|
|
|
|
<!-- <div class="buttonBox">
|
2025-11-25 15:39:17 +08:00
|
|
|
|
<el-button type="primary" icon="el-icon-Aim" @click="reset">复位</el-button>
|
2025-12-09 11:36:52 +08:00
|
|
|
|
</div> -->
|
2026-01-04 14:55:31 +08:00
|
|
|
|
|
2025-12-20 23:44:46 +08:00
|
|
|
|
<transition name="table-fade">
|
|
|
|
|
|
<div class="tableBox" v-if="show">
|
|
|
|
|
|
<vxe-table border auto-resize height="230px" :data="tableData" ref="tableRef">
|
2025-12-04 16:29:46 +08:00
|
|
|
|
<vxe-column type="seq" title="序号" align="center" width="80px"></vxe-column>
|
2026-06-11 20:27:37 +08:00
|
|
|
|
<vxe-column field="date" align="center" sortable title="发生时间" width="200px"></vxe-column>
|
|
|
|
|
|
<vxe-column field="name" align="center" title="监测点名称" width="200px"></vxe-column>
|
2025-12-04 16:29:46 +08:00
|
|
|
|
<vxe-column field="address" align="center" title="事件描述"></vxe-column>
|
|
|
|
|
|
</vxe-table>
|
2025-10-21 16:01:33 +08:00
|
|
|
|
</div>
|
2025-12-20 23:44:46 +08:00
|
|
|
|
</transition>
|
2025-10-21 14:56:27 +08:00
|
|
|
|
</div>
|
2026-01-04 14:55:31 +08:00
|
|
|
|
<!--绑定实时数据 -->
|
|
|
|
|
|
<Bind ref="bindRef" @bindClick="info" />
|
2025-10-21 14:56:27 +08:00
|
|
|
|
</div>
|
2025-10-20 13:41:00 +08:00
|
|
|
|
</template>
|
2025-10-21 10:21:15 +08:00
|
|
|
|
<script setup lang="ts">
|
2025-10-21 14:56:27 +08:00
|
|
|
|
import { ref, watch, onMounted, onUnmounted, provide } from 'vue'
|
|
|
|
|
|
import Table from '@/components/table/index.vue'
|
|
|
|
|
|
import TableStore from '@/utils/tableStore'
|
|
|
|
|
|
import { mainHeight } from '@/utils/layout'
|
2026-06-08 18:34:49 +08:00
|
|
|
|
import { Sort } from '@element-plus/icons-vue'
|
2026-01-04 14:55:31 +08:00
|
|
|
|
import { useAdminInfo } from '@/stores/adminInfo'
|
|
|
|
|
|
import { audit, add, coFqueryPage, getByUserId } from '@/api/cs-harmonic-boot/mxgraph'
|
|
|
|
|
|
import Bind from './bind.vue'
|
2025-10-21 14:56:27 +08:00
|
|
|
|
// import { getActive } from "@/api/manage_wx/index";
|
|
|
|
|
|
|
|
|
|
|
|
// const props = defineProps<{
|
|
|
|
|
|
// project: { id: string; name: string } | null
|
|
|
|
|
|
// }>()
|
2026-01-04 14:55:31 +08:00
|
|
|
|
const adminInfo = useAdminInfo()
|
2025-12-20 23:44:46 +08:00
|
|
|
|
const show = ref(false)
|
2025-10-21 14:56:27 +08:00
|
|
|
|
const prop = defineProps({
|
2025-12-04 16:29:46 +08:00
|
|
|
|
width: { type: [String, Number] },
|
|
|
|
|
|
height: { type: [String, Number] },
|
2025-12-10 10:30:32 +08:00
|
|
|
|
timeKey: { type: Array as () => string[] },
|
2025-10-21 14:56:27 +08:00
|
|
|
|
timeValue: { type: Object }
|
|
|
|
|
|
})
|
2026-01-04 14:55:31 +08:00
|
|
|
|
const bindRef = ref()
|
|
|
|
|
|
const tableData = ref([])
|
|
|
|
|
|
const bindId = ref('')
|
2025-10-21 14:56:27 +08:00
|
|
|
|
|
2025-12-04 16:29:46 +08:00
|
|
|
|
// 在父页面中添加事件监听器
|
|
|
|
|
|
window.addEventListener('message', function (event) {
|
|
|
|
|
|
const { action, data } = event.data
|
2025-10-21 14:56:27 +08:00
|
|
|
|
|
2025-12-04 16:29:46 +08:00
|
|
|
|
if (action == 'securityDetailData') {
|
|
|
|
|
|
// 处理接收到的 tableArray 数据
|
|
|
|
|
|
tableData.value = data
|
2025-10-21 14:56:27 +08:00
|
|
|
|
}
|
|
|
|
|
|
})
|
2025-12-04 16:29:46 +08:00
|
|
|
|
|
2025-10-21 14:56:27 +08:00
|
|
|
|
const tableRef = ref()
|
2025-12-10 10:30:32 +08:00
|
|
|
|
|
|
|
|
|
|
const pageHeight = mainHeight(40)
|
2026-01-04 14:55:31 +08:00
|
|
|
|
const bindClick = () => {
|
|
|
|
|
|
bindRef.value.open()
|
|
|
|
|
|
}
|
2025-10-21 14:56:27 +08:00
|
|
|
|
|
2025-11-25 15:39:17 +08:00
|
|
|
|
const reset = () => {
|
2025-12-10 10:30:32 +08:00
|
|
|
|
// 向 iframe 发送复位事件
|
|
|
|
|
|
sendResetToIframe()
|
|
|
|
|
|
// 清空表格数据
|
|
|
|
|
|
// tableData.value = [];
|
2025-12-04 16:29:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 向 iframe 发送复位消息的函数
|
|
|
|
|
|
const sendResetToIframe = () => {
|
2025-12-10 10:30:32 +08:00
|
|
|
|
const iframe = document.getElementById('iframeLeft') as HTMLIFrameElement
|
|
|
|
|
|
if (iframe && iframe.contentWindow) {
|
|
|
|
|
|
iframe.contentWindow.postMessage(
|
|
|
|
|
|
{
|
|
|
|
|
|
type: 'RESET_EVENT',
|
|
|
|
|
|
payload: true
|
|
|
|
|
|
},
|
|
|
|
|
|
'*' // 生产环境中应替换为具体的域名
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
2025-11-25 15:39:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-21 14:56:27 +08:00
|
|
|
|
const iframeSrc = ref('')
|
|
|
|
|
|
|
|
|
|
|
|
// 监听 props 变化
|
|
|
|
|
|
// watch(
|
|
|
|
|
|
// () => props.project,
|
|
|
|
|
|
// newVal => {
|
|
|
|
|
|
// if (newVal && newVal.id && newVal.name) {
|
|
|
|
|
|
// // window.location.origin
|
|
|
|
|
|
// // iframeSrc.value =
|
|
|
|
|
|
// // "http://192.168.1.179:4001" +
|
|
|
|
|
|
// // `/zutai/?id=${newVal.id}&&name=${encodeURIComponent(
|
|
|
|
|
|
// // newVal.name
|
|
|
|
|
|
// // )}&&preview=true&&display=true&&graphicDisplay=wx#/preview`;
|
|
|
|
|
|
// iframeSrc.value =
|
|
|
|
|
|
// 'http://192.168.1.179:4001' +
|
|
|
|
|
|
// `/zutai/?id=4b4f7f4260198776594f5f9d93a532e8&&name=stt&&preview=true&&display=true#/preview_YPT`
|
|
|
|
|
|
|
|
|
|
|
|
// // console.log("更新 iframeSrc:", iframeSrc.value);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// },
|
|
|
|
|
|
// { immediate: true, deep: true }
|
|
|
|
|
|
// )
|
|
|
|
|
|
|
2026-01-04 14:55:31 +08:00
|
|
|
|
onMounted(async () => {
|
|
|
|
|
|
info()
|
2025-12-04 16:29:46 +08:00
|
|
|
|
// tableStore.index()
|
2025-10-21 14:56:27 +08:00
|
|
|
|
// 监听来自 eventStatistics 组件的消息
|
|
|
|
|
|
// getActive({}).then((res: any) => {
|
|
|
|
|
|
// if (res.code == "A0000") {
|
|
|
|
|
|
// // window.location.origin
|
|
|
|
|
|
// iframeSrc.value =
|
|
|
|
|
|
// "http://192.168.1.179:4001" +
|
|
|
|
|
|
// `/zutai/?id=${res.data.id}&&name=${encodeURIComponent(
|
|
|
|
|
|
// res.data.name
|
|
|
|
|
|
// )}&&preview=true&&display=true&&graphicDisplay=wx#/preview`;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// });
|
|
|
|
|
|
})
|
2026-01-04 14:55:31 +08:00
|
|
|
|
const info = async () => {
|
|
|
|
|
|
iframeSrc.value = ''
|
|
|
|
|
|
await getByUserId({ userId: adminInfo.id })
|
|
|
|
|
|
.then(res => {
|
|
|
|
|
|
bindId.value = res.data.pageId
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(async err => {
|
|
|
|
|
|
// bindId.value = '4b4f7f4260198776594f5f9d93a532e8'
|
|
|
|
|
|
await coFqueryPage({
|
|
|
|
|
|
currentUserId: adminInfo.id,
|
|
|
|
|
|
roleCode: adminInfo.roleCode.join(','),
|
|
|
|
|
|
searchValue: '',
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 1000
|
|
|
|
|
|
}).then(res => {
|
|
|
|
|
|
bindId.value = res.data.records.filter(item => item.scope == 1)[0]?.id || null
|
2026-06-08 18:34:49 +08:00
|
|
|
|
|
2026-01-04 14:55:31 +08:00
|
|
|
|
})
|
|
|
|
|
|
})
|
|
|
|
|
|
await setTimeout(() => {
|
|
|
|
|
|
iframeSrc.value = window.location.origin + `/zutai/?id=${bindId.value}&&name=stt&&preview=true#/preview_YPT`
|
|
|
|
|
|
// iframeSrc.value = `http://192.168.2.128:4001/zutai/?id=${bindId.value}&&name=stt&&preview=true#/preview_YPT`
|
|
|
|
|
|
window.addEventListener('message', handleMessage)
|
|
|
|
|
|
}, 0)
|
|
|
|
|
|
}
|
2025-10-21 14:56:27 +08:00
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
|
// 清理事件监听器
|
|
|
|
|
|
window.removeEventListener('message', handleMessage)
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// iframe 加载完成回调 添加加载事件监听
|
|
|
|
|
|
const onIframeLoad = () => {
|
|
|
|
|
|
// console.log("iframe 加载完成");
|
|
|
|
|
|
// 通知 securityDetail.vue 组件 iframe 已加载完成
|
|
|
|
|
|
window.postMessage(
|
|
|
|
|
|
{
|
|
|
|
|
|
type: 'IFRAME_LOADED',
|
|
|
|
|
|
data: { loaded: true }
|
|
|
|
|
|
},
|
|
|
|
|
|
'*'
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理来自 eventStatistics 组件的消息
|
|
|
|
|
|
const handleMessage = (event: MessageEvent) => {
|
|
|
|
|
|
// 验证消息来源(在生产环境中应该验证 origin)
|
|
|
|
|
|
// if (event.origin !== 'trusted-origin') return;
|
|
|
|
|
|
|
|
|
|
|
|
const { type, payload } = event.data
|
|
|
|
|
|
|
|
|
|
|
|
if (type === 'SEND_KEYS_TO_IFRAME') {
|
|
|
|
|
|
// 将数据转发给 iframe
|
|
|
|
|
|
sendKeysToIframe(payload)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 向 iframe 发送 keyList 数据
|
|
|
|
|
|
const sendKeysToIframe = (keyList: string[]) => {
|
|
|
|
|
|
const iframe = document.getElementById('iframeLeft') as HTMLIFrameElement
|
|
|
|
|
|
if (iframe && iframe.contentWindow) {
|
|
|
|
|
|
iframe.contentWindow.postMessage(
|
|
|
|
|
|
{
|
|
|
|
|
|
type: 'ANALYSIS_KEYS',
|
|
|
|
|
|
payload: keyList
|
|
|
|
|
|
},
|
|
|
|
|
|
'*'
|
|
|
|
|
|
) // 在生产环境中应该指定具体的域名而不是 '*'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-20 13:41:00 +08:00
|
|
|
|
</script>
|
2025-10-21 14:56:27 +08:00
|
|
|
|
<style lang="scss" scoped>
|
2025-10-21 16:01:33 +08:00
|
|
|
|
.dataBox {
|
2025-10-21 14:56:27 +08:00
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.iframe-container {
|
|
|
|
|
|
flex: 3.5;
|
|
|
|
|
|
}
|
2025-12-10 10:30:32 +08:00
|
|
|
|
|
2025-12-20 23:44:46 +08:00
|
|
|
|
.bottom-container {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
bottom: 0px;
|
2025-12-10 10:30:32 +08:00
|
|
|
|
|
2025-10-21 16:01:33 +08:00
|
|
|
|
.buttonBox {
|
2025-12-04 16:29:46 +08:00
|
|
|
|
display: flex;
|
2025-10-21 16:01:33 +08:00
|
|
|
|
width: 150px;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
}
|
2025-12-10 10:30:32 +08:00
|
|
|
|
|
2025-10-21 16:01:33 +08:00
|
|
|
|
.tableBox {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
2025-10-21 14:56:27 +08:00
|
|
|
|
}
|
2026-06-08 18:34:49 +08:00
|
|
|
|
|
2025-12-20 23:44:46 +08:00
|
|
|
|
.tableBox {
|
|
|
|
|
|
/* 必须:初始高度/overflow 配合动画 */
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
/* 与表格高度一致,保证展开后高度正确 */
|
|
|
|
|
|
height: 230px;
|
|
|
|
|
|
// margin-top: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 过渡动画核心样式 */
|
|
|
|
|
|
.table-fade-enter-from,
|
|
|
|
|
|
.table-fade-leave-to {
|
|
|
|
|
|
/* 关闭时:高度收为0 + 透明度0 */
|
|
|
|
|
|
height: 0;
|
|
|
|
|
|
opacity: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.table-fade-enter-to,
|
|
|
|
|
|
.table-fade-leave-from {
|
|
|
|
|
|
/* 展开时:高度恢复 + 透明度1 */
|
|
|
|
|
|
height: 230px;
|
|
|
|
|
|
opacity: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 动画过渡时长 + 曲线(可自定义) */
|
|
|
|
|
|
.table-fade-enter-active,
|
|
|
|
|
|
.table-fade-leave-active {
|
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
|
/* 防止动画过程中出现滚动条 */
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 解决动画结束后瞬间闪回的问题 */
|
|
|
|
|
|
.table-fade-enter-active {
|
|
|
|
|
|
transition-delay: 0.05s;
|
|
|
|
|
|
}
|
2026-06-08 18:34:49 +08:00
|
|
|
|
|
2026-01-04 14:55:31 +08:00
|
|
|
|
.bindBut {
|
|
|
|
|
|
position: absolute;
|
2026-06-08 18:34:49 +08:00
|
|
|
|
right: 10px;
|
|
|
|
|
|
top: 7px;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
font-size: 18px;
|
2026-01-04 14:55:31 +08:00
|
|
|
|
}
|
2025-10-21 14:56:27 +08:00
|
|
|
|
</style>
|