This commit is contained in:
parent
8e68d5b162
commit
6cd7bd1dec
@ -6,13 +6,8 @@
|
|||||||
<YandexMap
|
<YandexMap
|
||||||
v-else
|
v-else
|
||||||
v-model="map"
|
v-model="map"
|
||||||
:settings="{
|
|
||||||
location: {
|
|
||||||
center: [coords?.longitude, coords?.latitude],
|
|
||||||
zoom: 9,
|
|
||||||
},
|
|
||||||
}"
|
|
||||||
class="w-full"
|
class="w-full"
|
||||||
|
:settings="{ location }"
|
||||||
style="height: calc(100dvh - 54px)"
|
style="height: calc(100dvh - 54px)"
|
||||||
>
|
>
|
||||||
<YandexMapDefaultSchemeLayer />
|
<YandexMapDefaultSchemeLayer />
|
||||||
@ -29,6 +24,7 @@
|
|||||||
:key="marker.id"
|
:key="marker.id"
|
||||||
position="top-center left-center"
|
position="top-center left-center"
|
||||||
:settings="{ coordinates: [marker.position.longitude, marker.position.latitude] }"
|
:settings="{ coordinates: [marker.position.longitude, marker.position.latitude] }"
|
||||||
|
@click="centerMap([marker.position.longitude, marker.position.latitude])"
|
||||||
>
|
>
|
||||||
<div class="marker">
|
<div class="marker">
|
||||||
<Icon name="i-lucide-map-pin" class="marker__icon" />
|
<Icon name="i-lucide-map-pin" class="marker__icon" />
|
||||||
@ -45,7 +41,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { LngLatBounds, YMap } from '@yandex/ymaps3-types'
|
import type { LngLat, LngLatBounds, YMap } from '@yandex/ymaps3-types'
|
||||||
|
import type { YMapLocationRequest } from '@yandex/ymaps3-types/imperative/YMap'
|
||||||
import type { YMapClusterer } from '@yandex/ymaps3-types/packages/clusterer'
|
import type { YMapClusterer } from '@yandex/ymaps3-types/packages/clusterer'
|
||||||
import { useGeolocation } from '@vueuse/core'
|
import { useGeolocation } from '@vueuse/core'
|
||||||
import { computed, shallowRef } from 'vue'
|
import { computed, shallowRef } from 'vue'
|
||||||
@ -57,7 +54,7 @@ import {
|
|||||||
YandexMapMarker,
|
YandexMapMarker,
|
||||||
} from 'vue-yandex-maps'
|
} from 'vue-yandex-maps'
|
||||||
|
|
||||||
const props = defineProps<{
|
defineProps<{
|
||||||
pickupPoints: {
|
pickupPoints: {
|
||||||
id: string
|
id: string
|
||||||
address: string
|
address: string
|
||||||
@ -66,13 +63,35 @@ const props = defineProps<{
|
|||||||
}>()
|
}>()
|
||||||
|
|
||||||
const { coords } = useGeolocation()
|
const { coords } = useGeolocation()
|
||||||
|
const clusterer = shallowRef<YMapClusterer | null>(null)
|
||||||
|
const trueBounds = ref<LngLatBounds>([[0, 0], [0, 0]])
|
||||||
|
const map = shallowRef<null | YMap>(null)
|
||||||
|
|
||||||
const hasCoords = computed(() => coords.value?.latitude !== Infinity && coords.value?.longitude !== Infinity)
|
const hasCoords = computed(() => coords.value?.latitude !== Infinity && coords.value?.longitude !== Infinity)
|
||||||
|
|
||||||
const map = shallowRef<null | YMap>(null)
|
const location = ref<YMapLocationRequest>({
|
||||||
|
zoom: 2,
|
||||||
|
})
|
||||||
|
|
||||||
const clusterer = shallowRef<YMapClusterer | null>(null)
|
function centerMap(coordinates: LngLat) {
|
||||||
const trueBounds = ref<LngLatBounds>([[0, 0], [0, 0]])
|
location.value = {
|
||||||
|
center: coordinates,
|
||||||
|
zoom: 18,
|
||||||
|
duration: 2500,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(coords, (newCoords) => {
|
||||||
|
if (newCoords && hasCoords.value) {
|
||||||
|
location.value = {
|
||||||
|
center: [newCoords.longitude, newCoords.latitude],
|
||||||
|
zoom: 9,
|
||||||
|
duration: 2500,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, { once: true })
|
||||||
|
|
||||||
|
defineExpose({ centerMap, location })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
"typegen": "node .typegen"
|
"typegen": "node .typegen"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@nuxt/content": "^3.7.1",
|
||||||
"@nuxt/fonts": "0.11.4",
|
"@nuxt/fonts": "0.11.4",
|
||||||
"@nuxt/icon": "1.15.0",
|
"@nuxt/icon": "1.15.0",
|
||||||
"@nuxt/image": "1.10.0",
|
"@nuxt/image": "1.10.0",
|
||||||
|
|||||||
@ -1,17 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="coords" class="delivery">
|
<div v-if="coords" class="delivery">
|
||||||
<div class="delivery__sidebar">
|
<div class="delivery__sidebar">
|
||||||
|
<UInput v-model="searchTerm" size="xl" class="w-full" placeholder="pvz" />
|
||||||
|
|
||||||
|
<div class="delivery__items">
|
||||||
<div
|
<div
|
||||||
v-for="point in yandexPvz?.points"
|
v-for="point in filteredPvz?.points"
|
||||||
:key="point.id"
|
:key="point.id"
|
||||||
class="pickup-point-item"
|
class="pickup-point-item"
|
||||||
@click="onPickupClick(point)"
|
@click="centerMap(point)"
|
||||||
>
|
>
|
||||||
<h3>Yandex</h3>
|
<h3>Yandex</h3>
|
||||||
{{ `${point?.address?.street} ${point?.address?.house}` }}
|
{{ `${point?.address?.street} ${point?.address?.house}` }}
|
||||||
<Icon class="pickup-point-item__action" name="lucide:chevron-right" />
|
<Icon class="pickup-point-item__action" name="lucide:chevron-right" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<PvzMap ref="mapRef" :pickup-points="yandexPvz?.points" />
|
<PvzMap ref="mapRef" :pickup-points="yandexPvz?.points" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -21,9 +26,10 @@ import { useGeolocation } from '@vueuse/core'
|
|||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
import PvzMap from '~/components/PvzMap.vue'
|
import PvzMap from '~/components/PvzMap.vue'
|
||||||
|
|
||||||
const yandexPvz = ref('')
|
|
||||||
const { coords } = useGeolocation()
|
const { coords } = useGeolocation()
|
||||||
const city = ref('')
|
const mapRef = ref<InstanceType<typeof PvzMap> | null>(null)
|
||||||
|
const yandexPvz = ref('')
|
||||||
|
const searchTerm = ref('')
|
||||||
|
|
||||||
const waitForCoords = () =>
|
const waitForCoords = () =>
|
||||||
new Promise<void>((resolve) => {
|
new Promise<void>((resolve) => {
|
||||||
@ -38,11 +44,13 @@ const waitForCoords = () =>
|
|||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await waitForCoords()
|
await waitForCoords()
|
||||||
|
|
||||||
|
// обратное геокодирование (т.е. получаение города из координат)
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`https://nominatim.openstreetmap.org/reverse?lat=${coords.value.latitude}&lon=${coords.value.longitude}&format=json&accept-language=ru`,
|
`https://nominatim.openstreetmap.org/reverse?lat=${coords.value.latitude}&lon=${coords.value.longitude}&format=json&accept-language=ru`,
|
||||||
)
|
)
|
||||||
const openstreetmap = await response.json()
|
const openstreetmap = await response.json()
|
||||||
|
|
||||||
|
// получение geo_id из названию города
|
||||||
const { data: yandexLocation } = await useFetch('/api/yandex_location', {
|
const { data: yandexLocation } = await useFetch('/api/yandex_location', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
@ -50,6 +58,7 @@ onMounted(async () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// получения пунктов выдачи города из geo_id
|
||||||
const { data: yandexPvzApi } = await useFetch('/api/yandex_pvz', {
|
const { data: yandexPvzApi } = await useFetch('/api/yandex_pvz', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
@ -60,14 +69,19 @@ onMounted(async () => {
|
|||||||
yandexPvz.value = yandexPvzApi.value
|
yandexPvz.value = yandexPvzApi.value
|
||||||
})
|
})
|
||||||
|
|
||||||
const mapRef = ref<InstanceType<typeof PvzMap> | null>(null)
|
// TODO сделать отдельный компонент UISearch
|
||||||
|
const filteredPvz = computed(() => {
|
||||||
|
if (!searchTerm.value && searchTerm.value === '')
|
||||||
|
return yandexPvz.value
|
||||||
|
|
||||||
const onPickupClick = (point: any) => {
|
const result = yandexPvz?.value?.points?.filter(value => value?.address?.full_address?.toLowerCase().includes(searchTerm.value.toLowerCase()))
|
||||||
const lat = point?.position?.latitude
|
return {
|
||||||
const lon = point?.position?.longitude
|
points: [...result],
|
||||||
if (typeof lat === 'number' && typeof lon === 'number') {
|
|
||||||
mapRef.value?.centerMap(lat, lon)
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const centerMap = (point: any) => {
|
||||||
|
mapRef.value?.centerMap([point?.position?.longitude, point?.position?.latitude])
|
||||||
}
|
}
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
@ -82,9 +96,13 @@ definePageMeta({
|
|||||||
|
|
||||||
&__sidebar {
|
&__sidebar {
|
||||||
width: 410px;
|
width: 410px;
|
||||||
height: calc(100dvh - 54px);
|
padding: 24px;
|
||||||
flex-shrink: 0;
|
}
|
||||||
|
|
||||||
|
&__items {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
flex-shrink: 0;
|
||||||
|
height: calc(100dvh - 54px - 40px - 24px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +110,7 @@ definePageMeta({
|
|||||||
position: relative;
|
position: relative;
|
||||||
width: 400px;
|
width: 400px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
padding: 24px;
|
padding-block: 24px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user