|
...
|
...
|
@@ -44,16 +44,31 @@ |
|
44
|
44
|
centered
|
|
45
|
45
|
>
|
|
46
|
46
|
<div>
|
|
47
|
|
- <a-form :label-col="labelCol">
|
|
48
|
|
- <a-row :gutter="20" class="pt-4 pl-6">
|
|
49
|
|
- <a-col :span="8">
|
|
|
47
|
+ <a-form :label-col="labelCol" :colon="false">
|
|
|
48
|
+ <a-row :gutter="20" class="mt-4">
|
|
|
49
|
+ <a-col :span="20">
|
|
|
50
|
+ <a-form-item label="搜索位置">
|
|
|
51
|
+ <AutoComplete
|
|
|
52
|
+ v-model:value="positionState.address"
|
|
|
53
|
+ :options="dataSource"
|
|
|
54
|
+ style="width: 100%"
|
|
|
55
|
+ placeholder="搜索位置"
|
|
|
56
|
+ @search="debounceSearch"
|
|
|
57
|
+ @select="handleSelect"
|
|
|
58
|
+ backfill
|
|
|
59
|
+ />
|
|
|
60
|
+ </a-form-item>
|
|
|
61
|
+ </a-col>
|
|
|
62
|
+ </a-row>
|
|
|
63
|
+ <a-row :gutter="20" class="">
|
|
|
64
|
+ <a-col :span="10">
|
|
50
|
65
|
<a-form-item label="经度">
|
|
51
|
|
- <Input type="input" v-model:value="positionState.longitude" disabled />
|
|
|
66
|
+ <Input v-model:value="positionState.longitude" disabled />
|
|
52
|
67
|
</a-form-item>
|
|
53
|
68
|
</a-col>
|
|
54
|
|
- <a-col :span="8">
|
|
|
69
|
+ <a-col :span="10">
|
|
55
|
70
|
<a-form-item label="纬度">
|
|
56
|
|
- <Input type="input" v-model:value="positionState.latitude" disabled />
|
|
|
71
|
+ <Input v-model:value="positionState.latitude" disabled />
|
|
57
|
72
|
</a-form-item>
|
|
58
|
73
|
</a-col>
|
|
59
|
74
|
</a-row>
|
|
...
|
...
|
@@ -68,18 +83,19 @@ |
|
68
|
83
|
import { BasicForm, useForm } from '/@/components/Form';
|
|
69
|
84
|
import { step1Schemas } from '../../config/data';
|
|
70
|
85
|
import { useScript } from '/@/hooks/web/useScript';
|
|
71
|
|
- import { Input, Divider, Upload, message, Modal, Form, Row, Col } from 'ant-design-vue';
|
|
|
86
|
+ import { Input, Upload, message, Modal, Form, Row, Col, AutoComplete } from 'ant-design-vue';
|
|
72
|
87
|
import { EnvironmentTwoTone, PlusOutlined } from '@ant-design/icons-vue';
|
|
73
|
88
|
import { upload } from '/@/api/oss/ossFileUploader';
|
|
74
|
89
|
import { FileItem } from '/@/components/Upload/src/typing';
|
|
75
|
90
|
import { BAI_DU_MAP_URL } from '/@/utils/fnUtils';
|
|
76
|
91
|
import icon from '/@/assets/images/wz.png';
|
|
|
92
|
+ import { useDebounceFn } from '@vueuse/core';
|
|
77
|
93
|
export default defineComponent({
|
|
78
|
94
|
components: {
|
|
79
|
95
|
BasicForm,
|
|
80
|
96
|
Input,
|
|
|
97
|
+ AutoComplete,
|
|
81
|
98
|
[Input.Group.name]: Input.Group,
|
|
82
|
|
- [Divider.name]: Divider,
|
|
83
|
99
|
Upload,
|
|
84
|
100
|
EnvironmentTwoTone,
|
|
85
|
101
|
PlusOutlined,
|
|
...
|
...
|
@@ -101,16 +117,7 @@ |
|
101
|
117
|
emits: ['next'],
|
|
102
|
118
|
setup(props, { emit }) {
|
|
103
|
119
|
const devicePic = ref('');
|
|
104
|
|
- let positionState = reactive<{
|
|
105
|
|
- longitude: string;
|
|
106
|
|
- latitude: string;
|
|
107
|
|
- description?: string;
|
|
108
|
|
- address: string;
|
|
109
|
|
- }>({
|
|
110
|
|
- longitude: '',
|
|
111
|
|
- latitude: '',
|
|
112
|
|
- address: '',
|
|
113
|
|
- });
|
|
|
120
|
+
|
|
114
|
121
|
const [register, { validate, resetFields, setFieldsValue, getFieldsValue, updateSchema }] =
|
|
115
|
122
|
useForm({
|
|
116
|
123
|
labelWidth: 100,
|
|
...
|
...
|
@@ -169,6 +176,35 @@ |
|
169
|
176
|
}
|
|
170
|
177
|
};
|
|
171
|
178
|
|
|
|
179
|
+ let positionState = reactive<{
|
|
|
180
|
+ longitude: string;
|
|
|
181
|
+ latitude: string;
|
|
|
182
|
+ description?: string;
|
|
|
183
|
+ address: string;
|
|
|
184
|
+ map: null;
|
|
|
185
|
+ marker: null;
|
|
|
186
|
+ }>({
|
|
|
187
|
+ longitude: '',
|
|
|
188
|
+ latitude: '',
|
|
|
189
|
+ address: '',
|
|
|
190
|
+ map: null,
|
|
|
191
|
+ marker: null,
|
|
|
192
|
+ });
|
|
|
193
|
+ /**
|
|
|
194
|
+ * 逆地址解析函数(根据坐标点获取详细地址)
|
|
|
195
|
+ * @param {Object} point 百度地图坐标点,必传
|
|
|
196
|
+ */
|
|
|
197
|
+ function getAddrByPoint(point) {
|
|
|
198
|
+ let geco = new BMap.Geocoder();
|
|
|
199
|
+ geco.getLocation(point, function (res) {
|
|
|
200
|
+ positionState.marker.setPosition(point); //重新设置标注的地理坐标
|
|
|
201
|
+ positionState.map.panTo(point); //将地图的中心点更改为给定的点
|
|
|
202
|
+ positionState.address = res.address; //记录该点的详细地址信息
|
|
|
203
|
+ positionState.longitude = point.lng; //记录当前坐标点
|
|
|
204
|
+ positionState.latitude = point.lat;
|
|
|
205
|
+ });
|
|
|
206
|
+ }
|
|
|
207
|
+
|
|
172
|
208
|
// 地图
|
|
173
|
209
|
const wrapRef = ref<HTMLDivElement | null>(null);
|
|
174
|
210
|
const { toPromise } = useScript({ src: BAI_DU_MAP_URL });
|
|
...
|
...
|
@@ -180,48 +216,94 @@ |
|
180
|
216
|
const BMap = (window as any).BMap;
|
|
181
|
217
|
if (!wrapEl) return;
|
|
182
|
218
|
let preMarker = null;
|
|
183
|
|
- const map = new BMap.Map(wrapEl);
|
|
|
219
|
+ positionState;
|
|
|
220
|
+ positionState.map = new BMap.Map(wrapEl, { enableMapClick: false });
|
|
184
|
221
|
let myIcon = new BMap.Icon(icon, new BMap.Size(20, 30));
|
|
185
|
222
|
const point = new BMap.Point(Number(longitude), Number(latitude));
|
|
186
|
|
- let marker = new BMap.Marker(point, { icon: myIcon });
|
|
187
|
|
- if (marker) {
|
|
188
|
|
- map.removeOverlay(preMarker);
|
|
|
223
|
+ positionState.marker = new BMap.Marker(point, { icon: myIcon, enableDragging: true });
|
|
|
224
|
+ if (positionState.marker) {
|
|
|
225
|
+ positionState.map.removeOverlay(preMarker);
|
|
189
|
226
|
}
|
|
190
|
|
- map.addOverlay(marker);
|
|
191
|
|
- preMarker = marker;
|
|
192
|
|
- map.centerAndZoom(point, 15);
|
|
193
|
|
- map.enableScrollWheelZoom(true);
|
|
194
|
|
- map.addEventListener('click', (e) => {
|
|
195
|
|
- const { lat, lng } = e.point;
|
|
196
|
|
- positionState.latitude = lat + '';
|
|
197
|
|
- positionState.longitude = lng + '';
|
|
198
|
|
- let gc = new BMap.Geocoder();
|
|
199
|
|
- let newPoint = new BMap.Point(lng, lat);
|
|
|
227
|
+ positionState.map.addOverlay(positionState.marker);
|
|
|
228
|
+ preMarker = positionState.marker;
|
|
|
229
|
+ positionState.map.centerAndZoom(point, 15);
|
|
|
230
|
+ positionState.map.enableScrollWheelZoom(true);
|
|
|
231
|
+ let navigationControl = new BMap.NavigationControl({
|
|
|
232
|
+ //创建一个特定样式的地图平移缩放控件
|
|
|
233
|
+ anchor: BMAP_ANCHOR_TOP_RIGHT, //靠右上角位置
|
|
|
234
|
+ type: BMAP_NAVIGATION_CONTROL_LARGE, //SMALL控件类型
|
|
|
235
|
+ });
|
|
|
236
|
+ positionState.map.addControl(navigationControl); //将控件添加到地图
|
|
200
|
237
|
|
|
201
|
|
- // 添加锚点
|
|
202
|
|
- if (!e.overlay) {
|
|
203
|
|
- let marker = new BMap.Marker(e.point, { icon: myIcon });
|
|
204
|
|
- map.removeOverlay(preMarker);
|
|
205
|
|
- map.addOverlay(marker);
|
|
206
|
|
- preMarker = marker;
|
|
207
|
|
- }
|
|
208
|
|
- //获取详细的地址,精确到街道的名称
|
|
209
|
|
- gc.getLocation(newPoint, (rs) => {
|
|
210
|
|
- let addComp = rs.addressComponents;
|
|
211
|
|
- let address = addComp.city + addComp.district + addComp.street + addComp.streetNumber;
|
|
212
|
|
- positionState.address = address;
|
|
213
|
|
- });
|
|
|
238
|
+ positionState.marker.addEventListener('dragend', function (e) {
|
|
|
239
|
+ getAddrByPoint(e.point); //拖拽结束后调用逆地址解析函数,e.point为拖拽后的地理坐标
|
|
|
240
|
+ });
|
|
|
241
|
+ positionState.map.addEventListener('click', (e) => {
|
|
|
242
|
+ getAddrByPoint(e.point);
|
|
214
|
243
|
});
|
|
215
|
244
|
}
|
|
|
245
|
+ const dataSource = ref<any[]>([]);
|
|
|
246
|
+
|
|
|
247
|
+ const onSearch = (searchText: string) => {
|
|
|
248
|
+ if (!searchText) {
|
|
|
249
|
+ dataSource.value = [];
|
|
|
250
|
+ return;
|
|
|
251
|
+ }
|
|
|
252
|
+ let local = new BMap.LocalSearch(positionState.map, {
|
|
|
253
|
+ onSearchComplete(res) {
|
|
|
254
|
+ //检索完成后的回调函数
|
|
|
255
|
+ if (local.getStatus() == BMAP_STATUS_SUCCESS) {
|
|
|
256
|
+ const searchArr = [];
|
|
|
257
|
+ for (let i = 0; i < res.getCurrentNumPois(); i++) {
|
|
|
258
|
+ const item = res.getPoi(i);
|
|
|
259
|
+ console.log(item);
|
|
|
260
|
+ searchArr.push({
|
|
|
261
|
+ label: item.address + item.title,
|
|
|
262
|
+ value: item.address + item.title,
|
|
|
263
|
+ point: item.point,
|
|
|
264
|
+ });
|
|
|
265
|
+ }
|
|
|
266
|
+ dataSource.value = searchArr;
|
|
|
267
|
+ }
|
|
|
268
|
+ },
|
|
|
269
|
+ }); //调用search方法,根据检索词searchText发起检索
|
|
|
270
|
+ local.search(searchText);
|
|
|
271
|
+ console.log(dataSource);
|
|
|
272
|
+ };
|
|
|
273
|
+ // 防抖函数包装一下,防止频繁执行
|
|
|
274
|
+ const debounceSearch = useDebounceFn(onSearch, 500);
|
|
|
275
|
+ function handleSelect(value, option) {
|
|
|
276
|
+ dataSource.value = [];
|
|
|
277
|
+ console.log(option);
|
|
|
278
|
+ positionState.address = option.value; //记录详细地址,含建筑物名
|
|
|
279
|
+ const { lat, lng } = option.point;
|
|
|
280
|
+ positionState.latitude = lat; //记录当前选中地址坐标
|
|
|
281
|
+ positionState.longitude = lng; //记录当前选中地址坐标
|
|
|
282
|
+ positionState.map.clearOverlays(); //清除地图上所有覆盖物
|
|
|
283
|
+ let myIcon = new BMap.Icon(icon, new BMap.Size(20, 30));
|
|
|
284
|
+ positionState.marker = new BMap.Marker(option.point, {
|
|
|
285
|
+ icon: myIcon,
|
|
|
286
|
+ enableDragging: true,
|
|
|
287
|
+ }); //根据所选坐标重新创建Marker
|
|
|
288
|
+ positionState.marker.addEventListener('dragend', function (e) {
|
|
|
289
|
+ getAddrByPoint(e.point); //拖拽结束后调用逆地址解析函数,e.point为拖拽后的地理坐标
|
|
|
290
|
+ });
|
|
|
291
|
+ positionState.map.addOverlay(positionState.marker); //将覆盖物重新添加到地图中
|
|
|
292
|
+ positionState.map.panTo(option.point); //将地图的中心点更改为选定坐标点
|
|
|
293
|
+ }
|
|
|
294
|
+
|
|
216
|
295
|
// 确定选择的位置
|
|
217
|
296
|
const handleOk = () => {
|
|
218
|
297
|
visible.value = false;
|
|
219
|
298
|
};
|
|
220
|
299
|
// 取消选择位置
|
|
221
|
300
|
const handleCancel = () => {
|
|
|
301
|
+ dataSource.value = [];
|
|
|
302
|
+
|
|
222
|
303
|
for (let key in positionState) {
|
|
223
|
304
|
positionState[key] = '';
|
|
224
|
305
|
}
|
|
|
306
|
+ console.log(positionState);
|
|
225
|
307
|
};
|
|
226
|
308
|
// 父组件调用更新字段值的方法
|
|
227
|
309
|
function parentSetFieldsValue(data) {
|
|
...
|
...
|
@@ -280,7 +362,7 @@ |
|
280
|
362
|
handleOk,
|
|
281
|
363
|
handleCancel,
|
|
282
|
364
|
wrapRef,
|
|
283
|
|
- labelCol: { style: { width: '40px' } },
|
|
|
365
|
+ labelCol: { style: { width: '100px' } },
|
|
284
|
366
|
parentSetFieldsValue,
|
|
285
|
367
|
parentGetFieldsValue,
|
|
286
|
368
|
parentValidate,
|
|
...
|
...
|
@@ -288,6 +370,10 @@ |
|
288
|
370
|
parentResetPositionState,
|
|
289
|
371
|
disabledDeviceType,
|
|
290
|
372
|
nextStep,
|
|
|
373
|
+ onSearch,
|
|
|
374
|
+ handleSelect,
|
|
|
375
|
+ dataSource,
|
|
|
376
|
+ debounceSearch,
|
|
291
|
377
|
};
|
|
292
|
378
|
},
|
|
293
|
379
|
});
|
...
|
...
|
|