Files
svgeditor2.0/src/components/mt-preview-ypt/iframeDia.vue

379 lines
11 KiB
Vue
Raw Normal View History

2025-12-05 10:45:02 +08:00
<template>
<div class="container">
<!-- 使用 v-for 遍历四个角落 -->
<div v-for="corner in corners" :key="corner.id" :class="['corner', corner.className]">
<div class="content">
<div class="title">{{ corner.title }}</div>
<el-descriptions :column="1" size="small" label-width="70px" border>
<el-descriptions-item v-for="(item, index) in corner.data" :key="index" :label="item.label">
<div v-html="item.value"></div>
</el-descriptions-item>
</el-descriptions>
</div>
<span class="close-btn" @click="closeCorner(corner.id)">
<Close />
</span>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, nextTick } from 'vue'
import { Close } from '@element-plus/icons-vue'
2025-12-05 11:25:26 +08:00
// 定义 emits
const emit = defineEmits<{
(e: 'lineListChange', lineList: string[]): void
}>()
2025-12-05 10:45:02 +08:00
// 定义接收的 props
const props = defineProps<{
eventList?: []
steadyState?: [
{
id: 'c53cccb8c65201c192d8c57fbdb4d993-W1O31AjTAx'
lineId: '00B78D0171091'
phaseType: 'Pq_RmsU'
statisticalName: '统计数据 / 相电压总有效值 / A / 平均值'
target: '统计数据$Pq_RmsU$A'
value: 45
valueType: 'A'
},
{
id: 'c53cccb8c65201c192d8c57fbdb4d993-W1O31AjTAx'
lineId: '00B78D0171091'
phaseType: 'Pq_RmsU'
statisticalName: '统计数据 / 相电压总有效值 / A / CP95'
target: '统计数据$Pq_RmsU$A'
value: 3.1415926
valueType: 'A'
},
{
id: 'c53cccb8c65201c192d8c57fbdb4d993-W1O31AjTAx'
lineId: '00B78D0171091'
phaseType: 'Pq_RmsU'
statisticalName: '统计数据 / 相电压总有效值 / A / 最大值'
target: '统计数据$Pq_RmsU$A'
value: 3.1415926
valueType: 'A'
},
{
id: 'c53cccb8c65201c192d8c57fbdb4d993-W1O31AjTAx'
lineId: '00B78D0171091'
phaseType: 'Pq_RmsU'
statisticalName: '统计数据 / 相电压总有效值 / A / 最小值'
target: '统计数据$Pq_RmsU$A'
value: 3.1415926
valueType: 'A'
},
{
id: 'c53cccb8c65201c192d8c57fbdb4d993-zOXUxFQ6Vt'
lineId: '00B78D0171092'
phaseType: 'Pq_RmsLU'
statisticalName: '统计数据 / 线电压总有效值 / BC / 平均值'
target: '统计数据$Pq_RmsLU$BC'
value: 3.1415926
valueType: 'BC'
},
{
id: 'c53cccb8c65201c192d8c57fbdb4d993-zOXUxFQ6Vt'
lineId: '00B78D0171092'
phaseType: 'Pq_RmsLU'
statisticalName: '统计数据 / 线电压总有效值 / BC / CP95'
target: '统计数据$Pq_RmsLU$BC'
value: 3.1415926
valueType: 'BC'
}
]
}>()
// 定义四个角落的数据
const corners = ref([
{
id: 'topLeft',
title: '左上',
className: 'top-left',
show: false,
data: [] as { label: string; value: string }[],
elementId: '' // 记录该角落对应的元素ID
},
{
id: 'topRight',
title: '右上',
className: 'top-right',
show: false,
data: [] as { label: string; value: string }[],
elementId: ''
}
])
const displayOrder = ref<number[]>([])
2025-12-05 11:25:26 +08:00
const lineList = ref<string[]>([]) // 缓存打开的lineId
2025-12-05 10:45:02 +08:00
// 处理稳态指标数据
const processSteadyStateData = (cornerIndex: number, elementId: string) => {
nextTick(() => {
if (!props.steadyState || props.steadyState.length == 0) {
if (corners.value[cornerIndex].data.length > 0) {
corners.value[cornerIndex].data[0].value = '暂无稳态指标数据'
}
return
}
let str = ``
props.steadyState
.filter(item => item.lineId === elementId)
.forEach(item => {
if (item.value == 3.1415926) {
str += `<div>${item.statisticalName}/</div>`
} else {
str += `<div>${item.statisticalName}${item.value}</div>`
}
})
if (str) {
if (corners.value[cornerIndex].data.length > 0) {
corners.value[cornerIndex].data[0].value =
`<div style="max-height: 100px;overflow-y: auto;">${str}</div>`
}
} else {
if (corners.value[cornerIndex].data.length > 0) {
corners.value[cornerIndex].data[0].value = '暂无稳态指标数据'
}
}
})
}
// 截取线路名称的最后一部分作为标题
const extractTitleFromLineName = (lineName: string): string => {
if (!lineName) return '未知监测点'
// 按照 "/" 分割字符串,取最后一部分
const parts = lineName.split('/')
return parts.length > 0 ? parts[parts.length - 1].trim() : lineName
}
// 更新指定角落数据的函数
const updateCornerData = (cornerIndex: number, dataItem: any, elementId: string, lineName: string) => {
// 更新标题为传入的 lineName 的最后一部分
corners.value[cornerIndex].title = extractTitleFromLineName(lineName)
// 格式化数据(只保留稳态指标一项)
corners.value[cornerIndex].data = [
{
label: '稳态指标',
value: '正在加载...'
}
]
// 记录该角落对应的元素ID
corners.value[cornerIndex].elementId = elementId
corners.value[cornerIndex].show = true
// 处理稳态指标数据
processSteadyStateData(cornerIndex, elementId)
}
// 显示下一个角落的函数
const showNextCorner = (elementId: string, lineName: string) => {
// 检查该元素ID是否已经显示过
const existingCornerIndex = corners.value.findIndex(corner => corner.elementId === elementId && corner.show)
if (existingCornerIndex !== -1) {
// 如果该元素已经显示过,更新标题
corners.value[existingCornerIndex].title = extractTitleFromLineName(lineName)
return
}
2025-12-05 11:25:26 +08:00
// // 确保 props.eventList 是数组并且过滤掉 null/undefined 元素
// if (!Array.isArray(props.eventList)) {
// console.warn('props.eventList 不是数组格式:', props.eventList)
// return
// }
2025-12-05 10:45:02 +08:00
2025-12-05 11:25:26 +08:00
// // 过滤掉 null 和 undefined 元素,然后查找匹配项
// const validItems = props.eventList.filter(item => item !== null && item !== undefined)
// const dataItem = validItems.find(item => item.lineId === elementId)
2025-12-05 10:45:02 +08:00
2025-12-05 11:25:26 +08:00
// // 如果没有找到匹配的数据项,则不更新数据
// if (!dataItem) {
// console.warn('未找到匹配的数据项:', elementId)
// return
// }
2025-12-05 10:45:02 +08:00
// 查找一个未显示的角落
const availableCornerIndex = corners.value.findIndex(corner => !corner.show)
if (availableCornerIndex !== -1) {
// 有空闲角落,显示在该角落
updateCornerData(availableCornerIndex, dataItem, elementId, lineName)
// 记录显示顺序
displayOrder.value.push(availableCornerIndex)
} else {
// 没有空闲角落,按顺序替换角落
// 获取需要替换的角落索引(循环替换)
const replaceIndex = displayOrder.value.shift() || 0
updateCornerData(replaceIndex, dataItem, elementId, lineName)
// 将替换的索引重新加入队列末尾
displayOrder.value.push(replaceIndex)
}
2025-12-05 11:25:26 +08:00
// 更新 lineList去重并触发事件
updateLineList(elementId)
}
// 更新 lineList去重并触发事件
const updateLineList = (elementId: string) => {
// 检查是否已存在
if (!lineList.value.includes(elementId)) {
lineList.value.push(elementId)
// 触发事件,传递更新后的 lineList
emit('lineListChange', [...lineList.value])
}
2025-12-05 10:45:02 +08:00
}
// 关闭指定角落的函数
const closeCorner = (id: string) => {
const cornerIndex = corners.value.findIndex(c => c.id === id)
if (cornerIndex !== -1) {
2025-12-05 11:25:26 +08:00
const elementId = corners.value[cornerIndex].elementId
2025-12-05 10:45:02 +08:00
corners.value[cornerIndex].show = false
corners.value[cornerIndex].elementId = '' // 清空元素ID记录
// 从显示顺序中移除该角落索引
const orderIndex = displayOrder.value.indexOf(cornerIndex)
if (orderIndex !== -1) {
displayOrder.value.splice(orderIndex, 1)
}
2025-12-05 11:25:26 +08:00
// 从 lineList 中移除对应的 elementId
const lineIndex = lineList.value.indexOf(elementId)
if (lineIndex !== -1) {
lineList.value.splice(lineIndex, 1)
// 触发事件,传递更新后的 lineList
emit('lineListChange', [...lineList.value])
}
2025-12-05 10:45:02 +08:00
}
}
// 关闭所有角落的函数
const closeAllCorners = () => {
corners.value.forEach(corner => {
corner.show = false
corner.elementId = ''
})
displayOrder.value = []
2025-12-05 11:25:26 +08:00
lineList.value = [] // 清空 lineList
// 触发事件,传递清空后的 lineList
emit('lineListChange', [])
2025-12-05 10:45:02 +08:00
}
onMounted(() => {
2025-12-05 11:25:26 +08:00
nextTick(() => {
showNextCorner('00B78D0171091', '在线设备 / 灿能测试 / EMC实验室 / 装置一 / 监测点1')
})
2025-12-05 10:45:02 +08:00
})
// 暴露方法给父组件使用
defineExpose({
showNextCorner,
closeCorner,
closeAllCorners
})
</script>
2025-12-05 11:25:26 +08:00
<style scoped lang="less">
2025-12-05 10:45:02 +08:00
.container {
position: relative;
}
.corner {
width: 240px;
background-color: #2b2d3a90;
position: absolute;
color: 000;
opacity: 0;
transform: scale(0.3);
transition: all 0.4s ease-out;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}
/* 显示状态的样式 */
.corner:not([style*='display: none']):not([style*='display:none']) {
opacity: 1;
transform: scale(1);
}
.top-left {
top: 10px;
left: 10px;
}
.top-right {
top: 10px;
2025-12-05 11:25:26 +08:00
right: 10px;
2025-12-05 10:45:02 +08:00
}
.bottom-left {
top: 170px;
left: 10px;
}
.bottom-right {
top: 170px;
right: 10px;
}
.content {
width: 100%;
height: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.title {
font-size: 16px;
padding: 8px;
border-bottom: 1px solid #fff;
background-color: #fff;
border-radius: 8px 8px 0 0;
}
.data-item {
display: flex;
margin-bottom: 4px;
font-size: 12px;
}
.label {
width: 55px;
flex-shrink: 0;
}
.value {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 关闭按钮样式 */
.close-btn {
position: absolute;
top: 10px;
right: 10px;
width: 14px;
2025-12-05 11:25:26 +08:00
color: #000;
2025-12-05 10:45:02 +08:00
font-size: 14px;
font-weight: bold;
cursor: pointer;
}
.indicator {
display: flex;
}
2025-12-05 11:25:26 +08:00
</style>