k-form-design-使用

成果

预览.gif

回显.gif

KFormDesign是什么

基于vue和ant-design-vue实现的表单设计器,样式使用less作为开发语言,主要功能是能通过简单操作来生成配置表单,生成可保存的JSON数据,并能将JSON还原成表单,使表单开发更简单更快速
KFormDesign主要分为两部分,k-form-design和k-form-build
k-form-design表单设计器,通过拖拽或点击设计生成表单json配置信息
k-form-build表单构建组件,将表单设计器生成的json数据构建成表单
官网:>https://www.kcz66.com/k-form-design/#/zh-cn/components/design
基本使用按照官网,讲的很详细

使用

我是先集成了源码,但是领导说不能集成源码,要为升级做考虑,然后又把它去了,功能实现没有动源码

1、前端用k-form-design作了表单设计器

2、后端把表单设计器生成的json数据存入数据库,表结构如下(重点)

DROP TABLE IF EXISTS `wf_form`;
CREATE TABLE `wf_form`  (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `code` VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '表单代号',
  `name` VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '表单名称',
  `type` TINYINT(2) NOT NULL DEFAULT 0 COMMENT '表单类型。0:简单表单;1:复杂表单;',
  `theme` VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '表单主题。不配置默认为表单名称',
  `design_data` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '表单设计数据。',
  `js_code` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '表单js代码。仅当复杂表单才有',
  `create_time` DATETIME(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` DATETIME(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = INNODB AUTO_INCREMENT = 10 CHARACTER SET = utf8  COMMENT = '表单设计表' ROW_FORMAT = DYNAMIC;

重点说下js_code字段

js_code这个字段是我从生成的design_data表单设计数据中提取出来的动态配置信息,这是重点,为后续的初始化事件,级联字段,切换字段做准备
不叨叨了,上代码

提取逻辑

private String splitJscode (String  designJson){
        // 定义规则
        String pattern = "(\"dynamicKey\":\")([^\"]+)(\")";
        //Pattern.compile函数
        Set sets =new HashSet<String>();
        Matcher matcher = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE).matcher(designJson);
        while (matcher.find()) { //表示往下遍历
            sets.add(matcher.group(2));
        }
        return String.join(",", sets);
    };

其实这个我是想,如果可以直接获取就好了,这个动态信息应该是必须要的,期待官网大大提供更好的方案,当然这个获取方法也很陋,欢迎分享更高效的提取方案

3、表单构建组件(重点)

初始化json信息

this.jsonData = JSON.parse(res.data.FORM_CONFIG_KEY.jsonData)

表单构建组件初始化配置信息

一个是获取DynamicData的动态配置信息,另一个是为了添加监控节点
associatedField

if (res.data.FORM_CONFIG_KEY.jsCode) {
              this.wkFormDynamicData(res.data.FORM_CONFIG_KEY.jsCode)
            }
wkFormDynamicData (jsCode) {
        if (jsCode) {
          this.dynamicData = {}
          this.associatedField = []
          const jsCodeArr = jsCode.split(',')
          window.console.log(jsCodeArr)
          jsCodeArr.forEach(dynamicValue => {
            const typedata = dynamicValue.split('-')
            if (typedata[0] === 'dict') {
              this.SysDictTypeDropDown(typedata[1]).then((res) => {
                const dictArr = []
                res.data.forEach(dict => dictArr.push({ value: dict.code, label: dict.value }))
                this.$set(this.dynamicData, dynamicValue, dictArr)
              })
              if (typedata[2]) {
                switch (typedata[2]) {
                  case 'switch': {
                    // switch 事件 dict-字典code-switch-监控节点字段-case字段值_case字段名|case字段值_case字段名
                    // 添加监控节点字段
                    this.associatedField.push({ associatedCode: typedata[3], key: dynamicValue, value: typedata })
                    break
                  }
                  default:
                  {
                    window.console.log('未定义事件' + typedata[2])
                  }
                }
              }
            } else if (typedata[0] === 'address_province') {
              this.SysTenantProvinceSelector().then((res) => {
                const addressArr = []
                res.forEach(province => {
                  addressArr.push({ value: province.code, label: province.name })
                })
                this.$set(this.dynamicData, dynamicValue, addressArr)
              }).catch((err) => {
                this.$message.error('启动错误:' + err.message)
              })
            } else if (typedata[0] === 'business_type') {
              // 添加监控字段
              this.SysTenantIndustryTypeSelector().then((res) => {
                const industryTypeArr = []
                res.forEach(industryType => {
                  industryTypeArr.push({ value: industryType.code, label: industryType.name })
                })
                this.$set(this.dynamicData, dynamicValue, industryTypeArr)
              }).catch((err) => {
                this.$message.error('启动错误:' + err.message)
              })
            } else if (typedata[0] === 'address_city' || typedata[0] === 'business_name') {
              // 子节点添加父节点监控,父节点变动获取子节点信息 子节点级联动态数据规范:子节点级联类型-父节点字段名-子节点字段名 父节点级联动态数据规范:父节点级联类型
              this.associatedField.push({ associatedCode: typedata[1], key: dynamicValue, value: typedata })
            }
          })
        }
      },

信息回显

先处理监控节点信息,再信息回显

setTimeout(() => {
              this.setDataInit(res.data.FORM_CONFIG_KEY.wkFormvalues)
            }, 10)
setDataInit(wkFormvalues) {
        window.console.log('wkFormvalues', wkFormvalues)
        // 表单回显初始化
        this.associatedField.forEach(item => {
          if (wkFormvalues[item.associatedCode]) {
            this.getSelectorInfo(item, wkFormvalues[item.associatedCode], item.associatedCode)
          }
        })
        // 表单回显
        this.$refs.kfb.setData(wkFormvalues)
        window.console.log('this.associatedField', this.associatedField)
        window.console.log('this.jsonData', this.jsonData)
        window.console.log('this.dynamicData', this.dynamicData)
      },

监控节点事件(主要是级联事件)

handleChange(value, key) {
        this.associatedField.forEach(item => this.getSelectorInfo(item, value, key))
      },
      getSelectorInfo(item, value, key, clearFlag) {
        if (item.associatedCode === key) {
          // 数据变化时触发
          if (item.value[0] === 'address_city') {
            // 父节点前清除关联信息
            if (clearFlag) {
              const json = {}
              json[item.value[2]] = ''
              this.$refs.kfb.setData(json)
            }
            // 存在
            this.SysTenantCitySelector(value).then((res) => {
              const cityArr = []
              res.forEach(city => {
                cityArr.push({ value: city.code, label: city.name })
              })
              this.$set(this.dynamicData, item.key, cityArr)
            })
          } else if (item.value[0] === 'business_name') {
            // 父节点前清除关联信息
            if (clearFlag) {
              const json = {}
              json[item.value[2]] = ''
              this.$refs.kfb.setData(json)
            }
            // 存在
            this.SysIndustrySelector(value).then((res) => {
              const industryArr = []
              res.forEach(industry => {
                industryArr.push({ value: industry.code, label: industry.name })
              })
              this.$set(this.dynamicData, item.key, industryArr)
            })
          } else if (item.value[0] === 'dict') {
            this.switchCase(item, value, key)
          }
        }
      },

动态节点切换关联事件(不知道这玩意叫啥,反正出现了这个场景,那就要开发)

      switchCase (item, value, key) {
        switch (item.value[2]) {
          case 'switch': {
            // switch 事件 dict-字典code-switch-监控节点字段-case字段值_case字段名|case字段值_case字段名
            if (value) {
              window.console.log('switch')
              item.value[4].split('|').forEach(switchCase => {
                const switchCaseSplit = switchCase.split('_')
                // case字段隐藏
                this.jsonData.list.forEach((datalist, datalistIndex) => {
                  if (datalist) {
                    if (datalist.type === 'tabs') {
                      datalist.columns.forEach((tabs, tabsIndex) => {
                        const listIndex = tabs.list.findIndex(modelInfo => modelInfo.model === switchCaseSplit[1])
                        if (listIndex > -1) {
                          this.jsonData.list[datalistIndex].columns[tabsIndex].list[listIndex].options.hidden = true
                          if (value === switchCaseSplit[0]) {
                            // 匹配case字段开启
                            this.jsonData.list[datalistIndex].columns[tabsIndex].list[listIndex].options.hidden = false
                          }
                        }
                      })
                    }
                  }
                })
              })
            }
            break
          }
          default:
          {
            window.console.log('未定义事件' + item.value[2])
          }
        }
      },

总结

k-form-design生成jsondata数据,通过抽取jscode获取动态数据
k-form-build根据jsondata构建表单
通过jscode生成dynamic-data选项控件的动态配置数据
并通过jscode获取监听节点通过change监控表单数据改变时触发事件
在通过setData回显数据

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容