import { useEffect, useMemo, useState } from 'react'; import type { ClientRuntimeConfig } from '@dukang/shared-types'; import { request } from '../lib/api'; import { buildTencentLocPickerUrl, parseTencentLocPickerMessage, type TencentPickedLocation, } from '../lib/tencentLocPicker'; type Props = { open: boolean; onClose: () => void; onPick: (loc: TencentPickedLocation) => void; latitude?: number | null; longitude?: number | null; /** 保留兼容,iframe 选点不使用 */ region?: string | null; }; let cachedKey: string | null | undefined; async function loadTencentLbsKey(): Promise { if (cachedKey) return cachedKey; const cfg = await request('PARTNER_H5', '/common/client-config', { silent: true, }); const key = (cfg.tencentLbsKey || '').trim(); if (!key) { throw new Error('未配置腾讯位置服务 Key,请联系管理员在系统设置中配置'); } cachedKey = key; return key; } export default function TencentLocPickerOverlay({ open, onClose, onPick, latitude, longitude, }: Props) { const [key, setKey] = useState(cachedKey ?? null); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); /** 选点结果仅存内存,界面不展示经纬度 */ const [pending, setPending] = useState(null); const [iframeReady, setIframeReady] = useState(false); useEffect(() => { if (!open) { setPending(null); setIframeReady(false); setError(''); return; } let cancelled = false; if (key) return; setLoading(true); void loadTencentLbsKey() .then((k) => { if (!cancelled) setKey(k); }) .catch((e) => { if (!cancelled) setError(e instanceof Error ? e.message : '加载地图配置失败'); }) .finally(() => { if (!cancelled) setLoading(false); }); return () => { cancelled = true; }; }, [open, key]); useEffect(() => { if (!open) return; function onMessage(event: MessageEvent) { const picked = parseTencentLocPickerMessage(event.data); if (!picked) return; setPending(picked); } window.addEventListener('message', onMessage); return () => window.removeEventListener('message', onMessage); }, [open]); const src = useMemo(() => { if (!key) return ''; const lat = latitude != null ? Number(latitude) : undefined; const lng = longitude != null ? Number(longitude) : undefined; return buildTencentLocPickerUrl(key, { latitude: lat != null && Number.isFinite(lat) ? lat : undefined, longitude: lng != null && Number.isFinite(lng) ? lng : undefined, }); }, [key, latitude, longitude]); if (!open) return null; function confirmPick() { if (!pending) return; onPick(pending); onClose(); } return (

地图选点

{pending ? '已选定位置,请点右上角「确认」' : '在地图上点选或搜索地点,选中后点右上角「确认」'}

{loading ? (

正在加载地图…

) : error ? (

{error}

请确认系统设置中已配置腾讯位置服务 Key,并白名单 apis.map.qq.com。

) : src ? ( <> {!iframeReady ? (

地图加载中…

) : null}