Commit f45224f2249e8634df9148f04656ce29aba57b91

Authored by YunaiV
1 parent 863ab6f3

1. 清理旧版本的 form generator

2. 接入表单详情
yudao-admin-ui/src/utils/generator/README.md deleted
1   -【add by 芋道源码】来自 https://github.com/JakHuang/form-generator/tree/dev/src/components/generator 目录
2 0 \ No newline at end of file
yudao-admin-ui/src/utils/generator/config.js deleted
1   -// 表单属性【右面板】
2   -export const formConf = {
3   - formRef: 'elForm',
4   - formModel: 'formData',
5   - size: 'medium',
6   - labelPosition: 'right',
7   - labelWidth: 100,
8   - formRules: 'rules',
9   - gutter: 15,
10   - disabled: false,
11   - span: 24,
12   - formBtns: true
13   -}
14   -
15   -// 输入型组件 【左面板】
16   -export const inputComponents = [
17   - {
18   - // 组件的自定义配置
19   - __config__: {
20   - label: '单行文本',
21   - labelWidth: null,
22   - showLabel: true,
23   - changeTag: true,
24   - tag: 'el-input',
25   - tagIcon: 'input',
26   - defaultValue: undefined,
27   - required: true,
28   - layout: 'colFormItem',
29   - span: 24,
30   - document: 'https://element.eleme.cn/#/zh-CN/component/input',
31   - // 正则校验规则
32   - regList: []
33   - },
34   - // 组件的插槽属性
35   - __slot__: {
36   - prepend: '',
37   - append: ''
38   - },
39   - // 其余的为可直接写在组件标签上的属性
40   - placeholder: '请输入',
41   - style: {width: '100%'},
42   - clearable: true,
43   - 'prefix-icon': '',
44   - 'suffix-icon': '',
45   - maxlength: null,
46   - 'show-word-limit': false,
47   - readonly: false,
48   - disabled: false
49   - },
50   - {
51   - __config__: {
52   - label: '多行文本',
53   - labelWidth: null,
54   - showLabel: true,
55   - tag: 'el-input',
56   - tagIcon: 'textarea',
57   - defaultValue: undefined,
58   - required: true,
59   - layout: 'colFormItem',
60   - span: 24,
61   - regList: [],
62   - changeTag: true,
63   - document: 'https://element.eleme.cn/#/zh-CN/component/input'
64   - },
65   - type: 'textarea',
66   - placeholder: '请输入',
67   - autosize: {
68   - minRows: 4,
69   - maxRows: 4
70   - },
71   - style: {width: '100%'},
72   - maxlength: null,
73   - 'show-word-limit': false,
74   - readonly: false,
75   - disabled: false
76   - },
77   - {
78   - __config__: {
79   - label: '密码',
80   - showLabel: true,
81   - labelWidth: null,
82   - changeTag: true,
83   - tag: 'el-input',
84   - tagIcon: 'password',
85   - defaultValue: undefined,
86   - layout: 'colFormItem',
87   - span: 24,
88   - required: true,
89   - regList: [],
90   - document: 'https://element.eleme.cn/#/zh-CN/component/input'
91   - },
92   - __slot__: {
93   - prepend: '',
94   - append: ''
95   - },
96   - placeholder: '请输入',
97   - 'show-password': true,
98   - style: {width: '100%'},
99   - clearable: true,
100   - 'prefix-icon': '',
101   - 'suffix-icon': '',
102   - maxlength: null,
103   - 'show-word-limit': false,
104   - readonly: false,
105   - disabled: false
106   - },
107   - {
108   - __config__: {
109   - label: '计数器',
110   - showLabel: true,
111   - changeTag: true,
112   - labelWidth: null,
113   - tag: 'el-input-number',
114   - tagIcon: 'number',
115   - defaultValue: undefined,
116   - span: 24,
117   - layout: 'colFormItem',
118   - required: true,
119   - regList: [],
120   - document: 'https://element.eleme.cn/#/zh-CN/component/input-number'
121   - },
122   - placeholder: '',
123   - min: undefined,
124   - max: undefined,
125   - step: 1,
126   - 'step-strictly': false,
127   - precision: undefined,
128   - 'controls-position': '',
129   - disabled: false
130   - },
131   - {
132   - __config__: {
133   - label: '编辑器',
134   - showLabel: true,
135   - changeTag: true,
136   - labelWidth: null,
137   - tag: 'tinymce',
138   - tagIcon: 'rich-text',
139   - defaultValue: null,
140   - span: 24,
141   - layout: 'colFormItem',
142   - required: true,
143   - regList: [],
144   - document: 'http://tinymce.ax-z.cn'
145   - },
146   - placeholder: '请输入',
147   - height: 300, // 编辑器高度
148   - branding: false // 隐藏右下角品牌烙印
149   - }
150   -]
151   -
152   -// 选择型组件 【左面板】
153   -export const selectComponents = [
154   - {
155   - __config__: {
156   - label: '下拉选择',
157   - showLabel: true,
158   - labelWidth: null,
159   - tag: 'el-select',
160   - tagIcon: 'select',
161   - layout: 'colFormItem',
162   - span: 24,
163   - required: true,
164   - regList: [],
165   - changeTag: true,
166   - document: 'https://element.eleme.cn/#/zh-CN/component/select'
167   - },
168   - __slot__: {
169   - options: [{
170   - label: '选项一',
171   - value: 1
172   - }, {
173   - label: '选项二',
174   - value: 2
175   - }]
176   - },
177   - placeholder: '请选择',
178   - style: {width: '100%'},
179   - clearable: true,
180   - disabled: false,
181   - filterable: false,
182   - multiple: false
183   - },
184   - {
185   - __config__: {
186   - label: '级联选择',
187   - url: 'https://www.fastmock.site/mock/f8d7a54fb1e60561e2f720d5a810009d/fg/cascaderList',
188   - method: 'get',
189   - dataPath: 'list',
190   - dataConsumer: 'options',
191   - showLabel: true,
192   - labelWidth: null,
193   - tag: 'el-cascader',
194   - tagIcon: 'cascader',
195   - layout: 'colFormItem',
196   - defaultValue: [],
197   - dataType: 'dynamic',
198   - span: 24,
199   - required: true,
200   - regList: [],
201   - changeTag: true,
202   - document: 'https://element.eleme.cn/#/zh-CN/component/cascader'
203   - },
204   - options: [{
205   - id: 1,
206   - value: 1,
207   - label: '选项1',
208   - children: [{
209   - id: 2,
210   - value: 2,
211   - label: '选项1-1'
212   - }]
213   - }],
214   - placeholder: '请选择',
215   - style: {width: '100%'},
216   - props: {
217   - props: {
218   - multiple: false,
219   - label: 'label',
220   - value: 'value',
221   - children: 'children'
222   - }
223   - },
224   - 'show-all-levels': true,
225   - disabled: false,
226   - clearable: true,
227   - filterable: false,
228   - separator: '/'
229   - },
230   - {
231   - __config__: {
232   - label: '单选框组',
233   - labelWidth: null,
234   - showLabel: true,
235   - tag: 'el-radio-group',
236   - tagIcon: 'radio',
237   - changeTag: true,
238   - defaultValue: undefined,
239   - layout: 'colFormItem',
240   - span: 24,
241   - optionType: 'default',
242   - regList: [],
243   - required: true,
244   - border: false,
245   - document: 'https://element.eleme.cn/#/zh-CN/component/radio'
246   - },
247   - __slot__: {
248   - options: [{
249   - label: '选项一',
250   - value: 1
251   - }, {
252   - label: '选项二',
253   - value: 2
254   - }]
255   - },
256   - style: {},
257   - size: 'medium',
258   - disabled: false
259   - },
260   - {
261   - __config__: {
262   - label: '多选框组',
263   - tag: 'el-checkbox-group',
264   - tagIcon: 'checkbox',
265   - defaultValue: [],
266   - span: 24,
267   - showLabel: true,
268   - labelWidth: null,
269   - layout: 'colFormItem',
270   - optionType: 'default',
271   - required: true,
272   - regList: [],
273   - changeTag: true,
274   - border: false,
275   - document: 'https://element.eleme.cn/#/zh-CN/component/checkbox'
276   - },
277   - __slot__: {
278   - options: [{
279   - label: '选项一',
280   - value: 1
281   - }, {
282   - label: '选项二',
283   - value: 2
284   - }]
285   - },
286   - style: {},
287   - size: 'medium',
288   - min: null,
289   - max: null,
290   - disabled: false
291   - },
292   - {
293   - __config__: {
294   - label: '开关',
295   - tag: 'el-switch',
296   - tagIcon: 'switch',
297   - defaultValue: false,
298   - span: 24,
299   - showLabel: true,
300   - labelWidth: null,
301   - layout: 'colFormItem',
302   - required: true,
303   - regList: [],
304   - changeTag: true,
305   - document: 'https://element.eleme.cn/#/zh-CN/component/switch'
306   - },
307   - style: {},
308   - disabled: false,
309   - 'active-text': '',
310   - 'inactive-text': '',
311   - 'active-color': null,
312   - 'inactive-color': null,
313   - 'active-value': true,
314   - 'inactive-value': false
315   - },
316   - {
317   - __config__: {
318   - label: '滑块',
319   - tag: 'el-slider',
320   - tagIcon: 'slider',
321   - defaultValue: null,
322   - span: 24,
323   - showLabel: true,
324   - layout: 'colFormItem',
325   - labelWidth: null,
326   - required: true,
327   - regList: [],
328   - changeTag: true,
329   - document: 'https://element.eleme.cn/#/zh-CN/component/slider'
330   - },
331   - disabled: false,
332   - min: 0,
333   - max: 100,
334   - step: 1,
335   - 'show-stops': false,
336   - range: false
337   - },
338   - {
339   - __config__: {
340   - label: '时间选择',
341   - tag: 'el-time-picker',
342   - tagIcon: 'time',
343   - defaultValue: null,
344   - span: 24,
345   - showLabel: true,
346   - layout: 'colFormItem',
347   - labelWidth: null,
348   - required: true,
349   - regList: [],
350   - changeTag: true,
351   - document: 'https://element.eleme.cn/#/zh-CN/component/time-picker'
352   - },
353   - placeholder: '请选择',
354   - style: {width: '100%'},
355   - disabled: false,
356   - clearable: true,
357   - 'picker-options': {
358   - selectableRange: '00:00:00-23:59:59'
359   - },
360   - format: 'HH:mm:ss',
361   - 'value-format': 'HH:mm:ss'
362   - },
363   - {
364   - __config__: {
365   - label: '时间范围',
366   - tag: 'el-time-picker',
367   - tagIcon: 'time-range',
368   - span: 24,
369   - showLabel: true,
370   - labelWidth: null,
371   - layout: 'colFormItem',
372   - defaultValue: null,
373   - required: true,
374   - regList: [],
375   - changeTag: true,
376   - document: 'https://element.eleme.cn/#/zh-CN/component/time-picker'
377   - },
378   - style: {width: '100%'},
379   - disabled: false,
380   - clearable: true,
381   - 'is-range': true,
382   - 'range-separator': '至',
383   - 'start-placeholder': '开始时间',
384   - 'end-placeholder': '结束时间',
385   - format: 'HH:mm:ss',
386   - 'value-format': 'HH:mm:ss'
387   - },
388   - {
389   - __config__: {
390   - label: '日期选择',
391   - tag: 'el-date-picker',
392   - tagIcon: 'date',
393   - defaultValue: null,
394   - showLabel: true,
395   - labelWidth: null,
396   - span: 24,
397   - layout: 'colFormItem',
398   - required: true,
399   - regList: [],
400   - changeTag: true,
401   - document: 'https://element.eleme.cn/#/zh-CN/component/date-picker'
402   - },
403   - placeholder: '请选择',
404   - type: 'date',
405   - style: {width: '100%'},
406   - disabled: false,
407   - clearable: true,
408   - format: 'yyyy-MM-dd',
409   - 'value-format': 'yyyy-MM-dd',
410   - readonly: false
411   - },
412   - {
413   - __config__: {
414   - label: '日期范围',
415   - tag: 'el-date-picker',
416   - tagIcon: 'date-range',
417   - defaultValue: null,
418   - span: 24,
419   - showLabel: true,
420   - labelWidth: null,
421   - required: true,
422   - layout: 'colFormItem',
423   - regList: [],
424   - changeTag: true,
425   - document: 'https://element.eleme.cn/#/zh-CN/component/date-picker'
426   - },
427   - style: {width: '100%'},
428   - type: 'daterange',
429   - 'range-separator': '至',
430   - 'start-placeholder': '开始日期',
431   - 'end-placeholder': '结束日期',
432   - disabled: false,
433   - clearable: true,
434   - format: 'yyyy-MM-dd',
435   - 'value-format': 'yyyy-MM-dd',
436   - readonly: false
437   - },
438   - {
439   - __config__: {
440   - label: '评分',
441   - tag: 'el-rate',
442   - tagIcon: 'rate',
443   - defaultValue: 0,
444   - span: 24,
445   - showLabel: true,
446   - labelWidth: null,
447   - layout: 'colFormItem',
448   - required: true,
449   - regList: [],
450   - changeTag: true,
451   - document: 'https://element.eleme.cn/#/zh-CN/component/rate'
452   - },
453   - style: {},
454   - max: 5,
455   - 'allow-half': false,
456   - 'show-text': false,
457   - 'show-score': false,
458   - disabled: false
459   - },
460   - {
461   - __config__: {
462   - label: '颜色选择',
463   - tag: 'el-color-picker',
464   - tagIcon: 'color',
465   - span: 24,
466   - defaultValue: null,
467   - showLabel: true,
468   - labelWidth: null,
469   - layout: 'colFormItem',
470   - required: true,
471   - regList: [],
472   - changeTag: true,
473   - document: 'https://element.eleme.cn/#/zh-CN/component/color-picker'
474   - },
475   - 'show-alpha': false,
476   - 'color-format': '',
477   - disabled: false,
478   - size: 'medium'
479   - },
480   - {
481   - __config__: {
482   - label: '上传',
483   - tag: 'el-upload',
484   - tagIcon: 'upload',
485   - layout: 'colFormItem',
486   - defaultValue: null,
487   - showLabel: true,
488   - labelWidth: null,
489   - required: true,
490   - span: 24,
491   - showTip: false,
492   - buttonText: '点击上传',
493   - regList: [],
494   - changeTag: true,
495   - fileSize: 2,
496   - sizeUnit: 'MB',
497   - document: 'https://element.eleme.cn/#/zh-CN/component/upload'
498   - },
499   - __slot__: {
500   - 'list-type': true
501   - },
502   - action: 'https://jsonplaceholder.typicode.com/posts/',
503   - disabled: false,
504   - accept: '',
505   - name: 'file',
506   - 'auto-upload': true,
507   - 'list-type': 'text',
508   - multiple: false
509   - }
510   -]
511   -
512   -// 布局型组件 【左面板】
513   -export const layoutComponents = [
514   - {
515   - __config__: {
516   - layout: 'rowFormItem',
517   - tagIcon: 'row',
518   - label: '行容器',
519   - layoutTree: true,
520   - document: 'https://element.eleme.cn/#/zh-CN/component/layout#row-attributes'
521   - },
522   - type: 'default',
523   - justify: 'start',
524   - align: 'top'
525   - },
526   - {
527   - __config__: {
528   - label: '按钮',
529   - showLabel: true,
530   - changeTag: true,
531   - labelWidth: null,
532   - tag: 'el-button',
533   - tagIcon: 'button',
534   - span: 24,
535   - layout: 'colFormItem',
536   - document: 'https://element.eleme.cn/#/zh-CN/component/button'
537   - },
538   - __slot__: {
539   - default: '主要按钮'
540   - },
541   - type: 'primary',
542   - icon: 'el-icon-search',
543   - round: false,
544   - size: 'medium',
545   - plain: false,
546   - circle: false,
547   - disabled: false
548   - },
549   - {
550   - __config__: {
551   - layout: 'colFormItem',
552   - tagIcon: 'table',
553   - tag: 'el-table',
554   - document: 'https://element.eleme.cn/#/zh-CN/component/table',
555   - span: 24,
556   - formId: 101,
557   - renderKey: 1595761764203,
558   - componentName: 'row101',
559   - showLabel: true,
560   - changeTag: true,
561   - labelWidth: null,
562   - label: '表格[开发中]',
563   - dataType: 'dynamic',
564   - method: 'get',
565   - dataPath: 'list',
566   - dataConsumer: 'data',
567   - url: 'https://www.fastmock.site/mock/f8d7a54fb1e60561e2f720d5a810009d/fg/tableData',
568   - children: [{
569   - __config__: {
570   - layout: 'raw',
571   - tag: 'el-table-column',
572   - renderKey: 15957617660153
573   - },
574   - prop: 'date',
575   - label: '日期'
576   - }, {
577   - __config__: {
578   - layout: 'raw',
579   - tag: 'el-table-column',
580   - renderKey: 15957617660152
581   - },
582   - prop: 'address',
583   - label: '地址'
584   - }, {
585   - __config__: {
586   - layout: 'raw',
587   - tag: 'el-table-column',
588   - renderKey: 15957617660151
589   - },
590   - prop: 'name',
591   - label: '名称'
592   - }, {
593   - __config__: {
594   - layout: 'raw',
595   - tag: 'el-table-column',
596   - renderKey: 1595774496335,
597   - children: [
598   - {
599   - __config__: {
600   - label: '按钮',
601   - tag: 'el-button',
602   - tagIcon: 'button',
603   - layout: 'raw',
604   - renderKey: 1595779809901
605   - },
606   - __slot__: {
607   - default: '主要按钮'
608   - },
609   - type: 'primary',
610   - icon: 'el-icon-search',
611   - round: false,
612   - size: 'medium'
613   - }
614   - ]
615   - },
616   - label: '操作'
617   - }]
618   - },
619   - data: [],
620   - directives: [{
621   - name: 'loading',
622   - value: true
623   - }],
624   - border: true,
625   - type: 'default',
626   - justify: 'start',
627   - align: 'top'
628   - }
629   -]
yudao-admin-ui/src/utils/generator/css.js deleted
1   -const styles = {
2   - 'el-rate': '.el-rate{display: inline-block; vertical-align: text-top;}',
3   - 'el-upload': '.el-upload__tip{line-height: 1.2;}'
4   -}
5   -
6   -function addCss(cssList, el) {
7   - const css = styles[el.tag]
8   - css && cssList.indexOf(css) === -1 && cssList.push(css)
9   - if (el.children) {
10   - el.children.forEach(el2 => addCss(cssList, el2))
11   - }
12   -}
13   -
14   -export function makeUpCss(conf) {
15   - const cssList = []
16   - conf.fields.forEach(el => addCss(cssList, el))
17   - return cssList.join('\n')
18   -}
yudao-admin-ui/src/utils/generator/drawingDefalut.js deleted
1   -export default [
2   - {
3   - __config__: {
4   - label: '单行文本',
5   - labelWidth: null,
6   - showLabel: true,
7   - changeTag: true,
8   - tag: 'el-input',
9   - tagIcon: 'input',
10   - defaultValue: undefined,
11   - required: true,
12   - layout: 'colFormItem',
13   - span: 24,
14   - document: 'https://element.eleme.cn/#/zh-CN/component/input',
15   - // 正则校验规则
16   - regList: [{
17   - pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
18   - message: '手机号格式错误'
19   - }]
20   - },
21   - // 组件的插槽属性
22   - __slot__: {
23   - prepend: '',
24   - append: ''
25   - },
26   - __vModel__: 'mobile',
27   - placeholder: '请输入手机号',
28   - style: { width: '100%' },
29   - clearable: true,
30   - 'prefix-icon': 'el-icon-mobile',
31   - 'suffix-icon': '',
32   - maxlength: 11,
33   - 'show-word-limit': true,
34   - readonly: false,
35   - disabled: false
36   - }
37   -]
yudao-admin-ui/src/utils/generator/html.js deleted
1   -/* eslint-disable max-len */
2   -import ruleTrigger from './ruleTrigger'
3   -
4   -let confGlobal
5   -let someSpanIsNot24
6   -
7   -export function dialogWrapper(str) {
8   - return `<el-dialog v-bind="$attrs" v-on="$listeners" @open="onOpen" @close="onClose" title="Dialog Titile">
9   - ${str}
10   - <div slot="footer">
11   - <el-button @click="close">取消</el-button>
12   - <el-button type="primary" @click="handelConfirm">确定</el-button>
13   - </div>
14   - </el-dialog>`
15   -}
16   -
17   -export function vueTemplate(str) {
18   - return `<template>
19   - <div>
20   - ${str}
21   - </div>
22   - </template>`
23   -}
24   -
25   -export function vueScript(str) {
26   - return `<script>
27   - ${str}
28   - </script>`
29   -}
30   -
31   -export function cssStyle(cssStr) {
32   - return `<style>
33   - ${cssStr}
34   - </style>`
35   -}
36   -
37   -function buildFormTemplate(scheme, child, type) {
38   - let labelPosition = ''
39   - if (scheme.labelPosition !== 'right') {
40   - labelPosition = `label-position="${scheme.labelPosition}"`
41   - }
42   - const disabled = scheme.disabled ? `:disabled="${scheme.disabled}"` : ''
43   - let str = `<el-form ref="${scheme.formRef}" :model="${scheme.formModel}" :rules="${scheme.formRules}" size="${scheme.size}" ${disabled} label-width="${scheme.labelWidth}px" ${labelPosition}>
44   - ${child}
45   - ${buildFromBtns(scheme, type)}
46   - </el-form>`
47   - if (someSpanIsNot24) {
48   - str = `<el-row :gutter="${scheme.gutter}">
49   - ${str}
50   - </el-row>`
51   - }
52   - return str
53   -}
54   -
55   -function buildFromBtns(scheme, type) {
56   - let str = ''
57   - if (scheme.formBtns && type === 'file') {
58   - str = `<el-form-item size="large">
59   - <el-button type="primary" @click="submitForm">提交</el-button>
60   - <el-button @click="resetForm">重置</el-button>
61   - </el-form-item>`
62   - if (someSpanIsNot24) {
63   - str = `<el-col :span="24">
64   - ${str}
65   - </el-col>`
66   - }
67   - }
68   - return str
69   -}
70   -
71   -// span不为24的用el-col包裹
72   -function colWrapper(scheme, str) {
73   - if (someSpanIsNot24 || scheme.__config__.span !== 24) {
74   - return `<el-col :span="${scheme.__config__.span}">
75   - ${str}
76   - </el-col>`
77   - }
78   - return str
79   -}
80   -
81   -const layouts = {
82   - colFormItem(scheme) {
83   - const config = scheme.__config__
84   - let labelWidth = ''
85   - let label = `label="${config.label}"`
86   - if (config.labelWidth && config.labelWidth !== confGlobal.labelWidth) {
87   - labelWidth = `label-width="${config.labelWidth}px"`
88   - }
89   - if (config.showLabel === false) {
90   - labelWidth = 'label-width="0"'
91   - label = ''
92   - }
93   - const required = !ruleTrigger[config.tag] && config.required ? 'required' : ''
94   - const tagDom = tags[config.tag] ? tags[config.tag](scheme) : null
95   - let str = `<el-form-item ${labelWidth} ${label} prop="${scheme.__vModel__}" ${required}>
96   - ${tagDom}
97   - </el-form-item>`
98   - str = colWrapper(scheme, str)
99   - return str
100   - },
101   - rowFormItem(scheme) {
102   - const config = scheme.__config__
103   - const type = scheme.type === 'default' ? '' : `type="${scheme.type}"`
104   - const justify = scheme.type === 'default' ? '' : `justify="${scheme.justify}"`
105   - const align = scheme.type === 'default' ? '' : `align="${scheme.align}"`
106   - const gutter = scheme.gutter ? `:gutter="${scheme.gutter}"` : ''
107   - const children = config.children.map(el => layouts[el.__config__.layout](el))
108   - let str = `<el-row ${type} ${justify} ${align} ${gutter}>
109   - ${children.join('\n')}
110   - </el-row>`
111   - str = colWrapper(scheme, str)
112   - return str
113   - }
114   -}
115   -
116   -const tags = {
117   - 'el-button': el => {
118   - const {
119   - tag, disabled
120   - } = attrBuilder(el)
121   - const type = el.type ? `type="${el.type}"` : ''
122   - const icon = el.icon ? `icon="${el.icon}"` : ''
123   - const round = el.round ? 'round' : ''
124   - const size = el.size ? `size="${el.size}"` : ''
125   - const plain = el.plain ? 'plain' : ''
126   - const circle = el.circle ? 'circle' : ''
127   - let child = buildElButtonChild(el)
128   -
129   - if (child) child = `\n${child}\n` // 换行
130   - return `<${tag} ${type} ${icon} ${round} ${size} ${plain} ${disabled} ${circle}>${child}</${tag}>`
131   - },
132   - 'el-input': el => {
133   - const {
134   - tag, disabled, vModel, clearable, placeholder, width
135   - } = attrBuilder(el)
136   - const maxlength = el.maxlength ? `:maxlength="${el.maxlength}"` : ''
137   - const showWordLimit = el['show-word-limit'] ? 'show-word-limit' : ''
138   - const readonly = el.readonly ? 'readonly' : ''
139   - const prefixIcon = el['prefix-icon'] ? `prefix-icon='${el['prefix-icon']}'` : ''
140   - const suffixIcon = el['suffix-icon'] ? `suffix-icon='${el['suffix-icon']}'` : ''
141   - const showPassword = el['show-password'] ? 'show-password' : ''
142   - const type = el.type ? `type="${el.type}"` : ''
143   - const autosize = el.autosize && el.autosize.minRows
144   - ? `:autosize="{minRows: ${el.autosize.minRows}, maxRows: ${el.autosize.maxRows}}"`
145   - : ''
146   - let child = buildElInputChild(el)
147   -
148   - if (child) child = `\n${child}\n` // 换行
149   - return `<${tag} ${vModel} ${type} ${placeholder} ${maxlength} ${showWordLimit} ${readonly} ${disabled} ${clearable} ${prefixIcon} ${suffixIcon} ${showPassword} ${autosize} ${width}>${child}</${tag}>`
150   - },
151   - 'el-input-number': el => {
152   - const {
153   - tag, disabled, vModel, placeholder
154   - } = attrBuilder(el)
155   - const controlsPosition = el['controls-position'] ? `controls-position=${el['controls-position']}` : ''
156   - const min = el.min ? `:min='${el.min}'` : ''
157   - const max = el.max ? `:max='${el.max}'` : ''
158   - const step = el.step ? `:step='${el.step}'` : ''
159   - const stepStrictly = el['step-strictly'] ? 'step-strictly' : ''
160   - const precision = el.precision ? `:precision='${el.precision}'` : ''
161   -
162   - return `<${tag} ${vModel} ${placeholder} ${step} ${stepStrictly} ${precision} ${controlsPosition} ${min} ${max} ${disabled}></${tag}>`
163   - },
164   - 'el-select': el => {
165   - const {
166   - tag, disabled, vModel, clearable, placeholder, width
167   - } = attrBuilder(el)
168   - const filterable = el.filterable ? 'filterable' : ''
169   - const multiple = el.multiple ? 'multiple' : ''
170   - let child = buildElSelectChild(el)
171   -
172   - if (child) child = `\n${child}\n` // 换行
173   - return `<${tag} ${vModel} ${placeholder} ${disabled} ${multiple} ${filterable} ${clearable} ${width}>${child}</${tag}>`
174   - },
175   - 'el-radio-group': el => {
176   - const { tag, disabled, vModel } = attrBuilder(el)
177   - const size = `size="${el.size}"`
178   - let child = buildElRadioGroupChild(el)
179   -
180   - if (child) child = `\n${child}\n` // 换行
181   - return `<${tag} ${vModel} ${size} ${disabled}>${child}</${tag}>`
182   - },
183   - 'el-checkbox-group': el => {
184   - const { tag, disabled, vModel } = attrBuilder(el)
185   - const size = `size="${el.size}"`
186   - const min = el.min ? `:min="${el.min}"` : ''
187   - const max = el.max ? `:max="${el.max}"` : ''
188   - let child = buildElCheckboxGroupChild(el)
189   -
190   - if (child) child = `\n${child}\n` // 换行
191   - return `<${tag} ${vModel} ${min} ${max} ${size} ${disabled}>${child}</${tag}>`
192   - },
193   - 'el-switch': el => {
194   - const { tag, disabled, vModel } = attrBuilder(el)
195   - const activeText = el['active-text'] ? `active-text="${el['active-text']}"` : ''
196   - const inactiveText = el['inactive-text'] ? `inactive-text="${el['inactive-text']}"` : ''
197   - const activeColor = el['active-color'] ? `active-color="${el['active-color']}"` : ''
198   - const inactiveColor = el['inactive-color'] ? `inactive-color="${el['inactive-color']}"` : ''
199   - const activeValue = el['active-value'] !== true ? `:active-value='${JSON.stringify(el['active-value'])}'` : ''
200   - const inactiveValue = el['inactive-value'] !== false ? `:inactive-value='${JSON.stringify(el['inactive-value'])}'` : ''
201   -
202   - return `<${tag} ${vModel} ${activeText} ${inactiveText} ${activeColor} ${inactiveColor} ${activeValue} ${inactiveValue} ${disabled}></${tag}>`
203   - },
204   - 'el-cascader': el => {
205   - const {
206   - tag, disabled, vModel, clearable, placeholder, width
207   - } = attrBuilder(el)
208   - const options = el.options ? `:options="${el.__vModel__}Options"` : ''
209   - const props = el.props ? `:props="${el.__vModel__}Props"` : ''
210   - const showAllLevels = el['show-all-levels'] ? '' : ':show-all-levels="false"'
211   - const filterable = el.filterable ? 'filterable' : ''
212   - const separator = el.separator === '/' ? '' : `separator="${el.separator}"`
213   -
214   - return `<${tag} ${vModel} ${options} ${props} ${width} ${showAllLevels} ${placeholder} ${separator} ${filterable} ${clearable} ${disabled}></${tag}>`
215   - },
216   - 'el-slider': el => {
217   - const { tag, disabled, vModel } = attrBuilder(el)
218   - const min = el.min ? `:min='${el.min}'` : ''
219   - const max = el.max ? `:max='${el.max}'` : ''
220   - const step = el.step ? `:step='${el.step}'` : ''
221   - const range = el.range ? 'range' : ''
222   - const showStops = el['show-stops'] ? `:show-stops="${el['show-stops']}"` : ''
223   -
224   - return `<${tag} ${min} ${max} ${step} ${vModel} ${range} ${showStops} ${disabled}></${tag}>`
225   - },
226   - 'el-time-picker': el => {
227   - const {
228   - tag, disabled, vModel, clearable, placeholder, width
229   - } = attrBuilder(el)
230   - const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : ''
231   - const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : ''
232   - const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : ''
233   - const isRange = el['is-range'] ? 'is-range' : ''
234   - const format = el.format ? `format="${el.format}"` : ''
235   - const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : ''
236   - const pickerOptions = el['picker-options'] ? `:picker-options='${JSON.stringify(el['picker-options'])}'` : ''
237   -
238   - return `<${tag} ${vModel} ${isRange} ${format} ${valueFormat} ${pickerOptions} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${disabled}></${tag}>`
239   - },
240   - 'el-date-picker': el => {
241   - const {
242   - tag, disabled, vModel, clearable, placeholder, width
243   - } = attrBuilder(el)
244   - const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : ''
245   - const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : ''
246   - const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : ''
247   - const format = el.format ? `format="${el.format}"` : ''
248   - const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : ''
249   - const type = el.type === 'date' ? '' : `type="${el.type}"`
250   - const readonly = el.readonly ? 'readonly' : ''
251   -
252   - return `<${tag} ${type} ${vModel} ${format} ${valueFormat} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${readonly} ${disabled}></${tag}>`
253   - },
254   - 'el-rate': el => {
255   - const { tag, disabled, vModel } = attrBuilder(el)
256   - const max = el.max ? `:max='${el.max}'` : ''
257   - const allowHalf = el['allow-half'] ? 'allow-half' : ''
258   - const showText = el['show-text'] ? 'show-text' : ''
259   - const showScore = el['show-score'] ? 'show-score' : ''
260   -
261   - return `<${tag} ${vModel} ${max} ${allowHalf} ${showText} ${showScore} ${disabled}></${tag}>`
262   - },
263   - 'el-color-picker': el => {
264   - const { tag, disabled, vModel } = attrBuilder(el)
265   - const size = `size="${el.size}"`
266   - const showAlpha = el['show-alpha'] ? 'show-alpha' : ''
267   - const colorFormat = el['color-format'] ? `color-format="${el['color-format']}"` : ''
268   -
269   - return `<${tag} ${vModel} ${size} ${showAlpha} ${colorFormat} ${disabled}></${tag}>`
270   - },
271   - 'el-upload': el => {
272   - const { tag } = el.__config__
273   - const disabled = el.disabled ? ':disabled=\'true\'' : ''
274   - const action = el.action ? `:action="${el.__vModel__}Action"` : ''
275   - const multiple = el.multiple ? 'multiple' : ''
276   - const listType = el['list-type'] !== 'text' ? `list-type="${el['list-type']}"` : ''
277   - const accept = el.accept ? `accept="${el.accept}"` : ''
278   - const name = el.name !== 'file' ? `name="${el.name}"` : ''
279   - const autoUpload = el['auto-upload'] === false ? ':auto-upload="false"' : ''
280   - const beforeUpload = `:before-upload="${el.__vModel__}BeforeUpload"`
281   - const fileList = `:file-list="${el.__vModel__}fileList"`
282   - const ref = `ref="${el.__vModel__}"`
283   - let child = buildElUploadChild(el)
284   -
285   - if (child) child = `\n${child}\n` // 换行
286   - return `<${tag} ${ref} ${fileList} ${action} ${autoUpload} ${multiple} ${beforeUpload} ${listType} ${accept} ${name} ${disabled}>${child}</${tag}>`
287   - },
288   - tinymce: el => {
289   - const { tag, vModel, placeholder } = attrBuilder(el)
290   - const height = el.height ? `:height="${el.height}"` : ''
291   - const branding = el.branding ? `:branding="${el.branding}"` : ''
292   - return `<${tag} ${vModel} ${placeholder} ${height} ${branding}></${tag}>`
293   - }
294   -}
295   -
296   -function attrBuilder(el) {
297   - return {
298   - tag: el.__config__.tag,
299   - vModel: `v-model="${confGlobal.formModel}.${el.__vModel__}"`,
300   - clearable: el.clearable ? 'clearable' : '',
301   - placeholder: el.placeholder ? `placeholder="${el.placeholder}"` : '',
302   - width: el.style && el.style.width ? ':style="{width: \'100%\'}"' : '',
303   - disabled: el.disabled ? ':disabled=\'true\'' : ''
304   - }
305   -}
306   -
307   -// el-buttin 子级
308   -function buildElButtonChild(scheme) {
309   - const children = []
310   - const slot = scheme.__slot__ || {}
311   - if (slot.default) {
312   - children.push(slot.default)
313   - }
314   - return children.join('\n')
315   -}
316   -
317   -// el-input 子级
318   -function buildElInputChild(scheme) {
319   - const children = []
320   - const slot = scheme.__slot__
321   - if (slot && slot.prepend) {
322   - children.push(`<template slot="prepend">${slot.prepend}</template>`)
323   - }
324   - if (slot && slot.append) {
325   - children.push(`<template slot="append">${slot.append}</template>`)
326   - }
327   - return children.join('\n')
328   -}
329   -
330   -// el-select 子级
331   -function buildElSelectChild(scheme) {
332   - const children = []
333   - const slot = scheme.__slot__
334   - if (slot && slot.options && slot.options.length) {
335   - children.push(`<el-option v-for="(item, index) in ${scheme.__vModel__}Options" :key="index" :label="item.label" :value="item.value" :disabled="item.disabled"></el-option>`)
336   - }
337   - return children.join('\n')
338   -}
339   -
340   -// el-radio-group 子级
341   -function buildElRadioGroupChild(scheme) {
342   - const children = []
343   - const slot = scheme.__slot__
344   - const config = scheme.__config__
345   - if (slot && slot.options && slot.options.length) {
346   - const tag = config.optionType === 'button' ? 'el-radio-button' : 'el-radio'
347   - const border = config.border ? 'border' : ''
348   - children.push(`<${tag} v-for="(item, index) in ${scheme.__vModel__}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`)
349   - }
350   - return children.join('\n')
351   -}
352   -
353   -// el-checkbox-group 子级
354   -function buildElCheckboxGroupChild(scheme) {
355   - const children = []
356   - const slot = scheme.__slot__
357   - const config = scheme.__config__
358   - if (slot && slot.options && slot.options.length) {
359   - const tag = config.optionType === 'button' ? 'el-checkbox-button' : 'el-checkbox'
360   - const border = config.border ? 'border' : ''
361   - children.push(`<${tag} v-for="(item, index) in ${scheme.__vModel__}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`)
362   - }
363   - return children.join('\n')
364   -}
365   -
366   -// el-upload 子级
367   -function buildElUploadChild(scheme) {
368   - const list = []
369   - const config = scheme.__config__
370   - if (scheme['list-type'] === 'picture-card') list.push('<i class="el-icon-plus"></i>')
371   - else list.push(`<el-button size="small" type="primary" icon="el-icon-upload">${config.buttonText}</el-button>`)
372   - if (config.showTip) list.push(`<div slot="tip" class="el-upload__tip">只能上传不超过 ${config.fileSize}${config.sizeUnit} 的${scheme.accept}文件</div>`)
373   - return list.join('\n')
374   -}
375   -
376   -/**
377   - * 组装html代码。【入口函数】
378   - * @param {Object} formConfig 整个表单配置
379   - * @param {String} type 生成类型,文件或弹窗等
380   - */
381   -export function makeUpHtml(formConfig, type) {
382   - const htmlList = []
383   - confGlobal = formConfig
384   - // 判断布局是否都沾满了24个栅格,以备后续简化代码结构
385   - someSpanIsNot24 = formConfig.fields.some(item => item.__config__.span !== 24)
386   - // 遍历渲染每个组件成html
387   - formConfig.fields.forEach(el => {
388   - htmlList.push(layouts[el.__config__.layout](el))
389   - })
390   - const htmlStr = htmlList.join('\n')
391   - // 将组件代码放进form标签
392   - let temp = buildFormTemplate(formConfig, htmlStr, type)
393   - // dialog标签包裹代码
394   - if (type === 'dialog') {
395   - temp = dialogWrapper(temp)
396   - }
397   - confGlobal = null
398   - return temp
399   -}
yudao-admin-ui/src/utils/generator/js.js deleted
1   -import { isArray } from 'util'
2   -import { exportDefault, titleCase, deepClone } from '@/utils/index'
3   -import ruleTrigger from './ruleTrigger'
4   -
5   -const units = {
6   - KB: '1024',
7   - MB: '1024 / 1024',
8   - GB: '1024 / 1024 / 1024'
9   -}
10   -let confGlobal
11   -const inheritAttrs = {
12   - file: '',
13   - dialog: 'inheritAttrs: false,'
14   -}
15   -
16   -/**
17   - * 组装js 【入口函数】
18   - * @param {Object} formConfig 整个表单配置
19   - * @param {String} type 生成类型,文件或弹窗等
20   - */
21   -export function makeUpJs(formConfig, type) {
22   - confGlobal = formConfig = deepClone(formConfig)
23   - const dataList = []
24   - const ruleList = []
25   - const optionsList = []
26   - const propsList = []
27   - const methodList = mixinMethod(type)
28   - const uploadVarList = []
29   - const created = []
30   -
31   - formConfig.fields.forEach(el => {
32   - buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created)
33   - })
34   -
35   - const script = buildexport(
36   - formConfig,
37   - type,
38   - dataList.join('\n'),
39   - ruleList.join('\n'),
40   - optionsList.join('\n'),
41   - uploadVarList.join('\n'),
42   - propsList.join('\n'),
43   - methodList.join('\n'),
44   - created.join('\n')
45   - )
46   - confGlobal = null
47   - return script
48   -}
49   -
50   -// 构建组件属性
51   -function buildAttributes(scheme, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created) {
52   - const config = scheme.__config__
53   - const slot = scheme.__slot__
54   - buildData(scheme, dataList)
55   - buildRules(scheme, ruleList)
56   -
57   - // 特殊处理options属性
58   - if (scheme.options || (slot && slot.options && slot.options.length)) {
59   - buildOptions(scheme, optionsList)
60   - if (config.dataType === 'dynamic') {
61   - const model = `${scheme.__vModel__}Options`
62   - const options = titleCase(model)
63   - const methodName = `get${options}`
64   - buildOptionMethod(methodName, model, methodList, scheme)
65   - callInCreated(methodName, created)
66   - }
67   - }
68   -
69   - // 处理props
70   - if (scheme.props && scheme.props.props) {
71   - buildProps(scheme, propsList)
72   - }
73   -
74   - // 处理el-upload的action
75   - if (scheme.action && config.tag === 'el-upload') {
76   - uploadVarList.push(
77   - `${scheme.__vModel__}Action: '${scheme.action}',
78   - ${scheme.__vModel__}fileList: [],`
79   - )
80   - methodList.push(buildBeforeUpload(scheme))
81   - // 非自动上传时,生成手动上传的函数
82   - if (!scheme['auto-upload']) {
83   - methodList.push(buildSubmitUpload(scheme))
84   - }
85   - }
86   -
87   - // 构建子级组件属性
88   - if (config.children) {
89   - config.children.forEach(item => {
90   - buildAttributes(item, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created)
91   - })
92   - }
93   -}
94   -
95   -// 在Created调用函数
96   -function callInCreated(methodName, created) {
97   - created.push(`this.${methodName}()`)
98   -}
99   -
100   -// 混入处理函数
101   -function mixinMethod(type) {
102   - const list = []; const
103   - minxins = {
104   - file: confGlobal.formBtns ? {
105   - submitForm: `submitForm() {
106   - this.$refs['${confGlobal.formRef}'].validate(valid => {
107   - if(!valid) return
108   - // TODO 提交表单
109   - })
110   - },`,
111   - resetForm: `resetForm() {
112   - this.$refs['${confGlobal.formRef}'].resetFields()
113   - },`
114   - } : null,
115   - dialog: {
116   - onOpen: 'onOpen() {},',
117   - onClose: `onClose() {
118   - this.$refs['${confGlobal.formRef}'].resetFields()
119   - },`,
120   - close: `close() {
121   - this.$emit('update:visible', false)
122   - },`,
123   - handelConfirm: `handelConfirm() {
124   - this.$refs['${confGlobal.formRef}'].validate(valid => {
125   - if(!valid) return
126   - this.close()
127   - })
128   - },`
129   - }
130   - }
131   -
132   - const methods = minxins[type]
133   - if (methods) {
134   - Object.keys(methods).forEach(key => {
135   - list.push(methods[key])
136   - })
137   - }
138   -
139   - return list
140   -}
141   -
142   -// 构建data
143   -function buildData(scheme, dataList) {
144   - const config = scheme.__config__
145   - if (scheme.__vModel__ === undefined) return
146   - const defaultValue = JSON.stringify(config.defaultValue)
147   - dataList.push(`${scheme.__vModel__}: ${defaultValue},`)
148   -}
149   -
150   -// 构建校验规则
151   -function buildRules(scheme, ruleList) {
152   - const config = scheme.__config__
153   - if (scheme.__vModel__ === undefined) return
154   - const rules = []
155   - if (ruleTrigger[config.tag]) {
156   - if (config.required) {
157   - const type = isArray(config.defaultValue) ? 'type: \'array\',' : ''
158   - let message = isArray(config.defaultValue) ? `请至少选择一个${config.label}` : scheme.placeholder
159   - if (message === undefined) message = `${config.label}不能为空`
160   - rules.push(`{ required: true, ${type} message: '${message}', trigger: '${ruleTrigger[config.tag]}' }`)
161   - }
162   - if (config.regList && isArray(config.regList)) {
163   - config.regList.forEach(item => {
164   - if (item.pattern) {
165   - rules.push(
166   - `{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${ruleTrigger[config.tag]}' }`
167   - )
168   - }
169   - })
170   - }
171   - ruleList.push(`${scheme.__vModel__}: [${rules.join(',')}],`)
172   - }
173   -}
174   -
175   -// 构建options
176   -function buildOptions(scheme, optionsList) {
177   - if (scheme.__vModel__ === undefined) return
178   - // el-cascader直接有options属性,其他组件都是定义在slot中,所以有两处判断
179   - let { options } = scheme
180   - if (!options) options = scheme.__slot__.options
181   - if (scheme.__config__.dataType === 'dynamic') { options = [] }
182   - const str = `${scheme.__vModel__}Options: ${JSON.stringify(options)},`
183   - optionsList.push(str)
184   -}
185   -
186   -function buildProps(scheme, propsList) {
187   - const str = `${scheme.__vModel__}Props: ${JSON.stringify(scheme.props.props)},`
188   - propsList.push(str)
189   -}
190   -
191   -// el-upload的BeforeUpload
192   -function buildBeforeUpload(scheme) {
193   - const config = scheme.__config__
194   - const unitNum = units[config.sizeUnit]; let rightSizeCode = ''; let acceptCode = ''; const
195   - returnList = []
196   - if (config.fileSize) {
197   - rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${config.fileSize}
198   - if(!isRightSize){
199   - this.$message.error('文件大小超过 ${config.fileSize}${config.sizeUnit}')
200   - }`
201   - returnList.push('isRightSize')
202   - }
203   - if (scheme.accept) {
204   - acceptCode = `let isAccept = new RegExp('${scheme.accept}').test(file.type)
205   - if(!isAccept){
206   - this.$message.error('应该选择${scheme.accept}类型的文件')
207   - }`
208   - returnList.push('isAccept')
209   - }
210   - const str = `${scheme.__vModel__}BeforeUpload(file) {
211   - ${rightSizeCode}
212   - ${acceptCode}
213   - return ${returnList.join('&&')}
214   - },`
215   - return returnList.length ? str : ''
216   -}
217   -
218   -// el-upload的submit
219   -function buildSubmitUpload(scheme) {
220   - const str = `submitUpload() {
221   - this.$refs['${scheme.__vModel__}'].submit()
222   - },`
223   - return str
224   -}
225   -
226   -function buildOptionMethod(methodName, model, methodList, scheme) {
227   - const config = scheme.__config__
228   - const str = `${methodName}() {
229   - // 注意:this.$axios是通过Vue.prototype.$axios = axios挂载产生的
230   - this.$axios({
231   - method: '${config.method}',
232   - url: '${config.url}'
233   - }).then(resp => {
234   - var { data } = resp
235   - this.${model} = data.${config.dataPath}
236   - })
237   - },`
238   - methodList.push(str)
239   -}
240   -
241   -// js整体拼接
242   -function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods, created) {
243   - const str = `${exportDefault}{
244   - ${inheritAttrs[type]}
245   - components: {},
246   - props: [],
247   - data () {
248   - return {
249   - ${conf.formModel}: {
250   - ${data}
251   - },
252   - ${conf.formRules}: {
253   - ${rules}
254   - },
255   - ${uploadVar}
256   - ${selectOptions}
257   - ${props}
258   - }
259   - },
260   - computed: {},
261   - watch: {},
262   - created () {
263   - ${created}
264   - },
265   - mounted () {},
266   - methods: {
267   - ${methods}
268   - }
269   -}`
270   - return str
271   -}
yudao-admin-ui/src/utils/generator/render.js deleted
1   -import { makeMap } from '@/utils/index'
2   -
3   -// 参考https://github.com/vuejs/vue/blob/v2.6.10/src/platforms/web/server/util.js
4   -const isAttr = makeMap(
5   - 'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,'
6   - + 'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,'
7   - + 'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,'
8   - + 'name,contenteditable,contextmenu,controls,coords,data,datetime,default,'
9   - + 'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,'
10   - + 'form,formaction,headers,height,hidden,high,href,hreflang,http-equiv,'
11   - + 'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,'
12   - + 'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,'
13   - + 'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,'
14   - + 'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,'
15   - + 'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,'
16   - + 'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,'
17   - + 'target,title,type,usemap,value,width,wrap'
18   -)
19   -
20   -function vModel(self, dataObject, defaultValue) {
21   - dataObject.props.value = defaultValue
22   -
23   - dataObject.on.input = val => {
24   - self.$emit('input', val)
25   - }
26   -}
27   -
28   -const componentChild = {
29   - 'el-button': {
30   - default(h, conf, key) {
31   - return conf[key]
32   - },
33   - },
34   - 'el-input': {
35   - prepend(h, conf, key) {
36   - return <template slot="prepend">{conf[key]}</template>
37   - },
38   - append(h, conf, key) {
39   - return <template slot="append">{conf[key]}</template>
40   - }
41   - },
42   - 'el-select': {
43   - options(h, conf, key) {
44   - const list = []
45   - conf.options.forEach(item => {
46   - list.push(<el-option label={item.label} value={item.value} disabled={item.disabled}></el-option>)
47   - })
48   - return list
49   - }
50   - },
51   - 'el-radio-group': {
52   - options(h, conf, key) {
53   - const list = []
54   - conf.options.forEach(item => {
55   - if (conf.optionType === 'button') list.push(<el-radio-button label={item.value}>{item.label}</el-radio-button>)
56   - else list.push(<el-radio label={item.value} border={conf.border}>{item.label}</el-radio>)
57   - })
58   - return list
59   - }
60   - },
61   - 'el-checkbox-group': {
62   - options(h, conf, key) {
63   - const list = []
64   - conf.options.forEach(item => {
65   - if (conf.optionType === 'button') {
66   - list.push(<el-checkbox-button label={item.value}>{item.label}</el-checkbox-button>)
67   - } else {
68   - list.push(<el-checkbox label={item.value} border={conf.border}>{item.label}</el-checkbox>)
69   - }
70   - })
71   - return list
72   - }
73   - },
74   - 'el-upload': {
75   - 'list-type': (h, conf, key) => {
76   - const list = []
77   - if (conf['list-type'] === 'picture-card') {
78   - list.push(<i class="el-icon-plus"></i>)
79   - } else {
80   - list.push(<el-button size="small" type="primary" icon="el-icon-upload">{conf.buttonText}</el-button>)
81   - }
82   - if (conf.showTip) {
83   - list.push(<div slot="tip" class="el-upload__tip">只能上传不超过 {conf.fileSize}{conf.sizeUnit} 的{conf.accept}文件</div>)
84   - }
85   - return list
86   - }
87   - }
88   -}
89   -
90   -export default {
91   - render(h) {
92   - const dataObject = {
93   - attrs: {},
94   - props: {},
95   - on: {},
96   - style: {}
97   - }
98   - const confClone = JSON.parse(JSON.stringify(this.conf))
99   - const children = []
100   -
101   - const childObjs = componentChild[confClone.tag]
102   - if (childObjs) {
103   - Object.keys(childObjs).forEach(key => {
104   - const childFunc = childObjs[key]
105   - if (confClone[key]) {
106   - children.push(childFunc(h, confClone, key))
107   - }
108   - })
109   - }
110   -
111   - Object.keys(confClone).forEach(key => {
112   - const val = confClone[key]
113   - if (key === 'vModel') {
114   - vModel(this, dataObject, confClone.defaultValue)
115   - } else if (dataObject[key]) {
116   - dataObject[key] = val
117   - } else if (!isAttr(key)) {
118   - dataObject.props[key] = val
119   - } else {
120   - dataObject.attrs[key] = val
121   - }
122   - })
123   - return h(this.conf.tag, dataObject, children)
124   - },
125   - props: ['conf']
126   -}
yudao-admin-ui/src/utils/generator/ruleTrigger.js deleted
1   -/**
2   - * 用于生成表单校验,指定正则规则的触发方式。
3   - * 未在此处声明无触发方式的组件将不生成rule!!
4   - */
5   -export default {
6   - 'el-input': 'blur',
7   - 'el-input-number': 'blur',
8   - 'el-select': 'change',
9   - 'el-radio-group': 'change',
10   - 'el-checkbox-group': 'change',
11   - 'el-cascader': 'change',
12   - 'el-time-picker': 'change',
13   - 'el-date-picker': 'change',
14   - 'el-rate': 'change',
15   - tinymce: 'blur'
16   -}
yudao-admin-ui/src/utils/generator/icon.json renamed to yudao-admin-ui/src/utils/icon.json
yudao-admin-ui/src/utils/parser/Parser.vue deleted
1   -<script>
2   -import { deepClone } from '@/utils/index'
3   -// import render from '@/components/render/render.js'
4   -import render from '../render/render.js' // edit by 芋道源码
5   -
6   -const ruleTrigger = {
7   - 'el-input': 'blur',
8   - 'el-input-number': 'blur',
9   - 'el-select': 'change',
10   - 'el-radio-group': 'change',
11   - 'el-checkbox-group': 'change',
12   - 'el-cascader': 'change',
13   - 'el-time-picker': 'change',
14   - 'el-date-picker': 'change',
15   - 'el-rate': 'change'
16   -}
17   -
18   -const layouts = {
19   - colFormItem(h, scheme) {
20   - const config = scheme.__config__
21   - const listeners = buildListeners.call(this, scheme)
22   -
23   - let labelWidth = config.labelWidth ? `${config.labelWidth}px` : null
24   - if (config.showLabel === false) labelWidth = '0'
25   - return (
26   - <el-col span={config.span}>
27   - <el-form-item label-width={labelWidth} prop={scheme.__vModel__}
28   - label={config.showLabel ? config.label : ''}>
29   - <render conf={scheme} on={listeners} />
30   - </el-form-item>
31   - </el-col>
32   - )
33   - },
34   - rowFormItem(h, scheme) {
35   - let child = renderChildren.apply(this, arguments)
36   - if (scheme.type === 'flex') {
37   - child = <el-row type={scheme.type} justify={scheme.justify} align={scheme.align}>
38   - {child}
39   - </el-row>
40   - }
41   - return (
42   - <el-col span={scheme.span}>
43   - <el-row gutter={scheme.gutter}>
44   - {child}
45   - </el-row>
46   - </el-col>
47   - )
48   - }
49   -}
50   -
51   -function renderFrom(h) {
52   - const { formConfCopy } = this
53   -
54   - return (
55   - <el-row gutter={formConfCopy.gutter}>
56   - <el-form
57   - size={formConfCopy.size}
58   - label-position={formConfCopy.labelPosition}
59   - disabled={formConfCopy.disabled}
60   - label-width={`${formConfCopy.labelWidth}px`}
61   - ref={formConfCopy.formRef}
62   - // model不能直接赋值 https://github.com/vuejs/jsx/issues/49#issuecomment-472013664
63   - props={{ model: this[formConfCopy.formModel] }}
64   - rules={this[formConfCopy.formRules]}
65   - >
66   - {renderFormItem.call(this, h, formConfCopy.fields)}
67   - {formConfCopy.formBtns && formBtns.call(this, h)}
68   - </el-form>
69   - </el-row>
70   - )
71   -}
72   -
73   -function formBtns(h) {
74   - return <el-col>
75   - <el-form-item size="large">
76   - <el-button type="primary" onClick={this.submitForm}>提交</el-button>
77   - <el-button onClick={this.resetForm}>重置</el-button>
78   - </el-form-item>
79   - </el-col>
80   -}
81   -
82   -function renderFormItem(h, elementList) {
83   - return elementList.map(scheme => {
84   - const config = scheme.__config__
85   - const layout = layouts[config.layout]
86   -
87   - if (layout) {
88   - return layout.call(this, h, scheme)
89   - }
90   - throw new Error(`没有与${config.layout}匹配的layout`)
91   - })
92   -}
93   -
94   -function renderChildren(h, scheme) {
95   - const config = scheme.__config__
96   - if (!Array.isArray(config.children)) return null
97   - return renderFormItem.call(this, h, config.children)
98   -}
99   -
100   -function setValue(event, config, scheme) {
101   - this.$set(config, 'defaultValue', event)
102   - this.$set(this[this.formConf.formModel], scheme.__vModel__, event)
103   -}
104   -
105   -function buildListeners(scheme) {
106   - const config = scheme.__config__
107   - const methods = this.formConf.__methods__ || {}
108   - const listeners = {}
109   -
110   - // 给__methods__中的方法绑定this和event
111   - Object.keys(methods).forEach(key => {
112   - listeners[key] = event => methods[key].call(this, event)
113   - })
114   - // 响应 render.js 中的 vModel $emit('input', val)
115   - listeners.input = event => setValue.call(this, event, config, scheme)
116   -
117   - return listeners
118   -}
119   -
120   -export default {
121   - components: {
122   - render
123   - },
124   - props: {
125   - formConf: {
126   - type: Object,
127   - required: true
128   - }
129   - },
130   - data() {
131   - const data = {
132   - formConfCopy: deepClone(this.formConf),
133   - [this.formConf.formModel]: {},
134   - [this.formConf.formRules]: {}
135   - }
136   - this.initFormData(data.formConfCopy.fields, data[this.formConf.formModel])
137   - this.buildRules(data.formConfCopy.fields, data[this.formConf.formRules])
138   - return data
139   - },
140   - methods: {
141   - initFormData(componentList, formData) {
142   - componentList.forEach(cur => {
143   - const config = cur.__config__
144   - if (cur.__vModel__) formData[cur.__vModel__] = config.defaultValue
145   - // debugger
146   - if (config.children) this.initFormData(config.children, formData)
147   - })
148   - },
149   - buildRules(componentList, rules) {
150   - componentList.forEach(cur => {
151   - const config = cur.__config__
152   - if (Array.isArray(config.regList)) {
153   - if (config.required) {
154   - const required = { required: config.required, message: cur.placeholder }
155   - if (Array.isArray(config.defaultValue)) {
156   - required.type = 'array'
157   - required.message = `请至少选择一个${config.label}`
158   - }
159   - required.message === undefined && (required.message = `${config.label}不能为空`)
160   - config.regList.push(required)
161   - }
162   - rules[cur.__vModel__] = config.regList.map(item => {
163   - item.pattern && (item.pattern = eval(item.pattern))
164   - item.trigger = ruleTrigger && ruleTrigger[config.tag]
165   - return item
166   - })
167   - }
168   - if (config.children) this.buildRules(config.children, rules)
169   - })
170   - },
171   - resetForm() {
172   - this.formConfCopy = deepClone(this.formConf)
173   - this.$refs[this.formConf.formRef].resetFields()
174   - },
175   - submitForm() {
176   - this.$refs[this.formConf.formRef].validate(valid => {
177   - if (!valid) return false
178   - // 触发sumit事件
179   - this.$emit('submit', this[this.formConf.formModel])
180   - return true
181   - })
182   - }
183   - },
184   - render(h) {
185   - return renderFrom.call(this, h)
186   - }
187   -}
188   -</script>
yudao-admin-ui/src/utils/parser/README.md deleted
1   -## form-generator JSON 解析器
2   ->用于将form-generator导出的JSON解析成一个表单。
3   -
4   -### 安装组件
5   -```
6   -npm i form-gen-parser
7   -```
8   -或者
9   -```
10   -yarn add form-gen-parser
11   -```
12   -
13   -### 使用示例
14   -> [查看在线示例](https://mrhj.gitee.io/form-generator/#/parser)
15   -
16   -示例代码:
17   -> [src\components\parser\example\Index.vue](https://github.com/JakHuang/form-generator/blob/dev/src/components/parser/example/Index.vue)
18   -
19   -【add by 芋道源码】https://github.com/JakHuang/form-generator/blob/dev/src/components/parser/
20 0 \ No newline at end of file
yudao-admin-ui/src/utils/parser/example/Index.vue deleted
1   -<template>
2   - <div class="test-form">
3   - <parser :form-conf="formConf" @submit="sumbitForm1" />
4   - <parser :key="key2" :form-conf="formConf" @submit="sumbitForm2" />
5   - <el-button @click="change">
6   - change
7   - </el-button>
8   - </div>
9   -</template>
10   -
11   -<script>
12   -import Parser from '../Parser'
13   -
14   -// 若parser是通过安装npm方式集成到项目中的,使用此行引入
15   -// import Parser from 'form-gen-parser'
16   -
17   -export default {
18   - components: {
19   - Parser
20   - },
21   - props: {},
22   - data() {
23   - return {
24   - key2: +new Date(),
25   - formConf: {
26   - fields: [
27   - {
28   - __config__: {
29   - label: '单行文本',
30   - labelWidth: null,
31   - showLabel: true,
32   - changeTag: true,
33   - tag: 'el-input',
34   - tagIcon: 'input',
35   - required: true,
36   - layout: 'colFormItem',
37   - span: 24,
38   - document: 'https://element.eleme.cn/#/zh-CN/component/input',
39   - regList: [
40   - {
41   - pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
42   - message: '手机号格式错误'
43   - }
44   - ]
45   - },
46   - __slot__: {
47   - prepend: '',
48   - append: ''
49   - },
50   - __vModel__: 'mobile',
51   - placeholder: '请输入手机号',
52   - style: {
53   - width: '100%'
54   - },
55   - clearable: true,
56   - 'prefix-icon': 'el-icon-mobile',
57   - 'suffix-icon': '',
58   - maxlength: 11,
59   - 'show-word-limit': true,
60   - readonly: false,
61   - disabled: false
62   - },
63   - {
64   - __config__: {
65   - label: '日期范围',
66   - tag: 'el-date-picker',
67   - tagIcon: 'date-range',
68   - defaultValue: null,
69   - span: 24,
70   - showLabel: true,
71   - labelWidth: null,
72   - required: true,
73   - layout: 'colFormItem',
74   - regList: [],
75   - changeTag: true,
76   - document:
77   - 'https://element.eleme.cn/#/zh-CN/component/date-picker',
78   - formId: 101,
79   - renderKey: 1585980082729
80   - },
81   - style: {
82   - width: '100%'
83   - },
84   - type: 'daterange',
85   - 'range-separator': '至',
86   - 'start-placeholder': '开始日期',
87   - 'end-placeholder': '结束日期',
88   - disabled: false,
89   - clearable: true,
90   - format: 'yyyy-MM-dd',
91   - 'value-format': 'yyyy-MM-dd',
92   - readonly: false,
93   - __vModel__: 'field101'
94   - },
95   - {
96   - __config__: {
97   - layout: 'rowFormItem',
98   - tagIcon: 'row',
99   - label: '行容器',
100   - layoutTree: true,
101   - children: [
102   - {
103   - __config__: {
104   - label: '评分',
105   - tag: 'el-rate',
106   - tagIcon: 'rate',
107   - defaultValue: 0,
108   - span: 24,
109   - showLabel: true,
110   - labelWidth: null,
111   - layout: 'colFormItem',
112   - required: true,
113   - regList: [],
114   - changeTag: true,
115   - document: 'https://element.eleme.cn/#/zh-CN/component/rate',
116   - formId: 102,
117   - renderKey: 1586839671259
118   - },
119   - style: {},
120   - max: 5,
121   - 'allow-half': false,
122   - 'show-text': false,
123   - 'show-score': false,
124   - disabled: false,
125   - __vModel__: 'field102'
126   - }
127   - ],
128   - document: 'https://element.eleme.cn/#/zh-CN/component/layout',
129   - formId: 101,
130   - span: 24,
131   - renderKey: 1586839668999,
132   - componentName: 'row101',
133   - gutter: 15
134   - },
135   - type: 'default',
136   - justify: 'start',
137   - align: 'top'
138   - },
139   - {
140   - __config__: {
141   - label: '按钮',
142   - showLabel: true,
143   - changeTag: true,
144   - labelWidth: null,
145   - tag: 'el-button',
146   - tagIcon: 'button',
147   - span: 24,
148   - layout: 'colFormItem',
149   - document: 'https://element.eleme.cn/#/zh-CN/component/button',
150   - renderKey: 1594288459289
151   - },
152   - __slot__: {
153   - default: '测试按钮1'
154   - },
155   - type: 'primary',
156   - icon: 'el-icon-search',
157   - round: false,
158   - size: 'medium',
159   - plain: false,
160   - circle: false,
161   - disabled: false,
162   - on: {
163   - click: 'clickTestButton1'
164   - }
165   - }
166   - ],
167   - __methods__: {
168   - clickTestButton1() {
169   - console.log(
170   - `%c【测试按钮1】点击事件里可以访问当前表单:
171   - 1) formModel='formData', 所以this.formData可以拿到当前表单的model
172   - 2) formRef='elForm', 所以this.$refs.elForm可以拿到当前表单的ref(vue组件)
173   - `,
174   - 'color:#409EFF;font-size: 15px'
175   - )
176   - console.log('表单的Model:', this.formData)
177   - console.log('表单的ref:', this.$refs.elForm)
178   - }
179   - },
180   - formRef: 'elForm',
181   - formModel: 'formData',
182   - size: 'small',
183   - labelPosition: 'right',
184   - labelWidth: 100,
185   - formRules: 'rules',
186   - gutter: 15,
187   - disabled: false,
188   - span: 24,
189   - formBtns: true,
190   - unFocusedComponentBorder: false
191   - },
192   - formConf2: {
193   - fields: [
194   - {
195   - __config__: {
196   - label: '单行文本',
197   - labelWidth: null,
198   - showLabel: true,
199   - changeTag: true,
200   - tag: 'el-input',
201   - tagIcon: 'input',
202   - required: true,
203   - layout: 'colFormItem',
204   - span: 24,
205   - document: 'https://element.eleme.cn/#/zh-CN/component/input',
206   - regList: [
207   - {
208   - pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
209   - message: '手机号格式错误'
210   - }
211   - ]
212   - },
213   - __slot__: {
214   - prepend: '',
215   - append: ''
216   - },
217   - __vModel__: 'mobile',
218   - placeholder: '请输入手机号',
219   - style: {
220   - width: '100%'
221   - },
222   - clearable: true,
223   - 'prefix-icon': 'el-icon-mobile',
224   - 'suffix-icon': '',
225   - maxlength: 11,
226   - 'show-word-limit': true,
227   - readonly: false,
228   - disabled: false
229   - },
230   - {
231   - __config__: {
232   - label: '日期范围',
233   - tag: 'el-date-picker',
234   - tagIcon: 'date-range',
235   - defaultValue: null,
236   - span: 24,
237   - showLabel: true,
238   - labelWidth: null,
239   - required: true,
240   - layout: 'colFormItem',
241   - regList: [],
242   - changeTag: true,
243   - document:
244   - 'https://element.eleme.cn/#/zh-CN/component/date-picker',
245   - formId: 101,
246   - renderKey: 1585980082729
247   - },
248   - style: {
249   - width: '100%'
250   - },
251   - type: 'daterange',
252   - 'range-separator': '至',
253   - 'start-placeholder': '开始日期',
254   - 'end-placeholder': '结束日期',
255   - disabled: false,
256   - clearable: true,
257   - format: 'yyyy-MM-dd',
258   - 'value-format': 'yyyy-MM-dd',
259   - readonly: false,
260   - __vModel__: 'field101'
261   - }
262   - ],
263   - formRef: 'elForm',
264   - formModel: 'formData',
265   - size: 'small',
266   - labelPosition: 'right',
267   - labelWidth: 100,
268   - formRules: 'rules',
269   - gutter: 15,
270   - disabled: false,
271   - span: 24,
272   - formBtns: true,
273   - unFocusedComponentBorder: false
274   - }
275   - }
276   - },
277   - computed: {},
278   - watch: {},
279   - created() {},
280   - mounted() {
281   - // 表单数据回填,模拟异步请求场景
282   - setTimeout(() => {
283   - // 请求回来的表单数据
284   - const data = {
285   - mobile: '18836662555'
286   - }
287   - // 回填数据
288   - this.fillFormData(this.formConf, data)
289   - // 更新表单
290   - this.key2 = +new Date()
291   - }, 2000)
292   - },
293   - methods: {
294   - fillFormData(form, data) {
295   - form.fields.forEach(item => {
296   - const val = data[item.__vModel__]
297   - if (val) {
298   - item.__config__.defaultValue = val
299   - }
300   - })
301   - },
302   - change() {
303   - this.key2 = +new Date()
304   - const t = this.formConf
305   - this.formConf = this.formConf2
306   - this.formConf2 = t
307   - },
308   - sumbitForm1(data) {
309   - console.log('sumbitForm1提交数据:', data)
310   - },
311   - sumbitForm2(data) {
312   - console.log('sumbitForm2提交数据:', data)
313   - }
314   - }
315   -}
316   -</script>
317   -
318   -<style lang="scss" scoped>
319   -.test-form {
320   - margin: 15px auto;
321   - width: 800px;
322   - padding: 15px;
323   -}
324   -</style>
yudao-admin-ui/src/utils/parser/index.js deleted
1   -import Parser from './Parser'
2   -
3   -export default Parser
yudao-admin-ui/src/utils/parser/package.json deleted
1   -{
2   - "name": "form-gen-parser",
3   - "version": "1.0.3",
4   - "description": "表单json解析器",
5   - "main": "lib/form-gen-parser.umd.js",
6   - "directories": {
7   - "example": "example"
8   - },
9   - "scripts": {
10   - "test": "echo \"Error: no test specified\" && exit 1"
11   - },
12   - "repository": {
13   - "type": "git",
14   - "url": "git+https://github.com/JakHuang/form-generator.git"
15   - },
16   - "dependencies": {
17   - "form-gen-render": "^1.0.0"
18   - },
19   - "author": "jakHuang",
20   - "license": "MIT",
21   - "bugs": {
22   - "url": "https://github.com/JakHuang/form-generator/issues"
23   - },
24   - "homepage": "https://github.com/JakHuang/form-generator/blob/dev/src/components/parser"
25   -}
yudao-admin-ui/src/utils/render/README.md deleted
1   -【add by 芋道源码】https://github.com/JakHuang/form-generator/blob/dev/src/components/render/
2 0 \ No newline at end of file
yudao-admin-ui/src/utils/render/package.json deleted
1   -{
2   - "name": "form-gen-render",
3   - "version": "1.0.4",
4   - "description": "表单核心render",
5   - "main": "lib/form-gen-render.umd.js",
6   - "scripts": {
7   - "test": "echo \"Error: no test specified\" && exit 1"
8   - },
9   - "repository": {
10   - "type": "git",
11   - "url": "git+https://github.com/JakHuang/form-generator.git"
12   - },
13   - "author": "jakhuang",
14   - "license": "MIT",
15   - "bugs": {
16   - "url": "https://github.com/JakHuang/form-generator/issues"
17   - },
18   - "homepage": "https://github.com/JakHuang/form-generator#readme"
19   -}
yudao-admin-ui/src/utils/render/render.js deleted
1   -import { deepClone } from '@/utils/index'
2   -
3   -const componentChild = {}
4   -/**
5   - * 将./slots中的文件挂载到对象componentChild上
6   - * 文件名为key,对应JSON配置中的__config__.tag
7   - * 文件内容为value,解析JSON配置中的__slot__
8   - */
9   -const slotsFiles = require.context('./slots', false, /\.js$/)
10   -const keys = slotsFiles.keys() || []
11   -keys.forEach(key => {
12   - const tag = key.replace(/^\.\/(.*)\.\w+$/, '$1')
13   - const value = slotsFiles(key).default
14   - componentChild[tag] = value
15   -})
16   -
17   -function vModel(dataObject, defaultValue) {
18   - dataObject.props.value = defaultValue
19   -
20   - dataObject.on.input = val => {
21   - this.$emit('input', val)
22   - }
23   -}
24   -
25   -function mountSlotFiles(h, confClone, children) {
26   - const childObjs = componentChild[confClone.__config__.tag]
27   - if (childObjs) {
28   - Object.keys(childObjs).forEach(key => {
29   - const childFunc = childObjs[key]
30   - if (confClone.__slot__ && confClone.__slot__[key]) {
31   - children.push(childFunc(h, confClone, key))
32   - }
33   - })
34   - }
35   -}
36   -
37   -function emitEvents(confClone) {
38   - ['on', 'nativeOn'].forEach(attr => {
39   - const eventKeyList = Object.keys(confClone[attr] || {})
40   - eventKeyList.forEach(key => {
41   - const val = confClone[attr][key]
42   - if (typeof val === 'string') {
43   - confClone[attr][key] = event => this.$emit(val, event)
44   - }
45   - })
46   - })
47   -}
48   -
49   -function buildDataObject(confClone, dataObject) {
50   - Object.keys(confClone).forEach(key => {
51   - const val = confClone[key]
52   - if (key === '__vModel__') {
53   - vModel.call(this, dataObject, confClone.__config__.defaultValue)
54   - } else if (dataObject[key] !== undefined) {
55   - if (dataObject[key] === null
56   - || dataObject[key] instanceof RegExp
57   - || ['boolean', 'string', 'number', 'function'].includes(typeof dataObject[key])) {
58   - dataObject[key] = val
59   - } else if (Array.isArray(dataObject[key])) {
60   - dataObject[key] = [...dataObject[key], ...val]
61   - } else {
62   - dataObject[key] = { ...dataObject[key], ...val }
63   - }
64   - } else {
65   - dataObject.attrs[key] = val
66   - }
67   - })
68   -
69   - // 清理属性
70   - clearAttrs(dataObject)
71   -}
72   -
73   -function clearAttrs(dataObject) {
74   - delete dataObject.attrs.__config__
75   - delete dataObject.attrs.__slot__
76   - delete dataObject.attrs.__methods__
77   -}
78   -
79   -function makeDataObject() {
80   - // 深入数据对象:
81   - // https://cn.vuejs.org/v2/guide/render-function.html#%E6%B7%B1%E5%85%A5%E6%95%B0%E6%8D%AE%E5%AF%B9%E8%B1%A1
82   - return {
83   - class: {},
84   - attrs: {},
85   - props: {},
86   - domProps: {},
87   - nativeOn: {},
88   - on: {},
89   - style: {},
90   - directives: [],
91   - scopedSlots: {},
92   - slot: null,
93   - key: null,
94   - ref: null,
95   - refInFor: true
96   - }
97   -}
98   -
99   -export default {
100   - props: {
101   - conf: {
102   - type: Object,
103   - required: true
104   - }
105   - },
106   - render(h) {
107   - const dataObject = makeDataObject()
108   - const confClone = deepClone(this.conf)
109   - const children = this.$slots.default || []
110   -
111   - // 如果slots文件夹存在与当前tag同名的文件,则执行文件中的代码
112   - mountSlotFiles.call(this, h, confClone, children)
113   -
114   - // 将字符串类型的事件,发送为消息
115   - emitEvents.call(this, confClone)
116   -
117   - // 将json表单配置转化为vue render可以识别的 “数据对象(dataObject)”
118   - buildDataObject.call(this, confClone, dataObject)
119   -
120   - return h(this.conf.__config__.tag, dataObject, children)
121   - }
122   -}
yudao-admin-ui/src/utils/render/slots/el-button.js deleted
1   -export default {
2   - default(h, conf, key) {
3   - return conf.__slot__[key]
4   - }
5   -}
yudao-admin-ui/src/utils/render/slots/el-checkbox-group.js deleted
1   -export default {
2   - options(h, conf, key) {
3   - const list = []
4   - conf.__slot__.options.forEach(item => {
5   - if (conf.__config__.optionType === 'button') {
6   - list.push(<el-checkbox-button label={item.value}>{item.label}</el-checkbox-button>)
7   - } else {
8   - list.push(<el-checkbox label={item.value} border={conf.border}>{item.label}</el-checkbox>)
9   - }
10   - })
11   - return list
12   - }
13   -}
yudao-admin-ui/src/utils/render/slots/el-input.js deleted
1   -export default {
2   - prepend(h, conf, key) {
3   - return <template slot="prepend">{conf.__slot__[key]}</template>
4   - },
5   - append(h, conf, key) {
6   - return <template slot="append">{conf.__slot__[key]}</template>
7   - }
8   -}
yudao-admin-ui/src/utils/render/slots/el-radio-group.js deleted
1   -export default {
2   - options(h, conf, key) {
3   - const list = []
4   - conf.__slot__.options.forEach(item => {
5   - if (conf.__config__.optionType === 'button') {
6   - list.push(<el-radio-button label={item.value}>{item.label}</el-radio-button>)
7   - } else {
8   - list.push(<el-radio label={item.value} border={conf.border}>{item.label}</el-radio>)
9   - }
10   - })
11   - return list
12   - }
13   -}
yudao-admin-ui/src/utils/render/slots/el-select.js deleted
1   -export default {
2   - options(h, conf, key) {
3   - const list = []
4   - conf.__slot__.options.forEach(item => {
5   - list.push(<el-option label={item.label} value={item.value} disabled={item.disabled}></el-option>)
6   - })
7   - return list
8   - }
9   -}
yudao-admin-ui/src/utils/render/slots/el-upload.js deleted
1   -export default {
2   - 'list-type': (h, conf, key) => {
3   - const list = []
4   - const config = conf.__config__
5   - if (conf['list-type'] === 'picture-card') {
6   - list.push(<i class="el-icon-plus"></i>)
7   - } else {
8   - list.push(<el-button size="small" type="primary" icon="el-icon-upload">{config.buttonText}</el-button>)
9   - }
10   - if (config.showTip) {
11   - list.push(
12   - <div slot="tip" class="el-upload__tip">只能上传不超过 {config.fileSize}{config.sizeUnit} 的{conf.accept}文件</div>
13   - )
14   - }
15   - return list
16   - }
17   -}
yudao-admin-ui/src/views/bpm/form/formEditor.vue
... ... @@ -150,7 +150,7 @@ import JsonDrawer from &#39;@/views/tool/build/JsonDrawer&#39;
150 150 import RightPanel from '@/views/tool/build/RightPanel'
151 151 import {
152 152 inputComponents, selectComponents, layoutComponents, formConf
153   -} from '@/utils/generator/config'
  153 +} from '@/components/generator/config'
154 154 import {
155 155 exportDefault, beautifierConf, isNumberStr, titleCase, deepClone, isObjectObject
156 156 } from '@/utils/index'
... ...
yudao-admin-ui/src/views/bpm/form/index.vue
... ... @@ -62,7 +62,7 @@
62 62  
63 63 <script>
64 64 import {deleteForm, getForm, getFormPage} from "@/api/bpm/form";
65   -import Parser from '@/utils/parser/Parser'
  65 +import Parser from '@/components/parser/Parser'
66 66  
67 67 export default {
68 68 name: "Form",
... ... @@ -121,181 +121,181 @@ export default {
121 121 this.detailOpen = true
122 122 getForm(row.id).then(response => {
123 123 const data = response.data
124   - // this.detailForm = {
125   - // ...JSON.parse(data.conf),
126   - // fields: this.decodeFields(data.fields)
127   - // }
128   - console.log({
  124 + this.detailForm = {
129 125 ...JSON.parse(data.conf),
130 126 fields: this.decodeFields(data.fields)
131   - })
132   - this.detailForm = {
133   - fields: [
134   - {
135   - __config__: {
136   - label: '单行文本',
137   - labelWidth: null,
138   - showLabel: true,
139   - changeTag: true,
140   - tag: 'el-input',
141   - tagIcon: 'input',
142   - required: true,
143   - layout: 'colFormItem',
144   - span: 24,
145   - document: 'https://element.eleme.cn/#/zh-CN/component/input',
146   - regList: [
147   - {
148   - pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
149   - message: '手机号格式错误'
150   - }
151   - ]
152   - },
153   - __slot__: {
154   - prepend: '',
155   - append: ''
156   - },
157   - __vModel__: 'mobile',
158   - placeholder: '请输入手机号',
159   - style: {
160   - width: '100%'
161   - },
162   - clearable: true,
163   - 'prefix-icon': 'el-icon-mobile',
164   - 'suffix-icon': '',
165   - maxlength: 11,
166   - 'show-word-limit': true,
167   - readonly: false,
168   - disabled: false
169   - },
170   - {
171   - __config__: {
172   - label: '日期范围',
173   - tag: 'el-date-picker',
174   - tagIcon: 'date-range',
175   - defaultValue: null,
176   - span: 24,
177   - showLabel: true,
178   - labelWidth: null,
179   - required: true,
180   - layout: 'colFormItem',
181   - regList: [],
182   - changeTag: true,
183   - document:
184   - 'https://element.eleme.cn/#/zh-CN/component/date-picker',
185   - formId: 101,
186   - renderKey: 1585980082729
187   - },
188   - style: {
189   - width: '100%'
190   - },
191   - type: 'daterange',
192   - 'range-separator': '至',
193   - 'start-placeholder': '开始日期',
194   - 'end-placeholder': '结束日期',
195   - disabled: false,
196   - clearable: true,
197   - format: 'yyyy-MM-dd',
198   - 'value-format': 'yyyy-MM-dd',
199   - readonly: false,
200   - __vModel__: 'field101'
201   - },
202   - {
203   - __config__: {
204   - layout: 'rowFormItem',
205   - tagIcon: 'row',
206   - label: '行容器',
207   - layoutTree: true,
208   - children: [
209   - {
210   - __config__: {
211   - label: '评分',
212   - tag: 'el-rate',
213   - tagIcon: 'rate',
214   - defaultValue: 0,
215   - span: 24,
216   - showLabel: true,
217   - labelWidth: null,
218   - layout: 'colFormItem',
219   - required: true,
220   - regList: [],
221   - changeTag: true,
222   - document: 'https://element.eleme.cn/#/zh-CN/component/rate',
223   - formId: 102,
224   - renderKey: 1586839671259
225   - },
226   - style: {},
227   - max: 5,
228   - 'allow-half': false,
229   - 'show-text': false,
230   - 'show-score': false,
231   - disabled: false,
232   - __vModel__: 'field102'
233   - }
234   - ],
235   - document: 'https://element.eleme.cn/#/zh-CN/component/layout',
236   - formId: 101,
237   - span: 24,
238   - renderKey: 1586839668999,
239   - componentName: 'row101',
240   - gutter: 15
241   - },
242   - type: 'default',
243   - justify: 'start',
244   - align: 'top'
245   - },
246   - {
247   - __config__: {
248   - label: '按钮',
249   - showLabel: true,
250   - changeTag: true,
251   - labelWidth: null,
252   - tag: 'el-button',
253   - tagIcon: 'button',
254   - span: 24,
255   - layout: 'colFormItem',
256   - document: 'https://element.eleme.cn/#/zh-CN/component/button',
257   - renderKey: 1594288459289
258   - },
259   - __slot__: {
260   - default: '测试按钮1'
261   - },
262   - type: 'primary',
263   - icon: 'el-icon-search',
264   - round: false,
265   - size: 'medium',
266   - plain: false,
267   - circle: false,
268   - disabled: false,
269   - on: {
270   - click: 'clickTestButton1'
271   - }
272   - }
273   - ],
274   - __methods__: {
275   - clickTestButton1() {
276   - console.log(
277   - `%c【测试按钮1】点击事件里可以访问当前表单:
278   - 1) formModel='formData', 所以this.formData可以拿到当前表单的model
279   - 2) formRef='elForm', 所以this.$refs.elForm可以拿到当前表单的ref(vue组件)
280   - `,
281   - 'color:#409EFF;font-size: 15px'
282   - )
283   - console.log('表单的Model:', this.formData)
284   - console.log('表单的ref:', this.$refs.elForm)
285   - }
286   - },
287   - formRef: 'elForm',
288   - formModel: 'formData',
289   - size: 'small',
290   - labelPosition: 'right',
291   - labelWidth: 100,
292   - formRules: 'rules',
293   - gutter: 15,
294   - disabled: false,
295   - span: 24,
296   - formBtns: true,
297   - unFocusedComponentBorder: false
298 127 }
  128 + // console.log({
  129 + // ...JSON.parse(data.conf),
  130 + // fields: this.decodeFields(data.fields)
  131 + // })
  132 + // this.detailForm = {
  133 + // fields: [
  134 + // {
  135 + // __config__: {
  136 + // label: '单行文本',
  137 + // labelWidth: null,
  138 + // showLabel: true,
  139 + // changeTag: true,
  140 + // tag: 'el-input',
  141 + // tagIcon: 'input',
  142 + // required: true,
  143 + // layout: 'colFormItem',
  144 + // span: 24,
  145 + // document: 'https://element.eleme.cn/#/zh-CN/component/input',
  146 + // regList: [
  147 + // {
  148 + // pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
  149 + // message: '手机号格式错误'
  150 + // }
  151 + // ]
  152 + // },
  153 + // __slot__: {
  154 + // prepend: '',
  155 + // append: ''
  156 + // },
  157 + // __vModel__: 'mobile',
  158 + // placeholder: '请输入手机号',
  159 + // style: {
  160 + // width: '100%'
  161 + // },
  162 + // clearable: true,
  163 + // 'prefix-icon': 'el-icon-mobile',
  164 + // 'suffix-icon': '',
  165 + // maxlength: 11,
  166 + // 'show-word-limit': true,
  167 + // readonly: false,
  168 + // disabled: false
  169 + // },
  170 + // {
  171 + // __config__: {
  172 + // label: '日期范围',
  173 + // tag: 'el-date-picker',
  174 + // tagIcon: 'date-range',
  175 + // defaultValue: null,
  176 + // span: 24,
  177 + // showLabel: true,
  178 + // labelWidth: null,
  179 + // required: true,
  180 + // layout: 'colFormItem',
  181 + // regList: [],
  182 + // changeTag: true,
  183 + // document:
  184 + // 'https://element.eleme.cn/#/zh-CN/component/date-picker',
  185 + // formId: 101,
  186 + // renderKey: 1585980082729
  187 + // },
  188 + // style: {
  189 + // width: '100%'
  190 + // },
  191 + // type: 'daterange',
  192 + // 'range-separator': '至',
  193 + // 'start-placeholder': '开始日期',
  194 + // 'end-placeholder': '结束日期',
  195 + // disabled: false,
  196 + // clearable: true,
  197 + // format: 'yyyy-MM-dd',
  198 + // 'value-format': 'yyyy-MM-dd',
  199 + // readonly: false,
  200 + // __vModel__: 'field101'
  201 + // },
  202 + // {
  203 + // __config__: {
  204 + // layout: 'rowFormItem',
  205 + // tagIcon: 'row',
  206 + // label: '行容器',
  207 + // layoutTree: true,
  208 + // children: [
  209 + // {
  210 + // __config__: {
  211 + // label: '评分',
  212 + // tag: 'el-rate',
  213 + // tagIcon: 'rate',
  214 + // defaultValue: 0,
  215 + // span: 24,
  216 + // showLabel: true,
  217 + // labelWidth: null,
  218 + // layout: 'colFormItem',
  219 + // required: true,
  220 + // regList: [],
  221 + // changeTag: true,
  222 + // document: 'https://element.eleme.cn/#/zh-CN/component/rate',
  223 + // formId: 102,
  224 + // renderKey: 1586839671259
  225 + // },
  226 + // style: {},
  227 + // max: 5,
  228 + // 'allow-half': false,
  229 + // 'show-text': false,
  230 + // 'show-score': false,
  231 + // disabled: false,
  232 + // __vModel__: 'field102'
  233 + // }
  234 + // ],
  235 + // document: 'https://element.eleme.cn/#/zh-CN/component/layout',
  236 + // formId: 101,
  237 + // span: 24,
  238 + // renderKey: 1586839668999,
  239 + // componentName: 'row101',
  240 + // gutter: 15
  241 + // },
  242 + // type: 'default',
  243 + // justify: 'start',
  244 + // align: 'top'
  245 + // },
  246 + // {
  247 + // __config__: {
  248 + // label: '按钮',
  249 + // showLabel: true,
  250 + // changeTag: true,
  251 + // labelWidth: null,
  252 + // tag: 'el-button',
  253 + // tagIcon: 'button',
  254 + // span: 24,
  255 + // layout: 'colFormItem',
  256 + // document: 'https://element.eleme.cn/#/zh-CN/component/button',
  257 + // renderKey: 1594288459289
  258 + // },
  259 + // __slot__: {
  260 + // default: '测试按钮1'
  261 + // },
  262 + // type: 'primary',
  263 + // icon: 'el-icon-search',
  264 + // round: false,
  265 + // size: 'medium',
  266 + // plain: false,
  267 + // circle: false,
  268 + // disabled: false,
  269 + // on: {
  270 + // click: 'clickTestButton1'
  271 + // }
  272 + // }
  273 + // ],
  274 + // __methods__: {
  275 + // clickTestButton1() {
  276 + // console.log(
  277 + // `%c【测试按钮1】点击事件里可以访问当前表单:
  278 + // 1) formModel='formData', 所以this.formData可以拿到当前表单的model
  279 + // 2) formRef='elForm', 所以this.$refs.elForm可以拿到当前表单的ref(vue组件)
  280 + // `,
  281 + // 'color:#409EFF;font-size: 15px'
  282 + // )
  283 + // console.log('表单的Model:', this.formData)
  284 + // console.log('表单的ref:', this.$refs.elForm)
  285 + // }
  286 + // },
  287 + // formRef: 'elForm',
  288 + // formModel: 'formData',
  289 + // size: 'small',
  290 + // labelPosition: 'right',
  291 + // labelWidth: 100,
  292 + // formRules: 'rules',
  293 + // gutter: 15,
  294 + // disabled: false,
  295 + // span: 24,
  296 + // formBtns: true,
  297 + // unFocusedComponentBorder: false
  298 + // }
299 299 });
300 300 },
301 301 decodeFields(fields) {
... ...
yudao-admin-ui/src/views/tool/build/FormDrawer.vue
... ... @@ -81,9 +81,9 @@ import ClipboardJS from &#39;clipboard&#39;
81 81 import { saveAs } from 'file-saver'
82 82 import {
83 83 makeUpHtml, vueTemplate, vueScript, cssStyle
84   -} from '@/utils/generator/html'
85   -import { makeUpJs } from '@/utils/generator/js'
86   -import { makeUpCss } from '@/utils/generator/css'
  84 +} from '@/components/generator/html'
  85 +import { makeUpJs } from '@/components/generator/js'
  86 +import { makeUpCss } from '@/components/generator/css'
87 87 import { exportDefault, beautifierConf, titleCase } from '@/utils/index'
88 88 import ResourceDialog from './ResourceDialog'
89 89 import loadMonaco from '@/utils/loadMonaco'
... ...
yudao-admin-ui/src/views/tool/build/IconsDialog.vue
... ... @@ -34,7 +34,7 @@
34 34 </div>
35 35 </template>
36 36 <script>
37   -import iconList from '@/utils/generator/icon.json'
  37 +import iconList from '@/utils/icon.json'
38 38  
39 39 const originList = iconList.map(name => `el-icon-${name}`)
40 40  
... ...
yudao-admin-ui/src/views/tool/build/RightPanel.vue
... ... @@ -655,7 +655,7 @@ import { isNumberStr } from &#39;@/utils/index&#39;
655 655 import IconsDialog from './IconsDialog'
656 656 import {
657 657 inputComponents, selectComponents, layoutComponents
658   -} from '@/utils/generator/config'
  658 +} from '@/components/generator/config'
659 659 import { saveFormConf } from '@/utils/db'
660 660  
661 661 const dateTimeFormat = {
... ...
yudao-admin-ui/src/views/tool/build/index.vue
... ... @@ -131,7 +131,7 @@ import JsonDrawer from &#39;./JsonDrawer&#39;
131 131 import RightPanel from './RightPanel'
132 132 import {
133 133 inputComponents, selectComponents, layoutComponents, formConf
134   -} from '@/utils/generator/config'
  134 +} from '@/components/generator/config'
135 135 import {
136 136 exportDefault, beautifierConf, isNumberStr, titleCase, deepClone, isObjectObject
137 137 } from '@/utils/index'
... ...