254 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			254 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import { isArray } from 'util'
 | ||
| import { exportDefault, titleCase } from '@/utils/generator/index'
 | ||
| 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 = JSON.parse(JSON.stringify(formConfig))
 | ||
|   const dataList = []
 | ||
|   const ruleList = []
 | ||
|   const optionsList = []
 | ||
|   const propsList = []
 | ||
|   const methodList = mixinMethod(type)
 | ||
|   const uploadVarList = []
 | ||
| 
 | ||
|   formConfig.fields.forEach(el => {
 | ||
|     buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList)
 | ||
|   })
 | ||
| 
 | ||
|   const script = buildexport(
 | ||
|     formConfig,
 | ||
|     type,
 | ||
|     dataList.join('\n'),
 | ||
|     ruleList.join('\n'),
 | ||
|     optionsList.join('\n'),
 | ||
|     uploadVarList.join('\n'),
 | ||
|     propsList.join('\n'),
 | ||
|     methodList.join('\n')
 | ||
|   )
 | ||
|   confGlobal = null
 | ||
|   return script
 | ||
| }
 | ||
| 
 | ||
| // 构建组件属性
 | ||
| function buildAttributes(scheme, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) {
 | ||
|   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)
 | ||
|       buildOptionMethod(`get${options}`, model, methodList)
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   // 处理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)
 | ||
|     })
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| // 混入处理函数
 | ||
| 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) {
 | ||
|   const str = `${methodName}() {
 | ||
|     // TODO 发起请求获取数据
 | ||
|     this.${model}
 | ||
|   },`
 | ||
|   methodList.push(str)
 | ||
| }
 | ||
| 
 | ||
| // js整体拼接
 | ||
| function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods) {
 | ||
|   const str = `${exportDefault}{
 | ||
|   ${inheritAttrs[type]}
 | ||
|   components: {},
 | ||
|   props: [],
 | ||
|   data () {
 | ||
|     return {
 | ||
|       ${conf.formModel}: {
 | ||
|         ${data}
 | ||
|       },
 | ||
|       ${conf.formRules}: {
 | ||
|         ${rules}
 | ||
|       },
 | ||
|       ${uploadVar}
 | ||
|       ${selectOptions}
 | ||
|       ${props}
 | ||
|     }
 | ||
|   },
 | ||
|   computed: {},
 | ||
|   watch: {},
 | ||
|   created () {},
 | ||
|   mounted () {},
 | ||
|   methods: {
 | ||
|     ${methods}
 | ||
|   }
 | ||
| }`
 | ||
|   return str
 | ||
| }
 |