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(null) const locationStatus = ref('idle') const rangeRadius = ref(DEFAULT_VISIT_RANGE_RADIUS) let locationTimer: ReturnType | 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) ) }