项目实训-jeecg-boot+flowable开发示例

目录

项目详解

前端

API

组件

后端

FlowDefinitionController.java

FlowTaskController.java

FlowInstanceController.java

项目开发

流程图

创建数据库

后端

ExcApply包详解

前端

创建教师申请页面:

关联流程

申请(ActApplyBtn.vue)

重新提交(ActHandleBtn.vue):

撤销(ActCancelBtn.vue):

审批历史(ActHandleBtn.vue)


项目详解

前端

API

flowable/api/definition.js:实现流程定义相关操作的api,连接后端FlowDefinitionController.java中的方法

flowable/api/finished.js、flowable/api/process.js、flowable/api/tode.js:实现流程执行相关操作的api

组件

flowable/components/ActApplyBtn.vue:提交按钮(启动流程)

flowable/components/ActCancelBtn.vue:撤回(销毁流程)

flowable/components/ActHandleBtn.vue:处理流程(0 通过、退回节点:1 驳回、2 退回、3 重新提交)

flowable/components/ActHistoricDetailBtn.vue:审批处理历史

flowable/components/HistoricDetail.vue:审批处理历史页面组件

后端

FlowDefinitionController.java

flowable/controller/FlowDefinitionController.java:工作流程定义

例如:获取流程定义列表、导入流程文件、读取xml文件等

FlowTaskController.java

flowable/controller/FlowTaskController.java:工作流任务管理

例如:查看发起流程、取消申请、撤回流程、获取待办任务等

FlowInstanceController.java

flowable/controller/FlowInstanceController.java:工作流流程实例管理

例如:激活或挂起流程实例、删除流程实例

项目开发

首先要实现任课老师提交实验课授课方式申请的工作流

流程图

先用部署好的流程设计页面画好流程图:

创建流程图时要选好候选人员:

若有网关要写好网关的条件表达式(排他网关一定得写条件表达式):

创建数据库

利用Jeecg-boot Online表单在线开发功能,为老师申请实验课任课方式创建数据库exc_apply

生成代码包ExcApply

后端

ExcApply包详解

ExcApply/controller/ExcApplyController.java:完成后端相关操作例如添加、修改、删除、查询等)

 实现relationAct接口,使得申请能够关联上流程

@AutoLog(value = "关联流程")
@ApiOperation(value="关联流程", notes="关联流程")
@RequestMapping(value = "/relationAct",method = RequestMethod.GET)
public Result<?> relationAct(HttpServletRequest request,HttpServletResponse response){
	String dataId = request.getParameter("dataId");
	excApplyService.relationAct(dataId);
	return Result.OK();
}

ExcApply/entity/ExcApply.java:对应exc_apply数据库的属性类

ExcApply/mapper/xml/ExcApplyMapper.xml:数据库exc_apply的xml

ExcApply/mapper/ExcApplyMapper.java:对应任课老师申请授课方式model的属性类

为使用IPage和Page实现分页:

public interface ExcApplyMapper extends BaseMapper<ExCApply> {

    IPage<ExcApply> myPage(Page<ExcApply> page, @Param(Constants.WRAPPER) QueryWrapper<ExcApply> queryWrapper);
}

service/IExcApplyServiceImpl.java:服务接口

为使用IPage和Page实现分页:

public interface IExCApplyService extends IService<ExCApply> {
    IPage<ExcApply> myPage(Page<ExcApply> page, QueryWrapper<ExcApply> queryWrapper);

    void relationAct(String dataId);
}

service/impl/ExCApplyServiceImpl.java:

Service必须继承FlowCallBackServiceI接口并实现其方法

@Service("excApplyService")
public class ExcApplyServiceImpl extends ServiceImpl<ExcApplyMapper, ExcApply> implements IExcApplyService , FlowCallBackServiceI {

@Autowired
    FlowCommonService flowCommonService;
    /**
     * 初始生成业务与流程的关联信息<br/>
     * 当业务模块新增一条数据后调用,此时业务数据关联一个流程定义,以备后续流程使用
     * @return 是否成功
     * @param title 必填。流程业务简要描述。例:2021年11月26日xxxxx申请
     * @param dataId 必填。业务数据Id,如果是一对多业务关系,传入主表的数据Id
     * @param serviceImplName 必填。业务service注入spring容器的名称。
     *                        例如:@Service("demoService")则传入 demoService
     * @param processDefinitionKey 必填。流程定义Key,传入此值,未来启动的会是该类流程的最新一个版本
     * @param processDefinitionId 选填。流程定义Id,传入此值,未来启动的为指定版本的流程
     */

public void initActBusiness(String title, String dataId, String serviceImplName, String processDefinitionKey, String processDefinitionId){
        flowCommonService.initActBusiness(title,dataId,"exCApplyService","process_tpho5a4q","ExcApply:14:de1f495f-d7d9-11ec-9c5d-927841cf098b");
    }
    @Override
    public void relationAct(String dataId) {
        flowCommonService.initActBusiness("实验授课申请:dataId"+dataId,dataId,"excApplyService","process_tpho5a4q","process_tpho5a4q:4:32128f7c-ce77-11ec-843e-927841cf098b");
    }

    

    @Override
    public IPage<ExcApply> myPage(Page<ExcApply> page, QueryWrapper<ExcApply> queryWrapper) {
        return this.baseMapper.myPage(page,queryWrapper);
    }


    @Override
    public void afterFlowHandle(FlowMyBusiness business) {
        //流程操作后做些什么
        business.getTaskNameId();//接下来审批的节点
        business.getValues();//前端传进来的参数
        business.getActStatus();//流程状态 ActStatus.java
        //....其他
    }

    @Override
    public Object getBusinessDataById(String dataId) {
        return this.getById(dataId);
    }

    @Override
    public Map<String, Object> flowValuesOfTask(String taskNameId, Map<String, Object> values) {
        return null;
    }

    @Override
    public List<String> flowCandidateUsernamesOfTask(String taskNameId, Map<String, Object> values) {
        // 案例,写死了jeecg,实际业务中通过当前节点来判断下一个节点的候选人并写回到反参中,如果为null,流程模块会根据默认设置处理
        return Lists.newArrayList("jeecg");
    }

    @Override
    public boolean save(ExcApply excApply){
        /**新增数据,初始化流程关联信息**/
        excApply.setId(IdUtil.fastSimpleUUID());
        this.relationAct(excApply.getId());
        return super.save(excApply);
    }

    @Override
    public boolean removeById(Serializable id){
        /**删除数据,移除流程关联信息**/
        flowCommonService.delActBusiness(id.toString());
        return super.removeById(id);
    }

}

 所实现的方法afterFlowHandle将在流程处理过程中被回调,用以增强处理业务层业务逻辑(之后修改

@Override
    public void afterFlowHandle(FlowMyBusiness business) {
        //流程操作后做些什么
        business.getTaskNameId();//接下来审批的节点
        business.getValues();//前端传进来的参数
        business.getActStatus();//流程状态 ActStatus.java
        //....其他
    }

在业务数据新增时,必须初始化业务和流程间的关联,调用FlowCommonService.initActBusiness方法

 /**
     * 初始生成业务与流程的关联信息<br/>
     * 当业务模块新增一条数据后调用,此时业务数据关联一个流程定义,以备后续流程使用
     * @return 是否成功
     * @param title 必填。流程业务简要描述。例:2021年11月26日xxxxx申请
     * @param dataId 必填。业务数据Id,如果是一对多业务关系,传入主表的数据Id
     * @param serviceImplName 必填。业务service注入spring容器的名称。
     *                        例如:@Service("demoService")则传入 demoService
     * @param processDefinitionKey 必填。流程定义Key,传入此值,未来启动的会是该类流程的最新一个版本
     * @param processDefinitionId 选填。流程定义Id,传入此值,未来启动的为指定版本的流程
     */
    public void initActBusiness(String title, String dataId, String serviceImplName, String processDefinitionKey, String processDefinitionId){
        flowCommonService.initActBusiness(title,dataId,"exCApplyService","process_tpho5a4q","process_tpho5a4q:3:b18ae95d-ce02-11ec-8534-927841cf098b");
    }

删除业务数据时调用flowCommonService.delActBusiness(id.toString());

@Override
    public boolean removeById(Serializable id){
        /**删除数据,移除流程关联信息**/
        flowCommonService.delActBusiness(id.toString());
        return super.removeById(id);
    }

前端

创建教师申请页面:

 

关联流程

教师申请完首先得点击“关联流程”按钮,让其与流程相关联:

<a @click="relationAct(record)">关联流程</a>
relationAct(r){
          getAction("/ExcApply/excApply/relationAct",{dataId:r.id}).then(res=>{
              if(res.success){
                  this.$message.success("操作成功")
                  this.loadData()
              }else{
                  this.$message.error("操作失败")
              }
          })
        }

relationAct方法调用后端relationAct方法:

@AutoLog(value = "关联流程")
	 @ApiOperation(value="关联流程", notes="关联流程")
	 @RequestMapping(value = "/relationAct",method = RequestMethod.GET)
	 public Result<?> relationAct(HttpServletRequest request,HttpServletResponse response){
		 String dataId = request.getParameter("dataId");
		 excApplyService.relationAct(dataId);
		 return Result.OK();
	 }

申请(ActApplyBtn.vue)

然后点击申请按钮提交申请:

必须传入流程需要的variables,如此流程之后是一个排他网关,${isNeeded == 'true'}为此网关的跳转条件,所以需要传入isNeeded来判断走哪一条路

 <act-apply-btn @success="loadData" :data-id="record.id" :variables="{isNeeded:record.needextea}"></act-apply-btn>

调用ActApplyBtn组件,此组件添加点击事件,调用definitionStartByDataId方法:

import {definitionStartByDataId} from "@views/flowable/api/definition";
applySubmit() {
            if (this.dataId && this.dataId.length < 1) {
                this.error = '必须传入参数dataId';
                this.$message.error(this.error);
                return;
            } else {
                this.error = '';
            }
            this.submitLoading = true;
            var params = Object.assign({
                dataId: this.dataId
            }, this.variables);
            console.log(params);
          definitionStartByDataId(this.dataId, params)
                .then(res => {
                    if (res.success) {
                        this.$message.success('操作成功');
                        this.$emit('success');
                    } else {
                        this.$message.error(res.message);
                    }
                })
                .finally(() => (this.submitLoading = false));
        }

definitionStartByDataId()方法调用后端FlowDefinitionServiceImpl.java中的startByDataId接口实现流程实例的部署:

// 部署流程实例
export function definitionStartByDataId(dataId,data) {
  return request({
    url: '/flowable/definition/startByDataId/' + dataId,
    method: 'post',
    data: data
  })
}

重新提交(ActHandleBtn.vue):

<act-handle-btn @success="loadData" :data-id="record.id" :type="3" text="重新提交"></act-handle-btn>

调用ActHandleBtn组件,0通过、退回节点(1驳回、2退回、3重新提交)。此组件添加点击事件处理不同类型的按钮:

handle() {
          this.form.comment = ''
          this.candidateUsersSelecteds = []
            if (this.type === this.handleType.delegate) {
                // this.delegateTask();
            } else if (this.type === this.handleType.pass) {
                this.passTask();
            } else if (this.type === this.handleType.back) {
                this.backTask();
            } else if(this.type === this.handleType.return){
                this.returnTask();
            } else if(this.type === this.handleType.reApply){
                this.reApply();
            }
            else {
                this.$message.warn('未知类型type,参见 handleType');
            }
        }

重新提交:

reApply() {
            const v = this;
            this.modalTaskTitle = '确认重新提交';
            this.modalTaskVisible = true;
        },

其他类似

撤销(ActCancelBtn.vue):

<act-cancel-btn @success="loadData" :data-id="record.id"></act-cancel-btn>

撤销按钮绑定点击事件cancel(),让撤销面板可见,填写撤销原因

cancel() {
            this.modalCancelVisible = true;
        },
        handelSubmitCancel() {
            this.submitLoading = true;
          deleteByDataId(this.dataId, this.cancelForm.reason)
                .then(res => {
                    if (res.success) {
                        this.$message.success('操作成功');
                        this.modalCancelVisible = false;
                        this.$emit('success');
                    } else {
                        this.$message.error(res.message);
                    }
                })
                .finally(() => (this.submitLoading = false));
        }
    }

审批历史(ActHandleBtn.vue)

点击审批历史按钮可查看进展:

<act-historic-detail-btn :data-id="record.id"></act-historic-detail-btn>

点击事件与提交类似

 

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值