fix: use pdf previews for documents

This commit is contained in:
2026-05-19 08:44:35 +08:00
parent 7e5a6a3f39
commit 63f2827cc9
14 changed files with 399 additions and 345 deletions

View File

@@ -1,19 +1,13 @@
@php
use App\Services\DocumentPreviewService;
$previewService = app(DocumentPreviewService::class);
$htmlContent = null;
$error = null;
try {
$htmlContent = $previewService->convertToHtml($document);
} catch (\Exception $e) {
$error = $e->getMessage();
}
use App\Services\DocumentPdfPreviewService;
$previewService = app(DocumentPdfPreviewService::class);
$canPreview = $previewService->canPreview($document);
$previewUrl = $canPreview ? $previewService->previewUrl($document) : null;
@endphp
<div class="document-preview-modal">
@if ($error)
@if (! $canPreview)
<div class="rounded-lg bg-danger-50 p-4 text-danger-600 dark:bg-danger-400/10 dark:text-danger-400">
<div class="flex items-center gap-3">
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
@@ -21,81 +15,29 @@
</svg>
<div>
<p class="font-semibold">预览失败</p>
<p class="text-sm">{{ $error }}</p>
<p class="text-sm">该文档尚未完成转换或原文件不存在</p>
</div>
</div>
</div>
@elseif ($htmlContent)
@elseif ($previewUrl)
<div class="rounded-lg border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-800">
<div class="border-b border-gray-200 bg-gray-50 px-4 py-3 dark:border-gray-700 dark:bg-gray-900">
<div class="flex items-center justify-between">
<h3 class="text-sm font-medium text-gray-700 dark:text-gray-300">
文档内容预览
PDF 内容预览
</h3>
<span class="text-xs text-gray-500 dark:text-gray-400">
{{ $document->display_file_name }}
</span>
</div>
</div>
<div class="max-h-[600px] overflow-y-auto p-6">
<div class="prose prose-sm max-w-none dark:prose-invert">
{!! $htmlContent !!}
</div>
</div>
<div class="border-t border-gray-200 bg-gray-50 px-4 py-3 dark:border-gray-700 dark:bg-gray-900">
<p class="text-xs text-gray-500 dark:text-gray-400">
提示:这是文档的预览版本,可能与原始格式略有差异。如需查看完整格式,请下载文档。
</p>
</div>
</div>
@else
<div class="rounded-lg bg-gray-50 p-4 text-gray-600 dark:bg-gray-800 dark:text-gray-400">
<div class="flex items-center gap-3">
<svg class="h-5 w-5 animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
<p>正在加载文档预览...</p>
</div>
<iframe
class="w-full rounded-b-lg bg-gray-100 dark:bg-gray-950"
style="height: min(82vh, 960px); min-height: 720px;"
src="{{ $previewUrl }}"
title="{{ $document->title }} PDF 预览"
></iframe>
</div>
@endif
</div>
<style>
.document-preview-modal .prose {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
}
.document-preview-modal .prose table {
width: 100%;
border-collapse: collapse;
margin: 1em 0;
}
.document-preview-modal .prose table td,
.document-preview-modal .prose table th {
border: 1px solid #e5e7eb;
padding: 0.5em;
}
.document-preview-modal .prose table th {
background-color: #f9fafb;
font-weight: 600;
}
.document-preview-modal .prose img {
max-width: 100%;
height: auto;
}
.dark .document-preview-modal .prose table td,
.dark .document-preview-modal .prose table th {
border-color: #374151;
}
.dark .document-preview-modal .prose table th {
background-color: #1f2937;
}
</style>

View File

@@ -1,18 +1,9 @@
@php
use App\Services\DocumentPreviewService;
use App\Services\DocumentPdfPreviewService;
$previewService = app(DocumentPreviewService::class);
$previewService = app(DocumentPdfPreviewService::class);
$canPreview = $previewService->canPreview($document);
$htmlContent = null;
$error = null;
if ($canPreview) {
try {
$htmlContent = $previewService->convertToHtml($document);
} catch (\Exception $e) {
$error = $e->getMessage();
}
}
$previewUrl = $canPreview ? $previewService->previewUrl($document) : null;
@endphp
<div class="document-preview-container">
@@ -37,7 +28,7 @@
<p>文档等待转换中...</p>
</div>
</div>
@elseif ($error)
@elseif (! $canPreview)
<div class="rounded-lg bg-danger-50 p-4 text-danger-600 dark:bg-danger-400/10 dark:text-danger-400">
<div class="flex items-center gap-3">
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
@@ -45,16 +36,16 @@
</svg>
<div>
<p class="font-semibold">预览加载失败</p>
<p class="text-sm">{{ $error }}</p>
<p class="text-sm">该文档尚未完成转换或原文件不存在</p>
</div>
</div>
</div>
@elseif ($htmlContent)
@elseif ($previewUrl)
<div class="rounded-lg border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-800">
<div class="border-b border-gray-200 bg-gray-50 px-4 py-3 dark:border-gray-700 dark:bg-gray-900">
<div class="flex items-center justify-between">
<h3 class="text-sm font-medium text-gray-700 dark:text-gray-300">
文档内容预览
PDF 内容预览
</h3>
<span class="text-xs text-gray-500 dark:text-gray-400">
{{ $document->display_file_name }}
@@ -62,48 +53,12 @@
</div>
</div>
<div class="max-h-[600px] overflow-y-auto p-6">
<div class="prose prose-sm max-w-none dark:prose-invert">
{!! $htmlContent !!}
</div>
</div>
<iframe
class="w-full rounded-b-lg bg-gray-100 dark:bg-gray-950"
style="height: min(82vh, 960px); min-height: 720px;"
src="{{ $previewUrl }}"
title="{{ $document->title }} PDF 预览"
></iframe>
</div>
@endif
</div>
<style>
.document-preview-container .prose {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
}
.document-preview-container .prose table {
width: 100%;
border-collapse: collapse;
margin: 1em 0;
}
.document-preview-container .prose table td,
.document-preview-container .prose table th {
border: 1px solid #e5e7eb;
padding: 0.5em;
}
.document-preview-container .prose table th {
background-color: #f9fafb;
font-weight: 600;
}
.document-preview-container .prose img {
max-width: 100%;
height: auto;
}
.dark .document-preview-container .prose table td,
.dark .document-preview-container .prose table th {
border-color: #374151;
}
.dark .document-preview-container .prose table th {
background-color: #1f2937;
}
</style>