UploadForm.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <?php
  2. namespace App\Livewire\UploadExam;
  3. use Livewire\Component;
  4. use Livewire\WithFileUploads;
  5. use Livewire\Attributes\On;
  6. use Filament\Notifications\Notification;
  7. use App\Jobs\ProcessOCRRecord;
  8. use Illuminate\Support\Facades\Storage;
  9. class UploadForm extends Component
  10. {
  11. use WithFileUploads;
  12. public ?string $teacherId = null;
  13. public ?string $studentId = null;
  14. public $uploadedImages = [];
  15. public bool $isUploading = false;
  16. public ?int $currentOcrRecordId = null;
  17. public ?string $ocrStatus = null;
  18. protected $listeners = [
  19. 'uploadComplete' => 'handleUploadComplete',
  20. ];
  21. public function mount($teacherId = null, $studentId = null)
  22. {
  23. $this->teacherId = $teacherId;
  24. $this->studentId = $studentId;
  25. }
  26. public function handleSubmit()
  27. {
  28. // 验证图片
  29. if (empty($this->uploadedImages)) {
  30. Notification::make()
  31. ->title('请上传试卷图片')
  32. ->danger()
  33. ->send();
  34. return;
  35. }
  36. $this->isUploading = true;
  37. try {
  38. // 保存图片
  39. $savedImages = [];
  40. foreach ($this->uploadedImages as $image) {
  41. $path = $image->store('exam-papers', 'public');
  42. $savedImages[] = [
  43. 'path' => $path,
  44. 'original_name' => $image->getClientOriginalName(),
  45. 'size' => $image->getSize(),
  46. ];
  47. }
  48. // 创建 OCR 记录(使用正确的字段名)
  49. $ocrRecord = \App\Models\OCRRecord::create([
  50. 'user_id' => $this->studentId,
  51. 'paper_title' => '待OCR识别',
  52. 'paper_type' => null, // OCR识别
  53. 'file_path' => $savedImages[0]['path'], // 只存储第一张图片的路径
  54. 'image_count' => count($savedImages),
  55. 'status' => 'processing',
  56. ]);
  57. $this->currentOcrRecordId = $ocrRecord->id;
  58. $this->ocrStatus = 'processing';
  59. // 派发 OCR 处理任务
  60. ProcessOCRRecord::dispatch($ocrRecord->id);
  61. $this->dispatch('uploadComplete', [
  62. 'ocrRecordId' => $ocrRecord->id,
  63. 'success' => true,
  64. 'message' => '图片上传成功,正在进行 OCR 识别...',
  65. ]);
  66. } catch (\Exception $e) {
  67. Notification::make()
  68. ->title('上传失败')
  69. ->body($e->getMessage())
  70. ->danger()
  71. ->send();
  72. $this->dispatch('uploadComplete', [
  73. 'success' => false,
  74. 'message' => $e->getMessage(),
  75. ]);
  76. } finally {
  77. $this->isUploading = false;
  78. }
  79. }
  80. public function resetForm()
  81. {
  82. $this->uploadedImages = [];
  83. $this->currentOcrRecordId = null;
  84. $this->ocrStatus = null;
  85. }
  86. public function removeImage($index)
  87. {
  88. unset($this->uploadedImages[$index]);
  89. $this->uploadedImages = array_values($this->uploadedImages);
  90. }
  91. public function handleUploadComplete($data)
  92. {
  93. if ($data['success'] ?? false) {
  94. // 清空表单
  95. $this->resetForm();
  96. }
  97. }
  98. public function checkOcrStatus()
  99. {
  100. if (!$this->currentOcrRecordId) {
  101. return;
  102. }
  103. $ocrRecord = \App\Models\OCRRecord::find($this->currentOcrRecordId);
  104. if ($ocrRecord) {
  105. $this->ocrStatus = $ocrRecord->status;
  106. if ($ocrRecord->status === 'completed') {
  107. // OCR完成,跳转到详情页
  108. $url = '/admin/exam-analysis?recordId=' . $ocrRecord->id . '&studentId=' . $this->studentId;
  109. $this->redirect($url);
  110. } elseif ($ocrRecord->status === 'failed') {
  111. Notification::make()
  112. ->title('OCR识别失败')
  113. ->body($ocrRecord->error_message ?? '未知错误')
  114. ->danger()
  115. ->send();
  116. $this->currentOcrRecordId = null;
  117. }
  118. }
  119. }
  120. public function render()
  121. {
  122. return view('livewire.upload-exam.upload-form');
  123. }
  124. }