@hzab/form-render-mobile 0.2.2 → 0.2.3
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/lib/index.js +1 -1
- package/package.json +1 -1
- package/src/components/LocationPicker/Map/AMap/common/{loader.js → loader.ts} +1 -1
- package/src/components/LocationPicker/Map/AMap/common/utils.ts +129 -0
- package/src/components/LocationPicker/Map/AMap/index.jsx +6 -9
- package/src/components/LocationPicker/components/MapSearch/index.jsx +2 -1
- package/src/components/LocationPicker/components/Notice/index.tsx +15 -0
- package/src/components/LocationPicker/components/PickerInfo/index.less +17 -0
- package/src/components/LocationPicker/components/PickerInfo/index.tsx +73 -0
- package/src/components/LocationPicker/components/ResInfo/index.less +13 -0
- package/src/components/LocationPicker/components/ResInfo/index.tsx +48 -0
- package/src/components/LocationPicker/index.less +6 -33
- package/src/components/LocationPicker/index.tsx +66 -89
- package/src/components/LocationPicker/servers/index.ts +18 -6
- package/src/index.less +3 -0
- package/src/components/LocationPicker/Map/AMap/common/getCurrentPosition.js +0 -17
- package/src/components/LocationPicker/Map/AMap/common/utils.js +0 -53
package/package.json
CHANGED
|
@@ -34,7 +34,7 @@ function Loader(opt) {
|
|
|
34
34
|
|
|
35
35
|
window._AMapLoaderTemp.plugins = plugins ? [...defaultPlugins, ...(plugins || [])] : defaultPlugins;
|
|
36
36
|
|
|
37
|
-
//
|
|
37
|
+
// 不用地图组件时可以不安装 "@amap/amap-jsapi-loader"
|
|
38
38
|
const AMapLoader = require("@amap/amap-jsapi-loader");
|
|
39
39
|
|
|
40
40
|
window._AMapLoaderTemp.loading = true;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import AMapLoader from "./loader";
|
|
2
|
+
|
|
3
|
+
if (!window._AMapLoaderTemp) {
|
|
4
|
+
window._AMapLoaderTemp = {};
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function setKey(key, securityJsCode) {
|
|
8
|
+
window._AMapLoaderTemp.key = key;
|
|
9
|
+
window._AMapLoaderTemp.securityJsCode = securityJsCode;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function setServerKey(key, securityJsCode) {
|
|
13
|
+
window._AMapLoaderTemp.serverKey = key;
|
|
14
|
+
window._AMapLoaderTemp.serverSecurityJsCode = securityJsCode;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function setSecurityJsCode(securityJsCode) {
|
|
18
|
+
window._AMapLoaderTemp.securityJsCode = securityJsCode;
|
|
19
|
+
window._AMapSecurityConfig = {
|
|
20
|
+
securityJsCode: securityJsCode,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type setMarkerOptT = {
|
|
25
|
+
id?: number | string;
|
|
26
|
+
marker?: Object;
|
|
27
|
+
map?: Object;
|
|
28
|
+
AMap?: Object;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type markersT = {
|
|
32
|
+
[k: number | string]: Object;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export class MapUtils {
|
|
36
|
+
public map;
|
|
37
|
+
public AMap;
|
|
38
|
+
public markers: markersT = {};
|
|
39
|
+
public pickerMarker;
|
|
40
|
+
|
|
41
|
+
constructor({ map, AMap }) {
|
|
42
|
+
if (!map) {
|
|
43
|
+
throw new Error("请传入地图实例");
|
|
44
|
+
}
|
|
45
|
+
this.map = map;
|
|
46
|
+
this.AMap = AMap;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 获取地图中心点
|
|
51
|
+
* @param map
|
|
52
|
+
* @returns { lng: Number, lat: Number }
|
|
53
|
+
*/
|
|
54
|
+
getCenter(map = this.map) {
|
|
55
|
+
if (!map) {
|
|
56
|
+
throw new Error("请传入地图实例和 AMap");
|
|
57
|
+
}
|
|
58
|
+
return map && map.getCenter && map.getCenter();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 设置地图中心点
|
|
63
|
+
* @param lon
|
|
64
|
+
* @param lat
|
|
65
|
+
* @param opt
|
|
66
|
+
*/
|
|
67
|
+
setCenter(lon, lat, opt = { map: this.map, AMap: this.AMap || window.AMap }) {
|
|
68
|
+
const { map = this.map, AMap = this.AMap || window.AMap } = opt || {};
|
|
69
|
+
if (!(AMap && map)) {
|
|
70
|
+
throw new Error("请传入地图实例和 AMap");
|
|
71
|
+
}
|
|
72
|
+
const position = new window.AMap.LngLat(lon, lat);
|
|
73
|
+
// 设置中心点
|
|
74
|
+
map.setCenter(position);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 创建或修改 Marker
|
|
79
|
+
* @param lon
|
|
80
|
+
* @param lat
|
|
81
|
+
* @param opt
|
|
82
|
+
* @returns
|
|
83
|
+
*/
|
|
84
|
+
setMarker(lon, lat, opt?: setMarkerOptT) {
|
|
85
|
+
const { id = Date.now(), marker, map = this.map, AMap = this.AMap } = opt || {};
|
|
86
|
+
if (!(AMap && map)) {
|
|
87
|
+
throw new Error("请传入地图实例和 AMap");
|
|
88
|
+
}
|
|
89
|
+
const position = new AMap.LngLat(lon, lat);
|
|
90
|
+
let _marker = marker || this.markers[id];
|
|
91
|
+
// 创建 Marker 或修改位置
|
|
92
|
+
if (_marker) {
|
|
93
|
+
// @ts-ignore
|
|
94
|
+
_marker.setPosition(position);
|
|
95
|
+
return _marker;
|
|
96
|
+
}
|
|
97
|
+
const _m = new AMap.Marker({
|
|
98
|
+
position,
|
|
99
|
+
});
|
|
100
|
+
this.markers[id] = _m;
|
|
101
|
+
map?.add(_m);
|
|
102
|
+
return _m;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* 创建或修改地图选点的 Marker
|
|
107
|
+
* @param lon
|
|
108
|
+
* @param lat
|
|
109
|
+
* @param opt
|
|
110
|
+
* @returns
|
|
111
|
+
*/
|
|
112
|
+
setPickerMarker(lon, lat, opt?: any) {
|
|
113
|
+
const { marker = this.pickerMarker } = opt || {};
|
|
114
|
+
this.pickerMarker = this.setMarker(lon, lat, {
|
|
115
|
+
...opt,
|
|
116
|
+
marker,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
on(...args) {
|
|
121
|
+
return this.map?.on(...args);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
off(...args) {
|
|
125
|
+
return this.map?.off(...args);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export { AMapLoader };
|
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
import { useEffect, useRef } from "react";
|
|
2
2
|
|
|
3
|
+
import { MapUtils } from "./common/utils";
|
|
3
4
|
import AMapLoader from "./common/loader";
|
|
4
5
|
|
|
5
6
|
import "./index.less";
|
|
6
7
|
|
|
7
|
-
let map = null;
|
|
8
|
-
let AMap = null;
|
|
9
|
-
|
|
10
8
|
if (window._AMapLoaderTemp && window._AMapLoaderTemp.key) {
|
|
11
9
|
AMapLoader({
|
|
12
10
|
key: window._AMapLoaderTemp.key,
|
|
13
11
|
securityJsCode: window._AMapLoaderTemp.securityJsCode,
|
|
14
|
-
}).then((_AMap) => {
|
|
15
|
-
AMap = _AMap;
|
|
16
12
|
});
|
|
17
13
|
}
|
|
18
14
|
|
|
19
15
|
function AMapCom(props) {
|
|
20
16
|
const mapRef = useRef();
|
|
17
|
+
const mapDomRef = useRef();
|
|
21
18
|
|
|
22
19
|
useEffect(() => {
|
|
23
20
|
const { key, securityJsCode, plugins } = props;
|
|
@@ -27,21 +24,21 @@ function AMapCom(props) {
|
|
|
27
24
|
plugins,
|
|
28
25
|
}).then((AMap) => {
|
|
29
26
|
const { zoom, center, init } = props;
|
|
30
|
-
|
|
27
|
+
mapRef.current = new AMap.Map(mapDomRef.current, {
|
|
31
28
|
zoom: zoom || 11,
|
|
32
29
|
center: center || [120.160217, 30.243861],
|
|
33
30
|
});
|
|
34
|
-
init && init(map, AMap);
|
|
31
|
+
init && init({ map: mapRef.current, mapUtils: new MapUtils({ map: mapRef.current, AMap }), AMap });
|
|
35
32
|
});
|
|
36
33
|
}, []);
|
|
37
34
|
|
|
38
35
|
useEffect(() => {
|
|
39
36
|
if (Array.isArray(props.center) && props.center.length > 1) {
|
|
40
|
-
|
|
37
|
+
mapRef.current?.setCenter(props.center);
|
|
41
38
|
}
|
|
42
39
|
}, [props.center]);
|
|
43
40
|
|
|
44
|
-
return <div ref={
|
|
41
|
+
return <div ref={mapDomRef} className="a-map-container" style={props.style}></div>;
|
|
45
42
|
}
|
|
46
43
|
|
|
47
44
|
export default AMapCom;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useCallback, useState } from "react";
|
|
2
|
-
import { SearchBar, CheckList, Button } from "antd-mobile";
|
|
2
|
+
import { SearchBar, CheckList, Button, Toast } from "antd-mobile";
|
|
3
3
|
import { debounce } from "lodash";
|
|
4
4
|
|
|
5
5
|
import { getSearchTips } from "../../servers";
|
|
@@ -37,6 +37,7 @@ function Search(props) {
|
|
|
37
37
|
setLoading(false);
|
|
38
38
|
})
|
|
39
39
|
.catch((err) => {
|
|
40
|
+
Toast.show({ icon: "fail", content: err });
|
|
40
41
|
setLoading(false);
|
|
41
42
|
});
|
|
42
43
|
}, 500),
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { NoticeBar } from "antd-mobile";
|
|
2
|
+
import { ExclamationCircleOutline } from "antd-mobile-icons";
|
|
3
|
+
|
|
4
|
+
export const Notice = (props) => {
|
|
5
|
+
return (
|
|
6
|
+
<NoticeBar
|
|
7
|
+
className="location-picker-notice-bar"
|
|
8
|
+
content={props.changeMode === "click" ? "点击地图上的位置,选择目标地址" : "拖拽移动地图,中心标点为目标地址"}
|
|
9
|
+
color="default"
|
|
10
|
+
icon={<ExclamationCircleOutline />}
|
|
11
|
+
/>
|
|
12
|
+
);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default Notice;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
.location-picker-info {
|
|
2
|
+
padding: 2vw 4vw;
|
|
3
|
+
.picker-info-lon,
|
|
4
|
+
.picker-info-lat,
|
|
5
|
+
.picker-info-addr {
|
|
6
|
+
display: flex;
|
|
7
|
+
.picker-info-label {
|
|
8
|
+
white-space: nowrap;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
.picker-info-lon {
|
|
12
|
+
}
|
|
13
|
+
.picker-info-lat {
|
|
14
|
+
}
|
|
15
|
+
.picker-info-addr {
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Input, DotLoading } from "antd-mobile";
|
|
2
|
+
|
|
3
|
+
import "./index.less";
|
|
4
|
+
|
|
5
|
+
export const PickerInfo = (props) => {
|
|
6
|
+
const { pickInfo, setPickInfo, setPoint, addrLoading, defaultLngLat } = props;
|
|
7
|
+
|
|
8
|
+
function onPILonChange(e) {
|
|
9
|
+
const val = +(e.target?.value || e || defaultLngLat.lon);
|
|
10
|
+
let res = null;
|
|
11
|
+
setPickInfo((info) => {
|
|
12
|
+
res = {
|
|
13
|
+
...info,
|
|
14
|
+
lon: val,
|
|
15
|
+
center: [val, info.lat],
|
|
16
|
+
};
|
|
17
|
+
return res;
|
|
18
|
+
});
|
|
19
|
+
return res;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function onPILatChange(e) {
|
|
23
|
+
const val = +(e.target?.value || e || defaultLngLat.lat);
|
|
24
|
+
let res = null;
|
|
25
|
+
setPickInfo((info) => {
|
|
26
|
+
res = {
|
|
27
|
+
...info,
|
|
28
|
+
lat: val,
|
|
29
|
+
center: [info.lon, val],
|
|
30
|
+
};
|
|
31
|
+
return res;
|
|
32
|
+
});
|
|
33
|
+
return res;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 失去焦点之后,地图居中
|
|
38
|
+
* @param e
|
|
39
|
+
*/
|
|
40
|
+
function onPILonBlur(e) {
|
|
41
|
+
const res = onPILonChange(e);
|
|
42
|
+
setPoint(res.lon, res.lat);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 失去焦点之后,地图居中
|
|
47
|
+
* @param e
|
|
48
|
+
*/
|
|
49
|
+
function onPILatBlur(e) {
|
|
50
|
+
const res = onPILatChange(e);
|
|
51
|
+
setPoint(res.lon, res.lat);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<div className="location-picker-info">
|
|
56
|
+
<div className="picker-info-lon">
|
|
57
|
+
<div className="picker-info-label">经度:</div>
|
|
58
|
+
<Input value={pickInfo.lon} onChange={onPILonChange} onBlur={onPILonBlur} />
|
|
59
|
+
</div>
|
|
60
|
+
<div className="picker-info-lat">
|
|
61
|
+
<div className="picker-info-label">纬度:</div>
|
|
62
|
+
|
|
63
|
+
<Input value={pickInfo.lat} onChange={onPILatChange} onBlur={onPILatBlur} />
|
|
64
|
+
</div>
|
|
65
|
+
<div className="picker-info-addr">
|
|
66
|
+
<div className="picker-info-label">地址:</div>
|
|
67
|
+
{addrLoading ? <DotLoading /> : pickInfo.addr}
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default PickerInfo;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { Button } from "antd-mobile";
|
|
3
|
+
import { LocationFill } from "antd-mobile-icons";
|
|
4
|
+
import { useField } from "@formily/react";
|
|
5
|
+
|
|
6
|
+
import { getPropsValue } from "../../common/utils";
|
|
7
|
+
|
|
8
|
+
import "./index.less";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 展示 form 表单当前项的数据
|
|
12
|
+
* @param props
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
export const ResInfo = (props) => {
|
|
16
|
+
const { onShow, isObjectRes, lonKey, latKey, addrKey, value, pickerText = "选点" } = props || {};
|
|
17
|
+
const field: any = useField();
|
|
18
|
+
|
|
19
|
+
// 数据格式转为内部格式,方便存取
|
|
20
|
+
const formatVal = useMemo(
|
|
21
|
+
() =>
|
|
22
|
+
getPropsValue(value, field, {
|
|
23
|
+
isObjectRes,
|
|
24
|
+
lonKey,
|
|
25
|
+
latKey,
|
|
26
|
+
addrKey,
|
|
27
|
+
}),
|
|
28
|
+
[isObjectRes, lonKey, latKey, addrKey, value, field.data],
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<div className="location-value-box">
|
|
33
|
+
<div className="location-value-head-box">
|
|
34
|
+
<div className="location-lon-lat">
|
|
35
|
+
<div>经度:{formatVal.lon} </div>
|
|
36
|
+
<div>纬度:{formatVal.lat}</div>
|
|
37
|
+
</div>
|
|
38
|
+
<Button className="location-btn" color="primary" fill="none" onClick={onShow}>
|
|
39
|
+
<LocationFill />
|
|
40
|
+
{pickerText}
|
|
41
|
+
</Button>
|
|
42
|
+
</div>
|
|
43
|
+
<div>地址:{formatVal.addr}</div>
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export default ResInfo;
|
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
.location-picker {
|
|
2
|
-
.location-value-box {
|
|
3
|
-
.location-value-head-box {
|
|
4
|
-
display: flex;
|
|
5
|
-
.location-lon-lat {
|
|
6
|
-
flex: 1;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.location-btn {
|
|
11
|
-
padding: 4px 0;
|
|
12
|
-
padding-left: 5px;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
2
|
}
|
|
16
3
|
|
|
17
4
|
.location-picker-popup {
|
|
5
|
+
.location-popup-content {
|
|
6
|
+
position: relative;
|
|
7
|
+
}
|
|
18
8
|
.adm-popup-body {
|
|
19
9
|
display: flex;
|
|
20
10
|
flex-direction: column;
|
|
@@ -26,23 +16,6 @@
|
|
|
26
16
|
border-bottom: 1px solid #f2f2f2;
|
|
27
17
|
}
|
|
28
18
|
|
|
29
|
-
.picker-info {
|
|
30
|
-
padding: 2vw 4vw;
|
|
31
|
-
.picker-info-lon,
|
|
32
|
-
.picker-info-lat {
|
|
33
|
-
display: inline-block;
|
|
34
|
-
}
|
|
35
|
-
.picker-info-lon {
|
|
36
|
-
margin-right: 4vw;
|
|
37
|
-
}
|
|
38
|
-
.picker-info-lat {
|
|
39
|
-
}
|
|
40
|
-
.picker-info-addr {
|
|
41
|
-
margin-top: 2vw;
|
|
42
|
-
line-height: 1.6;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
19
|
.location-picker-map {
|
|
47
20
|
position: relative;
|
|
48
21
|
width: 100%;
|
|
@@ -59,10 +32,10 @@
|
|
|
59
32
|
|
|
60
33
|
.location-picker-notice-bar {
|
|
61
34
|
position: absolute;
|
|
62
|
-
|
|
35
|
+
top: 0;
|
|
63
36
|
left: 0;
|
|
64
37
|
width: 100vw;
|
|
65
|
-
--background-color: rgba(0, 0, 0,
|
|
38
|
+
--background-color: rgba(0, 0, 0, 0.6);
|
|
66
39
|
}
|
|
67
40
|
|
|
68
41
|
.location-picker-center-icon {
|
|
@@ -85,7 +58,7 @@
|
|
|
85
58
|
display: flex;
|
|
86
59
|
align-items: center;
|
|
87
60
|
justify-content: center;
|
|
88
|
-
background-color: rgba(0, 0, 0, 0.
|
|
61
|
+
background-color: rgba(0, 0, 0, 0.3);
|
|
89
62
|
.spin-loading {
|
|
90
63
|
}
|
|
91
64
|
}
|