
14 changed files with 798 additions and 3 deletions
@ -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; |
||||
|
} |
@ -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; |
||||
|
} |
@ -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; |
||||
|
} |
@ -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); |
||||
|
} |
@ -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> |
@ -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; |
||||
|
} |
||||
|
} |
@ -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() + "成功!"); |
||||
|
} |
||||
|
|
||||
|
} |
@ -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); |
||||
|
} |
@ -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> |
@ -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); |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
@ -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> |
@ -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…
Reference in new issue