ListMenuPermissions.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. namespace App\Filament\Resources\MenuPermissionResource\Pages;
  3. use Illuminate\Database\Eloquent\Builder;
  4. use App\Filament\Resources\MenuPermissionResource;
  5. use App\Models\Teacher;
  6. use Filament\Actions;
  7. use Filament\Resources\Pages\ListRecords;
  8. use Filament\Support\Enums\FontWeight;
  9. use Filament\Tables;
  10. use Filament\Tables\Table;
  11. use Filament\Tables\Columns\TextColumn;
  12. use Filament\Tables\Columns\ToggleColumn;
  13. use Filament\Tables\Columns\BadgeColumn;
  14. use Filament\Tables\Filters\SelectFilter;
  15. use Filament\Tables\Filters\TernaryFilter;
  16. use Filament\Forms;
  17. use Filament\Forms\Components\Select;
  18. use Filament\Forms\Components\Toggle;
  19. use Filament\Forms\Components\TextInput;
  20. use Filament\Forms\Components\Textarea;
  21. class ListMenuPermissions extends ListRecords
  22. {
  23. public ?string $selectedTeacherId = null;
  24. protected static string $resource = MenuPermissionResource::class;
  25. public function mount(): void
  26. {
  27. parent::mount();
  28. // 默认选择第一个老师
  29. if (!$this->selectedTeacherId) {
  30. $firstTeacher = Teacher::first();
  31. if ($firstTeacher) {
  32. $this->selectedTeacherId = $firstTeacher->teacher_id;
  33. }
  34. }
  35. }
  36. /**
  37. * 更新选中的老师
  38. */
  39. public function updatedSelectedTeacherId(): void
  40. {
  41. // 当老师选择改变时,刷新表格数据
  42. $this->resetPage();
  43. }
  44. public function table(Table $table): Table
  45. {
  46. return $table
  47. ->query(
  48. $this->selectedTeacherId
  49. ? \App\Models\MenuPermission::where('user_id', $this->selectedTeacherId)
  50. : \App\Models\MenuPermission::where('id', 0) // 返回空结果
  51. )
  52. ->columns([
  53. TextColumn::make('user_id')
  54. ->label('老师ID')
  55. ->searchable()
  56. ->sortable(),
  57. TextColumn::make('menu_key')
  58. ->label('菜单标识')
  59. ->searchable()
  60. ->sortable(),
  61. TextColumn::make('menu_label')
  62. ->label('菜单名称')
  63. ->searchable(),
  64. TextColumn::make('menu_group')
  65. ->label('菜单分组')
  66. ->badge()
  67. ->color('gray'),
  68. TextColumn::make('menu_url')
  69. ->label('菜单URL')
  70. ->limit(50)
  71. ->copyable(),
  72. ToggleColumn::make('is_visible')
  73. ->label('是否可见')
  74. ->sortable(),
  75. TextColumn::make('sort_order')
  76. ->label('排序')
  77. ->sortable(),
  78. TextColumn::make('created_at')
  79. ->label('创建时间')
  80. ->dateTime('Y-m-d H:i')
  81. ->sortable()
  82. ->toggleable(isToggledHiddenByDefault: true),
  83. ])
  84. ->filters([
  85. SelectFilter::make('menu_group')
  86. ->label('菜单分组')
  87. ->options([
  88. '管理' => '管理',
  89. '工具' => '工具',
  90. '分析' => '分析',
  91. ])
  92. ->multiple(),
  93. TernaryFilter::make('is_visible')
  94. ->label('可见状态')
  95. ->placeholder('全部')
  96. ->trueLabel('可见')
  97. ->falseLabel('隐藏'),
  98. ])
  99. ->actions([
  100. Actions\EditAction::make(),
  101. Actions\DeleteAction::make(),
  102. ])
  103. ->bulkActions([
  104. Actions\BulkActionGroup::make([
  105. Actions\DeleteBulkAction::make(),
  106. Actions\BulkAction::make('toggle_visibility')
  107. ->label('批量切换可见性')
  108. ->icon('heroicon-m-eye')
  109. ->action(function ($records) {
  110. foreach ($records as $record) {
  111. $record->update(['is_visible' => !$record->is_visible]);
  112. }
  113. }),
  114. ]),
  115. ])
  116. ->defaultSort('sort_order')
  117. ->paginated([10, 25, 50, 100])
  118. ->poll('30s');
  119. }
  120. protected function getHeaderActions(): array
  121. {
  122. $teacher = $this->selectedTeacherId
  123. ? Teacher::where('teacher_id', $this->selectedTeacherId)->first()
  124. : null;
  125. return [
  126. Actions\CreateAction::make()
  127. ->visible(fn () => $this->selectedTeacherId !== null),
  128. Actions\Action::make('初始化选中老师菜单')
  129. ->label('为当前老师初始化菜单')
  130. ->icon('heroicon-o-plus-circle')
  131. ->color('success')
  132. ->visible(fn () => $this->selectedTeacherId !== null)
  133. ->action(function () use ($teacher) {
  134. if (!$teacher) {
  135. \Filament\Notifications\Notification::make()
  136. ->title('错误')
  137. ->body('请先选择老师')
  138. ->danger()
  139. ->send();
  140. return;
  141. }
  142. $menuKeys = [
  143. 'dashboard' => ['label' => '仪表盘', 'group' => '管理', 'sort' => 0],
  144. 'exam-history' => ['label' => '考试历史', 'group' => '管理', 'sort' => 1],
  145. 'exam-analysis' => ['label' => '考试分析', 'group' => '分析', 'sort' => 2],
  146. 'ocr-paper-grading' => ['label' => 'OCR试卷批改', 'group' => '工具', 'sort' => 3],
  147. 'intelligent-exam-generation' => ['label' => '智能出卷', 'group' => '工具', 'sort' => 4],
  148. 'knowledge-graph' => ['label' => '知识图谱', 'group' => '分析', 'sort' => 5],
  149. 'student-management' => ['label' => '学生管理', 'group' => '管理', 'sort' => 6],
  150. 'teacher-management' => ['label' => '老师管理', 'group' => '管理', 'sort' => 7],
  151. ];
  152. foreach ($menuKeys as $key => $data) {
  153. \App\Models\MenuPermission::updateOrCreate(
  154. [
  155. 'user_id' => $teacher->teacher_id,
  156. 'menu_key' => $key,
  157. ],
  158. [
  159. 'menu_label' => $data['label'],
  160. 'menu_group' => $data['group'],
  161. 'is_visible' => true,
  162. 'sort_order' => $data['sort'],
  163. ]
  164. );
  165. }
  166. // 刷新表格数据
  167. $this->resetPage();
  168. \Filament\Notifications\Notification::make()
  169. ->title('菜单初始化完成')
  170. ->body('已为老师 ' . $teacher->teacher_id . ' 初始化菜单权限')
  171. ->success()
  172. ->send();
  173. }),
  174. Actions\Action::make('初始化所有老师菜单')
  175. ->label('为所有老师初始化菜单')
  176. ->icon('heroicon-o-users')
  177. ->color('primary')
  178. ->action(function () {
  179. $teachers = Teacher::all();
  180. $menuKeys = [
  181. 'dashboard' => ['label' => '仪表盘', 'group' => '管理', 'sort' => 0],
  182. 'exam-history' => ['label' => '考试历史', 'group' => '管理', 'sort' => 1],
  183. 'exam-analysis' => ['label' => '考试分析', 'group' => '分析', 'sort' => 2],
  184. 'ocr-paper-grading' => ['label' => 'OCR试卷批改', 'group' => '工具', 'sort' => 3],
  185. 'intelligent-exam-generation' => ['label' => '智能出卷', 'group' => '工具', 'sort' => 4],
  186. 'knowledge-graph' => ['label' => '知识图谱', 'group' => '分析', 'sort' => 5],
  187. 'student-management' => ['label' => '学生管理', 'group' => '管理', 'sort' => 6],
  188. 'teacher-management' => ['label' => '老师管理', 'group' => '管理', 'sort' => 7],
  189. ];
  190. foreach ($teachers as $teacher) {
  191. foreach ($menuKeys as $key => $data) {
  192. \App\Models\MenuPermission::updateOrCreate(
  193. [
  194. 'user_id' => $teacher->teacher_id,
  195. 'menu_key' => $key,
  196. ],
  197. [
  198. 'menu_label' => $data['label'],
  199. 'menu_group' => $data['group'],
  200. 'is_visible' => true,
  201. 'sort_order' => $data['sort'],
  202. ]
  203. );
  204. }
  205. }
  206. \Filament\Notifications\Notification::make()
  207. ->title('菜单初始化完成')
  208. ->body('已为 ' . $teachers->count() . ' 位老师初始化菜单权限')
  209. ->success()
  210. ->send();
  211. }),
  212. ];
  213. }
  214. protected function getTableContentGrid(): ?array
  215. {
  216. return [
  217. 'md' => 2,
  218. 'xl' => 3,
  219. ];
  220. }
  221. protected function getTableHeader(): \Illuminate\Contracts\View\View|\Illuminate\Contracts\Support\Htmlable|null
  222. {
  223. $teacher = $this->selectedTeacherId
  224. ? Teacher::where('teacher_id', $this->selectedTeacherId)->first()
  225. : null;
  226. if ($teacher) {
  227. return view('filament.resources.menu-permission-resource.header', [
  228. 'teacher' => $teacher,
  229. ]);
  230. }
  231. return null;
  232. }
  233. }