schema([ Forms\Components\TextInput::make('title')->label('标题')->disabled(), Forms\Components\TextInput::make('full_title')->label('完整标题')->disabled(), Forms\Components\TextInput::make('chapter')->label('章节')->disabled(), Forms\Components\TextInput::make('grade')->label('年级')->disabled(), Forms\Components\TextInput::make('term')->label('学期')->disabled(), Forms\Components\Textarea::make('raw_markdown') ->label('卷子原始 Markdown') ->rows(12) ->disabled(), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('order')->label('顺序')->sortable(), Tables\Columns\TextColumn::make('title')->label('卷标题')->searchable(), Tables\Columns\TextColumn::make('file.original_filename')->label('来源文件')->toggleable(), Tables\Columns\TextColumn::make('grade')->label('年级'), Tables\Columns\TextColumn::make('term')->label('学期'), Tables\Columns\TextColumn::make('source_type')->label('类型'), Tables\Columns\TextColumn::make('parts_sum_question_count') ->label('题量') ->getStateUsing(fn (Model $record) => $record->parts_sum_question_count ?? 0) ->sortable(), Tables\Columns\TextColumn::make('parts_count') ->label('区块数') ->getStateUsing(fn (Model $record) => $record->parts_count ?? 0) ->sortable(), ]) ->filters([ SelectFilter::make('grade') ->label('年级') ->options(collect(range(1, 12))->mapWithKeys(fn ($grade) => [$grade => "{$grade}年级"])->all()), SelectFilter::make('term') ->label('学期') ->options([ '上学期' => '上学期', '下学期' => '下学期', ]), SelectFilter::make('source_type') ->label('来源类型') ->options([ 'textbook' => '教材', 'exam' => '考试', 'other' => '其他', ]), Filter::make('question_range') ->label('题量范围') ->form([ TextInput::make('min')->placeholder('最小题量')->numeric(), TextInput::make('max')->placeholder('最大题量')->numeric(), ]) ->query(function (Builder $query, array $data) { $min = $data['min'] ?? null; $max = $data['max'] ?? null; if ($min !== null && $min !== '') { $query->having('parts_sum_question_count', '>=', (int) $min); } if ($max !== null && $max !== '') { $query->having('parts_sum_question_count', '<=', (int) $max); } }), ], layout: FiltersLayout::AboveContentCollapsible) ->actions([ ViewAction::make() ->icon('heroicon-o-eye') ->iconButton() ->tooltip('查看详情'), ]) ->recordUrl(fn (Model $record): string => route('filament.admin.resources.source-papers.view', $record)); } public static function getRelations(): array { return [ PaperPartsRelationManager::class, PreQuestionCandidatesRelationManager::class, ]; } public static function getPages(): array { return [ 'index' => Pages\ListSourcePapers::route('/'), 'view' => Pages\ViewSourcePaper::route('/{record}'), ]; } public static function getEloquentQuery(): Builder { return parent::getEloquentQuery() ->with(['file']) ->withCount(['parts', 'candidates']) ->withSum('parts', 'question_count'); } }