@tmagic/editor 1.8.0-beta.24 → 1.8.0-beta.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,7 @@ import { getCondOpOptionsByFieldType } from "../utils/props.js";
2
2
  import { useServices } from "../hooks/use-services.js";
3
3
  import { getFieldType } from "../utils/data-source/index.js";
4
4
  import { TMagicSelect, getDesignConfig } from "@tmagic/design";
5
+ import { removeDataSourceFieldPrefix } from "@tmagic/utils";
5
6
  import { Fragment, computed, createBlock, createElementBlock, defineComponent, mergeProps, openBlock, renderList, resolveDynamicComponent, unref, withCtx } from "vue";
6
7
  //#region packages/editor/src/fields/CondOpSelect.vue?vue&type=script&setup=true&lang.ts
7
8
  var CondOpSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
@@ -29,8 +30,8 @@ var CondOpSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
29
30
  const props = __props;
30
31
  const optionComponent = getDesignConfig("components")?.option;
31
32
  const options = computed(() => {
32
- const [id, ...fieldNames] = [...props.config.parentFields || [], ...props.model.field];
33
- const ds = dataSourceService.getDataSourceById(id);
33
+ const [id, ...fieldNames] = [...props.config.parentFields || [], ...props.model.field || []];
34
+ const ds = id ? dataSourceService.getDataSourceById(removeDataSourceFieldPrefix(id)) : void 0;
34
35
  const type = getFieldType(ds, fieldNames);
35
36
  return getCondOpOptionsByFieldType(type);
36
37
  });
@@ -60,7 +60,9 @@ var Index_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComp
60
60
  let value;
61
61
  if (typeof props.config.checkStrictly !== "function") value = props.config.checkStrictly;
62
62
  else {
63
- const dsId = removeDataSourceFieldPrefix(props.model[0]);
63
+ const fieldValue = props.model[props.name];
64
+ const rawDsId = props.config.dataSourceId ?? (Array.isArray(fieldValue) ? fieldValue[0] : fieldValue);
65
+ const dsId = removeDataSourceFieldPrefix(`${rawDsId}`);
64
66
  const dataSource = dataSources.value.find((ds) => ds.id === dsId);
65
67
  value = props.config.checkStrictly(mForm, {
66
68
  values: mForm?.initValues || {},
@@ -1,6 +1,7 @@
1
1
  import { useServices } from "../hooks/use-services.js";
2
2
  import { getCascaderOptionsFromFields, getFieldType } from "../utils/data-source/index.js";
3
3
  import { MGroupList, filterFunction } from "@tmagic/form";
4
+ import { removeDataSourceFieldPrefix } from "@tmagic/utils";
4
5
  import { computed, createBlock, defineComponent, inject, openBlock, unref } from "vue";
5
6
  //#region packages/editor/src/fields/DisplayConds.vue?vue&type=script&setup=true&lang.ts
6
7
  var DisplayConds_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
@@ -31,9 +32,15 @@ var DisplayConds_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
31
32
  const { dataSourceService } = useServices();
32
33
  const mForm = inject("mForm");
33
34
  const parentFields = computed(() => filterFunction(mForm, props.config.parentFields, props) || []);
35
+ const resolveFieldPath = (path) => {
36
+ const [id, ...fieldNames] = path;
37
+ return {
38
+ ds: id ? dataSourceService.getDataSourceById(removeDataSourceFieldPrefix(`${id}`)) : void 0,
39
+ fieldNames
40
+ };
41
+ };
34
42
  const fieldOnChange = (_formState, v, { model }) => {
35
- const [id, ...fieldNames] = [...parentFields.value, ...v];
36
- const ds = dataSourceService.getDataSourceById(id);
43
+ const { ds, fieldNames } = resolveFieldPath([...parentFields.value, ...v]);
37
44
  const type = getFieldType(ds, fieldNames);
38
45
  if (type === "number") model.value = Number(model.value);
39
46
  else if (type === "boolean") model.value = Boolean(model.value);
@@ -59,11 +66,10 @@ var DisplayConds_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
59
66
  parentFields.value.length ? {
60
67
  type: "cascader",
61
68
  options: () => {
62
- const [dsId, ...keys] = parentFields.value;
63
- const ds = dataSourceService.getDataSourceById(dsId);
69
+ const { ds, fieldNames } = resolveFieldPath(parentFields.value);
64
70
  if (!ds) return [];
65
71
  let fields = ds.fields || [];
66
- keys.forEach((key) => {
72
+ fieldNames.forEach((key) => {
67
73
  fields = fields.find((f) => f.name === key)?.fields || [];
68
74
  });
69
75
  return getCascaderOptionsFromFields(fields, [
@@ -131,8 +137,7 @@ var DisplayConds_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
131
137
  items: [{
132
138
  name: "value",
133
139
  type: (_mForm, { model }) => {
134
- const [id, ...fieldNames] = [...parentFields.value, ...model.field];
135
- const ds = dataSourceService.getDataSourceById(id);
140
+ const { ds, fieldNames } = resolveFieldPath([...parentFields.value, ...model.field || []]);
136
141
  const type = getFieldType(ds, fieldNames);
137
142
  if (type === "number") return "number";
138
143
  if (type === "boolean") return "select";
@@ -1,4 +1,4 @@
1
- import { validateDataSourceFieldSelectValue } from "../../../utils/type-match-rules.js";
1
+ import { validateDataSourceFieldSelect } from "../../../utils/type-match-rules.js";
2
2
  import Left_default from "../icons/text-align/Left.js";
3
3
  import Center_default from "../icons/text-align/Center.js";
4
4
  import Right_default from "../icons/text-align/Right.js";
@@ -56,7 +56,7 @@ var Font_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
56
56
  },
57
57
  rules: [{ typeMatch: false }, { validator: ({ value, callback }, { config, model, prop }, mForm) => {
58
58
  if (value === "" || value === null || value === void 0) return callback();
59
- const result = validateDataSourceFieldSelectValue(value, {
59
+ const result = validateDataSourceFieldSelect(value, {
60
60
  fieldType: "data-source-field-select",
61
61
  mForm,
62
62
  props: {
package/dist/es/index.js CHANGED
@@ -31,7 +31,7 @@ import { IdleTask } from "./utils/dep/idle-task.js";
31
31
  import { ScrollViewer } from "./utils/scroll-viewer.js";
32
32
  import codeBlock_default from "./services/codeBlock.js";
33
33
  import dataSource_default from "./services/dataSource.js";
34
- import { ALL_COND_OPS, editorTypeMatchRules, validateDataSourceFieldSelectValue } from "./utils/type-match-rules.js";
34
+ import { ALL_COND_OPS, editorTypeMatchRules, validateDataSourceFieldSelect } from "./utils/type-match-rules.js";
35
35
  import events_default from "./services/events.js";
36
36
  import { EVENT_NAME_VALUE_SEPARATOR, collectEventNameOptionValues, getCompActionAllowedValues, getCompActionOptions, getEventNameAllowedValues, getEventNameOptions, isEventNameCheckStrictly, normalizeCompActionValue } from "./utils/event.js";
37
37
  import monaco_editor_default from "./utils/monaco-editor.js";
@@ -92,4 +92,4 @@ export * from "@tmagic/table";
92
92
  export * from "@tmagic/stage";
93
93
  export * from "@tmagic/design";
94
94
  export * from "@tmagic/utils";
95
- export { ALL_COND_OPS, CODE_DRAFT_STORAGE_KEY, COPY_CODE_STORAGE_KEY, COPY_DS_STORAGE_KEY, COPY_STORAGE_KEY, CodeBlockEditor_default as CodeBlockEditor, CodeBlockList_default as CodeBlockList, CodeBlockListPanel_default as CodeBlockListPanel, CodeDeleteErrorType, CodeSelect_default as CodeSelect, CodeSelectCol_default as CodeSelectCol, ColumnLayout, CompareForm_default as CompareForm, ComponentListPanel_default as ComponentListPanel, CondOpSelect_default as CondOpSelect, ContentMenu_default as ContentMenu, DEFAULT_LEFT_COLUMN_WIDTH, DEFAULT_RIGHT_COLUMN_WIDTH, DataSourceAddButton_default as DataSourceAddButton, DataSourceConfigPanel_default as DataSourceConfigPanel, Index_default as DataSourceFieldSelect, DataSourceFields_default as DataSourceFields, DataSourceInput_default as DataSourceInput, DataSourceMethodSelect_default as DataSourceMethodSelect, DataSourceMethods_default as DataSourceMethods, DataSourceMocks_default as DataSourceMocks, DataSourceSelect_default as DataSourceSelect, DepTargetType, DisplayConds_default as DisplayConds, DragType, EVENT_NAME_VALUE_SEPARATOR, EventSelect_default as EventSelect, Fixed2Other, FloatingBox_default as FloatingBox, H_GUIDE_LINE_STORAGE_KEY, HistoryDiffDialog_default as HistoryDiffDialog, Bucket_default as HistoryListBucket, BucketTab_default as HistoryListBucketTab, Icon_default as Icon, IdleTask, KeyBindingCommand, KeyValue_default as KeyValue, Keys, LEFT_COLUMN_WIDTH_STORAGE_KEY, LayerNodeContent_default as LayerNodeContent, LayerOffset, LayerPanel_default as LayerPanel, Layout, SplitView_default as LayoutContainer, MIN_CENTER_COLUMN_WIDTH, MIN_LEFT_COLUMN_WIDTH, MIN_RIGHT_COLUMN_WIDTH, PROPS_PANEL_WIDTH_STORAGE_KEY, PageFragmentSelect_default as PageFragmentSelect, FormPanel_default as PropsFormPanel, PropsPanel_default as PropsPanel, RIGHT_COLUMN_WIDTH_STORAGE_KEY, Resizer_default as Resizer, ScrollViewer, SideItemKey, SplitView_default as SplitView, StageCore, Index_default$1 as StyleSetter, CodeEditor_default as TMagicCodeEditor, Editor_default as TMagicEditor, ToolButton_default as ToolButton, Tree_default as Tree, TreeNode_default as TreeNode, UI_SELECT_MODE_EVENT_NAME, UndoRedo, V_GUIDE_LINE_STORAGE_KEY, ViewForm_default as ViewForm, advancedTabConfig, arrayOptions, beforePaste, booleanOptions, buildChangeRecords, calcAlignCenterStyle, calcLayerTargetIndex, calcMoveStyle, canUsePluginMethods, change2Fixed, classifyDragSources, codeBlock_default as codeBlockService, collectEventNameOptionValues, collectRelatedNodes, componentList_default as componentListService, confirmHistoryAction, createStackStep, dataSource_default as dataSourceService, debug, plugin_default as default, defaultIsExpandable, dep_default as depService, describeRevertStep, describeStepForRevert, deserializeStacks, designPlugin, detectStackOpType, detectTargetId, detectTargetName, displayTabConfig, editorNodeMergeCustomizer, editor_default as editorService, editorTypeMatchRules, eqOptions, error, eventTabConfig, events_default as eventsService, fillConfig, fixNodeLeft, fixNodePosition, formPlugin, generatePageName, generatePageNameByApp, getAddParent, getCascaderOptionsFromFields, getCodeBlockFormConfig, getCompActionAllowedValues, getCompActionOptions, getCondOpOptionsByFieldType, getDefaultConfig, getDisplayField, getEditorConfig, getEventNameAllowedValues, getEventNameOptions, getFieldType, getFormConfig, getFormValue, getGuideLineFromCache, getInitPositionStyle, getLastPushedHistoryIds, getNodeIndex, getOrCreateStack, getPageFragmentList, getPageList, getPageNameList, getPositionInContainer, getRelativeStyle, history_default as historyService, idbDelete, idbGet, idbSet, info, isEventNameCheckStrictly, isGlobalFlat, isIncludeDataSource, isIndexedDBSupported, keybinding_default as keybindingService, monaco_editor_default as loadMonaco, log, markStackSaved, mergeSteps, moveItemsInContainer, normalizeCompActionValue, numberOptions, openIndexedDB, props_default as propsService, resolveFieldByPath, resolveSelectedNode, serializeConfig, serializeStacks, setChildrenLayout, setEditorConfig, setLayout, stageOverlay_default as stageOverlayService, storage_default as storageService, styleTabConfig, tablePlugin, toggleFixedPosition, ui_default as uiService, undoFloor, updateStatus, useCodeBlockEdit, useCompareForm, useEditorContentHeight, useFilter, useFloatBox, useGetSo, useHistoryRevert, useNextFloatBoxPosition, useNodeStatus, useServices, useStage, useWindowRect, validateDataSourceFieldSelectValue, warn };
95
+ export { ALL_COND_OPS, CODE_DRAFT_STORAGE_KEY, COPY_CODE_STORAGE_KEY, COPY_DS_STORAGE_KEY, COPY_STORAGE_KEY, CodeBlockEditor_default as CodeBlockEditor, CodeBlockList_default as CodeBlockList, CodeBlockListPanel_default as CodeBlockListPanel, CodeDeleteErrorType, CodeSelect_default as CodeSelect, CodeSelectCol_default as CodeSelectCol, ColumnLayout, CompareForm_default as CompareForm, ComponentListPanel_default as ComponentListPanel, CondOpSelect_default as CondOpSelect, ContentMenu_default as ContentMenu, DEFAULT_LEFT_COLUMN_WIDTH, DEFAULT_RIGHT_COLUMN_WIDTH, DataSourceAddButton_default as DataSourceAddButton, DataSourceConfigPanel_default as DataSourceConfigPanel, Index_default as DataSourceFieldSelect, DataSourceFields_default as DataSourceFields, DataSourceInput_default as DataSourceInput, DataSourceMethodSelect_default as DataSourceMethodSelect, DataSourceMethods_default as DataSourceMethods, DataSourceMocks_default as DataSourceMocks, DataSourceSelect_default as DataSourceSelect, DepTargetType, DisplayConds_default as DisplayConds, DragType, EVENT_NAME_VALUE_SEPARATOR, EventSelect_default as EventSelect, Fixed2Other, FloatingBox_default as FloatingBox, H_GUIDE_LINE_STORAGE_KEY, HistoryDiffDialog_default as HistoryDiffDialog, Bucket_default as HistoryListBucket, BucketTab_default as HistoryListBucketTab, Icon_default as Icon, IdleTask, KeyBindingCommand, KeyValue_default as KeyValue, Keys, LEFT_COLUMN_WIDTH_STORAGE_KEY, LayerNodeContent_default as LayerNodeContent, LayerOffset, LayerPanel_default as LayerPanel, Layout, SplitView_default as LayoutContainer, MIN_CENTER_COLUMN_WIDTH, MIN_LEFT_COLUMN_WIDTH, MIN_RIGHT_COLUMN_WIDTH, PROPS_PANEL_WIDTH_STORAGE_KEY, PageFragmentSelect_default as PageFragmentSelect, FormPanel_default as PropsFormPanel, PropsPanel_default as PropsPanel, RIGHT_COLUMN_WIDTH_STORAGE_KEY, Resizer_default as Resizer, ScrollViewer, SideItemKey, SplitView_default as SplitView, StageCore, Index_default$1 as StyleSetter, CodeEditor_default as TMagicCodeEditor, Editor_default as TMagicEditor, ToolButton_default as ToolButton, Tree_default as Tree, TreeNode_default as TreeNode, UI_SELECT_MODE_EVENT_NAME, UndoRedo, V_GUIDE_LINE_STORAGE_KEY, ViewForm_default as ViewForm, advancedTabConfig, arrayOptions, beforePaste, booleanOptions, buildChangeRecords, calcAlignCenterStyle, calcLayerTargetIndex, calcMoveStyle, canUsePluginMethods, change2Fixed, classifyDragSources, codeBlock_default as codeBlockService, collectEventNameOptionValues, collectRelatedNodes, componentList_default as componentListService, confirmHistoryAction, createStackStep, dataSource_default as dataSourceService, debug, plugin_default as default, defaultIsExpandable, dep_default as depService, describeRevertStep, describeStepForRevert, deserializeStacks, designPlugin, detectStackOpType, detectTargetId, detectTargetName, displayTabConfig, editorNodeMergeCustomizer, editor_default as editorService, editorTypeMatchRules, eqOptions, error, eventTabConfig, events_default as eventsService, fillConfig, fixNodeLeft, fixNodePosition, formPlugin, generatePageName, generatePageNameByApp, getAddParent, getCascaderOptionsFromFields, getCodeBlockFormConfig, getCompActionAllowedValues, getCompActionOptions, getCondOpOptionsByFieldType, getDefaultConfig, getDisplayField, getEditorConfig, getEventNameAllowedValues, getEventNameOptions, getFieldType, getFormConfig, getFormValue, getGuideLineFromCache, getInitPositionStyle, getLastPushedHistoryIds, getNodeIndex, getOrCreateStack, getPageFragmentList, getPageList, getPageNameList, getPositionInContainer, getRelativeStyle, history_default as historyService, idbDelete, idbGet, idbSet, info, isEventNameCheckStrictly, isGlobalFlat, isIncludeDataSource, isIndexedDBSupported, keybinding_default as keybindingService, monaco_editor_default as loadMonaco, log, markStackSaved, mergeSteps, moveItemsInContainer, normalizeCompActionValue, numberOptions, openIndexedDB, props_default as propsService, resolveFieldByPath, resolveSelectedNode, serializeConfig, serializeStacks, setChildrenLayout, setEditorConfig, setLayout, stageOverlay_default as stageOverlayService, storage_default as storageService, styleTabConfig, tablePlugin, toggleFixedPosition, ui_default as uiService, undoFloor, updateStatus, useCodeBlockEdit, useCompareForm, useEditorContentHeight, useFilter, useFloatBox, useGetSo, useHistoryRevert, useNextFloatBoxPosition, useNodeStatus, useServices, useStage, useWindowRect, validateDataSourceFieldSelect, warn };
package/dist/es/style.css CHANGED
@@ -572,7 +572,11 @@ fieldset.m-fieldset .m-form-tip {
572
572
  .m-form-box .el-box__header {
573
573
  margin: 0;
574
574
  }
575
+ .m-form-box .m-box-body {
576
+ min-height: 0;
577
+ }
575
578
  .m-form-box .dialog-footer {
579
+ flex-shrink: 0;
576
580
  display: flex;
577
581
  align-items: center;
578
582
  justify-content: space-between;
@@ -152,24 +152,20 @@ var displayCondSuggestion = () => {
152
152
  };
153
153
  var validateDataSourceFieldPath = (path, options = {}) => {
154
154
  if (!getDataSources().length) return;
155
- let dsId = options.dataSourceId;
156
- let fieldNames = path;
157
- if (!dsId) {
158
- if (!path.length) return defaultMessage(options.message, "值不在可选项中", dataSourceIdSuggestion());
159
- const rawDsId = path[0];
160
- dsId = options.valueMode === "key" || !`${rawDsId}`.startsWith(DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX) ? `${rawDsId}` : removeDataSourceFieldPrefix(`${rawDsId}`);
161
- fieldNames = path.slice(1);
162
- }
155
+ const dsId = options.dataSourceId;
156
+ if (!dsId) return defaultMessage(options.message, "数据源不存在", dataSourceIdSuggestion());
163
157
  const ds = findDataSource(`${dsId}`);
164
158
  if (!ds) return defaultMessage(options.message, `数据源(${dsId})不存在`, dataSourceIdSuggestion());
165
- if (!fieldNames.length) return;
166
- const { field, ok, fields, failedName } = resolveFieldByPath(ds.fields, fieldNames);
159
+ if (!path.length) return;
160
+ const { field, ok, fields, failedName } = resolveFieldByPath(ds.fields, path);
167
161
  if (!ok) return defaultMessage(options.message, `数据源字段(${failedName})不存在`, listSuggestion(fields.map((item) => item.name)));
168
162
  const allowedTypes = options.dataSourceFieldType || ["any"];
169
163
  if (!allowedTypes.length || allowedTypes.includes("any")) return;
170
164
  const leafType = field?.type || "any";
171
- if (leafType === "any" || allowedTypes.includes(leafType)) return;
172
- return defaultMessage(options.message, "值不在可选项中", dataSourceIdSuggestion());
165
+ if (leafType !== "any" && !allowedTypes.includes(leafType)) {
166
+ const fieldName = field?.name || path[path.length - 1];
167
+ return defaultMessage(options.message, `请选择类型为${allowedTypes.join("或")}的字段,字段(${fieldName})的类型为${leafType}`);
168
+ }
173
169
  };
174
170
  var validateDataSourceMethodTuple = (value, message) => {
175
171
  if (!Array.isArray(value) || value.length !== 2 || value.some((item) => typeof item !== "string")) return defaultMessage(message, `${value}类型应为长度为 2 的字符串数组`, methodTupleSuggestion());
@@ -215,7 +211,7 @@ var validateCondOpSelect = (value, { message, props }) => {
215
211
  const parentFields = props.config?.parentFields || [];
216
212
  const fieldPath = Array.isArray(props.model?.field) ? props.model.field : [];
217
213
  const [id, ...fieldNames] = [...parentFields, ...fieldPath];
218
- const ds = id ? findDataSource(`${id}`) : void 0;
214
+ const ds = id ? findDataSource(removeDataSourceFieldPrefix(`${id}`)) : void 0;
219
215
  const allowed = getCondOpsByFieldType(getFieldType(ds, fieldNames));
220
216
  if (!allowed.has(value)) return defaultMessage(message, `${value} 不在可选项中`, listSuggestion([...allowed]));
221
217
  };
@@ -251,7 +247,7 @@ var isDataSourceFieldPathValue = (value, config) => {
251
247
  /**
252
248
  * data-source-field-select 的 typeMatch 校验逻辑,可供自定义 rules.validator 复用。
253
249
  */
254
- var validateDataSourceFieldSelectValue = (value, context, options) => {
250
+ var validateDataSourceFieldSelect = (value, context, options) => {
255
251
  const { mForm, message, props } = context;
256
252
  const config = props.config || {};
257
253
  if (!isDataSourceFieldPathValue(value, config)) {
@@ -265,14 +261,18 @@ var validateDataSourceFieldSelectValue = (value, context, options) => {
265
261
  }, message);
266
262
  }
267
263
  if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) return defaultMessage(message, `${value}类型应为字符串数组`, dataSourceFieldPathSuggestion());
268
- return validateDataSourceFieldPath(value, {
269
- dataSourceId: config.dataSourceId,
270
- valueMode: config.value,
264
+ let dataSourceId = config.dataSourceId ? `${config.dataSourceId}` : void 0;
265
+ let fieldNames = value;
266
+ if (!dataSourceId) {
267
+ dataSourceId = value.length ? removeDataSourceFieldPrefix(value[0]) : void 0;
268
+ fieldNames = value.slice(1);
269
+ }
270
+ return validateDataSourceFieldPath(fieldNames, {
271
+ dataSourceId,
271
272
  dataSourceFieldType: config.dataSourceFieldType,
272
273
  message
273
274
  });
274
275
  };
275
- var validateDataSourceFieldSelect = (value, context) => validateDataSourceFieldSelectValue(value, context);
276
276
  var validateDataSourceSelect = (value, { message, props }) => {
277
277
  const config = props.config || {};
278
278
  const dataSources = getDataSources();
@@ -342,7 +342,8 @@ var editorTypeMatchRules = {
342
342
  "ui-select": validateUiSelect,
343
343
  "data-source-input": validateDataSourceInput,
344
344
  "data-source-method-select": validateDataSourceMethodSelect,
345
- "data-source-field-select": validateDataSourceFieldSelect,
345
+ /** 注册进 typeMatch 规则表的入口,收窄为 TypeMatchValidator,避免调用方误传第三个参数 */
346
+ "data-source-field-select": (value, context) => validateDataSourceFieldSelect(value, context),
346
347
  "data-source-select": validateDataSourceSelect,
347
348
  "code-select": validateCodeSelect,
348
349
  "data-source-fields": validateDataSourceFields,
@@ -352,4 +353,4 @@ var editorTypeMatchRules = {
352
353
  "display-conds": validateDisplayConds
353
354
  };
354
355
  //#endregion
355
- export { ALL_COND_OPS, editorTypeMatchRules, validateDataSourceFieldSelectValue };
356
+ export { ALL_COND_OPS, editorTypeMatchRules, validateDataSourceFieldSelect };
package/dist/style.css CHANGED
@@ -572,7 +572,11 @@ fieldset.m-fieldset .m-form-tip {
572
572
  .m-form-box .el-box__header {
573
573
  margin: 0;
574
574
  }
575
+ .m-form-box .m-box-body {
576
+ min-height: 0;
577
+ }
575
578
  .m-form-box .dialog-footer {
579
+ flex-shrink: 0;
576
580
  display: flex;
577
581
  align-items: center;
578
582
  justify-content: space-between;
@@ -603,7 +603,11 @@ fieldset.m-fieldset .m-form-tip {
603
603
  .m-form-box .el-box__header {
604
604
  margin: 0;
605
605
  }
606
+ .m-form-box .m-box-body {
607
+ min-height: 0;
608
+ }
606
609
  .m-form-box .dialog-footer {
610
+ flex-shrink: 0;
607
611
  display: flex;
608
612
  align-items: center;
609
613
  justify-content: space-between;
@@ -10967,24 +10967,20 @@
10967
10967
  };
10968
10968
  var validateDataSourceFieldPath = (path, options = {}) => {
10969
10969
  if (!getDataSources().length) return;
10970
- let dsId = options.dataSourceId;
10971
- let fieldNames = path;
10972
- if (!dsId) {
10973
- if (!path.length) return defaultMessage(options.message, "值不在可选项中", dataSourceIdSuggestion());
10974
- const rawDsId = path[0];
10975
- dsId = options.valueMode === "key" || !`${rawDsId}`.startsWith(_tmagic_utils.DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX) ? `${rawDsId}` : (0, _tmagic_utils.removeDataSourceFieldPrefix)(`${rawDsId}`);
10976
- fieldNames = path.slice(1);
10977
- }
10970
+ const dsId = options.dataSourceId;
10971
+ if (!dsId) return defaultMessage(options.message, "数据源不存在", dataSourceIdSuggestion());
10978
10972
  const ds = findDataSource(`${dsId}`);
10979
10973
  if (!ds) return defaultMessage(options.message, `数据源(${dsId})不存在`, dataSourceIdSuggestion());
10980
- if (!fieldNames.length) return;
10981
- const { field, ok, fields, failedName } = resolveFieldByPath(ds.fields, fieldNames);
10974
+ if (!path.length) return;
10975
+ const { field, ok, fields, failedName } = resolveFieldByPath(ds.fields, path);
10982
10976
  if (!ok) return defaultMessage(options.message, `数据源字段(${failedName})不存在`, listSuggestion(fields.map((item) => item.name)));
10983
10977
  const allowedTypes = options.dataSourceFieldType || ["any"];
10984
10978
  if (!allowedTypes.length || allowedTypes.includes("any")) return;
10985
10979
  const leafType = field?.type || "any";
10986
- if (leafType === "any" || allowedTypes.includes(leafType)) return;
10987
- return defaultMessage(options.message, "值不在可选项中", dataSourceIdSuggestion());
10980
+ if (leafType !== "any" && !allowedTypes.includes(leafType)) {
10981
+ const fieldName = field?.name || path[path.length - 1];
10982
+ return defaultMessage(options.message, `请选择类型为${allowedTypes.join("或")}的字段,字段(${fieldName})的类型为${leafType}`);
10983
+ }
10988
10984
  };
10989
10985
  var validateDataSourceMethodTuple = (value, message) => {
10990
10986
  if (!Array.isArray(value) || value.length !== 2 || value.some((item) => typeof item !== "string")) return defaultMessage(message, `${value}类型应为长度为 2 的字符串数组`, methodTupleSuggestion());
@@ -11030,7 +11026,7 @@
11030
11026
  const parentFields = props.config?.parentFields || [];
11031
11027
  const fieldPath = Array.isArray(props.model?.field) ? props.model.field : [];
11032
11028
  const [id, ...fieldNames] = [...parentFields, ...fieldPath];
11033
- const allowed = getCondOpsByFieldType(getFieldType(id ? findDataSource(`${id}`) : void 0, fieldNames));
11029
+ const allowed = getCondOpsByFieldType(getFieldType(id ? findDataSource((0, _tmagic_utils.removeDataSourceFieldPrefix)(`${id}`)) : void 0, fieldNames));
11034
11030
  if (!allowed.has(value)) return defaultMessage(message, `${value} 不在可选项中`, listSuggestion([...allowed]));
11035
11031
  };
11036
11032
  var validateCodeSelectCol = (value, { message }) => {
@@ -11065,7 +11061,7 @@
11065
11061
  /**
11066
11062
  * data-source-field-select 的 typeMatch 校验逻辑,可供自定义 rules.validator 复用。
11067
11063
  */
11068
- var validateDataSourceFieldSelectValue = (value, context, options) => {
11064
+ var validateDataSourceFieldSelect = (value, context, options) => {
11069
11065
  const { mForm, message, props } = context;
11070
11066
  const config = props.config || {};
11071
11067
  if (!isDataSourceFieldPathValue(value, config)) {
@@ -11079,14 +11075,18 @@
11079
11075
  }, message);
11080
11076
  }
11081
11077
  if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) return defaultMessage(message, `${value}类型应为字符串数组`, dataSourceFieldPathSuggestion());
11082
- return validateDataSourceFieldPath(value, {
11083
- dataSourceId: config.dataSourceId,
11084
- valueMode: config.value,
11078
+ let dataSourceId = config.dataSourceId ? `${config.dataSourceId}` : void 0;
11079
+ let fieldNames = value;
11080
+ if (!dataSourceId) {
11081
+ dataSourceId = value.length ? (0, _tmagic_utils.removeDataSourceFieldPrefix)(value[0]) : void 0;
11082
+ fieldNames = value.slice(1);
11083
+ }
11084
+ return validateDataSourceFieldPath(fieldNames, {
11085
+ dataSourceId,
11085
11086
  dataSourceFieldType: config.dataSourceFieldType,
11086
11087
  message
11087
11088
  });
11088
11089
  };
11089
- var validateDataSourceFieldSelect = (value, context) => validateDataSourceFieldSelectValue(value, context);
11090
11090
  var validateDataSourceSelect = (value, { message, props }) => {
11091
11091
  const config = props.config || {};
11092
11092
  const dataSources = getDataSources();
@@ -11156,7 +11156,8 @@
11156
11156
  "ui-select": validateUiSelect,
11157
11157
  "data-source-input": validateDataSourceInput,
11158
11158
  "data-source-method-select": validateDataSourceMethodSelect,
11159
- "data-source-field-select": validateDataSourceFieldSelect,
11159
+ /** 注册进 typeMatch 规则表的入口,收窄为 TypeMatchValidator,避免调用方误传第三个参数 */
11160
+ "data-source-field-select": (value, context) => validateDataSourceFieldSelect(value, context),
11160
11161
  "data-source-select": validateDataSourceSelect,
11161
11162
  "code-select": validateCodeSelect,
11162
11163
  "data-source-fields": validateDataSourceFields,
@@ -22804,7 +22805,9 @@
22804
22805
  let value;
22805
22806
  if (typeof props.config.checkStrictly !== "function") value = props.config.checkStrictly;
22806
22807
  else {
22807
- const dsId = (0, _tmagic_utils.removeDataSourceFieldPrefix)(props.model[0]);
22808
+ const fieldValue = props.model[props.name];
22809
+ const rawDsId = props.config.dataSourceId ?? (Array.isArray(fieldValue) ? fieldValue[0] : fieldValue);
22810
+ const dsId = (0, _tmagic_utils.removeDataSourceFieldPrefix)(`${rawDsId}`);
22808
22811
  const dataSource = dataSources.value.find((ds) => ds.id === dsId);
22809
22812
  value = props.config.checkStrictly(mForm, {
22810
22813
  values: mForm?.initValues || {},
@@ -23650,9 +23653,16 @@
23650
23653
  const { dataSourceService } = useServices();
23651
23654
  const mForm = (0, vue.inject)("mForm");
23652
23655
  const parentFields = (0, vue.computed)(() => (0, _tmagic_form.filterFunction)(mForm, props.config.parentFields, props) || []);
23656
+ const resolveFieldPath = (path) => {
23657
+ const [id, ...fieldNames] = path;
23658
+ return {
23659
+ ds: id ? dataSourceService.getDataSourceById((0, _tmagic_utils.removeDataSourceFieldPrefix)(`${id}`)) : void 0,
23660
+ fieldNames
23661
+ };
23662
+ };
23653
23663
  const fieldOnChange = (_formState, v, { model }) => {
23654
- const [id, ...fieldNames] = [...parentFields.value, ...v];
23655
- const type = getFieldType(dataSourceService.getDataSourceById(id), fieldNames);
23664
+ const { ds, fieldNames } = resolveFieldPath([...parentFields.value, ...v]);
23665
+ const type = getFieldType(ds, fieldNames);
23656
23666
  if (type === "number") model.value = Number(model.value);
23657
23667
  else if (type === "boolean") model.value = Boolean(model.value);
23658
23668
  else if (type === "null") model.value = null;
@@ -23677,11 +23687,10 @@
23677
23687
  parentFields.value.length ? {
23678
23688
  type: "cascader",
23679
23689
  options: () => {
23680
- const [dsId, ...keys] = parentFields.value;
23681
- const ds = dataSourceService.getDataSourceById(dsId);
23690
+ const { ds, fieldNames } = resolveFieldPath(parentFields.value);
23682
23691
  if (!ds) return [];
23683
23692
  let fields = ds.fields || [];
23684
- keys.forEach((key) => {
23693
+ fieldNames.forEach((key) => {
23685
23694
  fields = fields.find((f) => f.name === key)?.fields || [];
23686
23695
  });
23687
23696
  return getCascaderOptionsFromFields(fields, [
@@ -23749,8 +23758,8 @@
23749
23758
  items: [{
23750
23759
  name: "value",
23751
23760
  type: (_mForm, { model }) => {
23752
- const [id, ...fieldNames] = [...parentFields.value, ...model.field];
23753
- const type = getFieldType(dataSourceService.getDataSourceById(id), fieldNames);
23761
+ const { ds, fieldNames } = resolveFieldPath([...parentFields.value, ...model.field || []]);
23762
+ const type = getFieldType(ds, fieldNames);
23754
23763
  if (type === "number") return "number";
23755
23764
  if (type === "boolean") return "select";
23756
23765
  if (type === "null") return "display";
@@ -23834,8 +23843,8 @@
23834
23843
  const props = __props;
23835
23844
  const optionComponent = (0, _tmagic_design.getDesignConfig)("components")?.option;
23836
23845
  const options = (0, vue.computed)(() => {
23837
- const [id, ...fieldNames] = [...props.config.parentFields || [], ...props.model.field];
23838
- return getCondOpOptionsByFieldType(getFieldType(dataSourceService.getDataSourceById(id), fieldNames));
23846
+ const [id, ...fieldNames] = [...props.config.parentFields || [], ...props.model.field || []];
23847
+ return getCondOpOptionsByFieldType(getFieldType(id ? dataSourceService.getDataSourceById((0, _tmagic_utils.removeDataSourceFieldPrefix)(id)) : void 0, fieldNames));
23839
23848
  });
23840
23849
  const fieldChangeHandler = (v) => {
23841
23850
  emit("change", v);
@@ -24310,7 +24319,7 @@
24310
24319
  },
24311
24320
  rules: [{ typeMatch: false }, { validator: ({ value, callback }, { config, model, prop }, mForm) => {
24312
24321
  if (value === "" || value === null || value === void 0) return callback();
24313
- const result = validateDataSourceFieldSelectValue(value, {
24322
+ const result = validateDataSourceFieldSelect(value, {
24314
24323
  fieldType: "data-source-field-select",
24315
24324
  mForm,
24316
24325
  props: {
@@ -26337,7 +26346,7 @@
26337
26346
  exports.useServices = useServices;
26338
26347
  exports.useStage = useStage;
26339
26348
  exports.useWindowRect = useWindowRect;
26340
- exports.validateDataSourceFieldSelectValue = validateDataSourceFieldSelectValue;
26349
+ exports.validateDataSourceFieldSelect = validateDataSourceFieldSelect;
26341
26350
  exports.warn = warn;
26342
26351
  Object.keys(_tmagic_form).forEach(function(k) {
26343
26352
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.8.0-beta.24",
2
+ "version": "1.8.0-beta.25",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -58,11 +58,11 @@
58
58
  "moveable": "^0.53.0",
59
59
  "serialize-javascript": "^7.0.7",
60
60
  "sortablejs": "^1.15.7",
61
- "@tmagic/design": "1.8.0-beta.24",
62
- "@tmagic/form": "1.8.0-beta.24",
63
- "@tmagic/utils": "1.8.0-beta.24",
64
- "@tmagic/stage": "1.8.0-beta.24",
65
- "@tmagic/table": "1.8.0-beta.24"
61
+ "@tmagic/design": "1.8.0-beta.25",
62
+ "@tmagic/stage": "1.8.0-beta.25",
63
+ "@tmagic/utils": "1.8.0-beta.25",
64
+ "@tmagic/table": "1.8.0-beta.25",
65
+ "@tmagic/form": "1.8.0-beta.25"
66
66
  },
67
67
  "devDependencies": {
68
68
  "@types/events": "^3.0.3",
@@ -76,7 +76,7 @@
76
76
  "type-fest": "^5.2.0",
77
77
  "typescript": "^6.0.3",
78
78
  "vue": "^3.5.41",
79
- "@tmagic/core": "1.8.0-beta.24"
79
+ "@tmagic/core": "1.8.0-beta.25"
80
80
  },
81
81
  "peerDependenciesMeta": {
82
82
  "typescript": {
@@ -31,6 +31,7 @@ import { computed } from 'vue';
31
31
 
32
32
  import { getDesignConfig, TMagicSelect } from '@tmagic/design';
33
33
  import type { CondOpSelectConfig, FieldProps } from '@tmagic/form';
34
+ import { removeDataSourceFieldPrefix } from '@tmagic/utils';
34
35
 
35
36
  import { useServices } from '@editor/hooks/use-services';
36
37
  import { getCondOpOptionsByFieldType, getFieldType } from '@editor/utils';
@@ -50,8 +51,8 @@ const props = defineProps<FieldProps<CondOpSelectConfig>>();
50
51
  const optionComponent = getDesignConfig('components')?.option;
51
52
 
52
53
  const options = computed(() => {
53
- const [id, ...fieldNames] = [...(props.config.parentFields || []), ...props.model.field];
54
- const ds = dataSourceService.getDataSourceById(id);
54
+ const [id, ...fieldNames] = [...(props.config.parentFields || []), ...(props.model.field || [])];
55
+ const ds = id ? dataSourceService.getDataSourceById(removeDataSourceFieldPrefix(id)) : undefined;
55
56
  const type = getFieldType(ds, fieldNames);
56
57
  return getCondOpOptionsByFieldType(type);
57
58
  });
@@ -143,7 +143,10 @@ const checkStrictly = computed(() => {
143
143
  if (typeof props.config.checkStrictly !== 'function') {
144
144
  value = props.config.checkStrictly;
145
145
  } else {
146
- const dsId = removeDataSourceFieldPrefix(props.model[0]);
146
+ const fieldValue = props.model[props.name];
147
+ // 指定了 dataSourceId 时取值里只有字段名,数据源 id 只能取自 config
148
+ const rawDsId = props.config.dataSourceId ?? (Array.isArray(fieldValue) ? fieldValue[0] : fieldValue);
149
+ const dsId = removeDataSourceFieldPrefix(`${rawDsId}`);
147
150
  const dataSource = dataSources.value.find((ds) => ds.id === dsId);
148
151
 
149
152
  value = props.config.checkStrictly(mForm, {
@@ -25,6 +25,7 @@ import {
25
25
  type GroupListConfig,
26
26
  MGroupList,
27
27
  } from '@tmagic/form';
28
+ import { removeDataSourceFieldPrefix } from '@tmagic/utils';
28
29
 
29
30
  import { useServices } from '@editor/hooks/use-services';
30
31
  import { getCascaderOptionsFromFields, getFieldType } from '@editor/utils';
@@ -46,9 +47,14 @@ const mForm = inject<FormState | undefined>('mForm');
46
47
 
47
48
  const parentFields = computed(() => filterFunction<string[]>(mForm, props.config.parentFields, props) || []);
48
49
 
50
+ const resolveFieldPath = (path: string[]) => {
51
+ const [id, ...fieldNames] = path;
52
+ const ds = id ? dataSourceService.getDataSourceById(removeDataSourceFieldPrefix(`${id}`)) : undefined;
53
+ return { ds, fieldNames };
54
+ };
55
+
49
56
  const fieldOnChange = (_formState: FormState | undefined, v: string[], { model }: { model: Record<string, any> }) => {
50
- const [id, ...fieldNames] = [...parentFields.value, ...v];
51
- const ds = dataSourceService.getDataSourceById(id);
57
+ const { ds, fieldNames } = resolveFieldPath([...parentFields.value, ...v]);
52
58
  const type = getFieldType(ds, fieldNames);
53
59
  if (type === 'number') {
54
60
  model.value = Number(model.value);
@@ -82,14 +88,13 @@ const config = computed<GroupListConfig>(() => ({
82
88
  ? {
83
89
  type: 'cascader',
84
90
  options: () => {
85
- const [dsId, ...keys] = parentFields.value;
86
- const ds = dataSourceService.getDataSourceById(dsId);
91
+ const { ds, fieldNames } = resolveFieldPath(parentFields.value);
87
92
  if (!ds) {
88
93
  return [];
89
94
  }
90
95
 
91
96
  let fields = ds.fields || [];
92
- keys.forEach((key) => {
97
+ fieldNames.forEach((key) => {
93
98
  const field = fields.find((f) => f.name === key);
94
99
  fields = field?.fields || [];
95
100
  });
@@ -139,8 +144,7 @@ const config = computed<GroupListConfig>(() => ({
139
144
  {
140
145
  name: 'value',
141
146
  type: (_mForm, { model }) => {
142
- const [id, ...fieldNames] = [...parentFields.value, ...model.field];
143
- const ds = dataSourceService.getDataSourceById(id);
147
+ const { ds, fieldNames } = resolveFieldPath([...parentFields.value, ...(model.field || [])]);
144
148
  const type = getFieldType(ds, fieldNames);
145
149
 
146
150
  if (type === 'number') {
@@ -21,7 +21,7 @@ import { appendValidateSuggestion } from '@tmagic/design';
21
21
  import { type ContainerChangeEventData, defineFormConfig, MContainer } from '@tmagic/form';
22
22
  import type { StyleSchema } from '@tmagic/schema';
23
23
 
24
- import { validateDataSourceFieldSelectValue } from '@editor/utils/type-match-rules';
24
+ import { validateDataSourceFieldSelect } from '@editor/utils/type-match-rules';
25
25
 
26
26
  import { AlignCenter, AlignLeft, AlignRight } from '../icons/text-align';
27
27
 
@@ -99,7 +99,7 @@ const formConfig = defineFormConfig([
99
99
  return callback();
100
100
  }
101
101
 
102
- const result = validateDataSourceFieldSelectValue(
102
+ const result = validateDataSourceFieldSelect(
103
103
  value,
104
104
  {
105
105
  fieldType: 'data-source-field-select',
@@ -209,7 +209,6 @@ const validateDataSourceFieldPath = (
209
209
  path: string[],
210
210
  options: {
211
211
  dataSourceId?: string;
212
- valueMode?: 'key' | 'value';
213
212
  dataSourceFieldType?: DataSourceFieldType[];
214
213
  message?: string;
215
214
  } = {},
@@ -219,19 +218,11 @@ const validateDataSourceFieldPath = (
219
218
  return undefined;
220
219
  }
221
220
 
222
- let dsId = options.dataSourceId;
223
- let fieldNames = path;
224
-
221
+ const dsId = options.dataSourceId;
225
222
  if (!dsId) {
226
- if (!path.length) {
227
- return defaultMessage(options.message, '值不在可选项中', dataSourceIdSuggestion());
228
- }
229
- const rawDsId = path[0];
230
- dsId =
231
- options.valueMode === 'key' || !`${rawDsId}`.startsWith(DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX)
232
- ? `${rawDsId}`
233
- : removeDataSourceFieldPrefix(`${rawDsId}`);
234
- fieldNames = path.slice(1);
223
+ // 仅当取值为空数组或首项为空串时命中。表单校验管道里 validateTypeMatch 对空数组会短路,
224
+ // 因此这里只可能来自直接调用 validateDataSourceFieldSelect 的自定义 validator
225
+ return defaultMessage(options.message, '数据源不存在', dataSourceIdSuggestion());
235
226
  }
236
227
 
237
228
  const ds = findDataSource(`${dsId}`);
@@ -239,11 +230,11 @@ const validateDataSourceFieldPath = (
239
230
  return defaultMessage(options.message, `数据源(${dsId})不存在`, dataSourceIdSuggestion());
240
231
  }
241
232
 
242
- if (!fieldNames.length) {
233
+ if (!path.length) {
243
234
  return undefined;
244
235
  }
245
236
 
246
- const { field, ok, fields, failedName } = resolveFieldByPath(ds.fields, fieldNames);
237
+ const { field, ok, fields, failedName } = resolveFieldByPath(ds.fields, path);
247
238
  if (!ok) {
248
239
  return defaultMessage(
249
240
  options.message,
@@ -258,11 +249,15 @@ const validateDataSourceFieldPath = (
258
249
  }
259
250
 
260
251
  const leafType = field?.type || 'any';
261
- if (leafType === 'any' || allowedTypes.includes(leafType)) {
262
- return undefined;
263
- }
252
+ if (leafType !== 'any' && !allowedTypes.includes(leafType)) {
253
+ const fieldName = field?.name || path[path.length - 1];
264
254
 
265
- return defaultMessage(options.message, '值不在可选项中', dataSourceIdSuggestion());
255
+ // 文案已点明当前字段类型与要求类型,无需再列同级可选字段
256
+ return defaultMessage(
257
+ options.message,
258
+ `请选择类型为${allowedTypes.join('或')}的字段,字段(${fieldName})的类型为${leafType}`,
259
+ );
260
+ }
266
261
  };
267
262
 
268
263
  const validateDataSourceMethodTuple = (value: any, message?: string): string | undefined => {
@@ -367,7 +362,7 @@ const validateCondOpSelect: TypeMatchValidator = (value, { message, props }) =>
367
362
  const parentFields = props.config?.parentFields || [];
368
363
  const fieldPath = Array.isArray(props.model?.field) ? props.model.field : [];
369
364
  const [id, ...fieldNames] = [...parentFields, ...fieldPath];
370
- const ds = id ? findDataSource(`${id}`) : undefined;
365
+ const ds = id ? findDataSource(removeDataSourceFieldPrefix(`${id}`)) : undefined;
371
366
  const fieldType = getFieldType(ds, fieldNames);
372
367
  const allowed = getCondOpsByFieldType(fieldType);
373
368
 
@@ -464,7 +459,7 @@ export type ValidateDataSourceFieldSelectOptions = {
464
459
  /**
465
460
  * data-source-field-select 的 typeMatch 校验逻辑,可供自定义 rules.validator 复用。
466
461
  */
467
- export const validateDataSourceFieldSelectValue = (
462
+ export const validateDataSourceFieldSelect = (
468
463
  value: any,
469
464
  context: TypeMatchValidateContext,
470
465
  options?: ValidateDataSourceFieldSelectOptions,
@@ -492,17 +487,22 @@ export const validateDataSourceFieldSelectValue = (
492
487
  return defaultMessage(message, `${value}类型应为字符串数组`, dataSourceFieldPathSuggestion());
493
488
  }
494
489
 
495
- return validateDataSourceFieldPath(value, {
496
- dataSourceId: config.dataSourceId,
497
- valueMode: config.value,
490
+ // 未指定 dataSourceId 时,路径首项为数据源 id,其余为字段名。
491
+ // value 模式的首项带 ds-field:: 前缀、key 模式不带,removeDataSourceFieldPrefix 对后者是幂等的,无需分支。
492
+ let dataSourceId = config.dataSourceId ? `${config.dataSourceId}` : undefined;
493
+ let fieldNames = value;
494
+ if (!dataSourceId) {
495
+ dataSourceId = value.length ? removeDataSourceFieldPrefix(value[0]) : undefined;
496
+ fieldNames = value.slice(1);
497
+ }
498
+
499
+ return validateDataSourceFieldPath(fieldNames, {
500
+ dataSourceId,
498
501
  dataSourceFieldType: config.dataSourceFieldType,
499
502
  message,
500
503
  });
501
504
  };
502
505
 
503
- const validateDataSourceFieldSelect: TypeMatchValidator = (value, context) =>
504
- validateDataSourceFieldSelectValue(value, context);
505
-
506
506
  const validateDataSourceSelect: TypeMatchValidator = (value, { message, props }) => {
507
507
  const config = props.config || {};
508
508
  const dataSources = getDataSources();
@@ -678,7 +678,8 @@ export const editorTypeMatchRules: Record<string, TypeMatchValidator> = {
678
678
  'ui-select': validateUiSelect,
679
679
  'data-source-input': validateDataSourceInput,
680
680
  'data-source-method-select': validateDataSourceMethodSelect,
681
- 'data-source-field-select': validateDataSourceFieldSelect,
681
+ /** 注册进 typeMatch 规则表的入口,收窄为 TypeMatchValidator,避免调用方误传第三个参数 */
682
+ 'data-source-field-select': (value, context) => validateDataSourceFieldSelect(value, context),
682
683
  'data-source-select': validateDataSourceSelect,
683
684
  'code-select': validateCodeSelect,
684
685
  'data-source-fields': validateDataSourceFields,
package/types/index.d.ts CHANGED
@@ -3498,7 +3498,7 @@ type ValidateDataSourceFieldSelectOptions = {
3498
3498
  /**
3499
3499
  * data-source-field-select 的 typeMatch 校验逻辑,可供自定义 rules.validator 复用。
3500
3500
  */
3501
- declare const validateDataSourceFieldSelectValue: (value: any, context: TypeMatchValidateContext, options?: ValidateDataSourceFieldSelectOptions) => string | undefined | Promise<string | undefined>;
3501
+ declare const validateDataSourceFieldSelect: (value: any, context: TypeMatchValidateContext, options?: ValidateDataSourceFieldSelectOptions) => string | undefined | Promise<string | undefined>;
3502
3502
  declare const editorTypeMatchRules: Record<string, TypeMatchValidator>;
3503
3503
  //#endregion
3504
3504
  //#region temp/packages/editor/src/utils/event.d.ts
@@ -6880,4 +6880,4 @@ declare const _default$43: {
6880
6880
  install: (app: App, opt?: Partial<EditorInstallOptions | DesignPluginOptions | FormInstallOptions>) => void;
6881
6881
  };
6882
6882
  //#endregion
6883
- export { ALL_COND_OPS, AddMNode, AddPrefixToObject, AsyncAfterHook, AsyncBeforeHook, AsyncHookPlugin, AsyncMethodName, BaseStepValue, BeforeAdd, CODE_DRAFT_STORAGE_KEY, COPY_CODE_STORAGE_KEY, COPY_DS_STORAGE_KEY, COPY_STORAGE_KEY, CanDropInFunction, CanDropInScene, _default as CodeBlockEditor, _default$1 as CodeBlockList, _default$2 as CodeBlockListPanel, CodeBlockListPanelSlots, CodeBlockListSlots, CodeBlockStepValue, CodeDeleteErrorType, CodeDslItem, CodeParamStatement, CodeRelation, _default$3 as CodeSelect, _default$4 as CodeSelectCol, CodeState, ColumnLayout, CombineInfo, CompareCategory, _default$5 as CompareForm, CompareFormBaseProps, CompareFormLoadConfig, CompareFormLoadConfigContext, ComponentGroup, ComponentGroupState, ComponentItem, _default$6 as ComponentListPanel, ComponentListPanelSlots, _default$7 as CondOpSelect, ConfirmAndRevertOptions, _default$8 as ContentMenu, ContentMenuTarget, ContentMenuType, CustomContentMenuFunction, CustomDiffFormOptions, DEFAULT_LEFT_COLUMN_WIDTH, DEFAULT_RIGHT_COLUMN_WIDTH, _default$9 as DataSourceAddButton, _default$10 as DataSourceConfigPanel, _default$11 as DataSourceFieldSelect, _default$12 as DataSourceFields, _default$13 as DataSourceInput, DataSourceListSlots, _default$14 as DataSourceMethodSelect, _default$15 as DataSourceMethods, _default$16 as DataSourceMocks, _default$17 as DataSourceSelect, DataSourceStepValue, DatasourceTypeOption, DepTargetType, DiffDialogPayload, _default$18 as DisplayConds, DragClassification, DragType, DslOpOptions, DslOpWithHistoryIdsResult, EVENT_NAME_VALUE_SEPARATOR, EditorChangeEvent, EditorChangeEventHistoryMeta, EditorChangeItem, EditorEvents, EditorInstallOptions, EditorNodeInfo, EditorSlots, EditorUpdateChangeItem, EventBus, EventBusEvent, EventNameOption, EventNameSelectOption, _default$19 as EventSelect, Fixed2Other, _default$20 as FloatingBox, FrameworkSlots, GetCodeBlockFormConfigOptions, GetColumnWidth, GetConfig, H_GUIDE_LINE_STORAGE_KEY, HistoryBucketConfig, _default$21 as HistoryDiffDialog, HistoryEvents, HistoryGroup, _default$22 as HistoryListBucket, _default$23 as HistoryListBucketTab, HistoryListExtraTab, HistoryOpOptions, HistoryOpOptionsWithChangeRecords, HistoryOpSource, HistoryOpType, HistoryPersistOptions, HistoryRowDescriptor, HistoryState, HistoryStepEntry, HistoryStepType, HistorySteps, _default$24 as Icon, IdleTask, IdleTaskEvents, IsExpandableFunction, KeyBindingCacheItem, KeyBindingCommand, KeyBindingItem, _default$25 as KeyValue, Keys, LEFT_COLUMN_WIDTH_STORAGE_KEY, _default$26 as LayerNodeContent, LayerNodeSlots, LayerNodeStatus, LayerOffset, _default$27 as LayerPanel, LayerPanelSlots, Layout, _default$28 as LayoutContainer, _default$28 as SplitView, ListState, MIN_CENTER_COLUMN_WIDTH, MIN_LEFT_COLUMN_WIDTH, MIN_RIGHT_COLUMN_WIDTH, MenuBarData, MenuButton, MenuComponent, MenuItem, NodeInvalidInfo, NodeInvalidSource, type OnDrag, PROPS_PANEL_WIDTH_STORAGE_KEY, PageBarSortOptions, _default$29 as PageFragmentSelect, PartSortableOptions, PastePosition, PersistedHistoryState, PropsFormConfigFunction, _default$30 as PropsFormPanel, PropsFormValueFunction, _default$31 as PropsPanel, PropsPanelSlots, PropsState, RIGHT_COLUMN_WIDTH_STORAGE_KEY, _default$32 as Resizer, ScrollViewer, ScrollViewerEvent, ScrollViewerSlots, SerializedUndoRedo, Services, SetColumnWidth, SideBarData, SideComponent, SideItem, SideItemKey, SidebarSlots, StageCore, StageOptions, StageOverlayState, StageRect, StageSlots, StepDiffItem, StepExtra, StepValue, StoreState, StoreStateKey, _default$33 as StyleSetter, SyncAfterHook, SyncBeforeHook, SyncHookPlugin, _default$34 as TMagicCodeEditor, _default$35 as TMagicEditor, _default$36 as ToolButton, _default$37 as Tree, _default$38 as TreeNode, TreeNodeData, type TypeMatchValidateContext, UI_SELECT_MODE_EVENT_NAME, UiState, UndoRedo, UpdateOptions, UseCompareFormReturn, UseHistoryRevertOptions, V_GUIDE_LINE_STORAGE_KEY, ValidateDataSourceFieldSelectOptions, _default$39 as ViewForm, WorkspaceSlots, advancedTabConfig, arrayOptions, beforePaste, booleanOptions, buildChangeRecords, calcAlignCenterStyle, calcLayerTargetIndex, calcMoveStyle, canUsePluginMethods, change2Fixed, classifyDragSources, _default$40 as codeBlockService, collectEventNameOptionValues, collectRelatedNodes, _default$41 as componentListService, confirmHistoryAction, createStackStep, _default$42 as dataSourceService, debug, _default$43 as default, defaultIsExpandable, _default$44 as depService, describeRevertStep, describeStepForRevert, deserializeStacks, designPlugin, detectStackOpType, detectTargetId, detectTargetName, displayTabConfig, editorNodeMergeCustomizer, _default$45 as editorService, editorTypeMatchRules, eqOptions, error, eventTabConfig, _default$46 as eventsService, fillConfig, fixNodeLeft, fixNodePosition, formPlugin, generatePageName, generatePageNameByApp, getAddParent, getCascaderOptionsFromFields, getCodeBlockFormConfig, getCompActionAllowedValues, getCompActionOptions, getCondOpOptionsByFieldType, getDefaultConfig, getDisplayField, getEditorConfig, getEventNameAllowedValues, getEventNameOptions, getFieldType, getFormConfig, getFormValue, getGuideLineFromCache, getInitPositionStyle, getLastPushedHistoryIds, getNodeIndex, getOrCreateStack, getPageFragmentList, getPageList, getPageNameList, getPositionInContainer, getRelativeStyle, _default$47 as historyService, idbDelete, idbGet, idbSet, info, isEventNameCheckStrictly, isGlobalFlat, isIncludeDataSource, isIndexedDBSupported, _default$48 as keybindingService, _default$49 as loadMonaco, log, markStackSaved, mergeSteps, moveItemsInContainer, normalizeCompActionValue, numberOptions, openIndexedDB, _default$50 as propsService, resolveFieldByPath, resolveSelectedNode, serializeConfig, serializeStacks, setChildrenLayout, setEditorConfig, setLayout, _default$51 as stageOverlayService, _default$52 as storageService, styleTabConfig, tablePlugin, toggleFixedPosition, _default$53 as uiService, undoFloor, updateStatus, useCodeBlockEdit, useCompareForm, useEditorContentHeight, useFilter, useFloatBox, useGetSo, useHistoryRevert, useNextFloatBoxPosition, useNodeStatus, useServices, useStage, useWindowRect, validateDataSourceFieldSelectValue, warn };
6883
+ export { ALL_COND_OPS, AddMNode, AddPrefixToObject, AsyncAfterHook, AsyncBeforeHook, AsyncHookPlugin, AsyncMethodName, BaseStepValue, BeforeAdd, CODE_DRAFT_STORAGE_KEY, COPY_CODE_STORAGE_KEY, COPY_DS_STORAGE_KEY, COPY_STORAGE_KEY, CanDropInFunction, CanDropInScene, _default as CodeBlockEditor, _default$1 as CodeBlockList, _default$2 as CodeBlockListPanel, CodeBlockListPanelSlots, CodeBlockListSlots, CodeBlockStepValue, CodeDeleteErrorType, CodeDslItem, CodeParamStatement, CodeRelation, _default$3 as CodeSelect, _default$4 as CodeSelectCol, CodeState, ColumnLayout, CombineInfo, CompareCategory, _default$5 as CompareForm, CompareFormBaseProps, CompareFormLoadConfig, CompareFormLoadConfigContext, ComponentGroup, ComponentGroupState, ComponentItem, _default$6 as ComponentListPanel, ComponentListPanelSlots, _default$7 as CondOpSelect, ConfirmAndRevertOptions, _default$8 as ContentMenu, ContentMenuTarget, ContentMenuType, CustomContentMenuFunction, CustomDiffFormOptions, DEFAULT_LEFT_COLUMN_WIDTH, DEFAULT_RIGHT_COLUMN_WIDTH, _default$9 as DataSourceAddButton, _default$10 as DataSourceConfigPanel, _default$11 as DataSourceFieldSelect, _default$12 as DataSourceFields, _default$13 as DataSourceInput, DataSourceListSlots, _default$14 as DataSourceMethodSelect, _default$15 as DataSourceMethods, _default$16 as DataSourceMocks, _default$17 as DataSourceSelect, DataSourceStepValue, DatasourceTypeOption, DepTargetType, DiffDialogPayload, _default$18 as DisplayConds, DragClassification, DragType, DslOpOptions, DslOpWithHistoryIdsResult, EVENT_NAME_VALUE_SEPARATOR, EditorChangeEvent, EditorChangeEventHistoryMeta, EditorChangeItem, EditorEvents, EditorInstallOptions, EditorNodeInfo, EditorSlots, EditorUpdateChangeItem, EventBus, EventBusEvent, EventNameOption, EventNameSelectOption, _default$19 as EventSelect, Fixed2Other, _default$20 as FloatingBox, FrameworkSlots, GetCodeBlockFormConfigOptions, GetColumnWidth, GetConfig, H_GUIDE_LINE_STORAGE_KEY, HistoryBucketConfig, _default$21 as HistoryDiffDialog, HistoryEvents, HistoryGroup, _default$22 as HistoryListBucket, _default$23 as HistoryListBucketTab, HistoryListExtraTab, HistoryOpOptions, HistoryOpOptionsWithChangeRecords, HistoryOpSource, HistoryOpType, HistoryPersistOptions, HistoryRowDescriptor, HistoryState, HistoryStepEntry, HistoryStepType, HistorySteps, _default$24 as Icon, IdleTask, IdleTaskEvents, IsExpandableFunction, KeyBindingCacheItem, KeyBindingCommand, KeyBindingItem, _default$25 as KeyValue, Keys, LEFT_COLUMN_WIDTH_STORAGE_KEY, _default$26 as LayerNodeContent, LayerNodeSlots, LayerNodeStatus, LayerOffset, _default$27 as LayerPanel, LayerPanelSlots, Layout, _default$28 as LayoutContainer, _default$28 as SplitView, ListState, MIN_CENTER_COLUMN_WIDTH, MIN_LEFT_COLUMN_WIDTH, MIN_RIGHT_COLUMN_WIDTH, MenuBarData, MenuButton, MenuComponent, MenuItem, NodeInvalidInfo, NodeInvalidSource, type OnDrag, PROPS_PANEL_WIDTH_STORAGE_KEY, PageBarSortOptions, _default$29 as PageFragmentSelect, PartSortableOptions, PastePosition, PersistedHistoryState, PropsFormConfigFunction, _default$30 as PropsFormPanel, PropsFormValueFunction, _default$31 as PropsPanel, PropsPanelSlots, PropsState, RIGHT_COLUMN_WIDTH_STORAGE_KEY, _default$32 as Resizer, ScrollViewer, ScrollViewerEvent, ScrollViewerSlots, SerializedUndoRedo, Services, SetColumnWidth, SideBarData, SideComponent, SideItem, SideItemKey, SidebarSlots, StageCore, StageOptions, StageOverlayState, StageRect, StageSlots, StepDiffItem, StepExtra, StepValue, StoreState, StoreStateKey, _default$33 as StyleSetter, SyncAfterHook, SyncBeforeHook, SyncHookPlugin, _default$34 as TMagicCodeEditor, _default$35 as TMagicEditor, _default$36 as ToolButton, _default$37 as Tree, _default$38 as TreeNode, TreeNodeData, type TypeMatchValidateContext, UI_SELECT_MODE_EVENT_NAME, UiState, UndoRedo, UpdateOptions, UseCompareFormReturn, UseHistoryRevertOptions, V_GUIDE_LINE_STORAGE_KEY, ValidateDataSourceFieldSelectOptions, _default$39 as ViewForm, WorkspaceSlots, advancedTabConfig, arrayOptions, beforePaste, booleanOptions, buildChangeRecords, calcAlignCenterStyle, calcLayerTargetIndex, calcMoveStyle, canUsePluginMethods, change2Fixed, classifyDragSources, _default$40 as codeBlockService, collectEventNameOptionValues, collectRelatedNodes, _default$41 as componentListService, confirmHistoryAction, createStackStep, _default$42 as dataSourceService, debug, _default$43 as default, defaultIsExpandable, _default$44 as depService, describeRevertStep, describeStepForRevert, deserializeStacks, designPlugin, detectStackOpType, detectTargetId, detectTargetName, displayTabConfig, editorNodeMergeCustomizer, _default$45 as editorService, editorTypeMatchRules, eqOptions, error, eventTabConfig, _default$46 as eventsService, fillConfig, fixNodeLeft, fixNodePosition, formPlugin, generatePageName, generatePageNameByApp, getAddParent, getCascaderOptionsFromFields, getCodeBlockFormConfig, getCompActionAllowedValues, getCompActionOptions, getCondOpOptionsByFieldType, getDefaultConfig, getDisplayField, getEditorConfig, getEventNameAllowedValues, getEventNameOptions, getFieldType, getFormConfig, getFormValue, getGuideLineFromCache, getInitPositionStyle, getLastPushedHistoryIds, getNodeIndex, getOrCreateStack, getPageFragmentList, getPageList, getPageNameList, getPositionInContainer, getRelativeStyle, _default$47 as historyService, idbDelete, idbGet, idbSet, info, isEventNameCheckStrictly, isGlobalFlat, isIncludeDataSource, isIndexedDBSupported, _default$48 as keybindingService, _default$49 as loadMonaco, log, markStackSaved, mergeSteps, moveItemsInContainer, normalizeCompActionValue, numberOptions, openIndexedDB, _default$50 as propsService, resolveFieldByPath, resolveSelectedNode, serializeConfig, serializeStacks, setChildrenLayout, setEditorConfig, setLayout, _default$51 as stageOverlayService, _default$52 as storageService, styleTabConfig, tablePlugin, toggleFixedPosition, _default$53 as uiService, undoFloor, updateStatus, useCodeBlockEdit, useCompareForm, useEditorContentHeight, useFilter, useFloatBox, useGetSo, useHistoryRevert, useNextFloatBoxPosition, useNodeStatus, useServices, useStage, useWindowRect, validateDataSourceFieldSelect, warn };