/** * 定位服务工具类 * 提供获取当前位置、地址解析等功能 */ /** * 获取当前位置 * @returns Promise<{latitude, longitude, address}> */ export const getCurrentLocation = () => { return new Promise((resolve, reject) => { uni.showLoading({ title: '正在获取位置...' }); uni.getLocation({ type: 'gcj02', // 使用国测局坐标系 geocode: true, // 解析地址信息 success: (res) => { console.log('📍 获取位置成功:', res); const locationData = { latitude: res.latitude, longitude: res.longitude, address: res.address || '位置信息获取中...' }; // 如果没有地址信息,尝试逆地理编码 if (!res.address) { reverseGeocode(res.latitude, res.longitude) .then(address => { locationData.address = address; resolve(locationData); }) .catch(() => { locationData.address = `${res.latitude.toFixed(6)}, ${res.longitude.toFixed(6)}`; resolve(locationData); }); } else { resolve(locationData); } }, fail: (err) => { console.error('❌ 获取位置失败:', err); let errorMsg = '获取位置失败'; if (err.errMsg) { if (err.errMsg.includes('auth deny')) { errorMsg = '位置权限被拒绝,请在设置中开启位置权限'; } else if (err.errMsg.includes('locate fail')) { errorMsg = '定位失败,请检查网络连接和GPS设置'; } } reject(new Error(errorMsg)); }, complete: () => { uni.hideLoading(); } }); }); }; /** * 逆地理编码 - 根据坐标获取地址 * @param {number} latitude 纬度 * @param {number} longitude 经度 * @returns Promise */ export const reverseGeocode = (latitude, longitude) => { return new Promise((resolve, reject) => { // 这里可以调用第三方地图服务API进行逆地理编码 // 暂时返回坐标信息 const address = `${latitude.toFixed(6)}, ${longitude.toFixed(6)}`; resolve(address); }); }; /** * 检查定位权限 * @returns Promise */ export const checkLocationPermission = () => { return new Promise((resolve) => { // #ifdef APP-PLUS const permissions = ['android.permission.ACCESS_FINE_LOCATION']; plus.android.requestPermissions(permissions, (result) => { resolve(result.granted && result.granted.length > 0); }, (error) => { console.error('权限检查失败:', error); resolve(false); }); // #endif // #ifndef APP-PLUS resolve(true); // 小程序和H5环境默认有权限 // #endif }); }; /** * 打开位置权限设置 */ export const openLocationSettings = () => { uni.showModal({ title: '位置权限', content: '需要位置权限才能进行签到,请在设置中开启位置权限', confirmText: '去设置', success: (res) => { if (res.confirm) { // #ifdef APP-PLUS plus.runtime.openURL('app-settings:'); // #endif // #ifdef MP-WEIXIN wx.openSetting(); // #endif } } }); }; /** * 计算两点间距离(米) * @param {number} lat1 纬度1 * @param {number} lng1 经度1 * @param {number} lat2 纬度2 * @param {number} lng2 经度2 * @returns {number} 距离(米) */ export const calculateDistance = (lat1, lng1, lat2, lng2) => { const R = 6371000; // 地球半径(米) const dLat = (lat2 - lat1) * Math.PI / 180; const dLng = (lng2 - lng1) * Math.PI / 180; const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * Math.sin(dLng / 2) * Math.sin(dLng / 2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return R * c; };