feat: first commit
This commit is contained in:
133
src/utils/location.ts
Normal file
133
src/utils/location.ts
Normal file
@ -0,0 +1,133 @@
|
||||
import Taro from '@tarojs/taro';
|
||||
|
||||
import { isNaN } from 'lodash-es';
|
||||
|
||||
import { CITY_CODE_TO_NAME_MAP, COUNTY_CODE_TO_NAME_MAP, PROVINCE_CODE_TO_NAME_MAP } from '@/constants/city';
|
||||
import http from '@/http';
|
||||
import { API } from '@/http/api';
|
||||
import store from '@/store';
|
||||
import { setLocationInfo } from '@/store/actions';
|
||||
import { selectLocation } from '@/store/selector';
|
||||
import { GetCityCodeRequest, LocationInfo } from '@/types/location';
|
||||
|
||||
import { authorize, getWxSetting } from './wx';
|
||||
|
||||
let locationInfo: Taro.getLocation.SuccessCallbackResult | null = null;
|
||||
let waitAuthorizeLocationPromise: ReturnType<typeof authorize> | null = null;
|
||||
const VALID_DISTANCE_KM = 999;
|
||||
|
||||
export const isValidLocation = (location: LocationInfo) => {
|
||||
if (!location) {
|
||||
return false;
|
||||
}
|
||||
return !isNaN(Number(location.latitude)) && !isNaN(Number(location.longitude));
|
||||
};
|
||||
|
||||
export const isValidDistance = (distance: number) => distance < 1000 * VALID_DISTANCE_KM;
|
||||
|
||||
export const isNotNeedAuthorizeLocation = () => getWxSetting('scope.userLocation');
|
||||
|
||||
export const calcDistance = (distance: number, fractionDigits = 2) => {
|
||||
if (isValidDistance(distance)) {
|
||||
return `${(distance / 1000).toFixed(fractionDigits)}km`;
|
||||
}
|
||||
return '999km';
|
||||
};
|
||||
|
||||
export const getCurrentCity = () => {
|
||||
const cityCode = selectLocation(store.getState()).cityCode;
|
||||
return CITY_CODE_TO_NAME_MAP.get(cityCode) || '';
|
||||
};
|
||||
|
||||
export const getCityValues = (codes: string[] = [], separator: string = '') => {
|
||||
const [province, city, county] = codes;
|
||||
const values: string[] = [];
|
||||
if (province) {
|
||||
const v = PROVINCE_CODE_TO_NAME_MAP.get(province);
|
||||
v && values.push(v);
|
||||
}
|
||||
if (city) {
|
||||
const v = CITY_CODE_TO_NAME_MAP.get(city);
|
||||
v && values.push(v);
|
||||
}
|
||||
if (county) {
|
||||
const v = COUNTY_CODE_TO_NAME_MAP.get(county);
|
||||
v && values.push(v);
|
||||
}
|
||||
return values.join(separator);
|
||||
};
|
||||
|
||||
export async function waitLocationAuthorizeHidden() {
|
||||
if (!waitAuthorizeLocationPromise) {
|
||||
return;
|
||||
}
|
||||
await waitAuthorizeLocationPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取经纬度信息
|
||||
* @param opts
|
||||
* @returns
|
||||
*/
|
||||
export async function getWxLocation(
|
||||
opts?: Taro.getLocation.Option,
|
||||
force = true
|
||||
): Promise<Taro.getLocation.SuccessCallbackResult | null> {
|
||||
if (locationInfo?.latitude) return Promise.resolve(locationInfo);
|
||||
|
||||
const notNeedAuthorize = await isNotNeedAuthorizeLocation();
|
||||
|
||||
if (!notNeedAuthorize) {
|
||||
waitAuthorizeLocationPromise = authorize('scope.userLocation', '请授权获取位置权限', force);
|
||||
if (!(await waitAuthorizeLocationPromise)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// 重新获取位置信息
|
||||
return new Promise(resolve => {
|
||||
try {
|
||||
Taro.getLocation({
|
||||
type: 'wgs84',
|
||||
...opts,
|
||||
success: res => {
|
||||
setTimeout(() => {
|
||||
locationInfo = null;
|
||||
}, 31000);
|
||||
if (res?.latitude) {
|
||||
locationInfo = res;
|
||||
return resolve(res);
|
||||
}
|
||||
resolve(null);
|
||||
},
|
||||
fail: () => resolve(null),
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function requestLocation(force: boolean = false) {
|
||||
const data = {} as GetCityCodeRequest;
|
||||
const lgInfo = await getWxLocation({}, force);
|
||||
if (!lgInfo) {
|
||||
return;
|
||||
}
|
||||
if (lgInfo?.latitude && lgInfo?.longitude) {
|
||||
data.latitude = lgInfo.latitude;
|
||||
data.longitude = lgInfo.longitude;
|
||||
}
|
||||
|
||||
const location = await http.post<LocationInfo>(API.LOCATION, {
|
||||
data,
|
||||
contentType: 'application/x-www-form-urlencoded',
|
||||
});
|
||||
if (!location.latitude) {
|
||||
location.latitude = data.latitude;
|
||||
}
|
||||
if (!location.longitude) {
|
||||
location.longitude = data.longitude;
|
||||
}
|
||||
store.dispatch(setLocationInfo(location));
|
||||
return location;
|
||||
}
|
||||
Reference in New Issue
Block a user