import React, { useState, useEffect } from 'react'; import { useParams } from 'next/navigation'; import { useTranslation } from 'react-i18next'; import { Box, Grid, Card, CardContent } from '@mui/material'; import { fetchWithRetry } from '@/lib/util/request'; import { useSnackbar } from '@/hooks/useSnackbar'; // 导入拆分后的组件 import CategoryTabs from './CategoryTabs'; import PromptList from './PromptList'; import PromptDetail from './PromptDetail'; import PromptEditDialog from './PromptEditDialog'; import { getLanguageFromPromptKey, shouldShowPrompt } from './promptUtils'; /** * 提示词设置主组件 */ export default function PromptSettings() { const { projectId } = useParams(); const { i18n, t } = useTranslation(); const { showSuccess, showErrorMessage, SnackbarComponent } = useSnackbar(); // 基础状态 const [currentLanguage, setCurrentLanguage] = useState(i18n.language === 'en' ? 'en' : 'zh-CN'); const [loading, setLoading] = useState(false); const [templates, setTemplates] = useState({}); const [customPrompts, setCustomPrompts] = useState([]); // 当前选中状态 const [selectedCategory, setSelectedCategory] = useState(null); const [selectedPrompt, setSelectedPrompt] = useState(null); const [promptContent, setPromptContent] = useState(''); // 编辑对话框状态 const [editDialog, setEditDialog] = useState({ open: false, promptType: '', promptKey: '', language: '', content: '', defaultContent: '', isNew: false }); // ======= 数据加载与初始化 ======= // 加载提示词数据 useEffect(() => { loadPromptData(); }, [projectId, currentLanguage]); // 监听语言变化 useEffect(() => { const newLang = i18n.language === 'en' ? 'en' : 'zh-CN'; if (newLang !== currentLanguage) { setCurrentLanguage(newLang); } }, [i18n.language, currentLanguage]); // 监听选中提示词变化 useEffect(() => { if (selectedPrompt) { loadPromptContent(); } }, [selectedPrompt]); // 初始化选择第一个分类和提示词 useEffect(() => { if (Object.keys(templates).length > 0 && currentLanguage && !selectedCategory) { const firstCategory = Object.keys(templates)[0]; setSelectedCategory(firstCategory); // 根据当前语言环境选择第一个匹配的提示词 const promptEntries = Object.keys(templates[firstCategory]?.prompts || {}); const firstPrompt = promptEntries.find(promptKey => shouldShowPrompt(promptKey, currentLanguage)); if (firstPrompt) { setSelectedPrompt(firstPrompt); } } }, [templates, selectedCategory, currentLanguage]); // ======= API 操作函数 ======= // 加载提示词数据 const loadPromptData = async () => { try { setLoading(true); const response = await fetchWithRetry(`/api/projects/${projectId}/custom-prompts?language=${currentLanguage}`); const data = await response.json(); if (data.success) { setTemplates(data.templates); setCustomPrompts(data.customPrompts); } else { showErrorMessage(data.message || '加载提示词数据失败'); } } catch (error) { console.error('加载提示词数据出错:', error); showErrorMessage('加载提示词数据失败'); } finally { setLoading(false); } }; // 加载提示词内容 const loadPromptContent = async (forceRefresh = false) => { if (!selectedPrompt) return; try { setLoading(true); const content = await getCurrentPromptContent(selectedPrompt, forceRefresh); setPromptContent(content); } catch (error) { console.error('加载提示词内容出错:', error); showErrorMessage('加载提示词内容失败'); } finally { setLoading(false); } }; // 加载默认提示词内容 const loadDefaultContent = async (promptType, promptKey) => { if (i18n.language === 'en' && !promptKey.endsWith('_EN')) { promptKey += '_EN'; } try { const response = await fetchWithRetry( `/api/projects/${projectId}/default-prompts?promptType=${promptType}&promptKey=${promptKey}` ); const data = await response.json(); if (data.success) { return data.content; } return ''; } catch (error) { console.error('加载默认提示词内容出错:', error); return ''; } }; // ======= 交互处理函数 ======= // 处理编辑提示词 const handleEditPrompt = async (promptType, promptKey, language) => { const existingPrompt = customPrompts.find( p => p.promptType === promptType && p.promptKey === promptKey && p.language === language ); const defaultContent = await loadDefaultContent(promptType, promptKey); setEditDialog({ open: true, promptType, promptKey, language, content: existingPrompt?.content || defaultContent, defaultContent, isNew: !existingPrompt }); }; // 处理删除提示词 const handleDeletePrompt = async (promptType, promptKey, language) => { try { setLoading(true); const query = new URLSearchParams({ promptType, promptKey, language }).toString(); const response = await fetchWithRetry(`/api/projects/${projectId}/custom-prompts?${query}`, { method: 'DELETE' }); const data = await response.json(); if (data.success) { showSuccess(t('settings.prompts.restoreSuccess')); // 先重新加载数据,然后强制刷新内容 await loadPromptData(); await loadPromptContent(true); // 强制刷新 } else { showErrorMessage(data.message || t('settings.prompts.restoreFailed')); } } catch (error) { console.error(t('settings.prompts.deleteError'), error); showErrorMessage(t('settings.prompts.restoreFailed')); } finally { setLoading(false); } }; // 处理保存提示词 const handleSavePrompt = async () => { try { setLoading(true); const { promptType, promptKey, language, content } = editDialog; const response = await fetchWithRetry(`/api/projects/${projectId}/custom-prompts`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ promptType, promptKey, language, content }) }); const data = await response.json(); if (data.success) { showSuccess(t('settings.prompts.saveSuccess')); setEditDialog({ ...editDialog, open: false }); // 先重新加载数据,然后强制刷新内容 await loadPromptData(); await loadPromptContent(true); // 强制刷新 } else { showErrorMessage(data.message || t('settings.prompts.saveFailed')); } } catch (error) { console.error(t('settings.prompts.saveError'), error); showErrorMessage(t('settings.prompts.saveFailed')); } finally { setLoading(false); } }; // 恢复默认内容 const handleRestoreDefault = () => { setEditDialog(prev => ({ ...prev, content: prev.defaultContent })); }; // ======= 工具函数 ======= // 检查提示词是否已自定义 const isCustomized = promptKey => { if (!selectedCategory || !promptKey || !templates[selectedCategory]) return false; const language = getLanguageFromPromptKey(promptKey); const promptType = templates[selectedCategory]?.prompts?.[promptKey]?.type; if (!promptType) return false; return customPrompts.some(p => p.promptType === promptType && p.promptKey === promptKey && p.language === language); }; // 获取当前提示词内容(直接从服务器获取最新数据) const getCurrentPromptContent = async (promptKey, forceRefresh = false) => { if (!selectedCategory || !promptKey || !templates[selectedCategory]) return ''; const language = getLanguageFromPromptKey(promptKey); const promptType = templates[selectedCategory]?.prompts?.[promptKey]?.type; if (!promptType) { return ''; } // 如果需要强制刷新,直接从服务器获取 if (forceRefresh) { try { const response = await fetchWithRetry( `/api/projects/${projectId}/custom-prompts?promptType=${promptType}&language=${language}` ); const data = await response.json(); if (data.success) { const existingPrompt = data.customPrompts.find( p => p.promptType === promptType && p.promptKey === promptKey && p.language === language ); if (existingPrompt) { return existingPrompt.content; } } } catch (error) { console.error(t('settings.prompts.fetchContentError'), error); } } else { // 使用缓存的状态 const existingPrompt = customPrompts.find( p => p.promptType === promptType && p.promptKey === promptKey && p.language === language ); if (existingPrompt) { return existingPrompt.content; } } // 回退到默认内容 return await loadDefaultContent(promptType, promptKey); }; // ======= 数据准备 ======= // 当前分类的配置 const currentCategoryConfig = templates[selectedCategory]; // 当前提示词的配置 const currentPromptConfig = currentCategoryConfig?.prompts?.[selectedPrompt]; // 分类配置项 const categoryEntries = Object.entries(templates); // 处理分类变更 const handleCategoryChange = newCategory => { setSelectedCategory(newCategory); // 根据当前语言环境选择第一个匹配的提示词 const promptEntries = Object.keys(templates[newCategory]?.prompts || {}); console.log('所有提示词:', promptEntries); const firstPrompt = promptEntries.find(promptKey => shouldShowPrompt(promptKey, currentLanguage)); setSelectedPrompt(firstPrompt); }; // 处理编辑按钮点击 const handleEditButtonClick = () => { const promptType = templates[selectedCategory]?.prompts?.[selectedPrompt]?.type; // 使用当前界面语言而不是从 promptKey 推断的语言 const language = currentLanguage; if (promptType) { handleEditPrompt(promptType, selectedPrompt, language); } }; // 处理删除按钮点击 const handleDeleteButtonClick = () => { const promptType = templates[selectedCategory]?.prompts?.[selectedPrompt]?.type; // 使用当前界面语言而不是从 promptKey 推断的语言 const language = currentLanguage; if (promptType) { handleDeletePrompt(promptType, selectedPrompt, language); } }; // 处理对话框内容变更 const handleDialogContentChange = newContent => { setEditDialog({ ...editDialog, content: newContent }); }; return ( {/* 主要分类选择 */} {/* 左右布局:左侧垂直提示词选择,右侧内容展示 */} {/* 左侧:垂直 TAB 选择具体提示词 */} {/* 右侧:提示词内容展示和操作 */} {/* 编辑提示词对话框 */} setEditDialog({ ...editDialog, open: false })} onSave={handleSavePrompt} onRestore={handleRestoreDefault} onContentChange={handleDialogContentChange} /> ); }