@jiangood/open-admin 3.0.15 → 3.1.1

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.
Files changed (82) hide show
  1. package/package.json +15 -2
  2. package/src/framework/biz/OrgTree.tsx +10 -6
  3. package/src/framework/biz/PermActions.tsx +5 -3
  4. package/src/framework/biz/RoleTree.tsx +10 -6
  5. package/src/framework/biz/index.tsx +1 -0
  6. package/src/framework/components/ContextMenu/index.tsx +17 -1
  7. package/src/framework/components/DownloadModal/index.tsx +40 -33
  8. package/src/framework/components/DrawerForm/index.tsx +108 -0
  9. package/src/framework/components/FormModal/index.tsx +16 -9
  10. package/src/framework/components/NamedIcon/index.tsx +2 -2
  11. package/src/framework/components/OrgSwitcher/index.tsx +6 -7
  12. package/src/framework/components/PageLoading/index.tsx +3 -3
  13. package/src/framework/components/ProTable/index.tsx +28 -25
  14. package/src/framework/components/ValueType/index.tsx +1 -1
  15. package/src/framework/components/index.ts +1 -0
  16. package/src/framework/config/themeConfig.ts +5 -5
  17. package/src/framework/fields/BaseRemoteSelect/index.tsx +23 -21
  18. package/src/framework/fields/FieldBoolean/index.tsx +6 -6
  19. package/src/framework/fields/FieldDate/index.tsx +10 -10
  20. package/src/framework/fields/FieldDateRange/index.tsx +20 -20
  21. package/src/framework/fields/FieldDictSelect/index.tsx +2 -2
  22. package/src/framework/fields/FieldEditor/index.tsx +1 -1
  23. package/src/framework/fields/FieldNumberRange/index.tsx +16 -17
  24. package/src/framework/fields/FieldPercent/index.tsx +2 -2
  25. package/src/framework/fields/FieldRemoteSelect/index.tsx +4 -4
  26. package/src/framework/fields/FieldRemoteTree/index.tsx +1 -1
  27. package/src/framework/fields/FieldRemoteTreeCascader/index.tsx +1 -1
  28. package/src/framework/fields/FieldRemoteTreeSelect/index.tsx +1 -1
  29. package/src/framework/fields/FieldSysOrgTree/index.tsx +1 -1
  30. package/src/framework/fields/FieldSysOrgTreeSelect/index.tsx +1 -1
  31. package/src/framework/fields/FieldTable/index.tsx +15 -13
  32. package/src/framework/fields/FieldTableSelect/index.tsx +5 -5
  33. package/src/framework/fields/FieldUploadFile/index.tsx +3 -3
  34. package/src/framework/fields/FieldUploadImage/index.tsx +31 -29
  35. package/src/framework/fields/types.ts +0 -2
  36. package/src/framework/router/PageFrame.tsx +1 -1
  37. package/src/framework/router/matcher.ts +2 -2
  38. package/src/framework/utils/ArrayUtils.ts +2 -2
  39. package/src/framework/utils/DateUtils.ts +1 -1
  40. package/src/framework/utils/{system/DictUtils.ts → DictUtils.ts} +1 -1
  41. package/src/framework/utils/EventBus.ts +7 -7
  42. package/src/framework/utils/HttpClient.ts +283 -0
  43. package/src/framework/utils/{system/PageUtils.ts → PageUtils.ts} +4 -4
  44. package/src/framework/utils/{system/PermUtils.ts → PermUtils.ts} +3 -3
  45. package/src/framework/utils/StringUtils.ts +10 -8
  46. package/src/framework/utils/TreeUtils.ts +3 -3
  47. package/src/framework/utils/UrlUtils.ts +2 -2
  48. package/src/framework/utils/index.ts +4 -1
  49. package/src/framework/views/ViewApproveStatus/index.tsx +1 -2
  50. package/src/framework/views/ViewBoolean/index.tsx +4 -1
  51. package/src/framework/views/ViewFile/index.tsx +4 -4
  52. package/src/framework/views/ViewImage/index.tsx +2 -2
  53. package/src/framework/views/ViewPassword/index.tsx +3 -2
  54. package/src/framework/views/ViewText/index.tsx +12 -3
  55. package/src/framework/views/types.ts +2 -4
  56. package/src/layouts/admin/AdminTabs.jsx +9 -0
  57. package/src/layouts/admin/AdminTabs.less +2 -2
  58. package/src/layouts/admin/HeaderRight.jsx +8 -7
  59. package/src/layouts/admin/TabLayout.jsx +2 -2
  60. package/src/layouts/admin/index.jsx +15 -11
  61. package/src/layouts/admin/index.less +16 -1
  62. package/src/layouts/index.tsx +24 -18
  63. package/src/pages/404.jsx +1 -1
  64. package/src/pages/article/$code.jsx +4 -4
  65. package/src/pages/index.jsx +1 -1
  66. package/src/pages/public/login.jsx +34 -27
  67. package/src/pages/public/test.jsx +1 -1
  68. package/src/pages/standalone/forceUpdatePwd.jsx +9 -7
  69. package/src/pages/system/article/index.jsx +9 -8
  70. package/src/pages/system/dict/index.jsx +19 -16
  71. package/src/pages/system/file/index.jsx +9 -9
  72. package/src/pages/system/job/index.jsx +17 -17
  73. package/src/pages/system/log/index.jsx +5 -7
  74. package/src/pages/system/org/index.jsx +31 -18
  75. package/src/pages/system/role/index.jsx +13 -12
  76. package/src/pages/system/role/rolePerm.jsx +25 -21
  77. package/src/pages/system/user/index.jsx +35 -33
  78. package/src/pages/system/user/userPerm.jsx +12 -12
  79. package/src/pages/userCenter/index.jsx +11 -9
  80. package/src/pages/userCenter/permView.jsx +7 -7
  81. package/src/framework/utils/system/HttpUtils.ts +0 -97
  82. package/src/framework/utils/system/index.ts +0 -4
@@ -13,7 +13,7 @@ import {
13
13
  Tag
14
14
  } from 'antd'
15
15
  import {PlusOutlined} from "@ant-design/icons";
16
- import {FormModal, HttpUtils, Page, PermActions, ProTable, UrlUtils, ValueType} from "../../../framework";
16
+ import {FormModal, HttpClient, Page, PermActions, ProTable, UrlUtils, ValueType} from "../../../framework";
17
17
 
18
18
 
19
19
  const cronOptions = [
@@ -40,7 +40,7 @@ const cronOptions = [
40
40
  ]
41
41
 
42
42
 
43
- export default class extends React.Component {
43
+ export default class JobPage extends React.Component {
44
44
 
45
45
  state = {
46
46
  selectedRowKeys: [],
@@ -58,8 +58,8 @@ export default class extends React.Component {
58
58
  modalRef = React.createRef()
59
59
 
60
60
  componentDidMount() {
61
- HttpUtils.get('admin/job/job-class-options').then(rs => {
62
- this.setState({jobClassOptions: rs})
61
+ HttpClient.get('admin/job/job-class-options', null, {toastError: false}).then(rs => {
62
+ this.setState({jobClassOptions: rs.data})
63
63
  }).catch(e => {
64
64
  console.error('[Job] 加载任务类选项失败:', e);
65
65
  })
@@ -76,8 +76,8 @@ export default class extends React.Component {
76
76
  }
77
77
 
78
78
  loadJobParamFields(className, jobData) {
79
- HttpUtils.post("admin/job/get-job-param-fields", jobData || {}, {className}).then(rs => {
80
- this.setState({paramList: rs})
79
+ HttpClient.post("admin/job/get-job-param-fields", jobData || {}, {className}, {toastError: false}).then(rs => {
80
+ this.setState({paramList: rs.data})
81
81
  }).catch(e => {
82
82
  console.error('[Job] 加载任务参数字段失败:', e);
83
83
  })
@@ -86,13 +86,13 @@ export default class extends React.Component {
86
86
  onFinish = async values => {
87
87
  const isNew = !values.id;
88
88
  const url = isNew ? 'admin/job/create' : 'admin/job/update';
89
- await HttpUtils.post(url, values)
89
+ await HttpClient.post(url, values)
90
90
  this.tableRef.current.reload()
91
91
  }
92
92
 
93
93
  handleDelete = row => {
94
94
  const hide = message.loading("删除任务中...")
95
- HttpUtils.post('admin/job/delete', {id: row.id}).then(rs => {
95
+ HttpClient.post('admin/job/delete', {id: row.id}, null, {toastError: false}).then(() => {
96
96
  hide();
97
97
  this.tableRef.current.reload();
98
98
  }).catch(e => {
@@ -102,7 +102,7 @@ export default class extends React.Component {
102
102
  }
103
103
 
104
104
  handleTriggerJob = row => {
105
- HttpUtils.post('admin/job/trigger-job', {id: row.id}).then(rs => {
105
+ HttpClient.post('admin/job/trigger-job', {id: row.id}, null, {toastError: false}).then(() => {
106
106
  this.tableRef.current.reload();
107
107
  }).catch(e => {
108
108
  console.error('[Job] 触发任务失败:', e);
@@ -167,8 +167,8 @@ export default class extends React.Component {
167
167
 
168
168
  showStatus = () => {
169
169
  this.setState({statusOpen: true})
170
- HttpUtils.get('admin/job/status').then(rs => {
171
- this.setState({status: rs})
170
+ HttpClient.get('admin/job/status', null, {toastError: false}).then(rs => {
171
+ this.setState({status: rs.data})
172
172
  }).catch(e => {
173
173
  console.error('[Job] 加载状态失败:', e);
174
174
  })
@@ -183,15 +183,15 @@ export default class extends React.Component {
183
183
  return <Page>
184
184
  <ProTable
185
185
  actionRef={this.tableRef}
186
- toolBarRender={() => (
186
+ toolBarRender={() => ( // NOSONAR: AntD 渲染函数惯例
187
187
  <PermActions>
188
188
  <Button type='primary' perm='job:create' icon={<PlusOutlined/>} onClick={() => this.handleAdd()}>新增</Button>
189
189
  <Button perm='job:read' onClick={this.showStatus}>查看状态</Button>
190
190
  </PermActions>
191
191
  )}
192
- request={(params) => HttpUtils.get('admin/job/page', params)}
192
+ request={(params) => HttpClient.get('admin/job/page', params)}
193
193
  columns={this.columns}
194
- searchFormRender={() => (
194
+ searchFormRender={() => ( // NOSONAR: AntD 渲染函数惯例
195
195
  <>
196
196
  <Form.Item label='名称' name='name'>
197
197
  <Input/>
@@ -295,9 +295,9 @@ export default class extends React.Component {
295
295
  return <a href={url} target='_blank'>日志</a>;
296
296
  },
297
297
  }
298
- ]} request={params => {
298
+ ]} request={(params) => {
299
299
  params.jobId = this.state.selectedRecord.id
300
- return HttpUtils.get('admin/job/execute-record', params);
300
+ return HttpClient.get('admin/job/execute-record', params);
301
301
  }}></ProTable>
302
302
 
303
303
  </Modal>
@@ -310,7 +310,7 @@ export default class extends React.Component {
310
310
  const option = this.state.jobClassOptions.find(o => o.value === changed.jobClass)
311
311
  if (option) {
312
312
  const {label} = option;
313
- const match = label.match(/[((](.*?)[))]/);
313
+ const match = label.match(/[((](.*?)[))]/); // NOSONAR: 匹配中英文括号内内容,已最简
314
314
  if (match) { // 取括号内中文描述设置为name
315
315
  this.modalRef.current.formInstance.setFieldValue("name", match[1])
316
316
  }
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
  import {Form, Input, Tag} from "antd";
3
- import {ViewText, FieldDateRange, HttpUtils, Page, ProTable} from "../../../framework";
3
+ import {ViewText, FieldDateRange, HttpClient, Page, ProTable} from "../../../framework";
4
4
 
5
- export default class extends React.Component {
5
+ export default class LogPage extends React.Component {
6
6
 
7
7
 
8
8
  columns = [
@@ -39,9 +39,7 @@ export default class extends React.Component {
39
39
  title: '结果',
40
40
  dataIndex: 'success',
41
41
  render(v) {
42
- return <>
43
- <Tag color={v ? 'green' : 'red'}>{v ? '成功' : '失败'}</Tag>
44
- </>
42
+ return <Tag color={v ? 'green' : 'red'}>{v ? '成功' : '失败'}</Tag>
45
43
  }
46
44
  },
47
45
  {
@@ -57,9 +55,9 @@ export default class extends React.Component {
57
55
  render() {
58
56
  return <Page title="操作日志" description="查看系统操作日志">
59
57
  <ProTable
60
- request={(params) => HttpUtils.get('admin/sysLog/page', params)}
58
+ request={(params) => HttpClient.get('admin/sysLog/page', params)}
61
59
  columns={this.columns}
62
- searchFormRender={() => (
60
+ searchFormRender={() => ( // NOSONAR: AntD 渲染函数惯例
63
61
  <>
64
62
  <Form.Item label='操作' name='operation'>
65
63
  <Input/>
@@ -1,5 +1,5 @@
1
1
  import {DeleteOutlined, EditOutlined, PlusOutlined, SettingOutlined, SyncOutlined} from '@ant-design/icons';
2
- import {Button, Card, Checkbox, Descriptions, Form, Input, InputNumber, Popover, Space, Spin, Splitter, Switch, Tree, Typography} from 'antd';
2
+ import {Button, Card, Checkbox, Descriptions, Form, Input, InputNumber, Modal, Popover, Space, Spin, Splitter, Switch, Tree, Typography} from 'antd';
3
3
  import React from 'react';
4
4
  import {
5
5
  FieldBoolean,
@@ -7,14 +7,14 @@ import {
7
7
  FieldRemoteTreeSelect,
8
8
  FieldUserSelect,
9
9
  FormModal, Gap,
10
- HttpUtils,
10
+ HttpClient,
11
11
  NamedIcon,
12
12
  Page,
13
13
  PermActions,
14
14
  ViewSwitch,
15
15
  } from "../../../framework";
16
16
 
17
- export default class extends React.Component {
17
+ export default class OrgPage extends React.Component {
18
18
 
19
19
  state = {
20
20
  selectedOrg: null,
@@ -26,6 +26,7 @@ export default class extends React.Component {
26
26
  treeData: [],
27
27
  treeLoading: false,
28
28
  draggable: false,
29
+ deleteModalOpen: false,
29
30
  }
30
31
  modalRef = React.createRef();
31
32
  treeRef = React.createRef();
@@ -36,18 +37,23 @@ export default class extends React.Component {
36
37
 
37
38
  loadTree = () => {
38
39
  this.setState({treeLoading: true})
39
- HttpUtils.get('admin/sysOrg/tree', this.state.params).then(rs => {
40
- this.setState({treeData: rs})
41
- }).finally(() => {
40
+ HttpClient.get('admin/sysOrg/tree', this.state.params, {toastError: false}).then(rs => {
41
+ this.setState({treeData: rs.data})
42
+ this.setState({treeLoading: false});
43
+ }).catch(() => {
42
44
  this.setState({treeLoading: false});
43
45
  })
44
46
  }
45
47
 
48
+ openDeleteModal = () => {
49
+ this.setState({deleteModalOpen: true})
50
+ }
51
+
46
52
  handleDelete = () => {
47
53
  const {selectedOrg} = this.state
48
54
  if (!selectedOrg) return
49
- HttpUtils.post('admin/sysOrg/delete', {id: selectedOrg.id}).then(() => {
50
- this.setState({selectedOrg: null})
55
+ HttpClient.post('admin/sysOrg/delete', {id: selectedOrg.id}, null).then(() => {
56
+ this.setState({selectedOrg: null, deleteModalOpen: false})
51
57
  this.loadTree()
52
58
  })
53
59
  }
@@ -57,8 +63,8 @@ export default class extends React.Component {
57
63
  this.setState({selectedOrg: null})
58
64
  return
59
65
  }
60
- HttpUtils.get("admin/sysOrg/detail", {id: selectedKeys[0]}).then(rs => {
61
- this.setState({selectedOrg: rs})
66
+ HttpClient.get("admin/sysOrg/detail", {id: selectedKeys[0]}).then(rs => {
67
+ this.setState({selectedOrg: rs.data})
62
68
  })
63
69
  }
64
70
 
@@ -74,7 +80,7 @@ export default class extends React.Component {
74
80
  handleModalFinish = async values => {
75
81
  const isNew = !values.id
76
82
  const url = isNew ? 'admin/sysOrg/create' : 'admin/sysOrg/update'
77
- await HttpUtils.post(url, values)
83
+ await HttpClient.post(url, values)
78
84
  this.loadTree()
79
85
  }
80
86
 
@@ -131,7 +137,7 @@ export default class extends React.Component {
131
137
  onSelect={this.onSelect}
132
138
  showIcon
133
139
  blockNode
134
- icon={item => <NamedIcon name={item.data.iconName}/>}
140
+ icon={item => <NamedIcon name={item.data.iconName}/>} // NOSONAR: AntD 渲染函数惯例
135
141
  draggable={this.state.draggable}
136
142
  onDrop={this.onDrop}
137
143
  showLine
@@ -152,8 +158,8 @@ export default class extends React.Component {
152
158
  label: '删除',
153
159
  perm: 'sys-org:delete',
154
160
  icon: <DeleteOutlined/>,
155
- confirm: '是否确定删除组织机构',
156
- onClick: this.handleDelete,
161
+ danger: true,
162
+ onClick: this.openDeleteModal,
157
163
  },
158
164
  ]}/>
159
165
  )}
@@ -185,9 +191,6 @@ export default class extends React.Component {
185
191
  <Form.Item label='名称' name='name' rules={[{required: true}]}>
186
192
  <Input/>
187
193
  </Form.Item>
188
- <Form.Item label='序号' name='seq'>
189
- <InputNumber/>
190
- </Form.Item>
191
194
  <Form.Item label='类型' name='type' rules={[{required: true}]}>
192
195
  <FieldRemoteSelect url='admin/sysOrg/type-options' placeholder='请选择类型'/>
193
196
  </Form.Item>
@@ -197,6 +200,9 @@ export default class extends React.Component {
197
200
  <Form.Item label='启用' name='enabled' rules={[{required: true}]}>
198
201
  <FieldBoolean/>
199
202
  </Form.Item>
203
+ <Form.Item label='序号' name='seq'>
204
+ <InputNumber/>
205
+ </Form.Item>
200
206
  <Form.Item label='扩展字段1' name='extra1'>
201
207
  <Input/>
202
208
  </Form.Item>
@@ -207,6 +213,13 @@ export default class extends React.Component {
207
213
  <Input/>
208
214
  </Form.Item>
209
215
  </FormModal>
216
+
217
+ <Modal open={this.state.deleteModalOpen} title="删除确认" okText="删除" cancelText="取消"
218
+ okButtonProps={{danger: true}}
219
+ onCancel={() => this.setState({deleteModalOpen: false})}
220
+ onOk={this.handleDelete}>
221
+ 是否确定删除组织机构「{selectedOrg?.name}」?
222
+ </Modal>
210
223
  </Page>
211
224
  }
212
225
 
@@ -216,7 +229,7 @@ export default class extends React.Component {
216
229
  const dragKey = dragNode.key;
217
230
  const dropPos = e.node.pos.split('-');
218
231
  const dropPosition = e.dropPosition - Number(dropPos[dropPos.length - 1]);
219
- HttpUtils.post('admin/sysOrg/sort', {dropPosition, dropToGap, dropKey, dragKey}).then(this.loadTree)
232
+ HttpClient.post('admin/sysOrg/sort', {dropPosition, dropToGap, dropKey, dragKey}, null).then(() => this.loadTree())
220
233
  };
221
234
  }
222
235
 
@@ -1,10 +1,10 @@
1
1
  import {PlusOutlined} from '@ant-design/icons'
2
2
  import {Button, Form, Input, InputNumber, Modal, Transfer} from 'antd'
3
3
  import React from 'react'
4
- import {FieldBoolean, FormModal, HttpUtils, Page, PageUtils, PermActions, ProTable, ViewText} from "../../../framework";
4
+ import {FieldBoolean, FormModal, HttpClient, Page, PageUtils, PermActions, ProTable, ViewText} from "../../../framework";
5
5
 
6
6
 
7
- export default class extends React.Component {
7
+ export default class RolePage extends React.Component {
8
8
 
9
9
  state = {
10
10
  usersModalOpen: false,
@@ -29,20 +29,20 @@ export default class extends React.Component {
29
29
 
30
30
  handleEditUser = record => {
31
31
  this.setState({usersModalOpen: true, selectedRecord: record})
32
- HttpUtils.get('admin/sysRole/user-list', {id: record.id}).then(rs => {
33
- this.setState({userList: rs.list, targetKeys: rs.selectedKeys})
32
+ HttpClient.get('admin/sysRole/user-list', {id: record.id}).then(rs => {
33
+ this.setState({userList: rs.data.list, targetKeys: rs.data.selectedKeys})
34
34
  })
35
35
  }
36
36
 
37
37
  onFinish = async values => {
38
38
  const isNew = !values.id;
39
39
  const url = isNew ? 'admin/sysRole/create' : 'admin/sysRole/update';
40
- await HttpUtils.post(url, values)
40
+ await HttpClient.post(url, values)
41
41
  this.tableRef.current.reload()
42
42
  }
43
43
 
44
44
  handleDelete = record => {
45
- HttpUtils.post('admin/sysRole/delete', {id: record.id}).then(rs => {
45
+ HttpClient.post('admin/sysRole/delete', {id: record.id}, null).then(() => {
46
46
  this.tableRef.current.reload()
47
47
  })
48
48
  }
@@ -83,7 +83,8 @@ export default class extends React.Component {
83
83
 
84
84
 
85
85
  render(v) {
86
- return v == null ? null : (v ? '是' : '否')
86
+ if (v == null) return null;
87
+ return v ? '是' : '否';
87
88
  },
88
89
 
89
90
 
@@ -126,7 +127,7 @@ export default class extends React.Component {
126
127
  id: this.state.selectedRecord.id,
127
128
  userIdList: this.state.targetKeys
128
129
  }
129
- HttpUtils.post('admin/sysRole/grant-users', params).then(rs => {
130
+ HttpClient.post('admin/sysRole/grant-users', params, null, {toastError: false}).then(() => {
130
131
  this.setState({usersModalOpen: false, usersModalLoading: false})
131
132
  }).catch(() => {
132
133
  this.setState({usersModalLoading: false})
@@ -140,14 +141,14 @@ export default class extends React.Component {
140
141
  >
141
142
  <ProTable
142
143
  actionRef={this.tableRef}
143
- toolBarRender={() => (
144
+ toolBarRender={() => ( // NOSONAR: AntD 渲染函数惯例
144
145
  <PermActions>
145
146
  <Button perm='sys-role:create' type='primary' icon={<PlusOutlined/>} onClick={this.handleAdd}>新增</Button>
146
147
  </PermActions>
147
148
  )}
148
- request={(params) => HttpUtils.get('admin/sysRole/page', params)}
149
+ request={(params) => HttpClient.get('admin/sysRole/page', params)}
149
150
  columns={this.columns}
150
- searchFormRender={() => (
151
+ searchFormRender={() => ( // NOSONAR: AntD 渲染函数惯例
151
152
  <>
152
153
  <Form.Item label='角色名称' name='name'>
153
154
  <Input/>
@@ -202,7 +203,7 @@ export default class extends React.Component {
202
203
  targetKeys={this.state.targetKeys}
203
204
  selectedKeys={this.state.selectedKeys}
204
205
  render={item => item.title}
205
- onChange={(nextTargetKeys, direction, moveKeys) => {
206
+ onChange={(nextTargetKeys, _direction, _moveKeys) => {
206
207
  this.setState({
207
208
  targetKeys: nextTargetKeys
208
209
  })
@@ -1,8 +1,8 @@
1
1
  import React from "react";
2
2
  import {Button, Card, Checkbox, Table, Typography} from "antd";
3
3
  import {SaveOutlined} from "@ant-design/icons";
4
- import {HttpUtils, Page} from "../../../framework";
5
- export default class extends React.Component {
4
+ import {HttpClient, Page} from "../../../framework";
5
+ export default class RolePermPage extends React.Component {
6
6
 
7
7
 
8
8
  state = {
@@ -39,9 +39,9 @@ export default class extends React.Component {
39
39
  return <Checkbox.Group options={options}
40
40
  value={rowSelectedKey}
41
41
  onChange={(ks) => {
42
- const rowSelectedKeys = this.state.rowSelectedKeys;
43
- rowSelectedKeys[record.id] = ks;
44
- this.setState({rowSelectedKeys})
42
+ this.setState(prevState => ({
43
+ rowSelectedKeys: {...prevState.rowSelectedKeys, [record.id]: ks}
44
+ }))
45
45
  }}/>
46
46
  }
47
47
  }
@@ -55,19 +55,25 @@ export default class extends React.Component {
55
55
 
56
56
  loadData() {
57
57
  this.setState({loading: true})
58
- Promise.all([
59
- HttpUtils.get('admin/sysRole/get', {id: this.roleId}).then(rs => {
60
- this.setState({roleInfo: rs})
61
- }),
62
- HttpUtils.get('admin/sysRole/perm-tree-table', {id: this.roleId}).then(rs => {
63
- this.setState({dataSource: rs})
64
- }),
65
- HttpUtils.get('admin/sysRole/own-perms', {id: this.roleId}).then(rs => {
66
- this.setState({rowSelectedKeys: rs})
67
- })
68
- ]).then(rs => {
69
- this.setState({loading: false})
70
- })
58
+ const requestCount = 3;
59
+ let finished = 0;
60
+ const onFinish = () => {
61
+ if (++finished === requestCount) {
62
+ this.setState({loading: false})
63
+ }
64
+ };
65
+ HttpClient.get('admin/sysRole/get', {id: this.roleId}).then(rs => {
66
+ this.setState({roleInfo: rs.data})
67
+ onFinish()
68
+ });
69
+ HttpClient.get('admin/sysRole/perm-tree-table', {id: this.roleId}).then(rs => {
70
+ this.setState({dataSource: rs.data})
71
+ onFinish()
72
+ });
73
+ HttpClient.get('admin/sysRole/own-perms', {id: this.roleId}).then(rs => {
74
+ this.setState({rowSelectedKeys: rs.data})
75
+ onFinish()
76
+ });
71
77
  }
72
78
 
73
79
  savePerms = () => {
@@ -82,9 +88,7 @@ export default class extends React.Component {
82
88
  menus.push(menuId)
83
89
  perms.push(...ks)
84
90
  }
85
- HttpUtils.post('admin/sysRole/save-perms', {id: this.roleId, perms, menus}).then(rs => {
86
- // Page.open(PageUtils.currentPathname(), PageUtils.currentLabel())
87
- })
91
+ HttpClient.post('admin/sysRole/save-perms', {id: this.roleId, perms, menus})
88
92
  };
89
93
 
90
94
 
@@ -1,5 +1,5 @@
1
1
  import {PlusOutlined} from '@ant-design/icons';
2
- import {Button, Card, Form, Input, Modal, Select, Splitter, message} from 'antd';
2
+ import {Button, Card, Form, Input, Modal, Select, Splitter, Typography} from 'antd';
3
3
  import React from 'react';
4
4
  import {
5
5
  PermActions,
@@ -8,7 +8,7 @@ import {
8
8
  FieldRemoteSelect,
9
9
  FieldSysOrgTreeSelect,
10
10
  FormModal,
11
- HttpUtils,
11
+ HttpClient,
12
12
  OrgTree,
13
13
  Page,
14
14
  ProTable,
@@ -16,11 +16,11 @@ import {
16
16
  } from "../../../framework";
17
17
  import UserPerm from "./userPerm";
18
18
 
19
- export default class extends React.Component {
19
+ export default class UserPage extends React.Component {
20
20
 
21
21
  state = {
22
22
  currentOrgId: null,
23
- addResultModal: { open: false, account: '', password: '' },
23
+ addResultModal: { open: false, name: '', account: '', password: '' },
24
24
  resetPwdUser: null,
25
25
  }
26
26
  permRef = React.createRef();
@@ -36,14 +36,13 @@ export default class extends React.Component {
36
36
  }
37
37
 
38
38
  onFinishResetPwd = async values => {
39
- await HttpUtils.post('admin/sysUser/reset-pwd', {id: this.state.resetPwdUser.id, password: values.password})
40
- message.success('重置密码成功')
39
+ await HttpClient.post('admin/sysUser/reset-pwd', {id: this.state.resetPwdUser.id, password: values.password})
41
40
  this.setState({resetPwdUser: null})
42
41
  this.tableRef.current?.reload()
43
42
  }
44
43
 
45
44
  handleDelete = r => {
46
- HttpUtils.post('admin/sysUser/delete', {id: r.id}).then(rs => {
45
+ HttpClient.post('admin/sysUser/delete', {id: r.id}, null).then(() => {
47
46
  this.tableRef.current.reload();
48
47
  })
49
48
  }
@@ -103,7 +102,8 @@ export default class extends React.Component {
103
102
  title: '状态',
104
103
  dataIndex: 'enabled',
105
104
  render(v) {
106
- return v == null ? null : (v ? '是' : '否')
105
+ if (v == null) return null;
106
+ return v ? '是' : '否';
107
107
  },
108
108
  },
109
109
  {
@@ -140,13 +140,14 @@ export default class extends React.Component {
140
140
  onFinish = async values => {
141
141
  const isNew = !values.id;
142
142
  const url = isNew ? 'admin/sysUser/create' : 'admin/sysUser/update';
143
- const result = await HttpUtils.post(url, values)
144
- if (result && result.password) {
143
+ const result = await HttpClient.post(url, values);
144
+ if (result?.data?.password) {
145
145
  this.setState({
146
146
  addResultModal: {
147
147
  open: true,
148
+ name: values.name,
148
149
  account: values.account,
149
- password: result.password,
150
+ password: result.data.password,
150
151
  }
151
152
  })
152
153
  }
@@ -166,17 +167,17 @@ export default class extends React.Component {
166
167
  <ProTable
167
168
  searchFormCols={3}
168
169
  actionRef={this.tableRef}
169
- toolBarRender={() => (
170
+ toolBarRender={() => ( // NOSONAR: AntD 渲染函数惯例
170
171
  <PermActions>
171
172
  <Button perm='sys-user:create' type='primary' icon={<PlusOutlined/>} onClick={this.handleAdd}>新增</Button>
172
173
  </PermActions>
173
174
  )}
174
175
  request={(params) => {
175
176
  params.orgId = this.state.currentOrgId
176
- return HttpUtils.get('admin/sysUser/page', params)
177
+ return HttpClient.get('admin/sysUser/page', params)
177
178
  }}
178
179
  columns={this.columns}
179
- searchFormRender={() => (
180
+ searchFormRender={() => ( // NOSONAR: AntD 渲染函数惯例
180
181
  <>
181
182
  <Form.Item label='姓名' name='name'>
182
183
  <Input/>
@@ -233,27 +234,25 @@ export default class extends React.Component {
233
234
  <Modal
234
235
  title="添加用户成功"
235
236
  open={this.state.addResultModal.open}
236
- onOk={() => this.setState({addResultModal: {open: false, account: '', password: ''}})}
237
- onCancel={() => this.setState({addResultModal: {open: false, account: '', password: ''}})}
237
+ onOk={() => this.setState({addResultModal: {open: false, name: '', account: '', password: ''}})}
238
+ onCancel={() => this.setState({addResultModal: {open: false, name: '', account: '', password: ''}})}
238
239
  width={420}
239
240
  footer={
240
- <div style={{display: 'flex', justifyContent: 'flex-end', gap: 8}}>
241
- <Button onClick={() => {
242
- navigator.clipboard.writeText(`账号:${this.state.addResultModal.account}\n密码:${this.state.addResultModal.password}`);
243
- message.success('复制成功')
244
- }}>复制</Button>
245
- <Button type="primary" onClick={() => this.setState({addResultModal: {open: false, account: '', password: ''}})}>确定</Button>
246
- </div>
241
+ <Button type="primary" onClick={() => this.setState({addResultModal: {open: false, name: '', account: '', password: ''}})}>确定</Button>
247
242
  }
248
243
  >
249
- <div>
250
- <div style={{marginBottom: 8}}>
251
- 账号:{this.state.addResultModal.account}
252
- </div>
253
- <div>
254
- 密码:{this.state.addResultModal.password}
255
- </div>
256
- </div>
244
+ <Typography.Paragraph
245
+ copyable={{
246
+ text: `系统访问地址:${window.location.origin}\n姓名:${this.state.addResultModal.name}\n账号:${this.state.addResultModal.account}\n密码:${this.state.addResultModal.password}`,
247
+ tooltips: '点击复制',
248
+ }}
249
+ style={{marginBottom: 0}}
250
+ >
251
+ <div>系统访问地址:{window.location.origin}</div>
252
+ <div>姓名:{this.state.addResultModal.name}</div>
253
+ <div>账号:{this.state.addResultModal.account}</div>
254
+ <div>密码:{this.state.addResultModal.password}</div>
255
+ </Typography.Paragraph>
257
256
  </Modal>
258
257
 
259
258
  <FormModal ref={this.resetPwdRef} title='重置密码' onFinish={this.onFinishResetPwd} width={420}>
@@ -267,8 +266,11 @@ export default class extends React.Component {
267
266
  </Form.Item>
268
267
  </>
269
268
  )}
270
- <Form.Item label="新密码" name="password" rules={[{required: true, message: '请输入新密码'}]}>
271
- <Input.Password placeholder="请输入新密码"/>
269
+ <Form.Item label="新密码" name="password" rules={[
270
+ {required: true, message: '请输入新密码'},
271
+ {pattern: /^[\x20-\x7E]{1,64}$/, message: '密码仅支持英文、数字与常见符号,长度不超过64位'}
272
+ ]}>
273
+ <Input.Password maxLength={64} placeholder="请输入新密码"/>
272
274
  </Form.Item>
273
275
  </FormModal>
274
276
 
@@ -1,6 +1,6 @@
1
- import {Form, Modal} from 'antd';
1
+ import {Form, Modal, message} from 'antd';
2
2
  import React from 'react';
3
- import {FieldDictSelect, FieldRemoteSelect, FieldSysOrgTree, HttpUtils} from "../../../framework";
3
+ import {FieldDictSelect, FieldRemoteSelect, FieldSysOrgTree, HttpClient} from "../../../framework";
4
4
 
5
5
 
6
6
  export default class UserPerm extends React.Component {
@@ -15,14 +15,14 @@ export default class UserPerm extends React.Component {
15
15
  dataPermType: null
16
16
  },
17
17
  }
18
- formRef = React.createRef()
18
+ formRef = React.createRef() // NOSONAR: React ref,内部通过 this.formRef 使用
19
19
 
20
- show(item) {
20
+ show(item) { // NOSONAR: ref 暴露给父组件调用的公共 API
21
21
  this.setState({visible: true})
22
22
 
23
- HttpUtils.get('admin/sysUser/get-perm-info', {id: item.id}).then(rs => {
24
- this.setState({formValues: rs})
25
- this.formRef.current.setFieldsValue(rs)
23
+ HttpClient.get('admin/sysUser/get-perm-info', {id: item.id}).then(rs => {
24
+ this.setState({formValues: rs.data})
25
+ this.formRef.current.setFieldsValue(rs.data)
26
26
  })
27
27
  }
28
28
 
@@ -34,17 +34,17 @@ export default class UserPerm extends React.Component {
34
34
  })
35
35
 
36
36
 
37
- HttpUtils.post('admin/sysUser/grant-perm', values).then(rs => {
37
+ HttpClient.post('admin/sysUser/grant-perm', values, null, {toastError: false}).then(() => {
38
38
  this.setState({
39
39
  visible: false,
40
40
  confirmLoading: false
41
41
  })
42
42
  this.props.onOk()
43
- }).finally(() => {
43
+ }).catch(e => {
44
+ message.error(HttpClient.errToMsg(e))
44
45
  this.setState({
45
46
  confirmLoading: false
46
47
  })
47
-
48
48
  })
49
49
  }
50
50
 
@@ -77,11 +77,11 @@ export default class UserPerm extends React.Component {
77
77
  </Form.Item>
78
78
 
79
79
 
80
- {this.state.formValues.dataPermType === 'CUSTOM' && <>
80
+ {this.state.formValues.dataPermType === 'CUSTOM' &&
81
81
  <Form.Item label='组织机构' name='orgIds'>
82
82
  <FieldSysOrgTree/>
83
83
  </Form.Item>
84
- </>}
84
+ }
85
85
 
86
86
 
87
87
  </Form>