123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- import type { ComputedRef, Ref } from 'vue';
- import type { FormProps, FormSchema, FormActionType } from '../types/form';
- import type { NamePath } from 'ant-design-vue/lib/form/interface';
- import { unref, toRaw } from 'vue';
- import { isArray, isFunction, isObject, isString } from '/@/utils/is';
- import { deepMerge } from '/@/utils';
- import { dateItemType, handleInputNumberValue } from '../helper';
- import { dateUtil } from '/@/utils/dateUtil';
- import { cloneDeep, uniqBy } from 'lodash-es';
- import { error } from '/@/utils/log';
- interface UseFormActionContext {
- emit: EmitType;
- getProps: ComputedRef<FormProps>;
- getSchema: ComputedRef<FormSchema[]>;
- formModel: Recordable;
- defaultValueRef: Ref<Recordable>;
- formElRef: Ref<FormActionType>;
- schemaRef: Ref<FormSchema[]>;
- handleFormValues: Fn;
- }
- export function useFormEvents({
- emit,
- getProps,
- formModel,
- getSchema,
- defaultValueRef,
- formElRef,
- schemaRef,
- handleFormValues,
- }: UseFormActionContext) {
- async function resetFields(): Promise<void> {
- const { resetFunc, submitOnReset } = unref(getProps);
- resetFunc && isFunction(resetFunc) && (await resetFunc());
- const formEl = unref(formElRef);
- if (!formEl) return;
- Object.keys(formModel).forEach((key) => {
- formModel[key] = defaultValueRef.value[key];
- });
- clearValidate();
- emit('reset', toRaw(formModel));
- submitOnReset && handleSubmit();
- }
- /**
- * @description: Set form value
- */
- async function setFieldsValue(values: Recordable): Promise<void> {
- const fields = unref(getSchema)
- .map((item) => item.field)
- .filter(Boolean);
- const validKeys: string[] = [];
- Object.keys(values).forEach((key) => {
- const schema = unref(getSchema).find((item) => item.field === key);
- let value = values[key];
- const hasKey = Reflect.has(values, key);
- value = handleInputNumberValue(schema?.component, value);
- // 0| '' is allow
- if (hasKey && fields.includes(key)) {
- // time type
- if (itemIsDateType(key)) {
- if (Array.isArray(value)) {
- const arr: any[] = [];
- for (const ele of value) {
- arr.push(ele ? dateUtil(ele) : null);
- }
- formModel[key] = arr;
- } else {
- const { componentProps } = schema || {};
- let _props = componentProps as any;
- if (typeof componentProps === 'function') {
- _props = _props({ formModel });
- }
- formModel[key] = value ? (_props?.valueFormat ? value : dateUtil(value)) : null;
- }
- } else {
- formModel[key] = value;
- }
- validKeys.push(key);
- }
- });
- validateFields(validKeys).catch((_) => {});
- }
- /**
- * @description: Delete based on field name
- */
- async function removeSchemaByFiled(fields: string | string[]): Promise<void> {
- const schemaList: FormSchema[] = cloneDeep(unref(getSchema));
- if (!fields) {
- return;
- }
- let fieldList: string[] = isString(fields) ? [fields] : fields;
- if (isString(fields)) {
- fieldList = [fields];
- }
- for (const field of fieldList) {
- _removeSchemaByFiled(field, schemaList);
- }
- schemaRef.value = schemaList;
- }
- /**
- * @description: Delete based on field name
- */
- function _removeSchemaByFiled(field: string, schemaList: FormSchema[]): void {
- if (isString(field)) {
- const index = schemaList.findIndex((schema) => schema.field === field);
- if (index !== -1) {
- delete formModel[field];
- schemaList.splice(index, 1);
- }
- }
- }
- /**
- * @description: Insert after a certain field, if not insert the last
- */
- async function appendSchemaByField(schema: FormSchema, prefixField?: string, first = false) {
- const schemaList: FormSchema[] = cloneDeep(unref(getSchema));
- const index = schemaList.findIndex((schema) => schema.field === prefixField);
- const hasInList = schemaList.some((item) => item.field === prefixField || schema.field);
- if (!hasInList) return;
- if (!prefixField || index === -1 || first) {
- first ? schemaList.unshift(schema) : schemaList.push(schema);
- schemaRef.value = schemaList;
- return;
- }
- if (index !== -1) {
- schemaList.splice(index + 1, 0, schema);
- }
- schemaRef.value = schemaList;
- }
- async function resetSchema(data: Partial<FormSchema> | Partial<FormSchema>[]) {
- let updateData: Partial<FormSchema>[] = [];
- if (isObject(data)) {
- updateData.push(data as FormSchema);
- }
- if (isArray(data)) {
- updateData = [...data];
- }
- const hasField = updateData.every(
- (item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field),
- );
- if (!hasField) {
- error(
- 'All children of the form Schema array that need to be updated must contain the `field` field',
- );
- return;
- }
- schemaRef.value = updateData as FormSchema[];
- }
- async function updateSchema(data: Partial<FormSchema> | Partial<FormSchema>[]) {
- let updateData: Partial<FormSchema>[] = [];
- if (isObject(data)) {
- updateData.push(data as FormSchema);
- }
- if (isArray(data)) {
- updateData = [...data];
- }
- const hasField = updateData.every(
- (item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field),
- );
- if (!hasField) {
- error(
- 'All children of the form Schema array that need to be updated must contain the `field` field',
- );
- return;
- }
- const schema: FormSchema[] = [];
- updateData.forEach((item) => {
- unref(getSchema).forEach((val) => {
- if (val.field === item.field) {
- const newSchema = deepMerge(val, item);
- schema.push(newSchema as FormSchema);
- } else {
- schema.push(val);
- }
- });
- });
- schemaRef.value = uniqBy(schema, 'field');
- }
- function getFieldsValue(): Recordable {
- const formEl = unref(formElRef);
- if (!formEl) return {};
- return handleFormValues(toRaw(unref(formModel)));
- }
- /**
- * @description: Is it time
- */
- function itemIsDateType(key: string) {
- return unref(getSchema).some((item) => {
- return item.field === key ? dateItemType.includes(item.component) : false;
- });
- }
- async function validateFields(nameList?: NamePath[] | undefined) {
- return unref(formElRef)?.validateFields(nameList);
- }
- async function validate(nameList?: NamePath[] | undefined) {
- return await unref(formElRef)?.validate(nameList);
- }
- async function clearValidate(name?: string | string[]) {
- await unref(formElRef)?.clearValidate(name);
- }
- async function scrollToField(name: NamePath, options?: ScrollOptions | undefined) {
- await unref(formElRef)?.scrollToField(name, options);
- }
- /**
- * @description: Form submission
- */
- async function handleSubmit(e?: Event): Promise<void> {
- e && e.preventDefault();
- const { submitFunc } = unref(getProps);
- if (submitFunc && isFunction(submitFunc)) {
- await submitFunc();
- return;
- }
- const formEl = unref(formElRef);
- if (!formEl) return;
- try {
- const values = await validate();
- const res = handleFormValues(values);
- emit('submit', res);
- } catch (error: any) {
- throw new Error(error);
- }
- }
- return {
- handleSubmit,
- clearValidate,
- validate,
- validateFields,
- getFieldsValue,
- updateSchema,
- resetSchema,
- appendSchemaByField,
- removeSchemaByFiled,
- resetFields,
- setFieldsValue,
- scrollToField,
- };
- }
|