document = $document; $this->tries = config('documents.conversion.retry_times', 3); $this->timeout = config('documents.conversion.timeout', 300); $this->backoff = config('documents.conversion.retry_delay', 60); } /** * 执行任务 * * @param DocumentConversionService $conversionService * @return void */ public function handle(DocumentConversionService $conversionService): void { try { Log::info('开始转换文档', [ 'document_id' => $this->document->id, 'document_title' => $this->document->title, 'attempt' => $this->attempts(), ]); // 转换文档为 Markdown $result = $conversionService->convertToMarkdown($this->document); $markdown = $result['markdown']; $mediaDir = $result['mediaDir'] ?? null; $tempDir = $result['tempDir']; try { // 保存 Markdown 文件和媒体文件 $markdownPath = $conversionService->saveMarkdownToFile($this->document, $markdown, $mediaDir); // 更新文档的 Markdown 信息 $conversionService->updateDocumentMarkdown($this->document, $markdownPath); } finally { // 清理临时目录 if (isset($tempDir) && file_exists($tempDir)) { $this->deleteDirectory($tempDir); } } Log::info('文档转换成功', [ 'document_id' => $this->document->id, 'document_title' => $this->document->title, 'markdown_path' => $markdownPath, ]); // 转换成功后,触发索引(如果需要) // 这将在后续任务中实现 // $this->document->searchable(); } catch (\Exception $e) { Log::error('文档转换失败', [ 'document_id' => $this->document->id, 'document_title' => $this->document->title, 'attempt' => $this->attempts(), 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), ]); // 如果已达到最大重试次数,标记为失败 if ($this->attempts() >= $this->tries) { $conversionService->handleConversionFailure($this->document, $e); } // 重新抛出异常以触发重试 throw $e; } } /** * 任务失败时的处理 * * @param \Throwable $exception * @return void */ public function failed(\Throwable $exception): void { Log::error('文档转换任务最终失败', [ 'document_id' => $this->document->id, 'document_title' => $this->document->title, 'error' => $exception->getMessage(), ]); // 确保文档状态被标记为失败 $conversionService = app(DocumentConversionService::class); $conversionService->handleConversionFailure( $this->document, $exception instanceof \Exception ? $exception : new \Exception($exception->getMessage()) ); } /** * 递归删除目录 * * @param string $dir 目录路径 * @return void */ protected function deleteDirectory(string $dir): void { if (!file_exists($dir)) { return; } if (!is_dir($dir)) { unlink($dir); return; } $files = array_diff(scandir($dir), ['.', '..']); foreach ($files as $file) { $path = $dir . '/' . $file; if (is_dir($path)) { $this->deleteDirectory($path); } else { unlink($path); } } rmdir($dir); } }