@jiangood/open-admin 1.3.4 → 2.0.1

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.
Files changed (153) hide show
  1. package/config/config.js +3 -8
  2. package/package.json +5 -9
  3. package/src/.umi-production/appData.json +325 -365
  4. package/src/.umi-production/core/helmet.ts +1 -1
  5. package/src/.umi-production/core/history.ts +1 -1
  6. package/src/.umi-production/core/historyIntelli.ts +1 -1
  7. package/src/.umi-production/core/pluginConfig.ts +1 -1
  8. package/src/.umi-production/core/polyfill.ts +216 -216
  9. package/src/.umi-production/core/route.tsx +2 -4
  10. package/src/.umi-production/exports.ts +3 -3
  11. package/src/.umi-production/testBrowser.tsx +1 -1
  12. package/src/.umi-production/tsconfig.json +1 -1
  13. package/src/.umi-production/umi.ts +2 -2
  14. package/src/framework/components/ErrorBoundary/index.tsx +86 -0
  15. package/src/framework/components/Gap/index.tsx +42 -0
  16. package/src/framework/components/NamedIcon/index.d.ts +6 -4
  17. package/src/framework/components/NamedIcon/index.jsx +9 -6
  18. package/src/framework/components/OrgTree/{index.jsx → index.tsx} +10 -19
  19. package/src/framework/components/PageLoading/{index.jsx → index.tsx} +2 -5
  20. package/src/framework/components/ProModal/index.tsx +1 -1
  21. package/src/framework/components/ProTable/components/ToolBar/{index.jsx → index.tsx} +3 -3
  22. package/src/framework/components/ProTable/index.less +1 -1
  23. package/src/framework/components/ProTable/{index.jsx → index.tsx} +9 -7
  24. package/src/framework/components/ProTable/utils/index.ts +62 -0
  25. package/src/framework/components/RoleTree/{index.jsx → index.tsx} +7 -17
  26. package/src/framework/components/ValueType/{index.jsx → index.tsx} +2 -1
  27. package/src/framework/components/ViewRange/index.tsx +15 -0
  28. package/src/framework/components/index.ts +2 -1
  29. package/src/framework/components/system/ButtonList.tsx +22 -0
  30. package/src/framework/components/system/index.tsx +4 -4
  31. package/src/framework/fields/BaseRemoteSelect/index.tsx +129 -0
  32. package/src/framework/fields/FieldDictSelect/{index.jsx → index.tsx} +10 -4
  33. package/src/framework/fields/FieldRemoteSelect/index.tsx +37 -0
  34. package/src/framework/fields/FieldRemoteSelectMultiple/index.tsx +29 -0
  35. package/src/framework/fields/FieldRemoteSelectMultipleInline/index.tsx +33 -0
  36. package/src/framework/fields/FieldRemoteTree/index.tsx +31 -0
  37. package/src/framework/fields/FieldRemoteTreeCascader/index.tsx +39 -0
  38. package/src/framework/fields/FieldRemoteTreeSelect/index.tsx +39 -0
  39. package/src/framework/fields/FieldRemoteTreeSelectMultiple/index.tsx +43 -0
  40. package/src/framework/fields/FieldSysOrgTree/{index.jsx → index.tsx} +2 -2
  41. package/src/framework/fields/FieldSysOrgTreeSelect/{index.jsx → index.tsx} +2 -2
  42. package/src/framework/fields/FieldTable/{index.jsx → index.tsx} +5 -5
  43. package/src/framework/fields/FieldUploadFile/{index.jsx → index.tsx} +1 -3
  44. package/src/framework/index.ts +0 -1
  45. package/src/framework/utils/ArrayUtils.ts +186 -0
  46. package/src/framework/utils/EventBusUtils.ts +0 -1
  47. package/src/framework/utils/MessageUtils.tsx +0 -2
  48. package/src/framework/utils/TreeUtils.ts +2 -2
  49. package/src/framework/utils/index.ts +1 -1
  50. package/src/framework/utils/system/FormRegistryUtils.ts +0 -1
  51. package/src/framework/utils/system/PermUtils.ts +2 -2
  52. package/src/framework/views/ViewApproveStatus/index.tsx +11 -0
  53. package/src/framework/views/ViewBoolean/index.tsx +6 -0
  54. package/src/framework/views/ViewFile/{index.jsx → index.tsx} +4 -4
  55. package/src/framework/views/ViewImage/{index.jsx → index.tsx} +3 -3
  56. package/src/framework/views/ViewPassword/{index.jsx → index.tsx} +2 -2
  57. package/src/framework/views/ViewProcessInstanceProgressButton/{index.jsx → index.tsx} +1 -2
  58. package/src/layouts/PageRender.jsx +6 -6
  59. package/src/layouts/admin/HeaderRight.jsx +2 -2
  60. package/src/layouts/admin/TabPageRender.jsx +28 -13
  61. package/src/layouts/admin/index.jsx +15 -14
  62. package/src/layouts/admin/index.less +1 -1
  63. package/src/layouts/index.jsx +12 -13
  64. package/src/layouts/index.less +2 -2
  65. package/src/loading.jsx +17 -16
  66. package/src/pages/login.jsx +132 -4
  67. package/src/{framework/pages/LoginPage.less → pages/login.less} +3 -3
  68. package/src/pages/system/dict/index.jsx +4 -3
  69. package/src/pages/system/file/index.jsx +6 -5
  70. package/src/pages/system/job/index.jsx +10 -9
  71. package/src/pages/system/{sysManual → manual}/index.jsx +1 -1
  72. package/src/pages/system/org/index.jsx +4 -5
  73. package/src/pages/system/role/index.jsx +5 -5
  74. package/src/pages/system/role/perm.jsx +6 -6
  75. package/src/pages/system/user/UserPerm.jsx +4 -4
  76. package/src/pages/system/user/index.jsx +2 -2
  77. package/src/pages/userCenter/ChangePassword.jsx +3 -5
  78. package/src/pages/userCenter/manual.jsx +1 -1
  79. package/src/pages/userCenter/message.jsx +1 -1
  80. package/src/framework/components/DownloadFileButton/index.d.ts +0 -11
  81. package/src/framework/components/Gap/index.d.ts +0 -23
  82. package/src/framework/components/Gap/index.jsx +0 -46
  83. package/src/framework/components/LinkButton/index.d.ts +0 -14
  84. package/src/framework/components/OrgTree/index.d.ts +0 -4
  85. package/src/framework/components/Page/index.d.ts +0 -17
  86. package/src/framework/components/PageLoading/index.d.ts +0 -1
  87. package/src/framework/components/ProTable/index.d.ts +0 -42
  88. package/src/framework/components/ProTable/utils/index.js +0 -43
  89. package/src/framework/components/RoleTree/index.d.ts +0 -4
  90. package/src/framework/components/ViewRange/index.d.ts +0 -14
  91. package/src/framework/components/ViewRange/index.jsx +0 -20
  92. package/src/framework/components/system/ButtonList.d.ts +0 -8
  93. package/src/framework/components/system/ButtonList.jsx +0 -42
  94. package/src/framework/fields/FieldBoolean/index.d.ts +0 -9
  95. package/src/framework/fields/FieldDate/index.d.ts +0 -23
  96. package/src/framework/fields/FieldDateRange/index.d.ts +0 -22
  97. package/src/framework/fields/FieldDictSelect/index.d.ts +0 -12
  98. package/src/framework/fields/FieldEditor/index.d.ts +0 -14
  99. package/src/framework/fields/FieldNumberRange/index.d.ts +0 -10
  100. package/src/framework/fields/FieldPercent/index.d.ts +0 -8
  101. package/src/framework/fields/FieldRemoteSelect/index.d.ts +0 -44
  102. package/src/framework/fields/FieldRemoteSelect/index.jsx +0 -66
  103. package/src/framework/fields/FieldRemoteSelectMultiple/index.d.ts +0 -20
  104. package/src/framework/fields/FieldRemoteSelectMultiple/index.jsx +0 -85
  105. package/src/framework/fields/FieldRemoteSelectMultipleInline/index.d.ts +0 -21
  106. package/src/framework/fields/FieldRemoteSelectMultipleInline/index.jsx +0 -88
  107. package/src/framework/fields/FieldRemoteTree/index.d.ts +0 -20
  108. package/src/framework/fields/FieldRemoteTree/index.jsx +0 -50
  109. package/src/framework/fields/FieldRemoteTreeCascader/index.d.ts +0 -18
  110. package/src/framework/fields/FieldRemoteTreeCascader/index.jsx +0 -59
  111. package/src/framework/fields/FieldRemoteTreeSelect/index.d.ts +0 -19
  112. package/src/framework/fields/FieldRemoteTreeSelect/index.jsx +0 -57
  113. package/src/framework/fields/FieldRemoteTreeSelectMultiple/index.d.ts +0 -20
  114. package/src/framework/fields/FieldRemoteTreeSelectMultiple/index.jsx +0 -62
  115. package/src/framework/fields/FieldSysOrgTree/index.d.ts +0 -9
  116. package/src/framework/fields/FieldSysOrgTreeSelect/index.d.ts +0 -9
  117. package/src/framework/fields/FieldTable/index.d.ts +0 -14
  118. package/src/framework/fields/FieldTableSelect/index.d.ts +0 -19
  119. package/src/framework/fields/FieldUploadFile/index.d.ts +0 -31
  120. package/src/framework/pages/LoginPage.d.ts +0 -16
  121. package/src/framework/pages/LoginPage.jsx +0 -135
  122. package/src/framework/pages/LoginPageUtils.ts +0 -36
  123. package/src/framework/pages/index.ts +0 -2
  124. package/src/framework/utils/ArrUtils.ts +0 -229
  125. package/src/framework/views/ViewApproveStatus/index.d.ts +0 -5
  126. package/src/framework/views/ViewApproveStatus/index.jsx +0 -15
  127. package/src/framework/views/ViewBoolean/index.d.ts +0 -3
  128. package/src/framework/views/ViewBoolean/index.jsx +0 -4
  129. package/src/framework/views/ViewBooleanEnableDisable/index.d.ts +0 -5
  130. package/src/framework/views/ViewFile/index.d.ts +0 -10
  131. package/src/framework/views/ViewFileButton/index.d.ts +0 -10
  132. package/src/framework/views/ViewImage/index.d.ts +0 -6
  133. package/src/framework/views/ViewPassword/index.d.ts +0 -5
  134. package/src/framework/views/ViewProcessInstanceProgress/index.d.ts +0 -12
  135. package/src/framework/views/ViewProcessInstanceProgressButton/index.d.ts +0 -6
  136. package/src/framework/views/ViewText/index.d.ts +0 -16
  137. package/src/pages/system/api/index.jsx +0 -279
  138. package/src/pages/test/views.jsx +0 -95
  139. package/src/framework/components/DownloadFileButton/{index.jsx → index.tsx} +0 -0
  140. package/src/framework/components/LinkButton/{index.jsx → index.tsx} +0 -0
  141. package/src/framework/components/Page/{index.jsx → index.tsx} +0 -0
  142. package/src/framework/components/ValueType/{registry.jsx → registry.tsx} +1 -1
  143. /package/src/framework/fields/FieldBoolean/{index.jsx → index.tsx} +0 -0
  144. /package/src/framework/fields/FieldDate/{index.jsx → index.tsx} +0 -0
  145. /package/src/framework/fields/FieldDateRange/{index.jsx → index.tsx} +0 -0
  146. /package/src/framework/fields/FieldEditor/{index.jsx → index.tsx} +0 -0
  147. /package/src/framework/fields/FieldNumberRange/{index.jsx → index.tsx} +0 -0
  148. /package/src/framework/fields/FieldPercent/{index.jsx → index.tsx} +0 -0
  149. /package/src/framework/fields/FieldTableSelect/{index.jsx → index.tsx} +0 -0
  150. /package/src/framework/views/ViewBooleanEnableDisable/{index.jsx → index.tsx} +0 -0
  151. /package/src/framework/views/ViewFileButton/{index.jsx → index.tsx} +0 -0
  152. /package/src/framework/views/ViewProcessInstanceProgress/{index.jsx → index.tsx} +0 -0
  153. /package/src/framework/views/ViewText/{index.jsx → index.tsx} +0 -0
@@ -0,0 +1,129 @@
1
+ import React from 'react';
2
+ import { Spin, message } from 'antd';
3
+ import { debounce } from 'lodash';
4
+ import { HttpUtils } from '../../utils';
5
+
6
+ interface BaseRemoteSelectState {
7
+ data: any[];
8
+ loading: boolean;
9
+ }
10
+
11
+ export interface BaseRemoteSelectProps {
12
+ url?: string;
13
+ value?: any;
14
+ debounceTime?: number;
15
+ [key: string]: any;
16
+ }
17
+
18
+ /**
19
+ * 远程数据加载选择器基类
20
+ *
21
+ * 处理通用的数据加载、防抖搜索、竞态处理、错误提示逻辑。
22
+ * 子类只需覆写 getLoadParams() 和 render()。
23
+ */
24
+ export class BaseRemoteSelect<P extends BaseRemoteSelectProps = BaseRemoteSelectProps> extends React.Component<P, BaseRemoteSelectState> {
25
+ private fetchIdRef: number = 0;
26
+ private loadDataDebounce: ReturnType<typeof debounce>;
27
+
28
+ static defaultProps = {
29
+ debounceTime: 300,
30
+ };
31
+
32
+ constructor(props: P) {
33
+ super(props);
34
+ this.state = {
35
+ data: [],
36
+ loading: false,
37
+ };
38
+ this.loadDataDebounce = debounce(this._loadData, (props as any).debounceTime || 300);
39
+ }
40
+
41
+ componentDidMount() {
42
+ if (this.shouldLoadOnMount()) {
43
+ this.loadData();
44
+ }
45
+ }
46
+
47
+ componentWillUnmount() {
48
+ this.loadDataDebounce.cancel();
49
+ }
50
+
51
+ // ========== 子类可覆写 ==========
52
+
53
+ /** 返回请求 URL */
54
+ getUrl(): string | undefined {
55
+ return this.props.url;
56
+ }
57
+
58
+ /** 返回请求参数。searchText=undefined 表示初始加载 */
59
+ getLoadParams(searchText?: string): Record<string, any> {
60
+ return { searchText, selected: this.props.value };
61
+ }
62
+
63
+ /** 是否在挂载时自动加载数据 */
64
+ shouldLoadOnMount(): boolean {
65
+ return true;
66
+ }
67
+
68
+ // ========== 数据加载 ==========
69
+
70
+ private _loadData = async (searchText?: string) => {
71
+ const url = this.getUrl();
72
+ const fetchId = ++this.fetchIdRef;
73
+
74
+ this.setState({ loading: true });
75
+
76
+ try {
77
+ const data = await HttpUtils.get(url, this.getLoadParams(searchText));
78
+
79
+ if (fetchId === this.fetchIdRef) {
80
+ this.setState({ data: data || [] });
81
+ }
82
+ } catch (error) {
83
+ console.error('远程加载失败:', error);
84
+ message.error('加载失败,请重试');
85
+ if (fetchId === this.fetchIdRef) {
86
+ this.setState({ data: [] });
87
+ }
88
+ } finally {
89
+ if (fetchId === this.fetchIdRef) {
90
+ this.setState({ loading: false });
91
+ }
92
+ }
93
+ };
94
+
95
+ /**
96
+ * 触发数据加载
97
+ * - 传 searchText → 防抖后加载(用于搜索输入)
98
+ * - 不传 → 立即加载(用于初始加载)
99
+ */
100
+ loadData = (searchText?: string) => {
101
+ if (searchText != null) {
102
+ this.loadDataDebounce(searchText);
103
+ } else {
104
+ this._loadData();
105
+ }
106
+ };
107
+
108
+ /** 搜索输入处理(供 showSearch.onSearch 使用) */
109
+ handleSearch = (value: string) => {
110
+ if (value.trim() === '') {
111
+ this.loadData();
112
+ return;
113
+ }
114
+ this.loadData(value.trim());
115
+ };
116
+
117
+ // ========== Helper 方法 ==========
118
+
119
+ getShowSearch(): { filterOption: false; onSearch: (value: string) => void } {
120
+ return {
121
+ filterOption: false,
122
+ onSearch: this.handleSearch,
123
+ };
124
+ }
125
+
126
+ getNotFoundContent(): React.ReactNode {
127
+ return this.state.loading ? <Spin size="small" /> : '数据为空';
128
+ }
129
+ }
@@ -1,10 +1,16 @@
1
1
  import React from "react";
2
2
  import {Select} from "antd";
3
3
  import {DictUtils} from "../../utils";
4
+ import type {SelectProps} from "antd/es/select";
5
+ import type {FieldProps} from '../types';
4
6
 
5
- export class FieldDictSelect extends React.Component {
7
+ interface FieldDictSelectProps extends Omit<SelectProps, 'options' | 'children' | 'mode' | 'value' | 'onChange'>, FieldProps<any> {
8
+ typeCode: string;
9
+ }
10
+
11
+ export class FieldDictSelect extends React.Component<FieldDictSelectProps> {
6
12
  render() {
7
- const {value, typeCode} = this.props;
13
+ const {value, typeCode} = this.props;
8
14
  const options = DictUtils.dictOptions(typeCode);
9
15
  const strValue = value == null ? null : String(value);
10
16
 
@@ -12,6 +18,6 @@ export class FieldDictSelect extends React.Component {
12
18
  onChange={this.props.onChange}
13
19
  style={{width: '100%', minWidth: 200}}
14
20
  options={options}
15
- />
21
+ />;
16
22
  }
17
- }
23
+ }
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import {Select} from 'antd';
3
+ import {BaseRemoteSelect} from '../BaseRemoteSelect';
4
+ import type {SelectProps} from "antd/es/select";
5
+ import type {FieldProps} from '../types';
6
+
7
+ interface FieldRemoteSelectProps extends Omit<SelectProps, 'value' | 'onChange'>, FieldProps<any> {
8
+ url: string;
9
+ debounceTime?: number;
10
+ paramsProcessor?: (params: any) => any;
11
+ responseProcessor?: (response: any) => any;
12
+ }
13
+
14
+ export class FieldRemoteSelect extends BaseRemoteSelect<FieldRemoteSelectProps> {
15
+ static defaultProps = {
16
+ placeholder: '请搜索选择',
17
+ };
18
+
19
+ render() {
20
+ const {value, placeholder, ...rest} = this.props;
21
+ const {data, loading} = this.state;
22
+
23
+ return (
24
+ <Select
25
+ showSearch={this.getShowSearch()}
26
+ options={data}
27
+ notFoundContent={this.getNotFoundContent()}
28
+ style={{width: '100%', minWidth: 200}}
29
+ allowClear
30
+ loading={loading}
31
+ value={value}
32
+ placeholder={placeholder}
33
+ {...rest}
34
+ />
35
+ );
36
+ }
37
+ }
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+ import { Select } from 'antd';
3
+ import { BaseRemoteSelect } from '../BaseRemoteSelect';
4
+
5
+ export class FieldRemoteSelectMultiple extends BaseRemoteSelect {
6
+ static defaultProps = {
7
+ placeholder: '请搜索选择',
8
+ };
9
+
10
+ render() {
11
+ const { value, onChange, url, ...selectProps } = this.props;
12
+ const { data, loading } = this.state;
13
+
14
+ return (
15
+ <Select
16
+ showSearch={this.getShowSearch()}
17
+ value={value}
18
+ onChange={onChange}
19
+ options={data}
20
+ notFoundContent={this.getNotFoundContent()}
21
+ style={{ width: '100%', minWidth: 200 }}
22
+ allowClear
23
+ mode="multiple"
24
+ loading={loading}
25
+ {...selectProps}
26
+ />
27
+ );
28
+ }
29
+ }
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import { Select } from 'antd';
3
+ import { StringUtils } from '../../utils';
4
+ import { BaseRemoteSelect } from '../BaseRemoteSelect';
5
+
6
+ /**
7
+ * 多选,但是值是字符串,逗号拼接的
8
+ */
9
+ export class FieldRemoteSelectMultipleInline extends BaseRemoteSelect {
10
+ static defaultProps = {
11
+ placeholder: '请搜索选择',
12
+ };
13
+
14
+ render() {
15
+ const { value, onChange, url, ...selectProps } = this.props;
16
+ const { data, loading } = this.state;
17
+
18
+ return (
19
+ <Select
20
+ showSearch={this.getShowSearch()}
21
+ value={StringUtils.split(value, ',')}
22
+ onChange={(arr) => onChange && onChange(StringUtils.join(arr, ','))}
23
+ options={data}
24
+ notFoundContent={this.getNotFoundContent()}
25
+ style={{ width: '100%', minWidth: 200 }}
26
+ allowClear
27
+ mode="multiple"
28
+ loading={loading}
29
+ {...selectProps}
30
+ />
31
+ );
32
+ }
33
+ }
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import { Spin, Tree } from 'antd';
3
+ import { BaseRemoteSelect } from '../BaseRemoteSelect';
4
+
5
+ /**
6
+ * 多选树
7
+ *
8
+ * 区别于下拉框,是扁平展示的树
9
+ * 这种需要扁平展示的树,通常都是多选。
10
+ */
11
+ export class FieldRemoteTree extends BaseRemoteSelect {
12
+ getLoadParams() {
13
+ return undefined;
14
+ }
15
+
16
+ render() {
17
+ if (this.state.loading) return <Spin />;
18
+
19
+ return (
20
+ <Tree
21
+ multiple
22
+ checkable
23
+ onCheck={(e) => this.props.onChange && this.props.onChange(e.checked)}
24
+ checkedKeys={this.props.value}
25
+ treeData={this.state.data}
26
+ defaultExpandAll
27
+ checkStrictly
28
+ />
29
+ );
30
+ }
31
+ }
@@ -0,0 +1,39 @@
1
+ import { Cascader, Spin } from 'antd';
2
+ import React from 'react';
3
+ import { TreeUtils } from '../../utils';
4
+ import { BaseRemoteSelect } from '../BaseRemoteSelect';
5
+
6
+ /**
7
+ * 远程树级联选择器,类似 select,但是树级联
8
+ *
9
+ * 注意,value 为非数组形式,区别于 cascader 组件
10
+ */
11
+ export class FieldRemoteTreeCascader extends BaseRemoteSelect {
12
+ getLoadParams() {
13
+ return undefined;
14
+ }
15
+
16
+ render() {
17
+ const { data, loading } = this.state;
18
+ if (loading) return <Spin />;
19
+
20
+ const { value, onChange, ...rest } = this.props;
21
+
22
+ let arr = [];
23
+ if (value != null) {
24
+ arr = TreeUtils.getKeyList(data, value);
25
+ }
26
+
27
+ return (
28
+ <Cascader
29
+ options={data}
30
+ onChange={(arr) => {
31
+ onChange && onChange(arr[arr.length - 1]);
32
+ }}
33
+ value={arr}
34
+ fieldNames={{ label: 'title', value: 'key' }}
35
+ {...rest}
36
+ />
37
+ );
38
+ }
39
+ }
@@ -0,0 +1,39 @@
1
+ import { Spin, TreeSelect } from 'antd';
2
+ import React from 'react';
3
+ import { StringUtils } from '../../utils';
4
+ import { BaseRemoteSelect } from '../BaseRemoteSelect';
5
+
6
+ export class FieldRemoteTreeSelect extends BaseRemoteSelect {
7
+ static defaultProps = {
8
+ treeDefaultExpandAll: true,
9
+ };
10
+
11
+ /** 树形接口不需要请求参数 */
12
+ getLoadParams() {
13
+ return undefined;
14
+ }
15
+
16
+ render() {
17
+ const { value, onChange, treeDefaultExpandAll } = this.props;
18
+ const { data, loading } = this.state;
19
+
20
+ if (loading) return <Spin />;
21
+
22
+ return (
23
+ <TreeSelect
24
+ style={{ width: '100%', minWidth: 200 }}
25
+ allowClear
26
+ dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
27
+ treeData={data}
28
+ showCheckedStrategy={TreeSelect.SHOW_ALL}
29
+ value={value || undefined}
30
+ onChange={onChange}
31
+ filterTreeNode={(inputValue, treeNode) =>
32
+ StringUtils.contains(treeNode.title, inputValue)
33
+ }
34
+ treeLine={{ showLeafIcon: true }}
35
+ treeDefaultExpandAll={treeDefaultExpandAll}
36
+ />
37
+ );
38
+ }
39
+ }
@@ -0,0 +1,43 @@
1
+ import { Spin, TreeSelect } from 'antd';
2
+ import React from 'react';
3
+ import { StringUtils } from '../../utils';
4
+ import { BaseRemoteSelect } from '../BaseRemoteSelect';
5
+
6
+ export class FieldRemoteTreeSelectMultiple extends BaseRemoteSelect {
7
+ static defaultProps = {
8
+ treeDefaultExpandAll: true,
9
+ style: {
10
+ width: '100%',
11
+ minWidth: 200,
12
+ },
13
+ };
14
+
15
+ getLoadParams() {
16
+ return undefined;
17
+ }
18
+
19
+ render() {
20
+ const { value, onChange, style, treeDefaultExpandAll } = this.props;
21
+ const { data, loading } = this.state;
22
+
23
+ if (loading) return <Spin />;
24
+
25
+ return (
26
+ <TreeSelect
27
+ style={style}
28
+ allowClear
29
+ dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
30
+ treeData={data}
31
+ showCheckedStrategy={TreeSelect.SHOW_ALL}
32
+ value={value || undefined}
33
+ onChange={onChange}
34
+ multiple
35
+ filterTreeNode={(inputValue, treeNode) =>
36
+ StringUtils.contains(treeNode.title, inputValue)
37
+ }
38
+ treeLine={{ showLeafIcon: true }}
39
+ treeDefaultExpandAll={treeDefaultExpandAll}
40
+ />
41
+ );
42
+ }
43
+ }
@@ -12,8 +12,8 @@ export class FieldSysOrgTree extends React.Component {
12
12
  render() {
13
13
  const {type, ...rest} = this.props;
14
14
  const url = type === 'dept'?
15
- '/admin/sysOrg/deptTree':
16
- '/admin/sysOrg/unitTree';
15
+ '/admin/sysOrg/dept-tree':
16
+ '/admin/sysOrg/unit-tree';
17
17
  return <FieldRemoteTree url={url} {...rest} />;
18
18
  }
19
19
 
@@ -13,8 +13,8 @@ export class FieldSysOrgTreeSelect extends React.Component {
13
13
  render() {
14
14
  const {type, ...rest} = this.props;
15
15
  const url = type === 'dept'?
16
- '/admin/sysOrg/deptTree':
17
- '/admin/sysOrg/unitTree';
16
+ '/admin/sysOrg/dept-tree':
17
+ '/admin/sysOrg/unit-tree';
18
18
 
19
19
  return <FieldRemoteTreeSelect url={url} {...rest}/>;
20
20
  }
@@ -2,7 +2,7 @@ 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 {ArrUtils} from "../../utils";
5
+ import {ArrayUtils} from "../../utils";
6
6
 
7
7
  /**
8
8
  * 可编辑表格
@@ -58,7 +58,7 @@ export class FieldTable extends React.Component {
58
58
 
59
59
  onCellChange = (index, dataIndex, e) => {
60
60
  let {dataSource} = this.state;
61
- let row = dataSource[index];
61
+ const row = dataSource[index];
62
62
 
63
63
  let v = e;
64
64
  if (e != null && e.hasOwnProperty('target')) {
@@ -78,13 +78,13 @@ export class FieldTable extends React.Component {
78
78
  };
79
79
 
80
80
  remove = (record) => {
81
- let {dataSource} = this.state;
82
- ArrUtils.remove(dataSource, record);
81
+ const {dataSource} = this.state;
82
+ ArrayUtils.remove(dataSource, record);
83
83
  this.setState({dataSource: [...dataSource]}, this.notifyParent);
84
84
  };
85
85
 
86
86
  notifyParent = () => {
87
- let {dataSource} = this.state;
87
+ const {dataSource} = this.state;
88
88
  this.props.onChange && this.props.onChange(dataSource);
89
89
  };
90
90
 
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import ImgCrop from "antd-img-crop";
3
3
  import {Modal, Upload} from "antd";
4
- import UploadOutlined from "@ant-design/icons/lib/icons/UploadOutlined";
4
+ import { UploadOutlined } from "@ant-design/icons";
5
5
  import {ViewFile} from "../../views";
6
6
  import {ObjectUtils} from "../../utils";
7
7
 
@@ -64,7 +64,6 @@ export class FieldUploadFile extends React.Component {
64
64
  }
65
65
 
66
66
  handleChange = ({fileList, event, file}) => {
67
- console.log('检测到文件变化', fileList);
68
67
  const rs = file.response;
69
68
  if (rs != null && rs.success === false) {
70
69
  Modal.error({
@@ -82,7 +81,6 @@ export class FieldUploadFile extends React.Component {
82
81
  }
83
82
  if (this.props.onChange) {
84
83
  const value = newIds.join(',');
85
- console.log('上传文件值', value);
86
84
  this.props.onChange(value);
87
85
  }
88
86
 
@@ -2,4 +2,3 @@ export * from './components'
2
2
  export * from './utils'
3
3
  export * from './fields'
4
4
  export * from './views'
5
- export * from './pages'
@@ -0,0 +1,186 @@
1
+ /**
2
+ * 数组工具类
3
+ * 提供了一系列对数组进行操作的静态方法。
4
+ */
5
+ export class ArrayUtils {
6
+
7
+ /**
8
+ * 检查数组是否包含某个元素。
9
+ * @param arr 目标数组。
10
+ * @param item 要检查的元素。
11
+ * @returns 如果包含则返回 true,否则返回 false。
12
+ */
13
+ static contains<T>(arr: T[], item: T): boolean {
14
+ return arr.indexOf(item) !== -1;
15
+ }
16
+
17
+ /**
18
+ * 检查数组是否包含至少一个指定的元素。
19
+ *
20
+ * @param arr 目标数组。
21
+ * @param items 要检查的一个或多个元素。
22
+ * @returns 如果包含任意一个元素则返回 true,否则返回 false。
23
+ */
24
+ static containsAny<T>(arr: T[], ...items: T[]): boolean {
25
+ for (const item of items) {
26
+ if (ArrayUtils.contains(arr, item)) {
27
+ return true;
28
+ }
29
+ }
30
+ return false;
31
+ }
32
+
33
+ /**
34
+ * 在数组末尾添加一个元素。
35
+ * @param arr 目标数组。
36
+ * @param item 要添加的元素。
37
+ */
38
+ static add<T>(arr: T[], item: T): void {
39
+ arr.push(item);
40
+ }
41
+
42
+ /**
43
+ * 在数组的指定索引处添加一个元素。
44
+ * @param arr 目标数组。
45
+ * @param index 插入位置的索引。
46
+ * @param item 要添加的元素。
47
+ */
48
+ static addAt<T>(arr: T[], index: number, item: T): void {
49
+ arr.splice(index, 0, item);
50
+ }
51
+
52
+ /**
53
+ * 将另一个数组的所有元素追加到目标数组的尾部。
54
+ * @param arr 目标数组。
55
+ * @param items 要追加的元素数组。
56
+ */
57
+ static addAll<T>(arr: T[], items: T[]): void {
58
+ arr.push(...items);
59
+ }
60
+
61
+ /**
62
+ * 移除数组指定索引处的元素。
63
+ * @param arr 目标数组。
64
+ * @param index 要移除元素的索引。
65
+ */
66
+ static removeAt<T>(arr: T[], index: number): void {
67
+ if (index >= 0 && index < arr.length) {
68
+ arr.splice(index, 1);
69
+ }
70
+ }
71
+
72
+ /**
73
+ * 移除数组中第一个匹配的元素。
74
+ * @param arr 目标数组。
75
+ * @param item 要移除的元素。
76
+ */
77
+ static remove<T>(arr: T[], item: T): void {
78
+ const index = arr.indexOf(item);
79
+ if (index !== -1) {
80
+ ArrayUtils.removeAt(arr, index);
81
+ }
82
+ }
83
+
84
+ /**
85
+ * 清空数组。
86
+ * @param arr 目标数组。
87
+ */
88
+ static clear<T>(arr: T[]): void {
89
+ arr.length = 0;
90
+ }
91
+
92
+ /**
93
+ * 截取数组的一个子集。
94
+ * @param arr 目标数组。
95
+ * @param fromIndex 开始索引(包含)。
96
+ * @param toIndex 结束索引(不包含)。
97
+ * @returns 截取后的新数组。
98
+ */
99
+ static sub<T>(arr: T[], fromIndex?: number, toIndex?: number): T[] {
100
+ return arr.slice(fromIndex, toIndex);
101
+ }
102
+
103
+ /**
104
+ * 交换数组中两个元素的位置。
105
+ * @param arr 目标数组。
106
+ * @param item1 元素1。
107
+ * @param item2 元素2。
108
+ */
109
+ static swap<T>(arr: T[], item1: T, item2: T): void {
110
+ const index1 = arr.indexOf(item1);
111
+ const index2 = arr.indexOf(item2);
112
+
113
+ if (index1 !== -1 && index2 !== -1) {
114
+ [arr[index1], arr[index2]] = [arr[index2], arr[index1]];
115
+ }
116
+ }
117
+
118
+ /**
119
+ * 在数组的指定索引处插入一个元素(与 addAt 相同,保留以兼容原 API)。
120
+ * @param arr 目标数组。
121
+ * @param index 插入位置的索引。
122
+ * @param item 要插入的元素。
123
+ */
124
+ static insert<T>(arr: T[], index: number, item: T): void {
125
+ ArrayUtils.addAt(arr, index, item);
126
+ }
127
+
128
+ /**
129
+ * 如果元素不存在于数组中,则将其添加到数组末尾。
130
+ * @param arr 目标数组。
131
+ * @param item 要添加的元素。
132
+ */
133
+ static pushIfNotExist<T>(arr: T[], item: T): void {
134
+ if (!ArrayUtils.contains(arr, item)) {
135
+ arr.push(item);
136
+ }
137
+ }
138
+
139
+ /**
140
+ * 将新数组中的所有元素添加到目标数组的末尾。
141
+ * @param arr 目标数组。
142
+ * @param newArr 要添加的元素数组。
143
+ */
144
+ static pushAll<T>(arr: T[], newArr: T[]): void {
145
+ ArrayUtils.addAll(arr, newArr);
146
+ }
147
+
148
+ /**
149
+ * 获取对象数组中某一属性值最大的对象。
150
+ *
151
+ * @param arr 对象数组。
152
+ * @param key 用于比较的属性名。
153
+ * @returns 属性值最大的对象,如果数组为空则返回 undefined。
154
+ */
155
+ static maxBy<T extends Record<K, any>, K extends keyof T>(
156
+ arr: T[],
157
+ key: K
158
+ ): T | undefined {
159
+ if (arr == null || arr.length === 0) {
160
+ return undefined;
161
+ }
162
+
163
+ let maxElement: T | undefined = undefined;
164
+ let maxValue: number = -Infinity;
165
+
166
+ for (const element of arr) {
167
+ const value = element[key];
168
+
169
+ if (typeof value === 'number' && value > maxValue) {
170
+ maxValue = value;
171
+ maxElement = element;
172
+ }
173
+ }
174
+
175
+ return maxElement;
176
+ }
177
+
178
+ /**
179
+ * 对数组进行去重。
180
+ * @param arr 目标数组。
181
+ * @returns 去重后的新数组。
182
+ */
183
+ static unique<T>(arr: T[]): T[] {
184
+ return [...new Set(arr)];
185
+ }
186
+ }