const fs = require('fs'); const path = require('path'); const pages = [ { name: 'Audit', route: 'audit', api: '/api/audit', description: '审计服务' }, { name: 'Chatbot', route: 'chatbot', api: '/api/chatbot', description: '聊天机器人' }, { name: 'Command', route: 'command', api: '/api/command', description: '命令服务' }, { name: 'Creative', route: 'creative', api: '/api/creative', description: '创意服务' }, { name: 'Customer', route: 'customer', api: '/api/customer', description: '客户服务' }, { name: 'Governance', route: 'governance', api: '/api/governance', description: '治理服务' }, { name: 'Monitoring', route: 'monitoring', api: '/api/monitoring', description: '监控服务' }, { name: 'NLP', route: 'nlp', api: '/api/nlp', description: '自然语言处理' }, { name: 'Omnichannel', route: 'omnichannel', api: '/api/omnichannel', description: '全渠道服务' }, { name: 'OrderFulfillment', route: 'order-fulfillment', api: '/api/orderFulfillment', description: '订单履约' }, { name: 'Recommendation', route: 'recommendation', api: '/api/recommendation', description: '推荐服务' }, { name: 'Sovereignty', route: 'sovereignty', api: '/api/sovereignty', description: '主权服务' }, { name: 'Sync', route: 'sync', api: '/api/sync', description: '同步服务' }, { name: 'Telemetry', route: 'telemetry', api: '/api/telemetry', description: '遥测服务' }, { name: 'Trace', route: 'trace', api: '/api/trace', description: '追踪服务' }, { name: 'Vault', route: 'vault', api: '/api/vault', description: '密钥库' }, { name: 'Webhook', route: 'webhook', api: '/api/webhook', description: 'Webhook服务' }, ]; const generatePage = (page) => { const componentTemplate = `import React, { useState, useEffect } from 'react'; import { Card, Table, Button, Space, Input, message, Tag, Modal, Form, Select, DatePicker, Row, Col, Statistic } from 'antd'; import { ReloadOutlined, PlusOutlined, SearchOutlined } from '@ant-design/icons'; import { ${page.name}DataSource } from '@/services/${page.route}DataSource'; import type { ${page.name}Item } from '@/services/${page.route}DataSource'; const { Option } = Select; const { RangePicker } = DatePicker; const ${page.name}Page: React.FC = () => { const [data, setData] = useState<${page.name}Item[]>([]); const [loading, setLoading] = useState(false); const [searchText, setSearchText] = useState(''); const [modalVisible, setModalVisible] = useState(false); const [form] = Form.useForm(); useEffect(() => { loadData(); }, []); const loadData = async () => { setLoading(true); try { const result = await ${page.name}DataSource.list(); setData(result); } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : String(error); message.error(\`加载失败: \${errorMessage}\`); } finally { setLoading(false); } }; const handleCreate = async (values: any) => { try { await ${page.name}DataSource.create(values); message.success('创建成功'); setModalVisible(false); form.resetFields(); loadData(); } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : String(error); message.error(\`创建失败: \${errorMessage}\`); } }; const columns = [ { title: 'ID', dataIndex: 'id', key: 'id', width: 200, }, { title: '名称', dataIndex: 'name', key: 'name', }, { title: '状态', dataIndex: 'status', key: 'status', render: (status: string) => { const color = status === 'ACTIVE' ? 'green' : status === 'INACTIVE' ? 'red' : 'default'; return {status}; }, }, { title: '创建时间', dataIndex: 'createdAt', key: 'createdAt', width: 180, }, { title: '操作', key: 'action', width: 150, render: (_: any, record: ${page.name}Item) => ( ), }, ]; return (
item.status === 'ACTIVE').length} valueStyle={{ color: '#3f8600' }} />
} value={searchText} onChange={(e) => setSearchText(e.target.value)} style={{ width: 200 }} />
item.name?.toLowerCase().includes(searchText.toLowerCase()) )} rowKey="id" loading={loading} pagination={{ pageSize: 20 }} /> setModalVisible(false)} onOk={() => form.submit()} >
); }; export default ${page.name}Page; `; return componentTemplate; }; const generateDataSource = (page) => { const dataSourceTemplate = `import { http } from './http'; export interface ${page.name}Item { id: string; name: string; status: string; createdAt: string; updatedAt?: string; } export interface ${page.name}DataSource { list(): Promise<${page.name}Item[]>; create(data: Partial<${page.name}Item>): Promise<${page.name}Item>; update(id: string, data: Partial<${page.name}Item>): Promise<${page.name}Item>; delete(id: string): Promise; } class ${page.name}ApiDataSource implements ${page.name}DataSource { async list() { const response = await http.get('${page.api}/list'); return response.data.data; } async create(data: Partial<${page.name}Item>) { const response = await http.post('${page.api}', data); return response.data.data; } async update(id: string, data: Partial<${page.name}Item>) { const response = await http.put(\`${page.api}/\${id}\`, data); return response.data.data; } async delete(id: string) { await http.delete(\`${page.api}/\${id}\`); } } class ${page.name}MockDataSource implements ${page.name}DataSource { private items: ${page.name}Item[] = [ { id: '1', name: '示例项目 1', status: 'ACTIVE', createdAt: new Date().toISOString() }, { id: '2', name: '示例项目 2', status: 'INACTIVE', createdAt: new Date().toISOString() }, ]; async list() { return this.items; } async create(data: Partial<${page.name}Item>) { const item: ${page.name}Item = { id: String(this.items.length + 1), name: data.name || '', status: data.status || 'ACTIVE', createdAt: new Date().toISOString(), }; this.items.push(item); return item; } async update(id: string, data: Partial<${page.name}Item>) { const index = this.items.findIndex(item => item.id === id); if (index >= 0) { this.items[index] = { ...this.items[index], ...data }; return this.items[index]; } throw new Error('Item not found'); } async delete(id: string) { const index = this.items.findIndex(item => item.id === id); if (index >= 0) { this.items.splice(index, 1); } } } const useMock = process.env.REACT_APP_USE_MOCK === 'true'; export const ${page.name}DataSource: ${page.name}DataSource = useMock ? new ${page.name}MockDataSource() : new ${page.name}ApiDataSource(); `; return dataSourceTemplate; }; const dashboardPath = 'd:\\trae_projects\\makemd\\makemd\\dashboard\\src'; pages.forEach(page => { const pageDir = path.join(dashboardPath, 'pages', page.name); const pageFile = path.join(pageDir, 'index.tsx'); const dataSourceFile = path.join(dashboardPath, 'services', `${page.route}DataSource.ts`); if (!fs.existsSync(pageDir)) { fs.mkdirSync(pageDir, { recursive: true }); console.log(`Created directory: ${pageDir}`); } fs.writeFileSync(pageFile, generatePage(page), 'utf8'); console.log(`Created page: ${pageFile}`); fs.writeFileSync(dataSourceFile, generateDataSource(page), 'utf8'); console.log(`Created data source: ${dataSourceFile}`); }); console.log('\nAll pages and data sources generated successfully!'); console.log('\nNext steps:'); console.log('1. Add routes to the router configuration'); console.log('2. Add menu items to the navigation'); console.log('3. Implement backend API endpoints if not exists');