@tmagic/editor 1.4.8 → 1.4.10

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.
Files changed (166) hide show
  1. package/dist/style.css +26 -0
  2. package/dist/tmagic-editor.js +3213 -2820
  3. package/dist/tmagic-editor.umd.cjs +3237 -2839
  4. package/package.json +14 -12
  5. package/src/Editor.vue +212 -0
  6. package/src/components/CodeBlockEditor.vue +268 -0
  7. package/src/components/CodeParams.vue +60 -0
  8. package/src/components/ContentMenu.vue +193 -0
  9. package/src/components/FloatingBox.vue +178 -0
  10. package/src/components/Icon.vue +27 -0
  11. package/src/components/Resizer.vue +23 -0
  12. package/src/components/ScrollBar.vue +151 -0
  13. package/src/components/ScrollViewer.vue +128 -0
  14. package/src/components/SearchInput.vue +37 -0
  15. package/src/components/SplitView.vue +186 -0
  16. package/src/components/ToolButton.vue +138 -0
  17. package/src/components/Tree.vue +71 -0
  18. package/src/components/TreeNode.vue +150 -0
  19. package/src/editorProps.ts +120 -0
  20. package/src/fields/Code.vue +50 -0
  21. package/src/fields/CodeLink.vue +80 -0
  22. package/src/fields/CodeSelect.vue +132 -0
  23. package/src/fields/CodeSelectCol.vue +139 -0
  24. package/src/fields/CondOpSelect.vue +87 -0
  25. package/src/fields/DataSourceFieldSelect/FieldSelect.vue +152 -0
  26. package/src/fields/DataSourceFieldSelect/Index.vue +168 -0
  27. package/src/fields/DataSourceFields.vue +329 -0
  28. package/src/fields/DataSourceInput.vue +339 -0
  29. package/src/fields/DataSourceMethodSelect.vue +153 -0
  30. package/src/fields/DataSourceMethods.vue +104 -0
  31. package/src/fields/DataSourceMocks.vue +255 -0
  32. package/src/fields/DataSourceSelect.vue +98 -0
  33. package/src/fields/DisplayConds.vue +145 -0
  34. package/src/fields/EventSelect.vue +375 -0
  35. package/src/fields/KeyValue.vue +137 -0
  36. package/src/fields/PageFragmentSelect.vue +63 -0
  37. package/src/fields/UISelect.vue +135 -0
  38. package/src/hooks/index.ts +24 -0
  39. package/src/hooks/use-code-block-edit.ts +83 -0
  40. package/src/hooks/use-data-source-edit.ts +46 -0
  41. package/src/hooks/use-data-source-method.ts +100 -0
  42. package/src/hooks/use-editor-content-height.ts +26 -0
  43. package/src/hooks/use-filter.ts +55 -0
  44. package/src/hooks/use-float-box.ts +76 -0
  45. package/src/hooks/use-getso.ts +35 -0
  46. package/src/hooks/use-next-float-box-position.ts +29 -0
  47. package/src/hooks/use-node-status.ts +48 -0
  48. package/src/hooks/use-stage.ts +129 -0
  49. package/src/hooks/use-window-rect.ts +20 -0
  50. package/src/icons/AppManageIcon.vue +15 -0
  51. package/src/icons/CenterIcon.vue +13 -0
  52. package/src/icons/CodeIcon.vue +28 -0
  53. package/src/icons/FolderMinusIcon.vue +22 -0
  54. package/src/icons/PinIcon.vue +25 -0
  55. package/src/icons/PinnedIcon.vue +25 -0
  56. package/src/index.ts +124 -0
  57. package/src/initService.ts +448 -0
  58. package/src/layouts/AddPageBox.vue +55 -0
  59. package/src/layouts/CodeEditor.vue +226 -0
  60. package/src/layouts/Framework.vue +165 -0
  61. package/src/layouts/NavMenu.vue +200 -0
  62. package/src/layouts/PropsPanel.vue +131 -0
  63. package/src/layouts/page-bar/AddButton.vue +48 -0
  64. package/src/layouts/page-bar/PageBar.vue +165 -0
  65. package/src/layouts/page-bar/PageBarScrollContainer.vue +192 -0
  66. package/src/layouts/page-bar/PageList.vue +55 -0
  67. package/src/layouts/page-bar/SwitchTypeButton.vue +45 -0
  68. package/src/layouts/sidebar/ComponentListPanel.vue +134 -0
  69. package/src/layouts/sidebar/Sidebar.vue +278 -0
  70. package/src/layouts/sidebar/code-block/CodeBlockList.vue +160 -0
  71. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +70 -0
  72. package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +84 -0
  73. package/src/layouts/sidebar/data-source/DataSourceList.vue +172 -0
  74. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +106 -0
  75. package/src/layouts/sidebar/layer/LayerMenu.vue +128 -0
  76. package/src/layouts/sidebar/layer/LayerNodeTool.vue +32 -0
  77. package/src/layouts/sidebar/layer/LayerPanel.vue +119 -0
  78. package/src/layouts/sidebar/layer/use-click.ts +113 -0
  79. package/src/layouts/sidebar/layer/use-drag.ts +167 -0
  80. package/src/layouts/sidebar/layer/use-keybinding.ts +54 -0
  81. package/src/layouts/sidebar/layer/use-node-status.ts +114 -0
  82. package/src/layouts/workspace/Breadcrumb.vue +35 -0
  83. package/src/layouts/workspace/Workspace.vue +46 -0
  84. package/src/layouts/workspace/viewer/NodeListMenu.vue +115 -0
  85. package/src/layouts/workspace/viewer/Stage.vue +246 -0
  86. package/src/layouts/workspace/viewer/StageOverlay.vue +68 -0
  87. package/src/layouts/workspace/viewer/ViewerMenu.vue +145 -0
  88. package/src/services/BaseService.ts +230 -0
  89. package/src/services/codeBlock.ts +327 -0
  90. package/src/services/componentList.ts +58 -0
  91. package/src/services/dataSource.ts +216 -0
  92. package/src/services/dep.ts +152 -0
  93. package/src/services/editor.ts +1135 -0
  94. package/src/services/events.ts +93 -0
  95. package/src/services/history.ts +126 -0
  96. package/src/services/keybinding.ts +220 -0
  97. package/src/services/props.ts +286 -0
  98. package/src/services/stageOverlay.ts +212 -0
  99. package/src/services/storage.ts +155 -0
  100. package/src/services/ui.ts +157 -0
  101. package/src/shims-vue.d.ts +6 -0
  102. package/src/theme/breadcrumb.scss +6 -0
  103. package/src/theme/code-block.scss +6 -0
  104. package/src/theme/code-editor.scss +38 -0
  105. package/src/theme/common/var.scss +14 -0
  106. package/src/theme/component-list-panel.scss +95 -0
  107. package/src/theme/content-menu.scss +76 -0
  108. package/src/theme/data-source-field-select.scss +16 -0
  109. package/src/theme/data-source-field.scss +12 -0
  110. package/src/theme/data-source-fields.scss +13 -0
  111. package/src/theme/data-source-input.scss +18 -0
  112. package/src/theme/data-source-methods.scss +13 -0
  113. package/src/theme/data-source.scss +28 -0
  114. package/src/theme/event.scss +37 -0
  115. package/src/theme/floating-box.scss +32 -0
  116. package/src/theme/framework.scss +69 -0
  117. package/src/theme/icon.scss +12 -0
  118. package/src/theme/index.scss +10 -0
  119. package/src/theme/key-value.scss +20 -0
  120. package/src/theme/layer-panel.scss +26 -0
  121. package/src/theme/layout.scss +9 -0
  122. package/src/theme/nav-menu.scss +78 -0
  123. package/src/theme/page-bar.scss +102 -0
  124. package/src/theme/page-fragment-select.scss +14 -0
  125. package/src/theme/props-panel.scss +55 -0
  126. package/src/theme/resizer.scss +66 -0
  127. package/src/theme/ruler.scss +38 -0
  128. package/src/theme/search-input.scss +14 -0
  129. package/src/theme/sidebar.scss +79 -0
  130. package/src/theme/stage.scss +76 -0
  131. package/src/theme/theme.scss +28 -0
  132. package/src/theme/tree.scss +89 -0
  133. package/src/theme/workspace.scss +9 -0
  134. package/src/type.ts +780 -0
  135. package/src/utils/compose.ts +52 -0
  136. package/src/utils/config.ts +29 -0
  137. package/src/utils/content-menu.ts +95 -0
  138. package/src/utils/data-source/formConfigs/base.ts +30 -0
  139. package/src/utils/data-source/formConfigs/http.ts +60 -0
  140. package/src/utils/data-source/index.ts +249 -0
  141. package/src/utils/editor.ts +313 -0
  142. package/src/utils/idle-task.ts +72 -0
  143. package/src/utils/index.ts +24 -0
  144. package/src/utils/keybinding-config.ts +125 -0
  145. package/src/utils/logger.ts +47 -0
  146. package/src/utils/monaco-editor.ts +8 -0
  147. package/src/utils/operator.ts +106 -0
  148. package/src/utils/props.ts +407 -0
  149. package/src/utils/scroll-viewer.ts +165 -0
  150. package/src/utils/tree.ts +15 -0
  151. package/src/utils/undo-redo.ts +76 -0
  152. package/types/editorProps.d.ts +3 -1
  153. package/types/fields/CondOpSelect.vue.d.ts +17 -0
  154. package/types/fields/DataSourceFieldSelect/FieldSelect.vue.d.ts +36 -0
  155. package/types/fields/{DataSourceFieldSelect.vue.d.ts → DataSourceFieldSelect/Index.vue.d.ts} +1 -1
  156. package/types/fields/DisplayConds.vue.d.ts +32 -0
  157. package/types/index.d.ts +3 -1
  158. package/types/layouts/Framework.vue.d.ts +3 -1
  159. package/types/layouts/PropsPanel.vue.d.ts +21 -21
  160. package/types/layouts/page-bar/PageBar.vue.d.ts +6 -0
  161. package/types/layouts/page-bar/PageBarScrollContainer.vue.d.ts +3 -0
  162. package/types/layouts/page-bar/PageList.vue.d.ts +25 -0
  163. package/types/services/ui.d.ts +1 -0
  164. package/types/type.d.ts +30 -4
  165. package/types/utils/data-source/index.d.ts +1 -0
  166. package/types/utils/props.d.ts +12 -0
@@ -0,0 +1,255 @@
1
+ <template>
2
+ <div class="m-editor-data-source-fields">
3
+ <MagicTable :data="model[name]" :columns="columns"></MagicTable>
4
+
5
+ <div class="m-editor-data-source-fields-footer">
6
+ <TMagicButton size="small" type="primary" :disabled="disabled" plain @click="newHandler()">添加</TMagicButton>
7
+ </div>
8
+
9
+ <FloatingBox
10
+ v-model:visible="addDialogVisible"
11
+ v-model:width="width"
12
+ v-model:height="editorHeight"
13
+ :title="drawerTitle"
14
+ :position="boxPosition"
15
+ >
16
+ <template #body>
17
+ <MFormBox
18
+ ref="addDialog"
19
+ label-width="120px"
20
+ :config="formConfig"
21
+ :values="formValues"
22
+ :parentValues="model[name]"
23
+ :disabled="disabled"
24
+ @submit="formChangeHandler"
25
+ ></MFormBox>
26
+ </template>
27
+ </FloatingBox>
28
+ </div>
29
+ </template>
30
+
31
+ <script setup lang="ts">
32
+ import { inject, Ref, ref } from 'vue';
33
+
34
+ import { TMagicButton, tMagicMessageBox, TMagicSwitch } from '@tmagic/design';
35
+ import { type FieldProps, type FormConfig, type FormState, MFormBox } from '@tmagic/form';
36
+ import type { MockSchema } from '@tmagic/schema';
37
+ import { type ColumnConfig, MagicTable } from '@tmagic/table';
38
+ import { getDefaultValueFromFields } from '@tmagic/utils';
39
+
40
+ import FloatingBox from '@editor/components/FloatingBox.vue';
41
+ import { useNextFloatBoxPosition } from '@editor/hooks/use-next-float-box-position';
42
+ import CodeEditor from '@editor/layouts/CodeEditor.vue';
43
+ import { Services } from '@editor/type';
44
+
45
+ import { useEditorContentHeight } from '..';
46
+
47
+ defineOptions({
48
+ name: 'MFieldsDataSourceMocks',
49
+ });
50
+
51
+ const props = withDefaults(
52
+ defineProps<
53
+ FieldProps<{
54
+ type: 'data-source-mocks';
55
+ }>
56
+ >(),
57
+ {
58
+ disabled: false,
59
+ },
60
+ );
61
+
62
+ const emit = defineEmits(['change']);
63
+
64
+ const services = inject<Services>('services');
65
+ const width = defineModel<number>('width', { default: 670 });
66
+
67
+ const drawerTitle = ref('');
68
+ const formValues = ref<Record<string, any>>({});
69
+
70
+ const formConfig: FormConfig = [
71
+ { name: 'index', type: 'hidden', filter: 'number', defaultValue: -1 },
72
+ {
73
+ name: 'title',
74
+ text: '名称',
75
+ rules: [
76
+ {
77
+ required: true,
78
+ message: '请输入字段名称',
79
+ },
80
+ {
81
+ required: true,
82
+ message: '请输入名称',
83
+ },
84
+ ],
85
+ },
86
+ {
87
+ name: 'description',
88
+ text: '描述',
89
+ },
90
+ {
91
+ name: 'enable',
92
+ text: '启用',
93
+ type: 'switch',
94
+ },
95
+ {
96
+ name: 'useInEditor',
97
+ text: '编辑器中使用',
98
+ type: 'switch',
99
+ },
100
+ {
101
+ name: 'data',
102
+ text: 'mock数据',
103
+ type: 'vs-code',
104
+ language: 'json',
105
+ options: inject('codeOptions', {}),
106
+ defaultValue: '{}',
107
+ height: '400px',
108
+ onChange: (formState: FormState | undefined, v: string | any) => {
109
+ if (typeof v !== 'string') return v;
110
+ return JSON.parse(v);
111
+ },
112
+ rules: [
113
+ {
114
+ validator: ({ value, callback }) => {
115
+ if (typeof value !== 'string') return callback();
116
+
117
+ try {
118
+ // 检测json是否存在语法错误
119
+ JSON.parse(value);
120
+
121
+ callback();
122
+ } catch (error: any) {
123
+ callback(error);
124
+ }
125
+ },
126
+ },
127
+ ],
128
+ },
129
+ ];
130
+
131
+ const columns: ColumnConfig[] = [
132
+ {
133
+ type: 'expand',
134
+ component: CodeEditor,
135
+ props: (row: MockSchema) => ({
136
+ initValues: row.data,
137
+ language: 'json',
138
+ height: '150px',
139
+ options: {
140
+ readOnly: true,
141
+ },
142
+ }),
143
+ },
144
+ {
145
+ label: '名称',
146
+ prop: 'title',
147
+ },
148
+ {
149
+ label: '描述',
150
+ prop: 'description',
151
+ },
152
+ {
153
+ label: '是否启用',
154
+ prop: 'enable',
155
+ type: 'component',
156
+ component: TMagicSwitch,
157
+ props: (row: MockSchema) => ({
158
+ modelValue: row.enable,
159
+ activeValue: true,
160
+ inactiveValue: false,
161
+ }),
162
+ listeners: (row: MockSchema, index: number) => ({
163
+ 'update:modelValue': (v: boolean) => {
164
+ toggleValue(row, 'enable', v, index);
165
+ },
166
+ }),
167
+ },
168
+ {
169
+ label: '编辑器中使用',
170
+ prop: 'useInEditor',
171
+ type: 'component',
172
+ component: TMagicSwitch,
173
+ props: (row: MockSchema) => ({
174
+ modelValue: row.useInEditor,
175
+ activeValue: true,
176
+ inactiveValue: false,
177
+ }),
178
+ listeners: (row: MockSchema, index: number) => ({
179
+ 'update:modelValue': (v: boolean) => {
180
+ toggleValue(row, 'useInEditor', v, index);
181
+ },
182
+ }),
183
+ },
184
+ {
185
+ label: '操作',
186
+ fixed: 'right',
187
+ actions: [
188
+ {
189
+ text: '编辑',
190
+ handler: (row: MockSchema, index: number) => {
191
+ formValues.value = {
192
+ ...row,
193
+ index,
194
+ };
195
+ drawerTitle.value = `编辑${row.title}`;
196
+ calcBoxPosition();
197
+ addDialogVisible.value = true;
198
+ },
199
+ },
200
+ {
201
+ text: '删除',
202
+ buttonType: 'danger',
203
+ handler: async (row: MockSchema, index: number) => {
204
+ await tMagicMessageBox.confirm(`确定删除${row.title}?`, '提示');
205
+ props.model[props.name].splice(index, 1);
206
+ emit('change', props.model[props.name]);
207
+ },
208
+ },
209
+ ],
210
+ },
211
+ ];
212
+
213
+ const newHandler = () => {
214
+ const isFirstRow = props.model[props.name].length === 0;
215
+ formValues.value = {
216
+ data: getDefaultValueFromFields(props.model.fields || []),
217
+ useInEditor: isFirstRow,
218
+ enable: isFirstRow,
219
+ };
220
+ drawerTitle.value = '新增Mock';
221
+ calcBoxPosition();
222
+ addDialogVisible.value = true;
223
+ };
224
+
225
+ const formChangeHandler = ({ index, ...value }: Record<string, any>) => {
226
+ if (index > -1) {
227
+ props.model[props.name][index] = value;
228
+ } else {
229
+ props.model[props.name].push(value);
230
+ }
231
+
232
+ addDialogVisible.value = false;
233
+
234
+ emit('change', props.model[props.name]);
235
+ };
236
+
237
+ const toggleValue = (row: MockSchema, key: 'enable' | 'useInEditor', value: boolean, index: number) => {
238
+ if (value) {
239
+ props.model[props.name].forEach((item: MockSchema) => {
240
+ item[key] = false;
241
+ });
242
+ }
243
+
244
+ formChangeHandler({
245
+ ...row,
246
+ [key]: value,
247
+ index,
248
+ });
249
+ };
250
+
251
+ const addDialogVisible = defineModel<boolean>('visible', { default: false });
252
+ const { height: editorHeight } = useEditorContentHeight();
253
+ const parentFloating = inject<Ref<HTMLDivElement | null>>('parentFloating', ref(null));
254
+ const { boxPosition, calcBoxPosition } = useNextFloatBoxPosition(services?.uiService, parentFloating);
255
+ </script>
@@ -0,0 +1,98 @@
1
+ <template>
2
+ <div class="m-fields-data-source-select">
3
+ <MSelect
4
+ :model="model"
5
+ :name="name"
6
+ :size="size"
7
+ :prop="prop"
8
+ :disabled="disabled"
9
+ :config="selectConfig"
10
+ :last-values="lastValues"
11
+ @change="changeHandler"
12
+ ></MSelect>
13
+
14
+ <TMagicButton
15
+ v-if="model[name] && hasDataSourceSidePanel"
16
+ class="m-fields-select-action-button"
17
+ :size="size"
18
+ @click="editHandler"
19
+ ><MIcon :icon="!notEditable ? Edit : View"></MIcon
20
+ ></TMagicButton>
21
+ </div>
22
+ </template>
23
+
24
+ <script setup lang="ts">
25
+ import { computed, inject } from 'vue';
26
+ import { Edit, View } from '@element-plus/icons-vue';
27
+
28
+ import { TMagicButton } from '@tmagic/design';
29
+ import { type FieldProps, filterFunction, type FormState, MSelect, type SelectConfig } from '@tmagic/form';
30
+
31
+ import MIcon from '@editor/components/Icon.vue';
32
+ import type { DataSourceSelect, EventBus, Services } from '@editor/type';
33
+ import { SideItemKey } from '@editor/type';
34
+
35
+ defineOptions({
36
+ name: 'MFieldsDataSourceSelect',
37
+ });
38
+
39
+ const emit = defineEmits(['change']);
40
+
41
+ const props = withDefaults(defineProps<FieldProps<DataSourceSelect>>(), {
42
+ disabled: false,
43
+ });
44
+
45
+ const mForm = inject<FormState | undefined>('mForm');
46
+ const { dataSourceService, uiService } = inject<Services>('services') || {};
47
+ const eventBus = inject<EventBus>('eventBus');
48
+
49
+ const dataSources = computed(() => dataSourceService?.get('dataSources') || []);
50
+
51
+ const notEditable = computed(() => filterFunction(mForm, props.config.notEditable, props));
52
+
53
+ const hasDataSourceSidePanel = computed(() =>
54
+ (uiService?.get('sideBarItems') || []).find((item) => item.$key === SideItemKey.DATA_SOURCE),
55
+ );
56
+
57
+ const selectConfig = computed<SelectConfig>(() => {
58
+ const { type, dataSourceType, value, ...config } = props.config;
59
+
60
+ const valueIsId = props.config.value === 'id';
61
+
62
+ return {
63
+ ...config,
64
+ type: 'select',
65
+ valueKey: 'dataSourceId',
66
+ options: dataSources.value
67
+ .filter((ds) => !props.config.dataSourceType || ds.type === props.config.dataSourceType)
68
+ .map((ds) => ({
69
+ value: valueIsId
70
+ ? ds.id
71
+ : {
72
+ isBindDataSource: true,
73
+ dataSourceType: ds.type,
74
+ dataSourceId: ds.id,
75
+ },
76
+ text: ds.title || ds.id,
77
+ })),
78
+ };
79
+ });
80
+
81
+ const changeHandler = (value: any) => {
82
+ emit('change', value);
83
+ };
84
+
85
+ const editHandler = () => {
86
+ const value = props.model[props.name];
87
+
88
+ if (!value) return;
89
+
90
+ const id = typeof value === 'string' ? value : value.dataSourceId;
91
+
92
+ const dataSource = dataSourceService?.getDataSourceById(id);
93
+
94
+ if (!dataSource) return;
95
+
96
+ eventBus?.emit('edit-data-source', id);
97
+ };
98
+ </script>
@@ -0,0 +1,145 @@
1
+ <template>
2
+ <MGroupList
3
+ style="width: 100%"
4
+ :config="config"
5
+ :name="name"
6
+ :disabled="disabled"
7
+ :model="model"
8
+ :last-values="lastValues"
9
+ :prop="prop"
10
+ :size="size"
11
+ ></MGroupList>
12
+ </template>
13
+
14
+ <script lang="ts" setup>
15
+ import { computed, inject } from 'vue';
16
+
17
+ import {
18
+ type FieldProps,
19
+ type FilterFunction,
20
+ filterFunction,
21
+ type FormState,
22
+ type GroupListConfig,
23
+ MGroupList,
24
+ } from '@tmagic/form';
25
+
26
+ import type { Services } from '@editor/type';
27
+ import { getCascaderOptionsFromFields } from '@editor/utils';
28
+
29
+ defineOptions({
30
+ name: 'm-fields-display-conds',
31
+ });
32
+
33
+ const props = withDefaults(
34
+ defineProps<
35
+ FieldProps<{
36
+ titlePrefix?: string;
37
+ parentFields?: string[] | FilterFunction<string[]>;
38
+ }>
39
+ >(),
40
+ {
41
+ disabled: false,
42
+ },
43
+ );
44
+
45
+ const { dataSourceService } = inject<Services>('services') || {};
46
+ const mForm = inject<FormState | undefined>('mForm');
47
+
48
+ const parentFields = computed(() => filterFunction<string[]>(mForm, props.config.parentFields, props) || []);
49
+
50
+ const config = computed<GroupListConfig>(() => ({
51
+ type: 'groupList',
52
+ name: props.name,
53
+ titlePrefix: props.config.titlePrefix,
54
+ expandAll: true,
55
+ items: [
56
+ {
57
+ type: 'table',
58
+ name: 'cond',
59
+ operateColWidth: 50,
60
+ items: [
61
+ parentFields.value.length
62
+ ? {
63
+ type: 'cascader',
64
+ options: () => {
65
+ const [dsId, ...keys] = parentFields.value;
66
+ const ds = dataSourceService?.getDataSourceById(dsId);
67
+ if (!ds) {
68
+ return [];
69
+ }
70
+
71
+ let fields = ds.fields || [];
72
+ keys.forEach((key) => {
73
+ const field = fields.find((f) => f.name === key);
74
+ fields = field?.fields || [];
75
+ });
76
+
77
+ return getCascaderOptionsFromFields(fields, ['string', 'number', 'boolean', 'any']);
78
+ },
79
+ name: 'field',
80
+ value: 'key',
81
+ label: '字段',
82
+ checkStrictly: false,
83
+ }
84
+ : {
85
+ type: 'data-source-field-select',
86
+ name: 'field',
87
+ value: 'key',
88
+ label: '字段',
89
+ checkStrictly: false,
90
+ dataSourceFieldType: ['string', 'number', 'boolean', 'any'],
91
+ },
92
+ {
93
+ type: 'cond-op-select',
94
+ parentFields: parentFields.value,
95
+ label: '条件',
96
+ width: 100,
97
+ name: 'op',
98
+ },
99
+ {
100
+ label: '值',
101
+ width: 100,
102
+ items: [
103
+ {
104
+ name: 'value',
105
+ type: (mForm, { model }) => {
106
+ const [id, ...fieldNames] = model.field;
107
+
108
+ const ds = dataSourceService?.getDataSourceById(id);
109
+
110
+ let fields = ds?.fields || [];
111
+ let type = '';
112
+ (fieldNames || []).forEach((fieldName: string) => {
113
+ const field = fields.find((f) => f.name === fieldName);
114
+ fields = field?.fields || [];
115
+ type = field?.type || '';
116
+ });
117
+
118
+ if (type === 'number') {
119
+ return 'number';
120
+ }
121
+
122
+ if (type === 'boolean') {
123
+ return 'select';
124
+ }
125
+
126
+ return 'text';
127
+ },
128
+ options: [
129
+ { text: 'true', value: true },
130
+ { text: 'false', value: false },
131
+ ],
132
+ display: (vm, { model }) => !['between', 'not_between'].includes(model.op),
133
+ },
134
+ {
135
+ name: 'range',
136
+ type: 'number-range',
137
+ display: (vm, { model }) => ['between', 'not_between'].includes(model.op),
138
+ },
139
+ ],
140
+ },
141
+ ],
142
+ },
143
+ ],
144
+ }));
145
+ </script>