| 
									
										
										
										
											2022-01-02 11:22:13 +08:00
										 |  |  |  | import { isArray } from 'util' | 
					
						
							| 
									
										
										
										
											2022-11-08 13:31:08 +08:00
										 |  |  |  | import { exportDefault, titleCase, deepClone } from '@/utils' | 
					
						
							| 
									
										
										
										
											2022-01-02 11:22:13 +08:00
										 |  |  |  | import ruleTrigger from './ruleTrigger' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | const units = { | 
					
						
							|  |  |  |  |   KB: '1024', | 
					
						
							|  |  |  |  |   MB: '1024 / 1024', | 
					
						
							|  |  |  |  |   GB: '1024 / 1024 / 1024' | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | let confGlobal | 
					
						
							|  |  |  |  | const inheritAttrs = { | 
					
						
							|  |  |  |  |   file: '', | 
					
						
							|  |  |  |  |   dialog: 'inheritAttrs: false,' | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /** | 
					
						
							|  |  |  |  |  * 组装js 【入口函数】 | 
					
						
							|  |  |  |  |  * @param {Object} formConfig 整个表单配置 | 
					
						
							|  |  |  |  |  * @param {String} type 生成类型,文件或弹窗等 | 
					
						
							|  |  |  |  |  */ | 
					
						
							|  |  |  |  | export function makeUpJs(formConfig, type) { | 
					
						
							|  |  |  |  |   confGlobal = formConfig = deepClone(formConfig) | 
					
						
							|  |  |  |  |   const dataList = [] | 
					
						
							|  |  |  |  |   const ruleList = [] | 
					
						
							|  |  |  |  |   const optionsList = [] | 
					
						
							|  |  |  |  |   const propsList = [] | 
					
						
							|  |  |  |  |   const methodList = mixinMethod(type) | 
					
						
							|  |  |  |  |   const uploadVarList = [] | 
					
						
							|  |  |  |  |   const created = [] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   formConfig.fields.forEach(el => { | 
					
						
							|  |  |  |  |     buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created) | 
					
						
							|  |  |  |  |   }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   const script = buildexport( | 
					
						
							|  |  |  |  |     formConfig, | 
					
						
							|  |  |  |  |     type, | 
					
						
							|  |  |  |  |     dataList.join('\n'), | 
					
						
							|  |  |  |  |     ruleList.join('\n'), | 
					
						
							|  |  |  |  |     optionsList.join('\n'), | 
					
						
							|  |  |  |  |     uploadVarList.join('\n'), | 
					
						
							|  |  |  |  |     propsList.join('\n'), | 
					
						
							|  |  |  |  |     methodList.join('\n'), | 
					
						
							|  |  |  |  |     created.join('\n') | 
					
						
							|  |  |  |  |   ) | 
					
						
							|  |  |  |  |   confGlobal = null | 
					
						
							|  |  |  |  |   return script | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 构建组件属性
 | 
					
						
							|  |  |  |  | function buildAttributes(scheme, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created) { | 
					
						
							|  |  |  |  |   const config = scheme.__config__ | 
					
						
							|  |  |  |  |   const slot = scheme.__slot__ | 
					
						
							|  |  |  |  |   buildData(scheme, dataList) | 
					
						
							|  |  |  |  |   buildRules(scheme, ruleList) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   // 特殊处理options属性
 | 
					
						
							|  |  |  |  |   if (scheme.options || (slot && slot.options && slot.options.length)) { | 
					
						
							|  |  |  |  |     buildOptions(scheme, optionsList) | 
					
						
							|  |  |  |  |     if (config.dataType === 'dynamic') { | 
					
						
							|  |  |  |  |       const model = `${scheme.__vModel__}Options` | 
					
						
							|  |  |  |  |       const options = titleCase(model) | 
					
						
							|  |  |  |  |       const methodName = `get${options}` | 
					
						
							|  |  |  |  |       buildOptionMethod(methodName, model, methodList, scheme) | 
					
						
							|  |  |  |  |       callInCreated(methodName, created) | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   // 处理props
 | 
					
						
							|  |  |  |  |   if (scheme.props && scheme.props.props) { | 
					
						
							|  |  |  |  |     buildProps(scheme, propsList) | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   // 处理el-upload的action
 | 
					
						
							|  |  |  |  |   if (scheme.action && config.tag === 'el-upload') { | 
					
						
							|  |  |  |  |     uploadVarList.push( | 
					
						
							|  |  |  |  |       `${scheme.__vModel__}Action: '${scheme.action}',
 | 
					
						
							|  |  |  |  |       ${scheme.__vModel__}fileList: [],`
 | 
					
						
							|  |  |  |  |     ) | 
					
						
							|  |  |  |  |     methodList.push(buildBeforeUpload(scheme)) | 
					
						
							|  |  |  |  |     // 非自动上传时,生成手动上传的函数
 | 
					
						
							|  |  |  |  |     if (!scheme['auto-upload']) { | 
					
						
							|  |  |  |  |       methodList.push(buildSubmitUpload(scheme)) | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   // 构建子级组件属性
 | 
					
						
							|  |  |  |  |   if (config.children) { | 
					
						
							|  |  |  |  |     config.children.forEach(item => { | 
					
						
							|  |  |  |  |       buildAttributes(item, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created) | 
					
						
							|  |  |  |  |     }) | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 在Created调用函数
 | 
					
						
							|  |  |  |  | function callInCreated(methodName, created) { | 
					
						
							|  |  |  |  |   created.push(`this.${methodName}()`) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 混入处理函数
 | 
					
						
							|  |  |  |  | function mixinMethod(type) { | 
					
						
							|  |  |  |  |   const list = []; const | 
					
						
							|  |  |  |  |     minxins = { | 
					
						
							|  |  |  |  |       file: confGlobal.formBtns ? { | 
					
						
							|  |  |  |  |         submitForm: `submitForm() {
 | 
					
						
							|  |  |  |  |         this.$refs['${confGlobal.formRef}'].validate(valid => { | 
					
						
							|  |  |  |  |           if(!valid) return | 
					
						
							|  |  |  |  |           // TODO 提交表单
 | 
					
						
							|  |  |  |  |         }) | 
					
						
							|  |  |  |  |       },`,
 | 
					
						
							|  |  |  |  |         resetForm: `resetForm() {
 | 
					
						
							|  |  |  |  |         this.$refs['${confGlobal.formRef}'].resetFields() | 
					
						
							|  |  |  |  |       },`
 | 
					
						
							|  |  |  |  |       } : null, | 
					
						
							|  |  |  |  |       dialog: { | 
					
						
							|  |  |  |  |         onOpen: 'onOpen() {},', | 
					
						
							|  |  |  |  |         onClose: `onClose() {
 | 
					
						
							|  |  |  |  |         this.$refs['${confGlobal.formRef}'].resetFields() | 
					
						
							|  |  |  |  |       },`,
 | 
					
						
							|  |  |  |  |         close: `close() {
 | 
					
						
							|  |  |  |  |         this.$emit('update:visible', false) | 
					
						
							|  |  |  |  |       },`,
 | 
					
						
							|  |  |  |  |         handelConfirm: `handelConfirm() {
 | 
					
						
							|  |  |  |  |         this.$refs['${confGlobal.formRef}'].validate(valid => { | 
					
						
							|  |  |  |  |           if(!valid) return | 
					
						
							|  |  |  |  |           this.close() | 
					
						
							|  |  |  |  |         }) | 
					
						
							|  |  |  |  |       },`
 | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   const methods = minxins[type] | 
					
						
							|  |  |  |  |   if (methods) { | 
					
						
							|  |  |  |  |     Object.keys(methods).forEach(key => { | 
					
						
							|  |  |  |  |       list.push(methods[key]) | 
					
						
							|  |  |  |  |     }) | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   return list | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 构建data
 | 
					
						
							|  |  |  |  | function buildData(scheme, dataList) { | 
					
						
							|  |  |  |  |   const config = scheme.__config__ | 
					
						
							|  |  |  |  |   if (scheme.__vModel__ === undefined) return | 
					
						
							|  |  |  |  |   const defaultValue = JSON.stringify(config.defaultValue) | 
					
						
							|  |  |  |  |   dataList.push(`${scheme.__vModel__}: ${defaultValue},`) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 构建校验规则
 | 
					
						
							|  |  |  |  | function buildRules(scheme, ruleList) { | 
					
						
							|  |  |  |  |   const config = scheme.__config__ | 
					
						
							|  |  |  |  |   if (scheme.__vModel__ === undefined) return | 
					
						
							|  |  |  |  |   const rules = [] | 
					
						
							|  |  |  |  |   if (ruleTrigger[config.tag]) { | 
					
						
							|  |  |  |  |     if (config.required) { | 
					
						
							|  |  |  |  |       const type = isArray(config.defaultValue) ? 'type: \'array\',' : '' | 
					
						
							|  |  |  |  |       let message = isArray(config.defaultValue) ? `请至少选择一个${config.label}` : scheme.placeholder | 
					
						
							|  |  |  |  |       if (message === undefined) message = `${config.label}不能为空` | 
					
						
							|  |  |  |  |       rules.push(`{ required: true, ${type} message: '${message}', trigger: '${ruleTrigger[config.tag]}' }`) | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     if (config.regList && isArray(config.regList)) { | 
					
						
							|  |  |  |  |       config.regList.forEach(item => { | 
					
						
							|  |  |  |  |         if (item.pattern) { | 
					
						
							|  |  |  |  |           rules.push( | 
					
						
							|  |  |  |  |             `{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${ruleTrigger[config.tag]}' }` | 
					
						
							|  |  |  |  |           ) | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |       }) | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     ruleList.push(`${scheme.__vModel__}: [${rules.join(',')}],`) | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 构建options
 | 
					
						
							|  |  |  |  | function buildOptions(scheme, optionsList) { | 
					
						
							|  |  |  |  |   if (scheme.__vModel__ === undefined) return | 
					
						
							|  |  |  |  |   // el-cascader直接有options属性,其他组件都是定义在slot中,所以有两处判断
 | 
					
						
							|  |  |  |  |   let { options } = scheme | 
					
						
							|  |  |  |  |   if (!options) options = scheme.__slot__.options | 
					
						
							|  |  |  |  |   if (scheme.__config__.dataType === 'dynamic') { options = [] } | 
					
						
							|  |  |  |  |   const str = `${scheme.__vModel__}Options: ${JSON.stringify(options)},` | 
					
						
							|  |  |  |  |   optionsList.push(str) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | function buildProps(scheme, propsList) { | 
					
						
							|  |  |  |  |   const str = `${scheme.__vModel__}Props: ${JSON.stringify(scheme.props.props)},` | 
					
						
							|  |  |  |  |   propsList.push(str) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // el-upload的BeforeUpload
 | 
					
						
							|  |  |  |  | function buildBeforeUpload(scheme) { | 
					
						
							|  |  |  |  |   const config = scheme.__config__ | 
					
						
							|  |  |  |  |   const unitNum = units[config.sizeUnit]; let rightSizeCode = ''; let acceptCode = ''; const | 
					
						
							|  |  |  |  |     returnList = [] | 
					
						
							|  |  |  |  |   if (config.fileSize) { | 
					
						
							|  |  |  |  |     rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${config.fileSize}
 | 
					
						
							|  |  |  |  |     if(!isRightSize){ | 
					
						
							|  |  |  |  |       this.$message.error('文件大小超过 ${config.fileSize}${config.sizeUnit}') | 
					
						
							|  |  |  |  |     }`
 | 
					
						
							|  |  |  |  |     returnList.push('isRightSize') | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   if (scheme.accept) { | 
					
						
							|  |  |  |  |     acceptCode = `let isAccept = new RegExp('${scheme.accept}').test(file.type)
 | 
					
						
							|  |  |  |  |     if(!isAccept){ | 
					
						
							|  |  |  |  |       this.$message.error('应该选择${scheme.accept}类型的文件') | 
					
						
							|  |  |  |  |     }`
 | 
					
						
							|  |  |  |  |     returnList.push('isAccept') | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   const str = `${scheme.__vModel__}BeforeUpload(file) {
 | 
					
						
							|  |  |  |  |     ${rightSizeCode} | 
					
						
							|  |  |  |  |     ${acceptCode} | 
					
						
							|  |  |  |  |     return ${returnList.join('&&')} | 
					
						
							|  |  |  |  |   },`
 | 
					
						
							|  |  |  |  |   return returnList.length ? str : '' | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // el-upload的submit
 | 
					
						
							|  |  |  |  | function buildSubmitUpload(scheme) { | 
					
						
							|  |  |  |  |   const str = `submitUpload() {
 | 
					
						
							|  |  |  |  |     this.$refs['${scheme.__vModel__}'].submit() | 
					
						
							|  |  |  |  |   },`
 | 
					
						
							|  |  |  |  |   return str | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | function buildOptionMethod(methodName, model, methodList, scheme) { | 
					
						
							|  |  |  |  |   const config = scheme.__config__ | 
					
						
							|  |  |  |  |   const str = `${methodName}() {
 | 
					
						
							|  |  |  |  |     // 注意:this.$axios是通过Vue.prototype.$axios = axios挂载产生的
 | 
					
						
							|  |  |  |  |     this.$axios({ | 
					
						
							|  |  |  |  |       method: '${config.method}', | 
					
						
							|  |  |  |  |       url: '${config.url}' | 
					
						
							|  |  |  |  |     }).then(resp => { | 
					
						
							|  |  |  |  |       var { data } = resp | 
					
						
							|  |  |  |  |       this.${model} = data.${config.dataPath} | 
					
						
							|  |  |  |  |     }) | 
					
						
							|  |  |  |  |   },`
 | 
					
						
							|  |  |  |  |   methodList.push(str) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // js整体拼接
 | 
					
						
							|  |  |  |  | function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods, created) { | 
					
						
							|  |  |  |  |   const str = `${exportDefault}{
 | 
					
						
							|  |  |  |  |   ${inheritAttrs[type]} | 
					
						
							|  |  |  |  |   components: {}, | 
					
						
							|  |  |  |  |   props: [], | 
					
						
							|  |  |  |  |   data () { | 
					
						
							|  |  |  |  |     return { | 
					
						
							|  |  |  |  |       ${conf.formModel}: { | 
					
						
							|  |  |  |  |         ${data} | 
					
						
							|  |  |  |  |       }, | 
					
						
							|  |  |  |  |       ${conf.formRules}: { | 
					
						
							|  |  |  |  |         ${rules} | 
					
						
							|  |  |  |  |       }, | 
					
						
							|  |  |  |  |       ${uploadVar} | 
					
						
							|  |  |  |  |       ${selectOptions} | 
					
						
							|  |  |  |  |       ${props} | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   }, | 
					
						
							|  |  |  |  |   computed: {}, | 
					
						
							|  |  |  |  |   watch: {}, | 
					
						
							|  |  |  |  |   created () { | 
					
						
							|  |  |  |  |     ${created} | 
					
						
							|  |  |  |  |   }, | 
					
						
							|  |  |  |  |   mounted () {}, | 
					
						
							|  |  |  |  |   methods: { | 
					
						
							|  |  |  |  |     ${methods} | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | }`
 | 
					
						
							|  |  |  |  |   return str | 
					
						
							|  |  |  |  | } |