| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- <?php
- namespace App\Filament\Pages;
- use App\Models\OCRRecord;
- use App\Models\OCRQuestionResult;
- use App\Jobs\ProcessOCRRecord;
- use Filament\Notifications\Notification;
- use Filament\Pages\Page;
- use Livewire\Attributes\Computed;
- class OCRRecordView extends Page
- {
- protected static ?string $title = 'OCR记录详情';
- protected static ?string $slug = 'ocr-record-view/{recordId}';
- protected string $view = 'filament.pages.ocr-record-view-new';
- public static function shouldRegisterNavigation(): bool
- {
- return false;
- }
- public string $recordId = '';
- public array $manualAnswers = [];
- public bool $hasAnalysisResults = false;
- #[Computed]
- public function record(): ?OCRRecord
- {
- return OCRRecord::with(['student', 'questions'])->find($this->recordId);
- }
- public function mount(string $recordId): void
- {
- $this->recordId = $recordId;
- $record = $this->record();
-
- if ($record) {
- // Fix stuck processing status: if status is processing but we have questions, it's actually completed
- if ($record->status === 'processing' && $record->questions()->count() > 0) {
- $record->update([
- 'status' => 'completed',
- 'processed_at' => $record->processed_at ?? now(),
- 'total_questions' => $record->questions()->count(),
- 'processed_questions' => $record->questions()->count(),
- ]);
- // Refresh record to get updated status
- $record = $this->record();
- }
- foreach ($record->questions as $question) {
- if ($question->manual_answer) {
- $this->manualAnswers[$question->id] = $question->manual_answer;
- }
- }
- // 检查是否已有AI分析结果
- $this->checkAnalysisResults($record);
- }
- }
- /**
- * Check if record already has AI analysis results
- */
- private function checkAnalysisResults(OCRRecord $record): void
- {
- // Only consider analyzed if ai_analyzed_at is set AND we have scores
- $this->hasAnalysisResults = $record->ai_analyzed_at && $record->questions()
- ->whereNotNull('ai_score')
- ->exists();
- }
- /**
- * Submit all questions for AI analysis.
- * Updates manual answers in batch, then sends data to LearningAnalytics.
- */
- public function submitForAnalysis(): void
- {
- $record = $this->record();
- if (! $record) {
- Notification::make()
- ->title('记录不存在')
- ->danger()
- ->send();
- return;
- }
- $updatedCount = 0;
- foreach ($record->questions as $question) {
- $manualAnswer = $this->manualAnswers[$question->id] ?? null;
- if ($manualAnswer && trim($manualAnswer) !== '') {
- $question->update([
- 'manual_answer' => trim($manualAnswer),
- 'answer_verified' => true,
- ]);
- $updatedCount++;
- }
- }
- // Call LearningAnalytics API
- $client = new \App\Services\LearningAnalyticsClient();
- $results = $client->analyze($record);
- if ($results === null) {
- Notification::make()
- ->title('分析失败')
- ->body('无法连接到分析服务或服务返回错误,请检查日志。')
- ->danger()
- ->send();
- return;
- }
- $aiUpdated = 0;
- // LearningAnalyticsClient已经处理了数据更新,这里只需要更新记录状态
- if (is_array($results) && count($results) > 0) {
- $aiUpdated = count($results);
- // 更新记录状态为已分析
- $record->update([
- 'ai_analyzed_at' => now(),
- 'ai_analysis_count' => $aiUpdated,
- ]);
- // 重新检查分析结果状态
- $this->checkAnalysisResults($record);
- }
- Notification::make()
- ->title('分析完成')
- ->body("已更新 {$updatedCount} 道题的答案,AI 分析完成 {$aiUpdated} 道题目")
- ->success()
- ->send();
- }
- public function startRecognition(): void
- {
- $record = $this->record();
- if (! $record) {
- Notification::make()
- ->title('记录不存在')
- ->danger()
- ->send();
- return;
- }
- if ($record->status === 'processing') {
- Notification::make()
- ->title('正在处理中')
- ->warning()
- ->send();
- return;
- }
- ProcessOCRRecord::dispatch($record);
- $record->update(['status' => 'processing']);
- Notification::make()
- ->title('开始识别')
- ->body('OCR识别任务已启动,请稍后刷新查看结果')
- ->success()
- ->send();
- }
- public function getStatusBadgeConfig(string $status): array
- {
- return match ($status) {
- 'pending' => ['class' => 'badge-warning', 'text' => '待处理'],
- 'processing' => ['class' => 'badge-info', 'text' => '处理中'],
- 'completed' => ['class' => 'badge-success', 'text' => '已完成'],
- 'failed' => ['class' => 'badge-error', 'text' => '失败'],
- default => ['class' => 'badge-ghost', 'text' => $status],
- };
- }
- }
|