/**
|
* 用于生成表单校验,指定正则规则的触发方式。
|
* 未在此处声明无触发方式的组件将不生成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
|
}
|