From 501e25d835c15a5731b092b66508e76c0c1b85ef Mon Sep 17 00:00:00 2001 From: AnotiaWang Date: Tue, 11 Feb 2025 21:37:11 +0800 Subject: [PATCH] feat: handle loading states --- components/DeepResearch.vue | 6 +++++ components/ResearchFeedback.vue | 16 +++++++++-- components/ResearchForm.vue | 44 ++++++++++++++++-------------- components/ResearchReport.vue | 48 ++++++++++++++++++++++++--------- pages/index.vue | 14 +++++----- 5 files changed, 87 insertions(+), 41 deletions(-) diff --git a/components/DeepResearch.vue b/components/DeepResearch.vue index e5bc732..6fa66e9 100644 --- a/components/DeepResearch.vue +++ b/components/DeepResearch.vue @@ -13,6 +13,7 @@ }) const selectedNode = ref() const searchResults = ref>({}) + const isLoading = ref(false) function handleResearchProgress(step: ResearchStep) { let node: TreeNode | null = null @@ -94,6 +95,7 @@ case 'complete': emit('complete', step) + isLoading.value = false break } } @@ -132,6 +134,7 @@ tree.value.children = [] selectedNode.value = undefined searchResults.value = {} + isLoading.value = true try { await deepResearch({ query, @@ -141,11 +144,14 @@ }) } catch (error) { console.error('Research failed:', error) + } finally { + isLoading.value = false } } defineExpose({ startResearch, + isLoading, }) diff --git a/components/ResearchFeedback.vue b/components/ResearchFeedback.vue index f1ab11b..5d2acfe 100644 --- a/components/ResearchFeedback.vue +++ b/components/ResearchFeedback.vue @@ -8,6 +8,10 @@ userAnswer: string } + const props = defineProps<{ + isLoadingSearch?: boolean + }>() + defineEmits<{ (e: 'submit', feedback: ResearchFeedbackResult[]): void }>() @@ -24,7 +28,8 @@ // All questions should be answered feedback.value.some((v) => !v.assistantQuestion || !v.userAnswer) || // Should not be loading - isLoading.value, + isLoading.value || + props.isLoadingSearch, ) async function getFeedback(query: string, numQuestions = 3) { @@ -94,6 +99,7 @@ defineExpose({ getFeedback, clear, + isLoading, }) @@ -113,7 +119,13 @@ - + Submit Answer diff --git a/components/ResearchForm.vue b/components/ResearchForm.vue index da07681..f5bd43a 100644 --- a/components/ResearchForm.vue +++ b/components/ResearchForm.vue @@ -6,27 +6,31 @@ numQuestions: number } + defineProps<{ + isLoadingFeedback: boolean + }>() + const emit = defineEmits<{ (e: 'submit', value: ResearchInputData): void }>() - const input = ref('天空为什么是蓝的?') - const breadth = ref(2) - const depth = ref(2) - const numQuestions = ref(3) - const isLoading = ref(false) + const form = reactive({ + query: '', + breadth: 2, + depth: 2, + numQuestions: 3, + }) + + const isSubmitButtonDisabled = computed(() => !form.query || !form.breadth || !form.depth || !form.numQuestions) function handleSubmit() { emit('submit', { - query: input.value, - breadth: breadth.value, - depth: depth.value, - numQuestions: numQuestions.value, + ...form, }) } - onMounted(() => { - input.value = '天空为什么是蓝的?' // default + defineExpose({ + form, }) @@ -37,30 +41,30 @@
- +
- + - + - + - + - + - +
diff --git a/components/ResearchReport.vue b/components/ResearchReport.vue index 7ebcece..08a3774 100644 --- a/components/ResearchReport.vue +++ b/components/ResearchReport.vue @@ -10,7 +10,7 @@ const loading = ref(false) const loadingExportPdf = ref(false) const reportContent = ref('') - const reportHtml = computed(() => marked(reportContent.value)) + const reportHtml = computed(() => marked(reportContent.value, { gfm: true, silent: true })) const isExportButtonDisabled = computed(() => !reportContent.value || loading.value || loadingExportPdf.value) async function generateReport(params: CustomReportParams) { @@ -31,28 +31,52 @@ } async function exportToPdf() { + const element = document.getElementById('report-content') + if (!element) return + + // Create a temp container + const tempContainer = document.createElement('div') loadingExportPdf.value = true + try { - // 动态导入 html2pdf,确保只在客户端执行 + // Dinamically import html2pdf // @ts-ignore const html2pdf = (await import('html2pdf.js')).default - const element = document.getElementById('report-content') + tempContainer.innerHTML = element.innerHTML + tempContainer.className = element.className - 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' }, - } + // Use print-friendly styles + tempContainer.style.cssText = ` + font-family: Arial, sans-serif; + color: black; + background-color: white; + padding: 20px; + ` - await html2pdf().set(opt).from(element).save() + document.body.appendChild(tempContainer) + + const opt = { + margin: [10, 10], + filename: 'research-report.pdf', + image: { type: 'jpeg', quality: 0.98 }, + html2canvas: { + scale: 2, + useCORS: true, + backgroundColor: '#ffffff', + }, + jsPDF: { + unit: 'mm', + format: 'a4', + orientation: 'portrait', + }, } + + await html2pdf().set(opt).from(tempContainer).save() } catch (error) { console.error('Export to PDF failed:', error) } finally { + document.body.removeChild(tempContainer) loadingExportPdf.value = false } } diff --git a/pages/index.vue b/pages/index.vue index 4646240..279e3a2 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -6,8 +6,8 @@

Deep Research Assistant

- - + + @@ -16,6 +16,7 @@