预检测

This commit is contained in:
sjl
2025-08-06 15:18:27 +08:00
parent 83998f88ac
commit d0724cb7f6
12 changed files with 739 additions and 164 deletions

View File

@@ -1,106 +1,346 @@
<template>
<el-dialog title="实时数据详情" v-model='dialogVisible' @close="handleClose" v-bind="dialogBig" >
<el-dialog title="实时数据详情" v-model='dialogVisible' @close="handleClose" v-bind="dialogBig">
<el-tabs v-model="activeTab" type="card">
<el-tab-pane label="被检设备1" name="channel1">
<el-tab-pane
v-for="(device, deviceName, index) in testDataStructure"
:key="deviceName"
:name="`channel${index + 1}`">
<template #label>
<span>
{{ deviceName }}
<el-icon v-if="tabStatus[deviceName]" style="color: red; margin-left: 5px;">
<CircleClose />
</el-icon>
<el-icon v-else style="color: green; margin-left: 5px;">
<CircleCheck />
</el-icon>
</span>
</template>
<div class="table-toolbar">
<el-form-item label="被检设备通道号" prop="createId">
<el-select v-model="timeRange" placeholder="选择时间范围" style="width: 150px;">
<el-option label="通道1" value="1"></el-option>
<el-option label="通道2" value="2"></el-option>
<el-option label="通道3" value="3"></el-option>
<el-option label="通道4" value="4"></el-option>
</el-select>
<el-select
v-model="selectedChannels[deviceName]"
placeholder="选择通道"
style="width: 150px;"
@change="() => handleDutChannelChange(deviceName)">
<el-option
v-for="(channelData, channelName) in device.dutData"
:key="channelName"
:label="channelName.replace('被检', '')"
:value="channelName">
</el-option>
</el-select>
</el-form-item>
<el-button type="primary" @click="exportData">导出数据</el-button>
</div>
<el-table
:data="tableData"
:data="tableDataMap[deviceName]"
:header-cell-style="{ textAlign: 'center',backgroundColor: 'var(--el-color-primary)',color: '#fff' } "
:cell-style="{ textAlign: 'center' }"
style="width: 100%"
:style="{ height: '400px',maxHeight: '400px',overflow:'hidden'}">
<el-table-column prop="monitorNum" label="数据时标" width="180"/>
<el-table-column label="被检设备1-通道1">
<el-table-column prop="Ua" label="A相(V)">
<el-table-column :label="`${deviceName}-${selectedChannels[deviceName]?.replace('被检', '') || '通道1'}`">
<el-table-column prop="Ua1" label="A相(V)">
</el-table-column>
<el-table-column prop="Ub" label="B相(V)">
<el-table-column prop="Ub1" label="B相(V)">
</el-table-column>
<el-table-column prop="Uc" label="C相(V)">
<el-table-column prop="Uc1" label="C相(V)">
</el-table-column>
</el-table-column>
<el-table-column label="标准设备-通道1">
<el-table-column prop="Ua" label="A相(V)">
<el-table-column :label="`标准设备-${getMappedStandardChannel(deviceName, selectedChannels[deviceName])?.replace('标准', '') || '通道1'}`">
<el-table-column prop="Ua2" label="A相(V)">
</el-table-column>
<el-table-column prop="Ub" label="B相(V)">
<el-table-column prop="Ub2" label="B相(V)">
</el-table-column>
<el-table-column prop="Uc" label="C相(V)">
<el-table-column prop="Uc2" label="C相(V)">
</el-table-column>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="被检设备2" name="channel2"></el-tab-pane>
</el-tabs>
</el-dialog>
</template>
<script setup lang='tsx' name='realTimeDataAlign'>
import { dialogBig } from "@/utils/elementBind";
import { ref, reactive } from "vue";
import { ref } from "vue";
import { ElMessage } from "element-plus";
import { CircleCheck, CircleClose } from '@element-plus/icons-vue';
const dialogVisible = ref(false);
const activeTab = ref('channel1');
const timeRange = ref('1');
// 表格数据示例
const tableData = ref([
{
monitorNum: '2023-05-20 10:30:01',
Ua: '220.5V',
Ub: '219.8V',
Uc: '220.2V',
Ia: '4.98A',
Ib: '5.01A',
Ic: '4.99A'
const testDataStructure = ref({
// 第一层:多个被检设备
'被检设备1': {
// 被检设备数据
dutData: {
'被检通道1': {
// 第三层各个时间点的ABC三相数据
'2023-05-20 10:30:01': {
Ua: '1',
Ub: '2',
Uc: '3',
},
'2023-05-20 10:30:04': {
Ua: '4',
Ub: '5',
Uc: '6',
},
'2023-05-20 10:30:07': {
Ua: '7',
Ub: '8',
Uc: '9',
},
'2023-05-20 10:30:10': {
Ua: '10',
Ub: '11',
Uc: '12',
},
'2023-05-20 10:30:13': {
Ua: '13',
Ub: '14',
Uc: '15',
}
},
'被检通道2': {
'2023-05-20 10:30:01': {
Ua: '7',
Ub: '8',
Uc: '9',
},
'2023-05-20 10:30:04': {
Ua: '10',
Ub: '11',
Uc: '12',
},
'2023-05-20 10:30:07': {
Ua: '13',
Ub: '14',
Uc: '15',
},
'2023-05-20 10:30:10': {
Ua: '16',
Ub: '17',
Uc: '18',
},
'2023-05-20 10:30:13': {
Ua: '19',
Ub: '20',
Uc: '21',
}
}
},
// 标准设备数据
standardData: {
'标准通道1': {
'2023-05-20 10:30:00': {
Ua: '01',
Ub: '02',
Uc: '03',
},
'2023-05-20 10:30:03': {
Ua: '04',
Ub: '05',
Uc: '06',
},
'2023-05-20 10:30:06': {
Ua: '07',
Ub: '08',
Uc: '09',
},
'2023-05-20 10:30:09': {
Ua: '010',
Ub: '011',
Uc: '012',
},
'2023-05-20 10:30:12': {
Ua: '013',
Ub: '014',
Uc: '015',
}
},
'标准通道2': {
'2023-05-20 10:30:01': {
Ua: '07',
Ub: '08',
Uc: '09',
},
'2023-05-20 10:30:04': {
Ua: '010',
Ub: '011',
Uc: '012',
},
'2023-05-20 10:30:07': {
Ua: '013',
Ub: '014',
Uc: '015',
},
'2023-05-20 10:30:10': {
Ua: '016',
Ub: '017',
Uc: '018',
},
'2023-05-20 10:30:13': {
Ua: '019',
Ub: '020',
Uc: '021',
}
}
}
},
{
monitorNum: '2023-05-20 10:30:04',
Ua: '220.3V',
Ub: '220.1V',
Uc: '219.9V',
Ia: '5.02A',
Ib: '4.99A',
Ic: '5.00A'
},
{
monitorNum: '2023-05-20 10:30:07',
Ua: '220.5V',
Ub: '219.8V',
Uc: '220.2V',
Ia: '4.98A',
Ib: '5.01A',
Ic: '4.99A'
},
{
monitorNum: '2023-05-20 10:30:10',
Ua: '220.3V',
Ub: '220.1V',
Uc: '219.9V',
Ia: '5.02A',
Ib: '4.99A',
Ic: '5.00A'
'被检设备2': {
dutData: {
'被检通道1': {
'2023-05-20 10:30:01': {
Ua: '11',
Ub: '12',
Uc: '13',
}
},
'被检通道2': {
'2023-05-20 10:30:01': {
Ua: '14',
Ub: '15',
Uc: '16',
}
}
},
standardData: {
'标准通道1': {
'2023-05-20 10:30:01': {
Ua: '011',
Ub: '012',
Uc: '013',
}
},
'标准通道2': {
'2023-05-20 10:30:01': {
Ua: '014',
Ub: '015',
Uc: '016',
}
}
}
}
]);
});
// 每个设备选中的通道
const selectedChannels = ref<Record<string, string>>({});
// 通道映射关系:被检设备通道 -> 标准设备通道
// 格式被检设备1-被检通道1标准设备1-标准通道2
const channelMapping = ref<Record<string, Record<string, string>>>({
'被检设备1': {
'被检通道1': '标准通道1',
'被检通道2': '标准通道2'
},
'被检设备2': {
'被检通道1': '标准通道2',
'被检通道2': '标准通道1'
}
});
// 每个设备的表格数据
const tableDataMap = ref<Record<string, any[]>>({});
// 每个tab的状态true表示有不完整数据false表示数据完整
const tabStatus = ref<Record<string, boolean>>({});
// 检查设备数据是否有不完整的行(包含/的行)
const hasIncompleteData = (deviceName: string) => {
const tableData = tableDataMap.value[deviceName];
if (!tableData || tableData.length === 0) return false;
// 检查每一行是否有缺失数据(包含/的字段)
return tableData.some(row => {
return row.Ua1 === '/' || row.Ub1 === '/' || row.Uc1 === '/' ||
row.Ua2 === '/' || row.Ub2 === '/' || row.Uc2 === '/';
});
};
// 获取映射的标准设备通道
const getMappedStandardChannel = (deviceName: string, dutChannel: string) => {
if (!channelMapping.value[deviceName]) {
return '标准通道1'; // 默认值
}
return channelMapping.value[deviceName][dutChannel] || '标准通道1';
};
// 处理被检设备通道切换
const handleDutChannelChange = (deviceName: string) => {
// 更新指定设备的表格数据但不改变tab图标状态
updateTableData(deviceName);
};
// 根据 testDataStructure 生成表格数据
const generateTableData = (deviceName: string, dutChannel: string) => {
const deviceData = testDataStructure.value[deviceName];
if (!deviceData) return [];
const dutData = deviceData.dutData[dutChannel];
// 获取映射的标准设备通道
const standardChannel = getMappedStandardChannel(deviceName, dutChannel);
const standardData = deviceData.standardData[standardChannel];
if (!dutData || !standardData) return [];
// 获取所有时间戳并去重排序
const dutTimestamps = Object.keys(dutData);
const standardTimestamps = Object.keys(standardData);
const allTimestamps = Array.from(new Set([...dutTimestamps, ...standardTimestamps])).sort();
// 生成表格数据
return allTimestamps.map(timestamp => {
const dutValues = dutData[timestamp];
const standardValues = standardData[timestamp];
return {
monitorNum: timestamp,
Ua1: dutValues ? dutValues.Ua : '/',
Ub1: dutValues ? dutValues.Ub : '/',
Uc1: dutValues ? dutValues.Uc : '/',
Ua2: standardValues ? standardValues.Ua : '/',
Ub2: standardValues ? standardValues.Ub : '/',
Uc2: standardValues ? standardValues.Uc : '/'
};
});
};
// 更新指定设备的表格数据
const updateTableData = (deviceName: string) => {
const selectedChannel = selectedChannels.value[deviceName];
if (selectedChannel) {
const tableData = generateTableData(deviceName, selectedChannel);
tableDataMap.value[deviceName] = tableData;
}
};
// 初始化所有设备的数据和状态
const initAllTableData = () => {
Object.keys(testDataStructure.value).forEach(deviceName => {
// 默认选择第一个通道
const firstChannel = Object.keys(testDataStructure.value[deviceName].dutData)[0];
selectedChannels.value[deviceName] = firstChannel;
// 生成表格数据
updateTableData(deviceName);
// 初始化tab状态只在初始化时设置一次
if (tabStatus.value[deviceName] === undefined) {
tabStatus.value[deviceName] = hasIncompleteData(deviceName);
}
});
};
const open = async () => {
dialogVisible.value = true;
};
// 刷新数据
const refreshData = () => {
ElMessage.info('正在刷新数据...');
// 这里可以添加实际的数据刷新逻辑
// 初始化数据和状态
initAllTableData();
// 设置默认激活的 tab
activeTab.value = 'channel1';
};
// 导出数据
@@ -120,14 +360,9 @@ defineExpose({ open });
<style scoped lang="scss">
.table-toolbar {
display: flex;
justify-content: space-between; // 关键修改:将子元素分布到两端
justify-content: space-between;
}
// 移除这个样式,避免影响布局
// .table-toolbar .el-button {
// margin-right: 10px;
// }
:deep(.el-dialog__body) {
padding: 10px 20px 20px 20px;
}