diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/action/BaseAction.java b/flow-engine-framework/src/main/java/com/codingapi/flow/action/BaseAction.java index d297fd61..6680208c 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/action/BaseAction.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/action/BaseAction.java @@ -4,6 +4,7 @@ import com.codingapi.flow.record.FlowRecord; import com.codingapi.flow.session.FlowSession; import lombok.Getter; +import lombok.Setter; import lombok.SneakyThrows; import java.util.HashMap; @@ -12,6 +13,7 @@ import java.util.function.Consumer; @Getter +@Setter public abstract class BaseAction implements IFlowAction { protected String id; @@ -39,21 +41,12 @@ public ActionDisplay display() { return display; } - - protected void setId(String id) { - this.id = id; - } - - protected void setType(ActionType type) { - this.type = type; - } - - protected void setTitle(String title) { - this.title = title; - } - - protected void setDisplay(ActionDisplay display) { - this.display = display; + @Override + public boolean equals(Object obj) { + if(obj instanceof BaseAction action){ + return action.getId().equals(id); + } + return super.equals(obj); } @Override @@ -71,6 +64,13 @@ public List generateRecords(FlowSession flowSession) { return List.of(); } + @Override + public void copy(IFlowAction action) { + this.id = action.id(); + this.type = action.type(); + this.title = action.title(); + this.display = action.display(); + } @SneakyThrows @SuppressWarnings("unchecked") diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/action/IFlowAction.java b/flow-engine-framework/src/main/java/com/codingapi/flow/action/IFlowAction.java index fe82c326..686fd991 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/action/IFlowAction.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/action/IFlowAction.java @@ -51,4 +51,9 @@ public interface IFlowAction { void run(FlowSession flowSession); + /** + * 复制动作 + */ + void copy(IFlowAction action); + } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/action/AddAuditAction.java b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/AddAuditAction.java similarity index 73% rename from flow-engine-framework/src/main/java/com/codingapi/flow/action/AddAuditAction.java rename to flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/AddAuditAction.java index daa94f65..c9cd7e30 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/action/AddAuditAction.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/AddAuditAction.java @@ -1,5 +1,8 @@ -package com.codingapi.flow.action; +package com.codingapi.flow.action.actions; +import com.codingapi.flow.action.ActionDisplay; +import com.codingapi.flow.action.ActionType; +import com.codingapi.flow.action.BaseAction; import com.codingapi.flow.utils.RandomUtils; import java.util.Map; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/action/CustomAction.java b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/CustomAction.java similarity index 72% rename from flow-engine-framework/src/main/java/com/codingapi/flow/action/CustomAction.java rename to flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/CustomAction.java index b2f71b3e..ff9eeac7 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/action/CustomAction.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/CustomAction.java @@ -1,5 +1,8 @@ -package com.codingapi.flow.action; +package com.codingapi.flow.action.actions; +import com.codingapi.flow.action.ActionDisplay; +import com.codingapi.flow.action.ActionType; +import com.codingapi.flow.action.BaseAction; import com.codingapi.flow.utils.RandomUtils; import java.util.Map; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/action/DefaultAction.java b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/DefaultAction.java similarity index 74% rename from flow-engine-framework/src/main/java/com/codingapi/flow/action/DefaultAction.java rename to flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/DefaultAction.java index 6158491f..304081d0 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/action/DefaultAction.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/DefaultAction.java @@ -1,5 +1,8 @@ -package com.codingapi.flow.action; +package com.codingapi.flow.action.actions; +import com.codingapi.flow.action.ActionDisplay; +import com.codingapi.flow.action.ActionType; +import com.codingapi.flow.action.BaseAction; import com.codingapi.flow.utils.RandomUtils; import java.util.Map; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/action/DelegateAction.java b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/DelegateAction.java similarity index 73% rename from flow-engine-framework/src/main/java/com/codingapi/flow/action/DelegateAction.java rename to flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/DelegateAction.java index 1d759643..6852c671 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/action/DelegateAction.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/DelegateAction.java @@ -1,5 +1,8 @@ -package com.codingapi.flow.action; +package com.codingapi.flow.action.actions; +import com.codingapi.flow.action.ActionDisplay; +import com.codingapi.flow.action.ActionType; +import com.codingapi.flow.action.BaseAction; import com.codingapi.flow.utils.RandomUtils; import java.util.Map; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/action/PassAction.java b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/PassAction.java similarity index 95% rename from flow-engine-framework/src/main/java/com/codingapi/flow/action/PassAction.java rename to flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/PassAction.java index eb49915e..157e2987 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/action/PassAction.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/PassAction.java @@ -1,5 +1,8 @@ -package com.codingapi.flow.action; +package com.codingapi.flow.action.actions; +import com.codingapi.flow.action.ActionDisplay; +import com.codingapi.flow.action.ActionType; +import com.codingapi.flow.action.BaseAction; import com.codingapi.flow.context.RepositoryContext; import com.codingapi.flow.event.FlowRecordDoneEvent; import com.codingapi.flow.event.FlowRecordTodoEvent; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/action/RejectAction.java b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/RejectAction.java similarity index 89% rename from flow-engine-framework/src/main/java/com/codingapi/flow/action/RejectAction.java rename to flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/RejectAction.java index 79b6b359..85b4f8af 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/action/RejectAction.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/RejectAction.java @@ -1,5 +1,9 @@ -package com.codingapi.flow.action; +package com.codingapi.flow.action.actions; +import com.codingapi.flow.action.ActionDisplay; +import com.codingapi.flow.action.ActionType; +import com.codingapi.flow.action.BaseAction; +import com.codingapi.flow.action.IFlowAction; import com.codingapi.flow.context.RepositoryContext; import com.codingapi.flow.event.FlowRecordTodoEvent; import com.codingapi.flow.event.IFlowEvent; @@ -32,6 +36,12 @@ public RejectAction() { this.script = RejectActionScript.startScript(); } + @Override + public void copy(IFlowAction action) { + super.copy(action); + this.script = ((RejectAction) action).script; + } + public void setScript(String script) { this.script = new RejectActionScript(script); } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/action/ReturnAction.java b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/ReturnAction.java similarity index 72% rename from flow-engine-framework/src/main/java/com/codingapi/flow/action/ReturnAction.java rename to flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/ReturnAction.java index c39650fc..51e7cc49 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/action/ReturnAction.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/ReturnAction.java @@ -1,5 +1,8 @@ -package com.codingapi.flow.action; +package com.codingapi.flow.action.actions; +import com.codingapi.flow.action.ActionDisplay; +import com.codingapi.flow.action.ActionType; +import com.codingapi.flow.action.BaseAction; import com.codingapi.flow.utils.RandomUtils; import java.util.Map; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/action/SaveAction.java b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/SaveAction.java similarity index 72% rename from flow-engine-framework/src/main/java/com/codingapi/flow/action/SaveAction.java rename to flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/SaveAction.java index 207dcffb..9ac2ac22 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/action/SaveAction.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/SaveAction.java @@ -1,5 +1,8 @@ -package com.codingapi.flow.action; +package com.codingapi.flow.action.actions; +import com.codingapi.flow.action.ActionDisplay; +import com.codingapi.flow.action.ActionType; +import com.codingapi.flow.action.BaseAction; import com.codingapi.flow.utils.RandomUtils; import java.util.Map; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/action/TransferAction.java b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/TransferAction.java similarity index 73% rename from flow-engine-framework/src/main/java/com/codingapi/flow/action/TransferAction.java rename to flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/TransferAction.java index 12800b1b..0aaa36eb 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/action/TransferAction.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/action/actions/TransferAction.java @@ -1,5 +1,8 @@ -package com.codingapi.flow.action; +package com.codingapi.flow.action.actions; +import com.codingapi.flow.action.ActionDisplay; +import com.codingapi.flow.action.ActionType; +import com.codingapi.flow.action.BaseAction; import com.codingapi.flow.utils.RandomUtils; import java.util.Map; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/action/factory/FlowActionFactory.java b/flow-engine-framework/src/main/java/com/codingapi/flow/action/factory/FlowActionFactory.java index ab5ed08f..11f8ae96 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/action/factory/FlowActionFactory.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/action/factory/FlowActionFactory.java @@ -1,6 +1,7 @@ package com.codingapi.flow.action.factory; import com.codingapi.flow.action.*; +import com.codingapi.flow.action.actions.*; import lombok.Getter; import lombok.SneakyThrows; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/builder/ActionBuilder.java b/flow-engine-framework/src/main/java/com/codingapi/flow/builder/ActionBuilder.java new file mode 100644 index 00000000..68313970 --- /dev/null +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/builder/ActionBuilder.java @@ -0,0 +1,28 @@ +package com.codingapi.flow.builder; + +import com.codingapi.flow.action.IFlowAction; + +import java.util.ArrayList; +import java.util.List; + +public class ActionBuilder { + + private final List actions; + + private ActionBuilder() { + this.actions = new ArrayList<>(); + } + + public static ActionBuilder builder() { + return new ActionBuilder(); + } + + public ActionBuilder addAction(IFlowAction action) { + this.actions.add(action); + return this; + } + + public List build() { + return actions; + } +} diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/builder/BaseNodeBuilder.java b/flow-engine-framework/src/main/java/com/codingapi/flow/builder/BaseNodeBuilder.java similarity index 95% rename from flow-engine-framework/src/main/java/com/codingapi/flow/node/builder/BaseNodeBuilder.java rename to flow-engine-framework/src/main/java/com/codingapi/flow/builder/BaseNodeBuilder.java index a766cf50..ae1dcf57 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/builder/BaseNodeBuilder.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/builder/BaseNodeBuilder.java @@ -1,4 +1,4 @@ -package com.codingapi.flow.node.builder; +package com.codingapi.flow.builder; import com.codingapi.flow.action.IFlowAction; import com.codingapi.flow.node.BaseFlowNode; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/builder/FormFieldPermissionsBuilder.java b/flow-engine-framework/src/main/java/com/codingapi/flow/builder/FormFieldPermissionsBuilder.java similarity index 95% rename from flow-engine-framework/src/main/java/com/codingapi/flow/node/builder/FormFieldPermissionsBuilder.java rename to flow-engine-framework/src/main/java/com/codingapi/flow/builder/FormFieldPermissionsBuilder.java index e7ea957f..14f1b52d 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/builder/FormFieldPermissionsBuilder.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/builder/FormFieldPermissionsBuilder.java @@ -1,4 +1,4 @@ -package com.codingapi.flow.node.builder; +package com.codingapi.flow.builder; import com.codingapi.flow.form.permission.FormFieldPermission; import com.codingapi.flow.form.permission.PermissionType; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/builder/NodeMapBuilder.java b/flow-engine-framework/src/main/java/com/codingapi/flow/builder/NodeMapBuilder.java similarity index 74% rename from flow-engine-framework/src/main/java/com/codingapi/flow/node/builder/NodeMapBuilder.java rename to flow-engine-framework/src/main/java/com/codingapi/flow/builder/NodeMapBuilder.java index e54cb8bf..c06a211b 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/builder/NodeMapBuilder.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/builder/NodeMapBuilder.java @@ -1,12 +1,10 @@ -package com.codingapi.flow.node.builder; +package com.codingapi.flow.builder; import com.codingapi.flow.action.IFlowAction; import com.codingapi.flow.action.factory.FlowActionFactory; import com.codingapi.flow.form.permission.FormFieldPermission; -import com.codingapi.flow.node.BaseAuditNode; import com.codingapi.flow.strategy.INodeStrategy; import com.codingapi.flow.strategy.NodeStrategyFactory; -import lombok.SneakyThrows; import java.util.ArrayList; import java.util.List; @@ -16,7 +14,7 @@ public class NodeMapBuilder { @SuppressWarnings("unchecked") public static List loadFormFieldPermissions(Map data) { - List> permissions = (List>) data.get("formFieldPermissions"); + List> permissions = (List>) data.get("fieldPermissions"); if (permissions != null) { List permissionList = new ArrayList<>(); for (Map item : permissions) { @@ -57,16 +55,4 @@ public static List loadNodeStrategies(Map data) { } - @SneakyThrows - public static T formMap(Map map, Class clazz) { - T node = clazz.getDeclaredConstructor().newInstance(); - node.setId((String) map.get("id")); - node.setName((String) map.get("name")); - node.setView((String) map.get("view")); - List actionList = NodeMapBuilder.loadActions(map); - node.setActions(actionList); - List strategyList = NodeMapBuilder.loadNodeStrategies(map); - node.setStrategies(strategyList); - return node; - } } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/builder/NodeStrategyBuilder.java b/flow-engine-framework/src/main/java/com/codingapi/flow/builder/NodeStrategyBuilder.java similarity index 93% rename from flow-engine-framework/src/main/java/com/codingapi/flow/node/builder/NodeStrategyBuilder.java rename to flow-engine-framework/src/main/java/com/codingapi/flow/builder/NodeStrategyBuilder.java index 446211cb..d28e1c77 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/builder/NodeStrategyBuilder.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/builder/NodeStrategyBuilder.java @@ -1,4 +1,4 @@ -package com.codingapi.flow.node.builder; +package com.codingapi.flow.builder; import com.codingapi.flow.strategy.INodeStrategy; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/BaseAuditNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/BaseAuditNode.java index 712fdca8..f6c6ce93 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/BaseAuditNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/BaseAuditNode.java @@ -1,20 +1,18 @@ package com.codingapi.flow.node; import com.codingapi.flow.action.IFlowAction; -import com.codingapi.flow.action.PassAction; import com.codingapi.flow.form.FormMeta; import com.codingapi.flow.node.manager.OperatorManager; import com.codingapi.flow.node.manager.StrategyManager; import com.codingapi.flow.operator.IFlowOperator; import com.codingapi.flow.record.FlowRecord; -import com.codingapi.flow.session.FlowAdvice; import com.codingapi.flow.session.FlowSession; import com.codingapi.flow.strategy.INodeStrategy; import com.codingapi.flow.strategy.MultiOperatorAuditStrategy; import com.codingapi.flow.utils.RandomUtils; -import com.codingapi.flow.workflow.Workflow; import lombok.Getter; import lombok.Setter; +import lombok.SneakyThrows; import org.springframework.util.StringUtils; import java.util.ArrayList; @@ -47,20 +45,10 @@ public Map toMap() { public void verifyNode(FormMeta form) { + super.verifyNode(form); if (!StringUtils.hasText(view)) { throw new IllegalArgumentException("view can not be null"); } - if (!StringUtils.hasText(name)) { - throw new IllegalArgumentException("name can not be null"); - } - if (!StringUtils.hasText(id)) { - throw new IllegalArgumentException("id can not be null"); - } - if (actions == null || actions.isEmpty()) { - throw new IllegalArgumentException("actions can not be null"); - } - StrategyManager strategyManager = this.strategyManager(); - strategyManager.verifyStrategies(form); } @@ -157,35 +145,12 @@ public List generateCurrentRecords(FlowSession session) { return records; } - @Override - public void verifySession(FlowSession session) { - super.verifySession(session); - FlowRecord flowRecord = session.getCurrentRecord(); - Workflow workflow = session.getWorkflow(); - // 数据验证 -// FieldPermissionManager fieldPermissionManager = this.formFieldsPermissionsManager(); -// fieldPermissionManager.verifyFormData(workflow.getForm(), flowRecord.getFormData(), session.getFormData().toMapData()); - - FlowAdvice flowAdvice = session.getAdvice(); - IFlowAction flowAction = flowAdvice.getAction(); - StrategyManager strategyManager = this.strategyManager(); - strategyManager.verifySession(session); - // 是否必须填写审批意见 - if (strategyManager.isEnableAdvice()) { - if (!StringUtils.hasText(flowAdvice.getAdvice())) { - throw new IllegalArgumentException("advice can not be null"); - } - } - // 通过操作 - if (flowAction instanceof PassAction) { - // 是否必须签名 - if (strategyManager.isEnableSignable()) { - if (!StringUtils.hasText(flowAdvice.getSignKey())) { - throw new IllegalArgumentException("signKey can not be null"); - } - } - } + @SneakyThrows + public static T formMap(Map map, Class clazz) { + T node = BaseFlowNode.loadFromMap(map, clazz); + node.setView((String) map.get("view")); + return node; } } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/BaseFlowNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/BaseFlowNode.java index 8114e33c..12b47391 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/BaseFlowNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/BaseFlowNode.java @@ -1,21 +1,19 @@ package com.codingapi.flow.node; import com.codingapi.flow.action.IFlowAction; -import com.codingapi.flow.action.ReturnAction; -import com.codingapi.flow.action.SaveAction; -import com.codingapi.flow.action.TransferAction; +import com.codingapi.flow.action.actions.CustomAction; import com.codingapi.flow.context.RepositoryContext; import com.codingapi.flow.form.FormMeta; -import com.codingapi.flow.node.builder.NodeMapBuilder; +import com.codingapi.flow.builder.NodeMapBuilder; import com.codingapi.flow.node.manager.ActionManager; import com.codingapi.flow.node.manager.StrategyManager; import com.codingapi.flow.record.FlowRecord; -import com.codingapi.flow.session.FlowAdvice; import com.codingapi.flow.session.FlowSession; import com.codingapi.flow.strategy.INodeStrategy; import lombok.Getter; import lombok.Setter; import lombok.SneakyThrows; +import org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.HashMap; @@ -58,16 +56,47 @@ public abstract class BaseFlowNode implements IFlowNode { protected List strategies; + /** + * 节点策略 + * @param strategies 节点策略 + */ public void setStrategies(List strategies) { - if(strategies!=null && !strategies.isEmpty()) { - if(this.strategies!=null){ - this.strategies.addAll(strategies); - }else { + if (strategies != null && !strategies.isEmpty()) { + if (this.strategies != null) { + StrategyManager strategyManager = new StrategyManager(this.strategies); + for (INodeStrategy nodeStrategy : strategies) { + INodeStrategy currentStrategy = strategyManager.getStrategy(nodeStrategy.getClass()); + if (currentStrategy != null) { + currentStrategy.copy(nodeStrategy); + } + } + } else { this.strategies = strategies; } } } + public void setActions(List actions) { + if (actions != null && !actions.isEmpty()) { + if (this.actions != null) { + ActionManager actionManager = new ActionManager(this.actions); + for (IFlowAction action : actions) { + IFlowAction currentAction = actionManager.getAction(action.getClass()); + if (currentAction != null) { + currentAction.copy(action); + }else { + if(action instanceof CustomAction) { + this.actions.add(action); + } + } + } + } else { + this.actions = actions; + } + } + } + + public BaseFlowNode(String name, String id) { this(name, id, 0, new ArrayList<>(), new ArrayList<>()); } @@ -115,7 +144,27 @@ public static T loadFromMap(Map map, Cl @Override public void verifyNode(FormMeta form) { + this.verifyDefaultConfig(); + ActionManager actionManager = this.actionManager(); + actionManager.verify(form); + StrategyManager strategyManager = this.strategyManager(); + strategyManager.verify(form); + } + + private void verifyDefaultConfig(){ + if (!StringUtils.hasText(name)) { + throw new IllegalArgumentException("name can not be null"); + } + if (!StringUtils.hasText(id)) { + throw new IllegalArgumentException("id can not be null"); + } + if (actions == null) { + throw new IllegalArgumentException("actions can not be null"); + } + if (strategies == null) { + throw new IllegalArgumentException("strategies can not be null"); + } } /** @@ -127,7 +176,7 @@ public boolean isWaitParallelRecord(FlowSession session) { RepositoryContext.getInstance().addParallelTriggerCount(currentRecord.getParallelId()); int parallelBranchTotal = currentRecord.getParallelBranchTotal(); int parallelBranchCount = RepositoryContext.getInstance().getParallelBranchTriggerCount(currentRecord.getParallelId()); - if(parallelBranchCount == parallelBranchTotal){ + if (parallelBranchCount == parallelBranchTotal) { // 清空并行节点,防止数据继续继承到后续节点 currentRecord.clearParallel(); } @@ -144,25 +193,11 @@ public boolean continueTrigger(FlowSession session) { @Override public void verifySession(FlowSession session) { - FlowAdvice flowAdvice = session.getAdvice(); + ActionManager actionManager = this.actionManager(); + actionManager.verifySession(session); - IFlowAction flowAction = flowAdvice.getAction(); - // 保存操作,不做检查 - if (flowAction instanceof SaveAction) { - return; - } - // 转办操作 - if (flowAction instanceof TransferAction) { - if (flowAdvice.getTransferOperators() == null || flowAdvice.getTransferOperators().isEmpty()) { - throw new IllegalArgumentException("transferOperators can not be null"); - } - } - // 退回操作 - if (flowAction instanceof ReturnAction) { - if (flowAdvice.getBackNode() == null) { - throw new IllegalArgumentException("backNode can not be null"); - } - } + StrategyManager strategyManager = this.strategyManager(); + strategyManager.verifySession(session); } @Override diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/IFlowNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/IFlowNode.java index f7494b0e..432c256a 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/IFlowNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/IFlowNode.java @@ -1,5 +1,6 @@ package com.codingapi.flow.node; +import com.codingapi.flow.action.actions.PassAction; import com.codingapi.flow.form.FormMeta; import com.codingapi.flow.node.manager.ActionManager; import com.codingapi.flow.node.manager.StrategyManager; @@ -84,7 +85,7 @@ public interface IFlowNode { /** * 节点是否完成 * 当前节点是否完成,由于IFlowAction无法判断节点是否完成,是否完成需要根据节点配置的多人审批规则来判定,因此在提交通过节点时 - * {@link com.codingapi.flow.action.PassAction#run(FlowSession)} 函数中会判断当前节点是否完成 + * {@link PassAction#run(FlowSession)} 函数中会判断当前节点是否完成 * 如果完成则将执行当前节点的生成流程记录函数 {@link IFlowNode#continueTrigger(FlowSession)} * @param session 会话 * @return true: 节点完成 diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/manager/ActionManager.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/manager/ActionManager.java index a01badf7..621ea38b 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/manager/ActionManager.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/manager/ActionManager.java @@ -1,6 +1,12 @@ package com.codingapi.flow.node.manager; import com.codingapi.flow.action.IFlowAction; +import com.codingapi.flow.action.actions.ReturnAction; +import com.codingapi.flow.action.actions.SaveAction; +import com.codingapi.flow.action.actions.TransferAction; +import com.codingapi.flow.form.FormMeta; +import com.codingapi.flow.session.FlowAdvice; +import com.codingapi.flow.session.FlowSession; import lombok.AllArgsConstructor; import lombok.Getter; @@ -30,4 +36,38 @@ public IFlowAction getActionById(String id) { return null; } + public void verify(FormMeta form) { + + } + + public void verifySession(FlowSession session) { + FlowAdvice flowAdvice = session.getAdvice(); + + IFlowAction flowAction = flowAdvice.getAction(); + // 保存操作,不做检查 + if (flowAction instanceof SaveAction) { + return; + } + // 转办操作 + if (flowAction instanceof TransferAction) { + if (flowAdvice.getTransferOperators() == null || flowAdvice.getTransferOperators().isEmpty()) { + throw new IllegalArgumentException("transferOperators can not be null"); + } + } + // 退回操作 + if (flowAction instanceof ReturnAction) { + if (flowAdvice.getBackNode() == null) { + throw new IllegalArgumentException("backNode can not be null"); + } + } + } + + public IFlowAction getAction(Class clazz) { + for (IFlowAction action : actions) { + if (action.getClass() == clazz) { + return action; + } + } + return null; + } } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/manager/StrategyManager.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/manager/StrategyManager.java index 6819b5f8..5a0988d4 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/manager/StrategyManager.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/manager/StrategyManager.java @@ -1,10 +1,13 @@ package com.codingapi.flow.node.manager; +import com.codingapi.flow.action.IFlowAction; +import com.codingapi.flow.action.actions.PassAction; import com.codingapi.flow.form.FormMeta; +import com.codingapi.flow.session.FlowAdvice; import com.codingapi.flow.session.FlowSession; import com.codingapi.flow.strategy.*; -import lombok.AllArgsConstructor; import lombok.Getter; +import org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.List; @@ -135,7 +138,7 @@ public float getMultiOperatorAuditMergePercent() { return 0; } - public void verifyStrategies(FormMeta form) { + public void verify(FormMeta form) { } @@ -160,6 +163,31 @@ public OperatorManager loadOperators(FlowSession session) { } public void verifySession(FlowSession session) { + FlowAdvice flowAdvice = session.getAdvice(); + IFlowAction flowAction = flowAdvice.getAction(); + // 是否必须填写审批意见 + if (this.isEnableAdvice()) { + if (!StringUtils.hasText(flowAdvice.getAdvice())) { + throw new IllegalArgumentException("advice can not be null"); + } + } + // 通过操作 + if (flowAction instanceof PassAction) { + // 是否必须签名 + if (this.isEnableSignable()) { + if (!StringUtils.hasText(flowAdvice.getSignKey())) { + throw new IllegalArgumentException("signKey can not be null"); + } + } + } + } + public INodeStrategy getStrategy(Class aClass) { + for (INodeStrategy strategy : strategies) { + if (strategy.getClass() == aClass) { + return strategy; + } + } + return null; } } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/ApprovalNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/ApprovalNode.java index 04356e04..4b8ea851 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/ApprovalNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/ApprovalNode.java @@ -1,12 +1,11 @@ package com.codingapi.flow.node.nodes; import com.codingapi.flow.action.IFlowAction; -import com.codingapi.flow.action.PassAction; -import com.codingapi.flow.action.RejectAction; -import com.codingapi.flow.action.SaveAction; +import com.codingapi.flow.action.actions.PassAction; +import com.codingapi.flow.action.actions.RejectAction; +import com.codingapi.flow.action.actions.SaveAction; import com.codingapi.flow.node.BaseAuditNode; -import com.codingapi.flow.node.builder.BaseNodeBuilder; -import com.codingapi.flow.node.builder.NodeMapBuilder; +import com.codingapi.flow.builder.BaseNodeBuilder; import com.codingapi.flow.strategy.*; import com.codingapi.flow.utils.RandomUtils; @@ -45,6 +44,8 @@ private static List defaultStrategies() { strategies.add(AdviceStrategy.defaultStrategy()); strategies.add(ErrorTriggerStrategy.defaultStrategy()); strategies.add(NodeTitleStrategy.defaultStrategy()); + strategies.add(FormFieldPermissionStrategy.defaultStrategy()); + strategies.add(OperatorLoadStrategy.defaultStrategy()); return strategies; } @@ -58,7 +59,7 @@ private static List defaultActions() { public static ApprovalNode formMap(Map map) { - return NodeMapBuilder.formMap(map, ApprovalNode.class); + return BaseAuditNode.formMap(map, ApprovalNode.class); } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/BranchNodeBranchNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/BranchNodeBranchNode.java index a72bc6ce..f0ee7974 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/BranchNodeBranchNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/BranchNodeBranchNode.java @@ -2,7 +2,7 @@ import com.codingapi.flow.node.BaseFlowNode; import com.codingapi.flow.node.IFlowNode; -import com.codingapi.flow.node.builder.BaseNodeBuilder; +import com.codingapi.flow.builder.BaseNodeBuilder; import com.codingapi.flow.script.node.ConditionScript; import com.codingapi.flow.session.FlowSession; import com.codingapi.flow.utils.RandomUtils; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/DelayNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/DelayNode.java index 4a5e78fc..c63830d5 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/DelayNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/DelayNode.java @@ -1,7 +1,7 @@ package com.codingapi.flow.node.nodes; import com.codingapi.flow.node.BaseFlowNode; -import com.codingapi.flow.node.builder.BaseNodeBuilder; +import com.codingapi.flow.builder.BaseNodeBuilder; import com.codingapi.flow.utils.RandomUtils; import java.util.Map; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/EndNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/EndNode.java index 9807fcf3..fb1343e0 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/EndNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/EndNode.java @@ -1,11 +1,11 @@ package com.codingapi.flow.node.nodes; import com.codingapi.flow.action.IFlowAction; -import com.codingapi.flow.action.PassAction; +import com.codingapi.flow.action.actions.PassAction; import com.codingapi.flow.context.RepositoryContext; import com.codingapi.flow.event.FlowRecordFinishEvent; import com.codingapi.flow.node.BaseFlowNode; -import com.codingapi.flow.node.builder.BaseNodeBuilder; +import com.codingapi.flow.builder.BaseNodeBuilder; import com.codingapi.flow.record.FlowRecord; import com.codingapi.flow.session.FlowSession; import com.codingapi.flow.utils.RandomUtils; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/HandleNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/HandleNode.java index 520f114f..84f81c66 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/HandleNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/HandleNode.java @@ -1,10 +1,9 @@ package com.codingapi.flow.node.nodes; import com.codingapi.flow.action.IFlowAction; -import com.codingapi.flow.action.PassAction; +import com.codingapi.flow.action.actions.PassAction; import com.codingapi.flow.node.BaseAuditNode; -import com.codingapi.flow.node.builder.BaseNodeBuilder; -import com.codingapi.flow.node.builder.NodeMapBuilder; +import com.codingapi.flow.builder.BaseNodeBuilder; import com.codingapi.flow.strategy.*; import com.codingapi.flow.utils.RandomUtils; @@ -46,6 +45,8 @@ private static List defaultStrategies() { strategies.add(OperatorLoadStrategy.defaultStrategy()); strategies.add(ErrorTriggerStrategy.defaultStrategy()); strategies.add(NodeTitleStrategy.defaultStrategy()); + strategies.add(FormFieldPermissionStrategy.defaultStrategy()); + strategies.add(OperatorLoadStrategy.defaultStrategy()); return strategies; } @@ -56,7 +57,7 @@ private static List defaultActions() { } public static HandleNode formMap(Map map) { - return NodeMapBuilder.formMap(map, HandleNode.class); + return BaseAuditNode.formMap(map, HandleNode.class); } public static Builder builder() { diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/InclusiveBranchNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/InclusiveBranchNode.java index 8368ae3e..0f09c837 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/InclusiveBranchNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/InclusiveBranchNode.java @@ -1,7 +1,7 @@ package com.codingapi.flow.node.nodes; import com.codingapi.flow.node.BaseFlowNode; -import com.codingapi.flow.node.builder.BaseNodeBuilder; +import com.codingapi.flow.builder.BaseNodeBuilder; import com.codingapi.flow.utils.RandomUtils; import java.util.Map; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/NotifyNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/NotifyNode.java index c6063786..6421a1e9 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/NotifyNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/NotifyNode.java @@ -1,10 +1,9 @@ package com.codingapi.flow.node.nodes; -import com.codingapi.flow.action.DefaultAction; +import com.codingapi.flow.action.actions.DefaultAction; import com.codingapi.flow.action.IFlowAction; import com.codingapi.flow.node.BaseAuditNode; -import com.codingapi.flow.node.builder.BaseNodeBuilder; -import com.codingapi.flow.node.builder.NodeMapBuilder; +import com.codingapi.flow.builder.BaseNodeBuilder; import com.codingapi.flow.strategy.*; import com.codingapi.flow.utils.RandomUtils; @@ -45,6 +44,8 @@ private static List defaultStrategies() { strategies.add(OperatorLoadStrategy.defaultStrategy()); strategies.add(ErrorTriggerStrategy.defaultStrategy()); strategies.add(NodeTitleStrategy.defaultStrategy()); + strategies.add(FormFieldPermissionStrategy.defaultStrategy()); + strategies.add(OperatorLoadStrategy.defaultStrategy()); return strategies; } @@ -55,7 +56,7 @@ private static List defaultActions() { } public static NotifyNode formMap(Map map) { - return NodeMapBuilder.formMap(map, NotifyNode.class); + return BaseAuditNode.formMap(map, NotifyNode.class); } public static Builder builder() { diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/ParallelBranchNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/ParallelBranchNode.java index 069d5a96..81c90286 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/ParallelBranchNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/ParallelBranchNode.java @@ -2,7 +2,7 @@ import com.codingapi.flow.node.BaseFlowNode; import com.codingapi.flow.node.IFlowNode; -import com.codingapi.flow.node.builder.BaseNodeBuilder; +import com.codingapi.flow.builder.BaseNodeBuilder; import com.codingapi.flow.record.FlowRecord; import com.codingapi.flow.session.FlowSession; import com.codingapi.flow.utils.RandomUtils; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/RouterBranchNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/RouterBranchNode.java index 1ccd23e0..109b7717 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/RouterBranchNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/RouterBranchNode.java @@ -1,7 +1,7 @@ package com.codingapi.flow.node.nodes; import com.codingapi.flow.node.BaseFlowNode; -import com.codingapi.flow.node.builder.BaseNodeBuilder; +import com.codingapi.flow.builder.BaseNodeBuilder; import com.codingapi.flow.utils.RandomUtils; import java.util.Map; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/StartNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/StartNode.java index bfd4a676..942933a2 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/StartNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/StartNode.java @@ -1,10 +1,10 @@ package com.codingapi.flow.node.nodes; import com.codingapi.flow.action.IFlowAction; -import com.codingapi.flow.action.PassAction; +import com.codingapi.flow.action.actions.PassAction; import com.codingapi.flow.context.GatewayContext; import com.codingapi.flow.node.BaseFlowNode; -import com.codingapi.flow.node.builder.BaseNodeBuilder; +import com.codingapi.flow.builder.BaseNodeBuilder; import com.codingapi.flow.node.manager.StrategyManager; import com.codingapi.flow.operator.IFlowOperator; import com.codingapi.flow.record.FlowRecord; @@ -74,7 +74,7 @@ public List generateCurrentRecords(FlowSession session) { private static List defaultStrategies() { List strategies = new ArrayList<>(); strategies.add(NodeTitleStrategy.defaultStrategy()); - strategies.add(new FormFieldPermissionStrategy()); + strategies.add(FormFieldPermissionStrategy.defaultStrategy()); return strategies; } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/SubProcessNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/SubProcessNode.java index 0eb9df55..5dc242e8 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/SubProcessNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/SubProcessNode.java @@ -1,7 +1,7 @@ package com.codingapi.flow.node.nodes; import com.codingapi.flow.node.BaseFlowNode; -import com.codingapi.flow.node.builder.BaseNodeBuilder; +import com.codingapi.flow.builder.BaseNodeBuilder; import com.codingapi.flow.utils.RandomUtils; import java.util.ArrayList; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/TriggerNode.java b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/TriggerNode.java index dcf93abb..63495300 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/TriggerNode.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/node/nodes/TriggerNode.java @@ -1,7 +1,7 @@ package com.codingapi.flow.node.nodes; import com.codingapi.flow.node.BaseFlowNode; -import com.codingapi.flow.node.builder.BaseNodeBuilder; +import com.codingapi.flow.builder.BaseNodeBuilder; import com.codingapi.flow.utils.RandomUtils; import java.util.ArrayList; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/AdviceStrategy.java b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/AdviceStrategy.java index 603a3f55..beab7559 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/AdviceStrategy.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/AdviceStrategy.java @@ -1,15 +1,15 @@ package com.codingapi.flow.strategy; +import com.codingapi.flow.utils.RandomUtils; import lombok.Data; -import java.util.HashMap; import java.util.Map; /** * 节点审批意见策略 */ @Data -public class AdviceStrategy implements INodeStrategy { +public class AdviceStrategy extends BaseStrategy { /** * 是否可空 @@ -20,6 +20,9 @@ public class AdviceStrategy implements INodeStrategy { */ private boolean signable; + public AdviceStrategy() { + super(RandomUtils.generateStringId()); + } public static AdviceStrategy defaultStrategy() { AdviceStrategy strategy = new AdviceStrategy(); @@ -28,19 +31,23 @@ public static AdviceStrategy defaultStrategy() { return strategy; } + @Override + public void copy(INodeStrategy target) { + this.adviceNullable = ((AdviceStrategy) target).adviceNullable; + this.signable = ((AdviceStrategy) target).signable; + } @Override public Map toMap() { - Map map = new HashMap<>(); - map.put(TYPE_KEY, strategyType()); + Map map = super.toMap(); map.put("adviceNullable", adviceNullable); map.put("signable", signable); return map; } public static AdviceStrategy fromMap(Map map) { - if (map == null || map.isEmpty()) return null; - AdviceStrategy strategy = new AdviceStrategy(); + AdviceStrategy strategy = BaseStrategy.fromMap(map, AdviceStrategy.class); + if (strategy == null) return null; strategy.setAdviceNullable((boolean) map.get("adviceNullable")); strategy.setSignable((boolean) map.get("signable")); return strategy; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/BaseStrategy.java b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/BaseStrategy.java new file mode 100644 index 00000000..118ba0d4 --- /dev/null +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/BaseStrategy.java @@ -0,0 +1,50 @@ +package com.codingapi.flow.strategy; + +import com.codingapi.flow.utils.RandomUtils; +import lombok.Setter; +import lombok.SneakyThrows; + +import java.util.HashMap; +import java.util.Map; + + +public abstract class BaseStrategy implements INodeStrategy { + + @Setter + private String id; + + public BaseStrategy(String id) { + this.id = id; + } + + @Override + public Map toMap() { + Map map = new HashMap<>(); + map.put(TYPE_KEY, strategyType()); + map.put("id", getId()); + return map; + } + + @Override + public String getId() { + return id; + } + + + @Override + public boolean equals(Object obj) { + if (obj instanceof BaseStrategy strategy) { + String id = this.getId(); + return strategy.getId().equals(id); + } + return super.equals(obj); + } + + @SneakyThrows + public static T fromMap(Map map, Class clazz) { + if (map == null || map.isEmpty()) return null; + T strategy = clazz.getDeclaredConstructor().newInstance(); + strategy.setId((String) map.get("id")); + return strategy; + } +} diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/ErrorTriggerStrategy.java b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/ErrorTriggerStrategy.java index 288fbff6..d97a6ac0 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/ErrorTriggerStrategy.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/ErrorTriggerStrategy.java @@ -3,29 +3,38 @@ import com.codingapi.flow.error.ErrorThrow; import com.codingapi.flow.script.node.ErrorTriggerScript; import com.codingapi.flow.session.FlowSession; +import com.codingapi.flow.utils.RandomUtils; -import java.util.HashMap; import java.util.Map; -public class ErrorTriggerStrategy implements INodeStrategy{ +public class ErrorTriggerStrategy extends BaseStrategy { private ErrorTriggerScript errorTriggerScript; + + public ErrorTriggerStrategy() { + super(RandomUtils.generateStringId()); + } + public void setErrorTriggerScript(String script) { this.errorTriggerScript = new ErrorTriggerScript(script); } + @Override + public void copy(INodeStrategy target) { + this.errorTriggerScript = ((ErrorTriggerStrategy) target).errorTriggerScript; + } + @Override public Map toMap() { - Map map = new HashMap<>(); - map.put(TYPE_KEY, strategyType()); + Map map = super.toMap(); map.put("script", errorTriggerScript.getScript()); return map; } public static ErrorTriggerStrategy fromMap(Map map) { - if (map == null || map.isEmpty()) return null; - ErrorTriggerStrategy strategy = new ErrorTriggerStrategy(); + ErrorTriggerStrategy strategy = BaseStrategy.fromMap(map, ErrorTriggerStrategy.class); + if (strategy == null) return null; strategy.setErrorTriggerScript((String) map.get("script")); return strategy; } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/FormFieldPermissionStrategy.java b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/FormFieldPermissionStrategy.java index 9dbd2a47..c0db0dfe 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/FormFieldPermissionStrategy.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/FormFieldPermissionStrategy.java @@ -1,44 +1,50 @@ package com.codingapi.flow.strategy; import com.codingapi.flow.form.permission.FormFieldPermission; -import com.codingapi.flow.node.builder.NodeMapBuilder; +import com.codingapi.flow.builder.NodeMapBuilder; import com.codingapi.flow.script.node.ErrorTriggerScript; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; +import com.codingapi.flow.utils.RandomUtils; +import lombok.Data; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; -@AllArgsConstructor -public class FormFieldPermissionStrategy implements INodeStrategy { +@Data +public class FormFieldPermissionStrategy extends BaseStrategy { /** * 表单字段权限 */ - @Setter - @Getter - private List formFieldPermissions; + private List fieldPermissions; public FormFieldPermissionStrategy() { - this.formFieldPermissions = new ArrayList<>(); + super(RandomUtils.generateStringId()); + this.fieldPermissions = new ArrayList<>(); + } + + public FormFieldPermissionStrategy(List fieldPermissions) { + super(RandomUtils.generateStringId()); + this.fieldPermissions = fieldPermissions; + } + + @Override + public void copy(INodeStrategy target) { + this.fieldPermissions = ((FormFieldPermissionStrategy) target).fieldPermissions; } @Override public Map toMap() { - Map map = new HashMap<>(); - map.put(TYPE_KEY, strategyType()); - map.put("fieldPermissions", formFieldPermissions.stream().map(FormFieldPermission::toMap).toList()); + Map map = super.toMap(); + map.put("fieldPermissions", fieldPermissions.stream().map(FormFieldPermission::toMap).toList()); return map; } public static FormFieldPermissionStrategy fromMap(Map map) { - if (map == null || map.isEmpty()) return null; - FormFieldPermissionStrategy strategy = new FormFieldPermissionStrategy(); - strategy.setFormFieldPermissions(NodeMapBuilder.loadFormFieldPermissions(map)); + FormFieldPermissionStrategy strategy = BaseStrategy.fromMap(map, FormFieldPermissionStrategy.class); + if (strategy == null) return null; + strategy.setFieldPermissions(NodeMapBuilder.loadFormFieldPermissions(map)); return strategy; } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/INodeStrategy.java b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/INodeStrategy.java index 0083b1df..2be69f6b 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/INodeStrategy.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/INodeStrategy.java @@ -8,8 +8,12 @@ public interface INodeStrategy { Map toMap(); + String getId(); + default String strategyType() { return this.getClass().getSimpleName(); } + void copy(INodeStrategy target); + } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/MultiOperatorAuditStrategy.java b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/MultiOperatorAuditStrategy.java index f7dbbfb8..e0c6de47 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/MultiOperatorAuditStrategy.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/MultiOperatorAuditStrategy.java @@ -1,15 +1,15 @@ package com.codingapi.flow.strategy; +import com.codingapi.flow.utils.RandomUtils; import lombok.Data; -import java.util.HashMap; import java.util.Map; /** * 多人审批策略 */ @Data -public class MultiOperatorAuditStrategy implements INodeStrategy { +public class MultiOperatorAuditStrategy extends BaseStrategy { private Type type; // 并签比例(0~1) @@ -26,18 +26,27 @@ public enum Type { RANDOM_ONE } + public MultiOperatorAuditStrategy() { + super(RandomUtils.generateStringId()); + } + + @Override + public void copy(INodeStrategy target) { + this.type = ((MultiOperatorAuditStrategy) target).getType(); + this.percent = ((MultiOperatorAuditStrategy) target).getPercent(); + } + @Override public Map toMap() { - Map map = new HashMap<>(); - map.put(TYPE_KEY, strategyType()); + Map map = super.toMap(); map.put("type", type); map.put("percent", String.valueOf(percent)); return map; } public static MultiOperatorAuditStrategy fromMap(Map map) { - if (map == null || map.isEmpty()) return null; - MultiOperatorAuditStrategy strategy = new MultiOperatorAuditStrategy(); + MultiOperatorAuditStrategy strategy = BaseStrategy.fromMap(map, MultiOperatorAuditStrategy.class); + if (strategy == null) return null; strategy.setType(Type.valueOf((String) map.get("type"))); strategy.setPercent(Float.parseFloat((String) map.get("percent"))); return strategy; diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/NodeTitleStrategy.java b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/NodeTitleStrategy.java index 894f5a48..3c44ba83 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/NodeTitleStrategy.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/NodeTitleStrategy.java @@ -2,17 +2,26 @@ import com.codingapi.flow.script.node.NodeTitleScript; import com.codingapi.flow.session.FlowSession; +import com.codingapi.flow.utils.RandomUtils; -import java.util.HashMap; import java.util.Map; -public class NodeTitleStrategy implements INodeStrategy { +public class NodeTitleStrategy extends BaseStrategy { /** * 审批人配置脚本 */ private NodeTitleScript nodeTitleScript; + public NodeTitleStrategy() { + super(RandomUtils.generateStringId()); + } + + @Override + public void copy(INodeStrategy target) { + this.nodeTitleScript = ((NodeTitleStrategy) target).nodeTitleScript; + } + public void setOperatorScript(String script) { this.nodeTitleScript = new NodeTitleScript(script); } @@ -31,15 +40,14 @@ public static NodeTitleStrategy defaultStrategy() { @Override public Map toMap() { - Map map = new HashMap<>(); - map.put(TYPE_KEY, strategyType()); + Map map = super.toMap(); map.put("script", nodeTitleScript.getScript()); return map; } public static NodeTitleStrategy fromMap(Map map) { - if (map == null || map.isEmpty()) return null; - NodeTitleStrategy strategy = new NodeTitleStrategy(); + NodeTitleStrategy strategy = BaseStrategy.fromMap(map, NodeTitleStrategy.class); + if (strategy == null) return null; strategy.setOperatorScript((String) map.get("script")); return strategy; } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/OperatorLoadStrategy.java b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/OperatorLoadStrategy.java index 9be48bd0..56f97331 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/OperatorLoadStrategy.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/OperatorLoadStrategy.java @@ -3,23 +3,31 @@ import com.codingapi.flow.node.manager.OperatorManager; import com.codingapi.flow.script.node.OperatorLoadScript; import com.codingapi.flow.session.FlowSession; -import lombok.NoArgsConstructor; +import com.codingapi.flow.utils.RandomUtils; -import java.util.HashMap; import java.util.Map; -@NoArgsConstructor -public class OperatorLoadStrategy implements INodeStrategy{ +public class OperatorLoadStrategy extends BaseStrategy{ /** * 审批人配置脚本 */ private OperatorLoadScript operatorLoadScript; + public OperatorLoadStrategy() { + super(RandomUtils.generateStringId()); + } + public OperatorLoadStrategy(String script) { + super(RandomUtils.generateStringId()); this.operatorLoadScript = new OperatorLoadScript(script); } + @Override + public void copy(INodeStrategy target) { + this.operatorLoadScript = ((OperatorLoadStrategy) target).operatorLoadScript; + } + public void setOperatorLoadScript(String script) { this.operatorLoadScript = new OperatorLoadScript(script); } @@ -37,15 +45,14 @@ public static OperatorLoadStrategy defaultStrategy() { @Override public Map toMap() { - Map map = new HashMap<>(); - map.put(TYPE_KEY, strategyType()); + Map map = super.toMap(); map.put("script", operatorLoadScript.getScript()); return map; } public static OperatorLoadStrategy fromMap(Map map) { - if (map == null || map.isEmpty()) return null; - OperatorLoadStrategy strategy = new OperatorLoadStrategy(); + OperatorLoadStrategy strategy = BaseStrategy.fromMap(map, OperatorLoadStrategy.class); + if (strategy == null) return null; strategy.setOperatorLoadScript((String) map.get("script")); return strategy; } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/RecordMergeStrategy.java b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/RecordMergeStrategy.java index 53296335..2814664d 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/RecordMergeStrategy.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/RecordMergeStrategy.java @@ -1,29 +1,37 @@ package com.codingapi.flow.strategy; +import com.codingapi.flow.utils.RandomUtils; import lombok.Data; -import java.util.HashMap; import java.util.Map; /** * 记录合并策略 */ @Data -public class RecordMergeStrategy implements INodeStrategy { +public class RecordMergeStrategy extends BaseStrategy { private boolean mergeable; + public RecordMergeStrategy() { + super(RandomUtils.generateStringId()); + } + + @Override + public void copy(INodeStrategy target) { + this.mergeable = ((RecordMergeStrategy)target).mergeable; + } + @Override public Map toMap() { - Map map = new HashMap<>(); - map.put(TYPE_KEY, strategyType()); + Map map = super.toMap(); map.put("mergeable", mergeable); return map; } public static RecordMergeStrategy fromMap(Map map) { - if (map == null || map.isEmpty()) return null; - RecordMergeStrategy strategy = new RecordMergeStrategy(); + RecordMergeStrategy strategy = BaseStrategy.fromMap( map, RecordMergeStrategy.class); + if (strategy == null) return null; strategy.mergeable = (boolean) map.get("mergeable"); return strategy; } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/ResubmitStrategy.java b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/ResubmitStrategy.java index 08b4a2fe..3c0487f1 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/ResubmitStrategy.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/ResubmitStrategy.java @@ -1,15 +1,15 @@ package com.codingapi.flow.strategy; +import com.codingapi.flow.utils.RandomUtils; import lombok.Data; -import java.util.HashMap; import java.util.Map; /** * 重新提交策略 */ @Data -public class ResubmitStrategy implements INodeStrategy { +public class ResubmitStrategy extends BaseStrategy { private Type type; @@ -20,21 +20,29 @@ public enum Type { CHAIN, } + public ResubmitStrategy() { + super(RandomUtils.generateStringId()); + } + + @Override + public void copy(INodeStrategy target) { + this.type = ((ResubmitStrategy) target).type; + } + public boolean isResume() { return type == Type.RESUME; } @Override public Map toMap() { - Map map = new HashMap<>(); - map.put(TYPE_KEY, strategyType()); + Map map = super.toMap(); map.put("type", type); return map; } public static ResubmitStrategy fromMap(Map map) { - if (map == null || map.isEmpty()) return null; - ResubmitStrategy strategy = new ResubmitStrategy(); + ResubmitStrategy strategy = BaseStrategy.fromMap( map, ResubmitStrategy.class); + if (strategy == null) return null; strategy.setType(Type.valueOf((String) map.get("type"))); return strategy; } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/SameOperatorAuditStrategy.java b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/SameOperatorAuditStrategy.java index 3d378419..d70b4d6a 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/SameOperatorAuditStrategy.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/SameOperatorAuditStrategy.java @@ -1,15 +1,15 @@ package com.codingapi.flow.strategy; +import com.codingapi.flow.utils.RandomUtils; import lombok.Data; -import java.util.HashMap; import java.util.Map; /** * 提交人与审批人一致 */ @Data -public class SameOperatorAuditStrategy implements INodeStrategy { +public class SameOperatorAuditStrategy extends BaseStrategy { private Type type; @@ -20,17 +20,25 @@ public enum Type { MANUAL_PASS, } + public SameOperatorAuditStrategy() { + super(RandomUtils.generateStringId()); + } + + @Override + public void copy(INodeStrategy target) { + this.type = ((SameOperatorAuditStrategy) target).getType(); + } + @Override public Map toMap() { - Map map = new HashMap<>(); - map.put(TYPE_KEY, strategyType()); + Map map = super.toMap(); map.put("type", type); return map; } public static SameOperatorAuditStrategy fromMap(Map map) { - if (map == null || map.isEmpty()) return null; - SameOperatorAuditStrategy strategy = new SameOperatorAuditStrategy(); + SameOperatorAuditStrategy strategy = BaseStrategy.fromMap(map, SameOperatorAuditStrategy.class); + if (strategy == null) return null; strategy.setType(Type.valueOf((String) map.get("type"))); return strategy; } diff --git a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/TimeoutStrategy.java b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/TimeoutStrategy.java index 589a53ff..4f4440d0 100644 --- a/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/TimeoutStrategy.java +++ b/flow-engine-framework/src/main/java/com/codingapi/flow/strategy/TimeoutStrategy.java @@ -1,15 +1,15 @@ package com.codingapi.flow.strategy; +import com.codingapi.flow.utils.RandomUtils; import lombok.Data; -import java.util.HashMap; import java.util.Map; /** * 超时策略 */ @Data -public class TimeoutStrategy implements INodeStrategy { +public class TimeoutStrategy extends BaseStrategy { // 默认超时时间,默认1天 public static final long DEFAULT_TIMEOUT_TIME = 60 * 60 * 24 * 1000; @@ -26,6 +26,17 @@ public enum Type { REJECT, } + public TimeoutStrategy() { + super(RandomUtils.generateStringId()); + } + + + @Override + public void copy(INodeStrategy target) { + this.type = ((TimeoutStrategy) target).getType(); + this.timeoutTime = ((TimeoutStrategy) target).getTimeoutTime(); + } + public static TimeoutStrategy defaultStrategy() { TimeoutStrategy timeoutStrategy = new TimeoutStrategy(); timeoutStrategy.setType(Type.REMIND); @@ -35,18 +46,15 @@ public static TimeoutStrategy defaultStrategy() { @Override public Map toMap() { - Map map = new HashMap<>(); - map.put(TYPE_KEY, strategyType()); + Map map = super.toMap(); map.put("type", type); map.put("timeoutTime", String.valueOf(timeoutTime)); return map; } public static TimeoutStrategy fromMap(Map map) { - if (map == null || map.isEmpty()) { - return null; - } - TimeoutStrategy timeoutStrategy = new TimeoutStrategy(); + TimeoutStrategy timeoutStrategy = BaseStrategy.fromMap(map, TimeoutStrategy.class); + if (timeoutStrategy == null) return null; timeoutStrategy.setType(Type.valueOf(map.get("type").toString())); timeoutStrategy.setTimeoutTime(Long.parseLong(map.get("timeoutTime").toString())); return timeoutStrategy; diff --git a/flow-engine-framework/src/test/java/com/codingapi/flow/script/ErrorTriggerScriptTest.java b/flow-engine-framework/src/test/java/com/codingapi/flow/script/ErrorTriggerScriptTest.java index 287ad067..a6b9b8ac 100644 --- a/flow-engine-framework/src/test/java/com/codingapi/flow/script/ErrorTriggerScriptTest.java +++ b/flow-engine-framework/src/test/java/com/codingapi/flow/script/ErrorTriggerScriptTest.java @@ -6,8 +6,8 @@ import com.codingapi.flow.form.FormMeta; import com.codingapi.flow.form.FormMetaBuilder; import com.codingapi.flow.form.permission.PermissionType; -import com.codingapi.flow.node.builder.FormFieldPermissionsBuilder; -import com.codingapi.flow.node.builder.NodeStrategyBuilder; +import com.codingapi.flow.builder.FormFieldPermissionsBuilder; +import com.codingapi.flow.builder.NodeStrategyBuilder; import com.codingapi.flow.node.nodes.ApprovalNode; import com.codingapi.flow.node.nodes.StartNode; import com.codingapi.flow.node.nodes.EndNode; diff --git a/flow-engine-framework/src/test/java/com/codingapi/flow/service/FlowServiceTest.java b/flow-engine-framework/src/test/java/com/codingapi/flow/service/FlowServiceTest.java index 74319747..c0cd9c96 100644 --- a/flow-engine-framework/src/test/java/com/codingapi/flow/service/FlowServiceTest.java +++ b/flow-engine-framework/src/test/java/com/codingapi/flow/service/FlowServiceTest.java @@ -1,14 +1,16 @@ package com.codingapi.flow.service; import com.codingapi.flow.action.IFlowAction; +import com.codingapi.flow.action.actions.CustomAction; +import com.codingapi.flow.builder.ActionBuilder; import com.codingapi.flow.context.GatewayContext; import com.codingapi.flow.edge.FlowEdge; import com.codingapi.flow.form.FormMeta; import com.codingapi.flow.form.FormMetaBuilder; import com.codingapi.flow.form.permission.PermissionType; import com.codingapi.flow.gateway.impl.UserGateway; -import com.codingapi.flow.node.builder.FormFieldPermissionsBuilder; -import com.codingapi.flow.node.builder.NodeStrategyBuilder; +import com.codingapi.flow.builder.FormFieldPermissionsBuilder; +import com.codingapi.flow.builder.NodeStrategyBuilder; import com.codingapi.flow.node.nodes.*; import com.codingapi.flow.pojo.body.FlowAdviceBody; import com.codingapi.flow.pojo.request.FlowActionRequest; @@ -138,6 +140,9 @@ void pass() { .addPermission("leave", "reason", PermissionType.WRITE) .build())) .build()) + .actions(ActionBuilder.builder() + .addAction(new CustomAction()) + .build()) .build(); ApprovalNode approvalNode = ApprovalNode.builder() diff --git a/flow-engine-framework/src/test/java/com/codingapi/flow/workflow/WorkflowBuilderTest.java b/flow-engine-framework/src/test/java/com/codingapi/flow/workflow/WorkflowBuilderTest.java index cb6063a1..c0f8075d 100644 --- a/flow-engine-framework/src/test/java/com/codingapi/flow/workflow/WorkflowBuilderTest.java +++ b/flow-engine-framework/src/test/java/com/codingapi/flow/workflow/WorkflowBuilderTest.java @@ -5,8 +5,8 @@ import com.codingapi.flow.form.FormMeta; import com.codingapi.flow.form.FormMetaBuilder; import com.codingapi.flow.form.permission.PermissionType; -import com.codingapi.flow.node.builder.FormFieldPermissionsBuilder; -import com.codingapi.flow.node.builder.NodeStrategyBuilder; +import com.codingapi.flow.builder.FormFieldPermissionsBuilder; +import com.codingapi.flow.builder.NodeStrategyBuilder; import com.codingapi.flow.node.nodes.ApprovalNode; import com.codingapi.flow.node.nodes.StartNode; import com.codingapi.flow.node.nodes.EndNode;