'$refresh']; public function mount( ?string $initialTeacherId = null, ?string $initialStudentId = null, bool $required = false, string $teacherLabel = '选择老师', string $studentLabel = '选择学生', string $teacherPlaceholder = '请选择老师...', string $studentPlaceholder = '请选择学生...', ?string $teacherHelperText = null, ?string $studentHelperText = null ): void { $this->teacherId = $initialTeacherId; $this->studentId = $initialStudentId; $this->required = $required; $this->teacherLabel = $teacherLabel; $this->studentLabel = $studentLabel; $this->teacherPlaceholder = $teacherPlaceholder; $this->studentPlaceholder = $studentPlaceholder; $this->teacherHelperText = $teacherHelperText; $this->studentHelperText = $studentHelperText; \Illuminate\Support\Facades\Log::info('TeacherStudentSelector组件已挂载', [ 'initial_teacher_id' => $initialTeacherId, 'initial_student_id' => $initialStudentId, 'has_teacher' => !empty($initialTeacherId), 'has_student' => !empty($initialStudentId) ]); $this->loadTeacherOptions(); // 验证 teacherId 是否在选项中 if ($this->teacherId && !array_key_exists($this->teacherId, $this->teacherOptions)) { $this->teacherId = null; } if ($this->teacherId) { $this->loadStudentOptions(); } } public function updatedTeacherId($value): void { \Illuminate\Support\Facades\Log::info('教师选择已更新', [ 'old_value' => $this->teacherId, 'new_value' => $value, 'is_empty' => empty($value) ]); // 当教师选择变化时,清空之前选择的学生 $this->studentId = null; $this->loadStudentOptions(); // 发送事件到父组件 $this->dispatch('teacherChanged', teacherId: $value); // 强制刷新组件视图 $this->dispatch('$refresh'); } public function updatedStudentId($value): void { \Illuminate\Support\Facades\Log::info('学生选择已更新', [ 'teacher_id' => $this->teacherId, 'student_id' => $value, 'is_empty' => empty($value), 'previous_value' => $this->studentId ]); // 发送事件到父组件 $this->dispatch('studentChanged', teacherId: $this->teacherId, studentId: $value ); // 同时分发到浏览器窗口,确保父组件能接收到 $this->dispatch('window-student-changed', teacherId: $this->teacherId, studentId: $value ); // 强制刷新组件视图 $this->dispatch('$refresh'); \Illuminate\Support\Facades\Log::info('学生选择事件已分发', [ 'dispatched' => true ]); } public function loadTeacherOptions(): void { try { $teachers = Teacher::query() ->leftJoin('users as u', 'teachers.teacher_id', '=', 'u.user_id') ->select( 'teachers.teacher_id', 'teachers.name', 'teachers.subject', 'u.username', 'u.email' ) ->orderBy('teachers.name') ->get(); // 检查是否有学生没有对应的老师记录 $teacherIds = $teachers->pluck('teacher_id')->toArray(); $missingTeacherIds = Student::query() ->distinct() ->whereNotIn('teacher_id', $teacherIds) ->pluck('teacher_id') ->toArray(); $teachersArray = $teachers->all(); if (!empty($missingTeacherIds)) { foreach ($missingTeacherIds as $missingId) { $teachersArray[] = (object) [ 'teacher_id' => $missingId, 'name' => '未知老师 (' . $missingId . ')', 'subject' => '未知', 'username' => null, 'email' => null ]; } usort($teachersArray, function($a, $b) { return strcmp($a->name, $b->name); }); } $this->teacherOptions = collect($teachersArray)->mapWithKeys(function ($teacher) { // 构建详细的显示文本,包含所有可用字段 $displayName = trim($teacher->name ?? $teacher->teacher_id); $subject = $teacher->subject ? " ({$teacher->subject})" : ''; $username = $teacher->username ? " [{$teacher->username}]" : ''; $email = $teacher->email ? " <{$teacher->email}>" : ''; return [ $teacher->teacher_id => "{$displayName}{$subject}{$username}{$email}" ]; })->toArray(); \Illuminate\Support\Facades\Log::info('已加载教师列表', [ 'teacher_count' => count($this->teacherOptions) ]); } catch (\Exception $e) { \Illuminate\Support\Facades\Log::error('加载老师列表失败', [ 'error' => $e->getMessage() ]); $this->teacherOptions = []; } } public function loadStudentOptions(): void { if (empty($this->teacherId)) { $this->studentOptions = []; return; } try { $students = Student::query() ->leftJoin('users as u', 'students.student_id', '=', 'u.user_id') ->where('students.teacher_id', $this->teacherId) ->select( 'students.student_id', 'students.name', 'students.grade', 'students.class_name', 'u.username', 'u.email', 'students.created_at' ) ->orderBy('students.grade') ->orderBy('students.class_name') ->orderBy('students.name') ->get(); \Illuminate\Support\Facades\Log::info('已加载学生列表', [ 'teacher_id' => $this->teacherId, 'student_count' => count($students) ]); // 如果没有找到学生,可能是因为 teacher_id 不在 teachers 表中 // 但学生表中确实有该 teacher_id 的记录,所以直接返回查询结果 $this->studentOptions = $students->mapWithKeys(function ($student) { // 构建详细的显示文本,包含所有可用字段 $displayName = trim($student->name ?? $student->student_id); $gradeClass = trim("{$student->grade} - {$student->class_name}"); $username = $student->username ? " [{$student->username}]" : ''; $email = $student->email ? " <{$student->email}>" : ''; return [ $student->student_id => "{$displayName} ({$gradeClass}){$username}{$email}" ]; })->toArray(); } catch (\Exception $e) { \Illuminate\Support\Facades\Log::error('加载学生列表失败', [ 'teacher_id' => $this->teacherId, 'error' => $e->getMessage() ]); $this->studentOptions = []; } } public function getSelectedTeacherName(): string { return $this->teacherOptions[$this->teacherId] ?? '未选择'; } public function getSelectedStudentName(): string { return $this->studentOptions[$this->studentId] ?? '未选择'; } public function hasSelections(): bool { return !empty($this->teacherId) && !empty($this->studentId); } public function isStudentDropdownDisabled(): bool { return empty($this->teacherId); } public function hasStudents(): bool { return !empty($this->studentOptions); } /** * 获取学生的详细信息(用于父组件) */ public function getStudentDetails(string $studentId): ?array { if (empty($studentId) || empty($this->teacherId)) { return null; } try { $student = Student::query() ->leftJoin('users as u', 'students.student_id', '=', 'u.user_id') ->where('students.student_id', $studentId) ->where('students.teacher_id', $this->teacherId) ->select( 'students.student_id', 'students.name', 'students.grade', 'students.class_name', 'u.username', 'u.email' ) ->first(); if (!$student) { return null; } return [ 'student_id' => $student->student_id, 'name' => $student->name, 'grade' => $student->grade, 'class_name' => $student->class_name, 'username' => $student->username, 'email' => $student->email, 'display_name' => trim($student->name ?? $student->student_id) . " ({$student->grade} - {$student->class_name})", 'full_display' => trim($student->name ?? $student->student_id) . " ({$student->grade} - {$student->class_name})" . ($student->username ? " [{$student->username}]" : '') . ($student->email ? " <{$student->email}>" : '') ]; } catch (\Exception $e) { \Illuminate\Support\Facades\Log::error('获取学生详细信息失败', [ 'student_id' => $studentId, 'error' => $e->getMessage() ]); return null; } } /** * 获取教师的详细信息(用于父组件) */ public function getTeacherDetails(string $teacherId): ?array { if (empty($teacherId)) { return null; } try { $teacher = Teacher::query() ->leftJoin('users as u', 'teachers.teacher_id', '=', 'u.user_id') ->where('teachers.teacher_id', $teacherId) ->select( 'teachers.teacher_id', 'teachers.name', 'teachers.subject', 'u.username', 'u.email' ) ->first(); if (!$teacher) { return null; } return [ 'teacher_id' => $teacher->teacher_id, 'name' => $teacher->name, 'subject' => $teacher->subject, 'username' => $teacher->username, 'email' => $teacher->email, 'display_name' => trim($teacher->name ?? $teacher->teacher_id) . ($teacher->subject ? " ({$teacher->subject})" : ''), 'full_display' => trim($teacher->name ?? $teacher->teacher_id) . ($teacher->subject ? " ({$teacher->subject})" : '') . ($teacher->username ? " [{$teacher->username}]" : '') . ($teacher->email ? " <{$teacher->email}>" : '') ]; } catch (\Exception $e) { \Illuminate\Support\Facades\Log::error('获取教师详细信息失败', [ 'teacher_id' => $teacherId, 'error' => $e->getMessage() ]); return null; } } public function render() { return view('livewire.teacher-student-selector'); } }