/** * 用于生成表单校验,指定正则规则的触发方式。 * 未在此处声明无触发方式的组件将不生成rule!! */ const ruleTrigger = { 'el-input': 'blur', 'el-input-number': 'blur', 'el-select': 'change', 'el-radio-group': 'change', 'el-checkbox-group': 'change', 'el-cascader': 'change', 'el-time-picker': 'change', 'el-date-picker': 'change', 'el-rate': 'change' } // 首字母大小 function titleCase(str) { return str.replace(/( |^)[a-z]/g, L => L.toUpperCase()) } // 去掉最后一个字符 function removeLastChar(source) { return source.substring(0, source.length - 1) } // const units = { // KB: '1024', // MB: '1024 / 1024', // GB: '1024 / 1024 / 1024' // } // let confGlobal // const inheritAttrs = { // file: '', // dialog: 'inheritAttrs: false,' // } /** * 组装js * @param {Object} formConfig 表单json结构 * @param {String} type 生成类型,文件或弹窗 */ export function makeUpJs(formConfig, type) { formConfig = JSON.parse(formConfig) const dataList = {} const ruleList = {} const optionsList = [] const propsList = [] const methodList = [] const uploadVarList = [] const specialList = [] // 特有属性 // 遍历“第一层”子组件 formConfig.fields.forEach(field => { buildAttributes(field, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, specialList) }) // 字符串数组 // ["field101Options: [{"label":"选项一","value":1},{"label":"选项二","value":2}],"] // console.log('optionsList', optionsList) // 最终生成的脚本 const script = buildexport( formConfig, type, dataList, ruleList, optionsList.join('\n'), uploadVarList.join('\n'), propsList.join('\n'), methodList.join('\n'), specialList.join('\n') ) // confGlobal = null return script } // 构建组件属性 function buildAttributes(field, formData, rules, optionsList, methodList, propsList, uploadVarList, specialList) { const config = field.__config__ const slot = field.__slot__ // 向“formData”填充数据 fillFormData(field, formData) // 向“rules”填充校验规则 fillRules(field, rules) // 处理options属性 if (field.options || (slot && slot.options && slot.options.length)) { buildOptions(field, optionsList) if (config.dataType === 'dynamic') { const model = `${field.__vModel__}Options` const options = titleCase(model) buildOptionMethod(`get${options}`, model, methodList) } } // // 处理props // if (field.props && field.props.props) { // buildProps(field, propsList) // } // // 处理el-upload的action // if (field.action && config.tag === 'el-upload') { // uploadVarList.push( // `${field.__vModel__}Action: '${field.action}', // ${field.__vModel__}fileList: [],` // ) // methodList.push(buildBeforeUpload(field)) // // 非自动上传时,生成手动上传的函数 // if (!field['auto-upload']) { // methodList.push(buildSubmitUpload(field)) // } // } // 处理“弹框组件”的属性和函数 if (field.FComponentType === 'dialog') { // 表单结构 let formModelStructure = '' field.__config__.children.forEach(child => { // if (child.__vModel__ === undefined) return let defaultValue = null if (typeof (child.__config__.defaultValue) === 'string' && !child.multiple) { defaultValue = `"${child.__config__.defaultValue}"` } else { defaultValue = `${JSON.stringify(child.__config__.defaultValue)}` } if (defaultValue === 'undefined') defaultValue = null formModelStructure += `"${child.__vModel__}": ${defaultValue},` }) // 去掉最后一个逗号 formModelStructure = removeLastChar(formModelStructure) // 校验结构 let formRulesStructure = '' field.__config__.children.forEach(child => { const childConfig = child.__config__ if (child.__vModel__ === undefined) return const rules = [] if (ruleTrigger[childConfig.tag]) { // 必填 if (childConfig.required) { const type = Array.isArray(childConfig.defaultValue) ? 'type: \'array\',' : '' let message = Array.isArray(childConfig.defaultValue) ? `请至少选择一个${childConfig.label}` : child.placeholder if (message === undefined) message = `${childConfig.label}不能为空` rules.push(`{ required: true, ${type} message: '${message}', trigger: '${ruleTrigger[childConfig.tag]}' }`) } // 自定义规则 // if (childConfig.regList && isArray(childConfig.regList)) { // childConfig.regList.forEach(item => { // if (item.pattern) { // rules.push( // `{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${ruleTrigger[childConfig.tag]}' }` // ) // } // }) // } formRulesStructure += `"${child.__vModel__}": [${rules.join(',')}],` } }) // 去掉最后一个逗号 formRulesStructure = removeLastChar(formRulesStructure) // 注意:这里添加的是“字符串” // specialList.push(`${field.__special__.visibleModel}: false,`) specialList.push(`"${field.FVisibleParamName}": false,`) specialList.push(`"${field.FFormDataParamName}": { ${formModelStructure} },`) specialList.push(`"${field.FFormRulesParamName}": { ${formRulesStructure} }`) // // 提交对话框中的表单 // methodList.push(` // // 提交对话框中的表单 // ${field.__special__.submitMethodName}() { // // 校验表单 // this.$refs['${field.__special__.formRef}'].validate(valid => { // if (!valid) return // // // 业务类型是“修改” // if (this.${field.__special__.businessTypeModel} === 'edit') { // // 重置业务类型 // this.${field.__special__.businessTypeModel} = undefined // // 业务类型是“新增” // } else { // // 表格新增一行 // this.formData.${field.__vModel__}.push(this.${field.__special__.formModel}) // } // // 清空对话框中的表单 // this.${field.__special__.formModel} = {} // // 关闭对话框 // this.${field.__special__.visibleModel} = false // }) // }, // `) // // // 修改表格行 // methodList.push(` // // 修改表格行 // ${field.__special__.tableEditMethodName}(index, row) { // // 对话框业务类型 // this.${field.__special__.businessTypeModel} = 'edit' // // 对话框表单赋值 // this.${field.__special__.formModel} = row // // 显示对话框 // this.${field.__special__.visibleModel} = true // }, // `) // // // 删除表格行 // methodList.push(` // // 删除表格行 // ${field.__special__.tableDeleteMethodName}(index, row) { // this.formData.${field.__vModel__}.splice(index, 1) // }, // `) } // 构建子级组件属性 if (config.children) { config.children.forEach(item => { buildAttributes(item, formData, rules, optionsList, methodList, propsList, uploadVarList, specialList) }) } } // // 混入处理函数 // // type(file页面|dialog弹框) // function mixinMethod(type) { // const list = [] // const minxins = { // // 页面 // file: confGlobal.formBtns ? { // // 四级折叠 // // 提交表单 // submitForm: ` // submitForm() { // this.$refs['${confGlobal.formRef}'].validate(valid => { // if(!valid) return // }) // }, // `, // // 重置表单 // 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]) // }) // } // // // console.log('list', list) // // return list // } /** * 向“formData”填充数据 * * export default { * data() { * return { * formData: { * id: '', * name: '', * gender: 1, * date: null * } * } * } * } * @param {*} field formDef.formJson.fields[n] * @param {*} formData 容器 */ function fillFormData(field, formData) { // 不是input元素,则跳过 if (field.__vModel__ === undefined) return // 不处理对话框中的“input” if (field.inDialog && field.inDialog === true) return // 示例: {id: '', name: '', gender: 1, date: null} formData[field.__vModel__] = field.__config__.defaultValue === undefined ? '' : field.__config__.defaultValue } // 向“rules”填充校验规则 // rules: { // number: [{ required: true, message: '请输入单据编号', trigger: 'blur' }], // bizDate: [{ required: true, message: '请选择业务日期', trigger: 'change' }], // price: [ // { required: true, message: '请输入单价', trigger: 'blur' }, // { pattern: /^[0-9]*$/, message: '请输入数字', trigger: 'blur' } // ] // } function fillRules(field, rules) { const config = field.__config__ // 不是input元素,则跳过 if (field.__vModel__ === undefined) return // 不处理对话框中的“input” if (field.inDialog && field.inDialog === true) return // 字段的所有校验规则 const fieldRules = [] if (ruleTrigger[config.tag]) { // 处理必填 if (config.required) { // 字段的单个校验规则 let fieldRule = {required: true, message: '', trigger: ruleTrigger[config.tag]} // 如果字段类型是数组 if (Array.isArray(config.defaultValue)) fieldRule.type = 'array' // 校验提示信息 fieldRule.message = Array.isArray(config.defaultValue) ? `请至少选择一个${config.label}` : field.placeholder if (fieldRule.message === undefined) fieldRule.message = `${config.label}不能为空` fieldRules.push(fieldRule) } // 处理正则校验 // if (config.regList && isArray(config.regList)) { // config.regList.forEach(item => { // if (item.pattern) { // fieldRules.push( // `{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${ruleTrigger[config.tag]}' }` // ) // } // }) // } rules[field.__vModel__] = fieldRules } } // 构建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, dataList, ruleList, selectOptions, uploadVar, props, methods, specials) { // const str = ` // export default { // ${inheritAttrs[type]} // components: {}, // props: [], // data () { // return { // ${conf.formModel}: { // ${dataList} // }, // ${conf.formRules}: { // ${ruleList} // }, // ${uploadVar} // ${selectOptions} // ${props} // ${specials} // } // }, // computed: {}, // watch: {}, // created () {}, // mounted () { // // 重置表单 // this.resetForm() // }, // methods: { // ${methods} // } // } // ` // return str const result = { data: { // ${conf.formModel}: { // ${dataList} // }, // ${conf.formRules}: { // ${ruleList} // }, // ${uploadVar} // ${selectOptions} // ${props} // ${specials} } } // console.log('specials', JSON.parse('{' + specials + '}')) // console.log('specials', JSON.parse('{"cityDialogVisible": false, "cityDialogFormData": { "name": null }, "cityDialogFormRules": { "name": [] }}')) // console.log('specials', '{' + specials + '}') result.data = JSON.parse('{' + specials + '}') result.data[conf.formModel] = dataList result.data[conf.formRules] = ruleList // console.log('result', JSON.stringify(result.data)) return result }