From 3c41091f963941019cbfb0df75a92a500e14e78c Mon Sep 17 00:00:00 2001 From: roymondchen Date: Fri, 24 Apr 2026 15:45:15 +0800 Subject: [PATCH] =?UTF-8?q?refactor(form):=20=E9=87=8D=E6=9E=84=20table/gr?= =?UTF-8?q?oup-list=20=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=E4=B8=8E?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=A1=8C=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 table 相关文件迁移至 containers/table 与 containers/table-group-list 目录 - 将新增行处理统一上移至 TableGroupList,通过 add 事件触发 - 抽取 TableGroupListCommonConfig 公共配置类型 - useFullscreen 内聚管理 zIndex - TableColumnConfig 支持 text 作为 label 别名 Made-with: Cursor --- .../editor/src/utils/data-source/index.ts | 12 ++-- packages/form-schema/src/base.ts | 64 ++++++++----------- packages/form/src/containers/GroupList.vue | 57 +---------------- .../{ => table-group-list}/TableGroupList.vue | 50 ++++++--------- .../table-group-list}/useAdd.ts | 40 ++++++++++-- .../{ => containers}/table/ActionsColumn.vue | 2 +- .../src/{ => containers}/table/SortColumn.vue | 0 .../form/src/{ => containers}/table/Table.vue | 26 +++----- .../form/src/{ => containers}/table/type.ts | 0 .../src/containers/table/useFullscreen.ts | 31 +++++++++ .../src/{ => containers}/table/useImport.ts | 7 +- .../{ => containers}/table/usePagination.ts | 2 +- .../{ => containers}/table/useSelection.ts | 0 .../src/{ => containers}/table/useSortable.ts | 2 +- .../{ => containers}/table/useTableColumns.ts | 13 ++-- packages/form/src/index.ts | 6 +- packages/form/src/plugin.ts | 2 +- packages/form/src/table/useFullscreen.ts | 18 ------ 18 files changed, 148 insertions(+), 184 deletions(-) rename packages/form/src/containers/{ => table-group-list}/TableGroupList.vue (83%) rename packages/form/src/{table => containers/table-group-list}/useAdd.ts (68%) rename packages/form/src/{ => containers}/table/ActionsColumn.vue (98%) rename packages/form/src/{ => containers}/table/SortColumn.vue (100%) rename packages/form/src/{ => containers}/table/Table.vue (87%) rename packages/form/src/{ => containers}/table/type.ts (100%) create mode 100644 packages/form/src/containers/table/useFullscreen.ts rename packages/form/src/{ => containers}/table/useImport.ts (90%) rename packages/form/src/{ => containers}/table/usePagination.ts (93%) rename packages/form/src/{ => containers}/table/useSelection.ts (100%) rename packages/form/src/{ => containers}/table/useSortable.ts (97%) rename packages/form/src/{ => containers}/table/useTableColumns.ts (95%) delete mode 100644 packages/form/src/table/useFullscreen.ts diff --git a/packages/editor/src/utils/data-source/index.ts b/packages/editor/src/utils/data-source/index.ts index 35a0a541..e43be06a 100644 --- a/packages/editor/src/utils/data-source/index.ts +++ b/packages/editor/src/utils/data-source/index.ts @@ -1,11 +1,11 @@ import type { DataSchema, DataSourceFieldType, DataSourceSchema } from '@tmagic/core'; -import { type CascaderOption, defineFormItem, type FormConfig } from '@tmagic/form'; +import { type CascaderOption, type FormConfig, type TabConfig } from '@tmagic/form'; import { dataSourceTemplateRegExp, getKeysArray, isNumber } from '@tmagic/utils'; import BaseFormConfig from './formConfigs/base'; import HttpFormConfig from './formConfigs/http'; -const dataSourceFormConfig = defineFormItem({ +const dataSourceFormConfig: TabConfig = { type: 'tab', items: [ { @@ -73,9 +73,13 @@ const dataSourceFormConfig = defineFormItem({ ], }, ], -}); +}; -const fillConfig = (config: FormConfig): FormConfig => [...BaseFormConfig(), ...config, dataSourceFormConfig]; +const fillConfig = (config: FormConfig): FormConfig => [ + ...BaseFormConfig(), + ...config, + dataSourceFormConfig, +]; export const getFormConfig = (type: string, configs: Record): FormConfig => { switch (type) { diff --git a/packages/form-schema/src/base.ts b/packages/form-schema/src/base.ts index 28427e4a..f13cf8fb 100644 --- a/packages/form-schema/src/base.ts +++ b/packages/form-schema/src/base.ts @@ -701,28 +701,43 @@ export interface PanelConfig extends FormItem, ContainerCommonConfig< schematic?: string; } -export interface TableColumnConfig extends FormItem { +export interface TableGroupListCommonConfig extends FormItem { + type: 'table' | 'groupList' | 'group-list'; + enableToggleMode?: boolean; + /** 最大行数 */ + max?: number; + enum?: any[]; + /** 是否显示添加按钮 */ + addable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean; + /** 新增的默认行,可以是函数动态生成或静态对象 */ + defaultAdd?: ((mForm: FormState | undefined, data: any) => any) | Record; + /** table 新增行时前置回调 */ + beforeAddRow?: (mForm: FormState | undefined, data: any) => boolean | Promise; +} + +export interface TableColumnConfig extends FormItem { name?: string; - label: string; + label?: string; + text?: string; width?: string | number; sortable?: boolean; - items?: FormConfig; - itemsFunction?: (row: any) => FormConfig; + items?: FormConfig; + itemsFunction?: (row: any) => FormConfig; titleTip?: FilterFunction; type?: string; + addButtonConfig?: { + props?: Record; + text?: string; + }; } /** * 表格容器 */ -export interface TableConfig extends FormItem { - type: 'table' | 'groupList' | 'group-list'; - items: TableColumnConfig[]; - tableItems?: TableColumnConfig[]; - groupItems?: TableColumnConfig[]; - enableToggleMode?: boolean; - /** 最大行数 */ - max?: number; +export interface TableConfig extends TableGroupListCommonConfig { + items: TableColumnConfig[]; + tableItems?: TableColumnConfig[]; + groupItems?: TableColumnConfig[]; /** 最大高度 */ maxHeight?: number | string; border?: boolean; @@ -731,9 +746,6 @@ export interface TableConfig extends FormItem { /** 操作栏宽度 */ operateColWidth?: number | string; pagination?: boolean; - enum?: any[]; - /** 是否显示添加按钮 */ - addable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean; /** 是否显示删除按钮 */ delete?: (model: any, index: number, values: any) => boolean | boolean; copyable?: (model: any, data: any) => boolean | boolean; @@ -741,8 +753,6 @@ export interface TableConfig extends FormItem { importable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean; /** 是否显示checkbox */ selection?: (mForm: FormState | undefined, data: any) => boolean | boolean | 'single'; - /** 新增的默认行,可以是函数动态生成或静态对象 */ - defaultAdd?: ((mForm: FormState | undefined, data: any) => any) | Record; copyHandler?: (mForm: FormState | undefined, data: any) => any; onSelect?: (mForm: FormState | undefined, data: any) => any; /** @deprecated 请使用 defaultSort */ @@ -760,20 +770,12 @@ export interface TableConfig extends FormItem { itemExtra?: string | FilterFunction; titleTip?: FilterFunction; rowKey?: string; - /** table 新增行时前置回调 */ - beforeAddRow?: (mForm: FormState | undefined, data: any) => boolean | Promise; - addButtonConfig?: { - props?: Record; - text?: string; - }; sort?: boolean; sortKey?: string; } -export interface GroupListConfig extends FormItem { - type: 'table' | 'groupList' | 'group-list'; +export interface GroupListConfig extends TableGroupListCommonConfig { span?: number; - enableToggleMode?: boolean; items: FormConfig; groupItems?: FormConfig; tableItems?: FormConfig; @@ -788,9 +790,6 @@ export interface GroupListConfig extends FormItem { * 当未设置时,默认展开第一项 */ defaultExpandQuantity?: number; - addable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean; - /** 新增的默认值,可以是函数动态生成或静态对象 */ - defaultAdd?: ((mForm: FormState | undefined, data: any) => any) | Record; delete?: (model: any, index: number | string | symbol, values: any) => boolean | boolean; copyable?: FilterFunction; movable?: ( @@ -800,13 +799,6 @@ export interface GroupListConfig extends FormItem { groupModel: any, ) => boolean | boolean; moveSpecifyLocation?: boolean; - addButtonConfig?: { - props?: Record; - text?: string; - }; - /** 最大行数 */ - max?: number; - beforeAddRow?: (mForm: FormState | undefined, data: any) => boolean; } interface StepItemConfig extends FormItem, ContainerCommonConfig { diff --git a/packages/form/src/containers/GroupList.vue b/packages/form/src/containers/GroupList.vue index 5fbd5461..1ef70cef 100644 --- a/packages/form/src/containers/GroupList.vue +++ b/packages/form/src/containers/GroupList.vue @@ -29,20 +29,16 @@ diff --git a/packages/form/src/table/useAdd.ts b/packages/form/src/containers/table-group-list/useAdd.ts similarity index 68% rename from packages/form/src/table/useAdd.ts rename to packages/form/src/containers/table-group-list/useAdd.ts index e95fefc3..83928f0c 100644 --- a/packages/form/src/table/useAdd.ts +++ b/packages/form/src/containers/table-group-list/useAdd.ts @@ -1,18 +1,43 @@ -import { inject } from 'vue'; +import { computed, inject } from 'vue'; import { tMagicMessage } from '@tmagic/design'; -import type { FormConfig, FormState } from '@tmagic/form-schema'; +import type { FormConfig, FormState, TableConfig, TableGroupListCommonConfig } from '@tmagic/form-schema'; -import { initValue } from '../utils/form'; - -import type { TableProps } from './type'; +import { initValue } from '../../utils/form'; +import type { TableProps } from '../table/type'; export const useAdd = ( - props: TableProps, - emit: (event: 'select' | 'change' | 'addDiffCount', ...args: any[]) => void, + props: Pick & { + config: Pick & + Pick & { + items: { name?: string | number }[]; + }; + }, + emit: (event: 'change', ...args: any[]) => void, ) => { const mForm = inject('mForm'); + const addable = computed(() => { + const modelName = props.name || props.config.name || ''; + + if (!modelName) return false; + + if (!props.model[modelName].length) { + return true; + } + + if (typeof props.config.addable === 'function') { + return props.config.addable(mForm, { + model: props.model[modelName], + formValue: mForm?.values, + prop: props.prop, + config: props.config, + }); + } + + return typeof props.config.addable === 'undefined' ? true : props.config.addable; + }); + const newHandler = async (row?: any) => { const modelName = props.name || props.config.name || ''; @@ -91,6 +116,7 @@ export const useAdd = ( }; return { + addable, newHandler, }; }; diff --git a/packages/form/src/table/ActionsColumn.vue b/packages/form/src/containers/table/ActionsColumn.vue similarity index 98% rename from packages/form/src/table/ActionsColumn.vue rename to packages/form/src/containers/table/ActionsColumn.vue index 51dbf6e9..636954aa 100644 --- a/packages/form/src/table/ActionsColumn.vue +++ b/packages/form/src/containers/table/ActionsColumn.vue @@ -38,7 +38,7 @@ import { cloneDeep } from 'lodash-es'; import { TMagicButton, TMagicTooltip } from '@tmagic/design'; -import type { FormState, TableConfig } from '../schema'; +import type { FormState, TableConfig } from '../../schema'; const emit = defineEmits(['change']); diff --git a/packages/form/src/table/SortColumn.vue b/packages/form/src/containers/table/SortColumn.vue similarity index 100% rename from packages/form/src/table/SortColumn.vue rename to packages/form/src/containers/table/SortColumn.vue diff --git a/packages/form/src/table/Table.vue b/packages/form/src/containers/table/Table.vue similarity index 87% rename from packages/form/src/table/Table.vue rename to packages/form/src/containers/table/Table.vue index ffcf8e03..51af437d 100644 --- a/packages/form/src/table/Table.vue +++ b/packages/form/src/containers/table/Table.vue @@ -58,7 +58,7 @@ >清空 - +
@@ -80,16 +80,15 @@