@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,14 +1,10 @@
|
|
|
1
|
-
export * from './system'
|
|
2
1
|
export * from './PageLoading'
|
|
3
2
|
export * from './ProTable'
|
|
4
|
-
export * from './DownloadFileButton'
|
|
5
3
|
export * from './NamedIcon'
|
|
6
4
|
export * from './LinkButton'
|
|
7
5
|
export * from './Gap'
|
|
8
6
|
export * from './Page'
|
|
9
7
|
export * from './ValueType'
|
|
10
8
|
export * from './ContextMenu'
|
|
11
|
-
export * from './
|
|
12
|
-
export
|
|
13
|
-
export * from './ViewRange'
|
|
14
|
-
export { default as ErrorBoundary } from './ErrorBoundary'
|
|
9
|
+
export * from './DownloadModal'
|
|
10
|
+
export { default as ErrorBoundary } from './ErrorBoundary'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Spin
|
|
2
|
+
import { Spin } from 'antd';
|
|
3
3
|
import { debounce } from 'lodash';
|
|
4
4
|
import { HttpUtils } from '../../utils';
|
|
5
5
|
|
|
@@ -80,8 +80,7 @@ export class BaseRemoteSelect<P extends BaseRemoteSelectProps = BaseRemoteSelect
|
|
|
80
80
|
this.setState({ data: data || [] });
|
|
81
81
|
}
|
|
82
82
|
} catch (error) {
|
|
83
|
-
console.
|
|
84
|
-
message.error('加载失败,请重试');
|
|
83
|
+
console.warn('[BaseRemoteSelect] 加载失败:', error);
|
|
85
84
|
if (fetchId === this.fetchIdRef) {
|
|
86
85
|
this.setState({ data: [] });
|
|
87
86
|
}
|
|
@@ -25,10 +25,9 @@ export class FieldBoolean extends React.Component {
|
|
|
25
25
|
|
|
26
26
|
switch (type) {
|
|
27
27
|
case 'radio':
|
|
28
|
-
return <Radio.Group value={v} onChange={onChange}>
|
|
28
|
+
return <Radio.Group value={v} onChange={e => onChange && onChange(e.target.value)}>
|
|
29
29
|
<Radio value={true}>是</Radio>
|
|
30
30
|
<Radio value={false}>否</Radio>
|
|
31
|
-
<Radio value={undefined}>不确定</Radio>
|
|
32
31
|
</Radio.Group>;
|
|
33
32
|
case 'checkbox':
|
|
34
33
|
return <Checkbox
|
|
@@ -43,7 +42,7 @@ export class FieldBoolean extends React.Component {
|
|
|
43
42
|
{value: false, label: '否'},
|
|
44
43
|
]}
|
|
45
44
|
value={v}
|
|
46
|
-
onChange={onChange}
|
|
45
|
+
onChange={value => onChange && onChange(value)}
|
|
47
46
|
style={{width: '100%'}}
|
|
48
47
|
allowClear={true}
|
|
49
48
|
placeholder={'请选择'}
|
|
@@ -51,7 +50,7 @@ export class FieldBoolean extends React.Component {
|
|
|
51
50
|
case 'switch':
|
|
52
51
|
return <Switch
|
|
53
52
|
checked={v}
|
|
54
|
-
onChange={onChange}
|
|
53
|
+
onChange={checked => onChange && onChange(checked)}
|
|
55
54
|
/>;
|
|
56
55
|
default:
|
|
57
56
|
return null;
|
|
@@ -77,27 +77,6 @@ export class FieldDate extends React.Component {
|
|
|
77
77
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
static getDefaultValue(type) {
|
|
81
|
-
const year = dayjs().format("YYYY");
|
|
82
|
-
const month = dayjs().format("YYYY-MM");
|
|
83
|
-
const quarter = dayjs().format("YYYY-QQ");
|
|
84
|
-
|
|
85
|
-
switch (type) {
|
|
86
|
-
case 'YYYY':
|
|
87
|
-
case 'YEAR':
|
|
88
|
-
return year;
|
|
89
|
-
case 'YYYY-MM':
|
|
90
|
-
case 'YEAR_MONTH':
|
|
91
|
-
return month;
|
|
92
|
-
case 'YYYY-QQ':
|
|
93
|
-
case 'YEAR_QUARTER':
|
|
94
|
-
return quarter;
|
|
95
|
-
default:
|
|
96
|
-
return null;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
|
|
101
80
|
strToDate(value, fmt) {
|
|
102
81
|
if (value != null && value !== '') {
|
|
103
82
|
const type = typeof value;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import {Editor as TinyMceEditor} from '@tinymce/tinymce-react';
|
|
3
|
-
import {
|
|
3
|
+
import {UrlUtils} from '../../utils';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* 富文本编辑器
|
|
@@ -9,52 +9,43 @@ import {SysUtils} from '../../utils';
|
|
|
9
9
|
*/
|
|
10
10
|
export class FieldEditor extends React.Component {
|
|
11
11
|
render() {
|
|
12
|
-
const uploadUrl =
|
|
13
|
-
const jsUrl =
|
|
12
|
+
const uploadUrl = UrlUtils.contextPath('/admin/sysFile/upload');
|
|
13
|
+
const jsUrl = UrlUtils.contextPath('/admin/tinymce/tinymce.min.js');
|
|
14
14
|
const {value, onChange, height} = this.props;
|
|
15
15
|
|
|
16
16
|
return (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}}
|
|
51
|
-
onChange={e => {
|
|
52
|
-
if (onChange) {
|
|
53
|
-
onChange(e.target.getContent());
|
|
54
|
-
}
|
|
55
|
-
}}
|
|
56
|
-
/>
|
|
57
|
-
</>
|
|
17
|
+
<TinyMceEditor
|
|
18
|
+
value={value}
|
|
19
|
+
tinymceScriptSrc={jsUrl}
|
|
20
|
+
init={{
|
|
21
|
+
min_height: 300,
|
|
22
|
+
language: 'zh_CN',
|
|
23
|
+
height: height,
|
|
24
|
+
images_upload_url: uploadUrl,
|
|
25
|
+
promotion: false,
|
|
26
|
+
cache_suffix: '?v=v7.7',
|
|
27
|
+
plugins: [
|
|
28
|
+
'advlist', 'autolink', 'lists', 'link', 'image', 'charmap', 'preview',
|
|
29
|
+
'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen',
|
|
30
|
+
'insertdatetime', 'media', 'table', 'code', 'help', 'wordcount',
|
|
31
|
+
'emoticons'
|
|
32
|
+
],
|
|
33
|
+
image_description: false,
|
|
34
|
+
setup: function (editor) {
|
|
35
|
+
editor.on('OpenWindow', function(e) {
|
|
36
|
+
const dialog = e.dialog;
|
|
37
|
+
if (dialog && dialog.getData().dimensions) {
|
|
38
|
+
dialog.showTab("upload");
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
}}
|
|
43
|
+
onEditorChange={content => {
|
|
44
|
+
if (onChange) {
|
|
45
|
+
onChange(content);
|
|
46
|
+
}
|
|
47
|
+
}}
|
|
48
|
+
/>
|
|
58
49
|
);
|
|
59
50
|
}
|
|
60
51
|
}
|
|
@@ -34,9 +34,9 @@ export class FieldNumberRange extends React.Component {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
componentDidMount() {
|
|
37
|
-
const {value, defaultValue} = this.props;
|
|
37
|
+
const {value, defaultValue, onChange} = this.props;
|
|
38
38
|
if (value == null && defaultValue) {
|
|
39
|
-
|
|
39
|
+
onChange && onChange(defaultValue);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -20,7 +20,7 @@ export class FieldRemoteTree extends BaseRemoteSelect {
|
|
|
20
20
|
<Tree
|
|
21
21
|
multiple
|
|
22
22
|
checkable
|
|
23
|
-
onCheck={(
|
|
23
|
+
onCheck={(checkedInfo) => this.props.onChange && this.props.onChange(checkedInfo.checked)}
|
|
24
24
|
checkedKeys={this.props.value}
|
|
25
25
|
treeData={this.state.data}
|
|
26
26
|
defaultExpandAll
|
|
@@ -2,7 +2,6 @@ import {Button, Input, Table} from 'antd'
|
|
|
2
2
|
import React from 'react'
|
|
3
3
|
import {DeleteOutlined, PlusOutlined} from "@ant-design/icons";
|
|
4
4
|
import './styles.less'
|
|
5
|
-
import {ArrayUtils} from "../../utils";
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* 可编辑表格
|
|
@@ -15,27 +14,27 @@ export class FieldTable extends React.Component {
|
|
|
15
14
|
super(props);
|
|
16
15
|
|
|
17
16
|
this.columns = this.props.columns.map(col => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
const newCol = { ...col };
|
|
18
|
+
const origRender = newCol.render;
|
|
19
|
+
|
|
20
|
+
if (origRender) {
|
|
21
|
+
newCol.render = (v, record, index) => {
|
|
22
|
+
const cmp = origRender(v, record, index);
|
|
23
|
+
return React.createElement(cmp.type, {
|
|
24
|
+
...cmp.props,
|
|
25
|
+
value: v,
|
|
26
|
+
onChange: (e) => {
|
|
27
|
+
this.onCellChange(index, newCol.dataIndex, e);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
21
30
|
};
|
|
22
31
|
} else {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
}
|
|
32
|
+
newCol.render = (v, record, index) => {
|
|
33
|
+
return <Input value={v} onChange={(e) => this.onCellChange(index, newCol.dataIndex, e)}/>;
|
|
34
|
+
};
|
|
37
35
|
}
|
|
38
|
-
|
|
36
|
+
|
|
37
|
+
return newCol;
|
|
39
38
|
});
|
|
40
39
|
|
|
41
40
|
this.columns.push({
|
|
@@ -57,18 +56,17 @@ export class FieldTable extends React.Component {
|
|
|
57
56
|
};
|
|
58
57
|
|
|
59
58
|
onCellChange = (index, dataIndex, e) => {
|
|
60
|
-
|
|
59
|
+
const {dataSource} = this.state;
|
|
61
60
|
const row = dataSource[index];
|
|
62
61
|
|
|
63
62
|
let v = e;
|
|
64
|
-
if (e != null && e
|
|
63
|
+
if (e != null && typeof e === 'object' && 'target' in e) {
|
|
65
64
|
v = e.target.value;
|
|
66
65
|
}
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
dataSource
|
|
71
|
-
this.setState({dataSource}, this.notifyParent);
|
|
67
|
+
const next = [...dataSource];
|
|
68
|
+
next[index] = {...row, [dataIndex]: v};
|
|
69
|
+
this.setState({dataSource: next}, this.notifyParent);
|
|
72
70
|
};
|
|
73
71
|
|
|
74
72
|
add = () => {
|
|
@@ -79,8 +77,7 @@ export class FieldTable extends React.Component {
|
|
|
79
77
|
|
|
80
78
|
remove = (record) => {
|
|
81
79
|
const {dataSource} = this.state;
|
|
82
|
-
|
|
83
|
-
this.setState({dataSource: [...dataSource]}, this.notifyParent);
|
|
80
|
+
this.setState({dataSource: dataSource.filter(item => item !== record)}, this.notifyParent);
|
|
84
81
|
};
|
|
85
82
|
|
|
86
83
|
notifyParent = () => {
|
|
@@ -3,7 +3,7 @@ import ImgCrop from "antd-img-crop";
|
|
|
3
3
|
import {Modal, Upload, message} from "antd";
|
|
4
4
|
import { UploadOutlined } from "@ant-design/icons";
|
|
5
5
|
import {ViewFile} from "../../views";
|
|
6
|
-
import {ObjectUtils,
|
|
6
|
+
import {ObjectUtils, UrlUtils} from "../../utils";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* 上传图片前裁切, 单张图片
|
|
@@ -28,12 +28,19 @@ export class FieldUploadFile extends React.Component {
|
|
|
28
28
|
this.state.fileList = this.convertInputToComponentValue(this.state.value);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
componentDidUpdate(prevProps) {
|
|
32
|
+
const next = {};
|
|
33
|
+
if (this.props.maxCount !== prevProps.maxCount) next.maxCount = this.props.maxCount;
|
|
34
|
+
if (this.props.cropImage !== prevProps.cropImage) next.cropImage = this.props.cropImage;
|
|
35
|
+
if (Object.keys(next).length > 0) this.setState(next);
|
|
36
|
+
}
|
|
37
|
+
|
|
31
38
|
convertInputToComponentValue(value) {
|
|
32
39
|
const list = [];
|
|
33
40
|
if (value && value.length > 0) {
|
|
34
41
|
const arr = value.split(",");
|
|
35
42
|
for (const id of arr) {
|
|
36
|
-
const url =
|
|
43
|
+
const url = UrlUtils.contextPath('/admin/sysFile/preview/' + id);
|
|
37
44
|
const file = {id, url, uid: id, name: id, status: 'done', fileName: id};
|
|
38
45
|
list.push(file);
|
|
39
46
|
}
|
|
@@ -113,7 +120,7 @@ export class FieldUploadFile extends React.Component {
|
|
|
113
120
|
const {accept, fileList, maxCount} = this.state;
|
|
114
121
|
|
|
115
122
|
return <Upload
|
|
116
|
-
action={
|
|
123
|
+
action={UrlUtils.contextPath('/admin/sysFile/upload')}
|
|
117
124
|
listType={this.props.listType || 'picture-card'}
|
|
118
125
|
fileList={fileList}
|
|
119
126
|
onChange={this.handleChange}
|
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
export * from './types';
|
|
3
3
|
export * from './FieldRemoteSelect';
|
|
4
4
|
export * from './FieldRemoteSelectMultiple';
|
|
5
|
-
export * from './FieldRemoteSelectMultipleInline';
|
|
6
5
|
export * from './FieldRemoteTree';
|
|
7
6
|
export * from './FieldDictSelect';
|
|
8
7
|
export * from './FieldEditor'
|
|
9
8
|
export * from './FieldRemoteTreeCascader'
|
|
10
9
|
export * from './FieldRemoteTreeSelect'
|
|
11
|
-
export * from './FieldRemoteTreeSelectMultiple'
|
|
12
10
|
export * from './FieldBoolean';
|
|
13
11
|
export * from './FieldDate';
|
|
14
12
|
export * from './FieldDateRange';
|
|
@@ -19,4 +17,4 @@ export * from './FieldSysOrgTreeSelect'
|
|
|
19
17
|
export * from './FieldSysOrgTree'
|
|
20
18
|
export * from './FieldPercent'
|
|
21
19
|
export * from './FieldUploadFile';
|
|
22
|
-
export * from '../
|
|
20
|
+
export * from '../biz/OrgTree';
|
package/src/framework/index.ts
CHANGED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export class ArrayUtils {
|
|
2
|
+
static contains(arr, item) {
|
|
3
|
+
return arr.indexOf(item) !== -1;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
static containsAny(arr, ...items) {
|
|
7
|
+
for (const item of items) {
|
|
8
|
+
if (ArrayUtils.contains(arr, item)) return true;
|
|
9
|
+
}
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
static maxBy(arr, key) {
|
|
14
|
+
if (arr == null || arr.length === 0) return undefined;
|
|
15
|
+
let maxElement = undefined;
|
|
16
|
+
let maxValue = -Infinity;
|
|
17
|
+
for (const element of arr) {
|
|
18
|
+
const value = element[key];
|
|
19
|
+
if (typeof value === 'number' && value > maxValue) {
|
|
20
|
+
maxValue = value;
|
|
21
|
+
maxElement = element;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return maxElement;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static unique(arr) {
|
|
28
|
+
return [...new Set(arr)];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export class DateUtils {
|
|
2
|
+
static convertTypeToFormat(type: string): string;
|
|
3
|
+
static year(date: Date): number;
|
|
4
|
+
static month(date: Date): string;
|
|
5
|
+
static date(date: Date): string;
|
|
6
|
+
static hour(date: Date): string;
|
|
7
|
+
static minute(date: Date): string;
|
|
8
|
+
static second(date: Date): string;
|
|
9
|
+
static formatDate(d: Date): string;
|
|
10
|
+
static formatTime(d: Date): string;
|
|
11
|
+
static formatDateTime(d: Date): string;
|
|
12
|
+
static formatDateCn(d: Date): string;
|
|
13
|
+
static now(): string;
|
|
14
|
+
static today(): string;
|
|
15
|
+
static thisYear(): number;
|
|
16
|
+
static thisMonth(): string;
|
|
17
|
+
static friendlyTime(pastDate: Date | string | number): string | undefined;
|
|
18
|
+
static friendlyTotalTime(time: number | string | null): string | null;
|
|
19
|
+
static beginOfMonth(): string;
|
|
20
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {StringUtils} from './StringUtils';
|
|
2
|
+
|
|
3
|
+
export class DateUtils {
|
|
4
|
+
static convertTypeToFormat(type) {
|
|
5
|
+
if (type === 'YEAR') type = 'YYYY';
|
|
6
|
+
else if (type === 'YEAR_MONTH') type = 'YYYY-MM';
|
|
7
|
+
else if (type === 'YEAR_QUARTER') type = 'YYYY-QQ';
|
|
8
|
+
else if (type === 'DAY') type = 'YYYY-MM-DD';
|
|
9
|
+
return type;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static year(date) { return date.getFullYear(); }
|
|
13
|
+
static month(date) { return StringUtils.pad(date.getMonth() + 1, 2); }
|
|
14
|
+
static date(date) { return StringUtils.pad(date.getDate(), 2); }
|
|
15
|
+
static hour(date) { return StringUtils.pad(date.getHours(), 2); }
|
|
16
|
+
static minute(date) { return StringUtils.pad(date.getMinutes(), 2); }
|
|
17
|
+
static second(date) { return StringUtils.pad(date.getSeconds(), 2); }
|
|
18
|
+
|
|
19
|
+
static formatDate(d) {
|
|
20
|
+
return this.year(d) + '-' + this.month(d) + '-' + this.date(d);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static formatTime(d) {
|
|
24
|
+
return this.hour(d) + ':' + this.minute(d) + ':' + this.second(d);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static formatDateTime(d) {
|
|
28
|
+
return this.formatDate(d) + ' ' + this.formatTime(d);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static formatDateCn(d) {
|
|
32
|
+
return this.year(d) + '年' + (d.getMonth() + 1) + '月' + d.getDate() + '日';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static now() { return this.formatDateTime(new Date()); }
|
|
36
|
+
static today() { return this.formatDate(new Date()); }
|
|
37
|
+
static thisYear() { return this.year(new Date()); }
|
|
38
|
+
static thisMonth() { return this.month(new Date()); }
|
|
39
|
+
|
|
40
|
+
static friendlyTime(pastDate) {
|
|
41
|
+
if (pastDate == null) return undefined;
|
|
42
|
+
if (!(pastDate instanceof Date)) pastDate = new Date(pastDate);
|
|
43
|
+
const currentDate = new Date();
|
|
44
|
+
let elapsedMilliseconds = currentDate.getTime() - pastDate.getTime();
|
|
45
|
+
const suffix = elapsedMilliseconds > 0 ? '前' : '后';
|
|
46
|
+
elapsedMilliseconds = Math.abs(elapsedMilliseconds);
|
|
47
|
+
const elapsedYears = Math.floor(elapsedMilliseconds / (1000 * 60 * 60 * 24 * 365));
|
|
48
|
+
const elapsedMonths = Math.floor(elapsedMilliseconds / (1000 * 60 * 60 * 24 * 30));
|
|
49
|
+
const elapsedDays = Math.floor(elapsedMilliseconds / (1000 * 60 * 60 * 24));
|
|
50
|
+
const elapsedHours = Math.floor(elapsedMilliseconds / (1000 * 60 * 60));
|
|
51
|
+
const elapsedMinutes = Math.floor(elapsedMilliseconds / (1000 * 60));
|
|
52
|
+
const elapsedSeconds = Math.floor(elapsedMilliseconds / 1000);
|
|
53
|
+
if (elapsedYears >= 1) return `${elapsedYears} 年${suffix}`;
|
|
54
|
+
if (elapsedMonths >= 1) return `${elapsedMonths} 个月${suffix}`;
|
|
55
|
+
if (elapsedDays >= 7) { const weeks = Math.floor(elapsedDays / 7); return `${weeks} 周${suffix}`; }
|
|
56
|
+
if (elapsedDays >= 1) return `${elapsedDays} 天${suffix}`;
|
|
57
|
+
if (elapsedHours >= 1) return `${elapsedHours} 小时${suffix}`;
|
|
58
|
+
if (elapsedMinutes >= 1) return `${elapsedMinutes} 分钟${suffix}`;
|
|
59
|
+
return `${elapsedSeconds} 秒${suffix}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static friendlyTotalTime(time) {
|
|
63
|
+
if (time == null || time === '-') return null;
|
|
64
|
+
let seconds;
|
|
65
|
+
if (typeof time === 'string') seconds = parseInt(time, 10) / 1000;
|
|
66
|
+
else seconds = time / 1000;
|
|
67
|
+
seconds = Math.floor(seconds);
|
|
68
|
+
if (seconds < 60) return seconds + '秒';
|
|
69
|
+
let min = seconds / 60;
|
|
70
|
+
seconds = seconds % 60;
|
|
71
|
+
min = Math.floor(min);
|
|
72
|
+
seconds = Math.floor(seconds);
|
|
73
|
+
return min + '分' + seconds + '秒';
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static beginOfMonth() {
|
|
77
|
+
const d = new Date();
|
|
78
|
+
d.setDate(1);
|
|
79
|
+
return this.formatDate(d);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export class DeviceUtils {
|
|
2
|
+
|
|
3
|
+
static isMobileDevice() {
|
|
4
|
+
const userAgent = navigator?.userAgent || navigator?.vendor || window?.opera || '';
|
|
5
|
+
if (/windows phone/i.test(userAgent)) return true;
|
|
6
|
+
if (/android/i.test(userAgent)) return true;
|
|
7
|
+
if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) return true;
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export class EventBus {
|
|
2
|
+
static on<T extends any[] = []>(name: string, callback: (...args: T) => void, ctx?: any): void;
|
|
3
|
+
static once<T extends any[] = []>(name: string, callback: (...args: T) => void, ctx?: any): void;
|
|
4
|
+
static emit<T extends any[] = []>(name: string, ...args: T): void;
|
|
5
|
+
static off<T extends any[] = []>(name: string, callback?: (...args: T) => void): void;
|
|
6
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export class EventBus {
|
|
2
|
+
static __stack = {};
|
|
3
|
+
|
|
4
|
+
static on(name, callback, ctx) {
|
|
5
|
+
if (!EventBus.__stack[name]) {
|
|
6
|
+
EventBus.__stack[name] = [];
|
|
7
|
+
}
|
|
8
|
+
EventBus.__stack[name].push({ fn: callback, ctx });
|
|
9
|
+
return () => EventBus.off(name, callback);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static once(name, callback, ctx) {
|
|
13
|
+
const unsubscribe = () => EventBus.off(name, callback);
|
|
14
|
+
const listener = (...args) => {
|
|
15
|
+
EventBus.off(name, listener);
|
|
16
|
+
callback.apply(ctx, args);
|
|
17
|
+
};
|
|
18
|
+
listener.__callback = callback;
|
|
19
|
+
EventBus.__stack[name] = EventBus.__stack[name] || [];
|
|
20
|
+
EventBus.__stack[name].push({ fn: listener, ctx });
|
|
21
|
+
return unsubscribe;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static emit(name, ...args) {
|
|
25
|
+
const list = EventBus.__stack[name];
|
|
26
|
+
if (list !== undefined) {
|
|
27
|
+
list.slice(0).forEach(entry => {
|
|
28
|
+
entry.fn.apply(entry.ctx, args);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static off(name, callback) {
|
|
34
|
+
const list = EventBus.__stack[name];
|
|
35
|
+
if (list === undefined) return;
|
|
36
|
+
if (callback === undefined) {
|
|
37
|
+
delete EventBus.__stack[name];
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const liveEvents = list.filter(
|
|
41
|
+
entry =>
|
|
42
|
+
entry.fn !== callback &&
|
|
43
|
+
entry.fn.__callback !== callback
|
|
44
|
+
);
|
|
45
|
+
if (liveEvents.length !== 0) {
|
|
46
|
+
EventBus.__stack[name] = liveEvents;
|
|
47
|
+
} else {
|
|
48
|
+
delete EventBus.__stack[name];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type {ModalFuncProps} from 'antd/es/modal/interface';
|
|
3
|
+
|
|
4
|
+
export class MessageUtils {
|
|
5
|
+
static alert(content: any, config?: Omit<ModalFuncProps, 'content' | 'icon' | 'onOk' | 'onCancel'>): Promise<void>;
|
|
6
|
+
static confirm(content: React.ReactNode, config?: Omit<ModalFuncProps, 'content' | 'icon' | 'onOk' | 'onCancel'>): Promise<boolean>;
|
|
7
|
+
static success(content: string, duration?: number): void;
|
|
8
|
+
static error(content: string, duration?: number): void;
|
|
9
|
+
static destroy(): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {message, Modal} from 'antd';
|
|
2
|
+
|
|
3
|
+
export class MessageUtils {
|
|
4
|
+
|
|
5
|
+
static alert(content, config) {
|
|
6
|
+
return new Promise(resolve => {
|
|
7
|
+
Modal.info({
|
|
8
|
+
title: '提示',
|
|
9
|
+
content,
|
|
10
|
+
okText: '确定',
|
|
11
|
+
onOk: () => resolve(),
|
|
12
|
+
icon: null,
|
|
13
|
+
...config,
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static confirm(content, config) {
|
|
19
|
+
return new Promise((resolve) => {
|
|
20
|
+
Modal.confirm({
|
|
21
|
+
title: '确认操作',
|
|
22
|
+
content,
|
|
23
|
+
okText: '确定',
|
|
24
|
+
cancelText: '取消',
|
|
25
|
+
onOk: () => resolve(true),
|
|
26
|
+
onCancel: () => resolve(false),
|
|
27
|
+
...config,
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static success(content, duration = 3) {
|
|
33
|
+
message.success(content, duration);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static error(content, duration = 3) {
|
|
37
|
+
message.error(content, duration);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static destroy() {
|
|
41
|
+
message.destroy();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {ObjectUtils} from './ObjectUtils';
|
|
2
|
+
|
|
3
|
+
declare module './ObjectUtils' {
|
|
4
|
+
interface ObjectUtils {
|
|
5
|
+
// Empty - no public methods to declare
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class ObjectUtils {
|
|
10
|
+
static copyPropertyIfPresent<TSource extends object, TTarget extends object>(
|
|
11
|
+
source: TSource | null | undefined,
|
|
12
|
+
target: TTarget | null | undefined
|
|
13
|
+
): void;
|
|
14
|
+
}
|