@hzab/form-render 1.6.18 → 1.6.20

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 (60) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +247 -239
  3. package/package.json +57 -57
  4. package/src/common/formily-utils.ts +125 -125
  5. package/src/common/schema-handler.ts +253 -253
  6. package/src/common/schema-merge.ts +68 -68
  7. package/src/components/ArrayBase/index.tsx +349 -349
  8. package/src/components/ArrayBase/style.less +90 -90
  9. package/src/components/ArrayBase/style.ts +2 -2
  10. package/src/components/ArrayCards/index.tsx +149 -149
  11. package/src/components/ArrayCards/style.less +14 -14
  12. package/src/components/ArrayCards/style.ts +4 -4
  13. package/src/components/ArrayTable/index.tsx +411 -411
  14. package/src/components/ArrayTable/style.less +52 -52
  15. package/src/components/ArrayTable/style.ts +7 -7
  16. package/src/components/DatePicker/index.tsx +108 -108
  17. package/src/components/LocationListPicker/assets/icon.js +1 -1
  18. package/src/components/LocationListPicker/components/AddrList/index.less +55 -55
  19. package/src/components/LocationListPicker/components/AddrList/index.tsx +75 -75
  20. package/src/components/LocationListPicker/components/Popup/address.schema.json +21 -21
  21. package/src/components/LocationListPicker/components/Popup/index.less +22 -22
  22. package/src/components/LocationListPicker/components/Popup/index.tsx +92 -92
  23. package/src/components/LocationListPicker/index.less +34 -34
  24. package/src/components/LocationListPicker/index.tsx +521 -520
  25. package/src/components/LocationPicker/Map/AMap/common/loader.ts +58 -58
  26. package/src/components/LocationPicker/Map/AMap/common/utils.ts +431 -431
  27. package/src/components/LocationPicker/Map/AMap/index.jsx +51 -51
  28. package/src/components/LocationPicker/README.md +44 -44
  29. package/src/components/LocationPicker/common/utils.ts +30 -30
  30. package/src/components/LocationPicker/components/ModalContent/index.tsx +387 -387
  31. package/src/components/LocationPicker/components/PickerInfo/index.tsx +109 -109
  32. package/src/components/LocationPicker/components/ResInfo/index.less +38 -38
  33. package/src/components/LocationPicker/components/ResInfo/index.tsx +65 -65
  34. package/src/components/LocationPicker/index.tsx +197 -197
  35. package/src/components/PersonnelSelect/index.less +21 -21
  36. package/src/components/PersonnelSelect/index.module.less +33 -33
  37. package/src/components/PersonnelSelect/type.ts +92 -92
  38. package/src/components/RichEditor/index.less +38 -38
  39. package/src/components/RichEditor/index.tsx +238 -238
  40. package/src/components/TreeCheckbox/components/CheckboxTable/index.tsx +61 -55
  41. package/src/components/TreeCheckbox/components/Render/index.tsx +28 -28
  42. package/src/components/TreeCheckbox/components/TabsRender/index.tsx +61 -58
  43. package/src/components/TreeCheckbox/index.less +18 -12
  44. package/src/components/TreeCheckbox/index.tsx +63 -63
  45. package/src/components/Upload/README.md +64 -64
  46. package/src/components/Upload/common/OfflineUpload.ts +339 -339
  47. package/src/components/Upload/common/customRequest.ts +81 -81
  48. package/src/components/Upload/common/fileName.ts +142 -142
  49. package/src/components/Upload/common/handleIOFileList.ts +393 -393
  50. package/src/components/Upload/common/nanoid.ts +7 -7
  51. package/src/components/Upload/common/ossUpload.js +159 -159
  52. package/src/components/Upload/common/utils.js +194 -194
  53. package/src/components/Upload/components/ItemList/index.tsx +52 -52
  54. package/src/components/Upload/components/PreviewModal/previewRender.tsx +80 -80
  55. package/src/components/Upload/index.tsx +17 -17
  56. package/src/components/Upload/uploader-input.jsx +187 -187
  57. package/src/components/Upload/uploader.jsx +316 -316
  58. package/src/components/UserSelect/index.tsx +123 -123
  59. package/src/components/index.tsx +17 -17
  60. package/src/index.tsx +198 -198
@@ -1,520 +1,521 @@
1
- // @ts-nocheck
2
- import { useEffect, useRef, useState } from "react";
3
- import { Button, message, Alert } from "antd";
4
- import { observer } from "@formily/react";
5
- import * as turf from "@turf/turf";
6
- import { nanoid } from "nanoid";
7
-
8
- import AddrList from "./components/AddrList";
9
- import Popup from "./components/Popup";
10
-
11
- import AMapCom from "../LocationPicker/Map/AMap";
12
- import MapSearch from "../LocationPicker/components/MapSearch";
13
- import { MapUtils } from "../LocationPicker/Map/AMap/common/utils";
14
- import { getAddress } from "../LocationPicker/servers";
15
- import { markerIconBase64 } from "../LocationPicker/assets/svg-icon";
16
-
17
- import { iconCircle0080ff } from "./assets/icon";
18
-
19
- import "./index.less";
20
-
21
- export const LocationListPicker = observer((props) => {
22
- const {
23
- value,
24
- readOnly,
25
- disabled,
26
- listProps,
27
- popupProps,
28
- ItemRender,
29
- markerIconConf,
30
- isAutoSearch,
31
- /** 是否支持新增多边形 */
32
- hasPolygon,
33
- /** 是否支持新增点位 */
34
- hasPoint = true,
35
- onChange,
36
- } = props;
37
-
38
- const [loading, setLoading] = useState(props.loading || false);
39
- const [showTip, setShowTip] = useState(false);
40
- const [tipText, setTipText] = useState("点击选择地址");
41
- const [tipPosition, setTipPosition] = useState({});
42
- const [activeId, setActiveId] = useState();
43
- const mapDomRef = useRef();
44
- const mapUtilsRef = useRef<MapUtils>();
45
- const listRef = useRef(value);
46
- const statusRef = useRef();
47
- const drawType = useRef("marker");
48
- const currentItemRef = useRef();
49
- const popupRef = useRef();
50
- const isEditingRef = useRef();
51
- const mapBoxRef = useRef(null);
52
-
53
- useEffect(() => {
54
- return () => {
55
- // 取消监听
56
- mapUtilsRef.current?.off("click", onMapClick);
57
- mapUtilsRef.current?.off("dblclick", onMapDbClick);
58
- mapDomRef.current.current.removeEventListener("mousemove", onMouseMove);
59
- };
60
- }, []);
61
-
62
- useEffect(() => {
63
- if (!Array.isArray(value) || value?.length == 0) {
64
- return;
65
- }
66
- // 处理 id
67
- value?.forEach((it) => {
68
- if (!it.id) {
69
- it.id = nanoid();
70
- }
71
- });
72
- listRef.current = value || [];
73
- if (!mapUtilsRef.current) {
74
- return;
75
- }
76
- renderMarker();
77
- }, [value]);
78
-
79
- function renderMarker() {
80
- listRef.current?.forEach((item) => {
81
- if (item.type === "polygon") {
82
- mapUtilsRef.current.setPolygon({
83
- ...item,
84
- onClick: onPolygonClick,
85
- });
86
- } else {
87
- mapUtilsRef.current.setMarker(item.longitude, item.latitude, {
88
- ...item,
89
- data: item,
90
- onClick: onMarkerClick,
91
- });
92
- mapUtilsRef.current.setCircle(item.longitude, item.latitude, item.range, { ...item, onClick: handleMarker });
93
- }
94
- });
95
- mapUtilsRef.current.setFitView();
96
- clearActive();
97
- }
98
-
99
- function mapInit({ map, mapUtils, mapDomRef: _mapDomRef }) {
100
- mapDomRef.current = _mapDomRef;
101
- _mapDomRef.current.addEventListener("mousemove", onMouseMove);
102
- mapUtilsRef.current = mapUtils;
103
- mapUtilsRef.current?.createPoly("Polygon");
104
- // 启动监听事件
105
- mapUtilsRef.current.on("click", onMapClick);
106
- mapUtilsRef.current.on("dblclick", onMapDbClick);
107
-
108
- mapUtilsRef.current.startPolygon({
109
- onClick: onPolygonClick,
110
- });
111
-
112
- renderMarker();
113
- }
114
-
115
- function onAddClick() {
116
- if (isEditingRef.current) {
117
- message.warn("请先完成上次操作");
118
- return;
119
- }
120
- clearActive();
121
- setTipText("点击选择地址");
122
- setShowTip(true);
123
- drawType.current = "marker";
124
- statusRef.current = "add";
125
- }
126
-
127
- function onDrawClick() {
128
- if (isEditingRef.current) {
129
- message.warn("请先完成上次操作");
130
- return;
131
- }
132
- isEditingRef.current = true;
133
- setTipText("点击绘制区域 双击完成绘制");
134
- setDrawPolygon();
135
- setShowTip(true);
136
- drawType.current = "polygon";
137
- statusRef.current = "add";
138
- }
139
-
140
- function setDrawPolygon() {
141
- mapUtilsRef.current.setDrawPolygon({});
142
- }
143
-
144
- function setInactivePolygon(item) {
145
- mapUtilsRef.current.setEditPolygon(item);
146
- }
147
-
148
- function onMapDbClick(e) {
149
- if (drawType.current !== "polygon") {
150
- return;
151
- }
152
- const graphical = mapUtilsRef.current.polyEditor?.PolygonEditor?.getTarget();
153
- if (graphical) {
154
- let points = [];
155
- let center = [];
156
- if (graphical.getPath().length > 0) {
157
- const coordinate = graphical.getPath().map((item) => [item.lng, item.lat]);
158
- points = coordinate;
159
- center = getPolygonCenter(coordinate);
160
- }
161
- mapUtilsRef.current.polyEditor?.PolygonEditor?.close();
162
- mapUtilsRef.current.polyEditor?.PolygonEditor?.setTarget();
163
- handlePolygon({
164
- type: "polygon",
165
- id: graphical.id,
166
- points,
167
- longitude: center[0],
168
- latitude: center[1],
169
- });
170
- }
171
- }
172
-
173
- function getPolygonCenter(coordinate) {
174
- if (coordinate.length > 0) {
175
- let features = turf.featureCollection(coordinate.map((item) => turf.point(item)));
176
- let center = turf.center(features).geometry.coordinates;
177
- return center;
178
- }
179
- return [];
180
- }
181
-
182
- async function handlePolygon(item) {
183
- const status = statusRef.current;
184
- const isAdd = status === "add";
185
- const isEdit = status === "edit";
186
- if (isAdd) {
187
- currentItemRef.current = item;
188
- }
189
- // 接口获取地址
190
- item.address = await getAddress(item.longitude, item.latitude);
191
- const list = [...(listRef.current || [])];
192
- if (isAdd) {
193
- list.push(item);
194
- } else if (isEdit) {
195
- const idx = list.findIndex((it) => it.id === item.id);
196
- list.splice(idx, 1, item);
197
- }
198
- onChange && onChange(list);
199
- clearStatus();
200
- }
201
-
202
-
203
- // 地图单击除现有元素范围外添加点位地址
204
- function onMapClick(e) {
205
- mapUtilsRef.current.isContains(e, handleMarker);
206
- }
207
-
208
- // 处理 marker、范围 绘制填写逻辑
209
- async function handleMarker(e) {
210
- if (drawType.current !== "marker") {
211
- return;
212
- }
213
-
214
- const status = statusRef.current;
215
- const isAdd = status === "add";
216
- const isEdit = status === "edit";
217
- setShowTip(false);
218
- if (!isAdd && !isEdit) {
219
- return;
220
- }
221
- isEditingRef.current = true;
222
-
223
- const { lng, lat } = e.lnglat || {};
224
-
225
- const preItem = currentItemRef.current;
226
- const id = isAdd ? nanoid() : preItem?.id;
227
-
228
- let item = {
229
- id,
230
- longitude: lng,
231
- latitude: lat,
232
- address: "",
233
- range: "",
234
- ...preItem,
235
- };
236
-
237
- // 解决新增时点击修改重复创建的问题
238
- if (isAdd) {
239
- item.longitude = lng;
240
- item.latitude = lat;
241
- currentItemRef.current = item;
242
- }
243
-
244
- // 接口获取地址
245
- item.address = await getAddress(lng, lat);
246
-
247
- // 更新地图状态
248
- mapUtilsRef.current.setMarker(lng, lat, {
249
- ...item,
250
- onClick: onMarkerClick,
251
- data: item,
252
- });
253
- // 回显范围
254
- mapUtilsRef.current.setCircle(lng, lat, item.range, { ...item });
255
-
256
- // 根据经纬度获取弹窗位置
257
- const { x, y } = mapUtilsRef.current.map.lngLatToContainer([lng, lat]);
258
- const mapDomRect = mapDomRef.current?.current?.getBoundingClientRect();
259
- // 获取屏幕 x y
260
- const screenX = mapDomRect?.left + x;
261
- const screenY = mapDomRect?.top + y;
262
- let res = {};
263
- try {
264
- res = await popupRef.current?.onShow({
265
- type: "marker",
266
- top: screenY,
267
- left: screenX,
268
- address: item.address,
269
- range: item.range,
270
- item,
271
- });
272
- } catch (error) {
273
- // 新增状态,取消时清除已添加的 marker circle
274
- isAdd && mapUtilsRef.current.rmMarker(item.id);
275
- // 编辑状态恢复数据
276
- if (isEdit) {
277
- mapUtilsRef.current.setMarker(preItem.longitude, preItem.latitude, {
278
- ...preItem,
279
- data: item,
280
- });
281
- mapUtilsRef.current.setCircle(preItem.longitude, preItem.latitude, preItem.range, { ...preItem });
282
- }
283
- clearStatus(item.id);
284
- return;
285
- }
286
-
287
- // 设置范围
288
- mapUtilsRef.current.setCircle(lng, lat, res.range, { ...item });
289
-
290
- item = Object.assign(item, res);
291
-
292
- const list = [...(listRef.current || [])];
293
-
294
- if (isAdd) {
295
- list.push(item);
296
- } else if (isEdit) {
297
- const idx = list.findIndex((it) => it.id === id);
298
- list.splice(idx, 1, item);
299
- }
300
-
301
- onChange && onChange(list);
302
- clearStatus();
303
- }
304
-
305
- function onPolygonClick(e) {
306
- if (!isEditingRef.current && statusRef.current !== "add") {
307
- drawType.current = "polygon";
308
- const id = e.target.id;
309
- clearEdit(id);
310
- setActiveId(id);
311
- setActivePolygon(e.target);
312
- } else if (statusRef.current === "add") {
313
- handleMarker(e);
314
- }
315
- }
316
-
317
- function onMarkerClick(e, ...args) {
318
- clearActive();
319
- if (!isEditingRef.current && statusRef.current !== "add") {
320
- setShowTip(false);
321
- isEditingRef.current = false;
322
- const { id } = e.target.getExtData() || {};
323
- setActiveId(id);
324
- setActiveMarkerIcon(id);
325
- }
326
- }
327
-
328
- /**
329
- * 选中态
330
- * @param item
331
- */
332
- function setActivePolygon(item) {
333
- clearActive();
334
- const target = mapUtilsRef.current.polygonEnum[item.id];
335
- const center = mapUtilsRef.current.getPolygonCenter(target.getPath()?.map((it) => [it.lng, it.lat]));
336
- mapUtilsRef.current.setCenter(center?.[0], center?.[1]);
337
- target?.setOptions({
338
- strokeColor: "#403ef5",
339
- strokeWeight: 4,
340
- });
341
- }
342
-
343
- function clearActive() {
344
- // 多边形清除选中态
345
- Object.keys(mapUtilsRef.current.polygonEnum).forEach((key) => {
346
- const item = mapUtilsRef.current.polygonEnum[key];
347
- item?.setOptions({
348
- strokeColor: "#1791fc",
349
- strokeWeight: 2,
350
- });
351
- });
352
- // Marker 清除选中态
353
- Object.keys(mapUtilsRef.current.markers).forEach((key) => {
354
- mapUtilsRef.current.setMarkerIcon(key, {
355
- image: iconCircle0080ff,
356
- size: [12, 12],
357
- offset: [-6, -6],
358
- });
359
- });
360
- }
361
-
362
- function clearEdit(id) {
363
- mapUtilsRef.current.polyEditor?.PolygonEditor?.close();
364
- mapUtilsRef.current.polyEditor?.PolygonEditor?.setTarget();
365
- }
366
-
367
- function clearStatus(id) {
368
- clearActive();
369
- isEditingRef.current = false;
370
- // 清除状态,解决重复创建的问题
371
- statusRef.current = null;
372
- // 编辑状态清除数据
373
- currentItemRef.current = null;
374
- setShowTip(false);
375
- popupRef.current.onCancel();
376
- }
377
-
378
- function onItemClick(item, i) {
379
- drawType.current = item.type || "marker";
380
- clearActive();
381
- clearStatus(item.id);
382
- setActiveId(item.id);
383
- const mapUtils = mapUtilsRef.current;
384
- if (item.type == "polygon") {
385
- // 选中态
386
- setActivePolygon(item);
387
- } else {
388
- const marker = mapUtils.markers[item.id];
389
- const position = marker?.getPosition();
390
- position && mapUtils.setCenter(position.lng, position.lat);
391
- setActiveMarkerIcon(item.id);
392
- }
393
- }
394
-
395
- function setActiveMarkerIcon(id) {
396
- mapUtilsRef.current.setMarkerIcon(id, {
397
- image: markerIconBase64,
398
- size: [34, 34],
399
- offset: [-17, -34],
400
- });
401
- }
402
-
403
- function onEdit(item, i) {
404
- if (isEditingRef.current) {
405
- message.warn("请先完成上次操作");
406
- return;
407
- }
408
- clearActive();
409
- drawType.current = item.type || "marker";
410
- setShowTip(true);
411
- mapUtilsRef.current.setCenter(item.longitude, item.latitude, { immediately: true });
412
- clearEdit(item.id);
413
- // 多边形清除选中态
414
- statusRef.current = "edit";
415
- currentItemRef.current = item;
416
- if (item.type == "polygon") {
417
- setTipText("点击绘制区域 双击完成绘制");
418
- setInactivePolygon(item);
419
- isEditingRef.current = true;
420
- } else {
421
- setTipText("点击选择地址");
422
- setActiveMarkerIcon(item.id);
423
- handleMarker({
424
- lnglat: {
425
- lng: item.longitude,
426
- lat: item.latitude,
427
- },
428
- });
429
- }
430
- }
431
-
432
- function onDelClick(item, i) {
433
- clearActive();
434
- drawType.current = item.type || "marker";
435
- mapUtilsRef.current.setCenter(item.longitude, item.latitude, { immediately: true });
436
- if (item.type !== "polygon") {
437
- setActiveId(item.id);
438
- setActiveMarkerIcon(item.id);
439
- }
440
- }
441
-
442
- function onDel(item, i) {
443
- drawType.current = item.type || "marker";
444
- const list = [...(listRef.current || [])];
445
- listRef.current?.splice(i, 1);
446
- list?.splice(i, 1);
447
- onChange && onChange(list);
448
- if (item.type === "polygon") {
449
- mapUtilsRef.current.rmPolygon(item.id);
450
- } else {
451
- // 清除对应的 marker
452
- mapUtilsRef.current.rmMarker(item.id);
453
- // 清除对应的 circle
454
- mapUtilsRef.current.rmCircle(item.id);
455
- }
456
- }
457
-
458
- function onDelCancel(item, i) {
459
- drawType.current = item.type || "marker";
460
- if (item.type !== "polygon") {
461
- clearActive();
462
- setActiveId(null);
463
- }
464
- }
465
-
466
- function setPoint(lng, lat) {
467
- mapUtilsRef.current.setCenter(lng, lat, { immediately: true });
468
- statusRef.current = "add";
469
- handleMarker({
470
- lnglat: {
471
- lng,
472
- lat,
473
- },
474
- });
475
- }
476
-
477
- function onMouseMove(e) {
478
- const { offsetX, offsetY } = e;
479
- setTipPosition({ left: offsetX + 10, top: offsetY + 10 });
480
- }
481
-
482
- return (
483
- <div className="location-list-picker">
484
- <div className="map-box" ref={mapBoxRef}>
485
- <AMapCom init={mapInit} loading={loading} markerIconConf={markerIconConf} />
486
- {!readOnly && !disabled && <MapSearch setPoint={setPoint} isAutoSearch={isAutoSearch} />}
487
- {showTip && (
488
- <Alert className="location-list-picker-notice-bar" message={tipText} type="info" style={tipPosition} />
489
- )}
490
- {hasPolygon && !readOnly && (
491
- <Button className="add-polygon-btn" onClick={onDrawClick} disabled={disabled}>
492
- 新增区域
493
- </Button>
494
- )}
495
- {hasPoint !== false && !readOnly && (
496
- <Button className="add-btn" onClick={onAddClick} disabled={disabled}>
497
- 新增地址
498
- </Button>
499
- )}
500
- <Popup ref={popupRef} mountElement={mapBoxRef.current} {...popupProps} />
501
- </div>
502
- <AddrList
503
- {...listProps}
504
- readOnly={readOnly}
505
- disabled={disabled}
506
- mapUtilsRef={mapUtilsRef}
507
- activeId={activeId}
508
- list={value}
509
- ItemRender={ItemRender}
510
- onItemClick={onItemClick}
511
- onEdit={onEdit}
512
- onDel={onDel}
513
- onDelClick={onDelClick}
514
- onDelCancel={onDelCancel}
515
- />
516
- </div>
517
- );
518
- });
519
-
520
- export default LocationListPicker;
1
+ // @ts-nocheck
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { Button, message, Alert } from "antd";
4
+ import { observer } from "@formily/react";
5
+ import * as turf from "@turf/turf";
6
+ import { nanoid } from "nanoid";
7
+
8
+ import AddrList from "./components/AddrList";
9
+ import Popup from "./components/Popup";
10
+
11
+ import AMapCom from "../LocationPicker/Map/AMap";
12
+ import MapSearch from "../LocationPicker/components/MapSearch";
13
+ import { MapUtils } from "../LocationPicker/Map/AMap/common/utils";
14
+ import { getAddress } from "../LocationPicker/servers";
15
+ import { markerIconBase64 } from "../LocationPicker/assets/svg-icon";
16
+
17
+ import { iconCircle0080ff } from "./assets/icon";
18
+
19
+ import "./index.less";
20
+
21
+ export const LocationListPicker = observer((props) => {
22
+ const {
23
+ value,
24
+ readOnly,
25
+ disabled,
26
+ listProps,
27
+ popupProps,
28
+ ItemRender,
29
+ markerIconConf,
30
+ isAutoSearch,
31
+ /** 是否支持新增多边形 */
32
+ hasPolygon,
33
+ /** 是否支持新增点位 */
34
+ hasPoint = true,
35
+ onChange,
36
+ } = props;
37
+
38
+ const [loading, setLoading] = useState(props.loading || false);
39
+ const [showTip, setShowTip] = useState(false);
40
+ const [tipText, setTipText] = useState("点击选择地址");
41
+ const [tipPosition, setTipPosition] = useState({});
42
+ const [activeId, setActiveId] = useState();
43
+ const mapDomRef = useRef();
44
+ const mapUtilsRef = useRef<MapUtils>();
45
+ const listRef = useRef(value);
46
+ const statusRef = useRef();
47
+ const drawType = useRef("marker");
48
+ const currentItemRef = useRef();
49
+ const popupRef = useRef();
50
+ const isEditingRef = useRef();
51
+ const mapBoxRef = useRef(null);
52
+
53
+ useEffect(() => {
54
+ return () => {
55
+ // 取消监听
56
+ mapUtilsRef.current?.off("click", onMapClick);
57
+ mapUtilsRef.current?.off("dblclick", onMapDbClick);
58
+ mapDomRef.current.current.removeEventListener("mousemove", onMouseMove);
59
+ };
60
+ }, []);
61
+
62
+ useEffect(() => {
63
+ if (!Array.isArray(value) || value?.length == 0) {
64
+ return;
65
+ }
66
+ // 处理 id
67
+ value?.forEach((it) => {
68
+ if (!it.id) {
69
+ it.id = nanoid();
70
+ }
71
+ });
72
+ listRef.current = value || [];
73
+ if (!mapUtilsRef.current) {
74
+ return;
75
+ }
76
+ renderMarker();
77
+ }, [value]);
78
+
79
+ function renderMarker() {
80
+ listRef.current?.forEach((item) => {
81
+ if (item.type === "polygon") {
82
+ mapUtilsRef.current.setPolygon({
83
+ ...item,
84
+ onClick: onPolygonClick,
85
+ });
86
+ } else {
87
+ mapUtilsRef.current.setMarker(item.longitude, item.latitude, {
88
+ ...item,
89
+ data: item,
90
+ onClick: onMarkerClick,
91
+ });
92
+ mapUtilsRef.current.setCircle(item.longitude, item.latitude, item.range, { ...item, onClick: handleMarker });
93
+ }
94
+ });
95
+ mapUtilsRef.current.setFitView();
96
+ clearActive();
97
+ }
98
+
99
+ function mapInit({ map, mapUtils, mapDomRef: _mapDomRef }) {
100
+ mapDomRef.current = _mapDomRef;
101
+ _mapDomRef.current.addEventListener("mousemove", onMouseMove);
102
+ mapUtilsRef.current = mapUtils;
103
+ mapUtilsRef.current?.createPoly("Polygon");
104
+ // 启动监听事件
105
+ mapUtilsRef.current.on("click", onMapClick);
106
+ mapUtilsRef.current.on("dblclick", onMapDbClick);
107
+
108
+ mapUtilsRef.current.startPolygon({
109
+ onClick: onPolygonClick,
110
+ });
111
+
112
+ renderMarker();
113
+ }
114
+
115
+ function onAddClick() {
116
+ if (isEditingRef.current) {
117
+ message.warn("请先完成上次操作");
118
+ return;
119
+ }
120
+ clearActive();
121
+ setTipText("点击选择地址");
122
+ setShowTip(true);
123
+ drawType.current = "marker";
124
+ statusRef.current = "add";
125
+ }
126
+
127
+ function onDrawClick() {
128
+ if (isEditingRef.current) {
129
+ message.warn("请先完成上次操作");
130
+ return;
131
+ }
132
+ isEditingRef.current = true;
133
+ setTipText("点击绘制区域 双击完成绘制");
134
+ setDrawPolygon();
135
+ setShowTip(true);
136
+ drawType.current = "polygon";
137
+ statusRef.current = "add";
138
+ }
139
+
140
+ function setDrawPolygon() {
141
+ mapUtilsRef.current.setDrawPolygon({});
142
+ }
143
+
144
+ function setInactivePolygon(item) {
145
+ mapUtilsRef.current.setEditPolygon(item);
146
+ }
147
+
148
+ function onMapDbClick(e) {
149
+ if (drawType.current !== "polygon") {
150
+ return;
151
+ }
152
+ const graphical = mapUtilsRef.current.polyEditor?.PolygonEditor?.getTarget();
153
+ if (graphical) {
154
+ let points = [];
155
+ let center = [];
156
+ if (graphical.getPath().length > 0) {
157
+ const coordinate = graphical.getPath().map((item) => [item.lng, item.lat]);
158
+ points = coordinate;
159
+ center = getPolygonCenter(coordinate);
160
+ }
161
+ mapUtilsRef.current.polyEditor?.PolygonEditor?.close();
162
+ mapUtilsRef.current.polyEditor?.PolygonEditor?.setTarget();
163
+ handlePolygon({
164
+ type: "polygon",
165
+ id: graphical.id,
166
+ points,
167
+ longitude: center[0],
168
+ latitude: center[1],
169
+ });
170
+ }
171
+ }
172
+
173
+ function getPolygonCenter(coordinate) {
174
+ if (coordinate.length > 0) {
175
+ let features = turf.featureCollection(coordinate.map((item) => turf.point(item)));
176
+ let center = turf.center(features).geometry.coordinates;
177
+ return center;
178
+ }
179
+ return [];
180
+ }
181
+
182
+ async function handlePolygon(item) {
183
+ const status = statusRef.current;
184
+ const isAdd = status === "add";
185
+ const isEdit = status === "edit";
186
+ if (isAdd) {
187
+ currentItemRef.current = item;
188
+ }
189
+ // 接口获取地址
190
+ item.address = await getAddress(item.longitude, item.latitude);
191
+ const list = [...(listRef.current || [])];
192
+ if (isAdd) {
193
+ list.push(item);
194
+ } else if (isEdit) {
195
+ const idx = list.findIndex((it) => it.id === item.id);
196
+ list.splice(idx, 1, item);
197
+ }
198
+ onChange && onChange(list);
199
+ clearStatus();
200
+ }
201
+
202
+ // 地图单击除现有元素范围外添加点位地址
203
+ function onMapClick(e) {
204
+ mapUtilsRef.current.isContains(e, handleMarker);
205
+ }
206
+
207
+ // 处理 marker、范围 绘制填写逻辑
208
+ async function handleMarker(e) {
209
+ if (drawType.current !== "marker") {
210
+ return;
211
+ }
212
+
213
+ const status = statusRef.current;
214
+ const isAdd = status === "add";
215
+ const isEdit = status === "edit";
216
+ setShowTip(false);
217
+ if (!isAdd && !isEdit) {
218
+ return;
219
+ }
220
+ isEditingRef.current = true;
221
+
222
+ const { lng, lat } = e.lnglat || {};
223
+
224
+ const preItem = currentItemRef.current;
225
+ const id = isAdd ? nanoid() : preItem?.id;
226
+
227
+ let item = {
228
+ id,
229
+ longitude: lng,
230
+ latitude: lat,
231
+ address: "",
232
+ range: "",
233
+ ...preItem,
234
+ };
235
+
236
+ // 接口获取地址
237
+ item.address = await getAddress(lng, lat);
238
+
239
+ // 解决新增时点击修改重复创建的问题
240
+ if (isAdd) {
241
+ item.longitude = lng;
242
+ item.latitude = lat;
243
+ currentItemRef.current = item;
244
+ }
245
+
246
+ // 更新地图状态
247
+ mapUtilsRef.current.setMarker(lng, lat, {
248
+ ...item,
249
+ onClick: onMarkerClick,
250
+ data: item,
251
+ });
252
+ // 回显范围
253
+ mapUtilsRef.current.setCircle(lng, lat, item.range, { ...item });
254
+
255
+ // 根据经纬度获取弹窗位置
256
+ const { x, y } = mapUtilsRef.current.map.lngLatToContainer([lng, lat]);
257
+ const mapDomRect = mapDomRef.current?.current?.getBoundingClientRect();
258
+ // 获取屏幕 x y
259
+ const screenX = mapDomRect?.left + x;
260
+ const screenY = mapDomRect?.top + y;
261
+ let res = {};
262
+ try {
263
+ res = await popupRef.current?.onShow({
264
+ type: "marker",
265
+ top: screenY,
266
+ left: screenX,
267
+ address: item.address,
268
+ range: item.range,
269
+ item,
270
+ });
271
+ } catch (error) {
272
+ // 新增状态,取消时清除已添加的 marker circle
273
+ isAdd && mapUtilsRef.current.rmMarker(item.id);
274
+ // 编辑状态恢复数据
275
+ if (isEdit) {
276
+ mapUtilsRef.current.setMarker(preItem.longitude, preItem.latitude, {
277
+ ...preItem,
278
+ data: item,
279
+ });
280
+ mapUtilsRef.current.setCircle(preItem.longitude, preItem.latitude, preItem.range, { ...preItem });
281
+ }
282
+ clearStatus(item.id);
283
+ return;
284
+ }
285
+
286
+ // 设置范围
287
+ mapUtilsRef.current.setCircle(lng, lat, res.range, { ...item });
288
+
289
+ item = Object.assign(item, res);
290
+
291
+ const list = [...(listRef.current || [])];
292
+
293
+ if (isAdd) {
294
+ list.push(item);
295
+ } else if (isEdit) {
296
+ const idx = list.findIndex((it) => it.id === id);
297
+ list.splice(idx, 1, item);
298
+ }
299
+
300
+ onChange && onChange(list);
301
+ clearStatus();
302
+ }
303
+
304
+ function onPolygonClick(e) {
305
+ if (!isEditingRef.current && statusRef.current !== "add") {
306
+ drawType.current = "polygon";
307
+ const id = e.target.id;
308
+ clearEdit(id);
309
+ setActiveId(id);
310
+ setActivePolygon(e.target);
311
+ } else if (statusRef.current === "add") {
312
+ handleMarker(e);
313
+ }
314
+ }
315
+
316
+ function onMarkerClick(e, ...args) {
317
+ clearActive();
318
+ if (!isEditingRef.current && statusRef.current !== "add") {
319
+ setShowTip(false);
320
+ isEditingRef.current = false;
321
+ const { id } = e.target.getExtData() || {};
322
+ setActiveId(id);
323
+ setActiveMarkerIcon(id);
324
+ }
325
+ }
326
+
327
+ /**
328
+ * 选中态
329
+ * @param item
330
+ */
331
+ function setActivePolygon(item) {
332
+ clearActive();
333
+ const target = mapUtilsRef.current.polygonEnum[item.id];
334
+ const center = mapUtilsRef.current.getPolygonCenter(target.getPath()?.map((it) => [it.lng, it.lat]));
335
+ mapUtilsRef.current.setCenter(center?.[0], center?.[1]);
336
+ target?.setOptions({
337
+ strokeColor: "#403ef5",
338
+ strokeWeight: 4,
339
+ });
340
+ }
341
+
342
+ function clearActive() {
343
+ // 多边形清除选中态
344
+ Object.keys(mapUtilsRef.current.polygonEnum).forEach((key) => {
345
+ const item = mapUtilsRef.current.polygonEnum[key];
346
+ item?.setOptions({
347
+ strokeColor: "#1791fc",
348
+ strokeWeight: 2,
349
+ });
350
+ });
351
+ // Marker 清除选中态
352
+ Object.keys(mapUtilsRef.current.markers).forEach((key) => {
353
+ mapUtilsRef.current.setMarkerIcon(key, {
354
+ image: iconCircle0080ff,
355
+ size: [12, 12],
356
+ offset: [-6, -6],
357
+ });
358
+ });
359
+ }
360
+
361
+ function clearEdit(id) {
362
+ mapUtilsRef.current.polyEditor?.PolygonEditor?.close();
363
+ mapUtilsRef.current.polyEditor?.PolygonEditor?.setTarget();
364
+ }
365
+
366
+ function clearStatus(id) {
367
+ clearActive();
368
+ isEditingRef.current = false;
369
+ // 清除状态,解决重复创建的问题
370
+ statusRef.current = null;
371
+ // 编辑状态清除数据
372
+ currentItemRef.current = null;
373
+ setShowTip(false);
374
+ popupRef.current.onCancel();
375
+ }
376
+
377
+ function onItemClick(item, i) {
378
+ drawType.current = item.type || "marker";
379
+ clearActive();
380
+ clearStatus(item.id);
381
+ setActiveId(item.id);
382
+ const mapUtils = mapUtilsRef.current;
383
+ if (item.type == "polygon") {
384
+ // 选中态
385
+ setActivePolygon(item);
386
+ } else {
387
+ const marker = mapUtils.markers[item.id];
388
+ const position = marker?.getPosition();
389
+ position && mapUtils.setCenter(position.lng, position.lat);
390
+ setActiveMarkerIcon(item.id);
391
+ }
392
+ }
393
+
394
+ function setActiveMarkerIcon(id) {
395
+ mapUtilsRef.current.setMarkerIcon(id, {
396
+ image: markerIconBase64,
397
+ size: [34, 34],
398
+ offset: [-17, -34],
399
+ });
400
+ }
401
+
402
+ function onEdit(item, i) {
403
+ if (isEditingRef.current) {
404
+ message.warn("请先完成上次操作");
405
+ return;
406
+ }
407
+ clearActive();
408
+ drawType.current = item.type || "marker";
409
+ setShowTip(true);
410
+ mapUtilsRef.current.setCenter(item.longitude, item.latitude, { immediately: true });
411
+ clearEdit(item.id);
412
+ // 多边形清除选中态
413
+ statusRef.current = "edit";
414
+ currentItemRef.current = item;
415
+ if (item.type == "polygon") {
416
+ setTipText("点击绘制区域 双击完成绘制");
417
+ setInactivePolygon(item);
418
+ isEditingRef.current = true;
419
+ } else {
420
+ setTipText("点击选择地址");
421
+ setActiveMarkerIcon(item.id);
422
+ handleMarker({
423
+ lnglat: {
424
+ lng: item.longitude,
425
+ lat: item.latitude,
426
+ },
427
+ });
428
+ }
429
+ }
430
+
431
+ function onDelClick(item, i) {
432
+ clearActive();
433
+ drawType.current = item.type || "marker";
434
+ mapUtilsRef.current.setCenter(item.longitude, item.latitude, { immediately: true });
435
+ if (item.type !== "polygon") {
436
+ setActiveId(item.id);
437
+ setActiveMarkerIcon(item.id);
438
+ }
439
+ }
440
+
441
+ function onDel(item, i) {
442
+ drawType.current = item.type || "marker";
443
+ const list = [...(listRef.current || [])];
444
+ listRef.current?.splice(i, 1);
445
+ list?.splice(i, 1);
446
+ onChange && onChange(list);
447
+ if (item.type === "polygon") {
448
+ mapUtilsRef.current.rmPolygon(item.id);
449
+ } else {
450
+ // 清除对应的 marker
451
+ mapUtilsRef.current.rmMarker(item.id);
452
+ // 清除对应的 circle
453
+ mapUtilsRef.current.rmCircle(item.id);
454
+ }
455
+ }
456
+
457
+ function onDelCancel(item, i) {
458
+ drawType.current = item.type || "marker";
459
+ if (item.type !== "polygon") {
460
+ clearActive();
461
+ setActiveId(null);
462
+ }
463
+ }
464
+
465
+ function setPoint(lng, lat) {
466
+ mapUtilsRef.current.setCenter(lng, lat, { immediately: true });
467
+ statusRef.current = "add";
468
+ currentItemRef.current = null;
469
+ popupRef.current?.onCancel();
470
+ handleMarker({
471
+ lnglat: {
472
+ lng,
473
+ lat,
474
+ },
475
+ });
476
+ }
477
+
478
+ function onMouseMove(e) {
479
+ const { offsetX, offsetY } = e;
480
+ setTipPosition({ left: offsetX + 10, top: offsetY + 10 });
481
+ }
482
+
483
+ return (
484
+ <div className="location-list-picker">
485
+ <div className="map-box" ref={mapBoxRef}>
486
+ <AMapCom init={mapInit} loading={loading} markerIconConf={markerIconConf} />
487
+ {!readOnly && !disabled && <MapSearch setPoint={setPoint} isAutoSearch={isAutoSearch} />}
488
+ {showTip && (
489
+ <Alert className="location-list-picker-notice-bar" message={tipText} type="info" style={tipPosition} />
490
+ )}
491
+ {hasPolygon && !readOnly && (
492
+ <Button className="add-polygon-btn" onClick={onDrawClick} disabled={disabled}>
493
+ 新增区域
494
+ </Button>
495
+ )}
496
+ {hasPoint !== false && !readOnly && (
497
+ <Button className="add-btn" onClick={onAddClick} disabled={disabled}>
498
+ 新增地址
499
+ </Button>
500
+ )}
501
+ <Popup ref={popupRef} mountElement={mapBoxRef.current} {...popupProps} />
502
+ </div>
503
+ <AddrList
504
+ {...listProps}
505
+ readOnly={readOnly}
506
+ disabled={disabled}
507
+ mapUtilsRef={mapUtilsRef}
508
+ activeId={activeId}
509
+ list={value}
510
+ ItemRender={ItemRender}
511
+ onItemClick={onItemClick}
512
+ onEdit={onEdit}
513
+ onDel={onDel}
514
+ onDelClick={onDelClick}
515
+ onDelCancel={onDelCancel}
516
+ />
517
+ </div>
518
+ );
519
+ });
520
+
521
+ export default LocationListPicker;