Files
deep-research-web-ui/components/ResearchReport.vue
2025-02-11 21:07:40 +08:00

96 lines
2.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { marked } from 'marked'
import { writeFinalReport, type WriteFinalReportParams } from '~/lib/deep-research'
interface CustomReportParams extends WriteFinalReportParams {
visitedUrls: string[]
}
const error = ref('')
const loading = ref(false)
const loadingExportPdf = ref(false)
const reportContent = ref('')
const reportHtml = computed(() => marked(reportContent.value))
const isExportButtonDisabled = computed(() => !reportContent.value || loading.value || loadingExportPdf.value)
async function generateReport(params: CustomReportParams) {
loading.value = true
error.value = ''
reportContent.value = ''
try {
for await (const chunk of writeFinalReport(params).textStream) {
reportContent.value += chunk
}
reportContent.value += `\n\n## Sources\n\n${params.visitedUrls.map((url) => `- ${url}`).join('\n')}`
} catch (e: any) {
console.error(`Generate report failed`, e)
error.value = e.message
} finally {
loading.value = false
}
}
async function exportToPdf() {
loadingExportPdf.value = true
try {
// 动态导入 html2pdf确保只在客户端执行
// @ts-ignore
const html2pdf = (await import('html2pdf.js')).default
const element = document.getElementById('report-content')
if (element) {
const opt = {
margin: [10, 10],
filename: 'research-report.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2 },
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
}
await html2pdf().set(opt).from(element).save()
}
} catch (error) {
console.error('Export to PDF failed:', error)
} finally {
loadingExportPdf.value = false
}
}
defineExpose({
generateReport,
exportToPdf,
})
</script>
<template>
<UCard>
<template #header>
<div class="flex items-center justify-between">
<h2 class="font-bold">4. Research Report</h2>
<UButton
color="info"
variant="ghost"
icon="i-lucide-download"
:disabled="isExportButtonDisabled"
:loading="loadingExportPdf"
@click="exportToPdf"
>
Export PDF
</UButton>
</div>
</template>
<div
v-if="reportContent"
id="report-content"
class="prose prose-sm max-w-none p-6 bg-gray-50 dark:bg-gray-800 dark:text-white rounded-lg shadow"
v-html="reportHtml"
/>
<template v-else>
<div v-if="error" class="text-red-500">{{ error }}</div>
<div v-else>{{ loading ? 'Generating report...' : 'Waiting for report..' }}.</div>
</template>
</UCard>
</template>