自定义表单使用案例

2022/6/1 vue

# 第1步

  • 进入预设高级搜索菜单 img

  • 点击新增添加对应需要生成数据 img

  • 点击表单设计进入设计页面 img

  • 需要注意图片中条件预设及扩展字段中的java字段名字段标注(为数据库备注,可能需要进行修改)将作为标题字段名 img

# 第2步

  • 从左侧点击或拖拽组件到需要的位置,并在右侧对组件或表单进行配置(组件属性为当前选中的组件进行配置, 表单属性为整个表单进行配置),配置完成后点击保存进行保存 img

# 第3步

  • 在要使用的地方加入组件渲染
  • 示例1(带有提交按钮的表单)
<template>
  <div>
    <base-form-parser ref="refFormParser" :key="parserKey" :form-conf="formConf" @submit="onSubmit" />
  </div>
</template>

<script>
import { fillFormData } from '@/components/formGenerator/utils/index.js'

export default {
  data () {
    return {
      // 生成器key
      parserKey: Date.now(),
      formConf: {
        fields: []
      }
    }
  },
  created() {
    this.getParserFormConfig()
  },
  methods: {
    // 验证通过 提交的数据
    onSubmit(formData) {
      // formData
    },
    // 也可手动通过ref调用提交
    testSubmit() {
      // 返回2个参数(参数1为校验状态, 参数2位提交的数据) 如果校验通过也会激活该组件的submit事件
      this.$refs.refFormParser.submitForm()
    },
    getParserFormConfig() {
      // 此处finishType为高级搜索预设配置的url
      this.$http.get('/sys/finish/conf/info', { finishType: '/material/manage/manage/add' }).then(({ ext }) => {
        if (ext && ext.finishConf) {
          try {
            this.formConf = JSON.parse(ext.finishConf)
            this.parserKey = Date.now()

            // 如果是新增页 无需使用下行代码,如果为编辑页,需要在获取详情接口中放入下列代码,第二参数为键值对象,将自动渲染值
            // fillFormData(this.formConf.fields, {paramExt: {}, name: '测试', age: '18'})
            // this.parserKey = Date.now()
          } catch (e) {
            //
          }
        }
      })
    }
  }
}
</script>
  • 示例2(自定义表单和自己的数据公用, 此自定义表单配置如果在页面上部应不显示提交按钮,通过ref调用)
<template>
  <div>
    <base-form-parser ref="refFormParser" :key="parserKey" :form-conf="formConf" />


    <th-desc>
      <el-form ref="refForm" :model="formData" :rules="formRules">
        <div class="base-page-head">图文介绍</div>
        <th-desc-item label="物料描述" required>
          <el-form-item prop="productDesc">
            <th-editor v-model="formData.productDesc" width="100%" show-word-limit :maxlength="1500" :height="200" />
          </el-form-item>
        </th-desc-item>

        <div class="base-page-footer">
          <el-button type="primary" :loading="submitLoading" @click="submitBtn">保存</el-button>
        </div>
      </el-form>
    </th-desc>
  </div>
</template>

<script>
import { fillFormData } from '@/components/formGenerator/utils/index.js'

export default {
  data () {
    return {
      parserKey: Date.now(),
      formConf: {
        fields: []
      },
      submitLoading: false,
      formData: {
        productDesc: '',
      },
      formRules: {
        productDesc: { required: true, message: '请输入' }
      }
    }
  },
  created() {
    this.getParserFormConfig()
    this.getDetailsFn()
  },
  methods: {
    // 提交按钮
    submitBtn () {
      // 获取自定义表单的数据
      const { validStatus, parserFormData } = this.$refs.refFormParser.submitForm()

      // 校验不通过返回
      if (!validStatus) return

      this.$refs.refForm.validate((valid) => {
        if (valid) {
          // 转换合并值
          const params = { ...this.formData, ...parserFormData }
          params.fileIds = params.fild && params.fild.length ? params.fild.map(i => i.id) : []
          params.areaId = params.areaId && params.areaId.length ? params.areaId[params.areaId.length - 1] : ''

          delete params.fileIdsCopy
          delete params.areaIdCopy
          
          // 调用接口
          this.submitLoading = true
          this.$http.post('123213', params).then(res => {
            this.$message.success(res.msg)
            this.$router.push('/material/manage/manage/list')
          }).finally(() => {
            this.submitLoading = false
          })
        } else {
          this.$nextTick(() => {
            document.querySelector('.is-error input').focus()
          })
        }
      })
    },
    getParserFormConfig() {
      // 此处finishType为高级搜索预设配置的url
      this.$http.get('/sys/finish/conf/info', { finishType: '/material/manage/manage/add' }).then(({ ext }) => {
        if (ext && ext.finishConf) {
          try {
            this.formConf = JSON.parse(ext.finishConf)
            this.parserKey = Date.now()
          } catch (e) {
            //
          }
        }
      })
    },
    // 获取详情
    getDetailsFn () {
      this.$http.get({ productId: '123456' }).then(res => {
        const result = {paramExt: {}, ...res.ext}
        // 处理后台需要转换的数据
        result.fileIdsCopy = result.fild || []
        result.areaIdCopy = result.allAreaId ? result.allAreaId.split('-').map(v => parseInt(v)) : []
        result.classIdCopy = [result.classId]
        result.listSkuValue = []
        result.areaId = result.allAreaId ? result.allAreaId.split('-').map(v => parseInt(v)) : []

        this.formData = result

        fillFormData(this.formConf.fields, result)
        this.parserKey = Date.now()
      })
    },
  }
}
</script>
  • 示例3 详情页使用 只显示数据( 使用方法同表单base-form-parser组件一样)
<template>
  <div>
    <base-form-read :key="parserKey" :form-conf="formConf" />
  </div>
</template>

<script>
import { fillFormData } from '@/components/formGenerator/utils/index.js'

export default {
  data () {
    return {
      parserKey: Date.now(),
      formConf: {
        fields: []
      }
    }
  },
  created() {
    this.getParserFormConfig()
    this.getDetailsFn()
  },
  methods: {
    getParserFormConfig() {
      // 此处finishType为高级搜索预设配置的url
      this.$http.get('/sys/finish/conf/info', { finishType: '/material/manage/manage/add' }).then(({ ext }) => {
        if (ext && ext.finishConf) {
          try {
            this.formConf = JSON.parse(ext.finishConf)
            this.parserKey = Date.now()
          } catch (e) {
            //
          }
        }
      })
    },
    // 获取详情
    getDetailsFn () {
      this.$http.get({ productId: '123456' }).then(res => {
        const result = {paramExt: {}, ...res.ext}
        // 处理后台需要转换的数据
        result.fileIdsCopy = result.fild || []
        result.areaIdCopy = result.allAreaId ? result.allAreaId.split('-').map(v => parseInt(v)) : []
        result.classIdCopy = [result.classId]
        result.listSkuValue = []
        result.areaId = result.allAreaId ? result.allAreaId.split('-').map(v => parseInt(v)) : []

        this.formData = result

        fillFormData(this.formConf.fields, result)
        this.parserKey = Date.now()
      })
    },
  }
}
</script>

自定义表单后端操作

# 第4步

  • 服务需要引入mongondb的配置。如果没有引入,则需要在bootstrap里面引入服务配置 img

# 第5步

  • 引入mogondb的工具类FormUtils

img

  • 里面包含了操作db的方法

# 第6步

  • 接收自定义表单业务的实体需要继承SupperDTO

img

  • 其中的paramExt用于统一封装保存,和返还给前端的数据集

# 第7步

  • 1.保存扩展字段

img

  • 2.将包含扩展扩展字段的DTO作为数据源传入

  • 3.原则上以 业务类型+企业主键 作为唯一值来保存业务的扩展字段

img

  • 4.以业务主键来区分同一业务不同的扩展字段

img

# 第8步

  • 修改扩展字段FormUtil.update

img

  • 修改扩展字段是覆盖式操作,根据类型+企业主键+bizId删除原业务保存的扩展字段,再重新进行插入。

# 第9步

  • 查询扩展字段(列表+详情)

img