diff --git a/frontend/src/pages/front/MarketPage.css b/frontend/src/pages/front/MarketPage.css index c888963..2c51cfc 100644 --- a/frontend/src/pages/front/MarketPage.css +++ b/frontend/src/pages/front/MarketPage.css @@ -1091,6 +1091,22 @@ border-color: var(--color-accent-light); } +.hub-platform-wrapper { + display: flex; + flex-direction: column; + gap: var(--space-sm); +} + +.hub-platform-code-section { + display: flex; + flex-direction: column; + gap: var(--space-sm); + padding: var(--space-md); + background: var(--color-bg-secondary); + border: 1px solid var(--color-border-light); + border-radius: var(--radius-md); +} + .hub-platform-header { display: flex; align-items: center; @@ -1713,3 +1729,13 @@ border-radius: var(--radius-md); border: 1px solid var(--color-border-light); } + +.hub-platform-code-section { + display: flex; + flex-direction: column; + gap: var(--space-sm); + padding: var(--space-md); + background: var(--color-bg-secondary); + border: 1px solid var(--color-border-light); + border-radius: var(--radius-md); +} diff --git a/frontend/src/pages/front/MarketPage.tsx b/frontend/src/pages/front/MarketPage.tsx index 220b302..b726d88 100644 --- a/frontend/src/pages/front/MarketPage.tsx +++ b/frontend/src/pages/front/MarketPage.tsx @@ -881,9 +881,14 @@ const HubImportModal: React.FC = ({ appType, platforms, onC const [statusMsg, setStatusMsg] = useState(''); // MCP code editor state for hub import + // shared: used by the standalone custom-import button const [hubCode, setHubCode] = useState(''); const [hubCodeVerifyResult, setHubCodeVerifyResult] = useState<'idle' | 'checking' | 'pass' | 'fail'>('idle'); const [hubCodeVerifyMsg, setHubCodeVerifyMsg] = useState(''); + // per-platform: each MCP platform has its own Streamable HTTP code input + const [hubCodeMap, setHubCodeMap] = useState>({}); + const [hubCodeVerifyResultMap, setHubCodeVerifyResultMap] = useState>({}); + const [hubCodeVerifyMsgMap, setHubCodeVerifyMsgMap] = useState>({}); const [hubName, setHubName] = useState(''); const [hubDescription, setHubDescription] = useState(''); @@ -908,12 +913,39 @@ const HubImportModal: React.FC = ({ appType, platforms, onC }, 1200); }; + const handleHubMcpVerifyForPlatform = (platformId: string) => { + const code = hubCodeMap[platformId] || ''; + if (!code.trim()) return; + setHubCodeVerifyResultMap(prev => ({ ...prev, [platformId]: 'checking' })); + setHubCodeVerifyMsgMap(prev => ({ ...prev, [platformId]: '' })); + setTimeout(() => { + const trimmed = code.trim(); + const hasMinLength = trimmed.length > 20; + const hasKeywords = /(transport|endpoint|mcp|server|client|connection|url)/i.test(trimmed); + if (hasMinLength && hasKeywords) { + setHubCodeVerifyResultMap(prev => ({ ...prev, [platformId]: 'pass' })); + setHubCodeVerifyMsgMap(prev => ({ ...prev, [platformId]: 'AI验证通过:代码包含必要的传输协议和端点配置,可以导入' })); + } else { + setHubCodeVerifyResultMap(prev => ({ ...prev, [platformId]: 'fail' })); + setHubCodeVerifyMsgMap(prev => ({ ...prev, [platformId]: 'AI验证失败:代码中缺少必要的关键词(transport/endpoint),请检查代码完整性' })); + } + }, 1200); + }; + const handleImport = (platformId: string) => { const url = importUrl[platformId]; + const isCustomImport = platformId === 'custom-import'; + const platformCode = isCustomImport ? hubCode : (hubCodeMap[platformId] || ''); // For Skills: require URL; for MCP: require code verification pass + name if (appType === 'skill' && !url?.trim()) return; - if (appType === 'mcp' && hubCodeVerifyResult !== 'pass') return; - if (appType === 'mcp' && !hubName.trim()) return; + if (appType === 'mcp') { + if (isCustomImport) { + if (hubCodeVerifyResult !== 'pass') return; + } else { + if (hubCodeVerifyResultMap[platformId] !== 'pass') return; + } + if (!hubName.trim()) return; + } setImportingId(platformId); setImportStatus('verifying'); setStatusMsg(appType === 'mcp' ? '正在验证代码...' : '正在验证URL链接...'); @@ -934,13 +966,17 @@ const HubImportModal: React.FC = ({ appType, platforms, onC if (step.status === 'published') { setTimeout(() => { const name = appType === 'skill' ? (hubName || extractSkillName(url || '', platformId)) : hubName; - onImport(platformId, appType === 'mcp' ? hubCode : (url || ''), name, importPrice, hubDescription); + const importPayload = appType === 'mcp' ? platformCode : (url || ''); + onImport(platformId, importPayload, name, importPrice, hubDescription); setImportingId(null); setImportStatus('idle'); setImportUrl(prev => ({ ...prev, [platformId]: '' })); setHubCode(''); setHubCodeVerifyResult('idle'); setHubCodeVerifyMsg(''); + setHubCodeMap(prev => ({ ...prev, [platformId]: '' })); + setHubCodeVerifyResultMap(prev => ({ ...prev, [platformId]: 'idle' })); + setHubCodeVerifyMsgMap(prev => ({ ...prev, [platformId]: '' })); setHubName(''); setHubDescription(''); }, 1000); @@ -962,7 +998,7 @@ const HubImportModal: React.FC = ({ appType, platforms, onC
2 {appType === 'skill' ? '在平台找到目标链接并复制' : '在平台获取MCP客户端代码'}
-
3 {appType === 'skill' ? '粘贴链接至输入框并点击导入' : '粘贴代码到编辑器,通过AI验证后点击导入'}
+
3 {appType === 'skill' ? '粘贴链接至输入框并点击导入' : '粘贴代码到对应平台输入框,通过AI验证后点击导入'}
@@ -1125,7 +1161,7 @@ const mcpClient = new MCPClient({
)} + {appType === 'mcp' && ( +
+ +