原来工作流用起来这么清爽(芋道源码yudao-cloud 二开笔记)

大家好,我是在加班的码农刘工。最近在使用芋道源码yudao-cloud开发一个系统,刚好需要使用工作流来实现审批和驳回的业务。

需求

实现一个公司绩效评分功能。员工自己填写每个月的绩效,填好后提交给领导打分审核。

在这里插入图片描述

工作流介绍

由于使用的是 yudao-cloud 进行的二开,框架内本身已经封装好了工作流的服务,功能介绍如下:

在这里插入图片描述

在这里插入图片描述

如何使用

首先需要把bpm服务启动,然后走一遍过程,才能清晰的知道该工作流是怎么样的业务流程。接下来是使用的步骤:

1、启动该服务之前需要先导入对应的sql

sql下载地址

2、运行 BpmServerApplication 类,启动工作流服务。

然后访问前端的 BPM 菜单,确认功能是否生效。如下图所示:

在这里插入图片描述

3、也可以看下官方的 审批接入业务表单,当然直接看我这个也不会误入歧途。

找到工作流程->流程管理->流程模型->新建流程

在这里插入图片描述

这里的标识是唯一的 最好在后端写一个常量或者枚举,也可以写在字典里,会有用到的地方。流程名称可随便写。

在这里插入图片描述

这里创建好以后还需要操作3个步骤

在这里插入图片描述

4、修改流程、设计流程、发布流程。

在这里插入图片描述

修改流程:

----流程分类:可以去随便去分类创建一个,再回来选择。

----表单类型:我这里主讲的是 业务表单,流程表单可以看看 官方流程表单

----表单提交路由和表单查看地址:这两个别有用途啊,不过我的需求用不到。表单提交路由可以把创建表单的页面路由进行填写,查看则是详情的地址。具体可查看 官方业务表单

----我的填写如下,然后确定。

在这里插入图片描述

设计流程:
开始和结束节点是必须的,直接按住拖拽即可。拖拽后点击可以可以直接连线。

在这里插入图片描述

点击审批节点,填写名称,选择审批人(我这里选择了用户,也可以选择部门或其它)

在这里插入图片描述

设计好以后保存模型,回到列表点击发布流程,这里流程就创建好了。

需求实现

在这里插入图片描述

1、我这里分为三张表:绩效表、绩效明细表、绩效审批表
// 绩效表
CREATE TABLE `system_performance` (
  `performance_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `year_months` varchar(20) NOT NULL COMMENT '年月',
  `status` int(11) NOT NULL COMMENT '状态:0-保存 1-待评分 2-已评分',
  // 省略创建/修改时间,创建/修改人,deleted,tenant_id
  PRIMARY KEY (`performance_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=utf8mb4 COMMENT='绩效表';

// 绩效明细表
CREATE TABLE `system_performance_score` (
  `score_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `performance_id` bigint(20) NOT NULL COMMENT '绩效表ID',
  `task_type` int(11) DEFAULT NULL COMMENT '任务类型:0-岗位任务 1-临时任务 2-目标任务',
  `task_name` varchar(60) DEFAULT NULL COMMENT '任务标题',
  `task_detail` text COMMENT '任务明细',
  `deadline` date DEFAULT NULL COMMENT '截止日期',
  `score` int(11) DEFAULT NULL COMMENT '分值',
  `self_score` int(11) DEFAULT NULL COMMENT '自评分',
  `leader_score` int(11) DEFAULT NULL COMMENT 'leader评分',
  `self_comment` varchar(200) DEFAULT NULL COMMENT '自评语',
  `leader_comment` varchar(200) DEFAULT NULL COMMENT 'leader语',
  `process_instance_type` varchar(100) DEFAULT NULL COMMENT '流程类型',
  `process_instance_id` varchar(100) DEFAULT NULL COMMENT '流程实例的编号',
  `status` tinyint(4) DEFAULT NULL COMMENT '流程结果 0-保存 1-审核中 2-审批通过 3-审批不通过',
  `present_user_id` bigint(20) DEFAULT NULL COMMENT '当前审批人',
  `present_nickname` varchar(255) DEFAULT NULL COMMENT '当前审批人昵称',
  // 省略创建/修改时间,创建/修改人,deleted,tenant_id
  PRIMARY KEY (`score_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=69 DEFAULT CHARSET=utf8mb4 COMMENT='绩效明细表';

// 绩效审批表
CREATE TABLE `system_performance_approve` (
  `approve_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `score_id` bigint(20) NOT NULL COMMENT '绩效明细ID',
  `process_instance_id` varchar(100) DEFAULT NULL COMMENT '流程实例的编号',
  `status` tinyint(4) DEFAULT NULL COMMENT '审批结果 1-审核中 2-审批通过 3-审批不通过',
  // 省略创建/修改时间,创建/修改人,deleted,tenant_id
  PRIMARY KEY (`approve_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='绩效审批表';

此处省略生成后端代码的过程

2、system引入bpm依赖

这里需要定义bpm的api,关于Feign服务调用可以看我的另一篇文章 Feign服务调用

在这里插入图片描述
在这里插入图片描述

3、提交接口的service实现类
@Override
@Transactional(rollbackFor = Exception.class)
public Long createPerformance(Long userId, PerformanceSaveReqVO createReqVO) {
    // 插入
    PerformanceDO performance = BeanUtils.toBean(createReqVO, PerformanceDO.class);
    performanceMapper.insert(performance);

    // 插入明细表
    createPerformanceScoreList(userId, performance.getStatus(), performance.getPerformanceId(), createReqVO.getPerformanceScores());

    // 返回
    return performance.getPerformanceId();
}

// 提交明细表
private void createPerformanceScoreList(Long userId, Integer status, Long performanceId, List<PerformanceScoreDO> list) {
    list.forEach(o -> o.setPerformanceId(performanceId));
    performanceScoreMapper.insertBatch(list);
    
	// 确认为提交时创建流程
    if (status.equals(PerformanceEnum.STATUS_TYPE_2.getCode())) {
        createPerformanceScoreFlow(userId, list);
    }
}


/**
 * 创建流程
 *
 * @param userId
 * @param performanceScoreDOList
 */
private void createPerformanceScoreFlow(Long userId, List<PerformanceScoreDO> performanceScoreDOList) {
    for (PerformanceScoreDO scoreDO : performanceScoreDOList) {
        // 发起 BPM 流程
        Map<String, Object> processInstanceVariables = new HashMap<>();
        // setProcessDefinitionKey 流程实例的唯一标识test_performance
        String processInstanceId = processInstanceApi.createProcessInstance(userId,
                new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(scoreDO.getProcessInstanceType())
                        .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(scoreDO.getScoreId()))
        ).getCheckedData();

        scoreDO.setProcessInstanceId(processInstanceId);
        
        // 获取流程当前节点的审批人,该方法需要在bpm模块定义
        CommonResult<String> apiTaskResult = processInstanceApi.getApiTaskListByProcessInstanceId(processInstanceId);
        if (apiTaskResult.getData() != null) {
            scoreDO.setPresentUserId(Long.valueOf(apiTaskResult.getData()));
            AdminUserDO adminUserDO = userMapper.selectById(scoreDO.getPresentUserId());
            scoreDO.setPresentNickname(adminUserDO.getNickname());
        }
        
		// todo 此处还需要创建审批
		
		
    }

    performanceScoreMapper.updateBatch(performanceScoreDOList);
}
4、审批接口

由于我个人的业务牵扯到较多的模块,代码贴了反而会更复杂,所以就省略了

@Transactional(rollbackFor = Exception.class)
@Override
public Boolean approvePerformanceScoreStatus(PerformanceUpdateStatusReqVO updateReqVO) {
	// 由于我个人的业务牵扯到较多的模块,代码贴了反而会更复杂,所以就省略了

	// todo 调用审批接口,审批是否通过
	
	// todo 更新绩效表信息

}

5、bpm的Feign接口定义
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
@Tag(name = "RPC 服务 - 流程实例")
public interface BpmProcessInstanceApi {

    String PREFIX = ApiConstants.PREFIX + "/process-instance";

    @PostMapping(PREFIX + "/create")
    @Operation(summary = "创建流程实例(提供给内部),返回实例编号")
    @Parameter(name = "userId", description = "用户编号", required = true, example = "1")
    CommonResult<String> createProcessInstance(@RequestParam("userId") Long userId,
                                               @Valid @RequestBody BpmProcessInstanceCreateReqDTO reqDTO);

    // 该接口的实现可参考BpmTaskController里的getTaskListByProcessInstanceId接口
    @PostMapping(PREFIX + "/getApiTaskListByProcessInstanceId")
    @Operation(summary = "获得指定流程实例的流程任务列表(获取审批人)")
    @Parameter(name = "userId", description = "用户编号", required = true, example = "1")
    CommonResult<String> getApiTaskListByProcessInstanceId(@RequestParam("processInstanceId") String processInstanceId);

    // 该接口的实现可参考BpmTaskController里的approveTask接口
    @PostMapping(PREFIX + "/approve")
    @Operation(summary = "审批通过任务")
    public CommonResult<Boolean> approveTask(@RequestParam("userId") Long userId,
                                             @RequestParam("processInstanceId") Long processInstanceId,
                                             @RequestParam("reason") Long reason);

    // 该接口的实现可参考BpmTaskController里的rejectTask接口
    @PostMapping(PREFIX + "/reject")
    @Operation(summary = "审批拒绝任务")
    public CommonResult<Boolean> rejectTask(@RequestParam("userId") Long userId,
                                             @RequestParam("processInstanceId") Long processInstanceId,
                                             @RequestParam("reason") Long reason);

}

好了,到此业务表单接入工作流完成。

总结

本篇文章主要讲实现的思路,帮大家尽少的踩坑。毕竟我真的是反复掉了好多次坑,有疑问的朋友也可以在评论区提问或交流。

下一篇文章再见!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值