@jiangood/open-admin 1.0.0-beta.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 +94 -0
- package/config/config.js +58 -0
- package/config/utils.js +73 -0
- package/package.json +42 -0
- package/src/.umi-production/appData.json +2365 -0
- package/src/.umi-production/core/EmptyRoute.tsx +9 -0
- package/src/.umi-production/core/defineApp.ts +16 -0
- package/src/.umi-production/core/helmet.ts +10 -0
- package/src/.umi-production/core/helmetContext.ts +4 -0
- package/src/.umi-production/core/history.ts +72 -0
- package/src/.umi-production/core/historyIntelli.ts +132 -0
- package/src/.umi-production/core/plugin.ts +40 -0
- package/src/.umi-production/core/pluginConfig.ts +324 -0
- package/src/.umi-production/core/pluginConfigJoi.d.ts +7 -0
- package/src/.umi-production/core/polyfill.ts +220 -0
- package/src/.umi-production/core/route.tsx +54 -0
- package/src/.umi-production/core/routeProps.js +5 -0
- package/src/.umi-production/core/routeProps.ts +6 -0
- package/src/.umi-production/core/terminal.ts +37 -0
- package/src/.umi-production/exports.ts +17 -0
- package/src/.umi-production/testBrowser.tsx +90 -0
- package/src/.umi-production/tsconfig.json +44 -0
- package/src/.umi-production/typings.d.ts +136 -0
- package/src/.umi-production/umi.ts +83 -0
- package/src/framework/components/DownloadFileButton/index.d.ts +11 -0
- package/src/framework/components/DownloadFileButton/index.jsx +33 -0
- package/src/framework/components/Gap/index.d.ts +23 -0
- package/src/framework/components/Gap/index.jsx +46 -0
- package/src/framework/components/LinkButton/index.d.ts +14 -0
- package/src/framework/components/LinkButton/index.jsx +10 -0
- package/src/framework/components/NamedIcon/index.d.ts +5 -0
- package/src/framework/components/NamedIcon/index.jsx +11 -0
- package/src/framework/components/OrgTree/index.d.ts +4 -0
- package/src/framework/components/OrgTree/index.jsx +58 -0
- package/src/framework/components/Page/index.d.ts +17 -0
- package/src/framework/components/Page/index.jsx +30 -0
- package/src/framework/components/Page/index.less +10 -0
- package/src/framework/components/PageLoading/index.d.ts +1 -0
- package/src/framework/components/PageLoading/index.jsx +25 -0
- package/src/framework/components/ProModal/index.tsx +66 -0
- package/src/framework/components/ProTable/components/ToolBar/index.jsx +123 -0
- package/src/framework/components/ProTable/components/ToolBar/index.less +53 -0
- package/src/framework/components/ProTable/index.d.ts +42 -0
- package/src/framework/components/ProTable/index.jsx +260 -0
- package/src/framework/components/ProTable/index.less +14 -0
- package/src/framework/components/ProTable/utils/index.js +43 -0
- package/src/framework/components/RoleTree/index.d.ts +4 -0
- package/src/framework/components/RoleTree/index.jsx +50 -0
- package/src/framework/components/ValueType/index.jsx +34 -0
- package/src/framework/components/ValueType/registry.jsx +26 -0
- package/src/framework/components/ViewRange/index.d.ts +14 -0
- package/src/framework/components/ViewRange/index.jsx +20 -0
- package/src/framework/components/index.ts +13 -0
- package/src/framework/components/system/ButtonList.d.ts +8 -0
- package/src/framework/components/system/ButtonList.jsx +42 -0
- package/src/framework/components/system/HasPerm.tsx +14 -0
- package/src/framework/components/system/index.tsx +29 -0
- package/src/framework/fields/FieldBoolean/index.d.ts +9 -0
- package/src/framework/fields/FieldBoolean/index.jsx +73 -0
- package/src/framework/fields/FieldDate/index.d.ts +23 -0
- package/src/framework/fields/FieldDate/index.jsx +116 -0
- package/src/framework/fields/FieldDateRange/index.d.ts +22 -0
- package/src/framework/fields/FieldDateRange/index.jsx +103 -0
- package/src/framework/fields/FieldDictSelect/index.d.ts +12 -0
- package/src/framework/fields/FieldDictSelect/index.jsx +16 -0
- package/src/framework/fields/FieldEditor/index.d.ts +14 -0
- package/src/framework/fields/FieldEditor/index.jsx +59 -0
- package/src/framework/fields/FieldNumberRange/index.d.ts +10 -0
- package/src/framework/fields/FieldNumberRange/index.jsx +55 -0
- package/src/framework/fields/FieldPercent/index.d.ts +8 -0
- package/src/framework/fields/FieldPercent/index.jsx +30 -0
- package/src/framework/fields/FieldRemoteSelect/index.d.ts +44 -0
- package/src/framework/fields/FieldRemoteSelect/index.jsx +125 -0
- package/src/framework/fields/FieldRemoteSelectMultiple/index.d.ts +20 -0
- package/src/framework/fields/FieldRemoteSelectMultiple/index.jsx +85 -0
- package/src/framework/fields/FieldRemoteSelectMultipleInline/index.d.ts +21 -0
- package/src/framework/fields/FieldRemoteSelectMultipleInline/index.jsx +88 -0
- package/src/framework/fields/FieldRemoteTree/index.d.ts +20 -0
- package/src/framework/fields/FieldRemoteTree/index.jsx +50 -0
- package/src/framework/fields/FieldRemoteTreeCascader/index.d.ts +18 -0
- package/src/framework/fields/FieldRemoteTreeCascader/index.jsx +59 -0
- package/src/framework/fields/FieldRemoteTreeSelect/index.d.ts +19 -0
- package/src/framework/fields/FieldRemoteTreeSelect/index.jsx +57 -0
- package/src/framework/fields/FieldRemoteTreeSelectMultiple/index.d.ts +20 -0
- package/src/framework/fields/FieldRemoteTreeSelectMultiple/index.jsx +62 -0
- package/src/framework/fields/FieldSysOrgTree/index.d.ts +9 -0
- package/src/framework/fields/FieldSysOrgTree/index.jsx +20 -0
- package/src/framework/fields/FieldSysOrgTreeSelect/index.d.ts +9 -0
- package/src/framework/fields/FieldSysOrgTreeSelect/index.jsx +22 -0
- package/src/framework/fields/FieldTable/index.d.ts +14 -0
- package/src/framework/fields/FieldTable/index.jsx +108 -0
- package/src/framework/fields/FieldTable/styles.less +29 -0
- package/src/framework/fields/FieldTableSelect/index.d.ts +19 -0
- package/src/framework/fields/FieldTableSelect/index.jsx +60 -0
- package/src/framework/fields/FieldUploadFile/index.d.ts +31 -0
- package/src/framework/fields/FieldUploadFile/index.jsx +139 -0
- package/src/framework/fields/index.ts +22 -0
- package/src/framework/fields/types.ts +16 -0
- package/src/framework/index.ts +5 -0
- package/src/framework/pages/LoginPage.d.ts +16 -0
- package/src/framework/pages/LoginPage.jsx +135 -0
- package/src/framework/pages/LoginPage.less +53 -0
- package/src/framework/pages/LoginPageUtils.ts +36 -0
- package/src/framework/pages/index.ts +2 -0
- package/src/framework/utils/ArrUtils.ts +229 -0
- package/src/framework/utils/ColorsUtils.ts +378 -0
- package/src/framework/utils/DateUtils.ts +187 -0
- package/src/framework/utils/DeviceUtils.ts +46 -0
- package/src/framework/utils/DomUtils.ts +50 -0
- package/src/framework/utils/EventBusUtils.ts +144 -0
- package/src/framework/utils/Logger.ts +40 -0
- package/src/framework/utils/MessageUtils.tsx +170 -0
- package/src/framework/utils/ObjectUtils.ts +118 -0
- package/src/framework/utils/StorageUtils.ts +50 -0
- package/src/framework/utils/StringUtils.ts +436 -0
- package/src/framework/utils/TreeUtils.ts +251 -0
- package/src/framework/utils/UrlUtils.ts +152 -0
- package/src/framework/utils/UuidUtils.ts +88 -0
- package/src/framework/utils/ValidateUtils.ts +28 -0
- package/src/framework/utils/index.ts +15 -0
- package/src/framework/utils/system/DictUtils.ts +97 -0
- package/src/framework/utils/system/FormRegistryUtils.ts +77 -0
- package/src/framework/utils/system/HttpUtils.ts +247 -0
- package/src/framework/utils/system/PageUtils.ts +163 -0
- package/src/framework/utils/system/PermUtils.ts +79 -0
- package/src/framework/utils/system/SysUtils.ts +97 -0
- package/src/framework/utils/system/ThemeUtils.ts +27 -0
- package/src/framework/utils/system/index.ts +7 -0
- package/src/framework/views/ViewApproveStatus/index.d.ts +3 -0
- package/src/framework/views/ViewApproveStatus/index.jsx +21 -0
- package/src/framework/views/ViewBoolean/index.d.ts +3 -0
- package/src/framework/views/ViewBoolean/index.jsx +4 -0
- package/src/framework/views/ViewBooleanEnableDisable/index.d.ts +5 -0
- package/src/framework/views/ViewBooleanEnableDisable/index.jsx +15 -0
- package/src/framework/views/ViewFile/index.d.ts +10 -0
- package/src/framework/views/ViewFile/index.jsx +49 -0
- package/src/framework/views/ViewFileButton/index.d.ts +10 -0
- package/src/framework/views/ViewFileButton/index.jsx +22 -0
- package/src/framework/views/ViewImage/index.d.ts +6 -0
- package/src/framework/views/ViewImage/index.jsx +60 -0
- package/src/framework/views/ViewPassword/index.d.ts +5 -0
- package/src/framework/views/ViewPassword/index.jsx +24 -0
- package/src/framework/views/ViewProcessInstanceProgress/index.d.ts +12 -0
- package/src/framework/views/ViewProcessInstanceProgress/index.jsx +97 -0
- package/src/framework/views/ViewProcessInstanceProgressButton/index.d.ts +6 -0
- package/src/framework/views/ViewProcessInstanceProgressButton/index.jsx +24 -0
- package/src/framework/views/ViewText/index.d.ts +16 -0
- package/src/framework/views/ViewText/index.jsx +42 -0
- package/src/framework/views/index.ts +12 -0
- package/src/framework/views/types.ts +26 -0
- package/src/index.ts +2 -0
- package/src/layouts/PageRender.d.ts +22 -0
- package/src/layouts/PageRender.jsx +90 -0
- package/src/layouts/admin/HeaderRight.jsx +104 -0
- package/src/layouts/admin/TabPageRender.jsx +158 -0
- package/src/layouts/admin/index.jsx +159 -0
- package/src/layouts/admin/index.less +65 -0
- package/src/layouts/index.jsx +187 -0
- package/src/layouts/index.less +24 -0
- package/src/loading.jsx +18 -0
- package/src/pages/404.jsx +13 -0
- package/src/pages/about.jsx +12 -0
- package/src/pages/index.jsx +10 -0
- package/src/pages/login.jsx +16 -0
- package/src/pages/system/api/ApiDoc.jsx +148 -0
- package/src/pages/system/api/index.jsx +267 -0
- package/src/pages/system/api/perm.jsx +69 -0
- package/src/pages/system/dict/Dict.jsx +67 -0
- package/src/pages/system/dict/DictItem.jsx +175 -0
- package/src/pages/system/dict/index.jsx +25 -0
- package/src/pages/system/file/index.jsx +147 -0
- package/src/pages/system/job/index.jsx +324 -0
- package/src/pages/system/log/index.jsx +77 -0
- package/src/pages/system/org/index.jsx +260 -0
- package/src/pages/system/role/index.jsx +302 -0
- package/src/pages/system/role/perm.jsx +107 -0
- package/src/pages/system/sysManual/index.jsx +126 -0
- package/src/pages/system/user/UserPerm.jsx +94 -0
- package/src/pages/system/user/index.jsx +253 -0
- package/src/pages/test/views.jsx +95 -0
- package/src/pages/ureport/index.jsx +16 -0
- package/src/pages/userCenter/ChangePassword.jsx +64 -0
- package/src/pages/userCenter/index.jsx +90 -0
- package/src/pages/userCenter/manual.jsx +57 -0
- package/src/pages/userCenter/message.jsx +103 -0
- package/src/style/global.less +51 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {FieldRemoteTreeProps} from "./FieldRemoteTree";
|
|
3
|
+
|
|
4
|
+
export interface FieldSysOrgTreeProps extends Omit<FieldRemoteTreeProps, 'url'> {
|
|
5
|
+
type?: 'dept' | 'unit';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class FieldSysOrgTree extends React.Component<FieldSysOrgTreeProps> {
|
|
9
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 组织机构树
|
|
3
|
+
*/
|
|
4
|
+
import React from "react";
|
|
5
|
+
import {FieldRemoteTree} from "../FieldRemoteTree";
|
|
6
|
+
|
|
7
|
+
export class FieldSysOrgTree extends React.Component {
|
|
8
|
+
static defaultProps = {
|
|
9
|
+
type: 'dept',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
render() {
|
|
13
|
+
const {type, ...rest} = this.props;
|
|
14
|
+
const url = type === 'dept'?
|
|
15
|
+
'/admin/sysOrg/deptTree':
|
|
16
|
+
'/admin/sysOrg/unitTree';
|
|
17
|
+
return <FieldRemoteTree url={url} {...rest} />;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {FieldRemoteTreeSelectProps} from "./FieldRemoteTreeSelect";
|
|
3
|
+
|
|
4
|
+
export interface FieldSysOrgTreeSelectProps extends Omit<FieldRemoteTreeSelectProps, 'url'> {
|
|
5
|
+
type?: 'dept' | 'unit';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class FieldSysOrgTreeSelect extends React.Component<FieldSysOrgTreeSelectProps> {
|
|
9
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 组织机构树选择器
|
|
3
|
+
*/
|
|
4
|
+
import React from "react";
|
|
5
|
+
import {FieldRemoteTreeSelect} from "../FieldRemoteTreeSelect";
|
|
6
|
+
|
|
7
|
+
export class FieldSysOrgTreeSelect extends React.Component {
|
|
8
|
+
|
|
9
|
+
static defaultProps = {
|
|
10
|
+
type: 'dept',
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
render() {
|
|
14
|
+
const {type, ...rest} = this.props;
|
|
15
|
+
const url = type === 'dept'?
|
|
16
|
+
'/admin/sysOrg/deptTree':
|
|
17
|
+
'/admin/sysOrg/unitTree';
|
|
18
|
+
|
|
19
|
+
return <FieldRemoteTreeSelect url={url} {...rest}/>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import {ColumnsType} from "antd/es/table";
|
|
3
|
+
import { FieldProps } from '../types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 可编辑表格
|
|
7
|
+
*/
|
|
8
|
+
interface FieldTableProps extends FieldProps<any[]> {
|
|
9
|
+
columns: ColumnsType<any>;
|
|
10
|
+
style?: React.CSSProperties;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class FieldTable extends React.Component<FieldTableProps, any> {
|
|
14
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import {Button, Input, Table} from 'antd'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import {DeleteOutlined, PlusOutlined} from "@ant-design/icons";
|
|
4
|
+
import './styles.less'
|
|
5
|
+
import {ArrUtils} from "../../utils";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 可编辑表格
|
|
9
|
+
*/
|
|
10
|
+
export class FieldTable extends React.Component {
|
|
11
|
+
|
|
12
|
+
columns = [];
|
|
13
|
+
|
|
14
|
+
constructor(props) {
|
|
15
|
+
super(props);
|
|
16
|
+
|
|
17
|
+
this.columns = this.props.columns.map(col => {
|
|
18
|
+
if (col.render == null) {
|
|
19
|
+
col.render = (v, record, index) => {
|
|
20
|
+
return <Input value={v} onChange={(e) => this.onCellChange(index, col.dataIndex, e)}/>;
|
|
21
|
+
};
|
|
22
|
+
} else {
|
|
23
|
+
if (!col._oldRender) {
|
|
24
|
+
col._oldRender = col.render;
|
|
25
|
+
col.render = (v, record, index) => {
|
|
26
|
+
const cmp = col._oldRender(v, record, index);
|
|
27
|
+
return React.createElement(cmp.type,
|
|
28
|
+
{
|
|
29
|
+
...cmp.props,
|
|
30
|
+
value: v,
|
|
31
|
+
onChange: (e) => {
|
|
32
|
+
this.onCellChange(index, col.dataIndex, e);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return col;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
this.columns.push({
|
|
42
|
+
title: '操作',
|
|
43
|
+
render: (v, record) => {
|
|
44
|
+
return <Button icon={<DeleteOutlined/>} title='删除' size='small' shape={'circle'}
|
|
45
|
+
onClick={() => this.remove(record)}></Button>;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
this.state = {
|
|
50
|
+
dataSource: this.props.value || []
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
state = {
|
|
56
|
+
dataSource: []
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
onCellChange = (index, dataIndex, e) => {
|
|
60
|
+
let {dataSource} = this.state;
|
|
61
|
+
let row = dataSource[index];
|
|
62
|
+
|
|
63
|
+
let v = e;
|
|
64
|
+
if (e != null && e.hasOwnProperty('target')) {
|
|
65
|
+
v = e.target.value;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
row[dataIndex] = v;
|
|
69
|
+
|
|
70
|
+
dataSource = [...dataSource];
|
|
71
|
+
this.setState({dataSource}, this.notifyParent);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
add = () => {
|
|
75
|
+
let {dataSource} = this.state;
|
|
76
|
+
dataSource = [...dataSource, {}];
|
|
77
|
+
this.setState({dataSource}, this.notifyParent);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
remove = (record) => {
|
|
81
|
+
let {dataSource} = this.state;
|
|
82
|
+
ArrUtils.remove(dataSource, record);
|
|
83
|
+
this.setState({dataSource: [...dataSource]}, this.notifyParent);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
notifyParent = () => {
|
|
87
|
+
let {dataSource} = this.state;
|
|
88
|
+
this.props.onChange && this.props.onChange(dataSource);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
render() {
|
|
92
|
+
return <div className='edit-table' style={this.props.style}>
|
|
93
|
+
<Table columns={this.columns}
|
|
94
|
+
dataSource={this.state.dataSource}
|
|
95
|
+
size='small'
|
|
96
|
+
footer={() => <Button type='dashed'
|
|
97
|
+
icon={<PlusOutlined/>}
|
|
98
|
+
onClick={this.add}>增加一行
|
|
99
|
+
</Button>}
|
|
100
|
+
pagination={false}
|
|
101
|
+
>
|
|
102
|
+
|
|
103
|
+
</Table>
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
</div>;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
.edit-table {
|
|
2
|
+
table{
|
|
3
|
+
width: 100%;
|
|
4
|
+
border-spacing: 0;
|
|
5
|
+
|
|
6
|
+
th {
|
|
7
|
+
background-color: rgb(250, 250, 250);
|
|
8
|
+
padding: 16px;
|
|
9
|
+
color: rgba(0, 0, 0, 0.88);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
th:last-child, td:last-child {
|
|
15
|
+
text-align: center;
|
|
16
|
+
width: 50px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
td {
|
|
20
|
+
padding: 2px;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
.add-btn-wrapper{
|
|
26
|
+
margin: 8px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { FieldProps } from '../types';
|
|
3
|
+
import {ColumnsType} from "antd/es/table";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 下拉表格
|
|
7
|
+
*
|
|
8
|
+
* 后端参考接口:
|
|
9
|
+
*/
|
|
10
|
+
interface FieldTableSelectProps extends FieldProps<string | number> {
|
|
11
|
+
url: string;
|
|
12
|
+
placeholder?: string;
|
|
13
|
+
|
|
14
|
+
// antd table 的列表
|
|
15
|
+
columns: ColumnsType<any>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class FieldTableSelect extends React.Component<FieldTableSelectProps, any> {
|
|
19
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {Button, Select} from "antd";
|
|
3
|
+
import {ProTable} from "../../components";
|
|
4
|
+
import {HttpUtils} from "../../utils";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 下拉表格
|
|
8
|
+
*
|
|
9
|
+
* 后端参考接口:
|
|
10
|
+
*/
|
|
11
|
+
export class FieldTableSelect extends React.Component {
|
|
12
|
+
|
|
13
|
+
static defaultProps = {
|
|
14
|
+
placeholder: '请搜索选择',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
state = {
|
|
18
|
+
open: false,
|
|
19
|
+
label: '',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
render() {
|
|
23
|
+
return <Select popupRender={this.popupRender}
|
|
24
|
+
open={this.state.open}
|
|
25
|
+
onOpenChange={v => this.setState({open: v})}
|
|
26
|
+
style={{minWidth: 300}}
|
|
27
|
+
value={this.props.value}
|
|
28
|
+
labelRender={() => this.state.label}
|
|
29
|
+
popupMatchSelectWidth={900}
|
|
30
|
+
placeholder={this.props.placeholder}
|
|
31
|
+
/>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
popupRender = () => {
|
|
35
|
+
return <ProTable
|
|
36
|
+
columns={[...this.props.columns, {
|
|
37
|
+
title: '操作',
|
|
38
|
+
dataIndex: 'action',
|
|
39
|
+
width: 100,
|
|
40
|
+
render: (text, record) => {
|
|
41
|
+
return <Button
|
|
42
|
+
size='small'
|
|
43
|
+
type='primary'
|
|
44
|
+
onClick={() => {
|
|
45
|
+
this.setState({
|
|
46
|
+
label: record.name,
|
|
47
|
+
open: false
|
|
48
|
+
});
|
|
49
|
+
this.props.onChange && this.props.onChange(record.id);
|
|
50
|
+
}}>选择</Button>;
|
|
51
|
+
}
|
|
52
|
+
}]}
|
|
53
|
+
showToolbarSearch
|
|
54
|
+
request={(params) => {
|
|
55
|
+
params.selected = this.props.value;
|
|
56
|
+
return HttpUtils.get(this.props.url, params);
|
|
57
|
+
}}>
|
|
58
|
+
</ProTable>;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {CropperProps} from "react-easy-crop/Cropper";
|
|
3
|
+
import {UploadListType} from "antd/es/upload/interface";
|
|
4
|
+
import { FieldProps } from '../types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 上传图片前裁切, 单张图片
|
|
8
|
+
*
|
|
9
|
+
* 可参考 react-easy-crop
|
|
10
|
+
*/
|
|
11
|
+
interface FieldUploadFileProps extends FieldProps<string> {
|
|
12
|
+
onFileChange?: (fileList: any[]) => void;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 是否裁切图片
|
|
16
|
+
*/
|
|
17
|
+
cropImage?: boolean;
|
|
18
|
+
cropperProps?: CropperProps;
|
|
19
|
+
|
|
20
|
+
maxCount?: number;
|
|
21
|
+
|
|
22
|
+
accept?: "image/*" | ".pdf" | ".docx" | '.xlsx' | string;
|
|
23
|
+
|
|
24
|
+
children?: React.ReactNode;
|
|
25
|
+
|
|
26
|
+
listType?: UploadListType;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class FieldUploadFile extends React.Component<FieldUploadFileProps, string> {
|
|
30
|
+
|
|
31
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import ImgCrop from "antd-img-crop";
|
|
3
|
+
import {Modal, Upload} from "antd";
|
|
4
|
+
import UploadOutlined from "@ant-design/icons/lib/icons/UploadOutlined";
|
|
5
|
+
import {ViewFile} from "../../views";
|
|
6
|
+
import {ObjectUtils} from "../../utils";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 上传图片前裁切, 单张图片
|
|
10
|
+
*
|
|
11
|
+
* 可参考 react-easy-crop
|
|
12
|
+
*/
|
|
13
|
+
export class FieldUploadFile extends React.Component {
|
|
14
|
+
|
|
15
|
+
state = {
|
|
16
|
+
// 传入的参数
|
|
17
|
+
maxCount: 1,
|
|
18
|
+
cropImage: false,
|
|
19
|
+
|
|
20
|
+
// 内部参数
|
|
21
|
+
fileList: [],
|
|
22
|
+
value: null, // 都好分隔的文件id
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
constructor(props) {
|
|
26
|
+
super(props);
|
|
27
|
+
ObjectUtils.copyPropertyIfPresent(props, this.state);
|
|
28
|
+
this.state.fileList = this.convertInputToComponentValue(this.state.value);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
convertInputToComponentValue(value) {
|
|
32
|
+
const list = [];
|
|
33
|
+
if (value && value.length > 0) {
|
|
34
|
+
const arr = value.split(",");
|
|
35
|
+
for (const id of arr) {
|
|
36
|
+
const url = 'admin/sysFile/preview/' + id;
|
|
37
|
+
const file = {id, url, uid: id, name: id, status: 'done', fileName: id};
|
|
38
|
+
list.push(file);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return list;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
convertComponentValueToOutput(fileList) {
|
|
46
|
+
const fileIds = [];
|
|
47
|
+
for (const f of fileList) {
|
|
48
|
+
if (f.status === 'done') {
|
|
49
|
+
if (f.response) { // 新上传的
|
|
50
|
+
const ajaxResult = f.response;
|
|
51
|
+
if (ajaxResult.success) {
|
|
52
|
+
const {id, name} = ajaxResult.data;
|
|
53
|
+
f.id = id;
|
|
54
|
+
fileIds.push(id);
|
|
55
|
+
} else {
|
|
56
|
+
Modal.error({title: '上传文件失败', content: ajaxResult.message});
|
|
57
|
+
}
|
|
58
|
+
} else { // 老的
|
|
59
|
+
fileIds.push(f.id);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return fileIds;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
handleChange = ({fileList, event, file}) => {
|
|
67
|
+
console.log('检测到文件变化', fileList);
|
|
68
|
+
const rs = file.response;
|
|
69
|
+
if (rs != null && rs.success === false) {
|
|
70
|
+
Modal.error({
|
|
71
|
+
title: '上传失败',
|
|
72
|
+
content: rs.message,
|
|
73
|
+
});
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
this.setState({fileList});
|
|
78
|
+
|
|
79
|
+
const newIds = this.convertComponentValueToOutput(fileList);
|
|
80
|
+
if (newIds.length > 0 && this.props.onFileChange) {
|
|
81
|
+
this.props.onFileChange(fileList);
|
|
82
|
+
}
|
|
83
|
+
if (this.props.onChange) {
|
|
84
|
+
const value = newIds.join(',');
|
|
85
|
+
console.log('上传文件值', value);
|
|
86
|
+
this.props.onChange(value);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
handlePreview = (file) => {
|
|
92
|
+
Modal.info({
|
|
93
|
+
title: '文件预览',
|
|
94
|
+
width: '80vw',
|
|
95
|
+
content: <ViewFile value={file.id} height='70vh'/>
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
render() {
|
|
101
|
+
if (this.state.cropImage) {
|
|
102
|
+
return <ImgCrop cropperProps={this.props.cropperProps} modalTitle={'裁剪图片'} fillColor={null}>
|
|
103
|
+
{this.getUpload()}
|
|
104
|
+
</ImgCrop>;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return this.getUpload();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
getUpload = () => {
|
|
111
|
+
const {accept, fileList, maxCount} = this.state;
|
|
112
|
+
|
|
113
|
+
return <Upload
|
|
114
|
+
action={'admin/sysFile/upload'}
|
|
115
|
+
listType={this.props.listType || 'picture-card'}
|
|
116
|
+
fileList={fileList}
|
|
117
|
+
onChange={this.handleChange}
|
|
118
|
+
multiple={false}
|
|
119
|
+
accept={accept}
|
|
120
|
+
maxCount={maxCount}
|
|
121
|
+
onPreview={this.handlePreview}
|
|
122
|
+
>
|
|
123
|
+
{this.renderButton()}
|
|
124
|
+
|
|
125
|
+
</Upload>;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
renderButton = () => {
|
|
129
|
+
const {fileList, maxCount} = this.state;
|
|
130
|
+
if (fileList.length >= maxCount) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return <>
|
|
135
|
+
<UploadOutlined/>
|
|
136
|
+
<div className="ant-upload-text">选择文件</div>
|
|
137
|
+
</>;
|
|
138
|
+
};
|
|
139
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// 表单组件,主要属性: value onChange
|
|
2
|
+
export * from './types';
|
|
3
|
+
export * from './FieldRemoteSelect';
|
|
4
|
+
export * from './FieldRemoteSelectMultiple';
|
|
5
|
+
export * from './FieldRemoteSelectMultipleInline';
|
|
6
|
+
export * from './FieldRemoteTree';
|
|
7
|
+
export * from './FieldDictSelect';
|
|
8
|
+
export * from './FieldEditor'
|
|
9
|
+
export * from './FieldRemoteTreeCascader'
|
|
10
|
+
export * from './FieldRemoteTreeSelect'
|
|
11
|
+
export * from './FieldRemoteTreeSelectMultiple'
|
|
12
|
+
export * from './FieldBoolean';
|
|
13
|
+
export * from './FieldDate';
|
|
14
|
+
export * from './FieldDateRange';
|
|
15
|
+
export * from './FieldNumberRange';
|
|
16
|
+
export * from './FieldTable'
|
|
17
|
+
export * from './FieldTableSelect'
|
|
18
|
+
export * from './FieldSysOrgTreeSelect'
|
|
19
|
+
export * from './FieldSysOrgTree'
|
|
20
|
+
export * from './FieldPercent'
|
|
21
|
+
export * from './FieldUploadFile';
|
|
22
|
+
export * from '../components/OrgTree';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React, {ReactNode} from "react";
|
|
2
|
+
|
|
3
|
+
export interface LoginPageProps {
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 表单渲染
|
|
7
|
+
* @param origForm 原始表单
|
|
8
|
+
*/
|
|
9
|
+
formRender?: (originalForm: ReactNode) => ReactNode
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class LoginPage extends React.Component<LoginPageProps, any> {
|
|
15
|
+
}
|
|
16
|
+
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {Button, Form, Input, message, Space} from 'antd';
|
|
3
|
+
import {LockOutlined, SafetyCertificateOutlined, UserOutlined, WarningOutlined} from '@ant-design/icons';
|
|
4
|
+
import "./LoginPage.less"
|
|
5
|
+
import {MessageUtils, SysUtils} from "../utils";
|
|
6
|
+
import {JSEncrypt} from "jsencrypt";
|
|
7
|
+
import {LoginPageUtils} from "./LoginPageUtils";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export class LoginPage extends React.Component {
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
state = {
|
|
14
|
+
logging: false,
|
|
15
|
+
|
|
16
|
+
siteInfo: {},
|
|
17
|
+
random: Math.random()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async componentDidMount() {
|
|
21
|
+
console.log('渲染登录页面')
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
if (localStorage.length === 0) {
|
|
25
|
+
MessageUtils.alert('站点数据缺失,刷新当前页面...')
|
|
26
|
+
window.location.reload()
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const siteInfo = SysUtils.getSiteInfo()
|
|
31
|
+
this.setState({siteInfo})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
submit = values => {
|
|
36
|
+
this.setState({logging: true})
|
|
37
|
+
|
|
38
|
+
const pubkey = this.state.siteInfo.rsaPublicKey;
|
|
39
|
+
if (!pubkey) {
|
|
40
|
+
message.error("未获取密钥,请刷新浏览器再试")
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
// 对密码加密
|
|
44
|
+
const crypt = new JSEncrypt();
|
|
45
|
+
crypt.setPublicKey(pubkey);
|
|
46
|
+
values.password = crypt.encrypt(values.password)
|
|
47
|
+
|
|
48
|
+
LoginPageUtils.postLogin(values).finally(()=>{
|
|
49
|
+
this.setState({logging: false})
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
render() {
|
|
55
|
+
const {siteInfo} = this.state
|
|
56
|
+
|
|
57
|
+
const pageStyle = {}
|
|
58
|
+
if (siteInfo.loginBackground) {
|
|
59
|
+
let url = 'admin/sysFile/preview/' + siteInfo.loginBackground;
|
|
60
|
+
pageStyle.backgroundImage = 'url("' + url + '")'
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<section className='login-page' style={pageStyle}>
|
|
65
|
+
<div className="login-content">
|
|
66
|
+
<h1>{siteInfo.title}</h1>
|
|
67
|
+
{this.getForm(siteInfo)}
|
|
68
|
+
|
|
69
|
+
{this.renderFormBottom()}
|
|
70
|
+
|
|
71
|
+
</div>
|
|
72
|
+
</section>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
getForm = siteInfo => {
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
const form = <Form
|
|
81
|
+
name="normal_login"
|
|
82
|
+
className="login-form"
|
|
83
|
+
initialValues={{remember: true}}
|
|
84
|
+
onFinish={this.submit}
|
|
85
|
+
requiredMark={false}
|
|
86
|
+
colon={false}
|
|
87
|
+
>
|
|
88
|
+
|
|
89
|
+
<Form.Item name="username" rules={[{required: true, message: '请输入用户名!'}]}>
|
|
90
|
+
<Input size='large' prefix={<UserOutlined/>} placeholder="用户名" autoComplete="off"/>
|
|
91
|
+
</Form.Item>
|
|
92
|
+
<Form.Item name="password" rules={[{required: true, message: '请输入密码!'}]}>
|
|
93
|
+
<Input autoComplete="off" prefix={<LockOutlined/>} type="password" placeholder="密码"
|
|
94
|
+
size='large'
|
|
95
|
+
/>
|
|
96
|
+
</Form.Item>
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
{siteInfo.captcha && <Form.Item name='captchaCode' rules={[{required: true}]}>
|
|
100
|
+
<Space style={{alignItems: 'center'}}>
|
|
101
|
+
<Input size='large' placeholder='验证码' prefix={<SafetyCertificateOutlined/>}/>
|
|
102
|
+
<img height={36}
|
|
103
|
+
width={100}
|
|
104
|
+
src={"/admin/auth/captchaImage?_random=" + this.state.random}
|
|
105
|
+
onClick={() => {
|
|
106
|
+
this.setState({random: Math.random()})
|
|
107
|
+
}}></img>
|
|
108
|
+
</Space>
|
|
109
|
+
</Form.Item>}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
<Form.Item style={{marginTop: 10}}>
|
|
113
|
+
<Button loading={this.state.logging} type="primary" htmlType="submit"
|
|
114
|
+
block size='large'>
|
|
115
|
+
登录
|
|
116
|
+
</Button>
|
|
117
|
+
</Form.Item>
|
|
118
|
+
</Form>;
|
|
119
|
+
|
|
120
|
+
if(this.props.formRender){
|
|
121
|
+
return this.props.formRender(form);
|
|
122
|
+
}
|
|
123
|
+
return form;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
renderFormBottom() {
|
|
127
|
+
let siteInfo = this.state.siteInfo;
|
|
128
|
+
if (siteInfo.loginBoxBottomTip) {
|
|
129
|
+
return <div style={{color: 'white', marginTop: 50, fontSize: '14px', textAlign: 'center'}}>
|
|
130
|
+
<WarningOutlined/> {siteInfo.loginBoxBottomTip}
|
|
131
|
+
</div>
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
}
|