guns-separation-ent企业版中工作流表单动态数据实现

1、背景

guns企业版本的工作流暂不支持动态数据,但应该是在开发的计划中,由于项目中要用到动态数据,后期又打算继续跟进guns的企业版本升级,所以本着尽量少动官方源码的前提下实现,工作流表单数据的实现。

2、介绍

首先guns工作流表单,前端用的是开源的k-form-build,数据库中存的是json数据,然后用这个插件进行解析;简单的看了一下,这个开源的表单设计器是支持动态数据加载的(http://kcz66.gitee.io/k-form-design/#/zh-cn/field/treeSelect),看了一下guns这部分的业务,其实后端原有的工作流业务是不需要动的,只要把前端的动态数据加载实现了就可以了。最终问题的定位主要在于:dynamicData="dynamicData"这行代码中。换言之,只要页面在渲染之前,后端将数据给到dynamicData这个变量就可以了。

3、前端实现

1、找到guns关于表单使用这个插件的地方:

src/views/flwoable/draftapply/createForm.vue (表单填写页面)

src/views/flwoable/applyed/seeForm.vue (追踪的页面)

src/views/flwoable/task/taskForm.vue(审批的页面)

2、src/views/flwoable/draftapply/createForm.vue 修改如下(新增和修改的代码我已经在下面的代码上标注了)

<template>
  <a-card
    :bordered="false"
    :loading="cardLoading"
  >
    <a-spin :spinning="spinningLoading">
      <div>
        <a-button class="but_item" type="dashed" @click="rollbackPage" icon="rollback">返回</a-button>
        <a-button class="but_item" type="primary" @click="handleSubmit">发布</a-button>
        <a-button class="but_item" @click="handleApplyed" v-if="hasPerm('flowableDraft:addOrUpdate')">存为草稿</a-button>
        <a-button class="but_item" @click="handleReset" >重置</a-button>
        <a-button class="but_item" @click="$refs.tracking.tracking(recordData.processDefinitionId)" v-if="hasPerm('flowableDefinition:trace')">流程图</a-button>
      </div>
      <!--start:此处有修改::dynamicData="dynamicData" -->
      <k-form-build ref="kfb" :dynamicData="dynamicData" :value="jsonData"/>
      <!--end:此处有修改::dynamicData="dynamicData" -->
      <tracking ref="tracking" v-if="hasPerm('flowableDefinition:trace')"/>
    </a-spin>
  </a-card>
</template>
<script>
  import { formStartFormData } from '@/api/modular/flowable/formManage'
  import { handleTaskStart } from '@/api/modular/flowable/handleTaskManage'
  import { draftAdd } from '@/api/modular/flowable/draftManage'
  import tracking from '../defenition/tracking'
  import { createdFormInitData } from '@/api/modular/main/extend/flow' // 此处为新增接口
  export default {
    components: {
      tracking
    },
    data () {
      return {
        // +++++++++++++++++++++开始++++++++此处代码有修改:新增dynamicData: {},++++++++++++++++++++
        dynamicData: {},
        // +++++++++++++++++++++结束++++++++此处代码有修改:新增dynamicData: {},++++++++++++++++++++
        jsonData: {},
        visible: false,
        confirmLoading: false,
        cardLoading: false,
        processDefinitionId: '',
        spinningLoading: false,
        recordData: {}
      }
    },
    methods: {
      /**
       * 初始化方法
       */
      open (record) {
        this.recordData = record
        this.processDefinitionId = record.processDefinitionId
        this.formStartFormData(record)
      },
      /**
       * 获取预加载表单的数据
       */
      formStartFormData (record) {
        this.cardLoading = true

        // ++++++++++++++++++++++++++新增动态数据代码++++++++++++++开始++++++++++++++++++++++++++
        createdFormInitData(record).then(res => {
          if (res.success) {
            if (res.data !== undefined && res.data !== null && res.data !== '') {
              this.dynamicData = res.data
            }
          } else {
            this.$message.error(res.message)
          }
        })
        // ++++++++++++++++++++++++++新增动态数据代码++++++++++++++结束++++++++++++++++++++++++++

        formStartFormData({ processDefinitionId: record.processDefinitionId }).then((res) => {
          this.cardLoading = false
          if (res.success) {
            this.jsonData = JSON.parse(res.data)
            if (record.formData != null) {
              setTimeout(() => {
                this.$refs.kfb.setData(JSON.parse(record.formData))
              }, 100)
            }
          } else {
            this.$message.error(res.message)
            this.returnPage()
          }
        })
      },
      /**
       * 提交表单
       */
      handleSubmit () {
        this.$refs.kfb.getData().then(values => {
          const formData = {}
          formData.formData = JSON.stringify(values)
          const subReq = {}
          subReq.processDefinitionId = this.processDefinitionId
          subReq.variables = formData
          this.spinningLoading = true
          handleTaskStart(subReq).then((res) => {
            this.spinningLoading = false
            if (res.success) {
              this.$message.success('发起成功')
              this.returnPage()
            } else {
              this.$message.error('发起失败:' + res.message)
            }
          })
        }).catch(() => {
          // console.log('验证未通过,获取失败')
        })
      },
      /**
       * 存为草稿
       */
      handleApplyed () {
        this.$refs.kfb.getData().then(values => {
          const params = {
            processDefinitionId: this.recordData.processDefinitionId,
            formJson: JSON.stringify(this.jsonData),
            processName: this.recordData.name === undefined ? this.recordData.processName : this.recordData.name,
            category: this.recordData.category,
            categoryName: this.recordData.categoryName,
            formData: JSON.stringify(values)
          }
          this.spinningLoading = true
          draftAdd(params).then((res) => {
            if (res.success) {
              this.$message.success('存为草稿成功')
              this.returnPage()
            } else {
              this.$message.error('存为草稿失败:' + res.message)
            }
          }).finally(res => {
            this.spinningLoading = false
          })
        }).catch(() => {
          // console.log('验证未通过,获取失败')
        })
      },
      /**
       * 返回并清空已生成的表单
       */
      returnPage () {
        const recordId = this.recordData.id
        this.$emit('close', recordId)
        this.jsonData = {}
        this.recordData = {}
      },
      /**
       * 正常返回
       */
      rollbackPage () {
        this.$emit('rollback')
        this.jsonData = {}
        this.recordData = {}
      },
      /**
       * 重置表单
       */
      handleReset () {
        this.$refs.kfb.reset()
      }
    }
  }
</script>
<style>
  .but_item{
    margin-right: 8px;
    margin-bottom: 10px;
  }
</style>

3、src/views/flwoable/applyed/seeForm.vue 修改如下(新增和修改的代码我已经在下面的代码上标注了)

<template>
  <a-modal
    :width="1200"
    :visible="visible"
    :confirmLoading="confirmLoading"
    :footer="null"
    @cancel="handleCancel"
  >
    <a-card
      :bordered="false"
      :loading="cardLoading"
    >
      <!--start:此处有修改::dynamicData="dynamicData" -->
      <k-form-build ref="kfb" :dynamicData="dynamicData" :value="jsonData"/>
      <!--end:此处有修改::dynamicData="dynamicData" -->
    </a-card>
  </a-modal>
</template>
<script>
  import { formgGlobalFormData } from '@/api/modular/flowable/formManage'
  import { flowableInstanceFormData } from '@/api/modular/flowable/instanceManage'
  import { seeFormInitData } from '@/api/modular/main/extend/flow'
  export default {
    data () {
      return {
        // +++++++++++++++++++++开始++++++++此处代码有修改:新增dynamicData: {},++++++++++++++++++++
        dynamicData: {},
        // +++++++++++++++++++++结束++++++++此处代码有修改:新增dynamicData: {},++++++++++++++++++++
        jsonData: {},
        visible: false,
        confirmLoading: false,
        cardLoading: false
      }
    },
    methods: {
      /**
       * 初始化方法
       */
      seeOpen (record) {
        this.visible = true
        this.cardLoading = true
        this.formgGlobalFormData(record)
      },
      /**
       * 获取表单数据
       */
      formgGlobalFormData (record) {
        // ++++++++++++++++++++++++++新增动态数据代码++++++++++++++开始++++++++++++++++++++++++++
        const parameter = { processDefinitionId: record.procDef.id }
        seeFormInitData(parameter).then(res => {
          if (res.success) {
            if (res.data !== undefined && res.data !== null && res.data !== '') {
              this.dynamicData = res.data
            }
          } else {
            this.$message.error(res.message)
          }
        })
        // ++++++++++++++++++++++++++新增动态数据代码++++++++++++++结束++++++++++++++++++++++++++

        const params = { processDefinitionId: record.procDef.id }
        formgGlobalFormData(params).then((res) => {
          if (res.success) {
            this.jsonData = JSON.parse(res.data)
            this.flowableInstanceFormData(record)
          } else {
            this.cardLoading = false
            this.$message.error(res.message)
          }
        })
      },
      /**
       * 流程实例中表单的数据
       */
      flowableInstanceFormData (record) {
        const params = { id: record.id }
        flowableInstanceFormData(params).then((res) => {
          this.cardLoading = false
          if (res.success) {
            if (res.data.formData === undefined) {
              this.$message.warning('未找到表单数据')
            } else {
              setTimeout(() => {
                this.$refs.kfb.setData(JSON.parse(res.data.formData))
              }, 100)
            }
          } else {
            this.$message.error(res.message)
          }
        })
      },
      /**
       * 关闭界面,置空表单
       */
      handleCancel () {
        this.jsonData = {}
        this.visible = false
      }
    }
  }
</script>

4、src/views/flwoable/task/taskForm.vue 修改如下(新增和修改的代码我已经在下面的代码上标注了)

<template>
  <a-card
    :bordered="false"
    :loading="cardLoading"
  >
    <a-spin :spinning="spinningLoading">
      <div>
        <a-button class="but_item" type="dashed" @click="returnPage" icon="rollback" :loading="butLoading">返回</a-button>
        <a-button class="but_item" @click="handleOpenSubmit" :disabled="buttonList.submit === 'N'" type="primary" icon="check">提交</a-button>
        <a-button class="but_item" @click="handleSave" :disabled="buttonList.save === 'N'">保存</a-button>
        <a-button class="but_item" @click="handleOpenBack" :disabled="buttonList.back === 'N'">退回</a-button>
        <a-button class="but_item" @click="handleOpenTurn" :disabled="buttonList.turn === 'N'">转办</a-button>
        <a-button class="but_item" @click="handleOpenEntrust" :disabled="buttonList.entrust === 'N'">委托</a-button>
        <a-button class="but_item" @click="handleOpenEnd" :disabled="buttonList.end === 'N'">终止</a-button>
        <a-button class="but_item" @click="$refs.tracking.tracking(recordData.procIns.id)" :disabled="buttonList.trace === 'N'">追踪</a-button>
        <a-popconfirm placement="top" :title="'确定挂起该任务?'" @confirm="() => handleSuspend()">
          <a-button class="but_item" :disabled="buttonList.suspend === 'N'">挂起</a-button>
        </a-popconfirm>
        <a-button class="but_item" @click="handleOpenJump" :disabled="buttonList.jump === 'N'">跳转</a-button>
        <a-button class="but_item" @click="handleOpenAddSign" :disabled="buttonList.addSign === 'N'">加签</a-button>
        <a-button class="but_item" @click="handleOpenDeleteSign" :disabled="buttonList.deleteSign === 'N'">减签</a-button>
        <a-button class="but_item" @click="handlePrintRow" >打印</a-button>
      </div>
      <div>
        <submit ref="submit" @close="returnPage" v-if="buttonList.submit === 'Y'"/>
        <back ref="back" @close="returnPage" v-if="buttonList.back === 'Y'"/>
        <turn ref="turn" @close="returnPage" v-if="buttonList.turn === 'Y'"/>
        <entrust ref="entrust" @close="returnPage" v-if="buttonList.entrust === 'Y'"/>
        <end ref="end" @close="returnPage" v-if="buttonList.end === 'Y'"/>
        <tracking ref="tracking" v-if="buttonList.trace === 'Y'"/>
        <jump ref="jump" @close="returnPage" v-if="buttonList.jump === 'Y'"/>
        <add-sign ref="addSign" @close="returnPage" v-if="buttonList.addSign === 'Y'"/>
        <delete-sign ref="deleteSign" @close="returnPage" v-if="buttonList.deleteSign === 'Y'"/>
      </div>
      <div id="printDiv">
        <!--start:此处有修改::dynamicData="dynamicData" -->
        <k-form-build ref="kfb" :dynamicData="dynamicData" :value="jsonData"/>
        <!--end:此处有修改::dynamicData="dynamicData" -->
      </div>
    </a-spin>
  </a-card>
</template>

<script>
  import { formTaskFormData } from '@/api/modular/flowable/formManage'
  import { handleTaskSave, handleTaskTaskData, handleTaskSuspend } from '@/api/modular/flowable/handleTaskManage'
  import { buttonTrace } from '@/api/modular/flowable/buttonManage'
  import Print from 'print-js'
  // 导入按钮功能的界面
  import submit from '../handleTask/submit'
  import back from '../handleTask/back'
  import turn from '../handleTask/turn'
  import entrust from '../handleTask/entrust'
  import end from '../handleTask/end'
  // import trackingForm from '../todoTask/trackingForm'
  import tracking from '../../tracking/tracking'
  import jump from '../handleTask/jump'
  import addSign from '../handleTask/addSign'
  import deleteSign from '../handleTask/deleteSign'
  import { taskFormInitData } from '@/api/modular/main/extend/flow'

  export default {
    components: {
      submit,
      back,
      turn,
      entrust,
      end,
      tracking,
      jump,
      addSign,
      deleteSign
    },
    data () {
      return {
        // +++++++++++++++++++++开始++++++++此处代码有修改:新增dynamicData: {},++++++++++++++++++++
        dynamicData: {},
        // +++++++++++++++++++++结束++++++++此处代码有修改:新增dynamicData: {},++++++++++++++++++++
        jsonData: {},
        visible: false,
        confirmLoading: false,
        spinningLoading: false,
        cardLoading: false,
        processDefinitionId: '',
        butLoading: false,
        buttonList: {},
        recordData: []
      }
    },
    methods: {
      /**
       * 初始化方法
       */
      open (record) {
        this.recordData = record
        this.formTaskFormDataTaskData(record)
        this.buttonTrace(record)
      },
      /**
       * 当前任务的任务表单及数据
       */
      formTaskFormDataTaskData (record) {
        this.cardLoading = true

        // ++++++++++++++++++++++++++新增动态数据代码++++++++++++++开始++++++++++++++++++++++++++
        const parameter = { processDefinitionId: record.procIns.procDef.id }
        taskFormInitData(parameter).then(res => {
          if (res.success) {
            if (res.data !== undefined && res.data !== null && res.data !== '') {
              this.dynamicData = res.data
            }
          } else {
            this.$message.error(res.message)
          }
        })
        // ++++++++++++++++++++++++++新增动态数据代码++++++++++++++结束++++++++++++++++++++++++++

        const values = {}
        values.processDefinitionId = record.procIns.procDef.id
        values.actId = record.activityId
        formTaskFormData(values).then((res) => {
          this.cardLoading = false
          if (res.success) {
            this.spinningLoading = true
            this.jsonData = JSON.parse(res.data)
            handleTaskTaskData({ taskId: record.id }).then((res) => {
              this.spinningLoading = false
              if (res.success) {
                this.$refs.kfb.setData(JSON.parse(res.data.formData))
              } else {
                this.$message.error(res.message)
              }
            })
          } else {
            this.$message.error(res.message)
            this.returnPage()
          }
        // eslint-disable-next-line handle-callback-err
        }).catch(err => {
          this.jsonData = {}
        })
      },
      /**
       * 获取当前任务的按钮
       */
      buttonTrace (record) {
        buttonTrace({ actId: record.activityId }).then((res) => {
          this.buttonList = res.data
        })
      },
      /**
       * 返回并清空已生成的表单
       */
      returnPage () {
        this.$emit('close')
        this.jsonData = {}
      },
      handleOpenSubmit () {
        this.$refs.kfb.getData().then(values => {
          const formData = {}
          formData.formData = JSON.stringify(values)
          this.$refs.submit.open(this.recordData, this.buttonList, formData)
        }).catch(() => {})
      },
      /**
       * 保存
       */
      handleSave () {
        this.$refs.kfb.getData().then(values => {
          values.processDefinitionId = this.recordData.processDefinitionId
          this.spinningLoading = true
          const formData = {}
          formData.formData = JSON.stringify(values)
          const req = {}
          req.taskId = this.recordData.id
          req.variables = formData
          handleTaskSave(req).then((res) => {
            this.spinningLoading = false
            if (res.success) {
              this.$message.success('保存成功')
              this.returnPage()
            } else {
              this.$message.error('保存失败:' + res.message)
            }
          })
        }).catch(() => {
          // console.log('验证未通过,获取失败')
        })
      },
      handleOpenBack () {
        this.$refs.back.open(this.recordData)
      },
      handleOpenTurn () {
        this.$refs.turn.open(this.recordData)
      },
      handleOpenEntrust () {
        this.$refs.entrust.open(this.recordData)
      },
      handleOpenEnd () {
        this.$refs.end.open(this.recordData)
      },
      handleSuspend () {
        this.spinningLoading = true
        handleTaskSuspend({ taskId: this.recordData.id }).then((res) => {
          this.spinningLoading = false
          if (res.success) {
            this.$message.success('挂起成功')
            this.returnPage()
          } else {
            this.$message.error('挂起失败:' + res.message)
          }
        })
      },
      handleOpenJump () {
        this.$refs.jump.open(this.recordData)
      },
      handleOpenAddSign () {
        this.$refs.addSign.open(this.recordData)
      },
      handleOpenDeleteSign () {
        this.$refs.deleteSign.open(this.recordData)
      },
      handlePrintRow (index, row) {
        Print({ printable: 'printDiv', type: 'html', targetStyles: ['*'] })
      }
    }
  }
</script>
<style>
  .but_item{
    margin-right: 10px;
    margin-bottom: 20px;
  }
</style>

5、新增代码axios接口部分(/api/modular/main/extend/flow)这是我放接口的地方,官方是推荐放在main下面的,为了将来升级用

import { axios } from '@/utils/request'

/**
 * 创建form初始化数据
 *
 * @author yubaoshan
 * @date 2020/4/26 12:08
 */
export function createdFormInitData (parameter) {
  return axios({
    url: '/flow/formInitData/createdFormInitData',
    method: 'get',
    params: parameter
  })
}

/**
 * 查看form初始化数据
 *
 * @author yubaoshan
 * @date 2020/4/26 12:08
 */
export function seeFormInitData (parameter) {
  return axios({
    url: '/flow/formInitData/seeFormInitData',
    method: 'get',
    params: parameter
  })
}

/**
 * 任务form初始化数据
 *
 * @author yubaoshan
 * @date 2020/4/26 12:08
 */
export function taskFormInitData (parameter) {
  return axios({
    url: '/flow/formInitData/taskFormInitData',
    method: 'get',
    params: parameter
  })
}

改完你会发现,都是改的一样的地方,唯一不一样的地方就是,请求的接口部分是不一样的;这个地方要特别说明一下,如果你想将动态数据都用一套的话,那么就用一个接口就可以了,而我这个地方之所以写了三个接口是增加灵活度

4、后端实现

后端原理我简单的说一下,就是想将来随便用户在什么地方写这个动态数据的实现都可以,只要继承了相关的接口就可以了。想了一下,后台选了简单的工厂设计模式;大概的思想就是有一个动态数据的生产工厂根据不同的参数生产出不同的数据产品(也就是前端要的数据dynamicData)。

1、新增所有代码结构

2、数据产品接口:DataProduct.java

package cn.stylefeng.guns.extend.flow.config;

import cn.stylefeng.guns.extend.flow.model.param.CreateFormParam;
import cn.stylefeng.guns.extend.flow.model.param.SeeFormParam;
import cn.stylefeng.guns.extend.flow.model.param.TaskFormParam;

public interface DataProduct {
    Object createdFormInitData(CreateFormParam createFormParam);

    Object seeFormInitData(SeeFormParam seeFormParam);

    Object taskFormInitData(TaskFormParam taskFormParam);
}

3、数据生产工厂 SimpleDataFactory.java

package cn.stylefeng.guns.extend.flow.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Map;

@Component
@Data
@ConfigurationProperties(prefix = "k-form-build")
public class SimpleDataFactory {

    private Map<String,String> initDataMethod;

    public Object makeDataProduct(String processDefinitionId) throws Exception {
        Object obj = null;
        String className = initDataMethod.get(processDefinitionId);
        if(!StringUtils.isEmpty(className)){
            obj = Class.forName(className).newInstance();
        }
        return obj;
    }
}

4、上面一你会看到,我实际上在取配置文件中的数据,然后根据配置文件的数据放到了一个map中,然后根据流程定义的id,动态创建实例;配置文件我是放到了application.yml中了,内容如下

#以下为新增配置
k-form-build:
  initDataMethod:
    "[leave:1:1294922085572947969]": "cn.stylefeng.guns.modular.service.TestFlow"

5、controller

package cn.stylefeng.guns.extend.flow.controller;

import cn.stylefeng.guns.core.annotion.BusinessLog;
import cn.stylefeng.guns.core.enums.LogAnnotionOpTypeEnum;
import cn.stylefeng.guns.core.pojo.response.ResponseData;
import cn.stylefeng.guns.core.pojo.response.SuccessResponseData;
import cn.stylefeng.guns.extend.flow.model.param.CreateFormParam;
import cn.stylefeng.guns.extend.flow.model.param.SeeFormParam;
import cn.stylefeng.guns.extend.flow.model.param.TaskFormParam;
import cn.stylefeng.guns.extend.flow.service.FormInitDataService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/flow/formInitData")
public class FormInitDataController {

    @Resource
    private FormInitDataService formInitDataService;

    @GetMapping("/createdFormInitData")
    @BusinessLog(title = "表单数据初始化", opType = LogAnnotionOpTypeEnum.QUERY)
    public ResponseData createdFormInitData(CreateFormParam createFormParam) {
        return new SuccessResponseData(formInitDataService.createdFormInitData(createFormParam));
    }

    @GetMapping("/seeFormInitData")
    @BusinessLog(title = "表单数据初始化", opType = LogAnnotionOpTypeEnum.QUERY)
    public ResponseData seeFormInitData(SeeFormParam seeFormParam) {
        return new SuccessResponseData(formInitDataService.seeFormInitData(seeFormParam));
    }

    @GetMapping("/taskFormInitData")
    @BusinessLog(title = "表单数据初始化", opType = LogAnnotionOpTypeEnum.QUERY)
    public ResponseData taskFormInitData(TaskFormParam taskFormParam) {
        return new SuccessResponseData(formInitDataService.taskFormInitData(taskFormParam));
    }
}

6、service

package cn.stylefeng.guns.extend.flow.service;

import cn.stylefeng.guns.extend.flow.model.param.CreateFormParam;
import cn.stylefeng.guns.extend.flow.model.param.SeeFormParam;
import cn.stylefeng.guns.extend.flow.model.param.TaskFormParam;

public interface FormInitDataService {
    Object createdFormInitData(CreateFormParam createFormParam);

    Object seeFormInitData(SeeFormParam seeFormParam);

    Object taskFormInitData(TaskFormParam taskFormParam);
}
package cn.stylefeng.guns.extend.flow.service.impl;

import cn.stylefeng.guns.core.exception.ServiceException;
import cn.stylefeng.guns.extend.flow.config.DataProduct;
import cn.stylefeng.guns.extend.flow.config.SimpleDataFactory;
import cn.stylefeng.guns.extend.flow.model.param.CreateFormParam;
import cn.stylefeng.guns.extend.flow.model.param.SeeFormParam;
import cn.stylefeng.guns.extend.flow.model.param.TaskFormParam;
import cn.stylefeng.guns.extend.flow.service.FormInitDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service
public class FormInitDataServiceImpl implements FormInitDataService {

    @Autowired
    private SimpleDataFactory simpleDataFactory;

    @Override
    public Object createdFormInitData(CreateFormParam createFormParam) {

        String processDefinitionId = createFormParam.getProcessDefinitionId();

        if(StringUtils.isEmpty(processDefinitionId)){
            throw new ServiceException(500, "参数异常:processDefinitionId空异常!");
        }

        Object data = null;
        try {
            Object obj = simpleDataFactory.makeDataProduct(processDefinitionId);
            if(!StringUtils.isEmpty(obj)){
                data = ((DataProduct) obj).createdFormInitData(createFormParam);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(500, "类加载异常:"+e.getMessage());
        }
        return data;
    }

    @Override
    public Object seeFormInitData(SeeFormParam seeFormParam) {

        String processDefinitionId = seeFormParam.getProcessDefinitionId();

        if(StringUtils.isEmpty(processDefinitionId)){
            throw new ServiceException(500, "参数异常:processDefinitionId空异常!");
        }

        Object data = null;
        try {
            Object obj = simpleDataFactory.makeDataProduct(processDefinitionId);
            if(!StringUtils.isEmpty(obj)){
                data = ((DataProduct) obj).seeFormInitData(seeFormParam);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(500, "类加载异常:"+e.getMessage());
        }
        return data;

    }

    @Override
    public Object taskFormInitData(TaskFormParam taskFormParam) {
        String processDefinitionId = taskFormParam.getProcessDefinitionId();

        if(StringUtils.isEmpty(processDefinitionId)){
            throw new ServiceException(500, "参数异常:processDefinitionId空异常!");
        }

        Object data = null;
        try {
            Object obj = simpleDataFactory.makeDataProduct(processDefinitionId);
            if(!StringUtils.isEmpty(obj)){
                data = ((DataProduct) obj).taskFormInitData(taskFormParam);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(500, "类加载异常:"+e.getMessage());
        }
        return data;
    }
}

7、三个参数

package cn.stylefeng.guns.extend.flow.model.param;

import cn.stylefeng.guns.flowable.modular.shortcut.param.FlowableShortcutParam;
import lombok.Data;

@Data
public class CreateFormParam extends FlowableShortcutParam {
    /**
     * 流程定义id
     */
    private String processDefinitionId;
}
package cn.stylefeng.guns.extend.flow.model.param;

import lombok.Data;

@Data
public class SeeFormParam{
    /**
     * 流程定义id
     */
    private String processDefinitionId;
}
package cn.stylefeng.guns.extend.flow.model.param;

import lombok.Data;

@Data
public class TaskFormParam {
    /**
     * 流程定义id
     */
    private String processDefinitionId;
}

其实上面这部分代码,我觉得就没什么了,重点看一下service就可以了,就是通过数据工厂拿到产品的接口,然后调用响应的方法就可以了

 

8、使用:使用的时候很简单,你只要实现数据产品的接口,然后在配置文件里面将流程定义id与你的实现进行关联就可以了

5、演示

1、写一个测试实现类:

package cn.stylefeng.guns.modular.service;

import cn.hutool.core.lang.Console;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.extra.spring.SpringUtil;
import cn.stylefeng.guns.extend.flow.config.DataProduct;
import cn.stylefeng.guns.extend.flow.model.param.CreateFormParam;
import cn.stylefeng.guns.extend.flow.model.param.SeeFormParam;
import cn.stylefeng.guns.extend.flow.model.param.TaskFormParam;
import cn.stylefeng.guns.pc.crmbiz.entity.CrmBiz;
import cn.stylefeng.guns.pc.crmbiz.service.CrmBizService;
import com.zaxxer.hikari.HikariDataSource;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TestFlow implements DataProduct {
    @Override
    public Object createdFormInitData(CreateFormParam createFormParam) {
        // dept
//        dept: [
//        {
//            value: "1",
//            label: "树形选项1",
//            children: [
//            { value: "11", label: "树形选项1-1" },
//            { value: "12", label: "树形选项1-2" }
//            ]
//        },
//        {
//            value: "2",
//            label: "树形选项2",
//            children: [
//            { value: "21", label: "树形选项2-1" },
//            { value: "22", label: "树形选项2-2" }
//            ]
//        }
//        ]
        Map<String,Object> map = new HashMap<>();
        List<Object> list = new ArrayList<>();

        for(int i=0; i<100; i++){
            Map<String,Object> temp = new HashMap<>();
            temp.put("value","1"+i);
            temp.put("label","研发部"+i);
            list.add(temp);
        }


        map.put("dept",list);

        return map;
    }

    @Override
    public Object seeFormInitData(SeeFormParam seeFormParam) {
        Map<String,Object> map = new HashMap<>();
        List<Object> list = new ArrayList<>();

        for(int i=0; i<100; i++){
            Map<String,Object> temp = new HashMap<>();
            temp.put("value","1"+i);
            temp.put("label","研发部"+i);
            list.add(temp);
        }


        map.put("dept",list);

        return map;
    }

    @Override
    public Object taskFormInitData(TaskFormParam taskFormParam) {
        Map<String,Object> map = new HashMap<>();
        List<Object> list = new ArrayList<>();

        for(int i=0; i<100; i++){
            Map<String,Object> temp = new HashMap<>();
            temp.put("value","1"+i);
            temp.put("label","研发部"+i);
            list.add(temp);
        }


        map.put("dept",list);

        return map;
    }
}

这里面的dept与表单设计里面的动态数据名称要对应

2、application.yml配置

3、流程定义id找一下,从数据库中找一下,找这张表就能看到了

4、最终效果

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

<每天一点>

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值