首页 > 其他分享 >基于jeecg-boot的flowable流程加签功能实现

基于jeecg-boot的flowable流程加签功能实现

时间:2023-10-31 12:38:15浏览次数:29  
标签:addSignForm String flowable route boot assignee query 加签


   

更多nbcio-boot功能请看演示系统

gitee源代码地址

在线演示(包括H5) : http://122.227.135.243:9888

      今天我们实现nbcio-boot的flowable的流程加签功能。

一、加签的几个概念

1、向前加签

任务在 A 这里,A 这个时候需要 B 核对一下,等 B 核对之后又回到 A 这里,这时 A 才能继续自己的任务

2、向后加签

任务在 A 这里,A 这个时候需要 B 处理这个事情,处理完毕之后就不用管了,继续后面的审批环节

3、多实例加签

任务只能对多实例任务进行加签,其它无效

二、前端实现

界面代码如下:

<!--加签流程-->
    <a-modal :z-index="100" :title="addSignTitle" @cancel="addSignOpen = false" :visible.sync="addSignOpen" :width="'40%'" append-to-body>
      <el-form ref="addSignForm" :model="addSignForm" label-width="160px">
        <el-form-item label="加签类型" prop="addSignType" :rules="[{ required: true, message: '请选择加签类型', trigger: 'blur' }]">
          <el-radio-group v-model="addSignForm.addSignType" @change="changeAddSignType">
              <el-radio :label="0">前加签</el-radio>
              <el-radio :label="1">后加签</el-radio>
              <el-radio :label="2">多实例加签</el-radio>
            </el-radio-group>
        </el-form-item>
        <el-form-item label="用户选择" prop="addSignUsers" :rules="[{ required: true, message: '请选择用户', trigger: 'blur' }]">
          <j-select-user-by-dep v-model="addSignForm.addSignUsers" />
        </el-form-item>
        <el-form-item label="处理意见" prop="comment" :rules="[{ required: true, message: '请输入处理意见', trigger: 'blur' }]">
          <el-input type="textarea" v-model="addSignForm.comment" placeholder="请输入处理意见" />
        </el-form-item>
        <el-form-item label="附件"  prop="commentFileDto.fileurl">
          <j-upload v-model="addSignForm.commentFileDto.fileurl"   ></j-upload>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addSignOpen = false">取 消</el-button>
        <el-button type="primary" @click="addSignComplete(true)">确 定</el-button>
      </span>
    </a-modal>

加签实现代码如下:

/** 加签 */
      handleAddSign() {
        this.addSignOpen = true;
        this.addSignTitle = "前加签流程";
      },
      changeAddSignType(val) {
        this.addSignForm.addSignType = val;
        if(this.addSignForm.addSignType === 0) {
          this.addSignTitle = "前加签流程";
        }
        if(this.addSignForm.addSignType === 1) {
          this.addSignTitle = "后加签流程";
        }
        if(this.addSignForm.addSignType === 2) {
          this.addSignTitle = "多实例加签流程";
        }
        console.log("changeAddSignType =",val);
        console.log("this.addSignTitle =",this.addSignTitle);
      },
      /** 加签任务 */
      addSignComplete() {
        if (!this.addSignForm.addSignUsers ) {
            this.$message.error("请选择用户");
            return;
        }
        // 流程信息
        this.addSignForm.deployId = this.$route.query && this.$route.query.deployId;
        this.addSignForm.taskId = this.$route.query && this.$route.query.taskId;
        this.addSignForm.procInsId = this.$route.query && this.$route.query.procInsId;
        this.addSignForm.instanceId = this.$route.query && this.$route.query.procInsId;
        // 初始化表单
        this.addSignForm.procDefId = this.$route.query && this.$route.query.procDefId;
        this.addSignForm.businessKey = this.$route.query && this.$route.query.businessKey;
        this.addSignForm.category = this.$route.query && this.$route.query.category;
        this.addSignForm.dataId = this.$route.query && this.$route.query.businessKey;
        //节点类型
        this.addSignForm.nodeType = this.$route.query && this.$route.query.nodeType;
        //online表单id和数据id
        this.addSignForm.onlineId = this.$route.query && this.$route.query.onlineId;
        if (this.addSignForm.category === 'online') {
          this.addSignForm.onlineDataId = this.$route.query && this.$route.query.businessKey;
        }  
        //对formdesigner后续加签审批的时候需要用到
        this.addSignForm.values = this.taskForm.values;
        console.log("this.addSignForm=",this.addSignForm);
        
        if(this.addSignForm.addSignType === 2) {
          multiInstanceAddSignTask(this.addSignForm).then(response => {
          this.$message.success(response.message);
          this.addSignOpen = false;
          this.goBack();
          });
        }
        else {
          addSignTask(this.addSignForm).then(response => {
          this.$message.success(response.message);
          this.addSignOpen = false;
          this.goBack();
          });
        }
      },

实现效果图如下:

基于jeecg-boot的flowable流程加签功能实现_flowable

三、后端主要代码

@Override
	public void addTasksBefore(String processInstanceId, String assignee, Set<String> assignees, String description) {
		addTask(processInstanceId, assignee, assignees, description, Boolean.FALSE);
		
	}

	@Override
	public void addTasksAfter(String processInstanceId, String assignee, Set<String> assignees, String description) {
		addTask(processInstanceId, assignee, assignees, description, Boolean.TRUE);
		
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void addTask(String processInstanceId, String assignee, Set<String> assignees, String description,
			Boolean flag) {
		TaskEntityImpl task = (TaskEntityImpl) taskService.createTaskQuery().processInstanceId(processInstanceId).taskAssignee(assignee).singleResult();
        Assert.notNull(task, String.format("分配人 [%s] 没有待处理任务", assignee));

        //如果是加签再加签
        String parentTaskId = task.getParentTaskId();
        if (StrUtil.isBlank(parentTaskId)) {
            task.setOwner(assignee);
            task.setAssignee(null);
            task.setCountEnabled(true);
            if (flag) {
                task.setScopeType("after");
            } else {
                task.setScopeType("before");
            }
            // 设置任务为空执行者
            taskService.saveTask(task);
        }
        //添加加签数据
        this.createSignSubTasks(assignee, assignees, task);
        //添加审批意见
        String type = flag ? FlowComment.HJQ.getType() : FlowComment.QJQ.getType();
        taskService.addComment(task.getId(), processInstanceId, type, description);
		
	}
	
	/**
     * 创建加签子任务
     * @param assignees 被加签人
     * @param assignee 加签人
     * @param taskEntity 父任务
     */
    private void createSignSubTasks(String assignee, Set<String> assignees, TaskEntity taskEntity) {
        if (CollectionUtil.isNotEmpty(assignees)) {
        	//1.创建被加签人的任务列表
            assignees.forEach(userId -> {
                if (StrUtil.isNotBlank(userId)) {
                    this.createSubTask(taskEntity, taskEntity.getId(), userId);
                }
            });
        	
            String parentTaskId = taskEntity.getParentTaskId();
            if (StrUtil.isBlank(parentTaskId)) {
                parentTaskId = taskEntity.getId();
            }
            String finalParentTaskId = parentTaskId;
            //2.创建加签人的任务并执行完毕
            String taskId = taskEntity.getId();
            if (StrUtil.isBlank(taskEntity.getParentTaskId())) {
                Task task = this.createSubTask(taskEntity, finalParentTaskId, assignee);
                taskId = task.getId();
            }
            Task taskInfo = taskService.createTaskQuery().taskId(taskId).singleResult();
            if (ObjectUtil.isNotNull(taskInfo)) {
                taskService.complete(taskId);
            }
            //如果是候选人,需要删除运行时候选不中的数据。
            long candidateCount = taskService.createTaskQuery().taskId(parentTaskId).taskCandidateUser(assignee).count();
            if (candidateCount > 0) {
                taskService.deleteCandidateUser(parentTaskId, assignee);
            }
        }
    }

	
	
	public String getMultiInstanceActAssigneeParam(String processDefinitionId, String actId) {
        AtomicReference<String> resultParam = new AtomicReference<>();
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(processDefinitionId).singleResult();
        //获取bpmnModel并转为modelNode
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
        //获取主流程
        Process mainProcess = bpmnModel.getMainProcess();
        //获取用户任务节点类型,深入子流程
        mainProcess.findFlowElementsOfType(UserTask.class, true).forEach(userTask -> {
            String userTaskId = userTask.getId();
            if (userTaskId.equals(actId)) {
                Object behavior = userTask.getBehavior();
                if (ObjectUtil.isNotNull(behavior)) {
                    //并行多实例节点
                    if (behavior instanceof ParallelMultiInstanceBehavior) {
                        ParallelMultiInstanceBehavior parallelMultiInstanceBehavior =
                                (ParallelMultiInstanceBehavior) behavior;
                        String collectionElementVariable = parallelMultiInstanceBehavior
                                .getCollectionElementVariable();
                        if (ObjectUtil.isNotEmpty(collectionElementVariable)) {
                            resultParam.set(collectionElementVariable);
                        }
                    }
                    //串行多实例节点
                    if (behavior instanceof SequentialMultiInstanceBehavior) {
                        SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior =
                                (SequentialMultiInstanceBehavior) behavior;
                        String collectionElementVariable = sequentialMultiInstanceBehavior
                                .getCollectionElementVariable();
                        if (ObjectUtil.isNotEmpty(collectionElementVariable)) {
                            resultParam.set(collectionElementVariable);
                        }
                    }
                }
            }
        });
        return resultParam.get();
    }

四、实际效果图如下:

基于jeecg-boot的flowable流程加签功能实现_vue.js_02

标签:addSignForm,String,flowable,route,boot,assignee,query,加签
From: https://blog.51cto.com/u_15070324/8103567

相关文章

  • 基于jeecg-boot的flowable流程收回功能实现(全网首创功能)
    更多nbcio-boot功能请看演示系统gitee源代码地址在线演示(包括H5):http://122.227.135.243:9888       对于之前的flowable流程,之前有撤回,拒绝,退回等功能,但都不能满足发起人对于流程收回的功能,发起人收回后可以重新进行流程发起,同时能够支持自定义业务的收回功能。 ......
  • java实现文件夹上传功能实例代码(SpringBoot框架)
    前言有时我们后台管理等服务可能会有这样一个简单需求,就是根据文件夹将整个文件夹下的所有资源都上传到我们的服务器上,本人也是搜索了大量资料,最终以最简单便捷的方式实现该功能,具体操作步骤如下一、前端如何设置上传组件并将资源上传到后台服务这里的项目框架为若依VUE版本......
  • SpringBoot中,为什么不直接使用一个Service写功能,而是Service接口+ServiceImpl实现类?
    当项目比较简单的时候,需求明确,变更不频繁或者几乎不怎么修改的时候,用第一种就好了当项目比较复杂,需求变更多的时候,用第二种比较好service层=service接口+serviceImpl实现类这种方式好处:1、解耦合2、便于扩展例如:publicinterfaceHumanService{StringgetName();}@Serv......
  • Gradle8.4构建SpringBoot多模块项目
    Gradle8.4构建SpringBoot多模块项目一、基本1、版本这个版本是Jdk8最后一个SpringBoot版本软件版本Gradle8.4SpringBoot2.7.15JDK82、Gradle基本介绍2.1、使用Wrapper方式构建好处:统一gradle的版本好处:不用安装gradle就可以使用Maven也是一样的......
  • 一文详解 springboot 项目启动时异步执行初始化逻辑
    你知道的越多,你不知道的越多点赞再看,养成习惯文章目录前言代码实现定义异步处理工具类实现java线程池新建AppInit实现ApplicationRunner接口完成启动项目时异步数据初始化前言前面的工作中,为了提高地区数据的响应时间,需要加载全国区划数据到redis中缓存起来,这个过程希......
  • Spring Boot 3系列之一(初始化项目)
    近期,JDK21正式发布,而SpringBoot3也推出已有一段时间。作为这两大技术领域的新一代标杆,它们带来了许多令人振奋的新功能和改进。尽管已有不少博客和文章对此进行了介绍,但对于我们这些身处一线的开发人员来说,有些文章和文档可能一看就会,一写就废。因此,为了更深入地理解JDK21和Spr......
  • SpringBoot事件驱动开发
    应用启动过程生命周期事件感知(9大事件)、应用运行中事件感知(无数种)事件发布:ApplicationEventPublisherAware或注入:ApplicationEventMulticaster事件监听:组件+@EventListener场景:当用户登录后,我们需要为用户增加一个积分、随机获取一张优惠券、增加日志等,传统的开发模式......
  • SpringBoot事件和监听器
    事件和监听器生命周期监听场景:监听应用的生命周期监听器-SpringApplicationRunListener自定义SpringApplicationRunListener来监听事件;1.1.编写SpringApplicationRunListener实现类1.2.在META-INF/spring.factories中配置org.springframework.boot.SpringApplication......
  • [Springboot整合thymeleaf]处理js中的路径问题。
    使用了thymeleaf模板引擎之后,html中的标签,都可以直接替换成th:srcth:href但是处理js的中的资源路径并不是像jsp那么简单了。可以通过以下方式解决。<!--处理路径问题--><scriptth:inline="javascript">varpath=[[${#request.contextPath}]]</script><scriptth:inl......
  • u-boot和bootloader到底有什么区别
    嵌入式软件工程师都听说过u-boot和bootloader,但很多工程师依然不知道他们到底是啥。今天就来简单讲讲 u-boot 和 bootloader 的内容以及区别。BootloaderBootloader从字面上来看就是启动加载的意思。用过电脑的都知道,windows开机时会首先加载bios,然后是系统内核,最后启动完毕......