@jiangood/open-admin-flowable 2.0.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +20 -20
- package/src/components/InstanceView.jsx +86 -0
- package/src/components/ProcessImageViewer.jsx +21 -0
- package/src/components/flowable/HistoryListPanel.jsx +49 -0
- package/src/components/flowable/done-table.jsx +31 -0
- package/src/components/flowable/my-table.jsx +34 -0
- package/src/components/flowable/todo-table.jsx +28 -0
- package/src/constants/api.js +39 -0
- package/src/constants/routes.js +8 -0
- package/src/pages/flowable/design/index.jsx +38 -13
- package/src/pages/flowable/design/provider/properties/AssignmentSection.jsx +4 -3
- package/src/pages/flowable/design/provider/properties/ConditionDesign.jsx +2 -3
- package/src/pages/flowable/design/provider/properties/DelegateExpressionProps.jsx +2 -1
- package/src/pages/flowable/design/provider/properties/FormProps.jsx +2 -1
- package/src/pages/flowable/index.jsx +8 -7
- package/src/pages/flowable/monitor/{definition.jsx → definition/index.jsx} +2 -1
- package/src/pages/flowable/monitor/instance/index.jsx +8 -4
- package/src/pages/flowable/monitor/instance/view.jsx +3 -100
- package/src/pages/flowable/monitor/{task.jsx → task/index.jsx} +6 -3
- package/src/pages/flowable/simulate/FinishedPhase.jsx +59 -0
- package/src/pages/flowable/simulate/InitPhase.jsx +54 -0
- package/src/pages/flowable/simulate/RunningPhase.jsx +117 -0
- package/src/pages/flowable/simulate/index.jsx +59 -243
- package/src/pages/flowable/user-task/form.jsx +12 -36
- package/src/pages/flowable/user-task/index.jsx +11 -169
- package/src/pages/flowable/user-task/instance/view.jsx +3 -83
package/package.json
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"devDependencies": {
|
|
3
|
-
"@types/react": "^19.2.
|
|
4
|
-
"@types/react-dom": "^19.
|
|
3
|
+
"@types/react": "^19.2.17",
|
|
4
|
+
"@types/react-dom": "^19.2.3",
|
|
5
5
|
"@types/react-lazylog": "^4.5.1",
|
|
6
|
-
"@umijs/plugins": "^4.
|
|
6
|
+
"@umijs/plugins": "^4.6.63",
|
|
7
7
|
"@umijs/types": "^3.5.43",
|
|
8
|
-
"typescript": "^5.
|
|
8
|
+
"typescript": "^5.9.3"
|
|
9
9
|
},
|
|
10
10
|
"peerDependencies": {
|
|
11
|
-
"@ant-design/icons": "^6.
|
|
12
|
-
"@jiangood/open-admin": "^2.
|
|
13
|
-
"@tinymce/tinymce-react": "^6.
|
|
14
|
-
"antd": "^6.
|
|
15
|
-
"antd-img-crop": "^4.
|
|
16
|
-
"axios": "^1.
|
|
17
|
-
"bpmn-js": "^18.
|
|
18
|
-
"dayjs": "^1.11.
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"react": "^19.
|
|
23
|
-
"
|
|
24
|
-
"umi": "^4.0.0"
|
|
11
|
+
"@ant-design/icons": "^6.2.5",
|
|
12
|
+
"@jiangood/open-admin": "^2.4.1",
|
|
13
|
+
"@tinymce/tinymce-react": "^6.3.0",
|
|
14
|
+
"antd": "^6.4.4",
|
|
15
|
+
"antd-img-crop": "^4.30.0",
|
|
16
|
+
"axios": "^1.18.0",
|
|
17
|
+
"bpmn-js": "^18.17.1",
|
|
18
|
+
"dayjs": "^1.11.21",
|
|
19
|
+
"lodash": "^4.18.1",
|
|
20
|
+
"qs": "^6.15.2",
|
|
21
|
+
"react": "^19.2.7",
|
|
22
|
+
"react-dom": "^19.2.7",
|
|
23
|
+
"umi": "^4.6.61"
|
|
25
24
|
},
|
|
26
25
|
"name": "@jiangood/open-admin-flowable",
|
|
27
26
|
"files": [
|
|
28
27
|
"src/*",
|
|
29
28
|
"!src/.umi",
|
|
30
29
|
"!src/layout",
|
|
31
|
-
"!src/forms"
|
|
30
|
+
"!src/forms",
|
|
31
|
+
"!src/pages/example"
|
|
32
32
|
],
|
|
33
33
|
"main": "src/index.ts",
|
|
34
34
|
"scripts": {
|
|
35
35
|
"dev": "umi dev"
|
|
36
36
|
},
|
|
37
|
-
"version": "2.0
|
|
37
|
+
"version": "2.1.0"
|
|
38
38
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {Gap, HttpUtils, Page, PageUtils, ProTable} from "@jiangood/open-admin";
|
|
3
|
+
import {Card, Empty, Skeleton, Table} from "antd";
|
|
4
|
+
import {USER_TASK_GET_INSTANCE_INFO, MONITOR_INSTANCE_VARS} from "@/constants/api";
|
|
5
|
+
|
|
6
|
+
export default class extends React.Component {
|
|
7
|
+
state = {
|
|
8
|
+
commentList: [],
|
|
9
|
+
vars: {},
|
|
10
|
+
id: null,
|
|
11
|
+
starter: null,
|
|
12
|
+
startTime: null,
|
|
13
|
+
name: null,
|
|
14
|
+
img: null,
|
|
15
|
+
loading: true,
|
|
16
|
+
errorMsg: null,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
componentDidMount() {
|
|
20
|
+
const params = PageUtils.currentParams();
|
|
21
|
+
const { id, businessKey } = params;
|
|
22
|
+
|
|
23
|
+
const reqParams = {id};
|
|
24
|
+
if (businessKey) reqParams.businessKey = businessKey;
|
|
25
|
+
HttpUtils.get(USER_TASK_GET_INSTANCE_INFO, reqParams).then(rs => {
|
|
26
|
+
this.setState(rs)
|
|
27
|
+
this.setState({
|
|
28
|
+
commentList: rs.commentList,
|
|
29
|
+
img: rs.img,
|
|
30
|
+
id: rs.id,
|
|
31
|
+
})
|
|
32
|
+
}).catch(e => {
|
|
33
|
+
this.setState({errorMsg: e})
|
|
34
|
+
}).finally(() => {
|
|
35
|
+
this.setState({loading: false})
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
getCommentColumns() {
|
|
40
|
+
return [
|
|
41
|
+
{dataIndex: 'content', title: '操作'},
|
|
42
|
+
{dataIndex: 'user', title: '处理人'},
|
|
43
|
+
{dataIndex: 'time', title: '处理时间'},
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
render() {
|
|
48
|
+
if (this.state.errorMsg) {
|
|
49
|
+
return <Empty description={this.state.errorMsg}></Empty>
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const {commentList, img, loading, id} = this.state
|
|
53
|
+
if (loading) {
|
|
54
|
+
return <Skeleton/>
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<Page padding>
|
|
59
|
+
<Card title='流程图'>
|
|
60
|
+
<img src={img} style={{maxWidth: '100%'}}/>
|
|
61
|
+
</Card>
|
|
62
|
+
<Gap/>
|
|
63
|
+
<Card title='审批记录'>
|
|
64
|
+
<Table dataSource={commentList}
|
|
65
|
+
size='small'
|
|
66
|
+
pagination={false}
|
|
67
|
+
rowKey='id'
|
|
68
|
+
columns={this.getCommentColumns()}
|
|
69
|
+
/>
|
|
70
|
+
</Card>
|
|
71
|
+
<Gap/>
|
|
72
|
+
{this.props.showVariables && (
|
|
73
|
+
<Card title='流程变量'>
|
|
74
|
+
<ProTable columns={[
|
|
75
|
+
{dataIndex: 'key', title: '变量名'},
|
|
76
|
+
{dataIndex: 'value', title: '变量值'},
|
|
77
|
+
]}
|
|
78
|
+
rowKey='key'
|
|
79
|
+
request={() => HttpUtils.get(MONITOR_INSTANCE_VARS, {id})}
|
|
80
|
+
/>
|
|
81
|
+
</Card>
|
|
82
|
+
)}
|
|
83
|
+
</Page>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Modal } from "antd";
|
|
2
|
+
|
|
3
|
+
export default function ProcessImageViewer({ imageUrl }) {
|
|
4
|
+
const show = () => {
|
|
5
|
+
Modal.info({
|
|
6
|
+
title: '流程图',
|
|
7
|
+
width: '70vw',
|
|
8
|
+
content: (
|
|
9
|
+
<div style={{ width: '100%', overflow: 'auto', maxHeight: '80vh' }}>
|
|
10
|
+
<img src={imageUrl} style={{ maxWidth: '100%' }} />
|
|
11
|
+
</div>
|
|
12
|
+
),
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div onClick={show} style={{ cursor: 'pointer', border: '1px solid #d9d9d9', borderRadius: 8, padding: 8, background: '#fafafa' }}>
|
|
18
|
+
<img src={imageUrl} style={{ maxWidth: '100%', maxHeight: 200, display: 'block', margin: '0 auto' }} />
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {Button, Empty, Spin, Table, Tag, Typography} from "antd";
|
|
2
|
+
import {HistoryOutlined} from "@ant-design/icons";
|
|
3
|
+
|
|
4
|
+
export default function HistoryListPanel({list, loading, onView, onDelete}) {
|
|
5
|
+
return (
|
|
6
|
+
<div style={{paddingLeft: 16}}>
|
|
7
|
+
<Typography.Title level={5}>
|
|
8
|
+
<HistoryOutlined/> 仿真历史
|
|
9
|
+
</Typography.Title>
|
|
10
|
+
{loading ? <Spin/> : list.length === 0 ? (
|
|
11
|
+
<Empty description="暂无仿真记录" image={Empty.PRESENTED_IMAGE_SIMPLE}/>
|
|
12
|
+
) : (
|
|
13
|
+
<Table dataSource={list}
|
|
14
|
+
size="small" pagination={false} rowKey="instanceId"
|
|
15
|
+
columns={[
|
|
16
|
+
{
|
|
17
|
+
title: '实例', dataIndex: 'name', ellipsis: true,
|
|
18
|
+
render: (text, record) => (
|
|
19
|
+
<a onClick={() => onView(record.instanceId)}>{text}</a>
|
|
20
|
+
),
|
|
21
|
+
},
|
|
22
|
+
{title: '发起人', dataIndex: 'starter', width: 80},
|
|
23
|
+
{
|
|
24
|
+
title: '状态', dataIndex: 'finished', width: 80,
|
|
25
|
+
render: (finished, record) => finished ? (
|
|
26
|
+
record.deleteReason ? (
|
|
27
|
+
<Tag color="error">已终止</Tag>
|
|
28
|
+
) : (
|
|
29
|
+
<Tag color="success">已完成</Tag>
|
|
30
|
+
)
|
|
31
|
+
) : (
|
|
32
|
+
<Tag color="processing">运行中</Tag>
|
|
33
|
+
),
|
|
34
|
+
},
|
|
35
|
+
{title: '发起时间', dataIndex: 'startTime', width: 100},
|
|
36
|
+
{
|
|
37
|
+
title: '操作', width: 60,
|
|
38
|
+
render: (_, record) => (
|
|
39
|
+
<Button type="link" danger size="small"
|
|
40
|
+
onClick={() => onDelete(record.instanceId)}>
|
|
41
|
+
删除
|
|
42
|
+
</Button>
|
|
43
|
+
),
|
|
44
|
+
},
|
|
45
|
+
]}/>
|
|
46
|
+
)}
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {Button} from "antd";
|
|
2
|
+
import {HttpUtils, PageUtils, ProTable} from "@jiangood/open-admin";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import {USER_TASK_DONE_PAGE} from "@/constants/api";
|
|
5
|
+
import {ROUTE_USER_INSTANCE_VIEW} from "@/constants/routes";
|
|
6
|
+
|
|
7
|
+
const columns = [
|
|
8
|
+
{title: '流程名称', dataIndex: 'instanceName'},
|
|
9
|
+
{title: '发起人', dataIndex: 'instanceStarter'},
|
|
10
|
+
{title: '发起时间', dataIndex: 'instanceStartTime'},
|
|
11
|
+
{title: '任务创建时间', dataIndex: 'createTime'},
|
|
12
|
+
{title: '处理时间', dataIndex: 'endTime'},
|
|
13
|
+
{title: '耗时', dataIndex: 'durationInfo'},
|
|
14
|
+
{title: '处理节点', dataIndex: 'taskName'},
|
|
15
|
+
{title: '操作人', dataIndex: 'assigneeInfo'},
|
|
16
|
+
{
|
|
17
|
+
title: '操作', dataIndex: 'option',
|
|
18
|
+
render: (_, record) => (
|
|
19
|
+
<Button size='small' onClick={() => PageUtils.open(ROUTE_USER_INSTANCE_VIEW + '?id=' + record.instanceId, '流程信息')}>查看</Button>
|
|
20
|
+
),
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
export default function DoneTable() {
|
|
25
|
+
return <ProTable
|
|
26
|
+
showToolbarSearch={false}
|
|
27
|
+
request={(params) => HttpUtils.get(USER_TASK_DONE_PAGE, params)}
|
|
28
|
+
columns={columns}
|
|
29
|
+
size='small'
|
|
30
|
+
/>;
|
|
31
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {Button} from "antd";
|
|
2
|
+
import {HttpUtils, PageUtils, ProTable} from "@jiangood/open-admin";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import {USER_TASK_MY_INSTANCE} from "@/constants/api";
|
|
5
|
+
import {ROUTE_USER_INSTANCE_VIEW} from "@/constants/routes";
|
|
6
|
+
|
|
7
|
+
const columns = [
|
|
8
|
+
{
|
|
9
|
+
title: '流程名称', dataIndex: 'processDefinitionName',
|
|
10
|
+
render(_, r) { return r.name || r.processDefinitionName; }
|
|
11
|
+
},
|
|
12
|
+
{title: '发起人', dataIndex: 'startUserName'},
|
|
13
|
+
{title: '发起时间', dataIndex: 'startTime'},
|
|
14
|
+
{title: '业务标识', dataIndex: 'businessKey'},
|
|
15
|
+
{title: '结束时间', dataIndex: 'endTime'},
|
|
16
|
+
{
|
|
17
|
+
title: '流程状态', dataIndex: 'x',
|
|
18
|
+
render(_, row) { return row.endTime == null ? '进行中' : '已结束'; }
|
|
19
|
+
},
|
|
20
|
+
{title: '终止原因', dataIndex: 'deleteReason'},
|
|
21
|
+
{
|
|
22
|
+
title: '操作', dataIndex: 'option',
|
|
23
|
+
render: (_, record) => (
|
|
24
|
+
<Button size='small' onClick={() => PageUtils.open(ROUTE_USER_INSTANCE_VIEW + '?id=' + record.id, '流程信息')}>查看</Button>
|
|
25
|
+
),
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
export default function MyTable() {
|
|
30
|
+
return <ProTable
|
|
31
|
+
request={(params) => HttpUtils.get(USER_TASK_MY_INSTANCE, params)}
|
|
32
|
+
columns={columns}
|
|
33
|
+
/>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {HttpUtils, LinkButton, ProTable} from "@jiangood/open-admin";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import {USER_TASK_TODO_PAGE} from "@/constants/api";
|
|
4
|
+
|
|
5
|
+
const columns = [
|
|
6
|
+
{title: '发起人', dataIndex: 'instanceStarter'},
|
|
7
|
+
{title: '流程名称', dataIndex: 'instanceName'},
|
|
8
|
+
{title: '当前节点', dataIndex: 'taskName', width: 100},
|
|
9
|
+
{title: '当前操作人', dataIndex: 'assigneeInfo', width: 100},
|
|
10
|
+
{title: '发起时间', dataIndex: 'instanceStartTime'},
|
|
11
|
+
{title: '任务创建时间', dataIndex: 'createTime'},
|
|
12
|
+
{
|
|
13
|
+
title: '操作', dataIndex: 'option',
|
|
14
|
+
render: (_, record) => {
|
|
15
|
+
let path = '/flowable/user-task/form?taskId=' + record.id;
|
|
16
|
+
return <LinkButton type='primary' path={path} label='处理任务'>处理</LinkButton>;
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export default function TodoTable() {
|
|
22
|
+
return <ProTable
|
|
23
|
+
showToolbarSearch={false}
|
|
24
|
+
request={(params) => HttpUtils.get(USER_TASK_TODO_PAGE, params)}
|
|
25
|
+
columns={columns}
|
|
26
|
+
size='small'
|
|
27
|
+
/>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export const MODEL_PAGE = 'admin/flowable/model/page'
|
|
2
|
+
export const MODEL_DETAIL = 'admin/flowable/model/detail'
|
|
3
|
+
export const MODEL_SAVE_CONTENT = 'admin/flowable/model/saveContent'
|
|
4
|
+
export const MODEL_DEPLOY = 'admin/flowable/model/deploy'
|
|
5
|
+
export const MODEL_DELETE = 'admin/flowable/model/delete'
|
|
6
|
+
export const MODEL_GET_DEFINITION_CONTENT = 'admin/flowable/model/getDefinitionContent'
|
|
7
|
+
export const MODEL_DEFINITION_PAGE = 'admin/flowable/model/definitionPage'
|
|
8
|
+
export const MODEL_FORM_OPTIONS = 'admin/flowable/model/formOptions'
|
|
9
|
+
export const MODEL_JAVA_DELEGATE_OPTIONS = 'admin/flowable/model/javaDelegateOptions'
|
|
10
|
+
export const MODEL_VAR_LIST = 'admin/flowable/model/varList'
|
|
11
|
+
export const MODEL_ASSIGNEE_OPTIONS = 'admin/flowable/model/assigneeOptions'
|
|
12
|
+
export const MODEL_CANDIDATE_GROUPS_OPTIONS = 'admin/flowable/model/candidateGroupsOptions'
|
|
13
|
+
export const MODEL_CANDIDATE_USERS_OPTIONS = 'admin/flowable/model/candidateUsersOptions'
|
|
14
|
+
|
|
15
|
+
export const SIMULATE_GET = 'admin/flowable/simulate/get'
|
|
16
|
+
export const SIMULATE_USERS = 'admin/flowable/simulate/users'
|
|
17
|
+
export const SIMULATE_LIST = 'admin/flowable/simulate/list'
|
|
18
|
+
export const SIMULATE_START = 'admin/flowable/simulate/start'
|
|
19
|
+
export const SIMULATE_STATUS = 'admin/flowable/simulate/status'
|
|
20
|
+
export const SIMULATE_TASK_HANDLE = 'admin/flowable/simulate/task/handle'
|
|
21
|
+
export const SIMULATE_DELETE = 'admin/flowable/simulate/delete'
|
|
22
|
+
|
|
23
|
+
export const USER_TASK_TODO_PAGE = 'admin/flowable/user-task/todoTaskPage'
|
|
24
|
+
export const USER_TASK_DONE_PAGE = 'admin/flowable/user-task/doneTaskPage'
|
|
25
|
+
export const USER_TASK_MY_INSTANCE = 'admin/flowable/user-task/myInstance'
|
|
26
|
+
export const USER_TASK_GET_INSTANCE_INFO = 'admin/flowable/user-task/getInstanceInfo'
|
|
27
|
+
export const USER_TASK_GET_INSTANCE_INFO_BY_TASK_ID = 'admin/flowable/user-task/getInstanceInfoByTaskId'
|
|
28
|
+
export const USER_TASK_HANDLE_TASK = 'admin/flowable/user-task/handleTask'
|
|
29
|
+
|
|
30
|
+
export const MONITOR_PROCESS_INSTANCE_CLOSE = 'admin/flowable/monitor/processInstance/close'
|
|
31
|
+
export const MONITOR_INSTANCE_PAGE = 'admin/flowable/monitor/instancePage'
|
|
32
|
+
export const MONITOR_SET_ASSIGNEE = 'admin/flowable/monitor/setAssignee'
|
|
33
|
+
export const MONITOR_TASK = 'admin/flowable/monitor/task'
|
|
34
|
+
export const MONITOR_DEFINITION_PAGE = 'admin/flowable/monitor/definitionPage'
|
|
35
|
+
export const MONITOR_INSTANCE_VARS = 'admin/flowable/monitor/instance/vars'
|
|
36
|
+
|
|
37
|
+
export const EXAMPLE_LEAVE_LIST = 'admin/flowable/example/leave/list'
|
|
38
|
+
export const EXAMPLE_LEAVE_DETAIL = 'admin/flowable/example/leave/detail'
|
|
39
|
+
export const EXAMPLE_LEAVE_START = 'admin/flowable/example/leave/start'
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const ROUTE_DESIGN = '/flowable/design'
|
|
2
|
+
export const ROUTE_SIMULATE = '/flowable/simulate'
|
|
3
|
+
export const ROUTE_TASK_FORM = '/flowable/user-task/form'
|
|
4
|
+
export const ROUTE_USER_INSTANCE_VIEW = '/flowable/user-task/instance/view'
|
|
5
|
+
export const ROUTE_MONITOR_TASK = '/flowable/monitor/task'
|
|
6
|
+
export const ROUTE_MONITOR_INSTANCE = '/flowable/monitor/instance'
|
|
7
|
+
export const ROUTE_MONITOR_DEFINITION = '/flowable/monitor/definition'
|
|
8
|
+
export const ROUTE_MONITOR_INSTANCE_VIEW = '/flowable/monitor/instance/view'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { createRef } from "react";
|
|
2
2
|
import {Button, Card, message, Modal, Space, Splitter} from "antd";
|
|
3
3
|
|
|
4
4
|
import 'bpmn-js/dist/assets/diagram-js.css'
|
|
@@ -8,8 +8,10 @@ import BpmnModeler from 'bpmn-js/lib/Modeler'
|
|
|
8
8
|
import './index.css'
|
|
9
9
|
import customTranslate from "./customTranslate/customTranslate";
|
|
10
10
|
import contextPad from "./contextPad";
|
|
11
|
-
import {CloudUploadOutlined, SaveOutlined} from "@ant-design/icons";
|
|
11
|
+
import {CloudUploadOutlined, DownloadOutlined, SaveOutlined, UploadOutlined} from "@ant-design/icons";
|
|
12
12
|
import {HttpUtils, PageLoading, PageUtils, ProTable} from "@jiangood/open-admin";
|
|
13
|
+
import {MODEL_DETAIL, MODEL_SAVE_CONTENT, MODEL_DEPLOY, MODEL_GET_DEFINITION_CONTENT, MODEL_DEFINITION_PAGE} from "@/constants/api";
|
|
14
|
+
import {ROUTE_SIMULATE} from "@/constants/routes";
|
|
13
15
|
import 'bpmn-js/dist/assets/bpmn-js.css';
|
|
14
16
|
import flowableJson from './descriptors/flowable';
|
|
15
17
|
import PropertiesPanel from './PropertiesPanel';
|
|
@@ -25,11 +27,12 @@ export default class extends React.Component {
|
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
bpmRef = React.createRef()
|
|
30
|
+
fileRef = createRef()
|
|
28
31
|
|
|
29
32
|
|
|
30
33
|
async componentDidMount() {
|
|
31
34
|
const params = PageUtils.currentParams()
|
|
32
|
-
const rs = await HttpUtils.get(
|
|
35
|
+
const rs = await HttpUtils.get(MODEL_DETAIL, {id: params.id})
|
|
33
36
|
this.setState({model: rs, id: params.id}, this.initBpmn)
|
|
34
37
|
}
|
|
35
38
|
|
|
@@ -56,10 +59,30 @@ export default class extends React.Component {
|
|
|
56
59
|
};
|
|
57
60
|
|
|
58
61
|
|
|
59
|
-
|
|
60
|
-
this.bpmnModeler.saveXML({format: true})
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
handleExportXML = async () => {
|
|
63
|
+
const res = await this.bpmnModeler.saveXML({format: true});
|
|
64
|
+
const blob = new Blob([res.xml], {type: 'application/xml'});
|
|
65
|
+
const url = URL.createObjectURL(blob);
|
|
66
|
+
const a = document.createElement('a');
|
|
67
|
+
a.href = url;
|
|
68
|
+
a.download = `${this.state.model.key}.bpmn20.xml`;
|
|
69
|
+
a.click();
|
|
70
|
+
URL.revokeObjectURL(url);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
handleImportXML = () => {
|
|
74
|
+
this.fileRef.current.click();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
handleFileChange = (e) => {
|
|
78
|
+
const file = e.target.files[0];
|
|
79
|
+
if (!file) return;
|
|
80
|
+
const reader = new FileReader();
|
|
81
|
+
reader.onload = (evt) => {
|
|
82
|
+
this.bpmnModeler.importXML(evt.target.result);
|
|
83
|
+
};
|
|
84
|
+
reader.readAsText(file);
|
|
85
|
+
e.target.value = '';
|
|
63
86
|
}
|
|
64
87
|
|
|
65
88
|
|
|
@@ -68,7 +91,7 @@ export default class extends React.Component {
|
|
|
68
91
|
const hide = message.loading('正在保存...', 0)
|
|
69
92
|
try {
|
|
70
93
|
const res = await this.bpmnModeler.saveXML();
|
|
71
|
-
await HttpUtils.post(
|
|
94
|
+
await HttpUtils.post(MODEL_SAVE_CONTENT, {id, content: res.xml});
|
|
72
95
|
} finally {
|
|
73
96
|
hide()
|
|
74
97
|
}
|
|
@@ -79,7 +102,7 @@ export default class extends React.Component {
|
|
|
79
102
|
const hide = message.loading('正在部署...', 0)
|
|
80
103
|
try {
|
|
81
104
|
const res = await this.bpmnModeler.saveXML();
|
|
82
|
-
await HttpUtils.post(
|
|
105
|
+
await HttpUtils.post(MODEL_DEPLOY, {id, content: res.xml});
|
|
83
106
|
} finally {
|
|
84
107
|
hide()
|
|
85
108
|
}
|
|
@@ -95,9 +118,10 @@ export default class extends React.Component {
|
|
|
95
118
|
<Button type='primary' icon={<SaveOutlined/>} onClick={this.handleSave}>暂存</Button>
|
|
96
119
|
<Button type='primary' danger icon={<CloudUploadOutlined/>}
|
|
97
120
|
onClick={this.handleDeploy}>部署</Button>
|
|
98
|
-
<Button onClick={this.
|
|
121
|
+
<Button icon={<DownloadOutlined/>} onClick={this.handleExportXML}>导出XML</Button>
|
|
122
|
+
<Button icon={<UploadOutlined/>} onClick={this.handleImportXML}>导入XML</Button>
|
|
99
123
|
<Button
|
|
100
|
-
onClick={() => PageUtils.open('
|
|
124
|
+
onClick={() => PageUtils.open(ROUTE_SIMULATE + '?id=' + this.state.id, "流程仿真")}> 仿真 </Button>
|
|
101
125
|
|
|
102
126
|
<Button title='查看已部署的历史版本' onClick={() => {
|
|
103
127
|
this.setState({deployedModal: true})
|
|
@@ -115,6 +139,7 @@ export default class extends React.Component {
|
|
|
115
139
|
</Splitter.Panel>
|
|
116
140
|
</Splitter>
|
|
117
141
|
|
|
142
|
+
<input ref={this.fileRef} type="file" accept=".xml" style={{display: 'none'}} onChange={this.handleFileChange}/>
|
|
118
143
|
|
|
119
144
|
<Modal title='已部署版本' width={800} footer={null}
|
|
120
145
|
open={this.state.deployedModal}
|
|
@@ -139,7 +164,7 @@ export default class extends React.Component {
|
|
|
139
164
|
dataIndex:'id',
|
|
140
165
|
render:(_, record)=> {
|
|
141
166
|
return <Button type='primary' onClick={()=>{
|
|
142
|
-
HttpUtils.get(
|
|
167
|
+
HttpUtils.get(MODEL_GET_DEFINITION_CONTENT,{id: record.id}).then(xml=>{
|
|
143
168
|
this.bpmnModeler.importXML(xml)
|
|
144
169
|
this.setState({deployedModal:false})
|
|
145
170
|
})
|
|
@@ -149,7 +174,7 @@ export default class extends React.Component {
|
|
|
149
174
|
]}
|
|
150
175
|
request={params => {
|
|
151
176
|
params.key = this.state.model.key
|
|
152
|
-
return HttpUtils.get(
|
|
177
|
+
return HttpUtils.get(MODEL_DEFINITION_PAGE, params)
|
|
153
178
|
}}>
|
|
154
179
|
|
|
155
180
|
</ProTable>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {Form, Radio} from "antd";
|
|
2
2
|
import {FieldRemoteSelect, FieldRemoteSelectMultipleInline, StringUtils} from "@jiangood/open-admin";
|
|
3
3
|
import React from "react";
|
|
4
|
+
import {MODEL_ASSIGNEE_OPTIONS, MODEL_CANDIDATE_GROUPS_OPTIONS, MODEL_CANDIDATE_USERS_OPTIONS} from "@/constants/api";
|
|
4
5
|
|
|
5
6
|
export default function AssignmentSection(props) {
|
|
6
7
|
const {element, modeling} = props
|
|
@@ -56,17 +57,17 @@ export default function AssignmentSection(props) {
|
|
|
56
57
|
}}>
|
|
57
58
|
{mode === 'assignee' && (
|
|
58
59
|
<Form.Item label="办理人" name='assignee'>
|
|
59
|
-
<FieldRemoteSelect url=
|
|
60
|
+
<FieldRemoteSelect url={MODEL_ASSIGNEE_OPTIONS}/>
|
|
60
61
|
</Form.Item>
|
|
61
62
|
)}
|
|
62
63
|
{mode === 'candidateGroups' && (
|
|
63
64
|
<Form.Item label="候选组" name='candidateGroups'>
|
|
64
|
-
<FieldRemoteSelect url=
|
|
65
|
+
<FieldRemoteSelect url={MODEL_CANDIDATE_GROUPS_OPTIONS}/>
|
|
65
66
|
</Form.Item>
|
|
66
67
|
)}
|
|
67
68
|
{mode === 'candidateUsers' && (
|
|
68
69
|
<Form.Item label="候选人" name='candidateUsers'>
|
|
69
|
-
<FieldRemoteSelectMultipleInline url=
|
|
70
|
+
<FieldRemoteSelectMultipleInline url={MODEL_CANDIDATE_USERS_OPTIONS}/>
|
|
70
71
|
</Form.Item>
|
|
71
72
|
)}
|
|
72
73
|
</Form>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {Button, Input, InputNumber, Modal, Select} from "antd";
|
|
2
2
|
import {Component} from "react";
|
|
3
3
|
import {FieldBoolean, FieldTable, HttpUtils, ObjectUtils, StringUtils, ThemeUtils} from "@jiangood/open-admin";
|
|
4
|
+
import {MODEL_VAR_LIST} from "@/constants/api";
|
|
4
5
|
import {ConditionExpressionUtils} from "./ConditionExpressionUtils";
|
|
5
6
|
|
|
6
7
|
|
|
@@ -132,9 +133,7 @@ export class ConditionDesignButton extends Component {
|
|
|
132
133
|
|
|
133
134
|
componentDidMount() {
|
|
134
135
|
const {processId} = this.props;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
HttpUtils.get('admin/flowable/model/varList', {code: processId}).then(rs => {
|
|
136
|
+
HttpUtils.get(MODEL_VAR_LIST, {code: processId}).then(rs => {
|
|
138
137
|
const options = rs.map(r => {
|
|
139
138
|
return {
|
|
140
139
|
label: r.label,
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {Select} from 'antd';
|
|
2
2
|
import {useEffect, useState} from 'react';
|
|
3
3
|
import {HttpUtils} from "@jiangood/open-admin";
|
|
4
|
+
import {MODEL_JAVA_DELEGATE_OPTIONS} from "@/constants/api";
|
|
4
5
|
|
|
5
6
|
export default function DelegateExpressionField({element, modeling}) {
|
|
6
7
|
const [options, setOptions] = useState([]);
|
|
7
8
|
|
|
8
9
|
useEffect(() => {
|
|
9
|
-
HttpUtils.get(
|
|
10
|
+
HttpUtils.get(MODEL_JAVA_DELEGATE_OPTIONS).then(rs => {
|
|
10
11
|
setOptions((rs || []).map(o => typeof o === 'string' ? {label: o, value: o} : o));
|
|
11
12
|
});
|
|
12
13
|
}, []);
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {Select} from 'antd';
|
|
2
2
|
import {useEffect, useState} from 'react';
|
|
3
3
|
import {HttpUtils} from "@jiangood/open-admin";
|
|
4
|
+
import {MODEL_FORM_OPTIONS} from "@/constants/api";
|
|
4
5
|
|
|
5
6
|
export default function FormField({element, modeling, processId}) {
|
|
6
7
|
const [options, setOptions] = useState([]);
|
|
7
8
|
|
|
8
9
|
useEffect(() => {
|
|
9
|
-
HttpUtils.get(
|
|
10
|
+
HttpUtils.get(MODEL_FORM_OPTIONS, {code: processId}).then(rs => {
|
|
10
11
|
setOptions((rs || []).map(o => typeof o === 'string' ? {label: o, value: o} : o));
|
|
11
12
|
});
|
|
12
13
|
}, [processId]);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {Button, Popconfirm, Space} from 'antd';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import {ButtonList, HttpUtils, Page, PageUtils, ProTable} from "@jiangood/open-admin";
|
|
4
|
+
import {MODEL_PAGE, MODEL_DELETE} from "@/constants/api";
|
|
5
|
+
import {ROUTE_DESIGN, ROUTE_MONITOR_TASK, ROUTE_MONITOR_INSTANCE, ROUTE_MONITOR_DEFINITION} from "@/constants/routes";
|
|
4
6
|
|
|
5
7
|
export default class extends React.Component {
|
|
6
8
|
|
|
@@ -35,7 +37,7 @@ export default class extends React.Component {
|
|
|
35
37
|
render: (_, record) => (
|
|
36
38
|
<Space>
|
|
37
39
|
<Button size='small' type='primary'
|
|
38
|
-
onClick={() => PageUtils.open('
|
|
40
|
+
onClick={() => PageUtils.open(ROUTE_DESIGN + '?id=' + record.id, '流程设计' + record.name)}> 设计 </Button>
|
|
39
41
|
<Popconfirm perm='flowable/model:delete' title={'是否确定删除流程模型'}
|
|
40
42
|
onConfirm={() => this.handleDelete(record)}>
|
|
41
43
|
<Button size='small' danger>删除</Button>
|
|
@@ -47,7 +49,7 @@ export default class extends React.Component {
|
|
|
47
49
|
|
|
48
50
|
|
|
49
51
|
handleDelete = row => {
|
|
50
|
-
HttpUtils.post(
|
|
52
|
+
HttpUtils.post(MODEL_DELETE, {id: row.id}).then(rs => {
|
|
51
53
|
this.actionRef.current.reload();
|
|
52
54
|
})
|
|
53
55
|
}
|
|
@@ -58,18 +60,18 @@ export default class extends React.Component {
|
|
|
58
60
|
return <Page padding>
|
|
59
61
|
<ProTable
|
|
60
62
|
actionRef={this.actionRef}
|
|
61
|
-
request={(params) => HttpUtils.get(
|
|
63
|
+
request={(params) => HttpUtils.get(MODEL_PAGE, params)}
|
|
62
64
|
columns={this.columns}
|
|
63
65
|
showToolbarSearch={true}
|
|
64
66
|
toolBarRender={() => {
|
|
65
67
|
return <ButtonList>
|
|
66
|
-
<Button onClick={() => PageUtils.open(
|
|
68
|
+
<Button onClick={() => PageUtils.open(ROUTE_MONITOR_TASK, "运行中的任务")}>
|
|
67
69
|
运行中的任务
|
|
68
70
|
</Button>
|
|
69
|
-
<Button onClick={() => PageUtils.open(
|
|
71
|
+
<Button onClick={() => PageUtils.open(ROUTE_MONITOR_INSTANCE, "运行中的流程实例")}>
|
|
70
72
|
运行中的流程实例
|
|
71
73
|
</Button>
|
|
72
|
-
<Button onClick={() => PageUtils.open(
|
|
74
|
+
<Button onClick={() => PageUtils.open(ROUTE_MONITOR_DEFINITION, "已部署的流程定义")}>
|
|
73
75
|
已部署的流程定义
|
|
74
76
|
</Button>
|
|
75
77
|
</ButtonList>
|
|
@@ -84,4 +86,3 @@ export default class extends React.Component {
|
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
|
|
87
|
-
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import {HttpUtils, ProTable} from "@jiangood/open-admin";
|
|
3
|
+
import {MONITOR_DEFINITION_PAGE} from "@/constants/api";
|
|
3
4
|
|
|
4
5
|
export default class extends React.Component {
|
|
5
6
|
|
|
@@ -79,7 +80,7 @@ export default class extends React.Component {
|
|
|
79
80
|
return <ProTable
|
|
80
81
|
search={false}
|
|
81
82
|
columns={this.columns}
|
|
82
|
-
request={(params) => HttpUtils.get(
|
|
83
|
+
request={(params) => HttpUtils.get(MONITOR_DEFINITION_PAGE, params)}
|
|
83
84
|
>
|
|
84
85
|
|
|
85
86
|
</ProTable>
|