diff --git a/src/components/formFields/any/index.tsx b/src/components/formFields/any/index.tsx
index b0f9666c86cd2e1fac2b1e91939a9c0dedd0751a..ad029b2c1164e02244fddb265657abd0659dd836 100644
--- a/src/components/formFields/any/index.tsx
+++ b/src/components/formFields/any/index.tsx
@@ -93,6 +93,7 @@ export default class AnyField extends Field : (
@@ -109,6 +110,7 @@ export default class AnyField extends Field :
diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx
index b5c5c7e5a90ea7fd81a91cbb25677987bd6d8131..4d6814e5e4081257869a0c2e98719a1994d0e192 100644
--- a/src/components/formFields/common.tsx
+++ b/src/components/formFields/common.tsx
@@ -92,6 +92,8 @@ export interface FieldProps {
onValueListAppend: (path: string, value: any, validation: true | FieldError[]) => Promise
// 事件:修改值 - 列表 - 删除
onValueListSplice: (path: string, index: number, count: number, validation: true | FieldError[]) => Promise
+ // 事件:修改值 - 列表 - 修改顺序
+ onValueListSort: (path: string, index: number, sortType: 'up' | 'down', validation: true | FieldError[]) => Promise
baseRoute: string,
loadDomain: (domain: string) => Promise
}
diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx
index d57ede7d03d740d0332260f80d07f74aa8c0b171..ca01bb30cef4d42c69960a20e7c6a711c155d08c 100644
--- a/src/components/formFields/form/index.tsx
+++ b/src/components/formFields/form/index.tsx
@@ -1,7 +1,7 @@
import React from 'react'
import { Field, FieldConfig, FieldConfigs, FieldError, FieldProps, IField } from '../common'
import getALLComponents from '../'
-import { getValue } from '../../../util/value'
+import { getValue, listItemMove } from '../../../util/value'
import { cloneDeep } from 'lodash'
import ConditionHelper from '../../../util/condition'
@@ -14,19 +14,27 @@ export interface FormFieldConfig extends FieldConfig {
initialValues?: any // 新增子项时的默认值
mode?: 'show' // 子项仅显示列表
modeValue?: string
+ canInsert?: boolean
+ canRemove?: boolean
+ canSort?: boolean
+ canCollapse?: boolean // 是否用Collapse折叠展示
}
export interface IFormField {
insertText: string
- onInsert: () => Promise
+ onInsert?: () => Promise
+ canCollapse?: boolean
children: React.ReactNode[]
}
export interface IFormFieldItem {
index: number
+ isLastIndex: boolean
title: string
removeText: string
- onRemove: () => Promise
+ onRemove?: () => Promise
+ onSort?: (sortType: 'up' | 'down') => Promise
+ canCollapse?: boolean
children: React.ReactNode[]
}
@@ -204,6 +212,15 @@ export default class FormField extends Field {
+ const formDataList = listItemMove(cloneDeep(this.state.formDataList), index, sortType)
+ this.setState({
+ formDataList
+ })
+ this.formFieldsMountedList = listItemMove(this.formFieldsMountedList, index, sortType)
+ await this.props.onValueListSort('', index, sortType, true)
+ }
handleChange = async (index: number, formFieldIndex: number, value: any) => {
// const formField = this.formItemsList[index][formFieldIndex]
@@ -308,6 +325,24 @@ export default class FormField extends Field {
+ const formFieldConfig = (this.props.config.fields || [])[formFieldIndex]
+ if (formFieldConfig) {
+ const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}`
+ await this.props.onValueListSort(`[${index}]${fullPath}`, _index, sortType, 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
+ })
+ }
+ }
/**
* 用于展示子表单组件中的每一子项中的每一个子表单项组件
@@ -353,7 +388,11 @@ export default class FormField extends Field await this.handleInsert(),
+ onInsert: canInsert? async () => await this.handleInsert(): undefined,
+ canCollapse,
children: (
(Array.isArray(value) ? value : []).map((itemValue: any, index: number) => {
return
{this.renderItemComponent({
index,
+ isLastIndex: value.length - 1 === index? true: false,
title: primaryField !== undefined ? getValue(itemValue, primaryField) : index.toString(),
removeText: removeText === undefined
? `删除 ${label}`
: removeText,
- onRemove: async () => await this.handleRemove(index),
+ onRemove: canRemove? async () => await this.handleRemove(index): undefined,
+ onSort: canSort? async (sortType: 'up' | 'down') => await this.handleSort(index, sortType): undefined,
+ canCollapse,
children: (fields || []).map((formFieldConfig, fieldIndex) => {
if (!ConditionHelper(formFieldConfig.condition, { record: itemValue, data: this.props.data, step: this.props.step })) {
return null
@@ -408,6 +451,7 @@ export default class FormField extends Field 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)}
+ onValueListSort={async (path, _index, sortType, validation) => await this.handleValueListSort(index, fieldIndex, path, _index, sortType, validation)}
baseRoute={this.props.baseRoute}
loadDomain={async (domain: string) => await this.props.loadDomain(domain)}
/>
diff --git a/src/components/formFields/group/index.tsx b/src/components/formFields/group/index.tsx
index 1826dcbbed806b702f780287526523070f2e8849..03c50eec96db9e9c025001b6f6e39e51284e7ebd 100644
--- a/src/components/formFields/group/index.tsx
+++ b/src/components/formFields/group/index.tsx
@@ -228,6 +228,25 @@ export default class GroupField extends Field {
+ const formFieldConfig = (this.props.config.fields || [])[formFieldIndex]
+ if (formFieldConfig) {
+ const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}`
+ await this.props.onValueListSort(fullPath, index, sortType, 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
+ })
+ }
+ }
+
renderComponent = (props: IGroupField) => {
return
您当前使用的UI版本没有实现GroupField组件。
@@ -305,6 +324,7 @@ export default class GroupField extends Field 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)}
+ onValueListSort={async (path, index, sortType, validation) => this.handleValueListSort(formFieldIndex, path, index, sortType, validation)}
baseRoute={this.props.baseRoute}
loadDomain={async (domain: string) => await this.props.loadDomain(domain)}
/>
diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx
index f211cd3b5b89f7597964d57af64744128aaedece..0a446a0c97872d3d50407b331bd59034333c335d 100644
--- a/src/components/formFields/importSubform/index.tsx
+++ b/src/components/formFields/importSubform/index.tsx
@@ -246,7 +246,24 @@ export default class ImportSubformField extends Field {
+ const formFieldConfig = (this.state.fields || [])[formFieldIndex]
+ if (formFieldConfig) {
+ const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}`
+ await this.props.onValueListSort(fullPath, index, sortType, 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
+ })
+ }
+ }
renderComponent = (props: IImportSubformField) => {
return
您当前使用的UI版本没有实现ImportSubformField组件。
@@ -340,6 +357,7 @@ export default class ImportSubformField extends Field 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)}
+ onValueListSort={async (path, index, sortType, validation) => this.handleValueListSort(formFieldIndex, path, index, sortType, validation)}
baseRoute={this.props.baseRoute}
loadDomain={async (domain: string) => await this.props.loadDomain(domain)}
/>
diff --git a/src/components/formFields/object/index.tsx b/src/components/formFields/object/index.tsx
index 42179c946e864979bdf5c3a000b792aad6e45d00..e9ad5c3403eafdd824c598584c05d0b5d9f30b69 100644
--- a/src/components/formFields/object/index.tsx
+++ b/src/components/formFields/object/index.tsx
@@ -320,6 +320,25 @@ export default class ObjectField extends Field {
+ const formFieldConfig = (this.props.config.fields || [])[formFieldIndex]
+ if (formFieldConfig) {
+ const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}`
+ await this.props.onValueListSort(fullPath === '' ? key : `${key}.${fullPath}`, _index, sortType, true)
+
+ const formDataList = cloneDeep(this.state.formDataList)
+ if (validation === true) {
+ formDataList[key][formFieldIndex] = { status: 'normal' }
+ } else {
+ formDataList[key][formFieldIndex] = { status: 'error', message: validation[0].message }
+ }
+
+ this.setState({
+ formDataList
+ })
+ }
+ }
+
/**
* 用于展示子表单组件
* @param _props
@@ -428,6 +447,7 @@ export default class ObjectField extends Field this.handleValueUnset(key, formFieldIndex, path, validation)}
onValueListAppend={async (path, value, validation) => this.handleValueListAppend(key, formFieldIndex, path, value, validation)}
onValueListSplice={async (path, _index, count, validation) => this.handleValueListSplice(key, formFieldIndex, path, _index, count, validation)}
+ onValueListSort={async (path, _index, sortType, validation) => this.handleValueListSort(key, formFieldIndex, path, _index, sortType, validation)}
baseRoute={this.props.baseRoute}
loadDomain={async (domain: string) => this.props.loadDomain(domain)}
/>
diff --git a/src/components/formFields/tabs/index.tsx b/src/components/formFields/tabs/index.tsx
index dee32136d5dc6af1d68d19be4081b4c280f10be5..21615d57c366a123554f7999669be65433471a57 100644
--- a/src/components/formFields/tabs/index.tsx
+++ b/src/components/formFields/tabs/index.tsx
@@ -282,6 +282,29 @@ export default class TabsField extends Field {
+ 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.onValueListSort(fullPath, _index, sortType, 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
+ })
+ }
+ }
/**
* 用于展示子表单组件
@@ -385,6 +408,7 @@ export default class TabsField extends Field 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)}
+ onValueListSort={async (path, _index, sortType, validation) => this.handleValueListSort(index, formFieldIndex, path, _index, sortType, validation)}
baseRoute={this.props.baseRoute}
loadDomain={async (domain: string) => await this.props.loadDomain(domain)}
/>
diff --git a/src/steps/filter/index.tsx b/src/steps/filter/index.tsx
index 05bc4f677c96a51181cdef419e15657707286243..c6cd09cbee7587ffce9eadd63d422c9e9c6d712f 100644
--- a/src/steps/filter/index.tsx
+++ b/src/steps/filter/index.tsx
@@ -6,7 +6,7 @@ import { ParamConfig } from '../../interface'
import ParamHelper from '../../util/param'
import { cloneDeep, get, set, unset } from 'lodash'
import ConditionHelper from '../../util/condition'
-import { getValue, setValue } from '../../util/value'
+import { getValue, setValue, listItemMove } from '../../util/value'
/**
* 表单步骤配置文件格式定义
@@ -381,6 +381,31 @@ export default class FilterStep extends Step {
})
}
}
+ handleValueListSort = async (formFieldIndex: number, path: string, index: number, sortType: 'up' | 'down', validation: true | FieldError[]) => {
+ const formFieldConfig = (this.props.config.fields || [])[formFieldIndex]
+ if (formFieldConfig) {
+ const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}`
+
+ const list = listItemMove(get(this.formValue, fullPath, []), index, sortType)
+ set(this.formValue, fullPath, list)
+ this.setState({
+ formValue: this.formValue
+ })
+ if (this.props.onChange) {
+ this.props.onChange(this.formValue)
+ }
+
+ if (validation === true) {
+ this.formData[formFieldIndex] = { status: 'normal' }
+ } else {
+ this.formData[formFieldIndex] = { status: 'error', message: validation[0].message }
+ }
+
+ await this.setState({
+ formData: cloneDeep(this.formData)
+ })
+ }
+ }
/**
* 表单步骤组件 - UI渲染方法
@@ -472,6 +497,7 @@ export default class FilterStep extends Step {
onValueUnset={async (path, validation) => await this.handleValueUnset(formFieldIndex, path, validation)}
onValueListAppend={async (path, value, validation) => await this.handleValueListAppend(formFieldIndex, path, value, validation)}
onValueListSplice={async (path, index, count, validation) => await this.handleValueListSplice(formFieldIndex, path, index, count, validation)}
+ onValueListSort={async (path, index, sortType, validation) => await this.handleValueListSort(formFieldIndex, path, index, sortType, validation)}
baseRoute={this.props.baseRoute}
loadDomain={async (domain: string) => await this.props.loadDomain(domain)}
/>
diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx
index 8eeb22380f3b02df082f4ee49e77f7c60d834b5f..320cfc2f4f8e77b2e8c44911766cc4da117486c6 100644
--- a/src/steps/form/index.tsx
+++ b/src/steps/form/index.tsx
@@ -2,7 +2,7 @@ import React from 'react'
import { Field, FieldConfigs, FieldError } from '../../components/formFields/common'
import Step, { StepConfig, StepProps } from '../common'
import getALLComponents from '../../components/formFields'
-import { getValue, setValue } from '../../util/value'
+import { getValue, setValue, listItemMove } from '../../util/value'
import { ParamConfig } from '../../interface'
import ParamHelper from '../../util/param'
import { cloneDeep, get, set, unset } from 'lodash'
@@ -318,7 +318,8 @@ export default class FormStep extends Step {
if (formFieldConfig) {
const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}`
- const list = get(this.formValue, fullPath, [])
+ let list = get(this.formValue, fullPath, [])
+ if (!Array.isArray(list)) list = []
list.push(value)
set(this.formValue, fullPath, list)
this.setState({
@@ -366,6 +367,31 @@ export default class FormStep extends Step {
})
}
}
+ handleValueListSort = async (formFieldIndex: number, path: string, index: number, sortType: 'up' | 'down', validation: true | FieldError[]) => {
+ const formFieldConfig = (this.props.config.fields || [])[formFieldIndex]
+ if (formFieldConfig) {
+ const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}`
+
+ const list = listItemMove(get(this.formValue, fullPath, []), index, sortType)
+ set(this.formValue, fullPath, list)
+ this.setState({
+ formValue: this.formValue
+ })
+ if (this.props.onChange) {
+ this.props.onChange(this.formValue)
+ }
+
+ if (validation === true) {
+ this.formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label }
+ } else {
+ this.formData[formFieldIndex] = { status: 'error', message: validation[0].message, name: formFieldConfig.label }
+ }
+
+ await this.setState({
+ formData: cloneDeep(this.formData)
+ })
+ }
+ }
/**
* 表单步骤组件 - UI渲染方法
@@ -470,6 +496,7 @@ export default class FormStep extends Step {
onValueUnset={async (path, validation) => await this.handleValueUnset(formFieldIndex, path, validation)}
onValueListAppend={async (path, value, validation) => await this.handleValueListAppend(formFieldIndex, path, value, validation)}
onValueListSplice={async (path, index, count, validation) => await this.handleValueListSplice(formFieldIndex, path, index, count, validation)}
+ onValueListSort={async (path, index, sortType, validation) => await this.handleValueListSort(formFieldIndex, path, index, sortType, validation)}
baseRoute={this.props.baseRoute}
loadDomain={async (domain: string) => await this.props.loadDomain(domain)}
/>
diff --git a/src/util/value.ts b/src/util/value.ts
index 8588af3c471e75f0ee8abc1138e1f918e6b50a35..f10cbd719e3f65a78f8dcf5b619e7f2cc8f5c9ee 100644
--- a/src/util/value.ts
+++ b/src/util/value.ts
@@ -13,15 +13,15 @@ export const getValue = (obj: any, path: string = '', defaultValue: any = undefi
}
const merge = (a: any, b: any): any => {
- return assignInWith(a, b, (a,b) => {
+ return assignInWith(a, b, (a, b) => {
if (isUndefined(a) && isArray(b)) {
a = []
}
if (isObject(b)) {
if (isArray(a)) {
- return merge(a,b).filter((i: any) => i !== undefined)
+ return merge(a, b).filter((i: any) => i !== undefined)
} else {
- return merge(a,b)
+ return merge(a, b)
}
}
})
@@ -103,3 +103,21 @@ export const getBoolean = (value: any) => {
}
return false
}
+
+/**
+ * 处理list元素上移、下移
+ * @param list list
+ * @param currentIndex 当前操作元素在list索引
+ * @param sortType up或down
+ */
+export const listItemMove = (list: any[], currentIndex: number, sortType: 'up' | 'down') => {
+ switch (sortType) {
+ case 'up':
+ currentIndex !== 0 && (list[currentIndex] = list.splice(currentIndex - 1, 1, list[currentIndex])[0])
+ break;
+ case 'down':
+ currentIndex < list.length - 1 && (list[currentIndex] = list.splice(currentIndex + 1, 1, list[currentIndex])[0])
+ break;
+ }
+ return list
+}