@cqsjjb/jjb-react-admin-component 3.3.11 → 3.3.12
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/AMap/index.js +2 -4
- package/AdaptiveTree/index.js +103 -107
- package/BMap/index.js +0 -6
- package/ControlWrapper/index.js +0 -11
- package/Editor/index.js +0 -1
- package/ErrorBoundary/index.js +3 -5
- package/FileUploader/index.js +35 -36
- package/FormilyDescriptions/index.js +3 -13
- package/FormilyRenderer/index.js +0 -1
- package/ImageCropper/index.js +0 -1
- package/ImageUploader/index.js +0 -1
- package/ListDataContainer/index.js +48 -47
- package/MediaQuery/index.js +2 -9
- package/PageLayout/index.js +6 -11
- package/PhoneBox/index.js +21 -23
- package/SearchForm/index.js +11 -20
- package/Table/index.js +16 -35
- package/TableAction/index.js +7 -10
- package/package.json +2 -2
- package/tools/index.js +1 -1
- package/Layout/README.md +0 -41
- package/Layout/index.d.ts +0 -81
- package/Layout/index.js +0 -99
- package/Layout/index.less +0 -112
|
@@ -1,48 +1,49 @@
|
|
|
1
1
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
2
|
-
import ProTable from '@cqsjjb/jjb-react-admin-component/Table';
|
|
3
|
-
import SearchForm from '@cqsjjb/jjb-react-admin-component/SearchForm';
|
|
4
2
|
import React, { useState, useEffect, useCallback, useImperativeHandle, forwardRef, useRef } from 'react';
|
|
5
|
-
import { Table, Form } from 'antd';
|
|
3
|
+
import { Table, Row, Col, Form } from 'antd';
|
|
4
|
+
import { isEqual } from 'lodash';
|
|
5
|
+
import SearchForm from '@cqsjjb/jjb-react-admin-component/SearchForm';
|
|
6
|
+
import ProTable from '@cqsjjb/jjb-react-admin-component/Table';
|
|
6
7
|
|
|
7
|
-
/**
|
|
8
|
-
* @component ListDataContainer
|
|
9
|
-
* @description 通用列表数据容器组件,提供搜索表单、数据表格、分页等功能的完整列表页面解决方案
|
|
10
|
-
*
|
|
11
|
-
* @props {Array} columns - 表格列配置,遵循Ant Design Table组件的columns规范
|
|
12
|
-
* @props {Function} fetchDataApi - 数据获取API函数,接收分页和搜索参数,返回包含list和total的对象
|
|
13
|
-
* @props {Array} searchFormConfig - 搜索表单配置数组
|
|
14
|
-
* @param {React.Component} searchFormConfig[].field - 表单项组件(如ControlWrapper.Select)
|
|
15
|
-
* @param {string} searchFormConfig[].name - 表单项字段名
|
|
16
|
-
* @param {string} searchFormConfig[].label - 表单项标签
|
|
17
|
-
* @param {Object} searchFormConfig[].fieldProps - 传递给字段组件的属性
|
|
18
|
-
* @param {Object} searchFormConfig[].itemProps - 传递给Form.Item的属性
|
|
19
|
-
* @param {React.ReactNode} searchFormConfig[].content - 字段组件的子元素(如Select.Option列表)
|
|
20
|
-
* @param {boolean} searchFormConfig[].required - 是否必填
|
|
21
|
-
* @props {string} rowKey - 表格行键值,默认为'id'
|
|
22
|
-
* @props {Object} initialPagination - 初始分页配置,包含current、pageSize等分页属性
|
|
23
|
-
* @props {Object} tableProps - 传递给Table组件的属性
|
|
24
|
-
* @props {Object} searchFormProps - 传递给SearchForm组件的属性
|
|
25
|
-
* @props {boolean} proTable - 是否使用ProTable组件,默认为false
|
|
26
|
-
* @example
|
|
27
|
-
* // 基础用法
|
|
28
|
-
* <ListDataContainer
|
|
29
|
-
* columns={tableColumns}
|
|
30
|
-
* fetchDataApi={getCourseList}
|
|
31
|
-
* searchFormConfig={[
|
|
32
|
-
* {
|
|
33
|
-
* field: Select,
|
|
34
|
-
* name: 'status',
|
|
35
|
-
* label: '状态',
|
|
36
|
-
* }
|
|
37
|
-
* {
|
|
38
|
-
* field: Input,
|
|
39
|
-
* name: 'name',
|
|
40
|
-
* label: '名称',
|
|
41
|
-
* required: true,
|
|
42
|
-
* }
|
|
43
|
-
* ]}
|
|
44
|
-
* />
|
|
45
|
-
*
|
|
8
|
+
/**
|
|
9
|
+
* @component ListDataContainer
|
|
10
|
+
* @description 通用列表数据容器组件,提供搜索表单、数据表格、分页等功能的完整列表页面解决方案
|
|
11
|
+
*
|
|
12
|
+
* @props {Array} columns - 表格列配置,遵循Ant Design Table组件的columns规范
|
|
13
|
+
* @props {Function} fetchDataApi - 数据获取API函数,接收分页和搜索参数,返回包含list和total的对象
|
|
14
|
+
* @props {Array} searchFormConfig - 搜索表单配置数组
|
|
15
|
+
* @param {React.Component} searchFormConfig[].field - 表单项组件(如ControlWrapper.Select)
|
|
16
|
+
* @param {string} searchFormConfig[].name - 表单项字段名
|
|
17
|
+
* @param {string} searchFormConfig[].label - 表单项标签
|
|
18
|
+
* @param {Object} searchFormConfig[].fieldProps - 传递给字段组件的属性
|
|
19
|
+
* @param {Object} searchFormConfig[].itemProps - 传递给Form.Item的属性
|
|
20
|
+
* @param {React.ReactNode} searchFormConfig[].content - 字段组件的子元素(如Select.Option列表)
|
|
21
|
+
* @param {boolean} searchFormConfig[].required - 是否必填
|
|
22
|
+
* @props {string} rowKey - 表格行键值,默认为'id'
|
|
23
|
+
* @props {Object} initialPagination - 初始分页配置,包含current、pageSize等分页属性
|
|
24
|
+
* @props {Object} tableProps - 传递给Table组件的属性
|
|
25
|
+
* @props {Object} searchFormProps - 传递给SearchForm组件的属性
|
|
26
|
+
* @props {boolean} proTable - 是否使用ProTable组件,默认为false
|
|
27
|
+
* @example
|
|
28
|
+
* // 基础用法
|
|
29
|
+
* <ListDataContainer
|
|
30
|
+
* columns={tableColumns}
|
|
31
|
+
* fetchDataApi={getCourseList}
|
|
32
|
+
* searchFormConfig={[
|
|
33
|
+
* {
|
|
34
|
+
* field: Select,
|
|
35
|
+
* name: 'status',
|
|
36
|
+
* label: '状态',
|
|
37
|
+
* }
|
|
38
|
+
* {
|
|
39
|
+
* field: Input,
|
|
40
|
+
* name: 'name',
|
|
41
|
+
* label: '名称',
|
|
42
|
+
* required: true,
|
|
43
|
+
* }
|
|
44
|
+
* ]}
|
|
45
|
+
* />
|
|
46
|
+
*
|
|
46
47
|
*/
|
|
47
48
|
|
|
48
49
|
const SELECT_COMPONENTS = ['Select', 'TreeSelect', 'Cascader', 'DatePicker', 'TimePicker', 'Checkbox', 'Radio', 'Switch', 'Slider', 'Upload'];
|
|
@@ -75,10 +76,10 @@ const ListDataContainer = /*#__PURE__*/forwardRef(({
|
|
|
75
76
|
return Component.displayName || Component.constructor.name;
|
|
76
77
|
};
|
|
77
78
|
|
|
78
|
-
/**
|
|
79
|
-
* 数据加载与刷新方法
|
|
80
|
-
* @param {Object} [overrideParams={}] - 可选,用于覆盖内部参数的键值对
|
|
81
|
-
* 若传入,会覆盖同名的表单参数和分页参数(如page、pageSize或搜索字段)
|
|
79
|
+
/**
|
|
80
|
+
* 数据加载与刷新方法
|
|
81
|
+
* @param {Object} [overrideParams={}] - 可选,用于覆盖内部参数的键值对
|
|
82
|
+
* 若传入,会覆盖同名的表单参数和分页参数(如page、pageSize或搜索字段)
|
|
82
83
|
*/
|
|
83
84
|
const loadDataSource = useCallback(async (overrideParams = {}) => {
|
|
84
85
|
if (!fetchDataApi) return;
|
|
@@ -94,7 +95,7 @@ const ListDataContainer = /*#__PURE__*/forwardRef(({
|
|
|
94
95
|
|
|
95
96
|
// 1. 获取组件内部的表单参数
|
|
96
97
|
const formValues = await form.current.validateFields();
|
|
97
|
-
console.warn(
|
|
98
|
+
console.warn("formValues", formValues);
|
|
98
99
|
|
|
99
100
|
// 2. 构造基础参数:分页参数 + 表单参数
|
|
100
101
|
const baseParams = {
|
package/MediaQuery/index.js
CHANGED
|
@@ -7,16 +7,11 @@ const MEDIA_QUERY_LIST = {
|
|
|
7
7
|
MIN_WIDTH_1200_AND_MAX_WIDTH_1439: '(min-width: 1200px) and (max-width: 1439px)',
|
|
8
8
|
MIN_WIDTH_1440: '(min-width: 1440px)'
|
|
9
9
|
};
|
|
10
|
-
function MediaQuery({
|
|
10
|
+
export default function MediaQuery({
|
|
11
11
|
children,
|
|
12
12
|
disabled
|
|
13
13
|
}) {
|
|
14
14
|
const [media, setMedia] = useState(undefined);
|
|
15
|
-
|
|
16
|
-
/** 显示弃用警告 */
|
|
17
|
-
useEffect(() => {
|
|
18
|
-
console.warn('[MediaQuery] 警告:该组件已弃用!');
|
|
19
|
-
}, []);
|
|
20
15
|
const mediaQueries = useMemo(() => {
|
|
21
16
|
if (disabled) return {};
|
|
22
17
|
return Object.fromEntries(Object.entries(MEDIA_QUERY_LIST).map(([key, query]) => [key, window.matchMedia(query)]));
|
|
@@ -44,6 +39,4 @@ function MediaQuery({
|
|
|
44
39
|
key: index,
|
|
45
40
|
'data-media-query': media
|
|
46
41
|
}) : item));
|
|
47
|
-
}
|
|
48
|
-
MediaQuery.displayName = 'MediaQuery';
|
|
49
|
-
export default MediaQuery;
|
|
42
|
+
}
|
package/PageLayout/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import React, { memo, useCallback
|
|
1
|
+
import React, { memo, useCallback } from 'react';
|
|
2
2
|
import { PageHeader } from '@ant-design/pro-layout';
|
|
3
|
-
import { AppDataContext } from '@cqsjjb/jjb-data-provider';
|
|
4
3
|
import './index.less';
|
|
5
4
|
import { getPrefixCls } from '../tools/index.js';
|
|
6
5
|
const prefixCls = getPrefixCls();
|
|
@@ -25,9 +24,6 @@ const PageLayout = /*#__PURE__*/memo(props => {
|
|
|
25
24
|
onBack,
|
|
26
25
|
'data-node-id': dataNodeId
|
|
27
26
|
} = props;
|
|
28
|
-
const {
|
|
29
|
-
checkField
|
|
30
|
-
} = useContext(AppDataContext);
|
|
31
27
|
const containerClass = [`${prefixCls}-layout-container`, transparent && `${prefixCls}-layout-container-transparent`, noStyle && `${prefixCls}-layout-container-no-style`].filter(Boolean).join(' ');
|
|
32
28
|
const backHandler = useCallback(() => {
|
|
33
29
|
if (onBack) {
|
|
@@ -44,22 +40,21 @@ const PageLayout = /*#__PURE__*/memo(props => {
|
|
|
44
40
|
className: containerClass,
|
|
45
41
|
"data-node-id": dataNodeId
|
|
46
42
|
}, !header ? /*#__PURE__*/React.createElement(PageHeader, {
|
|
47
|
-
title:
|
|
43
|
+
title: title,
|
|
48
44
|
extra: extra,
|
|
49
45
|
style: pageHeaderStyle,
|
|
50
46
|
onBack: previous || onBack ? backHandler : undefined
|
|
51
47
|
}) : header, formLine && /*#__PURE__*/React.createElement("div", {
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
className: `${prefixCls}-layout-container-tools`,
|
|
49
|
+
style: formLineStyle
|
|
54
50
|
}, formLine), /*#__PURE__*/React.createElement("div", {
|
|
55
51
|
style: contentStyle,
|
|
56
52
|
className: `${prefixCls}-layout-container-content`
|
|
57
53
|
}, /*#__PURE__*/React.createElement("div", {
|
|
58
54
|
className: `${prefixCls}-layout-container-content-abs`
|
|
59
55
|
}, children)), footer && /*#__PURE__*/React.createElement("div", {
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
className: `${prefixCls}-lay-container-bottom`,
|
|
57
|
+
style: footerStyle
|
|
62
58
|
}, footer));
|
|
63
59
|
});
|
|
64
|
-
PageLayout.displayName = 'PageLayout';
|
|
65
60
|
export default PageLayout;
|
package/PhoneBox/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import React, { useEffect, useState, useRef } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { Empty, Space, message, Tooltip, Button, QRCode } from 'antd';
|
|
3
3
|
import { SyncOutlined } from '@ant-design/icons';
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
4
|
+
import { http } from '@cqsjjb/jjb-common-lib';
|
|
5
|
+
import shexiang from './shexiang.svg';
|
|
6
6
|
import xinhao from './xinhao.svg';
|
|
7
7
|
import wangluo from './wangluo.svg';
|
|
8
8
|
import dianchi from './dianchi.svg';
|
|
9
|
-
import
|
|
9
|
+
import phone from './phone.svg';
|
|
10
10
|
import './index.less';
|
|
11
|
-
|
|
11
|
+
export default props => {
|
|
12
12
|
const {
|
|
13
13
|
iframeUrl,
|
|
14
14
|
// 展示内容url
|
|
@@ -118,7 +118,7 @@ function PhoneBox(props) {
|
|
|
118
118
|
return /*#__PURE__*/React.createElement("div", {
|
|
119
119
|
className: `phone-box ${size === 'small' ? 'phone-box-small' : ''}`
|
|
120
120
|
}, /*#__PURE__*/React.createElement("img", {
|
|
121
|
-
alt: "
|
|
121
|
+
alt: "",
|
|
122
122
|
src: phone,
|
|
123
123
|
width: 356,
|
|
124
124
|
height: 720
|
|
@@ -130,23 +130,23 @@ function PhoneBox(props) {
|
|
|
130
130
|
className: "phone-header-time"
|
|
131
131
|
}, currentTime), /*#__PURE__*/React.createElement("img", {
|
|
132
132
|
src: shexiang,
|
|
133
|
-
alt: "\u6444\u50CF\u5934",
|
|
134
133
|
width: 76,
|
|
135
|
-
height: 23
|
|
134
|
+
height: 23,
|
|
135
|
+
alt: ""
|
|
136
136
|
}), /*#__PURE__*/React.createElement(Space, {
|
|
137
137
|
className: "phone-header-status"
|
|
138
138
|
}, /*#__PURE__*/React.createElement("img", {
|
|
139
|
+
className: "status-xinhao",
|
|
139
140
|
src: xinhao,
|
|
140
|
-
alt: "
|
|
141
|
-
className: "status-xinhao"
|
|
141
|
+
alt: ""
|
|
142
142
|
}), /*#__PURE__*/React.createElement("img", {
|
|
143
|
+
className: "status-wangluo",
|
|
143
144
|
src: wangluo,
|
|
144
|
-
alt: "
|
|
145
|
-
className: "status-wangluo"
|
|
145
|
+
alt: ""
|
|
146
146
|
}), /*#__PURE__*/React.createElement("img", {
|
|
147
|
+
className: "status-dianchi",
|
|
147
148
|
src: dianchi,
|
|
148
|
-
alt: "
|
|
149
|
-
className: "status-dianchi"
|
|
149
|
+
alt: ""
|
|
150
150
|
}))), showEmpty && !iframeUrl ? /*#__PURE__*/React.createElement("div", {
|
|
151
151
|
style: {
|
|
152
152
|
width: 316,
|
|
@@ -165,8 +165,10 @@ function PhoneBox(props) {
|
|
|
165
165
|
className: "phone-box-action"
|
|
166
166
|
}, showPerview && /*#__PURE__*/React.createElement(Tooltip, {
|
|
167
167
|
open: qrcodeVisible,
|
|
168
|
+
placement: "bottom",
|
|
168
169
|
arrow: false,
|
|
169
170
|
color: "#FFF",
|
|
171
|
+
rootClassName: "qrcode-preview-tooltip",
|
|
170
172
|
title: /*#__PURE__*/React.createElement("div", {
|
|
171
173
|
className: "qrcode-preview-container"
|
|
172
174
|
}, /*#__PURE__*/React.createElement(QRCode, {
|
|
@@ -196,18 +198,14 @@ function PhoneBox(props) {
|
|
|
196
198
|
style: {
|
|
197
199
|
marginRight: '4px'
|
|
198
200
|
}
|
|
199
|
-
}), "\u91CD\u65B0\u751F\u6210"))
|
|
200
|
-
placement: "bottom",
|
|
201
|
-
rootClassName: "qrcode-preview-tooltip"
|
|
201
|
+
}), "\u91CD\u65B0\u751F\u6210"))
|
|
202
202
|
}, /*#__PURE__*/React.createElement(Button, {
|
|
203
203
|
ref: qrcodeButtonRef,
|
|
204
|
-
color: "primary",
|
|
205
|
-
variant: "outlined",
|
|
206
204
|
onClick: () => {
|
|
207
205
|
setQrcodeVisible(!qrcodeVisible);
|
|
208
206
|
getQrCodeUrl();
|
|
209
|
-
}
|
|
207
|
+
},
|
|
208
|
+
color: "primary",
|
|
209
|
+
variant: "outlined"
|
|
210
210
|
}, "\u626B\u7801\u9884\u89C8")), extraAction));
|
|
211
|
-
}
|
|
212
|
-
PhoneBox.displayName = 'PhoneBox';
|
|
213
|
-
export default PhoneBox;
|
|
211
|
+
};
|
package/SearchForm/index.js
CHANGED
|
@@ -58,7 +58,6 @@ const SearchForm = ({
|
|
|
58
58
|
}, [formRef, onRef]);
|
|
59
59
|
const isControlled = expand !== undefined;
|
|
60
60
|
const isOpen = isControlled ? expand : internalOpen;
|
|
61
|
-
// 展开/收起
|
|
62
61
|
const handleToggle = () => {
|
|
63
62
|
if (isControlled) {
|
|
64
63
|
onExpand && onExpand(!expand);
|
|
@@ -73,8 +72,8 @@ const SearchForm = ({
|
|
|
73
72
|
const getButtons = () => /*#__PURE__*/React.createElement(Space, null, /*#__PURE__*/React.createElement(Button, {
|
|
74
73
|
type: "primary",
|
|
75
74
|
icon: /*#__PURE__*/React.createElement(SearchOutlined, null),
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
htmlType: "submit",
|
|
76
|
+
loading: loading
|
|
78
77
|
}, "\u67E5\u8BE2"), /*#__PURE__*/React.createElement(Button, {
|
|
79
78
|
icon: /*#__PURE__*/React.createElement(UndoOutlined, null),
|
|
80
79
|
loading: loading,
|
|
@@ -92,28 +91,21 @@ const SearchForm = ({
|
|
|
92
91
|
onClick: handleToggle
|
|
93
92
|
}, isOpen ? '收起' : '展开'));
|
|
94
93
|
|
|
95
|
-
/**
|
|
96
|
-
* 处理 formLine,确保所有 Form.Item 都有 noStyle 属性
|
|
97
|
-
* @param {ReactNode[]} nodes - 表单节点数组
|
|
98
|
-
* @returns {ReactNode[]} - 处理后的节点数组
|
|
94
|
+
/**
|
|
95
|
+
* 处理 formLine,确保所有 Form.Item 都有 noStyle 属性
|
|
96
|
+
* @param {ReactNode[]} nodes - 表单节点数组
|
|
97
|
+
* @returns {ReactNode[]} - 处理后的节点数组
|
|
99
98
|
*/
|
|
100
99
|
const processFormLine = nodes => {
|
|
101
100
|
return nodes.map(node => {
|
|
102
101
|
// 检查是否是 Form.Item 组件
|
|
103
102
|
if (/*#__PURE__*/React.isValidElement(node) && node.type === Form.Item) {
|
|
104
103
|
// 如果没有 noStyle 属性,则克隆并添加
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
...(control.props.style || {}),
|
|
111
|
-
width: '100%'
|
|
112
|
-
},
|
|
113
|
-
allowClear: true,
|
|
114
|
-
...control.props
|
|
115
|
-
})
|
|
116
|
-
});
|
|
104
|
+
if (!node.props.noStyle) {
|
|
105
|
+
return /*#__PURE__*/React.cloneElement(node, {
|
|
106
|
+
noStyle: true
|
|
107
|
+
});
|
|
108
|
+
}
|
|
117
109
|
}
|
|
118
110
|
return node;
|
|
119
111
|
});
|
|
@@ -164,5 +156,4 @@ const SearchForm = ({
|
|
|
164
156
|
}
|
|
165
157
|
}, getButtons()))));
|
|
166
158
|
};
|
|
167
|
-
SearchForm.displayName = 'SearchForm';
|
|
168
159
|
export default SearchForm;
|
package/Table/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import React, { useRef, useEffect, useState, useCallback } from 'react';
|
|
|
3
3
|
import { ProTable } from '@ant-design/pro-components';
|
|
4
4
|
import './index.less';
|
|
5
5
|
import { antPrefix } from './utils';
|
|
6
|
-
function TablePro(props) {
|
|
6
|
+
export default function TablePro(props) {
|
|
7
7
|
const prefix = antPrefix || 'ant';
|
|
8
8
|
const baseCls = `.${prefix}-table`;
|
|
9
9
|
const ref = useRef(null);
|
|
@@ -12,9 +12,6 @@ function TablePro(props) {
|
|
|
12
12
|
const tableFooterCls = `${baseCls}-footer`;
|
|
13
13
|
const {
|
|
14
14
|
enableAutoScrollY = true,
|
|
15
|
-
rowKey,
|
|
16
|
-
columns,
|
|
17
|
-
scroll,
|
|
18
15
|
options = {
|
|
19
16
|
reload: false,
|
|
20
17
|
density: true,
|
|
@@ -28,23 +25,6 @@ function TablePro(props) {
|
|
|
28
25
|
...restProps
|
|
29
26
|
} = props;
|
|
30
27
|
const [scrollY, setScrollY] = useState(undefined);
|
|
31
|
-
|
|
32
|
-
// 1. rowKey 兜底处理:如果没有 rowKey,使用数据索引下标
|
|
33
|
-
const finalRowKey = rowKey || ((record, index) => index);
|
|
34
|
-
|
|
35
|
-
// 3. scroll 处理:如果没有 scroll,设置 scroll={{ x: 1000 }},注意要合并 y 值
|
|
36
|
-
const finalScroll = React.useMemo(() => {
|
|
37
|
-
const baseScroll = scroll || {
|
|
38
|
-
x: 1000
|
|
39
|
-
};
|
|
40
|
-
if (enableAutoScrollY) {
|
|
41
|
-
return {
|
|
42
|
-
...baseScroll,
|
|
43
|
-
y: scrollY || 0
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
return baseScroll;
|
|
47
|
-
}, [scroll, enableAutoScrollY, scrollY]);
|
|
48
28
|
const timerRef = useRef(null);
|
|
49
29
|
const calcTableScrollY = () => {
|
|
50
30
|
const tableBody = ref.current?.querySelector?.(tableBodyCls);
|
|
@@ -54,7 +34,7 @@ function TablePro(props) {
|
|
|
54
34
|
const tablePagination = ref.current?.querySelector?.(tablePaginationCls);
|
|
55
35
|
const tablePaginationRect = tablePagination?.getBoundingClientRect();
|
|
56
36
|
const tableFooterHeight = tableFooterRect?.height || 0;
|
|
57
|
-
const tablePaginationMargin = 16
|
|
37
|
+
const tablePaginationMargin = 16;
|
|
58
38
|
const tablePaginationHeight = tablePaginationRect?.height || 0;
|
|
59
39
|
const border = 2;
|
|
60
40
|
const margin = 20;
|
|
@@ -74,45 +54,46 @@ function TablePro(props) {
|
|
|
74
54
|
}, []);
|
|
75
55
|
useEffect(() => {
|
|
76
56
|
if (!ref.current || !enableAutoScrollY) return;
|
|
57
|
+
|
|
77
58
|
// 创建 ResizeObserver 监听元素尺寸变化
|
|
78
|
-
const
|
|
59
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
79
60
|
// 等待 table-pagination 元素生成后再计算
|
|
80
61
|
debouncedCalcScrollY();
|
|
81
62
|
});
|
|
82
63
|
const mutationObserver = new MutationObserver(() => {
|
|
83
64
|
debouncedCalcScrollY();
|
|
84
65
|
});
|
|
85
|
-
mutationObserver.observe(ref.current
|
|
66
|
+
mutationObserver.observe(ref.current, {
|
|
86
67
|
childList: true,
|
|
87
68
|
subtree: true,
|
|
88
69
|
attributes: true
|
|
89
70
|
});
|
|
90
71
|
|
|
91
72
|
// 开始观察 ref.current 的尺寸变化
|
|
92
|
-
|
|
73
|
+
resizeObserver.observe(ref.current);
|
|
93
74
|
return () => {
|
|
94
75
|
if (timerRef.current) {
|
|
95
76
|
clearTimeout(timerRef.current);
|
|
96
77
|
}
|
|
97
|
-
|
|
78
|
+
resizeObserver.disconnect();
|
|
98
79
|
mutationObserver.disconnect();
|
|
99
80
|
};
|
|
100
81
|
}, [ref, enableAutoScrollY, debouncedCalcScrollY]);
|
|
101
82
|
return /*#__PURE__*/React.createElement("div", {
|
|
102
|
-
ref: ref
|
|
83
|
+
ref: ref,
|
|
84
|
+
style: {
|
|
85
|
+
height: '100%'
|
|
86
|
+
}
|
|
103
87
|
}, /*#__PURE__*/React.createElement(ProTable, _extends({
|
|
104
88
|
ghost: true,
|
|
105
|
-
bordered: true,
|
|
106
|
-
defaultSize: "default",
|
|
107
89
|
columnEmptyText: true,
|
|
108
90
|
search: false,
|
|
109
|
-
scroll:
|
|
110
|
-
|
|
91
|
+
scroll: enableAutoScrollY ? {
|
|
92
|
+
y: scrollY || 0
|
|
93
|
+
} : undefined,
|
|
111
94
|
className: `${antPrefix}-gbs-pro-table`,
|
|
112
95
|
options: options
|
|
113
96
|
}, restProps, {
|
|
114
|
-
columns: columns
|
|
97
|
+
columns: restProps.columns
|
|
115
98
|
})));
|
|
116
|
-
}
|
|
117
|
-
TablePro.displayName = 'TablePro';
|
|
118
|
-
export default TablePro;
|
|
99
|
+
}
|
package/TableAction/index.js
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { tools } from '@cqsjjb/jjb-common-lib';
|
|
2
3
|
import { Dropdown, Space } from 'antd';
|
|
3
|
-
|
|
4
|
-
function TableAction({
|
|
4
|
+
export default function TableAction({
|
|
5
5
|
maximum = 3,
|
|
6
6
|
children,
|
|
7
7
|
space,
|
|
8
|
-
enabledIcon = true,
|
|
9
8
|
placement = 'bottomRight',
|
|
10
9
|
// 下拉菜单位置,默认 bottomRight
|
|
11
10
|
trigger = ['hover'] // 下拉触发方式,默认 hover
|
|
12
11
|
}) {
|
|
13
12
|
// 将 children 统一成数组并过滤空值
|
|
14
|
-
const childArray = (
|
|
13
|
+
const childArray = (tools.isArray(children) ? children : [].concat(children)).filter(Boolean);
|
|
15
14
|
const showArray = childArray.slice(0, maximum);
|
|
16
15
|
const hideArray = childArray.slice(maximum);
|
|
17
16
|
return /*#__PURE__*/React.createElement(Space, {
|
|
@@ -23,9 +22,7 @@ function TableAction({
|
|
|
23
22
|
label: child
|
|
24
23
|
}))
|
|
25
24
|
},
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}, /*#__PURE__*/React.createElement("a", null,
|
|
29
|
-
}
|
|
30
|
-
TableAction.displayName = 'TableAction';
|
|
31
|
-
export default TableAction;
|
|
25
|
+
placement: placement,
|
|
26
|
+
trigger: trigger
|
|
27
|
+
}, /*#__PURE__*/React.createElement("a", null, "\u66F4\u591A")));
|
|
28
|
+
}
|
package/package.json
CHANGED
package/tools/index.js
CHANGED
|
@@ -71,7 +71,7 @@ export function isHttpUrl(v) {
|
|
|
71
71
|
* @return {string}
|
|
72
72
|
*/
|
|
73
73
|
export function getPrefixCls() {
|
|
74
|
-
return process?.env?.app?.antd['ant-prefix'] || 'ant';
|
|
74
|
+
return window.process?.env?.app?.antd['ant-prefix'] || 'ant';
|
|
75
75
|
}
|
|
76
76
|
export function getAlgorithm() {
|
|
77
77
|
const value = document.documentElement.style.getPropertyValue(
|
package/Layout/README.md
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
页面布局组件
|
|
2
|
-
|
|
3
|
-
## 代码演示
|
|
4
|
-
|
|
5
|
-
```jsx
|
|
6
|
-
import { useState } from 'react';
|
|
7
|
-
import { Button } from 'antd';
|
|
8
|
-
import PageLayout from '@cqsjjb/jjb-react-admin-component/PageLayout';
|
|
9
|
-
|
|
10
|
-
function App() {
|
|
11
|
-
return (
|
|
12
|
-
<PageLayout title="用户中心">
|
|
13
|
-
|
|
14
|
-
</PageLayout>
|
|
15
|
-
)
|
|
16
|
-
}
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## API
|
|
20
|
-
|
|
21
|
-
| 属性 | 说明 | 类型 | 默认值 |
|
|
22
|
-
|-----------------|:-----------|:---------------:|------:|
|
|
23
|
-
| title | 页面标题 | `string` | - |
|
|
24
|
-
| extra | 右上角扩展 | `ReactNode` | - |
|
|
25
|
-
| header | 自定义头部 | `ReactNode` | - |
|
|
26
|
-
| footer | 自定义底部 | `ReactNode` | - |
|
|
27
|
-
| history | 路由历史对象 | `History` | - |
|
|
28
|
-
| noStyle | 去除所有样式 | `boolean` | false |
|
|
29
|
-
| noBorder | 取消边框 | `boolean` | false |
|
|
30
|
-
| formLine | form 表单行 | `ReactNode[]` | - |
|
|
31
|
-
| formLineStyle | form 表单行样式 | `CSSProperties` | - |
|
|
32
|
-
| previous | 显示返回上一页 | `boolean` | false |
|
|
33
|
-
| transparent | 背景透明 | `boolean` | false |
|
|
34
|
-
| contentStyle | 内容区样式 | `CSSProperties` | - |
|
|
35
|
-
| footerStyle | 底部样式 | `CSSProperties` | - |
|
|
36
|
-
| pageHeaderStyle | 头部样式 | `CSSProperties` | - |
|
|
37
|
-
| style | 自定义返回事件 | `CSSProperties` | - |
|
|
38
|
-
| onBack | 容器样式 | `() => void` | - |
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
注意:`previous`为`true`时`history`必传,否则点击返回无效。
|
package/Layout/index.d.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* LayoutHeader 组件属性
|
|
5
|
-
*/
|
|
6
|
-
export interface LayoutHeaderProps {
|
|
7
|
-
/** 自定义样式 */
|
|
8
|
-
style?: React.CSSProperties;
|
|
9
|
-
/** 标题文本 */
|
|
10
|
-
title?: React.ReactNode;
|
|
11
|
-
/** 右侧额外内容 */
|
|
12
|
-
extra?: React.ReactNode;
|
|
13
|
-
/** 是否显示返回按钮 */
|
|
14
|
-
previous?: boolean;
|
|
15
|
-
/** 头部下方内容 */
|
|
16
|
-
content?: React.ReactNode;
|
|
17
|
-
/** 自定义类名 */
|
|
18
|
-
className?: string;
|
|
19
|
-
/** 内容区域样式 */
|
|
20
|
-
contentStyle?: React.CSSProperties;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* LayoutBlock 组件属性
|
|
25
|
-
*/
|
|
26
|
-
export interface LayoutBlockProps {
|
|
27
|
-
/** 标题文本 */
|
|
28
|
-
title?: React.ReactNode;
|
|
29
|
-
/** 描述文本 */
|
|
30
|
-
description?: React.ReactNode;
|
|
31
|
-
/** 右侧额外内容 */
|
|
32
|
-
extra?: React.ReactNode;
|
|
33
|
-
/** 内容区域 */
|
|
34
|
-
content?: React.ReactNode;
|
|
35
|
-
/** 自定义样式 */
|
|
36
|
-
style?: React.CSSProperties;
|
|
37
|
-
/** 自定义类名 */
|
|
38
|
-
className?: string;
|
|
39
|
-
/** 内容区域样式 */
|
|
40
|
-
contentStyle?: React.CSSProperties;
|
|
41
|
-
/** 头部区域样式 */
|
|
42
|
-
headerStyle?: React.CSSProperties;
|
|
43
|
-
/** 头部区域类名 */
|
|
44
|
-
headerClassName?: string;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Layout 组件属性
|
|
49
|
-
*/
|
|
50
|
-
export interface LayoutProps {
|
|
51
|
-
/** 自定义样式 */
|
|
52
|
-
style?: React.CSSProperties;
|
|
53
|
-
/** 数据节点ID */
|
|
54
|
-
'data-node-id'?: string;
|
|
55
|
-
/** 子元素 */
|
|
56
|
-
children?: React.ReactNode;
|
|
57
|
-
/** 自定义类名 */
|
|
58
|
-
className?: string;
|
|
59
|
-
/** 内容区域样式 */
|
|
60
|
-
contentStyle?: React.CSSProperties;
|
|
61
|
-
/** 内容区域类名 */
|
|
62
|
-
contentClassName?: string;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* 布局头部组件
|
|
67
|
-
*/
|
|
68
|
-
export const LayoutHeader: React.FC<LayoutHeaderProps>;
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* 布局块组件
|
|
72
|
-
*/
|
|
73
|
-
export const LayoutBlock: React.FC<LayoutBlockProps>;
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* 布局容器组件
|
|
77
|
-
*/
|
|
78
|
-
declare const Layout: React.FC<LayoutProps>;
|
|
79
|
-
|
|
80
|
-
export default Layout;
|
|
81
|
-
|