diff --git a/frontend/src/utils/jsonSchemaUtils.ts b/frontend/src/utils/jsonSchemaUtils.ts index 7fa5a593..881aebd0 100644 --- a/frontend/src/utils/jsonSchemaUtils.ts +++ b/frontend/src/utils/jsonSchemaUtils.ts @@ -1,4 +1,5 @@ import type {ProFormColumnsType} from '@ant-design/pro-form'; +import request from '@/utils/request'; interface EditorConfig { language?: string; @@ -12,6 +13,15 @@ interface EditorConfig { folding?: boolean; } +interface DataSourceConfig { + type: 'api'; + url: string; + valueField: string; + labelField: string; + dependsOn?: string[]; + params?: Record; +} + interface JsonSchemaProperty { type: string; title?: string; @@ -21,6 +31,7 @@ interface JsonSchemaProperty { enumNames?: string[]; format?: string; editorConfig?: EditorConfig; + dataSource?: DataSourceConfig; items?: { type: string; enum?: any[]; @@ -40,6 +51,62 @@ interface JsonSchema { 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 []; @@ -57,6 +124,63 @@ export const convertJsonSchemaToColumns = (schema: JsonSchema): ProFormColumnsTy // 根据类型处理不同的表单项 switch (value.type) { case 'string': + // 如果有数据源配置,使用远程数据源的选择器 + if (value.dataSource && value.dataSource.type === 'api') { + const dataSource = value.dataSource; + console.log('Creating select field with dataSource:', key, 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 { @@ -135,9 +259,7 @@ export const convertJsonSchemaToColumns = (schema: JsonSchema): ProFormColumnsTy }; case 'array': - // 处理数组类型的枚举值,支持两种方式: - // 1. enum 定义在 items 中 - // 2. enum 直接定义在属性上 + // 处理数组类型的枚举值 if (value.items?.enum || value.enum) { const enumValues = value.items?.enum || value.enum || []; const enumNames = value.items?.enumNames || value.enumNames;