2025-11-11 19:50:12 +08:00
|
|
|
|
import { useState, useEffect } from 'react';
|
2025-11-26 14:56:13 +08:00
|
|
|
|
import { useNavigate, useSearchParams } from 'react-router-dom';
|
2025-10-30 11:14:43 +08:00
|
|
|
|
import {
|
2025-11-26 14:56:13 +08:00
|
|
|
|
Form, Input, InputNumber, Select, Button, Card,
|
2025-11-27 17:29:23 +08:00
|
|
|
|
Row, Col, Typography, Space, message, Radio
|
2025-10-30 11:14:43 +08:00
|
|
|
|
} from 'antd';
|
|
|
|
|
|
import {
|
2025-11-27 17:29:23 +08:00
|
|
|
|
RocketOutlined, ArrowLeftOutlined, CheckCircleOutlined
|
2025-10-30 11:14:43 +08:00
|
|
|
|
} from '@ant-design/icons';
|
2025-11-26 14:56:13 +08:00
|
|
|
|
import { AIProjectGenerator, type GenerationConfig } from '../components/AIProjectGenerator';
|
|
|
|
|
|
import type { WizardBasicInfo } from '../types';
|
2025-10-30 11:14:43 +08:00
|
|
|
|
|
|
|
|
|
|
const { TextArea } = Input;
|
2025-11-26 14:56:13 +08:00
|
|
|
|
const { Title, Paragraph } = Typography;
|
2025-10-30 11:14:43 +08:00
|
|
|
|
|
|
|
|
|
|
export default function ProjectWizardNew() {
|
|
|
|
|
|
const navigate = useNavigate();
|
2025-11-26 14:56:13 +08:00
|
|
|
|
const [searchParams] = useSearchParams();
|
2025-10-30 11:14:43 +08:00
|
|
|
|
const [form] = Form.useForm();
|
|
|
|
|
|
const [isMobile, setIsMobile] = useState(window.innerWidth <= 768);
|
2025-12-11 17:01:25 +08:00
|
|
|
|
|
2025-11-11 19:50:12 +08:00
|
|
|
|
// 状态管理
|
2025-11-26 14:56:13 +08:00
|
|
|
|
const [currentStep, setCurrentStep] = useState<'form' | 'generating'>('form');
|
|
|
|
|
|
const [generationConfig, setGenerationConfig] = useState<GenerationConfig | null>(null);
|
|
|
|
|
|
const [resumeProjectId, setResumeProjectId] = useState<string | null>(null);
|
2025-10-30 11:14:43 +08:00
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2025-11-11 19:50:12 +08:00
|
|
|
|
const handleResize = () => {
|
|
|
|
|
|
setIsMobile(window.innerWidth <= 768);
|
2025-10-30 11:14:43 +08:00
|
|
|
|
};
|
2025-11-11 19:50:12 +08:00
|
|
|
|
window.addEventListener('resize', handleResize);
|
|
|
|
|
|
return () => window.removeEventListener('resize', handleResize);
|
|
|
|
|
|
}, []);
|
2025-10-30 11:14:43 +08:00
|
|
|
|
|
2025-11-26 14:56:13 +08:00
|
|
|
|
// 检查URL参数,如果有project_id则恢复生成
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
const projectId = searchParams.get('project_id');
|
|
|
|
|
|
if (projectId) {
|
|
|
|
|
|
setResumeProjectId(projectId);
|
|
|
|
|
|
handleResumeGeneration(projectId);
|
|
|
|
|
|
}
|
|
|
|
|
|
}, [searchParams]);
|
2025-10-30 11:14:43 +08:00
|
|
|
|
|
2025-11-26 14:56:13 +08:00
|
|
|
|
// 恢复未完成项目的生成
|
|
|
|
|
|
const handleResumeGeneration = async (projectId: string) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const response = await fetch(`/api/projects/${projectId}`, {
|
|
|
|
|
|
credentials: 'include'
|
|
|
|
|
|
});
|
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
|
throw new Error('获取项目信息失败');
|
2025-10-30 11:14:43 +08:00
|
|
|
|
}
|
2025-11-26 14:56:13 +08:00
|
|
|
|
const project = await response.json();
|
2025-12-11 17:01:25 +08:00
|
|
|
|
|
2025-11-26 14:56:13 +08:00
|
|
|
|
const config: GenerationConfig = {
|
|
|
|
|
|
title: project.title,
|
|
|
|
|
|
description: project.description || '',
|
|
|
|
|
|
theme: project.theme || '',
|
|
|
|
|
|
genre: project.genre || '',
|
|
|
|
|
|
narrative_perspective: project.narrative_perspective || '第三人称',
|
|
|
|
|
|
target_words: project.target_words || 100000,
|
|
|
|
|
|
chapter_count: 3,
|
|
|
|
|
|
character_count: project.character_count || 5,
|
|
|
|
|
|
};
|
2025-12-11 17:01:25 +08:00
|
|
|
|
|
2025-11-26 14:56:13 +08:00
|
|
|
|
setGenerationConfig(config);
|
|
|
|
|
|
setCurrentStep('generating');
|
2025-10-30 11:14:43 +08:00
|
|
|
|
} catch (error) {
|
2025-11-26 14:56:13 +08:00
|
|
|
|
console.error('恢复生成失败:', error);
|
|
|
|
|
|
message.error('恢复生成失败,请重试');
|
|
|
|
|
|
navigate('/');
|
2025-10-30 11:14:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-11-26 14:56:13 +08:00
|
|
|
|
// 开始生成流程
|
|
|
|
|
|
const handleAutoGenerate = async (values: WizardBasicInfo) => {
|
|
|
|
|
|
const config: GenerationConfig = {
|
|
|
|
|
|
title: values.title,
|
|
|
|
|
|
description: values.description,
|
|
|
|
|
|
theme: values.theme,
|
|
|
|
|
|
genre: values.genre,
|
|
|
|
|
|
narrative_perspective: values.narrative_perspective,
|
|
|
|
|
|
target_words: values.target_words || 100000,
|
|
|
|
|
|
chapter_count: 3, // 默认生成3章大纲
|
|
|
|
|
|
character_count: values.character_count || 5,
|
2025-11-27 17:29:23 +08:00
|
|
|
|
outline_mode: values.outline_mode || 'one-to-many', // 添加大纲模式
|
2025-11-26 14:56:13 +08:00
|
|
|
|
};
|
2025-12-11 17:01:25 +08:00
|
|
|
|
|
2025-11-26 14:56:13 +08:00
|
|
|
|
setGenerationConfig(config);
|
|
|
|
|
|
setCurrentStep('generating');
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 生成完成回调
|
|
|
|
|
|
const handleComplete = (projectId: string) => {
|
|
|
|
|
|
console.log('项目创建完成:', projectId);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 返回表单页面
|
|
|
|
|
|
const handleBack = () => {
|
|
|
|
|
|
setCurrentStep('form');
|
|
|
|
|
|
setGenerationConfig(null);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-11-11 19:50:12 +08:00
|
|
|
|
// 渲染表单页面
|
|
|
|
|
|
const renderForm = () => (
|
2025-10-30 11:14:43 +08:00
|
|
|
|
<Card>
|
2025-11-11 19:50:12 +08:00
|
|
|
|
<Title level={isMobile ? 4 : 3} style={{ marginBottom: 24 }}>
|
|
|
|
|
|
创建新项目
|
|
|
|
|
|
</Title>
|
|
|
|
|
|
<Paragraph type="secondary" style={{ marginBottom: 32 }}>
|
2025-11-21 15:49:39 +08:00
|
|
|
|
填写基本信息后,AI将自动为您生成世界观、角色和大纲节点(大纲可在项目内手动展开为章节)
|
2025-11-11 19:50:12 +08:00
|
|
|
|
</Paragraph>
|
|
|
|
|
|
|
|
|
|
|
|
<Form
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
layout="vertical"
|
|
|
|
|
|
onFinish={handleAutoGenerate}
|
|
|
|
|
|
initialValues={{
|
|
|
|
|
|
genre: ['玄幻'],
|
|
|
|
|
|
chapter_count: 30,
|
|
|
|
|
|
narrative_perspective: '第三人称',
|
|
|
|
|
|
character_count: 5,
|
|
|
|
|
|
target_words: 100000,
|
2025-11-27 17:29:23 +08:00
|
|
|
|
outline_mode: 'one-to-many', // 默认为细化模式
|
2025-11-11 19:50:12 +08:00
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Form.Item
|
|
|
|
|
|
label="书名"
|
|
|
|
|
|
name="title"
|
|
|
|
|
|
rules={[{ required: true, message: '请输入书名' }]}
|
|
|
|
|
|
>
|
2025-10-30 11:14:43 +08:00
|
|
|
|
<Input placeholder="输入你的小说标题" size="large" />
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
|
2025-11-11 19:50:12 +08:00
|
|
|
|
<Form.Item
|
|
|
|
|
|
label="小说简介"
|
|
|
|
|
|
name="description"
|
|
|
|
|
|
rules={[{ required: true, message: '请输入小说简介' }]}
|
|
|
|
|
|
>
|
|
|
|
|
|
<TextArea
|
|
|
|
|
|
rows={3}
|
|
|
|
|
|
placeholder="用一段话介绍你的小说..."
|
|
|
|
|
|
showCount
|
|
|
|
|
|
maxLength={300}
|
|
|
|
|
|
/>
|
2025-10-30 11:14:43 +08:00
|
|
|
|
</Form.Item>
|
|
|
|
|
|
|
2025-11-11 19:50:12 +08:00
|
|
|
|
<Form.Item
|
|
|
|
|
|
label="主题"
|
|
|
|
|
|
name="theme"
|
|
|
|
|
|
rules={[{ required: true, message: '请输入主题' }]}
|
|
|
|
|
|
>
|
|
|
|
|
|
<TextArea
|
|
|
|
|
|
rows={4}
|
|
|
|
|
|
placeholder="描述你的小说主题..."
|
|
|
|
|
|
showCount
|
|
|
|
|
|
maxLength={500}
|
|
|
|
|
|
/>
|
2025-10-30 11:14:43 +08:00
|
|
|
|
</Form.Item>
|
|
|
|
|
|
|
2025-11-11 19:50:12 +08:00
|
|
|
|
<Form.Item
|
|
|
|
|
|
label="类型"
|
|
|
|
|
|
name="genre"
|
|
|
|
|
|
rules={[{ required: true, message: '请选择小说类型' }]}
|
|
|
|
|
|
>
|
2025-10-30 11:14:43 +08:00
|
|
|
|
<Select
|
|
|
|
|
|
mode="tags"
|
2025-11-11 19:50:12 +08:00
|
|
|
|
placeholder="选择或输入类型标签(如:玄幻、都市、修仙)"
|
2025-10-30 11:14:43 +08:00
|
|
|
|
size="large"
|
|
|
|
|
|
tokenSeparators={[',']}
|
|
|
|
|
|
maxTagCount={5}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Select.Option value="玄幻">玄幻</Select.Option>
|
|
|
|
|
|
<Select.Option value="都市">都市</Select.Option>
|
|
|
|
|
|
<Select.Option value="历史">历史</Select.Option>
|
|
|
|
|
|
<Select.Option value="科幻">科幻</Select.Option>
|
|
|
|
|
|
<Select.Option value="武侠">武侠</Select.Option>
|
|
|
|
|
|
<Select.Option value="仙侠">仙侠</Select.Option>
|
|
|
|
|
|
<Select.Option value="奇幻">奇幻</Select.Option>
|
|
|
|
|
|
<Select.Option value="悬疑">悬疑</Select.Option>
|
|
|
|
|
|
<Select.Option value="言情">言情</Select.Option>
|
|
|
|
|
|
<Select.Option value="修仙">修仙</Select.Option>
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
|
2025-11-27 17:29:23 +08:00
|
|
|
|
<Form.Item
|
|
|
|
|
|
label="大纲章节模式"
|
|
|
|
|
|
name="outline_mode"
|
|
|
|
|
|
rules={[{ required: true, message: '请选择大纲章节模式' }]}
|
|
|
|
|
|
tooltip="创建后不可更改,请根据创作习惯选择"
|
|
|
|
|
|
>
|
|
|
|
|
|
<Radio.Group size="large">
|
|
|
|
|
|
<Row gutter={16}>
|
|
|
|
|
|
<Col xs={24} sm={12}>
|
|
|
|
|
|
<Card
|
|
|
|
|
|
hoverable
|
|
|
|
|
|
style={{
|
2025-12-11 17:01:25 +08:00
|
|
|
|
borderColor: form.getFieldValue('outline_mode') === 'one-to-one' ? 'var(--color-primary)' : 'var(--color-border)',
|
2025-11-27 17:29:23 +08:00
|
|
|
|
borderWidth: 2,
|
|
|
|
|
|
height: '100%',
|
|
|
|
|
|
}}
|
|
|
|
|
|
onClick={() => form.setFieldValue('outline_mode', 'one-to-one')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Radio value="one-to-one" style={{ width: '100%' }}>
|
|
|
|
|
|
<Space direction="vertical" size={4} style={{ width: '100%' }}>
|
|
|
|
|
|
<div style={{ fontSize: 16, fontWeight: 'bold' }}>
|
2025-12-11 17:01:25 +08:00
|
|
|
|
<CheckCircleOutlined style={{ marginRight: 8, color: 'var(--color-success)' }} />
|
2025-11-27 17:29:23 +08:00
|
|
|
|
传统模式 (1→1)
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div style={{ fontSize: 12, color: '#666' }}>
|
|
|
|
|
|
一个大纲对应一个章节,简单直接
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div style={{ fontSize: 11, color: '#999' }}>
|
|
|
|
|
|
💡 适合:简单剧情、快速创作、短篇小说
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Space>
|
|
|
|
|
|
</Radio>
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
</Col>
|
2025-12-11 17:01:25 +08:00
|
|
|
|
|
2025-11-27 17:29:23 +08:00
|
|
|
|
<Col xs={24} sm={12}>
|
|
|
|
|
|
<Card
|
|
|
|
|
|
hoverable
|
|
|
|
|
|
style={{
|
2025-12-11 17:01:25 +08:00
|
|
|
|
borderColor: form.getFieldValue('outline_mode') === 'one-to-many' ? 'var(--color-primary)' : 'var(--color-border)',
|
2025-11-27 17:29:23 +08:00
|
|
|
|
borderWidth: 2,
|
|
|
|
|
|
height: '100%',
|
|
|
|
|
|
}}
|
|
|
|
|
|
onClick={() => form.setFieldValue('outline_mode', 'one-to-many')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Radio value="one-to-many" style={{ width: '100%' }}>
|
|
|
|
|
|
<Space direction="vertical" size={4} style={{ width: '100%' }}>
|
|
|
|
|
|
<div style={{ fontSize: 16, fontWeight: 'bold' }}>
|
2025-12-11 17:01:25 +08:00
|
|
|
|
<CheckCircleOutlined style={{ marginRight: 8, color: 'var(--color-success)' }} />
|
2025-11-27 17:29:23 +08:00
|
|
|
|
细化模式 (1→N) 推荐
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div style={{ fontSize: 12, color: '#666' }}>
|
|
|
|
|
|
一个大纲可展开为多个章节,灵活控制
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div style={{ fontSize: 11, color: '#999' }}>
|
|
|
|
|
|
💡 适合:复杂剧情、长篇创作、需要细化控制
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Space>
|
|
|
|
|
|
</Radio>
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
</Radio.Group>
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
|
2025-11-11 19:50:12 +08:00
|
|
|
|
<Row gutter={16}>
|
|
|
|
|
|
<Col xs={24} sm={12}>
|
|
|
|
|
|
<Form.Item
|
|
|
|
|
|
label="叙事视角"
|
|
|
|
|
|
name="narrative_perspective"
|
|
|
|
|
|
rules={[{ required: true, message: '请选择叙事视角' }]}
|
2025-11-03 15:28:51 +08:00
|
|
|
|
>
|
2025-11-11 19:50:12 +08:00
|
|
|
|
<Select size="large" placeholder="选择小说的叙事视角">
|
|
|
|
|
|
<Select.Option value="第一人称">第一人称</Select.Option>
|
|
|
|
|
|
<Select.Option value="第三人称">第三人称</Select.Option>
|
|
|
|
|
|
<Select.Option value="全知视角">全知视角</Select.Option>
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
<Col xs={24} sm={12}>
|
|
|
|
|
|
<Form.Item
|
|
|
|
|
|
label="角色数量"
|
|
|
|
|
|
name="character_count"
|
|
|
|
|
|
rules={[{ required: true, message: '请输入角色数量' }]}
|
|
|
|
|
|
>
|
|
|
|
|
|
<InputNumber
|
|
|
|
|
|
min={3}
|
|
|
|
|
|
max={20}
|
|
|
|
|
|
style={{ width: '100%' }}
|
|
|
|
|
|
size="large"
|
|
|
|
|
|
addonAfter="个"
|
|
|
|
|
|
placeholder="AI生成的角色数量"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
</Col>
|
2025-10-30 11:14:43 +08:00
|
|
|
|
</Row>
|
|
|
|
|
|
|
2025-11-11 19:50:12 +08:00
|
|
|
|
<Form.Item
|
|
|
|
|
|
label="目标字数"
|
|
|
|
|
|
name="target_words"
|
|
|
|
|
|
rules={[{ required: true, message: '请输入目标字数' }]}
|
|
|
|
|
|
>
|
|
|
|
|
|
<InputNumber
|
|
|
|
|
|
min={10000}
|
|
|
|
|
|
style={{ width: '100%' }}
|
2025-10-30 11:14:43 +08:00
|
|
|
|
size="large"
|
2025-11-11 19:50:12 +08:00
|
|
|
|
addonAfter="字"
|
|
|
|
|
|
placeholder="整部小说的目标字数"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Form.Item>
|
2025-10-30 11:14:43 +08:00
|
|
|
|
|
2025-11-11 19:50:12 +08:00
|
|
|
|
<Form.Item>
|
|
|
|
|
|
<Space direction="vertical" style={{ width: '100%' }} size={12}>
|
2025-10-30 11:14:43 +08:00
|
|
|
|
<Button
|
2025-11-11 19:50:12 +08:00
|
|
|
|
type="primary"
|
|
|
|
|
|
htmlType="submit"
|
2025-10-30 11:14:43 +08:00
|
|
|
|
size="large"
|
|
|
|
|
|
block
|
2025-11-11 19:50:12 +08:00
|
|
|
|
icon={<RocketOutlined />}
|
2025-10-30 11:14:43 +08:00
|
|
|
|
>
|
2025-11-11 19:50:12 +08:00
|
|
|
|
开始创建项目
|
2025-10-30 11:14:43 +08:00
|
|
|
|
</Button>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
size="large"
|
|
|
|
|
|
block
|
2025-11-11 19:50:12 +08:00
|
|
|
|
onClick={() => navigate('/')}
|
2025-10-30 11:14:43 +08:00
|
|
|
|
>
|
2025-11-11 19:50:12 +08:00
|
|
|
|
返回首页
|
2025-10-30 11:14:43 +08:00
|
|
|
|
</Button>
|
2025-11-11 19:50:12 +08:00
|
|
|
|
</Space>
|
|
|
|
|
|
</Form.Item>
|
2025-10-30 11:14:43 +08:00
|
|
|
|
</Form>
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
minHeight: '100vh',
|
2025-12-11 17:01:25 +08:00
|
|
|
|
background: 'var(--color-bg-base)',
|
2025-10-30 11:14:43 +08:00
|
|
|
|
}}>
|
2025-11-11 19:50:12 +08:00
|
|
|
|
{/* 顶部标题栏 - 固定不滚动 */}
|
2025-10-30 11:14:43 +08:00
|
|
|
|
<div style={{
|
2025-11-11 19:50:12 +08:00
|
|
|
|
position: 'sticky',
|
|
|
|
|
|
top: 0,
|
|
|
|
|
|
zIndex: 100,
|
2025-12-11 17:01:25 +08:00
|
|
|
|
background: 'var(--color-primary)',
|
|
|
|
|
|
boxShadow: 'var(--shadow-header)',
|
2025-10-30 11:14:43 +08:00
|
|
|
|
}}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
maxWidth: 1200,
|
|
|
|
|
|
margin: '0 auto',
|
|
|
|
|
|
display: 'flex',
|
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
|
justifyContent: 'space-between',
|
2025-11-11 19:50:12 +08:00
|
|
|
|
padding: isMobile ? '12px 16px' : '16px 24px',
|
2025-10-30 11:14:43 +08:00
|
|
|
|
}}>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
icon={<ArrowLeftOutlined />}
|
|
|
|
|
|
onClick={() => navigate('/')}
|
|
|
|
|
|
size={isMobile ? 'middle' : 'large'}
|
2025-11-11 19:50:12 +08:00
|
|
|
|
disabled={currentStep === 'generating'}
|
2025-10-30 11:14:43 +08:00
|
|
|
|
style={{
|
|
|
|
|
|
background: 'rgba(255,255,255,0.2)',
|
|
|
|
|
|
borderColor: 'rgba(255,255,255,0.3)',
|
|
|
|
|
|
color: '#fff',
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
2025-11-11 19:50:12 +08:00
|
|
|
|
{isMobile ? '返回' : '返回首页'}
|
2025-10-30 11:14:43 +08:00
|
|
|
|
</Button>
|
2025-12-11 17:01:25 +08:00
|
|
|
|
|
2025-10-30 11:14:43 +08:00
|
|
|
|
<Title level={isMobile ? 4 : 2} style={{
|
|
|
|
|
|
margin: 0,
|
|
|
|
|
|
color: '#fff',
|
|
|
|
|
|
textShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
|
|
|
|
|
}}>
|
2025-11-11 19:50:12 +08:00
|
|
|
|
项目创建向导
|
2025-10-30 11:14:43 +08:00
|
|
|
|
</Title>
|
2025-12-11 17:01:25 +08:00
|
|
|
|
|
2025-11-11 19:50:12 +08:00
|
|
|
|
<div style={{ width: isMobile ? 60 : 120 }}></div>
|
2025-10-30 11:14:43 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2025-11-11 19:50:12 +08:00
|
|
|
|
{/* 内容区域 */}
|
2025-10-30 11:14:43 +08:00
|
|
|
|
<div style={{
|
2025-11-11 19:50:12 +08:00
|
|
|
|
maxWidth: 800,
|
2025-10-30 11:14:43 +08:00
|
|
|
|
margin: '0 auto',
|
2025-11-11 19:50:12 +08:00
|
|
|
|
padding: isMobile ? '16px 12px' : '24px 24px',
|
2025-10-30 11:14:43 +08:00
|
|
|
|
}}>
|
2025-11-11 19:50:12 +08:00
|
|
|
|
{currentStep === 'form' && renderForm()}
|
2025-11-26 14:56:13 +08:00
|
|
|
|
{currentStep === 'generating' && generationConfig && (
|
|
|
|
|
|
<AIProjectGenerator
|
|
|
|
|
|
config={generationConfig}
|
|
|
|
|
|
storagePrefix="wizard"
|
|
|
|
|
|
onComplete={handleComplete}
|
|
|
|
|
|
onBack={handleBack}
|
|
|
|
|
|
isMobile={isMobile}
|
|
|
|
|
|
resumeProjectId={resumeProjectId || undefined}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
2025-10-30 11:14:43 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
2025-11-11 19:50:12 +08:00
|
|
|
|
}
|