fix(admin,partner): harden Tencent locpicker coords and confirm flow
CI / verify (pull_request) Has been cancelled
CI / verify (pull_request) Has been cancelled
Accept latlng-only postMessage, confirm before apply, and read LBS key per request. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -40,9 +40,13 @@ export default function TencentLocPickerOverlay({
|
||||
const [key, setKey] = useState<string | null>(cachedKey ?? null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState('');
|
||||
const [pending, setPending] = useState<TencentPickedLocation | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
if (!open) {
|
||||
setPending(null);
|
||||
return;
|
||||
}
|
||||
let cancelled = false;
|
||||
setError('');
|
||||
if (key) return;
|
||||
@@ -67,23 +71,30 @@ export default function TencentLocPickerOverlay({
|
||||
function onMessage(event: MessageEvent) {
|
||||
const picked = parseTencentLocPickerMessage(event.data);
|
||||
if (!picked) return;
|
||||
onPick(picked);
|
||||
onClose();
|
||||
setPending(picked);
|
||||
}
|
||||
window.addEventListener('message', onMessage);
|
||||
return () => window.removeEventListener('message', onMessage);
|
||||
}, [open, onPick, onClose]);
|
||||
}, [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: latitude != null ? Number(latitude) : undefined,
|
||||
longitude: longitude != null ? Number(longitude) : undefined,
|
||||
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 (
|
||||
<div
|
||||
style={{
|
||||
@@ -109,21 +120,50 @@ export default function TencentLocPickerOverlay({
|
||||
关闭
|
||||
</button>
|
||||
<span style={{ fontWeight: 600 }}>地图选点</span>
|
||||
<span style={{ width: 52 }} />
|
||||
<button
|
||||
type="button"
|
||||
className="partner-btn-primary"
|
||||
style={{ padding: '6px 12px', opacity: pending ? 1 : 0.45, width: 'auto' }}
|
||||
disabled={!pending}
|
||||
onClick={confirmPick}
|
||||
>
|
||||
确认
|
||||
</button>
|
||||
</div>
|
||||
{pending ? (
|
||||
<p
|
||||
className="label-md text-muted"
|
||||
style={{
|
||||
margin: 0,
|
||||
padding: '8px 16px',
|
||||
borderBottom: '1px solid rgba(0,0,0,0.04)',
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
已选 {pending.latitude.toFixed(6)}, {pending.longitude.toFixed(6)}
|
||||
{pending.name ? ` · ${pending.name}` : ''}
|
||||
</p>
|
||||
) : null}
|
||||
<div style={{ flex: 1, minHeight: 0, position: 'relative' }}>
|
||||
{loading ? (
|
||||
<p className="label-md text-muted" style={{ padding: 24, textAlign: 'center' }}>
|
||||
加载地图…
|
||||
</p>
|
||||
) : error ? (
|
||||
<p className="label-md" style={{ padding: 24, color: 'var(--color-heritage-red, #a61d24)' }}>
|
||||
{error}
|
||||
</p>
|
||||
<div style={{ padding: 24 }}>
|
||||
<p className="label-md" style={{ color: 'var(--color-heritage-red, #a61d24)' }}>
|
||||
{error}
|
||||
</p>
|
||||
<p className="label-md text-muted" style={{ marginTop: 12 }}>
|
||||
若地图能开但看不到附近地点列表,请确认 Key 已开启 WebServiceAPI,并白名单
|
||||
apis.map.qq.com。
|
||||
</p>
|
||||
</div>
|
||||
) : src ? (
|
||||
<iframe
|
||||
title="腾讯地图选点"
|
||||
src={src}
|
||||
allow="geolocation *"
|
||||
style={{ width: '100%', height: '100%', border: 0, display: 'block' }}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
Reference in New Issue
Block a user