From 362162d897b67712be885dadd5d2bf6ec23f2a89 Mon Sep 17 00:00:00 2001 From: zhenjintao Date: Thu, 20 Jan 2022 19:22:08 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20hidden=E3=80=81group=E3=80=81form?= =?UTF-8?q?=E3=80=81tabs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/detail/importSubform/index.tsx | 27 +- src/components/formFields/form/display.tsx | 344 +++++++++++++++++ src/components/formFields/group/display.tsx | 277 ++++++++++++++ src/components/formFields/hidden/display.tsx | 5 + .../formFields/importSubform/display.tsx | 272 +++++++++++++ src/components/formFields/index.tsx | 12 +- src/components/formFields/tabs/display.tsx | 362 ++++++++++++++++++ src/index.tsx | 5 + 8 files changed, 1295 insertions(+), 9 deletions(-) create mode 100644 src/components/formFields/form/display.tsx create mode 100644 src/components/formFields/group/display.tsx create mode 100644 src/components/formFields/hidden/display.tsx create mode 100644 src/components/formFields/importSubform/display.tsx create mode 100644 src/components/formFields/tabs/display.tsx diff --git a/src/components/detail/importSubform/index.tsx b/src/components/detail/importSubform/index.tsx index d56f6ab..5b0e44f 100644 --- a/src/components/detail/importSubform/index.tsx +++ b/src/components/detail/importSubform/index.tsx @@ -151,16 +151,11 @@ export default class ImportSubformField extends DetailField } - render = () => { + getConfigData=() => { const { config, - formLayout, - value, - record, - data, - step + value } = this.props - if (config.configFrom && config.configFrom.type === 'interface' && config.configFrom.interface) { this.interfaceHelper.request( config.configFrom.interface, @@ -187,7 +182,6 @@ export default class ImportSubformField extends DetailField { + const { + config, + formLayout, + value, + record, + data, + step + } = this.props + + const fields = this.state.fields if (!fields || !Array.isArray(fields) || fields.length === 0) { return } else { diff --git a/src/components/formFields/form/display.tsx b/src/components/formFields/form/display.tsx new file mode 100644 index 0000000..f6a861a --- /dev/null +++ b/src/components/formFields/form/display.tsx @@ -0,0 +1,344 @@ +import React from 'react' +import { display as getALLComponents } from '../' +import { FormFieldConfig } from '.' +import { Display, FieldConfigs, FieldError, FieldProps } from '../common' +import { getValue, setValue } from '../../../util/value' +import { cloneDeep } from 'lodash' +import ConditionHelper from '../../../util/condition' + +export interface IFormField { + canCollapse?: boolean + children: React.ReactNode[] +} + +export interface IFormFieldItem { + index: number + title: string + canCollapse?: boolean + children: React.ReactNode[] +} + +export interface IFormFieldItemField { + index: number + label: string + fieldType: string + children: React.ReactNode +} + +interface FormState { + didMount: boolean + formDataList: { status: 'normal' | 'error' | 'loading', message?: string }[][] + showItem: boolean + showIndex: number +} + +export default class FormField extends Display, FormState> { + getALLComponents = (type: any): typeof Display => getALLComponents[type] + + formFieldsList: Array | null>> = [] + formFieldsMountedList: Array> = [] + + constructor (props: FieldProps) { + super(props) + + this.state = { + didMount: false, + formDataList: [], + showItem: false, + showIndex: 0 + } + } + + didMount = async () => { + await this.setState({ + didMount: true + }) + } + + set = async (value: any) => { + if (this.props.config.unstringify && this.props.config.unstringify.length > 0 && Array.isArray(value)) { + for (let index = 0; index < value.length; index++) { + if (value[index]) { + for (const field of this.props.config.unstringify) { + const info = getValue(value[index], field) + try { + value[index] = setValue(value[index], field, JSON.parse(info)) + } catch (e) {} + } + } + } + } + + return value + } + + get = async () => { + const data: any[] = [] + + for (let index = 0; index < this.formFieldsList.length; index++) { + if (this.formFieldsList[index]) { + let item: any = {} + + if (Array.isArray(this.props.config.fields)) { + for (const formFieldIndex in this.props.config.fields) { + const formFieldConfig = this.props.config.fields[formFieldIndex] + if (!ConditionHelper(formFieldConfig.condition, { record: this.props.value[index], data: this.props.data, step: this.props.step })) { + continue + } + const formField = this.formFieldsList[index] && this.formFieldsList[index][formFieldIndex] + if (formField) { + const value = await formField.get() + item = setValue(item, formFieldConfig.field, value) + } + } + } + + if (this.props.config.stringify) { + for (const field of this.props.config.stringify) { + const info = getValue(item, field) + item = setValue(item, field, JSON.stringify(info)) + } + } + + data[index] = item + } + } + + return data + } + + handleMount = async (index: number, formFieldIndex: number) => { + if (!this.formFieldsMountedList[index]) { + this.formFieldsMountedList[index] = [] + } + if (this.formFieldsMountedList[index][formFieldIndex]) { + return true + } + this.formFieldsMountedList[index][formFieldIndex] = true + + const formDataList = cloneDeep(this.state.formDataList) + if (!formDataList[index]) formDataList[index] = [] + + if (this.formFieldsList[index] && this.formFieldsList[index][formFieldIndex]) { + const formField = this.formFieldsList[index][formFieldIndex] + if (formField) { + const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] + + let value = getValue(this.props.value[index] === undefined ? {} : this.props.value[index], formFieldConfig.field) + const source = value + if ((formFieldConfig.defaultValue) && value === undefined) { + value = await formField.reset() + } + value = await formField.set(value) + if (source !== value) { + this.props.onValueSet(`[${index}]${formFieldConfig.field}`, value, true) + } + + if (value !== undefined) { + formDataList[index][formFieldIndex] = { status: 'normal' } + } + + await formField.didMount() + } + } + + await this.setState({ + formDataList + }) + } + + handleValueSet = async (index: number, formFieldIndex: number, path: string, value: any, validation: true | FieldError[]) => { + const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] + if (formFieldConfig) { + const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + await this.props.onValueSet(`[${index}]${fullPath}`, value, true) + + const formDataList = cloneDeep(this.state.formDataList) + if (validation === true) { + formDataList[index][formFieldIndex] = { status: 'normal' } + } else { + formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } + } + + this.setState({ + formDataList + }) + } + } + + handleValueUnset = async (index: number, formFieldIndex: number, path: string, validation: true | FieldError[]) => { + const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] + if (formFieldConfig) { + const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + await this.props.onValueUnset(`[${index}]${fullPath}`, true) + + const formDataList = cloneDeep(this.state.formDataList) + if (validation === true) { + formDataList[index][formFieldIndex] = { status: 'normal' } + } else { + formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } + } + + this.setState({ + formDataList + }) + } + } + + handleValueListAppend = async (index: number, formFieldIndex: number, path: string, value: any, validation: true | FieldError[]) => { + const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] + if (formFieldConfig) { + const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + await this.props.onValueListAppend(`[${index}]${fullPath}`, value, true) + + const formDataList = cloneDeep(this.state.formDataList) + if (validation === true) { + formDataList[index][formFieldIndex] = { status: 'normal' } + } else { + formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } + } + + this.setState({ + formDataList + }) + } + } + + handleValueListSplice = async (index: number, formFieldIndex: number, path: string, _index: number, count: number, validation: true | FieldError[]) => { + const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] + if (formFieldConfig) { + const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + await this.props.onValueListSplice(`[${index}]${fullPath}`, _index, count, true) + + const formDataList = cloneDeep(this.state.formDataList) + if (validation === true) { + formDataList[index][formFieldIndex] = { status: 'normal' } + } else { + formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } + } + + this.setState({ + formDataList + }) + } + } + + /** + * 用于展示子表单组件中的每一子项中的每一个子表单项组件 + * @param props + * @returns + */ + renderItemFieldComponent = (props: IFormFieldItemField) => { + return + 您当前使用的UI版本没有实现FormField组件的renderItemFieldComponent方法。 + + } + + /** + * 用于展示子表单组件中的每一个子项 + * @param props + * @returns + */ + renderItemComponent = (props: IFormFieldItem) => { + return + 您当前使用的UI版本没有实现FormField组件的renderItemComponent方法。 + + } + + /** + * 用于展示子表单组件 + * @param _props + * @returns + */ + renderComponent = (_props: IFormField) => { + return + 您当前使用的UI版本没有实现FormField组件。 + + } + + render = () => { + const { + value = [], + data, + step, + config: { + fields, + primaryField, + canCollapse + } + } = this.props + + return ( + + { + this.renderComponent({ + canCollapse, + children: ( + this.state.didMount + ? (Array.isArray(value) ? value : []).map((itemValue: any, index: number) => { + return + {this.renderItemComponent({ + index, + title: primaryField !== undefined ? getValue(itemValue, primaryField, '').toString() : index.toString(), + canCollapse, + children: (fields || []).map((formFieldConfig, fieldIndex) => { + if (!ConditionHelper(formFieldConfig.condition, { record: itemValue, data: this.props.data, step: this.props.step })) { + if (!this.formFieldsMountedList[index]) this.formFieldsMountedList[index] = [] + this.formFieldsMountedList[index][fieldIndex] = false + return null + } + const FormField = this.getALLComponents(formFieldConfig.type) || Display + + let status = ((this.state.formDataList[index] || [])[fieldIndex] || {}).status || 'normal' + + if (['group', 'import_subform', 'object', 'tabs', 'form'].some((type) => type === formFieldConfig.type)) { + status = 'normal' + } + // 渲染表单项容器 + return ( +
+ { + this.renderItemFieldComponent({ + index: fieldIndex, + label: formFieldConfig.label, + fieldType: formFieldConfig.type, + children: ( + | null) => { + if (fieldRef) { + if (!this.formFieldsList[index]) this.formFieldsList[index] = [] + this.formFieldsList[index][fieldIndex] = fieldRef + this.handleMount(index, fieldIndex) + } + }} + value={getValue(value[index], formFieldConfig.field)} + record={value[index]} + data={cloneDeep(data)} + step={step} + config={formFieldConfig} + onValueSet={async (path, value, validation) => this.handleValueSet(index, fieldIndex, path, value, validation)} + onValueUnset={async (path, validation) => this.handleValueUnset(index, fieldIndex, path, validation)} + onValueListAppend={async (path, value, validation) => this.handleValueListAppend(index, fieldIndex, path, value, validation)} + onValueListSplice={async (path, _index, count, validation) => this.handleValueListSplice(index, fieldIndex, path, _index, count, validation)} + baseRoute={this.props.baseRoute} + loadDomain={async (domain: string) => await this.props.loadDomain(domain)} + /> + ) + }) + } +
+ ) + }) + }) + } +
+ } + ) + : [] + ) + }) + } +
+ ) + } +} diff --git a/src/components/formFields/group/display.tsx b/src/components/formFields/group/display.tsx new file mode 100644 index 0000000..fc9a131 --- /dev/null +++ b/src/components/formFields/group/display.tsx @@ -0,0 +1,277 @@ +import React from 'react' +import { display as getALLComponents, FieldConfigs } from '../' +import { GroupFieldConfig, IGroupField } from '.' +import { setValue, getValue, getBoolean } from '../../../util/value' +import { Display, FieldError, FieldProps } from '../common' +import { IFormItem } from '../../../steps/form' +import { cloneDeep } from 'lodash' +import ConditionHelper from '../../../util/condition' +import StatementHelper from '../../../util/statement' + +interface IGroupFieldState { + didMount: boolean + formData: { status: 'normal' | 'error' | 'loading', message?: string, name?: string }[] +} + +export default class GroupField extends Display { + // 各表单项对应的类型所使用的UI组件的类 + getALLComponents = (type: any): typeof Display => getALLComponents[type] + + formFields: Array | null> = [] + formFieldsMounted: Array = [] + + constructor (props: FieldProps) { + super(props) + + this.state = { + didMount: false, + formData: [] + } + } + + didMount = async () => { + await this.setState({ + didMount: true + }) + } + + get = async () => { + let data: any = {} + + if (Array.isArray(this.props.config.fields)) { + for (let formFieldIndex = 0; formFieldIndex < this.props.config.fields.length; formFieldIndex++) { + const formFieldConfig = this.props.config.fields[formFieldIndex] + if (!ConditionHelper(formFieldConfig.condition, { record: this.props.value, data: this.props.data, step: this.props.step })) { + continue + } + const formField = this.formFields[formFieldIndex] + if (formField) { + const value = await formField.get() + data = setValue(data, formFieldConfig.field, value) + } + } + } + return data + } + + handleMount = async (formFieldIndex: number) => { + if (this.formFieldsMounted[formFieldIndex]) { + return true + } + this.formFieldsMounted[formFieldIndex] = true + + if (this.formFields[formFieldIndex]) { + const formField = this.formFields[formFieldIndex] + if (formField) { + const formFieldConfig = this.props.config.fields[formFieldIndex] + + let value = getValue(this.props.value, formFieldConfig.field) + const source = value + if ((formFieldConfig.defaultValue) && value === undefined) { + value = await formField.reset() + } + value = await formField.set(value) + if (source !== value) { + this.props.onValueSet(formFieldConfig.field, value, true) + } + + if (value !== undefined) { + this.setState(({ formData }) => { + formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } + return { formData: cloneDeep(formData) } + }) + } + await formField.didMount() + } + } + } + + handleValueSet = async (formFieldIndex: number, path: string, value: any, validation: true | FieldError[]) => { + const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] + if (formFieldConfig) { + const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + await this.props.onValueSet(fullPath, value, true) + const formData = cloneDeep(this.state.formData) + if (validation === true) { + formData[formFieldIndex] = { status: 'normal' } + } else { + formData[formFieldIndex] = { status: 'error', message: validation[0].message } + } + + this.setState({ + formData + }) + } + } + + handleValueUnset = async (formFieldIndex: number, path: string, validation: true | FieldError[]) => { + const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] + if (formFieldConfig) { + const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + await this.props.onValueUnset(fullPath, true) + const formData = cloneDeep(this.state.formData) + if (validation === true) { + formData[formFieldIndex] = { status: 'normal' } + } else { + formData[formFieldIndex] = { status: 'error', message: validation[0].message } + } + + this.setState({ + formData + }) + } + } + + handleValueListAppend = async (formFieldIndex: number, path: string, value: any, validation: true | FieldError[]) => { + const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] + if (formFieldConfig) { + const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + await this.props.onValueListAppend(fullPath, value, true) + const formData = cloneDeep(this.state.formData) + if (validation === true) { + formData[formFieldIndex] = { status: 'normal' } + } else { + formData[formFieldIndex] = { status: 'error', message: validation[0].message } + } + + this.setState({ + formData + }) + } + } + + handleValueListSplice = async (formFieldIndex: number, path: string, index: number, count: number, validation: true | FieldError[]) => { + const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] + if (formFieldConfig) { + const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + await this.props.onValueListSplice(fullPath, index, count, true) + const formData = cloneDeep(this.state.formData) + if (validation === true) { + formData[formFieldIndex] = { status: 'normal' } + } else { + formData[formFieldIndex] = { status: 'error', message: validation[0].message } + } + + this.setState({ + formData + }) + } + } + + handleValueListSort = async (formFieldIndex: number, path: string, index: number, sortType: 'up' | 'down', validation: true | FieldError[]) => { + const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] + if (formFieldConfig) { + const formData = cloneDeep(this.state.formData) + if (validation === true) { + formData[formFieldIndex] = { status: 'normal' } + } else { + formData[formFieldIndex] = { status: 'error', message: validation[0].message } + } + + this.setState({ + formData + }) + } + } + + renderComponent = (props: IGroupField) => { + return + 您当前使用的UI版本没有实现GroupField组件。 + + } + + /** + * 表单项组件 - UI渲染方法 + * 各UI库需重写该方法 + * @param props + */ + renderItemComponent = (props: IFormItem) => { + return + 您当前使用的UI版本没有实现FormItem组件。 + + } + + render = () => { + const { + value, + record, + data, + step + } = this.props + + return ( + + {this.renderComponent({ + children: this.state.didMount + ? (this.props.config.fields || []).map((formFieldConfig, formFieldIndex) => { + if (!ConditionHelper(formFieldConfig.condition, { record: value, data: this.props.data, step: this.props.step })) { + this.formFieldsMounted[formFieldIndex] = false + return null + } + let hidden: boolean = true + let display: boolean = true + + if (formFieldConfig.type === 'hidden') { + hidden = true + display = false + } + + if (formFieldConfig.display === 'none') { + hidden = true + display = false + } + + const FormField = this.getALLComponents(formFieldConfig.type) || Display + + let status = (this.state.formData[formFieldIndex] || {}).status || 'normal' + + if (['group', 'import_subform', 'object', 'tabs', 'form'].some((type) => type === formFieldConfig.type)) { + status = 'normal' + } + + const renderData = { + key: formFieldIndex, + label: formFieldConfig.label, + status, + layout: 'horizontal' as 'horizontal', + message: (this.state.formData[formFieldIndex] || {}).message || '', + extra: StatementHelper(formFieldConfig.extra, { record: this.props.record, data: this.props.data, step: this.props.step }), + required: getBoolean(formFieldConfig.required), + visitable: display, + fieldType: formFieldConfig.type, + children: ( + | null) => { + if (formField) { + this.formFields[formFieldIndex] = formField + this.handleMount(formFieldIndex) + } + }} + value={getValue(value, formFieldConfig.field)} + record={record} + data={cloneDeep(data)} + step={step} + config={formFieldConfig} + onValueSet={async (path, value, validation) => this.handleValueSet(formFieldIndex, path, value, validation)} + onValueUnset={async (path, validation) => this.handleValueUnset(formFieldIndex, path, validation)} + onValueListAppend={async (path, value, validation) => this.handleValueListAppend(formFieldIndex, path, value, validation)} + onValueListSplice={async (path, index, count, validation) => this.handleValueListSplice(formFieldIndex, path, index, count, validation)} + baseRoute={this.props.baseRoute} + loadDomain={async (domain: string) => await this.props.loadDomain(domain)} + /> + ) + } + // 渲染表单项容器 + return ( + hidden + ? this.renderItemComponent(renderData) + : + ) + }) + : [] + })} + + ) + } +} diff --git a/src/components/formFields/hidden/display.tsx b/src/components/formFields/hidden/display.tsx new file mode 100644 index 0000000..0ff145f --- /dev/null +++ b/src/components/formFields/hidden/display.tsx @@ -0,0 +1,5 @@ +import { HiddenFieldConfig } from '.' +import { Display } from '../common' + +export default class HiddenField extends Display { +} diff --git a/src/components/formFields/importSubform/display.tsx b/src/components/formFields/importSubform/display.tsx new file mode 100644 index 0000000..98e797e --- /dev/null +++ b/src/components/formFields/importSubform/display.tsx @@ -0,0 +1,272 @@ +import React from 'react' +import { getValue } from '../../../util/value' + +import { DetailField, DetailFieldConfig, DetailFieldProps, IDetailField } from '../../detail/common' +import { Display } from '../../formFields/common' +import { display as getALLComponents, FieldConfigs } from '../../formFields' +import { IDetailItem } from '../../../steps/detail' +import { cloneDeep, isEqual } from 'lodash' +import ConditionHelper from '../../../util/condition' +import InterfaceHelper, { InterfaceConfig } from '../../../util/interface' +/** + * 子表单配置项 + * - withConfig: 拓展配置 + * - * - enable: 是否开启 + * - * - dataField: (序列化)数据 + * - * - configField: (序列化)配置 + */ +export interface ImportSubformFieldConfig extends DetailFieldConfig { + type: 'import_subform', + configFrom?: ImportSubformConfigFromData | ImportSubformConfigFromInterface +} + +interface ImportSubformConfigFromData { + type: 'data' + dataField?: string + configField?: string +} + +interface ImportSubformConfigFromInterface { + type: 'interface' + interface?: InterfaceConfig +} + +export interface IImportSubformField { + children: React.ReactNode[] +} + +interface IImportSubformFieldState { + didMount: boolean + fields: FieldConfigs[] + formData: { status: 'normal' | 'error' | 'loading', message?: string }[] +} + +export default class ImportSubformFieldDisplay extends DetailField implements IDetailField { + // 各表单项对应的类型所使用的UI组件的类 + getALLComponents = (type: any): typeof Display => getALLComponents[type] + + // 用于请求防频的判断条件 + requestConfig: string = '' + value: string = '' + + formFields: Array | null> = [] + formFieldsMounted: Array = [] + + interfaceHelper = new InterfaceHelper() + + constructor (props: DetailFieldProps) { + super(props) + + this.state = { + didMount: false, + fields: [], + formData: [] + } + } + + getFullpath + (field: string, path: string = '') { + const withConfigPath = this.props.config.configFrom?.type === 'data' && this.props.config.configFrom.dataField ? `${this.props.config.configFrom.dataField}` : '' + const _fullPath = `${withConfigPath}.${field}.${path}.` + const fullPath = _fullPath.replace(/(^\.*)|(\.*$)|(\.){2,}/g, '$3') + return fullPath + } + + didMount = async () => { + await this.setState({ + didMount: true + }) + } + + set: (value: any) => Promise = async (value) => { + return value + }; + + handleMount = async (formFieldIndex: number) => { + if (this.formFieldsMounted[formFieldIndex]) { + return true + } + this.formFieldsMounted[formFieldIndex] = true + if (this.formFields[formFieldIndex]) { + const formField = this.formFields[formFieldIndex] + if (formField) { + const formFieldConfig = this.state.fields[formFieldIndex] + + let value = getValue(this.props.value, this.getFullpath(formFieldConfig.field)) + const source = value + if ((formFieldConfig.defaultValue) && value === undefined) { + value = await formField.reset() + } + value = await formField.set(value) + if (source !== value) { + this.props.onValueSet(this.getFullpath(formFieldConfig.field), value, true) + } + await formField.didMount() + } + } + } + + getConfigData= () => { + const { + config, + value + } = this.props + if (config.configFrom && config.configFrom.type === 'interface' && config.configFrom.interface) { + this.interfaceHelper.request( + config.configFrom.interface, + {}, + { record: this.props.record, data: this.props.data, step: this.props.step }, + { loadDomain: this.props.loadDomain } + ).then((data: any) => { + let dataToUnstringfy = data + let dataToStringfy = JSON.stringify(data) + if (Object.prototype.toString.call(data) === '[object String]') { + try { + dataToStringfy = data + dataToUnstringfy = JSON.parse(data) + } catch (e) { + console.error('当前动态子表单接口响应数据格式不是合格的json字符串') + dataToUnstringfy = [] + dataToStringfy = '[]' + } + } + if (dataToStringfy !== JSON.stringify(this.state.fields)) { + this.setState({ + fields: dataToUnstringfy + }) + } + }) + } + let fields = this.state.fields + if (config.configFrom && config.configFrom.type === 'data') { + fields = config.configFrom.configField ? getValue(value, config.configFrom.configField) : [] + if (!isEqual(fields, this.state.fields)) { + this.setState({ + fields + }) + } + } + } + + componentDidMount () { + this.getConfigData() + } + + handleValueSet = async (formFieldIndex: number, path: string, value: any) => { + const formFieldConfig = (this.state.fields || [])[formFieldIndex] + if (formFieldConfig) { + const fullPath = this.getFullpath(formFieldConfig.field, path) + await this.props.onValueSet(fullPath, value, true) + } + } + + handleValueUnset = async (formFieldIndex: number, path: string) => { + const formFieldConfig = (this.state.fields || [])[formFieldIndex] + if (formFieldConfig) { + const fullPath = this.getFullpath(formFieldConfig.field, path) + await this.props.onValueUnset(fullPath, true) + } + } + + handleValueListAppend = async (formFieldIndex: number, path: string, value: any) => { + const formFieldConfig = (this.state.fields || [])[formFieldIndex] + if (formFieldConfig) { + const fullPath = this.getFullpath(formFieldConfig.field, path) + await this.props.onValueListAppend(fullPath, value, true) + } + } + + handleValueListSplice = async (formFieldIndex: number, path: string, index: number, count: number) => { + const formFieldConfig = (this.state.fields || [])[formFieldIndex] + if (formFieldConfig) { + const fullPath = this.getFullpath(formFieldConfig.field, path) + await this.props.onValueListSplice(fullPath, index, count, true) + } + } + + renderComponent = (props: IImportSubformField) => { + return + 您当前使用的UI版本没有实现ImportSubformField组件。 + + } + + /** + * 表单项组件 - UI渲染方法 + * 各UI库需重写该方法 + * @param props + */ + renderItemComponent = (props: IDetailItem) => { + return + 您当前使用的UI版本没有实现FormItem组件。 + + } + + render = () => { + const { + config, + value, + record, + data, + step + } = this.props + const fields = this.state.fields + + if (!fields || !Array.isArray(fields) || fields.length === 0) { + return + } else { + return ( + + {this.renderComponent({ + children: this.state.didMount + ? fields.map((formFieldConfig, formFieldIndex) => { + if (!ConditionHelper(formFieldConfig.condition, { record: value, data, step })) { + this.formFieldsMounted[formFieldIndex] = false + return null + } + let display: boolean = true + + if (formFieldConfig.type === 'hidden' || formFieldConfig.display === 'none') { + display = false + } + + const FormField = this.getALLComponents(formFieldConfig.type) || Display + + const renderData: IDetailItem = { + key: formFieldIndex, + label: formFieldConfig.label, + visitable: display, + fieldType: formFieldConfig.type, + layout: 'horizontal' as 'horizontal', + children: ( + | null) => { + if (formField) { + this.formFields[formFieldIndex] = formField + this.handleMount(formFieldIndex) + } + }} + value={getValue(value, this.getFullpath(formFieldConfig.field))} + record={record} + data={cloneDeep(data)} + step={step} + config={formFieldConfig} + onValueSet={async (path, value) => this.handleValueSet(formFieldIndex, path, value)} + onValueUnset={async (path) => this.handleValueUnset(formFieldIndex, path)} + onValueListAppend={async (path, value) => this.handleValueListAppend(formFieldIndex, path, value)} + onValueListSplice={async (path, index, count) => this.handleValueListSplice(formFieldIndex, path, index, count)} + baseRoute={this.props.baseRoute} + loadDomain={async (domain: string) => await this.props.loadDomain(domain)} + /> + ) + } + // 渲染表单项容器 + return this.renderItemComponent(renderData) + }) + : [] + })} + + ) + } + } +} diff --git a/src/components/formFields/index.tsx b/src/components/formFields/index.tsx index e7735a6..3fbf89a 100644 --- a/src/components/formFields/index.tsx +++ b/src/components/formFields/index.tsx @@ -25,6 +25,7 @@ import MultipleTextField, { MultipleTextFieldConfig } from './multipleText' import CustomField, { CustomFieldConfig } from './custom' import TextDisplay from './text/display' +import FormDisplay from './form/display' import RadioDisplay from './radio/display' import ColorDisplay from './color/display' import UploadDisplay from './upload/display' @@ -34,8 +35,12 @@ import DatetimeDisplay from './datetime/display' import DatetimeRangeDisplay from './datetimeRange/display' import SelectSingleDisplay from './select/single/display' import SelectMultipleDisplay from './select/multiple/display' +import ImportSubformDisplay from './importSubform/display' +import GroupDisplay from './group/display' import SwitchDisplay from './switch/display' +import TabsDisplay from './tabs/display' import MultipleTextDisplay from './multipleText/display' +import HiddenDisplay from './hidden/display' export interface HiddenFieldConfig extends FieldConfig { type: 'hidden' | 'none' @@ -124,14 +129,19 @@ export default { export const display = { text: TextDisplay, longtext: LongtextDisplay, + form: FormDisplay, radio: RadioDisplay, color: ColorDisplay, upload: UploadDisplay, + import_subform: ImportSubformDisplay, + group: GroupDisplay, number: NumberDisplay, datetime: DatetimeDisplay, datetimeRange: DatetimeRangeDisplay, select_single: SelectSingleDisplay, select_multiple: SelectMultipleDisplay, switch: SwitchDisplay, - multiple_text: MultipleTextDisplay + tabs: TabsDisplay, + multiple_text: MultipleTextDisplay, + hidden: HiddenDisplay } diff --git a/src/components/formFields/tabs/display.tsx b/src/components/formFields/tabs/display.tsx new file mode 100644 index 0000000..c7ba0d4 --- /dev/null +++ b/src/components/formFields/tabs/display.tsx @@ -0,0 +1,362 @@ +import React from 'react' +import { display as getALLComponents } from '../' +import { TabsFieldConfig, TabsFieldState } from '.' +import { Display, FieldConfigs, DisplayProps, FieldError } from '../common' +import ConditionHelper from '../../../util/condition' +import { getValue, setValue, getBoolean } from '../../../util/value' +import { cloneDeep } from 'lodash' + +export interface ITabsField { + children: React.ReactNode[] +} + +export interface ITabsFieldItem { + key: string + label: string + children: React.ReactNode[] +} + +export interface ITabsFieldItemField { + index: number + label: string + required: boolean + status: 'normal' | 'error' | 'loading' + description?: string + message?: string + extra?: string + fieldType: string + children: React.ReactNode +} + +export default class TabsField extends Display> { + // 各表单项对应的类型所使用的UI组件的类 + getALLComponents = (type: any): typeof Display => getALLComponents[type] + + formFieldsList: Array | null>> = [] + formFieldsMountedList: Array> = [] + + constructor (props: DisplayProps) { + super(props) + + this.state = { + didMount: false, + formDataList: [] + } + } + + didMount = async () => { + await this.setState({ + didMount: true + }) + } + + get = async () => { + let data: any = {} + + for (let index = 0; index < (this.props.config.tabs || []).length; index++) { + const tab = (this.props.config.tabs || [])[index] + const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) + + for (let formFieldIndex = 0; formFieldIndex < fields.length; formFieldIndex++) { + const formFieldConfig = fields[formFieldIndex] + if (!ConditionHelper(formFieldConfig.condition, { record: getValue(this.props.value, tab.field), data: this.props.data, step: this.props.step })) { + continue + } + const formField = this.formFieldsList[index] && this.formFieldsList[index][formFieldIndex] + if (formField) { + const value = await formField.get() + const fullPath = tab.field === '' || formFieldConfig.field === '' ? `${tab.field}${formFieldConfig.field}` : `${tab.field}.${formFieldConfig.field}` + data = setValue(data, fullPath, value) + } + } + } + + return data + } + + handleMount = async (index: number, formFieldIndex: number) => { + if (!this.formFieldsMountedList[index]) { + this.formFieldsMountedList[index] = [] + } + if (this.formFieldsMountedList[index][formFieldIndex]) { + return true + } + this.formFieldsMountedList[index][formFieldIndex] = true + + const tab = (this.props.config.tabs || [])[index] + + if (this.formFieldsList[index] && this.formFieldsList[index][formFieldIndex]) { + const formField = this.formFieldsList[index][formFieldIndex] + if (formField) { + const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) + const formFieldConfig = fields[formFieldIndex] + + const fullPath = tab.field === '' || formFieldConfig.field === '' ? `${tab.field}${formFieldConfig.field}` : `${tab.field}.${formFieldConfig.field}` + + let value = getValue(this.props.value, fullPath) + const source = value + if ((formFieldConfig.defaultValue) && value === undefined) { + value = await formField.reset() + } + value = await formField.set(value) + if (source !== value) { + this.props.onValueSet(fullPath, value, true) + } + + if (value !== undefined) { + this.setState(({ formDataList }) => { + if (!formDataList[index]) formDataList[index] = [] + formDataList[index][formFieldIndex] = { status: 'normal' } + return { formDataList: cloneDeep(formDataList) } + }) + } + await formField.didMount() + } + } + } + + handleChange = async (index: number, formFieldIndex: number, value: any) => { + } + + handleValueSet = async (index: number, formFieldIndex: number, path: string, value: any, validation: true | FieldError[]) => { + const tab = (this.props.config.tabs || [])[index] + + const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) + const formFieldConfig = fields[formFieldIndex] + if (formFieldConfig) { + const fieldPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + const fullPath = tab.field === '' || fieldPath === '' ? `${tab.field}${fieldPath}` : `${tab.field}.${fieldPath}` + await this.props.onValueSet(fullPath, value, true) + + const formDataList = cloneDeep(this.state.formDataList) + if (!formDataList[index]) formDataList[index] = [] + if (validation === true) { + formDataList[index][formFieldIndex] = { status: 'normal' } + } else { + formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } + } + + this.setState({ + formDataList + }) + } + } + + handleValueUnset = async (index: number, formFieldIndex: number, path: string, validation: true | FieldError[]) => { + const tab = (this.props.config.tabs || [])[index] + + const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) + const formFieldConfig = fields[formFieldIndex] + if (formFieldConfig) { + const fieldPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + const fullPath = tab.field === '' || fieldPath === '' ? `${tab.field}${fieldPath}` : `${tab.field}.${fieldPath}` + await this.props.onValueUnset(fullPath, true) + + const formDataList = cloneDeep(this.state.formDataList) + if (!formDataList[index]) formDataList[index] = [] + if (validation === true) { + formDataList[index][formFieldIndex] = { status: 'normal' } + } else { + formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } + } + + this.setState({ + formDataList + }) + } + } + + handleValueListAppend = async (index: number, formFieldIndex: number, path: string, value: any, validation: true | FieldError[]) => { + const tab = (this.props.config.tabs || [])[index] + + const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) + const formFieldConfig = fields[formFieldIndex] + if (formFieldConfig) { + const fieldPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + const fullPath = tab.field === '' || fieldPath === '' ? `${tab.field}${fieldPath}` : `${tab.field}.${fieldPath}` + await this.props.onValueListAppend(fullPath, value, true) + + const formDataList = cloneDeep(this.state.formDataList) + if (!formDataList[index]) formDataList[index] = [] + if (validation === true) { + formDataList[index][formFieldIndex] = { status: 'normal' } + } else { + formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } + } + + this.setState({ + formDataList + }) + } + } + + handleValueListSplice = async (index: number, formFieldIndex: number, path: string, _index: number, count: number, validation: true | FieldError[]) => { + const tab = (this.props.config.tabs || [])[index] + + const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) + const formFieldConfig = fields[formFieldIndex] + if (formFieldConfig) { + const fieldPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + const fullPath = tab.field === '' || fieldPath === '' ? `${tab.field}${fieldPath}` : `${tab.field}.${fieldPath}` + await this.props.onValueListSplice(fullPath, _index, count, true) + + const formDataList = cloneDeep(this.state.formDataList) + if (!formDataList[index]) formDataList[index] = [] + if (validation === true) { + formDataList[index][formFieldIndex] = { status: 'normal' } + } else { + formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } + } + + this.setState({ + formDataList + }) + } + } + + handleValueListSort = async (index: number, formFieldIndex: number, path: string, _index: number, sortType: 'up' | 'down', validation: true | FieldError[]) => { + const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) + const formFieldConfig = fields[formFieldIndex] + if (formFieldConfig) { + const formDataList = cloneDeep(this.state.formDataList) + if (!formDataList[index]) formDataList[index] = [] + if (validation === true) { + formDataList[index][formFieldIndex] = { status: 'normal' } + } else { + formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } + } + + this.setState({ + formDataList + }) + } + } + + /** + * 用于展示子表单组件 + * @param _props + * @returns + */ + renderComponent = (_props: ITabsField) => { + return + 您当前使用的UI版本没有实现FormField组件。 + + } + + /** + * 用于展示子表单组件中的每一个子项 + * @param props + * @returns + */ + renderItemComponent = (props: ITabsFieldItem) => { + return + 您当前使用的UI版本没有实现FormField组件的renderItemComponent方法。 + + } + + /** + * 用于展示子表单组件中的每一子项中的每一个子表单项组件 + * @param props + * @returns + */ + renderItemFieldComponent = (props: ITabsFieldItemField) => { + return + 您当前使用的UI版本没有实现FormField组件的renderItemFieldComponent方法。 + + } + + render = () => { + const { + value = {} + } = this.props + + return ( + + { + this.renderComponent({ + children: ( + this.state.didMount + ? (this.props.config.tabs || []).map((tab: any, index: number) => { + const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) + return ( + + {this.renderItemComponent({ + key: index.toString(), + label: tab.label, + children: fields.map((formFieldConfig, formFieldIndex) => { + if (!ConditionHelper(formFieldConfig.condition, { record: this.props.record, data: this.props.data, step: this.props.step })) { + if (!this.formFieldsMountedList[index]) this.formFieldsMountedList[index] = [] + this.formFieldsMountedList[index][formFieldIndex] = false + return null + } + let hidden: boolean = true + let display: boolean = true + + if (formFieldConfig.type === 'hidden') { + hidden = true + display = false + } + + if (formFieldConfig.display === 'none') { + hidden = true + display = false + } + + const FormField = this.getALLComponents(formFieldConfig.type) || Display + + let status = ((this.state.formDataList[index] || [])[formFieldIndex] || {}).status || 'normal' + + if (['group', 'import_subform', 'object', 'tabs', 'form'].some((type) => type === formFieldConfig.type)) { + status = 'normal' + } + // 渲染表单项容器 + if (hidden) { + return ( +
+ {this.renderItemFieldComponent({ + index: formFieldIndex, + label: formFieldConfig.label, + status, + message: ((this.state.formDataList[index] || [])[formFieldIndex] || {}).message || '', + required: getBoolean(formFieldConfig.required), + fieldType: formFieldConfig.type, + children: ( + | null) => { + if (!this.formFieldsList[index]) this.formFieldsList[index] = [] + this.formFieldsList[index][formFieldIndex] = formField + this.handleMount(index, formFieldIndex) + }} + value={getValue(getValue(value, tab.field), formFieldConfig.field)} + record={getValue(value, tab.field)} + data={cloneDeep(this.props.data)} + step={this.props.step} + config={formFieldConfig} + onValueSet={async (path, value, validation) => this.handleValueSet(index, formFieldIndex, path, value, validation)} + onValueUnset={async (path, validation) => this.handleValueUnset(index, formFieldIndex, path, validation)} + onValueListAppend={async (path, value, validation) => this.handleValueListAppend(index, formFieldIndex, path, value, validation)} + onValueListSplice={async (path, _index, count, validation) => this.handleValueListSplice(index, formFieldIndex, path, _index, count, validation)} + baseRoute={this.props.baseRoute} + loadDomain={async (domain: string) => await this.props.loadDomain(domain)} + /> + ) + })} +
+ ) + } else { + return + } + }) + })} + + ) + }) + : [] + ) + }) + } +
+ ) + } +} diff --git a/src/index.tsx b/src/index.tsx index c8abdd5..d911d62 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -28,6 +28,7 @@ export { default as MultipleTextField } from './components/formFields/multipleTe export { default as CustomField } from './components/formFields/custom' export { default as TextDisplay } from './components/formFields/text/display' +export { default as FormDisplay } from './components/formFields/form/display' export { default as LongTextDisplay } from './components/formFields/longtext/display' export { default as RadioDisplay } from './components/formFields/radio/display' export { default as ColorDisplay } from './components/formFields/color/display' @@ -38,7 +39,11 @@ export { default as DatetimeDisplay } from './components/formFields/datetime/dis export { default as DatetimeRangeDisplay } from './components/formFields/datetimeRange/display' export { default as SelectSingleDisplay } from './components/formFields/select/single/display' export { default as SelectMultipleDisplay } from './components/formFields/select/multiple/display' +export { default as ImportSubformDisplay } from './components/formFields/importSubform/display' +export { default as GroupDisplay } from './components/formFields/group/display' +export { default as TabsDisplay } from './components/formFields/tabs/display' export { default as MultipleTextDisplay } from './components/formFields/multipleText/display' +export { default as HiddenDisplay } from './components/formFields/hidden/display' export { default as TableStep } from './steps/table' export { default as TextColumn } from './components/tableColumns/text' -- Gitee From 4c42a15d5a18809d2369079673767a839405ed6b Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Tue, 19 Apr 2022 18:01:49 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=E7=BB=93=E5=90=88noPathCombination?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=A1=A8=E5=8D=95=E9=A1=B9form=E4=B8=8Bdispl?= =?UTF-8?q?ay=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/form/display.tsx | 100 ++++----------------- 1 file changed, 19 insertions(+), 81 deletions(-) diff --git a/src/components/formFields/form/display.tsx b/src/components/formFields/form/display.tsx index f6a861a..0999d80 100644 --- a/src/components/formFields/form/display.tsx +++ b/src/components/formFields/form/display.tsx @@ -1,7 +1,7 @@ import React from 'react' import { display as getALLComponents } from '../' import { FormFieldConfig } from '.' -import { Display, FieldConfigs, FieldError, FieldProps } from '../common' +import { Display, FieldConfigs, DisplayProps } from '../common' import { getValue, setValue } from '../../../util/value' import { cloneDeep } from 'lodash' import ConditionHelper from '../../../util/condition' @@ -27,7 +27,6 @@ export interface IFormFieldItemField { interface FormState { didMount: boolean - formDataList: { status: 'normal' | 'error' | 'loading', message?: string }[][] showItem: boolean showIndex: number } @@ -38,12 +37,11 @@ export default class FormField extends Display | null>> = [] formFieldsMountedList: Array> = [] - constructor (props: FieldProps) { + constructor (props: DisplayProps) { super(props) this.state = { didMount: false, - formDataList: [], showItem: false, showIndex: 0 } @@ -116,9 +114,6 @@ export default class FormField extends Display { + handleValueSet = async (index: number, formFieldIndex: number, path: string, value: any, options?: { noPathCombination?: boolean }) => { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - await this.props.onValueSet(`[${index}]${fullPath}`, value, true) - - const formDataList = cloneDeep(this.state.formDataList) - if (validation === true) { - formDataList[index][formFieldIndex] = { status: 'normal' } - } else { - formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } - } - - this.setState({ - formDataList - }) + const fullPath = options && options.noPathCombination ? path : (formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}`) + await this.props.onValueSet(`[${index}]${fullPath}`, value) } } - handleValueUnset = async (index: number, formFieldIndex: number, path: string, validation: true | FieldError[]) => { + handleValueUnset = async (index: number, formFieldIndex: number, path: string, options?: { noPathCombination?: boolean }) => { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - await this.props.onValueUnset(`[${index}]${fullPath}`, true) - - const formDataList = cloneDeep(this.state.formDataList) - if (validation === true) { - formDataList[index][formFieldIndex] = { status: 'normal' } - } else { - formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } - } - - this.setState({ - formDataList - }) + const fullPath = options && options.noPathCombination ? path : (formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}`) + await this.props.onValueUnset(`[${index}]${fullPath}`) } } - handleValueListAppend = async (index: number, formFieldIndex: number, path: string, value: any, validation: true | FieldError[]) => { + handleValueListAppend = async (index: number, formFieldIndex: number, path: string, value: any, options?: { noPathCombination?: boolean }) => { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - await this.props.onValueListAppend(`[${index}]${fullPath}`, value, true) - - const formDataList = cloneDeep(this.state.formDataList) - if (validation === true) { - formDataList[index][formFieldIndex] = { status: 'normal' } - } else { - formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } - } - - this.setState({ - formDataList - }) + const fullPath = options && options.noPathCombination ? path : (formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}`) + await this.props.onValueListAppend(`[${index}]${fullPath}`, value) } } - handleValueListSplice = async (index: number, formFieldIndex: number, path: string, _index: number, count: number, validation: true | FieldError[]) => { + handleValueListSplice = async (index: number, formFieldIndex: number, path: string, _index: number, count: number, options?: { noPathCombination?: boolean }) => { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - await this.props.onValueListSplice(`[${index}]${fullPath}`, _index, count, true) - - const formDataList = cloneDeep(this.state.formDataList) - if (validation === true) { - formDataList[index][formFieldIndex] = { status: 'normal' } - } else { - formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } - } - - this.setState({ - formDataList - }) + const fullPath = options && options.noPathCombination ? path : (formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}`) + await this.props.onValueListSplice(`[${index}]${fullPath}`, _index, count) } } @@ -289,11 +232,6 @@ export default class FormField extends Display type === formFieldConfig.type)) { - status = 'normal' - } // 渲染表单项容器 return (
@@ -316,10 +254,10 @@ export default class FormField extends Display this.handleValueSet(index, fieldIndex, path, value, validation)} - onValueUnset={async (path, validation) => this.handleValueUnset(index, fieldIndex, path, validation)} - onValueListAppend={async (path, value, validation) => this.handleValueListAppend(index, fieldIndex, path, value, validation)} - onValueListSplice={async (path, _index, count, validation) => this.handleValueListSplice(index, fieldIndex, path, _index, count, validation)} + onValueSet={async (path, value, options) => this.handleValueSet(index, fieldIndex, path, value, options)} + onValueUnset={async (path, options) => this.handleValueUnset(index, fieldIndex, path, options)} + onValueListAppend={async (path, value, options) => this.handleValueListAppend(index, fieldIndex, path, value, options)} + onValueListSplice={async (path, _index, count, options) => this.handleValueListSplice(index, fieldIndex, path, _index, count, options)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} /> -- Gitee From 53e4689253c99218b2fe3b5b7b90503ef659b6e7 Mon Sep 17 00:00:00 2001 From: zjt Date: Tue, 19 Apr 2022 20:26:14 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=E7=BB=93=E5=90=88noPathCombination?= =?UTF-8?q?=E4=BF=AE=E6=94=B9display?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/group/display.tsx | 218 ++++------ .../formFields/importSubform/display.tsx | 18 +- src/components/formFields/tabs/display.tsx | 379 +++++++----------- 3 files changed, 235 insertions(+), 380 deletions(-) diff --git a/src/components/formFields/group/display.tsx b/src/components/formFields/group/display.tsx index fc9a131..48f71a3 100644 --- a/src/components/formFields/group/display.tsx +++ b/src/components/formFields/group/display.tsx @@ -2,7 +2,7 @@ import React from 'react' import { display as getALLComponents, FieldConfigs } from '../' import { GroupFieldConfig, IGroupField } from '.' import { setValue, getValue, getBoolean } from '../../../util/value' -import { Display, FieldError, FieldProps } from '../common' +import { Display, DisplayProps } from '../common' import { IFormItem } from '../../../steps/form' import { cloneDeep } from 'lodash' import ConditionHelper from '../../../util/condition' @@ -10,7 +10,6 @@ import StatementHelper from '../../../util/statement' interface IGroupFieldState { didMount: boolean - formData: { status: 'normal' | 'error' | 'loading', message?: string, name?: string }[] } export default class GroupField extends Display { @@ -20,12 +19,11 @@ export default class GroupField extends Display | null> = [] formFieldsMounted: Array = [] - constructor (props: FieldProps) { + constructor(props: DisplayProps) { super(props) this.state = { - didMount: false, - formData: [] + didMount: false } } @@ -72,105 +70,43 @@ export default class GroupField extends Display { - formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } - return { formData: cloneDeep(formData) } - }) - } await formField.didMount() } } } - handleValueSet = async (formFieldIndex: number, path: string, value: any, validation: true | FieldError[]) => { + handleValueSet = async (formFieldIndex: number, path: string, value: any, options?: { noPathCombination?: boolean }) => { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - await this.props.onValueSet(fullPath, value, true) - const formData = cloneDeep(this.state.formData) - if (validation === true) { - formData[formFieldIndex] = { status: 'normal' } - } else { - formData[formFieldIndex] = { status: 'error', message: validation[0].message } - } - - this.setState({ - formData - }) + const fullPath = options && options.noPathCombination ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + await this.props.onValueSet(fullPath, value) } } - handleValueUnset = async (formFieldIndex: number, path: string, validation: true | FieldError[]) => { + handleValueUnset = async (formFieldIndex: number, path: string, options?: { noPathCombination?: boolean }) => { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - await this.props.onValueUnset(fullPath, true) - const formData = cloneDeep(this.state.formData) - if (validation === true) { - formData[formFieldIndex] = { status: 'normal' } - } else { - formData[formFieldIndex] = { status: 'error', message: validation[0].message } - } - - this.setState({ - formData - }) - } - } - - handleValueListAppend = async (formFieldIndex: number, path: string, value: any, validation: true | FieldError[]) => { - const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] - if (formFieldConfig) { - const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - await this.props.onValueListAppend(fullPath, value, true) - const formData = cloneDeep(this.state.formData) - if (validation === true) { - formData[formFieldIndex] = { status: 'normal' } - } else { - formData[formFieldIndex] = { status: 'error', message: validation[0].message } - } - - this.setState({ - formData - }) + const fullPath = options && options.noPathCombination ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + await this.props.onValueUnset(fullPath) } } - handleValueListSplice = async (formFieldIndex: number, path: string, index: number, count: number, validation: true | FieldError[]) => { + handleValueListAppend = async (formFieldIndex: number, path: string, value: any, options?: { noPathCombination?: boolean }) => { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - await this.props.onValueListSplice(fullPath, index, count, true) - const formData = cloneDeep(this.state.formData) - if (validation === true) { - formData[formFieldIndex] = { status: 'normal' } - } else { - formData[formFieldIndex] = { status: 'error', message: validation[0].message } - } - - this.setState({ - formData - }) + const fullPath = options && options.noPathCombination ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + await this.props.onValueListAppend(fullPath, value) } } - handleValueListSort = async (formFieldIndex: number, path: string, index: number, sortType: 'up' | 'down', validation: true | FieldError[]) => { + handleValueListSplice = async (formFieldIndex: number, path: string, index: number, count: number, options?: { noPathCombination?: boolean }) => { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] if (formFieldConfig) { - const formData = cloneDeep(this.state.formData) - if (validation === true) { - formData[formFieldIndex] = { status: 'normal' } - } else { - formData[formFieldIndex] = { status: 'error', message: validation[0].message } - } - - this.setState({ - formData - }) + const fullPath = options && options.noPathCombination ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + await this.props.onValueListSplice(fullPath, index, count) } } @@ -204,71 +140,65 @@ export default class GroupField extends Display { - if (!ConditionHelper(formFieldConfig.condition, { record: value, data: this.props.data, step: this.props.step })) { - this.formFieldsMounted[formFieldIndex] = false - return null - } - let hidden: boolean = true - let display: boolean = true - - if (formFieldConfig.type === 'hidden') { - hidden = true - display = false - } - - if (formFieldConfig.display === 'none') { - hidden = true - display = false - } - - const FormField = this.getALLComponents(formFieldConfig.type) || Display - - let status = (this.state.formData[formFieldIndex] || {}).status || 'normal' - - if (['group', 'import_subform', 'object', 'tabs', 'form'].some((type) => type === formFieldConfig.type)) { - status = 'normal' - } - - const renderData = { - key: formFieldIndex, - label: formFieldConfig.label, - status, - layout: 'horizontal' as 'horizontal', - message: (this.state.formData[formFieldIndex] || {}).message || '', - extra: StatementHelper(formFieldConfig.extra, { record: this.props.record, data: this.props.data, step: this.props.step }), - required: getBoolean(formFieldConfig.required), - visitable: display, - fieldType: formFieldConfig.type, - children: ( - | null) => { - if (formField) { - this.formFields[formFieldIndex] = formField - this.handleMount(formFieldIndex) - } - }} - value={getValue(value, formFieldConfig.field)} - record={record} - data={cloneDeep(data)} - step={step} - config={formFieldConfig} - onValueSet={async (path, value, validation) => this.handleValueSet(formFieldIndex, path, value, validation)} - onValueUnset={async (path, validation) => this.handleValueUnset(formFieldIndex, path, validation)} - onValueListAppend={async (path, value, validation) => this.handleValueListAppend(formFieldIndex, path, value, validation)} - onValueListSplice={async (path, index, count, validation) => this.handleValueListSplice(formFieldIndex, path, index, count, validation)} - baseRoute={this.props.baseRoute} - loadDomain={async (domain: string) => await this.props.loadDomain(domain)} - /> - ) - } - // 渲染表单项容器 - return ( - hidden - ? this.renderItemComponent(renderData) - : + if (!ConditionHelper(formFieldConfig.condition, { record: value, data: this.props.data, step: this.props.step })) { + this.formFieldsMounted[formFieldIndex] = false + return null + } + let hidden: boolean = true + let display: boolean = true + + if (formFieldConfig.type === 'hidden') { + hidden = true + display = false + } + + if (formFieldConfig.display === 'none') { + hidden = true + display = false + } + + const FormField = this.getALLComponents(formFieldConfig.type) || Display + + let status: 'normal' = 'normal' + const renderData = { + key: formFieldIndex, + label: formFieldConfig.label, + status, + layout: 'horizontal' as 'horizontal', + extra: StatementHelper(formFieldConfig.extra, { record: this.props.record, data: this.props.data, step: this.props.step }), + required: getBoolean(formFieldConfig.required), + visitable: display, + fieldType: formFieldConfig.type, + children: ( + | null) => { + if (formField) { + this.formFields[formFieldIndex] = formField + this.handleMount(formFieldIndex) + } + }} + value={getValue(value, formFieldConfig.field)} + record={record} + data={cloneDeep(data)} + step={step} + config={formFieldConfig} + onValueSet={async (path, value, options) => this.handleValueSet(formFieldIndex, path, value, options)} + onValueUnset={async (path, options) => this.handleValueUnset(formFieldIndex, path, options)} + onValueListAppend={async (path, value, options) => this.handleValueListAppend(formFieldIndex, path, value, options)} + onValueListSplice={async (path, index, count, options) => this.handleValueListSplice(formFieldIndex, path, index, count, options)} + baseRoute={this.props.baseRoute} + loadDomain={async (domain: string) => await this.props.loadDomain(domain)} + /> ) - }) + } + // 渲染表单项容器 + return ( + hidden + ? this.renderItemComponent(renderData) + : + ) + }) : [] })} diff --git a/src/components/formFields/importSubform/display.tsx b/src/components/formFields/importSubform/display.tsx index 98e797e..52b90e5 100644 --- a/src/components/formFields/importSubform/display.tsx +++ b/src/components/formFields/importSubform/display.tsx @@ -54,7 +54,7 @@ export default class ImportSubformFieldDisplay extends DetailField) { + constructor(props: DetailFieldProps) { super(props) this.state = { @@ -65,7 +65,7 @@ export default class ImportSubformFieldDisplay extends DetailField { + getConfigData = () => { const { config, value @@ -148,7 +148,7 @@ export default class ImportSubformFieldDisplay extends DetailField { + didMount: boolean + extra?: S +} export default class TabsField extends Display> { - // 各表单项对应的类型所使用的UI组件的类 - getALLComponents = (type: any): typeof Display => getALLComponents[type] + // 各表单项对应的类型所使用的UI组件的类 + getALLComponents = (type: any): typeof Display => getALLComponents[type] - formFieldsList: Array | null>> = [] - formFieldsMountedList: Array> = [] + formFieldsList: Array | null>> = [] + formFieldsMountedList: Array> = [] - constructor (props: DisplayProps) { - super(props) + constructor(props: DisplayProps) { + super(props) - this.state = { - didMount: false, - formDataList: [] - } - } + this.state = { + didMount: false + } + } + + didMount = async () => { + await this.setState({ + didMount: true + }) + } - didMount = async () => { - await this.setState({ - didMount: true - }) + get = async () => { + let data: any = {} + + for (let index = 0; index < (this.props.config.tabs || []).length; index++) { + const tab = (this.props.config.tabs || [])[index] + const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) + + for (let formFieldIndex = 0; formFieldIndex < fields.length; formFieldIndex++) { + const formFieldConfig = fields[formFieldIndex] + if (!ConditionHelper(formFieldConfig.condition, { record: getValue(this.props.value, tab.field), data: this.props.data, step: this.props.step })) { + continue + } + const formField = this.formFieldsList[index] && this.formFieldsList[index][formFieldIndex] + if (formField) { + const value = await formField.get() + const fullPath = tab.field === '' || formFieldConfig.field === '' ? `${tab.field}${formFieldConfig.field}` : `${tab.field}.${formFieldConfig.field}` + data = setValue(data, fullPath, value) + } + } } - get = async () => { - let data: any = {} - - for (let index = 0; index < (this.props.config.tabs || []).length; index++) { - const tab = (this.props.config.tabs || [])[index] - const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) - - for (let formFieldIndex = 0; formFieldIndex < fields.length; formFieldIndex++) { - const formFieldConfig = fields[formFieldIndex] - if (!ConditionHelper(formFieldConfig.condition, { record: getValue(this.props.value, tab.field), data: this.props.data, step: this.props.step })) { - continue - } - const formField = this.formFieldsList[index] && this.formFieldsList[index][formFieldIndex] - if (formField) { - const value = await formField.get() - const fullPath = tab.field === '' || formFieldConfig.field === '' ? `${tab.field}${formFieldConfig.field}` : `${tab.field}.${formFieldConfig.field}` - data = setValue(data, fullPath, value) - } - } - } - - return data - } + return data + } handleMount = async (index: number, formFieldIndex: number) => { if (!this.formFieldsMountedList[index]) { @@ -100,16 +103,9 @@ export default class TabsField extends Display { - if (!formDataList[index]) formDataList[index] = [] - formDataList[index][formFieldIndex] = { status: 'normal' } - return { formDataList: cloneDeep(formDataList) } - }) - } await formField.didMount() } } @@ -118,152 +114,86 @@ export default class TabsField extends Display { } - handleValueSet = async (index: number, formFieldIndex: number, path: string, value: any, validation: true | FieldError[]) => { + handleValueSet = async (index: number, formFieldIndex: number, path: string, value: any, options?: { noPathCombination?: boolean }) => { const tab = (this.props.config.tabs || [])[index] const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) const formFieldConfig = fields[formFieldIndex] if (formFieldConfig) { - const fieldPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + const fieldPath = options && options.noPathCombination ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` const fullPath = tab.field === '' || fieldPath === '' ? `${tab.field}${fieldPath}` : `${tab.field}.${fieldPath}` - await this.props.onValueSet(fullPath, value, true) - - const formDataList = cloneDeep(this.state.formDataList) - if (!formDataList[index]) formDataList[index] = [] - if (validation === true) { - formDataList[index][formFieldIndex] = { status: 'normal' } - } else { - formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } - } - - this.setState({ - formDataList - }) + await this.props.onValueSet(fullPath, value) } } - handleValueUnset = async (index: number, formFieldIndex: number, path: string, validation: true | FieldError[]) => { + handleValueUnset = async (index: number, formFieldIndex: number, path: string, options?: { noPathCombination?: boolean }) => { const tab = (this.props.config.tabs || [])[index] const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) const formFieldConfig = fields[formFieldIndex] if (formFieldConfig) { - const fieldPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + const fieldPath = options && options.noPathCombination ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` const fullPath = tab.field === '' || fieldPath === '' ? `${tab.field}${fieldPath}` : `${tab.field}.${fieldPath}` - await this.props.onValueUnset(fullPath, true) - - const formDataList = cloneDeep(this.state.formDataList) - if (!formDataList[index]) formDataList[index] = [] - if (validation === true) { - formDataList[index][formFieldIndex] = { status: 'normal' } - } else { - formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } - } - - this.setState({ - formDataList - }) + await this.props.onValueUnset(fullPath) } } - handleValueListAppend = async (index: number, formFieldIndex: number, path: string, value: any, validation: true | FieldError[]) => { + handleValueListAppend = async (index: number, formFieldIndex: number, path: string, value: any, options?: { noPathCombination?: boolean }) => { const tab = (this.props.config.tabs || [])[index] const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) const formFieldConfig = fields[formFieldIndex] if (formFieldConfig) { - const fieldPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + const fieldPath = options && options.noPathCombination ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` const fullPath = tab.field === '' || fieldPath === '' ? `${tab.field}${fieldPath}` : `${tab.field}.${fieldPath}` - await this.props.onValueListAppend(fullPath, value, true) - - const formDataList = cloneDeep(this.state.formDataList) - if (!formDataList[index]) formDataList[index] = [] - if (validation === true) { - formDataList[index][formFieldIndex] = { status: 'normal' } - } else { - formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } - } - - this.setState({ - formDataList - }) + await this.props.onValueListAppend(fullPath, value) } } - handleValueListSplice = async (index: number, formFieldIndex: number, path: string, _index: number, count: number, validation: true | FieldError[]) => { + handleValueListSplice = async (index: number, formFieldIndex: number, path: string, _index: number, count: number, options?: { noPathCombination?: boolean }) => { const tab = (this.props.config.tabs || [])[index] const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) const formFieldConfig = fields[formFieldIndex] if (formFieldConfig) { - const fieldPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` + const fieldPath = options && options.noPathCombination ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` const fullPath = tab.field === '' || fieldPath === '' ? `${tab.field}${fieldPath}` : `${tab.field}.${fieldPath}` - await this.props.onValueListSplice(fullPath, _index, count, true) - - const formDataList = cloneDeep(this.state.formDataList) - if (!formDataList[index]) formDataList[index] = [] - if (validation === true) { - formDataList[index][formFieldIndex] = { status: 'normal' } - } else { - formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } - } - - this.setState({ - formDataList - }) + await this.props.onValueListSplice(fullPath, _index, count) } } - handleValueListSort = async (index: number, formFieldIndex: number, path: string, _index: number, sortType: 'up' | 'down', validation: true | FieldError[]) => { - const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) - const formFieldConfig = fields[formFieldIndex] - if (formFieldConfig) { - const formDataList = cloneDeep(this.state.formDataList) - if (!formDataList[index]) formDataList[index] = [] - if (validation === true) { - formDataList[index][formFieldIndex] = { status: 'normal' } - } else { - formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } - } - - this.setState({ - formDataList - }) - } - } - - /** - * 用于展示子表单组件 - * @param _props - * @returns - */ - renderComponent = (_props: ITabsField) => { - return + /** + * 用于展示子表单组件 + * @param _props + * @returns + */ + renderComponent = (_props: ITabsField) => { + return 您当前使用的UI版本没有实现FormField组件。 - } - - /** - * 用于展示子表单组件中的每一个子项 - * @param props - * @returns - */ - renderItemComponent = (props: ITabsFieldItem) => { - return + } + + /** + * 用于展示子表单组件中的每一个子项 + * @param props + * @returns + */ + renderItemComponent = (props: ITabsFieldItem) => { + return 您当前使用的UI版本没有实现FormField组件的renderItemComponent方法。 - } - - /** - * 用于展示子表单组件中的每一子项中的每一个子表单项组件 - * @param props - * @returns - */ - renderItemFieldComponent = (props: ITabsFieldItemField) => { - return + } + + /** + * 用于展示子表单组件中的每一子项中的每一个子表单项组件 + * @param props + * @returns + */ + renderItemFieldComponent = (props: ITabsFieldItemField) => { + return 您当前使用的UI版本没有实现FormField组件的renderItemFieldComponent方法。 - } + } render = () => { const { @@ -277,81 +207,76 @@ export default class TabsField extends Display { - const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) - return ( - - {this.renderItemComponent({ - key: index.toString(), - label: tab.label, - children: fields.map((formFieldConfig, formFieldIndex) => { - if (!ConditionHelper(formFieldConfig.condition, { record: this.props.record, data: this.props.data, step: this.props.step })) { - if (!this.formFieldsMountedList[index]) this.formFieldsMountedList[index] = [] - this.formFieldsMountedList[index][formFieldIndex] = false - return null - } - let hidden: boolean = true - let display: boolean = true - - if (formFieldConfig.type === 'hidden') { - hidden = true - display = false - } - - if (formFieldConfig.display === 'none') { - hidden = true - display = false - } - - const FormField = this.getALLComponents(formFieldConfig.type) || Display - - let status = ((this.state.formDataList[index] || [])[formFieldIndex] || {}).status || 'normal' - - if (['group', 'import_subform', 'object', 'tabs', 'form'].some((type) => type === formFieldConfig.type)) { - status = 'normal' - } - // 渲染表单项容器 - if (hidden) { - return ( -
- {this.renderItemFieldComponent({ - index: formFieldIndex, - label: formFieldConfig.label, - status, - message: ((this.state.formDataList[index] || [])[formFieldIndex] || {}).message || '', - required: getBoolean(formFieldConfig.required), - fieldType: formFieldConfig.type, - children: ( - | null) => { - if (!this.formFieldsList[index]) this.formFieldsList[index] = [] - this.formFieldsList[index][formFieldIndex] = formField - this.handleMount(index, formFieldIndex) - }} - value={getValue(getValue(value, tab.field), formFieldConfig.field)} - record={getValue(value, tab.field)} - data={cloneDeep(this.props.data)} - step={this.props.step} - config={formFieldConfig} - onValueSet={async (path, value, validation) => this.handleValueSet(index, formFieldIndex, path, value, validation)} - onValueUnset={async (path, validation) => this.handleValueUnset(index, formFieldIndex, path, validation)} - onValueListAppend={async (path, value, validation) => this.handleValueListAppend(index, formFieldIndex, path, value, validation)} - onValueListSplice={async (path, _index, count, validation) => this.handleValueListSplice(index, formFieldIndex, path, _index, count, validation)} - baseRoute={this.props.baseRoute} - loadDomain={async (domain: string) => await this.props.loadDomain(domain)} - /> - ) - })} -
- ) - } else { - return - } - }) - })} - - ) - }) + const fields = this.props.config.mode === 'same' ? (this.props.config.fields || []) : (((this.props.config.tabs || [])[index] || {}).fields || []) + return ( + + {this.renderItemComponent({ + key: index.toString(), + label: tab.label, + children: fields.map((formFieldConfig, formFieldIndex) => { + if (!ConditionHelper(formFieldConfig.condition, { record: this.props.record, data: this.props.data, step: this.props.step })) { + if (!this.formFieldsMountedList[index]) this.formFieldsMountedList[index] = [] + this.formFieldsMountedList[index][formFieldIndex] = false + return null + } + let hidden: boolean = true + let display: boolean = true + + if (formFieldConfig.type === 'hidden') { + hidden = true + display = false + } + + if (formFieldConfig.display === 'none') { + hidden = true + display = false + } + + const FormField = this.getALLComponents(formFieldConfig.type) || Display + + let status: 'normal' = 'normal' + // 渲染表单项容器 + if (hidden) { + return ( +
+ {this.renderItemFieldComponent({ + index: formFieldIndex, + label: formFieldConfig.label, + status, + required: getBoolean(formFieldConfig.required), + fieldType: formFieldConfig.type, + children: ( + | null) => { + if (!this.formFieldsList[index]) this.formFieldsList[index] = [] + this.formFieldsList[index][formFieldIndex] = formField + this.handleMount(index, formFieldIndex) + }} + value={getValue(getValue(value, tab.field), formFieldConfig.field)} + record={getValue(value, tab.field)} + data={cloneDeep(this.props.data)} + step={this.props.step} + config={formFieldConfig} + onValueSet={async (path, value, validation) => this.handleValueSet(index, formFieldIndex, path, value, validation)} + onValueUnset={async (path, validation) => this.handleValueUnset(index, formFieldIndex, path, validation)} + onValueListAppend={async (path, value, validation) => this.handleValueListAppend(index, formFieldIndex, path, value, validation)} + onValueListSplice={async (path, _index, count, validation) => this.handleValueListSplice(index, formFieldIndex, path, _index, count, validation)} + baseRoute={this.props.baseRoute} + loadDomain={async (domain: string) => await this.props.loadDomain(domain)} + /> + ) + })} +
+ ) + } else { + return + } + }) + })} + + ) + }) : [] ) }) -- Gitee