| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- <template>
- <div class="flex w-full h-full overflow-hidden">
- <div class="flex-1 flex flex-col">
- <div
- class="h-32px shrink-0 px-12px flex items-center justify-between border border-solid border-gray-200"
- @click="onClick"
- >
- <span class="text-12px">日志</span>
- <IconButton :icon="open ? 'lucide:chevron-down' : 'lucide:chevron-up'" link></IconButton>
- </div>
- <div class="flex-1 text-12px p-12px overflow-auto">
- <div v-if="executions.length === 0" class="text-gray-400">
- 暂无运行日志,点击运行节点后查看。
- </div>
- <el-table v-else :data="executions" row-key="runnerKey" size="small" border class="w-full">
- <el-table-column type="expand" width="48">
- <template #default="scope">
- <div class="p-8px">
- <el-table
- :data="scope.row.nodes"
- row-key="nodeId"
- size="small"
- border
- class="w-full"
- >
- <el-table-column prop="nodeName" label="节点名称" min-width="160" />
- <el-table-column prop="nodeType" label="类型" width="120" />
- <el-table-column label="状态" width="100">
- <template #default="{ row }">
- <el-tag :type="statusTagType(row.status)" size="small">
- {{ statusText(row.status) }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="lastUpdateTime" label="最后时间" width="180" />
- <el-table-column label="详情" min-width="260">
- <template #default="{ row }">
- <el-tabs type="border-card" class="w-full">
- <el-tab-pane label="输入">
- <pre
- class="bg-#f7f7f7 rounded p-6px whitespace-pre-wrap break-all max-h-160px overflow-auto"
- >{{ formatJson(row.track?.input_variable) }}
- </pre
- >
- </el-tab-pane>
- <el-tab-pane label="输出">
- <pre
- class="bg-#f7f7f7 rounded p-6px whitespace-pre-wrap break-all max-h-160px overflow-auto"
- >{{ formatJson(row.track?.output_variable) }}
- </pre
- >
- </el-tab-pane>
- </el-tabs>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </template>
- </el-table-column>
- <el-table-column type="index" label="#" width="48" />
- <el-table-column prop="runnerKey" label="运行ID" min-width="220" />
- <el-table-column label="状态" width="100">
- <template #default="{ row }">
- <el-tag :type="statusTagType(row.status)" size="small">
- {{ statusText(row.status) }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="startedAt" label="开始时间" width="180" />
- <el-table-column prop="finishedAt" label="结束时间" width="180" />
- <el-table-column label="节点数" width="80">
- <template #default="{ row }">
- {{ row.nodes?.length || 0 }}
- </template>
- </el-table-column>
- </el-table>
- </div>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import { computed, ref } from 'vue'
- import { IconButton } from '@repo/ui'
- import { useRunnerStore, type NodeStatus, type RunnerStatus } from '@/store/modules/runner.store'
- const emit = defineEmits<{
- toggle: [open: boolean]
- }>()
- const open = ref(false)
- const runnerStore = useRunnerStore()
- const executions = computed(() => runnerStore.executions)
- const onClick = () => {
- open.value = !open.value
- emit('toggle', open.value)
- }
- const formatJson = (value: unknown) => {
- if (value === null || value === undefined) return '-'
- try {
- return JSON.stringify(value, null, 2)
- } catch {
- return String(value)
- }
- }
- const statusText = (status: NodeStatus | RunnerStatus) => {
- if (status === 'running') return '运行中'
- if (status === 'success') return '运行成功'
- if (status === 'finished') return '运行完成'
- if (status === 'failed') return '运行失败'
- if (status === 'error') return '运行异常'
- return '就绪'
- }
- const statusTagType = (
- status: NodeStatus | RunnerStatus
- ): 'info' | 'success' | 'warning' | 'danger' => {
- if (status === 'running') return 'warning'
- if (status === 'success' || status === 'finished') return 'success'
- if (status === 'failed' || status === 'error') return 'danger'
- return 'info'
- }
- </script>
|