feat: 表单回调函数支持直接传入函数,增加一个扩展参数可以直接操控全表单字段的状态

This commit is contained in:
gaoyunqi
2024-02-18 16:57:55 +08:00
parent b61380ee1d
commit 53b5209c30
2 changed files with 666 additions and 905 deletions

View File

@ -1,29 +1,11 @@
<template> <template>
<div> <div>
<Form <Form ref="formRef" :label-col="getProps?.labelCol" :labelAlign="getProps?.labelAlign" :layout="getProps?.layout" :model="formModel" :wrapper-col="getProps?.wrapperCol" @keypress.enter="handleEnterPress">
ref="formRef"
:model="formModel"
:layout="getProps?.layout"
:label-col="getProps?.labelCol"
:wrapper-col="getProps?.wrapperCol"
:labelAlign="getProps?.labelAlign"
@keypress.enter="handleEnterPress"
>
<Row v-bind="getRow"> <Row v-bind="getRow">
<template v-for="schema in getSchemas" :key="schema.field"> <template v-for="schema in getSchemas" :key="schema.field">
<Col <Col v-if="getIfShow(schema, formModel[schema.field])" v-show="getIsShow(schema, formModel[schema.field])" :span="schema.colProps?.span">
:span="schema.colProps?.span"
v-show="getIsShow(schema, formModel[schema.field])"
v-if="getIfShow(schema, formModel[schema.field])"
>
<template v-if="showComponent(schema)"> <template v-if="showComponent(schema)">
<SimpleFormItem <SimpleFormItem v-model:value="formModel[schema.field]" :form-api="formApi" :isWorkFlow="isWorkFlow" :refreshFieldObj="refreshFieldObj" :schema="schema" />
:refreshFieldObj="refreshFieldObj"
:schema="schema"
:form-api="formApi"
:isWorkFlow="isWorkFlow"
v-model:value="formModel[schema.field]"
/>
</template> </template>
</Col> </Col>
</template> </template>
@ -32,10 +14,10 @@
<div :style="{ textAlign: getProps.buttonLocation }"> <div :style="{ textAlign: getProps.buttonLocation }">
<slot name="buttonBefore"></slot> <slot name="buttonBefore"></slot>
<a-button type="primary" v-if="getProps.showSubmitButton" @click="handleSubmit"> <a-button v-if="getProps.showSubmitButton" type="primary" @click="handleSubmit">
{{ t('提交') }} {{ t('提交') }}
</a-button> </a-button>
<a-button style="margin-left: 10px" v-if="getProps.showResetButton" @click="handleReset"> <a-button v-if="getProps.showResetButton" style="margin-left: 10px" @click="handleReset">
{{ t('重置') }} {{ t('重置') }}
</a-button> </a-button>
<slot name="buttonAfter"></slot> <slot name="buttonAfter"></slot>
@ -45,49 +27,12 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { Form, FormInstance, Row, Col, Modal, message } from 'ant-design-vue'; import { Form, FormInstance, Row, Col, Modal, message } from 'ant-design-vue';
import { import { cloneDeep, isArray, isBoolean, isFunction, isObject, isString, uniqBy, isNil } from 'lodash-es';
cloneDeep, import { computed, reactive, ref, provide, unref, nextTick, toRaw, createVNode, inject, onMounted } from 'vue';
isArray, import { CardComponentProps, FormActionType, FormProps, FormSchema, GridComponentProps, TabComponentProps, regTestProps, requestProps } from '../../Form/src/types/form';
isBoolean,
isFunction,
isObject,
isString,
uniqBy,
isNil,
} from 'lodash-es';
import {
computed,
reactive,
ref,
provide,
unref,
nextTick,
toRaw,
createVNode,
inject,
onMounted,
} from 'vue';
import {
CardComponentProps,
FormActionType,
FormProps,
FormSchema,
GridComponentProps,
TabComponentProps,
regTestProps,
requestProps,
} from '../../Form/src/types/form';
import SimpleFormItem from './components/SimpleFormItem.vue'; import SimpleFormItem from './components/SimpleFormItem.vue';
import { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interface'; import { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interface';
import { import { arrayValueComponents, defaultValueComponents, staticDataComponents, noFieldComponent, noDefaultValueComponents, noShowWorkFlowComponents, noShowGenerateComponents } from '../../Form/src/helper';
arrayValueComponents,
defaultValueComponents,
staticDataComponents,
noFieldComponent,
noDefaultValueComponents,
noShowWorkFlowComponents,
noShowGenerateComponents,
} from '../../Form/src/helper';
import { deepMerge } from '/@/utils'; import { deepMerge } from '/@/utils';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'; import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { ModalFuncProps } from 'ant-design-vue/lib/modal/Modal'; import type { ModalFuncProps } from 'ant-design-vue/lib/modal/Modal';
@ -96,6 +41,7 @@
import { needDicDefaultValue } from '../../Designer/src/types'; import { needDicDefaultValue } from '../../Designer/src/types';
import { useMessage } from '/@/hooks/web/useMessage'; import { useMessage } from '/@/hooks/web/useMessage';
import { camelCaseString } from '/@/utils/event/design'; import { camelCaseString } from '/@/utils/event/design';
const { t } = useI18n(); const { t } = useI18n();
const { notification } = useMessage(); const { notification } = useMessage();
const formRef = ref<FormInstance>(); const formRef = ref<FormInstance>();
@ -109,23 +55,27 @@
const props = defineProps({ const props = defineProps({
// 表单配置规则 // 表单配置规则
formProps: { formProps: {
type: Object as PropType<FormProps>, type: Object as PropType<FormProps>
}, },
//表单数据 //表单数据
formModel: { formModel: {
type: Object as PropType<Recordable>, type: Object as PropType<Recordable>,
default: () => {}, default: () => {}
}, },
//是否是工作流 //是否是工作流
isWorkFlow: { isWorkFlow: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
//是否系统表单需要转驼峰,兼容旧系统表单 //是否系统表单需要转驼峰,兼容旧系统表单
isCamelCase: { isCamelCase: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
// 自定义监听 用于以编码开发的形式替代json配置中的change事件
watches: {
type: Array
}
}); });
const getSchemas = computed<FormSchema[]>(() => { const getSchemas = computed<FormSchema[]>(() => {
@ -143,7 +93,7 @@
return { return {
style: baseRowStyle, style: baseRowStyle,
...rowProps, ...rowProps
}; };
}); });
@ -159,19 +109,13 @@
}); });
function showComponent(schema) { function showComponent(schema) {
return props.isWorkFlow return props.isWorkFlow ? !noShowWorkFlowComponents.includes(schema.type) : !noShowGenerateComponents.includes(schema.type);
? !noShowWorkFlowComponents.includes(schema.type)
: !noShowGenerateComponents.includes(schema.type);
} }
function getIsShow(schema: FormSchema, itemValue: any): boolean { function getIsShow(schema: FormSchema, itemValue: any): boolean {
const { show } = schema; const { show } = schema;
const { showAdvancedButton } = getProps.value; const { showAdvancedButton } = getProps.value;
const itemIsAdvanced = showAdvancedButton const itemIsAdvanced = showAdvancedButton ? (isBoolean(schema.isAdvanced) ? schema.isAdvanced : true) : true;
? isBoolean(schema.isAdvanced)
? schema.isAdvanced
: true
: true;
let isShow = true; let isShow = true;
@ -183,7 +127,7 @@
values: itemValue, values: itemValue,
model: formModel!, model: formModel!,
schema: schema, schema: schema,
field: schema.field, field: schema.field
}); });
} }
@ -204,7 +148,7 @@
values: itemValue, values: itemValue,
model: formModel!, model: formModel!,
schema: schema, schema: schema,
field: schema.field, field: schema.field
}); });
} }
return isIfShow; return isIfShow;
@ -268,12 +212,7 @@
} }
function setComponentDefault(item) { function setComponentDefault(item) {
if ( if ((staticDataComponents.includes(item.component) && (item.componentProps as any)?.datasourceType === 'staticData') || (needDicDefaultValue.includes(item.type) && (item.componentProps as any)?.datasourceType === 'dic')) {
(staticDataComponents.includes(item.component) &&
(item.componentProps as any)?.datasourceType === 'staticData') ||
(needDicDefaultValue.includes(item.type) &&
(item.componentProps as any)?.datasourceType === 'dic')
) {
let { defaultSelect } = item.componentProps as any; let { defaultSelect } = item.componentProps as any;
formModel[item.field] = defaultSelect; formModel[item.field] = defaultSelect;
return; return;
@ -285,10 +224,8 @@
const singleFormObj = {}; const singleFormObj = {};
item.componentProps.childSchemas.map((singleCom) => { item.componentProps.childSchemas.map((singleCom) => {
if ( if (
(staticDataComponents.includes(singleCom.component) && (staticDataComponents.includes(singleCom.component) && (singleCom.componentProps as any)?.datasourceType === 'staticData') ||
(singleCom.componentProps as any)?.datasourceType === 'staticData') || (needDicDefaultValue.includes(singleCom.type) && (singleCom.componentProps as any)?.datasourceType === 'dic')
(needDicDefaultValue.includes(singleCom.type) &&
(singleCom.componentProps as any)?.datasourceType === 'dic')
) { ) {
let { defaultSelect } = singleCom.componentProps as any; let { defaultSelect } = singleCom.componentProps as any;
singleFormObj[singleCom.field] = defaultSelect; singleFormObj[singleCom.field] = defaultSelect;
@ -324,18 +261,13 @@
const validate = async (nameList?: NamePath[]): Promise<any> => formRef.value?.validate(nameList); const validate = async (nameList?: NamePath[]): Promise<any> => formRef.value?.validate(nameList);
//清除表单验证 //清除表单验证
const clearValidate = async (name?: string | string[]): Promise<any> => const clearValidate = async (name?: string | string[]): Promise<any> => formRef.value?.clearValidate(name);
formRef.value?.clearValidate(name);
//跳到某个字段 //跳到某个字段
const scrollToField = async (name: NamePath, options?: ScrollOptions): Promise<any> => const scrollToField = async (name: NamePath, options?: ScrollOptions): Promise<any> => formRef.value?.scrollToField(name, options);
formRef.value?.scrollToField(name, options);
//验证某个字段 //验证某个字段
const validateFields = async ( const validateFields = async (nameList?: NamePath[] | string, options?: ValidateOptions): Promise<any> => formRef.value?.validateFields(nameList, options);
nameList?: NamePath[] | string,
options?: ValidateOptions,
): Promise<any> => formRef.value?.validateFields(nameList, options);
const findSchema = (schemaArr, key) => { const findSchema = (schemaArr, key) => {
let schema; let schema;
@ -381,14 +313,8 @@
const isInput = schema?.component && defaultValueComponents.includes(schema.component); const isInput = schema?.component && defaultValueComponents.includes(schema.component);
const isSubForm = schema?.component && arrayValueComponents.includes(schema.component); const isSubForm = schema?.component && arrayValueComponents.includes(schema.component);
const isRange = schema?.component && schema?.component.includes('Range'); const isRange = schema?.component && schema?.component.includes('Range');
const isStatic = const isStatic = schema?.component && staticDataComponents.includes(schema.component) && schema?.componentProps.datasourceType === 'staticData';
schema?.component && const isDic = schema?.type && needDicDefaultValue.includes(schema.type) && schema?.componentProps.datasourceType === 'dic';
staticDataComponents.includes(schema.component) &&
schema?.componentProps.datasourceType === 'staticData';
const isDic =
schema?.type &&
needDicDefaultValue.includes(schema.type) &&
schema?.componentProps.datasourceType === 'dic';
if (isSubForm) { if (isSubForm) {
if (schema.component === 'OneForOne') { if (schema.component === 'OneForOne') {
@ -396,10 +322,8 @@
const singleFormObj = {}; const singleFormObj = {};
schema.componentProps.childSchemas.map((singleCom) => { schema.componentProps.childSchemas.map((singleCom) => {
if ( if (
(staticDataComponents.includes(singleCom.component) && (staticDataComponents.includes(singleCom.component) && singleCom?.componentProps.datasourceType === 'staticData') ||
singleCom?.componentProps.datasourceType === 'staticData') || (needDicDefaultValue.includes(singleCom.type) && singleCom?.componentProps.datasourceType === 'dic')
(needDicDefaultValue.includes(singleCom.type) &&
singleCom?.componentProps.datasourceType === 'dic')
) { ) {
singleFormObj[singleCom.field] = singleCom?.componentProps.defaultSelect; singleFormObj[singleCom.field] = singleCom?.componentProps.defaultSelect;
} else { } else {
@ -417,15 +341,12 @@
const startTimeKey = key.split(',')[0]; const startTimeKey = key.split(',')[0];
const endTimeKey = key.split(',')[1]; const endTimeKey = key.split(',')[1];
formModel[key] = schema?.defaultValue || []; formModel[key] = schema?.defaultValue || [];
formModel[startTimeKey] = formModel[startTimeKey] = schema?.defaultValue && schema?.defaultValue.length > 0 && schema?.defaultValue[0];
schema?.defaultValue && schema?.defaultValue.length > 0 && schema?.defaultValue[0]; formModel[endTimeKey] = schema?.defaultValue && schema?.defaultValue.length > 0 && schema?.defaultValue[1];
formModel[endTimeKey] =
schema?.defaultValue && schema?.defaultValue.length > 0 && schema?.defaultValue[1];
} else if (isStatic || isDic) { } else if (isStatic || isDic) {
formModel[key] = schema?.componentProps.defaultSelect; formModel[key] = schema?.componentProps.defaultSelect;
} else { } else {
formModel[key] = formModel[key] = schema?.defaultValue || schema?.defaultValue === 0 ? schema?.defaultValue : '';
schema?.defaultValue || schema?.defaultValue === 0 ? schema?.defaultValue : '';
} }
}); });
nextTick(() => clearValidate()); nextTick(() => clearValidate());
@ -478,18 +399,13 @@
for (const eventKey in schema.componentProps['events']) { for (const eventKey in schema.componentProps['events']) {
if (eventKey !== 'change') return; if (eventKey !== 'change') return;
try { try {
const event = new Function( const event = new Function('schema', 'formModel', 'formActionType', `${schema.componentProps['events'][eventKey]}`);
'schema',
'formModel',
'formActionType',
`${schema.componentProps['events'][eventKey]}`,
);
event(schema, formModel, formApi); event(schema, formModel, formApi);
} catch (error) { } catch (error) {
console.log('error', error); console.log('error', error);
notification.error({ notification.error({
message: 'Tip', message: 'Tip',
description: '触发事件填写有误!', description: '触发事件填写有误!'
}); });
} }
} }
@ -534,14 +450,9 @@
if (isArray(data)) { if (isArray(data)) {
updateData = [...data]; updateData = [...data];
} }
const hasField = updateData.every( const hasField = updateData.every((item) => noFieldComponent.includes(item.component!) || (Reflect.has(item, 'field') && item.field));
(item) =>
noFieldComponent.includes(item.component!) || (Reflect.has(item, 'field') && item.field),
);
if (!hasField) { if (!hasField) {
throw new Error( throw new Error('All children of the form Schema array that need to be updated must contain the `field` field');
'All children of the form Schema array that need to be updated must contain the `field` field',
);
} }
const schema: FormSchema[] = []; const schema: FormSchema[] = [];
updateData.forEach((item: FormSchema) => { updateData.forEach((item: FormSchema) => {
@ -565,10 +476,7 @@
schemaRef.value = uniqBy(schema, 'field'); schemaRef.value = uniqBy(schema, 'field');
}; };
const deepEachChild = ( const deepEachChild = (childs: GridComponentProps[] | TabComponentProps[] | CardComponentProps[], thisItem: FormSchema) => {
childs: GridComponentProps[] | TabComponentProps[] | CardComponentProps[],
thisItem: FormSchema,
) => {
childs?.forEach((child: GridComponentProps | CardComponentProps | TabComponentProps) => { childs?.forEach((child: GridComponentProps | CardComponentProps | TabComponentProps) => {
child.list.forEach((it: FormSchema) => { child.list.forEach((it: FormSchema) => {
if (['Card', 'Tab', 'Grid'].includes(it.component)) { if (['Card', 'Tab', 'Grid'].includes(it.component)) {
@ -594,14 +502,9 @@
updateData = [...data]; updateData = [...data];
} }
const hasField = updateData.every( const hasField = updateData.every((item) => noFieldComponent.includes(item.component!) || (Reflect.has(item, 'field') && item.field));
(item) =>
noFieldComponent.includes(item.component!) || (Reflect.has(item, 'field') && item.field),
);
if (!hasField) { if (!hasField) {
throw new Error( throw new Error('All children of the form Schema array that need to be updated must contain the `field` field');
'All children of the form Schema array that need to be updated must contain the `field` field',
);
return; return;
} }
@ -630,11 +533,7 @@
schemaRef.value = schemaList; schemaRef.value = schemaList;
}; };
//追加schema //追加schema
const appendSchemaByField = async ( const appendSchemaByField = async (schema: FormSchema, prefixField: string | undefined, first?: boolean | undefined): Promise<void> => {
schema: FormSchema,
prefixField: string | undefined,
first?: boolean | undefined,
): Promise<void> => {
const schemaList: FormSchema[] = cloneDeep(unref(getSchemas)); const schemaList: FormSchema[] = cloneDeep(unref(getSchemas));
const index = schemaList.findIndex((schema) => schema.field === prefixField); const index = schemaList.findIndex((schema) => schema.field === prefixField);
@ -675,7 +574,7 @@
content: createVNode('div', { style: 'color:red;' }, modal.content), content: createVNode('div', { style: 'color:red;' }, modal.content),
onOk: modal.onOk, onOk: modal.onOk,
onCancel: modal.onCancel, onCancel: modal.onCancel,
...modal, ...modal
}); });
}; };
@ -690,21 +589,21 @@
return defHttp[request.requestType]( return defHttp[request.requestType](
{ {
url: request.requestUrl, url: request.requestUrl,
params: request.params, params: request.params
}, },
{ {
errorMessageMode: request.errorMessageMode || 'none', errorMessageMode: request.errorMessageMode || 'none'
}, }
); );
} else { } else {
return defHttp[request.requestType]( return defHttp[request.requestType](
{ {
url: request.requestUrl, url: request.requestUrl,
data: request.params, data: request.params
}, },
{ {
errorMessageMode: request.errorMessageMode || 'none', errorMessageMode: request.errorMessageMode || 'none'
}, }
); );
} }
}; };
@ -750,7 +649,7 @@
httpRequest, httpRequest,
refreshAPI, refreshAPI,
changeStyle, changeStyle,
setDefaultValue, setDefaultValue
}; };
//将表单方法 导出 给父组件使用。 //将表单方法 导出 给父组件使用。

View File

@ -2,52 +2,20 @@
<div> <div>
<!--如果是grid 组件 需要新增grid布局包裹--> <!--如果是grid 组件 需要新增grid布局包裹-->
<template v-if="schema.component.includes('Grid')"> <template v-if="schema.component.includes('Grid')">
<Row <Row v-show="getIsShow(schema)" :align="(schema.componentProps as any ).align" :gutter="(schema.componentProps as any ).gutter ?? 0" :justify="(schema.componentProps as any ).justify" type="flex">
v-show="getIsShow(schema)"
:align="(schema.componentProps as any ).align"
:gutter="(schema.componentProps as any ).gutter ?? 0"
:justify="(schema.componentProps as any ).justify"
type="flex"
>
<Col v-for="(col, colIndex) in schema.children" :key="colIndex" :span="col.span"> <Col v-for="(col, colIndex) in schema.children" :key="colIndex" :span="col.span">
<template v-for="childSchema in col.list" :key="childSchema.field"> <template v-for="childSchema in col.list" :key="childSchema.field">
<SimpleFormItem <SimpleFormItem v-if="showComponent(childSchema)" v-model:value="formModel![childSchema.field]" :form-api="formApi" :isWorkFlow="isWorkFlow" :label-col="labelCol" :refreshFieldObj="refreshFieldObj" :schema="childSchema" />
v-if="showComponent(childSchema)"
v-model:value="formModel![childSchema.field]"
:form-api="formApi"
:isWorkFlow="isWorkFlow"
:label-col="labelCol"
:refreshFieldObj="refreshFieldObj"
:schema="childSchema"
/>
</template> </template>
</Col> </Col>
</Row> </Row>
</template> </template>
<!--如果是tab 组件 需要新增tab组件包裹--> <!--如果是tab 组件 需要新增tab组件包裹-->
<template v-else-if="schema.component === 'Tab'"> <template v-else-if="schema.component === 'Tab'">
<Tabs <Tabs v-show="getIsShow(schema)" v-model:activeKey="activeKey" :size="(schema.componentProps as any ).tabSize" :tabPosition="(schema.componentProps as any ).tabPosition" :type="(schema.componentProps as any ).type">
v-show="getIsShow(schema)" <TabPane v-for="(tab, tabIndex) in schema.children" :key="tabIndex" :forceRender="true" :tab="tab.name">
v-model:activeKey="activeKey"
:size="(schema.componentProps as any ).tabSize"
:tabPosition="(schema.componentProps as any ).tabPosition"
:type="(schema.componentProps as any ).type"
>
<TabPane
v-for="(tab, tabIndex) in schema.children"
:key="tabIndex"
:forceRender="true"
:tab="tab.name"
>
<template v-for="childSchema in tab.list" :key="childSchema.field"> <template v-for="childSchema in tab.list" :key="childSchema.field">
<SimpleFormItem <SimpleFormItem v-if="showComponent(childSchema)" v-model:value="formModel![childSchema.field]" :form-api="formApi" :isWorkFlow="isWorkFlow" :refreshFieldObj="refreshFieldObj" :schema="childSchema" />
v-if="showComponent(childSchema)"
v-model:value="formModel![childSchema.field]"
:form-api="formApi"
:isWorkFlow="isWorkFlow"
:refreshFieldObj="refreshFieldObj"
:schema="childSchema"
/>
</template> </template>
</TabPane> </TabPane>
</Tabs> </Tabs>
@ -64,13 +32,7 @@
:name="schema.field" :name="schema.field"
:wrapperCol="itemLabelWidthProp.wrapperCol" :wrapperCol="itemLabelWidthProp.wrapperCol"
> >
<component <component :is="formComponent(schema)" v-model:value="formModel![schema.field]" :disabled="getDisable" :size="formProps?.size" v-bind="schema.componentProps" />
:is="formComponent(schema)"
v-model:value="formModel![schema.field]"
:disabled="getDisable"
:size="formProps?.size"
v-bind="schema.componentProps"
/>
</FormItem> </FormItem>
</template> </template>
<!--如果是子表单 组件 需要v-model:value="表单对象[字段名]"--> <!--如果是子表单 组件 需要v-model:value="表单对象[字段名]"-->
@ -85,14 +47,7 @@
:name="schema.field" :name="schema.field"
:wrapperCol="itemLabelWidthProp.wrapperCol" :wrapperCol="itemLabelWidthProp.wrapperCol"
> >
<component <component :is="componentMap.get(schema.component)" v-model:value="formModel![schema.field]" :disabled="getDisable" :refreshFieldObj="refreshFieldObj" :size="formProps?.size" v-bind="schema.componentProps" />
:is="componentMap.get(schema.component)"
v-model:value="formModel![schema.field]"
:disabled="getDisable"
:refreshFieldObj="refreshFieldObj"
:size="formProps?.size"
v-bind="schema.componentProps"
/>
</FormItem> </FormItem>
</template> </template>
<template v-else-if="schema.component === 'TableLayout'"> <template v-else-if="schema.component === 'TableLayout'">
@ -104,21 +59,11 @@
height: tdElement.height ? tdElement.height + 'px' : '', height: tdElement.height ? tdElement.height + 'px' : '',
minHeight: (tdElement.height || '42') + 'px', minHeight: (tdElement.height || '42') + 'px',
overflow: 'hidden', overflow: 'hidden',
padding: '10px', padding: '10px'
}" }"
> >
<template <template v-for="childSchema in tdElement.children" :key="childSchema.field">
v-for="childSchema in tdElement.children" <SimpleFormItem v-if="showComponent(childSchema)" v-model:value="formModel![childSchema.field]" :form-api="formApi" :isWorkFlow="isWorkFlow" :refreshFieldObj="refreshFieldObj" :schema="childSchema" />
:key="childSchema.field"
>
<SimpleFormItem
v-if="showComponent(childSchema)"
v-model:value="formModel![childSchema.field]"
:form-api="formApi"
:isWorkFlow="isWorkFlow"
:refreshFieldObj="refreshFieldObj"
:schema="childSchema"
/>
</template> </template>
</div> </div>
</div> </div>
@ -149,62 +94,24 @@
/> />
</FormItem> </FormItem>
<!-- 因为Range会变为 开始时间 结束时间 2个属性给与表单数据 所以需要2个隐藏框绑定 starTime endTime --> <!-- 因为Range会变为 开始时间 结束时间 2个属性给与表单数据 所以需要2个隐藏框绑定 starTime endTime -->
<FormItem <FormItem v-show="false" :key="schema.key" :label="getComponentsProps.showLabel ? schema.label : ''" :name="schema.field.split(',')[0]">
v-show="false"
:key="schema.key"
:label="getComponentsProps.showLabel ? schema.label : ''"
:name="schema.field.split(',')[0]"
>
<input type="hidden" /> <input type="hidden" />
</FormItem> </FormItem>
<FormItem <FormItem v-show="false" :key="schema.key" :label="getComponentsProps.showLabel ? schema.label : ''" :name="schema.field.split(',')[1]">
v-show="false"
:key="schema.key"
:label="getComponentsProps.showLabel ? schema.label : ''"
:name="schema.field.split(',')[1]"
>
<input type="hidden" /> <input type="hidden" />
</FormItem> </FormItem>
</template> </template>
<!--如果checked 或者 switch组件 需要v-model:checked="表单对象[字段名]" "--> <!--如果checked 或者 switch组件 需要v-model:checked="表单对象[字段名]" "-->
<template v-else-if="checkedValueComponents.includes(schema.component)"> <template v-else-if="checkedValueComponents.includes(schema.component)">
<FormItem <FormItem v-if="getShow(schema)" v-show="getIsShow(schema)" :key="schema.key" :label="getComponentsProps.showLabel ? schema.label : ''" :label-col="labelCol" :name="schema.field" :rules="rules" :wrapperCol="itemLabelWidthProp.wrapperCol">
v-if="getShow(schema)" <component :is="componentMap.get(schema.component)" :key="refreshFieldObj[schema.field]" v-model:checked="formModel![schema.field]" :disabled="getDisable" :size="formProps?.size" v-bind="getComponentsProps" />
v-show="getIsShow(schema)"
:key="schema.key"
:label="getComponentsProps.showLabel ? schema.label : ''"
:label-col="labelCol"
:name="schema.field"
:rules="rules"
:wrapperCol="itemLabelWidthProp.wrapperCol"
>
<component
:is="componentMap.get(schema.component)"
:key="refreshFieldObj[schema.field]"
v-model:checked="formModel![schema.field]"
:disabled="getDisable"
:size="formProps?.size"
v-bind="getComponentsProps"
/>
</FormItem> </FormItem>
</template> </template>
<!--如果是card 组件 需要新增card组件包裹--> <!--如果是card 组件 需要新增card组件包裹-->
<template v-else-if="schema.component.includes('Card')"> <template v-else-if="schema.component.includes('Card')">
<CollapseContainer <CollapseContainer v-show="getIsShow(schema)" :bordered="false" :hasLeftBorder="true" :title="(schema.componentProps as any ).title">
v-show="getIsShow(schema)"
:bordered="false"
:hasLeftBorder="true"
:title="(schema.componentProps as any ).title"
>
<template v-for="childSchema in schema.children![0].list" :key="childSchema.field"> <template v-for="childSchema in schema.children![0].list" :key="childSchema.field">
<SimpleFormItem <SimpleFormItem v-if="showComponent(childSchema)" v-model:value="formModel![childSchema.field]" :form-api="formApi" :isWorkFlow="isWorkFlow" :refreshFieldObj="refreshFieldObj" :schema="childSchema" />
v-if="showComponent(childSchema)"
v-model:value="formModel![childSchema.field]"
:form-api="formApi"
:isWorkFlow="isWorkFlow"
:refreshFieldObj="refreshFieldObj"
:schema="childSchema"
/>
</template> </template>
</CollapseContainer> </CollapseContainer>
</template> </template>
@ -227,14 +134,7 @@
:validateTrigger="['blur', 'change']" :validateTrigger="['blur', 'change']"
:wrapperCol="itemLabelWidthProp.wrapperCol" :wrapperCol="itemLabelWidthProp.wrapperCol"
> >
<component <component :is="componentMap.get(schema.component)" :key="refreshFieldObj[schema.field]" :disabled="getDisable" :size="formProps?.size" :value="schema.defaultValue" v-bind="getComponentsProps" />
:is="componentMap.get(schema.component)"
:key="refreshFieldObj[schema.field]"
:disabled="getDisable"
:size="formProps?.size"
:value="schema.defaultValue"
v-bind="getComponentsProps"
/>
</FormItem> </FormItem>
</template> </template>
<template v-else> <template v-else>
@ -249,20 +149,11 @@
:validateTrigger="['blur', 'change']" :validateTrigger="['blur', 'change']"
:wrapperCol="itemLabelWidthProp.wrapperCol" :wrapperCol="itemLabelWidthProp.wrapperCol"
> >
<template <template v-if="getDisable && /Input|AutoCodeRule|DatePicker/.test(schema.component)">
v-if="getDisable && /Input|AutoCodeRule|DatePicker/.test(schema.component)"
>
<readonly :schema="schema" :value="formModel![schema.field]" /> <readonly :schema="schema" :value="formModel![schema.field]" />
</template> </template>
<template v-else> <template v-else>
<component <component :is="defaultComponent(schema)" :key="refreshFieldObj[schema.field]" v-model:value="formModel![schema.field]" :disabled="getDisable" :size="formProps?.size" v-bind="getComponentsProps" />
:is="defaultComponent(schema)"
:key="refreshFieldObj[schema.field]"
v-model:value="formModel![schema.field]"
:disabled="getDisable"
:size="formProps?.size"
v-bind="getComponentsProps"
/>
</template> </template>
</FormItem> </FormItem>
</template> </template>
@ -277,10 +168,7 @@
import { useItemLabelWidth } from '/@/components/Form/src/hooks/useLabelWidth'; import { useItemLabelWidth } from '/@/components/Form/src/hooks/useLabelWidth';
import { FormActionType, FormProps, FormSchema } from '/@/components/Form/src/types/form'; import { FormActionType, FormProps, FormSchema } from '/@/components/Form/src/types/form';
import { CollapseContainer } from '/@/components/Container'; import { CollapseContainer } from '/@/components/Container';
import { import { noShowWorkFlowComponents, noShowGenerateComponents } from '/@/components/Form/src/helper';
noShowWorkFlowComponents,
noShowGenerateComponents,
} from '/@/components/Form/src/helper';
import { useMessage } from '/@/hooks/web/useMessage'; import { useMessage } from '/@/hooks/web/useMessage';
import TableLayoutPreview from '/@/components/Form/src/components/TableLayoutPreview.vue'; import TableLayoutPreview from '/@/components/Form/src/components/TableLayoutPreview.vue';
import { camelCaseString } from '/@/utils/event/design'; import { camelCaseString } from '/@/utils/event/design';
@ -292,22 +180,22 @@
// 表单配置规则 // 表单配置规则
schema: { schema: {
type: Object as PropType<FormSchema>, type: Object as PropType<FormSchema>,
default: () => {}, default: () => {}
}, },
value: [Object, String, Number, Boolean, Array], value: [Object, String, Number, Boolean, Array],
formApi: { formApi: {
type: Object as PropType<FormActionType>, type: Object as PropType<FormActionType>
}, },
//刷新api使用 //刷新api使用
refreshFieldObj: { refreshFieldObj: {
type: Object, type: Object,
default: () => {}, default: () => {}
}, },
//是否是工作流 //是否是工作流
isWorkFlow: { isWorkFlow: {
type: Boolean, type: Boolean,
default: false, default: false
}, }
}); });
const formModel = inject<Recordable>('formModel'); const formModel = inject<Recordable>('formModel');
@ -315,14 +203,16 @@
const tabActiveKey = inject<Ref<number>>('tabActiveKey', ref(0)); const tabActiveKey = inject<Ref<number>>('tabActiveKey', ref(0));
const activeKey = ref<number>(0); const activeKey = ref<number>(0);
const isCamelCase = inject<boolean>('isCamelCase', false); const isCamelCase = inject<boolean>('isCamelCase', false);
// 注入整个表单的配置formProps是个计算属性不能修改formData则来自每个业务的表单页面。
const formData = inject('formData', { noInject: true });
watch( watch(
() => tabActiveKey?.value, () => tabActiveKey?.value,
(val) => { (val) => {
if (props.isWorkFlow) activeKey.value = val!; if (props.isWorkFlow) activeKey.value = val!;
}, },
{ {
immediate: true, immediate: true
}, }
); );
watch( watch(
() => activeKey?.value, () => activeKey?.value,
@ -330,8 +220,8 @@
if (props.isWorkFlow) tabActiveKey.value = val!; if (props.isWorkFlow) tabActiveKey.value = val!;
}, },
{ {
immediate: true, immediate: true
}, }
); );
// watch( // watch(
@ -381,7 +271,7 @@
values: formModel![getSchema.value.field], values: formModel![getSchema.value.field],
model: formModel!, model: formModel!,
schema: unref(getSchema), schema: unref(getSchema),
field: unref(getSchema).field, field: unref(getSchema).field
}); });
} }
return disabled; return disabled;
@ -395,38 +285,31 @@
componentProps({ componentProps({
schema: props.schema, schema: props.schema,
formModel, formModel,
formActionType: props.formApi, formActionType: props.formApi
}) ?? {}; }) ?? {};
} else { } else {
if (componentProps['events']) { if (componentProps['events']) {
for (const eventKey in componentProps['events']) { for (const eventKey in componentProps['events']) {
try { try {
const event = new Function( const fun = componentProps['events'][eventKey];
'schema', let event;
'formModel', if (typeof fun === 'string') {
'formActionType', event = new Function('schema', 'formModel', 'formActionType', 'extParams', `${fun}`);
`${componentProps['events'][eventKey]}`, } else if (typeof fun === 'function') {
); event = fun;
}
componentProps['on' + upperFirst(eventKey)] = function () { componentProps['on' + upperFirst(eventKey)] = function () {
let cloneFormModel = cloneDeep(formModel); let cloneFormModel = cloneDeep(formModel);
for (let item in cloneFormModel) { for (let item in cloneFormModel) {
let field = camelCaseString(item); let field = camelCaseString(item);
if (field) cloneFormModel[field] = cloneFormModel[item]; if (field) cloneFormModel[field] = cloneFormModel[item];
} }
event( event(props.schema, isCamelCase ? cloneFormModel : formModel, props.formApi, { formData });
props.schema,
isCamelCase ? cloneFormModel : formModel,
props.formApi,
);
if (isCamelCase) { if (isCamelCase) {
for (let item in formModel) { for (let item in formModel) {
let field = camelCaseString(item); let field = camelCaseString(item);
if ( if (cloneFormModel && field && cloneFormModel[field] !== undefined) {
cloneFormModel &&
field &&
cloneFormModel[field] !== undefined
) {
formModel[item] = cloneFormModel[field]; formModel[item] = cloneFormModel[field];
} }
} }
@ -436,7 +319,7 @@
console.log('error', error); console.log('error', error);
notification.error({ notification.error({
message: 'Tip', message: 'Tip',
description: '触发事件填写有误!', description: '触发事件填写有误!'
}); });
} }
} }
@ -453,15 +336,13 @@
}); });
const labelCol = computed(() => { const labelCol = computed(() => {
return unref(getComponentsProps).span return unref(getComponentsProps).span ? { span: unref(getComponentsProps).span } : unref(itemLabelWidthProp).labelCol;
? { span: unref(getComponentsProps).span }
: unref(itemLabelWidthProp).labelCol;
}); });
const rules = computed(() => { const rules = computed(() => {
const requiredRule = { const requiredRule = {
required: unref(getComponentsProps).required || false, required: unref(getComponentsProps).required || false,
message: `${props.schema.label}是必填项`, message: `${props.schema.label}是必填项`
}; };
const rulesList = cloneDeep(unref(getComponentsProps).rules); const rulesList = cloneDeep(unref(getComponentsProps).rules);
if (!rulesList) return [requiredRule]; if (!rulesList) return [requiredRule];
@ -477,10 +358,7 @@
// console.log('formitem watch!!!!!!!!'); // console.log('formitem watch!!!!!!!!');
//填值以后需要手动校验的组件 //填值以后需要手动校验的组件
const validateComponents = ['User', 'RichTextEditor', 'Upload', 'SelectMap']; const validateComponents = ['User', 'RichTextEditor', 'Upload', 'SelectMap'];
if ( if (validateComponents.includes(props.schema.component) && formModel![props.schema.field]) {
validateComponents.includes(props.schema.component) &&
formModel![props.schema.field]
) {
setTimeout(() => { setTimeout(() => {
props.formApi?.validateFields([props.schema.field]); props.formApi?.validateFields([props.schema.field]);
}, 100); }, 100);
@ -488,8 +366,8 @@
}, },
{ {
deep: true, deep: true,
immediate: true, immediate: true
}, }
); );
onMounted(() => { onMounted(() => {
// console.log('onMounted'); // console.log('onMounted');
@ -510,31 +388,15 @@
}); });
const formComponent = (schema) => { const formComponent = (schema) => {
return componentMap.get( return componentMap.get(['caseErpApplyDetailList', 'case_erp_apply_detailList', 'CASE_ERP_APPLY_DETAILList'].includes(schema.field) ? 'ErpApply' : schema.component);
[
'caseErpApplyDetailList',
'case_erp_apply_detailList',
'CASE_ERP_APPLY_DETAILList',
].includes(schema.field)
? 'ErpApply'
: schema.component,
);
}; };
const defaultComponent = (schema) => { const defaultComponent = (schema) => {
return componentMap.get( return componentMap.get(schema.key === 'ac18952da41b45c9a66ffba3e42b7f3d' ? 'ErpUpload' : schema.key === 'b3ba87573cf0466d951bc63fd4df1c78' ? 'ErpCheck' : schema.component);
schema.key === 'ac18952da41b45c9a66ffba3e42b7f3d'
? 'ErpUpload'
: schema.key === 'b3ba87573cf0466d951bc63fd4df1c78'
? 'ErpCheck'
: schema.component,
);
}; };
function showComponent(schema) { function showComponent(schema) {
return props.isWorkFlow return props.isWorkFlow ? !noShowWorkFlowComponents.includes(schema.type) : !noShowGenerateComponents.includes(schema.type);
? !noShowWorkFlowComponents.includes(schema.type)
: !noShowGenerateComponents.includes(schema.type);
} }
function getShow(schema: FormSchema): boolean { function getShow(schema: FormSchema): boolean {