TextbookCatalogResource.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <?php
  2. namespace App\Filament\Resources;
  3. use App\Filament\Resources\TextbookCatalogResource\Pages;
  4. use App\Models\Textbook;
  5. use App\Models\TextbookCatalog;
  6. use BackedEnum;
  7. use UnitEnum;
  8. use Filament\Resources\Resource;
  9. use Filament\Forms\Components;
  10. use Filament\Schemas\Schema;
  11. use Filament\Tables;
  12. use Filament\Tables\Columns\TextColumn;
  13. use Filament\Tables\Columns\BadgeColumn;
  14. use Filament\Actions\EditAction;
  15. use Filament\Actions\DeleteAction;
  16. use Filament\Actions\Action;
  17. use Illuminate\Database\Eloquent\Model;
  18. class TextbookCatalogResource extends Resource
  19. {
  20. protected static ?string $model = TextbookCatalog::class;
  21. protected static ?string $recordTitleAttribute = 'title';
  22. protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-squares-2x2';
  23. protected static ?string $navigationLabel = '教材目录';
  24. protected static UnitEnum|string|null $navigationGroup = '教材管理';
  25. protected static ?int $navigationSort = 3;
  26. public static function form(Schema $schema): Schema
  27. {
  28. return $schema->components([
  29. Components\Select::make('textbook_id')
  30. ->label('教材')
  31. ->options(
  32. Textbook::query()
  33. ->orderBy('id')
  34. ->get(['id', 'official_title'])
  35. ->mapWithKeys(function ($textbook) {
  36. $label = $textbook->official_title ?: '未命名教材';
  37. return [$textbook->id => $label];
  38. })
  39. ->toArray()
  40. )
  41. ->searchable()
  42. ->required(),
  43. Components\TextInput::make('title')
  44. ->label('目录标题')
  45. ->required(),
  46. Components\TextInput::make('display_no')
  47. ->label('编号'),
  48. Components\Select::make('node_type')
  49. ->label('类型')
  50. ->options([
  51. 'chapter' => '章',
  52. 'section' => '节',
  53. 'subsection' => '小节',
  54. 'item' => '条目',
  55. 'project' => '项目学习',
  56. 'reading' => '阅读材料',
  57. 'practice' => '综合实践',
  58. 'summary' => '复习',
  59. 'appendix' => '附录',
  60. ])
  61. ->required(),
  62. Components\TextInput::make('depth')
  63. ->label('层级')
  64. ->numeric(),
  65. Components\TextInput::make('sort_order')
  66. ->label('排序')
  67. ->numeric(),
  68. Components\TextInput::make('page_start')
  69. ->label('起始页码')
  70. ->numeric(),
  71. Components\TextInput::make('page_end')
  72. ->label('结束页码')
  73. ->numeric(),
  74. ])->columns(2);
  75. }
  76. public static function table(Tables\Table $table): Tables\Table
  77. {
  78. return $table
  79. ->columns([
  80. TextColumn::make('textbook.series_name')
  81. ->label('教材系列')
  82. ->searchable()
  83. ->wrap(),
  84. TextColumn::make('textbook.official_title')
  85. ->label('教材')
  86. ->searchable()
  87. ->wrap(),
  88. TextColumn::make('title')
  89. ->label('目录标题')
  90. ->searchable()
  91. ->wrap(),
  92. TextColumn::make('display_no')
  93. ->label('编号')
  94. ->searchable(),
  95. BadgeColumn::make('node_type')
  96. ->label('类型')
  97. ->formatStateUsing(fn (string $state): string => match ($state) {
  98. 'chapter' => '章',
  99. 'section' => '节',
  100. 'subsection' => '小节',
  101. 'item' => '条目',
  102. 'project' => '项目学习',
  103. 'reading' => '阅读材料',
  104. 'practice' => '综合实践',
  105. 'summary' => '复习',
  106. 'appendix' => '附录',
  107. default => '其他',
  108. })
  109. ->color('info'),
  110. TextColumn::make('depth')
  111. ->label('层级')
  112. ->sortable(),
  113. TextColumn::make('page_start')
  114. ->label('起始页码')
  115. ->sortable(),
  116. TextColumn::make('page_end')
  117. ->label('结束页码')
  118. ->sortable(),
  119. TextColumn::make('created_at')
  120. ->label('创建时间')
  121. ->dateTime('Y-m-d H:i')
  122. ->sortable()
  123. ->toggleable(),
  124. ])
  125. ->filters([
  126. Tables\Filters\SelectFilter::make('textbook_id')
  127. ->label('教材')
  128. ->options(function () {
  129. return Textbook::query()
  130. ->orderBy('id')
  131. ->get(['id', 'official_title'])
  132. ->mapWithKeys(function ($textbook) {
  133. $label = $textbook->official_title ?: '未命名教材';
  134. return [$textbook->id => $label];
  135. })
  136. ->toArray();
  137. })
  138. ->searchable()
  139. ->preload(),
  140. Tables\Filters\SelectFilter::make('node_type')
  141. ->label('节点类型')
  142. ->options([
  143. 'chapter' => '章',
  144. 'section' => '节',
  145. 'subsection' => '小节',
  146. 'item' => '条目',
  147. 'project' => '项目学习',
  148. 'reading' => '阅读材料',
  149. 'practice' => '综合实践',
  150. 'summary' => '复习',
  151. 'appendix' => '附录',
  152. 'custom' => '其他',
  153. ]),
  154. ])
  155. ->actions([
  156. EditAction::make()
  157. ->label('编辑'),
  158. Action::make('delete')
  159. ->label('删除')
  160. ->color('danger')
  161. ->icon('heroicon-o-trash')
  162. ->requiresConfirmation()
  163. ->modalHeading('删除教材目录')
  164. ->modalDescription('确定要删除这个教材目录吗?此操作无法撤销。')
  165. ->action(function (Model $record) {
  166. $record->delete();
  167. return redirect()->refresh();
  168. }),
  169. ])
  170. ->paginated([10, 25, 50, 100])
  171. ->poll(null); // 禁用自动刷新
  172. }
  173. public static function getEloquentQuery(): \Illuminate\Database\Eloquent\Builder
  174. {
  175. return parent::getEloquentQuery()
  176. ->with(['textbook', 'textbook.series']);
  177. }
  178. public static function getPages(): array
  179. {
  180. return [
  181. 'index' => Pages\ManageTextbookCatalogs::route('/'),
  182. ];
  183. }
  184. public static function canViewAny(): bool
  185. {
  186. // 临时允许所有用户查看,等待权限系统完善
  187. return true;
  188. }
  189. public static function canCreate(): bool
  190. {
  191. // 临时允许所有用户创建,等待权限系统完善
  192. return true;
  193. }
  194. public static function canEdit(Model $record): bool
  195. {
  196. // 临时允许所有用户编辑,等待权限系统完善
  197. return true;
  198. }
  199. public static function canDelete(Model $record): bool
  200. {
  201. // 临时允许所有用户删除,等待权限系统完善
  202. return true;
  203. }
  204. public static function canDeleteAny(): bool
  205. {
  206. // 临时允许所有用户批量删除,等待权限系统完善
  207. return true;
  208. }
  209. protected static function deleteRecord(Model $record): bool
  210. {
  211. return (bool) $record->delete();
  212. }
  213. }