Ver Fonte

学案报告

yemeishu há 4 dias atrás
pai
commit
60582f1898

+ 28 - 1
app/Filament/Resources/MarkdownImportResource.php

@@ -35,6 +35,7 @@ use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
 use App\Support\TextEncoding;
 use App\Rules\MarkdownFileExtension;
 use Filament\Tables\Columns\TextColumn;
+use Filament\Tables\Columns\ProgressColumn;
 use Filament\Tables\Enums\FiltersLayout;
 
 class MarkdownImportResource extends Resource
@@ -307,7 +308,25 @@ class MarkdownImportResource extends Resource
                 TextColumn::make('progress_label')
                     ->label('进度')
                     ->getStateUsing(fn (?Model $record) => $record?->progress_label ?: '—')
-                    ->color('gray'),
+                    ->color('gray')
+                    ->toggleable(),
+
+                ProgressColumn::make('progress_percent')
+                    ->label('进度条')
+                    ->getStateUsing(function (?Model $record): ?int {
+                        if (!$record) {
+                            return null;
+                        }
+                        return $record->progress_percent;
+                    })
+                    ->visible(fn (?Model $record): bool => $record?->status === 'processing')
+                    ->color(fn (?int $progress): string => match (true) {
+                        $progress === null => 'gray',
+                        $progress < 30 => 'danger',
+                        $progress < 70 => 'warning',
+                        default => 'success',
+                    })
+                    ->formatStateUsing(fn (?int $state): string => $state !== null ? "{$state}%" : '—'),
 
                 TextColumn::make('parsed_count')
                     ->label('候选题数')
@@ -548,6 +567,14 @@ class MarkdownImportResource extends Resource
         ];
     }
 
+    /**
+     * 启用自动刷新,每5秒更新一次进度
+     */
+    public static function getPollingInterval(): ?string
+    {
+        return '5s';
+    }
+
     /**
      * 解析 Markdown
      */

+ 26 - 5
app/Jobs/ProcessMarkdownCandidateBatch.php

@@ -55,8 +55,12 @@ class ProcessMarkdownCandidateBatch implements ShouldQueue
 
         $processed = 0;
         $failed = 0;
+        $totalRecords = $records->count();
 
-        foreach ($records as $record) {
+        // 初始化进度
+        $this->refreshProgress();
+
+        foreach ($records as $index => $record) {
             try {
                 $meta = $record->meta ?? [];
                 if (!empty($meta['ai_parsed'])) {
@@ -126,6 +130,11 @@ class ProcessMarkdownCandidateBatch implements ShouldQueue
                 ]);
 
                 $processed++;
+
+                // 每处理5个记录就更新一次进度,避免过于频繁
+                if (($index + 1) % 5 === 0 || ($index + 1) === $totalRecords) {
+                    $this->refreshProgress();
+                }
             } catch (\Throwable $e) {
                 $failed++;
 
@@ -137,6 +146,11 @@ class ProcessMarkdownCandidateBatch implements ShouldQueue
                     'error' => $e->getMessage(),
                     'trace' => $e->getTraceAsString(),
                 ]);
+
+                // 失败时也更新进度
+                if (($index + 1) % 5 === 0 || ($index + 1) === $totalRecords) {
+                    $this->refreshProgress();
+                }
             }
         }
 
@@ -188,7 +202,7 @@ class ProcessMarkdownCandidateBatch implements ShouldQueue
         }
 
         // 统一使用与 refreshProgress 相同的查询逻辑
-        [$total, $parsed] = $this->calculateProgress();
+        [$total, $parsed, $batchInfo] = $this->calculateProgress();
 
         // 只有当所有候选题都已处理(解析或过滤)完成时才更新状态
         if ($total > 0 && $parsed >= $total) {
@@ -249,12 +263,19 @@ class ProcessMarkdownCandidateBatch implements ShouldQueue
             })
             ->count();
 
-        return [$total, $parsed];
+        // 计算当前正在处理的批次信息
+        $batchInfo = sprintf(
+            '批次 %d-%d',
+            $this->sequenceStart,
+            $this->sequenceEnd
+        );
+
+        return [$total, $parsed, $batchInfo];
     }
 
     private function refreshProgress(): void
     {
-        [$total, $parsed] = $this->calculateProgress();
+        [$total, $parsed, $batchInfo] = $this->calculateProgress();
 
         // 计算有stem但AI置信度为0的数量(可能是非题目被错误解析)
         $stemOnlyCount = PreQuestionCandidate::query()
@@ -286,7 +307,7 @@ class ProcessMarkdownCandidateBatch implements ShouldQueue
                 'progress_current' => min($parsed, $total),
                 'progress_updated_at' => now(),
                 'progress_stage' => MarkdownImport::STAGE_AI_PARSING,
-                'progress_message' => "AI 解析中… {$parsed}/{$total}" .
+                'progress_message' => "{$batchInfo} | AI 解析中… {$parsed}/{$total}" .
                     ($stemOnlyCount > 0 ? " (含{$stemOnlyCount}个待筛选)" : '') .
                     ($filteredCount > 0 ? " (已过滤{$filteredCount}个非题目)" : ''),
             ]);