feat: 初始化知识库系统项目

- 实现基于 Laravel 11 和 Filament 3.X 的文档管理系统
- 添加用户认证和分组管理功能
- 实现文档上传、分类和权限控制
- 集成 Word 文档自动转换为 Markdown
- 集成 Meilisearch 全文搜索引擎
- 实现文档在线预览功能
- 添加安全日志和审计功能
- 完整的简体中文界面
- 包含完整的项目文档和部署指南

技术栈:
- Laravel 11.x
- Filament 3.X
- Meilisearch 1.5+
- Pandoc 文档转换
- Redis 队列系统
- Pest PHP 测试框架
This commit is contained in:
Knowledge Base System
2025-12-05 14:44:44 +08:00
commit acf549c43c
165 changed files with 32838 additions and 0 deletions

View File

@@ -0,0 +1,94 @@
<?php
namespace App\Filament\Resources\DocumentResource\Pages;
use App\Filament\Resources\DocumentResource;
use Filament\Actions;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\EditRecord;
use Illuminate\Support\Facades\Storage;
class EditDocument extends EditRecord
{
protected static string $resource = DocumentResource::class;
protected function getHeaderActions(): array
{
return [
Actions\ViewAction::make()
->label('查看'),
Actions\DeleteAction::make()
->label('删除'),
];
}
protected function mutateFormDataBeforeFill(array $data): array
{
// 将文件路径设置到 file 字段以便显示
if (isset($data['file_path'])) {
$data['file'] = $data['file_path'];
}
return $data;
}
protected function mutateFormDataBeforeSave(array $data): array
{
// 如果是全局文档,确保 group_id 为 null
if ($data['type'] === 'global') {
$data['group_id'] = null;
}
// 处理文件更新
if (isset($data['file']) && $data['file'] !== $this->record->file_path) {
$filePath = $data['file'];
// 删除旧的 Word 文件
if ($this->record->file_path && Storage::disk('local')->exists($this->record->file_path)) {
Storage::disk('local')->delete($this->record->file_path);
}
// 删除旧的 Markdown 文件
if ($this->record->markdown_path && Storage::disk('markdown')->exists($this->record->markdown_path)) {
Storage::disk('markdown')->delete($this->record->markdown_path);
}
// 获取原始文件名(由于使用了 preserveFilenames()basename 就是原始文件名)
$originalFileName = basename($filePath);
// 更新文件信息
$data['file_path'] = $filePath;
$data['file_name'] = $originalFileName; // 保存原始文件名
$data['file_size'] = Storage::disk('local')->size($filePath);
$data['mime_type'] = Storage::disk('local')->mimeType($filePath);
// 重置转换状态,准备重新转换
$data['conversion_status'] = 'pending';
$data['markdown_path'] = null;
$data['markdown_preview'] = null;
$data['conversion_error'] = null;
}
// 移除临时的 file 字段
unset($data['file']);
return $data;
}
protected function afterSave(): void
{
// 如果文档的转换状态是 pending说明文件已更新需要触发重新转换
if ($this->record->conversion_status === 'pending') {
$conversionService = app(\App\Services\DocumentConversionService::class);
$conversionService->queueConversion($this->record);
}
}
protected function getSavedNotification(): ?Notification
{
return Notification::make()
->success()
->title('文档更新成功')
->body('文档信息已成功更新。');
}
}