重置一下
This commit is contained in:
@@ -10,7 +10,7 @@ import {
|
||||
import { ContractData, weChatGroup, ChatRecord } from "@/pages/pc/ckbox/data";
|
||||
import { useWebSocketStore } from "@/store/module/websocket/websocket";
|
||||
|
||||
declare const qq: any;
|
||||
declare const AMap: any;
|
||||
|
||||
interface SelectMapProps {
|
||||
visible: boolean;
|
||||
@@ -34,7 +34,7 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
const pendingClickRef = useRef<{
|
||||
lat: number;
|
||||
lng: number;
|
||||
latlng: any;
|
||||
lnglat: any;
|
||||
} | null>(null); // 保存待处理的点击坐标
|
||||
const [options, setOptions] = useState([]);
|
||||
const [mapLoading, setMapLoading] = useState(true);
|
||||
@@ -56,70 +56,122 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
}, []);
|
||||
|
||||
const addMarker = useCallback(
|
||||
(latlng: any) => {
|
||||
console.log("addMarker 调用,坐标:", latlng);
|
||||
|
||||
const qq = (window as any).qq;
|
||||
if (!qq || !qq.maps || !mapRef.current) {
|
||||
console.error("地图API未加载或地图未初始化");
|
||||
return;
|
||||
}
|
||||
(lnglat: any) => {
|
||||
console.log("addMarker 调用,坐标:", lnglat);
|
||||
|
||||
// 先清除所有现有的标记点
|
||||
clearAllMarkers();
|
||||
|
||||
// 创建新的标记点(腾讯地图默认红色标记)
|
||||
const newMarker = new qq.maps.Marker({
|
||||
position: latlng,
|
||||
// 创建红色图标,保持默认倒水滴形状
|
||||
const redIcon = new AMap.Icon({
|
||||
size: new AMap.Size(25, 34), // 默认标记点尺寸
|
||||
image: "https://webapi.amap.com/theme/v1.3/markers/n/mark_r.png", // 红色标记点图片
|
||||
imageOffset: new AMap.Pixel(0, 0),
|
||||
imageSize: new AMap.Size(25, 34),
|
||||
});
|
||||
|
||||
// 创建新的标记点
|
||||
const newMarker = new AMap.Marker({
|
||||
position: lnglat,
|
||||
map: mapRef.current,
|
||||
icon: redIcon,
|
||||
});
|
||||
|
||||
// 将新标记点添加到数组中
|
||||
markersRef.current.push(newMarker);
|
||||
|
||||
mapRef.current.setCenter(latlng);
|
||||
mapRef.current.setCenter(lnglat);
|
||||
mapRef.current.setZoom(16); // 确保缩放到合适级别
|
||||
console.log("新 marker 已添加并居中");
|
||||
},
|
||||
[clearAllMarkers],
|
||||
);
|
||||
|
||||
// 通用的地址获取函数(使用腾讯地图逆地理编码API)
|
||||
const getAddressForLocation = useCallback((lat: number, lng: number) => {
|
||||
// 通用的地址获取函数
|
||||
const getAddressForLocation = useCallback(
|
||||
(lat: number, lng: number, lnglat: any) => {
|
||||
console.log("=== getAddressForLocation 调用 ===");
|
||||
console.log("坐标:", { lat, lng });
|
||||
console.log(
|
||||
"Geocoder ref 状态:",
|
||||
geocoderRef.current ? "存在" : "不存在",
|
||||
);
|
||||
|
||||
// 使用腾讯地图逆地理编码API
|
||||
const key = "5ZSBZ-23ICU-XDKVU-4ZQ7Z-O35AJ-XUF6S";
|
||||
const url = `https://apis.map.qq.com/ws/geocoder/v1/?location=${lat},${lng}&key=${key}&get_poi=1`;
|
||||
// 检查 Geocoder 是否已初始化
|
||||
if (!geocoderRef.current) {
|
||||
console.warn("Geocoder 未初始化,无法获取地址");
|
||||
return false;
|
||||
}
|
||||
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
console.log("=== 腾讯地图逆地理编码回调 ===");
|
||||
console.log("Result:", result);
|
||||
// 使用更精确的坐标进行查询
|
||||
// 高德地图 getAddress 支持 LngLat 对象或 [lng, lat] 数组
|
||||
let queryLnglat: any;
|
||||
if (lnglat && typeof lnglat.getLat === "function") {
|
||||
// 如果传入的是 LngLat 对象,直接使用
|
||||
queryLnglat = lnglat;
|
||||
} else {
|
||||
// 否则创建新的 LngLat 对象或使用数组格式
|
||||
try {
|
||||
queryLnglat = new AMap.LngLat(lng, lat);
|
||||
} catch (error) {
|
||||
console.error("创建 LngLat 对象失败,使用数组格式:", error);
|
||||
queryLnglat = [lng, lat];
|
||||
}
|
||||
}
|
||||
console.log("调用 geocoder.getAddress,坐标:", queryLnglat);
|
||||
|
||||
if (result.status === 0 && result.result) {
|
||||
const data = result.result;
|
||||
const formattedAddress =
|
||||
data.formatted_addresses?.recommend || data.address || "";
|
||||
const addressComponent = data.address_component || {};
|
||||
const pois = data.pois || [];
|
||||
try {
|
||||
geocoderRef.current.getAddress(
|
||||
queryLnglat,
|
||||
(status: string, result: any) => {
|
||||
console.log("=== Geocoder 回调触发(通用函数) ===");
|
||||
console.log("Status:", status);
|
||||
console.log(
|
||||
"Result:",
|
||||
result ? JSON.stringify(result, null, 2) : "null",
|
||||
);
|
||||
|
||||
if (
|
||||
status === "complete" &&
|
||||
result &&
|
||||
result.info === "OK" &&
|
||||
result.regeocode
|
||||
) {
|
||||
const regeocode = result.regeocode;
|
||||
const formattedAddress = regeocode.formattedAddress || "";
|
||||
const addressComponent = regeocode.addressComponent || {};
|
||||
|
||||
// 构建详细地址信息
|
||||
let addressLabel = formattedAddress;
|
||||
let poiName = "点击位置";
|
||||
|
||||
// 优先级1: 如果有POI信息,优先使用POI名称
|
||||
if (pois.length > 0) {
|
||||
const poi = pois[0];
|
||||
poiName = poi.title || poiName;
|
||||
if (regeocode.pois && regeocode.pois.length > 0) {
|
||||
const poi = regeocode.pois[0];
|
||||
poiName = poi.name || poiName;
|
||||
const poiAddress = poi.address || "";
|
||||
addressLabel = poiAddress
|
||||
? `${poiName} ${poiAddress}`
|
||||
: `${poiName} ${formattedAddress}`;
|
||||
}
|
||||
// 优先级2: 组合地址组件
|
||||
// 优先级2: 如果有建筑物信息
|
||||
else if (regeocode.buildings && regeocode.buildings.length > 0) {
|
||||
const building = regeocode.buildings[0];
|
||||
poiName = building.name || addressComponent.building || poiName;
|
||||
addressLabel = `${poiName} ${formattedAddress}`;
|
||||
}
|
||||
// 优先级3: 如果有AOI(兴趣区域)信息
|
||||
else if (regeocode.aois && regeocode.aois.length > 0) {
|
||||
const aoi = regeocode.aois[0];
|
||||
poiName = aoi.name || poiName;
|
||||
addressLabel = `${poiName} ${formattedAddress}`;
|
||||
}
|
||||
// 优先级4: 使用地址组件构建详细地址
|
||||
else if (addressComponent.building) {
|
||||
poiName = addressComponent.building;
|
||||
addressLabel = `${poiName} ${formattedAddress}`;
|
||||
}
|
||||
// 优先级5: 组合地址组件
|
||||
else {
|
||||
const parts = [];
|
||||
if (addressComponent.province)
|
||||
@@ -127,9 +179,12 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
if (addressComponent.city) parts.push(addressComponent.city);
|
||||
if (addressComponent.district)
|
||||
parts.push(addressComponent.district);
|
||||
if (addressComponent.street) parts.push(addressComponent.street);
|
||||
if (addressComponent.street_number)
|
||||
parts.push(addressComponent.street_number);
|
||||
if (addressComponent.township)
|
||||
parts.push(addressComponent.township);
|
||||
if (addressComponent.street)
|
||||
parts.push(addressComponent.street);
|
||||
if (addressComponent.streetNumber)
|
||||
parts.push(addressComponent.streetNumber);
|
||||
|
||||
if (parts.length > 0) {
|
||||
const fullAddress = parts.join("");
|
||||
@@ -139,7 +194,8 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
"点击位置";
|
||||
addressLabel = fullAddress || formattedAddress;
|
||||
} else {
|
||||
addressLabel = formattedAddress || `纬度: ${lat}, 经度: ${lng}`;
|
||||
addressLabel =
|
||||
formattedAddress || `纬度: ${lat}, 经度: ${lng}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +208,40 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
|
||||
message.success("地址信息获取成功");
|
||||
} else {
|
||||
console.warn("逆地理编码返回异常:", result);
|
||||
console.warn("=== Geocoder 返回异常,尝试 PlaceSearch ===");
|
||||
console.warn("Status:", status);
|
||||
console.warn("Result:", result);
|
||||
// Geocoder 失败,使用 PlaceSearch 作为备用
|
||||
if (placeSearchRef.current) {
|
||||
try {
|
||||
const searchLnglat = lnglat || [lng, lat];
|
||||
placeSearchRef.current.searchNearBy(
|
||||
"",
|
||||
searchLnglat,
|
||||
1000,
|
||||
(searchStatus: string, searchResult: any) => {
|
||||
if (
|
||||
searchStatus === "complete" &&
|
||||
searchResult &&
|
||||
searchResult.info === "OK" &&
|
||||
searchResult.poiList?.pois?.length > 0
|
||||
) {
|
||||
const poi = searchResult.poiList.pois[0];
|
||||
const poiLabel = poi.address
|
||||
? `${poi.name} ${poi.address}`
|
||||
: poi.name;
|
||||
setSelectedLocation({
|
||||
lat: lat,
|
||||
lng: lng,
|
||||
label: poiLabel,
|
||||
poiname: poi.name,
|
||||
});
|
||||
message.success("通过附近搜索获取到地址信息");
|
||||
} else {
|
||||
console.warn("PlaceSearch 返回异常:", {
|
||||
status: searchStatus,
|
||||
result: searchResult,
|
||||
});
|
||||
const coordLabel = `纬度: ${lat}, 经度: ${lng}`;
|
||||
setSelectedLocation({
|
||||
lat: lat,
|
||||
@@ -162,9 +251,13 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
});
|
||||
message.warning("无法获取详细地址信息,但坐标已记录");
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("=== 逆地理编码API调用异常 ===", error);
|
||||
},
|
||||
);
|
||||
} catch (placeSearchError) {
|
||||
console.error(
|
||||
"PlaceSearch.searchNearBy 调用异常:",
|
||||
placeSearchError,
|
||||
);
|
||||
const coordLabel = `纬度: ${lat}, 经度: ${lng}`;
|
||||
setSelectedLocation({
|
||||
lat: lat,
|
||||
@@ -173,37 +266,95 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
poiname: "点击位置",
|
||||
});
|
||||
message.warning("无法获取详细地址信息,但坐标已记录");
|
||||
}
|
||||
} else {
|
||||
const coordLabel = `纬度: ${lat}, 经度: ${lng}`;
|
||||
setSelectedLocation({
|
||||
lat: lat,
|
||||
lng: lng,
|
||||
label: coordLabel,
|
||||
poiname: "点击位置",
|
||||
});
|
||||
}, []);
|
||||
message.warning("无法获取详细地址信息,但坐标已记录");
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("=== Geocoder.getAddress 调用异常 ===", error);
|
||||
// 如果 geocoder 调用失败,尝试使用 PlaceSearch
|
||||
if (placeSearchRef.current) {
|
||||
console.log("尝试使用 PlaceSearch 作为备用方案");
|
||||
try {
|
||||
placeSearchRef.current.searchNearBy(
|
||||
"",
|
||||
lnglat || [lng, lat],
|
||||
1000,
|
||||
(status: string, result: any) => {
|
||||
if (
|
||||
status === "complete" &&
|
||||
result &&
|
||||
result.info === "OK" &&
|
||||
result.poiList?.pois?.length > 0
|
||||
) {
|
||||
const poi = result.poiList.pois[0];
|
||||
const poiLabel = poi.address
|
||||
? `${poi.name} ${poi.address}`
|
||||
: poi.name;
|
||||
setSelectedLocation({
|
||||
lat: lat,
|
||||
lng: lng,
|
||||
label: poiLabel,
|
||||
poiname: poi.name,
|
||||
});
|
||||
message.success("通过附近搜索获取到地址信息");
|
||||
} else {
|
||||
const coordLabel = `纬度: ${lat}, 经度: ${lng}`;
|
||||
setSelectedLocation({
|
||||
lat: lat,
|
||||
lng: lng,
|
||||
label: coordLabel,
|
||||
poiname: "点击位置",
|
||||
});
|
||||
message.warning("无法获取详细地址信息,但坐标已记录");
|
||||
}
|
||||
},
|
||||
);
|
||||
} catch (placeSearchError) {
|
||||
console.error("PlaceSearch 调用也失败:", placeSearchError);
|
||||
const coordLabel = `纬度: ${lat}, 经度: ${lng}`;
|
||||
setSelectedLocation({
|
||||
lat: lat,
|
||||
lng: lng,
|
||||
label: coordLabel,
|
||||
poiname: "点击位置",
|
||||
});
|
||||
message.warning("无法获取详细地址信息,但坐标已记录");
|
||||
}
|
||||
} else {
|
||||
const coordLabel = `纬度: ${lat}, 经度: ${lng}`;
|
||||
setSelectedLocation({
|
||||
lat: lat,
|
||||
lng: lng,
|
||||
label: coordLabel,
|
||||
poiname: "点击位置",
|
||||
});
|
||||
message.warning("无法获取详细地址信息,但坐标已记录");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const initMap = useCallback(() => {
|
||||
console.log("initMap 执行中");
|
||||
setMapLoading(true);
|
||||
|
||||
// 检查 qq 对象是否已加载
|
||||
if (!(window as any).qq || !(window as any).qq.maps) {
|
||||
console.warn("腾讯地图API尚未加载,等待中...");
|
||||
// 等待最多5秒,每100ms检查一次
|
||||
let attempts = 0;
|
||||
const maxAttempts = 50;
|
||||
const checkInterval = setInterval(() => {
|
||||
attempts++;
|
||||
if ((window as any).qq && (window as any).qq.maps) {
|
||||
clearInterval(checkInterval);
|
||||
console.log("腾讯地图API已加载,继续初始化");
|
||||
initMap();
|
||||
} else if (attempts >= maxAttempts) {
|
||||
clearInterval(checkInterval);
|
||||
console.error("腾讯地图API加载超时");
|
||||
message.error("地图加载失败,请刷新页面重试");
|
||||
setMapLoading(false);
|
||||
}
|
||||
}, 100);
|
||||
return;
|
||||
}
|
||||
|
||||
// 确保容器存在
|
||||
const container = document.getElementById("tencent-map-container");
|
||||
const container = document.getElementById("amap-container");
|
||||
if (!container) {
|
||||
console.error("地图容器不存在");
|
||||
setMapLoading(false);
|
||||
@@ -216,13 +367,10 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
container.style.position = "relative";
|
||||
container.style.zIndex = "1";
|
||||
|
||||
const qq = (window as any).qq;
|
||||
|
||||
// 腾讯地图初始化(注意:坐标顺序是 lat, lng)
|
||||
const center = new qq.maps.LatLng(24.470164, 118.113653); // 默认中心
|
||||
const map = new qq.maps.Map("tencent-map-container", {
|
||||
const map = new AMap.Map("amap-container", {
|
||||
zoom: 16,
|
||||
center: center,
|
||||
center: [118.113653, 24.470164], // 默认中心
|
||||
viewMode: "2D", // 明确指定视图模式
|
||||
});
|
||||
mapRef.current = map;
|
||||
|
||||
@@ -232,91 +380,165 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
setMapLoading(false);
|
||||
}, 10000); // 10秒超时
|
||||
|
||||
// 标记服务已初始化
|
||||
geocoderRef.current = true; // 使用HTTP API,不需要实例
|
||||
placeSearchRef.current = true; // 使用HTTP API,不需要实例
|
||||
|
||||
// 获取当前位置(使用浏览器原生定位)
|
||||
console.log("=== 开始获取当前位置 ===");
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
position => {
|
||||
const lat = position.coords.latitude;
|
||||
const lng = position.coords.longitude;
|
||||
const qq = (window as any).qq;
|
||||
if (!qq || !qq.maps) {
|
||||
console.error("腾讯地图API未加载");
|
||||
// 立即加载插件,不等待地图 complete 事件
|
||||
console.log("=== 立即开始加载 AMap 插件(地图创建后) ===");
|
||||
AMap.plugin(
|
||||
[
|
||||
"AMap.AutoComplete",
|
||||
"AMap.PlaceSearch",
|
||||
"AMap.Geocoder",
|
||||
"AMap.Geolocation",
|
||||
],
|
||||
error => {
|
||||
if (error) {
|
||||
console.error("=== AMap 插件加载失败 ===", error);
|
||||
message.error("地图插件加载失败,部分功能可能不可用");
|
||||
clearTimeout(loadingTimeout);
|
||||
setMapLoading(false);
|
||||
return;
|
||||
}
|
||||
const latlng = new qq.maps.LatLng(lat, lng);
|
||||
console.log("=== AMap 插件加载成功 ===");
|
||||
|
||||
// 立即创建 PlaceSearch 和 Geocoder 实例
|
||||
const placeSearch = new AMap.PlaceSearch({
|
||||
city: "全国",
|
||||
map: map,
|
||||
});
|
||||
placeSearchRef.current = placeSearch;
|
||||
console.log("PlaceSearch 实例已创建");
|
||||
|
||||
const geocoder = new AMap.Geocoder({
|
||||
city: "全国",
|
||||
radius: 1000, // 搜索半径,单位米
|
||||
extensions: "all", // 返回详细信息,包括POI、建筑物等
|
||||
});
|
||||
geocoderRef.current = geocoder;
|
||||
console.log("Geocoder 实例已创建并保存到 ref,现在可以立即使用");
|
||||
|
||||
// 创建 Geolocation 实例用于获取当前位置
|
||||
const geolocation = new AMap.Geolocation({
|
||||
enableHighAccuracy: true, // 是否使用高精度定位,默认:true
|
||||
timeout: 10000, // 超过10秒后停止定位,默认:无穷大
|
||||
maximumAge: 0, // 定位结果缓存0毫秒,默认:0
|
||||
convert: true, // 自动偏移坐标,偏移后的坐标为高德坐标,默认:true
|
||||
showButton: false, // 显示定位按钮,默认:true
|
||||
buttonPosition: "RB", // 定位按钮停靠位置,默认:'LB',左下角
|
||||
showMarker: false, // 定位成功后在定位到的位置显示点标记,默认:true
|
||||
showCircle: false, // 定位成功后用圆圈表示定位精度范围,默认:true
|
||||
panToLocation: false, // 定位成功后将定位到的位置作为地图中心点,默认:true
|
||||
zoomToAccuracy: false, // 定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
|
||||
});
|
||||
geolocationRef.current = geolocation;
|
||||
|
||||
// 获取当前位置
|
||||
console.log("=== 开始获取当前位置 ===");
|
||||
geolocation.getCurrentPosition((status: string, result: any) => {
|
||||
console.log("=== 定位回调触发 ===");
|
||||
console.log("定位状态:", status);
|
||||
console.log("定位结果:", result);
|
||||
|
||||
if (status === "complete") {
|
||||
const { position, formattedAddress, addressComponent } = result;
|
||||
const lat = position.lat;
|
||||
const lng = position.lng;
|
||||
const lnglat = new AMap.LngLat(lng, lat);
|
||||
|
||||
console.log("定位成功,当前位置:", { lat, lng });
|
||||
console.log("定位地址:", formattedAddress);
|
||||
|
||||
// 将地图中心设置为当前位置
|
||||
map.setCenter(latlng);
|
||||
map.setCenter(lnglat);
|
||||
map.setZoom(16);
|
||||
|
||||
// 添加当前位置标记
|
||||
addMarker(latlng);
|
||||
addMarker(lnglat);
|
||||
|
||||
// 获取地址信息
|
||||
getAddressForLocation(lat, lng);
|
||||
},
|
||||
error => {
|
||||
console.warn("定位失败:", error);
|
||||
// 设置选中位置信息
|
||||
let addressLabel = formattedAddress || `纬度: ${lat}, 经度: ${lng}`;
|
||||
let poiName = "当前位置";
|
||||
|
||||
// 尝试从地址组件中获取更详细的信息
|
||||
if (addressComponent) {
|
||||
const parts = [];
|
||||
if (addressComponent.province)
|
||||
parts.push(addressComponent.province);
|
||||
if (addressComponent.city) parts.push(addressComponent.city);
|
||||
if (addressComponent.district)
|
||||
parts.push(addressComponent.district);
|
||||
if (addressComponent.street) parts.push(addressComponent.street);
|
||||
if (addressComponent.streetNumber)
|
||||
parts.push(addressComponent.streetNumber);
|
||||
|
||||
if (parts.length > 0) {
|
||||
addressLabel = parts.join("");
|
||||
}
|
||||
|
||||
poiName =
|
||||
addressComponent.street ||
|
||||
addressComponent.district ||
|
||||
"当前位置";
|
||||
}
|
||||
|
||||
setSelectedLocation({
|
||||
lat: lat,
|
||||
lng: lng,
|
||||
label: addressLabel,
|
||||
poiname: poiName,
|
||||
});
|
||||
|
||||
message.success("已获取当前位置");
|
||||
} else {
|
||||
console.warn("定位失败:", result);
|
||||
message.warning(
|
||||
"无法获取当前位置,请手动点击地图选择位置。原因: " +
|
||||
(error.message || "定位服务不可用"),
|
||||
(result.message || "定位服务不可用"),
|
||||
);
|
||||
// 定位失败时,使用默认中心点
|
||||
console.log("使用默认中心点");
|
||||
clearTimeout(loadingTimeout);
|
||||
setMapLoading(false);
|
||||
},
|
||||
{
|
||||
enableHighAccuracy: true,
|
||||
timeout: 10000,
|
||||
maximumAge: 0,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
console.warn("浏览器不支持定位");
|
||||
message.warning("浏览器不支持定位功能");
|
||||
clearTimeout(loadingTimeout);
|
||||
setMapLoading(false);
|
||||
}
|
||||
});
|
||||
|
||||
// 如果有待处理的点击坐标,立即处理它
|
||||
if (pendingClickRef.current) {
|
||||
console.log("=== 检测到待处理的点击坐标,立即处理 ===");
|
||||
const { lat, lng } = pendingClickRef.current;
|
||||
const { lat, lng, lnglat } = pendingClickRef.current;
|
||||
console.log("待处理坐标:", { lat, lng });
|
||||
setTimeout(() => {
|
||||
getAddressForLocation(lat, lng);
|
||||
const success = getAddressForLocation(lat, lng, lnglat);
|
||||
if (success) {
|
||||
console.log("✓ 待处理的坐标已成功获取地址");
|
||||
pendingClickRef.current = null; // 清除待处理坐标
|
||||
} else {
|
||||
console.warn("待处理的坐标获取地址失败");
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// 绑定点击事件
|
||||
console.log("立即绑定点击事件");
|
||||
qq.maps.event.addListener(map, "click", (e: any) => {
|
||||
// 立即绑定点击事件,插件可能已加载或正在加载
|
||||
console.log("立即绑定点击事件(插件可能已初始化)");
|
||||
map.on("click", (e: any) => {
|
||||
console.log("=== 地图点击事件触发 ===");
|
||||
console.log("点击事件对象:", e);
|
||||
console.log("点击位置对象:", e.latLng);
|
||||
console.log("点击位置对象:", e.lnglat);
|
||||
console.log(
|
||||
"Geocoder ref 状态:",
|
||||
geocoderRef.current ? "已初始化" : "未初始化",
|
||||
);
|
||||
|
||||
if (!e || !e.latLng) {
|
||||
console.error("点击事件无效,缺少 latLng");
|
||||
if (!e || !e.lnglat) {
|
||||
console.error("点击事件无效,缺少 lnglat");
|
||||
return;
|
||||
}
|
||||
|
||||
const latlng = e.latLng;
|
||||
const lat = latlng.getLat();
|
||||
const lng = latlng.getLng();
|
||||
const lnglat = e.lnglat;
|
||||
const lat = lnglat.getLat();
|
||||
const lng = lnglat.getLng();
|
||||
console.log(`点击坐标 - 纬度: ${lat}, 经度: ${lng}`);
|
||||
|
||||
// 立即添加标记和居中
|
||||
addMarker(latlng);
|
||||
addMarker(lnglat);
|
||||
|
||||
// 设置基本 selectedLocation(至少有坐标)
|
||||
setSelectedLocation({
|
||||
@@ -326,12 +548,19 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
poiname: "点击位置",
|
||||
});
|
||||
|
||||
// 立即获取地址
|
||||
getAddressForLocation(lat, lng);
|
||||
// 如果 Geocoder 已初始化,立即使用它
|
||||
if (geocoderRef.current) {
|
||||
console.log("Geocoder 已初始化,立即获取地址");
|
||||
getAddressForLocation(lat, lng, lnglat);
|
||||
} else {
|
||||
console.log("Geocoder 未初始化,保存坐标待插件加载完成后处理");
|
||||
// 保存待处理的坐标
|
||||
pendingClickRef.current = { lat, lng, lnglat };
|
||||
}
|
||||
});
|
||||
|
||||
// 等待地图完全加载后关闭 loading
|
||||
qq.maps.event.addListener(map, "tilesloaded", () => {
|
||||
map.on("complete", () => {
|
||||
console.log("地图加载完成");
|
||||
// 清除超时定时器
|
||||
clearTimeout(loadingTimeout);
|
||||
@@ -347,39 +576,30 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
console.log("地图容器指针事件已启用");
|
||||
}
|
||||
});
|
||||
|
||||
// 如果地图加载失败,也设置加载完成
|
||||
map.on("error", (error: any) => {
|
||||
console.error("地图加载错误:", error);
|
||||
clearTimeout(loadingTimeout);
|
||||
setMapLoading(false);
|
||||
message.error("地图加载失败");
|
||||
});
|
||||
}, [addMarker, getAddressForLocation]);
|
||||
|
||||
const handleSearch = value => {
|
||||
if (value) {
|
||||
// 使用腾讯地图搜索建议API
|
||||
const key = "5ZSBZ-23ICU-XDKVU-4ZQ7Z-O35AJ-XUF6S";
|
||||
const url = `https://apis.map.qq.com/ws/place/v1/suggestion?keyword=${encodeURIComponent(value)}&key=${key}®ion=全国`;
|
||||
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.status === 0 && result.data) {
|
||||
AMap.plugin("AMap.AutoComplete", () => {
|
||||
const auto = new AMap.AutoComplete({ city: "全国" });
|
||||
auto.search(value, (status, result) => {
|
||||
if (status === "complete") {
|
||||
setOptions(
|
||||
result.data.map((item: any) => ({
|
||||
value: item.title,
|
||||
data: {
|
||||
name: item.title,
|
||||
address: item.address,
|
||||
district: item.adname,
|
||||
location: {
|
||||
lat: item.location.lat,
|
||||
lng: item.location.lng,
|
||||
},
|
||||
},
|
||||
result.tips.map(tip => ({
|
||||
value: tip.name,
|
||||
data: tip,
|
||||
})),
|
||||
);
|
||||
} else {
|
||||
setOptions([]);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("搜索建议API调用失败:", error);
|
||||
setOptions([]);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
setOptions([]);
|
||||
@@ -387,23 +607,16 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
};
|
||||
|
||||
const onSelect = (value, option) => {
|
||||
const qq = (window as any).qq;
|
||||
if (!qq || !qq.maps) {
|
||||
message.error("地图API未加载,请稍后再试");
|
||||
return;
|
||||
}
|
||||
const { district, address, name, location } = option.data;
|
||||
const latlng = new qq.maps.LatLng(location.lat, location.lng);
|
||||
const lnglat = location;
|
||||
setSelectedLocation({
|
||||
lat: location.lat,
|
||||
lng: location.lng,
|
||||
label: `${name} ${address || district || ""}`,
|
||||
lat: lnglat.lat,
|
||||
lng: lnglat.lng,
|
||||
label: `${name} ${address || district}`,
|
||||
poiname: name,
|
||||
});
|
||||
addMarker(latlng);
|
||||
if (mapRef.current) {
|
||||
mapRef.current.setCenter(latlng);
|
||||
}
|
||||
addMarker(lnglat);
|
||||
mapRef.current.setCenter(lnglat);
|
||||
};
|
||||
|
||||
const handleModalChange = useCallback(
|
||||
@@ -412,17 +625,9 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
console.log("模态打开:开始加载地图脚本");
|
||||
setMapLoading(true);
|
||||
setSelectedLocation(null);
|
||||
|
||||
// 检查是否已加载腾讯地图脚本
|
||||
if ((window as any).qq && (window as any).qq.maps) {
|
||||
console.log("腾讯地图脚本已加载,直接初始化");
|
||||
setTimeout(() => initMap(), 100);
|
||||
return;
|
||||
}
|
||||
|
||||
const script = document.createElement("script");
|
||||
script.src =
|
||||
"https://map.qq.com/api/gljs?v=1.exp&key=5ZSBZ-23ICU-XDKVU-4ZQ7Z-O35AJ-XUF6S";
|
||||
"https://webapi.amap.com/maps?v=1.4.15&key=79370028f5763e46742125ed2e900c76&plugin=AMap.PlaceSearch,AMap.AutoComplete,AMap.Geocoder,AMap.Geolocation";
|
||||
script.async = true;
|
||||
script.onload = () => {
|
||||
console.log("脚本加载成功:开始初始化地图");
|
||||
@@ -443,14 +648,16 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
placeSearchRef.current = null;
|
||||
geolocationRef.current = null;
|
||||
// Cleanup on close
|
||||
const scripts = document.querySelectorAll('script[src*="map.qq.com"]');
|
||||
const scripts = document.querySelectorAll(
|
||||
'script[src*="webapi.amap.com"]',
|
||||
);
|
||||
scripts.forEach(s => {
|
||||
if (document.body.contains(s)) {
|
||||
document.body.removeChild(s);
|
||||
}
|
||||
});
|
||||
if (mapRef.current) {
|
||||
// 腾讯地图没有destroy方法,设置为null即可
|
||||
mapRef.current.destroy();
|
||||
mapRef.current = null;
|
||||
}
|
||||
setMapLoading(false);
|
||||
@@ -462,57 +669,75 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
|
||||
// 手动获取当前位置
|
||||
const handleGetCurrentLocation = useCallback(() => {
|
||||
if (!navigator.geolocation) {
|
||||
message.warning("浏览器不支持定位服务");
|
||||
return;
|
||||
}
|
||||
|
||||
const qq = (window as any).qq;
|
||||
if (!qq || !qq.maps) {
|
||||
message.error("地图API未加载,请稍后再试");
|
||||
if (!geolocationRef.current) {
|
||||
message.warning("定位服务未初始化,请稍候再试");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("=== 手动触发获取当前位置 ===");
|
||||
message.loading({ content: "正在获取当前位置...", key: "location" });
|
||||
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
position => {
|
||||
geolocationRef.current.getCurrentPosition((status: string, result: any) => {
|
||||
message.destroy("location");
|
||||
console.log("=== 手动定位回调触发 ===");
|
||||
const lat = position.coords.latitude;
|
||||
const lng = position.coords.longitude;
|
||||
const latlng = new qq.maps.LatLng(lat, lng);
|
||||
console.log("定位状态:", status);
|
||||
console.log("定位结果:", result);
|
||||
|
||||
if (status === "complete" && result && result.position) {
|
||||
const { position, formattedAddress, addressComponent } = result;
|
||||
const lat = position.lat;
|
||||
const lng = position.lng;
|
||||
const lnglat = new AMap.LngLat(lng, lat);
|
||||
|
||||
console.log("定位成功,当前位置:", { lat, lng });
|
||||
|
||||
// 将地图中心设置为当前位置
|
||||
if (mapRef.current) {
|
||||
mapRef.current.setCenter(latlng);
|
||||
mapRef.current.setCenter(lnglat);
|
||||
mapRef.current.setZoom(16);
|
||||
}
|
||||
|
||||
// 添加当前位置标记
|
||||
addMarker(latlng);
|
||||
addMarker(lnglat);
|
||||
|
||||
// 设置选中位置信息
|
||||
let addressLabel = formattedAddress || `纬度: ${lat}, 经度: ${lng}`;
|
||||
let poiName = "当前位置";
|
||||
|
||||
// 尝试从地址组件中获取更详细的信息
|
||||
if (addressComponent) {
|
||||
const parts = [];
|
||||
if (addressComponent.province) parts.push(addressComponent.province);
|
||||
if (addressComponent.city) parts.push(addressComponent.city);
|
||||
if (addressComponent.district) parts.push(addressComponent.district);
|
||||
if (addressComponent.street) parts.push(addressComponent.street);
|
||||
if (addressComponent.streetNumber)
|
||||
parts.push(addressComponent.streetNumber);
|
||||
|
||||
if (parts.length > 0) {
|
||||
addressLabel = parts.join("");
|
||||
}
|
||||
|
||||
poiName =
|
||||
addressComponent.street || addressComponent.district || "当前位置";
|
||||
}
|
||||
|
||||
setSelectedLocation({
|
||||
lat: lat,
|
||||
lng: lng,
|
||||
label: addressLabel,
|
||||
poiname: poiName,
|
||||
});
|
||||
|
||||
// 获取地址信息
|
||||
getAddressForLocation(lat, lng);
|
||||
message.success("已获取当前位置");
|
||||
},
|
||||
error => {
|
||||
message.destroy("location");
|
||||
console.warn("定位失败:", error);
|
||||
} else {
|
||||
console.warn("定位失败:", result);
|
||||
message.error(
|
||||
"获取当前位置失败: " + (error.message || "定位服务不可用"),
|
||||
"获取当前位置失败: " + (result?.message || "定位服务不可用"),
|
||||
);
|
||||
},
|
||||
{
|
||||
enableHighAccuracy: true,
|
||||
timeout: 10000,
|
||||
maximumAge: 0,
|
||||
},
|
||||
);
|
||||
}, [addMarker, getAddressForLocation]);
|
||||
}
|
||||
});
|
||||
}, [addMarker]);
|
||||
|
||||
const handleSendLocation = () => {
|
||||
if (!selectedLocation || !selectedLocation.lat || !selectedLocation.lng) {
|
||||
@@ -571,7 +796,7 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
handleModalChange(true);
|
||||
// 确保容器在模态框打开后可以接收事件
|
||||
setTimeout(() => {
|
||||
const container = document.getElementById("tencent-map-container");
|
||||
const container = document.getElementById("amap-container");
|
||||
if (container) {
|
||||
container.style.pointerEvents = "auto";
|
||||
container.style.cursor = "crosshair";
|
||||
@@ -607,7 +832,7 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={handleGetCurrentLocation}
|
||||
disabled={!navigator.geolocation}
|
||||
disabled={!geolocationRef.current}
|
||||
>
|
||||
定位当前位置
|
||||
</Button>
|
||||
@@ -652,7 +877,7 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
id="tencent-map-container"
|
||||
id="amap-container"
|
||||
style={{
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
|
||||
Reference in New Issue
Block a user