This commit is contained in:
dengqichen 2024-12-30 15:57:44 +08:00
parent 725175d069
commit fe0004bbac
2 changed files with 63 additions and 158 deletions

View File

@ -1,8 +1,9 @@
import React, {useEffect, ReactNode} from 'react'; import React, {useEffect} from 'react';
import {Drawer, Form, Input, Select, Button, Space, Tabs, Tooltip} from 'antd'; import {Drawer, Space, Tabs, TabsProps} from 'antd';
import {InfoCircleOutlined} from '@ant-design/icons';
import {Cell} from '@antv/x6'; import {Cell} from '@antv/x6';
import {NodeDefinitionResponse} from "@/pages/Workflow/NodeDesign/types"; import {NodeDefinitionResponse} from "@/pages/Workflow/NodeDesign/types";
import {BetaSchemaForm} from '@ant-design/pro-form';
import {convertJsonSchemaToColumns} from '@/utils/jsonSchemaUtils';
interface NodeConfigDrawerProps { interface NodeConfigDrawerProps {
visible: boolean; visible: boolean;
@ -12,49 +13,30 @@ interface NodeConfigDrawerProps {
onCancel: () => void; onCancel: () => void;
} }
interface SchemaProperty { interface Variables {
type: string; [key: string]: any;
title: string;
description?: string;
enum?: string[];
enumNames?: string[];
format?: string;
} }
const NodeConfigDrawer: React.FC<NodeConfigDrawerProps> = ({ const NodeConfigDrawer: React.FC<NodeConfigDrawerProps> = ({
visible, visible,
node, node,
nodeDefinition, nodeDefinition,
onOk, onOk,
onCancel, onCancel,
}) => { }) => {
const [form] = Form.useForm(); const handleSubmit = async (values: any) => {
// 在组件挂载或 nodeDefinition 更新时设置表单初始值
useEffect(() => {
if (!nodeDefinition) return;
const initialValues = {
...nodeDefinition.panelVariables,
...nodeDefinition.localVariables
};
console.log('设置表单初始值:', initialValues);
form.setFieldsValue(initialValues);
}, [nodeDefinition, form]);
const handleOk = async () => {
try { try {
const values = await form.validateFields();
// 将表单数据分离为 panelVariables 和 localVariables // 将表单数据分离为 panelVariables 和 localVariables
const panelVariables = {}; const panelVariables: Variables = {};
const localVariables = {}; const localVariables: Variables = {};
// 处理 panelVariablesSchema 中定义的字段 // 处理 panelVariablesSchema 中定义的字段
if (nodeDefinition?.panelVariablesSchema?.properties) { if (nodeDefinition?.panelVariablesSchema?.properties) {
Object.entries(nodeDefinition.panelVariablesSchema.properties).forEach(([key, property]) => { Object.entries(nodeDefinition.panelVariablesSchema.properties).forEach(([key, property]) => {
// 如果值存在就用表单值,否则用默认值
if (values[key] !== undefined) { if (values[key] !== undefined) {
panelVariables[key] = values[key]; panelVariables[key] = values[key];
} else if ((property as SchemaProperty).default !== undefined) { } else if (property.default !== undefined) {
panelVariables[key] = (property as SchemaProperty).default; panelVariables[key] = property.default;
} }
}); });
} }
@ -62,153 +44,74 @@ const NodeConfigDrawer: React.FC<NodeConfigDrawerProps> = ({
// 处理 localVariablesSchema 中定义的字段 // 处理 localVariablesSchema 中定义的字段
if (nodeDefinition?.localVariablesSchema?.properties) { if (nodeDefinition?.localVariablesSchema?.properties) {
Object.entries(nodeDefinition.localVariablesSchema.properties).forEach(([key, property]) => { Object.entries(nodeDefinition.localVariablesSchema.properties).forEach(([key, property]) => {
// 如果值存在就用表单值,否则用默认值
if (values[key] !== undefined) { if (values[key] !== undefined) {
localVariables[key] = values[key]; localVariables[key] = values[key];
} else if ((property as SchemaProperty).default !== undefined) { } else if (property.default !== undefined) {
localVariables[key] = (property as SchemaProperty).default; localVariables[key] = property.default;
} }
}); });
} }
const updatedNodeDefinition = { const updatedNodeDefinition = {
...nodeDefinition, ...nodeDefinition,
panelVariables: panelVariables, panelVariables,
localVariables: localVariables localVariables
}; };
// 返回更新后的完整节点定义
onOk(updatedNodeDefinition); onOk(updatedNodeDefinition);
// form.resetFields();
} catch (error) { } catch (error) {
console.error('Validation failed:', error); console.error('Validation failed:', error);
} }
}; };
const handleCancel = () => { const items: TabsProps['items'] = [
form.resetFields(); nodeDefinition?.panelVariablesSchema && {
onCancel(); key: 'panel',
}; label: '面板变量',
children: (
const renderFormItem = (key: string, property: SchemaProperty, required: boolean, isReadOnly: boolean) => { <BetaSchemaForm
const baseProps = { layoutType="Form"
name: key, columns={convertJsonSchemaToColumns(nodeDefinition.panelVariablesSchema)}
label: ( onFinish={handleSubmit}
<Space> initialValues={nodeDefinition.panelVariables || {}}
{property.title} submitter={false}
{property.description && ( />
<Tooltip title={property.description}> )
<InfoCircleOutlined/> },
</Tooltip> nodeDefinition?.localVariablesSchema && {
)} key: 'local',
</Space> label: '环境变量',
), children: (
rules: [{required, message: `请输入${property.title}`}], <BetaSchemaForm
initialValue: key === 'code' ? nodeDefinition?.nodeType : property.default // 如果是 code 字段,使用 nodeType 作为默认值 layoutType="Form"
}; columns={convertJsonSchemaToColumns(nodeDefinition.localVariablesSchema)}
onFinish={handleSubmit}
if (key === 'code') { initialValues={nodeDefinition.localVariables || {}}
return ( submitter={false}
<Form.Item key={key} {...baseProps}> readonly={true}
<Input disabled value={nodeDefinition?.nodeType}/> />
</Form.Item> )
);
} }
].filter(Boolean) as TabsProps['items'];
if (isReadOnly) {
return (
<Form.Item key={key} {...baseProps}>
<Input disabled value={property.default}/>
</Form.Item>
);
}
switch (property.type) {
case 'string':
if (property.enum) {
return (
<Form.Item key={key} {...baseProps}>
<Select>
{property.enum.map((value, index) => (
<Select.Option key={value} value={value}>
{property.enumNames?.[index] || value}
</Select.Option>
))}
</Select>
</Form.Item>
);
}
return (
<Form.Item key={key} {...baseProps}>
{property.format === 'textarea' ? (
<Input.TextArea rows={3}/>
) : (
<Input/>
)}
</Form.Item>
);
case 'integer': // 添加对 integer 类型的支持
return (
<Form.Item key={key} {...baseProps}>
<Input type="number"/>
</Form.Item>
);
case 'number':
return (
<Form.Item key={key} {...baseProps}>
<Input type="number"/>
</Form.Item>
);
case 'boolean':
return (
<Form.Item key={key} {...baseProps} valuePropName="checked">
<Select>
<Select.Option value={true}></Select.Option>
<Select.Option value={false}></Select.Option>
</Select>
</Form.Item>
);
default:
return null;
}
};
return ( return (
<Drawer <Drawer
title={`编辑节点 - ${nodeDefinition?.nodeName || ''}`} title={`编辑节点 - ${nodeDefinition?.nodeName || ''}`}
placement="right" placement="right"
width={480} width={480}
onClose={handleCancel} onClose={onCancel}
open={visible} open={visible}
extra={
<Space>
<Button onClick={handleCancel}></Button>
<Button type="primary" onClick={handleOk}></Button>
</Space>
}
> >
<Form form={form} layout="vertical"> <Tabs items={items}/>
<Tabs items={[ <div style={{ position: 'absolute', bottom: 0, width: '100%', borderTop: '1px solid #e8e8e8', padding: '10px 16px', textAlign: 'right', left: 0, background: '#fff' }}>
nodeDefinition?.panelVariablesSchema && { <Space>
key: 'panel', <button onClick={onCancel} className="ant-btn">
label: '面板变量',
children: Object.entries(nodeDefinition.panelVariablesSchema.properties || {}).map(([key, property]) => { </button>
// 获取必填字段列表 <button onClick={() => document.querySelector('form')?.submit()} className="ant-btn ant-btn-primary">
const requiredFields = nodeDefinition.panelVariablesSchema?.required || [];
const required = requiredFields.includes(key); </button>
return renderFormItem(key, property as SchemaProperty, required, false); </Space>
}) </div>
},
nodeDefinition?.localVariablesSchema && {
key: 'local',
label: '环境变量',
children: Object.entries(nodeDefinition.localVariablesSchema.properties || {}).map(([key, property]) => {
const requiredFields = nodeDefinition.localVariablesSchema?.required || [];
const required = requiredFields.includes(key);
return renderFormItem(key, property as SchemaProperty, required, true);
})
}
].filter(Boolean)}/>
</Form>
</Drawer> </Drawer>
); );
}; };

View File

@ -107,4 +107,6 @@ export interface NodeDefinitionResponse extends BaseResponse {
uiVariables: UIVariables | null; uiVariables: UIVariables | null;
localVariablesSchema: NodeVariablesSchema | null; localVariablesSchema: NodeVariablesSchema | null;
formVariablesSchema: NodeVariablesSchema | null; formVariablesSchema: NodeVariablesSchema | null;
panelVariables?: Record<string, any>;
localVariables?: Record<string, any>;
} }