@cqsjjb/jjb-react-admin-component 3.3.1-beta.4 → 3.3.1-beta.6
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/package.json +1 -1
- package/AMap/index.js +0 -372
- package/AdaptiveTree/index.js +0 -184
- package/BMap/index.js +0 -167
- package/ControlWrapper/index.js +0 -65
- package/ControlWrapper/index.less +0 -38
- package/Editor/index.js +0 -310
- package/ErrorBoundary/index.js +0 -35
- package/FileUploader/index.js +0 -312
- package/FormilyDescriptions/index.js +0 -313
- package/FormilyRenderer/index.js +0 -58
- package/ImageCropper/index.js +0 -116
- package/ImageUploader/index.js +0 -310
- package/ListDataContainer/index.js +0 -211
- package/MediaQuery/index.js +0 -42
- package/PageLayout/index.js +0 -60
- package/SearchForm/index.js +0 -95
- package/Table/index.js +0 -118
- package/TableAction/index.js +0 -30
package/BMap/index.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useRef, useState, useCallback } from 'react';
|
|
2
|
-
import { Button, Col, message, Modal, Result, Row } from 'antd';
|
|
3
|
-
import './index.less';
|
|
4
|
-
const _B_MAP_SEARCH_ = '_B_MAP_SEARCH_';
|
|
5
|
-
const _B_MAP_DEFAULT_POINT_ = {
|
|
6
|
-
lng: 116.404,
|
|
7
|
-
lat: 39.915
|
|
8
|
-
};
|
|
9
|
-
const BMap = ({
|
|
10
|
-
lng: propLng,
|
|
11
|
-
lat: propLat,
|
|
12
|
-
title = '百度地图',
|
|
13
|
-
width = 700,
|
|
14
|
-
onOk,
|
|
15
|
-
onCancel
|
|
16
|
-
}) => {
|
|
17
|
-
const [lng, setLng] = useState(_B_MAP_DEFAULT_POINT_.lng);
|
|
18
|
-
const [lat, setLat] = useState(_B_MAP_DEFAULT_POINT_.lat);
|
|
19
|
-
const GL = useRef(null);
|
|
20
|
-
const mapRef = useRef(null);
|
|
21
|
-
|
|
22
|
-
/** 初始化地图 */
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
if (typeof window.BMapGL === 'undefined') {
|
|
25
|
-
message.error('未导入百度地图文件,生成地图失败!').then(() => null);
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
const initLng = propLng || _B_MAP_DEFAULT_POINT_.lng;
|
|
29
|
-
const initLat = propLat || _B_MAP_DEFAULT_POINT_.lat;
|
|
30
|
-
setLng(initLng);
|
|
31
|
-
setLat(initLat);
|
|
32
|
-
const point = new window.BMapGL.Point(initLng, initLat);
|
|
33
|
-
const map = new window.BMapGL.Map(GL.current);
|
|
34
|
-
mapRef.current = map;
|
|
35
|
-
map.centerAndZoom(point, 18);
|
|
36
|
-
map.enableScrollWheelZoom(true);
|
|
37
|
-
map.addControl(new window.BMapGL.ScaleControl());
|
|
38
|
-
map.addControl(new window.BMapGL.ZoomControl());
|
|
39
|
-
map.addControl(new window.BMapGL.NavigationControl3D());
|
|
40
|
-
map.addControl(new window.BMapGL.CityListControl({
|
|
41
|
-
anchor: window.BMAP_ANCHOR_TOP_LEFT,
|
|
42
|
-
offset: new window.BMapGL.Size(10, 10),
|
|
43
|
-
onChangeSuccess: e => {
|
|
44
|
-
map.clearOverlays();
|
|
45
|
-
setLng(e.point.lng);
|
|
46
|
-
setLat(e.point.lat);
|
|
47
|
-
const p = new window.BMapGL.Point(e.point.lng, e.point.lat);
|
|
48
|
-
const marker = new window.BMapGL.Marker(p);
|
|
49
|
-
map.addOverlay(marker);
|
|
50
|
-
}
|
|
51
|
-
}));
|
|
52
|
-
const locationControl = new window.BMapGL.LocationControl({
|
|
53
|
-
anchor: window.BMAP_ANCHOR_BOTTOM_LEFT,
|
|
54
|
-
offset: new window.BMapGL.Size(20, 20)
|
|
55
|
-
});
|
|
56
|
-
locationControl.addEventListener('locationError', () => message.error('未知原因,定位失败!'));
|
|
57
|
-
map.addControl(locationControl);
|
|
58
|
-
const marker = new window.BMapGL.Marker(point);
|
|
59
|
-
map.addOverlay(marker);
|
|
60
|
-
map.addEventListener('click', e => {
|
|
61
|
-
map.clearOverlays();
|
|
62
|
-
setLng(e.latlng.lng);
|
|
63
|
-
setLat(e.latlng.lat);
|
|
64
|
-
const p = new window.BMapGL.Point(e.latlng.lng, e.latlng.lat);
|
|
65
|
-
const marker = new window.BMapGL.Marker(p);
|
|
66
|
-
map.addOverlay(marker);
|
|
67
|
-
});
|
|
68
|
-
setTimeout(() => {
|
|
69
|
-
const autoComplete = new window.BMapGL.Autocomplete({
|
|
70
|
-
input: _B_MAP_SEARCH_,
|
|
71
|
-
location: map
|
|
72
|
-
});
|
|
73
|
-
let myValue;
|
|
74
|
-
autoComplete.addEventListener('onconfirm', e => {
|
|
75
|
-
const value = e.item.value;
|
|
76
|
-
myValue = value.province + value.city + value.district + value.street + value.business;
|
|
77
|
-
setPlace();
|
|
78
|
-
});
|
|
79
|
-
function setPlace() {
|
|
80
|
-
const local = new window.BMapGL.LocalSearch(map, {
|
|
81
|
-
onSearchComplete: myFun
|
|
82
|
-
});
|
|
83
|
-
map.clearOverlays();
|
|
84
|
-
function myFun() {
|
|
85
|
-
const pp = local.getResults().getPoi(0).point;
|
|
86
|
-
setLng(pp.lng);
|
|
87
|
-
setLat(pp.lat);
|
|
88
|
-
map.centerAndZoom(pp, 18);
|
|
89
|
-
map.addOverlay(new window.BMapGL.Marker(pp));
|
|
90
|
-
}
|
|
91
|
-
local.search(myValue);
|
|
92
|
-
}
|
|
93
|
-
}, 500);
|
|
94
|
-
}, [propLng, propLat]);
|
|
95
|
-
|
|
96
|
-
/** 重置地图 */
|
|
97
|
-
const onResetMap = useCallback(() => {
|
|
98
|
-
if (!mapRef.current) return;
|
|
99
|
-
const map = mapRef.current;
|
|
100
|
-
map.clearOverlays();
|
|
101
|
-
setLng(_B_MAP_DEFAULT_POINT_.lng);
|
|
102
|
-
setLat(_B_MAP_DEFAULT_POINT_.lat);
|
|
103
|
-
const point = new window.BMapGL.Point(_B_MAP_DEFAULT_POINT_.lng, _B_MAP_DEFAULT_POINT_.lat);
|
|
104
|
-
const marker = new window.BMapGL.Marker(point);
|
|
105
|
-
map.centerAndZoom(_B_MAP_DEFAULT_POINT_, 18);
|
|
106
|
-
map.addOverlay(marker);
|
|
107
|
-
}, []);
|
|
108
|
-
|
|
109
|
-
/** 确认操作 */
|
|
110
|
-
const handleOk = useCallback(() => {
|
|
111
|
-
const map = mapRef.current;
|
|
112
|
-
if (!map) return;
|
|
113
|
-
const point = new window.BMapGL.Point(lng, lat);
|
|
114
|
-
const geocoder = new window.BMapGL.Geocoder();
|
|
115
|
-
geocoder.getLocation(point, (rs = {}) => {
|
|
116
|
-
const comp = rs?.addressComponents;
|
|
117
|
-
onOk && onOk({
|
|
118
|
-
lng,
|
|
119
|
-
lat,
|
|
120
|
-
comp,
|
|
121
|
-
compText: comp && [comp.province, comp.city, comp.district, comp.street, comp.streetNumber].join('') || undefined
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
}, [lng, lat, onOk]);
|
|
125
|
-
const hasMapScript = typeof window.BMapGL !== 'undefined';
|
|
126
|
-
return /*#__PURE__*/React.createElement(Modal, {
|
|
127
|
-
open: true,
|
|
128
|
-
destroyOnClose: true,
|
|
129
|
-
title: title,
|
|
130
|
-
width: width,
|
|
131
|
-
footer: hasMapScript && /*#__PURE__*/React.createElement(Row, {
|
|
132
|
-
align: "middle",
|
|
133
|
-
justify: "space-between"
|
|
134
|
-
}, /*#__PURE__*/React.createElement(Col, null, "\u5F53\u524D\u5750\u6807\uFF1A", [lng, lat].join('-')), /*#__PURE__*/React.createElement(Col, null, /*#__PURE__*/React.createElement(Button, {
|
|
135
|
-
ghost: true,
|
|
136
|
-
type: "primary",
|
|
137
|
-
style: {
|
|
138
|
-
marginRight: 12
|
|
139
|
-
},
|
|
140
|
-
onClick: onResetMap
|
|
141
|
-
}, "\u91CD\u7F6E\u5730\u56FE"), /*#__PURE__*/React.createElement(Button, {
|
|
142
|
-
type: "primary",
|
|
143
|
-
onClick: handleOk
|
|
144
|
-
}, "\u786E\u8BA4\u5750\u6807"))),
|
|
145
|
-
maskClosable: false,
|
|
146
|
-
onCancel: () => onCancel && onCancel()
|
|
147
|
-
}, hasMapScript ? /*#__PURE__*/React.createElement("div", {
|
|
148
|
-
style: {
|
|
149
|
-
position: 'relative'
|
|
150
|
-
}
|
|
151
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
152
|
-
ref: GL,
|
|
153
|
-
style: {
|
|
154
|
-
height: 500,
|
|
155
|
-
userSelect: 'none'
|
|
156
|
-
}
|
|
157
|
-
}), /*#__PURE__*/React.createElement("input", {
|
|
158
|
-
id: _B_MAP_SEARCH_,
|
|
159
|
-
type: "text",
|
|
160
|
-
maxLength: 30,
|
|
161
|
-
placeholder: "\u8BF7\u8F93\u5165\u5173\u952E\u5B57\u67E5\u8BE2"
|
|
162
|
-
})) : /*#__PURE__*/React.createElement(Result, {
|
|
163
|
-
status: "error",
|
|
164
|
-
title: "\u52A0\u8F7D\u5730\u56FE\u5931\u8D25\uFF0C\u7F3A\u5C11\u5FC5\u8981\u7684\u6587\u4EF6\uFF01"
|
|
165
|
-
}));
|
|
166
|
-
};
|
|
167
|
-
export default BMap;
|
package/ControlWrapper/index.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
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 React from 'react';
|
|
3
|
-
import { Input as OriginInput, Select as OriginSelect, Cascader as OriginCascader, DatePicker as OriginDatePicker, TreeSelect as OriginTreeSelect } from 'antd';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 通用包裹组件
|
|
7
|
-
* @param {*} WrappedComponent antd 原生组件
|
|
8
|
-
* @param {*} extraProps 额外的透传配置
|
|
9
|
-
*/
|
|
10
|
-
function withLabel(WrappedComponent, extraProps = {}) {
|
|
11
|
-
return function Wrapper(props) {
|
|
12
|
-
const {
|
|
13
|
-
label,
|
|
14
|
-
onChange,
|
|
15
|
-
...restProps
|
|
16
|
-
} = props;
|
|
17
|
-
const handleChange = (val, ...args) => {
|
|
18
|
-
if (onChange) {
|
|
19
|
-
// 统一处理空字符串 -> undefined
|
|
20
|
-
onChange(val === '' ? undefined : val, ...args);
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
return /*#__PURE__*/React.createElement(WrappedComponent, _extends({
|
|
24
|
-
style: {
|
|
25
|
-
width: '100%'
|
|
26
|
-
},
|
|
27
|
-
prefix: label
|
|
28
|
-
}, extraProps, restProps, {
|
|
29
|
-
onChange: handleChange
|
|
30
|
-
}));
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// ============ 输入类 ============
|
|
35
|
-
const Input = withLabel(OriginInput);
|
|
36
|
-
|
|
37
|
-
// ============ 选择类 ============
|
|
38
|
-
const Select = withLabel(OriginSelect, {
|
|
39
|
-
maxTagCount: 3
|
|
40
|
-
});
|
|
41
|
-
const Cascader = withLabel(OriginCascader, {
|
|
42
|
-
maxTagCount: 3
|
|
43
|
-
});
|
|
44
|
-
const TreeSelect = withLabel(OriginTreeSelect, {
|
|
45
|
-
showSearch: true,
|
|
46
|
-
allowClear: true,
|
|
47
|
-
showCheckedStrategy: OriginTreeSelect.SHOW_PARENT,
|
|
48
|
-
treeNodeFilterProp: 'title'
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
// ============ 日期类 ============
|
|
52
|
-
const DatePicker = withLabel(OriginDatePicker);
|
|
53
|
-
DatePicker.RangePicker = withLabel(OriginDatePicker.RangePicker);
|
|
54
|
-
DatePicker.TimePicker = withLabel(OriginDatePicker.TimePicker);
|
|
55
|
-
DatePicker.WeekPicker = withLabel(OriginDatePicker.WeekPicker);
|
|
56
|
-
DatePicker.MonthPicker = withLabel(OriginDatePicker.MonthPicker);
|
|
57
|
-
DatePicker.QuarterPicker = withLabel(OriginDatePicker.QuarterPicker);
|
|
58
|
-
DatePicker.YearPicker = withLabel(OriginDatePicker.YearPicker);
|
|
59
|
-
export default {
|
|
60
|
-
Input,
|
|
61
|
-
Select,
|
|
62
|
-
Cascader,
|
|
63
|
-
TreeSelect,
|
|
64
|
-
DatePicker
|
|
65
|
-
};
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
@com-prefix-cls: if(isdefined(@ant-prefix), @ant-prefix, ant);
|
|
2
|
-
|
|
3
|
-
.@{com-prefix-cls}-form-item-control-label-wrapper {
|
|
4
|
-
.@{com-prefix-cls}-form-item-control-label-span {
|
|
5
|
-
border: 1px solid #d9d9d9;
|
|
6
|
-
height: 32px;
|
|
7
|
-
line-height: 30px;
|
|
8
|
-
box-sizing: border-box;
|
|
9
|
-
margin-right: -1px;
|
|
10
|
-
padding: 0 2px 0 8px;
|
|
11
|
-
border-top-left-radius: 4px;
|
|
12
|
-
border-bottom-left-radius: 4px;
|
|
13
|
-
white-space: nowrap;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
&.@{com-prefix-cls}-form-item-control-label-has {
|
|
17
|
-
.@{com-prefix-cls}-select-selector, .@{com-prefix-cls}-picker, .@{com-prefix-cls}-input, .@{com-prefix-cls}-input-affix-wrapper {
|
|
18
|
-
border-top-left-radius: 0;
|
|
19
|
-
border-bottom-left-radius: 0;
|
|
20
|
-
border-left-color: transparent !important;
|
|
21
|
-
&:hover, &:focus, &:focus-within{
|
|
22
|
-
border-left-color: @colorPrimary !important;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
&-default {
|
|
28
|
-
.@{com-prefix-cls}-form-item-control-label-span {
|
|
29
|
-
border-color: #d9d9d9;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
&-dark {
|
|
34
|
-
.@{com-prefix-cls}-form-item-control-label-span {
|
|
35
|
-
border-color: #424242;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
package/Editor/index.js
DELETED
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
import '@wangeditor-next/editor/dist/css/style.css';
|
|
2
|
-
import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef } from 'react';
|
|
3
|
-
import { message } from 'antd';
|
|
4
|
-
import { http, tools } from '@cqsjjb/jjb-common-lib';
|
|
5
|
-
import { createEditor, createToolbar } from '@wangeditor-next/editor';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* 工具函数:标准化 HTML 内容为空值
|
|
9
|
-
*/
|
|
10
|
-
function normalizeEmptyHtml(html) {
|
|
11
|
-
if (!html) return '';
|
|
12
|
-
const cleaned = html.replace(/\s+/g, '').toLowerCase();
|
|
13
|
-
return cleaned === '<p><br></p>' || cleaned === '<p></p>' || cleaned === '' ? '' : html;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 校验上传文件类型和大小
|
|
18
|
-
*/
|
|
19
|
-
function validateFile(file, {
|
|
20
|
-
validTypes,
|
|
21
|
-
validExts,
|
|
22
|
-
maxSize,
|
|
23
|
-
typeName
|
|
24
|
-
}) {
|
|
25
|
-
const ext = file.name.split('.').pop().toLowerCase();
|
|
26
|
-
if (!validTypes.includes(file.type) && !validExts.includes(ext)) {
|
|
27
|
-
message.error(`只能上传${typeName}文件(${validExts.join(', ')})`);
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
if (file.size > maxSize) {
|
|
31
|
-
message.error(`${typeName}大小不能超过 ${maxSize / 1024 / 1024}MB`);
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
return true;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* 通用上传函数
|
|
39
|
-
*/
|
|
40
|
-
async function handleUpload(file, insertFn, options) {
|
|
41
|
-
const {
|
|
42
|
-
typeName,
|
|
43
|
-
validTypes,
|
|
44
|
-
validExts,
|
|
45
|
-
maxSize,
|
|
46
|
-
uploadServer,
|
|
47
|
-
uploadFileName,
|
|
48
|
-
uploadHeaders,
|
|
49
|
-
application,
|
|
50
|
-
uploadCustomRequest
|
|
51
|
-
} = options;
|
|
52
|
-
try {
|
|
53
|
-
if (!validateFile(file, {
|
|
54
|
-
validTypes,
|
|
55
|
-
validExts,
|
|
56
|
-
maxSize,
|
|
57
|
-
typeName
|
|
58
|
-
})) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// 自定义上传
|
|
63
|
-
if (typeof uploadCustomRequest === 'function') {
|
|
64
|
-
const url = await uploadCustomRequest(file);
|
|
65
|
-
insertFn(url, file.name);
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// 默认上传
|
|
70
|
-
const formData = new FormData();
|
|
71
|
-
formData.append(uploadFileName, file);
|
|
72
|
-
const resp = await fetch(uploadServer, {
|
|
73
|
-
method: 'POST',
|
|
74
|
-
headers: {
|
|
75
|
-
...uploadHeaders,
|
|
76
|
-
...(application ? {
|
|
77
|
-
tenantCode: application.tenantCode
|
|
78
|
-
} : {})
|
|
79
|
-
},
|
|
80
|
-
body: formData
|
|
81
|
-
});
|
|
82
|
-
const res = await resp.json();
|
|
83
|
-
if (res?.data?.fileUrl) {
|
|
84
|
-
insertFn(res.data.fileUrl, file.name);
|
|
85
|
-
} else if (Array.isArray(res?.data)) {
|
|
86
|
-
res.data.forEach(url => insertFn(url, file.name));
|
|
87
|
-
} else {
|
|
88
|
-
message.error(res?.respDesc || `${typeName}上传失败`);
|
|
89
|
-
}
|
|
90
|
-
} catch (e) {
|
|
91
|
-
console.error(e);
|
|
92
|
-
message.error(`${typeName}上传失败`);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
const RCEditor = /*#__PURE__*/forwardRef(function RCEditor(props, ref) {
|
|
96
|
-
const {
|
|
97
|
-
value,
|
|
98
|
-
bordered = true,
|
|
99
|
-
mode = 'default',
|
|
100
|
-
height = 300,
|
|
101
|
-
disabled = false,
|
|
102
|
-
zIndex = 1000,
|
|
103
|
-
uploadUrl = `${window.process.env.app.API_HOST}/attachment/files/upload-speed-simple`,
|
|
104
|
-
uploadFileName = 'file',
|
|
105
|
-
uploadHeaders = {},
|
|
106
|
-
uploadCustomRequest,
|
|
107
|
-
placeholder = '请输入...',
|
|
108
|
-
uploadImageFileSize = 5 * 1024 * 1024,
|
|
109
|
-
uploadVideoFileSize = 50 * 1024 * 1024,
|
|
110
|
-
borderStyle = 'solid',
|
|
111
|
-
borderColor = '#e8e8e8',
|
|
112
|
-
borderWidth = 1,
|
|
113
|
-
borderRadius = 2,
|
|
114
|
-
onBlur = tools.noop,
|
|
115
|
-
onFocus = tools.noop,
|
|
116
|
-
onChange = tools.noop
|
|
117
|
-
} = props;
|
|
118
|
-
|
|
119
|
-
// 编辑器
|
|
120
|
-
const editorRef = useRef(null);
|
|
121
|
-
// 工具栏
|
|
122
|
-
const toolbarRef = useRef(null);
|
|
123
|
-
// 编辑器实例
|
|
124
|
-
const editorInstanceRef = useRef(null);
|
|
125
|
-
// 最后一次的html
|
|
126
|
-
const lastHtmlRef = useRef('');
|
|
127
|
-
// 是否是第一次聚焦
|
|
128
|
-
const isFirstFocusRef = useRef(true);
|
|
129
|
-
// 应用配置
|
|
130
|
-
const appConfig = tools.toObject(window.process?.env?.app);
|
|
131
|
-
|
|
132
|
-
// 上传地址
|
|
133
|
-
const uploadServer = useMemo(() => {
|
|
134
|
-
if (!appConfig) return uploadUrl;
|
|
135
|
-
return http.HTTP_URL_REG.test(uploadUrl) ? uploadUrl : `${appConfig.API_HOST}${uploadUrl}`;
|
|
136
|
-
}, [appConfig, uploadUrl]);
|
|
137
|
-
|
|
138
|
-
// 初始化编辑器
|
|
139
|
-
useEffect(() => {
|
|
140
|
-
if (!editorRef.current) return;
|
|
141
|
-
const editor = createEditor({
|
|
142
|
-
selector: editorRef.current,
|
|
143
|
-
config: {
|
|
144
|
-
placeholder,
|
|
145
|
-
readOnly: disabled,
|
|
146
|
-
onChange(editor) {
|
|
147
|
-
// 获取html
|
|
148
|
-
let html = editor.getHtml();
|
|
149
|
-
// 标准化html
|
|
150
|
-
html = normalizeEmptyHtml(html);
|
|
151
|
-
// 存储最后一次的html
|
|
152
|
-
lastHtmlRef.current = html;
|
|
153
|
-
|
|
154
|
-
// 如果不是第一次聚焦,并且有onChange函数,则调用onChange函数
|
|
155
|
-
if (!isFirstFocusRef.current && tools.isFunction(onChange)) {
|
|
156
|
-
onChange(html);
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
onFocus: () => {
|
|
160
|
-
// 如果是第一次聚焦,则设置为不是第一次聚焦
|
|
161
|
-
if (isFirstFocusRef.current) {
|
|
162
|
-
isFirstFocusRef.current = false;
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
// 调用onFocus函数
|
|
166
|
-
tools.isFunction(onFocus) && onFocus();
|
|
167
|
-
},
|
|
168
|
-
onBlur: () => tools.isFunction(onBlur) && onBlur(),
|
|
169
|
-
// 菜单配置
|
|
170
|
-
MENU_CONF: {
|
|
171
|
-
uploadImage: {
|
|
172
|
-
server: uploadServer,
|
|
173
|
-
fieldName: uploadFileName,
|
|
174
|
-
maxFileSize: uploadImageFileSize,
|
|
175
|
-
headers: {
|
|
176
|
-
...uploadHeaders,
|
|
177
|
-
...(appConfig ? {
|
|
178
|
-
tenantCode: appConfig.tenantCode
|
|
179
|
-
} : {})
|
|
180
|
-
},
|
|
181
|
-
timeout: 60000,
|
|
182
|
-
customUpload: async (file, insertFn) => {
|
|
183
|
-
await handleUpload(file, insertFn, {
|
|
184
|
-
typeName: '图片',
|
|
185
|
-
validTypes: ['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/webp'],
|
|
186
|
-
validExts: ['png', 'jpg', 'jpeg', 'gif', 'webp'],
|
|
187
|
-
maxSize: uploadImageFileSize,
|
|
188
|
-
uploadServer,
|
|
189
|
-
uploadFileName,
|
|
190
|
-
uploadHeaders,
|
|
191
|
-
appConfig,
|
|
192
|
-
uploadCustomRequest
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
},
|
|
196
|
-
uploadVideo: {
|
|
197
|
-
server: uploadServer,
|
|
198
|
-
fieldName: uploadFileName,
|
|
199
|
-
maxFileSize: uploadVideoFileSize,
|
|
200
|
-
headers: {
|
|
201
|
-
...uploadHeaders,
|
|
202
|
-
...(appConfig ? {
|
|
203
|
-
tenantCode: appConfig.tenantCode
|
|
204
|
-
} : {})
|
|
205
|
-
},
|
|
206
|
-
timeout: 120000,
|
|
207
|
-
customUpload: async (file, insertFn) => {
|
|
208
|
-
await handleUpload(file, insertFn, {
|
|
209
|
-
typeName: '视频',
|
|
210
|
-
validTypes: ['video/mp4', 'video/webm', 'video/ogg', 'video/mkv'],
|
|
211
|
-
validExts: ['mp4', 'webm', 'ogg', 'mkv'],
|
|
212
|
-
maxSize: uploadVideoFileSize,
|
|
213
|
-
uploadServer,
|
|
214
|
-
uploadFileName,
|
|
215
|
-
uploadHeaders,
|
|
216
|
-
appConfig,
|
|
217
|
-
uploadCustomRequest
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
},
|
|
223
|
-
mode
|
|
224
|
-
});
|
|
225
|
-
createToolbar({
|
|
226
|
-
editor,
|
|
227
|
-
selector: toolbarRef.current,
|
|
228
|
-
config: {},
|
|
229
|
-
mode
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
// 初始化内容
|
|
233
|
-
const initialHtml = normalizeEmptyHtml(value || '');
|
|
234
|
-
// 设置html
|
|
235
|
-
editor.setHtml(initialHtml);
|
|
236
|
-
// 存储最后一次的html
|
|
237
|
-
lastHtmlRef.current = initialHtml;
|
|
238
|
-
// 禁用编辑器
|
|
239
|
-
if (disabled) editor.disable();
|
|
240
|
-
// 存储编辑器实例
|
|
241
|
-
editorInstanceRef.current = editor;
|
|
242
|
-
// 销毁编辑器
|
|
243
|
-
return () => {
|
|
244
|
-
try {
|
|
245
|
-
editor.destroy();
|
|
246
|
-
} catch (e) {}
|
|
247
|
-
editorInstanceRef.current = null;
|
|
248
|
-
};
|
|
249
|
-
}, []);
|
|
250
|
-
|
|
251
|
-
// 受控 value
|
|
252
|
-
useEffect(() => {
|
|
253
|
-
// 获取编辑器实例
|
|
254
|
-
const editor = editorInstanceRef.current;
|
|
255
|
-
if (!editor) return;
|
|
256
|
-
// 标准化html
|
|
257
|
-
const safeHtml = normalizeEmptyHtml(value || '');
|
|
258
|
-
if (safeHtml !== lastHtmlRef.current) {
|
|
259
|
-
editor.setHtml(safeHtml);
|
|
260
|
-
// 存储最后一次的html
|
|
261
|
-
lastHtmlRef.current = safeHtml;
|
|
262
|
-
}
|
|
263
|
-
}, [value]);
|
|
264
|
-
|
|
265
|
-
// disabled 切换
|
|
266
|
-
useEffect(() => {
|
|
267
|
-
const editor = editorInstanceRef.current;
|
|
268
|
-
if (!editor) return;
|
|
269
|
-
// 禁用编辑器
|
|
270
|
-
if (disabled) editor.disable();
|
|
271
|
-
// 启用编辑器
|
|
272
|
-
else editor.enable();
|
|
273
|
-
}, [disabled]);
|
|
274
|
-
// 暴露编辑器实例
|
|
275
|
-
useImperativeHandle(ref, () => ({
|
|
276
|
-
// 获取编辑器实例
|
|
277
|
-
getEditorInstance: () => editorInstanceRef.current,
|
|
278
|
-
// 获取html
|
|
279
|
-
getHtml: () => normalizeEmptyHtml(editorInstanceRef.current?.getHtml?.() || ''),
|
|
280
|
-
// 设置html
|
|
281
|
-
setHtml: html => {
|
|
282
|
-
if (!editorInstanceRef.current) return;
|
|
283
|
-
const safeHtml = normalizeEmptyHtml(html || '');
|
|
284
|
-
editorInstanceRef.current.setHtml(safeHtml);
|
|
285
|
-
lastHtmlRef.current = safeHtml;
|
|
286
|
-
},
|
|
287
|
-
// 获取纯文本
|
|
288
|
-
getPlainText: () => editorInstanceRef.current?.getText?.() || ''
|
|
289
|
-
}));
|
|
290
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
291
|
-
style: {
|
|
292
|
-
zIndex,
|
|
293
|
-
border: bordered ? `${borderWidth}px ${borderStyle} ${borderColor}` : 'none',
|
|
294
|
-
overflow: 'hidden',
|
|
295
|
-
borderRadius
|
|
296
|
-
}
|
|
297
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
298
|
-
ref: toolbarRef,
|
|
299
|
-
style: {
|
|
300
|
-
borderBottom: bordered ? `${borderWidth}px ${borderStyle} ${borderColor}` : 'none'
|
|
301
|
-
}
|
|
302
|
-
}), /*#__PURE__*/React.createElement("div", {
|
|
303
|
-
ref: editorRef,
|
|
304
|
-
style: {
|
|
305
|
-
height,
|
|
306
|
-
overflowY: 'auto'
|
|
307
|
-
}
|
|
308
|
-
}));
|
|
309
|
-
});
|
|
310
|
-
export default RCEditor;
|
package/ErrorBoundary/index.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Result } from 'antd';
|
|
3
|
-
export default class ErrorBoundary extends React.Component {
|
|
4
|
-
state = {
|
|
5
|
-
hasError: false,
|
|
6
|
-
errorInfo: '',
|
|
7
|
-
errorStack: undefined
|
|
8
|
-
};
|
|
9
|
-
componentDidCatch(error, info) {
|
|
10
|
-
this.setState({
|
|
11
|
-
hasError: true,
|
|
12
|
-
errorInfo: error.message,
|
|
13
|
-
errorStack: info.componentStack
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
render() {
|
|
17
|
-
if (this.state.hasError) {
|
|
18
|
-
return /*#__PURE__*/React.createElement(Result, {
|
|
19
|
-
status: "error",
|
|
20
|
-
title: "\u62B1\u6B49\uFF0C\u5E94\u7528\u5185\u90E8\u53D1\u751F\u5F02\u5E38\u9519\u8BEF\u3002",
|
|
21
|
-
subTitle: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", null, this.state.errorInfo), /*#__PURE__*/React.createElement("div", {
|
|
22
|
-
style: {
|
|
23
|
-
width: 700,
|
|
24
|
-
display: 'inline-block',
|
|
25
|
-
overflow: 'auto',
|
|
26
|
-
maxHeight: 400,
|
|
27
|
-
textAlign: 'left',
|
|
28
|
-
whiteSpace: 'pre-line'
|
|
29
|
-
}
|
|
30
|
-
}, this.state.errorStack))
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
return this.props.children;
|
|
34
|
-
}
|
|
35
|
-
}
|