From 2c9bda734e836d0d1819634b8a654ecec2f31dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B6=85=E7=BA=A7=E8=80=81=E7=99=BD=E5=85=94?= Date: Fri, 21 Nov 2025 15:51:50 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84SelectMap=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E9=9B=86=E6=88=90=E8=85=BE=E8=AE=AF=E5=9C=B0=E5=9B=BE?= =?UTF-8?q?API=EF=BC=8C=E6=9B=BF=E6=8D=A2AMap=E3=80=82=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E4=BA=86=E6=A0=87=E8=AE=B0=E5=A4=84=E7=90=86=E5=92=8C=E5=9C=B0?= =?UTF-8?q?=E5=9D=80=E6=A3=80=E7=B4=A2=E9=80=BB=E8=BE=91=EF=BC=8C=E4=BB=A5?= =?UTF-8?q?=E5=88=A9=E7=94=A8=E8=85=BE=E8=AE=AF=E7=9A=84=E5=9C=B0=E7=90=86?= =?UTF-8?q?=E7=BC=96=E7=A0=81=E5=92=8C=E4=BD=8D=E7=BD=AE=E5=BB=BA=E8=AE=AE?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E3=80=82=E5=A2=9E=E5=BC=BA=E7=9A=84=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E5=A4=84=E7=90=86=E5=92=8C=E5=8A=A0=E8=BD=BD=E7=8A=B6?= =?UTF-8?q?=E6=80=81=EF=BC=8C=E4=BB=A5=E6=94=B9=E5=96=84=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=BD=93=E9=AA=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MessageEnter/components/selectMap.tsx | 779 +++++++----------- Touchkebao/src/utils/dbAction/contact.ts | 22 +- 2 files changed, 288 insertions(+), 513 deletions(-) diff --git a/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageEnter/components/selectMap.tsx b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageEnter/components/selectMap.tsx index 7393c08c..7492be75 100644 --- a/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageEnter/components/selectMap.tsx +++ b/Touchkebao/src/pages/pc/ckbox/weChat/components/ChatWindow/components/MessageEnter/components/selectMap.tsx @@ -10,7 +10,7 @@ import { import { ContractData, weChatGroup, ChatRecord } from "@/pages/pc/ckbox/data"; import { useWebSocketStore } from "@/store/module/websocket/websocket"; -declare const AMap: any; +declare const qq: any; interface SelectMapProps { visible: boolean; @@ -34,7 +34,7 @@ const SelectMap: React.FC = ({ const pendingClickRef = useRef<{ lat: number; lng: number; - lnglat: any; + latlng: any; } | null>(null); // 保存待处理的点击坐标 const [options, setOptions] = useState([]); const [mapLoading, setMapLoading] = useState(true); @@ -56,282 +56,103 @@ const SelectMap: React.FC = ({ }, []); const addMarker = useCallback( - (lnglat: any) => { - console.log("addMarker 调用,坐标:", lnglat); + (latlng: any) => { + console.log("addMarker 调用,坐标:", latlng); + + const qq = (window as any).qq; + if (!qq || !qq.maps || !mapRef.current) { + console.error("地图API未加载或地图未初始化"); + return; + } // 先清除所有现有的标记点 clearAllMarkers(); - // 创建红色图标,保持默认倒水滴形状 - 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, + // 创建新的标记点(腾讯地图默认红色标记) + const newMarker = new qq.maps.Marker({ + position: latlng, map: mapRef.current, - icon: redIcon, }); // 将新标记点添加到数组中 markersRef.current.push(newMarker); - mapRef.current.setCenter(lnglat); + mapRef.current.setCenter(latlng); mapRef.current.setZoom(16); // 确保缩放到合适级别 console.log("新 marker 已添加并居中"); }, [clearAllMarkers], ); - // 通用的地址获取函数 - const getAddressForLocation = useCallback( - (lat: number, lng: number, lnglat: any) => { - console.log("=== getAddressForLocation 调用 ==="); - console.log("坐标:", { lat, lng }); - console.log( - "Geocoder ref 状态:", - geocoderRef.current ? "存在" : "不存在", - ); + // 通用的地址获取函数(使用腾讯地图逆地理编码API) + const getAddressForLocation = useCallback((lat: number, lng: number) => { + console.log("=== getAddressForLocation 调用 ==="); + console.log("坐标:", { lat, lng }); - // 检查 Geocoder 是否已初始化 - if (!geocoderRef.current) { - console.warn("Geocoder 未初始化,无法获取地址"); - return false; - } + // 使用腾讯地图逆地理编码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`; - // 使用更精确的坐标进行查询 - // 高德地图 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); + fetch(url) + .then(response => response.json()) + .then(result => { + console.log("=== 腾讯地图逆地理编码回调 ==="); + console.log("Result:", result); - 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 (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 || []; - 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 = "点击位置"; - // 构建详细地址信息 - let addressLabel = formattedAddress; - let poiName = "点击位置"; - - // 优先级1: 如果有POI信息,优先使用POI名称 - 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: 如果有建筑物信息 - 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) - parts.push(addressComponent.province); - if (addressComponent.city) parts.push(addressComponent.city); - if (addressComponent.district) - parts.push(addressComponent.district); - 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(""); - poiName = - addressComponent.street || - addressComponent.district || - "点击位置"; - addressLabel = fullAddress || formattedAddress; - } else { - addressLabel = - formattedAddress || `纬度: ${lat}, 经度: ${lng}`; - } - } - - setSelectedLocation({ - lat: lat, - lng: lng, - label: addressLabel, - poiname: poiName, - }); - - message.success("地址信息获取成功"); - } else { - 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, - lng: lng, - label: coordLabel, - poiname: "点击位置", - }); - message.warning("无法获取详细地址信息,但坐标已记录"); - } - }, - ); - } catch (placeSearchError) { - console.error( - "PlaceSearch.searchNearBy 调用异常:", - 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("无法获取详细地址信息,但坐标已记录"); - } - } - }, - ); - } 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("无法获取详细地址信息,但坐标已记录"); + // 优先级1: 如果有POI信息,优先使用POI名称 + if (pois.length > 0) { + const poi = pois[0]; + poiName = poi.title || poiName; + const poiAddress = poi.address || ""; + addressLabel = poiAddress + ? `${poiName} ${poiAddress}` + : `${poiName} ${formattedAddress}`; } + // 优先级2: 组合地址组件 + else { + 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.street_number) + parts.push(addressComponent.street_number); + + if (parts.length > 0) { + const fullAddress = parts.join(""); + poiName = + addressComponent.street || + addressComponent.district || + "点击位置"; + addressLabel = fullAddress || formattedAddress; + } else { + addressLabel = formattedAddress || `纬度: ${lat}, 经度: ${lng}`; + } + } + + setSelectedLocation({ + lat: lat, + lng: lng, + label: addressLabel, + poiname: poiName, + }); + + message.success("地址信息获取成功"); } else { + console.warn("逆地理编码返回异常:", result); const coordLabel = `纬度: ${lat}, 经度: ${lng}`; setSelectedLocation({ lat: lat, @@ -341,20 +162,48 @@ const SelectMap: React.FC = ({ }); message.warning("无法获取详细地址信息,但坐标已记录"); } - return false; - } - - return true; - }, - [], - ); + }) + .catch(error => { + console.error("=== 逆地理编码API调用异常 ===", error); + const coordLabel = `纬度: ${lat}, 经度: ${lng}`; + setSelectedLocation({ + lat: lat, + lng: lng, + label: coordLabel, + poiname: "点击位置", + }); + message.warning("无法获取详细地址信息,但坐标已记录"); + }); + }, []); 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("amap-container"); + const container = document.getElementById("tencent-map-container"); if (!container) { console.error("地图容器不存在"); setMapLoading(false); @@ -367,10 +216,13 @@ const SelectMap: React.FC = ({ container.style.position = "relative"; container.style.zIndex = "1"; - const map = new AMap.Map("amap-container", { + 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", { zoom: 16, - center: [118.113653, 24.470164], // 默认中心 - viewMode: "2D", // 明确指定视图模式 + center: center, }); mapRef.current = map; @@ -380,165 +232,91 @@ const SelectMap: React.FC = ({ setMapLoading(false); }, 10000); // 10秒超时 - // 立即加载插件,不等待地图 complete 事件 - console.log("=== 立即开始加载 AMap 插件(地图创建后) ==="); - AMap.plugin( - [ - "AMap.AutoComplete", - "AMap.PlaceSearch", - "AMap.Geocoder", - "AMap.Geolocation", - ], - error => { - if (error) { - console.error("=== AMap 插件加载失败 ===", error); - message.error("地图插件加载失败,部分功能可能不可用"); + // 标记服务已初始化 + 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未加载"); + return; + } + const latlng = new qq.maps.LatLng(lat, lng); + + console.log("定位成功,当前位置:", { lat, lng }); + + // 将地图中心设置为当前位置 + map.setCenter(latlng); + map.setZoom(16); + + // 添加当前位置标记 + addMarker(latlng); + + // 获取地址信息 + getAddressForLocation(lat, lng); + }, + error => { + console.warn("定位失败:", error); + message.warning( + "无法获取当前位置,请手动点击地图选择位置。原因: " + + (error.message || "定位服务不可用"), + ); + // 定位失败时,使用默认中心点 + console.log("使用默认中心点"); clearTimeout(loadingTimeout); setMapLoading(false); - return; - } - console.log("=== AMap 插件加载成功 ==="); + }, + { + enableHighAccuracy: true, + timeout: 10000, + maximumAge: 0, + }, + ); + } else { + console.warn("浏览器不支持定位"); + message.warning("浏览器不支持定位功能"); + clearTimeout(loadingTimeout); + setMapLoading(false); + } - // 立即创建 PlaceSearch 和 Geocoder 实例 - const placeSearch = new AMap.PlaceSearch({ - city: "全国", - map: map, - }); - placeSearchRef.current = placeSearch; - console.log("PlaceSearch 实例已创建"); + // 如果有待处理的点击坐标,立即处理它 + if (pendingClickRef.current) { + console.log("=== 检测到待处理的点击坐标,立即处理 ==="); + const { lat, lng } = pendingClickRef.current; + console.log("待处理坐标:", { lat, lng }); + setTimeout(() => { + getAddressForLocation(lat, lng); + console.log("✓ 待处理的坐标已成功获取地址"); + pendingClickRef.current = null; // 清除待处理坐标 + }, 100); + } - 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(lnglat); - map.setZoom(16); - - // 添加当前位置标记 - 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, - }); - - message.success("已获取当前位置"); - } else { - console.warn("定位失败:", result); - message.warning( - "无法获取当前位置,请手动点击地图选择位置。原因: " + - (result.message || "定位服务不可用"), - ); - // 定位失败时,使用默认中心点 - console.log("使用默认中心点"); - } - }); - - // 如果有待处理的点击坐标,立即处理它 - if (pendingClickRef.current) { - console.log("=== 检测到待处理的点击坐标,立即处理 ==="); - const { lat, lng, lnglat } = pendingClickRef.current; - console.log("待处理坐标:", { lat, lng }); - setTimeout(() => { - const success = getAddressForLocation(lat, lng, lnglat); - if (success) { - console.log("✓ 待处理的坐标已成功获取地址"); - pendingClickRef.current = null; // 清除待处理坐标 - } else { - console.warn("待处理的坐标获取地址失败"); - } - }, 100); - } - }, - ); - - // 立即绑定点击事件,插件可能已加载或正在加载 - console.log("立即绑定点击事件(插件可能已初始化)"); - map.on("click", (e: any) => { + // 绑定点击事件 + console.log("立即绑定点击事件"); + qq.maps.event.addListener(map, "click", (e: any) => { console.log("=== 地图点击事件触发 ==="); console.log("点击事件对象:", e); - console.log("点击位置对象:", e.lnglat); - console.log( - "Geocoder ref 状态:", - geocoderRef.current ? "已初始化" : "未初始化", - ); + console.log("点击位置对象:", e.latLng); - if (!e || !e.lnglat) { - console.error("点击事件无效,缺少 lnglat"); + if (!e || !e.latLng) { + console.error("点击事件无效,缺少 latLng"); return; } - const lnglat = e.lnglat; - const lat = lnglat.getLat(); - const lng = lnglat.getLng(); + const latlng = e.latLng; + const lat = latlng.getLat(); + const lng = latlng.getLng(); console.log(`点击坐标 - 纬度: ${lat}, 经度: ${lng}`); // 立即添加标记和居中 - addMarker(lnglat); + addMarker(latlng); // 设置基本 selectedLocation(至少有坐标) setSelectedLocation({ @@ -548,19 +326,12 @@ const SelectMap: React.FC = ({ poiname: "点击位置", }); - // 如果 Geocoder 已初始化,立即使用它 - if (geocoderRef.current) { - console.log("Geocoder 已初始化,立即获取地址"); - getAddressForLocation(lat, lng, lnglat); - } else { - console.log("Geocoder 未初始化,保存坐标待插件加载完成后处理"); - // 保存待处理的坐标 - pendingClickRef.current = { lat, lng, lnglat }; - } + // 立即获取地址 + getAddressForLocation(lat, lng); }); // 等待地图完全加载后关闭 loading - map.on("complete", () => { + qq.maps.event.addListener(map, "tilesloaded", () => { console.log("地图加载完成"); // 清除超时定时器 clearTimeout(loadingTimeout); @@ -576,47 +347,63 @@ const SelectMap: React.FC = ({ console.log("地图容器指针事件已启用"); } }); - - // 如果地图加载失败,也设置加载完成 - map.on("error", (error: any) => { - console.error("地图加载错误:", error); - clearTimeout(loadingTimeout); - setMapLoading(false); - message.error("地图加载失败"); - }); }, [addMarker, getAddressForLocation]); const handleSearch = value => { if (value) { - AMap.plugin("AMap.AutoComplete", () => { - const auto = new AMap.AutoComplete({ city: "全国" }); - auto.search(value, (status, result) => { - if (status === "complete") { + // 使用腾讯地图搜索建议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) { setOptions( - result.tips.map(tip => ({ - value: tip.name, - data: tip, + 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, + }, + }, })), ); + } else { + setOptions([]); } + }) + .catch(error => { + console.error("搜索建议API调用失败:", error); + setOptions([]); }); - }); } else { setOptions([]); } }; 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 lnglat = location; + const latlng = new qq.maps.LatLng(location.lat, location.lng); setSelectedLocation({ - lat: lnglat.lat, - lng: lnglat.lng, - label: `${name} ${address || district}`, + lat: location.lat, + lng: location.lng, + label: `${name} ${address || district || ""}`, poiname: name, }); - addMarker(lnglat); - mapRef.current.setCenter(lnglat); + addMarker(latlng); + if (mapRef.current) { + mapRef.current.setCenter(latlng); + } }; const handleModalChange = useCallback( @@ -625,9 +412,17 @@ const SelectMap: React.FC = ({ 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://webapi.amap.com/maps?v=1.4.15&key=79370028f5763e46742125ed2e900c76&plugin=AMap.PlaceSearch,AMap.AutoComplete,AMap.Geocoder,AMap.Geolocation"; + "https://map.qq.com/api/gljs?v=1.exp&key=5ZSBZ-23ICU-XDKVU-4ZQ7Z-O35AJ-XUF6S"; script.async = true; script.onload = () => { console.log("脚本加载成功:开始初始化地图"); @@ -648,16 +443,14 @@ const SelectMap: React.FC = ({ placeSearchRef.current = null; geolocationRef.current = null; // Cleanup on close - const scripts = document.querySelectorAll( - 'script[src*="webapi.amap.com"]', - ); + const scripts = document.querySelectorAll('script[src*="map.qq.com"]'); scripts.forEach(s => { if (document.body.contains(s)) { document.body.removeChild(s); } }); if (mapRef.current) { - mapRef.current.destroy(); + // 腾讯地图没有destroy方法,设置为null即可 mapRef.current = null; } setMapLoading(false); @@ -669,75 +462,57 @@ const SelectMap: React.FC = ({ // 手动获取当前位置 const handleGetCurrentLocation = useCallback(() => { - if (!geolocationRef.current) { - message.warning("定位服务未初始化,请稍候再试"); + if (!navigator.geolocation) { + message.warning("浏览器不支持定位服务"); + return; + } + + const qq = (window as any).qq; + if (!qq || !qq.maps) { + message.error("地图API未加载,请稍后再试"); return; } console.log("=== 手动触发获取当前位置 ==="); message.loading({ content: "正在获取当前位置...", key: "location" }); - geolocationRef.current.getCurrentPosition((status: string, result: any) => { - message.destroy("location"); - console.log("=== 手动定位回调触发 ==="); - 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); + navigator.geolocation.getCurrentPosition( + position => { + 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("定位成功,当前位置:", { lat, lng }); // 将地图中心设置为当前位置 if (mapRef.current) { - mapRef.current.setCenter(lnglat); + mapRef.current.setCenter(latlng); mapRef.current.setZoom(16); } // 添加当前位置标记 - 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, - }); + addMarker(latlng); + // 获取地址信息 + getAddressForLocation(lat, lng); message.success("已获取当前位置"); - } else { - console.warn("定位失败:", result); + }, + error => { + message.destroy("location"); + console.warn("定位失败:", error); message.error( - "获取当前位置失败: " + (result?.message || "定位服务不可用"), + "获取当前位置失败: " + (error.message || "定位服务不可用"), ); - } - }); - }, [addMarker]); + }, + { + enableHighAccuracy: true, + timeout: 10000, + maximumAge: 0, + }, + ); + }, [addMarker, getAddressForLocation]); const handleSendLocation = () => { if (!selectedLocation || !selectedLocation.lat || !selectedLocation.lng) { @@ -796,7 +571,7 @@ const SelectMap: React.FC = ({ handleModalChange(true); // 确保容器在模态框打开后可以接收事件 setTimeout(() => { - const container = document.getElementById("amap-container"); + const container = document.getElementById("tencent-map-container"); if (container) { container.style.pointerEvents = "auto"; container.style.cursor = "crosshair"; @@ -832,7 +607,7 @@ const SelectMap: React.FC = ({ @@ -877,7 +652,7 @@ const SelectMap: React.FC = ({ )}
{ try { - console.log("getContactCount 调用参数:", { - userId, - type, - customerId, - groupIds, - exclude, - }); + // console.log("getContactCount 调用参数:", { + // userId, + // type, + // customerId, + // groupIds, + // exclude, + // }); const conditions: any[] = [ { field: "userId", operator: "equals", value: userId }, @@ -394,14 +394,14 @@ export class ContactManager { } } - console.log("查询条件:", conditions); + // console.log("查询条件:", conditions); const contacts = await contactUnifiedService.findWhereMultiple(conditions); - console.log( - `查询结果数量: ${contacts.length}, type: ${type}, groupIds: ${groupIds}`, - ); + // console.log( + // `查询结果数量: ${contacts.length}, type: ${type}, groupIds: ${groupIds}`, + // ); return contacts.length; } catch (error) {