Jelajahi Sumber

优化合并 pdf 功能

yemeishu 2 jam lalu
induk
melakukan
3e11b25bcf
2 mengubah file dengan 84 tambahan dan 11 penghapusan
  1. 56 8
      app/Services/ExamPdfExportService.php
  2. 28 3
      app/Services/PdfMerger.php

+ 56 - 8
app/Services/ExamPdfExportService.php

@@ -121,28 +121,76 @@ class ExamPdfExportService
             $examPdfPath = $tempDir . "/{$paperId}_exam.pdf";
             $gradingPdfPath = $tempDir . "/{$paperId}_grading.pdf";
 
-            // 下载试卷PDF
-            $examContent = Http::get($examPdfUrl)->body();
+            // 【修复】下载试卷PDF - 添加HTTP状态码检查
+            $examResponse = Http::get($examPdfUrl);
+            if (!$examResponse->successful()) {
+                Log::error('ExamPdfExportService: 下载试卷PDF失败', [
+                    'url' => $examPdfUrl,
+                    'status_code' => $examResponse->status()
+                ]);
+                return null;
+            }
+
+            $examContent = $examResponse->body();
             if (empty($examContent)) {
-                Log::error('ExamPdfExportService: 下载试卷PDF失败', ['url' => $examPdfUrl]);
+                Log::error('ExamPdfExportService: 下载试卷PDF内容为空', ['url' => $examPdfUrl]);
+                return null;
+            }
+
+            // 写入文件并验证
+            if (file_put_contents($examPdfPath, $examContent) === false) {
+                Log::error('ExamPdfExportService: 写入试卷PDF文件失败', ['path' => $examPdfPath]);
+                return null;
+            }
+
+            if (!file_exists($examPdfPath) || filesize($examPdfPath) === 0) {
+                Log::error('ExamPdfExportService: 试卷PDF文件无效', [
+                    'path' => $examPdfPath,
+                    'exists' => file_exists($examPdfPath),
+                    'size' => file_exists($examPdfPath) ? filesize($examPdfPath) : 'N/A'
+                ]);
                 return null;
             }
-            file_put_contents($examPdfPath, $examContent);
 
             if ($progressCallback) {
                 $progressCallback(50, '下载判卷PDF...');
             }
 
-            // 下载判卷PDF
-            $gradingContent = Http::get($gradingPdfUrl)->body();
+            // 【修复】下载判卷PDF - 添加HTTP状态码检查
+            $gradingResponse = Http::get($gradingPdfUrl);
+            if (!$gradingResponse->successful()) {
+                Log::error('ExamPdfExportService: 下载判卷PDF失败', [
+                    'url' => $gradingPdfUrl,
+                    'status_code' => $gradingResponse->status()
+                ]);
+                return null;
+            }
+
+            $gradingContent = $gradingResponse->body();
             if (empty($gradingContent)) {
-                Log::error('ExamPdfExportService: 下载判卷PDF失败', ['url' => $gradingPdfUrl]);
+                Log::error('ExamPdfExportService: 下载判卷PDF内容为空', ['url' => $gradingPdfUrl]);
+                return null;
+            }
+
+            // 写入文件并验证
+            if (file_put_contents($gradingPdfPath, $gradingContent) === false) {
+                Log::error('ExamPdfExportService: 写入判卷PDF文件失败', ['path' => $gradingPdfPath]);
+                return null;
+            }
+
+            if (!file_exists($gradingPdfPath) || filesize($gradingPdfPath) === 0) {
+                Log::error('ExamPdfExportService: 判卷PDF文件无效', [
+                    'path' => $gradingPdfPath,
+                    'exists' => file_exists($gradingPdfPath),
+                    'size' => file_exists($gradingPdfPath) ? filesize($gradingPdfPath) : 'N/A'
+                ]);
                 return null;
             }
-            file_put_contents($gradingPdfPath, $gradingContent);
 
             Log::info('PDF文件下载完成', [
+                'exam_path' => $examPdfPath,
                 'exam_size' => filesize($examPdfPath),
+                'grading_path' => $gradingPdfPath,
                 'grading_size' => filesize($gradingPdfPath)
             ]);
 

+ 28 - 3
app/Services/PdfMerger.php

@@ -287,18 +287,37 @@ class PdfMerger
 
     /**
      * 使用qpdf合并PDF(带进度回调)
-     * 【修复】qpdf命令格式问题 - 使用正确的页面范围语法
+     * 【修复】qpdf命令格式和文件验证问题
      * 正确格式:qpdf --empty --pages file1.pdf,file2.pdf -- output.pdf
      * qpdf会自动合并所有页面,无需手动指定页面范围
      */
     private function mergeWithQpdf(array $pdfPaths, string $outputPath, ?callable $progressCallback = null): bool
     {
+        // 【重要】验证输入文件是否存在
+        foreach ($pdfPaths as $index => $path) {
+            if (!file_exists($path)) {
+                Log::error('qpdf合并失败:PDF文件不存在', [
+                    'file_path' => $path,
+                    'file_index' => $index,
+                    'all_files' => $pdfPaths
+                ]);
+
+                if ($progressCallback) {
+                    $progressCallback(-1, "PDF文件不存在: " . basename($path));
+                }
+
+                return false;
+            }
+            Log::debug('qpdf验证文件存在', ['path' => $path, 'size' => filesize($path)]);
+        }
+
         // 【修复】构建正确的qpdf命令
         // qpdf --empty --pages file1.pdf,file2.pdf -- output.pdf
         // 注意:qpdf不需要手动指定页面范围,会自动合并所有页面
 
-        $pagesArg = implode(',', array_map('escapeshellarg', $pdfPaths));
-        $command = "qpdf --empty --pages {$pagesArg} -- -- " . escapeshellarg($outputPath);
+        // 直接使用文件路径,不使用escapeshellarg(避免单引号问题)
+        $pagesArg = implode(',', $pdfPaths);
+        $command = "qpdf --empty --pages {$pagesArg} -- -- {$outputPath}";
 
         Log::debug('执行qpdf命令', ['command' => $command]);
 
@@ -338,9 +357,15 @@ class PdfMerger
             'duration_ms' => $duration,
             'timeout_seconds' => $timeout,
             'command' => $command,
+            'input_files' => $pdfPaths,
+            'output_file' => $outputPath,
             'note' => 'qpdf会自动合并所有页面,不需要指定页面范围'
         ]);
 
+        if ($progressCallback) {
+            $progressCallback(-1, 'qpdf合并失败: ' . $output->errorOutput());
+        }
+
         return false;
     }
 }