import { forwardRef, useImperativeHandle, useState } from 'react'; import { Form, Input, Select, App } from 'antd'; import { useTranslation } from 'react-i18next'; import type { CustomToolItem, CustomToolModalRef, ToolItem } from '../types' import RbModal from '@/components/RbModal'; import { parseSchema, addTool, updateTool } from '@/api/tools'; import Table from '@/components/Table'; import { stringRegExp } from '@/utils/validator'; const FormItem = Form.Item; interface CustomToolModalProps { refresh: () => void; } interface OperationItem { method: string; path: string; summary: string; description: string; parameters: Record> request_body: null | string; responses: Record> tags: string[] } interface ParseSchemaData { title: string; description: string; version: string; base_url: string; operations: OperationItem[] } const authTypeList = ['none', 'api_key', 'basic_auth'] const CustomToolModal = forwardRef(({ refresh }, ref) => { const { t } = useTranslation(); const { message } = App.useApp(); const [visible, setVisible] = useState(false); const [form] = Form.useForm(); const [loading, setLoading] = useState(false); const [editVo, setEditVo] = useState(null) const values = Form.useWatch([], form) const [parseSchemaData, setParseSchemaData] = useState({} as ParseSchemaData) // 封装取消方法,添加关闭弹窗逻辑 const handleClose = () => { setVisible(false); form.resetFields(); setLoading(false); setEditVo(null) setParseSchemaData({} as ParseSchemaData) }; const handleOpen = (data?: ToolItem) => { if (data?.id) { const { config_data, ...rest } = data form.setFieldsValue({ ...rest, config: {...config_data} }) setEditVo(data) formatSchema(config_data.schema_content) } else { form.resetFields(); } setVisible(true); }; // 封装保存方法,添加提交逻辑 const handleSave = () => { form .validateFields() .then(() => { setLoading(true); // 创建新服务对象 const { config, ...reset } = values const request = editVo?.id ? updateTool(editVo?.id, { ...editVo, ...reset, config: { ...editVo.config_data, ...config } }) : addTool({ ...values, tool_type: 'custom' }) request.then(() => { message.success(t('tool.addServiceSuccess')); handleClose(); refresh() }) .finally(() => { setLoading(false); }) }) .catch((err) => { console.log('表单验证失败:', err); setLoading(false); }); }; const formatSchema = (value: string) => { if (!value || value.trim() === '') return setParseSchemaData({} as ParseSchemaData) parseSchema({ schema_content: value }) .then(res => { const response = res as { data: ParseSchemaData } setParseSchemaData(response.data) }) } // 暴露给父组件的方法 useImperativeHandle(ref, () => ({ handleOpen, handleClose })); return (
{/* 名称和图标 */} {/* */} formatSchema(e.target.value)} /> rowKey="summary" pagination={false} bordered={true} columns={[ { title: t('tool.name'), dataIndex: 'summary', key: 'summary', render: (summary) => ( {summary ?? parseSchemaData.title} ) }, { title: t('tool.desc'), dataIndex: 'description', key: 'description', }, { title: t('tool.method'), dataIndex: 'method', key: 'method', }, { title: t('tool.path'), dataIndex: 'path', key: 'path', }, ]} initialData={parseSchemaData.operations || []} emptySize={88} emptyText={t('tool.toolEmpty')} /> <> {/* 认证方式 */} } {/* API Key: 认证方式 = bearer_token 展示 */} {values?.config?.auth_type === 'bearer_token' && } {/* API Key: 认证方式 = basic_auth 展示 */} {values?.config?.auth_type === 'basic_auth' && <> }