定位获取城市功能,需要微信地图的key?

This commit is contained in:
2026-07-06 14:02:07 +08:00
parent 67af6d7d53
commit c87d79109a
18 changed files with 792 additions and 70 deletions
+4 -1
View File
@@ -2,9 +2,11 @@ export { isWechatBrowser, isMiniProgram, getRuntimePlatform } from './env';
export { initWechatJssdk, ensureJssdkReady, isJssdkReady } from './jssdk';
export {
getWechatLocation,
getWechatLocationDetailed,
canUseWechatLocation,
isWechatEnv,
} from './location';
export type { WechatLocationOutcome } from './location';
export { scanQrCode } from './scan';
export { invokeWechatPay } from './pay';
export { chooseWechatImages, canUseWechatChooseImage } from './chooseImage';
@@ -24,7 +26,7 @@ export { DEFAULT_JS_API_LIST } from './types';
import type { WeixinSdkConfig } from './types';
import { initWechatJssdk } from './jssdk';
import { getWechatLocation } from './location';
import { getWechatLocation, getWechatLocationDetailed } from './location';
import { scanQrCode } from './scan';
import { invokeWechatPay } from './pay';
import { chooseWechatImages } from './chooseImage';
@@ -45,6 +47,7 @@ export function createWeixinSdk(config: WeixinSdkConfig) {
bindWechatPhone(config, payload),
getPhoneNumber: () => getWechatPhoneNumber(config),
getLocation: () => getWechatLocation(config),
getLocationDetailed: () => getWechatLocationDetailed(config),
scanQrCode: () => scanQrCode(config),
chooseImages: (options?: Parameters<typeof chooseWechatImages>[1]) =>
chooseWechatImages(config, options),
+46 -11
View File
@@ -3,16 +3,29 @@ import { getRuntimePlatform, isWechatBrowser } from './env';
import { ensureJssdkReady } from './jssdk';
import type { WeixinSdkConfig } from './types';
export type WechatLocationOutcome = {
sdk: 'jssdk' | 'geolocation';
location: WechatGpsLocation | null;
errMsg?: string;
};
/** 获取 GPS 定位(微信 JSSDK / 小程序优先,否则 H5 Geolocation */
export async function getWechatLocation(config?: WeixinSdkConfig): Promise<WechatGpsLocation | null> {
const outcome = await getWechatLocationDetailed(config);
return outcome.location;
}
export async function getWechatLocationDetailed(
config?: WeixinSdkConfig,
): Promise<WechatLocationOutcome> {
const platform = getRuntimePlatform();
if (platform === 'mini' && window.wx?.getLocation) {
return new Promise((resolve) => {
window.wx!.getLocation!({
type: 'gcj02',
success: (res) => resolve(res),
fail: () => resolve(null),
success: (res) => resolve({ sdk: 'jssdk', location: res }),
fail: (res) => resolve({ sdk: 'jssdk', location: null, errMsg: res.errMsg }),
});
});
}
@@ -25,29 +38,51 @@ export async function getWechatLocation(config?: WeixinSdkConfig): Promise<Wecha
getAccessToken: config.getAccessToken,
});
if (window.wx?.getLocation) {
const jsApiOk = await new Promise<boolean>((resolve) => {
window.wx!.checkJsApi?.({
jsApiList: ['getLocation'],
success: (res) => resolve(!!res.checkResult?.getLocation),
fail: () => resolve(false),
});
});
if (!jsApiOk) {
return { sdk: 'jssdk', location: null, errMsg: 'getLocation 未授权或不可用' };
}
return new Promise((resolve) => {
window.wx!.getLocation!({
type: 'gcj02',
success: (res) => resolve(res),
fail: () => resolve(null),
success: (res) => resolve({ sdk: 'jssdk', location: res }),
fail: (res) => resolve({ sdk: 'jssdk', location: null, errMsg: res.errMsg }),
});
});
}
} catch {
/* fall through */
return { sdk: 'jssdk', location: null, errMsg: '微信 JSSDK getLocation 不可用' };
} catch (err) {
const errMsg = err instanceof Error ? err.message : String(err);
return { sdk: 'jssdk', location: null, errMsg };
}
}
if (typeof navigator === 'undefined' || !navigator.geolocation) return null;
if (typeof navigator === 'undefined' || !navigator.geolocation) {
return { sdk: 'geolocation', location: null, errMsg: '浏览器不支持定位' };
}
return new Promise((resolve) => {
navigator.geolocation.getCurrentPosition(
(pos) =>
resolve({
latitude: pos.coords.latitude,
longitude: pos.coords.longitude,
accuracy: pos.coords.accuracy,
sdk: 'geolocation',
location: {
latitude: pos.coords.latitude,
longitude: pos.coords.longitude,
accuracy: pos.coords.accuracy,
},
}),
(err) =>
resolve({
sdk: 'geolocation',
location: null,
errMsg: err.message || '定位失败',
}),
() => resolve(null),
{ enableHighAccuracy: false, timeout: 8000, maximumAge: 60_000 },
);
});