f396cb1fef
Hide locate on store forms; restore optimized locpicker overlay. Add TENCENT_LBS_SECRET_KEY and server-side sig for WebServiceAPI. Co-authored-by: Cursor <cursoragent@cursor.com>
102 lines
2.4 KiB
TypeScript
102 lines
2.4 KiB
TypeScript
export type TencentPickedLocation = {
|
||
latitude: number;
|
||
longitude: number;
|
||
address?: string;
|
||
name?: string;
|
||
cityname?: string;
|
||
};
|
||
|
||
export type LbsPlaceItem = {
|
||
id: string;
|
||
title: string;
|
||
address: string;
|
||
latitude: number;
|
||
longitude: number;
|
||
city?: string;
|
||
};
|
||
|
||
export function placeToPicked(item: LbsPlaceItem): TencentPickedLocation {
|
||
return {
|
||
latitude: item.latitude,
|
||
longitude: item.longitude,
|
||
address: item.address || undefined,
|
||
name: item.title || undefined,
|
||
cityname: item.city || undefined,
|
||
};
|
||
}
|
||
|
||
type LocPickerMessage = {
|
||
module?: string;
|
||
latlng?: { lat?: number; lng?: number };
|
||
poiaddress?: string;
|
||
poiname?: string;
|
||
cityname?: string;
|
||
};
|
||
|
||
const REFERER = 'dukang';
|
||
|
||
function coerceMessageData(data: unknown): LocPickerMessage | null {
|
||
if (data == null) return null;
|
||
if (typeof data === 'string') {
|
||
const trimmed = data.trim();
|
||
if (!trimmed || (trimmed[0] !== '{' && trimmed[0] !== '[')) return null;
|
||
try {
|
||
return JSON.parse(trimmed) as LocPickerMessage;
|
||
} catch {
|
||
return null;
|
||
}
|
||
}
|
||
if (typeof data === 'object') return data as LocPickerMessage;
|
||
return null;
|
||
}
|
||
|
||
/** 腾讯地图选点组件(iframe) */
|
||
export function buildTencentLocPickerUrl(
|
||
key: string,
|
||
options?: { latitude?: number; longitude?: number },
|
||
): string {
|
||
const params = new URLSearchParams({
|
||
search: '1',
|
||
type: '1',
|
||
key,
|
||
referer: REFERER,
|
||
policy: '1',
|
||
total: '20',
|
||
radius: '2000',
|
||
mapdraggable: '1',
|
||
});
|
||
const lat = options?.latitude;
|
||
const lng = options?.longitude;
|
||
if (
|
||
lat != null &&
|
||
lng != null &&
|
||
Number.isFinite(lat) &&
|
||
Number.isFinite(lng) &&
|
||
!(lat === 0 && lng === 0)
|
||
) {
|
||
params.set('coord', `${lat},${lng}`);
|
||
params.set('coordtype', '5');
|
||
}
|
||
return `https://apis.map.qq.com/tools/locpicker?${params.toString()}`;
|
||
}
|
||
|
||
export function parseTencentLocPickerMessage(data: unknown): TencentPickedLocation | null {
|
||
const loc = coerceMessageData(data);
|
||
if (!loc || loc.module !== 'locationPicker') return null;
|
||
const lat = Number(loc.latlng?.lat);
|
||
const lng = Number(loc.latlng?.lng);
|
||
if (!Number.isFinite(lat) || !Number.isFinite(lng)) return null;
|
||
|
||
let name = loc.poiname?.trim() || undefined;
|
||
const address = loc.poiaddress?.trim() || undefined;
|
||
if (name === '我的位置' && address) name = address;
|
||
|
||
return {
|
||
latitude: lat,
|
||
longitude: lng,
|
||
address,
|
||
name,
|
||
cityname: loc.cityname?.trim() || undefined,
|
||
};
|
||
}
|