<template>
|
<div class="multi-device-workbench">
|
<div class="main-grid">
|
<div class="left-panel">
|
<GroupList @select="handleGroupSelect" />
|
<GroupTopology
|
v-if="selectedGroup"
|
:group="selectedGroup"
|
class="topology-panel"
|
/>
|
</div>
|
<div class="right-panel">
|
<el-tabs v-model="activeTab" type="card" class="workbench-tabs">
|
<el-tab-pane label="任务编排" name="orchestration">
|
<TaskOrchestration
|
:group="selectedGroup"
|
@task-started="handleTaskStarted"
|
/>
|
</el-tab-pane>
|
<el-tab-pane label="执行监控" name="monitor">
|
<ExecutionMonitor
|
ref="monitorRef"
|
:group-id="selectedGroupId"
|
:task-id="selectedTaskId"
|
class="monitor-panel"
|
@task-selected="handleTaskSelected"
|
/>
|
</el-tab-pane>
|
<el-tab-pane label="结果分析" name="analysis">
|
<ResultAnalysis
|
ref="analysisRef"
|
:task="selectedTask"
|
class="analysis-panel"
|
/>
|
</el-tab-pane>
|
</el-tabs>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script setup>
|
import { computed, ref, watch } from 'vue'
|
import GroupList from './components/DeviceGroup/GroupList.vue'
|
import GroupTopology from './components/DeviceGroup/GroupTopology.vue'
|
import TaskOrchestration from './components/MultiDeviceTest/TaskOrchestration.vue'
|
import ExecutionMonitor from './components/MultiDeviceTest/ExecutionMonitor.vue'
|
import ResultAnalysis from './components/MultiDeviceTest/ResultAnalysis.vue'
|
|
const selectedGroup = ref(null)
|
const monitorRef = ref(null)
|
const analysisRef = ref(null)
|
const activeTab = ref('orchestration')
|
const selectedTaskId = ref(null)
|
const selectedTask = ref(null)
|
|
const selectedGroupId = computed(() => {
|
if (!selectedGroup.value) return null
|
return selectedGroup.value.id || selectedGroup.value.groupId
|
})
|
|
const handleGroupSelect = (group) => {
|
selectedGroup.value = group
|
selectedTask.value = null
|
selectedTaskId.value = null
|
// 切换到编排标签页
|
activeTab.value = 'orchestration'
|
}
|
|
const handleTaskStarted = (task) => {
|
// 任务启动后,切换到监控标签页(如果当前不在监控页)
|
if (activeTab.value !== 'monitor') {
|
activeTab.value = 'monitor'
|
}
|
// 立即刷新监控列表,显示新启动的任务
|
setTimeout(() => {
|
monitorRef.value?.fetchTasks?.()
|
}, 300)
|
|
// 如果传入了任务信息,可以自动选中
|
if (task && task.taskId) {
|
selectedTaskId.value = task.taskId
|
}
|
}
|
|
const handleTaskSelected = (task) => {
|
selectedTask.value = task
|
selectedTaskId.value = task?.taskId || null
|
// 如果任务已完成或失败,切换到结果分析标签页
|
if (task && (task.status === 'COMPLETED' || task.status === 'FAILED')) {
|
activeTab.value = 'analysis'
|
// 刷新分析数据
|
setTimeout(() => {
|
analysisRef.value?.fetchSteps?.()
|
}, 100)
|
}
|
}
|
</script>
|
|
<style scoped>
|
.multi-device-workbench {
|
padding: 24px;
|
min-height: 100%;
|
background: linear-gradient(180deg, #f6f9ff 0%, #f4f6fb 100%);
|
}
|
|
.main-grid {
|
display: grid;
|
grid-template-columns: 360px 1fr;
|
gap: 24px;
|
}
|
|
.left-panel {
|
display: flex;
|
flex-direction: column;
|
gap: 24px;
|
}
|
|
.topology-panel {
|
flex: 1;
|
min-height: 300px;
|
}
|
|
.right-panel {
|
display: flex;
|
flex-direction: column;
|
min-height: 0;
|
}
|
|
.workbench-tabs {
|
flex: 1;
|
display: flex;
|
flex-direction: column;
|
min-height: 0;
|
}
|
|
.workbench-tabs :deep(.el-tabs__content) {
|
flex: 1;
|
overflow: auto;
|
}
|
|
.workbench-tabs :deep(.el-tab-pane) {
|
height: 100%;
|
}
|
|
.monitor-panel,
|
.analysis-panel {
|
flex: 1;
|
min-height: 500px;
|
}
|
|
@media (max-width: 1200px) {
|
.main-grid {
|
grid-template-columns: 1fr;
|
}
|
}
|
</style>
|