修改位置交互,修改代码逻辑

This commit is contained in:
2025-10-18 22:21:04 +08:00
parent c446df73b5
commit 39fa0b2d04
36 changed files with 2743 additions and 1995 deletions

View File

@@ -149,25 +149,68 @@ page {
/* 控制按钮样式统一 */
.control-btn.signin-btn,
.control-btn.register-btn {
width: 100rpx;
height: 100rpx;
.control-btn.register-btn,
.control-btn.sign-out-btn,
.control-btn.auth-btn,
.control-btn.location-btn,
.control-btn.reset-btn,
.control-btn.staff-management-btn {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.15);
box-shadow: 0 6rpx 30rpx rgba(0, 0, 0, 0.2);
font-size: 24rpx;
padding: 0;
margin: 0;
border: none;
color: #333333;
text-align: center;
line-height: 1;
background: rgba(255, 255, 255, 0.9);
border: 1rpx solid rgba(0, 0, 0, 0.1);
}
/* 按钮图标样式 */
.btn-icon {
font-size: 40rpx;
margin-bottom: 8rpx;
display: block;
line-height: 1;
}
/* 按钮文字样式 */
.btn-text {
font-size: 22rpx;
font-weight: 500;
display: block;
line-height: 1.2;
}
.control-btn.signin-btn:active,
.control-btn.register-btn:active {
.control-btn.register-btn:active,
.control-btn.sign-out-btn:active {
transform: scale(0.95);
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
/* 所有按钮点击状态 */
.control-btn.signin-btn:active,
.control-btn.register-btn:active,
.control-btn.auth-btn:active,
.control-btn.sign-out-btn:active,
.control-btn.location-btn:active,
.control-btn.reset-btn:active,
.control-btn.staff-management-btn:active {
background: rgba(240, 240, 240, 0.9);
transform: scale(0.95);
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
border: 1rpx solid rgba(0, 0, 0, 0.2);
}
.btn-signin {
background-color: #1aad19;
color: white;

View File

@@ -1,61 +1,64 @@
// index.ts
// 引入服务和工具函数
import { UserInfo, Marker } from '../../types';
import { showToast } from '../../utils/helpers';
import userService from '../../services/userService';
import locationTrackingService from '../../services/locationTrackingService';
// 引入模块
// 引入主页面模块
import { MainPageModule } from './modules/mainPageModule';
// 主页面组件
Component({
// 主页面组件接口定义
interface IndexPageComponent {
data: {
// 地图中心点坐标
longitude: 102.833722,
latitude: 24.880095,
scale: 13, // 地图缩放级别
markers: [] as Marker[], // 地图标记点数组
userInfo: null as UserInfo | null, // 用户信息
// 用户认证状态(分离外部登录状态和用户二级状态)
authStatus: {
hasWxCode: false, // 是否已获取微信code外部登录状态
userStatus: 'unknown' as 'unknown' | 'registered' | 'unregistered' | 'signed_in' | 'signed_out', // 用户二级状态
},
showUserPanel: false, // 是否显示用户信息面板
showOrderPanel: false, // 是否显示订单详情面板
currentOrder: null as any, // 当前选中的订单
currentDeliveryPerson: null as any, // 当前选中的货运人员
currentWarehouse: null as any, // 当前选中的仓库
currentPanelPosition: { x: 0, y: 0 }, // 当前信息面板位置
polyline: null as any, // 路线规划结果
pendingOrders: [] as any[] ,// 待分配订单
currentRoute: null as any, // 当前路线信息
showRoute: false, // 是否显示路线
routeDistance: 0, // 路线距离
routeDuration: 0, // 路线预计时间
// 底部弹窗相关状态
showWarehouseModal: false, // 仓库底部弹窗
showDeliveryPersonModal: false, // 货运人员底部弹窗
// 底部弹窗状态bottom或full
warehouseModalState: 'bottom',
deliveryPersonModalState: 'bottom',
// 操作按钮显示状态(基于用户状态动态计算)
mainPageModule: MainPageModule | null;
// 核心UI状态
showUserPanel: boolean;
showOrderPanel: boolean;
showDeliveryPersonModal: boolean;
showWarehouseModal: boolean;
};
}
showSignOutButton: false // 是否显示签退按钮
// 主页面组件
Component<IndexPageComponent>({
data: {
mainPageModule: null as MainPageModule | null,
// 核心UI状态
showUserPanel: false,
showOrderPanel: false,
showDeliveryPersonModal: false,
showWarehouseModal: false
},
lifetimes: {
async attached() {
// 组件挂载时初始化
await this.initPage();
attached() {
console.log('index page attached');
this.initPage();
},
detached() {
console.log('index page detached');
// 清理资源
if (this.data.mainPageModule) {
this.data.mainPageModule.cleanup();
}
},
detached() {
// 组件卸载时清理
(this as any).mainPageModule = null;
show() {
console.log('index page show');
// 页面显示时调用主页面模块的onShow方法
if (this.data.mainPageModule) {
this.data.mainPageModule.onShow();
}
},
hide() {
console.log('index page hide');
// 页面隐藏时调用主页面模块的onHide方法
if (this.data.mainPageModule) {
this.data.mainPageModule.onHide();
}
}
},
@@ -82,11 +85,14 @@ Component({
const app = getApp<any>();
// 初始化主页面模块
(this as any).mainPageModule = new MainPageModule(this);
const loginModule = (this as any).mainPageModule.getLoginModule();
this.setData({
mainPageModule: new MainPageModule(this)
});
// 设置globalData中的loginModule引用用于废弃方法的重定向
app.globalData.loginModule = loginModule;
if (this.data.mainPageModule) {
app.globalData.loginModule = this.data.mainPageModule.getLoginModule();
}
// 异步检查登录状态
await this.checkAndUpdateLoginStatus();
@@ -95,9 +101,14 @@ Component({
// 异步检查并更新登录状态
async checkAndUpdateLoginStatus() {
const app = getApp<any>();
const loginModule = (this as any).mainPageModule.getLoginModule();
try {
// 获取登录模块
if (!this.data.mainPageModule) {
console.error('mainPageModule未初始化');
return;
}
const loginModule = this.data.mainPageModule.getLoginModule();
// 显示加载状态
wx.showLoading({
title: '检查登录状态...',
@@ -108,21 +119,8 @@ Component({
const isLoggedIn = await this.asyncCheckLoginStatus(loginModule);
if (isLoggedIn) {
// 已登录状态
const userStatus = await loginModule.determineUserStatus(app.globalData.userInfo);
this.setData({
userInfo: app.globalData.userInfo,
'authStatus.hasWxCode': true,
'authStatus.userStatus': userStatus,
// 初始化按钮显示状态
showSignInButton: loginModule.shouldShowSignInButton(),
showRegisterButton: loginModule.shouldShowRegisterButton(),
showAuthButton: false
});
// === 全局登录流程完成,登录成功 ===
// 统一在此处执行一次完整的页面刷新
this.refreshPageAfterLogin();
// 已登录状态 - 按钮状态会在refreshPageAfterLogin中统一更新
console.log('✅ 登录检查成功,等待统一页面刷新');
} else {
// 未登录状态
this.setData({
@@ -173,6 +171,9 @@ Component({
console.log('✅ 使用本地登录状态,用户状态已更新:', userStatus);
// 登录成功后统一刷新页面
this.refreshPageAfterLogin();
return true;
}
@@ -213,19 +214,24 @@ Component({
// 更新按钮显示状态
updateButtonDisplayStatus() {
const loginModule = (this as any).mainPageModule.getLoginModule();
if (!this.data.mainPageModule) {
console.error('mainPageModule未初始化');
return;
}
const loginModule = this.data.mainPageModule.getLoginModule();
const showSignInButton = loginModule.shouldShowSignInButton();
const showRegisterButton = loginModule.shouldShowRegisterButton();
// 签退按钮显示逻辑:已签到用户显示签退按钮
const showSignOutButton = this.data.authStatus.userStatus === 'signed_in';
const showSignOutButton = this.data.authStatus && this.data.authStatus.userStatus === 'signed_in';
console.log('🔄 更新按钮显示状态:');
console.log(' - showSignInButton:', showSignInButton);
console.log(' - showRegisterButton:', showRegisterButton);
console.log(' - showSignOutButton:', showSignOutButton);
console.log(' - 当前用户状态:', this.data.authStatus.userStatus);
console.log(' - 当前hasWxCode:', this.data.authStatus.hasWxCode);
console.log(' - 当前用户状态:', this.data.authStatus ? this.data.authStatus.userStatus : 'undefined');
console.log(' - 当前hasWxCode:', this.data.authStatus ? this.data.authStatus.hasWxCode : 'undefined');
this.setData({
showSignInButton,
@@ -238,7 +244,12 @@ Component({
// 登录成功后统一刷新页面
async refreshPageAfterLogin() {
const loginModule = (this as any).mainPageModule.getLoginModule();
if (!this.data.mainPageModule) {
console.error('mainPageModule未初始化');
return;
}
const loginModule = this.data.mainPageModule.getLoginModule();
const app = getApp<any>();
console.log('🔄 === 全局登录流程完成,执行统一页面刷新 ===');
@@ -250,13 +261,14 @@ Component({
this.updateButtonDisplayStatus();
// 3. 初始化主页面模块
await (this as any).mainPageModule.onLoad();
await this.data.mainPageModule.onLoad();
// 4. 登录成功后主动加载业务数据(仓库、订单等)
// 4. 登录成功后只加载公开数据(仓库等),不加载业务数据
// 业务数据(员工位置等)只有在用户签到后才应该加载
if (app.globalData.isLoggedIn) {
console.log('🔍 登录成功,开始加载业务数据...');
await (this as any).mainPageModule.refreshAllData();
console.log('✅ 业务数据加载完成');
console.log('🔍 登录成功,开始加载公开数据...');
await this.data.mainPageModule.loadPublicData();
console.log('✅ 公开数据加载完成');
}
console.log('✅ 统一页面刷新完成');
@@ -278,7 +290,12 @@ Component({
// 处理签到 - 已迁移到LoginModule
async handleSignIn() {
const loginModule = (this as any).mainPageModule.getLoginModule();
if (!this.data.mainPageModule) {
console.error('mainPageModule未初始化');
return;
}
const loginModule = this.data.mainPageModule.getLoginModule();
const success = await loginModule.handleSignIn();
if (success) {
@@ -286,18 +303,22 @@ Component({
this.updateButtonDisplayStatus();
// 刷新页面数据
await (this as any).mainPageModule.refreshAllData();
await this.data.mainPageModule.refreshAllData();
}
},
// 处理授权登录 - 已迁移到LoginModule
async handleAuthLogin() {
const loginModule = (this as any).mainPageModule.getLoginModule();
if (!this.data.mainPageModule) {
console.error('mainPageModule未初始化');
return;
}
const loginModule = this.data.mainPageModule.getLoginModule();
const success = await loginModule.handleAuthLogin();
if (success) {
const app = getApp<any>();
const loginModule = (this as any).mainPageModule.getLoginModule();
const userStatus = loginModule.determineUserStatus(app.globalData.userInfo);
this.setData({
userInfo: app.globalData.userInfo,
@@ -323,7 +344,11 @@ Component({
});
// 调用loginModule的logout方法
const loginModule = (this as any).mainPageModule.getLoginModule();
if (!this.data.mainPageModule) {
console.error('mainPageModule未初始化');
return;
}
const loginModule = this.data.mainPageModule.getLoginModule();
await loginModule.logout();
// 更新页面状态
@@ -364,10 +389,18 @@ Component({
console.warn('调试信息 - 停止位置追踪失败:', trackingError);
}
// 清除登录信息,防止自动重新登录
console.log('调试信息 - 开始清除登录信息');
const app = getApp<any>();
app.doGlobalLogout();
// 停止位置模块的实时跟踪
try {
if (this.data.mainPageModule) {
const locationModule = this.data.mainPageModule.getLocationModule();
if (locationModule) {
await locationModule.stopRealTimeTracking();
console.log('调试信息 - 位置模块实时跟踪已停止');
}
}
} catch (trackingError) {
console.warn('调试信息 - 停止位置模块实时跟踪失败:', trackingError);
}
// 保存签退状态到本地存储,防止自动重新登录
console.log('调试信息 - 保存签退状态到本地存储');
@@ -377,13 +410,25 @@ Component({
const savedStatus = wx.getStorageSync('userStatus');
console.log('调试信息 - 验证保存的签退状态:', savedStatus);
// 更新用户状态为已签退
// 更新用户状态为已签退不调用doGlobalLogout保持登录状态
this.setData({
'authStatus.userStatus': 'signed_out',
showSignOutButton: false,
showSignInButton: true
});
// 清除所有员工图标
if (this.data.mainPageModule) {
const employeeModule = this.data.mainPageModule.getEmployeeModule();
if (employeeModule) {
// 清除员工标记点
const { markers } = this.data;
const filteredMarkers = markers.filter((marker: any) => marker.type !== 'employee');
this.setData({ markers: filteredMarkers });
console.log('调试信息 - 已清除所有员工图标');
}
}
wx.hideLoading();
showToast('签退成功');
console.log('调试信息 - 用户签退完成');
@@ -401,9 +446,25 @@ Component({
});
},
// 跳转到管理员页面
goToAdminPage() {
wx.navigateTo({
url: '/pages/admin/admin'
});
},
// 跳转到员工管理页面
goToEmployeeManagement() {
wx.navigateTo({
url: '/pages/employee/employee'
});
},
// 阻止事件冒泡
stopPropagation(e: any) {
e.stopPropagation();
if (e && typeof e.stopPropagation === 'function') {
e.stopPropagation();
}
},
@@ -422,8 +483,8 @@ Component({
// 用户登出
userLogout() {
if ((this as any).mainPageModule) {
const loginModule = (this as any).mainPageModule.getLoginModule();
if (this.data.mainPageModule) {
const loginModule = this.data.mainPageModule.getLoginModule();
loginModule.logout();
// 更新页面状态
@@ -449,91 +510,91 @@ Component({
// 隐藏所有面板
hideAllPanels() {
if ((this as any).mainPageModule) {
(this as any).mainPageModule.hideAllPanels();
if (this.data.mainPageModule) {
this.data.mainPageModule.hideAllPanels();
}
},
// 重置标记点状态
resetMarkers() {
if ((this as any).mainPageModule) {
(this as any).mainPageModule.resetMarkers();
if (this.data.mainPageModule) {
this.data.mainPageModule.resetMarkers();
}
},
// 地图点击事件
onMapTap(e: any) {
if ((this as any).mainPageModule) {
(this as any).mainPageModule.onMapTap(e);
if (this.data.mainPageModule) {
this.data.mainPageModule.onMapTap(e);
}
},
// 标记点点击事件
onMarkerTap(e: any) {
if ((this as any).mainPageModule) {
(this as any).mainPageModule.onMarkerTap(e);
if (this.data.mainPageModule) {
this.data.mainPageModule.onMarkerTap(e);
}
},
// 分配订单
async assignOrder(orderId: number, deliveryPersonId: number) {
if ((this as any).mainPageModule) {
const orderModule = (this as any).mainPageModule.getOrderModule();
if (this.data.mainPageModule) {
const orderModule = this.data.mainPageModule.getOrderModule();
await orderModule.assignOrder(orderId, deliveryPersonId);
}
},
// 更新订单状态
async updateOrderStatus(orderId: number, status: 'pending' | 'assigned' | 'in_transit' | 'delivered') {
if ((this as any).mainPageModule) {
const orderModule = (this as any).mainPageModule.getOrderModule();
if (this.data.mainPageModule) {
const orderModule = this.data.mainPageModule.getOrderModule();
await orderModule.updateOrderStatus(orderId, status);
}
},
// 展开仓库面板
expandWarehousePanel() {
if ((this as any).mainPageModule) {
const warehouseModule = (this as any).mainPageModule.getWarehouseModule();
if (this.data.mainPageModule) {
const warehouseModule = this.data.mainPageModule.getWarehouseModule();
warehouseModule.expandWarehousePanel();
}
},
// 收起仓库面板
collapseWarehousePanel() {
if ((this as any).mainPageModule) {
const warehouseModule = (this as any).mainPageModule.getWarehouseModule();
if (this.data.mainPageModule) {
const warehouseModule = this.data.mainPageModule.getWarehouseModule();
warehouseModule.collapseWarehousePanel();
}
},
// 展开货运人员面板
// 展开员面板
expandDeliveryPersonPanel() {
if ((this as any).mainPageModule) {
const deliveryPersonModule = (this as any).mainPageModule.getDeliveryPersonModule();
deliveryPersonModule.expandDeliveryPersonPanel();
if (this.data.mainPageModule) {
const employeeModule = this.data.mainPageModule.getEmployeeModule();
employeeModule.expandDeliveryPersonPanel();
}
},
// 收起货运人员面板
// 收起员面板
collapseDeliveryPersonPanel() {
if ((this as any).mainPageModule) {
const deliveryPersonModule = (this as any).mainPageModule.getDeliveryPersonModule();
deliveryPersonModule.collapseDeliveryPersonPanel();
if (this.data.mainPageModule) {
const employeeModule = this.data.mainPageModule.getEmployeeModule();
employeeModule.collapseDeliveryPersonPanel();
}
},
// 刷新所有数据
async refreshAllData() {
if ((this as any).mainPageModule) {
await (this as any).mainPageModule.refreshAllData();
if (this.data.mainPageModule) {
await this.data.mainPageModule.refreshAllData();
}
},
// 开始定位(处理地图控制按钮点击)
async startLocation() {
if ((this as any).mainPageModule) {
const mapModule = (this as any).mainPageModule.getMapModule();
if (this.data.mainPageModule) {
const mapModule = this.data.mainPageModule.getMapModule();
await mapModule.startLocation();
}
},

View File

@@ -26,7 +26,8 @@
type="primary"
size="mini"
>
签到
<text class="btn-icon">✅</text>
<text class="btn-text">签到</text>
</button>
<!-- 注册按钮 - 游客用户 -->
@@ -37,7 +38,8 @@
type="default"
size="mini"
>
注册
<text class="btn-icon">📝</text>
<text class="btn-text">注册</text>
</button>
<!-- 授权登录按钮 - 未授权用户 -->
@@ -48,7 +50,8 @@
type="warn"
size="mini"
>
登录
<text class="btn-icon">🔑</text>
<text class="btn-text">登录</text>
</button>
<!-- 签退按钮 - 已签到用户 -->
@@ -59,14 +62,16 @@
type="warn"
size="mini"
>
签退
<text class="btn-icon">🚪</text>
<text class="btn-text">签退</text>
</button>
</view>
<!-- 地图控制按钮 -->
<view class="map-controls">
<view class="control-btn location-btn" bindtap="startLocation">
<image src="/images/ma.png" mode="aspectFit"></image>
<text class="btn-icon">📍</text>
<text class="btn-text">定位</text>
</view>
</view>
@@ -74,11 +79,17 @@
<view wx:if="{{authStatus.hasWxCode}}"
class="control-btn reset-btn"
bindtap="showUserPanel">
<image
src="/images/trucks.png"
mode="aspectFit"
></image>
<view wx:if="{{userInfo.role === 'ADMIN'}}" class="admin-badge">管理</view>
<text class="btn-icon">👤</text>
<text class="btn-text">我的</text>
<view wx:if="{{userInfo.role === 'ADMIN'}}" class="admin-badge"/>
</view>
<!-- 员工管理按钮(仅管理员可见) -->
<view wx:if="{{authStatus.hasWxCode && userInfo.role === 'ADMIN'}}"
class="control-btn staff-management-btn"
bindtap="goToEmployeeManagement">
<text class="btn-icon">👥</text>
<text class="btn-text">员工</text>
</view>
</view>
@@ -92,7 +103,7 @@
<view class="user-panel-content" bindtap="stopPropagation">
<view class="user-avatar">
<image
src="/images/user-avatar.png"
src="/images/trucks.png"
mode="aspectFill"
class="avatar-image"
></image>
@@ -103,6 +114,7 @@
<text class="user-id">ID: {{userInfo.id || '未获取'}}</text>
<text class="user-phone">电话:{{userInfo.phone || '未设置'}}</text>
<text class="user-role">角色:{{userInfo.role === 'ADMIN' ? '管理员' : '货运员'}}</text>
<!-- 退出后台代码 -->
<button class="btn-logout" bindtap="handleLogout" size="mini">退出登录</button>
</view>

View File

@@ -88,6 +88,17 @@
gap: 20rpx;
}
/* 右侧控制按钮容器 */
.right-controls-container {
position: absolute;
top: 20rpx;
right: 30rpx;
z-index: 10;
display: flex;
flex-direction: column;
gap: 20rpx;
}
.control-btn {
width: 80rpx;
height: 80rpx;
@@ -1407,4 +1418,26 @@
100% {
opacity: 0.7;
}
}
/* 员工管理按钮样式 */
.staff-management-btn {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
background-color: white;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
.staff-management-btn:active {
background-color: #f5f5f5;
transform: scale(0.98);
}
.staff-management-btn image {
width: 40rpx;
height: 40rpx;
}

View File

@@ -14,11 +14,32 @@ export class DataModule {
/**
* 初始化页面数据
*/
public initializeData(): void {
public async initializeData(): Promise<void> {
// 检查是否已静默登录,如果是则尝试获取真实位置
let initialLongitude = 102.833722;
let initialLatitude = 24.880095;
const app = getApp<any>();
if (app.globalData.isLoggedIn) {
try {
// 导入地图服务
const mapService = require('../../../services/mapService').default;
const location = await mapService.getCurrentLocation();
if (location && !isNaN(location.latitude) && !isNaN(location.longitude)) {
initialLongitude = location.longitude;
initialLatitude = location.latitude;
console.log('[DATA MODULE] 静默登录后使用真实位置:', location);
}
} catch (error) {
console.warn('[DATA MODULE] 获取真实位置失败,使用默认位置:', error);
}
}
this.pageContext.setData({
// 地图相关数据
longitude: 102.833722,
latitude: 24.880095,
longitude: initialLongitude,
latitude: initialLatitude,
scale: 13,
markers: [] as Marker[],
polyline: null,
@@ -148,7 +169,7 @@ export class DataModule {
*/
public updateMarkers(markers: Marker[]): void {
// 验证每个标记点的坐标
const validatedMarkers = markers.map((marker, index) => {
const validatedMarkers = markers.map((marker) => {
// 检查经纬度是否为有效数字
if (isNaN(marker.longitude) || isNaN(marker.latitude)) {
// 为无效坐标设置默认值
@@ -283,4 +304,26 @@ export class DataModule {
public resetAllData(): void {
this.initializeData();
}
/**
* 获取位置模块(用于其他模块访问位置模块)
*/
public getLocationModule(): any {
// 通过页面上下文获取位置模块
if (this.pageContext.data.mainPageModule) {
return this.pageContext.data.mainPageModule.getLocationModule();
}
return null;
}
/**
* 获取地图模块(用于其他模块访问地图模块)
*/
public getMapModule(): any {
// 通过页面上下文获取地图模块
if (this.pageContext.data.mainPageModule) {
return this.pageContext.data.mainPageModule.getMapModule();
}
return null;
}
}

View File

@@ -1,10 +1,12 @@
// 货运人员模块 - 处理货运人员管理、位置跟踪、交互
import deliveryPersonService from '../../../services/deliveryPersonService';
// 员模块 - 处理所有员工(管理员和货运人员管理、位置跟踪、交互
import employeeService from '../../../services/employeeService';
import { Role } from '../../../utils/roleUtils';
// getApp是微信小程序全局函数无需导入
import { showToast } from '../../../utils/helpers';
import { DataModule } from './dataModule';
export class DeliveryPersonModule {
export class EmployeeModule {
private pageContext: any;
private dataModule: DataModule;
@@ -14,210 +16,44 @@ export class DeliveryPersonModule {
}
/**
* 加载货运人员数据
* 加载所有员工数据(包括管理员和货运人员
*/
async loadDeliveryPersons(): Promise<void> {
async loadAllEmployees(): Promise<void> {
try {
const deliveryPersons = await deliveryPersonService.getDeliveryPersons();
// 获取所有员工数据
const allEmployees = await employeeService.getEmployees();
// 更新地图标记点
this.updateDeliveryPersonMarkers(deliveryPersons);
console.log('货运人员数据加载完成,数量:', deliveryPersons.length);
console.log('所有员工数据加载完成,数量:', allEmployees.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('开始实时跟踪失败');
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;
private getEmployeeIcon(role: string): string {
console.log(`获取员工图标,角色: ${role}`);
// 查找并更新对应的货运人员标记点
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状态');
switch (role) {
case Role.ADMIN:
// 管理员使用皇冠图标
iconPath = '/images/crown.png';
console.log('使用管理员图标(👑');
break;
case 'busy':
// 为避免图片加载失败,暂时使用备用图片
iconPath = fallbackIconPath;
console.log('使用备用图标busy状态');
break;
case 'offline':
// 为避免图片加载失败,暂时使用备用图片
iconPath = fallbackIconPath;
console.log('使用备用图标offline状态');
case Role.DELIVERY_PERSON:
// 货运人员使用货车图标
iconPath = '/images/truck.png';
console.log('使用货运人员图标(🚚');
break;
default:
iconPath = fallbackIconPath;
console.log('使用备用图标(默认状态)');
// 默认使用货车图标
iconPath = '/images/truck.png';
console.log('使用默认图标(🚚)');
break;
}

View File

@@ -0,0 +1,278 @@
// 位置模块 - 处理位置追踪、位置更新和地图标记点更新
import { DataModule } from './dataModule';
import { showToast } from '../../../utils/helpers';
import locationTrackingService from '../../../services/locationTrackingService';
import { OnlineUserInfo } from '../../../services/locationTrackingService';
// 位置模块接口定义
export interface LocationModule {
initialize(): Promise<void>;
cleanup(): void;
startRealTimeTracking(): Promise<void>;
stopRealTimeTracking(): Promise<void>;
updateEmployeeLocation(employeeId: number, location: { longitude: number, latitude: number }): Promise<void>;
}
export class LocationModule {
private pageContext: any;
private dataModule: DataModule;
private isTracking: boolean;
constructor(pageContext: any, dataModule: DataModule) {
this.pageContext = pageContext;
this.dataModule = dataModule;
this.isTracking = false;
// 绑定回调方法
this.handleLocationUpdates = this.handleLocationUpdates.bind(this);
}
/**
* 初始化位置模块
*/
async initialize(): Promise<void> {
console.log('位置模块初始化');
// 订阅位置更新
this.subscribeToLocationUpdates();
console.log('位置模块初始化完成');
}
/**
* 清理位置模块
*/
cleanup(): void {
console.log('清理位置模块');
// 取消位置更新订阅
this.unsubscribeFromLocationUpdates();
// 停止实时跟踪
if (this.isTracking) {
this.stopRealTimeTracking().catch(error => {
console.error('停止实时跟踪失败:', error);
});
}
}
/**
* 开始实时跟踪位置
*/
async startRealTimeTracking(): Promise<void> {
try {
// 获取当前用户信息
const userInfo = this.dataModule.getData().userInfo;
if (!userInfo || !userInfo.id) {
throw new Error('用户信息获取失败');
}
// 启动位置跟踪订阅
await locationTrackingService.startTrackingAfterSignIn();
this.isTracking = true;
showToast('已开始实时跟踪');
console.log('开始实时跟踪位置');
} catch (error) {
console.error('开始实时跟踪失败:', error);
showToast('开始实时跟踪失败');
throw error;
}
}
/**
* 停止实时跟踪位置
*/
async stopRealTimeTracking(): Promise<void> {
try {
// 获取当前用户信息
const userInfo = this.dataModule.getData().userInfo;
if (!userInfo || !userInfo.id) {
throw new Error('用户信息获取失败');
}
// 停止位置跟踪
await locationTrackingService.stopTracking();
this.isTracking = false;
showToast('已停止实时跟踪');
console.log('停止实时跟踪位置');
} catch (error) {
console.error('停止实时跟踪失败:', error);
showToast('停止实时跟踪失败');
throw error;
}
}
/**
* 更新员工位置
*/
async updateEmployeeLocation(employeeId: number, location: { longitude: number, latitude: number }): Promise<void> {
try {
console.log(`员工 ${employeeId} 位置更新:`, location);
// 通过locationTrackingService更新位置
await locationTrackingService.updateUserLocation(location);
console.log(`员工 ${employeeId} 位置更新完成`);
} catch (error) {
console.error('更新员工位置失败:', error);
showToast('更新位置失败');
throw error;
}
}
/**
* 订阅位置更新
*/
private subscribeToLocationUpdates(): void {
console.log('订阅位置更新');
locationTrackingService.subscribeToLocationUpdates(this.handleLocationUpdates);
}
/**
* 取消订阅位置更新
*/
private unsubscribeFromLocationUpdates(): void {
console.log('取消订阅位置更新');
locationTrackingService.unsubscribeFromLocationUpdates(this.handleLocationUpdates);
}
/**
* 处理位置更新回调
*/
private handleLocationUpdates(locationData: any): void {
console.log('收到位置更新回调:', locationData);
if (locationData.type === 'onlineUserList' && locationData.users) {
// 处理在线用户列表更新
console.log('处理在线用户列表,用户数量:', locationData.users.length);
this.updateEmployeeMarkers(locationData.users);
} else if (Array.isArray(locationData)) {
// 处理位置更新数组(旧格式)
console.log('处理位置更新数组,用户数量:', locationData.length);
this.updateEmployeeMarkers(locationData);
} else if (locationData.userId && locationData.latitude && locationData.longitude) {
// 处理单个用户位置更新
console.log('处理单个用户位置更新:', locationData.userId);
this.updateSingleEmployeeMarker(locationData);
} else {
console.warn('未知的位置数据格式:', locationData);
}
}
/**
* 更新员工标记点
*/
private updateEmployeeMarkers(onlineUsers: any[]): void {
console.log('开始更新员工标记点,在线用户数量:', onlineUsers.length);
// 获取地图模块来更新标记点
const mapModule = this.dataModule.getMapModule();
if (!mapModule) {
console.error('地图模块未找到,无法更新员工标记点');
return;
}
// 为每个在线用户创建标记点
const employeeMarkers = onlineUsers.map(user => {
// 获取用户角色信息
const userRole = user.role || this.getUserRole(user.userId);
// 解析位置信息(支持多种格式)
const longitude = user.longitude || (user.lastLocation && user.lastLocation.longitude) || 0;
const latitude = user.latitude || (user.lastLocation && user.lastLocation.latitude) || 0;
const lastUpdateTime = user.lastUpdateTime || Date.now();
const employeeMarker = {
id: 10000 + user.userId, // 避免ID冲突
type: 'employee',
title: user.userName || `员工${user.userId}`,
longitude: longitude,
latitude: latitude,
iconPath: this.getEmployeeIcon(user.userId, userRole),
width: 32,
height: 32,
zIndex: 30,
data: {
userId: user.userId,
role: userRole,
lastUpdateTime: lastUpdateTime
}
};
return employeeMarker;
});
// 调用地图模块更新员工标记点
mapModule.updateEmployeeMarkers(employeeMarkers);
console.log(`成功更新了 ${employeeMarkers.length} 个员工标记点`);
}
/**
* 更新单个员工标记点
*/
private updateSingleEmployeeMarker(locationUpdate: any): void {
console.log('更新单个员工标记点:', locationUpdate.userId);
// 获取地图模块
const mapModule = this.dataModule.getMapModule();
if (!mapModule) {
console.error('地图模块未找到,无法更新员工标记点');
return;
}
// 获取用户角色信息
const userRole = this.getUserRole(locationUpdate.userId);
// 创建单个员工标记点
const employeeMarker = {
id: 10000 + locationUpdate.userId,
type: 'employee',
title: `员工${locationUpdate.userId}`,
longitude: locationUpdate.longitude,
latitude: locationUpdate.latitude,
iconPath: this.getEmployeeIcon(locationUpdate.userId, userRole),
width: 32,
height: 32,
zIndex: 30,
data: {
userId: locationUpdate.userId,
role: userRole,
lastUpdateTime: locationUpdate.timestamp || Date.now()
}
};
// 调用地图模块更新单个标记点
mapModule.updateSingleEmployeeMarker(employeeMarker);
console.log('单个员工标记点更新完成');
}
/**
* 获取用户角色
*/
private getUserRole(userId: number): string {
// 从数据模块获取用户信息
const userInfo = this.dataModule.getData().userInfo;
if (userInfo && userInfo.id === userId) {
return userInfo.role || 'employee';
}
// 如果是其他用户,默认为货运人员
return 'employee';
}
/**
* 获取员工图标
*/
private getEmployeeIcon(userId: number, userRole: string): string {
// 根据用户角色返回不同的图标
if (userRole === 'ADMIN') {
return '/images/crown.png'; // 管理员图标
} else {
return '/images/trucks.png'; // 货运人员图标
}
}
}

View File

@@ -234,9 +234,17 @@ export class LoginModule {
// 启动位置追踪服务
try {
// 先启动位置追踪服务
await locationTrackingService.startTrackingAfterSignIn();
console.log('位置追踪服务已启动');
// 然后调用位置模块的实时跟踪功能
const locationModule = this.dataModule.getLocationModule();
if (locationModule) {
await locationModule.startRealTimeTracking();
console.log('位置模块实时跟踪已启动');
}
// 订阅位置更新回调,采用统一方式更新所有用户位置
locationTrackingService.subscribeToLocationUpdates((onlineUsers) => {
console.log('🚚 位置更新回调 - 在线用户列表已更新,用户数量:', onlineUsers.length);
@@ -433,10 +441,8 @@ export class LoginModule {
// 根据服务器返回的状态映射到前端状态
switch (response.status) {
case 'signed_in':
case 'online':
return 'signed_in';
case 'signed_out':
case 'offline':
return 'signed_out';
case 'registered':
return 'registered';

View File

@@ -3,17 +3,32 @@ import { LoginModule } from './loginModule';
import { MapModule } from './mapModule';
import { OrderModule } from './orderModule';
import { WarehouseModule } from './warehouseModule';
import { DeliveryPersonModule } from './deliveryPersonModule';
import { EmployeeModule } from './deliveryPersonModule';
import { LocationModule } from './locationModule';
import { DataModule } from './dataModule';
import { showToast } from '../../../utils/helpers';
// 主页面模块接口定义
export interface MainPageModule {
getLoginModule(): LoginModule;
onLoad(): Promise<void>;
onShow(): void;
onHide(): void;
onLogout(): void;
hideAllPanels(): void;
resetMarkers(): void;
cleanup(): void;
refreshAllData(): Promise<void>;
}
export class MainPageModule {
private pageContext: any;
private loginModule: LoginModule;
private mapModule: MapModule;
private orderModule: OrderModule;
private warehouseModule: WarehouseModule;
private deliveryPersonModule: DeliveryPersonModule;
private employeeModule: EmployeeModule;
private locationModule: LocationModule;
private dataModule: DataModule;
constructor(pageContext: any) {
@@ -25,7 +40,8 @@ export class MainPageModule {
this.mapModule = new MapModule(pageContext, this.dataModule);
this.orderModule = new OrderModule(pageContext, this.dataModule);
this.warehouseModule = new WarehouseModule(pageContext, this.dataModule);
this.deliveryPersonModule = new DeliveryPersonModule(pageContext, this.dataModule);
this.employeeModule = new EmployeeModule(pageContext, this.dataModule);
this.locationModule = new LocationModule(pageContext, this.dataModule);
}
/**
@@ -38,6 +54,9 @@ export class MainPageModule {
// 初始化应用
await this.initApp();
// 初始化位置模块
await this.locationModule.initialize();
// 加载地图数据
await this.loadAllData();
@@ -58,12 +77,22 @@ export class MainPageModule {
this.refreshDataIfNeeded();
}
/**
* 页面隐藏
*/
onHide(): void {
console.log('主页面隐藏');
// 清理位置模块
this.locationModule.cleanup();
}
/**
* 初始化应用
*/
private async initApp(): Promise<void> {
// 初始化数据
this.dataModule.initializeData();
await this.dataModule.initializeData();
console.log('应用初始化');
}
@@ -119,7 +148,7 @@ export class MainPageModule {
// 并行加载各种业务数据(需要登录)
await Promise.all([
this.orderModule.loadPendingOrders(),
this.deliveryPersonModule.loadDeliveryPersons()
this.employeeModule.loadAllEmployees()
]);
console.log('所有业务数据加载完成');
@@ -160,7 +189,7 @@ export class MainPageModule {
this.dataModule.updatePendingOrders([]);
const filteredMarkers = this.pageContext.data.markers.filter((marker: any) =>
marker.type !== 'warehouse' && marker.type !== 'delivery_person'
marker.type !== 'warehouse' && marker.type !== 'employee'
);
this.dataModule.updateMarkers(filteredMarkers);
}
@@ -230,7 +259,7 @@ export class MainPageModule {
this.warehouseModule.onWarehouseMarkerClick(marker.data, e);
break;
case 'delivery_person':
this.deliveryPersonModule.onDeliveryPersonMarkerClick(marker.data, e);
this.employeeModule.onDeliveryPersonMarkerClick(marker.data, e);
break;
default:
this.mapModule.onMarkerTap(e);
@@ -267,10 +296,17 @@ export class MainPageModule {
}
/**
* 获取货运人员模块
* 获取员模块
*/
getDeliveryPersonModule(): DeliveryPersonModule {
return this.deliveryPersonModule;
getEmployeeModule(): EmployeeModule {
return this.employeeModule;
}
/**
* 获取位置模块
*/
getLocationModule(): LocationModule {
return this.locationModule;
}
/**

View File

@@ -83,11 +83,16 @@ export class MapModule {
return;
}
// 更新数据模块中的位置信息和缩放级别
// 强制重置地图视角到用户位置
// 1. 更新用户位置
this.dataModule.updateUserLocation(location.latitude, location.longitude);
this.dataModule.setMapScale(15); // 定位成功后放大到更详细级别
// 2. 重置地图缩放级别到15详细级别
this.dataModule.setMapScale(15);
// 3. 添加地图动画效果,让视角平滑回到用户位置
this.animateMapToUserLocation(location.latitude, location.longitude);
console.log('[MAP MODULE] 定位成功,坐标已更新:', location);
console.log('[MAP MODULE] 定位成功,坐标已更新,视角已重置:', location);
showToast('已定位到您的位置');
} catch (error) {
console.error('[MAP MODULE] 定位失败:', error);
this.setDefaultLocation();
@@ -105,9 +110,44 @@ export class MapModule {
// 更新数据模块中的位置信息和缩放级别
this.dataModule.updateUserLocation(defaultLatitude, defaultLongitude);
this.dataModule.setMapScale(13);
// 动画效果回到默认位置
this.animateMapToUserLocation(defaultLatitude, defaultLongitude);
console.log('[MAP MODULE] 默认位置设置完成');
}
/**
* 动画效果将地图视角平滑移动到用户位置
*/
private animateMapToUserLocation(latitude: number, longitude: number): void {
// 使用微信小程序的MapContext.moveToLocation方法实现地图移动
const mapContext = wx.createMapContext('myMap', this.pageContext);
// 先设置地图中心点
this.pageContext.setData({
latitude: latitude,
longitude: longitude
});
// 使用moveToLocation方法平滑移动地图视角
mapContext.moveToLocation({
latitude: latitude,
longitude: longitude,
success: () => {
console.log('[MAP MODULE] 地图视角移动成功,位置:', { latitude, longitude });
},
fail: (err: any) => {
console.error('[MAP MODULE] 地图视角移动失败:', err);
// 如果moveToLocation失败直接设置中心点
this.pageContext.setData({
latitude: latitude,
longitude: longitude
});
}
});
console.log('[MAP MODULE] 地图视角动画已启动,移动到位置:', { latitude, longitude });
}
/**
* 加载地图数据(仓库和货运人员)
@@ -126,39 +166,30 @@ export class MapModule {
/**
* 生成初始标记点
*/
private generateInitialMarkers(): Marker[] {
// 获取当前坐标
const longitude = this.pageContext.data.longitude;
const latitude = this.pageContext.data.latitude;
public generateInitialMarkers(): Marker[] {
console.log('生成初始标记点');
// 检查坐标是否为有效数字
let validLongitude = longitude;
let validLatitude = latitude;
const markers: Marker[] = [];
if (isNaN(longitude) || isNaN(latitude)) {
console.warn(`无效的坐标值: longitude=${longitude}, latitude=${latitude}, 使用默认坐标`);
validLongitude = 102.833722; // 默认经度
validLatitude = 24.880095; // 默认纬度
// 更新页面数据中的坐标
this.dataModule.updateUserLocation(validLatitude, validLongitude);
}
// 生成初始标记点
return [
{
id: -1, // 用户位置标记
// 获取用户位置
const userLocation = this.pageContext.data.userLocation;
if (userLocation && userLocation.longitude && userLocation.latitude) {
// 添加用户位置标记点
markers.push({
id: -1,
title: '用户位置',
longitude: validLongitude,
latitude: validLatitude,
longitude: userLocation.longitude,
latitude: userLocation.latitude,
iconPath: '/images/trucks.png',
width: 40,
height: 40,
zIndex: 99
}
];
});
console.log('已添加用户位置标记点');
}
return markers;
}
/**
@@ -191,6 +222,57 @@ export class MapModule {
console.log('用户头像已更新');
}
/**
* 更新员工标记点
*/
updateEmployeeMarkers(employeeMarkers: Marker[]): void {
console.log('开始更新员工标记点,数量:', employeeMarkers.length);
const { markers } = this.pageContext.data;
// 过滤掉现有的员工标记点
const filteredMarkers = markers.filter((marker: any) =>
marker.type !== 'employee'
);
// 合并标记点
const updatedMarkers = [...filteredMarkers, ...employeeMarkers];
// 更新数据模块中的标记点
this.dataModule.updateMarkers(updatedMarkers);
console.log('员工标记点更新完成,总标记点数量:', updatedMarkers.length);
}
/**
* 更新单个员工标记点
*/
updateSingleEmployeeMarker(employeeMarker: Marker): void {
console.log('更新单个员工标记点:', employeeMarker.id);
const { markers } = this.pageContext.data;
// 查找现有的员工标记点
const markerIndex = markers.findIndex((marker: any) =>
marker.type === 'employee' && marker.id === employeeMarker.id
);
let updatedMarkers;
if (markerIndex !== -1) {
// 更新现有的标记点
updatedMarkers = [...markers];
updatedMarkers[markerIndex] = employeeMarker;
} else {
// 添加新的标记点
updatedMarkers = [...markers, employeeMarker];
}
// 更新数据模块中的标记点
this.dataModule.updateMarkers(updatedMarkers);
console.log('单个员工标记点更新完成');
}
/**
* 处理地图点击事件
*/