Files
TaskPool/web/src/views/history/LogViewer.vue
T
2026-04-08 20:23:57 +08:00

82 lines
1.9 KiB
Vue

<script setup lang="ts">
import { ref, watch, onUnmounted } from 'vue'
import LogDetailCard from '@/components/LogDetailCard.vue'
import type { TaskLog } from '@/api'
const props = withDefaults(defineProps<{
open: boolean
log: TaskLog | null
content: string
title?: string
loading?: boolean
variant?: 'full' | 'simple'
emptyTitle?: string
emptyDescription?: string
}>(), {
variant: 'simple'
})
const emit = defineEmits<{
'update:open': [value: boolean]
}>()
const isFullscreen = ref(false)
function close() {
isFullscreen.value = false
emit('update:open', false)
}
// 统一控制 Body 滚动
function toggleBodyScroll(lock: boolean) {
if (lock) {
document.body.style.overflow = 'hidden'
} else {
document.body.style.overflow = ''
}
}
// 监听打开状态
watch(() => props.open, (val) => {
if (val) {
isFullscreen.value = false
toggleBodyScroll(true)
} else {
toggleBodyScroll(false)
}
}, { immediate: true })
// 确保组件卸载时恢复滚动
onUnmounted(() => {
toggleBodyScroll(false)
})
</script>
<template>
<Teleport to="body">
<div v-if="open" class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-0 sm:p-4"
@click.self="close">
<div
:class="[
'bg-background shadow-2xl flex flex-col transition-all duration-300 overflow-hidden',
isFullscreen
? 'fixed inset-0 w-screen h-screen z-[60] rounded-none'
: 'w-full sm:w-[90vw] md:w-[80vw] max-w-5xl h-[90vh] sm:h-[85vh] rounded-xl'
]">
<LogDetailCard
class="flex-1"
:log="log"
:content="content"
:title="title"
:loading="loading"
:variant="isFullscreen ? 'simple' : variant"
:empty-title="emptyTitle"
:empty-description="emptyDescription"
@close="close"
@maximize="isFullscreen = !isFullscreen"
/>
</div>
</div>
</Teleport>
</template>