OCRRecordList.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <?php
  2. namespace App\Filament\Pages;
  3. use App\Jobs\ProcessOCRRecord;
  4. use App\Models\OCRRecord;
  5. use App\Models\Student;
  6. use BackedEnum;
  7. use Filament\Notifications\Notification;
  8. use Filament\Pages\Page;
  9. use Livewire\Attributes\Computed;
  10. use Livewire\WithPagination;
  11. use UnitEnum;
  12. class OCRRecordList extends Page
  13. {
  14. use WithPagination;
  15. protected static ?string $title = 'OCR识别记录';
  16. protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-camera';
  17. protected static ?string $navigationLabel = 'OCR识别记录';
  18. protected static string|UnitEnum|null $navigationGroup = '管理';
  19. protected static ?int $navigationSort = 2;
  20. protected static ?string $slug = 'ocr-records';
  21. protected string $view = 'filament.pages.ocr-record-list';
  22. public ?string $filterStatus = null;
  23. public ?string $filterGrade = null;
  24. public ?string $filterClass = null;
  25. public ?string $search = null;
  26. public int $perPage = 10;
  27. #[Computed]
  28. public function records()
  29. {
  30. $query = OCRRecord::with('student')
  31. ->when($this->filterStatus, fn($q) => $q->where('status', $this->filterStatus))
  32. ->when($this->filterGrade, fn($q) => $q->whereHas('student', fn($sq) => $sq->where('grade', $this->filterGrade)))
  33. ->when($this->filterClass, fn($q) => $q->whereHas('student', fn($sq) => $sq->where('class_name', $this->filterClass)))
  34. ->when($this->search, fn($q) => $q->whereHas('student', fn($sq) => $sq->where('name', 'like', "%{$this->search}%")))
  35. ->latest();
  36. return $query->paginate($this->perPage);
  37. }
  38. #[Computed]
  39. public function grades(): array
  40. {
  41. return Student::distinct()->pluck('grade')->filter()->toArray();
  42. }
  43. #[Computed]
  44. public function classes(): array
  45. {
  46. return Student::distinct()->pluck('class_name')->filter()->toArray();
  47. }
  48. #[Computed]
  49. public function statistics(): array
  50. {
  51. return [
  52. 'total' => OCRRecord::count(),
  53. 'pending' => OCRRecord::where('status', 'pending')->count(),
  54. 'processing' => OCRRecord::where('status', 'processing')->count(),
  55. 'completed' => OCRRecord::where('status', 'completed')->count(),
  56. 'failed' => OCRRecord::where('status', 'failed')->count(),
  57. ];
  58. }
  59. public function resetFilters(): void
  60. {
  61. $this->filterStatus = null;
  62. $this->filterGrade = null;
  63. $this->filterClass = null;
  64. $this->search = null;
  65. $this->resetPage();
  66. }
  67. public function updatedFilterStatus(): void
  68. {
  69. $this->resetPage();
  70. }
  71. public function updatedFilterGrade(): void
  72. {
  73. $this->resetPage();
  74. }
  75. public function updatedFilterClass(): void
  76. {
  77. $this->resetPage();
  78. }
  79. public function updatedSearch(): void
  80. {
  81. $this->resetPage();
  82. }
  83. public function startRecognition(int $recordId): void
  84. {
  85. $record = OCRRecord::find($recordId);
  86. if (!$record) {
  87. Notification::make()
  88. ->title('记录不存在')
  89. ->danger()
  90. ->send();
  91. return;
  92. }
  93. if ($record->status === 'completed') {
  94. Notification::make()
  95. ->title('该记录已完成识别')
  96. ->warning()
  97. ->send();
  98. return;
  99. }
  100. if ($record->status === 'processing') {
  101. Notification::make()
  102. ->title('该记录正在处理中')
  103. ->info()
  104. ->send();
  105. return;
  106. }
  107. try {
  108. // 分发OCR处理任务
  109. ProcessOCRRecord::dispatch($recordId);
  110. Notification::make()
  111. ->title('已开始识别')
  112. ->body("记录 #{$recordId} 已加入处理队列")
  113. ->success()
  114. ->send();
  115. } catch (\Exception $e) {
  116. Notification::make()
  117. ->title('识别启动失败')
  118. ->body($e->getMessage())
  119. ->danger()
  120. ->send();
  121. }
  122. }
  123. }