From f75ac9b3649048ba73ff024f44d3f2b0539fbfbc Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Tue, 4 Jan 2022 17:18:21 +0800 Subject: [PATCH 01/38] =?UTF-8?q?immutable=E5=AE=9E=E7=8E=B0=E6=96=B9?= =?UTF-8?q?=E6=A1=88demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + src/components/formFields/any/index.tsx | 3 + src/components/formFields/common.tsx | 20 +- src/components/formFields/form/index.tsx | 9 +- src/components/formFields/group/index.tsx | 3 +- .../formFields/importSubform/index.tsx | 4 +- src/components/formFields/object/index.tsx | 3 +- src/components/formFields/tabs/index.tsx | 3 +- src/steps/filter/index.tsx | 3 +- src/steps/form/index.tsx | 382 +++++++++++++++++- src/util/value.ts | 13 + 11 files changed, 412 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 91472ce..ddc84db 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "@types/react": "^16.9.46", "@types/react-router-dom": "^5.1.5", "axios": "^0.20.0", + "immutable": "^4.0.0", "lodash": "^4.17.21", "marked": "^1.2.5", "moment": "^2.29.0", diff --git a/src/components/formFields/any/index.tsx b/src/components/formFields/any/index.tsx index e93f34e..a4a051d 100644 --- a/src/components/formFields/any/index.tsx +++ b/src/components/formFields/any/index.tsx @@ -97,6 +97,7 @@ export default class AnyField extends Field : ( type === 'number' ? {}} @@ -115,6 +116,7 @@ export default class AnyField extends Field : {}} form={this.props.form} @@ -132,6 +134,7 @@ export default class AnyField extends Field ) })} diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index 9b2f8f6..20302e2 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -5,7 +5,8 @@ import { FieldConfigs as getFieldConfigs } from './' import ParamHelper from '../../util/param' import { ConditionConfig } from '../../util/condition' import { StatementConfig } from '../../util/statement' - +import { is, getIn, fromJS } from 'immutable' + /** * 表单项基类配置文件格式定义 * - field: 表单项字段名 @@ -92,6 +93,7 @@ export interface FieldProps { // 事件:修改值 - 列表 - 修改顺序 onValueListSort: (path: string, index: number, sortType: 'up' | 'down', validation: true | FieldError[]) => Promise baseRoute: string, + path: string, // 组件所在路径以字段拼接展示 loadDomain: (domain: string) => Promise } @@ -170,7 +172,21 @@ export class Field extends React.Component< 当前UI库未实现该表单类型 } - + + shouldComponentUpdate(nextProps= {} as any, nextState = {}) { + if (!is(nextProps.config, this.props.config) || !is(nextProps.value, this.props.value)) { + console.log('props-true'); + return true; + } + if (!is(this.state, nextState)) { + console.log('state-true'); + return true; + } + + console.log('no update' ); + + return false; + } render = () => { return ( 当前UI库未实现该表单类型 diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index d95ddea..c32ab6c 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, listItemMove, setValue, getBoolean } from '../../../util/value' +import { getValue, listItemMove, setValue, getBoolean, getChainPath } from '../../../util/value' import { cloneDeep } from 'lodash' import ConditionHelper from '../../../util/condition' import StatementHelper from '../../../util/statement' @@ -235,7 +235,8 @@ export default class FormField extends Field await this.handleValueListSort(index, fieldIndex, path, _index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} + path={getChainPath(formFieldConfig.field, this.props.path)} /> ) }) diff --git a/src/components/formFields/group/index.tsx b/src/components/formFields/group/index.tsx index 2f28e43..a80f77a 100644 --- a/src/components/formFields/group/index.tsx +++ b/src/components/formFields/group/index.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { setValue, getValue, getBoolean } from '../../../util/value' +import { setValue, getValue, getBoolean, getChainPath } from '../../../util/value' import { Field, FieldConfig, FieldError, FieldProps, IField } from '../common' import getALLComponents, { FieldConfigs } from '../' import { IFormItem } from '../../../steps/form' @@ -344,6 +344,7 @@ export default class GroupField extends Field this.handleValueListSort(formFieldIndex, path, index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} + path={getChainPath(formFieldConfig.field, this.props.path)} /> ) } diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx index bfda6b1..2f18940 100644 --- a/src/components/formFields/importSubform/index.tsx +++ b/src/components/formFields/importSubform/index.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { setValue, getValue, getBoolean } from '../../../util/value' +import { setValue, getValue, getBoolean, getChainPath } from '../../../util/value' import { Field, FieldConfig, FieldError, FieldProps, IField } from '../common' import getALLComponents, { FieldConfigs } from '../' @@ -8,6 +8,7 @@ import { cloneDeep } from 'lodash' import ConditionHelper from '../../../util/condition' import InterfaceHelper, { InterfaceConfig } from '../../../util/interface' import StatementHelper from '../../../util/statement' +import { setIn } from 'immutable' /** * 子表单配置项 @@ -428,6 +429,7 @@ export default class ImportSubformField extends Field this.handleValueListSort(formFieldIndex, path, index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} + path={getChainPath(formFieldConfig.field, this.props.path)} /> ) } diff --git a/src/components/formFields/object/index.tsx b/src/components/formFields/object/index.tsx index b0de063..a68d174 100644 --- a/src/components/formFields/object/index.tsx +++ b/src/components/formFields/object/index.tsx @@ -3,7 +3,7 @@ import getALLComponents from '../' import React from 'react' import ConditionHelper from '../../../util/condition' import { cloneDeep } from 'lodash' -import { getValue, setValue, getBoolean } from '../../../util/value' +import { getValue, setValue, getBoolean, getChainPath } from '../../../util/value' import StatementHelper from '../../../util/statement' export interface ObjectFieldConfig extends FieldConfig { @@ -479,6 +479,7 @@ export default class ObjectField extends Field this.handleValueListSort(key, formFieldIndex, path, _index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => this.props.loadDomain(domain)} + path={getChainPath(formFieldConfig.field, this.props.path)} /> ) }) diff --git a/src/components/formFields/tabs/index.tsx b/src/components/formFields/tabs/index.tsx index a32b115..72e98d6 100644 --- a/src/components/formFields/tabs/index.tsx +++ b/src/components/formFields/tabs/index.tsx @@ -3,7 +3,7 @@ import getALLComponents from '../' import React from 'react' import ConditionHelper from '../../../util/condition' import { cloneDeep } from 'lodash' -import { getValue, setValue, getBoolean } from '../../../util/value' +import { getValue, setValue, getBoolean, getChainPath } from '../../../util/value' import StatementHelper from '../../../util/statement' export type TabsFieldConfig = TabsFieldConfig_Same | TabsFieldConfig_Diff @@ -439,6 +439,7 @@ export default class TabsField extends Field this.handleValueListSort(index, formFieldIndex, path, _index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} + path={getChainPath(formFieldConfig.field, this.props.path)} /> ) })} diff --git a/src/steps/filter/index.tsx b/src/steps/filter/index.tsx index 3f1bd37..b280205 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, listItemMove } from '../../util/value' +import { getValue, setValue, listItemMove, getChainPath } from '../../util/value' /** * 表单步骤配置文件格式定义 @@ -507,6 +507,7 @@ export default class FilterStep extends Step { 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)} + path={getChainPath(formFieldIndex, formFieldConfig.field)} /> ) } diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index 5c641fa..3de7aef 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -2,13 +2,15 @@ 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, listItemMove, getBoolean } from '../../util/value' +import { getValue, setValue, listItemMove, getBoolean, getChainPath } from '../../util/value' import { ParamConfig } from '../../interface' import ParamHelper from '../../util/param' -import { cloneDeep, get, set, unset } from 'lodash' +import { cloneDeep, get, set, unset, update } from 'lodash' import ConditionHelper, { ConditionConfig } from '../../util/condition' import StatementHelper, { StatementConfig } from '../../util/statement' import OperationHelper, { OperationConfig } from '../../util/operation' +import fp from 'lodash/fp' +import { Map, List, getIn, setIn, updateIn, fromJS } from 'immutable' /** * 表单步骤配置文件格式定义 @@ -170,10 +172,318 @@ export default class FormStep extends Step { formFields: Array | null> = [] formFieldsMounted: Array = [] + // formValue: { [field: string]: any } = Map({}) formValue: { [field: string]: any } = {} formData: { status: 'normal' | 'error' | 'loading', message?: string, name: string }[] = [] canSubmit: boolean = false submitData: object = {} + record_:object = { + "pageFormData": { + "dataAssociation": { + "sourceMaterial": { + "fields": [ + { + "label": "上提12", + "field": "liftUp", + "type": "switch", + "extra": { + "statement": "", + "params": [] + }, + "valueTrue": true, + "valueFalse": false, + "defaultValue": { + "source": "static", + "value": false + }, + "required": true, + "condition": { + "params": [] + } + }, + { + "label": "上提楼层尾icon-短文本链接", + "field": "upTailIcon", + "type": "text", + "extra": { + "params": [] + }, + "placeholder": "请输入尾icon地址", + "regExp": {}, + "defaultValue": { + "source": "static", + "value": "" + }, + "required": true, + "condition": { + "params": [ + { + "field": "upward", + "data": { + "source": "record", + "field": "material.liftUp" + } + } + ], + "template": "${upward} === true" + } + }, + { + "label": "尾icon高度-数值", + "field": "upTailIconHight", + "type": "number", + "extra": { + "params": [] + }, + "precision": 0, + "step": 1, + "max": 120, + "regExp": {}, + "defaultValue": { + "source": "static", + "value": 0 + }, + "required": true, + "condition": { + "params": [ + { + "field": "upward", + "data": { + "source": "record", + "field": "material.liftUp" + } + } + ], + "template": "${upward} === true" + } + }, + { + "label": "上提楼层头icon-短文本", + "field": "upHeadIcon", + "type": "text", + "extra": { + "params": [] + }, + "placeholder": "请输入头icon地址", + "cjkLength": 2, + "regExp": {}, + "defaultValue": { + "source": "static", + "value": "" + }, + "required": true, + "condition": { + "params": [ + { + "field": "upward", + "data": { + "source": "record", + "field": "material.liftUp" + } + } + ], + "template": "${upward} === true" + } + }, + { + "label": "业务标题-短文本", + "field": "title", + "type": "text", + "extra": { + "params": [] + }, + "placeholder": "请输入展示文案", + "maxLength": 12, + "minLength": null, + "cjkLength": 2, + "regExp": { + "expression": "", + "message": "业务标题重复" + }, + "defaultValue": { + "source": "static", + "value": "" + }, + "required": true, + "condition": { + "params": [] + } + }, + { + "label": "业务标题色值", + "field": "titleColor", + "type": "color", + "extra": { + "params": [] + }, + "defaultValue": { + "source": "static", + "value": "#ffffff" + }, + "required": true, + "condition": { + "params": [ + { + "field": "upward", + "data": { + "source": "record", + "field": "material.liftUp" + } + } + ], + "template": "${upward} === true" + } + }, + { + "label": "业务副标题-文本1", + "field": "subTitle", + "type": "text", + "extra": { + "params": [] + }, + "placeholder": "请输入展示文案", + "maxLength": 16, + "minLength": null, + "cjkLength": 2, + "regExp": { + "expression": "", + "message": "文案超过8个字" + }, + "defaultValue": { + "source": "static", + "value": "" + }, + "required": true, + "condition": { + "params": [] + } + }, + { + "label": "业务副标题色值", + "field": "subtitleColor", + "type": "color", + "extra": { + "params": [] + }, + "defaultValue": { + "source": "static", + "value": "" + }, + "required": true, + "condition": { + "params": [ + { + "field": "upward", + "data": { + "source": "record", + "field": "material.liftUp" + } + } + ], + "template": "${upward} === true " + } + }, + { + "label": "icon图片", + "field": "icon", + "type": "upload", + "extra": { + "statement": "icon尺寸33x44,支持png格式,50K以内", + "params": [] + }, + "interface": { + "domain": "jdg", + "url": "/upload/imageUpload", + "urlParams": [], + "method": "POST", + "contentType": "json", + "withCredentials": true, + "params": [], + "data": [], + "condition": { + "enable": true, + "success": {}, + "fail": {} + }, + "response": [ + { + "path": "data" + } + ], + "cache": {} + }, + "requireField": "file", + "mode": "image", + "sizeCheck": { + "maxSize": 50, + "sizeUnit": "K", + "height": null, + "width": null + }, + "defaultValue": { + "source": "static", + "value": "" + }, + "required": true, + "condition": { + "params": [], + "template": "" + } + }, + { + "label": "背景颜色-取色器", + "field": "bgColor", + "type": "color", + "extra": { + "params": [] + }, + "defaultValue": { + "source": "static", + "value": "#ffffff" + }, + "required": true, + "condition": { + "params": [ + { + "field": "upward", + "data": { + "source": "record", + "field": "material.liftUp" + } + } + ], + "template": "${upward} === true" + } + }, + { + "label": "跳转链接", + "field": "jumpUrl", + "type": "text", + "extra": { + "statement": "1、跳转地址必须经西格玛审核; 2、跳转地址需在APP白名单中,不在可找商详技术处理", + "params": [] + }, + "placeholder": "请输入跳转链接", + "regExp": { + "expression": "(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\'\\/\\\\\\+&%$#_]*)?", + "message": "请输入正确格式" + }, + "defaultValue": { + "source": "static", + "value": "" + }, + "required": true, + "condition": { + "params": [], + "template": "" + } + } + ] + } + } + } +} +data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sourceMaterial.fields"],"defaultValue":{"source":"step","field":"data","step":1,"unstringify":["data.pageFormData.dataAssociation.sourceMaterial.field"]},"businessSuffix":"","unstringify":["pageFormData.dataAssociation.sourceMaterial.fields"],"version":"1.0.0","subversion":"0","fields":[{"canInsert":true,"canSort":true,"canRemove":true,"label":"字段设置","primaryField":"label","fields":[{"label":"字段描述","field":"label","type":"text"},{"label":"字段名","field":"field","type":"text"},{"field":"","label":"","type":"import_subform","interface":{"url":"https://storage.jd.com/swm-plus/prod-floor-fields/config/form/index.json","urlParams":[],"method":"GET"},"defaultValue":{"source":"record","field":""}}],"field":"pageFormData.dataAssociation.sourceMaterial.fields","type":"form","canCollapse":true}],"type":"form","applicationName":"example","actions":[{"type":"ccms","mode":"primary","label":"保存并发布","callback":{"type":"cancel"},"handle":{"type":"ccms","page":822,"mode":"popup","label":"","params":[{"field":"systemId","data":{"source":"record","value":"create","field":"systemId"}},{"field":"type","data":{"source":"record","field":"type"}},{"field":"appName","data":{"source":"record","field":"appName"}},{"field":"pageFormData","data":{"source":"record","field":"pageFormData"}},{"data":{"source":"static","value":1},"field":"saveAndPublish"},{"field":"templateUseType","data":{"source":"step","value":1,"field":"data.jdgBusiFloor.templateUseType","step":1}},{"field":"id","data":{"source":"record","field":"jdgBusiFloor.id"}}]},"condition":{"debug":true}},{"type":"submit","mode":"primary","label":"保存为草稿","callback":{"type":"none"},"handle":{"type":"ccms"},"condition":{"params":[]}}]},"fields":[{"canInsert":true,"canSort":true,"defaultValue":{"source":"static","value":""},"canRemove":true,"label":"字段设置","primaryField":"label","fields":[{"label":"字段描述","field":"label","type":"text"},{"label":"字段名","field":"field","type":"text"},{"field":"","label":"","type":"import_subform","interface":{"url":"https://storage.jd.com/swm-plus/prod-floor-fields/config/form/index.json","urlParams":[],"method":"GET"},"defaultValue":{"source":"record","field":""}}],"field":"pageFormData.dataAssociation.sourceMaterial.fields","type":"form","canCollapse":true}],"stringify":["pageFormData.dataAssociation.sourceMaterial.fields"],"actions":[{"type":"ccms","mode":"primary","label":"保存并发布","callback":{"type":"cancel"},"handle":{"type":"ccms","page":822,"mode":"popup","label":"","params":[{"field":"systemId","data":{"source":"record","value":"create","field":"systemId"}},{"field":"type","data":{"source":"record","field":"type"}},{"field":"appName","data":{"source":"record","field":"appName"}},{"field":"pageFormData","data":{"source":"record","field":"pageFormData"}},{"data":{"source":"static","value":1},"field":"saveAndPublish"},{"field":"templateUseType","data":{"source":"step","value":1,"field":"data.jdgBusiFloor.templateUseType","step":1}},{"field":"id","data":{"source":"record","field":"jdgBusiFloor.id"}}]},"condition":{"debug":true}},{"type":"submit","mode":"primary","label":"保存为草稿","callback":{"type":"none"},"handle":{"type":"ccms"},"condition":{"params":[]}}],"applicationName":"example","businessSuffix":"","version":"1.0.0","subversion":"0"}] /** * 初始化表单的值 @@ -183,7 +493,8 @@ export default class FormStep extends Step { super(props) this.state = { ready: false, - formValue: {}, + // formValue: {}, + formValue: Map({}), formData: [] } } @@ -203,6 +514,7 @@ export default class FormStep extends Step { } = this.props this.formValue = {} + // this.formValue = Map({}) this.formData = [] if (this.props.config.defaultValue) { @@ -222,7 +534,10 @@ export default class FormStep extends Step { for (const formFieldIndex in formFieldsConfig) { const formFieldConfig = formFieldsConfig[formFieldIndex] const value = getValue(formDefault, formFieldConfig.field) - this.formValue = setValue(this.formValue, formFieldConfig.field, value) + + const fieldPathArr = formFieldConfig.field.split('.') + // this.formValue = setValue(this.formValue, formFieldConfig.field, value) + this.formValue = setIn(this.formValue, fieldPathArr, value) this.formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } } } @@ -247,14 +562,16 @@ export default class FormStep extends Step { const formField = this.formFields[formFieldIndex] if (formField) { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] - - let value = getValue(this.formValue, formFieldConfig.field) + const fieldPathArr = formFieldConfig.field.split('.') + // let value = getValue(this.formValue, formFieldConfig.field) + let value = getIn(this.formValue, fieldPathArr) if ((formFieldConfig.defaultValue) && value === undefined) { value = await formField.reset() } value = await formField.set(value) - this.formValue = setValue(this.formValue, formFieldConfig.field, value) - + // this.formValue = setValue(this.formValue, formFieldConfig.field, value) + this.formValue = setIn(this.formValue, fieldPathArr, value) + if (value !== undefined) { const validation = await formField.validate(value) if (validation === true) { @@ -378,25 +695,39 @@ export default class FormStep extends Step { if (formFieldConfig) { const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - set(this.formValue, fullPath, value) - this.setState({ - formValue: this.formValue + const fullPathArr = fullPath.split('.') + + + // set(this.formValue, fullPath, value) + // this.formValue = setIn(this.formValue, fullPathArr, value) + // this.setState({ + // formValue: this.formValue + // }) + this.setState(({formValue}) => { + // return {formValue: set(formValue, fullPath, value)} + // return {formValue: fp.update(fullPath, ()=> value, formValue)} + // return {formValue: setIn(this.formValue, fullPathArr, value)} + return {formValue: updateIn(formValue, fullPathArr, () => value)} }) + var temp = [fullPathArr[0]] + this.formValue = updateIn(this.formValue, fullPathArr, () => value) + // this.setState(({formValue}) => ({formValue: this.formValue})) + console.log('set--', this.formValue, fullPath, fullPathArr, value); 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 } - } + // if (validation === true) { + // this.formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } + // } else { + // this.formData[formFieldIndex] = { status: 'error', message: validation[0].message, name: formFieldConfig.label } + // } console.log('form set data', this.formData) - await this.setState({ - formData: cloneDeep(this.formData) - }) + // await this.setState({ + // formData: cloneDeep(this.formData) + // }) } } @@ -669,7 +1000,8 @@ export default class FormStep extends Step { if (['group', 'import_subform', 'object', 'tabs', 'form'].some((type) => type === formFieldConfig.type)) { status = 'normal' } - + const fieldPathArr = formFieldConfig.field.split('.') + const renderData = { key: formFieldIndex, label: formFieldConfig.label, @@ -690,10 +1022,14 @@ export default class FormStep extends Step { } }} formLayout={layout} - value={formFieldConfig.field !== undefined ? getValue(formValue, formFieldConfig.field) : undefined} + // value={formFieldConfig.field !== undefined ? getValue(formValue, formFieldConfig.field) : undefined} + value={formFieldConfig.field !== undefined ? getIn(formValue, fieldPathArr) : undefined} + // record={formValue.toJS()} record={formValue} + // record={this.record_} form={this} - data={cloneDeep(data)} + // data={cloneDeep(data)} + data={this.data_} step={step} config={formFieldConfig} onChange={async (value: any) => { await this.handleChange(formFieldIndex, value) }} @@ -704,6 +1040,7 @@ export default class FormStep extends Step { 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)} + path={getChainPath(formFieldIndex, formFieldConfig.field)} /> ) } @@ -722,3 +1059,4 @@ export default class FormStep extends Step { } } } + diff --git a/src/util/value.ts b/src/util/value.ts index 35a8463..b9d9e4c 100644 --- a/src/util/value.ts +++ b/src/util/value.ts @@ -121,3 +121,16 @@ export const listItemMove = (list: any[], currentIndex: number, sortType: 'up' | } return list } + +/** + * 组件所在的字符串链式路径 + * @param currentPath + * @param sourcePath + * @returns + */ +export const getChainPath = (currentPath: string | number = '', sourcePath: string | number = '') => { + if (!currentPath && currentPath !== 0) {currentPath = ''} else {currentPath = currentPath.toString()} + if (!sourcePath && sourcePath !== 0) {sourcePath = ''} else {sourcePath = sourcePath.toString()} + const finalPath = (sourcePath +'.'+ currentPath).replace(/(^\.*)|(\.*$)|(\.){2,}/g, '$3') + return finalPath +} \ No newline at end of file -- Gitee From da62fecb53c32bf382373a8a869efd5ff2bf0072 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Fri, 7 Jan 2022 16:21:26 +0800 Subject: [PATCH 02/38] feat: redux demo --- package.json | 5 +- src/HOC/stepComponentHOC.jsx | 29 +++++++ src/components/formFields/common.tsx | 2 +- .../formFields/importSubform/index.tsx | 1 - src/main.tsx | 27 ++++--- src/steps/common.tsx | 34 ++++++-- src/steps/form/index.tsx | 80 ++++++++++++------- src/steps/table/index.tsx | 6 +- src/store/common.tsx | 7 ++ src/store/index.tsx | 1 + src/store/reducers/data.tsx | 43 ++++++++++ src/store/reducers/formValue.tsx | 38 +++++++++ src/store/reducers/index.tsx | 2 + src/store/store.tsx | 52 ++++++++++++ 14 files changed, 273 insertions(+), 54 deletions(-) create mode 100644 src/HOC/stepComponentHOC.jsx create mode 100644 src/store/common.tsx create mode 100644 src/store/index.tsx create mode 100644 src/store/reducers/data.tsx create mode 100644 src/store/reducers/formValue.tsx create mode 100644 src/store/reducers/index.tsx create mode 100644 src/store/store.tsx diff --git a/package.json b/package.json index ddc84db..4a2484e 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "@types/react": "^16.9.46", "@types/react-router-dom": "^5.1.5", "axios": "^0.20.0", + "immer": "^9.0.7", "immutable": "^4.0.0", "lodash": "^4.17.21", "marked": "^1.2.5", @@ -80,7 +81,9 @@ "qiankun": "^2.5.1", "query-string": "^6.13.8", "rc-table": "^7.9.10", - "react-loadable": "^5.5.0" + "react-loadable": "^5.5.0", + "react-redux": "^7.2.6", + "redux": "^4.1.2" }, "peerDependencies": { "react": "^16.13.1", diff --git a/src/HOC/stepComponentHOC.jsx b/src/HOC/stepComponentHOC.jsx new file mode 100644 index 0000000..3f46d7d --- /dev/null +++ b/src/HOC/stepComponentHOC.jsx @@ -0,0 +1,29 @@ +import React from 'react' +import {connect} from 'react-redux' +import { compose } from 'redux' +import { InterfaceState, PreloadedState } from '../store/store' +import { setFormValue } from '../store/reducers/formValue' + +const StepComponentHOC = function (WrappedComponent) { + class StepContainer extends React.Component { + render () { + console.log('props==', this.props); + return ( + WrappedComponent + ) + } + } + const mapStateToProps = (state) => { + return { + data: state.data.data, + formValue: state.formValue.formValue + } + } + const mapDispatchToProps = (dispatch) => { + return { + handleFormValue: () => dispatch(setFormValue(payload)) + } + } + return connect(mapStateToProps, mapDispatchToProps)(StepContainer) +} +export { StepComponentHOC as default } \ No newline at end of file diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index 20302e2..f5ecdac 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -5,7 +5,7 @@ import { FieldConfigs as getFieldConfigs } from './' import ParamHelper from '../../util/param' import { ConditionConfig } from '../../util/condition' import { StatementConfig } from '../../util/statement' -import { is, getIn, fromJS } from 'immutable' +import { is } from 'immutable' /** * 表单项基类配置文件格式定义 diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx index 2f18940..cdf3171 100644 --- a/src/components/formFields/importSubform/index.tsx +++ b/src/components/formFields/importSubform/index.tsx @@ -8,7 +8,6 @@ import { cloneDeep } from 'lodash' import ConditionHelper from '../../../util/condition' import InterfaceHelper, { InterfaceConfig } from '../../../util/interface' import StatementHelper from '../../../util/statement' -import { setIn } from 'immutable' /** * 子表单配置项 diff --git a/src/main.tsx b/src/main.tsx index d580507..0ab033d 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,9 +1,12 @@ -import React from 'react' +import React, { forwardRef } from 'react' import marked from 'marked' +import { Provider, connect } from 'react-redux' import Step, { StepProps } from './steps/common' import StepComponents, { StepConfigs } from './steps' import { RichStringConfig } from './interface' - +import { store } from './store' +import { compose } from 'redux' +import { InterfaceState, PreloadedState } from './store/store' /** * 页面配置文件格式定义 * - basic: 页面基本配置 @@ -38,7 +41,7 @@ export interface ICCMS { * - config: 页面配置文件 * - sourceData: 传入数据 */ -export interface CCMSProps { +export interface CCMSProps { config: CCMSConfig sourceData: any baseRoute: string @@ -50,6 +53,7 @@ export interface CCMSProps { handlePageRedirect?: (path: string) => void callback: (success: boolean) => void onMount?: () => void + handleFormValue?: (payload: object) => object } /** @@ -58,7 +62,7 @@ export interface CCMSProps { * - viewStep: 界面当前所在步骤 * - data: 各步骤数据 */ -interface CCMSState { +export interface CCMSState { realStep: number viewStep: number[] data: any[] @@ -67,7 +71,7 @@ interface CCMSState { /** * 页面组件 */ -export default class CCMS extends React.Component { +export default class CCMS1 extends React.Component { getStepComponent = (key: string) => StepComponents[key] /** @@ -236,7 +240,7 @@ export default class CCMS extends React.Component { loadDomain, handlePageRedirect } = this.props - + const handleFormValue = this.props.handleFormValue ? this.props.handleFormValue : (payload: object) => ({}) const { realStep, viewStep, @@ -256,7 +260,7 @@ export default class CCMS extends React.Component { // 调用UI渲染方法 return ( - + {this.renderComponent({ title, description, @@ -276,12 +280,13 @@ export default class CCMS extends React.Component { loadPageFrameURL, loadPageConfig, loadDomain, - handlePageRedirect + handlePageRedirect, + handleFormValue } - + const StepComponent = this.getStepComponent(currentStep.type) const children = ( - StepComponent ? : 您当前使用的UI版本没有实现{currentStep.type}步骤组件。 + StepComponent ? : 您当前使用的UI版本没有实现{currentStep.type}步骤组件。 ) return (
{children}
@@ -291,7 +296,7 @@ export default class CCMS extends React.Component { } })) })} -
+ ) } } diff --git a/src/steps/common.tsx b/src/steps/common.tsx index 88da0fd..863e59f 100644 --- a/src/steps/common.tsx +++ b/src/steps/common.tsx @@ -1,6 +1,9 @@ import React from 'react' import { CCMSConfig } from '../main' - +import {connect} from 'react-redux' +import { compose } from 'redux' +import { InterfaceState, PreloadedState } from '../store/store' +import { setFormValue } from '../store/reducers/formValue' /** * 页面流转步骤基类配置定义 * - type: 类型,对应各子类 @@ -33,16 +36,17 @@ export interface StepProps { baseRoute: string loadDomain: (domain: string) => Promise handlePageRedirect?: (path: string) => void + handleFormValue?: (payload: object) => object } /** * 页面步骤基类 */ -export default class Step extends React.Component, S> { - static defaultProps = { - config: { - } - }; + export default class Step extends React.Component, S> { + // static defaultProps = { // 暂时注释 + // config: { + // } + // }; stepPush = () => { this.props.onMount() @@ -60,3 +64,21 @@ export default class Step extends React.Component< return <> } } + +// const mapStateToProps = (state: PreloadedState) => { +// return { +// data: state.data.data, +// formValue: state.formValue.formValue +// } +// // return { +// // data: state.ccmsStore.data, +// // formValue: state.ccmsStore.formValue +// // } +// } +// const mapDispatchToProps = (dispatch: Function) => { +// return { +// handleFormValue: (payload: any):object => dispatch(setFormValue(payload)) +// } +// } +// connect(mapStateToProps, mapDispatchToProps)(Step) + diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index 3de7aef..e89edb3 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -10,8 +10,11 @@ import ConditionHelper, { ConditionConfig } from '../../util/condition' import StatementHelper, { StatementConfig } from '../../util/statement' import OperationHelper, { OperationConfig } from '../../util/operation' import fp from 'lodash/fp' -import { Map, List, getIn, setIn, updateIn, fromJS } from 'immutable' - +import produce from 'immer' +import { connect } from 'react-redux' +import { InterfaceState, PreloadedState } from '../../store/store' +import { setFormValue } from '../../store/reducers/formValue' +import StepComponentHOC from '../../HOC/stepComponentHOC' /** * 表单步骤配置文件格式定义 * - layout: 表单布局类型 @@ -154,7 +157,7 @@ export interface IFormItem { * 表单步骤组件 - 状态 * - formData: 表单的值 */ -interface FormState { +export interface FormState { ready: boolean formValue: { [field: string]: any } formData: { status: 'normal' | 'error' | 'loading', message?: string, name: string }[] @@ -163,7 +166,7 @@ interface FormState { /** * 表单步骤组件 */ -export default class FormStep extends Step { + const FormStepTemp = class FormStep extends Step { // ts对class的声明文件报错,临时解决 // 各表单项对应的类型所使用的UI组件的类 getALLComponents = (type: any): typeof Field => getALLComponents[type] OperationHelper = OperationHelper @@ -172,7 +175,6 @@ export default class FormStep extends Step { formFields: Array | null> = [] formFieldsMounted: Array = [] - // formValue: { [field: string]: any } = Map({}) formValue: { [field: string]: any } = {} formData: { status: 'normal' | 'error' | 'loading', message?: string, name: string }[] = [] canSubmit: boolean = false @@ -493,8 +495,7 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour super(props) this.state = { ready: false, - // formValue: {}, - formValue: Map({}), + formValue: {}, formData: [] } } @@ -514,7 +515,6 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour } = this.props this.formValue = {} - // this.formValue = Map({}) this.formData = [] if (this.props.config.defaultValue) { @@ -534,10 +534,13 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour for (const formFieldIndex in formFieldsConfig) { const formFieldConfig = formFieldsConfig[formFieldIndex] const value = getValue(formDefault, formFieldConfig.field) - - const fieldPathArr = formFieldConfig.field.split('.') + // this.formValue = setValue(this.formValue, formFieldConfig.field, value) - this.formValue = setIn(this.formValue, fieldPathArr, value) + console.log('this.formValue', this.formValue, formFieldConfig.field); + + this.formValue = produce(this.formValue, draft => { + setValue(draft, formFieldConfig.field, value) + }) this.formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } } } @@ -563,14 +566,16 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour if (formField) { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] const fieldPathArr = formFieldConfig.field.split('.') - // let value = getValue(this.formValue, formFieldConfig.field) - let value = getIn(this.formValue, fieldPathArr) + let value = getValue(this.formValue, formFieldConfig.field) + // let value = immuHelperX.$apply(this.formValue, formFieldConfig.field, (val:any)=>val) if ((formFieldConfig.defaultValue) && value === undefined) { value = await formField.reset() } value = await formField.set(value) // this.formValue = setValue(this.formValue, formFieldConfig.field, value) - this.formValue = setIn(this.formValue, fieldPathArr, value) + this.formValue = produce(this.formValue, draft => { + setValue(draft, formFieldConfig.field, value) + }) if (value !== undefined) { const validation = await formField.validate(value) @@ -697,22 +702,18 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour const fullPathArr = fullPath.split('.') + if(this.props.handleFormValue) { + this.props.handleFormValue({path: fullPath, value}) + } // set(this.formValue, fullPath, value) - // this.formValue = setIn(this.formValue, fullPathArr, value) - // this.setState({ - // formValue: this.formValue - // }) - this.setState(({formValue}) => { - // return {formValue: set(formValue, fullPath, value)} - // return {formValue: fp.update(fullPath, ()=> value, formValue)} - // return {formValue: setIn(this.formValue, fullPathArr, value)} - return {formValue: updateIn(formValue, fullPathArr, () => value)} + this.formValue = produce(this.formValue, draft => { + setValue(draft, fullPath, value) }) - var temp = [fullPathArr[0]] - this.formValue = updateIn(this.formValue, fullPathArr, () => value) - // this.setState(({formValue}) => ({formValue: this.formValue})) console.log('set--', this.formValue, fullPath, fullPathArr, value); + this.setState({ + formValue: this.formValue + }) if (this.props.onChange) { this.props.onChange(this.formValue) } @@ -725,9 +726,9 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour console.log('form set data', this.formData) - // await this.setState({ - // formData: cloneDeep(this.formData) - // }) + await this.setState({ + formData: cloneDeep(this.formData) + }) } } @@ -1022,8 +1023,8 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour } }} formLayout={layout} - // value={formFieldConfig.field !== undefined ? getValue(formValue, formFieldConfig.field) : undefined} - value={formFieldConfig.field !== undefined ? getIn(formValue, fieldPathArr) : undefined} + value={formFieldConfig.field !== undefined ? getValue(formValue, formFieldConfig.field) : undefined} + // value={formFieldConfig.field !== undefined ? immuHelperX.$apply(formValue, formFieldConfig.field, (v:any) => v) : undefined} // record={formValue.toJS()} record={formValue} // record={this.record_} @@ -1059,4 +1060,21 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour } } } +const mapStateToProps = (state: PreloadedState) => { + return { + data: state.data.data, + formValue: state.formValue.formValue + } +} +const mapDispatchToProps = (dispatch: Function) => { + return { + handleFormValue: (payload: any):object => dispatch(setFormValue(payload)) + } +} +const mergeProps = (stateProps:any, dispatchProps: any, ownProps: any) => Object.assign( + {}, stateProps, dispatchProps, ownProps +) + +const FormStep_ = connect(mapStateToProps, mapDispatchToProps, mergeProps)(FormStepTemp) +export default FormStep_ diff --git a/src/steps/table/index.tsx b/src/steps/table/index.tsx index 72111dc..18f421e 100644 --- a/src/steps/table/index.tsx +++ b/src/steps/table/index.tsx @@ -5,7 +5,7 @@ import getALLComponents, { ColumnConfigs } from '../../components/tableColumns' import Step, { StepConfig, StepProps } from '../common' import { ParamConfig } from '../../interface' import ColumnStyleComponent from './common/columnStyle' -import CCMS, { CCMSConfig } from '../../main' +import CCMS_123, { CCMSConfig } from '../../main' import { cloneDeep, get, set } from 'lodash' import InterfaceHelper, { InterfaceConfig } from '../../util/interface' import ConditionHelper, { ConditionConfig } from '../../util/condition' @@ -217,7 +217,7 @@ interface TableState { * 表格步骤组件 */ export default class TableStep extends Step { - CCMS = CCMS + CCMS_ = CCMS_123 getALLComponents = (type: any) => getALLComponents[type] interfaceHelper = new InterfaceHelper() /** @@ -660,7 +660,7 @@ export default class TableStep extends Step { }) } - const CCMS = this.CCMS + const CCMS = this.CCMS_ return ( diff --git a/src/store/common.tsx b/src/store/common.tsx new file mode 100644 index 0000000..c7e81da --- /dev/null +++ b/src/store/common.tsx @@ -0,0 +1,7 @@ +export declare interface actionInterface { + type: string + payload: { + path: string + value: any + } +} \ No newline at end of file diff --git a/src/store/index.tsx b/src/store/index.tsx new file mode 100644 index 0000000..9a3b2c8 --- /dev/null +++ b/src/store/index.tsx @@ -0,0 +1 @@ +export { default as store } from './store' \ No newline at end of file diff --git a/src/store/reducers/data.tsx b/src/store/reducers/data.tsx new file mode 100644 index 0000000..d278ade --- /dev/null +++ b/src/store/reducers/data.tsx @@ -0,0 +1,43 @@ +const SET_FULL_SCREEN = 'ccms/mode/SET_FULL_SCREEN'; +const SET_PLAYER = 'ccms/mode/SET_PLAYER'; + +const initialState = { + data: [] +}; + +const reducer = function (state: object, action: object) { + if (typeof state === 'undefined') state = initialState; + // switch (action.type) { + // case SET_FULL_SCREEN: + // return Object.assign({}, state, { + // isFullScreen: action.isFullScreen + // }); + // case SET_PLAYER: + // return Object.assign({}, state, { + // isPlayerOnly: action.isPlayerOnly, + // hasEverEnteredEditor: state.hasEverEnteredEditor || !action.isPlayerOnly + // }); + // default: + return state; + // } +}; + +// const setFullScreen = function (isFullScreen) { +// return { +// type: SET_FULL_SCREEN, +// isFullScreen: isFullScreen +// }; +// }; +// const setPlayer = function (isPlayerOnly) { +// return { +// type: SET_PLAYER, +// isPlayerOnly: isPlayerOnly +// }; +// }; + +export { + reducer as default, + initialState as dataInitialState, + // setFullScreen, + // setPlayer +}; diff --git a/src/store/reducers/formValue.tsx b/src/store/reducers/formValue.tsx new file mode 100644 index 0000000..ace1170 --- /dev/null +++ b/src/store/reducers/formValue.tsx @@ -0,0 +1,38 @@ +import produce from "immer"; +import { set } from 'lodash' +import { actionInterface } from '../common' + +const SET_FORM_VALUE = 'ccms/formValue/SET_FORM_VALUE'; + +const initialState = { + formValue: {}, +}; + + +const reducer = async function (state: object, action: actionInterface) { + const { payload } = action + if (typeof state === 'undefined' || !payload) state = initialState; + switch (payload && payload.value) { + case SET_FORM_VALUE: + set(state, payload.path, payload.value) + return Object.assign({}, state) + // const a = await produce(state, (draft) => { + + // }) + default: + return state; + } +}; + +const setFormValue = function (payload:{ path: string, value: any }):actionInterface { + return { + type: SET_FORM_VALUE, + payload + }; +}; + +export { + reducer as default, + initialState as formValueInitialState, + setFormValue +}; diff --git a/src/store/reducers/index.tsx b/src/store/reducers/index.tsx new file mode 100644 index 0000000..9ffdc7b --- /dev/null +++ b/src/store/reducers/index.tsx @@ -0,0 +1,2 @@ +export { default as dataReducer, dataInitialState} from './data' +export { default as formValueReducer, formValueInitialState } from './formValue' \ No newline at end of file diff --git a/src/store/store.tsx b/src/store/store.tsx new file mode 100644 index 0000000..8a0ec21 --- /dev/null +++ b/src/store/store.tsx @@ -0,0 +1,52 @@ +import { createStore, combineReducers, compose } from 'redux' +import { dataReducer, dataInitialState, formValueReducer, formValueInitialState } from './reducers' + +export interface InterfaceState { + data: object, + formValue: object +} + + +declare const $CombinedState: unique symbol +interface EmptyObject { + readonly [$CombinedState]?: undefined +} +type CombinedState = EmptyObject & S + +/** + * Recursively makes combined state objects partial. Only combined state _root + * objects_ (i.e. the generated higher level object with keys mapping to + * individual reducers) are partial. + */ +export type PreloadedState = Required extends EmptyObject + ? S extends CombinedState + ? { + [K in keyof S1]?: S1[K] extends object ? PreloadedState : S1[K] + } + : S + : { + [K in keyof S]: S[K] extends string | number | boolean | symbol + ? S[K] + : PreloadedState + } + + + + +const initialState: PreloadedState = { + // ccmsStore: { + // ...dataInitialState, + // ...formValueInitialState + // } + data: dataInitialState, + formValue: formValueInitialState +} +const reducers = { + data: dataReducer, + formValue: formValueReducer +} +// @ts-ignore +const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; +const reducers_ = combineReducers(reducers) +let store = createStore(reducers_, initialState, composeEnhancers()) +export default store \ No newline at end of file -- Gitee From 50d22c1efb8805a0b3bfabefe88f28117391c9db Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Fri, 7 Jan 2022 20:00:16 +0800 Subject: [PATCH 03/38] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8redux=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HOC/stepComponentHOC.jsx | 29 ------------------ src/main.tsx | 8 ++--- src/steps/common.tsx | 23 +------------- src/steps/form/index.tsx | 31 +++---------------- src/store/common.tsx | 7 ----- src/store/index.tsx | 1 - src/store/reducers/data.tsx | 43 -------------------------- src/store/reducers/formValue.tsx | 38 ----------------------- src/store/reducers/index.tsx | 2 -- src/store/store.tsx | 52 -------------------------------- 10 files changed, 8 insertions(+), 226 deletions(-) delete mode 100644 src/HOC/stepComponentHOC.jsx delete mode 100644 src/store/common.tsx delete mode 100644 src/store/index.tsx delete mode 100644 src/store/reducers/data.tsx delete mode 100644 src/store/reducers/formValue.tsx delete mode 100644 src/store/reducers/index.tsx delete mode 100644 src/store/store.tsx diff --git a/src/HOC/stepComponentHOC.jsx b/src/HOC/stepComponentHOC.jsx deleted file mode 100644 index 3f46d7d..0000000 --- a/src/HOC/stepComponentHOC.jsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react' -import {connect} from 'react-redux' -import { compose } from 'redux' -import { InterfaceState, PreloadedState } from '../store/store' -import { setFormValue } from '../store/reducers/formValue' - -const StepComponentHOC = function (WrappedComponent) { - class StepContainer extends React.Component { - render () { - console.log('props==', this.props); - return ( - WrappedComponent - ) - } - } - const mapStateToProps = (state) => { - return { - data: state.data.data, - formValue: state.formValue.formValue - } - } - const mapDispatchToProps = (dispatch) => { - return { - handleFormValue: () => dispatch(setFormValue(payload)) - } - } - return connect(mapStateToProps, mapDispatchToProps)(StepContainer) -} -export { StepComponentHOC as default } \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx index 0ab033d..86e32d1 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,12 +1,8 @@ import React, { forwardRef } from 'react' import marked from 'marked' -import { Provider, connect } from 'react-redux' import Step, { StepProps } from './steps/common' import StepComponents, { StepConfigs } from './steps' import { RichStringConfig } from './interface' -import { store } from './store' -import { compose } from 'redux' -import { InterfaceState, PreloadedState } from './store/store' /** * 页面配置文件格式定义 * - basic: 页面基本配置 @@ -260,7 +256,7 @@ export default class CCMS1 extends React.Component { // 调用UI渲染方法 return ( - + {this.renderComponent({ title, description, @@ -296,7 +292,7 @@ export default class CCMS1 extends React.Component { } })) })} - + ) } } diff --git a/src/steps/common.tsx b/src/steps/common.tsx index 863e59f..579e3e2 100644 --- a/src/steps/common.tsx +++ b/src/steps/common.tsx @@ -1,9 +1,6 @@ import React from 'react' import { CCMSConfig } from '../main' -import {connect} from 'react-redux' -import { compose } from 'redux' -import { InterfaceState, PreloadedState } from '../store/store' -import { setFormValue } from '../store/reducers/formValue' + /** * 页面流转步骤基类配置定义 * - type: 类型,对应各子类 @@ -64,21 +61,3 @@ export interface StepProps { return <> } } - -// const mapStateToProps = (state: PreloadedState) => { -// return { -// data: state.data.data, -// formValue: state.formValue.formValue -// } -// // return { -// // data: state.ccmsStore.data, -// // formValue: state.ccmsStore.formValue -// // } -// } -// const mapDispatchToProps = (dispatch: Function) => { -// return { -// handleFormValue: (payload: any):object => dispatch(setFormValue(payload)) -// } -// } -// connect(mapStateToProps, mapDispatchToProps)(Step) - diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index e89edb3..4a7e78c 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -10,11 +10,7 @@ import ConditionHelper, { ConditionConfig } from '../../util/condition' import StatementHelper, { StatementConfig } from '../../util/statement' import OperationHelper, { OperationConfig } from '../../util/operation' import fp from 'lodash/fp' -import produce from 'immer' -import { connect } from 'react-redux' -import { InterfaceState, PreloadedState } from '../../store/store' -import { setFormValue } from '../../store/reducers/formValue' -import StepComponentHOC from '../../HOC/stepComponentHOC' +import produce from 'immer' /** * 表单步骤配置文件格式定义 * - layout: 表单布局类型 @@ -157,7 +153,7 @@ export interface IFormItem { * 表单步骤组件 - 状态 * - formData: 表单的值 */ -export interface FormState { +interface FormState { ready: boolean formValue: { [field: string]: any } formData: { status: 'normal' | 'error' | 'loading', message?: string, name: string }[] @@ -166,7 +162,7 @@ export interface FormState { /** * 表单步骤组件 */ - const FormStepTemp = class FormStep extends Step { // ts对class的声明文件报错,临时解决 +export default class FormStep extends Step { // ts对class的声明文件报错,临时解决 // 各表单项对应的类型所使用的UI组件的类 getALLComponents = (type: any): typeof Field => getALLComponents[type] OperationHelper = OperationHelper @@ -1029,8 +1025,8 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour record={formValue} // record={this.record_} form={this} - // data={cloneDeep(data)} - data={this.data_} + data={cloneDeep(data)} + // data={this.data_} step={step} config={formFieldConfig} onChange={async (value: any) => { await this.handleChange(formFieldIndex, value) }} @@ -1060,21 +1056,4 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour } } } -const mapStateToProps = (state: PreloadedState) => { - return { - data: state.data.data, - formValue: state.formValue.formValue - } -} -const mapDispatchToProps = (dispatch: Function) => { - return { - handleFormValue: (payload: any):object => dispatch(setFormValue(payload)) - } -} -const mergeProps = (stateProps:any, dispatchProps: any, ownProps: any) => Object.assign( - {}, stateProps, dispatchProps, ownProps -) - -const FormStep_ = connect(mapStateToProps, mapDispatchToProps, mergeProps)(FormStepTemp) -export default FormStep_ diff --git a/src/store/common.tsx b/src/store/common.tsx deleted file mode 100644 index c7e81da..0000000 --- a/src/store/common.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export declare interface actionInterface { - type: string - payload: { - path: string - value: any - } -} \ No newline at end of file diff --git a/src/store/index.tsx b/src/store/index.tsx deleted file mode 100644 index 9a3b2c8..0000000 --- a/src/store/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default as store } from './store' \ No newline at end of file diff --git a/src/store/reducers/data.tsx b/src/store/reducers/data.tsx deleted file mode 100644 index d278ade..0000000 --- a/src/store/reducers/data.tsx +++ /dev/null @@ -1,43 +0,0 @@ -const SET_FULL_SCREEN = 'ccms/mode/SET_FULL_SCREEN'; -const SET_PLAYER = 'ccms/mode/SET_PLAYER'; - -const initialState = { - data: [] -}; - -const reducer = function (state: object, action: object) { - if (typeof state === 'undefined') state = initialState; - // switch (action.type) { - // case SET_FULL_SCREEN: - // return Object.assign({}, state, { - // isFullScreen: action.isFullScreen - // }); - // case SET_PLAYER: - // return Object.assign({}, state, { - // isPlayerOnly: action.isPlayerOnly, - // hasEverEnteredEditor: state.hasEverEnteredEditor || !action.isPlayerOnly - // }); - // default: - return state; - // } -}; - -// const setFullScreen = function (isFullScreen) { -// return { -// type: SET_FULL_SCREEN, -// isFullScreen: isFullScreen -// }; -// }; -// const setPlayer = function (isPlayerOnly) { -// return { -// type: SET_PLAYER, -// isPlayerOnly: isPlayerOnly -// }; -// }; - -export { - reducer as default, - initialState as dataInitialState, - // setFullScreen, - // setPlayer -}; diff --git a/src/store/reducers/formValue.tsx b/src/store/reducers/formValue.tsx deleted file mode 100644 index ace1170..0000000 --- a/src/store/reducers/formValue.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import produce from "immer"; -import { set } from 'lodash' -import { actionInterface } from '../common' - -const SET_FORM_VALUE = 'ccms/formValue/SET_FORM_VALUE'; - -const initialState = { - formValue: {}, -}; - - -const reducer = async function (state: object, action: actionInterface) { - const { payload } = action - if (typeof state === 'undefined' || !payload) state = initialState; - switch (payload && payload.value) { - case SET_FORM_VALUE: - set(state, payload.path, payload.value) - return Object.assign({}, state) - // const a = await produce(state, (draft) => { - - // }) - default: - return state; - } -}; - -const setFormValue = function (payload:{ path: string, value: any }):actionInterface { - return { - type: SET_FORM_VALUE, - payload - }; -}; - -export { - reducer as default, - initialState as formValueInitialState, - setFormValue -}; diff --git a/src/store/reducers/index.tsx b/src/store/reducers/index.tsx deleted file mode 100644 index 9ffdc7b..0000000 --- a/src/store/reducers/index.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export { default as dataReducer, dataInitialState} from './data' -export { default as formValueReducer, formValueInitialState } from './formValue' \ No newline at end of file diff --git a/src/store/store.tsx b/src/store/store.tsx deleted file mode 100644 index 8a0ec21..0000000 --- a/src/store/store.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { createStore, combineReducers, compose } from 'redux' -import { dataReducer, dataInitialState, formValueReducer, formValueInitialState } from './reducers' - -export interface InterfaceState { - data: object, - formValue: object -} - - -declare const $CombinedState: unique symbol -interface EmptyObject { - readonly [$CombinedState]?: undefined -} -type CombinedState = EmptyObject & S - -/** - * Recursively makes combined state objects partial. Only combined state _root - * objects_ (i.e. the generated higher level object with keys mapping to - * individual reducers) are partial. - */ -export type PreloadedState = Required extends EmptyObject - ? S extends CombinedState - ? { - [K in keyof S1]?: S1[K] extends object ? PreloadedState : S1[K] - } - : S - : { - [K in keyof S]: S[K] extends string | number | boolean | symbol - ? S[K] - : PreloadedState - } - - - - -const initialState: PreloadedState = { - // ccmsStore: { - // ...dataInitialState, - // ...formValueInitialState - // } - data: dataInitialState, - formValue: formValueInitialState -} -const reducers = { - data: dataReducer, - formValue: formValueReducer -} -// @ts-ignore -const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; -const reducers_ = combineReducers(reducers) -let store = createStore(reducers_, initialState, composeEnhancers()) -export default store \ No newline at end of file -- Gitee From bf46f801cdd2d3b0a5a9297ff123c63cc8e67321 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Tue, 11 Jan 2022 14:58:15 +0800 Subject: [PATCH 04/38] =?UTF-8?q?feat:=E6=95=B0=E6=8D=AE=E4=B8=8D=E5=8F=AF?= =?UTF-8?q?=E5=8F=98immer=E5=A4=84=E7=90=86=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/common.tsx | 41 +- src/components/formFields/form/index.tsx | 15 +- .../formFields/importSubform/index.tsx | 9 +- src/components/formFields/text/index.tsx | 6 +- src/steps/form/index.tsx | 377 ++---------------- src/util/param.ts | 4 +- src/util/produce.tsx | 55 +++ 7 files changed, 134 insertions(+), 373 deletions(-) create mode 100644 src/util/produce.tsx diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index f5ecdac..a85039a 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -5,8 +5,8 @@ import { FieldConfigs as getFieldConfigs } from './' import ParamHelper from '../../util/param' import { ConditionConfig } from '../../util/condition' import { StatementConfig } from '../../util/statement' -import { is } from 'immutable' - +import { isEqual } from 'lodash' + /** * 表单项基类配置文件格式定义 * - field: 表单项字段名 @@ -172,21 +172,36 @@ export class Field extends React.Component< 当前UI库未实现该表单类型 } - shouldComponentUpdate(nextProps= {} as any, nextState = {}) { - if (!is(nextProps.config, this.props.config) || !is(nextProps.value, this.props.value)) { - console.log('props-true'); - return true; - } - if (!is(this.state, nextState)) { - console.log('state-true'); - return true; + console.log('nextProps', nextProps, this.props); + //@ts-ignore + // if (!isEqual(this.state, nextState) || (window.needUpdatePath && window.needUpdatePath.indexOf(nextProps.path) != -1)) { + // return true + // } + // console.log('no update' ); + // return false + + if (isEqual(this.state, nextState) && isEqual(nextProps.config, this.props.config) && nextProps.value === this.props.value && nextProps.record === this.props.record && isEqual(nextProps.data, this.props.data)) { + if (nextProps.value === this.props.value) { + console.log(123, this.props.value); } - console.log('no update' ); - return false; - } + } + return true; + + + // if (is(nextProps.value, this.props.value)) { + // console.log('=is=', nextProps.value, this.props.value); + // } + + // if (!isEqual(this.state, nextState) || !isEqual(nextProps.value, this.props.value) || !isEqual(nextProps.record, this.props.record) || !isEqual(nextProps.config, this.props.config) || !isEqual(nextProps.data, this.props.data)) { + // return true; + // } + // console.log('no update' ); + // return false; +} + render = () => { return ( 当前UI库未实现该表单类型 diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index c32ab6c..c1a16d0 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -2,7 +2,8 @@ import React from 'react' import { Field, FieldConfig, FieldConfigs, FieldError, FieldProps, IField } from '../common' import getALLComponents from '../' import { getValue, listItemMove, setValue, getBoolean, getChainPath } from '../../../util/value' -import { cloneDeep } from 'lodash' +// import { cloneDeep } from 'lodash' +import { cloneDeep } from '../../../util/produce' import ConditionHelper from '../../../util/condition' import StatementHelper from '../../../util/statement' @@ -235,8 +236,8 @@ export default class FormField extends Field implements IField { @@ -415,8 +416,8 @@ export default class ImportSubformField extends Field await this.props.onValueSet('', value, await this.validate(value)) + onChange: async (value: string) => { + //@ts-ignore + window.needUpdatePath = this.props.path + return await this.props.onValueSet('', value, await this.validate(value)) + } })} ) diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index 4a7e78c..74c5ced 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -5,7 +5,8 @@ import getALLComponents from '../../components/formFields' import { getValue, setValue, listItemMove, getBoolean, getChainPath } from '../../util/value' import { ParamConfig } from '../../interface' import ParamHelper from '../../util/param' -import { cloneDeep, get, set, unset, update } from 'lodash' +import { get, set, unset, update } from 'lodash' +import { cloneDeep, splice, sort } from '../../util/produce' import ConditionHelper, { ConditionConfig } from '../../util/condition' import StatementHelper, { StatementConfig } from '../../util/statement' import OperationHelper, { OperationConfig } from '../../util/operation' @@ -175,313 +176,6 @@ export default class FormStep extends Step { // ts对clas formData: { status: 'normal' | 'error' | 'loading', message?: string, name: string }[] = [] canSubmit: boolean = false submitData: object = {} - record_:object = { - "pageFormData": { - "dataAssociation": { - "sourceMaterial": { - "fields": [ - { - "label": "上提12", - "field": "liftUp", - "type": "switch", - "extra": { - "statement": "", - "params": [] - }, - "valueTrue": true, - "valueFalse": false, - "defaultValue": { - "source": "static", - "value": false - }, - "required": true, - "condition": { - "params": [] - } - }, - { - "label": "上提楼层尾icon-短文本链接", - "field": "upTailIcon", - "type": "text", - "extra": { - "params": [] - }, - "placeholder": "请输入尾icon地址", - "regExp": {}, - "defaultValue": { - "source": "static", - "value": "" - }, - "required": true, - "condition": { - "params": [ - { - "field": "upward", - "data": { - "source": "record", - "field": "material.liftUp" - } - } - ], - "template": "${upward} === true" - } - }, - { - "label": "尾icon高度-数值", - "field": "upTailIconHight", - "type": "number", - "extra": { - "params": [] - }, - "precision": 0, - "step": 1, - "max": 120, - "regExp": {}, - "defaultValue": { - "source": "static", - "value": 0 - }, - "required": true, - "condition": { - "params": [ - { - "field": "upward", - "data": { - "source": "record", - "field": "material.liftUp" - } - } - ], - "template": "${upward} === true" - } - }, - { - "label": "上提楼层头icon-短文本", - "field": "upHeadIcon", - "type": "text", - "extra": { - "params": [] - }, - "placeholder": "请输入头icon地址", - "cjkLength": 2, - "regExp": {}, - "defaultValue": { - "source": "static", - "value": "" - }, - "required": true, - "condition": { - "params": [ - { - "field": "upward", - "data": { - "source": "record", - "field": "material.liftUp" - } - } - ], - "template": "${upward} === true" - } - }, - { - "label": "业务标题-短文本", - "field": "title", - "type": "text", - "extra": { - "params": [] - }, - "placeholder": "请输入展示文案", - "maxLength": 12, - "minLength": null, - "cjkLength": 2, - "regExp": { - "expression": "", - "message": "业务标题重复" - }, - "defaultValue": { - "source": "static", - "value": "" - }, - "required": true, - "condition": { - "params": [] - } - }, - { - "label": "业务标题色值", - "field": "titleColor", - "type": "color", - "extra": { - "params": [] - }, - "defaultValue": { - "source": "static", - "value": "#ffffff" - }, - "required": true, - "condition": { - "params": [ - { - "field": "upward", - "data": { - "source": "record", - "field": "material.liftUp" - } - } - ], - "template": "${upward} === true" - } - }, - { - "label": "业务副标题-文本1", - "field": "subTitle", - "type": "text", - "extra": { - "params": [] - }, - "placeholder": "请输入展示文案", - "maxLength": 16, - "minLength": null, - "cjkLength": 2, - "regExp": { - "expression": "", - "message": "文案超过8个字" - }, - "defaultValue": { - "source": "static", - "value": "" - }, - "required": true, - "condition": { - "params": [] - } - }, - { - "label": "业务副标题色值", - "field": "subtitleColor", - "type": "color", - "extra": { - "params": [] - }, - "defaultValue": { - "source": "static", - "value": "" - }, - "required": true, - "condition": { - "params": [ - { - "field": "upward", - "data": { - "source": "record", - "field": "material.liftUp" - } - } - ], - "template": "${upward} === true " - } - }, - { - "label": "icon图片", - "field": "icon", - "type": "upload", - "extra": { - "statement": "icon尺寸33x44,支持png格式,50K以内", - "params": [] - }, - "interface": { - "domain": "jdg", - "url": "/upload/imageUpload", - "urlParams": [], - "method": "POST", - "contentType": "json", - "withCredentials": true, - "params": [], - "data": [], - "condition": { - "enable": true, - "success": {}, - "fail": {} - }, - "response": [ - { - "path": "data" - } - ], - "cache": {} - }, - "requireField": "file", - "mode": "image", - "sizeCheck": { - "maxSize": 50, - "sizeUnit": "K", - "height": null, - "width": null - }, - "defaultValue": { - "source": "static", - "value": "" - }, - "required": true, - "condition": { - "params": [], - "template": "" - } - }, - { - "label": "背景颜色-取色器", - "field": "bgColor", - "type": "color", - "extra": { - "params": [] - }, - "defaultValue": { - "source": "static", - "value": "#ffffff" - }, - "required": true, - "condition": { - "params": [ - { - "field": "upward", - "data": { - "source": "record", - "field": "material.liftUp" - } - } - ], - "template": "${upward} === true" - } - }, - { - "label": "跳转链接", - "field": "jumpUrl", - "type": "text", - "extra": { - "statement": "1、跳转地址必须经西格玛审核; 2、跳转地址需在APP白名单中,不在可找商详技术处理", - "params": [] - }, - "placeholder": "请输入跳转链接", - "regExp": { - "expression": "(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\'\\/\\\\\\+&%$#_]*)?", - "message": "请输入正确格式" - }, - "defaultValue": { - "source": "static", - "value": "" - }, - "required": true, - "condition": { - "params": [], - "template": "" - } - } - ] - } - } - } -} -data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sourceMaterial.fields"],"defaultValue":{"source":"step","field":"data","step":1,"unstringify":["data.pageFormData.dataAssociation.sourceMaterial.field"]},"businessSuffix":"","unstringify":["pageFormData.dataAssociation.sourceMaterial.fields"],"version":"1.0.0","subversion":"0","fields":[{"canInsert":true,"canSort":true,"canRemove":true,"label":"字段设置","primaryField":"label","fields":[{"label":"字段描述","field":"label","type":"text"},{"label":"字段名","field":"field","type":"text"},{"field":"","label":"","type":"import_subform","interface":{"url":"https://storage.jd.com/swm-plus/prod-floor-fields/config/form/index.json","urlParams":[],"method":"GET"},"defaultValue":{"source":"record","field":""}}],"field":"pageFormData.dataAssociation.sourceMaterial.fields","type":"form","canCollapse":true}],"type":"form","applicationName":"example","actions":[{"type":"ccms","mode":"primary","label":"保存并发布","callback":{"type":"cancel"},"handle":{"type":"ccms","page":822,"mode":"popup","label":"","params":[{"field":"systemId","data":{"source":"record","value":"create","field":"systemId"}},{"field":"type","data":{"source":"record","field":"type"}},{"field":"appName","data":{"source":"record","field":"appName"}},{"field":"pageFormData","data":{"source":"record","field":"pageFormData"}},{"data":{"source":"static","value":1},"field":"saveAndPublish"},{"field":"templateUseType","data":{"source":"step","value":1,"field":"data.jdgBusiFloor.templateUseType","step":1}},{"field":"id","data":{"source":"record","field":"jdgBusiFloor.id"}}]},"condition":{"debug":true}},{"type":"submit","mode":"primary","label":"保存为草稿","callback":{"type":"none"},"handle":{"type":"ccms"},"condition":{"params":[]}}]},"fields":[{"canInsert":true,"canSort":true,"defaultValue":{"source":"static","value":""},"canRemove":true,"label":"字段设置","primaryField":"label","fields":[{"label":"字段描述","field":"label","type":"text"},{"label":"字段名","field":"field","type":"text"},{"field":"","label":"","type":"import_subform","interface":{"url":"https://storage.jd.com/swm-plus/prod-floor-fields/config/form/index.json","urlParams":[],"method":"GET"},"defaultValue":{"source":"record","field":""}}],"field":"pageFormData.dataAssociation.sourceMaterial.fields","type":"form","canCollapse":true}],"stringify":["pageFormData.dataAssociation.sourceMaterial.fields"],"actions":[{"type":"ccms","mode":"primary","label":"保存并发布","callback":{"type":"cancel"},"handle":{"type":"ccms","page":822,"mode":"popup","label":"","params":[{"field":"systemId","data":{"source":"record","value":"create","field":"systemId"}},{"field":"type","data":{"source":"record","field":"type"}},{"field":"appName","data":{"source":"record","field":"appName"}},{"field":"pageFormData","data":{"source":"record","field":"pageFormData"}},{"data":{"source":"static","value":1},"field":"saveAndPublish"},{"field":"templateUseType","data":{"source":"step","value":1,"field":"data.jdgBusiFloor.templateUseType","step":1}},{"field":"id","data":{"source":"record","field":"jdgBusiFloor.id"}}]},"condition":{"debug":true}},{"type":"submit","mode":"primary","label":"保存为草稿","callback":{"type":"none"},"handle":{"type":"ccms"},"condition":{"params":[]}}],"applicationName":"example","businessSuffix":"","version":"1.0.0","subversion":"0"}] /** * 初始化表单的值 @@ -531,12 +225,7 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour const formFieldConfig = formFieldsConfig[formFieldIndex] const value = getValue(formDefault, formFieldConfig.field) - // this.formValue = setValue(this.formValue, formFieldConfig.field, value) - console.log('this.formValue', this.formValue, formFieldConfig.field); - - this.formValue = produce(this.formValue, draft => { - setValue(draft, formFieldConfig.field, value) - }) + this.formValue = setValue(this.formValue, formFieldConfig.field, value) this.formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } } } @@ -568,10 +257,7 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour value = await formField.reset() } value = await formField.set(value) - // this.formValue = setValue(this.formValue, formFieldConfig.field, value) - this.formValue = produce(this.formValue, draft => { - setValue(draft, formFieldConfig.field, value) - }) + this.formValue = setValue(this.formValue, formFieldConfig.field, value) if (value !== undefined) { const validation = await formField.validate(value) @@ -695,30 +381,27 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] if (formFieldConfig) { const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - - const fullPathArr = fullPath.split('.') - - if(this.props.handleFormValue) { + + if(this.props.handleFormValue) { this.props.handleFormValue({path: fullPath, value}) } // set(this.formValue, fullPath, value) - this.formValue = produce(this.formValue, draft => { - setValue(draft, fullPath, value) - }) - console.log('set--', this.formValue, fullPath, fullPathArr, value); - this.setState({ + this.formValue = cloneDeep(this.formValue, 'set', fullPath, value) + console.log('test--->set--', this.formValue, fullPath, value); + this.setState(({formValue})=>({ 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 } - // } + if (validation === true) { + this.formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } + } else { + this.formData[formFieldIndex] = { status: 'error', message: validation[0].message, name: formFieldConfig.label } + } console.log('form set data', this.formData) @@ -759,9 +442,10 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` let list = get(this.formValue, fullPath, []) - if (!Array.isArray(list)) list = [] - list.push(value) - set(this.formValue, fullPath, list) + console.log('list---', list, value); + let cloneList = cloneDeep(list,'push', fullPath, value) + // set(this.formValue, fullPath, list) + this.formValue = cloneDeep(this.formValue, 'set', fullPath, cloneList) this.setState({ formValue: this.formValue }) @@ -787,8 +471,9 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` const list = get(this.formValue, fullPath, []) - list.splice(index, count) - set(this.formValue, fullPath, list) + const cloneList = splice(list, index, count) + // set(this.formValue, fullPath, list) + this.formValue = cloneDeep(this.formValue, 'set', fullPath, cloneList) this.setState({ formValue: this.formValue }) @@ -813,8 +498,10 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour 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) + // const list = listItemMove(get(this.formValue, fullPath, []), index, sortType) + const list = sort(get(this.formValue, fullPath, []), index, sortType) + // set(this.formValue, fullPath, list) + this.formValue = cloneDeep(this.formValue, 'set', fullPath, list) this.setState({ formValue: this.formValue }) @@ -1019,18 +706,16 @@ data_: any = [{"type":"form","":{"stringify":["pageFormData.dataAssociation.sour } }} formLayout={layout} - value={formFieldConfig.field !== undefined ? getValue(formValue, formFieldConfig.field) : undefined} - // value={formFieldConfig.field !== undefined ? immuHelperX.$apply(formValue, formFieldConfig.field, (v:any) => v) : undefined} - // record={formValue.toJS()} - record={formValue} - // record={this.record_} + value={formFieldConfig.field !== undefined ? cloneDeep(getValue(formValue, formFieldConfig.field)) : undefined} + record={cloneDeep(formValue)} form={this} data={cloneDeep(data)} - // data={this.data_} step={step} + // stepValue={cloneDeep(formValue)} config={formFieldConfig} onChange={async (value: any) => { await this.handleChange(formFieldIndex, value) }} onValueSet={async (path, value, validation) => await this.handleValueSet(formFieldIndex, path, value, validation)} + // onDidMountSet 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)} diff --git a/src/util/param.ts b/src/util/param.ts index 0742e6b..cbe4e5a 100644 --- a/src/util/param.ts +++ b/src/util/param.ts @@ -2,7 +2,7 @@ import { get, set } from "lodash" import qs from "query-string" import { ParamConfig } from "../interface"; -export default function ParamHelper ( config: ParamConfig, datas: { record?: object, data: object[], step: number }) { +export default function ParamHelper ( config: ParamConfig, datas: { record?: object, data: object[], step: number }) { // step--> stepValue switch (config.source) { case 'record': if (datas.record) { @@ -18,7 +18,7 @@ export default function ParamHelper ( config: ParamConfig, datas: { record?: obj if (config.field === '') { return datas.data[datas.step] } else { - return get(datas.data[datas.step], config.field) + return get(datas.data[datas.step], config.field) //return get(stepValue, config.field) } } break diff --git a/src/util/produce.tsx b/src/util/produce.tsx new file mode 100644 index 0000000..4f077e3 --- /dev/null +++ b/src/util/produce.tsx @@ -0,0 +1,55 @@ +import produce, { setAutoFreeze, original } from 'immer' +import lodash from 'lodash' +import { listItemMove } from '../util/value' + +type OperationType = 'set' | 'push' | 'splice' +type FormValue = { [field: string]: any } +type FormData = { status: 'normal' | 'error' | 'loading', message?: string, name: string }[] +type FormDataList = { status: 'normal' | 'error' | 'loading', message?: string }[][] +type Data = any[] +type Data_ = Data | FormData | FormValue | FormDataList +setAutoFreeze(false) + +/** + * immer使用produce的封装 + * @param current 当前数据 + * @param operationType 修改方法,只读项没必要用,对应lodash的操作方法 + * @param path lodash链式路径 + * @param value 要修改为的值 + * @returns 修改后数据 + */ + export const cloneDeep = (current: any, operationType?: OperationType, path?: string, value?: any) => { + if (!operationType) return current // 注意这里没有深拷贝,只有在修改时才使用immer的api + let target = produce(current, (draft: any) => { + if (!path) path='' + // const method = lodash[operationType] + // @ts-ignore + // method(draft, path, value) // 写return method(draft, path, value)会卡顿 + switch (operationType) { + case 'set': + return lodash.set(draft, path, value) + break + // case 'get': + // return lodash.get(draft, path, value) + // break + case 'push': + return lodash.concat(draft, value) + break + } + }) + return target +} + +export const splice = (current: any, index:number, count:number) => { + let target = produce(current, (draft: any)=>{ + draft.splice(index, count) + }) + return target +} + +export const sort = (current: any, index: number, sortType: 'up' | 'down') => { + let target = produce(current, (draft: any)=>{ + return listItemMove(draft, index, sortType) + }) + return target +} \ No newline at end of file -- Gitee From ac656f118c5c262c7fcdae17d26400addc561a44 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Tue, 11 Jan 2022 17:26:10 +0800 Subject: [PATCH 05/38] =?UTF-8?q?fix:immer=E4=BF=AE=E6=94=B9=E5=BD=B1?= =?UTF-8?q?=E5=93=8D=E5=88=B0=E5=BA=8F=E5=88=97=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/steps/form/index.tsx | 6 +++--- src/util/produce.tsx | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index 74c5ced..f4699ca 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -2,11 +2,12 @@ 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, listItemMove, getBoolean, getChainPath } from '../../util/value' +// import { getValue, setValue, listItemMove, getBoolean, getChainPath } from '../../util/value' +import { getValue, listItemMove, getBoolean, getChainPath } from '../../util/value' import { ParamConfig } from '../../interface' import ParamHelper from '../../util/param' import { get, set, unset, update } from 'lodash' -import { cloneDeep, splice, sort } from '../../util/produce' +import { cloneDeep, splice, sort, setValue } from '../../util/produce' import ConditionHelper, { ConditionConfig } from '../../util/condition' import StatementHelper, { StatementConfig } from '../../util/statement' import OperationHelper, { OperationConfig } from '../../util/operation' @@ -252,7 +253,6 @@ export default class FormStep extends Step { // ts对clas const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] const fieldPathArr = formFieldConfig.field.split('.') let value = getValue(this.formValue, formFieldConfig.field) - // let value = immuHelperX.$apply(this.formValue, formFieldConfig.field, (val:any)=>val) if ((formFieldConfig.defaultValue) && value === undefined) { value = await formField.reset() } diff --git a/src/util/produce.tsx b/src/util/produce.tsx index 4f077e3..9a75f7a 100644 --- a/src/util/produce.tsx +++ b/src/util/produce.tsx @@ -52,4 +52,39 @@ export const sort = (current: any, index: number, sortType: 'up' | 'down') => { return listItemMove(draft, index, sortType) }) return target +} + +const merge = (a: any, b: any): any => { + return lodash.assignInWith(a, b, (a, b) => { + if (lodash.isUndefined(a) && lodash.isArray(b)) { + a = [] + } + if (lodash.isObject(b)) { + if (lodash.isArray(a)) { + return merge(a, b).filter((i: any) => i !== undefined) + } else { + return merge(a, b) + } + } + }) +} + +export const setValue = (obj: any, path: string = '', value: any) => { + let target = produce(obj, (draft: any) => { + if (path === '') { + if (Object.prototype.toString.call(value) === '[object Object]') { + draft = merge(draft, value) + } else if (value !== undefined) { + draft = value + } + } else { + const source = lodash.get(draft, path) + if (Object.prototype.toString.call(value) === '[object Object]' && Object.prototype.toString.call(source) === '[object Object]') { + lodash.set(draft, path, merge(source, value)) + } else { + lodash.set(draft, path, value) + } + } + }) + return target } \ No newline at end of file -- Gitee From 031a53eba304ece5d3ab58b55e9257bedd41ea27 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Fri, 14 Jan 2022 15:30:00 +0800 Subject: [PATCH 06/38] =?UTF-8?q?feat:=20=E7=BB=84=E4=BB=B6=E6=8C=82?= =?UTF-8?q?=E8=BD=BDstep=E4=B8=BAformValue=E7=9A=84=E5=80=BC=E3=80=81?= =?UTF-8?q?=E4=B8=8A=E6=8A=A5condition=E4=BE=9D=E8=B5=96=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/detail/common.tsx | 3 +- src/components/formFields/common.tsx | 49 ++++++------ src/components/formFields/form/index.tsx | 80 +++++++++++++------ .../formFields/importSubform/index.tsx | 21 ++++- src/components/formFields/text/index.test.tsx | 4 +- src/components/formFields/text/index.tsx | 7 +- .../formFields/treeSelect/index.tsx | 2 +- .../tableColumns/enum/index.test.tsx | 3 +- src/interface.ts | 4 +- src/main.tsx | 3 +- src/steps/common.tsx | 3 +- src/steps/detail/index.tsx | 3 +- src/steps/fetch/index.tsx | 2 +- src/steps/filter/index.tsx | 3 +- src/steps/form/index.tsx | 39 +++++---- src/steps/skip/index.tsx | 6 +- src/steps/table/index.tsx | 8 +- src/util/condition.ts | 10 ++- src/util/interface.ts | 14 ++-- src/util/operation.tsx | 11 +-- src/util/param.ts | 10 +-- src/util/produce.tsx | 9 ++- src/util/statement.ts | 8 +- src/util/value.ts | 6 +- 24 files changed, 187 insertions(+), 121 deletions(-) diff --git a/src/components/detail/common.tsx b/src/components/detail/common.tsx index a112c87..9985d6d 100644 --- a/src/components/detail/common.tsx +++ b/src/components/detail/common.tsx @@ -73,7 +73,8 @@ export interface DetailFieldProps { value: T, record: { [field: string]: any }, data: any[], - step: number, + step: { [field: string]: any } // formValue挂载 + // step: number, config: C // TODO 待删除 onChange: (value: T) => Promise diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index a85039a..1d870ed 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -5,7 +5,7 @@ import { FieldConfigs as getFieldConfigs } from './' import ParamHelper from '../../util/param' import { ConditionConfig } from '../../util/condition' import { StatementConfig } from '../../util/statement' -import { isEqual } from 'lodash' +import { isEqual, get } from 'lodash' /** * 表单项基类配置文件格式定义 @@ -78,7 +78,7 @@ export interface FieldProps { value: T, record: { [field: string]: any }, data: any[], - step: number, + // step: number, config: C // TODO 待删除 onChange: (value: T) => Promise @@ -94,6 +94,7 @@ export interface FieldProps { onValueListSort: (path: string, index: number, sortType: 'up' | 'down', validation: true | FieldError[]) => Promise baseRoute: string, path: string, // 组件所在路径以字段拼接展示 + step: { [field: string]: any } // 传递formValue loadDomain: (domain: string) => Promise } @@ -172,34 +173,32 @@ export class Field extends React.Component< 当前UI库未实现该表单类型 } - shouldComponentUpdate(nextProps= {} as any, nextState = {}) { - console.log('nextProps', nextProps, this.props); - //@ts-ignore - // if (!isEqual(this.state, nextState) || (window.needUpdatePath && window.needUpdatePath.indexOf(nextProps.path) != -1)) { - // return true - // } - // console.log('no update' ); - // return false - - if (isEqual(this.state, nextState) && isEqual(nextProps.config, this.props.config) && nextProps.value === this.props.value && nextProps.record === this.props.record && isEqual(nextProps.data, this.props.data)) { - if (nextProps.value === this.props.value) { - console.log(123, this.props.value); + dependentFieldsArr: any + shouldComponentUpdate(nextProps:FieldProps, nextState: S) { + console.log('nextProps', nextProps, this.props, nextProps.value == this.props.value); + console.log('this.dependentFieldsArr',this.dependentFieldsArr); + const dependentFieldsArr = this.dependentFieldsArr + let dependentIsChange = false + if (dependentFieldsArr) { + for (let i=0;i< dependentFieldsArr.length;i++) { + const nextDependentField = get(nextProps.step, dependentFieldsArr[i]) + const currentDependentField = get(this.props.step, dependentFieldsArr[i]) + if (nextDependentField !== currentDependentField) { + dependentIsChange = true + break + } + } } + +/** + * config受value影响变化 ,data提交前不变, 去掉这两项的比较 + * record也不比较,需要比较的话就在dependentFieldsArr取出record绝对路径 + * */ + if (!dependentIsChange && isEqual(this.state, nextState) && nextProps.value === this.props.value) { console.log('no update' ); return false; } return true; - - - // if (is(nextProps.value, this.props.value)) { - // console.log('=is=', nextProps.value, this.props.value); - // } - - // if (!isEqual(this.state, nextState) || !isEqual(nextProps.value, this.props.value) || !isEqual(nextProps.record, this.props.record) || !isEqual(nextProps.config, this.props.config) || !isEqual(nextProps.data, this.props.data)) { - // return true; - // } - // console.log('no update' ); - // return false; } render = () => { diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index c1a16d0..3fd3abf 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -1,9 +1,10 @@ import React from 'react' import { Field, FieldConfig, FieldConfigs, FieldError, FieldProps, IField } from '../common' import getALLComponents from '../' -import { getValue, listItemMove, setValue, getBoolean, getChainPath } from '../../../util/value' +// import { getValue, listItemMove, setValue, getBoolean, getChainPath } from '../../../util/value' // import { cloneDeep } from 'lodash' -import { cloneDeep } from '../../../util/produce' +import { getValue, getBoolean, getChainPath } from '../../../util/value' +import { cloneDeep, setValue , sort, splice} from '../../../util/produce' import ConditionHelper from '../../../util/condition' import StatementHelper from '../../../util/statement' @@ -67,6 +68,7 @@ export default class FormField extends Field | null>> = [] formFieldsMountedList: Array> = [] + dependentFieldsArr: string[] = [] //condition中依赖字段的存放数组 constructor (props: FieldProps) { super(props) @@ -214,15 +216,17 @@ export default class FormField extends Field { if (!this.formFieldsMountedList[index]) { - this.formFieldsMountedList[index] = [] + // this.formFieldsMountedList[index] = [] + cloneDeep(this.formFieldsMountedList, 'set', `[${index}]`, []) } if (this.formFieldsMountedList[index][formFieldIndex]) { return true } - this.formFieldsMountedList[index][formFieldIndex] = true + // this.formFieldsMountedList[index][formFieldIndex] = true + this.formFieldsMountedList = cloneDeep(this.formFieldsMountedList, 'set', `[${index}][${formFieldIndex}]`, true) - const formDataList = cloneDeep(this.state.formDataList) - if (!formDataList[index]) formDataList[index] = [] + let formDataList = cloneDeep(this.state.formDataList) + if (!formDataList[index]) formDataList = cloneDeep(formDataList, 'set', `[${index}]`, []) if (this.formFieldsList[index] && this.formFieldsList[index][formFieldIndex]) { const formField = this.formFieldsList[index][formFieldIndex] @@ -261,38 +265,46 @@ export default class FormField extends Field { const index = (this.props.value || []).length - const formDataList = cloneDeep(this.state.formDataList) - formDataList[index] = [] + const formDataList = cloneDeep(this.state.formDataList, 'set', `[${index}]`, []) this.setState({ formDataList }) - this.formFieldsList[index] = [] - this.formFieldsMountedList[index] = [] + // this.formFieldsList[index] = [] + this.formFieldsList = cloneDeep(this.formFieldsList, 'set', `${index}`, []) + // this.formFieldsMountedList[index] = [] + this.formFieldsMountedList = cloneDeep(this.formFieldsMountedList, 'set', `${index}`, []) await this.props.onValueListAppend('', this.props.config.initialValues === undefined ? {} : cloneDeep(this.props.config.initialValues), true) } handleRemove = async (index: number) => { - const formDataList = cloneDeep(this.state.formDataList) - formDataList.splice(index, 1) + // const formDataList = cloneDeep(this.state.formDataList) + const formDataList = splice(this.state.formDataList, index, 1) this.setState({ + //@ts-ignore formDataList }) - - this.formFieldsList.splice(index, 1) - this.formFieldsMountedList.splice(index, 1) - + // this.formFieldsList.splice(index, 1) + //@ts-ignore + this.formFieldsList = splice(this.formFieldsList,index, 1) + // this.formFieldsMountedList.splice(index, 1) + //@ts-ignore + this.formFieldsMountedList = splice(this.formFieldsMountedList,index, 1) await this.props.onValueListSplice('', index, 1, true) } handleSort = async (index: number, sortType: 'up' | 'down') => { - const formDataList = listItemMove(cloneDeep(this.state.formDataList), index, sortType) + var list = cloneDeep(this.state.formDataList) + let formDataList = sort(list, index, sortType) this.setState({ - formDataList + //@ts-ignore + formDataList: formDataList }) - this.formFieldsList = listItemMove(this.formFieldsList, index, sortType) - this.formFieldsMountedList = listItemMove(this.formFieldsMountedList, index, sortType) + //@ts-ignore + this.formFieldsList = sort(this.formFieldsList, index, sortType) + //@ts-ignore + this.formFieldsMountedList = sort(this.formFieldsMountedList, index, sortType) await this.props.onValueListSort('', index, sortType, true) } @@ -494,9 +506,23 @@ export default class FormField extends Field await this.handleSort(index, sortType) : undefined, canCollapse, children: (fields || []).map((formFieldConfig, fieldIndex) => { + const conditionParams = formFieldConfig.condition?.params + if (conditionParams && Array.isArray(conditionParams)) { + const dependentFieldsArr = conditionParams.map(ite => { + if (ite.data?.source === 'record') { + return ite?.data?.field && `${this.props.path}.${ite.data.field}` + } else if (ite.data?.source === 'data' || ite.data?.source === 'step') { + return ite?.data?.field && `${ite.data.field}` + } + return '' + }).filter(ite=>ite) + this.dependentFieldsArr = dependentFieldsArr + console.log('this.dependentFieldsArr--formList', this.dependentFieldsArr); + } 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 + // if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = cloneDeep(this.formFieldsMountedList, 'set', `${index}`, [] ) + // this.formFieldsMountedList[index][fieldIndex] = false + this.formFieldsMountedList = cloneDeep(this.formFieldsMountedList, 'set', `${[index]}.${fieldIndex}`, false) return null } const FormField = this.getALLComponents(formFieldConfig.type) || Field @@ -523,8 +549,9 @@ export default class FormField extends Field | null) => { if (fieldRef) { - if (!this.formFieldsList[index]) this.formFieldsList[index] = [] - this.formFieldsList[index][fieldIndex] = fieldRef + if (!this.formFieldsList[index]) this.formFieldsList = cloneDeep(this.formFieldsList, 'set', `[${index}]`, []) + // this.formFieldsList[index][fieldIndex] = fieldRef + this.formFieldsList = cloneDeep(this.formFieldsList, 'set', `[${index}][${fieldIndex}]`, fieldRef) this.handleMount(index, fieldIndex) } }} @@ -532,8 +559,9 @@ export default class FormField extends Field this.handleChange(index, fieldIndex, value)} onValueSet={async (path, value, validation) => this.handleValueSet(index, fieldIndex, path, value, validation)} @@ -543,7 +571,7 @@ export default class FormField extends Field await this.handleValueListSort(index, fieldIndex, path, _index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} - path={getChainPath(formFieldConfig.field, this.props.path)} + path={getChainPath(`${fieldIndex}.${formFieldConfig.field}`, this.props.path)} /> ) }) diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx index 9042cb0..eecdbc4 100644 --- a/src/components/formFields/importSubform/index.tsx +++ b/src/components/formFields/importSubform/index.tsx @@ -1,11 +1,12 @@ import React from 'react' -import { setValue, getValue, getBoolean, getChainPath } from '../../../util/value' +// import { setValue, getValue, getBoolean, getChainPath } from '../../../util/value' +import { getValue, getBoolean, getChainPath } from '../../../util/value' import { Field, FieldConfig, FieldError, FieldProps, IField } from '../common' import getALLComponents, { FieldConfigs } from '../' import { IFormItem } from '../../../steps/form' // import { cloneDeep } from 'lodash' -import { cloneDeep } from '../../../util/produce' +import { cloneDeep, setValue } from '../../../util/produce' import ConditionHelper from '../../../util/condition' import InterfaceHelper, { InterfaceConfig } from '../../../util/interface' import StatementHelper from '../../../util/statement' @@ -370,6 +371,19 @@ export default class ImportSubformField extends Field { + const conditionParams = formFieldConfig.condition?.params + if (conditionParams && Array.isArray(conditionParams)) { + const dependentFieldsArr = conditionParams.map(ite => { + if (ite.data?.source === 'record') { + return ite?.data?.field && `${this.props.path}.${ite.data.field}` + } else if (ite.data?.source === 'data' || ite.data?.source === 'step') { + return ite?.data?.field && `${ite.data.field}` + } + return '' + }).filter(ite=>ite) + this.dependentFieldsArr = dependentFieldsArr + console.log('this.dependentFieldsArr--子表单', this.dependentFieldsArr); + } if (!ConditionHelper(formFieldConfig.condition, { record: value, data, step })) { this.formFieldsMounted[formFieldIndex] = false return null @@ -418,8 +432,9 @@ export default class ImportSubformField extends Field { await this.handleChange(formFieldIndex, value) }} onValueSet={async (path, value, validation) => this.handleValueSet(formFieldIndex, path, value, validation)} diff --git a/src/components/formFields/text/index.test.tsx b/src/components/formFields/text/index.test.tsx index 1633d3f..61e5844 100644 --- a/src/components/formFields/text/index.test.tsx +++ b/src/components/formFields/text/index.test.tsx @@ -89,7 +89,7 @@ test('文本框默认值 -数据值 query', () => { cleanup() resolve(true) }} - config={{ field: 'jest', label: 'jest', type: 'text', defaultValue: { source: 'query', filed: 'default' } }} + config={{ field: 'jest', label: 'jest', type: 'text', defaultValue: { source: 'query', field: 'default' } }} /> ) }) @@ -108,7 +108,7 @@ test('文本框默认值 -数据值 hash', () => { cleanup() resolve(true) }} - config={{ field: 'jest', label: 'jest', type: 'text', defaultValue: { source: 'hash', filed: 'default' } }} + config={{ field: 'jest', label: 'jest', type: 'text', defaultValue: { source: 'hash', field: 'default' } }} /> ) }) diff --git a/src/components/formFields/text/index.tsx b/src/components/formFields/text/index.tsx index ae4adeb..7150c17 100644 --- a/src/components/formFields/text/index.tsx +++ b/src/components/formFields/text/index.tsx @@ -1,4 +1,5 @@ import React from 'react' +import { isEqual, get } from 'lodash' import { getBoolean } from '../../../util/value' import { Field, FieldConfig, FieldError, IField } from '../common' @@ -161,11 +162,7 @@ export default class TextField extends Field { - //@ts-ignore - window.needUpdatePath = this.props.path - return await this.props.onValueSet('', value, await this.validate(value)) - } + onChange: async (value: string) => await this.props.onValueSet('', value, await this.validate(value)) })} ) diff --git a/src/components/formFields/treeSelect/index.tsx b/src/components/formFields/treeSelect/index.tsx index 6d3973a..9440c97 100644 --- a/src/components/formFields/treeSelect/index.tsx +++ b/src/components/formFields/treeSelect/index.tsx @@ -99,7 +99,7 @@ export default class TreeSelectField extends Field { if (config) { diff --git a/src/components/tableColumns/enum/index.test.tsx b/src/components/tableColumns/enum/index.test.tsx index 1560a5a..b0e744c 100644 --- a/src/components/tableColumns/enum/index.test.tsx +++ b/src/components/tableColumns/enum/index.test.tsx @@ -16,12 +16,13 @@ const defaultProps: ColumnProps = { label: 'test', valueType: 'string', multiple: true, + align: 'left', options: { from: 'manual', data: [{ extra: 'a', // todo label: '1', - key: 'filed' + key: 'field' }] }, defaultValue: '' diff --git a/src/interface.ts b/src/interface.ts index 594c704..ac9b062 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -40,11 +40,11 @@ interface URLParamConfig { } interface QueryParamConfig { source: 'query', - filed: any + field: string } interface HashParamConfig { source: 'hash', - filed: any + field: string } interface InterfaceParamConfig { source: 'interface', diff --git a/src/main.tsx b/src/main.tsx index 86e32d1..1dac8e5 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -265,7 +265,8 @@ export default class CCMS1 extends React.Component { const props: StepProps = { ref: (e) => { this.steps[index] = e }, data, - step: index, + // step: index, + step: data[index], onSubmit: (data: any, unmountView: boolean = true) => this.handleSubmit(index, data, unmountView), onMount: () => this.handleMount(index), onUnmount: (reload: boolean = false, data?: any) => this.handleUnmount(index, reload, data), diff --git a/src/steps/common.tsx b/src/steps/common.tsx index 579e3e2..d24543a 100644 --- a/src/steps/common.tsx +++ b/src/steps/common.tsx @@ -20,7 +20,8 @@ export interface StepConfig { export interface StepProps { ref: (instance: Step | null) => void data: any[] - step: number + step: {[field: string]: any} + // step: number config: C onChange?: (data: any) => Promise onSubmit: (data: any, unmountView?: boolean) => Promise diff --git a/src/steps/detail/index.tsx b/src/steps/detail/index.tsx index 6b5b504..f58c069 100644 --- a/src/steps/detail/index.tsx +++ b/src/steps/detail/index.tsx @@ -411,8 +411,9 @@ export default class DetailStep extends Step { formLayout={layout} value={detailFieldConfig.field !== undefined ? getValue(detailValue, detailFieldConfig.field) : undefined} record={detailValue} + step={cloneDeep(detailValue)} + // step={step} data={cloneDeep(data)} - step={step} config={detailFieldConfig} onChange={async (value: any) => { await this.handleChange(detailFieldIndex, value) }} onValueSet={async (path, value, validation) => await this.handleValueSet(detailFieldIndex, path, value, validation)} diff --git a/src/steps/fetch/index.tsx b/src/steps/fetch/index.tsx index 19f631e..9545263 100644 --- a/src/steps/fetch/index.tsx +++ b/src/steps/fetch/index.tsx @@ -40,7 +40,7 @@ export default class FetchStep extends Step { try { const content = await this.interfaceHelper.request( merge(config.interface, { cache: { disabled: true } }), - {...(this.popData || {}), ...(init_data || {}), ...(this.props.data[this.props.step] || {})}, + {...(this.popData || {}), ...(init_data || {}), ...(this.props.step || {})}, { data: this.props.data, step: this.props.step diff --git a/src/steps/filter/index.tsx b/src/steps/filter/index.tsx index b280205..74562d7 100644 --- a/src/steps/filter/index.tsx +++ b/src/steps/filter/index.tsx @@ -496,8 +496,9 @@ export default class FilterStep extends Step { formLayout={'inline'} value={formFieldConfig.field !== undefined ? get(formValue, formFieldConfig.field) : undefined} record={formValue} + step={cloneDeep(formValue)} + // step={step} data={cloneDeep(data)} - step={step} config={formFieldConfig} onChange={async (value: any) => { await this.handleChange(formFieldIndex, value) }} onValueSet={async (path, value, validation) => await this.handleValueSet(formFieldIndex, path, value, validation)} diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index f4699ca..be6c385 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -6,13 +6,12 @@ import getALLComponents from '../../components/formFields' import { getValue, listItemMove, getBoolean, getChainPath } from '../../util/value' import { ParamConfig } from '../../interface' import ParamHelper from '../../util/param' -import { get, set, unset, update } from 'lodash' +import { get, set, unset, update , isEqual } from 'lodash' import { cloneDeep, splice, sort, setValue } from '../../util/produce' import ConditionHelper, { ConditionConfig } from '../../util/condition' import StatementHelper, { StatementConfig } from '../../util/statement' import OperationHelper, { OperationConfig } from '../../util/operation' -import fp from 'lodash/fp' -import produce from 'immer' + /** * 表单步骤配置文件格式定义 * - layout: 表单布局类型 @@ -168,6 +167,8 @@ export default class FormStep extends Step { // ts对clas // 各表单项对应的类型所使用的UI组件的类 getALLComponents = (type: any): typeof Field => getALLComponents[type] OperationHelper = OperationHelper + dependentFieldsArr: string[] = [] //condition中依赖字段的存放数组 + // 各表单项所使用的UI组件的实例 formFields: Array | null> = [] @@ -251,7 +252,6 @@ export default class FormStep extends Step { // ts对clas const formField = this.formFields[formFieldIndex] if (formField) { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] - const fieldPathArr = formFieldConfig.field.split('.') let value = getValue(this.formValue, formFieldConfig.field) if ((formFieldConfig.defaultValue) && value === undefined) { value = await formField.reset() @@ -285,9 +285,9 @@ export default class FormStep extends Step { // ts对clas this.submitData = {} if (this.props.config.validations) { for (const validation of this.props.config.validations) { - if (!ConditionHelper(validation.condition, { record: this.state.formValue, data: this.props.data, step: this.props.step })) { + if (!ConditionHelper(validation.condition, { record: this.state.formValue, data: this.props.data, step: this.formValue })) { this.canSubmit = false - const message = StatementHelper(validation.message, { record: this.state.formValue, data: this.props.data, step: this.props.step }) || '未填写失败文案或失败文案配置异常' + const message = StatementHelper(validation.message, { record: this.state.formValue, data: this.props.data, step: this.formValue }) || '未填写失败文案或失败文案配置异常' this.renderModalComponent({ message }) return } @@ -601,7 +601,7 @@ export default class FormStep extends Step { // ts对clas if (Object.prototype.toString.call(actions) === '[object Array]') { actions_ = [] for (let index = 0, len = actions.length; index < len; index++) { - if (!ConditionHelper(actions[index].condition, { record: formValue, data, step })) { + if (!ConditionHelper(actions[index].condition, { record: formValue, data, step: formValue })) { continue } if (actions[index].type === 'submit') { @@ -655,7 +655,20 @@ export default class FormStep extends Step { // ts对clas submitText: this.props.config?.submitText?.replace(/(^\s*)|(\s*$)/g, ''), // TODO 待删除 cancelText: this.props.config?.cancelText?.replace(/(^\s*)|(\s*$)/g, ''), // TODO 待删除 children: fields.map((formFieldConfig, formFieldIndex) => { - if (!ConditionHelper(formFieldConfig.condition, { record: formValue, data, step })) { + const conditionParams = formFieldConfig.condition?.params + if (conditionParams && Array.isArray(conditionParams)) { + const dependentFieldsArr = conditionParams.map(ite => { + if (ite.data?.source === 'record') { + return ite?.data?.field && `${getChainPath(formFieldConfig.field)}.${ite.data.field}` + } else if (ite.data?.source === 'data' || ite.data?.source === 'step') { + return ite?.data?.field && `${ite.data.field}` + } + return '' + }).filter(ite=>ite) + this.dependentFieldsArr = dependentFieldsArr + console.log('this.dependentFieldsArr--formStep', this.dependentFieldsArr); + } + if (!ConditionHelper(formFieldConfig.condition, { record: formValue, data, step: formValue })) { this.formFieldsMounted[formFieldIndex] = false return null } @@ -684,14 +697,13 @@ export default class FormStep extends Step { // ts对clas if (['group', 'import_subform', 'object', 'tabs', 'form'].some((type) => type === formFieldConfig.type)) { status = 'normal' } - const fieldPathArr = formFieldConfig.field.split('.') const renderData = { key: formFieldIndex, label: formFieldConfig.label, status, message: formData[formFieldIndex]?.message || '', - extra: StatementHelper(formFieldConfig.extra, { data: this.props.data, step: this.props.step }), + extra: StatementHelper(formFieldConfig.extra, { data: this.props.data, step: formValue }), required: getBoolean(formFieldConfig.required), layout, visitable: display, @@ -710,19 +722,18 @@ export default class FormStep extends Step { // ts对clas record={cloneDeep(formValue)} form={this} data={cloneDeep(data)} - step={step} - // stepValue={cloneDeep(formValue)} + // step={step} + step={cloneDeep(formValue)} config={formFieldConfig} onChange={async (value: any) => { await this.handleChange(formFieldIndex, value) }} onValueSet={async (path, value, validation) => await this.handleValueSet(formFieldIndex, path, value, validation)} - // onDidMountSet 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)} - path={getChainPath(formFieldIndex, formFieldConfig.field)} + path={formFieldConfig.field} /> ) } diff --git a/src/steps/skip/index.tsx b/src/steps/skip/index.tsx index 955b549..1579c48 100644 --- a/src/steps/skip/index.tsx +++ b/src/steps/skip/index.tsx @@ -52,11 +52,11 @@ export default class SkipStep extends Step { } break case 'data': - if (data && data[step]) { + if (data && step) { if (defaultField) { - formDefault = getValue(data[step], defaultField) + formDefault = getValue(step, defaultField) } else { - formDefault = data[step] + formDefault = step } } break diff --git a/src/steps/table/index.tsx b/src/steps/table/index.tsx index 18f421e..85ebdc1 100644 --- a/src/steps/table/index.tsx +++ b/src/steps/table/index.tsx @@ -477,7 +477,7 @@ export default class TableStep extends Step { pageAuth } = this.state - let getDate = field ? getValue(data[step], field) : data[step] + let getDate = field ? getValue(step, field) : step if (Object.prototype.toString.call(getDate) !== '[object Array]') { getDate = [] } @@ -565,9 +565,9 @@ export default class TableStep extends Step { } if (pagination && pagination.mode === 'server') { - const paginationCurrent = Number((pagination.current === undefined || pagination.current === '') ? data[step] : get(data[step], pagination.current, 1)) - const paginationPageSize = Number((pagination.pageSize === undefined || pagination.pageSize === '') ? data[step] : get(data[step], pagination.pageSize, 10)) - const paginationTotal = Number((pagination.total === undefined || pagination.total === '') ? data[step] : get(data[step], pagination.total, 0)) + const paginationCurrent = Number((pagination.current === undefined || pagination.current === '') ? step : get(step, pagination.current, 1)) + const paginationPageSize = Number((pagination.pageSize === undefined || pagination.pageSize === '') ? step : get(step, pagination.pageSize, 10)) + const paginationTotal = Number((pagination.total === undefined || pagination.total === '') ? step : get(step, pagination.total, 0)) props.pagination = { current: Number.isNaN(paginationCurrent) ? 1 : paginationCurrent, diff --git a/src/util/condition.ts b/src/util/condition.ts index 7d7542b..edd3016 100644 --- a/src/util/condition.ts +++ b/src/util/condition.ts @@ -1,4 +1,6 @@ -import { set, cloneDeep, template } from "lodash" +// import { set, cloneDeep, template } from "lodash" +import { template } from "lodash" +import { cloneDeep } from '../util/produce' import { ParamConfig } from "../interface"; import ParamHelper from "./param"; @@ -22,7 +24,7 @@ export interface ConditionConfig { debug?: boolean } -export default function ConditionHelper(condition: ConditionConfig | undefined, datas: { record?: object, data: object[], step: number }): boolean { +export default function ConditionHelper(condition: ConditionConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; } }): boolean { if (condition === undefined || ((condition.statement === undefined || condition.statement === '') && (condition.template === undefined || condition.template === ''))) { return true } else { @@ -36,7 +38,7 @@ export default function ConditionHelper(condition: ConditionConfig | undefined, if (param.field === '') { statementParams = value === undefined ? 'undefined' : JSON.stringify(value) } else { - set(statementParams, param.field, value === undefined ? 'undefined' : JSON.stringify(value)) + statementParams = cloneDeep(statementParams, 'set', param.field, value === undefined ? 'undefined' : JSON.stringify(value)) } } }) @@ -87,7 +89,7 @@ export default function ConditionHelper(condition: ConditionConfig | undefined, if (param.field === '') { statementParams = ParamHelper(param.data, cloneDeep(datas)) } else { - set(statementParams, param.field, ParamHelper(param.data, cloneDeep(datas))) + statementParams = cloneDeep(statementParams, 'set', param.field, ParamHelper(param.data, cloneDeep(datas))) } } }) diff --git a/src/util/interface.ts b/src/util/interface.ts index 5e4783b..58ecba1 100644 --- a/src/util/interface.ts +++ b/src/util/interface.ts @@ -1,4 +1,6 @@ -import { isEqual, cloneDeep, template, get, set, merge } from "lodash" +// import { isEqual, cloneDeep, template, get, set, merge } from "lodash" +import { isEqual, template, get, merge } from "lodash" +import { cloneDeep } from '../util/produce' import axios, { AxiosRequestConfig } from 'axios' import { ParamConfig } from "../interface"; import ParamHelper from "./param"; @@ -96,7 +98,7 @@ export default class InterfaceHelper { public request ( config: InterfaceConfig, source: any, - datas: { record?: object, data: object[], step: number }, + datas: { record?: object, data: object[], step: { [field: string]: any; } }, option?: { loadDomain?: (domain: string) => Promise extra_data?: { params?: any, data?: any } @@ -112,7 +114,7 @@ export default class InterfaceHelper { if (param.field === '') { urlParams = ParamHelper(param.data, datas) } else { - set(urlParams, param.field, ParamHelper(param.data, datas)) + urlParams = cloneDeep(urlParams, 'set', param.field, ParamHelper(param.data, datas)) } } }) @@ -145,7 +147,7 @@ export default class InterfaceHelper { if (param.field === '') { params = ParamHelper(param.data, datas) } else { - set(params, param.field, ParamHelper(param.data, datas)) + params = cloneDeep(params, 'set', param.field, ParamHelper(param.data, datas)) } } }) @@ -173,7 +175,7 @@ export default class InterfaceHelper { if (param.field === '') { data = ParamHelper(param.data, datas) } else { - set(data, param.field, ParamHelper(param.data, datas)) + data = cloneDeep(data, 'set', param.field, ParamHelper(param.data, datas)) } } }) @@ -252,7 +254,7 @@ export default class InterfaceHelper { if (field === undefined || field === '') { content = value } else { - set(content, field, value) + content = cloneDeep(content, 'set', field, value) } } this._response = content diff --git a/src/util/operation.tsx b/src/util/operation.tsx index 3f9f3b9..f4bf008 100644 --- a/src/util/operation.tsx +++ b/src/util/operation.tsx @@ -1,6 +1,7 @@ import React from 'react'; import queryString from 'query-string'; -import { set } from "lodash"; +// import { set } from "lodash"; +import { cloneDeep } from '../util/produce' import { ParamConfig } from "../interface"; import { CCMSConfig, CCMSProps } from "../main"; import { getParam } from "./value"; @@ -51,7 +52,7 @@ type CCMSOperationConfig = CCMSPopupOperationConfig | CCMSRedirectOperationConfi interface OperationHelperProps { config?: OperationConfig, - datas: { record?: object, data: object[], step: number }, + datas: { record?: object, data: object[], step: { [field: string]: any; } }, checkPageAuth: (pageID: any) => Promise, loadPageURL: (pageID: any) => Promise, loadPageFrameURL: (pageID: any) => Promise, @@ -100,16 +101,16 @@ export default class OperationHelper extends React.Component { if (config.type === 'ccms') { - const sourceData = {} + let sourceData = {} if (config.params === undefined) { for (const [field, param] of Object.entries(config.data || {})) { const value = getParam(param, datas) - set(sourceData, field, value) + sourceData = cloneDeep(sourceData, 'set', field, value) } } else { for (const {field, data} of config.params) { const value = getParam(data, datas) - set(sourceData, field, value) + sourceData = cloneDeep(sourceData, 'set', field, value) } } if (config.mode === 'popup' || config.mode === 'invisible') { diff --git a/src/util/param.ts b/src/util/param.ts index cbe4e5a..867187b 100644 --- a/src/util/param.ts +++ b/src/util/param.ts @@ -1,8 +1,8 @@ -import { get, set } from "lodash" +import { get } from "lodash" import qs from "query-string" import { ParamConfig } from "../interface"; -export default function ParamHelper ( config: ParamConfig, datas: { record?: object, data: object[], step: number }) { // step--> stepValue +export default function ParamHelper ( config: ParamConfig, datas: { record?: object, data: object[], step: { [field: string]: any } }) { // step--> stepValue switch (config.source) { case 'record': if (datas.record) { @@ -14,11 +14,11 @@ export default function ParamHelper ( config: ParamConfig, datas: { record?: obj } break case 'data': - if (datas.data[datas.step]) { + if (datas.step) { if (config.field === '') { - return datas.data[datas.step] + return datas.step } else { - return get(datas.data[datas.step], config.field) //return get(stepValue, config.field) + return get(datas.step, config.field) //return get(step, config.field) } } break diff --git a/src/util/produce.tsx b/src/util/produce.tsx index 9a75f7a..98f5159 100644 --- a/src/util/produce.tsx +++ b/src/util/produce.tsx @@ -8,6 +8,12 @@ type FormData = { status: 'normal' | 'error' | 'loading', message?: string, nam type FormDataList = { status: 'normal' | 'error' | 'loading', message?: string }[][] type Data = any[] type Data_ = Data | FormData | FormValue | FormDataList + +/** + * setAutoFreeze + * 默认为true, 防止外部修改,维护数据不可变 + * 为false 可以修改数据源 + */ setAutoFreeze(false) /** @@ -29,9 +35,6 @@ setAutoFreeze(false) case 'set': return lodash.set(draft, path, value) break - // case 'get': - // return lodash.get(draft, path, value) - // break case 'push': return lodash.concat(draft, value) break diff --git a/src/util/statement.ts b/src/util/statement.ts index 81ea1e5..61f95fa 100644 --- a/src/util/statement.ts +++ b/src/util/statement.ts @@ -1,4 +1,6 @@ -import { set, cloneDeep, template } from "lodash" +// import { set, cloneDeep, template } from "lodash" +import { template } from "lodash" +import { cloneDeep } from '../util/produce' import { ParamConfig } from "../interface"; import ParamHelper from "./param"; @@ -7,7 +9,7 @@ export interface StatementConfig { params: { field: string, data: ParamConfig }[] } -export default function StatementHelper(config: StatementConfig | undefined, datas: { record?: object, data: object[], step: number }): string { +export default function StatementHelper(config: StatementConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; }}): string { if (config === undefined || config.statement === undefined || config.statement === '') { return '' } else { @@ -19,7 +21,7 @@ export default function StatementHelper(config: StatementConfig | undefined, dat if (param.field === '') { statementParams = ParamHelper(param.data, cloneDeep(datas)) } else { - set(statementParams, param.field, ParamHelper(param.data, cloneDeep(datas))) + statementParams = cloneDeep(statementParams, 'set', param.field, ParamHelper(param.data, cloneDeep(datas))) } } }) diff --git a/src/util/value.ts b/src/util/value.ts index b9d9e4c..87e6014 100644 --- a/src/util/value.ts +++ b/src/util/value.ts @@ -51,14 +51,14 @@ export const getParam = ( datas: { record?: object data: object[] - step: number + step: { [field: string]: any; } } ) => { switch (config.source) { case 'record': return getValue(datas.record || {}, config.field) case 'data': - return getValue(datas.data[datas.step], config.field) + return getValue(datas.step, config.field) case 'source': return getValue(datas.data[0] || {}, config.field) case 'step': @@ -79,7 +79,7 @@ export const getParamText = ( datas: { record?: object data: object[] - step: number + step: { [field: string]: any; } } ) => { for (const { field, data } of params) { -- Gitee From 0eeff92928fc49b2e764dbb14959387e95262405 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Mon, 17 Jan 2022 18:04:50 +0800 Subject: [PATCH 07/38] =?UTF-8?q?feat:=20produce=E5=86=99=E6=B3=95?= =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/form/index.tsx | 96 ++++++++---------- .../formFields/importSubform/index.tsx | 26 ++--- src/steps/form/index.tsx | 50 ++++------ src/util/condition.ts | 10 +- src/util/interface.ts | 16 +-- src/util/operation.tsx | 6 +- src/util/produce.tsx | 99 ++++++++++++------- src/util/statement.ts | 6 +- 8 files changed, 159 insertions(+), 150 deletions(-) diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index 3fd3abf..d3e15a5 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -4,7 +4,7 @@ import getALLComponents from '../' // import { getValue, listItemMove, setValue, getBoolean, getChainPath } from '../../../util/value' // import { cloneDeep } from 'lodash' import { getValue, getBoolean, getChainPath } from '../../../util/value' -import { cloneDeep, setValue , sort, splice} from '../../../util/produce' +import { set, setValue , sort, splice} from '../../../util/produce' import ConditionHelper from '../../../util/condition' import StatementHelper from '../../../util/statement' @@ -131,7 +131,7 @@ export default class FormField extends Field { if (!this.formFieldsMountedList[index]) { - // this.formFieldsMountedList[index] = [] - cloneDeep(this.formFieldsMountedList, 'set', `[${index}]`, []) + this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}]`, []) } if (this.formFieldsMountedList[index][formFieldIndex]) { return true } // this.formFieldsMountedList[index][formFieldIndex] = true - this.formFieldsMountedList = cloneDeep(this.formFieldsMountedList, 'set', `[${index}][${formFieldIndex}]`, true) + this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}][${formFieldIndex}]`, true) - let formDataList = cloneDeep(this.state.formDataList) - if (!formDataList[index]) formDataList = cloneDeep(formDataList, 'set', `[${index}]`, []) + let formDataList = this.state.formDataList + if (!formDataList[index]) formDataList = set(formDataList, `[${index}]`, []) if (this.formFieldsList[index] && this.formFieldsList[index][formFieldIndex]) { const formField = this.formFieldsList[index][formFieldIndex] @@ -247,9 +246,9 @@ export default class FormField extends Field { const index = (this.props.value || []).length - const formDataList = cloneDeep(this.state.formDataList, 'set', `[${index}]`, []) + const formDataList = set(this.state.formDataList, `[${index}]`, []) this.setState({ formDataList }) - // this.formFieldsList[index] = [] - this.formFieldsList = cloneDeep(this.formFieldsList, 'set', `${index}`, []) - // this.formFieldsMountedList[index] = [] - this.formFieldsMountedList = cloneDeep(this.formFieldsMountedList, 'set', `${index}`, []) + this.formFieldsList = set(this.formFieldsList, `${index}`, []) + this.formFieldsMountedList = set(this.formFieldsMountedList, `${index}`, []) - await this.props.onValueListAppend('', this.props.config.initialValues === undefined ? {} : cloneDeep(this.props.config.initialValues), true) + await this.props.onValueListAppend('', this.props.config.initialValues === undefined ? {} : this.props.config.initialValues, true) } handleRemove = async (index: number) => { - // const formDataList = cloneDeep(this.state.formDataList) - const formDataList = splice(this.state.formDataList, index, 1) + const formDataList = splice(this.state.formDataList, '', index, 1) this.setState({ - //@ts-ignore formDataList }) - // this.formFieldsList.splice(index, 1) - //@ts-ignore - this.formFieldsList = splice(this.formFieldsList,index, 1) - // this.formFieldsMountedList.splice(index, 1) - //@ts-ignore - this.formFieldsMountedList = splice(this.formFieldsMountedList,index, 1) + this.formFieldsList = splice(this.formFieldsList, '', index, 1) + this.formFieldsMountedList = splice(this.formFieldsMountedList, '', index, 1) await this.props.onValueListSplice('', index, 1, true) } handleSort = async (index: number, sortType: 'up' | 'down') => { - var list = cloneDeep(this.state.formDataList) - let formDataList = sort(list, index, sortType) + var list = this.state.formDataList + let formDataList = sort(list, '', index, sortType) this.setState({ - //@ts-ignore formDataList: formDataList }) - //@ts-ignore - this.formFieldsList = sort(this.formFieldsList, index, sortType) - //@ts-ignore - this.formFieldsMountedList = sort(this.formFieldsMountedList, index, sortType) + this.formFieldsList = sort(this.formFieldsList,'', index, sortType) + this.formFieldsMountedList = sort(this.formFieldsMountedList, '', index, sortType) await this.props.onValueListSort('', index, sortType, true) } @@ -343,11 +331,11 @@ export default class FormField extends Field | null) => { if (fieldRef) { - if (!this.formFieldsList[index]) this.formFieldsList = cloneDeep(this.formFieldsList, 'set', `[${index}]`, []) + if (!this.formFieldsList[index]) this.formFieldsList = set(this.formFieldsList, `[${index}]`, []) // this.formFieldsList[index][fieldIndex] = fieldRef - this.formFieldsList = cloneDeep(this.formFieldsList, 'set', `[${index}][${fieldIndex}]`, fieldRef) + this.formFieldsList = set(this.formFieldsList, `[${index}][${fieldIndex}]`, fieldRef) this.handleMount(index, fieldIndex) } }} form={this.props.form} formLayout={formLayout} - value={cloneDeep(getValue(value[index], formFieldConfig.field))} - record={cloneDeep(value[index])} - step={cloneDeep(this.props.step)} - data={cloneDeep(data)} + value={getValue(value[index], formFieldConfig.field)} + record={value[index]} + step={this.props.step} + data={data} // step={step} config={formFieldConfig} onChange={(value: any) => this.handleChange(index, fieldIndex, value)} diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx index eecdbc4..0442aa7 100644 --- a/src/components/formFields/importSubform/index.tsx +++ b/src/components/formFields/importSubform/index.tsx @@ -6,7 +6,7 @@ import { Field, FieldConfig, FieldError, FieldProps, IField } from '../common' import getALLComponents, { FieldConfigs } from '../' import { IFormItem } from '../../../steps/form' // import { cloneDeep } from 'lodash' -import { cloneDeep, setValue } from '../../../util/produce' +import { setValue } from '../../../util/produce' import ConditionHelper from '../../../util/condition' import InterfaceHelper, { InterfaceConfig } from '../../../util/interface' import StatementHelper from '../../../util/statement' @@ -116,7 +116,7 @@ export default class ImportSubformField extends Field { formData[formFieldIndex] = { status: 'normal' } - return { formData: cloneDeep(formData) } + return { formData: formData } }) } else { await this.setState(({ formData }) => { formData[formFieldIndex] = { status: 'error', message: validation[0].message } - return { formData: cloneDeep(formData) } + return { formData: formData } }) } } @@ -219,7 +219,7 @@ export default class ImportSubformField extends Field { await this.handleChange(formFieldIndex, value) }} diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index be6c385..929b021 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -6,8 +6,8 @@ import getALLComponents from '../../components/formFields' import { getValue, listItemMove, getBoolean, getChainPath } from '../../util/value' import { ParamConfig } from '../../interface' import ParamHelper from '../../util/param' -import { get, set, unset, update , isEqual } from 'lodash' -import { cloneDeep, splice, sort, setValue } from '../../util/produce' +import { get, unset, update , isEqual } from 'lodash' +import { push, splice, sort, set, setValue } from '../../util/produce' import ConditionHelper, { ConditionConfig } from '../../util/condition' import StatementHelper, { StatementConfig } from '../../util/statement' import OperationHelper, { OperationConfig } from '../../util/operation' @@ -235,7 +235,7 @@ export default class FormStep extends Step { // ts对clas await this.setState({ ready: true, formValue: this.formValue, - formData: cloneDeep(this.formData) + formData: this.formData }) // 表单初始化结束,展示表单界面。 @@ -273,7 +273,7 @@ export default class FormStep extends Step { // ts对clas await this.setState({ formValue: this.formValue, - formData: cloneDeep(this.formData) + formData: this.formData }) } @@ -321,7 +321,7 @@ export default class FormStep extends Step { // ts对clas } await this.setState({ - formData: cloneDeep(this.formData) + formData: this.formData }) } @@ -369,7 +369,7 @@ export default class FormStep extends Step { // ts对clas await this.setState({ formValue: this.formValue, - formData: cloneDeep(this.formData) + formData: this.formData }) if (this.props.onChange) { this.props.onChange(this.formValue) @@ -386,8 +386,8 @@ export default class FormStep extends Step { // ts对clas this.props.handleFormValue({path: fullPath, value}) } - // set(this.formValue, fullPath, value) - this.formValue = cloneDeep(this.formValue, 'set', fullPath, value) + + this.formValue = set(this.formValue, fullPath, value) console.log('test--->set--', this.formValue, fullPath, value); this.setState(({formValue})=>({ formValue: this.formValue @@ -406,7 +406,7 @@ export default class FormStep extends Step { // ts对clas console.log('form set data', this.formData) await this.setState({ - formData: cloneDeep(this.formData) + formData: this.formData }) } } @@ -431,7 +431,7 @@ export default class FormStep extends Step { // ts对clas } await this.setState({ - formData: cloneDeep(this.formData) + formData: this.formData }) } } @@ -441,11 +441,7 @@ export default class FormStep extends Step { // ts对clas if (formFieldConfig) { const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - let list = get(this.formValue, fullPath, []) - console.log('list---', list, value); - let cloneList = cloneDeep(list,'push', fullPath, value) - // set(this.formValue, fullPath, list) - this.formValue = cloneDeep(this.formValue, 'set', fullPath, cloneList) + this.formValue = push(this.formValue, fullPath, value) //向this.formValue的fullPath下的值添加value this.setState({ formValue: this.formValue }) @@ -460,7 +456,7 @@ export default class FormStep extends Step { // ts对clas } await this.setState({ - formData: cloneDeep(this.formData) + formData: this.formData }) } } @@ -470,10 +466,7 @@ export default class FormStep extends Step { // ts对clas if (formFieldConfig) { const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - const list = get(this.formValue, fullPath, []) - const cloneList = splice(list, index, count) - // set(this.formValue, fullPath, list) - this.formValue = cloneDeep(this.formValue, 'set', fullPath, cloneList) + this.formValue = splice(this.formValue, fullPath, index, count) this.setState({ formValue: this.formValue }) @@ -488,7 +481,7 @@ export default class FormStep extends Step { // ts对clas } await this.setState({ - formData: cloneDeep(this.formData) + formData: this.formData }) } } @@ -498,10 +491,7 @@ export default class FormStep extends Step { // ts对clas if (formFieldConfig) { const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - // const list = listItemMove(get(this.formValue, fullPath, []), index, sortType) - const list = sort(get(this.formValue, fullPath, []), index, sortType) - // set(this.formValue, fullPath, list) - this.formValue = cloneDeep(this.formValue, 'set', fullPath, list) + this.formValue = sort(this.formValue, fullPath, index, sortType) this.setState({ formValue: this.formValue }) @@ -516,7 +506,7 @@ export default class FormStep extends Step { // ts对clas } await this.setState({ - formData: cloneDeep(this.formData) + formData: this.formData }) } } @@ -718,12 +708,12 @@ export default class FormStep extends Step { // ts对clas } }} formLayout={layout} - value={formFieldConfig.field !== undefined ? cloneDeep(getValue(formValue, formFieldConfig.field)) : undefined} - record={cloneDeep(formValue)} + value={formFieldConfig.field !== undefined ? getValue(formValue, formFieldConfig.field) : undefined} + record={formValue} form={this} - data={cloneDeep(data)} + data={data} // step={step} - step={cloneDeep(formValue)} + step={formValue} config={formFieldConfig} onChange={async (value: any) => { await this.handleChange(formFieldIndex, value) }} onValueSet={async (path, value, validation) => await this.handleValueSet(formFieldIndex, path, value, validation)} diff --git a/src/util/condition.ts b/src/util/condition.ts index edd3016..633e565 100644 --- a/src/util/condition.ts +++ b/src/util/condition.ts @@ -1,6 +1,6 @@ // import { set, cloneDeep, template } from "lodash" import { template } from "lodash" -import { cloneDeep } from '../util/produce' +import { set } from '../util/produce' import { ParamConfig } from "../interface"; import ParamHelper from "./param"; @@ -34,11 +34,11 @@ export default function ConditionHelper(condition: ConditionConfig | undefined, if (condition.params) { condition.params.forEach((param) => { if (param.field !== undefined && param.data !== undefined) { - const value = ParamHelper(param.data, cloneDeep(datas)) + const value = ParamHelper(param.data, datas) if (param.field === '') { statementParams = value === undefined ? 'undefined' : JSON.stringify(value) } else { - statementParams = cloneDeep(statementParams, 'set', param.field, value === undefined ? 'undefined' : JSON.stringify(value)) + statementParams = set(statementParams, param.field, value === undefined ? 'undefined' : JSON.stringify(value)) } } }) @@ -87,9 +87,9 @@ export default function ConditionHelper(condition: ConditionConfig | undefined, condition.params.forEach((param) => { if (param.field !== undefined && param.data !== undefined) { if (param.field === '') { - statementParams = ParamHelper(param.data, cloneDeep(datas)) + statementParams = ParamHelper(param.data,datas) } else { - statementParams = cloneDeep(statementParams, 'set', param.field, ParamHelper(param.data, cloneDeep(datas))) + statementParams = set(statementParams, param.field, ParamHelper(param.data, datas)) } } }) diff --git a/src/util/interface.ts b/src/util/interface.ts index 58ecba1..8e1d80b 100644 --- a/src/util/interface.ts +++ b/src/util/interface.ts @@ -1,6 +1,6 @@ // import { isEqual, cloneDeep, template, get, set, merge } from "lodash" import { isEqual, template, get, merge } from "lodash" -import { cloneDeep } from '../util/produce' +import { set } from '../util/produce' import axios, { AxiosRequestConfig } from 'axios' import { ParamConfig } from "../interface"; import ParamHelper from "./param"; @@ -114,7 +114,7 @@ export default class InterfaceHelper { if (param.field === '') { urlParams = ParamHelper(param.data, datas) } else { - urlParams = cloneDeep(urlParams, 'set', param.field, ParamHelper(param.data, datas)) + urlParams = set(urlParams, param.field, ParamHelper(param.data, datas)) } } }) @@ -147,7 +147,7 @@ export default class InterfaceHelper { if (param.field === '') { params = ParamHelper(param.data, datas) } else { - params = cloneDeep(params, 'set', param.field, ParamHelper(param.data, datas)) + params = set(params, param.field, ParamHelper(param.data, datas)) } } }) @@ -175,7 +175,7 @@ export default class InterfaceHelper { if (param.field === '') { data = ParamHelper(param.data, datas) } else { - data = cloneDeep(data, 'set', param.field, ParamHelper(param.data, datas)) + data = set(data, param.field, ParamHelper(param.data, datas)) } } }) @@ -197,10 +197,10 @@ export default class InterfaceHelper { ) { return this._response } else { - this._config = cloneDeep(config) + this._config = config this._url = url - this._params = cloneDeep(params) - this._data = cloneDeep(data) + this._params = params + this._data = data const request: AxiosRequestConfig = { url, @@ -254,7 +254,7 @@ export default class InterfaceHelper { if (field === undefined || field === '') { content = value } else { - content = cloneDeep(content, 'set', field, value) + content = set(content, field, value) } } this._response = content diff --git a/src/util/operation.tsx b/src/util/operation.tsx index f4bf008..05a63ff 100644 --- a/src/util/operation.tsx +++ b/src/util/operation.tsx @@ -1,7 +1,7 @@ import React from 'react'; import queryString from 'query-string'; // import { set } from "lodash"; -import { cloneDeep } from '../util/produce' +import { set } from '../util/produce' import { ParamConfig } from "../interface"; import { CCMSConfig, CCMSProps } from "../main"; import { getParam } from "./value"; @@ -105,12 +105,12 @@ export default class OperationHelper extends React.Component { - if (!operationType) return current // 注意这里没有深拷贝,只有在修改时才使用immer的api - let target = produce(current, (draft: any) => { - if (!path) path='' - // const method = lodash[operationType] - // @ts-ignore - // method(draft, path, value) // 写return method(draft, path, value)会卡顿 - switch (operationType) { - case 'set': - return lodash.set(draft, path, value) - break - case 'push': - return lodash.concat(draft, value) - break - } +export const set = (current: any, path?: string, value?: any) => { + let target = produce(current, (draft: any) => { + if (path) { + return lodash.set(draft, path, value) + } + return draft + }) + return target +} +/** + * current指定路径下的数组添加元素 + * @param current + * @param path + * @param value + * @returns + */ +export const push = (current: any, path: string = '', value?: any) => { + let list + const target = produce(current, (draft: any) => { + if (!path) list = draft // path为空时,向current根路径push + else list = lodash.get(draft, path, []) + console.log('error', lodash.concat(list, value)); + list.push(value) }) return target } -export const splice = (current: any, index:number, count:number) => { - let target = produce(current, (draft: any)=>{ - draft.splice(index, count) +/** + * current指定路径下的数组删除元素 + * @param current + * @param path + * @param index + * @param count + * @returns + */ +export const splice = (current: any, path: string='', index: number, count: number) => { + let list + const target = produce(current, (draft: any) => { + if (!path) list = draft + else list = lodash.get(draft, path, []) + list.splice(index, count) }) return target } -export const sort = (current: any, index: number, sortType: 'up' | 'down') => { - let target = produce(current, (draft: any)=>{ - return listItemMove(draft, index, sortType) +/** + * 数组排序 + * @param current + * @param path + * @param index + * @param sortType + * @returns + */ +export const sort = (current: any, path: string='', index: number, sortType: 'up' | 'down') => { + let list + const target = produce(current, (draft: any) => { + if (!path) list = draft + else list = lodash.get(draft, path, []) + listItemMove(list, index, sortType) }) return target } +/** + * lodash 递归合并来源对象的自身和继承的可枚举属性到目标对象 + * @param a 目标对象 + * @param b 来源对象 + * @returns + */ const merge = (a: any, b: any): any => { return lodash.assignInWith(a, b, (a, b) => { if (lodash.isUndefined(a) && lodash.isArray(b)) { @@ -73,7 +104,7 @@ const merge = (a: any, b: any): any => { } export const setValue = (obj: any, path: string = '', value: any) => { - let target = produce(obj, (draft: any) => { + let target = produce(obj, (draft: any) => { if (path === '') { if (Object.prototype.toString.call(value) === '[object Object]') { draft = merge(draft, value) diff --git a/src/util/statement.ts b/src/util/statement.ts index 61f95fa..73e59c5 100644 --- a/src/util/statement.ts +++ b/src/util/statement.ts @@ -1,6 +1,6 @@ // import { set, cloneDeep, template } from "lodash" import { template } from "lodash" -import { cloneDeep } from '../util/produce' +import { set } from '../util/produce' import { ParamConfig } from "../interface"; import ParamHelper from "./param"; @@ -19,9 +19,9 @@ export default function StatementHelper(config: StatementConfig | undefined, dat config.params.forEach((param) => { if (param.field !== undefined && param.data !== undefined) { if (param.field === '') { - statementParams = ParamHelper(param.data, cloneDeep(datas)) + statementParams = ParamHelper(param.data, datas) } else { - statementParams = cloneDeep(statementParams, 'set', param.field, ParamHelper(param.data, cloneDeep(datas))) + statementParams = set(statementParams, param.field, ParamHelper(param.data, datas)) } } }) -- Gitee From 7be7d6e9b54caa1dc9055489ceeaeb09620210f4 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Tue, 18 Jan 2022 18:56:13 +0800 Subject: [PATCH 08/38] =?UTF-8?q?feat:=E6=9B=BF=E6=8D=A2form=E3=80=81filte?= =?UTF-8?q?r=E6=AD=A5=E9=AA=A4=E6=B7=B1=E6=8B=B7=E8=B4=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/any/index.tsx | 7 +- src/components/formFields/custom/index.tsx | 6 +- src/components/formFields/form/index.tsx | 12 +- src/components/formFields/group/index.tsx | 55 ++++----- .../formFields/importSubform/index.tsx | 46 ++++---- src/components/formFields/object/index.tsx | 107 +++++++++--------- src/components/formFields/tabs/index.tsx | 73 ++++++------ src/steps/common.tsx | 8 +- src/steps/filter/index.tsx | 85 +++++++------- src/steps/form/index.tsx | 50 ++++---- src/steps/table/index.tsx | 6 +- src/util/produce.tsx | 29 ++--- 12 files changed, 245 insertions(+), 239 deletions(-) diff --git a/src/components/formFields/any/index.tsx b/src/components/formFields/any/index.tsx index a4a051d..5b2ea1e 100644 --- a/src/components/formFields/any/index.tsx +++ b/src/components/formFields/any/index.tsx @@ -1,6 +1,7 @@ import React, { ReactNode } from 'react' import { Field, FieldConfig, IField, FieldInterface } from '../common' +import { getChainPath } from '../../../util/value' import TextField from '../text' import * as _ from 'lodash' import NumberField from '../number' @@ -97,7 +98,7 @@ export default class AnyField extends Field : ( type === 'number' ? {}} @@ -116,7 +117,7 @@ export default class AnyField extends Field : {}} form={this.props.form} @@ -134,7 +135,7 @@ export default class AnyField extends Field ) })} diff --git a/src/components/formFields/custom/index.tsx b/src/components/formFields/custom/index.tsx index 492ef98..672607e 100644 --- a/src/components/formFields/custom/index.tsx +++ b/src/components/formFields/custom/index.tsx @@ -2,7 +2,7 @@ import React, { RefObject } from 'react' import { Field, FieldConfig, IField, FieldInterface, FieldProps, FieldError } from '../common' import { loadMicroApp, MicroApp } from 'qiankun' import moment from 'moment' -import { cloneDeep } from 'lodash' +// import { cloneDeep } from 'lodash' export interface CustomFieldConfig extends FieldConfig, FieldInterface { type: 'custom' @@ -53,7 +53,7 @@ export default class CustomField extends Field imple this.customField.update({ value: this.props.value, record: this.props.record, - data: cloneDeep(this.props.data), + data: this.props.data, form: this.props.form, step: this.props.step, config: this.props.config, @@ -82,7 +82,7 @@ export default class CustomField extends Field imple props: { value: this.props.value, record: this.props.record, - data: cloneDeep(this.props.data), + data: this.props.data, form: this.props.form, step: this.props.step, config: this.props.config, diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index d3e15a5..1709298 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -131,7 +131,7 @@ export default class FormField extends Field { - formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } - return { formData: cloneDeep(formData) } + formData = set(formData, `[${formFieldIndex}]`, { status: 'normal', name: formFieldConfig.label }) + return { formData: formData } }) } else { await this.setState(({ formData }) => { - formData[formFieldIndex] = { status: 'error', message: validation[0].message, name: formFieldConfig.label } - return { formData: cloneDeep(formData) } + formData = set(formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message, name: formFieldConfig.label }) + return { formData: formData } }) } } @@ -168,11 +169,11 @@ export default class GroupField extends Field { if (!ConditionHelper(formFieldConfig.condition, { record: value, data: this.props.data, step: this.props.step })) { - this.formFieldsMounted[formFieldIndex] = false + this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, false) return null } let hidden: boolean = true @@ -325,7 +326,7 @@ export default class GroupField extends Field | null) => { if (formField) { - this.formFields[formFieldIndex] = formField + this.formFields = set(this.formFields, `[${formFieldIndex}]`, formField) this.handleMount(formFieldIndex) } }} @@ -333,7 +334,7 @@ export default class GroupField extends Field { await this.handleChange(formFieldIndex, value) }} diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx index 0442aa7..9514d35 100644 --- a/src/components/formFields/importSubform/index.tsx +++ b/src/components/formFields/importSubform/index.tsx @@ -6,7 +6,7 @@ import { Field, FieldConfig, FieldError, FieldProps, IField } from '../common' import getALLComponents, { FieldConfigs } from '../' import { IFormItem } from '../../../steps/form' // import { cloneDeep } from 'lodash' -import { setValue } from '../../../util/produce' +import { set, setValue } from '../../../util/produce' import ConditionHelper from '../../../util/condition' import InterfaceHelper, { InterfaceConfig } from '../../../util/interface' import StatementHelper from '../../../util/statement' @@ -116,7 +116,7 @@ export default class ImportSubformField extends Field { - formData[formFieldIndex] = { status: 'normal' } + formData = set(formData, `[${formFieldIndex}]`, { status: 'normal' }) return { formData: formData } }) } else { await this.setState(({ formData }) => { - formData[formFieldIndex] = { status: 'error', message: validation[0].message } + formData = set(formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message }) return { formData: formData } }) } @@ -219,11 +219,11 @@ export default class ImportSubformField extends Field | null) => { if (formField) { - this.formFields[formFieldIndex] = formField + this.formFields = set(this.formFields, `[${formFieldIndex}]`, formField) this.handleMount(formFieldIndex) } }} diff --git a/src/components/formFields/object/index.tsx b/src/components/formFields/object/index.tsx index a68d174..5025b52 100644 --- a/src/components/formFields/object/index.tsx +++ b/src/components/formFields/object/index.tsx @@ -2,8 +2,9 @@ import { Field, FieldConfig, FieldConfigs, FieldError, FieldProps, IField } from import getALLComponents from '../' import React from 'react' import ConditionHelper from '../../../util/condition' -import { cloneDeep } from 'lodash' -import { getValue, setValue, getBoolean, getChainPath } from '../../../util/value' +// import { cloneDeep } from 'lodash' +import { set, setValue } from '../../../util/produce' +import { getValue, getBoolean, getChainPath } from '../../../util/value' import StatementHelper from '../../../util/statement' export interface ObjectFieldConfig extends FieldConfig { @@ -105,10 +106,10 @@ export default class ObjectField extends Field extends Field extends Field { if (!this.formFieldsMountedList[key]) { - this.formFieldsMountedList[key] = [] + this.formFieldsMountedList = set(this.formFieldsMountedList, `[${key}]`, []) } if (this.formFieldsMountedList[key][formFieldIndex]) { return true } - this.formFieldsMountedList[key][formFieldIndex] = true + this.formFieldsMountedList = set(this.formFieldsMountedList, `[${key}][${formFieldIndex}]`, true) if (this.formFieldsList[key] && this.formFieldsList[key][formFieldIndex]) { const formField = this.formFieldsList[key][formFieldIndex] @@ -164,15 +165,15 @@ export default class ObjectField extends Field { - if (!formDataList[key]) formDataList[key] = [] - formDataList[key][formFieldIndex] = { status: 'normal' } - return { formDataList: cloneDeep(formDataList) } + if (!formDataList[key]) formDataList= set(formDataList, `[${key}]`, []) + formDataList = set(formDataList, `[${key}][${formFieldIndex}]`, { status: 'normal' }) + return { formDataList: formDataList } }) } else { await this.setState(({ formDataList }) => { - if (!formDataList[key]) formDataList[key] = [] - formDataList[key][formFieldIndex] = { status: 'error', message: validation[0].message } - return { formDataList: cloneDeep(formDataList) } + if (!formDataList[key]) formDataList= set(formDataList, `[${key}]`, []) + formDataList = set(formDataList, `[${key}][${formFieldIndex}]`, { status: 'error', message: validation[0].message }) + return { formDataList: formDataList } }) } } @@ -190,11 +191,11 @@ export default class ObjectField extends Field { formDataList[key] = [] - return { formDataList: cloneDeep(formDataList) } + return { formDataList: formDataList } }) this.props.onValueSet(key, {}, true) @@ -203,27 +204,27 @@ export default class ObjectField extends Field { - delete this.formFieldsList[key] - delete this.formFieldsMountedList[key] + this.formFieldsList = set(this.formFieldsList, `${this.formFieldsList[key]}`) + this.formFieldsMountedList = set(this.formFieldsMountedList, `${this.formFieldsMountedList[key]}`) await this.setState(({ formDataList }) => { - delete formDataList[key] - return { formDataList: cloneDeep(formDataList) } + formDataList = set(formDataList, `${formDataList[key]}`) + return { formDataList: formDataList } }) this.props.onValueUnset(key, true) } handleChangeKey = async (prev: string, next: string) => { - this.formFieldsList[next] = this.formFieldsList[prev] - delete this.formFieldsList[prev] + this.formFieldsList = set(this.formFieldsList, `[${next}]`, this.formFieldsList[prev]) + this.formFieldsList = set(this.formFieldsList, `${this.formFieldsList[prev]}`) - this.formFieldsMountedList[next] = this.formFieldsMountedList[prev] - delete this.formFieldsMountedList[prev] + this.formFieldsMountedList = set(this.formFieldsMountedList, `[${next}]`, this.formFieldsMountedList[prev]) + this.formFieldsMountedList = set(this.formFieldsMountedList, `${this.formFieldsMountedList[prev]}`) await this.setState(({ formDataList }) => { - formDataList[next] = formDataList[prev] - delete formDataList[prev] - return { formDataList: cloneDeep(formDataList) } + formDataList = set(formDataList, `[${next}]`, formDataList[prev]) + formDataList = set(formDataList, `${formDataList[prev]}`) + return { formDataList: formDataList } }) this.props.onValueSet(next, this.props.value[prev], true) @@ -242,17 +243,17 @@ export default class ObjectField extends Field { - // if (!formDataList[key]) formDataList[key] = [] - // formDataList[key][formFieldIndex] = { value, status: 'normal' } + // if (!formDataList[key]) formDataList = set(formDataList, `[${key}]`, []) + // formDataList = set(formDataList, `[${key}][${formFieldIndex}]`, { status: 'normal' }) // return { formDataList: cloneDeep(formDataList) } // }) // } else { // await this.setState(({ formDataList }) => { - // if (!formDataList[key]) formDataList[key] = [] - // formDataList[key][formFieldIndex] = { value, status: 'error', message: validation[0].message } + // if (!formDataList[key]) formDataList = set(formDataList, `[${key}]`, []) + // formDataList = set(formDataList, `[${key}][${formFieldIndex}]`, { status: 'error', message: validation[0].message }) // return { formDataList: cloneDeep(formDataList) } // }) // } @@ -265,11 +266,11 @@ export default class ObjectField extends Field extends Field extends Field extends Field extends Field extends Field await this.handleRemove(key), children: (Array.isArray(this.props.config.fields) ? this.props.config.fields : []).map((formFieldConfig, formFieldIndex) => { if (!ConditionHelper(formFieldConfig.condition, { record: this.props.record, data: this.props.data, step: this.props.step })) { - if (!this.formFieldsMountedList[key]) this.formFieldsMountedList[key] = [] - this.formFieldsMountedList[key][formFieldIndex] = false + if (!this.formFieldsMountedList[key]) this.formFieldsMountedList = set(this.formFieldsMountedList, `[${key}]`, []) + this.formFieldsMountedList = set(this.formFieldsMountedList, `[${key}][${formFieldIndex}]`, false) return null } let hidden: boolean = true @@ -459,8 +460,8 @@ export default class ObjectField extends Field | null) => { if (formField) { - if (!this.formFieldsList[key]) this.formFieldsList[key] = [] - this.formFieldsList[key][formFieldIndex] = formField + if (!this.formFieldsList[key]) this.formFieldsList = set(this.formFieldsList, `[${key}]`, []) + this.formFieldsList = set(this.formFieldsList, `[${key}][${formFieldIndex}]`, formField) this.handleMount(key, formFieldIndex) } }} @@ -468,7 +469,7 @@ export default class ObjectField extends Field this.handleChange(key, formFieldIndex, value)} diff --git a/src/components/formFields/tabs/index.tsx b/src/components/formFields/tabs/index.tsx index 72e98d6..1a286fb 100644 --- a/src/components/formFields/tabs/index.tsx +++ b/src/components/formFields/tabs/index.tsx @@ -2,8 +2,9 @@ import { Field, FieldConfig, FieldConfigs, FieldError, FieldProps, IField } from import getALLComponents from '../' import React from 'react' import ConditionHelper from '../../../util/condition' -import { cloneDeep } from 'lodash' -import { getValue, setValue, getBoolean, getChainPath } from '../../../util/value' +// import { cloneDeep } from 'lodash' +import { set, setValue } from '../../../util/produce' +import { getValue, getBoolean, getChainPath } from '../../../util/value' import StatementHelper from '../../../util/statement' export type TabsFieldConfig = TabsFieldConfig_Same | TabsFieldConfig_Diff @@ -114,7 +115,7 @@ export default class TabsField extends Field extends Field extends Field { - if (!formDataList[index]) formDataList[index] = [] - formDataList[index][formFieldIndex] = { status: 'normal' } - return { formDataList: cloneDeep(formDataList) } + if (!formDataList[index]) formDataList = set(formDataList, `[${index}]`, []) + formDataList= set(formDataList, `[${index}][${formFieldIndex}]`, { status: 'normal' }) + return { formDataList: formDataList } }) } else { await this.setState(({ formDataList }) => { - if (!formDataList[index]) formDataList[index] = [] - formDataList[index][formFieldIndex] = { status: 'error', message: validation[0].message } - return { formDataList: cloneDeep(formDataList) } + if (!formDataList[index]) formDataList = set(formDataList, `[${index}]`, []) + formDataList = set(formDataList, `[${index}][${formFieldIndex}]`, { status: 'error', message: validation[0].message }) + return { formDataList: formDataList } }) } } @@ -212,12 +213,12 @@ export default class TabsField extends Field extends Field extends Field extends Field extends Field extends Field { 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 + if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}]`, []) + this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}][${formFieldIndex}]`, false) return null } let hidden: boolean = true @@ -420,15 +421,15 @@ export default class TabsField extends Field | null) => { - if (!this.formFieldsList[index]) this.formFieldsList[index] = [] - this.formFieldsList[index][formFieldIndex] = formField + if (!this.formFieldsList[index]) this.formFieldsList = set(this.formFieldsList, `[${index}]`, []) + this.formFieldsList = set(this.formFieldsList, `[${index}][${formFieldIndex}]`, formField) this.handleMount(index, formFieldIndex) }} form={this.props.form} formLayout={this.props.formLayout} value={getValue(getValue(value, tab.field), formFieldConfig.field)} record={getValue(value, tab.field)} - data={cloneDeep(this.props.data)} + data={this.props.data} step={this.props.step} config={formFieldConfig} onChange={(value: any) => this.handleChange(index, formFieldIndex, value)} diff --git a/src/steps/common.tsx b/src/steps/common.tsx index d24543a..c76cbec 100644 --- a/src/steps/common.tsx +++ b/src/steps/common.tsx @@ -41,10 +41,10 @@ export interface StepProps { * 页面步骤基类 */ export default class Step extends React.Component, S> { - // static defaultProps = { // 暂时注释 - // config: { - // } - // }; + static defaultProps = { + config: { + } + }; stepPush = () => { this.props.onMount() diff --git a/src/steps/filter/index.tsx b/src/steps/filter/index.tsx index 74562d7..6994b28 100644 --- a/src/steps/filter/index.tsx +++ b/src/steps/filter/index.tsx @@ -4,9 +4,10 @@ import Step, { StepConfig, StepProps } from '../common' import getALLComponents from '../../components/formFields' import { ParamConfig } from '../../interface' import ParamHelper from '../../util/param' -import { cloneDeep, get, set, unset } from 'lodash' +import { get } from 'lodash' +import { push, splice, sort, set, setValue } from '../../util/produce' import ConditionHelper from '../../util/condition' -import { getValue, setValue, listItemMove, getChainPath } from '../../util/value' +import { getValue, getChainPath } from '../../util/value' /** * 表单步骤配置文件格式定义 @@ -118,13 +119,13 @@ export default class FilterStep extends Step { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] const value = (formFieldConfig.field === undefined || formFieldConfig.field === '') ? formDefault : get(formDefault, formFieldConfig.field) this.formValue = setValue(this.formValue, formFieldConfig.field, value) - this.formData[formFieldIndex] = { status: 'normal' } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal' }) } } await this.setState({ formValue: this.formValue, - formData: cloneDeep(this.formData) + formData: this.formData }) // 表单初始化结束,展示表单界面。 @@ -141,7 +142,7 @@ export default class FilterStep extends Step { return true } - this.formFieldsMounted[formFieldIndex] = true + this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, true) if (this.formFields[formFieldIndex]) { const formField = this.formFields[formFieldIndex] @@ -157,16 +158,16 @@ export default class FilterStep extends Step { if (value !== undefined) { const validation = await formField.validate(value) if (validation === true) { - this.formData[formFieldIndex] = { status: 'normal' } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal' }) } else { - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message }) } } } } await this.setState({ formValue: this.formValue, - formData: cloneDeep(this.formData) + formData: this.formData }) } @@ -198,7 +199,7 @@ export default class FilterStep extends Step { console.info('表单校验通过', data) await this.setState({ - formData: cloneDeep(this.formData) + formData: this.formData }) if (canSubmit && this.props.onSubmit) { @@ -235,16 +236,16 @@ export default class FilterStep extends Step { const validation = await formField.validate(value) if (validation === true) { - this.formData[formFieldIndex] = { status: 'normal' } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal' }) } else { - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message }) } } } await this.setState({ formValue: this.formValue, - formData: cloneDeep(this.formData) + formData: this.formData }) this.handleSubmit() @@ -263,14 +264,14 @@ export default class FilterStep extends Step { const validation = await formField.validate(value) if (validation === true) { - this.formData[formFieldIndex] = { status: 'normal' } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal' }) } else { - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message }) } await this.setState({ formValue: this.formValue, - formData: cloneDeep(this.formData) + formData: this.formData }) if (this.props.onChange) { this.props.onChange(this.formValue) @@ -283,7 +284,7 @@ export default class FilterStep extends Step { if (formFieldConfig) { const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - set(this.formValue, fullPath, value) + this.formValue = set(this.formValue, fullPath, value) this.setState({ formValue: this.formValue }) @@ -292,13 +293,13 @@ export default class FilterStep extends Step { } if (validation === true) { - this.formData[formFieldIndex] = { status: 'normal' } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal' }) } else { - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message }) } await this.setState({ - formData: cloneDeep(this.formData) + formData: this.formData }) } } @@ -308,7 +309,8 @@ export default class FilterStep extends Step { if (formFieldConfig) { const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - unset(this.formValue, fullPath) + // unset(this.formValue, fullPath) + this.formValue = set(this.formValue, fullPath) this.setState({ formValue: this.formValue }) @@ -317,13 +319,13 @@ export default class FilterStep extends Step { } if (validation === true) { - this.formData[formFieldIndex] = { status: 'normal' } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal' }) } else { - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message }) } await this.setState({ - formData: cloneDeep(this.formData) + formData: this.formData }) } } @@ -333,9 +335,7 @@ export default class FilterStep extends Step { if (formFieldConfig) { const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - const list = get(this.formValue, fullPath, []) - list.push(value) - set(this.formValue, fullPath, list) + this.formValue = push(this.formValue, fullPath, value) this.setState({ formValue: this.formValue }) @@ -344,13 +344,13 @@ export default class FilterStep extends Step { } if (validation === true) { - this.formData[formFieldIndex] = { status: 'normal' } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal' }) } else { - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message }) } await this.setState({ - formData: cloneDeep(this.formData) + formData: this.formData }) } } @@ -360,9 +360,7 @@ export default class FilterStep extends Step { if (formFieldConfig) { const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - const list = get(this.formValue, fullPath, []) - list.splice(index, count) - set(this.formValue, fullPath, list) + this.formValue = splice(this.formValue, fullPath, index, count) this.setState({ formValue: this.formValue }) @@ -371,13 +369,13 @@ export default class FilterStep extends Step { } if (validation === true) { - this.formData[formFieldIndex] = { status: 'normal' } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal' }) } else { - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message }) } await this.setState({ - formData: cloneDeep(this.formData) + formData: this.formData }) } } @@ -386,8 +384,7 @@ export default class FilterStep extends Step { 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.formValue = sort(this.formValue, fullPath, index, sortType) this.setState({ formValue: this.formValue }) @@ -396,13 +393,13 @@ export default class FilterStep extends Step { } if (validation === true) { - this.formData[formFieldIndex] = { status: 'normal' } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal' }) } else { - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message }) } await this.setState({ - formData: cloneDeep(this.formData) + formData: this.formData }) } } @@ -453,7 +450,7 @@ export default class FilterStep extends Step { resetText: this.props.config?.resetText?.replace(/(^\s*)|(\s*$)/g, ""), children: fields.map((formFieldConfig, formFieldIndex) => { if (!ConditionHelper(formFieldConfig.condition, { record: formValue, data, step })) { - this.formFieldsMounted[formFieldIndex] = false + this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, false) return null } let hidden: boolean = true @@ -488,7 +485,7 @@ export default class FilterStep extends Step { key={formFieldIndex} ref={(formField: Field | null) => { if (formFieldIndex !== null) { - this.formFields[formFieldIndex] = formField + this.formFields = set(this.formFields, `[${formFieldIndex}]`, formField) this.handleFormFieldMount(formFieldIndex) } }} @@ -496,9 +493,9 @@ export default class FilterStep extends Step { formLayout={'inline'} value={formFieldConfig.field !== undefined ? get(formValue, formFieldConfig.field) : undefined} record={formValue} - step={cloneDeep(formValue)} + step={formValue} // step={step} - data={cloneDeep(data)} + data={data} config={formFieldConfig} onChange={async (value: any) => { await this.handleChange(formFieldIndex, value) }} onValueSet={async (path, value, validation) => await this.handleValueSet(formFieldIndex, path, value, validation)} diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index 929b021..83ef800 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -3,10 +3,10 @@ import { Field, FieldConfigs, FieldError } from '../../components/formFields/com import Step, { StepConfig, StepProps } from '../common' import getALLComponents from '../../components/formFields' // import { getValue, setValue, listItemMove, getBoolean, getChainPath } from '../../util/value' -import { getValue, listItemMove, getBoolean, getChainPath } from '../../util/value' +import { getValue, getBoolean, getChainPath } from '../../util/value' import { ParamConfig } from '../../interface' import ParamHelper from '../../util/param' -import { get, unset, update , isEqual } from 'lodash' +import { get, unset } from 'lodash' import { push, splice, sort, set, setValue } from '../../util/produce' import ConditionHelper, { ConditionConfig } from '../../util/condition' import StatementHelper, { StatementConfig } from '../../util/statement' @@ -226,9 +226,9 @@ export default class FormStep extends Step { // ts对clas for (const formFieldIndex in formFieldsConfig) { const formFieldConfig = formFieldsConfig[formFieldIndex] const value = getValue(formDefault, formFieldConfig.field) - + this.formValue = setValue(this.formValue, formFieldConfig.field, value) - this.formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal', name: formFieldConfig.label }) } } @@ -246,7 +246,7 @@ export default class FormStep extends Step { // ts对clas if (this.formFieldsMounted[formFieldIndex]) { return true } - this.formFieldsMounted[formFieldIndex] = true + this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, true) if (this.formFields[formFieldIndex]) { const formField = this.formFields[formFieldIndex] @@ -262,9 +262,9 @@ export default class FormStep extends Step { // ts对clas if (value !== undefined) { const validation = await formField.validate(value) if (validation === true) { - this.formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal', name: formFieldConfig.label }) } else { - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message, name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message, name: formFieldConfig.label }) } } await formField.didMount() @@ -305,7 +305,7 @@ export default class FormStep extends Step { // ts对clas if (validation !== true) { console.warn('表单项中存在问题', value, formFieldConfig) - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message, name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message, name: formFieldConfig.label }) this.canSubmit = false } this.submitData = setValue(this.submitData, formFieldConfig.field, value) @@ -362,9 +362,9 @@ export default class FormStep extends Step { // ts对clas const validation = await formField.validate(value) if (validation === true) { - this.formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal', name: formFieldConfig.label }) } else { - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message, name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message, name: formFieldConfig.label }) } await this.setState({ @@ -398,9 +398,9 @@ export default class FormStep extends Step { // ts对clas } if (validation === true) { - this.formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal', name: formFieldConfig.label }) } else { - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message, name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message, name: formFieldConfig.label }) } console.log('form set data', this.formData) @@ -416,7 +416,8 @@ export default class FormStep extends Step { // ts对clas if (formFieldConfig) { const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - unset(this.formValue, fullPath) + // unset(this.formValue, fullPath) + this.formValue = set(this.formValue, fullPath) this.setState({ formValue: this.formValue }) @@ -425,9 +426,9 @@ export default class FormStep extends Step { // ts对clas } if (validation === true) { - this.formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal', name: formFieldConfig.label }) } else { - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message, name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message, name: formFieldConfig.label }) } await this.setState({ @@ -440,6 +441,7 @@ export default class FormStep extends Step { // ts对clas const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] if (formFieldConfig) { const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` +console.log('step handleValueListAppend', fullPath, value); this.formValue = push(this.formValue, fullPath, value) //向this.formValue的fullPath下的值添加value this.setState({ @@ -450,9 +452,9 @@ export default class FormStep extends Step { // ts对clas } if (validation === true) { - this.formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal', name: formFieldConfig.label }) } else { - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message, name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message, name: formFieldConfig.label }) } await this.setState({ @@ -475,9 +477,9 @@ export default class FormStep extends Step { // ts对clas } if (validation === true) { - this.formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal', name: formFieldConfig.label }) } else { - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message, name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message, name: formFieldConfig.label }) } await this.setState({ @@ -500,9 +502,9 @@ export default class FormStep extends Step { // ts对clas } if (validation === true) { - this.formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal', name: formFieldConfig.label }) } else { - this.formData[formFieldIndex] = { status: 'error', message: validation[0].message, name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message, name: formFieldConfig.label }) } await this.setState({ @@ -659,7 +661,7 @@ export default class FormStep extends Step { // ts对clas console.log('this.dependentFieldsArr--formStep', this.dependentFieldsArr); } if (!ConditionHelper(formFieldConfig.condition, { record: formValue, data, step: formValue })) { - this.formFieldsMounted[formFieldIndex] = false + this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, false) return null } let hidden: boolean = true @@ -677,7 +679,7 @@ export default class FormStep extends Step { // ts对clas // 隐藏项同时打标录入数据并清空填写项 if (!hidden) { - this.formData[formFieldIndex] = { status: 'normal', name: formFieldConfig.label } + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal', name: formFieldConfig.label }) } const FormField = this.getALLComponents(formFieldConfig.type) || Field @@ -703,7 +705,7 @@ export default class FormStep extends Step { // ts对clas key={formFieldIndex} ref={(formField: Field | null) => { if (formField !== null) { - this.formFields[formFieldIndex] = formField + this.formFields = set(this.formFields, `[${formFieldIndex}]`, formField) this.handleFormFieldMount(formFieldIndex) } }} diff --git a/src/steps/table/index.tsx b/src/steps/table/index.tsx index 85ebdc1..9c05ee7 100644 --- a/src/steps/table/index.tsx +++ b/src/steps/table/index.tsx @@ -5,7 +5,7 @@ import getALLComponents, { ColumnConfigs } from '../../components/tableColumns' import Step, { StepConfig, StepProps } from '../common' import { ParamConfig } from '../../interface' import ColumnStyleComponent from './common/columnStyle' -import CCMS_123, { CCMSConfig } from '../../main' +import CCMS, { CCMSConfig } from '../../main' import { cloneDeep, get, set } from 'lodash' import InterfaceHelper, { InterfaceConfig } from '../../util/interface' import ConditionHelper, { ConditionConfig } from '../../util/condition' @@ -217,7 +217,7 @@ interface TableState { * 表格步骤组件 */ export default class TableStep extends Step { - CCMS_ = CCMS_123 + CCMS = CCMS getALLComponents = (type: any) => getALLComponents[type] interfaceHelper = new InterfaceHelper() /** @@ -660,7 +660,7 @@ export default class TableStep extends Step { }) } - const CCMS = this.CCMS_ + const CCMS = this.CCMS return ( diff --git a/src/util/produce.tsx b/src/util/produce.tsx index 40ea1f3..70651ad 100644 --- a/src/util/produce.tsx +++ b/src/util/produce.tsx @@ -19,10 +19,14 @@ type OperationType = 'set' | 'push' | 'splice' * @param value * @returns */ -export const set = (current: any, path?: string, value?: any) => { +export function set (current: any, path?: string, value?: any) { let target = produce(current, (draft: any) => { if (path) { - return lodash.set(draft, path, value) + if (arguments.length == 2) { // 移除对象路径的属性 参数改动时同步修改这块 + lodash.unset(draft, path) + } else { + return lodash.set(draft, path, value) + } } return draft }) @@ -36,12 +40,15 @@ export const set = (current: any, path?: string, value?: any) => { * @returns */ export const push = (current: any, path: string = '', value?: any) => { - let list const target = produce(current, (draft: any) => { - if (!path) list = draft // path为空时,向current根路径push - else list = lodash.get(draft, path, []) - console.log('error', lodash.concat(list, value)); - list.push(value) + let list = lodash.get(draft, path) + if (!Array.isArray(list)) { // 如果指定路径下不是数组类型 + var tempArr = [] + tempArr.push(value) + lodash.set(draft, path, tempArr) + } else { + list.push(value) + } }) return target } @@ -55,10 +62,8 @@ export const push = (current: any, path: string = '', value?: any) => { * @returns */ export const splice = (current: any, path: string='', index: number, count: number) => { - let list const target = produce(current, (draft: any) => { - if (!path) list = draft - else list = lodash.get(draft, path, []) + const list = lodash.get(draft, path, []) list.splice(index, count) }) return target @@ -73,10 +78,8 @@ export const splice = (current: any, path: string='', index: number, count: numb * @returns */ export const sort = (current: any, path: string='', index: number, sortType: 'up' | 'down') => { - let list const target = produce(current, (draft: any) => { - if (!path) list = draft - else list = lodash.get(draft, path, []) + const list = lodash.get(draft, path, []) listItemMove(list, index, sortType) }) return target -- Gitee From 3d5b69742d3d98c82100250ed842944c4538cf2b Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Wed, 19 Jan 2022 17:12:26 +0800 Subject: [PATCH 09/38] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0dependentFields?= =?UTF-8?q?=E3=80=81onReportFields?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/any/index.tsx | 3 ++ src/components/formFields/common.tsx | 14 ++++--- src/components/formFields/form/index.tsx | 33 ++++++++-------- src/components/formFields/group/index.tsx | 22 +++++++++-- .../formFields/importSubform/index.tsx | 39 ++++++++++--------- src/components/formFields/object/index.tsx | 18 ++++++++- src/components/formFields/tabs/index.tsx | 20 +++++++++- src/steps/filter/index.tsx | 20 +++++++++- src/steps/form/index.tsx | 35 ++++++++++------- src/util/produce.tsx | 3 +- src/util/value.ts | 24 +++++++++++- 11 files changed, 168 insertions(+), 63 deletions(-) diff --git a/src/components/formFields/any/index.tsx b/src/components/formFields/any/index.tsx index 5b2ea1e..63c6865 100644 --- a/src/components/formFields/any/index.tsx +++ b/src/components/formFields/any/index.tsx @@ -99,6 +99,7 @@ export default class AnyField extends Field : ( type === 'number' ? {}} @@ -118,6 +119,7 @@ export default class AnyField extends Field : {}} form={this.props.form} @@ -136,6 +138,7 @@ export default class AnyField extends Field ) })} diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index 1d870ed..8f1c3f9 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -94,6 +94,8 @@ export interface FieldProps { onValueListSort: (path: string, index: number, sortType: 'up' | 'down', validation: true | FieldError[]) => Promise baseRoute: string, path: string, // 组件所在路径以字段拼接展示 + dependentFields: string[] // condition依赖字段存放数组 + onReportFields?:(fields: string[]) => Promise //向上层上报依赖字段 step: { [field: string]: any } // 传递formValue loadDomain: (domain: string) => Promise } @@ -173,17 +175,19 @@ export class Field extends React.Component< 当前UI库未实现该表单类型 } - dependentFieldsArr: any shouldComponentUpdate(nextProps:FieldProps, nextState: S) { console.log('nextProps', nextProps, this.props, nextProps.value == this.props.value); - console.log('this.dependentFieldsArr',this.dependentFieldsArr); - const dependentFieldsArr = this.dependentFieldsArr + const dependentFieldsArr = nextProps.dependentFields + // console.log('dependentFieldsArr',dependentFieldsArr); let dependentIsChange = false - if (dependentFieldsArr) { + if (dependentFieldsArr && dependentFieldsArr.length) { for (let i=0;i< dependentFieldsArr.length;i++) { const nextDependentField = get(nextProps.step, dependentFieldsArr[i]) const currentDependentField = get(this.props.step, dependentFieldsArr[i]) - if (nextDependentField !== currentDependentField) { + if ((nextDependentField || currentDependentField) && nextDependentField !== currentDependentField) { + dependentIsChange = true + break + } else if (dependentFieldsArr[i].includes(nextProps.path)) { dependentIsChange = true break } diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index 1709298..9bab838 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -3,8 +3,8 @@ import { Field, FieldConfig, FieldConfigs, FieldError, FieldProps, IField } from import getALLComponents from '../' // import { getValue, listItemMove, setValue, getBoolean, getChainPath } from '../../../util/value' // import { cloneDeep } from 'lodash' -import { getValue, getBoolean, getChainPath } from '../../../util/value' -import { set, setValue , sort, splice} from '../../../util/produce' +import { getValue, getBoolean, getChainPath, getDependentFieldsArr } from '../../../util/value' +import { set, setValue , sort, splice, push } from '../../../util/produce' import ConditionHelper from '../../../util/condition' import StatementHelper from '../../../util/statement' @@ -68,7 +68,7 @@ export default class FormField extends Field | null>> = [] formFieldsMountedList: Array> = [] - dependentFieldsArr: string[] = [] //condition中依赖字段的存放数组 + dependentFields_: string[] = [] constructor (props: FieldProps) { super(props) @@ -232,6 +232,10 @@ export default class FormField extends Field { + const dependentFields_ = this.dependentFields_.concat(fields) + this.props.onReportFields && await this.props.onReportFields(dependentFields_) + } /** * 用于展示子表单组件中的每一子项中的每一个子表单项组件 * @param props @@ -494,19 +506,6 @@ export default class FormField extends Field await this.handleSort(index, sortType) : undefined, canCollapse, children: (fields || []).map((formFieldConfig, fieldIndex) => { - const conditionParams = formFieldConfig.condition?.params - if (conditionParams && Array.isArray(conditionParams)) { - const dependentFieldsArr = conditionParams.map(ite => { - if (ite.data?.source === 'record') { - return ite?.data?.field && `${this.props.path}.${ite.data.field}` - } else if (ite.data?.source === 'data' || ite.data?.source === 'step') { - return ite?.data?.field && `${ite.data.field}` - } - return '' - }).filter(ite=>ite) - this.dependentFieldsArr = dependentFieldsArr - console.log('this.dependentFieldsArr--formList', this.dependentFieldsArr); - } if (!ConditionHelper(formFieldConfig.condition, { record: itemValue, data: this.props.data, step: this.props.step })) { if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `${index}`, [] ) // this.formFieldsMountedList[index][fieldIndex] = false @@ -560,6 +559,8 @@ export default class FormField extends Field await this.props.loadDomain(domain)} path={getChainPath(`${fieldIndex}.${formFieldConfig.field}`, this.props.path)} + dependentFields={getDependentFieldsArr(formFieldConfig, this.props)} + onReportFields={async (fields: string[]) => await this.handleReportFields(fields)} /> ) }) diff --git a/src/components/formFields/group/index.tsx b/src/components/formFields/group/index.tsx index d80055c..1b8ebd6 100644 --- a/src/components/formFields/group/index.tsx +++ b/src/components/formFields/group/index.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { getValue, getBoolean, getChainPath } from '../../../util/value' +import { getValue, getBoolean, getChainPath, getDependentFieldsArr } from '../../../util/value' import { Field, FieldConfig, FieldError, FieldProps, IField } from '../common' import getALLComponents, { FieldConfigs } from '../' import { IFormItem } from '../../../steps/form' @@ -28,7 +28,8 @@ export default class GroupField extends Field | null> = [] formFieldsMounted: Array = [] - + dependentFields_: string[] = [] + constructor (props: FieldProps) { super(props) @@ -99,12 +100,16 @@ export default class GroupField extends Field { + const dependentFields_ = this.dependentFields_.concat(fields) + this.props.onReportFields && await this.props.onReportFields(dependentFields_) + } + renderComponent = (props: IGroupField) => { return 您当前使用的UI版本没有实现GroupField组件。 @@ -346,6 +360,8 @@ export default class GroupField extends Field await this.props.loadDomain(domain)} path={getChainPath(formFieldConfig.field, this.props.path)} + dependentFields={getDependentFieldsArr(formFieldConfig, this.props)} + onReportFields={async(fields: string[]) => await this.handleReportFields(fields)} /> ) } diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx index 9514d35..9efde32 100644 --- a/src/components/formFields/importSubform/index.tsx +++ b/src/components/formFields/importSubform/index.tsx @@ -1,12 +1,12 @@ import React from 'react' // import { setValue, getValue, getBoolean, getChainPath } from '../../../util/value' -import { getValue, getBoolean, getChainPath } from '../../../util/value' +import { getValue, getBoolean, getChainPath, getDependentFieldsArr } from '../../../util/value' import { Field, FieldConfig, FieldError, FieldProps, IField } from '../common' import getALLComponents, { FieldConfigs } from '../' import { IFormItem } from '../../../steps/form' -// import { cloneDeep } from 'lodash' -import { set, setValue } from '../../../util/produce' +import { concat, uniq } from 'lodash' +import { set, setValue, push } from '../../../util/produce' import ConditionHelper from '../../../util/condition' import InterfaceHelper, { InterfaceConfig } from '../../../util/interface' import StatementHelper from '../../../util/statement' @@ -48,7 +48,8 @@ export default class ImportSubformField extends Field | null> = [] formFieldsMounted: Array = [] - + dependentFields_: string[] = [] + interfaceHelper = new InterfaceHelper() constructor (props: FieldProps) { @@ -148,13 +149,17 @@ export default class ImportSubformField extends Field { + const dependentFields_ = this.dependentFields_.concat(fields) + this.props.onReportFields && await this.props.onReportFields(dependentFields_) + } + renderComponent = (props: IImportSubformField) => { return 您当前使用的UI版本没有实现ImportSubformField组件。 @@ -371,19 +385,6 @@ export default class ImportSubformField extends Field { - const conditionParams = formFieldConfig.condition?.params - if (conditionParams && Array.isArray(conditionParams)) { - const dependentFieldsArr = conditionParams.map(ite => { - if (ite.data?.source === 'record') { - return ite?.data?.field && `${this.props.path}.${ite.data.field}` - } else if (ite.data?.source === 'data' || ite.data?.source === 'step') { - return ite?.data?.field && `${ite.data.field}` - } - return '' - }).filter(ite=>ite) - this.dependentFieldsArr = dependentFieldsArr - console.log('this.dependentFieldsArr--子表单', this.dependentFieldsArr); - } if (!ConditionHelper(formFieldConfig.condition, { record: value, data, step })) { this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, false) return null @@ -445,6 +446,8 @@ export default class ImportSubformField extends Field await this.props.loadDomain(domain)} path={getChainPath(formFieldConfig.field, this.props.path)} + dependentFields={getDependentFieldsArr(formFieldConfig, this.props)} + onReportFields={async(fields: string[]) => await this.handleReportFields(fields)} /> ) } diff --git a/src/components/formFields/object/index.tsx b/src/components/formFields/object/index.tsx index 5025b52..cd88f6c 100644 --- a/src/components/formFields/object/index.tsx +++ b/src/components/formFields/object/index.tsx @@ -4,7 +4,7 @@ import React from 'react' import ConditionHelper from '../../../util/condition' // import { cloneDeep } from 'lodash' import { set, setValue } from '../../../util/produce' -import { getValue, getBoolean, getChainPath } from '../../../util/value' +import { getValue, getBoolean, getChainPath, getDependentFieldsArr } from '../../../util/value' import StatementHelper from '../../../util/statement' export interface ObjectFieldConfig extends FieldConfig { @@ -54,6 +54,7 @@ export default class ObjectField extends Field | null> } = {} formFieldsMountedList: { [key: string]: Array } = {} + dependentFields_: string[] = [] constructor (props: FieldProps) { super(props) @@ -150,6 +151,10 @@ export default class ObjectField extends Field extends Field { + const dependentFields_ = this.dependentFields_.concat(fields) + this.props.onReportFields && await this.props.onReportFields(dependentFields_) + } + /** * 用于展示子表单组件 * @param _props @@ -481,6 +495,8 @@ export default class ObjectField extends Field this.props.loadDomain(domain)} path={getChainPath(formFieldConfig.field, this.props.path)} + dependentFields={getDependentFieldsArr(formFieldConfig, this.props)} + onReportFields={async(fields: string[]) => await this.handleReportFields(fields)} /> ) }) diff --git a/src/components/formFields/tabs/index.tsx b/src/components/formFields/tabs/index.tsx index 1a286fb..d956464 100644 --- a/src/components/formFields/tabs/index.tsx +++ b/src/components/formFields/tabs/index.tsx @@ -4,7 +4,7 @@ import React from 'react' import ConditionHelper from '../../../util/condition' // import { cloneDeep } from 'lodash' import { set, setValue } from '../../../util/produce' -import { getValue, getBoolean, getChainPath } from '../../../util/value' +import { getValue, getBoolean, getChainPath, getDependentFieldsArr } from '../../../util/value' import StatementHelper from '../../../util/statement' export type TabsFieldConfig = TabsFieldConfig_Same | TabsFieldConfig_Diff @@ -66,7 +66,8 @@ export default class TabsField extends Field | null>> = [] formFieldsMountedList: Array> = [] - + dependentFields_: string[] = [] + constructor (props: FieldProps) { super(props) @@ -167,6 +168,10 @@ export default class TabsField extends Field extends Field { + const dependentFields_ = this.dependentFields_.concat(fields) + this.props.onReportFields && await this.props.onReportFields(dependentFields_) + } + /** * 用于展示子表单组件 * @param _props @@ -441,6 +455,8 @@ export default class TabsField extends Field await this.props.loadDomain(domain)} path={getChainPath(formFieldConfig.field, this.props.path)} + dependentFields={getDependentFieldsArr(formFieldConfig, this.props)} + onReportFields={async(fields: string[]) => await this.handleReportFields(fields)} /> ) })} diff --git a/src/steps/filter/index.tsx b/src/steps/filter/index.tsx index 6994b28..0998c97 100644 --- a/src/steps/filter/index.tsx +++ b/src/steps/filter/index.tsx @@ -7,7 +7,7 @@ import ParamHelper from '../../util/param' import { get } from 'lodash' import { push, splice, sort, set, setValue } from '../../util/produce' import ConditionHelper from '../../util/condition' -import { getValue, getChainPath } from '../../util/value' +import { getValue, getChainPath, getDependentFieldsArr } from '../../util/value' /** * 表单步骤配置文件格式定义 @@ -89,6 +89,7 @@ export default class FilterStep extends Step { // 各表单项所使用的UI组件的实例 formFields: Array | null> = [] formFieldsMounted: Array = [] + dependentFields_: string[] = [] formValue: { [field: string]: any } = {} formData: { status: 'normal' | 'error' | 'loading', message?: string }[] = [] @@ -404,6 +405,21 @@ export default class FilterStep extends Step { } } + /** + * 上报condition依赖字段名称 + * @param fields + */ + handleReportFields = async (fields: string[]) => { + const dependentFields_ = this.dependentFields_ + for(let i=0;i { baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} path={getChainPath(formFieldIndex, formFieldConfig.field)} + dependentFields={this.dependentFields_} + onReportFields={async (fields: string[]) => await this.handleReportFields(fields)} /> ) } diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index 83ef800..d8420fa 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -3,7 +3,7 @@ import { Field, FieldConfigs, FieldError } from '../../components/formFields/com import Step, { StepConfig, StepProps } from '../common' import getALLComponents from '../../components/formFields' // import { getValue, setValue, listItemMove, getBoolean, getChainPath } from '../../util/value' -import { getValue, getBoolean, getChainPath } from '../../util/value' +import { getValue, getBoolean, getChainPath, getDependentFieldsArr } from '../../util/value' import { ParamConfig } from '../../interface' import ParamHelper from '../../util/param' import { get, unset } from 'lodash' @@ -11,6 +11,7 @@ import { push, splice, sort, set, setValue } from '../../util/produce' import ConditionHelper, { ConditionConfig } from '../../util/condition' import StatementHelper, { StatementConfig } from '../../util/statement' import OperationHelper, { OperationConfig } from '../../util/operation' +import { timingSafeEqual } from 'crypto' /** * 表单步骤配置文件格式定义 @@ -167,12 +168,12 @@ export default class FormStep extends Step { // ts对clas // 各表单项对应的类型所使用的UI组件的类 getALLComponents = (type: any): typeof Field => getALLComponents[type] OperationHelper = OperationHelper - dependentFieldsArr: string[] = [] //condition中依赖字段的存放数组 // 各表单项所使用的UI组件的实例 formFields: Array | null> = [] formFieldsMounted: Array = [] + dependentFields_: string[] = [] formValue: { [field: string]: any } = {} formData: { status: 'normal' | 'error' | 'loading', message?: string, name: string }[] = [] @@ -525,6 +526,21 @@ console.log('step handleValueListAppend', fullPath, value); } } } +/** + * 上报condition依赖字段名称 + * @param fields + */ + handleReportFields = async (fields: string[]) => { + const dependentFields_ = this.dependentFields_ + for(let i=0;i { - const conditionParams = formFieldConfig.condition?.params - if (conditionParams && Array.isArray(conditionParams)) { - const dependentFieldsArr = conditionParams.map(ite => { - if (ite.data?.source === 'record') { - return ite?.data?.field && `${getChainPath(formFieldConfig.field)}.${ite.data.field}` - } else if (ite.data?.source === 'data' || ite.data?.source === 'step') { - return ite?.data?.field && `${ite.data.field}` - } - return '' - }).filter(ite=>ite) - this.dependentFieldsArr = dependentFieldsArr - console.log('this.dependentFieldsArr--formStep', this.dependentFieldsArr); - } if (!ConditionHelper(formFieldConfig.condition, { record: formValue, data, step: formValue })) { this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, false) return null @@ -726,6 +729,8 @@ console.log('step handleValueListAppend', fullPath, value); baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} path={formFieldConfig.field} + dependentFields={this.dependentFields_} + onReportFields={async (fields: string[]) => await this.handleReportFields(fields)} /> ) } diff --git a/src/util/produce.tsx b/src/util/produce.tsx index 70651ad..5f5889a 100644 --- a/src/util/produce.tsx +++ b/src/util/produce.tsx @@ -70,7 +70,7 @@ export const splice = (current: any, path: string='', index: number, count: numb } /** - * 数组排序 + * current指定路径下数组排序 * @param current * @param path * @param index @@ -85,6 +85,7 @@ export const sort = (current: any, path: string='', index: number, sortType: 'up return target } + /** * lodash 递归合并来源对象的自身和继承的可枚举属性到目标对象 * @param a 目标对象 diff --git a/src/util/value.ts b/src/util/value.ts index 87e6014..766dc5f 100644 --- a/src/util/value.ts +++ b/src/util/value.ts @@ -1,6 +1,7 @@ import queryString from 'query-string' import { ParamConfig } from '../interface' import { set, get, isArray, assignInWith, isObject, isUndefined } from 'lodash' +import { FieldConfig } from '../components/formFields/common' export const getValue = (obj: any, path: string = '', defaultValue: any = undefined) => { if (path === undefined) { @@ -133,4 +134,25 @@ export const getChainPath = (currentPath: string | number = '', sourcePath: stri if (!sourcePath && sourcePath !== 0) {sourcePath = ''} else {sourcePath = sourcePath.toString()} const finalPath = (sourcePath +'.'+ currentPath).replace(/(^\.*)|(\.*$)|(\.){2,}/g, '$3') return finalPath -} \ No newline at end of file +} + +/** + * 获取condition依赖字段存放数组 + * @param formFieldConfig + * @returns + */ + export const getDependentFieldsArr = (formFieldConfig: FieldConfig, props: any) => { + const conditionParams = formFieldConfig.condition?.params + if (conditionParams && Array.isArray(conditionParams) && conditionParams.length) { + return conditionParams.map(ite => { + if (ite.data?.source === 'record') { + return ite?.data?.field && `${props.path}.${ite.data.field}` + } else if (ite.data?.source === 'data' || ite.data?.source === 'step') { + return ite?.data?.field && `${ite.data.field}` + } + return '' + }).filter(ite=>ite) + } + return [] +} + -- Gitee From f9d215be601b5d75675cba5f602b5809e5108d32 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Thu, 20 Jan 2022 11:33:17 +0800 Subject: [PATCH 10/38] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9SCU=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/common.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index df8d10d..9189179 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -186,9 +186,11 @@ export class Field extends React.Component< for (let i=0;i< dependentFieldsArr.length;i++) { const nextDependentField = get(nextProps.step, dependentFieldsArr[i]) const currentDependentField = get(this.props.step, dependentFieldsArr[i]) - if ((nextDependentField || currentDependentField) && nextDependentField !== currentDependentField) { - dependentIsChange = true - break + if ((nextDependentField || currentDependentField) ) { + if (nextDependentField !== currentDependentField) { + dependentIsChange = true + break + } } else if (dependentFieldsArr[i].includes(nextProps.path)) { dependentIsChange = true break -- Gitee From 2664a3dcbaa75bb258a7c69f47b81a05c354900c Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Thu, 20 Jan 2022 11:51:02 +0800 Subject: [PATCH 11/38] =?UTF-8?q?fix:=20tabs=E4=BF=AE=E6=94=B9=E4=B8=8D?= =?UTF-8?q?=E5=8F=AF=E6=8B=93=E5=B1=95=E5=B1=9E=E6=80=A7=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/tabs/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/formFields/tabs/index.tsx b/src/components/formFields/tabs/index.tsx index d956464..fa16644 100644 --- a/src/components/formFields/tabs/index.tsx +++ b/src/components/formFields/tabs/index.tsx @@ -153,12 +153,12 @@ export default class TabsField extends Field { if (!this.formFieldsMountedList[index]) { - this.formFieldsMountedList[index] = [] + this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}]`, []) } if (this.formFieldsMountedList[index][formFieldIndex]) { return true } - this.formFieldsMountedList[index][formFieldIndex] = true + this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}][${formFieldIndex}]`, true) const tab = (this.props.config.tabs || [])[index] -- Gitee From d90c90dc9ab1e3253363669d254dbea313f807b2 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Thu, 20 Jan 2022 18:43:29 +0800 Subject: [PATCH 12/38] =?UTF-8?q?fix:=E5=AD=97=E6=AE=B5=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E9=80=BB=E8=BE=91=E6=9B=B4=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/common.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index 9189179..195a09c 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -186,12 +186,12 @@ export class Field extends React.Component< for (let i=0;i< dependentFieldsArr.length;i++) { const nextDependentField = get(nextProps.step, dependentFieldsArr[i]) const currentDependentField = get(this.props.step, dependentFieldsArr[i]) - if ((nextDependentField || currentDependentField) ) { - if (nextDependentField !== currentDependentField) { + if (dependentFieldsArr[i] === nextProps.path) { // 处于最后一层依赖字段 + if ((nextDependentField || currentDependentField) && (nextDependentField !== currentDependentField)) { dependentIsChange = true break } - } else if (dependentFieldsArr[i].includes(nextProps.path)) { + } else if (dependentFieldsArr[i].includes(nextProps.path)){ dependentIsChange = true break } -- Gitee From 1ca7c06e17121d845dd0de26912864fe5f7ee631 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Mon, 24 Jan 2022 14:14:15 +0800 Subject: [PATCH 13/38] =?UTF-8?q?fix:=20paramHelper=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E4=B8=8A=E6=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/common.tsx | 21 +++--- src/components/formFields/form/index.tsx | 31 ++++---- src/components/formFields/group/index.tsx | 29 ++++---- .../formFields/importSubform/index.tsx | 33 ++++----- src/components/formFields/object/index.tsx | 23 +++--- src/components/formFields/select/common.tsx | 4 +- src/components/formFields/tabs/index.tsx | 25 ++++--- src/steps/detail/index.tsx | 2 +- src/steps/filter/index.tsx | 27 +++---- src/steps/form/index.tsx | 36 +++++----- src/steps/header/index.tsx | 2 +- src/util/condition.ts | 8 +-- src/util/interface.ts | 17 ++--- src/util/param.ts | 8 ++- src/util/statement.ts | 6 +- src/util/value.ts | 71 ++++++++++++++----- 16 files changed, 189 insertions(+), 154 deletions(-) diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index 195a09c..acd4553 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -96,8 +96,8 @@ export interface FieldProps { onValueListSort: (path: string, index: number, sortType: 'up' | 'down', validation: true | FieldError[]) => Promise baseRoute: string, path: string, // 组件所在路径以字段拼接展示 - dependentFields: string[] // condition依赖字段存放数组 - onReportFields?:(fields: string[]) => Promise //向上层上报依赖字段 + dependentFields: string[] // param依赖字段存放数组 + onReportFields?:(field: string) => Promise //向父组件上报依赖字段 step: { [field: string]: any } // 传递formValue loadDomain: (domain: string) => Promise } @@ -144,7 +144,7 @@ export class Field extends React.Component< config } = this.props if (config.defaultValue !== undefined) { - return ParamHelper(config.defaultValue, { record: this.props.record, data: this.props.data, step: this.props.step }) + return ParamHelper(config.defaultValue, { record: this.props.record, data: this.props.data, step: this.props.step }, this) } return undefined @@ -179,22 +179,20 @@ export class Field extends React.Component< } shouldComponentUpdate(nextProps:FieldProps, nextState: S) { console.log('nextProps', nextProps, this.props, nextProps.value == this.props.value); + const dependentFieldsArr = nextProps.dependentFields // console.log('dependentFieldsArr',dependentFieldsArr); let dependentIsChange = false if (dependentFieldsArr && dependentFieldsArr.length) { - for (let i=0;i< dependentFieldsArr.length;i++) { + for (let i=dependentFieldsArr.length;i>=0;i--) { const nextDependentField = get(nextProps.step, dependentFieldsArr[i]) const currentDependentField = get(this.props.step, dependentFieldsArr[i]) - if (dependentFieldsArr[i] === nextProps.path) { // 处于最后一层依赖字段 - if ((nextDependentField || currentDependentField) && (nextDependentField !== currentDependentField)) { - dependentIsChange = true - break - } - } else if (dependentFieldsArr[i].includes(nextProps.path)){ + + if ((nextDependentField || currentDependentField) && nextDependentField !== currentDependentField) { dependentIsChange = true break } + } } @@ -241,7 +239,7 @@ export class Display extends React.Componen config } = this.props if (config.defaultValue !== undefined) { - return ParamHelper(config.defaultValue, { record: this.props.record, data: this.props.data, step: this.props.step }) + return ParamHelper(config.defaultValue, { record: this.props.record, data: this.props.data, step: this.props.step }, this) } return undefined @@ -280,3 +278,4 @@ export class FieldError { this.message = message } } + diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index 9bab838..a6ef1a6 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -3,7 +3,7 @@ import { Field, FieldConfig, FieldConfigs, FieldError, FieldProps, IField } from import getALLComponents from '../' // import { getValue, listItemMove, setValue, getBoolean, getChainPath } from '../../../util/value' // import { cloneDeep } from 'lodash' -import { getValue, getBoolean, getChainPath, getDependentFieldsArr } from '../../../util/value' +import { getValue, getBoolean, getChainPath, updateCommonPrefixItem } from '../../../util/value' import { set, setValue , sort, splice, push } from '../../../util/produce' import ConditionHelper from '../../../util/condition' import StatementHelper from '../../../util/statement' @@ -189,7 +189,7 @@ export default class FormField extends Field { - const dependentFields_ = this.dependentFields_.concat(fields) - this.props.onReportFields && await this.props.onReportFields(dependentFields_) + handleReportFields = async (field: string) => { + // if (this.dependentFields_.includes(field)) return + let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) + if (typeof update === 'boolean') return + this.dependentFields_ = update + this.props.onReportFields && await this.props.onReportFields(field) } + /** * 用于展示子表单组件中的每一子项中的每一个子表单项组件 * @param props @@ -466,6 +466,7 @@ export default class FormField extends Field { + console.log('render--formList'); const { value = [], formLayout, @@ -506,7 +507,7 @@ export default class FormField extends Field 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 })) { + if (!ConditionHelper(formFieldConfig.condition, { record: itemValue, data: this.props.data, step: this.props.step }, this)) { if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `${index}`, [] ) // this.formFieldsMountedList[index][fieldIndex] = false this.formFieldsMountedList = set(this.formFieldsMountedList, `${[index]}.${fieldIndex}`, false) @@ -528,7 +529,7 @@ export default class FormField extends Field await this.handleValueListSort(index, fieldIndex, path, _index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} - path={getChainPath(`${fieldIndex}.${formFieldConfig.field}`, this.props.path)} - dependentFields={getDependentFieldsArr(formFieldConfig, this.props)} - onReportFields={async (fields: string[]) => await this.handleReportFields(fields)} + path={getChainPath(`${index}.${formFieldConfig.field}`, this.props.path)} + dependentFields={this.dependentFields_} + onReportFields={async (field: string) => await this.handleReportFields(field)} /> ) }) diff --git a/src/components/formFields/group/index.tsx b/src/components/formFields/group/index.tsx index 40e3bdd..388f04a 100644 --- a/src/components/formFields/group/index.tsx +++ b/src/components/formFields/group/index.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { getValue, getBoolean, getChainPath, getDependentFieldsArr } from '../../../util/value' +import { getValue, getBoolean, getChainPath, updateCommonPrefixItem } from '../../../util/value' import { Field, FieldConfig, FieldError, FieldProps, IField } from '../common' import getALLComponents, { FieldConfigs } from '../' import { IFormItem } from '../../../steps/form' @@ -48,7 +48,8 @@ export default class GroupField extends Field | null> = [] formFieldsMounted: Array = [] dependentFields_: string[] = [] - + _path: string = '' // 自身字段所在路径 + constructor (props: FieldProps) { super(props) @@ -102,7 +103,7 @@ export default class GroupField extends Field { - const dependentFields_ = this.dependentFields_.concat(fields) - this.props.onReportFields && await this.props.onReportFields(dependentFields_) + handleReportFields = async (field: string) => { + let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) + if (typeof update === 'boolean') return + this.dependentFields_ = update + this.props.onReportFields && await this.props.onReportFields(field) } renderComponent = (props: IGroupField) => { @@ -320,7 +319,7 @@ export default class GroupField extends Field { - if (!ConditionHelper(formFieldConfig.condition, { record: value, data: this.props.data, step: this.props.step })) { + if (!ConditionHelper(formFieldConfig.condition, { record: value, data: this.props.data, step: this.props.step }, this)) { this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, false) return null } @@ -360,7 +359,7 @@ export default class GroupField extends Field await this.props.loadDomain(domain)} path={getChainPath(formFieldConfig.field, this.props.path)} - dependentFields={getDependentFieldsArr(formFieldConfig, this.props)} - onReportFields={async(fields: string[]) => await this.handleReportFields(fields)} + dependentFields={this.dependentFields_} + onReportFields={async(field: string) => await this.handleReportFields(field)} /> ) } diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx index 51f7c1e..b319daf 100644 --- a/src/components/formFields/importSubform/index.tsx +++ b/src/components/formFields/importSubform/index.tsx @@ -1,6 +1,6 @@ import React from 'react' // import { setValue, getValue, getBoolean, getChainPath } from '../../../util/value' -import { getValue, getBoolean, getChainPath, getDependentFieldsArr } from '../../../util/value' +import { getValue, getBoolean, getChainPath, updateCommonPrefixItem } from '../../../util/value' import { Field, FieldConfig, FieldError, FieldProps, IField } from '../common' import getALLComponents, { FieldConfigs } from '../' @@ -38,7 +38,7 @@ export interface IImportSubformField { interface IImportSubformFieldState { didMount: boolean fields: FieldConfigs[] - formData: { status: 'normal' | 'error' | 'loading', message?: string }[] | any + formData: { status: 'normal' | 'error' | 'loading', message?: string }[] } export default class ImportSubformField extends Field implements IField { @@ -84,7 +84,7 @@ export default class ImportSubformField extends Field { - const dependentFields_ = this.dependentFields_.concat(fields) - this.props.onReportFields && await this.props.onReportFields(dependentFields_) + handleReportFields = async (field: string) => { + // if (this.dependentFields_.includes(field)) return + let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) + if (typeof update === 'boolean') return + this.dependentFields_ = update + // this.dependentFields_.push(field) + this.props.onReportFields && await this.props.onReportFields(field) } renderComponent = (props: IImportSubformField) => { @@ -357,7 +357,8 @@ export default class ImportSubformField extends Field { let dataToUnstringfy = data let dataToStringfy = JSON.stringify(data) @@ -389,7 +390,7 @@ export default class ImportSubformField extends Field { - if (!ConditionHelper(formFieldConfig.condition, { record: value, data, step })) { + if (!ConditionHelper(formFieldConfig.condition, { record: value, data, step }, this)) { this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, false) return null } @@ -428,7 +429,7 @@ export default class ImportSubformField extends Field await this.props.loadDomain(domain)} path={getChainPath(formFieldConfig.field, this.props.path)} - dependentFields={getDependentFieldsArr(formFieldConfig, this.props)} - onReportFields={async(fields: string[]) => await this.handleReportFields(fields)} + dependentFields={this.dependentFields_} + onReportFields={async(field: string) => await this.handleReportFields(field)} /> ) } diff --git a/src/components/formFields/object/index.tsx b/src/components/formFields/object/index.tsx index cd88f6c..35ed558 100644 --- a/src/components/formFields/object/index.tsx +++ b/src/components/formFields/object/index.tsx @@ -4,7 +4,7 @@ import React from 'react' import ConditionHelper from '../../../util/condition' // import { cloneDeep } from 'lodash' import { set, setValue } from '../../../util/produce' -import { getValue, getBoolean, getChainPath, getDependentFieldsArr } from '../../../util/value' +import { getValue, getBoolean, getChainPath, updateCommonPrefixItem } from '../../../util/value' import StatementHelper from '../../../util/statement' export interface ObjectFieldConfig extends FieldConfig { @@ -152,10 +152,6 @@ export default class ObjectField extends Field extends Field { - const dependentFields_ = this.dependentFields_.concat(fields) - this.props.onReportFields && await this.props.onReportFields(dependentFields_) + handleReportFields = async (field: string) => { + let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) + if (typeof update === 'boolean') return + this.dependentFields_ = update + this.props.onReportFields && await this.props.onReportFields(field) } + /** * 用于展示子表单组件 * @param _props @@ -494,9 +493,9 @@ export default class ObjectField extends Field this.handleValueListSort(key, formFieldIndex, path, _index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => this.props.loadDomain(domain)} - path={getChainPath(formFieldConfig.field, this.props.path)} - dependentFields={getDependentFieldsArr(formFieldConfig, this.props)} - onReportFields={async(fields: string[]) => await this.handleReportFields(fields)} + path={getChainPath(`${key}${formFieldConfig.field}`, this.props.path)} + dependentFields={this.dependentFields_} + onReportFields={async(field: string) => await this.handleReportFields(field)} /> ) }) diff --git a/src/components/formFields/select/common.tsx b/src/components/formFields/select/common.tsx index 528b21d..2b8cf78 100644 --- a/src/components/formFields/select/common.tsx +++ b/src/components/formFields/select/common.tsx @@ -37,7 +37,7 @@ export default class SelectField extends Fiel config: EnumerationOptionsConfig | undefined ) => { if (config) { - EnumerationHelper.options(config, (config, source) => this.interfaceHelper.request(config, source, { record: this.props.record, data: this.props.data, step: this.props.step }, { loadDomain: this.props.loadDomain })).then((options) => { + EnumerationHelper.options(config, (config, source) => this.interfaceHelper.request(config, source, { record: this.props.record, data: this.props.data, step: this.props.step }, { loadDomain: this.props.loadDomain }, this)).then((options) => { if (JSON.stringify(this.state.options) !== JSON.stringify(options)) { this.setState({ options @@ -66,7 +66,7 @@ export class SelectDisplay extends Display { if (config) { - EnumerationHelper.options(config, (config, source) => this.interfaceHelper.request(config, source, { record: this.props.record, data: this.props.data, step: this.props.step }, { loadDomain: this.props.loadDomain })).then((options) => { + EnumerationHelper.options(config, (config, source) => this.interfaceHelper.request(config, source, { record: this.props.record, data: this.props.data, step: this.props.step }, { loadDomain: this.props.loadDomain }, this)).then((options) => { if (JSON.stringify(this.state.options) !== JSON.stringify(options)) { this.setState({ options diff --git a/src/components/formFields/tabs/index.tsx b/src/components/formFields/tabs/index.tsx index fa16644..2498340 100644 --- a/src/components/formFields/tabs/index.tsx +++ b/src/components/formFields/tabs/index.tsx @@ -4,7 +4,7 @@ import React from 'react' import ConditionHelper from '../../../util/condition' // import { cloneDeep } from 'lodash' import { set, setValue } from '../../../util/produce' -import { getValue, getBoolean, getChainPath, getDependentFieldsArr } from '../../../util/value' +import { getValue, getBoolean, getChainPath, updateCommonPrefixItem } from '../../../util/value' import StatementHelper from '../../../util/statement' export type TabsFieldConfig = TabsFieldConfig_Same | TabsFieldConfig_Diff @@ -67,7 +67,7 @@ export default class TabsField extends Field | null>> = [] formFieldsMountedList: Array> = [] dependentFields_: string[] = [] - + constructor (props: FieldProps) { super(props) @@ -168,10 +168,6 @@ export default class TabsField extends Field extends Field { - const dependentFields_ = this.dependentFields_.concat(fields) - this.props.onReportFields && await this.props.onReportFields(dependentFields_) + handleReportFields = async (field: string) => { + let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) + if (typeof update === 'boolean') return + this.dependentFields_ = update + this.props.onReportFields && await this.props.onReportFields(field) } + /** * 用于展示子表单组件 * @param _props @@ -454,9 +453,9 @@ export default class TabsField extends Field this.handleValueListSort(index, formFieldIndex, path, _index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} - path={getChainPath(formFieldConfig.field, this.props.path)} - dependentFields={getDependentFieldsArr(formFieldConfig, this.props)} - onReportFields={async(fields: string[]) => await this.handleReportFields(fields)} + path={getChainPath(`${index}.${formFieldConfig.field}`, this.props.path)} + dependentFields={this.dependentFields_} + onReportFields={async(field: string) => await this.handleReportFields(field)} /> ) })} diff --git a/src/steps/detail/index.tsx b/src/steps/detail/index.tsx index dcac904..c566bb3 100644 --- a/src/steps/detail/index.tsx +++ b/src/steps/detail/index.tsx @@ -145,7 +145,7 @@ export default class DetailStep extends Step { const detailData = cloneDeep(this.state.detailData) if (this.props.config.defaultValue) { - let detailDefault = ParamHelper(this.props.config.defaultValue, { data, step }) + let detailDefault = ParamHelper(this.props.config.defaultValue, { data, step }, this) if (this.props.config.unstringify) { for (const field of this.props.config.unstringify) { const info = getValue(detailDefault, field) diff --git a/src/steps/filter/index.tsx b/src/steps/filter/index.tsx index 0998c97..7085808 100644 --- a/src/steps/filter/index.tsx +++ b/src/steps/filter/index.tsx @@ -7,7 +7,7 @@ import ParamHelper from '../../util/param' import { get } from 'lodash' import { push, splice, sort, set, setValue } from '../../util/produce' import ConditionHelper from '../../util/condition' -import { getValue, getChainPath, getDependentFieldsArr } from '../../util/value' +import { getValue, getChainPath, updateCommonPrefixItem } from '../../util/value' /** * 表单步骤配置文件格式定义 @@ -115,7 +115,7 @@ export default class FilterStep extends Step { this.formData = [] if (this.props.config.defaultValue) { - const formDefault = ParamHelper(this.props.config.defaultValue, { data: this.props.data, step: this.props.step }) + const formDefault = ParamHelper(this.props.config.defaultValue, { data: this.props.data, step: this.props.step }, this) for (const formFieldIndex in (this.props.config.fields || [])) { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] const value = (formFieldConfig.field === undefined || formFieldConfig.field === '') ? formDefault : get(formDefault, formFieldConfig.field) @@ -216,7 +216,7 @@ export default class FilterStep extends Step { this.formData = [] if (this.props.config.defaultValue) { - const formDefault = ParamHelper(this.props.config.defaultValue, { data: this.props.data, step: this.props.step }) + const formDefault = ParamHelper(this.props.config.defaultValue, { data: this.props.data, step: this.props.step }, this) for (const formFieldIndex in (this.props.config.fields || [])) { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] const value = (formFieldConfig.field === undefined || formFieldConfig.field === '') ? formDefault : get(formDefault, formFieldConfig.field) @@ -406,18 +406,13 @@ export default class FilterStep extends Step { } /** - * 上报condition依赖字段名称 + * 上报param依赖字段名称 * @param fields */ - handleReportFields = async (fields: string[]) => { - const dependentFields_ = this.dependentFields_ - for(let i=0;i { + let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) + if (typeof update === 'boolean') return + this.dependentFields_ = update } /** @@ -465,7 +460,7 @@ export default class FilterStep extends Step { submitText: this.props.config?.submitText?.replace(/(^\s*)|(\s*$)/g, ""), resetText: this.props.config?.resetText?.replace(/(^\s*)|(\s*$)/g, ""), children: fields.map((formFieldConfig, formFieldIndex) => { - if (!ConditionHelper(formFieldConfig.condition, { record: formValue, data, step })) { + if (!ConditionHelper(formFieldConfig.condition, { record: formValue, data, step }, this)) { this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, false) return null } @@ -521,9 +516,9 @@ export default class FilterStep extends Step { 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)} - path={getChainPath(formFieldIndex, formFieldConfig.field)} + path={getChainPath(formFieldConfig.field)} dependentFields={this.dependentFields_} - onReportFields={async (fields: string[]) => await this.handleReportFields(fields)} + onReportFields={async (field: string) => await this.handleReportFields(field)} /> ) } diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index 2296e08..aaaaeb3 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -4,14 +4,13 @@ import Step, { StepConfig, StepProps } from '../common' import getALLComponents from '../../components/formFields' import { ColumnsConfig, ParamConfig } from '../../interface' // import { getValue, setValue, listItemMove, getBoolean, getChainPath } from '../../util/value' -import { getValue, getBoolean, getChainPath, getDependentFieldsArr } from '../../util/value' +import { getValue, getBoolean, getChainPath, updateCommonPrefixItem } from '../../util/value' import ParamHelper from '../../util/param' import { get, unset } from 'lodash' import { push, splice, sort, set, setValue } from '../../util/produce' import ConditionHelper, { ConditionConfig } from '../../util/condition' import StatementHelper, { StatementConfig } from '../../util/statement' import OperationHelper, { OperationConfig } from '../../util/operation' -import { timingSafeEqual } from 'crypto' /** * 表单步骤配置文件格式定义 @@ -228,7 +227,7 @@ export default class FormStep extends Step { // ts对clas this.formData = [] if (this.props.config.defaultValue) { - let formDefault = ParamHelper(this.props.config.defaultValue, { data, step }) + let formDefault = ParamHelper(this.props.config.defaultValue, { data, step }, this) if (this.props.config.unstringify) { for (const field of this.props.config.unstringify) { @@ -303,9 +302,9 @@ export default class FormStep extends Step { // ts对clas this.submitData = {} if (this.props.config.validations) { for (const validation of this.props.config.validations) { - if (!ConditionHelper(validation.condition, { record: this.state.formValue, data: this.props.data, step: this.formValue })) { + if (!ConditionHelper(validation.condition, { record: this.state.formValue, data: this.props.data, step: this.formValue }, this)) { this.canSubmit = false - const message = StatementHelper(validation.message, { record: this.state.formValue, data: this.props.data, step: this.formValue }) || '未填写失败文案或失败文案配置异常' + const message = StatementHelper(validation.message, { record: this.state.formValue, data: this.props.data, step: this.formValue }, this) || '未填写失败文案或失败文案配置异常' this.renderModalComponent({ message }) return } @@ -544,19 +543,14 @@ console.log('step handleValueListAppend', fullPath, value); } } /** - * 上报condition依赖字段名称 + * 上报param依赖字段名称 * @param fields */ - handleReportFields = async (fields: string[]) => { - const dependentFields_ = this.dependentFields_ - for(let i=0;i { + let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) + if (typeof update === 'boolean') return + this.dependentFields_ = update + console.log('step依赖', this.dependentFields_); } /** @@ -603,6 +597,8 @@ console.log('step handleValueListAppend', fullPath, value); } render () { + console.log('render--formStep'); + const { data, step, @@ -627,7 +623,7 @@ console.log('step handleValueListAppend', fullPath, value); if (Object.prototype.toString.call(actions) === '[object Array]') { actions_ = [] for (let index = 0, len = actions.length; index < len; index++) { - if (!ConditionHelper(actions[index].condition, { record: formValue, data, step: formValue })) { + if (!ConditionHelper(actions[index].condition, { record: formValue, data, step: formValue }, this)) { continue } if (actions[index].type === 'submit') { @@ -682,7 +678,7 @@ console.log('step handleValueListAppend', fullPath, value); submitText: this.props.config?.submitText?.replace(/(^\s*)|(\s*$)/g, ''), // TODO 待删除 cancelText: this.props.config?.cancelText?.replace(/(^\s*)|(\s*$)/g, ''), // TODO 待删除 children: fields.map((formFieldConfig, formFieldIndex) => { - if (!ConditionHelper(formFieldConfig.condition, { record: formValue, data, step: formValue })) { + if (!ConditionHelper(formFieldConfig.condition, { record: formValue, data, step: formValue }, this)) { this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, false) return null } @@ -726,7 +722,7 @@ console.log('step handleValueListAppend', fullPath, value); : undefined, status, message: formData[formFieldIndex]?.message || '', - extra: StatementHelper(formFieldConfig.extra, { data: this.props.data, step: formValue }), + extra: StatementHelper(formFieldConfig.extra, { data: this.props.data, step: formValue }, this), required: getBoolean(formFieldConfig.required), layout, visitable: display, @@ -758,7 +754,7 @@ console.log('step handleValueListAppend', fullPath, value); loadDomain={async (domain: string) => await this.props.loadDomain(domain)} path={formFieldConfig.field} dependentFields={this.dependentFields_} - onReportFields={async (fields: string[]) => await this.handleReportFields(fields)} + onReportFields={async (field: string) => await this.handleReportFields(field)} /> ) } diff --git a/src/steps/header/index.tsx b/src/steps/header/index.tsx index a7ec2d7..671db3d 100644 --- a/src/steps/header/index.tsx +++ b/src/steps/header/index.tsx @@ -243,7 +243,7 @@ export default class HeaderStep extends Step { handleStatisticContent = (config: statisticContentConfig, _position: string) => { return (config.statistics || []).map((statistic, index) => { - const value = statistic.value ? ParamHelper(statistic.value, { data: this.props.data, step: this.props.step }) : undefined + const value = statistic.value ? ParamHelper(statistic.value, { data: this.props.data, step: this.props.step }, this) : undefined switch (statistic.type) { case 'value': return this.renderStatisticComponent({ diff --git a/src/util/condition.ts b/src/util/condition.ts index 633e565..989eec9 100644 --- a/src/util/condition.ts +++ b/src/util/condition.ts @@ -24,7 +24,7 @@ export interface ConditionConfig { debug?: boolean } -export default function ConditionHelper(condition: ConditionConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; } }): boolean { +export default function ConditionHelper(condition: ConditionConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; } }, _this?: any): boolean { if (condition === undefined || ((condition.statement === undefined || condition.statement === '') && (condition.template === undefined || condition.template === ''))) { return true } else { @@ -34,7 +34,7 @@ export default function ConditionHelper(condition: ConditionConfig | undefined, if (condition.params) { condition.params.forEach((param) => { if (param.field !== undefined && param.data !== undefined) { - const value = ParamHelper(param.data, datas) + const value = ParamHelper(param.data, datas, _this) if (param.field === '') { statementParams = value === undefined ? 'undefined' : JSON.stringify(value) } else { @@ -87,9 +87,9 @@ export default function ConditionHelper(condition: ConditionConfig | undefined, condition.params.forEach((param) => { if (param.field !== undefined && param.data !== undefined) { if (param.field === '') { - statementParams = ParamHelper(param.data,datas) + statementParams = ParamHelper(param.data,datas, _this) } else { - statementParams = set(statementParams, param.field, ParamHelper(param.data, datas)) + statementParams = set(statementParams, param.field, ParamHelper(param.data, datas, _this)) } } }) diff --git a/src/util/interface.ts b/src/util/interface.ts index 8e1d80b..bdad0fc 100644 --- a/src/util/interface.ts +++ b/src/util/interface.ts @@ -102,7 +102,8 @@ export default class InterfaceHelper { option?: { loadDomain?: (domain: string) => Promise extra_data?: { params?: any, data?: any } - } + }, + _this?: any // 位置要调整 ): Promise { return new Promise(async (resolve, reject) => { // 处理URL @@ -112,9 +113,9 @@ export default class InterfaceHelper { config.urlParams.forEach((param) => { if (param.field !== undefined && param.data !== undefined) { if (param.field === '') { - urlParams = ParamHelper(param.data, datas) + urlParams = ParamHelper(param.data, datas, _this) } else { - urlParams = set(urlParams, param.field, ParamHelper(param.data, datas)) + urlParams = set(urlParams, param.field, ParamHelper(param.data, datas, _this)) } } }) @@ -145,9 +146,9 @@ export default class InterfaceHelper { config.params.forEach((param) => { if (param.field !== undefined && param.data !== undefined) { if (param.field === '') { - params = ParamHelper(param.data, datas) + params = ParamHelper(param.data, datas, _this) } else { - params = set(params, param.field, ParamHelper(param.data, datas)) + params = set(params, param.field, ParamHelper(param.data, datas, _this)) } } }) @@ -159,7 +160,7 @@ export default class InterfaceHelper { if (config.data) { config.data.forEach((param) => { if (param.field !== undefined && param.data !== undefined) { - (data as FormData).append(param.field, ParamHelper(param.data, datas)) + (data as FormData).append(param.field, ParamHelper(param.data, datas, _this)) } }) } @@ -173,9 +174,9 @@ export default class InterfaceHelper { config.data.forEach((param) => { if (param.field !== undefined && param.data !== undefined) { if (param.field === '') { - data = ParamHelper(param.data, datas) + data = ParamHelper(param.data, datas, _this) } else { - data = set(data, param.field, ParamHelper(param.data, datas)) + data = set(data, param.field, ParamHelper(param.data, datas, _this)) } } }) diff --git a/src/util/param.ts b/src/util/param.ts index 867187b..9f43e02 100644 --- a/src/util/param.ts +++ b/src/util/param.ts @@ -1,11 +1,13 @@ import { get } from "lodash" import qs from "query-string" import { ParamConfig } from "../interface"; +import { getChainPath } from '../util/value' -export default function ParamHelper ( config: ParamConfig, datas: { record?: object, data: object[], step: { [field: string]: any } }) { // step--> stepValue +export default function ParamHelper ( config: ParamConfig, datas: { record?: object, data: object[], step: { [field: string]: any } }, _this: any) { // step--> stepValue switch (config.source) { case 'record': if (datas.record) { + _this && _this.props.onReportFields && _this.props.onReportFields(getChainPath(config.field, _this._path)) if (config.field === '') { return datas.record } else { @@ -15,6 +17,7 @@ export default function ParamHelper ( config: ParamConfig, datas: { record?: obj break case 'data': if (datas.step) { + _this && _this.props.onReportFields && _this.props.onReportFields(`${config.field}`) if (config.field === '') { return datas.step } else { @@ -33,6 +36,7 @@ export default function ParamHelper ( config: ParamConfig, datas: { record?: obj break case 'step': if (datas.data[config.step]) { + _this && _this.props.onReportFields && _this.props.onReportFields(`${config.field}`) if (config.field === '') { return datas.data[config.step] } else { @@ -46,8 +50,10 @@ export default function ParamHelper ( config: ParamConfig, datas: { record?: obj } else { return get(qs.parse(window.location.search, { arrayFormat: 'bracket' }), config.field) } + break case 'static': return config.value + break } return undefined } \ No newline at end of file diff --git a/src/util/statement.ts b/src/util/statement.ts index 73e59c5..4cbcf42 100644 --- a/src/util/statement.ts +++ b/src/util/statement.ts @@ -9,7 +9,7 @@ export interface StatementConfig { params: { field: string, data: ParamConfig }[] } -export default function StatementHelper(config: StatementConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; }}): string { +export default function StatementHelper(config: StatementConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; }}, _this?: any): string { if (config === undefined || config.statement === undefined || config.statement === '') { return '' } else { @@ -19,9 +19,9 @@ export default function StatementHelper(config: StatementConfig | undefined, dat config.params.forEach((param) => { if (param.field !== undefined && param.data !== undefined) { if (param.field === '') { - statementParams = ParamHelper(param.data, datas) + statementParams = ParamHelper(param.data, datas, _this) } else { - statementParams = set(statementParams, param.field, ParamHelper(param.data, datas)) + statementParams = set(statementParams, param.field, ParamHelper(param.data, datas, _this)) } } }) diff --git a/src/util/value.ts b/src/util/value.ts index 766dc5f..5680a83 100644 --- a/src/util/value.ts +++ b/src/util/value.ts @@ -136,23 +136,62 @@ export const getChainPath = (currentPath: string | number = '', sourcePath: stri return finalPath } -/** - * 获取condition依赖字段存放数组 - * @param formFieldConfig - * @returns - */ - export const getDependentFieldsArr = (formFieldConfig: FieldConfig, props: any) => { - const conditionParams = formFieldConfig.condition?.params - if (conditionParams && Array.isArray(conditionParams) && conditionParams.length) { - return conditionParams.map(ite => { - if (ite.data?.source === 'record') { - return ite?.data?.field && `${props.path}.${ite.data.field}` - } else if (ite.data?.source === 'data' || ite.data?.source === 'step') { - return ite?.data?.field && `${ite.data.field}` +// /** 废弃 +// * 获取param依赖字段存放数组 +// * @param formFieldConfig +// * @returns +// */ +// export const getDependentFieldsArr = (formFieldConfig: FieldConfig, props: any) => { +// const conditionParams = formFieldConfig.condition?.params +// if (conditionParams && Array.isArray(conditionParams) && conditionParams.length) { +// return conditionParams.map(ite => { +// if (ite.data?.source === 'record') { +// return ite?.data?.field && `${props.path}.${ite.data.field}` +// } else if (ite.data?.source === 'data' || ite.data?.source === 'step') { +// return ite?.data?.field && `${ite.data.field}` +// } +// return '' +// }).filter(ite=>ite) +// } +// return [] +// } + + +export const getLongestCommonPrefix = (arr: string[]) => { + if (arr.length===0 ||arr[0].length===0){return "";} + for (let i=0,len1=arr[0].length;iite) } - return [] + return arr[0]; } +/** + * + * @param arr 目标数组 + * @param sourceField 来源字段 + * @returns 与来源字段比较共同前缀后更新的数组 | 是否更新并上报 + */ +export const updateCommonPrefixItem = (arr: string[], sourceField: string):string[] | boolean => { + const reg = /[^\.]+(?=\.?)/ + const sourceFieldPrefix = sourceField.match(reg)?.[0] + const commonPrefixItemS = [sourceField] + for(let i=arr.length - 1;i>=0;i--) { + const arrItem = arr[i] + if (sourceField.includes(arrItem)) { + return false + } + const arrItemPrefix = arrItem.match(reg)?.[0] + if (arrItemPrefix && arrItemPrefix === sourceFieldPrefix) { + arr.splice(i, 1) + commonPrefixItemS.push(arrItem) + } + + } + arr.push(getLongestCommonPrefix(commonPrefixItemS).replace(/\.$/, '')) + return arr +} -- Gitee From c5d9bc05b358b7438f9c463407195f8a18f7f7c3 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Mon, 24 Jan 2022 15:54:06 +0800 Subject: [PATCH 14/38] =?UTF-8?q?docs:=20=E4=BF=AE=E6=94=B9=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/common.tsx | 6 +++--- src/components/formFields/form/index.tsx | 2 +- src/components/formFields/group/index.tsx | 2 +- src/components/formFields/importSubform/index.tsx | 2 +- src/components/formFields/object/index.tsx | 2 +- src/components/formFields/tabs/index.tsx | 2 +- src/steps/filter/index.tsx | 2 +- src/steps/form/index.tsx | 5 +---- 8 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index acd4553..56f4020 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -95,9 +95,9 @@ export interface FieldProps { // 事件:修改值 - 列表 - 修改顺序 onValueListSort: (path: string, index: number, sortType: 'up' | 'down', validation: true | FieldError[]) => Promise baseRoute: string, - path: string, // 组件所在路径以字段拼接展示 - dependentFields: string[] // param依赖字段存放数组 - onReportFields?:(field: string) => Promise //向父组件上报依赖字段 + path: string, // 组件所在路径以字段拼接展示 1.3.0新增 + dependentFields: string[] // 子组件param依赖字段存放数组 1.3.0新增 + onReportFields?:(field: string) => Promise //向父组件上报依赖字段 1.3.0新增 step: { [field: string]: any } // 传递formValue loadDomain: (domain: string) => Promise } diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index a6ef1a6..4193456 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -422,7 +422,7 @@ export default class FormField extends Field { // if (this.dependentFields_.includes(field)) return diff --git a/src/components/formFields/group/index.tsx b/src/components/formFields/group/index.tsx index 388f04a..6de13ea 100644 --- a/src/components/formFields/group/index.tsx +++ b/src/components/formFields/group/index.tsx @@ -277,7 +277,7 @@ export default class GroupField extends Field { let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx index b319daf..31667cc 100644 --- a/src/components/formFields/importSubform/index.tsx +++ b/src/components/formFields/importSubform/index.tsx @@ -314,7 +314,7 @@ export default class ImportSubformField extends Field { // if (this.dependentFields_.includes(field)) return diff --git a/src/components/formFields/object/index.tsx b/src/components/formFields/object/index.tsx index 35ed558..6d081ec 100644 --- a/src/components/formFields/object/index.tsx +++ b/src/components/formFields/object/index.tsx @@ -358,7 +358,7 @@ export default class ObjectField extends Field { let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) diff --git a/src/components/formFields/tabs/index.tsx b/src/components/formFields/tabs/index.tsx index 2498340..89c1d00 100644 --- a/src/components/formFields/tabs/index.tsx +++ b/src/components/formFields/tabs/index.tsx @@ -326,7 +326,7 @@ export default class TabsField extends Field { let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) diff --git a/src/steps/filter/index.tsx b/src/steps/filter/index.tsx index 7085808..b7296bb 100644 --- a/src/steps/filter/index.tsx +++ b/src/steps/filter/index.tsx @@ -407,7 +407,7 @@ export default class FilterStep extends Step { /** * 上报param依赖字段名称 - * @param fields + * @param field */ handleReportFields = async (field: string) => { let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index aaaaeb3..74a3c15 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -458,7 +458,6 @@ export default class FormStep extends Step { // ts对clas const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] if (formFieldConfig) { const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` -console.log('step handleValueListAppend', fullPath, value); this.formValue = push(this.formValue, fullPath, value) //向this.formValue的fullPath下的值添加value this.setState({ @@ -544,7 +543,7 @@ console.log('step handleValueListAppend', fullPath, value); } /** * 上报param依赖字段名称 - * @param fields + * @param field */ handleReportFields = async (field: string) => { let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) @@ -597,8 +596,6 @@ console.log('step handleValueListAppend', fullPath, value); } render () { - console.log('render--formStep'); - const { data, step, -- Gitee From 8903021c24874f67e7b6ee2830f6b0dc56f3df52 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Wed, 26 Jan 2022 15:58:41 +0800 Subject: [PATCH 15/38] =?UTF-8?q?feat:=20=E4=B8=8D=E5=86=8D=E5=BC=95?= =?UTF-8?q?=E7=94=A8ObjectField?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/index.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/formFields/index.tsx b/src/components/formFields/index.tsx index e7735a6..4842a89 100644 --- a/src/components/formFields/index.tsx +++ b/src/components/formFields/index.tsx @@ -18,7 +18,7 @@ import ImportSubformField, { ImportSubformFieldConfig } from './importSubform' import GroupField, { GroupFieldConfig } from './group' import AnyField, { AnyFieldConfig } from './any' import SwitchField, { SwitchFieldConfig } from './switch' -import ObjectField, { ObjectFieldConfig } from './object' +// import ObjectField, { ObjectFieldConfig } from './object' import HiddenField from './hidden' import TabsField, { TabsFieldConfig } from './tabs' import MultipleTextField, { MultipleTextFieldConfig } from './multipleText' @@ -64,7 +64,7 @@ export type FieldConfigs = ImportSubformFieldConfig | GroupFieldConfig | AnyFieldConfig | - ObjectFieldConfig | + // ObjectFieldConfig | TabsFieldConfig | MultipleTextFieldConfig | CustomFieldConfig @@ -90,7 +90,7 @@ export type componentType = 'group' | 'any' | 'switch' | - 'object' | + // 'object' | 'tabs' | 'multiple_text'| 'custom' @@ -114,7 +114,7 @@ export default { group: GroupField, any: AnyField, switch: SwitchField, - object: ObjectField, + // object: ObjectField, hidden: HiddenField, tabs: TabsField, multiple_text: MultipleTextField, -- Gitee From f4687894023cd7bb0add0996a69e715799a95de7 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Thu, 27 Jan 2022 18:45:31 +0800 Subject: [PATCH 16/38] =?UTF-8?q?feat:=20getfullpath=E6=94=B9=E4=B8=BAgetC?= =?UTF-8?q?hainPath?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/detail/importSubform/index.tsx | 17 ++++---- src/components/formFields/any/index.tsx | 6 +-- src/components/formFields/form/index.tsx | 3 +- src/components/formFields/group/index.tsx | 3 +- .../formFields/importSubform/index.tsx | 19 ++++----- src/components/formFields/object/index.tsx | 2 +- src/components/formFields/tabs/index.tsx | 2 +- src/steps/form/index.tsx | 3 +- src/util/param.ts | 2 +- src/util/value.ts | 40 ++++++++++++------- 10 files changed, 50 insertions(+), 47 deletions(-) diff --git a/src/components/detail/importSubform/index.tsx b/src/components/detail/importSubform/index.tsx index 9828bbc..e6d5509 100644 --- a/src/components/detail/importSubform/index.tsx +++ b/src/components/detail/importSubform/index.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { getValue } from '../../../util/value' +import { getValue , getChainPath} from '../../../util/value' import { DetailField, DetailFieldConfig, DetailFieldProps, IDetailField } from '../common' import { Display } from '../../formFields/common' @@ -67,12 +67,7 @@ export default class ImportSubformField extends DetailField { await this.setState({ @@ -89,15 +84,16 @@ export default class ImportSubformField extends DetailField } else { + const withConfigPath = this.props.config.configFrom?.type === 'data' && this.props.config.configFrom.dataField ? `${this.props.config.configFrom.dataField}` : '' return ( {this.renderComponent({ @@ -234,7 +231,7 @@ export default class ImportSubformField extends DetailField : ( type === 'number' ? : {}} @@ -137,7 +137,7 @@ export default class AnyField extends Field ) diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index 4193456..abbf399 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -1,7 +1,6 @@ import React from 'react' import { Field, FieldConfig, FieldConfigs, FieldError, FieldProps, IField } from '../common' import getALLComponents from '../' -// import { getValue, listItemMove, setValue, getBoolean, getChainPath } from '../../../util/value' // import { cloneDeep } from 'lodash' import { getValue, getBoolean, getChainPath, updateCommonPrefixItem } from '../../../util/value' import { set, setValue , sort, splice, push } from '../../../util/produce' @@ -559,7 +558,7 @@ export default class FormField extends Field await this.handleValueListSort(index, fieldIndex, path, _index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} - path={getChainPath(`${index}.${formFieldConfig.field}`, this.props.path)} + path={getChainPath(this.props.path, `${index}.${formFieldConfig.field}`)} dependentFields={this.dependentFields_} onReportFields={async (field: string) => await this.handleReportFields(field)} /> diff --git a/src/components/formFields/group/index.tsx b/src/components/formFields/group/index.tsx index 6de13ea..e3227fc 100644 --- a/src/components/formFields/group/index.tsx +++ b/src/components/formFields/group/index.tsx @@ -48,7 +48,6 @@ export default class GroupField extends Field | null> = [] formFieldsMounted: Array = [] dependentFields_: string[] = [] - _path: string = '' // 自身字段所在路径 constructor (props: FieldProps) { super(props) @@ -388,7 +387,7 @@ export default class GroupField extends Field this.handleValueListSort(formFieldIndex, path, index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} - path={getChainPath(formFieldConfig.field, this.props.path)} + path={getChainPath(this.props.path, formFieldConfig.field)} dependentFields={this.dependentFields_} onReportFields={async(field: string) => await this.handleReportFields(field)} /> diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx index 31667cc..0bafbaa 100644 --- a/src/components/formFields/importSubform/index.tsx +++ b/src/components/formFields/importSubform/index.tsx @@ -1,5 +1,4 @@ import React from 'react' -// import { setValue, getValue, getBoolean, getChainPath } from '../../../util/value' import { getValue, getBoolean, getChainPath, updateCommonPrefixItem } from '../../../util/value' import { Field, FieldConfig, FieldError, FieldProps, IField } from '../common' @@ -65,12 +64,7 @@ export default class ImportSubformField extends Field { await this.setState({ @@ -89,8 +83,9 @@ export default class ImportSubformField extends Field } else { + const withConfigPath = this.props.config.withConfig?.enable && this.props.config.withConfig?.dataField ? `${this.props.config.withConfig.dataField}` : '' return ( {this.renderComponent({ @@ -445,7 +442,7 @@ export default class ImportSubformField extends Field this.handleValueListSort(formFieldIndex, path, index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} - path={getChainPath(formFieldConfig.field, this.props.path)} + path={getChainPath(this.props.path, formFieldConfig.field)} dependentFields={this.dependentFields_} onReportFields={async(field: string) => await this.handleReportFields(field)} /> diff --git a/src/components/formFields/object/index.tsx b/src/components/formFields/object/index.tsx index 6d081ec..91520cb 100644 --- a/src/components/formFields/object/index.tsx +++ b/src/components/formFields/object/index.tsx @@ -493,7 +493,7 @@ export default class ObjectField extends Field this.handleValueListSort(key, formFieldIndex, path, _index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => this.props.loadDomain(domain)} - path={getChainPath(`${key}${formFieldConfig.field}`, this.props.path)} + path={getChainPath(this.props.path, `${key}${formFieldConfig.field}`)} dependentFields={this.dependentFields_} onReportFields={async(field: string) => await this.handleReportFields(field)} /> diff --git a/src/components/formFields/tabs/index.tsx b/src/components/formFields/tabs/index.tsx index 89c1d00..70fd6e7 100644 --- a/src/components/formFields/tabs/index.tsx +++ b/src/components/formFields/tabs/index.tsx @@ -453,7 +453,7 @@ export default class TabsField extends Field this.handleValueListSort(index, formFieldIndex, path, _index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} - path={getChainPath(`${index}.${formFieldConfig.field}`, this.props.path)} + path={getChainPath(this.props.path, `${index}.${formFieldConfig.field}`)} dependentFields={this.dependentFields_} onReportFields={async(field: string) => await this.handleReportFields(field)} /> diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index 74a3c15..ecae8cd 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -3,7 +3,6 @@ import { Field, FieldConfigs, FieldError } from '../../components/formFields/com import Step, { StepConfig, StepProps } from '../common' import getALLComponents from '../../components/formFields' import { ColumnsConfig, ParamConfig } from '../../interface' -// import { getValue, setValue, listItemMove, getBoolean, getChainPath } from '../../util/value' import { getValue, getBoolean, getChainPath, updateCommonPrefixItem } from '../../util/value' import ParamHelper from '../../util/param' import { get, unset } from 'lodash' @@ -749,7 +748,7 @@ export default class FormStep extends Step { // ts对clas 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)} - path={formFieldConfig.field} + path={getChainPath(formFieldConfig.field)} dependentFields={this.dependentFields_} onReportFields={async (field: string) => await this.handleReportFields(field)} /> diff --git a/src/util/param.ts b/src/util/param.ts index 9f43e02..209bee6 100644 --- a/src/util/param.ts +++ b/src/util/param.ts @@ -7,7 +7,7 @@ export default function ParamHelper ( config: ParamConfig, datas: { record?: obj switch (config.source) { case 'record': if (datas.record) { - _this && _this.props.onReportFields && _this.props.onReportFields(getChainPath(config.field, _this._path)) + _this && _this.props.onReportFields && _this.props.onReportFields(getChainPath(_this.props.path, config.field)) if (config.field === '') { return datas.record } else { diff --git a/src/util/value.ts b/src/util/value.ts index 5680a83..9ad8fd8 100644 --- a/src/util/value.ts +++ b/src/util/value.ts @@ -123,19 +123,28 @@ export const listItemMove = (list: any[], currentIndex: number, sortType: 'up' | return list } -/** - * 组件所在的字符串链式路径 - * @param currentPath - * @param sourcePath - * @returns - */ -export const getChainPath = (currentPath: string | number = '', sourcePath: string | number = '') => { - if (!currentPath && currentPath !== 0) {currentPath = ''} else {currentPath = currentPath.toString()} - if (!sourcePath && sourcePath !== 0) {sourcePath = ''} else {sourcePath = sourcePath.toString()} - const finalPath = (sourcePath +'.'+ currentPath).replace(/(^\.*)|(\.*$)|(\.){2,}/g, '$3') - return finalPath +// 参数转化为链式路径 +export const getChainPath = (...arg: any[]) => { + // const withConfigPath = this.props.config.withConfig?.enable && this.props.config.withConfig?.dataField ? `${this.props.config.withConfig.dataField}` : '' + // const _fullPath = `${withConfigPath}.${field}.${path}.` + const _fullPath = arg.join('.') + const fullPath = _fullPath.replace(/(^\.*)|(\.*$)|(\.){2,}/g, '$3') + return fullPath } +// /** 废弃 +// * 组件所在的字符串链式路径 +// * @param currentPath +// * @param sourcePath +// * @returns +// */ +// export const getChainPath = (currentPath: string | number = '', sourcePath: string | number = '') => { +// if (!currentPath && currentPath !== 0) {currentPath = ''} else {currentPath = currentPath.toString()} +// if (!sourcePath && sourcePath !== 0) {sourcePath = ''} else {sourcePath = sourcePath.toString()} +// const finalPath = (sourcePath +'.'+ currentPath).replace(/(^\.*)|(\.*$)|(\.){2,}/g, '$3') +// return finalPath +// } + // /** 废弃 // * 获取param依赖字段存放数组 // * @param formFieldConfig @@ -156,7 +165,9 @@ export const getChainPath = (currentPath: string | number = '', sourcePath: stri // return [] // } - +/** + * 获取一个数组中最长共同前缀 + */ export const getLongestCommonPrefix = (arr: string[]) => { if (arr.length===0 ||arr[0].length===0){return "";} for (let i=0,len1=arr[0].length;i Date: Thu, 27 Jan 2022 22:35:09 +0800 Subject: [PATCH 17/38] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9SCU?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/common.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index 56f4020..22c84c3 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -197,10 +197,10 @@ export class Field extends React.Component< } /** - * config受value影响变化 ,data提交前不变, 去掉这两项的比较 + * data提交前不变, 去掉这项的比较 * record也不比较,需要比较的话就在dependentFieldsArr取出record绝对路径 * */ - if (!dependentIsChange && isEqual(this.state, nextState) && nextProps.value === this.props.value) { + if (!dependentIsChange && isEqual(this.state, nextState) && nextProps.value === this.props.value && this.props.config === nextProps.config) { console.log('no update' ); return false; } -- Gitee From 0967226b27e0683e6e8d50f906e9dd83204a3ec8 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Fri, 28 Jan 2022 18:56:06 +0800 Subject: [PATCH 18/38] =?UTF-8?q?fix:=20tabs=E3=80=81form=E7=9A=84Helper?= =?UTF-8?q?=E4=B8=ADrecord=E8=B7=AF=E5=BE=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/common.tsx | 2 +- src/components/formFields/form/index.tsx | 6 +++++- src/components/formFields/tabs/index.tsx | 17 +++++++++++------ src/util/param.ts | 2 +- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index 22c84c3..19098f8 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -200,7 +200,7 @@ export class Field extends React.Component< * data提交前不变, 去掉这项的比较 * record也不比较,需要比较的话就在dependentFieldsArr取出record绝对路径 * */ - if (!dependentIsChange && isEqual(this.state, nextState) && nextProps.value === this.props.value && this.props.config === nextProps.config) { + if (!dependentIsChange && isEqual(this.state, nextState) && nextProps.value === this.props.value) { console.log('no update' ); return false; } diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index abbf399..636b683 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -68,6 +68,7 @@ export default class FormField extends Field | null>> = [] formFieldsMountedList: Array> = [] dependentFields_: string[] = [] + selfPath:string = '' // Tabs和formList需要保存自身路径传给子组件 constructor (props: FieldProps) { super(props) @@ -506,6 +507,9 @@ export default class FormField extends Field await this.handleSort(index, sortType) : undefined, canCollapse, children: (fields || []).map((formFieldConfig, fieldIndex) => { + if (!this.selfPath) { + this.selfPath = getChainPath(this.props.path, index) + } if (!ConditionHelper(formFieldConfig.condition, { record: itemValue, data: this.props.data, step: this.props.step }, this)) { if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `${index}`, [] ) // this.formFieldsMountedList[index][fieldIndex] = false @@ -528,7 +532,7 @@ export default class FormField extends Field extends Field | null>> = [] formFieldsMountedList: Array> = [] dependentFields_: string[] = [] + selfPath:string = '' // Tabs和formList需要保存自身路径传给子组件 constructor (props: FieldProps) { super(props) @@ -92,7 +93,7 @@ export default class TabsField extends Field extends Field { - if (!ConditionHelper(formFieldConfig.condition, { record: this.props.record, data: this.props.data, step: this.props.step })) { + if (!this.selfPath) { + this.selfPath = getChainPath(this.props.path, tab.field) + } + + if (!ConditionHelper(formFieldConfig.condition, { record: getValue(value, tab.field), data: this.props.data, step: this.props.step }, this)) { if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}]`, []) this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}][${formFieldIndex}]`, false) return null @@ -427,7 +432,7 @@ export default class TabsField extends Field extends Field extends Field this.handleValueListSort(index, formFieldIndex, path, _index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} - path={getChainPath(this.props.path, `${index}.${formFieldConfig.field}`)} + path={getChainPath(this.props.path, `${tab.field}.${formFieldConfig.field}`)} dependentFields={this.dependentFields_} onReportFields={async(field: string) => await this.handleReportFields(field)} /> diff --git a/src/util/param.ts b/src/util/param.ts index 209bee6..f10ea63 100644 --- a/src/util/param.ts +++ b/src/util/param.ts @@ -7,7 +7,7 @@ export default function ParamHelper ( config: ParamConfig, datas: { record?: obj switch (config.source) { case 'record': if (datas.record) { - _this && _this.props.onReportFields && _this.props.onReportFields(getChainPath(_this.props.path, config.field)) + _this && _this.props.onReportFields && _this.props.onReportFields(getChainPath(_this.selfPath || _this.props.path, config.field)) if (config.field === '') { return datas.record } else { -- Gitee From 457abe7ce9056deaf8398012aecc44be1e4a8114 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Fri, 28 Jan 2022 19:11:18 +0800 Subject: [PATCH 19/38] =?UTF-8?q?fix:=20=E8=A1=A5=E5=85=85helper=E5=8F=82?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/object/index.tsx | 4 ++-- src/components/formFields/treeSelect/index.tsx | 3 ++- src/components/formFields/upload/index.tsx | 3 ++- src/steps/form/index.tsx | 1 - 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/components/formFields/object/index.tsx b/src/components/formFields/object/index.tsx index 91520cb..cf28780 100644 --- a/src/components/formFields/object/index.tsx +++ b/src/components/formFields/object/index.tsx @@ -81,7 +81,7 @@ export default class ObjectField extends Field extends Field await this.handleChangeKey(key, value), onRemove: async () => await this.handleRemove(key), children: (Array.isArray(this.props.config.fields) ? this.props.config.fields : []).map((formFieldConfig, formFieldIndex) => { - if (!ConditionHelper(formFieldConfig.condition, { record: this.props.record, data: this.props.data, step: this.props.step })) { + if (!ConditionHelper(formFieldConfig.condition, { record: this.props.record, data: this.props.data, step: this.props.step }, this)) { if (!this.formFieldsMountedList[key]) this.formFieldsMountedList = set(this.formFieldsMountedList, `[${key}]`, []) this.formFieldsMountedList = set(this.formFieldsMountedList, `[${key}][${formFieldIndex}]`, false) return null diff --git a/src/components/formFields/treeSelect/index.tsx b/src/components/formFields/treeSelect/index.tsx index 9440c97..13d8211 100644 --- a/src/components/formFields/treeSelect/index.tsx +++ b/src/components/formFields/treeSelect/index.tsx @@ -113,7 +113,8 @@ export default class TreeSelectField extends Field { this.setState({ interfaceOptionsData: this.formatTree( diff --git a/src/components/formFields/upload/index.tsx b/src/components/formFields/upload/index.tsx index 5b8fc83..29f4372 100644 --- a/src/components/formFields/upload/index.tsx +++ b/src/components/formFields/upload/index.tsx @@ -161,7 +161,8 @@ export default class UploadField extends Field { // ts对clas this.formValue = set(this.formValue, fullPath, value) - console.log('test--->set--', this.formValue, fullPath, value); this.setState(({formValue})=>({ formValue: this.formValue })) -- Gitee From ec6c3a0d989e8fa67b83f80c45d78d5acf64419a Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Fri, 28 Jan 2022 22:08:26 +0800 Subject: [PATCH 20/38] =?UTF-8?q?fix:=20tabs=20value=E5=8F=96=E5=80=BC?= =?UTF-8?q?=E6=9C=AA=E9=87=87=E7=94=A8getChainPath=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E5=87=BA=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/tabs/index.tsx | 2 +- src/util/value.ts | 35 ------------------------ 2 files changed, 1 insertion(+), 36 deletions(-) diff --git a/src/components/formFields/tabs/index.tsx b/src/components/formFields/tabs/index.tsx index a40a559..e6375e0 100644 --- a/src/components/formFields/tabs/index.tsx +++ b/src/components/formFields/tabs/index.tsx @@ -445,7 +445,7 @@ export default class TabsField extends Field { - // const withConfigPath = this.props.config.withConfig?.enable && this.props.config.withConfig?.dataField ? `${this.props.config.withConfig.dataField}` : '' - // const _fullPath = `${withConfigPath}.${field}.${path}.` const _fullPath = arg.join('.') const fullPath = _fullPath.replace(/(^\.*)|(\.*$)|(\.){2,}/g, '$3') return fullPath } -// /** 废弃 -// * 组件所在的字符串链式路径 -// * @param currentPath -// * @param sourcePath -// * @returns -// */ -// export const getChainPath = (currentPath: string | number = '', sourcePath: string | number = '') => { -// if (!currentPath && currentPath !== 0) {currentPath = ''} else {currentPath = currentPath.toString()} -// if (!sourcePath && sourcePath !== 0) {sourcePath = ''} else {sourcePath = sourcePath.toString()} -// const finalPath = (sourcePath +'.'+ currentPath).replace(/(^\.*)|(\.*$)|(\.){2,}/g, '$3') -// return finalPath -// } - -// /** 废弃 -// * 获取param依赖字段存放数组 -// * @param formFieldConfig -// * @returns -// */ -// export const getDependentFieldsArr = (formFieldConfig: FieldConfig, props: any) => { -// const conditionParams = formFieldConfig.condition?.params -// if (conditionParams && Array.isArray(conditionParams) && conditionParams.length) { -// return conditionParams.map(ite => { -// if (ite.data?.source === 'record') { -// return ite?.data?.field && `${props.path}.${ite.data.field}` -// } else if (ite.data?.source === 'data' || ite.data?.source === 'step') { -// return ite?.data?.field && `${ite.data.field}` -// } -// return '' -// }).filter(ite=>ite) -// } -// return [] -// } - /** * 获取一个数组中最长共同前缀 */ -- Gitee From d075d31ab498f77943949a5330d908d76470206b Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Sat, 29 Jan 2022 09:05:25 +0800 Subject: [PATCH 21/38] =?UTF-8?q?fix:=20=E5=8E=86=E5=8F=B2=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E4=B8=ADstatementHelper=E4=B8=ADrecord=E5=8F=96?= =?UTF-8?q?=E5=80=BC=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/common.tsx | 2 +- src/components/formFields/group/index.tsx | 2 +- src/components/formFields/importSubform/index.tsx | 2 +- src/util/produce.tsx | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index 19098f8..22c84c3 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -200,7 +200,7 @@ export class Field extends React.Component< * data提交前不变, 去掉这项的比较 * record也不比较,需要比较的话就在dependentFieldsArr取出record绝对路径 * */ - if (!dependentIsChange && isEqual(this.state, nextState) && nextProps.value === this.props.value) { + if (!dependentIsChange && isEqual(this.state, nextState) && nextProps.value === this.props.value && this.props.config === nextProps.config) { console.log('no update' ); return false; } diff --git a/src/components/formFields/group/index.tsx b/src/components/formFields/group/index.tsx index e3227fc..97c5a08 100644 --- a/src/components/formFields/group/index.tsx +++ b/src/components/formFields/group/index.tsx @@ -358,7 +358,7 @@ export default class GroupField extends Field Date: Sat, 29 Jan 2022 09:10:14 +0800 Subject: [PATCH 22/38] =?UTF-8?q?docs:=20=20immer=E3=80=81=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E5=AD=97=E6=AE=B5=E4=B8=8A=E6=8A=A5=E8=AF=B4=E6=98=8E?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/readme.md | 67 +++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/components/formFields/readme.md b/src/components/formFields/readme.md index e69de29..565e722 100644 --- a/src/components/formFields/readme.md +++ b/src/components/formFields/readme.md @@ -0,0 +1,67 @@ +# immer + +Immer是一个简单易用、体量小巧、设计巧妙的immutable 库,以最小的成本实现了js的不可变数据结构。 + +Js的对象是引用类型的,在使用过程中常常会不经意的修改。为了解决这个问题,除了可以使用深度拷贝的方法(但成本高,影响性能),还可以使用一些不可变数据结构的库,Immer就是其中的佼佼者。 +immer基于copy-on-write机制——在当前的状态数据上复制出一份临时的草稿,然后对这份草稿修改,最后生成新的状态数据。借力于ES6的Proxy,跟响应式的自动跟踪是一样的。 +https://immerjs.github.io/immer/api + +# immer写法 + +```js +import produce from "immer" + +this.state = { + members: [{name: 'user', age: 18}] +} + +// 一般写法 +this.setState(state=>{ + return produce(state,draft=>{ + draft.members[0].age++; + }) +}) +// 高阶写法 +this.setState(state=>{ + return produce(draft=>{ + draft.members[0].age++; + })(state) +}) +// 简洁写法 +this.setState(produce(draft => { + draft.members[0].age++; +})) +``` +# immer拓展 +1. 返回值问题 +以高阶函数写法为例 +语法:produce(recipe: (draftState) => void | draftState, ?PatchListener)(currentState): nextState +recipe 是否有返回值,nextState 的生成过程是不同的: +- recipe 没有返回值时:nextState是根据recipe 函数内的 draftState生成的; +- recipe有返回值时:nextState是根据 recipe 函数的返回值生成的 + +了解了这些,方便在开发中更加灵活地运用immer +2. Auto freezing(自动冻结) +Immer 会自动冻结使用 produce 修改过的状态树,这样可以防止在变更函数外部修改状态树。这个特性会带来性能影响,所以需要在生产环境中关闭。可以使用 setAutoFreeze(true / false) 打开或者关闭。在开发环境中建议打开,可以避免不可预测的状态树更改 +https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze + +# immer结合shouldComponentUpdate做了哪些事? + SCU的对于引用类型对象的比较,如果通过比较它们的值往往很耗费性能,有了数据结构共享,我们可以通过比较复杂对象的每一个节点的指针指向是否相同,大大节省性能损耗 + +# 项目中数据依赖字段上报规则及注意record(当前记录)注意事项 +1. 每一个组件在handleMount以后知道它们的this.props.path和自身的field路径,以path字段向下传递给子组件,我们在paramHelper里面对应record里的依赖项的处理是,拿到父级的路径和record依赖的字段(举例为DepField),通过getChainPath(this.props.path, DepField)拿到完整的链式路径,onReportFields上报给父组件有哪些依赖项,参见下: + +path=this.props.path+field ----传递子组件---> path=this.props.path+field +父组件 <----onReportFields--- getChainPath(this.props.path, DepField) + +2. 正常来说,父组件的value就是子组件的record, 特殊的是tabs和form两个组件对应分别多了tab.field和index,这里通过Helper传递record时,取值分别对应下探到tab.field和index。 +示例: + +```js +// import_subform和group用法: +ConditionHelper(formFieldConfig.condition, { record: this.props.value,...}) +ConditionHelper(formFieldConfig.condition, { record: this.props.value,...}) +// tabs和form用法: +ConditionHelper(formFieldConfig.condition, { record: this.props.value[tab.field],...}) +ConditionHelper(formFieldConfig.condition, { record: this.props.value[index],...}) +``` \ No newline at end of file -- Gitee From e1a525d0257c6925dc874edd006fe0ff63a08123 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Sat, 29 Jan 2022 09:33:02 +0800 Subject: [PATCH 23/38] =?UTF-8?q?fix:=20=E5=8E=BB=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8console?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/common.tsx | 4 ++-- src/components/formFields/form/index.tsx | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index 22c84c3..ae766a2 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -178,7 +178,7 @@ export class Field extends React.Component< } shouldComponentUpdate(nextProps:FieldProps, nextState: S) { - console.log('nextProps', nextProps, this.props, nextProps.value == this.props.value); + // console.log('nextProps', nextProps, this.props, nextProps.value == this.props.value); const dependentFieldsArr = nextProps.dependentFields // console.log('dependentFieldsArr',dependentFieldsArr); @@ -201,7 +201,7 @@ export class Field extends React.Component< * record也不比较,需要比较的话就在dependentFieldsArr取出record绝对路径 * */ if (!dependentIsChange && isEqual(this.state, nextState) && nextProps.value === this.props.value && this.props.config === nextProps.config) { - console.log('no update' ); + // console.log('no update' ); return false; } return true; diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index 636b683..21e8bd2 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -466,7 +466,6 @@ export default class FormField extends Field { - console.log('render--formList'); const { value = [], formLayout, -- Gitee From 8fab4f8e8b5628db01c9fe5ea782d22e605f11f0 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Wed, 9 Feb 2022 15:34:40 +0800 Subject: [PATCH 24/38] =?UTF-8?q?fix:=20=E4=BB=A3=E7=A0=81cherry-pick?= =?UTF-8?q?=E5=90=8E=E4=BF=AE=E5=A4=8DwithConfigPath=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/detail/importSubform/index.tsx | 12 +++++++---- .../formFields/importSubform/index.tsx | 21 ++++++++++++------- src/steps/form/index.tsx | 5 ----- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/components/detail/importSubform/index.tsx b/src/components/detail/importSubform/index.tsx index e6d5509..a2e1574 100644 --- a/src/components/detail/importSubform/index.tsx +++ b/src/components/detail/importSubform/index.tsx @@ -101,33 +101,37 @@ export default class ImportSubformField extends DetailField { + const withConfigPath = this.props.config.configFrom?.type === 'data' && this.props.config.configFrom.dataField ? `${this.props.config.configFrom.dataField}` : '' const formFieldConfig = (this.state.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = this.getFullpath(formFieldConfig.field, path) + const fullPath = getChainPath(withConfigPath, formFieldConfig.field, path) await this.props.onValueSet(fullPath, value, true) } } handleValueUnset = async (formFieldIndex: number, path: string) => { + const withConfigPath = this.props.config.configFrom?.type === 'data' && this.props.config.configFrom.dataField ? `${this.props.config.configFrom.dataField}` : '' const formFieldConfig = (this.state.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = this.getFullpath(formFieldConfig.field, path) + const fullPath = getChainPath(withConfigPath, formFieldConfig.field, path) await this.props.onValueUnset(fullPath, true) } } handleValueListAppend = async (formFieldIndex: number, path: string, value: any) => { + const withConfigPath = this.props.config.configFrom?.type === 'data' && this.props.config.configFrom.dataField ? `${this.props.config.configFrom.dataField}` : '' const formFieldConfig = (this.state.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = this.getFullpath(formFieldConfig.field, path) + const fullPath = getChainPath(withConfigPath, formFieldConfig.field, path) await this.props.onValueListAppend(fullPath, value, true) } } handleValueListSplice = async (formFieldIndex: number, path: string, index: number, count: number) => { + const withConfigPath = this.props.config.configFrom?.type === 'data' && this.props.config.configFrom.dataField ? `${this.props.config.configFrom.dataField}` : '' const formFieldConfig = (this.state.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = this.getFullpath(formFieldConfig.field, path) + const fullPath = getChainPath(withConfigPath, formFieldConfig.field, path) await this.props.onValueListSplice(fullPath, index, count, true) } } diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx index 206ea4c..f1fbd81 100644 --- a/src/components/formFields/importSubform/index.tsx +++ b/src/components/formFields/importSubform/index.tsx @@ -153,16 +153,17 @@ export default class ImportSubformField extends Field { const formFieldConfig = (this.state.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = this.getFullpath(formFieldConfig.field, path) + const withConfigPath = this.props.config.withConfig?.enable && this.props.config.withConfig?.dataField ? `${this.props.config.withConfig.dataField}` : '' + const fullPath = getChainPath(withConfigPath, formFieldConfig.field, path) await this.props.onValueSet(fullPath, value, true) let formData = this.state.formData @@ -235,7 +237,8 @@ export default class ImportSubformField extends Field { const formFieldConfig = (this.state.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = this.getFullpath(formFieldConfig.field, path) + const withConfigPath = this.props.config.withConfig?.enable && this.props.config.withConfig?.dataField ? `${this.props.config.withConfig.dataField}` : '' + const fullPath = getChainPath(withConfigPath, formFieldConfig.field, path) await this.props.onValueUnset(fullPath, true) let formData = this.state.formData @@ -254,7 +257,8 @@ export default class ImportSubformField extends Field { const formFieldConfig = (this.state.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = this.getFullpath(formFieldConfig.field, path) + const withConfigPath = this.props.config.withConfig?.enable && this.props.config.withConfig?.dataField ? `${this.props.config.withConfig.dataField}` : '' + const fullPath = getChainPath(withConfigPath, formFieldConfig.field, path) await this.props.onValueListAppend(fullPath, value, true) let formData = this.state.formData @@ -273,7 +277,8 @@ export default class ImportSubformField extends Field { const formFieldConfig = (this.state.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = this.getFullpath(formFieldConfig.field, path) + const withConfigPath = this.props.config.withConfig?.enable && this.props.config.withConfig?.dataField ? `${this.props.config.withConfig.dataField}` : '' + const fullPath = getChainPath(withConfigPath, formFieldConfig.field, path) await this.props.onValueListSplice(fullPath, index, count, true) let formData = this.state.formData @@ -292,7 +297,8 @@ export default class ImportSubformField extends Field { const formFieldConfig = (this.state.fields || [])[formFieldIndex] if (formFieldConfig) { - const fullPath = this.getFullpath(formFieldConfig.field, path) + const withConfigPath = this.props.config.withConfig?.enable && this.props.config.withConfig?.dataField ? `${this.props.config.withConfig.dataField}` : '' + const fullPath = getChainPath(withConfigPath, formFieldConfig.field, path) await this.props.onValueListSort(fullPath, index, sortType, true) let formData = this.state.formData @@ -317,7 +323,6 @@ export default class ImportSubformField extends Field { // ts对clas if (formFieldConfig) { const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - if(this.props.handleFormValue) { - this.props.handleFormValue({path: fullPath, value}) - } - - this.formValue = set(this.formValue, fullPath, value) this.setState(({formValue})=>({ formValue: this.formValue -- Gitee From 956c2c2c0593d627c240c81ab691ca869f04a5fa Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Wed, 9 Feb 2022 18:08:20 +0800 Subject: [PATCH 25/38] =?UTF-8?q?fix:=20handleReportFields=E6=94=BE?= =?UTF-8?q?=E5=88=B0formfield=E7=9A=84common?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/any/index.tsx | 3 --- src/components/formFields/common.tsx | 17 +++++++++++++++-- src/components/formFields/form/index.tsx | 14 +------------- src/components/formFields/group/index.tsx | 13 +------------ .../formFields/importSubform/index.tsx | 13 ------------- src/components/formFields/object/index.tsx | 13 +------------ src/components/formFields/tabs/index.tsx | 12 ------------ src/steps/filter/index.tsx | 1 - src/steps/form/index.tsx | 3 +-- src/util/param.ts | 11 +++++++---- 10 files changed, 26 insertions(+), 74 deletions(-) diff --git a/src/components/formFields/any/index.tsx b/src/components/formFields/any/index.tsx index 37a3744..f6c28c3 100644 --- a/src/components/formFields/any/index.tsx +++ b/src/components/formFields/any/index.tsx @@ -99,7 +99,6 @@ export default class AnyField extends Field : ( type === 'number' ? {}} @@ -119,7 +118,6 @@ export default class AnyField extends Field : {}} form={this.props.form} @@ -138,7 +136,6 @@ export default class AnyField extends Field ) })} diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index ae766a2..e162c1c 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -3,6 +3,7 @@ import { ColumnsConfig, ParamConfig } from '../../interface' import { FieldConfigs as getFieldConfigs } from './' import ParamHelper from '../../util/param' +import { updateCommonPrefixItem } from '../../util/value' import { ConditionConfig } from '../../util/condition' import { StatementConfig } from '../../util/statement' import { isEqual, get } from 'lodash' @@ -96,7 +97,6 @@ export interface FieldProps { onValueListSort: (path: string, index: number, sortType: 'up' | 'down', validation: true | FieldError[]) => Promise baseRoute: string, path: string, // 组件所在路径以字段拼接展示 1.3.0新增 - dependentFields: string[] // 子组件param依赖字段存放数组 1.3.0新增 onReportFields?:(field: string) => Promise //向父组件上报依赖字段 1.3.0新增 step: { [field: string]: any } // 传递formValue loadDomain: (domain: string) => Promise @@ -132,6 +132,7 @@ export interface FieldInterface { * - S: 表单项的扩展状态 */ export class Field extends React.Component, S> implements IField { + dependentFields: string[] = [] // 组件param依赖字段存放数组 1.3.0新增 static defaultProps = { config: {} }; @@ -172,6 +173,18 @@ export class Field extends React.Component< didMount: () => Promise = async () => { } +/** + * 上报param依赖字段名称 + * @param field + */ + handleReportFields: (field: string) => void = async (field) => { + // if (this.dependentFields.includes(field)) return + let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields, field) + if (typeof update === 'boolean') return + this.dependentFields = update + this.props.onReportFields && await this.props.onReportFields(field) + } + renderComponent = (props: E) => { return 当前UI库未实现该表单类型 @@ -180,7 +193,7 @@ export class Field extends React.Component< shouldComponentUpdate(nextProps:FieldProps, nextState: S) { // console.log('nextProps', nextProps, this.props, nextProps.value == this.props.value); - const dependentFieldsArr = nextProps.dependentFields + const dependentFieldsArr = this.dependentFields // console.log('dependentFieldsArr',dependentFieldsArr); let dependentIsChange = false if (dependentFieldsArr && dependentFieldsArr.length) { diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index 21e8bd2..be27d88 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -67,7 +67,6 @@ export default class FormField extends Field | null>> = [] formFieldsMountedList: Array> = [] - dependentFields_: string[] = [] selfPath:string = '' // Tabs和formList需要保存自身路径传给子组件 constructor (props: FieldProps) { @@ -420,17 +419,7 @@ export default class FormField extends Field { - // if (this.dependentFields_.includes(field)) return - let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) - if (typeof update === 'boolean') return - this.dependentFields_ = update - this.props.onReportFields && await this.props.onReportFields(field) - } + /** * 用于展示子表单组件中的每一子项中的每一个子表单项组件 @@ -562,7 +551,6 @@ export default class FormField extends Field await this.props.loadDomain(domain)} path={getChainPath(this.props.path, `${index}.${formFieldConfig.field}`)} - dependentFields={this.dependentFields_} onReportFields={async (field: string) => await this.handleReportFields(field)} /> ) diff --git a/src/components/formFields/group/index.tsx b/src/components/formFields/group/index.tsx index 97c5a08..ec804d3 100644 --- a/src/components/formFields/group/index.tsx +++ b/src/components/formFields/group/index.tsx @@ -47,7 +47,6 @@ export default class GroupField extends Field | null> = [] formFieldsMounted: Array = [] - dependentFields_: string[] = [] constructor (props: FieldProps) { super(props) @@ -274,16 +273,7 @@ export default class GroupField extends Field { - let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) - if (typeof update === 'boolean') return - this.dependentFields_ = update - this.props.onReportFields && await this.props.onReportFields(field) - } + renderComponent = (props: IGroupField) => { return @@ -388,7 +378,6 @@ export default class GroupField extends Field await this.props.loadDomain(domain)} path={getChainPath(this.props.path, formFieldConfig.field)} - dependentFields={this.dependentFields_} onReportFields={async(field: string) => await this.handleReportFields(field)} /> ) diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx index f1fbd81..986e055 100644 --- a/src/components/formFields/importSubform/index.tsx +++ b/src/components/formFields/importSubform/index.tsx @@ -50,7 +50,6 @@ export default class ImportSubformField extends Field | null> = [] formFieldsMounted: Array = [] - dependentFields_: string[] = [] interfaceHelper = new InterfaceHelper() @@ -314,17 +313,6 @@ export default class ImportSubformField extends Field { - // if (this.dependentFields_.includes(field)) return - let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) - if (typeof update === 'boolean') return - this.dependentFields_ = update - this.props.onReportFields && await this.props.onReportFields(field) - } renderComponent = (props: IImportSubformField) => { return @@ -462,7 +450,6 @@ export default class ImportSubformField extends Field await this.props.loadDomain(domain)} path={getChainPath(this.props.path, formFieldConfig.field)} - dependentFields={this.dependentFields_} onReportFields={async(field: string) => await this.handleReportFields(field)} /> ) diff --git a/src/components/formFields/object/index.tsx b/src/components/formFields/object/index.tsx index cf28780..2e737fc 100644 --- a/src/components/formFields/object/index.tsx +++ b/src/components/formFields/object/index.tsx @@ -54,7 +54,6 @@ export default class ObjectField extends Field | null> } = {} formFieldsMountedList: { [key: string]: Array } = {} - dependentFields_: string[] = [] constructor (props: FieldProps) { super(props) @@ -356,16 +355,7 @@ export default class ObjectField extends Field { - let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) - if (typeof update === 'boolean') return - this.dependentFields_ = update - this.props.onReportFields && await this.props.onReportFields(field) - } + /** @@ -494,7 +484,6 @@ export default class ObjectField extends Field this.props.loadDomain(domain)} path={getChainPath(this.props.path, `${key}${formFieldConfig.field}`)} - dependentFields={this.dependentFields_} onReportFields={async(field: string) => await this.handleReportFields(field)} /> ) diff --git a/src/components/formFields/tabs/index.tsx b/src/components/formFields/tabs/index.tsx index e6375e0..753da54 100644 --- a/src/components/formFields/tabs/index.tsx +++ b/src/components/formFields/tabs/index.tsx @@ -66,7 +66,6 @@ export default class TabsField extends Field | null>> = [] formFieldsMountedList: Array> = [] - dependentFields_: string[] = [] selfPath:string = '' // Tabs和formList需要保存自身路径传给子组件 constructor (props: FieldProps) { @@ -325,16 +324,6 @@ export default class TabsField extends Field { - let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) - if (typeof update === 'boolean') return - this.dependentFields_ = update - this.props.onReportFields && await this.props.onReportFields(field) - } /** @@ -459,7 +448,6 @@ export default class TabsField extends Field await this.props.loadDomain(domain)} path={getChainPath(this.props.path, `${tab.field}.${formFieldConfig.field}`)} - dependentFields={this.dependentFields_} onReportFields={async(field: string) => await this.handleReportFields(field)} /> ) diff --git a/src/steps/filter/index.tsx b/src/steps/filter/index.tsx index b7296bb..a1aded3 100644 --- a/src/steps/filter/index.tsx +++ b/src/steps/filter/index.tsx @@ -517,7 +517,6 @@ export default class FilterStep extends Step { baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} path={getChainPath(formFieldConfig.field)} - dependentFields={this.dependentFields_} onReportFields={async (field: string) => await this.handleReportFields(field)} /> ) diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index 1e8e7d7..1e7612a 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -542,7 +542,7 @@ export default class FormStep extends Step { // ts对clas let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) if (typeof update === 'boolean') return this.dependentFields_ = update - console.log('step依赖', this.dependentFields_); + // console.log('step依赖', this.dependentFields_); } /** @@ -743,7 +743,6 @@ export default class FormStep extends Step { // ts对clas baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} path={getChainPath(formFieldConfig.field)} - dependentFields={this.dependentFields_} onReportFields={async (field: string) => await this.handleReportFields(field)} /> ) diff --git a/src/util/param.ts b/src/util/param.ts index f10ea63..c9fc1d3 100644 --- a/src/util/param.ts +++ b/src/util/param.ts @@ -1,4 +1,4 @@ -import { get } from "lodash" +import _, { get } from "lodash" import qs from "query-string" import { ParamConfig } from "../interface"; import { getChainPath } from '../util/value' @@ -7,7 +7,10 @@ export default function ParamHelper ( config: ParamConfig, datas: { record?: obj switch (config.source) { case 'record': if (datas.record) { - _this && _this.props.onReportFields && _this.props.onReportFields(getChainPath(_this.selfPath || _this.props.path, config.field)) + if (_this) { + const fullPath = getChainPath(_this.selfPath || _this.props.path, config.field) + _this.handleReportFields(fullPath) + } if (config.field === '') { return datas.record } else { @@ -17,7 +20,7 @@ export default function ParamHelper ( config: ParamConfig, datas: { record?: obj break case 'data': if (datas.step) { - _this && _this.props.onReportFields && _this.props.onReportFields(`${config.field}`) + _this && _this.handleReportFields(`${config.field}`) if (config.field === '') { return datas.step } else { @@ -36,7 +39,7 @@ export default function ParamHelper ( config: ParamConfig, datas: { record?: obj break case 'step': if (datas.data[config.step]) { - _this && _this.props.onReportFields && _this.props.onReportFields(`${config.field}`) + _this && _this.handleReportFields(`${config.field}`) if (config.field === '') { return datas.data[config.step] } else { -- Gitee From cd00d1ba23981a0574559276dec6c5c0bb5800b0 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Wed, 9 Feb 2022 20:09:51 +0800 Subject: [PATCH 26/38] =?UTF-8?q?fix:=20=E5=8E=BB=E9=99=A4step=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E4=B8=ADhandleReportFields?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/steps/filter/index.tsx | 11 ---------- src/steps/form/index.tsx | 43 ++++++++++++++------------------------ 2 files changed, 16 insertions(+), 38 deletions(-) diff --git a/src/steps/filter/index.tsx b/src/steps/filter/index.tsx index a1aded3..07e9094 100644 --- a/src/steps/filter/index.tsx +++ b/src/steps/filter/index.tsx @@ -405,16 +405,6 @@ export default class FilterStep extends Step { } } - /** - * 上报param依赖字段名称 - * @param field - */ - handleReportFields = async (field: string) => { - let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) - if (typeof update === 'boolean') return - this.dependentFields_ = update - } - /** * 表单步骤组件 - UI渲染方法 * 各UI库需重写该方法 @@ -517,7 +507,6 @@ export default class FilterStep extends Step { baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} path={getChainPath(formFieldConfig.field)} - onReportFields={async (field: string) => await this.handleReportFields(field)} /> ) } diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index 1e7612a..1092ece 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -199,7 +199,7 @@ export default class FormStep extends Step { // ts对clas * 初始化表单的值 * @param props */ - constructor (props: StepProps) { + constructor(props: StepProps) { super(props) this.state = { ready: false, @@ -242,7 +242,7 @@ export default class FormStep extends Step { // ts对clas for (const formFieldIndex in formFieldsConfig) { const formFieldConfig = formFieldsConfig[formFieldIndex] const value = getValue(formDefault, formFieldConfig.field) - + this.formValue = setValue(this.formValue, formFieldConfig.field, value) this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal', name: formFieldConfig.label }) } @@ -274,7 +274,7 @@ export default class FormStep extends Step { // ts对clas } value = await formField.set(value) this.formValue = setValue(this.formValue, formFieldConfig.field, value) - + if (value !== undefined) { const validation = await formField.validate(value) if (validation === true) { @@ -397,9 +397,9 @@ export default class FormStep extends Step { // ts对clas const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] if (formFieldConfig) { const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - + this.formValue = set(this.formValue, fullPath, value) - this.setState(({formValue})=>({ + this.setState(({ formValue }) => ({ formValue: this.formValue })) @@ -452,7 +452,7 @@ export default class FormStep extends Step { // ts对clas if (formFieldConfig) { const fullPath = formFieldConfig.field === '' || path === '' ? `${formFieldConfig.field}${path}` : `${formFieldConfig.field}.${path}` - this.formValue = push(this.formValue, fullPath, value) //向this.formValue的fullPath下的值添加value + this.formValue = push(this.formValue, fullPath, value) // 向this.formValue的fullPath下的值添加value this.setState({ formValue: this.formValue }) @@ -534,16 +534,6 @@ export default class FormStep extends Step { // ts对clas } } } -/** - * 上报param依赖字段名称 - * @param field - */ - handleReportFields = async (field: string) => { - let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields_, field) - if (typeof update === 'boolean') return - this.dependentFields_ = update - // console.log('step依赖', this.dependentFields_); - } /** * 表单步骤组件 - UI渲染方法 @@ -588,7 +578,7 @@ export default class FormStep extends Step { // ts对clas }) } - render () { + render() { const { data, step, @@ -654,7 +644,7 @@ export default class FormStep extends Step { // ts对clas } } } - + if (ready) { return ( @@ -687,7 +677,7 @@ export default class FormStep extends Step { // ts对clas // 隐藏项同时打标录入数据并清空填写项 if (!hidden) { - this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal', name: formFieldConfig.label }) + this.formData = set(this.formData, `[${formFieldIndex}]`, { status: 'normal', name: formFieldConfig.label }) } const FormField = this.getALLComponents(formFieldConfig.type) || Field @@ -697,18 +687,18 @@ export default class FormStep extends Step { // ts对clas if (['group', 'import_subform', 'object', 'tabs', 'form'].some((type) => type === formFieldConfig.type)) { status = 'normal' } - + const renderData = { key: formFieldIndex, label: formFieldConfig.label, columns: columns?.enable ? { - type: formFieldConfig.columns?.type || columns?.type || 'span', - value: formFieldConfig.columns?.value || columns?.value || 1, - wrap: formFieldConfig.columns?.wrap || columns?.wrap || false, - gap: columns?.gap || 0, - rowGap: columns?.rowGap || 0 - } + type: formFieldConfig.columns?.type || columns?.type || 'span', + value: formFieldConfig.columns?.value || columns?.value || 1, + wrap: formFieldConfig.columns?.wrap || columns?.wrap || false, + gap: columns?.gap || 0, + rowGap: columns?.rowGap || 0 + } : undefined, status, message: formData[formFieldIndex]?.message || '', @@ -743,7 +733,6 @@ export default class FormStep extends Step { // ts对clas baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} path={getChainPath(formFieldConfig.field)} - onReportFields={async (field: string) => await this.handleReportFields(field)} /> ) } -- Gitee From c02570723beffd5e3dfad75aec17d6708721826d Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Thu, 10 Feb 2022 00:56:28 +0800 Subject: [PATCH 27/38] =?UTF-8?q?fix:=20path=E6=94=B9=E4=B8=BAcontainerPat?= =?UTF-8?q?h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/any/index.tsx | 6 +- src/components/formFields/common.tsx | 59 +++++++++---------- src/components/formFields/form/index.tsx | 10 +--- src/components/formFields/group/index.tsx | 2 +- .../formFields/importSubform/index.tsx | 2 +- src/components/formFields/object/index.tsx | 2 +- src/components/formFields/readme.md | 16 ++--- src/components/formFields/tabs/index.tsx | 7 +-- src/steps/detail/index.tsx | 2 +- src/steps/filter/index.tsx | 8 +-- src/steps/form/index.tsx | 14 ++--- src/steps/header/index.tsx | 2 +- src/util/param.ts | 14 ++--- 13 files changed, 66 insertions(+), 78 deletions(-) diff --git a/src/components/formFields/any/index.tsx b/src/components/formFields/any/index.tsx index f6c28c3..566caf9 100644 --- a/src/components/formFields/any/index.tsx +++ b/src/components/formFields/any/index.tsx @@ -98,7 +98,7 @@ export default class AnyField extends Field : ( type === 'number' ? {}} @@ -117,7 +117,7 @@ export default class AnyField extends Field : {}} form={this.props.form} @@ -135,7 +135,7 @@ export default class AnyField extends Field ) })} diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index e162c1c..01f5d11 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -96,8 +96,8 @@ export interface FieldProps { // 事件:修改值 - 列表 - 修改顺序 onValueListSort: (path: string, index: number, sortType: 'up' | 'down', validation: true | FieldError[]) => Promise baseRoute: string, - path: string, // 组件所在路径以字段拼接展示 1.3.0新增 - onReportFields?:(field: string) => Promise //向父组件上报依赖字段 1.3.0新增 + containerPath: string, // 容器组件所在路径以字段拼接展示 1.3.0新增 + onReportFields?: (field: string) => Promise // 向父组件上报依赖字段 1.3.0新增 step: { [field: string]: any } // 传递formValue loadDomain: (domain: string) => Promise } @@ -140,7 +140,7 @@ export class Field extends React.Component< /** * 获取默认值 */ - defaultValue = async () => { + async defaultValue (this: any) { const { config } = this.props @@ -173,31 +173,32 @@ export class Field extends React.Component< didMount: () => Promise = async () => { } -/** - * 上报param依赖字段名称 - * @param field - */ - handleReportFields: (field: string) => void = async (field) => { - // if (this.dependentFields.includes(field)) return - let update: string[] | boolean = updateCommonPrefixItem(this.dependentFields, field) - if (typeof update === 'boolean') return - this.dependentFields = update - this.props.onReportFields && await this.props.onReportFields(field) - } + /** + * 上报param依赖字段名称 + * @param field + */ + handleReportFields: (field: string) => void = async (field) => { + // if (this.dependentFields.includes(field)) return + const update: string[] | boolean = updateCommonPrefixItem(this.dependentFields, field) + if (typeof update === 'boolean') return + this.dependentFields = update + this.props.onReportFields && await this.props.onReportFields(field) + } renderComponent = (props: E) => { return 当前UI库未实现该表单类型 } - shouldComponentUpdate(nextProps:FieldProps, nextState: S) { + + shouldComponentUpdate (nextProps: FieldProps, nextState: S) { // console.log('nextProps', nextProps, this.props, nextProps.value == this.props.value); - + const dependentFieldsArr = this.dependentFields // console.log('dependentFieldsArr',dependentFieldsArr); let dependentIsChange = false if (dependentFieldsArr && dependentFieldsArr.length) { - for (let i=dependentFieldsArr.length;i>=0;i--) { + for (let i = dependentFieldsArr.length; i >= 0; i--) { const nextDependentField = get(nextProps.step, dependentFieldsArr[i]) const currentDependentField = get(this.props.step, dependentFieldsArr[i]) @@ -205,20 +206,19 @@ export class Field extends React.Component< dependentIsChange = true break } - } } - -/** - * data提交前不变, 去掉这项的比较 - * record也不比较,需要比较的话就在dependentFieldsArr取出record绝对路径 - * */ - if (!dependentIsChange && isEqual(this.state, nextState) && nextProps.value === this.props.value && this.props.config === nextProps.config) { - // console.log('no update' ); - return false; + + /** + * data提交前不变, 去掉这项的比较 + * record也不比较,需要比较的话就在dependentFieldsArr取出record绝对路径 + * */ + if (!dependentIsChange && isEqual(this.state, nextState) && nextProps.value === this.props.value && this.props.config === nextProps.config) { + // console.log('no update' ); + return false + } + return true } - return true; -} render = () => { return ( @@ -252,7 +252,7 @@ export class Display extends React.Componen config } = this.props if (config.defaultValue !== undefined) { - return ParamHelper(config.defaultValue, { record: this.props.record, data: this.props.data, step: this.props.step }, this) + return ParamHelper(config.defaultValue, { record: this.props.record, data: this.props.data, step: this.props.step }) } return undefined @@ -291,4 +291,3 @@ export class FieldError { this.message = message } } - diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index be27d88..e95af8e 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -67,7 +67,6 @@ export default class FormField extends Field | null>> = [] formFieldsMountedList: Array> = [] - selfPath:string = '' // Tabs和formList需要保存自身路径传给子组件 constructor (props: FieldProps) { super(props) @@ -280,13 +279,13 @@ export default class FormField extends Field { var list = this.state.formDataList - let formDataList = sort(list, '', index, sortType) + const formDataList = sort(list, '', index, sortType) this.setState({ formDataList: formDataList }) @@ -495,9 +494,6 @@ export default class FormField extends Field await this.handleSort(index, sortType) : undefined, canCollapse, children: (fields || []).map((formFieldConfig, fieldIndex) => { - if (!this.selfPath) { - this.selfPath = getChainPath(this.props.path, index) - } if (!ConditionHelper(formFieldConfig.condition, { record: itemValue, data: this.props.data, step: this.props.step }, this)) { if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `${index}`, [] ) // this.formFieldsMountedList[index][fieldIndex] = false @@ -550,7 +546,7 @@ export default class FormField extends Field await this.handleValueListSort(index, fieldIndex, path, _index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} - path={getChainPath(this.props.path, `${index}.${formFieldConfig.field}`)} + containerPath={getChainPath(this.props.containerPath, this.props.config.field, index)} onReportFields={async (field: string) => await this.handleReportFields(field)} /> ) diff --git a/src/components/formFields/group/index.tsx b/src/components/formFields/group/index.tsx index ec804d3..a2be717 100644 --- a/src/components/formFields/group/index.tsx +++ b/src/components/formFields/group/index.tsx @@ -377,7 +377,7 @@ export default class GroupField extends Field this.handleValueListSort(formFieldIndex, path, index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} - path={getChainPath(this.props.path, formFieldConfig.field)} + containerPath={getChainPath(this.props.containerPath, this.props.config.field)} onReportFields={async(field: string) => await this.handleReportFields(field)} /> ) diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx index 986e055..c296d83 100644 --- a/src/components/formFields/importSubform/index.tsx +++ b/src/components/formFields/importSubform/index.tsx @@ -449,7 +449,7 @@ export default class ImportSubformField extends Field this.handleValueListSort(formFieldIndex, path, index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} - path={getChainPath(this.props.path, formFieldConfig.field)} + containerPath={getChainPath(this.props.containerPath, this.props.config.field)} onReportFields={async(field: string) => await this.handleReportFields(field)} /> ) diff --git a/src/components/formFields/object/index.tsx b/src/components/formFields/object/index.tsx index 2e737fc..1ee93c8 100644 --- a/src/components/formFields/object/index.tsx +++ b/src/components/formFields/object/index.tsx @@ -483,7 +483,7 @@ export default class ObjectField extends Field this.handleValueListSort(key, formFieldIndex, path, _index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => this.props.loadDomain(domain)} - path={getChainPath(this.props.path, `${key}${formFieldConfig.field}`)} + containerPath={getChainPath(this.props.containerPath, this.props.config.field, key)} onReportFields={async(field: string) => await this.handleReportFields(field)} /> ) diff --git a/src/components/formFields/readme.md b/src/components/formFields/readme.md index 565e722..d69849c 100644 --- a/src/components/formFields/readme.md +++ b/src/components/formFields/readme.md @@ -1,4 +1,4 @@ -# immer +#### immer Immer是一个简单易用、体量小巧、设计巧妙的immutable 库,以最小的成本实现了js的不可变数据结构。 @@ -6,7 +6,7 @@ Js的对象是引用类型的,在使用过程中常常会不经意的修改。 immer基于copy-on-write机制——在当前的状态数据上复制出一份临时的草稿,然后对这份草稿修改,最后生成新的状态数据。借力于ES6的Proxy,跟响应式的自动跟踪是一样的。 https://immerjs.github.io/immer/api -# immer写法 +#### immer写法 ```js import produce from "immer" @@ -32,7 +32,7 @@ this.setState(produce(draft => { draft.members[0].age++; })) ``` -# immer拓展 +#### immer拓展 1. 返回值问题 以高阶函数写法为例 语法:produce(recipe: (draftState) => void | draftState, ?PatchListener)(currentState): nextState @@ -45,14 +45,14 @@ recipe 是否有返回值,nextState 的生成过程是不同的: Immer 会自动冻结使用 produce 修改过的状态树,这样可以防止在变更函数外部修改状态树。这个特性会带来性能影响,所以需要在生产环境中关闭。可以使用 setAutoFreeze(true / false) 打开或者关闭。在开发环境中建议打开,可以避免不可预测的状态树更改 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze -# immer结合shouldComponentUpdate做了哪些事? +#### immer结合shouldComponentUpdate做了哪些事? SCU的对于引用类型对象的比较,如果通过比较它们的值往往很耗费性能,有了数据结构共享,我们可以通过比较复杂对象的每一个节点的指针指向是否相同,大大节省性能损耗 -# 项目中数据依赖字段上报规则及注意record(当前记录)注意事项 -1. 每一个组件在handleMount以后知道它们的this.props.path和自身的field路径,以path字段向下传递给子组件,我们在paramHelper里面对应record里的依赖项的处理是,拿到父级的路径和record依赖的字段(举例为DepField),通过getChainPath(this.props.path, DepField)拿到完整的链式路径,onReportFields上报给父组件有哪些依赖项,参见下: +#### 项目中数据依赖字段上报规则及注意record(当前记录)注意事项 +1. 每一个组件在handleMount以后知道它们的this.props.containerPath和自身的field路径,以containerPath字段向下传递给子组件,我们在paramHelper里面对应record里的依赖项的处理是,拿到父级的路径和record依赖的字段(举例为DepField),通过getChainPath(this.props.containerPath, DepField)拿到完整的链式路径,onReportFields上报给父组件有哪些依赖项,参见下: -path=this.props.path+field ----传递子组件---> path=this.props.path+field -父组件 <----onReportFields--- getChainPath(this.props.path, DepField) +containerPath=this.props.containerPath+field ----传递子组件---> containerPath=this.props.containerPath+field +父组件 <----onReportFields--- getChainPath(this.props.containerPath, DepField) 2. 正常来说,父组件的value就是子组件的record, 特殊的是tabs和form两个组件对应分别多了tab.field和index,这里通过Helper传递record时,取值分别对应下探到tab.field和index。 示例: diff --git a/src/components/formFields/tabs/index.tsx b/src/components/formFields/tabs/index.tsx index 753da54..b8c0c81 100644 --- a/src/components/formFields/tabs/index.tsx +++ b/src/components/formFields/tabs/index.tsx @@ -66,7 +66,6 @@ export default class TabsField extends Field | null>> = [] formFieldsMountedList: Array> = [] - selfPath:string = '' // Tabs和formList需要保存自身路径传给子组件 constructor (props: FieldProps) { super(props) @@ -381,10 +380,6 @@ export default class TabsField extends Field { - if (!this.selfPath) { - this.selfPath = getChainPath(this.props.path, tab.field) - } - if (!ConditionHelper(formFieldConfig.condition, { record: getValue(value, tab.field), data: this.props.data, step: this.props.step }, this)) { if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}]`, []) this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}][${formFieldIndex}]`, false) @@ -447,7 +442,7 @@ export default class TabsField extends Field this.handleValueListSort(index, formFieldIndex, path, _index, sortType, validation)} baseRoute={this.props.baseRoute} loadDomain={async (domain: string) => await this.props.loadDomain(domain)} - path={getChainPath(this.props.path, `${tab.field}.${formFieldConfig.field}`)} + containerPath={getChainPath(this.props.containerPath, this.props.config.field, tab.field)} onReportFields={async(field: string) => await this.handleReportFields(field)} /> ) diff --git a/src/steps/detail/index.tsx b/src/steps/detail/index.tsx index c566bb3..dcac904 100644 --- a/src/steps/detail/index.tsx +++ b/src/steps/detail/index.tsx @@ -145,7 +145,7 @@ export default class DetailStep extends Step { const detailData = cloneDeep(this.state.detailData) if (this.props.config.defaultValue) { - let detailDefault = ParamHelper(this.props.config.defaultValue, { data, step }, this) + let detailDefault = ParamHelper(this.props.config.defaultValue, { data, step }) if (this.props.config.unstringify) { for (const field of this.props.config.unstringify) { const info = getValue(detailDefault, field) diff --git a/src/steps/filter/index.tsx b/src/steps/filter/index.tsx index 07e9094..a6704ec 100644 --- a/src/steps/filter/index.tsx +++ b/src/steps/filter/index.tsx @@ -115,7 +115,7 @@ export default class FilterStep extends Step { this.formData = [] if (this.props.config.defaultValue) { - const formDefault = ParamHelper(this.props.config.defaultValue, { data: this.props.data, step: this.props.step }, this) + const formDefault = ParamHelper(this.props.config.defaultValue, { data: this.props.data, step: this.props.step }) for (const formFieldIndex in (this.props.config.fields || [])) { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] const value = (formFieldConfig.field === undefined || formFieldConfig.field === '') ? formDefault : get(formDefault, formFieldConfig.field) @@ -216,7 +216,7 @@ export default class FilterStep extends Step { this.formData = [] if (this.props.config.defaultValue) { - const formDefault = ParamHelper(this.props.config.defaultValue, { data: this.props.data, step: this.props.step }, this) + const formDefault = ParamHelper(this.props.config.defaultValue, { data: this.props.data, step: this.props.step }) for (const formFieldIndex in (this.props.config.fields || [])) { const formFieldConfig = (this.props.config.fields || [])[formFieldIndex] const value = (formFieldConfig.field === undefined || formFieldConfig.field === '') ? formDefault : get(formDefault, formFieldConfig.field) @@ -450,7 +450,7 @@ export default class FilterStep extends Step { submitText: this.props.config?.submitText?.replace(/(^\s*)|(\s*$)/g, ""), resetText: this.props.config?.resetText?.replace(/(^\s*)|(\s*$)/g, ""), children: fields.map((formFieldConfig, formFieldIndex) => { - if (!ConditionHelper(formFieldConfig.condition, { record: formValue, data, step }, this)) { + if (!ConditionHelper(formFieldConfig.condition, { record: formValue, data, step })) { this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, false) return null } @@ -506,7 +506,7 @@ export default class FilterStep extends Step { 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)} - path={getChainPath(formFieldConfig.field)} + containerPath={''} /> ) } diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index 1092ece..cca1d8a 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -226,7 +226,7 @@ export default class FormStep extends Step { // ts对clas this.formData = [] if (this.props.config.defaultValue) { - let formDefault = ParamHelper(this.props.config.defaultValue, { data, step }, this) + let formDefault = ParamHelper(this.props.config.defaultValue, { data, step }) if (this.props.config.unstringify) { for (const field of this.props.config.unstringify) { @@ -301,9 +301,9 @@ export default class FormStep extends Step { // ts对clas this.submitData = {} if (this.props.config.validations) { for (const validation of this.props.config.validations) { - if (!ConditionHelper(validation.condition, { record: this.state.formValue, data: this.props.data, step: this.formValue }, this)) { + if (!ConditionHelper(validation.condition, { record: this.state.formValue, data: this.props.data, step: this.formValue })) { this.canSubmit = false - const message = StatementHelper(validation.message, { record: this.state.formValue, data: this.props.data, step: this.formValue }, this) || '未填写失败文案或失败文案配置异常' + const message = StatementHelper(validation.message, { record: this.state.formValue, data: this.props.data, step: this.formValue }) || '未填写失败文案或失败文案配置异常' this.renderModalComponent({ message }) return } @@ -603,7 +603,7 @@ export default class FormStep extends Step { // ts对clas if (Object.prototype.toString.call(actions) === '[object Array]') { actions_ = [] for (let index = 0, len = actions.length; index < len; index++) { - if (!ConditionHelper(actions[index].condition, { record: formValue, data, step: formValue }, this)) { + if (!ConditionHelper(actions[index].condition, { record: formValue, data, step: formValue })) { continue } if (actions[index].type === 'submit') { @@ -658,7 +658,7 @@ export default class FormStep extends Step { // ts对clas submitText: this.props.config?.submitText?.replace(/(^\s*)|(\s*$)/g, ''), // TODO 待删除 cancelText: this.props.config?.cancelText?.replace(/(^\s*)|(\s*$)/g, ''), // TODO 待删除 children: fields.map((formFieldConfig, formFieldIndex) => { - if (!ConditionHelper(formFieldConfig.condition, { record: formValue, data, step: formValue }, this)) { + if (!ConditionHelper(formFieldConfig.condition, { record: formValue, data, step: formValue })) { this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, false) return null } @@ -702,7 +702,7 @@ export default class FormStep extends Step { // ts对clas : undefined, status, message: formData[formFieldIndex]?.message || '', - extra: StatementHelper(formFieldConfig.extra, { data: this.props.data, step: formValue }, this), + extra: StatementHelper(formFieldConfig.extra, { data: this.props.data, step: formValue }), required: getBoolean(formFieldConfig.required), layout, visitable: display, @@ -732,7 +732,7 @@ export default class FormStep extends Step { // ts对clas 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)} - path={getChainPath(formFieldConfig.field)} + containerPath={''} /> ) } diff --git a/src/steps/header/index.tsx b/src/steps/header/index.tsx index 671db3d..a7ec2d7 100644 --- a/src/steps/header/index.tsx +++ b/src/steps/header/index.tsx @@ -243,7 +243,7 @@ export default class HeaderStep extends Step { handleStatisticContent = (config: statisticContentConfig, _position: string) => { return (config.statistics || []).map((statistic, index) => { - const value = statistic.value ? ParamHelper(statistic.value, { data: this.props.data, step: this.props.step }, this) : undefined + const value = statistic.value ? ParamHelper(statistic.value, { data: this.props.data, step: this.props.step }) : undefined switch (statistic.type) { case 'value': return this.renderStatisticComponent({ diff --git a/src/util/param.ts b/src/util/param.ts index c9fc1d3..a02d243 100644 --- a/src/util/param.ts +++ b/src/util/param.ts @@ -2,15 +2,13 @@ import _, { get } from "lodash" import qs from "query-string" import { ParamConfig } from "../interface"; import { getChainPath } from '../util/value' +import { Field , FieldConfig } from '../components/formFields/common' -export default function ParamHelper ( config: ParamConfig, datas: { record?: object, data: object[], step: { [field: string]: any } }, _this: any) { // step--> stepValue +export default function ParamHelper (config: ParamConfig, datas: { record?: object, data: object[], step: { [field: string]: unknown } }, _this?: Field) { // step--> stepValue switch (config.source) { case 'record': if (datas.record) { - if (_this) { - const fullPath = getChainPath(_this.selfPath || _this.props.path, config.field) - _this.handleReportFields(fullPath) - } + _this && _this.handleReportFields && _this.handleReportFields(getChainPath(_this.props.containerPath, config.field)) if (config.field === '') { return datas.record } else { @@ -20,11 +18,11 @@ export default function ParamHelper ( config: ParamConfig, datas: { record?: obj break case 'data': if (datas.step) { - _this && _this.handleReportFields(`${config.field}`) + _this && _this.handleReportFields && _this.handleReportFields(`${config.field}`) if (config.field === '') { return datas.step } else { - return get(datas.step, config.field) //return get(step, config.field) + return get(datas.step, config.field) // return get(step, config.field) } } break @@ -39,7 +37,7 @@ export default function ParamHelper ( config: ParamConfig, datas: { record?: obj break case 'step': if (datas.data[config.step]) { - _this && _this.handleReportFields(`${config.field}`) + _this && _this.handleReportFields && _this.handleReportFields(`${config.field}`) if (config.field === '') { return datas.data[config.step] } else { -- Gitee From 3711a6d9aff74e870b19a04ee6694f65f3d6c132 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Thu, 10 Feb 2022 00:58:32 +0800 Subject: [PATCH 28/38] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=9C=80?= =?UTF-8?q?=E9=95=BF=E5=85=B1=E5=90=8C=E5=89=8D=E7=BC=80=E7=BC=BA=E9=99=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/value.ts | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/util/value.ts b/src/util/value.ts index c447f91..86903cb 100644 --- a/src/util/value.ts +++ b/src/util/value.ts @@ -130,6 +130,22 @@ export const getChainPath = (...arg: any[]) => { return fullPath } +/** + * + * @param source 来源字符串 + * @param find 目标字符串 + * @returns 返回目标字符串出现在来源字符串中所有索引 + */ + function indexes(source: string, find: string) { + var result = [] + for (let i = 0; i < source.length; ++i) { + if (source.substring(i, i + find.length) == find) { + result.push(i) + } + } + return result +} + /** * 获取一个数组中最长共同前缀 */ @@ -139,13 +155,24 @@ export const getLongestCommonPrefix = (arr: string[]) => { let c=arr[0].charAt(i); for (let j=1,len2=arr.length;j Date: Thu, 10 Feb 2022 11:08:43 +0800 Subject: [PATCH 29/38] =?UTF-8?q?fix:=20=E4=BB=A3=E7=A0=81=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/form/index.tsx | 23 +++--- src/components/formFields/group/index.tsx | 5 +- .../formFields/importSubform/index.tsx | 11 +-- src/components/formFields/object/index.tsx | 6 +- src/components/formFields/tabs/index.tsx | 15 ++-- src/steps/common.tsx | 2 +- src/steps/detail/index.tsx | 3 +- src/steps/filter/index.tsx | 7 +- src/steps/form/index.tsx | 22 +++--- src/steps/header/index.tsx | 18 ++--- src/util/condition.ts | 12 ++- src/util/enumeration.ts | 4 +- src/util/interface.ts | 30 ++++---- src/util/operation.tsx | 19 +++-- src/util/param.ts | 10 +-- src/util/produce.tsx | 57 +++++++------- src/util/statement.ts | 13 ++-- src/util/value.ts | 76 +++++++++---------- 18 files changed, 151 insertions(+), 182 deletions(-) diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index e95af8e..7bc2146 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -220,7 +220,7 @@ export default class FormField extends Field { if (!ConditionHelper(formFieldConfig.condition, { record: itemValue, data: this.props.data, step: this.props.step }, this)) { - if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `${index}`, [] ) + if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `${index}`, []) // this.formFieldsMountedList[index][fieldIndex] = false this.formFieldsMountedList = set(this.formFieldsMountedList, `${[index]}.${fieldIndex}`, false) return null @@ -547,7 +544,7 @@ export default class FormField extends Field await this.props.loadDomain(domain)} containerPath={getChainPath(this.props.containerPath, this.props.config.field, index)} - onReportFields={async (field: string) => await this.handleReportFields(field)} + onReportFields={async (field: string) => await this.handleReportFields(field)} /> ) }) diff --git a/src/components/formFields/group/index.tsx b/src/components/formFields/group/index.tsx index a2be717..5737063 100644 --- a/src/components/formFields/group/index.tsx +++ b/src/components/formFields/group/index.tsx @@ -124,7 +124,6 @@ export default class GroupField extends Field { return 您当前使用的UI版本没有实现GroupField组件。 @@ -378,7 +375,7 @@ export default class GroupField extends Field await this.props.loadDomain(domain)} containerPath={getChainPath(this.props.containerPath, this.props.config.field)} - onReportFields={async(field: string) => await this.handleReportFields(field)} + onReportFields={async (field: string) => await this.handleReportFields(field)} /> ) } diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx index c296d83..986204a 100644 --- a/src/components/formFields/importSubform/index.tsx +++ b/src/components/formFields/importSubform/index.tsx @@ -1,11 +1,10 @@ import React from 'react' -import { getValue, getBoolean, getChainPath, updateCommonPrefixItem } from '../../../util/value' +import { getValue, getBoolean, getChainPath } from '../../../util/value' import { Field, FieldConfig, FieldError, FieldProps, IField } from '../common' import getALLComponents, { FieldConfigs } from '../' import { IFormItem } from '../../../steps/form' -import { concat, uniq } from 'lodash' -import { set, setValue, push } from '../../../util/produce' +import { set, setValue } from '../../../util/produce' import ConditionHelper from '../../../util/condition' import InterfaceHelper, { InterfaceConfig } from '../../../util/interface' import StatementHelper from '../../../util/statement' @@ -50,7 +49,6 @@ export default class ImportSubformField extends Field | null> = [] formFieldsMounted: Array = [] - interfaceHelper = new InterfaceHelper() constructor (props: FieldProps) { @@ -63,8 +61,6 @@ export default class ImportSubformField extends Field { await this.setState({ didMount: true @@ -313,7 +309,6 @@ export default class ImportSubformField extends Field { return 您当前使用的UI版本没有实现ImportSubformField组件。 @@ -450,7 +445,7 @@ export default class ImportSubformField extends Field await this.props.loadDomain(domain)} containerPath={getChainPath(this.props.containerPath, this.props.config.field)} - onReportFields={async(field: string) => await this.handleReportFields(field)} + onReportFields={async (field: string) => await this.handleReportFields(field)} /> ) } diff --git a/src/components/formFields/object/index.tsx b/src/components/formFields/object/index.tsx index 1ee93c8..99e1c92 100644 --- a/src/components/formFields/object/index.tsx +++ b/src/components/formFields/object/index.tsx @@ -165,13 +165,13 @@ export default class ObjectField extends Field { - if (!formDataList[key]) formDataList= set(formDataList, `[${key}]`, []) + if (!formDataList[key]) formDataList = set(formDataList, `[${key}]`, []) formDataList = set(formDataList, `[${key}][${formFieldIndex}]`, { status: 'normal' }) return { formDataList: formDataList } }) } else { await this.setState(({ formDataList }) => { - if (!formDataList[key]) formDataList= set(formDataList, `[${key}]`, []) + if (!formDataList[key]) formDataList = set(formDataList, `[${key}]`, []) formDataList = set(formDataList, `[${key}][${formFieldIndex}]`, { status: 'error', message: validation[0].message }) return { formDataList: formDataList } }) @@ -484,7 +484,7 @@ export default class ObjectField extends Field this.props.loadDomain(domain)} containerPath={getChainPath(this.props.containerPath, this.props.config.field, key)} - onReportFields={async(field: string) => await this.handleReportFields(field)} + onReportFields={async (field: string) => await this.handleReportFields(field)} /> ) }) diff --git a/src/components/formFields/tabs/index.tsx b/src/components/formFields/tabs/index.tsx index b8c0c81..6bb7967 100644 --- a/src/components/formFields/tabs/index.tsx +++ b/src/components/formFields/tabs/index.tsx @@ -2,9 +2,8 @@ import { Field, FieldConfig, FieldConfigs, FieldError, FieldProps, IField } from import getALLComponents from '../' import React from 'react' import ConditionHelper from '../../../util/condition' -import { get } from 'lodash' import { set, setValue } from '../../../util/produce' -import { getValue, getBoolean, getChainPath, updateCommonPrefixItem } from '../../../util/value' +import { getValue, getBoolean, getChainPath } from '../../../util/value' import StatementHelper from '../../../util/statement' export type TabsFieldConfig = TabsFieldConfig_Same | TabsFieldConfig_Diff @@ -218,7 +217,7 @@ export default class TabsField extends Field extends Field extends Field extends Field extends Field extends Field await this.props.loadDomain(domain)} containerPath={getChainPath(this.props.containerPath, this.props.config.field, tab.field)} - onReportFields={async(field: string) => await this.handleReportFields(field)} + onReportFields={async (field: string) => await this.handleReportFields(field)} /> ) })} diff --git a/src/steps/common.tsx b/src/steps/common.tsx index c76cbec..ecd4181 100644 --- a/src/steps/common.tsx +++ b/src/steps/common.tsx @@ -40,7 +40,7 @@ export interface StepProps { /** * 页面步骤基类 */ - export default class Step extends React.Component, S> { +export default class Step extends React.Component, S> { static defaultProps = { config: { } diff --git a/src/steps/detail/index.tsx b/src/steps/detail/index.tsx index dcac904..179273f 100644 --- a/src/steps/detail/index.tsx +++ b/src/steps/detail/index.tsx @@ -389,8 +389,7 @@ export default class DetailStep extends Step { const { ready, - detailValue, - detailData + detailValue } = this.state if (ready) { diff --git a/src/steps/filter/index.tsx b/src/steps/filter/index.tsx index a6704ec..bb6e103 100644 --- a/src/steps/filter/index.tsx +++ b/src/steps/filter/index.tsx @@ -7,7 +7,7 @@ import ParamHelper from '../../util/param' import { get } from 'lodash' import { push, splice, sort, set, setValue } from '../../util/produce' import ConditionHelper from '../../util/condition' -import { getValue, getChainPath, updateCommonPrefixItem } from '../../util/value' +import { getValue } from '../../util/value' /** * 表单步骤配置文件格式定义 @@ -380,6 +380,7 @@ 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) { @@ -447,8 +448,8 @@ export default class FilterStep extends Step { {this.renderComponent({ onSubmit: this.props.config?.hiddenSubmit ? undefined : async () => this.handleSubmit(), onReset: this.props.config?.hiddenReset ? undefined : async () => this.handleReset(), - submitText: this.props.config?.submitText?.replace(/(^\s*)|(\s*$)/g, ""), - resetText: this.props.config?.resetText?.replace(/(^\s*)|(\s*$)/g, ""), + submitText: this.props.config?.submitText?.replace(/(^\s*)|(\s*$)/g, ''), + resetText: this.props.config?.resetText?.replace(/(^\s*)|(\s*$)/g, ''), children: fields.map((formFieldConfig, formFieldIndex) => { if (!ConditionHelper(formFieldConfig.condition, { record: formValue, data, step })) { this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, false) diff --git a/src/steps/form/index.tsx b/src/steps/form/index.tsx index cca1d8a..79114bf 100644 --- a/src/steps/form/index.tsx +++ b/src/steps/form/index.tsx @@ -3,9 +3,8 @@ import { Field, FieldConfigs, FieldError } from '../../components/formFields/com import Step, { StepConfig, StepProps } from '../common' import getALLComponents from '../../components/formFields' import { ColumnsConfig, ParamConfig } from '../../interface' -import { getValue, getBoolean, getChainPath, updateCommonPrefixItem } from '../../util/value' +import { getValue, getBoolean } from '../../util/value' import ParamHelper from '../../util/param' -import { get, unset } from 'lodash' import { push, splice, sort, set, setValue } from '../../util/produce' import ConditionHelper, { ConditionConfig } from '../../util/condition' import StatementHelper, { StatementConfig } from '../../util/statement' @@ -184,7 +183,6 @@ export default class FormStep extends Step { // ts对clas getALLComponents = (type: any): typeof Field => getALLComponents[type] OperationHelper = OperationHelper - // 各表单项所使用的UI组件的实例 formFields: Array | null> = [] formFieldsMounted: Array = [] @@ -199,7 +197,7 @@ export default class FormStep extends Step { // ts对clas * 初始化表单的值 * @param props */ - constructor(props: StepProps) { + constructor (props: StepProps) { super(props) this.state = { ready: false, @@ -578,10 +576,9 @@ export default class FormStep extends Step { // ts对clas }) } - render() { + render () { const { data, - step, config: { columns, // layout = 'horizontal', @@ -693,12 +690,12 @@ export default class FormStep extends Step { // ts对clas label: formFieldConfig.label, columns: columns?.enable ? { - type: formFieldConfig.columns?.type || columns?.type || 'span', - value: formFieldConfig.columns?.value || columns?.value || 1, - wrap: formFieldConfig.columns?.wrap || columns?.wrap || false, - gap: columns?.gap || 0, - rowGap: columns?.rowGap || 0 - } + type: formFieldConfig.columns?.type || columns?.type || 'span', + value: formFieldConfig.columns?.value || columns?.value || 1, + wrap: formFieldConfig.columns?.wrap || columns?.wrap || false, + gap: columns?.gap || 0, + rowGap: columns?.rowGap || 0 + } : undefined, status, message: formData[formFieldIndex]?.message || '', @@ -751,4 +748,3 @@ export default class FormStep extends Step { // ts对clas } } } - diff --git a/src/steps/header/index.tsx b/src/steps/header/index.tsx index a7ec2d7..2b8b574 100644 --- a/src/steps/header/index.tsx +++ b/src/steps/header/index.tsx @@ -75,7 +75,6 @@ export interface statisticContentConfig extends basicContentConfig { statistics?: (valueStatisticConfig | enumerationStatisticConfig)[] } - interface basicStatisticConfig { label?: string value?: ParamConfig @@ -337,20 +336,19 @@ export default class HeaderStep extends Step { switch (mainContent.type) { case 'plain': props.mainContent = this.handlePlainContent(mainContent, 'main') - break; + break case 'markdown': props.mainContent = this.handleMarkdownContent(mainContent, 'main') - break; + break case 'html': props.mainContent = this.handleHTMLContent(mainContent, 'main') - break; + break case 'detail': props.mainContent = this.handleDetailContent(mainContent, 'main') - break; + break case 'statistic': props.mainContent = this.handleStatisticContent(mainContent, 'main') - default: - break; + break } } @@ -359,12 +357,12 @@ export default class HeaderStep extends Step { switch (extraContent.type) { case 'statistic': props.extraContent = this.handleStatisticContent(extraContent, 'extra') - break; + break case 'image': props.extraContent = this.handleImageContent(extraContent, 'extra') - break; + break default: - break; + break } } diff --git a/src/util/condition.ts b/src/util/condition.ts index 989eec9..d42ef17 100644 --- a/src/util/condition.ts +++ b/src/util/condition.ts @@ -1,8 +1,7 @@ -// import { set, cloneDeep, template } from "lodash" -import { template } from "lodash" +import { template } from 'lodash' import { set } from '../util/produce' -import { ParamConfig } from "../interface"; -import ParamHelper from "./param"; +import { ParamConfig } from '../interface' +import ParamHelper from './param' export interface ConditionConfig { /** @@ -24,7 +23,7 @@ export interface ConditionConfig { debug?: boolean } -export default function ConditionHelper(condition: ConditionConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; } }, _this?: any): boolean { +export default function ConditionHelper (condition: ConditionConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; } }, _this?: any): boolean { if (condition === undefined || ((condition.statement === undefined || condition.statement === '') && (condition.template === undefined || condition.template === ''))) { return true } else { @@ -87,14 +86,13 @@ export default function ConditionHelper(condition: ConditionConfig | undefined, condition.params.forEach((param) => { if (param.field !== undefined && param.data !== undefined) { if (param.field === '') { - statementParams = ParamHelper(param.data,datas, _this) + statementParams = ParamHelper(param.data, datas, _this) } else { statementParams = set(statementParams, param.field, ParamHelper(param.data, datas, _this)) } } }) } - try { const statement = statementTemplate(statementParams) try { diff --git a/src/util/enumeration.ts b/src/util/enumeration.ts index 0b3c41d..67b0c3d 100644 --- a/src/util/enumeration.ts +++ b/src/util/enumeration.ts @@ -1,5 +1,5 @@ -import { InterfaceConfig } from "./interface"; -import { getValue } from "./value"; +import { InterfaceConfig } from './interface' +import { getValue } from './value' export type EnumerationOptionsConfig = ManualEnumerationOptionsConfig | InterfaceEnumerationOptionsConfig diff --git a/src/util/interface.ts b/src/util/interface.ts index bdad0fc..308a05c 100644 --- a/src/util/interface.ts +++ b/src/util/interface.ts @@ -2,9 +2,9 @@ import { isEqual, template, get, merge } from "lodash" import { set } from '../util/produce' import axios, { AxiosRequestConfig } from 'axios' -import { ParamConfig } from "../interface"; -import ParamHelper from "./param"; -import { getValue } from "./value"; +import { ParamConfig } from '../interface' +import ParamHelper from './param' +import { getValue } from './value' export interface InterfaceConfig { domain?: string @@ -22,12 +22,12 @@ export interface InterfaceConfig { enable?: boolean, field?: string, value?: any, - success?: { type: 'none' } | - { type: 'modal', content?: { type: 'static', content?: string } | - { type: 'field', field?: string }}, - fail?: { type: 'none' } | + success?: { type: 'none' } | + { type: 'modal', content?: { type: 'static', content?: string } | + { type: 'field', field?: string }}, + fail?: { type: 'none' } | { type: 'modal', content?: {type: 'static', content?: string } | - {type: 'field', field?: string }} + {type: 'field', field?: string }} } response?: { @@ -185,12 +185,12 @@ export default class InterfaceHelper { merge(data, option.extra_data.data) } } - + // 缓存判断 if (config.cache && config.cache.global && Object.keys(InterfaceHelper.cache).includes(config.cache.global)) { resolve(InterfaceHelper.cache[config.cache.global]) } else if ( - (!config.cache || !config.cache.disabled) && + (!config.cache || !config.cache.disabled) && isEqual(this._config, config) && isEqual(this._url, url) && isEqual(this._params, params) && @@ -202,7 +202,7 @@ export default class InterfaceHelper { this._url = url this._params = params this._data = data - + const request: AxiosRequestConfig = { url, method: config.method || 'GET', @@ -213,10 +213,10 @@ export default class InterfaceHelper { if (config.method === 'POST') { request.data = data } - + try { const response = await axios(request).then((response) => response.data) - + if (config.condition && config.condition.enable) { if (get(response, config.condition.field || '') === config.condition.value) { if (config.condition.success) { @@ -246,7 +246,7 @@ export default class InterfaceHelper { return } } - + if (config.response) { if (Array.isArray(config.response)) { let content = {} @@ -287,4 +287,4 @@ export default class InterfaceHelper { } }) } -} \ No newline at end of file +} diff --git a/src/util/operation.tsx b/src/util/operation.tsx index 05a63ff..aa3c6c9 100644 --- a/src/util/operation.tsx +++ b/src/util/operation.tsx @@ -1,10 +1,10 @@ -import React from 'react'; -import queryString from 'query-string'; +import React from 'react' +import queryString from 'query-string' // import { set } from "lodash"; import { set } from '../util/produce' -import { ParamConfig } from "../interface"; -import { CCMSConfig, CCMSProps } from "../main"; -import { getParam } from "./value"; +import { ParamConfig } from '../interface' +import { CCMSConfig, CCMSProps } from '../main' +import { getParam } from './value' export type OperationConfig = CCMSOperationConfig @@ -51,7 +51,7 @@ interface CCMSInvisibleOperationConfig extends _CCMSOperationConfig { type CCMSOperationConfig = CCMSPopupOperationConfig | CCMSRedirectOperationConfig | CCMSWindowOperationConfig | CCMSInvisibleOperationConfig interface OperationHelperProps { - config?: OperationConfig, + config?: OperationConfig, datas: { record?: object, data: object[], step: { [field: string]: any; } }, checkPageAuth: (pageID: any) => Promise, loadPageURL: (pageID: any) => Promise, @@ -78,7 +78,7 @@ export default class OperationHelper extends React.Component 您当前使用的UI版本没有实现OpertionHelper组件。 @@ -108,7 +108,7 @@ export default class OperationHelper extends React.Component) { // step--> stepValue switch (config.source) { @@ -57,4 +57,4 @@ export default function ParamHelper (config: ParamConfig, datas: { record?: obje break } return undefined -} \ No newline at end of file +} diff --git a/src/util/produce.tsx b/src/util/produce.tsx index 68afdeb..2d97d10 100644 --- a/src/util/produce.tsx +++ b/src/util/produce.tsx @@ -1,8 +1,7 @@ -import produce, { setAutoFreeze, original } from 'immer' +import produce, { setAutoFreeze } from 'immer' import lodash from 'lodash' import { listItemMove } from '../util/value' -type OperationType = 'set' | 'push' | 'splice' /** * setAutoFreeze @@ -12,18 +11,17 @@ type OperationType = 'set' | 'push' | 'splice' */ setAutoFreeze(false) - /** * 对应loadsh 的set - * @param current - * @param path - * @param value - * @returns + * @param current + * @param path + * @param value + * @returns */ -export function set (current: any, path?: string, value?: any) { - let target = produce(current, (draft: any) => { +export function set(current: any, path?: string, value?: any) { + const target = produce(current, (draft: any) => { if (path) { - if (arguments.length == 2) { // 移除对象路径的属性 参数改动时同步修改这块 + if (arguments.length === 2) { // 移除对象路径的属性 参数改动时同步修改这块 lodash.unset(draft, path) } else { return lodash.set(draft, path, value) @@ -35,14 +33,14 @@ export function set (current: any, path?: string, value?: any) { } /** * current指定路径下的数组添加元素 - * @param current - * @param path - * @param value - * @returns + * @param current + * @param path + * @param value + * @returns */ export const push = (current: any, path: string = '', value?: any) => { const target = produce(current, (draft: any) => { - let list = lodash.get(draft, path) + const list = lodash.get(draft, path) if (!Array.isArray(list)) { // 如果指定路径下不是数组类型 var tempArr = [] tempArr.push(value) @@ -56,13 +54,13 @@ export const push = (current: any, path: string = '', value?: any) => { /** * current指定路径下的数组删除元素 - * @param current - * @param path - * @param index - * @param count - * @returns + * @param current + * @param path + * @param index + * @param count + * @returns */ -export const splice = (current: any, path: string='', index: number, count: number) => { +export const splice = (current: any, path: string = '', index: number, count: number) => { const target = produce(current, (draft: any) => { const list = lodash.get(draft, path, []) list.splice(index, count) @@ -73,12 +71,12 @@ export const splice = (current: any, path: string='', index: number, count: numb /** * current指定路径下数组排序 * @param current - * @param path - * @param index - * @param sortType - * @returns + * @param path + * @param index + * @param sortType + * @returns */ -export const sort = (current: any, path: string='', index: number, sortType: 'up' | 'down') => { +export const sort = (current: any, path: string = '', index: number, sortType: 'up' | 'down') => { const target = produce(current, (draft: any) => { const list = lodash.get(draft, path, []) listItemMove(list, index, sortType) @@ -86,12 +84,11 @@ export const sort = (current: any, path: string='', index: number, sortType: 'up return target } - /** * lodash 递归合并来源对象的自身和继承的可枚举属性到目标对象 * @param a 目标对象 * @param b 来源对象 - * @returns + * @returns */ const merge = (a: any, b: any): any => { return lodash.assignInWith(a, b, (a, b) => { @@ -109,7 +106,7 @@ const merge = (a: any, b: any): any => { } export const setValue = (obj: any, path: string = '', value: any) => { - let target = produce(obj, (draft: any) => { + const target = produce(obj, (draft: any) => { if (path === '') { if (Object.prototype.toString.call(value) === '[object Object]') { draft = merge(draft, value) @@ -126,4 +123,4 @@ export const setValue = (obj: any, path: string = '', value: any) => { } }) return target -} \ No newline at end of file +} diff --git a/src/util/statement.ts b/src/util/statement.ts index 4cbcf42..fd7c9fa 100644 --- a/src/util/statement.ts +++ b/src/util/statement.ts @@ -1,15 +1,14 @@ -// import { set, cloneDeep, template } from "lodash" -import { template } from "lodash" +import { template } from 'lodash' import { set } from '../util/produce' -import { ParamConfig } from "../interface"; -import ParamHelper from "./param"; +import { ParamConfig } from '../interface' +import ParamHelper from './param' export interface StatementConfig { statement: string params: { field: string, data: ParamConfig }[] } -export default function StatementHelper(config: StatementConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; }}, _this?: any): string { +export default function StatementHelper (config: StatementConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; }}, _this?: any): string { if (config === undefined || config.statement === undefined || config.statement === '') { return '' } else { @@ -26,7 +25,7 @@ export default function StatementHelper(config: StatementConfig | undefined, dat } }) } - + try { const statement = statementTemplate(statementParams) return statement @@ -35,4 +34,4 @@ export default function StatementHelper(config: StatementConfig | undefined, dat return '' } } -} \ No newline at end of file +} diff --git a/src/util/value.ts b/src/util/value.ts index 86903cb..c21ce55 100644 --- a/src/util/value.ts +++ b/src/util/value.ts @@ -1,7 +1,6 @@ import queryString from 'query-string' import { ParamConfig } from '../interface' import { set, get, isArray, assignInWith, isObject, isUndefined } from 'lodash' -import { FieldConfig } from '../components/formFields/common' export const getValue = (obj: any, path: string = '', defaultValue: any = undefined) => { if (path === undefined) { @@ -115,31 +114,30 @@ export const listItemMove = (list: any[], currentIndex: number, sortType: 'up' | switch (sortType) { case 'up': currentIndex !== 0 && (list[currentIndex] = list.splice(currentIndex - 1, 1, list[currentIndex])[0]) - break; + break case 'down': currentIndex < list.length - 1 && (list[currentIndex] = list.splice(currentIndex + 1, 1, list[currentIndex])[0]) - break; + break } return list } // 参数转化为链式路径 export const getChainPath = (...arg: any[]) => { - const _fullPath = arg.join('.') + const _fullPath = arg.join('.') const fullPath = _fullPath.replace(/(^\.*)|(\.*$)|(\.){2,}/g, '$3') return fullPath } /** - * * @param source 来源字符串 * @param find 目标字符串 * @returns 返回目标字符串出现在来源字符串中所有索引 */ - function indexes(source: string, find: string) { - var result = [] +function indexes (source: string, find: string) { + const result = [] for (let i = 0; i < source.length; ++i) { - if (source.substring(i, i + find.length) == find) { + if (source.substring(i, i + find.length) === find) { result.push(i) } } @@ -150,52 +148,48 @@ export const getChainPath = (...arg: any[]) => { * 获取一个数组中最长共同前缀 */ export const getLongestCommonPrefix = (arr: string[]) => { - if (arr.length===0 ||arr[0].length===0){return "";} - for (let i=0,len1=arr[0].length;i { - const reg = /[^\.]+(?=\.?)/ +export const updateCommonPrefixItem = (arr: string[], sourceField: string): string[] | boolean => { + const reg = /[^\\.]+(?=\.?)/ const sourceFieldPrefix = sourceField.match(reg)?.[0] const commonPrefixItemS = [sourceField] - for(let i=arr.length - 1;i>=0;i--) { - const arrItem = arr[i] - if (sourceField.includes(arrItem)) { - return false - } - const arrItemPrefix = arrItem.match(reg)?.[0] - if (arrItemPrefix && arrItemPrefix === sourceFieldPrefix) { - arr.splice(i, 1) - commonPrefixItemS.push(arrItem) - } - + for (let i = arr.length - 1; i >= 0; i--) { + const arrItem = arr[i] + if (sourceField.includes(arrItem)) { + return false } - + const arrItemPrefix = arrItem.match(reg)?.[0] + if (arrItemPrefix && arrItemPrefix === sourceFieldPrefix) { + arr.splice(i, 1) + commonPrefixItemS.push(arrItem) + } + } + arr.push(getLongestCommonPrefix(commonPrefixItemS)) return arr } -- Gitee From c86083aea366635d49fb358d942c242310c8ade6 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Thu, 10 Feb 2022 11:51:14 +0800 Subject: [PATCH 30/38] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9paramHelper=20TS?= =?UTF-8?q?=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/common.tsx | 2 +- src/components/formFields/form/index.tsx | 4 ++-- src/components/formFields/group/index.tsx | 2 +- src/components/formFields/tabs/index.tsx | 4 +--- src/util/param.ts | 8 ++++---- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index 01f5d11..a856135 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -140,7 +140,7 @@ export class Field extends React.Component< /** * 获取默认值 */ - async defaultValue (this: any) { + defaultValue : () => Promise = async () => { const { config } = this.props diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index 7bc2146..c67dcbb 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -2,8 +2,8 @@ import React from 'react' import { Field, FieldConfig, FieldConfigs, FieldError, FieldProps, IField } from '../common' import getALLComponents from '../' // import { cloneDeep } from 'lodash' -import { getValue, getBoolean, getChainPath, updateCommonPrefixItem } from '../../../util/value' -import { set, setValue , sort, splice, push } from '../../../util/produce' +import { getValue, getBoolean, getChainPath } from '../../../util/value' +import { set, setValue, sort, splice } from '../../../util/produce' import ConditionHelper from '../../../util/condition' import StatementHelper from '../../../util/statement' diff --git a/src/components/formFields/group/index.tsx b/src/components/formFields/group/index.tsx index 5737063..c74bccc 100644 --- a/src/components/formFields/group/index.tsx +++ b/src/components/formFields/group/index.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { getValue, getBoolean, getChainPath, updateCommonPrefixItem } from '../../../util/value' +import { getValue, getBoolean, getChainPath } from '../../../util/value' import { Field, FieldConfig, FieldError, FieldProps, IField } from '../common' import getALLComponents, { FieldConfigs } from '../' import { IFormItem } from '../../../steps/form' diff --git a/src/components/formFields/tabs/index.tsx b/src/components/formFields/tabs/index.tsx index 6bb7967..e4b8aaf 100644 --- a/src/components/formFields/tabs/index.tsx +++ b/src/components/formFields/tabs/index.tsx @@ -183,7 +183,7 @@ export default class TabsField extends Field { if (!formDataList[index]) formDataList = set(formDataList, `[${index}]`, []) - formDataList= set(formDataList, `[${index}][${formFieldIndex}]`, { status: 'normal' }) + formDataList = set(formDataList, `[${index}][${formFieldIndex}]`, { status: 'normal' }) return { formDataList: formDataList } }) } else { @@ -322,8 +322,6 @@ export default class TabsField extends Field) { // step--> stepValue +export default function ParamHelper (config: ParamConfig, datas: { record?: object, data: object[], step: { [field: string]: unknown } }, _this?: Field) { // 1.3.0新增 step由索引变为formValue switch (config.source) { case 'record': if (datas.record) { @@ -22,7 +22,7 @@ export default function ParamHelper (config: ParamConfig, datas: { record?: obje if (config.field === '') { return datas.step } else { - return get(datas.step, config.field) // return get(step, config.field) + return get(datas.step, config.field) } } break -- Gitee From 80ea69b33eb52ecc0273ef084cabbdfa3436b1a4 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Thu, 10 Feb 2022 15:16:32 +0800 Subject: [PATCH 31/38] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0extraContainerP?= =?UTF-8?q?ath=E5=A4=84=E7=90=86=E8=A1=A8=E5=8D=95=E9=A1=B9=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=9C=A8=E5=AE=B9=E5=99=A8=E7=BB=84=E4=BB=B6=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E4=B8=8A=E5=B1=82=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/form/index.tsx | 8 ++++---- src/components/formFields/group/index.tsx | 8 ++++---- src/components/formFields/importSubform/index.tsx | 6 +++--- src/components/formFields/tabs/index.tsx | 6 +++--- src/util/condition.ts | 2 +- src/util/interface.ts | 2 +- src/util/param.ts | 7 +++++-- src/util/statement.ts | 2 +- 8 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index c67dcbb..c2bf259 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -187,7 +187,7 @@ export default class FormField extends Field { - var list = this.state.formDataList + const list = this.state.formDataList const formDataList = sort(list, '', index, sortType) this.setState({ formDataList: formDataList @@ -491,7 +491,7 @@ export default class FormField extends Field 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 }, this)) { + if (!ConditionHelper(formFieldConfig.condition, { record: itemValue, data: this.props.data, step: this.props.step, extraContainerPath: this.props.config.field }, this)) { if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `${index}`, []) // this.formFieldsMountedList[index][fieldIndex] = false this.formFieldsMountedList = set(this.formFieldsMountedList, `${[index]}.${fieldIndex}`, false) @@ -513,7 +513,7 @@ export default class FormField extends Field { - if (!ConditionHelper(formFieldConfig.condition, { record: value, data: this.props.data, step: this.props.step }, this)) { + if (!ConditionHelper(formFieldConfig.condition, { record: value, data: this.props.data, step: this.props.step, extraContainerPath: this.props.config.field }, this)) { this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, false) return null } @@ -345,7 +345,7 @@ export default class GroupField extends Field { - if (!ConditionHelper(formFieldConfig.condition, { record: value, data, step }, this)) { + if (!ConditionHelper(formFieldConfig.condition, { record: value, data, step, extraContainerPath: this.props.config.field }, this)) { this.formFieldsMounted = set(this.formFieldsMounted, `[${formFieldIndex}]`, false) return null } @@ -414,7 +414,7 @@ export default class ImportSubformField extends Field extends Field extends Field { - if (!ConditionHelper(formFieldConfig.condition, { record: getValue(value, tab.field), data: this.props.data, step: this.props.step }, this)) { + if (!ConditionHelper(formFieldConfig.condition, { record: getValue(value, tab.field), data: this.props.data, step: this.props.step, extraContainerPath: this.props.config.field }, this)) { if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}]`, []) this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}][${formFieldIndex}]`, false) return null @@ -413,7 +413,7 @@ export default class TabsField extends Field Promise extra_data?: { params?: any, data?: any } diff --git a/src/util/param.ts b/src/util/param.ts index 03ab1e1..1d041c2 100644 --- a/src/util/param.ts +++ b/src/util/param.ts @@ -4,11 +4,14 @@ import { ParamConfig } from '../interface' import { getChainPath } from '../util/value' import { Field } from '../components/formFields/common' -export default function ParamHelper (config: ParamConfig, datas: { record?: object, data: object[], step: { [field: string]: unknown } }, _this?: Field) { // 1.3.0新增 step由索引变为formValue +export default function ParamHelper (config: ParamConfig, datas: { record?: object, data: object[], step: { [field: string]: unknown }, extraContainerPath?: string }, _this?: Field) { // 1.3.0新增 step由索引变为formValue switch (config.source) { case 'record': if (datas.record) { - _this && _this.handleReportFields && _this.handleReportFields(getChainPath(_this.props.containerPath, config.field)) + if (_this) { + const fullPath = datas.extraContainerPath ? getChainPath(_this.props.containerPath, datas.extraContainerPath, config.field) : getChainPath(_this.props.containerPath, config.field) + _this.handleReportFields && _this.handleReportFields(getChainPath(fullPath)) + } if (config.field === '') { return datas.record } else { diff --git a/src/util/statement.ts b/src/util/statement.ts index fd7c9fa..6ee50ac 100644 --- a/src/util/statement.ts +++ b/src/util/statement.ts @@ -8,7 +8,7 @@ export interface StatementConfig { params: { field: string, data: ParamConfig }[] } -export default function StatementHelper (config: StatementConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; }}, _this?: any): string { +export default function StatementHelper (config: StatementConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; }, extraContainerPath?: string }, _this?: any): string { if (config === undefined || config.statement === undefined || config.statement === '') { return '' } else { -- Gitee From 740130bae12c2be8eed1eaf791e42cc74706ab99 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Thu, 10 Feb 2022 15:52:57 +0800 Subject: [PATCH 32/38] =?UTF-8?q?fix:=20subform=E3=80=81group=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E9=A1=B9record=E5=8F=96=E5=80=BCvalue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/importSubform/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx index 3fdb533..0217651 100644 --- a/src/components/formFields/importSubform/index.tsx +++ b/src/components/formFields/importSubform/index.tsx @@ -431,7 +431,7 @@ export default class ImportSubformField extends Field Date: Thu, 10 Feb 2022 16:40:10 +0800 Subject: [PATCH 33/38] =?UTF-8?q?fix:=20=E5=AE=8C=E5=96=84tab=E5=92=8Cform?= =?UTF-8?q?=E7=9A=84extraContainerPath?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/common.tsx | 3 +-- src/components/formFields/form/index.tsx | 6 +++--- src/components/formFields/tabs/index.tsx | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/components/formFields/common.tsx b/src/components/formFields/common.tsx index a856135..42b527c 100644 --- a/src/components/formFields/common.tsx +++ b/src/components/formFields/common.tsx @@ -140,7 +140,7 @@ export class Field extends React.Component< /** * 获取默认值 */ - defaultValue : () => Promise = async () => { + defaultValue : () => Promise = async () => { const { config } = this.props @@ -178,7 +178,6 @@ export class Field extends React.Component< * @param field */ handleReportFields: (field: string) => void = async (field) => { - // if (this.dependentFields.includes(field)) return const update: string[] | boolean = updateCommonPrefixItem(this.dependentFields, field) if (typeof update === 'boolean') return this.dependentFields = update diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index c2bf259..ec0a425 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -187,7 +187,7 @@ export default class FormField extends Field 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, extraContainerPath: this.props.config.field }, this)) { + if (!ConditionHelper(formFieldConfig.condition, { record: itemValue, data: this.props.data, step: this.props.step, extraContainerPath: getChainPath(this.props.config.field, index) }, this)) { if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `${index}`, []) // this.formFieldsMountedList[index][fieldIndex] = false this.formFieldsMountedList = set(this.formFieldsMountedList, `${[index]}.${fieldIndex}`, false) @@ -513,7 +513,7 @@ export default class FormField extends Field extends Field extends Field { - if (!ConditionHelper(formFieldConfig.condition, { record: getValue(value, tab.field), data: this.props.data, step: this.props.step, extraContainerPath: this.props.config.field }, this)) { + if (!ConditionHelper(formFieldConfig.condition, { record: getValue(value, tab.field), data: this.props.data, step: this.props.step, extraContainerPath: getChainPath(this.props.config.field, tab.field) }, this)) { if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}]`, []) this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}][${formFieldIndex}]`, false) return null @@ -413,7 +413,7 @@ export default class TabsField extends Field Date: Thu, 10 Feb 2022 17:48:45 +0800 Subject: [PATCH 34/38] =?UTF-8?q?refactor:=20=E6=8F=90=E5=8F=96=E5=87=BAha?= =?UTF-8?q?ndleValueCallback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/form/index.tsx | 221 ++++++-------- src/components/formFields/group/index.tsx | 84 ++---- .../formFields/importSubform/index.tsx | 82 ++---- src/components/formFields/tabs/index.tsx | 278 ++++++++---------- 4 files changed, 254 insertions(+), 411 deletions(-) diff --git a/src/components/formFields/form/index.tsx b/src/components/formFields/form/index.tsx index ec0a425..dbc4b0b 100644 --- a/src/components/formFields/form/index.tsx +++ b/src/components/formFields/form/index.tsx @@ -168,7 +168,7 @@ export default class FormField extends Field { + let formDataList = this.state.formDataList + if (validation === true) { + formDataList = set(formDataList, `[${index}][${formFieldIndex}]`, { status: 'normal' }) + } else { + formDataList = set(formDataList, `[${index}][${formFieldIndex}]`, { status: 'error', message: validation[0].message }) + } + + 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) { @@ -329,16 +345,7 @@ export default class FormField extends Field { return - {this.renderItemComponent({ - index, - isLastIndex: value.length - 1 === index, - title: primaryField !== undefined ? getValue(itemValue, primaryField, '').toString() : index.toString(), - removeText: removeText === undefined - ? `删除 ${label}` - : removeText, - 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, extraContainerPath: getChainPath(this.props.config.field, index) }, this)) { - if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `${index}`, []) - // this.formFieldsMountedList[index][fieldIndex] = false - this.formFieldsMountedList = set(this.formFieldsMountedList, `${[index]}.${fieldIndex}`, false) - return null - } - const FormField = this.getALLComponents(formFieldConfig.type) || Field - - 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, - status, - message: ((this.state.formDataList[index] || [])[fieldIndex] || {}).message || '', - extra: StatementHelper(formFieldConfig.extra, { record: itemValue, data: this.props.data, step: this.props.step, extraContainerPath: getChainPath(this.props.config.field, index) }, this), - required: getBoolean(formFieldConfig.required), - layout: formLayout, - fieldType: formFieldConfig.type, - children: ( - | null) => { - if (fieldRef) { - if (!this.formFieldsList[index]) this.formFieldsList = set(this.formFieldsList, `[${index}]`, []) - // this.formFieldsList[index][fieldIndex] = fieldRef - this.formFieldsList = set(this.formFieldsList, `[${index}][${fieldIndex}]`, fieldRef) - this.handleMount(index, fieldIndex) - } - }} - form={this.props.form} - formLayout={formLayout} - value={getValue(value[index], formFieldConfig.field)} - record={value[index]} - step={this.props.step} - data={data} - // step={step} - config={formFieldConfig} - onChange={(value: any) => this.handleChange(index, fieldIndex, value)} - 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)} - 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)} - containerPath={getChainPath(this.props.containerPath, this.props.config.field, index)} - onReportFields={async (field: string) => await this.handleReportFields(field)} - /> - ) - }) - } -
- ) - }) + {this.renderItemComponent({ + index, + isLastIndex: value.length - 1 === index, + title: primaryField !== undefined ? getValue(itemValue, primaryField, '').toString() : index.toString(), + removeText: removeText === undefined + ? `删除 ${label}` + : removeText, + 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, extraContainerPath: getChainPath(this.props.config.field, index) }, this)) { + if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `${index}`, []) + // this.formFieldsMountedList[index][fieldIndex] = false + this.formFieldsMountedList = set(this.formFieldsMountedList, `${[index]}.${fieldIndex}`, false) + return null + } + const FormField = this.getALLComponents(formFieldConfig.type) || Field + + 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, + status, + message: ((this.state.formDataList[index] || [])[fieldIndex] || {}).message || '', + extra: StatementHelper(formFieldConfig.extra, { record: itemValue, data: this.props.data, step: this.props.step, extraContainerPath: getChainPath(this.props.config.field, index) }, this), + required: getBoolean(formFieldConfig.required), + layout: formLayout, + fieldType: formFieldConfig.type, + children: ( + | null) => { + if (fieldRef) { + if (!this.formFieldsList[index]) this.formFieldsList = set(this.formFieldsList, `[${index}]`, []) + // this.formFieldsList[index][fieldIndex] = fieldRef + this.formFieldsList = set(this.formFieldsList, `[${index}][${fieldIndex}]`, fieldRef) + this.handleMount(index, fieldIndex) + } + }} + form={this.props.form} + formLayout={formLayout} + value={getValue(value[index], formFieldConfig.field)} + record={value[index]} + step={this.props.step} + data={data} + // step={step} + config={formFieldConfig} + onChange={(value: any) => this.handleChange(index, fieldIndex, value)} + 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)} + 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)} + containerPath={getChainPath(this.props.containerPath, this.props.config.field, index)} + onReportFields={async (field: string) => await this.handleReportFields(field)} + /> + ) + }) + } +
+ ) }) - } -
+ }) + } +
} ) : [] diff --git a/src/components/formFields/group/index.tsx b/src/components/formFields/group/index.tsx index 3d2cc03..69ff1bf 100644 --- a/src/components/formFields/group/index.tsx +++ b/src/components/formFields/group/index.tsx @@ -136,17 +136,7 @@ export default class GroupField extends Field { - formData = set(formData, `[${formFieldIndex}]`, { status: 'normal', name: formFieldConfig.label }) - return { formData: formData } - }) - } else { - await this.setState(({ formData }) => { - formData = set(formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message, name: formFieldConfig.label }) - return { formData: formData } - }) - } + this.handleValueCallback(formFieldIndex, validation) } await formField.didMount() } @@ -182,21 +172,28 @@ export default class GroupField extends Field { + let formData = this.state.formData + if (validation === true) { + formData = set(formData, `[${formFieldIndex}]`, { status: 'normal' }) + } else { + formData = set(formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message }) + } + + await this.setState({ + formData + }) + } + 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) - let formData = this.state.formData - if (validation === true) { - formData = set(formData, `[${formFieldIndex}]`, { status: 'normal' }) - } else { - formData = set(formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message }) - } - - this.setState({ - formData - }) + this.handleValueCallback(formFieldIndex, validation) } } @@ -205,16 +202,7 @@ export default class GroupField extends Field { - formData = set(formData, `[${formFieldIndex}]`, { status: 'normal' }) - return { formData: formData } - }) - } else { - await this.setState(({ formData }) => { - formData = set(formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message }) - return { formData: formData } - }) - } + this.handleValueCallback(formFieldIndex, validation) } await formField.didMount() } @@ -209,6 +199,21 @@ export default class ImportSubformField extends Field { + let formData = this.state.formData + if (validation === true) { + formData = set(formData, `[${formFieldIndex}]`, { status: 'normal' }) + } else { + formData = set(formData, `[${formFieldIndex}]`, { status: 'error', message: validation[0].message }) + } + await this.setState({ + formData + }) + } + handleValueSet = async (formFieldIndex: number, path: string, value: any, validation: true | FieldError[]) => { const formFieldConfig = (this.state.fields || [])[formFieldIndex] if (formFieldConfig) { @@ -216,16 +221,7 @@ export default class ImportSubformField extends Field extends Field { - if (!formDataList[index]) formDataList = set(formDataList, `[${index}]`, []) - formDataList = set(formDataList, `[${index}][${formFieldIndex}]`, { status: 'normal' }) - return { formDataList: formDataList } - }) - } else { - await this.setState(({ formDataList }) => { - if (!formDataList[index]) formDataList = set(formDataList, `[${index}]`, []) - formDataList = set(formDataList, `[${index}][${formFieldIndex}]`, { status: 'error', message: validation[0].message }) - return { formDataList: formDataList } - }) - } + this.handleValueCallback(index, formFieldIndex, validation) } await formField.didMount() } @@ -202,6 +190,23 @@ export default class TabsField extends Field { } + /** + * 处理set、unset、append、splice、sort后的操作 + */ + handleValueCallback = async (index: number, formFieldIndex: number, validation: true | FieldError[]) => { + let formDataList = this.state.formDataList + // if (!formDataList[index]) formDataList = set(formDataList, `[${index}]`, []) + if (validation === true) { + formDataList = set(formDataList, `[${index}][${formFieldIndex}]`, { status: 'normal' }) + } else { + formDataList = set(formDataList, `[${index}][${formFieldIndex}]`, { status: 'error', message: validation[0].message }) + } + + this.setState({ + formDataList + }) + } + handleValueSet = async (index: number, formFieldIndex: number, path: string, value: any, validation: true | FieldError[]) => { const tab = (this.props.config.tabs || [])[index] @@ -212,17 +217,7 @@ export default class TabsField extends Field extends Field extends Field extends Field extends Field extends Field { - return + 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 { - value = {}, - config: { - label - } + value = {} } = this.props return ( @@ -372,86 +324,86 @@ export default class TabsField extends Field { 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: getValue(value, tab.field), data: this.props.data, step: this.props.step, extraContainerPath: getChainPath(this.props.config.field, tab.field) }, this)) { - if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}]`, []) - this.formFieldsMountedList = set(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) || Field - - 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), - extra: StatementHelper(formFieldConfig.extra, { record: getValue(value, tab.field), data: this.props.data, step: this.props.step, extraContainerPath: getChainPath(this.props.config.field, tab.field) }, this), - layout: this.props.formLayout, - fieldType: formFieldConfig.type, - children: ( - | null) => { - if (!this.formFieldsList[index]) this.formFieldsList = set(this.formFieldsList, `[${index}]`, []) - this.formFieldsList = set(this.formFieldsList, `[${index}][${formFieldIndex}]`, formField) - this.handleMount(index, formFieldIndex) - }} - form={this.props.form} - formLayout={this.props.formLayout} - value={getValue(value, getChainPath(tab.field, formFieldConfig.field))} - record={getValue(value, tab.field)} - data={this.props.data} - step={this.props.step} - config={formFieldConfig} - onChange={(value: any) => this.handleChange(index, formFieldIndex, value)} - 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)} - 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)} - containerPath={getChainPath(this.props.containerPath, this.props.config.field, tab.field)} - onReportFields={async (field: string) => await this.handleReportFields(field)} - /> - ) - })} -
- ) - } else { - return - } - }) - })} - + + {this.renderItemComponent({ + key: index.toString(), + label: tab.label, + children: fields.map((formFieldConfig, formFieldIndex) => { + if (!ConditionHelper(formFieldConfig.condition, { record: getValue(value, tab.field), data: this.props.data, step: this.props.step, extraContainerPath: getChainPath(this.props.config.field, tab.field) }, this)) { + if (!this.formFieldsMountedList[index]) this.formFieldsMountedList = set(this.formFieldsMountedList, `[${index}]`, []) + this.formFieldsMountedList = set(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) || Field + + 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), + extra: StatementHelper(formFieldConfig.extra, { record: getValue(value, tab.field), data: this.props.data, step: this.props.step, extraContainerPath: getChainPath(this.props.config.field, tab.field) }, this), + layout: this.props.formLayout, + fieldType: formFieldConfig.type, + children: ( + | null) => { + if (!this.formFieldsList[index]) this.formFieldsList = set(this.formFieldsList, `[${index}]`, []) + this.formFieldsList = set(this.formFieldsList, `[${index}][${formFieldIndex}]`, formField) + this.handleMount(index, formFieldIndex) + }} + form={this.props.form} + formLayout={this.props.formLayout} + value={getValue(value, getChainPath(tab.field, formFieldConfig.field))} + record={getValue(value, tab.field)} + data={this.props.data} + step={this.props.step} + config={formFieldConfig} + onChange={(value: any) => this.handleChange(index, formFieldIndex, value)} + 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)} + 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)} + containerPath={getChainPath(this.props.containerPath, this.props.config.field, tab.field)} + onReportFields={async (field: string) => await this.handleReportFields(field)} + /> + ) + })} +
+ ) + } else { + return + } + }) + })} + ) }) : [] -- Gitee From a796efa05e854eddada9bd50314329941c0bf147 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Thu, 10 Feb 2022 18:24:13 +0800 Subject: [PATCH 35/38] =?UTF-8?q?style:=20any=E4=BB=A3=E7=A0=81=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/any/index.tsx | 121 +++++++++--------- .../formFields/importSubform/index.tsx | 1 - 2 files changed, 62 insertions(+), 60 deletions(-) diff --git a/src/components/formFields/any/index.tsx b/src/components/formFields/any/index.tsx index 566caf9..996a04c 100644 --- a/src/components/formFields/any/index.tsx +++ b/src/components/formFields/any/index.tsx @@ -30,8 +30,7 @@ export default class AnyField extends Field { const { - value, - onChange + value } = this.props if (type === 'null') { this.props.onValueSet('', null, true) @@ -81,63 +80,67 @@ export default class AnyField extends Field this.handleChangeType(type) }), - valueContent: type === 'string' ? {}} - form={this.props.form} - formLayout={'horizontal'} - value={typeof value === 'string' ? value : ''} - record={record} - data={_.cloneDeep(data)} - step={step} - config={{ type: 'text', field: '', label: '' }} - onChange={async (value: string) => { await onChange(value) }} - onValueSet={this.props.onValueSet} - onValueUnset={this.props.onValueUnset} - onValueListAppend={this.props.onValueListAppend} - onValueListSplice={this.props.onValueListSplice} - onValueListSort={this.props.onValueListSort} - baseRoute={this.props.baseRoute} - loadDomain={this.props.loadDomain} - containerPath={getChainPath(this.props.containerPath, '')} - /> : ( - type === 'number' ? {}} - form={this.props.form} - formLayout={'horizontal'} - record={record} - value={typeof value === 'number' ? value : ''} - data={_.cloneDeep(data)} - step={step} - config={{ type: 'number', field: '', label: '' }} - onChange={async (value) => { await onChange(Number(value)) }} - onValueSet={async (path, value, validation) => await this.props.onValueSet(path, Number(value), validation)} - onValueUnset={this.props.onValueUnset} - onValueListAppend={this.props.onValueListAppend} - onValueListSplice={this.props.onValueListSplice} - onValueListSort={this.props.onValueListSort} - baseRoute={this.props.baseRoute} - loadDomain={this.props.loadDomain} - containerPath={getChainPath(this.props.containerPath, '')} - /> : {}} - form={this.props.form} - formLayout={'horizontal'} - record={record} - value={typeof value === 'boolean' ? value : false} - data={_.cloneDeep(data)} - step={step} - config={{ type: 'switch', field: '', label: '' }} - onChange={async (value) => { await onChange(Boolean(value)) }} - onValueSet={this.props.onValueSet} - onValueUnset={this.props.onValueUnset} - onValueListAppend={this.props.onValueListAppend} - onValueListSplice={this.props.onValueListSplice} - onValueListSort={this.props.onValueListSort} - baseRoute={this.props.baseRoute} - loadDomain={this.props.loadDomain} - containerPath={getChainPath(this.props.containerPath, '')} - /> - ) + valueContent: + type === 'string' + ? {}} + form={this.props.form} + formLayout={'horizontal'} + value={typeof value === 'string' ? value : ''} + record={record} + data={_.cloneDeep(data)} + step={step} + config={{ type: 'text', field: '', label: '' }} + onChange={async (value: string) => { await onChange(value) }} + onValueSet={this.props.onValueSet} + onValueUnset={this.props.onValueUnset} + onValueListAppend={this.props.onValueListAppend} + onValueListSplice={this.props.onValueListSplice} + onValueListSort={this.props.onValueListSort} + baseRoute={this.props.baseRoute} + loadDomain={this.props.loadDomain} + containerPath={getChainPath(this.props.containerPath, '')} + /> + : ( + type === 'number' + ? {}} + form={this.props.form} + formLayout={'horizontal'} + record={record} + value={typeof value === 'number' ? value : ''} + data={_.cloneDeep(data)} + step={step} + config={{ type: 'number', field: '', label: '' }} + onChange={async (value) => { await onChange(Number(value)) }} + onValueSet={async (path, value, validation) => await this.props.onValueSet(path, Number(value), validation)} + onValueUnset={this.props.onValueUnset} + onValueListAppend={this.props.onValueListAppend} + onValueListSplice={this.props.onValueListSplice} + onValueListSort={this.props.onValueListSort} + baseRoute={this.props.baseRoute} + loadDomain={this.props.loadDomain} + containerPath={getChainPath(this.props.containerPath, '')} + /> + : {}} + form={this.props.form} + formLayout={'horizontal'} + record={record} + value={typeof value === 'boolean' ? value : false} + data={_.cloneDeep(data)} + step={step} + config={{ type: 'switch', field: '', label: '' }} + onChange={async (value) => { await onChange(Boolean(value)) }} + onValueSet={this.props.onValueSet} + onValueUnset={this.props.onValueUnset} + onValueListAppend={this.props.onValueListAppend} + onValueListSplice={this.props.onValueListSplice} + onValueListSort={this.props.onValueListSort} + baseRoute={this.props.baseRoute} + loadDomain={this.props.loadDomain} + containerPath={getChainPath(this.props.containerPath, '')} + />) })}
) diff --git a/src/components/formFields/importSubform/index.tsx b/src/components/formFields/importSubform/index.tsx index 0c846ff..d60bd69 100644 --- a/src/components/formFields/importSubform/index.tsx +++ b/src/components/formFields/importSubform/index.tsx @@ -291,7 +291,6 @@ export default class ImportSubformField extends Field Date: Fri, 11 Feb 2022 23:28:25 +0800 Subject: [PATCH 36/38] =?UTF-8?q?fix:=20=E5=AE=8C=E5=96=84=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E5=89=8D=E7=BC=80=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/value.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/util/value.ts b/src/util/value.ts index c21ce55..c7dd643 100644 --- a/src/util/value.ts +++ b/src/util/value.ts @@ -146,23 +146,24 @@ function indexes (source: string, find: string) { /** * 获取一个数组中最长共同前缀 + *@param arr 入参数组的元素是二级及以上路径,为节省性能,该方法没有适配处理多个一级路径的共同前缀,一级路径没有共同前缀 + * + * eg: 根据项目使用场景,如['81.mode', '81.me.1', '81.my.1', '81.m']的共同前缀为81,不可以是81.m */ export const getLongestCommonPrefix = (arr: string[]) => { if (arr.length === 0 || arr[0].length === 0) { return '' } for (let i = 0, len1 = arr[0].length; i < len1; i++) { const c = arr[0].charAt(i) for (let j = 1, len2 = arr.length; j < len2; j++) { - if (i === arr[j].length || arr[j].charAt(i) !== c) { + if (i === arr[j].length || arr[j].charAt(i) !== c || (i === len1 - 1 && arr[j].length > len1 && arr[j].charAt(len1) !== '.')) { const _indexes = indexes(arr[0], '.') const res = arr[0].substring(0, i).replace(/\.+$/, '') // 去掉尾部'.' - if (_indexes.length) { - for (let n = 0; n < _indexes.length; n++) { - if (res.length === _indexes[n]) { - return res - } + for (let n = 0; n < _indexes.length; n++) { + if (res.length === _indexes[n]) { + return res } - return res.replace(/\.+[^\\.]+$/, '') } + return res.replace(/\.+[^\\.]+$/, '') } } } @@ -173,6 +174,8 @@ export const getLongestCommonPrefix = (arr: string[]) => { * @param arr 目标数组 * @param sourceField 来源字段 * @returns 与来源字段比较共同前缀后更新的数组 | 是否更新并上报 + * + * eg: ['a.0', 'b']不会插入'a.0.c',会插入'a'替换'a.0',原数组改变为['a', 'b'] */ export const updateCommonPrefixItem = (arr: string[], sourceField: string): string[] | boolean => { const reg = /[^\\.]+(?=\.?)/ @@ -180,7 +183,9 @@ export const updateCommonPrefixItem = (arr: string[], sourceField: string): stri const commonPrefixItemS = [sourceField] for (let i = arr.length - 1; i >= 0; i--) { const arrItem = arr[i] - if (sourceField.includes(arrItem)) { + // const sourceFieldLevels = indexes(sourceField, '.').length + // const arrItemLevels = indexes(arrItem, '.').length + if (sourceField === arrItem) { return false } const arrItemPrefix = arrItem.match(reg)?.[0] -- Gitee From e62ca5f404bbdc4188c10eabce8145e5b81aa9a0 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Tue, 22 Feb 2022 00:02:44 +0800 Subject: [PATCH 37/38] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9this=E7=9A=84ts?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/condition.ts | 3 ++- src/util/interface.ts | 3 ++- src/util/statement.ts | 3 ++- src/util/value.ts | 2 -- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/util/condition.ts b/src/util/condition.ts index cf48fbd..6a2331b 100644 --- a/src/util/condition.ts +++ b/src/util/condition.ts @@ -2,6 +2,7 @@ import { template } from 'lodash' import { set } from '../util/produce' import { ParamConfig } from '../interface' import ParamHelper from './param' +import { Field } from '../components/formFields/common' export interface ConditionConfig { /** @@ -23,7 +24,7 @@ export interface ConditionConfig { debug?: boolean } -export default function ConditionHelper (condition: ConditionConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; }, extraContainerPath?: string }, _this?: any): boolean { +export default function ConditionHelper (condition: ConditionConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; }, extraContainerPath?: string }, _this?: Field): boolean { if (condition === undefined || ((condition.statement === undefined || condition.statement === '') && (condition.template === undefined || condition.template === ''))) { return true } else { diff --git a/src/util/interface.ts b/src/util/interface.ts index 0971d88..3b0c9fd 100644 --- a/src/util/interface.ts +++ b/src/util/interface.ts @@ -5,6 +5,7 @@ import axios, { AxiosRequestConfig } from 'axios' import { ParamConfig } from '../interface' import ParamHelper from './param' import { getValue } from './value' +import { Field } from '../components/formFields/common' export interface InterfaceConfig { domain?: string @@ -103,7 +104,7 @@ export default class InterfaceHelper { loadDomain?: (domain: string) => Promise extra_data?: { params?: any, data?: any } }, - _this?: any // 位置要调整 + _this?: Field ): Promise { return new Promise(async (resolve, reject) => { // 处理URL diff --git a/src/util/statement.ts b/src/util/statement.ts index 6ee50ac..9329a8a 100644 --- a/src/util/statement.ts +++ b/src/util/statement.ts @@ -2,13 +2,14 @@ import { template } from 'lodash' import { set } from '../util/produce' import { ParamConfig } from '../interface' import ParamHelper from './param' +import { Field } from '../components/formFields/common' export interface StatementConfig { statement: string params: { field: string, data: ParamConfig }[] } -export default function StatementHelper (config: StatementConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; }, extraContainerPath?: string }, _this?: any): string { +export default function StatementHelper (config: StatementConfig | undefined, datas: { record?: object, data: object[], step: { [field: string]: any; }, extraContainerPath?: string }, _this?: Field): string { if (config === undefined || config.statement === undefined || config.statement === '') { return '' } else { diff --git a/src/util/value.ts b/src/util/value.ts index c7dd643..a94db1d 100644 --- a/src/util/value.ts +++ b/src/util/value.ts @@ -183,8 +183,6 @@ export const updateCommonPrefixItem = (arr: string[], sourceField: string): stri const commonPrefixItemS = [sourceField] for (let i = arr.length - 1; i >= 0; i--) { const arrItem = arr[i] - // const sourceFieldLevels = indexes(sourceField, '.').length - // const arrItemLevels = indexes(arrItem, '.').length if (sourceField === arrItem) { return false } -- Gitee From 35227bf0588ec0939f1e017c4b968332063aec32 Mon Sep 17 00:00:00 2001 From: cuiwenlong7 Date: Tue, 15 Mar 2022 17:31:24 +0800 Subject: [PATCH 38/38] =?UTF-8?q?fix:=20Display=E4=BC=A0=E5=85=A5this?= =?UTF-8?q?=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/formFields/select/common.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/formFields/select/common.tsx b/src/components/formFields/select/common.tsx index 2b8cf78..2141c97 100644 --- a/src/components/formFields/select/common.tsx +++ b/src/components/formFields/select/common.tsx @@ -66,7 +66,7 @@ export class SelectDisplay extends Display { if (config) { - EnumerationHelper.options(config, (config, source) => this.interfaceHelper.request(config, source, { record: this.props.record, data: this.props.data, step: this.props.step }, { loadDomain: this.props.loadDomain }, this)).then((options) => { + EnumerationHelper.options(config, (config, source) => this.interfaceHelper.request(config, source, { record: this.props.record, data: this.props.data, step: this.props.step }, { loadDomain: this.props.loadDomain })).then((options) => { if (JSON.stringify(this.state.options) !== JSON.stringify(options)) { this.setState({ options -- Gitee