表单设计器
This commit is contained in:
parent
90d0792f0d
commit
c033c10fb9
@ -19,6 +19,7 @@ import {
|
|||||||
} from 'antd';
|
} from 'antd';
|
||||||
import { PlusOutlined, DeleteOutlined } from '@ant-design/icons';
|
import { PlusOutlined, DeleteOutlined } from '@ant-design/icons';
|
||||||
import type { FieldConfig, FormConfig } from '../types';
|
import type { FieldConfig, FormConfig } from '../types';
|
||||||
|
import { DataSourceType } from '@/pages/Workflow/Design/utils/dataSourceLoader';
|
||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
const { TabPane } = Tabs;
|
const { TabPane } = Tabs;
|
||||||
@ -40,7 +41,7 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
|
|||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (selectedField) {
|
if (selectedField) {
|
||||||
// 确保 apiDataSource 被正确设置到表单
|
// 确保嵌套对象被正确设置到表单
|
||||||
const formValues = {
|
const formValues = {
|
||||||
...selectedField,
|
...selectedField,
|
||||||
apiDataSource: selectedField.apiDataSource || {
|
apiDataSource: selectedField.apiDataSource || {
|
||||||
@ -50,6 +51,9 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
|
|||||||
labelField: '',
|
labelField: '',
|
||||||
valueField: '',
|
valueField: '',
|
||||||
},
|
},
|
||||||
|
predefinedDataSource: selectedField.predefinedDataSource || {
|
||||||
|
sourceType: '',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
form.setFieldsValue(formValues);
|
form.setFieldsValue(formValues);
|
||||||
}
|
}
|
||||||
@ -75,6 +79,14 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
|
|||||||
};
|
};
|
||||||
console.log('🔄 切换到 API 数据源,已初始化配置对象');
|
console.log('🔄 切换到 API 数据源,已初始化配置对象');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 切换到预定义数据源时,初始化 predefinedDataSource 对象
|
||||||
|
if (changedValues.dataSourceType === 'predefined' && !updatedField.predefinedDataSource) {
|
||||||
|
updatedField.predefinedDataSource = {
|
||||||
|
sourceType: '',
|
||||||
|
};
|
||||||
|
console.log('🔄 切换到预定义数据源,已初始化配置对象');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果改变的是 apiDataSource 的子字段
|
// 如果改变的是 apiDataSource 的子字段
|
||||||
@ -86,9 +98,18 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
|
|||||||
console.log('💾 API 数据源配置已更新:', updatedField.apiDataSource);
|
console.log('💾 API 数据源配置已更新:', updatedField.apiDataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果改变的是 predefinedDataSource 的子字段
|
||||||
|
if ('predefinedDataSource' in changedValues) {
|
||||||
|
updatedField.predefinedDataSource = {
|
||||||
|
...updatedField.predefinedDataSource,
|
||||||
|
...changedValues.predefinedDataSource,
|
||||||
|
};
|
||||||
|
console.log('💾 预定义数据源配置已更新:', updatedField.predefinedDataSource);
|
||||||
|
}
|
||||||
|
|
||||||
// 合并其他字段
|
// 合并其他字段
|
||||||
Object.keys(changedValues).forEach(key => {
|
Object.keys(changedValues).forEach(key => {
|
||||||
if (key !== 'dataSourceType' && key !== 'apiDataSource') {
|
if (key !== 'dataSourceType' && key !== 'apiDataSource' && key !== 'predefinedDataSource') {
|
||||||
(updatedField as any)[key] = changedValues[key];
|
(updatedField as any)[key] = changedValues[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -314,9 +335,10 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
|
|||||||
|
|
||||||
{/* 数据源类型选择 */}
|
{/* 数据源类型选择 */}
|
||||||
<Form.Item label="数据源类型" name="dataSourceType">
|
<Form.Item label="数据源类型" name="dataSourceType">
|
||||||
<Radio.Group buttonStyle="solid">
|
<Radio.Group buttonStyle="solid" style={{ display: 'flex', flexWrap: 'nowrap' }}>
|
||||||
<Radio.Button value="static">静态数据</Radio.Button>
|
<Radio.Button value="static" style={{ flex: 1, textAlign: 'center' }}>静态数据</Radio.Button>
|
||||||
<Radio.Button value="api">接口数据</Radio.Button>
|
<Radio.Button value="predefined" style={{ flex: 1, textAlign: 'center' }}>预定义</Radio.Button>
|
||||||
|
<Radio.Button value="api" style={{ flex: 1, textAlign: 'center' }}>自定义</Radio.Button>
|
||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
@ -358,6 +380,42 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* 预定义方法配置 */}
|
||||||
|
{selectedField.dataSourceType === 'predefined' && (
|
||||||
|
<div>
|
||||||
|
<Text strong>预定义方法</Text>
|
||||||
|
<div style={{ marginTop: 12 }}>
|
||||||
|
<Form.Item
|
||||||
|
label="数据源"
|
||||||
|
name={['predefinedDataSource', 'sourceType']}
|
||||||
|
rules={[{ required: true, message: '请选择数据源' }]}
|
||||||
|
>
|
||||||
|
<Select placeholder="选择预定义数据源">
|
||||||
|
{Object.keys(DataSourceType).map((key) => {
|
||||||
|
const sourceType = DataSourceType[key as keyof typeof DataSourceType];
|
||||||
|
return (
|
||||||
|
<Select.Option key={sourceType} value={sourceType}>
|
||||||
|
{key.replace(/_/g, ' ')}
|
||||||
|
</Select.Option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<div style={{
|
||||||
|
padding: 12,
|
||||||
|
background: '#f5f5f5',
|
||||||
|
borderRadius: 4,
|
||||||
|
fontSize: 12,
|
||||||
|
color: '#666'
|
||||||
|
}}>
|
||||||
|
<div><strong>💡 提示:</strong></div>
|
||||||
|
<div style={{ marginTop: 4 }}>使用系统预定义的数据源方法,无需配置URL和字段映射</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* API 数据源配置 */}
|
{/* API 数据源配置 */}
|
||||||
{selectedField.dataSourceType === 'api' && (
|
{selectedField.dataSourceType === 'api' && (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* 自定义 Hook:处理字段选项数据
|
* 自定义 Hook:处理字段选项数据
|
||||||
* 支持静态数据和动态API数据
|
* 支持静态数据、动态API数据和预定义数据源
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import type { FieldConfig, FieldOption } from '../types';
|
import type { FieldConfig, FieldOption } from '../types';
|
||||||
import request from '../../../utils/request';
|
import request from '../../../utils/request';
|
||||||
|
import { loadDataSource, DataSourceType as WorkflowDataSourceType } from '@/pages/Workflow/Design/utils/dataSourceLoader';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从对象中根据路径提取数据
|
* 从对象中根据路径提取数据
|
||||||
@ -40,6 +41,30 @@ export const useFieldOptions = (field: FieldConfig): FieldOption[] => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 预定义数据源(使用 Workflow 中定义的数据源加载器)
|
||||||
|
if (field.dataSourceType === 'predefined' && field.predefinedDataSource) {
|
||||||
|
const { sourceType } = field.predefinedDataSource;
|
||||||
|
|
||||||
|
if (!sourceType) {
|
||||||
|
console.warn('⚠️ 预定义数据源配置不完整,缺少 sourceType');
|
||||||
|
setOptions([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 调用 Workflow 的数据源加载器
|
||||||
|
const dataSourceOptions = await loadDataSource(sourceType as WorkflowDataSourceType);
|
||||||
|
|
||||||
|
// dataSourceLoader 已经转换为 { label, value } 格式
|
||||||
|
setOptions(dataSourceOptions);
|
||||||
|
console.log('✅ 预定义数据源加载成功', { sourceType, count: dataSourceOptions.length });
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ 加载预定义数据源失败', { sourceType, error });
|
||||||
|
setOptions([]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// API 数据源
|
// API 数据源
|
||||||
if (field.dataSourceType === 'api' && field.apiDataSource) {
|
if (field.dataSourceType === 'api' && field.apiDataSource) {
|
||||||
const { url, method = 'GET', dataPath, labelField, valueField } = field.apiDataSource;
|
const { url, method = 'GET', dataPath, labelField, valueField } = field.apiDataSource;
|
||||||
@ -98,7 +123,7 @@ export const useFieldOptions = (field: FieldConfig): FieldOption[] => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
loadOptions();
|
loadOptions();
|
||||||
}, [field.dataSourceType, field.options, field.apiDataSource]);
|
}, [field.dataSourceType, field.options, field.apiDataSource, field.predefinedDataSource]);
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -29,7 +29,7 @@ export interface FieldOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 数据源类型
|
// 数据源类型
|
||||||
export type DataSourceType = 'static' | 'api';
|
export type DataSourceType = 'static' | 'api' | 'predefined';
|
||||||
|
|
||||||
// API 数据源配置
|
// API 数据源配置
|
||||||
export interface ApiDataSource {
|
export interface ApiDataSource {
|
||||||
@ -41,6 +41,11 @@ export interface ApiDataSource {
|
|||||||
valueField: string; // 值字段名(如 'id', 'code', 'value')
|
valueField: string; // 值字段名(如 'id', 'code', 'value')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 预定义数据源配置(使用 dataSourceLoader 中定义的数据源)
|
||||||
|
export interface PredefinedDataSource {
|
||||||
|
sourceType: string; // 数据源类型,对应 DataSourceType 枚举(如 'JENKINS_SERVERS')
|
||||||
|
}
|
||||||
|
|
||||||
// 字段配置
|
// 字段配置
|
||||||
export interface FieldConfig {
|
export interface FieldConfig {
|
||||||
id: string;
|
id: string;
|
||||||
@ -51,9 +56,10 @@ export interface FieldConfig {
|
|||||||
required?: boolean;
|
required?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
defaultValue?: any;
|
defaultValue?: any;
|
||||||
options?: FieldOption[]; // 静态选项数据
|
options?: FieldOption[]; // 静态选项数据
|
||||||
dataSourceType?: DataSourceType; // 数据源类型:static(静态)或 api(接口)
|
dataSourceType?: DataSourceType; // 数据源类型:static(静态)、api(接口)或 predefined(预定义)
|
||||||
apiDataSource?: ApiDataSource; // API 数据源配置(当 dataSourceType 为 'api' 时使用)
|
apiDataSource?: ApiDataSource; // API 数据源配置(当 dataSourceType 为 'api' 时使用)
|
||||||
|
predefinedDataSource?: PredefinedDataSource; // 预定义数据源配置(当 dataSourceType 为 'predefined' 时使用)
|
||||||
min?: number;
|
min?: number;
|
||||||
max?: number;
|
max?: number;
|
||||||
rows?: number;
|
rows?: number;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user