提交 | 用户 | 时间
|
759b1c
|
1 |
import { isArray } from 'util' |
H |
2 |
import { exportDefault, titleCase, deepClone } from '@/utils' |
|
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 |
} |