'', 'template_type' => 'question_generation', 'template_content' => '', 'variables' => '[]', 'description' => '', 'tags' => '', 'is_active' => 'yes', ]; /** * 获取提示词列表 */ public function getPrompts(): array { $service = app(QuestionServiceApi::class); try { // 获取所有提示词 $prompts = $service->listPrompts(); // 筛选 if ($this->selectedType) { $prompts = array_filter($prompts, fn($prompt) => $prompt['template_type'] === $this->selectedType ); } if ($this->search) { $searchTerm = strtolower($this->search); $prompts = array_filter($prompts, fn($prompt) => str_contains(strtolower($prompt['template_name']), $searchTerm) || str_contains(strtolower($prompt['description']), $searchTerm) ); } // 分页 $total = count($prompts); $offset = ($this->currentPage - 1) * $this->perPage; $paginated = array_slice($prompts, $offset, $this->perPage); return [ 'data' => $paginated, 'meta' => [ 'page' => $this->currentPage, 'per_page' => $this->perPage, 'total' => $total, 'total_pages' => (int) ceil($total / $this->perPage), ] ]; } catch (\Exception $e) { \Log::error('Failed to fetch prompts: ' . $e->getMessage()); return ['data' => [], 'meta' => ['total' => 0]]; } } /** * 获取提示词类型统计 */ public function getTypeStats(): array { $service = app(QuestionServiceApi::class); try { $prompts = $service->listPrompts(); $stats = []; foreach ($prompts as $prompt) { $type = $prompt['template_type']; if (!isset($stats[$type])) { $stats[$type] = 0; } $stats[$type]++; } return $stats; } catch (\Exception $e) { \Log::error('Failed to fetch prompt stats: ' . $e->getMessage()); return []; } } /** * 获取所有类型选项 */ public function getTypeOptions(): array { return [ '题目生成' => '题目生成', '掌握度评估' => '掌握度评估', '技能熟练度' => '技能熟练度', '质量审核' => '质量审核', ]; } /** * 筛选更新 */ public function updatedSelectedType(): void { $this->currentPage = 1; } public function updatedSearch(): void { $this->currentPage = 1; } public function updatedPerPage(): void { $this->currentPage = 1; } /** * 跳转到指定页 */ public function gotoPage(int $page): void { $this->currentPage = $page; } /** * 上一页 */ public function previousPage(): void { if ($this->currentPage > 1) { $this->currentPage--; } } /** * 下一页 */ public function nextPage(): void { $totalPages = $this->prompts['meta']['total_pages'] ?? 1; if ($this->currentPage < $totalPages) { $this->currentPage++; } } /** * 创建新提示词 */ #[On('create-prompt')] public function createPrompt(): void { $this->resetPromptForm(); $this->isEditing = false; $this->editingName = null; $this->showPromptModal = true; } /** * 编辑提示词 */ #[On('edit-prompt')] public function editPrompt(array $prompt): void { $this->form = [ 'template_name' => $prompt['template_name'] ?? '', 'template_type' => $prompt['template_type'] ?? 'question_generation', 'template_content' => $this->fetchPromptContent($prompt['template_name'] ?? '') ?? '', 'variables' => $prompt['variables'] ?? '[]', 'description' => $prompt['description'] ?? '', 'tags' => $prompt['tags'] ?? '', 'is_active' => ($prompt['is_active'] === 'yes' || $prompt['is_active'] === true) ? 'yes' : 'no', ]; $this->isEditing = true; $this->editingName = $prompt['template_name'] ?? null; $this->showPromptModal = true; } /** * 删除提示词 */ #[On('delete-prompt')] public function deletePrompt(string $promptName): void { try { $this->request('DELETE', "/prompts/{$promptName}"); Notification::make() ->title('删除成功') ->body("提示词 {$promptName} 已删除") ->success() ->send(); } catch (\Exception $e) { Notification::make() ->title('删除失败') ->body($e->getMessage()) ->danger() ->send(); } } /** * 启用/禁用提示词 */ #[On('toggle-prompt')] public function togglePrompt(?string $promptName = null, ?bool $isActive = null): void { if (!$promptName || $isActive === null) { return; } try { $this->request('PUT', "/prompts/{$promptName}", [ 'is_active' => $isActive ? 'no' : 'yes', ]); Notification::make() ->title(($isActive ? '已禁用 ' : '已启用 ') . $promptName) ->success() ->send(); } catch (\Exception $e) { Notification::make() ->title('更新状态失败') ->body($e->getMessage()) ->danger() ->send(); } } /** * 复制提示词 */ #[On('duplicate-prompt')] public function duplicatePrompt(array $prompt): void { $newName = ($prompt['template_name'] ?? 'template') . '_copy'; try { $this->request('POST', '/prompts', [ 'template_name' => $newName, 'template_type' => $prompt['template_type'] ?? 'question_generation', 'template_content' => $this->fetchPromptContent($prompt['template_name'] ?? '') ?? '', 'variables' => $prompt['variables'] ?? '[]', 'description' => $prompt['description'] ?? '', 'tags' => $prompt['tags'] ?? '', ]); Notification::make() ->title('复制成功') ->body("已创建副本:{$newName}") ->success() ->send(); } catch (\Exception $e) { Notification::make() ->title('复制失败') ->body($e->getMessage()) ->danger() ->send(); } } /** * 刷新数据 */ #[On('refresh-prompts')] public function refreshPrompts(): void { Notification::make() ->title('数据已刷新') ->success() ->send(); } /** * 头部操作 */ protected function getHeaderActions(): array { return [ Actions\Action::make('create') ->label('新建提示词') ->icon('heroicon-m-plus') ->color('success') ->action('createPrompt'), Actions\Action::make('refresh') ->label('刷新') ->icon('heroicon-m-arrow-path') ->color('warning') ->action('refreshPrompts'), ]; } public function savePrompt(): void { $data = $this->validate([ 'form.template_name' => $this->isEditing ? 'nullable|string' : 'required|string', 'form.template_type' => 'required|string', 'form.template_content' => 'required|string', 'form.variables' => 'nullable|string', 'form.description' => 'nullable|string', 'form.tags' => 'nullable|string', 'form.is_active' => 'nullable|string', ])['form']; try { if ($this->isEditing && $this->editingName) { $payload = [ 'template_content' => $data['template_content'], 'template_type' => $data['template_type'], 'variables' => $data['variables'] ?? '[]', 'description' => $data['description'] ?? '', 'tags' => $data['tags'] ?? '', 'is_active' => $data['is_active'] ?? 'yes', ]; $this->request('PUT', "/prompts/{$this->editingName}", $payload); } else { $this->request('POST', '/prompts', [ 'template_name' => $data['template_name'], 'template_type' => $data['template_type'], 'template_content' => $data['template_content'], 'variables' => $data['variables'] ?? '[]', 'description' => $data['description'] ?? '', 'tags' => $data['tags'] ?? '', ]); } $this->showPromptModal = false; $this->refreshPrompts(); Notification::make() ->title('保存成功') ->success() ->send(); } catch (\Exception $e) { Notification::make() ->title('保存失败') ->body($e->getMessage()) ->danger() ->send(); } } protected function request(string $method, string $path, array $payload = []): mixed { $baseUrl = rtrim(config('services.question_bank.base_url', env('QUESTION_BANK_API_BASE', 'http://localhost:5015')), '/'); $url = $baseUrl . $path; $response = Http::timeout(10)->send($method, $url, [ 'json' => $payload, ]); if (!$response->successful()) { throw new \Exception("API 请求失败: {$response->status()} - " . ($response->json('detail') ?? $response->body())); } return $response->json(); } protected function fetchPromptContent(string $templateName): ?string { if (!$templateName) { return null; } try { $baseUrl = rtrim(config('services.question_bank.base_url', env('QUESTION_BANK_API_BASE', 'http://localhost:5015')), '/'); $resp = Http::timeout(8)->get($baseUrl . "/prompts/{$templateName}"); if ($resp->successful()) { return $resp->json('template_content'); } } catch (\Exception $e) { \Log::warning('获取提示词内容失败: ' . $e->getMessage()); } return null; } protected function resetPromptForm(): void { $this->form = [ 'template_name' => '', 'template_type' => 'question_generation', 'template_content' => '', 'variables' => '[]', 'description' => '', 'tags' => '', 'is_active' => 'yes', ]; } }