Files
KnowledgeBase/app/Observers/DocumentObserver.php

138 lines
4.3 KiB
PHP
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.
<?php
namespace App\Observers;
use App\Models\Document;
use App\Services\DocumentSearchService;
/**
* 文档观察者
* 监听文档模型事件,自动管理 Meilisearch 索引
*/
class DocumentObserver
{
protected DocumentSearchService $searchService;
public function __construct(DocumentSearchService $searchService)
{
$this->searchService = $searchService;
}
/**
* 处理文档 "created" 事件
* 注意:文档创建时不立即索引,等待转换完成后再索引
*/
public function created(Document $document): void
{
// 文档创建时不立即索引,因为 Markdown 内容还未生成
// 索引将在转换完成后通过 updated 事件触发
}
/**
* 处理文档 "updated" 事件
* 当文档更新时,检查转换状态并更新索引
*/
public function updated(Document $document): void
{
// 检查转换状态是否变为 completed
if ($document->wasChanged('conversion_status') && $document->conversion_status === 'completed') {
// 转换完成,创建或更新索引
$this->searchService->indexDocument($document);
} elseif ($document->wasChanged(['title', 'description', 'markdown_path', 'knowledge_base_id'])) {
// 其他重要字段更新时,也更新索引
$this->searchService->updateDocumentIndex($document);
}
}
/**
* 处理文档 "deleting" 事件
* 在删除前清理相关文件
*/
public function deleting(Document $document): void
{
$this->cleanupDocumentFiles($document);
}
/**
* 处理文档 "deleted" 事件
* 从 Meilisearch 中移除文档索引
*/
public function deleted(Document $document): void
{
$this->searchService->removeDocumentFromIndex($document);
}
/**
* 处理文档 "restored" 事件
* 恢复文档时重新索引
*/
public function restored(Document $document): void
{
if ($document->shouldBeSearchable()) {
$this->searchService->indexDocument($document);
}
}
/**
* 处理文档 "force deleting" 事件
* 在强制删除前清理相关文件
*/
public function forceDeleting(Document $document): void
{
$this->cleanupDocumentFiles($document);
}
/**
* 处理文档 "force deleted" 事件
* 强制删除时也要移除索引
*/
public function forceDeleted(Document $document): void
{
$this->searchService->removeDocumentFromIndex($document);
}
/**
* 清理文档相关的所有文件
* 包括原始文档文件、Markdown 文件和媒体文件
*
* @param Document $document
* @return void
*/
protected function cleanupDocumentFiles(Document $document): void
{
try {
// 删除原始文档文件
if ($document->file_path && \Storage::disk('local')->exists($document->file_path)) {
\Storage::disk('local')->delete($document->file_path);
\Log::info('已删除原始文档文件', [
'document_id' => $document->id,
'file_path' => $document->file_path,
]);
}
// 删除 Markdown 文件和整个文档目录(包括 media
if ($document->markdown_path) {
// 获取文档目录例如2025/12/04/{uuid}
$documentDir = dirname($document->markdown_path);
// 删除整个文档目录(包括 Markdown 文件和 media 目录)
if (\Storage::disk('markdown')->exists($documentDir)) {
\Storage::disk('markdown')->deleteDirectory($documentDir);
\Log::info('已删除文档目录', [
'document_id' => $document->id,
'directory' => $documentDir,
]);
}
}
app(\App\Services\DocumentPdfPreviewService::class)->clearCachedPreview($document);
} catch (\Exception $e) {
\Log::error('清理文档文件失败', [
'document_id' => $document->id,
'error' => $e->getMessage(),
]);
// 不抛出异常,避免影响删除操作
}
}
}