|
@@ -0,0 +1,259 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <BasicModal
|
|
|
|
|
+ v-bind="$attrs"
|
|
|
|
|
+ @register="register"
|
|
|
|
|
+ title="地图选择"
|
|
|
|
|
+ @ok="handleSubmit"
|
|
|
|
|
+ @cancel="handleCancel"
|
|
|
|
|
+ :width="828"
|
|
|
|
|
+ :minHeight="500"
|
|
|
|
|
+ centered
|
|
|
|
|
+ >
|
|
|
|
|
+ <GoogleMap
|
|
|
|
|
+ ref="mapRef"
|
|
|
|
|
+ api-key="AIzaSyBGUvCR1bppO9pfuS0MUWzuftiZ127y4Os"
|
|
|
|
|
+ mapId="DEMO_MAP_ID"
|
|
|
|
|
+ :center="center"
|
|
|
|
|
+ :map-type-control="false"
|
|
|
|
|
+ :disable-default-ui="true"
|
|
|
|
|
+ :language="lang"
|
|
|
|
|
+ region="JP"
|
|
|
|
|
+ :zoom="7"
|
|
|
|
|
+ map-type-id="roadmap"
|
|
|
|
|
+ :mapTypeControlOptions="{
|
|
|
|
|
+ style: 1,
|
|
|
|
|
+ position: 3,
|
|
|
|
|
+ }"
|
|
|
|
|
+ style="width: 800px; height: 500px"
|
|
|
|
|
+ @click="handleMapClick"
|
|
|
|
|
+ v-loading="loadingRef"
|
|
|
|
|
+ :loading-tip="t('common.loadingText')"
|
|
|
|
|
+ >
|
|
|
|
|
+ <CustomControl position="TOP_LEFT">
|
|
|
|
|
+ <div class="p-20px">
|
|
|
|
|
+ <a-input id="pac-input" allow-clear />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </CustomControl>
|
|
|
|
|
+ </GoogleMap>
|
|
|
|
|
+ <div v-if="searchMarker.lng || searchMarker.lat">
|
|
|
|
|
+ 纬度 {{ searchMarker.lat }}, 经度 {{ searchMarker.lng }}</div
|
|
|
|
|
+ >
|
|
|
|
|
+
|
|
|
|
|
+ <template #centerFooter> </template>
|
|
|
|
|
+ </BasicModal>
|
|
|
|
|
+</template>
|
|
|
|
|
+<script lang="ts">
|
|
|
|
|
+ import { computed, defineComponent, ref, watch } from 'vue';
|
|
|
|
|
+ import { BasicModal, useModalInner } from '/@/components/Modal';
|
|
|
|
|
+ import { FormSchema, useForm } from '/@/components/Form/index';
|
|
|
|
|
+
|
|
|
|
|
+ import { useI18n } from '/@/hooks/web/useI18n';
|
|
|
|
|
+ import {
|
|
|
|
|
+ GoogleMap,
|
|
|
|
|
+ // AdvancedMarker,
|
|
|
|
|
+ // MarkerCluster,
|
|
|
|
|
+ // // InfoWindow,
|
|
|
|
|
+ CustomControl,
|
|
|
|
|
+ } from 'vue3-google-map';
|
|
|
|
|
+ import { useLocaleStore } from '/@/store/modules/locale';
|
|
|
|
|
+
|
|
|
|
|
+ const { t } = useI18n();
|
|
|
|
|
+ const schemas: FormSchema[] = [
|
|
|
|
|
+ {
|
|
|
|
|
+ field: 'projectName',
|
|
|
|
|
+ label: '项目名称',
|
|
|
|
|
+ component: 'Input',
|
|
|
|
|
+ colProps: {
|
|
|
|
|
+ span: 24,
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ field: 'projectSn',
|
|
|
|
|
+ label: '项目编号',
|
|
|
|
|
+ component: 'Input',
|
|
|
|
|
+ colProps: {
|
|
|
|
|
+ span: 24,
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ field: 'location',
|
|
|
|
|
+ label: '位置',
|
|
|
|
|
+ component: 'Input',
|
|
|
|
|
+ slot: 'location',
|
|
|
|
|
+ colProps: {
|
|
|
|
|
+ span: 24,
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ field: 'isShow',
|
|
|
|
|
+ label: '是否展示',
|
|
|
|
|
+ component: 'Switch',
|
|
|
|
|
+ colProps: {
|
|
|
|
|
+ span: 24,
|
|
|
|
|
+ },
|
|
|
|
|
+ componentProps: {
|
|
|
|
|
+ defaultChecked: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ ];
|
|
|
|
|
+ const localeStore = useLocaleStore();
|
|
|
|
|
+ export default defineComponent({
|
|
|
|
|
+ components: { BasicModal, GoogleMap, CustomControl },
|
|
|
|
|
+ props: {
|
|
|
|
|
+ userData: { type: Object },
|
|
|
|
|
+ },
|
|
|
|
|
+ emits: ['register', 'success', 'update'],
|
|
|
|
|
+ setup(_, { emit }) {
|
|
|
|
|
+ // const { createMessage } = useMessage();
|
|
|
|
|
+ const sceneNum = ref('');
|
|
|
|
|
+ const location = ref('');
|
|
|
|
|
+ const loadingRef = ref(true);
|
|
|
|
|
+ const center = { lat: 35.717, lng: 139.731 };
|
|
|
|
|
+ const mapRef = ref();
|
|
|
|
|
+ const searchMarker = ref({ lat: 0, lng: 0 });
|
|
|
|
|
+ const searchMarkerRef = ref();
|
|
|
|
|
+
|
|
|
|
|
+ const lang = computed(() => localeStore.getLocale);
|
|
|
|
|
+
|
|
|
|
|
+ const [registerForm, { setFieldsValue }] = useForm({
|
|
|
|
|
+ schemas: schemas,
|
|
|
|
|
+ labelWidth: 100,
|
|
|
|
|
+ showActionButtonGroup: false,
|
|
|
|
|
+ actionColOptions: {
|
|
|
|
|
+ span: 24,
|
|
|
|
|
+ },
|
|
|
|
|
+ // submitFunc: handleSubmit,
|
|
|
|
|
+ });
|
|
|
|
|
+ const [register, { closeModal }] = useModalInner((data) => {
|
|
|
|
|
+ data && onDataReceive(data);
|
|
|
|
|
+ });
|
|
|
|
|
+ watch(
|
|
|
|
|
+ () => mapRef.value?.ready,
|
|
|
|
|
+ (ready) => {
|
|
|
|
|
+ if (!ready) return;
|
|
|
|
|
+ console.log('ready', ready);
|
|
|
|
|
+
|
|
|
|
|
+ loadingRef.value = false;
|
|
|
|
|
+ const map = mapRef.value.map;
|
|
|
|
|
+ if (map) {
|
|
|
|
|
+ const defaultBounds = {
|
|
|
|
|
+ north: center.lat + 0.1,
|
|
|
|
|
+ south: center.lat - 0.1,
|
|
|
|
|
+ east: center.lng + 0.1,
|
|
|
|
|
+ west: center.lng - 0.1,
|
|
|
|
|
+ };
|
|
|
|
|
+ const input = document.getElementById('pac-input') as HTMLInputElement;
|
|
|
|
|
+ const options = {
|
|
|
|
|
+ bounds: defaultBounds,
|
|
|
|
|
+ componentRestrictions: { country: 'jp' },
|
|
|
|
|
+ fields: ['address_components', 'geometry', 'icon', 'name'],
|
|
|
|
|
+ strictBounds: false,
|
|
|
|
|
+ };
|
|
|
|
|
+ // @ts-ignore
|
|
|
|
|
+ const autocomplete = new google.maps.places.Autocomplete(input, options);
|
|
|
|
|
+ // debugger;
|
|
|
|
|
+
|
|
|
|
|
+ console.log('map', map);
|
|
|
|
|
+ autocomplete.bindTo('bounds', map);
|
|
|
|
|
+ // @ts-ignore
|
|
|
|
|
+ searchMarkerRef.value = new google.maps.Marker({
|
|
|
|
|
+ map,
|
|
|
|
|
+ // @ts-ignore
|
|
|
|
|
+ anchorPoint: new google.maps.Point(0, -29),
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ autocomplete.addListener('place_changed', () => {
|
|
|
|
|
+ searchMarkerRef.value.setVisible(false);
|
|
|
|
|
+
|
|
|
|
|
+ const place = autocomplete.getPlace();
|
|
|
|
|
+
|
|
|
|
|
+ if (!place.geometry || !place.geometry.location) {
|
|
|
|
|
+ // window.alert("No details available for input: '" + place.name + "'");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // If the place has a geometry, then present it on a map.
|
|
|
|
|
+ if (place.geometry.viewport) {
|
|
|
|
|
+ map.fitBounds(place.geometry.viewport);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ map.setCenter(place.geometry.location);
|
|
|
|
|
+ map.setZoom(17);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ searchMarker.value.lat = place.geometry.location.lat();
|
|
|
|
|
+ searchMarker.value.lng = place.geometry.location.lng();
|
|
|
|
|
+ console.log('last-get', searchMarker.value);
|
|
|
|
|
+ searchMarkerRef.value.setPosition(place.geometry.location);
|
|
|
|
|
+ searchMarkerRef.value.setVisible(true);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ deep: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ function onDataReceive(data) {
|
|
|
|
|
+ console.log('Data Received', data, data.num);
|
|
|
|
|
+
|
|
|
|
|
+ setFieldsValue({
|
|
|
|
|
+ ...data,
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ sceneNum.value = data.num;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const resetMapview = () => {
|
|
|
|
|
+ searchMarker.value = { lat: 0, lng: 0 };
|
|
|
|
|
+ searchMarkerRef.value?.setVisible(false);
|
|
|
|
|
+ mapRef.value?.map?.setCenter(center);
|
|
|
|
|
+ mapRef.value?.map?.setZoom(7);
|
|
|
|
|
+ const input = document.getElementById('pac-input') as HTMLInputElement;
|
|
|
|
|
+ if (input) {
|
|
|
|
|
+ input.value = '';
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ const handleMapClick = async (event) => {
|
|
|
|
|
+ const { lat, lng } = event.latLng;
|
|
|
|
|
+ searchMarker.value.lat = lat();
|
|
|
|
|
+ searchMarker.value.lng = lng();
|
|
|
|
|
+ searchMarkerRef.value?.setVisible(true);
|
|
|
|
|
+ searchMarkerRef.value?.setPosition(searchMarker.value);
|
|
|
|
|
+ };
|
|
|
|
|
+ const handleSubmit = async () => {
|
|
|
|
|
+ if (searchMarker.value.lat || searchMarker.value.lng) {
|
|
|
|
|
+ emit('update', searchMarker.value);
|
|
|
|
|
+ }
|
|
|
|
|
+ closeModal();
|
|
|
|
|
+ resetMapview();
|
|
|
|
|
+ };
|
|
|
|
|
+ const handleCancel = async () => {
|
|
|
|
|
+ resetMapview();
|
|
|
|
|
+ };
|
|
|
|
|
+ return {
|
|
|
|
|
+ t,
|
|
|
|
|
+ register,
|
|
|
|
|
+ schemas,
|
|
|
|
|
+ handleSubmit,
|
|
|
|
|
+ closeModal,
|
|
|
|
|
+ registerForm,
|
|
|
|
|
+ location,
|
|
|
|
|
+ handleMapClick,
|
|
|
|
|
+ loadingRef,
|
|
|
|
|
+ lang,
|
|
|
|
|
+ mapRef,
|
|
|
|
|
+ center,
|
|
|
|
|
+ searchMarker,
|
|
|
|
|
+ handleCancel,
|
|
|
|
|
+ // searchMarkerShow,
|
|
|
|
|
+ };
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+</script>
|
|
|
|
|
+<style lang="less" scoped>
|
|
|
|
|
+ .map-select {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: row;
|
|
|
|
|
+ gap: 0 20px;
|
|
|
|
|
+ }
|
|
|
|
|
+</style>
|