diff --git a/frontend/src/pages/ProjectList.tsx b/frontend/src/pages/ProjectList.tsx index 097cffa..94546f9 100644 --- a/frontend/src/pages/ProjectList.tsx +++ b/frontend/src/pages/ProjectList.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; -import { Card, Button, Empty, Modal, message, Spin, Row, Col, Statistic, Space, Tag, Progress, Typography, Tooltip, Badge, Alert, Upload, Checkbox, Divider, Switch, Dropdown } from 'antd'; +import { Card, Button, Empty, Modal, message, Spin, Row, Col, Statistic, Space, Tag, Progress, Typography, Tooltip, Badge, Alert, Upload, Checkbox, Divider, Switch, Dropdown, Form, Input, InputNumber } from 'antd'; import { EditOutlined, DeleteOutlined, BookOutlined, RocketOutlined, CalendarOutlined, FileTextOutlined, TrophyOutlined, FireOutlined, SettingOutlined, InfoCircleOutlined, CloseOutlined, UploadOutlined, DownloadOutlined, ApiOutlined, MoreOutlined, BulbOutlined } from '@ant-design/icons'; import { projectApi } from '../services/api'; import { useStore } from '../store'; @@ -27,6 +27,10 @@ export default function ProjectList() { includeWritingStyles: true, includeGenerationHistory: true, }); + const [editModalVisible, setEditModalVisible] = useState(false); + const [editingProject, setEditingProject] = useState(null); + const [editForm] = Form.useForm(); + const [updating, setUpdating] = useState(false); const { refreshProjects, deleteProject } = useProjectSync(); @@ -72,6 +76,45 @@ export default function ProjectList() { }); }; + const handleEditProject = (project: any) => { + setEditingProject(project); + editForm.setFieldsValue({ + description: project.description || '', + target_words: project.target_words || 0, + }); + setEditModalVisible(true); + }; + + const handleCloseEditModal = () => { + setEditModalVisible(false); + setEditingProject(null); + editForm.resetFields(); + }; + + const handleUpdateProject = async () => { + try { + const values = await editForm.validateFields(); + setUpdating(true); + + await projectApi.updateProject(editingProject.id, { + description: values.description, + target_words: values.target_words, + }); + + message.success('项目更新成功'); + handleCloseEditModal(); + await refreshProjects(); + } catch (error: any) { + if (error.errorFields) { + message.error('请检查表单填写'); + } else { + message.error('更新失败,请重试'); + } + } finally { + setUpdating(false); + } + }; + const handleEnterProject = (id: string) => { // 简化后直接进入项目,不再检查向导状态 navigate(`/project/${id}`); @@ -783,15 +826,26 @@ export default function ProjectList() { {formatDate(project.updated_at)} + + + + + + {/* 可滚动内容区域 */} @@ -302,6 +417,101 @@ export default function WorldSetting() { + + {/* AI重新生成加载遮罩 */} + + + {/* 预览重新生成的内容模态框 */} + + {newWorldData && ( +
+
+ + ⚠️ 注意:点击"确认替换"将会用新内容替换当前的世界观设定 + +
+ +
+ + 时间设定 + + + {newWorldData.time_period} + +
+ +
+ + 地点设定 + + + {newWorldData.location} + +
+ +
+ + 氛围设定 + + + {newWorldData.atmosphere} + +
+ +
+ + 规则设定 + + + {newWorldData.rules} + +
+
+ )} +
); } \ No newline at end of file