schema([ Forms\Components\TextInput::make('title')->label('标题'), Forms\Components\Select::make('type') ->label('题型') ->options([ 'choice' => '选择题', 'fill' => '填空题', 'answer' => '解答题', 'mixed' => '混合', ]), Forms\Components\TextInput::make('question_count')->label('题量')->numeric(), 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('paper.title')->label('卷子'), Tables\Columns\TextColumn::make('order')->label('顺序')->sortable(), Tables\Columns\TextInputColumn::make('title')->label('区块标题')->searchable(), Tables\Columns\SelectColumn::make('type') ->label('题型') ->options([ 'choice' => '选择题', 'fill' => '填空题', 'answer' => '解答题', 'mixed' => '混合', ]), Tables\Columns\TextInputColumn::make('question_count') ->label('题量(人工)') ->type('number'), Tables\Columns\TextColumn::make('candidates_count') ->counts('candidates') ->label('题量(自动)'), Tables\Columns\TextColumn::make('question_delta') ->label('差异') ->getStateUsing(fn (PaperPart $record) => ($record->question_count ?? 0) - ($record->candidates_count ?? $record->candidates()->count())) ->badge() ->color(fn (PaperPart $record) => (($record->question_count ?? 0) - ($record->candidates_count ?? $record->candidates()->count())) === 0 ? 'success' : 'warning'), ]) ->filters([ Tables\Filters\SelectFilter::make('source_paper_id') ->label('卷子') ->options(function () { return \App\Models\SourcePaper::query() ->orderByDesc('id') ->get(['id', 'title', 'full_title']) ->mapWithKeys(function ($paper) { $label = $paper->title ?: $paper->full_title ?: '未命名卷子'; return [$paper->id => $label]; }) ->toArray(); }), ]) ->actions([ ViewAction::make(), ]) ->bulkActions([ BulkAction::make('bulk_type') ->label('批量设置题型') ->form([ Forms\Components\Select::make('type') ->label('题型') ->options([ 'choice' => '选择题', 'fill' => '填空题', 'answer' => '解答题', 'mixed' => '混合', ]) ->required(), ]) ->action(function (array $data, $records) { foreach ($records as $record) { $record->update(['type' => $data['type']]); } }), ]) ->recordClasses(fn (PaperPart $record) => ($record->question_count ?? 0) !== ($record->candidates_count ?? $record->candidates()->count()) ? 'bg-amber-50' : null); } public static function getRelations(): array { return [ PreQuestionCandidatesRelationManager::class, ]; } public static function getPages(): array { return [ 'index' => Pages\ListPaperParts::route('/'), 'view' => Pages\ViewPaperPart::route('/{record}'), ]; } }