mirror of
				https://github.com/Tencent/tmagic-editor.git
				synced 2025-11-04 18:52:18 +08:00 
			
		
		
		
	feat(form,editor): 表单新增修改数据记录
This commit is contained in:
		
							parent
							
								
									0a1f03b5c7
								
							
						
					
					
						commit
						9f7d67b17b
					
				@ -63,7 +63,13 @@ import { computed, inject, Ref, ref } from 'vue';
 | 
			
		||||
 | 
			
		||||
import type { CodeBlockContent } from '@tmagic/core';
 | 
			
		||||
import { TMagicButton, TMagicDialog, tMagicMessage, tMagicMessageBox, TMagicTag } from '@tmagic/design';
 | 
			
		||||
import { type FormConfig, type FormState, MFormBox, type TableColumnConfig } from '@tmagic/form';
 | 
			
		||||
import {
 | 
			
		||||
  type ContainerChangeEventData,
 | 
			
		||||
  type FormConfig,
 | 
			
		||||
  type FormState,
 | 
			
		||||
  MFormBox,
 | 
			
		||||
  type TableColumnConfig,
 | 
			
		||||
} from '@tmagic/form';
 | 
			
		||||
 | 
			
		||||
import FloatingBox from '@editor/components/FloatingBox.vue';
 | 
			
		||||
import { useEditorContentHeight } from '@editor/hooks/use-editor-content-height';
 | 
			
		||||
@ -88,7 +94,7 @@ const props = defineProps<{
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  submit: [values: CodeBlockContent];
 | 
			
		||||
  submit: [values: CodeBlockContent, eventData: ContainerChangeEventData];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const services = inject<Services>('services');
 | 
			
		||||
@ -209,9 +215,9 @@ const functionConfig = computed<FormConfig>(() => [
 | 
			
		||||
  },
 | 
			
		||||
]);
 | 
			
		||||
 | 
			
		||||
const submitForm = (values: CodeBlockContent) => {
 | 
			
		||||
const submitForm = (values: CodeBlockContent, data: ContainerChangeEventData) => {
 | 
			
		||||
  changedValue.value = undefined;
 | 
			
		||||
  emit('submit', values);
 | 
			
		||||
  emit('submit', values, data);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const errorHandler = (error: any) => {
 | 
			
		||||
@ -238,7 +244,7 @@ const beforeClose = (done: (cancel?: boolean) => void) => {
 | 
			
		||||
      distinguishCancelAndClose: true,
 | 
			
		||||
    })
 | 
			
		||||
    .then(() => {
 | 
			
		||||
      changedValue.value && submitForm(changedValue.value);
 | 
			
		||||
      changedValue.value && submitForm(changedValue.value, { changeRecords: formBox.value?.form?.changeRecords });
 | 
			
		||||
      done();
 | 
			
		||||
    })
 | 
			
		||||
    .catch((action: string) => {
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { computed, ref } from 'vue';
 | 
			
		||||
 | 
			
		||||
import { FormConfig, MForm } from '@tmagic/form';
 | 
			
		||||
import { type ContainerChangeEventData, type FormConfig, type FormValue, MForm } from '@tmagic/form';
 | 
			
		||||
 | 
			
		||||
import type { CodeParamStatement } from '@editor/type';
 | 
			
		||||
import { error } from '@editor/utils';
 | 
			
		||||
@ -59,10 +59,10 @@ const codeParamsConfig = computed(() =>
 | 
			
		||||
/**
 | 
			
		||||
 * 参数值修改更新
 | 
			
		||||
 */
 | 
			
		||||
const onParamsChangeHandler = async () => {
 | 
			
		||||
const onParamsChangeHandler = async (v: FormValue, eventData: ContainerChangeEventData) => {
 | 
			
		||||
  try {
 | 
			
		||||
    const value = await form.value?.submitForm(true);
 | 
			
		||||
    emit('change', value);
 | 
			
		||||
    emit('change', value, eventData);
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    error(e);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,7 @@ const emit = defineEmits<{
 | 
			
		||||
  change: [value: string | any];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const props = withDefaults(
 | 
			
		||||
withDefaults(
 | 
			
		||||
  defineProps<
 | 
			
		||||
    FieldProps<
 | 
			
		||||
      {
 | 
			
		||||
@ -44,7 +44,6 @@ const props = withDefaults(
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const save = (v: string | any) => {
 | 
			
		||||
  props.model[props.name] = v;
 | 
			
		||||
  emit('change', v);
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -21,8 +21,8 @@ import { isEmpty } from 'lodash-es';
 | 
			
		||||
 | 
			
		||||
import { HookCodeType, HookType } from '@tmagic/core';
 | 
			
		||||
import { TMagicCard } from '@tmagic/design';
 | 
			
		||||
import type { FieldProps, FormItem } from '@tmagic/form';
 | 
			
		||||
import { FormState, MContainer } from '@tmagic/form';
 | 
			
		||||
import type { ContainerChangeEventData, FieldProps, FormItem, GroupListConfig } from '@tmagic/form';
 | 
			
		||||
import { MContainer } from '@tmagic/form';
 | 
			
		||||
 | 
			
		||||
import type { Services } from '@editor/type';
 | 
			
		||||
 | 
			
		||||
@ -30,7 +30,9 @@ defineOptions({
 | 
			
		||||
  name: 'MFieldsCodeSelect',
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change']);
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [v: any, eventData: ContainerChangeEventData];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const services = inject<Services>('services');
 | 
			
		||||
 | 
			
		||||
@ -45,12 +47,12 @@ const props = withDefaults(
 | 
			
		||||
  {},
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const codeConfig = computed(() => ({
 | 
			
		||||
const codeConfig = computed<GroupListConfig>(() => ({
 | 
			
		||||
  type: 'group-list',
 | 
			
		||||
  name: 'hookData',
 | 
			
		||||
  enableToggleMode: false,
 | 
			
		||||
  expandAll: true,
 | 
			
		||||
  title: (mForm: FormState, { model, index }: any) => {
 | 
			
		||||
  title: (mForm, { model, index }: any) => {
 | 
			
		||||
    if (model.codeType === HookCodeType.DATA_SOURCE_METHOD) {
 | 
			
		||||
      if (Array.isArray(model.codeId)) {
 | 
			
		||||
        if (model.codeId.length < 2) {
 | 
			
		||||
@ -78,11 +80,13 @@ const codeConfig = computed(() => ({
 | 
			
		||||
            { value: HookCodeType.DATA_SOURCE_METHOD, text: '数据源方法' },
 | 
			
		||||
          ],
 | 
			
		||||
          defaultValue: 'code',
 | 
			
		||||
          onChange: (mForm: FormState, v: HookCodeType, { model }: any) => {
 | 
			
		||||
          onChange: (mForm, v: HookCodeType, { model, prop, changeRecords }) => {
 | 
			
		||||
            if (v === HookCodeType.DATA_SOURCE_METHOD) {
 | 
			
		||||
              model.codeId = [];
 | 
			
		||||
              changeRecords.push({ propPath: prop.replace('codeType', 'codeId'), value: [] });
 | 
			
		||||
            } else {
 | 
			
		||||
              model.codeId = '';
 | 
			
		||||
              changeRecords.push({ propPath: prop.replace('codeType', 'codeId'), value: '' });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return v;
 | 
			
		||||
@ -93,7 +97,7 @@ const codeConfig = computed(() => ({
 | 
			
		||||
          name: 'codeId',
 | 
			
		||||
          span: 18,
 | 
			
		||||
          labelWidth: 0,
 | 
			
		||||
          display: (mForm: FormState, { model }: any) => model.codeType !== HookCodeType.DATA_SOURCE_METHOD,
 | 
			
		||||
          display: (mForm, { model }) => model.codeType !== HookCodeType.DATA_SOURCE_METHOD,
 | 
			
		||||
          notEditable: () => !services?.codeBlockService.getEditStatus(),
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
@ -101,7 +105,7 @@ const codeConfig = computed(() => ({
 | 
			
		||||
          name: 'codeId',
 | 
			
		||||
          span: 18,
 | 
			
		||||
          labelWidth: 0,
 | 
			
		||||
          display: (mForm: FormState, { model }: any) => model.codeType === HookCodeType.DATA_SOURCE_METHOD,
 | 
			
		||||
          display: (mForm, { model }) => model.codeType === HookCodeType.DATA_SOURCE_METHOD,
 | 
			
		||||
          notEditable: () => !services?.dataSourceService.get('editable'),
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
@ -126,7 +130,5 @@ watch(
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const changeHandler = async () => {
 | 
			
		||||
  emit('change', props.model[props.name]);
 | 
			
		||||
};
 | 
			
		||||
const changeHandler = (v: any, eventData: ContainerChangeEventData) => emit('change', v, eventData);
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
        :config="selectConfig"
 | 
			
		||||
        :model="model"
 | 
			
		||||
        :size="size"
 | 
			
		||||
        @change="onParamsChangeHandler"
 | 
			
		||||
        @change="onCodeIdChangeHandler"
 | 
			
		||||
      ></MContainer>
 | 
			
		||||
 | 
			
		||||
      <!-- 查看/编辑按钮 -->
 | 
			
		||||
@ -41,7 +41,14 @@ import { isEmpty, map } from 'lodash-es';
 | 
			
		||||
 | 
			
		||||
import type { Id } from '@tmagic/core';
 | 
			
		||||
import { TMagicButton } from '@tmagic/design';
 | 
			
		||||
import { createValues, type FieldProps, filterFunction, type FormState, MContainer } from '@tmagic/form';
 | 
			
		||||
import {
 | 
			
		||||
  type ContainerChangeEventData,
 | 
			
		||||
  createValues,
 | 
			
		||||
  type FieldProps,
 | 
			
		||||
  filterFunction,
 | 
			
		||||
  type FormState,
 | 
			
		||||
  MContainer,
 | 
			
		||||
} from '@tmagic/form';
 | 
			
		||||
 | 
			
		||||
import CodeParams from '@editor/components/CodeParams.vue';
 | 
			
		||||
import MIcon from '@editor/components/Icon.vue';
 | 
			
		||||
@ -55,7 +62,9 @@ defineOptions({
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
const services = inject<Services>('services');
 | 
			
		||||
const eventBus = inject<EventBus>('eventBus');
 | 
			
		||||
const emit = defineEmits(['change']);
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [v: any, eventData: ContainerChangeEventData];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const props = withDefaults(defineProps<FieldProps<CodeSelectColConfig>>(), {
 | 
			
		||||
  disabled: false,
 | 
			
		||||
@ -125,12 +134,30 @@ const selectConfig = {
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const onCodeIdChangeHandler = (value: any) => {
 | 
			
		||||
  props.model.params = value.params;
 | 
			
		||||
  emit('change', props.model, {
 | 
			
		||||
    changeRecords: [
 | 
			
		||||
      {
 | 
			
		||||
        propPath: props.prop,
 | 
			
		||||
        value: value[props.name],
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 参数值修改更新
 | 
			
		||||
 */
 | 
			
		||||
const onParamsChangeHandler = (value: any) => {
 | 
			
		||||
const onParamsChangeHandler = (value: any, eventData: ContainerChangeEventData) => {
 | 
			
		||||
  props.model.params = value.params;
 | 
			
		||||
  emit('change', props.model);
 | 
			
		||||
  emit('change', props.model, {
 | 
			
		||||
    ...eventData,
 | 
			
		||||
    changeRecords: (eventData.changeRecords || []).map((item) => ({
 | 
			
		||||
      prop: `${props.prop.replace(props.name, '')}${item.propPath}`,
 | 
			
		||||
      value: item.value,
 | 
			
		||||
    })),
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const editCode = (id: string) => {
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,10 @@ defineOptions({
 | 
			
		||||
  name: 'MFieldsCondOpSelect',
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change']);
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [value: string];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const { dataSourceService } = inject<Services>('services') || {};
 | 
			
		||||
 | 
			
		||||
const props = defineProps<FieldProps<CondOpSelectConfig>>();
 | 
			
		||||
@ -81,7 +84,7 @@ const options = computed(() => {
 | 
			
		||||
  return [...arrayOptions, ...eqOptions, ...numberOptions];
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const fieldChangeHandler = (v: string[]) => {
 | 
			
		||||
const fieldChangeHandler = (v: string) => {
 | 
			
		||||
  emit('change', v);
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -51,7 +51,13 @@ import { inject, Ref, ref } from 'vue';
 | 
			
		||||
 | 
			
		||||
import type { DataSchema } from '@tmagic/core';
 | 
			
		||||
import { TMagicButton, tMagicMessage, tMagicMessageBox } from '@tmagic/design';
 | 
			
		||||
import { type FieldProps, type FormConfig, type FormState, MFormBox } from '@tmagic/form';
 | 
			
		||||
import {
 | 
			
		||||
  type ContainerChangeEventData,
 | 
			
		||||
  type FieldProps,
 | 
			
		||||
  type FormConfig,
 | 
			
		||||
  type FormState,
 | 
			
		||||
  MFormBox,
 | 
			
		||||
} from '@tmagic/form';
 | 
			
		||||
import { type ColumnConfig, MagicTable } from '@tmagic/table';
 | 
			
		||||
import { getDefaultValueFromFields } from '@tmagic/utils';
 | 
			
		||||
 | 
			
		||||
@ -75,7 +81,9 @@ const props = withDefaults(
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change']);
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [v: any, eventData?: ContainerChangeEventData];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const services = inject<Services>('services');
 | 
			
		||||
 | 
			
		||||
@ -91,16 +99,29 @@ const newHandler = () => {
 | 
			
		||||
  addDialogVisible.value = true;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const fieldChange = ({ index, ...value }: Record<string, any>) => {
 | 
			
		||||
  if (index > -1) {
 | 
			
		||||
    props.model[props.name][index] = value;
 | 
			
		||||
  } else {
 | 
			
		||||
    props.model[props.name].push(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
const fieldChange = ({ index, ...value }: Record<string, any>, data: ContainerChangeEventData) => {
 | 
			
		||||
  addDialogVisible.value = false;
 | 
			
		||||
 | 
			
		||||
  emit('change', props.model[props.name]);
 | 
			
		||||
  if (index > -1) {
 | 
			
		||||
    emit('change', value, {
 | 
			
		||||
      modifyKey: index,
 | 
			
		||||
      changeRecords: (data.changeRecords || []).map((item) => ({
 | 
			
		||||
        propPath: `${props.prop}.${index}.${item.propPath}`,
 | 
			
		||||
        value: item.value,
 | 
			
		||||
      })),
 | 
			
		||||
    });
 | 
			
		||||
  } else {
 | 
			
		||||
    const modifyKey = props.model[props.name].length;
 | 
			
		||||
    emit('change', value, {
 | 
			
		||||
      modifyKey,
 | 
			
		||||
      changeRecords: [
 | 
			
		||||
        {
 | 
			
		||||
          propPath: `${props.prop}.${modifyKey}`,
 | 
			
		||||
          value,
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const fieldColumns: ColumnConfig[] = [
 | 
			
		||||
@ -310,11 +331,9 @@ const addFromJsonFromChange = ({ data }: { data: string }) => {
 | 
			
		||||
  try {
 | 
			
		||||
    const value = JSON.parse(data);
 | 
			
		||||
 | 
			
		||||
    props.model[props.name] = getFieldsConfig(value, props.model[props.name]);
 | 
			
		||||
 | 
			
		||||
    addFromJsonDialogVisible.value = false;
 | 
			
		||||
 | 
			
		||||
    emit('change', props.model[props.name]);
 | 
			
		||||
    emit('change', getFieldsConfig(value, props.model[props.name]));
 | 
			
		||||
  } catch (e: any) {
 | 
			
		||||
    tMagicMessage.error(e.message);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -21,14 +21,17 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { nextTick, ref } from 'vue';
 | 
			
		||||
import { cloneDeep } from 'lodash-es';
 | 
			
		||||
 | 
			
		||||
import type { CodeBlockContent } from '@tmagic/core';
 | 
			
		||||
import { TMagicButton } from '@tmagic/design';
 | 
			
		||||
import type { FieldProps } from '@tmagic/form';
 | 
			
		||||
import { TMagicButton, tMagicMessageBox } from '@tmagic/design';
 | 
			
		||||
import type { ContainerChangeEventData, FieldProps } from '@tmagic/form';
 | 
			
		||||
import { type ColumnConfig, MagicTable } from '@tmagic/table';
 | 
			
		||||
 | 
			
		||||
import CodeBlockEditor from '@editor/components/CodeBlockEditor.vue';
 | 
			
		||||
import { useDataSourceMethod } from '@editor/hooks/use-data-source-method';
 | 
			
		||||
import type { CodeParamStatement } from '@editor/type';
 | 
			
		||||
import { getEditorConfig } from '@editor/utils/config';
 | 
			
		||||
 | 
			
		||||
defineOptions({
 | 
			
		||||
  name: 'MFieldsDataSourceMethods',
 | 
			
		||||
@ -47,7 +50,10 @@ const props = withDefaults(
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change']);
 | 
			
		||||
 | 
			
		||||
const { codeConfig, codeBlockEditor, createCode, editCode, deleteCode, submitCode } = useDataSourceMethod();
 | 
			
		||||
const codeConfig = ref<CodeBlockContent>();
 | 
			
		||||
const codeBlockEditor = ref<InstanceType<typeof CodeBlockEditor>>();
 | 
			
		||||
 | 
			
		||||
let editIndex = -1;
 | 
			
		||||
 | 
			
		||||
const methodColumns: ColumnConfig[] = [
 | 
			
		||||
  {
 | 
			
		||||
@ -73,16 +79,31 @@ const methodColumns: ColumnConfig[] = [
 | 
			
		||||
    actions: [
 | 
			
		||||
      {
 | 
			
		||||
        text: '编辑',
 | 
			
		||||
        handler: (row: CodeBlockContent) => {
 | 
			
		||||
          editCode(props.model, row.name);
 | 
			
		||||
          emit('change', props.model[props.name]);
 | 
			
		||||
        handler: (method: CodeBlockContent, index: number) => {
 | 
			
		||||
          let codeContent = method.content || `({ params, dataSource, app }) => {\n  // place your code here\n}`;
 | 
			
		||||
 | 
			
		||||
          if (typeof codeContent !== 'string') {
 | 
			
		||||
            codeContent = codeContent.toString();
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          codeConfig.value = {
 | 
			
		||||
            ...cloneDeep(method),
 | 
			
		||||
            content: codeContent,
 | 
			
		||||
          };
 | 
			
		||||
 | 
			
		||||
          editIndex = index;
 | 
			
		||||
 | 
			
		||||
          nextTick(() => {
 | 
			
		||||
            codeBlockEditor.value?.show();
 | 
			
		||||
          });
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        text: '删除',
 | 
			
		||||
        buttonType: 'danger',
 | 
			
		||||
        handler: (row: CodeBlockContent) => {
 | 
			
		||||
          deleteCode(props.model, row.name);
 | 
			
		||||
        handler: async (row: CodeBlockContent, index: number) => {
 | 
			
		||||
          await tMagicMessageBox.confirm(`确定删除${row.name}?`, '提示');
 | 
			
		||||
          props.model[props.name].splice(index, 1);
 | 
			
		||||
          emit('change', props.model[props.name]);
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
@ -91,14 +112,51 @@ const methodColumns: ColumnConfig[] = [
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
const createCodeHandler = () => {
 | 
			
		||||
  createCode(props.model);
 | 
			
		||||
  codeConfig.value = {
 | 
			
		||||
    name: '',
 | 
			
		||||
    content: `({ params, dataSource, app, flowState }) => {\n  // place your code here\n}`,
 | 
			
		||||
    params: [],
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  emit('change', props.model[props.name]);
 | 
			
		||||
  editIndex = -1;
 | 
			
		||||
 | 
			
		||||
  nextTick(() => {
 | 
			
		||||
    codeBlockEditor.value?.show();
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const submitCodeHandler = (values: CodeBlockContent) => {
 | 
			
		||||
  submitCode(values);
 | 
			
		||||
const submitCodeHandler = (value: CodeBlockContent, data: ContainerChangeEventData) => {
 | 
			
		||||
  if (value.content) {
 | 
			
		||||
    // 在保存的时候转换代码内容
 | 
			
		||||
    const parseDSL = getEditorConfig('parseDSL');
 | 
			
		||||
    if (typeof value.content === 'string') {
 | 
			
		||||
      value.content = parseDSL<(...args: any[]) => any>(value.content);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (editIndex > -1) {
 | 
			
		||||
    emit('change', value, {
 | 
			
		||||
      modifyKey: editIndex,
 | 
			
		||||
      changeRecords: (data.changeRecords || []).map((item) => ({
 | 
			
		||||
        propPath: `${props.prop}.${editIndex}.${item.propPath}`,
 | 
			
		||||
        value: item.value,
 | 
			
		||||
      })),
 | 
			
		||||
    });
 | 
			
		||||
  } else {
 | 
			
		||||
    const modifyKey = props.model[props.name].length;
 | 
			
		||||
    emit('change', value, {
 | 
			
		||||
      modifyKey,
 | 
			
		||||
      changeRecords: [
 | 
			
		||||
        {
 | 
			
		||||
          propPath: `${props.prop}.${modifyKey}`,
 | 
			
		||||
          value,
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  emit('change', props.model[props.name]);
 | 
			
		||||
  editIndex = -1;
 | 
			
		||||
  codeConfig.value = void 0;
 | 
			
		||||
 | 
			
		||||
  codeBlockEditor.value?.hide();
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@ import { computed, inject } from 'vue';
 | 
			
		||||
 | 
			
		||||
import type { DisplayCond } from '@tmagic/core';
 | 
			
		||||
import {
 | 
			
		||||
  type ContainerChangeEventData,
 | 
			
		||||
  type FieldProps,
 | 
			
		||||
  type FilterFunction,
 | 
			
		||||
  filterFunction,
 | 
			
		||||
@ -33,7 +34,7 @@ defineOptions({
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [value: DisplayCond[]];
 | 
			
		||||
  change: [value: DisplayCond[], eventData?: ContainerChangeEventData];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const props = withDefaults(
 | 
			
		||||
@ -149,7 +150,11 @@ const config = computed<GroupListConfig>(() => ({
 | 
			
		||||
  ],
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const changeHandler = (v: DisplayCond[]) => {
 | 
			
		||||
  emit('change', v);
 | 
			
		||||
const changeHandler = (v: DisplayCond[], eventData?: ContainerChangeEventData) => {
 | 
			
		||||
  if (!Array.isArray(props.model[props.name])) {
 | 
			
		||||
    props.model[props.name] = [];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  emit('change', v, eventData);
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,7 @@
 | 
			
		||||
        :key="index"
 | 
			
		||||
        :disabled="disabled"
 | 
			
		||||
        :size="size"
 | 
			
		||||
        :prop="`${prop}.${index}`"
 | 
			
		||||
        :config="actionsConfig"
 | 
			
		||||
        :model="cardItem"
 | 
			
		||||
        :label-width="config.labelWidth || '100px'"
 | 
			
		||||
@ -32,7 +33,8 @@
 | 
			
		||||
            :model="cardItem"
 | 
			
		||||
            :disabled="disabled"
 | 
			
		||||
            :size="size"
 | 
			
		||||
            @change="onChangeHandler"
 | 
			
		||||
            :prop="`${prop}.${index}`"
 | 
			
		||||
            @change="eventNameChangeHandler"
 | 
			
		||||
          ></MFormContainer>
 | 
			
		||||
          <TMagicButton
 | 
			
		||||
            style="color: #f56c6c"
 | 
			
		||||
@ -56,7 +58,14 @@ import { has } from 'lodash-es';
 | 
			
		||||
import type { EventOption, MComponent, MContainer } from '@tmagic/core';
 | 
			
		||||
import { ActionType } from '@tmagic/core';
 | 
			
		||||
import { TMagicButton } from '@tmagic/design';
 | 
			
		||||
import type { CascaderOption, ChildConfig, FieldProps, FormState, PanelConfig } from '@tmagic/form';
 | 
			
		||||
import type {
 | 
			
		||||
  CascaderOption,
 | 
			
		||||
  ChildConfig,
 | 
			
		||||
  ContainerChangeEventData,
 | 
			
		||||
  FieldProps,
 | 
			
		||||
  FormState,
 | 
			
		||||
  PanelConfig,
 | 
			
		||||
} from '@tmagic/form';
 | 
			
		||||
import { MContainer as MFormContainer, MPanel } from '@tmagic/form';
 | 
			
		||||
import { DATA_SOURCE_FIELDS_CHANGE_EVENT_PREFIX, traverseNode } from '@tmagic/utils';
 | 
			
		||||
 | 
			
		||||
@ -69,7 +78,9 @@ defineOptions({
 | 
			
		||||
 | 
			
		||||
const props = defineProps<FieldProps<EventSelectConfig>>();
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change']);
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [v: any, eventData?: ContainerChangeEventData];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const services = inject<Services>('services');
 | 
			
		||||
 | 
			
		||||
@ -355,21 +366,27 @@ const addEvent = () => {
 | 
			
		||||
    name: '',
 | 
			
		||||
    actions: [],
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  if (!props.model[props.name]) {
 | 
			
		||||
    props.model[props.name] = [];
 | 
			
		||||
  }
 | 
			
		||||
  props.model[props.name].push(defaultEvent);
 | 
			
		||||
  onChangeHandler();
 | 
			
		||||
 | 
			
		||||
  emit('change', defaultEvent, {
 | 
			
		||||
    modifyKey: props.model[props.name].length,
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 删除事件
 | 
			
		||||
const removeEvent = (index: number) => {
 | 
			
		||||
  if (!props.name) return;
 | 
			
		||||
  props.model[props.name].splice(index, 1);
 | 
			
		||||
  onChangeHandler();
 | 
			
		||||
  emit('change', props.model[props.name]);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const onChangeHandler = () => {
 | 
			
		||||
  emit('change', props.model);
 | 
			
		||||
const eventNameChangeHandler = (v: any, eventData: ContainerChangeEventData) => {
 | 
			
		||||
  emit('change', props.model[props.name], eventData);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const onChangeHandler = (v: any, eventData: ContainerChangeEventData) =>
 | 
			
		||||
  emit('change', props.model[props.name], eventData);
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -86,7 +86,9 @@ const props = withDefaults(
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits<(e: 'change', value: Record<string, any>) => void>();
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [value: Record<string, any>];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const records = ref<[string, string][]>([]);
 | 
			
		||||
const showCode = ref(false);
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { provide, reactive, ref, toRaw, watch, watchEffect } from 'vue';
 | 
			
		||||
import { provide, reactive, ref, shallowRef, toRaw, watch, watchEffect } from 'vue';
 | 
			
		||||
import { cloneDeep, isEqual } from 'lodash-es';
 | 
			
		||||
 | 
			
		||||
import { TMagicForm } from '@tmagic/design';
 | 
			
		||||
@ -36,7 +36,7 @@ import { TMagicForm } from '@tmagic/design';
 | 
			
		||||
import Container from './containers/Container.vue';
 | 
			
		||||
import { getConfig } from './utils/config';
 | 
			
		||||
import { initValue } from './utils/form';
 | 
			
		||||
import type { FormConfig, FormState, FormValue, ValidateError } from './schema';
 | 
			
		||||
import type { ChangeRecord, ContainerChangeEventData, FormConfig, FormState, FormValue, ValidateError } from './schema';
 | 
			
		||||
 | 
			
		||||
defineOptions({
 | 
			
		||||
  name: 'MForm',
 | 
			
		||||
@ -81,7 +81,7 @@ const props = withDefaults(
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change', 'error', 'field-input', 'field-change']);
 | 
			
		||||
const emit = defineEmits(['change', 'error', 'field-input', 'field-change', 'update:stepActive']);
 | 
			
		||||
 | 
			
		||||
const tMagicForm = ref<InstanceType<typeof TMagicForm>>();
 | 
			
		||||
const initialized = ref(false);
 | 
			
		||||
@ -135,9 +135,13 @@ watchEffect(async () => {
 | 
			
		||||
 | 
			
		||||
provide('mForm', formState);
 | 
			
		||||
 | 
			
		||||
const changeRecords = shallowRef<ChangeRecord[]>([]);
 | 
			
		||||
 | 
			
		||||
watch(
 | 
			
		||||
  [() => props.config, () => props.initValues],
 | 
			
		||||
  ([config], [preConfig]) => {
 | 
			
		||||
    changeRecords.value = [];
 | 
			
		||||
 | 
			
		||||
    if (!isEqual(toRaw(config), toRaw(preConfig))) {
 | 
			
		||||
      initialized.value = false;
 | 
			
		||||
    }
 | 
			
		||||
@ -165,8 +169,11 @@ watch(
 | 
			
		||||
  { immediate: true },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const changeHandler = () => {
 | 
			
		||||
  emit('change', values.value);
 | 
			
		||||
const changeHandler = (v: FormValue, eventData: ContainerChangeEventData) => {
 | 
			
		||||
  if (eventData.changeRecords?.length) {
 | 
			
		||||
    changeRecords.value.push(...eventData.changeRecords);
 | 
			
		||||
  }
 | 
			
		||||
  emit('change', values.value, eventData);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const submitHandler = (e: SubmitEvent) => {
 | 
			
		||||
@ -180,10 +187,14 @@ defineExpose({
 | 
			
		||||
  lastValuesProcessed,
 | 
			
		||||
  formState,
 | 
			
		||||
  initialized,
 | 
			
		||||
  changeRecords,
 | 
			
		||||
 | 
			
		||||
  changeHandler,
 | 
			
		||||
 | 
			
		||||
  resetForm: () => tMagicForm.value?.resetFields(),
 | 
			
		||||
  resetForm: () => {
 | 
			
		||||
    tMagicForm.value?.resetFields();
 | 
			
		||||
    changeRecords.value = [];
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  submitForm: async (native?: boolean): Promise<any> => {
 | 
			
		||||
    try {
 | 
			
		||||
 | 
			
		||||
@ -40,7 +40,7 @@ import { computed, ref, watchEffect } from 'vue';
 | 
			
		||||
import { TMagicButton, TMagicScrollbar } from '@tmagic/design';
 | 
			
		||||
 | 
			
		||||
import Form from './Form.vue';
 | 
			
		||||
import type { FormConfig } from './schema';
 | 
			
		||||
import type { ContainerChangeEventData, FormConfig, FormValue } from './schema';
 | 
			
		||||
 | 
			
		||||
defineOptions({
 | 
			
		||||
  name: 'MFormBox',
 | 
			
		||||
@ -68,7 +68,11 @@ const props = withDefaults(
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['submit', 'change', 'error']);
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [v: any, eventData: ContainerChangeEventData];
 | 
			
		||||
  submit: [v: any, eventData: ContainerChangeEventData];
 | 
			
		||||
  error: [e: any];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const footerHeight = 60;
 | 
			
		||||
 | 
			
		||||
@ -98,14 +102,14 @@ watchEffect(() => {
 | 
			
		||||
const submitHandler = async () => {
 | 
			
		||||
  try {
 | 
			
		||||
    const values = await form.value?.submitForm();
 | 
			
		||||
    emit('submit', values);
 | 
			
		||||
    emit('submit', values, { changeRecords: form.value?.changeRecords });
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    emit('error', e);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const changeHandler = (value: any) => {
 | 
			
		||||
  emit('change', value);
 | 
			
		||||
const changeHandler = (value: FormValue, eventData: ContainerChangeEventData) => {
 | 
			
		||||
  emit('change', value, eventData);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const show = () => {};
 | 
			
		||||
 | 
			
		||||
@ -65,7 +65,7 @@ import { computed, ref } from 'vue';
 | 
			
		||||
import { TMagicButton, TMagicCol, TMagicDialog, TMagicRow } from '@tmagic/design';
 | 
			
		||||
 | 
			
		||||
import Form from './Form.vue';
 | 
			
		||||
import { FormConfig, StepConfig } from './schema';
 | 
			
		||||
import { ContainerChangeEventData, FormConfig, FormValue, StepConfig } from './schema';
 | 
			
		||||
 | 
			
		||||
defineOptions({
 | 
			
		||||
  name: 'MFormDialog',
 | 
			
		||||
@ -132,7 +132,7 @@ const closeHandler = () => {
 | 
			
		||||
const save = async () => {
 | 
			
		||||
  try {
 | 
			
		||||
    const values = await form.value?.submitForm();
 | 
			
		||||
    emit('submit', values);
 | 
			
		||||
    emit('submit', values, { changeRecords: form.value?.changeRecords });
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    emit('error', e);
 | 
			
		||||
  }
 | 
			
		||||
@ -146,8 +146,8 @@ const nextStep = () => {
 | 
			
		||||
  stepActive.value += 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const changeHandler = (value: any) => {
 | 
			
		||||
  emit('change', value);
 | 
			
		||||
const changeHandler = (value: FormValue, eventData: ContainerChangeEventData) => {
 | 
			
		||||
  emit('change', value, eventData);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const show = () => {
 | 
			
		||||
 | 
			
		||||
@ -59,7 +59,7 @@ import { ref, watchEffect } from 'vue';
 | 
			
		||||
import { TMagicButton, TMagicCol, TMagicDrawer, TMagicRow } from '@tmagic/design';
 | 
			
		||||
 | 
			
		||||
import Form from './Form.vue';
 | 
			
		||||
import type { FormConfig } from './schema';
 | 
			
		||||
import type { ContainerChangeEventData, FormConfig, FormValue } from './schema';
 | 
			
		||||
 | 
			
		||||
defineOptions({
 | 
			
		||||
  name: 'MFormDialog',
 | 
			
		||||
@ -110,14 +110,14 @@ watchEffect(() => {
 | 
			
		||||
const submitHandler = async () => {
 | 
			
		||||
  try {
 | 
			
		||||
    const values = await form.value?.submitForm();
 | 
			
		||||
    emit('submit', values);
 | 
			
		||||
    emit('submit', values, { changeRecords: form.value?.changeRecords });
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    emit('error', e);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const changeHandler = (value: any) => {
 | 
			
		||||
  emit('change', value);
 | 
			
		||||
const changeHandler = (value: FormValue, eventData: ContainerChangeEventData) => {
 | 
			
		||||
  emit('change', value, eventData);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const openHandler = () => {
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,7 @@ import { computed, inject } from 'vue';
 | 
			
		||||
 | 
			
		||||
import { TMagicCol } from '@tmagic/design';
 | 
			
		||||
 | 
			
		||||
import { ChildConfig, FormState } from '../schema';
 | 
			
		||||
import type { ChildConfig, ContainerChangeEventData, FormState } from '../schema';
 | 
			
		||||
import { display as displayFunction } from '../utils/form';
 | 
			
		||||
 | 
			
		||||
import Container from './Container.vue';
 | 
			
		||||
@ -43,10 +43,13 @@ const props = defineProps<{
 | 
			
		||||
  disabled?: boolean;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [v: any, eventData: ContainerChangeEventData];
 | 
			
		||||
  addDiffCount: [];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
const display = computed(() => displayFunction(mForm, props.config.display, props));
 | 
			
		||||
const changeHandler = () => emit('change', props.model);
 | 
			
		||||
const changeHandler = (v: any, eventData: ContainerChangeEventData) => emit('change', v, eventData);
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -191,12 +191,12 @@
 | 
			
		||||
    </template>
 | 
			
		||||
 | 
			
		||||
    <template v-else-if="items && display">
 | 
			
		||||
      <template v-if="name || name === 0 ? model[name] : model">
 | 
			
		||||
      <template v-if="isValidName() ? model[name] : model">
 | 
			
		||||
        <Container
 | 
			
		||||
          v-for="item in items"
 | 
			
		||||
          :key="key(item)"
 | 
			
		||||
          :model="name || name === 0 ? model[name] : model"
 | 
			
		||||
          :last-values="name || name === 0 ? lastValues[name] || {} : lastValues"
 | 
			
		||||
          :model="isValidName() ? model[name] : model"
 | 
			
		||||
          :last-values="isValidName() ? lastValues[name] || {} : lastValues"
 | 
			
		||||
          :is-compare="isCompare"
 | 
			
		||||
          :config="item"
 | 
			
		||||
          :size="size"
 | 
			
		||||
@ -220,13 +220,20 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { computed, inject, ref, watch, watchEffect } from 'vue';
 | 
			
		||||
import { computed, inject, ref, toRaw, watch, watchEffect } from 'vue';
 | 
			
		||||
import { WarningFilled } from '@element-plus/icons-vue';
 | 
			
		||||
import { isEqual } from 'lodash-es';
 | 
			
		||||
 | 
			
		||||
import { TMagicButton, TMagicFormItem, TMagicIcon, TMagicTooltip } from '@tmagic/design';
 | 
			
		||||
 | 
			
		||||
import { ChildConfig, ContainerCommonConfig, FormState, FormValue, TypeFunction } from '../schema';
 | 
			
		||||
import type {
 | 
			
		||||
  ChildConfig,
 | 
			
		||||
  ContainerChangeEventData,
 | 
			
		||||
  ContainerCommonConfig,
 | 
			
		||||
  FormState,
 | 
			
		||||
  FormValue,
 | 
			
		||||
  TypeFunction,
 | 
			
		||||
} from '../schema';
 | 
			
		||||
import { display as displayFunction, filterFunction, getRules } from '../utils/form';
 | 
			
		||||
 | 
			
		||||
defineOptions({
 | 
			
		||||
@ -258,7 +265,10 @@ const props = withDefaults(
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [v: any, eventData: ContainerChangeEventData];
 | 
			
		||||
  addDiffCount: [];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
 | 
			
		||||
@ -285,7 +295,12 @@ const itemProp = computed(() => {
 | 
			
		||||
  } else {
 | 
			
		||||
    return props.prop;
 | 
			
		||||
  }
 | 
			
		||||
  return `${props.prop}${props.prop ? '.' : ''}${n}`;
 | 
			
		||||
 | 
			
		||||
  if (typeof props.prop !== 'undefined' && props.prop !== '') {
 | 
			
		||||
    return `${props.prop}.${n}`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return `${n}`;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const tagName = computed(() => `m-${items.value ? 'form' : 'fields'}-${type.value}`);
 | 
			
		||||
@ -360,18 +375,6 @@ const filterHandler = (filter: any, value: FormValue | number | string) => {
 | 
			
		||||
  return value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const changeHandler = (onChange: any, value: FormValue | number | string) => {
 | 
			
		||||
  if (typeof onChange === 'function') {
 | 
			
		||||
    return onChange(mForm, value, {
 | 
			
		||||
      model: props.model,
 | 
			
		||||
      values: mForm?.initValues,
 | 
			
		||||
      formValue: mForm?.values,
 | 
			
		||||
      prop: itemProp.value,
 | 
			
		||||
      config: props.config,
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const trimHandler = (trim: any, value: FormValue | number | string) => {
 | 
			
		||||
  if (typeof value === 'string' && trim) {
 | 
			
		||||
    return value.replace(/^\s*/, '').replace(/\s*$/, '');
 | 
			
		||||
@ -381,28 +384,80 @@ const trimHandler = (trim: any, value: FormValue | number | string) => {
 | 
			
		||||
// 继续抛出给更高层级的组件
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
 | 
			
		||||
const onChangeHandler = async function (v: FormValue, key?: string) {
 | 
			
		||||
  const { filter, onChange, trim, name, dynamicKey } = props.config as any;
 | 
			
		||||
  let value: FormValue | number | string = v;
 | 
			
		||||
const hasModifyKey = (eventDataItem: ContainerChangeEventData) =>
 | 
			
		||||
  typeof eventDataItem?.modifyKey !== 'undefined' && eventDataItem.modifyKey !== '';
 | 
			
		||||
 | 
			
		||||
const isValidName = () => {
 | 
			
		||||
  const valueType = typeof name.value;
 | 
			
		||||
  if (valueType !== 'string' && valueType !== 'symbol' && valueType !== 'number') {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (name.value === '') {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (typeof name.value === 'number') {
 | 
			
		||||
    return name.value >= 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const onChangeHandler = async function (v: any, eventData: ContainerChangeEventData = {}) {
 | 
			
		||||
  const { filter, onChange, trim, dynamicKey } = props.config as any;
 | 
			
		||||
  let value: FormValue | number | string | any[] = toRaw(v);
 | 
			
		||||
  const changeRecords = eventData.changeRecords || [];
 | 
			
		||||
  const newChangeRecords = [...changeRecords];
 | 
			
		||||
 | 
			
		||||
  try {
 | 
			
		||||
    value = filterHandler(filter, v);
 | 
			
		||||
    value = (await changeHandler(onChange, value)) ?? value;
 | 
			
		||||
 | 
			
		||||
    if (typeof onChange === 'function') {
 | 
			
		||||
      value =
 | 
			
		||||
        (await onChange(mForm, value, {
 | 
			
		||||
          model: props.model,
 | 
			
		||||
          values: mForm?.initValues,
 | 
			
		||||
          formValue: mForm?.values,
 | 
			
		||||
          prop: itemProp.value,
 | 
			
		||||
          config: props.config,
 | 
			
		||||
          changeRecords: newChangeRecords,
 | 
			
		||||
        })) ?? value;
 | 
			
		||||
    }
 | 
			
		||||
    value = trimHandler(trim, value) ?? value;
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    console.error(e);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // field内容下包含field-link时,model===value, 这里避免循环引用
 | 
			
		||||
  if ((name || name === 0) && props.model !== value && (v !== value || props.model[name] !== value)) {
 | 
			
		||||
  let valueProp = itemProp.value;
 | 
			
		||||
 | 
			
		||||
  if (hasModifyKey(eventData)) {
 | 
			
		||||
    if (dynamicKey) {
 | 
			
		||||
      props.model[eventData.modifyKey!] = value;
 | 
			
		||||
    } else if (isValidName()) {
 | 
			
		||||
      props.model[name.value][eventData.modifyKey!] = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    valueProp = valueProp ? `${valueProp}.${eventData.modifyKey}` : eventData.modifyKey!;
 | 
			
		||||
 | 
			
		||||
    // 需要清除掉modifyKey,不然往上层抛出后还会被认为需要修改
 | 
			
		||||
    delete eventData.modifyKey;
 | 
			
		||||
  } else if (isValidName() && props.model !== value && (v !== value || props.model[name.value] !== value)) {
 | 
			
		||||
    // field内容下包含field-link时,model===value, 这里避免循环引用
 | 
			
		||||
    // eslint-disable-next-line vue/no-mutating-props
 | 
			
		||||
    props.model[name] = value;
 | 
			
		||||
    props.model[name.value] = value;
 | 
			
		||||
  }
 | 
			
		||||
  // 动态表单类型,根据value和key参数,直接修改model
 | 
			
		||||
  if (key !== undefined && dynamicKey) {
 | 
			
		||||
    // eslint-disable-next-line vue/no-mutating-props
 | 
			
		||||
    props.model[key] = value;
 | 
			
		||||
 | 
			
		||||
  if (changeRecords.length === 0) {
 | 
			
		||||
    newChangeRecords.push({
 | 
			
		||||
      propPath: valueProp,
 | 
			
		||||
      value,
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  emit('change', props.model);
 | 
			
		||||
 | 
			
		||||
  emit('change', props.model, {
 | 
			
		||||
    ...eventData,
 | 
			
		||||
    changeRecords: newChangeRecords,
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@
 | 
			
		||||
        :prop="`${prop}${prop ? '.' : ''}${config.name}.value`"
 | 
			
		||||
        :true-value="1"
 | 
			
		||||
        :false-value="0"
 | 
			
		||||
        @update:modelValue="change"
 | 
			
		||||
        @update:modelValue="valueChangeHandler"
 | 
			
		||||
        ><span v-html="config.legend"></span><span v-if="config.extra" v-html="config.extra" class="m-form-tip"></span
 | 
			
		||||
      ></TMagicCheckbox>
 | 
			
		||||
    </component>
 | 
			
		||||
@ -29,7 +29,7 @@
 | 
			
		||||
          :disabled="disabled"
 | 
			
		||||
          :labelWidth="lWidth"
 | 
			
		||||
          :size="size"
 | 
			
		||||
          @change="change"
 | 
			
		||||
          @change="changeHandler"
 | 
			
		||||
          @add-diff-count="onAddDiffCount()"
 | 
			
		||||
        ></Container>
 | 
			
		||||
      </div>
 | 
			
		||||
@ -50,7 +50,7 @@
 | 
			
		||||
        :labelWidth="lWidth"
 | 
			
		||||
        :size="size"
 | 
			
		||||
        :disabled="disabled"
 | 
			
		||||
        @change="change"
 | 
			
		||||
        @change="changeHandler"
 | 
			
		||||
        @addDiffCount="onAddDiffCount()"
 | 
			
		||||
      ></Container>
 | 
			
		||||
    </template>
 | 
			
		||||
@ -62,7 +62,7 @@ import { computed, inject } from 'vue';
 | 
			
		||||
 | 
			
		||||
import { TMagicCheckbox } from '@tmagic/design';
 | 
			
		||||
 | 
			
		||||
import { FieldsetConfig, FormState } from '../schema';
 | 
			
		||||
import { ContainerChangeEventData, FieldsetConfig, FormState } from '../schema';
 | 
			
		||||
 | 
			
		||||
import Container from './Container.vue';
 | 
			
		||||
 | 
			
		||||
@ -90,7 +90,10 @@ const props = withDefaults(
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [v: any, eventData: ContainerChangeEventData];
 | 
			
		||||
  addDiffCount: [];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
 | 
			
		||||
@ -110,10 +113,12 @@ const lWidth = computed(() => {
 | 
			
		||||
  return props.config.labelWidth || props.labelWidth || (props.config.text ? undefined : '0');
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const change = () => {
 | 
			
		||||
  emit('change', props.model);
 | 
			
		||||
const valueChangeHandler = (value: number | boolean) => {
 | 
			
		||||
  emit('change', value, { modifyKey: 'value' });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const changeHandler = (v: any, eventData: ContainerChangeEventData) => emit('change', v, eventData);
 | 
			
		||||
 | 
			
		||||
const key = (item: any, index: number) => item[mForm?.keyProp || '__key'] ?? index;
 | 
			
		||||
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,14 @@
 | 
			
		||||
      @addDiffCount="onAddDiffCount()"
 | 
			
		||||
    ></MFieldsGroupListItem>
 | 
			
		||||
 | 
			
		||||
    <TMagicButton @click="addHandler" type="primary" :disabled="disabled" v-if="addable">新增</TMagicButton>
 | 
			
		||||
    <TMagicButton
 | 
			
		||||
      v-if="addable"
 | 
			
		||||
      type="primary"
 | 
			
		||||
      :size="config.enableToggleMode ? 'small' : 'default'"
 | 
			
		||||
      :disabled="disabled"
 | 
			
		||||
      @click="addHandler"
 | 
			
		||||
      >新增</TMagicButton
 | 
			
		||||
    >
 | 
			
		||||
 | 
			
		||||
    <TMagicButton :icon="Grid" size="small" @click="toggleMode" v-if="config.enableToggleMode">切换为表格</TMagicButton>
 | 
			
		||||
  </div>
 | 
			
		||||
@ -37,7 +44,7 @@ import { Grid } from '@element-plus/icons-vue';
 | 
			
		||||
 | 
			
		||||
import { TMagicButton } from '@tmagic/design';
 | 
			
		||||
 | 
			
		||||
import { FormState, GroupListConfig } from '../schema';
 | 
			
		||||
import type { ContainerChangeEventData, FormState, GroupListConfig } from '../schema';
 | 
			
		||||
import { initValue } from '../utils/form';
 | 
			
		||||
 | 
			
		||||
import MFieldsGroupListItem from './GroupListItem.vue';
 | 
			
		||||
@ -58,7 +65,10 @@ const props = defineProps<{
 | 
			
		||||
  disabled?: boolean;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [v: any, eventData?: ContainerChangeEventData];
 | 
			
		||||
  addDiffCount: [];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
 | 
			
		||||
@ -77,10 +87,8 @@ const addable = computed(() => {
 | 
			
		||||
  return typeof props.config.addable === 'undefined' ? true : props.config.addable;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const changeHandler = () => {
 | 
			
		||||
  if (!props.name) return false;
 | 
			
		||||
 | 
			
		||||
  emit('change', props.model[props.name]);
 | 
			
		||||
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
 | 
			
		||||
  emit('change', props.model, eventData);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const addHandler = async () => {
 | 
			
		||||
@ -105,14 +113,22 @@ const addHandler = async () => {
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  props.model[props.name].push(groupValue);
 | 
			
		||||
  changeHandler();
 | 
			
		||||
 | 
			
		||||
  emit('change', props.model[props.name], {
 | 
			
		||||
    changeRecords: [
 | 
			
		||||
      {
 | 
			
		||||
        propPath: `${props.prop}.${props.model[props.name].length - 1}`,
 | 
			
		||||
        value: groupValue,
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const removeHandler = (index: number) => {
 | 
			
		||||
  if (!props.name) return false;
 | 
			
		||||
 | 
			
		||||
  props.model[props.name].splice(index, 1);
 | 
			
		||||
  changeHandler();
 | 
			
		||||
  emit('change', props.model[props.name]);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const swapHandler = (idx1: number, idx2: number) => {
 | 
			
		||||
@ -120,7 +136,7 @@ const swapHandler = (idx1: number, idx2: number) => {
 | 
			
		||||
 | 
			
		||||
  const [currRow] = props.model[props.name].splice(idx1, 1);
 | 
			
		||||
  props.model[props.name].splice(idx2, 0, currRow);
 | 
			
		||||
  changeHandler();
 | 
			
		||||
  emit('change', props.model[props.name]);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const toggleMode = () => {
 | 
			
		||||
 | 
			
		||||
@ -48,7 +48,7 @@ import { CaretBottom, CaretRight, CaretTop, Delete } from '@element-plus/icons-v
 | 
			
		||||
 | 
			
		||||
import { TMagicButton, TMagicIcon } from '@tmagic/design';
 | 
			
		||||
 | 
			
		||||
import { FormState, GroupListConfig } from '../schema';
 | 
			
		||||
import type { ContainerChangeEventData, FormState, GroupListConfig } from '../schema';
 | 
			
		||||
import { filterFunction } from '../utils/form';
 | 
			
		||||
 | 
			
		||||
import Container from './Container.vue';
 | 
			
		||||
@ -103,7 +103,9 @@ const itemExtra = computed(() => filterFunction(mForm, props.config.itemExtra, p
 | 
			
		||||
 | 
			
		||||
const removeHandler = () => emit('remove-item', props.index);
 | 
			
		||||
 | 
			
		||||
const changeHandler = () => emit('change');
 | 
			
		||||
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
 | 
			
		||||
  emit('change', props.model, eventData);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const expandHandler = () => {
 | 
			
		||||
  expand.value = !expand.value;
 | 
			
		||||
 | 
			
		||||
@ -63,7 +63,7 @@ import { CaretBottom, CaretRight } from '@element-plus/icons-vue';
 | 
			
		||||
 | 
			
		||||
import { TMagicButton, TMagicCard } from '@tmagic/design';
 | 
			
		||||
 | 
			
		||||
import { FormState, PanelConfig } from '../schema';
 | 
			
		||||
import type { ContainerChangeEventData, FormState, PanelConfig } from '../schema';
 | 
			
		||||
import { filterFunction } from '../utils/form';
 | 
			
		||||
 | 
			
		||||
import Container from './Container.vue';
 | 
			
		||||
@ -84,7 +84,10 @@ const props = defineProps<{
 | 
			
		||||
  disabled?: boolean;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [v: any, eventData: ContainerChangeEventData];
 | 
			
		||||
  addDiffCount: [];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
 | 
			
		||||
@ -94,6 +97,8 @@ const items = computed(() => props.config.items);
 | 
			
		||||
 | 
			
		||||
const filter = (config: any) => filterFunction(mForm, config, props);
 | 
			
		||||
 | 
			
		||||
const changeHandler = () => emit('change', props.model);
 | 
			
		||||
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
 | 
			
		||||
  emit('change', props.model, eventData);
 | 
			
		||||
};
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,7 @@ import { inject } from 'vue';
 | 
			
		||||
 | 
			
		||||
import { TMagicRow } from '@tmagic/design';
 | 
			
		||||
 | 
			
		||||
import { FormState, RowConfig } from '../schema';
 | 
			
		||||
import type { ContainerChangeEventData, FormState, RowConfig } from '../schema';
 | 
			
		||||
 | 
			
		||||
import Col from './Col.vue';
 | 
			
		||||
 | 
			
		||||
@ -45,10 +45,15 @@ const props = defineProps<{
 | 
			
		||||
  disabled?: boolean;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [v: any, eventData: ContainerChangeEventData];
 | 
			
		||||
  addDiffCount: [];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
 | 
			
		||||
const changeHandler = () => emit('change', props.name ? props.model[props.name] : props.model);
 | 
			
		||||
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
 | 
			
		||||
  emit('change', props.name ? props.model[props.name] : props.model, eventData);
 | 
			
		||||
};
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -37,7 +37,7 @@ import { inject, ref, watchEffect } from 'vue';
 | 
			
		||||
 | 
			
		||||
import { TMagicStep, TMagicSteps } from '@tmagic/design';
 | 
			
		||||
 | 
			
		||||
import { FormState, StepConfig } from '../schema';
 | 
			
		||||
import type { ContainerChangeEventData, FormState, StepConfig } from '../schema';
 | 
			
		||||
 | 
			
		||||
import Container from './Container.vue';
 | 
			
		||||
 | 
			
		||||
@ -48,6 +48,7 @@ defineOptions({
 | 
			
		||||
const props = withDefaults(
 | 
			
		||||
  defineProps<{
 | 
			
		||||
    model: any;
 | 
			
		||||
    name?: string;
 | 
			
		||||
    lastValues?: any;
 | 
			
		||||
    isCompare?: boolean;
 | 
			
		||||
    config: StepConfig;
 | 
			
		||||
@ -61,7 +62,10 @@ const props = withDefaults(
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [v: any, eventData: ContainerChangeEventData];
 | 
			
		||||
  addDiffCount: [];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
const active = ref(1);
 | 
			
		||||
@ -75,8 +79,9 @@ const stepClick = (index: number) => {
 | 
			
		||||
  mForm?.$emit('update:stepActive', active.value);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const changeHandler = () => {
 | 
			
		||||
  emit('change', props.model);
 | 
			
		||||
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
 | 
			
		||||
  emit('change', props.model, eventData);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -113,7 +113,7 @@
 | 
			
		||||
                    :lastValues="lastData[scope.$index]"
 | 
			
		||||
                    :is-compare="isCompare"
 | 
			
		||||
                    :size="size"
 | 
			
		||||
                    @change="$emit('change', model[modelName])"
 | 
			
		||||
                    @change="changeHandler"
 | 
			
		||||
                    @addDiffCount="onAddDiffCount()"
 | 
			
		||||
                  ></Container>
 | 
			
		||||
                </template>
 | 
			
		||||
@ -206,7 +206,7 @@ import {
 | 
			
		||||
} from '@tmagic/design';
 | 
			
		||||
import { asyncLoadJs, sleep } from '@tmagic/utils';
 | 
			
		||||
 | 
			
		||||
import { FormState, SortProp, TableColumnConfig, TableConfig } from '../schema';
 | 
			
		||||
import type { ContainerChangeEventData, FormState, SortProp, TableColumnConfig, TableConfig } from '../schema';
 | 
			
		||||
import { display as displayFunc, initValue } from '../utils/form';
 | 
			
		||||
 | 
			
		||||
import Container from './Container.vue';
 | 
			
		||||
@ -395,7 +395,15 @@ const newHandler = async (row?: any) => {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  props.model[modelName.value].push(inputs);
 | 
			
		||||
  emit('change', props.model[modelName.value]);
 | 
			
		||||
 | 
			
		||||
  emit('change', props.model[modelName.value], {
 | 
			
		||||
    changeRecords: [
 | 
			
		||||
      {
 | 
			
		||||
        propPath: `${props.prop}.${props.model[modelName.value].length - 1}`,
 | 
			
		||||
        value: inputs,
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
@ -644,6 +652,10 @@ const getProp = (index: number) => {
 | 
			
		||||
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
 | 
			
		||||
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
 | 
			
		||||
  emit('change', props.model, eventData);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
defineExpose({
 | 
			
		||||
  toggleRowSelection,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@ -71,12 +71,12 @@
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { computed, inject, ref, watchEffect } from 'vue';
 | 
			
		||||
import { cloneDeep, isEmpty } from 'lodash-es';
 | 
			
		||||
import { isEmpty } from 'lodash-es';
 | 
			
		||||
 | 
			
		||||
import { getDesignConfig, TMagicBadge } from '@tmagic/design';
 | 
			
		||||
 | 
			
		||||
import { FormState, TabConfig, TabPaneConfig } from '../schema';
 | 
			
		||||
import { display as displayFunc, filterFunction } from '../utils/form';
 | 
			
		||||
import type { ContainerChangeEventData, FormState, TabConfig, TabPaneConfig } from '../schema';
 | 
			
		||||
import { display as displayFunc, filterFunction, initValue } from '../utils/form';
 | 
			
		||||
 | 
			
		||||
import Container from './Container.vue';
 | 
			
		||||
 | 
			
		||||
@ -137,7 +137,10 @@ const props = withDefaults(
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  change: [v: any, eventData?: ContainerChangeEventData];
 | 
			
		||||
  addDiffCount: [];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
const activeTabName = ref(getActive(mForm, props, ''));
 | 
			
		||||
@ -166,8 +169,8 @@ const tabItems = (tab: TabPaneConfig) => (props.config.dynamic ? props.config.it
 | 
			
		||||
 | 
			
		||||
const tabClickHandler = (tab: any) => tabClick(mForm, tab, props);
 | 
			
		||||
 | 
			
		||||
const onTabAdd = () => {
 | 
			
		||||
  if (!props.config.name) throw new Error('dynamic tab 必须配置name');
 | 
			
		||||
const onTabAdd = async () => {
 | 
			
		||||
  if (!props.name) throw new Error('dynamic tab 必须配置name');
 | 
			
		||||
 | 
			
		||||
  if (typeof props.config.onTabAdd === 'function') {
 | 
			
		||||
    props.config.onTabAdd(mForm, {
 | 
			
		||||
@ -175,17 +178,32 @@ const onTabAdd = () => {
 | 
			
		||||
      prop: props.prop,
 | 
			
		||||
      config: props.config,
 | 
			
		||||
    });
 | 
			
		||||
  } else if (tabs.value.length > 0) {
 | 
			
		||||
    const newObj = cloneDeep(tabs.value[0]);
 | 
			
		||||
    emit('change', props.model);
 | 
			
		||||
  } else {
 | 
			
		||||
    const newObj = await initValue(mForm, {
 | 
			
		||||
      config: props.config.items,
 | 
			
		||||
      initValues: {},
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    newObj.title = `标签${tabs.value.length + 1}`;
 | 
			
		||||
    props.model[props.config.name].push(newObj);
 | 
			
		||||
 | 
			
		||||
    props.model[props.name].push(newObj);
 | 
			
		||||
 | 
			
		||||
    emit('change', props.model[props.name], {
 | 
			
		||||
      changeRecords: [
 | 
			
		||||
        {
 | 
			
		||||
          propPath: `${props.prop}.${props.model[props.name].length - 1}`,
 | 
			
		||||
          value: newObj,
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  emit('change', props.model);
 | 
			
		||||
  mForm?.$emit('field-change', props.prop, props.model[props.config.name]);
 | 
			
		||||
 | 
			
		||||
  mForm?.$emit('field-change', props.prop, props.model[props.name]);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const onTabRemove = (tabName: string) => {
 | 
			
		||||
  if (!props.config.name) throw new Error('dynamic tab 必须配置name');
 | 
			
		||||
  if (!props.name) throw new Error('dynamic tab 必须配置name');
 | 
			
		||||
 | 
			
		||||
  if (typeof props.config.onTabRemove === 'function') {
 | 
			
		||||
    props.config.onTabRemove(mForm, tabName, {
 | 
			
		||||
@ -194,23 +212,20 @@ const onTabRemove = (tabName: string) => {
 | 
			
		||||
      config: props.config,
 | 
			
		||||
    });
 | 
			
		||||
  } else {
 | 
			
		||||
    props.model[props.config.name].splice(+tabName, 1);
 | 
			
		||||
    props.model[props.name].splice(+tabName, 1);
 | 
			
		||||
 | 
			
		||||
    // 防止删除后没有选中的问题
 | 
			
		||||
    if (tabName < activeTabName.value || activeTabName.value >= props.model[props.config.name].length) {
 | 
			
		||||
    if (tabName < activeTabName.value || activeTabName.value >= props.model[props.name].length) {
 | 
			
		||||
      activeTabName.value = (+activeTabName.value - 1).toString();
 | 
			
		||||
      tabClick(mForm, { name: activeTabName.value }, props);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  emit('change', props.model);
 | 
			
		||||
  mForm?.$emit('field-change', props.prop, props.model[props.config.name]);
 | 
			
		||||
  mForm?.$emit('field-change', props.prop, props.model[props.name]);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const changeHandler = () => {
 | 
			
		||||
  emit('change', props.model);
 | 
			
		||||
  if (typeof props.config.onChange === 'function') {
 | 
			
		||||
    props.config.onChange(mForm, { model: props.model, prop: props.prop, config: props.config });
 | 
			
		||||
  }
 | 
			
		||||
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
 | 
			
		||||
  emit('change', props.model, eventData);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 在tabs组件中收集事件触发次数,即该tab下的差异数
 | 
			
		||||
 | 
			
		||||
@ -59,7 +59,7 @@ const changeFieldMap = async () => {
 | 
			
		||||
    let oldVal = props.model?.[v.name] || '';
 | 
			
		||||
    if (!oldVal && v.defaultValue !== undefined) {
 | 
			
		||||
      oldVal = v.defaultValue;
 | 
			
		||||
      emit('change', oldVal, v.name);
 | 
			
		||||
      emit('change', oldVal, { modifyKey: v.name });
 | 
			
		||||
    }
 | 
			
		||||
    fieldMap.value[v.name] = oldVal;
 | 
			
		||||
    fieldLabelMap.value[v.name] = v.label || '';
 | 
			
		||||
@ -85,6 +85,8 @@ onBeforeUnmount(() => {
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const inputChangeHandler = (key: string) => {
 | 
			
		||||
  emit('change', fieldMap.value[key], key);
 | 
			
		||||
  emit('change', fieldMap.value[key], {
 | 
			
		||||
    modifyKey: key,
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,16 @@ export interface ValidateError {
 | 
			
		||||
  field: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ChangeRecord {
 | 
			
		||||
  propPath?: string;
 | 
			
		||||
  value: any;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ContainerChangeEventData {
 | 
			
		||||
  modifyKey?: string;
 | 
			
		||||
  changeRecords?: ChangeRecord[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface FieldProps<T = any> {
 | 
			
		||||
  config: T;
 | 
			
		||||
  model: any;
 | 
			
		||||
@ -157,34 +167,34 @@ export interface Input {
 | 
			
		||||
export type TypeFunction = (
 | 
			
		||||
  mForm: FormState | undefined,
 | 
			
		||||
  data: {
 | 
			
		||||
    model: Record<any, any>;
 | 
			
		||||
    model: FormValue;
 | 
			
		||||
  },
 | 
			
		||||
) => string;
 | 
			
		||||
 | 
			
		||||
export type FilterFunction<T = boolean> = (
 | 
			
		||||
  mForm: FormState | undefined,
 | 
			
		||||
  data: {
 | 
			
		||||
    model: Record<any, any>;
 | 
			
		||||
    values: Record<any, any>;
 | 
			
		||||
    parent?: Record<any, any>;
 | 
			
		||||
    formValue: Record<any, any>;
 | 
			
		||||
    model: FormValue;
 | 
			
		||||
    values: FormValue;
 | 
			
		||||
    parent?: FormValue;
 | 
			
		||||
    formValue: FormValue;
 | 
			
		||||
    prop: string;
 | 
			
		||||
    config: any;
 | 
			
		||||
    index?: number;
 | 
			
		||||
  },
 | 
			
		||||
) => T;
 | 
			
		||||
 | 
			
		||||
type OnChangeHandler = (
 | 
			
		||||
  mForm: FormState | undefined,
 | 
			
		||||
  value: any,
 | 
			
		||||
  data: {
 | 
			
		||||
    model: Record<any, any>;
 | 
			
		||||
    values: Record<any, any>;
 | 
			
		||||
    parent?: Record<any, any>;
 | 
			
		||||
    formValue: Record<any, any>;
 | 
			
		||||
    config: any;
 | 
			
		||||
  },
 | 
			
		||||
) => any;
 | 
			
		||||
export interface OnChangeHandlerData {
 | 
			
		||||
  model: FormValue;
 | 
			
		||||
  values?: FormValue;
 | 
			
		||||
  parent?: FormValue;
 | 
			
		||||
  formValue?: FormValue;
 | 
			
		||||
  config: any;
 | 
			
		||||
  prop: string;
 | 
			
		||||
  changeRecords: ChangeRecord[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type OnChangeHandler = (mForm: FormState | undefined, value: any, data: OnChangeHandlerData) => any;
 | 
			
		||||
 | 
			
		||||
type DefaultValueFunction = (mForm: FormState | undefined) => any;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -152,6 +152,7 @@ const dsl: MApp = {
 | 
			
		||||
          text: 'Tmagic editor 营销活动编辑器',
 | 
			
		||||
          multiple: true,
 | 
			
		||||
          events: [],
 | 
			
		||||
          displayConds: [],
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          type: 'qrcode',
 | 
			
		||||
@ -176,6 +177,7 @@ const dsl: MApp = {
 | 
			
		||||
          url: 'https://github.com/Tencent/tmagic-editor',
 | 
			
		||||
          events: [],
 | 
			
		||||
          created: [],
 | 
			
		||||
          displayConds: [],
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          type: 'img',
 | 
			
		||||
@ -201,6 +203,7 @@ const dsl: MApp = {
 | 
			
		||||
          url: '',
 | 
			
		||||
          events: [],
 | 
			
		||||
          created: [],
 | 
			
		||||
          displayConds: [],
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          type: 'button',
 | 
			
		||||
@ -245,6 +248,7 @@ const dsl: MApp = {
 | 
			
		||||
            },
 | 
			
		||||
          ],
 | 
			
		||||
          created: [],
 | 
			
		||||
          displayConds: [],
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          type: 'overlay',
 | 
			
		||||
@ -479,14 +483,6 @@ const dsl: MApp = {
 | 
			
		||||
      afterResponse: '',
 | 
			
		||||
    },
 | 
			
		||||
  ],
 | 
			
		||||
  dataSourceDeps: {
 | 
			
		||||
    ds_b64c92b5: {
 | 
			
		||||
      button_430: {
 | 
			
		||||
        name: '按钮',
 | 
			
		||||
        keys: ['text'],
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default dsl;
 | 
			
		||||
 | 
			
		||||
@ -189,6 +189,25 @@ export default createForm([
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    type: 'tab',
 | 
			
		||||
    name: 'tab',
 | 
			
		||||
    editable: true,
 | 
			
		||||
    dynamic: true,
 | 
			
		||||
    active: '0',
 | 
			
		||||
    tabType: 'border-card',
 | 
			
		||||
    items: [
 | 
			
		||||
      {
 | 
			
		||||
        name: 'xx',
 | 
			
		||||
        items: [
 | 
			
		||||
          {
 | 
			
		||||
            name: 'text',
 | 
			
		||||
            text: 'text',
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    type: 'table',
 | 
			
		||||
    name: 'table',
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user