amis-editor 4.1.0-beta.4 → 4.2.0-beta.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (216) hide show
  1. package/dist/component/Breadcrumb.d.ts +23 -2
  2. package/dist/component/ClassNameControl.d.ts +1 -1
  3. package/dist/component/Control/APIControl.d.ts +2 -2
  4. package/dist/component/Control/OptionControl.d.ts +3 -3
  5. package/dist/component/Control/PopoverEdit.d.ts +4 -4
  6. package/dist/component/Control/ValidationControl.d.ts +1 -1
  7. package/dist/component/Editor.d.ts +20 -1
  8. package/dist/component/IFramePreview.d.ts +2 -1
  9. package/dist/component/NodeWrapper.d.ts +1 -1
  10. package/dist/component/Panel/RenderersPanel.d.ts +1 -2
  11. package/dist/component/Preview.d.ts +3 -1
  12. package/dist/component/RegionWrapper.d.ts +4 -0
  13. package/dist/component/VRenderer.d.ts +4 -0
  14. package/dist/component/base/InputComponentName.d.ts +1 -1
  15. package/dist/component/base/SearchCustomRendererPanel.d.ts +15 -0
  16. package/dist/component/base/SearchPanel.d.ts +83 -0
  17. package/dist/component/base/SearchRendererPanel.d.ts +2 -42
  18. package/dist/env.d.ts +1 -1
  19. package/dist/exports.min.js +1 -1
  20. package/dist/index.d.ts +4 -1
  21. package/dist/index.min.js +1 -1
  22. package/dist/manager.d.ts +16 -4
  23. package/dist/plugin/Alert.d.ts +1 -1
  24. package/dist/plugin/Button.d.ts +1 -1
  25. package/dist/plugin/Card.d.ts +1 -0
  26. package/dist/plugin/Cards.d.ts +2 -1
  27. package/dist/plugin/Carousel.d.ts +1 -0
  28. package/dist/plugin/Chart.d.ts +1 -0
  29. package/dist/plugin/Collapse.d.ts +1 -0
  30. package/dist/plugin/Custom.d.ts +3 -0
  31. package/dist/plugin/CustomRegion.d.ts +40 -0
  32. package/dist/plugin/Dialog.d.ts +1 -1
  33. package/dist/plugin/Drawer.d.ts +1 -1
  34. package/dist/plugin/DropDownButton.d.ts +1 -1
  35. package/dist/plugin/Each.d.ts +1 -1
  36. package/dist/plugin/Flex.d.ts +1 -0
  37. package/dist/plugin/Form/Control.d.ts +1 -0
  38. package/dist/plugin/Form/Form.d.ts +19 -3
  39. package/dist/plugin/Form/Formula.d.ts +3 -3
  40. package/dist/plugin/Form/InputURL.d.ts +1 -0
  41. package/dist/plugin/Form/Switch.d.ts +2 -0
  42. package/dist/plugin/Grid.d.ts +1 -0
  43. package/dist/plugin/HBox.d.ts +1 -0
  44. package/dist/plugin/IFrame.d.ts +3 -3
  45. package/dist/plugin/Json.d.ts +1 -0
  46. package/dist/plugin/List.d.ts +2 -1
  47. package/dist/plugin/Mapping.d.ts +1 -0
  48. package/dist/plugin/Markdown.d.ts +1 -0
  49. package/dist/plugin/Nav.d.ts +1 -0
  50. package/dist/plugin/Page.d.ts +1 -1
  51. package/dist/plugin/Panel/Outline.d.ts +8 -0
  52. package/dist/plugin/Progress.d.ts +1 -0
  53. package/dist/plugin/QRCode.d.ts +1 -0
  54. package/dist/plugin/Reset.d.ts +0 -1
  55. package/dist/plugin/Service.d.ts +1 -0
  56. package/dist/plugin/Sparkline.d.ts +1 -0
  57. package/dist/plugin/Status.d.ts +1 -0
  58. package/dist/plugin/Steps.d.ts +1 -0
  59. package/dist/plugin/Submit.d.ts +0 -1
  60. package/dist/plugin/Table.d.ts +1 -1
  61. package/dist/plugin/TableView.d.ts +1 -0
  62. package/dist/plugin/Tasks.d.ts +1 -0
  63. package/dist/plugin/TooltipWrapper.d.ts +1 -0
  64. package/dist/plugin/Video.d.ts +1 -0
  65. package/dist/plugin/WebComponent.d.ts +1 -0
  66. package/dist/plugin/Wizard.d.ts +11 -2
  67. package/dist/plugin/Wrapper.d.ts +1 -0
  68. package/dist/plugin.d.ts +8 -7
  69. package/dist/store/editor.d.ts +47 -11
  70. package/dist/store/node.d.ts +6 -0
  71. package/dist/style.css +1 -1
  72. package/dist/util.d.ts +1 -1
  73. package/package.json +10 -3
  74. package/src/component/schemaTpl.tsx +2157 -0
  75. package/src/plugin/Alert.tsx +87 -0
  76. package/src/plugin/AnchorNav.tsx +233 -0
  77. package/src/plugin/Audio.tsx +154 -0
  78. package/src/plugin/Avatar.tsx +77 -0
  79. package/src/plugin/Breadcrumb.tsx +107 -0
  80. package/src/plugin/Button.tsx +281 -0
  81. package/src/plugin/ButtonGroup.tsx +85 -0
  82. package/src/plugin/ButtonToolbar.tsx +87 -0
  83. package/src/plugin/CRUD.tsx +1835 -0
  84. package/src/plugin/Card.tsx +290 -0
  85. package/src/plugin/Cards.tsx +318 -0
  86. package/src/plugin/Carousel.tsx +377 -0
  87. package/src/plugin/Chart.tsx +218 -0
  88. package/src/plugin/CodeView.tsx +60 -0
  89. package/src/plugin/Collapse.tsx +136 -0
  90. package/src/plugin/CollapseGroup.tsx +167 -0
  91. package/src/plugin/Container.tsx +40 -0
  92. package/src/plugin/Custom.tsx +128 -0
  93. package/src/plugin/CustomRegion.tsx +156 -0
  94. package/src/plugin/Date.tsx +74 -0
  95. package/src/plugin/Datetime.tsx +68 -0
  96. package/src/plugin/Dialog.tsx +176 -0
  97. package/src/plugin/Divider.tsx +36 -0
  98. package/src/plugin/Drawer.tsx +214 -0
  99. package/src/plugin/DropDownButton.tsx +235 -0
  100. package/src/plugin/Each.tsx +150 -0
  101. package/src/plugin/ErrorRenderer.tsx +15 -0
  102. package/src/plugin/Flex.tsx +151 -0
  103. package/src/plugin/Form/ButtonGroupSelect.tsx +75 -0
  104. package/src/plugin/Form/ButtonToolbar.tsx +110 -0
  105. package/src/plugin/Form/ChainedSelect.tsx +70 -0
  106. package/src/plugin/Form/Checkbox.tsx +87 -0
  107. package/src/plugin/Form/Checkboxes.tsx +167 -0
  108. package/src/plugin/Form/CodeEditor.tsx +81 -0
  109. package/src/plugin/Form/Combo.tsx +582 -0
  110. package/src/plugin/Form/ConditionBuilder.tsx +315 -0
  111. package/src/plugin/Form/Control.tsx +139 -0
  112. package/src/plugin/Form/DiffEditor.tsx +111 -0
  113. package/src/plugin/Form/FieldSet.tsx +163 -0
  114. package/src/plugin/Form/Form.tsx +687 -0
  115. package/src/plugin/Form/Formula.tsx +79 -0
  116. package/src/plugin/Form/Group.tsx +295 -0
  117. package/src/plugin/Form/Hidden.tsx +44 -0
  118. package/src/plugin/Form/InputArray.tsx +228 -0
  119. package/src/plugin/Form/InputCity.tsx +93 -0
  120. package/src/plugin/Form/InputColor.tsx +123 -0
  121. package/src/plugin/Form/InputDate.tsx +175 -0
  122. package/src/plugin/Form/InputDateRange.tsx +225 -0
  123. package/src/plugin/Form/InputDateTime.tsx +183 -0
  124. package/src/plugin/Form/InputDateTimeRange.tsx +221 -0
  125. package/src/plugin/Form/InputEmail.tsx +33 -0
  126. package/src/plugin/Form/InputExcel.tsx +85 -0
  127. package/src/plugin/Form/InputFile.tsx +221 -0
  128. package/src/plugin/Form/InputGroup.tsx +96 -0
  129. package/src/plugin/Form/InputImage.tsx +266 -0
  130. package/src/plugin/Form/InputKV.tsx +72 -0
  131. package/src/plugin/Form/InputMonth.tsx +35 -0
  132. package/src/plugin/Form/InputMonthRange.tsx +195 -0
  133. package/src/plugin/Form/InputNumber.tsx +89 -0
  134. package/src/plugin/Form/InputPassword.tsx +33 -0
  135. package/src/plugin/Form/InputQuarter.tsx +35 -0
  136. package/src/plugin/Form/InputQuarterRange.tsx +195 -0
  137. package/src/plugin/Form/InputRange.tsx +121 -0
  138. package/src/plugin/Form/InputRating.tsx +78 -0
  139. package/src/plugin/Form/InputRepeat.tsx +57 -0
  140. package/src/plugin/Form/InputRichText.tsx +186 -0
  141. package/src/plugin/Form/InputSubForm.tsx +189 -0
  142. package/src/plugin/Form/InputTable.tsx +434 -0
  143. package/src/plugin/Form/InputTag.tsx +70 -0
  144. package/src/plugin/Form/InputText.tsx +186 -0
  145. package/src/plugin/Form/InputTime.tsx +85 -0
  146. package/src/plugin/Form/InputTree.tsx +229 -0
  147. package/src/plugin/Form/InputURL.tsx +34 -0
  148. package/src/plugin/Form/InputYear.tsx +35 -0
  149. package/src/plugin/Form/Item.tsx +327 -0
  150. package/src/plugin/Form/ListSelect.tsx +73 -0
  151. package/src/plugin/Form/LocationPicker.tsx +62 -0
  152. package/src/plugin/Form/MatrixCheckboxes.tsx +136 -0
  153. package/src/plugin/Form/NestedSelect.tsx +211 -0
  154. package/src/plugin/Form/Picker.tsx +209 -0
  155. package/src/plugin/Form/Radios.tsx +119 -0
  156. package/src/plugin/Form/Select.tsx +233 -0
  157. package/src/plugin/Form/Static.tsx +322 -0
  158. package/src/plugin/Form/Switch.tsx +107 -0
  159. package/src/plugin/Form/TabsTransfer.tsx +259 -0
  160. package/src/plugin/Form/Textarea.tsx +83 -0
  161. package/src/plugin/Form/Transfer.tsx +368 -0
  162. package/src/plugin/Form/TreeSelect.tsx +263 -0
  163. package/src/plugin/Form/UUID.tsx +48 -0
  164. package/src/plugin/Grid.tsx +798 -0
  165. package/src/plugin/HBox.tsx +727 -0
  166. package/src/plugin/IFrame.tsx +70 -0
  167. package/src/plugin/Image.tsx +314 -0
  168. package/src/plugin/Images.tsx +231 -0
  169. package/src/plugin/Json.tsx +69 -0
  170. package/src/plugin/Link.tsx +93 -0
  171. package/src/plugin/List.tsx +278 -0
  172. package/src/plugin/ListItem.tsx +229 -0
  173. package/src/plugin/Log.tsx +52 -0
  174. package/src/plugin/Mapping.tsx +149 -0
  175. package/src/plugin/Markdown.tsx +47 -0
  176. package/src/plugin/Nav.tsx +184 -0
  177. package/src/plugin/Operation.tsx +95 -0
  178. package/src/plugin/Others/Action.tsx +426 -0
  179. package/src/plugin/Others/BasicToolbar.tsx +585 -0
  180. package/src/plugin/Others/DataDebug.tsx +134 -0
  181. package/src/plugin/Others/TableCell.tsx +480 -0
  182. package/src/plugin/Others/Unknown.tsx +37 -0
  183. package/src/plugin/Page.tsx +306 -0
  184. package/src/plugin/Panel/AvailableRenderers.tsx +41 -0
  185. package/src/plugin/Panel/Code.tsx +44 -0
  186. package/src/plugin/Panel/Name.tsx +26 -0
  187. package/src/plugin/Panel/Outline.tsx +40 -0
  188. package/src/plugin/Panel.tsx +243 -0
  189. package/src/plugin/Plain.tsx +84 -0
  190. package/src/plugin/Progress.tsx +125 -0
  191. package/src/plugin/Property.tsx +139 -0
  192. package/src/plugin/QRCode.tsx +96 -0
  193. package/src/plugin/Reset.tsx +23 -0
  194. package/src/plugin/Service.tsx +162 -0
  195. package/src/plugin/Sparkline.tsx +40 -0
  196. package/src/plugin/Status.tsx +76 -0
  197. package/src/plugin/Steps.tsx +128 -0
  198. package/src/plugin/Submit.tsx +23 -0
  199. package/src/plugin/Table.tsx +428 -0
  200. package/src/plugin/TableView.tsx +709 -0
  201. package/src/plugin/Tabs.tsx +362 -0
  202. package/src/plugin/Tasks.tsx +274 -0
  203. package/src/plugin/Time.tsx +68 -0
  204. package/src/plugin/TooltipWrapper.tsx +193 -0
  205. package/src/plugin/Tpl.tsx +158 -0
  206. package/src/plugin/Video.tsx +158 -0
  207. package/src/plugin/WebComponent.tsx +53 -0
  208. package/src/plugin/Wizard.tsx +740 -0
  209. package/src/plugin/Wrapper.tsx +107 -0
  210. package/src/plugin.ts +1050 -0
  211. package/dist/150a58f3318ca7541ed9.png +0 -0
  212. package/dist/471adb97c322b226e589.png +0 -0
  213. package/dist/4de5f42360bc5946c3c2.png +0 -0
  214. package/dist/4e9968bba3855f088fed.png +0 -0
  215. package/dist/7f09c38ebc687fea847a.png +0 -0
  216. package/dist/c94073576487510314ea.png +0 -0
@@ -0,0 +1,2157 @@
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
+ autoFillApi: {},
681
+
682
+ apiString: {
683
+ name: 'api',
684
+ type: 'input-text',
685
+ placeholder: 'http://'
686
+ },
687
+
688
+ required: {
689
+ name: 'required',
690
+ type: 'switch',
691
+ mode: 'inline',
692
+ className: 'w-full',
693
+ label: '是否必填'
694
+ },
695
+
696
+ description: {
697
+ name: 'description',
698
+ type: 'textarea',
699
+ label: '描述',
700
+ pipeIn: (value: any, data: any) => value || data.desc || ''
701
+ },
702
+
703
+ options: {
704
+ label: '选项 Options',
705
+ name: 'options',
706
+ type: 'combo',
707
+ multiple: true,
708
+ draggable: true,
709
+ addButtonText: '新增选项',
710
+ scaffold: {
711
+ label: '',
712
+ value: ''
713
+ },
714
+ items: [
715
+ {
716
+ type: 'input-text',
717
+ name: 'label',
718
+ placeholder: '名称',
719
+ required: true
720
+ },
721
+ {
722
+ type: 'select',
723
+ name: 'value',
724
+ pipeIn: (value: any) => {
725
+ if (typeof value === 'string') {
726
+ return 'text';
727
+ }
728
+ if (typeof value === 'boolean') {
729
+ return 'boolean';
730
+ }
731
+ if (typeof value === 'number') {
732
+ return 'number';
733
+ }
734
+ return 'text';
735
+ },
736
+ pipeOut: (value: any, oldValue: any) => {
737
+ if (value === 'text') {
738
+ return String(oldValue);
739
+ }
740
+ if (value === 'number') {
741
+ const convertTo = Number(oldValue);
742
+ if (isNaN(convertTo)) {
743
+ return 0;
744
+ }
745
+ return convertTo;
746
+ }
747
+ if (value === 'boolean') {
748
+ return Boolean(oldValue);
749
+ }
750
+ return '';
751
+ },
752
+ options: [
753
+ {label: '文本', value: 'text'},
754
+ {label: '数字', value: 'number'},
755
+ {label: '布尔', value: 'boolean'}
756
+ ]
757
+ },
758
+ {
759
+ type: 'input-number',
760
+ name: 'value',
761
+ placeholder: '值',
762
+ visibleOn: 'typeof data.value === "number"',
763
+ unique: true
764
+ },
765
+ {
766
+ type: 'switch',
767
+ name: 'value',
768
+ placeholder: '值',
769
+ visibleOn: 'typeof data.value === "boolean"',
770
+ unique: true
771
+ },
772
+ {
773
+ type: 'input-text',
774
+ name: 'value',
775
+ placeholder: '值',
776
+ visibleOn:
777
+ 'typeof data.value === "undefined" || typeof data.value === "string"',
778
+ unique: true
779
+ }
780
+ ]
781
+ },
782
+
783
+ tree: {
784
+ label: '选项 Options',
785
+ name: 'options',
786
+ type: 'combo',
787
+ multiple: true,
788
+ draggable: true,
789
+ addButtonText: '新增选项',
790
+ description:
791
+ '静态数据暂不支持多级,请切换到代码模式,或者采用 source 接口获取。',
792
+ scaffold: {
793
+ label: '',
794
+ value: ''
795
+ },
796
+ items: [
797
+ {
798
+ type: 'input-text',
799
+ name: 'label',
800
+ placeholder: '名称',
801
+ required: true
802
+ },
803
+
804
+ {
805
+ type: 'input-text',
806
+ name: 'value',
807
+ placeholder: '值',
808
+ unique: true
809
+ }
810
+ ]
811
+ },
812
+
813
+ horizontalMode: {
814
+ label: '表单项左右占比设置',
815
+ name: 'horizontal',
816
+ type: 'switch',
817
+ onText: '继承',
818
+ offText: '自定义',
819
+ mode: 'inline',
820
+ className: 'w-full',
821
+ inputClassName: 'text-sm',
822
+ visibleOn: 'this.mode == "horizontal" && this.label !== false',
823
+ pipeIn: (value: any) => !value,
824
+ pipeOut: (value: any, originValue: any, data: any) =>
825
+ value
826
+ ? null
827
+ : data.formHorizontal || {
828
+ leftFixed: 'normal'
829
+ }
830
+ },
831
+
832
+ horizontal: {
833
+ type: 'combo',
834
+ syncDefaultValue: false,
835
+ name: 'horizontal',
836
+ multiLine: true,
837
+ visibleOn:
838
+ 'data.mode == "horizontal" && data.label !== false && data.horizontal',
839
+ pipeIn: (value: any) => {
840
+ return {
841
+ leftRate:
842
+ value && typeof value.left === 'number'
843
+ ? value.left
844
+ : value && /\bcol\-(?:xs|sm|md|lg)\-(\d+)\b/.test(value.left)
845
+ ? parseInt(RegExp.$1, 10)
846
+ : 2,
847
+ leftFixed: (value && value.leftFixed) || ''
848
+ };
849
+ },
850
+ pipeOut: (value: any) => {
851
+ let left = Math.min(11, Math.max(1, value.leftRate || 2));
852
+
853
+ return {
854
+ leftFixed: value.leftFixed || '',
855
+ left: left,
856
+ right: 12 - left
857
+ };
858
+ },
859
+ inputClassName: 'no-padder',
860
+ items: [
861
+ {
862
+ name: 'leftFixed',
863
+ type: 'button-group-select',
864
+ label: '左侧宽度',
865
+ size: 'xs',
866
+ options: [
867
+ {
868
+ label: '比率',
869
+ value: ''
870
+ },
871
+
872
+ {
873
+ label: '小宽度',
874
+ value: 'sm',
875
+ visibleOn: 'this.leftFixed'
876
+ },
877
+
878
+ {
879
+ label: '固定宽度',
880
+ value: 'normal'
881
+ },
882
+
883
+ {
884
+ label: '大宽度',
885
+ value: 'lg',
886
+ visibleOn: 'this.leftFixed'
887
+ }
888
+ ]
889
+ },
890
+ {
891
+ name: 'leftRate',
892
+ type: 'input-range',
893
+ visibleOn: '!this.leftFixed',
894
+ min: 1,
895
+ max: 11,
896
+ step: 1,
897
+ label: '左右分布调整(n/12)',
898
+ labelRemark: {
899
+ trigger: 'click',
900
+ className: 'm-l-xs',
901
+ rootClose: true,
902
+ content: '一共 12 等份,这里可以设置左侧宽度占比 n/12。',
903
+ placement: 'left'
904
+ }
905
+ }
906
+ ]
907
+ },
908
+
909
+ subFormItemMode: {
910
+ label: '子表单展示模式',
911
+ name: 'subFormMode',
912
+ type: 'button-group-select',
913
+ size: 'sm',
914
+ option: '继承',
915
+ // mode: 'inline',
916
+ // className: 'w-full',
917
+ pipeIn: defaultValue(''),
918
+ options: [
919
+ {
920
+ label: '继承',
921
+ value: ''
922
+ },
923
+
924
+ {
925
+ label: '正常',
926
+ value: 'normal'
927
+ },
928
+
929
+ {
930
+ label: '内联',
931
+ value: 'inline'
932
+ },
933
+
934
+ {
935
+ label: '水平',
936
+ value: 'horizontal'
937
+ }
938
+ ]
939
+ },
940
+
941
+ subFormHorizontalMode: {
942
+ label: '子表单水平占比设置',
943
+ name: 'subFormHorizontal',
944
+ type: 'switch',
945
+ onText: '继承',
946
+ offText: '自定义',
947
+ mode: 'inline',
948
+ className: 'w-full',
949
+ inputClassName: 'text-sm',
950
+ visibleOn: 'this.subFormMode == "horizontal"',
951
+ pipeIn: (value: any) => !value,
952
+ pipeOut: (value: any, originValue: any, data: any) =>
953
+ value
954
+ ? null
955
+ : data.formHorizontal || {
956
+ leftFixed: 'normal'
957
+ }
958
+ },
959
+
960
+ subFormHorizontal: {
961
+ type: 'combo',
962
+ syncDefaultValue: false,
963
+ visibleOn: 'data.subFormMode == "horizontal" && data.subFormHorizontal',
964
+ name: 'subFormHorizontal',
965
+ multiLine: true,
966
+ pipeIn: (value: any) => {
967
+ return {
968
+ leftRate:
969
+ value && typeof value.left === 'number'
970
+ ? value.left
971
+ : value && /\bcol\-(?:xs|sm|md|lg)\-(\d+)\b/.test(value.left)
972
+ ? parseInt(RegExp.$1, 10)
973
+ : 2,
974
+ leftFixed: (value && value.leftFixed) || ''
975
+ };
976
+ },
977
+ pipeOut: (value: any) => {
978
+ let left = Math.min(11, Math.max(1, value.leftRate || 2));
979
+
980
+ return {
981
+ leftFixed: value.leftFixed || '',
982
+ left: left,
983
+ right: 12 - left
984
+ };
985
+ },
986
+ inputClassName: 'no-padder',
987
+ items: [
988
+ {
989
+ name: 'leftFixed',
990
+ type: 'button-group-select',
991
+ label: '左侧宽度',
992
+ size: 'xs',
993
+ options: [
994
+ {
995
+ label: '比率',
996
+ value: ''
997
+ },
998
+
999
+ {
1000
+ label: '小宽度',
1001
+ value: 'sm',
1002
+ visibleOn: 'this.leftFixed'
1003
+ },
1004
+
1005
+ {
1006
+ label: '固定宽度',
1007
+ value: 'normal'
1008
+ },
1009
+
1010
+ {
1011
+ label: '大宽度',
1012
+ value: 'lg',
1013
+ visibleOn: 'this.leftFixed'
1014
+ }
1015
+ ]
1016
+ },
1017
+ {
1018
+ name: 'leftRate',
1019
+ type: 'input-range',
1020
+ visibleOn: '!this.leftFixed',
1021
+ min: 1,
1022
+ max: 11,
1023
+ step: 1,
1024
+ label: '左右分布调整(n/12)',
1025
+ labelRemark: {
1026
+ trigger: 'click',
1027
+ className: 'm-l-xs',
1028
+ rootClose: true,
1029
+ content: '一共 12 等份,这里可以设置左侧宽度占比 n/12。',
1030
+ placement: 'left'
1031
+ }
1032
+ }
1033
+ ]
1034
+ },
1035
+
1036
+ validations: (function () {
1037
+ const options = [
1038
+ // {
1039
+ // label: '必填',
1040
+ // value: 'isRequired'
1041
+ // },
1042
+ {
1043
+ label: '邮箱格式',
1044
+ value: 'isEmail'
1045
+ },
1046
+ {
1047
+ label: 'Url格式',
1048
+ value: 'isUrl'
1049
+ },
1050
+ {
1051
+ label: '数字',
1052
+ value: 'isNumeric'
1053
+ },
1054
+ {
1055
+ label: '字母',
1056
+ value: 'isAlpha'
1057
+ },
1058
+ {
1059
+ label: '字母和数字',
1060
+ value: 'isAlphanumeric'
1061
+ },
1062
+ {
1063
+ label: '整型数字',
1064
+ value: 'isInt'
1065
+ },
1066
+ {
1067
+ label: '浮点型数字',
1068
+ value: 'isFloat'
1069
+ },
1070
+ {
1071
+ label: '固定长度',
1072
+ value: 'isLength'
1073
+ },
1074
+ {
1075
+ label: '最大长度',
1076
+ value: 'maxLength'
1077
+ },
1078
+ {
1079
+ label: '最小长度',
1080
+ value: 'minLength'
1081
+ },
1082
+ {
1083
+ label: '最大值',
1084
+ value: 'maximum'
1085
+ },
1086
+ {
1087
+ label: '最小值',
1088
+ value: 'minimum'
1089
+ },
1090
+ {
1091
+ label: '手机号码',
1092
+ value: 'isPhoneNumber'
1093
+ },
1094
+ {
1095
+ label: '电话号码',
1096
+ value: 'isTelNumber'
1097
+ },
1098
+ {
1099
+ label: '邮编号码',
1100
+ value: 'isZipcode'
1101
+ },
1102
+ {
1103
+ label: '身份证号码',
1104
+ value: 'isId'
1105
+ },
1106
+ {
1107
+ label: 'JSON格式',
1108
+ value: 'isJson'
1109
+ },
1110
+ {
1111
+ label: '与指定值相同',
1112
+ value: 'equals'
1113
+ },
1114
+ {
1115
+ label: '与指定字段值相同',
1116
+ value: 'equalsField'
1117
+ },
1118
+ {
1119
+ label: '自定义正则',
1120
+ value: 'matchRegexp'
1121
+ },
1122
+ {
1123
+ label: '自定义正则2',
1124
+ value: 'matchRegexp1'
1125
+ },
1126
+ {
1127
+ label: '自定义正则3',
1128
+ value: 'matchRegexp2'
1129
+ },
1130
+ {
1131
+ label: '自定义正则4',
1132
+ value: 'matchRegexp3'
1133
+ },
1134
+ {
1135
+ label: '自定义正则5',
1136
+ value: 'matchRegexp4'
1137
+ }
1138
+ ];
1139
+
1140
+ const trueProps = [
1141
+ 'isEmail',
1142
+ 'isUrl',
1143
+ 'isNumeric',
1144
+ 'isAlpha',
1145
+ 'isAlphanumeric',
1146
+ 'isInt',
1147
+ 'isFloat',
1148
+ 'isJson',
1149
+ 'isPhoneNumber',
1150
+ 'isTelNumber',
1151
+ 'isZipcode',
1152
+ 'isId'
1153
+ ];
1154
+
1155
+ function firstValue(arr: Array<any>, iterator: (item: any) => any) {
1156
+ let theone = find(arr, iterator);
1157
+ return theone ? theone.value : '';
1158
+ }
1159
+
1160
+ return {
1161
+ type: 'combo',
1162
+ syncDefaultValue: false,
1163
+ name: 'validations',
1164
+ label: '验证规则',
1165
+ addButtonText: '新增规则',
1166
+ multiple: true,
1167
+ pipeIn: (value: any) => {
1168
+ if (typeof value === 'string' && value) {
1169
+ value = str2rules(value);
1170
+ }
1171
+ if (!isObject(value)) {
1172
+ return value;
1173
+ }
1174
+
1175
+ let arr: Array<any> = [];
1176
+
1177
+ Object.keys(value).forEach(key => {
1178
+ if (/^\$\$/.test(key)) {
1179
+ return;
1180
+ }
1181
+
1182
+ arr.push({
1183
+ type: key,
1184
+ [key]: Array.isArray(value[key]) ? value[key][0] : value[key]
1185
+ });
1186
+ });
1187
+
1188
+ return arr;
1189
+ },
1190
+ pipeOut: (value: any) => {
1191
+ if (!Array.isArray(value)) {
1192
+ return value;
1193
+ }
1194
+ let obj: any = {};
1195
+
1196
+ value.forEach((item: any) => {
1197
+ let key: string =
1198
+ item.type ||
1199
+ firstValue(options, (item: any) => !obj[item.value]) ||
1200
+ options[0].value;
1201
+ obj[key] = item[key] || (~trueProps.indexOf(key) ? true : '');
1202
+ });
1203
+
1204
+ return obj;
1205
+ },
1206
+ items: [
1207
+ {
1208
+ type: 'select',
1209
+ unique: true,
1210
+ name: 'type',
1211
+ options: options,
1212
+ columnClassName: 'w-sm'
1213
+ },
1214
+ {
1215
+ type: 'input-number',
1216
+ name: 'isLength',
1217
+ visibleOn: 'data.type == "isLength"',
1218
+ placeholder: '设置长度',
1219
+ value: '1'
1220
+ },
1221
+ {
1222
+ type: 'input-number',
1223
+ name: 'maximum',
1224
+ visibleOn: 'data.type == "maximum"',
1225
+ placeholder: '设置最大值'
1226
+ },
1227
+ {
1228
+ type: 'input-number',
1229
+ name: 'minimum',
1230
+ visibleOn: 'data.type == "minimum"',
1231
+ placeholder: '设置最小值'
1232
+ },
1233
+ {
1234
+ type: 'input-number',
1235
+ name: 'maxLength',
1236
+ visibleOn: 'data.type == "maxLength"',
1237
+ placeholder: '设置最大长度值'
1238
+ },
1239
+ {
1240
+ type: 'input-number',
1241
+ name: 'minLength',
1242
+ visibleOn: 'data.type == "minLength"',
1243
+ placeholder: '设置最小长度值'
1244
+ },
1245
+ {
1246
+ type: 'input-text',
1247
+ name: 'equals',
1248
+ visibleOn: 'data.type == "equals"',
1249
+ placeholder: '设置值',
1250
+ value: ''
1251
+ },
1252
+ {
1253
+ type: 'input-text',
1254
+ name: 'equalsField',
1255
+ visibleOn: 'data.type == "equalsField"',
1256
+ placeholder: '设置字段名',
1257
+ value: ''
1258
+ },
1259
+ {
1260
+ type: 'input-text',
1261
+ name: 'matchRegexp',
1262
+ visibleOn: 'data.type == "matchRegexp"',
1263
+ placeholder: '设置正则规则'
1264
+ },
1265
+ {
1266
+ type: 'input-text',
1267
+ name: 'matchRegexp1',
1268
+ visibleOn: 'data.type == "matchRegexp1"',
1269
+ placeholder: '设置正则规则'
1270
+ },
1271
+ {
1272
+ type: 'input-text',
1273
+ name: 'matchRegexp2',
1274
+ visibleOn: 'data.type == "matchRegexp2"',
1275
+ placeholder: '设置正则规则'
1276
+ },
1277
+ {
1278
+ type: 'input-text',
1279
+ name: 'matchRegexp3',
1280
+ visibleOn: 'data.type == "matchRegexp3"',
1281
+ placeholder: '设置正则规则'
1282
+ },
1283
+ {
1284
+ type: 'input-text',
1285
+ name: 'matchRegexp4',
1286
+ visibleOn: 'data.type == "matchRegexp4"',
1287
+ placeholder: '设置正则规则'
1288
+ }
1289
+ ]
1290
+ };
1291
+ })(),
1292
+
1293
+ validationErrors: (function () {
1294
+ const options = [
1295
+ // {
1296
+ // label: '必填',
1297
+ // value: 'isRequired'
1298
+ // },
1299
+ {
1300
+ label: '邮箱格式',
1301
+ value: 'isEmail'
1302
+ },
1303
+ {
1304
+ label: 'Url格式',
1305
+ value: 'isUrl'
1306
+ },
1307
+ {
1308
+ label: '数字',
1309
+ value: 'isNumeric'
1310
+ },
1311
+ {
1312
+ label: '字母',
1313
+ value: 'isAlpha'
1314
+ },
1315
+ {
1316
+ label: '字母和数字',
1317
+ value: 'isAlphanumeric'
1318
+ },
1319
+ {
1320
+ label: '整型数字',
1321
+ value: 'isInt'
1322
+ },
1323
+ {
1324
+ label: '浮点型数字',
1325
+ value: 'isFloat'
1326
+ },
1327
+ {
1328
+ label: '固定长度',
1329
+ value: 'isLength'
1330
+ },
1331
+ {
1332
+ label: '最大长度',
1333
+ value: 'maxLength'
1334
+ },
1335
+ {
1336
+ label: '最小长度',
1337
+ value: 'minLength'
1338
+ },
1339
+ {
1340
+ label: '最大值',
1341
+ value: 'maximum'
1342
+ },
1343
+ {
1344
+ label: '最小值',
1345
+ value: 'minimum'
1346
+ },
1347
+ {
1348
+ label: 'JSON格式',
1349
+ value: 'isJson'
1350
+ },
1351
+ {
1352
+ label: '手机号码',
1353
+ value: 'isPhoneNumber'
1354
+ },
1355
+ {
1356
+ label: '电话号码',
1357
+ value: 'isTelNumber'
1358
+ },
1359
+ {
1360
+ label: '邮编号码',
1361
+ value: 'isZipcode'
1362
+ },
1363
+ {
1364
+ label: '身份证号码',
1365
+ value: 'isId'
1366
+ },
1367
+ {
1368
+ label: '与指定值相同',
1369
+ value: 'equals'
1370
+ },
1371
+ {
1372
+ label: '与指定字段值相同',
1373
+ value: 'equalsField'
1374
+ },
1375
+ {
1376
+ label: '自定义正则',
1377
+ value: 'matchRegexp'
1378
+ },
1379
+ {
1380
+ label: '自定义正则2',
1381
+ value: 'matchRegexp1'
1382
+ },
1383
+ {
1384
+ label: '自定义正则3',
1385
+ value: 'matchRegexp2'
1386
+ },
1387
+ {
1388
+ label: '自定义正则4',
1389
+ value: 'matchRegexp3'
1390
+ },
1391
+ {
1392
+ label: '自定义正则5',
1393
+ value: 'matchRegexp4'
1394
+ }
1395
+ ];
1396
+
1397
+ const defaultMessages = {
1398
+ isEmail: 'Email 格式不正确',
1399
+ isRequired: '这是必填项',
1400
+ isUrl: 'Url 格式不正确',
1401
+ isInt: '请输入整形数字',
1402
+ isAlpha: '请输入字母',
1403
+ isNumeric: '请输入数字',
1404
+ isAlphanumeric: '请输入字母或者数字',
1405
+ isFloat: '请输入浮点型数值',
1406
+ isWords: '请输入字母',
1407
+ isUrlPath: '只能输入字母、数字、`-` 和 `_`.',
1408
+ matchRegexp: '格式不正确, 请输入符合规则为 `$1` 的内容。',
1409
+ minLength: '请输入更多的内容,至少输入 $1 个字符。',
1410
+ maxLength: '请控制内容长度, 请不要输入 $1 个字符以上',
1411
+ maximum: '当前输入值超出最大值 $1,请检查',
1412
+ minimum: '当前输入值低于最小值 $1,请检查',
1413
+ isJson: '请检查 Json 格式。',
1414
+ isPhoneNumber: '请输入合法的手机号码',
1415
+ isTelNumber: '请输入合法的电话号码',
1416
+ isZipcode: '请输入合法的邮编地址',
1417
+ isId: '请输入合法的身份证号',
1418
+ isLength: '请输入长度为 $1 的内容',
1419
+ notEmptyString: '请不要全输入空白字符',
1420
+ equalsField: '输入的数据与 $1 值不一致',
1421
+ equals: '输入的数据与 $1 不一致'
1422
+ };
1423
+
1424
+ function firstValue(arr: Array<any>, iterator: (item: any) => any) {
1425
+ let theone = find(arr, iterator);
1426
+ return theone ? theone.value : '';
1427
+ }
1428
+
1429
+ return {
1430
+ type: 'combo',
1431
+ syncDefaultValue: false,
1432
+ name: 'validationErrors',
1433
+ label: '自定义验证提示',
1434
+ description: '自带提示不满足时,可以自定义。',
1435
+ addButtonText: '新增提示',
1436
+ multiple: true,
1437
+ pipeIn: (value: any) => {
1438
+ if (!isObject(value)) {
1439
+ return value;
1440
+ }
1441
+
1442
+ let arr: Array<any> = [];
1443
+
1444
+ Object.keys(value).forEach(key => {
1445
+ if (/^\$\$/.test(key)) {
1446
+ return;
1447
+ }
1448
+
1449
+ arr.push({
1450
+ type: key,
1451
+ msg: value[key]
1452
+ });
1453
+ });
1454
+
1455
+ return arr;
1456
+ },
1457
+ pipeOut: (value: any) => {
1458
+ if (!Array.isArray(value)) {
1459
+ return value;
1460
+ }
1461
+ let obj: any = {};
1462
+
1463
+ value.forEach((item: any) => {
1464
+ let key: string =
1465
+ item.type ||
1466
+ firstValue(options, (item: any) => !obj[item.value]) ||
1467
+ options[0].value;
1468
+ obj[key] = item.msg || (defaultMessages as any)[key] || '';
1469
+ });
1470
+
1471
+ return obj;
1472
+ },
1473
+ items: [
1474
+ {
1475
+ type: 'select',
1476
+ unique: true,
1477
+ name: 'type',
1478
+ options: options,
1479
+ columnClassName: 'w-sm'
1480
+ },
1481
+
1482
+ {
1483
+ type: 'input-text',
1484
+ name: 'msg',
1485
+ placeholder: '提示信息'
1486
+ },
1487
+
1488
+ {
1489
+ type: 'formula',
1490
+ name: 'msg',
1491
+ initSet: false,
1492
+ formula: `({
1493
+ isEmail: 'Email 格式不正确',
1494
+ isRequired: '这是必填项',
1495
+ isUrl: 'Url 格式不正确',
1496
+ isInt: '请输入整形数字',
1497
+ isAlpha: '请输入字母',
1498
+ isNumeric: '请输入数字',
1499
+ isAlphanumeric: '请输入字母或者数字',
1500
+ isFloat: '请输入浮点型数值',
1501
+ isWords: '请输入字母',
1502
+ isUrlPath: '只能输入字母、数字、\`-\` 和 \`_\`.',
1503
+ matchRegexp: '格式不正确, 请输入符合规则为 \`$1\` 的内容。',
1504
+ minLength: '请输入更多的内容,至少输入 $1 个字符。',
1505
+ maxLength: '请控制内容长度, 请不要输入 $1 个字符以上',
1506
+ maximum: '当前输入值超出最大值 $1,请检查',
1507
+ minimum: '当前输入值低于最小值 $1,请检查',
1508
+ isJson: '请检查 Json 格式。',
1509
+ isLength: '请输入长度为 $1 的内容',
1510
+ notEmptyString: '请不要全输入空白字符',
1511
+ equalsField: '输入的数据与 $1 值不一致',
1512
+ equals: '输入的数据与 $1 不一致',
1513
+ isPhoneNumber: '请输入合法的手机号码',
1514
+ isTelNumber: '请输入合法的电话号码',
1515
+ isZipcode: '请输入合法的邮编地址',
1516
+ isId: '请输入合法的身份证号',
1517
+ })[data.type] || ''`
1518
+ }
1519
+ ]
1520
+ };
1521
+ })(),
1522
+
1523
+ submitOnChange: {
1524
+ label: '修改即提交',
1525
+ type: 'switch',
1526
+ name: 'submitOnChange',
1527
+ mode: 'inline',
1528
+ className: 'w-full',
1529
+ labelRemark: {
1530
+ trigger: 'click',
1531
+ className: 'm-l-xs',
1532
+ rootClose: true,
1533
+ content: '设置后,表单中每次有修改都会触发提交',
1534
+ placement: 'left'
1535
+ }
1536
+ },
1537
+
1538
+ validateOnChange: {
1539
+ type: 'button-group-select',
1540
+ name: 'validateOnChange',
1541
+ label: '修改即触发表单验证',
1542
+ description: '默认为当表单提交过则每次修改都触发验证。',
1543
+ size: 'xs',
1544
+ mode: 'inline',
1545
+ className: 'w-full',
1546
+ options: [
1547
+ {
1548
+ label: '默认',
1549
+ value: ''
1550
+ },
1551
+
1552
+ {
1553
+ label: '开启',
1554
+ value: true
1555
+ },
1556
+
1557
+ {
1558
+ label: '关闭',
1559
+ value: false
1560
+ }
1561
+ ],
1562
+ pipeIn: defaultValue(''),
1563
+ pipeOut: (value: any) => (value === '' ? undefined : !!value)
1564
+ },
1565
+
1566
+ validationControl: {
1567
+ type: 'ae-validationControl',
1568
+ label: '校验',
1569
+ mode: 'normal'
1570
+ },
1571
+
1572
+ visible: {
1573
+ type: 'fieldSet',
1574
+ title: '显隐配置',
1575
+ collapsable: false, // 避免和最外层的属性配置面板的tabs样式重叠
1576
+ body: [
1577
+ {
1578
+ label: '设置方式',
1579
+ name: 'visible',
1580
+ type: 'button-group-select',
1581
+ size: 'xs',
1582
+ mode: 'inline',
1583
+ className: 'w-full',
1584
+ options: [
1585
+ {
1586
+ label: '静态设置',
1587
+ value: 1
1588
+ },
1589
+
1590
+ {
1591
+ label: '表达式',
1592
+ value: 2
1593
+ }
1594
+ ],
1595
+ pipeIn: (value: any) => (typeof value === 'boolean' ? 1 : 2),
1596
+ pipeOut: (value: any) => (value === 1 ? true : ''),
1597
+ onChange: (value: any, oldValue: boolean, model: any, form: any) => {
1598
+ if (value) {
1599
+ form.setValues({
1600
+ __visibleOn: form.data.visibleOn,
1601
+ visibleOn: '',
1602
+ clearValueOnHidden: false
1603
+ });
1604
+ } else {
1605
+ form.setValueByName('visibleOn', form.data.__visibleOn);
1606
+ }
1607
+ }
1608
+ },
1609
+
1610
+ {
1611
+ type: 'switch',
1612
+ label: '可见(visible)',
1613
+ name: 'visible',
1614
+ visibleOn: 'typeof this.visible === "boolean"',
1615
+ pipeIn: (value: any, data: any) => value !== false && !data.hidden,
1616
+ mode: 'inline',
1617
+ className: 'w-full m-b-none',
1618
+ onChange: (value: boolean, oldValue: boolean, model: any, form: any) =>
1619
+ form.setValueByName('visibleOn', '')
1620
+ },
1621
+
1622
+ {
1623
+ name: 'visibleOn',
1624
+ label: '可见表达式(visibleOn)',
1625
+ labelRemark: {
1626
+ trigger: 'click',
1627
+ className: 'm-l-xs',
1628
+ rootClose: true,
1629
+ content:
1630
+ '纯粹的 JS 语法,this 指向当前数据层。文档:<a href="https://baidu.github.io/amis/docs/concepts/expression">表达式语法</a>',
1631
+ placement: 'left'
1632
+ },
1633
+ placeholder: '如:this.type === 1',
1634
+ type: 'input-text',
1635
+ visibleOn: 'typeof this.visible !== "boolean"',
1636
+ autoComplete: false,
1637
+ pipeIn: (value: any, data: any) =>
1638
+ value || (data.hiddenOn && `!(${data.hiddenOn})`) || '',
1639
+ className: 'm-b-none'
1640
+ }
1641
+ ]
1642
+ },
1643
+
1644
+ initFetch: {
1645
+ type: 'group',
1646
+ label: '是否初始加载',
1647
+ visibleOn: 'this.initApi',
1648
+ direction: 'vertical',
1649
+ className: 'm-b-none',
1650
+ labelRemark: {
1651
+ trigger: 'click',
1652
+ rootClose: true,
1653
+ className: 'm-l-xs',
1654
+ content:
1655
+ '当配置初始化接口后,组件初始就会拉取接口数据,可以通过以下配置修改。',
1656
+ placement: 'left'
1657
+ },
1658
+ body: [
1659
+ {
1660
+ name: 'initFetch',
1661
+ type: 'radios',
1662
+ inline: true,
1663
+ onChange: () => {},
1664
+ // pipeIn: (value:any) => typeof value === 'boolean' ? value : '1'
1665
+ options: [
1666
+ {
1667
+ label: '是',
1668
+ value: true
1669
+ },
1670
+
1671
+ {
1672
+ label: '否',
1673
+ value: false
1674
+ },
1675
+
1676
+ {
1677
+ label: '表达式',
1678
+ value: ''
1679
+ }
1680
+ ]
1681
+ },
1682
+
1683
+ {
1684
+ name: 'initFetchOn',
1685
+ autoComplete: false,
1686
+ visibleOn: 'typeof this.initFetch !== "boolean"',
1687
+ type: 'input-text',
1688
+ placeholder: '如:this.id 表示有 id 值时初始加载',
1689
+ className: 'm-t-n-sm'
1690
+ }
1691
+ ]
1692
+ },
1693
+
1694
+ disabled: (additions: Array<any> = []) => {
1695
+ return {
1696
+ type: 'fieldSet',
1697
+ title: '禁用配置',
1698
+ collapsable: false, // 避免和最外层的属性配置面板的tabs样式重叠
1699
+ body: [
1700
+ ...additions,
1701
+ {
1702
+ label: '设置方式',
1703
+ name: 'disabled',
1704
+ type: 'button-group-select',
1705
+ size: 'xs',
1706
+ mode: 'inline',
1707
+ className: 'w-full',
1708
+ options: [
1709
+ {
1710
+ label: '静态设置',
1711
+ value: 1
1712
+ },
1713
+
1714
+ {
1715
+ label: '表达式',
1716
+ value: 2
1717
+ }
1718
+ ],
1719
+ pipeIn: (value: any) => (typeof value === 'boolean' ? 1 : 2),
1720
+ pipeOut: (value: any) => (value === 1 ? false : '')
1721
+ },
1722
+
1723
+ {
1724
+ type: 'switch',
1725
+ label: '禁用(disabled)',
1726
+ name: 'disabled',
1727
+ visibleOn: 'typeof this.disabled === "boolean"',
1728
+ pipeIn: (value: any, data: any) => value !== false && !data.hidden,
1729
+ mode: 'inline',
1730
+ className: 'w-full m-b-none',
1731
+ onChange: (
1732
+ value: boolean,
1733
+ oldValue: boolean,
1734
+ model: any,
1735
+ form: any
1736
+ ) => form.setValueByName('disabledOn', '')
1737
+ },
1738
+
1739
+ {
1740
+ name: 'disabledOn',
1741
+ label: '禁用表达式(disabledOn)',
1742
+ placeholder: '如:this.type === 1',
1743
+ labelRemark: {
1744
+ trigger: 'click',
1745
+ className: 'm-l-xs',
1746
+ rootClose: true,
1747
+ content:
1748
+ '纯粹的 JS 语法,this 指向当前数据层。文档:<a href="https://baidu.github.io/amis/docs/concepts/expression">表达式语法</a>',
1749
+ placement: 'left'
1750
+ },
1751
+ type: 'input-text',
1752
+ visibleOn: 'typeof this.disabled !== "boolean"',
1753
+ className: 'm-b-none'
1754
+ }
1755
+ ]
1756
+ };
1757
+ },
1758
+
1759
+ switchDefaultValue: {
1760
+ type: 'switch',
1761
+ name: 'value',
1762
+ label: '设置默认值',
1763
+ mode: 'inline',
1764
+ className: 'w-full',
1765
+ pipeIn: (value: any) => typeof value !== 'undefined',
1766
+ pipeOut: (value: any, origin: any, data: any) => (value ? '' : undefined),
1767
+ remark: '不设置时根据 name 获取'
1768
+ },
1769
+
1770
+ multiple: {
1771
+ label: '多选模式',
1772
+ name: 'multiple',
1773
+ type: 'switch',
1774
+ mode: 'inline',
1775
+ className: 'w-full'
1776
+ },
1777
+
1778
+ joinValues: {
1779
+ type: 'switch',
1780
+ name: 'joinValues',
1781
+ mode: 'inline',
1782
+ className: 'w-full',
1783
+ visibleOn: 'data.multiple',
1784
+ label: '是否拼接值',
1785
+ value: true,
1786
+ description:
1787
+ '开启后将选中的选项 value 的值用连接符拼接起来,作为当前表单项的值。'
1788
+ },
1789
+
1790
+ delimiter: {
1791
+ type: 'input-text',
1792
+ name: 'delimiter',
1793
+ label: '连接符',
1794
+ visibleOn: 'data.multiple && data.joinValues',
1795
+ pipeIn: defaultValue(',')
1796
+ },
1797
+
1798
+ extractValue: {
1799
+ type: 'switch',
1800
+ name: 'extractValue',
1801
+ mode: 'inline',
1802
+ className: 'w-full',
1803
+ label: '是否抽取value值',
1804
+ visibleOn: 'data.joinValues === false',
1805
+ pipeIn: defaultValue(false),
1806
+ description: '开启后将选中的选项 value 的值封装为数组,作为当前表单项的值。'
1807
+ },
1808
+
1809
+ creatable: {
1810
+ label: '可创建选项',
1811
+ name: 'creatable',
1812
+ type: 'switch',
1813
+ mode: 'inline',
1814
+ className: 'w-full'
1815
+ },
1816
+
1817
+ createBtnLabel: {
1818
+ label: '创建按钮文字',
1819
+ name: 'createBtnLabel',
1820
+ type: 'input-text',
1821
+ mode: 'inline',
1822
+ placeholder: '新增选项',
1823
+ className: 'w-full'
1824
+ },
1825
+
1826
+ editable: {
1827
+ label: '可编辑选项',
1828
+ name: 'editable',
1829
+ type: 'switch',
1830
+ mode: 'inline',
1831
+ className: 'w-full'
1832
+ },
1833
+
1834
+ removable: {
1835
+ label: '可删除选项',
1836
+ name: 'removable',
1837
+ type: 'switch',
1838
+ mode: 'inline',
1839
+ className: 'w-full'
1840
+ },
1841
+
1842
+ ref: () => {
1843
+ // {
1844
+ // type: 'input-text',
1845
+ // name: '$ref',
1846
+ // label: '选择定义',
1847
+ // labelRemark: '输入已经在page中设定好的定义'
1848
+ // }
1849
+ return null;
1850
+ },
1851
+
1852
+ imageUrl: {
1853
+ type: 'input-text',
1854
+ label: '图片'
1855
+ },
1856
+
1857
+ fileUrl: {
1858
+ type: 'input-text',
1859
+ label: '文件'
1860
+ },
1861
+
1862
+ markdownBody: {
1863
+ name: 'value',
1864
+ type: 'editor',
1865
+ language: 'markdown',
1866
+ size: 'xxl',
1867
+ label: 'Markdown 内容',
1868
+ options: {
1869
+ lineNumbers: 'off'
1870
+ }
1871
+ },
1872
+
1873
+ richText: {
1874
+ label: '富文本',
1875
+ type: 'input-rich-text',
1876
+ buttons: [
1877
+ 'paragraphFormat',
1878
+ 'quote',
1879
+ 'color',
1880
+ '|',
1881
+ 'bold',
1882
+ 'italic',
1883
+ 'underline',
1884
+ 'strikeThrough',
1885
+ '|',
1886
+ 'formatOL',
1887
+ 'formatUL',
1888
+ 'align',
1889
+ '|',
1890
+ 'insertLink',
1891
+ 'insertImage',
1892
+ 'insertTable',
1893
+ '|',
1894
+ 'undo',
1895
+ 'redo',
1896
+ 'fullscreen'
1897
+ ],
1898
+ name: 'html',
1899
+ description:
1900
+ '支持使用 <code>\\${xxx}</code> 来获取变量,或者用 lodash.template 语法来写模板逻辑。<a target="_blank" href="/amis/zh-CN/docs/concepts/template">详情</a>',
1901
+ size: 'lg'
1902
+ },
1903
+
1904
+ showCounter: {
1905
+ label: '是否显示计数器',
1906
+ name: 'showCounter',
1907
+ type: 'switch',
1908
+ mode: 'inline',
1909
+ className: 'w-full'
1910
+ },
1911
+
1912
+ borderMode: {
1913
+ type: 'select',
1914
+ name: 'borderMode',
1915
+ label: '边框模式',
1916
+ options: [
1917
+ {label: '全边框', value: 'full'},
1918
+ {label: '半边框', value: 'half'},
1919
+ {label: '无边框', value: 'none'}
1920
+ ]
1921
+ },
1922
+
1923
+ data: {
1924
+ type: 'input-kv',
1925
+ name: 'data',
1926
+ label: '初始静态数据'
1927
+ }
1928
+ };
1929
+
1930
+ /**
1931
+ * 样式相关的属性面板,因为预计会比较多所以拆出来
1932
+ */
1933
+ export const styleTpl = {
1934
+ name: 'style',
1935
+ type: 'combo',
1936
+ label: '',
1937
+ noBorder: true,
1938
+ multiLine: true,
1939
+ items: [
1940
+ {
1941
+ type: 'fieldSet',
1942
+ title: '文字',
1943
+ body: [
1944
+ {
1945
+ type: 'group',
1946
+ body: [
1947
+ {
1948
+ label: '文字大小',
1949
+ type: 'input-text',
1950
+ name: 'fontSize'
1951
+ },
1952
+ {
1953
+ label: '文字粗细',
1954
+ name: 'fontWeight',
1955
+ type: 'select',
1956
+ options: ['normal', 'bold', 'lighter', 'bolder']
1957
+ }
1958
+ ]
1959
+ },
1960
+ {
1961
+ type: 'group',
1962
+ body: [
1963
+ {
1964
+ label: '文字颜色',
1965
+ type: 'input-color',
1966
+ name: 'color'
1967
+ },
1968
+ {
1969
+ label: '对齐方式',
1970
+ name: 'textAlign',
1971
+ type: 'select',
1972
+ options: [
1973
+ 'left',
1974
+ 'right',
1975
+ 'center',
1976
+ 'justify',
1977
+ 'justify-all',
1978
+ 'start',
1979
+ 'end',
1980
+ 'match-parent'
1981
+ ]
1982
+ }
1983
+ ]
1984
+ }
1985
+ ]
1986
+ },
1987
+ {
1988
+ type: 'fieldSet',
1989
+ title: '背景',
1990
+ body: [
1991
+ {
1992
+ label: '颜色',
1993
+ name: 'backgroundColor',
1994
+ type: 'input-color'
1995
+ },
1996
+ getSchemaTpl('imageUrl', {
1997
+ name: 'backgroundImage'
1998
+ })
1999
+ ]
2000
+ },
2001
+ {
2002
+ type: 'fieldSet',
2003
+ title: '边距',
2004
+ body: [
2005
+ {
2006
+ type: 'group',
2007
+ label: '外边距',
2008
+ body: [
2009
+ {
2010
+ label: '上',
2011
+ name: 'marginTop',
2012
+ type: 'input-text'
2013
+ },
2014
+ {
2015
+ label: '右',
2016
+ name: 'marginRight',
2017
+ type: 'input-text'
2018
+ },
2019
+ {
2020
+ label: '下',
2021
+ name: 'marginBottom',
2022
+ type: 'input-text'
2023
+ },
2024
+ {
2025
+ label: '左',
2026
+ name: 'marginLeft',
2027
+ type: 'input-text'
2028
+ }
2029
+ ]
2030
+ },
2031
+ {
2032
+ type: 'group',
2033
+ label: '内边距',
2034
+ body: [
2035
+ {
2036
+ label: '上',
2037
+ name: 'paddingTop',
2038
+ type: 'input-text'
2039
+ },
2040
+ {
2041
+ label: '右',
2042
+ name: 'paddingRight',
2043
+ type: 'input-text'
2044
+ },
2045
+ {
2046
+ label: '下',
2047
+ name: 'paddingBottom',
2048
+ type: 'input-text'
2049
+ },
2050
+ {
2051
+ label: '左',
2052
+ name: 'paddingLeft',
2053
+ type: 'input-text'
2054
+ }
2055
+ ]
2056
+ }
2057
+ ]
2058
+ },
2059
+ {
2060
+ type: 'fieldSet',
2061
+ title: '边框',
2062
+ body: [
2063
+ {
2064
+ type: 'group',
2065
+ body: [
2066
+ {
2067
+ label: '样式',
2068
+ name: 'borderStyle',
2069
+ type: 'select',
2070
+ options: ['none', 'solid', 'dotted', 'dashed']
2071
+ },
2072
+ {
2073
+ label: '颜色',
2074
+ name: 'borderColor',
2075
+ type: 'input-color'
2076
+ }
2077
+ ]
2078
+ },
2079
+ {
2080
+ type: 'group',
2081
+ body: [
2082
+ {
2083
+ label: '宽度',
2084
+ name: 'borderWidth',
2085
+ type: 'input-text'
2086
+ },
2087
+ {
2088
+ label: '圆角宽度',
2089
+ name: 'borderRadius',
2090
+ type: 'input-text'
2091
+ }
2092
+ ]
2093
+ }
2094
+ ]
2095
+ },
2096
+ {
2097
+ type: 'fieldSet',
2098
+ title: '特效',
2099
+ body: [
2100
+ {
2101
+ label: '透明度',
2102
+ name: 'opacity',
2103
+ min: 0,
2104
+ max: 1,
2105
+ step: 0.05,
2106
+ type: 'input-range',
2107
+ pipeIn: defaultValue(1)
2108
+ },
2109
+ {
2110
+ label: '阴影',
2111
+ name: 'boxShadow',
2112
+ type: 'input-text'
2113
+ }
2114
+ ]
2115
+ }
2116
+ ]
2117
+ };
2118
+ tpls.style = styleTpl;
2119
+
2120
+ export function getSchemaTpl(name: string, patch?: object): any {
2121
+ const tpl = tpls[name];
2122
+
2123
+ if (typeof tpl === 'function') {
2124
+ return tpl(patch);
2125
+ }
2126
+
2127
+ return tpl
2128
+ ? patch
2129
+ ? {
2130
+ ...tpl,
2131
+ ...patch
2132
+ }
2133
+ : tpl
2134
+ : null;
2135
+ }
2136
+
2137
+ export function setSchemaTpl(name: string, value: any) {
2138
+ tpls[name] = value;
2139
+ }
2140
+
2141
+ export function valuePipeOut(value: any) {
2142
+ try {
2143
+ if (value === 'undefined') {
2144
+ return undefined;
2145
+ }
2146
+
2147
+ return JSON.parse(value);
2148
+ } catch (e) {
2149
+ return value;
2150
+ }
2151
+ }
2152
+
2153
+ export function defaultValue(defaultValue: any, strictMode: boolean = true) {
2154
+ return strictMode
2155
+ ? (value: any) => (typeof value === 'undefined' ? defaultValue : value)
2156
+ : (value: any) => value || defaultValue;
2157
+ }