@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.
@@ -1,10 +1,16 @@
1
1
  import { useEffect, useMemo, useRef, useState } from "react";
2
- import { Popup, Button, SpinLoading, DotLoading, NoticeBar } from "antd-mobile";
2
+ import { Popup, Button, SpinLoading, Toast } from "antd-mobile";
3
3
  import { useField, useFieldSchema } from "@formily/react";
4
- import { LocationFill, ExclamationCircleOutline } from "antd-mobile-icons";
4
+ import { LocationFill } from "antd-mobile-icons";
5
5
  import { debounce } from "lodash";
6
6
 
7
+ import ResInfo from "./components/ResInfo";
8
+
9
+ import PickerInfo from "./components/PickerInfo";
7
10
  import AMapCom from "./Map/AMap";
11
+ import Notice from "./components/Notice";
12
+
13
+ import { MapUtils } from "./Map/AMap/common/utils";
8
14
  import { getCurrentPosition } from "../../common/location-utils";
9
15
  import MapSearch from "./components/MapSearch";
10
16
 
@@ -18,8 +24,6 @@ const defaultLngLat = {
18
24
  lat: 30.243861,
19
25
  };
20
26
 
21
- declare var AMap: any;
22
-
23
27
  // 获取当前经纬度
24
28
  getCurrentPosition()
25
29
  .then((res) => {
@@ -58,14 +62,16 @@ export function LocationPicker(props) {
58
62
  value,
59
63
  // 搜索框是否自动搜索
60
64
  isAutoSearch = true,
65
+ // 是否是移动端,changeMode == 'move' 时改变监听事件
66
+ isMobile = true,
61
67
  } = props;
62
68
  const field: any = useField();
63
69
  const fieldSchema = useFieldSchema();
64
70
 
65
- const mapRef: any = useRef();
66
- const markerRef: any = useRef();
71
+ const mapUtilsRef = useRef<MapUtils>();
67
72
 
68
73
  const [loading, setLoading] = useState(false);
74
+ const [addrLoading, setAddrLoading] = useState(false);
69
75
  const [visible, setVisible] = useState(false);
70
76
  // 数据格式转为内部格式,方便存取
71
77
  const opt = {
@@ -80,42 +86,31 @@ export function LocationPicker(props) {
80
86
  [isObjectRes, lonKey, latKey, addrKey, value, field.data],
81
87
  );
82
88
 
83
- // 表单实际的值
84
- const [resInfo, setResInfo] = useState(formatVal);
85
89
  // 地图选点组件选中的值
86
90
  const [pickInfo, setPickInfo] = useState(formatVal);
87
- const [addrLoading, setAddrLoading] = useState(false);
88
91
 
89
92
  useEffect(() => {
90
93
  if (visible) {
91
94
  let _lon = defaultLngLat.lon;
92
95
  let _lat = defaultLngLat.lat;
93
- if (resInfo.lon && resInfo.lat) {
94
- _lon = resInfo.lon;
95
- _lat = resInfo.lat;
96
+ if (formatVal.lon && formatVal.lat) {
97
+ _lon = formatVal.lon;
98
+ _lat = formatVal.lat;
96
99
  }
97
100
  // 解决关闭弹窗之后点位不居中的问题
98
101
  if (window.AMap && window.AMap.LngLat) {
99
- const position = new window.AMap.LngLat(_lon, _lat);
100
- mapRef.current?.setCenter(position);
102
+ setMapCenter(_lon, _lat);
101
103
  }
102
104
  setPoint(_lon, _lat, { isAutoFixAddr: false });
103
105
  }
104
- }, [visible, resInfo, changeMode]);
106
+ }, [visible, formatVal, changeMode]);
105
107
 
106
108
  useEffect(() => {
107
- setResInfo((_res) => {
108
- const { lon: _lon, lat: _lat, addr: _addr } = formatVal;
109
- if ((_lon && _lon != _res.lon) || (_lat && _lat != _res.lat)) {
110
- setPoint(_lon, _lat, { isAutoFixAddr });
111
- }
112
- return formatVal;
113
- });
114
109
  setPickInfo(formatVal);
115
110
  }, [formatVal, isAutoFixAddr]);
116
111
 
117
- function mapInit(_map, AMap) {
118
- mapRef.current = _map;
112
+ function mapInit({ map, mapUtils }) {
113
+ mapUtilsRef.current = mapUtils;
119
114
  setLoading(false);
120
115
  let _lon = defaultLngLat.lon;
121
116
  let _lat = defaultLngLat.lat;
@@ -125,45 +120,37 @@ export function LocationPicker(props) {
125
120
  }
126
121
  setPoint(_lon, _lat, { isAutoFixAddr });
127
122
 
123
+ setMapCenter(_lon, _lat);
128
124
  if (changeMode === "click") {
129
- setMarker(_lon, _lat);
125
+ mapUtilsRef.current?.setPickerMarker(_lon, _lat);
130
126
  // 点击选中点位的情况
131
- mapRef.current.on("click", function (ev) {
127
+ mapUtilsRef.current.on("click", function (ev) {
132
128
  const { lng: evLon, lat: evLat } = ev.lnglat || {};
133
129
  setPoint(evLon, evLat, { changeCenter: true });
134
130
  });
135
131
  } else {
136
132
  // 移动地图
137
- mapRef.current.on(
138
- "moveend",
133
+ mapUtilsRef.current.on(
134
+ isMobile ? "touchend" : "mouseup",
139
135
  debounce(function (ev) {
140
- let currentCenter = mapRef.current.getCenter();
136
+ let currentCenter = mapUtilsRef.current?.getCenter();
141
137
  const { lng: centerLon, lat: centerLat } = currentCenter || {};
142
138
  // 移动选中点位的情况
143
139
  let _lon = centerLon;
144
140
  let _lat = centerLat;
145
141
  setPoint(_lon, _lat);
146
- }, 500),
142
+ }, 1000),
147
143
  );
148
144
  }
149
145
  }
150
146
 
151
- function setMarker(_lon, _lat) {
152
- if (changeMode !== "click") {
153
- return;
154
- }
155
- if (window.AMap && mapRef.current) {
156
- const position = new AMap.LngLat(_lon, _lat);
157
- // 创建 Marker 或修改位置
158
- if (markerRef.current) {
159
- markerRef.current.setPosition(position);
160
- } else {
161
- markerRef.current = new AMap.Marker({
162
- position,
163
- });
164
- mapRef.current?.add(markerRef.current);
165
- }
166
- }
147
+ /**
148
+ * 设置地图中心点
149
+ * @param lon
150
+ * @param lat
151
+ */
152
+ function setMapCenter(lon, lat) {
153
+ mapUtilsRef.current?.setCenter(lon, lat);
167
154
  }
168
155
 
169
156
  function setPoint(_lon, _lat, opt?: any) {
@@ -173,11 +160,11 @@ export function LocationPicker(props) {
173
160
  (_isAutoFixAddr || !pickInfo.addr) && getAddr(lon, lat);
174
161
  const res = { ...pickInfo, lon, lat, center: [lon, lat] };
175
162
  setPickInfo(res);
176
- setMarker(_lon, _lat);
163
+ if (changeMode === "click") {
164
+ mapUtilsRef.current?.setPickerMarker(_lon, _lat);
165
+ }
177
166
  if (changeCenter) {
178
- const position = new AMap.LngLat(_lon, _lat);
179
- // 设置中心点
180
- mapRef.current.setCenter(position);
167
+ setMapCenter(_lon, _lat);
181
168
  }
182
169
  }
183
170
 
@@ -193,17 +180,20 @@ export function LocationPicker(props) {
193
180
  setPickInfo((_p) => ({ ..._p, addr }));
194
181
  })
195
182
  .catch((err) => {
183
+ Toast.show({ icon: "fail", content: err });
196
184
  setAddrLoading(false);
197
185
  });
198
186
  }
199
187
 
200
188
  function onShow() {
201
- !mapRef.current && setLoading(true);
189
+ // 等待地图加载完毕
190
+ !mapUtilsRef.current && setVisible(true);
202
191
  setVisible(true);
203
192
  }
204
193
 
205
194
  function onClose() {
206
195
  setVisible(false);
196
+ setLoading(false);
207
197
  }
208
198
 
209
199
  function onOk() {
@@ -231,19 +221,9 @@ export function LocationPicker(props) {
231
221
 
232
222
  return (
233
223
  <div className="location-picker">
234
- <div className="location-value-box">
235
- <div className="location-value-head-box">
236
- <div className="location-lon-lat">
237
- <div>经度:{resInfo.lon} </div>
238
- <div>纬度:{resInfo.lat}</div>
239
- </div>
240
- <Button className="location-btn" color="primary" fill="none" onClick={onShow}>
241
- <LocationFill />
242
- 选点
243
- </Button>
244
- </div>
245
- <div>地址:{resInfo.addr}</div>
246
- </div>
224
+ {/* 显示表单选中的结果 */}
225
+ <ResInfo {...props} onShow={onShow} />
226
+ {/* 弹窗 */}
247
227
  <Popup
248
228
  maskClassName="location-picker-popup-mask"
249
229
  className="location-picker-popup"
@@ -263,33 +243,30 @@ export function LocationPicker(props) {
263
243
  确认
264
244
  </Button>
265
245
  </div>
266
- <div className="picker-info">
267
- <div className="picker-info-lon">经度:{pickInfo.lon} </div>
268
- <div className="picker-info-lat">纬度:{pickInfo.lat}</div>
269
- <div className="picker-info-addr">地址:{addrLoading ? <DotLoading /> : pickInfo.addr}</div>
270
- </div>
271
- {/* 关闭弹窗之后清除搜索内容 */}
272
- {hasSearch && visible ? <MapSearch setPoint={setPoint} isAutoSearch={isAutoSearch} /> : null}
273
- <div className="location-picker-map">
274
- <AMapCom
275
- init={mapInit}
276
- loading={loading}
277
- center={pickInfo.center ? pickInfo.center : [defaultLngLat.lon, defaultLngLat.lat]}
278
- style={{ height: "68vh" }}
279
- />
280
- <NoticeBar
281
- className="location-picker-notice-bar"
282
- content={changeMode === "click" ? "点击地图上的位置,选择目标地址" : "拖拽移动地图,中心标点为目标地址"}
283
- color="default"
284
- icon={<ExclamationCircleOutline />}
246
+
247
+ <div className="location-popup-content">
248
+ {/* 点击/移动 地图选中的数据 */}
249
+ <PickerInfo
250
+ pickInfo={pickInfo}
251
+ setPickInfo={setPickInfo}
252
+ setPoint={setPoint}
253
+ addrLoading={addrLoading}
254
+ defaultLngLat={defaultLngLat}
285
255
  />
286
- {!loading && changeMode !== "click" && <LocationFill className="location-picker-center-icon" />}
287
- </div>
288
- {loading && (
289
- <div className="spin-loading-wrap">
290
- <SpinLoading className="spin-loading" color="primary" />
256
+
257
+ {/* 关闭弹窗之后清除搜索内容 */}
258
+ {hasSearch && visible ? <MapSearch setPoint={setPoint} isAutoSearch={isAutoSearch} /> : null}
259
+ <div className="location-picker-map">
260
+ <AMapCom init={mapInit} loading={loading} style={{ height: "68vh" }} />
261
+ <Notice changeMode={changeMode} />
262
+ {!loading && changeMode !== "click" && <LocationFill className="location-picker-center-icon" />}
291
263
  </div>
292
- )}
264
+ {loading && (
265
+ <div className="spin-loading-wrap">
266
+ <SpinLoading className="spin-loading" color="primary" />
267
+ </div>
268
+ )}
269
+ </div>
293
270
  </Popup>
294
271
  </div>
295
272
  );
@@ -1,5 +1,9 @@
1
- import { Toast } from "antd-mobile";
2
-
1
+ /**
2
+ * 根据经纬度获取定义的地址
3
+ * @param lon
4
+ * @param lat
5
+ * @returns
6
+ */
3
7
  export function getAddress(lon, lat) {
4
8
  return new Promise((resolve, reject) => {
5
9
  if (!window.AMap) {
@@ -15,7 +19,7 @@ export function getAddress(lon, lat) {
15
19
  } else if (result === "USER_DAILY_QUERY_OVER_LIMIT") {
16
20
  // 超出限制,使用 webServer 进行请求
17
21
  if (!window._AMapLoaderTemp.serverKey) {
18
- Toast.show({ icon: "fail", content: "超出使用限制,请联系管理员" });
22
+ reject(new Error("超出使用限制,请联系管理员"));
19
23
  return;
20
24
  }
21
25
  fetch(
@@ -31,7 +35,8 @@ export function getAddress(lon, lat) {
31
35
  if (res.status === "1") {
32
36
  resolve(res.regeocode?.formatted_address);
33
37
  } else {
34
- Toast.show({ icon: "fail", content: res.info });
38
+ console.warn("Warn getAddress fetch: ", res);
39
+ reject(new Error(res.info));
35
40
  }
36
41
  })
37
42
  .catch(reject);
@@ -42,6 +47,12 @@ export function getAddress(lon, lat) {
42
47
  });
43
48
  }
44
49
 
50
+ /**
51
+ * 获取搜索提示
52
+ * @param search
53
+ * @param cityCode
54
+ * @returns
55
+ */
45
56
  export function getSearchTips(search, cityCode = "0571") {
46
57
  return new Promise((resolve, reject) => {
47
58
  if (!window.AMap) {
@@ -70,7 +81,7 @@ export function getSearchTips(search, cityCode = "0571") {
70
81
  } else if (result === "USER_DAILY_QUERY_OVER_LIMIT") {
71
82
  // 超出限制,使用 webServer 进行请求
72
83
  if (!window._AMapLoaderTemp.serverKey) {
73
- Toast.show({ icon: "fail", content: "超出使用限制,请联系管理员" });
84
+ reject(new Error("超出使用限制,请联系管理员"));
74
85
  return;
75
86
  }
76
87
  fetch(
@@ -97,7 +108,8 @@ export function getSearchTips(search, cityCode = "0571") {
97
108
  }),
98
109
  );
99
110
  } else {
100
- Toast.show({ icon: "fail", content: res.info });
111
+ console.warn("Warn getSearchTips fetch: ", res);
112
+ reject(new Error(res.info));
101
113
  }
102
114
  })
103
115
  .catch(reject);
package/src/index.less CHANGED
@@ -5,6 +5,9 @@
5
5
  .adm-list-item-content {
6
6
  border-top: unset;
7
7
  }
8
+ .adm-formily-item{
9
+ font-size: 30px ;
10
+ }
8
11
  }
9
12
  }
10
13
  .picker-box {
@@ -1,17 +0,0 @@
1
- function getCurrentPosition(config) {
2
- return new Promise((resolve, reject) => {
3
- navigator.geolocation.getCurrentPosition(
4
- (position) => {
5
- resolve(position);
6
- },
7
- reject,
8
- {
9
- enableHighAccuracy: true,
10
- timeout: 5000,
11
- ...config,
12
- },
13
- );
14
- });
15
- }
16
-
17
- export default getCurrentPosition;
@@ -1,53 +0,0 @@
1
- import AMapLoader from "@/components/AMap/common/loader.js";
2
-
3
- if (!window._AMapLoaderTemp) {
4
- window._AMapLoaderTemp = {};
5
- }
6
-
7
- /**
8
- * 根据经纬度获取地址
9
- * @param {Array} lngLatArr
10
- * @returns
11
- */
12
- export function getAddress(lngLatArr) {
13
- return new Promise((resolve, reject) => {
14
- if (!lngLatArr) {
15
- reject("参数有误");
16
- return;
17
- }
18
- return AMapLoader({
19
- key: window._AMapLoaderTemp.key,
20
- securityJsCode: window._AMapLoaderTemp.securityJsCode,
21
- }).then((AMap) => {
22
- const geocoder = new AMap.Geocoder({});
23
-
24
- geocoder.getAddress(lngLatArr, function (state, result) {
25
- if (state === "complete" && result.regeocode) {
26
- resolve(result.regeocode.formattedAddress);
27
- } else {
28
- reject("根据经纬度查询地址失败");
29
- console.error("根据经纬度查询地址失败");
30
- }
31
- });
32
- });
33
- });
34
- }
35
-
36
- export function setKey(key, securityJsCode) {
37
- window._AMapLoaderTemp.key = key;
38
- window._AMapLoaderTemp.securityJsCode = securityJsCode;
39
- }
40
-
41
- export function setServerKey(key, securityJsCode) {
42
- window._AMapLoaderTemp.serverKey = key;
43
- window._AMapLoaderTemp.serverSecurityJsCode = securityJsCode;
44
- }
45
-
46
- export function setSecurityJsCode(securityJsCode) {
47
- window._AMapLoaderTemp.securityJsCode = securityJsCode;
48
- window._AMapSecurityConfig = {
49
- securityJsCode: securityJsCode,
50
- };
51
- }
52
-
53
- export { AMapLoader };