@hzab/form-render-mobile 0.2.3 → 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.
@@ -1,35 +1,28 @@
1
- import { useEffect, useMemo, useRef, useState } from "react";
2
- import { Popup, Button, SpinLoading, Toast } from "antd-mobile";
1
+ import { useRef, useState } from "react";
2
+ import { Popup, Button } from "antd-mobile";
3
3
  import { useField, useFieldSchema } from "@formily/react";
4
- import { LocationFill } from "antd-mobile-icons";
5
- import { debounce } from "lodash";
6
4
 
7
5
  import ResInfo from "./components/ResInfo";
8
-
9
- import PickerInfo from "./components/PickerInfo";
10
- import AMapCom from "./Map/AMap";
11
- import Notice from "./components/Notice";
6
+ import ModalContent from "./components/ModalContent";
12
7
 
13
8
  import { MapUtils } from "./Map/AMap/common/utils";
14
9
  import { getCurrentPosition } from "../../common/location-utils";
15
- import MapSearch from "./components/MapSearch";
16
-
17
- import { getAddress } from "./servers/index";
18
- import { getPropsValue, getParentValue } from "./common/utils";
10
+ import { getParentValue } from "./common/utils";
19
11
 
20
12
  import "./index.less";
21
13
 
22
- const defaultLngLat = {
23
- lon: 120.160217,
24
- lat: 30.243861,
14
+ const defaultLocation = {
15
+ lon: 120.168893,
16
+ lat: 30.225404,
17
+ addr: "浙江省杭州市上城区南星街道杭州西湖风景名胜区",
25
18
  };
26
19
 
27
20
  // 获取当前经纬度
28
21
  getCurrentPosition()
29
22
  .then((res) => {
30
23
  const { coords = {} } = res;
31
- defaultLngLat.lon = coords.longitude;
32
- defaultLngLat.lat = coords.latitude;
24
+ defaultLocation.lon = coords.longitude;
25
+ defaultLocation.lat = coords.latitude;
33
26
  })
34
27
  .catch((e) => {
35
28
  console.warn("Error getCurrentPosition e: ", e);
@@ -37,6 +30,18 @@ getCurrentPosition()
37
30
 
38
31
  export function LocationPicker(props) {
39
32
  const {
33
+ /**
34
+ * 地图显示类型:
35
+ * 弹窗 dialog
36
+ * 直接显示 show
37
+ */
38
+ mode = "dialog",
39
+ /**
40
+ * 选择器和地图的布局
41
+ * 水平 hor
42
+ * 垂直 ver
43
+ */
44
+ layout = "ver",
40
45
  // 是否允许搜索
41
46
  hasSearch = true,
42
47
  /**
@@ -52,8 +57,8 @@ export function LocationPicker(props) {
52
57
  isAutoFixAddr = false,
53
58
  /**
54
59
  * 改变经纬度等数据的触发模式
55
- * 移动地图:move
56
- * 点击地图:click
60
+ * 移动地图 move
61
+ * 点击地图 click
57
62
  */
58
63
  changeMode = "move",
59
64
  lonKey = "longitude",
@@ -62,128 +67,15 @@ export function LocationPicker(props) {
62
67
  value,
63
68
  // 搜索框是否自动搜索
64
69
  isAutoSearch = true,
65
- // 是否是移动端,changeMode == 'move' 时改变监听事件
66
- isMobile = true,
67
70
  } = props;
68
71
  const field: any = useField();
69
72
  const fieldSchema = useFieldSchema();
70
73
 
71
74
  const mapUtilsRef = useRef<MapUtils>();
75
+ const pickInfoRef = useRef(defaultLocation);
72
76
 
73
77
  const [loading, setLoading] = useState(false);
74
- const [addrLoading, setAddrLoading] = useState(false);
75
78
  const [visible, setVisible] = useState(false);
76
- // 数据格式转为内部格式,方便存取
77
- const opt = {
78
- isObjectRes,
79
- lonKey,
80
- latKey,
81
- addrKey,
82
- };
83
-
84
- const formatVal = useMemo(
85
- () => getPropsValue(value, field, opt),
86
- [isObjectRes, lonKey, latKey, addrKey, value, field.data],
87
- );
88
-
89
- // 地图选点组件选中的值
90
- const [pickInfo, setPickInfo] = useState(formatVal);
91
-
92
- useEffect(() => {
93
- if (visible) {
94
- let _lon = defaultLngLat.lon;
95
- let _lat = defaultLngLat.lat;
96
- if (formatVal.lon && formatVal.lat) {
97
- _lon = formatVal.lon;
98
- _lat = formatVal.lat;
99
- }
100
- // 解决关闭弹窗之后点位不居中的问题
101
- if (window.AMap && window.AMap.LngLat) {
102
- setMapCenter(_lon, _lat);
103
- }
104
- setPoint(_lon, _lat, { isAutoFixAddr: false });
105
- }
106
- }, [visible, formatVal, changeMode]);
107
-
108
- useEffect(() => {
109
- setPickInfo(formatVal);
110
- }, [formatVal, isAutoFixAddr]);
111
-
112
- function mapInit({ map, mapUtils }) {
113
- mapUtilsRef.current = mapUtils;
114
- setLoading(false);
115
- let _lon = defaultLngLat.lon;
116
- let _lat = defaultLngLat.lat;
117
- if (pickInfo.lon && pickInfo.lat) {
118
- _lon = pickInfo.lon;
119
- _lat = pickInfo.lat;
120
- }
121
- setPoint(_lon, _lat, { isAutoFixAddr });
122
-
123
- setMapCenter(_lon, _lat);
124
- if (changeMode === "click") {
125
- mapUtilsRef.current?.setPickerMarker(_lon, _lat);
126
- // 点击选中点位的情况
127
- mapUtilsRef.current.on("click", function (ev) {
128
- const { lng: evLon, lat: evLat } = ev.lnglat || {};
129
- setPoint(evLon, evLat, { changeCenter: true });
130
- });
131
- } else {
132
- // 移动地图
133
- mapUtilsRef.current.on(
134
- isMobile ? "touchend" : "mouseup",
135
- debounce(function (ev) {
136
- let currentCenter = mapUtilsRef.current?.getCenter();
137
- const { lng: centerLon, lat: centerLat } = currentCenter || {};
138
- // 移动选中点位的情况
139
- let _lon = centerLon;
140
- let _lat = centerLat;
141
- setPoint(_lon, _lat);
142
- }, 1000),
143
- );
144
- }
145
- }
146
-
147
- /**
148
- * 设置地图中心点
149
- * @param lon
150
- * @param lat
151
- */
152
- function setMapCenter(lon, lat) {
153
- mapUtilsRef.current?.setCenter(lon, lat);
154
- }
155
-
156
- function setPoint(_lon, _lat, opt?: any) {
157
- const { isAutoFixAddr: _isAutoFixAddr = isAutoFixAddr || true, changeCenter } = opt || {};
158
- const lon = _lon || pickInfo.lon;
159
- const lat = _lat || pickInfo.lat;
160
- (_isAutoFixAddr || !pickInfo.addr) && getAddr(lon, lat);
161
- const res = { ...pickInfo, lon, lat, center: [lon, lat] };
162
- setPickInfo(res);
163
- if (changeMode === "click") {
164
- mapUtilsRef.current?.setPickerMarker(_lon, _lat);
165
- }
166
- if (changeCenter) {
167
- setMapCenter(_lon, _lat);
168
- }
169
- }
170
-
171
- function getAddr(_lng, _lat) {
172
- if (!window.AMap) {
173
- return "";
174
- }
175
-
176
- setAddrLoading(true);
177
- getAddress(_lng, _lat)
178
- .then((addr) => {
179
- setAddrLoading(false);
180
- setPickInfo((_p) => ({ ..._p, addr }));
181
- })
182
- .catch((err) => {
183
- Toast.show({ icon: "fail", content: err });
184
- setAddrLoading(false);
185
- });
186
- }
187
79
 
188
80
  function onShow() {
189
81
  // 等待地图加载完毕
@@ -193,81 +85,123 @@ export function LocationPicker(props) {
193
85
 
194
86
  function onClose() {
195
87
  setVisible(false);
196
- setLoading(false);
197
88
  }
198
89
 
199
- function onOk() {
200
- const res = {
201
- [lonKey]: pickInfo.lon,
202
- [latKey]: pickInfo.lat,
203
- [addrKey]: pickInfo.addr,
90
+ function onChange(res = pickInfoRef.current) {
91
+ const info = res || pickInfoRef.current;
92
+ const _res = {
93
+ [lonKey]: info.lon,
94
+ [latKey]: info.lat,
95
+ [addrKey]: info.addr,
204
96
  };
205
- props.onChange && props.onChange(res);
97
+ props.onChange && props.onChange(_res);
206
98
  if (isObjectRes === false) {
207
99
  // 只有一层的情况
208
100
  if (!field.parent) {
209
- field.form.setValues(res);
101
+ field.form.setValues(_res);
210
102
  } else if (field.parent && fieldSchema.parent) {
211
103
  // 嵌套在 ArrayBase: ArrayTable ArrayCard 等 里面的情况
212
104
  const parentVal = getParentValue(field);
213
- Object.keys(res).forEach((key) => {
214
- parentVal[key] = res[key];
105
+ Object.keys(_res).forEach((key) => {
106
+ parentVal[key] = _res[key];
215
107
  });
216
108
  }
217
109
  }
110
+ }
218
111
 
112
+ function onOk() {
113
+ onChange();
219
114
  onClose();
220
115
  }
221
116
 
222
- return (
223
- <div className="location-picker">
224
- {/* 显示表单选中的结果 */}
225
- <ResInfo {...props} onShow={onShow} />
226
- {/* 弹窗 */}
227
- <Popup
228
- maskClassName="location-picker-popup-mask"
229
- className="location-picker-popup"
230
- onMaskClick={onClose}
231
- onClose={onClose}
232
- bodyStyle={{
233
- minHeight: "80vh",
234
- maxHeight: "100vh",
235
- }}
236
- visible={visible}
237
- >
238
- <div className="location-popup-header">
239
- <Button fill="none" onClick={onClose}>
240
- 取消
241
- </Button>
242
- <Button color="primary" fill="none" onClick={onOk} loading={addrLoading || loading}>
243
- 确认
244
- </Button>
245
- </div>
117
+ function setResInfo(res) {
118
+ setPickInfo(res);
119
+ onChange(res);
120
+ }
121
+
122
+ function setPickInfo(res) {
123
+ pickInfoRef.current = res;
124
+ }
246
125
 
247
- <div className="location-popup-content">
248
- {/* 点击/移动 地图选中的数据 */}
249
- <PickerInfo
250
- pickInfo={pickInfo}
251
- setPickInfo={setPickInfo}
252
- setPoint={setPoint}
253
- addrLoading={addrLoading}
254
- defaultLngLat={defaultLngLat}
255
- />
126
+ const _props = {
127
+ /**
128
+ * 地图显示类型:
129
+ * 弹窗 dialog
130
+ * 直接显示 show
131
+ */
132
+ mode: mode ?? "dialog",
133
+ /**
134
+ * 选择器和地图的布局
135
+ * 水平 hor
136
+ * 垂直 ver
137
+ */
138
+ layout: layout ?? "ver",
139
+ // 是否允许搜索
140
+ hasSearch: hasSearch ?? true,
141
+ /**
142
+ *
143
+ isObjectRes
144
+ true: 把所有数据存放在一个对象中(该对象和其他表单项平级),对象 key 为当前项的 name
145
+ false: 所有数据打平放到当前的 data 中,和其他表单项平级
146
+ */
147
+ isObjectRes: isObjectRes ?? true,
148
+ /**
149
+ * 打开地图时是否根据经纬度自动修正已填的地址
150
+ */
151
+ isAutoFixAddr: isAutoFixAddr ?? false,
152
+ /**
153
+ * 改变经纬度等数据的触发模式
154
+ * 移动地图:move
155
+ * 点击地图:click
156
+ */
157
+ changeMode: changeMode ?? "move",
158
+ lonKey: lonKey ?? "longitude",
159
+ latKey: latKey ?? "latitude",
160
+ addrKey: addrKey ?? "address",
161
+ value,
162
+ // 搜索框是否自动搜索
163
+ isAutoSearch: isAutoSearch ?? true,
164
+ defaultLocation,
165
+ };
256
166
 
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" />}
263
- </div>
264
- {loading && (
265
- <div className="spin-loading-wrap">
266
- <SpinLoading className="spin-loading" color="primary" />
167
+ return (
168
+ <div className="location-picker">
169
+ {mode === "show" ? (
170
+ <ModalContent {..._props} visible={visible} setPickInfo={setResInfo} layout={layout} />
171
+ ) : (
172
+ <>
173
+ {/* 弹窗 */}
174
+ {/* 有弹窗时,显示表单选中的结果 */}
175
+ <ResInfo {..._props} onShow={onShow} />
176
+ <Popup
177
+ maskClassName="location-picker-popup-mask"
178
+ className="location-picker-popup"
179
+ onMaskClick={onClose}
180
+ onClose={onClose}
181
+ bodyStyle={{
182
+ minHeight: "78vh",
183
+ maxHeight: "100vh",
184
+ }}
185
+ visible={visible}
186
+ >
187
+ <div className="location-popup-header">
188
+ <Button fill="none" onClick={onClose}>
189
+ 取消
190
+ </Button>
191
+ <Button color="primary" fill="none" onClick={onOk} loading={loading}>
192
+ 确认
193
+ </Button>
267
194
  </div>
268
- )}
269
- </div>
270
- </Popup>
195
+ <ModalContent
196
+ {..._props}
197
+ visible={visible}
198
+ setPickInfo={setPickInfo}
199
+ layout={layout}
200
+ setLoading={setLoading}
201
+ />
202
+ </Popup>
203
+ </>
204
+ )}
271
205
  </div>
272
206
  );
273
207
  }
package/src/index.less CHANGED
@@ -1,13 +1,14 @@
1
1
  .form-render {
2
+ font-size: 4vw;
3
+ .adm-formily-item {
4
+ font-size: 4vw;
5
+ }
2
6
  .adm-list-body {
3
7
  background-color: unset;
4
8
  .adm-card-body {
5
9
  .adm-list-item-content {
6
10
  border-top: unset;
7
11
  }
8
- .adm-formily-item{
9
- font-size: 30px ;
10
- }
11
12
  }
12
13
  }
13
14
  .picker-box {
@@ -37,7 +38,8 @@
37
38
  }
38
39
  }
39
40
 
40
- & .adm-radio, & .adm-checkbox {
41
+ & .adm-radio,
42
+ & .adm-checkbox {
41
43
  padding-right: 10px;
42
44
  }
43
45
  }