form->fill([ 'searchQuery' => '', 'documentType' => null, 'groupId' => null, ]); } /** * 定义搜索表单 */ public function form(Form $form): Form { return $form ->schema([ TextInput::make('searchQuery') ->label('搜索关键词') ->placeholder('请输入搜索关键词...') ->required() ->maxLength(255), Select::make('documentType') ->label('文档类型') ->placeholder('全部类型') ->options([ 'global' => '全局知识库', 'dedicated' => '专用知识库', ]) ->native(false), Select::make('groupId') ->label('所属分组') ->placeholder('全部分组') ->options(Group::pluck('name', 'id')) ->searchable() ->native(false), ]) ->columns(3); } /** * 定义搜索结果表格 */ public function table(Table $table): Table { return $table ->query($this->getTableQuery()) ->columns([ TextColumn::make('title') ->label('文档标题') ->searchable() ->sortable() ->limit(50), TextColumn::make('markdown_preview') ->label('内容片段') ->limit(100) ->wrap() ->default('暂无内容预览'), TextColumn::make('type') ->label('文档类型') ->badge() ->formatStateUsing(fn (string $state): string => match ($state) { 'global' => '全局知识库', 'dedicated' => '专用知识库', default => $state, }) ->color(fn (string $state): string => match ($state) { 'global' => 'success', 'dedicated' => 'info', default => 'gray', }), TextColumn::make('group.name') ->label('所属分组') ->default('无') ->sortable(), TextColumn::make('created_at') ->label('上传时间') ->dateTime('Y-m-d H:i') ->sortable(), ]) ->actions([ Action::make('preview') ->label('预览') ->icon('heroicon-o-eye') ->color('info') ->modalHeading(fn (Document $record) => $record->title) ->modalContent(fn (Document $record) => view('filament.pages.document-preview-modal', [ 'document' => $record, ])) ->modalWidth('7xl') ->modalSubmitAction(false) ->modalCancelActionLabel('关闭') ->visible(fn (Document $record) => $record->conversion_status === 'completed'), Action::make('download') ->label('下载') ->icon('heroicon-o-arrow-down-tray') ->action(function (Document $record) { try { $documentService = app(DocumentService::class); $user = Auth::user(); // 记录下载日志 $documentService->logDownload($record, $user); // 返回文件下载响应 return $documentService->downloadDocument($record, $user); } catch (\Exception $e) { Notification::make() ->title('下载失败') ->body($e->getMessage()) ->danger() ->send(); } }), ]) ->paginated([10, 25, 50, 100]) ->defaultPaginationPageOption(25) ->emptyStateHeading('暂无搜索结果') ->emptyStateDescription('请输入搜索关键词并点击搜索按钮') ->emptyStateIcon('heroicon-o-magnifying-glass'); } /** * 获取表格查询构建器 */ protected function getTableQuery(): Builder { if (!$this->hasSearched || empty($this->searchQuery)) { // 如果还没有搜索或搜索关键词为空,返回空查询 return Document::query()->whereRaw('1 = 0'); } // 使用 DocumentSearchService 进行搜索 $searchService = app(DocumentSearchService::class); $user = Auth::user(); $filters = []; if ($this->documentType) { $filters['type'] = $this->documentType; } if ($this->groupId) { $filters['group_id'] = $this->groupId; } // 执行搜索 $results = $searchService->search($this->searchQuery, $user, $filters); // 获取搜索结果的 ID 列表 $documentIds = $results->pluck('id')->toArray(); // 返回包含这些 ID 的查询构建器 if (empty($documentIds)) { return Document::query()->whereRaw('1 = 0'); } return Document::query() ->whereIn('id', $documentIds) ->with(['group', 'uploader']); } /** * 执行搜索 */ public function search(): void { // 验证表单 $data = $this->form->getState(); // 检查搜索关键词是否为空 if (empty($data['searchQuery'])) { Notification::make() ->title('请输入搜索关键词') ->warning() ->send(); return; } // 更新搜索参数 $this->searchQuery = $data['searchQuery']; $this->documentType = $data['documentType']; $this->groupId = $data['groupId']; $this->hasSearched = true; // 重置表格分页 $this->resetTable(); Notification::make() ->title('搜索完成') ->success() ->send(); } /** * 清空搜索 */ public function clearSearch(): void { $this->form->fill([ 'searchQuery' => '', 'documentType' => null, 'groupId' => null, ]); $this->searchQuery = null; $this->documentType = null; $this->groupId = null; $this->hasSearched = false; $this->resetTable(); Notification::make() ->title('已清空搜索') ->success() ->send(); } /** * 获取页面头部操作 */ protected function getHeaderActions(): array { return []; } }