Skip to content

Commit c082e08

Browse files
committed
1 parent df0488b commit c082e08

10 files changed

Lines changed: 193 additions & 49 deletions

File tree

flow-engine-framework/src/main/java/com/codingapi/flow/pojo/response/FlowContent.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.codingapi.flow.action.IFlowAction;
44
import com.codingapi.flow.form.FormMeta;
5+
import com.codingapi.flow.manager.ActionManager;
56
import com.codingapi.flow.manager.NodeStrategyManager;
67
import com.codingapi.flow.manager.OperatorManager;
78
import com.codingapi.flow.node.IFlowNode;
@@ -40,6 +41,16 @@ public class FlowContent {
4041
*/
4142
private String view;
4243

44+
/**
45+
* 审批意见是否必填
46+
*/
47+
private boolean adviceNullable;
48+
49+
/**
50+
* 签名是否必填
51+
*/
52+
private boolean signable;
53+
4354
/**
4455
* 表单元数据
4556
*/
@@ -107,9 +118,13 @@ public void pushNextNodes(FlowSession flowSession, List<IFlowNode> nextNodes) {
107118
}
108119

109120
public void pushCurrentNode(IFlowNode currentNode) {
110-
this.actions = currentNode.actionManager().getActions();
121+
ActionManager actionManager = currentNode.actionManager();
122+
NodeStrategyManager strategyManager = currentNode.strategyManager();
123+
this.actions = actionManager.getActions();
111124
Map<String,Object> nodeData = currentNode.toMap();
112125
this.view = (String) nodeData.get("view");
126+
this.adviceNullable = strategyManager.isEnableAdvice();
127+
this.signable = strategyManager.isEnableSignable();
113128
}
114129

115130
public void pushWorkflow(Workflow workflow) {

flow-engine-framework/src/main/java/com/codingapi/flow/record/FlowRecord.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import lombok.Setter;
1717
import org.springframework.util.StringUtils;
1818

19-
import java.util.ArrayList;
2019
import java.util.List;
2120
import java.util.Map;
2221

frontend/apps/app-pc/src/pages/todo.tsx

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
WorkflowSelectModal
99
} from "@flow-engine/flow-design";
1010
import {Button, Space, Tabs, type TabsProps} from "antd";
11+
import dayjs from "dayjs";
1112

1213
const TodoPage: React.FC = () => {
1314

@@ -18,10 +19,12 @@ const TodoPage: React.FC = () => {
1819
const [selectVisible, setSelectVisible] = React.useState(false);
1920
const [approvalVisible, setApprovalVisible] = React.useState(false);
2021
const [workflowCode, setWorkflowCode] = React.useState<string>('');
22+
const [currentRecordId, setCurrentRecordId] = React.useState<string>('');
23+
const [currentTab, setCurrentTab] = React.useState<string>('all');
2124

2225
const columns: TableProps<any>['columns'] = [
2326
{
24-
dataIndex: 'id',
27+
dataIndex: 'recordId',
2528
title: '编号',
2629
},
2730
{
@@ -31,28 +34,45 @@ const TodoPage: React.FC = () => {
3134
{
3235
dataIndex: 'readTime',
3336
title: '读取状态',
37+
render: (text, record) => {
38+
return text ? '已读' : '未读';
39+
}
3440
},
3541
{
3642
dataIndex: 'createTime',
3743
title: '创建时间',
44+
render: (text, record) => {
45+
return dayjs(text).format('YYYY-MM-DD HH:mm:ss');
46+
}
3847
},
3948
{
4049
dataIndex: 'currentOperatorId',
4150
title: '审批人',
51+
hidden: true,
52+
},
53+
{
54+
dataIndex: 'currentOperatorName',
55+
title: '审批人',
4256
},
4357
{
4458
dataIndex: 'recordState',
4559
title: '状态',
60+
render: (text, record) => {
61+
return text ? '已办' : '待办';
62+
}
4663
},
4764
{
4865
dataIndex: 'option',
4966
title: '操作',
5067
render: (value, record) => {
5168
return (
5269
<Space>
53-
<a onClick={() => {
54-
55-
}}>办理</a>
70+
<a
71+
onClick={() => {
72+
setCurrentRecordId(record.recordId);
73+
setApprovalVisible(true);
74+
}}
75+
>办理</a>
5676
</Space>
5777
)
5878
}
@@ -104,21 +124,29 @@ const TodoPage: React.FC = () => {
104124
}
105125
];
106126

127+
const reloadCurrentTab = () => {
128+
if (currentTab === 'all') {
129+
actionAll.current?.reload();
130+
}
131+
if (currentTab === 'done') {
132+
actionDone.current?.reload();
133+
}
134+
if (currentTab === 'todo') {
135+
actionTodo.current?.reload();
136+
}
137+
}
138+
139+
React.useEffect(() => {
140+
reloadCurrentTab();
141+
},[currentTab]);
142+
107143
return (
108144
<div>
109145
<Tabs
110146
items={items}
111147
centered={true}
112148
onChange={(currentKey) => {
113-
if (currentKey === 'all') {
114-
actionAll.current?.reload();
115-
}
116-
if (currentKey === 'done') {
117-
actionDone.current?.reload();
118-
}
119-
if (currentKey === 'todo') {
120-
actionTodo.current?.reload();
121-
}
149+
setCurrentTab(currentKey);
122150
}}
123151
tabBarExtraContent={{
124152
right: (
@@ -147,8 +175,10 @@ const TodoPage: React.FC = () => {
147175
<ApprovalPanelDrawer
148176
workflowCode={workflowCode}
149177
open={approvalVisible}
178+
recordId={currentRecordId}
150179
onClose={() => {
151180
setApprovalVisible(false);
181+
reloadCurrentTab();
152182
}}
153183
/>
154184
</div>

frontend/packages/flow-design/src/components/flow-approval/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {detail} from "@/api/record";
44
import {FlowContent} from "@/components/flow-approval/typings";
55
import {ApprovalLayout} from "@/components/flow-approval/layout";
66

7-
87
interface ApprovalPanelProps {
98
workflowCode?: string;
109
recordId?:string;

frontend/packages/flow-design/src/components/flow-approval/layout/body.tsx

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,60 @@ import {useApprovalContext} from "@/components/flow-approval/hooks/use-approval-
33
import {Col, Form, Row} from "antd";
44
import {ViewPlugin} from "@/plugins/view";
55

6-
export const Body = () => {
7-
const {state, context} = useApprovalContext();
86

7+
const FormViewComponent: React.FC = () => {
8+
const {state, context} = useApprovalContext();
99
const ViewComponent = ViewPlugin.getInstance().get(state.flow?.view || 'default');
10-
10+
// 是否可合并审批
11+
const mergeable = state.flow?.mergeable || false;
1112
const todos = state.flow?.todos || [];
12-
const [viewForm] = Form.useForm();
13+
const viewForms = todos.map(item=>{
14+
return {
15+
instance:Form.useForm()[0],
16+
data:item.data,
17+
}
18+
})
1319

1420
React.useEffect(() => {
15-
context.getPresenter().getFormActionContext().addAction({
16-
save(): any {
17-
return viewForm.getFieldsValue();
18-
},
19-
key(): string {
20-
return 'view-form'
21-
}
22-
})
21+
viewForms.forEach(item=>{
22+
const formInstance = item.instance;
23+
const data = item.data;
24+
context.getPresenter().getFormActionContext().addAction({
25+
save(): any {
26+
return formInstance.getFieldsValue();
27+
},
28+
key(): string {
29+
return 'view-form'
30+
}
31+
});
32+
formInstance.setFieldsValue(data);
33+
});
2334
}, []);
2435

36+
if(ViewComponent){
37+
if(mergeable){
38+
return (
39+
<div>
40+
<h3>合并审批</h3>
41+
</div>
42+
)
43+
}
44+
return (
45+
<>
46+
{viewForms.map((item,index)=>(
47+
<ViewComponent key={index} form={item.instance}/>
48+
))}
49+
</>
50+
)
51+
}
52+
}
53+
54+
export const Body = () => {
2555
return (
2656
<Row>
2757
<Col span={18}>
2858
表单详情
29-
30-
{ViewComponent && todos.length <= 1 && (
31-
<ViewComponent form={viewForm}/>
32-
)}
33-
59+
<FormViewComponent/>
3460
</Col>
3561
<Col span={6}>
3662
流转历史
Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import React from "react";
22
import {useApprovalContext} from "@/components/flow-approval/hooks/use-approval-context";
33
import {Button, Flex, message} from "antd";
4-
import {create} from "@/api/record";
54

65
export const Header = () => {
76
const {state, context} = useApprovalContext()
87

98
const actions = state.flow?.actions || [];
109

11-
const formActionContext = context.getPresenter().getFormActionContext();
10+
const actionPresenter = context.getPresenter().getFlowActionPresenter();
1211

1312
return (
1413
<Flex
@@ -18,24 +17,21 @@ export const Header = () => {
1817
{actions.map(item => {
1918
return (
2019
<Button
21-
onClick={()=>{
20+
onClick={() => {
2221
const actionId = item.id;
23-
const formData = formActionContext.save();
24-
const body = {
25-
formData,
26-
actionId,
27-
workId: state.flow?.workId,
28-
}
29-
create(body).then((res)=>{
30-
message.success("流程已经创建")
31-
})
22+
actionPresenter.action(actionId).then(() => {
23+
message.success("操作成功");
24+
context.close();
25+
});
3226
}}
3327
>{item.title}</Button>
3428
)
3529
})}
36-
<Button onClick={() => {
37-
context.close();
38-
}}>关闭</Button>
30+
<Button
31+
onClick={() => {
32+
context.close();
33+
}}
34+
>关闭</Button>
3935
</Flex>
4036
)
4137
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
import {FlowApprovalApi} from "@/components/flow-approval/typings";
2+
import {action as actionRecord, create as createRecord} from "@/api/record";
23

34
export class FlowApprovalApiImpl implements FlowApprovalApi {
45

6+
create = async (body: Record<string, any>)=> {
7+
const response = await createRecord(body);
8+
if(response.success){
9+
return response.data;
10+
}
11+
}
12+
13+
action =async (body: Record<string, any>)=> {
14+
return await actionRecord(body);
15+
}
16+
517
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import {FlowApprovalApi, State} from "@/components/flow-approval/typings";
2+
import {FormActionContext} from "@/components/flow-approval/presenters/form";
3+
4+
export class FlowActionPresenter {
5+
6+
private readonly api: FlowApprovalApi;
7+
private readonly formActionContext:FormActionContext;
8+
private state: State;
9+
10+
constructor(state: State,
11+
api: FlowApprovalApi,
12+
formActionContext:FormActionContext) {
13+
this.state = state;
14+
this.api = api;
15+
this.formActionContext = formActionContext;
16+
}
17+
18+
public syncState(state: State) {
19+
this.state = state;
20+
}
21+
22+
23+
public async action(actionId:string) {
24+
const recordId = this.state.flow?.recordId;
25+
const workId = this.state.flow?.workId;
26+
const formData = this.formActionContext.save();
27+
if(recordId){
28+
const request = {
29+
formData,
30+
recordId,
31+
advice:{
32+
actionId,
33+
}
34+
}
35+
await this.api.action(request);
36+
}else {
37+
const createRequest = {
38+
workId,
39+
formData,
40+
actionId,
41+
}
42+
const recordId = await this.api.create(createRequest);
43+
const actionRequest = {
44+
formData,
45+
recordId,
46+
advice:{
47+
actionId,
48+
}
49+
}
50+
await this.api.action(actionRequest);
51+
}
52+
}
53+
54+
}

0 commit comments

Comments
 (0)