表单设计器
This commit is contained in:
parent
90d0792f0d
commit
c033c10fb9
@ -19,6 +19,7 @@ import {
|
||||
} from 'antd';
|
||||
import { PlusOutlined, DeleteOutlined } from '@ant-design/icons';
|
||||
import type { FieldConfig, FormConfig } from '../types';
|
||||
import { DataSourceType } from '@/pages/Workflow/Design/utils/dataSourceLoader';
|
||||
|
||||
const { Text } = Typography;
|
||||
const { TabPane } = Tabs;
|
||||
@ -40,7 +41,7 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
|
||||
|
||||
React.useEffect(() => {
|
||||
if (selectedField) {
|
||||
// 确保 apiDataSource 被正确设置到表单
|
||||
// 确保嵌套对象被正确设置到表单
|
||||
const formValues = {
|
||||
...selectedField,
|
||||
apiDataSource: selectedField.apiDataSource || {
|
||||
@ -50,6 +51,9 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
|
||||
labelField: '',
|
||||
valueField: '',
|
||||
},
|
||||
predefinedDataSource: selectedField.predefinedDataSource || {
|
||||
sourceType: '',
|
||||
},
|
||||
};
|
||||
form.setFieldsValue(formValues);
|
||||
}
|
||||
@ -75,6 +79,14 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
|
||||
};
|
||||
console.log('🔄 切换到 API 数据源,已初始化配置对象');
|
||||
}
|
||||
|
||||
// 切换到预定义数据源时,初始化 predefinedDataSource 对象
|
||||
if (changedValues.dataSourceType === 'predefined' && !updatedField.predefinedDataSource) {
|
||||
updatedField.predefinedDataSource = {
|
||||
sourceType: '',
|
||||
};
|
||||
console.log('🔄 切换到预定义数据源,已初始化配置对象');
|
||||
}
|
||||
}
|
||||
|
||||
// 如果改变的是 apiDataSource 的子字段
|
||||
@ -86,9 +98,18 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
|
||||
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 => {
|
||||
if (key !== 'dataSourceType' && key !== 'apiDataSource') {
|
||||
if (key !== 'dataSourceType' && key !== 'apiDataSource' && key !== 'predefinedDataSource') {
|
||||
(updatedField as any)[key] = changedValues[key];
|
||||
}
|
||||
});
|
||||
@ -314,9 +335,10 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
|
||||
|
||||
{/* 数据源类型选择 */}
|
||||
<Form.Item label="数据源类型" name="dataSourceType">
|
||||
<Radio.Group buttonStyle="solid">
|
||||
<Radio.Button value="static">静态数据</Radio.Button>
|
||||
<Radio.Button value="api">接口数据</Radio.Button>
|
||||
<Radio.Group buttonStyle="solid" style={{ display: 'flex', flexWrap: 'nowrap' }}>
|
||||
<Radio.Button value="static" style={{ flex: 1, textAlign: 'center' }}>静态数据</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>
|
||||
</Form.Item>
|
||||
|
||||
@ -358,6 +380,42 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
|
||||
</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 数据源配置 */}
|
||||
{selectedField.dataSourceType === 'api' && (
|
||||
<div>
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
/**
|
||||
* 自定义 Hook:处理字段选项数据
|
||||
* 支持静态数据和动态API数据
|
||||
* 支持静态数据、动态API数据和预定义数据源
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import type { FieldConfig, FieldOption } from '../types';
|
||||
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;
|
||||
}
|
||||
|
||||
// 预定义数据源(使用 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 数据源
|
||||
if (field.dataSourceType === 'api' && field.apiDataSource) {
|
||||
const { url, method = 'GET', dataPath, labelField, valueField } = field.apiDataSource;
|
||||
@ -98,7 +123,7 @@ export const useFieldOptions = (field: FieldConfig): FieldOption[] => {
|
||||
};
|
||||
|
||||
loadOptions();
|
||||
}, [field.dataSourceType, field.options, field.apiDataSource]);
|
||||
}, [field.dataSourceType, field.options, field.apiDataSource, field.predefinedDataSource]);
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
@ -29,7 +29,7 @@ export interface FieldOption {
|
||||
}
|
||||
|
||||
// 数据源类型
|
||||
export type DataSourceType = 'static' | 'api';
|
||||
export type DataSourceType = 'static' | 'api' | 'predefined';
|
||||
|
||||
// API 数据源配置
|
||||
export interface ApiDataSource {
|
||||
@ -41,6 +41,11 @@ export interface ApiDataSource {
|
||||
valueField: string; // 值字段名(如 'id', 'code', 'value')
|
||||
}
|
||||
|
||||
// 预定义数据源配置(使用 dataSourceLoader 中定义的数据源)
|
||||
export interface PredefinedDataSource {
|
||||
sourceType: string; // 数据源类型,对应 DataSourceType 枚举(如 'JENKINS_SERVERS')
|
||||
}
|
||||
|
||||
// 字段配置
|
||||
export interface FieldConfig {
|
||||
id: string;
|
||||
@ -51,9 +56,10 @@ export interface FieldConfig {
|
||||
required?: boolean;
|
||||
disabled?: boolean;
|
||||
defaultValue?: any;
|
||||
options?: FieldOption[]; // 静态选项数据
|
||||
dataSourceType?: DataSourceType; // 数据源类型:static(静态)或 api(接口)
|
||||
apiDataSource?: ApiDataSource; // API 数据源配置(当 dataSourceType 为 'api' 时使用)
|
||||
options?: FieldOption[]; // 静态选项数据
|
||||
dataSourceType?: DataSourceType; // 数据源类型:static(静态)、api(接口)或 predefined(预定义)
|
||||
apiDataSource?: ApiDataSource; // API 数据源配置(当 dataSourceType 为 'api' 时使用)
|
||||
predefinedDataSource?: PredefinedDataSource; // 预定义数据源配置(当 dataSourceType 为 'predefined' 时使用)
|
||||
min?: number;
|
||||
max?: number;
|
||||
rows?: number;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user