import { Card, Descriptions, Empty, Typography, Button, Modal, Form, Input, message, Flex, InputNumber, Select, theme } from 'antd'; import { GlobalOutlined, EditOutlined, SyncOutlined, FormOutlined } from '@ant-design/icons'; import { useState } from 'react'; import { useStore } from '../store'; import { worldSettingCardStyles } from '../components/CardStyles'; import { projectApi, wizardStreamApi } from '../services/api'; import { SSELoadingOverlay } from '../components/SSELoadingOverlay'; const { Title, Paragraph } = Typography; const { TextArea } = Input; export default function WorldSetting() { const { currentProject, setCurrentProject } = useStore(); const [isEditModalVisible, setIsEditModalVisible] = useState(false); const [editForm] = Form.useForm(); const [isSaving, setIsSaving] = useState(false); const [isEditProjectModalVisible, setIsEditProjectModalVisible] = useState(false); const [editProjectForm] = Form.useForm(); const [isSavingProject, setIsSavingProject] = useState(false); const [isRegenerating, setIsRegenerating] = useState(false); const [regenerateProgress, setRegenerateProgress] = useState(0); const [regenerateMessage, setRegenerateMessage] = useState(''); const [isPreviewModalVisible, setIsPreviewModalVisible] = useState(false); const [newWorldData, setNewWorldData] = useState<{ time_period: string; location: string; atmosphere: string; rules: string; } | null>(null); const [isSavingPreview, setIsSavingPreview] = useState(false); const [modal, contextHolder] = Modal.useModal(); const { token } = theme.useToken(); // AI重新生成世界观 const handleRegenerate = async () => { if (!currentProject) return; modal.confirm({ title: '确认重新生成', content: '确定要使用AI重新生成世界观设定吗?这将替换当前的世界观内容。', centered: true, okText: '确认重新生成', cancelText: '取消', onOk: async () => { setIsRegenerating(true); setRegenerateProgress(0); setRegenerateMessage('准备重新生成世界观...'); try { await wizardStreamApi.regenerateWorldBuildingStream( currentProject.id, {}, { onProgress: (msg: string, progress: number) => { setRegenerateProgress(progress); setRegenerateMessage(msg); }, onChunk: (chunk: string) => { // 可以在这里显示生成的内容片段(可选) console.log('生成片段:', chunk); }, onResult: (result: { time_period: string; location: string; atmosphere: string; rules: string }) => { // 保存新生成的数据 const newData = { time_period: result.time_period, location: result.location, atmosphere: result.atmosphere, rules: result.rules, }; setNewWorldData(newData); }, onError: (errorMsg: string) => { console.error('重新生成失败:', errorMsg); message.error(errorMsg || '重新生成失败,请重试'); }, onComplete: () => { setIsRegenerating(false); setRegenerateProgress(0); setRegenerateMessage(''); // 显示预览对话框 setIsPreviewModalVisible(true); } } ); } catch (error) { console.error('重新生成出错:', error); message.error('重新生成出错,请重试'); setIsRegenerating(false); setRegenerateProgress(0); setRegenerateMessage(''); } } }); }; // 确认保存重新生成的内容 const handleConfirmSave = async () => { if (!currentProject || !newWorldData) return; setIsSavingPreview(true); try { const updatedProject = await projectApi.updateProject(currentProject.id, { world_time_period: newWorldData.time_period, world_location: newWorldData.location, world_atmosphere: newWorldData.atmosphere, world_rules: newWorldData.rules, }); setCurrentProject(updatedProject); message.success('世界观已更新!'); setIsPreviewModalVisible(false); setNewWorldData(null); } catch (error) { console.error('保存失败:', error); message.error('保存失败,请重试'); } finally { setIsSavingPreview(false); } }; // 取消保存,关闭预览 const handleCancelSave = () => { setIsPreviewModalVisible(false); setNewWorldData(null); message.info('已取消,保持原有内容'); }; if (!currentProject) return null; // 检查是否有世界设定信息 const hasWorldSetting = currentProject.world_time_period || currentProject.world_location || currentProject.world_atmosphere || currentProject.world_rules; if (!hasWorldSetting) { return (
{/* 固定头部 */}

世界设定

{/* 可滚动内容区域 */}
世界设定信息在创建项目向导中生成,用于构建小说的世界观背景。
); } return (
{contextHolder} {/* 固定头部 */}

世界设定

{/* 可滚动内容区域 */}
基础信息 } > {currentProject.title} {currentProject.description && ( {currentProject.description} )} {currentProject.theme || '未设定'} {currentProject.genre || '未设定'} {currentProject.narrative_perspective || '未设定'} {currentProject.target_words ? `${currentProject.target_words.toLocaleString()} 字` : '未设定'} 小说世界观 } >
{currentProject.world_time_period && (
时间设定 {currentProject.world_time_period}
)} {currentProject.world_location && (
地点设定 {currentProject.world_location}
)} {currentProject.world_atmosphere && (
氛围设定 {currentProject.world_atmosphere}
)} {currentProject.world_rules && (
规则设定 {currentProject.world_rules}
)}
{/* 编辑世界观模态框 */} { setIsEditModalVisible(false); editForm.resetFields(); }} onOk={async () => { try { const values = await editForm.validateFields(); setIsSaving(true); const updatedProject = await projectApi.updateProject(currentProject.id, { world_time_period: values.world_time_period, world_location: values.world_location, world_atmosphere: values.world_atmosphere, world_rules: values.world_rules, }); setCurrentProject(updatedProject); message.success('世界观更新成功'); setIsEditModalVisible(false); editForm.resetFields(); } catch (error) { console.error('更新世界观失败:', error); message.error('更新失败,请重试'); } finally { setIsSaving(false); } }} confirmLoading={isSaving} width={800} okText="保存" cancelText="取消" >