Skip to content

Commit 253e294

Browse files
committed
新功能支持:2024-11-27
1. 支持审批意见数据的表单返回 【已完成】 2. 选人组件的支持 3. 历史记录数据的展示 【已完成】 4. 流程图的展示 【已完成】
1 parent 6af1b94 commit 253e294

File tree

30 files changed

+470
-37
lines changed

30 files changed

+470
-37
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.flow-chart-content {
2+
border: 1px solid #ebeef5;
3+
transition: 0.3s;
4+
padding: 15px 16px;
5+
border-radius: 12px;
6+
position: relative;
7+
8+
.flow-view {
9+
width: 100%;
10+
height: 85vh;
11+
}
12+
}
13+
14+
15+
16+
.lf-mini-map {
17+
border: none !important;
18+
box-shadow: 3px 0 10px 1px rgb(228, 224, 219);
19+
}

admin-ui/src/components/Flow/flow/FlowChart.tsx

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,69 @@
1-
import React from "react";
1+
import React, {useEffect, useRef} from "react";
22
import {FlowData} from "@/components/Flow/flow/data";
3+
import {LogicFlow} from "@logicflow/core";
4+
import {DndPanel, Menu, MiniMap, Snapshot} from "@logicflow/extension";
5+
import Start from "@/components/Flow/nodes/Start";
6+
import Node from "@/components/Flow/nodes/Node";
7+
import Over from "@/components/Flow/nodes/Over";
8+
import Circulate from "@/components/Flow/nodes/Circulate";
9+
import '@logicflow/core/es/index.css';
10+
import '@logicflow/extension/lib/style/index.css';
11+
import "./FlowChart.scss";
312

413
interface FlowChartProps {
5-
flowData:FlowData
14+
flowData: FlowData
615
}
716

8-
const FlowChart:React.FC<FlowChartProps> = (props)=>{
17+
const FlowChart: React.FC<FlowChartProps> = (props) => {
18+
19+
const flowData = props.flowData;
20+
21+
const container = useRef<HTMLDivElement>(null);
22+
const lfRef = useRef<LogicFlow>(null);
23+
24+
console.log(flowData.getFlowSchema());
25+
26+
useEffect(() => {
27+
const SilentConfig = {
28+
isSilentMode: true,
29+
stopScrollGraph: false,
30+
stopMoveGraph: false,
31+
stopZoomGraph: false,
32+
edgeTextEdit: false,
33+
};
34+
35+
//@ts-ignore
36+
lfRef.current = new LogicFlow({
37+
//@ts-ignore
38+
container: container.current,
39+
...SilentConfig,
40+
background: {
41+
backgroundColor: '#f3f5f8'
42+
},
43+
plugins: [Menu, DndPanel, MiniMap, Snapshot],
44+
grid: false,
45+
edgeType: 'bezier',
46+
});
47+
48+
lfRef.current.setTheme({
49+
bezier: {
50+
stroke: '#8f94e3',
51+
strokeWidth: 1,
52+
},
53+
});
54+
lfRef.current.register(Start);
55+
lfRef.current.register(Node);
56+
lfRef.current.register(Over);
57+
lfRef.current.register(Circulate);
58+
59+
lfRef.current.render(flowData.getFlowSchema());
60+
}, []);
961

1062
return (
1163
<>
12-
Flow Chart
64+
<div className="flow-chart-content">
65+
<div className={"flow-view"} ref={container}/>
66+
</div>
1367
</>
1468
)
1569
}

admin-ui/src/components/Flow/flow/FlowHistory.tsx

Lines changed: 99 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,113 @@
11
import React from "react";
22
import {FlowData} from "@/components/Flow/flow/data";
3-
3+
import {Divider} from "antd";
4+
import {ProDescriptions} from "@ant-design/pro-components";
5+
import moment from "moment";
6+
import FlowHistoryLine from "@/components/Flow/flow/FlowHistoryLine";
7+
import "./FlowHistoryLine.scss";
48

59
interface FlowHistoryProps {
610
flowData:FlowData
711
}
812

913
const FlowHistory:React.FC<FlowHistoryProps> = (props)=>{
1014

15+
const flowData = props.flowData;
16+
17+
const flowRecord = flowData.getCurrentFlowRecord();
18+
1119
return (
1220
<>
13-
Flow History
21+
<Divider>
22+
<span className="Divider-title">基本信息</span>
23+
</Divider>
24+
<div className="flowApprovalHistory">
25+
<ProDescriptions
26+
className="proDescriptions"
27+
column={2}
28+
bordered
29+
labelStyle={{
30+
textAlign: "center",
31+
width: "180px",
32+
}}
33+
contentStyle={{
34+
width: "300px",
35+
}}
36+
>
37+
<ProDescriptions.Item
38+
span={2}
39+
label={"标题"}
40+
>
41+
<span dangerouslySetInnerHTML={{ __html: flowRecord.title }} ></span>
42+
</ProDescriptions.Item>
43+
<ProDescriptions.Item
44+
span={1}
45+
label={"发起人"}
46+
>
47+
{flowRecord.createOperator.name}
48+
</ProDescriptions.Item>
49+
<ProDescriptions.Item
50+
span={1}
51+
label={"发起时间"}
52+
>
53+
{moment(flowRecord.createTime).format("YYYY-MM-DD HH:mm:ss")}
54+
</ProDescriptions.Item>
55+
56+
<ProDescriptions.Item
57+
span={1}
58+
label={"状态"}
59+
>
60+
{flowRecord.flowStatus === 'RUNNING' && '进行中'}
61+
{flowRecord.flowStatus === 'FINISH' && '已结束'}
62+
</ProDescriptions.Item>
63+
<ProDescriptions.Item
64+
span={1}
65+
label={"流程状态"}
66+
>
67+
{flowRecord.recodeType === 'TODO' && '待办'}
68+
{flowRecord.recodeType === 'DONE' && '已办'}
69+
{flowRecord.recodeType === 'TRANSFER' && '已转办'}
70+
</ProDescriptions.Item>
71+
<ProDescriptions.Item
72+
span={1}
73+
label={"是否延期"}
74+
>
75+
{flowRecord.postponedCount > 0 ? '延期' : '未延期'}
76+
</ProDescriptions.Item>
77+
<ProDescriptions.Item
78+
span={1}
79+
label={"是否干预"}
80+
>
81+
{flowRecord.interfere ? '干预' : '未干预'}
82+
</ProDescriptions.Item>
83+
<ProDescriptions.Item
84+
span={1}
85+
label={"是否已读"}
86+
>
87+
{flowRecord.read ? '已读' : '未读'}
88+
</ProDescriptions.Item>
89+
<ProDescriptions.Item
90+
span={1}
91+
label={"超时时间"}
92+
>
93+
{flowRecord.timeoutTime == 0 ? '未设置' : moment(flowRecord.timeoutTime).format("YYYY-MM-DD HH:mm:ss")}
94+
</ProDescriptions.Item>
95+
<ProDescriptions.Item
96+
span={1}
97+
label={"节点名称"}
98+
>
99+
{flowData.getNode(flowRecord.nodeCode)?.name}
100+
</ProDescriptions.Item>
101+
</ProDescriptions>
102+
<div className="flowApprovalHistory-RecordLine">
103+
<Divider>
104+
<span className="Divider-title">流程历史</span>
105+
</Divider>
106+
<div className="record-line">
107+
<FlowHistoryLine flowData={flowData}/>
108+
</div>
109+
</div>
110+
</div>
14111
</>
15112
)
16113
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
.UserOutlined {
2+
padding: 10px;
3+
color: #fff;
4+
background: #1890ff;
5+
border-radius: 50%;
6+
font-size: 20px;
7+
}
8+
.ant-timeline .ant-timeline-item-content {
9+
margin-inline-start: 33px;
10+
}
11+
12+
.ant-timeline .ant-timeline-item {
13+
padding-bottom: 50px;
14+
}
15+
.ant-timeline .ant-timeline-item-tail {
16+
border-inline-start: 2px solid #ccc;
17+
}
18+
.title{
19+
font-size: 16px;
20+
font-weight: bold;
21+
}
22+
.opinion{
23+
display: flex;
24+
align-items: flex-start;
25+
font-size: 15px;
26+
&>div {
27+
&:nth-child(2) {
28+
width: 350px;
29+
}
30+
}
31+
}
32+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import React from "react";
2+
import {UserOutlined} from "@ant-design/icons";
3+
import {Timeline} from "antd";
4+
import moment from "moment";
5+
import {FlowData} from "@/components/Flow/flow/data";
6+
7+
interface FlowHistoryLineProps {
8+
flowData: FlowData
9+
}
10+
11+
const FlowHistoryLine: React.FC<FlowHistoryLineProps> = (props) => {
12+
const flowData = props.flowData;
13+
const timelineData = flowData.getHistoryRecords();
14+
const items = timelineData.map((item: any, index: any) => {
15+
return {
16+
dot: <UserOutlined className="UserOutlined" />,
17+
children: (
18+
<div>
19+
<div className="title">{flowData.getNode(item.nodeCode).name}</div>
20+
<div>
21+
<span>创建人:</span> <span>{item.currentOperator.name}</span>
22+
{item.opinion && (
23+
<span style={{ marginLeft: '10px' }}>
24+
({item.opinion.result == 1 ? '转办' : item.opinion.result == 2 ? '通过' : item.opinion.result == 3 ? '驳回' : '暂存'})
25+
</span>
26+
)}
27+
</div>
28+
<div><span>创建时间:</span> <span>{moment(item.createTime).format("YYYY-MM-DD HH:mm:ss")}</span>
29+
</div>
30+
<div className="opinion"><div>审批意见:</div> <div>{item.opinion?.advice || '暂无意见'}</div></div>
31+
</div>
32+
),
33+
key: index,
34+
}
35+
});
36+
37+
return (
38+
<div>
39+
<Timeline items={items} />
40+
</div>
41+
);
42+
}
43+
44+
export default FlowHistoryLine

admin-ui/src/components/Flow/flow/data.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,51 @@ export class FlowData extends FlowWorkData {
147147
}
148148
}
149149

150+
151+
getNodeState = (code:string)=>{
152+
const historyRecords = this.data.historyRecords || [];
153+
154+
const historyNodeCodes = historyRecords.map((record: any) => {
155+
return record.nodeCode;
156+
});
157+
158+
const currentNodeCode = this.data.flowNode.code;
159+
if(currentNodeCode === code) {
160+
return "current";
161+
}
162+
163+
if(historyNodeCodes.indexOf(code) !== -1) {
164+
return "done";
165+
}
166+
167+
return "wait";
168+
}
169+
170+
getFlowSchema = () => {
171+
172+
if(this.data.flowWork.schema) {
173+
const schema = JSON.parse(this.data.flowWork.schema);
174+
175+
for(const node of schema.nodes) {
176+
node.properties.settingVisible = false;
177+
node.properties.state = this.getNodeState(node.properties.code);
178+
}
179+
return schema;
180+
}
181+
return null;
182+
}
183+
150184
hasData() {
151185
return !!this.data;
152186
}
153187

188+
getCurrentFlowRecord = () => {
189+
return this.data.flowRecord;
190+
}
191+
192+
getHistoryRecords = () => {
193+
return this.data.historyRecords;
194+
}
195+
154196
}
155197

admin-ui/src/components/Flow/nodes/Circulate/index.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,11 @@ $color: #61aa1f;
4040
right: 0;
4141
}
4242

43+
44+
.state {
45+
margin-right: 10px;
46+
font-size: 14px;
47+
position: absolute;
48+
right: 0;
49+
}
4350
}

0 commit comments

Comments
 (0)