This commit is contained in:
那些花儿
2025-09-25 13:42:37 +08:00
parent 37e23100e1
commit 271b5837c8
78 changed files with 2197 additions and 1164 deletions
@@ -236,46 +236,6 @@ public class FlowCommonController {
@Aop(TransAop.READ_COMMITTED)
public Result executeTask(@Param("data") String param) {
Dict args = Json.fromJson(Dict.class, param);
// Long processTaskId = args.getLong(FlowConst.PROCESS_TASK_ID_KEY);
// String operator = SecurityUtil.getUserId();
// args.remove(FlowConst.PROCESS_TASK_ID_KEY);
// Integer submitType = args.getInt(FlowConst.SUBMIT_TYPE);
// if (submitType == null) {
// submitType = ProcessSubmitTypeEnum.AGREE.getCode();
// }
// args.put(FlowConst.SUBMIT_TYPE, submitType);
//
// // 设置办理人信息到表单参数
// args.put(FlowConst.TASK_FORM_DATA_PREFIX + "userName", SecurityUtil.getUserUsername());
// args.put(FlowConst.TASK_FORM_DATA_PREFIX + "loginName", SecurityUtil.getUserLoginname());
// args.put(FlowConst.TASK_FORM_DATA_PREFIX + "unitId", SecurityUtil.getUnitId());
// args.put(FlowConst.TASK_FORM_DATA_PREFIX + "unitName", SecurityUtil.getUnitId());
// args.put(FlowConst.TASK_FORM_DATA_PREFIX + "unionId", SecurityUtil.getUnionId());
//
// if (ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.ROLLBACK.getCode())) {
// // 退回上一个节点
// flowEngine.executeAndJumpTask(processTaskId, operator, args, null);
// } else if (ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.REJECT.getCode())) {
// // 拒绝,跳转到结束节点
// flowEngine.executeAndJumpToEnd(processTaskId, operator, args);
// } else if (ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.JUMP.getCode())) {
// // 跳转到指定节点
// String taskName = args.getStr(FlowConst.TASK_NAME);
// flowEngine.executeAndJumpTask(processTaskId, operator, args, taskName);
// } else if (ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.ROLLBACK_TO_OPERATOR.getCode())) {
// // 退回发起人
// flowEngine.executeAndJumpToFirstTaskNode(processTaskId, operator, args);
// } else if (ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.COUNTERSIGN_DISAGREE.getCode())) {
// // 会签不同意,追加不同意标识
// args.put(FlowConst.COUNTERSIGN_DISAGREE_FLAG, 1);
// flowEngine.executeProcessTask(processTaskId, operator, args);
// } else if (ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.RE_APPLY.getCode())) {
// // 重新提交
// flowEngine.executeProcessTask(processTaskId, operator, args);
// } else {
// // 默认执行
// flowEngine.executeProcessTask(processTaskId, operator, args);
// }
flowCommonService.executeTask(args);
return Result.success();
}
@@ -330,7 +290,7 @@ public class FlowCommonController {
@At("/surrogate")
@SaCheckLogin
@ApiOperation("代理")
@ApiOperation("委托")
public Result surrogate(@Param("taskId") Long taskId, @Param("actorIds") String[] actorIds) {
flowEngine.processTaskService().addTaskActor(taskId, Arrays.asList(actorIds));
return Result.success();
@@ -338,11 +298,9 @@ public class FlowCommonController {
@At("/addCandidate")
@SaCheckLogin
@ApiOperation("代理")
@ApiOperation("加签")
public Result addCandidate(@Param("taskId") Long taskId, @Param("actorIds") String[] actorIds) {
flowEngine.processTaskService().addCandidateActor(taskId, Arrays.asList(actorIds));
return Result.success();
}
}
@@ -9,8 +9,6 @@ import com.budwk.app.flow.engine.parser.impl.*;
/**
*
* 流程引擎配置类
* @author mldong
* @date 2022/6/12
*/
public class Configuration {
public Configuration() {
@@ -16,8 +16,6 @@ import java.util.stream.Collectors;
/**
*
* 执行对象参数
* @author mldong
* @date 2023/4/25
*/
@Data
public class Execution {
@@ -27,9 +27,6 @@ import java.util.List;
/**
* 工作流引擎实现
*
* @author mldong
* @date 2023/5/29
*/
public class FlowEngineImpl implements FlowEngine {
protected Configuration configuration;
@@ -8,8 +8,6 @@ import java.util.List;
/**
*
* 单例服务上下文
* @author mldong
* @date 2022/6/12
*/
public class ServiceContext {
private static Context context;
@@ -6,8 +6,6 @@ import lombok.Data;
/**
* 流程开始事件
* @author mldong
* @date 2023/12/5
*/
@Data
@Builder
@@ -2,8 +2,6 @@ package com.budwk.app.flow.engine.event;
/**
* 流程事件监听接口
* @author mldong
* @date 2023/12/5
*/
public interface ProcessEventListener {
void onEvent(ProcessEvent event);
@@ -6,8 +6,6 @@ import java.util.List;
/**
* 流程事件发布者类
* @author mldong
* @date 2023/12/5
*/
public class ProcessPublisher {
// 事件通知方法
@@ -5,8 +5,6 @@ import com.budwk.app.flow.engine.core.Execution;
/**
* 流程各模型操作处理接口
* @author mldong
* @date 2023/5/17
*/
public interface IHandler {
/**
@@ -16,8 +16,6 @@ import java.util.stream.Collectors;
/**
* 会签任务处理,用于判断会签任务是否可通过
*
* @author mldong
* @date 2023/11/24
*/
public class CountersignHandler implements IHandler {
private TaskModel taskModel;
@@ -16,8 +16,6 @@ import java.util.List;
/**
* 创建任务处理器
* @author mldong
* @date 2023/5/16
*/
public class CreateTaskHandler implements IHandler {
private TaskModel taskModel;
@@ -14,10 +14,7 @@ import com.budwk.app.flow.enums.ProcessEventTypeEnum;
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
/**
*
* 结束流程实例的处理器
* @author mldong
* @date 2023/5/29
*/
public class EndProcessHandler implements IHandler {
private EndModel endModel;
@@ -11,8 +11,6 @@ import java.util.List;
/**
* 合并分支操作的处理器
* @author mldong
* @date 2023/5/21
*/
public class MergeBranchHandler implements IHandler {
private JoinModel joinModel;
@@ -9,9 +9,6 @@ import com.budwk.app.flow.entity.ProcessDefine;
/**
* 启动子流程处理类
*
* @author mldong
* @date 2023/12/7
*/
public class StartSubProcessHandler implements IHandler {
private SubProcessModel model;
@@ -12,8 +12,6 @@ import java.util.Map;
/**
*
* 简单的上下文发现实现类
* @author mldong
* @date 2023/4/26
*/
public class SimpleContext implements Context {
private Dict dict = Dict.create();
@@ -16,8 +16,6 @@ import java.util.List;
/**
* 任务拦截器,处理代理人
*
* @author mldong
* @date 2023/12/6
*/
@IocBean
public class SurrogateInterceptor implements FlowInterceptor {
@@ -14,6 +14,7 @@ import com.budwk.app.sys.views.View_user;
import org.dromara.warm.flow.core.exception.FlowException;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.lang.util.NutMap;
import java.util.Date;
import java.util.HashMap;
@@ -22,8 +23,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
/**
* 流程工具
*
* @author mldong
* @date 2023/10/7
*/
public class FlowUtil {
private FlowUtil() {
@@ -83,6 +82,19 @@ public class FlowUtil {
return Dict.create();
}
/**
* 参数转字典
*
* @param variable
* @return
*/
public static NutMap variableToNutMap(String variable) {
if (JSONUtil.isTypeJSON(variable)) {
return NutMap.WRAP(JSONUtil.parseObj(variable));
}
return NutMap.NEW();
}
/**
* 判断是否为第一个任务节点
*
@@ -15,9 +15,6 @@ import java.util.Date;
* <p>
* 流程任务
* </p>
*
* @author mldong
* @since 2023-09-26
*/
@Getter
@Setter
@@ -25,7 +22,6 @@ import java.util.Date;
@Comment("流程任务")
public class ProcessTask extends BaseModel {
@Comment("主键")
@Id
private Long id;
@@ -12,9 +12,6 @@ import org.nutz.dao.entity.annotation.Table;
* <p>
* 流程任务和参与人关系
* </p>
*
* @author mldong
* @since 2023-09-26
*/
@EqualsAndHashCode(callSuper = true)
@Data
@@ -8,13 +8,13 @@ import lombok.Getter;
@Getter
public enum ProcessTaskStateEnum {
DOING(10,"进行中"),
DOING(10, "进行中"),
FINISHED(20, "已完成"),
WITHDRAW(30, "已撤回"),
INTERRUPT(40, "强行终止"),
PENDING(50,"挂起"),
ABANDON(99,"废弃")
;
PENDING(50, "挂起"),
TRANSFER(60, "转办"),
ABANDON(99, "已废弃");
private final Integer code;
private final String message;
@@ -17,9 +17,6 @@ import java.util.List;
* <p>
* 流程实例 服务类
* </p>
*
* @author mldong
* @since 2023-09-26
*/
public interface ProcessInstanceService extends BaseService<ProcessInstance> {
/**
@@ -28,12 +28,6 @@ public interface ProcessSurrogateService extends BaseService<ProcessSurrogate> {
*/
boolean update(ProcessSurrogate param);
/**
* 自定义分页查询流程委托代理
* @param param
* @return
*/
// CommonPage<ProcessSurrogateVO> page(ProcessSurrogatePageParam param);
/**
* 通过id查询
* @param id
@@ -9,9 +9,6 @@ import com.budwk.app.flow.vo.ProcessTaskActorVO;
* <p>
* 流程任务和参与人关系 服务类
* </p>
*
* @author mldong
* @since 2023-09-26
*/
public interface ProcessTaskActorService extends BaseService<ProcessTaskActor> {
/**
@@ -28,12 +25,6 @@ public interface ProcessTaskActorService extends BaseService<ProcessTaskActor> {
*/
boolean update(ProcessTaskActor param);
/**
* 自定义分页查询流程任务和参与人关系
* @param param
* @return
*/
// CommonPage<ProcessTaskActorVO> page(ProcessTaskActorPageParam param);
/**
* 通过id查询
* @param id
@@ -11,77 +11,82 @@ import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.vo.ProcessTaskVO;
import java.util.List;
import java.util.Map;
/**
* <p>
* 流程任务 服务类
* </p>
*
* @author mldong
* @since 2023-09-26
*/
public interface ProcessTaskService extends BaseService<ProcessTask> {
/**
* 添加流程任务
* @param param
* @return
*/
* 添加流程任务
*
* @param param
* @return
*/
boolean save(ProcessTask param);
/**
* 更新流程任务
* @param param
* @return
*/
* 更新流程任务
*
* @param param
* @return
*/
boolean update(ProcessTask param);
/**
* 通过id查询
* @param id
* @return
*/
* 通过id查询
*
* @param id
* @return
*/
ProcessTaskVO findById(Long id);
/**
* 保存流程任务
*
* @param processTask
*/
void saveProcessTask(ProcessTask processTask);
/**
* 更新流程任务
*
* @param processTask
*/
void updateProcessTask(ProcessTask processTask);
/**
* 根据流程实例ID获取正在进行的任务
*
* @param processInstanceId 流程实例ID
* @param taskNames 任务名称
* @param taskNames 任务名称
* @return
*/
List<ProcessTask> getDoingTaskList(Long processInstanceId, String[] taskNames);
/**
* 根据流程实例ID获取已完成的任务
*
* @param processInstanceId 流程实例ID
* @param taskNames 任务名称
* @param taskNames 任务名称
* @return
*/
List<ProcessTask> getDoneTaskList(Long processInstanceId, String[] taskNames);
/**
* 将流程任务修改为已完成
*
* @param processTaskId
* @param operator 任务处理人
* @param operator 任务处理人
* @param args
*/
void finishProcessTask(Long processTaskId, String operator, Dict args);
/**
* 废弃任务
*
* @param processTaskId
* @param operator
* @param args
@@ -90,6 +95,7 @@ public interface ProcessTaskService extends BaseService<ProcessTask> {
/**
* 根据任务模型和流程执行对象创建任务
*
* @param taskModel
* @param execution
* @return
@@ -98,6 +104,7 @@ public interface ProcessTaskService extends BaseService<ProcessTask> {
/**
* 通过id获取流程任务
*
* @param id
* @return
*/
@@ -105,27 +112,32 @@ public interface ProcessTaskService extends BaseService<ProcessTask> {
/**
* 向指定的任务id添加参与者
*
* @param processTaskId 任务id
* @param actors 参与者
* @param actors 参与者
*/
void addTaskActor(Long processTaskId, List<String> actors);
/**
* 向指定的任务id添加参与者
*
* @param processTaskId 流程任务id
* @param actors 参与者
* @param actors 参与者
*/
void addCandidateActor(Long processTaskId, List<String> actors);
/**
* 向指定任务移除参与者
*
* @param processTaskId 任务id
* @param actors 参与者
* @param actors 参与者
*/
void removeTaskActor(Long processTaskId, List<String> actors);
/**
* 根据taskId、operator,判断操作人operator是否允许执行任务
* @param task 任务对象
*
* @param task 任务对象
* @param operator 操作人
* @return boolean 是否允许操作
*/
@@ -133,6 +145,7 @@ public interface ProcessTaskService extends BaseService<ProcessTask> {
/**
* 根据任务ID获取参与者ID
*
* @param processTaskId
* @return
*/
@@ -140,7 +153,8 @@ public interface ProcessTaskService extends BaseService<ProcessTask> {
/**
* 根据当前任务对象驳回至上一步处理
* @param model 流程定义模型,用以获取上一步模型对象
*
* @param model 流程定义模型,用以获取上一步模型对象
* @param currentTask 当前任务对象
* @return Task 任务对象
*/
@@ -148,6 +162,7 @@ public interface ProcessTaskService extends BaseService<ProcessTask> {
/**
* 获取可跳转的任务节点名称
*
* @param processInstanceId
* @return
*/
@@ -155,6 +170,7 @@ public interface ProcessTaskService extends BaseService<ProcessTask> {
/**
* 创建会签任务
*
* @param taskModel
* @param execution
* @return
@@ -163,16 +179,26 @@ public interface ProcessTaskService extends BaseService<ProcessTask> {
/**
* 根据执行对象、自定义节点模型创建历史任务记录
*
* @param execution 执行对象
* @param model 自定义节点模型
* @param model 自定义节点模型
* @return 历史任务
*/
ProcessTask history(Execution execution, CustomModel model);
/**
* 根据流程实例ID获取最新的进行中的任务
*
* @param processInstanceId
* @return
*/
ProcessTaskVO latest(Long processInstanceId);
/**
* 转办任务
*
* @param taskId 任务ID
* @param transferUserId 转办用户ID
*/
void transfer(Long taskId, String transferUserId);
}
@@ -211,7 +211,7 @@ public class ProcessTaskServiceImpl extends BaseServiceImpl<ProcessTask> impleme
if (CollectionUtil.isEmpty(actors)) return;
List<String> dbActors = getTaskActors(processTaskId);
List<String> newActors = actors.stream().filter(actor -> !dbActors.contains(actor)).toList();
Sql sql = Sqls.create("select id,username,loginname,unitName from vw_user where id in (@ids)");
Sql sql = Sqls.create("select id,username,loginname,unitName,unitId from vw_user where id in (@ids)");
sql.setParam("ids", newActors);
List<NutMap> list = listMap(sql);
@@ -222,19 +222,11 @@ public class ProcessTaskServiceImpl extends BaseServiceImpl<ProcessTask> impleme
processTaskActor.setActorName(actor.getString("username"));
processTaskActor.setActorAccount(actor.getString("loginname"));
processTaskActor.setActorUnitName(actor.getString("unitName"));
processTaskActor.setActorUnitId(actor.getString("unitId"));
processTaskActor.setCreatedAt(System.currentTimeMillis());
System.out.println(StrUtil.format("给任务:{},添加参与者:{}", processTaskId, actor.toString()));
insert(processTaskActor);
}
// actors.stream().filter(actor -> !dbActors.contains(actor)).forEach(actor -> {
// ProcessTaskActor processTaskActor = new ProcessTaskActor();
// processTaskActor.setProcessTaskId(processTaskId);
// processTaskActor.setActorId(actor);
// processTaskActor.setCreatedAt(System.currentTimeMillis());
// System.out.println(StrUtil.format("给任务:{},添加参与者:{}", processTaskId, actor));
// insert(processTaskActor);
// });
}
@Override
@@ -465,6 +457,41 @@ public class ProcessTaskServiceImpl extends BaseServiceImpl<ProcessTask> impleme
return findById(processTaskList.get(0).getId());
}
@Override
@Aop(TransAop.READ_COMMITTED)
public void transfer(Long taskId, String transferUserId) {
// 设置原任务状态为已转办
ProcessTask task = fetch(taskId);
task.setTaskState(ProcessTaskStateEnum.TRANSFER.getCode());
Dict variable = FlowUtil.variableToDict(task.getVariable());
variable.put(FlowConst.TASK_FORM_DATA_PREFIX + "transferUserId", transferUserId);
task.setVariable(JSONUtil.toJsonStr(variable));
updateIgnoreNull(task);
// 创建转办任务
ProcessTask newTask = BeanUtil.copyProperties(task, ProcessTask.class, "id");
newTask.setTaskParentId(taskId);
newTask.setId(null);
newTask.setCreatedAt(null);
newTask.setUpdatedAt(null);
newTask.setCreatedBy(null);
newTask.setUpdatedBy(null);
variable.put(FlowConst.TASK_FORM_DATA_PREFIX + "transferUserId", null);
newTask.setVariable(JSONUtil.toJsonStr(variable));
newTask.setTaskState(ProcessTaskStateEnum.DOING.getCode());
dao().insert(newTask);
// 创建转办任务参与者
addTaskActor(newTask.getId(), List.of(transferUserId));
// 发布流程任务开始事件
List<ProcessTask> processTaskList = List.of(task);
processTaskList.forEach(processTask -> {
ProcessPublisher.notify(ProcessEvent.builder().eventType(ProcessEventTypeEnum.PROCESS_TASK_START).sourceId(processTask.getId()).build());
});
}
/**
* 根据Task模型的assignee、assignmentHandler属性以及运行时数据,确定参与者
*
@@ -1,5 +1,6 @@
package com.budwk.app.flow.vo;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
@@ -78,6 +79,7 @@ public class ProcessTaskVO extends ProcessTask {
this.taskFormData.put(key,ext.get(key));
this.taskFormData.put(key.replaceAll(FlowConst.TASK_FORM_DATA_PREFIX,""),ext.get(key));
});
this.taskFormData.put("finishTimeForDocx", DateUtil.format(getFinishTime(),"yyyy年MM月dd日"));
return taskFormData;
}