diff --git a/yudao-admin-ui/src/utils/generator/README.md b/yudao-admin-ui/src/utils/generator/README.md
new file mode 100644
index 000000000..46a4c15ec
--- /dev/null
+++ b/yudao-admin-ui/src/utils/generator/README.md
@@ -0,0 +1 @@
+【add by 芋道源码】来自 https://github.com/JakHuang/form-generator/tree/dev/src/components/generator 目录
\ No newline at end of file
diff --git a/yudao-admin-ui/src/utils/index.js b/yudao-admin-ui/src/utils/index.js
index 918580f7b..4d29dd0ec 100644
--- a/yudao-admin-ui/src/utils/index.js
+++ b/yudao-admin-ui/src/utils/index.js
@@ -5,12 +5,12 @@ import { parseTime } from './ruoyi'
*/
export function formatDate(cellValue) {
if (cellValue == null || cellValue == "") return "";
- var date = new Date(cellValue)
+ var date = new Date(cellValue)
var year = date.getFullYear()
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
- var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
- var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
- var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
+ var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
+ var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
+ var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
}
@@ -250,26 +250,65 @@ export function debounce(func, wait, immediate) {
}
}
-/**
- * This is just a simple version of deep copy
- * Has a lot of edge cases bug
- * If you want to use a perfect deep copy, use lodash's _.cloneDeep
- * @param {Object} source
- * @returns {Object}
- */
-export function deepClone(source) {
- if (!source && typeof source !== 'object') {
- throw new Error('error arguments', 'deepClone')
+// /**
+// * This is just a simple version of deep copy
+// * Has a lot of edge cases bug
+// * If you want to use a perfect deep copy, use lodash's _.cloneDeep
+// * @param {Object} source
+// * @returns {Object}
+// */
+// export function deepClone(source) {
+// if (!source && typeof source !== 'object') {
+// throw new Error('error arguments', 'deepClone')
+// }
+// const targetObj = source.constructor === Array ? [] : {}
+// Object.keys(source).forEach(keys => {
+// if (source[keys] && typeof source[keys] === 'object') {
+// targetObj[keys] = deepClone(source[keys])
+// } else {
+// targetObj[keys] = source[keys]
+// }
+// })
+// return targetObj
+// }
+
+// 深拷贝对象
+// 【add by 芋道源码】https://github.com/JakHuang/form-generator/blob/dev/src/utils/index.js#L107
+export function deepClone(obj) {
+ const _toString = Object.prototype.toString
+
+ // null, undefined, non-object, function
+ if (!obj || typeof obj !== 'object') {
+ return obj
}
- const targetObj = source.constructor === Array ? [] : {}
- Object.keys(source).forEach(keys => {
- if (source[keys] && typeof source[keys] === 'object') {
- targetObj[keys] = deepClone(source[keys])
- } else {
- targetObj[keys] = source[keys]
- }
- })
- return targetObj
+
+ // DOM Node
+ if (obj.nodeType && 'cloneNode' in obj) {
+ return obj.cloneNode(true)
+ }
+
+ // Date
+ if (_toString.call(obj) === '[object Date]') {
+ return new Date(obj.getTime())
+ }
+
+ // RegExp
+ if (_toString.call(obj) === '[object RegExp]') {
+ const flags = []
+ if (obj.global) { flags.push('g') }
+ if (obj.multiline) { flags.push('m') }
+ if (obj.ignoreCase) { flags.push('i') }
+
+ return new RegExp(obj.source, flags.join(''))
+ }
+
+ const result = Array.isArray(obj) ? [] : obj.constructor ? new obj.constructor() : {}
+
+ for (const key in obj) {
+ result[key] = deepClone(obj[key])
+ }
+
+ return result
}
/**
@@ -330,7 +369,7 @@ export function makeMap(str, expectsLowerCase) {
? val => map[val.toLowerCase()]
: val => map[val]
}
-
+
export const exportDefault = 'export default '
export const beautifierConf = {
@@ -387,4 +426,4 @@ export function camelCase(str) {
export function isNumberStr(str) {
return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
}
-
+
diff --git a/yudao-admin-ui/src/utils/parser/Parser.vue b/yudao-admin-ui/src/utils/parser/Parser.vue
new file mode 100644
index 000000000..632371a66
--- /dev/null
+++ b/yudao-admin-ui/src/utils/parser/Parser.vue
@@ -0,0 +1,188 @@
+
diff --git a/yudao-admin-ui/src/utils/parser/README.md b/yudao-admin-ui/src/utils/parser/README.md
new file mode 100644
index 000000000..6239e7c3e
--- /dev/null
+++ b/yudao-admin-ui/src/utils/parser/README.md
@@ -0,0 +1,19 @@
+## form-generator JSON 解析器
+>用于将form-generator导出的JSON解析成一个表单。
+
+### 安装组件
+```
+npm i form-gen-parser
+```
+或者
+```
+yarn add form-gen-parser
+```
+
+### 使用示例
+> [查看在线示例](https://mrhj.gitee.io/form-generator/#/parser)
+
+示例代码:
+> [src\components\parser\example\Index.vue](https://github.com/JakHuang/form-generator/blob/dev/src/components/parser/example/Index.vue)
+
+【add by 芋道源码】https://github.com/JakHuang/form-generator/blob/dev/src/components/parser/
\ No newline at end of file
diff --git a/yudao-admin-ui/src/utils/parser/example/Index.vue b/yudao-admin-ui/src/utils/parser/example/Index.vue
new file mode 100644
index 000000000..d218509c2
--- /dev/null
+++ b/yudao-admin-ui/src/utils/parser/example/Index.vue
@@ -0,0 +1,324 @@
+
+
+
+
+
+
+
diff --git a/yudao-admin-ui/src/utils/parser/index.js b/yudao-admin-ui/src/utils/parser/index.js
new file mode 100644
index 000000000..0a44b2ccc
--- /dev/null
+++ b/yudao-admin-ui/src/utils/parser/index.js
@@ -0,0 +1,3 @@
+import Parser from './Parser'
+
+export default Parser
diff --git a/yudao-admin-ui/src/utils/parser/package.json b/yudao-admin-ui/src/utils/parser/package.json
new file mode 100644
index 000000000..ffeaba32f
--- /dev/null
+++ b/yudao-admin-ui/src/utils/parser/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "form-gen-parser",
+ "version": "1.0.3",
+ "description": "表单json解析器",
+ "main": "lib/form-gen-parser.umd.js",
+ "directories": {
+ "example": "example"
+ },
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/JakHuang/form-generator.git"
+ },
+ "dependencies": {
+ "form-gen-render": "^1.0.0"
+ },
+ "author": "jakHuang",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/JakHuang/form-generator/issues"
+ },
+ "homepage": "https://github.com/JakHuang/form-generator/blob/dev/src/components/parser"
+}
diff --git a/yudao-admin-ui/src/utils/render/README.md b/yudao-admin-ui/src/utils/render/README.md
new file mode 100644
index 000000000..14fd3aee7
--- /dev/null
+++ b/yudao-admin-ui/src/utils/render/README.md
@@ -0,0 +1 @@
+【add by 芋道源码】https://github.com/JakHuang/form-generator/blob/dev/src/components/render/
\ No newline at end of file
diff --git a/yudao-admin-ui/src/utils/render/package.json b/yudao-admin-ui/src/utils/render/package.json
new file mode 100644
index 000000000..96bffcfec
--- /dev/null
+++ b/yudao-admin-ui/src/utils/render/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "form-gen-render",
+ "version": "1.0.4",
+ "description": "表单核心render",
+ "main": "lib/form-gen-render.umd.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/JakHuang/form-generator.git"
+ },
+ "author": "jakhuang",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/JakHuang/form-generator/issues"
+ },
+ "homepage": "https://github.com/JakHuang/form-generator#readme"
+}
diff --git a/yudao-admin-ui/src/utils/render/render.js b/yudao-admin-ui/src/utils/render/render.js
new file mode 100644
index 000000000..f3325dcdf
--- /dev/null
+++ b/yudao-admin-ui/src/utils/render/render.js
@@ -0,0 +1,122 @@
+import { deepClone } from '@/utils/index'
+
+const componentChild = {}
+/**
+ * 将./slots中的文件挂载到对象componentChild上
+ * 文件名为key,对应JSON配置中的__config__.tag
+ * 文件内容为value,解析JSON配置中的__slot__
+ */
+const slotsFiles = require.context('./slots', false, /\.js$/)
+const keys = slotsFiles.keys() || []
+keys.forEach(key => {
+ const tag = key.replace(/^\.\/(.*)\.\w+$/, '$1')
+ const value = slotsFiles(key).default
+ componentChild[tag] = value
+})
+
+function vModel(dataObject, defaultValue) {
+ dataObject.props.value = defaultValue
+
+ dataObject.on.input = val => {
+ this.$emit('input', val)
+ }
+}
+
+function mountSlotFiles(h, confClone, children) {
+ const childObjs = componentChild[confClone.__config__.tag]
+ if (childObjs) {
+ Object.keys(childObjs).forEach(key => {
+ const childFunc = childObjs[key]
+ if (confClone.__slot__ && confClone.__slot__[key]) {
+ children.push(childFunc(h, confClone, key))
+ }
+ })
+ }
+}
+
+function emitEvents(confClone) {
+ ['on', 'nativeOn'].forEach(attr => {
+ const eventKeyList = Object.keys(confClone[attr] || {})
+ eventKeyList.forEach(key => {
+ const val = confClone[attr][key]
+ if (typeof val === 'string') {
+ confClone[attr][key] = event => this.$emit(val, event)
+ }
+ })
+ })
+}
+
+function buildDataObject(confClone, dataObject) {
+ Object.keys(confClone).forEach(key => {
+ const val = confClone[key]
+ if (key === '__vModel__') {
+ vModel.call(this, dataObject, confClone.__config__.defaultValue)
+ } else if (dataObject[key] !== undefined) {
+ if (dataObject[key] === null
+ || dataObject[key] instanceof RegExp
+ || ['boolean', 'string', 'number', 'function'].includes(typeof dataObject[key])) {
+ dataObject[key] = val
+ } else if (Array.isArray(dataObject[key])) {
+ dataObject[key] = [...dataObject[key], ...val]
+ } else {
+ dataObject[key] = { ...dataObject[key], ...val }
+ }
+ } else {
+ dataObject.attrs[key] = val
+ }
+ })
+
+ // 清理属性
+ clearAttrs(dataObject)
+}
+
+function clearAttrs(dataObject) {
+ delete dataObject.attrs.__config__
+ delete dataObject.attrs.__slot__
+ delete dataObject.attrs.__methods__
+}
+
+function makeDataObject() {
+ // 深入数据对象:
+ // https://cn.vuejs.org/v2/guide/render-function.html#%E6%B7%B1%E5%85%A5%E6%95%B0%E6%8D%AE%E5%AF%B9%E8%B1%A1
+ return {
+ class: {},
+ attrs: {},
+ props: {},
+ domProps: {},
+ nativeOn: {},
+ on: {},
+ style: {},
+ directives: [],
+ scopedSlots: {},
+ slot: null,
+ key: null,
+ ref: null,
+ refInFor: true
+ }
+}
+
+export default {
+ props: {
+ conf: {
+ type: Object,
+ required: true
+ }
+ },
+ render(h) {
+ const dataObject = makeDataObject()
+ const confClone = deepClone(this.conf)
+ const children = this.$slots.default || []
+
+ // 如果slots文件夹存在与当前tag同名的文件,则执行文件中的代码
+ mountSlotFiles.call(this, h, confClone, children)
+
+ // 将字符串类型的事件,发送为消息
+ emitEvents.call(this, confClone)
+
+ // 将json表单配置转化为vue render可以识别的 “数据对象(dataObject)”
+ buildDataObject.call(this, confClone, dataObject)
+
+ return h(this.conf.__config__.tag, dataObject, children)
+ }
+}
diff --git a/yudao-admin-ui/src/utils/render/slots/el-button.js b/yudao-admin-ui/src/utils/render/slots/el-button.js
new file mode 100644
index 000000000..a2d9684eb
--- /dev/null
+++ b/yudao-admin-ui/src/utils/render/slots/el-button.js
@@ -0,0 +1,5 @@
+export default {
+ default(h, conf, key) {
+ return conf.__slot__[key]
+ }
+}
diff --git a/yudao-admin-ui/src/utils/render/slots/el-checkbox-group.js b/yudao-admin-ui/src/utils/render/slots/el-checkbox-group.js
new file mode 100644
index 000000000..0a85c8e75
--- /dev/null
+++ b/yudao-admin-ui/src/utils/render/slots/el-checkbox-group.js
@@ -0,0 +1,13 @@
+export default {
+ options(h, conf, key) {
+ const list = []
+ conf.__slot__.options.forEach(item => {
+ if (conf.__config__.optionType === 'button') {
+ list.push({item.label})
+ } else {
+ list.push({item.label})
+ }
+ })
+ return list
+ }
+}
diff --git a/yudao-admin-ui/src/utils/render/slots/el-input.js b/yudao-admin-ui/src/utils/render/slots/el-input.js
new file mode 100644
index 000000000..8bd02db2a
--- /dev/null
+++ b/yudao-admin-ui/src/utils/render/slots/el-input.js
@@ -0,0 +1,8 @@
+export default {
+ prepend(h, conf, key) {
+ return {conf.__slot__[key]}
+ },
+ append(h, conf, key) {
+ return {conf.__slot__[key]}
+ }
+}
diff --git a/yudao-admin-ui/src/utils/render/slots/el-radio-group.js b/yudao-admin-ui/src/utils/render/slots/el-radio-group.js
new file mode 100644
index 000000000..c78506f9a
--- /dev/null
+++ b/yudao-admin-ui/src/utils/render/slots/el-radio-group.js
@@ -0,0 +1,13 @@
+export default {
+ options(h, conf, key) {
+ const list = []
+ conf.__slot__.options.forEach(item => {
+ if (conf.__config__.optionType === 'button') {
+ list.push({item.label})
+ } else {
+ list.push({item.label})
+ }
+ })
+ return list
+ }
+}
diff --git a/yudao-admin-ui/src/utils/render/slots/el-select.js b/yudao-admin-ui/src/utils/render/slots/el-select.js
new file mode 100644
index 000000000..cbf4a2030
--- /dev/null
+++ b/yudao-admin-ui/src/utils/render/slots/el-select.js
@@ -0,0 +1,9 @@
+export default {
+ options(h, conf, key) {
+ const list = []
+ conf.__slot__.options.forEach(item => {
+ list.push()
+ })
+ return list
+ }
+}
diff --git a/yudao-admin-ui/src/utils/render/slots/el-upload.js b/yudao-admin-ui/src/utils/render/slots/el-upload.js
new file mode 100644
index 000000000..8ce3c351c
--- /dev/null
+++ b/yudao-admin-ui/src/utils/render/slots/el-upload.js
@@ -0,0 +1,17 @@
+export default {
+ 'list-type': (h, conf, key) => {
+ const list = []
+ const config = conf.__config__
+ if (conf['list-type'] === 'picture-card') {
+ list.push()
+ } else {
+ list.push({config.buttonText})
+ }
+ if (config.showTip) {
+ list.push(
+
只能上传不超过 {config.fileSize}{config.sizeUnit} 的{conf.accept}文件
+ )
+ }
+ return list
+ }
+}
diff --git a/yudao-admin-ui/src/views/bpm/form/index.vue b/yudao-admin-ui/src/views/bpm/form/index.vue
index 9abb7cef3..f2998c963 100644
--- a/yudao-admin-ui/src/views/bpm/form/index.vue
+++ b/yudao-admin-ui/src/views/bpm/form/index.vue
@@ -38,6 +38,8 @@
+ 详情
修改
+
+
+
+
+