@jiangood/open-admin 1.0.1 → 1.1.0

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 (176) hide show
  1. package/config/common-plugin.js +94 -0
  2. package/config/config.js +58 -0
  3. package/config/utils.js +73 -0
  4. package/package.json +8 -11
  5. package/src/.umi-production/appData.json +2365 -0
  6. package/src/.umi-production/core/EmptyRoute.tsx +9 -0
  7. package/src/.umi-production/core/defineApp.ts +16 -0
  8. package/src/.umi-production/core/helmet.ts +10 -0
  9. package/src/.umi-production/core/helmetContext.ts +4 -0
  10. package/src/.umi-production/core/history.ts +72 -0
  11. package/src/.umi-production/core/historyIntelli.ts +132 -0
  12. package/src/.umi-production/core/plugin.ts +40 -0
  13. package/src/.umi-production/core/pluginConfig.ts +324 -0
  14. package/src/.umi-production/core/pluginConfigJoi.d.ts +7 -0
  15. package/src/.umi-production/core/polyfill.ts +220 -0
  16. package/src/.umi-production/core/route.tsx +54 -0
  17. package/src/.umi-production/core/routeProps.js +5 -0
  18. package/src/.umi-production/core/routeProps.ts +6 -0
  19. package/src/.umi-production/core/terminal.ts +37 -0
  20. package/src/.umi-production/exports.ts +17 -0
  21. package/src/.umi-production/testBrowser.tsx +90 -0
  22. package/src/.umi-production/tsconfig.json +44 -0
  23. package/src/.umi-production/typings.d.ts +136 -0
  24. package/src/.umi-production/umi.ts +83 -0
  25. package/src/framework/components/{DownloadFileButton.jsx → DownloadFileButton/index.jsx} +1 -1
  26. package/src/framework/components/{LinkButton.d.ts → LinkButton/index.d.ts} +1 -1
  27. package/src/framework/components/{LinkButton.jsx → LinkButton/index.jsx} +1 -1
  28. package/src/framework/components/NamedIcon/index.d.ts +5 -0
  29. package/src/framework/components/{NamedIcon.tsx → NamedIcon/index.jsx} +1 -5
  30. package/src/framework/components/OrgTree/index.d.ts +4 -0
  31. package/src/framework/{field-components/system/OrgTree.tsx → components/OrgTree/index.jsx} +1 -4
  32. package/src/framework/components/PageLoading/index.d.ts +1 -0
  33. package/src/framework/components/{PageLoading.tsx → PageLoading/index.jsx} +3 -5
  34. package/src/framework/components/RoleTree/index.d.ts +4 -0
  35. package/src/framework/{field-components/system/RoleTree.tsx → components/RoleTree/index.jsx} +1 -4
  36. package/src/framework/components/ValueType/index.jsx +1 -1
  37. package/src/framework/components/ValueType/registry.jsx +2 -3
  38. package/src/framework/components/{view/ViewRange → ViewRange}/index.d.ts +5 -7
  39. package/src/framework/components/index.ts +3 -7
  40. package/src/framework/components/system/index.tsx +1 -1
  41. package/src/framework/fields/FieldBoolean/index.d.ts +9 -0
  42. package/src/framework/{field-components/FieldBoolean.jsx → fields/FieldBoolean/index.jsx} +6 -9
  43. package/src/framework/{field-components/FieldDate.d.ts → fields/FieldDate/index.d.ts} +5 -9
  44. package/src/framework/{field-components/FieldDate.jsx → fields/FieldDate/index.jsx} +28 -26
  45. package/src/framework/fields/FieldDateRange/index.d.ts +22 -0
  46. package/src/framework/{field-components/FieldDateRange.jsx → fields/FieldDateRange/index.jsx} +26 -27
  47. package/src/framework/fields/FieldDictSelect/index.d.ts +12 -0
  48. package/src/framework/{field-components/FieldDictSelect.jsx → fields/FieldDictSelect/index.jsx} +5 -5
  49. package/src/framework/fields/FieldEditor/index.d.ts +14 -0
  50. package/src/framework/fields/FieldEditor/index.jsx +59 -0
  51. package/src/framework/fields/FieldNumberRange/index.d.ts +10 -0
  52. package/src/framework/{field-components/FieldNumberRange.jsx → fields/FieldNumberRange/index.jsx} +20 -24
  53. package/src/framework/fields/FieldPercent/index.d.ts +8 -0
  54. package/src/framework/{field-components/FieldPercent.jsx → fields/FieldPercent/index.jsx} +9 -6
  55. package/src/framework/fields/FieldRemoteSelect/index.d.ts +44 -0
  56. package/src/framework/fields/FieldRemoteSelect/index.jsx +125 -0
  57. package/src/framework/fields/FieldRemoteSelectMultiple/index.d.ts +20 -0
  58. package/src/framework/{field-components/FieldRemoteSelectMultiple.jsx → fields/FieldRemoteSelectMultiple/index.jsx} +4 -5
  59. package/src/framework/fields/FieldRemoteSelectMultipleInline/index.d.ts +21 -0
  60. package/src/framework/{field-components/FieldRemoteSelectMultipleInline.jsx → fields/FieldRemoteSelectMultipleInline/index.jsx} +8 -6
  61. package/src/framework/fields/FieldRemoteTree/index.d.ts +20 -0
  62. package/src/framework/fields/FieldRemoteTree/index.jsx +50 -0
  63. package/src/framework/{field-components/FieldRemoteTreeCascader.d.ts → fields/FieldRemoteTreeCascader/index.d.ts} +10 -15
  64. package/src/framework/{field-components/FieldRemoteTreeCascader.jsx → fields/FieldRemoteTreeCascader/index.jsx} +11 -13
  65. package/src/framework/fields/FieldRemoteTreeSelect/index.d.ts +19 -0
  66. package/src/framework/{field-components/FieldRemoteTreeSelect.jsx → fields/FieldRemoteTreeSelect/index.jsx} +10 -20
  67. package/src/framework/fields/FieldRemoteTreeSelectMultiple/index.d.ts +20 -0
  68. package/src/framework/{field-components/FieldRemoteTreeSelectMultiple.jsx → fields/FieldRemoteTreeSelectMultiple/index.jsx} +11 -21
  69. package/src/framework/fields/FieldSysOrgTree/index.d.ts +9 -0
  70. package/src/framework/fields/FieldSysOrgTree/index.jsx +20 -0
  71. package/src/framework/fields/FieldSysOrgTreeSelect/index.d.ts +9 -0
  72. package/src/framework/{field-components/FieldSysOrgTreeSelect.jsx → fields/FieldSysOrgTreeSelect/index.jsx} +7 -8
  73. package/src/framework/fields/FieldTable/index.d.ts +14 -0
  74. package/src/framework/{field-components/FieldTable.jsx → fields/FieldTable/index.jsx} +38 -38
  75. package/src/framework/fields/FieldTableSelect/index.d.ts +19 -0
  76. package/src/framework/{field-components/FieldTableSelect.jsx → fields/FieldTableSelect/index.jsx} +13 -12
  77. package/src/framework/{field-components/FieldUploadFile.d.ts → fields/FieldUploadFile/index.d.ts} +12 -15
  78. package/src/framework/{field-components/FieldUploadFile.jsx → fields/FieldUploadFile/index.jsx} +32 -34
  79. package/src/framework/{field-components → fields}/index.ts +2 -1
  80. package/src/framework/fields/types.ts +16 -0
  81. package/src/framework/index.ts +2 -2
  82. package/src/framework/utils/index.ts +0 -1
  83. package/src/framework/utils/system/DictUtils.ts +1 -1
  84. package/src/framework/views/ViewApproveStatus/index.d.ts +3 -0
  85. package/src/framework/{view-components/ViewApproveStatus.tsx → views/ViewApproveStatus/index.jsx} +3 -8
  86. package/src/framework/views/ViewBoolean/index.d.ts +3 -0
  87. package/src/framework/views/ViewBoolean/index.jsx +4 -0
  88. package/src/framework/views/ViewBooleanEnableDisable/index.d.ts +5 -0
  89. package/src/framework/{components/view/ViewBooleanEnableDisable.tsx → views/ViewBooleanEnableDisable/index.jsx} +2 -7
  90. package/src/framework/{components/view/ViewFileButton.d.ts → views/ViewFile/index.d.ts} +3 -3
  91. package/src/framework/views/ViewFileButton/index.d.ts +10 -0
  92. package/src/framework/views/ViewFileButton/index.jsx +22 -0
  93. package/src/framework/views/ViewImage/index.d.ts +6 -0
  94. package/src/framework/views/ViewPassword/index.d.ts +5 -0
  95. package/src/framework/{view-components/ViewPassword.tsx → views/ViewPassword/index.jsx} +2 -3
  96. package/src/framework/views/ViewProcessInstanceProgress/index.d.ts +12 -0
  97. package/src/framework/{view-components/ViewFlowableInstanceProgress.jsx → views/ViewProcessInstanceProgress/index.jsx} +2 -2
  98. package/src/framework/views/ViewProcessInstanceProgressButton/index.d.ts +6 -0
  99. package/src/framework/{view-components/ViewFlowableInstanceProgressButton.tsx → views/ViewProcessInstanceProgressButton/index.jsx} +4 -6
  100. package/src/framework/views/ViewText/index.d.ts +16 -0
  101. package/src/framework/views/ViewText/index.jsx +42 -0
  102. package/src/framework/views/index.ts +12 -0
  103. package/src/framework/views/types.ts +26 -0
  104. package/src/layouts/admin/index.jsx +0 -2
  105. package/src/layouts/index.jsx +38 -16
  106. package/src/pages/404.jsx +4 -4
  107. package/src/pages/about.jsx +0 -2
  108. package/src/pages/index.jsx +4 -19
  109. package/src/pages/login.jsx +3 -8
  110. package/src/pages/system/api/ApiDoc.jsx +19 -15
  111. package/src/pages/system/api/index.jsx +23 -24
  112. package/src/pages/system/api/perm.jsx +4 -4
  113. package/src/pages/system/dict/Dict.jsx +0 -5
  114. package/src/pages/system/dict/DictItem.jsx +23 -25
  115. package/src/pages/system/dict/index.jsx +2 -2
  116. package/src/pages/system/file/index.jsx +16 -29
  117. package/src/pages/system/job/index.jsx +44 -44
  118. package/src/pages/system/log/index.jsx +3 -4
  119. package/src/pages/system/org/index.jsx +34 -36
  120. package/src/pages/system/role/index.jsx +68 -74
  121. package/src/pages/system/role/perm.jsx +0 -1
  122. package/src/pages/system/sysManual/index.jsx +27 -28
  123. package/src/pages/system/user/UserPerm.jsx +5 -8
  124. package/src/pages/system/user/index.jsx +46 -51
  125. package/src/pages/test/views.jsx +95 -0
  126. package/src/pages/ureport/index.jsx +2 -2
  127. package/src/pages/userCenter/ChangePassword.jsx +2 -1
  128. package/src/pages/userCenter/index.jsx +8 -8
  129. package/src/pages/userCenter/manual.jsx +3 -5
  130. package/src/pages/userCenter/message.jsx +14 -16
  131. package/config/dist/common-plugin.js +0 -149
  132. package/config/dist/config.js +0 -45
  133. package/config/dist/index.js +0 -18
  134. package/src/app.js +0 -1
  135. package/src/asserts/welcome.png +0 -0
  136. package/src/forms/demoForm.jsx +0 -16
  137. package/src/framework/components/Ellipsis.jsx +0 -39
  138. package/src/framework/components/Ellipsis.less +0 -8
  139. package/src/framework/components/view/ViewEllipsis.d.ts +0 -11
  140. package/src/framework/components/view/ViewEllipsis.jsx +0 -30
  141. package/src/framework/components/view/ViewFile.d.ts +0 -10
  142. package/src/framework/components/view/ViewFileButton.jsx +0 -0
  143. package/src/framework/components/view/ViewImage.d.ts +0 -9
  144. package/src/framework/components/view/ViewText.tsx +0 -16
  145. package/src/framework/components/view/index.ts +0 -10
  146. package/src/framework/field-components/FieldBoolean.d.ts +0 -13
  147. package/src/framework/field-components/FieldDateRange.d.ts +0 -6
  148. package/src/framework/field-components/FieldDictSelect.d.ts +0 -13
  149. package/src/framework/field-components/FieldEditor.d.ts +0 -10
  150. package/src/framework/field-components/FieldEditor.jsx +0 -58
  151. package/src/framework/field-components/FieldNumberRange.d.ts +0 -13
  152. package/src/framework/field-components/FieldPercent.d.ts +0 -12
  153. package/src/framework/field-components/FieldRemoteSelect.d.ts +0 -13
  154. package/src/framework/field-components/FieldRemoteSelect.jsx +0 -87
  155. package/src/framework/field-components/FieldRemoteSelectMultiple.d.ts +0 -13
  156. package/src/framework/field-components/FieldRemoteSelectMultipleInline.d.ts +0 -20
  157. package/src/framework/field-components/FieldRemoteTree.d.ts +0 -21
  158. package/src/framework/field-components/FieldRemoteTree.jsx +0 -45
  159. package/src/framework/field-components/FieldRemoteTreeSelect.d.ts +0 -17
  160. package/src/framework/field-components/FieldRemoteTreeSelectMultiple.d.ts +0 -17
  161. package/src/framework/field-components/FieldSysOrgTree.d.ts +0 -12
  162. package/src/framework/field-components/FieldSysOrgTree.jsx +0 -23
  163. package/src/framework/field-components/FieldSysOrgTreeSelect.d.ts +0 -12
  164. package/src/framework/field-components/FieldTable.d.ts +0 -17
  165. package/src/framework/field-components/FieldTableSelect.d.ts +0 -19
  166. package/src/framework/field-components/system/index.ts +0 -2
  167. package/src/framework/view-components/ViewBoolean.tsx +0 -6
  168. package/src/framework/view-components/ViewFlowableInstanceProgress.d.ts +0 -12
  169. package/src/framework/view-components/ViewProps.ts +0 -11
  170. package/src/framework/view-components/index.ts +0 -6
  171. package/src/pages/test.jsx +0 -200
  172. /package/src/framework/components/{DownloadFileButton.d.ts → DownloadFileButton/index.d.ts} +0 -0
  173. /package/src/framework/components/{view/ViewRange → ViewRange}/index.jsx +0 -0
  174. /package/src/framework/{field-components/FieldTable.less → fields/FieldTable/styles.less} +0 -0
  175. /package/src/framework/{components/view/ViewFile.jsx → views/ViewFile/index.jsx} +0 -0
  176. /package/src/framework/{components/view/ViewImage.jsx → views/ViewImage/index.jsx} +0 -0
@@ -4,50 +4,51 @@
4
4
  import React from "react";
5
5
  import dayjs from "dayjs";
6
6
  import {DatePicker, TimePicker} from "antd";
7
- import {DateUtils, StringUtils} from "../utils";
7
+ import {DateUtils, StringUtils} from "../../utils";
8
8
 
9
9
  const SP = StringUtils.ISO_SPLITTER;
10
10
 
11
11
  export class FieldDateRange extends React.Component {
12
12
  static defaultProps = {
13
13
  type: 'YYYY-MM-DD'
14
- }
14
+ };
15
15
 
16
16
  render() {
17
- let {type, value, onChange, ...rest} = this.props;
18
- type = DateUtils.convertTypeToFormat(type)
19
- switch (type) {
17
+ const {type, value, onChange, ...rest} = this.props;
18
+ const formattedType = DateUtils.convertTypeToFormat(type);
19
+
20
+ switch (formattedType) {
20
21
  case 'YYYY':
21
22
  return <DatePicker.RangePicker
22
23
  value={this.strToDate(value, 'YYYY')}
23
- onChange={v => onChange(this.dateToStr(v,'YYYY'))}
24
+ onChange={v => onChange && onChange(this.dateToStr(v, 'YYYY'))}
24
25
  picker="year"
25
26
  {...rest}
26
27
  />;
27
28
  case 'YYYY-MM':
28
29
  return <DatePicker.RangePicker
29
30
  value={this.strToDate(value, 'YYYY-MM')}
30
- onChange={v => onChange(this.dateToStr(v,'YYYY-MM'))}
31
+ onChange={v => onChange && onChange(this.dateToStr(v, 'YYYY-MM'))}
31
32
  picker="month"
32
33
  {...rest}
33
34
  />;
34
35
  case 'YYYY-QQ':
35
36
  return <DatePicker.RangePicker
36
37
  value={this.strToDate(value, 'YYYY-QQ')}
37
- onChange={v => onChange(this.dateToStr(v,'YYYY-QQ'))}
38
+ onChange={v => onChange && onChange(this.dateToStr(v, 'YYYY-QQ'))}
38
39
  picker="quarter"
39
40
  {...rest}
40
41
  />;
41
42
  case 'YYYY-MM-DD':
42
- return <DatePicker.RangePicker
43
+ return <DatePicker.RangePicker
43
44
  value={this.strToDate(value, 'YYYY-MM-DD')}
44
- onChange={v => onChange(this.dateToStr(v,'YYYY-MM-DD'))}
45
+ onChange={v => onChange && onChange(this.dateToStr(v, 'YYYY-MM-DD'))}
45
46
  {...rest}
46
47
  />;
47
48
  case 'YYYY-MM-DD HH:mm':
48
49
  return <DatePicker.RangePicker
49
50
  value={this.strToDate(value, 'YYYY-MM-DD HH:mm')}
50
- onChange={v => onChange(this.dateToStr(v,'YYYY-MM-DD HH:mm'))}
51
+ onChange={v => onChange && onChange(this.dateToStr(v, 'YYYY-MM-DD HH:mm'))}
51
52
  format='YYYY-MM-DD HH:mm'
52
53
  showTime
53
54
  {...rest}
@@ -55,7 +56,7 @@ export class FieldDateRange extends React.Component {
55
56
  case 'YYYY-MM-DD HH:mm:ss':
56
57
  return <DatePicker.RangePicker
57
58
  value={this.strToDate(value, 'YYYY-MM-DD HH:mm:ss')}
58
- onChange={v => onChange(this.dateToStr(v,'YYYY-MM-DD HH:mm:ss'))}
59
+ onChange={v => onChange && onChange(this.dateToStr(v, 'YYYY-MM-DD HH:mm:ss'))}
59
60
  showTime
60
61
  {...rest}
61
62
  />;
@@ -63,42 +64,40 @@ export class FieldDateRange extends React.Component {
63
64
  return <TimePicker.RangePicker
64
65
  format='HH:mm'
65
66
  value={this.strToDate(value, 'HH:mm')}
66
- onChange={v => onChange(this.dateToStr(v,'HH:mm'))}
67
+ onChange={v => onChange && onChange(this.dateToStr(v, 'HH:mm'))}
67
68
  {...rest}
68
69
  />;
69
70
  case 'HH:mm:ss':
70
71
  return <TimePicker.RangePicker
71
72
  value={this.strToDate(value, 'HH:mm:ss')}
72
- onChange={v => onChange(this.dateToStr(v,'HH:mm:ss'))}
73
+ onChange={v => onChange && onChange(this.dateToStr(v, 'HH:mm:ss'))}
73
74
  {...rest}
74
75
  />;
76
+ default:
77
+ return <div>未知组件 {formattedType}</div>;
75
78
  }
76
79
 
77
- return <div>未知组件 {type}</div>
78
80
  }
79
81
 
80
-
81
-
82
82
  strToDate(v, fmt) {
83
- console.log('调用转换')
84
83
  if (!v) {
85
84
  return null;
86
85
  }
87
86
 
88
- const arr = v.split(SP)
89
- let s1 = arr[0];
90
- let s2 = arr[1];
91
- return [dayjs(s1), dayjs(s2)]
87
+ const arr = v.split(SP);
88
+ const s1 = arr[0];
89
+ const s2 = arr[1];
90
+ return [dayjs(s1), dayjs(s2)];
92
91
  }
93
92
 
94
93
  dateToStr(dateArr, fmt) {
95
- const d1 = dateArr[0]
96
- const d2 = dateArr[1]
94
+ const d1 = dateArr[0];
95
+ const d2 = dateArr[1];
97
96
 
98
- const s1 = d1 ? d1.format(fmt) : ""
97
+ const s1 = d1 ? d1.format(fmt) : "";
99
98
  const s2 = d2 ? d2.format(fmt) : "";
100
99
 
101
- return s1 + SP + s2
100
+ return s1 + SP + s2;
102
101
  }
103
102
 
104
- }
103
+ }
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import {SelectProps} from "antd/es/select";
3
+ import { FieldProps } from '../types';
4
+
5
+ interface FieldDictSelectProps extends Omit<SelectProps, 'options' | 'children'|'mode' | 'value' | 'onChange'>, FieldProps<any> {
6
+ /**
7
+ * 字典类型编码
8
+ */
9
+ typeCode: string;
10
+ }
11
+
12
+ export function FieldDictSelect(props: FieldDictSelectProps);
@@ -1,10 +1,10 @@
1
1
  import React from "react";
2
2
  import {Select} from "antd";
3
- import {DictUtils} from "../utils";
3
+ import {DictUtils} from "../../utils";
4
4
 
5
5
  export function FieldDictSelect(props) {
6
- const {value, onChange, typeCode, ...rest} = props
7
- const options = DictUtils.dictOptions(typeCode)
6
+ const {value, onChange, typeCode, ...rest} = props;
7
+ const options = DictUtils.dictOptions(typeCode);
8
8
 
9
9
  return <Select value={value}
10
10
  onChange={onChange}
@@ -12,5 +12,5 @@ export function FieldDictSelect(props) {
12
12
  options={options}
13
13
  {...rest}>
14
14
 
15
- </Select>
16
- }
15
+ </Select>;
16
+ }
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { FieldProps } from '../types';
3
+
4
+ /**
5
+ * 富文本编辑器
6
+ *
7
+ * 图片上传相关配置 https://www.tiny.cloud/docs/tinymce/7/image/
8
+ */
9
+ interface FieldEditProps extends FieldProps<string> {
10
+ height?: number;
11
+ }
12
+
13
+ export class FieldEditor extends React.Component<FieldEditProps, any> {
14
+ }
@@ -0,0 +1,59 @@
1
+ import React from 'react';
2
+ import {Editor as TinyMceEditor} from '@tinymce/tinymce-react';
3
+
4
+ /**
5
+ * 富文本编辑器
6
+ *
7
+ * 图片上传相关配置 https://www.tiny.cloud/docs/tinymce/7/image/
8
+ */
9
+ export class FieldEditor extends React.Component {
10
+ render() {
11
+ const uploadUrl = 'admin/sysFile/upload';
12
+ const jsUrl = 'admin/tinymce/tinymce.min.js';
13
+ const {value, onChange, height} = this.props;
14
+
15
+ return (
16
+ <>
17
+ <TinyMceEditor
18
+ initialValue={value}
19
+ tinymceScriptSrc={jsUrl}
20
+ init={{
21
+ min_height: 300,
22
+ language: 'zh_CN',
23
+ height: height,
24
+
25
+ // 上传图片
26
+ images_upload_url: uploadUrl,
27
+ promotion: false, // 不显示升级按钮(右上角)
28
+ cache_suffix: '?v=v7.7',
29
+
30
+ plugins: [
31
+ 'advlist', 'autolink', 'lists', 'link', 'image', 'charmap', 'preview',
32
+ 'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen',
33
+ 'insertdatetime', 'media', 'table', 'code', 'help', 'wordcount',
34
+ 'emoticons'
35
+ ],
36
+ image_description: false,
37
+
38
+ // 设置图片上传对话框默认选中上传Tab
39
+ setup: function (editor) {
40
+ editor.on('OpenWindow', function(e) {
41
+ const dialog = e.dialog;
42
+ // 包含 dimensions 属性应该就是 上传图片的对话框
43
+ if (dialog && dialog.getData().dimensions) {
44
+ dialog.showTab("upload");
45
+ }
46
+ });
47
+ },
48
+
49
+ }}
50
+ onChange={e => {
51
+ if (onChange) {
52
+ onChange(e.target.getContent());
53
+ }
54
+ }}
55
+ />
56
+ </>
57
+ );
58
+ }
59
+ }
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { FieldProps } from '../types';
3
+
4
+ interface FieldNumberRangeProps extends FieldProps<string> {
5
+ defaultValue?: string;
6
+ }
7
+
8
+ export class FieldNumberRange extends React.Component<FieldNumberRangeProps, any> {
9
+
10
+ }
@@ -1,59 +1,55 @@
1
1
  import React from "react";
2
2
  import {InputNumber} from "antd";
3
- import {StringUtils} from "../utils";
4
-
3
+ import {StringUtils} from "../../utils";
5
4
 
6
5
  const SP = StringUtils.ISO_SPLITTER;
7
6
 
8
7
  export class FieldNumberRange extends React.Component {
9
-
10
-
11
8
  onChangeA = (a) => {
12
- const {b} = this.parse(this.props.value)
13
- this.props.onChange && this.props.onChange(this.merge(a, b))
14
- }
9
+ const {b} = this.parse(this.props.value);
10
+ this.props.onChange && this.props.onChange(this.merge(a, b));
11
+ };
12
+
15
13
  onChangeB = (b) => {
16
- const {a} = this.parse(this.props.value)
17
- this.props.onChange && this.props.onChange(this.merge(a, b))
18
- }
14
+ const {a} = this.parse(this.props.value);
15
+ this.props.onChange && this.props.onChange(this.merge(a, b));
16
+ };
19
17
 
20
18
  merge(a, b) {
21
19
  if (a == null) {
22
- a = ''
20
+ a = '';
23
21
  }
24
22
  if (b == null) {
25
- b = ''
23
+ b = '';
26
24
  }
27
25
  return a + SP + b;
28
26
  }
29
27
 
30
28
  parse(v) {
31
29
  if (v == null) {
32
- return {a: null, b: null}
30
+ return {a: null, b: null};
33
31
  }
34
32
  const arr = v.split(SP);
35
- return {a: arr[0], b: arr[1]}
33
+ return {a: arr[0] ? Number(arr[0]) : null, b: arr[1] ? Number(arr[1]) : null};
36
34
  }
37
35
 
38
36
  componentDidMount() {
39
- let {value, defaultValue} = this.props
40
- if (value == null) {
41
- this.props.onChange && this.props.onChange(defaultValue)
37
+ const {value, defaultValue} = this.props;
38
+ if (value == null && defaultValue) {
39
+ this.props.onChange && this.props.onChange(defaultValue);
42
40
  }
43
-
44
41
  }
45
42
 
46
-
47
43
  render() {
48
- let {value, defaultValue} = this.props
44
+ let {value, defaultValue} = this.props;
49
45
  if (value == null) {
50
- value = defaultValue
46
+ value = defaultValue;
51
47
  }
52
- const {a, b} = this.parse(value)
48
+ const {a, b} = this.parse(value);
53
49
 
54
50
  return <div style={{display: 'flex', alignItems: 'center'}}>
55
51
  <InputNumber value={a} onChange={this.onChangeA}/> - <InputNumber value={b} onChange={this.onChangeB}/>
56
- </div>
52
+ </div>;
57
53
  }
58
54
 
59
- }
55
+ }
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { FieldProps } from '../types';
3
+
4
+ /**
5
+ * 数字的百分数输入框
6
+ */
7
+ export class FieldPercent extends React.Component<FieldProps<number>, any> {
8
+ }
@@ -1,20 +1,24 @@
1
1
  import {InputNumber, Space} from 'antd';
2
2
  import React from 'react';
3
3
 
4
+ /**
5
+ * 数字的百分数输入框
6
+ */
4
7
  export class FieldPercent extends React.Component {
5
8
  render() {
6
9
  const {value, onChange, ...rest} = this.props;
7
10
 
8
-
9
11
  return (
10
12
  <Space.Compact>
11
13
  <InputNumber
12
14
  min={0}
13
15
  max={100}
14
- value={ Number((value * 100).toFixed(0))}
16
+ value={Number((value * 100).toFixed(0))}
15
17
  onChange={v => {
16
- v = (v / 100).toFixed(2);
17
- onChange(Number(v))
18
+ if (v !== null) {
19
+ const percentValue = Number((v / 100).toFixed(2));
20
+ onChange && onChange(percentValue);
21
+ }
18
22
  }}
19
23
  {...rest}
20
24
  />
@@ -23,5 +27,4 @@ export class FieldPercent extends React.Component {
23
27
 
24
28
  );
25
29
  }
26
- }
27
-
30
+ }
@@ -0,0 +1,44 @@
1
+ import React from 'react';
2
+ import { SelectProps } from "antd/es/select";
3
+ import { FieldProps } from '../types';
4
+
5
+ interface FieldRemoteSelectProps extends Omit<SelectProps, 'value' | 'onChange'>, FieldProps<any> {
6
+ /**
7
+ * 请求地址
8
+ */
9
+ url: string;
10
+ /**
11
+ * 防抖时间(毫秒)
12
+ */
13
+ debounceTime?: number;
14
+ /**
15
+ * 请求参数处理函数
16
+ */
17
+ paramsProcessor?: (params: any) => any;
18
+ /**
19
+ * 响应数据处理函数
20
+ */
21
+ dataProcessor?: (data: any) => any;
22
+ /**
23
+ * 缓存大小
24
+ */
25
+ cacheSize?: number;
26
+ /**
27
+ * 初始加载
28
+ */
29
+ initialLoad?: boolean;
30
+ /**
31
+ * 搜索时是否清空已选项
32
+ */
33
+ clearOnSearch?: boolean;
34
+ /**
35
+ * 请求失败回调
36
+ */
37
+ onError?: (error: any) => void;
38
+ /**
39
+ * 加载完成回调
40
+ */
41
+ onLoad?: (data: any) => void;
42
+ }
43
+
44
+ export const FieldRemoteSelect: React.FC<FieldRemoteSelectProps>;
@@ -0,0 +1,125 @@
1
+ import React, { useState, useEffect, useCallback, useRef } from 'react';
2
+ import { Select, Spin, message } from 'antd';
3
+ import { debounce } from 'lodash';
4
+ import { HttpUtils } from "../../utils";
5
+
6
+ export const FieldRemoteSelect = ({
7
+ url,
8
+ debounceTime = 500,
9
+ paramsProcessor,
10
+ dataProcessor,
11
+ cacheSize = 10,
12
+ initialLoad = true,
13
+ clearOnSearch = false,
14
+ onError,
15
+ onLoad,
16
+ value,
17
+ ...rest
18
+ }) => {
19
+ const [options, setOptions] = useState([]);
20
+ const [loading, setLoading] = useState(false);
21
+ const [cache, setCache] = useState(new Map());
22
+ const fetchIdRef = useRef(0);
23
+ const searchHistoryRef = useRef([]);
24
+
25
+ const loadData = useCallback(async (searchText = '') => {
26
+ const fetchId = ++fetchIdRef.current;
27
+ const cacheKey = searchText || '_initial_';
28
+
29
+ // 检查缓存
30
+ if (cache.has(cacheKey)) {
31
+ const cachedData = cache.get(cacheKey);
32
+ setOptions(cachedData || []);
33
+ onLoad?.(cachedData);
34
+ return;
35
+ }
36
+
37
+ setLoading(true);
38
+
39
+ try {
40
+ let params = { searchText, selected: value };
41
+ if (paramsProcessor) {
42
+ params = paramsProcessor(params);
43
+ }
44
+
45
+ const data = await HttpUtils.get(url, params);
46
+ const processedData = dataProcessor ? dataProcessor(data) : data;
47
+
48
+ if (fetchId === fetchIdRef.current) {
49
+ setOptions(processedData || []);
50
+
51
+ // 更新缓存
52
+ setCache(prevCache => {
53
+ const newCache = new Map(prevCache);
54
+ newCache.set(cacheKey, processedData || []);
55
+
56
+ // 限制缓存大小
57
+ if (newCache.size > cacheSize) {
58
+ const firstKey = newCache.keys().next().value;
59
+ newCache.delete(firstKey);
60
+ }
61
+
62
+ return newCache;
63
+ });
64
+
65
+ onLoad?.(processedData);
66
+ }
67
+ } catch (error) {
68
+ console.error('远程搜索失败:', error);
69
+ message.error('搜索失败,请重试');
70
+ setOptions([]);
71
+ onError?.(error);
72
+ } finally {
73
+ if (fetchId === fetchIdRef.current) {
74
+ setLoading(false);
75
+ }
76
+ }
77
+ }, [url, value, paramsProcessor, dataProcessor, cache, cacheSize, onError, onLoad]);
78
+
79
+ // 使用 useMemo 缓存 debounce 函数
80
+ const debouncedLoadData = useCallback(
81
+ debounce((value) => loadData(value), debounceTime),
82
+ [loadData, debounceTime]
83
+ );
84
+
85
+ useEffect(() => {
86
+ if (initialLoad) {
87
+ loadData();
88
+ }
89
+ }, [initialLoad, loadData]);
90
+
91
+ const handleSearch = useCallback((searchValue) => {
92
+ const trimmedValue = searchValue.trim();
93
+
94
+ // 记录搜索历史
95
+ if (trimmedValue && !searchHistoryRef.current.includes(trimmedValue)) {
96
+ searchHistoryRef.current = [trimmedValue, ...searchHistoryRef.current].slice(0, 5);
97
+ }
98
+
99
+ if (trimmedValue === '') {
100
+ setOptions([]);
101
+ return;
102
+ }
103
+
104
+ debouncedLoadData(trimmedValue);
105
+ }, [debouncedLoadData]);
106
+
107
+ return (
108
+ <Select
109
+ showSearch={{
110
+ filterOption: false,
111
+ onSearch: handleSearch,
112
+ }}
113
+ options={options}
114
+ notFoundContent={loading ? <Spin size="small" /> : '数据为空'}
115
+ style={{ width: '100%', minWidth: 200 }}
116
+ allowClear
117
+ loading={loading}
118
+ {...rest}
119
+ />
120
+ );
121
+ };
122
+
123
+ FieldRemoteSelect.defaultProps = {
124
+ placeholder: '请搜索选择'
125
+ };
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import {SelectProps} from "antd/es/select";
3
+
4
+ interface FieldRemoteSelectMultipleProps extends Omit<SelectProps, 'options' | 'children'| 'mode' | 'value' | 'onChange'> {
5
+ /**
6
+ * 请求地址
7
+ */
8
+ url: string;
9
+ /**
10
+ * 选中的值
11
+ */
12
+ value?: any[];
13
+ /**
14
+ * 值变化回调
15
+ */
16
+ onChange?: (value: any[]) => void;
17
+ }
18
+
19
+ export class FieldRemoteSelectMultiple extends React.Component<FieldRemoteSelectMultipleProps, any> {
20
+ }
@@ -1,18 +1,18 @@
1
1
  import React from 'react';
2
2
  import {Select, Spin, message} from 'antd';
3
3
  import {debounce} from 'lodash';
4
- import {HttpUtils} from "../utils";
4
+ import {HttpUtils} from "../../utils";
5
5
 
6
6
  export class FieldRemoteSelectMultiple extends React.Component {
7
7
  constructor(props) {
8
8
  super(props);
9
9
 
10
+ this.fetchIdRef = 0;
10
11
  this.state = {
11
12
  options: [],
12
13
  loading: false,
13
14
  };
14
15
 
15
- this.fetchIdRef = 0;
16
16
  this.loadDataDebounce = debounce(this.loadData, 800);
17
17
  }
18
18
 
@@ -21,7 +21,7 @@ export class FieldRemoteSelectMultiple extends React.Component {
21
21
  };
22
22
 
23
23
  componentDidMount() {
24
- this.loadData('')
24
+ this.loadData('');
25
25
  }
26
26
 
27
27
  componentWillUnmount() {
@@ -82,5 +82,4 @@ export class FieldRemoteSelectMultiple extends React.Component {
82
82
  </Select>
83
83
  );
84
84
  }
85
- }
86
-
85
+ }
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import {SelectProps} from "antd/es/select";
3
+ import { FieldProps } from '../types';
4
+
5
+ /**
6
+ * 多选,但是值是字符串,逗号破解的
7
+ */
8
+ export interface FieldRemoteSelectMultipleInlineProps extends Omit<SelectProps, 'options' | 'children'| 'mode' | 'value' | 'onChange'>, FieldProps<string> {
9
+ /**
10
+ * 请求地址
11
+ */
12
+ url: string;
13
+
14
+ /**
15
+ * 默认展开所有
16
+ */
17
+ treeDefaultExpandAll?: boolean;
18
+ }
19
+
20
+ export class FieldRemoteSelectMultipleInline extends React.Component<FieldRemoteSelectMultipleInlineProps, any> {
21
+ }
@@ -1,18 +1,21 @@
1
1
  import React from 'react';
2
2
  import {Select, Spin, message} from 'antd';
3
3
  import {debounce} from 'lodash';
4
- import {HttpUtils, StringUtils} from "../utils";
4
+ import {HttpUtils, StringUtils} from "../../utils";
5
5
 
6
+ /**
7
+ * 多选,但是值是字符串,逗号破解的
8
+ */
6
9
  export class FieldRemoteSelectMultipleInline extends React.Component {
7
10
  constructor(props) {
8
11
  super(props);
9
12
 
13
+ this.fetchIdRef = 0;
10
14
  this.state = {
11
15
  options: [],
12
16
  loading: false,
13
17
  };
14
18
 
15
- this.fetchIdRef = 0;
16
19
  this.loadDataDebounce = debounce(this.loadData, 800);
17
20
  }
18
21
 
@@ -21,7 +24,7 @@ export class FieldRemoteSelectMultipleInline extends React.Component {
21
24
  };
22
25
 
23
26
  componentDidMount() {
24
- this.loadData('')
27
+ this.loadData('');
25
28
  }
26
29
 
27
30
  componentWillUnmount() {
@@ -71,7 +74,7 @@ export class FieldRemoteSelectMultipleInline extends React.Component {
71
74
  }
72
75
  }
73
76
  value={StringUtils.split(value, ',')}
74
- onChange={arr=>onChange(StringUtils.join(arr, ','))}
77
+ onChange={arr => onChange && onChange(StringUtils.join(arr, ','))}
75
78
  options={options}
76
79
  notFoundContent={loading ? <Spin size="small"/> : '数据为空'}
77
80
  style={{width: '100%', minWidth: 200}}
@@ -82,5 +85,4 @@ export class FieldRemoteSelectMultipleInline extends React.Component {
82
85
  </Select>
83
86
  );
84
87
  }
85
- }
86
-
88
+ }