amis-editor 4.0.2-beta.16 → 4.1.0-beta.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (195) hide show
  1. package/dist/component/Breadcrumb.d.ts +23 -2
  2. package/dist/component/Editor.d.ts +19 -0
  3. package/dist/component/Panel/RenderersPanel.d.ts +1 -2
  4. package/dist/component/RegionWrapper.d.ts +15 -8
  5. package/dist/component/RendererThumb.d.ts +5 -5
  6. package/dist/component/VRenderer.d.ts +5 -1
  7. package/dist/component/base/SearchCustomRendererPanel.d.ts +15 -0
  8. package/dist/component/base/SearchPanel.d.ts +83 -0
  9. package/dist/component/base/SearchRendererPanel.d.ts +3 -43
  10. package/dist/exports.min.js +1 -1
  11. package/dist/index.d.ts +4 -1
  12. package/dist/index.min.js +1 -1
  13. package/dist/manager.d.ts +14 -3
  14. package/dist/plugin/Card.d.ts +1 -0
  15. package/dist/plugin/Cards.d.ts +1 -0
  16. package/dist/plugin/Carousel.d.ts +1 -0
  17. package/dist/plugin/Chart.d.ts +1 -0
  18. package/dist/plugin/Collapse.d.ts +1 -0
  19. package/dist/plugin/Custom.d.ts +3 -0
  20. package/dist/plugin/CustomRegion.d.ts +43 -0
  21. package/dist/plugin/Flex.d.ts +1 -0
  22. package/dist/plugin/Form/Control.d.ts +1 -0
  23. package/dist/plugin/Form/InputURL.d.ts +1 -0
  24. package/dist/plugin/Grid.d.ts +1 -0
  25. package/dist/plugin/HBox.d.ts +1 -0
  26. package/dist/plugin/Json.d.ts +1 -0
  27. package/dist/plugin/List.d.ts +1 -0
  28. package/dist/plugin/Mapping.d.ts +1 -0
  29. package/dist/plugin/Markdown.d.ts +1 -0
  30. package/dist/plugin/Nav.d.ts +1 -0
  31. package/dist/plugin/Panel/Outline.d.ts +8 -0
  32. package/dist/plugin/Progress.d.ts +1 -0
  33. package/dist/plugin/QRCode.d.ts +1 -0
  34. package/dist/plugin/Reset.d.ts +0 -1
  35. package/dist/plugin/Service.d.ts +1 -0
  36. package/dist/plugin/Sparkline.d.ts +1 -0
  37. package/dist/plugin/Status.d.ts +1 -0
  38. package/dist/plugin/Steps.d.ts +1 -0
  39. package/dist/plugin/Submit.d.ts +0 -1
  40. package/dist/plugin/TableView.d.ts +1 -0
  41. package/dist/plugin/Tasks.d.ts +1 -0
  42. package/dist/plugin/TooltipWrapper.d.ts +2 -0
  43. package/dist/plugin/Video.d.ts +1 -0
  44. package/dist/plugin/WebComponent.d.ts +1 -0
  45. package/dist/plugin/Wrapper.d.ts +1 -0
  46. package/dist/plugin.d.ts +2 -2
  47. package/dist/store/editor.d.ts +20 -2
  48. package/dist/store/node.d.ts +6 -0
  49. package/dist/style.css +1 -1
  50. package/dist/util.d.ts +7 -2
  51. package/package.json +6 -3
  52. package/src/component/schemaTpl.tsx +2155 -0
  53. package/src/plugin/.DS_Store +0 -0
  54. package/src/plugin/Alert.tsx +87 -0
  55. package/src/plugin/AnchorNav.tsx +233 -0
  56. package/src/plugin/Audio.tsx +161 -0
  57. package/src/plugin/Avatar.tsx +77 -0
  58. package/src/plugin/Breadcrumb.tsx +107 -0
  59. package/src/plugin/Button.tsx +283 -0
  60. package/src/plugin/ButtonGroup.tsx +88 -0
  61. package/src/plugin/ButtonToolbar.tsx +89 -0
  62. package/src/plugin/CRUD.tsx +1832 -0
  63. package/src/plugin/Card.tsx +290 -0
  64. package/src/plugin/Cards.tsx +315 -0
  65. package/src/plugin/Carousel.tsx +386 -0
  66. package/src/plugin/Chart.tsx +218 -0
  67. package/src/plugin/CodeView.tsx +60 -0
  68. package/src/plugin/Collapse.tsx +143 -0
  69. package/src/plugin/CollapseGroup.tsx +167 -0
  70. package/src/plugin/Container.tsx +44 -0
  71. package/src/plugin/Custom.tsx +128 -0
  72. package/src/plugin/CustomRegion.tsx +150 -0
  73. package/src/plugin/Date.tsx +81 -0
  74. package/src/plugin/Datetime.tsx +75 -0
  75. package/src/plugin/Dialog.tsx +178 -0
  76. package/src/plugin/Divider.tsx +36 -0
  77. package/src/plugin/Drawer.tsx +217 -0
  78. package/src/plugin/DropDownButton.tsx +234 -0
  79. package/src/plugin/Each.tsx +152 -0
  80. package/src/plugin/ErrorRenderer.tsx +15 -0
  81. package/src/plugin/Flex.tsx +156 -0
  82. package/src/plugin/Form/ButtonGroupSelect.tsx +86 -0
  83. package/src/plugin/Form/ButtonToolbar.tsx +121 -0
  84. package/src/plugin/Form/ChainedSelect.tsx +70 -0
  85. package/src/plugin/Form/Checkbox.tsx +87 -0
  86. package/src/plugin/Form/Checkboxes.tsx +167 -0
  87. package/src/plugin/Form/CodeEditor.tsx +91 -0
  88. package/src/plugin/Form/Combo.tsx +582 -0
  89. package/src/plugin/Form/ConditionBuilder.tsx +324 -0
  90. package/src/plugin/Form/Control.tsx +139 -0
  91. package/src/plugin/Form/DiffEditor.tsx +117 -0
  92. package/src/plugin/Form/FieldSet.tsx +175 -0
  93. package/src/plugin/Form/Form.tsx +692 -0
  94. package/src/plugin/Form/Formula.tsx +91 -0
  95. package/src/plugin/Form/Group.tsx +300 -0
  96. package/src/plugin/Form/Hidden.tsx +56 -0
  97. package/src/plugin/Form/InputArray.tsx +228 -0
  98. package/src/plugin/Form/InputCity.tsx +93 -0
  99. package/src/plugin/Form/InputColor.tsx +123 -0
  100. package/src/plugin/Form/InputDate.tsx +175 -0
  101. package/src/plugin/Form/InputDateRange.tsx +225 -0
  102. package/src/plugin/Form/InputDateTime.tsx +183 -0
  103. package/src/plugin/Form/InputDateTimeRange.tsx +221 -0
  104. package/src/plugin/Form/InputEmail.tsx +33 -0
  105. package/src/plugin/Form/InputExcel.tsx +85 -0
  106. package/src/plugin/Form/InputFile.tsx +228 -0
  107. package/src/plugin/Form/InputGroup.tsx +105 -0
  108. package/src/plugin/Form/InputImage.tsx +277 -0
  109. package/src/plugin/Form/InputKV.tsx +72 -0
  110. package/src/plugin/Form/InputMonth.tsx +35 -0
  111. package/src/plugin/Form/InputMonthRange.tsx +195 -0
  112. package/src/plugin/Form/InputNumber.tsx +97 -0
  113. package/src/plugin/Form/InputPassword.tsx +33 -0
  114. package/src/plugin/Form/InputQuarter.tsx +35 -0
  115. package/src/plugin/Form/InputQuarterRange.tsx +195 -0
  116. package/src/plugin/Form/InputRange.tsx +121 -0
  117. package/src/plugin/Form/InputRating.tsx +78 -0
  118. package/src/plugin/Form/InputRepeat.tsx +69 -0
  119. package/src/plugin/Form/InputRichText.tsx +197 -0
  120. package/src/plugin/Form/InputSubForm.tsx +198 -0
  121. package/src/plugin/Form/InputTable.tsx +434 -0
  122. package/src/plugin/Form/InputTag.tsx +81 -0
  123. package/src/plugin/Form/InputText.tsx +186 -0
  124. package/src/plugin/Form/InputTime.tsx +95 -0
  125. package/src/plugin/Form/InputTree.tsx +240 -0
  126. package/src/plugin/Form/InputURL.tsx +34 -0
  127. package/src/plugin/Form/InputYear.tsx +35 -0
  128. package/src/plugin/Form/Item.tsx +325 -0
  129. package/src/plugin/Form/ListSelect.tsx +84 -0
  130. package/src/plugin/Form/LocationPicker.tsx +75 -0
  131. package/src/plugin/Form/MatrixCheckboxes.tsx +147 -0
  132. package/src/plugin/Form/NestedSelect.tsx +222 -0
  133. package/src/plugin/Form/Picker.tsx +217 -0
  134. package/src/plugin/Form/Radios.tsx +130 -0
  135. package/src/plugin/Form/Select.tsx +216 -0
  136. package/src/plugin/Form/Static.tsx +335 -0
  137. package/src/plugin/Form/Switch.tsx +116 -0
  138. package/src/plugin/Form/TabsTransfer.tsx +270 -0
  139. package/src/plugin/Form/Textarea.tsx +94 -0
  140. package/src/plugin/Form/Transfer.tsx +379 -0
  141. package/src/plugin/Form/TreeSelect.tsx +263 -0
  142. package/src/plugin/Form/UUID.tsx +48 -0
  143. package/src/plugin/Grid.tsx +799 -0
  144. package/src/plugin/HBox.tsx +727 -0
  145. package/src/plugin/IFrame.tsx +72 -0
  146. package/src/plugin/Image.tsx +318 -0
  147. package/src/plugin/Images.tsx +238 -0
  148. package/src/plugin/Json.tsx +76 -0
  149. package/src/plugin/Link.tsx +95 -0
  150. package/src/plugin/List.tsx +278 -0
  151. package/src/plugin/ListItem.tsx +233 -0
  152. package/src/plugin/Log.tsx +52 -0
  153. package/src/plugin/Mapping.tsx +156 -0
  154. package/src/plugin/Markdown.tsx +47 -0
  155. package/src/plugin/Nav.tsx +186 -0
  156. package/src/plugin/Operation.tsx +97 -0
  157. package/src/plugin/Others/Action.tsx +428 -0
  158. package/src/plugin/Others/BasicToolbar.tsx +591 -0
  159. package/src/plugin/Others/DataDebug.tsx +134 -0
  160. package/src/plugin/Others/TableCell.tsx +480 -0
  161. package/src/plugin/Others/Unknown.tsx +37 -0
  162. package/src/plugin/Page.tsx +308 -0
  163. package/src/plugin/Panel/AvailableRenderers.tsx +41 -0
  164. package/src/plugin/Panel/Code.tsx +44 -0
  165. package/src/plugin/Panel/Name.tsx +26 -0
  166. package/src/plugin/Panel/Outline.tsx +40 -0
  167. package/src/plugin/Panel.tsx +243 -0
  168. package/src/plugin/Plain.tsx +91 -0
  169. package/src/plugin/Progress.tsx +132 -0
  170. package/src/plugin/Property.tsx +139 -0
  171. package/src/plugin/QRCode.tsx +98 -0
  172. package/src/plugin/Reset.tsx +23 -0
  173. package/src/plugin/Service.tsx +167 -0
  174. package/src/plugin/Sparkline.tsx +40 -0
  175. package/src/plugin/Status.tsx +78 -0
  176. package/src/plugin/Steps.tsx +140 -0
  177. package/src/plugin/Submit.tsx +23 -0
  178. package/src/plugin/Table.tsx +440 -0
  179. package/src/plugin/TableView.tsx +711 -0
  180. package/src/plugin/Tabs.tsx +364 -0
  181. package/src/plugin/Tasks.tsx +276 -0
  182. package/src/plugin/Time.tsx +75 -0
  183. package/src/plugin/TooltipWrapper.tsx +193 -0
  184. package/src/plugin/Tpl.tsx +162 -0
  185. package/src/plugin/Video.tsx +160 -0
  186. package/src/plugin/WebComponent.tsx +56 -0
  187. package/src/plugin/Wizard.tsx +743 -0
  188. package/src/plugin/Wrapper.tsx +107 -0
  189. package/src/plugin.ts +1046 -0
  190. package/dist/150a58f3318ca7541ed9.png +0 -0
  191. package/dist/471adb97c322b226e589.png +0 -0
  192. package/dist/4de5f42360bc5946c3c2.png +0 -0
  193. package/dist/4e9968bba3855f088fed.png +0 -0
  194. package/dist/7f09c38ebc687fea847a.png +0 -0
  195. package/dist/c94073576487510314ea.png +0 -0
@@ -0,0 +1,2155 @@
1
+ /**
2
+ * @file amis schema 配置模板,主要很多地方都要全部配置的化,
3
+ * 会有很多份,而且改起来很麻烦,复用率高的放在这管理。
4
+ */
5
+ import {isObject} from '../util';
6
+ import find = require('lodash/find');
7
+ import {normalizeOptions, str2rules, buildApi, Select, Html} from 'amis';
8
+ import flatten from 'lodash/flatten';
9
+ import React = require('react');
10
+ import {InputComponentName} from './base/InputComponentName';
11
+ import remarkTpl from './remarkTpl';
12
+
13
+ const tpls: {
14
+ [propName: string]: any;
15
+ } = {
16
+ formItemName: {
17
+ label: '字段名',
18
+ name: 'name',
19
+ type: 'input-text'
20
+ // validations: {
21
+ // matchRegexp: /^[a-z\$][a-z0-0\-_]*$/i
22
+ // },
23
+ // validationErrors: {
24
+ // "matchRegexp": "请输入合法的变量名"
25
+ // },
26
+ // validateOnChange: false
27
+ },
28
+
29
+ formItemMode: {
30
+ label: '表单项展示模式',
31
+ name: 'mode',
32
+ type: 'button-group-select',
33
+ size: 'sm',
34
+ option: '继承',
35
+ // mode: 'inline',
36
+ // className: 'w-full',
37
+ pipeIn: defaultValue(''),
38
+ options: [
39
+ {
40
+ label: '继承',
41
+ value: ''
42
+ },
43
+
44
+ {
45
+ label: '正常',
46
+ value: 'normal'
47
+ },
48
+
49
+ {
50
+ label: '内联',
51
+ value: 'inline'
52
+ },
53
+
54
+ {
55
+ label: '水平',
56
+ value: 'horizontal'
57
+ }
58
+ ]
59
+ },
60
+
61
+ formItemInline: {
62
+ label: '表单项内联',
63
+ name: 'inline',
64
+ type: 'switch',
65
+ visibleOn: 'data.mode != "inline"',
66
+ mode: 'inline',
67
+ className: 'w-full',
68
+ pipeIn: defaultValue(false)
69
+ // onChange: (value:any, origin:any, item:any, form:any) => form.getValueByName('size') === "full" && form.setValueByName('')
70
+ },
71
+
72
+ formItemSize: {
73
+ name: 'size',
74
+ label: '控件尺寸',
75
+ type: 'button-group-select',
76
+ size: 'sm',
77
+ pipeIn: defaultValue('full'),
78
+ // mode: 'inline',
79
+ // className: 'w-full',
80
+ options: [
81
+ {
82
+ label: '极小',
83
+ value: 'xs'
84
+ },
85
+
86
+ {
87
+ label: '小',
88
+ value: 'sm'
89
+ },
90
+
91
+ {
92
+ label: '中',
93
+ value: 'md'
94
+ },
95
+
96
+ {
97
+ label: '大',
98
+ value: 'lg'
99
+ },
100
+
101
+ {
102
+ label: '默认',
103
+ value: ''
104
+ }
105
+ ]
106
+ },
107
+
108
+ minLength: {
109
+ name: 'minLength',
110
+ type: 'input-number',
111
+ label: '限制最小数量'
112
+ },
113
+
114
+ maxLength: {
115
+ name: 'maxLength',
116
+ type: 'input-number',
117
+ label: '限制最大数量'
118
+ },
119
+
120
+ label: [
121
+ {
122
+ label: 'Label',
123
+ name: 'label',
124
+ type: 'input-text',
125
+ hiddenOn: 'data.label === false'
126
+ },
127
+ {
128
+ name: 'label',
129
+ label: '隐藏 Label',
130
+ type: 'switch',
131
+ mode: 'inline',
132
+ className: 'w-full',
133
+ pipeIn: (value: any) => value === false,
134
+ pipeOut: (value: any) => (value === true ? false : ''),
135
+ visibleOn:
136
+ '__props__.formMode === "horizontal" || data.mode === "horizontal" || data.label ===false',
137
+ description: '当 form 为水平布局时有用,可以用来去掉间隔。'
138
+ }
139
+ ],
140
+
141
+ placeholder: {
142
+ label: '占位符',
143
+ name: 'placeholder',
144
+ type: 'input-text',
145
+ placeholder: '占位符'
146
+ },
147
+
148
+ tabs: (
149
+ config: Array<{
150
+ title: string;
151
+ body: Array<any>;
152
+ }>
153
+ ) => {
154
+ return {
155
+ type: 'tabs',
156
+ tabsMode: 'line', // tiled
157
+ className: 'editor-prop-config-tabs',
158
+ contentClassName:
159
+ 'no-border editor-prop-config-tabs-cont hoverShowScrollBar',
160
+ tabs: config
161
+ .filter(item => item)
162
+ .map(item => ({
163
+ ...item,
164
+ body: flatten(item.body)
165
+ }))
166
+ };
167
+ },
168
+
169
+ collapse: (
170
+ config: Array<{
171
+ title: string;
172
+ body: Array<any>;
173
+ }>
174
+ ) => {
175
+ return {
176
+ type: 'wrapper',
177
+ className: 'editor-prop-config-collapse',
178
+ body: config
179
+ .filter(item => item)
180
+ .map(item => ({
181
+ type: 'collapse',
182
+ headingClassName: 'editor-prop-config-head',
183
+ bodyClassName: 'editor-prop-config-body',
184
+ ...item,
185
+ body: flatten(item.body)
186
+ }))
187
+ };
188
+ },
189
+
190
+ fieldSet: (config: {
191
+ title: string;
192
+ body: Array<any>;
193
+ collapsed?: boolean;
194
+ collapsable?: boolean;
195
+ }) => {
196
+ return {
197
+ collapsable: true,
198
+ collapsed: false,
199
+ ...config,
200
+ type: 'fieldset',
201
+ title: config.title,
202
+ body: flatten(config.body.filter((item: any) => item))
203
+ };
204
+ },
205
+
206
+ clearable: {
207
+ type: 'switch',
208
+ name: 'clearable',
209
+ mode: 'inline',
210
+ className: 'w-full',
211
+ label: '启用清除按钮'
212
+ },
213
+
214
+ hint: {
215
+ label: '输入提示',
216
+ type: 'input-text',
217
+ name: 'hint',
218
+ description: '当输入框获得焦点的时候显示,用来提示用户输入内容。'
219
+ },
220
+
221
+ remark: remarkTpl({name: 'remark', label: '控件提示'}),
222
+
223
+ labelRemark: remarkTpl({name: 'labelRemark', label: '标题提示'}),
224
+
225
+ expression: {
226
+ type: 'input-text',
227
+ description: '支持 JS 表达式,如:`this.xxx == 1`'
228
+ },
229
+
230
+ icon: {
231
+ label: '图标',
232
+ type: 'icon-picker',
233
+ name: 'icon',
234
+ placeholder: '点击选择图标',
235
+ clearable: true,
236
+ description: ''
237
+ },
238
+
239
+ size: {
240
+ label: '控件尺寸',
241
+ type: 'button-group-select',
242
+ name: 'size',
243
+ size: 'sm',
244
+ clearable: true,
245
+ options: [
246
+ {
247
+ label: '极小',
248
+ value: 'xs'
249
+ },
250
+ {
251
+ label: '小',
252
+ value: 'sm'
253
+ },
254
+ {
255
+ label: '中',
256
+ value: 'md'
257
+ },
258
+ {
259
+ label: '大',
260
+ value: 'lg'
261
+ }
262
+ ]
263
+ },
264
+
265
+ name: {
266
+ label: '名字',
267
+ name: 'name',
268
+ type: 'input-text',
269
+ description: '需要联动时才需要,其他组件可以通过这个名字跟当前组件联动',
270
+ placeholder: '请输入字母或者数字'
271
+ },
272
+
273
+ reload: {
274
+ label: '刷新目标组件',
275
+ name: 'reload',
276
+ asFormItem: true,
277
+ // type: 'input-text',
278
+ component: InputComponentName,
279
+ description:
280
+ '可以指定操作完成后刷新目标组件,请填写目标组件的 <code>name</code> 属性,多个组件请用<code>,</code>隔开,如果目标组件为表单项,请先填写表单的名字,再用<code>.</code>连接表单项的名字如:<code>xxForm.xxControl</code>。另外如果刷新目标对象设置为 <code>window</code>,则会刷新整个页面。',
281
+ labelRemark: {
282
+ trigger: 'click',
283
+ className: 'm-l-xs',
284
+ rootClose: true,
285
+ content:
286
+ '设置名字后,当前组件操作完成会触发目标组件(根据设置的名字)的刷新。',
287
+ placement: 'left'
288
+ }
289
+ },
290
+
291
+ className: {
292
+ label: 'CSS 类名',
293
+ type: 'ae-classname',
294
+ name: 'className',
295
+ labelRemark: {
296
+ trigger: 'click',
297
+ className: 'm-l-xs',
298
+ rootClose: true,
299
+ content:
300
+ '有哪些辅助类 CSS 类名?请前往 <a href="https://baidu.github.io/amis/docs/concepts/style" target="_blank">样式说明</a>,除此之外你可以添加自定义类名,然后在系统配置中添加自定义样式。',
301
+ placement: 'left'
302
+ }
303
+ },
304
+
305
+ apiControl: (patch: any = {}) => {
306
+ const {name, label, value, description, sampleBuilder, ...rest} = patch;
307
+
308
+ return {
309
+ type: 'ae-apiControl',
310
+ label,
311
+ name,
312
+ description,
313
+ labelRemark: sampleBuilder
314
+ ? {
315
+ icon: '',
316
+ label: '示例',
317
+ title: '接口返回示例',
318
+ tooltipClassName: 'ae-ApiSample-tooltip',
319
+ render: (data: any) => (
320
+ <Html
321
+ className="ae-ApiSample"
322
+ inline={false}
323
+ html={`
324
+ <pre><code>${sampleBuilder(data)}</code></pre>
325
+ `}
326
+ />
327
+ ),
328
+ trigger: 'click',
329
+ className: 'm-l-xs',
330
+ rootClose: true,
331
+ placement: 'left'
332
+ }
333
+ : undefined,
334
+ ...rest
335
+ };
336
+ },
337
+
338
+ api: (patch: any = {}) => {
339
+ const {name, label, value, description, sampleBuilder, ...rest} = patch;
340
+
341
+ return {
342
+ type: 'container',
343
+ body: [
344
+ {
345
+ type: 'checkbox',
346
+ label: label || 'API',
347
+ labelRemark: sampleBuilder
348
+ ? {
349
+ icon: '',
350
+ label: '示例',
351
+ title: '接口返回示例',
352
+ tooltipClassName: 'ae-ApiSample-tooltip',
353
+ render: (data: any) => (
354
+ <Html
355
+ className="ae-ApiSample"
356
+ inline={false}
357
+ html={`
358
+ <pre><code>${sampleBuilder(data)}</code></pre>
359
+ `}
360
+ />
361
+ ),
362
+ trigger: 'click',
363
+ className: 'm-l-xs',
364
+ rootClose: true,
365
+ placement: 'left'
366
+ }
367
+ : undefined,
368
+ option: `高级配置`,
369
+ name: name || 'api',
370
+ mode: 'inline',
371
+ className: 'w-full m-b-sm',
372
+ inputClassName: 'pull-right text-sm m-t-sm p-t-none',
373
+ onChange: () => {},
374
+ pipeIn: (value: any) => value && typeof value !== 'string',
375
+ pipeOut: (value: any, originValue: any) => {
376
+ const api = buildApi(originValue);
377
+
378
+ return value
379
+ ? {
380
+ method: api.method,
381
+ url: api.url
382
+ }
383
+ : api.url
384
+ ? `${api.method ? `${api.method}:` : ''}${api.url}`
385
+ : '';
386
+ }
387
+ },
388
+
389
+ {
390
+ name: name || 'api',
391
+ type: 'input-text',
392
+ value,
393
+ placeholder: 'http://',
394
+ description: description,
395
+ visibleOn: `!this.${name || 'api'} || typeof this.${
396
+ name || 'api'
397
+ } === 'string'`,
398
+ className: 'm-b-none',
399
+ labelRemark: {}
400
+ // disabledOn: `data.${name || 'api'} && data.${name || 'api'}.data && Object.keys(data.${name || 'api'}.data).length || data.${name || 'api'} && data.${name || 'api'}.sendOn`,
401
+ },
402
+
403
+ {
404
+ type: 'combo',
405
+ name: name || 'api',
406
+ description: description,
407
+ syncDefaultValue: false,
408
+ multiLine: true,
409
+ visibleOn: `this.${name || 'api'} && typeof this.${
410
+ name || 'api'
411
+ } !== 'string'`,
412
+ className: 'm-b-none',
413
+ messages: {
414
+ validateFailed: '接口配置中存在错误,请仔细检查'
415
+ },
416
+ pipeIn: (value: any) => {
417
+ if (typeof value === 'string') {
418
+ let url = value;
419
+ let method = 'get';
420
+
421
+ const m =
422
+ /^(raw:|external:)?(get|post|put|patch|delete):(.*)$/.exec(url);
423
+ if (m) {
424
+ url = m[1] + m[3];
425
+ method = m[2];
426
+ }
427
+
428
+ return {
429
+ method,
430
+ url
431
+ };
432
+ }
433
+
434
+ return value;
435
+ },
436
+ items: [
437
+ {
438
+ label: '发送方式',
439
+ name: 'method',
440
+ value: 'get',
441
+ type: 'select',
442
+ mode: 'horizontal',
443
+ horizontal: {
444
+ leftFixed: 'sm'
445
+ },
446
+ options: [
447
+ {
448
+ value: 'get',
449
+ label: 'GET'
450
+ },
451
+ {
452
+ value: 'post',
453
+ label: 'POST'
454
+ },
455
+ {
456
+ value: 'put',
457
+ label: 'PUT'
458
+ },
459
+ {
460
+ value: 'patch',
461
+ label: 'PATCH'
462
+ },
463
+ {
464
+ value: 'delete',
465
+ label: 'DELETE'
466
+ }
467
+ ]
468
+ },
469
+
470
+ {
471
+ label: '接口地址',
472
+ type: 'input-text',
473
+ name: 'url',
474
+ placeholder: 'http://',
475
+ required: true
476
+ },
477
+
478
+ {
479
+ type: 'switch',
480
+ label: '数据映射',
481
+ name: 'data',
482
+ mode: 'inline',
483
+ className: 'w-full m-b-xs',
484
+ pipeIn: (value: any) => !!value,
485
+ pipeOut: (value: any) => (value ? {'&': '$$'} : null)
486
+ },
487
+
488
+ {
489
+ type: 'tpl',
490
+ visibleOn: '!this.data',
491
+ inline: false,
492
+ className: 'text-sm text-muted m-b',
493
+ tpl: '当没开启数据映射时,发送 API 的时候会发送尽可能多的数据,如果你想自己控制发送的数据,或者需要额外的数据处理,请开启此选项'
494
+ },
495
+
496
+ {
497
+ type: 'input-kv',
498
+ syncDefaultValue: false,
499
+ name: 'data',
500
+ visibleOn: 'this.data',
501
+ descriptionClassName: 'help-block text-xs m-b-none',
502
+ description:
503
+ '<p>当没开启数据映射时,发送数据自动切成白名单模式,配置啥发送啥,请绑定数据。如:<code>{"a": "\\${a}", "b": 2}</code></p><p>如果希望在默认的基础上定制,请先添加一个 Key 为 `&` Value 为 `\\$$` 作为第一行。</p><div>当值为 <code>__undefined</code>时,表示删除对应的字段,可以结合<code>{"&": "\\$$"}</code>来达到黑名单效果。</div>'
504
+ },
505
+
506
+ {
507
+ label: '发送条件',
508
+ type: 'input-text',
509
+ name: 'sendOn',
510
+ placeholder: '如:this.type == "123"',
511
+ description: '用表达式来设置该请求的发送条件'
512
+ },
513
+
514
+ {
515
+ type: 'switch',
516
+ label: '是否设置缓存',
517
+ name: 'cache',
518
+ mode: 'inline',
519
+ className: 'w-full m-b-xs',
520
+ description: '设置该请求缓存的有效时间',
521
+ pipeIn: (value: any) => !!value,
522
+ pipeOut: (value: any) => (value ? 3000 : undefined)
523
+ },
524
+
525
+ {
526
+ type: 'input-number',
527
+ name: 'cache',
528
+ mode: 'inline',
529
+ min: 0,
530
+ step: 500,
531
+ visibleOn: 'this.cache',
532
+ pipeIn: (value: any) => (typeof value === 'number' ? value : 0)
533
+ },
534
+
535
+ {
536
+ label: '文件下载',
537
+ type: 'switch',
538
+ name: 'responseType',
539
+ mode: 'inline',
540
+ className: 'block',
541
+ pipeIn: (value: any) => value === 'blob',
542
+ pipeOut: (value: any) => (value ? 'blob' : undefined),
543
+ description:
544
+ '当接口为二进制文件下载时请勾选,并设置 Content-Disposition'
545
+ },
546
+
547
+ {
548
+ label: '数据格式',
549
+ type: 'button-group-select',
550
+ name: 'dataType',
551
+ description:
552
+ '发送体格式为:<%= data.dataType === "json" ? "application/json" : data.dataType === "form-data" ? "multipart/form-data" : data.dataType === "form" ? "application/x-www-form-urlencoded" : "" %>,当发送内容中存在文件时会自动使用 form-data 格式。',
553
+ size: 'sm',
554
+ className: 'block',
555
+ mode: 'inline',
556
+ options: [
557
+ {
558
+ label: 'JSON',
559
+ value: 'json'
560
+ },
561
+ {
562
+ label: 'FormData',
563
+ value: 'form-data'
564
+ },
565
+ {
566
+ label: 'Form',
567
+ value: 'form'
568
+ }
569
+ ]
570
+ },
571
+
572
+ {
573
+ type: 'switch',
574
+ label: '数据替换',
575
+ name: 'replaceData',
576
+ mode: 'inline',
577
+ className: 'w-full',
578
+ description: '默认数据都是追加方式,开启这个后是完全替换'
579
+ },
580
+
581
+ {
582
+ type: 'switch',
583
+ label: '返回结果映射',
584
+ name: 'responseData',
585
+ mode: 'inline',
586
+ className: 'w-full m-b-xs',
587
+ pipeIn: (value: any) => !!value,
588
+ pipeOut: (value: any) => (value ? {'&': '$$'} : null)
589
+ },
590
+
591
+ {
592
+ type: 'tpl',
593
+ visibleOn: '!this.responseData',
594
+ inline: false,
595
+ className: 'text-sm text-muted m-b',
596
+ tpl: '如果需要对返回结果做额外的数据处理,请开启此选项'
597
+ },
598
+
599
+ {
600
+ type: 'input-kv',
601
+ syncDefaultValue: false,
602
+ name: 'responseData',
603
+ visibleOn: 'this.responseData',
604
+ descriptionClassName: 'help-block text-xs m-b-none'
605
+ },
606
+
607
+ {
608
+ title: '自定义适配器',
609
+ type: 'fieldSet',
610
+ className: 'm-b-none',
611
+ size: 'sm',
612
+ collapsable: false, // 避免和最外层的属性配置面板的tabs样式重叠
613
+ collapsedOn: '!this.requestAdaptor && !this.adaptor',
614
+ body: [
615
+ {
616
+ name: 'requestAdaptor',
617
+ type: 'js-editor',
618
+ allowFullscreen: true,
619
+ label: '发送适配器',
620
+ description:
621
+ '函数签名:(api) => api, 数据在 api.data 中,修改后返回 api 对象。'
622
+ },
623
+
624
+ {
625
+ name: 'adaptor',
626
+ type: 'js-editor',
627
+ allowFullscreen: true,
628
+ label: '接收适配器',
629
+ description: '函数签名: (payload, response, api) => payload'
630
+ }
631
+ ]
632
+ }
633
+ ]
634
+ }
635
+ ],
636
+ ...rest
637
+ };
638
+ },
639
+
640
+ source: (patch: any = {}) => {
641
+ return getSchemaTpl('api', {
642
+ name: 'source',
643
+ label: '获取选项接口',
644
+ description: '可以通过接口获取动态选项,一次拉取全部。',
645
+ sampleBuilder: (schema: any) =>
646
+ JSON.stringify(
647
+ {
648
+ status: 0,
649
+ msg: '',
650
+ data: {
651
+ options: [
652
+ {
653
+ label: '选项A',
654
+ value: 'a'
655
+ },
656
+
657
+ {
658
+ label: '选项B',
659
+ value: 'b'
660
+ }
661
+ ]
662
+ }
663
+ },
664
+ null,
665
+ 2
666
+ ),
667
+ ...patch
668
+ });
669
+ },
670
+
671
+ autoFill: {
672
+ type: 'input-kv',
673
+ name: 'autoFill',
674
+ label: '自动填充',
675
+ descriptionClassName: 'help-block text-xs m-b-none',
676
+ description:
677
+ '将当前已选中的选项的某个字段的值,自动填充到表单中某个表单项中,支持数据映射'
678
+ },
679
+
680
+ apiString: {
681
+ name: 'api',
682
+ type: 'input-text',
683
+ placeholder: 'http://'
684
+ },
685
+
686
+ required: {
687
+ name: 'required',
688
+ type: 'switch',
689
+ mode: 'inline',
690
+ className: 'w-full',
691
+ label: '是否必填'
692
+ },
693
+
694
+ description: {
695
+ name: 'description',
696
+ type: 'textarea',
697
+ label: '描述',
698
+ pipeIn: (value: any, data: any) => value || data.desc || ''
699
+ },
700
+
701
+ options: {
702
+ label: '选项 Options',
703
+ name: 'options',
704
+ type: 'combo',
705
+ multiple: true,
706
+ draggable: true,
707
+ addButtonText: '新增选项',
708
+ scaffold: {
709
+ label: '',
710
+ value: ''
711
+ },
712
+ items: [
713
+ {
714
+ type: 'input-text',
715
+ name: 'label',
716
+ placeholder: '名称',
717
+ required: true
718
+ },
719
+ {
720
+ type: 'select',
721
+ name: 'value',
722
+ pipeIn: (value: any) => {
723
+ if (typeof value === 'string') {
724
+ return 'text';
725
+ }
726
+ if (typeof value === 'boolean') {
727
+ return 'boolean';
728
+ }
729
+ if (typeof value === 'number') {
730
+ return 'number';
731
+ }
732
+ return 'text';
733
+ },
734
+ pipeOut: (value: any, oldValue: any) => {
735
+ if (value === 'text') {
736
+ return String(oldValue);
737
+ }
738
+ if (value === 'number') {
739
+ const convertTo = Number(oldValue);
740
+ if (isNaN(convertTo)) {
741
+ return 0;
742
+ }
743
+ return convertTo;
744
+ }
745
+ if (value === 'boolean') {
746
+ return Boolean(oldValue);
747
+ }
748
+ return '';
749
+ },
750
+ options: [
751
+ {label: '文本', value: 'text'},
752
+ {label: '数字', value: 'number'},
753
+ {label: '布尔', value: 'boolean'}
754
+ ]
755
+ },
756
+ {
757
+ type: 'input-number',
758
+ name: 'value',
759
+ placeholder: '值',
760
+ visibleOn: 'typeof data.value === "number"',
761
+ unique: true
762
+ },
763
+ {
764
+ type: 'switch',
765
+ name: 'value',
766
+ placeholder: '值',
767
+ visibleOn: 'typeof data.value === "boolean"',
768
+ unique: true
769
+ },
770
+ {
771
+ type: 'input-text',
772
+ name: 'value',
773
+ placeholder: '值',
774
+ visibleOn:
775
+ 'typeof data.value === "undefined" || typeof data.value === "string"',
776
+ unique: true
777
+ }
778
+ ]
779
+ },
780
+
781
+ tree: {
782
+ label: '选项 Options',
783
+ name: 'options',
784
+ type: 'combo',
785
+ multiple: true,
786
+ draggable: true,
787
+ addButtonText: '新增选项',
788
+ description:
789
+ '静态数据暂不支持多级,请切换到代码模式,或者采用 source 接口获取。',
790
+ scaffold: {
791
+ label: '',
792
+ value: ''
793
+ },
794
+ items: [
795
+ {
796
+ type: 'input-text',
797
+ name: 'label',
798
+ placeholder: '名称',
799
+ required: true
800
+ },
801
+
802
+ {
803
+ type: 'input-text',
804
+ name: 'value',
805
+ placeholder: '值',
806
+ unique: true
807
+ }
808
+ ]
809
+ },
810
+
811
+ horizontalMode: {
812
+ label: '表单项左右占比设置',
813
+ name: 'horizontal',
814
+ type: 'switch',
815
+ onText: '继承',
816
+ offText: '自定义',
817
+ mode: 'inline',
818
+ className: 'w-full',
819
+ inputClassName: 'text-sm',
820
+ visibleOn: 'this.mode == "horizontal" && this.label !== false',
821
+ pipeIn: (value: any) => !value,
822
+ pipeOut: (value: any, originValue: any, data: any) =>
823
+ value
824
+ ? null
825
+ : data.formHorizontal || {
826
+ leftFixed: 'normal'
827
+ }
828
+ },
829
+
830
+ horizontal: {
831
+ type: 'combo',
832
+ syncDefaultValue: false,
833
+ name: 'horizontal',
834
+ multiLine: true,
835
+ visibleOn:
836
+ 'data.mode == "horizontal" && data.label !== false && data.horizontal',
837
+ pipeIn: (value: any) => {
838
+ return {
839
+ leftRate:
840
+ value && typeof value.left === 'number'
841
+ ? value.left
842
+ : value && /\bcol\-(?:xs|sm|md|lg)\-(\d+)\b/.test(value.left)
843
+ ? parseInt(RegExp.$1, 10)
844
+ : 2,
845
+ leftFixed: (value && value.leftFixed) || ''
846
+ };
847
+ },
848
+ pipeOut: (value: any) => {
849
+ let left = Math.min(11, Math.max(1, value.leftRate || 2));
850
+
851
+ return {
852
+ leftFixed: value.leftFixed || '',
853
+ left: left,
854
+ right: 12 - left
855
+ };
856
+ },
857
+ inputClassName: 'no-padder',
858
+ items: [
859
+ {
860
+ name: 'leftFixed',
861
+ type: 'button-group-select',
862
+ label: '左侧宽度',
863
+ size: 'xs',
864
+ options: [
865
+ {
866
+ label: '比率',
867
+ value: ''
868
+ },
869
+
870
+ {
871
+ label: '小宽度',
872
+ value: 'sm',
873
+ visibleOn: 'this.leftFixed'
874
+ },
875
+
876
+ {
877
+ label: '固定宽度',
878
+ value: 'normal'
879
+ },
880
+
881
+ {
882
+ label: '大宽度',
883
+ value: 'lg',
884
+ visibleOn: 'this.leftFixed'
885
+ }
886
+ ]
887
+ },
888
+ {
889
+ name: 'leftRate',
890
+ type: 'input-range',
891
+ visibleOn: '!this.leftFixed',
892
+ min: 1,
893
+ max: 11,
894
+ step: 1,
895
+ label: '左右分布调整(n/12)',
896
+ labelRemark: {
897
+ trigger: 'click',
898
+ className: 'm-l-xs',
899
+ rootClose: true,
900
+ content: '一共 12 等份,这里可以设置左侧宽度占比 n/12。',
901
+ placement: 'left'
902
+ }
903
+ }
904
+ ]
905
+ },
906
+
907
+ subFormItemMode: {
908
+ label: '子表单展示模式',
909
+ name: 'subFormMode',
910
+ type: 'button-group-select',
911
+ size: 'sm',
912
+ option: '继承',
913
+ // mode: 'inline',
914
+ // className: 'w-full',
915
+ pipeIn: defaultValue(''),
916
+ options: [
917
+ {
918
+ label: '继承',
919
+ value: ''
920
+ },
921
+
922
+ {
923
+ label: '正常',
924
+ value: 'normal'
925
+ },
926
+
927
+ {
928
+ label: '内联',
929
+ value: 'inline'
930
+ },
931
+
932
+ {
933
+ label: '水平',
934
+ value: 'horizontal'
935
+ }
936
+ ]
937
+ },
938
+
939
+ subFormHorizontalMode: {
940
+ label: '子表单水平占比设置',
941
+ name: 'subFormHorizontal',
942
+ type: 'switch',
943
+ onText: '继承',
944
+ offText: '自定义',
945
+ mode: 'inline',
946
+ className: 'w-full',
947
+ inputClassName: 'text-sm',
948
+ visibleOn: 'this.subFormMode == "horizontal"',
949
+ pipeIn: (value: any) => !value,
950
+ pipeOut: (value: any, originValue: any, data: any) =>
951
+ value
952
+ ? null
953
+ : data.formHorizontal || {
954
+ leftFixed: 'normal'
955
+ }
956
+ },
957
+
958
+ subFormHorizontal: {
959
+ type: 'combo',
960
+ syncDefaultValue: false,
961
+ visibleOn: 'data.subFormMode == "horizontal" && data.subFormHorizontal',
962
+ name: 'subFormHorizontal',
963
+ multiLine: true,
964
+ pipeIn: (value: any) => {
965
+ return {
966
+ leftRate:
967
+ value && typeof value.left === 'number'
968
+ ? value.left
969
+ : value && /\bcol\-(?:xs|sm|md|lg)\-(\d+)\b/.test(value.left)
970
+ ? parseInt(RegExp.$1, 10)
971
+ : 2,
972
+ leftFixed: (value && value.leftFixed) || ''
973
+ };
974
+ },
975
+ pipeOut: (value: any) => {
976
+ let left = Math.min(11, Math.max(1, value.leftRate || 2));
977
+
978
+ return {
979
+ leftFixed: value.leftFixed || '',
980
+ left: left,
981
+ right: 12 - left
982
+ };
983
+ },
984
+ inputClassName: 'no-padder',
985
+ items: [
986
+ {
987
+ name: 'leftFixed',
988
+ type: 'button-group-select',
989
+ label: '左侧宽度',
990
+ size: 'xs',
991
+ options: [
992
+ {
993
+ label: '比率',
994
+ value: ''
995
+ },
996
+
997
+ {
998
+ label: '小宽度',
999
+ value: 'sm',
1000
+ visibleOn: 'this.leftFixed'
1001
+ },
1002
+
1003
+ {
1004
+ label: '固定宽度',
1005
+ value: 'normal'
1006
+ },
1007
+
1008
+ {
1009
+ label: '大宽度',
1010
+ value: 'lg',
1011
+ visibleOn: 'this.leftFixed'
1012
+ }
1013
+ ]
1014
+ },
1015
+ {
1016
+ name: 'leftRate',
1017
+ type: 'input-range',
1018
+ visibleOn: '!this.leftFixed',
1019
+ min: 1,
1020
+ max: 11,
1021
+ step: 1,
1022
+ label: '左右分布调整(n/12)',
1023
+ labelRemark: {
1024
+ trigger: 'click',
1025
+ className: 'm-l-xs',
1026
+ rootClose: true,
1027
+ content: '一共 12 等份,这里可以设置左侧宽度占比 n/12。',
1028
+ placement: 'left'
1029
+ }
1030
+ }
1031
+ ]
1032
+ },
1033
+
1034
+ validations: (function () {
1035
+ const options = [
1036
+ // {
1037
+ // label: '必填',
1038
+ // value: 'isRequired'
1039
+ // },
1040
+ {
1041
+ label: '邮箱格式',
1042
+ value: 'isEmail'
1043
+ },
1044
+ {
1045
+ label: 'Url格式',
1046
+ value: 'isUrl'
1047
+ },
1048
+ {
1049
+ label: '数字',
1050
+ value: 'isNumeric'
1051
+ },
1052
+ {
1053
+ label: '字母',
1054
+ value: 'isAlpha'
1055
+ },
1056
+ {
1057
+ label: '字母和数字',
1058
+ value: 'isAlphanumeric'
1059
+ },
1060
+ {
1061
+ label: '整型数字',
1062
+ value: 'isInt'
1063
+ },
1064
+ {
1065
+ label: '浮点型数字',
1066
+ value: 'isFloat'
1067
+ },
1068
+ {
1069
+ label: '固定长度',
1070
+ value: 'isLength'
1071
+ },
1072
+ {
1073
+ label: '最大长度',
1074
+ value: 'maxLength'
1075
+ },
1076
+ {
1077
+ label: '最小长度',
1078
+ value: 'minLength'
1079
+ },
1080
+ {
1081
+ label: '最大值',
1082
+ value: 'maximum'
1083
+ },
1084
+ {
1085
+ label: '最小值',
1086
+ value: 'minimum'
1087
+ },
1088
+ {
1089
+ label: '手机号码',
1090
+ value: 'isPhoneNumber'
1091
+ },
1092
+ {
1093
+ label: '电话号码',
1094
+ value: 'isTelNumber'
1095
+ },
1096
+ {
1097
+ label: '邮编号码',
1098
+ value: 'isZipcode'
1099
+ },
1100
+ {
1101
+ label: '身份证号码',
1102
+ value: 'isId'
1103
+ },
1104
+ {
1105
+ label: 'JSON格式',
1106
+ value: 'isJson'
1107
+ },
1108
+ {
1109
+ label: '与指定值相同',
1110
+ value: 'equals'
1111
+ },
1112
+ {
1113
+ label: '与指定字段值相同',
1114
+ value: 'equalsField'
1115
+ },
1116
+ {
1117
+ label: '自定义正则',
1118
+ value: 'matchRegexp'
1119
+ },
1120
+ {
1121
+ label: '自定义正则2',
1122
+ value: 'matchRegexp1'
1123
+ },
1124
+ {
1125
+ label: '自定义正则3',
1126
+ value: 'matchRegexp2'
1127
+ },
1128
+ {
1129
+ label: '自定义正则4',
1130
+ value: 'matchRegexp3'
1131
+ },
1132
+ {
1133
+ label: '自定义正则5',
1134
+ value: 'matchRegexp4'
1135
+ }
1136
+ ];
1137
+
1138
+ const trueProps = [
1139
+ 'isEmail',
1140
+ 'isUrl',
1141
+ 'isNumeric',
1142
+ 'isAlpha',
1143
+ 'isAlphanumeric',
1144
+ 'isInt',
1145
+ 'isFloat',
1146
+ 'isJson',
1147
+ 'isPhoneNumber',
1148
+ 'isTelNumber',
1149
+ 'isZipcode',
1150
+ 'isId'
1151
+ ];
1152
+
1153
+ function firstValue(arr: Array<any>, iterator: (item: any) => any) {
1154
+ let theone = find(arr, iterator);
1155
+ return theone ? theone.value : '';
1156
+ }
1157
+
1158
+ return {
1159
+ type: 'combo',
1160
+ syncDefaultValue: false,
1161
+ name: 'validations',
1162
+ label: '验证规则',
1163
+ addButtonText: '新增规则',
1164
+ multiple: true,
1165
+ pipeIn: (value: any) => {
1166
+ if (typeof value === 'string' && value) {
1167
+ value = str2rules(value);
1168
+ }
1169
+ if (!isObject(value)) {
1170
+ return value;
1171
+ }
1172
+
1173
+ let arr: Array<any> = [];
1174
+
1175
+ Object.keys(value).forEach(key => {
1176
+ if (/^\$\$/.test(key)) {
1177
+ return;
1178
+ }
1179
+
1180
+ arr.push({
1181
+ type: key,
1182
+ [key]: Array.isArray(value[key]) ? value[key][0] : value[key]
1183
+ });
1184
+ });
1185
+
1186
+ return arr;
1187
+ },
1188
+ pipeOut: (value: any) => {
1189
+ if (!Array.isArray(value)) {
1190
+ return value;
1191
+ }
1192
+ let obj: any = {};
1193
+
1194
+ value.forEach((item: any) => {
1195
+ let key: string =
1196
+ item.type ||
1197
+ firstValue(options, (item: any) => !obj[item.value]) ||
1198
+ options[0].value;
1199
+ obj[key] = item[key] || (~trueProps.indexOf(key) ? true : '');
1200
+ });
1201
+
1202
+ return obj;
1203
+ },
1204
+ items: [
1205
+ {
1206
+ type: 'select',
1207
+ unique: true,
1208
+ name: 'type',
1209
+ options: options,
1210
+ columnClassName: 'w-sm'
1211
+ },
1212
+ {
1213
+ type: 'input-number',
1214
+ name: 'isLength',
1215
+ visibleOn: 'data.type == "isLength"',
1216
+ placeholder: '设置长度',
1217
+ value: '1'
1218
+ },
1219
+ {
1220
+ type: 'input-number',
1221
+ name: 'maximum',
1222
+ visibleOn: 'data.type == "maximum"',
1223
+ placeholder: '设置最大值'
1224
+ },
1225
+ {
1226
+ type: 'input-number',
1227
+ name: 'minimum',
1228
+ visibleOn: 'data.type == "minimum"',
1229
+ placeholder: '设置最小值'
1230
+ },
1231
+ {
1232
+ type: 'input-number',
1233
+ name: 'maxLength',
1234
+ visibleOn: 'data.type == "maxLength"',
1235
+ placeholder: '设置最大长度值'
1236
+ },
1237
+ {
1238
+ type: 'input-number',
1239
+ name: 'minLength',
1240
+ visibleOn: 'data.type == "minLength"',
1241
+ placeholder: '设置最小长度值'
1242
+ },
1243
+ {
1244
+ type: 'input-text',
1245
+ name: 'equals',
1246
+ visibleOn: 'data.type == "equals"',
1247
+ placeholder: '设置值',
1248
+ value: ''
1249
+ },
1250
+ {
1251
+ type: 'input-text',
1252
+ name: 'equalsField',
1253
+ visibleOn: 'data.type == "equalsField"',
1254
+ placeholder: '设置字段名',
1255
+ value: ''
1256
+ },
1257
+ {
1258
+ type: 'input-text',
1259
+ name: 'matchRegexp',
1260
+ visibleOn: 'data.type == "matchRegexp"',
1261
+ placeholder: '设置正则规则'
1262
+ },
1263
+ {
1264
+ type: 'input-text',
1265
+ name: 'matchRegexp1',
1266
+ visibleOn: 'data.type == "matchRegexp1"',
1267
+ placeholder: '设置正则规则'
1268
+ },
1269
+ {
1270
+ type: 'input-text',
1271
+ name: 'matchRegexp2',
1272
+ visibleOn: 'data.type == "matchRegexp2"',
1273
+ placeholder: '设置正则规则'
1274
+ },
1275
+ {
1276
+ type: 'input-text',
1277
+ name: 'matchRegexp3',
1278
+ visibleOn: 'data.type == "matchRegexp3"',
1279
+ placeholder: '设置正则规则'
1280
+ },
1281
+ {
1282
+ type: 'input-text',
1283
+ name: 'matchRegexp4',
1284
+ visibleOn: 'data.type == "matchRegexp4"',
1285
+ placeholder: '设置正则规则'
1286
+ }
1287
+ ]
1288
+ };
1289
+ })(),
1290
+
1291
+ validationErrors: (function () {
1292
+ const options = [
1293
+ // {
1294
+ // label: '必填',
1295
+ // value: 'isRequired'
1296
+ // },
1297
+ {
1298
+ label: '邮箱格式',
1299
+ value: 'isEmail'
1300
+ },
1301
+ {
1302
+ label: 'Url格式',
1303
+ value: 'isUrl'
1304
+ },
1305
+ {
1306
+ label: '数字',
1307
+ value: 'isNumeric'
1308
+ },
1309
+ {
1310
+ label: '字母',
1311
+ value: 'isAlpha'
1312
+ },
1313
+ {
1314
+ label: '字母和数字',
1315
+ value: 'isAlphanumeric'
1316
+ },
1317
+ {
1318
+ label: '整型数字',
1319
+ value: 'isInt'
1320
+ },
1321
+ {
1322
+ label: '浮点型数字',
1323
+ value: 'isFloat'
1324
+ },
1325
+ {
1326
+ label: '固定长度',
1327
+ value: 'isLength'
1328
+ },
1329
+ {
1330
+ label: '最大长度',
1331
+ value: 'maxLength'
1332
+ },
1333
+ {
1334
+ label: '最小长度',
1335
+ value: 'minLength'
1336
+ },
1337
+ {
1338
+ label: '最大值',
1339
+ value: 'maximum'
1340
+ },
1341
+ {
1342
+ label: '最小值',
1343
+ value: 'minimum'
1344
+ },
1345
+ {
1346
+ label: 'JSON格式',
1347
+ value: 'isJson'
1348
+ },
1349
+ {
1350
+ label: '手机号码',
1351
+ value: 'isPhoneNumber'
1352
+ },
1353
+ {
1354
+ label: '电话号码',
1355
+ value: 'isTelNumber'
1356
+ },
1357
+ {
1358
+ label: '邮编号码',
1359
+ value: 'isZipcode'
1360
+ },
1361
+ {
1362
+ label: '身份证号码',
1363
+ value: 'isId'
1364
+ },
1365
+ {
1366
+ label: '与指定值相同',
1367
+ value: 'equals'
1368
+ },
1369
+ {
1370
+ label: '与指定字段值相同',
1371
+ value: 'equalsField'
1372
+ },
1373
+ {
1374
+ label: '自定义正则',
1375
+ value: 'matchRegexp'
1376
+ },
1377
+ {
1378
+ label: '自定义正则2',
1379
+ value: 'matchRegexp1'
1380
+ },
1381
+ {
1382
+ label: '自定义正则3',
1383
+ value: 'matchRegexp2'
1384
+ },
1385
+ {
1386
+ label: '自定义正则4',
1387
+ value: 'matchRegexp3'
1388
+ },
1389
+ {
1390
+ label: '自定义正则5',
1391
+ value: 'matchRegexp4'
1392
+ }
1393
+ ];
1394
+
1395
+ const defaultMessages = {
1396
+ isEmail: 'Email 格式不正确',
1397
+ isRequired: '这是必填项',
1398
+ isUrl: 'Url 格式不正确',
1399
+ isInt: '请输入整形数字',
1400
+ isAlpha: '请输入字母',
1401
+ isNumeric: '请输入数字',
1402
+ isAlphanumeric: '请输入字母或者数字',
1403
+ isFloat: '请输入浮点型数值',
1404
+ isWords: '请输入字母',
1405
+ isUrlPath: '只能输入字母、数字、`-` 和 `_`.',
1406
+ matchRegexp: '格式不正确, 请输入符合规则为 `$1` 的内容。',
1407
+ minLength: '请输入更多的内容,至少输入 $1 个字符。',
1408
+ maxLength: '请控制内容长度, 请不要输入 $1 个字符以上',
1409
+ maximum: '当前输入值超出最大值 $1,请检查',
1410
+ minimum: '当前输入值低于最小值 $1,请检查',
1411
+ isJson: '请检查 Json 格式。',
1412
+ isPhoneNumber: '请输入合法的手机号码',
1413
+ isTelNumber: '请输入合法的电话号码',
1414
+ isZipcode: '请输入合法的邮编地址',
1415
+ isId: '请输入合法的身份证号',
1416
+ isLength: '请输入长度为 $1 的内容',
1417
+ notEmptyString: '请不要全输入空白字符',
1418
+ equalsField: '输入的数据与 $1 值不一致',
1419
+ equals: '输入的数据与 $1 不一致'
1420
+ };
1421
+
1422
+ function firstValue(arr: Array<any>, iterator: (item: any) => any) {
1423
+ let theone = find(arr, iterator);
1424
+ return theone ? theone.value : '';
1425
+ }
1426
+
1427
+ return {
1428
+ type: 'combo',
1429
+ syncDefaultValue: false,
1430
+ name: 'validationErrors',
1431
+ label: '自定义验证提示',
1432
+ description: '自带提示不满足时,可以自定义。',
1433
+ addButtonText: '新增提示',
1434
+ multiple: true,
1435
+ pipeIn: (value: any) => {
1436
+ if (!isObject(value)) {
1437
+ return value;
1438
+ }
1439
+
1440
+ let arr: Array<any> = [];
1441
+
1442
+ Object.keys(value).forEach(key => {
1443
+ if (/^\$\$/.test(key)) {
1444
+ return;
1445
+ }
1446
+
1447
+ arr.push({
1448
+ type: key,
1449
+ msg: value[key]
1450
+ });
1451
+ });
1452
+
1453
+ return arr;
1454
+ },
1455
+ pipeOut: (value: any) => {
1456
+ if (!Array.isArray(value)) {
1457
+ return value;
1458
+ }
1459
+ let obj: any = {};
1460
+
1461
+ value.forEach((item: any) => {
1462
+ let key: string =
1463
+ item.type ||
1464
+ firstValue(options, (item: any) => !obj[item.value]) ||
1465
+ options[0].value;
1466
+ obj[key] = item.msg || (defaultMessages as any)[key] || '';
1467
+ });
1468
+
1469
+ return obj;
1470
+ },
1471
+ items: [
1472
+ {
1473
+ type: 'select',
1474
+ unique: true,
1475
+ name: 'type',
1476
+ options: options,
1477
+ columnClassName: 'w-sm'
1478
+ },
1479
+
1480
+ {
1481
+ type: 'input-text',
1482
+ name: 'msg',
1483
+ placeholder: '提示信息'
1484
+ },
1485
+
1486
+ {
1487
+ type: 'formula',
1488
+ name: 'msg',
1489
+ initSet: false,
1490
+ formula: `({
1491
+ isEmail: 'Email 格式不正确',
1492
+ isRequired: '这是必填项',
1493
+ isUrl: 'Url 格式不正确',
1494
+ isInt: '请输入整形数字',
1495
+ isAlpha: '请输入字母',
1496
+ isNumeric: '请输入数字',
1497
+ isAlphanumeric: '请输入字母或者数字',
1498
+ isFloat: '请输入浮点型数值',
1499
+ isWords: '请输入字母',
1500
+ isUrlPath: '只能输入字母、数字、\`-\` 和 \`_\`.',
1501
+ matchRegexp: '格式不正确, 请输入符合规则为 \`$1\` 的内容。',
1502
+ minLength: '请输入更多的内容,至少输入 $1 个字符。',
1503
+ maxLength: '请控制内容长度, 请不要输入 $1 个字符以上',
1504
+ maximum: '当前输入值超出最大值 $1,请检查',
1505
+ minimum: '当前输入值低于最小值 $1,请检查',
1506
+ isJson: '请检查 Json 格式。',
1507
+ isLength: '请输入长度为 $1 的内容',
1508
+ notEmptyString: '请不要全输入空白字符',
1509
+ equalsField: '输入的数据与 $1 值不一致',
1510
+ equals: '输入的数据与 $1 不一致',
1511
+ isPhoneNumber: '请输入合法的手机号码',
1512
+ isTelNumber: '请输入合法的电话号码',
1513
+ isZipcode: '请输入合法的邮编地址',
1514
+ isId: '请输入合法的身份证号',
1515
+ })[data.type] || ''`
1516
+ }
1517
+ ]
1518
+ };
1519
+ })(),
1520
+
1521
+ submitOnChange: {
1522
+ label: '修改即提交',
1523
+ type: 'switch',
1524
+ name: 'submitOnChange',
1525
+ mode: 'inline',
1526
+ className: 'w-full',
1527
+ labelRemark: {
1528
+ trigger: 'click',
1529
+ className: 'm-l-xs',
1530
+ rootClose: true,
1531
+ content: '设置后,表单中每次有修改都会触发提交',
1532
+ placement: 'left'
1533
+ }
1534
+ },
1535
+
1536
+ validateOnChange: {
1537
+ type: 'button-group-select',
1538
+ name: 'validateOnChange',
1539
+ label: '修改即触发表单验证',
1540
+ description: '默认为当表单提交过则每次修改都触发验证。',
1541
+ size: 'xs',
1542
+ mode: 'inline',
1543
+ className: 'w-full',
1544
+ options: [
1545
+ {
1546
+ label: '默认',
1547
+ value: ''
1548
+ },
1549
+
1550
+ {
1551
+ label: '开启',
1552
+ value: true
1553
+ },
1554
+
1555
+ {
1556
+ label: '关闭',
1557
+ value: false
1558
+ }
1559
+ ],
1560
+ pipeIn: defaultValue(''),
1561
+ pipeOut: (value: any) => (value === '' ? undefined : !!value)
1562
+ },
1563
+
1564
+ validationControl: {
1565
+ type: 'ae-validationControl',
1566
+ label: '校验',
1567
+ mode: 'normal'
1568
+ },
1569
+
1570
+ visible: {
1571
+ type: 'fieldSet',
1572
+ title: '显隐配置',
1573
+ collapsable: false, // 避免和最外层的属性配置面板的tabs样式重叠
1574
+ body: [
1575
+ {
1576
+ label: '设置方式',
1577
+ name: 'visible',
1578
+ type: 'button-group-select',
1579
+ size: 'xs',
1580
+ mode: 'inline',
1581
+ className: 'w-full',
1582
+ options: [
1583
+ {
1584
+ label: '静态设置',
1585
+ value: 1
1586
+ },
1587
+
1588
+ {
1589
+ label: '表达式',
1590
+ value: 2
1591
+ }
1592
+ ],
1593
+ pipeIn: (value: any) => (typeof value === 'boolean' ? 1 : 2),
1594
+ pipeOut: (value: any) => (value === 1 ? true : ''),
1595
+ onChange: (value: any, oldValue: boolean, model: any, form: any) => {
1596
+ if (value) {
1597
+ form.setValues({
1598
+ __visibleOn: form.data.visibleOn,
1599
+ visibleOn: '',
1600
+ clearValueOnHidden: false
1601
+ });
1602
+ } else {
1603
+ form.setValueByName('visibleOn', form.data.__visibleOn);
1604
+ }
1605
+ }
1606
+ },
1607
+
1608
+ {
1609
+ type: 'switch',
1610
+ label: '可见(visible)',
1611
+ name: 'visible',
1612
+ visibleOn: 'typeof this.visible === "boolean"',
1613
+ pipeIn: (value: any, data: any) => value !== false && !data.hidden,
1614
+ mode: 'inline',
1615
+ className: 'w-full m-b-none',
1616
+ onChange: (value: boolean, oldValue: boolean, model: any, form: any) =>
1617
+ form.setValueByName('visibleOn', '')
1618
+ },
1619
+
1620
+ {
1621
+ name: 'visibleOn',
1622
+ label: '可见表达式(visibleOn)',
1623
+ labelRemark: {
1624
+ trigger: 'click',
1625
+ className: 'm-l-xs',
1626
+ rootClose: true,
1627
+ content:
1628
+ '纯粹的 JS 语法,this 指向当前数据层。文档:<a href="https://baidu.github.io/amis/docs/concepts/expression">表达式语法</a>',
1629
+ placement: 'left'
1630
+ },
1631
+ placeholder: '如:this.type === 1',
1632
+ type: 'input-text',
1633
+ visibleOn: 'typeof this.visible !== "boolean"',
1634
+ autoComplete: false,
1635
+ pipeIn: (value: any, data: any) =>
1636
+ value || (data.hiddenOn && `!(${data.hiddenOn})`) || '',
1637
+ className: 'm-b-none'
1638
+ }
1639
+ ]
1640
+ },
1641
+
1642
+ initFetch: {
1643
+ type: 'group',
1644
+ label: '是否初始加载',
1645
+ visibleOn: 'this.initApi',
1646
+ direction: 'vertical',
1647
+ className: 'm-b-none',
1648
+ labelRemark: {
1649
+ trigger: 'click',
1650
+ rootClose: true,
1651
+ className: 'm-l-xs',
1652
+ content:
1653
+ '当配置初始化接口后,组件初始就会拉取接口数据,可以通过以下配置修改。',
1654
+ placement: 'left'
1655
+ },
1656
+ body: [
1657
+ {
1658
+ name: 'initFetch',
1659
+ type: 'radios',
1660
+ inline: true,
1661
+ onChange: () => {},
1662
+ // pipeIn: (value:any) => typeof value === 'boolean' ? value : '1'
1663
+ options: [
1664
+ {
1665
+ label: '是',
1666
+ value: true
1667
+ },
1668
+
1669
+ {
1670
+ label: '否',
1671
+ value: false
1672
+ },
1673
+
1674
+ {
1675
+ label: '表达式',
1676
+ value: ''
1677
+ }
1678
+ ]
1679
+ },
1680
+
1681
+ {
1682
+ name: 'initFetchOn',
1683
+ autoComplete: false,
1684
+ visibleOn: 'typeof this.initFetch !== "boolean"',
1685
+ type: 'input-text',
1686
+ placeholder: '如:this.id 表示有 id 值时初始加载',
1687
+ className: 'm-t-n-sm'
1688
+ }
1689
+ ]
1690
+ },
1691
+
1692
+ disabled: (additions: Array<any> = []) => {
1693
+ return {
1694
+ type: 'fieldSet',
1695
+ title: '禁用配置',
1696
+ collapsable: false, // 避免和最外层的属性配置面板的tabs样式重叠
1697
+ body: [
1698
+ ...additions,
1699
+ {
1700
+ label: '设置方式',
1701
+ name: 'disabled',
1702
+ type: 'button-group-select',
1703
+ size: 'xs',
1704
+ mode: 'inline',
1705
+ className: 'w-full',
1706
+ options: [
1707
+ {
1708
+ label: '静态设置',
1709
+ value: 1
1710
+ },
1711
+
1712
+ {
1713
+ label: '表达式',
1714
+ value: 2
1715
+ }
1716
+ ],
1717
+ pipeIn: (value: any) => (typeof value === 'boolean' ? 1 : 2),
1718
+ pipeOut: (value: any) => (value === 1 ? false : '')
1719
+ },
1720
+
1721
+ {
1722
+ type: 'switch',
1723
+ label: '禁用(disabled)',
1724
+ name: 'disabled',
1725
+ visibleOn: 'typeof this.disabled === "boolean"',
1726
+ pipeIn: (value: any, data: any) => value !== false && !data.hidden,
1727
+ mode: 'inline',
1728
+ className: 'w-full m-b-none',
1729
+ onChange: (
1730
+ value: boolean,
1731
+ oldValue: boolean,
1732
+ model: any,
1733
+ form: any
1734
+ ) => form.setValueByName('disabledOn', '')
1735
+ },
1736
+
1737
+ {
1738
+ name: 'disabledOn',
1739
+ label: '禁用表达式(disabledOn)',
1740
+ placeholder: '如:this.type === 1',
1741
+ labelRemark: {
1742
+ trigger: 'click',
1743
+ className: 'm-l-xs',
1744
+ rootClose: true,
1745
+ content:
1746
+ '纯粹的 JS 语法,this 指向当前数据层。文档:<a href="https://baidu.github.io/amis/docs/concepts/expression">表达式语法</a>',
1747
+ placement: 'left'
1748
+ },
1749
+ type: 'input-text',
1750
+ visibleOn: 'typeof this.disabled !== "boolean"',
1751
+ className: 'm-b-none'
1752
+ }
1753
+ ]
1754
+ };
1755
+ },
1756
+
1757
+ switchDefaultValue: {
1758
+ type: 'switch',
1759
+ name: 'value',
1760
+ label: '设置默认值',
1761
+ mode: 'inline',
1762
+ className: 'w-full',
1763
+ pipeIn: (value: any) => typeof value !== 'undefined',
1764
+ pipeOut: (value: any, origin: any, data: any) => (value ? '' : undefined),
1765
+ remark: '不设置时根据 name 获取'
1766
+ },
1767
+
1768
+ multiple: {
1769
+ label: '多选模式',
1770
+ name: 'multiple',
1771
+ type: 'switch',
1772
+ mode: 'inline',
1773
+ className: 'w-full'
1774
+ },
1775
+
1776
+ joinValues: {
1777
+ type: 'switch',
1778
+ name: 'joinValues',
1779
+ mode: 'inline',
1780
+ className: 'w-full',
1781
+ visibleOn: 'data.multiple',
1782
+ label: '是否拼接值',
1783
+ value: true,
1784
+ description:
1785
+ '开启后将选中的选项 value 的值用连接符拼接起来,作为当前表单项的值。'
1786
+ },
1787
+
1788
+ delimiter: {
1789
+ type: 'input-text',
1790
+ name: 'delimiter',
1791
+ label: '连接符',
1792
+ visibleOn: 'data.multiple && data.joinValues',
1793
+ pipeIn: defaultValue(',')
1794
+ },
1795
+
1796
+ extractValue: {
1797
+ type: 'switch',
1798
+ name: 'extractValue',
1799
+ mode: 'inline',
1800
+ className: 'w-full',
1801
+ label: '是否抽取value值',
1802
+ visibleOn: 'data.joinValues === false',
1803
+ pipeIn: defaultValue(false),
1804
+ description: '开启后将选中的选项 value 的值封装为数组,作为当前表单项的值。'
1805
+ },
1806
+
1807
+ creatable: {
1808
+ label: '可创建选项',
1809
+ name: 'creatable',
1810
+ type: 'switch',
1811
+ mode: 'inline',
1812
+ className: 'w-full'
1813
+ },
1814
+
1815
+ createBtnLabel: {
1816
+ label: '创建按钮文字',
1817
+ name: 'createBtnLabel',
1818
+ type: 'input-text',
1819
+ mode: 'inline',
1820
+ placeholder: '新增选项',
1821
+ className: 'w-full'
1822
+ },
1823
+
1824
+ editable: {
1825
+ label: '可编辑选项',
1826
+ name: 'editable',
1827
+ type: 'switch',
1828
+ mode: 'inline',
1829
+ className: 'w-full'
1830
+ },
1831
+
1832
+ removable: {
1833
+ label: '可删除选项',
1834
+ name: 'removable',
1835
+ type: 'switch',
1836
+ mode: 'inline',
1837
+ className: 'w-full'
1838
+ },
1839
+
1840
+ ref: () => {
1841
+ // {
1842
+ // type: 'input-text',
1843
+ // name: '$ref',
1844
+ // label: '选择定义',
1845
+ // labelRemark: '输入已经在page中设定好的定义'
1846
+ // }
1847
+ return null;
1848
+ },
1849
+
1850
+ imageUrl: {
1851
+ type: 'input-text',
1852
+ label: '图片'
1853
+ },
1854
+
1855
+ fileUrl: {
1856
+ type: 'input-text',
1857
+ label: '文件'
1858
+ },
1859
+
1860
+ markdownBody: {
1861
+ name: 'value',
1862
+ type: 'editor',
1863
+ language: 'markdown',
1864
+ size: 'xxl',
1865
+ label: 'Markdown 内容',
1866
+ options: {
1867
+ lineNumbers: 'off'
1868
+ }
1869
+ },
1870
+
1871
+ richText: {
1872
+ label: '富文本',
1873
+ type: 'input-rich-text',
1874
+ buttons: [
1875
+ 'paragraphFormat',
1876
+ 'quote',
1877
+ 'color',
1878
+ '|',
1879
+ 'bold',
1880
+ 'italic',
1881
+ 'underline',
1882
+ 'strikeThrough',
1883
+ '|',
1884
+ 'formatOL',
1885
+ 'formatUL',
1886
+ 'align',
1887
+ '|',
1888
+ 'insertLink',
1889
+ 'insertImage',
1890
+ 'insertTable',
1891
+ '|',
1892
+ 'undo',
1893
+ 'redo',
1894
+ 'fullscreen'
1895
+ ],
1896
+ name: 'html',
1897
+ description:
1898
+ '支持使用 <code>\\${xxx}</code> 来获取变量,或者用 lodash.template 语法来写模板逻辑。<a target="_blank" href="/amis/zh-CN/docs/concepts/template">详情</a>',
1899
+ size: 'lg'
1900
+ },
1901
+
1902
+ showCounter: {
1903
+ label: '是否显示计数器',
1904
+ name: 'showCounter',
1905
+ type: 'switch',
1906
+ mode: 'inline',
1907
+ className: 'w-full'
1908
+ },
1909
+
1910
+ borderMode: {
1911
+ type: 'select',
1912
+ name: 'borderMode',
1913
+ label: '边框模式',
1914
+ options: [
1915
+ {label: '全边框', value: 'full'},
1916
+ {label: '半边框', value: 'half'},
1917
+ {label: '无边框', value: 'none'}
1918
+ ]
1919
+ },
1920
+
1921
+ data: {
1922
+ type: 'input-kv',
1923
+ name: 'data',
1924
+ label: '初始静态数据'
1925
+ }
1926
+ };
1927
+
1928
+ /**
1929
+ * 样式相关的属性面板,因为预计会比较多所以拆出来
1930
+ */
1931
+ export const styleTpl = {
1932
+ name: 'style',
1933
+ type: 'combo',
1934
+ label: '',
1935
+ noBorder: true,
1936
+ multiLine: true,
1937
+ items: [
1938
+ {
1939
+ type: 'fieldSet',
1940
+ title: '文字',
1941
+ body: [
1942
+ {
1943
+ type: 'group',
1944
+ body: [
1945
+ {
1946
+ label: '文字大小',
1947
+ type: 'input-text',
1948
+ name: 'fontSize'
1949
+ },
1950
+ {
1951
+ label: '文字粗细',
1952
+ name: 'fontWeight',
1953
+ type: 'select',
1954
+ options: ['normal', 'bold', 'lighter', 'bolder']
1955
+ }
1956
+ ]
1957
+ },
1958
+ {
1959
+ type: 'group',
1960
+ body: [
1961
+ {
1962
+ label: '文字颜色',
1963
+ type: 'input-color',
1964
+ name: 'color'
1965
+ },
1966
+ {
1967
+ label: '对齐方式',
1968
+ name: 'textAlign',
1969
+ type: 'select',
1970
+ options: [
1971
+ 'left',
1972
+ 'right',
1973
+ 'center',
1974
+ 'justify',
1975
+ 'justify-all',
1976
+ 'start',
1977
+ 'end',
1978
+ 'match-parent'
1979
+ ]
1980
+ }
1981
+ ]
1982
+ }
1983
+ ]
1984
+ },
1985
+ {
1986
+ type: 'fieldSet',
1987
+ title: '背景',
1988
+ body: [
1989
+ {
1990
+ label: '颜色',
1991
+ name: 'backgroundColor',
1992
+ type: 'input-color'
1993
+ },
1994
+ getSchemaTpl('imageUrl', {
1995
+ name: 'backgroundImage'
1996
+ })
1997
+ ]
1998
+ },
1999
+ {
2000
+ type: 'fieldSet',
2001
+ title: '边距',
2002
+ body: [
2003
+ {
2004
+ type: 'group',
2005
+ label: '外边距',
2006
+ body: [
2007
+ {
2008
+ label: '上',
2009
+ name: 'marginTop',
2010
+ type: 'input-text'
2011
+ },
2012
+ {
2013
+ label: '右',
2014
+ name: 'marginRight',
2015
+ type: 'input-text'
2016
+ },
2017
+ {
2018
+ label: '下',
2019
+ name: 'marginBottom',
2020
+ type: 'input-text'
2021
+ },
2022
+ {
2023
+ label: '左',
2024
+ name: 'marginLeft',
2025
+ type: 'input-text'
2026
+ }
2027
+ ]
2028
+ },
2029
+ {
2030
+ type: 'group',
2031
+ label: '内边距',
2032
+ body: [
2033
+ {
2034
+ label: '上',
2035
+ name: 'paddingTop',
2036
+ type: 'input-text'
2037
+ },
2038
+ {
2039
+ label: '右',
2040
+ name: 'paddingRight',
2041
+ type: 'input-text'
2042
+ },
2043
+ {
2044
+ label: '下',
2045
+ name: 'paddingBottom',
2046
+ type: 'input-text'
2047
+ },
2048
+ {
2049
+ label: '左',
2050
+ name: 'paddingLeft',
2051
+ type: 'input-text'
2052
+ }
2053
+ ]
2054
+ }
2055
+ ]
2056
+ },
2057
+ {
2058
+ type: 'fieldSet',
2059
+ title: '边框',
2060
+ body: [
2061
+ {
2062
+ type: 'group',
2063
+ body: [
2064
+ {
2065
+ label: '样式',
2066
+ name: 'borderStyle',
2067
+ type: 'select',
2068
+ options: ['none', 'solid', 'dotted', 'dashed']
2069
+ },
2070
+ {
2071
+ label: '颜色',
2072
+ name: 'borderColor',
2073
+ type: 'input-color'
2074
+ }
2075
+ ]
2076
+ },
2077
+ {
2078
+ type: 'group',
2079
+ body: [
2080
+ {
2081
+ label: '宽度',
2082
+ name: 'borderWidth',
2083
+ type: 'input-text'
2084
+ },
2085
+ {
2086
+ label: '圆角宽度',
2087
+ name: 'borderRadius',
2088
+ type: 'input-text'
2089
+ }
2090
+ ]
2091
+ }
2092
+ ]
2093
+ },
2094
+ {
2095
+ type: 'fieldSet',
2096
+ title: '特效',
2097
+ body: [
2098
+ {
2099
+ label: '透明度',
2100
+ name: 'opacity',
2101
+ min: 0,
2102
+ max: 1,
2103
+ step: 0.05,
2104
+ type: 'input-range',
2105
+ pipeIn: defaultValue(1)
2106
+ },
2107
+ {
2108
+ label: '阴影',
2109
+ name: 'boxShadow',
2110
+ type: 'input-text'
2111
+ }
2112
+ ]
2113
+ }
2114
+ ]
2115
+ };
2116
+ tpls.style = styleTpl;
2117
+
2118
+ export function getSchemaTpl(name: string, patch?: object): any {
2119
+ const tpl = tpls[name];
2120
+
2121
+ if (typeof tpl === 'function') {
2122
+ return tpl(patch);
2123
+ }
2124
+
2125
+ return tpl
2126
+ ? patch
2127
+ ? {
2128
+ ...tpl,
2129
+ ...patch
2130
+ }
2131
+ : tpl
2132
+ : null;
2133
+ }
2134
+
2135
+ export function setSchemaTpl(name: string, value: any) {
2136
+ tpls[name] = value;
2137
+ }
2138
+
2139
+ export function valuePipeOut(value: any) {
2140
+ try {
2141
+ if (value === 'undefined') {
2142
+ return undefined;
2143
+ }
2144
+
2145
+ return JSON.parse(value);
2146
+ } catch (e) {
2147
+ return value;
2148
+ }
2149
+ }
2150
+
2151
+ export function defaultValue(defaultValue: any, strictMode: boolean = true) {
2152
+ return strictMode
2153
+ ? (value: any) => (typeof value === 'undefined' ? defaultValue : value)
2154
+ : (value: any) => value || defaultValue;
2155
+ }