@hzab/form-render-mobile 0.2.2 → 0.2.4
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/common/utils.ts +0 -4
- package/src/components/LocationPicker/components/MapSearch/index.jsx +2 -1
- package/src/components/LocationPicker/components/ModalContent/index.less +48 -0
- package/src/components/LocationPicker/components/ModalContent/index.tsx +202 -0
- 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 +78 -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 +4 -77
- package/src/components/LocationPicker/index.tsx +130 -219
- package/src/components/LocationPicker/servers/index.ts +18 -6
- package/src/index.less +6 -1
- 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,48 @@
|
|
|
1
|
+
.location-picker-modal-content {
|
|
2
|
+
position: relative;
|
|
3
|
+
|
|
4
|
+
.location-picker-map {
|
|
5
|
+
position: relative;
|
|
6
|
+
width: 100%;
|
|
7
|
+
flex: 1;
|
|
8
|
+
.a-map-container {
|
|
9
|
+
height: inherit;
|
|
10
|
+
.amap-logo,
|
|
11
|
+
.amap-copyright {
|
|
12
|
+
z-index: 0;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.location-picker-center-icon {
|
|
17
|
+
position: absolute;
|
|
18
|
+
top: 50%;
|
|
19
|
+
left: 50%;
|
|
20
|
+
transform: translate(-50%, -100%);
|
|
21
|
+
font-size: 32px;
|
|
22
|
+
color: #1890ff;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.spin-loading-wrap {
|
|
27
|
+
position: absolute;
|
|
28
|
+
top: 0;
|
|
29
|
+
left: 0;
|
|
30
|
+
right: 0;
|
|
31
|
+
bottom: 0;
|
|
32
|
+
z-index: 9;
|
|
33
|
+
display: flex;
|
|
34
|
+
align-items: center;
|
|
35
|
+
justify-content: center;
|
|
36
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
37
|
+
.spin-loading {
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/* 水平样式 */
|
|
41
|
+
&.location-modal-content-layout-hor {
|
|
42
|
+
display: flex;
|
|
43
|
+
|
|
44
|
+
.location-picker-info {
|
|
45
|
+
width: 50vw;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { SpinLoading, Toast } from "antd-mobile";
|
|
3
|
+
import { LocationFill } from "antd-mobile-icons";
|
|
4
|
+
import { useField } from "@formily/react";
|
|
5
|
+
import { debounce } from "lodash";
|
|
6
|
+
|
|
7
|
+
import PickerInfo from "../PickerInfo";
|
|
8
|
+
import AMapCom from "../../Map/AMap";
|
|
9
|
+
import Notice from "../Notice";
|
|
10
|
+
import MapSearch from "../MapSearch";
|
|
11
|
+
|
|
12
|
+
import { MapUtils } from "../../Map/AMap/common/utils";
|
|
13
|
+
import { getAddress } from "../../servers";
|
|
14
|
+
import { getPropsValue } from "../../common/utils";
|
|
15
|
+
|
|
16
|
+
import "./index.less";
|
|
17
|
+
|
|
18
|
+
export const ModalContent = (props) => {
|
|
19
|
+
const {
|
|
20
|
+
/**
|
|
21
|
+
* 选择器和地图的布局
|
|
22
|
+
* 水平 hor
|
|
23
|
+
* 垂直 ver
|
|
24
|
+
*/
|
|
25
|
+
layout = "ver",
|
|
26
|
+
// 是否允许搜索
|
|
27
|
+
hasSearch = true,
|
|
28
|
+
/**
|
|
29
|
+
*
|
|
30
|
+
isObjectRes
|
|
31
|
+
true: 把所有数据存放在一个对象中(该对象和其他表单项平级),对象 key 为当前项的 name
|
|
32
|
+
false: 所有数据打平放到当前的 data 中,和其他表单项平级
|
|
33
|
+
*/
|
|
34
|
+
isObjectRes = true,
|
|
35
|
+
/**
|
|
36
|
+
* 打开地图时是否根据经纬度自动修正已填的地址
|
|
37
|
+
*/
|
|
38
|
+
isAutoFixAddr = false,
|
|
39
|
+
/**
|
|
40
|
+
* 改变经纬度等数据的触发模式
|
|
41
|
+
* 移动地图 move
|
|
42
|
+
* 点击地图 click
|
|
43
|
+
*/
|
|
44
|
+
changeMode = "move",
|
|
45
|
+
lonKey = "longitude",
|
|
46
|
+
latKey = "latitude",
|
|
47
|
+
addrKey = "address",
|
|
48
|
+
value,
|
|
49
|
+
// 搜索框是否自动搜索
|
|
50
|
+
isAutoSearch = true,
|
|
51
|
+
//
|
|
52
|
+
visible,
|
|
53
|
+
defaultLocation,
|
|
54
|
+
} = props;
|
|
55
|
+
|
|
56
|
+
const field: any = useField();
|
|
57
|
+
|
|
58
|
+
const mapUtilsRef = useRef<MapUtils>();
|
|
59
|
+
|
|
60
|
+
// 数据格式转为内部格式,方便存取
|
|
61
|
+
const formatVal = useMemo(
|
|
62
|
+
() =>
|
|
63
|
+
getPropsValue(value, field, {
|
|
64
|
+
isObjectRes,
|
|
65
|
+
lonKey,
|
|
66
|
+
latKey,
|
|
67
|
+
addrKey,
|
|
68
|
+
}),
|
|
69
|
+
[isObjectRes, lonKey, latKey, addrKey, value, field.data],
|
|
70
|
+
);
|
|
71
|
+
const [loading, setLoading] = useState(false);
|
|
72
|
+
const [addrLoading, setAddrLoading] = useState(false);
|
|
73
|
+
// 地图选点组件选中的值
|
|
74
|
+
const [pickInfo, setPickInfo] = useState(formatVal);
|
|
75
|
+
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (visible) {
|
|
78
|
+
let _lon = defaultLocation.lon;
|
|
79
|
+
let _lat = defaultLocation.lat;
|
|
80
|
+
if (formatVal.lon && formatVal.lat) {
|
|
81
|
+
_lon = formatVal.lon;
|
|
82
|
+
_lat = formatVal.lat;
|
|
83
|
+
}
|
|
84
|
+
// 解决关闭弹窗之后点位不居中的问题
|
|
85
|
+
if (window.AMap && window.AMap.LngLat) {
|
|
86
|
+
setMapCenter(_lon, _lat);
|
|
87
|
+
}
|
|
88
|
+
setPickPoint(_lon, _lat, { isAutoFixAddr: false });
|
|
89
|
+
}
|
|
90
|
+
}, [visible, formatVal, changeMode]);
|
|
91
|
+
|
|
92
|
+
function mapInit({ map, mapUtils }) {
|
|
93
|
+
mapUtilsRef.current = mapUtils;
|
|
94
|
+
let _lon = defaultLocation.lon;
|
|
95
|
+
let _lat = defaultLocation.lat;
|
|
96
|
+
if (pickInfo.lon && pickInfo.lat) {
|
|
97
|
+
_lon = pickInfo.lon;
|
|
98
|
+
_lat = pickInfo.lat;
|
|
99
|
+
}
|
|
100
|
+
setPickPoint(_lon, _lat, { isAutoFixAddr });
|
|
101
|
+
|
|
102
|
+
setMapCenter(_lon, _lat);
|
|
103
|
+
setLoading(false);
|
|
104
|
+
|
|
105
|
+
if (changeMode === "click") {
|
|
106
|
+
mapUtilsRef.current?.setPickerMarker(_lon, _lat);
|
|
107
|
+
// 点击选中点位的情况
|
|
108
|
+
mapUtilsRef.current.on("click", function (ev) {
|
|
109
|
+
const { lng: evLon, lat: evLat } = ev.lnglat || {};
|
|
110
|
+
setPickPoint(evLon, evLat, { changeCenter: true });
|
|
111
|
+
});
|
|
112
|
+
} else {
|
|
113
|
+
// 移动地图
|
|
114
|
+
mapUtilsRef.current.on(
|
|
115
|
+
"touchend",
|
|
116
|
+
debounce(function (ev) {
|
|
117
|
+
let currentCenter = mapUtilsRef.current?.getCenter();
|
|
118
|
+
const { lng: centerLon, lat: centerLat } = currentCenter || {};
|
|
119
|
+
// 移动选中点位的情况
|
|
120
|
+
let _lon = centerLon;
|
|
121
|
+
let _lat = centerLat;
|
|
122
|
+
setPickPoint(_lon, _lat);
|
|
123
|
+
}, 1000),
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* 设置地图中心点
|
|
130
|
+
* @param lon
|
|
131
|
+
* @param lat
|
|
132
|
+
*/
|
|
133
|
+
function setMapCenter(lon, lat) {
|
|
134
|
+
mapUtilsRef.current?.setCenter(lon, lat);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function setPickPoint(_lon, _lat, opt?: any) {
|
|
138
|
+
const { isAutoFixAddr: _isAutoFixAddr = isAutoFixAddr || true, changeCenter } = opt || {};
|
|
139
|
+
const lon = _lon || pickInfo.lon;
|
|
140
|
+
const lat = _lat || pickInfo.lat;
|
|
141
|
+
if (changeMode === "click") {
|
|
142
|
+
mapUtilsRef.current?.setPickerMarker(_lon, _lat);
|
|
143
|
+
}
|
|
144
|
+
if (changeCenter) {
|
|
145
|
+
setMapCenter(_lon, _lat);
|
|
146
|
+
}
|
|
147
|
+
const addr = _isAutoFixAddr || !pickInfo.addr ? await getAddr(lon, lat) : pickInfo.addr;
|
|
148
|
+
const res = { ...pickInfo, lon, lat, addr };
|
|
149
|
+
setPickInfo(res);
|
|
150
|
+
props.setPickInfo && props.setPickInfo(res);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function getAddr(_lng, _lat) {
|
|
154
|
+
return new Promise((resolve, reject) => {
|
|
155
|
+
if (!window.AMap) {
|
|
156
|
+
reject();
|
|
157
|
+
return new Error("window.AMap is not defined");
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
setAddrLoading(true);
|
|
161
|
+
getAddress(_lng, _lat)
|
|
162
|
+
.then((addr) => {
|
|
163
|
+
setAddrLoading(false);
|
|
164
|
+
setPickInfo((_p) => ({ ..._p, addr }));
|
|
165
|
+
resolve(addr);
|
|
166
|
+
})
|
|
167
|
+
.catch((err) => {
|
|
168
|
+
reject(err);
|
|
169
|
+
Toast.show({ icon: "fail", content: err });
|
|
170
|
+
setAddrLoading(false);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return (
|
|
176
|
+
<div className={`location-picker-modal-content location-modal-content-layout-${layout}`}>
|
|
177
|
+
{/* 点击/移动 地图选中的数据 */}
|
|
178
|
+
<PickerInfo
|
|
179
|
+
pickInfo={pickInfo}
|
|
180
|
+
setPickInfo={setPickInfo}
|
|
181
|
+
setPoint={setPickPoint}
|
|
182
|
+
addrLoading={addrLoading}
|
|
183
|
+
defaultLocation={defaultLocation}
|
|
184
|
+
/>
|
|
185
|
+
|
|
186
|
+
<div className="location-picker-map">
|
|
187
|
+
{/* 关闭弹窗之后清除搜索内容 */}
|
|
188
|
+
{hasSearch && visible ? <MapSearch setPoint={setPickPoint} isAutoSearch={isAutoSearch} /> : null}
|
|
189
|
+
<AMapCom init={mapInit} loading={loading} style={{ height: "66vh" }} />
|
|
190
|
+
{!loading && changeMode !== "click" && <LocationFill className="location-picker-center-icon" />}
|
|
191
|
+
<Notice changeMode={changeMode} />
|
|
192
|
+
</div>
|
|
193
|
+
{loading && (
|
|
194
|
+
<div className="spin-loading-wrap">
|
|
195
|
+
<SpinLoading className="spin-loading" />
|
|
196
|
+
</div>
|
|
197
|
+
)}
|
|
198
|
+
</div>
|
|
199
|
+
);
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
export default ModalContent;
|
|
@@ -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,78 @@
|
|
|
1
|
+
import { Input, DotLoading } from "antd-mobile";
|
|
2
|
+
|
|
3
|
+
import "./index.less";
|
|
4
|
+
|
|
5
|
+
export const PickerInfo = (props) => {
|
|
6
|
+
const { pickInfo, setPickInfo, setPoint, addrLoading, defaultLocation } = props;
|
|
7
|
+
|
|
8
|
+
function onPILonChange(e) {
|
|
9
|
+
const val = e?.target?.value ?? e;
|
|
10
|
+
const res: { lon; lat; addr } = { ...pickInfo };
|
|
11
|
+
res.lon = val;
|
|
12
|
+
setPickInfo(res);
|
|
13
|
+
return res;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function onPILatChange(e) {
|
|
17
|
+
const val = e?.target?.value ?? e;
|
|
18
|
+
const res: { lon; lat; addr } = { ...pickInfo };
|
|
19
|
+
res.lat = val;
|
|
20
|
+
setPickInfo(res);
|
|
21
|
+
return res;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 失去焦点之后,地图居中
|
|
26
|
+
* @param e
|
|
27
|
+
*/
|
|
28
|
+
function onPILonBlur(e) {
|
|
29
|
+
const res = onPILonChange(e);
|
|
30
|
+
setPoint && setPoint(res?.lon || defaultLocation.lon, res?.lat || defaultLocation.lat, { changeCenter: true });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 失去焦点之后,地图居中
|
|
35
|
+
* @param e
|
|
36
|
+
*/
|
|
37
|
+
function onPILatBlur(e) {
|
|
38
|
+
const res = onPILatChange(e);
|
|
39
|
+
setPoint && setPoint(res?.lon || defaultLocation.lon, res?.lat || defaultLocation.lat, { changeCenter: true });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div className="location-picker-info">
|
|
44
|
+
<div className="picker-info-lon">
|
|
45
|
+
<div className="picker-info-label">经度:</div>
|
|
46
|
+
<Input
|
|
47
|
+
className="picker-info-input"
|
|
48
|
+
disabled={addrLoading}
|
|
49
|
+
max={180}
|
|
50
|
+
min={-180}
|
|
51
|
+
value={pickInfo.lon}
|
|
52
|
+
onChange={onPILonChange}
|
|
53
|
+
onBlur={onPILonBlur}
|
|
54
|
+
onEnterPress={onPILonBlur}
|
|
55
|
+
/>
|
|
56
|
+
</div>
|
|
57
|
+
<div className="picker-info-lat">
|
|
58
|
+
<div className="picker-info-label">纬度:</div>
|
|
59
|
+
<Input
|
|
60
|
+
className="picker-info-input"
|
|
61
|
+
disabled={addrLoading}
|
|
62
|
+
max={90}
|
|
63
|
+
min={-90}
|
|
64
|
+
value={pickInfo.lat}
|
|
65
|
+
onChange={onPILatChange}
|
|
66
|
+
onBlur={onPILatBlur}
|
|
67
|
+
onEnterPress={onPILatBlur}
|
|
68
|
+
/>
|
|
69
|
+
</div>
|
|
70
|
+
<div className="picker-info-addr">
|
|
71
|
+
<div className="picker-info-label">地址:</div>
|
|
72
|
+
{addrLoading ? <DotLoading /> : pickInfo.addr}
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
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;
|