js.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. import { titleCase } from '@/utils/index'
  2. import { trigger } from './config'
  3. // 文件大小设置
  4. const units = {
  5. KB: '1024',
  6. MB: '1024 / 1024',
  7. GB: '1024 / 1024 / 1024',
  8. }
  9. /**
  10. * @name: 生成js需要的数据
  11. * @description: 生成js需要的数据
  12. * @param {*} conf
  13. * @param {*} type 弹窗或表单
  14. * @return {*}
  15. */
  16. export function makeUpJs(conf, type) {
  17. conf = JSON.parse(JSON.stringify(conf))
  18. const dataList = []
  19. const ruleList = []
  20. const optionsList = []
  21. const propsList = []
  22. const methodList = []
  23. const uploadVarList = []
  24. conf.fields.forEach((el) => {
  25. buildAttributes(
  26. el,
  27. dataList,
  28. ruleList,
  29. optionsList,
  30. methodList,
  31. propsList,
  32. uploadVarList
  33. )
  34. })
  35. const script = buildexport(
  36. conf,
  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. )
  45. return script
  46. }
  47. /**
  48. * @name: 生成参数
  49. * @description: 生成参数,包括表单数据表单验证数据,多选选项数据,上传数据等
  50. * @return {*}
  51. */
  52. function buildAttributes(
  53. el,
  54. dataList,
  55. ruleList,
  56. optionsList,
  57. methodList,
  58. propsList,
  59. uploadVarList
  60. ){
  61. buildData(el, dataList)
  62. buildRules(el, ruleList)
  63. if (el.options && el.options.length) {
  64. buildOptions(el, optionsList)
  65. if (el.dataType === 'dynamic') {
  66. const model = `${el.vModel}Options`
  67. const options = titleCase(model)
  68. buildOptionMethod(`get${options}`, model, methodList)
  69. }
  70. }
  71. if (el.props && el.props.props) {
  72. buildProps(el, propsList)
  73. }
  74. if (el.action && el.tag === 'el-upload') {
  75. uploadVarList.push(
  76. `
  77. // 上传请求路径
  78. const ${el.vModel}Action = ref('${el.action}')
  79. // 上传文件列表
  80. const ${el.vModel}fileList = ref([])`
  81. )
  82. methodList.push(buildBeforeUpload(el))
  83. if (!el['auto-upload']) {
  84. methodList.push(buildSubmitUpload(el))
  85. }
  86. }
  87. if (el.children) {
  88. el.children.forEach((el2) => {
  89. buildAttributes(
  90. el2,
  91. dataList,
  92. ruleList,
  93. optionsList,
  94. methodList,
  95. propsList,
  96. uploadVarList
  97. )
  98. })
  99. }
  100. }
  101. /**
  102. * @name: 生成表单数据formData
  103. * @description: 生成表单数据formData
  104. * @param {*} conf
  105. * @param {*} dataList 数据列表
  106. * @return {*}
  107. */
  108. function buildData(conf, dataList) {
  109. if (conf.vModel === undefined) return
  110. let defaultValue
  111. if (typeof conf.defaultValue === 'string' && !conf.multiple) {
  112. defaultValue = `'${conf.defaultValue}'`
  113. } else {
  114. defaultValue = `${JSON.stringify(conf.defaultValue)}`
  115. }
  116. dataList.push(`${conf.vModel}: ${defaultValue},`)
  117. }
  118. /**
  119. * @name: 生成表单验证数据rule
  120. * @description: 生成表单验证数据rule
  121. * @param {*} conf
  122. * @param {*} ruleList 验证数据列表
  123. * @return {*}
  124. */
  125. function buildRules(conf, ruleList) {
  126. if (conf.vModel === undefined) return
  127. const rules = []
  128. if (trigger[conf.tag]) {
  129. if (conf.required) {
  130. const type = Array.isArray(conf.defaultValue) ? "type: 'array'," : ''
  131. let message = Array.isArray(conf.defaultValue)
  132. ? `请至少选择一个${conf.vModel}`
  133. : conf.placeholder
  134. if (message === undefined) message = `${conf.label}不能为空`
  135. rules.push(
  136. `{ required: true, ${type} message: '${message}', trigger: '${
  137. trigger[conf.tag]
  138. }' }`
  139. )
  140. }
  141. if (conf.regList && Array.isArray(conf.regList)) {
  142. conf.regList.forEach((item) => {
  143. if (item.pattern) {
  144. rules.push(
  145. `{ pattern: new RegExp(${item.pattern}), message: '${
  146. item.message
  147. }', trigger: '${trigger[conf.tag]}' }`
  148. )
  149. }
  150. })
  151. }
  152. ruleList.push(`${conf.vModel}: [${rules.join(',')}],`)
  153. }
  154. }
  155. /**
  156. * @name: 生成选项数据
  157. * @description: 生成选项数据,单选多选下拉等
  158. * @param {*} conf
  159. * @param {*} optionsList 选项数据列表
  160. * @return {*}
  161. */
  162. function buildOptions(conf, optionsList) {
  163. if (conf.vModel === undefined) return
  164. if (conf.dataType === 'dynamic') {
  165. conf.options = []
  166. }
  167. const str = `const ${conf.vModel}Options = ref(${JSON.stringify(conf.options)})`
  168. optionsList.push(str)
  169. }
  170. /**
  171. * @name: 生成方法
  172. * @description: 生成方法
  173. * @param {*} methodName 方法名
  174. * @param {*} model
  175. * @param {*} methodList 方法列表
  176. * @return {*}
  177. */
  178. function buildOptionMethod(methodName, model, methodList) {
  179. const str = `function ${methodName}() {
  180. // TODO 发起请求获取数据
  181. ${model}.value
  182. }`
  183. methodList.push(str)
  184. }
  185. /**
  186. * @name: 生成表单组件需要的props设置
  187. * @description: 生成表单组件需要的props设置,如;级联组件
  188. * @param {*} conf
  189. * @param {*} propsList
  190. * @return {*}
  191. */
  192. function buildProps(conf, propsList) {
  193. if (conf.dataType === 'dynamic') {
  194. conf.valueKey !== 'value' && (conf.props.props.value = conf.valueKey)
  195. conf.labelKey !== 'label' && (conf.props.props.label = conf.labelKey)
  196. conf.childrenKey !== 'children' &&
  197. (conf.props.props.children = conf.childrenKey)
  198. }
  199. const str = `
  200. // props设置
  201. const ${conf.vModel}Props = ref(${JSON.stringify(conf.props.props)})`
  202. propsList.push(str)
  203. }
  204. /**
  205. * @name: 生成上传组件的相关内容
  206. * @description: 生成上传组件的相关内容
  207. * @param {*} conf
  208. * @return {*}
  209. */
  210. function buildBeforeUpload(conf) {
  211. const unitNum = units[conf.sizeUnit]
  212. let rightSizeCode = ''
  213. let acceptCode = ''
  214. const returnList = []
  215. if (conf.fileSize) {
  216. rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${conf.fileSize}
  217. if(!isRightSize){
  218. proxy.$modal.msgError('文件大小超过 ${conf.fileSize}${conf.sizeUnit}')
  219. }`
  220. returnList.push('isRightSize')
  221. }
  222. if (conf.accept) {
  223. acceptCode = `let isAccept = new RegExp('${conf.accept}').test(file.type)
  224. if(!isAccept){
  225. proxy.$modal.msgError('应该选择${conf.accept}类型的文件')
  226. }`
  227. returnList.push('isAccept')
  228. }
  229. const str = `
  230. /**
  231. * @name: 上传之前的文件判断
  232. * @description: 上传之前的文件判断,判断文件大小文件类型等
  233. * @param {*} file
  234. * @return {*}
  235. */
  236. function ${conf.vModel}BeforeUpload(file) {
  237. ${rightSizeCode}
  238. ${acceptCode}
  239. return ${returnList.join('&&')}
  240. }`
  241. return returnList.length ? str : ''
  242. }
  243. /**
  244. * @name: 生成提交表单方法
  245. * @description: 生成提交表单方法
  246. * @param {Object} conf vModel 表单ref
  247. * @return {*}
  248. */
  249. function buildSubmitUpload(conf) {
  250. const str = `function submitUpload() {
  251. this.$refs['${conf.vModel}'].submit()
  252. }`
  253. return str
  254. }
  255. /**
  256. * @name: 组装js代码
  257. * @description: 组装js代码方法
  258. * @return {*}
  259. */
  260. function buildexport(
  261. conf,
  262. type,
  263. data,
  264. rules,
  265. selectOptions,
  266. uploadVar,
  267. props,
  268. methods
  269. ) {
  270. let str = `
  271. const { proxy } = getCurrentInstance()
  272. const ${conf.formRef} = ref()
  273. const data = reactive({
  274. ${conf.formModel}: {
  275. ${data}
  276. },
  277. ${conf.formRules}: {
  278. ${rules}
  279. }
  280. })
  281. const {${conf.formModel}, ${conf.formRules}} = toRefs(data)
  282. ${selectOptions}
  283. ${uploadVar}
  284. ${props}
  285. ${methods}
  286. `
  287. if(type === 'dialog') {
  288. str += `
  289. // 弹窗设置
  290. const dialogVisible = defineModel()
  291. // 弹窗确认回调
  292. const emit = defineEmits(['confirm'])
  293. /**
  294. * @name: 弹窗打开后执行
  295. * @description: 弹窗打开后执行方法
  296. * @return {*}
  297. */
  298. function onOpen(){
  299. }
  300. /**
  301. * @name: 弹窗关闭时执行
  302. * @description: 弹窗关闭方法,重置表单
  303. * @return {*}
  304. */
  305. function onClose(){
  306. ${conf.formRef}.value.resetFields()
  307. }
  308. /**
  309. * @name: 弹窗取消
  310. * @description: 弹窗取消方法
  311. * @return {*}
  312. */
  313. function close(){
  314. dialogVisible.value = false
  315. }
  316. /**
  317. * @name: 弹窗表单提交
  318. * @description: 弹窗表单提交方法
  319. * @return {*}
  320. */
  321. function handelConfirm(){
  322. ${conf.formRef}.value.validate((valid) => {
  323. if (!valid) return
  324. // TODO 提交表单
  325. close()
  326. // 回调父级组件
  327. emit('confirm')
  328. })
  329. }
  330. `
  331. } else {
  332. str += `
  333. /**
  334. * @name: 表单提交
  335. * @description: 表单提交方法
  336. * @return {*}
  337. */
  338. function submitForm() {
  339. ${conf.formRef}.value.validate((valid) => {
  340. if (!valid) return
  341. // TODO 提交表单
  342. })
  343. }
  344. /**
  345. * @name: 表单重置
  346. * @description: 表单重置方法
  347. * @return {*}
  348. */
  349. function resetForm() {
  350. ${conf.formRef}.value.resetFields()
  351. }
  352. `
  353. }
  354. return str
  355. }