msmail / src /views /DebugView.vue
github-actions[bot]
Update from GitHub Actions
11a8eb2
raw
history blame
5.1 kB
<template>
<div class="debug-view p-6">
<div class="mb-4">
<t-button theme="primary" @click="loadDebugData" :loading="loading">
<template #icon>
<t-icon name="refresh" />
</template>
刷新数据
</t-button>
</div>
<t-loading :loading="loading" text="正在加载调试数据...">
<div v-if="error" class="mb-4">
<t-alert theme="error" :message="error" />
</div>
<div v-if="!loading && debugList.length === 0" class="text-center py-12">
<t-icon name="inbox" size="48px" class="text-gray-400 mb-4" />
<p class="text-gray-500">暂无调试数据</p>
</div>
<div v-else class="space-y-4">
<t-card
v-for="item in debugList"
:key="item.debugId"
:class="{ 'border-red-200': item.hasError }"
class="cursor-pointer hover:shadow-md transition-shadow"
@click="toggleDebugContent(item.debugId)"
>
<template #header>
<div class="flex justify-between items-center">
<div class="flex items-center space-x-3">
<strong class="text-lg">{{ item.email }}</strong>
<t-tag
:theme="item.hasError ? 'danger' : 'success'"
variant="light"
>
{{ item.hasError ? '失败' : '成功' }}
</t-tag>
<span class="text-gray-500 text-sm">
{{ formatTime(item.timestamp) }}
</span>
</div>
<t-icon
:name="expandedItems.has(item.debugId) ? 'chevron-up' : 'chevron-down'"
class="text-gray-400"
/>
</div>
</template>
<div v-if="expandedItems.has(item.debugId)" class="space-y-4">
<div v-if="item.hasError" class="mb-4">
<t-alert theme="error" :message="`错误信息: ${item.errorMessage}`" />
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm">
<div>
<span class="font-medium text-gray-700">调试ID:</span>
<span class="ml-2 text-gray-600 font-mono">{{ item.debugId }}</span>
</div>
<div>
<span class="font-medium text-gray-700">邮箱:</span>
<span class="ml-2 text-gray-600">{{ item.email }}</span>
</div>
<div>
<span class="font-medium text-gray-700">时间:</span>
<span class="ml-2 text-gray-600">{{ formatTime(item.timestamp) }}</span>
</div>
<div>
<span class="font-medium text-gray-700">页面标题:</span>
<span class="ml-2 text-gray-600">{{ item.title }}</span>
</div>
<div class="md:col-span-2">
<span class="font-medium text-gray-700">页面URL:</span>
<span class="ml-2 text-gray-600 break-all">{{ item.url }}</span>
</div>
</div>
<div>
<h4 class="font-medium text-gray-700 mb-2">页面截图:</h4>
<div class="border rounded-lg overflow-hidden bg-gray-50">
<img
:src="item.screenshotUrl"
:alt="`${item.email} 的页面截图`"
class="w-full h-auto max-h-96 object-contain"
loading="lazy"
@error="handleImageError"
/>
</div>
</div>
</div>
</t-card>
</div>
</t-loading>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
interface DebugItem {
debugId: string
email: string
timestamp: string
url: string
title: string
hasError: boolean
errorMessage?: string
screenshotUrl: string
}
const loading = ref(false)
const error = ref('')
const debugList = ref<DebugItem[]>([])
const expandedItems = ref(new Set<string>())
const loadDebugData = async () => {
loading.value = true
error.value = ''
try {
const response = await fetch('/api/debug/list')
const result = await response.json()
if (result.success) {
debugList.value = result.data
} else {
error.value = `加载失败: ${result.error}`
}
} catch (err) {
error.value = `网络错误: ${err instanceof Error ? err.message : String(err)}`
} finally {
loading.value = false
}
}
const toggleDebugContent = (debugId: string) => {
if (expandedItems.value.has(debugId)) {
expandedItems.value.delete(debugId)
} else {
expandedItems.value.add(debugId)
}
}
const formatTime = (timestamp: string) => {
return new Date(timestamp).toLocaleString('zh-CN')
}
const handleImageError = (event: Event) => {
const img = event.target as HTMLImageElement
img.style.display = 'none'
const parent = img.parentElement
if (parent) {
parent.innerHTML = '<div class="text-center py-8 text-gray-500">截图加载失败</div>'
}
}
onMounted(() => {
loadDebugData()
})
</script>