OCRQuestionResult.php 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. ];
  36. protected $casts = [
  37. 'skill_ids' => 'array',
  38. 'score_area_bbox' => 'array',
  39. 'ai_score' => 'float',
  40. 'mark_confidence' => 'float',
  41. 'student_answer_bbox' => 'array',
  42. 'answer_confidence' => 'float',
  43. 'question_bbox' => 'array',
  44. 'ai_confidence' => 'float',
  45. 'ai_analyzed_at' => 'datetime',
  46. ];
  47. public function ocrRecord(): BelongsTo
  48. {
  49. return $this->belongsTo(OCRRecord::class, 'ocr_record_id', 'id');
  50. }
  51. public function getMarkBadgeAttribute(): string
  52. {
  53. if (!$this->mark_detected) {
  54. return '<span class="px-2 py-1 text-xs rounded bg-gray-100 text-gray-800">未识别</span>';
  55. }
  56. return match ($this->mark_detected) {
  57. '✓', '√', '✔', 'correct' => '<span class="px-2 py-1 text-xs rounded bg-green-100 text-green-800">正确 ✓</span>',
  58. '✗', '×', '❌', 'wrong' => '<span class="px-2 py-1 text-xs rounded bg-red-100 text-red-800">错误 ✗</span>',
  59. default => '<span class="px-2 py-1 text-xs rounded bg-yellow-100 text-yellow-800">' . $this->mark_detected . '</span>',
  60. };
  61. }
  62. public function getConfidenceColorAttribute(): string
  63. {
  64. $confidence = $this->score_confidence ?? 0;
  65. return match (true) {
  66. $confidence >= 0.8 => 'text-green-600',
  67. $confidence >= 0.6 => 'text-yellow-600',
  68. $confidence >= 0.4 => 'text-orange-600',
  69. default => 'text-red-600',
  70. };
  71. }
  72. public function getAnswerAreaCropUrlAttribute(): string
  73. {
  74. if ($this->answer_area_crop_path && file_exists(public_path($this->answer_area_crop_path))) {
  75. return asset($this->answer_area_crop_path);
  76. }
  77. return '';
  78. }
  79. }