From 1cd69b33fecd75fe8522d9a261e1c03e806ecf69 Mon Sep 17 00:00:00 2001 From: roymondchen Date: Tue, 2 Jun 2026 17:03:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(editor):=20=E5=AF=B9=E6=AF=94=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=20loadCo?= =?UTF-8?q?nfig=20=E5=8A=A0=E8=BD=BD=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 CompareCategory 等类型抽取到 type.ts, 新增 CompareFormLoadConfig 支持外部接管表单配置加载, HistoryDiffDialog 透传 loadConfig 并支持 width 配置及对外导出。 --- .../editor/src/components/CompareForm.vue | 51 ++++++++++++------- packages/editor/src/index.ts | 1 + .../history-list/HistoryDiffDialog.vue | 33 ++++++++---- packages/editor/src/type.ts | 34 +++++++++++++ 4 files changed, 90 insertions(+), 29 deletions(-) diff --git a/packages/editor/src/components/CompareForm.vue b/packages/editor/src/components/CompareForm.vue index 91ce9b94..e9c3d423 100644 --- a/packages/editor/src/components/CompareForm.vue +++ b/packages/editor/src/components/CompareForm.vue @@ -24,20 +24,13 @@ import { type CodeBlockContent, type DataSourceSchema, HookType, type MNode } fr import { type FormConfig, type FormState, type FormValue, MForm } from '@tmagic/form'; import { useServices } from '@editor/hooks/use-services'; +import type { CompareCategory, CompareFormLoadConfig } from '@editor/type'; import { getCodeBlockFormConfig } from '@editor/utils/code-block'; defineOptions({ name: 'MEditorCompareForm', }); -/** - * 对比类型: - * - node: 节点组件,按 `type` 从 propsService 获取属性表单配置 - * - data-source: 数据源,按 `type`(base/http/...) 从 dataSourceService 获取数据源表单配置 - * - code-block: 数据源代码块,使用内置的代码块表单配置 - */ -export type CompareCategory = 'node' | 'data-source' | 'code-block'; - const props = withDefaults( defineProps<{ /** 当前值(修改后的值) */ @@ -68,6 +61,12 @@ const props = withDefaults( * 因此在差异对比场景下也需要透传,避免出现 `formState.xxx is undefined` 的运行时错误。 */ extendState?: (_state: FormState) => Record | Promise>; + /** + * 自定义 FormConfig 加载逻辑。传入后将接管内置的按 `category`(node/data-source/code-block) + * 取配置逻辑,调用方可根据业务自行返回(或异步返回)表单配置。可通过 + * `ctx.defaultLoadConfig()` 复用默认结果再做二次加工。返回的 config 直接用于对比展示。 + */ + loadConfig?: CompareFormLoadConfig; }>(), { category: 'node', @@ -153,22 +152,23 @@ const showDiff = ({ curValue, lastValue, config }: { curValue: any; lastValue: a return !isEqual(curValue, lastValue); }; -const loadConfig = async () => { +/** + * 内置的默认 FormConfig 加载逻辑:按 `category` 从对应 service / 工具取配置。 + * 作为 ctx.defaultLoadConfig 透传给自定义 `loadConfig`,方便复用与二次加工。 + */ +const defaultLoadConfig = async (): Promise => { switch (props.category) { case 'node': { if (!props.type) { - config.value = []; - return; + return []; } - config.value = await propsService.getPropsConfig(props.type); - break; + return await propsService.getPropsConfig(props.type); } case 'data-source': { - config.value = dataSourceService.getFormConfig(props.type || 'base'); - break; + return dataSourceService.getFormConfig(props.type || 'base'); } case 'code-block': { - config.value = getCodeBlockFormConfig({ + return getCodeBlockFormConfig({ paramColConfig: codeBlockService.getParamsColConfig(), // 通过传入 dataSourceType 间接表达"是数据源代码块"——在对比场景下 props.dataSourceType // 由调用方按 step 上下文显式传入,未传则视为普通代码块,「执行时机」字段隐藏。 @@ -178,15 +178,28 @@ const loadConfig = async () => { // 对比模式只读,不需要校验/语法检查 editable: false, }); - break; } default: - config.value = []; + return []; } }; +const loadConfig = async () => { + if (props.loadConfig) { + config.value = await props.loadConfig({ + category: props.category, + type: props.type, + dataSourceType: props.dataSourceType, + defaultLoadConfig, + }); + return; + } + + config.value = await defaultLoadConfig(); +}; + watch( - [() => props.category, () => props.type, () => props.dataSourceType], + [() => props.category, () => props.type, () => props.dataSourceType, () => props.loadConfig], () => { loadConfig(); }, diff --git a/packages/editor/src/index.ts b/packages/editor/src/index.ts index b3e25b92..869fa4da 100644 --- a/packages/editor/src/index.ts +++ b/packages/editor/src/index.ts @@ -72,6 +72,7 @@ export { default as Resizer } from './components/Resizer.vue'; export { default as CodeBlockEditor } from './components/CodeBlockEditor.vue'; export { default as CompareForm } from './components/CompareForm.vue'; export { default as HistoryListBucket } from './layouts/history-list/Bucket.vue'; +export { default as HistoryDiffDialog } from './layouts/history-list/HistoryDiffDialog.vue'; export { default as FloatingBox } from './components/FloatingBox.vue'; export { default as Tree } from './components/Tree.vue'; export { default as TreeNode } from './components/TreeNode.vue'; diff --git a/packages/editor/src/layouts/history-list/HistoryDiffDialog.vue b/packages/editor/src/layouts/history-list/HistoryDiffDialog.vue index a3598948..4a8b3793 100644 --- a/packages/editor/src/layouts/history-list/HistoryDiffDialog.vue +++ b/packages/editor/src/layouts/history-list/HistoryDiffDialog.vue @@ -4,10 +4,10 @@ v-model="visible" class="m-editor-history-diff-dialog" title="查看修改差异" - width="900px" top="5vh" destroy-on-close append-to-body + :width="width" >
@@ -42,6 +42,7 @@ :value="rightValue" :last-value="leftValue" :extend-state="extendState" + :load-config="loadConfig" height="70vh" /> @@ -71,21 +72,33 @@ import { isEqual } from 'lodash-es'; import { TMagicButton, TMagicDialog, TMagicRadioButton, TMagicRadioGroup, TMagicTag } from '@tmagic/design'; import type { FormState } from '@tmagic/form'; -import CompareForm, { type CompareCategory } from '@editor/components/CompareForm.vue'; +import CompareForm from '@editor/components/CompareForm.vue'; import CodeEditor from '@editor/layouts/CodeEditor.vue'; +import type { CompareCategory, CompareFormLoadConfig } from '@editor/type'; defineOptions({ name: 'MEditorHistoryDiffDialog', }); -defineProps<{ - /** - * 来自 Editor 顶层的 `extendFormState`,用于扩展 MForm.formState。 - * 透传给 CompareForm,从而让差异对比时表单 item 中依赖业务上下文的 - * `display` / `disabled` 等 filterFunction 正常工作。 - */ - extendState?: (_state: FormState) => Record | Promise>; -}>(); +withDefaults( + defineProps<{ + /** + * 来自 Editor 顶层的 `extendFormState`,用于扩展 MForm.formState。 + * 透传给 CompareForm,从而让差异对比时表单 item 中依赖业务上下文的 + * `display` / `disabled` 等 filterFunction 正常工作。 + */ + extendState?: (_state: FormState) => Record | Promise>; + /** + * 自定义 FormConfig 加载逻辑,透传给 CompareForm。传入后将接管内置的按 `category` + * 取配置逻辑,可通过 `ctx.defaultLoadConfig()` 复用默认结果再做二次加工。 + */ + loadConfig?: CompareFormLoadConfig; + width?: string; + }>(), + { + width: '900px', + }, +); /** 差异对话框的入参 */ export interface DiffDialogPayload { diff --git a/packages/editor/src/type.ts b/packages/editor/src/type.ts index fa967dda..ab419808 100644 --- a/packages/editor/src/type.ts +++ b/packages/editor/src/type.ts @@ -498,6 +498,40 @@ export interface HistoryListExtraTab { } // #endregion HistoryListExtraTab +// #region CompareForm +/** + * 对比表单(CompareForm)的对比类型: + * - node: 节点组件,按 `type` 从 propsService 获取属性表单配置 + * - data-source: 数据源,按 `type`(base/http/...) 从 dataSourceService 获取数据源表单配置 + * - code-block: 数据源代码块,使用内置的代码块表单配置 + */ +export type CompareCategory = 'node' | 'data-source' | 'code-block'; + +/** + * 自定义 `loadConfig` 时回传的上下文,聚合了组件当前的对比入参, + * 方便调用方在外部按需拼装 FormConfig。 + */ +export interface CompareFormLoadConfigContext { + /** 对比类型,见 CompareCategory */ + category: string; + /** 节点 / 数据源类型 */ + type?: string; + /** 数据源代码块场景下的数据源类型 */ + dataSourceType?: string; + /** + * 内置的默认 FormConfig 加载逻辑(按 `category` 从 propsService / dataSourceService / + * 代码块工具取配置)。自定义 `loadConfig` 可调用它复用默认结果,再做二次加工。 + */ + defaultLoadConfig: () => Promise; +} + +/** + * 自定义 FormConfig 加载逻辑。传入后将接管内置的按 `category` 取配置逻辑, + * 可通过 `ctx.defaultLoadConfig()` 复用默认结果再做二次加工。 + */ +export type CompareFormLoadConfig = (ctx: CompareFormLoadConfigContext) => FormConfig | Promise; +// #endregion CompareForm + // #region SideItemKey export enum SideItemKey { COMPONENT_LIST = 'component-list',