yemeishu 2 недель назад
Родитель
Сommit
5b9226d131

+ 67 - 19
app/Filament/Resources/StudentResource.php

@@ -114,9 +114,11 @@ class StudentResource extends Resource
                     ->formatStateUsing(fn ($state) => $state ?: '未分配'),
                 Tables\Columns\TextColumn::make('teacher.user.full_name')
                     ->label('指导老师')
-                    ->default('未分配')
                     ->sortable()
                     ->searchable()
+                    ->getStateUsing(fn (Student $record) => $record->teacher?->user?->full_name
+                        ?? $record->teacher?->name
+                        ?? '未分配')
                     ->visible(fn () => !($currentUser?->isTeacher() ?? false)), // 老师登录时不显示老师列
             ])
             ->filters([
@@ -154,28 +156,29 @@ class StudentResource extends Resource
     protected static function teacherOptions(): array
     {
         // 使用缓存优化性能,缓存1小时
-        return cache()->remember('teacher_options', 3600, function () {
-            return Teacher::with(['user' => function ($query) {
-                    $query->select('user_id', 'full_name', 'role');
-                }])
-                ->whereHas('user', function ($query) {
-                    $query->where('role', 'teacher');
-                })
-                ->select('teacher_id', 'user_id', 'name')
-                ->get()
-                ->map(function ($teacher) {
-                    return [
-                        'id' => $teacher->teacher_id,
-                        'name' => $teacher->user->full_name ?? $teacher->name
-                    ];
-                })
-                ->pluck('name', 'id')
-                ->toArray();
+        $options = cache()->remember('teacher_options', 3600, function () {
+            return self::queryTeacherOptions();
         });
+
+        // 如果缓存因历史关联错误导致为空,自动重建一次
+        if (empty($options)) {
+            $options = self::queryTeacherOptions();
+            cache()->put('teacher_options', $options, 3600);
+        }
+
+        return $options;
     }
 
     protected static function teacherOptionsForCurrentUser(): array
     {
+        $currentRecordId = request()->route('record') ?? request()->input('record');
+        $currentStudentTeacher = null;
+        if ($currentRecordId) {
+            $currentStudentTeacher = \App\Models\Student::query()
+                ->select('teacher_id')
+                ->find($currentRecordId);
+        }
+
         // 如果是老师登录,只返回自己的选项
         if (auth()->user()?->isTeacher() ?? false) {
             $teacherId = auth()->user()->teacher?->teacher_id;
@@ -190,7 +193,15 @@ class StudentResource extends Resource
         }
 
         // 如果是管理员,返回所有老师
-        return self::teacherOptions();
+        $options = self::teacherOptions();
+
+        // 确保当前记录的老师在选项里,避免验证器 in 失败
+        if ($currentStudentTeacher && $currentStudentTeacher->teacher_id && !isset($options[$currentStudentTeacher->teacher_id])) {
+            $fallbackLabel = '老师 ' . $currentStudentTeacher->teacher_id;
+            $options[$currentStudentTeacher->teacher_id] = $fallbackLabel;
+        }
+
+        return $options;
     }
 
     protected static function gradeOptions(): array
@@ -232,6 +243,43 @@ class StudentResource extends Resource
         Cache::forget('class_options');
     }
 
+    /**
+     * 查询老师选项(解耦缓存,便于复用和自动重建)
+     */
+    protected static function queryTeacherOptions(): array
+    {
+        $byRole = Teacher::with(['user' => function ($query) {
+                $query->select('user_id', 'full_name', 'role');
+            }])
+            ->whereHas('user', function ($query) {
+                $query->where('role', 'teacher');
+            })
+            ->select('teacher_id', 'user_id', 'name')
+            ->get()
+            ->map(function ($teacher) {
+                return [
+                    'id' => $teacher->teacher_id,
+                    'name' => $teacher->user->full_name ?? $teacher->name ?? $teacher->teacher_id,
+                ];
+            })
+            ->pluck('name', 'id')
+            ->toArray();
+
+        if (!empty($byRole)) {
+            return $byRole;
+        }
+
+        // 兜底:直接列出 teachers 表的记录,避免选项为空导致 in 校验报错
+        return Teacher::query()
+            ->select('teacher_id', 'name')
+            ->get()
+            ->mapWithKeys(function ($teacher) {
+                $label = $teacher->name ?: ('老师 ' . $teacher->teacher_id);
+                return [$teacher->teacher_id => $label];
+            })
+            ->toArray();
+    }
+
     /**
      * 在保存前自动设置老师ID
      */

+ 2 - 1
app/Models/Teacher.php

@@ -33,7 +33,8 @@ class Teacher extends Model
      */
     public function user(): BelongsTo
     {
-        return $this->belongsTo(User::class, 'id', 'user_id');
+        // teachers.user_id 对应 users.user_id(而非默认的 id)
+        return $this->belongsTo(User::class, 'user_id', 'user_id');
     }
 
     /**

+ 18 - 2
resources/views/components/exam/paper-body.blade.php

@@ -95,10 +95,18 @@
                     </div>
                 @endif
                 @if($gradingMode)
+                    @php
+                        $solutionText = trim($q->solution ?? '');
+                        // 去掉前置的“解题思路”标签,避免出现“解题思路:【解题思路】”重复
+                        $solutionText = preg_replace('/^【?\s*解题思路\s*】?\s*[::]?\s*/u', '', $solutionText);
+                        $solutionHtml = $solutionText === ''
+                            ? '<span style="color:#999;font-style:italic;">(暂无解题思路)</span>'
+                            : \App\Services\MathFormulaProcessor::processFormulas($solutionText);
+                    @endphp
                     <div class="question-lead spacer"></div>
                     <div class="answer-meta">
                         <div class="answer-line"><strong>正确答案:</strong><span class="solution-content">{!! \App\Services\MathFormulaProcessor::processFormulas($q->answer ?? '') !!}</span></div>
-                        <div class="answer-line"><strong>解题思路:</strong><span class="solution-content">{!! \App\Services\MathFormulaProcessor::processFormulas($q->solution ?? '') !!}</span></div>
+                        <div class="answer-line"><strong>解题思路:</strong><span class="solution-content">{!! $solutionHtml !!}</span></div>
                     </div>
                 @endif
             </div>
@@ -146,10 +154,18 @@
                     <span class="question-stem">{!! $renderedContent !!}</span>
                 </div>
                 @if($gradingMode)
+                    @php
+                        $solutionText = trim($q->solution ?? '');
+                        // 去掉前置的“解题思路”标签,避免出现“解题思路:【解题思路】”重复
+                        $solutionText = preg_replace('/^【?\s*解题思路\s*】?\s*[::]?\s*/u', '', $solutionText);
+                        $solutionHtml = $solutionText === ''
+                            ? '<span style="color:#999;font-style:italic;">(暂无解题思路)</span>'
+                            : \App\Services\MathFormulaProcessor::processFormulas($solutionText);
+                    @endphp
                     <div class="question-lead spacer"></div>
                     <div class="answer-meta">
                         <div class="answer-line"><strong>正确答案:</strong><span class="solution-content">{!! \App\Services\MathFormulaProcessor::processFormulas($q->answer ?? '') !!}</span></div>
-                        <div class="answer-line"><strong>解题思路:</strong><span class="solution-content">{!! \App\Services\MathFormulaProcessor::processFormulas($q->solution ?? '') !!}</span></div>
+                        <div class="answer-line"><strong>解题思路:</strong><span class="solution-content">{!! $solutionHtml !!}</span></div>
                     </div>
                 @endif
             </div>

+ 1 - 1
resources/views/filament/pages/student-management.blade.php

@@ -84,7 +84,7 @@
                                 </p>
                             </div>
                             <button
-                                wire:click="filterByTeacher('{{ $teacher['teacher_id'] }}')"
+                                onclick="window.location.href='/admin/students?tableFilters[teacher_id][value]={{ $teacher['teacher_id'] }}'"
                                 class="inline-flex items-center gap-1 rounded-lg border border-primary-200 bg-primary-50 px-3 py-1 text-xs font-semibold text-primary-700 transition hover:bg-primary-100 dark:border-primary-500/40 dark:bg-primary-500/10 dark:text-primary-300"
                             >
                                 查看学生