@hzab/form-render 1.6.17 → 1.6.19
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/CHANGELOG.md +291 -283
- package/README.md +239 -239
- package/package.json +57 -57
- package/src/common/formily-utils.ts +125 -125
- package/src/common/schema-handler.ts +253 -253
- package/src/common/schema-merge.ts +68 -68
- package/src/components/ArrayBase/index.tsx +349 -349
- package/src/components/ArrayBase/style.less +90 -90
- package/src/components/ArrayBase/style.ts +2 -2
- package/src/components/ArrayCards/index.tsx +149 -149
- package/src/components/ArrayCards/style.less +14 -14
- package/src/components/ArrayCards/style.ts +4 -4
- package/src/components/ArrayTable/index.tsx +411 -411
- package/src/components/ArrayTable/style.less +52 -52
- package/src/components/ArrayTable/style.ts +7 -7
- package/src/components/DatePicker/index.tsx +108 -108
- package/src/components/LocationListPicker/assets/icon.js +1 -1
- package/src/components/LocationListPicker/components/AddrList/index.less +55 -55
- package/src/components/LocationListPicker/components/AddrList/index.tsx +75 -75
- package/src/components/LocationListPicker/components/Popup/address.schema.json +21 -21
- package/src/components/LocationListPicker/components/Popup/index.less +22 -22
- package/src/components/LocationListPicker/components/Popup/index.tsx +92 -92
- package/src/components/LocationListPicker/index.less +34 -34
- package/src/components/LocationListPicker/index.tsx +521 -520
- package/src/components/LocationPicker/Map/AMap/common/loader.ts +58 -58
- package/src/components/LocationPicker/Map/AMap/common/utils.ts +431 -431
- package/src/components/LocationPicker/Map/AMap/index.jsx +51 -51
- package/src/components/LocationPicker/README.md +44 -44
- package/src/components/LocationPicker/common/utils.ts +30 -30
- package/src/components/LocationPicker/components/ModalContent/index.tsx +387 -387
- package/src/components/LocationPicker/components/PickerInfo/index.tsx +109 -109
- package/src/components/LocationPicker/components/ResInfo/index.less +38 -38
- package/src/components/LocationPicker/components/ResInfo/index.tsx +65 -65
- package/src/components/LocationPicker/index.tsx +197 -197
- package/src/components/PersonnelSelect/index.less +21 -21
- package/src/components/PersonnelSelect/index.module.less +33 -33
- package/src/components/PersonnelSelect/index.tsx +305 -300
- package/src/components/PersonnelSelect/type.ts +92 -92
- package/src/components/RichEditor/index.less +38 -38
- package/src/components/RichEditor/index.tsx +238 -238
- package/src/components/TreeCheckbox/components/CheckboxTable/index.tsx +55 -55
- package/src/components/TreeCheckbox/components/TabsRender/index.tsx +58 -58
- package/src/components/TreeCheckbox/index.less +12 -12
- package/src/components/TreeCheckbox/index.tsx +63 -63
- package/src/components/Upload/README.md +64 -64
- package/src/components/Upload/common/OfflineUpload.ts +339 -339
- package/src/components/Upload/common/customRequest.ts +81 -81
- package/src/components/Upload/common/fileName.ts +142 -142
- package/src/components/Upload/common/handleIOFileList.ts +393 -393
- package/src/components/Upload/common/nanoid.ts +7 -7
- package/src/components/Upload/common/ossUpload.js +159 -159
- package/src/components/Upload/common/utils.js +194 -194
- package/src/components/Upload/components/ItemList/index.tsx +52 -52
- package/src/components/Upload/components/PreviewModal/previewRender.tsx +80 -80
- package/src/components/Upload/index.tsx +17 -17
- package/src/components/Upload/uploader-input.jsx +187 -187
- package/src/components/Upload/uploader.jsx +316 -316
- package/src/components/UserSelect/index.tsx +123 -123
- package/src/components/index.tsx +17 -17
- package/src/index.tsx +198 -198
|
@@ -1,387 +1,387 @@
|
|
|
1
|
-
import { useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
-
import { Spin, message } from "antd";
|
|
3
|
-
import { observer } from "@formily/react";
|
|
4
|
-
|
|
5
|
-
import PickerInfo from "../PickerInfo";
|
|
6
|
-
import AMapCom from "../../Map/AMap";
|
|
7
|
-
import Notice from "../Notice";
|
|
8
|
-
import MapSearch from "../MapSearch";
|
|
9
|
-
|
|
10
|
-
import { getCurrentPosition } from "../../../../common/location-utils";
|
|
11
|
-
import { MapUtils } from "../../Map/AMap/common/utils";
|
|
12
|
-
import { getAddress } from "../../servers";
|
|
13
|
-
import { getPropsValue } from "../../common/utils";
|
|
14
|
-
|
|
15
|
-
import { positionIcon as positionIconDef, resetIcon as resetIconDef } from "../../assets/svg-icon";
|
|
16
|
-
|
|
17
|
-
import "./index.less";
|
|
18
|
-
|
|
19
|
-
export const ModalContent = observer((props: any) => {
|
|
20
|
-
const {
|
|
21
|
-
mode,
|
|
22
|
-
element = "Polypoint",
|
|
23
|
-
/**
|
|
24
|
-
* 选择器和地图的布局
|
|
25
|
-
* 水平 输入框在前 hor
|
|
26
|
-
* 垂直 输入框在前 ver
|
|
27
|
-
* 水平 输入框在后 hor-reverse
|
|
28
|
-
* 垂直 输入框在后 ver-reverse
|
|
29
|
-
*/
|
|
30
|
-
layout = "ver",
|
|
31
|
-
// 是否允许搜索
|
|
32
|
-
hasSearch = true,
|
|
33
|
-
/**
|
|
34
|
-
* 打开地图时是否根据经纬度自动修正已填的地址
|
|
35
|
-
*/
|
|
36
|
-
isAutoFixAddr = false,
|
|
37
|
-
lonKey = "longitude",
|
|
38
|
-
latKey = "latitude",
|
|
39
|
-
addrKey = "address",
|
|
40
|
-
pointsKey = "points",
|
|
41
|
-
rangeKey = "range",
|
|
42
|
-
value,
|
|
43
|
-
// 搜索框是否自动搜索
|
|
44
|
-
isAutoSearch = true,
|
|
45
|
-
//
|
|
46
|
-
visible,
|
|
47
|
-
visibleKey,
|
|
48
|
-
defaultLocation = {},
|
|
49
|
-
disabled,
|
|
50
|
-
readOnly,
|
|
51
|
-
icons,
|
|
52
|
-
markerIconConf,
|
|
53
|
-
getCurPositionConf,
|
|
54
|
-
init,
|
|
55
|
-
} = props;
|
|
56
|
-
|
|
57
|
-
const mapUtilsRef = useRef<MapUtils>();
|
|
58
|
-
|
|
59
|
-
// 数据格式转为内部格式,方便存取
|
|
60
|
-
const formatVal = useMemo(
|
|
61
|
-
() =>
|
|
62
|
-
getPropsValue(value, {
|
|
63
|
-
lonKey,
|
|
64
|
-
latKey,
|
|
65
|
-
addrKey,
|
|
66
|
-
pointsKey,
|
|
67
|
-
rangeKey
|
|
68
|
-
}),
|
|
69
|
-
[lonKey, latKey, addrKey, pointsKey,rangeKey, value, value?.[rangeKey], value?.[pointsKey], value?.[lonKey], value?.[latKey], value?.[addrKey]],
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
const [loading, setLoading] = useState(props.loading || false);
|
|
73
|
-
const [addrLoading, setAddrLoading] = useState(false);
|
|
74
|
-
// 地图选点组件选中的值
|
|
75
|
-
const [pickInfo, setPickInfo] = useState(formatVal);
|
|
76
|
-
const pickerInfoRef = useRef(pickInfo);
|
|
77
|
-
const formatValRef = useRef(formatVal);
|
|
78
|
-
|
|
79
|
-
const isShowMode = mode === "show";
|
|
80
|
-
|
|
81
|
-
useEffect(() => {
|
|
82
|
-
setLoading(props.loading);
|
|
83
|
-
}, [props.loading]);
|
|
84
|
-
|
|
85
|
-
useEffect(() => {
|
|
86
|
-
if (isShowMode) {
|
|
87
|
-
// mode === 'show' 的情况
|
|
88
|
-
let _lon = formatVal.lon;
|
|
89
|
-
let _lat = formatVal.lat;
|
|
90
|
-
let _points = formatVal.points;
|
|
91
|
-
formatValRef.current = {
|
|
92
|
-
...formatVal,
|
|
93
|
-
};
|
|
94
|
-
if (_lon && _lat && _lon !== pickInfo.lon && _lat !== pickInfo.lat) {
|
|
95
|
-
// 解决关闭弹窗之后点位不居中的问题
|
|
96
|
-
if (window.AMap && window.AMap.LngLat) {
|
|
97
|
-
setMapCenter(_lon, _lat);
|
|
98
|
-
if (element === "Polypoint") {
|
|
99
|
-
setPickPoint(_lon, _lat, { isAutoFixAddr: false, addr: formatVal.addr });
|
|
100
|
-
} else {
|
|
101
|
-
setDrawEditor(_points || []);
|
|
102
|
-
}
|
|
103
|
-
} else {
|
|
104
|
-
// 解决刷新页面 AMap 未加载导致的异常问题
|
|
105
|
-
window._AMapLoaderTemp?.promise?.then(() => {
|
|
106
|
-
setMapCenter(_lon, _lat);
|
|
107
|
-
if (element === "Polypoint") {
|
|
108
|
-
setPickPoint(_lon, _lat, { isAutoFixAddr: false, addr: formatVal.addr });
|
|
109
|
-
} else {
|
|
110
|
-
setDrawEditor(_points || []);
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
} else if (visibleKey) {
|
|
116
|
-
// 处理弹窗展示数据回显逻辑
|
|
117
|
-
let _lon = defaultLocation.lon;
|
|
118
|
-
let _lat = defaultLocation.lat;
|
|
119
|
-
let _points = defaultLocation.points || [];
|
|
120
|
-
let addr = defaultLocation.addr;
|
|
121
|
-
if (formatVal.lon && formatVal.lat) {
|
|
122
|
-
_lon = formatVal.lon;
|
|
123
|
-
_lat = formatVal.lat;
|
|
124
|
-
addr = formatVal.addr;
|
|
125
|
-
}
|
|
126
|
-
// 解决关闭弹窗之后点位不居中的问题
|
|
127
|
-
if (window.AMap && window.AMap.LngLat) {
|
|
128
|
-
setMapCenter(_lon, _lat);
|
|
129
|
-
} else {
|
|
130
|
-
// 解决刷新页面 AMap 未加载导致的异常问题
|
|
131
|
-
window._AMapLoaderTemp?.promise?.then(() => {
|
|
132
|
-
setMapCenter(_lon, _lat);
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
if (_lon && _lat && _lon !== pickerInfoRef.current?.lon && _lat !== pickerInfoRef.current?.lat) {
|
|
136
|
-
if (element === "Polypoint") {
|
|
137
|
-
setPickPoint(_lon, _lat, { isAutoFixAddr: false, addr: addr });
|
|
138
|
-
} else {
|
|
139
|
-
setDrawEditor(_points || []);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
init({ editDone: onMapDbClick });
|
|
144
|
-
return () => {
|
|
145
|
-
// 取消监听
|
|
146
|
-
mapUtilsRef.current?.off("dblclick", onMapDbClick);
|
|
147
|
-
mapUtilsRef.current?.off("click", onClickMap);
|
|
148
|
-
};
|
|
149
|
-
}, []);
|
|
150
|
-
|
|
151
|
-
async function onMapDbClick() {
|
|
152
|
-
if (element !== "Polypoint") {
|
|
153
|
-
const graphical = mapUtilsRef.current.polyEditor[`${element}Editor`].getTarget();
|
|
154
|
-
if (graphical) {
|
|
155
|
-
const points = graphical.getPath().map((item) => [item.lng, item.lat]);
|
|
156
|
-
const center = mapUtilsRef.current.getPolygonCenter(points);
|
|
157
|
-
const addr = await getAddr(center[0], center[1]);
|
|
158
|
-
mapUtilsRef.current.polyEditor[`${element}Editor`].close();
|
|
159
|
-
mapUtilsRef.current.polyEditor[`${element}Editor`].setTarget();
|
|
160
|
-
props.setPickInfo &&
|
|
161
|
-
props.setPickInfo({
|
|
162
|
-
points,
|
|
163
|
-
addr,
|
|
164
|
-
lon: center[0],
|
|
165
|
-
lat: center[1],
|
|
166
|
-
});
|
|
167
|
-
setPickInfo({
|
|
168
|
-
points,
|
|
169
|
-
addr,
|
|
170
|
-
lon: center[0],
|
|
171
|
-
lat: center[1],
|
|
172
|
-
range: 0
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
function mapInit({ map, mapUtils }) {
|
|
179
|
-
mapUtilsRef.current = mapUtils;
|
|
180
|
-
mapUtilsRef.current.on("dblclick", onMapDbClick);
|
|
181
|
-
let _lon = defaultLocation.lon;
|
|
182
|
-
let _lat = defaultLocation.lat;
|
|
183
|
-
let _points = defaultLocation.points;
|
|
184
|
-
let _range = defaultLocation.range
|
|
185
|
-
if (pickInfo.lon && pickInfo.lat) {
|
|
186
|
-
_lon = pickInfo.lon;
|
|
187
|
-
_lat = pickInfo.lat;
|
|
188
|
-
_points = pickInfo.points;
|
|
189
|
-
_range = pickInfo.range
|
|
190
|
-
} else if (formatValRef.current?.lon && formatValRef.current?.lat) {
|
|
191
|
-
_lon = formatValRef.current?.lon;
|
|
192
|
-
_lat = formatValRef.current?.lat;
|
|
193
|
-
_points = formatValRef.current?.points;
|
|
194
|
-
_range = formatValRef.current?.range;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
setMapCenter(_lon, _lat);
|
|
198
|
-
|
|
199
|
-
setLoading(props.loading || false);
|
|
200
|
-
if (!(disabled || readOnly)) {
|
|
201
|
-
if (element === "Polypoint") {
|
|
202
|
-
mapUtilsRef.current?.setPickerMarker(_lon, _lat);
|
|
203
|
-
// 点击选中点位的情况
|
|
204
|
-
mapUtilsRef.current.on("click", onClickMap);
|
|
205
|
-
} else {
|
|
206
|
-
mapUtilsRef.current?.createPoly(element);
|
|
207
|
-
if (_points.length == 0) {
|
|
208
|
-
mapUtilsRef.current?.startPolygon({
|
|
209
|
-
onClick: onPolygonClick,
|
|
210
|
-
element,
|
|
211
|
-
});
|
|
212
|
-
mapUtilsRef.current.setDrawPolygon({ element });
|
|
213
|
-
}
|
|
214
|
-
setDrawEditor(_points);
|
|
215
|
-
}
|
|
216
|
-
} else {
|
|
217
|
-
// 禁用、只读情况使用 marker 展示点位
|
|
218
|
-
if (element === "Polypoint") {
|
|
219
|
-
mapUtilsRef.current?.setPickerMarker(_lon, _lat);
|
|
220
|
-
mapUtilsRef.current.setCircle(_lon, _lat, _range);
|
|
221
|
-
} else {
|
|
222
|
-
setDrawEditor(_points, true);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
function onClickMap(ev) {
|
|
228
|
-
const { lng: evLon, lat: evLat } = ev.lnglat || {};
|
|
229
|
-
if (element === "Polypoint") {
|
|
230
|
-
setPickPoint(evLon, evLat, { changeCenter: true });
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
function setDrawEditor(_points, disabled = false) {
|
|
235
|
-
if (!mapUtilsRef.current) {
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
mapUtilsRef.current?.createPoly(element);
|
|
239
|
-
if (_points && _points.length > 0) {
|
|
240
|
-
const graphical = mapUtilsRef.current?.setPolygon({
|
|
241
|
-
points: _points,
|
|
242
|
-
id: "setDrawEditor",
|
|
243
|
-
element,
|
|
244
|
-
onClick: !disabled && onPolygonClick,
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
function onPolygonClick(e) {
|
|
250
|
-
mapUtilsRef.current.setEditPolygon({ ...e.target, element });
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* 设置地图中心点
|
|
255
|
-
* @param lon
|
|
256
|
-
* @param lat
|
|
257
|
-
*/
|
|
258
|
-
function setMapCenter(lon = pickInfo.lon, lat = pickInfo.lat) {
|
|
259
|
-
lon && lat && mapUtilsRef.current?.setCenter(lon, lat);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
async function setPickPoint(_lon, _lat, opt?: any) {
|
|
263
|
-
const { isAutoFixAddr: _isAutoFixAddr = isAutoFixAddr || true, changeCenter, addr: _addr } = opt || {};
|
|
264
|
-
const lon = _lon || pickInfo.lon;
|
|
265
|
-
const lat = _lat || pickInfo.lat;
|
|
266
|
-
let addr = _addr;
|
|
267
|
-
mapUtilsRef.current?.setPickerMarker(_lon, _lat);
|
|
268
|
-
if (changeCenter) {
|
|
269
|
-
setMapCenter(_lon, _lat);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// 开启自动修复地址 且 opt 参数中没有地址,请求地址
|
|
273
|
-
if (_isAutoFixAddr && !addr) {
|
|
274
|
-
addr = await getAddr(lon, lat);
|
|
275
|
-
}
|
|
276
|
-
const res = { ...pickInfo, lon, lat, addr };
|
|
277
|
-
setPickInfo(res);
|
|
278
|
-
pickerInfoRef.current = res;
|
|
279
|
-
props.setPickInfo && props.setPickInfo(res);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
function getAddr(_lng, _lat) {
|
|
283
|
-
return new Promise((resolve, reject) => {
|
|
284
|
-
if (!window.AMap) {
|
|
285
|
-
reject();
|
|
286
|
-
return new Error("window.AMap is not defined");
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
setAddrLoading(true);
|
|
290
|
-
getAddress(_lng, _lat)
|
|
291
|
-
.then((addr) => {
|
|
292
|
-
setAddrLoading(false);
|
|
293
|
-
setPickInfo((_p) => {
|
|
294
|
-
pickerInfoRef.current = { ..._p, addr };
|
|
295
|
-
return pickerInfoRef.current;
|
|
296
|
-
});
|
|
297
|
-
resolve(addr);
|
|
298
|
-
})
|
|
299
|
-
.catch((err) => {
|
|
300
|
-
reject(err);
|
|
301
|
-
message.error(err);
|
|
302
|
-
setAddrLoading(false);
|
|
303
|
-
});
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
function resetCenter() {
|
|
308
|
-
setMapCenter();
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
function getPosition() {
|
|
312
|
-
setLoading(true);
|
|
313
|
-
// 获取当前经纬度
|
|
314
|
-
getCurrentPosition(getCurPositionConf)
|
|
315
|
-
.then((res) => {
|
|
316
|
-
const { coords = {} } = res;
|
|
317
|
-
setPickPoint(coords.longitude, coords.latitude, { changeCenter: true });
|
|
318
|
-
setLoading(false);
|
|
319
|
-
})
|
|
320
|
-
.catch((e) => {
|
|
321
|
-
setLoading(false);
|
|
322
|
-
message.error("定位获取失败");
|
|
323
|
-
console.warn("Error getCurrentPosition e: ", e);
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
// 展示获取当前定位按钮 props.showGetPositionBtn !== false 且非禁用、只读模式
|
|
328
|
-
const showGetPositionBtn = props.showGetPositionBtn !== false && !(disabled || readOnly);
|
|
329
|
-
|
|
330
|
-
const { markerIcon, positionIcon, resetIcon } = icons || {};
|
|
331
|
-
|
|
332
|
-
return (
|
|
333
|
-
<div className={`location-picker-modal-content location-mode-${mode} location-modal-content-layout-${layout}`}>
|
|
334
|
-
<PickerInfo
|
|
335
|
-
element={element}
|
|
336
|
-
pickInfo={pickInfo}
|
|
337
|
-
setPickInfo={setPickInfo}
|
|
338
|
-
setPoint={setPickPoint}
|
|
339
|
-
addrLoading={addrLoading}
|
|
340
|
-
defaultLocation={defaultLocation}
|
|
341
|
-
disabled={disabled}
|
|
342
|
-
readOnly={element !== "Polypoint" ? true : readOnly}
|
|
343
|
-
/>
|
|
344
|
-
<div className="location-picker-map-wrap">
|
|
345
|
-
<div className="location-picker-map">
|
|
346
|
-
{/* 关闭弹窗之后清除搜索内容 */}
|
|
347
|
-
{hasSearch && !disabled && !readOnly ? (
|
|
348
|
-
<MapSearch
|
|
349
|
-
key={visible}
|
|
350
|
-
setPoint={element !== "Polypoint" && (readOnly || disabled) ? setMapCenter : setPickPoint}
|
|
351
|
-
isAutoSearch={isAutoSearch}
|
|
352
|
-
/>
|
|
353
|
-
) : null}
|
|
354
|
-
<AMapCom init={mapInit} loading={loading} markerIconConf={markerIconConf} />
|
|
355
|
-
<div className="set-map-actions">
|
|
356
|
-
{/* 已选的点位居中 */}
|
|
357
|
-
<div className="actions-icon-box reset-icon-box" onClick={resetCenter}>
|
|
358
|
-
{typeof resetIcon === "string" ? (
|
|
359
|
-
<img className="reset-icon" src={resetIcon} />
|
|
360
|
-
) : (
|
|
361
|
-
resetIcon || resetIconDef
|
|
362
|
-
)}
|
|
363
|
-
</div>
|
|
364
|
-
{/* 获取当前经纬度 */}
|
|
365
|
-
{showGetPositionBtn && element === "Polypoint" ? (
|
|
366
|
-
<div className="actions-icon-box center-icon-box" onClick={getPosition}>
|
|
367
|
-
{typeof positionIcon === "string" ? (
|
|
368
|
-
<img className="center-icon" src={positionIcon} />
|
|
369
|
-
) : (
|
|
370
|
-
positionIcon || positionIconDef
|
|
371
|
-
)}
|
|
372
|
-
</div>
|
|
373
|
-
) : null}
|
|
374
|
-
</div>
|
|
375
|
-
</div>
|
|
376
|
-
{disabled || readOnly ? null : <Notice />}
|
|
377
|
-
</div>
|
|
378
|
-
{loading && (
|
|
379
|
-
<div className="spin-loading-wrap">
|
|
380
|
-
<Spin className="spin-loading" />
|
|
381
|
-
</div>
|
|
382
|
-
)}
|
|
383
|
-
</div>
|
|
384
|
-
);
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
export default ModalContent;
|
|
1
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { Spin, message } from "antd";
|
|
3
|
+
import { observer } from "@formily/react";
|
|
4
|
+
|
|
5
|
+
import PickerInfo from "../PickerInfo";
|
|
6
|
+
import AMapCom from "../../Map/AMap";
|
|
7
|
+
import Notice from "../Notice";
|
|
8
|
+
import MapSearch from "../MapSearch";
|
|
9
|
+
|
|
10
|
+
import { getCurrentPosition } from "../../../../common/location-utils";
|
|
11
|
+
import { MapUtils } from "../../Map/AMap/common/utils";
|
|
12
|
+
import { getAddress } from "../../servers";
|
|
13
|
+
import { getPropsValue } from "../../common/utils";
|
|
14
|
+
|
|
15
|
+
import { positionIcon as positionIconDef, resetIcon as resetIconDef } from "../../assets/svg-icon";
|
|
16
|
+
|
|
17
|
+
import "./index.less";
|
|
18
|
+
|
|
19
|
+
export const ModalContent = observer((props: any) => {
|
|
20
|
+
const {
|
|
21
|
+
mode,
|
|
22
|
+
element = "Polypoint",
|
|
23
|
+
/**
|
|
24
|
+
* 选择器和地图的布局
|
|
25
|
+
* 水平 输入框在前 hor
|
|
26
|
+
* 垂直 输入框在前 ver
|
|
27
|
+
* 水平 输入框在后 hor-reverse
|
|
28
|
+
* 垂直 输入框在后 ver-reverse
|
|
29
|
+
*/
|
|
30
|
+
layout = "ver",
|
|
31
|
+
// 是否允许搜索
|
|
32
|
+
hasSearch = true,
|
|
33
|
+
/**
|
|
34
|
+
* 打开地图时是否根据经纬度自动修正已填的地址
|
|
35
|
+
*/
|
|
36
|
+
isAutoFixAddr = false,
|
|
37
|
+
lonKey = "longitude",
|
|
38
|
+
latKey = "latitude",
|
|
39
|
+
addrKey = "address",
|
|
40
|
+
pointsKey = "points",
|
|
41
|
+
rangeKey = "range",
|
|
42
|
+
value,
|
|
43
|
+
// 搜索框是否自动搜索
|
|
44
|
+
isAutoSearch = true,
|
|
45
|
+
//
|
|
46
|
+
visible,
|
|
47
|
+
visibleKey,
|
|
48
|
+
defaultLocation = {},
|
|
49
|
+
disabled,
|
|
50
|
+
readOnly,
|
|
51
|
+
icons,
|
|
52
|
+
markerIconConf,
|
|
53
|
+
getCurPositionConf,
|
|
54
|
+
init,
|
|
55
|
+
} = props;
|
|
56
|
+
|
|
57
|
+
const mapUtilsRef = useRef<MapUtils>();
|
|
58
|
+
|
|
59
|
+
// 数据格式转为内部格式,方便存取
|
|
60
|
+
const formatVal = useMemo(
|
|
61
|
+
() =>
|
|
62
|
+
getPropsValue(value, {
|
|
63
|
+
lonKey,
|
|
64
|
+
latKey,
|
|
65
|
+
addrKey,
|
|
66
|
+
pointsKey,
|
|
67
|
+
rangeKey
|
|
68
|
+
}),
|
|
69
|
+
[lonKey, latKey, addrKey, pointsKey,rangeKey, value, value?.[rangeKey], value?.[pointsKey], value?.[lonKey], value?.[latKey], value?.[addrKey]],
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const [loading, setLoading] = useState(props.loading || false);
|
|
73
|
+
const [addrLoading, setAddrLoading] = useState(false);
|
|
74
|
+
// 地图选点组件选中的值
|
|
75
|
+
const [pickInfo, setPickInfo] = useState(formatVal);
|
|
76
|
+
const pickerInfoRef = useRef(pickInfo);
|
|
77
|
+
const formatValRef = useRef(formatVal);
|
|
78
|
+
|
|
79
|
+
const isShowMode = mode === "show";
|
|
80
|
+
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
setLoading(props.loading);
|
|
83
|
+
}, [props.loading]);
|
|
84
|
+
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
if (isShowMode) {
|
|
87
|
+
// mode === 'show' 的情况
|
|
88
|
+
let _lon = formatVal.lon;
|
|
89
|
+
let _lat = formatVal.lat;
|
|
90
|
+
let _points = formatVal.points;
|
|
91
|
+
formatValRef.current = {
|
|
92
|
+
...formatVal,
|
|
93
|
+
};
|
|
94
|
+
if (_lon && _lat && _lon !== pickInfo.lon && _lat !== pickInfo.lat) {
|
|
95
|
+
// 解决关闭弹窗之后点位不居中的问题
|
|
96
|
+
if (window.AMap && window.AMap.LngLat) {
|
|
97
|
+
setMapCenter(_lon, _lat);
|
|
98
|
+
if (element === "Polypoint") {
|
|
99
|
+
setPickPoint(_lon, _lat, { isAutoFixAddr: false, addr: formatVal.addr });
|
|
100
|
+
} else {
|
|
101
|
+
setDrawEditor(_points || []);
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
// 解决刷新页面 AMap 未加载导致的异常问题
|
|
105
|
+
window._AMapLoaderTemp?.promise?.then(() => {
|
|
106
|
+
setMapCenter(_lon, _lat);
|
|
107
|
+
if (element === "Polypoint") {
|
|
108
|
+
setPickPoint(_lon, _lat, { isAutoFixAddr: false, addr: formatVal.addr });
|
|
109
|
+
} else {
|
|
110
|
+
setDrawEditor(_points || []);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
} else if (visibleKey) {
|
|
116
|
+
// 处理弹窗展示数据回显逻辑
|
|
117
|
+
let _lon = defaultLocation.lon;
|
|
118
|
+
let _lat = defaultLocation.lat;
|
|
119
|
+
let _points = defaultLocation.points || [];
|
|
120
|
+
let addr = defaultLocation.addr;
|
|
121
|
+
if (formatVal.lon && formatVal.lat) {
|
|
122
|
+
_lon = formatVal.lon;
|
|
123
|
+
_lat = formatVal.lat;
|
|
124
|
+
addr = formatVal.addr;
|
|
125
|
+
}
|
|
126
|
+
// 解决关闭弹窗之后点位不居中的问题
|
|
127
|
+
if (window.AMap && window.AMap.LngLat) {
|
|
128
|
+
setMapCenter(_lon, _lat);
|
|
129
|
+
} else {
|
|
130
|
+
// 解决刷新页面 AMap 未加载导致的异常问题
|
|
131
|
+
window._AMapLoaderTemp?.promise?.then(() => {
|
|
132
|
+
setMapCenter(_lon, _lat);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
if (_lon && _lat && _lon !== pickerInfoRef.current?.lon && _lat !== pickerInfoRef.current?.lat) {
|
|
136
|
+
if (element === "Polypoint") {
|
|
137
|
+
setPickPoint(_lon, _lat, { isAutoFixAddr: false, addr: addr });
|
|
138
|
+
} else {
|
|
139
|
+
setDrawEditor(_points || []);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
init({ editDone: onMapDbClick });
|
|
144
|
+
return () => {
|
|
145
|
+
// 取消监听
|
|
146
|
+
mapUtilsRef.current?.off("dblclick", onMapDbClick);
|
|
147
|
+
mapUtilsRef.current?.off("click", onClickMap);
|
|
148
|
+
};
|
|
149
|
+
}, []);
|
|
150
|
+
|
|
151
|
+
async function onMapDbClick() {
|
|
152
|
+
if (element !== "Polypoint") {
|
|
153
|
+
const graphical = mapUtilsRef.current.polyEditor[`${element}Editor`].getTarget();
|
|
154
|
+
if (graphical) {
|
|
155
|
+
const points = graphical.getPath().map((item) => [item.lng, item.lat]);
|
|
156
|
+
const center = mapUtilsRef.current.getPolygonCenter(points);
|
|
157
|
+
const addr = await getAddr(center[0], center[1]);
|
|
158
|
+
mapUtilsRef.current.polyEditor[`${element}Editor`].close();
|
|
159
|
+
mapUtilsRef.current.polyEditor[`${element}Editor`].setTarget();
|
|
160
|
+
props.setPickInfo &&
|
|
161
|
+
props.setPickInfo({
|
|
162
|
+
points,
|
|
163
|
+
addr,
|
|
164
|
+
lon: center[0],
|
|
165
|
+
lat: center[1],
|
|
166
|
+
});
|
|
167
|
+
setPickInfo({
|
|
168
|
+
points,
|
|
169
|
+
addr,
|
|
170
|
+
lon: center[0],
|
|
171
|
+
lat: center[1],
|
|
172
|
+
range: 0
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function mapInit({ map, mapUtils }) {
|
|
179
|
+
mapUtilsRef.current = mapUtils;
|
|
180
|
+
mapUtilsRef.current.on("dblclick", onMapDbClick);
|
|
181
|
+
let _lon = defaultLocation.lon;
|
|
182
|
+
let _lat = defaultLocation.lat;
|
|
183
|
+
let _points = defaultLocation.points;
|
|
184
|
+
let _range = defaultLocation.range
|
|
185
|
+
if (pickInfo.lon && pickInfo.lat) {
|
|
186
|
+
_lon = pickInfo.lon;
|
|
187
|
+
_lat = pickInfo.lat;
|
|
188
|
+
_points = pickInfo.points;
|
|
189
|
+
_range = pickInfo.range
|
|
190
|
+
} else if (formatValRef.current?.lon && formatValRef.current?.lat) {
|
|
191
|
+
_lon = formatValRef.current?.lon;
|
|
192
|
+
_lat = formatValRef.current?.lat;
|
|
193
|
+
_points = formatValRef.current?.points;
|
|
194
|
+
_range = formatValRef.current?.range;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
setMapCenter(_lon, _lat);
|
|
198
|
+
|
|
199
|
+
setLoading(props.loading || false);
|
|
200
|
+
if (!(disabled || readOnly)) {
|
|
201
|
+
if (element === "Polypoint") {
|
|
202
|
+
mapUtilsRef.current?.setPickerMarker(_lon, _lat);
|
|
203
|
+
// 点击选中点位的情况
|
|
204
|
+
mapUtilsRef.current.on("click", onClickMap);
|
|
205
|
+
} else {
|
|
206
|
+
mapUtilsRef.current?.createPoly(element);
|
|
207
|
+
if (_points.length == 0) {
|
|
208
|
+
mapUtilsRef.current?.startPolygon({
|
|
209
|
+
onClick: onPolygonClick,
|
|
210
|
+
element,
|
|
211
|
+
});
|
|
212
|
+
mapUtilsRef.current.setDrawPolygon({ element });
|
|
213
|
+
}
|
|
214
|
+
setDrawEditor(_points);
|
|
215
|
+
}
|
|
216
|
+
} else {
|
|
217
|
+
// 禁用、只读情况使用 marker 展示点位
|
|
218
|
+
if (element === "Polypoint") {
|
|
219
|
+
mapUtilsRef.current?.setPickerMarker(_lon, _lat);
|
|
220
|
+
mapUtilsRef.current.setCircle(_lon, _lat, _range);
|
|
221
|
+
} else {
|
|
222
|
+
setDrawEditor(_points, true);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function onClickMap(ev) {
|
|
228
|
+
const { lng: evLon, lat: evLat } = ev.lnglat || {};
|
|
229
|
+
if (element === "Polypoint") {
|
|
230
|
+
setPickPoint(evLon, evLat, { changeCenter: true });
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function setDrawEditor(_points, disabled = false) {
|
|
235
|
+
if (!mapUtilsRef.current) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
mapUtilsRef.current?.createPoly(element);
|
|
239
|
+
if (_points && _points.length > 0) {
|
|
240
|
+
const graphical = mapUtilsRef.current?.setPolygon({
|
|
241
|
+
points: _points,
|
|
242
|
+
id: "setDrawEditor",
|
|
243
|
+
element,
|
|
244
|
+
onClick: !disabled && onPolygonClick,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function onPolygonClick(e) {
|
|
250
|
+
mapUtilsRef.current.setEditPolygon({ ...e.target, element });
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* 设置地图中心点
|
|
255
|
+
* @param lon
|
|
256
|
+
* @param lat
|
|
257
|
+
*/
|
|
258
|
+
function setMapCenter(lon = pickInfo.lon, lat = pickInfo.lat) {
|
|
259
|
+
lon && lat && mapUtilsRef.current?.setCenter(lon, lat);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async function setPickPoint(_lon, _lat, opt?: any) {
|
|
263
|
+
const { isAutoFixAddr: _isAutoFixAddr = isAutoFixAddr || true, changeCenter, addr: _addr } = opt || {};
|
|
264
|
+
const lon = _lon || pickInfo.lon;
|
|
265
|
+
const lat = _lat || pickInfo.lat;
|
|
266
|
+
let addr = _addr;
|
|
267
|
+
mapUtilsRef.current?.setPickerMarker(_lon, _lat);
|
|
268
|
+
if (changeCenter) {
|
|
269
|
+
setMapCenter(_lon, _lat);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// 开启自动修复地址 且 opt 参数中没有地址,请求地址
|
|
273
|
+
if (_isAutoFixAddr && !addr) {
|
|
274
|
+
addr = await getAddr(lon, lat);
|
|
275
|
+
}
|
|
276
|
+
const res = { ...pickInfo, lon, lat, addr };
|
|
277
|
+
setPickInfo(res);
|
|
278
|
+
pickerInfoRef.current = res;
|
|
279
|
+
props.setPickInfo && props.setPickInfo(res);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function getAddr(_lng, _lat) {
|
|
283
|
+
return new Promise((resolve, reject) => {
|
|
284
|
+
if (!window.AMap) {
|
|
285
|
+
reject();
|
|
286
|
+
return new Error("window.AMap is not defined");
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
setAddrLoading(true);
|
|
290
|
+
getAddress(_lng, _lat)
|
|
291
|
+
.then((addr) => {
|
|
292
|
+
setAddrLoading(false);
|
|
293
|
+
setPickInfo((_p) => {
|
|
294
|
+
pickerInfoRef.current = { ..._p, addr };
|
|
295
|
+
return pickerInfoRef.current;
|
|
296
|
+
});
|
|
297
|
+
resolve(addr);
|
|
298
|
+
})
|
|
299
|
+
.catch((err) => {
|
|
300
|
+
reject(err);
|
|
301
|
+
message.error(err);
|
|
302
|
+
setAddrLoading(false);
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function resetCenter() {
|
|
308
|
+
setMapCenter();
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function getPosition() {
|
|
312
|
+
setLoading(true);
|
|
313
|
+
// 获取当前经纬度
|
|
314
|
+
getCurrentPosition(getCurPositionConf)
|
|
315
|
+
.then((res) => {
|
|
316
|
+
const { coords = {} } = res;
|
|
317
|
+
setPickPoint(coords.longitude, coords.latitude, { changeCenter: true });
|
|
318
|
+
setLoading(false);
|
|
319
|
+
})
|
|
320
|
+
.catch((e) => {
|
|
321
|
+
setLoading(false);
|
|
322
|
+
message.error("定位获取失败");
|
|
323
|
+
console.warn("Error getCurrentPosition e: ", e);
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// 展示获取当前定位按钮 props.showGetPositionBtn !== false 且非禁用、只读模式
|
|
328
|
+
const showGetPositionBtn = props.showGetPositionBtn !== false && !(disabled || readOnly);
|
|
329
|
+
|
|
330
|
+
const { markerIcon, positionIcon, resetIcon } = icons || {};
|
|
331
|
+
|
|
332
|
+
return (
|
|
333
|
+
<div className={`location-picker-modal-content location-mode-${mode} location-modal-content-layout-${layout}`}>
|
|
334
|
+
<PickerInfo
|
|
335
|
+
element={element}
|
|
336
|
+
pickInfo={pickInfo}
|
|
337
|
+
setPickInfo={setPickInfo}
|
|
338
|
+
setPoint={setPickPoint}
|
|
339
|
+
addrLoading={addrLoading}
|
|
340
|
+
defaultLocation={defaultLocation}
|
|
341
|
+
disabled={disabled}
|
|
342
|
+
readOnly={element !== "Polypoint" ? true : readOnly}
|
|
343
|
+
/>
|
|
344
|
+
<div className="location-picker-map-wrap">
|
|
345
|
+
<div className="location-picker-map">
|
|
346
|
+
{/* 关闭弹窗之后清除搜索内容 */}
|
|
347
|
+
{hasSearch && !disabled && !readOnly ? (
|
|
348
|
+
<MapSearch
|
|
349
|
+
key={visible}
|
|
350
|
+
setPoint={element !== "Polypoint" && (readOnly || disabled) ? setMapCenter : setPickPoint}
|
|
351
|
+
isAutoSearch={isAutoSearch}
|
|
352
|
+
/>
|
|
353
|
+
) : null}
|
|
354
|
+
<AMapCom init={mapInit} loading={loading} markerIconConf={markerIconConf} />
|
|
355
|
+
<div className="set-map-actions">
|
|
356
|
+
{/* 已选的点位居中 */}
|
|
357
|
+
<div className="actions-icon-box reset-icon-box" onClick={resetCenter}>
|
|
358
|
+
{typeof resetIcon === "string" ? (
|
|
359
|
+
<img className="reset-icon" src={resetIcon} />
|
|
360
|
+
) : (
|
|
361
|
+
resetIcon || resetIconDef
|
|
362
|
+
)}
|
|
363
|
+
</div>
|
|
364
|
+
{/* 获取当前经纬度 */}
|
|
365
|
+
{showGetPositionBtn && element === "Polypoint" ? (
|
|
366
|
+
<div className="actions-icon-box center-icon-box" onClick={getPosition}>
|
|
367
|
+
{typeof positionIcon === "string" ? (
|
|
368
|
+
<img className="center-icon" src={positionIcon} />
|
|
369
|
+
) : (
|
|
370
|
+
positionIcon || positionIconDef
|
|
371
|
+
)}
|
|
372
|
+
</div>
|
|
373
|
+
) : null}
|
|
374
|
+
</div>
|
|
375
|
+
</div>
|
|
376
|
+
{disabled || readOnly ? null : <Notice />}
|
|
377
|
+
</div>
|
|
378
|
+
{loading && (
|
|
379
|
+
<div className="spin-loading-wrap">
|
|
380
|
+
<Spin className="spin-loading" />
|
|
381
|
+
</div>
|
|
382
|
+
)}
|
|
383
|
+
</div>
|
|
384
|
+
);
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
export default ModalContent;
|