// pages/main/travel-location-map/index.ts import { TravelLocationApi } from "../../../api/TravelLocationApi"; import { TravelLocation, TravelLocationTypeLabel } from "../../../types/Travel"; interface MapMarker { id: number; latitude: number; longitude: number; width: number; height: number; customCallout: { anchorY: number; anchorX: number; display: string; }; /** 该位置的所有地点 */ locations: TravelLocation[]; } interface TravelMapData { travelId: number; centerLat: number; centerLng: number; scale: number; markers: MapMarker[]; locations: TravelLocation[]; includePoints: Array<{ latitude: number; longitude: number }>; isLoading: boolean; detailVisible: boolean; detailIds: number[]; } Page({ data: { travelId: 0, centerLat: 39.908823, centerLng: 116.397470, scale: 13, markers: [], locations: [], includePoints: [], isLoading: true, detailVisible: false, detailIds: [] }, onLoad(options: any) { const travelId = options.travelId ? parseInt(options.travelId) : 0; if (travelId) { this.setData({ travelId }); this.loadLocations(travelId); } else { wx.showToast({ title: "参数错误", icon: "error" }); setTimeout(() => { wx.navigateBack(); }, 1500); } }, /** 加载所有地点 */ async loadLocations(travelId: number) { this.setData({ isLoading: true }); try { const result = await TravelLocationApi.getList({ index: 0, size: 100, equalsExample: { travelId } }); // 过滤有位置信息的地点 const locations = result.list.filter(loc => loc.lat && loc.lng); if (locations.length === 0) { wx.showToast({ title: "暂无位置记录", icon: "none" }); this.setData({ isLoading: false }); return; } // 为每个地点添加类型标签 locations.forEach(location => { (location as any).typeLabel = location.type ? TravelLocationTypeLabel[location.type] : ""; }); // 按位置分组,处理重叠地点 const locationMap = new Map(); locations.forEach(location => { const key = `${location.lat},${location.lng}`; if (!locationMap.has(key)) { locationMap.set(key, []); } locationMap.get(key)!.push(location); }); // 生成地图标记(每个唯一位置一个标记) const markers: MapMarker[] = Array.from(locationMap.values()).map((locs, index) => ({ id: index, latitude: locs[0].lat!, longitude: locs[0].lng!, width: 24, height: 30, customCallout: { anchorY: -2, anchorX: 0, display: "ALWAYS" }, locations: locs })); // 计算中心点(所有标记的平均位置) const centerLat = locations.reduce((sum, l) => sum + l.lat!, 0) / locations.length; const centerLng = locations.reduce((sum, l) => sum + l.lng!, 0) / locations.length; // 缩放视野以包含所有标记点 const includePoints = locations.map((l) => ({ latitude: l.lat!, longitude: l.lng! })); this.setData({ locations, markers, centerLat, centerLng, includePoints, isLoading: false }); } catch (err: any) { wx.showToast({ title: "加载失败", icon: "error" }); this.setData({ isLoading: false }); } }, /** 标记点击事件 */ onMarkerTap(e: any) { const markerId = e.detail.markerId || e.markerId; this.loadLocationDetail(markerId); }, /** 气泡点击事件 */ onCalloutTap(e: any) { const markerId = e.detail.markerId || e.markerId; this.loadLocationDetail(markerId); }, /** 加载位置详情 */ loadLocationDetail(markerId: number) { const marker = this.data.markers[markerId]; if (!marker || !marker.locations || marker.locations.length === 0) { return; } // 获取该标记点的所有地点 ID const locationIds = marker.locations.map(loc => loc.id!).filter(id => id); if (locationIds.length === 0) { return; } this.setData({ detailVisible: true, detailIds: locationIds }); }, /** 关闭详情 */ closeDetail() { this.setData({ detailVisible: false }); } });