'use client'; import { useState, useEffect } from 'react'; import api from '@/lib/api'; import { Loader2, Trash2, Plus, Save, X, Network } from 'lucide-react'; import JsonEditor from '@/components/common/JsonEditor'; interface RoutingManagerProps { productId: number | null; productTitle: string; isOpen: boolean; onClose: () => void; } interface ProductRouting { id: number; routing_key: string; script_version: string; priority: number; config?: any; // JSON object or string meta?: any; } export default function RoutingManager({ productId, productTitle, isOpen, onClose }: RoutingManagerProps) { const [routings, setRoutings] = useState([]); const [loading, setLoading] = useState(false); const [submitting, setSubmitting] = useState(false); // 移动端 Tab 状态: 'list' | 'add' const [activeTab, setActiveTab] = useState<'list' | 'add'>('list'); // 新增 Routing 的表单状态 const [newRouting, setNewRouting] = useState({ routing_key: '', script_version: 'latest', priority: 10, config: '{}', }); // 加载路由列表 useEffect(() => { if (isOpen && productId) { fetchRoutings(); setActiveTab('list'); // 默认显示列表 } }, [isOpen, productId]); const fetchRoutings = async () => { setLoading(true); try { const res = await api.get('/api/vas/product_routing/list', { params: { product_id: productId } }); setRoutings(Array.isArray(res.data.data) ? res.data.data : []); } catch (e) { console.warn("Fetch routings failed"); setRoutings([]); } finally { setLoading(false); } }; const handleAddRouting = async () => { if (!newRouting.routing_key) return alert("Routing Key 必填"); setSubmitting(true); try { let configObj = {}; try { configObj = JSON.parse(newRouting.config); } catch (err) { alert("Config JSON 格式错误,请检查"); setSubmitting(false); return; } await api.post('/api/vas/product_routing/create', { ...newRouting, config: configObj, product_id: productId }); alert("路由添加成功"); fetchRoutings(); setNewRouting({ routing_key: '', script_version: 'latest', priority: 10, config: '{}' }); setActiveTab('list'); // 提交成功后切回列表 } catch (e: any) { alert("添加失败: " + (e.response?.data?.message || e.message)); } finally { setSubmitting(false); } }; const handleDeleteRouting = async (id: number) => { if (!confirm("确定删除此路由配置吗?")) return; try { await api.delete('/api/vas/product_routing/delete', {params: {"id": id}}); fetchRoutings(); } catch (e) { alert("删除失败"); } }; if (!isOpen) return null; return (
{/* 容器: - 移动端:w-full h-full (全屏), rounded-none - 桌面端:max-w-5xl h-[90vh], rounded-xl */}
{/* Header */}

路由策略配置

商品: {productTitle}

{/* Mobile Tabs */}
{/* Content */}
{/* 左侧:添加表单 (Desktop: 30%, Mobile: 根据 Tab 显示) */}

添加新规则

setNewRouting({...newRouting, routing_key: e.target.value})} />
setNewRouting({...newRouting, script_version: e.target.value})} />
setNewRouting({...newRouting, priority: parseInt(e.target.value)})} />
{/* JSON Config Editor */}
setNewRouting({...newRouting, config: val})} height="h-64" placeholder='{"headless": true, "timeout": 30000}' />
{/* 右侧:列表 (Desktop: 70%, Mobile: 根据 Tab 显示) */}

现有路由列表

{loading ? (
加载中...
) : routings.length === 0 ? (
暂无路由配置,请添加。
) : (
{routings.map((r) => (
{r.routing_key} v{r.script_version} P{r.priority}
ID: {r.id}
{/* Config Preview */}
{typeof r.config === 'string' ? r.config : JSON.stringify(r.config, null, 2)}
))}
)}
); }