326 lines
10 KiB
TypeScript
326 lines
10 KiB
TypeScript
// 货运人员模块 - 处理货运人员管理、位置跟踪、交互
|
||
import deliveryPersonService from '../../../services/deliveryPersonService';
|
||
|
||
import { showToast } from '../../../utils/helpers';
|
||
import { DataModule } from './dataModule';
|
||
|
||
export class DeliveryPersonModule {
|
||
private pageContext: any;
|
||
private dataModule: DataModule;
|
||
|
||
constructor(pageContext: any, dataModule: DataModule) {
|
||
this.pageContext = pageContext;
|
||
this.dataModule = dataModule;
|
||
}
|
||
|
||
/**
|
||
* 加载货运人员数据
|
||
*/
|
||
async loadDeliveryPersons(): Promise<void> {
|
||
try {
|
||
const deliveryPersons = await deliveryPersonService.getDeliveryPersons();
|
||
|
||
// 更新地图标记点
|
||
this.updateDeliveryPersonMarkers(deliveryPersons);
|
||
|
||
console.log('货运人员数据加载完成,数量:', deliveryPersons.length);
|
||
} catch (error) {
|
||
console.error('加载货运人员数据失败:', error);
|
||
showToast('加载货运人员数据失败');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 更新货运人员位置
|
||
*/
|
||
async updateDeliveryPersonLocation(personId: number, location: { longitude: number, latitude: number }): Promise<void> {
|
||
try {
|
||
await deliveryPersonService.updateDeliveryPersonLocation(personId, location);
|
||
|
||
console.log(`货运人员 ${personId} 位置更新:`, location);
|
||
|
||
// 重新加载货运人员数据
|
||
await this.loadDeliveryPersons();
|
||
|
||
} catch (error) {
|
||
console.error('更新货运人员位置失败:', error);
|
||
showToast('更新位置失败');
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 开始实时位置跟踪
|
||
*/
|
||
async startRealTimeTracking(): Promise<void> {
|
||
try {
|
||
// 获取当前用户信息
|
||
const userInfo = this.dataModule.getData().userInfo;
|
||
if (!userInfo || !userInfo.id) {
|
||
throw new Error('用户信息获取失败');
|
||
}
|
||
|
||
// 使用新的WebSocket接口订阅位置更新
|
||
await deliveryPersonService.subscribeToRealTimeLocations(userInfo.id);
|
||
|
||
// 设置位置更新回调
|
||
deliveryPersonService.subscribeToRealTimeLocations(this.handleRealTimeLocationUpdate.bind(this));
|
||
|
||
showToast('开始实时跟踪');
|
||
console.log('开始实时跟踪货运人员位置');
|
||
} catch (error) {
|
||
console.error('开始实时跟踪失败:', error);
|
||
showToast('开始实时跟踪失败');
|
||
}
|
||
}
|
||
|
||
handleRealTimeLocationUpdate(location: any): void {
|
||
console.log('收到实时位置更新:', location);
|
||
// 这里可以添加更新地图标记点的逻辑
|
||
// 根据位置更新信息更新对应的货运人员标记点
|
||
if (location && location.deliveryPersonId) {
|
||
this.updateSingleDeliveryPersonMarker(location);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 更新单个货运人员标记点
|
||
*/
|
||
private updateSingleDeliveryPersonMarker(location: any): void {
|
||
const { markers } = this.pageContext.data;
|
||
|
||
// 查找并更新对应的货运人员标记点
|
||
const updatedMarkers = markers.map((marker: any) => {
|
||
if (marker.type === 'delivery_person' && marker.data && marker.data.id === location.deliveryPersonId) {
|
||
// 更新标记点位置
|
||
return {
|
||
...marker,
|
||
longitude: location.longitude,
|
||
latitude: location.latitude,
|
||
data: {
|
||
...marker.data,
|
||
currentLocation: {
|
||
longitude: location.longitude,
|
||
latitude: location.latitude
|
||
}
|
||
}
|
||
};
|
||
}
|
||
return marker;
|
||
});
|
||
|
||
// 更新数据模块中的标记点
|
||
this.dataModule.updateMarkers(updatedMarkers);
|
||
}
|
||
|
||
/**
|
||
* 停止实时跟踪货运人员位置
|
||
*/
|
||
async stopRealTimeTracking(): Promise<void> {
|
||
try {
|
||
// 获取当前用户信息
|
||
const userInfo = this.dataModule.getData().userInfo;
|
||
if (!userInfo || !userInfo.id) {
|
||
throw new Error('用户信息获取失败');
|
||
}
|
||
|
||
// 使用新的WebSocket接口取消订阅
|
||
await deliveryPersonService.unsubscribeFromRealTimeLocations();
|
||
|
||
showToast('已停止实时跟踪');
|
||
console.log('停止实时跟踪货运人员位置');
|
||
} catch (error) {
|
||
console.error('停止实时跟踪失败:', error);
|
||
showToast('停止实时跟踪失败');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 更新货运人员标记点
|
||
*/
|
||
private updateDeliveryPersonMarkers(deliveryPersons: any[]): void {
|
||
console.log(`[DELIVERY PERSON MODULE] 开始更新货运人员标记点,货运人员总数: ${deliveryPersons.length}`);
|
||
|
||
const { markers } = this.pageContext.data;
|
||
|
||
// 移除现有的货运人员标记点
|
||
const filteredMarkers = markers.filter((marker: any) => marker.type !== 'delivery_person');
|
||
console.log(`[DELIVERY PERSON MODULE] 移除现有货运人员标记点后,剩余标记点数量: ${filteredMarkers.length}`);
|
||
|
||
// 添加新的货运人员标记点
|
||
const deliveryPersonMarkers = deliveryPersons.map((person, index) => {
|
||
// 验证货运人员坐标是否有效
|
||
// 注意:坐标信息嵌套在currentLocation对象中
|
||
let validLongitude = person.currentLocation?.longitude;
|
||
let validLatitude = person.currentLocation?.latitude;
|
||
|
||
if (isNaN(validLongitude) || isNaN(validLatitude)) {
|
||
console.error(`[DELIVERY PERSON MODULE] 货运人员${index} (ID: ${person.id}) 坐标无效: (${validLongitude}, ${validLatitude}),使用默认坐标`);
|
||
validLongitude = 102.833722; // 默认经度
|
||
validLatitude = 24.880095; // 默认纬度
|
||
} else {
|
||
console.log(`[DELIVERY PERSON MODULE] 货运人员${index} (ID: ${person.id}) 坐标有效: (${validLongitude}, ${validLatitude})`);
|
||
}
|
||
|
||
const iconPath = this.getDeliveryPersonIcon(person.status);
|
||
|
||
return {
|
||
id: 2000 + index, // 货运人员标记点ID从2000开始
|
||
longitude: validLongitude,
|
||
latitude: validLatitude,
|
||
iconPath: iconPath,
|
||
width: 26,
|
||
height: 26,
|
||
zIndex: 20,
|
||
type: 'delivery_person',
|
||
data: person
|
||
};
|
||
});
|
||
|
||
console.log(`[DELIVERY PERSON MODULE] 生成新货运人员标记点数量: ${deliveryPersonMarkers.length}`);
|
||
|
||
// 更新数据模块中的标记点
|
||
const allMarkers = [...filteredMarkers, ...deliveryPersonMarkers];
|
||
console.log(`[DELIVERY PERSON MODULE] 准备更新所有标记点,总数: ${allMarkers.length}`);
|
||
this.dataModule.updateMarkers(allMarkers);
|
||
}
|
||
|
||
/**
|
||
* 获取货运人员状态对应的图标
|
||
*/
|
||
private getDeliveryPersonIcon(status: string): string {
|
||
console.log(`获取货运人员图标,状态: ${status}`);
|
||
|
||
// 根据报错信息,直接使用已知存在的备用图片路径
|
||
// 实际项目中,应确保相关图片资源正确放置在指定路径
|
||
const fallbackIconPath = '/images/trucks.png';
|
||
|
||
// 根据不同状态使用不同的图片路径
|
||
let iconPath = '';
|
||
|
||
switch (status) {
|
||
case 'idle':
|
||
// 为避免图片加载失败,暂时使用备用图片
|
||
iconPath = fallbackIconPath;
|
||
console.log('使用备用图标(idle状态)');
|
||
break;
|
||
case 'busy':
|
||
// 为避免图片加载失败,暂时使用备用图片
|
||
iconPath = fallbackIconPath;
|
||
console.log('使用备用图标(busy状态)');
|
||
break;
|
||
case 'offline':
|
||
// 为避免图片加载失败,暂时使用备用图片
|
||
iconPath = fallbackIconPath;
|
||
console.log('使用备用图标(offline状态)');
|
||
break;
|
||
default:
|
||
iconPath = fallbackIconPath;
|
||
console.log('使用备用图标(默认状态)');
|
||
break;
|
||
}
|
||
|
||
console.log(`最终使用图标路径: ${iconPath}`);
|
||
|
||
return iconPath;
|
||
}
|
||
|
||
/**
|
||
* 显示货运人员详情面板
|
||
*/
|
||
showDeliveryPersonPanel(person: any, position: { x: number, y: number }): void {
|
||
// 关闭其他面板
|
||
this.pageContext.hideAllPanels();
|
||
|
||
this.dataModule.setCurrentDeliveryPerson(person);
|
||
this.dataModule.setPanelPosition(position);
|
||
this.dataModule.toggleDeliveryPersonModal(true, 'bottom');
|
||
}
|
||
|
||
/**
|
||
* 隐藏货运人员详情面板
|
||
*/
|
||
hideDeliveryPersonPanel(): void {
|
||
this.dataModule.toggleDeliveryPersonModal(false);
|
||
this.dataModule.setCurrentDeliveryPerson(null);
|
||
}
|
||
|
||
/**
|
||
* 展开货运人员详情面板
|
||
*/
|
||
expandDeliveryPersonPanel(): void {
|
||
this.dataModule.toggleDeliveryPersonModal(true, 'full');
|
||
}
|
||
|
||
/**
|
||
* 收起货运人员详情面板
|
||
*/
|
||
collapseDeliveryPersonPanel(): void {
|
||
this.dataModule.toggleDeliveryPersonModal(true, 'bottom');
|
||
}
|
||
|
||
/**
|
||
* 处理货运人员标记点点击
|
||
*/
|
||
onDeliveryPersonMarkerClick(person: any, position: { x: number, y: number }): void {
|
||
console.log('货运人员被点击:', person);
|
||
|
||
// 显示货运人员详情面板
|
||
this.showDeliveryPersonPanel(person, position);
|
||
}
|
||
|
||
/**
|
||
* 获取货运人员状态文本
|
||
*/
|
||
getDeliveryPersonStatusText(status: string): string {
|
||
const statusMap: Record<string, string> = {
|
||
'idle': '空闲',
|
||
'busy': '忙碌',
|
||
'offline': '离线'
|
||
};
|
||
return statusMap[status] || status;
|
||
}
|
||
|
||
/**
|
||
* 获取货运人员状态颜色
|
||
*/
|
||
getDeliveryPersonStatusColor(status: string): string {
|
||
switch (status) {
|
||
case 'idle':
|
||
return '#52c41a'; // 绿色
|
||
case 'busy':
|
||
return '#faad14'; // 橙色
|
||
case 'offline':
|
||
return '#d9d9d9'; // 灰色
|
||
default:
|
||
return '#d9d9d9'; // 灰色
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取货运人员当前订单信息
|
||
*/
|
||
getCurrentOrderInfo(person: any): string {
|
||
if (!person.currentOrder) {
|
||
return '暂无订单';
|
||
}
|
||
|
||
const order = person.currentOrder;
|
||
return `订单 #${order.id} - ${this.getOrderStatusText(order.status)}`;
|
||
}
|
||
|
||
/**
|
||
* 获取订单状态文本
|
||
*/
|
||
private getOrderStatusText(status: string): string {
|
||
const statusMap: Record<string, string> = {
|
||
'pending': '未分配',
|
||
'assigned': '已分配',
|
||
'in_transit': '配送中',
|
||
'delivered': '已完成',
|
||
'cancelled': '已取消'
|
||
};
|
||
return statusMap[status] || status;
|
||
}
|
||
} |