@jiangood/open-admin 2.2.4 → 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 -51
- package/package.json +1 -2
- package/src/.umi-production/appData.json +60 -72
- package/src/framework/components/DownloadFileButton/index.tsx +1 -1
- package/src/framework/components/OrgTree/index.tsx +1 -1
- 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/FieldRemoteTreeSelect/index.tsx +3 -3
- package/src/framework/fields/FieldRemoteTreeSelectMultiple/index.tsx +3 -3
- package/src/framework/utils/system/HttpUtils.ts +3 -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.jsx → PageRender.tsx} +6 -5
- package/src/layouts/admin/HeaderRight.jsx +1 -0
- package/src/layouts/admin/index.jsx +3 -2
- package/src/layouts/admin/index.less +6 -6
- package/src/layouts/index.jsx +59 -43
- package/src/pages/login.jsx +2 -0
- package/src/pages/system/dict/index.jsx +1 -1
- package/src/pages/system/file/index.jsx +1 -1
- package/src/pages/system/job/index.jsx +17 -4
- package/src/pages/system/manual/index.jsx +2 -2
- package/src/pages/system/role/index.jsx +7 -7
- package/src/pages/system/user/UserPerm.jsx +1 -1
- package/src/pages/system/user/index.jsx +1 -1
- package/src/pages/userCenter/index.jsx +1 -1
- package/src/layouts/PageRender.d.ts +0 -7
|
@@ -25,7 +25,7 @@ export class DownloadFileButton extends React.Component {
|
|
|
25
25
|
|
|
26
26
|
return <> <Button {...rest}>{children}</Button>
|
|
27
27
|
|
|
28
|
-
<Modal title='提示' footer={null} onCancel={()=>{this.setState({open:false})}}
|
|
28
|
+
<Modal title='提示' footer={null} mask={{closable: false}} onCancel={()=>{this.setState({open:false})}}>
|
|
29
29
|
<Spin /> 下载文件中,请勿关闭浏览器
|
|
30
30
|
</Modal>
|
|
31
31
|
</>
|
|
@@ -2,8 +2,8 @@ import React from "react";
|
|
|
2
2
|
import {Alert, Spin} from "antd";
|
|
3
3
|
import {ThemeUtils} from "../../utils";
|
|
4
4
|
|
|
5
|
-
export function PageLoading(props: { message?: string }) {
|
|
6
|
-
const
|
|
5
|
+
export function PageLoading(props: { message?: string; messages?: string[] }) {
|
|
6
|
+
const titles = props.messages || (props.message ? [props.message] : ['页面加载中...']);
|
|
7
7
|
|
|
8
8
|
return <div style={{
|
|
9
9
|
height: '100vh', width: '100%',
|
|
@@ -15,7 +15,9 @@ export function PageLoading(props: { message?: string }) {
|
|
|
15
15
|
<Spin size={"large"}></Spin>
|
|
16
16
|
</div>
|
|
17
17
|
<div style={{marginTop: '1rem'}}>
|
|
18
|
-
|
|
18
|
+
{titles.map((msg, i) => (
|
|
19
|
+
<Alert key={i} message={msg} type="info" showIcon style={{marginBottom: i < titles.length - 1 ? 8 : 0}} />
|
|
20
|
+
))}
|
|
19
21
|
</div>
|
|
20
22
|
</div>
|
|
21
23
|
</div>;
|
|
@@ -51,8 +51,8 @@ export class ProModal extends React.Component<ProModalProps, any> {
|
|
|
51
51
|
render() {
|
|
52
52
|
return (
|
|
53
53
|
<Modal
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
mask={{ closable: false }}
|
|
55
|
+
destroyOnHidden
|
|
56
56
|
title={this.props.title}
|
|
57
57
|
open={this.state.visible}
|
|
58
58
|
onCancel={this.hide}
|
|
@@ -23,14 +23,14 @@ export class FieldRemoteTreeSelect extends BaseRemoteSelect {
|
|
|
23
23
|
<TreeSelect
|
|
24
24
|
style={{ width: '100%', minWidth: 200 }}
|
|
25
25
|
allowClear
|
|
26
|
-
|
|
26
|
+
styles={{ popup: { root: { maxHeight: 400, overflow: 'auto' } } }}
|
|
27
27
|
treeData={data}
|
|
28
28
|
showCheckedStrategy={TreeSelect.SHOW_ALL}
|
|
29
29
|
value={value || undefined}
|
|
30
30
|
onChange={onChange}
|
|
31
|
-
|
|
31
|
+
showSearch={{ filterTreeNode: (inputValue, treeNode) =>
|
|
32
32
|
StringUtils.contains(treeNode.title, inputValue)
|
|
33
|
-
}
|
|
33
|
+
}}
|
|
34
34
|
treeLine={{ showLeafIcon: true }}
|
|
35
35
|
treeDefaultExpandAll={treeDefaultExpandAll}
|
|
36
36
|
/>
|
|
@@ -26,15 +26,15 @@ export class FieldRemoteTreeSelectMultiple extends BaseRemoteSelect {
|
|
|
26
26
|
<TreeSelect
|
|
27
27
|
style={style}
|
|
28
28
|
allowClear
|
|
29
|
-
|
|
29
|
+
styles={{ popup: { root: { maxHeight: 400, overflow: 'auto' } } }}
|
|
30
30
|
treeData={data}
|
|
31
31
|
showCheckedStrategy={TreeSelect.SHOW_ALL}
|
|
32
32
|
value={value || undefined}
|
|
33
33
|
onChange={onChange}
|
|
34
34
|
multiple
|
|
35
|
-
|
|
35
|
+
showSearch={{ filterTreeNode: (inputValue, treeNode) =>
|
|
36
36
|
StringUtils.contains(treeNode.title, inputValue)
|
|
37
|
-
}
|
|
37
|
+
}}
|
|
38
38
|
treeLine={{ showLeafIcon: true }}
|
|
39
39
|
treeDefaultExpandAll={treeDefaultExpandAll}
|
|
40
40
|
/>
|
|
@@ -46,6 +46,7 @@ export class HttpUtils {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
if (!success) {
|
|
49
|
+
console.error(`[HttpUtils] 请求失败: ${url}`, {code: body.code, message, data: body});
|
|
49
50
|
MessageUtils.error(message || '操作失败');
|
|
50
51
|
reject('操作失败');
|
|
51
52
|
return
|
|
@@ -58,6 +59,7 @@ export class HttpUtils {
|
|
|
58
59
|
resolve(transformData ? data : response);
|
|
59
60
|
}).catch((e: unknown) => {
|
|
60
61
|
// 统一异常处理
|
|
62
|
+
console.error(`[HttpUtils] 请求异常: ${url}`, e);
|
|
61
63
|
let msg = '操作失败';
|
|
62
64
|
|
|
63
65
|
if (axios.isAxiosError(e)) {
|
|
@@ -239,6 +241,7 @@ export class HttpUtils {
|
|
|
239
241
|
const response = await HttpUtils.coreRequest(downloadConfig, false) as AxiosResponse;
|
|
240
242
|
await HttpUtils.handleDownloadBlob(response);
|
|
241
243
|
} catch (error) {
|
|
244
|
+
console.error('[HttpUtils] 下载文件失败:', error);
|
|
242
245
|
// coreRequest已经处理了401、504和通用的错误提示
|
|
243
246
|
return Promise.reject(error);
|
|
244
247
|
}
|
|
@@ -1,25 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {ColorsUtils} from '../ColorsUtils';
|
|
2
|
+
|
|
3
|
+
declare const OPEN_ADMIN_THEME: Record<string, string> | undefined;
|
|
4
|
+
|
|
4
5
|
export class ThemeUtils {
|
|
5
|
-
|
|
6
|
-
public static readonly theme = {
|
|
6
|
+
private static readonly defaultTheme: Record<string, string> = {
|
|
7
7
|
"primary-color": "#1961AC",
|
|
8
8
|
"success-color": "#52c41a",
|
|
9
9
|
"warning-color": "#faad14",
|
|
10
10
|
"error-color": "#ff4d4f",
|
|
11
11
|
"background-color": "#f5f5f5",
|
|
12
|
-
|
|
13
12
|
"primary-color-hover": "#4990CD",
|
|
14
13
|
"primary-color-click": "#124B93"
|
|
15
14
|
};
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
private static cachedTheme: Record<string, string> | null = null;
|
|
17
|
+
|
|
18
|
+
static get theme(): Record<string, string> {
|
|
19
|
+
if (this.cachedTheme) return this.cachedTheme;
|
|
20
|
+
this.cachedTheme = this.loadTheme();
|
|
21
|
+
return this.cachedTheme;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
private static loadTheme(): Record<string, string> {
|
|
25
|
+
let custom: Record<string, string> = {};
|
|
26
|
+
try {
|
|
27
|
+
if (typeof OPEN_ADMIN_THEME !== 'undefined' && OPEN_ADMIN_THEME) {
|
|
28
|
+
custom = OPEN_ADMIN_THEME;
|
|
29
|
+
}
|
|
30
|
+
} catch {}
|
|
31
|
+
|
|
32
|
+
const result = {...this.defaultTheme, ...custom};
|
|
33
|
+
|
|
34
|
+
// Auto-derive hover/click from primary if not explicitly set
|
|
35
|
+
if (custom["primary-color"]) {
|
|
36
|
+
if (!custom["primary-color-hover"]) {
|
|
37
|
+
result["primary-color-hover"] = ColorsUtils.lighten(result["primary-color"], 20);
|
|
38
|
+
}
|
|
39
|
+
if (!custom["primary-color-click"]) {
|
|
40
|
+
result["primary-color-click"] = ColorsUtils.lighten(result["primary-color"], -10);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public static getColor(key: string): string | undefined {
|
|
23
48
|
return ThemeUtils.theme[key];
|
|
24
49
|
}
|
|
25
50
|
}
|
|
@@ -32,6 +32,7 @@ export class ViewProcessInstanceProgress extends React.Component {
|
|
|
32
32
|
this.setState(rs)
|
|
33
33
|
this.setState({data: rs})
|
|
34
34
|
}).catch(e => {
|
|
35
|
+
console.error('[ViewProcessInstanceProgress] 加载流程实例失败:', e);
|
|
35
36
|
this.setState({errorMsg: e})
|
|
36
37
|
}).finally(() => {
|
|
37
38
|
this.setState({loading: false})
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import {matchRoutes, useAppData} from "umi";
|
|
2
|
-
import React from "react";
|
|
3
2
|
import {Result} from "antd";
|
|
4
3
|
|
|
4
|
+
interface PageRenderProps {
|
|
5
|
+
pathname: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
5
8
|
/**
|
|
6
9
|
* 通过指定 pathname 渲染页面
|
|
7
|
-
* @param {object} props
|
|
8
|
-
* @param {string} props.pathname - 路径 如 /flowable/task/form
|
|
9
10
|
*/
|
|
10
|
-
export function PageRender({pathname}) {
|
|
11
|
+
export function PageRender({pathname}: PageRenderProps) {
|
|
11
12
|
const appData = useAppData()
|
|
12
13
|
const matchArr = matchRoutes(appData.clientRoutes, pathname)
|
|
13
14
|
|
|
@@ -25,4 +26,4 @@ export function PageRender({pathname}) {
|
|
|
25
26
|
subTitle={<div>路由地址:{pathname}</div>}
|
|
26
27
|
/>
|
|
27
28
|
)
|
|
28
|
-
}
|
|
29
|
+
}
|
|
@@ -27,6 +27,7 @@ export class HeaderRight extends React.Component {
|
|
|
27
27
|
await MessageUtils.alert('退出登录成功');
|
|
28
28
|
history.replace('/login')
|
|
29
29
|
}).catch(async e => {
|
|
30
|
+
console.error('[HeaderRight] 退出登录失败:', e);
|
|
30
31
|
const confirm = await MessageUtils.confirm('退出登录失败,是否清空缓存');
|
|
31
32
|
if (confirm) {
|
|
32
33
|
localStorage.clear();
|
|
@@ -197,7 +197,8 @@ export default class extends React.Component {
|
|
|
197
197
|
menu.icon = <Badge dot count={rs} size={"small"}>{menu.icon}</Badge>
|
|
198
198
|
this.setState({menuTree: [...menuTree]})
|
|
199
199
|
}
|
|
200
|
-
|
|
200
|
+
}).catch(e => {
|
|
201
|
+
console.error('[Layout] 加载消息数失败:', e);
|
|
201
202
|
})
|
|
202
203
|
}
|
|
203
204
|
};
|
|
@@ -206,7 +207,7 @@ export default class extends React.Component {
|
|
|
206
207
|
render() {
|
|
207
208
|
const {siteInfo, loginInfo} = this.state
|
|
208
209
|
|
|
209
|
-
return <Layout className='main-layout'>
|
|
210
|
+
return <Layout className='main-layout' style={{'--primary-color': ThemeUtils.getColor("primary-color"), '--primary-color-click': ThemeUtils.getColor("primary-color-click")}}>
|
|
210
211
|
<Header className='header'>
|
|
211
212
|
<div className='header-left'>
|
|
212
213
|
{siteInfo.showLogo !== false && siteInfo.logoUrl &&
|
|
@@ -42,12 +42,12 @@
|
|
|
42
42
|
white-space: nowrap;
|
|
43
43
|
|
|
44
44
|
&:hover {
|
|
45
|
-
color: #1961AC;
|
|
45
|
+
color: var(--primary-color, var(--primary-color, #1961AC));
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
&.active {
|
|
49
|
-
color: #1961AC;
|
|
50
|
-
box-shadow: inset 0 -2px 0 #1961AC;
|
|
49
|
+
color: var(--primary-color, var(--primary-color, #1961AC));
|
|
50
|
+
box-shadow: inset 0 -2px 0 var(--primary-color, var(--primary-color, #1961AC));
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
cursor: pointer;
|
|
64
64
|
|
|
65
65
|
&:hover {
|
|
66
|
-
background: #
|
|
66
|
+
background: var(--primary-color-click, #124B93);
|
|
67
67
|
color: white;
|
|
68
68
|
}
|
|
69
69
|
}
|
|
@@ -134,11 +134,11 @@
|
|
|
134
134
|
flex-shrink: 0;
|
|
135
135
|
|
|
136
136
|
&:hover {
|
|
137
|
-
color: #1961AC;
|
|
137
|
+
color: var(--primary-color, #1961AC);
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
&.active {
|
|
141
|
-
color: #1961AC;
|
|
141
|
+
color: var(--primary-color, #1961AC);
|
|
142
142
|
background: #fff;
|
|
143
143
|
font-weight: 500;
|
|
144
144
|
}
|
package/src/layouts/index.jsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {useState, useEffect} from "react";
|
|
2
2
|
import {App, ConfigProvider} from "antd";
|
|
3
3
|
import zhCN from 'antd/locale/zh_CN';
|
|
4
4
|
import dayjs from 'dayjs';
|
|
@@ -13,17 +13,6 @@ import './index.less'
|
|
|
13
13
|
|
|
14
14
|
dayjs.locale('zh-cn');
|
|
15
15
|
|
|
16
|
-
// 不需要登录和布局的页面
|
|
17
|
-
const PUBLIC_PAGES = ['/login', '/test']
|
|
18
|
-
|
|
19
|
-
function isPublicPage(pathname, search) {
|
|
20
|
-
if (pathname === '/' || pathname === '/index') return false;
|
|
21
|
-
if (pathname.startsWith("/test/")) return true;
|
|
22
|
-
if (PUBLIC_PAGES.includes(pathname)) return true;
|
|
23
|
-
if (search && new URLSearchParams(search).has('_noLayout')) return true;
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
16
|
const configProps = {
|
|
28
17
|
input: {autoComplete: 'off'},
|
|
29
18
|
form: {validateMessages: {required: '必填项'}, colon: false},
|
|
@@ -55,47 +44,74 @@ const configProps = {
|
|
|
55
44
|
},
|
|
56
45
|
};
|
|
57
46
|
|
|
58
|
-
function
|
|
59
|
-
return
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
47
|
+
function AppWrapper({children}) {
|
|
48
|
+
return <ConfigProvider {...configProps}><App>{children}</App></ConfigProvider>;
|
|
49
|
+
}
|
|
50
|
+
|
|
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
|
+
})();
|
|
55
|
+
|
|
56
|
+
function isPublicPage(pathname, search) {
|
|
57
|
+
if (pathname === '/' || pathname === '/index') return false;
|
|
58
|
+
|
|
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;
|
|
70
64
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (new URLSearchParams(search).has('_noLayout')) return true;
|
|
68
|
+
return false;
|
|
76
69
|
}
|
|
77
70
|
|
|
78
71
|
export function Layouts() {
|
|
79
72
|
const {pathname, search} = useLocation();
|
|
80
|
-
const [
|
|
81
|
-
const
|
|
73
|
+
const [siteInfoLoaded, setSiteInfoLoaded] = useState(false);
|
|
74
|
+
const [loginChecked, setLoginChecked] = useState(false);
|
|
75
|
+
|
|
76
|
+
const ready = siteInfoLoaded && loginChecked;
|
|
77
|
+
const isPublic = isPublicPage(pathname, search);
|
|
82
78
|
|
|
83
79
|
useEffect(() => {
|
|
84
|
-
if (
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
80
|
+
if (isPublic) {
|
|
81
|
+
setSiteInfoLoaded(false);
|
|
82
|
+
setLoginChecked(false);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (ready) return;
|
|
89
86
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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]);
|
|
93
102
|
|
|
94
|
-
if (
|
|
95
|
-
return <ConfigProvider {...configProps}><App><PageLoading message='加载中...'/></App></ConfigProvider>;
|
|
96
|
-
}
|
|
103
|
+
if (isPublic) return <AppWrapper><Outlet/></AppWrapper>;
|
|
97
104
|
|
|
98
|
-
return
|
|
105
|
+
return (
|
|
106
|
+
<AppWrapper>
|
|
107
|
+
{ready ? <AdminLayout/> : (
|
|
108
|
+
<PageLoading messages={[
|
|
109
|
+
!siteInfoLoaded && '加载站点信息...',
|
|
110
|
+
!loginChecked && '检查登录中...',
|
|
111
|
+
].filter(Boolean)}/>
|
|
112
|
+
)}
|
|
113
|
+
</AppWrapper>
|
|
114
|
+
);
|
|
99
115
|
}
|
|
100
116
|
|
|
101
117
|
export default Layouts;
|
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
|
})
|
|
@@ -49,6 +50,7 @@ export default class extends React.Component {
|
|
|
49
50
|
SysUtils.setSiteInfo(rs)
|
|
50
51
|
this.setState({siteInfo: rs})
|
|
51
52
|
} catch (e) {
|
|
53
|
+
console.error('[Login] 加载站点信息失败:', e);
|
|
52
54
|
message.error('加载站点信息失败,请刷新页面重试')
|
|
53
55
|
}
|
|
54
56
|
}
|
|
@@ -130,7 +130,7 @@ export default class extends React.Component {
|
|
|
130
130
|
open={this.state.formOpen}
|
|
131
131
|
onOk={() => this.formRef.current.submit()}
|
|
132
132
|
onCancel={() => this.setState({formOpen: false})}
|
|
133
|
-
|
|
133
|
+
destroyOnHidden
|
|
134
134
|
>
|
|
135
135
|
|
|
136
136
|
<Form ref={this.formRef} labelCol={{flex: '100px'}}
|
|
@@ -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,6 +83,8 @@ 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
|
|
|
@@ -90,6 +94,8 @@ export default class extends React.Component {
|
|
|
90
94
|
HttpUtils.post(url, values).then(rs => {
|
|
91
95
|
this.setState({formOpen: false})
|
|
92
96
|
this.tableRef.current.reload();
|
|
97
|
+
}).catch(e => {
|
|
98
|
+
console.error('[Job] 保存作业失败:', e);
|
|
93
99
|
})
|
|
94
100
|
}
|
|
95
101
|
|
|
@@ -97,12 +103,17 @@ export default class extends React.Component {
|
|
|
97
103
|
const hide = message.loading("删除作业中...")
|
|
98
104
|
HttpUtils.post('admin/job/delete', {id: row.id}).then(rs => {
|
|
99
105
|
this.tableRef.current.reload();
|
|
100
|
-
}).catch(
|
|
106
|
+
}).catch(e => {
|
|
107
|
+
console.error('[Job] 删除作业失败:', e);
|
|
108
|
+
hide();
|
|
109
|
+
})
|
|
101
110
|
}
|
|
102
111
|
|
|
103
112
|
handleTriggerJob = row => {
|
|
104
113
|
HttpUtils.get('admin/job/trigger-job', {id: row.id}).then(rs => {
|
|
105
114
|
this.tableRef.current.reload();
|
|
115
|
+
}).catch(e => {
|
|
116
|
+
console.error('[Job] 触发作业失败:', e);
|
|
106
117
|
})
|
|
107
118
|
}
|
|
108
119
|
|
|
@@ -167,6 +178,8 @@ export default class extends React.Component {
|
|
|
167
178
|
this.setState({statusOpen: true})
|
|
168
179
|
HttpUtils.get('admin/job/status').then(rs => {
|
|
169
180
|
this.setState({status: rs})
|
|
181
|
+
}).catch(e => {
|
|
182
|
+
console.error('[Job] 加载状态失败:', e);
|
|
170
183
|
})
|
|
171
184
|
};
|
|
172
185
|
|
|
@@ -197,7 +210,7 @@ export default class extends React.Component {
|
|
|
197
210
|
|
|
198
211
|
<Modal title='作业调度'
|
|
199
212
|
open={this.state.formOpen}
|
|
200
|
-
|
|
213
|
+
destroyOnHidden
|
|
201
214
|
width={800}
|
|
202
215
|
onOk={() => this.formRef.current.submit()}
|
|
203
216
|
onCancel={() => this.setState({formOpen: false})}
|
|
@@ -247,7 +260,7 @@ export default class extends React.Component {
|
|
|
247
260
|
footer={null}
|
|
248
261
|
width={1024}
|
|
249
262
|
>
|
|
250
|
-
<Alert
|
|
263
|
+
<Alert title={<pre>{this.state.status}</pre>}></Alert>
|
|
251
264
|
|
|
252
265
|
</Modal>
|
|
253
266
|
|
|
@@ -256,7 +269,7 @@ export default class extends React.Component {
|
|
|
256
269
|
onCancel={() => this.setState({executeRecordOpen: false})}
|
|
257
270
|
footer={null}
|
|
258
271
|
width={1024}
|
|
259
|
-
|
|
272
|
+
destroyOnHidden
|
|
260
273
|
>
|
|
261
274
|
<ProTable columns={[{
|
|
262
275
|
title: '开始时间',
|
|
@@ -99,8 +99,8 @@ export default class extends React.Component {
|
|
|
99
99
|
open={this.state.formOpen}
|
|
100
100
|
onOk={() => this.formRef.current.submit()}
|
|
101
101
|
onCancel={() => this.setState({formOpen: false})}
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
destroyOnHidden
|
|
103
|
+
mask={{ closable: false }}
|
|
104
104
|
>
|
|
105
105
|
|
|
106
106
|
<Form ref={this.formRef} labelCol={{flex: '100px'}}
|
|
@@ -199,8 +199,8 @@ export default class extends React.Component {
|
|
|
199
199
|
open={this.state.formOpen}
|
|
200
200
|
onOk={() => this.formRef.current.submit()}
|
|
201
201
|
onCancel={() => this.setState({formOpen: false})}
|
|
202
|
-
|
|
203
|
-
|
|
202
|
+
destroyOnHidden
|
|
203
|
+
mask={{ closable: false }}
|
|
204
204
|
width={600}
|
|
205
205
|
>
|
|
206
206
|
|
|
@@ -240,8 +240,8 @@ export default class extends React.Component {
|
|
|
240
240
|
|
|
241
241
|
<Modal title={'角色用户' + "【" + this.state.formValues?.name + '】'}
|
|
242
242
|
open={this.state.usersModalOpen}
|
|
243
|
-
|
|
244
|
-
|
|
243
|
+
destroyOnHidden
|
|
244
|
+
mask={{ closable: false }}
|
|
245
245
|
width={800}
|
|
246
246
|
onCancel={() => this.setState({usersModalOpen: false})}
|
|
247
247
|
onOk={this.handleSaveUsers}
|
|
@@ -249,7 +249,7 @@ export default class extends React.Component {
|
|
|
249
249
|
|
|
250
250
|
|
|
251
251
|
<Transfer
|
|
252
|
-
|
|
252
|
+
styles={{ section: { height: '60vh', width: 300 } }}
|
|
253
253
|
|
|
254
254
|
dataSource={this.state.userList} titles={["未选择", "已选择"]}
|
|
255
255
|
targetKeys={this.state.targetKeys}
|
|
@@ -273,8 +273,8 @@ export default class extends React.Component {
|
|
|
273
273
|
|
|
274
274
|
<Modal title={'角色授权菜单权限' + "【" + this.state.formValues?.name + '】'}
|
|
275
275
|
open={this.state.menuOpen}
|
|
276
|
-
|
|
277
|
-
|
|
276
|
+
destroyOnHidden
|
|
277
|
+
mask={{ closable: false }}
|
|
278
278
|
width={800}
|
|
279
279
|
onCancel={() => this.setState({menuOpen: false})}
|
|
280
280
|
onOk={this.handleGrantMenu}
|
|
@@ -208,7 +208,7 @@ export default class extends React.Component {
|
|
|
208
208
|
open={this.state.formOpen}
|
|
209
209
|
onOk={() => this.formRef.current.submit()}
|
|
210
210
|
onCancel={() => this.setState({formOpen: false})}
|
|
211
|
-
|
|
211
|
+
destroyOnHidden
|
|
212
212
|
>
|
|
213
213
|
|
|
214
214
|
<Form ref={this.formRef} labelCol={{flex: '100px'}}
|