@jiangood/open-admin 2.5.5 → 2.5.7
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 +2 -2
- package/package.json +3 -2
- package/src/.umi-production/appData.json +91 -90
- package/src/.umi-production/core/route.tsx +6 -6
- package/src/.umi-production/umi.ts +1 -1
- package/src/framework/GlobalData.d.ts +8 -0
- package/src/framework/GlobalData.js +33 -0
- package/src/framework/{components/system → biz}/HasPerm.tsx +1 -1
- package/src/framework/{components/OrgTree/index.tsx → biz/OrgTree.tsx} +12 -2
- package/src/framework/{components/system/ButtonList.tsx → biz/PermActions.tsx} +6 -5
- package/src/framework/{components/RoleTree/index.tsx → biz/RoleTree.tsx} +13 -3
- package/src/framework/{components/system → biz}/index.tsx +4 -2
- package/src/framework/components/ContextMenu/index.tsx +12 -4
- package/src/framework/components/DownloadModal/index.tsx +332 -0
- package/src/framework/components/ErrorBoundary/index.tsx +18 -0
- package/src/framework/components/NamedIcon/{index.jsx → index.tsx} +8 -3
- package/src/framework/components/Page/index.tsx +2 -2
- package/src/framework/components/ProTable/index.tsx +3 -10
- package/src/framework/components/index.ts +2 -6
- package/src/framework/fields/BaseRemoteSelect/index.tsx +2 -3
- package/src/framework/fields/FieldBoolean/index.tsx +3 -4
- package/src/framework/fields/FieldDate/index.tsx +0 -21
- package/src/framework/fields/FieldEditor/index.tsx +35 -44
- package/src/framework/fields/FieldNumberRange/index.tsx +2 -2
- package/src/framework/fields/FieldRemoteTree/index.tsx +1 -1
- package/src/framework/fields/FieldTable/index.tsx +24 -27
- package/src/framework/fields/FieldUploadFile/index.tsx +10 -3
- package/src/framework/fields/index.ts +1 -3
- package/src/framework/index.ts +2 -0
- package/src/framework/utils/ArrayUtils.d.ts +6 -0
- package/src/framework/utils/ArrayUtils.js +30 -0
- package/src/framework/utils/DateUtils.d.ts +20 -0
- package/src/framework/utils/DateUtils.js +81 -0
- package/src/framework/utils/DeviceUtils.d.ts +3 -0
- package/src/framework/utils/DeviceUtils.js +10 -0
- package/src/framework/utils/EventBus.d.ts +6 -0
- package/src/framework/utils/EventBus.js +51 -0
- package/src/framework/utils/MessageUtils.d.ts +10 -0
- package/src/framework/utils/MessageUtils.js +43 -0
- package/src/framework/utils/ObjectUtils.d.ts +14 -0
- package/src/framework/utils/ObjectUtils.js +12 -0
- package/src/framework/utils/StorageUtils.d.ts +4 -0
- package/src/framework/utils/{StorageUtils.ts → StorageUtils.js} +7 -11
- package/src/framework/utils/StringUtils.d.ts +17 -0
- package/src/framework/utils/StringUtils.js +107 -0
- package/src/framework/utils/TreeUtils.d.ts +13 -0
- package/src/framework/utils/TreeUtils.js +64 -0
- package/src/framework/utils/UrlUtils.d.ts +6 -0
- package/src/framework/utils/UrlUtils.js +71 -0
- package/src/framework/utils/index.ts +1 -5
- package/src/framework/utils/system/DictUtils.d.ts +20 -0
- package/src/framework/utils/system/DictUtils.js +31 -0
- package/src/framework/utils/system/FormRegistry.d.ts +8 -0
- package/src/framework/utils/system/FormRegistry.js +31 -0
- package/src/framework/utils/system/HttpUtils.d.ts +14 -0
- package/src/framework/utils/system/HttpUtils.js +87 -0
- package/src/framework/utils/system/PageUtils.d.ts +14 -0
- package/src/framework/utils/system/PageUtils.js +59 -0
- package/src/framework/utils/system/PermUtils.d.ts +5 -0
- package/src/framework/utils/system/PermUtils.js +27 -0
- package/src/framework/utils/system/ThemeUtils.d.ts +6 -0
- package/src/framework/utils/system/{ThemeUtils.ts → ThemeUtils.js} +19 -19
- package/src/framework/utils/system/index.ts +1 -2
- package/src/framework/views/ViewFile/index.tsx +3 -3
- package/src/framework/views/ViewImage/index.tsx +3 -3
- package/src/framework/views/{ViewBooleanEnableDisable → ViewSwitch}/index.tsx +1 -1
- package/src/framework/views/index.ts +3 -4
- package/src/layouts/admin/HeaderRight.jsx +32 -47
- package/src/layouts/admin/index.jsx +5 -29
- package/src/layouts/index.jsx +29 -19
- package/src/pages/about.jsx +0 -1
- package/src/pages/{userCenter/ChangePassword.jsx → account/changePassword.jsx} +1 -2
- package/src/pages/{userCenter → account}/index.jsx +2 -6
- package/src/pages/forceUpdatePwd.jsx +89 -0
- package/src/pages/login.jsx +5 -5
- package/src/pages/system/dict/index.jsx +6 -6
- package/src/pages/system/file/index.jsx +4 -4
- package/src/pages/system/job/index.jsx +2 -2
- package/src/pages/system/org/index.jsx +2 -2
- package/src/pages/system/role/index.jsx +4 -4
- package/src/pages/system/role/{perm.jsx → rolePerm.jsx} +2 -2
- package/src/pages/system/user/index.jsx +4 -4
- package/src/framework/components/DownloadFileButton/index.tsx +0 -33
- package/src/framework/components/NamedIcon/index.d.ts +0 -7
- package/src/framework/components/ProTable/utils/index.ts +0 -62
- package/src/framework/fields/FieldRemoteSelectMultipleInline/index.tsx +0 -33
- package/src/framework/fields/FieldRemoteTreeSelectMultiple/index.tsx +0 -43
- package/src/framework/utils/ArrayUtils.ts +0 -186
- package/src/framework/utils/ColorsUtils.ts +0 -378
- package/src/framework/utils/DateUtils.ts +0 -187
- package/src/framework/utils/DeviceUtils.ts +0 -46
- package/src/framework/utils/DomUtils.ts +0 -50
- package/src/framework/utils/EventBusUtils.ts +0 -143
- package/src/framework/utils/Logger.ts +0 -40
- package/src/framework/utils/MessageUtils.tsx +0 -90
- package/src/framework/utils/ObjectUtils.ts +0 -118
- package/src/framework/utils/StringUtils.ts +0 -436
- package/src/framework/utils/TreeUtils.ts +0 -251
- package/src/framework/utils/UrlUtils.ts +0 -152
- package/src/framework/utils/UuidUtils.ts +0 -88
- package/src/framework/utils/ValidateUtils.ts +0 -28
- package/src/framework/utils/system/DictUtils.ts +0 -96
- package/src/framework/utils/system/FormRegistryUtils.ts +0 -76
- package/src/framework/utils/system/HttpUtils.ts +0 -251
- package/src/framework/utils/system/PageUtils.ts +0 -163
- package/src/framework/utils/system/PermUtils.ts +0 -79
- package/src/framework/utils/system/SysUtils.ts +0 -105
- package/src/framework/views/ViewProcessInstanceProgress/index.tsx +0 -98
- package/src/framework/views/ViewProcessInstanceProgressButton/index.tsx +0 -23
- package/src/pages/userCenter/message.jsx +0 -105
- /package/src/framework/{components → views}/ViewRange/index.tsx +0 -0
- /package/src/pages/system/user/{UserPerm.jsx → userPerm.jsx} +0 -0
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import {ColorsUtils} from '../ColorsUtils';
|
|
2
|
-
|
|
3
|
-
declare const OPEN_ADMIN_THEME: Record<string, string> | undefined;
|
|
4
|
-
|
|
5
1
|
export class ThemeUtils {
|
|
6
|
-
|
|
2
|
+
static defaultTheme = {
|
|
7
3
|
"primary-color": "#1961AC",
|
|
8
4
|
"success-color": "#52c41a",
|
|
9
5
|
"warning-color": "#faad14",
|
|
@@ -13,40 +9,44 @@ export class ThemeUtils {
|
|
|
13
9
|
"primary-color-click": "#124B93"
|
|
14
10
|
};
|
|
15
11
|
|
|
16
|
-
|
|
12
|
+
static cachedTheme = null;
|
|
17
13
|
|
|
18
|
-
static get theme()
|
|
14
|
+
static get theme() {
|
|
19
15
|
if (this.cachedTheme) return this.cachedTheme;
|
|
20
16
|
this.cachedTheme = this.loadTheme();
|
|
21
17
|
return this.cachedTheme;
|
|
22
18
|
}
|
|
23
19
|
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
/** 调亮/调暗十六进制颜色 */
|
|
21
|
+
static _lightenHex(hex, percent) {
|
|
22
|
+
const num = parseInt(hex.replace('#', ''), 16);
|
|
23
|
+
const r = num >> 16 & 255, g = num >> 8 & 255, b = num & 255;
|
|
24
|
+
const t = percent < 0 ? 0 : 255;
|
|
25
|
+
const p = Math.abs(percent) / 100;
|
|
26
|
+
return '#' + (0x1000000 + (Math.round((t - r) * p) + r) * 0x10000
|
|
27
|
+
+ (Math.round((t - g) * p) + g) * 0x100 + (Math.round((t - b) * p) + b)).toString(16).slice(1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static loadTheme() {
|
|
31
|
+
let custom = {};
|
|
26
32
|
try {
|
|
27
33
|
if (typeof OPEN_ADMIN_THEME !== 'undefined' && OPEN_ADMIN_THEME) {
|
|
28
34
|
custom = OPEN_ADMIN_THEME;
|
|
29
35
|
}
|
|
30
|
-
} catch {}
|
|
31
|
-
|
|
36
|
+
} catch (e) {}
|
|
32
37
|
const result = {...this.defaultTheme, ...custom};
|
|
33
|
-
|
|
34
|
-
// Auto-derive hover/click from primary if not explicitly set
|
|
35
38
|
if (custom["primary-color"]) {
|
|
36
39
|
if (!custom["primary-color-hover"]) {
|
|
37
|
-
result["primary-color-hover"] =
|
|
40
|
+
result["primary-color-hover"] = ThemeUtils._lightenHex(result["primary-color"], 20);
|
|
38
41
|
}
|
|
39
42
|
if (!custom["primary-color-click"]) {
|
|
40
|
-
result["primary-color-click"] =
|
|
43
|
+
result["primary-color-click"] = ThemeUtils._lightenHex(result["primary-color"], -10);
|
|
41
44
|
}
|
|
42
45
|
}
|
|
43
|
-
|
|
44
46
|
return result;
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
static getColor(key) {
|
|
48
50
|
return ThemeUtils.theme[key];
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
|
-
|
|
52
|
-
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import {Carousel, Empty} from 'antd';
|
|
3
|
+
import {UrlUtils} from '../../utils';
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
export class ViewFile extends React.Component {
|
|
@@ -14,7 +15,7 @@ export class ViewFile extends React.Component {
|
|
|
14
15
|
|
|
15
16
|
const arr = fileId.split(',');
|
|
16
17
|
|
|
17
|
-
const urlList = arr.map(id => 'admin/sysFile/preview/' + id);
|
|
18
|
+
const urlList = arr.map(id => UrlUtils.contextPath('/admin/sysFile/preview/' + id));
|
|
18
19
|
const height = this.props.height;
|
|
19
20
|
|
|
20
21
|
if(urlList.length === 1){
|
|
@@ -29,9 +30,8 @@ export class ViewFile extends React.Component {
|
|
|
29
30
|
|
|
30
31
|
// 多个文件则用走马灯
|
|
31
32
|
const iframeList = urlList.map((url) => {
|
|
32
|
-
return <div style={{height}}>
|
|
33
|
+
return <div key={url} style={{height}}>
|
|
33
34
|
<iframe
|
|
34
|
-
key={url}
|
|
35
35
|
src={url}
|
|
36
36
|
width='99%'
|
|
37
37
|
frameBorder={0}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import {Modal} from 'antd';
|
|
3
|
-
import {
|
|
3
|
+
import {UrlUtils} from '../../utils';
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
export class ViewImage extends React.Component {
|
|
@@ -27,11 +27,11 @@ export class ViewImage extends React.Component {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
if (isId) {
|
|
30
|
-
urlList.push(
|
|
30
|
+
urlList.push(UrlUtils.contextPath('/admin/sysFile/preview/' + v));
|
|
31
31
|
continue;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
urlList.push(
|
|
34
|
+
urlList.push(UrlUtils.contextPath(v));
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
const imgs = urlList.map((url) => (
|
|
@@ -3,10 +3,9 @@ export * from './types';
|
|
|
3
3
|
export * from './ViewPassword';
|
|
4
4
|
export * from './ViewBoolean';
|
|
5
5
|
export * from './ViewApproveStatus'
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './ViewProcessInstanceProgressButton'
|
|
8
|
-
export * from './ViewBooleanEnableDisable'
|
|
6
|
+
export * from './ViewSwitch'
|
|
9
7
|
export * from './ViewImage'
|
|
10
8
|
export * from './ViewFile'
|
|
11
9
|
export * from './ViewText'
|
|
12
|
-
export * from './ViewFileButton'
|
|
10
|
+
export * from './ViewFileButton'
|
|
11
|
+
export * from './ViewRange'
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {NotificationOutlined, SettingOutlined, UserOutlined} from "@ant-design/icons";
|
|
1
|
+
import {Avatar, Dropdown} from "antd";
|
|
3
2
|
import React from "react";
|
|
4
3
|
import {history} from "umi";
|
|
5
|
-
import {DeviceUtils, HttpUtils, MessageUtils,
|
|
4
|
+
import {DeviceUtils, HttpUtils, MessageUtils, PageUtils, GlobalData} from "../../framework";
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
const ID = 'header-right';
|
|
9
6
|
export class HeaderRight extends React.Component {
|
|
10
7
|
|
|
11
8
|
state = {
|
|
@@ -13,7 +10,6 @@ export class HeaderRight extends React.Component {
|
|
|
13
10
|
};
|
|
14
11
|
|
|
15
12
|
componentDidMount() {
|
|
16
|
-
document.dispatchEvent(new CustomEvent('componentDidMount', {detail: ID}))
|
|
17
13
|
if (DeviceUtils.isMobileDevice()) {
|
|
18
14
|
this.setState({isMobileDevice: true})
|
|
19
15
|
}
|
|
@@ -36,12 +32,12 @@ export class HeaderRight extends React.Component {
|
|
|
36
32
|
})
|
|
37
33
|
}
|
|
38
34
|
|
|
39
|
-
|
|
40
|
-
PageUtils.open('/
|
|
35
|
+
account = () => {
|
|
36
|
+
PageUtils.open('/account', '个人中心')
|
|
41
37
|
}
|
|
42
38
|
|
|
43
39
|
render() {
|
|
44
|
-
const info =
|
|
40
|
+
const info = GlobalData.getLoginInfo()
|
|
45
41
|
|
|
46
42
|
if (this.state.isMobileDevice) {
|
|
47
43
|
return <div className='header-right'>
|
|
@@ -51,44 +47,33 @@ export class HeaderRight extends React.Component {
|
|
|
51
47
|
|
|
52
48
|
return <div className='header-right'>
|
|
53
49
|
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
items: [
|
|
82
|
-
{key: 'userCenter', label: '个人中心'},
|
|
83
|
-
{key: 'about', label: '关于系统'},
|
|
84
|
-
{key: 'logout', label: '退出登录'},
|
|
85
|
-
|
|
86
|
-
]
|
|
87
|
-
}}><SettingOutlined/>
|
|
88
|
-
|
|
89
|
-
</Dropdown>
|
|
90
|
-
|
|
91
|
-
</div>
|
|
50
|
+
<Dropdown menu={{
|
|
51
|
+
onClick: ({key}) => {
|
|
52
|
+
switch (key) {
|
|
53
|
+
case 'account':
|
|
54
|
+
this.account()
|
|
55
|
+
break;
|
|
56
|
+
case 'logout':
|
|
57
|
+
this.logout();
|
|
58
|
+
break;
|
|
59
|
+
case 'about':
|
|
60
|
+
this.about()
|
|
61
|
+
break
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
items: [
|
|
65
|
+
{key: 'account', label: '个人中心'},
|
|
66
|
+
{key: 'about', label: '关于系统'},
|
|
67
|
+
{key: 'logout', label: '退出登录'},
|
|
68
|
+
]
|
|
69
|
+
}}>
|
|
70
|
+
<div className='item' style={{cursor: 'pointer'}}>
|
|
71
|
+
<Avatar size="small" style={{backgroundColor: '#1677ff', verticalAlign: 'middle'}}>
|
|
72
|
+
{info.name?.charAt(0)}
|
|
73
|
+
</Avatar>
|
|
74
|
+
<span style={{marginLeft: 8}}>{info.name}</span>
|
|
75
|
+
</div>
|
|
76
|
+
</Dropdown>
|
|
92
77
|
|
|
93
78
|
</div>
|
|
94
79
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import {Layout, Menu, Skeleton, Watermark} from 'antd';
|
|
3
3
|
|
|
4
4
|
import {history, Link} from 'umi';
|
|
5
5
|
import "./index.less"
|
|
6
|
-
import {
|
|
6
|
+
import {HttpUtils, NamedIcon, PageUtils, GlobalData, ThemeUtils, TreeUtils} from "../../framework";
|
|
7
7
|
|
|
8
8
|
import { HeaderRight } from "./HeaderRight";
|
|
9
9
|
import { TabPageRender } from "./TabPageRender";
|
|
@@ -37,8 +37,8 @@ export default class extends React.Component {
|
|
|
37
37
|
// 判断是否手机端,自动收起菜单
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
const siteInfo =
|
|
41
|
-
const loginInfo =
|
|
40
|
+
const siteInfo = GlobalData.getSiteInfo();
|
|
41
|
+
const loginInfo = GlobalData.getLoginInfo()
|
|
42
42
|
this.setState({siteInfo, loginInfo})
|
|
43
43
|
|
|
44
44
|
this.initMenu()
|
|
@@ -84,7 +84,6 @@ export default class extends React.Component {
|
|
|
84
84
|
|
|
85
85
|
this.setState({menuTree, pathMenuMap, topMenus, sideMenus, activeTopMenuKey, currentMenuKey})
|
|
86
86
|
|
|
87
|
-
this.loadBadge(menuMap)
|
|
88
87
|
}).catch(err => {
|
|
89
88
|
console.error('加载菜单失败:', err)
|
|
90
89
|
this.setState({menuTree: [], topMenus: [], sideMenus: []})
|
|
@@ -170,27 +169,6 @@ export default class extends React.Component {
|
|
|
170
169
|
);
|
|
171
170
|
}
|
|
172
171
|
|
|
173
|
-
loadBadge = menuMap => {
|
|
174
|
-
for (let id in menuMap) {
|
|
175
|
-
const item = menuMap[id]
|
|
176
|
-
const {messageCountUrl} = item;
|
|
177
|
-
if (!messageCountUrl) {
|
|
178
|
-
continue
|
|
179
|
-
}
|
|
180
|
-
HttpUtils.get(messageCountUrl).then(rs => {
|
|
181
|
-
const {menuTree} = this.state
|
|
182
|
-
const menu = TreeUtils.findByKey(id, menuTree, 'key')
|
|
183
|
-
if (menu) {
|
|
184
|
-
menu.icon = <Badge dot count={rs} size={"small"}>{menu.icon}</Badge>
|
|
185
|
-
this.setState({menuTree: [...menuTree]})
|
|
186
|
-
}
|
|
187
|
-
}).catch(e => {
|
|
188
|
-
console.error('[Layout] 加载消息数失败:', e);
|
|
189
|
-
})
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
|
|
194
172
|
render() {
|
|
195
173
|
const {siteInfo, loginInfo} = this.state
|
|
196
174
|
|
|
@@ -217,9 +195,7 @@ export default class extends React.Component {
|
|
|
217
195
|
</Header>
|
|
218
196
|
|
|
219
197
|
<Content id='admin-layout-content'>
|
|
220
|
-
|
|
221
|
-
{this.renderCenterContent(loginInfo)}
|
|
222
|
-
</ErrorBoundary>
|
|
198
|
+
{this.renderCenterContent(loginInfo)}
|
|
223
199
|
</Content>
|
|
224
200
|
|
|
225
201
|
</Layout>
|
package/src/layouts/index.jsx
CHANGED
|
@@ -3,10 +3,11 @@ 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, useLocation} from "umi";
|
|
6
|
+
import {Outlet, useLocation, history} from "umi";
|
|
7
7
|
|
|
8
8
|
import AdminLayout from "./admin"
|
|
9
|
-
import {HttpUtils, PageLoading, PageUtils,
|
|
9
|
+
import {HttpUtils, PageLoading, PageUtils, GlobalData, ThemeUtils, DownloadModal} from "../framework";
|
|
10
|
+
import {ErrorBoundary} from "../framework";
|
|
10
11
|
|
|
11
12
|
import '../style/global.less'
|
|
12
13
|
import './index.less'
|
|
@@ -36,12 +37,12 @@ const configProps = {
|
|
|
36
37
|
};
|
|
37
38
|
|
|
38
39
|
function AppWrapper({children}) {
|
|
39
|
-
return <ConfigProvider {...configProps}><App
|
|
40
|
+
return <ConfigProvider {...configProps}><App><DownloadModal />{children}</App></ConfigProvider>;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
const PUBLIC_PAGES = (() => {
|
|
43
44
|
const raw = typeof OPEN_ADMIN_PUBLIC_PAGES !== 'undefined' && OPEN_ADMIN_PUBLIC_PAGES;
|
|
44
|
-
return raw ? raw.split(',').map(s => s.trim()) : ['/login', '/test'];
|
|
45
|
+
return raw ? raw.split(',').map(s => s.trim()) : ['/login', '/test', '/forceUpdatePwd'];
|
|
45
46
|
})();
|
|
46
47
|
|
|
47
48
|
function isPublicPage(pathname, search) {
|
|
@@ -60,7 +61,8 @@ function isPublicPage(pathname, search) {
|
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
export function Layouts() {
|
|
63
|
-
const
|
|
64
|
+
const location = useLocation();
|
|
65
|
+
const {pathname, search} = location;
|
|
64
66
|
const [siteInfoLoaded, setSiteInfoLoaded] = useState(false);
|
|
65
67
|
const [loginChecked, setLoginChecked] = useState(false);
|
|
66
68
|
|
|
@@ -77,31 +79,39 @@ export function Layouts() {
|
|
|
77
79
|
|
|
78
80
|
Promise.all([
|
|
79
81
|
HttpUtils.get("/admin/public/site-info").then(data => {
|
|
80
|
-
|
|
82
|
+
GlobalData.setSiteInfo(data);
|
|
81
83
|
setSiteInfoLoaded(true);
|
|
82
84
|
}),
|
|
83
|
-
HttpUtils.get('/admin/public/
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
HttpUtils.get('/admin/public/user-info').then(data => {
|
|
86
|
+
GlobalData.setDictInfo(data.dictInfo);
|
|
87
|
+
GlobalData.setLoginInfo(data.loginInfo);
|
|
88
|
+
|
|
89
|
+
if (data.needUpdatePwd && pathname !== '/forceUpdatePwd') {
|
|
90
|
+
history.push('/forceUpdatePwd');
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
86
94
|
setLoginChecked(true);
|
|
87
95
|
}),
|
|
88
96
|
]).catch(() => {
|
|
89
97
|
console.error('[Layout] 初始化应用失败');
|
|
90
98
|
PageUtils.redirectToLogin();
|
|
91
99
|
});
|
|
92
|
-
}, [
|
|
100
|
+
}, [location]);
|
|
93
101
|
|
|
94
|
-
if (isPublic) return <AppWrapper><Outlet/></AppWrapper>;
|
|
102
|
+
if (isPublic) return <ErrorBoundary minimal><AppWrapper><Outlet/></AppWrapper></ErrorBoundary>;
|
|
95
103
|
|
|
96
104
|
return (
|
|
97
|
-
<
|
|
98
|
-
|
|
99
|
-
<
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
+
<ErrorBoundary minimal>
|
|
106
|
+
<AppWrapper>
|
|
107
|
+
{ready ? <AdminLayout/> : (
|
|
108
|
+
<PageLoading messages={[
|
|
109
|
+
!siteInfoLoaded && '加载站点信息...',
|
|
110
|
+
!loginChecked && '检查登录中...',
|
|
111
|
+
].filter(Boolean)}/>
|
|
112
|
+
)}
|
|
113
|
+
</AppWrapper>
|
|
114
|
+
</ErrorBoundary>
|
|
105
115
|
);
|
|
106
116
|
}
|
|
107
117
|
|
package/src/pages/about.jsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import {Button, Form, Input, Modal} from "antd";
|
|
3
3
|
import {history} from 'umi'
|
|
4
|
-
import {HttpUtils
|
|
4
|
+
import {HttpUtils} from "../../framework";
|
|
5
5
|
|
|
6
6
|
export default class extends React.Component {
|
|
7
7
|
|
|
@@ -12,7 +12,6 @@ export default class extends React.Component {
|
|
|
12
12
|
title: '提示',
|
|
13
13
|
content: '修改密码成功',
|
|
14
14
|
onOk: () => {
|
|
15
|
-
SysUtils.setToken(null)
|
|
16
15
|
history.push('/login')
|
|
17
16
|
}
|
|
18
17
|
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import {Avatar, Card, Col, Row, Tabs} from "antd";
|
|
3
|
-
import ChangePassword from "./
|
|
3
|
+
import ChangePassword from "./changePassword";
|
|
4
4
|
import {HttpUtils, Page} from "../../framework";
|
|
5
5
|
|
|
6
6
|
export default class extends React.Component {
|
|
@@ -71,11 +71,7 @@ export default class extends React.Component {
|
|
|
71
71
|
<ChangePassword/>
|
|
72
72
|
</div>
|
|
73
73
|
},
|
|
74
|
-
|
|
75
|
-
label: '消息订阅', key: 'topic', children: <div>
|
|
76
|
-
当账号管理邮箱后,系统消息会发送邮件给您
|
|
77
|
-
</div>
|
|
78
|
-
}
|
|
74
|
+
|
|
79
75
|
]}
|
|
80
76
|
tabPlacement='left'
|
|
81
77
|
>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {Button, Form, Input, message} from "antd";
|
|
3
|
+
import {history} from 'umi'
|
|
4
|
+
import {HttpUtils, PageUtils, GlobalData} from "../framework";
|
|
5
|
+
|
|
6
|
+
export default class extends React.Component {
|
|
7
|
+
|
|
8
|
+
state = {
|
|
9
|
+
checking: true
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async componentDidMount() {
|
|
13
|
+
try {
|
|
14
|
+
const rs = await HttpUtils.get('/admin/public/user-info', null, {showError: false});
|
|
15
|
+
if (!rs.login) {
|
|
16
|
+
PageUtils.redirectToLogin();
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
GlobalData.setLoginInfo(rs.loginInfo);
|
|
20
|
+
this.setState({checking: false});
|
|
21
|
+
} catch (e) {
|
|
22
|
+
PageUtils.redirectToLogin();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
onFinish = (values) => {
|
|
27
|
+
HttpUtils.post('admin/userCenter/update-pwd', values).then(() => {
|
|
28
|
+
message.success('修改密码成功,请重新登录');
|
|
29
|
+
history.push('/login');
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
validator = (rule, value) => {
|
|
34
|
+
return new Promise((resolve, reject) => {
|
|
35
|
+
HttpUtils.get("admin/sysUser/pwd-strength", {password: value}).then(response => {
|
|
36
|
+
const rs = response.data
|
|
37
|
+
if (!rs.success) {
|
|
38
|
+
reject(rs.message)
|
|
39
|
+
}
|
|
40
|
+
resolve()
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
render() {
|
|
46
|
+
if (this.state.checking) return null;
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<div style={{
|
|
50
|
+
display: 'flex',
|
|
51
|
+
justifyContent: 'center',
|
|
52
|
+
alignItems: 'center',
|
|
53
|
+
minHeight: '100vh',
|
|
54
|
+
background: '#f0f2f5'
|
|
55
|
+
}}>
|
|
56
|
+
<div style={{
|
|
57
|
+
background: '#fff',
|
|
58
|
+
padding: '40px',
|
|
59
|
+
borderRadius: '8px',
|
|
60
|
+
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
|
|
61
|
+
maxWidth: 400,
|
|
62
|
+
width: '100%'
|
|
63
|
+
}}>
|
|
64
|
+
<h2 style={{textAlign: 'center', marginBottom: 24}}>修改密码</h2>
|
|
65
|
+
<p style={{textAlign: 'center', color: '#999', marginBottom: 24}}>
|
|
66
|
+
首次登录或密码已被重置,请修改密码后重新登录
|
|
67
|
+
</p>
|
|
68
|
+
<Form onFinish={this.onFinish}>
|
|
69
|
+
<Form.Item name='newPassword'
|
|
70
|
+
label='新密码'
|
|
71
|
+
extra={'请输入字母、数字、特殊字符'}
|
|
72
|
+
rules={[
|
|
73
|
+
{required: true, message: '请输入新密码'},
|
|
74
|
+
{validator: this.validator}
|
|
75
|
+
]}
|
|
76
|
+
>
|
|
77
|
+
<Input.Password/>
|
|
78
|
+
</Form.Item>
|
|
79
|
+
<Form.Item style={{marginTop: 40}}>
|
|
80
|
+
<Button type="primary" htmlType="submit" block size='large'>
|
|
81
|
+
确定
|
|
82
|
+
</Button>
|
|
83
|
+
</Form.Item>
|
|
84
|
+
</Form>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
}
|
package/src/pages/login.jsx
CHANGED
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import {Button, Form, Input, message} from 'antd';
|
|
3
3
|
import {LockOutlined, UserOutlined, WarningOutlined} from '@ant-design/icons';
|
|
4
4
|
import {history} from 'umi';
|
|
5
|
-
import {
|
|
5
|
+
import {EventBus, HttpUtils, PageUtils, GlobalData} from "../framework";
|
|
6
6
|
|
|
7
7
|
import "./login.less"
|
|
8
8
|
|
|
@@ -19,7 +19,7 @@ function getRedirect() {
|
|
|
19
19
|
function postLogin(values) {
|
|
20
20
|
return new Promise((resolve, reject) => {
|
|
21
21
|
HttpUtils.post('/admin/auth/login', values).then(rs => {
|
|
22
|
-
|
|
22
|
+
EventBus.emit('loginSuccess')
|
|
23
23
|
history.push(getRedirect())
|
|
24
24
|
resolve(rs)
|
|
25
25
|
}).catch(e => {
|
|
@@ -44,15 +44,15 @@ export default class extends React.Component {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
async componentDidMount() {
|
|
47
|
-
const siteInfo =
|
|
47
|
+
const siteInfo = GlobalData.getSiteInfo()
|
|
48
48
|
if (siteInfo && siteInfo.title) {
|
|
49
49
|
this.setState({siteInfo})
|
|
50
50
|
return
|
|
51
51
|
}
|
|
52
52
|
// localStorage 中无站点信息,从服务端重新加载
|
|
53
53
|
try {
|
|
54
|
-
const rs = await HttpUtils.get('/admin/public/site-info')
|
|
55
|
-
|
|
54
|
+
const rs = await HttpUtils.get('/admin/public/site-info', null, { showError: false })
|
|
55
|
+
GlobalData.setSiteInfo(rs)
|
|
56
56
|
this.setState({siteInfo: rs})
|
|
57
57
|
} catch (e) {
|
|
58
58
|
console.error('[Login] 加载站点信息失败:', e);
|
|
@@ -2,13 +2,13 @@ import {DeleteOutlined, EditOutlined, PlusOutlined} from '@ant-design/icons';
|
|
|
2
2
|
import {Button, Card, Descriptions, Empty, Form, Input, InputNumber, Modal, Popconfirm, Splitter, Tree, Tag, TreeSelect, Typography} from 'antd';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
PermActions,
|
|
6
6
|
FieldBoolean,
|
|
7
7
|
FieldDictSelect,
|
|
8
8
|
HttpUtils,
|
|
9
9
|
Page,
|
|
10
10
|
ProTable,
|
|
11
|
-
|
|
11
|
+
ViewSwitch,
|
|
12
12
|
} from "../../../framework";
|
|
13
13
|
|
|
14
14
|
export default class extends React.Component {
|
|
@@ -139,7 +139,7 @@ export default class extends React.Component {
|
|
|
139
139
|
{
|
|
140
140
|
title: '启用', dataIndex: 'enabled',
|
|
141
141
|
render(v) {
|
|
142
|
-
return <
|
|
142
|
+
return <ViewSwitch value={v}/>
|
|
143
143
|
}
|
|
144
144
|
},
|
|
145
145
|
{title: '序号', dataIndex: 'seq'},
|
|
@@ -147,14 +147,14 @@ export default class extends React.Component {
|
|
|
147
147
|
title: '操作', dataIndex: 'option',
|
|
148
148
|
render: (_, record) => {
|
|
149
149
|
return (
|
|
150
|
-
<
|
|
150
|
+
<PermActions>
|
|
151
151
|
<Button size='small' perm='sys-dict:update'
|
|
152
152
|
onClick={() => this.handleItemEdit(record)}>编辑</Button>
|
|
153
153
|
<Popconfirm perm='sys-dict:delete' title='是否确定删除字典项'
|
|
154
154
|
onConfirm={() => this.handleItemDelete(record)}>
|
|
155
155
|
<Button size='small'>删除</Button>
|
|
156
156
|
</Popconfirm>
|
|
157
|
-
</
|
|
157
|
+
</PermActions>
|
|
158
158
|
);
|
|
159
159
|
},
|
|
160
160
|
},
|
|
@@ -204,7 +204,7 @@ export default class extends React.Component {
|
|
|
204
204
|
<Descriptions.Item label="类型编码">{selectedType.typeCode}</Descriptions.Item>
|
|
205
205
|
<Descriptions.Item label="分类">{this.getParentLabel() || '-'}</Descriptions.Item>
|
|
206
206
|
<Descriptions.Item label="序号">{selectedType.seq}</Descriptions.Item>
|
|
207
|
-
<Descriptions.Item label="启用"><
|
|
207
|
+
<Descriptions.Item label="启用"><ViewSwitch value={selectedType.enabled}/></Descriptions.Item>
|
|
208
208
|
</Descriptions>}
|
|
209
209
|
</Card>
|
|
210
210
|
<Card size='small'>
|