Skip to content

Commit a441008

Browse files
authored
Merge pull request #80 from codingapi/dev
Dev
2 parents 0bd370f + 420ee51 commit a441008

File tree

150 files changed

+6488
-1575
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

150 files changed

+6488
-1575
lines changed

admin-ui/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
"@ant-design/icons": "^5.4.0",
77
"@ant-design/pro-components": "^2.7.19",
88
"@babel/standalone": "^7.25.6",
9+
"@dnd-kit/core": "^6.2.0",
10+
"@dnd-kit/sortable": "^9.0.0",
911
"@logicflow/core": "^2.0.5",
1012
"@logicflow/extension": "^2.0.9",
1113
"@reduxjs/toolkit": "^2.2.7",

admin-ui/src/api/flow.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,12 @@ export async function schema(body: any) {
3838

3939
// 流程控制
4040

41-
export async function detail(id:any) {
42-
return get('/api/query/flowRecord/detail', {id});
41+
export async function startFlow(body:any) {
42+
return post('/api/cmd/flowRecord/startFlow', body);
43+
}
44+
45+
export async function detail(id?:any,workCode?:any) {
46+
return get('/api/query/flowRecord/detail', {id,workCode});
4347
}
4448

4549
export async function saveFlow(body:any) {
@@ -50,6 +54,14 @@ export async function submitFlow(body:any) {
5054
return post('/api/cmd/flowRecord/submitFlow', body);
5155
}
5256

57+
export async function trySubmitFlow(body:any) {
58+
return post('/api/cmd/flowRecord/trySubmitFlow', body);
59+
}
60+
61+
export async function custom(body:any) {
62+
return post('/api/cmd/flowRecord/custom', body);
63+
}
64+
5365
export async function recall(body:any) {
5466
return post('/api/cmd/flowRecord/recall', body);
5567
}

admin-ui/src/api/user.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {page, post} from "@/api/index";
1+
import {page, post,get} from "@/api/index";
22

33
export async function list(
44
params: any,
@@ -12,6 +12,10 @@ export async function list(
1212
return page('/api/query/user/list', params, sort, filter, match);
1313
}
1414

15+
export async function users() {
16+
return get('/api/query/user/list', {current:1,pageSize:999999});
17+
}
18+
1519

1620
export async function save(body: any) {
1721
return post('/api/cmd/user/save', body);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React from "react";
2+
import {ModalForm, ProFormDigit} from "@ant-design/pro-components";
3+
import {PostponedFormProps} from "@/components/Flow/flow/types";
4+
5+
6+
const PostponedFormView:React.FC<PostponedFormProps> = (props)=>{
7+
8+
return (
9+
<ModalForm
10+
title={"延期调整"}
11+
open={props.visible}
12+
modalProps={{
13+
onCancel: () => {
14+
props.setVisible(false);
15+
},
16+
onClose: () => {
17+
props.setVisible(false);
18+
},
19+
destroyOnClose:true,
20+
}}
21+
onFinish={async (values) => {
22+
props.onFinish(values);
23+
}}
24+
>
25+
<ProFormDigit
26+
name={"hours"}
27+
label={"延期时间"}
28+
tooltip={"以当前时间开始延期,延期单位为小时"}
29+
addonAfter={"小时"}
30+
rules={[
31+
{
32+
required: true,
33+
message: "请输入延期时间"
34+
}
35+
]}
36+
/>
37+
</ModalForm>
38+
)
39+
}
40+
41+
export default PostponedFormView;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import React from 'react';
2+
import {Modal, Result} from "antd";
3+
import {ProDescriptions} from "@ant-design/pro-components";
4+
import {FlowResultItem, ResultFormProps} from "@/components/Flow/flow/types";
5+
6+
7+
const ResultFormView: React.FC<ResultFormProps> = (props) => {
8+
const {result} = props;
9+
10+
if (!result) {
11+
return null;
12+
}
13+
14+
const resultStateTag = ()=>{
15+
const resultState = result.resultState;
16+
if(resultState === "SUCCESS") {
17+
return "success"
18+
}
19+
if(resultState === "WARNING") {
20+
return "warning"
21+
}
22+
return "info";
23+
};
24+
25+
26+
return (
27+
<Modal
28+
width={"40%"}
29+
height={"60%"}
30+
open={props.visible}
31+
onCancel={() => {
32+
props.setVisible(false);
33+
if (props.flowCloseable) {
34+
props.closeFlow();
35+
}
36+
}}
37+
onClose={() => {
38+
props.setVisible(false);
39+
if (props.flowCloseable) {
40+
props.closeFlow();
41+
}
42+
}}
43+
onOk={() => {
44+
props.setVisible(false);
45+
if (props.flowCloseable) {
46+
props.closeFlow();
47+
}
48+
}}
49+
destroyOnClose={true}
50+
>
51+
52+
<Result
53+
status={resultStateTag()}
54+
title={result.title}
55+
>
56+
{result.items && result.items.map((item: FlowResultItem, index: number) => {
57+
return (
58+
<ProDescriptions
59+
column={2}
60+
>
61+
<ProDescriptions.Item
62+
span={2}
63+
label={item.label}
64+
valueType="text"
65+
>
66+
{item.value}
67+
</ProDescriptions.Item>
68+
</ProDescriptions>
69+
)
70+
})}
71+
</Result>
72+
</Modal>
73+
)
74+
}
75+
76+
export default ResultFormView;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import React, {useEffect} from "react";
2+
import {UserSelectProps} from "@/components/Flow/flow/types";
3+
import {ModalForm, ProForm, ProFormSelect} from "@ant-design/pro-components";
4+
import {users} from "@/api/user";
5+
6+
7+
const UserSelectView: React.FC<UserSelectProps> = (props) => {
8+
9+
const [form] = ProForm.useForm();
10+
11+
const [userList, setUserList] = React.useState<any[]>([]);
12+
13+
useEffect(() => {
14+
users().then((res) => {
15+
if (res.success) {
16+
const list = res.data.list.filter((item:any)=>{
17+
const specifyUserIds = props.specifyUserIds;
18+
if(specifyUserIds && specifyUserIds.length > 0){
19+
return specifyUserIds.includes(item.id);
20+
}
21+
});
22+
setUserList(list);
23+
// 默认选中当前用户
24+
form.setFieldValue("users", props.currentUserIds);
25+
}
26+
})
27+
}, []);
28+
29+
return (
30+
<ModalForm
31+
form={form}
32+
open={props.visible}
33+
title={"用户选择(模拟测试)"}
34+
modalProps={{
35+
onCancel: () => {
36+
props.setVisible(false);
37+
},
38+
onClose: () => {
39+
props.setVisible(false);
40+
}
41+
}}
42+
onFinish={async (values) => {
43+
const users = values.users;
44+
const selectedUsers = userList.filter((item: any) => {
45+
return users.includes(item.id);
46+
});
47+
props.onFinish(selectedUsers);
48+
props.setVisible(false);
49+
}}
50+
>
51+
<ProFormSelect
52+
mode={"tags"}
53+
name={"users"}
54+
label={"用户"}
55+
options={userList.map((item: any) => {
56+
return {
57+
label: item.name,
58+
value: item.id
59+
}
60+
})}
61+
/>
62+
</ModalForm>
63+
)
64+
}
65+
66+
export default UserSelectView;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import React from "react";
2+
import {FlowData} from "@/components/Flow/flow/data";
3+
import {Button, Space} from "antd";
4+
5+
6+
interface FlowButtonsProps {
7+
flowData: FlowData;
8+
requestLoading: boolean;
9+
setRequestLoading: (loading: boolean) => void;
10+
handlerClick: (item: any) => void;
11+
}
12+
13+
const FlowButtons: React.FC<FlowButtonsProps> = (props) => {
14+
const flowData = props.flowData;
15+
16+
if (!flowData ) {
17+
return null;
18+
}
19+
20+
if(flowData.hasData() && flowData.isDone()){
21+
return null;
22+
}
23+
24+
const buttons = flowData.getNodeButtons();
25+
26+
return (
27+
<Space>
28+
{buttons && buttons.map((item: any) => {
29+
const style = item.style && {
30+
...JSON.parse(item.style),
31+
color: "white",
32+
} || {};
33+
return (
34+
<Button
35+
key={item.id}
36+
onClick={() => {
37+
props.handlerClick(item);
38+
}}
39+
loading={props.requestLoading}
40+
style={{
41+
...style
42+
}}
43+
>
44+
{item.name}
45+
</Button>
46+
)
47+
})}
48+
</Space>
49+
)
50+
}
51+
52+
export default FlowButtons;
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+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import React, {useEffect, useRef} from "react";
2+
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";
12+
13+
interface FlowChartProps {
14+
flowData: FlowData
15+
}
16+
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+
useEffect(() => {
25+
const SilentConfig = {
26+
isSilentMode: true,
27+
stopScrollGraph: false,
28+
stopMoveGraph: false,
29+
stopZoomGraph: false,
30+
edgeTextEdit: false,
31+
};
32+
33+
//@ts-ignore
34+
lfRef.current = new LogicFlow({
35+
//@ts-ignore
36+
container: container.current,
37+
...SilentConfig,
38+
background: {
39+
backgroundColor: '#f3f5f8'
40+
},
41+
plugins: [Menu, DndPanel, MiniMap, Snapshot],
42+
grid: false,
43+
edgeType: 'bezier',
44+
});
45+
46+
lfRef.current.setTheme({
47+
bezier: {
48+
stroke: '#8f94e3',
49+
strokeWidth: 1,
50+
},
51+
});
52+
lfRef.current.register(Start);
53+
lfRef.current.register(Node);
54+
lfRef.current.register(Over);
55+
lfRef.current.register(Circulate);
56+
57+
lfRef.current.render(flowData.getFlowSchema());
58+
}, []);
59+
60+
return (
61+
<>
62+
<div className="flow-chart-content">
63+
<div className={"flow-view"} ref={container}/>
64+
</div>
65+
</>
66+
)
67+
}
68+
69+
export default FlowChart;

0 commit comments

Comments
 (0)