defaultSort('id', 'asc') ->columns([ TextColumn::make('id')->label('ID')->sortable(), TextColumn::make('official_title')->label('教材名称')->searchable()->wrap(), TextColumn::make('series_name')->label('教材系列')->sortable(), TextColumn::make('stage') ->label('学段') ->sortable() ->formatStateUsing(fn ($state) => match ($state) { 'primary' => '小学', 'junior' => '初中', 'senior' => '高中', default => $state ?: '未标注', }), TextColumn::make('grade')->label('年级')->sortable(), TextColumn::make('semester')->label('学期')->sortable(), TextColumn::make('isbn')->label('ISBN')->toggleable(isToggledHiddenByDefault: true), TextColumn::make('status') ->label('状态') ->sortable() ->formatStateUsing(fn ($state) => match ($state) { 'draft' => '草稿', 'published' => '已发布', 'archived' => '已归档', default => $state ?: '未知', }), TextColumn::make('created_at') ->label('创建时间') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('updated_at') ->label('更新时间') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), ]) ->filters([ SelectFilter::make('stage') ->label('学段') ->options([ 'primary' => '小学', 'junior' => '初中', 'senior' => '高中', ]), SelectFilter::make('grade') ->label('年级') ->options(collect(range(1, 12))->mapWithKeys(fn ($grade) => [$grade => "{$grade}年级"])->all()), SelectFilter::make('semester') ->label('学期') ->options([ 1 => '上学期', 2 => '下学期', ]), SelectFilter::make('status') ->label('发布状态') ->options([ 'draft' => '草稿', 'published' => '已发布', 'archived' => '已归档', ]), Filter::make('keyword') ->label('关键词') ->form([ TextInput::make('value') ->placeholder('教材名称 / ISBN / 系列'), ]), ], layout: FiltersLayout::AboveContentCollapsible) ->actions([ EditAction::make() ->label('编辑') ->icon('heroicon-o-pencil-square') ->iconButton() ->tooltip('编辑'), Action::make('delete') ->label('删除') ->color('danger') ->icon('heroicon-o-trash') ->iconButton() ->tooltip('删除') ->requiresConfirmation() ->modalHeading('删除教材') ->modalDescription('确定要删除这个教材吗?此操作无法撤销。') ->action(function (Model $record) { // 添加调试日志 \Log::info('Deleting textbook', ['id' => $record->id, 'record' => $record]); if (!$record || !$record->id) { \Filament\Notifications\Notification::make() ->title('错误') ->body('无效的教材记录。') ->danger() ->send(); return; } $apiService = app(\App\Services\TextbookApiService::class); $deleted = $apiService->deleteTextbook($record->id); \Log::info('Delete result', ['deleted' => $deleted]); if ($deleted) { \Filament\Notifications\Notification::make() ->title('成功') ->body('教材删除成功。') ->success() ->send(); } else { \Filament\Notifications\Notification::make() ->title('错误') ->body('删除失败,请重试。') ->danger() ->send(); } }), Action::make('view_catalog') ->label('查看目录') ->icon('heroicon-o-list-bullet') ->iconButton() ->tooltip('查看目录') ->url(fn(Model $record): string => route('filament.admin.resources.textbook-catalogs.index', ['tableFilters[textbook_id][value]' => $record->id]) ), ]) ->bulkActions([ \Filament\Actions\BulkActionGroup::make([ \Filament\Actions\DeleteBulkAction::make() ->label('批量删除'), BulkAction::make('archive') ->label('批量归档') ->color('warning') ->icon('heroicon-o-archive-box') ->requiresConfirmation() ->action(function ($records): void { $apiService = app(\App\Services\TextbookApiService::class); foreach ($records as $record) { $apiService->updateTextbook((int) $record->id, ['status' => 'archived']); } }), ]), ]) ->recordUrl(fn (Model $record): string => route('filament.admin.resources.textbooks.view', $record)) ->defaultSort('sort_order') ->paginated([10, 25, 50, 100]); } }