import type {ProFormColumnsType} from '@ant-design/pro-components'; import request from '@/utils/request'; interface EditorConfig { language?: string; theme?: string; minimap?: boolean; lineNumbers?: boolean; wordWrap?: boolean; fontSize?: number; tabSize?: number; autoComplete?: boolean; folding?: boolean; } interface DataSourceConfig { type: 'api'; url: string; valueField: string; labelField: string; dependsOn?: string[]; params?: Record; } interface JsonSchemaProperty { type: string; title?: string; description?: string; default?: any; enum?: any[]; enumNames?: string[]; format?: string; editorConfig?: EditorConfig; dataSource?: DataSourceConfig; items?: { type: string; enum?: any[]; enumNames?: string[]; }; minimum?: number; maximum?: number; minLength?: number; maxLength?: number; pattern?: string; readOnly?: boolean; } interface JsonSchema { type: string; properties: Record; required?: string[]; } // 处理参数替换,将 ${fieldName} 替换为实际值 const replaceParams = (params: Record, formValues: Record): Record => { const result: Record = {}; for (const [key, value] of Object.entries(params)) { if (typeof value === 'string' && value.startsWith('${') && value.endsWith('}')) { const fieldName = value.slice(2, -1); result[key] = formValues[fieldName] || formValues[key]; } else { result[key] = value; } } return result; }; // 获取远程数据源的选项 const fetchDataSourceOptions = async ( dataSource: DataSourceConfig, formValues: Record = {} ) => { try { // 处理依赖参数 const params = { ...formValues, // 包含所有表单值 ...(dataSource.params ? replaceParams(dataSource.params, formValues) : {}) // 覆盖特定参数 }; console.log('Fetching data from:', dataSource.url); console.log('With params:', params); // 发起请求 const response = await request.get(dataSource.url, { params }); console.log('API Response:', response); // 转换响应数据为选项格式 if (!Array.isArray(response)) { console.warn('Response is not an array:', response); return []; } const options = response.map(item => { const option = { label: item[dataSource.labelField], value: item[dataSource.valueField], }; console.log('Mapped option:', option); return option; }); console.log('Final options:', options); return options; } catch (error) { console.error('Failed to fetch data source options:', error); return []; } }; export const convertJsonSchemaToColumns = (schema: JsonSchema): ProFormColumnsType[] => { if (!schema?.properties) return []; return Object.entries(schema.properties).map(([key, value]: [string, JsonSchemaProperty]) => { const baseConfig = { title: value.description ? `${value.title || key} (${value.description})` : (value.title || key), dataIndex: key, formItemProps: { required: schema.required?.includes(key), }, initialValue: value.default, readonly: value.readOnly, }; // 根据类型处理不同的表单项 switch (value.type) { case 'string': // 如果有数据源配置,使用远程数据源的选择器 if (value.dataSource && value.dataSource.type === 'api') { const dataSource = value.dataSource; return { ...baseConfig, valueType: 'select', fieldProps: { showSearch: true, placeholder: `请选择${value.title || key}`, disabled: value.readOnly, allowClear: true, showArrow: true, filterOption: (input: string, option: any) => option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0, onChange: (value: any, option: any) => { console.log('Select value changed:', value, option); }, }, dependencies: dataSource.dependsOn, request: async (params: any) => { console.log('Select field request triggered:', key); console.log('Request params:', params); // 获取表单当前值,包括当前字段的值 const formValues = { ...params?.form?.getFieldsValue(), [key]: params?.value, // 包含当前字段的值 ...params // 包含其他参数 }; console.log('Current form values:', formValues); // 检查依赖字段是否都有值 const hasDependencies = !dataSource.dependsOn?.some( field => { const value = formValues[field]; return value === undefined || value === null || value === ''; } ); console.log('Dependencies check:', { required: dataSource.dependsOn, formValues, hasDependencies }); // 如果有依赖且依赖值都存在,或者没有依赖,则发起请求 if (!dataSource.dependsOn || hasDependencies) { return await fetchDataSourceOptions(dataSource, formValues); } console.log('Skipping request due to missing dependencies'); return []; }, }; } // 如果有枚举值,使用选择器 if (value.enum) { return { ...baseConfig, valueType: 'select', fieldProps: { options: value.enum.map((item, index) => ({ label: value.enumNames?.[index] || item, value: item, })), placeholder: `请选择${value.title || key}`, disabled: value.readOnly, }, }; } // 处理 monaco-editor 格式 if (value.format === 'monaco-editor') { const editorConfig = value.editorConfig || {}; return { ...baseConfig, valueType: 'code', fieldProps: { language: editorConfig.language || 'shell', height: 300, options: { minimap: { enabled: editorConfig.minimap ?? false }, fontSize: editorConfig.fontSize || 14, lineNumbers: editorConfig.lineNumbers ? 'on' : 'off', wordWrap: editorConfig.wordWrap ? 'on' : 'off', tabSize: editorConfig.tabSize || 2, scrollBeyondLastLine: false, automaticLayout: true, folding: editorConfig.folding ?? true, autoClosingBrackets: 'always', autoClosingQuotes: 'always', formatOnPaste: true, formatOnType: true, suggestOnTriggerCharacters: editorConfig.autoComplete ?? true, renderWhitespace: 'boundary', readOnly: value.readOnly, } } }; } // 否则使用文本输入框 return { ...baseConfig, valueType: 'text', fieldProps: { placeholder: `请输入${value.title || key}`, disabled: value.readOnly, }, }; case 'number': case 'integer': return { ...baseConfig, valueType: 'digit', fieldProps: { min: value.minimum, max: value.maximum, placeholder: `请输入${value.title || key}`, style: { width: '100%' }, disabled: value.readOnly, }, }; case 'boolean': return { ...baseConfig, valueType: 'switch', fieldProps: { disabled: value.readOnly, }, }; case 'array': // 处理数组类型的枚举值 if (value.items?.enum || value.enum) { const enumValues = value.items?.enum || value.enum || []; const enumNames = value.items?.enumNames || value.enumNames; return { ...baseConfig, valueType: 'select', fieldProps: { mode: 'multiple', options: enumValues.map((item, index) => ({ label: enumNames?.[index] || item, value: item, })), placeholder: `请选择${value.title || key}`, disabled: value.readOnly, }, }; } // 否则使用标签输入 return { ...baseConfig, valueType: 'select', fieldProps: { mode: 'tags', placeholder: `请输入${value.title || key}`, disabled: value.readOnly, }, }; case 'object': return { ...baseConfig, valueType: 'jsonCode', fieldProps: { placeholder: `请输入${value.title || key}`, disabled: value.readOnly, }, }; default: return { ...baseConfig, valueType: 'text', fieldProps: { placeholder: `请输入${value.title || key}`, disabled: value.readOnly, }, }; } }); };