| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- <?php
- namespace App\Livewire\UploadExam;
- use Livewire\Component;
- use App\Services\ExamPaperService;
- use Filament\Notifications\Notification;
- use Livewire\Attributes\On;
- class GradingPanel extends Component
- {
- public ?string $teacherId = null;
- public ?string $studentId = null;
- public ?string $selectedPaperId = null;
- public array $questions = [];
- public array $gradingData = [];
- public array $questionGrades = []; // 添加这个属性
- public ?string $paperName = null;
- public ?string $paperClass = null;
- public ?string $paperStudent = null;
- public ?string $paperDate = null;
- public bool $showGrading = false; // 添加这个属性
- protected $listeners = [
- 'loadPaper' => 'loadPaper',
- 'submitManualGrading' => 'handleSubmitFromParent',
- ];
- // 接收从父组件传递的参数
- public function mount(
- ?string $teacherId = null,
- ?string $studentId = null,
- ?string $selectedPaperId = null,
- array $questions = []
- ): void {
- $this->teacherId = $teacherId;
- $this->studentId = $studentId;
- $this->selectedPaperId = $selectedPaperId;
- $this->questions = $questions;
-
- // 如果传入了题目,初始化评分数据
- if (!empty($questions)) {
- $this->initializeGradingData();
- }
- }
- #[On('loadPaper')]
- public function loadPaper(string $paperId, string $teacherId, string $studentId): void
- {
- $this->selectedPaperId = $paperId;
- $this->teacherId = $teacherId;
- $this->studentId = $studentId;
- }
- public function updatedSelectedPaperId($value): void
- {
- if (!empty($value)) {
- // 清空评分数据
- $this->gradingData = [];
- $this->loadPaperForGrading($value);
- } else {
- $this->questions = [];
- $this->gradingData = [];
- $this->showGrading = false;
- }
- }
- public function setChoiceAnswer(int $index, bool $isCorrect)
- {
- if (!isset($this->gradingData[$index])) {
- $this->gradingData[$index] = [];
- }
- $this->gradingData[$index]['is_correct'] = $isCorrect;
- // 选择题自动计算分数
- if ($isCorrect && isset($this->questions[$index]['score'])) {
- $this->gradingData[$index]['score'] = $this->questions[$index]['score'];
- } else {
- $this->gradingData[$index]['score'] = 0;
- }
- }
- public function resetGrading()
- {
- $this->gradingData = array_fill(0, count($this->questions), ['score' => null, 'is_correct' => null]);
- Notification::make()
- ->title('已重置评分')
- ->success()
- ->send();
- }
- public function submitGrading()
- {
- try {
- // 数据验证和处理
- $this->convertGradingDataToQuestionGrades();
- \Log::info('GradingPanel: 转换后的评分数据', [
- 'questionGrades' => $this->questionGrades
- ]);
- if (empty($this->questionGrades)) {
- Notification::make()
- ->title('请至少为一道题目评分')
- ->danger()
- ->send();
- return;
- }
- // dispatch 事件让父页面处理提交
- $this->dispatch('submitManualGrading',
- questionGrades: $this->questionGrades,
- gradingData: $this->gradingData,
- questions: $this->questions
- );
- } catch (\Exception $e) {
- \Log::error('GradingPanel: 提交失败', [
- 'error' => $e->getMessage(),
- 'trace' => $e->getTraceAsString()
- ]);
- Notification::make()
- ->title('提交失败')
- ->body($e->getMessage())
- ->danger()
- ->send();
- }
- }
- private function convertGradingDataToQuestionGrades()
- {
- $this->questionGrades = [];
- foreach ($this->questions as $index => $question) {
- $grading = $this->gradingData[$index] ?? null;
- // 检查 grading 数据是否存在且有评分信息
- if ($grading && (
- (isset($grading['is_correct']) && $grading['is_correct'] !== null) ||
- (isset($grading['score']) && $grading['score'] !== null)
- )) {
- $questionId = $question['id'];
- // 处理评分数据...
- $this->questionGrades[$questionId] = [
- 'is_correct' => $grading['is_correct'] ?? null,
- 'score' => $grading['score'] ?? null,
- 'student_answer' => '',
- ];
- }
- }
- }
- public function render()
- {
- return view('livewire.upload-exam.grading-panel');
- }
- public function loadPaperForGrading($paperId): void
- {
- try {
- $paper = \App\Models\Paper::where('paper_id', $paperId)->first();
- if (!$paper) {
- Notification::make()
- ->title('试卷不存在')
- ->danger()
- ->send();
- return;
- }
- // 设置试卷信息
- $this->paperName = $paper->paper_name;
- $this->paperClass = $paper->difficulty_category ?? '未设置';
- $this->paperStudent = $paper->student_id;
- $this->paperDate = $paper->created_at->format('Y-m-d H:i');
- // 使用 Service 加载题目
- $questions = app(ExamPaperService::class)->getPaperQuestions($paperId);
-
- // 转换 Service 返回的题目格式以适配 GradingPanel 的视图
- // Service 返回的格式:
- // [
- // 'id' => $q->id,
- // 'question_number' => $q->question_number,
- // 'question_bank_id' => $q->question_bank_id,
- // 'question_type' => $q->question_type,
- // 'content' => $detail['stem'] ?? '题目内容缺失',
- // 'answer' => $detail['answer'] ?? '',
- // 'score' => $q->score ?? 5,
- // 'kp_code' => $q->knowledge_point,
- // ]
-
- $this->questions = collect($questions)->map(function($q) {
- // 如果是特殊信息行(如 no_questions, missing_data),直接返回
- if (isset($q['is_empty']) || isset($q['is_missing_data']) || isset($q['is_error'])) {
- return $q;
- }
- return [
- 'id' => $q['id'],
- 'question_number' => $q['question_number'],
- 'question_type' => $q['question_type'],
- 'question_text' => $q['content'], // 视图可能使用 question_text
- 'content' => $q['content'],
- 'options' => [], // 暂时留空,如果需要选项显示需要从 Service 获取更多详情
- 'answer' => $q['answer'],
- 'correct_answer' => $q['answer'],
- 'student_answer' => '',
- 'score' => $q['score'],
- 'max_score' => $q['score'],
- 'question_bank_id' => $q['question_bank_id'],
- 'is_empty' => false
- ];
- })->toArray();
- $this->initializeGradingData();
- $this->showGrading = true;
- } catch (\Exception $e) {
- \Log::error('加载试卷题目失败', [
- 'paper_id' => $paperId,
- 'error' => $e->getMessage()
- ]);
- Notification::make()
- ->title('加载失败')
- ->body($e->getMessage())
- ->danger()
- ->send();
- }
- }
-
- private function initializeGradingData()
- {
- $this->gradingData = array_fill(0, count($this->questions), ['score' => null, 'is_correct' => null, 'comment' => '']);
- }
- }
|