增强SelectMap组件,添加用户当前位置获取功能,优化地址解析逻辑和错误处理,改进加载状态显示,提升用户体验。

This commit is contained in:
超级老白兔
2025-11-21 19:02:41 +08:00
parent 6c9551be05
commit 782031cbc6

View File

@@ -57,6 +57,7 @@ const SelectMap: React.FC<SelectMapProps> = ({
);
const [map, setMap] = useState<any>(null);
const [isReverseGeocoding, setIsReverseGeocoding] = useState(false);
const [isLocating, setIsLocating] = useState(false);
const mapContainerRef = useRef<HTMLDivElement>(null);
const geocoderRef = useRef<any>(null);
const searchServiceRef = useRef<any>(null);
@@ -79,27 +80,70 @@ const SelectMap: React.FC<SelectMapProps> = ({
geocoderRef.current = new window.qq.maps.Geocoder({
complete: (result: any) => {
setIsReverseGeocoding(false);
try {
if (result && result.detail) {
const detail = result.detail;
const location = detail.location || detail.latLng;
if (location) {
const lat =
location.lat || (location.getLat ? location.getLat() : null);
const lng =
location.lng || (location.getLng ? location.getLng() : null);
if (lat && lng) {
// 构建地址标签
let addressLabel = "";
if (detail.formatted_addresses) {
addressLabel =
detail.formatted_addresses.recommend ||
detail.formatted_addresses.rough ||
"";
}
if (!addressLabel && detail.address) {
addressLabel = detail.address;
}
if (!addressLabel && detail.addressComponents) {
const addr = detail.addressComponents;
const parts = [];
if (addr.province) parts.push(addr.province);
if (addr.city) parts.push(addr.city);
if (addr.district) parts.push(addr.district);
if (addr.street) parts.push(addr.street);
if (addr.street_number) parts.push(addr.street_number);
addressLabel = parts.join("");
}
if (!addressLabel) {
addressLabel = `${lat.toFixed(6)}, ${lng.toFixed(6)}`;
}
setSelectedLocation({
x: location.lng?.toString() || location.getLng().toString(),
y: location.lat?.toString() || location.getLat().toString(),
x: lng.toString(),
y: lat.toString(),
scale: "16",
label:
detail.address || detail.formatted_addresses?.recommend || "",
label: addressLabel,
poiname:
detail.addressComponents?.street || detail.address || "",
detail.addressComponents?.street || detail.poiid || "",
maptype: "0",
poiid: detail.poiid || "",
});
} else {
message.warning("无法解析位置信息");
}
} else {
message.warning("未找到位置信息");
}
} else {
message.warning("获取地址信息失败:返回数据为空");
}
} catch (error) {
console.error("解析地址信息错误:", error);
message.error("解析地址信息失败");
}
},
error: () => {
error: (error: any) => {
setIsReverseGeocoding(false);
message.error("获取地址信息失败");
console.error("反向地理编码错误:", error);
message.error("获取地址信息失败,请稍后重试");
},
});
@@ -163,10 +207,60 @@ const SelectMap: React.FC<SelectMapProps> = ({
markerRef.current = newMarker;
// 反向地理编码
if (geocoderRef.current) {
setIsReverseGeocoding(true);
geocoderRef.current.getAddress(new window.qq.maps.LatLng(lat, lng));
}
});
// 获取用户当前位置
if (navigator.geolocation) {
setIsLocating(true);
navigator.geolocation.getCurrentPosition(
position => {
setIsLocating(false);
const userLat = position.coords.latitude;
const userLng = position.coords.longitude;
// 移动地图中心到用户位置
const userLocation = new window.qq.maps.LatLng(userLat, userLng);
mapInstance.setCenter(userLocation);
mapInstance.setZoom(16);
// 添加标记点
if (markerRef.current) {
markerRef.current.setMap(null);
}
const newMarker = new window.qq.maps.Marker({
position: userLocation,
map: mapInstance,
});
markerRef.current = newMarker;
// 获取用户位置的地址信息
if (geocoderRef.current) {
setIsReverseGeocoding(true);
geocoderRef.current.getAddress(userLocation);
}
},
error => {
setIsLocating(false);
console.error("获取位置失败:", error);
// 如果获取位置失败,使用默认位置(北京)
message.info("无法获取您的位置,已定位到默认位置");
},
{
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 0,
},
);
} else {
message.info("您的浏览器不支持地理定位功能");
}
return () => {
if (mapInstance) {
window.qq.maps.event.clearListeners(mapInstance, "click");
@@ -309,6 +403,7 @@ const SelectMap: React.FC<SelectMapProps> = ({
}
setIsSearching(false);
setIsReverseGeocoding(false);
setIsLocating(false);
onClose();
};
@@ -379,12 +474,12 @@ const SelectMap: React.FC<SelectMapProps> = ({
{/* 地图区域 */}
<div className={styles.mapArea}>
<Spin
spinning={isReverseGeocoding || isLocating}
tip={isLocating ? "正在定位您的位置..." : "正在获取地址信息..."}
>
<div ref={mapContainerRef} className={styles.mapContainer} />
{isReverseGeocoding && (
<div className={styles.loadingOverlay}>
<Spin tip="正在获取地址信息..." />
</div>
)}
</Spin>
</div>
{/* 选中位置信息 */}