| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- <?php
- namespace App\Services;
- use App\Models\OCRRecord;
- use App\Models\OCRQuestionResult;
- use App\Models\Paper;
- use Illuminate\Support\Facades\Http;
- use Illuminate\Support\Facades\Log;
- class IntelligentGradingService
- {
- /**
- * 对OCR结果进行AI判分(使用分析项目API)
- */
- public function gradeSubmission(int $ocrRecordId): array
- {
- $ocrRecord = OCRRecord::findOrFail($ocrRecordId);
- $ocrResults = OCRQuestionResult::where('ocr_record_id', $ocrRecordId)->get();
- Log::info('开始AI判分', ['ocr_record_id' => $ocrRecordId, 'question_count' => $ocrResults->count()]);
- try {
- // 调用分析项目API进行判分
- $apiUrl = env('LEARNING_ANALYTICS_API', 'http://localhost:8000') . '/api/grade-submission';
- $response = Http::timeout(60)->post($apiUrl, [
- 'ocr_record_id' => $ocrRecordId,
- 'paper_title' => $ocrRecord->paper_title,
- 'questions' => $ocrResults->toArray(),
- ]);
- if (!$response->successful()) {
- throw new \Exception('分析API调用失败:' . $response->body());
- }
- $data = $response->json();
- // 更新OCR结果
- foreach ($data['question_results'] as $result) {
- OCRQuestionResult::where('ocr_record_id', $ocrRecordId)
- ->where('question_number', $result['question_number'])
- ->update([
- 'ai_score' => $result['score'],
- 'ai_feedback' => $result['feedback'],
- 'ai_confidence' => $result['confidence'] ?? 0.9,
- 'ai_analyzed_at' => now(),
- ]);
- }
- // 更新总成绩到papers表(如果存在对应的paper记录)
- if (!empty($data['total_score'])) {
- $paper = Paper::where('paper_name', $ocrRecord->paper_title)->first();
- if ($paper) {
- $paper->update(['total_score' => $data['total_score']]);
- }
- }
- Log::info('AI判分完成', [
- 'ocr_record_id' => $ocrRecordId,
- 'total_score' => $data['total_score'] ?? 0,
- ]);
- return $data;
- } catch (\Exception $e) {
- Log::error('AI判分失败', [
- 'ocr_record_id' => $ocrRecordId,
- 'error' => $e->getMessage(),
- ]);
- // 使用本地简单判分作为后备
- return $this->localGradingFallback($ocrRecordId, $ocrResults);
- }
- }
- /**
- * 本地简单判分(后备方案)
- */
- protected function localGradingFallback(int $ocrRecordId, $ocrResults): array
- {
- Log::warning('使用本地判分作为后备方案', ['ocr_record_id' => $ocrRecordId]);
- $results = [];
- $totalScore = 0;
- foreach ($ocrResults as $question) {
- // 简化判分逻辑:根据答案置信度给分
- $score = $question->answer_confidence >= 0.8 ? 5.0 : 2.0;
- $question->update([
- 'ai_score' => $score,
- 'ai_feedback' => '基于置信度的模拟评分',
- 'ai_confidence' => $question->answer_confidence,
- 'ai_analyzed_at' => now(),
- ]);
- $results[] = [
- 'question_number' => $question->question_number,
- 'score' => $score,
- 'feedback' => '基于置信度的模拟评分',
- 'confidence' => $question->answer_confidence,
- ];
- $totalScore += $score;
- }
- return [
- 'total_score' => $totalScore,
- 'question_results' => $results,
- 'method' => 'local_fallback',
- ];
- }
- }
|