mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-07 21:19:51 +00:00
add execute result branch
This commit is contained in:
parent
69d4b3f93d
commit
e6e964aa8c
@ -9,13 +9,16 @@ import (
|
||||
type WorkflowNodeType string
|
||||
|
||||
const (
|
||||
WorkflowNodeTypeStart = WorkflowNodeType("start")
|
||||
WorkflowNodeTypeEnd = WorkflowNodeType("end")
|
||||
WorkflowNodeTypeApply = WorkflowNodeType("apply")
|
||||
WorkflowNodeTypeDeploy = WorkflowNodeType("deploy")
|
||||
WorkflowNodeTypeNotify = WorkflowNodeType("notify")
|
||||
WorkflowNodeTypeBranch = WorkflowNodeType("branch")
|
||||
WorkflowNodeTypeCondition = WorkflowNodeType("condition")
|
||||
WorkflowNodeTypeStart = WorkflowNodeType("start")
|
||||
WorkflowNodeTypeEnd = WorkflowNodeType("end")
|
||||
WorkflowNodeTypeApply = WorkflowNodeType("apply")
|
||||
WorkflowNodeTypeDeploy = WorkflowNodeType("deploy")
|
||||
WorkflowNodeTypeNotify = WorkflowNodeType("notify")
|
||||
WorkflowNodeTypeBranch = WorkflowNodeType("branch")
|
||||
WorkflowNodeTypeCondition = WorkflowNodeType("condition")
|
||||
WorkflowNodeTypeExecuteResultBranch = WorkflowNodeType("execute_result_branch")
|
||||
WorkflowNodeTypeExecuteSuccess = WorkflowNodeType("execute_success")
|
||||
WorkflowNodeTypeExecuteFailure = WorkflowNodeType("execute_failure")
|
||||
)
|
||||
|
||||
type WorkflowTriggerType string
|
||||
|
27
internal/workflow/node-processor/execute_failure_node.go
Normal file
27
internal/workflow/node-processor/execute_failure_node.go
Normal file
@ -0,0 +1,27 @@
|
||||
package nodeprocessor
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/usual2970/certimate/internal/domain"
|
||||
)
|
||||
|
||||
type executeFailureNode struct {
|
||||
node *domain.WorkflowNode
|
||||
*nodeLogger
|
||||
}
|
||||
|
||||
func NewExecuteFailureNode(node *domain.WorkflowNode) *executeFailureNode {
|
||||
return &executeFailureNode{
|
||||
node: node,
|
||||
nodeLogger: NewNodeLogger(node),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *executeFailureNode) Run(ctx context.Context) error {
|
||||
e.AddOutput(ctx,
|
||||
e.node.Name,
|
||||
"进入执行失败分支",
|
||||
)
|
||||
return nil
|
||||
}
|
27
internal/workflow/node-processor/execute_success_node.go
Normal file
27
internal/workflow/node-processor/execute_success_node.go
Normal file
@ -0,0 +1,27 @@
|
||||
package nodeprocessor
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/usual2970/certimate/internal/domain"
|
||||
)
|
||||
|
||||
type executeSuccessNode struct {
|
||||
node *domain.WorkflowNode
|
||||
*nodeLogger
|
||||
}
|
||||
|
||||
func NewExecuteSuccessNode(node *domain.WorkflowNode) *executeSuccessNode {
|
||||
return &executeSuccessNode{
|
||||
node: node,
|
||||
nodeLogger: NewNodeLogger(node),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *executeSuccessNode) Run(ctx context.Context) error {
|
||||
e.AddOutput(ctx,
|
||||
e.node.Name,
|
||||
"进入执行成功分支",
|
||||
)
|
||||
return nil
|
||||
}
|
@ -57,6 +57,10 @@ func GetProcessor(node *domain.WorkflowNode) (nodeProcessor, error) {
|
||||
return NewDeployNode(node), nil
|
||||
case domain.WorkflowNodeTypeNotify:
|
||||
return NewNotifyNode(node), nil
|
||||
case domain.WorkflowNodeTypeExecuteSuccess:
|
||||
return NewExecuteSuccessNode(node), nil
|
||||
case domain.WorkflowNodeTypeExecuteFailure:
|
||||
return NewExecuteFailureNode(node), nil
|
||||
}
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ func (w *workflowProcessor) Run(ctx context.Context) error {
|
||||
func (w *workflowProcessor) runNode(ctx context.Context, node *domain.WorkflowNode) error {
|
||||
current := node
|
||||
for current != nil {
|
||||
if current.Type == domain.WorkflowNodeTypeBranch {
|
||||
if current.Type == domain.WorkflowNodeTypeBranch || current.Type == domain.WorkflowNodeTypeExecuteResultBranch {
|
||||
for _, branch := range current.Branches {
|
||||
if err := w.runNode(ctx, &branch); err != nil {
|
||||
continue
|
||||
@ -38,24 +38,37 @@ func (w *workflowProcessor) runNode(ctx context.Context, node *domain.WorkflowNo
|
||||
}
|
||||
}
|
||||
|
||||
if current.Type != domain.WorkflowNodeTypeBranch {
|
||||
processor, err := GetProcessor(current)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var runErr error
|
||||
var processor nodeProcessor
|
||||
for {
|
||||
if current.Type != domain.WorkflowNodeTypeBranch && current.Type != domain.WorkflowNodeTypeExecuteResultBranch {
|
||||
processor, runErr = GetProcessor(current)
|
||||
if runErr != nil {
|
||||
break
|
||||
}
|
||||
|
||||
err = processor.Run(ctx)
|
||||
runErr = processor.Run(ctx)
|
||||
|
||||
log := processor.Log(ctx)
|
||||
if log != nil {
|
||||
w.logs = append(w.logs, *log)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
log := processor.Log(ctx)
|
||||
if log != nil {
|
||||
w.logs = append(w.logs, *log)
|
||||
}
|
||||
if runErr != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if runErr != nil && current.Next != nil && current.Next.Type != domain.WorkflowNodeTypeExecuteResultBranch {
|
||||
return runErr
|
||||
} else if runErr != nil && current.Next != nil && current.Next.Type == domain.WorkflowNodeTypeExecuteResultBranch {
|
||||
current = getBranchByType(current.Next.Branches, domain.WorkflowNodeTypeExecuteFailure)
|
||||
} else if runErr == nil && current.Next != nil && current.Next.Type == domain.WorkflowNodeTypeExecuteResultBranch {
|
||||
current = getBranchByType(current.Next.Branches, domain.WorkflowNodeTypeExecuteSuccess)
|
||||
} else {
|
||||
current = current.Next
|
||||
}
|
||||
current = current.Next
|
||||
|
||||
}
|
||||
return nil
|
||||
@ -68,3 +81,12 @@ func WithWorkflowId(ctx context.Context, id string) context.Context {
|
||||
func GetWorkflowId(ctx context.Context) string {
|
||||
return ctx.Value("workflow_id").(string)
|
||||
}
|
||||
|
||||
func getBranchByType(branches []domain.WorkflowNode, nodeType domain.WorkflowNodeType) *domain.WorkflowNode {
|
||||
for _, branch := range branches {
|
||||
if branch.Type == nodeType {
|
||||
return &branch
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import BranchNode from "./node/BranchNode";
|
||||
import ConditionNode from "./node/ConditionNode";
|
||||
import DeployNode from "./node/DeployNode";
|
||||
import EndNode from "./node/EndNode";
|
||||
import ExecuteResultBranchNode from "./node/ExecuteResultBranchNode";
|
||||
import ExecuteResultNode from "./node/ExecuteResultNode";
|
||||
import NotifyNode from "./node/NotifyNode";
|
||||
import StartNode from "./node/StartNode";
|
||||
|
||||
@ -35,6 +37,13 @@ const WorkflowElement = ({ node, disabled, branchId, branchIndex }: WorkflowElem
|
||||
case WorkflowNodeType.Branch:
|
||||
return <BranchNode node={node} disabled={disabled} />;
|
||||
|
||||
case WorkflowNodeType.ExecuteResultBranch:
|
||||
return <ExecuteResultBranchNode node={node} disabled={disabled} />;
|
||||
|
||||
case WorkflowNodeType.ExecuteSuccess:
|
||||
case WorkflowNodeType.ExecuteFailure:
|
||||
return <ExecuteResultNode node={node} disabled={disabled} branchId={branchId!} branchIndex={branchIndex!} />;
|
||||
|
||||
case WorkflowNodeType.Condition:
|
||||
return <ConditionNode node={node} disabled={disabled} branchId={branchId!} branchIndex={branchIndex!} />;
|
||||
|
||||
|
@ -27,20 +27,29 @@ const AddNode = ({ node, disabled }: AddNodeProps) => {
|
||||
[WorkflowNodeType.Apply, "workflow_node.apply.label", <SolutionOutlinedIcon />],
|
||||
[WorkflowNodeType.Deploy, "workflow_node.deploy.label", <CloudUploadOutlinedIcon />],
|
||||
[WorkflowNodeType.Branch, "workflow_node.branch.label", <SisternodeOutlinedIcon />],
|
||||
[WorkflowNodeType.ExecuteResultBranch, "workflow_node.execute_result_branch.label", <SisternodeOutlinedIcon />],
|
||||
[WorkflowNodeType.Notify, "workflow_node.notify.label", <SendOutlinedIcon />],
|
||||
].map(([type, label, icon]) => {
|
||||
return {
|
||||
key: type as string,
|
||||
disabled: disabled,
|
||||
label: t(label as string),
|
||||
icon: icon,
|
||||
onClick: () => {
|
||||
const nextNode = newNode(type as WorkflowNodeType);
|
||||
addNode(nextNode, node.id);
|
||||
},
|
||||
};
|
||||
});
|
||||
}, [node.id, disabled]);
|
||||
]
|
||||
.filter(([type]) => {
|
||||
if (node.type !== WorkflowNodeType.Apply && node.type !== WorkflowNodeType.Deploy && type === WorkflowNodeType.ExecuteResultBranch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
.map(([type, label, icon]) => {
|
||||
return {
|
||||
key: type as string,
|
||||
disabled: disabled,
|
||||
label: t(label as string),
|
||||
icon: icon,
|
||||
onClick: () => {
|
||||
const nextNode = newNode(type as WorkflowNodeType);
|
||||
addNode(nextNode, node.id);
|
||||
},
|
||||
};
|
||||
});
|
||||
}, [node.id, disabled, node.type]);
|
||||
|
||||
return (
|
||||
<div className="relative py-6 before:absolute before:left-1/2 before:top-0 before:h-full before:w-[2px] before:-translate-x-1/2 before:bg-stone-200 before:content-['']">
|
||||
|
84
ui/src/components/workflow/node/ExecuteResultBranchNode.tsx
Normal file
84
ui/src/components/workflow/node/ExecuteResultBranchNode.tsx
Normal file
@ -0,0 +1,84 @@
|
||||
import { memo } from "react";
|
||||
import { theme } from "antd";
|
||||
|
||||
import { type WorkflowNode } from "@/domain/workflow";
|
||||
|
||||
import AddNode from "./AddNode";
|
||||
import WorkflowElement from "../WorkflowElement";
|
||||
import { type SharedNodeProps } from "./_SharedNode";
|
||||
|
||||
const { useToken } = theme;
|
||||
|
||||
export type BrandNodeProps = SharedNodeProps;
|
||||
|
||||
const ExecuteResultBranchNode = ({ node, disabled }: BrandNodeProps) => {
|
||||
const token = useToken();
|
||||
|
||||
const renderBranch = (node: WorkflowNode, branchNodeId?: string, branchIndex?: number) => {
|
||||
const elements: JSX.Element[] = [];
|
||||
|
||||
let current = node as typeof node | undefined;
|
||||
while (current) {
|
||||
elements.push(<WorkflowElement key={current.id} node={current} disabled={disabled} branchId={branchNodeId} branchIndex={branchIndex} />);
|
||||
current = current.next;
|
||||
}
|
||||
|
||||
return elements;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="relative flex gap-x-16 before:absolute before:inset-x-[128px] before:top-0 before:h-[2px] before:bg-stone-200 before:content-[''] after:absolute after:inset-x-[128px] after:bottom-0 after:h-[2px] after:bg-stone-200 after:content-['']"
|
||||
style={{
|
||||
backgroundColor: token.token.colorBgContainer,
|
||||
}}
|
||||
>
|
||||
{node.branches?.map((branch, index) => (
|
||||
<div
|
||||
key={branch.id}
|
||||
className="relative flex flex-col items-center before:absolute before:left-1/2 before:top-0 before:h-full before:w-[2px] before:-translate-x-1/2 before:bg-stone-200 before:content-['']"
|
||||
>
|
||||
{index == 0 && (
|
||||
<>
|
||||
<div
|
||||
className="absolute -left-px -top-1 h-2 w-1/2"
|
||||
style={{
|
||||
backgroundColor: token.token.colorBgContainer,
|
||||
}}
|
||||
></div>
|
||||
<div
|
||||
className="absolute -bottom-1 -left-px z-50 h-2 w-1/2"
|
||||
style={{
|
||||
backgroundColor: token.token.colorBgContainer,
|
||||
}}
|
||||
></div>
|
||||
</>
|
||||
)}
|
||||
{node.branches && index == node.branches.length - 1 && (
|
||||
<>
|
||||
<div
|
||||
className="absolute -right-px -top-1 h-2 w-1/2"
|
||||
style={{
|
||||
backgroundColor: token.token.colorBgContainer,
|
||||
}}
|
||||
></div>
|
||||
<div
|
||||
className="absolute -bottom-1 -right-px z-50 h-2 w-1/2"
|
||||
style={{
|
||||
backgroundColor: token.token.colorBgContainer,
|
||||
}}
|
||||
></div>
|
||||
</>
|
||||
)}
|
||||
<div className="relative flex flex-col items-center">{renderBranch(branch, node.id, index)}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<AddNode node={node} disabled={disabled} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(ExecuteResultBranchNode);
|
60
ui/src/components/workflow/node/ExecuteResultNode.tsx
Normal file
60
ui/src/components/workflow/node/ExecuteResultNode.tsx
Normal file
@ -0,0 +1,60 @@
|
||||
import { memo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { MoreOutlined as MoreOutlinedIcon } from "@ant-design/icons";
|
||||
import { Button, Card, Popover } from "antd";
|
||||
|
||||
import { CheckCircleIcon, XCircleIcon } from "lucide-react";
|
||||
import { WorkflowNodeType } from "@/domain/workflow";
|
||||
import AddNode from "./AddNode";
|
||||
import SharedNode, { type SharedNodeProps } from "./_SharedNode";
|
||||
|
||||
export type ConditionNodeProps = SharedNodeProps & {
|
||||
branchId: string;
|
||||
branchIndex: number;
|
||||
};
|
||||
|
||||
const ExecuteResultNode = ({ node, disabled, branchId, branchIndex }: ConditionNodeProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Popover
|
||||
arrow={false}
|
||||
content={
|
||||
<SharedNode.Menu
|
||||
node={node}
|
||||
branchId={branchId}
|
||||
branchIndex={branchIndex}
|
||||
disabled={disabled}
|
||||
trigger={<Button color="primary" icon={<MoreOutlinedIcon />} variant="text" />}
|
||||
/>
|
||||
}
|
||||
overlayClassName="shadow-md"
|
||||
overlayInnerStyle={{ padding: 0 }}
|
||||
placement="rightTop"
|
||||
>
|
||||
<Card className="relative z-[1] mt-10 w-[256px] shadow-md" styles={{ body: { padding: 0 } }} hoverable>
|
||||
<div className="flex h-[48px] flex-col items-center justify-center truncate px-4 py-2">
|
||||
<div className="flex items-center space-x-2">
|
||||
{node.type === WorkflowNodeType.ExecuteSuccess ? (
|
||||
<>
|
||||
<CheckCircleIcon size={18} className="text-green-500" />
|
||||
<div>{t("workflow_node.execute_success.label")}</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<XCircleIcon size={18} className="text-red-500" />
|
||||
<div>{t("workflow_node.execute_failure.label")}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Popover>
|
||||
|
||||
<AddNode node={node} disabled={disabled} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(ExecuteResultNode);
|
@ -90,7 +90,13 @@ const SharedNodeMenu = ({ trigger, node, disabled, branchId, branchIndex, afterU
|
||||
};
|
||||
|
||||
const handleDeleteClick = async () => {
|
||||
if (node.type === WorkflowNodeType.Branch || node.type === WorkflowNodeType.Condition) {
|
||||
if (
|
||||
node.type === WorkflowNodeType.Branch ||
|
||||
node.type === WorkflowNodeType.Condition ||
|
||||
node.type === WorkflowNodeType.ExecuteResultBranch ||
|
||||
node.type === WorkflowNodeType.ExecuteSuccess ||
|
||||
node.type === WorkflowNodeType.ExecuteFailure
|
||||
) {
|
||||
await removeBranch(branchId!, branchIndex!);
|
||||
} else {
|
||||
await removeNode(node.id);
|
||||
@ -148,7 +154,11 @@ const SharedNodeMenu = ({ trigger, node, disabled, branchId, branchIndex, afterU
|
||||
key: "remove",
|
||||
disabled: disabled || node.type === WorkflowNodeType.Start,
|
||||
label:
|
||||
node.type === WorkflowNodeType.Branch || node.type === WorkflowNodeType.Condition
|
||||
node.type === WorkflowNodeType.Branch ||
|
||||
node.type === WorkflowNodeType.Condition ||
|
||||
node.type === WorkflowNodeType.ExecuteResultBranch ||
|
||||
node.type === WorkflowNodeType.ExecuteSuccess ||
|
||||
node.type === WorkflowNodeType.ExecuteFailure
|
||||
? t("workflow_node.action.remove_branch")
|
||||
: t("workflow_node.action.remove_node"),
|
||||
icon: <CloseCircleOutlinedIcon />,
|
||||
|
@ -30,6 +30,9 @@ export enum WorkflowNodeType {
|
||||
Start = "start",
|
||||
End = "end",
|
||||
Branch = "branch",
|
||||
ExecuteResultBranch = "execute_result_branch",
|
||||
ExecuteSuccess = "execute_success",
|
||||
ExecuteFailure = "execute_failure",
|
||||
Condition = "condition",
|
||||
Apply = "apply",
|
||||
Deploy = "deploy",
|
||||
@ -41,6 +44,9 @@ const workflowNodeTypeDefaultNames: Map<WorkflowNodeType, string> = new Map([
|
||||
[WorkflowNodeType.Start, i18n.t("workflow_node.start.label")],
|
||||
[WorkflowNodeType.End, i18n.t("workflow_node.end.label")],
|
||||
[WorkflowNodeType.Branch, i18n.t("workflow_node.branch.label")],
|
||||
[WorkflowNodeType.ExecuteResultBranch, i18n.t("workflow_node.execute_result_branch.label")],
|
||||
[WorkflowNodeType.ExecuteSuccess, i18n.t("workflow_node.execute_success.label")],
|
||||
[WorkflowNodeType.ExecuteFailure, i18n.t("workflow_node.execute_failure.label")],
|
||||
[WorkflowNodeType.Condition, i18n.t("workflow_node.condition.label")],
|
||||
[WorkflowNodeType.Apply, i18n.t("workflow_node.apply.label")],
|
||||
[WorkflowNodeType.Deploy, i18n.t("workflow_node.deploy.label")],
|
||||
@ -210,6 +216,17 @@ export const newNode = (nodeType: WorkflowNodeType, options: NewNodeOptions = {}
|
||||
node.branches = [newNode(WorkflowNodeType.Condition, { branchIndex: 0 }), newNode(WorkflowNodeType.Condition, { branchIndex: 1 })];
|
||||
}
|
||||
break;
|
||||
case WorkflowNodeType.ExecuteResultBranch:
|
||||
{
|
||||
node.branches = [newNode(WorkflowNodeType.ExecuteSuccess), newNode(WorkflowNodeType.ExecuteFailure)];
|
||||
}
|
||||
break;
|
||||
case WorkflowNodeType.ExecuteSuccess:
|
||||
case WorkflowNodeType.ExecuteFailure:
|
||||
{
|
||||
node.validated = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return node;
|
||||
@ -223,7 +240,7 @@ export const updateNode = (node: WorkflowNode, targetNode: WorkflowNode) => {
|
||||
Object.assign(current, targetNode);
|
||||
break;
|
||||
}
|
||||
if (current.type === WorkflowNodeType.Branch) {
|
||||
if (current.type === WorkflowNodeType.Branch || current.type === WorkflowNodeType.ExecuteResultBranch) {
|
||||
current.branches = current.branches!.map((branch) => updateNode(branch, targetNode));
|
||||
}
|
||||
current = current.next as WorkflowNode;
|
||||
@ -236,16 +253,16 @@ export const addNode = (node: WorkflowNode, preId: string, targetNode: WorkflowN
|
||||
return produce(node, (draft) => {
|
||||
let current = draft;
|
||||
while (current) {
|
||||
if (current.id === preId && targetNode.type !== WorkflowNodeType.Branch) {
|
||||
if (current.id === preId && targetNode.type !== WorkflowNodeType.Branch && targetNode.type !== WorkflowNodeType.ExecuteResultBranch) {
|
||||
targetNode.next = current.next;
|
||||
current.next = targetNode;
|
||||
break;
|
||||
} else if (current.id === preId && targetNode.type === WorkflowNodeType.Branch) {
|
||||
} else if (current.id === preId && (targetNode.type === WorkflowNodeType.Branch || targetNode.type === WorkflowNodeType.ExecuteResultBranch)) {
|
||||
targetNode.branches![0].next = current.next;
|
||||
current.next = targetNode;
|
||||
break;
|
||||
}
|
||||
if (current.type === WorkflowNodeType.Branch) {
|
||||
if (current.type === WorkflowNodeType.Branch || current.type === WorkflowNodeType.ExecuteResultBranch) {
|
||||
current.branches = current.branches!.map((branch) => addNode(branch, preId, targetNode));
|
||||
}
|
||||
current = current.next as WorkflowNode;
|
||||
@ -269,7 +286,7 @@ export const addBranch = (node: WorkflowNode, branchNodeId: string) => {
|
||||
);
|
||||
break;
|
||||
}
|
||||
if (current.type === WorkflowNodeType.Branch) {
|
||||
if (current.type === WorkflowNodeType.Branch || current.type === WorkflowNodeType.ExecuteResultBranch) {
|
||||
current.branches = current.branches!.map((branch) => addBranch(branch, branchNodeId));
|
||||
}
|
||||
current = current.next as WorkflowNode;
|
||||
@ -286,7 +303,7 @@ export const removeNode = (node: WorkflowNode, targetNodeId: string) => {
|
||||
current.next = current.next.next;
|
||||
break;
|
||||
}
|
||||
if (current.type === WorkflowNodeType.Branch) {
|
||||
if (current.type === WorkflowNodeType.Branch || current.type === WorkflowNodeType.ExecuteResultBranch) {
|
||||
current.branches = current.branches!.map((branch) => removeNode(branch, targetNodeId));
|
||||
}
|
||||
current = current.next as WorkflowNode;
|
||||
@ -306,7 +323,7 @@ export const removeBranch = (node: WorkflowNode, branchNodeId: string, branchInd
|
||||
};
|
||||
while (current && last) {
|
||||
if (current.id === branchNodeId) {
|
||||
if (current.type !== WorkflowNodeType.Branch) {
|
||||
if (current.type !== WorkflowNodeType.Branch && current.type !== WorkflowNodeType.ExecuteResultBranch) {
|
||||
return draft;
|
||||
}
|
||||
current.branches!.splice(branchIndex, 1);
|
||||
@ -328,7 +345,7 @@ export const removeBranch = (node: WorkflowNode, branchNodeId: string, branchInd
|
||||
|
||||
break;
|
||||
}
|
||||
if (current.type === WorkflowNodeType.Branch) {
|
||||
if (current.type === WorkflowNodeType.Branch || current.type === WorkflowNodeType.ExecuteResultBranch) {
|
||||
current.branches = current.branches!.map((branch) => removeBranch(branch, branchNodeId, branchIndex));
|
||||
}
|
||||
current = current.next as WorkflowNode;
|
||||
@ -350,6 +367,11 @@ export const getWorkflowOutputBeforeId = (node: WorkflowNode, id: string, type:
|
||||
return true;
|
||||
}
|
||||
|
||||
// 如果当前节点是execute_failure,清除execute_result_branch节点前一个节点的输出
|
||||
if (current.type === WorkflowNodeType.ExecuteFailure) {
|
||||
output.splice(output.length - 1);
|
||||
}
|
||||
|
||||
if (current.type !== WorkflowNodeType.Branch && current.outputs && current.outputs.some((io) => io.type === type)) {
|
||||
output.push({
|
||||
...current,
|
||||
@ -357,7 +379,7 @@ export const getWorkflowOutputBeforeId = (node: WorkflowNode, id: string, type:
|
||||
});
|
||||
}
|
||||
|
||||
if (current.type === WorkflowNodeType.Branch) {
|
||||
if (current.type === WorkflowNodeType.Branch || current.type === WorkflowNodeType.ExecuteResultBranch) {
|
||||
const currentLength = output.length;
|
||||
for (const branch of current.branches!) {
|
||||
if (traverse(branch, output)) {
|
||||
@ -380,7 +402,7 @@ export const getWorkflowOutputBeforeId = (node: WorkflowNode, id: string, type:
|
||||
export const isAllNodesValidated = (node: WorkflowNode): boolean => {
|
||||
let current = node as typeof node | undefined;
|
||||
while (current) {
|
||||
if (current.type === WorkflowNodeType.Branch) {
|
||||
if (current.type === WorkflowNodeType.Branch || current.type === WorkflowNodeType.ExecuteResultBranch) {
|
||||
for (const branch of current.branches!) {
|
||||
if (!isAllNodesValidated(branch)) {
|
||||
return false;
|
||||
|
@ -362,5 +362,11 @@
|
||||
|
||||
"workflow_node.branch.label": "Branch",
|
||||
|
||||
"workflow_node.execute_result_branch.label": "Execute result branch",
|
||||
|
||||
"workflow_node.execute_success.label": "Execute success",
|
||||
|
||||
"workflow_node.execute_failure.label": "Execute failure",
|
||||
|
||||
"workflow_node.condition.label": "Condition"
|
||||
}
|
||||
|
@ -362,5 +362,11 @@
|
||||
|
||||
"workflow_node.branch.label": "分支",
|
||||
|
||||
"workflow_node.execute_result_branch.label": "执行结果分支",
|
||||
|
||||
"workflow_node.execute_success.label": "执行成功",
|
||||
|
||||
"workflow_node.execute_failure.label": "执行失败",
|
||||
|
||||
"workflow_node.condition.label": "条件"
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user