'use client'; import { useState, useEffect } from 'react'; import api from '@/lib/api'; import { Loader2, Plus, Save, X, FileJson, List, Edit3 } from 'lucide-react'; import JsonEditor from '@/components/common/JsonEditor'; interface SchemaManagerProps { isOpen: boolean; onClose: () => void; } interface SchemaItem { id: number; name: string; schema_json: string; description?: string; } export default function SchemaManager({ isOpen, onClose }: SchemaManagerProps) { const [schemas, setSchemas] = useState([]); const [loading, setLoading] = useState(false); // 移动端 Tab 状态: 'list' | 'editor' const [activeTab, setActiveTab] = useState<'list' | 'editor'>('list'); // 编辑模式状态 const [editingId, setEditingId] = useState(null); const [formData, setFormData] = useState({ name: '', description: '', schema_json: '{\n "type": "object",\n "properties": {\n "field_name": { "type": "string", "title": "示例字段" }\n }\n}' }); useEffect(() => { if (isOpen) { fetchSchemas(); setActiveTab('list'); // 打开时默认显示列表 } }, [isOpen]); const fetchSchemas = async () => { setLoading(true); try { const res = await api.get('/api/vas/schema/list'); setSchemas(Array.isArray(res.data.data) ? res.data.data : []); } catch (e) { console.warn("API Error, using mock schema data"); setSchemas([]); } finally { setLoading(false); } }; const handleSave = async () => { if (!formData.name) return alert("名称必填"); try { JSON.parse(formData.schema_json); // 校验 JSON if (editingId) { await api.post(`/api/vas/schema/update`, formData, {params: {"id": editingId}}); } else { await api.post('/api/vas/schema/create', formData); } alert("保存成功"); fetchSchemas(); // 保存后逻辑: // 如果是新建,保存后清空表单并留再编辑页,或者切回列表 // 这里选择保留在当前页,但如果是移动端可以考虑切回列表 if (!editingId) { setFormData({ name: '', description: '', schema_json: '{}' }); } } catch (e: any) { alert("保存失败: " + (e.message || "JSON 格式错误")); } }; const handleCreateNew = () => { setEditingId(null); setFormData({ name: '', description: '', schema_json: '{}' }); setActiveTab('editor'); // 移动端自动切换到编辑器 tab }; const handleEdit = (item: SchemaItem) => { setEditingId(item.id); setFormData({ name: item.name, description: item.description || '', schema_json: typeof item.schema_json === 'string' ? item.schema_json : JSON.stringify(item.schema_json, null, 2) }); setActiveTab('editor'); // 移动端自动切换到编辑器 tab }; const handleDelete = async (id: number) => { if(!confirm("删除 Schema 可能导致关联商品失效,确定删除吗?")) return; try { await api.delete('/api/vas/schema/delete', {params: {"id": id}}); fetchSchemas(); if (editingId === id) { setEditingId(null); setFormData({ name: '', description: '', schema_json: '{}' }); setActiveTab('list'); // 删除后切回列表 } } catch (e) { alert("删除失败"); } }; if (!isOpen) return null; return (
{/* 容器: - 移动端:全屏 (w-full h-full),无圆角 - 桌面端:固定大小 (max-w-4xl h-[85vh]),有圆角 */}
{/* Header */}

表单 Schema 管理

{/* Mobile Tabs (仅移动端显示) */}
{/* Content Body */}
{/* 左侧:列表 - 移动端:根据 activeTab === 'list' 显示/隐藏 - 桌面端:md:flex md:w-1/3 */}
{loading &&
加载中...
} {!loading && schemas.length === 0 &&
暂无数据
} {schemas.map(s => (
handleEdit(s)} className={`p-3 rounded-lg cursor-pointer border transition ${ editingId === s.id ? 'bg-white border-blue-500 shadow-md ring-1 ring-blue-500' : 'bg-white border-slate-200 hover:border-blue-300' }`} >
{s.name}
ID: {s.id}
))}
{/* 右侧:编辑区 - 移动端:根据 activeTab === 'editor' 显示/隐藏 - 桌面端:md:flex md:w-2/3 */}

{editingId ? `编辑 Schema #${editingId}` : '创建新 Schema'} {editingId && ( )}

setFormData({...formData, name: e.target.value})} placeholder="e.g. Japan Visa Form" />
setFormData({...formData, description: e.target.value})} placeholder="简短描述用途" />
{/* JSON Editor */}
setFormData({...formData, schema_json: val})} height="h-[400px] md:h-80" // 移动端稍微高一点 placeholder='{"type": "object", ...}' />
{editingId && ( )}
); }