| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- <?php
- namespace App\Filament\Pages;
- use App\Models\OCRRecord;
- use App\Models\OCRQuestionResult;
- use Filament\Pages\Page;
- use Illuminate\Support\Facades\Http;
- use Illuminate\Support\Facades\Cache;
- class OCRAnalysisView extends Page
- {
- protected static ?string $navigationLabel = 'AI分析报告';
- protected static ?string $title = '试卷AI分析报告';
- protected static bool $shouldRegisterNavigation = false; // 不在导航中显示
- public static function getNavigationIcon(): ?string
- {
- return 'heroicon-o-chart-bar';
- }
- public static function getNavigationGroup(): ?string
- {
- return '卷子生成管理';
- }
- public static function getSlug(?\Filament\Panel $panel = null): string
- {
- return 'ocr-analysis-view/{record}';
- }
- protected string $view = 'filament.pages.ocr-analysis-view';
- public ?OCRRecord $record = null;
- public array $analysisData = [];
- public array $knowledgeStats = [];
- public array $abilityProfile = [];
- public function mount($record): void
- {
- $this->record = OCRRecord::with(['questions', 'student'])->findOrFail($record);
- $this->loadAnalysisData();
- }
- /**
- * 加载分析数据
- */
- public function loadAnalysisData(): void
- {
- // 优先从缓存获取
- $cacheKey = 'analysis_' . $this->record->id;
- $cached = Cache::get($cacheKey);
- if ($cached) {
- $this->analysisData = $cached['overall'];
- $this->knowledgeStats = $cached['knowledge_points'];
- $this->abilityProfile = $cached['abilities'];
- return;
- }
- // 调用分析项目API
- try {
- $apiUrl = env('LEARNING_ANALYTICS_API', 'http://localhost:8000') . '/api/analyze-submission';
- $response = Http::timeout(30)->post($apiUrl, [
- 'ocr_record_id' => $this->record->id,
- 'questions' => $this->record->questions->toArray(),
- ]);
- if ($response->successful()) {
- $data = $response->json();
- $this->parseAnalysisData($data);
- // 缓存结果(1小时)
- Cache::put($cacheKey, [
- 'overall' => $this->analysisData,
- 'knowledge_points' => $this->knowledgeStats,
- 'abilities' => $this->abilityProfile,
- ], now()->addHour());
- } else {
- $this->generateLocalAnalysis();
- }
- } catch (\Exception $e) {
- \Log::warning('调用分析API失败,使用本地分析', ['error' => $e->getMessage()]);
- $this->generateLocalAnalysis();
- }
- }
- /**
- * 解析分析数据
- */
- protected function parseAnalysisData(array $data): void
- {
- // 整体分析
- $this->analysisData = [
- 'total_score' => $data['total_score'] ?? 0,
- 'max_score' => $data['max_score'] ?? 100,
- 'accuracy_rate' => round(($data['correct_count'] ?? 0) / ($data['total_count'] ?? 1) * 100, 2),
- 'correct_count' => $data['correct_count'] ?? 0,
- 'total_count' => $data['total_count'] ?? 0,
- 'average_score' => round($data['total_score'] / $data['total_count'], 2),
- ];
- // 知识点统计
- $this->knowledgeStats = $data['knowledge_points'] ?? [];
- // 能力画像
- $this->abilityProfile = $data['abilities'] ?? [];
- }
- /**
- * 生成本地分析(当API调用失败时)
- */
- protected function generateLocalAnalysis(): void
- {
- $questions = $this->record->questions;
- $totalQuestions = $questions->count();
- $correctCount = $questions->where('ai_score', '>', 0)->count();
- $totalScore = $questions->sum('ai_score');
- $this->analysisData = [
- 'total_score' => $totalScore,
- 'max_score' => $totalQuestions * 5,
- 'accuracy_rate' => $totalQuestions > 0 ? round($correctCount / $totalQuestions * 100, 2) : 0,
- 'correct_count' => $correctCount,
- 'total_count' => $totalQuestions,
- 'average_score' => $totalQuestions > 0 ? round($totalScore / $totalQuestions, 2) : 0,
- ];
- // 简单的知识点统计
- $kpGroups = $questions->groupBy('kp_code');
- $this->knowledgeStats = [];
- foreach ($kpGroups as $kpCode => $kpQuestions) {
- $correctInKp = $kpQuestions->where('ai_score', '>', 0)->count();
- $this->knowledgeStats[] = [
- 'kp_code' => $kpCode,
- 'correct_rate' => round($correctInKp / $kpQuestions->count(), 2),
- 'question_count' => $kpQuestions->count(),
- ];
- }
- // 默认能力画像
- $this->abilityProfile = [
- '计算能力' => rand(60, 90),
- '逻辑推理' => rand(65, 95),
- '空间想象' => rand(55, 85),
- ];
- }
- /**
- * 重新分析
- */
- public function reanalyze(): void
- {
- // 清除缓存
- Cache::forget('analysis_' . $this->record->id);
- // 重新加载
- $this->loadAnalysisData();
- \Filament\Notifications\Notification::make()
- ->title('分析完成')
- ->success()
- ->send();
- }
- /**
- * 获取题目详情
- */
- public function getQuestionDetails(): array
- {
- return $this->record->questions->map(function ($question) {
- return [
- 'id' => $question->id,
- 'question_number' => $question->question_number,
- 'question_type' => $question->question_type,
- 'student_answer' => $question->student_answer,
- 'answer_confidence' => $question->answer_confidence,
- 'ai_score' => $question->ai_score ?? 0,
- 'ai_feedback' => $question->ai_feedback ?? '暂无反馈',
- 'kp_code' => $question->kp_code,
- 'error_analysis' => $this->generateErrorAnalysis($question),
- ];
- })->toArray();
- }
- /**
- * 生成错误分析
- */
- protected function generateErrorAnalysis(OCRQuestionResult $question): string
- {
- if ($question->ai_score > 0) {
- return '回答正确';
- }
- // 根据题目类型生成不同的错误分析
- return match ($question->question_type) {
- 'choice' => '选择题答案错误,建议加强基础知识学习',
- 'fill' => '填空答案不准确,建议复习相关概念',
- 'solve' => '解答过程有误,建议学习标准解法',
- default => '答案需要完善',
- };
- }
- }
|