哪里做网站便宜wordpress无限加载
2026/3/20 7:25:58 网站建设 项目流程
哪里做网站便宜,wordpress无限加载,版面设计软件,山东人才招聘信息网官网一、Flowable简介 Flowable 是一个轻量级、开源的业务流程管理#xff08;BPM#xff09;和工作流引擎#xff0c;旨在帮助开发者和企业实现业务流程的自动化。它支持 BPMN 2.0 标准#xff0c;适用于各种规模的企业和项目。Flowable 的核心功能包括流程定义、流程执行、任…一、Flowable简介Flowable 是一个轻量级、开源的业务流程管理BPM和工作流引擎旨在帮助开发者和企业实现业务流程的自动化。它支持 BPMN 2.0 标准适用于各种规模的企业和项目。Flowable 的核心功能包括流程定义、流程执行、任务管理、历史记录查询等广泛应用于企业级应用中。官网https://www.flowable.com/open-source/docs/二、Spring Boot3整合环境JDK21、Spring Boot3.4.1、Flowable7.1.01.引入依赖!-- Flowable启动引擎 -- dependency groupIdorg.flowable/groupId artifactIdflowable-spring-boot-starter/artifactId version7.1.0/version /dependency2.yml配置注意本文数据源、数据库是MySQL和Druid各位码友请根据实际情况调整spring: #配置数据源 datasource: #MySQL driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/foleable?useUnicodetruecharacterEncodingutf-8serverTimezoneUTCuseSSLfalseallowPublicKeyRetrievaltrue username: root password: 123456 type: com.alibaba.druid.pool.DruidDataSource flowable: # 开启定时任务JOB async-executor-activate: true # 在引擎启动时会自动更新数据库架构 database-schema-update: true3.线程池配置1.提供一个全局的默认线程池2.提供一个folwable依赖的线程池注意Bean的名称一定要是applicationTaskExecutorimport org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.ThreadPoolExecutor; /** * 统一线程池管理 * * author xie **/ Configuration public class ThreadPoolTaskConfig { Bean(applicationTaskExecutor) public ThreadPoolTaskExecutor applicationTaskExecutor() { ThreadPoolTaskExecutor executor new ThreadPoolTaskExecutor(); //此方法返回可用处理器的虚拟机的最大数量; 不小于1 int core Runtime.getRuntime().availableProcessors(); executor.setCorePoolSize(core);//设置核心线程数 executor.setMaxPoolSize(core * 2 1);//设置最大线程数 executor.setKeepAliveSeconds(120);//除核心线程外的线程存活时间 executor.setQueueCapacity(120);//如果传入值大于0底层队列使用的是LinkedBlockingQueue,否则默认使用SynchronousQueue executor.setThreadNamePrefix(thread-default-execute);//线程名称前缀 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());//设置拒绝策略抛出 RejectedExecutionException来拒绝新任务的处理。 // executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());//设置拒绝策略使用主线程 // executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());//设置拒绝策略直接丢弃掉 // executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());//设置拒绝策略丢弃最早的未处理的任务请求。 return executor; } }不配置线程池可能出现以下错误三、流程定义官方流程设计器docker run -p 9096:8080 -d --name flow flowable/flowable-ui:6.8.0访问IP加启动容器的端口默认账户/密码admin/test进入设计器创建流程并设计创建测试流程这里先简单画个流程 后期写个详细流程图的绘画确定后进入设计界面添加用活动后设置名称点击用户任务设置用户任务的执行人这里先简单设置一个固定的人分配用户ID为user1再重复添加一个用户任务添加一下结束事件最后就依次连线就行了选中开始节点然后连接到用户一最后的效果图点击保存选择查看刚刚创建的流程导出XML四、部署流程1.把导出的xml放入我们工程的resources目录2.部署流程(这里先把我们后面用到的查询服务都注入)Resource private RepositoryService repositoryService; Resource private RuntimeService runtimeService; Autowired private TaskService taskService; Resource private HistoryService historyService; Resource IdentityService identityService; /** * 初始化流程 * * method: initFlow * return: * author: xie * date: 2024/12/24 上午9:26 **/ GetMapping(initFlow) Transactional(rollbackFor Exception.class) public void initFlow() { // 获取bpmn文件夹的所有.bpmn20.xml文件 ClassPathResource bpmnFolder new ClassPathResource(bpmn/); var files bpmnFolder.getFile().listFiles((dir, name) - name.endsWith(.bpmn20.xml)); if (files ! null files.length 0) { // 创建部署对象 var deploymentBuilder repositoryService.createDeployment(); for (var file : files) { // 添加BPMN文件到部署 deploymentBuilder.addInputStream(file.getName(), file.toURI().toURL().openStream()); } // 执行部署 Deployment deployment deploymentBuilder.deploy(); } }五、查询部署的全部流程当然这里也可以进行分页查询已经写在下面注释了 这里为了测试 我就简单写了/*** * 查询所有的流程实例 * method: queryAllDeployedProcesses * return: * author: xie * date: 2024/12/20 下午1:12 **/ GetMapping(/queryAllDeployedProcesses) public ListJSONObject queryAllDeployedProcesses() { ListJSONObject jsonObjects new ArrayList(); // 查询所有流程定义 ListProcessDefinition processDefinitions repositoryService.createProcessDefinitionQuery() .orderByProcessDefinitionKey().asc() // 按流程定义的 Key 排序 .latestVersion() // 只查询每个流程定义的最新版本 .list(); // 打印所有已部署的流程的 key 和 name for (ProcessDefinition processDefinition : processDefinitions) { System.out.println(Process ID: processDefinition.getId()); System.out.println(Process Key: processDefinition.getKey()); System.out.println(Process Name: processDefinition.getName()); System.out.println(Process Version: processDefinition.getVersion()); JSONObject object new JSONObject(); object.put(id, processDefinition.getId()); object.put(key, processDefinition.getKey()); object.put(name, processDefinition.getName()); object.put(version, processDefinition.getVersion()); jsonObjects.add(object); } //分页查询 // 创建查询对象 // ProcessDefinitionQuery query repositoryService.createProcessDefinitionQuery() // .latestVersion() // 只查询最新版本的流程定义 // .orderByProcessDefinitionKey().asc(); // 按流程定义的 Key 升序排序 // // // 获取总条数 // long totalCount query.count(); // // // 分页查询流程定义 // ListProcessDefinition processDefinitions query.listPage((pageNum - 1) * pageSize, pageSize); return jsonObjects; }看看界面的效果吧这个简单的前端页面展示方便查询六、发起审批/** * 是否被拒绝标记 */ public static final String REFUSEFLAG refuseFlag; /** * 发起流程 * * param key : 流程信息 * method: startFlow * return: * author: xie * date: 2024/12/20 下午1:43 **/ GetMapping(/startFlow) Transactional(rollbackFor Exception.class) public String startFlow(RequestParam(key) String key) { MapString, Object map Map.of( businessType, 业务类型业务审批、请假、出差等, day, 1, REFUSEFLAG, false ); //发起人用户ID String userId SysConstan.USER_ID; //订单号 String businessKey PO00001; //参数一 流程key //参数二 页面单据类型比如请假流水号、订单号等 //参数三 运行时变量信息比如请假天数 //设置发起人 identityService.setAuthenticatedUserId(userId); //启动流程变量 ProcessInstance processInstanceByKey runtimeService.startProcessInstanceByKey(key, businessKey, map); log.info(流程实例id-{}, processInstanceByKey.getId()); // 清除当前用户 identityService.setAuthenticatedUserId(null); return processInstanceByKey.getId(); }注意参数key指的是我们上一步部署流程后得到的key也就是页面查询的keymap对象是设置的变量集比如我们请假的时候可能要根据不同的天数走不同的分支这里的变量集后期可以自己封装一个对象指定一些必须传入的变量信息拒绝标记由于Flowable并不会记录流程是否是被拒绝而结束的流程实例userIdFlowable默认是无状态的可以通过identityService临时设置发起人businessKey业务订单号可以把它看做是审批的单据号后面审批通过了需要通知业务系统的时候需要用到七、查询所有发起的流程及展示状态这里包含了我的发起、我参与审批的流程、根据业务单号查询审批流程等查询功能/** * 查询所有流程实例 * * method: queryAllprocess * return: * author: xie * date: 2024/12/20 下午3:35 **/ GetMapping(queryAllprocess) public ListJSONObject queryAllprocess() { // 获取所有活跃的流程实例包括已结束的 ListHistoricProcessInstance allProcessInstances historyService.createHistoricProcessInstanceQuery() //查询用户参与过的流程实例 //.involvedUser(1) //查询发起人用户 //.startedBy(SysConstan.USER_ID) //根据变量查询自己设的变量 //.variableValueEquals(businessType, 查询的业务类型) //根据订单号模糊查询 //.processInstanceBusinessKeyLikeIgnoreCase(orderCode) .orderByProcessInstanceStartTime().asc() // 可以按ID排序便于调试 .list(); // 查询所有的流程实例包括历史的和活跃的 ListJSONObject jsonObjects new ArrayList(); for (HistoricProcessInstance processInstance : allProcessInstances) { String processInstanceId processInstance.getId(); JSONObject json new JSONObject(); if (processInstance.getEndTime() null) { json.put(status, 审批中); } else { json.put(status, 审批完成); } json.put(id, processInstance.getProcessDefinitionId()); json.put(processInstanceId, processInstanceId); json.put(startUser, processInstance.getStartUserId()); json.put(key, processInstance.getProcessDefinitionKey()); json.put(businessKey, processInstance.getBusinessKey()); json.put(name, processInstance.getProcessDefinitionName()); json.put(deleteReason, processInstance.getDeleteReason()); json.put(startTime, DateUtil.format(processInstance.getStartTime(), yyyy-MM-dd HH:mm:ss)); json.put(endTime, processInstance.getEndTime() ! null ? DateUtil.format(processInstance.getEndTime(), yyyy-MM-dd HH:mm:ss) : ); // 获取与任务相关的所有变量 // 获取该流程实例的变量 ListHistoricVariableInstance variables historyService.createHistoricVariableInstanceQuery() .processInstanceId(processInstanceId) .list(); if(CollUtil.isNotEmpty(variables)){ for (HistoricVariableInstance variable : variables) { json.put(variable.getVariableName(), variable.getValue()); if (REFUSEFLAG.equals(variable.getVariableName()) variable.getValue() ! null variable.getValue().toString().equalsIgnoreCase(true)) { json.put(status, 审批驳回); } } } jsonObjects.add(json); } return jsonObjects; }这里就用到了发起流程时是否驳回这个变量判断当前业务单据是否被驳回查询流程时可以有多种条件查询比如查询我发起的审批流程上面代码已经列出查询条件对应的页面简单展示发起后进入到用户一审批八、我的代办任务这里注释了用户ID条件查询实际业务系统应该是要设置当前用户的ID查询/** * 获取代办列表 (这里暂时查看所有的) * * method: getTasks * return: * author: xie * date: 2024/12/20 下午1:44 **/ GetMapping(/allTasks) public ListJSONObject getTasks() { ListTask taskList taskService .createTaskQuery() //查询业务类型为指定的任务 //.processInstanceBusinessKey(LEAVE) //查询所有zhangsan用户代办的任务 //.taskAssignee(SysConstan.USER_ID) .list(); ListJSONObject jsonObjects new ArrayList(); for (Task task : taskList) { JSONObject json new JSONObject(); json.put(id, task.getId()); json.put(name, task.getName()); json.put(user, task.getAssignee()); json.put(processDefinitionId, task.getProcessDefinitionId()); json.put(processInstanceId, task.getProcessInstanceId()); // 获取与任务相关的所有变量 MapString, Object taskVariables taskService.getVariables(task.getId()); // 打印出任务的变量 json.putAll(taskVariables); jsonObjects.add(json); } return jsonObjects; }九、完成任务这里的任务ID为上面我的代办任务接口查询出来Task的ID/** * 完成任务 * * method: testComplete * return: * author: xie * date: 2024/12/20 下午1:44 **/ GetMapping(/testComplete) Transactional(rollbackFor Exception.class) public boolean testComplete(RequestParam(id) String taskId) { // 获取任务对应的流程实例ID Task task taskService.createTaskQuery().taskId(taskId).singleResult(); // 检查任务是否为空 if (task null) { System.out.println(任务不存在); return false; } String processInstanceId task.getProcessInstanceId(); String orderCode (String) runtimeService.getVariable(processInstanceId, orderCode); log.info(业务单据:{}, orderCode); // 1. 设置新执行者 //taskService.setAssignee(taskId, newAssigneeId); // 任务的执行者被替换为新的用户 taskService.addComment(taskId, processInstanceId, 备注信息test); // 完成任务 taskService.complete(taskId); // 查询当前流程实例的所有活动任务 boolean isFinish processInstanceFinished(processInstanceId); log.debug(流程是否完成L{}, isFinish); return isFinish; } /** * 校验当前流程是否结束了 * method: isProcessInstanceFinished * param processInstanceId : * return: * author: xie * date: 2024/12/23 下午1:57 **/ public boolean processInstanceFinished(String processInstanceId) { // 获取当前流程实例 ProcessInstance processInstance runtimeService.createProcessInstanceQuery() .processInstanceId(processInstanceId) .singleResult(); // 如果 processInstance 为空表示该流程实例已结束 return processInstance null; }十、驳回任务processInstanceId指的是发起流程的实例ID/** * 驳回流程 * method: stopFlow * param processInstanceId : * return: * author: xie * date: 2024/12/24 下午4:38 **/ GetMapping(stopFlow) Transactional(rollbackFor Exception.class) public void stopFlow(RequestParam(id) String processInstanceId) { // 在删除前设置拒绝变量 runtimeService.setVariable(processInstanceId, refuseFlag, true); //拒绝 后一个参数是拒绝的原因 runtimeService.deleteProcessInstance(processInstanceId, 驳回任务备注原因); }十一、 完成效果展示1.BPMN-JS插件渲染的连接线不起效果2.Flowable引擎自带构建的图片没有经过的节点

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询