refactor travel
This commit is contained in:
181
miniprogram/pages/main/travel-location-map/index.ts
Normal file
181
miniprogram/pages/main/travel-location-map/index.ts
Normal file
@ -0,0 +1,181 @@
|
||||
// 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: <TravelMapData>{
|
||||
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<string, TravelLocation[]>();
|
||||
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
|
||||
});
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user