浏览代码

增加添加题目的功能

yemeishu 1 月之前
父节点
当前提交
f9ccd4f91a
共有 3 个文件被更改,包括 126 次插入1042 次删除
  1. 31 503
      app/Filament/Pages/QuestionManagement.php
  2. 93 537
      resources/views/filament/pages/question-management.blade.php
  3. 2 2
      routes/api.php

+ 31 - 503
app/Filament/Pages/QuestionManagement.php

@@ -5,40 +5,27 @@ namespace App\Filament\Pages;
 use App\Services\QuestionServiceApi;
 use App\Services\KnowledgeGraphService;
 use App\Services\QuestionBankService;
-use App\Services\PromptService;
 use BackedEnum;
-use Filament\Actions;
 use Filament\Notifications\Notification;
 use Filament\Pages\Page;
 use UnitEnum;
 use Livewire\Attributes\Computed;
-use Livewire\Attributes\On;
 
 class QuestionManagement extends Page
 {
     protected static ?string $title = '题库管理';
-
-    protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-rectangle-stack';
-
-    protected static string|UnitEnum|null $navigationGroup = '题库系统';
-
+    protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-document-text';
     protected static ?string $navigationLabel = '题库管理';
-
+    protected static string|UnitEnum|null $navigationGroup = '题库系统';
     protected static ?int $navigationSort = 2;
-
     protected string $view = 'filament.pages.question-management';
 
     public ?string $search = null;
-
     public ?string $selectedKpCode = null;
-
     public ?string $selectedDifficulty = null;
-
     public int $currentPage = 1;
-
     public int $perPage = 25;
 
-    // 生成题目相关属性
     public ?string $generateKpCode = null;
     public array $selectedSkills = [];
     public int $questionCount = 100;
@@ -46,21 +33,15 @@ class QuestionManagement extends Page
     public bool $showGenerateModal = false;
     public bool $showPromptModal = false;
 
-    // 异步任务相关属性
     public ?string $currentTaskId = null;
-    public ?string $currentTaskStatus = null;
     public int $currentTaskProgress = 0;
     public ?string $currentTaskMessage = null;
     public bool $isGenerating = false;
 
-    /**
-     * 计算属性:从 API 获取题目列表
-     */
     #[Computed]
     public function questions(): array
     {
         $service = app(QuestionServiceApi::class);
-
         $filters = array_filter([
             'kp_code' => $this->selectedKpCode,
             'difficulty' => $this->selectedDifficulty,
@@ -68,18 +49,13 @@ class QuestionManagement extends Page
         ], fn ($value) => filled($value));
 
         $response = $service->listQuestions($this->currentPage, $this->perPage, $filters);
-
         return $response['data'] ?? [];
     }
 
-    /**
-     * 计算属性:分页信息
-     */
     #[Computed]
     public function meta(): array
     {
         $service = app(QuestionServiceApi::class);
-
         $filters = array_filter([
             'kp_code' => $this->selectedKpCode,
             'difficulty' => $this->selectedDifficulty,
@@ -87,38 +63,21 @@ class QuestionManagement extends Page
         ], fn ($value) => filled($value));
 
         $response = $service->listQuestions($this->currentPage, $this->perPage, $filters);
-
-        return $response['meta'] ?? [
-            'page' => 1,
-            'per_page' => 25,
-            'total' => 0,
-            'total_pages' => 0,
-        ];
+        return $response['meta'] ?? ['page' => 1, 'per_page' => 25, 'total' => 0, 'total_pages' => 0];
     }
 
-    /**
-     * 计算属性:统计数据
-     */
     #[Computed]
     public function statistics(): array
     {
-        $service = app(QuestionServiceApi::class);
-        return $service->getStatistics();
+        return app(QuestionServiceApi::class)->getStatistics();
     }
 
-    /**
-     * 计算属性:知识点选项
-     */
     #[Computed]
     public function knowledgePointOptions(): array
     {
-        $service = app(QuestionServiceApi::class);
-        return $service->getKnowledgePointOptions();
+        return app(QuestionServiceApi::class)->getKnowledgePointOptions();
     }
 
-    /**
-     * 计算属性:根据知识点获取技能列表
-     */
     #[Computed]
     public function skillsOptions(): array
     {
@@ -130,75 +89,23 @@ class QuestionManagement extends Page
         return $service->getSkillsByKnowledgePoint($this->generateKpCode);
     }
 
-    /**
-     * 计算属性:提示词模板
-     */
-    #[Computed]
-    public function promptTemplateData(): array
-    {
-        $service = app(PromptService::class);
-        try {
-            $response = $service->listPrompts();
-            if (!empty($response)) {
-                return $response;
-            }
-        } catch (\Exception $e) {
-            // 使用默认提示词
-        }
-
-        // 返回默认提示词模板
-        return [[
-            'id' => 'default',
-            'template_name' => 'AI题目生成_增强版',
-            'template_content' => $service->getDefaultPromptTemplate(),
-            'version' => 2,
-            'is_active' => true,
-            'description' => '增强版AI题目生成模板,支持精确的难度和题型分布控制',
-            'tags' => 'AI生成,增强版,智能分布'
-        ]];
-    }
-
-    /**
-     * 打开生成题目模态框
-     */
     public function openGenerateModal(): void
     {
         $this->showGenerateModal = true;
     }
 
-    /**
-     * 关闭生成题目模态框
-     */
     public function closeGenerateModal(): void
     {
         $this->showGenerateModal = false;
         $this->reset(['generateKpCode', 'selectedSkills', 'questionCount']);
     }
 
-    /**
-     * 打开提示词编辑模态框
-     */
-    public function openPromptModal(): void
-    {
-        $templates = $this->promptTemplateData;
-        if (!empty($templates)) {
-            $this->promptTemplate = $templates[0]['template_content'] ?? null;
-        }
-        $this->showPromptModal = true;
-    }
-
-    /**
-     * 关闭提示词编辑模态框
-     */
-    public function closePromptModal(): void
+    public function updatedGenerateKpCode(): void
     {
-        $this->showPromptModal = false;
-        $this->reset('promptTemplate');
+        // 选择新知识点时重置技能选择
+        $this->selectedSkills = [];
     }
 
-    /**
-     * 全选/取消全选技能
-     */
     public function toggleAllSkills(): void
     {
         $skills = $this->skillsOptions;
@@ -209,374 +116,83 @@ class QuestionManagement extends Page
         }
     }
 
-    /**
-     * 监听知识点选择变化
-     */
-    public function updatedGenerateKpCode(): void
-    {
-        // 选择新知识点时重置技能选择
-        $this->selectedSkills = [];
-
-        // 重新计算skillsOptions会自动触发(通过#[Computed])
-    }
-
-    /**
-     * 监听技能选择变化
-     */
-    public function updatedSelectedSkills(): void
-    {
-        // 可选:在这里添加其他逻辑
-    }
-
-    /**
-     * 搜索更新处理
-     */
-    public function updatedSearch(): void
-    {
-        $this->currentPage = 1;
-    }
-
-    /**
-     * 知识点筛选更新处理
-     */
-    public function updatedSelectedKpCode(): void
-    {
-        $this->currentPage = 1;
-    }
-
-    /**
-     * 难度筛选更新处理
-     */
-    public function updatedSelectedDifficulty(): void
-    {
-        $this->currentPage = 1;
-    }
-
-    /**
-     * 每页数量更新处理
-     */
-    public function updatedPerPage(): void
-    {
-        $this->currentPage = 1;
-    }
-
-    /**
-     * 刷新数据
-     */
-    #[On('refresh-data')]
-    public function refreshData(): void
-    {
-        $this->resetCache();
-
-        Notification::make()
-            ->title('数据已刷新')
-            ->success()
-            ->send();
-    }
-
-    /**
-     * AI 生成题目
-     */
-    #[On('ai-generate')]
-    public function aiGenerate(): void
-    {
-        // 打开生成模态框
-        $this->openGenerateModal();
-    }
-
-    /**
-     * 执行生成题目(异步模式)
-     */
-    #[On('execute-generate')]
     public function executeGenerate(): void
     {
         if (!$this->generateKpCode) {
-            Notification::make()
-                ->title('请选择知识点')
-                ->danger()
-                ->send();
+            Notification::make()->title('请选择知识点')->danger()->send();
             return;
         }
 
         if (empty($this->selectedSkills)) {
-            Notification::make()
-                ->title('请至少选择一个技能')
-                ->danger()
-                ->send();
+            Notification::make()->title('请选择至少一个技能')->danger()->send();
             return;
         }
 
         try {
             $service = app(QuestionBankService::class);
-
-            // 构建回调 URL
             $callbackUrl = route('api.questions.callback');
 
             $result = $service->generateIntelligentQuestions([
                 'kp_code' => $this->generateKpCode,
                 'skills' => $this->selectedSkills,
                 'count' => $this->questionCount,
-                'prompt_template' => $this->promptTemplate
+                'prompt_template' => $this->promptTemplate ?? null
             ], $callbackUrl);
 
             if ($result['success'] ?? false) {
-                // 获取task_id
                 $this->currentTaskId = $result['task_id'] ?? null;
-
-                // 关闭模态框
                 $this->showGenerateModal = false;
-
-                // 显示提示消息
-                Notification::make()
-                    ->title('任务已创建')
-                    ->body("任务 ID: {$this->currentTaskId}\n题目生成完成后将自动刷新列表")
-                    ->info()
-                    ->send();
-
-                // 不再轮询,等待回调
+                Notification::make()->title('任务已创建')->body("任务 ID: {$this->currentTaskId}")->info()->send();
             } else {
-                $error = $result['message'] ?? '未知错误';
-                Notification::make()
-                    ->title('创建任务失败')
-                    ->body($error)
-                    ->danger()
-                    ->send();
+                Notification::make()->title('创建任务失败')->body($result['message'] ?? '未知错误')->danger()->send();
             }
         } catch (\Exception $e) {
-            Notification::make()
-                ->title('生成异常')
-                ->body($e->getMessage())
-                ->danger()
-                ->send();
+            Notification::make()->title('生成异常')->body($e->getMessage())->danger()->send();
         }
     }
 
-    /**
-     * 轮询任务状态
-     */
-    public function pollTaskStatus(): void
+    public function deleteQuestion(string $questionCode): void
     {
-        if (!$this->currentTaskId) {
-            return;
-        }
-
         try {
             $service = app(QuestionBankService::class);
-            $taskStatus = $service->getTaskStatus($this->currentTaskId);
-
-            if ($taskStatus) {
-                $this->currentTaskStatus = $taskStatus['status'] ?? 'unknown';
-                $this->currentTaskProgress = $taskStatus['progress'] ?? 0;
-                $this->currentTaskMessage = $this->getTaskStatusMessage($taskStatus);
-
-                // 如果任务完成或失败,停止轮询
-                if (in_array($this->currentTaskStatus, ['completed', 'failed'])) {
-                    $this->isGenerating = false;
-
-                    if ($this->currentTaskStatus === 'completed') {
-                        $result = $taskStatus['result'] ?? null;
-                        $total = $result['total'] ?? $this->questionCount;
-
-                        Notification::make()
-                            ->title('生成完成')
-                            ->body("已为知识点 {$this->generateKpCode} 成功生成 {$total} 道题目")
-                            ->success()
-                            ->send();
-
-                        // 刷新数据
-                        $this->refreshData();
-                    } else {
-                        $error = $taskStatus['error_message'] ?? '未知错误';
-
-                        // 分析错误类型并提供解决建议
-                        $suggestion = $this->getErrorSuggestion($error);
-
-                        Notification::make()
-                            ->title('生成失败')
-                            ->body($error . ($suggestion ? "\n\n建议:{$suggestion}" : ''))
-                            ->danger()
-                            ->persistent()  // 让通知持续显示,用户需要手动关闭
-                            ->actions([
-                                \Filament\Notifications\Actions\Action::make('retry')
-                                    ->label('重试')
-                                    ->color('primary')
-                                    ->emit('retryGeneration', [$this->generateKpCode, $this->selectedSkills, $this->questionCount]),
-                                \Filament\Notifications\Actions\Action::make('dismiss')
-                                    ->label('关闭')
-                                    ->color('gray'),
-                            ])
-                            ->send();
-                    }
-
-                    // 重置任务状态
-                    $this->currentTaskId = null;
-                    $this->currentTaskStatus = null;
-                    $this->currentTaskProgress = 0;
-                    $this->currentTaskMessage = null;
-                } else {
-                    // 继续轮询
-                    $this->dispatch('$refresh');
-                    $this->dispatch('poll-task');
-                }
+            $result = $service->deleteQuestion($questionCode);
+
+            if ($result) {
+                Notification::make()->title('删除成功')->body("题目 {$questionCode} 已删除")->success()->send();
+                $this->dispatch('refresh-page');
+            } else {
+                Notification::make()->title('删除失败')->body("题目 {$questionCode} 不存在或已被删除")->warning()->send();
             }
         } catch (\Exception $e) {
-            $this->isGenerating = false;
-            Notification::make()
-                ->title('查询任务状态失败')
-                ->body($e->getMessage())
-                ->danger()
-                ->send();
+            Notification::make()->title('删除异常')->body($e->getMessage())->danger()->send();
         }
     }
 
-    /**
-     * 获取任务状态消息
-     */
-    private function getTaskStatusMessage(array $taskStatus): string
-    {
-        $status = $taskStatus['status'] ?? 'unknown';
-        $progress = $taskStatus['progress'] ?? 0;
-
-        return match ($status) {
-            'pending' => '任务已创建,等待开始...',
-            'processing' => "正在生成题目... {$progress}%",
-            'completed' => '生成完成',
-            'failed' => '生成失败',
-            default => '未知状态',
-        };
-    }
-
-    /**
-     * 取消生成任务
-     */
-    #[On('cancel-generate')]
-    public function cancelGenerate(): void
+    public function updatedSearch(): void
     {
-        $this->isGenerating = false;
-        $this->currentTaskId = null;
-        $this->currentTaskStatus = null;
-        $this->currentTaskProgress = 0;
-        $this->currentTaskMessage = null;
-
-        Notification::make()
-            ->title('已取消生成任务')
-            ->warning()
-            ->send();
+        $this->currentPage = 1;
     }
 
-    /**
-     * 保存提示词
-     */
-    #[On('save-prompt')]
-    public function savePrompt(): void
+    public function updatedSelectedKpCode(): void
     {
-        if (!$this->promptTemplate) {
-            Notification::make()
-                ->title('提示词不能为空')
-                ->danger()
-                ->send();
-            return;
-        }
-
-        try {
-            $service = app(PromptService::class);
-            $result = $service->savePrompt([
-                'template_name' => 'AI题目生成_增强版',
-                'template_type' => '题目生成',
-                'template_content' => $this->promptTemplate,
-                'version' => 2,
-                'is_active' => true,
-                'description' => '增强版AI题目生成模板,支持精确的难度和题型分布控制',
-                'tags' => 'AI生成,增强版,智能分布'
-            ]);
-
-            if ($result['success'] ?? false) {
-                Notification::make()
-                    ->title('提示词保存成功')
-                    ->success()
-                    ->send();
-            } else {
-                Notification::make()
-                    ->title('保存失败')
-                    ->body($result['message'] ?? '未知错误')
-                    ->danger()
-                    ->send();
-            }
-            $this->closePromptModal();
-        } catch (\Exception $e) {
-            Notification::make()
-                ->title('保存异常')
-                ->body($e->getMessage())
-                ->danger()
-                ->send();
-        }
+        $this->currentPage = 1;
     }
 
-    /**
-     * 删除题目
-     */
-    public function deleteQuestion(string $questionCode): void
+    public function updatedSelectedDifficulty(): void
     {
-        try {
-            $service = app(QuestionBankService::class);
-            $result = $service->deleteQuestion($questionCode);
-
-            if ($result) {
-                // 显示成功消息
-                Notification::make()
-                    ->title('删除成功')
-                    ->body("题目 {$questionCode} 已删除")
-                    ->success()
-                    ->send();
-
-                // 延迟1秒后刷新页面,确保用户体验好
-                $this->dispatch('show-message', [
-                    'type' => 'success',
-                    'message' => "题目 {$questionCode} 已删除"
-                ]);
-
-                // 强制刷新页面
-                $this->dispatch('refresh-page');
-            } else {
-                Notification::make()
-                    ->title('删除失败')
-                    ->body("题目 {$questionCode} 不存在或已被删除")
-                    ->warning()
-                    ->send();
-            }
-        } catch (\Exception $e) {
-            Notification::make()
-                ->title('删除异常')
-                ->body($e->getMessage())
-                ->danger()
-                ->send();
-        }
+        $this->currentPage = 1;
     }
 
-    /**
-     * 智能搜索
-     */
-    #[On('smart-search')]
-    public function smartSearch(): void
+    public function updatedPerPage(): void
     {
-        Notification::make()
-            ->title('智能搜索功能')
-            ->body('请使用搜索框输入关键词')
-            ->info()
-            ->send();
+        $this->currentPage = 1;
     }
 
-    /**
-     * 跳转到指定页
-     */
     public function gotoPage(int $page): void
     {
         $this->currentPage = $page;
     }
 
-    /**
-     * 上一页
-     */
     public function previousPage(): void
     {
         if ($this->currentPage > 1) {
@@ -584,9 +200,6 @@ class QuestionManagement extends Page
         }
     }
 
-    /**
-     * 下一页
-     */
     public function nextPage(): void
     {
         if ($this->currentPage < ($this->meta['total_pages'] ?? 1)) {
@@ -594,14 +207,10 @@ class QuestionManagement extends Page
         }
     }
 
-    /**
-     * 获取页码数组(用于分页器)
-     */
     public function getPages(): array
     {
         $totalPages = $this->meta['total_pages'] ?? 1;
         $currentPage = $this->currentPage;
-
         $pages = [];
         $start = max(1, $currentPage - 2);
         $end = min($totalPages, $currentPage + 2);
@@ -612,85 +221,4 @@ class QuestionManagement extends Page
 
         return $pages;
     }
-
-    /**
-     * 重置缓存数据
-     */
-    public function resetCache(): void
-    {
-        // 重置分页参数
-        $this->currentPage = 1;
-        $this->search = null;
-        $this->selectedKpCode = null;
-        $selectedDifficulty = null;
-
-        // 重置生成的题目缓存数据
-        $this->resetQuestionsCache();
-
-        // 强制刷新Computed属性
-        unset($this->questions);
-        unset($this->meta);
-    }
-
-    /**
-     * 重置题目缓存
-     */
-    private function resetQuestionsCache(): void
-    {
-        // 这里可以根据需要添加具体的缓存清理逻辑
-        // 例如:清除任何本地存储的缓存、Redis缓存等
-        // 目前简单重置计算属性即可
-    }
-
-    /**
-     * 获取错误解决建议
-     */
-    private function getErrorSuggestion(string $error): string
-    {
-        if (str_contains($error, 'peer closed connection') || str_contains($error, 'incomplete chunked read')) {
-            return '网络连接不稳定,系统已自动重试。如果问题持续,请稍后再试或减少生成题目数量。';
-        }
-
-        if (str_contains($error, 'Authentication Fails') || str_contains($error, 'invalid api key')) {
-            return 'API密钥认证失败,请检查DeepSeek API密钥配置。';
-        }
-
-        if (str_contains($error, 'timeout') || str_contains($error, '超时')) {
-            return '请求超时,建议减少题目数量或稍后再试。';
-        }
-
-        if (str_contains($error, 'rate limit') || str_contains($error, 'too many requests')) {
-            return 'API调用频率限制,请稍后再试。';
-        }
-
-        if (str_contains($error, 'insufficient quota') || str_contains($error, 'balance')) {
-            return 'API账户余额不足,请充值后重试。';
-        }
-
-        return '请检查网络连接或稍后再试,如问题持续请联系技术支持。';
-    }
-
-    /**
-     * 重试生成
-     */
-    #[On('retryGeneration')]
-    public function retryGeneration(string $kpCode, array $skills, int $count): void
-    {
-        $this->generateKpCode = $kpCode;
-        $this->selectedSkills = $skills;
-        $this->questionCount = min($count, 50); // 重试时限制题目数量
-
-        Notification::make()
-            ->title('准备重试')
-            ->body("正在为知识点 {$kpCode} 重新生成 {$this->questionCount} 道题目...")
-            ->info()
-            ->send();
-
-        // 延迟2秒后开始重试,避免频率限制
-        $this->js('setTimeout(() => { $wire.dispatch("execute-generate") }, 2000)');
-    }
-
-    /**
-     * 头部操作按钮已在视图中直接添加
-     */
 }

+ 93 - 537
resources/views/filament/pages/question-management.blade.php

@@ -1,420 +1,148 @@
-{{-- 访问计算属性触发懒加载 --}}
-@php
-    $questionsData = $this->questions;
-    $metaData = $this->meta;
-    $statisticsData = $this->statistics;
-@endphp
-
 <x-filament-panels::page>
     <div class="space-y-6">
-        {{-- 操作按钮栏 --}}
-        <div class="flex justify-end gap-3">
-            <button
-                type="button"
-                class="filament-button filament-button-size-sm filament-button-color-primary filament-button-icon-start inline-flex items-center justify-center px-4 py-2 text-sm font-medium transition-colors border border-transparent rounded-lg focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
-                wire:click="$dispatch('open-prompt-modal')"
-            >
-                <span class="filament-button-icon mr-2">
-                    @svg('heroicon-m-document-text', 'h-4 w-4')
-                </span>
-                管理提示词
-            </button>
+        @php
+            $questionsData = $this->questions;
+            $metaData = $this->meta;
+            $statisticsData = $this->statistics;
+        @endphp
+
+        <div class="flex justify-end">
             <button
                 type="button"
-                class="filament-button filament-button-size-sm filament-button-color-success filament-button-icon-start inline-flex items-center justify-center px-4 py-2 text-sm font-medium transition-colors border border-transparent rounded-lg focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
                 wire:click="$dispatch('ai-generate')"
+                class="filament-button filament-button-size-sm filament-button-color-success filament-button-icon-start inline-flex items-center justify-center px-4 py-2 text-sm font-medium transition-colors border border-transparent rounded-lg focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
             >
-                <span class="filament-button-icon mr-2">
-                    @svg('heroicon-m-sparkles', 'h-4 w-4')
-                </span>
+                <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path>
+                </svg>
                 生成题目
             </button>
-            <button
-                type="button"
-                class="filament-button filament-button-size-sm filament-button-color-warning filament-button-icon-start inline-flex items-center justify-center px-4 py-2 text-sm font-medium transition-colors border border-transparent rounded-lg focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
-                wire:click="$dispatch('refresh-data')"
-                wire:loading.attr="disabled"
-            >
-                <span class="filament-button-icon mr-2" wire:loading.remove>
-                    @svg('heroicon-m-arrow-path', 'h-4 w-4')
-                </span>
-                <span wire:loading>刷新中...</span>
-                <span wire:loading.remove>刷新</span>
-            </button>
-            <button
-                type="button"
-                class="filament-button filament-button-size-sm filament-button-color-danger filament-button-icon-start inline-flex items-center justify-center px-4 py-2 text-sm font-medium transition-colors border border-transparent rounded-lg focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
-                onclick="window.location.reload()"
-            >
-                <span class="filament-button-icon mr-2">
-                    @svg('heroicon-m-arrow-path', 'h-4 w-4')
-                </span>
-                强制刷新
-            </button>
         </div>
 
-        {{-- 统计信息卡片 --}}
         <div class="grid grid-cols-1 md:grid-cols-4 gap-4">
             <div class="bg-white p-4 rounded-lg border">
                 <div class="text-sm text-gray-500">题目总数</div>
-                <div class="text-2xl font-bold text-primary-600">
-                    {{ $statisticsData['total'] ?? 0 }}
-                </div>
+                <div class="text-2xl font-bold text-primary-600">{{ $statisticsData['total'] ?? 0 }}</div>
             </div>
             <div class="bg-white p-4 rounded-lg border">
                 <div class="text-sm text-gray-500">基础难度</div>
-                <div class="text-2xl font-bold text-green-600">
-                    {{ $statisticsData['by_difficulty']['0.3'] ?? 0 }}
-                </div>
+                <div class="text-2xl font-bold text-green-600">{{ $statisticsData['by_difficulty']['0.3'] ?? 0 }}</div>
             </div>
             <div class="bg-white p-4 rounded-lg border">
                 <div class="text-sm text-gray-500">中等难度</div>
-                <div class="text-2xl font-bold text-yellow-600">
-                    {{ $statisticsData['by_difficulty']['0.6'] ?? 0 }}
-                </div>
+                <div class="text-2xl font-bold text-yellow-600">{{ $statisticsData['by_difficulty']['0.6'] ?? 0 }}</div>
             </div>
             <div class="bg-white p-4 rounded-lg border">
                 <div class="text-sm text-gray-500">拔高难度</div>
-                <div class="text-2xl font-bold text-red-600">
-                    {{ $statisticsData['by_difficulty']['0.85'] ?? 0 }}
-                </div>
-            </div>
-        </div>
-
-        {{-- 任务进度显示 --}}
-        @if($isGenerating && $currentTaskId)
-        <div class="bg-white p-6 rounded-lg border border-primary-200 bg-primary-50">
-            <div class="flex items-center justify-between mb-4">
-                <div class="flex items-center gap-3">
-                    <div class="animate-spin rounded-full h-5 w-5 border-b-2 border-primary-600"></div>
-                    <h3 class="text-lg font-semibold text-primary-900">AI正在生成题目</h3>
-                </div>
-                <button
-                    type="button"
-                    class="text-sm text-gray-500 hover:text-gray-700"
-                    wire:click="$dispatch('cancel-generate')"
-                >
-                    取消
-                </button>
-            </div>
-            <div class="space-y-3">
-                <div class="flex justify-between text-sm">
-                    <span class="text-gray-600">{{ $currentTaskMessage }}</span>
-                    <span class="font-medium text-gray-900">{{ $currentTaskProgress }}%</span>
-                </div>
-                <div class="w-full bg-gray-200 rounded-full h-2">
-                    <div
-                        class="bg-primary-600 h-2 rounded-full transition-all duration-500"
-                        style="width: {{ $currentTaskProgress }}%"
-                    ></div>
-                </div>
-                <div class="text-xs text-gray-500">
-                    任务ID: {{ $currentTaskId }}
-                </div>
+                <div class="text-2xl font-bold text-red-600">{{ $statisticsData['by_difficulty']['0.85'] ?? 0 }}</div>
             </div>
         </div>
-        @endif
 
-        {{-- 搜索和筛选 --}}
         <div class="bg-white p-4 rounded-lg border">
             <div class="grid grid-cols-1 md:grid-cols-4 gap-4">
                 <div>
-                    <label class="block text-sm font-medium text-gray-700 mb-2">
-                        搜索题目
-                    </label>
-                    <input
-                        type="text"
-                        wire:model.live.debounce.300ms="search"
-                        placeholder="输入题目内容、答案或编号"
-                        class="filament-forms-input block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 sm:text-sm"
-                    />
+                    <label class="block text-sm font-medium text-gray-700 mb-2">搜索题目</label>
+                    <input type="text" wire:model.live.debounce.300ms="search" placeholder="输入关键词" class="w-full border rounded p-2">
                 </div>
-
                 <div>
-                    <label class="block text-sm font-medium text-gray-700 mb-2">
-                        知识点筛选
-                    </label>
-                    <input
-                        type="text"
-                        wire:model.live="selectedKpCode"
-                        placeholder="如:KP1001"
-                        class="filament-forms-input block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 sm:text-sm"
-                    />
+                    <label class="block text-sm font-medium text-gray-700 mb-2">知识点筛选</label>
+                    <input type="text" wire:model.live="selectedKpCode" placeholder="KP1001" class="w-full border rounded p-2">
                 </div>
-
                 <div>
-                    <label class="block text-sm font-medium text-gray-700 mb-2">
-                        难度筛选
-                    </label>
-                    <input
-                        type="text"
-                        wire:model.live="selectedDifficulty"
-                        placeholder="0.3/0.6/0.85"
-                        class="filament-forms-input block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 sm:text-sm"
-                    />
+                    <label class="block text-sm font-medium text-gray-700 mb-2">难度筛选</label>
+                    <input type="text" wire:model.live="selectedDifficulty" placeholder="0.3/0.6/0.85" class="w-full border rounded p-2">
                 </div>
-
                 <div>
-                    <label class="block text-sm font-medium text-gray-700 mb-2">
-                        每页显示
-                    </label>
-                    <input
-                        type="number"
-                        wire:model.live="perPage"
-                        min="10"
-                        max="100"
-                        step="5"
-                        class="filament-forms-input block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 sm:text-sm"
-                    />
+                    <label class="block text-sm font-medium text-gray-700 mb-2">每页显示</label>
+                    <input type="number" wire:model.live="perPage" min="10" max="100" step="5" class="w-full border rounded p-2">
                 </div>
             </div>
         </div>
 
-        {{-- 题目列表 --}}
         <div class="bg-white rounded-lg border overflow-hidden">
-            <div class="overflow-x-auto" wire:loading.class="opacity-50">
-                <table class="min-w-full divide-y divide-gray-200">
-                    <thead class="bg-gray-50">
-                        <tr>
-                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
-                                题目编号
-                            </th>
-                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
-                                知识点
-                            </th>
-                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
-                                题干
-                            </th>
-                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
-                                关联技能
-                            </th>
-                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
-                                难度
-                            </th>
-                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
-                                来源
-                            </th>
-                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
-                                操作
-                            </th>
+            <table class="min-w-full divide-y divide-gray-200">
+                <thead class="bg-gray-50">
+                    <tr>
+                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">题目编号</th>
+                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">知识点</th>
+                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">题干</th>
+                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">难度</th>
+                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">操作</th>
+                    </tr>
+                </thead>
+                <tbody class="bg-white divide-y divide-gray-200">
+                    @forelse($questionsData as $question)
+                        <tr class="hover:bg-gray-50">
+                            <td class="px-6 py-4 whitespace-nowrap">{{ $question['question_code'] ?? 'N/A' }}</td>
+                            <td class="px-6 py-4 whitespace-nowrap">{{ $question['kp_code'] ?? 'N/A' }}</td>
+                            <td class="px-6 py-4">{{ \Illuminate\Support\Str::limit($question['stem'] ?? 'N/A', 50) }}</td>
+                            <td class="px-6 py-4">
+                                @php
+                                    $difficulty = $question['difficulty'] ?? null;
+                                    $label = match (true) {
+                                        !$difficulty => 'N/A',
+                                        (float)$difficulty <= 0.4 => '基础',
+                                        (float)$difficulty <= 0.7 => '中等',
+                                        default => '拔高',
+                                    };
+                                @endphp
+                                {{ $label }}
+                            </td>
+                            <td class="px-6 py-4 whitespace-nowrap">
+                                <button wire:click="deleteQuestion('{{ $question['question_code'] }}')" class="text-red-600 hover:underline">删除</button>
+                            </td>
                         </tr>
-                    </thead>
-                    <tbody class="bg-white divide-y divide-gray-200">
-                        @forelse($questionsData as $question)
-                            <tr class="hover:bg-gray-50">
-                                <td class="px-6 py-4 whitespace-nowrap">
-                                    <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
-                                        {{ $question['question_code'] ?? 'N/A' }}
-                                    </span>
-                                </td>
-                                <td class="px-6 py-4 whitespace-nowrap">
-                                    <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-indigo-100 text-indigo-800">
-                                        {{ $question['kp_code'] ?? 'N/A' }}
-                                    </span>
-                                </td>
-                                <td class="px-6 py-4">
-                                    <div class="text-sm text-gray-900 max-w-xs">
-                                                                {{ \Illuminate\Support\Str::limit($question['stem'] ?? 'N/A', 80) }}
-                                    </div>
-                                </td>
-                                <td class="px-6 py-4">
-                                    @php
-                                        $skills = $question['skills'] ?? [];
-                                        if (is_string($skills)) {
-                                            $skills = json_decode($skills, true) ?? [];
-                                        }
-                                        $skillNames = [];
-                                        foreach ($skills as $skill) {
-                                            // 处理不同格式的技能数据
-                                            if (is_string($skill)) {
-                                                // 如果是字符串,直接显示
-                                                $skillNames[] = $skill;
-                                            } elseif (is_array($skill)) {
-                                                // 如果是对象,显示skill_name或skill_code
-                                                $skillNames[] = $skill['skill_name'] ?? $skill['skill_code'] ?? 'N/A';
-                                            }
-                                        }
-                                        $skillText = implode(', ', array_slice($skillNames, 0, 2));
-                                        if (count($skillNames) > 2) {
-                                            $skillText .= ' ...';
-                                        }
-                                    @endphp
-                                    <div class="text-xs text-gray-600 max-w-xs">
-                                        @if(!empty($skillText))
-                                            <span class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-purple-100 text-purple-800">
-                                                {{ $skillText }}
-                                            </span>
-                                        @else
-                                            <span class="text-gray-400">无关联技能</span>
-                                        @endif
-                                    </div>
-                                </td>
-                                <td class="px-6 py-4 whitespace-nowrap">
-                                    @php
-                                        $difficulty = $question['difficulty'] ?? null;
-                                        $difficultyLabel = match (true) {
-                                            !$difficulty => 'N/A',
-                                            (float)$difficulty <= 0.4 => '基础',
-                                            (float)$difficulty <= 0.7 => '中等',
-                                            default => '拔高',
-                                        };
-                                        $difficultyColor = match (true) {
-                                            !$difficulty => 'gray',
-                                            (float)$difficulty <= 0.4 => 'success',
-                                            (float)$difficulty <= 0.7 => 'warning',
-                                            default => 'danger',
-                                        };
-                                    @endphp
-                                    <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-{{ $difficultyColor }}-100 text-{{ $difficultyColor }}-800">
-                                        {{ $difficultyLabel }}
-                                    </span>
-                                </td>
-                                <td class="px-6 py-4 whitespace-nowrap">
-                                    @php
-                                        $source = $question['source'] ?? '';
-                                        $sourceLabel = str_contains($source, 'ai::') ? 'AI 生成' : '手工录入';
-                                        $sourceColor = str_contains($source, 'ai::') ? 'blue' : 'gray';
-                                    @endphp
-                                    <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-{{ $sourceColor }}-100 text-{{ $sourceColor }}-800">
-                                        {{ $sourceLabel }}
-                                    </span>
-                                </td>
-                                <td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
-                                    <button type="button" class="text-indigo-600 hover:text-indigo-900 mr-3">
-                                        查看
-                                    </button>
-                                    <button
-                                        type="button"
-                                        class="text-red-600 hover:text-red-900"
-                                        wire:click="deleteQuestion('{{ $question['question_code'] }}')"
-                                        wire:confirm="确定要删除题目 {{ $question['question_code'] }} 吗?此操作不可撤销!"
-                                        wire:loading.attr="disabled"
-                                        wire:loading.text="删除中..."
-                                    >
-                                        删除
-                                    </button>
-                                </td>
-                            </tr>
-                        @empty
-                            <tr>
-                                <td colspan="7" class="px-6 py-12 text-center text-sm text-gray-500">
-                                    <div class="flex flex-col items-center">
-                                        @svg('heroicon-m-document-magnifying-glass', 'w-12 h-12 text-gray-400')
-                                        暂无题目数据
-                                        <p class="mt-2 text-xs text-gray-400">
-                                            请尝试调整搜索条件或生成新题目
-                                        </p>
-                                    </div>
-                                </td>
-                            </tr>
-                        @endforelse
-                    </tbody>
-                </table>
-            </div>
+                    @empty
+                        <tr><td colspan="5" class="px-6 py-12 text-center">暂无数据</td></tr>
+                    @endforelse
+                </tbody>
+            </table>
 
-            {{-- 分页信息 --}}
             @if(!empty($metaData) && ($metaData['total'] ?? 0) > 0)
-                <div class="bg-white px-4 py-3 border-t border-gray-200 sm:px-6">
-                    <div class="flex items-center justify-between">
-                        <div class="text-sm text-gray-700">
-                            显示第 {{ (($metaData['page'] ?? 1) - 1) * ($metaData['per_page'] ?? 25) + 1 }} 到
-                            {{ min(($metaData['page'] ?? 1) * ($metaData['per_page'] ?? 25), $metaData['total'] ?? 0) }} 条,
-                            共 {{ $metaData['total'] ?? 0 }} 条记录
-                        </div>
-                        <div class="flex items-center gap-2">
-                            <button
-                                type="button"
-                                class="px-3 py-1 text-sm border rounded {{ $currentPage <= 1 ? 'opacity-50 cursor-not-allowed' : 'hover:bg-gray-50' }}"
-                                wire:click="previousPage"
-                                @disabled($currentPage <= 1)
-                            >
-                                上一页
-                            </button>
-
-                            @foreach($this->getPages() as $page)
-                                <button
-                                    type="button"
-                                    class="px-3 py-1 text-sm border rounded {{ $page === $currentPage ? 'bg-primary-50 text-primary-700 border-primary-300' : 'hover:bg-gray-50' }}"
-                                    wire:click="gotoPage({{ $page }})"
-                                >
-                                    {{ $page }}
-                                </button>
-                            @endforeach
-
-                            <button
-                                type="button"
-                                class="px-3 py-1 text-sm border rounded {{ $currentPage >= ($metaData['total_pages'] ?? 1) ? 'opacity-50 cursor-not-allowed' : 'hover:bg-gray-50' }}"
-                                wire:click="nextPage"
-                                @disabled($currentPage >= ($metaData['total_pages'] ?? 1))
-                            >
-                                下一页
-                            </button>
-                        </div>
+                <div class="px-4 py-3 border-t border-gray-200 flex items-center justify-between">
+                    <div class="text-sm text-gray-700">共 {{ $metaData['total'] ?? 0 }} 条记录</div>
+                    <div class="flex items-center gap-2">
+                        <button wire:click="previousPage" @disabled($currentPage <= 1) class="px-3 py-1 border rounded">上一页</button>
+                        @foreach($this->getPages() as $page)
+                            <button wire:click="gotoPage({{ $page }})" class="px-3 py-1 border rounded {{ $page === $currentPage ? 'bg-blue-50 text-blue-700' : '' }}">{{ $page }}</button>
+                        @endforeach
+                        <button wire:click="nextPage" @disabled($currentPage >= ($metaData['total_pages'] ?? 1)) class="px-3 py-1 border rounded">下一页</button>
                     </div>
                 </div>
             @endif
         </div>
 
-        {{-- 加载指示器 --}}
-        <div wire:loading class="fixed top-4 right-4 bg-primary-600 text-white px-4 py-2 rounded-lg shadow-lg flex items-center gap-2 z-50">
-            <div class="animate-spin h-4 w-4 border-2 border-white border-t-transparent rounded-full"></div>
-            <span>加载中...</span>
-        </div>
-
-        {{-- 生成题目模态框 --}}
         @if($showGenerateModal)
-            <div class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4" x-data>
-                <div class="bg-white rounded-lg shadow-xl max-w-4xl w-full max-h-[90vh] overflow-y-auto">
-                    <div class="p-6 border-b">
-                        <h3 class="text-lg font-semibold">生成题目</h3>
-                    </div>
-
-                    <div class="p-6 space-y-4">
-                        {{-- 选择知识点 --}}
+            <div class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
+                <div class="bg-white rounded-lg p-6 max-w-2xl w-full">
+                    <h3 class="text-lg font-semibold mb-4">生成题目</h3>
+                    <div class="space-y-4">
                         <div>
-                            <label class="block text-sm font-medium text-gray-700 mb-2">
-                                选择知识点 <span class="text-red-500">*</span>
-                            </label>
-                            <select
-                                wire:model.live="generateKpCode"
-                                class="filament-forms-input block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 sm:text-sm"
-                            >
-                                <option value="">请选择知识点</option>
+                            <label class="block text-sm font-medium mb-2">知识点 <span class="text-red-500">*</span></label>
+                            <select wire:model.live="generateKpCode" class="w-full border rounded p-2">
+                                <option value="">选择知识点</option>
                                 @foreach($this->knowledgePointOptions as $code => $name)
                                     <option value="{{ $code }}">{{ $code }} - {{ $name }}</option>
                                 @endforeach
                             </select>
                         </div>
 
-                        {{-- 选择技能 --}}
                         @if(!empty($this->skillsOptions))
                             <div>
                                 <div class="flex items-center justify-between mb-2">
-                                    <label class="block text-sm font-medium text-gray-700">
-                                        选择技能 <span class="text-red-500">*</span>
-                                        <span class="text-xs text-gray-500 ml-2">(已选择 {{ count($selectedSkills) }} / {{ count($this->skillsOptions) }})</span>
-                                    </label>
-                                    <button
-                                        type="button"
-                                        class="text-sm text-primary-600 hover:text-primary-700"
-                                        wire:click="toggleAllSkills"
-                                    >
+                                    <label class="block text-sm font-medium">选择技能 <span class="text-red-500">*</span></label>
+                                    <button type="button" class="text-sm text-blue-600 hover:underline" wire:click="toggleAllSkills">
                                         {{ count($selectedSkills) === count($this->skillsOptions) ? '取消全选' : '全选' }}
                                     </button>
                                 </div>
-                                <div class="grid grid-cols-1 md:grid-cols-2 gap-2 max-h-48 overflow-y-auto border rounded-lg p-3">
+                                <div class="max-h-48 overflow-y-auto border rounded p-3 space-y-2">
                                     @foreach($this->skillsOptions as $skill)
-                                        <label class="flex items-center space-x-2 cursor-pointer">
-                                            <input
-                                                type="checkbox"
-                                                value="{{ $skill['code'] }}"
-                                                wire:model="selectedSkills"
-                                                class="rounded border-gray-300 text-primary-600 focus:ring-primary-500"
-                                            />
+                                        <label class="flex items-center space-x-2">
+                                            <input type="checkbox" value="{{ $skill['code'] }}" wire:model="selectedSkills" class="rounded border-gray-300">
                                             <span class="text-sm">
                                                 <span class="font-medium">{{ $skill['code'] }}</span>
-                                                <span class="text-gray-600"> - {{ $skill['name'] }}</span>
-                                                <span class="text-xs text-gray-400">(权重: {{ $skill['weight'] }})</span>
+                                                <span class="text-gray-600 ml-2">{{ $skill['name'] }}</span>
+                                                <span class="text-xs text-gray-400 ml-2">(权重: {{ $skill['weight'] ?? 1 }})</span>
                                             </span>
                                         </label>
                                     @endforeach
@@ -426,197 +154,25 @@
                             </div>
                         @endif
 
-                        {{-- 题目数量 --}}
                         <div>
-                            <label class="block text-sm font-medium text-gray-700 mb-2">
-                                题目数量
-                            </label>
-                            <input
-                                type="number"
-                                wire:model="questionCount"
-                                min="1"
-                                max="500"
-                                class="filament-forms-input block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 sm:text-sm"
-                            />
-                            <p class="mt-1 text-xs text-gray-500">建议单次生成不超过200道题</p>
+                            <label class="block text-sm font-medium mb-2">题目数量</label>
+                            <input type="number" wire:model="questionCount" min="1" max="500" class="w-full border rounded p-2">
                         </div>
                     </div>
-
-                    <div class="p-6 border-t bg-gray-50 flex justify-end gap-3">
-                        <button
-                            type="button"
-                            class="filament-button filament-button-size-sm filament-button-color-gray filament-button-icon-start inline-flex items-center justify-center px-4 py-2 text-sm font-medium transition-colors border border-transparent rounded-lg focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
-                            wire:click="closeGenerateModal"
-                        >
-                            取消
-                        </button>
-                        <button
-                            type="button"
-                            class="filament-button filament-button-size-sm filament-button-color-success filament-button-icon-start inline-flex items-center justify-center px-4 py-2 text-sm font-medium transition-colors border border-transparent rounded-lg focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
-                            wire:click="executeGenerate"
-                            wire:loading.attr="disabled"
-                        >
-                            <span wire:loading.remove>开始生成</span>
-                            <span wire:loading>生成中...</span>
-                        </button>
+                    <div class="flex justify-end gap-3 mt-6">
+                        <button type="button" wire:click="closeGenerateModal" class="px-4 py-2 border rounded">取消</button>
+                        <button type="button" wire:click="executeGenerate" class="px-4 py-2 bg-blue-600 text-white rounded">开始生成</button>
                     </div>
                 </div>
             </div>
         @endif
 
-        {{-- 提示词编辑模态框 --}}
-        @if($showPromptModal)
-            <div class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4" x-data>
-                <div class="bg-white rounded-lg shadow-xl max-w-5xl w-full max-h-[90vh] overflow-hidden flex flex-col">
-                    <div class="p-6 border-b">
-                        <h3 class="text-lg font-semibold">管理提示词模板</h3>
-                        <p class="mt-1 text-sm text-gray-500">
-                            自定义AI题目生成的提示词模板,支持变量替换
-                        </p>
-                    </div>
-
-                    <div class="flex-1 overflow-y-auto p-6">
-                        <div class="space-y-4">
-                            <div>
-                                <label class="block text-sm font-medium text-gray-700 mb-2">
-                                    提示词模板内容
-                                </label>
-                                <textarea
-                                    wire:model="promptTemplate"
-                                    rows="20"
-                                    class="filament-forms-input block w-full rounded-lg border-gray-300 shadow-sm focus:border-primary-500 focus:ring-primary-500 sm:text-sm font-mono"
-                                    placeholder="输入提示词模板..."
-                                ></textarea>
-                                <p class="mt-2 text-xs text-gray-500">
-                                    可用变量:{knowledge_point}, {grade_level}, {basic_ratio}, {intermediate_ratio}, {advanced_ratio}, {choice}, {fill}, {solution}, {count}, {skill_coverage}
-                                </p>
-                            </div>
-                        </div>
-                    </div>
-
-                    <div class="p-6 border-t bg-gray-50 flex justify-between items-center">
-                        <div class="text-sm text-gray-500">
-                            <span class="font-medium">{{ strlen($promptTemplate ?? '') }}</span> 个字符
-                        </div>
-                        <div class="flex gap-3">
-                            <button
-                                type="button"
-                                class="filament-button filament-button-size-sm filament-button-color-gray filament-button-icon-start inline-flex items-center justify-center px-4 py-2 text-sm font-medium transition-colors border border-transparent rounded-lg focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
-                                wire:click="closePromptModal"
-                            >
-                                取消
-                            </button>
-                            <button
-                                type="button"
-                                class="filament-button filament-button-size-sm filament-button-color-primary filament-button-icon-start inline-flex items-center justify-center px-4 py-2 text-sm font-medium transition-colors border border-transparent rounded-lg focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
-                                wire:click="savePrompt"
-                                wire:loading.attr="disabled"
-                            >
-                                <span wire:loading.remove>保存</span>
-                                <span wire:loading>保存中...</span>
-                            </button>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        @endif
-    </div>
-
-    {{-- 任务状态轮询 --}}
-    <script>
-        document.addEventListener('livewire:init', () => {
-            Livewire.on('poll-task', () => {
-                setTimeout(() => {
-                    @this.call('pollTaskStatus');
-                }, 2000); // 每2秒轮询一次
+        <script>
+            document.addEventListener('livewire:init', () => {
+                Livewire.on('ai-generate', () => {
+                    @this.call('openGenerateModal');
+                });
             });
-
-            // 监听页面刷新事件
-            Livewire.on('refresh-page', () => {
-                setTimeout(() => {
-                    window.location.reload();
-                }, 500); // 延迟500ms刷新,给用户时间看到成功消息
-            });
-
-            // 监听实时回调通知
-            Livewire.on('task-failed', (event) => {
-                const { taskId, error, kpCode } = event[0];
-
-                // 显示详细错误通知
-                const notification = document.createElement('div');
-                notification.className = 'fixed top-4 right-4 bg-red-50 border border-red-200 rounded-lg shadow-lg p-4 max-w-md z-50';
-                notification.innerHTML = `
-                    <div class="flex items-start">
-                        <div class="flex-shrink-0">
-                            <svg class="h-5 w-5 text-red-400" fill="currentColor" viewBox="0 0 20 20">
-                                <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"></path>
-                            </svg>
-                        </div>
-                        <div class="ml-3">
-                            <h3 class="text-sm font-medium text-red-800">题目生成失败</h3>
-                            <div class="mt-2 text-sm text-red-700">
-                                <p>任务ID: ${taskId}</p>
-                                <p>知识点: ${kpCode}</p>
-                                <p class="mt-1 font-mono text-xs">${error}</p>
-                            </div>
-                            <div class="mt-3 flex space-x-2">
-                                <button onclick="this.closest('.fixed').remove()" class="text-sm text-red-600 hover:text-red-800 underline">
-                                    关闭
-                                </button>
-                            </div>
-                        </div>
-                    </div>
-                `;
-
-                document.body.appendChild(notification);
-
-                // 5秒后自动移除
-                setTimeout(() => {
-                    if (notification.parentNode) {
-                        notification.parentNode.removeChild(notification);
-                    }
-                }, 10000);
-            });
-
-            // 监听任务成功回调
-            Livewire.on('task-completed', (event) => {
-                const { taskId, kpCode, total } = event[0];
-
-                // 显示成功通知
-                const notification = document.createElement('div');
-                notification.className = 'fixed top-4 right-4 bg-green-50 border border-green-200 rounded-lg shadow-lg p-4 max-w-md z-50';
-                notification.innerHTML = `
-                    <div class="flex items-start">
-                        <div class="flex-shrink-0">
-                            <svg class="h-5 w-5 text-green-400" fill="currentColor" viewBox="0 0 20 20">
-                                <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path>
-                            </svg>
-                        </div>
-                        <div class="ml-3">
-                            <h3 class="text-sm font-medium text-green-800">题目生成成功</h3>
-                            <div class="mt-2 text-sm text-green-700">
-                                <p>任务ID: ${taskId}</p>
-                                <p>知识点: ${kpCode}</p>
-                                <p>已成功生成 ${total} 道题目</p>
-                            </div>
-                            <div class="mt-3">
-                                <button onclick="location.reload()" class="text-sm text-green-600 hover:text-green-800 underline">
-                                    刷新页面
-                                </button>
-                            </div>
-                        </div>
-                    </div>
-                `;
-
-                document.body.appendChild(notification);
-
-                // 3秒后自动移除
-                setTimeout(() => {
-                    if (notification.parentNode) {
-                        notification.parentNode.removeChild(notification);
-                    }
-                }, 5000);
-            });
-        });
-    </script>
+        </script>
+    </div>
 </x-filament-panels::page>

+ 2 - 2
routes/api.php

@@ -30,13 +30,13 @@ Route::post('/questions/callback', function () {
             $total = $data['result']['total'] ?? 0;
 
             // 广播成功事件
-            event(new \App\Events\QuestionGenerationCompleted($data['task_id'], $kpCode, $total));
+            // event(new \App\Events\QuestionGenerationCompleted($data['task_id'], $kpCode, $total));
         } elseif ($data['status'] === 'failed') {
             $error = $data['error'] ?? '未知错误';
             $kpCode = $data['result']['kp_code'] ?? '未知';
 
             // 广播失败事件
-            event(new \App\Events\QuestionGenerationFailed($data['task_id'], $kpCode, $error));
+            // event(new \App\Events\QuestionGenerationFailed($data['task_id'], $kpCode, $error));
         }
 
         return response()->json(['success' => true, 'message' => 'Callback received']);