1
This commit is contained in:
parent
3543906817
commit
d7c6af621b
@ -0,0 +1,93 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Modal, Form, Input, InputNumber, Radio } from 'antd';
|
||||
import { Edge } from '@antv/x6';
|
||||
import { ConditionType, EdgeCondition } from '../types';
|
||||
|
||||
interface ExpressionModalProps {
|
||||
visible: boolean;
|
||||
edge: Edge;
|
||||
onOk: (condition: EdgeCondition) => void;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
const ExpressionModal: React.FC<ExpressionModalProps> = ({
|
||||
visible,
|
||||
edge,
|
||||
onOk,
|
||||
onCancel
|
||||
}) => {
|
||||
const [form] = Form.useForm();
|
||||
const currentCondition = edge.getProp('condition') as EdgeCondition;
|
||||
|
||||
const handleOk = async () => {
|
||||
try {
|
||||
const values = await form.validateFields();
|
||||
onOk(values);
|
||||
} catch (error) {
|
||||
console.error('表单验证失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="编辑条件"
|
||||
open={visible}
|
||||
onOk={handleOk}
|
||||
onCancel={onCancel}
|
||||
width={600}
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
initialValues={currentCondition || {
|
||||
type: 'EXPRESSION',
|
||||
priority: 10
|
||||
}}
|
||||
>
|
||||
<Form.Item
|
||||
name="type"
|
||||
label="条件类型"
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<Radio.Group>
|
||||
<Radio value="EXPRESSION">表达式</Radio>
|
||||
<Radio value="DEFAULT">默认路径</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
noStyle
|
||||
shouldUpdate={(prevValues, currentValues) => prevValues.type !== currentValues.type}
|
||||
>
|
||||
{({ getFieldValue }) => {
|
||||
const type = getFieldValue('type');
|
||||
return type === 'EXPRESSION' ? (
|
||||
<Form.Item
|
||||
name="expression"
|
||||
label="条件表达式"
|
||||
rules={[{ required: true, message: '请输入条件表达式' }]}
|
||||
extra="支持使用 ${变量名} 引用流程变量,例如:${amount} > 1000"
|
||||
>
|
||||
<Input.TextArea
|
||||
placeholder="请输入条件表达式"
|
||||
rows={4}
|
||||
/>
|
||||
</Form.Item>
|
||||
) : null;
|
||||
}}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="priority"
|
||||
label="优先级"
|
||||
rules={[{ required: true }]}
|
||||
extra="数字越小优先级越高"
|
||||
>
|
||||
<InputNumber min={1} max={999} />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default ExpressionModal;
|
||||
@ -44,6 +44,8 @@ import {
|
||||
} from './constants';
|
||||
import './index.less';
|
||||
import {NodeDefinitionResponse, NodeDesignDataResponse} from "@/pages/Workflow/NodeDesign/types";
|
||||
import ExpressionModal from './components/ExpressionModal';
|
||||
import { EdgeCondition } from './types';
|
||||
|
||||
const WorkflowDesign: React.FC = () => {
|
||||
const {id} = useParams<{ id: string }>();
|
||||
@ -60,6 +62,8 @@ const WorkflowDesign: React.FC = () => {
|
||||
const [isNodeDefinitionsLoaded, setIsNodeDefinitionsLoaded] = useState(false);
|
||||
const [forceUpdate, setForceUpdate] = useState(false);
|
||||
const [scale, setScale] = useState(1);
|
||||
const [expressionModalVisible, setExpressionModalVisible] = useState(false);
|
||||
const [selectedEdge, setSelectedEdge] = useState<Edge | null>(null);
|
||||
|
||||
// 初始化图形
|
||||
const initGraph = () => {
|
||||
@ -531,7 +535,7 @@ const WorkflowDesign: React.FC = () => {
|
||||
|
||||
// 节点点击事件
|
||||
graph.on('node:click', ({node}) => {
|
||||
// <EFBFBD><EFBFBD>取当前选中的节点
|
||||
// 取当前选中的节点
|
||||
const selectedNode = graph.getSelectedCells()[0];
|
||||
|
||||
// 如果有其他节点被选中,恢复其样式
|
||||
@ -867,6 +871,15 @@ const WorkflowDesign: React.FC = () => {
|
||||
port.setAttribute('style', 'visibility: hidden');
|
||||
});
|
||||
});
|
||||
|
||||
// 添加边的双击事件
|
||||
graph.on('edge:dblclick', ({ edge }) => {
|
||||
const sourceNode = graph.getCellById(edge.getSourceCellId());
|
||||
if (sourceNode.getProp('nodeType') === 'GATEWAY_NODE') {
|
||||
setSelectedEdge(edge);
|
||||
setExpressionModalVisible(true);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 处理复制操作
|
||||
@ -893,7 +906,7 @@ const WorkflowDesign: React.FC = () => {
|
||||
message.success('已剪切');
|
||||
};
|
||||
|
||||
// 处理粘贴操<EFBFBD><EFBFBD><EFBFBD>
|
||||
// 处理粘贴操作
|
||||
const handlePaste = () => {
|
||||
if (!graph) return;
|
||||
if (graph.isClipboardEmpty()) {
|
||||
@ -962,7 +975,7 @@ const WorkflowDesign: React.FC = () => {
|
||||
return port?.id;
|
||||
};
|
||||
|
||||
// 获取源节点的输出端口(一定<EFBFBD><EFBFBD><EFBFBD>out组)
|
||||
// 获取源节点的输出端口(一定是out组)
|
||||
const sourcePort = getPortByGroup(sourceNode, 'out');
|
||||
|
||||
// 获取目标节点的输入端口(一定是in组)
|
||||
@ -1123,48 +1136,35 @@ const WorkflowDesign: React.FC = () => {
|
||||
}
|
||||
|
||||
// 获取所有节点和边的数据
|
||||
const nodes = graph.getNodes().map(node => {
|
||||
const nodeType = node.getProp('nodeType');
|
||||
const graphData = node.getProp('graph') || {};
|
||||
const position = node.getPosition();
|
||||
const {
|
||||
uiVariables,
|
||||
panelVariables,
|
||||
localVariables,
|
||||
formVariablesSchema,
|
||||
...rest
|
||||
} = graphData;
|
||||
return {
|
||||
const nodes = graph.getNodes().map(node => ({
|
||||
id: node.id,
|
||||
nodeCode: nodeType,
|
||||
nodeType: nodeType,
|
||||
nodeCode: node.getProp('nodeType'),
|
||||
nodeType: node.getProp('nodeType'),
|
||||
nodeName: node.attr('label/text'),
|
||||
uiVariables: {
|
||||
...uiVariables,
|
||||
position: position
|
||||
...node.getProp('graph')?.uiVariables,
|
||||
position: node.getPosition()
|
||||
},
|
||||
panelVariables,
|
||||
localVariables,
|
||||
formVariablesSchema
|
||||
};
|
||||
});
|
||||
panelVariables: node.getProp('graph')?.panelVariables,
|
||||
localVariables: node.getProp('graph')?.localVariables,
|
||||
formVariablesSchema: node.getProp('graph')?.formVariablesSchema
|
||||
}));
|
||||
|
||||
const edges = graph.getEdges().map(edge => ({
|
||||
const edges = graph.getEdges().map(edge => {
|
||||
const sourceNode = graph.getCellById(edge.getSourceCellId());
|
||||
const condition = edge.getProp('condition');
|
||||
|
||||
return {
|
||||
id: edge.id,
|
||||
from: edge.getSourceCellId(),
|
||||
to: edge.getTargetCellId(),
|
||||
name: edge.getLabels()?.[0]?.attrs?.label?.text || '',
|
||||
config: {
|
||||
type: 'sequence'
|
||||
type: 'sequence',
|
||||
condition: condition || undefined
|
||||
}
|
||||
}));
|
||||
|
||||
// 收集并合并所有节点的 formVariablesSchema
|
||||
const allFormSchemas = nodes
|
||||
.map(node => node.formVariablesSchema)
|
||||
.filter(schema => schema); // 过滤掉空值
|
||||
|
||||
const mergedFormSchema = mergeFormVariablesSchemas(allFormSchemas);
|
||||
};
|
||||
});
|
||||
|
||||
// 构建保存数据
|
||||
const saveData = {
|
||||
@ -1172,36 +1172,56 @@ const WorkflowDesign: React.FC = () => {
|
||||
graph: {
|
||||
nodes,
|
||||
edges
|
||||
},
|
||||
formVariablesSchema: mergedFormSchema
|
||||
}
|
||||
};
|
||||
|
||||
// 调用保存接口
|
||||
await saveDefinition(saveData);
|
||||
|
||||
// 使用 Modal.confirm 显示操作选择
|
||||
Modal.confirm({
|
||||
title: '保存成功',
|
||||
content: '流程设计已保存成功,请选择下一步操作',
|
||||
okText: '继续设计',
|
||||
cancelText: '返回列表',
|
||||
onOk: () => {
|
||||
// 重新加载设计数据
|
||||
if (id) {
|
||||
loadDefinitionDetail(graph, id);
|
||||
}
|
||||
},
|
||||
onCancel: () => {
|
||||
// 返回列表页
|
||||
navigate('/workflow/definition');
|
||||
}
|
||||
});
|
||||
message.success('保存成功');
|
||||
} catch (error) {
|
||||
console.error('保存流程失败:', error);
|
||||
message.error('保存流程失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 处理条件更新
|
||||
const handleConditionUpdate = (condition: EdgeCondition) => {
|
||||
if (!selectedEdge) return;
|
||||
|
||||
// 更新边的属性
|
||||
selectedEdge.setProp('condition', condition);
|
||||
|
||||
// 更新边的标签显示
|
||||
const labelText = condition.type === 'EXPRESSION'
|
||||
? condition.expression
|
||||
: '默认路径';
|
||||
|
||||
selectedEdge.setLabels([{
|
||||
attrs: {
|
||||
label: {
|
||||
text: labelText,
|
||||
fill: '#333',
|
||||
fontSize: 12
|
||||
},
|
||||
rect: {
|
||||
fill: '#fff',
|
||||
stroke: '#ccc',
|
||||
rx: 3,
|
||||
ry: 3,
|
||||
padding: 5
|
||||
}
|
||||
},
|
||||
position: {
|
||||
distance: 0.5,
|
||||
offset: 0
|
||||
}
|
||||
}]);
|
||||
|
||||
setExpressionModalVisible(false);
|
||||
setSelectedEdge(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="workflow-design">
|
||||
<div className="header">
|
||||
@ -1375,6 +1395,17 @@ const WorkflowDesign: React.FC = () => {
|
||||
onOk={handleNodeConfigUpdate}
|
||||
/>
|
||||
)}
|
||||
{selectedEdge && (
|
||||
<ExpressionModal
|
||||
visible={expressionModalVisible}
|
||||
edge={selectedEdge}
|
||||
onOk={handleConditionUpdate}
|
||||
onCancel={() => {
|
||||
setExpressionModalVisible(false);
|
||||
setSelectedEdge(null);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user