yemeishu 4 өдөр өмнө
parent
commit
83e89846be

+ 133 - 177
app/Filament/Resources/MarkdownImportResource.php

@@ -35,7 +35,6 @@ 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
@@ -215,149 +214,106 @@ class MarkdownImportResource extends Resource
     {
         return $table
             ->columns([
+                // 文件名列 - 固定宽度,可折行显示
                 TextColumn::make('file_name')
-                    ->label('文件')
+                    ->label('文件')
                     ->searchable()
-                    ->sortable(),
-
-                TextColumn::make('remote_url')
-                    ->label('源文件')
-                    ->getStateUsing(fn (?Model $record) => $record?->remote_url ? '查看' : '—')
-                    ->icon('heroicon-o-document-arrow-down')
-                    ->color('primary')
-                    ->url(fn (?Model $record) => $record?->remote_url)
-                    ->openUrlInNewTab()
-                    ->toggleable(),
+                    ->sortable()
+                    ->weight('bold')
+                    ->color('gray-900')
+                    ->wrap()
+                    ->width('200px'),
 
-                TextColumn::make('filename_parse_status')
-                    ->label('命名解析')
-                    ->badge()
+                // 状态列 - 固定宽度
+                TextColumn::make('current_status')
+                    ->label('状态')
                     ->getStateUsing(function (?Model $record): string {
-                        if (!$record) {
-                            return '未知';
-                        }
-                        $parsed = $record->parseFilename();
-                        return empty($parsed) ? '不规范' : '正常';
-                    })
-                    ->color(function (?Model $record): string {
-                        if (!$record) {
-                            return 'gray';
-                        }
-                        return empty($record->parseFilename()) ? 'warning' : 'success';
-                    })
-                    ->tooltip(function (?Model $record): ?string {
-                        if (!$record) {
-                            return null;
-                        }
-                        $parsed = $record->parseFilename();
-                        if (empty($parsed)) {
-                            return '系列_年级_学期_学科_名称';
-                        }
-                        return sprintf(
-                            '系列:%s 年级:%s 学期:%s 学科:%s 名称:%s',
-                            $parsed['series'] ?? '-',
-                            $parsed['grade'] ?? '-',
-                            $parsed['term'] ?? '-',
-                            $parsed['subject'] ?? '-',
-                            $parsed['name'] ?? '-'
-                        );
-                    })
-                    ->url(fn (?Model $record): ?string => $record ? route('filament.admin.pages.markdown-import-workbench', [
-                        'import_id' => $record->id,
-                    ]) : null)
-                    ->openUrlInNewTab(),
-
-                TextColumn::make('source_name')
-                    ->label('来源')
-                    ->toggleable(isToggledHiddenByDefault: true),
+                        if (!$record) return '—';
 
-                TextColumn::make('status')
-                    ->label('状态')
+                        return match ($record->status) {
+                            'pending' => '⏳ 待处理',
+                            'processing' => '🟡 处理中',
+                            'parsed' => '✅ 已解析',
+                            'reviewed' => '📝 已校对',
+                            'completed' => '🎉 已完成',
+                            'failed' => '❌ 处理失败',
+                            default => '—',
+                        };
+                    })
                     ->badge()
-                    ->color(fn (string $state): string => match ($state) {
+                    ->color(fn (?Model $record): string => match ($record?->status ?? '') {
                         'pending' => 'gray',
                         'processing' => 'warning',
-                        'parsed' => 'info',
+                        'parsed' => 'success',
                         'reviewed' => 'primary',
                         'completed' => 'success',
                         'failed' => 'danger',
                         default => 'gray',
                     })
+                    ->width('120px'),
+
+                // 详细信息列 - 自适应剩余空间,完整显示所有内容
+                TextColumn::make('detailed_progress')
+                    ->label('详情')
                     ->getStateUsing(function (?Model $record): string {
-                        if (!$record) {
-                            return '—';
-                        }
+                        if (!$record) return '—';
 
                         return match ($record->status) {
-                            'pending' => '待处理',
-                            'processing' => $record->progress_label ?: '处理中',
-                            'parsed' => '已解析(待校对)',
-                            'reviewed' => '已校对(待入库)',
-                            'completed' => '已完成(已入库)',
-                            'failed' => '失败' . ($record->progress_message ? "({$record->progress_message})" : ''),
-                            default => (string) $record->status,
+                            'processing' => $record->progress_message ?: 'AI 正在解析题目...',
+                            'parsed' => sprintf(
+                                '已解析 %d 个候选题,请进入校对环节',
+                                $record->parsed_count ?? 0
+                            ),
+                            'reviewed' => sprintf(
+                                '已校对 %d 个候选题,请确认入库',
+                                $record->accepted_count ?? 0
+                            ),
+                            'completed' => sprintf(
+                                '成功入库 %d 个题目',
+                                $record->accepted_count ?? 0
+                            ),
+                            'failed' => $record->error_message ?: '未知错误',
+                            'pending' => '准备就绪,等待开始解析',
+                            default => '—',
                         };
-                    }),
-
-                TextColumn::make('progress_message')
-                    ->label('当前步骤')
-                    ->getStateUsing(fn (?Model $record) => $record?->progress_message ?: '—')
+                    })
                     ->wrap()
-                    ->limit(60),
+                    ->color('gray-600')
+                    ->width('1fr'), // 占据剩余所有空间
 
-                TextColumn::make('progress_label')
-                    ->label('进度')
-                    ->getStateUsing(fn (?Model $record) => $record?->progress_label ?: '—')
-                    ->color('gray')
-                    ->toggleable(),
+                // 快速操作列 - 固定宽度
+                TextColumn::make('quick_actions')
+                    ->label('操作')
+                    ->getStateUsing(function (?Model $record): string {
+                        if (!$record) return '—';
 
-                ProgressColumn::make('progress_percent')
-                    ->label('进度条')
-                    ->getStateUsing(function (?Model $record): ?int {
-                        if (!$record) {
-                            return null;
-                        }
-                        return $record->progress_percent;
+                        return match ($record->status) {
+                            'processing' => '🔄 处理中',
+                            'parsed', 'reviewed' => '👁️ 查看校对',
+                            'completed' => '📊 查看结果',
+                            'failed' => '🔁 重试',
+                            'pending' => '▶️ 开始',
+                            default => '—',
+                        };
                     })
-                    ->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',
+                    ->url(function (?Model $record): ?string {
+                        if (!$record) return null;
+
+                        return match ($record->status) {
+                            'parsed', 'reviewed' => route('filament.admin.resources.pre-question-candidates.index', [
+                                'import_id' => $record->id,
+                                'tab' => $record->status === 'reviewed' ? 'reviewed' : null
+                            ]),
+                            'completed' => route('filament.admin.pages.markdown-import-workbench', [
+                                'import_id' => $record->id,
+                            ]),
+                            default => null,
+                        };
                     })
-                    ->formatStateUsing(fn (?int $state): string => $state !== null ? "{$state}%" : '—'),
-
-                TextColumn::make('parsed_count')
-                    ->label('候选题数')
-                    ->getStateUsing(fn (?Model $record) => $record?->parsed_count ?? 0)
-                    ->sortable(),
-
-                TextColumn::make('accepted_count')
-                    ->label('已接受')
-                    ->getStateUsing(fn (?Model $record) => $record?->accepted_count ?? 0)
-                    ->sortable(),
-
-                TextColumn::make('created_at')
-                    ->label('导入时间')
-                    ->dateTime()
-                    ->sortable(),
-
-                TextColumn::make('processing_started_at')
-                    ->label('开始')
-                    ->dateTime('m-d H:i')
-                    ->toggleable(isToggledHiddenByDefault: true),
-
-                TextColumn::make('processing_finished_at')
-                    ->label('结束')
-                    ->dateTime('m-d H:i')
-                    ->toggleable(isToggledHiddenByDefault: true),
-
-                TextColumn::make('error_message')
-                    ->label('错误')
-                    ->visible(fn (?Model $record): bool => $record?->status === 'failed')
+                    ->color('primary')
+                    ->weight('medium')
                     ->wrap()
-                    ->limit(80),
+                    ->width('100px'),
             ])
             ->filters([
                 Tables\Filters\SelectFilter::make('status')
@@ -410,22 +366,71 @@ class MarkdownImportResource extends Resource
                     }),
             ], layout: FiltersLayout::AboveContentCollapsible)
             ->actions([
+                // 第一行按钮 - 主要操作
                 EditAction::make()
-                    ->label('编辑'),
+                    ->label('编辑')
+                    ->size('sm'),
 
                 Action::make('workbench')
-                    ->label('导入工作台')
+                    ->label('工作台')
                     ->icon('heroicon-o-rectangle-stack')
                     ->color('primary')
+                    ->size('sm')
                     ->visible(fn (?Model $record): bool => !empty($record?->parseFilename()))
                     ->url(fn (?Model $record): string => route('filament.admin.pages.markdown-import-workbench', [
                         'import_id' => $record?->id,
                     ])),
 
+                Action::make('review')
+                    ->label('校对')
+                    ->icon('heroicon-o-clipboard-document-list')
+                    ->color('success')
+                    ->size('sm')
+                    ->visible(fn (?Model $record): bool => in_array($record?->status, ['parsed', 'reviewed', 'completed']) && !empty($record?->parseFilename()))
+                    ->url(function (?Model $record): string {
+                        $importId = $record?->id;
+                        $status = $record?->status;
+
+                        if ($status === 'parsed') {
+                            return route('filament.admin.resources.pre-question-candidates.index', [
+                                'import_id' => $importId
+                            ]);
+                        } elseif (in_array($status, ['reviewed', 'completed'])) {
+                            return route('filament.admin.resources.pre-question-candidates.index', [
+                                'import_id' => $importId,
+                                'tab' => 'reviewed'
+                            ]);
+                        }
+
+                        return route('filament.admin.resources.pre-question-candidates.index', [
+                            'import_id' => $importId
+                        ]);
+                    }),
+
+                Action::make('delete')
+                    ->label('删除')
+                    ->icon('heroicon-o-trash')
+                    ->color('danger')
+                    ->size('sm')
+                    ->requiresConfirmation()
+                    ->modalHeading('删除导入记录')
+                    ->modalDescription('确定要删除这条导入记录吗?此操作不可撤销。')
+                    ->action(function (?Model $record) {
+                        if ($record) {
+                            $record->delete();
+                            Notification::make()
+                                ->title('删除成功')
+                                ->success()
+                                ->send();
+                        }
+                    }),
+
+                // 第二行按钮 - 处理操作
                 Action::make('run_pipeline')
-                    ->label('触发全流程')
+                    ->label('全流程')
                     ->icon('heroicon-o-play-circle')
                     ->color('success')
+                    ->size('sm')
                     ->requiresConfirmation()
                     ->modalHeading('触发 Markdown 拆分 + AI 结构化')
                     ->modalDescription('立即提交队列,按 source_file → source_paper → paper_part → candidate → AI 结构化 执行。')
@@ -450,9 +455,10 @@ class MarkdownImportResource extends Resource
                     }),
 
                 Action::make('parse')
-                    ->label('解析 Markdown')
+                    ->label('解析')
                     ->icon('heroicon-o-cog-6-tooth')
                     ->color('info')
+                    ->size('sm')
                     ->visible(fn (?Model $record): bool => in_array($record?->status, ['pending', 'failed']))
                     ->requiresConfirmation()
                     ->modalHeading('解析 Markdown')
@@ -464,9 +470,10 @@ class MarkdownImportResource extends Resource
                     }),
 
                 Action::make('ai_parse')
-                    ->label('AI 解析')
+                    ->label('AI解析')
                     ->icon('heroicon-o-sparkles')
                     ->color('warning')
+                    ->size('sm')
                     ->visible(fn (?Model $record): bool => in_array($record?->status, ['pending', 'processing', 'parsed', 'failed']))
                     ->requiresConfirmation()
                     ->modalHeading('重新执行 AI 解析')
@@ -478,50 +485,6 @@ class MarkdownImportResource extends Resource
 
                         static::triggerAiParsing($record);
                     }),
-
-                Action::make('review')
-                    ->label('进入校对')
-                    ->icon('heroicon-o-clipboard-document-list')
-                    ->color('success')
-                    ->visible(fn (?Model $record): bool => in_array($record?->status, ['parsed', 'reviewed', 'completed']) && !empty($record?->parseFilename()))
-                    ->url(function (?Model $record): string {
-                        // 根据状态跳转到不同页面
-                        $importId = $record?->id;
-                        $status = $record?->status;
-
-                        // 兼容 PHP 7.4 的写法
-                        if ($status === 'parsed') {
-                            return route('filament.admin.resources.pre-question-candidates.index', [
-                                'import_id' => $importId
-                            ]);
-                        } elseif (in_array($status, ['reviewed', 'completed'])) {
-                            return route('filament.admin.resources.pre-question-candidates.index', [
-                                'import_id' => $importId,
-                                'tab' => 'reviewed'  // 显示已校对标签页
-                            ]);
-                        }
-
-                        return route('filament.admin.resources.pre-question-candidates.index', [
-                            'import_id' => $importId
-                        ]);
-                    }),
-
-                Action::make('delete')
-                    ->label('删除')
-                    ->icon('heroicon-o-trash')
-                    ->color('danger')
-                    ->requiresConfirmation()
-                    ->modalHeading('删除导入记录')
-                    ->modalDescription('确定要删除这条导入记录吗?此操作不可撤销。')
-                    ->action(function (?Model $record) {
-                        if ($record) {
-                            $record->delete();
-                            Notification::make()
-                                ->title('删除成功')
-                                ->success()
-                                ->send();
-                        }
-                    }),
             ])
             ->bulkActions([
                 BulkActionGroup::make([
@@ -567,13 +530,6 @@ class MarkdownImportResource extends Resource
         ];
     }
 
-    /**
-     * 启用自动刷新,每5秒更新一次进度
-     */
-    public static function getPollingInterval(): ?string
-    {
-        return '5s';
-    }
 
     /**
      * 解析 Markdown