Browse Source

通用审批相关代码

zhanglei
dimengzhe 3 months ago
parent
commit
624fa4ef1f
  1. 23
      anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flowapprover/FlowApprover.java
  2. 20
      anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flowapprover/FlowApproverDto.java
  3. 21
      anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flowcc/FlowCc.java
  4. 39
      anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow3/Flow3Service.java
  5. 18
      anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Mapper.java
  6. 9
      anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Mapper.xml
  7. 111
      anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Rest.java
  8. 441
      anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Service.java
  9. 17
      anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowapprover/FlowApproverMapper.java
  10. 10
      anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowapprover/FlowApproverMapper.xml
  11. 53
      anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowapprover/FlowApproverService.java
  12. 16
      anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowcc/FlowCcMapper.java
  13. 4
      anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowcc/FlowCcMapper.xml
  14. 19
      anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowcc/FlowCcService.java

23
anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flowapprover/FlowApprover.java

@ -0,0 +1,23 @@
package com.yxt.anrui.flowable.api.flowapprover;
import com.yxt.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @description:
* @author: dimengzhe
* @date: 2025/2/20
**/
@Data
public class FlowApprover extends BaseEntity {
private static final long serialVersionUID = 8140464420543873852L;
@ApiModelProperty("申请sid")
private String businessSid;
@ApiModelProperty("序号")
private Integer sortNo;
@ApiModelProperty("审批人sid")
private String approverSid;
@ApiModelProperty("审批人名称")
private String approvalName;
}

20
anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flowapprover/FlowApproverDto.java

@ -0,0 +1,20 @@
package com.yxt.anrui.flowable.api.flowapprover;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* @description:
* @author: dimengzhe
* @date: 2025/2/20
**/
@Data
public class FlowApproverDto {
@ApiModelProperty("申请sid")
private String businessSid;
@ApiModelProperty("审批人sid")
private List<String> approverSidList;
}

21
anrui-flowable/anrui-flowable-api/src/main/java/com/yxt/anrui/flowable/api/flowcc/FlowCc.java

@ -0,0 +1,21 @@
package com.yxt.anrui.flowable.api.flowcc;
import com.yxt.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @description:
* @author: dimengzhe
* @date: 2025/2/20
**/
@Data
public class FlowCc extends BaseEntity {
private static final long serialVersionUID = -4299550952719113083L;
@ApiModelProperty("申请sid")
private String businessSid;
@ApiModelProperty("抄送人sids")
private String ccSids;
@ApiModelProperty("抄送人名称")
private String ccNames;
}

39
anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow3/Flow3Service.java

@ -95,8 +95,6 @@ public class Flow3Service extends MybatisBaseService<FlowMapper, Flowable> {
private MessageFeign messageFeign;
@Autowired
private SysFlowccFeign sysFlowccFeign;
@Autowired
private ProcessEngine processEngine;
public ResultBean<UpdateFlowFieldVo> businessStartProcessInstanceById(BusinessVariables bv) {
ResultBean<UpdateFlowFieldVo> rb = ResultBean.fireFail();
@ -146,6 +144,8 @@ public class Flow3Service extends MybatisBaseService<FlowMapper, Flowable> {
String id_ = "";
String name_ = "";
String task_def_key_ = "";
//设置是否是管理员自动审批,默认否
boolean adminContains = false;
//查询当前实例的最新待办任务
List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();
if (StringUtils.isBlank(nextNodeUserSids)) {
@ -168,6 +168,21 @@ public class Flow3Service extends MybatisBaseService<FlowMapper, Flowable> {
taskService.setVariablesLocal(id_, variables);
}
}
tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();
//遍历待办任务
for (int i = 0; i < tasks.size(); i++) {
Task task2 = tasks.get(i);
String isMultiInstanceTask = isMultiInstanceTask(task2);
id_ = task2.getId();
task_def_key_ = task2.getTaskDefinitionKey();
name_ = task2.getName();
if ("会签任务".equals(isMultiInstanceTask) || "或签任务".equals(isMultiInstanceTask)) {
if(ProcDefEnum.DEFAUL_TADMIN_SID.getProDefId().equals(task2.getAssignee())){
adminContains = true;
break;
}
}
}
} else {
Task task2 = tasks.get(0);
id_ = task2.getId();
@ -179,8 +194,10 @@ public class Flow3Service extends MybatisBaseService<FlowMapper, Flowable> {
taskService.setVariablesLocal(id_, variables);
}
//提交前传入下一环节待办人
if (ProcDefEnum.DEFAUL_TADMIN_SID.getProDefId().equals(nextNodeUserSids)) {
if (ProcDefEnum.DEFAUL_TADMIN_SID.getProDefId().equals(nextNodeUserSids) || adminContains) {
return handleAutomaticApproval(bv, task, id_, task_def_key_, variables, variablesSeconds, processDefinition);
}
// 如果申请人与下一环节审批人相同,则自动审批
@ -301,6 +318,22 @@ public class Flow3Service extends MybatisBaseService<FlowMapper, Flowable> {
nodeState = task2.getName();
taskDefKey = task2.getTaskDefinitionKey();
}
tasks = taskService.createTaskQuery().processInstanceId(instanceId).list();
//遍历待办任务
for (int i = 0; i < tasks.size(); i++) {
Task task2 = tasks.get(i);
isMultiInstanceTask = isMultiInstanceTask(task2);
vo.setTaskId(task2.getId());
nodeState = task2.getName();
taskDefKey = task2.getTaskDefinitionKey();
if ("会签任务".equals(isMultiInstanceTask) || "或签任务".equals(isMultiInstanceTask)) {
if(ProcDefEnum.DEFAUL_TADMIN_SID.getProDefId().equals(task2.getAssignee())){
nextUserSid = ProcDefEnum.DEFAUL_TADMIN_SID.getProDefId();
adminContains = true;
break;
}
}
}
} else {
nodeState = FlowComment.SETTLE.getRemark();
taskDefKey = "Event_end";

18
anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Mapper.java

@ -0,0 +1,18 @@
package com.yxt.anrui.flowable.biz.flow4;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yxt.anrui.flowable.api.flow.Flowable;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @description:
* @author: dimengzhe
* @date: 2025/2/20
**/
@Mapper
public interface Flow4Mapper extends BaseMapper<Flowable> {
List<String> selectByProcInstId(String instanceId);
}

9
anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Mapper.xml

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yxt.anrui.flowable.biz.flow4.Flow4Mapper">
<select id="selectByProcInstId" resultType="java.lang.String">
select ASSIGNEE_
from act_hi_taskinst
where PROC_INST_ID_ = #{instanceId}
</select>
</mapper>

111
anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Rest.java

@ -0,0 +1,111 @@
package com.yxt.anrui.flowable.biz.flow4;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.yxt.anrui.flowable.api.flow.UpdateFlowFieldVo;
import com.yxt.anrui.flowable.biz.flow2.FlowRest;
import com.yxt.anrui.flowable.feign.form.MessageFlowVo;
import com.yxt.anrui.flowable.feign.form.MessageFlowableQuery;
import com.yxt.anrui.flowable.sqloperationsymbol.BusinessVariables;
import com.yxt.anrui.portal.api.sysflowcc.SysFlowccVo;
import com.yxt.anrui.portal.api.sysuser.SysUserVo;
import com.yxt.anrui.portal.api.sysuser.UserByRolesAndOrgQuery;
import com.yxt.common.base.utils.StringUtils;
import com.yxt.common.core.result.ResultBean;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import java.util.concurrent.*;
/**
* @description: 通用审批
* @author: dimengzhe
* @date: 2025/2/20
**/
@RestController
@RequestMapping("v4/flow")
public class Flow4Rest {
Logger log = LoggerFactory.getLogger(FlowRest.class);
@Autowired
private Flow4Service flowService;
@PostMapping("/startProcess")
public ResultBean<UpdateFlowFieldVo> startProcess(@RequestBody BusinessVariables bv) {
ResultBean<UpdateFlowFieldVo> rb = ResultBean.fireFail();
//获取表单中的参数
Map<String, Object> formVariables = bv.getFormVariables();
formVariables = formVariables == null ? new HashMap<>() : formVariables;
//发起人的组织全路径
String orgPath = bv.getOrgSidPath();
formVariables.put("createrOrgPath", orgPath);
formVariables.put("businessSid", bv.getBusinessSid());
//启动流程实例
ResultBean<UpdateFlowFieldVo> startResultBean = flowService.businessStartProcessInstanceById(bv);
return startResultBean;
}
@PostMapping("/submit2")
ResultBean submit2() {
ResultBean rb = ResultBean.fireFail();
List<String> userIds = new ArrayList<>();
userIds.add("aaa");
userIds.add("bbb");
userIds.add("ccc");
Map<String, Object> variables = new HashMap<>();
variables.put("approvers", userIds);
BusinessVariables bv = new BusinessVariables();
bv.setFormVariables(variables);
bv.setModelId("process_wj9q4vwi:1:17170004");
bv.setUserSid("7f56f6ec-4a5f-47b0-aaab-158d64cb97b1");
//启动流程
ResultBean<UpdateFlowFieldVo> voResultBean = startProcess(bv);
System.out.println("voResultBean{}" + voResultBean);
return rb.success();
}
public ResultBean<UpdateFlowFieldVo> handleProsess(BusinessVariables bv) {
ResultBean<UpdateFlowFieldVo> rb = ResultBean.fireFail();
ResultBean<UpdateFlowFieldVo> updateFlowFieldVoResultBean = flowService.handleProsess(bv, true);
//添加抄送
log.info("流程返回:{}", JSONObject.toJSONString(updateFlowFieldVoResultBean));
//需要判断办结后再执行 TODO
if (updateFlowFieldVoResultBean.getSuccess()) {
log.info("流程返回:{}", JSONObject.toJSONString(updateFlowFieldVoResultBean));
if ("Event_end".equals(updateFlowFieldVoResultBean.getData().getTaskDefKey())) {
try {
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
.setNameFormat("demo-pool-%d").build();
ExecutorService pool = new ThreadPoolExecutor(2, 100,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
Future future1 = pool.submit(() -> {
HashMap<String, Object> map = new HashMap<>();
map.put("bv", bv);
UpdateFlowFieldVo ufVo = updateFlowFieldVoResultBean.getData();
ufVo.setTaskId(bv.getTaskId());
map.put("uff", ufVo);
flowService.cc(map, bv.getTaskDefKey());
});
} catch (Exception e) {
e.printStackTrace();
return rb.setMsg("抄送失败");
}
}
}
return updateFlowFieldVoResultBean;
}
}

441
anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow4/Flow4Service.java

@ -0,0 +1,441 @@
package com.yxt.anrui.flowable.biz.flow4;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yxt.anrui.flowable.api.flow.Flowable;
import com.yxt.anrui.flowable.api.flow.UpdateFlowFieldVo;
import com.yxt.anrui.flowable.api.flowapprover.FlowApprover;
import com.yxt.anrui.flowable.api.flowapprover.FlowApproverDto;
import com.yxt.anrui.flowable.api.flowcc.FlowCc;
import com.yxt.anrui.flowable.api.flowcomment.FlowComment;
import com.yxt.anrui.flowable.api.flowtask.LatestTaskVo;
import com.yxt.anrui.flowable.api.processcomment.ProcessCommentDto;
import com.yxt.anrui.flowable.api.utils.ProcDefEnum;
import com.yxt.anrui.flowable.biz.flow2.FlowMapper;
import com.yxt.anrui.flowable.biz.flowapprover.FlowApproverService;
import com.yxt.anrui.flowable.biz.flowcc.FlowCcService;
import com.yxt.anrui.flowable.biz.flowtask.FlowTaskService;
import com.yxt.anrui.flowable.biz.process.ProcessService;
import com.yxt.anrui.flowable.biz.processcomment.ProcessCommentService;
import com.yxt.anrui.flowable.common.ProcessConstants;
import com.yxt.anrui.flowable.feign.MessageFeign;
import com.yxt.anrui.flowable.feign.form.MessageFlowVo;
import com.yxt.anrui.flowable.feign.form.MessageFlowableQuery;
import com.yxt.anrui.flowable.sqloperationsymbol.BusinessVariables;
import com.yxt.anrui.portal.api.sysflowableconfig.SysFlowableConfigFeign;
import com.yxt.anrui.portal.api.sysflowableconfig.SysFlowableConfigQuery;
import com.yxt.anrui.portal.api.sysflowableconfig.SysFlowableConfigVvo;
import com.yxt.anrui.portal.api.sysflowcc.SysFlowccFeign;
import com.yxt.anrui.portal.api.sysflowcc.SysFlowccVo;
import com.yxt.anrui.portal.api.sysuser.SysUserFeign;
import com.yxt.anrui.portal.api.sysuser.SysUserVo;
import com.yxt.anrui.portal.api.sysuser.UserByRolesAndOrgQuery;
import com.yxt.anrui.portal.api.sysuser.UserssQuery;
import com.yxt.common.base.service.MybatisBaseService;
import com.yxt.common.base.utils.StringUtils;
import com.yxt.common.core.result.ResultBean;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.*;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.DelegationState;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import java.util.stream.Collectors;
/**
* @description:
* @author: dimengzhe
* @date: 2025/2/20
**/
@Service
@Slf4j
public class Flow4Service extends MybatisBaseService<Flow4Mapper, Flowable> {
@Autowired
RepositoryService repositoryService;
@Autowired
RuntimeService runtimeService;
@Autowired
ManagementService managementService;
@Autowired
ProcessEngineConfigurationImpl processEngineConfiguration;
@Autowired
private SysUserFeign sysUserFeign;
@Autowired
protected IdentityService identityService;
@Autowired
protected TaskService taskService;
@Autowired
private SysFlowableConfigFeign sysFlowableConfigFeign;
@Autowired
private FlowTaskService flowTaskService;
@Autowired
private ProcessCommentService processCommentService;
@Autowired
protected HistoryService historyService;
@Autowired
private ProcessService processService;
@Autowired
private MessageFeign messageFeign;
@Autowired
private SysFlowccFeign sysFlowccFeign;
@Autowired
private FlowApproverService flowApproverService;
@Autowired
private FlowCcService flowCcService;
/**
* 启动流程
*
* @param bv
* @return
*/
public ResultBean<UpdateFlowFieldVo> businessStartProcessInstanceById(BusinessVariables bv) {
ResultBean<UpdateFlowFieldVo> rb = ResultBean.fireFail();
UpdateFlowFieldVo updateFlowFieldVo = new UpdateFlowFieldVo();
String procDefId = bv.getModelId();
String userSid = bv.getUserSid();
String nextNodeUserSids = bv.getNextNodeUserSids();
Map<String, Object> variables = bv.getFormVariables();
// 获取审批人列表
List<String> approvers = (List<String>) variables.get("approvers");
// 获取抄送人列表
List<String> ccList = (List<String>) variables.get("ccList");
//根据流程定义id查询
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId)
.latestVersion().singleResult();
if (Objects.nonNull(processDefinition) && processDefinition.isSuspended()) {
return rb.setMsg("流程已被挂起,请先激活流程");
}
// 设置流程发起人Id到流程中
ResultBean<SysUserVo> sysUserVoResultBean = sysUserFeign.fetchBySid(userSid);
SysUserVo sysUser = sysUserVoResultBean.getData();
identityService.setAuthenticatedUserId(sysUser.getSid());
variables.put(ProcessConstants.PROCESS_INITIATOR, userSid);
variables.put(ProcessConstants.USER_TYPE_ASSIGNEE, userSid);
ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDefId, variables);
// 给第一步申请人节点设置任务执行人和意见
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();
if (Objects.nonNull(task)) {
taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.START.getType(),
sysUser.getName() + "发起流程申请");
taskService.setAssignee(task.getId(), userSid);
taskService.complete(task.getId(), variables);
}
assembleFlowApprover(bv);
//查询当前实例的最新待办任务
List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();
task = tasks.get(0);
Integer sortNo = sortNo(procDefId, task.getTaskDefinitionKey());
System.out.println("获取环节序号================" + sortNo);
String approverSid = flowApproverService.selectApproverSid(bv.getBusinessSid(), sortNo);
String id_ = task.getId();
String task_def_key_ = task.getTaskDefinitionKey();
String nodeState = task.getName();
//查询下一环节是否有转办并添加评论
nextNodeUserSids = change(approverSid, processInstance.getProcessInstanceId());
taskService.setAssignee(id_, nextNodeUserSids);
taskService.setVariablesLocal(id_, variables);
updateFlowFieldVo.setProcInsId(task.getProcessInstanceId());
updateFlowFieldVo.setNodeState(nodeState);
updateFlowFieldVo.setTaskId(id_);
updateFlowFieldVo.setTaskDefKey(task_def_key_);
updateFlowFieldVo.setProcDefId(bv.getModelId());
updateFlowFieldVo.setSid(bv.getBusinessSid());
updateFlowFieldVo.setName(processDefinition.getName());
return rb.success().setData(updateFlowFieldVo).setMsg("流程启动成功");
}
/**
* 查询下一环节用户是否有转办用户若有转办用户则添加转办评论
*
* @param nextNodeUserSids 下一环节用户
* @param instanceId 实例id
* @return
*/
public String change(String nextNodeUserSids, String instanceId) {
//查询下一环节是否有转办
String firstSid = "";
String firstName = "";
//默认无转办
boolean isChange = false;
if (StringUtils.isNotBlank(nextNodeUserSids)) {
List<String> nextUserList = Arrays.asList(nextNodeUserSids.split(","));
if (nextUserList.size() == 1) {
firstSid = nextUserList.get(0);
ResultBean<SysUserVo> userVoResultBean = sysUserFeign.fetchBySid(firstSid);
if (userVoResultBean.getData() != null) {
firstName = userVoResultBean.getData().getName();
}
SysFlowableConfigQuery sysFlowableConfigQuery = new SysFlowableConfigQuery();
sysFlowableConfigQuery.setUserSid(firstSid);
sysFlowableConfigQuery.setNowDate(new Date());
ResultBean<SysFlowableConfigVvo> sysFlowableConfigVvoResultBean = sysFlowableConfigFeign.selectByUserSid(sysFlowableConfigQuery);
if (sysFlowableConfigVvoResultBean.getData() != null) {
if (StringUtils.isNotBlank(sysFlowableConfigVvoResultBean.getData().getChangeUserSid())) {
nextNodeUserSids = sysFlowableConfigVvoResultBean.getData().getChangeUserSid();
isChange = true;
}
}
}
}
if (isChange) {//添加评论
ResultBean<SysUserVo> userVoResultBean = sysUserFeign.fetchBySid(nextNodeUserSids);
ProcessCommentDto processCommentDto = new ProcessCommentDto();
processCommentDto.setReviewerSid(firstSid);
if (userVoResultBean.getData() != null) {
String changeName = userVoResultBean.getData().getName();
processCommentDto.setReviewer(firstName);
processCommentDto.setContent("交" + changeName + "转办");
}
processCommentDto.setTime(new Date());
processCommentDto.setProcessId(instanceId);
processCommentService.saveOrUpdateDto(processCommentDto);
}
return nextNodeUserSids;
}
public Integer sortNo(String proDefId, String taskDefKey) {
// 获取所有 UserTask,并以 Map 形式存储环节位置
Map<String, Integer> taskKeyToPositionMap = new HashMap<>();
// 获取流程定义的 BPMN 模型
BpmnModel bpmnModel = repositoryService.getBpmnModel(proDefId);
// 使用 Stream API 遍历流程元素并缓存顺序
List<UserTask> userTasks = bpmnModel.getProcesses().stream()
.flatMap(process -> process.getFlowElements().stream()) // 遍历所有流程
.filter(flowElement -> flowElement instanceof UserTask) // 只筛选 UserTask
.map(flowElement -> (UserTask) flowElement)
.collect(Collectors.toList());
// 将 UserTask 的 key 和位置映射到 Map 中
int position = 1;
for (UserTask userTask : userTasks) {
taskKeyToPositionMap.put(userTask.getId(), position++);
}
Integer taskPosition = taskKeyToPositionMap.get(taskDefKey);
return taskPosition;
}
public void assembleFlowApprover(BusinessVariables bv) {
Map<String, Object> variables = bv.getFormVariables();
// 获取审批人列表
List<String> approvers = (List<String>) variables.get("approvers");
// 获取抄送人列表
List<String> ccList = (List<String>) variables.get("ccList");
FlowApproverDto flowApproverDto = new FlowApproverDto();
flowApproverDto.setBusinessSid(bv.getBusinessSid());
flowApproverDto.setApproverSidList(approvers);
ResultBean resultBean = flowApproverService.saveFlowApprover(flowApproverDto);
String ccSids = String.join(",", ccList);
ResultBean<List<SysUserVo>> listResultBean = sysUserFeign.fetchBySids(ccSids);
List<String> ccNameList = listResultBean.getData().stream().map(v -> v.getName()).collect(Collectors.toList());
// 将 List<String> 转换为逗号分隔的字符串
String result = String.join(",", ccNameList);
FlowCc flowCc = new FlowCc();
flowCc.setBusinessSid(bv.getBusinessSid());
flowCc.setCcSids(ccSids);
flowCc.setCcNames(result);
flowCcService.insert(flowCc);
}
/**
* 办理
*
* @param bv
* @param b
* @return
*/
public ResultBean<UpdateFlowFieldVo> handleProsess(BusinessVariables bv, boolean b) {
ResultBean<UpdateFlowFieldVo> rb = ResultBean.fireFail();
UpdateFlowFieldVo vo = new UpdateFlowFieldVo();
//获取表单中的参数
Map<String, Object> formVariables = bv.getFormVariables();
formVariables = formVariables == null ? new HashMap<>() : formVariables;
formVariables.put("businessSid", bv.getBusinessSid());
String nextUserSid = bv.getNextNodeUserSids();
String taskId = bv.getTaskId();
String userSid = bv.getUserSid();
String instanceId = bv.getInstanceId();
String comment = bv.getComment();
String nodeState = "";
String taskDefKey = "";
String orgPath = bv.getOrgSidPath();
//查询任务id为taskId的任务是否存在
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (Objects.isNull(task)) {
return rb.setMsg("任务不存在");
}
String assignee = task.getAssignee();
if (b && (StringUtils.isNotBlank(assignee) && assignee.indexOf(userSid) < 0)) {
return rb.setMsg("当前用户不是环节的待办人,不能进行办理操作!");
}
if (DelegationState.PENDING.equals(task.getDelegationState())) {
//加签
Authentication.setAuthenticatedUserId(userSid);
taskService.addComment(taskId, instanceId,
FlowComment.DELEGATE.getType(), comment);
taskService.resolveTask(taskId, formVariables);
nodeState = task.getName();
taskDefKey = task.getTaskDefinitionKey();
} else {
//当前环节办理通过,且将下一环节用户放入流程中
taskService.addComment(taskId, instanceId, FlowComment.NORMAL.getType(), comment);
log.error("taskid:{},userSid:{}", taskId, userSid);
log.error("formVariables:{}", JSON.toJSONString(formVariables));
taskService.setAssignee(taskId, userSid);
taskService.complete(taskId, formVariables);//当前用户办理通过
//查询当前实例的最新待办任务
List<Task> tasks = taskService.createTaskQuery().processInstanceId(bv.getInstanceId()).list();
if (tasks.size() > 0) {
task = tasks.get(0);
Integer sortNo = sortNo(bv.getModelId(), task.getTaskDefinitionKey());
System.out.println("获取环节序号================" + sortNo);
String approverSid = flowApproverService.selectApproverSid(bv.getBusinessSid(), sortNo);
String id_ = task.getId();
//查询下一环节用户是否有转办人
nextUserSid = change(approverSid, bv.getInstanceId());
taskService.setAssignee(id_, nextUserSid);//将下一环节用户放入流程中
vo.setTaskId(id_);
//在act_ru_variable表中增加环节上的业务参数的变量
taskService.setVariablesLocal(id_, formVariables);
nodeState = task.getName();
taskDefKey = task.getTaskDefinitionKey();
} else {
nodeState = FlowComment.SETTLE.getRemark();
taskDefKey = "Event_end";
vo.setNodeState(FlowComment.SETTLE.getRemark());
}
}
vo.setProcInsId(instanceId);
vo.setProcDefId(bv.getModelId());
vo.setNodeState(nodeState);
vo.setTaskDefKey(taskDefKey);
vo.setSid(bv.getBusinessSid());
return rb.success().setData(vo);
}
/**
* 流程抄送的功能
*
* @param map
* @return
*/
public ResultBean cc(Map<String, Object> map, String taskDefKey) {
ResultBean rb = ResultBean.fireFail();
log.info("FlowableRest-cc:{}", JSONObject.toJSONString(map));
Object bv1 = map.get("bv");
BusinessVariables bv = new BusinessVariables();
BeanUtil.copyProperties(bv1, bv);
Object uff1 = map.get("uff");
UpdateFlowFieldVo uff = new UpdateFlowFieldVo();
BeanUtil.copyProperties(uff1, uff);
uff.setTaskDefKey(taskDefKey);
FlowCc flowCc = flowCcService.selectByBusinessSid(bv.getBusinessSid());
StringBuilder userSids = new StringBuilder(flowCc.getCcSids());
StringBuilder userName = new StringBuilder(flowCc.getCcNames());
//抄送的业务逻辑
MessageFlowableQuery mfq = new MessageFlowableQuery();
MessageFlowVo messageFlowVo = new MessageFlowVo();
BeanUtil.copyProperties(uff, messageFlowVo);
mfq.setUfVo(messageFlowVo);
//移动端的参数
HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery()
.includeProcessVariables().taskId(bv.getTaskId()).singleResult();
if (historicTaskInstance == null) {
log.info("抄送失败:没有获取到业务参数!");
return rb.setMsg("抄送失败!");
}
Map<String, Object> processVariables = historicTaskInstance.getProcessVariables();
String createrOrgPath = (String) processVariables.get("createrOrgPath");
if (historicTaskInstance == null) {
log.info("抄送失败:没有获取到业务参数!");
return rb.setMsg("抄送失败!");
}
//
String assignee = (String) processVariables.get("assignee");
ResultBean<SysUserVo> stringResultBean = sysUserFeign.fetchBySid(assignee);
String assigneeName = "";
if (stringResultBean.getData() != null) {
assigneeName = stringResultBean.getData().getName();
}
Map<String, Object> app = new HashMap<>();
if (processVariables.get("app") != null) {
app = (Map<String, Object>) processVariables.get("app");
}
log.info("抄送方法-historicTaskInstance:{}", JSONObject.toJSONString(historicTaskInstance));
mfq.setAppMap(app);
mfq.setBusinessSid(bv.getBusinessSid());
mfq.setMsgContent(assigneeName + "抄送的流程审批,请查看");
// act_re_procdef
Map<String, String> process = processService.getProcessDefByDefId(historicTaskInstance.getProcessDefinitionId());
log.info("抄送成功-process:{}", process);
if (process == null) {
log.info("抄送失败,流程定义不存在!");
return rb.setMsg("抄送失败,流程定义不存在!");
}
mfq.setModuleName(process.get("NAME_"));
if (processVariables.containsKey("orderNames")) {
mfq.setMsgTitle(processVariables.get("orderNames").toString());
} else {
mfq.setMsgTitle(process.get("NAME_"));
}
if (processVariables.containsKey("sendRecommendSid")) {//增加的其他的抄送人
userSids.append(processVariables.get("sendRecommendSid").toString()).append(",");
}
//查询是否有设置转办的,抄送给设置转办人员
List<String> zbUserSids = processCommentService.selectByIdAndComment("转办", bv.getInstanceId());
zbUserSids.removeAll(Collections.singleton(null));
if (!zbUserSids.isEmpty()) {
String zbUser = String.join(",", zbUserSids);
userSids.append(zbUser).append(",");
}
userSids.deleteCharAt(userSids.length() - 1);
//若抄送的用户已在审批人员中(审批记录中有该用户),则该用户不抄送
List<String> taskinstUserSidList = baseMapper.selectByProcInstId(bv.getInstanceId());
List<String> uss = Arrays.asList(userSids.toString().split(","));
List<String> uniqueList = new ArrayList<String>(new HashSet<String>(uss));
uniqueList.removeIf(taskinstUserSidList::contains);
String userSidss = String.join(",", uniqueList);
mfq.setUserSids(userSidss);
mfq.setOrgPath(createrOrgPath);
mfq.setUserSid(assignee);
mfq.setApplicationName(assigneeName);
ResultBean<String> resultBean = messageFeign.pushMessageCC(mfq);
log.info("抄送成功:{}", userName.toString());
log.info("抄送成功-resultBean:{}", resultBean);
if (!resultBean.getSuccess()) {
log.info("抄送失败,同送消息异常!:{}", JSONObject.toJSONString(resultBean));
return rb.setMsg("抄送失败,同送消息异常!");
}
return rb.success().setMsg("抄送" + userName.toString() + "成功!");
}
}

17
anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowapprover/FlowApproverMapper.java

@ -0,0 +1,17 @@
package com.yxt.anrui.flowable.biz.flowapprover;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yxt.anrui.flowable.api.flow.Flowable;
import com.yxt.anrui.flowable.api.flowapprover.FlowApprover;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* @description:
* @author: dimengzhe
* @date: 2025/2/20
**/
@Mapper
public interface FlowApproverMapper extends BaseMapper<FlowApprover> {
String selectApproverSid(@Param("businessSid") String businessSid, @Param("sortNo") Integer sortNo);
}

10
anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowapprover/FlowApproverMapper.xml

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yxt.anrui.flowable.biz.flowapprover.FlowApproverMapper">
<select id="selectApproverSid" resultType="java.lang.String">
select approverSid
from flow_approver
where businessSid = #{businessSid}
and sortNo = #{sortNo}
</select>
</mapper>

53
anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowapprover/FlowApproverService.java

@ -0,0 +1,53 @@
package com.yxt.anrui.flowable.biz.flowapprover;
import com.yxt.anrui.flowable.api.flow.Flowable;
import com.yxt.anrui.flowable.api.flowapprover.FlowApprover;
import com.yxt.anrui.flowable.api.flowapprover.FlowApproverDto;
import com.yxt.anrui.flowable.biz.flow4.Flow4Mapper;
import com.yxt.anrui.portal.api.sysuser.SysUserFeign;
import com.yxt.anrui.portal.api.sysuser.SysUserVo;
import com.yxt.common.base.service.MybatisBaseService;
import com.yxt.common.core.result.ResultBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
/**
* @description:
* @author: dimengzhe
* @date: 2025/2/20
**/
@Service
public class FlowApproverService extends MybatisBaseService<FlowApproverMapper, FlowApprover> {
@Autowired
private SysUserFeign sysUserFeign;
public ResultBean saveFlowApprover(FlowApproverDto flowApproverDto) {
ResultBean<String> rb = ResultBean.fireFail();
String businessSid = flowApproverDto.getBusinessSid();
List<String> approverSidList = flowApproverDto.getApproverSidList();
approverSidList.removeAll(Collections.singleton(null));
if (!approverSidList.isEmpty()) {
for (int i = 0; i < approverSidList.size(); i++) {
FlowApprover flowApprover = new FlowApprover();
String approverSid = approverSidList.get(i);
Integer sortNo = i + 2;
flowApprover.setBusinessSid(businessSid);
flowApprover.setApproverSid(approverSid);
ResultBean<SysUserVo> sysUserVoResultBean = sysUserFeign.fetchBySid(approverSid);
SysUserVo sysUser = sysUserVoResultBean.getData();
flowApprover.setApprovalName(sysUser.getName());
flowApprover.setSortNo(sortNo);
baseMapper.insert(flowApprover);
}
}
return rb.success();
}
public String selectApproverSid(String businessSid, Integer sortNo) {
return baseMapper.selectApproverSid(businessSid,sortNo);
}
}

16
anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowcc/FlowCcMapper.java

@ -0,0 +1,16 @@
package com.yxt.anrui.flowable.biz.flowcc;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yxt.anrui.flowable.api.flowapprover.FlowApprover;
import com.yxt.anrui.flowable.api.flowcc.FlowCc;
import org.apache.ibatis.annotations.Mapper;
/**
* @description:
* @author: dimengzhe
* @date: 2025/2/20
**/
@Mapper
public interface FlowCcMapper extends BaseMapper<FlowCc> {
FlowCc selectByBusinessSid(String businessSid);
}

4
anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowcc/FlowCcMapper.xml

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yxt.anrui.flowable.biz.flowcc.FlowCcMapper">
</mapper>

19
anrui-flowable/anrui-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowcc/FlowCcService.java

@ -0,0 +1,19 @@
package com.yxt.anrui.flowable.biz.flowcc;
import com.yxt.anrui.flowable.api.flowapprover.FlowApprover;
import com.yxt.anrui.flowable.api.flowcc.FlowCc;
import com.yxt.anrui.flowable.biz.flowapprover.FlowApproverMapper;
import com.yxt.common.base.service.MybatisBaseService;
import org.springframework.stereotype.Service;
/**
* @description:
* @author: dimengzhe
* @date: 2025/2/20
**/
@Service
public class FlowCcService extends MybatisBaseService<FlowCcMapper, FlowCc> {
public FlowCc selectByBusinessSid(String businessSid) {
return baseMapper.selectByBusinessSid(businessSid);
}
}
Loading…
Cancel
Save