use anyhow::{Context, Result}; use colored::*; use std::fs; use std::path::{Path, PathBuf}; use crate::template; pub fn generate_project(name: &str, template_name: &str, output_dir: &Path) -> Result<()> { // 验证模板存在 let template = template::get_template(template_name) .ok_or_else(|| anyhow::anyhow!("模板 '{}' 不存在", template_name))?; println!("📝 使用模板: {}", template.name.bright_green()); println!("📂 创建目录: {}", output_dir.display().to_string().bright_yellow()); // 创建项目目录 fs::create_dir_all(output_dir) .context("创建项目目录失败")?; // 根据模板类型生成不同的项目结构 match template_name { "wallet" => generate_wallet_project(name, output_dir)?, "exchange" => generate_exchange_project(name, output_dir)?, _ => generate_standard_project(name, template_name, output_dir)?, } Ok(()) } fn generate_wallet_project(name: &str, output_dir: &Path) -> Result<()> { println!("💼 生成NAC钱包项目..."); // 创建目录结构 create_dir_structure(output_dir, &[ "src", "src/components", "src/hooks", "src/utils", "src/services", "src/stores", "public", ])?; // 生成package.json let package_json = format!(r#"{{ "name": "{}", "version": "1.0.0", "type": "module", "scripts": {{ "dev": "vite", "build": "vite build", "preview": "vite preview" }}, "dependencies": {{ "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.20.0", "@tanstack/react-query": "^5.0.0", "zustand": "^4.4.0", "axios": "^1.6.0" }}, "devDependencies": {{ "@types/react": "^18.2.0", "@types/react-dom": "^18.2.0", "@vitejs/plugin-react": "^4.2.0", "vite": "^5.0.0", "typescript": "^5.3.0" }} }} "#, name); fs::write(output_dir.join("package.json"), package_json)?; // 生成vite.config.js let vite_config = r#"import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' export default defineConfig({ plugins: [react()], server: { port: 3000 } }) "#; fs::write(output_dir.join("vite.config.js"), vite_config)?; // 生成index.html let index_html = format!(r#" {} - NAC钱包
"#, name); fs::write(output_dir.join("index.html"), index_html)?; // 生成src/main.jsx let main_jsx = r#"import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' import './index.css' ReactDOM.createRoot(document.getElementById('root')).render( , ) "#; fs::write(output_dir.join("src/main.jsx"), main_jsx)?; // 生成src/App.jsx let app_jsx = r#"import { useState } from 'react' import WalletConnector from './components/WalletConnector' import './App.css' function App() { const [account, setAccount] = useState(null) return (

NAC 钱包

{account && (

账户信息

地址: {account.address}

余额: {account.balance} XTZH

)}
) } export default App "#; fs::write(output_dir.join("src/App.jsx"), app_jsx)?; // 生成WalletConnector组件 let wallet_connector = r#"import { useState } from 'react' export default function WalletConnector({ onConnect }) { const [loading, setLoading] = useState(false) const handleConnect = async () => { setLoading(true) try { // TODO: 实现NAC钱包连接逻辑 const account = { address: 'nac1...', balance: '1000.00' } onConnect(account) } catch (error) { console.error('连接失败:', error) } finally { setLoading(false) } } return ( ) } "#; fs::write(output_dir.join("src/components/WalletConnector.jsx"), wallet_connector)?; // 生成CSS let app_css = r#".app { max-width: 1200px; margin: 0 auto; padding: 2rem; } header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem; } .account-info { background: #f5f5f5; padding: 1.5rem; border-radius: 8px; } "#; fs::write(output_dir.join("src/App.css"), app_css)?; fs::write(output_dir.join("src/index.css"), "* { margin: 0; padding: 0; box-sizing: border-box; }")?; // 生成README let readme = format!(r#"# {} - NAC钱包 NAC原生公链钱包应用 ## 功能特性 - 钱包连接与管理 - 资产查看与转账 - 交易历史记录 - 宪法收据验证 ## 开发 ```bash npm install npm run dev ``` ## 构建 ```bash npm run build ``` "#, name); fs::write(output_dir.join("README.md"), readme)?; Ok(()) } fn generate_exchange_project(name: &str, output_dir: &Path) -> Result<()> { println!("🏦 生成RWA交易所项目..."); // 创建目录结构 create_dir_structure(output_dir, &[ "src", "src/components", "src/pages", "src/hooks", "src/utils", "src/services", "src/stores", "public", ])?; // 生成package.json let package_json = format!(r#"{{ "name": "{}", "version": "1.0.0", "type": "module", "scripts": {{ "dev": "vite", "build": "vite build", "preview": "vite preview" }}, "dependencies": {{ "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.20.0", "@tanstack/react-query": "^5.0.0", "zustand": "^4.4.0", "axios": "^1.6.0", "recharts": "^2.10.0" }}, "devDependencies": {{ "@types/react": "^18.2.0", "@types/react-dom": "^18.2.0", "@vitejs/plugin-react": "^4.2.0", "vite": "^5.0.0", "typescript": "^5.3.0" }} }} "#, name); fs::write(output_dir.join("package.json"), package_json)?; // 生成vite.config.js let vite_config = r#"import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' export default defineConfig({ plugins: [react()], server: { port: 3000, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } } }) "#; fs::write(output_dir.join("vite.config.js"), vite_config)?; // 生成index.html let index_html = format!(r#" {} - NAC RWA交易所
"#, name); fs::write(output_dir.join("index.html"), index_html)?; // 生成src/main.jsx let main_jsx = r#"import React from 'react' import ReactDOM from 'react-dom/client' import { BrowserRouter } from 'react-router-dom' import App from './App' import './index.css' ReactDOM.createRoot(document.getElementById('root')).render( , ) "#; fs::write(output_dir.join("src/main.jsx"), main_jsx)?; // 生成src/App.jsx let app_jsx = r#"import { Routes, Route } from 'react-router-dom' import HomePage from './pages/HomePage' import TradePage from './pages/TradePage' import './App.css' function App() { return (
} /> } />
) } export default App "#; fs::write(output_dir.join("src/App.jsx"), app_jsx)?; // 生成HomePage let home_page = r#"export default function HomePage() { return (

欢迎来到NAC RWA交易所

全球首个RWA原生公链交易平台

资产上架

一键将RWA资产上链交易

碎片化交易

支持资产碎片化,降低投资门槛

跨链桥接

多链资产互通,流动性最大化

) } "#; fs::write(output_dir.join("src/pages/HomePage.jsx"), home_page)?; // 生成TradePage let trade_page = r#"import { useState } from 'react' export default function TradePage() { const [orderType, setOrderType] = useState('buy') const [amount, setAmount] = useState('') const [price, setPrice] = useState('') const handleSubmit = (e) => { e.preventDefault() console.log('提交订单:', { orderType, amount, price }) } return (

订单簿

{/* TODO: 实现订单簿 */}

下单

setPrice(e.target.value)} /> setAmount(e.target.value)} />
) } "#; fs::write(output_dir.join("src/pages/TradePage.jsx"), trade_page)?; // 生成CSS let app_css = r#".app { min-height: 100vh; } .navbar { display: flex; justify-content: space-between; align-items: center; padding: 1rem 2rem; background: #1a1a1a; color: white; } .nav-links a { margin-left: 1.5rem; color: white; text-decoration: none; } .home-page { max-width: 1200px; margin: 0 auto; padding: 2rem; } .features { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.5rem; margin-top: 2rem; } .feature-card { padding: 1.5rem; background: #f5f5f5; border-radius: 8px; } .trade-page { display: grid; grid-template-columns: 2fr 1fr; gap: 1.5rem; max-width: 1200px; margin: 0 auto; padding: 2rem; } .trade-form form { display: flex; flex-direction: column; gap: 1rem; } .order-type { display: flex; gap: 0.5rem; } .order-type button { flex: 1; padding: 0.75rem; border: none; background: #e0e0e0; cursor: pointer; } .order-type button.active { background: #4CAF50; color: white; } "#; fs::write(output_dir.join("src/App.css"), app_css)?; fs::write(output_dir.join("src/index.css"), "* { margin: 0; padding: 0; box-sizing: border-box; }")?; // 生成README let readme = format!(r#"# {} - NAC RWA交易所 NAC原生公链RWA资产交易平台 ## 功能特性 - 资产上架与交易 - 订单簿与撮合引擎 - 碎片化交易支持 - 跨链资产桥接 - 实时行情数据 ## 开发 ```bash npm install npm run dev ``` ## 构建 ```bash npm run build ``` ## API接口 后端API运行在 `http://localhost:8080` 主要接口: - GET /api/assets - 获取资产列表 - GET /api/orderbook/:asset - 获取订单簿 - POST /api/orders - 创建订单 - GET /api/trades - 获取交易历史 "#, name); fs::write(output_dir.join("README.md"), readme)?; Ok(()) } fn generate_standard_project(_name: &str, _template_name: &str, _output_dir: &Path) -> Result<()> { // TODO: 实现标准模板生成 Ok(()) } fn create_dir_structure(base: &Path, dirs: &[&str]) -> Result<()> { for dir in dirs { fs::create_dir_all(base.join(dir))?; } Ok(()) }