import { useEffect, useState } from 'react'; import { Button, Form, Input, Modal, Space, Table, Tag, Typography, message, } from 'antd'; import { PlusOutlined, ReloadOutlined, CopyOutlined } from '@ant-design/icons'; import dayjs from 'dayjs'; import type { ColumnsType } from 'antd/es/table'; import { listServices, registerService, revokeService, enableService, deleteService, type ServiceCreateResult, type ServiceRow, } from '../../api'; const STATUS_COLOR: Record = { active: 'green', revoked: 'red', }; export default function Services() { const [rows, setRows] = useState([]); const [loading, setLoading] = useState(false); const [createOpen, setCreateOpen] = useState(false); const [created, setCreated] = useState(null); const [form] = Form.useForm(); const load = async () => { setLoading(true); try { const res = await listServices(); setRows(res.services); } finally { setLoading(false); } }; useEffect(() => { load(); }, []); const onRevoke = async (id: number) => { Modal.confirm({ title: '吊销此服务的 API Key?', content: '吊销后该 MCP 服务将无法调用鉴权 API。吊销后可执行删除操作。', okText: '吊销', okType: 'danger', cancelText: '取消', onOk: async () => { try { await revokeService(id); message.success('已吊销'); } catch (e: any) { message.error(e?.response?.data?.detail || '吊销失败'); } finally { load(); } }, }); }; const onEnable = async (id: number) => { await enableService(id); message.success('已启用'); load(); }; const onDelete = async (id: number) => { Modal.confirm({ title: '删除此服务?', content: '删除后记录将永久移除,无法恢复。', okText: '删除', okType: 'danger', cancelText: '取消', onOk: async () => { try { await deleteService(id); message.success('已删除'); } catch (e: any) { message.error(e?.response?.data?.detail || '删除失败'); } finally { load(); } }, }); }; const onCreate = async () => { try { const values = await form.validateFields(); const res = await registerService({ service_name: values.service_name, service_url: values.service_url, description: values.description, }); setCreated(res); setCreateOpen(false); form.resetFields(); load(); } catch (e: any) { if (e?.response?.data?.detail) { message.error(e.response.data.detail); } else if (!e?.errorFields) { message.error('注册失败'); } } }; const onCopy = (text: string) => { navigator.clipboard.writeText(text).then(() => { message.success('已复制'); }); }; const columns: ColumnsType = [ { title: 'API Key', dataIndex: 'api_key', key: 'api_key', width: 400, render: (key: string) => ( {key} ) : row.status === 'revoked' ? ( ) : ( - ), }, ]; return (
{/* 注册服务表单 */} setCreateOpen(false)} okText="注册" cancelText="取消" >
{/* 注册结果:API Key */} setCreated(null)} footer={} > 配置到 MCP 服务的 MCP_AUTH_API_KEY 环境变量: ); }