OCRQuestionResult.php 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. <?php
  2. namespace App\Models;
  3. use Illuminate\Database\Eloquent\Factories\HasFactory;
  4. use Illuminate\Database\Eloquent\Model;
  5. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  6. class OCRQuestionResult extends Model
  7. {
  8. use HasFactory;
  9. protected $table = 'ocr_question_results';
  10. public $timestamps = false;
  11. protected $fillable = [
  12. 'ocr_record_id',
  13. 'question_number',
  14. 'kp_code',
  15. 'skill_ids',
  16. 'score_area_text',
  17. 'score_area_bbox',
  18. 'score_value',
  19. 'score_confidence',
  20. 'mark_detected',
  21. 'mark_confidence',
  22. 'student_answer',
  23. 'manual_answer',
  24. 'answer_verified',
  25. 'student_answer_bbox',
  26. 'answer_confidence',
  27. 'answer_area_crop_path',
  28. 'question_text',
  29. 'question_bbox',
  30. 'ai_score',
  31. 'ai_feedback',
  32. 'ai_confidence',
  33. 'ai_analysis_method',
  34. 'ai_analyzed_at',
  35. 'question_bank_id',
  36. 'generation_status',
  37. 'generation_task_id',
  38. 'generation_error',
  39. ];
  40. protected $casts = [
  41. 'skill_ids' => 'array',
  42. 'score_area_bbox' => 'array',
  43. 'ai_score' => 'float',
  44. 'mark_confidence' => 'float',
  45. 'student_answer_bbox' => 'array',
  46. 'answer_confidence' => 'float',
  47. 'question_bbox' => 'array',
  48. 'ai_confidence' => 'float',
  49. 'ai_analyzed_at' => 'datetime',
  50. ];
  51. public function ocrRecord(): BelongsTo
  52. {
  53. return $this->belongsTo(OCRRecord::class, 'ocr_record_id', 'id');
  54. }
  55. public function getMarkBadgeAttribute(): string
  56. {
  57. if (!$this->mark_detected) {
  58. return '<span class="px-2 py-1 text-xs rounded bg-gray-100 text-gray-800">未识别</span>';
  59. }
  60. return match ($this->mark_detected) {
  61. '✓', '√', '✔', 'correct' => '<span class="px-2 py-1 text-xs rounded bg-green-100 text-green-800">正确 ✓</span>',
  62. '✗', '×', '❌', 'wrong' => '<span class="px-2 py-1 text-xs rounded bg-red-100 text-red-800">错误 ✗</span>',
  63. default => '<span class="px-2 py-1 text-xs rounded bg-yellow-100 text-yellow-800">' . $this->mark_detected . '</span>',
  64. };
  65. }
  66. public function getConfidenceColorAttribute(): string
  67. {
  68. $confidence = $this->score_confidence ?? 0;
  69. return match (true) {
  70. $confidence >= 0.8 => 'text-green-600',
  71. $confidence >= 0.6 => 'text-yellow-600',
  72. $confidence >= 0.4 => 'text-orange-600',
  73. default => 'text-red-600',
  74. };
  75. }
  76. public function getAnswerAreaCropUrlAttribute(): string
  77. {
  78. if ($this->answer_area_crop_path && file_exists(public_path($this->answer_area_crop_path))) {
  79. return asset($this->answer_area_crop_path);
  80. }
  81. return '';
  82. }
  83. }