@jiangood/open-admin-flowable 2.0.1 → 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
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {Button, Popconfirm, Space} from "antd";
|
|
1
|
+
import {Button, message, Popconfirm, Space} from "antd";
|
|
2
2
|
import {HttpUtils, PageUtils, ProTable} from "@jiangood/open-admin";
|
|
3
3
|
import React from "react";
|
|
4
|
+
import {MONITOR_PROCESS_INSTANCE_CLOSE, MONITOR_INSTANCE_PAGE} from "@/constants/api";
|
|
5
|
+
import {ROUTE_MONITOR_INSTANCE_VIEW} from "@/constants/routes";
|
|
4
6
|
|
|
5
7
|
export default class extends React.Component {
|
|
6
8
|
|
|
@@ -52,7 +54,7 @@ export default class extends React.Component {
|
|
|
52
54
|
fixed: 'right',
|
|
53
55
|
render: (_, r) => {
|
|
54
56
|
return <Space>
|
|
55
|
-
<Button size='small' onClick={() => PageUtils.open('
|
|
57
|
+
<Button size='small' onClick={() => PageUtils.open(ROUTE_MONITOR_INSTANCE_VIEW + '?id=' + r.id, '查看流程')}>查看</Button>
|
|
56
58
|
<Popconfirm title={'关闭流程'}
|
|
57
59
|
onConfirm={() => this.close(r.id)}>
|
|
58
60
|
<Button size='small' >终止</Button>
|
|
@@ -63,8 +65,10 @@ export default class extends React.Component {
|
|
|
63
65
|
]
|
|
64
66
|
|
|
65
67
|
close = (id) => {
|
|
66
|
-
HttpUtils.get(
|
|
68
|
+
HttpUtils.get(MONITOR_PROCESS_INSTANCE_CLOSE, {id}).then((rs) => {
|
|
67
69
|
this.tableRef.current.reload()
|
|
70
|
+
}).catch(e => {
|
|
71
|
+
message.error(e?.message || '关闭流程失败');
|
|
68
72
|
})
|
|
69
73
|
}
|
|
70
74
|
|
|
@@ -74,7 +78,7 @@ export default class extends React.Component {
|
|
|
74
78
|
return <ProTable
|
|
75
79
|
actionRef={this.tableRef}
|
|
76
80
|
columns={this.columns}
|
|
77
|
-
request={(params) => HttpUtils.get(
|
|
81
|
+
request={(params) => HttpUtils.get(MONITOR_INSTANCE_PAGE, params)}
|
|
78
82
|
>
|
|
79
83
|
|
|
80
84
|
</ProTable>
|
|
@@ -1,102 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {Gap, HttpUtils, Page, PageUtils, ProTable} from "@jiangood/open-admin";
|
|
3
|
-
import {Card, Empty, Skeleton, Table} from "antd";
|
|
4
|
-
|
|
5
|
-
export default class extends React.Component {
|
|
6
|
-
state = {
|
|
7
|
-
instanceCommentList: [],
|
|
8
|
-
vars: {},
|
|
9
|
-
|
|
10
|
-
id: null,
|
|
11
|
-
starter: null,
|
|
12
|
-
startTime: null,
|
|
13
|
-
name: null,
|
|
14
|
-
|
|
15
|
-
data: {
|
|
16
|
-
commentList: [],
|
|
17
|
-
img: null
|
|
18
|
-
},
|
|
19
|
-
loading: true,
|
|
20
|
-
|
|
21
|
-
errorMsg: null
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
componentDidMount() {
|
|
26
|
-
const {businessKey, id} = PageUtils.currentParams()
|
|
27
|
-
|
|
28
|
-
HttpUtils.get("admin/flowable/user-task/getInstanceInfo", {id, businessKey}).then(rs => {
|
|
29
|
-
this.setState(rs)
|
|
30
|
-
this.setState({data: rs})
|
|
31
|
-
}).catch(e => {
|
|
32
|
-
this.setState({errorMsg: e})
|
|
33
|
-
}).finally(() => {
|
|
34
|
-
this.setState({loading: false})
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
render() {
|
|
41
|
-
|
|
42
|
-
if (this.state.errorMsg) {
|
|
43
|
-
return <Empty description={this.state.errorMsg}></Empty>
|
|
44
|
-
}
|
|
45
|
-
const {id} = PageUtils.currentParams()
|
|
46
|
-
|
|
47
|
-
const {data, loading} = this.state
|
|
48
|
-
const {commentList, img} = data
|
|
49
|
-
if (loading) {
|
|
50
|
-
return <Skeleton/>
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return <Page padding>
|
|
55
|
-
<Card title='流程图'>
|
|
56
|
-
<img src={img} style={{maxWidth: '100%'}}/>
|
|
57
|
-
</Card>
|
|
58
|
-
<Gap/>
|
|
59
|
-
<Card title='审批记录'>
|
|
60
|
-
<Table dataSource={commentList}
|
|
61
|
-
size='small'
|
|
62
|
-
pagination={false}
|
|
63
|
-
rowKey='id'
|
|
64
|
-
columns={[
|
|
65
|
-
{
|
|
66
|
-
dataIndex: 'content',
|
|
67
|
-
title: '操作'
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
dataIndex: 'user',
|
|
71
|
-
title: '处理人'
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
dataIndex: 'time',
|
|
75
|
-
title: '处理时间'
|
|
76
|
-
},
|
|
77
|
-
]}
|
|
78
|
-
/>
|
|
79
|
-
</Card>
|
|
80
|
-
|
|
81
|
-
<Gap/>
|
|
82
|
-
<Card title='流程变量'>
|
|
83
|
-
<ProTable columns={[
|
|
84
|
-
{
|
|
85
|
-
dataIndex: 'key',
|
|
86
|
-
title: '变量名'
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
dataIndex: 'value',
|
|
90
|
-
title: '变量值'
|
|
91
|
-
},
|
|
92
|
-
]}
|
|
93
|
-
rowKey='key'
|
|
94
|
-
request={() => HttpUtils.get('admin/flowable/monitor/instance/vars', {id})}
|
|
95
|
-
></ProTable>
|
|
96
|
-
|
|
97
|
-
</Card>
|
|
98
|
-
</Page>
|
|
99
|
-
}
|
|
100
|
-
|
|
1
|
+
import InstanceView from "@/components/InstanceView";
|
|
101
2
|
|
|
3
|
+
export default function MonitorInstanceView() {
|
|
4
|
+
return <InstanceView showVariables />;
|
|
102
5
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {FieldUserSelect, HttpUtils, Page, ProTable} from "@jiangood/open-admin";
|
|
2
|
-
import {Button, Form, Modal} from "antd";
|
|
2
|
+
import {Button, Form, message, Modal} from "antd";
|
|
3
3
|
import React from "react";
|
|
4
|
+
import {MONITOR_SET_ASSIGNEE, MONITOR_TASK} from "@/constants/api";
|
|
4
5
|
|
|
5
6
|
export default class extends React.Component {
|
|
6
7
|
|
|
@@ -18,9 +19,11 @@ export default class extends React.Component {
|
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
submitSetAssignee = values => {
|
|
21
|
-
HttpUtils.post(
|
|
22
|
+
HttpUtils.post(MONITOR_SET_ASSIGNEE,values).then(()=>{
|
|
22
23
|
this.setState({assigneeFormOpen:false})
|
|
23
24
|
this.taskTableRef.current.reload()
|
|
25
|
+
}).catch(e => {
|
|
26
|
+
message.error(e?.message || '指定处理人失败');
|
|
24
27
|
})
|
|
25
28
|
};
|
|
26
29
|
render() {
|
|
@@ -72,7 +75,7 @@ export default class extends React.Component {
|
|
|
72
75
|
}
|
|
73
76
|
}
|
|
74
77
|
]}
|
|
75
|
-
request={(params) => HttpUtils.get(
|
|
78
|
+
request={(params) => HttpUtils.get(MONITOR_TASK, params)}
|
|
76
79
|
>
|
|
77
80
|
<Form.Item label='受理人' name='assignee'>
|
|
78
81
|
<FieldUserSelect />
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {Button, Empty, Space, Spin, Table, Tag} from "antd";
|
|
3
|
+
import {HistoryOutlined, ReloadOutlined} from "@ant-design/icons";
|
|
4
|
+
|
|
5
|
+
export default class FinishedPhase extends React.Component {
|
|
6
|
+
render() {
|
|
7
|
+
const {historyList, historyLoading,
|
|
8
|
+
onReset, onViewHistory, onDeleteHistory} = this.props;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<div>
|
|
12
|
+
<Space style={{marginBottom: 16}}>
|
|
13
|
+
<Button icon={<HistoryOutlined/>} onClick={onReset}>历史记录</Button>
|
|
14
|
+
<Button icon={<ReloadOutlined/>} onClick={onReset}>重新仿真</Button>
|
|
15
|
+
</Space>
|
|
16
|
+
|
|
17
|
+
{historyLoading ? <Spin style={{display: 'block', margin: '80px auto'}}/> : (
|
|
18
|
+
historyList.length === 0 ? (
|
|
19
|
+
<Empty description="暂无仿真记录" image={Empty.PRESENTED_IMAGE_SIMPLE}/>
|
|
20
|
+
) : (
|
|
21
|
+
<Table dataSource={historyList}
|
|
22
|
+
size="small" pagination={false} rowKey="instanceId"
|
|
23
|
+
columns={[
|
|
24
|
+
{
|
|
25
|
+
title: '实例', dataIndex: 'name', ellipsis: true,
|
|
26
|
+
render: (text, record) => (
|
|
27
|
+
<a onClick={() => onViewHistory(record.instanceId)}>{text}</a>
|
|
28
|
+
),
|
|
29
|
+
},
|
|
30
|
+
{title: '发起人', dataIndex: 'starter', width: 80},
|
|
31
|
+
{
|
|
32
|
+
title: '状态', dataIndex: 'finished', width: 80,
|
|
33
|
+
render: (finished, record) => finished ? (
|
|
34
|
+
record.deleteReason ? (
|
|
35
|
+
<Tag color="error">已终止</Tag>
|
|
36
|
+
) : (
|
|
37
|
+
<Tag color="success">已完成</Tag>
|
|
38
|
+
)
|
|
39
|
+
) : (
|
|
40
|
+
<Tag color="processing">运行中</Tag>
|
|
41
|
+
),
|
|
42
|
+
},
|
|
43
|
+
{title: '发起时间', dataIndex: 'startTime', width: 100},
|
|
44
|
+
{
|
|
45
|
+
title: '操作', width: 60,
|
|
46
|
+
render: (_, record) => (
|
|
47
|
+
<Button type="link" danger size="small"
|
|
48
|
+
onClick={() => onDeleteHistory(record.instanceId)}>
|
|
49
|
+
删除
|
|
50
|
+
</Button>
|
|
51
|
+
),
|
|
52
|
+
},
|
|
53
|
+
]}/>
|
|
54
|
+
)
|
|
55
|
+
)}
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {Button, Form, Input, Select, Splitter} from "antd";
|
|
3
|
+
import {StringUtils} from "@jiangood/open-admin";
|
|
4
|
+
import {PlayCircleOutlined} from "@ant-design/icons";
|
|
5
|
+
import HistoryListPanel from "@/components/flowable/HistoryListPanel";
|
|
6
|
+
|
|
7
|
+
export default class InitPhase extends React.Component {
|
|
8
|
+
render() {
|
|
9
|
+
const {model, users, submitting, historyList, historyLoading,
|
|
10
|
+
onStart, onLoadUsers, onViewHistory, onDeleteHistory} = this.props;
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<Splitter>
|
|
14
|
+
<Splitter.Panel defaultSize="55%">
|
|
15
|
+
<Form onFinish={onStart} layout="vertical">
|
|
16
|
+
<Form.Item name="key" noStyle initialValue={model.key}/>
|
|
17
|
+
|
|
18
|
+
<Form.Item label="业务标识" name="id"
|
|
19
|
+
rules={[{required: true, message: '请输入业务标识'}]}
|
|
20
|
+
initialValue={StringUtils.random(16)}>
|
|
21
|
+
<Input/>
|
|
22
|
+
</Form.Item>
|
|
23
|
+
|
|
24
|
+
<Form.Item label="发起人" name="initiatorId"
|
|
25
|
+
rules={[{required: true, message: '请选择发起人'}]}>
|
|
26
|
+
<Select showSearch placeholder="搜索并选择用户"
|
|
27
|
+
filterOption={false}
|
|
28
|
+
onSearch={onLoadUsers}
|
|
29
|
+
options={users.map(u => ({label: u.name, value: u.id}))}
|
|
30
|
+
style={{width: 300}}/>
|
|
31
|
+
</Form.Item>
|
|
32
|
+
|
|
33
|
+
{model.variables?.map(item => (
|
|
34
|
+
<Form.Item key={item.name} name={['variables', item.name]} label={item.label}>
|
|
35
|
+
<Input/>
|
|
36
|
+
</Form.Item>
|
|
37
|
+
))}
|
|
38
|
+
|
|
39
|
+
<Form.Item>
|
|
40
|
+
<Button type="primary" htmlType="submit" icon={<PlayCircleOutlined/>}
|
|
41
|
+
loading={submitting}>
|
|
42
|
+
启动仿真
|
|
43
|
+
</Button>
|
|
44
|
+
</Form.Item>
|
|
45
|
+
</Form>
|
|
46
|
+
</Splitter.Panel>
|
|
47
|
+
<Splitter.Panel defaultSize="45%">
|
|
48
|
+
<HistoryListPanel list={historyList} loading={historyLoading}
|
|
49
|
+
onView={onViewHistory} onDelete={onDeleteHistory}/>
|
|
50
|
+
</Splitter.Panel>
|
|
51
|
+
</Splitter>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {Button, Card, Empty, Input, Select, Space, Splitter, Table, Tag, Typography} from "antd";
|
|
3
|
+
import {CheckCircleOutlined, CloseCircleOutlined} from "@ant-design/icons";
|
|
4
|
+
import ProcessImageViewer from "@/components/ProcessImageViewer";
|
|
5
|
+
|
|
6
|
+
export default class RunningPhase extends React.Component {
|
|
7
|
+
render() {
|
|
8
|
+
const {status, submitting, taskFormValues, users, onLoadUsers,
|
|
9
|
+
onAssigneeChange, onCommentChange, onTask} = this.props;
|
|
10
|
+
const {img, commentList, tasks, finished, deleteReason} = status;
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<Splitter>
|
|
14
|
+
<Splitter.Panel defaultSize="60%">
|
|
15
|
+
<div style={{paddingRight: 16}}>
|
|
16
|
+
<Typography.Title level={5}>流程图</Typography.Title>
|
|
17
|
+
<ProcessImageViewer imageUrl={img}/>
|
|
18
|
+
<div style={{marginTop: 16}}>
|
|
19
|
+
<Typography.Title level={5}>处理记录</Typography.Title>
|
|
20
|
+
<Table dataSource={commentList || []}
|
|
21
|
+
size="small" pagination={false} rowKey="time"
|
|
22
|
+
columns={[
|
|
23
|
+
{dataIndex: 'content', title: '操作'},
|
|
24
|
+
{dataIndex: 'user', title: '处理人', width: 120},
|
|
25
|
+
{dataIndex: 'time', title: '处理时间', width: 160},
|
|
26
|
+
]}/>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
</Splitter.Panel>
|
|
30
|
+
<Splitter.Panel defaultSize="40%">
|
|
31
|
+
<div style={{paddingLeft: 16}}>
|
|
32
|
+
<Space style={{marginBottom: 12}}>
|
|
33
|
+
<Typography.Text strong>实例名称:</Typography.Text>
|
|
34
|
+
<Typography.Text>{status.name}</Typography.Text>
|
|
35
|
+
</Space>
|
|
36
|
+
<br/>
|
|
37
|
+
<Space style={{marginBottom: 12}}>
|
|
38
|
+
<Typography.Text strong>业务标识:</Typography.Text>
|
|
39
|
+
<Typography.Text>{status.businessKey}</Typography.Text>
|
|
40
|
+
</Space>
|
|
41
|
+
<br/>
|
|
42
|
+
<Space style={{marginBottom: 12}}>
|
|
43
|
+
<Typography.Text strong>发起人:</Typography.Text>
|
|
44
|
+
<Typography.Text>{status.starter}</Typography.Text>
|
|
45
|
+
</Space>
|
|
46
|
+
<br/>
|
|
47
|
+
<Space style={{marginBottom: 12}}>
|
|
48
|
+
<Typography.Text strong>发起时间:</Typography.Text>
|
|
49
|
+
<Typography.Text>{status.startTime}</Typography.Text>
|
|
50
|
+
</Space>
|
|
51
|
+
<br/>
|
|
52
|
+
<Space style={{marginBottom: 16}}>
|
|
53
|
+
<Typography.Text strong>状态:</Typography.Text>
|
|
54
|
+
{finished ? (
|
|
55
|
+
deleteReason ? (
|
|
56
|
+
<Tag icon={<CloseCircleOutlined/>} color="error">已终止</Tag>
|
|
57
|
+
) : (
|
|
58
|
+
<Tag icon={<CheckCircleOutlined/>} color="success">已完成</Tag>
|
|
59
|
+
)
|
|
60
|
+
) : (
|
|
61
|
+
<Tag color="processing">运行中</Tag>
|
|
62
|
+
)}
|
|
63
|
+
</Space>
|
|
64
|
+
|
|
65
|
+
{finished && deleteReason && (
|
|
66
|
+
<Card size="small" title="终止原因" style={{marginBottom: 16}}>
|
|
67
|
+
<Typography.Text type="secondary">{deleteReason}</Typography.Text>
|
|
68
|
+
</Card>
|
|
69
|
+
)}
|
|
70
|
+
|
|
71
|
+
{!finished && tasks?.map(task => (
|
|
72
|
+
<Card key={task.taskId} size="small" title={task.taskName}
|
|
73
|
+
style={{marginBottom: 12}}>
|
|
74
|
+
<Space direction="vertical" style={{width: '100%'}}>
|
|
75
|
+
<div>
|
|
76
|
+
<Typography.Text strong>处理人:</Typography.Text>
|
|
77
|
+
<Select showSearch placeholder="选择处理人"
|
|
78
|
+
value={(taskFormValues[task.taskId] || {}).assignee}
|
|
79
|
+
style={{width: '100%'}}
|
|
80
|
+
filterOption={false}
|
|
81
|
+
onSearch={onLoadUsers}
|
|
82
|
+
onChange={value => onAssigneeChange(task.taskId, value)}
|
|
83
|
+
options={users.map(u => ({label: u.name, value: u.id}))}/>
|
|
84
|
+
</div>
|
|
85
|
+
<div>
|
|
86
|
+
<Typography.Text strong>审批意见:</Typography.Text>
|
|
87
|
+
<Input.TextArea rows={2}
|
|
88
|
+
value={(taskFormValues[task.taskId] || {}).comment}
|
|
89
|
+
onChange={e => onCommentChange(task.taskId, e)}/>
|
|
90
|
+
</div>
|
|
91
|
+
<Space>
|
|
92
|
+
<Button type="primary"
|
|
93
|
+
icon={<CheckCircleOutlined/>}
|
|
94
|
+
loading={submitting}
|
|
95
|
+
onClick={() => onTask(task.taskId, 'APPROVE')}>
|
|
96
|
+
同意
|
|
97
|
+
</Button>
|
|
98
|
+
<Button danger
|
|
99
|
+
icon={<CloseCircleOutlined/>}
|
|
100
|
+
loading={submitting}
|
|
101
|
+
onClick={() => onTask(task.taskId, 'REJECT')}>
|
|
102
|
+
不同意
|
|
103
|
+
</Button>
|
|
104
|
+
</Space>
|
|
105
|
+
</Space>
|
|
106
|
+
</Card>
|
|
107
|
+
))}
|
|
108
|
+
|
|
109
|
+
{!finished && (!tasks || tasks.length === 0) && (
|
|
110
|
+
<Empty description="暂无活跃任务"/>
|
|
111
|
+
)}
|
|
112
|
+
</div>
|
|
113
|
+
</Splitter.Panel>
|
|
114
|
+
</Splitter>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
}
|