| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- import { ref } from 'vue'
- import { onHide, onShow, onUnload } from '@dcloudio/uni-app'
- import { getLocation, type LocationResult } from '@/lib/location'
- import { getDictTypeApi } from '@/services/modules/common'
- import { DEFAULT_VISIT_RANGE_RADIUS } from '../taskVisit.config'
- import type { VisitLocationStatus } from '../types'
- const LOCATION_POLL_INTERVAL = 5 * 60_000
- export const useVisitLocation = () => {
- const currentLocation = ref<LocationResult | null>(null)
- const locationStatus = ref<VisitLocationStatus>('idle')
- const rangeRadius = ref(DEFAULT_VISIT_RANGE_RADIUS)
- let locationTimer: ReturnType<typeof setInterval> | undefined
- let locating = false
- const stopLocationPolling = () => {
- if (!locationTimer) return
- clearInterval(locationTimer)
- locationTimer = undefined
- }
- const refreshCurrentLocation = async () => {
- if (locating) return
- locating = true
- if (!currentLocation.value) {
- locationStatus.value = 'locating'
- }
- try {
- const location = await getLocation()
- if (!isValidLocation(location)) {
- throw new Error('Invalid location result')
- }
- currentLocation.value = location
- locationStatus.value = 'ready'
- } catch {
- locationStatus.value = 'error'
- // 授权失败后暂停自动轮询,避免反复唤起授权提示;用户可手动重试。
- stopLocationPolling()
- } finally {
- locating = false
- }
- }
- const startLocationPolling = () => {
- stopLocationPolling()
- void refreshCurrentLocation()
- locationTimer = setInterval(() => {
- void refreshCurrentLocation()
- }, LOCATION_POLL_INTERVAL)
- }
- const loadRangeRadius = async () => {
- try {
- const res = await getDictTypeApi('point_jwd')
- const radius = Number(res.data?.[0]?.value)
- if (Number.isFinite(radius) && radius > 0) {
- rangeRadius.value = radius
- }
- } catch {
- rangeRadius.value = DEFAULT_VISIT_RANGE_RADIUS
- }
- }
- onShow(() => {
- startLocationPolling()
- void loadRangeRadius()
- })
- onHide(stopLocationPolling)
- onUnload(stopLocationPolling)
- return {
- currentLocation,
- locationStatus,
- rangeRadius,
- refreshCurrentLocation: startLocationPolling,
- }
- }
- const isValidLocation = (location: LocationResult) => {
- return (
- Number.isFinite(location.latitude) &&
- Number.isFinite(location.longitude) &&
- !(location.latitude === 0 && location.longitude === 0)
- )
- }
|