add 新增 warmflow 源码级定制化开发

This commit is contained in:
疯狂的狮子Li 2026-09-11 16:36:19 +08:00
parent ad017ca4da
commit bd82af3727
29 changed files with 156 additions and 297 deletions

View File

@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.warm.flow.config; package org.dromara.warm.flow.config;
import java.io.Serial;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -33,6 +34,8 @@ import java.util.List;
@Setter @Setter
@ConfigurationProperties("warm-flow") @ConfigurationProperties("warm-flow")
public class WarmFlowProperties implements Serializable { public class WarmFlowProperties implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** /**
* 开关 * 开关
@ -44,11 +47,6 @@ public class WarmFlowProperties implements Serializable {
*/ */
private FrameworkType framework; private FrameworkType framework;
/**
* 启动banner
*/
private boolean banner = true;
/** /**
* 数据填充处理类路径 * 数据填充处理类路径
*/ */
@ -101,7 +99,7 @@ public class WarmFlowProperties implements Serializable {
*/ */
private boolean topTextShow = true; private boolean topTextShow = true;
public void init() {; public void init() {
// 设置数据填充处理类 // 设置数据填充处理类
FlowEngine.initDataFillHandler(this.getDataFillHandlerPath()); FlowEngine.initDataFillHandler(this.getDataFillHandlerPath());
@ -112,25 +110,8 @@ public class WarmFlowProperties implements Serializable {
// 设置全局监听器 // 设置全局监听器
FlowEngine.initGlobalListener(this.getGlobalListenerPath()); FlowEngine.initGlobalListener(this.getGlobalListenerPath());
// 打印banner图
printBanner();
// 初始化流程状态对应的自定义三原色 // 初始化流程状态对应的自定义三原色
ChartStatus.initCustomColor(this.getChartStatusColor(), this.getChartStatusColorClassics(), this.getChartStatusColorMimic()); ChartStatus.initCustomColor(this.getChartStatusColor(), this.getChartStatusColorClassics(), this.getChartStatusColorMimic());
} }
private void printBanner() {
if (this.isBanner()) {
System.out.println("\n" +
" ▄ ▄ ▄▄▄▄▄▄ ▄ \n" +
" █ █ █ ▄▄▄ ▄ ▄▄ ▄▄▄▄▄ █ █ ▄▄▄ ▄ ▄ \n" +
" ▀ █▀█ █ ▀ █ █▀ ▀ █ █ █ ▄▄▄▄▄ █▄▄▄▄▄ █ █▀ ▀█ ▀▄ ▄ ▄▀ \n" +
" ██ ██▀ ▄▀▀▀█ █ █ █ █ █ █ █ █ █▄█▄█ \n" +
" █ █ ▀▄▄▀█ █ █ █ █ █ █▄▄ ▀█▄█▀ █ █ \n" +
"\n" +
"\033[32m :: Warm-Flow :: (v" + WarmFlowProperties.class.getPackage()
.getImplementationVersion() + ")\033[0m\n");
}
}
} }

View File

@ -1,96 +0,0 @@
/*
* Copyright 2024-2025, Warm-Flow (290631660@qq.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.warm.flow.dto;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
* 响应信息主体
*
* @author ruoyi
*/
@Setter
@Getter
public class ApiResult<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 成功
*/
public static final int SUCCESS = 200;
/**
* 失败
*/
public static final int FAIL = 500;
private int code;
private String msg;
private T data;
public static <T> ApiResult<T> ok() {
return restResult(null, SUCCESS, "操作成功");
}
public static <T> ApiResult<T> ok(T data) {
return restResult(data, SUCCESS, "操作成功");
}
public static <T> ApiResult<T> ok(T data, String msg) {
return restResult(data, SUCCESS, msg);
}
public static <T> ApiResult<T> fail() {
return restResult(null, FAIL, "操作失败");
}
public static <T> ApiResult<T> fail(String msg) {
return restResult(null, FAIL, msg);
}
public static <T> ApiResult<T> fail(T data) {
return restResult(data, FAIL, "操作失败");
}
public static <T> ApiResult<T> fail(T data, String msg) {
return restResult(data, FAIL, msg);
}
public static <T> ApiResult<T> fail(int code, String msg) {
return restResult(null, code, msg);
}
private static <T> ApiResult<T> restResult(T data, int code, String msg) {
ApiResult<T> apiResult = new ApiResult<>();
apiResult.setCode(code);
apiResult.setData(data);
apiResult.setMsg(msg);
return apiResult;
}
public static <T> Boolean isError(ApiResult<T> ret) {
return !isSuccess(ret);
}
public static <T> Boolean isSuccess(ApiResult<T> ret) {
return ApiResult.SUCCESS == ret.getCode();
}
}

View File

@ -33,7 +33,6 @@ import org.dromara.warm.flow.entity.FlowSkip;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
/** /**
* 流程定义json对象 * 流程定义json对象
@ -283,7 +282,7 @@ public class DefJson {
.map(FlowNode::getSkipList) .map(FlowNode::getSkipList)
.filter(Objects::nonNull) .filter(Objects::nonNull)
.flatMap(List::stream) .flatMap(List::stream)
.collect(Collectors.toList()); .toList();
flowCombine.setAllSkips(skipList); flowCombine.setAllSkips(skipList);
return flowCombine; return flowCombine;

View File

@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.warm.flow.dto; package org.dromara.warm.flow.dto;
import java.io.Serial;
import lombok.Getter; import lombok.Getter;
@ -28,6 +29,8 @@ import java.io.Serializable;
@Getter @Getter
@Setter @Setter
public class FlowDto implements Serializable { public class FlowDto implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** /**
* ID * ID

View File

@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.warm.flow.dto; package org.dromara.warm.flow.dto;
import java.io.Serial;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@ -34,6 +35,7 @@ import java.util.List;
@Accessors(chain = true) @Accessors(chain = true)
public class FlowPage<T> implements Serializable { public class FlowPage<T> implements Serializable {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**

View File

@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.warm.flow.dto; package org.dromara.warm.flow.dto;
import java.io.Serial;
import org.dromara.warm.flow.json.JsonUtil; import org.dromara.warm.flow.json.JsonUtil;
@ -35,13 +36,14 @@ import java.util.*;
* @author warm * @author warm
* @since 2023/3/31 17:18 * @since 2023/3/31 17:18
*/ */
@Getter
public class FlowParams implements Serializable { public class FlowParams implements Serializable {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
* 流程编码 * 流程编码
*/ */
@Getter
private String flowCode; private String flowCode;
/** /**
@ -52,7 +54,6 @@ public class FlowParams implements Serializable {
/** /**
* 节点编码如果要指定跳转节点传入 * 节点编码如果要指定跳转节点传入
*/ */
@Getter
private String nodeCode; private String nodeCode;
/** /**
@ -63,97 +64,81 @@ public class FlowParams implements Serializable {
/** /**
* 跳转类型PASS审批通过 REJECT退回 * 跳转类型PASS审批通过 REJECT退回
*/ */
@Getter
private String skipType; private String skipType;
/** /**
* 审批意见 * 审批意见
*/ */
@Getter
private String message; private String message;
/** /**
* 流程变量 * 流程变量
*/ */
@Getter
private Map<String, Object> variable = new HashMap<>(); private Map<String, Object> variable = new HashMap<>();
/** /**
* 流程实例状态 * 流程实例状态
*/ */
@Getter
private String flowStatus; private String flowStatus;
/** /**
* 历史任务表状态 * 历史任务表状态
*/ */
@Getter
private String hisStatus; private String hisStatus;
/** /**
* 流程激活状态0挂起 1激活 * 流程激活状态0挂起 1激活
*/ */
@Getter
private Integer activityStatus; private Integer activityStatus;
/** /**
* 协作方式(1审批 2转办 3委派 4会签 5票签 6加签 7减签) * 协作方式(1审批 2转办 3委派 4会签 5票签 6加签 7减签)
*/ */
@Getter
private Integer cooperateType; private Integer cooperateType;
/** /**
* 扩展字段预留给业务系统使用 * 扩展字段预留给业务系统使用
*/ */
@Getter
private String ext; private String ext;
/** /**
* 扩展字段预留给业务系统使用 * 扩展字段预留给业务系统使用
*/ */
@Getter
private String hisTaskExt; private String hisTaskExt;
/** /**
* 增加办理人加签转办委托 * 增加办理人加签转办委托
*/ */
@Getter
private List<String> addHandlers; private List<String> addHandlers;
/** /**
* 减少办理人减签委托 * 减少办理人减签委托
*/ */
@Getter
private List<String> reductionHandlers; private List<String> reductionHandlers;
/** /**
* 忽略-办理权限校验true忽略false不忽略 * 忽略-办理权限校验true忽略false不忽略
*/ */
@Getter
private boolean ignore; private boolean ignore;
/** /**
* 忽略-委派处理true忽略false不忽略 * 忽略-委派处理true忽略false不忽略
*/ */
@Getter
private boolean ignoreDepute; private boolean ignoreDepute;
/** /**
* 忽略-会签票签处理true忽略false不忽略 * 忽略-会签票签处理true忽略false不忽略
*/ */
@Getter
private boolean ignoreCooperate; private boolean ignoreCooperate;
/** /**
* 执行的下个任务的办理人 * 执行的下个任务的办理人
*/ */
@Getter
private String[] nextHandler; private String[] nextHandler;
/** /**
* 下个任务处理人配置类型true-追加false-覆盖默认false * 下个任务处理人配置类型true-追加false-覆盖默认false
*/ */
@Getter
private boolean nextHandlerAppend; private boolean nextHandlerAppend;
public FlowParams() { public FlowParams() {

View File

@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.warm.flow.dto; package org.dromara.warm.flow.dto;
import java.io.Serial;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
@ -37,6 +38,7 @@ import java.util.List;
@NoArgsConstructor @NoArgsConstructor
public class Tree implements Serializable { public class Tree implements Serializable {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**

View File

@ -62,7 +62,7 @@ public class FlowDefinition implements RootEntity {
* *
* 删除标记 * 删除标记
*/ */
@TableLogic(value = "0", delval = "1") @TableLogic
private String delFlag; private String delFlag;
/** /**

View File

@ -50,7 +50,7 @@ public class FlowHisTask implements RootEntity {
/** /**
* 删除标记 * 删除标记
*/ */
@TableLogic(value = "0", delval = "1") @TableLogic
private String delFlag; private String delFlag;
/** /**

View File

@ -59,7 +59,7 @@ public class FlowInstance implements RootEntity {
/** /**
* 删除标记 * 删除标记
*/ */
@TableLogic(value = "0", delval = "1") @TableLogic
private String delFlag; private String delFlag;
/** /**

View File

@ -67,7 +67,7 @@ public class FlowNode implements RootEntity {
/** /**
* 删除标记 * 删除标记
*/ */
@TableLogic(value = "0", delval = "1") @TableLogic
private String delFlag; private String delFlag;
/** /**

View File

@ -57,7 +57,7 @@ public class FlowSkip implements RootEntity {
/** /**
* 删除标记 * 删除标记
*/ */
@TableLogic(value = "0", delval = "1") @TableLogic
private String delFlag; private String delFlag;
/** /**

View File

@ -59,7 +59,7 @@ public class FlowTask implements RootEntity {
/** /**
* 删除标记 * 删除标记
*/ */
@TableLogic(value = "0", delval = "1") @TableLogic
private String delFlag; private String delFlag;
/** /**

View File

@ -57,7 +57,7 @@ public class FlowUser implements RootEntity {
/** /**
* 删除标记 * 删除标记
*/ */
@TableLogic(value = "0", delval = "1") @TableLogic
private String delFlag; private String delFlag;
/** /**

View File

@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.warm.flow.exception; package org.dromara.warm.flow.exception;
import java.io.Serial;
import lombok.Getter; import lombok.Getter;
@ -23,6 +24,7 @@ import lombok.Getter;
* @author warm * @author warm
*/ */
public final class FlowException extends RuntimeException { public final class FlowException extends RuntimeException {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**

View File

@ -43,7 +43,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
/** /**
* 流程图绘制Service业务层处理 * 流程图绘制Service业务层处理
@ -61,8 +60,9 @@ public class ChartService {
Map<String, NodeJson> nodeMap = StreamUtils.toMap(nodeList, NodeJson::getNodeCode Map<String, NodeJson> nodeMap = StreamUtils.toMap(nodeList, NodeJson::getNodeCode
, node -> node.setStatus(ChartStatus.NOT_DONE.getKey())); , node -> node.setStatus(ChartStatus.NOT_DONE.getKey()));
Map<String, SkipJson> skipMap = nodeList.stream().map(NodeJson::getSkipList).flatMap(List::stream) List<SkipJson> allSkips = nodeList.stream().map(NodeJson::getSkipList).flatMap(List::stream).toList();
.collect(Collectors.toMap(this::getSkipKey, skip -> skip.setStatus(ChartStatus.NOT_DONE.getKey()))); Map<String, SkipJson> skipMap = StreamUtils.toMap(allSkips, this::getSkipKey
, skip -> skip.setStatus(ChartStatus.NOT_DONE.getKey()));
pathWayData.getPathWayNodes().forEach(node -> nodeMap.get(node.getNodeCode()).setStatus(ChartStatus.DONE.getKey())); pathWayData.getPathWayNodes().forEach(node -> nodeMap.get(node.getNodeCode()).setStatus(ChartStatus.DONE.getKey()));
pathWayData.getPathWaySkips().forEach(skip -> skipMap.get(getSkipKey(skip)).setStatus(ChartStatus.DONE.getKey())); pathWayData.getPathWaySkips().forEach(skip -> skipMap.get(getSkipKey(skip)).setStatus(ChartStatus.DONE.getKey()));
@ -79,7 +79,7 @@ public class ChartService {
List<NodeJson> nodeList = defJson.getNodeList(); List<NodeJson> nodeList = defJson.getNodeList();
List<SkipJson> skipList = defJson.getNodeList().stream().map(NodeJson::getSkipList) List<SkipJson> skipList = defJson.getNodeList().stream().map(NodeJson::getSkipList)
.filter(Objects::nonNull).flatMap(List::stream).collect(Collectors.toList()); .filter(Objects::nonNull).flatMap(List::stream).toList();
Map<String, NodeJson> nodeMap = StreamUtils.toMap(nodeList, NodeJson::getNodeCode, node -> node); Map<String, NodeJson> nodeMap = StreamUtils.toMap(nodeList, NodeJson::getNodeCode, node -> node);
Map<String, SkipJson> skipMap = StreamUtils.toMap(skipList, this::getSkipKey, skip -> skip); Map<String, SkipJson> skipMap = StreamUtils.toMap(skipList, this::getSkipKey, skip -> skip);

View File

@ -155,8 +155,7 @@ public class DefService extends WarmServiceImpl<FlowDefinition> {
List<FlowNode> nodeList = FlowEngine.nodeService().getByDefId(id); List<FlowNode> nodeList = FlowEngine.nodeService().getByDefId(id);
definition.setNodeList(nodeList); definition.setNodeList(nodeList);
List<FlowSkip> skips = FlowEngine.skipService().getByDefId(id); List<FlowSkip> skips = FlowEngine.skipService().getByDefId(id);
Map<String, List<FlowSkip>> flowSkipMap = skips.stream() Map<String, List<FlowSkip>> flowSkipMap = StreamUtils.groupByKey(skips, FlowSkip::getNowNodeCode);
.collect(Collectors.groupingBy(FlowSkip::getNowNodeCode));
nodeList.forEach(flowNode -> flowNode.setSkipList(flowSkipMap.get(flowNode.getNodeCode()))); nodeList.forEach(flowNode -> flowNode.setSkipList(flowSkipMap.get(flowNode.getNodeCode())));
return definition; return definition;
} }
@ -254,8 +253,8 @@ public class DefService extends WarmServiceImpl<FlowDefinition> {
FlowDefinition definition = sourceDef.copy(); FlowDefinition definition = sourceDef.copy();
definition.setVersion(getNewVersion(definition)); definition.setVersion(getNewVersion(definition));
List<FlowNode> nodeList = FlowEngine.nodeService().getByDefId(id).stream().map(FlowNode::copy).collect(Collectors.toList()); List<FlowNode> nodeList = StreamUtils.toList(FlowEngine.nodeService().getByDefId(id), FlowNode::copy);
List<FlowSkip> skipList = FlowEngine.skipService().getByDefId(id).stream().map(FlowSkip::copy).collect(Collectors.toList()); List<FlowSkip> skipList = StreamUtils.toList(FlowEngine.skipService().getByDefId(id), FlowSkip::copy);
FlowEngine.dataFillHandler().idFill(definition); FlowEngine.dataFillHandler().idFill(definition);
nodeList.forEach(node -> node.setDefinitionId(definition.getId()).setVersion(definition.getVersion())); nodeList.forEach(node -> node.setDefinitionId(definition.getId()).setVersion(definition.getVersion()));

View File

@ -40,7 +40,6 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import org.dromara.warm.flow.entity.FlowInstance; import org.dromara.warm.flow.entity.FlowInstance;
@ -202,11 +201,8 @@ public class InsService extends WarmServiceImpl<FlowInstance> {
List<Long> taskIds = new ArrayList<>(); List<Long> taskIds = new ArrayList<>();
instanceIds.forEach(instanceId -> taskIds.addAll( instanceIds.forEach(instanceId -> taskIds.addAll(
FlowEngine.taskService() StreamUtils.toList(FlowEngine.taskService()
.list(new FlowTask().setInstanceId(instanceId)) .list(new FlowTask().setInstanceId(instanceId)), FlowTask::getId)));
.stream()
.map(FlowTask::getId)
.collect(Collectors.toList())));
if (CollUtil.isNotEmpty(taskIds)) { if (CollUtil.isNotEmpty(taskIds)) {
FlowEngine.userService().deleteByTaskIds(taskIds); FlowEngine.userService().deleteByTaskIds(taskIds);

View File

@ -351,11 +351,7 @@ public class NodeService extends WarmServiceImpl<FlowNode> {
* @since 2024/8/21 11:32 * @since 2024/8/21 11:32
*/ */
private FlowSkip getSkipByCheck(List<FlowSkip> skips, String skipType) { private FlowSkip getSkipByCheck(List<FlowSkip> skips, String skipType) {
return Optional.ofNullable(skips) return StreamUtils.findFirst(skips, t -> StrUtil.isEmpty(t.getSkipType()) || skipType.equals(t.getSkipType()))
.orElse(Collections.emptyList())
.stream()
.filter(t -> StrUtil.isEmpty(t.getSkipType()) || skipType.equals(t.getSkipType()))
.findFirst()
.orElseThrow(() -> new FlowException(ExceptionCons.NULL_SKIP_TYPE)); .orElseThrow(() -> new FlowException(ExceptionCons.NULL_SKIP_TYPE));
} }

View File

@ -37,7 +37,6 @@ import org.dromara.warm.flow.utils.*;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import org.dromara.warm.flow.entity.FlowTask; import org.dromara.warm.flow.entity.FlowTask;
@ -159,57 +158,57 @@ public class TaskService extends WarmServiceImpl<FlowTask> {
// TODO min 后续考虑并发问题待办任务和实例表不同步可给待办任务id加锁抽取所接口方便后续兼容分布式锁 // TODO min 后续考虑并发问题待办任务和实例表不同步可给待办任务id加锁抽取所接口方便后续兼容分布式锁
// 流程开启前正确性校验 // 流程开启前正确性校验
R r = getAndCheck(task); R r = getAndCheck(task);
flowParams.variable(MapUtil.mergeAll(r.instance.getVariableMap(), flowParams.getVariable())); flowParams.variable(MapUtil.mergeAll(r.instance().getVariableMap(), flowParams.getVariable()));
// 非第一个记得跳转类型必传 // 非第一个记得跳转类型必传
if (!NodeType.isStart(task.getNodeType())) { if (!NodeType.isStart(task.getNodeType())) {
AssertUtil.isFalse(StrUtil.isNotEmpty(flowParams.getSkipType()), ExceptionCons.NULL_CONDITION_VALUE); AssertUtil.isFalse(StrUtil.isNotEmpty(flowParams.getSkipType()), ExceptionCons.NULL_CONDITION_VALUE);
} }
task.setUserList(FlowEngine.userService().listByAssociatedAndTypes(task.getId())); task.setUserList(FlowEngine.userService().listByAssociatedAndTypes(task.getId()));
FlowCombine flowCombine = FlowEngine.defService().getFlowCombineNoDef(r.definition.getId()); FlowCombine flowCombine = FlowEngine.defService().getFlowCombineNoDef(r.definition().getId());
// 执行开始监听器 // 执行开始监听器
ListenerUtil.executeStart(new ListenerVariable(r.definition, r.instance, r.nowNode, flowParams.getVariable() ListenerUtil.executeStart(new ListenerVariable(r.definition(), r.instance(), r.nowNode(), flowParams.getVariable()
, task).setFlowParams(flowParams)); , task).setFlowParams(flowParams));
// 如果是受托人在处理任务需要处理一条委派记录并且更新委托人回到计划审批人,然后直接返回流程实例 // 如果是受托人在处理任务需要处理一条委派记录并且更新委托人回到计划审批人,然后直接返回流程实例
if (!flowParams.isIgnoreDepute() && handleDepute(task, flowParams)) { if (!flowParams.isIgnoreDepute() && handleDepute(task, flowParams)) {
return r.instance; return r.instance();
} }
// 判断当前处理人是否有权限处理 // 判断当前处理人是否有权限处理
checkAuth(task, flowParams); checkAuth(task, flowParams);
//或签会签票签逻辑处理 //或签会签票签逻辑处理
if (!flowParams.isIgnoreCooperate() && cooperate(r.nowNode, task, flowParams)) { if (!flowParams.isIgnoreCooperate() && cooperate(r.nowNode(), task, flowParams)) {
return r.instance; return r.instance();
} }
// 获取后续任务节点结合 // 获取后续任务节点结合
PathWayData pathWayData = new PathWayData().setInsId(task.getInstanceId()).setSkipType(flowParams.getSkipType()); PathWayData pathWayData = new PathWayData().setInsId(task.getInstanceId()).setSkipType(flowParams.getSkipType());
FlowNode nextNode = FlowEngine.nodeService().getNextNode(r.nowNode, flowParams.getNodeCode() FlowNode nextNode = FlowEngine.nodeService().getNextNode(r.nowNode(), flowParams.getNodeCode()
, flowParams.getSkipType(), pathWayData, flowCombine); , flowParams.getSkipType(), pathWayData, flowCombine);
List<FlowNode> nextNodes = FlowEngine.nodeService().getNextByCheckGateway(flowParams.getVariable() List<FlowNode> nextNodes = FlowEngine.nodeService().getNextByCheckGateway(flowParams.getVariable()
, nextNode, pathWayData, flowCombine); , nextNode, pathWayData, flowCombine);
// 判断并行网关和包容网关节点只剩一个前置代办任务才能生成新的代办任务 // 判断并行网关和包容网关节点只剩一个前置代办任务才能生成新的代办任务
isGenerateNewTask(pathWayData, r.instance, nextNodes); isGenerateNewTask(pathWayData, r.instance(), nextNodes);
pathWayData.getTargetNodes().addAll(nextNodes); pathWayData.getTargetNodes().addAll(nextNodes);
// 设置流程图元数据 // 设置流程图元数据
r.instance.setDefJson(FlowEngine.chartService().skipMetadata(pathWayData)); r.instance().setDefJson(FlowEngine.chartService().skipMetadata(pathWayData));
// 构建增待办任务和设置结束任务历史记录 // 构建增待办任务和设置结束任务历史记录
List<FlowTask> addTasks = StreamUtils.toList(nextNodes, node -> addTask(node, r.instance, r.definition, flowParams)); List<FlowTask> addTasks = StreamUtils.toList(nextNodes, node -> addTask(node, r.instance(), r.definition(), flowParams));
// 办理人变量替换 // 办理人变量替换
ExpressionUtil.evalVariable(addTasks, flowParams.variable(MapUtil.mergeAll(r.instance.getVariableMap(), flowParams.getVariable()))); ExpressionUtil.evalVariable(addTasks, flowParams.variable(MapUtil.mergeAll(r.instance().getVariableMap(), flowParams.getVariable())));
// 执行分派监听器 // 执行分派监听器
ListenerUtil.executeAssignment(new ListenerVariable(r.definition, r.instance, r.nowNode, flowParams.getVariable() ListenerUtil.executeAssignment(new ListenerVariable(r.definition(), r.instance(), r.nowNode(), flowParams.getVariable()
, task, nextNodes, addTasks).setFlowParams(flowParams)); , task, nextNodes, addTasks).setFlowParams(flowParams));
// 更新流程信息 // 更新流程信息
updateFlowInfo(task, r.instance, addTasks, flowParams, nextNodes); updateFlowInfo(task, r.instance(), addTasks, flowParams, nextNodes);
// 一票否决谨慎使用如果退回退回指向节点后还存在其他正在执行的待办任务转历史任务状态都为失效,重走流程 // 一票否决谨慎使用如果退回退回指向节点后还存在其他正在执行的待办任务转历史任务状态都为失效,重走流程
if (CollUtil.isNotEmpty(nextNodes) && SkipType.isReject(flowParams.getSkipType())) { if (CollUtil.isNotEmpty(nextNodes) && SkipType.isReject(flowParams.getSkipType())) {
@ -217,13 +216,13 @@ public class TaskService extends WarmServiceImpl<FlowTask> {
} }
// 处理未完成的任务当流程完成还存在待办任务未完成转历史任务状态完成 // 处理未完成的任务当流程完成还存在待办任务未完成转历史任务状态完成
handUndoneTask(r.instance); handUndoneTask(r.instance());
// 执行完成和创建监听器 // 执行完成和创建监听器
ListenerUtil.endCreateListener(new ListenerVariable(r.definition, r.instance, r.nowNode ListenerUtil.endCreateListener(new ListenerVariable(r.definition(), r.instance(), r.nowNode()
, flowParams.getVariable(), task, nextNodes, addTasks).setFlowParams(flowParams)); , flowParams.getVariable(), task, nextNodes, addTasks).setFlowParams(flowParams));
return r.instance; return r.instance();
} }
public FlowInstance revoke(Long instanceId, FlowParams flowParams) { public FlowInstance revoke(Long instanceId, FlowParams flowParams) {
@ -318,8 +317,8 @@ public class TaskService extends WarmServiceImpl<FlowTask> {
public FlowInstance termination(FlowTask task, FlowParams flowParams) { public FlowInstance termination(FlowTask task, FlowParams flowParams) {
R r = getAndCheck(task); R r = getAndCheck(task);
flowParams.skipType(SkipType.PASS.getKey()); flowParams.skipType(SkipType.PASS.getKey());
flowParams.variable(MapUtil.mergeAll(r.instance.getVariableMap(), flowParams.getVariable())); flowParams.variable(MapUtil.mergeAll(r.instance().getVariableMap(), flowParams.getVariable()));
ListenerUtil.executeStart(new ListenerVariable(r.definition, r.instance, r.nowNode, flowParams.getVariable() ListenerUtil.executeStart(new ListenerVariable(r.definition(), r.instance(), r.nowNode(), flowParams.getVariable()
, task).setFlowParams(flowParams)); , task).setFlowParams(flowParams));
// 判断当前处理人是否有权限处理 // 判断当前处理人是否有权限处理
@ -327,38 +326,38 @@ public class TaskService extends WarmServiceImpl<FlowTask> {
checkAuth(task, flowParams); checkAuth(task, flowParams);
// 所有待办转历史 // 所有待办转历史
FlowNode endNode = FlowEngine.nodeService().getEndNode(r.instance.getDefinitionId()); FlowNode endNode = FlowEngine.nodeService().getEndNode(r.instance().getDefinitionId());
// 设置流程图元数据 // 设置流程图元数据
PathWayData pathWayData = new PathWayData() PathWayData pathWayData = new PathWayData()
.setInsId(task.getInstanceId()) .setInsId(task.getInstanceId())
.setSkipType(flowParams.getSkipType()) .setSkipType(flowParams.getSkipType())
.setPathWayNodes(Collections.singletonList(r.nowNode)) .setPathWayNodes(Collections.singletonList(r.nowNode()))
.setTargetNodes(Collections.singletonList(endNode)); .setTargetNodes(Collections.singletonList(endNode));
r.instance.setDefJson(FlowEngine.chartService().skipMetadata(pathWayData)); r.instance().setDefJson(FlowEngine.chartService().skipMetadata(pathWayData));
// 流程实例完成 // 流程实例完成
r.instance.setNodeType(endNode.getNodeType()) r.instance().setNodeType(endNode.getNodeType())
.setNodeCode(endNode.getNodeCode()) .setNodeCode(endNode.getNodeCode())
.setNodeName(endNode.getNodeName()) .setNodeName(endNode.getNodeName())
.setFlowStatus(StrUtil.emptyToDefault(flowParams.getFlowStatus(), FlowStatus.TERMINATE.getKey())); .setFlowStatus(StrUtil.emptyToDefault(flowParams.getFlowStatus(), FlowStatus.TERMINATE.getKey()));
// 待办任务转历史 // 待办任务转历史
flowParams.flowStatus(r.instance.getFlowStatus()); flowParams.flowStatus(r.instance().getFlowStatus());
FlowHisTask insHis = FlowEngine.hisTaskService().setSkipInsHis(task, Collections.singletonList(endNode) FlowHisTask insHis = FlowEngine.hisTaskService().setSkipInsHis(task, Collections.singletonList(endNode)
, flowParams); , flowParams);
FlowEngine.hisTaskService().save(insHis); FlowEngine.hisTaskService().save(insHis);
FlowEngine.insService().updateById(r.instance); FlowEngine.insService().updateById(r.instance());
// 删除流程相关办理人 // 删除流程相关办理人
FlowEngine.userService().deleteByTaskIds(Collections.singletonList(task.getId())); FlowEngine.userService().deleteByTaskIds(Collections.singletonList(task.getId()));
// 处理未完成的任务当流程完成还存在待办任务未完成转历史任务状态完成 // 处理未完成的任务当流程完成还存在待办任务未完成转历史任务状态完成
handUndoneTask(r.instance); handUndoneTask(r.instance());
// 最后判断是否存在节点监听器存在执行节点监听器 // 最后判断是否存在节点监听器存在执行节点监听器
ListenerUtil.executeFinish(new ListenerVariable(r.definition, r.instance, r.nowNode, flowParams.getVariable() ListenerUtil.executeFinish(new ListenerVariable(r.definition(), r.instance(), r.nowNode(), flowParams.getVariable()
, task).setFlowParams(flowParams)); , task).setFlowParams(flowParams));
return r.instance; return r.instance();
} }
public boolean deleteByInsIds(List<Long> instanceIds) { public boolean deleteByInsIds(List<Long> instanceIds) {
@ -421,9 +420,9 @@ public class TaskService extends WarmServiceImpl<FlowTask> {
public boolean updateHandler(Long taskId, FlowParams flowParams) { public boolean updateHandler(Long taskId, FlowParams flowParams) {
// 获取待办任务 // 获取待办任务
R r = getAndCheck(taskId); R r = getAndCheck(taskId);
flowParams.variable(MapUtil.mergeAll(r.instance.getVariableMap(), flowParams.getVariable())); flowParams.variable(MapUtil.mergeAll(r.instance().getVariableMap(), flowParams.getVariable()));
// 执行开始监听器 // 执行开始监听器
ListenerUtil.executeStart(new ListenerVariable(r.definition, r.instance, r.nowNode, null, r.task)); ListenerUtil.executeStart(new ListenerVariable(r.definition(), r.instance(), r.nowNode(), null, r.task()));
// 获取给谁的权限 // 获取给谁的权限
if (!flowParams.isIgnore()) { if (!flowParams.isIgnore()) {
@ -444,7 +443,7 @@ public class TaskService extends WarmServiceImpl<FlowTask> {
FlowEngine.userService().remove(new FlowUser().setAssociated(taskId) FlowEngine.userService().remove(new FlowUser().setAssociated(taskId)
.setProcessedBy(reductionHandler)); .setProcessedBy(reductionHandler));
} }
hisTask = FlowEngine.hisTaskService().setCooperateHis(r.task, flowParams, flowParams.getReductionHandlers()); hisTask = FlowEngine.hisTaskService().setCooperateHis(r.task(), flowParams, flowParams.getReductionHandlers());
} }
// 新增权限人 // 新增权限人
@ -460,14 +459,14 @@ public class TaskService extends WarmServiceImpl<FlowTask> {
FlowEngine.userService().saveBatch(StreamUtils.toList(flowParams.getAddHandlers(), permission -> FlowEngine.userService().saveBatch(StreamUtils.toList(flowParams.getAddHandlers(), permission ->
FlowEngine.userService().structureUser(taskId, permission FlowEngine.userService().structureUser(taskId, permission
, type, flowParams.getHandler()))); , type, flowParams.getHandler())));
hisTask = FlowEngine.hisTaskService().setCooperateHis(r.task, flowParams, flowParams.getAddHandlers()); hisTask = FlowEngine.hisTaskService().setCooperateHis(r.task(), flowParams, flowParams.getAddHandlers());
} }
if (ObjectUtil.isNotNull(hisTask)) { if (ObjectUtil.isNotNull(hisTask)) {
FlowEngine.hisTaskService().save(hisTask); FlowEngine.hisTaskService().save(hisTask);
} }
// 最后判断是否存在节点监听器存在执行节点监听器 // 最后判断是否存在节点监听器存在执行节点监听器
ListenerUtil.executeFinish(new ListenerVariable(r.definition, r.instance, r.nowNode, flowParams.getVariable() ListenerUtil.executeFinish(new ListenerVariable(r.definition(), r.instance(), r.nowNode(), flowParams.getVariable()
, r.task)); , r.task()));
return true; return true;
} }
@ -487,23 +486,23 @@ public class TaskService extends WarmServiceImpl<FlowTask> {
R r = getAndCheck(task); R r = getAndCheck(task);
flowParams.flowStatus(StrUtil.emptyToDefault(flowParams.getFlowStatus(), FlowStatus.PENDING.getKey())); flowParams.flowStatus(StrUtil.emptyToDefault(flowParams.getFlowStatus(), FlowStatus.PENDING.getKey()));
// 执行开始监听器 // 执行开始监听器
ListenerUtil.executeStart(new ListenerVariable(r.definition, r.instance, r.nowNode, flowParams.getVariable() ListenerUtil.executeStart(new ListenerVariable(r.definition(), r.instance(), r.nowNode(), flowParams.getVariable()
, r.task).setFlowParams(flowParams)); , r.task()).setFlowParams(flowParams));
// 判断当前处理人是否有权限处理 // 判断当前处理人是否有权限处理
checkAuth(r.task, flowParams); checkAuth(r.task(), flowParams);
// 设置流程历史任务信息 // 设置流程历史任务信息
FlowHisTask insHis = FlowEngine.hisTaskService().notSkip(r.task, flowParams); FlowHisTask insHis = FlowEngine.hisTaskService().notSkip(r.task(), flowParams);
FlowEngine.hisTaskService().save(insHis); FlowEngine.hisTaskService().save(insHis);
FlowEngine.insService().updateById(r.instance.setFlowStatus(flowParams.getFlowStatus())); FlowEngine.insService().updateById(r.instance().setFlowStatus(flowParams.getFlowStatus()));
// 执行任务完成监听器 // 执行任务完成监听器
ListenerUtil.executeFinish(new ListenerVariable(r.definition, r.instance, r.nowNode ListenerUtil.executeFinish(new ListenerVariable(r.definition(), r.instance(), r.nowNode()
, flowParams.getVariable(), r.task)); , flowParams.getVariable(), r.task()));
return r.instance; return r.instance();
} }
public FlowTask addTask(FlowNode node, FlowInstance instance, FlowDefinition definition, FlowParams flowParams) { public FlowTask addTask(FlowNode node, FlowInstance instance, FlowDefinition definition, FlowParams flowParams) {
@ -544,9 +543,7 @@ public class TaskService extends WarmServiceImpl<FlowTask> {
mergeVariable(instance, flowParams.getVariable()); mergeVariable(instance, flowParams.getVariable());
if (CollUtil.isNotEmpty(addTasks)) { if (CollUtil.isNotEmpty(addTasks)) {
// 终结节点任务不算待办任务取其中最后一个作为实例最终信息 // 终结节点任务不算待办任务取其中最后一个作为实例最终信息
List<FlowTask> endTasks = addTasks.stream() List<FlowTask> endTasks = StreamUtils.filter(addTasks, addTask -> NodeType.isEnd(addTask.getNodeType()));
.filter(addTask -> NodeType.isEnd(addTask.getNodeType()))
.collect(Collectors.toList());
addTasks.removeAll(endTasks); addTasks.removeAll(endTasks);
FlowTask finallyTask = CollUtil.getLast(endTasks); FlowTask finallyTask = CollUtil.getLast(endTasks);
if (finallyTask == null) { if (finallyTask == null) {
@ -650,18 +647,10 @@ public class TaskService extends WarmServiceImpl<FlowTask> {
return new R(instance, definition, nowNode, task); return new R(instance, definition, nowNode, task);
} }
private static class R { /**
public final FlowInstance instance; * 办理校验后的上下文实例定义当前节点当前任务
public final FlowDefinition definition; */
public final FlowNode nowNode; private record R(FlowInstance instance, FlowDefinition definition, FlowNode nowNode, FlowTask task) {
public final FlowTask task;
public R(FlowInstance instance, FlowDefinition definition, FlowNode nowNode, FlowTask task) {
this.instance = instance;
this.definition = definition;
this.nowNode = nowNode;
this.task = task;
}
} }
private boolean handleDepute(FlowTask task, FlowParams flowParams) { private boolean handleDepute(FlowTask task, FlowParams flowParams) {
@ -828,9 +817,8 @@ public class TaskService extends WarmServiceImpl<FlowTask> {
DefJson defJson = JsonUtil.strToBean(instance.getDefJson(), DefJson.class); DefJson defJson = JsonUtil.strToBean(instance.getDefJson(), DefJson.class);
Map<String, NodeJson> nodeJsonMap = StreamUtils.toMap(defJson.getNodeList(), NodeJson::getNodeCode, node -> node); Map<String, NodeJson> nodeJsonMap = StreamUtils.toMap(defJson.getNodeList(), NodeJson::getNodeCode, node -> node);
// 途径节点中的并行/包容网关只剩一个前置待办任务时才能生成新的代办任务 // 途径节点中的并行/包容网关只剩一个前置待办任务时才能生成新的代办任务
List<FlowNode> parallelOrInclusiveList = pathWayData.getPathWayNodes().stream() List<FlowNode> parallelOrInclusiveList = StreamUtils.filter(pathWayData.getPathWayNodes(),
.filter(t -> NodeType.isGateWayParallel(t.getNodeType()) || NodeType.isGateWayInclusive(t.getNodeType())) t -> NodeType.isGateWayParallel(t.getNodeType()) || NodeType.isGateWayInclusive(t.getNodeType()));
.collect(Collectors.toList());
if (CollUtil.isEmpty(parallelOrInclusiveList)) { if (CollUtil.isEmpty(parallelOrInclusiveList)) {
return; return;
} }
@ -964,7 +952,7 @@ public class TaskService extends WarmServiceImpl<FlowTask> {
R r = getAndCheck(taskId); R r = getAndCheck(taskId);
FlowDto flowDto = new FlowDto(); FlowDto flowDto = new FlowDto();
flowDto.setData(r.instance.getVariableMap().get(FlowCons.FORM_DATA)); flowDto.setData(r.instance().getVariableMap().get(FlowCons.FORM_DATA));
return flowDto; return flowDto;
} }

View File

@ -55,7 +55,7 @@ public interface HandlerStrategy extends ExpressionStrategy<List<String>> {
return StreamUtils.toList((List<?>) o, Object::toString); return StreamUtils.toList((List<?>) o, Object::toString);
} }
if (o instanceof Object[]) { if (o instanceof Object[]) {
return Arrays.stream((Object[]) o).map(Object::toString).collect(Collectors.toList()); return Arrays.stream((Object[]) o).map(Object::toString).toList();
} }
return Collections.singletonList(o.toString()); return Collections.singletonList(o.toString());
} }

View File

@ -15,7 +15,7 @@
*/ */
package org.dromara.warm.flow.ui.controller; package org.dromara.warm.flow.ui.controller;
import org.dromara.warm.flow.dto.ApiResult; import org.dromara.common.core.domain.R;
import org.dromara.warm.flow.dto.DefJson; import org.dromara.warm.flow.dto.DefJson;
import org.dromara.warm.flow.dto.FlowDto; import org.dromara.warm.flow.dto.FlowDto;
import org.dromara.warm.flow.entity.FlowInstance; import org.dromara.warm.flow.entity.FlowInstance;
@ -42,14 +42,14 @@ public class WarmFlowController {
* 保存流程json字符串 * 保存流程json字符串
* *
* @param defJson 流程数据集合 * @param defJson 流程数据集合
* @return ApiResult<Void> * @return R<Void>
* @throws Exception 异常 * @throws Exception 异常
* @author xiarg * @author xiarg
* @since 2024/10/29 16:31 * @since 2024/10/29 16:31
*/ */
@PostMapping("/save-json") @PostMapping("/save-json")
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ApiResult<Void> saveJson(@RequestBody DefJson defJson, @RequestHeader("onlyNodeSkip") boolean onlyNodeSkip) throws Exception { public R<Void> saveJson(@RequestBody DefJson defJson, @RequestHeader("onlyNodeSkip") boolean onlyNodeSkip) throws Exception {
return WarmFlowService.saveJson(defJson, onlyNodeSkip); return WarmFlowService.saveJson(defJson, onlyNodeSkip);
} }
@ -57,12 +57,12 @@ public class WarmFlowController {
* 获取流程定义数据(包含节点和跳转) * 获取流程定义数据(包含节点和跳转)
* *
* @param id 流程定义id * @param id 流程定义id
* @return ApiResult<DefVo> * @return R<DefVo>
* @author xiarg * @author xiarg
* @since 2024/10/29 16:31 * @since 2024/10/29 16:31
*/ */
@GetMapping(value = {"/query-def", "/query-def/{id}"}) @GetMapping(value = {"/query-def", "/query-def/{id}"})
public ApiResult<DefJson> queryDef(@PathVariable(value = "id", required = false) Long id) { public R<DefJson> queryDef(@PathVariable(value = "id", required = false) Long id) {
return WarmFlowService.queryDef(id); return WarmFlowService.queryDef(id);
} }
@ -70,10 +70,10 @@ public class WarmFlowController {
* 获取流程图 * 获取流程图
* *
* @param id 流程实例id * @param id 流程实例id
* @return ApiResult<DefJson> * @return R<DefJson>
*/ */
@GetMapping("/query-flow-chart/{id}") @GetMapping("/query-flow-chart/{id}")
public ApiResult<DefJson> queryFlowChart(@PathVariable("id") Long id) { public R<DefJson> queryFlowChart(@PathVariable("id") Long id) {
return WarmFlowService.queryFlowChart(id); return WarmFlowService.queryFlowChart(id);
} }
@ -83,7 +83,7 @@ public class WarmFlowController {
* @return List<String> * @return List<String>
*/ */
@GetMapping("/handler-type") @GetMapping("/handler-type")
public ApiResult<List<String>> handlerType() { public R<List<String>> handlerType() {
return WarmFlowService.handlerType(); return WarmFlowService.handlerType();
} }
@ -93,7 +93,7 @@ public class WarmFlowController {
* @return HandlerSelectVo * @return HandlerSelectVo
*/ */
@GetMapping("/handler-result") @GetMapping("/handler-result")
public ApiResult<HandlerSelectVo> handlerResult(HandlerQuery query) { public R<HandlerSelectVo> handlerResult(HandlerQuery query) {
return WarmFlowService.handlerResult(query); return WarmFlowService.handlerResult(query);
} }
@ -103,7 +103,7 @@ public class WarmFlowController {
* @return HandlerSelectVo * @return HandlerSelectVo
*/ */
@GetMapping("/handler-feedback") @GetMapping("/handler-feedback")
public ApiResult<List<HandlerFeedBackVo>> handlerFeedback(HandlerFeedBackDto handlerFeedBackDto) { public R<List<HandlerFeedBackVo>> handlerFeedback(HandlerFeedBackDto handlerFeedBackDto) {
return WarmFlowService.handlerFeedback(handlerFeedBackDto); return WarmFlowService.handlerFeedback(handlerFeedBackDto);
} }
@ -113,7 +113,7 @@ public class WarmFlowController {
* @return List<Dict> * @return List<Dict>
*/ */
@GetMapping("/handler-dict") @GetMapping("/handler-dict")
public ApiResult<List<Dict>> handlerDict() { public R<List<Dict>> handlerDict() {
return WarmFlowService.handlerDict(); return WarmFlowService.handlerDict();
} }
@ -121,12 +121,12 @@ public class WarmFlowController {
* 根据任务id获取待办任务表单及数据 * 根据任务id获取待办任务表单及数据
* *
* @param taskId 当前任务id * @param taskId 当前任务id
* @return {@link ApiResult< FlowDto >} * @return {@link R< FlowDto >}
* @author liangli * @author liangli
* @date 2024/8/21 17:08 * @date 2024/8/21 17:08
**/ **/
@GetMapping(value = "/execute/load/{taskId}") @GetMapping(value = "/execute/load/{taskId}")
public ApiResult<FlowDto> load(@PathVariable("taskId") Long taskId) { public R<FlowDto> load(@PathVariable("taskId") Long taskId) {
return WarmFlowService.load(taskId); return WarmFlowService.load(taskId);
} }
@ -137,7 +137,7 @@ public class WarmFlowController {
* @return * @return
*/ */
@GetMapping(value = "/execute/hisLoad/{taskId}") @GetMapping(value = "/execute/hisLoad/{taskId}")
public ApiResult<FlowDto> hisLoad(@PathVariable("taskId") Long hisTaskId) { public R<FlowDto> hisLoad(@PathVariable("taskId") Long hisTaskId) {
return WarmFlowService.hisLoad(hisTaskId); return WarmFlowService.hisLoad(hisTaskId);
} }
@ -153,7 +153,7 @@ public class WarmFlowController {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@PostMapping(value = "/execute/handle") @PostMapping(value = "/execute/handle")
public ApiResult<FlowInstance> handle(@RequestBody Map<String, Object> formData, @RequestParam("taskId") Long taskId public R<FlowInstance> handle(@RequestBody Map<String, Object> formData, @RequestParam("taskId") Long taskId
, @RequestParam("skipType") String skipType, @RequestParam("message") String message , @RequestParam("skipType") String skipType, @RequestParam("message") String message
, @RequestParam(value = "nodeCode", required = false) String nodeCode) { , @RequestParam(value = "nodeCode", required = false) String nodeCode) {
return WarmFlowService.handle(formData, taskId, skipType, message, nodeCode); return WarmFlowService.handle(formData, taskId, skipType, message, nodeCode);
@ -165,7 +165,7 @@ public class WarmFlowController {
* @return List<NodeExt> * @return List<NodeExt>
*/ */
@GetMapping("/node-ext") @GetMapping("/node-ext")
public ApiResult<List<NodeExt>> nodeExt() { public R<List<NodeExt>> nodeExt() {
return WarmFlowService.nodeExt(); return WarmFlowService.nodeExt();
} }
@ -175,7 +175,7 @@ public class WarmFlowController {
* @return List<NodeExt> * @return List<NodeExt>
*/ */
@GetMapping("/listener-list") @GetMapping("/listener-list")
public ApiResult<List<ListenerVo>> listenerList() { public R<List<ListenerVo>> listenerList() {
return WarmFlowService.listenerList(); return WarmFlowService.listenerList();
} }

View File

@ -15,7 +15,7 @@
*/ */
package org.dromara.warm.flow.ui.controller; package org.dromara.warm.flow.ui.controller;
import org.dromara.warm.flow.dto.ApiResult; import org.dromara.common.core.domain.R;
import org.dromara.warm.flow.ui.service.WarmFlowService; import org.dromara.warm.flow.ui.service.WarmFlowService;
import org.dromara.warm.flow.ui.vo.WarmFlowVo; import org.dromara.warm.flow.ui.vo.WarmFlowVo;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@ -34,10 +34,10 @@ public class WarmFlowUiController {
/** /**
* 返回流程定义的配置 * 返回流程定义的配置
* *
* @return ApiResult<WarmFlowVo> * @return R<WarmFlowVo>
*/ */
@GetMapping("/config") @GetMapping("/config")
public ApiResult<WarmFlowVo> config() { public R<WarmFlowVo> config() {
return WarmFlowService.config(); return WarmFlowService.config();
} }

View File

@ -27,6 +27,7 @@ import org.dromara.warm.flow.entity.FlowInstance;
import org.dromara.warm.flow.enums.FormCustomEnum; import org.dromara.warm.flow.enums.FormCustomEnum;
import org.dromara.warm.flow.enums.ModelEnum; import org.dromara.warm.flow.enums.ModelEnum;
import org.dromara.warm.flow.exception.FlowException; import org.dromara.warm.flow.exception.FlowException;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StreamUtils;
@ -49,23 +50,23 @@ public class WarmFlowService {
/** /**
* 返回流程定义的配置 * 返回流程定义的配置
* *
* @return ApiResult<WarmFlowVo> * @return R<WarmFlowVo>
*/ */
public static ApiResult<WarmFlowVo> config() { public static R<WarmFlowVo> config() {
WarmFlowVo warmFlowVo = new WarmFlowVo(); WarmFlowVo warmFlowVo = new WarmFlowVo();
WarmFlowProperties warmFlow = FlowEngine.getFlowConfig(); WarmFlowProperties warmFlow = FlowEngine.getFlowConfig();
warmFlowVo.setFramework(warmFlow.getFramework().name()); warmFlowVo.setFramework(warmFlow.getFramework().name());
// 获取tokenName // 获取tokenName
String tokenName = warmFlow.getTokenName(); String tokenName = warmFlow.getTokenName();
if (StrUtil.isEmpty(tokenName)) { if (StrUtil.isEmpty(tokenName)) {
return ApiResult.fail("未配置tokenName"); return R.fail("未配置tokenName");
} }
String[] tokenNames = tokenName.split(","); String[] tokenNames = tokenName.split(",");
List<String> tokenNameList = Arrays.stream(tokenNames).filter(StrUtil::isNotEmpty) List<String> tokenNameList = Arrays.stream(tokenNames).filter(StrUtil::isNotEmpty)
.map(String::trim).collect(Collectors.toList()); .map(String::trim).toList();
warmFlowVo.setTokenNameList(tokenNameList); warmFlowVo.setTokenNameList(tokenNameList);
return ApiResult.ok(warmFlowVo); return R.ok(warmFlowVo);
} }
/** /**
@ -73,25 +74,25 @@ public class WarmFlowService {
* *
* @param defJson 流程数据集合 * @param defJson 流程数据集合
* @param onlyNodeSkip 是否只保存节点和跳转 * @param onlyNodeSkip 是否只保存节点和跳转
* @return ApiResult<Void> * @return R<Void>
* @throws Exception 异常 * @throws Exception 异常
* @author xiarg * @author xiarg
* @since 2024/10/29 16:31 * @since 2024/10/29 16:31
*/ */
public static ApiResult<Void> saveJson(DefJson defJson, boolean onlyNodeSkip) throws Exception { public static R<Void> saveJson(DefJson defJson, boolean onlyNodeSkip) throws Exception {
FlowEngine.defService().saveDef(defJson, onlyNodeSkip); FlowEngine.defService().saveDef(defJson, onlyNodeSkip);
return ApiResult.ok(); return R.ok();
} }
/** /**
* 获取流程定义数据(包含节点和跳转) * 获取流程定义数据(包含节点和跳转)
* *
* @param id 流程定义id * @param id 流程定义id
* @return ApiResult<DefVo> * @return R<DefVo>
* @author xiarg * @author xiarg
* @since 2024/10/29 16:31 * @since 2024/10/29 16:31
*/ */
public static ApiResult<DefJson> queryDef(Long id) { public static R<DefJson> queryDef(Long id) {
try { try {
DefJson defJson; DefJson defJson;
if (id == null) { if (id == null) {
@ -106,7 +107,7 @@ public class WarmFlowService {
List<Tree> treeList = categoryService.queryCategory(); List<Tree> treeList = categoryService.queryCategory();
defJson.setCategoryList(TreeUtil.buildTree(treeList)); defJson.setCategoryList(TreeUtil.buildTree(treeList));
} }
return ApiResult.ok(defJson); return R.ok(defJson);
} catch (Exception e) { } catch (Exception e) {
log.error("获取流程json字符串", e); log.error("获取流程json字符串", e);
throw new FlowException("获取流程json字符串失败", e); throw new FlowException("获取流程json字符串失败", e);
@ -117,9 +118,9 @@ public class WarmFlowService {
* 获取流程图 * 获取流程图
* *
* @param id 流程实例id * @param id 流程实例id
* @return ApiResult<DefJson> * @return R<DefJson>
*/ */
public static ApiResult<DefJson> queryFlowChart(Long id) { public static R<DefJson> queryFlowChart(Long id) {
try { try {
FlowInstance instance = FlowEngine.insService().getById(id); FlowInstance instance = FlowEngine.insService().getById(id);
String defJsonStr = instance.getDefJson(); String defJsonStr = instance.getDefJson();
@ -137,7 +138,7 @@ public class WarmFlowService {
chartExtService.execute(defJson); chartExtService.execute(defJson);
} }
return ApiResult.ok(defJson); return R.ok(defJson);
} catch (Exception e) { } catch (Exception e) {
log.error("获取流程图", e); log.error("获取流程图", e);
throw new FlowException("获取流程图失败", e); throw new FlowException("获取流程图失败", e);
@ -149,15 +150,15 @@ public class WarmFlowService {
* *
* @return List<String> * @return List<String>
*/ */
public static ApiResult<List<String>> handlerType() { public static R<List<String>> handlerType() {
try { try {
// 需要业务系统实现该接口 // 需要业务系统实现该接口
HandlerSelectService handlerSelectService = SpringUtils.getBeanOrNull(HandlerSelectService.class); HandlerSelectService handlerSelectService = SpringUtils.getBeanOrNull(HandlerSelectService.class);
if (handlerSelectService == null) { if (handlerSelectService == null) {
return ApiResult.ok(Collections.emptyList()); return R.ok(Collections.emptyList());
} }
List<String> handlerType = handlerSelectService.getHandlerType(); List<String> handlerType = handlerSelectService.getHandlerType();
return ApiResult.ok(handlerType); return R.ok(handlerType);
} catch (Exception e) { } catch (Exception e) {
log.error("办理人权限设置列表tabs页签异常", e); log.error("办理人权限设置列表tabs页签异常", e);
throw new FlowException("办理人权限设置列表tabs页签失败", e); throw new FlowException("办理人权限设置列表tabs页签失败", e);
@ -169,15 +170,15 @@ public class WarmFlowService {
* *
* @return HandlerSelectVo * @return HandlerSelectVo
*/ */
public static ApiResult<HandlerSelectVo> handlerResult(HandlerQuery query) { public static R<HandlerSelectVo> handlerResult(HandlerQuery query) {
try { try {
// 需要业务系统实现该接口 // 需要业务系统实现该接口
HandlerSelectService handlerSelectService = SpringUtils.getBeanOrNull(HandlerSelectService.class); HandlerSelectService handlerSelectService = SpringUtils.getBeanOrNull(HandlerSelectService.class);
if (handlerSelectService == null) { if (handlerSelectService == null) {
return ApiResult.ok(new HandlerSelectVo()); return R.ok(new HandlerSelectVo());
} }
HandlerSelectVo handlerSelectVo = handlerSelectService.getHandlerSelect(query); HandlerSelectVo handlerSelectVo = handlerSelectService.getHandlerSelect(query);
return ApiResult.ok(handlerSelectVo); return R.ok(handlerSelectVo);
} catch (Exception e) { } catch (Exception e) {
log.error("办理人权限设置列表结果异常", e); log.error("办理人权限设置列表结果异常", e);
throw new FlowException("办理人权限设置列表结果失败", e); throw new FlowException("办理人权限设置列表结果失败", e);
@ -189,17 +190,17 @@ public class WarmFlowService {
* *
* @return HandlerSelectVo * @return HandlerSelectVo
*/ */
public static ApiResult<List<HandlerFeedBackVo>> handlerFeedback(HandlerFeedBackDto handlerFeedBackDto) { public static R<List<HandlerFeedBackVo>> handlerFeedback(HandlerFeedBackDto handlerFeedBackDto) {
try { try {
// 需要业务系统实现该接口 // 需要业务系统实现该接口
HandlerSelectService handlerSelectService = SpringUtils.getBeanOrNull(HandlerSelectService.class); HandlerSelectService handlerSelectService = SpringUtils.getBeanOrNull(HandlerSelectService.class);
if (handlerSelectService == null) { if (handlerSelectService == null) {
List<HandlerFeedBackVo> handlerFeedBackVos = StreamUtils.toList(handlerFeedBackDto.getStorageIds(), List<HandlerFeedBackVo> handlerFeedBackVos = StreamUtils.toList(handlerFeedBackDto.getStorageIds(),
storageId -> new HandlerFeedBackVo(storageId, null)); storageId -> new HandlerFeedBackVo(storageId, null));
return ApiResult.ok(handlerFeedBackVos); return R.ok(handlerFeedBackVos);
} }
List<HandlerFeedBackVo> handlerFeedBackVos = handlerSelectService.handlerFeedback(handlerFeedBackDto.getStorageIds()); List<HandlerFeedBackVo> handlerFeedBackVos = handlerSelectService.handlerFeedback(handlerFeedBackDto.getStorageIds());
return ApiResult.ok(handlerFeedBackVos); return R.ok(handlerFeedBackVos);
} catch (Exception e) { } catch (Exception e) {
log.error("办理人权限名称回显", e); log.error("办理人权限名称回显", e);
throw new FlowException("办理人权限名称回显", e); throw new FlowException("办理人权限名称回显", e);
@ -211,7 +212,7 @@ public class WarmFlowService {
* *
* @return List<Dict> * @return List<Dict>
*/ */
public static ApiResult<List<Dict>> handlerDict() { public static R<List<Dict>> handlerDict() {
try { try {
// 需要业务系统实现该接口 // 需要业务系统实现该接口
HandlerDictService handlerDictService = SpringUtils.getBeanOrNull(HandlerDictService.class); HandlerDictService handlerDictService = SpringUtils.getBeanOrNull(HandlerDictService.class);
@ -230,9 +231,9 @@ public class WarmFlowService {
dictList.add(dict1); dictList.add(dict1);
dictList.add(dict2); dictList.add(dict2);
return ApiResult.ok(dictList); return R.ok(dictList);
} }
return ApiResult.ok(handlerDictService.getHandlerDict()); return R.ok(handlerDictService.getHandlerDict());
} catch (Exception e) { } catch (Exception e) {
log.error("办理人权限设置列表结果异常", e); log.error("办理人权限设置列表结果异常", e);
throw new FlowException("办理人权限设置列表结果失败", e); throw new FlowException("办理人权限设置列表结果失败", e);
@ -243,14 +244,14 @@ public class WarmFlowService {
* 根据任务id获取待办任务表单及数据 * 根据任务id获取待办任务表单及数据
* *
* @param taskId 当前任务id * @param taskId 当前任务id
* @return {@link ApiResult<FlowDto>} * @return {@link R<FlowDto>}
* @author liangli * @author liangli
* @date 2024/8/21 17:08 * @date 2024/8/21 17:08
**/ **/
public static ApiResult<FlowDto> load(Long taskId) { public static R<FlowDto> load(Long taskId) {
FlowParams flowParams = FlowParams.build(); FlowParams flowParams = FlowParams.build();
return ApiResult.ok(FlowEngine.taskService().load(taskId, flowParams)); return R.ok(FlowEngine.taskService().load(taskId, flowParams));
} }
/** /**
@ -259,10 +260,10 @@ public class WarmFlowService {
* @param hisTaskId * @param hisTaskId
* @return * @return
*/ */
public static ApiResult<FlowDto> hisLoad(Long hisTaskId) { public static R<FlowDto> hisLoad(Long hisTaskId) {
FlowParams flowParams = FlowParams.build(); FlowParams flowParams = FlowParams.build();
return ApiResult.ok(FlowEngine.taskService().hisLoad(hisTaskId, flowParams)); return R.ok(FlowEngine.taskService().hisLoad(hisTaskId, flowParams));
} }
/** /**
@ -275,7 +276,7 @@ public class WarmFlowService {
* @param nodeCode * @param nodeCode
* @return * @return
*/ */
public static ApiResult<FlowInstance> handle(Map<String, Object> formData, Long taskId, String skipType public static R<FlowInstance> handle(Map<String, Object> formData, Long taskId, String skipType
, String message, String nodeCode) { , String message, String nodeCode) {
FlowParams flowParams = FlowParams.build() FlowParams flowParams = FlowParams.build()
.skipType(skipType) .skipType(skipType)
@ -284,7 +285,7 @@ public class WarmFlowService {
flowParams.formData(formData); flowParams.formData(formData);
return ApiResult.ok(FlowEngine.taskService().skip(taskId, flowParams)); return R.ok(FlowEngine.taskService().skip(taskId, flowParams));
} }
/** /**
@ -292,15 +293,15 @@ public class WarmFlowService {
* *
* @return List<NodeExt> * @return List<NodeExt>
*/ */
public static ApiResult<List<NodeExt>> nodeExt() { public static R<List<NodeExt>> nodeExt() {
try { try {
// 需要业务系统实现该接口 // 需要业务系统实现该接口
NodeExtService nodeExtService = SpringUtils.getBeanOrNull(NodeExtService.class); NodeExtService nodeExtService = SpringUtils.getBeanOrNull(NodeExtService.class);
if (nodeExtService == null) { if (nodeExtService == null) {
return ApiResult.ok(Collections.emptyList()); return R.ok(Collections.emptyList());
} }
List<NodeExt> nodeExts = nodeExtService.getNodeExt(); List<NodeExt> nodeExts = nodeExtService.getNodeExt();
return ApiResult.ok(nodeExts); return R.ok(nodeExts);
} catch (Exception e) { } catch (Exception e) {
log.error("获取节点扩展属性", e); log.error("获取节点扩展属性", e);
throw new FlowException("获取节点扩展属性失败", e); throw new FlowException("获取节点扩展属性失败", e);
@ -312,15 +313,15 @@ public class WarmFlowService {
* *
* @return List<NodeExt> * @return List<NodeExt>
*/ */
public static ApiResult<List<ListenerVo>> listenerList() { public static R<List<ListenerVo>> listenerList() {
try { try {
// 需要业务系统实现该接口 // 需要业务系统实现该接口
ListenerListService listenerListService = SpringUtils.getBeanOrNull(ListenerListService.class); ListenerListService listenerListService = SpringUtils.getBeanOrNull(ListenerListService.class);
if (listenerListService == null) { if (listenerListService == null) {
return ApiResult.ok(Collections.emptyList()); return R.ok(Collections.emptyList());
} }
List<ListenerVo> listenerList = listenerListService.listenerList(); List<ListenerVo> listenerList = listenerListService.listenerList();
return ApiResult.ok(listenerList); return R.ok(listenerList);
} catch (Exception e) { } catch (Exception e) {
log.error("获取监听器列表", e); log.error("获取监听器列表", e);
throw new FlowException("获取监听器列表失败", e); throw new FlowException("获取监听器列表失败", e);

View File

@ -36,7 +36,7 @@ public class TreeUtil {
*/ */
public static List<Tree> buildTree(List<Tree> trees) { public static List<Tree> buildTree(List<Tree> trees) {
List<Tree> returnList = new ArrayList<>(); List<Tree> returnList = new ArrayList<>();
List<String> tempList = trees.stream().map(Tree::getId).collect(Collectors.toList()); List<String> tempList = trees.stream().map(Tree::getId).toList();
for (Tree dept : trees) { for (Tree dept : trees) {
// 如果是顶级节点, 遍历该父节点的所有子节点 // 如果是顶级节点, 遍历该父节点的所有子节点
if (!tempList.contains(dept.getParentId())) { if (!tempList.contains(dept.getParentId())) {

View File

@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.warm.flow.ui.vo; package org.dromara.warm.flow.ui.vo;
import java.io.Serial;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@ -31,6 +32,7 @@ import java.util.List;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
public class Dict implements Serializable { public class Dict implements Serializable {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**

View File

@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.warm.flow.ui.vo; package org.dromara.warm.flow.ui.vo;
import java.io.Serial;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
@ -32,6 +33,7 @@ import java.io.Serializable;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class ListenerVo implements Serializable { public class ListenerVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**

View File

@ -14,8 +14,11 @@
* limitations under the License. * limitations under the License.
*/ */
package org.dromara.warm.flow.ui.vo; package org.dromara.warm.flow.ui.vo;
import java.io.Serial;
import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import java.io.Serializable; import java.io.Serializable;
@ -30,6 +33,7 @@ import java.util.List;
@Getter @Getter
@Setter @Setter
public class NodeExt implements Serializable { public class NodeExt implements Serializable {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private String code; private String code;
private String name; private String name;
@ -57,24 +61,17 @@ public class NodeExt implements Serializable {
@Getter @Getter
@Setter @Setter
@NoArgsConstructor
@AllArgsConstructor
public static class DictItem { public static class DictItem {
private String label; private String label;
private String value; private String value;
private boolean selected; private boolean selected;
public DictItem() {
}
public DictItem(String label, String value) { public DictItem(String label, String value) {
this.label = label; this.label = label;
this.value = value; this.value = value;
} }
public DictItem(String label, String value, boolean selected) {
this.label = label;
this.value = value;
this.selected = selected;
}
} }
} }

View File

@ -96,7 +96,7 @@ public class ExpressionUtil {
.map(s -> evalVariable(s, variable)).filter(Objects::nonNull) .map(s -> evalVariable(s, variable)).filter(Objects::nonNull)
.flatMap(List::stream) .flatMap(List::stream)
.distinct() .distinct()
.collect(Collectors.toList()); .toList();
// 转换办理人比如设计器中预设了能办理的人如果其中包含角色或者部门id等可以通过此接口进行转换成用户id // 转换办理人比如设计器中预设了能办理的人如果其中包含角色或者部门id等可以通过此接口进行转换成用户id
PermissionHandler permissionHandler = FlowEngine.permissionHandler(); PermissionHandler permissionHandler = FlowEngine.permissionHandler();