import { Modal, Form, Input, InputNumber, Select, Tag, Space, Button, message, Divider } from 'antd'; import { PlusOutlined } from '@ant-design/icons'; import { useState, useEffect } from 'react'; import type { ExpansionPlanData, Character } from '../types'; import { characterApi } from '../services/api'; const { TextArea } = Input; interface ExpansionPlanEditorProps { visible: boolean; planData: ExpansionPlanData | null; chapterSummary: string | null; projectId: string; onSave: (data: ExpansionPlanData & { summary?: string }) => Promise; onCancel: () => void; } export default function ExpansionPlanEditor({ visible, planData, chapterSummary, projectId, onSave, onCancel }: ExpansionPlanEditorProps) { const [form] = Form.useForm(); const [loading, setLoading] = useState(false); // 关键事件标签输入 const [keyEventInput, setKeyEventInput] = useState(''); const [keyEvents, setKeyEvents] = useState([]); // 角色列表和选择 const [availableCharacters, setAvailableCharacters] = useState([]); const [characters, setCharacters] = useState([]); const [loadingCharacters, setLoadingCharacters] = useState(false); // 加载项目角色列表 useEffect(() => { if (visible && projectId) { loadCharacters(); } }, [visible, projectId]); const loadCharacters = async () => { try { setLoadingCharacters(true); setAvailableCharacters([]); // 重置为空数组 const response = await characterApi.getCharacters(projectId); console.log('加载到的角色数据:', response); // API返回的是 {total, items} 格式,需要提取items let chars: Character[] = []; if (Array.isArray(response)) { chars = response; } else if (response && typeof response === 'object' && 'items' in response && Array.isArray((response as any).items)) { chars = (response as any).items; } else { console.error('角色API返回格式异常:', response); message.warning('角色数据格式异常'); } setAvailableCharacters(chars); console.log('设置的角色列表:', chars); } catch (error: any) { console.error('加载角色列表失败:', error); setAvailableCharacters([]); message.error('加载角色列表失败: ' + (error?.message || '未知错误')); } finally { setLoadingCharacters(false); } }; // 当planData或chapterSummary变化时更新状态 useEffect(() => { if (visible) { if (planData) { setKeyEvents(planData.key_events || []); setCharacters(planData.character_focus || []); form.setFieldsValue({ summary: chapterSummary || '', emotional_tone: planData.emotional_tone, narrative_goal: planData.narrative_goal, conflict_type: planData.conflict_type, estimated_words: planData.estimated_words }); } else { // 重置状态 setKeyEvents([]); setCharacters([]); form.setFieldsValue({ summary: chapterSummary || '' }); } } }, [planData, chapterSummary, form, visible]); const handleAddKeyEvent = () => { if (keyEventInput.trim()) { setKeyEvents([...keyEvents, keyEventInput.trim()]); setKeyEventInput(''); } }; const handleAddCharacter = (characterName: string) => { if (characterName && !characters.includes(characterName)) { setCharacters([...characters, characterName]); } }; const handleSubmit = async () => { try { setLoading(true); const values = await form.validateFields(); // 验证至少有一个关键事件 if (keyEvents.length === 0) { message.warning('请至少添加一个关键事件'); setLoading(false); return; } // 验证至少有一个角色 if (characters.length === 0) { message.warning('请至少添加一个涉及角色'); setLoading(false); return; } const updatedPlan: ExpansionPlanData & { summary?: string } = { summary: values.summary, key_events: keyEvents, character_focus: characters, emotional_tone: values.emotional_tone, narrative_goal: values.narrative_goal, conflict_type: values.conflict_type, estimated_words: values.estimated_words, scenes: planData?.scenes || null }; await onSave(updatedPlan); // message.success('规划信息保存成功'); } catch (error) { console.error('保存失败:', error); message.error('保存失败,请重试'); } finally { setLoading(false); } }; const handleCancel = () => { form.resetFields(); setKeyEvents([]); setCharacters([]); setKeyEventInput(''); onCancel(); }; return ( 取消 , ]} >
{/* 情节概要 */}