columns([ TextColumn::make('author_name') ->label('作者') ->searchable() ->weight('bold'), TextColumn::make('content') ->label('内容') ->limit(60) ->searchable(), TextColumn::make('post.title') ->label('文章') ->limit(30) ->description(fn ($record) => $record->post ? \Illuminate\Support\Str::limit($record->post->excerpt_or_fallback, 50) : null) ->url(fn ($record) => $record->post ? route('posts.show', $record->post->id) : null) ->openUrlInNewTab(), TextColumn::make('status') ->label('状态') ->badge() ->formatStateUsing(fn ($state) => match ($state) { 'published' => '已发布', 'pending' => '待审核', 'spam' => '垃圾', 'rejected' => '已拒绝', default => $state, }) ->color(fn ($state) => match ($state) { 'published' => 'success', 'pending' => 'warning', 'spam' => 'danger', default => 'gray', }), TextColumn::make('ip') ->label('IP'), TextColumn::make('created_at') ->label('时间') ->dateTime('Y-m-d H:i') ->sortable(), ]) ->filters([ SelectFilter::make('status') ->label('状态') ->options([ 'published' => '已发布', 'pending' => '待审核', 'spam' => '垃圾', 'rejected' => '已拒绝', ]), ], \Filament\Tables\Enums\FiltersLayout::AboveContent) ->recordActions([ Action::make('approve') ->label('通过') ->icon('heroicon-o-check') ->color('success') ->visible(fn (Comment $record) => $record->status !== 'published') ->action(function (Comment $record): void { $record->update(['status' => 'published']); $record->post?->increment('comment_count'); Notification::make()->title('评论已通过')->success()->send(); }), Action::make('spam') ->label('垃圾') ->icon('heroicon-o-x-mark') ->color('danger') ->visible(fn (Comment $record) => $record->status !== 'spam') ->action(function (Comment $record): void { if ($record->status === 'published') { $record->post?->decrement('comment_count'); } $record->update(['status' => 'spam']); Notification::make()->title('已标记为垃圾评论')->success()->send(); }), Action::make('notSpam') ->label('非垃圾') ->icon('heroicon-o-check-badge') ->color('success') ->requiresConfirmation() ->modalHeading('标记为非垃圾') ->modalDescription('该评论将恢复为已发布状态。') ->visible(fn (Comment $record) => $record->status === 'spam') ->action(function (Comment $record): void { $record->update(['status' => 'published']); $record->post?->increment('comment_count'); Notification::make()->title('已恢复发布')->success()->send(); }), EditAction::make(), ]) ->recordUrl(null) ->recordAction(null) ->toolbarActions([ Action::make('purgeSpam') ->label('清空垃圾评论') ->icon('heroicon-o-trash') ->color('danger') ->requiresConfirmation() ->modalHeading('清空垃圾评论') ->modalDescription(fn (): string => '将永久删除全部 '.Comment::query()->where('status', 'spam')->count().' 条垃圾评论,不可恢复。') ->visible(fn (): bool => Comment::query()->where('status', 'spam')->exists()) ->action(function (): void { $count = Comment::query()->where('status', 'spam')->count(); Comment::query()->where('status', 'spam')->delete(); Notification::make()->title("已删除 {$count} 条垃圾评论")->success()->send(); }), BulkActionGroup::make([ BulkAction::make('markSpam') ->label('标为垃圾') ->icon('heroicon-o-x-mark') ->color('danger') ->requiresConfirmation() ->action(function (Collection $records): void { $records->each(function (Comment $record): void { if ($record->status === 'published') { $record->post?->decrement('comment_count'); } $record->update(['status' => 'spam']); }); Notification::make()->title('已标记 '.$records->count().' 条为垃圾评论')->success()->send(); }), DeleteBulkAction::make(), ]), ]) ->defaultSort('created_at', 'desc'); } }