| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- <?php
- namespace App\Filament\Resources;
- use App\Filament\Resources\TextbookCatalogResource\Pages;
- use App\Models\TextbookCatalog;
- use App\Services\TextbookApiService;
- use BackedEnum;
- use UnitEnum;
- use Filament\Resources\Resource;
- use Filament\Tables;
- use Filament\Tables\Columns\TextColumn;
- use Filament\Tables\Columns\BadgeColumn;
- use Filament\Actions\EditAction;
- use Filament\Actions\DeleteAction;
- use Illuminate\Database\Eloquent\Model;
- class TextbookCatalogResource extends Resource
- {
- protected static ?string $model = ApiTextbookCatalog::class;
- protected static ?string $recordTitleAttribute = 'title';
- protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-squares-2x2';
- protected static ?string $navigationLabel = '教材目录';
- protected static UnitEnum|string|null $navigationGroup = '教材管理';
- protected static ?int $navigationSort = 3;
- protected static ?TextbookApiService $apiService = null;
- public static function boot()
- {
- parent::boot();
- static::$apiService = app(TextbookApiService::class);
- }
- protected static function getApiService(): TextbookApiService
- {
- if (!static::$apiService) {
- static::$apiService = app(TextbookApiService::class);
- }
- return static::$apiService;
- }
- public static function table(Tables\Table $table): Tables\Table
- {
- return $table
- ->columns([
- TextColumn::make('textbook.official_title')
- ->label('教材')
- ->searchable()
- ->wrap(),
- TextColumn::make('title')
- ->label('目录标题')
- ->searchable()
- ->wrap(),
- TextColumn::make('display_no')
- ->label('编号')
- ->searchable(),
- BadgeColumn::make('node_type')
- ->label('类型')
- ->formatStateUsing(fn (string $state): string => match ($state) {
- 'chapter' => '章',
- 'section' => '节',
- 'subsection' => '小节',
- 'item' => '条目',
- 'project' => '项目学习',
- 'reading' => '阅读材料',
- 'practice' => '综合实践',
- 'summary' => '复习',
- 'appendix' => '附录',
- default => '其他',
- })
- ->color('info'),
- TextColumn::make('depth')
- ->label('层级')
- ->sortable(),
- TextColumn::make('page_start')
- ->label('起始页码')
- ->sortable(),
- TextColumn::make('page_end')
- ->label('结束页码')
- ->sortable(),
- TextColumn::make('created_at')
- ->label('创建时间')
- ->dateTime('Y-m-d H:i')
- ->sortable()
- ->toggleable(),
- ])
- ->filters([
- Tables\Filters\SelectFilter::make('textbook_id')
- ->label('教材')
- ->options(function () {
- $textbooks = static::getApiService()->getTextbooks();
- $options = [];
- foreach ($textbooks['data'] ?? [] as $t) {
- $options[$t['id']] = $t['official_title'];
- }
- return $options;
- })
- ->searchable()
- ->preload(),
- Tables\Filters\SelectFilter::make('node_type')
- ->label('节点类型')
- ->options([
- 'chapter' => '章',
- 'section' => '节',
- 'subsection' => '小节',
- 'item' => '条目',
- 'project' => '项目学习',
- 'reading' => '阅读材料',
- 'practice' => '综合实践',
- 'summary' => '复习',
- 'appendix' => '附录',
- 'custom' => '其他',
- ]),
- ])
- ->actions([
- EditAction::make()
- ->label('编辑'),
- DeleteAction::make()
- ->label('删除'),
- ])
- ->paginated([10, 25, 50, 100])
- ->poll(null); // 禁用自动刷新
- }
- public static function getEloquentQuery(): \Illuminate\Database\Eloquent\builder
- {
- // 完全不使用数据库查询,所有数据通过 API 获取
- // 强制使用 migrations 表,这个表肯定存在
- return parent::getEloquentQuery()->from('migrations')->whereRaw('1=0');
- }
- public static function getRecord(?string $key): ?Model
- {
- // 教材目录是嵌套数据,需要根据 textbook_id 获取
- $textbookId = request()->get('textbook_id');
- if (!$textbookId) {
- return null;
- }
- $catalog = static::getApiService()->getTextbookCatalog((int) $textbookId, 'flat');
- foreach ($catalog as $node) {
- if ($node['id'] == $key) {
- return new ApiTextbookCatalog($node);
- }
- }
- return null;
- }
- public static function getRecords(): array
- {
- $textbookId = request()->get('tableFilters.textbook_id.value');
- if (!$textbookId) {
- return [];
- }
- $catalog = static::getApiService()->getTextbookCatalog((int) $textbookId, 'flat');
- $records = [];
- foreach ($catalog as $node) {
- $records[] = new ApiTextbookCatalog($node);
- }
- return $records;
- }
- public static function getPages(): array
- {
- return [
- 'index' => Pages\ManageTextbookCatalogs::route('/'),
- ];
- }
- public static function canViewAny(): bool
- {
- // 临时允许所有用户查看,等待权限系统完善
- return true;
- }
- public static function canCreate(): bool
- {
- // 临时允许所有用户创建,等待权限系统完善
- return true;
- }
- public static function canEdit(Model $record): bool
- {
- // 临时允许所有用户编辑,等待权限系统完善
- return true;
- }
- public static function canDelete(Model $record): bool
- {
- // 临时允许所有用户删除,等待权限系统完善
- return true;
- }
- public static function canDeleteAny(): bool
- {
- // 临时允许所有用户批量删除,等待权限系统完善
- return true;
- }
- protected static function deleteRecord(Model $record): bool
- {
- // 删除记录时,同时通过 API 删除题库服务中的数据
- return static::getApiService()->deleteTextbookCatalog($record->id);
- }
- }
- /**
- * API 教材目录模型 - 完全通过 API 获取数据
- * 这个类继承自 Model 但不执行任何数据库查询
- */
- class ApiTextbookCatalog extends \Illuminate\Database\Eloquent\Model
- {
- protected $table = 'migrations'; // 使用肯定存在的表
- // 禁用时间戳
- public $timestamps = false;
- // 禁用所有fillable检查
- protected $guarded = [];
- public function __construct(array $attributes = [])
- {
- parent::__construct($attributes);
- }
- }
|