Add check-in feature and update travel planner UI
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import type { CheckInLocationSnapshot } from '@/domain/check-in'
|
||||
|
||||
interface CurrentLocationOptions {
|
||||
highAccuracyExpireTime?: number
|
||||
timeoutMs?: number
|
||||
}
|
||||
|
||||
function locationOptionsSupported(): boolean {
|
||||
try {
|
||||
return typeof uni.canIUse !== 'function'
|
||||
|| uni.canIUse('getLocation.object.isHighAccuracy')
|
||||
}
|
||||
catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export function isLocationPermissionDenied(error: unknown): boolean {
|
||||
if (!error || typeof error !== 'object')
|
||||
return false
|
||||
const message = String((error as { errMsg?: unknown }).errMsg ?? '')
|
||||
return !/privacy/i.test(message)
|
||||
&& /auth deny|auth denied|authorize:fail|permission/i.test(message)
|
||||
}
|
||||
|
||||
export function getCurrentGcj02Location(options: CurrentLocationOptions = {}): Promise<CheckInLocationSnapshot> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const highAccuracyExpireTime = Math.max(3000, options.highAccuracyExpireTime ?? 8000)
|
||||
const timeoutMs = Math.max(3000, options.timeoutMs ?? 15000)
|
||||
let settled = false
|
||||
let timeout: ReturnType<typeof setTimeout> | null = null
|
||||
const finish = (callback: () => void) => {
|
||||
if (settled)
|
||||
return
|
||||
settled = true
|
||||
if (timeout)
|
||||
clearTimeout(timeout)
|
||||
callback()
|
||||
}
|
||||
timeout = setTimeout(() => {
|
||||
finish(() => reject(new Error('定位超时,请到开阔处重试')))
|
||||
}, timeoutMs)
|
||||
const commonOptions = {
|
||||
type: 'gcj02' as const,
|
||||
success: (result: UniNamespace.GetLocationSuccess) => {
|
||||
const longitude = Number(result.longitude)
|
||||
const latitude = Number(result.latitude)
|
||||
const accuracy = Number(result.accuracy ?? result.horizontalAccuracy)
|
||||
if (!Number.isFinite(longitude) || !Number.isFinite(latitude)) {
|
||||
finish(() => reject(new Error('定位结果无效,请稍后重试')))
|
||||
return
|
||||
}
|
||||
finish(() => resolve({
|
||||
longitude,
|
||||
latitude,
|
||||
accuracy: Number.isFinite(accuracy) && accuracy >= 0 ? accuracy : null,
|
||||
receivedAt: new Date().toISOString(),
|
||||
coordinateSystem: 'GCJ02',
|
||||
}))
|
||||
},
|
||||
fail: (error: unknown) => finish(() => reject(error)),
|
||||
}
|
||||
|
||||
if (locationOptionsSupported()) {
|
||||
uni.getLocation({
|
||||
...commonOptions,
|
||||
isHighAccuracy: true,
|
||||
highAccuracyExpireTime,
|
||||
})
|
||||
return
|
||||
}
|
||||
uni.getLocation(commonOptions)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user