@jiangood/open-admin 3.1.7 → 3.1.9
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 +1 -1
- package/src/framework/GlobalData.ts +2 -0
- package/src/framework/biz/OrgTree.tsx +4 -0
- package/src/framework/biz/PermActions.tsx +1 -1
- package/src/framework/biz/RoleTree.tsx +4 -0
- package/src/framework/components/DownloadModal/index.tsx +10 -3
- package/src/framework/components/FormModal/index.tsx +4 -4
- package/src/framework/components/LogViewer/index.tsx +249 -0
- package/src/framework/components/NamedIcon/index.tsx +1 -1
- package/src/framework/components/Page/index.less +2 -0
- package/src/framework/components/Page/index.tsx +21 -13
- package/src/framework/components/PageLoading/index.tsx +2 -2
- package/src/framework/components/ProTable/index.less +44 -0
- package/src/framework/components/ProTable/index.tsx +54 -13
- package/src/framework/components/index.ts +1 -0
- package/src/framework/config/themeConfig.ts +30 -6
- package/src/framework/fields/BaseRemoteSelect/index.tsx +4 -4
- package/src/framework/fields/FieldDateRange/index.tsx +1 -1
- package/src/framework/fields/FieldDictSelect/index.tsx +1 -1
- package/src/framework/fields/FieldNumberRange/index.tsx +1 -1
- package/src/framework/fields/FieldTable/styles.less +3 -3
- package/src/framework/fields/FieldUploadImage/index.tsx +4 -4
- package/src/framework/utils/HttpClient.ts +63 -25
- package/src/framework/utils/UrlUtils.ts +1 -1
- package/src/layouts/admin/AdminTabs.jsx +35 -1
- package/src/layouts/admin/AdminTabs.less +28 -7
- package/src/layouts/admin/index.jsx +1 -1
- package/src/layouts/admin/index.less +25 -1
- package/src/layouts/index.tsx +47 -10
- package/src/pages/article/$code.jsx +2 -2
- package/src/pages/index.jsx +1 -1
- package/src/pages/system/article/index.jsx +13 -15
- package/src/pages/system/codegen/index.jsx +1 -3
- package/src/pages/system/dict/index.jsx +2 -2
- package/src/pages/system/file/index.jsx +3 -3
- package/src/pages/system/job/index.jsx +151 -40
- package/src/pages/system/log/index.jsx +2 -2
- package/src/pages/system/org/index.jsx +5 -5
- package/src/pages/system/role/index.jsx +12 -13
- package/src/pages/system/role/rolePerm.jsx +1 -1
- package/src/pages/system/user/index.jsx +7 -7
- package/src/pages/system/user/userPerm.jsx +2 -2
- package/src/pages/userCenter/index.jsx +1 -1
- package/src/pages/userCenter/permView.jsx +2 -2
- package/src/style/global.less +2 -2
package/src/pages/index.jsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {PlusOutlined} from '@ant-design/icons'
|
|
2
|
-
import {
|
|
1
|
+
import {PlusOutlined, SearchOutlined} from '@ant-design/icons'
|
|
2
|
+
import {Form, Input, InputNumber} from 'antd'
|
|
3
3
|
import React from 'react'
|
|
4
4
|
import {
|
|
5
5
|
DictUtils,
|
|
@@ -106,26 +106,24 @@ export default class ArticleListPage extends React.Component {
|
|
|
106
106
|
]
|
|
107
107
|
|
|
108
108
|
render() {
|
|
109
|
-
return <Page
|
|
110
|
-
title="文章管理"
|
|
111
|
-
description="管理系统文章,如关于、帮助等页面"
|
|
112
|
-
>
|
|
109
|
+
return <Page>
|
|
113
110
|
<ProTable
|
|
114
111
|
actionRef={this.tableRef}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
112
|
+
searchInline
|
|
113
|
+
toolBarRightRender={() => (
|
|
114
|
+
<PermActions actions={[
|
|
115
|
+
{label: '新增', type: 'primary', icon: <PlusOutlined/>, perm: 'article:create', onClick: this.handleAdd},
|
|
116
|
+
]}/>
|
|
119
117
|
)}
|
|
120
118
|
request={(params) => HttpClient.get('admin/article/page', params)}
|
|
121
119
|
columns={this.columns}
|
|
122
|
-
searchFormRender={() => (
|
|
120
|
+
searchFormRender={() => (
|
|
123
121
|
<>
|
|
124
|
-
<Form.Item
|
|
125
|
-
<Input/>
|
|
122
|
+
<Form.Item name='code' noStyle>
|
|
123
|
+
<Input prefix={<SearchOutlined/>} placeholder='文章编码' allowClear/>
|
|
126
124
|
</Form.Item>
|
|
127
|
-
<Form.Item
|
|
128
|
-
<Input/>
|
|
125
|
+
<Form.Item name='title' noStyle>
|
|
126
|
+
<Input placeholder='文章标题' allowClear/>
|
|
129
127
|
</Form.Item>
|
|
130
128
|
</>
|
|
131
129
|
)}
|
|
@@ -96,9 +96,7 @@ export default class CodegenPage extends React.Component {
|
|
|
96
96
|
|
|
97
97
|
render() {
|
|
98
98
|
const selected = this.selectedOption()
|
|
99
|
-
return <Page
|
|
100
|
-
description='扫描实体,生成 Repository / Service / Controller / 前端页面 / 菜单 代码并写入项目源码目录'
|
|
101
|
-
actions={
|
|
99
|
+
return <Page actions={
|
|
102
100
|
<Space>
|
|
103
101
|
<Perm code='sys-codegen:generate'>
|
|
104
102
|
<Button type='primary' loading={this.state.loading} onClick={this.handlePreview}>预览</Button>
|
|
@@ -164,7 +164,7 @@ export default class DictPage extends React.Component {
|
|
|
164
164
|
const {selectedType, selectedTypeCode} = this.state
|
|
165
165
|
const hasTypeSelected = selectedType != null && selectedTypeCode != null
|
|
166
166
|
|
|
167
|
-
return <Page
|
|
167
|
+
return <Page>
|
|
168
168
|
<Splitter>
|
|
169
169
|
<Splitter.Panel defaultSize={300} style={{paddingRight: 8}}>
|
|
170
170
|
<Card loading={this.state.treeLoading}
|
|
@@ -269,7 +269,7 @@ export default class DictPage extends React.Component {
|
|
|
269
269
|
allowClear
|
|
270
270
|
maxLength={20}
|
|
271
271
|
options={COLOR_OPTIONS}
|
|
272
|
-
filterOption={(input, option) =>
|
|
272
|
+
filterOption={(input, option) =>
|
|
273
273
|
(option.value + option.label).toLowerCase().includes(input.toLowerCase())
|
|
274
274
|
}
|
|
275
275
|
placeholder='如 SUCCESS、#ff0000'
|
|
@@ -32,7 +32,7 @@ export default class FilePage extends React.Component {
|
|
|
32
32
|
title: '缩略图',
|
|
33
33
|
dataIndex: 'objectName',
|
|
34
34
|
width: 80,
|
|
35
|
-
render: (objectName, record) => {
|
|
35
|
+
render: (objectName, record) => {
|
|
36
36
|
if (record.type !== 'image') {
|
|
37
37
|
return '-'
|
|
38
38
|
}
|
|
@@ -151,7 +151,7 @@ export default class FilePage extends React.Component {
|
|
|
151
151
|
<ProTable
|
|
152
152
|
actionRef={this.tableRef}
|
|
153
153
|
rowSelection={{}}
|
|
154
|
-
|
|
154
|
+
toolBarRightRender={(params, selection) => (
|
|
155
155
|
<Space>
|
|
156
156
|
<Button type='primary' icon={<CloudUploadOutlined/>} onClick={() => this.setState({formOpen: true})}>上传文件</Button>
|
|
157
157
|
<PermActions
|
|
@@ -171,7 +171,7 @@ export default class FilePage extends React.Component {
|
|
|
171
171
|
}}
|
|
172
172
|
|
|
173
173
|
columns={this.columns}
|
|
174
|
-
searchFormRender={() => (
|
|
174
|
+
searchFormRender={() => (
|
|
175
175
|
<>
|
|
176
176
|
<Form.Item label='文件名' name='originName'>
|
|
177
177
|
<Input/>
|
|
@@ -2,18 +2,18 @@ import React from 'react'
|
|
|
2
2
|
import {
|
|
3
3
|
Alert,
|
|
4
4
|
AutoComplete,
|
|
5
|
-
Button,
|
|
6
5
|
Divider,
|
|
7
6
|
Form,
|
|
8
7
|
Input,
|
|
9
8
|
Modal,
|
|
9
|
+
Progress,
|
|
10
10
|
Select,
|
|
11
|
-
Spin,
|
|
12
11
|
Switch,
|
|
13
|
-
Tag
|
|
12
|
+
Tag,
|
|
13
|
+
Tooltip
|
|
14
14
|
} from 'antd'
|
|
15
|
-
import {PlusOutlined} from "@ant-design/icons";
|
|
16
|
-
import {FormModal, getMessageApi, HttpClient, Page, PermActions, ProTable, UrlUtils, ValueType} from "../../../framework";
|
|
15
|
+
import {PlusOutlined, SearchOutlined} from "@ant-design/icons";
|
|
16
|
+
import {FormModal, DictUtils, FieldDictSelect, getMessageApi, HttpClient, LogViewer, Page, PermActions, ProTable, UrlUtils, ValueType} from "../../../framework";
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
const cronOptions = [
|
|
@@ -55,11 +55,12 @@ export default class JobPage extends React.Component {
|
|
|
55
55
|
executeRecordOpen: false,
|
|
56
56
|
|
|
57
57
|
logOpen: false,
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
|
|
59
|
+
progressMap: {},
|
|
60
60
|
}
|
|
61
61
|
tableRef = React.createRef()
|
|
62
62
|
modalRef = React.createRef()
|
|
63
|
+
progressTimer = null
|
|
63
64
|
|
|
64
65
|
componentDidMount() {
|
|
65
66
|
HttpClient.get('admin/job/job-class-options', null, {toastError: false}).then(rs => {
|
|
@@ -67,6 +68,39 @@ export default class JobPage extends React.Component {
|
|
|
67
68
|
}).catch(e => {
|
|
68
69
|
console.error('[Job] 加载任务类选项失败:', e);
|
|
69
70
|
})
|
|
71
|
+
this.startProgressPolling()
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
componentWillUnmount() {
|
|
75
|
+
this.stopProgressPolling()
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
startProgressPolling = () => {
|
|
79
|
+
this.loadProgress()
|
|
80
|
+
this.progressTimer = setInterval(() => {
|
|
81
|
+
if (!document.hidden) {
|
|
82
|
+
this.loadProgress()
|
|
83
|
+
}
|
|
84
|
+
}, 3000)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
stopProgressPolling = () => {
|
|
88
|
+
if (this.progressTimer) {
|
|
89
|
+
clearInterval(this.progressTimer)
|
|
90
|
+
this.progressTimer = null
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
loadProgress = () => {
|
|
95
|
+
HttpClient.get('admin/job/progress', null, {toastError: false}).then(rs => {
|
|
96
|
+
const progressMap = {}
|
|
97
|
+
;(rs.data || []).forEach(p => {
|
|
98
|
+
progressMap[p.jobId] = p
|
|
99
|
+
})
|
|
100
|
+
this.setState({progressMap})
|
|
101
|
+
}).catch(e => {
|
|
102
|
+
console.error('[Job] 加载任务进度失败:', e);
|
|
103
|
+
})
|
|
70
104
|
}
|
|
71
105
|
|
|
72
106
|
handleAdd = () => {
|
|
@@ -108,6 +142,7 @@ export default class JobPage extends React.Component {
|
|
|
108
142
|
handleTriggerJob = row => {
|
|
109
143
|
HttpClient.post('admin/job/trigger-job', {id: row.id}, null, {toastError: false}).then(() => {
|
|
110
144
|
this.tableRef.current.reload();
|
|
145
|
+
this.loadProgress()
|
|
111
146
|
}).catch(e => {
|
|
112
147
|
console.error('[Job] 触发任务失败:', e);
|
|
113
148
|
})
|
|
@@ -148,6 +183,38 @@ export default class JobPage extends React.Component {
|
|
|
148
183
|
},
|
|
149
184
|
},
|
|
150
185
|
|
|
186
|
+
{
|
|
187
|
+
title: '日志聚合',
|
|
188
|
+
dataIndex: 'logAggregation',
|
|
189
|
+
render: v => DictUtils.dictTag('jobLogAggregation', v) || '每次执行',
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
{
|
|
193
|
+
title: '运行状态',
|
|
194
|
+
dataIndex: 'progress',
|
|
195
|
+
width: 220,
|
|
196
|
+
render: (_, record) => {
|
|
197
|
+
const p = this.state.progressMap[record.id]
|
|
198
|
+
if (!p) {
|
|
199
|
+
return <Tag>未运行</Tag>
|
|
200
|
+
}
|
|
201
|
+
return <div>
|
|
202
|
+
<Tag color={p.stateColor || 'default'}>{p.stateLabel}</Tag>
|
|
203
|
+
{p.percent != null && <Progress percent={p.percent} size='small'/>}
|
|
204
|
+
{p.message && <Tooltip title={p.message}>
|
|
205
|
+
<div style={{
|
|
206
|
+
fontSize: 12,
|
|
207
|
+
color: 'var(--oa-color-text-secondary, rgba(0, 0, 0, 0.65))',
|
|
208
|
+
overflow: 'hidden',
|
|
209
|
+
textOverflow: 'ellipsis',
|
|
210
|
+
whiteSpace: 'nowrap',
|
|
211
|
+
maxWidth: 200
|
|
212
|
+
}}>{p.message}</div>
|
|
213
|
+
</Tooltip>}
|
|
214
|
+
</div>
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
|
|
151
218
|
{
|
|
152
219
|
title: '操作',
|
|
153
220
|
dataIndex: 'option',
|
|
@@ -180,19 +247,43 @@ export default class JobPage extends React.Component {
|
|
|
180
247
|
|
|
181
248
|
showExecuteRecord(record) {
|
|
182
249
|
this.setState({executeRecordOpen: true, selectedRecord: record})
|
|
250
|
+
this.loadProgress()
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* 执行记录弹窗顶部:当前任务的运行中进度(内存态)
|
|
255
|
+
*/
|
|
256
|
+
renderRunningProgress() {
|
|
257
|
+
const {selectedRecord, progressMap} = this.state
|
|
258
|
+
const p = selectedRecord ? progressMap[selectedRecord.id] : null
|
|
259
|
+
if (!p || p.state !== 'RUNNING') {
|
|
260
|
+
return null
|
|
261
|
+
}
|
|
262
|
+
return <Alert
|
|
263
|
+
type='info'
|
|
264
|
+
showIcon
|
|
265
|
+
style={{marginBottom: 12}}
|
|
266
|
+
title={<div>
|
|
267
|
+
<div style={{marginBottom: 6}}>{p.message || '任务运行中'}</div>
|
|
268
|
+
{p.percent != null && <Progress percent={p.percent} size='small'/>}
|
|
269
|
+
</div>}
|
|
270
|
+
/>
|
|
183
271
|
}
|
|
184
272
|
|
|
185
273
|
showLog = (record) => {
|
|
186
|
-
this.setState({logOpen: true,
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
274
|
+
this.setState({logOpen: true, selectedLogRecord: record})
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* 该执行记录对应的日志是否仍在写入:用进度快照里的 logId 精确匹配
|
|
279
|
+
*/
|
|
280
|
+
isLogRunning = () => {
|
|
281
|
+
const {selectedLogRecord, progressMap} = this.state
|
|
282
|
+
if (!selectedLogRecord) {
|
|
283
|
+
return false
|
|
284
|
+
}
|
|
285
|
+
return Object.values(progressMap).some(p =>
|
|
286
|
+
p.logId === selectedLogRecord.id && p.state === 'RUNNING')
|
|
196
287
|
}
|
|
197
288
|
|
|
198
289
|
|
|
@@ -200,21 +291,22 @@ export default class JobPage extends React.Component {
|
|
|
200
291
|
return <Page>
|
|
201
292
|
<ProTable
|
|
202
293
|
actionRef={this.tableRef}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
<
|
|
207
|
-
|
|
294
|
+
searchInline
|
|
295
|
+
toolBarRightRender={() => (
|
|
296
|
+
<PermActions actions={[
|
|
297
|
+
{label: '新增', type: 'primary', icon: <PlusOutlined/>, perm: 'job:create', onClick: () => this.handleAdd()},
|
|
298
|
+
{label: '查看状态', perm: 'job:read', onClick: this.showStatus},
|
|
299
|
+
]}/>
|
|
208
300
|
)}
|
|
209
301
|
request={(params) => HttpClient.get('admin/job/page', params)}
|
|
210
302
|
columns={this.columns}
|
|
211
|
-
searchFormRender={() => (
|
|
303
|
+
searchFormRender={() => (
|
|
212
304
|
<>
|
|
213
|
-
<Form.Item
|
|
214
|
-
<Input/>
|
|
305
|
+
<Form.Item name='name' noStyle>
|
|
306
|
+
<Input prefix={<SearchOutlined/>} placeholder='任务名称' allowClear/>
|
|
215
307
|
</Form.Item>
|
|
216
|
-
<Form.Item
|
|
217
|
-
<Input/>
|
|
308
|
+
<Form.Item name='jobClass' noStyle>
|
|
309
|
+
<Input placeholder='执行类' allowClear/>
|
|
218
310
|
</Form.Item>
|
|
219
311
|
</>
|
|
220
312
|
)}
|
|
@@ -241,6 +333,11 @@ export default class JobPage extends React.Component {
|
|
|
241
333
|
<Switch/>
|
|
242
334
|
</Form.Item>
|
|
243
335
|
|
|
336
|
+
<Form.Item label='日志聚合' name='logAggregation' initialValue='PER_RUN'
|
|
337
|
+
help='高频任务建议按天聚合:一天只保留一条执行记录,日志文件按天合并'>
|
|
338
|
+
<FieldDictSelect typeCode='jobLogAggregation'/>
|
|
339
|
+
</Form.Item>
|
|
340
|
+
|
|
244
341
|
{this.state.paramList?.map(p => (
|
|
245
342
|
<div key={p.name}>
|
|
246
343
|
<Divider>任务参数</Divider>
|
|
@@ -276,6 +373,7 @@ export default class JobPage extends React.Component {
|
|
|
276
373
|
width={1024}
|
|
277
374
|
destroyOnHidden
|
|
278
375
|
>
|
|
376
|
+
{this.renderRunningProgress()}
|
|
279
377
|
<ProTable columns={[{
|
|
280
378
|
title: '开始时间',
|
|
281
379
|
dataIndex: 'beginTime',
|
|
@@ -289,6 +387,24 @@ export default class JobPage extends React.Component {
|
|
|
289
387
|
dataIndex: 'jobRunTimeLabel',
|
|
290
388
|
|
|
291
389
|
},
|
|
390
|
+
{
|
|
391
|
+
title: '执行次数',
|
|
392
|
+
dataIndex: 'executeCount',
|
|
393
|
+
width: 90,
|
|
394
|
+
render: v => v == null ? 1 : v,
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
title: '失败次数',
|
|
398
|
+
dataIndex: 'failCount',
|
|
399
|
+
width: 90,
|
|
400
|
+
render: v => (v == null || v === 0) ? '-' : <span style={{color: 'var(--oa-color-error, #ff4d4f)'}}>{v}</span>,
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
title: '累计耗时',
|
|
404
|
+
dataIndex: 'totalRunTimeLabel',
|
|
405
|
+
width: 100,
|
|
406
|
+
render: v => v || '-',
|
|
407
|
+
},
|
|
292
408
|
{
|
|
293
409
|
title: '是否成功',
|
|
294
410
|
dataIndex: 'success',
|
|
@@ -323,21 +439,16 @@ export default class JobPage extends React.Component {
|
|
|
323
439
|
width={1024}
|
|
324
440
|
destroyOnHidden
|
|
325
441
|
footer={this.state.selectedLogRecord ? (
|
|
326
|
-
<a href={UrlUtils.contextPath('/admin/sys/log/job/' + this.state.selectedLogRecord.id)}
|
|
442
|
+
<a href={UrlUtils.contextPath('/admin/sys/log/raw/job/' + this.state.selectedLogRecord.id)}
|
|
327
443
|
target='_blank' rel='noreferrer'>在新窗口打开</a>
|
|
328
444
|
) : null}
|
|
329
445
|
>
|
|
330
|
-
|
|
331
|
-
<
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
wordBreak: 'break-all',
|
|
337
|
-
fontSize: 12,
|
|
338
|
-
lineHeight: 1.6
|
|
339
|
-
}}>{this.state.logContent}</pre>
|
|
340
|
-
</Spin>
|
|
446
|
+
{this.state.selectedLogRecord && (
|
|
447
|
+
<LogViewer key={this.state.selectedLogRecord.id}
|
|
448
|
+
logKey={'job/' + this.state.selectedLogRecord.id}
|
|
449
|
+
running={this.isLogRunning()}
|
|
450
|
+
height={480}/>
|
|
451
|
+
)}
|
|
341
452
|
</Modal>
|
|
342
453
|
</Page>
|
|
343
454
|
}
|
|
@@ -348,7 +459,7 @@ export default class JobPage extends React.Component {
|
|
|
348
459
|
const option = this.state.jobClassOptions.find(o => o.value === changed.jobClass)
|
|
349
460
|
if (option) {
|
|
350
461
|
const {label} = option;
|
|
351
|
-
const match = label.match(/[((](.*?)[))]/);
|
|
462
|
+
const match = label.match(/[((](.*?)[))]/);
|
|
352
463
|
if (match) { // 取括号内中文描述设置为name
|
|
353
464
|
this.modalRef.current.formInstance.setFieldValue("name", match[1])
|
|
354
465
|
}
|
|
@@ -53,11 +53,11 @@ export default class LogPage extends React.Component {
|
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
render() {
|
|
56
|
-
return <Page
|
|
56
|
+
return <Page>
|
|
57
57
|
<ProTable
|
|
58
58
|
request={(params) => HttpClient.get('admin/sysLog/page', params)}
|
|
59
59
|
columns={this.columns}
|
|
60
|
-
searchFormRender={() => (
|
|
60
|
+
searchFormRender={() => (
|
|
61
61
|
<>
|
|
62
62
|
<Form.Item label='操作' name='operation'>
|
|
63
63
|
<Input/>
|
|
@@ -94,13 +94,13 @@ export default class OrgPage extends React.Component {
|
|
|
94
94
|
const params = this.state.params
|
|
95
95
|
const canSort = PermUtils.hasPermission('sys-org:update')
|
|
96
96
|
|
|
97
|
-
return <Page
|
|
98
|
-
<Button type='primary' perm='sys-org:create' icon={<PlusOutlined/>} onClick={this.handleAdd}>新增</Button>
|
|
99
|
-
}>
|
|
97
|
+
return <Page>
|
|
100
98
|
<Splitter>
|
|
101
99
|
<Splitter.Panel defaultSize={400} style={{paddingRight: 8}}>
|
|
102
100
|
|
|
103
|
-
|
|
101
|
+
|
|
102
|
+
<Card title="机构树" extra={<Button type='primary' perm='sys-org:create'
|
|
103
|
+
icon={<PlusOutlined/>} onClick={this.handleAdd}>新增</Button>}>
|
|
104
104
|
<div style={{display: 'flex', alignItems: 'center', gap: 4}}>
|
|
105
105
|
<Input.Search placeholder='搜索' value={params.searchText} onChange={e => {
|
|
106
106
|
params.searchText = e.target.value
|
|
@@ -140,7 +140,7 @@ export default class OrgPage extends React.Component {
|
|
|
140
140
|
onSelect={this.onSelect}
|
|
141
141
|
showIcon
|
|
142
142
|
blockNode
|
|
143
|
-
icon={item => <NamedIcon name={item.data.iconName}/>}
|
|
143
|
+
icon={item => <NamedIcon name={item.data.iconName}/>}
|
|
144
144
|
draggable={this.state.draggable}
|
|
145
145
|
onDrop={this.onDrop}
|
|
146
146
|
showLine
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {PlusOutlined} from '@ant-design/icons'
|
|
2
|
-
import {
|
|
1
|
+
import {PlusOutlined, SearchOutlined} from '@ant-design/icons'
|
|
2
|
+
import {Form, Input, InputNumber} from 'antd'
|
|
3
3
|
import React from 'react'
|
|
4
4
|
import {FieldBoolean, FormModal, HttpClient, Page, PageUtils, PermActions, ProTable, UserPicker, ViewText} from "../../../framework";
|
|
5
5
|
|
|
@@ -133,25 +133,24 @@ export default class RolePage extends React.Component {
|
|
|
133
133
|
|
|
134
134
|
render() {
|
|
135
135
|
return <Page
|
|
136
|
-
title="角色管理"
|
|
137
|
-
description="管理系统角色,包括角色权限分配、用户设置等"
|
|
138
136
|
>
|
|
139
137
|
<ProTable
|
|
140
138
|
actionRef={this.tableRef}
|
|
141
|
-
|
|
142
|
-
<PermActions
|
|
143
|
-
|
|
144
|
-
|
|
139
|
+
toolBarRightRender={() => (
|
|
140
|
+
<PermActions actions={[
|
|
141
|
+
{label: '新增', type: 'primary', icon: <PlusOutlined/>, perm: 'sys-role:create', onClick: this.handleAdd},
|
|
142
|
+
]}/>
|
|
145
143
|
)}
|
|
146
144
|
request={(params) => HttpClient.get('admin/sysRole/page', params)}
|
|
147
145
|
columns={this.columns}
|
|
148
|
-
|
|
146
|
+
searchInline
|
|
147
|
+
searchFormRender={() => (
|
|
149
148
|
<>
|
|
150
|
-
<Form.Item
|
|
151
|
-
<Input/>
|
|
149
|
+
<Form.Item name='name' noStyle>
|
|
150
|
+
<Input prefix={<SearchOutlined/>} placeholder='角色名称' allowClear/>
|
|
152
151
|
</Form.Item>
|
|
153
|
-
<Form.Item
|
|
154
|
-
<Input/>
|
|
152
|
+
<Form.Item name='code' noStyle>
|
|
153
|
+
<Input placeholder='角色编码' allowClear/>
|
|
155
154
|
</Form.Item>
|
|
156
155
|
</>
|
|
157
156
|
)}
|
|
@@ -93,7 +93,7 @@ export default class RolePermPage extends React.Component {
|
|
|
93
93
|
|
|
94
94
|
|
|
95
95
|
render() {
|
|
96
|
-
return <Page
|
|
96
|
+
return <Page>
|
|
97
97
|
<Card title='角色权限设置' loading={this.state.loading}
|
|
98
98
|
variant={"borderless"}
|
|
99
99
|
extra={<Button type='primary' icon={<SaveOutlined/>} onClick={this.savePerms}>保存权限</Button>}>
|
|
@@ -152,9 +152,9 @@ export default class UserPage extends React.Component {
|
|
|
152
152
|
|
|
153
153
|
render() {
|
|
154
154
|
|
|
155
|
-
return <Page
|
|
155
|
+
return <Page >
|
|
156
156
|
<Splitter>
|
|
157
|
-
<Splitter.Panel defaultSize={
|
|
157
|
+
<Splitter.Panel defaultSize={340} style={{paddingRight: 8}}>
|
|
158
158
|
<Card size='small'>
|
|
159
159
|
<OrgTree onChange={this.onSelectOrg}/>
|
|
160
160
|
</Card>
|
|
@@ -163,17 +163,17 @@ export default class UserPage extends React.Component {
|
|
|
163
163
|
<ProTable
|
|
164
164
|
searchFormCols={3}
|
|
165
165
|
actionRef={this.tableRef}
|
|
166
|
-
|
|
167
|
-
<PermActions
|
|
168
|
-
|
|
169
|
-
|
|
166
|
+
toolBarRightRender={() => (
|
|
167
|
+
<PermActions actions={[
|
|
168
|
+
{label: '新增', type: 'primary', icon: <PlusOutlined/>, perm: 'sys-user:create', onClick: this.handleAdd},
|
|
169
|
+
]}/>
|
|
170
170
|
)}
|
|
171
171
|
request={(params) => {
|
|
172
172
|
params.orgId = this.state.currentOrgId
|
|
173
173
|
return HttpClient.get('admin/sysUser/page', params)
|
|
174
174
|
}}
|
|
175
175
|
columns={this.columns}
|
|
176
|
-
searchFormRender={() => (
|
|
176
|
+
searchFormRender={() => (
|
|
177
177
|
<>
|
|
178
178
|
<Form.Item label='姓名' name='name'>
|
|
179
179
|
<Input/>
|
|
@@ -15,9 +15,9 @@ export default class UserPerm extends React.Component {
|
|
|
15
15
|
dataPermType: null
|
|
16
16
|
},
|
|
17
17
|
}
|
|
18
|
-
formRef = React.createRef()
|
|
18
|
+
formRef = React.createRef()
|
|
19
19
|
|
|
20
|
-
show(item) {
|
|
20
|
+
show(item) {
|
|
21
21
|
this.setState({visible: true})
|
|
22
22
|
|
|
23
23
|
HttpClient.get('admin/sysUser/get-perm-info', {id: item.id}).then(rs => {
|
|
@@ -26,7 +26,7 @@ export default class PermView extends React.Component {
|
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
title: '状态', dataIndex: 'status', key: 'status', width: 140,
|
|
29
|
-
render: (status) => {
|
|
29
|
+
render: (status) => {
|
|
30
30
|
if (status === 'mine') {
|
|
31
31
|
return <Tag color='blue'>我的机构</Tag>;
|
|
32
32
|
}
|
|
@@ -48,7 +48,7 @@ export default class PermView extends React.Component {
|
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
title: '状态', dataIndex: 'status', key: 'status', width: 140,
|
|
51
|
-
render: (status) => {
|
|
51
|
+
render: (status) => {
|
|
52
52
|
if (status === 'all') {
|
|
53
53
|
return <Tag color='green'>已授权</Tag>;
|
|
54
54
|
}
|
package/src/style/global.less
CHANGED
|
@@ -26,9 +26,9 @@ table.oa-table {
|
|
|
26
26
|
background-color: var(--oa-color-fill, #f5f5f5); /* 悬停背景色 */
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
/* 斑马纹效果 -
|
|
29
|
+
/* 斑马纹效果 - 用最浅一档填充色;若用页面底色,暗色下会在容器上形成纯黑条 */
|
|
30
30
|
tr:nth-child(even) {
|
|
31
|
-
background-color: var(--oa-color-
|
|
31
|
+
background-color: var(--oa-color-fill-quaternary, #f9f9f9);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
/* 响应式表格 - 在小屏幕上添加水平滚动 */
|