|
|
@@ -2,34 +2,13 @@
|
|
|
<div class="bg-white shadow-md rounded-lg p-6">
|
|
|
<h2 class="text-xl font-semibold text-gray-900 mb-6">试卷评分</h2>
|
|
|
|
|
|
- {{-- 试卷基本信息 --}}
|
|
|
- <div class="bg-gray-50 rounded-lg p-4 mb-6">
|
|
|
- <div class="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
|
|
|
- <div>
|
|
|
- <span class="text-gray-600">试卷名称:</span>
|
|
|
- <span class="font-medium text-gray-900">{{ $paperName ?? '未知' }}</span>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- <span class="text-gray-600">班级:</span>
|
|
|
- <span class="font-medium text-gray-900">{{ $paperClass ?? '未知' }}</span>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- <span class="text-gray-600">学生:</span>
|
|
|
- <span class="font-medium text-gray-900">{{ $paperStudent ?? '未知' }}</span>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- <span class="text-gray-600">考试日期:</span>
|
|
|
- <span class="font-medium text-gray-900">{{ $paperDate ?? '未知' }}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
{{-- 评分列表 --}}
|
|
|
@if(!empty($questions))
|
|
|
- <div class="space-y-4">
|
|
|
+ <div class="space-y-6">
|
|
|
@foreach($questions as $index => $question)
|
|
|
- <div class="border border-gray-200 rounded-lg p-4 hover:border-blue-300 transition-colors">
|
|
|
- <div class="flex items-start justify-between mb-3">
|
|
|
+ <div class="border border-gray-200 rounded-lg p-6 hover:border-blue-300 transition-colors">
|
|
|
+ {{-- 题目顶部信息 --}}
|
|
|
+ <div class="flex items-center justify-between mb-4">
|
|
|
<div class="flex items-center">
|
|
|
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-blue-100 text-blue-800 mr-3">
|
|
|
第 {{ $question['question_number'] ?? ($index + 1) }} 题
|
|
|
@@ -41,108 +20,145 @@
|
|
|
({{ $question['score'] ?? 0 }} 分)
|
|
|
</span>
|
|
|
</div>
|
|
|
+
|
|
|
+ {{-- 当前评分状态(实时更新,放在左上角) --}}
|
|
|
+ <div class="flex items-center">
|
|
|
+ @if($question['question_type'] === 'choice')
|
|
|
+ <span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium
|
|
|
+ {{ ($gradingData[$index]['is_correct'] ?? null) === true
|
|
|
+ ? 'bg-green-100 text-green-800'
|
|
|
+ : (($gradingData[$index]['is_correct'] ?? null) === false
|
|
|
+ ? 'bg-red-100 text-red-800'
|
|
|
+ : 'bg-gray-100 text-gray-800') }}">
|
|
|
+ {{ ($gradingData[$index]['is_correct'] ?? null) === true
|
|
|
+ ? '正确'
|
|
|
+ : (($gradingData[$index]['is_correct'] ?? null) === false
|
|
|
+ ? '错误'
|
|
|
+ : '未评分') }}
|
|
|
+ @if(($gradingData[$index]['is_correct'] ?? null) !== null)
|
|
|
+ ({{ ($gradingData[$index]['is_correct'] ?? false) ? ($question['score'] ?? 0) : 0 }} 分)
|
|
|
+ @endif
|
|
|
+ </span>
|
|
|
+ @else
|
|
|
+ @php
|
|
|
+ $score = floatval($gradingData[$index]['score'] ?? 0);
|
|
|
+ $maxScore = floatval($question['score'] ?? 0);
|
|
|
+ $isCorrect = $maxScore > 0 ? ($score >= $maxScore && $score > 0) : false;
|
|
|
+ $isEmpty = ($gradingData[$index]['score'] ?? null) === null;
|
|
|
+ @endphp
|
|
|
+ <span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium
|
|
|
+ {{ $isEmpty
|
|
|
+ ? 'bg-gray-100 text-gray-800'
|
|
|
+ : ($isCorrect ? 'bg-green-100 text-green-800' : 'bg-yellow-100 text-yellow-800') }}">
|
|
|
+ {{ $isEmpty
|
|
|
+ ? '未评分'
|
|
|
+ : ($isCorrect ? '完全正确' : '部分得分') }}
|
|
|
+ @if(!$isEmpty)
|
|
|
+ ({{ $score }} / {{ $maxScore }} 分)
|
|
|
+ @endif
|
|
|
+ </span>
|
|
|
+ @endif
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
- {{-- 题目内容 --}}
|
|
|
- <div class="mb-4">
|
|
|
- <p class="text-gray-800">{{ $question['content'] ?? $question['question_text'] ?? '' }}</p>
|
|
|
+ {{-- 左右布局:题目内容 | 评分操作 --}}
|
|
|
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
|
+ {{-- 左侧:题目内容 --}}
|
|
|
+ <div class="lg:col-span-2">
|
|
|
+ {{-- 题目内容 --}}
|
|
|
+ <div class="mb-4">
|
|
|
+ <p class="text-gray-800">{{ $question['content'] ?? $question['question_text'] ?? '' }}</p>
|
|
|
|
|
|
- {{-- 选择题选项 --}}
|
|
|
- @if(($question['question_type'] ?? '') === 'choice' && !empty($question['options']))
|
|
|
- <div class="mt-3 grid grid-cols-1 md:grid-cols-2 gap-2">
|
|
|
- @foreach($question['options'] as $option)
|
|
|
- <div class="text-sm text-gray-700 bg-gray-50 px-3 py-2 rounded">
|
|
|
- <span class="font-medium">{{ $option['key'] ?? '' }}.</span>
|
|
|
- <span class="ml-1">{{ $option['value'] ?? '' }}</span>
|
|
|
+ {{-- 选择题选项 --}}
|
|
|
+ @if(($question['question_type'] ?? '') === 'choice' && !empty($question['options']))
|
|
|
+ <div class="mt-3 grid grid-cols-1 md:grid-cols-2 gap-2">
|
|
|
+ @foreach($question['options'] as $option)
|
|
|
+ <div class="text-sm text-gray-700 bg-gray-50 px-3 py-2 rounded">
|
|
|
+ <span class="font-medium">{{ $option['key'] ?? '' }}.</span>
|
|
|
+ <span class="ml-1">{{ $option['value'] ?? '' }}</span>
|
|
|
+ </div>
|
|
|
+ @endforeach
|
|
|
</div>
|
|
|
- @endforeach
|
|
|
- </div>
|
|
|
- @endif
|
|
|
- </div>
|
|
|
-
|
|
|
- {{-- 参考答案 --}}
|
|
|
- <div class="mb-4 p-3 bg-green-50 border border-green-200 rounded-md">
|
|
|
- <div class="flex items-start">
|
|
|
- <svg class="h-5 w-5 text-green-500 mr-2 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
|
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
|
|
- </svg>
|
|
|
- <div>
|
|
|
- <p class="text-sm font-medium text-green-800">参考答案</p>
|
|
|
- @if(!empty($question['answer']))
|
|
|
- <p class="text-sm text-green-700 mt-1">{{ $question['answer'] }}</p>
|
|
|
- @else
|
|
|
- <p class="text-sm text-yellow-700 mt-1">⚠️ 未找到参考答案</p>
|
|
|
@endif
|
|
|
</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
|
|
|
- {{-- 评分操作区 --}}
|
|
|
- <div class="border-t pt-4">
|
|
|
- @if($question['question_type'] === 'choice')
|
|
|
- {{-- 选择题评分 --}}
|
|
|
- <div class="flex items-center space-x-4">
|
|
|
- <span class="text-sm font-medium text-gray-700">评分:</span>
|
|
|
- <div class="flex space-x-2">
|
|
|
- <button
|
|
|
- type="button"
|
|
|
- wire:click="setChoiceAnswer({{ $index }}, true)"
|
|
|
- class="inline-flex items-center px-4 py-2 border rounded-md text-sm font-medium transition-colors
|
|
|
- {{ ($gradingData[$index]['is_correct'] ?? null) === true
|
|
|
- ? 'border-green-500 bg-green-500 text-white'
|
|
|
- : 'border-gray-300 bg-white text-gray-700 hover:bg-green-50 hover:border-green-300' }}">
|
|
|
- <svg class="h-4 w-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
|
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
|
|
- </svg>
|
|
|
- 正确 (✓)
|
|
|
- </button>
|
|
|
- <button
|
|
|
- type="button"
|
|
|
- wire:click="setChoiceAnswer({{ $index }}, false)"
|
|
|
- class="inline-flex items-center px-4 py-2 border rounded-md text-sm font-medium transition-colors
|
|
|
- {{ ($gradingData[$index]['is_correct'] ?? null) === false
|
|
|
- ? 'border-red-500 bg-red-500 text-white'
|
|
|
- : 'border-gray-300 bg-white text-gray-700 hover:bg-red-50 hover:border-red-300' }}">
|
|
|
- <svg class="h-4 w-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
|
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
|
|
- </svg>
|
|
|
- 错误 (✗)
|
|
|
- </button>
|
|
|
+ {{-- 参考答案 --}}
|
|
|
+ <div class="p-3 bg-green-50 border border-green-200 rounded-md">
|
|
|
+ <div class="flex items-start">
|
|
|
+ <svg class="h-5 w-5 text-green-500 mr-2 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
|
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
|
|
+ </svg>
|
|
|
+ <div>
|
|
|
+ <p class="text-sm font-medium text-green-800">参考答案</p>
|
|
|
+ @if(!empty($question['answer']))
|
|
|
+ <p class="text-sm text-green-700 mt-1">{{ $question['answer'] }}</p>
|
|
|
+ @else
|
|
|
+ <p class="text-sm text-yellow-700 mt-1">⚠️ 未找到参考答案</p>
|
|
|
+ @endif
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- @if(($gradingData[$index]['is_correct'] ?? null) !== null)
|
|
|
- <span class="text-sm text-gray-600">
|
|
|
- 当前:{{ ($gradingData[$index]['is_correct'] ?? false) ? '正确' : '错误' }}
|
|
|
- ({{ ($gradingData[$index]['is_correct'] ?? false) ? ($question['score'] ?? 0) : 0 }} 分)
|
|
|
- </span>
|
|
|
- @endif
|
|
|
</div>
|
|
|
- @else
|
|
|
- {{-- 填空题/解答题评分 --}}
|
|
|
- <div class="flex items-center space-x-4">
|
|
|
- <span class="text-sm font-medium text-gray-700">得分:</span>
|
|
|
- <div class="flex items-center space-x-2">
|
|
|
- <input
|
|
|
- type="number"
|
|
|
- wire:model.live="gradingData.{{ $index }}.score"
|
|
|
- placeholder="0 - {{ $question['score'] ?? 0 }}"
|
|
|
- min="0"
|
|
|
- max="{{ $question['score'] ?? 0 }}"
|
|
|
- step="0.5"
|
|
|
- class="w-24 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm">
|
|
|
- <span class="text-sm text-gray-600">/ {{ $question['score'] ?? 0 }} 分</span>
|
|
|
- </div>
|
|
|
- @if(($gradingData[$index]['score'] ?? null) !== null)
|
|
|
- @php
|
|
|
- $score = $gradingData[$index]['score'] ?? 0;
|
|
|
- $maxScore = $question['score'] ?? 0;
|
|
|
- $isCorrect = $score >= $maxScore;
|
|
|
- @endphp
|
|
|
- <span class="text-sm {{ $isCorrect ? 'text-green-600' : 'text-yellow-600' }}">
|
|
|
- ({{ $isCorrect ? '完全正确' : '部分得分' }}:{{ number_format(($score / $maxScore) * 100, 1) }}%)
|
|
|
- </span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {{-- 右侧:评分操作区 --}}
|
|
|
+ <div class="lg:col-span-1">
|
|
|
+ <div class="border-l pl-6 h-full flex flex-col justify-center">
|
|
|
+ @if($question['question_type'] === 'choice')
|
|
|
+ {{-- 选择题评分 --}}
|
|
|
+ <div class="space-y-4">
|
|
|
+ <div class="text-sm font-medium text-gray-700">评分</div>
|
|
|
+ <div class="flex flex-col space-y-2">
|
|
|
+ <button
|
|
|
+ type="button"
|
|
|
+ wire:click="setChoiceAnswer({{ $index }}, true)"
|
|
|
+ class="inline-flex items-center justify-center px-4 py-3 border rounded-md text-sm font-medium transition-colors
|
|
|
+ {{ ($gradingData[$index]['is_correct'] ?? null) === true
|
|
|
+ ? 'border-green-500 bg-green-500 text-white'
|
|
|
+ : 'border-gray-300 bg-white text-gray-700 hover:bg-green-50 hover:border-green-300' }}">
|
|
|
+ <svg class="h-4 w-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
|
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
|
|
+ </svg>
|
|
|
+ 正确 (✓)
|
|
|
+ </button>
|
|
|
+ <button
|
|
|
+ type="button"
|
|
|
+ wire:click="setChoiceAnswer({{ $index }}, false)"
|
|
|
+ class="inline-flex items-center justify-center px-4 py-3 border rounded-md text-sm font-medium transition-colors
|
|
|
+ {{ ($gradingData[$index]['is_correct'] ?? null) === false
|
|
|
+ ? 'border-red-500 bg-red-500 text-white'
|
|
|
+ : 'border-gray-300 bg-white text-gray-700 hover:bg-red-50 hover:border-red-300' }}">
|
|
|
+ <svg class="h-4 w-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
|
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
|
|
+ </svg>
|
|
|
+ 错误 (✗)
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ @else
|
|
|
+ {{-- 填空题/解答题评分 --}}
|
|
|
+ <div class="space-y-4">
|
|
|
+ <div class="text-sm font-medium text-gray-700">评分</div>
|
|
|
+ <div class="space-y-3">
|
|
|
+ <div>
|
|
|
+ <label class="block text-xs text-gray-600 mb-1">得分</label>
|
|
|
+ <div class="flex items-center space-x-2">
|
|
|
+ <input
|
|
|
+ type="number"
|
|
|
+ wire:model="gradingData.{{ $index }}.score"
|
|
|
+ wire:change="$refresh"
|
|
|
+ placeholder="0"
|
|
|
+ min="0"
|
|
|
+ max="{{ $question['score'] ?? 0 }}"
|
|
|
+ step="0.5"
|
|
|
+ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm">
|
|
|
+ </div>
|
|
|
+ <div class="text-xs text-gray-500 mt-1">满分:{{ $question['score'] ?? 0 }} 分</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
@endif
|
|
|
</div>
|
|
|
- @endif
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@endforeach
|