@jiangood/open-admin 2.0.1 → 2.2.5
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/config/common-plugin.js +51 -0
- package/config/config.js +1 -56
- package/package.json +5 -2
- package/src/.umi-production/appData.json +73 -100
- package/src/.umi-production/umi.ts +2 -2
- package/src/framework/components/DownloadFileButton/index.tsx +1 -1
- package/src/framework/components/OrgTree/index.tsx +1 -1
- package/src/framework/components/Page/index.less +1 -1
- package/src/framework/components/Page/index.tsx +19 -22
- package/src/framework/components/PageLoading/index.tsx +5 -3
- package/src/framework/components/ProModal/index.tsx +2 -2
- package/src/framework/components/ProTable/components/ToolBar/index.tsx +1 -1
- package/src/framework/fields/FieldEditor/index.tsx +3 -2
- package/src/framework/fields/FieldRemoteTreeSelect/index.tsx +3 -3
- package/src/framework/fields/FieldRemoteTreeSelectMultiple/index.tsx +3 -3
- package/src/framework/fields/FieldUploadFile/index.tsx +8 -4
- package/src/framework/utils/MessageUtils.tsx +21 -99
- package/src/framework/utils/system/HttpUtils.ts +5 -1
- package/src/framework/utils/system/SysUtils.ts +8 -0
- package/src/framework/utils/system/ThemeUtils.ts +37 -12
- package/src/framework/views/ViewFile/index.tsx +1 -1
- package/src/framework/views/ViewProcessInstanceProgress/index.tsx +1 -0
- package/src/layouts/PageRender.tsx +29 -0
- package/src/layouts/admin/HeaderRight.jsx +1 -0
- package/src/layouts/admin/TabPageRender.jsx +138 -158
- package/src/layouts/admin/index.jsx +123 -19
- package/src/layouts/admin/index.less +124 -6
- package/src/layouts/index.jsx +94 -161
- package/src/pages/404.jsx +7 -5
- package/src/pages/about.jsx +3 -3
- package/src/pages/index.jsx +4 -5
- package/src/pages/login.jsx +18 -9
- package/src/pages/login.less +0 -1
- package/src/pages/system/dict/index.jsx +8 -11
- package/src/pages/system/file/index.jsx +6 -6
- package/src/pages/system/job/index.jsx +26 -11
- package/src/pages/system/log/index.jsx +4 -5
- package/src/pages/system/manual/index.jsx +8 -6
- package/src/pages/system/org/index.jsx +4 -2
- package/src/pages/system/role/index.jsx +16 -14
- package/src/pages/system/role/perm.jsx +3 -4
- package/src/pages/system/user/UserPerm.jsx +1 -1
- package/src/pages/system/user/index.jsx +9 -7
- package/src/pages/userCenter/index.jsx +2 -2
- package/src/pages/userCenter/message.jsx +4 -2
- package/src/layouts/PageRender.d.ts +0 -22
- package/src/layouts/PageRender.jsx +0 -90
package/src/layouts/index.jsx
CHANGED
|
@@ -1,185 +1,118 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {ConfigProvider} from "antd";
|
|
1
|
+
import {useState, useEffect} from "react";
|
|
2
|
+
import {App, ConfigProvider} from "antd";
|
|
3
3
|
import zhCN from 'antd/locale/zh_CN';
|
|
4
4
|
import dayjs from 'dayjs';
|
|
5
5
|
import 'dayjs/locale/zh-cn';
|
|
6
|
-
import {Outlet,
|
|
6
|
+
import {Outlet, useLocation} from "umi";
|
|
7
7
|
|
|
8
8
|
import AdminLayout from "./admin"
|
|
9
|
-
import {
|
|
10
|
-
ArrayUtils,
|
|
11
|
-
HttpUtils,
|
|
12
|
-
MessageHolder,
|
|
13
|
-
PageLoading,
|
|
14
|
-
PageUtils, StringUtils,
|
|
15
|
-
SysUtils,
|
|
16
|
-
ThemeUtils,
|
|
17
|
-
} from "../framework";
|
|
18
|
-
import {Logger} from "../framework/utils/Logger";
|
|
9
|
+
import {HttpUtils, PageLoading, PageUtils, SysUtils, ThemeUtils} from "../framework";
|
|
19
10
|
|
|
20
11
|
import '../style/global.less'
|
|
21
12
|
import './index.less'
|
|
22
13
|
|
|
23
14
|
dayjs.locale('zh-cn');
|
|
24
15
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
16
|
+
const configProps = {
|
|
17
|
+
input: {autoComplete: 'off'},
|
|
18
|
+
form: {validateMessages: {required: '必填项'}, colon: false},
|
|
19
|
+
button: {autoInsertSpace: false},
|
|
20
|
+
locale: zhCN,
|
|
21
|
+
theme: {
|
|
22
|
+
token: {
|
|
23
|
+
colorPrimary: ThemeUtils.getColor("primary-color"),
|
|
24
|
+
colorSuccess: ThemeUtils.getColor("success-color"),
|
|
25
|
+
colorWarning: ThemeUtils.getColor("warning-color"),
|
|
26
|
+
colorError: ThemeUtils.getColor("error-color"),
|
|
27
|
+
borderRadius: 4,
|
|
28
|
+
},
|
|
29
|
+
components: {
|
|
30
|
+
Menu: {
|
|
31
|
+
darkItemBg: ThemeUtils.getColor("primary-color"),
|
|
32
|
+
darkPopupBg: ThemeUtils.getColor("primary-color"),
|
|
33
|
+
darkItemSelectedBg: ThemeUtils.getColor("primary-color-click"),
|
|
34
|
+
darkItemHoverBg: ThemeUtils.getColor("primary-color-hover"),
|
|
35
|
+
darkSubMenuItemBg: ThemeUtils.getColor("primary-color"),
|
|
36
|
+
},
|
|
37
|
+
Layout: {
|
|
38
|
+
siderBg: ThemeUtils.getColor("primary-color"),
|
|
39
|
+
triggerBg: ThemeUtils.getColor("primary-color-click"),
|
|
40
|
+
headerBg: 'white',
|
|
41
|
+
triggerHeight: 32,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
function AppWrapper({children}) {
|
|
48
|
+
return <ConfigProvider {...configProps}><App>{children}</App></ConfigProvider>;
|
|
37
49
|
}
|
|
38
50
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return false
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
class _Layouts extends React.Component {
|
|
47
|
-
|
|
48
|
-
log = Logger.getLogger('Layouts')
|
|
49
|
-
|
|
50
|
-
state = {
|
|
51
|
-
messageHolderInit:false,
|
|
52
|
-
siteInfoLoading: true,
|
|
53
|
-
loginInfoFinish: false
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
onMessageHolderFinish = () => {
|
|
57
|
-
this.loadSiteInfo()
|
|
58
|
-
this.setState({messageHolderInit:true});
|
|
59
|
-
}
|
|
60
|
-
|
|
51
|
+
const PUBLIC_PAGES = (() => {
|
|
52
|
+
const raw = typeof OPEN_ADMIN_PUBLIC_PAGES !== 'undefined' && OPEN_ADMIN_PUBLIC_PAGES;
|
|
53
|
+
return raw ? raw.split(',').map(s => s.trim()) : ['/login', '/test'];
|
|
54
|
+
})();
|
|
61
55
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
SysUtils.setSiteInfo(rs)
|
|
65
|
-
this.setState({siteInfoLoading: false})
|
|
66
|
-
this.loadLoginInfo()
|
|
67
|
-
})
|
|
68
|
-
};
|
|
56
|
+
function isPublicPage(pathname, search) {
|
|
57
|
+
if (pathname === '/' || pathname === '/index') return false;
|
|
69
58
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (
|
|
74
|
-
|
|
59
|
+
for (const pattern of PUBLIC_PAGES) {
|
|
60
|
+
if (pattern.endsWith('/**')) {
|
|
61
|
+
if (pathname.startsWith(pattern.slice(0, -3))) return true;
|
|
62
|
+
} else if (pathname === pattern) {
|
|
63
|
+
return true;
|
|
75
64
|
}
|
|
76
65
|
}
|
|
77
66
|
|
|
67
|
+
if (new URLSearchParams(search).has('_noLayout')) return true;
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
78
70
|
|
|
71
|
+
export function Layouts() {
|
|
72
|
+
const {pathname, search} = useLocation();
|
|
73
|
+
const [siteInfoLoaded, setSiteInfoLoaded] = useState(false);
|
|
74
|
+
const [loginChecked, setLoginChecked] = useState(false);
|
|
79
75
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (checkIsPurePage(pathname) || checkIsSimplePage(pathname) || this.state.loginInfoFinish) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
HttpUtils.get('/admin/public/check-login')
|
|
87
|
-
.then(rs => {
|
|
88
|
-
const {needUpdatePwd, dictInfo, loginInfo} = rs
|
|
89
|
-
SysUtils.setDictInfo(dictInfo)
|
|
90
|
-
SysUtils.setLoginInfo(loginInfo)
|
|
91
|
-
if (!needUpdatePwd) {
|
|
92
|
-
this.setState({loginInfoFinish: true});
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (needUpdatePwd) {
|
|
97
|
-
PageUtils.open('/userCenter/ChangePassword', '修改密码')
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
.catch(async () => {
|
|
102
|
-
PageUtils.redirectToLogin()
|
|
103
|
-
})
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
render() {
|
|
107
|
-
return <ConfigProvider
|
|
108
|
-
input={{autoComplete: 'off'}}
|
|
109
|
-
form={{
|
|
110
|
-
validateMessages: {
|
|
111
|
-
required: '必填项'
|
|
112
|
-
}, colon: false
|
|
113
|
-
}}
|
|
114
|
-
button={{
|
|
115
|
-
autoInsertSpace: false
|
|
116
|
-
}}
|
|
117
|
-
locale={zhCN}
|
|
118
|
-
theme={{
|
|
119
|
-
token: {
|
|
120
|
-
colorPrimary: ThemeUtils.getColor("primary-color"),
|
|
121
|
-
colorSuccess: ThemeUtils.getColor("success-color"),
|
|
122
|
-
colorWarning: ThemeUtils.getColor("warning-color"),
|
|
123
|
-
colorError: ThemeUtils.getColor("error-color"),
|
|
124
|
-
borderRadius: 4,
|
|
125
|
-
},
|
|
126
|
-
components: {
|
|
127
|
-
Menu: {
|
|
128
|
-
darkItemBg: ThemeUtils.getColor("primary-color"),
|
|
129
|
-
darkPopupBg: ThemeUtils.getColor("primary-color"),
|
|
130
|
-
darkItemSelectedBg: ThemeUtils.getColor("primary-color-click"),
|
|
131
|
-
darkItemHoverBg: ThemeUtils.getColor("primary-color-hover"),
|
|
132
|
-
darkSubMenuItemBg: ThemeUtils.getColor("primary-color")
|
|
133
|
-
},
|
|
134
|
-
Layout: {
|
|
135
|
-
siderBg: ThemeUtils.getColor("primary-color"),
|
|
136
|
-
triggerBg: ThemeUtils.getColor("primary-color-click"),
|
|
137
|
-
headerBg: 'white',
|
|
138
|
-
triggerHeight: 32
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}}>
|
|
142
|
-
|
|
143
|
-
<MessageHolder onFinish={this.onMessageHolderFinish} />
|
|
144
|
-
{this.renderContent()}
|
|
145
|
-
</ConfigProvider>
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
renderContent = () => {
|
|
150
|
-
const {pathname} = this.props.location;
|
|
151
|
-
|
|
152
|
-
if(checkIsPurePage(pathname)){
|
|
153
|
-
return <Outlet/>
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if(!this.state.messageHolderInit) {
|
|
157
|
-
this.log.info('加载message holder...')
|
|
158
|
-
return <PageLoading message='加载消息组件...'/>
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const {params = {}} = this.props.location;
|
|
162
|
-
if (checkIsSimplePage(pathname) || params.hasOwnProperty('_noLayout')) {
|
|
163
|
-
return <Outlet/>
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
if (this.state.siteInfoLoading) {
|
|
169
|
-
return <PageLoading message='加载站点信息...'/>
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
|
|
76
|
+
const ready = siteInfoLoaded && loginChecked;
|
|
77
|
+
const isPublic = isPublicPage(pathname, search);
|
|
173
78
|
|
|
174
|
-
|
|
175
|
-
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (isPublic) {
|
|
81
|
+
setSiteInfoLoaded(false);
|
|
82
|
+
setLoginChecked(false);
|
|
83
|
+
return;
|
|
176
84
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
85
|
+
if (ready) return;
|
|
86
|
+
|
|
87
|
+
Promise.all([
|
|
88
|
+
HttpUtils.get("/admin/public/site-info").then(data => {
|
|
89
|
+
SysUtils.setSiteInfo(data);
|
|
90
|
+
setSiteInfoLoaded(true);
|
|
91
|
+
}),
|
|
92
|
+
HttpUtils.get('/admin/public/check-login').then(data => {
|
|
93
|
+
SysUtils.setDictInfo(data.dictInfo);
|
|
94
|
+
SysUtils.setLoginInfo(data.loginInfo);
|
|
95
|
+
setLoginChecked(true);
|
|
96
|
+
}),
|
|
97
|
+
]).catch(() => {
|
|
98
|
+
console.error('[Layout] 初始化应用失败');
|
|
99
|
+
PageUtils.redirectToLogin();
|
|
100
|
+
});
|
|
101
|
+
}, [pathname]);
|
|
102
|
+
|
|
103
|
+
if (isPublic) return <AppWrapper><Outlet/></AppWrapper>;
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<AppWrapper>
|
|
107
|
+
{ready ? <AdminLayout/> : (
|
|
108
|
+
<PageLoading messages={[
|
|
109
|
+
!siteInfoLoaded && '加载站点信息...',
|
|
110
|
+
!loginChecked && '检查登录中...',
|
|
111
|
+
].filter(Boolean)}/>
|
|
112
|
+
)}
|
|
113
|
+
</AppWrapper>
|
|
114
|
+
);
|
|
180
115
|
}
|
|
181
116
|
|
|
182
|
-
|
|
183
|
-
export
|
|
184
|
-
export default Layouts
|
|
185
|
-
export * from './PageRender'
|
|
117
|
+
export default Layouts;
|
|
118
|
+
export * from './PageRender'
|
package/src/pages/404.jsx
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import {Result} from "antd";
|
|
3
|
+
import {Page} from "../framework";
|
|
3
4
|
|
|
4
5
|
export default class extends React.Component {
|
|
5
6
|
|
|
6
7
|
render() {
|
|
7
|
-
return <
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
return <Page>
|
|
9
|
+
<Result
|
|
10
|
+
status={404}
|
|
11
|
+
title='页面不存在'
|
|
12
|
+
/>
|
|
13
|
+
</Page>
|
|
12
14
|
}
|
|
13
15
|
}
|
package/src/pages/about.jsx
CHANGED
package/src/pages/index.jsx
CHANGED
package/src/pages/login.jsx
CHANGED
|
@@ -24,6 +24,7 @@ function postLogin(values) {
|
|
|
24
24
|
history.push(getRedirect())
|
|
25
25
|
resolve(rs)
|
|
26
26
|
}).catch(e => {
|
|
27
|
+
console.error('[Login] 登录失败:', e);
|
|
27
28
|
reject(e)
|
|
28
29
|
})
|
|
29
30
|
})
|
|
@@ -38,14 +39,20 @@ export default class extends React.Component {
|
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
async componentDidMount() {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
const siteInfo = SysUtils.getSiteInfo()
|
|
43
|
+
if (siteInfo && siteInfo.rsaPublicKey) {
|
|
44
|
+
this.setState({siteInfo})
|
|
44
45
|
return
|
|
45
46
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
// localStorage 中无站点信息,从服务端重新加载
|
|
48
|
+
try {
|
|
49
|
+
const rs = await HttpUtils.get('/admin/public/site-info')
|
|
50
|
+
SysUtils.setSiteInfo(rs)
|
|
51
|
+
this.setState({siteInfo: rs})
|
|
52
|
+
} catch (e) {
|
|
53
|
+
console.error('[Login] 加载站点信息失败:', e);
|
|
54
|
+
message.error('加载站点信息失败,请刷新页面重试')
|
|
55
|
+
}
|
|
49
56
|
}
|
|
50
57
|
|
|
51
58
|
submit = values => {
|
|
@@ -69,9 +76,11 @@ export default class extends React.Component {
|
|
|
69
76
|
render() {
|
|
70
77
|
const {siteInfo} = this.state
|
|
71
78
|
|
|
72
|
-
const pageStyle = {
|
|
79
|
+
const pageStyle = {
|
|
80
|
+
backgroundImage: `url("${SysUtils.contextPath('/admin/public/login_bg.jpg')}")`
|
|
81
|
+
}
|
|
73
82
|
if (siteInfo.loginBackground) {
|
|
74
|
-
const url = 'admin/sysFile/preview/' + siteInfo.loginBackground;
|
|
83
|
+
const url = SysUtils.contextPath('/admin/sysFile/preview/' + siteInfo.loginBackground);
|
|
75
84
|
pageStyle.backgroundImage = 'url("' + url + '")'
|
|
76
85
|
}
|
|
77
86
|
|
|
@@ -110,7 +119,7 @@ export default class extends React.Component {
|
|
|
110
119
|
<Space style={{alignItems: 'center'}}>
|
|
111
120
|
<Input size='large' placeholder='验证码' prefix={<SafetyCertificateOutlined/>}/>
|
|
112
121
|
<img height={36} width={100}
|
|
113
|
-
src={"/admin/auth/captcha-image?_random=" + this.state.random}
|
|
122
|
+
src={SysUtils.contextPath("/admin/auth/captcha-image?_random=" + this.state.random)}
|
|
114
123
|
onClick={() => this.setState({random: Math.random()})}/>
|
|
115
124
|
</Space>
|
|
116
125
|
</Form.Item>
|
package/src/pages/login.less
CHANGED
|
@@ -33,7 +33,9 @@ export default class extends React.Component {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
onFinish = values => {
|
|
36
|
-
|
|
36
|
+
const isNew = !values.id;
|
|
37
|
+
const url = isNew ? 'admin/dict/create' : 'admin/dict/update';
|
|
38
|
+
HttpUtils.post(url, values).then(rs => {
|
|
37
39
|
this.setState({formOpen: false})
|
|
38
40
|
this.tableRef.current.reload()
|
|
39
41
|
})
|
|
@@ -90,15 +92,11 @@ export default class extends React.Component {
|
|
|
90
92
|
title: '操作',
|
|
91
93
|
dataIndex: 'option',
|
|
92
94
|
render: (_, record) => {
|
|
93
|
-
if(!record.id){ // 非数据库定义的不让修改
|
|
94
|
-
return
|
|
95
|
-
}
|
|
96
|
-
|
|
97
95
|
return (
|
|
98
96
|
<ButtonList>
|
|
99
|
-
<Button size='small' perm='
|
|
97
|
+
<Button size='small' perm='sys-dict:update'
|
|
100
98
|
onClick={() => this.handleEdit(record)}> 编辑 </Button>
|
|
101
|
-
<Popconfirm perm='
|
|
99
|
+
<Popconfirm perm='sys-dict:delete' title='是否确定删除字典项'
|
|
102
100
|
onConfirm={() => this.handleDelete(record)}>
|
|
103
101
|
<Button size='small'>删除</Button>
|
|
104
102
|
</Popconfirm>
|
|
@@ -109,13 +107,13 @@ export default class extends React.Component {
|
|
|
109
107
|
]
|
|
110
108
|
|
|
111
109
|
render() {
|
|
112
|
-
return <Page
|
|
110
|
+
return <Page>
|
|
113
111
|
<ProTable
|
|
114
112
|
rowKey='uid'
|
|
115
113
|
actionRef={this.tableRef}
|
|
116
114
|
toolBarRender={() => {
|
|
117
115
|
return <ButtonList>
|
|
118
|
-
<Button perm='
|
|
116
|
+
<Button perm='sys-dict:create' type='primary' onClick={this.handleAdd} >
|
|
119
117
|
<PlusOutlined/> 新增
|
|
120
118
|
</Button>
|
|
121
119
|
</ButtonList>
|
|
@@ -126,14 +124,13 @@ export default class extends React.Component {
|
|
|
126
124
|
}}
|
|
127
125
|
columns={this.columns}
|
|
128
126
|
showToolbarSearch={true}
|
|
129
|
-
scrollY={500}
|
|
130
127
|
/>
|
|
131
128
|
<Modal
|
|
132
129
|
title='编辑数据字典项'
|
|
133
130
|
open={this.state.formOpen}
|
|
134
131
|
onOk={() => this.formRef.current.submit()}
|
|
135
132
|
onCancel={() => this.setState({formOpen: false})}
|
|
136
|
-
|
|
133
|
+
destroyOnHidden
|
|
137
134
|
>
|
|
138
135
|
|
|
139
136
|
<Form ref={this.formRef} labelCol={{flex: '100px'}}
|
|
@@ -2,7 +2,7 @@ import React from 'react'
|
|
|
2
2
|
import {Button, Form, Input, Modal, Popconfirm} from 'antd'
|
|
3
3
|
import {CloudUploadOutlined} from "@ant-design/icons";
|
|
4
4
|
|
|
5
|
-
import {ButtonList, FieldDateRange, FieldDictSelect, FieldUploadFile, HttpUtils, ProTable} from "../../../framework";
|
|
5
|
+
import {ButtonList, FieldDateRange, FieldDictSelect, FieldUploadFile, HttpUtils, Page, ProTable, SysUtils} from "../../../framework";
|
|
6
6
|
|
|
7
7
|
export default class extends React.Component {
|
|
8
8
|
|
|
@@ -59,7 +59,7 @@ export default class extends React.Component {
|
|
|
59
59
|
title: '预览',
|
|
60
60
|
dataIndex: 'id',
|
|
61
61
|
render(id, record) {
|
|
62
|
-
const nodes = [<a href={'/admin/sysFile/preview/' + record.id} target='_blank'>预览</a>]
|
|
62
|
+
const nodes = [<a href={SysUtils.contextPath('/admin/sysFile/preview/' + record.id)} target='_blank'>预览</a>]
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
if (record.imageUrls?.length > 0) {
|
|
@@ -79,7 +79,7 @@ export default class extends React.Component {
|
|
|
79
79
|
dataIndex: 'option',
|
|
80
80
|
render: (_, record) => (
|
|
81
81
|
<ButtonList>
|
|
82
|
-
<Popconfirm perm='
|
|
82
|
+
<Popconfirm perm='sys-file:delete' title='是否确定删除文件信息'
|
|
83
83
|
onConfirm={() => this.handleDelete(record)}>
|
|
84
84
|
<a>删除</a>
|
|
85
85
|
</Popconfirm>
|
|
@@ -89,7 +89,7 @@ export default class extends React.Component {
|
|
|
89
89
|
]
|
|
90
90
|
|
|
91
91
|
render() {
|
|
92
|
-
return
|
|
92
|
+
return <Page>
|
|
93
93
|
<ProTable
|
|
94
94
|
actionRef={this.tableRef}
|
|
95
95
|
toolBarRender={() => {
|
|
@@ -127,7 +127,7 @@ export default class extends React.Component {
|
|
|
127
127
|
this.tableRef.current.reload()
|
|
128
128
|
}}
|
|
129
129
|
footer={null}
|
|
130
|
-
|
|
130
|
+
destroyOnHidden
|
|
131
131
|
>
|
|
132
132
|
<Form ref={this.formRef}
|
|
133
133
|
initialValues={this.state.formValues}
|
|
@@ -140,7 +140,7 @@ export default class extends React.Component {
|
|
|
140
140
|
</Form>
|
|
141
141
|
</Modal>
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
</Page>
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
} from 'antd'
|
|
17
17
|
import {PlusOutlined} from "@ant-design/icons";
|
|
18
18
|
|
|
19
|
-
import {ButtonList, HttpUtils, Page, ProTable, StringUtils, ValueType} from "../../../framework";
|
|
19
|
+
import {ButtonList, HttpUtils, Page, ProTable, StringUtils, SysUtils, ValueType} from "../../../framework";
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
const cronOptions = [
|
|
@@ -66,6 +66,8 @@ export default class extends React.Component {
|
|
|
66
66
|
componentDidMount() {
|
|
67
67
|
HttpUtils.get('admin/job/job-class-options').then(rs => {
|
|
68
68
|
this.setState({jobClassOptions: rs})
|
|
69
|
+
}).catch(e => {
|
|
70
|
+
console.error('[Job] 加载作业类选项失败:', e);
|
|
69
71
|
})
|
|
70
72
|
}
|
|
71
73
|
|
|
@@ -81,13 +83,19 @@ export default class extends React.Component {
|
|
|
81
83
|
loadJobParamFields(className, jobData) {
|
|
82
84
|
HttpUtils.post("admin/job/get-job-param-fields", jobData || {}, {className}).then(rs => {
|
|
83
85
|
this.setState({paramList: rs})
|
|
86
|
+
}).catch(e => {
|
|
87
|
+
console.error('[Job] 加载作业参数字段失败:', e);
|
|
84
88
|
})
|
|
85
89
|
}
|
|
86
90
|
|
|
87
91
|
onFinish = (values) => {
|
|
88
|
-
|
|
92
|
+
const isNew = !values.id;
|
|
93
|
+
const url = isNew ? 'admin/job/create' : 'admin/job/update';
|
|
94
|
+
HttpUtils.post(url, values).then(rs => {
|
|
89
95
|
this.setState({formOpen: false})
|
|
90
96
|
this.tableRef.current.reload();
|
|
97
|
+
}).catch(e => {
|
|
98
|
+
console.error('[Job] 保存作业失败:', e);
|
|
91
99
|
})
|
|
92
100
|
}
|
|
93
101
|
|
|
@@ -95,12 +103,17 @@ export default class extends React.Component {
|
|
|
95
103
|
const hide = message.loading("删除作业中...")
|
|
96
104
|
HttpUtils.post('admin/job/delete', {id: row.id}).then(rs => {
|
|
97
105
|
this.tableRef.current.reload();
|
|
98
|
-
}).catch(
|
|
106
|
+
}).catch(e => {
|
|
107
|
+
console.error('[Job] 删除作业失败:', e);
|
|
108
|
+
hide();
|
|
109
|
+
})
|
|
99
110
|
}
|
|
100
111
|
|
|
101
112
|
handleTriggerJob = row => {
|
|
102
113
|
HttpUtils.get('admin/job/trigger-job', {id: row.id}).then(rs => {
|
|
103
114
|
this.tableRef.current.reload();
|
|
115
|
+
}).catch(e => {
|
|
116
|
+
console.error('[Job] 触发作业失败:', e);
|
|
104
117
|
})
|
|
105
118
|
}
|
|
106
119
|
|
|
@@ -149,9 +162,9 @@ export default class extends React.Component {
|
|
|
149
162
|
return (
|
|
150
163
|
<Space>
|
|
151
164
|
<Button size='small' onClick={() => this.showExecuteRecord(record)}>执行记录</Button>
|
|
152
|
-
<Button size='small' onClick={() => this.handleTriggerJob(record)}>执行一次</Button>
|
|
153
|
-
<Button size='small' onClick={() => this.handleEdit(record)}> 编辑 </Button>
|
|
154
|
-
<Popconfirm title='是否确定删除?' onConfirm={() => this.handleDelete(record)}>
|
|
165
|
+
<Button size='small' perm='job:trigger' onClick={() => this.handleTriggerJob(record)}>执行一次</Button>
|
|
166
|
+
<Button size='small' perm='job:update' onClick={() => this.handleEdit(record)}> 编辑 </Button>
|
|
167
|
+
<Popconfirm perm='job:delete' title='是否确定删除?' onConfirm={() => this.handleDelete(record)}>
|
|
155
168
|
<Button size='small'>删除</Button>
|
|
156
169
|
</Popconfirm>
|
|
157
170
|
</Space>
|
|
@@ -165,6 +178,8 @@ export default class extends React.Component {
|
|
|
165
178
|
this.setState({statusOpen: true})
|
|
166
179
|
HttpUtils.get('admin/job/status').then(rs => {
|
|
167
180
|
this.setState({status: rs})
|
|
181
|
+
}).catch(e => {
|
|
182
|
+
console.error('[Job] 加载状态失败:', e);
|
|
168
183
|
})
|
|
169
184
|
};
|
|
170
185
|
|
|
@@ -174,7 +189,7 @@ export default class extends React.Component {
|
|
|
174
189
|
|
|
175
190
|
|
|
176
191
|
render() {
|
|
177
|
-
return <Page
|
|
192
|
+
return <Page>
|
|
178
193
|
<ProTable
|
|
179
194
|
actionRef={this.tableRef}
|
|
180
195
|
toolBarRender={() => {
|
|
@@ -195,7 +210,7 @@ export default class extends React.Component {
|
|
|
195
210
|
|
|
196
211
|
<Modal title='作业调度'
|
|
197
212
|
open={this.state.formOpen}
|
|
198
|
-
|
|
213
|
+
destroyOnHidden
|
|
199
214
|
width={800}
|
|
200
215
|
onOk={() => this.formRef.current.submit()}
|
|
201
216
|
onCancel={() => this.setState({formOpen: false})}
|
|
@@ -245,7 +260,7 @@ export default class extends React.Component {
|
|
|
245
260
|
footer={null}
|
|
246
261
|
width={1024}
|
|
247
262
|
>
|
|
248
|
-
<Alert
|
|
263
|
+
<Alert title={<pre>{this.state.status}</pre>}></Alert>
|
|
249
264
|
|
|
250
265
|
</Modal>
|
|
251
266
|
|
|
@@ -254,7 +269,7 @@ export default class extends React.Component {
|
|
|
254
269
|
onCancel={() => this.setState({executeRecordOpen: false})}
|
|
255
270
|
footer={null}
|
|
256
271
|
width={1024}
|
|
257
|
-
|
|
272
|
+
destroyOnHidden
|
|
258
273
|
>
|
|
259
274
|
<ProTable columns={[{
|
|
260
275
|
title: '开始时间',
|
|
@@ -289,7 +304,7 @@ export default class extends React.Component {
|
|
|
289
304
|
title: '操作',
|
|
290
305
|
dataIndex: 'option',
|
|
291
306
|
render: (_, record) => {
|
|
292
|
-
const url = '/admin/sys/log/' + record.id;
|
|
307
|
+
const url = SysUtils.contextPath('/admin/sys/log/' + record.id);
|
|
293
308
|
return <a href={url} target='_blank'>日志</a>;
|
|
294
309
|
},
|
|
295
310
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import {Form, Input, Tag} from "antd";
|
|
3
|
-
import {ViewText, FieldDateRange, HttpUtils, ProTable} from "../../../framework";
|
|
3
|
+
import {ViewText, FieldDateRange, HttpUtils, Page, ProTable} from "../../../framework";
|
|
4
4
|
|
|
5
5
|
export default class extends React.Component {
|
|
6
6
|
|
|
@@ -54,7 +54,7 @@ export default class extends React.Component {
|
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
render() {
|
|
57
|
-
return
|
|
57
|
+
return <Page>
|
|
58
58
|
<ProTable
|
|
59
59
|
request={(params) => HttpUtils.get('admin/sysLog/page', params)}
|
|
60
60
|
columns={this.columns}
|
|
@@ -66,8 +66,7 @@ export default class extends React.Component {
|
|
|
66
66
|
<FieldDateRange/>
|
|
67
67
|
</Form.Item>
|
|
68
68
|
</ProTable>
|
|
69
|
-
|
|
70
|
-
</>
|
|
69
|
+
</Page>
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
|