feat(component): 添加组件复制功能

- 引入 copyDesign 和 copyAll API 接口
- 新增组件模式类型定义 (create/edit/copy)
- 实现仅复制设计和复制设计及代码功能
- 添加复制模式下表单初始化逻辑- 更新模态框标题和按钮状态判断
- 禁用复制模式下的部分表单字段
- 优化组件接口设计区域显示逻辑
-修复关闭模态框时未重置模式的问题
- 调整编辑和复制模式下的项目ID处理逻辑
master
钟良源 3 months ago
parent 18835dc1d5
commit 44569a0e5a

@ -37,3 +37,8 @@ export const remove = (ids) => {
export const exportComponent = (id) => { export const exportComponent = (id) => {
return axios.get(`${urlPrefix}/componentBase/export?id=${id}`); return axios.get(`${urlPrefix}/componentBase/export?id=${id}`);
}; };
// 复制代码和设计
export const copyAll = (params) => {
return axios.post(`${urlPrefix}/componentBase/copy`, params);
};

@ -8,3 +8,8 @@ const urlPrefix = '/api/v1/bpms-workbench';
export function getReviewGroupByNew(params: ReviewGroup) { export function getReviewGroupByNew(params: ReviewGroup) {
return axios.get(`${urlPrefix}/componentMarket/reviewGroupByNew`, { params }); return axios.get(`${urlPrefix}/componentMarket/reviewGroupByNew`, { params });
} }
// 复制组件设计
export function copyDesign(params) {
return axios.post(`${urlPrefix}/componentMarket/copyDesign`, params);
}

@ -19,14 +19,17 @@ import styles from './style/addComponentModal.module.less';
import EditorSection from '@/components/EditorSection'; import EditorSection from '@/components/EditorSection';
import AddApiModal from '@/pages/componentDevelopment/componentList/addApiModal'; import AddApiModal from '@/pages/componentDevelopment/componentList/addApiModal';
import { getComponentClassify } from '@/api/componentClassify'; import { getComponentClassify } from '@/api/componentClassify';
import { compProjectValidate, compSubmit, getTagList } from '@/api/componentBase'; import { compProjectValidate, compSubmit, getTagList, copyAll } from '@/api/componentBase';
import { copyDesign } from '@/api/componentMarket';
import { getComponentDesign, updateComponentDesign } from '@/api/componentDevelopProcess'; import { getComponentDesign, updateComponentDesign } from '@/api/componentDevelopProcess';
const FormItem = Form.Item; const FormItem = Form.Item;
const Option = Select.Option; const Option = Select.Option;
// 定义组件模式类型
type ComponentMode = 'create' | 'edit' | 'copy';
const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => { const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh, mode = 'create' }) => {
const [selectedImage, setSelectedImage] = useState(''); const [selectedImage, setSelectedImage] = useState('');
const [description, setDescription] = useState(''); const [description, setDescription] = useState('');
const [classifyList, setClassifyList] = useState([]); const [classifyList, setClassifyList] = useState([]);
@ -42,6 +45,13 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => {
const cs = `arco-upload-list-item${file && file.status === 'error' ? ' is-error' : ''}`; 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[] = [ const columns: TableColumnProps[] = [
{ {
title: '接口名称', title: '接口名称',
@ -80,14 +90,14 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => {
setSelectedApiData(record); setSelectedApiData(record);
setShowApiModal(true); setShowApiModal(true);
}} }}
disabled={baseInfo && !['DEFAULT', 'DESIGN'].includes(baseInfo.componentStatus)} disabled={isCopyMode || (baseInfo && !['DEFAULT', 'DESIGN'].includes(baseInfo.componentStatus))}
> >
</Button> </Button>
<Button <Button
type="text" type="text"
status="danger" status="danger"
disabled={baseInfo && !['DEFAULT', 'DESIGN'].includes(baseInfo.componentStatus)} disabled={isCopyMode || (baseInfo && !['DEFAULT', 'DESIGN'].includes(baseInfo.componentStatus))}
onClick={async () => { onClick={async () => {
// 显示删除确认框 // 显示删除确认框
Modal.confirm({ Modal.confirm({
@ -134,7 +144,6 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => {
} }
]; ];
const getComponentClassifyList = async () => { const getComponentClassifyList = async () => {
const res: any = await getComponentClassify('component'); const res: any = await getComponentClassify('component');
if (res.code === 200) { if (res.code === 200) {
@ -218,7 +227,7 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => {
if (res.code === 200) { if (res.code === 200) {
setComponentData(res.data); setComponentData(res.data);
setShowSaveBtn(true); setShowSaveBtn(true);
Message.success(baseInfo ? '组件信息更新成功' : '组件信息提交完成,可继续组件接口设计'); Message.success(isEditMode ? '组件信息更新成功' : isCopyMode ? '组件复制成功' : '组件信息提交完成,可继续组件接口设计');
onReFresh(); onReFresh();
// 最终保存成功后关闭弹窗 // 最终保存成功后关闭弹窗
@ -235,7 +244,7 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => {
} }
else { else {
Message.error(baseInfo ? '组件信息更新失败' : '组件信息提交失败'); Message.error(isEditMode ? '组件信息更新失败' : isCopyMode ? '组件复制失败' : '组件信息提交失败');
} }
} catch (error) { } catch (error) {
console.error('提交/更新失败:', error); console.error('提交/更新失败:', error);
@ -260,6 +269,75 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => {
} }
}; };
// 仅复制设计
const handleCopyDesign = async () => {
try {
await form.validate();
const formData = form.getFields();
// 构造要提交的数据
const params = {
...baseInfo,
name: formData.name,
projectId: formData.projectId,
logoUrl: selectedImage,
desc: description,
componentClassify: formData.componentClassify,
codeLanguage: formData.codeLanguage === 'Java:8' ? 'Java' : 'Python',
type: formData.type === '普通组件' ? 'normal' : 'loop',
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 = {
...baseInfo,
name: formData.name,
projectId: formData.projectId,
logoUrl: selectedImage,
desc: description,
componentClassify: formData.componentClassify,
codeLanguage: formData.codeLanguage === 'Java:8' ? 'Java' : 'Python',
type: formData.type === '普通组件' ? 'normal' : 'loop',
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);
}
};
useEffect(() => { useEffect(() => {
getComponentClassifyList(); getComponentClassifyList();
getTageList(); getTageList();
@ -267,11 +345,11 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => {
// 当baseInfo或visible变化时设置表单初始值 // 当baseInfo或visible变化时设置表单初始值
useEffect(() => { useEffect(() => {
if (visible && baseInfo) { if (visible && (isEditMode || isCopyMode)) {
// 设置表单字段值 // 设置表单字段值
form.setFieldsValue({ form.setFieldsValue({
name: baseInfo.name || '', name: baseInfo.name || '',
projectId: baseInfo.projectId || '', projectId: (isCopyMode ? '' : baseInfo.projectId) || '',
componentClassify: baseInfo.componentClassify || '', componentClassify: baseInfo.componentClassify || '',
codeLanguage: baseInfo.codeLanguage || '', codeLanguage: baseInfo.codeLanguage || '',
tags: baseInfo.tags || [], tags: baseInfo.tags || [],
@ -279,15 +357,20 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => {
}); });
// 设置其他状态 // 设置其他状态
setSelectedImage(baseInfo.logoUrl || ''); setSelectedImage(baseInfo.logoUrl || '');
setDescription(baseInfo.desc || ''); setDescription(baseInfo.desc || '');
setShowSaveBtn(true); setShowSaveBtn(true);
// 获取组件设计数据 // 获取组件设计数据(仅在编辑模式下)
if (isEditMode) {
getComponentDesignData(baseInfo.id); getComponentDesignData(baseInfo.id);
} }
else if (visible) { // else {
// // 复制模式下清空接口设计数据
// setComponentDesignData([]);
// }
}
else if (visible && isCreateMode) {
// 重置表单 // 重置表单
form.resetFields(); form.resetFields();
setSelectedImage(''); setSelectedImage('');
@ -296,15 +379,32 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => {
setComponentDesignData([]); // 清空接口设计数据 setComponentDesignData([]); // 清空接口设计数据
setComponentData(null); setComponentData(null);
} }
}, [baseInfo, visible, form]); }, [baseInfo, visible, form, isEditMode, isCopyMode, isCreateMode]);
const modalFooter = () => { const modalFooter = () => {
const isEditMode = !!baseInfo; // 判断是否为编辑模式
return ( return (
<Space size={30}> <Space size={30}>
<Button size="small" type="outline" style={{ borderRadius: 5 }} onClick={() => setVisible(false)}></Button> <Button size="small" type="outline" style={{ borderRadius: 5 }} onClick={() => setVisible(false)}></Button>
{showSaveBtn ? ( {isCopyMode ? (
<>
<Button
size="small"
type="primary"
style={{ borderRadius: 5 }}
onClick={handleCopyDesign}
>
</Button>
<Button
size="small"
type="primary"
style={{ borderRadius: 5 }}
onClick={handleCopyAll}
>
</Button>
</>
) : showSaveBtn ? (
<Button size="small" type="primary" style={{ borderRadius: 5 }} onClick={() => onSubmit()}> <Button size="small" type="primary" style={{ borderRadius: 5 }} onClick={() => onSubmit()}>
{isEditMode ? '更新' : '保存'} {isEditMode ? '更新' : '保存'}
</Button> </Button>
@ -373,7 +473,7 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => {
return ( return (
<Modal <Modal
className={styles['add-component-modal']} className={styles['add-component-modal']}
title={baseInfo ? '编辑组件' : '新增组件'} title={isEditMode ? '编辑组件' : isCopyMode ? '复制组件' : '新增组件'}
visible={visible} visible={visible}
autoFocus={false} autoFocus={false}
focusLock={true} focusLock={true}
@ -387,6 +487,7 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => {
setDescription(''); setDescription('');
setShowSaveBtn(false); setShowSaveBtn(false);
setFile(null); setFile(null);
setCreated(false);
}} }}
> >
<Form form={form} className={styles['add-component-container']}> <Form form={form} className={styles['add-component-container']}>
@ -440,7 +541,7 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => {
style={{ width: '90%' }} style={{ width: '90%' }}
allowClear allowClear
placeholder="请输入代码标识" placeholder="请输入代码标识"
disabled={created || baseInfo} disabled={created || isEditMode}
onChange={(e) => validateProjectId(e)} onChange={(e) => validateProjectId(e)}
/> />
</FormItem> </FormItem>
@ -486,7 +587,7 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => {
<Select <Select
placeholder="请选择组件语言" placeholder="请选择组件语言"
style={{ width: '90%' }} style={{ width: '90%' }}
disabled={created || baseInfo} disabled={created || isEditMode || isCopyMode}
> >
{['Java:8', 'Python:3.10.12'].map((option, index) => ( {['Java:8', 'Python:3.10.12'].map((option, index) => (
<Option key={option} disabled={index === 3} value={option}> <Option key={option} disabled={index === 3} value={option}>
@ -529,10 +630,10 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => {
<Select <Select
placeholder="请选择组件类型" placeholder="请选择组件类型"
style={{ width: '90%' }} style={{ width: '90%' }}
disabled={created || baseInfo} disabled={created || isEditMode}
> >
{['普通组件', '监听组件'].map((option, index) => ( {['普通组件', '监听组件'].map((option, index) => (
<Option key={option} disabled={index === 3} value={option}> <Option key={option} value={option}>
{option} {option}
</Option> </Option>
))} ))}
@ -548,7 +649,7 @@ const AddComponentModal = ({ visible, baseInfo, setVisible, onReFresh }) => {
</div> </div>
</div> </div>
{showSaveBtn && <div className={styles['last-half']}> {showSaveBtn && !isCopyMode && <div className={styles['last-half']}>
<div className={styles['last-half-header']}> <div className={styles['last-half-header']}>
<p> </p> <p> </p>
<Space split={<Divider type="vertical" />}> <Space split={<Divider type="vertical" />}>

@ -30,6 +30,7 @@ const GlobalVarContainer = () => {
}); });
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const [mode, setMode] = useState<'create' | 'edit' | 'copy'>('create'); // 添加模式状态
const menuItems = [ const menuItems = [
{ {
@ -170,10 +171,12 @@ const GlobalVarContainer = () => {
onShowEdit={(row, index) => { onShowEdit={(row, index) => {
setSelectComponent(row); setSelectComponent(row);
setVisible(true); setVisible(true);
setMode('edit'); // 设置模式为复制
}} }}
onCopyHandler={(row) => { onCopyHandler={(row) => {
// TODO: 实现组件复制逻辑 setSelectComponent(row);
console.log('Copy handler', row); setVisible(true);
setMode('copy'); // 设置模式为复制
}} }}
onShareCollaboration={(row) => { onShareCollaboration={(row) => {
// TODO: 实现分享协作逻辑 // TODO: 实现分享协作逻辑
@ -356,8 +359,15 @@ const GlobalVarContainer = () => {
<AddComponentModal <AddComponentModal
visible={visible} visible={visible}
baseInfo={selectComponent} baseInfo={selectComponent}
setVisible={setVisible} setVisible={(visible) => {
setVisible(visible);
// 当关闭模态框时重置模式为create
if (!visible) {
setMode('create');
}
}}
onReFresh={fetchComponentData} onReFresh={fetchComponentData}
mode={mode} // 传递模式
/> />
</> </>
); );

Loading…
Cancel
Save