Skip to content

Commit 529427e

Browse files
committed
add action plugin
1 parent 66ee50a commit 529427e

11 files changed

Lines changed: 131 additions & 50 deletions

File tree

flow-engine-framework/src/main/java/com/codingapi/flow/script/ScriptDefaultConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def run(request){
2121
*/
2222
public static final String SCRIPT_DEFAULT_ACTION_REJECT = """
2323
// @SCRIPT_TITLE 返回开始节点
24+
// @SCRIPT_META {"type":"START"}
2425
def run(request){
2526
return request.getStartNode().getId();
2627
}

frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/action/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export const ActionTable: React.FC<ActionTableProps> = (props) => {
6868
<Space>
6969
<a
7070
onClick={() => {
71+
form.resetFields();
7172
form.setFieldsValue(record);
7273
setVisible(true);
7374
}}
@@ -113,7 +114,9 @@ export const ActionTable: React.FC<ActionTableProps> = (props) => {
113114
}}
114115
pagination={false}
115116
/>
117+
116118
<ActionConfigModal
119+
nodeId={node.id}
117120
open={visible}
118121
manager={presenter.getFlowActionManager()}
119122
form={form}

frontend/packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/action/presenter.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ export class FlowActionListPresenter {
4545
if (item.id === actionId) {
4646
return {
4747
...item,
48-
title: action.title,
48+
...action,
4949
display: {
50-
...action
50+
...item.display,
51+
...action.display,
5152
}
5253
}
5354
}

frontend/packages/flow-pc/flow-pc-design/src/components/design-panel/manager/node.ts

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export class NodeConvertorManager {
2525
actions: node.actions,
2626
script: node.script,
2727
view: node.view,
28+
display: node.display,
2829
...this.toStrategyRender(node),
2930
},
3031
blocks: blocks.map(item => this.toItemRender(item))
@@ -50,6 +51,7 @@ export class NodeConvertorManager {
5051
actions: data?.actions || [],
5152
strategies: this.toStrategyData(data),
5253
script: data?.script,
54+
display: data?.display,
5355
blocks: blocks.map(item => {
5456
return this.toDataItem(item)
5557
}),
@@ -98,11 +100,11 @@ interface MappingData {
98100
}
99101

100102

101-
export class NodeManger{
103+
export class NodeManger {
104+
// 设计时最新的数据
102105
private readonly nodes: FlowNode[];
103106
private readonly nodeList: FlowNode[];
104107

105-
106108
constructor(nodes: FlowNode[]) {
107109
this.nodes = nodes;
108110
this.nodeList = [];
@@ -119,12 +121,43 @@ export class NodeManger{
119121
}
120122
}
121123

124+
/**
125+
* 获取可以退回的节点
126+
* @param nodeId
127+
*/
128+
public getBackNodes(nodeId: string) {
129+
const list: FlowNode[] = [];
130+
for (const node of this.nodeList) {
131+
if (node.id === nodeId) {
132+
break;
133+
}
134+
if (node.display) {
135+
list.push(node);
136+
}
137+
}
138+
return list;
139+
}
140+
141+
142+
public getSize() {
143+
return this.nodes.length;
144+
}
145+
146+
public getNodeByType(type:string){
147+
for (const node of this.nodeList) {
148+
if (node.type === type) {
149+
return node;
150+
}
151+
}
152+
return null;
153+
}
154+
122155

123156
/**
124157
* 获取节点
125158
* @param id 节点id
126159
*/
127-
public getNode(id:string){
160+
public getNode(id: string) {
128161
for (const node of this.nodeList) {
129162
if (node.id === id) {
130163
return node;
@@ -231,15 +264,15 @@ export class NodeRouterManager {
231264
public mapping(data: MappingData) {
232265
const nodeId = data.node;
233266
let matchNode = null;
234-
for(const node of this.nodeList) {
235-
if(matchNode) {
236-
break;
267+
for (const node of this.nodeList) {
268+
if (matchNode) {
269+
break;
237270
}
238-
if(node.type === nodeId){
271+
if (node.type === nodeId) {
239272
matchNode = node;
240273
}
241274
}
242-
if(matchNode){
275+
if (matchNode) {
243276
return {
244277
...data,
245278
node: matchNode.id

frontend/packages/flow-pc/flow-pc-design/src/components/design-panel/presenters/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ export class Presenter {
142142
console.log('save latest:', apiData);
143143
}
144144

145+
public getNodeManager(){
146+
return new NodeManger(this.state.workflow.nodes || []);
147+
}
148+
145149
public async createNode(form: string, type: string) {
146150
const flowNode = await this.api.createNode(type);
147151
const nodeManager = new NodeConvertorManager();

frontend/packages/flow-pc/flow-pc-design/src/components/script/components/action/components/reject.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@ export const RejectActionForm:React.FC<ActionFormProps> = (props)=>{
1313
<Form.Item
1414
name={"script"}
1515
label={"拒绝策略"}
16+
help={"配置拒绝时跳转的节点"}
1617
>
17-
<ConditionRejectView/>
18+
<ConditionRejectView
19+
nodeId={props.nodeId}
20+
/>
1821
</Form.Item>
1922
</Col>
2023
</Row>

frontend/packages/flow-pc/flow-pc-design/src/components/script/modal/action-config-modal.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const ActionConfigModal: React.FC<ActionModalProps> = (props) => {
1717
}}
1818
>
1919
<ActionForm
20+
nodeId={props.nodeId}
2021
form={props.form}
2122
manager={props.manager}
2223
onFinish={(values) => {

frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/action-reject-view-type.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
export const VIEW_KEY = 'ConditionRejectViewPlugin';
22

33
export interface ConditionRejectViewPlugin {
4+
// 当前节点id
5+
nodeId:string;
46
// 当前的脚本
57
value?: string;
68
// 脚本更改回掉

frontend/packages/flow-pc/flow-pc-design/src/components/script/plugins/view/action-reject-view.tsx

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ import React from "react";
22
import {ConditionRejectViewPlugin, VIEW_KEY} from "@/components/script/plugins/action-reject-view-type";
33
import {ViewBindPlugin} from "@flow-engine/flow-core";
44
import {useDesignContext} from "@/components/design-panel/hooks/use-design-context";
5-
import {RejectNodeManager} from "@/components/script/services/action-reject";
5+
import {ActionRejectService} from "@/components/script/services/action-reject";
6+
import {Select} from "antd";
67

78

8-
const useActionRejectManager = () => {
9-
const {state} = useDesignContext();
10-
const nodes = state.workflow.nodes || [];
11-
return new RejectNodeManager(nodes);
9+
const useActionRejectService = (nodeId: string) => {
10+
const {context} = useDesignContext();
11+
const nodeManager = context.getPresenter().getNodeManager();
12+
return new ActionRejectService(nodeManager);
1213
}
1314

14-
1515
export const ConditionRejectView: React.FC<ConditionRejectViewPlugin> = (props) => {
1616

17-
const rejectNodeManager = useActionRejectManager();
17+
const rejectService = useActionRejectService(props.nodeId);
1818
const ConditionRejectViewComponent = ViewBindPlugin.getInstance().get(VIEW_KEY);
1919

2020
if (ConditionRejectViewComponent) {
@@ -23,15 +23,21 @@ export const ConditionRejectView: React.FC<ConditionRejectViewPlugin> = (props)
2323
);
2424
}
2525

26+
const handleChange = (option: any) => {
27+
const script = rejectService.getScript(option);
28+
props.onChange?.(script);
29+
}
30+
2631
return (
27-
<div
28-
style={{
29-
marginTop: "8px",
30-
padding: "8px",
31-
}}
32-
>
33-
reject
34-
{rejectNodeManager.getSize()}
35-
</div>
32+
<>
33+
<Select
34+
options={rejectService.getOptions(props.nodeId)}
35+
value={rejectService.getValue(props.value)}
36+
onChange={(value, option) => {
37+
handleChange(option);
38+
}}
39+
placeholder={"请选择拒绝退回到的节点"}
40+
/>
41+
</>
3642
)
3743
}

frontend/packages/flow-pc/flow-pc-design/src/components/script/services/action-reject.ts

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,69 @@
11
import {GroovyScriptConvertorUtil} from "@flow-engine/flow-core";
2-
import {FlowNode} from "@/components/design-panel/types";
2+
import {ActionSelectOption} from "@/components/script/typings";
3+
import {NodeManger} from "@/components/design-panel/manager/node";
34

5+
export class ActionRejectService {
46

5-
export class RejectNodeManager {
7+
private readonly nodeManger: NodeManger;
68

7-
private readonly nodes:FlowNode[];
9+
public constructor(nodeManger: NodeManger) {
10+
this.nodeManger = nodeManger;
11+
}
812

9-
constructor(nodes: FlowNode[]) {
10-
this.nodes = nodes;
13+
public getOptions(nodeId: string) {
14+
const options: ActionSelectOption[] = [];
15+
const backNodes = this.nodeManger.getBackNodes(nodeId);
16+
for (const node of backNodes) {
17+
options.push({
18+
label: node.name,
19+
value: node.id,
20+
})
21+
}
22+
options.push({
23+
label: '终止流程',
24+
value: 'TERMINATE',
25+
danger: true,
26+
})
27+
return options;
28+
}
29+
30+
public getValue(script?: string) {
31+
const type = ActionRejectScriptUtils.getType(script);
32+
const node = this.nodeManger.getNodeByType(type);
33+
if (node) {
34+
return node.id;
35+
}
36+
return type;
1137
}
1238

13-
public getSize(){
14-
return this.nodes.length;
39+
public getScript(option: ActionSelectOption) {
40+
return ActionRejectScriptUtils.update(option);
1541
}
42+
1643
}
1744

1845
export class ActionRejectScriptUtils {
1946

20-
public static update(type: string, script: string) {
21-
let groovy;
22-
if (script) {
23-
const returnData = GroovyScriptConvertorUtil.getReturnScript(script).trim();
24-
groovy = script.replace(returnData, `'${type}'`);
25-
groovy = GroovyScriptConvertorUtil.updateScriptMeta(groovy, `{"type":"${type}"}`);
26-
} else {
27-
groovy = `// @CUSTOM_SCRIPT 自定义脚本,返回的数据为动作类型
28-
// @SCRIPT_META {"type":"${type}"}
47+
public static update(option: ActionSelectOption) {
48+
const groovy = `// @CUSTOM_SCRIPT 跳转到 ${option.label}
49+
// @SCRIPT_META {"type":"${option.value}"}
2950
def run(request){
30-
return '${type}';
51+
return '${option.value}';
3152
}
3253
`
33-
}
3454
return GroovyScriptConvertorUtil.formatScript(groovy);
3555
}
3656

3757

38-
public static getType(script:string){
39-
const meta = GroovyScriptConvertorUtil.getScriptMeta(script);
40-
const data = JSON.parse(meta);
41-
if(data){
42-
return data.type;
58+
public static getType(script?: string) {
59+
if (script) {
60+
const meta = GroovyScriptConvertorUtil.getScriptMeta(script);
61+
if (meta) {
62+
const data = JSON.parse(meta);
63+
if (data) {
64+
return data.type;
65+
}
66+
}
4367
}
4468
return undefined;
4569
}

0 commit comments

Comments
 (0)