import React, { useEffect, useState } from 'react'; import { Modal, Form, Input, Grid, Space, Divider, Button, Table, TableColumnProps, Select, Message, Upload, Progress } from '@arco-design/web-react'; import { IconPlus, IconEdit } from '@arco-design/web-react/icon'; import styles from './style/addComponentModal.module.less'; import EditorSection from '@/components/EditorSection'; import AddApiModal from '@/pages/componentDevelopment/componentList/addApiModal'; import CompReview from '@/pages/componentDevelopment/componentList/compReview'; import { getComponentClassify } from '@/api/componentClassify'; import { compProjectValidate, compSubmit, getTagList, copyAll, getMyComponentList, getCooperationComponentList } from '@/api/componentBase'; import { copyDesign } from '@/api/componentMarket'; import { codeInit, getComponentDesign, updateComponentDesign } from '@/api/componentDevelopProcess'; const FormItem = Form.Item; const Option = Select.Option; // 定义组件模式类型 type ComponentMode = 'create' | 'edit' | 'copy'; const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh, mode = 'create' }) => { const [selectedImage, setSelectedImage] = useState(''); const [description, setDescription] = useState(''); const [classifyList, setClassifyList] = useState([]); const [showSaveBtn, setShowSaveBtn] = useState(false); const [tagsList, setTagsList] = useState([]); const [componentInfo, setComponentInfo] = useState(null); // 合并后的组件信息状态 const [componentDesignData, setComponentDesignData] = useState([]); // 新增状态用于存储接口设计数据 const [selectedApiData, setSelectedApiData] = useState(null); // 新增状态用于存储选中的API数据 const [showApiModal, setShowApiModal] = useState(false); const [created, setCreated] = useState(false); // 是否提交了组件信息 const [codeInitLoading, setCodeInitLoading] = useState(false); // 代码初始化按钮 loading const [file, setFile] = useState(null); const [form] = Form.useForm(); // 组件语言选项 const codeLanguageOptions = [ { label: 'Java:8', value: 'Java' }, { label: 'Python:3.10.12', value: 'Python' } ]; // 组件类型选项 const componentTypeOptions = [ { label: '普通组件', value: 'normal' }, { label: '监听组件', value: 'loop' } ]; const cs = `arco-upload-list-item${file && file.status === 'error' ? ' is-error' : ''}`; // 判断是否为复制模式 const isCopyMode = mode === 'copy'; // 判断是否为编辑模式 const isEditMode = mode === 'edit'; // 判断是否为创建模式 const isCreateMode = mode === 'create'; const columns: TableColumnProps[] = [ { title: '接口名称', dataIndex: 'ident' }, { title: '输入参数', dataIndex: 'parameters', render: (_, record) => { if (!record.parameters || record.parameters.length === 0) { return '-'; } return record.parameters.map(param => param.ident).join(', '); } }, { title: '输出参数', dataIndex: 'responses', render: (_, record) => { if (!record.responses || record.responses.length === 0) { return '-'; } return record.responses.map(response => response.ident).join(', '); } }, { title: '操作', dataIndex: 'op', width: 240, render: (_, record) => ( <> { // 设置选中的API数据,用于编辑时回显 setSelectedApiData(record); setShowApiModal(true); }} disabled={isCopyMode || (componentInfo && !['DEFAULT', 'DESIGN'].includes(componentInfo.componentStatus))} > 编辑 { // 显示删除确认框 Modal.confirm({ title: '确认删除', content: `确定要删除接口 "${record.ident}" 吗?此操作不可恢复。`, okButtonProps: { status: 'danger' }, onOk: async () => { // 从 componentDesignData 中过滤掉要删除的记录 const updatedData = componentDesignData.filter(item => item.ident !== record.ident); // 构造要提交的数据 const params = { baseInfo: componentInfo, operates: updatedData // 保持数组格式 }; // 调用接口更新数据 const res: any = await updateComponentDesign(params); try { if (res.code === 200) { Message.success('删除成功'); // 更新本地状态 setComponentDesignData(updatedData); } else { Message.error(res.message || '删除失败'); // 删除失败时恢复数据 setComponentDesignData(componentDesignData); } } catch (error) { console.error('删除失败:', error); Message.error('删除失败'); // 删除失败时恢复数据 setComponentDesignData(componentDesignData); } } }); }} > 删除 > ) } ]; const getComponentClassifyList = async () => { const res: any = await getComponentClassify('component'); if (res.code === 200) { const data = []; res.data.forEach((item) => { data.push({ label: item.classifyName, value: item.id }); }); setClassifyList(data); } }; const getTageList = async () => { const res: any = await getTagList(); if (res.code === 200) setTagsList(res.data); }; const validateProjectId = async (projectId: string) => { if (!projectId) return; try { const res = await compProjectValidate(projectId); if (res.data === false) { // 项目标识已存在,设置表单字段错误 form.setFields({ projectId: { value: projectId, error: { message: '项目标识已存在' } } }); } else { // 项目标识可用,清除错误 form.setFields({ projectId: { value: projectId, error: null } }); } } catch (error) { // API调用出错 form.setFields({ projectId: { value: projectId, error: { message: '验证项目标识时发生错误' } } }); } }; const onSubmit = async (showMessage = true) => { try { await form.validate(); const formData = form.getFields(); const params: any = { ...componentInfo, name: formData.name, projectId: formData.projectId, logoUrl: selectedImage, desc: description, componentClassify: formData.componentClassify, codeLanguage: formData.codeLanguage, // 直接使用value值 type: formData.type, // 直接使用value值 tags: formData.tags }; // 如果是编辑模式(componentInfo存在),则传递id if (componentInfo && componentInfo.id) { params.id = componentInfo.id; } const res: any = await compSubmit(params); if (res.code === 200) { setComponentInfo(res.data); setShowSaveBtn(true); showMessage && Message.success(isEditMode ? '组件信息更新成功' : isCopyMode ? '组件复制成功' : '组件信息提交完成,可继续组件接口设计'); onReFresh(); // 最终保存成功后关闭弹窗 if (showSaveBtn && showMessage) { setVisible(false); return; } // 提交成功后获取组件设计数据 if (res.data && res.data.id) { setCreated(true); getComponentDesignData(res.data.id); } } else { showMessage && Message.error(isEditMode ? '组件信息更新失败' : isCopyMode ? '组件复制失败' : '组件信息提交失败'); } } catch (error) { console.error('提交/更新失败:', error); } }; const fetchComponentData = async (extraParams: any = {}) => { try { const params = { currPage: 1, pageSize: 99, ...extraParams }; const res: any = await getMyComponentList(params); if (res.code === 200 && res.data.list.length > 0) { setComponentInfo(res.data.list[0]); getComponentDesignData(res.data.list[0].id); } } catch (error) { console.error('获取组件列表失败:', error); Message.error('获取组件列表失败'); } }; const getComponentDesignData = async (componentBaseId) => { try { const res = await getComponentDesign(componentBaseId); if (res.data) { // 处理返回的数据,使其符合表格显示格式 const processedData = res.data.operates.map(item => ({ ...item, key: item.ident, name: item.ident // 使用ident作为名称显示 })); setComponentDesignData(processedData); } } catch (error) { console.error('获取组件设计数据失败:', error); Message.error('获取组件设计数据失败'); } }; // 仅复制设计 const handleCopyDesign = async () => { try { await form.validate(); const formData = form.getFields(); // 构造要提交的数据 const params = { ...componentInfo, name: formData.name, projectId: formData.projectId, logoUrl: selectedImage, desc: description, componentClassify: formData.componentClassify, codeLanguage: formData.codeLanguage, // 直接使用value值 type: formData.type, // 直例使用value值 tags: formData.tags }; const res: any = await copyDesign(params); if (res.code === 200) { Message.success('仅复制设计成功'); onReFresh && onReFresh(); setVisible(false); } else { Message.error(res.message || '复制失败'); } } catch (error) { console.error('复制失败:', error); } }; // 复制设计和代码 const handleCopyAll = async () => { try { await form.validate(); const formData = form.getFields(); // 构造要提交的数据 const params = { ...componentInfo, name: formData.name, projectId: formData.projectId, logoUrl: selectedImage, desc: description, componentClassify: formData.componentClassify, codeLanguage: formData.codeLanguage, // 直接使用value值 type: formData.type, // 直接使用value값 tags: formData.tags }; const res: any = await copyAll(params); if (res.code === 200) { Message.success('复制设计和代码成功'); onReFresh && onReFresh(); setVisible(false); } else { Message.error(res.message || '复制失败'); } } catch (error) { console.error('复制失败:', error); } }; const handleCodeInit = async () => { setCodeInitLoading(true); Message.warning('代码初始化中'); const res: any = await codeInit(componentInfo?.id); setCodeInitLoading(false); if (res.code === 200) { Message.success('代码初始化完成'); fetchComponentData({ id: componentInfo?.id }); } else Message.error(res.message || '代码初始化失败'); }; useEffect(() => { getComponentClassifyList(); getTageList(); }, []); // 当baseInfo或visible变化时,设置表单初始值 useEffect(() => { if (visible && (isEditMode || isCopyMode)) { // 设置表单字段值 form.setFieldsValue({ name: baseInfo.name || '', projectId: (isCopyMode ? '' : baseInfo.projectId) || '', componentClassify: baseInfo.componentClassify || '', codeLanguage: baseInfo.codeLanguage || '', tags: baseInfo.tags || [], type: baseInfo.type || '' }); // 设置其他状态 setSelectedImage(baseInfo.logoUrl || ''); setDescription(baseInfo.desc || ''); setShowSaveBtn(true); setComponentInfo(baseInfo); // 获取组件设计数据 if (isEditMode || isCopyMode) { getComponentDesignData(baseInfo.id); } // else { // // 复制模式下清空接口设计数据 // setComponentDesignData([]); // } } else if (visible && isCreateMode) { // 重置表单 form.resetFields(); setSelectedImage(''); setDescription(''); setShowSaveBtn(false); setComponentDesignData([]); // 清空接口设计数据 setComponentInfo(null); } }, [baseInfo, visible, form, isEditMode, isCopyMode, isCreateMode]); const modalFooter = () => { return ( setVisible(false)}>取消 {isCopyMode ? ( <> 仅复制设计 复制设计和代码 > ) : showSaveBtn ? ( onSubmit()}> {isEditMode ? '更新' : '保存'} ) : ( onSubmit()}> {isEditMode ? '更新组件信息' : '提交组件信息'} )} ); }; const UploadImage = () => { // 如果是编辑模式且有componentInfo.logoUrl,则使用componentInfo中的logoUrl const initialImageUrl = componentInfo && componentInfo.logoUrl ? componentInfo.logoUrl : null; return ( { setFile({ ...currentFile, url: URL.createObjectURL(currentFile.originFile) }); if (currentFile.status === 'done') setSelectedImage(currentFile.response.data.link); }} onProgress={(currentFile) => { setFile(currentFile); }} > {(file && file.url) || initialImageUrl ? ( {file && file.status === 'uploading' && file.percent < 100 && ( )} ) : ( )} ); }; return ( setVisible(false)} afterClose={() => { // 关闭模态框后重置表单 form.resetFields(); setSelectedImage(''); setDescription(''); setShowSaveBtn(false); setFile(null); setCreated(false); }} > validateProjectId(e)} /> {classifyList.map((option, index) => ( {option.label} ))} {codeLanguageOptions.map((option) => ( {option.label} ))} {tagsList.map((option, index) => ( {option.label} ))} {componentTypeOptions.map((option) => ( {option.label} ))} 描述: {showSaveBtn && !isCopyMode && 组件接口 }> handleCodeInit()} > 代码初始化 { setSelectedApiData(null); // 确保新增时清空选中的API数据 setShowApiModal(true); }} disabled={componentInfo && !['DEFAULT', 'DESIGN'].includes(componentInfo.componentStatus)} > + 新增接口 { // 更新成功后重新获取组件设计数据 if (componentInfo && componentInfo.id) { getComponentDesignData(componentInfo.id); } }} onCancel={() => { setShowApiModal(false); setSelectedApiData(null); // 重置选中的API数据 }} onOk={() => { setShowApiModal(false); setSelectedApiData(null); // 重置选中的API数据 }} /> } ); }; export default AddComponentModal;
组件接口