@jiangood/open-admin-flowable 2.2.2 → 2.2.3

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.
@@ -1,26 +1,372 @@
1
1
  import React from "react";
2
- import {Tabs} from "antd";
3
- import {Page, PageLoading} from "@jiangood/open-admin";
4
- import TodoTable from "../../../components/flowable/todo-table";
5
- import DoneTable from "../../../components/flowable/done-table";
6
- import MyTable from "../../../components/flowable/my-table";
2
+ import {Button, Card, Empty, Form, Input, message, Modal, Radio, Skeleton, Spin, Splitter, Table, Tabs, Typography} from "antd";
3
+ import {FormRegistryUtils, Gap, HttpUtils, Page, PageLoading, PageUtils, ProTable} from "@jiangood/open-admin";
4
+
5
+ function TodoTable({onProcess}) {
6
+ const columns = [
7
+ {title: '发起人', dataIndex: 'instanceStarter'},
8
+ {title: '流程名称', dataIndex: 'instanceName'},
9
+ {title: '当前节点', dataIndex: 'taskName', width: 100},
10
+ {title: '当前操作人', dataIndex: 'assigneeInfo', width: 100},
11
+ {title: '发起时间', dataIndex: 'instanceStartTime'},
12
+ {title: '任务创建时间', dataIndex: 'createTime'},
13
+ {
14
+ title: '操作', dataIndex: 'option',
15
+ render: (_, record) => (
16
+ <Button size='small' type='primary' onClick={() => onProcess(record)}>处理</Button>
17
+ ),
18
+ },
19
+ ];
20
+ return <ProTable
21
+ showToolbarSearch={false}
22
+ request={(params) => HttpUtils.get('admin/flowable/user-task/todoTaskPage', params)}
23
+ columns={columns}
24
+ size='small'
25
+ />;
26
+ }
27
+
28
+ function DoneTable({onView}) {
29
+ const columns = [
30
+ {title: '流程名称', dataIndex: 'instanceName'},
31
+ {title: '发起人', dataIndex: 'instanceStarter'},
32
+ {title: '发起时间', dataIndex: 'instanceStartTime'},
33
+ {title: '任务创建时间', dataIndex: 'createTime'},
34
+ {title: '处理时间', dataIndex: 'endTime'},
35
+ {title: '耗时', dataIndex: 'durationInfo'},
36
+ {title: '处理节点', dataIndex: 'taskName'},
37
+ {title: '操作人', dataIndex: 'assigneeInfo'},
38
+ {
39
+ title: '操作', dataIndex: 'option',
40
+ render: (_, record) => (
41
+ <Button size='small' onClick={() => onView(record)}>查看</Button>
42
+ ),
43
+ },
44
+ ];
45
+ return <ProTable
46
+ showToolbarSearch={false}
47
+ request={(params) => HttpUtils.get('admin/flowable/user-task/doneTaskPage', params)}
48
+ columns={columns}
49
+ size='small'
50
+ />;
51
+ }
52
+
53
+ function MyTable({onView}) {
54
+ const columns = [
55
+ {
56
+ title: '流程名称', dataIndex: 'processDefinitionName',
57
+ render(_, r) { return r.name || r.processDefinitionName; }
58
+ },
59
+ {title: '发起人', dataIndex: 'startUserName'},
60
+ {title: '发起时间', dataIndex: 'startTime'},
61
+ {title: '业务标识', dataIndex: 'businessKey'},
62
+ {title: '结束时间', dataIndex: 'endTime'},
63
+ {
64
+ title: '流程状态', dataIndex: 'x',
65
+ render(_, row) { return row.endTime == null ? '进行中' : '已结束'; }
66
+ },
67
+ {title: '终止原因', dataIndex: 'deleteReason'},
68
+ {
69
+ title: '操作', dataIndex: 'option',
70
+ render: (_, record) => (
71
+ <Button size='small' onClick={() => onView(record)}>查看</Button>
72
+ ),
73
+ },
74
+ ];
75
+ return <ProTable
76
+ request={(params) => HttpUtils.get('admin/flowable/user-task/myInstance', params)}
77
+ columns={columns}
78
+ />;
79
+ }
80
+
81
+ class FormModal extends React.Component {
82
+ state = {
83
+ submitLoading: false,
84
+ flowVisible: false,
85
+ formData: {},
86
+ instanceCommentList: [],
87
+ vars: {},
88
+ data: {taskId: null, commentList: [], img: null},
89
+ loading: true,
90
+ errorMsg: null,
91
+ }
92
+
93
+ componentDidMount() {
94
+ const taskId = this.props.taskId ?? PageUtils.currentParams()?.taskId
95
+ HttpUtils.get('admin/flowable/user-task/getInstanceInfoByTaskId', {taskId}).then(rs => {
96
+ this.setState({data: rs})
97
+ }).catch(e => {
98
+ if (e?.message?.includes('任务已被处理')) {
99
+ message.warning('此任务已被处理');
100
+ setTimeout(() => {
101
+ this.props.onClose?.();
102
+ if (!this.props.onClose) PageUtils.closeCurrent();
103
+ }, 1500);
104
+ } else {
105
+ message.error(e?.message || '获取任务信息失败');
106
+ }
107
+ this.setState({errorMsg: e})
108
+ }).finally(() => {
109
+ this.setState({loading: false})
110
+ })
111
+ }
112
+
113
+ handleTask = async value => {
114
+ this.setState({submitLoading: true});
115
+ try {
116
+ if (value.result === 'APPROVE') {
117
+ value.formData = this.state.formData
118
+ }
119
+ value.taskId = this.state.data.taskId
120
+ await HttpUtils.post('admin/flowable/user-task/handleTask', value)
121
+ this.props.onClose?.();
122
+ if (!this.props.onClose) PageUtils.closeCurrent()
123
+ } catch (error) {
124
+ message.error(error?.message || '操作失败')
125
+ } finally {
126
+ this.setState({submitLoading: false})
127
+ }
128
+ }
129
+
130
+ renderProcess = (commentList) => <Card title='处理记录'>
131
+ <Table dataSource={commentList}
132
+ size='small'
133
+ pagination={false}
134
+ rowKey='id'
135
+ columns={[
136
+ {dataIndex: 'content', title: '操作'},
137
+ {dataIndex: 'user', title: '处理人'},
138
+ {dataIndex: 'time', title: '处理时间'},
139
+ ]}
140
+ />
141
+ </Card>;
142
+
143
+ renderForm = () => {
144
+ const {data, formData} = this.state
145
+ const {businessKey} = data
146
+ const formKey = data.formKey;
147
+ const formName = data.formKey + 'Form'
148
+
149
+ let ExForm = FormRegistryUtils.get(formName);
150
+ if (!ExForm) {
151
+ console.error(" 表单不存在: " + formName + ",请检查表单源代码:src/forms/" + formName + ".jsx")
152
+ return <Empty description={"表单不存在: " + formName}></Empty>
153
+ }
154
+
155
+ return <ExForm id={businessKey} formKey={formKey} value={formData}
156
+ onChange={v => this.setState({formData: v})}></ExForm>
157
+ }
158
+
159
+ render() {
160
+ const {submitLoading} = this.state
161
+ const {data, loading} = this.state
162
+ const {commentList, img} = data
163
+ if (loading) {
164
+ return <Spin/>
165
+ }
166
+ const {flowVisible} = this.state;
167
+ const formContent = <>
168
+ <Splitter>
169
+ <Splitter.Panel>
170
+ <Typography.Title level={4}>{data.name}</Typography.Title>
171
+ <Typography.Text type="secondary">{data.starter} &nbsp;&nbsp; {data.startTime}</Typography.Text>
172
+ <Gap></Gap>
173
+ {this.renderForm()}
174
+ </Splitter.Panel>
175
+ <Splitter.Panel defaultSize={400}>
176
+ <Card title='审批意见'>
177
+ <Form layout='vertical' onFinish={this.handleTask} disabled={submitLoading}>
178
+ <Form.Item label='审批结果' name='result' rules={[{required: true, message: '请选择'}]}
179
+ initialValue={'APPROVE'}>
180
+ <Radio.Group>
181
+ <Radio value='APPROVE'>同意</Radio>
182
+ <Radio value='REJECT'>不同意</Radio>
183
+ </Radio.Group>
184
+ </Form.Item>
185
+ <Form.Item label='审批意见' name='comment'
186
+ rules={[{required: true, message: '请输入审批意见'}]}>
187
+ <Input.TextArea/>
188
+ </Form.Item>
189
+ <div style={{display: 'flex', gap: 8}}>
190
+ <Button type='primary' htmlType='submit' loading={submitLoading}
191
+ size={"middle"}>提交</Button>
192
+ <Button size="middle"
193
+ onClick={() => this.setState({flowVisible: true})}>流程图</Button>
194
+ </div>
195
+ </Form>
196
+ </Card>
197
+ <Gap></Gap>
198
+ {this.renderProcess(commentList)}
199
+ </Splitter.Panel>
200
+ </Splitter>
201
+ <Modal title="流程图" open={flowVisible}
202
+ onCancel={() => this.setState({flowVisible: false})}
203
+ footer={null} width="80vw">
204
+ <img src={img} style={{maxWidth: '100%'}}/>
205
+ </Modal>
206
+ </>;
207
+
208
+ if (this.props.embedded) return formContent;
209
+ return <Page padding>{formContent}</Page>
210
+ }
211
+ }
212
+
213
+ class ViewModal extends React.Component {
214
+ state = {
215
+ commentList: [],
216
+ vars: {},
217
+ id: null,
218
+ starter: null,
219
+ startTime: null,
220
+ name: null,
221
+ img: null,
222
+ loading: true,
223
+ errorMsg: null,
224
+ }
225
+
226
+ componentDidMount() {
227
+ const params = PageUtils.currentParams();
228
+ const id = this.props.id ?? params.id;
229
+ const businessKey = this.props.businessKey ?? params.businessKey;
230
+
231
+ const reqParams = {id};
232
+ if (businessKey) reqParams.businessKey = businessKey;
233
+ HttpUtils.get('admin/flowable/user-task/getInstanceInfo', reqParams).then(rs => {
234
+ this.setState(rs)
235
+ this.setState({
236
+ commentList: rs.commentList,
237
+ img: rs.img,
238
+ id: rs.id,
239
+ })
240
+ }).catch(e => {
241
+ this.setState({errorMsg: e})
242
+ }).finally(() => {
243
+ this.setState({loading: false})
244
+ })
245
+ }
246
+
247
+ getCommentColumns() {
248
+ return [
249
+ {dataIndex: 'content', title: '操作'},
250
+ {dataIndex: 'user', title: '处理人'},
251
+ {dataIndex: 'time', title: '处理时间'},
252
+ ];
253
+ }
254
+
255
+ render() {
256
+ if (this.state.errorMsg) {
257
+ return <Empty description={this.state.errorMsg}></Empty>
258
+ }
259
+
260
+ const {commentList, img, loading, id} = this.state
261
+ if (loading) {
262
+ return <Skeleton/>
263
+ }
264
+
265
+ const content = <>
266
+ <Card title='流程图'>
267
+ <img src={img} style={{maxWidth: '100%'}}/>
268
+ </Card>
269
+ <Gap/>
270
+ <Card title='审批记录'>
271
+ <Table dataSource={commentList}
272
+ size='small'
273
+ pagination={false}
274
+ rowKey='id'
275
+ columns={this.getCommentColumns()}
276
+ />
277
+ </Card>
278
+ <Gap/>
279
+ {this.props.showVariables && (
280
+ <Card title='流程变量'>
281
+ <ProTable columns={[
282
+ {dataIndex: 'key', title: '变量名'},
283
+ {dataIndex: 'value', title: '变量值'},
284
+ ]}
285
+ rowKey='key'
286
+ request={() => HttpUtils.get('admin/flowable/monitor/instance/vars', {id})}
287
+ />
288
+ </Card>
289
+ )}
290
+ </>;
291
+
292
+ if (this.props.embedded) return content;
293
+ return <Page padding>{content}</Page>
294
+ }
295
+ }
7
296
 
8
297
  export default class extends React.Component {
9
- state = { show: true }
298
+ state = {
299
+ show: true,
300
+ formModal: {visible: false, taskId: null},
301
+ viewModal: {visible: false, id: null, title: ''},
302
+ refreshKey: 0,
303
+ }
10
304
 
11
305
  render() {
12
306
  if (!this.state.show) {
13
307
  return <PageLoading/>
14
308
  }
15
309
 
310
+ const {formModal, viewModal} = this.state;
311
+
16
312
  const items = [
17
- {label: '待办任务', key: '1', children: <TodoTable/>},
18
- {label: '已办任务', key: '2', children: <DoneTable/>},
19
- {label: '我发起的', key: '3', children: <MyTable/>},
313
+ {
314
+ label: '待办任务', key: '1', children: <TodoTable
315
+ key={this.state.refreshKey}
316
+ onProcess={(record) => this.setState({formModal: {visible: true, taskId: record.id}})}
317
+ />
318
+ },
319
+ {
320
+ label: '已办任务', key: '2', children: <DoneTable
321
+ onView={(record) => this.setState({viewModal: {visible: true, id: record.instanceId, title: '流程信息'}})}
322
+ />
323
+ },
324
+ {
325
+ label: '我发起的', key: '3', children: <MyTable
326
+ onView={(record) => this.setState({viewModal: {visible: true, id: record.id, title: '流程信息'}})}
327
+ />
328
+ },
20
329
  ];
21
330
 
22
- return <Page padding>
23
- <Tabs defaultActiveKey="1" destroyOnHidden items={items}/>
24
- </Page>
331
+ return <>
332
+ <Page padding>
333
+ <Tabs defaultActiveKey="1" destroyOnHidden items={items}/>
334
+ </Page>
335
+ <Modal
336
+ title="处理任务"
337
+ open={formModal.visible}
338
+ onCancel={() => this.setState({formModal: {visible: false, taskId: null}})}
339
+ width="80vw"
340
+ footer={null}
341
+ destroyOnClose
342
+ maskClosable={false}
343
+ >
344
+ {formModal.taskId && (
345
+ <FormModal
346
+ taskId={formModal.taskId}
347
+ embedded
348
+ onClose={() => this.setState(prev => ({
349
+ formModal: {visible: false, taskId: null},
350
+ refreshKey: prev.refreshKey + 1,
351
+ }))}
352
+ />
353
+ )}
354
+ </Modal>
355
+ <Modal
356
+ title={viewModal.title}
357
+ open={viewModal.visible}
358
+ onCancel={() => this.setState({viewModal: {visible: false, id: null, title: ''}})}
359
+ width="80vw"
360
+ footer={null}
361
+ destroyOnClose
362
+ >
363
+ {viewModal.id && (
364
+ <ViewModal
365
+ id={viewModal.id}
366
+ embedded
367
+ />
368
+ )}
369
+ </Modal>
370
+ </>
25
371
  }
26
372
  }
@@ -1,84 +0,0 @@
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
- export default class extends React.Component {
5
- state = {
6
- commentList: [],
7
- vars: {},
8
- id: null,
9
- starter: null,
10
- startTime: null,
11
- name: null,
12
- img: null,
13
- loading: true,
14
- errorMsg: null,
15
- }
16
-
17
- componentDidMount() {
18
- const params = PageUtils.currentParams();
19
- const { id, businessKey } = params;
20
-
21
- const reqParams = {id};
22
- if (businessKey) reqParams.businessKey = businessKey;
23
- HttpUtils.get('admin/flowable/user-task/getInstanceInfo', reqParams).then(rs => {
24
- this.setState(rs)
25
- this.setState({
26
- commentList: rs.commentList,
27
- img: rs.img,
28
- id: rs.id,
29
- })
30
- }).catch(e => {
31
- this.setState({errorMsg: e})
32
- }).finally(() => {
33
- this.setState({loading: false})
34
- })
35
- }
36
-
37
- getCommentColumns() {
38
- return [
39
- {dataIndex: 'content', title: '操作'},
40
- {dataIndex: 'user', title: '处理人'},
41
- {dataIndex: 'time', title: '处理时间'},
42
- ];
43
- }
44
-
45
- render() {
46
- if (this.state.errorMsg) {
47
- return <Empty description={this.state.errorMsg}></Empty>
48
- }
49
-
50
- const {commentList, img, loading, id} = this.state
51
- if (loading) {
52
- return <Skeleton/>
53
- }
54
-
55
- return (
56
- <Page padding>
57
- <Card title='流程图'>
58
- <img src={img} style={{maxWidth: '100%'}}/>
59
- </Card>
60
- <Gap/>
61
- <Card title='审批记录'>
62
- <Table dataSource={commentList}
63
- size='small'
64
- pagination={false}
65
- rowKey='id'
66
- columns={this.getCommentColumns()}
67
- />
68
- </Card>
69
- <Gap/>
70
- {this.props.showVariables && (
71
- <Card title='流程变量'>
72
- <ProTable columns={[
73
- {dataIndex: 'key', title: '变量名'},
74
- {dataIndex: 'value', title: '变量值'},
75
- ]}
76
- rowKey='key'
77
- request={() => HttpUtils.get('admin/flowable/monitor/instance/vars', {id})}
78
- />
79
- </Card>
80
- )}
81
- </Page>
82
- )
83
- }
84
- }
@@ -1,29 +0,0 @@
1
- import {Button} from "antd";
2
- import {HttpUtils, PageUtils, ProTable} from "@jiangood/open-admin";
3
- import React from "react";
4
-
5
- const columns = [
6
- {title: '流程名称', dataIndex: 'instanceName'},
7
- {title: '发起人', dataIndex: 'instanceStarter'},
8
- {title: '发起时间', dataIndex: 'instanceStartTime'},
9
- {title: '任务创建时间', dataIndex: 'createTime'},
10
- {title: '处理时间', dataIndex: 'endTime'},
11
- {title: '耗时', dataIndex: 'durationInfo'},
12
- {title: '处理节点', dataIndex: 'taskName'},
13
- {title: '操作人', dataIndex: 'assigneeInfo'},
14
- {
15
- title: '操作', dataIndex: 'option',
16
- render: (_, record) => (
17
- <Button size='small' onClick={() => PageUtils.open('/flowable/user-task/instance/view' + '?id=' + record.instanceId, '流程信息')}>查看</Button>
18
- ),
19
- },
20
- ];
21
-
22
- export default function DoneTable() {
23
- return <ProTable
24
- showToolbarSearch={false}
25
- request={(params) => HttpUtils.get('admin/flowable/user-task/doneTaskPage', params)}
26
- columns={columns}
27
- size='small'
28
- />;
29
- }
@@ -1,32 +0,0 @@
1
- import {Button} from "antd";
2
- import {HttpUtils, PageUtils, ProTable} from "@jiangood/open-admin";
3
- import React from "react";
4
-
5
- const columns = [
6
- {
7
- title: '流程名称', dataIndex: 'processDefinitionName',
8
- render(_, r) { return r.name || r.processDefinitionName; }
9
- },
10
- {title: '发起人', dataIndex: 'startUserName'},
11
- {title: '发起时间', dataIndex: 'startTime'},
12
- {title: '业务标识', dataIndex: 'businessKey'},
13
- {title: '结束时间', dataIndex: 'endTime'},
14
- {
15
- title: '流程状态', dataIndex: 'x',
16
- render(_, row) { return row.endTime == null ? '进行中' : '已结束'; }
17
- },
18
- {title: '终止原因', dataIndex: 'deleteReason'},
19
- {
20
- title: '操作', dataIndex: 'option',
21
- render: (_, record) => (
22
- <Button size='small' onClick={() => PageUtils.open('/flowable/user-task/instance/view' + '?id=' + record.id, '流程信息')}>查看</Button>
23
- ),
24
- },
25
- ];
26
-
27
- export default function MyTable() {
28
- return <ProTable
29
- request={(params) => HttpUtils.get('admin/flowable/user-task/myInstance', params)}
30
- columns={columns}
31
- />;
32
- }
@@ -1,27 +0,0 @@
1
- import {HttpUtils, LinkButton, ProTable} from "@jiangood/open-admin";
2
- import React from "react";
3
-
4
- const columns = [
5
- {title: '发起人', dataIndex: 'instanceStarter'},
6
- {title: '流程名称', dataIndex: 'instanceName'},
7
- {title: '当前节点', dataIndex: 'taskName', width: 100},
8
- {title: '当前操作人', dataIndex: 'assigneeInfo', width: 100},
9
- {title: '发起时间', dataIndex: 'instanceStartTime'},
10
- {title: '任务创建时间', dataIndex: 'createTime'},
11
- {
12
- title: '操作', dataIndex: 'option',
13
- render: (_, record) => {
14
- let path = '/flowable/user-task/form?taskId=' + record.id;
15
- return <LinkButton type='primary' path={path} label='处理任务'>处理</LinkButton>;
16
- },
17
- },
18
- ];
19
-
20
- export default function TodoTable() {
21
- return <ProTable
22
- showToolbarSearch={false}
23
- request={(params) => HttpUtils.get('admin/flowable/user-task/todoTaskPage', params)}
24
- columns={columns}
25
- size='small'
26
- />;
27
- }
@@ -1,87 +0,0 @@
1
- import React from "react";
2
- import {HttpUtils, ProTable} from "@jiangood/open-admin";
3
-
4
- export default class extends React.Component {
5
-
6
- columns = [
7
- {
8
- title: 'ID',
9
- dataIndex: 'id',
10
- },
11
- {
12
- title: '分类',
13
- dataIndex: 'category',
14
- },
15
- {
16
- title: '名称',
17
- dataIndex: 'name',
18
- },
19
- {
20
- title: '键',
21
- dataIndex: 'key',
22
- },
23
- {
24
- title: '描述',
25
- dataIndex: 'description',
26
- },
27
- {
28
- title: '版本',
29
- dataIndex: 'version',
30
- },
31
- {
32
- title: '资源名称',
33
- dataIndex: 'resourceName',
34
- },
35
- {
36
- title: '部署ID',
37
- dataIndex: 'deploymentId',
38
- },
39
- {
40
- title: '图表资源名称',
41
- dataIndex: 'diagramResourceName',
42
- },
43
- {
44
- title: '是否有开始表单键',
45
- dataIndex: 'hasStartFormKey',
46
- render: (value) => value ? '是' : '否',
47
- },
48
- {
49
- title: '是否有图形符号',
50
- dataIndex: 'hasGraphicalNotation',
51
- render: (value) => value ? '是' : '否',
52
- },
53
- {
54
- title: '是否挂起',
55
- dataIndex: 'suspended',
56
- render: (value) => value ? '是' : '否',
57
- },
58
- {
59
- title: '租户ID',
60
- dataIndex: 'tenantId',
61
- },
62
- {
63
- title: '派生自',
64
- dataIndex: 'derivedFrom',
65
- },
66
- {
67
- title: '根派生来源',
68
- dataIndex: 'derivedFromRoot',
69
- },
70
- {
71
- title: '派生版本',
72
- dataIndex: 'derivedVersion',
73
- },
74
-
75
-
76
- ]
77
-
78
- render() {
79
- return <ProTable
80
- search={false}
81
- columns={this.columns}
82
- request={(params) => HttpUtils.get('admin/flowable/monitor/definitionPage', params)}
83
- >
84
-
85
- </ProTable>
86
- }
87
- }